[Libreoffice-commits] core.git: 13 commits - sc/inc sc/qa sc/source

Kohei Yoshida kohei.yoshida at collabora.com
Mon Nov 4 19:59:29 CET 2013


 dev/null                                          |binary
 sc/inc/column.hxx                                 |    3 
 sc/inc/document.hxx                               |   10 -
 sc/inc/rangenam.hxx                               |    5 
 sc/inc/table.hxx                                  |    1 
 sc/inc/tokenuno.hxx                               |    2 
 sc/qa/unit/data/xls/data-table/mortgage.xls       |binary
 sc/qa/unit/data/xlsx/data-table/multi-table.xlsx  |binary
 sc/qa/unit/data/xlsx/data-table/one-variable.xlsx |binary
 sc/qa/unit/subsequent_filters-test.cxx            |   95 ++++++++++++++++
 sc/qa/unit/ucalc.hxx                              |    2 
 sc/qa/unit/ucalc_formula.cxx                      |   66 +++++++++++
 sc/source/core/data/column.cxx                    |   14 +-
 sc/source/core/data/column3.cxx                   |   23 ----
 sc/source/core/data/documen2.cxx                  |    8 -
 sc/source/core/data/documentimport.cxx            |   57 ++++++----
 sc/source/core/data/table2.cxx                    |    8 -
 sc/source/core/tool/rangenam.cxx                  |   20 +++
 sc/source/filter/inc/sheetdatabuffer.hxx          |    5 
 sc/source/filter/inc/workbookhelper.hxx           |    7 +
 sc/source/filter/inc/worksheethelper.hxx          |   20 +--
 sc/source/filter/oox/defnamesbuffer.cxx           |    2 
 sc/source/filter/oox/formulabuffer.cxx            |   38 +-----
 sc/source/filter/oox/numberformatsbuffer.cxx      |    2 
 sc/source/filter/oox/sheetdatabuffer.cxx          |  124 +++++++++++-----------
 sc/source/filter/oox/workbookhelper.cxx           |   50 ++++++--
 sc/source/filter/oox/worksheethelper.cxx          |   31 ++---
 sc/source/filter/orcus/interface.cxx              |    2 
 sc/source/filter/xml/xmlcelli.cxx                 |    3 
 sc/source/ui/unoobj/tokenuno.cxx                  |    2 
 30 files changed, 378 insertions(+), 222 deletions(-)

New commits:
commit 2f75a279ccff70aa276e16e8c709c8b4b2924103
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Mon Nov 4 13:57:34 2013 -0500

    Two new test cases for importing data tables from XLSX.
    
    Change-Id: I87da806612ae50fe1d64b851c5180ff1792752cb

diff --git a/sc/qa/unit/data/xlsx/data-table/multi-table.xlsx b/sc/qa/unit/data/xlsx/data-table/multi-table.xlsx
new file mode 100644
index 0000000..c2bf488
Binary files /dev/null and b/sc/qa/unit/data/xlsx/data-table/multi-table.xlsx differ
diff --git a/sc/qa/unit/data/xlsx/data-table/one-variable.xlsx b/sc/qa/unit/data/xlsx/data-table/one-variable.xlsx
new file mode 100644
index 0000000..7ff098b2
Binary files /dev/null and b/sc/qa/unit/data/xlsx/data-table/one-variable.xlsx differ
diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx
index 3eae17d..4f7d702 100644
--- a/sc/qa/unit/subsequent_filters-test.cxx
+++ b/sc/qa/unit/subsequent_filters-test.cxx
@@ -109,6 +109,8 @@ public:
     void testRepeatedColumnsODS();
     void testDataValidityODS();
     void testDataTableMortgageXLS();
+    void testDataTableOneVarXLSX();
+    void testDataTableMultiTableXLSX();
 
     void testDataBarODS();
     void testDataBarXLSX();
@@ -174,6 +176,8 @@ public:
     CPPUNIT_TEST(testRepeatedColumnsODS);
     CPPUNIT_TEST(testDataValidityODS);
     CPPUNIT_TEST(testDataTableMortgageXLS);
+    CPPUNIT_TEST(testDataTableOneVarXLSX);
+    CPPUNIT_TEST(testDataTableMultiTableXLSX);
     CPPUNIT_TEST(testBrokenQuotesCSV);
     CPPUNIT_TEST(testCellValueXLSX);
     CPPUNIT_TEST(testControlImport);
@@ -1077,6 +1081,8 @@ void ScFiltersTest::testDataValidityODS()
 void ScFiltersTest::testDataTableMortgageXLS()
 {
     ScDocShellRef xDocSh = loadDoc("data-table/mortgage.", XLS);
+    CPPUNIT_ASSERT_MESSAGE("Failed to load the document.", xDocSh.Is());
+
     ScFormulaOptions aOptions;
     aOptions.SetFormulaSepArg(",");
     aOptions.SetFormulaSepArrayCol(",");
@@ -1125,6 +1131,87 @@ void ScFiltersTest::testDataTableMortgageXLS()
     xDocSh->DoClose();
 }
 
+void ScFiltersTest::testDataTableOneVarXLSX()
+{
+    ScDocShellRef xDocSh = loadDoc("data-table/one-variable.", XLSX);
+    CPPUNIT_ASSERT_MESSAGE("Failed to load the document.", xDocSh.Is());
+
+    ScFormulaOptions aOptions;
+    aOptions.SetFormulaSepArg(",");
+    aOptions.SetFormulaSepArrayCol(",");
+    aOptions.SetFormulaSepArrayRow(";");
+    xDocSh->SetFormulaOptions(aOptions);
+
+    ScDocument* pDoc = xDocSh->GetDocument();
+
+    // Right now, we have a bug that prevents Calc from re-calculating these
+    // cells automatically upon file load. We can remove this call if/when we
+    // fix the aforementioned bug.
+    pDoc->CalcAll();
+
+    // B5:B11 should have multiple operations formula cells.  Just check the
+    // top and bottom cells.
+
+    if (!checkFormula(*pDoc, ScAddress(1,4,0), "MULTIPLE.OPERATIONS(B$4,$A$2,$A5)"))
+        CPPUNIT_FAIL("Wrong formula!");
+
+    CPPUNIT_ASSERT_EQUAL(2.0, pDoc->GetValue(ScAddress(1,4,0)));
+
+    if (!checkFormula(*pDoc, ScAddress(1,10,0), "MULTIPLE.OPERATIONS(B$4,$A$2,$A11)"))
+        CPPUNIT_FAIL("Wrong formula!");
+
+    CPPUNIT_ASSERT_EQUAL(14.0, pDoc->GetValue(ScAddress(1,10,0)));
+
+    // Likewise, E5:I5 should have multiple operations formula cells.  Just
+    // check the left- and right-most cells.
+
+    if (!checkFormula(*pDoc, ScAddress(4,4,0), "MULTIPLE.OPERATIONS($D5,$B$2,E$4)"))
+        CPPUNIT_FAIL("Wrong formula!");
+
+    CPPUNIT_ASSERT_EQUAL(10.0, pDoc->GetValue(ScAddress(4,4,0)));
+
+    if (!checkFormula(*pDoc, ScAddress(8,4,0), "MULTIPLE.OPERATIONS($D5,$B$2,I$4)"))
+        CPPUNIT_FAIL("Wrong formula!");
+
+    CPPUNIT_ASSERT_EQUAL(50.0, pDoc->GetValue(ScAddress(8,4,0)));
+
+    xDocSh->DoClose();
+}
+
+void ScFiltersTest::testDataTableMultiTableXLSX()
+{
+    ScDocShellRef xDocSh = loadDoc("data-table/multi-table.", XLSX);
+    CPPUNIT_ASSERT_MESSAGE("Failed to load the document.", xDocSh.Is());
+
+    ScFormulaOptions aOptions;
+    aOptions.SetFormulaSepArg(",");
+    aOptions.SetFormulaSepArrayCol(",");
+    aOptions.SetFormulaSepArrayRow(";");
+    xDocSh->SetFormulaOptions(aOptions);
+
+    ScDocument* pDoc = xDocSh->GetDocument();
+
+    // Right now, we have a bug that prevents Calc from re-calculating these
+    // cells automatically upon file load. We can remove this call if/when we
+    // fix the aforementioned bug.
+    pDoc->CalcAll();
+
+    // B4:M15 should have multiple operations formula cells.  We'll just check
+    // the top-left and bottom-right ones.
+
+    if (!checkFormula(*pDoc, ScAddress(1,3,0), "MULTIPLE.OPERATIONS($A$3,$E$1,$A4,$D$1,B$3)"))
+        CPPUNIT_FAIL("Wrong formula!");
+
+    CPPUNIT_ASSERT_EQUAL(1.0, pDoc->GetValue(ScAddress(1,3,0)));
+
+    if (!checkFormula(*pDoc, ScAddress(12,14,0), "MULTIPLE.OPERATIONS($A$3,$E$1,$A15,$D$1,M$3)"))
+        CPPUNIT_FAIL("Wrong formula!");
+
+    CPPUNIT_ASSERT_EQUAL(144.0, pDoc->GetValue(ScAddress(12,14,0)));
+
+    xDocSh->DoClose();
+}
+
 void ScFiltersTest::testBrokenQuotesCSV()
 {
     const OUString aFileNameBase("fdo48621_broken_quotes.");
commit e77379bb2c0a6b3869b544b30d8f42137f82cf8b
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Mon Nov 4 13:27:44 2013 -0500

    Create data-table directory and move the test file into it.
    
    Change-Id: I1007525a7d2e1135f0388975f9cb7b0cef9b3142

diff --git a/sc/qa/unit/data/xls/data-table-mortgage.xls b/sc/qa/unit/data/xls/data-table/mortgage.xls
similarity index 100%
rename from sc/qa/unit/data/xls/data-table-mortgage.xls
rename to sc/qa/unit/data/xls/data-table/mortgage.xls
diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx
index a9956e1..3eae17d 100644
--- a/sc/qa/unit/subsequent_filters-test.cxx
+++ b/sc/qa/unit/subsequent_filters-test.cxx
@@ -108,7 +108,7 @@ public:
     void testMergedCellsODS();
     void testRepeatedColumnsODS();
     void testDataValidityODS();
-    void testDataTableXLS();
+    void testDataTableMortgageXLS();
 
     void testDataBarODS();
     void testDataBarXLSX();
@@ -173,7 +173,7 @@ public:
     CPPUNIT_TEST(testMergedCellsODS);
     CPPUNIT_TEST(testRepeatedColumnsODS);
     CPPUNIT_TEST(testDataValidityODS);
-    CPPUNIT_TEST(testDataTableXLS);
+    CPPUNIT_TEST(testDataTableMortgageXLS);
     CPPUNIT_TEST(testBrokenQuotesCSV);
     CPPUNIT_TEST(testCellValueXLSX);
     CPPUNIT_TEST(testControlImport);
@@ -1074,9 +1074,9 @@ void ScFiltersTest::testDataValidityODS()
     xDocSh->DoClose();
 }
 
