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