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