-void ScFiltersTest::testDataTableXLS()
+void ScFiltersTest::testDataTableMortgageXLS()
 {
-    ScDocShellRef xDocSh = loadDoc("data-table-mortgage.", XLS);
+    ScDocShellRef xDocSh = loadDoc("data-table/mortgage.", XLS);
     ScFormulaOptions aOptions;
     aOptions.SetFormulaSepArg(",");
     aOptions.SetFormulaSepArrayCol(",");
commit 370399c8304eb30254f1fa3b5fa773ddefd9b0c0
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Mon Nov 4 11:50:18 2013 -0500

    Import data tables from xlsx via ScDocumentImport.
    
    Change-Id: Id3d526720f99b7557476915beab35b429ec97c1d

diff --git a/sc/source/filter/inc/sheetdatabuffer.hxx b/sc/source/filter/inc/sheetdatabuffer.hxx
index 192f359..ceb3a80 100644
--- a/sc/source/filter/inc/sheetdatabuffer.hxx
+++ b/sc/source/filter/inc/sheetdatabuffer.hxx
@@ -176,9 +176,8 @@ private:
                             const ::com::sun::star::table::CellRangeAddress& rRange,
                             const ApiTokenSequence& rTokens ) const;
     /** Inserts the passed table operation into the sheet. */
-    void                finalizeTableOperation(
-                            const ::com::sun::star::table::CellRangeAddress& rRange,
-                            const DataTableModel& rModel ) const;
+    void finalizeTableOperation(
+        const ::com::sun::star::table::CellRangeAddress& rRange, const DataTableModel& rModel );
 
     /** Writes all cell formatting attributes to the passed cell range list. (depreciates writeXfIdRangeProperties) */
     void                applyCellMerging( const ::com::sun::star::table::CellRangeAddress& rRange );
diff --git a/sc/source/filter/oox/sheetdatabuffer.cxx b/sc/source/filter/oox/sheetdatabuffer.cxx
index f55d365..2b340c5 100644
--- a/sc/source/filter/oox/sheetdatabuffer.cxx
+++ b/sc/source/filter/oox/sheetdatabuffer.cxx
@@ -51,6 +51,8 @@
 #include "scitems.hxx"
 #include "formulacell.hxx"
 #include "docpool.hxx"
