/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" #include "XMLChangeTrackingImportHelper.hxx" #include "XMLConverter.hxx" #include "cell.hxx" #include "document.hxx" #include "chgviset.hxx" #include "rangeutl.hxx" #include #include #include #include #define SC_CHANGE_ID_PREFIX "ct" ScMyCellInfo::ScMyCellInfo() : pCell(NULL), sFormulaAddress(), sFormula(), sInputString(), fValue(0.0), nMatrixCols(0), nMatrixRows(0), eGrammar( formula::FormulaGrammar::GRAM_STORAGE_DEFAULT), nType(NUMBERFORMAT_ALL), nMatrixFlag(MM_NONE) { } ScMyCellInfo::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) : pCell(pTempCell), sFormulaAddress(rFormulaAddress), sFormula(rFormula), sInputString(rInputString), fValue(rValue), nMatrixCols(nTempMatrixCols), nMatrixRows(nTempMatrixRows), eGrammar( eTempGrammar), nType(nTempType), nMatrixFlag(nTempMatrixFlag) { } ScMyCellInfo::~ScMyCellInfo() { if (pCell) pCell->Delete(); } ScBaseCell* ScMyCellInfo::CreateCell(ScDocument* pDoc) { if (pDoc) { if (!pCell && sFormula.getLength() && sFormulaAddress.getLength()) { ScAddress aPos; sal_Int32 nOffset(0); ScRangeStringConverter::GetAddressFromString(aPos, sFormulaAddress, pDoc, ::formula::FormulaGrammar::CONV_OOO, nOffset); pCell = new ScFormulaCell(pDoc, aPos, sFormula, eGrammar, nMatrixFlag); static_cast(pCell)->SetMatColsRows(static_cast(nMatrixCols), static_cast(nMatrixRows)); } if ((nType == NUMBERFORMAT_DATE || nType == NUMBERFORMAT_TIME) && sInputString.Len() == 0) { sal_uInt32 nFormat(0); if (nType == NUMBERFORMAT_DATE) nFormat = pDoc->GetFormatTable()->GetStandardFormat( NUMBERFORMAT_DATE, ScGlobal::eLnge ); else if (nType == NUMBERFORMAT_TIME) nFormat = pDoc->GetFormatTable()->GetStandardFormat( NUMBERFORMAT_TIME, ScGlobal::eLnge ); pDoc->GetFormatTable()->GetInputLineString(fValue, nFormat, sInputString); } } return pCell ? pCell->CloneWithoutNote( *pDoc ) : 0; } ScMyDeleted::ScMyDeleted() : pCellInfo(NULL) { } ScMyDeleted::~ScMyDeleted() { if (pCellInfo) delete pCellInfo; } ScMyGenerated::ScMyGenerated(ScMyCellInfo* pTempCellInfo, const ScBigRange& aTempBigRange) : aBigRange(aTempBigRange), nID(0), pCellInfo(pTempCellInfo) { } ScMyGenerated::~ScMyGenerated() { if (pCellInfo) delete pCellInfo; } ScMyBaseAction::ScMyBaseAction(const ScChangeActionType nTempActionType) : aDependencies(), aDeletedList(), nActionNumber(0), nRejectingNumber(0), nPreviousAction(0), nActionType(nTempActionType), nActionState(SC_CAS_VIRGIN) { } ScMyBaseAction::~ScMyBaseAction() { } ScMyInsAction::ScMyInsAction(const ScChangeActionType nActionTypeP) : ScMyBaseAction(nActionTypeP) { } ScMyInsAction::~ScMyInsAction() { } ScMyDelAction::ScMyDelAction(const ScChangeActionType nActionTypeP) : ScMyBaseAction(nActionTypeP), aGeneratedList(), pInsCutOff(NULL), aMoveCutOffs(), nD(0) { } ScMyDelAction::~ScMyDelAction() { if (pInsCutOff) delete pInsCutOff; } ScMyMoveAction::ScMyMoveAction() : ScMyBaseAction(SC_CAT_MOVE), aGeneratedList(), pMoveRanges(NULL) { } ScMyMoveAction::~ScMyMoveAction() { if (pMoveRanges) delete pMoveRanges; } ScMyContentAction::ScMyContentAction() : ScMyBaseAction(SC_CAT_CONTENT), pCellInfo(NULL) { } ScMyContentAction::~ScMyContentAction() { if (pCellInfo) delete pCellInfo; } ScMyRejAction::ScMyRejAction() : ScMyBaseAction(SC_CAT_REJECT) { } ScMyRejAction::~ScMyRejAction() { } ScXMLChangeTrackingImportHelper::ScXMLChangeTrackingImportHelper() : aUsers(), aActions(), pDoc(NULL), pTrack(NULL), pCurrentAction(NULL), sIDPrefix(RTL_CONSTASCII_USTRINGPARAM(SC_CHANGE_ID_PREFIX)), nMultiSpanned(0), nMultiSpannedSlaveCount(0), bChangeTrack(sal_False) { nPrefixLength = sIDPrefix.getLength(); } ScXMLChangeTrackingImportHelper::~ScXMLChangeTrackingImportHelper() { } void ScXMLChangeTrackingImportHelper::StartChangeAction(const ScChangeActionType nActionType) { DBG_ASSERT(!pCurrentAction, "a not inserted action"); switch (nActionType) { case SC_CAT_INSERT_COLS: case SC_CAT_INSERT_ROWS: case SC_CAT_INSERT_TABS: { pCurrentAction = new ScMyInsAction(nActionType); } break; case SC_CAT_DELETE_COLS: case SC_CAT_DELETE_ROWS: case SC_CAT_DELETE_TABS: { pCurrentAction = new ScMyDelAction(nActionType); } break; case SC_CAT_MOVE: { pCurrentAction = new ScMyMoveAction(); } break; case SC_CAT_CONTENT: { pCurrentAction = new ScMyContentAction(); } break; case SC_CAT_REJECT: { pCurrentAction = new ScMyRejAction(); } break; default: { // added to avoid warnings } } } sal_uInt32 ScXMLChangeTrackingImportHelper::GetIDFromString(const rtl::OUString& sID) { sal_uInt32 nResult(0); sal_uInt32 nLength(sID.getLength()); if (nLength) { if (sID.compareTo(sIDPrefix, nPrefixLength) == 0) { rtl::OUString sValue(sID.copy(nPrefixLength, nLength - nPrefixLength)); sal_Int32 nValue; SvXMLUnitConverter::convertNumber(nValue, sValue); DBG_ASSERT(nValue > 0, "wrong change action ID"); nResult = nValue; } else { DBG_ERROR("wrong change action ID"); } } return nResult; } void ScXMLChangeTrackingImportHelper::SetActionInfo(const ScMyActionInfo& aInfo) { pCurrentAction->aInfo = aInfo; String aUser(aInfo.sUser); StrData* pStrData = new StrData( aUser ); if ( !aUsers.Insert( pStrData ) ) delete pStrData; } void ScXMLChangeTrackingImportHelper::SetPreviousChange(const sal_uInt32 nPreviousAction, ScMyCellInfo* pCellInfo) { DBG_ASSERT(pCurrentAction->nActionType == SC_CAT_CONTENT, "wrong action type"); ScMyContentAction* pAction = static_cast(pCurrentAction); pAction->nPreviousAction = nPreviousAction; pAction->pCellInfo = pCellInfo; } void ScXMLChangeTrackingImportHelper::SetPosition(const sal_Int32 nPosition, const sal_Int32 nCount, const sal_Int32 nTable) { DBG_ASSERT(((pCurrentAction->nActionType != SC_CAT_MOVE) && (pCurrentAction->nActionType != SC_CAT_CONTENT) && (pCurrentAction->nActionType != SC_CAT_REJECT)), "wrong action type"); DBG_ASSERT(nCount > 0, "wrong count"); switch(pCurrentAction->nActionType) { case SC_CAT_INSERT_COLS: case SC_CAT_DELETE_COLS: { pCurrentAction->aBigRange.Set(nPosition, nInt32Min, nTable, nPosition + nCount - 1, nInt32Max, nTable); } break; case SC_CAT_INSERT_ROWS: case SC_CAT_DELETE_ROWS: { pCurrentAction->aBigRange.Set(nInt32Min, nPosition, nTable, nInt32Max, nPosition + nCount - 1, nTable); } break; case SC_CAT_INSERT_TABS: case SC_CAT_DELETE_TABS: { pCurrentAction->aBigRange.Set(nInt32Min, nInt32Min, nPosition, nInt32Max, nInt32Max, nPosition + nCount - 1); } break; default: { // added to avoid warnings } } } void ScXMLChangeTrackingImportHelper::AddDeleted(const sal_uInt32 nID) { ScMyDeleted* pDeleted = new ScMyDeleted(); pDeleted->nID = nID; pCurrentAction->aDeletedList.push_front(pDeleted); } void ScXMLChangeTrackingImportHelper::AddDeleted(const sal_uInt32 nID, ScMyCellInfo* pCellInfo) { ScMyDeleted* pDeleted = new ScMyDeleted(); pDeleted->nID = nID; pDeleted->pCellInfo = pCellInfo; pCurrentAction->aDeletedList.push_front(pDeleted); } void ScXMLChangeTrackingImportHelper::SetMultiSpanned(const sal_Int16 nTempMultiSpanned) { if (nTempMultiSpanned) { DBG_ASSERT(((pCurrentAction->nActionType == SC_CAT_DELETE_COLS) || (pCurrentAction->nActionType == SC_CAT_DELETE_ROWS)), "wrong action type"); nMultiSpanned = nTempMultiSpanned; nMultiSpannedSlaveCount = 0; } } void ScXMLChangeTrackingImportHelper::SetInsertionCutOff(const sal_uInt32 nID, const sal_Int32 nPosition) { if ((pCurrentAction->nActionType == SC_CAT_DELETE_COLS) || (pCurrentAction->nActionType == SC_CAT_DELETE_ROWS)) { static_cast(pCurrentAction)->pInsCutOff = new ScMyInsertionCutOff(nID, nPosition); } else { DBG_ERROR("wrong action type"); } } void ScXMLChangeTrackingImportHelper::AddMoveCutOff(const sal_uInt32 nID, const sal_Int32 nStartPosition, const sal_Int32 nEndPosition) { if ((pCurrentAction->nActionType == SC_CAT_DELETE_COLS) || (pCurrentAction->nActionType == SC_CAT_DELETE_ROWS)) { static_cast(pCurrentAction)->aMoveCutOffs.push_front(ScMyMoveCutOff(nID, nStartPosition, nEndPosition)); } else { DBG_ERROR("wrong action type"); } } void ScXMLChangeTrackingImportHelper::SetMoveRanges(const ScBigRange& aSourceRange, const ScBigRange& aTargetRange) { if (pCurrentAction->nActionType == SC_CAT_MOVE) { static_cast(pCurrentAction)->pMoveRanges = new ScMyMoveRanges(aSourceRange, aTargetRange); } else { DBG_ERROR("wrong action type"); } } void ScXMLChangeTrackingImportHelper::GetMultiSpannedRange() { if ((pCurrentAction->nActionType == SC_CAT_DELETE_COLS) || (pCurrentAction->nActionType == SC_CAT_DELETE_ROWS)) { if (nMultiSpannedSlaveCount) { static_cast(pCurrentAction)->nD = nMultiSpannedSlaveCount; } ++nMultiSpannedSlaveCount; if (nMultiSpannedSlaveCount >= nMultiSpanned) { nMultiSpanned = 0; nMultiSpannedSlaveCount = 0; } } else { DBG_ERROR("wrong action type"); } } void ScXMLChangeTrackingImportHelper::AddGenerated(ScMyCellInfo* pCellInfo, const ScBigRange& aBigRange) { ScMyGenerated* pGenerated = new ScMyGenerated(pCellInfo, aBigRange); if (pCurrentAction->nActionType == SC_CAT_MOVE) { static_cast(pCurrentAction)->aGeneratedList.push_back(pGenerated); } else if ((pCurrentAction->nActionType == SC_CAT_DELETE_COLS) || (pCurrentAction->nActionType == SC_CAT_DELETE_ROWS)) { static_cast(pCurrentAction)->aGeneratedList.push_back(pGenerated); } else { DBG_ERROR("try to insert a generated action to a wrong action"); } } void ScXMLChangeTrackingImportHelper::EndChangeAction() { if ((pCurrentAction->nActionType == SC_CAT_DELETE_COLS) || (pCurrentAction->nActionType == SC_CAT_DELETE_ROWS)) GetMultiSpannedRange(); if (pCurrentAction && pCurrentAction->nActionNumber > 0) aActions.push_back(pCurrentAction); else { DBG_ERROR("no current action"); } pCurrentAction = NULL; } void ScXMLChangeTrackingImportHelper::ConvertInfo(const ScMyActionInfo& aInfo, String& rUser, DateTime& aDateTime) { Date aDate(aInfo.aDateTime.Day, aInfo.aDateTime.Month, aInfo.aDateTime.Year); Time aTime(aInfo.aDateTime.Hours, aInfo.aDateTime.Minutes, aInfo.aDateTime.Seconds, aInfo.aDateTime.HundredthSeconds); aDateTime.SetDate( aDate.GetDate() ); aDateTime.SetTime( aTime.GetTime() ); // #97286# old files didn't store 100th seconds, enable again if ( aInfo.aDateTime.HundredthSeconds ) pTrack->SetTime100thSeconds( sal_True ); StrData aStrData( aInfo.sUser ); sal_uInt16 nPos; if ( pTrack->GetUserCollection().Search( &aStrData, nPos ) ) { const StrData* pUser = static_cast( pTrack->GetUserCollection().At( nPos ) ); if ( pUser ) rUser = pUser->GetString(); else rUser = aInfo.sUser; // shouldn't happen } else rUser = aInfo.sUser; // shouldn't happen } ScChangeAction* ScXMLChangeTrackingImportHelper::CreateInsertAction(ScMyInsAction* pAction) { DateTime aDateTime( Date(0), Time(0) ); String aUser; ConvertInfo(pAction->aInfo, aUser, aDateTime); String sComment (pAction->aInfo.sComment); ScChangeAction* pNewAction = new ScChangeActionIns(pAction->nActionNumber, pAction->nActionState, pAction->nRejectingNumber, pAction->aBigRange, aUser, aDateTime, sComment, pAction->nActionType); return pNewAction; } ScChangeAction* ScXMLChangeTrackingImportHelper::CreateDeleteAction(ScMyDelAction* pAction) { DateTime aDateTime( Date(0), Time(0) ); String aUser; ConvertInfo(pAction->aInfo, aUser, aDateTime); String sComment (pAction->aInfo.sComment); ScChangeAction* pNewAction = new ScChangeActionDel(pAction->nActionNumber, pAction->nActionState, pAction->nRejectingNumber, pAction->aBigRange, aUser, aDateTime, sComment, pAction->nActionType, pAction->nD, pTrack); return pNewAction; } ScChangeAction* ScXMLChangeTrackingImportHelper::CreateMoveAction(ScMyMoveAction* pAction) { DBG_ASSERT(pAction->pMoveRanges, "no move ranges"); if (pAction->pMoveRanges) { DateTime aDateTime( Date(0), Time(0) ); String aUser; ConvertInfo(pAction->aInfo, aUser, aDateTime); String sComment (pAction->aInfo.sComment); ScChangeAction* pNewAction = new ScChangeActionMove(pAction->nActionNumber, pAction->nActionState, pAction->nRejectingNumber, pAction->pMoveRanges->aTargetRange, aUser, aDateTime, sComment, pAction->pMoveRanges->aSourceRange , pTrack); return pNewAction; } return NULL; } ScChangeAction* ScXMLChangeTrackingImportHelper::CreateRejectionAction(ScMyRejAction* pAction) { DateTime aDateTime( Date(0), Time(0) ); String aUser; ConvertInfo(pAction->aInfo, aUser, aDateTime); String sComment (pAction->aInfo.sComment); ScChangeAction* pNewAction = new ScChangeActionReject(pAction->nActionNumber, pAction->nActionState, pAction->nRejectingNumber, pAction->aBigRange, aUser, aDateTime, sComment); return pNewAction; } ScChangeAction* ScXMLChangeTrackingImportHelper::CreateContentAction(ScMyContentAction* pAction) { ScBaseCell* pCell = NULL; if (pAction->pCellInfo) pCell = pAction->pCellInfo->CreateCell(pDoc); DateTime aDateTime( Date(0), Time(0) ); String aUser; ConvertInfo(pAction->aInfo, aUser, aDateTime); String sComment (pAction->aInfo.sComment); ScChangeAction* pNewAction = new ScChangeActionContent(pAction->nActionNumber, pAction->nActionState, pAction->nRejectingNumber, pAction->aBigRange, aUser, aDateTime, sComment, pCell, pDoc, pAction->pCellInfo->sInputString); return pNewAction; } void ScXMLChangeTrackingImportHelper::CreateGeneratedActions(ScMyGeneratedList& rList) { if (!rList.empty()) { ScMyGeneratedList::iterator aItr(rList.begin()); ScMyGeneratedList::iterator aEndItr(rList.end()); while (aItr != aEndItr) { if( (*aItr)->nID == 0) { ScBaseCell* pCell = NULL; if ((*aItr)->pCellInfo) pCell = (*aItr)->pCellInfo->CreateCell(pDoc); if (pCell) { (*aItr)->nID = pTrack->AddLoadedGenerated(pCell, (*aItr)->aBigRange, (*aItr)->pCellInfo->sInputString ); DBG_ASSERT((*aItr)->nID, "could not insert generated action"); } } ++aItr; } } } void ScXMLChangeTrackingImportHelper::SetDeletionDependencies(ScMyDelAction* pAction, ScChangeActionDel* pDelAct) { if (!pAction->aGeneratedList.empty()) { DBG_ASSERT(((pAction->nActionType == SC_CAT_DELETE_COLS) || (pAction->nActionType == SC_CAT_DELETE_ROWS) || (pAction->nActionType == SC_CAT_DELETE_TABS)), "wrong action type"); if (pDelAct) { ScMyGeneratedList::iterator aItr(pAction->aGeneratedList.begin()); ScMyGeneratedList::iterator aEndItr(pAction->aGeneratedList.end()); while (aItr != aEndItr) { DBG_ASSERT((*aItr)->nID, "a not inserted generated action"); pDelAct->SetDeletedInThis((*aItr)->nID, pTrack); if (*aItr) delete *aItr; aItr = pAction->aGeneratedList.erase(aItr); } } } if (pAction->pInsCutOff) { DBG_ASSERT(((pAction->nActionType == SC_CAT_DELETE_COLS) || (pAction->nActionType == SC_CAT_DELETE_ROWS) || (pAction->nActionType == SC_CAT_DELETE_TABS)), "wrong action type"); ScChangeAction* pChangeAction = pTrack->GetAction(pAction->pInsCutOff->nID); if (pChangeAction && pChangeAction->IsInsertType()) { ScChangeActionIns* pInsAction = static_cast(pChangeAction); if (pInsAction && pDelAct) pDelAct->SetCutOffInsert(pInsAction, static_cast(pAction->pInsCutOff->nPosition)); } else { DBG_ERROR("no cut off insert action"); } } if (!pAction->aMoveCutOffs.empty()) { DBG_ASSERT(((pAction->nActionType == SC_CAT_DELETE_COLS) || (pAction->nActionType == SC_CAT_DELETE_ROWS) || (pAction->nActionType == SC_CAT_DELETE_TABS)), "wrong action type"); ScMyMoveCutOffs::iterator aItr(pAction->aMoveCutOffs.begin()); ScMyMoveCutOffs::iterator aEndItr(pAction->aMoveCutOffs.end()); while(aItr != aEndItr) { ScChangeAction* pChangeAction = pTrack->GetAction(aItr->nID); if (pChangeAction && (pChangeAction->GetType() == SC_CAT_MOVE)) { ScChangeActionMove* pMoveAction = static_cast(pChangeAction); if (pMoveAction && pDelAct) pDelAct->AddCutOffMove(pMoveAction, static_cast(aItr->nStartPosition), static_cast(aItr->nEndPosition)); } else { DBG_ERROR("no cut off move action"); } aItr = pAction->aMoveCutOffs.erase(aItr); } } } void ScXMLChangeTrackingImportHelper::SetMovementDependencies(ScMyMoveAction* pAction, ScChangeActionMove* pMoveAct) { if (!pAction->aGeneratedList.empty()) { if (pAction->nActionType == SC_CAT_MOVE) { if (pMoveAct) { ScMyGeneratedList::iterator aItr(pAction->aGeneratedList.begin()); ScMyGeneratedList::iterator aEndItr(pAction->aGeneratedList.end()); while (aItr != aEndItr) { DBG_ASSERT((*aItr)->nID, "a not inserted generated action"); pMoveAct->SetDeletedInThis((*aItr)->nID, pTrack); if (*aItr) delete *aItr; aItr = pAction->aGeneratedList.erase(aItr); } } } } } void ScXMLChangeTrackingImportHelper::SetContentDependencies(ScMyContentAction* pAction, ScChangeActionContent* pActContent) { if (pAction->nPreviousAction) { DBG_ASSERT(pAction->nActionType == SC_CAT_CONTENT, "wrong action type"); ScChangeAction* pPrevAct = pTrack->GetAction(pAction->nPreviousAction); if (pPrevAct) { ScChangeActionContent* pPrevActContent = static_cast(pPrevAct); if (pPrevActContent && pActContent) { pActContent->SetPrevContent(pPrevActContent); pPrevActContent->SetNextContent(pActContent); const ScBaseCell* pOldCell = pActContent->GetOldCell(); if (pOldCell) { ScBaseCell* pNewCell = pOldCell->CloneWithoutNote( *pDoc ); if (pNewCell) { pPrevActContent->SetNewCell(pNewCell, pDoc, EMPTY_STRING); pPrevActContent->SetNewValue(pActContent->GetOldCell(), pDoc); } } } } } } void ScXMLChangeTrackingImportHelper::SetDependencies(ScMyBaseAction* pAction) { ScChangeAction* pAct = pTrack->GetAction(pAction->nActionNumber); if (pAct) { if (!pAction->aDependencies.empty()) { ScMyDependencies::iterator aItr(pAction->aDependencies.begin()); ScMyDependencies::iterator aEndItr(pAction->aDependencies.end()); while(aItr != aEndItr) { pAct->AddDependent(*aItr, pTrack); aItr = pAction->aDependencies.erase(aItr); } } if (!pAction->aDeletedList.empty()) { ScMyDeletedList::iterator aItr(pAction->aDeletedList.begin()); ScMyDeletedList::iterator aEndItr(pAction->aDeletedList.end()); while(aItr != aEndItr) { pAct->SetDeletedInThis((*aItr)->nID, pTrack); ScChangeAction* pDeletedAct = pTrack->GetAction((*aItr)->nID); if ((pDeletedAct->GetType() == SC_CAT_CONTENT) && (*aItr)->pCellInfo) { ScChangeActionContent* pContentAct = static_cast(pDeletedAct); if (pContentAct && (*aItr)->pCellInfo) { ScBaseCell* pCell = (*aItr)->pCellInfo->CreateCell(pDoc); if (!ScBaseCell::CellEqual(pCell, pContentAct->GetNewCell())) { // #i40704# Don't overwrite SetNewCell result by calling SetNewValue, // instead pass the input string to SetNewCell. pContentAct->SetNewCell(pCell, pDoc, (*aItr)->pCellInfo->sInputString); } } } if (*aItr) delete *aItr; aItr = pAction->aDeletedList.erase(aItr); } } if ((pAction->nActionType == SC_CAT_DELETE_COLS) || (pAction->nActionType == SC_CAT_DELETE_ROWS)) SetDeletionDependencies(static_cast(pAction), static_cast(pAct)); else if (pAction->nActionType == SC_CAT_MOVE) SetMovementDependencies(static_cast(pAction), static_cast(pAct)); else if (pAction->nActionType == SC_CAT_CONTENT) SetContentDependencies(static_cast(pAction), static_cast(pAct)); } else { DBG_ERROR("could not find the action"); } } void ScXMLChangeTrackingImportHelper::SetNewCell(ScMyContentAction* pAction) { ScChangeAction* pChangeAction = pTrack->GetAction(pAction->nActionNumber); if (pChangeAction) { ScChangeActionContent* pChangeActionContent = static_cast(pChangeAction); if (pChangeActionContent) { if (pChangeActionContent->IsTopContent() && !pChangeActionContent->IsDeletedIn()) { sal_Int32 nCol, nRow, nTab, nCol2, nRow2, nTab2; pAction->aBigRange.GetVars(nCol, nRow, nTab, nCol2, nRow2, nTab2); if ((nCol >= 0) && (nCol <= MAXCOL) && (nRow >= 0) && (nRow <= MAXROW) && (nTab >= 0) && (nTab <= MAXTAB)) { ScAddress aAddress (static_cast(nCol), static_cast(nRow), static_cast(nTab)); ScBaseCell* pCell = pDoc->GetCell(aAddress); if (pCell) { ScBaseCell* pNewCell = NULL; if (pCell->GetCellType() != CELLTYPE_FORMULA) pNewCell = pCell->CloneWithoutNote( *pDoc ); else { sal_uInt8 nMatrixFlag = static_cast(pCell)->GetMatrixFlag(); String sFormula; // With GRAM_ODFF reference detection is faster on compilation. /* FIXME: new cell should be created with a clone * of the token array instead. Any reason why this * wasn't done? */ static_cast(pCell)->GetFormula(sFormula,formula::FormulaGrammar::GRAM_ODFF); rtl::OUString sOUFormula(sFormula); // #i87826# [Collaboration] Rejected move destroys formulas // FIXME: adjust ScFormulaCell::GetFormula(), so that the right formula string // is returned and no further string handling is necessary rtl::OUString sOUFormula2; if ( nMatrixFlag != MM_NONE ) { sOUFormula2 = sOUFormula.copy( 2, sOUFormula.getLength() - 3 ); } else { sOUFormula2 = sOUFormula.copy( 1, sOUFormula.getLength() - 1 ); } String sFormula2(sOUFormula2); pNewCell = new ScFormulaCell(pDoc, aAddress, sFormula2,formula::FormulaGrammar::GRAM_ODFF, nMatrixFlag); if (pNewCell) { if (nMatrixFlag == MM_FORMULA) { SCCOL nCols; SCROW nRows; static_cast(pCell)->GetMatColsRows(nCols, nRows); static_cast(pNewCell)->SetMatColsRows(nCols, nRows); } static_cast(pNewCell)->SetInChangeTrack(sal_True); } } pChangeActionContent->SetNewCell(pNewCell, pDoc, EMPTY_STRING); // #i40704# don't overwrite the formula string from above with pCell's content if (pCell->GetCellType() != CELLTYPE_FORMULA) pChangeActionContent->SetNewValue(pCell, pDoc); } } else { DBG_ERROR("wrong cell position"); } } } } } void ScXMLChangeTrackingImportHelper::CreateChangeTrack(ScDocument* pTempDoc) { pDoc = pTempDoc; if (pDoc) { pTrack = new ScChangeTrack(pDoc, aUsers); // #97286# old files didn't store 100th seconds, disable until encountered pTrack->SetTime100thSeconds( sal_False ); ScMyActions::iterator aItr(aActions.begin()); ScMyActions::iterator aEndItr(aActions.end()); while (aItr != aEndItr) { ScChangeAction* pAction = NULL; switch ((*aItr)->nActionType) { case SC_CAT_INSERT_COLS: case SC_CAT_INSERT_ROWS: case SC_CAT_INSERT_TABS: { pAction = CreateInsertAction(static_cast(*aItr)); } break; case SC_CAT_DELETE_COLS: case SC_CAT_DELETE_ROWS: case SC_CAT_DELETE_TABS: { ScMyDelAction* pDelAct = static_cast(*aItr); pAction = CreateDeleteAction(pDelAct); CreateGeneratedActions(pDelAct->aGeneratedList); } break; case SC_CAT_MOVE: { ScMyMoveAction* pMovAct = static_cast(*aItr); pAction = CreateMoveAction(pMovAct); CreateGeneratedActions(pMovAct->aGeneratedList); } break; case SC_CAT_CONTENT: { pAction = CreateContentAction(static_cast(*aItr)); } break; case SC_CAT_REJECT: { pAction = CreateRejectionAction(static_cast(*aItr)); } break; default: { // added to avoid warnings } } if (pAction) pTrack->AppendLoaded(pAction); else { DBG_ERROR("no action"); } ++aItr; } if (pTrack->GetLast()) pTrack->SetActionMax(pTrack->GetLast()->GetActionNumber()); aItr = aActions.begin(); aEndItr = aActions.end(); while (aItr != aEndItr) { SetDependencies(*aItr); if ((*aItr)->nActionType == SC_CAT_CONTENT) ++aItr; else { if (*aItr) delete (*aItr); aItr = aActions.erase(aItr); } } aItr = aActions.begin(); aEndItr = aActions.end(); while (aItr != aEndItr) { DBG_ASSERT((*aItr)->nActionType == SC_CAT_CONTENT, "wrong action type"); SetNewCell(static_cast(*aItr)); if (*aItr) delete (*aItr); aItr = aActions.erase(aItr); } if (aProtect.getLength()) pTrack->SetProtection(aProtect); else if (pDoc->GetChangeTrack() && pDoc->GetChangeTrack()->IsProtected()) pTrack->SetProtection(pDoc->GetChangeTrack()->GetProtection()); if ( pTrack->GetLast() ) pTrack->SetLastSavedActionNumber(pTrack->GetLast()->GetActionNumber()); pDoc->SetChangeTrack(pTrack); } }