[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