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