[Libreoffice-commits] .: 25 commits - sc/inc sc/qa sc/source

Kohei Yoshida kohei at kemper.freedesktop.org
Wed Jul 11 17:36:51 PDT 2012


 sc/inc/document.hxx                            |    6 
 sc/qa/unit/data/contentCSV/hard-recalc.csv     |    1 
 sc/qa/unit/data/contentCSV/matrix2.csv         |    5 
 sc/qa/unit/data/ods/hard-recalc.ods            |binary
 sc/qa/unit/data/ods/matrix.ods                 |binary
 sc/qa/unit/data/ods/volatile.ods               |binary
 sc/qa/unit/subsequent_filters-test.cxx         |  244 +++++++++++++++----------
 sc/source/core/data/bcaslot.cxx                |    4 
 sc/source/core/data/cell.cxx                   |    4 
 sc/source/core/data/documen2.cxx               |    2 
 sc/source/core/data/documen7.cxx               |    8 
 sc/source/core/data/document.cxx               |    1 
 sc/source/core/tool/formularesult.cxx          |   15 +
 sc/source/filter/xml/XMLStylesImportHelper.cxx |   16 +
 sc/source/filter/xml/XMLStylesImportHelper.hxx |    1 
 sc/source/filter/xml/xmlcelli.cxx              |   91 ++++++---
 sc/source/filter/xml/xmlcelli.hxx              |   10 -
 sc/source/filter/xml/xmlimprt.cxx              |   12 -
 sc/source/filter/xml/xmlsubti.cxx              |  111 +----------
 sc/source/filter/xml/xmlsubti.hxx              |   44 ----
 sc/source/ui/docshell/docsh.cxx                |   19 +
 sc/source/ui/docshell/docsh4.cxx               |    2 
 22 files changed, 323 insertions(+), 273 deletions(-)

New commits:
commit 9e603369f5e8df5d12c5e6bd9018f6b8eef0358d
Author: Daniel Bankston <daniel.e.bankston at gmail.com>
Date:   Wed Jul 11 18:12:27 2012 -0500

    Remove method that is no longer needed
    
    I added this method recently, but it is no longer needed.
    
    Change-Id: I0baa67ce1eb41cddde52a61bca65feede65c3994

diff --git a/sc/inc/cell.hxx b/sc/inc/cell.hxx
index 204e289..f609a46 100644
--- a/sc/inc/cell.hxx
+++ b/sc/inc/cell.hxx
@@ -448,7 +448,6 @@ public:
     sal_uInt16      GetErrCode();   // interpret first if necessary
     sal_uInt16      GetRawError();  // don't interpret, just return code or result error
     short           GetFormatType() const                   { return nFormatType; }
-    void            SetFormatType( short nFType )           { nFormatType = nFType; }
     sal_uLong       GetFormatIndex() const                  { return nFormatIndex; }
     void            GetFormatInfo( short& nType, sal_uLong& nIndex ) const
                         { nType = nFormatType; nIndex = nFormatIndex; }
commit 59b32886a48954f9dad96b3329d172ac73aaa065
Author: Daniel Bankston <daniel.e.bankston at gmail.com>
Date:   Wed Jul 11 17:48:00 2012 -0500

    Fix cause of osl warning
    
    Change-Id: Idfeaab29da60f323fdf8528599459cc38ab9f27c

diff --git a/sc/source/filter/xml/XMLStylesImportHelper.cxx b/sc/source/filter/xml/XMLStylesImportHelper.cxx
index 438ac0e..2f54d6b 100644
--- a/sc/source/filter/xml/XMLStylesImportHelper.cxx
+++ b/sc/source/filter/xml/XMLStylesImportHelper.cxx
@@ -85,6 +85,13 @@ void ScMyStyleRanges::AddRange(const ScRange& rRange,
             mpTimeList->addRange(rRange);
         }
         break;