+#include "paramisc.hxx"
+#include "documentimport.hxx"
 
 namespace oox {
 namespace xls {
@@ -565,71 +567,79 @@ void SheetDataBuffer::finalizeArrayFormula( const CellRangeAddress& rRange, cons
         xTokens->setArrayTokens( rTokens );
 }
 
-void SheetDataBuffer::finalizeTableOperation( const CellRangeAddress& rRange, const DataTableModel& rModel ) const
+void SheetDataBuffer::finalizeTableOperation( const CellRangeAddress& rRange, const DataTableModel& rModel )
 {
+    if (rModel.mbRef1Deleted)
+        return;
+
+    if (rModel.maRef1.isEmpty())
+        return;
+
+    if (rRange.StartColumn <= 0 || rRange.StartRow <= 0)
+        return;
+
     sal_Int16 nSheet = getSheetIndex();
-    bool bOk = false;
-    if( !rModel.mbRef1Deleted && !rModel.maRef1.isEmpty() && (rRange.StartColumn > 0) && (rRange.StartRow > 0) )
+
+    CellAddress aRef1;
+    if (!getAddressConverter().convertToCellAddress(aRef1, rModel.maRef1, nSheet, true))
+        return;
+
+    ScDocumentImport& rDoc = getDocImport();
+    ScTabOpParam aParam;
+
+    ScRange aScRange;
+    ScUnoConversion::FillScRange(aScRange, rRange);
+
+    if (rModel.mb2dTable)
     {
-        CellRangeAddress aOpRange = rRange;
-        CellAddress aRef1;
-        if( getAddressConverter().convertToCellAddress( aRef1, rModel.maRef1, nSheet, true ) ) try
-        {
-            if( rModel.mb2dTable )
-            {
-                CellAddress aRef2;
-                if( !rModel.mbRef2Deleted && getAddressConverter().convertToCellAddress( aRef2, rModel.maRef2, nSheet, true ) )
-                {
-                    // API call expects input values inside operation range
-                    --aOpRange.StartColumn;
-                    --aOpRange.StartRow;
-                    // formula range is top-left cell of operation range
-                    CellRangeAddress aFormulaRange( nSheet, aOpRange.StartColumn, aOpRange.StartRow, aOpRange.StartColumn, aOpRange.StartRow );
-                    // set multiple operation
-                    Reference< XMultipleOperation > xMultOp( getCellRange( aOpRange ), UNO_QUERY_THROW );
-                    xMultOp->setTableOperation( aFormulaRange, TableOperationMode_BOTH, aRef2, aRef1 );
-                    bOk = true;
-                }
-            }
-            else if( rModel.mbRowTable )
-            {
-                // formula range is column to the left of operation range
-                CellRangeAddress aFormulaRange( nSheet, aOpRange.StartColumn - 1, aOpRange.StartRow, aOpRange.StartColumn - 1, aOpRange.EndRow );
-                // API call expects input values (top row) inside operation range
-                --aOpRange.StartRow;
-                // set multiple operation
-                Reference< XMultipleOperation > xMultOp( getCellRange( aOpRange ), UNO_QUERY_THROW );
-                xMultOp->setTableOperation( aFormulaRange, TableOperationMode_ROW, aRef1, aRef1 );
-                bOk = true;
-            }
-            else
-            {
-                // formula range is row above operation range
-                CellRangeAddress aFormulaRange( nSheet, aOpRange.StartColumn, aOpRange.StartRow - 1, aOpRange.EndColumn, aOpRange.StartRow - 1 );
-                // API call expects input values (left column) inside operation range
-                --aOpRange.StartColumn;
-                // set multiple operation
-                Reference< XMultipleOperation > xMultOp( getCellRange( aOpRange ), UNO_QUERY_THROW );
-                xMultOp->setTableOperation( aFormulaRange, TableOperationMode_COLUMN, aRef1, aRef1 );
-                bOk = true;
-            }
-        }
-        catch( Exception& )
-        {
-        }
+        // Two-variable data table.
+        if (rModel.mbRef2Deleted)
+            return;
+
+        if (rModel.maRef2.isEmpty())
+            return;
+
+        CellAddress aRef2;
+        if (!getAddressConverter().convertToCellAddress(aRef2, rModel.maRef2, nSheet, true))
+            return;
+
+        aParam.meMode = ScTabOpParam::Both;
+
+        aParam.aRefFormulaCell.Set(rRange.StartColumn-1, rRange.StartRow-1, nSheet, false, false, false);
+        aParam.aRefFormulaEnd = aParam.aRefFormulaCell;
+
+        aScRange.aStart.IncRow(-1);
+        aScRange.aStart.IncCol(-1);
+
+        // Ref1 is row input cell and Ref2 is column input cell.
+        aParam.aRefRowCell.Set(aRef1.Column, aRef1.Row, aRef1.Sheet, false, false, false);
+        aParam.aRefColCell.Set(aRef2.Column, aRef2.Row, aRef2.Sheet, false, false, false);
+        rDoc.setTableOpCells(aScRange, aParam);
+
+        return;
     }
 
-    // on error: fill cell range with #REF! error codes
-    if( !bOk ) try
+    // One-variable data table.
+
+    if (rModel.mbRowTable)
     {
-        Reference< XCellRangeData > xCellRangeData( getCellRange( rRange ), UNO_QUERY_THROW );
-        size_t nWidth = static_cast< size_t >( rRange.EndColumn - rRange.StartColumn + 1 );
-        size_t nHeight = static_cast< size_t >( rRange.EndRow - rRange.StartRow + 1 );
-        Matrix< Any > aErrorCells( nWidth, nHeight, Any( getFormulaParser().convertErrorToFormula( BIFF_ERR_REF ) ) );
-        xCellRangeData->setDataArray( ContainerHelper::matrixToSequenceSequence( aErrorCells ) );
+        // One-variable row input cell (horizontal).
+        aParam.meMode = ScTabOpParam::Row;
+        aParam.aRefRowCell.Set(aRef1.Column, aRef1.Row, aRef1.Sheet, false, false, false);
+        aParam.aRefFormulaCell.Set(rRange.StartColumn-1, rRange.StartRow, nSheet, false, true, false);
+        aParam.aRefFormulaEnd = aParam.aRefFormulaCell;
+        aScRange.aStart.IncRow(-1);
+        rDoc.setTableOpCells(aScRange, aParam);
     }
-    catch( Exception& )
+    else
     {
+        // One-variable column input cell (vertical).
+        aParam.meMode = ScTabOpParam::Column;
+        aParam.aRefColCell.Set(aRef1.Column, aRef1.Row, aRef1.Sheet, false, false, false);
+        aParam.aRefFormulaCell.Set(rRange.StartColumn, rRange.StartRow-1, nSheet, true, false, false);
+        aParam.aRefFormulaEnd = aParam.aRefFormulaCell;
+        aScRange.aStart.IncCol(-1);
+        rDoc.setTableOpCells(aScRange, aParam);
     }
 }
 
commit 96860b65d4bb95603549f72b1e82c6ee49458ba8
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Nov 1 21:14:35 2013 -0400

    Renamed test file.
    
    Change-Id: I912778f2eedb162f2a04c0a7bc8a5220ea0fca2c

diff --git a/sc/qa/unit/data/xls/data-table.xls b/sc/qa/unit/data/xls/data-table-mortgage.xls
similarity index 100%
rename from sc/qa/unit/data/xls/data-table.xls
rename to sc/qa/unit/data/xls/data-table-mortgage.xls
diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx
index 08b57eb..a9956e1 100644
--- a/sc/qa/unit/subsequent_filters-test.cxx
+++ b/sc/qa/unit/subsequent_filters-test.cxx
@@ -1076,7 +1076,7 @@ void ScFiltersTest::testDataValidityODS()
 
 void ScFiltersTest::testDataTableXLS()
 {
-    ScDocShellRef xDocSh = loadDoc("data-table.", XLS);
+    ScDocShellRef xDocSh = loadDoc("data-table-mortgage.", XLS);
     ScFormulaOptions aOptions;
     aOptions.SetFormulaSepArg(",");
     aOptions.SetFormulaSepArrayCol(",");
commit 58b8d6d453a402f9e4068f055572da3c766af081
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Nov 1 20:23:18 2013 -0400

    Use position hints for broadcasters when activating formula cells.
    
    No reason not to do this since we are bulk-registering formula cells.
    
    Change-Id: Ie0356c62a3c4698f5560272cb0c104f84cacde56

diff --git a/sc/source/core/data/documentimport.cxx b/sc/source/core/data/documentimport.cxx
index f52eb38..3b33f46 100644
--- a/sc/source/core/data/documentimport.cxx
+++ b/sc/source/core/data/documentimport.cxx
@@ -19,16 +19,22 @@
 #include "stringutil.hxx"
 #include "compiler.hxx"
 #include "paramisc.hxx"
+#include "listenercontext.hxx"
 
 #include "svl/sharedstringpool.hxx"
 
 struct ScDocumentImportImpl
 {
     ScDocument& mrDoc;
+    sc::StartListeningContext maListenCxt;
     sc::ColumnBlockPositionSet maBlockPosSet;
     sal_uInt16 mnDefaultScriptNumeric;
 
-    ScDocumentImportImpl(ScDocument& rDoc) : mrDoc(rDoc), maBlockPosSet(rDoc), mnDefaultScriptNumeric(SC_SCRIPTTYPE_UNKNOWN) {}
+    ScDocumentImportImpl(ScDocument& rDoc) :
+        mrDoc(rDoc),
+        maListenCxt(rDoc),
+        maBlockPosSet(rDoc),
+        mnDefaultScriptNumeric(SC_SCRIPTTYPE_UNKNOWN) {}
 };
 
 ScDocumentImport::ScDocumentImport(ScDocument& rDoc) : mpImpl(new ScDocumentImportImpl(rDoc)) {}
@@ -398,13 +404,15 @@ namespace {
 class CellStoreInitializer
 {
     ScDocument& mrDoc;
+    sc::StartListeningContext& mrListenCxt;
     sc::CellTextAttrStoreType maAttrs;
     sc::CellTextAttrStoreType::iterator miPos;
     sal_uInt16 mnScriptNumeric;
 
 public:
-    CellStoreInitializer(ScDocument& rDoc, sal_uInt16 nScriptNumeric) :
+    CellStoreInitializer(ScDocument& rDoc, sc::StartListeningContext& rCxt, sal_uInt16 nScriptNumeric) :
         mrDoc(rDoc),
+        mrListenCxt(rCxt),
         maAttrs(MAXROWCOUNT),
         miPos(maAttrs.begin()),
         mnScriptNumeric(nScriptNumeric) {}
@@ -429,7 +437,7 @@ public:
             for (; it != itEnd; ++it)
             {
                 ScFormulaCell& rFC = **it;
-                rFC.StartListeningTo(&mrDoc);
+                rFC.StartListeningTo(mrListenCxt);
             }
         }
     }
@@ -444,7 +452,8 @@ public:
 
 void ScDocumentImport::finalize()
 {
-    // Populate the text width and script type arrays in all columns.
+    // Populate the text width and script type arrays in all columns. Also
+    // activate all formula cells.
     ScDocument::TableContainer::iterator itTab = mpImpl->mrDoc.maTabs.begin(), itTabEnd = mpImpl->mrDoc.maTabs.end();
     for (; itTab != itTabEnd; ++itTab)
     {
@@ -461,7 +470,7 @@ void ScDocumentImport::finalize()
 
 void ScDocumentImport::initColumn(ScColumn& rCol)
 {
-    CellStoreInitializer aFunc(mpImpl->mrDoc, mpImpl->mnDefaultScriptNumeric);
+    CellStoreInitializer aFunc(mpImpl->mrDoc, mpImpl->maListenCxt, mpImpl->mnDefaultScriptNumeric);
     std::for_each(rCol.maCells.begin(), rCol.maCells.end(), aFunc);
     aFunc.swap(rCol.maCellTextAttrs);
     rCol.RegroupFormulaCells();
commit 8c6dd2cbcdf72b249051321dd7f7d3375e52f7b3
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Nov 1 20:14:12 2013 -0400

    No point using the pimpl pattern here.
    
    The whole class is already hidden in the source file.
    
    Change-Id: Ib6157ae275217a95586735f74beee1700041a679

diff --git a/sc/source/core/data/documentimport.cxx b/sc/source/core/data/documentimport.cxx
index c2b951a..f52eb38 100644
--- a/sc/source/core/data/documentimport.cxx
+++ b/sc/source/core/data/documentimport.cxx
@@ -397,23 +397,17 @@ namespace {
 
 class CellStoreInitializer
 {
-    struct Impl
-    {
-        sc::CellTextAttrStoreType maAttrs;
-        sc::CellTextAttrStoreType::iterator miPos;
-        sal_uInt16 mnScriptNumeric;
-
-        Impl(const sal_uInt32 nMaxRowCount, const sal_uInt16 nScriptNumeric)
-            : maAttrs(nMaxRowCount), miPos(maAttrs.begin()), mnScriptNumeric(nScriptNumeric)
-        {}
-    };
-
     ScDocument& mrDoc;
-    boost::shared_ptr<Impl> mpImpl;
+    sc::CellTextAttrStoreType maAttrs;
+    sc::CellTextAttrStoreType::iterator miPos;
+    sal_uInt16 mnScriptNumeric;
 
 public:
     CellStoreInitializer(ScDocument& rDoc, sal_uInt16 nScriptNumeric) :
-        mrDoc(rDoc), mpImpl(new Impl(MAXROWCOUNT, nScriptNumeric)) {}
+        mrDoc(rDoc),
+        maAttrs(MAXROWCOUNT),
+        miPos(maAttrs.begin()),
+        mnScriptNumeric(nScriptNumeric) {}
 
     void operator() (const sc::CellStoreType::value_type& node)
     {
@@ -423,9 +417,9 @@ public:
         // Fill with default values for non-empty cell segments.
         sc::CellTextAttr aDefault;
         if (node.type == sc::element_type_numeric)
-            aDefault.mnScriptType = mpImpl->mnScriptNumeric;
+            aDefault.mnScriptType = mnScriptNumeric;
         std::vector<sc::CellTextAttr> aDefaults(node.size, aDefault);
-        mpImpl->miPos = mpImpl->maAttrs.set(mpImpl->miPos, node.position, aDefaults.begin(), aDefaults.end());
+        miPos = maAttrs.set(miPos, node.position, aDefaults.begin(), aDefaults.end());
 
         if (node.type == sc::element_type_formula)
         {
@@ -442,7 +436,7 @@ public:
 
     void swap(sc::CellTextAttrStoreType& rAttrs)
     {
-        mpImpl->maAttrs.swap(rAttrs);
+        maAttrs.swap(rAttrs);
     }
 };
 
commit 20a359ea3669b0f33edf7b9d66e56343e0624a0d
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Nov 1 20:09:57 2013 -0400

    Have all formula cells start listening at once after the file load.
    
    Rather than doing it individually.
    
    Change-Id: I5ed55947b715bf6d7d61a1f8b751be7fdcf425fb

diff --git a/sc/source/core/data/documentimport.cxx b/sc/source/core/data/documentimport.cxx
index 323ccfb..c2b951a 100644
--- a/sc/source/core/data/documentimport.cxx
+++ b/sc/source/core/data/documentimport.cxx
@@ -395,7 +395,7 @@ void ScDocumentImport::setTableOpCells(const ScRange& rRange, const ScTabOpParam
 
 namespace {
 
-class CellTextAttrInitializer
+class CellStoreInitializer
 {
     struct Impl
     {
@@ -408,10 +408,12 @@ class CellTextAttrInitializer
         {}
     };
 
+    ScDocument& mrDoc;
     boost::shared_ptr<Impl> mpImpl;
 
 public:
-    CellTextAttrInitializer(sal_uInt16 nScriptNumeric) : mpImpl(new Impl(MAXROWCOUNT, nScriptNumeric)) {}
+    CellStoreInitializer(ScDocument& rDoc, sal_uInt16 nScriptNumeric) :
+        mrDoc(rDoc), mpImpl(new Impl(MAXROWCOUNT, nScriptNumeric)) {}
 
     void operator() (const sc::CellStoreType::value_type& node)
     {
@@ -424,6 +426,18 @@ public:
             aDefault.mnScriptType = mpImpl->mnScriptNumeric;
         std::vector<sc::CellTextAttr> aDefaults(node.size, aDefault);
         mpImpl->miPos = mpImpl->maAttrs.set(mpImpl->miPos, node.position, aDefaults.begin(), aDefaults.end());
+
+        if (node.type == sc::element_type_formula)
+        {
+            // Have all formula cells start listening to the document.
+            sc::formula_block::iterator it = sc::formula_block::begin(*node.data);
+            sc::formula_block::iterator itEnd = sc::formula_block::end(*node.data);
+            for (; it != itEnd; ++it)
+            {
+                ScFormulaCell& rFC = **it;
+                rFC.StartListeningTo(&mrDoc);
+            }
+        }
     }
 
     void swap(sc::CellTextAttrStoreType& rAttrs)
@@ -453,7 +467,7 @@ void ScDocumentImport::finalize()
 
 void ScDocumentImport::initColumn(ScColumn& rCol)
 {
-    CellTextAttrInitializer aFunc(mpImpl->mnDefaultScriptNumeric);
+    CellStoreInitializer aFunc(mpImpl->mrDoc, mpImpl->mnDefaultScriptNumeric);
     std::for_each(rCol.maCells.begin(), rCol.maCells.end(), aFunc);
     aFunc.swap(rCol.maCellTextAttrs);
     rCol.RegroupFormulaCells();
diff --git a/sc/source/filter/orcus/interface.cxx b/sc/source/filter/orcus/interface.cxx
index df2da17..1372d775 100644
--- a/sc/source/filter/orcus/interface.cxx
+++ b/sc/source/filter/orcus/interface.cxx
@@ -364,7 +364,6 @@ void ScOrcusSheet::set_shared_formula(
 
     // For now, orcus doesn't support setting cached result. Mark it for re-calculation.
     pCell->SetDirty(true);
-    pCell->StartListeningTo(&mrDoc.getDoc());
 }
 
 void ScOrcusSheet::set_shared_formula(
@@ -388,7 +387,6 @@ void ScOrcusSheet::set_shared_formula(os::row_t row, os::col_t col, size_t sinde
 
     // For now, orcus doesn't support setting cached result. Mark it for re-calculation.
     pCell->SetDirty(true);
-    pCell->StartListeningTo(&mrDoc.getDoc());
 }
 
 void ScOrcusSheet::set_array_formula(
diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx
index 31e5bea9..a3f3a0f0 100644
--- a/sc/source/filter/xml/xmlcelli.cxx
+++ b/sc/source/filter/xml/xmlcelli.cxx
@@ -1027,7 +1027,6 @@ void ScXMLTableRowCellContext::SetFormulaCell(ScFormulaCell* pFCell) const
             pFCell->SetHybridDouble(fValue);
             pFCell->ResetDirty();
         }
-        pFCell->StartListeningTo(rXMLImport.GetDocument());
     }
 }
 
@@ -1075,7 +1074,6 @@ void ScXMLTableRowCellContext::PutTextCell( const ScAddress& rCurrentPos,
                         SAL_WARN("sc", "matrix cell without matrix");
                 }
             }
-            pFCell->StartListeningTo(rXMLImport.GetDocument());
         }
     }
     else //regular text cells
@@ -1437,7 +1435,6 @@ void ScXMLTableRowCellContext::AddFormulaCell( const ScAddress& rCellPos )
                         nMatrixCols, nMatrixRows, pMat, new formula::FormulaDoubleToken(fValue));
                     pFCell->ResetDirty();
                 }
-                pFCell->StartListeningTo(rXMLImport.GetDocument());
             }
         }
         else
commit 488b1ea1b9e780930802f5e4eead37552d1c3f6c
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Nov 1 18:36:42 2013 -0400

    Fix multiple operations with formula cell with indirect dependency.
    
    Now the unit test passes.  Good.
    
    Change-Id: I23fa8355805c192f43db0199f3628f2bf457a645

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 0a03ad9..c08236b 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -492,7 +492,7 @@ public:
     bool HasBroadcaster() const;
 
     void Broadcast( SCROW nRow );
-    void BroadcastCells( const std::vector<SCROW>& rRows );
+    void BroadcastCells( const std::vector<SCROW>& rRows, sal_uLong nHint );
 
     // cell notes
     ScPostIt* GetCellNote( SCROW nRow );
diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx
index 3cb9ab9..9f824e5 100644
--- a/sc/qa/unit/ucalc_formula.cxx
+++ b/sc/qa/unit/ucalc_formula.cxx
@@ -1387,11 +1387,10 @@ void Test::testMultipleOperations()
     aParam.aRefFormulaCell.Set(2,0,0,false,false,false);
     aParam.aRefFormulaEnd = aParam.aRefFormulaCell;
     m_pDoc->InsertTableOp(aParam, 0, 2, 1, 4, aMark);
-#if 0 // TODO: Make this pass.
     CPPUNIT_ASSERT_EQUAL(30.0, m_pDoc->GetValue(1,2,0));
     CPPUNIT_ASSERT_EQUAL(40.0, m_pDoc->GetValue(1,3,0));
     CPPUNIT_ASSERT_EQUAL(50.0, m_pDoc->GetValue(1,4,0));
-#endif
+
     m_pDoc->DeleteTab(0);
 }
 
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 018f9e1..512ccc5 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -890,7 +890,7 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
         SwapCellTextAttrs(nRow1, nRow2);
         SwapCellNotes(nRow1, nRow2);
         CellStorageModified();
-        BroadcastCells(aRows);
+        BroadcastCells(aRows, SC_HINT_DATACHANGED);
         return;
     }
 
@@ -938,7 +938,7 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
         SwapCellTextAttrs(nRow1, nRow2);
         SwapCellNotes(nRow1, nRow2);
         CellStorageModified();
-        BroadcastCells(aRows);
+        BroadcastCells(aRows, SC_HINT_DATACHANGED);
         return;
     }
 
@@ -983,7 +983,7 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
         SwapCellTextAttrs(nRow1, nRow2);
         SwapCellNotes(nRow1, nRow2);
         CellStorageModified();
-        BroadcastCells(aRows);
+        BroadcastCells(aRows, SC_HINT_DATACHANGED);
         return;
     }
 
@@ -1117,7 +1117,7 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
     SwapCellTextAttrs(nRow1, nRow2);
     SwapCellNotes(nRow1, nRow2);
     CellStorageModified();
-    BroadcastCells(aRows);
+    BroadcastCells(aRows, SC_HINT_DATACHANGED);
 }
 
 namespace {
@@ -2760,7 +2760,7 @@ public:
     {
         std::vector<SCROW> aRows;
         maValueRanges.getRows(aRows);
-        mrColumn.BroadcastCells(aRows);
+        mrColumn.BroadcastCells(aRows, SC_HINT_DATACHANGED);
     }
 };
 
