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 "XMLChangeTrackingImportHelper.hxx"
21 : #include "XMLConverter.hxx"
22 : #include "formulacell.hxx"
23 : #include "document.hxx"
24 : #include "chgviset.hxx"
25 : #include "rangeutl.hxx"
26 : #include <tools/datetime.hxx>
27 : #include <osl/diagnose.h>
28 : #include <svl/zforlist.hxx>
29 : #include <sax/tools/converter.hxx>
30 :
31 : #define SC_CHANGE_ID_PREFIX "ct"
32 :
33 0 : ScMyCellInfo::ScMyCellInfo(
34 : const ScCellValue& rCell, const OUString& rFormulaAddress, const OUString& rFormula,
35 : const formula::FormulaGrammar::Grammar eTempGrammar, const OUString& rInputString,
36 : const double& rValue, const sal_uInt16 nTempType, const sal_uInt8 nTempMatrixFlag, const sal_Int32 nTempMatrixCols,
37 : const sal_Int32 nTempMatrixRows ) :
38 : maCell(rCell),
39 : sFormulaAddress(rFormulaAddress),
40 : sFormula(rFormula),
41 : sInputString(rInputString),
42 : fValue(rValue),
43 : nMatrixCols(nTempMatrixCols),
44 : nMatrixRows(nTempMatrixRows),
45 : eGrammar( eTempGrammar),
46 : nType(nTempType),
47 0 : nMatrixFlag(nTempMatrixFlag)
48 : {
49 0 : }
50 :
51 0 : ScMyCellInfo::~ScMyCellInfo() {}
52 :
53 0 : const ScCellValue& ScMyCellInfo::CreateCell( ScDocument* pDoc )
54 : {
55 0 : if (!maCell.isEmpty())
56 0 : return maCell;
57 :
58 0 : if (!sFormula.isEmpty() && !sFormulaAddress.isEmpty())
59 : {
60 0 : ScAddress aPos;
61 0 : sal_Int32 nOffset(0);
62 0 : ScRangeStringConverter::GetAddressFromString(aPos, sFormulaAddress, pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset);
63 0 : maCell.meType = CELLTYPE_FORMULA;
64 0 : maCell.mpFormula = new ScFormulaCell(pDoc, aPos, sFormula, eGrammar, nMatrixFlag);
65 0 : maCell.mpFormula->SetMatColsRows(static_cast<SCCOL>(nMatrixCols), static_cast<SCROW>(nMatrixRows));
66 : }
67 :
68 0 : if ((nType == css::util::NumberFormat::DATE || nType == css::util::NumberFormat::TIME) && sInputString.isEmpty())
69 : {
70 0 : sal_uInt32 nFormat(0);
71 0 : if (nType == css::util::NumberFormat::DATE)
72 0 : nFormat = pDoc->GetFormatTable()->GetStandardFormat( css::util::NumberFormat::DATE, ScGlobal::eLnge );
73 0 : else if (nType == css::util::NumberFormat::TIME)
74 0 : nFormat = pDoc->GetFormatTable()->GetStandardFormat( css::util::NumberFormat::TIME, ScGlobal::eLnge );
75 0 : pDoc->GetFormatTable()->GetInputLineString(fValue, nFormat, sInputString);
76 : }
77 :
78 0 : return maCell;
79 : }
80 :
81 0 : ScMyDeleted::ScMyDeleted()
82 : : nID(0)
83 0 : , pCellInfo(NULL)
84 : {
85 0 : }
86 :
87 0 : ScMyDeleted::~ScMyDeleted()
88 : {
89 0 : delete pCellInfo;
90 0 : }
91 :
92 0 : ScMyGenerated::ScMyGenerated(ScMyCellInfo* pTempCellInfo, const ScBigRange& aTempBigRange)
93 : : aBigRange(aTempBigRange)
94 : , nID(0)
95 0 : , pCellInfo(pTempCellInfo)
96 : {
97 0 : }
98 :
99 0 : ScMyGenerated::~ScMyGenerated()
100 : {
101 0 : delete pCellInfo;
102 0 : }
103 :
104 0 : ScMyBaseAction::ScMyBaseAction(const ScChangeActionType nTempActionType)
105 : : aDependencies(),
106 : aDeletedList(),
107 : nActionNumber(0),
108 : nRejectingNumber(0),
109 : nPreviousAction(0),
110 : nActionType(nTempActionType),
111 0 : nActionState(SC_CAS_VIRGIN)
112 : {
113 0 : }
114 :
115 0 : ScMyBaseAction::~ScMyBaseAction()
116 : {
117 0 : }
118 :
119 0 : ScMyInsAction::ScMyInsAction(const ScChangeActionType nActionTypeP)
120 0 : : ScMyBaseAction(nActionTypeP)
121 : {
122 0 : }
123 :
124 0 : ScMyInsAction::~ScMyInsAction()
125 : {
126 0 : }
127 :
128 0 : ScMyDelAction::ScMyDelAction(const ScChangeActionType nActionTypeP)
129 : : ScMyBaseAction(nActionTypeP),
130 : aGeneratedList(),
131 : pInsCutOff(NULL),
132 : aMoveCutOffs(),
133 0 : nD(0)
134 : {
135 0 : }
136 :
137 0 : ScMyDelAction::~ScMyDelAction()
138 : {
139 0 : if (pInsCutOff)
140 0 : delete pInsCutOff;
141 0 : }
142 :
143 0 : ScMyMoveAction::ScMyMoveAction()
144 : : ScMyBaseAction(SC_CAT_MOVE),
145 : aGeneratedList(),
146 0 : pMoveRanges(NULL)
147 : {
148 0 : }
149 :
150 0 : ScMyMoveAction::~ScMyMoveAction()
151 : {
152 0 : if (pMoveRanges)
153 0 : delete pMoveRanges;
154 0 : }
155 :
156 0 : ScMyContentAction::ScMyContentAction()
157 : : ScMyBaseAction(SC_CAT_CONTENT),
158 0 : pCellInfo(NULL)
159 : {
160 0 : }
161 :
162 0 : ScMyContentAction::~ScMyContentAction()
163 : {
164 0 : delete pCellInfo;
165 0 : }
166 :
167 0 : ScMyRejAction::ScMyRejAction()
168 0 : : ScMyBaseAction(SC_CAT_REJECT)
169 : {
170 0 : }
171 :
172 0 : ScMyRejAction::~ScMyRejAction()
173 : {
174 0 : }
175 :
176 1 : ScXMLChangeTrackingImportHelper::ScXMLChangeTrackingImportHelper() :
177 : aActions(),
178 : pDoc(NULL),
179 : pTrack(NULL),
180 : pCurrentAction(NULL),
181 : sIDPrefix(SC_CHANGE_ID_PREFIX),
182 : nMultiSpanned(0),
183 : nMultiSpannedSlaveCount(0),
184 1 : bChangeTrack(false)
185 : {
186 1 : nPrefixLength = sIDPrefix.getLength();
187 1 : }
188 :
189 1 : ScXMLChangeTrackingImportHelper::~ScXMLChangeTrackingImportHelper()
190 : {
191 1 : }
192 :
193 0 : void ScXMLChangeTrackingImportHelper::StartChangeAction(const ScChangeActionType nActionType)
194 : {
195 : OSL_ENSURE(!pCurrentAction, "a not inserted action");
196 0 : switch (nActionType)
197 : {
198 : case SC_CAT_INSERT_COLS:
199 : case SC_CAT_INSERT_ROWS:
200 : case SC_CAT_INSERT_TABS:
201 : {
202 0 : pCurrentAction = new ScMyInsAction(nActionType);
203 : }
204 0 : break;
205 : case SC_CAT_DELETE_COLS:
206 : case SC_CAT_DELETE_ROWS:
207 : case SC_CAT_DELETE_TABS:
208 : {
209 0 : pCurrentAction = new ScMyDelAction(nActionType);
210 : }
211 0 : break;
212 : case SC_CAT_MOVE:
213 : {
214 0 : pCurrentAction = new ScMyMoveAction();
215 : }
216 0 : break;
217 : case SC_CAT_CONTENT:
218 : {
219 0 : pCurrentAction = new ScMyContentAction();
220 : }
221 0 : break;
222 : case SC_CAT_REJECT:
223 : {
224 0 : pCurrentAction = new ScMyRejAction();
225 : }
226 0 : break;
227 : default:
228 : {
229 : // added to avoid warnings
230 : }
231 : }
232 0 : }
233 :
234 0 : sal_uInt32 ScXMLChangeTrackingImportHelper::GetIDFromString(const OUString& sID)
235 : {
236 0 : sal_uInt32 nResult(0);
237 0 : sal_uInt32 nLength(sID.getLength());
238 0 : if (nLength)
239 : {
240 0 : if (sID.compareTo(sIDPrefix, nPrefixLength) == 0)
241 : {
242 0 : OUString sValue(sID.copy(nPrefixLength, nLength - nPrefixLength));
243 : sal_Int32 nValue;
244 0 : ::sax::Converter::convertNumber(nValue, sValue);
245 : OSL_ENSURE(nValue > 0, "wrong change action ID");
246 0 : nResult = nValue;
247 : }
248 : else
249 : {
250 : OSL_FAIL("wrong change action ID");
251 : }
252 : }
253 0 : return nResult;
254 : }
255 :
256 0 : void ScXMLChangeTrackingImportHelper::SetActionInfo(const ScMyActionInfo& aInfo)
257 : {
258 0 : pCurrentAction->aInfo = aInfo;
259 0 : aUsers.insert(aInfo.sUser);
260 0 : }
261 :
262 0 : void ScXMLChangeTrackingImportHelper::SetPreviousChange(const sal_uInt32 nPreviousAction,
263 : ScMyCellInfo* pCellInfo)
264 : {
265 : OSL_ENSURE(pCurrentAction->nActionType == SC_CAT_CONTENT, "wrong action type");
266 0 : ScMyContentAction* pAction = static_cast<ScMyContentAction*>(pCurrentAction);
267 0 : pAction->nPreviousAction = nPreviousAction;
268 0 : pAction->pCellInfo = pCellInfo;
269 0 : }
270 :
271 0 : void ScXMLChangeTrackingImportHelper::SetPosition(const sal_Int32 nPosition, const sal_Int32 nCount, const sal_Int32 nTable)
272 : {
273 : OSL_ENSURE(((pCurrentAction->nActionType != SC_CAT_MOVE) &&
274 : (pCurrentAction->nActionType != SC_CAT_CONTENT) &&
275 : (pCurrentAction->nActionType != SC_CAT_REJECT)), "wrong action type");
276 : OSL_ENSURE(nCount > 0, "wrong count");
277 0 : switch(pCurrentAction->nActionType)
278 : {
279 : case SC_CAT_INSERT_COLS:
280 : case SC_CAT_DELETE_COLS:
281 : {
282 : pCurrentAction->aBigRange.Set(nPosition, nInt32Min, nTable,
283 0 : nPosition + nCount - 1, nInt32Max, nTable);
284 : }
285 0 : break;
286 : case SC_CAT_INSERT_ROWS:
287 : case SC_CAT_DELETE_ROWS:
288 : {
289 : pCurrentAction->aBigRange.Set(nInt32Min, nPosition, nTable,
290 0 : nInt32Max, nPosition + nCount - 1, nTable);
291 : }
292 0 : break;
293 : case SC_CAT_INSERT_TABS:
294 : case SC_CAT_DELETE_TABS:
295 : {
296 : pCurrentAction->aBigRange.Set(nInt32Min, nInt32Min, nPosition,
297 0 : nInt32Max, nInt32Max, nPosition + nCount - 1);
298 : }
299 0 : break;
300 : default:
301 : {
302 : // added to avoid warnings
303 : }
304 : }
305 0 : }
306 :
307 0 : void ScXMLChangeTrackingImportHelper::AddDeleted(const sal_uInt32 nID)
308 : {
309 0 : ScMyDeleted* pDeleted = new ScMyDeleted();
310 0 : pDeleted->nID = nID;
311 0 : pCurrentAction->aDeletedList.push_front(pDeleted);
312 0 : }
313 :
314 0 : void ScXMLChangeTrackingImportHelper::AddDeleted(const sal_uInt32 nID, ScMyCellInfo* pCellInfo)
315 : {
316 0 : ScMyDeleted* pDeleted = new ScMyDeleted();
317 0 : pDeleted->nID = nID;
318 0 : pDeleted->pCellInfo = pCellInfo;
319 0 : pCurrentAction->aDeletedList.push_front(pDeleted);
320 0 : }
321 :
322 0 : void ScXMLChangeTrackingImportHelper::SetMultiSpanned(const sal_Int16 nTempMultiSpanned)
323 : {
324 0 : if (nTempMultiSpanned)
325 : {
326 : OSL_ENSURE(((pCurrentAction->nActionType == SC_CAT_DELETE_COLS) ||
327 : (pCurrentAction->nActionType == SC_CAT_DELETE_ROWS)), "wrong action type");
328 0 : nMultiSpanned = nTempMultiSpanned;
329 0 : nMultiSpannedSlaveCount = 0;
330 : }
331 0 : }
332 :
333 0 : void ScXMLChangeTrackingImportHelper::SetInsertionCutOff(const sal_uInt32 nID, const sal_Int32 nPosition)
334 : {
335 0 : if ((pCurrentAction->nActionType == SC_CAT_DELETE_COLS) ||
336 0 : (pCurrentAction->nActionType == SC_CAT_DELETE_ROWS))
337 : {
338 0 : static_cast<ScMyDelAction*>(pCurrentAction)->pInsCutOff = new ScMyInsertionCutOff(nID, nPosition);
339 : }
340 : else
341 : {
342 : OSL_FAIL("wrong action type");
343 : }
344 0 : }
345 :
346 0 : void ScXMLChangeTrackingImportHelper::AddMoveCutOff(const sal_uInt32 nID, const sal_Int32 nStartPosition, const sal_Int32 nEndPosition)
347 : {
348 0 : if ((pCurrentAction->nActionType == SC_CAT_DELETE_COLS) ||
349 0 : (pCurrentAction->nActionType == SC_CAT_DELETE_ROWS))
350 : {
351 0 : static_cast<ScMyDelAction*>(pCurrentAction)->aMoveCutOffs.push_front(ScMyMoveCutOff(nID, nStartPosition, nEndPosition));
352 : }
353 : else
354 : {
355 : OSL_FAIL("wrong action type");
356 : }
357 0 : }
358 :
359 0 : void ScXMLChangeTrackingImportHelper::SetMoveRanges(const ScBigRange& aSourceRange, const ScBigRange& aTargetRange)
360 : {
361 0 : if (pCurrentAction->nActionType == SC_CAT_MOVE)
362 : {
363 0 : static_cast<ScMyMoveAction*>(pCurrentAction)->pMoveRanges = new ScMyMoveRanges(aSourceRange, aTargetRange);
364 : }
365 : else
366 : {
367 : OSL_FAIL("wrong action type");
368 : }
369 0 : }
370 :
371 0 : void ScXMLChangeTrackingImportHelper::GetMultiSpannedRange()
372 : {
373 0 : if ((pCurrentAction->nActionType == SC_CAT_DELETE_COLS) ||
374 0 : (pCurrentAction->nActionType == SC_CAT_DELETE_ROWS))
375 : {
376 0 : if (nMultiSpannedSlaveCount)
377 : {
378 0 : static_cast<ScMyDelAction*>(pCurrentAction)->nD = nMultiSpannedSlaveCount;
379 : }
380 0 : ++nMultiSpannedSlaveCount;
381 0 : if (nMultiSpannedSlaveCount >= nMultiSpanned)
382 : {
383 0 : nMultiSpanned = 0;
384 0 : nMultiSpannedSlaveCount = 0;
385 : }
386 : }
387 : else
388 : {
389 : OSL_FAIL("wrong action type");
390 : }
391 0 : }
392 :
393 0 : void ScXMLChangeTrackingImportHelper::AddGenerated(ScMyCellInfo* pCellInfo, const ScBigRange& aBigRange)
394 : {
395 0 : ScMyGenerated* pGenerated = new ScMyGenerated(pCellInfo, aBigRange);
396 0 : if (pCurrentAction->nActionType == SC_CAT_MOVE)
397 : {
398 0 : static_cast<ScMyMoveAction*>(pCurrentAction)->aGeneratedList.push_back(pGenerated);
399 : }
400 0 : else if ((pCurrentAction->nActionType == SC_CAT_DELETE_COLS) ||
401 0 : (pCurrentAction->nActionType == SC_CAT_DELETE_ROWS))
402 : {
403 0 : static_cast<ScMyDelAction*>(pCurrentAction)->aGeneratedList.push_back(pGenerated);
404 : }
405 : else
406 : {
407 0 : delete pGenerated;
408 : OSL_FAIL("try to insert a generated action to a wrong action");
409 : }
410 0 : }
411 :
412 0 : void ScXMLChangeTrackingImportHelper::EndChangeAction()
413 : {
414 0 : if (!pCurrentAction)
415 : {
416 : OSL_FAIL("no current action");
417 0 : return;
418 : }
419 :
420 0 : if ((pCurrentAction->nActionType == SC_CAT_DELETE_COLS) ||
421 0 : (pCurrentAction->nActionType == SC_CAT_DELETE_ROWS))
422 0 : GetMultiSpannedRange();
423 :
424 0 : if (pCurrentAction->nActionNumber > 0)
425 0 : aActions.push_back(pCurrentAction);
426 : else
427 : {
428 : OSL_FAIL("no current action");
429 : }
430 :
431 0 : pCurrentAction = NULL;
432 : }
433 :
434 0 : void ScXMLChangeTrackingImportHelper::ConvertInfo(const ScMyActionInfo& aInfo, OUString& rUser, DateTime& aDateTime)
435 : {
436 0 : aDateTime = DateTime( aInfo.aDateTime);
437 :
438 : // old files didn't store nanoseconds, enable again
439 0 : if ( aInfo.aDateTime.NanoSeconds )
440 0 : pTrack->SetTimeNanoSeconds( true );
441 :
442 0 : const std::set<OUString>& rUsers = pTrack->GetUserCollection();
443 0 : std::set<OUString>::const_iterator it = rUsers.find(aInfo.sUser);
444 0 : if (it != rUsers.end())
445 : {
446 : // It's probably pointless to do this.
447 0 : rUser = *it;
448 : }
449 : else
450 0 : rUser = aInfo.sUser; // shouldn't happen
451 0 : }
452 :
453 0 : ScChangeAction* ScXMLChangeTrackingImportHelper::CreateInsertAction(ScMyInsAction* pAction)
454 : {
455 0 : DateTime aDateTime( Date(0), tools::Time(0) );
456 0 : OUString aUser;
457 0 : ConvertInfo(pAction->aInfo, aUser, aDateTime);
458 :
459 0 : OUString sComment (pAction->aInfo.sComment);
460 :
461 : ScChangeAction* pNewAction = new ScChangeActionIns(pAction->nActionNumber, pAction->nActionState, pAction->nRejectingNumber,
462 0 : pAction->aBigRange, aUser, aDateTime, sComment, pAction->nActionType);
463 0 : return pNewAction;
464 : }
465 :
466 0 : ScChangeAction* ScXMLChangeTrackingImportHelper::CreateDeleteAction(ScMyDelAction* pAction)
467 : {
468 0 : DateTime aDateTime( Date(0), tools::Time(0) );
469 0 : OUString aUser;
470 0 : ConvertInfo(pAction->aInfo, aUser, aDateTime);
471 :
472 0 : OUString sComment (pAction->aInfo.sComment);
473 :
474 : ScChangeAction* pNewAction = new ScChangeActionDel(pAction->nActionNumber, pAction->nActionState, pAction->nRejectingNumber,
475 0 : pAction->aBigRange, aUser, aDateTime, sComment, pAction->nActionType, pAction->nD, pTrack);
476 0 : return pNewAction;
477 : }
478 :
479 0 : ScChangeAction* ScXMLChangeTrackingImportHelper::CreateMoveAction(ScMyMoveAction* pAction)
480 : {
481 : OSL_ENSURE(pAction->pMoveRanges, "no move ranges");
482 0 : if (pAction->pMoveRanges)
483 : {
484 0 : DateTime aDateTime( Date(0), tools::Time(0) );
485 0 : OUString aUser;
486 0 : ConvertInfo(pAction->aInfo, aUser, aDateTime);
487 :
488 0 : OUString sComment (pAction->aInfo.sComment);
489 :
490 : ScChangeAction* pNewAction = new ScChangeActionMove(pAction->nActionNumber, pAction->nActionState, pAction->nRejectingNumber,
491 0 : pAction->pMoveRanges->aTargetRange, aUser, aDateTime, sComment, pAction->pMoveRanges->aSourceRange , pTrack);
492 0 : return pNewAction;
493 : }
494 0 : return NULL;
495 : }
496 :
497 0 : ScChangeAction* ScXMLChangeTrackingImportHelper::CreateRejectionAction(ScMyRejAction* pAction)
498 : {
499 0 : DateTime aDateTime( Date(0), tools::Time(0) );
500 0 : OUString aUser;
501 0 : ConvertInfo(pAction->aInfo, aUser, aDateTime);
502 :
503 0 : OUString sComment (pAction->aInfo.sComment);
504 :
505 : ScChangeAction* pNewAction = new ScChangeActionReject(pAction->nActionNumber, pAction->nActionState, pAction->nRejectingNumber,
506 0 : pAction->aBigRange, aUser, aDateTime, sComment);
507 0 : return pNewAction;
508 : }
509 :
510 0 : ScChangeAction* ScXMLChangeTrackingImportHelper::CreateContentAction(ScMyContentAction* pAction)
511 : {
512 0 : ScCellValue aCell;
513 0 : OUString sInputString;
514 0 : if (pAction->pCellInfo)
515 : {
516 0 : aCell = pAction->pCellInfo->CreateCell(pDoc);
517 0 : sInputString = pAction->pCellInfo->sInputString;
518 : }
519 :
520 0 : DateTime aDateTime( Date(0), tools::Time(0) );
521 0 : OUString aUser;
522 0 : ConvertInfo(pAction->aInfo, aUser, aDateTime);
523 :
524 0 : OUString sComment (pAction->aInfo.sComment);
525 :
526 : ScChangeAction* pNewAction = new ScChangeActionContent(pAction->nActionNumber, pAction->nActionState, pAction->nRejectingNumber,
527 0 : pAction->aBigRange, aUser, aDateTime, sComment, aCell, pDoc, sInputString);
528 0 : return pNewAction;
529 : }
530 :
531 0 : void ScXMLChangeTrackingImportHelper::CreateGeneratedActions(ScMyGeneratedList& rList)
532 : {
533 0 : if (!rList.empty())
534 : {
535 0 : ScMyGeneratedList::iterator aItr(rList.begin());
536 0 : ScMyGeneratedList::iterator aEndItr(rList.end());
537 0 : while (aItr != aEndItr)
538 : {
539 0 : if ((*aItr)->nID == 0)
540 : {
541 0 : ScCellValue aCell;
542 0 : if ((*aItr)->pCellInfo)
543 0 : aCell = (*aItr)->pCellInfo->CreateCell(pDoc);
544 :
545 0 : if (!aCell.isEmpty())
546 : {
547 0 : (*aItr)->nID = pTrack->AddLoadedGenerated(aCell, (*aItr)->aBigRange, (*aItr)->pCellInfo->sInputString);
548 : OSL_ENSURE((*aItr)->nID, "could not insert generated action");
549 0 : }
550 : }
551 0 : ++aItr;
552 : }
553 : }
554 0 : }
555 :
556 0 : void ScXMLChangeTrackingImportHelper::SetDeletionDependencies(ScMyDelAction* pAction, ScChangeActionDel* pDelAct)
557 : {
558 0 : if (!pAction->aGeneratedList.empty())
559 : {
560 : OSL_ENSURE(((pAction->nActionType == SC_CAT_DELETE_COLS) ||
561 : (pAction->nActionType == SC_CAT_DELETE_ROWS) ||
562 : (pAction->nActionType == SC_CAT_DELETE_TABS)), "wrong action type");
563 0 : if (pDelAct)
564 : {
565 0 : ScMyGeneratedList::iterator aItr(pAction->aGeneratedList.begin());
566 0 : ScMyGeneratedList::iterator aEndItr(pAction->aGeneratedList.end());
567 0 : while (aItr != aEndItr)
568 : {
569 : OSL_ENSURE((*aItr)->nID, "a not inserted generated action");
570 0 : pDelAct->SetDeletedInThis((*aItr)->nID, pTrack);
571 0 : if (*aItr)
572 0 : delete *aItr;
573 0 : aItr = pAction->aGeneratedList.erase(aItr);
574 : }
575 : }
576 : }
577 0 : if (pAction->pInsCutOff)
578 : {
579 : OSL_ENSURE(((pAction->nActionType == SC_CAT_DELETE_COLS) ||
580 : (pAction->nActionType == SC_CAT_DELETE_ROWS) ||
581 : (pAction->nActionType == SC_CAT_DELETE_TABS)), "wrong action type");
582 0 : ScChangeAction* pChangeAction = pTrack->GetAction(pAction->pInsCutOff->nID);
583 0 : if (pChangeAction && pChangeAction->IsInsertType())
584 : {
585 0 : ScChangeActionIns* pInsAction = static_cast<ScChangeActionIns*>(pChangeAction);
586 0 : if (pInsAction && pDelAct)
587 0 : pDelAct->SetCutOffInsert(pInsAction, static_cast<sal_Int16>(pAction->pInsCutOff->nPosition));
588 : }
589 : else
590 : {
591 : OSL_FAIL("no cut off insert action");
592 : }
593 : }
594 0 : if (!pAction->aMoveCutOffs.empty())
595 : {
596 : OSL_ENSURE(((pAction->nActionType == SC_CAT_DELETE_COLS) ||
597 : (pAction->nActionType == SC_CAT_DELETE_ROWS) ||
598 : (pAction->nActionType == SC_CAT_DELETE_TABS)), "wrong action type");
599 0 : ScMyMoveCutOffs::iterator aItr(pAction->aMoveCutOffs.begin());
600 0 : ScMyMoveCutOffs::iterator aEndItr(pAction->aMoveCutOffs.end());
601 0 : while(aItr != aEndItr)
602 : {
603 0 : ScChangeAction* pChangeAction = pTrack->GetAction(aItr->nID);
604 0 : if (pChangeAction && (pChangeAction->GetType() == SC_CAT_MOVE))
605 : {
606 0 : ScChangeActionMove* pMoveAction = static_cast<ScChangeActionMove*>(pChangeAction);
607 0 : if (pMoveAction && pDelAct)
608 0 : pDelAct->AddCutOffMove(pMoveAction, static_cast<sal_Int16>(aItr->nStartPosition),
609 0 : static_cast<sal_Int16>(aItr->nEndPosition));
610 : }
611 : else
612 : {
613 : OSL_FAIL("no cut off move action");
614 : }
615 0 : aItr = pAction->aMoveCutOffs.erase(aItr);
616 : }
617 : }
618 0 : }
619 :
620 0 : void ScXMLChangeTrackingImportHelper::SetMovementDependencies(ScMyMoveAction* pAction, ScChangeActionMove* pMoveAct)
621 : {
622 0 : if (!pAction->aGeneratedList.empty())
623 : {
624 0 : if (pAction->nActionType == SC_CAT_MOVE)
625 : {
626 0 : if (pMoveAct)
627 : {
628 0 : ScMyGeneratedList::iterator aItr(pAction->aGeneratedList.begin());
629 0 : ScMyGeneratedList::iterator aEndItr(pAction->aGeneratedList.end());
630 0 : while (aItr != aEndItr)
631 : {
632 : OSL_ENSURE((*aItr)->nID, "a not inserted generated action");
633 0 : pMoveAct->SetDeletedInThis((*aItr)->nID, pTrack);
634 0 : if (*aItr)
635 0 : delete *aItr;
636 0 : aItr = pAction->aGeneratedList.erase(aItr);
637 : }
638 : }
639 : }
640 : }
641 0 : }
642 :
643 0 : void ScXMLChangeTrackingImportHelper::SetContentDependencies(ScMyContentAction* pAction, ScChangeActionContent* pActContent)
644 : {
645 0 : if (!pAction->nPreviousAction)
646 0 : return;
647 :
648 : OSL_ENSURE(pAction->nActionType == SC_CAT_CONTENT, "wrong action type");
649 0 : ScChangeAction* pPrevAct = pTrack->GetAction(pAction->nPreviousAction);
650 0 : if (!pPrevAct)
651 0 : return;
652 :
653 0 : ScChangeActionContent* pPrevActContent = static_cast<ScChangeActionContent*>(pPrevAct);
654 0 : if (!pPrevActContent || !pActContent)
655 0 : return;
656 :
657 0 : pActContent->SetPrevContent(pPrevActContent);
658 0 : pPrevActContent->SetNextContent(pActContent);
659 0 : const ScCellValue& rOldCell = pActContent->GetOldCell();
660 0 : if (rOldCell.isEmpty())
661 0 : return;
662 :
663 0 : pPrevActContent->SetNewCell(rOldCell, pDoc, EMPTY_OUSTRING);
664 : }
665 :
666 0 : void ScXMLChangeTrackingImportHelper::SetDependencies(ScMyBaseAction* pAction)
667 : {
668 0 : ScChangeAction* pAct = pTrack->GetAction(pAction->nActionNumber);
669 0 : if (pAct)
670 : {
671 0 : if (!pAction->aDependencies.empty())
672 : {
673 0 : ScMyDependencies::iterator aItr(pAction->aDependencies.begin());
674 0 : ScMyDependencies::iterator aEndItr(pAction->aDependencies.end());
675 0 : while(aItr != aEndItr)
676 : {
677 0 : pAct->AddDependent(*aItr, pTrack);
678 0 : aItr = pAction->aDependencies.erase(aItr);
679 : }
680 : }
681 0 : if (!pAction->aDeletedList.empty())
682 : {
683 0 : ScMyDeletedList::iterator aItr(pAction->aDeletedList.begin());
684 0 : ScMyDeletedList::iterator aEndItr(pAction->aDeletedList.end());
685 0 : while(aItr != aEndItr)
686 : {
687 0 : pAct->SetDeletedInThis((*aItr)->nID, pTrack);
688 0 : ScChangeAction* pDeletedAct = pTrack->GetAction((*aItr)->nID);
689 0 : if ((pDeletedAct->GetType() == SC_CAT_CONTENT) && (*aItr)->pCellInfo)
690 : {
691 0 : ScChangeActionContent* pContentAct = static_cast<ScChangeActionContent*>(pDeletedAct);
692 0 : if (pContentAct && (*aItr)->pCellInfo)
693 : {
694 0 : const ScCellValue& rCell = (*aItr)->pCellInfo->CreateCell(pDoc);
695 0 : if (!rCell.equalsWithoutFormat(pContentAct->GetNewCell()))
696 : {
697 : // #i40704# Don't overwrite SetNewCell result by calling SetNewValue,
698 : // instead pass the input string to SetNewCell.
699 0 : pContentAct->SetNewCell(rCell, pDoc, (*aItr)->pCellInfo->sInputString);
700 : }
701 : }
702 : }
703 0 : if (*aItr)
704 0 : delete *aItr;
705 0 : aItr = pAction->aDeletedList.erase(aItr);
706 : }
707 : }
708 0 : if ((pAction->nActionType == SC_CAT_DELETE_COLS) ||
709 0 : (pAction->nActionType == SC_CAT_DELETE_ROWS))
710 0 : SetDeletionDependencies(static_cast<ScMyDelAction*>(pAction), static_cast<ScChangeActionDel*>(pAct));
711 0 : else if (pAction->nActionType == SC_CAT_MOVE)
712 0 : SetMovementDependencies(static_cast<ScMyMoveAction*>(pAction), static_cast<ScChangeActionMove*>(pAct));
713 0 : else if (pAction->nActionType == SC_CAT_CONTENT)
714 0 : SetContentDependencies(static_cast<ScMyContentAction*>(pAction), static_cast<ScChangeActionContent*>(pAct));
715 : }
716 : else
717 : {
718 : OSL_FAIL("could not find the action");
719 : }
720 0 : }
721 :
722 0 : void ScXMLChangeTrackingImportHelper::SetNewCell(ScMyContentAction* pAction)
723 : {
724 0 : ScChangeAction* pChangeAction = pTrack->GetAction(pAction->nActionNumber);
725 0 : if (pChangeAction)
726 : {
727 0 : ScChangeActionContent* pChangeActionContent = static_cast<ScChangeActionContent*>(pChangeAction);
728 0 : if (pChangeActionContent)
729 : {
730 0 : if (pChangeActionContent->IsTopContent() && !pChangeActionContent->IsDeletedIn())
731 : {
732 : sal_Int32 nCol, nRow, nTab, nCol2, nRow2, nTab2;
733 0 : pAction->aBigRange.GetVars(nCol, nRow, nTab, nCol2, nRow2, nTab2);
734 0 : if ((nCol >= 0) && (nCol <= MAXCOL) &&
735 0 : (nRow >= 0) && (nRow <= MAXROW) &&
736 0 : (nTab >= 0) && (nTab <= MAXTAB))
737 : {
738 : ScAddress aAddress (static_cast<SCCOL>(nCol),
739 : static_cast<SCROW>(nRow),
740 0 : static_cast<SCTAB>(nTab));
741 0 : ScCellValue aCell;
742 0 : aCell.assign(*pDoc, aAddress);
743 0 : if (!aCell.isEmpty())
744 : {
745 0 : ScCellValue aNewCell;
746 0 : if (aCell.meType != CELLTYPE_FORMULA)
747 : {
748 0 : aNewCell = aCell;
749 0 : pChangeActionContent->SetNewCell(aNewCell, pDoc, EMPTY_OUSTRING);
750 0 : pChangeActionContent->SetNewValue(aCell, pDoc);
751 : }
752 : else
753 : {
754 0 : sal_uInt8 nMatrixFlag = aCell.mpFormula->GetMatrixFlag();
755 0 : OUString sFormula;
756 : // With GRAM_ODFF reference detection is faster on compilation.
757 : /* FIXME: new cell should be created with a clone
758 : * of the token array instead. Any reason why this
759 : * wasn't done? */
760 0 : aCell.mpFormula->GetFormula(sFormula, formula::FormulaGrammar::GRAM_ODFF);
761 :
762 : // #i87826# [Collaboration] Rejected move destroys formulas
763 : // FIXME: adjust ScFormulaCell::GetFormula(), so that the right formula string
764 : // is returned and no further string handling is necessary
765 0 : OUString sFormula2;
766 0 : if ( nMatrixFlag != MM_NONE )
767 : {
768 0 : sFormula2 = sFormula.copy( 2, sFormula.getLength() - 3 );
769 : }
770 : else
771 : {
772 0 : sFormula2 = sFormula.copy( 1, sFormula.getLength() - 1 );
773 : }
774 :
775 0 : aNewCell.meType = CELLTYPE_FORMULA;
776 0 : aNewCell.mpFormula = new ScFormulaCell(pDoc, aAddress, sFormula2,formula::FormulaGrammar::GRAM_ODFF, nMatrixFlag);
777 0 : if (nMatrixFlag == MM_FORMULA)
778 : {
779 : SCCOL nCols;
780 : SCROW nRows;
781 0 : aCell.mpFormula->GetMatColsRows(nCols, nRows);
782 0 : aNewCell.mpFormula->SetMatColsRows(nCols, nRows);
783 : }
784 0 : aNewCell.mpFormula->SetInChangeTrack(true);
785 0 : pChangeActionContent->SetNewCell(aNewCell, pDoc, EMPTY_OUSTRING);
786 : // #i40704# don't overwrite the formula string via SetNewValue()
787 0 : }
788 0 : }
789 : }
790 : else
791 : {
792 : OSL_FAIL("wrong cell position");
793 : }
794 : }
795 : }
796 : }
797 0 : }
798 :
799 1 : void ScXMLChangeTrackingImportHelper::CreateChangeTrack(ScDocument* pTempDoc)
800 : {
801 1 : pDoc = pTempDoc;
802 1 : if (pDoc)
803 : {
804 1 : pTrack = new ScChangeTrack(pDoc, aUsers);
805 : // old files didn't store nanoseconds, disable until encountered
806 1 : pTrack->SetTimeNanoSeconds( false );
807 :
808 1 : ScMyActions::iterator aItr(aActions.begin());
809 1 : ScMyActions::iterator aEndItr(aActions.end());
810 2 : while (aItr != aEndItr)
811 : {
812 0 : ScChangeAction* pAction = NULL;
813 :
814 0 : switch ((*aItr)->nActionType)
815 : {
816 : case SC_CAT_INSERT_COLS:
817 : case SC_CAT_INSERT_ROWS:
818 : case SC_CAT_INSERT_TABS:
819 : {
820 0 : pAction = CreateInsertAction(static_cast<ScMyInsAction*>(*aItr));
821 : }
822 0 : break;
823 : case SC_CAT_DELETE_COLS:
824 : case SC_CAT_DELETE_ROWS:
825 : case SC_CAT_DELETE_TABS:
826 : {
827 0 : ScMyDelAction* pDelAct = static_cast<ScMyDelAction*>(*aItr);
828 0 : pAction = CreateDeleteAction(pDelAct);
829 0 : CreateGeneratedActions(pDelAct->aGeneratedList);
830 : }
831 0 : break;
832 : case SC_CAT_MOVE:
833 : {
834 0 : ScMyMoveAction* pMovAct = static_cast<ScMyMoveAction*>(*aItr);
835 0 : pAction = CreateMoveAction(pMovAct);
836 0 : CreateGeneratedActions(pMovAct->aGeneratedList);
837 : }
838 0 : break;
839 : case SC_CAT_CONTENT:
840 : {
841 0 : pAction = CreateContentAction(static_cast<ScMyContentAction*>(*aItr));
842 : }
843 0 : break;
844 : case SC_CAT_REJECT:
845 : {
846 0 : pAction = CreateRejectionAction(static_cast<ScMyRejAction*>(*aItr));
847 : }
848 0 : break;
849 : default:
850 : {
851 : // added to avoid warnings
852 : }
853 : }
854 :
855 0 : if (pAction)
856 0 : pTrack->AppendLoaded(pAction);
857 : else
858 : {
859 : OSL_FAIL("no action");
860 : }
861 :
862 0 : ++aItr;
863 : }
864 1 : if (pTrack->GetLast())
865 0 : pTrack->SetActionMax(pTrack->GetLast()->GetActionNumber());
866 :
867 1 : aItr = aActions.begin();
868 1 : aEndItr = aActions.end();
869 2 : while (aItr != aEndItr)
870 : {
871 0 : SetDependencies(*aItr);
872 :
873 0 : if ((*aItr)->nActionType == SC_CAT_CONTENT)
874 0 : ++aItr;
875 : else
876 : {
877 0 : if (*aItr)
878 0 : delete (*aItr);
879 0 : aItr = aActions.erase(aItr);
880 : }
881 : }
882 :
883 1 : aItr = aActions.begin();
884 1 : aEndItr = aActions.end();
885 2 : while (aItr != aEndItr)
886 : {
887 : OSL_ENSURE((*aItr)->nActionType == SC_CAT_CONTENT, "wrong action type");
888 0 : SetNewCell(static_cast<ScMyContentAction*>(*aItr));
889 0 : if (*aItr)
890 0 : delete (*aItr);
891 0 : aItr = aActions.erase(aItr);
892 : }
893 1 : if (aProtect.getLength())
894 0 : pTrack->SetProtection(aProtect);
895 1 : else if (pDoc->GetChangeTrack() && pDoc->GetChangeTrack()->IsProtected())
896 1 : pTrack->SetProtection(pDoc->GetChangeTrack()->GetProtection());
897 :
898 1 : if ( pTrack->GetLast() )
899 0 : pTrack->SetLastSavedActionNumber(pTrack->GetLast()->GetActionNumber());
900 :
901 1 : pDoc->SetChangeTrack(pTrack);
902 : }
903 157 : }
904 :
905 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|