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