1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_xmloff.hxx"
30 #include "XMLChangedRegionImportContext.hxx"
31 #include "XMLChangeElementImportContext.hxx"
32 #include <com/sun/star/uno/Reference.h>
33 #include <com/sun/star/util/DateTime.hpp>
34 #include <com/sun/star/text/XTextCursor.hpp>
35 #include <xmloff/xmlimp.hxx>
36 #include "xmloff/xmlnmspe.hxx"
37 #include <xmloff/nmspmap.hxx>
38 #include <xmloff/xmltoken.hxx>
39 #include <xmloff/xmluconv.hxx>
40 
41 
42 using namespace ::xmloff::token;
43 
44 using ::rtl::OUString;
45 using ::com::sun::star::uno::Reference;
46 using ::com::sun::star::text::XTextCursor;
47 using ::com::sun::star::util::DateTime;
48 using ::com::sun::star::xml::sax::XAttributeList;
49 
50 
51 
52 TYPEINIT1(XMLChangedRegionImportContext, SvXMLImportContext);
53 
54 XMLChangedRegionImportContext::XMLChangedRegionImportContext(
55 	SvXMLImport& rImport,
56 	sal_uInt16 nPrefix,
57 	const OUString& rLocalName) :
58         SvXMLImportContext(rImport, nPrefix, rLocalName),
59         bMergeLastPara(sal_True)
60 {
61 }
62 
63 XMLChangedRegionImportContext::~XMLChangedRegionImportContext()
64 {
65 }
66 
67 void XMLChangedRegionImportContext::StartElement(
68 	const Reference<XAttributeList> & xAttrList)
69 {
70 	// process attributes: id
71     bool bHaveXmlId( false );
72 	sal_Int16 nLength = xAttrList->getLength();
73 	for(sal_Int16 nAttr = 0; nAttr < nLength; nAttr++)
74 	{
75 		OUString sLocalName;
76 		sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
77 			GetKeyByAttrName( xAttrList->getNameByIndex(nAttr),
78 							  &sLocalName );
79 
80         const OUString sValue = xAttrList->getValueByIndex(nAttr);
81         if (XML_NAMESPACE_XML == nPrefix)
82         {
83             if (IsXMLToken(sLocalName, XML_ID))
84             {
85                 sID = sValue;
86                 bHaveXmlId = true;
87             }
88         }
89         else if (XML_NAMESPACE_TEXT == nPrefix)
90         {
91             if (IsXMLToken(sLocalName, XML_ID))
92             {
93                 if (!bHaveXmlId) { sID = sValue; }
94             }
95             else if( IsXMLToken( sLocalName, XML_MERGE_LAST_PARAGRAPH ) )
96             {
97                 sal_Bool bTmp;
98                 if( SvXMLUnitConverter::convertBool(bTmp, sValue) )
99                 {
100                     bMergeLastPara = bTmp;
101                 }
102             }
103         }
104 	}
105 }
106 
107 SvXMLImportContext* XMLChangedRegionImportContext::CreateChildContext(
108 	sal_uInt16 nPrefix,
109 	const OUString& rLocalName,
110 	const Reference<XAttributeList> & xAttrList)
111 {
112 	SvXMLImportContext* pContext = NULL;
113 
114 	if (XML_NAMESPACE_TEXT == nPrefix)
115 	{
116 		if ( IsXMLToken( rLocalName, XML_INSERTION ) ||
117              IsXMLToken( rLocalName, XML_DELETION ) ||
118              IsXMLToken( rLocalName, XML_FORMAT_CHANGE ) )
119 		{
120 			// create XMLChangeElementImportContext for all kinds of changes
121 			pContext = new XMLChangeElementImportContext(
122 			   GetImport(), nPrefix, rLocalName,
123 			   IsXMLToken( rLocalName, XML_DELETION ),
124 			   *this);
125 		}
126 		// else: it may be a text element, see below
127 	}
128 
129 	if (NULL == pContext)
130 	{
131 		pContext = SvXMLImportContext::CreateChildContext(nPrefix, rLocalName,
132 														  xAttrList);
133 
134 		// was it a text element? If not, use default!
135 		if (NULL == pContext)
136 		{
137 			pContext = SvXMLImportContext::CreateChildContext(
138 				nPrefix, rLocalName, xAttrList);
139 		}
140 	}
141 
142 	return pContext;
143 }
144 
145 void XMLChangedRegionImportContext::EndElement()
146 {
147 	// restore old XCursor (if necessary)
148 	if (xOldCursor.is())
149 	{
150 		// delete last paragraph
151 		// (one extra paragraph was inserted in the beginning)
152 		UniReference<XMLTextImportHelper> rHelper =
153 			GetImport().GetTextImport();
154 		rHelper->DeleteParagraph();
155 
156 		GetImport().GetTextImport()->SetCursor(xOldCursor);
157 		xOldCursor = NULL;
158 	}
159 }
160 
161 void XMLChangedRegionImportContext::SetChangeInfo(
162 	const OUString& rType,
163 	const OUString& rAuthor,
164 	const OUString& rComment,
165 	const OUString& rDate)
166 {
167 	DateTime aDateTime;
168 	if (SvXMLUnitConverter::convertDateTime(aDateTime, rDate))
169 	{
170 		GetImport().GetTextImport()->RedlineAdd(
171 			rType, sID, rAuthor, rComment, aDateTime, bMergeLastPara);
172 	}
173 }
174 
175 void XMLChangedRegionImportContext::UseRedlineText()
176 {
177 	// if we haven't already installed the redline cursor, do it now
178 	if (! xOldCursor.is())
179 	{
180 		// get TextImportHelper and old Cursor
181 		UniReference<XMLTextImportHelper> rHelper(GetImport().GetTextImport());
182 		Reference<XTextCursor> xCursor( rHelper->GetCursor() );
183 
184 		// create Redline and new Cursor
185 		Reference<XTextCursor> xNewCursor =
186 			rHelper->RedlineCreateText(xCursor, sID);
187 
188 		if (xNewCursor.is())
189 		{
190 			// save old cursor and install new one
191 			xOldCursor = xCursor;
192 			rHelper->SetCursor( xNewCursor );
193 		}
194 		// else: leave as is
195 	}
196 }
197