+        case util::NumberFormat::DATE:
+        {
+            if (!mpDateList)
+                mpDateList.reset(new ScSimpleRangeList);
+            mpDateList->addRange(rRange);
+        }
+        break;
         case util::NumberFormat::DATETIME:
         {
             if (!mpDateTimeList)
@@ -152,6 +159,8 @@ void ScMyStyleRanges::InsertCol(const sal_Int32 nCol, const sal_Int32 nTab, ScDo
         mpNumberList->insertCol(static_cast<SCCOL>(nCol), static_cast<SCTAB>(nTab));
     if (mpTimeList)
         mpTimeList->insertCol(static_cast<SCCOL>(nCol), static_cast<SCTAB>(nTab));
+    if (mpDateList)
+        mpDateList->insertCol(static_cast<SCCOL>(nCol), static_cast<SCTAB>(nTab));
     if (mpDateTimeList)
         mpDateTimeList->insertCol(static_cast<SCCOL>(nCol), static_cast<SCTAB>(nTab));
     if (mpPercentList)
@@ -205,6 +214,13 @@ void ScMyStyleRanges::SetStylesToRanges(const rtl::OUString* pStyleName, ScXMLIm
         SetStylesToRanges(aList, pStyleName, util::NumberFormat::TIME, NULL, rImport);
         mpTimeList->clear();
     }
+    if (mpDateList)
+    {
+        list<ScRange> aList;
+        mpDateList->getRangeList(aList);
+        SetStylesToRanges(aList, pStyleName, util::NumberFormat::DATE, NULL, rImport);
+        mpDateList->clear();
+    }
     if (mpDateTimeList)
     {
         list<ScRange> aList;
diff --git a/sc/source/filter/xml/XMLStylesImportHelper.hxx b/sc/source/filter/xml/XMLStylesImportHelper.hxx
index 6a988d0..87765f3 100644
--- a/sc/source/filter/xml/XMLStylesImportHelper.hxx
+++ b/sc/source/filter/xml/XMLStylesImportHelper.hxx
@@ -97,6 +97,7 @@ class ScMyStyleRanges : public SvRefBase
     ::boost::shared_ptr<ScSimpleRangeList> mpTextList;
     ::boost::shared_ptr<ScSimpleRangeList> mpNumberList;
     ::boost::shared_ptr<ScSimpleRangeList> mpTimeList;
+    ::boost::shared_ptr<ScSimpleRangeList> mpDateList;
     ::boost::shared_ptr<ScSimpleRangeList> mpDateTimeList;
     ::boost::shared_ptr<ScSimpleRangeList> mpPercentList;
     ::boost::shared_ptr<ScSimpleRangeList> mpLogicalList;
commit 371cb44c52e11af8f9a3ec66827ec057c521804f
Author: Daniel Bankston <daniel.e.bankston at gmail.com>
Date:   Wed Jul 11 17:33:25 2012 -0500

    ODS Import: Improve method names and comments
    
    -EndElement used to be very long method that I broke into sub-methods.
     Some of these method names were possibly misleading so changed them to
     better reflect their intent.
    -I added and improved comments in this area too.
    
    Change-Id: I290c74362aff268b5e153a67dc9145965341cb9d

diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx
index 5858138..ede4131 100644
--- a/sc/source/filter/xml/xmlcelli.cxx
+++ b/sc/source/filter/xml/xmlcelli.cxx
@@ -753,10 +753,12 @@ void ScXMLTableRowCellContext::SetFormulaCell(ScFormulaCell* pFCell) const
     }
 }
 
-void ScXMLTableRowCellContext::AddTextCellToDoc( const ScAddress& rCurrentPos,
+void ScXMLTableRowCellContext::PutTextCell( const ScAddress& rCurrentPos,
         const SCCOL nCurrentCol, const ::boost::optional< rtl::OUString >& pOUText )
 {
     bool bDoIncrement = true;
+    //matrix reference cells that contain text formula results;
+    //cell was already put in document, just need to set text here.
     if( rXMLImport.GetTables().IsPartOfMatrix(rCurrentPos) )
     {
         ScBaseCell* pCell = rXMLImport.GetDocument()->GetCell( rCurrentPos );
@@ -775,7 +777,7 @@ void ScXMLTableRowCellContext::AddTextCellToDoc( const ScAddress& rCurrentPos,
             pFCell->ResetDirty();
         }
     }
-    else
+    else //regular text cells
     {
         ScBaseCell* pNewCell = NULL;
         ScDocument* pDoc = rXMLImport.GetDocument();
@@ -798,8 +800,10 @@ void ScXMLTableRowCellContext::AddTextCellToDoc( const ScAddress& rCurrentPos,
         rXMLImport.ProgressBarIncrement(false);
 }
 
-void ScXMLTableRowCellContext::AddNumberCellToDoc( const ScAddress& rCurrentPos )
+void ScXMLTableRowCellContext::PutValueCell( const ScAddress& rCurrentPos )
 {
+    //matrix reference cells that contain value formula results;
+    //cell was already put in document, just need to set value here.
     if( rXMLImport.GetTables().IsPartOfMatrix(rCurrentPos) )
     {
         ScBaseCell* pCell = rXMLImport.GetDocument()->GetCell( rCurrentPos );
@@ -809,7 +813,7 @@ void ScXMLTableRowCellContext::AddNumberCellToDoc( const ScAddress& rCurrentPos
             SetFormulaCell(pFCell);
         }
     }
-    else
+    else  //regular value cell
     {
         // #i62435# Initialize the value cell's script type
         // if the default style's number format is latin-only.
@@ -836,7 +840,7 @@ bool isEmptyOrNote( ScDocument* pDoc, const ScAddress& rCurrentPos )
 
 }
 
-void ScXMLTableRowCellContext::AddCellsToTable( const ScAddress& rCellPos,
+void ScXMLTableRowCellContext::AddTextAndValueCells( const ScAddress& rCellPos,
         const ::boost::optional< rtl::OUString >& pOUText, ScAddress& rCurrentPos )
 {
     ScMyTables& rTables = rXMLImport.GetTables();
@@ -864,7 +868,7 @@ void ScXMLTableRowCellContext::AddCellsToTable( const ScAddress& rCellPos,
                         {
                             case util::NumberFormat::TEXT:
                             {
-                                AddTextCellToDoc( rCurrentPos, i, pOUText );
+                                PutTextCell( rCurrentPos, i, pOUText );
                             }
                             break;
                             case util::NumberFormat::NUMBER:
@@ -875,7 +879,7 @@ void ScXMLTableRowCellContext::AddCellsToTable( const ScAddress& rCellPos,
                             case util::NumberFormat::DATETIME:
                             case util::NumberFormat::LOGICAL:
                             {
-                                AddNumberCellToDoc( rCurrentPos );
+                                PutValueCell( rCurrentPos );
                             }
                             break;
                             default:
@@ -988,7 +992,7 @@ void ScXMLTableRowCellContext::AddNonFormulaCells( const ScAddress& rCellPos )
     if( HasSpecialContent() )
         bIsEmpty = false;
 
-    AddCellsToTable( rCellPos, pOUText, aCurrentPos );
+    AddTextAndValueCells( rCellPos, pOUText, aCurrentPos );
 
     if( CellsAreRepeated() )
     {
@@ -1007,7 +1011,7 @@ void ScXMLTableRowCellContext::AddNonFormulaCells( const ScAddress& rCellPos )
     }
 }
 
-void ScXMLTableRowCellContext::AddNonMatrixFormulaCell( const ScAddress& rCellPos )
+void ScXMLTableRowCellContext::PutFormulaCell( const ScAddress& rCellPos )
 {
     ScDocument* pDoc = rXMLImport.GetDocument();
 
@@ -1071,20 +1075,23 @@ void ScXMLTableRowCellContext::AddFormulaCell( const ScAddress& rCellPos )
         {
             if (nMatrixCols > 0 && nMatrixRows > 0)
             {
+                //matrix cells are put in the document, but we must set the
+                //value/text of each matrix cell later
                 rXMLImport.GetTables().AddMatrixRange(
                         rCellPos.Col(), rCellPos.Row(),
                         rCellPos.Col() + nMatrixCols - 1,
                         rCellPos.Row() + nMatrixRows - 1,
                         pOUFormula->first, pOUFormula->second, eGrammar);
 
-                //add the cached formula result of the first matrix position
+                //set the value/text of the first matrix position (top-left).
+                //the value/text of the matrix reference cells will be set later.
                 ScFormulaCell* pFCell =
                     static_cast<ScFormulaCell*>( rXMLImport.GetDocument()->GetCell(rCellPos) );
                 SetFormulaCell(pFCell);
             }
         }
         else
-            AddNonMatrixFormulaCell( rCellPos );
+            PutFormulaCell( rCellPos );
 
         SetAnnotation( rCellPos );
         SetDetectiveObj( rCellPos );
diff --git a/sc/source/filter/xml/xmlcelli.hxx b/sc/source/filter/xml/xmlcelli.hxx
index 9b038c6..b16eff5 100644
--- a/sc/source/filter/xml/xmlcelli.hxx
+++ b/sc/source/filter/xml/xmlcelli.hxx
@@ -92,13 +92,13 @@ class ScXMLTableRowCellContext : public SvXMLImportContext
     bool CellsAreRepeated() const;
 
     void SetFormulaCell             ( ScFormulaCell* pFCell ) const;
-    void AddTextCellToDoc           ( const ScAddress& rScCurrentPos, const SCCOL nCurrentCol,
+    void PutTextCell                ( const ScAddress& rScCurrentPos, const SCCOL nCurrentCol,
                                       const ::boost::optional< rtl::OUString >& pOUText );
-    void AddNumberCellToDoc         ( const ScAddress& rScCurrentPos );
-    void AddCellsToTable            ( const ScAddress& rScCellPos,
+    void PutValueCell               ( const ScAddress& rScCurrentPos );
+    void AddTextAndValueCells       ( const ScAddress& rScCellPos,
                                       const ::boost::optional< rtl::OUString >& pOUText, ScAddress& rScCurrentPos );
     void AddNonFormulaCells         ( const ScAddress& rScCellPos );
-    void AddNonMatrixFormulaCell    ( const ScAddress& rScCurrentPos );
+    void PutFormulaCell             ( const ScAddress& rScCurrentPos );
     void AddFormulaCell             ( const ScAddress& rScCellPos );
 
 public:
commit 4e5c55afee36d02bdfe4c0fb09e3b42e9eadb6c5
Author: Daniel Bankston <daniel.e.bankston at gmail.com>
Date:   Wed Jul 11 16:49:19 2012 -0500

    Distinguish between DATE and DATETIME formats in ODS import
    
    Change-Id: Ia727e48582a87efc8a8e632108f5949ac36bf49c

diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx
index e3ab416..5858138 100644
--- a/sc/source/filter/xml/xmlcelli.cxx
+++ b/sc/source/filter/xml/xmlcelli.cxx
@@ -871,6 +871,7 @@ void ScXMLTableRowCellContext::AddCellsToTable( const ScAddress& rCellPos,
                             case util::NumberFormat::PERCENT:
                             case util::NumberFormat::CURRENCY:
                             case util::NumberFormat::TIME:
+                            case util::NumberFormat::DATE:
                             case util::NumberFormat::DATETIME:
                             case util::NumberFormat::LOGICAL:
                             {
diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx
index c3e3cd7..831176c 100644
--- a/sc/source/filter/xml/xmlimprt.cxx
+++ b/sc/source/filter/xml/xmlimprt.cxx
@@ -1979,7 +1979,8 @@ ScXMLImport::ScXMLImport(
         { XML_FLOAT,        util::NumberFormat::NUMBER },
         { XML_STRING,       util::NumberFormat::TEXT },
         { XML_TIME,         util::NumberFormat::TIME },
-        { XML_DATE,         util::NumberFormat::DATETIME },
+        { XML_DATE,         util::NumberFormat::DATE },
+        { XML_DATE_TIME,    util::NumberFormat::DATETIME },
         { XML_PERCENTAGE,   util::NumberFormat::PERCENT },
         { XML_CURRENCY,     util::NumberFormat::CURRENCY },
         { XML_BOOLEAN,      util::NumberFormat::LOGICAL }
commit c3452373b90bc952f32db8a08413c87958b0f2df
Author: Daniel Bankston <daniel.e.bankston at gmail.com>
Date:   Wed Jul 11 01:54:46 2012 -0500

    Add test for volatile functions for ODS import
    
    Change-Id: If2f85e32ddeb9f25b4a355ce5451dc04925bbbc9

diff --git a/sc/qa/unit/data/ods/volatile.ods b/sc/qa/unit/data/ods/volatile.ods
new file mode 100644
index 0000000..6278de7
Binary files /dev/null and b/sc/qa/unit/data/ods/volatile.ods differ
diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx
index 01197ff..b57757d 100644
--- a/sc/qa/unit/subsequent_filters-test.cxx
+++ b/sc/qa/unit/subsequent_filters-test.cxx
@@ -109,6 +109,7 @@ public:
     void testHardRecalcODS();
     void testFunctionsODS();
     void testCachedFormulaResultsODS();
+    void testVolatileFunctionsODS();
     void testCachedMatrixFormulaResultsODS();
     void testDatabaseRangesODS();
     void testDatabaseRangesXLS();
@@ -145,6 +146,7 @@ public:
     CPPUNIT_TEST(testHardRecalcODS);
     CPPUNIT_TEST(testFunctionsODS);
     CPPUNIT_TEST(testCachedFormulaResultsODS);
+    CPPUNIT_TEST(testVolatileFunctionsODS);
     CPPUNIT_TEST(testCachedMatrixFormulaResultsODS);
     CPPUNIT_TEST(testDatabaseRangesODS);
     CPPUNIT_TEST(testDatabaseRangesXLS);
@@ -388,6 +390,28 @@ void ScFiltersTest::testCachedFormulaResultsODS()
     xDocSh->DoClose();
 }
 
+void ScFiltersTest::testVolatileFunctionsODS()
+{
+    const rtl::OUString aFileNameBase(RTL_CONSTASCII_USTRINGPARAM("volatile."));
+    ScDocShellRef xDocSh = loadDoc( aFileNameBase, ODS );
+
+    CPPUNIT_ASSERT_MESSAGE("Failed to load volatile.ods", xDocSh.Is());
+    ScDocument* pDoc = xDocSh->GetDocument();
+
+    //we want to me sure that volatile functions are always recalculated
+    //regardless of cached results.  if you update the ods file, you must
+    //update the values here.
+    //if NOW() is recacluated, then it should never equal sTodayCache
+    OUString sTodayCache("07/11/12 12:28 AM");
+    OUString sTodayRecalc(pDoc->GetString(0,1,0));
+    CPPUNIT_ASSERT(sTodayCache != sTodayRecalc);
+
+    OUString sTodayRecalcRef(pDoc->GetString(2,1,0));
+    CPPUNIT_ASSERT(sTodayCache != sTodayRecalcRef);
+
+    xDocSh->DoClose();
+}
+
 void ScFiltersTest::testCachedMatrixFormulaResultsODS()
 {
     const rtl::OUString aFileNameBase(RTL_CONSTASCII_USTRINGPARAM("matrix."));
commit 6bf50c8d50a599d820289831ec4175136882b0d4
Author: Daniel Bankston <daniel.e.bankston at gmail.com>
Date:   Tue Jul 10 23:54:03 2012 -0500

    Always Recalc volatile formula cells in import
    
    -Previous method was flawed. It actually works now.
    -Thanks to Kohei and Markus for helping me with this.
    -Thanks to Markus for finally coming up with the actual solution.
    
    Change-Id: Iad28da12c548c583df14ab7d71f4cee8ccc3552a

diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx
index c4846c0..6ab3d2d 100644
--- a/sc/source/core/data/cell.cxx
+++ b/sc/source/core/data/cell.cxx
@@ -1099,6 +1099,10 @@ void ScFormulaCell::CompileXML( ScProgress& rProgress )
     //  (for macro warning, CompileXML is called at the end of loading XML file)
     if ( !pDocument->GetHasMacroFunc() && pCode->HasOpCodeRPN( ocMacro ) )
         pDocument->SetHasMacroFunc( true );
+
+    //volatile cells must be added here for import
+    if( pCode->IsRecalcModeAlways() )
+        pDocument->PutInFormulaTree(this);
 }
 
 
diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx
index c1b7a85..e3ab416 100644
--- a/sc/source/filter/xml/xmlcelli.cxx
+++ b/sc/source/filter/xml/xmlcelli.cxx
@@ -749,8 +749,7 @@ void ScXMLTableRowCellContext::SetFormulaCell(ScFormulaCell* pFCell) const
             pFCell->SetHybridString( *pOUTextValue );
         else
             pFCell->SetHybridDouble( fValue );
-        if( !pFCell->GetCode()->IsRecalcModeAlways() )
-            pFCell->ResetDirty();
+        pFCell->ResetDirty();
     }
 }
 
@@ -773,8 +772,7 @@ void ScXMLTableRowCellContext::AddTextCellToDoc( const ScAddress& rCurrentPos,
                 pFCell->SetHybridString( *pOUText );
             else
                 bDoIncrement = false;
-            if( !pFCell->GetCode()->IsRecalcModeAlways() )
-                pFCell->ResetDirty();
+            pFCell->ResetDirty();
         }
     }
     else
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index 752367c..5f7b828 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -437,6 +437,8 @@ sal_Bool ScDocShell::LoadXML( SfxMedium* pLoadMedium, const ::com::sun::star::un
     rtl::OUString sGenerator(xDocProps->getGenerator());
     if(sGenerator.indexOf(SC_LIBO_PROD_NAME) == -1)
         DoHardRecalc(false);
+    else //still need to recalc volatile formula cells
+        DoRecalc(false);
 
     aDocument.SetXMLFromWrapper( false );
     AfterXMLLoading(bRet);
commit 99314cb07e009279a803799020534dde587ee1a5
Author: Daniel Bankston <daniel.e.bankston at gmail.com>
Date:   Tue Jul 10 15:11:35 2012 -0500

    Reduce some redundant code
    
    Change-Id: I23bf34793c8a1409c8753f572a6122dee2f4128f

diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx
index 791f3f0..c1b7a85 100644
--- a/sc/source/filter/xml/xmlcelli.cxx
+++ b/sc/source/filter/xml/xmlcelli.cxx
@@ -741,6 +741,19 @@ void ScXMLTableRowCellContext::SetCellRangeSource( const ScAddress& rPosition )
     }
 }
 
+void ScXMLTableRowCellContext::SetFormulaCell(ScFormulaCell* pFCell) const
+{
+    if(pFCell)
+    {
+        if( bFormulaTextResult && pOUTextValue && !pOUTextValue->isEmpty() )
+            pFCell->SetHybridString( *pOUTextValue );
+        else
+            pFCell->SetHybridDouble( fValue );
+        if( !pFCell->GetCode()->IsRecalcModeAlways() )
+            pFCell->ResetDirty();
+    }
+}
+
 void ScXMLTableRowCellContext::AddTextCellToDoc( const ScAddress& rCurrentPos,
         const SCCOL nCurrentCol, const ::boost::optional< rtl::OUString >& pOUText )
 {
@@ -795,12 +808,7 @@ void ScXMLTableRowCellContext::AddNumberCellToDoc( const ScAddress& rCurrentPos
         if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
         {
             ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);
-            if( bFormulaTextResult && pOUTextValue && !pOUTextValue->isEmpty() )
-                pFCell->SetHybridString( *pOUTextValue );
-            else
-                pFCell->SetHybridDouble( fValue );
-            if( !pFCell->GetCode()->IsRecalcModeAlways() )
-                pFCell->ResetDirty();
+            SetFormulaCell(pFCell);
         }
     }
     else
@@ -1027,12 +1035,7 @@ void ScXMLTableRowCellContext::AddNonMatrixFormulaCell( const ScAddress& rCellPo
             delete pCode;
 
             ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pNewCell);
-            if( bFormulaTextResult && pOUTextValue && !pOUTextValue->isEmpty() )
-                pFCell->SetHybridString( *pOUTextValue );
-            else
-                pFCell->SetHybridDouble( fValue );
-            if( !(pFCell->GetCode()->IsRecalcModeOnLoad() || !pFCell->GetCode()->IsRecalcModeOnLoadOnce()) )
-                pFCell->ResetDirty();
+            SetFormulaCell(pFCell);
         }
         else if ( aText[0] == '\'' && aText.getLength() > 1 )
         {
@@ -1078,15 +1081,7 @@ void ScXMLTableRowCellContext::AddFormulaCell( const ScAddress& rCellPos )
                 //add the cached formula result of the first matrix position
                 ScFormulaCell* pFCell =
                     static_cast<ScFormulaCell*>( rXMLImport.GetDocument()->GetCell(rCellPos) );
-                if(pFCell)
-                {
-                    if( bFormulaTextResult && pOUTextValue && !pOUTextValue->isEmpty() )
-                        pFCell->SetHybridString( *pOUTextValue );
-                    else
-                        pFCell->SetHybridDouble( fValue );
-                    if( !pFCell->GetCode()->IsRecalcModeAlways() )
-                        pFCell->ResetDirty();
-                }
+                SetFormulaCell(pFCell);
             }
         }
         else
diff --git a/sc/source/filter/xml/xmlcelli.hxx b/sc/source/filter/xml/xmlcelli.hxx
index 3df155e..9b038c6 100644
--- a/sc/source/filter/xml/xmlcelli.hxx
+++ b/sc/source/filter/xml/xmlcelli.hxx
@@ -45,6 +45,7 @@
 #include <boost/optional.hpp>
 
 class ScXMLImport;
+class ScFormulaCell;
 struct ScXMLAnnotationData;
 
 class ScXMLTableRowCellContext : public SvXMLImportContext
@@ -90,6 +91,7 @@ class ScXMLTableRowCellContext : public SvXMLImportContext
     bool HasSpecialContent() const;
     bool CellsAreRepeated() const;
 
+    void SetFormulaCell             ( ScFormulaCell* pFCell ) const;
     void AddTextCellToDoc           ( const ScAddress& rScCurrentPos, const SCCOL nCurrentCol,
                                       const ::boost::optional< rtl::OUString >& pOUText );
     void AddNumberCellToDoc         ( const ScAddress& rScCurrentPos );
commit d880f3d3bf7b6052156e3d6c30f00d22fe66aee1
Author: Daniel Bankston <daniel.e.bankston at gmail.com>
Date:   Tue Jul 10 13:55:39 2012 -0500

    Always recalc certain functions on import
    
    Change-Id: Ie8cffc4a856328dd658714726de7ca77028a33a7

diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx
index 3ff5b58..791f3f0 100644
--- a/sc/source/filter/xml/xmlcelli.cxx
+++ b/sc/source/filter/xml/xmlcelli.cxx
@@ -760,7 +760,8 @@ void ScXMLTableRowCellContext::AddTextCellToDoc( const ScAddress& rCurrentPos,
                 pFCell->SetHybridString( *pOUText );
             else
                 bDoIncrement = false;
-            pFCell->ResetDirty();
+            if( !pFCell->GetCode()->IsRecalcModeAlways() )
+                pFCell->ResetDirty();
         }
     }
     else
@@ -798,7 +799,8 @@ void ScXMLTableRowCellContext::AddNumberCellToDoc( const ScAddress& rCurrentPos
                 pFCell->SetHybridString( *pOUTextValue );
             else
                 pFCell->SetHybridDouble( fValue );
-            pFCell->ResetDirty();
+            if( !pFCell->GetCode()->IsRecalcModeAlways() )
+                pFCell->ResetDirty();
         }
     }
     else
@@ -1029,7 +1031,8 @@ void ScXMLTableRowCellContext::AddNonMatrixFormulaCell( const ScAddress& rCellPo
                 pFCell->SetHybridString( *pOUTextValue );
             else
                 pFCell->SetHybridDouble( fValue );
-            pFCell->ResetDirty();
+            if( !(pFCell->GetCode()->IsRecalcModeOnLoad() || !pFCell->GetCode()->IsRecalcModeOnLoadOnce()) )
+                pFCell->ResetDirty();
         }
         else if ( aText[0] == '\'' && aText.getLength() > 1 )
         {
@@ -1081,7 +1084,8 @@ void ScXMLTableRowCellContext::AddFormulaCell( const ScAddress& rCellPos )
                         pFCell->SetHybridString( *pOUTextValue );
                     else
                         pFCell->SetHybridDouble( fValue );
-                    pFCell->ResetDirty();
+                    if( !pFCell->GetCode()->IsRecalcModeAlways() )
+                        pFCell->ResetDirty();
                 }
             }
         }
commit 9ba62d504ca93a377b7de328e2d00caa786638c6
Author: Daniel Bankston <daniel.e.bankston at gmail.com>
Date:   Sun Jul 8 13:28:22 2012 -0500

    Remove calls to ScFormulaCell::SetFormatType() that are no longer necessary
    
    Change-Id: I632273a2278cd76d2af96192885a11bea85bd6a0

diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx
index 9f54f5c..3ff5b58 100644
--- a/sc/source/filter/xml/xmlcelli.cxx
+++ b/sc/source/filter/xml/xmlcelli.cxx
@@ -760,7 +760,6 @@ void ScXMLTableRowCellContext::AddTextCellToDoc( const ScAddress& rCurrentPos,
                 pFCell->SetHybridString( *pOUText );
             else
                 bDoIncrement = false;
-            pFCell->SetFormatType( nCellType );
             pFCell->ResetDirty();
         }
     }
@@ -1030,7 +1029,6 @@ void ScXMLTableRowCellContext::AddNonMatrixFormulaCell( const ScAddress& rCellPo
                 pFCell->SetHybridString( *pOUTextValue );
             else
                 pFCell->SetHybridDouble( fValue );
-            pFCell->SetFormatType( nCellType );
             pFCell->ResetDirty();
         }
         else if ( aText[0] == '\'' && aText.getLength() > 1 )
@@ -1083,7 +1081,6 @@ void ScXMLTableRowCellContext::AddFormulaCell( const ScAddress& rCellPos )
                         pFCell->SetHybridString( *pOUTextValue );
                     else
                         pFCell->SetHybridDouble( fValue );
-                    pFCell->SetFormatType( nCellType );
                     pFCell->ResetDirty();
                 }
             }
commit 24c444ef7d595e69fd825f08668a5b0aeb010c45
Author: Daniel Bankston <daniel.e.bankston at gmail.com>
Date:   Sun Jul 8 13:13:14 2012 -0500

    Expand cached matrix formula result test case to include other potential probs
    
    Change-Id: Idb036ffdf09ee92b34118d9f52ea1d06c15fb31b

diff --git a/sc/qa/unit/data/contentCSV/matrix2.csv b/sc/qa/unit/data/contentCSV/matrix2.csv
index 44b3f71..955d345 100644
--- a/sc/qa/unit/data/contentCSV/matrix2.csv
+++ b/sc/qa/unit/data/contentCSV/matrix2.csv
@@ -1,2 +1,5 @@
-Matrix with errors:,,
-Err:502,Err:502,Err:502
+Matrices with errors and other misc potential problems:,,,,
+Err:502,Err:502,Err:502,,error result
+#N/A,#N/A,#N/A,,n/a
+TRUE,TRUE,TRUE,,Display TRUE instead of 1
+FALSE,FALSE,FALSE,,Display FALSE instead of 0
diff --git a/sc/qa/unit/data/ods/matrix.ods b/sc/qa/unit/data/ods/matrix.ods
index 7b69691..2a8c4ab 100644
Binary files a/sc/qa/unit/data/ods/matrix.ods and b/sc/qa/unit/data/ods/matrix.ods differ
commit c4878470aa18a4e018173c04bcf9e56eff2cdc3b
Author: Daniel Bankston <daniel.e.bankston at gmail.com>
Date:   Sun Jul 8 12:57:36 2012 -0500

    Fix problem with cached matrix formula results that contain errors
    
    Change-Id: I9277714780e00e311e6e81a9de6e4d39409d5c9b

diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx
index ed4350a..9f54f5c 100644
--- a/sc/source/filter/xml/xmlcelli.cxx
+++ b/sc/source/filter/xml/xmlcelli.cxx
@@ -795,7 +795,10 @@ void ScXMLTableRowCellContext::AddNumberCellToDoc( const ScAddress& rCurrentPos
         if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
         {
             ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);
-            pFCell->SetHybridDouble( fValue );
+            if( bFormulaTextResult && pOUTextValue && !pOUTextValue->isEmpty() )
+                pFCell->SetHybridString( *pOUTextValue );
+            else
+                pFCell->SetHybridDouble( fValue );
             pFCell->ResetDirty();
         }
     }