@@ -2792,7 +2792,7 @@ public:
     {
         std::vector<SCROW> aRows;
         maValueRanges.getRows(aRows);
-        mrColumn.BroadcastCells(aRows);
+        mrColumn.BroadcastCells(aRows, SC_HINT_TABLEOPDIRTY);
     }
 };
 
@@ -3173,7 +3173,7 @@ void ScColumn::BroadcastRecalcOnRefMove()
     sc::AutoCalcSwitch aSwitch(*pDocument, false);
     RecalcOnRefMoveCollector aFunc;
     sc::ProcessFormula(maCells, aFunc);
-    BroadcastCells(aFunc.getDirtyRows());
+    BroadcastCells(aFunc.getDirtyRows(), SC_HINT_DATACHANGED);
 }
 
 void ScColumn::CalcAll()
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index ece9035..61f5326 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -74,13 +74,13 @@ void ScColumn::Broadcast( SCROW nRow )
     pDocument->Broadcast(aHint);
 }
 
-void ScColumn::BroadcastCells( const std::vector<SCROW>& rRows )
+void ScColumn::BroadcastCells( const std::vector<SCROW>& rRows, sal_uLong nHint )
 {
     if (rRows.empty())
         return;
 
     // Broadcast the changes.
-    ScHint aHint(SC_HINT_DATACHANGED, ScAddress(nCol, 0, nTab));
+    ScHint aHint(nHint, ScAddress(nCol, 0, nTab));
     std::vector<SCROW>::const_iterator itRow = rRows.begin(), itRowEnd = rRows.end();
     for (; itRow != itRowEnd; ++itRow)
     {
@@ -285,7 +285,7 @@ void ScColumn::DeleteRow( SCROW nStartRow, SCSIZE nSize )
     sc::SharedFormulaUtil::joinFormulaCellAbove(aPos);
 
     // Single cell broadcasts on deleted cells.
-    BroadcastCells(aDeleteRowsFunc.getNonEmptyRows());
+    BroadcastCells(aDeleteRowsFunc.getNonEmptyRows(), SC_HINT_DATACHANGED);
 
     // Shift the text attribute array too (before the broadcast).
     maCellTextAttrs.erase(nStartRow, nEndRow);
@@ -628,7 +628,7 @@ void ScColumn::DeleteArea(SCROW nStartRow, SCROW nEndRow, sal_uInt16 nDelFlag)
 
     // Broadcast on only cells that were deleted; no point broadcasting on
     // cells that were already empty before the deletion.
-    BroadcastCells(aDeletedRows);
+    BroadcastCells(aDeletedRows, SC_HINT_DATACHANGED);
 }
 
 bool ScColumn::InitBlockPosition( sc::ColumnBlockPosition& rBlockPos )
commit a364a87f73fc2730a987992a8d4242bc12f788d0
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Nov 1 15:16:40 2013 -0400

    Add test for multiple operations.  Part of it fails currently.
    
    Change-Id: I90e3bbaae41fac51711b8502fbeb6ee2ebf19082

diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx
index 5689435..b9c1d42 100644
--- a/sc/qa/unit/ucalc.hxx
+++ b/sc/qa/unit/ucalc.hxx
@@ -93,6 +93,7 @@ public:
     void testFormulaRefUpdateSheets();
     void testFormulaRefUpdateMove();
     void testFormulaRefUpdateNamedExpression();
+    void testMultipleOperations();
     void testFuncCOLUMN();
     void testFuncROW();
     void testFuncSUM();
@@ -300,6 +301,7 @@ public:
     CPPUNIT_TEST(testFormulaRefUpdateSheets);
     CPPUNIT_TEST(testFormulaRefUpdateMove);
     CPPUNIT_TEST(testFormulaRefUpdateNamedExpression);
+    CPPUNIT_TEST(testMultipleOperations);
     CPPUNIT_TEST(testFuncCOLUMN);
     CPPUNIT_TEST(testFuncROW);
     CPPUNIT_TEST(testFuncSUM);
diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx
index 598c65d..3cb9ab9 100644
--- a/sc/qa/unit/ucalc_formula.cxx
+++ b/sc/qa/unit/ucalc_formula.cxx
@@ -21,6 +21,7 @@
 #include "scmod.hxx"
 #include "docsh.hxx"
 #include "docfunc.hxx"
+#include "paramisc.hxx"
 
 #include "formula/vectortoken.hxx"
 
@@ -1308,6 +1309,7 @@ void Test::testFormulaRefUpdateNamedExpression()
     m_pDoc->SetValue(ScAddress(3,9,1), 10);
     CPPUNIT_ASSERT_EQUAL(33.0, m_pDoc->GetValue(ScAddress(2,7,1)));
 
+    // Delete the inserted sheet, which will shift the 'Formula' sheet to the left.
     m_pDoc->DeleteTab(0);
 
     aName = OUString();
@@ -1341,6 +1343,58 @@ void Test::testFormulaRefUpdateNamedExpression()
     m_pDoc->DeleteTab(0);
 }
 
