diff options
author | Eike Rathke <erack@redhat.com> | 2015-06-25 11:44:46 +0200 |
---|---|---|
committer | Andras Timar <andras.timar@collabora.com> | 2015-08-06 12:51:53 +0200 |
commit | 9f09039c62ef881d5bb10f78fbe28fdfe3cdbaea (patch) | |
tree | 994b175a34bc6aaa2d47b6a46dfc07f71aabcf58 /sc | |
parent | 34258936780b74a211b3d00df8d4f1731b3cfbec (diff) |
TableRef: invalidate table column names on most sheet operations
Kept only on insertions and deletions, but even that may not be useful
as the names aren't updated at any time so even a mere cell change will
bring this out of sync. But serves as a starting point for further
implementation.
Change-Id: Idfede4b03b9f554cd35f984502fce625c725853c
(cherry picked from commit 98ba33677c288ff80c6f2812e85039175b7fcff8)
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/dbdata.hxx | 6 | ||||
-rw-r--r-- | sc/source/core/tool/dbdata.cxx | 58 |
2 files changed, 63 insertions, 1 deletions
diff --git a/sc/inc/dbdata.hxx b/sc/inc/dbdata.hxx index c1d41f934810..b77e218df346 100644 --- a/sc/inc/dbdata.hxx +++ b/sc/inc/dbdata.hxx @@ -110,7 +110,6 @@ public: void SetKeepFmt(bool bSet) { bKeepFmt = bSet; } bool IsStripData() const { return bStripData; } void SetStripData(bool bSet) { bStripData = bSet; } - const ::std::vector< OUString >& GetTableColumnNames() { return maTableColumnNames; } void SetTableColumnNames( const ::std::vector< OUString >& rNames ) { maTableColumnNames = rNames; } OUString GetSourceString() const; @@ -154,6 +153,11 @@ public: SCsCOL nDx, SCsROW nDy, SCsTAB nDz); void ExtendDataArea(ScDocument* pDoc); + +private: + + void AdjustTableColumnNames( UpdateRefMode eUpdateRefMode, SCCOL nDx, SCCOL nCol1, + SCCOL nOldCol1, SCCOL nOldCol2, SCCOL nNewCol1, SCCOL nNewCol2 ); }; class SC_DLLPUBLIC ScDBCollection diff --git a/sc/source/core/tool/dbdata.cxx b/sc/source/core/tool/dbdata.cxx index 34c2f69b2835..c99f893c4fe7 100644 --- a/sc/source/core/tool/dbdata.cxx +++ b/sc/source/core/tool/dbdata.cxx @@ -276,6 +276,8 @@ void ScDBData::GetArea(ScRange& rRange) const void ScDBData::SetArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) { + ::std::vector<OUString>().swap( maTableColumnNames); // invalidate column names/offsets + nTable = nTab; nStartCol = nCol1; nStartRow = nRow1; @@ -488,8 +490,13 @@ void ScDBData::UpdateMoveTab(SCTAB nOldPos, SCTAB nNewPos) bool bChanged = ( nTab != aRange.aStart.Tab() ); if (bChanged) + { + // Save and restore column names, as SetArea() invalidates them. + ::std::vector<OUString> aNames( maTableColumnNames); SetArea( nTab, aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(),aRange.aEnd .Row() ); + maTableColumnNames = aNames; + } // MoveTo ist nicht noetig, wenn nur die Tabelle geaendert ist @@ -510,12 +517,20 @@ void ScDBData::UpdateReference(ScDocument* pDoc, UpdateRefMode eUpdateRefMode, SCTAB theTab2; GetArea( theTab1, theCol1, theRow1, theCol2, theRow2 ); theTab2 = theTab1; + SCCOL nOldCol1 = theCol1, nOldCol2 = theCol2; bool bDoUpdate = ScRefUpdate::Update( pDoc, eUpdateRefMode, nCol1,nRow1,nTab1, nCol2,nRow2,nTab2, nDx,nDy,nDz, theCol1,theRow1,theTab1, theCol2,theRow2,theTab2 ) != UR_NOTHING; if (bDoUpdate) + { + // MoveTo() invalidates column names via SetArea(); adjust, remember + // and set new column offsets for names. + AdjustTableColumnNames( eUpdateRefMode, nDx, nCol1, nOldCol1, nOldCol2, theCol1, theCol2); + ::std::vector<OUString> aNames( maTableColumnNames); MoveTo( theTab1, theCol1, theRow1, theCol2, theRow2 ); + maTableColumnNames = aNames; + } ScRange aRangeAdvSource; if ( GetAdvancedQuerySource(aRangeAdvSource) ) @@ -542,7 +557,50 @@ void ScDBData::ExtendDataArea(ScDocument* pDoc) { // Extend the DB area to include data rows immediately below. // or shrink it if all cells are empty + SCCOL nOldCol1 = nStartCol, nOldCol2 = nEndCol; pDoc->GetDataArea(nTable, nStartCol, nStartRow, nEndCol, nEndRow, false, true); + if (nStartCol != nOldCol1 || nEndCol != nOldCol2) + ::std::vector<OUString>().swap( maTableColumnNames); // invalidate column names/offsets +} + +void ScDBData::AdjustTableColumnNames( UpdateRefMode eUpdateRefMode, SCCOL nDx, SCCOL nCol1, + SCCOL nOldCol1, SCCOL nOldCol2, SCCOL nNewCol1, SCCOL nNewCol2 ) +{ + if (maTableColumnNames.empty()) + return; + + SCCOL nDiff1 = nNewCol1 - nOldCol1; + SCCOL nDiff2 = nNewCol2 - nOldCol2; + if (nDiff1 == nDiff2) + return; // not moved or entirely moved, nothing to do + + ::std::vector<OUString> aNewNames; + if (eUpdateRefMode == URM_INSDEL) + { + // nCol1 is the first column of the block that gets shifted, determine + // the head and tail elements that are to be copied for deletion or + // insertion. + size_t nHead = static_cast<size_t>(::std::max( nCol1 + (nDx < 0 ? nDx : 0) - nOldCol1, 0)); + size_t nTail = static_cast<size_t>(::std::max( nOldCol2 - nCol1 + 1, 0)); + size_t n = nHead + nTail; + if (0 < n && n <= maTableColumnNames.size()) + { + if (nDx > 0) + n += nDx; + aNewNames.resize(n); + // Copy head. + for (size_t i = 0; i < nHead; ++i) + { + aNewNames[i] = maTableColumnNames[i]; + } + // Copy tail, inserted middle range, if any, stays empty. + for (size_t i = n - nTail, j = maTableColumnNames.size() - nTail; i < n; ++i, ++j) + { + aNewNames[i] = maTableColumnNames[j]; + } + } + } // else empty aNewNames invalidates names/offsets + aNewNames.swap( maTableColumnNames); } namespace { |