@@ -1052,15 +1055,6 @@ void ScXMLTableRowCellContext::AddNonMatrixFormulaCell( const ScAddress& rCellPo
     }
 }
 
-namespace{
-
-bool isErrOrNA(const rtl::OUString& rStr)
-{
-    return (rStr.indexOf("Err:")  > -1) || (rStr.indexOf("#N/A") > -1);
-}
-
-}
-
 void ScXMLTableRowCellContext::AddFormulaCell( const ScAddress& rCellPos )
 {
     if( cellExists(rCellPos) )
@@ -1069,10 +1063,6 @@ void ScXMLTableRowCellContext::AddFormulaCell( const ScAddress& rCellPos )
         OSL_ENSURE(((nColsRepeated == 1) && (nRepeatedRows == 1)), "repeated cells with formula not possible now");
         rXMLImport.GetStylesImportHelper()->AddCell(rCellPos);
 
-        //if this is an "Err:###" or "#N/A" then use text:p value
-        if( bFormulaTextResult && pOUTextContent && isErrOrNA(*pOUTextContent) )
-            pOUTextValue.reset(*pOUTextContent);
-
         //add matrix
         if(bIsMatrix)
         {
@@ -1115,6 +1105,15 @@ void ScXMLTableRowCellContext::AddFormulaCell( const ScAddress& rCellPos )
     }
 }
 
+namespace{
+
+bool isErrOrNA(const rtl::OUString& rStr)
+{
+    return (rStr.indexOf("Err:")  > -1) || (rStr.indexOf("#N/A") > -1);
+}
+
+}
+
 void ScXMLTableRowCellContext::EndElement()
 {
     if( bHasTextImport && rXMLImport.GetRemoveLastChar() )
@@ -1131,6 +1130,10 @@ void ScXMLTableRowCellContext::EndElement()
         }
     }
 
+    //if this is an "Err:###" or "#N/A" then use text:p value
+    if( bFormulaTextResult && pOUTextContent && isErrOrNA(*pOUTextContent) )
+        pOUTextValue.reset(*pOUTextContent);
+
     ScAddress aCellPos = rXMLImport.GetTables().GetCurrentCellPos();
     if( aCellPos.Col() > 0 && nRepeatedRows > 1 )
         aCellPos.SetRow( aCellPos.Row() - (nRepeatedRows - 1) );
commit 2fbe6e30c4481a4885b3e487bcd5466456a7b1d5
Author: Daniel Bankston <daniel.e.bankston at gmail.com>
Date:   Sun Jul 8 12:45:52 2012 -0500

    Add test for cached matrix formula results
    
    -Includes test case for cached formula result errors
    
    Change-Id: I446240daffdbd6cd7ebd3c3b8dc2305c789d8519

diff --git a/sc/qa/unit/data/contentCSV/matrix2.csv b/sc/qa/unit/data/contentCSV/matrix2.csv
new file mode 100644
index 0000000..44b3f71
--- /dev/null
+++ b/sc/qa/unit/data/contentCSV/matrix2.csv
@@ -0,0 +1,2 @@
+Matrix with errors:,,
+Err:502,Err:502,Err:502
diff --git a/sc/qa/unit/data/ods/matrix.ods b/sc/qa/unit/data/ods/matrix.ods
index 3c9f16a..7b69691 100644
Binary files a/sc/qa/unit/data/ods/matrix.ods and b/sc/qa/unit/data/ods/matrix.ods differ
diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx
index ad89fd8..01197ff 100644
--- a/sc/qa/unit/subsequent_filters-test.cxx
+++ b/sc/qa/unit/subsequent_filters-test.cxx
@@ -109,6 +109,7 @@ public:
     void testHardRecalcODS();
     void testFunctionsODS();
     void testCachedFormulaResultsODS();
+    void testCachedMatrixFormulaResultsODS();
     void testDatabaseRangesODS();
     void testDatabaseRangesXLS();
     void testDatabaseRangesXLSX();
@@ -144,6 +145,7 @@ public:
     CPPUNIT_TEST(testHardRecalcODS);
     CPPUNIT_TEST(testFunctionsODS);
     CPPUNIT_TEST(testCachedFormulaResultsODS);
+    CPPUNIT_TEST(testCachedMatrixFormulaResultsODS);
     CPPUNIT_TEST(testDatabaseRangesODS);
     CPPUNIT_TEST(testDatabaseRangesXLS);
     CPPUNIT_TEST(testDatabaseRangesXLSX);
@@ -323,7 +325,7 @@ void ScFiltersTest::testHardRecalcODS()
     ScDocShellRef xDocSh = loadDoc( aFileNameBase, ODS );
     xDocSh->DoHardRecalc(true);
 
-    CPPUNIT_ASSERT_MESSAGE("Failed to load functions.*", xDocSh.Is());
+    CPPUNIT_ASSERT_MESSAGE("Failed to load hard-recalc.*", xDocSh.Is());
     ScDocument* pDoc = xDocSh->GetDocument();
     rtl::OUString aCSVFileName;
 
@@ -386,6 +388,25 @@ void ScFiltersTest::testCachedFormulaResultsODS()
     xDocSh->DoClose();
 }
 
