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