summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2015-06-25 11:44:46 +0200
committerAndras Timar <andras.timar@collabora.com>2015-08-06 12:51:53 +0200
commit9f09039c62ef881d5bb10f78fbe28fdfe3cdbaea (patch)
tree994b175a34bc6aaa2d47b6a46dfc07f71aabcf58 /sc
parent34258936780b74a211b3d00df8d4f1731b3cfbec (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.hxx6
-rw-r--r--sc/source/core/tool/dbdata.cxx58
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 {