+void ScFiltersTest::testCachedMatrixFormulaResultsODS()
+{
+    const rtl::OUString aFileNameBase(RTL_CONSTASCII_USTRINGPARAM("matrix."));
+    ScDocShellRef xDocSh = loadDoc( aFileNameBase, ODS);
+
+    CPPUNIT_ASSERT_MESSAGE("Failed to load matrix.*", xDocSh.Is());
+    ScDocument* pDoc = xDocSh->GetDocument();
+
+    //test matrix
+    rtl::OUString aCSVFileName;
+    createCSVPath(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("matrix.")), aCSVFileName);
+    testFile(aCSVFileName, pDoc, 0);
+    //test matrix with errors
+    createCSVPath(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("matrix2.")), aCSVFileName);
+    testFile(aCSVFileName, pDoc, 1);
+
+    xDocSh->DoClose();
+}
+
 namespace {
 
 void testDBRanges_Impl(ScDocument* pDoc, sal_Int32 nFormat)
commit 20f8ade0aed4ce2f923370e148cd2d2b251fc863
Author: Daniel Bankston <daniel.e.bankston at gmail.com>
Date:   Sun Jul 8 11:26:52 2012 -0500

    Use cached formula results for matrices
    
    Change-Id: Ia77a94184c3d598f16a2f51d996f4c7058d9e303

diff --git a/sc/source/core/tool/formularesult.cxx b/sc/source/core/tool/formularesult.cxx
index 9606899..3b94481 100644
--- a/sc/source/core/tool/formularesult.cxx
+++ b/sc/source/core/tool/formularesult.cxx
@@ -398,11 +398,16 @@ void ScFormulaResult::SetHybridDouble( double f )
     ResetToDefaults();
     if (mbToken && mpToken)
     {
-        String aString( GetString());
-        String aFormula( GetHybridFormula());
-        mpToken->DecRef();
-        mpToken = new ScHybridCellToken( f, aString, aFormula);
-        mpToken->IncRef();
+        if(GetType() == formula::svMatrixCell)
+            SetDouble(f);
+        else
+        {
+            String aString( GetString());
+            String aFormula( GetHybridFormula());
+            mpToken->DecRef();
+            mpToken = new ScHybridCellToken( f, aString, aFormula);
+            mpToken->IncRef();
+        }
     }
     else
     {
diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx
index 3da5996..ed4350a 100644
--- a/sc/source/filter/xml/xmlcelli.cxx
+++ b/sc/source/filter/xml/xmlcelli.cxx
@@ -355,8 +355,7 @@ SvXMLImportContext *ScXMLTableRowCellContext::CreateChildContext( sal_uInt16 nPr
 
             ScAddress aCellPos = rXMLImport.GetTables().GetCurrentCellPos();
 
-            if( ((nCellType == util::NumberFormat::TEXT) || bFormulaTextResult) &&
-                !rXMLImport.GetTables().IsPartOfMatrix(aCellPos.Col(), aCellPos.Row()) )
+            if( ((nCellType == util::NumberFormat::TEXT) || bFormulaTextResult) )
             {
                 if (!bHasTextImport)
                 {
@@ -746,7 +745,7 @@ void ScXMLTableRowCellContext::AddTextCellToDoc( const ScAddress& rCurrentPos,
         const SCCOL nCurrentCol, const ::boost::optional< rtl::OUString >& pOUText )
 {
     bool bDoIncrement = true;
-    if( rXMLImport.GetTables().IsPartOfMatrix(rCurrentPos.Col(), rCurrentPos.Row()) )
+    if( rXMLImport.GetTables().IsPartOfMatrix(rCurrentPos) )
     {
         ScBaseCell* pCell = rXMLImport.GetDocument()->GetCell( rCurrentPos );
         bDoIncrement = ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA );
@@ -761,6 +760,7 @@ void ScXMLTableRowCellContext::AddTextCellToDoc( const ScAddress& rCurrentPos,
                 pFCell->SetHybridString( *pOUText );
             else
                 bDoIncrement = false;
+            pFCell->SetFormatType( nCellType );
             pFCell->ResetDirty();
         }
     }
@@ -789,7 +789,7 @@ void ScXMLTableRowCellContext::AddTextCellToDoc( const ScAddress& rCurrentPos,
 
 void ScXMLTableRowCellContext::AddNumberCellToDoc( const ScAddress& rCurrentPos )
 {
-    if( rXMLImport.GetTables().IsPartOfMatrix(rCurrentPos.Col(), rCurrentPos.Row()) )
+    if( rXMLImport.GetTables().IsPartOfMatrix(rCurrentPos) )
     {
         ScBaseCell* pCell = rXMLImport.GetDocument()->GetCell( rCurrentPos );
         if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
@@ -996,15 +996,6 @@ void ScXMLTableRowCellContext::AddNonFormulaCells( const ScAddress& rCellPos )
     }
 }
 
-namespace{
-
-bool isErrOrNA(const rtl::OUString& rStr)
-{
-    return (rStr.indexOf("Err:")  > -1) || (rStr.indexOf("#N/A") > -1);
-}
-
-}
-
 void ScXMLTableRowCellContext::AddNonMatrixFormulaCell( const ScAddress& rCellPos )
 {
     ScDocument* pDoc = rXMLImport.GetDocument();
@@ -1015,10 +1006,6 @@ void ScXMLTableRowCellContext::AddNonMatrixFormulaCell( const ScAddress& rCellPo
     ::boost::scoped_ptr<ScExternalRefManager::ApiGuard> pExtRefGuard;
     pExtRefGuard.reset(new ScExternalRefManager::ApiGuard(pDoc));
 
-    //if this is an "Err:###" or "#N/A" then use text:p value
-    if( bFormulaTextResult && pOUTextContent && isErrOrNA(*pOUTextContent) )
-        pOUTextValue.reset(*pOUTextContent);
-
     ScBaseCell* pNewCell = NULL;
 
     if ( !aText.isEmpty() )
@@ -1065,6 +1052,15 @@ void ScXMLTableRowCellContext::AddNonMatrixFormulaCell( const ScAddress& rCellPo
     }
 }
 
+namespace{
+
+bool isErrOrNA(const rtl::OUString& rStr)
+{
+    return (rStr.indexOf("Err:")  > -1) || (rStr.indexOf("#N/A") > -1);
+}
+
+}
+
 void ScXMLTableRowCellContext::AddFormulaCell( const ScAddress& rCellPos )
 {
     if( cellExists(rCellPos) )
@@ -1072,9 +1068,13 @@ void ScXMLTableRowCellContext::AddFormulaCell( const ScAddress& rCellPos )
         SetContentValidation( rCellPos );
         OSL_ENSURE(((nColsRepeated == 1) && (nRepeatedRows == 1)), "repeated cells with formula not possible now");
         rXMLImport.GetStylesImportHelper()->AddCell(rCellPos);
-        if (!bIsMatrix)
-            AddNonMatrixFormulaCell( rCellPos );
-        else
+
+        //if this is an "Err:###" or "#N/A" then use text:p value
+        if( bFormulaTextResult && pOUTextContent && isErrOrNA(*pOUTextContent) )
+            pOUTextValue.reset(*pOUTextContent);
+
+        //add matrix
+        if(bIsMatrix)
         {
             if (nMatrixCols > 0 && nMatrixRows > 0)
             {
@@ -1083,8 +1083,24 @@ void ScXMLTableRowCellContext::AddFormulaCell( const ScAddress& rCellPos )
                         rCellPos.Col() + nMatrixCols - 1,
                         rCellPos.Row() + nMatrixRows - 1,
                         pOUFormula->first, pOUFormula->second, eGrammar);
+
+                //add the cached formula result of the first matrix position
+                ScFormulaCell* pFCell =
+                    static_cast<ScFormulaCell*>( rXMLImport.GetDocument()->GetCell(rCellPos) );
+                if(pFCell)
+                {
+                    if( bFormulaTextResult && pOUTextValue && !pOUTextValue->isEmpty() )
+                        pFCell->SetHybridString( *pOUTextValue );
+                    else
+                        pFCell->SetHybridDouble( fValue );
+                    pFCell->SetFormatType( nCellType );
+                    pFCell->ResetDirty();
+                }
             }
         }
+        else
+            AddNonMatrixFormulaCell( rCellPos );
+
         SetAnnotation( rCellPos );
         SetDetectiveObj( rCellPos );
         SetCellRangeSource( rCellPos );
diff --git a/sc/source/filter/xml/xmlsubti.cxx b/sc/source/filter/xml/xmlsubti.cxx
index 7825bbf..c5a5eeb 100644
--- a/sc/source/filter/xml/xmlsubti.cxx
+++ b/sc/source/filter/xml/xmlsubti.cxx
@@ -207,18 +207,7 @@ void ScMyTables::DeleteTable()
     rImport.GetStylesImportHelper()->SetStylesToRanges();
     rImport.SetStylesToRangesFinished();
 
-    //#i48793#; has to be set before protection
-    if (!aMatrixRangeList.empty())
-    {
-        ScMyMatrixRangeList::iterator aItr = aMatrixRangeList.begin();
-        ScMyMatrixRangeList::iterator aEndItr = aMatrixRangeList.end();
-        while(aItr != aEndItr)
-        {
-            SetMatrix(aItr->aScRange, aItr->sFormula, aItr->sFormulaNmsp, aItr->eGrammar);
-            ++aItr;
-        }
-        aMatrixRangeList.clear();
-    }
+    maMatrixRangeList.RemoveAll();
 
     if (rImport.GetDocument() && maProtectionData.mbProtected)
     {
@@ -294,62 +283,30 @@ void ScMyTables::AddMatrixRange(
         nStartColumn, nStartRow, maCurrentCellPos.Tab(),
         nEndColumn, nEndRow, maCurrentCellPos.Tab()
     );
-    ScMatrixRange aMRange(aScRange, rFormula, rFormulaNmsp, eGrammar);
-    aMatrixRangeList.push_back(aMRange);
-}
 
-bool ScMyTables::IsPartOfMatrix(const SCCOL nColumn, const SCROW nRow)
-{
-    bool bResult(false);
-    if (!aMatrixRangeList.empty())
-    {
-        ScMyMatrixRangeList::iterator aItr(aMatrixRangeList.begin());
-        ScMyMatrixRangeList::iterator aEndItr(aMatrixRangeList.end());
-        bool bReady(false);
-        while(!bReady && aItr != aEndItr)
-        {
-            if (maCurrentCellPos.Tab() > aItr->aScRange.aStart.Tab())
-            {
-                OSL_FAIL("should never hapen, because the list should be cleared in DeleteTable");
-                aItr = aMatrixRangeList.erase(aItr);
-            }
-            else if ((nRow > aItr->aScRange.aEnd.Row()) && (nColumn > aItr->aScRange.aEnd.Col()))
-            {
-                SetMatrix(aItr->aScRange, aItr->sFormula, aItr->sFormulaNmsp, aItr->eGrammar);
-                aItr = aMatrixRangeList.erase(aItr);
-            }
-            else if (nColumn < aItr->aScRange.aStart.Col())
-                bReady = true;
-            else if ( nColumn >= aItr->aScRange.aStart.Col() && nColumn <= aItr->aScRange.aEnd.Col() &&
-                      nRow >= aItr->aScRange.aStart.Row() && nRow <= aItr->aScRange.aEnd.Row() )
-            {
-                bReady = true;
-                bResult = true;
-            }
-            else
-                ++aItr;
-        }
-    }
-    return bResult;
-}
+    maMatrixRangeList.Append(aScRange);
 
-void ScMyTables::SetMatrix(const ScRange& rScRange, const rtl::OUString& rFormula,
-        const rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar)
-{
     ScDocument* pDoc = rImport.GetDocument();
     ScMarkData aMark;
-    aMark.SetMarkArea( rScRange );
-    aMark.SelectTable( rScRange.aStart.Tab(), sal_True );
+    aMark.SetMarkArea( aScRange );
+    aMark.SelectTable( aScRange.aStart.Tab(), sal_True );
     ScTokenArray* pCode = new ScTokenArray;
     pCode->AddStringXML( rFormula );
     if( (eGrammar == formula::FormulaGrammar::GRAM_EXTERNAL) && !rFormulaNmsp.isEmpty() )
         pCode->AddStringXML( rFormulaNmsp );
     pDoc->InsertMatrixFormula(
-        rScRange.aStart.Col(), rScRange.aStart.Row(),
-        rScRange.aEnd.Col(), rScRange.aEnd.Row(),
+        aScRange.aStart.Col(), aScRange.aStart.Row(),
+        aScRange.aEnd.Col(), aScRange.aEnd.Row(),
         aMark, EMPTY_STRING, pCode, eGrammar );
     delete pCode;
     pDoc->IncXMLImportedFormulaCount( rFormula.getLength() );
 }
 
+bool ScMyTables::IsPartOfMatrix(const ScAddress& rScAddress) const
+{
+    if (!maMatrixRangeList.empty())
+        return maMatrixRangeList.In(rScAddress);
+    return false;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlsubti.hxx b/sc/source/filter/xml/xmlsubti.hxx
index 3f98af9..e080cfd 100644
--- a/sc/source/filter/xml/xmlsubti.hxx
+++ b/sc/source/filter/xml/xmlsubti.hxx
@@ -40,28 +40,10 @@
 #include "XMLTableShapeResizer.hxx"
 #include "formula/grammar.hxx"
 #include "tabprotection.hxx"
-
-#include <vector>
-#include <list>
-#include <boost/ptr_container/ptr_vector.hpp>
+#include "rangelst.hxx"
 
 class ScXMLImport;
 
-struct ScMatrixRange
-{
-    rtl::OUString sFormula;
-    rtl::OUString sFormulaNmsp;
-    formula::FormulaGrammar::Grammar eGrammar;
-    ScRange aScRange;
-    ScMatrixRange(const ScRange& rScRange, const rtl::OUString& rFormula, const rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammarP) :
-        sFormula(rFormula),
-        sFormulaNmsp(rFormulaNmsp),
-        eGrammar(eGrammarP),
-        aScRange(rScRange)
-    {
-    }
-};
-
 struct ScXMLTabProtectionData
 {
     ::rtl::OUString maPassword;
@@ -77,8 +59,6 @@ struct ScXMLTabProtectionData
 class ScMyTables
 {
 private:
-    typedef std::list<ScMatrixRange>    ScMyMatrixRangeList;
-
     ScXMLImport&                        rImport;
 
     ScMyOLEFixer                        aFixupOLEs;
@@ -89,8 +69,8 @@ private:
     ::com::sun::star::uno::Reference < ::com::sun::star::drawing::XShapes > xShapes;
     rtl::OUString                       sCurrentSheetName;
     ScAddress                           maCurrentCellPos;
+    ScRangeList                         maMatrixRangeList;
     ScXMLTabProtectionData              maProtectionData;
-    ScMyMatrixRangeList                 aMatrixRangeList;
     sal_Int32                           nCurrentColStylePos;
     sal_Int16                           nCurrentDrawPage;
     sal_Int16                           nCurrentXShapes;
@@ -132,18 +112,13 @@ public:
                                                const rtl::OUString &rRangeList);
 
     void                                AddMatrixRange( const SCCOL nStartColumn,
-                                                const SCROW nStartRow,
-                                                const SCCOL nEndColumn,
-                                                const SCROW nEndRow,
-                                                const rtl::OUString& rFormula,
-                                                const rtl::OUString& rFormulaNmsp,
-                                                const formula::FormulaGrammar::Grammar );
-
-    bool                                IsPartOfMatrix( const SCCOL nColumn, const SCROW nRow);
-    void                                SetMatrix( const ScRange& rScRange,
-                                                const rtl::OUString& rFormula,
-                                                const rtl::OUString& rFormulaNmsp,
-                                                const formula::FormulaGrammar::Grammar );
+                                            const SCROW nStartRow,
+                                            const SCCOL nEndColumn,
+                                            const SCROW nEndRow,
+                                            const rtl::OUString& rFormula,
+                                            const rtl::OUString& rFormulaNmsp,
+                                            const formula::FormulaGrammar::Grammar );
+    bool                                IsPartOfMatrix( const ScAddress& rScAddress) const;
 };
 
 #endif
commit e94b1331b1e2139e09bd0ef663394ede80f11be3
Author: Daniel Bankston <daniel.e.bankston at gmail.com>
Date:   Sat Jul 7 07:15:21 2012 -0500

    Use indexOf instead of match
    
    Change-Id: I2743929c3ba06ce1345d7217d9297515d2b5b2e4

diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx
index 59ca217..3da5996 100644
--- a/sc/source/filter/xml/xmlcelli.cxx
+++ b/sc/source/filter/xml/xmlcelli.cxx
@@ -996,6 +996,15 @@ void ScXMLTableRowCellContext::AddNonFormulaCells( const ScAddress& rCellPos )
     }
 }
 
+namespace{
+
+bool isErrOrNA(const rtl::OUString& rStr)
+{
+    return (rStr.indexOf("Err:")  > -1) || (rStr.indexOf("#N/A") > -1);
+}
+
+}
+
 void ScXMLTableRowCellContext::AddNonMatrixFormulaCell( const ScAddress& rCellPos )
 {
     ScDocument* pDoc = rXMLImport.GetDocument();
@@ -1007,8 +1016,7 @@ void ScXMLTableRowCellContext::AddNonMatrixFormulaCell( const ScAddress& rCellPo
     pExtRefGuard.reset(new ScExternalRefManager::ApiGuard(pDoc));
 
     //if this is an "Err:###" or "#N/A" then use text:p value
-    if( bFormulaTextResult && pOUTextContent &&
-        (pOUTextContent->match("Err:") || pOUTextContent->match("#N/A")) )
+    if( bFormulaTextResult && pOUTextContent && isErrOrNA(*pOUTextContent) )
         pOUTextValue.reset(*pOUTextContent);
 
     ScBaseCell* pNewCell = NULL;
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index 9e769de..752367c 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -429,10 +429,13 @@ sal_Bool ScDocShell::LoadXML( SfxMedium* pLoadMedium, const ::com::sun::star::un
     if ( nError )
         pLoadMedium->SetError( nError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
 
+    //if the document was not generated by LibreOffice, do hard recalc in case some other document
+    //generator saved cached formula results that differ from LibreOffice's calculated results or
+    //did not use cached formula results.
     uno::Reference<document::XDocumentPropertiesSupplier> xDPS(GetModel(), uno::UNO_QUERY_THROW);
     uno::Reference<document::XDocumentProperties> xDocProps = xDPS->getDocumentProperties();
     rtl::OUString sGenerator(xDocProps->getGenerator());
-    if(!sGenerator.match(SC_LIBO_PROD_NAME))
+    if(sGenerator.indexOf(SC_LIBO_PROD_NAME) == -1)
         DoHardRecalc(false);
 
     aDocument.SetXMLFromWrapper( false );
commit 5c5798878fd858183bd59b842ffa2ab79877cce5
Author: Daniel Bankston <daniel.e.bankston at gmail.com>
Date:   Fri Jul 6 22:30:54 2012 -0500

    Use text:p value if cached formula result is Err:### or #N/A
    
    This should be removed once we have export working correctly for
    function errors.
    
    Change-Id: Ibdd20478b458dd7849544ec90f32d754e3a71755

diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx
index 4c92ec7..59ca217 100644
--- a/sc/source/filter/xml/xmlcelli.cxx
+++ b/sc/source/filter/xml/xmlcelli.cxx
@@ -187,6 +187,11 @@ ScXMLTableRowCellContext::ScXMLTableRowCellContext( ScXMLImport& rImport,
                 {
                     ::sax::Converter::convertDouble(fValue, sValue);
                     bIsEmpty = false;
+
+                    //if office:value="0", treat like text in case the formula
+                    //result is "Err:###" or "#N/A" until we confirm otherwise
+                    if(fValue == 0.0)
+                        bFormulaTextResult = true;
                 }
             }
             break;
@@ -1001,6 +1006,11 @@ void ScXMLTableRowCellContext::AddNonMatrixFormulaCell( const ScAddress& rCellPo
     ::boost::scoped_ptr<ScExternalRefManager::ApiGuard> pExtRefGuard;
     pExtRefGuard.reset(new ScExternalRefManager::ApiGuard(pDoc));
 
+    //if this is an "Err:###" or "#N/A" then use text:p value
+    if( bFormulaTextResult && pOUTextContent &&
+        (pOUTextContent->match("Err:") || pOUTextContent->match("#N/A")) )
+        pOUTextValue.reset(*pOUTextContent);
+
     ScBaseCell* pNewCell = NULL;
 
     if ( !aText.isEmpty() )
commit 9c1cab31c7072079d50794f390c357c164447898
Author: Daniel Bankston <daniel.e.bankston at gmail.com>
Date:   Fri Jul 6 20:59:34 2012 -0500

    Set proper number format for formula cell
    
    Set proper number format for formula cell so that cached
    formula results are displayed properly.
    Example: so =NOT(1) will properly display as FALSE instead of as 0.
    
    Change-Id: Ifa4e3e83bc81779e34be385508da23a3b66c0a8c

diff --git a/sc/inc/cell.hxx b/sc/inc/cell.hxx
index f609a46..204e289 100644
--- a/sc/inc/cell.hxx
+++ b/sc/inc/cell.hxx
@@ -448,6 +448,7 @@ public:
     sal_uInt16      GetErrCode();   // interpret first if necessary
     sal_uInt16      GetRawError();  // don't interpret, just return code or result error
     short           GetFormatType() const                   { return nFormatType; }
+    void            SetFormatType( short nFType )           { nFormatType = nFType; }
     sal_uLong       GetFormatIndex() const                  { return nFormatIndex; }
     void            GetFormatInfo( short& nType, sal_uLong& nIndex ) const
                         { nType = nFormatType; nIndex = nFormatIndex; }
diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx
index efd2c99..4c92ec7 100644
--- a/sc/source/filter/xml/xmlcelli.cxx
+++ b/sc/source/filter/xml/xmlcelli.cxx
@@ -254,7 +254,6 @@ ScXMLTableRowCellContext::ScXMLTableRowCellContext( ScXMLImport& rImport,
     {
         if (nCellType == util::NumberFormat::TEXT)
             bFormulaTextResult = true;
-        nCellType = util::NumberFormat::UNDEFINED;
     }
     rXMLImport.GetStylesImportHelper()->SetAttributes(pStyleName, pCurrencySymbol, nCellType);
 }
@@ -1023,6 +1022,7 @@ void ScXMLTableRowCellContext::AddNonMatrixFormulaCell( const ScAddress& rCellPo
                 pFCell->SetHybridString( *pOUTextValue );
             else
                 pFCell->SetHybridDouble( fValue );
+            pFCell->SetFormatType( nCellType );
             pFCell->ResetDirty();
         }
         else if ( aText[0] == '\'' && aText.getLength() > 1 )
commit 5e92e0282691d54b7919e71041d6a9a09a495ec0
Author: Daniel Bankston <daniel.e.bankston at gmail.com>
Date:   Fri Jul 6 20:55:47 2012 -0500

    Add test for import of cached formula results (without hard-recalc)
    
    Change-Id: I7e73465d152332661f48e4dcd9ae28135821df68

diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx
index 7063046..ad89fd8 100644
--- a/sc/qa/unit/subsequent_filters-test.cxx
+++ b/sc/qa/unit/subsequent_filters-test.cxx
@@ -108,6 +108,7 @@ public:
     void testRangeNameXLSX();
     void testHardRecalcODS();
     void testFunctionsODS();
+    void testCachedFormulaResultsODS();
     void testDatabaseRangesODS();
     void testDatabaseRangesXLS();
     void testDatabaseRangesXLSX();
@@ -142,6 +143,7 @@ public:
     CPPUNIT_TEST(testRangeNameXLSX);
     CPPUNIT_TEST(testHardRecalcODS);
     CPPUNIT_TEST(testFunctionsODS);
+    CPPUNIT_TEST(testCachedFormulaResultsODS);
     CPPUNIT_TEST(testDatabaseRangesODS);
     CPPUNIT_TEST(testDatabaseRangesXLS);
     CPPUNIT_TEST(testDatabaseRangesXLSX);
@@ -359,6 +361,31 @@ void ScFiltersTest::testFunctionsODS()
     xDocSh->DoClose();
 }
 
+void ScFiltersTest::testCachedFormulaResultsODS()
+{
+    const rtl::OUString aFileNameBase(RTL_CONSTASCII_USTRINGPARAM("functions."));
+    ScDocShellRef xDocSh = loadDoc( aFileNameBase, ODS );
+
+    CPPUNIT_ASSERT_MESSAGE("Failed to load functions.*", xDocSh.Is());
+    ScDocument* pDoc = xDocSh->GetDocument();
+    rtl::OUString aCSVFileName;
+
+    //test cached formula results of logical functions
+    createCSVPath(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("logical-functions.")), aCSVFileName);
+    testFile(aCSVFileName, pDoc, 0);
+    //test cached formula results of spreadsheet functions
+    createCSVPath(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("spreadsheet-functions.")), aCSVFileName);
+    testFile(aCSVFileName, pDoc, 1);
+    //test cached formula results of mathematical functions
+    createCSVPath(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("mathematical-functions.")), aCSVFileName);
+    testFile(aCSVFileName, pDoc, 2, PureString);
+    //test cached formula results of informations functions
+    createCSVPath(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("information-functions.")), aCSVFileName);
+    testFile(aCSVFileName, pDoc, 3);
+
+    xDocSh->DoClose();
+}
+
 namespace {
 
 void testDBRanges_Impl(ScDocument* pDoc, sal_Int32 nFormat)
commit 04658a793d9d68ef910db746f7b88ac61ee43c1b
Author: Daniel Bankston <daniel.e.bankston at gmail.com>
Date:   Fri Jul 6 02:22:12 2012 -0500

    Add test for hard recalc
    
    Change-Id: I0fdbac47d6049d4a8b0b100eb1ce0fdab3eed262

diff --git a/sc/qa/unit/data/contentCSV/hard-recalc.csv b/sc/qa/unit/data/contentCSV/hard-recalc.csv
new file mode 100644
index 0000000..5d7a586
--- /dev/null
+++ b/sc/qa/unit/data/contentCSV/hard-recalc.csv
@@ -0,0 +1 @@
+2+2=,4
diff --git a/sc/qa/unit/data/ods/hard-recalc.ods b/sc/qa/unit/data/ods/hard-recalc.ods
new file mode 100644
index 0000000..970ba2c
Binary files /dev/null and b/sc/qa/unit/data/ods/hard-recalc.ods differ
diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx
index 2497bb0..7063046 100644
--- a/sc/qa/unit/subsequent_filters-test.cxx
+++ b/sc/qa/unit/subsequent_filters-test.cxx
@@ -106,6 +106,7 @@ public:
     //ods, xls, xlsx filter tests
     void testRangeNameXLS();
     void testRangeNameXLSX();
+    void testHardRecalcODS();
     void testFunctionsODS();
     void testDatabaseRangesODS();
     void testDatabaseRangesXLS();
@@ -139,6 +140,7 @@ public:
     CPPUNIT_TEST_SUITE(ScFiltersTest);
     CPPUNIT_TEST(testRangeNameXLS);
     CPPUNIT_TEST(testRangeNameXLSX);
+    CPPUNIT_TEST(testHardRecalcODS);
     CPPUNIT_TEST(testFunctionsODS);
     CPPUNIT_TEST(testDatabaseRangesODS);
     CPPUNIT_TEST(testDatabaseRangesXLS);
@@ -313,6 +315,24 @@ void ScFiltersTest::testRangeNameXLSX()
     xDocSh->DoClose();
 }
 
+void ScFiltersTest::testHardRecalcODS()
+{
+    const rtl::OUString aFileNameBase(RTL_CONSTASCII_USTRINGPARAM("hard-recalc."));
+    ScDocShellRef xDocSh = loadDoc( aFileNameBase, ODS );
+    xDocSh->DoHardRecalc(true);
+
+    CPPUNIT_ASSERT_MESSAGE("Failed to load functions.*", xDocSh.Is());
+    ScDocument* pDoc = xDocSh->GetDocument();
+    rtl::OUString aCSVFileName;
+
+    //test hard recalc: document has an incorrect cached formula result
+    //hard recalc should have updated to the correct result
+    createCSVPath(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("hard-recalc.")), aCSVFileName);
+    testFile(aCSVFileName, pDoc, 0);
+
+    xDocSh->DoClose();
+}
+
 void ScFiltersTest::testFunctionsODS()
 {
     const rtl::OUString aFileNameBase(RTL_CONSTASCII_USTRINGPARAM("functions."));
commit adaf0d9bf6b5f44c3e32c41fdaac4254a4a24263
Author: Daniel Bankston <daniel.e.bankston at gmail.com>
Date:   Fri Jul 6 02:04:28 2012 -0500

    Use bool instead of sal_uInt16 for HardCalcState
    
    Change-Id: Ia855780c28dc05e1606e8118fabd2a86bfcc5fa2

diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 72d5168..6d4a02e 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -340,7 +340,7 @@ private:
     sal_uInt16              nSrcVer;                        // file version (load/save)
     SCROW               nSrcMaxRow;                     // number of lines to load/save
     sal_uInt16              nFormulaTrackCount;
-    sal_uInt16              nHardRecalcState;               // 0: soft, 1: hard-warn, 2: hard
+    bool                bHardRecalcState;               // false: soft, true: hard
     SCTAB               nVisibleTab;                    // for OLE etc.
 
     ScLkUpdMode         eLinkMode;
@@ -1668,8 +1668,8 @@ public:
     sal_uInt16              GetFormulaTrackCount() const { return nFormulaTrackCount; }
     bool                IsInFormulaTree( ScFormulaCell* pCell ) const;
     bool                IsInFormulaTrack( ScFormulaCell* pCell ) const;
-    sal_uInt16              GetHardRecalcState() { return nHardRecalcState; }
-    void                SetHardRecalcState( sal_uInt16 nVal ) { nHardRecalcState = nVal; }
+    bool                GetHardRecalcState() { return bHardRecalcState; }
+    void                SetHardRecalcState( bool bVal ) { bHardRecalcState = bVal; }
     void                StartAllListeners();
     const ScFormulaCell*    GetFormulaTree() const { return pFormulaTree; }
     bool                HasForcedFormulas() const { return bHasForcedFormulas; }
diff --git a/sc/source/core/data/bcaslot.cxx b/sc/source/core/data/bcaslot.cxx
index 2d99ff4..b30a21e 100644
--- a/sc/source/core/data/bcaslot.cxx
+++ b/sc/source/core/data/bcaslot.cxx
@@ -151,8 +151,6 @@ bool ScBroadcastAreaSlot::CheckHardRecalcStateCondition() const
     {   // this is more hypothetical now, check existed for old SV_PTRARR_SORT
         if ( !pDoc->GetHardRecalcState() )
         {
-            pDoc->SetHardRecalcState( 1 );
-
             SfxObjectShell* pShell = pDoc->GetDocumentShell();
             OSL_ENSURE( pShell, "Missing DocShell :-/" );
 
@@ -160,7 +158,7 @@ bool ScBroadcastAreaSlot::CheckHardRecalcStateCondition() const
                 pShell->SetError( SCWARN_CORE_HARD_RECALC, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
 
             pDoc->SetAutoCalc( false );
-            pDoc->SetHardRecalcState( 2 );
+            pDoc->SetHardRecalcState( true );
         }
         return true;
     }
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index 2419859..6b3aa3c 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -173,7 +173,7 @@ ScDocument::ScDocument( ScDocumentMode  eMode,
         nSrcVer( SC_CURRENT_VERSION ),
         nSrcMaxRow( MAXROW ),
         nFormulaTrackCount(0),
-        nHardRecalcState(0),
+        bHardRecalcState(false),
         nVisibleTab( 0 ),
         eLinkMode(LM_UNKNOWN),
         bAutoCalc( eMode == SCDOCMODE_DOCUMENT ),
diff --git a/sc/source/core/data/documen7.cxx b/sc/source/core/data/documen7.cxx
index 818aa22..71bf25b 100644
--- a/sc/source/core/data/documen7.cxx
+++ b/sc/source/core/data/documen7.cxx
@@ -87,7 +87,7 @@ void ScDocument::Broadcast( const ScHint& rHint )
 {
     if ( !pBASM )
         return ;    // Clipboard or Undo
-    if ( !nHardRecalcState )
+    if ( !bHardRecalcState )
     {
         ScBulkBroadcast aBulkBroadcast( pBASM);     // scoped bulk broadcast
         bool bIsBroadcasted = false;
@@ -130,7 +130,7 @@ void ScDocument::AreaBroadcast( const ScHint& rHint )
 {
     if ( !pBASM )
         return ;    // Clipboard or Undo
-    if ( !nHardRecalcState )
+    if ( !bHardRecalcState )
     {
         ScBulkBroadcast aBulkBroadcast( pBASM);     // scoped bulk broadcast
         if ( pBASM->AreaBroadcast( rHint ) )
@@ -153,7 +153,7 @@ void ScDocument::AreaBroadcastInRange( const ScRange& rRange, const ScHint& rHin
 {
     if ( !pBASM )
         return ;    // Clipboard or Undo
-    if ( !nHardRecalcState )
+    if ( !bHardRecalcState )
     {
         ScBulkBroadcast aBulkBroadcast( pBASM);     // scoped bulk broadcast
         if ( pBASM->AreaBroadcastInRange( rRange, rHint ) )
@@ -295,7 +295,7 @@ void ScDocument::CalcFormulaTree( bool bOnlyForced, bool bNoProgress )
     //! _nicht_ SetAutoCalc( true ) weil das evtl. CalcFormulaTree( true )
     //! aufruft, wenn vorher disabled war und bHasForcedFormulas gesetzt ist
     bAutoCalc = true;
-    if ( nHardRecalcState )
+    if ( bHardRecalcState )
         CalcAll();
     else
     {
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index d604919..9e769de 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -365,12 +365,12 @@ void ScDocShell::AfterXMLLoading(sal_Bool bRet)
 
     if (pModificator)
     {
-        sal_uInt16 nRecalcState = aDocument.GetHardRecalcState();
+        bool bRecalcState = aDocument.GetHardRecalcState();
         //temporarily set hard-recalc to prevent calling ScFormulaCell::Notify()
         //which will set the cells dirty.
-        aDocument.SetHardRecalcState(2);
+        aDocument.SetHardRecalcState(true);
         delete pModificator;
-        aDocument.SetHardRecalcState(nRecalcState);
+        aDocument.SetHardRecalcState(bRecalcState);
         pModificator = NULL;
     }
     else
diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx
index 3680178..babda0d 100644
--- a/sc/source/ui/docshell/docsh4.cxx
+++ b/sc/source/ui/docshell/docsh4.cxx
@@ -1786,7 +1786,7 @@ void ScDocShell::GetState( SfxItemSet &rSet )
         switch (nWhich)
         {
             case FID_AUTO_CALC:
-                if ( (sal_Bool) aDocument.GetHardRecalcState() )
+                if ( aDocument.GetHardRecalcState() )
                     rSet.DisableItem( nWhich );
                 else
                     rSet.Put( SfxBoolItem( nWhich, aDocument.GetAutoCalc() ) );
commit f107e3a5f7cc19957435f1e90617105509394b4d
Author: Daniel Bankston <daniel.e.bankston at gmail.com>
Date:   Thu Jul 5 18:15:45 2012 -0500

    Use cached formula results instead of recalculating
    
    This commit undoes some of previous commit in attempt to be less "hackish".
    -When importing LibreOffice generated ODS documents, use cached formula
     results instead of always recalcuating.
    -For other generators, do hard-recalc.
    
    Still need to:
    -Stop matrix formula cells from being set dirty to avoid recalculating them.
    -Implement special cases for functions that should always be recalculated.
    
    Change-Id: I959872aa2f446b80f9204ee26e94de7140f1f6f9

diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index b5119e1..72d5168 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -366,7 +366,6 @@ private:
     bool                bInsertingFromOtherDoc;
     bool                bLoadingMedium;
     bool                bImportingXML;      // special handling of formula text
-    bool                bImportingLiboGenDoc; //to avoid recalculating formula results of libo generated docs
     bool                bXMLFromWrapper;    // distinguish ScXMLImportWrapper from external component
     bool                bCalcingAfterLoad;              // in CalcAfterLoad TRUE
     // don't construct/destruct listeners temporarily
@@ -1560,8 +1559,6 @@ public:
     void            SetLoadingMedium( bool bVal );
     void            SetImportingXML( bool bVal );
     bool            IsImportingXML() const { return bImportingXML; }
-    void            SetImportingLiboGenDoc( bool bVal ) { bImportingLiboGenDoc = bVal; };
-    bool            IsImportingLiboGenDoc() const { return bImportingLiboGenDoc; }
     void            SetXMLFromWrapper( bool bVal );
     bool            IsXMLFromWrapper() const { return bXMLFromWrapper; }
     void            SetCalcingAfterLoad( bool bVal ) { bCalcingAfterLoad = bVal; }
diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx
index e05cde7..c4846c0 100644
--- a/sc/source/core/data/cell.cxx
+++ b/sc/source/core/data/cell.cxx
@@ -1827,8 +1827,7 @@ void ScFormulaCell::SetDirty()
 
 void ScFormulaCell::SetDirtyVar()
 {
-    if(!pDocument->IsImportingLiboGenDoc())
-        bDirty = true;
+    bDirty = true;
     // mark the sheet of this cell to be calculated
     //#FIXME do we need to revert this remnant of old fake vba events? pDocument->AddCalculateTable( aPos.Tab() );
 }
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index 0921f20..2419859 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -188,7 +188,6 @@ ScDocument::ScDocument( ScDocumentMode  eMode,
         bInsertingFromOtherDoc( false ),
         bLoadingMedium( false ),
         bImportingXML( false ),
-        bImportingLiboGenDoc( false ),
         bXMLFromWrapper( false ),
         bCalcingAfterLoad( false ),
         bNoListening( false ),
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 965f09c..f3724d5 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -3410,7 +3410,6 @@ void ScDocument::CompileXML()
     if ( pValidationList )
         pValidationList->CompileXML();
 
-    SetDirty();
     SetAutoCalc( bOldAutoCalc );
 }
 
diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx
index 1553542..efd2c99 100644
--- a/sc/source/filter/xml/xmlcelli.cxx
+++ b/sc/source/filter/xml/xmlcelli.cxx
@@ -757,8 +757,7 @@ void ScXMLTableRowCellContext::AddTextCellToDoc( const ScAddress& rCurrentPos,
                 pFCell->SetHybridString( *pOUText );
             else
                 bDoIncrement = false;
-            if(rXMLImport.GetDocument()->IsImportingLiboGenDoc())
-                pFCell->ResetDirty();
+            pFCell->ResetDirty();
         }
     }
     else
@@ -793,8 +792,7 @@ void ScXMLTableRowCellContext::AddNumberCellToDoc( const ScAddress& rCurrentPos
         {
             ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);
             pFCell->SetHybridDouble( fValue );
-            if(rXMLImport.GetDocument()->IsImportingLiboGenDoc())
-                pFCell->ResetDirty();
+            pFCell->ResetDirty();
         }
     }
     else
@@ -1025,8 +1023,7 @@ void ScXMLTableRowCellContext::AddNonMatrixFormulaCell( const ScAddress& rCellPo
                 pFCell->SetHybridString( *pOUTextValue );
             else
                 pFCell->SetHybridDouble( fValue );
-            if(pDoc->IsImportingLiboGenDoc())
-                pFCell->ResetDirty();
+            pFCell->ResetDirty();
         }
         else if ( aText[0] == '\'' && aText.getLength() > 1 )
         {
diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx
index 5082f3b..c3e3cd7 100644
--- a/sc/source/filter/xml/xmlimprt.cxx
+++ b/sc/source/filter/xml/xmlimprt.cxx
@@ -52,6 +52,7 @@
 
 #include "xmlimprt.hxx"
 #include "document.hxx"
+#include "docsh.hxx"
 #include "docuno.hxx"
 #include "nameuno.hxx"
 #include "xmlbodyi.hxx"
@@ -99,7 +100,6 @@
 #define SC_REPEAT_ROW "repeat-row"
 #define SC_FILTER "filter"
 #define SC_PRINT_RANGE "print-range"
-#define SC_LIBO_PROD_NAME "LibreOffice"
 
 using namespace com::sun::star;
 using namespace ::xmloff::token;
@@ -2811,12 +2811,6 @@ throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::R
         xActionLockable->addActionLock();
 
     pDoc->EnableAdjustHeight(false);
-
-     uno::Reference<document::XDocumentPropertiesSupplier> xDPS(GetModel(), uno::UNO_QUERY_THROW);
-     uno::Reference<document::XDocumentProperties> xDocProps = xDPS->getDocumentProperties();
-     rtl::OUString sGenerator(xDocProps->getGenerator());
-     if(sGenerator.match(SC_LIBO_PROD_NAME))
-        pDoc->SetImportingLiboGenDoc(true);
 }
 
 // XServiceInfo
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index 528ad18..d604919 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -116,6 +116,8 @@
 #include <vector>
 #include <boost/shared_ptr.hpp>
 
+#define SC_LIBO_PROD_NAME "LibreOffice"
+
 using namespace com::sun::star;
 using ::com::sun::star::uno::Reference;
 using ::com::sun::star::uno::UNO_QUERY;
@@ -363,7 +365,12 @@ void ScDocShell::AfterXMLLoading(sal_Bool bRet)
 
     if (pModificator)
     {
+        sal_uInt16 nRecalcState = aDocument.GetHardRecalcState();
+        //temporarily set hard-recalc to prevent calling ScFormulaCell::Notify()
+        //which will set the cells dirty.
+        aDocument.SetHardRecalcState(2);
         delete pModificator;
+        aDocument.SetHardRecalcState(nRecalcState);
         pModificator = NULL;
     }
     else
@@ -422,9 +429,14 @@ sal_Bool ScDocShell::LoadXML( SfxMedium* pLoadMedium, const ::com::sun::star::un
     if ( nError )
         pLoadMedium->SetError( nError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
 
+    uno::Reference<document::XDocumentPropertiesSupplier> xDPS(GetModel(), uno::UNO_QUERY_THROW);
+    uno::Reference<document::XDocumentProperties> xDocProps = xDPS->getDocumentProperties();
+    rtl::OUString sGenerator(xDocProps->getGenerator());
+    if(!sGenerator.match(SC_LIBO_PROD_NAME))
+        DoHardRecalc(false);
+
     aDocument.SetXMLFromWrapper( false );
     AfterXMLLoading(bRet);
-    aDocument.SetImportingLiboGenDoc(false);
     //! row heights...
 
     return bRet;
commit 1cdfb19c2202b56e4de6f10104bb4841372956cb
Author: Daniel Bankston <daniel.e.bankston at gmail.com>
Date:   Tue Jul 3 03:06:29 2012 -0500

    Use imported formula results if ODS doc was generated by LibreOffice
    
    During ODS import, use imported formula results instead of recalculating if
    the document was generated by LibreOffice.
    Still need to implement recalculating special cases such as NOW().
    
    Change-Id: Ia54690224dc0d8f74b93cafd8d01b072e85c7416

diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 72d5168..b5119e1 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -366,6 +366,7 @@ private:
     bool                bInsertingFromOtherDoc;
     bool                bLoadingMedium;
     bool                bImportingXML;      // special handling of formula text
+    bool                bImportingLiboGenDoc; //to avoid recalculating formula results of libo generated docs
     bool                bXMLFromWrapper;    // distinguish ScXMLImportWrapper from external component
     bool                bCalcingAfterLoad;              // in CalcAfterLoad TRUE
     // don't construct/destruct listeners temporarily
@@ -1559,6 +1560,8 @@ public:
     void            SetLoadingMedium( bool bVal );
     void            SetImportingXML( bool bVal );
     bool            IsImportingXML() const { return bImportingXML; }
+    void            SetImportingLiboGenDoc( bool bVal ) { bImportingLiboGenDoc = bVal; };
+    bool            IsImportingLiboGenDoc() const { return bImportingLiboGenDoc; }
     void            SetXMLFromWrapper( bool bVal );
     bool            IsXMLFromWrapper() const { return bXMLFromWrapper; }
     void            SetCalcingAfterLoad( bool bVal ) { bCalcingAfterLoad = bVal; }
diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx
index c4846c0..e05cde7 100644
--- a/sc/source/core/data/cell.cxx
+++ b/sc/source/core/data/cell.cxx
@@ -1827,7 +1827,8 @@ void ScFormulaCell::SetDirty()
 
 void ScFormulaCell::SetDirtyVar()
 {
-    bDirty = true;
+    if(!pDocument->IsImportingLiboGenDoc())
+        bDirty = true;
     // mark the sheet of this cell to be calculated
     //#FIXME do we need to revert this remnant of old fake vba events? pDocument->AddCalculateTable( aPos.Tab() );
 }
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index 2419859..0921f20 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -188,6 +188,7 @@ ScDocument::ScDocument( ScDocumentMode  eMode,
         bInsertingFromOtherDoc( false ),
         bLoadingMedium( false ),
         bImportingXML( false ),
+        bImportingLiboGenDoc( false ),
         bXMLFromWrapper( false ),
         bCalcingAfterLoad( false ),
         bNoListening( false ),
diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx
index 87614e4..1553542 100644
--- a/sc/source/filter/xml/xmlcelli.cxx
+++ b/sc/source/filter/xml/xmlcelli.cxx
@@ -757,6 +757,8 @@ void ScXMLTableRowCellContext::AddTextCellToDoc( const ScAddress& rCurrentPos,
                 pFCell->SetHybridString( *pOUText );
             else
                 bDoIncrement = false;
+            if(rXMLImport.GetDocument()->IsImportingLiboGenDoc())
+                pFCell->ResetDirty();
         }
     }
     else
@@ -788,7 +790,12 @@ void ScXMLTableRowCellContext::AddNumberCellToDoc( const ScAddress& rCurrentPos
     {
         ScBaseCell* pCell = rXMLImport.GetDocument()->GetCell( rCurrentPos );
         if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
-            static_cast<ScFormulaCell*>(pCell)->SetHybridDouble( fValue );
+        {
+            ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);
+            pFCell->SetHybridDouble( fValue );
+            if(rXMLImport.GetDocument()->IsImportingLiboGenDoc())
+                pFCell->ResetDirty();
+        }
     }
     else
     {
@@ -1013,10 +1020,13 @@ void ScXMLTableRowCellContext::AddNonMatrixFormulaCell( const ScAddress& rCellPo
             pNewCell = new ScFormulaCell( pDoc, rCellPos, pCode, eGrammar, MM_NONE );
             delete pCode;
 
+            ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pNewCell);
             if( bFormulaTextResult && pOUTextValue && !pOUTextValue->isEmpty() )
-                static_cast<ScFormulaCell*>(pNewCell)->SetHybridString( *pOUTextValue );
+                pFCell->SetHybridString( *pOUTextValue );
             else
-                static_cast<ScFormulaCell*>(pNewCell)->SetHybridDouble( fValue );
+                pFCell->SetHybridDouble( fValue );
+            if(pDoc->IsImportingLiboGenDoc())
+                pFCell->ResetDirty();
         }
         else if ( aText[0] == '\'' && aText.getLength() > 1 )
         {
@@ -1036,7 +1046,6 @@ void ScXMLTableRowCellContext::AddNonMatrixFormulaCell( const ScAddress& rCellPo
             else
                 pNewCell = ScBaseCell::CreateTextCell( aText, pDoc );
         }
-
         pDoc->PutCell( rCellPos, pNewCell );
     }
 }
diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx
index 4ab81b8..5082f3b 100644
--- a/sc/source/filter/xml/xmlimprt.cxx
+++ b/sc/source/filter/xml/xmlimprt.cxx
@@ -99,6 +99,7 @@
 #define SC_REPEAT_ROW "repeat-row"
 #define SC_FILTER "filter"
 #define SC_PRINT_RANGE "print-range"
+#define SC_LIBO_PROD_NAME "LibreOffice"
 
 using namespace com::sun::star;
 using namespace ::xmloff::token;
@@ -2808,7 +2809,14 @@ throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::R
     uno::Reference<document::XActionLockable> xActionLockable(xDoc, uno::UNO_QUERY);
     if (xActionLockable.is())
         xActionLockable->addActionLock();
+
     pDoc->EnableAdjustHeight(false);
+
+     uno::Reference<document::XDocumentPropertiesSupplier> xDPS(GetModel(), uno::UNO_QUERY_THROW);
+     uno::Reference<document::XDocumentProperties> xDocProps = xDPS->getDocumentProperties();
+     rtl::OUString sGenerator(xDocProps->getGenerator());
+     if(sGenerator.match(SC_LIBO_PROD_NAME))
+        pDoc->SetImportingLiboGenDoc(true);
 }
 
 // XServiceInfo
@@ -3112,10 +3120,8 @@ throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeE
     }
     SvXMLImport::endDocument();
 
-    if (pDoc && bSelfImportingXMLSet)
-    {
+    if(pDoc && bSelfImportingXMLSet)
         ScModelObj::getImplementation(GetModel())->AfterXMLLoading(true);
-    }
 }
 
 // XEventListener
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index f0f7ff4..528ad18 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -424,7 +424,7 @@ sal_Bool ScDocShell::LoadXML( SfxMedium* pLoadMedium, const ::com::sun::star::un
 
     aDocument.SetXMLFromWrapper( false );
     AfterXMLLoading(bRet);
-
+    aDocument.SetImportingLiboGenDoc(false);
     //! row heights...
 
     return bRet;
commit f069fca63ffe38f745a311e69e1b2b3131abeb95
Author: Daniel Bankston <daniel.e.bankston at gmail.com>
Date:   Mon Jul 2 13:36:36 2012 -0500

    Improve performance of data validity unit test
    
    - Now using OStringBuffer instead of OString for multiple appends.
    - Simplified logic.
    
    Change-Id: I991c3e538439d68e242a7f97bab9c2d82631467e

diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx
index 37aa7e7..2497bb0 100644
--- a/sc/qa/unit/subsequent_filters-test.cxx
+++ b/sc/qa/unit/subsequent_filters-test.cxx
@@ -825,31 +825,24 @@ void checkValiditationEntries( const ValDataTestParams& rVDTParams )
     //get actual data validation entry from document
     const ScValidationData* pValDataTest = pDoc->GetValidationEntry( rVDTParams.nExpectedIndex );
 
-    rtl::OString sCol( rtl::OString::valueOf(static_cast<sal_Int32>(rVDTParams.aPosition.Col())) );
-    rtl::OString sRow( rtl::OString::valueOf(static_cast<sal_Int32>(rVDTParams.aPosition.Row())) );
-    rtl::OString sTab( rtl::OString::valueOf(static_cast<sal_Int32>(rVDTParams.aPosition.Tab())) );
-    rtl::OString msg( "Data Validation Entry with base-cell-address: (" +
-                       sCol + "," + sRow + "," + sTab + ") was not imported correctly." );
+    sal_Int32 nCol( static_cast<sal_Int32>(rVDTParams.aPosition.Col()) );
+    sal_Int32 nRow( static_cast<sal_Int32>(rVDTParams.aPosition.Row()) );
+    sal_Int32 nTab( static_cast<sal_Int32>(rVDTParams.aPosition.Tab()) );
+    rtl::OStringBuffer sMsg("Data Validation Entry with base-cell-address: (");
+    sMsg.append(nCol).append(",").append(nRow).append(",").append(nTab).append(") was not imported correctly.");
     //check if expected and actual data validation entries are equal
-    CPPUNIT_ASSERT_MESSAGE( msg.pData->buffer, pValDataTest && aValData.EqualEntries(*pValDataTest) );
+    CPPUNIT_ASSERT_MESSAGE( sMsg.getStr(), pValDataTest && aValData.EqualEntries(*pValDataTest) );
 }
 
-bool checkCellValidity( const ScAddress& rValBaseAddr, const ScRange& rRange, const ScDocument* pDoc, rtl::OString& sMsg )
+void checkCellValidity( const ScAddress& rValBaseAddr, const ScRange& rRange, const ScDocument* pDoc )
 {
     SCCOL nBCol( rValBaseAddr.Col() );
-    SCTAB nBRow( rValBaseAddr.Row() );
-    SCTAB nTab( rValBaseAddr.Tab() );
+    SCROW nBRow( rValBaseAddr.Row() );
+    SCTAB nTab( static_cast<const sal_Int32>(rValBaseAddr.Tab()) );
     //get from the document the data validation entry we are checking against
     const SfxUInt32Item* pItem = static_cast<const SfxUInt32Item*>(pDoc->GetAttr(nBCol, nBRow, nTab, ATTR_VALIDDATA) );
     const ScValidationData* pValData = pDoc->GetValidationEntry( pItem->GetValue() );
 
-    rtl::OString sCol, sRow;
-    rtl::OString sBCol = rtl::OString::valueOf(static_cast<sal_Int32>(nBCol));
-    rtl::OString sBRow = rtl::OString::valueOf(static_cast<sal_Int32>(nBRow));
-    rtl::OString sTab = rtl::OString::valueOf(static_cast<sal_Int32>(nTab));
-    sMsg += "\nThe following cells failed to reference the data validation entry with base-cell-address: (" +
-            sBCol + "," + sBRow + "," + sTab + ")\n";
-    bool bPassed = true;
     //check that each cell in the expected range is associated with the data validation entry
     for(SCCOL i = rRange.aStart.Col(); i <= rRange.aEnd.Col(); ++i)
     {
@@ -857,27 +850,25 @@ bool checkCellValidity( const ScAddress& rValBaseAddr, const ScRange& rRange, co
         {
             const SfxUInt32Item* pItemTest = static_cast<const SfxUInt32Item*>( pDoc->GetAttr(i, j, nTab, ATTR_VALIDDATA) );
             const ScValidationData* pValDataTest = pDoc->GetValidationEntry( pItemTest->GetValue() );
-
-            sCol = rtl::OString::valueOf(static_cast<sal_Int32>(i));
-            sRow = rtl::OString::valueOf(static_cast<sal_Int32>(j));
+            //prevent string operations for occurring unnecessarily
             if(!(pValDataTest && pValData->GetKey() == pValDataTest->GetKey()))
             {
-                bPassed = false;
-                rtl::OString sEntryKey = rtl::OString::valueOf(static_cast<sal_Int32>(pValData->GetKey()));
-                sMsg += "(" + sCol + "," + sRow + "," + sTab + "), expected key: " + sEntryKey + ", actual key: ";
+                sal_Int32 nCol = static_cast<const sal_Int32>(i);
+                sal_Int32 nRow = static_cast<const sal_Int32>(j);
+                sal_Int32 nTab32 = static_cast<const sal_Int32>(nTab);
+                rtl::OStringBuffer sMsg("\nData validation entry base-cell-address: (");
+                sMsg.append( static_cast<const sal_Int32>(nBCol) ).append(",");
+                sMsg.append( static_cast<const sal_Int32>(nBRow) ).append(",");
+                sMsg.append( nTab32 ).append(")\n");
+                sMsg.append("Cell: (").append(nCol).append(",").append(nRow).append(",").append(nTab32).append(")");
+                sal_uInt32 expectedKey(pValData->GetKey());
+                sal_uInt32 actualKey(-1);
                 if(pValDataTest)
-                {
-                    rtl::OString sTestKey = rtl::OString::valueOf(static_cast<sal_Int32>(pValDataTest->GetKey()));
-                    sMsg += sTestKey;
-                }
-                else sMsg += "none";
-                sMsg += "\n";
+                    actualKey = pValDataTest->GetKey();
+                CPPUNIT_ASSERT_EQUAL_MESSAGE(sMsg.getStr(), expectedKey, actualKey);
             }
         }
     }
-    if(bPassed) sMsg += "None failed.\n";
-    sMsg += "\n";
-    return bPassed;
 }
 
 }
@@ -902,7 +893,7 @@ void ScFiltersTest::testDataValidityODS()
     //sheet2's expected Data Validation Entry values
     ValDataTestParams aVDTParams2(
         SC_VALID_WHOLE, SC_COND_BETWEEN, String("1"), String("10"), pDoc,
-        ScAddress(2,3,1), String("Error sheet 2"),
+        aValBaseAddr2, String("Error sheet 2"),
         String("Must be a whole number between 1 and 10."),
         SC_VALERR_STOP, 2
     );
@@ -915,10 +906,8 @@ void ScFiltersTest::testDataValidityODS()
     ScRange aRange2( 2,3,1, 6,7,1 ); //sheet2
 
     //check each sheet's cells for data validity
-    rtl::OString sMsg;
-    bool bPassed1 = checkCellValidity( aValBaseAddr1, aRange1, pDoc, sMsg );
-    bool bPassed2 = checkCellValidity( aValBaseAddr2, aRange2, pDoc, sMsg );
-    CPPUNIT_ASSERT_MESSAGE( sMsg.pData->buffer, bPassed1 && bPassed2 );
+    checkCellValidity( aValBaseAddr1, aRange1, pDoc );
+    checkCellValidity( aValBaseAddr2, aRange2, pDoc );
 
     //check each sheet's content
     rtl::OUString aCSVFileName1;
commit cd2f8a1cabbfb924c62d7af2aac3ac09288c2d4c
Author: Daniel Bankston <daniel.e.bankston at gmail.com>
Date:   Mon Jun 25 01:21:26 2012 -0500

    Stop calculating row heights and instead use imported row heights only
    
    Change-Id: I1a5e33c292fb915e61511efbdb9ce4a0cfd7265f

diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx
index 01e1d1c..4ab81b8 100644
--- a/sc/source/filter/xml/xmlimprt.cxx
+++ b/sc/source/filter/xml/xmlimprt.cxx
@@ -2808,6 +2808,7 @@ throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::R
     uno::Reference<document::XActionLockable> xActionLockable(xDoc, uno::UNO_QUERY);
     if (xActionLockable.is())
         xActionLockable->addActionLock();
+    pDoc->EnableAdjustHeight(false);
 }
 
 // XServiceInfo
@@ -3101,8 +3102,6 @@ throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeE
                 if (!pSheetData->IsSheetBlocked( nTab ))
                     pDoc->SetStreamValid( nTab, true );
         }
-
-        aTables.UpdateRowHeights();
         aTables.FixupOLEs();
     }
     if (GetModel().is())
diff --git a/sc/source/filter/xml/xmlsubti.cxx b/sc/source/filter/xml/xmlsubti.cxx
index 662f278..7825bbf 100644
--- a/sc/source/filter/xml/xmlsubti.cxx
+++ b/sc/source/filter/xml/xmlsubti.cxx
@@ -200,48 +200,6 @@ void ScMyTables::AddColumn(bool bIsCovered)
         rImport.GetStylesImportHelper()->InsertCol(maCurrentCellPos.Col(), maCurrentCellPos.Tab(), rImport.GetDocument());
 }
 
-void ScMyTables::UpdateRowHeights()
-{
-    if (rImport.GetModel().is())
-    {
-        ScXMLImport::MutexGuard aGuard(rImport);
-
-        // update automatic row heights
-
-        // For sheets with any kind of shapes (including notes),
-        // update row heights immediately (before setting the positions).
-        // For sheets without shapes, set "pending" flag
-        // and update row heights when a sheet is shown.
-        // The current sheet (from view settings) is always updated immediately.
-
-        ScDocument* pDoc = ScXMLConverter::GetScDocument(rImport.GetModel());
-        if (pDoc)
-        {
-            SCTAB nCount = pDoc->GetTableCount();
-            ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
-
-            SCTAB nVisible = rImport.GetVisibleSheet();
-
-            ScMarkData aUpdateSheets;
-            for (SCTAB nTab=0; nTab<nCount; ++nTab)
-            {
-                const SdrPage* pPage = pDrawLayer ? pDrawLayer->GetPage(nTab) : NULL;
-                if ( nTab == nVisible || ( pPage && pPage->GetObjCount() != 0 ) )
-                    aUpdateSheets.SelectTable( nTab, true );
-                else
-                    pDoc->SetPendingRowHeights( nTab, true );
-            }
-
-            if (aUpdateSheets.GetSelectCount())
-            {
-                pDoc->LockStreamValid( true );      // ignore draw page size (but not formula results)
-                ScModelObj::getImplementation(rImport.GetModel())->UpdateAllRowHeights(&aUpdateSheets);
-                pDoc->LockStreamValid( false );
-            }
-        }
-    }
-}
-
 void ScMyTables::DeleteTable()
 {
     ScXMLImport::MutexGuard aGuard(rImport);
diff --git a/sc/source/filter/xml/xmlsubti.hxx b/sc/source/filter/xml/xmlsubti.hxx
index 971cb69..3f98af9 100644
--- a/sc/source/filter/xml/xmlsubti.hxx
+++ b/sc/source/filter/xml/xmlsubti.hxx
@@ -107,7 +107,6 @@ public:
     void                                AddRow();
     void                                SetRowStyle(const rtl::OUString& rCellStyleName);
     void                                AddColumn(bool bIsCovered);
-    void                                UpdateRowHeights();
     void                                FixupOLEs() { aFixupOLEs.FixupOLEs(); }
     bool                                IsOLE(com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& rShape) const
                                             { return ScMyOLEFixer::IsOLE(rShape); }
commit 40732062925db3dff78e8c2d1612e403cb8463f6
Author: Daniel Bankston <daniel.e.bankston at gmail.com>
Date:   Fri Jun 22 23:53:25 2012 -0500

    Add unit test for ODS row height import
    
    Change-Id: If8535f80d2f2cd57132d9d694d6bb2535df31c80

diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx
index 60264b9..37aa7e7 100644
--- a/sc/qa/unit/subsequent_filters-test.cxx
+++ b/sc/qa/unit/subsequent_filters-test.cxx
@@ -460,8 +460,10 @@ void testFormats_Impl(ScFiltersTest* pFiltersTest, ScDocument* pDoc, sal_Int32 n
         pPattern = pDoc->GetPattern(1,3,1);
         pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
         CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be underlined with a dotted line", UNDERLINE_DOTTED, aFont.GetUnderline());
-        //test case for proper import height of first row with styles and text (related to i53253)
-        CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(253), pDoc->GetRowHeight(0,1) );
+        //check row height import
+        CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(256), pDoc->GetRowHeight(0,1) ); //0.178in
+        CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(304), pDoc->GetRowHeight(1,1) ); //0.211in
+        CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(477), pDoc->GetRowHeight(5,1) ); //0.3311in
         //test case for i53253 where a cell has text with different styles and space between the text.
         rtl::OUString aTestStr;
         pDoc->GetString(3,0,1, aTestStr);
commit d40e653425fe04dcaf913c18ce9f9da39e62529d
Author: Daniel Bankston <daniel.e.bankston at gmail.com>
Date:   Thu Jun 21 00:32:19 2012 -0500

    Change sc subseq unit tests to use more appropriate cppunit assert macros
    
    -Changed where appropriate to use CPPUNIT_ASSERT_EQUAL_MESSAGE or
    CPPUNIT_ASSERT_EQUAL instead of always using CPPUNIT_ASSERT_MESSAGE.
    
    Change-Id: I1855b1b382f39f811905e18a8f24fb34a481031f

diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx
index 2fab37a..60264b9 100644
--- a/sc/qa/unit/subsequent_filters-test.cxx
+++ b/sc/qa/unit/subsequent_filters-test.cxx
@@ -261,24 +261,24 @@ void testRangeNameImpl(ScDocument* pDoc)
     CPPUNIT_ASSERT_MESSAGE("range name Global1 not found", pRangeData);
     double aValue;
     pDoc->GetValue(1,0,0,aValue);
-    CPPUNIT_ASSERT_MESSAGE("range name Global1 should reference Sheet1.A1", aValue == 1);
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("range name Global1 should reference Sheet1.A1", 1.0, aValue);
     pRangeData = pDoc->GetRangeName(0)->findByUpperName(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("LOCAL1")));
     CPPUNIT_ASSERT_MESSAGE("range name Sheet1.Local1 not found", pRangeData);
     pDoc->GetValue(1,2,0,aValue);
-    CPPUNIT_ASSERT_MESSAGE("range name Sheet1.Local1 should reference Sheet1.A3", aValue == 3);
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("range name Sheet1.Local1 should reference Sheet1.A3", 3.0, aValue);
     pRangeData = pDoc->GetRangeName(1)->findByUpperName(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("LOCAL2")));
     CPPUNIT_ASSERT_MESSAGE("range name Sheet2.Local2 not found", pRangeData);
     pDoc->GetValue(1,1,1,aValue);
-    CPPUNIT_ASSERT_MESSAGE("range name Sheet2.Local2 should reference Sheet2.A2", aValue == 7);
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("range name Sheet2.Local2 should reference Sheet2.A2", 7.0, aValue);
     //check for correct results for the remaining formulas
     pDoc->GetValue(1,1,0, aValue);
-    CPPUNIT_ASSERT_MESSAGE("=global2 should be 2", aValue == 2);
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("=global2 should be 2", 2.0, aValue);
     pDoc->GetValue(1,3,0, aValue);
-    CPPUNIT_ASSERT_MESSAGE("=local2 should be 4", aValue == 4);
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("=local2 should be 4", 4.0, aValue);
     pDoc->GetValue(2,0,0, aValue);
-    CPPUNIT_ASSERT_MESSAGE("=SUM(global3) should be 10", aValue == 10);
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("=SUM(global3) should be 10", 10.0, aValue);
     pDoc->GetValue(1,0,1,aValue);
-    CPPUNIT_ASSERT_MESSAGE("range name Sheet2.local1 should reference Sheet1.A5", aValue == 5);
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("range name Sheet2.local1 should reference Sheet1.A5", 5.0, aValue);
 }
 
 }
@@ -366,16 +366,16 @@ void testDBRanges_Impl(ScDocument* pDoc, sal_Int32 nFormat)
         double aValue;
         pDoc->GetValue(0,10,1, aValue);
         rtl::OUString aString;
-        CPPUNIT_ASSERT_MESSAGE("Sheet2: A11: formula result is incorrect", aValue == 4);
+        CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet2: A11: formula result is incorrect", 4.0, aValue);
         pDoc->GetValue(1, 10, 1, aValue);
-        CPPUNIT_ASSERT_MESSAGE("Sheet2: B11: formula result is incorrect", aValue == 2);
+        CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet2: B11: formula result is incorrect", 2.0, aValue);
     }
     double aValue;
     pDoc->GetValue(3,10,1, aValue);
     rtl::OUString aString;
-    CPPUNIT_ASSERT_MESSAGE("Sheet2: D11: formula result is incorrect", aValue == 4);
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet2: D11: formula result is incorrect", 4.0, aValue);
     pDoc->GetValue(4, 10, 1, aValue);
-    CPPUNIT_ASSERT_MESSAGE("Sheet2: E11: formula result is incorrect", aValue == 2);
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet2: E11: formula result is incorrect", 2.0, aValue);
 
 }
 
