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