+void Test::testMultipleOperations()
+{
+    m_pDoc->InsertTab(0, "MultiOp");
+
+    sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // turn auto calc on.
+
+    // Insert the reference formula at top row.
+    m_pDoc->SetValue(ScAddress(0,0,0), 1);
+    m_pDoc->SetString(ScAddress(1,0,0), "=A1*10");
+    CPPUNIT_ASSERT_EQUAL(10.0, m_pDoc->GetValue(ScAddress(1,0,0)));
+
+    // Insert variable inputs in A3:A5.
+    m_pDoc->SetValue(ScAddress(0,2,0), 2);
+    m_pDoc->SetValue(ScAddress(0,3,0), 3);
+    m_pDoc->SetValue(ScAddress(0,4,0), 4);
+
+    // Set multiple operations range.
+    ScTabOpParam aParam;
+    aParam.aRefFormulaCell = ScRefAddress(1,0,0,false,false,false);
+    aParam.aRefFormulaEnd = aParam.aRefFormulaCell;
+    aParam.aRefColCell = ScRefAddress(0,0,0,false,false,false);
+    ScMarkData aMark;
+    aMark.SetMarkArea(ScRange(0,2,0,1,4,0)); // Select A3:B5.
+    m_pDoc->InsertTableOp(aParam, 0, 2, 1, 4, aMark);
+    CPPUNIT_ASSERT_EQUAL(20.0, m_pDoc->GetValue(1,2,0));
+    CPPUNIT_ASSERT_EQUAL(30.0, m_pDoc->GetValue(1,3,0));
+    CPPUNIT_ASSERT_EQUAL(40.0, m_pDoc->GetValue(1,4,0));
+
+    // Clear A3:B5.
+    clearRange(m_pDoc, ScRange(0,2,0,1,4,0));
+
+    // This time, use indirect reference formula cell.
+    m_pDoc->SetString(ScAddress(2,0,0), "=B1"); // C1 simply references B1.
+    CPPUNIT_ASSERT_EQUAL(10.0, m_pDoc->GetValue(ScAddress(2,0,0)));
+
+    // Insert variable inputs in A3:A5.
+    m_pDoc->SetValue(ScAddress(0,2,0), 3);
+    m_pDoc->SetValue(ScAddress(0,3,0), 4);
+    m_pDoc->SetValue(ScAddress(0,4,0), 5);
+
+    // Set multiple operations range again, but this time, we'll use C1 as the reference formula.
+    aParam.aRefFormulaCell.Set(2,0,0,false,false,false);
+    aParam.aRefFormulaEnd = aParam.aRefFormulaCell;
+    m_pDoc->InsertTableOp(aParam, 0, 2, 1, 4, aMark);
+#if 0 // TODO: Make this pass.
+    CPPUNIT_ASSERT_EQUAL(30.0, m_pDoc->GetValue(1,2,0));
+    CPPUNIT_ASSERT_EQUAL(40.0, m_pDoc->GetValue(1,3,0));
+    CPPUNIT_ASSERT_EQUAL(50.0, m_pDoc->GetValue(1,4,0));
+#endif
+    m_pDoc->DeleteTab(0);
+}
+
 void Test::testFuncCOLUMN()
 {
     m_pDoc->InsertTab(0, "Formula");
commit 13b69492716c506976a31a26fe0590aa06b3d1a3
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Nov 1 13:28:00 2013 -0400

    We need to update sheet positions of range names when modifying sheets.
    
    And add Dump() to ScRangeData for debugging convenience and re-enable
    previously failed test cases.
    
    Change-Id: I9d8f41a8be4c9c301254ef300c7b7f0c1ea7f393

diff --git a/sc/inc/rangenam.hxx b/sc/inc/rangenam.hxx
index 65fae47..6113709 100644
--- a/sc/inc/rangenam.hxx
+++ b/sc/inc/rangenam.hxx
@@ -24,6 +24,7 @@
 #include "address.hxx"
 #include "formula/grammar.hxx"
 #include "scdllapi.h"
+#include "calcmacros.hxx"
 
 #include <map>
 #include <vector>
@@ -151,6 +152,10 @@ public:
     SCCOL GetMaxCol() const;
 
     void            CompileUnresolvedXML();
+
+#if DEBUG_FORMULA_COMPILER
+    void Dump() const;
+#endif
 };
 
 inline bool ScRangeData::HasType( RangeType nType ) const
diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx
index 92eebc2..598c65d 100644
--- a/sc/qa/unit/ucalc_formula.cxx
+++ b/sc/qa/unit/ucalc_formula.cxx
@@ -1296,20 +1296,29 @@ void Test::testFormulaRefUpdateNamedExpression()
     m_pDoc->SetValue(ScAddress(3,9,0), 20);
     CPPUNIT_ASSERT_EQUAL(43.0, m_pDoc->GetValue(ScAddress(2,7,0)));
 
-#if 0
     // Insert a new sheet before the current.
     m_pDoc->InsertTab(0, "New");
     OUString aName;
     m_pDoc->GetName(1, aName);
     CPPUNIT_ASSERT_EQUAL(OUString("Formula"), aName);
+
+    pName = pGlobalNames->findByUpperName("MYRANGE");
+    CPPUNIT_ASSERT_MESSAGE("Failed to find named expression 'MyRange' in the global scope.", pName);
+
     m_pDoc->SetValue(ScAddress(3,9,1), 10);
     CPPUNIT_ASSERT_EQUAL(33.0, m_pDoc->GetValue(ScAddress(2,7,1)));
 
     m_pDoc->DeleteTab(0);
 
+    aName = OUString();
+    m_pDoc->GetName(0, aName);
+    CPPUNIT_ASSERT_EQUAL(OUString("Formula"), aName);
+
+    pName = pGlobalNames->findByUpperName("MYRANGE");
+    CPPUNIT_ASSERT_MESSAGE("Failed to find named expression 'MyRange' in the global scope.", pName);
+
     m_pDoc->SetValue(ScAddress(3,9,0), 11);
     CPPUNIT_ASSERT_EQUAL(34.0, m_pDoc->GetValue(ScAddress(2,7,0)));
-#endif
 
     // Clear all and start over.
     clearRange(m_pDoc, ScRange(0,0,0,100,100,0));
diff --git a/sc/source/core/tool/rangenam.cxx b/sc/source/core/tool/rangenam.cxx
index b963eab..4389a4b 100644
--- a/sc/source/core/tool/rangenam.cxx
+++ b/sc/source/core/tool/rangenam.cxx
@@ -196,6 +196,18 @@ void ScRangeData::CompileUnresolvedXML()
     }
 }
 