@@ -434,67 +434,57 @@ void testFormats_Impl(ScFiltersTest* pFiltersTest, ScDocument* pDoc, sal_Int32 n
     pPattern = pDoc->GetPattern(0,0,1);
     Font aFont;
     pPattern->GetFont(aFont,SC_AUTOCOL_RAW);
-    CPPUNIT_ASSERT_MESSAGE("font size should be 10", aFont.GetSize().getHeight() == 200);
-    CPPUNIT_ASSERT_MESSAGE("font color should be black", aFont.GetColor() == COL_AUTO);
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("font size should be 10", 200l, aFont.GetSize().getHeight());
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("font color should be black", COL_AUTO, aFont.GetColor().GetColor());
     pPattern = pDoc->GetPattern(0,1,1);
     pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
-    CPPUNIT_ASSERT_MESSAGE("font size should be 12", aFont.GetSize().getHeight() == 240);
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("font size should be 12", 240l, aFont.GetSize().getHeight());
     pPattern = pDoc->GetPattern(0,2,1);
     pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
-    CPPUNIT_ASSERT_MESSAGE("font should be italic",aFont.GetItalic() == ITALIC_NORMAL);
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be italic", ITALIC_NORMAL, aFont.GetItalic());
     pPattern = pDoc->GetPattern(0,4,1);
     pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
-    CPPUNIT_ASSERT_MESSAGE("font should be bold",aFont.GetWeight() == WEIGHT_BOLD );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be bold", WEIGHT_BOLD, aFont.GetWeight());
     pPattern = pDoc->GetPattern(1,0,1);
     pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
-    CPPUNIT_ASSERT_MESSAGE("font should be blue", aFont.GetColor() == COL_BLUE );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be blue", COL_BLUE, aFont.GetColor().GetColor());
     pPattern = pDoc->GetPattern(1,1,1);
     pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
-    CPPUNIT_ASSERT_MESSAGE("font should be striked out with a single line", aFont.GetStrikeout() == STRIKEOUT_SINGLE );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be striked out with a single line", STRIKEOUT_SINGLE, aFont.GetStrikeout());
     //some tests on sheet2 only for ods
     if (nFormat == ODS)
     {
         pPattern = pDoc->GetPattern(1,2,1);
         pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
-        CPPUNIT_ASSERT_MESSAGE("font should be striked out with a double line", aFont.GetStrikeout() == STRIKEOUT_DOUBLE );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be striked out with a double line", STRIKEOUT_DOUBLE, aFont.GetStrikeout());
         pPattern = pDoc->GetPattern(1,3,1);
         pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
-        CPPUNIT_ASSERT_MESSAGE("font should be underlined with a dotted line", aFont.GetUnderline() == UNDERLINE_DOTTED);
+        CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be underlined with a dotted line", UNDERLINE_DOTTED, aFont.GetUnderline());
         //test case for proper import height of first row with styles and text (related to i53253)
-        sal_uInt16 nRowHeight = pDoc->GetRowHeight(0,1);
-        rtl::OString sRowHeight = rtl::OString::valueOf( static_cast<sal_Int32>(nRowHeight) );
-        rtl::OString aMsg1("Expected: 253; Actual: ");
-        aMsg1 += sRowHeight;
-        CPPUNIT_ASSERT_MESSAGE( aMsg1.pData->buffer, nRowHeight == 253 );
+        CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(253), pDoc->GetRowHeight(0,1) );
         //test case for i53253 where a cell has text with different styles and space between the text.
-        rtl::OUString aTestOUStr;
-        pDoc->GetString(3,0,1, aTestOUStr);
-        rtl::OUString aKnownGoodOUStr("text14 space");
-        rtl::OString aTestOStr(rtl::OUStringToOString(aTestOUStr, RTL_TEXTENCODING_UTF8));
-        rtl::OString aKnownGoodOStr(rtl::OUStringToOString(aKnownGoodOUStr, RTL_TEXTENCODING_UTF8));
-        rtl::OString aMsg2("Expected: \"" + aKnownGoodOStr + "\"; Actual: \"" + aTestOStr + "\"");
-        CPPUNIT_ASSERT_MESSAGE( aMsg2.pData->buffer, aKnownGoodOUStr.equals(aTestOUStr) );
+        rtl::OUString aTestStr;
+        pDoc->GetString(3,0,1, aTestStr);
+        rtl::OUString aKnownGoodStr("text14 space");
+        CPPUNIT_ASSERT_EQUAL( aKnownGoodStr, aTestStr );
         //test case for cell text with line breaks.
-        pDoc->GetString(3,5,1, aTestOUStr);
-        aKnownGoodOUStr = "Hello,\nCalc!";
-        aTestOStr = rtl::OUStringToOString(aTestOUStr, RTL_TEXTENCODING_UTF8);
-        aKnownGoodOStr = rtl::OUStringToOString(aKnownGoodOUStr, RTL_TEXTENCODING_UTF8);
-        rtl::OString aMsg3("Expected: \"" + aKnownGoodOStr + "\"; Actual: \"" + aTestOStr + "\"");
-        CPPUNIT_ASSERT_MESSAGE( aMsg3.pData->buffer, aKnownGoodOUStr.equals(aTestOUStr) );
+        pDoc->GetString(3,5,1, aTestStr);
+        aKnownGoodStr = "Hello,\nCalc!";
+        CPPUNIT_ASSERT_EQUAL( aKnownGoodStr, aTestStr );
     }
     pPattern = pDoc->GetPattern(1,4,1);
     Color aColor = static_cast<const SvxBrushItem&>(pPattern->GetItem(ATTR_BACKGROUND)).GetColor();
     CPPUNIT_ASSERT_MESSAGE("background color should be green", aColor == COL_LIGHTGREEN);
     pPattern = pDoc->GetPattern(2,0,1);
     SvxCellHorJustify eHorJustify = static_cast<SvxCellHorJustify>(static_cast<const SvxHorJustifyItem&>(pPattern->GetItem(ATTR_HOR_JUSTIFY)).GetValue());
