[ooo-build-commit] .: 2 commits - patches/dev300 patches/vba
Kohei Yoshida
kohei at kemper.freedesktop.org
Mon Mar 8 20:52:56 PST 2010
patches/dev300/apply | 11
patches/dev300/calc-extref-simple-ref-tracking.diff | 609 -----
patches/dev300/calc-perf-extref-shrink-range.diff | 762 -------
patches/dev300/calc-subtotal-function-update.diff | 3
patches/dev300/calc-xls-disable-adjust-row-height.diff | 11
patches/dev300/cws-koheiextref01-offapi.diff | 22
patches/dev300/cws-koheiextref01-oox.diff | 13
patches/dev300/cws-koheiextref01-sc.diff | 1825 +++++++++++++++++
patches/dev300/sc-dbrange-dynamic-resize.diff | 97
patches/vba/cws-vbasupportdev300.diff | 8
10 files changed, 1894 insertions(+), 1467 deletions(-)
New commits:
commit 1d6206fad2170806bae78f7d8a3b3ad8c84924b2
Author: Kohei Yoshida <kyoshida at novell.com>
Date: Mon Mar 8 22:34:46 2010 -0500
Adjusted patches dependent on the cws-koheiextref01 patches.
* patches/dev300/apply:
Removed:
* patches/dev300/calc-extref-simple-ref-tracking.diff:
* patches/dev300/calc-perf-extref-shrink-range.diff:
Modified.
* patches/dev300/calc-subtotal-function-update.diff:
* patches/dev300/calc-xls-disable-adjust-row-height.diff:
* patches/dev300/sc-dbrange-dynamic-resize.diff:
* patches/vba/cws-vbasupportdev300.diff:
diff --git a/patches/dev300/apply b/patches/dev300/apply
index fd75306..f9f58c5 100644
--- a/patches/dev300/apply
+++ b/patches/dev300/apply
@@ -3570,9 +3570,6 @@ calc-english-func-names-officecfg.diff, i#38765, kohei
# Keep track of cells with SUBTOTAL functions the right way.
calc-subtotal-function-update.diff, n#578802, kohei
-# Reduce cache table size & improve lookup performance on external references.
-calc-perf-extref-shrink-range.diff, i#109168, kohei
-
# Fix incorrect positioning of cell notes during row insertion.
calc-note-position-fix.diff, n#579454, kohei
@@ -3584,9 +3581,6 @@ calc-insert-current-time-sc.diff, kohei
calc-insert-current-time-svx.diff, kohei
calc-insert-current-time-vcl.diff, kohei
-# Simplify external ref cell tracking & break links turn ref cells into static values.
-calc-extref-simple-ref-tracking.diff, n#585094, i#103739, i#109170, kohei
-
# Allow export of filtered range selection, and show error when fails.
calc-pdf-export-allow-filtered-range-sc.diff, n#585028, kohei
calc-pdf-export-allow-filtered-range-filter.diff, n#585028, kohei
diff --git a/patches/dev300/calc-extref-simple-ref-tracking.diff b/patches/dev300/calc-extref-simple-ref-tracking.diff
deleted file mode 100644
index ff223ef..0000000
--- a/patches/dev300/calc-extref-simple-ref-tracking.diff
+++ /dev/null
@@ -1,609 +0,0 @@
-diff --git sc/inc/externalrefmgr.hxx sc/inc/externalrefmgr.hxx
-index 2906113..36e1e8f 100644
---- sc/inc/externalrefmgr.hxx
-+++ sc/inc/externalrefmgr.hxx
-@@ -46,6 +46,7 @@
- #include <boost/shared_ptr.hpp>
- #include <vector>
- #include <list>
-+#include <set>
- #include <formula/ExternalReferenceHelper.hxx>
-
- class ScDocument;
-@@ -59,6 +60,7 @@ class ScTokenArray;
- class String;
- class SfxObjectShellRef;
- class Window;
-+class ScFormulaCell;
-
- class ScExternalRefCache;
-
-@@ -354,58 +356,8 @@ class SC_DLLPUBLIC ScExternalRefManager : public formula::ExternalReferenceHelpe
- {
- public:
-
-- // SUNWS needs a forward declared friend, otherwise types and members
-- // of the outer class are not accessible.
-- class RefCells;
-- friend class ScExternalRefManager::RefCells;
--
-- /**
-- * Collection of cell addresses that contain external references. This
-- * data is used for link updates.
-- */
-- class RefCells
-- {
-- public:
-- RefCells();
-- ~RefCells();
--
-- void insertCell(const ScAddress& rAddr);
-- void removeCell(const ScAddress& rAddr);
-- void moveTable(SCTAB nOldTab, SCTAB nNewTab, bool bCopy);
-- void insertTable(SCTAB nPos);
-- void removeTable(SCTAB nPos);
-- void refreshAllCells(ScExternalRefManager& rRefMgr);
-- private:
--
-- typedef ::std::hash_set<SCROW> RowSet;
-- typedef ::std::hash_map<SCCOL, RowSet> ColSet;
--
-- // SUNWS needs a forward declared friend, otherwise types and members
-- // of the outer class are not accessible.
-- struct TabItem;
-- friend struct ScExternalRefManager::RefCells::TabItem;
--
-- struct TabItem
-- {
-- SCTAB mnIndex;
-- ColSet maCols;
-- explicit TabItem(SCTAB nIndex);
-- explicit TabItem(const TabItem& r);
-- };
-- typedef ::boost::shared_ptr<TabItem> TabItemRef;
--
-- /**
-- * Return the position that points either to the specified table
-- * position or to the position where a new table would be inserted in
-- * case the specified table is not present.
-- *
-- * @param nTab index of the desired table
-- */
-- ::std::list<TabItemRef>::iterator getTabPos(SCTAB nTab);
--
-- // This list must be sorted by the table index at all times.
-- ::std::list<TabItemRef> maTables;
-- };
-+ typedef ::std::set<ScFormulaCell*> RefCellSet;
-+ typedef ::std::hash_map<sal_uInt16, RefCellSet> RefCellMap;
-
- enum LinkUpdateType { LINK_MODIFIED, LINK_BROKEN };
-
-@@ -441,7 +393,6 @@ private:
- typedef ::std::hash_map<sal_uInt16, SrcShell> DocShellMap;
- typedef ::std::hash_map<sal_uInt16, bool> LinkedDocMap;
-
-- typedef ::std::hash_map<sal_uInt16, RefCells> RefCellMap;
- typedef ::std::hash_map<sal_uInt16, SvNumberFormatterMergeMap> NumFmtMap;
-
-
-@@ -668,32 +619,12 @@ public:
- void resetSrcFileData(const String& rBaseFileUrl);
-
- /**
-- * Update a single referencing cell position.
-- *
-- * @param rOldPos old position
-- * @param rNewPos new position
-- */
-- void updateRefCell(const ScAddress& rOldPos, const ScAddress& rNewPos, bool bCopy);
--
-- /**
-- * Update referencing cells affected by sheet movement.
-- *
-- * @param nOldTab old sheet position
-- * @param nNewTab new sheet position
-- * @param bCopy whether this is a sheet move (false) or sheet copy (true)
-- */
-- void updateRefMoveTable(SCTAB nOldTab, SCTAB nNewTab, bool bCopy);
--
-- /**
-- * Update referencing cells affected by sheet insertion.
-- *
-- * @param nPos sheet insertion position. All sheets to the right
-- * including the one at the insertion poistion shift to the
-- * right by one.
-+ * Stop tracking a specific formula cell.
-+ *
-+ * @param pCell pointer to cell that formerly contained external
-+ * reference.
- */
-- void updateRefInsertTable(SCTAB nPos);
--
-- void updateRefDeleteTable(SCTAB nPos);
-+ void removeRefCell(ScFormulaCell* pCell);
-
- /**
- * Register a new link listener to a specified external document. Note
-diff --git sc/source/core/data/cell.cxx sc/source/core/data/cell.cxx
-index 312ad38..b781747 100644
---- sc/source/core/data/cell.cxx
-+++ sc/source/core/data/cell.cxx
-@@ -833,6 +833,9 @@ ScFormulaCell::~ScFormulaCell()
- if (pCode->HasOpCode(ocMacro))
- pDocument->GetMacroManager()->RemoveDependentCell(this);
-
-+ if (pDocument->HasExternalRefManager())
-+ pDocument->GetExternalRefManager()->removeRefCell(this);
-+
- delete pCode;
- #ifdef DBG_UTIL
- eCellType = CELLTYPE_DESTROYED;
-diff --git sc/source/core/data/cell2.cxx sc/source/core/data/cell2.cxx
-index 32a0fa5..033ad58 100644
---- sc/source/core/data/cell2.cxx
-+++ sc/source/core/data/cell2.cxx
-@@ -1133,17 +1133,6 @@ void ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode,
-
- delete pOld;
- }
--
-- pCode->Reset();
-- for ( formula::FormulaToken* t = pCode->GetNextReferenceOrName(); t; t = pCode->GetNextReferenceOrName() )
-- {
-- StackVar sv = t->GetType();
-- if (sv == svExternalSingleRef || sv == svExternalDoubleRef || sv == svExternalName)
-- {
-- pDocument->GetExternalRefManager()->updateRefCell(aOldPos, aPos, eUpdateRefMode == URM_COPY);
-- break;
-- }
-- }
- }
-
- void ScFormulaCell::UpdateInsertTab(SCTAB nTable)
-diff --git sc/source/core/data/documen2.cxx sc/source/core/data/documen2.cxx
-index cbcd57a..6dfb1c5 100644
---- sc/source/core/data/documen2.cxx
-+++ sc/source/core/data/documen2.cxx
-@@ -811,10 +811,6 @@ BOOL ScDocument::MoveTab( SCTAB nOldPos, SCTAB nNewPos )
- if (pDrawLayer)
- DrawMovePage( static_cast<sal_uInt16>(nOldPos), static_cast<sal_uInt16>(nNewPos) );
-
-- // Update cells containing external references.
-- if (pExternalRefMgr.get())
-- pExternalRefMgr->updateRefMoveTable(nOldPos, nNewPos, false);
--
- bValid = TRUE;
- }
- }
-@@ -932,10 +928,6 @@ BOOL ScDocument::CopyTab( SCTAB nOldPos, SCTAB nNewPos, const ScMarkData* pOnlyM
-
- pTab[nNewPos]->SetPageStyle( pTab[nOldPos]->GetPageStyle() );
- pTab[nNewPos]->SetPendingRowHeights( pTab[nOldPos]->IsPendingRowHeights() );
--
-- // Update cells containing external references.
-- if (pExternalRefMgr.get())
-- pExternalRefMgr->updateRefMoveTable(nOldPos, nNewPos, true);
- }
- else
- SetAutoCalc( bOldAutoCalc );
-diff --git sc/source/core/data/document.cxx sc/source/core/data/document.cxx
-index 91abb1b..7471be0 100644
---- sc/source/core/data/document.cxx
-+++ sc/source/core/data/document.cxx
-@@ -392,10 +392,6 @@ BOOL ScDocument::InsertTab( SCTAB nPos, const String& rName,
- if ( pChartListenerCollection )
- pChartListenerCollection->UpdateScheduledSeriesRanges();
-
-- // Update cells containing external references.
-- if (pExternalRefMgr.get())
-- pExternalRefMgr->updateRefInsertTable(nPos);
--
- SetDirty();
- bValid = TRUE;
- }
-@@ -487,11 +483,6 @@ BOOL ScDocument::DeleteTab( SCTAB nTab, ScDocument* pRefUndoDoc )
- // #81844# sheet names of references are not valid until sheet is deleted
- pChartListenerCollection->UpdateScheduledSeriesRanges();
-
--
-- // Update cells containing external references.
-- if (pExternalRefMgr.get())
-- pExternalRefMgr->updateRefDeleteTable(nTab);
--
- SetAutoCalc( bOldAutoCalc );
- bValid = TRUE;
- }
-diff --git sc/source/ui/docshell/externalrefmgr.cxx sc/source/ui/docshell/externalrefmgr.cxx
-index 9081d07..f6ab979 100644
---- sc/source/ui/docshell/externalrefmgr.cxx
-+++ sc/source/ui/docshell/externalrefmgr.cxx
-@@ -140,6 +140,71 @@ private:
- ScExternalRefManager::LinkUpdateType meType;
- };
-
-+struct UpdateFormulaCell : public unary_function<ScFormulaCell*, void>
-+{
-+ void operator() (ScFormulaCell* pCell) const
-+ {
-+ // Check to make sure the cell really contains ocExternalRef.
-+ // External names, external cell and range references all have a
-+ // ocExternalRef token.
-+ const ScTokenArray* pCode = pCell->GetCode();
-+ if (!pCode->HasOpCode( ocExternalRef))
-+ return;
-+
-+ ScTokenArray* pArray = pCell->GetCode();
-+ if (pArray)
-+ // Clear the error code, or a cell with error won't get re-compiled.
-+ pArray->SetCodeError(0);
-+
-+ pCell->SetCompile(true);
-+ pCell->CompileTokenArray();
-+ pCell->SetDirty();
-+ }
-+};
-+
-+class RemoveFormulaCell : public unary_function<pair<const sal_uInt16, ScExternalRefManager::RefCellSet>, void>
-+{
-+public:
-+ explicit RemoveFormulaCell(ScFormulaCell* p) : mpCell(p) {}
-+ void operator() (pair<const sal_uInt16, ScExternalRefManager::RefCellSet>& r) const
-+ {
-+ r.second.erase(mpCell);
-+ }
-+private:
-+ ScFormulaCell* mpCell;
-+};
-+
-+class ConvertFormulaToStatic : public unary_function<ScFormulaCell*, void>
-+{
-+public:
-+ explicit ConvertFormulaToStatic(ScDocument* pDoc) : mpDoc(pDoc) {}
-+ void operator() (ScFormulaCell* pCell) const
-+ {
-+ String aStr;
-+ pCell->aPos.Format(aStr, SCA_VALID);
-+ ScAddress aPos = pCell->aPos;
-+
-+ // We don't check for empty cells because empty external cells are
-+ // treated as having a value of 0.
-+
-+ if (pCell->IsValue())
-+ {
-+ // Turn this into value cell.
-+ double fVal = pCell->GetValue();
-+ mpDoc->PutCell(aPos, new ScValueCell(fVal));
-+ }
-+ else
-+ {
-+ // string cell otherwise.
-+ String aVal;
-+ pCell->GetString(aVal);
-+ mpDoc->PutCell(aPos, new ScStringCell(aVal));
-+ }
-+ }
-+private:
-+ ScDocument* mpDoc;
-+};
-+
- }
-
- // ============================================================================
-@@ -1417,230 +1482,6 @@ ScExternalRefCache::TableTypeRef ScExternalRefManager::getCacheTable(sal_uInt16
-
- // ============================================================================
-
--ScExternalRefManager::RefCells::TabItem::TabItem(SCTAB nIndex) :
-- mnIndex(nIndex)
--{
--}
--
--ScExternalRefManager::RefCells::TabItem::TabItem(const TabItem& r) :
-- mnIndex(r.mnIndex),
-- maCols(r.maCols)
--{
--}
--
--ScExternalRefManager::RefCells::RefCells()
--{
--}
--
--ScExternalRefManager::RefCells::~RefCells()
--{
--}
--
--list<ScExternalRefManager::RefCells::TabItemRef>::iterator ScExternalRefManager::RefCells::getTabPos(SCTAB nTab)
--{
-- list<TabItemRef>::iterator itr = maTables.begin(), itrEnd = maTables.end();
-- for (; itr != itrEnd; ++itr)
-- if ((*itr)->mnIndex >= nTab)
-- return itr;
-- // Not found. return the end position.
-- return itrEnd;
--}
--
--void ScExternalRefManager::RefCells::insertCell(const ScAddress& rAddr)
--{
-- SCTAB nTab = rAddr.Tab();
-- SCCOL nCol = rAddr.Col();
-- SCROW nRow = rAddr.Row();
--
-- // Search by table index.
-- list<TabItemRef>::iterator itrTab = getTabPos(nTab);
-- TabItemRef xTabRef;
-- if (itrTab == maTables.end())
-- {
-- // All previous tables come before the specificed table.
-- xTabRef.reset(new TabItem(nTab));
-- maTables.push_back(xTabRef);
-- }
-- else if ((*itrTab)->mnIndex > nTab)
-- {
-- // Insert at the current iterator position.
-- xTabRef.reset(new TabItem(nTab));
-- maTables.insert(itrTab, xTabRef);
-- }
-- else if ((*itrTab)->mnIndex == nTab)
-- {
-- // The table found.
-- xTabRef = *itrTab;
-- }
-- ColSet& rCols = xTabRef->maCols;
--
-- // Then by column index.
-- ColSet::iterator itrCol = rCols.find(nCol);
-- if (itrCol == rCols.end())
-- {
-- RowSet aRows;
-- pair<ColSet::iterator, bool> r = rCols.insert(ColSet::value_type(nCol, aRows));
-- if (!r.second)
-- // column insertion failed.
-- return;
-- itrCol = r.first;
-- }
-- RowSet& rRows = itrCol->second;
--
-- // Finally, insert the row index.
-- rRows.insert(nRow);
--}
--
--void ScExternalRefManager::RefCells::removeCell(const ScAddress& rAddr)
--{
-- SCTAB nTab = rAddr.Tab();
-- SCCOL nCol = rAddr.Col();
-- SCROW nRow = rAddr.Row();
--
-- // Search by table index.
-- list<TabItemRef>::iterator itrTab = getTabPos(nTab);
-- if (itrTab == maTables.end() || (*itrTab)->mnIndex != nTab)
-- // No such table.
-- return;
--
-- ColSet& rCols = (*itrTab)->maCols;
--
-- // Then by column index.
-- ColSet::iterator itrCol = rCols.find(nCol);
-- if (itrCol == rCols.end())
-- // No such column
-- return;
--
-- RowSet& rRows = itrCol->second;
-- rRows.erase(nRow);
--}
--
--void ScExternalRefManager::RefCells::moveTable(SCTAB nOldTab, SCTAB nNewTab, bool bCopy)
--{
-- if (nOldTab == nNewTab)
-- // Nothing to do here.
-- return;
--
-- list<TabItemRef>::iterator itrOld = getTabPos(nOldTab);
-- if (itrOld == maTables.end() || (*itrOld)->mnIndex != nOldTab)
-- // No table to move or copy.
-- return;
--
-- list<TabItemRef>::iterator itrNew = getTabPos(nNewTab);
-- if (bCopy)
-- {
-- // Simply make a duplicate of the original table, insert it at the
-- // new tab position, and increment the table index for all tables
-- // that come after that inserted table.
--
-- TabItemRef xNewTab(new TabItem(*(*itrOld)));
-- xNewTab->mnIndex = nNewTab;
-- maTables.insert(itrNew, xNewTab);
-- list<TabItemRef>::iterator itr = itrNew, itrEnd = maTables.end();
-- if (itr != itrEnd) // #i99807# check that itr is not at end already
-- for (++itr; itr != itrEnd; ++itr)
-- (*itr)->mnIndex += 1;
-- }
-- else
-- {
-- if (itrOld == itrNew)
-- {
-- // No need to move the table. Just update the table index.
-- (*itrOld)->mnIndex = nNewTab;
-- return;
-- }
--
-- if (nOldTab < nNewTab)
-- {
-- // Iterate from the old tab position to the new tab position (not
-- // inclusive of the old tab itself), and decrement their tab
-- // index by one.
-- list<TabItemRef>::iterator itr = itrOld;
-- for (++itr; itr != itrNew; ++itr)
-- (*itr)->mnIndex -= 1;
--
-- // Insert a duplicate of the original table. This does not
-- // invalidate the iterators.
-- (*itrOld)->mnIndex = nNewTab - 1;
-- if (itrNew == maTables.end())
-- maTables.push_back(*itrOld);
-- else
-- maTables.insert(itrNew, *itrOld);
--
-- // Remove the original table.
-- maTables.erase(itrOld);
-- }
-- else
-- {
-- // nNewTab < nOldTab
--
-- // Iterate from the new tab position to the one before the old tab
-- // position, and increment their tab index by one.
-- list<TabItemRef>::iterator itr = itrNew;
-- for (++itr; itr != itrOld; ++itr)
-- (*itr)->mnIndex += 1;
--
-- (*itrOld)->mnIndex = nNewTab;
-- maTables.insert(itrNew, *itrOld);
--
-- // Remove the original table.
-- maTables.erase(itrOld);
-- }
-- }
--}
--
--void ScExternalRefManager::RefCells::insertTable(SCTAB nPos)
--{
-- TabItemRef xNewTab(new TabItem(nPos));
-- list<TabItemRef>::iterator itr = getTabPos(nPos);
-- if (itr == maTables.end())
-- maTables.push_back(xNewTab);
-- else
-- maTables.insert(itr, xNewTab);
--}
--
--void ScExternalRefManager::RefCells::removeTable(SCTAB nPos)
--{
-- list<TabItemRef>::iterator itr = getTabPos(nPos);
-- if (itr == maTables.end())
-- // nothing to remove.
-- return;
--
-- maTables.erase(itr);
--}
--
--void ScExternalRefManager::RefCells::refreshAllCells(ScExternalRefManager& rRefMgr)
--{
-- // Get ALL the cell positions for re-compilation.
-- for (list<TabItemRef>::iterator itrTab = maTables.begin(), itrTabEnd = maTables.end();
-- itrTab != itrTabEnd; ++itrTab)
-- {
-- SCTAB nTab = (*itrTab)->mnIndex;
-- ColSet& rCols = (*itrTab)->maCols;
-- for (ColSet::iterator itrCol = rCols.begin(), itrColEnd = rCols.end();
-- itrCol != itrColEnd; ++itrCol)
-- {
-- SCCOL nCol = itrCol->first;
-- RowSet& rRows = itrCol->second;
-- RowSet aNewRows;
-- for (RowSet::iterator itrRow = rRows.begin(), itrRowEnd = rRows.end();
-- itrRow != itrRowEnd; ++itrRow)
-- {
-- SCROW nRow = *itrRow;
-- ScAddress aCell(nCol, nRow, nTab);
-- if (rRefMgr.compileTokensByCell(aCell))
-- // This cell still contains an external refernce.
-- aNewRows.insert(nRow);
-- }
-- // Update the rows so that cells with no external references are
-- // no longer tracked.
-- rRows.swap(aNewRows);
-- }
-- }
--}
--
--// ----------------------------------------------------------------------------
--
- ScExternalRefManager::LinkListener::LinkListener()
- {
- }
-@@ -1985,8 +1826,8 @@ void ScExternalRefManager::refreshAllRefCells(sal_uInt16 nFileId)
- if (itrFile == maRefCells.end())
- return;
-
-- RefCells& rRefCells = itrFile->second;
-- rRefCells.refreshAllCells(*this);
-+ RefCellSet& rRefCells = itrFile->second;
-+ for_each(rRefCells.begin(), rRefCells.end(), UpdateFormulaCell());
-
- ScViewData* pViewData = ScDocShell::GetViewData();
- if (!pViewData)
-@@ -2007,7 +1848,7 @@ void ScExternalRefManager::insertRefCell(sal_uInt16 nFileId, const ScAddress& rC
- RefCellMap::iterator itr = maRefCells.find(nFileId);
- if (itr == maRefCells.end())
- {
-- RefCells aRefCells;
-+ RefCellSet aRefCells;
- pair<RefCellMap::iterator, bool> r = maRefCells.insert(
- RefCellMap::value_type(nFileId, aRefCells));
- if (!r.second)
-@@ -2016,7 +1857,10 @@ void ScExternalRefManager::insertRefCell(sal_uInt16 nFileId, const ScAddress& rC
-
- itr = r.first;
- }
-- itr->second.insertCell(rCell);
-+
-+ ScBaseCell* pCell = mpDoc->GetCell(rCell);
-+ if (pCell && pCell->GetCellType() == CELLTYPE_FORMULA)
-+ itr->second.insert(static_cast<ScFormulaCell*>(pCell));
- }
-
- ScDocument* ScExternalRefManager::getSrcDocument(sal_uInt16 nFileId)
-@@ -2352,6 +2196,18 @@ void ScExternalRefManager::refreshNames(sal_uInt16 nFileId)
-
- void ScExternalRefManager::breakLink(sal_uInt16 nFileId)
- {
-+ // Turn all formula cells referencing this external document into static
-+ // cells.
-+ RefCellMap::iterator itrRefs = maRefCells.find(nFileId);
-+ if (itrRefs != maRefCells.end())
-+ {
-+ // Make a copy because removing the formula cells below will modify
-+ // the original container.
-+ RefCellSet aSet = itrRefs->second;
-+ for_each(aSet.begin(), aSet.end(), ConvertFormulaToStatic(mpDoc));
-+ maRefCells.erase(nFileId);
-+ }
-+
- lcl_removeByFileId(nFileId, maDocShells);
-
- if (maDocShells.empty())
-@@ -2423,32 +2279,9 @@ void ScExternalRefManager::resetSrcFileData(const String& rBaseFileUrl)
- }
- }
-
--void ScExternalRefManager::updateRefCell(const ScAddress& rOldPos, const ScAddress& rNewPos, bool bCopy)
--{
-- for (RefCellMap::iterator itr = maRefCells.begin(), itrEnd = maRefCells.end(); itr != itrEnd; ++itr)
-- {
-- if (!bCopy)
-- itr->second.removeCell(rOldPos);
-- itr->second.insertCell(rNewPos);
-- }
--}
--
--void ScExternalRefManager::updateRefMoveTable(SCTAB nOldTab, SCTAB nNewTab, bool bCopy)
--{
-- for (RefCellMap::iterator itr = maRefCells.begin(), itrEnd = maRefCells.end(); itr != itrEnd; ++itr)
-- itr->second.moveTable(nOldTab, nNewTab, bCopy);
--}
--
--void ScExternalRefManager::updateRefInsertTable(SCTAB nPos)
--{
-- for (RefCellMap::iterator itr = maRefCells.begin(), itrEnd = maRefCells.end(); itr != itrEnd; ++itr)
-- itr->second.insertTable(nPos);
--}
--
--void ScExternalRefManager::updateRefDeleteTable(SCTAB nPos)
-+void ScExternalRefManager::removeRefCell(ScFormulaCell* pCell)
- {
-- for (RefCellMap::iterator itr = maRefCells.begin(), itrEnd = maRefCells.end(); itr != itrEnd; ++itr)
-- itr->second.removeTable(nPos);
-+ for_each(maRefCells.begin(), maRefCells.end(), RemoveFormulaCell(pCell));
- }
-
- void ScExternalRefManager::addLinkListener(sal_uInt16 nFileId, LinkListener* pListener)
diff --git a/patches/dev300/calc-perf-extref-shrink-range.diff b/patches/dev300/calc-perf-extref-shrink-range.diff
deleted file mode 100644
index 384c2e7..0000000
--- a/patches/dev300/calc-perf-extref-shrink-range.diff
+++ /dev/null
@@ -1,762 +0,0 @@
-diff --git sc/inc/externalrefmgr.hxx sc/inc/externalrefmgr.hxx
-index 22e114d..2906113 100644
---- sc/inc/externalrefmgr.hxx
-+++ sc/inc/externalrefmgr.hxx
-@@ -39,6 +39,7 @@
- #include "vcl/timer.hxx"
- #include "svtools/zforlist.hxx"
- #include "scmatrix.hxx"
-+#include "rangelst.hxx"
-
- #include <hash_map>
- #include <hash_set>
-@@ -129,6 +130,15 @@ public:
- class Table;
- friend class ScExternalRefCache::Table;
-
-+ /**
-+ * Represents a single cached table in an external document. It only
-+ * stores non-empty cells; empty cells should never be stored in the data
-+ * cache. Instead, cached ranges should be used to determine whether or
-+ * not a cell is empty or needs fetching from the source document. If a
-+ * cell's value is not stored but its address is within the cached ranges,
-+ * that cell is already queried in the source document and we know it's
-+ * empty.
-+ */
- class Table
- {
- public:
-@@ -143,7 +153,7 @@ public:
- Table();
- ~Table();
-
-- SC_DLLPUBLIC void setCell(SCCOL nCol, SCROW nRow, TokenRef pToken, sal_uInt32 nFmtIndex = 0);
-+ SC_DLLPUBLIC void setCell(SCCOL nCol, SCROW nRow, TokenRef pToken, sal_uInt32 nFmtIndex = 0, bool bSetCacheRange = true);
- TokenRef getCell(SCCOL nCol, SCROW nRow, sal_uInt32* pnFmtIndex = NULL) const;
- bool hasRow( SCROW nRow ) const;
- /** Set/clear referenced status flag only if current status is not
-@@ -154,14 +164,35 @@ public:
- ReferencedFlag getReferencedFlag() const;
- bool isReferenced() const;
- /// Obtain a sorted vector of rows.
-- void getAllRows(::std::vector<SCROW>& rRows) const;
-+ void getAllRows(::std::vector<SCROW>& rRows, SCROW nLow = 0, SCROW nHigh = MAXROW) const;
- /// Obtain a sorted vector of columns.
-- void getAllCols(SCROW nRow, ::std::vector<SCCOL>& rCols) const;
-+ void getAllCols(SCROW nRow, ::std::vector<SCCOL>& rCols, SCCOL nLow = 0, SCCOL nHigh = MAXCOL) const;
- void getAllNumberFormats(::std::vector<sal_uInt32>& rNumFmts) const;
-+ const ScRangeList& getCachedRanges() const;
-+ bool isRangeCached(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const;
-+
-+ void setCachedCell(SCCOL nCol, SCROW nRow);
-+ void setCachedCellRange(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
-+
-+ /**
-+ * Call this to mark the entire table "cached". This will prevent all
-+ * future attempts to access the source document even when non-cached
-+ * cells are queried. In such case, non-cached cells are treated as
-+ * empty cells. Useful when loading a document with own external data
-+ * cache.
-+ */
-+ SC_DLLPUBLIC void setWholeTableCached();
-+ private:
-+ bool isInCachedRanges(SCCOL nCol, SCROW nRow) const;
-+ TokenRef getEmptyOrNullToken(SCCOL nCol, SCROW nRow) const;
-
- private:
-- RowsDataType maRows;
-- ReferencedFlag meReferenced;
-+ /** Data cache */
-+ RowsDataType maRows;
-+ /** Collection of individual cached ranges. The table ranges are
-+ * not used & always zero. */
-+ ScRangeList maCachedRanges;
-+ ReferencedFlag meReferenced;
- };
-
- typedef ::boost::shared_ptr<Table> TableTypeRef;
-@@ -184,8 +215,7 @@ public:
- * @return pointer to the token instance in the cache.
- */
- ScExternalRefCache::TokenRef getCellData(
-- sal_uInt16 nFileId, const String& rTabName, SCCOL nCol, SCROW nRow,
-- bool bEmptyCellOnNull, bool bWriteEmpty, sal_uInt32* pnFmtIndex);
-+ sal_uInt16 nFileId, const String& rTabName, SCCOL nCol, SCROW nRow, sal_uInt32* pnFmtIndex);
-
- /**
- * Get a cached cell range data.
-@@ -195,12 +225,12 @@ public:
- * guaranteed if the TokenArrayRef is properly used..
- */
- ScExternalRefCache::TokenArrayRef getCellRangeData(
-- sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange, bool bEmptyCellOnNull, bool bWriteEmpty);
-+ sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange);
-
- ScExternalRefCache::TokenArrayRef getRangeNameTokens(sal_uInt16 nFileId, const String& rName);
- void setRangeNameTokens(sal_uInt16 nFileId, const String& rName, TokenArrayRef pArray);
-
-- void setCellData(sal_uInt16 nFileId, const String& rTabName, SCROW nRow, SCCOL nCol, TokenRef pToken, sal_uInt32 nFmtIndex);
-+ void setCellData(sal_uInt16 nFileId, const String& rTabName, SCCOL nCol, SCROW nRow, TokenRef pToken, sal_uInt32 nFmtIndex);
-
- struct SingleRangeData
- {
-diff --git sc/source/core/data/documen5.cxx sc/source/core/data/documen5.cxx
-index 24cbf48..564bf3f 100644
---- sc/source/core/data/documen5.cxx
-+++ sc/source/core/data/documen5.cxx
-@@ -930,6 +930,9 @@ void ScDocument::UpdateChartListenerCollection()
- SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
- DBG_ASSERT(pPage,"Page ?");
-
-+ if (!pPage)
-+ continue;
-+
- SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
- SdrObject* pObject = aIter.Next();
- while (pObject)
-diff --git sc/source/core/data/document.cxx sc/source/core/data/document.cxx
-index 8c4c4a3..eb83c8a 100644
---- sc/source/core/data/document.cxx
-+++ sc/source/core/data/document.cxx
-@@ -713,6 +713,10 @@ bool ScDocument::ShrinkToDataArea(SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow
- if (nRow2 < rEndRow)
- rEndRow = nRow2;
-
-+ if (rStartCol > rEndCol || rStartRow > rEndRow)
-+ // invalid range.
-+ return false;
-+
- return true; // success!
- }
-
-diff --git sc/source/filter/excel/xilink.cxx sc/source/filter/excel/xilink.cxx
-index 0026821..b76baf6 100644
---- sc/source/filter/excel/xilink.cxx
-+++ sc/source/filter/excel/xilink.cxx
-@@ -570,6 +570,7 @@ void XclImpSupbook::LoadCachedValues()
- const String& rTabName = pTab->GetTabName();
- ScExternalRefCache::TableTypeRef pCacheTable = pRefMgr->getCacheTable(nFileId, rTabName, true);
- pTab->LoadCachedValues(pCacheTable);
-+ pCacheTable->setWholeTableCached();
- }
- }
-
-diff --git sc/source/filter/xml/xmltabi.cxx sc/source/filter/xml/xmltabi.cxx
-index a2995a6..9fa3a12 100644
---- sc/source/filter/xml/xmltabi.cxx
-+++ sc/source/filter/xml/xmltabi.cxx
-@@ -217,6 +217,7 @@ ScXMLTableContext::ScXMLTableContext( ScXMLImport& rImport,
- ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
- pExternalRefInfo->mnFileId = pRefMgr->getExternalFileId(aExtUrl);
- pExternalRefInfo->mpCacheTable = pRefMgr->getCacheTable(pExternalRefInfo->mnFileId, aExtTabName, true);
-+ pExternalRefInfo->mpCacheTable->setWholeTableCached();
- }
- }
- else
-diff --git sc/source/ui/docshell/externalrefmgr.cxx sc/source/ui/docshell/externalrefmgr.cxx
-index da04ce2..9081d07 100644
---- sc/source/ui/docshell/externalrefmgr.cxx
-+++ sc/source/ui/docshell/externalrefmgr.cxx
-@@ -68,6 +68,8 @@
- #include <memory>
- #include <algorithm>
-
-+#include <boost/scoped_ptr.hpp>
-+
- using ::std::auto_ptr;
- using ::com::sun::star::uno::Any;
- using ::rtl::OUString;
-@@ -173,7 +175,7 @@ bool ScExternalRefCache::Table::isReferenced() const
- return meReferenced != UNREFERENCED;
- }
-
--void ScExternalRefCache::Table::setCell(SCCOL nCol, SCROW nRow, TokenRef pToken, sal_uInt32 nFmtIndex)
-+void ScExternalRefCache::Table::setCell(SCCOL nCol, SCROW nRow, TokenRef pToken, sal_uInt32 nFmtIndex, bool bSetCacheRange)
- {
- using ::std::pair;
- RowsDataType::iterator itrRow = maRows.find(nRow);
-@@ -196,6 +198,8 @@ void ScExternalRefCache::Table::setCell(SCCOL nCol, SCROW nRow, TokenRef pToken,
- aCell.mxToken = pToken;
- aCell.mnFmtIndex = nFmtIndex;
- rRow.insert(RowDataType::value_type(nCol, aCell));
-+ if (bSetCacheRange)
-+ setCachedCell(nCol, nRow);
- }
-
- ScExternalRefCache::TokenRef ScExternalRefCache::Table::getCell(SCCOL nCol, SCROW nRow, sal_uInt32* pnFmtIndex) const
-@@ -204,7 +208,7 @@ ScExternalRefCache::TokenRef ScExternalRefCache::Table::getCell(SCCOL nCol, SCRO
- if (itrTable == maRows.end())
- {
- // this table doesn't have the specified row.
-- return TokenRef();
-+ return getEmptyOrNullToken(nCol, nRow);
- }
-
- const RowDataType& rRowData = itrTable->second;
-@@ -212,7 +216,7 @@ ScExternalRefCache::TokenRef ScExternalRefCache::Table::getCell(SCCOL nCol, SCRO
- if (itrRow == rRowData.end())
- {
- // this row doesn't have the specified column.
-- return TokenRef();
-+ return getEmptyOrNullToken(nCol, nRow);
- }
-
- const Cell& rCell = itrRow->second;
-@@ -228,20 +232,21 @@ bool ScExternalRefCache::Table::hasRow( SCROW nRow ) const
- return itrRow != maRows.end();
- }
-
--void ScExternalRefCache::Table::getAllRows(vector<SCROW>& rRows) const
-+void ScExternalRefCache::Table::getAllRows(vector<SCROW>& rRows, SCROW nLow, SCROW nHigh) const
- {
- vector<SCROW> aRows;
- aRows.reserve(maRows.size());
- RowsDataType::const_iterator itr = maRows.begin(), itrEnd = maRows.end();
- for (; itr != itrEnd; ++itr)
-- aRows.push_back(itr->first);
-+ if (nLow <= itr->first && itr->first <= nHigh)
-+ aRows.push_back(itr->first);
-
- // hash map is not ordered, so we need to explicitly sort it.
- ::std::sort(aRows.begin(), aRows.end());
- rRows.swap(aRows);
- }
-
--void ScExternalRefCache::Table::getAllCols(SCROW nRow, vector<SCCOL>& rCols) const
-+void ScExternalRefCache::Table::getAllCols(SCROW nRow, vector<SCCOL>& rCols, SCCOL nLow, SCCOL nHigh) const
- {
- RowsDataType::const_iterator itrRow = maRows.find(nRow);
- if (itrRow == maRows.end())
-@@ -253,7 +258,8 @@ void ScExternalRefCache::Table::getAllCols(SCROW nRow, vector<SCCOL>& rCols) con
- aCols.reserve(rRowData.size());
- RowDataType::const_iterator itrCol = rRowData.begin(), itrColEnd = rRowData.end();
- for (; itrCol != itrColEnd; ++itrCol)
-- aCols.push_back(itrCol->first);
-+ if (nLow <= itrCol->first && itrCol->first <= nHigh)
-+ aCols.push_back(itrCol->first);
-
- // hash map is not ordered, so we need to explicitly sort it.
- ::std::sort(aCols.begin(), aCols.end());
-@@ -275,6 +281,54 @@ void ScExternalRefCache::Table::getAllNumberFormats(vector<sal_uInt32>& rNumFmts
- }
- }
-
-+const ScRangeList& ScExternalRefCache::Table::getCachedRanges() const
-+{
-+ return maCachedRanges;
-+}
-+
-+bool ScExternalRefCache::Table::isRangeCached(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const
-+{
-+ return maCachedRanges.In(ScRange(nCol1, nRow1, 0, nCol2, nRow2, 0));
-+}
-+
-+void ScExternalRefCache::Table::setCachedCell(SCCOL nCol, SCROW nRow)
-+{
-+ setCachedCellRange(nCol, nRow, nCol, nRow);
-+}
-+
-+void ScExternalRefCache::Table::setCachedCellRange(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
-+{
-+ ScRange aRange(nCol1, nRow1, 0, nCol2, nRow2, 0);
-+ if (!maCachedRanges.Count())
-+ maCachedRanges.Append(aRange);
-+ else
-+ maCachedRanges.Join(aRange);
-+
-+ String aStr;
-+ maCachedRanges.Format(aStr, SCA_VALID);
-+}
-+
-+void ScExternalRefCache::Table::setWholeTableCached()
-+{
-+ setCachedCellRange(0, 0, MAXCOL, MAXROW);
-+}
-+
-+bool ScExternalRefCache::Table::isInCachedRanges(SCCOL nCol, SCROW nRow) const
-+{
-+ return maCachedRanges.In(ScRange(nCol, nRow, 0, nCol, nRow, 0));
-+}
-+
-+ScExternalRefCache::TokenRef ScExternalRefCache::Table::getEmptyOrNullToken(
-+ SCCOL nCol, SCROW nRow) const
-+{
-+ if (isInCachedRanges(nCol, nRow))
-+ {
-+ TokenRef p(new ScEmptyCellToken(false, false));
-+ return p;
-+ }
-+ return TokenRef();
-+}
-+
- // ----------------------------------------------------------------------------
-
- ScExternalRefCache::TableName::TableName(const String& rUpper, const String& rReal) :
-@@ -339,8 +393,7 @@ const String* ScExternalRefCache::getRealRangeName(sal_uInt16 nFileId, const Str
- }
-
- ScExternalRefCache::TokenRef ScExternalRefCache::getCellData(
-- sal_uInt16 nFileId, const String& rTabName, SCCOL nCol, SCROW nRow,
-- bool bEmptyCellOnNull, bool bWriteEmpty, sal_uInt32* pnFmtIndex)
-+ sal_uInt16 nFileId, const String& rTabName, SCCOL nCol, SCROW nRow, sal_uInt32* pnFmtIndex)
- {
- DocDataType::const_iterator itrDoc = maDocs.find(nFileId);
- if (itrDoc == maDocs.end())
-@@ -365,18 +418,11 @@ ScExternalRefCache::TokenRef ScExternalRefCache::getCellData(
- return TokenRef();
- }
-
-- TokenRef pToken = pTableData->getCell(nCol, nRow, pnFmtIndex);
-- if (!pToken && bEmptyCellOnNull)
-- {
-- pToken.reset(new ScEmptyCellToken(false, false));
-- if (bWriteEmpty)
-- pTableData->setCell(nCol, nRow, pToken);
-- }
-- return pToken;
-+ return pTableData->getCell(nCol, nRow, pnFmtIndex);
- }
-
- ScExternalRefCache::TokenArrayRef ScExternalRefCache::getCellRangeData(
-- sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange, bool bEmptyCellOnNull, bool bWriteEmpty)
-+ sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange)
- {
- DocDataType::iterator itrDoc = maDocs.find(nFileId);
- if (itrDoc == maDocs.end())
-@@ -406,13 +452,14 @@ ScExternalRefCache::TokenArrayRef ScExternalRefCache::getCellRangeData(
- return TokenArrayRef();
-
- ScRange aCacheRange( nCol1, nRow1, static_cast<SCTAB>(nTabFirstId), nCol2, nRow2, static_cast<SCTAB>(nTabLastId));
-+
- RangeArrayMap::const_iterator itrRange = rDoc.maRangeArrays.find( aCacheRange);
- if (itrRange != rDoc.maRangeArrays.end())
-- {
-+ // Cache hit!
- return itrRange->second;
-- }
-
-- TokenArrayRef pArray(new ScTokenArray);
-+ ::boost::scoped_ptr<ScRange> pNewRange;
-+ TokenArrayRef pArray;
- bool bFirstTab = true;
- for (size_t nTab = nTabFirstId; nTab <= nTabLastId; ++nTab)
- {
-@@ -420,27 +467,63 @@ ScExternalRefCache::TokenArrayRef ScExternalRefCache::getCellRangeData(
- if (!pTab.get())
- return TokenArrayRef();
-
-+ SCCOL nDataCol1 = nCol1, nDataCol2 = nCol2;
-+ SCROW nDataRow1 = nRow1, nDataRow2 = nRow2;
-+
-+ if (!pTab->isRangeCached(nDataCol1, nDataRow1, nDataCol2, nDataRow2))
-+ {
-+ // specified range is not entirely within cached ranges.
-+ return TokenArrayRef();
-+ }
-+
- ScMatrixRef xMat = new ScMatrix(
-- static_cast<SCSIZE>(nCol2-nCol1+1), static_cast<SCSIZE>(nRow2-nRow1+1));
-+ static_cast<SCSIZE>(nDataCol2-nDataCol1+1), static_cast<SCSIZE>(nDataRow2-nDataRow1+1));
-
-- for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
-+#if 0
-+ // TODO: Switch to this code block once we have support for sparsely-filled
-+ // matrices in ScMatrix.
-+
-+ // Only fill non-empty cells, for better performance.
-+ vector<SCROW> aRows;
-+ pTab->getAllRows(aRows, nDataRow1, nDataRow2);
-+ for (vector<SCROW>::const_iterator itr = aRows.begin(), itrEnd = aRows.end(); itr != itrEnd; ++itr)
- {
-- for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
-+ SCROW nRow = *itr;
-+ vector<SCCOL> aCols;
-+ pTab->getAllCols(nRow, aCols, nDataCol1, nDataCol2);
-+ for (vector<SCCOL>::const_iterator itrCol = aCols.begin(), itrColEnd = aCols.end(); itrCol != itrColEnd; ++itrCol)
- {
-+ SCCOL nCol = *itrCol;
- TokenRef pToken = pTab->getCell(nCol, nRow);
- if (!pToken)
-+ // This should never happen!
-+ return TokenArrayRef();
-+
-+ SCSIZE nC = nCol - nDataCol1, nR = nRow - nDataRow1;
-+ switch (pToken->GetType())
- {
-- if (bEmptyCellOnNull)
-- {
-- pToken.reset(new ScEmptyCellToken(false, false));
-- if (bWriteEmpty)
-- pTab->setCell(nCol, nRow, pToken);
-- }
-- else
-- return TokenArrayRef();
-+ case svDouble:
-+ xMat->PutDouble(pToken->GetDouble(), nC, nR);
-+ break;
-+ case svString:
-+ xMat->PutString(pToken->GetString(), nC, nR);
-+ break;
-+ default:
-+ ;
- }
--
-+ }
-+ }
-+#else
-+ // Empty all matrix elements first, and fill only non-empty elements.
-+ for (SCROW nRow = nDataRow1; nRow <= nDataRow2; ++nRow)
-+ {
-+ for (SCCOL nCol = nDataCol1; nCol <= nDataCol2; ++nCol)
-+ {
-+ TokenRef pToken = pTab->getCell(nCol, nRow);
- SCSIZE nC = nCol - nCol1, nR = nRow - nRow1;
-+ if (!pToken)
-+ return TokenArrayRef();
-+
- switch (pToken->GetType())
- {
- case svDouble:
-@@ -454,17 +537,27 @@ ScExternalRefCache::TokenArrayRef ScExternalRefCache::getCellRangeData(
- }
- }
- }
-+#endif
-
- if (!bFirstTab)
- pArray->AddOpCode(ocSep);
-
- ScMatrix* pMat2 = xMat;
- ScMatrixToken aToken(pMat2);
-+ if (!pArray)
-+ pArray.reset(new ScTokenArray);
- pArray->AddToken(aToken);
-
- bFirstTab = false;
-+
-+ if (!pNewRange)
-+ pNewRange.reset(new ScRange(nDataCol1, nDataRow1, 0, nDataCol2, nDataRow2, 0));
-+ else
-+ pNewRange->ExtendTo(ScRange(nDataCol1, nDataRow1, 0, nDataCol2, nDataRow2, 0));
- }
-- rDoc.maRangeArrays.insert( RangeArrayMap::value_type( aCacheRange, pArray));
-+
-+ if (pNewRange)
-+ rDoc.maRangeArrays.insert( RangeArrayMap::value_type(*pNewRange, pArray));
- return pArray;
- }
-
-@@ -495,7 +588,7 @@ void ScExternalRefCache::setRangeNameTokens(sal_uInt16 nFileId, const String& rN
- pDoc->maRealRangeNameMap.insert(NamePairMap::value_type(aUpperName, rName));
- }
-
--void ScExternalRefCache::setCellData(sal_uInt16 nFileId, const String& rTabName, SCROW nRow, SCCOL nCol,
-+void ScExternalRefCache::setCellData(sal_uInt16 nFileId, const String& rTabName, SCCOL nCol, SCROW nRow,
- TokenRef pToken, sal_uInt32 nFmtIndex)
- {
- if (!isDocInitialized(nFileId))
-@@ -520,6 +613,7 @@ void ScExternalRefCache::setCellData(sal_uInt16 nFileId, const String& rTabName,
- pTableData.reset(new Table);
-
- pTableData->setCell(nCol, nRow, pToken, nFmtIndex);
-+ pTableData->setCachedCell(nCol, nRow);
- }
-
- void ScExternalRefCache::setCellRangeData(sal_uInt16 nFileId, const ScRange& rRange, const vector<SingleRangeData>& rData,
-@@ -565,20 +659,27 @@ void ScExternalRefCache::setCellRangeData(sal_uInt16 nFileId, const ScRange& rRa
- SCSIZE nC = nCol - nCol1, nR = nRow - nRow1;
- TokenRef pToken;
- const ScMatrixRef& pMat = itrData->mpRangeData;
-+ if (pMat->IsEmpty(nC, nR))
-+ // Don't cache empty cells.
-+ continue;
-+
- if (pMat->IsValue(nC, nR))
- pToken.reset(new formula::FormulaDoubleToken(pMat->GetDouble(nC, nR)));
- else if (pMat->IsString(nC, nR))
- pToken.reset(new formula::FormulaStringToken(pMat->GetString(nC, nR)));
-- else
-- pToken.reset(new ScEmptyCellToken(false, false));
-
-- pTabData->setCell(nCol, nRow, pToken);
-+ if (pToken)
-+ // Don't mark this cell 'cached' here, for better performance.
-+ pTabData->setCell(nCol, nRow, pToken, 0, false);
- }
- }
-+ // Mark the whole range 'cached'.
-+ pTabData->setCachedCellRange(nCol1, nRow1, nCol2, nRow2);
- }
-
- size_t nTabLastId = nTabFirstId + rRange.aEnd.Tab() - rRange.aStart.Tab();
- ScRange aCacheRange( nCol1, nRow1, static_cast<SCTAB>(nTabFirstId), nCol2, nRow2, static_cast<SCTAB>(nTabLastId));
-+
- rDoc.maRangeArrays.insert( RangeArrayMap::value_type( aCacheRange, pArray));
- }
-
-@@ -975,6 +1076,9 @@ ScExternalRefCache::TableTypeRef ScExternalRefCache::getCacheTable(sal_uInt16 nF
- {
- // specified table found.
- if( pnIndex ) *pnIndex = nIndex;
-+ if (bCreateNew && !rDoc.maTables[nIndex])
-+ rDoc.maTables[nIndex].reset(new Table);
-+
- return rDoc.maTables[nIndex];
- }
-
-@@ -1142,11 +1246,11 @@ static FormulaToken* lcl_convertToToken(ScBaseCell* pCell)
- return NULL;
- }
-
--static ScTokenArray* lcl_convertToTokenArray(ScDocument* pSrcDoc, const ScRange& rRange,
-+static ScTokenArray* lcl_convertToTokenArray(ScDocument* pSrcDoc, ScRange& rRange,
- vector<ScExternalRefCache::SingleRangeData>& rCacheData)
- {
-- const ScAddress& s = rRange.aStart;
-- const ScAddress& e = rRange.aEnd;
-+ ScAddress& s = rRange.aStart;
-+ ScAddress& e = rRange.aEnd;
-
- SCTAB nTab1 = s.Tab(), nTab2 = e.Tab();
- SCCOL nCol1 = s.Col(), nCol2 = e.Col();
-@@ -1160,19 +1264,35 @@ static ScTokenArray* lcl_convertToTokenArray(ScDocument* pSrcDoc, const ScRange&
- // range to it.
- return NULL;
-
-+ ::boost::scoped_ptr<ScRange> pUsedRange;
-+
- auto_ptr<ScTokenArray> pArray(new ScTokenArray);
- bool bFirstTab = true;
- vector<ScExternalRefCache::SingleRangeData>::iterator
- itrCache = rCacheData.begin(), itrCacheEnd = rCacheData.end();
-+
- for (SCTAB nTab = nTab1; nTab <= nTab2 && itrCache != itrCacheEnd; ++nTab, ++itrCache)
- {
-+ // Only loop within the data area.
-+ SCCOL nDataCol1 = nCol1, nDataCol2 = nCol2;
-+ SCROW nDataRow1 = nRow1, nDataRow2 = nRow2;
-+ if (!pSrcDoc->ShrinkToDataArea(nTab, nDataCol1, nDataRow1, nDataCol2, nDataRow2))
-+ // no data within specified range.
-+ continue;
-+
-+ if (pUsedRange.get())
-+ // Make sure the used area only grows, not shrinks.
-+ pUsedRange->ExtendTo(ScRange(nDataCol1, nDataRow1, 0, nDataCol2, nDataRow2, 0));
-+ else
-+ pUsedRange.reset(new ScRange(nDataCol1, nDataRow1, 0, nDataCol2, nDataRow2, 0));
-+
- ScMatrixRef xMat = new ScMatrix(
-- static_cast<SCSIZE>(nCol2-nCol1+1),
-- static_cast<SCSIZE>(nRow2-nRow1+1));
-+ static_cast<SCSIZE>(nDataCol2-nDataCol1+1),
-+ static_cast<SCSIZE>(nDataRow2-nDataRow1+1));
-
-- for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
-+ for (SCCOL nCol = nDataCol1; nCol <= nDataCol2; ++nCol)
- {
-- for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
-+ for (SCROW nRow = nDataRow1; nRow <= nDataRow2; ++nRow)
- {
- SCSIZE nC = nCol - nCol1, nR = nRow - nRow1;
- ScBaseCell* pCell;
-@@ -1239,6 +1359,31 @@ static ScTokenArray* lcl_convertToTokenArray(ScDocument* pSrcDoc, const ScRange&
-
- bFirstTab = false;
- }
-+
-+ if (!pUsedRange.get())
-+ return NULL;
-+
-+ s.SetCol(pUsedRange->aStart.Col());
-+ s.SetRow(pUsedRange->aStart.Row());
-+ e.SetCol(pUsedRange->aEnd.Col());
-+ e.SetRow(pUsedRange->aEnd.Row());
-+
-+ return pArray.release();
-+}
-+
-+static ScTokenArray* lcl_fillEmptyMatrix(const ScRange& rRange)
-+{
-+ SCSIZE nC = static_cast<SCSIZE>(rRange.aEnd.Col()-rRange.aStart.Col()+1);
-+ SCSIZE nR = static_cast<SCSIZE>(rRange.aEnd.Row()-rRange.aStart.Row()+1);
-+ ScMatrixRef xMat = new ScMatrix(nC, nR);
-+ for (SCSIZE i = 0; i < nC; ++i)
-+ for (SCSIZE j = 0; j < nR; ++j)
-+ xMat->PutEmpty(i, j);
-+
-+ ScMatrix* pMat2 = xMat;
-+ ScMatrixToken aToken(pMat2);
-+ auto_ptr<ScTokenArray> pArray(new ScTokenArray);
-+ pArray->AddToken(aToken);
- return pArray.release();
- }
-
-@@ -1598,20 +1743,13 @@ ScExternalRefCache::TokenRef ScExternalRefManager::getSingleRefToken(
- if (pFmt)
- pFmt->mbIsSet = false;
-
-- bool bLoading = mpDoc->IsImportingXML();
--
- // Check if the given table name and the cell position is cached.
-- // #i101304# When loading a file, the saved cache (hidden sheet)
-- // is assumed to contain all data for the loaded formulas.
-- // No cache entries are created from empty cells in the saved sheet,
-- // so they have to be created here (bWriteEmpty parameter).
-- // Otherwise, later interpretation of the loaded formulas would
-- // load the source document even if the user didn't want to update.
- sal_uInt32 nFmtIndex = 0;
- ScExternalRefCache::TokenRef pToken = maRefCache.getCellData(
-- nFileId, rTabName, rCell.Col(), rCell.Row(), bLoading, bLoading, &nFmtIndex);
-+ nFileId, rTabName, rCell.Col(), rCell.Row(), &nFmtIndex);
- if (pToken)
- {
-+ // Cache hit !
- if (pFmt)
- {
- short nFmtType = mpDoc->GetFormatTable()->GetType(nFmtIndex);
-@@ -1629,11 +1767,8 @@ ScExternalRefCache::TokenRef ScExternalRefManager::getSingleRefToken(
- ScDocument* pSrcDoc = getSrcDocument(nFileId);
- if (!pSrcDoc)
- {
-- // Source document is not reachable. Try to get data from the cache
-- // once again, but this time treat a non-cached cell as an empty cell
-- // as long as the table itself is cached.
-- pToken = maRefCache.getCellData(
-- nFileId, rTabName, rCell.Col(), rCell.Row(), true, false, &nFmtIndex);
-+ // Source document not reachable. Throw a reference error.
-+ pToken.reset(new FormulaErrorToken(errNoRef));
- return pToken;
- }
-
-@@ -1642,12 +1777,30 @@ ScExternalRefCache::TokenRef ScExternalRefManager::getSingleRefToken(
- if (!pSrcDoc->GetTable(rTabName, nTab))
- {
- // specified table name doesn't exist in the source document.
-- return ScExternalRefCache::TokenRef();
-+ pToken.reset(new FormulaErrorToken(errNoRef));
-+ return pToken;
- }
-
- if (pTab)
- *pTab = nTab;
-
-+ SCCOL nDataCol1 = 0, nDataCol2 = MAXCOL;
-+ SCROW nDataRow1 = 0, nDataRow2 = MAXROW;
-+ pSrcDoc->ShrinkToDataArea(nTab, nDataCol1, nDataRow1, nDataCol2, nDataRow2);
-+ if (rCell.Col() < nDataCol1 || nDataCol2 < rCell.Col() || rCell.Row() < nDataRow1 || nDataRow2 < rCell.Row())
-+ {
-+ // requested cell is outside the data area. Don't even bother caching
-+ // this data, but add it to the cached range to prevent accessing the
-+ // source document time and time again.
-+ ScExternalRefCache::TableTypeRef pCacheTab =
-+ maRefCache.getCacheTable(nFileId, rTabName, true, NULL);
-+ if (pCacheTab)
-+ pCacheTab->setCachedCell(rCell.Col(), rCell.Row());
-+
-+ pToken.reset(new ScEmptyCellToken(false, false));
-+ return pToken;
-+ }
-+
- pSrcDoc->GetCell(rCell.Col(), rCell.Row(), nTab, pCell);
- ScExternalRefCache::TokenRef pTok(lcl_convertToToken(pCell));
-
-@@ -1670,39 +1823,45 @@ ScExternalRefCache::TokenRef ScExternalRefManager::getSingleRefToken(
- pTok.reset( new FormulaErrorToken( errNoValue));
- }
-
-- // Now, insert the token into cache table.
-- maRefCache.setCellData(nFileId, rTabName, rCell.Row(), rCell.Col(), pTok, nFmtIndex);
-+ // Now, insert the token into cache table but don't cache empty cells.
-+ if (pTok->GetType() != formula::svEmptyCell)
-+ maRefCache.setCellData(nFileId, rTabName, rCell.Col(), rCell.Row(), pTok, nFmtIndex);
-+
- return pTok;
- }
-
--ScExternalRefCache::TokenArrayRef ScExternalRefManager::getDoubleRefTokens(sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange, const ScAddress* pCurPos)
-+ScExternalRefCache::TokenArrayRef ScExternalRefManager::getDoubleRefTokens(
-+ sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange, const ScAddress* pCurPos)
- {
- if (pCurPos)
- insertRefCell(nFileId, *pCurPos);
-
- maybeLinkExternalFile(nFileId);
-
-- bool bLoading = mpDoc->IsImportingXML();
--
- // Check if the given table name and the cell position is cached.
-- // #i101304# When loading, put empty cells into cache, see getSingleRefToken.
-- ScExternalRefCache::TokenArrayRef p = maRefCache.getCellRangeData(nFileId, rTabName, rRange, bLoading, bLoading);
-- if (p.get())
-- return p;
-+ ScExternalRefCache::TokenArrayRef pArray =
-+ maRefCache.getCellRangeData(nFileId, rTabName, rRange);
-+ if (pArray)
-+ // Cache hit !
-+ return pArray;
-
- ScDocument* pSrcDoc = getSrcDocument(nFileId);
- if (!pSrcDoc)
- {
-- // Source document is not reachable. Try to get data from the cache
-- // once again, but this time treat non-cached cells as empty cells as
-- // long as the table itself is cached.
-- return maRefCache.getCellRangeData(nFileId, rTabName, rRange, true, false);
-+ // Source document is not reachable. Throw a reference error.
-+ pArray.reset(new ScTokenArray);
-+ pArray->AddToken(FormulaErrorToken(errNoRef));
-+ return pArray;
- }
-
- SCTAB nTab1;
- if (!pSrcDoc->GetTable(rTabName, nTab1))
-+ {
- // specified table name doesn't exist in the source document.
-- return ScExternalRefCache::TokenArrayRef();
-+ pArray.reset(new ScTokenArray);
-+ pArray->AddToken(FormulaErrorToken(errNoRef));
-+ return pArray;
-+ }
-
- ScRange aRange(rRange);
- SCTAB nTabSpan = aRange.aEnd.Tab() - aRange.aStart.Tab();
-@@ -1726,12 +1885,24 @@ ScExternalRefCache::TokenArrayRef ScExternalRefManager::getDoubleRefTokens(sal_u
- aRange.aStart.SetTab(nTab1);
- aRange.aEnd.SetTab(nTab1 + nTabSpan);
-
-- ScExternalRefCache::TokenArrayRef pArray;
- pArray.reset(lcl_convertToTokenArray(pSrcDoc, aRange, aCacheData));
-
- if (pArray)
- // Cache these values.
-- maRefCache.setCellRangeData(nFileId, rRange, aCacheData, pArray);
-+ maRefCache.setCellRangeData(nFileId, aRange, aCacheData, pArray);
-+ else
-+ {
-+ // Array is empty. Fill it with an empty matrix of the required size.
-+ pArray.reset(lcl_fillEmptyMatrix(rRange));
-+
-+ // Make sure to set this range 'cached', to prevent unnecessarily
-+ // accessing the src document time and time again.
-+ ScExternalRefCache::TableTypeRef pCacheTab =
-+ maRefCache.getCacheTable(nFileId, rTabName, true, NULL);
-+ if (pCacheTab)
-+ pCacheTab->setCachedCellRange(
-+ rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row());
-+ }
-
- return pArray;
- }
-@@ -1858,6 +2029,12 @@ ScDocument* ScExternalRefManager::getSrcDocument(sal_uInt16 nFileId)
-
- if (itr != itrEnd)
- {
-+ // document already loaded.
-+
-+ // TODO: Find out a way to access a document that's already open in
-+ // memory and re-use that instance, instead of loading it from the
-+ // disk again.
-+
- SfxObjectShell* p = itr->second.maShell;
- itr->second.maLastAccess = Time();
- return static_cast<ScDocShell*>(p)->GetDocument();
diff --git a/patches/dev300/calc-subtotal-function-update.diff b/patches/dev300/calc-subtotal-function-update.diff
index 444eabe..61265b8 100644
--- a/patches/dev300/calc-subtotal-function-update.diff
+++ b/patches/dev300/calc-subtotal-function-update.diff
@@ -31,7 +31,7 @@
}
ScFormulaCell::ScFormulaCell( const ScFormulaCell& rCell, ScDocument& rDoc, const ScAddress& rPos, int nCloneFlags ) :
-@@ -818,11 +821,15 @@ ScFormulaCell::ScFormulaCell( const ScFo
+@@ -818,12 +821,16 @@ ScFormulaCell::ScFormulaCell( const ScFo
if( nCloneFlags & SC_CLONECELL_STARTLISTENING )
StartListeningTo( &rDoc );
@@ -44,6 +44,7 @@
{
pDocument->RemoveFromFormulaTree( this );
+ pDocument->RemoveSubTotalCell(this);
+
if (pCode->HasOpCode(ocMacro))
pDocument->GetMacroManager()->RemoveDependentCell(this);
diff --git a/patches/dev300/calc-xls-disable-adjust-row-height.diff b/patches/dev300/calc-xls-disable-adjust-row-height.diff
index dfd90cc..17c8135 100644
--- a/patches/dev300/calc-xls-disable-adjust-row-height.diff
+++ b/patches/dev300/calc-xls-disable-adjust-row-height.diff
@@ -1,16 +1,19 @@
diff --git sc/source/filter/excel/read.cxx sc/source/filter/excel/read.cxx
-index a868e17..e3e7ecd 100644
+index 16c07d3..c3af16d 100644
--- sc/source/filter/excel/read.cxx
+++ sc/source/filter/excel/read.cxx
-@@ -1171,7 +1171,12 @@ FltError ImportExcel8::Read( void )
+@@ -1213,10 +1213,13 @@ FltError ImportExcel8::Read( void )
+ GetPivotTableManager().ConvertPivotTables();
pProgress.reset();
-
+-
+#if 0
+ // Excel documents look much better without this call; better in the
+ // sense that the row heights are identical to the original heights in
+ // Excel.
- AdjustRowHeight();
+ if (pD->IsAdjustHeightEnabled())
+ AdjustRowHeight();
+-
+#endif
PostDocLoad();
diff --git a/patches/dev300/sc-dbrange-dynamic-resize.diff b/patches/dev300/sc-dbrange-dynamic-resize.diff
index ed427ad..e05f910 100644
--- a/patches/dev300/sc-dbrange-dynamic-resize.diff
+++ b/patches/dev300/sc-dbrange-dynamic-resize.diff
@@ -24,18 +24,9 @@ index eea9076..00ea53b 100644
BOOL IsByRow() const { return bByRow; }
void SetByRow(BOOL bByR) { bByRow = bByR; }
diff --git sc/inc/document.hxx sc/inc/document.hxx
-index 846daf5..7775029 100644
+index 86a0a27..6b6307c 100644
--- sc/inc/document.hxx
+++ sc/inc/document.hxx
-@@ -874,7 +874,7 @@ public:
- bool ShrinkToDataArea(SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow) const;
-
- void GetDataArea( SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow,
-- SCCOL& rEndCol, SCROW& rEndRow, BOOL bIncludeOld );
-+ SCCOL& rEndCol, SCROW& rEndRow, BOOL bIncludeOld ) const;
- SC_DLLPUBLIC BOOL GetCellArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow ) const;
- SC_DLLPUBLIC BOOL GetTableArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow ) const;
- SC_DLLPUBLIC BOOL GetPrintArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow,
@@ -1393,6 +1393,9 @@ public:
SCTAB nTab, ScQueryParam& rQueryParam );
void GetUpperCellString(SCCOL nCol, SCROW nRow, SCTAB nTab, String& rStr);
@@ -59,24 +50,11 @@ index bc50237..01ddffb 100644
ScQueryParam();
ScQueryParam( const ScQueryParam& r );
-diff --git sc/inc/table.hxx sc/inc/table.hxx
-index 3659381..89f505e 100644
---- sc/inc/table.hxx
-+++ sc/inc/table.hxx
-@@ -379,7 +379,7 @@ public:
- SCCOL nStartCol, SCROW nStartRow, SCCOL& rEndCol, SCROW nEndRow );
-
- void GetDataArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow,
-- BOOL bIncludeOld );
-+ BOOL bIncludeOld ) const;
-
- SCSIZE GetEmptyLinesInBlock( SCCOL nStartCol, SCROW nStartRow,
- SCCOL nEndCol, SCROW nEndRow, ScDirection eDir );
diff --git sc/source/core/data/documen3.cxx sc/source/core/data/documen3.cxx
-index 01868e9..0c31071 100644
+index 48083a3..36d902a 100644
--- sc/source/core/data/documen3.cxx
+++ sc/source/core/data/documen3.cxx
-@@ -1256,6 +1256,18 @@ BOOL ScDocument::HasRowHeader( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol,
+@@ -1253,6 +1253,18 @@ BOOL ScDocument::HasRowHeader( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol,
//return FALSE;
}
@@ -95,7 +73,7 @@ index 01868e9..0c31071 100644
//
// GetFilterEntries - Eintraege fuer AutoFilter-Listbox
//
-@@ -1268,6 +1280,7 @@ BOOL ScDocument::GetFilterEntries(
+@@ -1265,6 +1277,7 @@ BOOL ScDocument::GetFilterEntries(
ScDBData* pDBData = pDBCollection->GetDBAtCursor(nCol, nRow, nTab, FALSE); //!??
if (pDBData)
{
@@ -103,7 +81,7 @@ index 01868e9..0c31071 100644
SCTAB nAreaTab;
SCCOL nStartCol;
SCROW nStartRow;
-@@ -1279,6 +1292,7 @@ BOOL ScDocument::GetFilterEntries(
+@@ -1276,6 +1289,7 @@ BOOL ScDocument::GetFilterEntries(
ScQueryParam aParam;
pDBData->GetQueryParam( aParam );
@@ -111,32 +89,6 @@ index 01868e9..0c31071 100644
rStrings.SetCaseSensitive( aParam.bCaseSens );
// return all filter entries, if a filter condition is connected with a boolean OR
-diff --git sc/source/core/data/document.cxx sc/source/core/data/document.cxx
-index 3180d78..bb0d324 100644
---- sc/source/core/data/document.cxx
-+++ sc/source/core/data/document.cxx
-@@ -669,7 +669,7 @@ bool ScDocument::ShrinkToDataArea(SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow
- // zusammenhaengender Bereich
-
- void ScDocument::GetDataArea( SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow,
-- SCCOL& rEndCol, SCROW& rEndRow, BOOL bIncludeOld )
-+ SCCOL& rEndCol, SCROW& rEndRow, BOOL bIncludeOld ) const
- {
- if (VALIDTAB(nTab))
- if (pTab[nTab])
-diff --git sc/source/core/data/table1.cxx sc/source/core/data/table1.cxx
-index 22d9f64..a9f7255 100644
---- sc/source/core/data/table1.cxx
-+++ sc/source/core/data/table1.cxx
-@@ -685,7 +685,7 @@ BOOL ScTable::GetDataStart( SCCOL& rStartCol, SCROW& rStartRow ) const
- }
-
- void ScTable::GetDataArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow,
-- BOOL bIncludeOld )
-+ BOOL bIncludeOld ) const
- {
- BOOL bLeft = FALSE;
- BOOL bRight = FALSE;
diff --git sc/source/core/data/table3.cxx sc/source/core/data/table3.cxx
index 986755a..2ecc8c1 100644
--- sc/source/core/data/table3.cxx
@@ -208,25 +160,10 @@ index 4f0e755..5fae4bd 100644
rQueryParam.Resize( MAXQUERY );
for (SCSIZE i=0; i<MAXQUERY; i++)
diff --git sc/source/core/tool/queryparam.cxx sc/source/core/tool/queryparam.cxx
-index b97558d..d04880f 100644
+index 7b129e6..80dd170 100644
--- sc/source/core/tool/queryparam.cxx
+++ sc/source/core/tool/queryparam.cxx
-@@ -171,7 +171,13 @@ ScQueryParamTable::~ScQueryParamTable()
-
- ScQueryParam::ScQueryParam() :
- ScQueryParamBase(),
-- ScQueryParamTable()
-+ ScQueryParamTable(),
-+ bDestPers(true),
-+ nDestTab(0),
-+ nDestCol(0),
-+ nDestRow(0),
-+ nDynamicEndRow(0),
-+ bUseDynamicRange(false)
- {
- Clear();
- }
-@@ -181,7 +187,8 @@ ScQueryParam::ScQueryParam() :
+@@ -185,7 +185,8 @@ ScQueryParam::ScQueryParam() :
ScQueryParam::ScQueryParam( const ScQueryParam& r ) :
ScQueryParamBase(r),
ScQueryParamTable(r),
@@ -236,7 +173,7 @@ index b97558d..d04880f 100644
{
}
-@@ -191,7 +198,9 @@ ScQueryParam::ScQueryParam( const ScDBQueryParamInternal& r ) :
+@@ -195,7 +196,9 @@ ScQueryParam::ScQueryParam( const ScDBQueryParamInternal& r ) :
bDestPers(true),
nDestTab(0),
nDestCol(0),
@@ -247,7 +184,7 @@ index b97558d..d04880f 100644
{
}
-@@ -225,6 +234,8 @@ void ScQueryParam::ClearDestParams()
+@@ -229,6 +232,8 @@ void ScQueryParam::ClearDestParams()
nDestTab = 0;
nDestCol = 0;
nDestRow = 0;
@@ -256,7 +193,7 @@ index b97558d..d04880f 100644
}
//------------------------------------------------------------------------
-@@ -247,6 +258,8 @@ ScQueryParam& ScQueryParam::operator=( const ScQueryParam& r )
+@@ -251,6 +256,8 @@ ScQueryParam& ScQueryParam::operator=( const ScQueryParam& r )
bDuplicate = r.bDuplicate;
bByRow = r.bByRow;
bDestPers = r.bDestPers;
@@ -265,7 +202,7 @@ index b97558d..d04880f 100644
maEntries = r.maEntries;
-@@ -285,7 +298,9 @@ BOOL ScQueryParam::operator==( const ScQueryParam& rOther ) const
+@@ -289,7 +296,9 @@ BOOL ScQueryParam::operator==( const ScQueryParam& rOther ) const
&& (bDestPers == rOther.bDestPers)
&& (nDestTab == rOther.nDestTab)
&& (nDestCol == rOther.nDestCol)
@@ -276,7 +213,7 @@ index b97558d..d04880f 100644
{
bEqual = TRUE;
for ( SCSIZE i=0; i<nUsed && bEqual; i++ )
-@@ -309,6 +324,7 @@ void ScQueryParam::MoveToDest()
+@@ -313,6 +322,7 @@ void ScQueryParam::MoveToDest()
nCol2 = sal::static_int_cast<SCCOL>( nCol2 + nDifX );
nRow2 = sal::static_int_cast<SCROW>( nRow2 + nDifY );
nTab = sal::static_int_cast<SCTAB>( nTab + nDifZ );
@@ -359,7 +296,7 @@ index 30081ce..a5f860a 100644
pDBData->SetQueryParam( aParam ); // speichern
}
diff --git sc/source/ui/view/tabvwshc.cxx sc/source/ui/view/tabvwshc.cxx
-index 968984d..42d6fb3 100644
+index 968984d..01ae2ca 100644
--- sc/source/ui/view/tabvwshc.cxx
+++ sc/source/ui/view/tabvwshc.cxx
@@ -178,8 +178,9 @@ SfxModelessDialog* ScTabViewShell::CreateRefDialog(
@@ -373,13 +310,7 @@ index 968984d..42d6fb3 100644
ScQueryItem aItem( SCITEM_QUERYDATA, GetViewData(), &aQueryParam );
ScRange aAdvSource;
-@@ -197,14 +198,14 @@ SfxModelessDialog* ScTabViewShell::CreateRefDialog(
-
- case SID_FILTER:
- {
--
- ScQueryParam aQueryParam;
- SfxItemSet aArgSet( GetPool(),
+@@ -203,8 +204,9 @@ SfxModelessDialog* ScTabViewShell::CreateRefDialog(
SCITEM_QUERYDATA,
SCITEM_QUERYDATA );
diff --git a/patches/vba/cws-vbasupportdev300.diff b/patches/vba/cws-vbasupportdev300.diff
index 36781f2..996df7c 100644
--- a/patches/vba/cws-vbasupportdev300.diff
+++ b/patches/vba/cws-vbasupportdev300.diff
@@ -12811,13 +12811,17 @@
#include <svx/editobj.hxx>
#include <svtools/intitem.hxx>
#include <svx/flditem.hxx>
-@@ -822,6 +823,9 @@ ScFormulaCell::ScFormulaCell( const ScFo
+@@ -822,10 +823,13 @@ ScFormulaCell::ScFormulaCell( const ScFo
ScFormulaCell::~ScFormulaCell()
{
pDocument->RemoveFromFormulaTree( this );
++
+ if (pCode->HasOpCode(ocMacro))
+ pDocument->GetMacroManager()->RemoveDependentCell(this);
-+
+
+ if (pDocument->HasExternalRefManager())
+ pDocument->GetExternalRefManager()->removeRefCell(this);
+
delete pCode;
#ifdef DBG_UTIL
eCellType = CELLTYPE_DESTROYED;
commit 52a6984bb91dfb8cf4140ba5a53166904099b6e7
Author: Kohei Yoshida <kyoshida at novell.com>
Date: Mon Mar 8 22:09:58 2010 -0500
Backported from koheiextref01 cws.
* patches/dev300/apply:
* patches/dev300/cws-koheiextref01-offapi.diff:
* patches/dev300/cws-koheiextref01-oox.diff:
* patches/dev300/cws-koheiextref01-sc.diff:
diff --git a/patches/dev300/apply b/patches/dev300/apply
index 479c996..fd75306 100644
--- a/patches/dev300/apply
+++ b/patches/dev300/apply
@@ -212,6 +212,11 @@ cws-koheicopyborder-svx.diff, kohei
# kohei04 cws
cws-kohei04-sc.diff, kohei
+# koheiextref01 cws
+cws-koheiextref01-offapi.diff, kohei
+cws-koheiextref01-oox.diff, kohei
+cws-koheiextref01-sc.diff, kohei
+
[ LinuxOnly ]
# Don't stat tons of config files we don't need to read on startup
speed-configmgr.diff, i#56783, michael
diff --git a/patches/dev300/cws-koheiextref01-offapi.diff b/patches/dev300/cws-koheiextref01-offapi.diff
new file mode 100644
index 0000000..b88e57e
--- /dev/null
+++ b/patches/dev300/cws-koheiextref01-offapi.diff
@@ -0,0 +1,22 @@
+diff --git offapi/com/sun/star/sheet/XExternalDocLink.idl offapi/com/sun/star/sheet/XExternalDocLink.idl
+index 35561f6..83a2495 100644
+--- offapi/com/sun/star/sheet/XExternalDocLink.idl
++++ offapi/com/sun/star/sheet/XExternalDocLink.idl
+@@ -63,9 +63,16 @@ interface XExternalDocLink
+
+ @param aSheetName sheet name
+
++ @param DynamicCache specify whether or not the cache can grow when
++ non-cached regions are queried. If <true/>, querying a non-cached
++ cell in this sheet cache will allow Calc to try to access the source
++ document to fetch the value in first access. If <false/>, the source
++ document will not be accessed, and the non-cached regions are treated
++ as empty cells.
++
+ @return com::sun::star::sheet::XExternalSheetCache sheet cache instance
+ */
+- com::sun::star::sheet::XExternalSheetCache addSheetCache( [in] string aSheetName );
++ com::sun::star::sheet::XExternalSheetCache addSheetCache( [in] string aSheetName, [in] boolean DynamicCache );
+
+ //-------------------------------------------------------------------------
+
diff --git a/patches/dev300/cws-koheiextref01-oox.diff b/patches/dev300/cws-koheiextref01-oox.diff
new file mode 100644
index 0000000..d082089
--- /dev/null
+++ b/patches/dev300/cws-koheiextref01-oox.diff
@@ -0,0 +1,13 @@
+diff --git oox/source/xls/externallinkbuffer.cxx oox/source/xls/externallinkbuffer.cxx
+index c756252..5006204 100644
+--- oox/source/xls/externallinkbuffer.cxx
++++ oox/source/xls/externallinkbuffer.cxx
+@@ -912,7 +912,7 @@ void ExternalLink::insertExternalSheet( const OUString& rSheetName )
+ OSL_ENSURE( rSheetName.getLength() > 0, "ExternalLink::insertExternalSheet - empty sheet name" );
+ if( mxDocLink.is() )
+ {
+- Reference< XExternalSheetCache > xSheetCache = mxDocLink->addSheetCache( rSheetName );
++ Reference< XExternalSheetCache > xSheetCache = mxDocLink->addSheetCache( rSheetName, false );
+ sal_Int32 nCacheIdx = xSheetCache.is() ? xSheetCache->getTokenIndex() : -1;
+ maSheetCaches.push_back( nCacheIdx );
+ }
diff --git a/patches/dev300/cws-koheiextref01-sc.diff b/patches/dev300/cws-koheiextref01-sc.diff
new file mode 100644
index 0000000..9cd978e
--- /dev/null
+++ b/patches/dev300/cws-koheiextref01-sc.diff
@@ -0,0 +1,1825 @@
+diff --git sc/inc/column.hxx sc/inc/column.hxx
+index 983ca1f..6d02c3e 100644
+--- sc/inc/column.hxx
++++ sc/inc/column.hxx
+@@ -278,7 +278,6 @@ public:
+ void CalcAfterLoad();
+ void CompileAll();
+ void CompileXML( ScProgress& rProgress );
+- bool MarkUsedExternalReferences();
+
+ void ResetChanged( SCROW nStartRow, SCROW nEndRow );
+
+diff --git sc/inc/document.hxx sc/inc/document.hxx
+index 768e1ad..38d35e9 100644
+--- sc/inc/document.hxx
++++ sc/inc/document.hxx
+@@ -870,8 +870,8 @@ public:
+
+ bool ShrinkToDataArea(SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow) const;
+
+- void GetDataArea( SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow,
+- SCCOL& rEndCol, SCROW& rEndRow, BOOL bIncludeOld );
++ void GetDataArea( SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow,
++ SCCOL& rEndCol, SCROW& rEndRow, BOOL bIncludeOld ) const;
+ SC_DLLPUBLIC BOOL GetCellArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow ) const;
+ SC_DLLPUBLIC BOOL GetTableArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow ) const;
+ SC_DLLPUBLIC BOOL GetPrintArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow,
+diff --git sc/inc/externalrefmgr.hxx sc/inc/externalrefmgr.hxx
+index 22e114d..7db9bc9 100644
+--- sc/inc/externalrefmgr.hxx
++++ sc/inc/externalrefmgr.hxx
+@@ -39,12 +39,14 @@
+ #include "vcl/timer.hxx"
+ #include "svtools/zforlist.hxx"
+ #include "scmatrix.hxx"
++#include "rangelst.hxx"
+
+ #include <hash_map>
+ #include <hash_set>
+ #include <boost/shared_ptr.hpp>
+ #include <vector>
+ #include <list>
++#include <set>
+ #include <formula/ExternalReferenceHelper.hxx>
+
+ class ScDocument;
+@@ -58,6 +60,7 @@ class ScTokenArray;
+ class String;
+ class SfxObjectShellRef;
+ class Window;
++class ScFormulaCell;
+
+ class ScExternalRefCache;
+
+@@ -129,6 +132,15 @@ public:
+ class Table;
+ friend class ScExternalRefCache::Table;
+
++ /**
++ * Represents a single cached table in an external document. It only
++ * stores non-empty cells; empty cells should never be stored in the data
++ * cache. Instead, cached ranges should be used to determine whether or
++ * not a cell is empty or needs fetching from the source document. If a
++ * cell's value is not stored but its address is within the cached ranges,
++ * that cell is already queried in the source document and we know it's
++ * empty.
++ */
+ class Table
+ {
+ public:
+@@ -143,7 +155,14 @@ public:
+ Table();
+ ~Table();
+
+- SC_DLLPUBLIC void setCell(SCCOL nCol, SCROW nRow, TokenRef pToken, sal_uInt32 nFmtIndex = 0);
++ /**
++ * Add cell value to the cache.
++ *
++ * @param bSetCacheRange if true, mark this cell 'cached'. This is
++ * false _only when_ adding a range of cell
++ * values, for performance reasons.
++ */
++ SC_DLLPUBLIC void setCell(SCCOL nCol, SCROW nRow, TokenRef pToken, sal_uInt32 nFmtIndex = 0, bool bSetCacheRange = true);
+ TokenRef getCell(SCCOL nCol, SCROW nRow, sal_uInt32* pnFmtIndex = NULL) const;
+ bool hasRow( SCROW nRow ) const;
+ /** Set/clear referenced status flag only if current status is not
+@@ -154,14 +173,35 @@ public:
+ ReferencedFlag getReferencedFlag() const;
+ bool isReferenced() const;
+ /// Obtain a sorted vector of rows.
+- void getAllRows(::std::vector<SCROW>& rRows) const;
++ void getAllRows(::std::vector<SCROW>& rRows, SCROW nLow = 0, SCROW nHigh = MAXROW) const;
+ /// Obtain a sorted vector of columns.
+- void getAllCols(SCROW nRow, ::std::vector<SCCOL>& rCols) const;
++ void getAllCols(SCROW nRow, ::std::vector<SCCOL>& rCols, SCCOL nLow = 0, SCCOL nHigh = MAXCOL) const;
+ void getAllNumberFormats(::std::vector<sal_uInt32>& rNumFmts) const;
++ const ScRangeList& getCachedRanges() const;
++ bool isRangeCached(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const;
++
++ void setCachedCell(SCCOL nCol, SCROW nRow);
++ void setCachedCellRange(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
++
++ /**
++ * Call this to mark the entire table "cached". This will prevent all
++ * future attempts to access the source document even when non-cached
++ * cells are queried. In such case, non-cached cells are treated as
++ * empty cells. Useful when loading a document with own external data
++ * cache.
++ */
++ SC_DLLPUBLIC void setWholeTableCached();
++ private:
++ bool isInCachedRanges(SCCOL nCol, SCROW nRow) const;
++ TokenRef getEmptyOrNullToken(SCCOL nCol, SCROW nRow) const;
+
+ private:
+- RowsDataType maRows;
+- ReferencedFlag meReferenced;
++ /** Data cache */
++ RowsDataType maRows;
++ /** Collection of individual cached ranges. The table ranges are
++ * not used & always zero. */
++ ScRangeList maCachedRanges;
++ ReferencedFlag meReferenced;
+ };
+
+ typedef ::boost::shared_ptr<Table> TableTypeRef;
+@@ -184,8 +224,7 @@ public:
+ * @return pointer to the token instance in the cache.
+ */
+ ScExternalRefCache::TokenRef getCellData(
+- sal_uInt16 nFileId, const String& rTabName, SCCOL nCol, SCROW nRow,
+- bool bEmptyCellOnNull, bool bWriteEmpty, sal_uInt32* pnFmtIndex);
++ sal_uInt16 nFileId, const String& rTabName, SCCOL nCol, SCROW nRow, sal_uInt32* pnFmtIndex);
+
+ /**
+ * Get a cached cell range data.
+@@ -195,12 +234,12 @@ public:
+ * guaranteed if the TokenArrayRef is properly used..
+ */
+ ScExternalRefCache::TokenArrayRef getCellRangeData(
+- sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange, bool bEmptyCellOnNull, bool bWriteEmpty);
++ sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange);
+
+ ScExternalRefCache::TokenArrayRef getRangeNameTokens(sal_uInt16 nFileId, const String& rName);
+ void setRangeNameTokens(sal_uInt16 nFileId, const String& rName, TokenArrayRef pArray);
+
+- void setCellData(sal_uInt16 nFileId, const String& rTabName, SCROW nRow, SCCOL nCol, TokenRef pToken, sal_uInt32 nFmtIndex);
++ void setCellData(sal_uInt16 nFileId, const String& rTabName, SCCOL nCol, SCROW nRow, TokenRef pToken, sal_uInt32 nFmtIndex);
+
+ struct SingleRangeData
+ {
+@@ -324,58 +363,8 @@ class SC_DLLPUBLIC ScExternalRefManager : public formula::ExternalReferenceHelpe
+ {
+ public:
+
+- // SUNWS needs a forward declared friend, otherwise types and members
+- // of the outer class are not accessible.
+- class RefCells;
+- friend class ScExternalRefManager::RefCells;
+-
+- /**
+- * Collection of cell addresses that contain external references. This
+- * data is used for link updates.
+- */
+- class RefCells
+- {
+- public:
+- RefCells();
+- ~RefCells();
+-
+- void insertCell(const ScAddress& rAddr);
+- void removeCell(const ScAddress& rAddr);
+- void moveTable(SCTAB nOldTab, SCTAB nNewTab, bool bCopy);
+- void insertTable(SCTAB nPos);
+- void removeTable(SCTAB nPos);
+- void refreshAllCells(ScExternalRefManager& rRefMgr);
+- private:
+-
+- typedef ::std::hash_set<SCROW> RowSet;
+- typedef ::std::hash_map<SCCOL, RowSet> ColSet;
+-
+- // SUNWS needs a forward declared friend, otherwise types and members
+- // of the outer class are not accessible.
+- struct TabItem;
+- friend struct ScExternalRefManager::RefCells::TabItem;
+-
+- struct TabItem
+- {
+- SCTAB mnIndex;
+- ColSet maCols;
+- explicit TabItem(SCTAB nIndex);
+- explicit TabItem(const TabItem& r);
+- };
+- typedef ::boost::shared_ptr<TabItem> TabItemRef;
+-
+- /**
+- * Return the position that points either to the specified table
+- * position or to the position where a new table would be inserted in
+- * case the specified table is not present.
+- *
+- * @param nTab index of the desired table
+- */
+- ::std::list<TabItemRef>::iterator getTabPos(SCTAB nTab);
+-
+- // This list must be sorted by the table index at all times.
+- ::std::list<TabItemRef> maTables;
+- };
++ typedef ::std::set<ScFormulaCell*> RefCellSet;
++ typedef ::std::hash_map<sal_uInt16, RefCellSet> RefCellMap;
+
+ enum LinkUpdateType { LINK_MODIFIED, LINK_BROKEN };
+
+@@ -411,7 +400,6 @@ private:
+ typedef ::std::hash_map<sal_uInt16, SrcShell> DocShellMap;
+ typedef ::std::hash_map<sal_uInt16, bool> LinkedDocMap;
+
+- typedef ::std::hash_map<sal_uInt16, RefCells> RefCellMap;
+ typedef ::std::hash_map<sal_uInt16, SvNumberFormatterMergeMap> NumFmtMap;
+
+
+@@ -508,12 +496,7 @@ public:
+ */
+ bool markUsedByLinkListeners();
+
+- /**
+- * Set all tables of a document as referenced, used only during
+- * store-to-file.
+- * @returns <TRUE/> if ALL tables of ALL external documents are marked.
+- */
+- bool setCacheDocReferenced( sal_uInt16 nFileId );
++ bool markUsedExternalRefCells();
+
+ /**
+ * Set a table as referenced, used only during store-to-file.
+@@ -553,7 +536,8 @@ public:
+ * @return shared_ptr to a token array instance. <i>The caller must not
+ * delete the instance returned by this method.</i>
+ */
+- ScExternalRefCache::TokenArrayRef getDoubleRefTokens(sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange, const ScAddress* pCurPos);
++ ScExternalRefCache::TokenArrayRef getDoubleRefTokens(
++ sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange, const ScAddress* pCurPos);
+
+ /**
+ * Get an array of tokens corresponding with a specified name in a
+@@ -566,7 +550,8 @@ public:
+ *
+ * @return shared_ptr to array of tokens composing the name
+ */
+- ScExternalRefCache::TokenArrayRef getRangeNameTokens(sal_uInt16 nFileId, const String& rName, const ScAddress* pCurPos = NULL);
++ ScExternalRefCache::TokenArrayRef getRangeNameTokens(
++ sal_uInt16 nFileId, const String& rName, const ScAddress* pCurPos = NULL);
+
+ const String& getOwnDocumentName() const;
+ bool isOwnDocument(const String& rFile) const;
+@@ -638,32 +623,12 @@ public:
+ void resetSrcFileData(const String& rBaseFileUrl);
+
+ /**
+- * Update a single referencing cell position.
+- *
+- * @param rOldPos old position
+- * @param rNewPos new position
+- */
+- void updateRefCell(const ScAddress& rOldPos, const ScAddress& rNewPos, bool bCopy);
+-
+- /**
+- * Update referencing cells affected by sheet movement.
+- *
+- * @param nOldTab old sheet position
+- * @param nNewTab new sheet position
+- * @param bCopy whether this is a sheet move (false) or sheet copy (true)
+- */
+- void updateRefMoveTable(SCTAB nOldTab, SCTAB nNewTab, bool bCopy);
+-
+- /**
+- * Update referencing cells affected by sheet insertion.
+- *
+- * @param nPos sheet insertion position. All sheets to the right
+- * including the one at the insertion poistion shift to the
+- * right by one.
++ * Stop tracking a specific formula cell.
++ *
++ * @param pCell pointer to cell that formerly contained external
++ * reference.
+ */
+- void updateRefInsertTable(SCTAB nPos);
+-
+- void updateRefDeleteTable(SCTAB nPos);
++ void removeRefCell(ScFormulaCell* pCell);
+
+ /**
+ * Register a new link listener to a specified external document. Note
+@@ -715,8 +680,6 @@ private:
+ */
+ void maybeCreateRealFileName(sal_uInt16 nFileId);
+
+- bool compileTokensByCell(const ScAddress& rCell);
+-
+ /**
+ * Purge those source document instances that have not been accessed for
+ * the specified duration.
+diff --git sc/inc/linkuno.hxx sc/inc/linkuno.hxx
+index 75b3a09..8168ef8 100644
+--- sc/inc/linkuno.hxx
++++ sc/inc/linkuno.hxx
+@@ -546,7 +546,7 @@ public:
+
+ // XExternalDocLink
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XExternalSheetCache >
+- SAL_CALL addSheetCache( const ::rtl::OUString& aSheetName )
++ SAL_CALL addSheetCache( const ::rtl::OUString& aSheetName, sal_Bool bDynamicCache )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XNameAccess
+diff --git sc/inc/table.hxx sc/inc/table.hxx
+index 589d73f..56ab75a 100644
+--- sc/inc/table.hxx
++++ sc/inc/table.hxx
+@@ -377,8 +377,8 @@ public:
+ void ExtendPrintArea( OutputDevice* pDev,
+ SCCOL nStartCol, SCROW nStartRow, SCCOL& rEndCol, SCROW nEndRow );
+
+- void GetDataArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow,
+- BOOL bIncludeOld );
++ void GetDataArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow,
++ BOOL bIncludeOld ) const;
+
+ SCSIZE GetEmptyLinesInBlock( SCCOL nStartCol, SCROW nStartRow,
+ SCCOL nEndCol, SCROW nEndRow, ScDirection eDir );
+@@ -415,7 +415,6 @@ public:
+ void CalcAfterLoad();
+ void CompileAll();
+ void CompileXML( ScProgress& rProgress );
+- bool MarkUsedExternalReferences();
+
+ void UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
+ SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
+diff --git sc/source/core/data/cell.cxx sc/source/core/data/cell.cxx
+index bebcf5a..80b5846 100644
+--- sc/source/core/data/cell.cxx
++++ sc/source/core/data/cell.cxx
+@@ -822,6 +822,10 @@ ScFormulaCell::ScFormulaCell( const ScFormulaCell& rCell, ScDocument& rDoc, cons
+ ScFormulaCell::~ScFormulaCell()
+ {
+ pDocument->RemoveFromFormulaTree( this );
++
++ if (pDocument->HasExternalRefManager())
++ pDocument->GetExternalRefManager()->removeRefCell(this);
++
+ delete pCode;
+ #ifdef DBG_UTIL
+ eCellType = CELLTYPE_DESTROYED;
+diff --git sc/source/core/data/cell2.cxx sc/source/core/data/cell2.cxx
+index 5f0b95c..8b7fdf1 100644
+--- sc/source/core/data/cell2.cxx
++++ sc/source/core/data/cell2.cxx
+@@ -1039,17 +1039,6 @@ void ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode,
+
+ delete pOld;
+ }
+-
+- pCode->Reset();
+- for ( formula::FormulaToken* t = pCode->GetNextReferenceOrName(); t; t = pCode->GetNextReferenceOrName() )
+- {
+- StackVar sv = t->GetType();
+- if (sv == svExternalSingleRef || sv == svExternalDoubleRef || sv == svExternalName)
+- {
+- pDocument->GetExternalRefManager()->updateRefCell(aOldPos, aPos, eUpdateRefMode == URM_COPY);
+- break;
+- }
+- }
+ }
+
+ void ScFormulaCell::UpdateInsertTab(SCTAB nTable)
+diff --git sc/source/core/data/column.cxx sc/source/core/data/column.cxx
+index 81586a1..cc5360a 100644
+--- sc/source/core/data/column.cxx
++++ sc/source/core/data/column.cxx
+@@ -2103,22 +2103,6 @@ void ScColumn::CalcAfterLoad()
+ }
+
+
+-bool ScColumn::MarkUsedExternalReferences()
+-{
+- bool bAllMarked = false;
+- if (pItems)
+- {
+- for (SCSIZE i = 0; i < nCount && !bAllMarked; ++i)
+- {
+- ScBaseCell* pCell = pItems[i].pCell;
+- if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+- bAllMarked = ((ScFormulaCell*)pCell)->MarkUsedExternalReferences();
+- }
+- }
+- return bAllMarked;
+-}
+-
+-
+ void ScColumn::ResetChanged( SCROW nStartRow, SCROW nEndRow )
+ {
+ if (pItems)
+diff --git sc/source/core/data/documen2.cxx sc/source/core/data/documen2.cxx
+index 26933b3..8fe59e2 100644
+--- sc/source/core/data/documen2.cxx
++++ sc/source/core/data/documen2.cxx
+@@ -806,10 +806,6 @@ BOOL ScDocument::MoveTab( SCTAB nOldPos, SCTAB nNewPos )
+ if (pDrawLayer)
+ DrawMovePage( static_cast<sal_uInt16>(nOldPos), static_cast<sal_uInt16>(nNewPos) );
+
+- // Update cells containing external references.
+- if (pExternalRefMgr.get())
+- pExternalRefMgr->updateRefMoveTable(nOldPos, nNewPos, false);
+-
+ bValid = TRUE;
+ }
+ }
+@@ -927,10 +923,6 @@ BOOL ScDocument::CopyTab( SCTAB nOldPos, SCTAB nNewPos, const ScMarkData* pOnlyM
+
+ pTab[nNewPos]->SetPageStyle( pTab[nOldPos]->GetPageStyle() );
+ pTab[nNewPos]->SetPendingRowHeights( pTab[nOldPos]->IsPendingRowHeights() );
+-
+- // Update cells containing external references.
+- if (pExternalRefMgr.get())
+- pExternalRefMgr->updateRefMoveTable(nOldPos, nNewPos, true);
+ }
+ else
+ SetAutoCalc( bOldAutoCalc );
+diff --git sc/source/core/data/documen3.cxx sc/source/core/data/documen3.cxx
+index f59a922..d0a7749 100644
+--- sc/source/core/data/documen3.cxx
++++ sc/source/core/data/documen3.cxx
+@@ -463,11 +463,8 @@ void ScDocument::MarkUsedExternalReferences()
+ // Charts.
+ bool bAllMarked = pExternalRefMgr->markUsedByLinkListeners();
+ // Formula cells.
+- for (SCTAB nTab = 0; !bAllMarked && nTab < nMaxTableNumber; ++nTab)
+- {
+- if (pTab[nTab])
+- bAllMarked = pTab[nTab]->MarkUsedExternalReferences();
+- }
++ bAllMarked = pExternalRefMgr->markUsedExternalRefCells();
++
+ /* NOTE: Conditional formats and validation objects are marked when
+ * collecting them during export. */
+ }
+diff --git sc/source/core/data/documen5.cxx sc/source/core/data/documen5.cxx
+index 24cbf48..564bf3f 100644
+--- sc/source/core/data/documen5.cxx
++++ sc/source/core/data/documen5.cxx
+@@ -930,6 +930,9 @@ void ScDocument::UpdateChartListenerCollection()
+ SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"Page ?");
+
++ if (!pPage)
++ continue;
++
+ SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+diff --git sc/source/core/data/document.cxx sc/source/core/data/document.cxx
+index 4b2a812..980cbc8 100644
+--- sc/source/core/data/document.cxx
++++ sc/source/core/data/document.cxx
+@@ -344,10 +344,6 @@ BOOL ScDocument::InsertTab( SCTAB nPos, const String& rName,
+ if ( pChartListenerCollection )
+ pChartListenerCollection->UpdateScheduledSeriesRanges();
+
+- // Update cells containing external references.
+- if (pExternalRefMgr.get())
+- pExternalRefMgr->updateRefInsertTable(nPos);
+-
+ SetDirty();
+ bValid = TRUE;
+ }
+@@ -436,11 +432,6 @@ BOOL ScDocument::DeleteTab( SCTAB nTab, ScDocument* pRefUndoDoc )
+ // #81844# sheet names of references are not valid until sheet is deleted
+ pChartListenerCollection->UpdateScheduledSeriesRanges();
+
+-
+- // Update cells containing external references.
+- if (pExternalRefMgr.get())
+- pExternalRefMgr->updateRefDeleteTable(nTab);
+-
+ SetAutoCalc( bOldAutoCalc );
+ bValid = TRUE;
+ }
+@@ -663,17 +654,20 @@ bool ScDocument::ShrinkToDataArea(SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow
+ if (nRow2 < rEndRow)
+ rEndRow = nRow2;
+
++ if (rStartCol > rEndCol || rStartRow > rEndRow)
++ // invalid range.
++ return false;
++
+ return true; // success!
+ }
+
+ // zusammenhaengender Bereich
+
+ void ScDocument::GetDataArea( SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow,
+- SCCOL& rEndCol, SCROW& rEndRow, BOOL bIncludeOld )
++ SCCOL& rEndCol, SCROW& rEndRow, BOOL bIncludeOld ) const
+ {
+- if (VALIDTAB(nTab))
+- if (pTab[nTab])
+- pTab[nTab]->GetDataArea( rStartCol, rStartRow, rEndCol, rEndRow, bIncludeOld );
++ if (ValidTab(nTab) && pTab[nTab])
++ pTab[nTab]->GetDataArea( rStartCol, rStartRow, rEndCol, rEndRow, bIncludeOld );
+ }
+
+
+diff --git sc/source/core/data/table1.cxx sc/source/core/data/table1.cxx
+index 22d9f64..a9f7255 100644
+--- sc/source/core/data/table1.cxx
++++ sc/source/core/data/table1.cxx
+@@ -685,7 +685,7 @@ BOOL ScTable::GetDataStart( SCCOL& rStartCol, SCROW& rStartRow ) const
+ }
+
+ void ScTable::GetDataArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow,
+- BOOL bIncludeOld )
++ BOOL bIncludeOld ) const
+ {
+ BOOL bLeft = FALSE;
+ BOOL bRight = FALSE;
+diff --git sc/source/core/data/table2.cxx sc/source/core/data/table2.cxx
+index 9f3ac31..46b8184 100644
+--- sc/source/core/data/table2.cxx
++++ sc/source/core/data/table2.cxx
+@@ -1130,17 +1130,6 @@ void ScTable::CalcAfterLoad()
+ }
+
+
+-bool ScTable::MarkUsedExternalReferences()
+-{
+- bool bAllMarked = false;
+- for (SCCOL i=0; i <= MAXCOL && !bAllMarked; ++i)
+- {
+- bAllMarked = aCol[i].MarkUsedExternalReferences();
+- }
+- return bAllMarked;
+-}
+-
+-
+ void ScTable::ResetChanged( const ScRange& rRange )
+ {
+ SCCOL nStartCol = rRange.aStart.Col();
+diff --git sc/source/core/tool/queryparam.cxx sc/source/core/tool/queryparam.cxx
+index b97558d..7b129e6 100644
+--- sc/source/core/tool/queryparam.cxx
++++ sc/source/core/tool/queryparam.cxx
+@@ -171,7 +171,11 @@ ScQueryParamTable::~ScQueryParamTable()
+
+ ScQueryParam::ScQueryParam() :
+ ScQueryParamBase(),
+- ScQueryParamTable()
++ ScQueryParamTable(),
++ bDestPers(true),
++ nDestTab(0),
++ nDestCol(0),
++ nDestRow(0)
+ {
+ Clear();
+ }
+diff --git sc/source/filter/excel/read.cxx sc/source/filter/excel/read.cxx
+index bf46290..16c07d3 100644
+--- sc/source/filter/excel/read.cxx
++++ sc/source/filter/excel/read.cxx
+@@ -1214,7 +1214,9 @@ FltError ImportExcel8::Read( void )
+
+ pProgress.reset();
+
+- AdjustRowHeight();
++ if (pD->IsAdjustHeightEnabled())
++ AdjustRowHeight();
++
+ PostDocLoad();
+
+ pD->CalcAfterLoad();
+diff --git sc/source/filter/excel/xilink.cxx sc/source/filter/excel/xilink.cxx
+index 0026821..b76baf6 100644
+--- sc/source/filter/excel/xilink.cxx
++++ sc/source/filter/excel/xilink.cxx
+@@ -570,6 +570,7 @@ void XclImpSupbook::LoadCachedValues()
+ const String& rTabName = pTab->GetTabName();
+ ScExternalRefCache::TableTypeRef pCacheTable = pRefMgr->getCacheTable(nFileId, rTabName, true);
+ pTab->LoadCachedValues(pCacheTable);
++ pCacheTable->setWholeTableCached();
+ }
+ }
+
+diff --git sc/source/filter/xml/xmlexternaltabi.cxx sc/source/filter/xml/xmlexternaltabi.cxx
+index b953b26..a5685e9 100644
+--- sc/source/filter/xml/xmlexternaltabi.cxx
++++ sc/source/filter/xml/xmlexternaltabi.cxx
+@@ -373,7 +373,7 @@ SvXMLImportContext* ScXMLExternalRefCellContext::CreateChildContext(
+ const SvXMLTokenMap& rTokenMap = mrScImport.GetTableRowCellElemTokenMap();
+ sal_uInt16 nToken = rTokenMap.Get(nPrefix, rLocalName);
+ if (nToken == XML_TOK_TABLE_ROW_CELL_P)
+- return new ScXMLExternalRefCellTextContext(mrScImport, nPrefix, rLocalName, xAttrList, maCellString);
++ return new ScXMLExternalRefCellTextContext(mrScImport, nPrefix, rLocalName, xAttrList, *this);
+
+ return new SvXMLImportContext(GetImport(), nPrefix, rLocalName);
+ }
+@@ -402,14 +402,20 @@ void ScXMLExternalRefCellContext::EndElement()
+ }
+ }
+
++void ScXMLExternalRefCellContext::SetCellString(const OUString& rStr)
++{
++ maCellString = rStr;
++}
++
+ // ============================================================================
+
+ ScXMLExternalRefCellTextContext::ScXMLExternalRefCellTextContext(
+ ScXMLImport& rImport, USHORT nPrefix, const OUString& rLName,
+- const Reference<XAttributeList>& /*xAttrList*/, OUString& rCellString ) :
++ const Reference<XAttributeList>& /*xAttrList*/,
++ ScXMLExternalRefCellContext& rParent ) :
+ SvXMLImportContext( rImport, nPrefix, rLName ),
+ mrScImport(rImport),
+- mrCellString(rCellString)
++ mrParent(rParent)
+ {
+ }
+
+@@ -425,9 +431,10 @@ SvXMLImportContext* ScXMLExternalRefCellTextContext::CreateChildContext(
+
+ void ScXMLExternalRefCellTextContext::Characters(const OUString& rChar)
+ {
+- mrCellString = rChar;
++ maCellStrBuf.append(rChar);
+ }
+
+ void ScXMLExternalRefCellTextContext::EndElement()
+ {
++ mrParent.SetCellString(maCellStrBuf.makeStringAndClear());
+ }
+diff --git sc/source/filter/xml/xmlexternaltabi.hxx sc/source/filter/xml/xmlexternaltabi.hxx
+index 6ece1ad..100cf9d 100644
+--- sc/source/filter/xml/xmlexternaltabi.hxx
++++ sc/source/filter/xml/xmlexternaltabi.hxx
+@@ -32,6 +32,7 @@
+ #define SC_XMLEXTERNALTABI_HXX
+
+ #include <xmloff/xmlictxt.hxx>
++#include "rtl/ustrbuf.hxx"
+
+ class ScXMLImport;
+ struct ScXMLExternalTabData;
+@@ -132,6 +133,8 @@ public:
+
+ virtual void EndElement();
+
++ void SetCellString(const ::rtl::OUString& rStr);
++
+ private:
+ ScXMLImport& mrScImport;
+ ScXMLExternalTabData& mrExternalRefInfo;
+@@ -153,7 +156,7 @@ public:
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+- ::rtl::OUString& rCellString );
++ ScXMLExternalRefCellContext& rParent );
+
+ virtual ~ScXMLExternalRefCellTextContext();
+
+@@ -168,7 +171,9 @@ public:
+
+ private:
+ ScXMLImport& mrScImport;
+- ::rtl::OUString& mrCellString;
++ ScXMLExternalRefCellContext& mrParent;
++
++ ::rtl::OUStringBuffer maCellStrBuf;
+ };
+
+ #endif
+diff --git sc/source/filter/xml/xmltabi.cxx sc/source/filter/xml/xmltabi.cxx
+index 2c39eab..c023da1 100644
+--- sc/source/filter/xml/xmltabi.cxx
++++ sc/source/filter/xml/xmltabi.cxx
+@@ -101,21 +101,27 @@ static bool lcl_isExternalRefCache(const rtl::OUString& rName, rtl::OUString& rU
+ const sal_Unicode c = p[i];
+ if (i <= 7)
+ {
++ // Checking the prefix 'file://'.
+ if (c != aPrefix[i])
+ return false;
+ }
+- else if (c == '#')
++ else if (bInUrl)
+ {
+- if (cPrev != '\'')
+- return false;
++ // parsing file URL
++ if (c == '#')
++ {
++ if (cPrev != '\'')
++ return false;
+
+- rUrl = aUrlBuf.makeStringAndClear();
+- rUrl = rUrl.copy(0, rUrl.getLength()-1); // remove the trailing single-quote.
+- bInUrl = false;
++ rUrl = aUrlBuf.makeStringAndClear();
++ rUrl = rUrl.copy(0, rUrl.getLength()-1); // remove the trailing single-quote.
++ bInUrl = false;
++ }
++ else
++ aUrlBuf.append(c);
+ }
+- else if (bInUrl)
+- aUrlBuf.append(c);
+ else
++ // parsing sheet name.
+ aTabNameBuf.append(c);
+
+ cPrev = c;
+@@ -209,6 +215,7 @@ ScXMLTableContext::ScXMLTableContext( ScXMLImport& rImport,
+ ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
+ pExternalRefInfo->mnFileId = pRefMgr->getExternalFileId(aExtUrl);
+ pExternalRefInfo->mpCacheTable = pRefMgr->getCacheTable(pExternalRefInfo->mnFileId, aExtTabName, true);
++ pExternalRefInfo->mpCacheTable->setWholeTableCached();
+ }
+ }
+ else
+diff --git sc/source/ui/docshell/externalrefmgr.cxx sc/source/ui/docshell/externalrefmgr.cxx
+index da04ce2..36800a9 100644
+--- sc/source/ui/docshell/externalrefmgr.cxx
++++ sc/source/ui/docshell/externalrefmgr.cxx
+@@ -68,6 +68,8 @@
+ #include <memory>
+ #include <algorithm>
+
++#include <boost/scoped_ptr.hpp>
++
+ using ::std::auto_ptr;
+ using ::com::sun::star::uno::Any;
+ using ::rtl::OUString;
+@@ -138,6 +140,69 @@ private:
+ ScExternalRefManager::LinkUpdateType meType;
+ };
+
++struct UpdateFormulaCell : public unary_function<ScFormulaCell*, void>
++{
++ void operator() (ScFormulaCell* pCell) const
++ {
++ // Check to make sure the cell really contains ocExternalRef.
++ // External names, external cell and range references all have a
++ // ocExternalRef token.
++ const ScTokenArray* pCode = pCell->GetCode();
++ if (!pCode->HasOpCode( ocExternalRef))
++ return;
++
++ ScTokenArray* pArray = pCell->GetCode();
++ if (pArray)
++ // Clear the error code, or a cell with error won't get re-compiled.
... etc. - the rest is truncated
More information about the ooo-build-commit
mailing list