sc/inc/dbdata.hxx | 6 ++ sc/inc/document.hxx | 1 sc/inc/rangelst.hxx | 1 sc/source/core/data/documen3.cxx | 6 ++ sc/source/core/tool/dbdata.cxx | 82 ++++++++++++++++++++++++++++++++------- sc/source/core/tool/rangelst.cxx | 9 ++++ sc/source/ui/docshell/docsh.cxx | 18 ++++++++ sc/source/ui/inc/docsh.hxx | 6 ++ 8 files changed, 115 insertions(+), 14 deletions(-)
New commits: commit bf1498a15b1c3105f5ab38896f6d98c3f1729be9 Author: Eike Rathke <[email protected]> Date: Thu Sep 3 00:27:35 2015 +0200 introduce ScRangeList::Join(const ScRangeList&) diff --git a/sc/inc/rangelst.hxx b/sc/inc/rangelst.hxx index 062e618..6a9e81c 100644 --- a/sc/inc/rangelst.hxx +++ b/sc/inc/rangelst.hxx @@ -48,6 +48,7 @@ public: sal_Unicode cDelimiter = 0 ) const; void Join( const ScRange&, bool bIsInList = false ); + void Join( const ScRangeList& ); bool UpdateReference( UpdateRefMode, ScDocument*, const ScRange& rWhere, diff --git a/sc/source/core/tool/rangelst.cxx b/sc/source/core/tool/rangelst.cxx index d4bc70e..9243a34 100644 --- a/sc/source/core/tool/rangelst.cxx +++ b/sc/source/core/tool/rangelst.cxx @@ -349,6 +349,15 @@ void ScRangeList::Join( const ScRange& r, bool bIsInList ) Append( r ); } +void ScRangeList::Join( const ScRangeList& r ) +{ + if (this == &r) + return; + + for (auto const& it : r.maRanges) + Join( *it ); +} + bool ScRangeList::operator==( const ScRangeList& r ) const { if ( this == &r ) commit f0744793c85f6305201f5122d5a4376eb6df9ae6 Author: Eike Rathke <[email protected]> Date: Wed Sep 2 20:52:15 2015 +0200 comment a nice-to-have idea Change-Id: If03dba2fa7394ec898cb6d87e06bc85171319fcd diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx index 560ba3e..84dff20 100644 --- a/sc/source/ui/docshell/docsh.cxx +++ b/sc/source/ui/docshell/docsh.cxx @@ -3069,6 +3069,10 @@ ScDocShellModificator::~ScDocShellModificator() ScDocument& rDoc = rDocShell.GetDocument(); if (!maContentModified.empty() && !rDoc.IsImportingXML()) { + /* TODO: it would be nice to join a pending list with the next + * instance further down in the stack so that only the last one + * popped actually does the work. For that we'd need a parent or keep a + * master list at ScDocShell. */ for (size_t i=0, n = maContentModified.size(); i < n; ++i) { const ScRange* p = maContentModified[i]; commit 0347ba13460fdd33ca77efa53457ee66651f189b Author: Eike Rathke <[email protected]> Date: Wed Sep 2 20:29:35 2015 +0200 TableRef: use ScRangeList instead of vector for Join() ... so adjacent areas result in one call to RefreshTableColumnNames(). Change-Id: I1c42a37cbe9630b66504654fec021e39f0c0e67c diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx index 5acd5b4..560ba3e 100644 --- a/sc/source/ui/docshell/docsh.cxx +++ b/sc/source/ui/docshell/docsh.cxx @@ -3067,10 +3067,14 @@ ScDocShellModificator::ScDocShellModificator( ScDocShell& rDS ) ScDocShellModificator::~ScDocShellModificator() { ScDocument& rDoc = rDocShell.GetDocument(); - if (!mvContentModified.empty() && !rDoc.IsImportingXML()) + if (!maContentModified.empty() && !rDoc.IsImportingXML()) { - for (auto const& it : mvContentModified) - rDoc.RefreshTableColumnNames( it); + for (size_t i=0, n = maContentModified.size(); i < n; ++i) + { + const ScRange* p = maContentModified[i]; + if (p) + rDoc.RefreshTableColumnNames( *p); + } } rDoc.SetAutoCalcShellDisabled( bAutoCalcShellDisabled ); if ( !bAutoCalcShellDisabled && rDocShell.IsDocumentModifiedPending() ) @@ -3100,7 +3104,7 @@ void ScDocShellModificator::SetDocumentModified() void ScDocShellModificator::AppendCellContentModified( const ScRange& rRange ) { - mvContentModified.push_back( rRange); + maContentModified.Join( rRange); } bool ScDocShell::IsChangeRecording() const diff --git a/sc/source/ui/inc/docsh.hxx b/sc/source/ui/inc/docsh.hxx index 7aab3ff..3c4c7d9 100644 --- a/sc/source/ui/inc/docsh.hxx +++ b/sc/source/ui/inc/docsh.hxx @@ -453,7 +453,7 @@ typedef tools::SvRef<ScDocShell> ScDocShellRef; */ class SC_DLLPUBLIC ScDocShellModificator { - ::std::vector<ScRange> mvContentModified; + ScRangeList maContentModified; ScDocShell& rDocShell; boost::scoped_ptr<ScRefreshTimerProtector> mpProtector; bool bAutoCalcShellDisabled; commit 034b1b724aeed9ae02990354caa2a402a13386c0 Author: Eike Rathke <[email protected]> Date: Wed Sep 2 20:22:44 2015 +0200 TableRef: ensure column name vector has the minimum needed size ... otherwise refresh completely. Change-Id: I51b2a87a1c61a0ceef0424192f3b3e9cef24174b diff --git a/sc/source/core/tool/dbdata.cxx b/sc/source/core/tool/dbdata.cxx index 156a2fd..d6e2a52 100644 --- a/sc/source/core/tool/dbdata.cxx +++ b/sc/source/core/tool/dbdata.cxx @@ -744,7 +744,8 @@ void ScDBData::RefreshTableColumnNames( ScDocument* pDoc, const ScRange& rRange if (!aIntersection.IsValid()) return; - if (maTableColumnNames.empty()) + if (maTableColumnNames.empty() || + maTableColumnNames.size() < static_cast<size_t>(aIntersection.aEnd.Col() - nStartCol + 1)) { RefreshTableColumnNames( pDoc); return; commit e716e43c3ba2397ddcea8659981e9ebdadda639b Author: Eike Rathke <[email protected]> Date: Wed Sep 2 19:57:16 2015 +0200 TableRef: factor out and reuse SetTableColumnName() Change-Id: Ie18530e3fd9d7028a0f36646c56b6ff4375e6b2d diff --git a/sc/source/core/tool/dbdata.cxx b/sc/source/core/tool/dbdata.cxx index 82ee2c6..156a2fd 100644 --- a/sc/source/core/tool/dbdata.cxx +++ b/sc/source/core/tool/dbdata.cxx @@ -643,6 +643,23 @@ public: private: OUString maSearchName; }; + +/** Set a numbered table column name at given nIndex, preventing duplicates, + numbering starting at nCount. No check whether nIndex is valid. */ +void SetTableColumnName( ::std::vector<OUString>& rVec, size_t nIndex, const OUString& rName, sal_Int32 nCount ) +{ + do + { + OUString aStr( rName + OUString::number( nCount)); + auto it( ::std::find_if( rVec.begin(), rVec.end(), TableColumnNameSearch( aStr))); + if (it == rVec.end()) + { + rVec[nIndex] = aStr; + break; // do while + } + ++nCount; + } while(true); +} } void ScDBData::RefreshTableColumnNames( ScDocument* pDoc ) @@ -708,20 +725,7 @@ void ScDBData::RefreshTableColumnNames( ScDocument* pDoc ) for (size_t i=0, n=aNewNames.size(); i < n; ++i) { if (aNewNames[i].isEmpty()) - { - size_t nCount = i+1; - do - { - OUString aStr( aColumn + OUString::number( nCount)); - auto it( ::std::find_if( aNewNames.begin(), aNewNames.end(), TableColumnNameSearch( aStr))); - if (it == aNewNames.end()) - { - aNewNames[i] = aStr; - break; // do while - } - ++nCount; - } while(true); - } + SetTableColumnName( aNewNames, i, aColumn, i+1); } } @@ -760,6 +764,13 @@ void ScDBData::RefreshTableColumnNames( ScDocument* pDoc, const ScRange& rRange const OUString& rStr = pCell->getString( pDoc); if (!rStr.isEmpty()) maTableColumnNames[nCol-nStartCol] = rStr; + else + { + // Usually this is called for only a few positions of which + // most are not empty, so init from resource only if necessary. + OUString aColumn( ScGlobal::GetRscString(STR_COLUMN)); + SetTableColumnName( maTableColumnNames, nCol-nStartCol, aColumn, nCol-nStartCol+1); + } } } } commit b2e5de0b998fac091452190d0386b1d998900399 Author: Eike Rathke <[email protected]> Date: Wed Sep 2 19:50:34 2015 +0200 replace for with while 'i' was unused now.. Change-Id: I1ee7c5af75d049b0dfec6d3a17d730503c71ffc6 diff --git a/sc/source/core/tool/dbdata.cxx b/sc/source/core/tool/dbdata.cxx index cf86a1e..82ee2c6 100644 --- a/sc/source/core/tool/dbdata.cxx +++ b/sc/source/core/tool/dbdata.cxx @@ -753,7 +753,7 @@ void ScDBData::RefreshTableColumnNames( ScDocument* pDoc, const ScRange& rRange ScRefCellValue* pCell; SCCOL nCol; SCROW nRow; - for (size_t i=0; (pCell = aIter.GetNext( nCol, nRow)) != nullptr; ++i) + while((pCell = aIter.GetNext( nCol, nRow)) != nullptr) { if (pCell->hasString()) { commit 834eddc8f75fa73b36f3ab5804104829809d8949 Author: Eike Rathke <[email protected]> Date: Wed Sep 2 19:31:29 2015 +0200 TableRef: add RefreshTableColumnNames() from range Change-Id: I32a47e306469aec5fe366a6621129e14b0d49c13 diff --git a/sc/inc/dbdata.hxx b/sc/inc/dbdata.hxx index efe0d2f..22ccc329 100644 --- a/sc/inc/dbdata.hxx +++ b/sc/inc/dbdata.hxx @@ -125,6 +125,10 @@ public: /** Refresh/update the column names with the header row's cell contents. */ SC_DLLPUBLIC void RefreshTableColumnNames( ScDocument* pDoc ); + /** Refresh/update the column names with the header row's cell contents + within the given range. */ + void RefreshTableColumnNames( ScDocument* pDoc, const ScRange& rRange ); + /** Finds the column named rName and returns the corresponding offset within the table. @returns -1 if not found. @@ -283,6 +287,8 @@ public: ScDBData* GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2); ScDBData* GetDBNearCursor(SCCOL nCol, SCROW nRow, SCTAB nTab ); + void RefreshTableColumnNames( const ScRange& rRange ); + void DeleteOnTab( SCTAB nTab ); void UpdateReference(UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1, diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index 9ea6729..c19bc6f 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -570,6 +570,7 @@ public: ScDBData* GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, ScDBDataPortion ePortion); const ScDBData* GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const; ScDBData* GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2); + void RefreshTableColumnNames( const ScRange& rRange ); SC_DLLPUBLIC const ScRangeData* GetRangeAtBlock( const ScRange& rBlock, OUString* pName=NULL ) const; diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx index 32791da..53dff92 100644 --- a/sc/source/core/data/documen3.cxx +++ b/sc/source/core/data/documen3.cxx @@ -313,6 +313,12 @@ ScDBData* ScDocument::GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nC return NULL; } +void ScDocument::RefreshTableColumnNames( const ScRange& rRange ) +{ + if (pDBCollection) + pDBCollection->RefreshTableColumnNames( rRange); +} + bool ScDocument::HasPivotTable() const { return pDPCollection && pDPCollection->GetCount(); diff --git a/sc/source/core/tool/dbdata.cxx b/sc/source/core/tool/dbdata.cxx index 825e6ca..cf86a1e 100644 --- a/sc/source/core/tool/dbdata.cxx +++ b/sc/source/core/tool/dbdata.cxx @@ -728,6 +728,42 @@ void ScDBData::RefreshTableColumnNames( ScDocument* pDoc ) aNewNames.swap( maTableColumnNames); } +void ScDBData::RefreshTableColumnNames( ScDocument* pDoc, const ScRange& rRange ) +{ + if (!HasHeader()) + return; + + ScRange aRange( ScAddress::UNINITIALIZED); + GetArea( aRange); + aRange.aEnd.SetRow( aRange.aStart.Row()); + ScRange aIntersection( aRange.Intersection( rRange)); + if (!aIntersection.IsValid()) + return; + + if (maTableColumnNames.empty()) + { + RefreshTableColumnNames( pDoc); + return; + } + + // Update column names from cells in intersecting header range, but don't + // set names to empty string. + ScHorizontalCellIterator aIter( pDoc, nTable, + aIntersection.aStart.Col(), nStartRow, aIntersection.aEnd.Col(), nStartRow); + ScRefCellValue* pCell; + SCCOL nCol; + SCROW nRow; + for (size_t i=0; (pCell = aIter.GetNext( nCol, nRow)) != nullptr; ++i) + { + if (pCell->hasString()) + { + const OUString& rStr = pCell->getString( pDoc); + if (!rStr.isEmpty()) + maTableColumnNames[nCol-nStartCol] = rStr; + } + } +} + sal_Int32 ScDBData::GetColumnNameOffset( const OUString& rName ) const { if (maTableColumnNames.empty()) @@ -1173,6 +1209,12 @@ ScDBData* ScDBCollection::GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCO return NULL; } +void ScDBCollection::RefreshTableColumnNames( const ScRange& rRange ) +{ + for (auto const& it : maNamedDBs) + it->RefreshTableColumnNames( pDoc, rRange); +} + void ScDBCollection::DeleteOnTab( SCTAB nTab ) { FindByTable func(nTab); diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx index db72e8e..5acd5b4 100644 --- a/sc/source/ui/docshell/docsh.cxx +++ b/sc/source/ui/docshell/docsh.cxx @@ -3067,6 +3067,11 @@ ScDocShellModificator::ScDocShellModificator( ScDocShell& rDS ) ScDocShellModificator::~ScDocShellModificator() { ScDocument& rDoc = rDocShell.GetDocument(); + if (!mvContentModified.empty() && !rDoc.IsImportingXML()) + { + for (auto const& it : mvContentModified) + rDoc.RefreshTableColumnNames( it); + } rDoc.SetAutoCalcShellDisabled( bAutoCalcShellDisabled ); if ( !bAutoCalcShellDisabled && rDocShell.IsDocumentModifiedPending() ) rDocShell.SetDocumentModified(); // last one shuts off the lights commit 1cb61611c2308df86bf9acfafe25faff624dad26 Author: Eike Rathke <[email protected]> Date: Wed Sep 2 17:23:41 2015 +0200 add ScDocShellModificator::AppendCellContentModified() ... e.g. for future ScDBData column names update. Change-Id: I893b494c50a278022d3ea4fa73230dfdc3d468b1 diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx index c9c6b70..db72e8e 100644 --- a/sc/source/ui/docshell/docsh.cxx +++ b/sc/source/ui/docshell/docsh.cxx @@ -3093,6 +3093,11 @@ void ScDocShellModificator::SetDocumentModified() } } +void ScDocShellModificator::AppendCellContentModified( const ScRange& rRange ) +{ + mvContentModified.push_back( rRange); +} + bool ScDocShell::IsChangeRecording() const { ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack(); diff --git a/sc/source/ui/inc/docsh.hxx b/sc/source/ui/inc/docsh.hxx index ce1d312..7aab3ff 100644 --- a/sc/source/ui/inc/docsh.hxx +++ b/sc/source/ui/inc/docsh.hxx @@ -453,6 +453,7 @@ typedef tools::SvRef<ScDocShell> ScDocShellRef; */ class SC_DLLPUBLIC ScDocShellModificator { + ::std::vector<ScRange> mvContentModified; ScDocShell& rDocShell; boost::scoped_ptr<ScRefreshTimerProtector> mpProtector; bool bAutoCalcShellDisabled; @@ -465,6 +466,11 @@ public: ScDocShellModificator( ScDocShell& ); ~ScDocShellModificator(); void SetDocumentModified(); + + /** Append a cell position/range to the list of modified cell + contents. Used in dtor to call maintenance on data structures + that depend on cell content. */ + void AppendCellContentModified( const ScRange& rRange ); }; //#i97876# Spreadsheet data changes are not notified _______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
