Date: prev next · Thread: first prev next last
2013 Archives by date, by thread · List index


Hi,

I have submitted a patch for review:

    https://gerrit.libreoffice.org/1870

To pull it, you can do:

    git pull ssh://gerrit.libreoffice.org:29418/core refs/changes/70/1870/1

import inherited number formats with cached values, fdo#59724

Change-Id: I698f60daf4e591b57d8d99c130d2e524dc10c306
Reviewed-on: https://gerrit.libreoffice.org/1866
Reviewed-by: Kohei Yoshida <kohei.yoshida@gmail.com>
Tested-by: Kohei Yoshida <kohei.yoshida@gmail.com>
---
M formula/inc/formula/token.hxx
M sc/inc/cell.hxx
M sc/inc/formularesult.hxx
M sc/inc/token.hxx
M sc/source/core/data/cell.cxx
M sc/source/core/data/cell2.cxx
M sc/source/core/tool/cellform.cxx
M sc/source/core/tool/formularesult.cxx
M sc/source/core/tool/token.cxx
M sc/source/filter/xml/xmlcelli.cxx
M sc/source/filter/xml/xmlcelli.hxx
M sc/source/ui/docshell/docsh.cxx
12 files changed, 123 insertions(+), 52 deletions(-)



diff --git a/formula/inc/formula/token.hxx b/formula/inc/formula/token.hxx
index b72234e..3a174d7 100644
--- a/formula/inc/formula/token.hxx
+++ b/formula/inc/formula/token.hxx
@@ -58,6 +58,9 @@
                                         // and/or string result and a formula
                                         // string to be compiled.
 
+    svHybridValueCell,                  // A temporary formula cell with an value
+                                        // and possibily a string representation
+
     svExternalSingleRef,
     svExternalDoubleRef,
     svExternalName,
diff --git a/sc/inc/cell.hxx b/sc/inc/cell.hxx
index 008b510..0322db6 100644
--- a/sc/inc/cell.hxx
+++ b/sc/inc/cell.hxx
@@ -429,6 +429,7 @@
                     // display as empty string if formula::svEmptyCell result
     bool            IsEmptyDisplayedAsString();
     bool            IsValue();      // also true if formula::svEmptyCell
+    bool            IsHybridValueCell(); // for cells after import to deal with inherited number 
formats
     double          GetValue();
     double          GetValueAlways();   // ignore errors
     rtl::OUString   GetString();
@@ -492,6 +493,13 @@
                                     const formula::FormulaGrammar::Grammar eGrammar )
                         { aResult.SetHybridFormula( r); eTempGrammar = eGrammar; }
 
