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