xref: /AOO41X/main/sc/source/filter/xml/XMLChangeTrackingExportHelper.cxx (revision b3f79822e811ac3493b185030a72c3c5a51f32d8)
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