+#if DEBUG_FORMULA_COMPILER
+void ScRangeData::Dump() const
+{
+    cout << "-- ScRangeData" << endl;
+    cout << "  name: " << aName << endl;
+    cout << "  ref position: (col=" << aPos.Col() << ", row=" << aPos.Row() << ", sheet=" << aPos.Tab() << ")" << endl;
+
+    if (pCode)
+        pCode->Dump();
+}
+#endif
+
 void ScRangeData::GuessPosition()
 {
     // set a position that allows "absoluting" of all relative references
@@ -392,6 +404,9 @@ void ScRangeData::UpdateInsertTab( sc::RefUpdateInsertTabContext& rCxt, SCTAB nL
     sc::RefUpdateResult aRes = pCode->AdjustReferenceOnInsertedTab(rCxt, aPos);
     if (aRes.mbReferenceModified)
         rCxt.maUpdatedNames.setUpdatedName(nLocalTab, nIndex);
+
+    if (rCxt.mnInsertPos <= aPos.Tab())
+        aPos.IncTab(rCxt.mnSheets);
 }
 
 void ScRangeData::UpdateDeleteTab( sc::RefUpdateDeleteTabContext& rCxt, SCTAB nLocalTab )
@@ -399,6 +414,9 @@ void ScRangeData::UpdateDeleteTab( sc::RefUpdateDeleteTabContext& rCxt, SCTAB nL
     sc::RefUpdateResult aRes = pCode->AdjustReferenceOnDeletedTab(rCxt, aPos);
     if (aRes.mbReferenceModified)
         rCxt.maUpdatedNames.setUpdatedName(nLocalTab, nIndex);
+
+    if (rCxt.mnDeletePos <= aPos.Tab())
+        aPos.IncTab(-rCxt.mnSheets);
 }
 
 void ScRangeData::UpdateMoveTab( sc::RefUpdateMoveTabContext& rCxt, SCTAB nLocalTab )
@@ -406,6 +424,8 @@ void ScRangeData::UpdateMoveTab( sc::RefUpdateMoveTabContext& rCxt, SCTAB nLocal
     sc::RefUpdateResult aRes = pCode->AdjustReferenceOnMovedTab(rCxt, aPos);
     if (aRes.mbReferenceModified)
         rCxt.maUpdatedNames.setUpdatedName(nLocalTab, nIndex);
+
+    aPos.SetTab(rCxt.getNewTab(aPos.Tab()));
 }
 
 void ScRangeData::MakeValidName( OUString& rName )
commit 07b66cd3ac1a9f6c7b61a1d7da6e9d266e6de92d
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Thu Oct 31 17:53:02 2013 -0400

    Insert matrix formula vis ScDocumentImport, and more formula imorts.
    
    Now SetGroupFormulaCell() is no longer used.
    
    Change-Id: I10a387da04724794974eaf491a8efa4cda09d82a

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 3ee53d6..0a03ad9 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -284,7 +284,6 @@ public:
      */
     ScFormulaCell* SetFormulaCell( SCROW nRow, ScFormulaCell* pCell );
     ScFormulaCell* SetFormulaCell( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, ScFormulaCell* pCell );
-    bool SetGroupFormulaCell( SCROW nRow, ScFormulaCell* pCell );
 
     svl::SharedString GetSharedString( SCROW nRow ) const;
 
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index fb3a175..6929e9b 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -825,16 +825,6 @@ public:
      */
     SC_DLLPUBLIC ScFormulaCell* SetFormulaCell( const ScAddress& rPos, ScFormulaCell* pCell );
 
-    /**
-     * Set formula cell, and transfer its ownership to the document.  Unlike
-     * SetFormulaCell(), this call will <i>not</i> attempt to group the passed
-     * formula cell with the adjacent cells or cell groups.
-     *
-     * @return true if the cell is inserted, false otherwise. The caller
-     *         should delete the cell instance if the method returns false.
-     */
-    SC_DLLPUBLIC bool SetGroupFormulaCell( const ScAddress& rPos, ScFormulaCell* pCell );
-
     SC_DLLPUBLIC void InsertMatrixFormula(SCCOL nCol1, SCROW nRow1,
                                         SCCOL nCol2, SCROW nRow2,
                                         const ScMarkData& rMark,
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 126b0ae..8eb75be 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -339,7 +339,6 @@ public:
      *         is deleted automatically on failure to insert.
      */
     ScFormulaCell* SetFormulaCell( SCCOL nCol, SCROW nRow, ScFormulaCell* pCell );
-    bool SetGroupFormulaCell( SCCOL nCol, SCROW nRow, ScFormulaCell* pCell );
 
     svl::SharedString GetSharedString( SCCOL nCol, SCROW nRow ) const;
 
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 991039c..ece9035 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -1769,21 +1769,6 @@ ScFormulaCell* ScColumn::SetFormulaCell( sc::ColumnBlockPosition& rBlockPos, SCR
     return pCell;
 }
 
-bool ScColumn::SetGroupFormulaCell( SCROW nRow, ScFormulaCell* pCell )
-{
-    sc::CellStoreType::iterator it = GetPositionToInsert(nRow);
-    sal_uInt32 nCellFormat = GetNumberFormat(nRow);
-    if( (nCellFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0)
-        pCell->SetNeedNumberFormat(true);
-    it = maCells.set(it, nRow, pCell);
-    maCellTextAttrs.set(nRow, sc::CellTextAttr());
-
-    CellStorageModified();
-
-    ActivateNewFormulaCell(it, nRow, *pCell, false);
-    return true;
-}
-
 svl::SharedString ScColumn::GetSharedString( SCROW nRow ) const
 {
     sc::CellStoreType::const_position_type aPos = maCells.position(nRow);
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index 930c8d1..1e0bb87 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -1093,14 +1093,6 @@ ScFormulaCell* ScDocument::SetFormulaCell( const ScAddress& rPos, ScFormulaCell*
     return maTabs[rPos.Tab()]->SetFormulaCell(rPos.Col(), rPos.Row(), pCell);
 }
 
-bool ScDocument::SetGroupFormulaCell( const ScAddress& rPos, ScFormulaCell* pCell )
-{
-    if (!TableExists(rPos.Tab()))
-        return false;
-
-    return maTabs[rPos.Tab()]->SetGroupFormulaCell(rPos.Col(), rPos.Row(), pCell);
-}
-
 void ScDocument::SetConsolidateDlgData( const ScConsolidateParam* pData )
 {
     delete pConsolidateDlgData;
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 5295af6..c94d66a 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1383,14 +1383,6 @@ ScFormulaCell* ScTable::SetFormulaCell( SCCOL nCol, SCROW nRow, ScFormulaCell* p
     return aCol[nCol].SetFormulaCell(nRow, pCell);
 }
 
-bool ScTable::SetGroupFormulaCell( SCCOL nCol, SCROW nRow, ScFormulaCell* pCell )
-{
-    if (!ValidColRow(nCol, nRow))
-        return false;
-
-    return aCol[nCol].SetGroupFormulaCell(nRow, pCell);
-}
-
 svl::SharedString ScTable::GetSharedString( SCCOL nCol, SCROW nRow ) const
 {
     if (!ValidColRow(nCol, nRow))
diff --git a/sc/source/filter/oox/formulabuffer.cxx b/sc/source/filter/oox/formulabuffer.cxx
index a4e3b7b..ade158f 100644
--- a/sc/source/filter/oox/formulabuffer.cxx
+++ b/sc/source/filter/oox/formulabuffer.cxx
@@ -16,6 +16,7 @@
 #include <com/sun/star/table/XCell2.hpp>
 #include "formulacell.hxx"
 #include "document.hxx"
+#include "documentimport.hxx"
 #include "convuno.hxx"
 
 #include "rangelst.hxx"
@@ -92,9 +93,7 @@ void FormulaBuffer::applyCellFormula( ScDocument& rDoc, const ApiTokenSequence&
     ScUnoConversion::FillScAddress( aCellPos, rAddress );
     ScTokenConversion::ConvertToTokenArray( rDoc, aTokenArray, rTokens );
     ScFormulaCell* pNewCell = new ScFormulaCell( &rDoc, aCellPos, &aTokenArray );
-    pNewCell->StartListeningTo( &rDoc );
-    rDoc.EnsureTable(aCellPos.Tab());
-    rDoc.SetGroupFormulaCell(aCellPos, pNewCell);
+    getDocImport().setFormulaCell(aCellPos, pNewCell);
 }
 
 void FormulaBuffer::applyCellFormulas( const std::vector< TokenAddressItem >& rVector )
@@ -140,7 +139,7 @@ void FormulaBuffer::applySharedFormulas( sal_Int32 nTab )
     const std::vector<SharedFormulaEntry>& rSharedFormulas = itShared->second;
     const std::vector<SharedFormulaDesc>& rCells = itCells->second;
 
-    ScDocument& rDoc = getScDocument();
+    ScDocumentImport& rDoc = getDocImport();
 
     sc::SharedFormulaGroups aGroups;
     {
@@ -154,7 +153,7 @@ void FormulaBuffer::applySharedFormulas( sal_Int32 nTab )
 
             ScAddress aPos;
             ScUnoConversion::FillScAddress(aPos, rAddr);
-            ScCompiler aComp(&rDoc, aPos);
+            ScCompiler aComp(&rDoc.getDoc(), aPos);
             aComp.SetGrammar(formula::FormulaGrammar::GRAM_ENGLISH_XL_OOX);
             ScTokenArray* pArray = aComp.CompileString(rTokenStr);
             if (pArray)
@@ -174,17 +173,8 @@ void FormulaBuffer::applySharedFormulas( sal_Int32 nTab )
 
             ScAddress aPos;
             ScUnoConversion::FillScAddress(aPos, rAddr);
-            ScFormulaCell* pCell = new ScFormulaCell(&rDoc, aPos, pArray);
-            bool bInserted = rDoc.SetGroupFormulaCell(aPos, pCell);
-            if (!bInserted)
-            {
-                // Insertion failed.
-                delete pCell;
-                continue;
-            }
-
-            pCell->StartListeningTo(&rDoc);
-
+            ScFormulaCell* pCell = new ScFormulaCell(&rDoc.getDoc(), aPos, pArray);
+            rDoc.setFormulaCell(aPos, pCell);
             if (it->maCellValue.isEmpty())
             {
                 // No cached cell value. Mark it for re-calculation.
@@ -210,7 +200,7 @@ void FormulaBuffer::applySharedFormulas( sal_Int32 nTab )
 
 void FormulaBuffer::applyArrayFormulas( const std::vector< TokenRangeAddressItem >& rVector )
 {
-    ScDocument& rDoc = getScDocument();
+    ScDocumentImport& rDocImport = getDocImport();
     std::vector<TokenRangeAddressItem>::const_iterator it = rVector.begin(), itEnd = rVector.end();
     for (; it != itEnd; ++it)
     {
@@ -219,21 +209,11 @@ void FormulaBuffer::applyArrayFormulas( const std::vector< TokenRangeAddressItem
         ScRange aRange;
         ScUnoConversion::FillScRange(aRange, it->maCellRangeAddress);
 
-        ScCompiler aComp(&rDoc, aPos);
+        ScCompiler aComp(&rDocImport.getDoc(), aPos);
         aComp.SetGrammar(formula::FormulaGrammar::GRAM_ENGLISH_XL_OOX);
         ScTokenArray* pArray = aComp.CompileString(it->maTokenAndAddress.maTokenStr);
         if (pArray)
-        {
-            ScMarkData aMark;
-            aMark.SelectOneTable(aPos.Tab());
-            rDoc.InsertMatrixFormula(
-                aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row(),
-                aMark, it->maTokenAndAddress.maTokenStr, pArray, formula::FormulaGrammar::GRAM_ENGLISH_XL_OOX);
-
-            ScFormulaCell* pFC = rDoc.GetFormulaCell(aPos);
-            if (pFC)
-                pFC->StartListeningTo(&rDoc);
-        }
+            rDocImport.setMatrixCells(aRange, *pArray, formula::FormulaGrammar::GRAM_ENGLISH_XL_OOX);
     }
 }
 
diff --git a/sc/source/filter/oox/worksheethelper.cxx b/sc/source/filter/oox/worksheethelper.cxx
index fe02efa..fb5eadd 100644
--- a/sc/source/filter/oox/worksheethelper.cxx
+++ b/sc/source/filter/oox/worksheethelper.cxx
@@ -1578,12 +1578,12 @@ void WorksheetHelper::putRichString( const CellAddress& rAddress, const RichStri
 
 void WorksheetHelper::putFormulaTokens( const CellAddress& rAddress, const ApiTokenSequence& rTokens )
 {
-    ScDocument& rDoc = getScDocument();
+    ScDocumentImport& rDoc = getDocImport();
     ScTokenArray aTokenArray;
     ScAddress aCellPos;
     ScUnoConversion::FillScAddress( aCellPos, rAddress );
-    ScTokenConversion::ConvertToTokenArray( rDoc, aTokenArray, rTokens );
-    getDocImport().setFormulaCell(aCellPos, aTokenArray);
+    ScTokenConversion::ConvertToTokenArray(rDoc.getDoc(), aTokenArray, rTokens);
+    rDoc.setFormulaCell(aCellPos, aTokenArray);
 }
 
 void WorksheetHelper::initializeWorksheetImport()
commit 835fee82efb70b40b94f6babc2706ee1eb66dcf7
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Thu Oct 31 16:25:32 2013 -0400

    Populate raw cell values using ScDocumentImport.
    
    Also fix incorrect const methods. Methods that populate the document
    model should not be marked const even if the compiler allows it.
    
    Change-Id: Ic5d1670ce93c166d0f44ace04494fccab6eac275

diff --git a/sc/inc/tokenuno.hxx b/sc/inc/tokenuno.hxx
index a323b62..4287405 100644
--- a/sc/inc/tokenuno.hxx
+++ b/sc/inc/tokenuno.hxx
@@ -43,7 +43,7 @@ public:
                         ScTokenArray& rTokenArray,
                         const com::sun::star::uno::Sequence< com::sun::star::sheet::FormulaToken >& rSequence );
     static SC_DLLPUBLIC bool ConvertToTokenSequence(
-                        ScDocument& rDoc,
+                        const ScDocument& rDoc,
                         com::sun::star::uno::Sequence< com::sun::star::sheet::FormulaToken >& rSequence,
                         const ScTokenArray& rTokenArray );
 };
diff --git a/sc/source/filter/inc/workbookhelper.hxx b/sc/source/filter/inc/workbookhelper.hxx
index 4db98ce..a905612 100644
--- a/sc/source/filter/inc/workbookhelper.hxx
+++ b/sc/source/filter/inc/workbookhelper.hxx
@@ -149,7 +149,11 @@ public:
     void                useInternalChartDataTable( bool bInternal );
 
     // document model ---------------------------------------------------------
-    ScDocument& getScDocument() const;
+    ScDocument& getScDocument();
+    const ScDocument& getScDocument() const;
+
+    ScDocumentImport& getDocImport();
+
     ScEditEngineDefaulter& getEditEngine() const;
     /** Returns a reference to the source/target spreadsheet document model. */
     ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheetDocument >
diff --git a/sc/source/filter/inc/worksheethelper.hxx b/sc/source/filter/inc/worksheethelper.hxx
index 270cafe..8cda876 100644
--- a/sc/source/filter/inc/worksheethelper.hxx
+++ b/sc/source/filter/inc/worksheethelper.hxx
@@ -281,23 +281,17 @@ public:
     void                setManualRowHeight( sal_Int32 nRow );
 
     /** Inserts a value cell directly into the Calc sheet. */
-    void                putValue(
-                            const ::com::sun::star::table::CellAddress& rAddress,
-                            double fValue ) const;
+    void putValue( const com::sun::star::table::CellAddress& rAddress, double fValue );
 
     /** Inserts a string cell directly into the Calc sheet. */
-    void                putString(
-                            const ::com::sun::star::table::CellAddress& rAddress,
-                            const OUString& rText ) const;
+    void putString( const com::sun::star::table::CellAddress& rAddress, const OUString& rText );
     /** Inserts a rich-string cell directly into the Calc sheet. */
-    void                putRichString(
-                            const ::com::sun::star::table::CellAddress& rAddress,
-                            const RichString& rString,
-                            const Font* pFirstPortionFont ) const;
+    void putRichString(
+        const com::sun::star::table::CellAddress& rAddress,
+        const RichString& rString, const Font* pFirstPortionFont );
     /** Inserts a formula cell directly into the Calc sheet. */
-    void                putFormulaTokens(
-                            const ::com::sun::star::table::CellAddress& rAddress,
-                            const ApiTokenSequence& rTokens ) const;
+    void putFormulaTokens(
+        const com::sun::star::table::CellAddress& rAddress, const ApiTokenSequence& rTokens );
 
     /** Initial conversion before importing the worksheet. */
     void                initializeWorksheetImport();
diff --git a/sc/source/filter/oox/defnamesbuffer.cxx b/sc/source/filter/oox/defnamesbuffer.cxx
index 3c3dd09..94203a8 100644
--- a/sc/source/filter/oox/defnamesbuffer.cxx
+++ b/sc/source/filter/oox/defnamesbuffer.cxx
@@ -458,7 +458,7 @@ bool DefinedName::getAbsoluteRange( CellRangeAddress& orRange ) const
 {
     ScTokenArray* pTokenArray = mpScRangeData->GetCode();
     Sequence< FormulaToken > aFTokenSeq;
-    ScTokenConversion::ConvertToTokenSequence( this->getScDocument(), aFTokenSeq, *pTokenArray );
+    ScTokenConversion::ConvertToTokenSequence(getScDocument(), aFTokenSeq, *pTokenArray);
     return getFormulaParser().extractCellRange( orRange, aFTokenSeq, false );
 }
 
diff --git a/sc/source/filter/oox/numberformatsbuffer.cxx b/sc/source/filter/oox/numberformatsbuffer.cxx
index d6992f5..2b6f271 100644
--- a/sc/source/filter/oox/numberformatsbuffer.cxx
+++ b/sc/source/filter/oox/numberformatsbuffer.cxx
@@ -1936,7 +1936,7 @@ sal_Int32 NumberFormat::finalizeImport( const Reference< XNumberFormats >& rxNum
 
 void NumberFormat::fillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs ) const
 {
-    ScDocument& rDoc = getScDocument();
+    const ScDocument& rDoc = getScDocument();
     static sal_uLong  nDflt = rDoc.GetFormatTable()->GetStandardFormat( ScGlobal::eLnge );
     sal_uLong nScNumFmt = nDflt;
     if ( maApiData.mnIndex )
diff --git a/sc/source/filter/oox/workbookhelper.cxx b/sc/source/filter/oox/workbookhelper.cxx
index f7fc225..496be44 100644
--- a/sc/source/filter/oox/workbookhelper.cxx
+++ b/sc/source/filter/oox/workbookhelper.cxx
@@ -662,7 +662,7 @@ void WorkbookGlobals::finalize()
         //stop preventing establishment of listeners as is done in
         //ScDocShell::AfterXMLLoading() for ods
         getScDocument().SetInsertingFromOtherDoc(false);
-        getScDocument().RebuildFormulaGroups();
+        getDocImport().finalize();
 
         if (mxCLKernelThread.is())
             mxCLKernelThread->join();
@@ -755,11 +755,21 @@ void WorkbookHelper::finalizeWorkbookImport()
 
 // document model -------------------------------------------------------------
 
-ScDocument& WorkbookHelper::getScDocument() const
+ScDocument& WorkbookHelper::getScDocument()
 {
     return mrBookGlob.getScDocument();
 }
 
+const ScDocument& WorkbookHelper::getScDocument() const
+{
+    return mrBookGlob.getScDocument();
+}
+
+ScDocumentImport& WorkbookHelper::getDocImport()
+{
+    return mrBookGlob.getDocImport();
+}
+
 ScEditEngineDefaulter& WorkbookHelper::getEditEngine() const
 {
     return mrBookGlob.getEditEngine();
diff --git a/sc/source/filter/oox/worksheethelper.cxx b/sc/source/filter/oox/worksheethelper.cxx
index ee8201f..fe02efa 100644
--- a/sc/source/filter/oox/worksheethelper.cxx
+++ b/sc/source/filter/oox/worksheethelper.cxx
@@ -69,6 +69,7 @@
 #include "editutil.hxx"
 #include "tokenarray.hxx"
 #include "tablebuffer.hxx"
+#include "documentimport.hxx"
 
 #include <svl/stritem.hxx>
 #include <editeng/editobj.hxx>
@@ -355,11 +356,11 @@ private:
     typedef ::std::list< ValidationModel >              ValidationModelList;
 
     /** Inserts all imported hyperlinks into their cell ranges. */
-    void                finalizeHyperlinkRanges() const;
+    void finalizeHyperlinkRanges();
     /** Generates the final URL for the passed hyperlink. */
     OUString            getHyperlinkUrl( const HyperlinkModel& rHyperlink ) const;
     /** Inserts a hyperlinks into the specified cell. */
-    void                insertHyperlink( const CellAddress& rAddress, const OUString& rUrl ) const;
+    void insertHyperlink( const CellAddress& rAddress, const OUString& rUrl );
 
     /** Inserts all imported data validations into their cell ranges. */
     void                finalizeValidationRanges() const;
@@ -977,7 +978,7 @@ void WorksheetGlobals::finalizeDrawingImport()
 
 // private --------------------------------------------------------------------
 
-void WorksheetGlobals::finalizeHyperlinkRanges() const
+void WorksheetGlobals::finalizeHyperlinkRanges()
 {
     for( HyperlinkModelList::const_iterator aIt = maHyperlinks.begin(), aEnd = maHyperlinks.end(); aIt != aEnd; ++aIt )
     {
@@ -1018,7 +1019,7 @@ OUString WorksheetGlobals::getHyperlinkUrl( const HyperlinkModel& rHyperlink ) c
     return aUrl;
 }
 
-void WorksheetGlobals::insertHyperlink( const CellAddress& rAddress, const OUString& rUrl ) const
+void WorksheetGlobals::insertHyperlink( const CellAddress& rAddress, const OUString& rUrl )
 {
     Reference< XCell > xCell = getCell( rAddress );
     if( xCell.is() ) switch( xCell->getType() )
@@ -1544,11 +1545,11 @@ void WorksheetHelper::setRowModel( const RowModel& rModel )
     mrSheetGlob.setRowModel( rModel );
 }
 
-void WorksheetHelper::putValue( const CellAddress& rAddress, double fValue ) const
+void WorksheetHelper::putValue( const CellAddress& rAddress, double fValue )
 {
     ScAddress aAddress;
     ScUnoConversion::FillScAddress( aAddress, rAddress );
-    getScDocument().SetValue( aAddress.Col(), aAddress.Row(), aAddress.Tab(), fValue );
+    getDocImport().setNumericCell(aAddress, fValue);
 }
 
 void WorksheetHelper::setCellFormulaValue( const ::com::sun::star::table::CellAddress& rAddress,
@@ -1557,34 +1558,32 @@ void WorksheetHelper::setCellFormulaValue( const ::com::sun::star::table::CellAd
     getFormulaBuffer().setCellFormulaValue( rAddress, fValue );
 }
 
-void WorksheetHelper::putString( const CellAddress& rAddress, const OUString& rText ) const
+void WorksheetHelper::putString( const CellAddress& rAddress, const OUString& rText )
 {
     ScAddress aAddress;
     ScUnoConversion::FillScAddress( aAddress, rAddress );
-    ScDocument& rDoc = getScDocument();
     if ( !rText.isEmpty() )
-        rDoc.SetTextCell(aAddress, rText);
+        getDocImport().setStringCell(aAddress, rText);
 }
 
-void WorksheetHelper::putRichString( const CellAddress& rAddress, const RichString& rString, const Font* pFirstPortionFont ) const
+void WorksheetHelper::putRichString( const CellAddress& rAddress, const RichString& rString, const Font* pFirstPortionFont )
 {
-    ScDocument& rDoc = getScDocument();
     ScEditEngineDefaulter& rEE = getEditEngine();
 
     // The cell will own the text object instance returned from convert().
     ScAddress aAddress;
     ScUnoConversion::FillScAddress( aAddress, rAddress );
-    rDoc.SetEditText(aAddress, rString.convert(rEE, pFirstPortionFont));
+    getDocImport().setEditCell(aAddress, rString.convert(rEE, pFirstPortionFont));
 }
 
-void WorksheetHelper::putFormulaTokens( const CellAddress& rAddress, const ApiTokenSequence& rTokens ) const
+void WorksheetHelper::putFormulaTokens( const CellAddress& rAddress, const ApiTokenSequence& rTokens )
 {
     ScDocument& rDoc = getScDocument();
     ScTokenArray aTokenArray;
     ScAddress aCellPos;
     ScUnoConversion::FillScAddress( aCellPos, rAddress );
     ScTokenConversion::ConvertToTokenArray( rDoc, aTokenArray, rTokens );
-    rDoc.SetFormula(aCellPos, aTokenArray);
+    getDocImport().setFormulaCell(aCellPos, aTokenArray);
 }
 
 void WorksheetHelper::initializeWorksheetImport()
diff --git a/sc/source/ui/unoobj/tokenuno.cxx b/sc/source/ui/unoobj/tokenuno.cxx
index 1694981..ff1b417 100644
--- a/sc/source/ui/unoobj/tokenuno.cxx
+++ b/sc/source/ui/unoobj/tokenuno.cxx
@@ -372,7 +372,7 @@ bool ScTokenConversion::ConvertToTokenArray( ScDocument& rDoc,
     return !rTokenArray.Fill(rSequence,rDoc.GetExternalRefManager());
 }
 
-bool ScTokenConversion::ConvertToTokenSequence( ScDocument& rDoc,
+bool ScTokenConversion::ConvertToTokenSequence( const ScDocument& rDoc,
         uno::Sequence<sheet::FormulaToken>& rSequence, const ScTokenArray& rTokenArray )
 {
     bool bError = false;
commit 8228f6736b91da06f439080665bdc389297bb5b7
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Thu Oct 31 14:30:18 2013 -0400

    Set up ScDocumentImport accessor and initialize it.
    
    Also, those createFoo() methods shouldn't be const since it does
    modify the state of the document model.
    
    Change-Id: I6a9267c54710f359506ca39c1e213f82595ebfe3

diff --git a/sc/source/filter/inc/workbookhelper.hxx b/sc/source/filter/inc/workbookhelper.hxx
index 9ea2353..4db98ce 100644
--- a/sc/source/filter/inc/workbookhelper.hxx
+++ b/sc/source/filter/inc/workbookhelper.hxx
@@ -56,6 +56,7 @@ namespace oox { namespace core {
 } }
 
 class ScDocument;
+class ScDocumentImport;
 class ScEditEngineDefaulter;
 
 namespace oox {
diff --git a/sc/source/filter/oox/workbookhelper.cxx b/sc/source/filter/oox/workbookhelper.cxx
index 9ae6fea..f7fc225 100644
--- a/sc/source/filter/oox/workbookhelper.cxx
+++ b/sc/source/filter/oox/workbookhelper.cxx
@@ -72,6 +72,7 @@
 #include "datauno.hxx"
 #include "globalnames.hxx"
 #include "clkernelthread.hxx"
+#include "documentimport.hxx"
 #include "rtl/ref.hxx"
 
 #include "formulabuffer.hxx"
@@ -80,6 +81,7 @@
 #include "editeng/editstat.hxx"
 
 #include <boost/noncopyable.hpp>
+#include <boost/scoped_ptr.hpp>
 
 namespace oox {
 namespace xls {
@@ -147,7 +149,10 @@ public:
         return *mxEditEngine.get();
     }
 
-    ScDocument& getScDocument() const { return *mpDoc; }
+    ScDocument& getScDocument() { return *mpDoc; }
+    const ScDocument& getScDocument() const { return *mpDoc; }
+
+    ScDocumentImport& getDocImport();
 
     /** Returns a reference to the source/target spreadsheet document model. */
     inline Reference< XSpreadsheetDocument > getDocument() const { return mxDoc; }
@@ -156,15 +161,15 @@ public:
     /** Returns the specified cell or page style from the Calc document. */
     Reference< XStyle > getStyleObject( const OUString& rStyleName, bool bPageStyle ) const;
     /** Creates and returns a defined name on-the-fly in the Calc document. */
-    ScRangeData* createNamedRangeObject( OUString& orName, const Sequence< FormulaToken>& rTokens, sal_Int32 nIndex, sal_Int32 nNameFlags ) const;
+    ScRangeData* createNamedRangeObject( OUString& orName, const Sequence< FormulaToken>& rTokens, sal_Int32 nIndex, sal_Int32 nNameFlags );
     /** Creates and returns a defined name on the-fly in the correct Calc sheet. */
-    ScRangeData* createLocalNamedRangeObject( OUString& orName, const Sequence< FormulaToken>& rTokens, sal_Int32 nIndex, sal_Int32 nNameFlags, sal_Int32 nTab ) const;
+    ScRangeData* createLocalNamedRangeObject( OUString& orName, const Sequence< FormulaToken>& rTokens, sal_Int32 nIndex, sal_Int32 nNameFlags, sal_Int32 nTab );
     /** Creates and returns a database range on-the-fly in the Calc document. */
-    Reference< XDatabaseRange > createDatabaseRangeObject( OUString& orName, const CellRangeAddress& rRangeAddr ) const;
+    Reference< XDatabaseRange > createDatabaseRangeObject( OUString& orName, const CellRangeAddress& rRangeAddr );
     /** Creates and returns an unnamed database range on-the-fly in the Calc document. */
-    Reference< XDatabaseRange > createUnnamedDatabaseRangeObject( const CellRangeAddress& rRangeAddr ) const;
+    Reference< XDatabaseRange > createUnnamedDatabaseRangeObject( const CellRangeAddress& rRangeAddr );
     /** Creates and returns a com.sun.star.style.Style object for cells or pages. */
-    Reference< XStyle > createStyleObject( OUString& orStyleName, bool bPageStyle ) const;
+    Reference< XStyle > createStyleObject( OUString& orStyleName, bool bPageStyle );
     /** Helper to switch chart data table - specifically for xlsx imports */
     void useInternalChartDataTable( bool bInternal );
 
@@ -306,6 +311,7 @@ private:
     rtl_TextEncoding    meTextEnc;              /// BIFF byte string text encoding.
     bool                mbHasCodePage;          /// True = CODEPAGE record exists in imported stream.
     ScDocument* mpDoc;
+    boost::scoped_ptr<ScDocumentImport> mxDocImport;
 };
 
 // ----------------------------------------------------------------------------
@@ -329,6 +335,10 @@ WorkbookGlobals::~WorkbookGlobals()
     mrExcelFilter.unregisterWorkbookGlobals();
 }
 
+ScDocumentImport& WorkbookGlobals::getDocImport()
+{
+    return *mxDocImport;
+}
 
 Reference< XNameContainer > WorkbookGlobals::getStyleFamily( bool bPageStyles ) const
 {
@@ -396,7 +406,8 @@ OUString findUnusedName( const ScRangeName* pRangeName, const OUString& rSuggest
 
 }
 
-ScRangeData* WorkbookGlobals::createNamedRangeObject( OUString& orName, const Sequence< FormulaToken>& rTokens, sal_Int32 nIndex, sal_Int32 nNameFlags ) const
+ScRangeData* WorkbookGlobals::createNamedRangeObject(
+    OUString& orName, const Sequence< FormulaToken>& rTokens, sal_Int32 nIndex, sal_Int32 nNameFlags )
 {
     // create the name and insert it into the Calc document
     ScRangeData* pScRangeData = NULL;
@@ -412,7 +423,8 @@ ScRangeData* WorkbookGlobals::createNamedRangeObject( OUString& orName, const Se
     return pScRangeData;
 }
 
-ScRangeData* WorkbookGlobals::createLocalNamedRangeObject( OUString& orName, const Sequence< FormulaToken >&  rTokens, sal_Int32 nIndex, sal_Int32 nNameFlags, sal_Int32 nTab ) const
+ScRangeData* WorkbookGlobals::createLocalNamedRangeObject(
+    OUString& orName, const Sequence< FormulaToken >&  rTokens, sal_Int32 nIndex, sal_Int32 nNameFlags, sal_Int32 nTab )
 {
     // create the name and insert it into the Calc document
     ScRangeData* pScRangeData = NULL;
@@ -428,7 +440,7 @@ ScRangeData* WorkbookGlobals::createLocalNamedRangeObject( OUString& orName, con
     return pScRangeData;
 }
 
-Reference< XDatabaseRange > WorkbookGlobals::createDatabaseRangeObject( OUString& orName, const CellRangeAddress& rRangeAddr ) const
+Reference< XDatabaseRange > WorkbookGlobals::createDatabaseRangeObject( OUString& orName, const CellRangeAddress& rRangeAddr )
 {
     // validate cell range
     CellRangeAddress aDestRange = rRangeAddr;
@@ -453,7 +465,7 @@ Reference< XDatabaseRange > WorkbookGlobals::createDatabaseRangeObject( OUString
     return xDatabaseRange;
 }
 
-Reference< XDatabaseRange > WorkbookGlobals::createUnnamedDatabaseRangeObject( const CellRangeAddress& rRangeAddr ) const
+Reference< XDatabaseRange > WorkbookGlobals::createUnnamedDatabaseRangeObject( const CellRangeAddress& rRangeAddr )
 {
     // validate cell range
     CellRangeAddress aDestRange = rRangeAddr;
@@ -482,7 +494,7 @@ Reference< XDatabaseRange > WorkbookGlobals::createUnnamedDatabaseRangeObject( c
     return xDatabaseRange;
 }
 
-Reference< XStyle > WorkbookGlobals::createStyleObject( OUString& orStyleName, bool bPageStyle ) const
+Reference< XStyle > WorkbookGlobals::createStyleObject( OUString& orStyleName, bool bPageStyle )
 {
     Reference< XStyle > xStyle;
     try
@@ -547,6 +559,8 @@ void WorkbookGlobals::initialize( bool bWorkbookFile )
     if (!mpDoc)
         throw RuntimeException("Workbookhelper::getScDocument(): Failed to access ScDocument from model", Reference<XInterface>());
 
+    mxDocImport.reset(new ScDocumentImport(*mpDoc));
+
     mxFormulaBuffer.reset( new FormulaBuffer( *this ) );
     mxWorkbookSettings.reset( new WorkbookSettings( *this ) );
     mxViewSettings.reset( new ViewSettings( *this ) );


More information about the Libreoffice-commits mailing list