diff options
author | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2011-06-03 06:03:40 +0200 |
---|---|---|
committer | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2011-06-03 06:03:40 +0200 |
commit | ea7fe02f4d149466bb2170b4bf0a45676936112b (patch) | |
tree | 4487bf54ce2f85345bce570cf6e21a9b8a9d570f | |
parent | d4a8a64c218a4640e9701356aa87701d5a80589b (diff) |
improve performance of ScUndoInsertTables::Undo
we can now insert several sheets and then undo in nearly no time
-rw-r--r-- | sc/inc/cell.hxx | 2 | ||||
-rw-r--r-- | sc/inc/column.hxx | 2 | ||||
-rw-r--r-- | sc/inc/compiler.hxx | 2 | ||||
-rw-r--r-- | sc/inc/document.hxx | 1 | ||||
-rw-r--r-- | sc/inc/table.hxx | 2 | ||||
-rw-r--r-- | sc/source/core/data/cell2.cxx | 20 | ||||
-rw-r--r-- | sc/source/core/data/column.cxx | 9 | ||||
-rw-r--r-- | sc/source/core/data/document.cxx | 89 | ||||
-rw-r--r-- | sc/source/core/data/table1.cxx | 11 | ||||
-rw-r--r-- | sc/source/core/tool/compiler.cxx | 28 | ||||
-rw-r--r-- | sc/source/ui/inc/uiitems.hxx | 1 | ||||
-rw-r--r-- | sc/source/ui/inc/viewdata.hxx | 1 | ||||
-rw-r--r-- | sc/source/ui/inc/viewfunc.hxx | 1 | ||||
-rw-r--r-- | sc/source/ui/undo/undotab.cxx | 8 | ||||
-rw-r--r-- | sc/source/ui/view/tabvwsh5.cxx | 7 | ||||
-rw-r--r-- | sc/source/ui/view/viewdata.cxx | 13 | ||||
-rw-r--r-- | sc/source/ui/view/viewfun2.cxx | 45 |
17 files changed, 197 insertions, 45 deletions
diff --git a/sc/inc/cell.hxx b/sc/inc/cell.hxx index 4d257e4d53f5..8384d51772d5 100644 --- a/sc/inc/cell.hxx +++ b/sc/inc/cell.hxx @@ -444,7 +444,7 @@ public: void UpdateInsertTab(SCTAB nTable, SCTAB nNewSheets = 1); void UpdateInsertTabAbs(SCTAB nTable); - sal_Bool UpdateDeleteTab(SCTAB nTable, sal_Bool bIsMove = false); + sal_Bool UpdateDeleteTab(SCTAB nTable, sal_Bool bIsMove = false, SCTAB nSheets = 1); void UpdateMoveTab(SCTAB nOldPos, SCTAB nNewPos, SCTAB nTabNo); void UpdateRenameTab(SCTAB nTable, const String& rName); sal_Bool TestTabRefAbs(SCTAB nTable); diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index b2c202a93031..6ce3bed4639e 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -292,7 +292,7 @@ public: ScDocument* pUndoDoc = NULL ); void UpdateInsertTab( SCTAB nTable, SCTAB nNewSheets = 1); void UpdateInsertTabOnlyCells( SCTAB nTable, SCTAB nNewSheets = 1); - void UpdateDeleteTab( SCTAB nTable, bool bIsMove, ScColumn* pRefUndo = NULL ); + void UpdateDeleteTab( SCTAB nTable, bool bIsMove, ScColumn* pRefUndo = NULL, SCTAB nSheets = 1 ); void UpdateMoveTab(SCTAB nOldPos, SCTAB nNewPos, SCTAB nTabNo); void UpdateCompile( bool bForceIfNameInUse = false ); void UpdateTranspose( const ScRange& rSource, const ScAddress& rDest, diff --git a/sc/inc/compiler.hxx b/sc/inc/compiler.hxx index 614051f9d5f7..1e1d81e73912 100644 --- a/sc/inc/compiler.hxx +++ b/sc/inc/compiler.hxx @@ -445,7 +445,7 @@ public: SCsCOL nDx, SCsROW nDy, SCsTAB nDz ); ScRangeData* UpdateInsertTab(SCTAB nTable, sal_Bool bIsName, SCTAB nNewSheets = 1 ); - ScRangeData* UpdateDeleteTab(SCTAB nTable, sal_Bool bIsMove, sal_Bool bIsName, sal_Bool& bCompile); + ScRangeData* UpdateDeleteTab(SCTAB nTable, sal_Bool bIsMove, sal_Bool bIsName, sal_Bool& bCompile, SCTAB nSheets = 1); ScRangeData* UpdateMoveTab(SCTAB nOldPos, SCTAB nNewPos, sal_Bool bIsName ); bool HasModifiedRange(); diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index abd11159cdc8..b85218cf3fe2 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -579,6 +579,7 @@ public: sal_Bool bExternalDocument = false ); SC_DLLPUBLIC bool InsertTabs( SCTAB nPos, const std::vector<rtl::OUString>& rNames, bool bExternalDocument = false, bool bNamesValid = false ); + SC_DLLPUBLIC bool DeleteTabs( SCTAB nTab, SCTAB nSheets, ScDocument* pRefUndoDoc = NULL ); SC_DLLPUBLIC sal_Bool DeleteTab( SCTAB nTab, ScDocument* pRefUndoDoc = NULL ); SC_DLLPUBLIC sal_Bool RenameTab( SCTAB nTab, const String& rName, sal_Bool bUpdateRef = sal_True, diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx index 1ed9d4ccd206..4f2c8458f9d2 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -477,7 +477,7 @@ public: void UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY ); void UpdateInsertTab(SCTAB nTable, SCTAB nNewSheets = 1); - void UpdateDeleteTab( SCTAB nTable, sal_Bool bIsMove, ScTable* pRefUndo = NULL ); + void UpdateDeleteTab( SCTAB nTable, sal_Bool bIsMove, ScTable* pRefUndo = NULL, SCTAB nSheets = 1 ); void UpdateMoveTab(SCTAB nOldPos, SCTAB nNewPos, SCTAB nTabNo, ScProgress& ); void UpdateCompile( sal_Bool bForceIfNameInUse = false ); void SetTabNo(SCTAB nNewTab); diff --git a/sc/source/core/data/cell2.cxx b/sc/source/core/data/cell2.cxx index dad359414b10..a2735276501b 100644 --- a/sc/source/core/data/cell2.cxx +++ b/sc/source/core/data/cell2.cxx @@ -1142,7 +1142,7 @@ void ScFormulaCell::UpdateInsertTab(SCTAB nTable, SCTAB nNewSheets) ScRangeData* pRangeData; ScCompiler aComp(pDocument, aPos, *pCode); aComp.SetGrammar(pDocument->GetGrammar()); - pRangeData = aComp.UpdateInsertTab( nTable, false ); + pRangeData = aComp.UpdateInsertTab( nTable, false, nNewSheets ); if (pRangeData) // Shared Formula gegen echte Formel { // austauschen sal_Bool bRefChanged; @@ -1152,10 +1152,10 @@ void ScFormulaCell::UpdateInsertTab(SCTAB nTable, SCTAB nNewSheets) ScCompiler aComp2(pDocument, aPos, *pCode); aComp2.SetGrammar(pDocument->GetGrammar()); aComp2.MoveRelWrap(pRangeData->GetMaxCol(), pRangeData->GetMaxRow()); - aComp2.UpdateInsertTab( nTable, false ); + aComp2.UpdateInsertTab( nTable, false, nNewSheets ); // If the shared formula contained a named range/formula containing // an absolute reference to a sheet, those have to be readjusted. - aComp2.UpdateDeleteTab( nTable, false, sal_True, bRefChanged ); + aComp2.UpdateDeleteTab( nTable, false, sal_True, bRefChanged, nNewSheets ); bCompile = sal_True; } // kein StartListeningTo weil pTab[nTab] noch nicht existiert! @@ -1164,21 +1164,21 @@ void ScFormulaCell::UpdateInsertTab(SCTAB nTable, SCTAB nNewSheets) aPos.IncTab(); } -sal_Bool ScFormulaCell::UpdateDeleteTab(SCTAB nTable, sal_Bool bIsMove) +sal_Bool ScFormulaCell::UpdateDeleteTab(SCTAB nTable, sal_Bool bIsMove, SCTAB nSheets) { sal_Bool bRefChanged = false; - sal_Bool bPosChanged = ( aPos.Tab() > nTable ? sal_True : false ); + sal_Bool bPosChanged = ( aPos.Tab() > nTable + nSheets ? sal_True : false ); pCode->Reset(); if( pCode->GetNextReferenceRPN() && !pDocument->IsClipOrUndo() ) { EndListeningTo( pDocument ); // IncTab _nach_ EndListeningTo und _vor_ Compiler UpdateDeleteTab ! if ( bPosChanged ) - aPos.IncTab(-1); + aPos.IncTab(-1*nSheets); ScRangeData* pRangeData; ScCompiler aComp(pDocument, aPos, *pCode); aComp.SetGrammar(pDocument->GetGrammar()); - pRangeData = aComp.UpdateDeleteTab(nTable, bIsMove, false, bRefChanged); + pRangeData = aComp.UpdateDeleteTab(nTable, bIsMove, false, bRefChanged, nSheets); if (pRangeData) // Shared Formula gegen echte Formel { // austauschen pDocument->RemoveFromFormulaTree( this ); // update formula count @@ -1188,10 +1188,10 @@ sal_Bool ScFormulaCell::UpdateDeleteTab(SCTAB nTable, sal_Bool bIsMove) aComp2.SetGrammar(pDocument->GetGrammar()); aComp2.CompileTokenArray(); aComp2.MoveRelWrap(pRangeData->GetMaxCol(), pRangeData->GetMaxRow()); - aComp2.UpdateDeleteTab( nTable, false, false, bRefChanged ); + aComp2.UpdateDeleteTab( nTable, false, false, bRefChanged, nSheets ); // If the shared formula contained a named range/formula containing // an absolute reference to a sheet, those have to be readjusted. - aComp2.UpdateInsertTab( nTable,sal_True ); + aComp2.UpdateInsertTab( nTable,sal_True, nSheets ); // bRefChanged kann beim letzten UpdateDeleteTab zurueckgesetzt worden sein bRefChanged = sal_True; bCompile = sal_True; @@ -1199,7 +1199,7 @@ sal_Bool ScFormulaCell::UpdateDeleteTab(SCTAB nTable, sal_Bool bIsMove) // kein StartListeningTo weil pTab[nTab] noch nicht korrekt! } else if ( bPosChanged ) - aPos.IncTab(-1); + aPos.IncTab(-1*nSheets); return bRefChanged; } diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx index 174a858fbe34..e21e4a5ad31d 100644 --- a/sc/source/core/data/column.cxx +++ b/sc/source/core/data/column.cxx @@ -1769,10 +1769,13 @@ void ScColumn::UpdateInsertTabAbs(SCTAB nTable) } -void ScColumn::UpdateDeleteTab( SCTAB nTable, bool bIsMove, ScColumn* pRefUndo ) +void ScColumn::UpdateDeleteTab( SCTAB nTable, bool bIsMove, ScColumn* pRefUndo, SCTAB nSheets ) { if (nTab > nTable) - pAttrArray->SetTab(--nTab); + { + nTab -= nSheets; + pAttrArray->SetTab(nTab); + } if (pItems) for (SCSIZE i = 0; i < nCount; i++) @@ -1785,7 +1788,7 @@ void ScColumn::UpdateDeleteTab( SCTAB nTable, bool bIsMove, ScColumn* pRefUndo ) back the formula cell while keeping the original note. */ ScBaseCell* pSave = pRefUndo ? pOld->CloneWithoutNote( *pDocument ) : 0; - bool bChanged = pOld->UpdateDeleteTab(nTable, bIsMove); + bool bChanged = pOld->UpdateDeleteTab(nTable, bIsMove, nSheets); if ( nRow != pItems[i].nRow ) Search( nRow, i ); // Listener geloescht/eingefuegt? diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index aaa1585cbd36..772087de0c43 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -595,7 +595,7 @@ sal_Bool ScDocument::DeleteTab( SCTAB nTab, ScDocument* pRefUndoDoc ) // normal reference update - aRange.aEnd.SetTab( static_cast<SCTAB>(pTab.size()) ); + aRange.aEnd.SetTab( static_cast<SCTAB>(pTab.size())-1 ); xColNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,-1 ); xRowNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,-1 ); if (pRangeName) @@ -651,6 +651,93 @@ sal_Bool ScDocument::DeleteTab( SCTAB nTab, ScDocument* pRefUndoDoc ) } +bool ScDocument::DeleteTabs( SCTAB nTab, SCTAB nSheets, ScDocument* pRefUndoDoc ) +{ + bool bValid = false; + if (VALIDTAB(nTab) && (nTab + nSheets) < static_cast<SCTAB>(pTab.size())) + { + if (pTab[nTab]) + { + SCTAB nTabCount = static_cast<SCTAB>(pTab.size()); + if (nTabCount > nSheets) + { + bool bOldAutoCalc = GetAutoCalc(); + SetAutoCalc( false ); // avoid multiple calculations + for (SCTAB aTab = 0; aTab < nSheets; ++aTab) + { + ScRange aRange( 0, 0, nTab, MAXCOL, MAXROW, nTab + aTab ); + DelBroadcastAreasInRange( aRange ); + + // #i8180# remove database ranges etc. that are on the deleted tab + // (restored in undo with ScRefUndoData) + + xColNameRanges->DeleteOnTab( nTab + aTab ); + xRowNameRanges->DeleteOnTab( nTab + aTab ); + pDBCollection->DeleteOnTab( nTab + aTab ); + if (pDPCollection) + pDPCollection->DeleteOnTab( nTab + aTab ); + if (pDetOpList) + pDetOpList->DeleteOnTab( nTab + aTab ); + DeleteAreaLinksOnTab( nTab + aTab ); + if (pRangeName) + pRangeName->UpdateTabRef( nTab + aTab, 2 ); + } + // normal reference update + + ScRange aRange( 0, 0, nTab, MAXCOL, MAXROW, nTabCount - 1 ); + xColNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,-1*nSheets ); + xRowNameRanges->UpdateReference( URM_INSDEL, this, aRange, 0,0,-1*nSheets ); + pDBCollection->UpdateReference( + URM_INSDEL, 0,0,nTab, MAXCOL,MAXROW,MAXTAB, 0,0,-1*nSheets ); + if (pDPCollection) + pDPCollection->UpdateReference( URM_INSDEL, aRange, 0,0,-1*nSheets ); + if (pDetOpList) + pDetOpList->UpdateReference( this, URM_INSDEL, aRange, 0,0,-1*nSheets ); + UpdateChartRef( URM_INSDEL, 0,0,nTab, MAXCOL,MAXROW,MAXTAB, 0,0,-1*nSheets ); + UpdateRefAreaLinks( URM_INSDEL, aRange, 0,0,-1*nSheets ); + if ( pCondFormList ) + pCondFormList->UpdateReference( URM_INSDEL, aRange, 0,0,-1*nSheets ); + if ( pValidationList ) + pValidationList->UpdateReference( URM_INSDEL, aRange, 0,0,-1*nSheets ); + if ( pUnoBroadcaster ) + pUnoBroadcaster->Broadcast( ScUpdateRefHint( URM_INSDEL, aRange, 0,0,-1*nSheets ) ); + + SCTAB i; + for (i=0; i< static_cast<SCTAB>(pTab.size()); i++) + if (pTab[i]) + pTab[i]->UpdateDeleteTab(nTab,false, + pRefUndoDoc ? pRefUndoDoc->pTab[i] : 0,nSheets); + pTab.erase(pTab.begin()+ nTab, pTab.begin() + nTab + nSheets); + // UpdateBroadcastAreas must be called between UpdateDeleteTab, + // which ends listening, and StartAllListeners, to not modify + // areas that are to be inserted by starting listeners. + UpdateBroadcastAreas( URM_INSDEL, aRange, 0,0,-1*nSheets); + TableContainer::iterator it = pTab.begin(); + for (; it != pTab.end(); ++it) + if ( *it ) + (*it)->UpdateCompile(); + // Excel-Filter deletes some Tables while loading, Listeners will + // only be triggered after the loading is done. + if ( !bInsertingFromOtherDoc ) + { + it = pTab.begin(); + for (; it != pTab.end(); ++it) + if ( *it ) + (*it)->StartAllListeners(); + SetDirty(); + } + // sheet names of references are not valid until sheet is deleted + pChartListenerCollection->UpdateScheduledSeriesRanges(); + + SetAutoCalc( bOldAutoCalc ); + bValid = true; + } + } + } + return bValid; +} + + sal_Bool ScDocument::RenameTab( SCTAB nTab, const String& rName, sal_Bool /* bUpdateRef */, sal_Bool bExternalDocument ) { diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx index 87b1cdb15827..4c03e1b21170 100644 --- a/sc/source/core/data/table1.cxx +++ b/sc/source/core/data/table1.cxx @@ -1402,21 +1402,22 @@ void ScTable::UpdateInsertTab(SCTAB nTable, SCTAB nNewSheets) { if (nTab >= nTable) nTab += nNewSheets; - for (SCCOL i=0; i <= MAXCOL; i++) aCol[i].UpdateInsertTab(nTable); + for (SCCOL i=0; i <= MAXCOL; i++) aCol[i].UpdateInsertTab(nTable, nNewSheets); if (IsStreamValid()) SetStreamValid(false); } -void ScTable::UpdateDeleteTab( SCTAB nTable, sal_Bool bIsMove, ScTable* pRefUndo ) +void ScTable::UpdateDeleteTab( SCTAB nTable, sal_Bool bIsMove, ScTable* pRefUndo, SCTAB nSheets ) { - if (nTab > nTable) nTab--; + if (nTab > nTable) + nTab -= nSheets; SCCOL i; if (pRefUndo) - for (i=0; i <= MAXCOL; i++) aCol[i].UpdateDeleteTab(nTable, bIsMove, &pRefUndo->aCol[i]); + for (i=0; i <= MAXCOL; i++) aCol[i].UpdateDeleteTab(nTable, bIsMove, &pRefUndo->aCol[i], nSheets); else - for (i=0; i <= MAXCOL; i++) aCol[i].UpdateDeleteTab(nTable, bIsMove, NULL); + for (i=0; i <= MAXCOL; i++) aCol[i].UpdateDeleteTab(nTable, bIsMove, NULL, nSheets); if (IsStreamValid()) SetStreamValid(false); diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx index 95e9bd2f5f9f..6df80d8ba7f7 100644 --- a/sc/source/core/tool/compiler.cxx +++ b/sc/source/core/tool/compiler.cxx @@ -4484,7 +4484,7 @@ ScRangeData* ScCompiler::UpdateInsertTab( SCTAB nTable, sal_Bool bIsName , SCTAB { ScRangeData* pRangeData = NULL; SCTAB nPosTab = aPos.Tab(); // _after_ incremented! - SCTAB nOldPosTab = ((nPosTab > nTable) ? (nPosTab - 1) : nPosTab); + SCTAB nOldPosTab = ((nPosTab > nTable) ? (nPosTab - nNewSheets) : nPosTab); sal_Bool bIsRel = false; ScToken* t; pArr->Reset(); @@ -4515,7 +4515,7 @@ ScRangeData* ScCompiler::UpdateInsertTab( SCTAB nTable, sal_Bool bIsName , SCTAB rRef.nTab = sal::static_int_cast<SCsTAB>( rRef.nTab + pDoc->GetTableCount() ); // was a wrap } if (nTable <= rRef.nTab) - ++rRef.nTab; + rRef.nTab += nNewSheets; rRef.nRelTab = rRef.nTab - nPosTab; } else @@ -4532,7 +4532,7 @@ ScRangeData* ScCompiler::UpdateInsertTab( SCTAB nTable, sal_Bool bIsName , SCTAB rRef.nTab = sal::static_int_cast<SCsTAB>( rRef.nTab + pDoc->GetTableCount() ); // was a wrap } if (nTable <= rRef.nTab) - ++rRef.nTab; + rRef.nTab += nNewSheets; rRef.nRelTab = rRef.nTab - nPosTab; } else @@ -4563,7 +4563,7 @@ ScRangeData* ScCompiler::UpdateInsertTab( SCTAB nTable, sal_Bool bIsName , SCTAB rRef1.nTab = sal::static_int_cast<SCsTAB>( rRef1.nTab + pDoc->GetTableCount() ); // was a wrap } if (nTable <= rRef1.nTab) - ++rRef1.nTab; + rRef1.nTab += nNewSheets; rRef1.nRelTab = rRef1.nTab - nPosTab; } if ( t->GetType() == svDoubleRef ) @@ -4578,7 +4578,7 @@ ScRangeData* ScCompiler::UpdateInsertTab( SCTAB nTable, sal_Bool bIsName , SCTAB rRef2.nTab = sal::static_int_cast<SCsTAB>( rRef2.nTab + pDoc->GetTableCount() ); // was a wrap } if (nTable <= rRef2.nTab) - ++rRef2.nTab; + rRef2.nTab += nNewSheets; rRef2.nRelTab = rRef2.nTab - nPosTab; } } @@ -4589,12 +4589,12 @@ ScRangeData* ScCompiler::UpdateInsertTab( SCTAB nTable, sal_Bool bIsName , SCTAB } ScRangeData* ScCompiler::UpdateDeleteTab(SCTAB nTable, sal_Bool /* bIsMove */, sal_Bool bIsName, - sal_Bool& rChanged) + sal_Bool& rChanged, SCTAB nSheets) { ScRangeData* pRangeData = NULL; SCTAB nTab, nTab2; SCTAB nPosTab = aPos.Tab(); // _after_ decremented! - SCTAB nOldPosTab = ((nPosTab >= nTable) ? (nPosTab + 1) : nPosTab); + SCTAB nOldPosTab = ((nPosTab >= nTable) ? (nPosTab + nSheets) : nPosTab); rChanged = false; sal_Bool bIsRel = false; ScToken* t; @@ -4626,7 +4626,7 @@ ScRangeData* ScCompiler::UpdateDeleteTab(SCTAB nTable, sal_Bool /* bIsMove */, s nTab = rRef.nTab; if ( nTable < nTab ) { - rRef.nTab = nTab - 1; + rRef.nTab = nTab - nSheets; rChanged = sal_True; } else if ( nTable == nTab ) @@ -4639,7 +4639,7 @@ ScRangeData* ScCompiler::UpdateDeleteTab(SCTAB nTable, sal_Bool /* bIsMove */, s else nTab2 = rRef2.nTab; if ( nTab == nTab2 - || (nTab+1) >= pDoc->GetTableCount() ) + || (nTab+nSheets) >= pDoc->GetTableCount() ) { rRef.nTab = MAXTAB+1; rRef.SetTabDeleted( sal_True ); @@ -4669,13 +4669,13 @@ ScRangeData* ScCompiler::UpdateDeleteTab(SCTAB nTable, sal_Bool /* bIsMove */, s nTab = rRef.nTab; if ( nTable < nTab ) { - rRef.nTab = nTab - 1; + rRef.nTab = nTab - nSheets; rChanged = sal_True; } else if ( nTable == nTab ) { if ( !t->GetDoubleRef().Ref1.IsTabDeleted() ) - rRef.nTab = nTab - 1; // shrink area + rRef.nTab = nTab - nSheets; // shrink area else { rRef.nTab = MAXTAB+1; @@ -4712,7 +4712,7 @@ ScRangeData* ScCompiler::UpdateDeleteTab(SCTAB nTable, sal_Bool /* bIsMove */, s nTab = rRef1.nTab; if ( nTable < nTab ) { - rRef1.nTab = nTab - 1; + rRef1.nTab = nTab - nSheets; rChanged = sal_True; } else if ( nTable == nTab ) @@ -4753,13 +4753,13 @@ ScRangeData* ScCompiler::UpdateDeleteTab(SCTAB nTable, sal_Bool /* bIsMove */, s nTab = rRef2.nTab; if ( nTable < nTab ) { - rRef2.nTab = nTab - 1; + rRef2.nTab = nTab - nSheets; rChanged = sal_True; } else if ( nTable == nTab ) { if ( !rRef1.IsTabDeleted() ) - rRef2.nTab = nTab - 1; // shrink area + rRef2.nTab = nTab - nSheets; // shrink area else { rRef2.nTab = MAXTAB+1; diff --git a/sc/source/ui/inc/uiitems.hxx b/sc/source/ui/inc/uiitems.hxx index f65c5a0f9542..7f71a152684e 100644 --- a/sc/source/ui/inc/uiitems.hxx +++ b/sc/source/ui/inc/uiitems.hxx @@ -93,6 +93,7 @@ public: #define SC_TAB_COPIED 4 #define SC_TAB_HIDDEN 5 #define SC_TABS_INSERTED 6 +#define SC_TABS_DELETED 7 class ScTablesHint : public SfxHint { diff --git a/sc/source/ui/inc/viewdata.hxx b/sc/source/ui/inc/viewdata.hxx index f09069d040c8..d0160ba2708e 100644 --- a/sc/source/ui/inc/viewdata.hxx +++ b/sc/source/ui/inc/viewdata.hxx @@ -279,6 +279,7 @@ public: void InsertTab( SCTAB nTab ); void InsertTabs( SCTAB nTab, SCTAB nNewSheets ); void DeleteTab( SCTAB nTab ); + void DeleteTabs( SCTAB nTab, SCTAB nSheets ); void CopyTab( SCTAB nSrcTab, SCTAB nDestTab ); void MoveTab( SCTAB nSrcTab, SCTAB nDestTab ); diff --git a/sc/source/ui/inc/viewfunc.hxx b/sc/source/ui/inc/viewfunc.hxx index a0914aa49899..bfec3eee672d 100644 --- a/sc/source/ui/inc/viewfunc.hxx +++ b/sc/source/ui/inc/viewfunc.hxx @@ -267,6 +267,7 @@ public: sal_Bool DeleteTable( SCTAB nTabNr, sal_Bool bRecord = true ); sal_Bool DeleteTables(const std::vector<SCTAB>& TheTabs, sal_Bool bRecord = true ); + bool DeleteTables(SCTAB nTab, SCTAB nSheets); sal_Bool RenameTable( const String& rName, SCTAB nTabNr ); void MoveTable( sal_uInt16 nDestDocNo, SCTAB nDestTab, sal_Bool bCopy, const String* pNewTabName = NULL ); diff --git a/sc/source/ui/undo/undotab.cxx b/sc/source/ui/undo/undotab.cxx index 95b524b47a1c..5d61267fd3e8 100644 --- a/sc/source/ui/undo/undotab.cxx +++ b/sc/source/ui/undo/undotab.cxx @@ -243,13 +243,7 @@ void ScUndoInsertTables::Undo() pDocShell->SetInUndo( sal_True ); //! BeginUndo bDrawIsInUndo = sal_True; - vector<SCTAB> TheTabs; - for(SCTAB i=0; i< static_cast<SCTAB>(aNameList.size()); ++i) - { - TheTabs.push_back(nTab+i); - } - pViewShell->DeleteTables( TheTabs, false ); - TheTabs.clear(); + pViewShell->DeleteTables( nTab, static_cast<SCTAB>(aNameList.size()) ); bDrawIsInUndo = false; pDocShell->SetInUndo( false ); //! EndUndo diff --git a/sc/source/ui/view/tabvwsh5.cxx b/sc/source/ui/view/tabvwsh5.cxx index 4b47f9610108..1bc112d13e78 100644 --- a/sc/source/ui/view/tabvwsh5.cxx +++ b/sc/source/ui/view/tabvwsh5.cxx @@ -242,6 +242,9 @@ void ScTabViewShell::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) case SC_TABS_INSERTED: GetViewData()->InsertTabs( nTab1, nTab2 ); break; + case SC_TABS_DELETED: + GetViewData()->DeleteTabs( nTab1, nTab2 ); + break; default: OSL_FAIL("unbekannter ScTablesHint"); } @@ -289,6 +292,10 @@ void ScTabViewShell::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) if ( nTab1 <= nNewTab ) nNewTab += nTab2; break; + case SC_TABS_DELETED: + if ( nTab1 < nNewTab ) + nNewTab -= nTab2; + break; } ScDocument* pDoc = GetViewData()->GetDocument(); diff --git a/sc/source/ui/view/viewdata.cxx b/sc/source/ui/view/viewdata.cxx index 17d7acde30c3..551dffbb2b67 100644 --- a/sc/source/ui/view/viewdata.cxx +++ b/sc/source/ui/view/viewdata.cxx @@ -495,6 +495,19 @@ void ScViewData::DeleteTab( SCTAB nTab ) aMarkData.DeleteTab( nTab ); } +void ScViewData::DeleteTabs( SCTAB nTab, SCTAB nSheets ) +{ + for (SCTAB aTab = 0; aTab < nSheets; ++aTab) + { + aMarkData.DeleteTab( nTab + aTab ); + delete pTabData[nTab + aTab]; + } + + pTabData.erase(pTabData.begin() + nTab, pTabData.begin()+ nTab+nSheets); + UpdateThis(); + +} + void ScViewData::CopyTab( SCTAB nSrcTab, SCTAB nDestTab ) { if (nDestTab==SC_TAB_APPEND) diff --git a/sc/source/ui/view/viewfun2.cxx b/sc/source/ui/view/viewfun2.cxx index a5bbae6c4fe4..16402be06c35 100644 --- a/sc/source/ui/view/viewfun2.cxx +++ b/sc/source/ui/view/viewfun2.cxx @@ -2089,11 +2089,54 @@ sal_Bool ScViewFunc::DeleteTable( SCTAB nTab, sal_Bool bRecord ) return bSuccess; } +//only use this method for undo for now, all sheets must be connected +//this method doesn't support undo for now, merge it when it with the other method later +bool ScViewFunc::DeleteTables( const SCTAB nTab, SCTAB nSheets ) +{ + ScDocShell* pDocSh = GetViewData()->GetDocShell(); + ScDocument* pDoc = pDocSh->GetDocument(); + bool bVbaEnabled = pDoc->IsInVBAMode(); + SCTAB nNewTab = nTab; + WaitObject aWait( GetFrameWin() ); + + while ( nNewTab > 0 && !pDoc->IsVisible( nNewTab ) ) + --nNewTab; + + if (pDoc->DeleteTabs(nTab, nSheets, NULL)) + { + if( bVbaEnabled ) + { + for (SCTAB aTab = 0; aTab < nSheets; ++aTab) + { + String sCodeName; + bool bHasCodeName = pDoc->GetCodeName( nTab + aTab, sCodeName ); + if ( bHasCodeName ) + VBA_DeleteModule( *pDocSh, sCodeName ); + } + } + + pDocSh->Broadcast( ScTablesHint( SC_TABS_DELETED, nTab, nSheets ) ); + if ( nNewTab >= pDoc->GetTableCount() ) + nNewTab = pDoc->GetTableCount() - 1; + SetTabNo( nNewTab, sal_True ); + + pDocSh->PostPaintExtras(); + pDocSh->SetDocumentModified(); + + SfxApplication* pSfxApp = SFX_APP(); // Navigator + pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) ); + pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) ); + pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) ); + return true; + } + return false; +} + sal_Bool ScViewFunc::DeleteTables(const vector<SCTAB> &TheTabs, sal_Bool bRecord ) { ScDocShell* pDocSh = GetViewData()->GetDocShell(); ScDocument* pDoc = pDocSh->GetDocument(); - sal_Bool bVbaEnabled = pDoc ? pDoc->IsInVBAMode() : false; + sal_Bool bVbaEnabled = pDoc->IsInVBAMode(); SCTAB nNewTab = TheTabs[0]; WaitObject aWait( GetFrameWin() ); if (bRecord && !pDoc->IsUndoEnabled()) |