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 101 : ScChangeTrackingExportHelper::ScChangeTrackingExportHelper(ScXMLExport& rTempExport)
47 : : rExport(rTempExport),
48 : pChangeTrack(NULL),
49 : pEditTextObj(NULL),
50 : pDependings(NULL),
51 101 : sChangeIDPrefix(SC_CHANGE_ID_PREFIX)
52 : {
53 101 : pChangeTrack = rExport.GetDocument() ? rExport.GetDocument()->GetChangeTrack() : NULL;
54 101 : pDependings = new ScChangeActionMap();
55 101 : }
56 :
57 196 : ScChangeTrackingExportHelper::~ScChangeTrackingExportHelper()
58 : {
59 98 : if (pDependings)
60 98 : delete pDependings;
61 98 : }
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 = bool( rExport.getExportFlags() & SvXMLExportFlags::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 & css::util::NumberFormat::DEFINED) == css::util::NumberFormat::DEFINED)
244 0 : nType -= css::util::NumberFormat::DEFINED;
245 0 : switch(nType)
246 : {
247 : case css::util::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 css::util::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 0 : void ScChangeTrackingExportHelper::WriteValueCell(const ScCellValue& rCell, const OUString& sValue)
283 : {
284 : OSL_ASSERT(rCell.meType == CELLTYPE_VALUE);
285 :
286 0 : SetValueAttributes(rCell.mfValue, sValue);
287 0 : SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_CHANGE_TRACK_TABLE_CELL, true, true);
288 0 : }
289 :
290 0 : void ScChangeTrackingExportHelper::WriteStringCell(const ScCellValue& rCell)
291 : {
292 : OSL_ASSERT(rCell.meType == CELLTYPE_STRING);
293 :
294 0 : rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING);
295 0 : SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_CHANGE_TRACK_TABLE_CELL, true, true);
296 0 : if (!rCell.mpString->isEmpty())
297 : {
298 0 : SvXMLElementExport aElemP(rExport, XML_NAMESPACE_TEXT, XML_P, true, false);
299 0 : bool bPrevCharWasSpace(true);
300 0 : rExport.GetTextParagraphExport()->exportText(rCell.mpString->getString(), bPrevCharWasSpace);
301 0 : }
302 0 : }
303 :
304 0 : void ScChangeTrackingExportHelper::WriteEditCell(const ScCellValue& rCell)
305 : {
306 : OSL_ASSERT(rCell.meType == CELLTYPE_EDIT);
307 :
308 0 : OUString sString;
309 0 : if (rCell.mpEditText)
310 0 : sString = ScEditUtil::GetString(*rCell.mpEditText, rExport.GetDocument());
311 :
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 (rCell.mpEditText && !sString.isEmpty())
315 : {
316 0 : if (!pEditTextObj)
317 : {
318 0 : pEditTextObj = new ScEditEngineTextObj();
319 0 : xText.set(pEditTextObj);
320 : }
321 0 : pEditTextObj->SetText(*rCell.mpEditText);
322 0 : if (xText.is())
323 0 : rExport.GetTextParagraphExport()->exportText(xText, false, false);
324 0 : }
325 0 : }
326 :
327 0 : void ScChangeTrackingExportHelper::WriteFormulaCell(const ScCellValue& rCell, const OUString& sValue)
328 : {
329 : OSL_ASSERT(rCell.meType == CELLTYPE_FORMULA);
330 :
331 0 : ScFormulaCell* pFormulaCell = rCell.mpFormula;
332 0 : OUString sAddress;
333 0 : const ScDocument* pDoc = rExport.GetDocument();
334 0 : ScRangeStringConverter::GetStringFromAddress(sAddress, pFormulaCell->aPos, pDoc, ::formula::FormulaGrammar::CONV_OOO);
335 0 : rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CELL_ADDRESS, sAddress);
336 0 : const formula::FormulaGrammar::Grammar eGrammar = pDoc->GetStorageGrammar();
337 0 : sal_uInt16 nNamespacePrefix = (eGrammar == formula::FormulaGrammar::GRAM_ODFF ? XML_NAMESPACE_OF : XML_NAMESPACE_OOOC);
338 0 : OUString sFormula;
339 0 : pFormulaCell->GetFormula(sFormula, eGrammar);
340 0 : sal_uInt8 nMatrixFlag(pFormulaCell->GetMatrixFlag());
341 0 : if (nMatrixFlag)
342 : {
343 0 : if (nMatrixFlag == MM_FORMULA)
344 : {
345 : SCCOL nColumns;
346 : SCROW nRows;
347 0 : pFormulaCell->GetMatColsRows(nColumns, nRows);
348 0 : OUStringBuffer sColumns;
349 0 : OUStringBuffer sRows;
350 0 : ::sax::Converter::convertNumber(sColumns, static_cast<sal_Int32>(nColumns));
351 0 : ::sax::Converter::convertNumber(sRows, static_cast<sal_Int32>(nRows));
352 0 : rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_MATRIX_COLUMNS_SPANNED, sColumns.makeStringAndClear());
353 0 : rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_MATRIX_ROWS_SPANNED, sRows.makeStringAndClear());
354 : }
355 : else
356 : {
357 0 : rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MATRIX_COVERED, XML_TRUE);
358 : }
359 0 : OUString sMatrixFormula = sFormula.copy(1, sFormula.getLength() - 2);
360 0 : OUString sQValue = rExport.GetNamespaceMap().GetQNameByKey( nNamespacePrefix, sMatrixFormula, false );
361 0 : rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FORMULA, sQValue);
362 : }
363 : else
364 : {
365 0 : OUString sQValue = rExport.GetNamespaceMap().GetQNameByKey( nNamespacePrefix, sFormula, false );
366 0 : rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FORMULA, sQValue);
367 : }
368 0 : if (pFormulaCell->IsValue())
369 : {
370 0 : SetValueAttributes(pFormulaCell->GetValue(), sValue);
371 0 : SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_CHANGE_TRACK_TABLE_CELL, true, true);
372 : }
373 : else
374 : {
375 0 : rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING);
376 0 : OUString sCellValue = pFormulaCell->GetString().getString();
377 0 : SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_CHANGE_TRACK_TABLE_CELL, true, true);
378 0 : if (!sCellValue.isEmpty())
379 : {
380 0 : SvXMLElementExport aElemP(rExport, XML_NAMESPACE_TEXT, XML_P, true, false);
381 0 : bool bPrevCharWasSpace(true);
382 0 : rExport.GetTextParagraphExport()->exportText(sCellValue, bPrevCharWasSpace);
383 0 : }
384 0 : }
385 0 : }
386 :
387 0 : void ScChangeTrackingExportHelper::WriteCell(const ScCellValue& rCell, const OUString& sValue)
388 : {
389 0 : if (rCell.isEmpty())
390 : {
391 0 : WriteEmptyCell();
392 0 : return;
393 : }
394 :
395 0 : switch (rCell.meType)
396 : {
397 : case CELLTYPE_VALUE:
398 0 : WriteValueCell(rCell, sValue);
399 0 : break;
400 : case CELLTYPE_STRING:
401 0 : WriteStringCell(rCell);
402 0 : break;
403 : case CELLTYPE_EDIT:
404 0 : WriteEditCell(rCell);
405 0 : break;
406 : case CELLTYPE_FORMULA:
407 0 : WriteFormulaCell(rCell, sValue);
408 0 : break;
409 : default:
410 0 : WriteEmptyCell();
411 : }
412 : }
413 :
414 0 : void ScChangeTrackingExportHelper::WriteContentChange(ScChangeAction* pAction)
415 : {
416 0 : SvXMLElementExport aElemChange(rExport, XML_NAMESPACE_TABLE, XML_CELL_CONTENT_CHANGE, true, true);
417 0 : const ScChangeAction* pConstAction = pAction;
418 0 : WriteBigRange(pConstAction->GetBigRange(), XML_CELL_ADDRESS);
419 0 : WriteChangeInfo(pAction);
420 0 : WriteDependings(pAction);
421 : {
422 0 : ScChangeActionContent* pPrevAction = static_cast<ScChangeActionContent*>(pAction)->GetPrevContent();
423 0 : if (pPrevAction)
424 0 : rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ID, GetChangeID(pPrevAction->GetActionNumber()));
425 0 : SvXMLElementExport aElemPrev(rExport, XML_NAMESPACE_TABLE, XML_PREVIOUS, true, true);
426 0 : OUString sValue;
427 0 : static_cast<ScChangeActionContent*>(pAction)->GetOldString(sValue, rExport.GetDocument());
428 0 : WriteCell(static_cast<ScChangeActionContent*>(pAction)->GetOldCell(), sValue);
429 0 : }
430 0 : }
431 :
432 0 : void ScChangeTrackingExportHelper::AddInsertionAttributes(const ScChangeAction* pConstAction)
433 : {
434 0 : sal_Int32 nPosition(0);
435 0 : sal_Int32 nCount(0);
436 0 : sal_Int32 nStartPosition(0);
437 0 : sal_Int32 nEndPosition(0);
438 : sal_Int32 nStartColumn;
439 : sal_Int32 nEndColumn;
440 : sal_Int32 nStartRow;
441 : sal_Int32 nEndRow;
442 : sal_Int32 nStartSheet;
443 : sal_Int32 nEndSheet;
444 0 : const ScBigRange& rBigRange = pConstAction->GetBigRange();
445 : rBigRange.GetVars(nStartColumn, nStartRow, nStartSheet,
446 0 : nEndColumn, nEndRow, nEndSheet);
447 0 : switch (pConstAction->GetType())
448 : {
449 : case SC_CAT_INSERT_COLS :
450 : {
451 0 : rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, XML_COLUMN);
452 0 : nStartPosition = nStartColumn;
453 0 : nEndPosition = nEndColumn;
454 : }
455 0 : break;
456 : case SC_CAT_INSERT_ROWS :
457 : {
458 0 : rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, XML_ROW);
459 0 : nStartPosition = nStartRow;
460 0 : nEndPosition = nEndRow;
461 : }
462 0 : break;
463 : case SC_CAT_INSERT_TABS :
464 : {
465 0 : rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, XML_TABLE);
466 0 : nStartPosition = nStartSheet;
467 0 : nEndPosition = nEndSheet;
468 : }
469 0 : break;
470 : default :
471 : {
472 : OSL_FAIL("wrong insertion type");
473 : }
474 0 : break;
475 : }
476 0 : nPosition = nStartPosition;
477 0 : nCount = nEndPosition - nStartPosition + 1;
478 0 : OUStringBuffer sBuffer;
479 0 : ::sax::Converter::convertNumber(sBuffer, nPosition);
480 0 : rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_POSITION, sBuffer.makeStringAndClear());
481 : OSL_ENSURE(nCount > 0, "wrong insertion count");
482 0 : if (nCount > 1)
483 : {
484 0 : ::sax::Converter::convertNumber(sBuffer, nCount);
485 0 : rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_COUNT, sBuffer.makeStringAndClear());
486 : }
487 0 : if (pConstAction->GetType() != SC_CAT_INSERT_TABS)
488 : {
489 0 : ::sax::Converter::convertNumber(sBuffer, nStartSheet);
490 0 : rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE, sBuffer.makeStringAndClear());
491 0 : }
492 0 : }
493 :
494 0 : void ScChangeTrackingExportHelper::WriteInsertion(ScChangeAction* pAction)
495 : {
496 0 : AddInsertionAttributes(pAction);
497 0 : SvXMLElementExport aElemChange(rExport, XML_NAMESPACE_TABLE, XML_INSERTION, true, true);
498 0 : WriteChangeInfo(pAction);
499 0 : WriteDependings(pAction);
500 0 : }
501 :
502 0 : void ScChangeTrackingExportHelper::AddDeletionAttributes(const ScChangeActionDel* pDelAction, const ScChangeActionDel* /* pLastAction */)
503 : {
504 0 : sal_Int32 nPosition(0);
505 0 : const ScBigRange& rBigRange = pDelAction->GetBigRange();
506 0 : sal_Int32 nStartColumn(0);
507 0 : sal_Int32 nEndColumn(0);
508 0 : sal_Int32 nStartRow(0);
509 0 : sal_Int32 nEndRow(0);
510 0 : sal_Int32 nStartSheet(0);
511 0 : sal_Int32 nEndSheet(0);
512 : rBigRange.GetVars(nStartColumn, nStartRow, nStartSheet,
513 0 : nEndColumn, nEndRow, nEndSheet);
514 0 : switch (pDelAction->GetType())
515 : {
516 : case SC_CAT_DELETE_COLS :
517 : {
518 0 : rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, XML_COLUMN);
519 0 : nPosition = nStartColumn;
520 : }
521 0 : break;
522 : case SC_CAT_DELETE_ROWS :
523 : {
524 0 : rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, XML_ROW);
525 0 : nPosition = nStartRow;
526 : }
527 0 : break;
528 : case SC_CAT_DELETE_TABS :
529 : {
530 0 : rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TYPE, XML_TABLE);
531 0 : nPosition = nStartSheet;
532 : }
533 0 : break;
534 : default :
535 : {
536 : OSL_FAIL("wrong deletion type");
537 : }
538 0 : break;
539 : }
540 0 : OUStringBuffer sBuffer;
541 0 : ::sax::Converter::convertNumber(sBuffer, nPosition);
542 0 : rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_POSITION, sBuffer.makeStringAndClear());
543 0 : if (pDelAction->GetType() != SC_CAT_DELETE_TABS)
544 : {
545 0 : ::sax::Converter::convertNumber(sBuffer, nStartSheet);
546 0 : rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE, sBuffer.makeStringAndClear());
547 0 : if (pDelAction->IsMultiDelete() && !pDelAction->GetDx() && !pDelAction->GetDy())
548 : {
549 0 : const ScChangeAction* p = pDelAction->GetNext();
550 0 : bool bAll(false);
551 0 : sal_Int32 nSlavesCount (1);
552 0 : while (!bAll && p)
553 : {
554 0 : if ( !p || p->GetType() != pDelAction->GetType() )
555 0 : bAll = true;
556 : else
557 : {
558 0 : const ScChangeActionDel* pDel = static_cast<const ScChangeActionDel*>(p);
559 0 : if ( (pDel->GetDx() > pDelAction->GetDx() || pDel->GetDy() > pDelAction->GetDy()) &&
560 0 : pDel->GetBigRange() == pDelAction->GetBigRange() )
561 : {
562 0 : ++nSlavesCount;
563 0 : p = p->GetNext();
564 : }
565 : else
566 0 : bAll = true;
567 : }
568 : }
569 :
570 0 : ::sax::Converter::convertNumber(sBuffer, nSlavesCount);
571 0 : rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_MULTI_DELETION_SPANNED, sBuffer.makeStringAndClear());
572 : }
573 0 : }
574 0 : }
575 :
576 0 : void ScChangeTrackingExportHelper::WriteCutOffs(const ScChangeActionDel* pAction)
577 : {
578 0 : const ScChangeActionIns* pCutOffIns = pAction->GetCutOffInsert();
579 0 : const ScChangeActionDelMoveEntry* pLinkMove = pAction->GetFirstMoveEntry();
580 0 : if (pCutOffIns || pLinkMove)
581 : {
582 0 : SvXMLElementExport aCutOffsElem (rExport, XML_NAMESPACE_TABLE, XML_CUT_OFFS, true, true);
583 0 : OUStringBuffer sBuffer;
584 0 : if (pCutOffIns)
585 : {
586 0 : rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ID, GetChangeID(pCutOffIns->GetActionNumber()));
587 : ::sax::Converter::convertNumber(sBuffer,
588 0 : static_cast<sal_Int32>(pAction->GetCutOffCount()));
589 0 : rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_POSITION, sBuffer.makeStringAndClear());
590 0 : SvXMLElementExport aInsertCutOffElem (rExport, XML_NAMESPACE_TABLE, XML_INSERTION_CUT_OFF, true, true);
591 : }
592 0 : while (pLinkMove)
593 : {
594 0 : rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ID, GetChangeID(pLinkMove->GetAction()->GetActionNumber()));
595 0 : if (pLinkMove->GetCutOffFrom() == pLinkMove->GetCutOffTo())
596 : {
597 : ::sax::Converter::convertNumber(sBuffer,
598 0 : static_cast<sal_Int32>(pLinkMove->GetCutOffFrom()));
599 0 : rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_POSITION, sBuffer.makeStringAndClear());
600 : }
601 : else
602 : {
603 : ::sax::Converter::convertNumber(sBuffer,
604 0 : static_cast<sal_Int32>(pLinkMove->GetCutOffFrom()));
605 0 : rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_START_POSITION, sBuffer.makeStringAndClear());
606 : ::sax::Converter::convertNumber(sBuffer,
607 0 : static_cast<sal_Int32>(pLinkMove->GetCutOffTo()));
608 0 : rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_END_POSITION, sBuffer.makeStringAndClear());
609 : }
610 0 : SvXMLElementExport aMoveCutOffElem (rExport, XML_NAMESPACE_TABLE, XML_MOVEMENT_CUT_OFF, true, true);
611 0 : pLinkMove = pLinkMove->GetNext();
612 0 : }
613 : }
614 0 : }
615 :
616 0 : void ScChangeTrackingExportHelper::WriteDeletion(ScChangeAction* pAction)
617 : {
618 0 : ScChangeActionDel* pDelAction = static_cast<ScChangeActionDel*> (pAction);
619 0 : AddDeletionAttributes(pDelAction, pDelAction);
620 0 : SvXMLElementExport aElemChange(rExport, XML_NAMESPACE_TABLE, XML_DELETION, true, true);
621 0 : WriteChangeInfo(pDelAction);
622 0 : WriteDependings(pDelAction);
623 0 : WriteCutOffs(pDelAction);
624 0 : }
625 :
626 0 : void ScChangeTrackingExportHelper::WriteMovement(ScChangeAction* pAction)
627 : {
628 0 : const ScChangeActionMove* pMoveAction = static_cast<ScChangeActionMove*> (pAction);
629 0 : SvXMLElementExport aElemChange(rExport, XML_NAMESPACE_TABLE, XML_MOVEMENT, true, true);
630 0 : WriteBigRange(pMoveAction->GetFromRange(), XML_SOURCE_RANGE_ADDRESS);
631 0 : WriteBigRange(pMoveAction->GetBigRange(), XML_TARGET_RANGE_ADDRESS);
632 0 : WriteChangeInfo(pAction);
633 0 : WriteDependings(pAction);
634 0 : }
635 :
636 0 : void ScChangeTrackingExportHelper::WriteRejection(ScChangeAction* pAction)
637 : {
638 0 : SvXMLElementExport aElemChange(rExport, XML_NAMESPACE_TABLE, XML_REJECTION, true, true);
639 0 : WriteChangeInfo(pAction);
640 0 : WriteDependings(pAction);
641 0 : }
642 :
643 0 : void ScChangeTrackingExportHelper::CollectCellAutoStyles(const ScCellValue& rCell)
644 : {
645 0 : if (rCell.meType != CELLTYPE_EDIT)
646 0 : return;
647 :
648 0 : if (!pEditTextObj)
649 : {
650 0 : pEditTextObj = new ScEditEngineTextObj();
651 0 : xText.set(pEditTextObj);
652 : }
653 :
654 0 : pEditTextObj->SetText(*rCell.mpEditText);
655 0 : if (xText.is())
656 0 : rExport.GetTextParagraphExport()->collectTextAutoStyles(xText, false, false);
657 : }
658 :
659 0 : void ScChangeTrackingExportHelper::CollectActionAutoStyles(ScChangeAction* pAction)
660 : {
661 0 : if (pAction->GetType() != SC_CAT_CONTENT)
662 0 : return;
663 :
664 0 : if (pChangeTrack->IsGenerated(pAction->GetActionNumber()))
665 0 : CollectCellAutoStyles(static_cast<ScChangeActionContent*>(pAction)->GetNewCell());
666 : else
667 : {
668 0 : CollectCellAutoStyles(static_cast<ScChangeActionContent*>(pAction)->GetOldCell());
669 0 : if (static_cast<ScChangeActionContent*>(pAction)->IsTopContent() && pAction->IsDeletedIn())
670 0 : CollectCellAutoStyles(static_cast<ScChangeActionContent*>(pAction)->GetNewCell());
671 : }
672 : }
673 :
674 0 : void ScChangeTrackingExportHelper::WorkWithChangeAction(ScChangeAction* pAction)
675 : {
676 0 : rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ID, GetChangeID(pAction->GetActionNumber()));
677 0 : GetAcceptanceState(pAction);
678 0 : if (pAction->IsRejecting())
679 0 : rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_REJECTING_CHANGE_ID, GetChangeID(pAction->GetRejectAction()));
680 0 : if (pAction->GetType() == SC_CAT_CONTENT)
681 0 : WriteContentChange(pAction);
682 0 : else if (pAction->IsInsertType())
683 0 : WriteInsertion(pAction);
684 0 : else if (pAction->IsDeleteType())
685 0 : WriteDeletion(pAction);
686 0 : else if (pAction->GetType() == SC_CAT_MOVE)
687 0 : WriteMovement(pAction);
688 0 : else if (pAction->GetType() == SC_CAT_REJECT)
689 0 : WriteRejection(pAction);
690 : else
691 : {
692 : OSL_FAIL("not a writeable type");
693 : }
694 0 : rExport.CheckAttrList();
695 0 : }
696 :
697 29 : void ScChangeTrackingExportHelper::CollectAutoStyles()
698 : {
699 29 : if (pChangeTrack)
700 : {
701 0 : sal_uInt32 nCount (pChangeTrack->GetActionMax());
702 0 : if (nCount)
703 : {
704 0 : ScChangeAction* pAction = pChangeTrack->GetFirst();
705 0 : CollectActionAutoStyles(pAction);
706 0 : ScChangeAction* pLastAction = pChangeTrack->GetLast();
707 0 : while (pAction != pLastAction)
708 : {
709 0 : pAction = pAction->GetNext();
710 0 : CollectActionAutoStyles(pAction);
711 : }
712 0 : pAction = pChangeTrack->GetFirstGenerated();
713 0 : while (pAction)
714 : {
715 0 : CollectActionAutoStyles(pAction);
716 0 : pAction = pAction->GetNext();
717 : }
718 : }
719 : }
720 29 : }
721 :
722 29 : void ScChangeTrackingExportHelper::CollectAndWriteChanges()
723 : {
724 29 : if (pChangeTrack)
725 : {
726 0 : SvXMLElementExport aCangeListElem(rExport, XML_NAMESPACE_TABLE, XML_TRACKED_CHANGES, true, true);
727 : {
728 0 : ScChangeAction* pAction = pChangeTrack->GetFirst();
729 0 : if (pAction)
730 : {
731 0 : WorkWithChangeAction(pAction);
732 0 : ScChangeAction* pLastAction = pChangeTrack->GetLast();
733 0 : while (pAction != pLastAction)
734 : {
735 0 : pAction = pAction->GetNext();
736 0 : WorkWithChangeAction(pAction);
737 : }
738 : }
739 0 : }
740 : }
741 185 : }
742 :
743 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|