+    /**
+     * For import only: use for formula cells that return a number
+     * formatted as some kind of string
+     */
+    void SetHybridValueString( double nVal, const OUString& r )
+                        { aResult.SetHybridValueString( nVal, r ); }
+
     void SetResultMatrix( SCCOL nCols, SCROW nRows, const ScConstMatrixRef& pMat, 
formula::FormulaToken* pUL )
     {
         aResult.SetMatrix(nCols, nRows, pMat, pUL);
diff --git a/sc/inc/formularesult.hxx b/sc/inc/formularesult.hxx
index 2128636..673bcdb 100644
--- a/sc/inc/formularesult.hxx
+++ b/sc/inc/formularesult.hxx
@@ -162,7 +162,7 @@
     ScConstMatrixRef GetMatrix() const;
 
     /** Return formula string if type formula::svHybridCell, else empty string. */
-    const String& GetHybridFormula() const;
+    const OUString& GetHybridFormula() const;
 
     /** Should only be used by import filters, best in the order
         SetHybridDouble(), SetHybridString(), or only SetHybridString() for
@@ -179,6 +179,8 @@
         SetHybridFormula() for formula string to be compiled later. */
     SC_DLLPUBLIC void SetHybridFormula( const String & rFormula );
 
+    void SetHybridValueString( double nVal, const OUString& rStr );
+
     SC_DLLPUBLIC void SetMatrix( SCCOL nCols, SCROW nRows, const ScConstMatrixRef& pMat, 
formula::FormulaToken* pUL );
 
     /** Get the const ScMatrixFormulaCellToken* if token is of that type, else
diff --git a/sc/inc/token.hxx b/sc/inc/token.hxx
index e08db6c..a540555 100644
--- a/sc/inc/token.hxx
+++ b/sc/inc/token.hxx
@@ -414,26 +414,37 @@
 class SC_DLLPUBLIC ScHybridCellToken : public ScToken
 {
 private:
-            double              fDouble;
-            String              aString;
-            String              aFormula;
+    double mfDouble;
+    String maString;
+    OUString maFormula;
 public:
-                                ScHybridCellToken( double f,
-                                        const String & rStr,
-                                        const String & rFormula ) :
-                                    ScToken( formula::svHybridCell ),
-                                    fDouble( f ), aString( rStr ),
-                                    aFormula( rFormula ) {}
-                                ScHybridCellToken( const ScHybridCellToken& r ) :
-                                    ScToken( r ), fDouble( r.fDouble),
-                                    aString( r.aString), aFormula( r.aFormula) {}
-            const String &      GetFormula() const  { return aFormula; }
-    virtual double              GetDouble() const;
-    virtual const String &      GetString() const;
-    virtual bool                operator==( const formula::FormulaToken& rToken ) const;
-    virtual FormulaToken*       Clone() const { return new ScHybridCellToken(*this); }
+    ScHybridCellToken( double f,
+            const OUString & rStr,
+            const OUString & rFormula ) :
+        ScToken( formula::svHybridCell ),
+        mfDouble( f ), maString( rStr ),
+        maFormula( rFormula ) {}
+
+    const OUString& GetFormula() const  { return maFormula; }
+    virtual double GetDouble() const;
+    virtual const String& GetString() const;
+    virtual bool operator==( const formula::FormulaToken& rToken ) const;
+    virtual FormulaToken* Clone() const { return new ScHybridCellToken(*this); }
 };
 
+class SC_DLLPUBLIC ScHybridValueCellToken : public ScToken
+{
+private:
+    double mfValue;
+    String maString;
+public:
+    ScHybridValueCellToken (double f, const OUString& rStr ):
+        ScToken( formula::svHybridValueCell ),
+        mfValue( f ), maString( rStr ) {}
+
+    virtual double GetDouble() const { return mfValue; }
+    virtual const String & GetString() const { return maString; }
+};
 
 // Simplify argument passing to RefUpdate methods with ScSingleRefToken or
 // ScDoubleRefToken
diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx
index bbf8976..e938ffe 100644
--- a/sc/source/core/data/cell.cxx
+++ b/sc/source/core/data/cell.cxx
@@ -978,7 +978,7 @@
         delete pCodeOld;
     if( !pCode->GetCodeError() )
     {
-        if ( !pCode->GetLen() && aResult.GetHybridFormula().Len() && rFormula == 
rtl::OUString(aResult.GetHybridFormula()) )
+        if ( !pCode->GetLen() && !aResult.GetHybridFormula().isEmpty() && rFormula == 
aResult.GetHybridFormula() )
         {   // not recursive CompileTokenArray/Compile/CompileTokenArray
             if ( rFormula[0] == '=' )
                 pCode->AddBad( rFormula.copy(1) );
@@ -1002,7 +1002,7 @@
 void ScFormulaCell::CompileTokenArray( bool bNoListening )
 {
     // Not already compiled?
-    if( !pCode->GetLen() && aResult.GetHybridFormula().Len() )
+    if( !pCode->GetLen() && !aResult.GetHybridFormula().isEmpty() )
         Compile( aResult.GetHybridFormula(), bNoListening, eTempGrammar);
     else if( bCompile && !pDocument->IsClipOrUndo() && !pCode->GetCodeError() )
     {
@@ -1110,7 +1110,7 @@
 {
     bool bNewCompiled = false;
     // If a Calc 1.0-doc is read, we have a result, but no token array
-    if( !pCode->GetLen() && aResult.GetHybridFormula().Len() )
+    if( !pCode->GetLen() && !aResult.GetHybridFormula().isEmpty() )
     {
         Compile( aResult.GetHybridFormula(), true, eTempGrammar);
         aResult.SetToken( NULL);
@@ -1459,7 +1459,7 @@
         // This should only be a temporary condition and, since we set an
         // error, if ran into it again we'd bump into the dirty-clearing
         // condition further down.
-        if ( !pCode->GetLen() && aResult.GetHybridFormula().Len() )
+        if ( !pCode->GetLen() && !aResult.GetHybridFormula().isEmpty() )
         {
             pCode->SetCodeError( errNoCode );
             // This is worth an assertion; if encountered in daily work
@@ -1595,7 +1595,7 @@
                 }
                 else
                 {
-                    if ( eOld == svHybridCell )     // string result from SetFormulaResultString?
+                    if ( eOld == svHybridCell || eOld == svHybridValueCell )     // string result 
from SetFormulaResultString?
                         eOld = svString;            // ScHybridCellToken has a valid GetString 
method
 
                     // #i106045# use approxEqual to compare with stored value
@@ -1620,7 +1620,7 @@
             if ( bChanged && !bContentChanged && pDocument->IsStreamValid(aPos.Tab()) )
             {
                 if ( ( eOld == svUnknown && ( eNew == svError || ( eNew == svDouble && 
aNewResult.GetDouble() == 0.0 ) ) ) ||
-                     ( eOld == svHybridCell && eNew == svString && aResult.GetString() == 
aNewResult.GetString() ) ||
+                     ( (eOld == svHybridCell || eOld == svHybridValueCell) && eNew == svString && 
aResult.GetString() == aNewResult.GetString() ) ||
                      ( eOld == svDouble && eNew == svDouble && rtl::math::approxEqual( 
aResult.GetDouble(), aNewResult.GetDouble() ) ) )
                 {
                     // no change, see above
diff --git a/sc/source/core/data/cell2.cxx b/sc/source/core/data/cell2.cxx
index bcf5283..c23377f 100644
--- a/sc/source/core/data/cell2.cxx
+++ b/sc/source/core/data/cell2.cxx
@@ -496,6 +496,11 @@
     return aResult.IsValue();
 }
 
+bool ScFormulaCell::IsHybridValueCell()
+{
+    return aResult.GetType() == formula::svHybridValueCell;
+}
+
 double ScFormulaCell::GetValue()
 {
     MaybeInterpret();
@@ -1600,7 +1605,7 @@
             SetHybridFormula( aFormula, formula::FormulaGrammar::GRAM_NATIVE);
         }
     }
-    else if ( !pCode->GetLen() && aResult.GetHybridFormula().Len() )
+    else if ( !pCode->GetLen() && !aResult.GetHybridFormula().isEmpty() )
     {
         Compile( aResult.GetHybridFormula(), false, eTempGrammar );
         aResult.SetToken( NULL);
@@ -1647,7 +1652,7 @@
             SetHybridFormula( aFormula, formula::FormulaGrammar::GRAM_NATIVE);
         }
     }
-    else if ( !pCode->GetLen() && aResult.GetHybridFormula().Len() )
+    else if ( !pCode->GetLen() && !aResult.GetHybridFormula().isEmpty() )
     {
         Compile( aResult.GetHybridFormula(), false, eTempGrammar );
         aResult.SetToken( NULL);
diff --git a/sc/source/core/tool/cellform.cxx b/sc/source/core/tool/cellform.cxx
index 01dc61b..4a3ecc6 100644
--- a/sc/source/core/tool/cellform.cxx
+++ b/sc/source/core/tool/cellform.cxx
@@ -125,6 +125,8 @@
                             double fValue = pFCell->GetValue();
                             if ( !bNullVals && fValue == 0.0 )
                                 rString = rtl::OUString();
+                            else if ( pFCell->IsHybridValueCell() )
+                                rString = pFCell->GetString();
                             else
                                 rFormatter.GetOutputString( fValue, nFormat, rString, ppColor, 
bUseStarFormat );
                         }
diff --git a/sc/source/core/tool/formularesult.cxx b/sc/source/core/tool/formularesult.cxx
index 9e1032e..791dbad 100644
--- a/sc/source/core/tool/formularesult.cxx
+++ b/sc/source/core/tool/formularesult.cxx
@@ -268,7 +268,8 @@
 bool ScFormulaResult::IsValue() const
 {
     formula::StackVar sv = GetCellResultType();
-    return sv == formula::svDouble || sv == formula::svError || sv == formula::svEmptyCell;
+    return sv == formula::svDouble || sv == formula::svError
+        || sv == formula::svEmptyCell || sv == formula::svHybridValueCell;
 }
 
 bool ScFormulaResult::IsMultiline() const
@@ -331,6 +332,7 @@
             switch (mpToken->GetType())
             {
                 case formula::svHybridCell:
+                case formula::svHybridValueCell:
                     return mpToken->GetDouble();
                 case formula::svMatrixCell:
                     {
@@ -359,6 +361,7 @@
         {
             case formula::svString:
             case formula::svHybridCell:
+            case formula::svHybridValueCell:
                 return mpToken->GetString();
             case formula::svMatrixCell:
                 {
@@ -382,7 +385,7 @@
     return NULL;
 }
 
-const String & ScFormulaResult::GetHybridFormula() const
+const OUString& ScFormulaResult::GetHybridFormula() const
 {
     if (GetType() == formula::svHybridCell)
     {
@@ -390,7 +393,7 @@
         if (p)
             return p->GetFormula();
     }
-    return EMPTY_STRING;
+    return EMPTY_OUSTRING;
 }
 
 void ScFormulaResult::SetHybridDouble( double f )
@@ -443,6 +446,23 @@
     mbToken = true;
 }
 
+void ScFormulaResult::SetHybridValueString( double nVal, const OUString& rStr )
+{
+    if(GetType() == formula::svMatrixCell)
+    {
+        SetDouble(nVal);
+        return;
+    }
+
+    ResetToDefaults();
+    if (mbToken && mpToken)
+        mpToken->DecRef();
+
+    mpToken = new ScHybridValueCellToken( nVal, rStr );
+    mpToken->IncRef();
+    mbToken = true;
+}
+
 void ScFormulaResult::SetMatrix( SCCOL nCols, SCROW nRows, const ScConstMatrixRef& pMat, 
formula::FormulaToken* pUL )
 {
     ResetToDefaults();
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 4ea3d4e..8e8c329 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1096,13 +1096,13 @@
 }
 
 
-double          ScHybridCellToken::GetDouble() const    { return fDouble; }
-const String &  ScHybridCellToken::GetString() const    { return aString; }
+double ScHybridCellToken::GetDouble() const { return mfDouble; }
+const String& ScHybridCellToken::GetString() const { return maString; }
 bool ScHybridCellToken::operator==( const FormulaToken& r ) const
 {
     return FormulaToken::operator==( r ) &&
-        fDouble == r.GetDouble() && aString == r.GetString() &&
-        aFormula == static_cast<const ScHybridCellToken &>(r).GetFormula();
+        mfDouble == r.GetDouble() && maString == r.GetString() &&
+        maFormula == static_cast<const ScHybridCellToken &>(r).GetFormula();
 }
 
 
diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx
index 6e73782..42714a1 100644
--- a/sc/source/filter/xml/xmlcelli.cxx
+++ b/sc/source/filter/xml/xmlcelli.cxx
@@ -122,7 +122,9 @@
     bHasTextImport(false),
     bIsFirstTextImport(false),
     bSolarMutexLocked(false),
-    bFormulaTextResult(false)
+    bFormulaTextResult(false),
+    mbPossibleErrorCell(false),
+    mbCheckWithCompilerForError(false)
 {
     rtl::math::setNan(&fValue); // NaN by default
 
@@ -352,9 +354,13 @@
 
             ScAddress aCellPos = rXMLImport.GetTables().GetCurrentCellPos();
 
-            if( ((nCellType == util::NumberFormat::TEXT) || bFormulaTextResult) )
+            if( ((nCellType == util::NumberFormat::TEXT) || pOUFormula || bFormulaTextResult) )
             {
-                if (!bHasTextImport)
+                if ( pOUFormula )
+                {
+                    pContext = new ScXMLTextPContext(rXMLImport, nPrefix, rLName, xAttrList, this);
+                }
+                else if (!bHasTextImport)
                 {
                     bIsFirstTextImport = true;
                     bHasTextImport = true;
@@ -725,7 +731,7 @@
     {
         if( bFormulaTextResult && pOUTextValue )
         {
-            if (!GetScImport().IsFormulaErrorConstant(*pOUTextValue))
+            if( !IsPossibleErrorString() )
             {
                 pFCell->SetHybridString( *pOUTextValue );
                 pFCell->ResetDirty();
@@ -733,11 +739,13 @@
         }
         else if (!rtl::math::isNan(fValue))
         {
-            pFCell->SetHybridDouble(fValue);
+            if( pOUTextContent )
+                pFCell->SetHybridValueString( fValue, *pOUTextContent );
+            else
+                pFCell->SetHybridDouble(fValue);
             pFCell->ResetDirty();
         }
         pFCell->StartListeningTo(rXMLImport.GetDocument());
-        // Leave the cell dirty when the cached result is not given.
     }
 }
 
@@ -766,7 +774,7 @@
 
             if(!aCellString.isEmpty())
             {
-                if (bDoIncrement && !GetScImport().IsFormulaErrorConstant(aCellString))
+                if (bDoIncrement && !IsPossibleErrorString())
                 {
                     pFCell->SetHybridString( aCellString );
                     pFCell->ResetDirty();
@@ -1113,7 +1121,7 @@
                 ScMatrixRef pMat(new ScMatrix(nMatrixCols, nMatrixRows));
                 if (bFormulaTextResult && pOUTextValue)
                 {
-                    if (!GetScImport().IsFormulaErrorConstant(*pOUTextValue))
+                    if (!IsPossibleErrorString())
                     {
                         pFCell->SetResultMatrix(
                             nMatrixCols, nMatrixRows, pMat, new 
formula::FormulaStringToken(*pOUTextValue));
@@ -1153,14 +1161,20 @@
 // - is blank
 // - has a constant error value beginning with "#" (such as "#VALUE!" or "#N/A")
 // - has an "Err:[###]" (where "[###]" is an error number)
-bool ScXMLTableRowCellContext::HasSpecialCaseFormulaText() const
+void ScXMLTableRowCellContext::HasSpecialCaseFormulaText()
 {
-    if(  pOUTextContent &&
-         ( pOUTextContent->isEmpty() || (pOUTextContent->indexOf("#") > -1) ||
-           (pOUTextContent->indexOf("Err:")  > -1) )
-      )
-        return true;
-    return false;
+    if(  pOUTextContent )
+    {
+        if ( pOUTextContent->isEmpty()  || (pOUTextContent->indexOf("Err:")  > -1) )
+            mbPossibleErrorCell = true;
+        else if (pOUTextContent->indexOf("#") > -1)
+            mbCheckWithCompilerForError = true;
+    }
+}
+
+bool ScXMLTableRowCellContext::IsPossibleErrorString() const
+{
+     return mbPossibleErrorCell || ( mbCheckWithCompilerForError && 
GetScImport().IsFormulaErrorConstant(*pOUTextValue) );
 }
 
 
@@ -1179,8 +1193,8 @@
             aTextImport->ResetCursor();
         }
     }
-
-    if( bFormulaTextResult && HasSpecialCaseFormulaText() )
+    HasSpecialCaseFormulaText();
+    if( bFormulaTextResult && (mbPossibleErrorCell || mbCheckWithCompilerForError) )
     {
         pOUTextValue.reset(*pOUTextContent);
         nCellType = util::NumberFormat::TEXT;
diff --git a/sc/source/filter/xml/xmlcelli.hxx b/sc/source/filter/xml/xmlcelli.hxx
index 32f0698..2bf8b8c 100644
--- a/sc/source/filter/xml/xmlcelli.hxx
+++ b/sc/source/filter/xml/xmlcelli.hxx
@@ -65,6 +65,8 @@
     bool        bIsFirstTextImport;
     bool        bSolarMutexLocked;
     bool        bFormulaTextResult;
+    bool        mbPossibleErrorCell;
+    bool        mbCheckWithCompilerForError;
 
     const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
     ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
@@ -92,7 +94,9 @@
     void PutFormulaCell             ( const ScAddress& rScCurrentPos );
     void AddFormulaCell             ( const ScAddress& rScCellPos );
 
-    bool HasSpecialCaseFormulaText() const;
+    void HasSpecialCaseFormulaText();
+
+    bool IsPossibleErrorString() const;
 
 public:
 
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index 43fd526..d7bcfcc 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -466,8 +466,10 @@
     if (bHardRecalc)
         DoHardRecalc(false);
     else
+    {
         // still need to recalc volatile formula cells.
-        aDocument.CalcFormulaTree(false, true, false);
+        aDocument.Broadcast( SC_HINT_DATACHANGED, BCA_BRDCST_ALWAYS, NULL );
+    }
 
     bool bAdjustHeightOld = aDocument.IsAdjustHeightEnabled();
     aDocument.EnableAdjustHeight(false);

-- 
To view, visit https://gerrit.libreoffice.org/1870
To unsubscribe, visit https://gerrit.libreoffice.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I698f60daf4e591b57d8d99c130d2e524dc10c306
Gerrit-PatchSet: 1
Gerrit-Project: core
Gerrit-Branch: libreoffice-4-0-0
Gerrit-Owner: Markus Mohrhard <markus.mohrhard@googlemail.com>
Gerrit-Reviewer: Kohei Yoshida <kohei.yoshida@gmail.com>


Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.