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_sc.hxx"
26 #include "XMLChangeTrackingExportHelper.hxx"
27 #include "xmlexprt.hxx"
28 #include "XMLConverter.hxx"
29 #include "document.hxx"
30 #include "chgtrack.hxx"
31 #include "chgviset.hxx"
32 #include "cell.hxx"
33 #include "textuno.hxx"
34 #include "rangeutl.hxx"
35 #include <xmloff/xmlnmspe.hxx>
36 #include <xmloff/nmspmap.hxx>
37 #include <xmloff/xmluconv.hxx>
38 #include <com/sun/star/util/DateTime.hpp>
39 #include <tools/debug.hxx>
40 #include <tools/datetime.hxx>
41 #include <svl/zforlist.hxx>
42 
43 #define SC_CHANGE_ID_PREFIX "ct"
44 
45 using namespace ::com::sun::star;
46 using namespace xmloff::token;
47 
ScChangeTrackingExportHelper(ScXMLExport & rTempExport)48 ScChangeTrackingExportHelper::ScChangeTrackingExportHelper(ScXMLExport& rTempExport)
49 	: rExport(rTempExport),
50 	pChangeTrack(NULL),
51 	pEditTextObj(NULL),
52 	pDependings(NULL),
53 	sChangeIDPrefix(RTL_CONSTASCII_USTRINGPARAM(SC_CHANGE_ID_PREFIX))
54 {
55 	pChangeTrack = rExport.GetDocument() ? rExport.GetDocument()->GetChangeTrack() : NULL;
56 	pDependings = new ScChangeActionTable();
57 }
58 
~ScChangeTrackingExportHelper()59 ScChangeTrackingExportHelper::~ScChangeTrackingExportHelper()
60 {
61 	if (pDependings)
62 		delete pDependings;
63 }
64 
GetChangeID(const sal_uInt32 nActionNumber)65 rtl::OUString ScChangeTrackingExportHelper::GetChangeID(const sal_uInt32 nActionNumber)
66 {
67 	rtl::OUStringBuffer sBuffer(sChangeIDPrefix);
68 	SvXMLUnitConverter::convertNumber(sBuffer, static_cast<sal_Int32>(nActionNumber));
69 	return sBuffer.makeStringAndClear();
70 }
71 
GetAcceptanceState(const ScChangeAction * pAction)72 void ScChangeTrackingExportHelper::GetAcceptanceState(const ScChangeAction* pAction)
73 {
74 	if (pAction->IsRejected())
75 		rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ACCEPTANCE_STATE, XML_REJECTED);
76 	else if (pAction->IsAccepted())
77 		rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ACCEPTANCE_STATE, XML_ACCEPTED);
78 }
79 
WriteBigRange(const ScBigRange & rBigRange,XMLTokenEnum aName)80 void ScChangeTrackingExportHelper::WriteBigRange(const ScBigRange& rBigRange, XMLTokenEnum aName)
81 {
82 	sal_Int32 nStartColumn;
83 	sal_Int32 nEndColumn;
84 	sal_Int32 nStartRow;
85 	sal_Int32 nEndRow;
86 	sal_Int32 nStartSheet;
87 	sal_Int32 nEndSheet;
88 	rBigRange.GetVars(nStartColumn, nStartRow, nStartSheet,
89 		nEndColumn, nEndRow, nEndSheet);
90 	if ((nStartColumn == nEndColumn) && (nStartRow == nEndRow) && (nStartSheet == nEndSheet))
91 	{
92 		rtl::OUStringBuffer sBuffer;
93 		SvXMLUnitConverter::convertNumber(sBuffer, nStartColumn);
94 		rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_COLUMN, sBuffer.makeStringAndClear());
95 		SvXMLUnitConverter::convertNumber(sBuffer, nStartRow);
96 		rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ROW, sBuffer.makeStringAndClear());
97 		SvXMLUnitConverter::convertNumber(sBuffer, nStartSheet);
98 		rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE, sBuffer.makeStringAndClear());
99 	}
100 	else
101 	{
102 		rtl::OUStringBuffer sBuffer;
103 		SvXMLUnitConverter::convertNumber(sBuffer, nStartColumn);
104 		rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_START_COLUMN, sBuffer.makeStringAndClear());
105 		SvXMLUnitConverter::convertNumber(sBuffer, nStartRow);
106 		rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_START_ROW, sBuffer.makeStringAndClear());
107 		SvXMLUnitConverter::convertNumber(sBuffer, nStartSheet);
108 		rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_START_TABLE, sBuffer.makeStringAndClear());
109 		SvXMLUnitConverter::convertNumber(sBuffer, nEndColumn);
110 		rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_END_COLUMN, sBuffer.makeStringAndClear());
111 		SvXMLUnitConverter::convertNumber(sBuffer, nEndRow);
112 		rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_END_ROW, sBuffer.makeStringAndClear());
113 		SvXMLUnitConverter::convertNumber(sBuffer, nEndSheet);
114 		rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_END_TABLE, sBuffer.makeStringAndClear());
115 	}
116 	SvXMLElementExport aBigRangeElem(rExport, XML_NAMESPACE_TABLE, aName, sal_True, sal_True);
117 }
118 
WriteChangeInfo(const ScChangeAction * pAction)119 void ScChangeTrackingExportHelper::WriteChangeInfo(const ScChangeAction* pAction)
120 {
121 	SvXMLElementExport aElemInfo (rExport, XML_NAMESPACE_OFFICE, XML_CHANGE_INFO, sal_True, sal_True);
122 
123     {
124     	SvXMLElementExport aCreatorElem( rExport, XML_NAMESPACE_DC,
125 	    									XML_CREATOR, sal_True,
126 		    								sal_False );
127         rtl::OUString sAuthor(pAction->GetUser());
128 	    rExport.Characters(sAuthor);
129     }
130 
131 	{
132 	    rtl::OUStringBuffer sDate;
133 	    ScXMLConverter::ConvertDateTimeToString(pAction->GetDateTimeUTC(), sDate);
134 		SvXMLElementExport aDateElem( rExport, XML_NAMESPACE_DC,
135 										  XML_DATE, sal_True,
136 										  sal_False );
137 		rExport.Characters(sDate.makeStringAndClear());
138 	}
139 
140 	rtl::OUString sComment(pAction->GetComment());
141 	if (sComment.getLength())
142 	{
143 		SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TEXT, XML_P, sal_True, sal_False);
144 		sal_Bool bPrevCharWasSpace(sal_True);
145 		rExport.GetTextParagraphExport()->exportText(sComment, bPrevCharWasSpace);
146 	}
147 }
148 
WriteGenerated(const ScChangeAction * pGeneratedAction)149 void ScChangeTrackingExportHelper::WriteGenerated(const ScChangeAction* pGeneratedAction)
150 {
151 #ifdef DBG_UTIL
152 	sal_uInt32 nActionNumber(pGeneratedAction->GetActionNumber());
153 	DBG_ASSERT(pChangeTrack->IsGenerated(nActionNumber), "a not generated action found");
154 #endif
155 	SvXMLElementExport aElemPrev(rExport, XML_NAMESPACE_TABLE, XML_CELL_CONTENT_DELETION, sal_True, sal_True);
156 	WriteBigRange(pGeneratedAction->GetBigRange(), XML_CELL_ADDRESS);
157 	String sValue;
158 	static_cast<const ScChangeActionContent*>(pGeneratedAction)->GetNewString(sValue);
159 	WriteCell(static_cast<const ScChangeActionContent*>(pGeneratedAction)->GetNewCell(), sValue);
160 }
161 
WriteDeleted(const ScChangeAction * pDeletedAction)162 void ScChangeTrackingExportHelper::WriteDeleted(const ScChangeAction* pDeletedAction)
163 {
164 	sal_uInt32 nActionNumber(pDeletedAction->GetActionNumber());
165 	if (pDeletedAction->GetType() == SC_CAT_CONTENT)
166 	{
167 		const ScChangeActionContent* pContentAction = static_cast<const ScChangeActionContent*>(pDeletedAction);
168 		if (pContentAction)
169 		{
170 			if (!pChangeTrack->IsGenerated(nActionNumber))
171 			{
172 				rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ID, GetChangeID(nActionNumber));
173 				SvXMLElementExport aElemPrev(rExport, XML_NAMESPACE_TABLE, XML_CELL_CONTENT_DELETION, sal_True, sal_True);
174 				if (static_cast<const ScChangeActionContent*>(pDeletedAction)->IsTopContent() && pDeletedAction->IsDeletedIn())
175 				{
176 					String sValue;
177 					pContentAction->GetNewString(sValue);
178 	 				WriteCell(pContentAction->GetNewCell(), sValue);
179 				}
180 			}
181 			else
182 				WriteGenerated(pContentAction);
183 		}
184 	}
185 	else
186 	{
187 		rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ID, GetChangeID(nActionNumber));
188 		SvXMLElementExport aElemPrev(rExport, XML_NAMESPACE_TABLE, XML_CHANGE_DELETION, sal_True, sal_True);
189 	}
190 }
191 
WriteDepending(const ScChangeAction * pDependAction)192 void ScChangeTrackingExportHelper::WriteDepending(const ScChangeAction* pDependAction)
193 {
194 	sal_uInt32 nActionNumber(pDependAction->GetActionNumber());
195 	rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ID, GetChangeID(nActionNumber));
196 
197     // #i80033# save old "dependence" element if backward compatibility is requested,
198     // correct "dependency" element otherwise
199     const bool bSaveBackwardsCompatible = ( rExport.getExportFlags() & EXPORT_SAVEBACKWARDCOMPATIBLE );
200     SvXMLElementExport aDependElem(rExport, XML_NAMESPACE_TABLE,
201         bSaveBackwardsCompatible ? XML_DEPENDENCE : XML_DEPENDENCY,
202         sal_True, sal_True);
203 }
204 
WriteDependings(ScChangeAction * pAction)205 void ScChangeTrackingExportHelper::WriteDependings(ScChangeAction* pAction)
206 {
207 	if (pAction->HasDependent())
208 	{
209 		SvXMLElementExport aDependingsElem (rExport, XML_NAMESPACE_TABLE, XML_DEPENDENCIES, sal_True, sal_True);
210 		const ScChangeActionLinkEntry* pEntry = pAction->GetFirstDependentEntry();
211 		while (pEntry)
212 		{
213 			WriteDepending(pEntry->GetAction());
214 			pEntry = pEntry->GetNext();
215 		}
216 	}
217 	if (pAction->HasDeleted())
218 	{
219 		SvXMLElementExport aDependingsElem (rExport, XML_NAMESPACE_TABLE, XML_DELETIONS, sal_True, sal_True);
220 		const ScChangeActionLinkEntry* pEntry = pAction->GetFirstDeletedEntry();
221 		while (pEntry)
222 		{
223 			WriteDeleted(pEntry->GetAction());
224 			pEntry = pEntry->GetNext();
225 		}
226 		/*if (pAction->IsDeleteType())
227 		{
228 			ScChangeActionDel* pDelAction = static_cast<ScChangeActionDel*> (pAction);
229 			if (pDelAction)
230 			{
231 				const ScChangeActionCellListEntry* pCellEntry = pDelAction->GetFirstCellEntry();
232 				while (pCellEntry)
233 				{
234 					WriteGenerated(pCellEntry->GetContent());
235 					pCellEntry = pCellEntry->GetNext();
236 				}
237 			}
238 		}
239 		else if (pAction->GetType() == SC_CAT_MOVE)
240 		{
241 			ScChangeActionMove* pMoveAction = static_cast<ScChangeActionMove*> (pAction);
242 			if (pMoveAction)
243 			{
244 				const ScChangeActionCellListEntry* pCellEntry = pMoveAction->GetFirstCellEntry();
245 				while (pCellEntry)
246 				{
247 					WriteGenerated(pCellEntry->GetContent());
248 					pCellEntry = pCellEntry->GetNext();
249 				}
250 			}
251 		}*/
252 	}
253 }
254 
255 /*void ScChangeTrackingExportHelper::WriteDependings(ScChangeAction* pAction)
256 {
257 	pChangeTrack->GetDependents(pAction, *pDependings);
258 	if (pDependings->Count())
259 	{
260 		SvXMLElementExport aDependingsElem (rExport, XML_NAMESPACE_TABLE, XML_DEPENDENCIES, sal_True, sal_True);
261 		ScChangeAction* pDependAction = pDependings->First();
262 		while (pDependAction != NULL)
263 		{
264 			WriteDepending(pDependAction);
265 			pDependAction = pDependings->Next();
266 		}
267 	}
268 }*/
269 
WriteEmptyCell()270 void ScChangeTrackingExportHelper::WriteEmptyCell()
271 {
272 	SvXMLElementExport aElemEmptyCell(rExport, XML_NAMESPACE_TABLE, XML_CHANGE_TRACK_TABLE_CELL, sal_True, sal_True);
273 }
274 
SetValueAttributes(const double & fValue,const String & sValue)275 void ScChangeTrackingExportHelper::SetValueAttributes(const double& fValue, const String& sValue)
276 {
277 	sal_Bool bSetAttributes(sal_False);
278 	if (sValue.Len())
279 	{
280 		sal_uInt32 nIndex;
281 		double fTempValue;
282 		if (rExport.GetDocument() && rExport.GetDocument()->GetFormatTable()->IsNumberFormat(sValue, nIndex, fTempValue))
283 		{
284 			sal_uInt16 nType = rExport.GetDocument()->GetFormatTable()->GetType(nIndex);
285             if ((nType & NUMBERFORMAT_DEFINED) == NUMBERFORMAT_DEFINED)
286                 nType -= NUMBERFORMAT_DEFINED;
287 			switch(nType)
288 			{
289 				case NUMBERFORMAT_DATE:
290 					{
291 						if ( rExport.GetMM100UnitConverter().setNullDate(rExport.GetModel()) )
292 						{
293 							rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_DATE);
294 							rtl::OUStringBuffer sBuffer;
295 							rExport.GetMM100UnitConverter().convertDateTime(sBuffer, fTempValue);
296 							rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_DATE_VALUE, sBuffer.makeStringAndClear());
297 							bSetAttributes = sal_True;
298 						}
299 					}
300 					break;
301 				case NUMBERFORMAT_TIME:
302 					{
303 						rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_TIME);
304 						rtl::OUStringBuffer sBuffer;
305 						rExport.GetMM100UnitConverter().convertTime(sBuffer, fTempValue);
306 						rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_TIME_VALUE, sBuffer.makeStringAndClear());
307 						bSetAttributes = sal_True;
308 					}
309 					break;
310 			}
311 		}
312 	}
313 	if (!bSetAttributes)
314 	{
315 		rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_FLOAT);
316 		rtl::OUStringBuffer sBuffer;
317 		SvXMLUnitConverter::convertDouble(sBuffer, fValue);
318 		rtl::OUString sNumValue(sBuffer.makeStringAndClear());
319 		if (sNumValue.getLength())
320 			rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE, sNumValue);
321 	}
322 }
323 
324 
WriteValueCell(const ScBaseCell * pCell,const String & sValue)325 void ScChangeTrackingExportHelper::WriteValueCell(const ScBaseCell* pCell, const String& sValue)
326 {
327 	const ScValueCell* pValueCell = static_cast<const ScValueCell*>(pCell);
328 	if (pValueCell)
329 	{
330 		SetValueAttributes(pValueCell->GetValue(), sValue);
331 		SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_CHANGE_TRACK_TABLE_CELL, sal_True, sal_True);
332 /*		if (sValue.Len())
333 		{
334 			SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TEXT, XML_P, sal_True, sal_False);
335 			sal_Bool bPrevCharWasSpace(sal_True);
336 			rExport.GetTextParagraphExport()->exportText(sValue, bPrevCharWasSpace);
337 		}*/
338 	}
339 }
340 
WriteStringCell(const ScBaseCell * pCell)341 void ScChangeTrackingExportHelper::WriteStringCell(const ScBaseCell* pCell)
342 {
343 	const ScStringCell* pStringCell = static_cast<const ScStringCell*>(pCell);
344 	if (pStringCell)
345 	{
346 		String sString;
347 		pStringCell->GetString(sString);
348 		rtl::OUString sOUString(sString);
349 		rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING);
350 		SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_CHANGE_TRACK_TABLE_CELL, sal_True, sal_True);
351 		if (sOUString.getLength())
352 		{
353 			SvXMLElementExport aElemP(rExport, XML_NAMESPACE_TEXT, XML_P, sal_True, sal_False);
354 			sal_Bool bPrevCharWasSpace(sal_True);
355 			rExport.GetTextParagraphExport()->exportText(sOUString, bPrevCharWasSpace);
356 		}
357 	}
358 }
359 
WriteEditCell(const ScBaseCell * pCell)360 void ScChangeTrackingExportHelper::WriteEditCell(const ScBaseCell* pCell)
361 {
362 	const ScEditCell* pEditCell = static_cast<const ScEditCell*>(pCell);
363 	if (pEditCell)
364 	{
365 		String sString;
366 		pEditCell->GetString(sString);
367 		rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING);
368 		SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_CHANGE_TRACK_TABLE_CELL, sal_True, sal_True);
369 		if (sString.Len())
370 		{
371 			if (!pEditTextObj)
372 			{
373 				pEditTextObj = new ScEditEngineTextObj();
374 				xText.set(pEditTextObj);
375 			}
376 			pEditTextObj->SetText(*(pEditCell->GetData()));
377 			if (xText.is())
378 				rExport.GetTextParagraphExport()->exportText(xText, sal_False, sal_False);
379 		}
380 	}
381 }
382 
WriteFormulaCell(const ScBaseCell * pCell,const String & sValue)383 void ScChangeTrackingExportHelper::WriteFormulaCell(const ScBaseCell* pCell, const String& sValue)
384 {
385 	ScBaseCell* pBaseCell = const_cast<ScBaseCell*>(pCell);
386 	ScFormulaCell* pFormulaCell = static_cast<ScFormulaCell*>(pBaseCell);
387 	if (pFormulaCell)
388 	{
389 		rtl::OUString sAddress;
390         const ScDocument* pDoc = rExport.GetDocument();
391 		ScRangeStringConverter::GetStringFromAddress(sAddress, pFormulaCell->aPos, pDoc, ::formula::FormulaGrammar::CONV_OOO);
392 		rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CELL_ADDRESS, sAddress);
393         const formula::FormulaGrammar::Grammar eGrammar = pDoc->GetStorageGrammar();
394         sal_uInt16 nNamespacePrefix = (eGrammar == formula::FormulaGrammar::GRAM_ODFF ? XML_NAMESPACE_OF : XML_NAMESPACE_OOOC);
395 		String sFormula;
396 		pFormulaCell->GetFormula(sFormula, eGrammar);
397 		rtl::OUString sOUFormula(sFormula);
398 		sal_uInt8 nMatrixFlag(pFormulaCell->GetMatrixFlag());
399 		if (nMatrixFlag)
400 		{
401 			if (nMatrixFlag == MM_FORMULA)
402 			{
403 				SCCOL nColumns;
404 				SCROW nRows;
405 				pFormulaCell->GetMatColsRows(nColumns, nRows);
406 				rtl::OUStringBuffer sColumns;
407 				rtl::OUStringBuffer sRows;
408 				SvXMLUnitConverter::convertNumber(sColumns, static_cast<sal_Int32>(nColumns));
409 				SvXMLUnitConverter::convertNumber(sRows, static_cast<sal_Int32>(nRows));
410 				rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_MATRIX_COLUMNS_SPANNED, sColumns.makeStringAndClear());
411 				rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_MATRIX_ROWS_SPANNED, sRows.makeStringAndClear());
412 			}
413 			else
414 			{
415 				rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MATRIX_COVERED, XML_TRUE);
416 			}
417 			rtl::OUString sMatrixFormula = sOUFormula.copy(1, sOUFormula.getLength() - 2);
418             rtl::OUString sQValue = rExport.GetNamespaceMap().GetQNameByKey( nNamespacePrefix, sMatrixFormula, sal_False );
419 			rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FORMULA, sQValue);
420 		}
421 		else
422         {
423             rtl::OUString sQValue = rExport.GetNamespaceMap().GetQNameByKey( nNamespacePrefix, sFormula, sal_False );
424 			rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FORMULA, sQValue);
425         }
426 		if (pFormulaCell->IsValue())
427 		{
428 			SetValueAttributes(pFormulaCell->GetValue(), sValue);
429 			SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_CHANGE_TRACK_TABLE_CELL, sal_True, sal_True);
430 		}
431 		else
432 		{
433 			rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING);
434 			String sCellValue;
435 			pFormulaCell->GetString(sCellValue);
436 			rtl::OUString sOUValue(sCellValue);
437 			SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_CHANGE_TRACK_TABLE_CELL, sal_True, sal_True);
438 			if (sOUValue.getLength())
439 			{
440 				SvXMLElementExport aElemP(rExport, XML_NAMESPACE_TEXT, XML_P, sal_True, sal_False);
441 				sal_Bool bPrevCharWasSpace(sal_True);
442 				rExport.GetTextParagraphExport()->exportText(sOUValue, bPrevCharWasSpace);
443 			}
444 		}
445 	}
446 }
447 
WriteCell(const ScBaseCell * pCell,const String & sValue)448 void ScChangeTrackingExportHelper::WriteCell(const ScBaseCell* pCell, const String& sValue)
449 {
450 	if (pCell)
451 	{
452 		switch (pCell->GetCellType())
453 		{
454 			case CELLTYPE_NONE:
455 				WriteEmptyCell();
456 				break;
457 			case CELLTYPE_VALUE:
458 				WriteValueCell(pCell, sValue);
459 				break;
460 			case CELLTYPE_STRING:
461 				WriteStringCell(pCell);
462 				break;
463 			case CELLTYPE_EDIT:
464 				WriteEditCell(pCell);
465 				break;
466 			case CELLTYPE_FORMULA:
467 				WriteFormulaCell(pCell, sValue);
468 				break;
469             default:
470             {
471                 // added to avoid warnings
472             }
473 		}
474 	}
475 	else
476 		WriteEmptyCell();
477 }
478 
WriteContentChange(ScChangeAction * pAction)479 void ScChangeTrackingExportHelper::WriteContentChange(ScChangeAction* pAction)
480 {
481 	SvXMLElementExport aElemChange(rExport, XML_NAMESPACE_TABLE, XML_CELL_CONTENT_CHANGE, sal_True, sal_True);
482 	const ScChangeAction* pConstAction = pAction;
483 	WriteBigRange(pConstAction->GetBigRange(), XML_CELL_ADDRESS);
484 	WriteChangeInfo(pAction);
485 	WriteDependings(pAction);
486 	{
487 		ScChangeActionContent* pPrevAction = static_cast<ScChangeActionContent*>(pAction)->GetPrevContent();
488 		if (pPrevAction)
489 			rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ID, GetChangeID(pPrevAction->GetActionNumber()));
490 		SvXMLElementExport aElemPrev(rExport, XML_NAMESPACE_TABLE, XML_PREVIOUS, sal_True, sal_True);
491 		String sValue;
492 		static_cast<ScChangeActionContent*>(pAction)->GetOldString(sValue);
493 		WriteCell(static_cast<ScChangeActionContent*>(pAction)->GetOldCell(), sValue);
494 	}
495 }
496 
AddInsertionAttributes(const ScChangeAction * pConstAction)497 void ScChangeTrackingExportHelper::AddInsertionAttributes(const ScChangeAction* pConstAction)
498 {
499 	sal_Int32 nPosition(0);
500 	sal_Int32 nCount(0);
501 	sal_Int32 nStartPosition(0);
502 	sal_Int32 nEndPosition(0);
503 	sal_Int32 nStartColumn;
504 	sal_Int32 nEndColumn;
505 	sal_Int32 nStartRow;
506 	sal_Int32 nEndRow;
507 	sal_Int32 nStartSheet;
508 	sal_Int32 nEndSheet;
509 	const ScBigRange& rBigRange = pConstAction->GetBigRange();
510 	rBigRange.GetVars(nStartColumn, nStartRow, nStartSheet,
511 		nEndColumn, nEndRow, nEndSheet);
512 	switch (pConstAction->GetType())
513 	{
514 		case SC_CAT_INSERT_COLS :
515 		{
516 			rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, XML_COLUMN);
517 			nStartPosition = nStartColumn;
518 			nEndPosition = nEndColumn;
519 		}
520 		break;
521 		case SC_CAT_INSERT_ROWS :
522 		{
523 			rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, XML_ROW);
524 			nStartPosition = nStartRow;
525 			nEndPosition = nEndRow;
526 		}
527 		break;
528 		case SC_CAT_INSERT_TABS :
529 		{
530 			rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, XML_TABLE);
531 			nStartPosition = nStartSheet;
532 			nEndPosition = nEndSheet;
533 		}
534 		break;
535 		default :
536 		{
537 			DBG_ERROR("wrong insertion type");
538 		}
539 		break;
540 	}
541 	nPosition = nStartPosition;
542 	nCount = nEndPosition - nStartPosition + 1;
543 	rtl::OUStringBuffer sBuffer;
544 	SvXMLUnitConverter::convertNumber(sBuffer, nPosition);
545 	rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_POSITION, sBuffer.makeStringAndClear());
546 	DBG_ASSERT(nCount > 0, "wrong insertion count");
547 	if (nCount > 1)
548 	{
549 		SvXMLUnitConverter::convertNumber(sBuffer, nCount);
550 		rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_COUNT, sBuffer.makeStringAndClear());
551 	}
552 	if (pConstAction->GetType() != SC_CAT_INSERT_TABS)
553 	{
554 		SvXMLUnitConverter::convertNumber(sBuffer, nStartSheet);
555 		rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE, sBuffer.makeStringAndClear());
556 	}
557 }
558 
WriteInsertion(ScChangeAction * pAction)559 void ScChangeTrackingExportHelper::WriteInsertion(ScChangeAction* pAction)
560 {
561 	AddInsertionAttributes(pAction);
562 	SvXMLElementExport aElemChange(rExport, XML_NAMESPACE_TABLE, XML_INSERTION, sal_True, sal_True);
563 	WriteChangeInfo(pAction);
564 	WriteDependings(pAction);
565 }
566 
AddDeletionAttributes(const ScChangeActionDel * pDelAction,const ScChangeActionDel *)567 void ScChangeTrackingExportHelper::AddDeletionAttributes(const ScChangeActionDel* pDelAction, const ScChangeActionDel* /* pLastAction */)
568 {
569 	sal_Int32 nPosition(0);
570 	const ScBigRange& rBigRange = pDelAction->GetBigRange();
571 	sal_Int32 nStartColumn(0);
572 	sal_Int32 nEndColumn(0);
573 	sal_Int32 nStartRow(0);
574 	sal_Int32 nEndRow(0);
575 	sal_Int32 nStartSheet(0);
576 	sal_Int32 nEndSheet(0);
577 	rBigRange.GetVars(nStartColumn, nStartRow, nStartSheet,
578 		nEndColumn, nEndRow, nEndSheet);
579 	switch (pDelAction->GetType())
580 	{
581 		case SC_CAT_DELETE_COLS :
582 		{
583 			rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, XML_COLUMN);
584 			nPosition = nStartColumn;
585 		}
586 		break;
587 		case SC_CAT_DELETE_ROWS :
588 		{
589 			rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, XML_ROW);
590 			nPosition = nStartRow;
591 		}
592 		break;
593 		case SC_CAT_DELETE_TABS :
594 		{
595 			rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, XML_TABLE);
596 			nPosition = nStartSheet;
597 			//DBG_ERROR("not implemented feature");
598 		}
599 		break;
600 		default :
601 		{
602 			DBG_ERROR("wrong deletion type");
603 		}
604 		break;
605 	}
606 	rtl::OUStringBuffer sBuffer;
607 	SvXMLUnitConverter::convertNumber(sBuffer, nPosition);
608 	rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_POSITION, sBuffer.makeStringAndClear());
609 	if (pDelAction->GetType() != SC_CAT_DELETE_TABS)
610 	{
611 		SvXMLUnitConverter::convertNumber(sBuffer, nStartSheet);
612 		rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE, sBuffer.makeStringAndClear());
613 		if (pDelAction->IsMultiDelete() && !pDelAction->GetDx() && !pDelAction->GetDy())
614 		{
615 			const ScChangeAction* p = pDelAction->GetNext();
616 			sal_Bool bAll(sal_False);
617 			sal_Int32 nSlavesCount (1);
618 			while (!bAll && p)
619 			{
620 				if ( !p || p->GetType() != pDelAction->GetType() )
621 					bAll = sal_True;
622 				else
623 				{
624 					const ScChangeActionDel* pDel = (const ScChangeActionDel*) p;
625 					if ( (pDel->GetDx() > pDelAction->GetDx() || pDel->GetDy() > pDelAction->GetDy()) &&
626 							pDel->GetBigRange() == pDelAction->GetBigRange() )
627 					{
628 						++nSlavesCount;
629 						p = p->GetNext();
630 					}
631 					else
632 						bAll = sal_True;
633 				}
634 			}
635 
636 			SvXMLUnitConverter::convertNumber(sBuffer, nSlavesCount);
637 			rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MULTI_DELETION_SPANNED, sBuffer.makeStringAndClear());
638 		}
639 	}
640 }
641 
WriteCutOffs(const ScChangeActionDel * pAction)642 void ScChangeTrackingExportHelper::WriteCutOffs(const ScChangeActionDel* pAction)
643 {
644 	const ScChangeActionIns* pCutOffIns = pAction->GetCutOffInsert();
645 	const ScChangeActionDelMoveEntry* pLinkMove = pAction->GetFirstMoveEntry();
646 	if (pCutOffIns || pLinkMove)
647 	{
648 		SvXMLElementExport aCutOffsElem (rExport, XML_NAMESPACE_TABLE, XML_CUT_OFFS, sal_True, sal_True);
649 		rtl::OUStringBuffer sBuffer;
650 		if (pCutOffIns)
651 		{
652 			rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ID, GetChangeID(pCutOffIns->GetActionNumber()));
653 			SvXMLUnitConverter::convertNumber(sBuffer, static_cast<sal_Int32>(pAction->GetCutOffCount()));
654 			rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_POSITION, sBuffer.makeStringAndClear());
655 			SvXMLElementExport aInsertCutOffElem (rExport, XML_NAMESPACE_TABLE, XML_INSERTION_CUT_OFF, sal_True, sal_True);
656 		}
657 		while (pLinkMove)
658 		{
659 			rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ID, GetChangeID(pLinkMove->GetAction()->GetActionNumber()));
660 			if (pLinkMove->GetCutOffFrom() == pLinkMove->GetCutOffTo())
661 			{
662 				SvXMLUnitConverter::convertNumber(sBuffer, static_cast<sal_Int32>(pLinkMove->GetCutOffFrom()));
663 				rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_POSITION, sBuffer.makeStringAndClear());
664 			}
665 			else
666 			{
667 				SvXMLUnitConverter::convertNumber(sBuffer, static_cast<sal_Int32>(pLinkMove->GetCutOffFrom()));
668 				rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_START_POSITION, sBuffer.makeStringAndClear());
669 				SvXMLUnitConverter::convertNumber(sBuffer, static_cast<sal_Int32>(pLinkMove->GetCutOffTo()));
670 				rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_END_POSITION, sBuffer.makeStringAndClear());
671 			}
672 			SvXMLElementExport aMoveCutOffElem (rExport, XML_NAMESPACE_TABLE, XML_MOVEMENT_CUT_OFF, sal_True, sal_True);
673 			pLinkMove = pLinkMove->GetNext();
674 		}
675 	}
676 }
677 
WriteDeletion(ScChangeAction * pAction)678 void ScChangeTrackingExportHelper::WriteDeletion(ScChangeAction* pAction)
679 {
680 	ScChangeActionDel* pDelAction = static_cast<ScChangeActionDel*> (pAction);
681 	AddDeletionAttributes(pDelAction, pDelAction);
682 	SvXMLElementExport aElemChange(rExport, XML_NAMESPACE_TABLE, XML_DELETION, sal_True, sal_True);
683 	WriteChangeInfo(pDelAction);
684 	WriteDependings(pDelAction);
685 	WriteCutOffs(pDelAction);
686 }
687 
WriteMovement(ScChangeAction * pAction)688 void ScChangeTrackingExportHelper::WriteMovement(ScChangeAction* pAction)
689 {
690 	const ScChangeActionMove* pMoveAction = static_cast<ScChangeActionMove*> (pAction);
691 	SvXMLElementExport aElemChange(rExport, XML_NAMESPACE_TABLE, XML_MOVEMENT, sal_True, sal_True);
692 	WriteBigRange(pMoveAction->GetFromRange(), XML_SOURCE_RANGE_ADDRESS);
693 	WriteBigRange(pMoveAction->GetBigRange(), XML_TARGET_RANGE_ADDRESS);
694 	WriteChangeInfo(pAction);
695 	WriteDependings(pAction);
696 }
697 
WriteRejection(ScChangeAction * pAction)698 void ScChangeTrackingExportHelper::WriteRejection(ScChangeAction* pAction)
699 {
700 	SvXMLElementExport aElemChange(rExport, XML_NAMESPACE_TABLE, XML_REJECTION, sal_True, sal_True);
701 	WriteChangeInfo(pAction);
702 	WriteDependings(pAction);
703 }
704 
CollectCellAutoStyles(const ScBaseCell * pBaseCell)705 void ScChangeTrackingExportHelper::CollectCellAutoStyles(const ScBaseCell* pBaseCell)
706 {
707 	if (pBaseCell && (pBaseCell->GetCellType() == CELLTYPE_EDIT))
708 	{
709 		const ScEditCell* pEditCell = static_cast<const ScEditCell*>(pBaseCell);
710 		if (pEditCell)
711 		{
712 			if (!pEditTextObj)
713 			{
714 				pEditTextObj = new ScEditEngineTextObj();
715 				xText.set(pEditTextObj);
716 			}
717 			pEditTextObj->SetText(*(pEditCell->GetData()));
718 			if (xText.is())
719 				rExport.GetTextParagraphExport()->collectTextAutoStyles(xText, sal_False, sal_False);
720 		}
721 	}
722 }
723 
CollectActionAutoStyles(ScChangeAction * pAction)724 void ScChangeTrackingExportHelper::CollectActionAutoStyles(ScChangeAction* pAction)
725 {
726 	if (pAction->GetType() == SC_CAT_CONTENT)
727 	{
728 		if (pChangeTrack->IsGenerated(pAction->GetActionNumber()))
729 	 		CollectCellAutoStyles(static_cast<ScChangeActionContent*>(pAction)->GetNewCell());
730 		else
731 		{
732 	 		CollectCellAutoStyles(static_cast<ScChangeActionContent*>(pAction)->GetOldCell());
733 			if (static_cast<ScChangeActionContent*>(pAction)->IsTopContent() && pAction->IsDeletedIn())
734 	 			CollectCellAutoStyles(static_cast<ScChangeActionContent*>(pAction)->GetNewCell());
735 		}
736 	}
737 }
738 
WorkWithChangeAction(ScChangeAction * pAction)739 void ScChangeTrackingExportHelper::WorkWithChangeAction(ScChangeAction* pAction)
740 {
741 	rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ID, GetChangeID(pAction->GetActionNumber()));
742 	GetAcceptanceState(pAction);
743 	if (pAction->IsRejecting())
744 		rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_REJECTING_CHANGE_ID, GetChangeID(pAction->GetRejectAction()));
745 	if (pAction->GetType() == SC_CAT_CONTENT)
746 		WriteContentChange(pAction);
747 	else if (pAction->IsInsertType())
748 		WriteInsertion(pAction);
749 	else if (pAction->IsDeleteType())
750 		WriteDeletion(pAction);
751 	else if (pAction->GetType() == SC_CAT_MOVE)
752 		WriteMovement(pAction);
753 	else if (pAction->GetType() == SC_CAT_REJECT)
754 		WriteRejection(pAction);
755 	else
756 	{
757 		DBG_ERROR("not a writeable type");
758 	}
759 	rExport.CheckAttrList();
760 }
761 
CollectAutoStyles()762 void ScChangeTrackingExportHelper::CollectAutoStyles()
763 {
764 	if (pChangeTrack)
765 	{
766 		sal_uInt32 nCount (pChangeTrack->GetActionMax());
767 		if (nCount)
768 		{
769 			ScChangeAction* pAction = pChangeTrack->GetFirst();
770 			CollectActionAutoStyles(pAction);
771 			ScChangeAction* pLastAction = pChangeTrack->GetLast();
772 			while (pAction != pLastAction)
773 			{
774 				pAction = pAction->GetNext();
775 				CollectActionAutoStyles(pAction);
776 			}
777 			pAction = pChangeTrack->GetFirstGenerated();
778 			while (pAction)
779 			{
780 				CollectActionAutoStyles(pAction);
781 				pAction = pAction->GetNext();
782 			}
783 		}
784 	}
785 }
786 
CollectAndWriteChanges()787 void ScChangeTrackingExportHelper::CollectAndWriteChanges()
788 {
789 	if (pChangeTrack)
790 	{
791 /*		if (pChangeTrack->IsProtected())
792 		{
793 			rtl::OUStringBuffer aBuffer;
794 			SvXMLUnitConverter::encodeBase64(aBuffer, pChangeTrack->GetProtection());
795 			if (aBuffer.getLength())
796 				rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY, aBuffer.makeStringAndClear());
797 		}*/
798 		SvXMLElementExport aCangeListElem(rExport, XML_NAMESPACE_TABLE, XML_TRACKED_CHANGES, sal_True, sal_True);
799 		{
800 			ScChangeAction* pAction = pChangeTrack->GetFirst();
801 			if (pAction)
802 			{
803 				WorkWithChangeAction(pAction);
804 				ScChangeAction* pLastAction = pChangeTrack->GetLast();
805 				while (pAction != pLastAction)
806 				{
807 					pAction = pAction->GetNext();
808 					WorkWithChangeAction(pAction);
809 				}
810 			}
811 		}
812 	}
813 }
814