1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_xmloff.hxx"
26 #include "XMLChangedRegionImportContext.hxx"
27 #include "XMLChangeElementImportContext.hxx"
28 #include <com/sun/star/uno/Reference.h>
29 #include <com/sun/star/util/DateTime.hpp>
30 #include <com/sun/star/text/XTextCursor.hpp>
31 #include <xmloff/xmlimp.hxx>
32 #include "xmloff/xmlnmspe.hxx"
33 #include <xmloff/nmspmap.hxx>
34 #include <xmloff/xmltoken.hxx>
35 #include <xmloff/xmluconv.hxx>
36 
37 
38 using namespace ::xmloff::token;
39 
40 using ::rtl::OUString;
41 using ::com::sun::star::uno::Reference;
42 using ::com::sun::star::text::XTextCursor;
43 using ::com::sun::star::util::DateTime;
44 using ::com::sun::star::xml::sax::XAttributeList;
45 
46 
47 
48 TYPEINIT1(XMLChangedRegionImportContext, SvXMLImportContext);
49 
XMLChangedRegionImportContext(SvXMLImport & rImport,sal_uInt16 nPrefix,const OUString & rLocalName)50 XMLChangedRegionImportContext::XMLChangedRegionImportContext(
51 	SvXMLImport& rImport,
52 	sal_uInt16 nPrefix,
53 	const OUString& rLocalName) :
54         SvXMLImportContext(rImport, nPrefix, rLocalName),
55         bMergeLastPara(sal_True)
56 {
57 }
58 
~XMLChangedRegionImportContext()59 XMLChangedRegionImportContext::~XMLChangedRegionImportContext()
60 {
61 }
62 
StartElement(const Reference<XAttributeList> & xAttrList)63 void XMLChangedRegionImportContext::StartElement(
64 	const Reference<XAttributeList> & xAttrList)
65 {
66 	// process attributes: id
67     bool bHaveXmlId( false );
68 	sal_Int16 nLength = xAttrList->getLength();
69 	for(sal_Int16 nAttr = 0; nAttr < nLength; nAttr++)
70 	{
71 		OUString sLocalName;
72 		sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
73 			GetKeyByAttrName( xAttrList->getNameByIndex(nAttr),
74 							  &sLocalName );
75 
76         const OUString sValue = xAttrList->getValueByIndex(nAttr);
77         if (XML_NAMESPACE_XML == nPrefix)
78         {
79             if (IsXMLToken(sLocalName, XML_ID))
80             {
81                 sID = sValue;
82                 bHaveXmlId = true;
83             }
84         }
85         else if (XML_NAMESPACE_TEXT == nPrefix)
86         {
87             if (IsXMLToken(sLocalName, XML_ID))
88             {
89                 if (!bHaveXmlId) { sID = sValue; }
90             }
91             else if( IsXMLToken( sLocalName, XML_MERGE_LAST_PARAGRAPH ) )
92             {
93                 sal_Bool bTmp;
94                 if( SvXMLUnitConverter::convertBool(bTmp, sValue) )
95                 {
96                     bMergeLastPara = bTmp;
97                 }
98             }
99         }
100 	}
101 }
102 
CreateChildContext(sal_uInt16 nPrefix,const OUString & rLocalName,const Reference<XAttributeList> & xAttrList)103 SvXMLImportContext* XMLChangedRegionImportContext::CreateChildContext(
104 	sal_uInt16 nPrefix,
105 	const OUString& rLocalName,
106 	const Reference<XAttributeList> & xAttrList)
107 {
108 	SvXMLImportContext* pContext = NULL;
109 
110 	if (XML_NAMESPACE_TEXT == nPrefix)
111 	{
112 		if ( IsXMLToken( rLocalName, XML_INSERTION ) ||
113              IsXMLToken( rLocalName, XML_DELETION ) ||
114              IsXMLToken( rLocalName, XML_FORMAT_CHANGE ) )
115 		{
116 			// create XMLChangeElementImportContext for all kinds of changes
117 			pContext = new XMLChangeElementImportContext(
118 			   GetImport(), nPrefix, rLocalName,
119 			   IsXMLToken( rLocalName, XML_DELETION ),
120 			   *this);
121 		}
122 		// else: it may be a text element, see below
123 	}
124 
125 	if (NULL == pContext)
126 	{
127 		pContext = SvXMLImportContext::CreateChildContext(nPrefix, rLocalName,
128 														  xAttrList);
129 
130 		// was it a text element? If not, use default!
131 		if (NULL == pContext)
132 		{
133 			pContext = SvXMLImportContext::CreateChildContext(
134 				nPrefix, rLocalName, xAttrList);
135 		}
136 	}
137 
138 	return pContext;
139 }
140 
EndElement()141 void XMLChangedRegionImportContext::EndElement()
142 {
143 	// restore old XCursor (if necessary)
144 	if (xOldCursor.is())
145 	{
146 		// delete last paragraph
147 		// (one extra paragraph was inserted in the beginning)
148 		UniReference<XMLTextImportHelper> rHelper =
149 			GetImport().GetTextImport();
150 		rHelper->DeleteParagraph();
151 
152 		GetImport().GetTextImport()->SetCursor(xOldCursor);
153 		xOldCursor = NULL;
154 	}
155 }
156 
SetChangeInfo(const OUString & rType,const OUString & rAuthor,const OUString & rComment,const OUString & rDate)157 void XMLChangedRegionImportContext::SetChangeInfo(
158 	const OUString& rType,
159 	const OUString& rAuthor,
160 	const OUString& rComment,
161 	const OUString& rDate)
162 {
163 	DateTime aDateTime;
164 	if (SvXMLUnitConverter::convertDateTime(aDateTime, rDate))
165 	{
166 		GetImport().GetTextImport()->RedlineAdd(
167 			rType, sID, rAuthor, rComment, aDateTime, bMergeLastPara);
168 	}
169 }
170 
UseRedlineText()171 void XMLChangedRegionImportContext::UseRedlineText()
172 {
173 	// if we haven't already installed the redline cursor, do it now
174 	if (! xOldCursor.is())
175 	{
176 		// get TextImportHelper and old Cursor
177 		UniReference<XMLTextImportHelper> rHelper(GetImport().GetTextImport());
178 		Reference<XTextCursor> xCursor( rHelper->GetCursor() );
179 
180 		// create Redline and new Cursor
181 		Reference<XTextCursor> xNewCursor =
182 			rHelper->RedlineCreateText(xCursor, sID);
183 
184 		if (xNewCursor.is())
185 		{
186 			// save old cursor and install new one
187 			xOldCursor = xCursor;
188 			rHelper->SetCursor( xNewCursor );
189 		}
190 		// else: leave as is
191 	}
192 }
193