-    CPPUNIT_ASSERT_MESSAGE("cell content should be aligned centre horizontally", eHorJustify == SVX_HOR_JUSTIFY_CENTER);
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("cell content should be aligned centre horizontally", SVX_HOR_JUSTIFY_CENTER, eHorJustify);
     //test alignment
     pPattern = pDoc->GetPattern(2,1,1);
     eHorJustify = static_cast<SvxCellHorJustify>(static_cast<const SvxHorJustifyItem&>(pPattern->GetItem(ATTR_HOR_JUSTIFY)).GetValue());
-    CPPUNIT_ASSERT_MESSAGE("cell content should be aligned right horizontally", eHorJustify == SVX_HOR_JUSTIFY_RIGHT);
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("cell content should be aligned right horizontally", SVX_HOR_JUSTIFY_RIGHT, eHorJustify);
     pPattern = pDoc->GetPattern(2,2,1);
     eHorJustify = static_cast<SvxCellHorJustify>(static_cast<const SvxHorJustifyItem&>(pPattern->GetItem(ATTR_HOR_JUSTIFY)).GetValue());
-    CPPUNIT_ASSERT_MESSAGE("cell content should be aligned block horizontally", eHorJustify == SVX_HOR_JUSTIFY_BLOCK);
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("cell content should be aligned block horizontally", SVX_HOR_JUSTIFY_BLOCK, eHorJustify);
 
     //test Sheet3 only for ods
     if ( nFormat == ODS )
@@ -733,16 +723,11 @@ void checkMergedCells( ScDocument* pDoc, const ScAddress& rStartAddress,
     pDoc->ExtendMerge( rStartAddress.Col(), rStartAddress.Row(),
                        nActualEndCol, nActualEndRow, rStartAddress.Tab(), false );
     rtl::OString sTab = rtl::OString::valueOf( static_cast<sal_Int32>(rStartAddress.Tab() + 1) );
-    rtl::OString sExpectedEndCol = rtl::OString::valueOf( static_cast<sal_Int32>(rExpectedEndAddress.Col()) );
-    rtl::OString sExpectedEndRow = rtl::OString::valueOf( static_cast<sal_Int32>(rExpectedEndAddress.Row()) );

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list