[Libreoffice-commits] .: formula/inc sc/inc sc/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Wed Jan 23 15:46:41 PST 2013


 formula/inc/formula/token.hxx         |    3 ++
 sc/inc/cell.hxx                       |    8 ++++++
 sc/inc/formularesult.hxx              |    4 ++-
 sc/inc/token.hxx                      |   45 +++++++++++++++++++++-------------
 sc/source/core/data/cell.cxx          |    8 +++---
 sc/source/core/data/cell2.cxx         |    9 +++++-
 sc/source/core/tool/cellform.cxx      |    2 +
 sc/source/core/tool/formularesult.cxx |   19 ++++++++++++--
 sc/source/core/tool/token.cxx         |    8 +++---
 sc/source/filter/xml/xmlcelli.cxx     |   14 +++++++---
 10 files changed, 86 insertions(+), 34 deletions(-)

New commits:
commit ae516fabd96a948b62c4d3a522555fc955750c3e
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Thu Jan 24 00:32:41 2013 +0100

    import inherited number formats with cached values, fdo#59724
    
    Change-Id: I698f60daf4e591b57d8d99c130d2e524dc10c306

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 @@ enum StackVarEnum
                                         // 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 716b76f..d146a98 100644
--- a/sc/inc/cell.hxx
+++ b/sc/inc/cell.hxx
@@ -430,6 +430,7 @@ public:
                     // 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();
@@ -493,6 +494,13 @@ public:
                                     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 @@ public:
     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 @@ public:
         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 @@ public:
 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 ce073e2..2b0366c 100644
--- a/sc/source/core/data/cell.cxx
+++ b/sc/source/core/data/cell.cxx
@@ -988,7 +988,7 @@ void ScFormulaCell::Compile( const rtl::OUString& rFormula, bool bNoListening,
         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) );
@@ -1012,7 +1012,7 @@ void ScFormulaCell::Compile( const rtl::OUString& rFormula, bool bNoListening,
 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() )
     {
@@ -1120,7 +1120,7 @@ void ScFormulaCell::CalcAfterLoad()
 {
     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);
@@ -1469,7 +1469,7 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
         // 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
diff --git a/sc/source/core/data/cell2.cxx b/sc/source/core/data/cell2.cxx
index c43f0c1..73c960c 100644
--- a/sc/source/core/data/cell2.cxx
+++ b/sc/source/core/data/cell2.cxx
@@ -496,6 +496,11 @@ bool ScFormulaCell::IsValue()
     return aResult.IsValue();
 }
 
+bool ScFormulaCell::IsHybridValueCell()
+{
+    return aResult.GetType() == formula::svHybridValueCell;
+}
+
 double ScFormulaCell::GetValue()
 {
     MaybeInterpret();
@@ -1600,7 +1605,7 @@ void ScFormulaCell::CompileDBFormula( bool bCreateFormulaString )
             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 @@ void ScFormulaCell::CompileNameFormula( bool bCreateFormulaString )
             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 @@ void ScCellFormat::GetString( ScBaseCell* pCell, sal_uLong nFormat, rtl::OUStrin
                             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..9139c9a 100644
--- a/sc/source/core/tool/formularesult.cxx
+++ b/sc/source/core/tool/formularesult.cxx
@@ -268,6 +268,8 @@ bool ScFormulaResult::IsEmptyDisplayedAsString() const
 bool ScFormulaResult::IsValue() const
 {
     formula::StackVar sv = GetCellResultType();
+    if( sv == formula::svHybridValueCell )
+        return true;
     return sv == formula::svDouble || sv == formula::svError || sv == formula::svEmptyCell;
 }
 
@@ -331,6 +333,8 @@ double ScFormulaResult::GetDouble() const
             switch (mpToken->GetType())
             {
                 case formula::svHybridCell:
+                case formula::svHybridValueCell:
+                    return mpToken->GetDouble();
                     return mpToken->GetDouble();
                 case formula::svMatrixCell:
                     {
@@ -359,6 +363,7 @@ const String & ScFormulaResult::GetString() const
         {
             case formula::svString:
             case formula::svHybridCell:
+            case formula::svHybridValueCell:
                 return mpToken->GetString();
             case formula::svMatrixCell:
                 {
@@ -382,7 +387,7 @@ ScConstMatrixRef ScFormulaResult::GetMatrix() const
     return NULL;
 }
 
-const String & ScFormulaResult::GetHybridFormula() const
+const OUString& ScFormulaResult::GetHybridFormula() const
 {
     if (GetType() == formula::svHybridCell)
     {
@@ -390,7 +395,7 @@ const String & ScFormulaResult::GetHybridFormula() const
         if (p)
             return p->GetFormula();
     }
-    return EMPTY_STRING;
+    return EMPTY_OUSTRING;
 }
 
 void ScFormulaResult::SetHybridDouble( double f )
@@ -443,6 +448,16 @@ void ScFormulaResult::SetHybridFormula( const String & rFormula )
     mbToken = true;
 }
 
+void ScFormulaResult::SetHybridValueString( double nVal, const OUString& rStr )
+{
+    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 @@ void ScMatrixFormulaCellToken::SetUpperLeftDouble( double f )
 }
 
 
-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 edf309bc..e93f33d 100644
--- a/sc/source/filter/xml/xmlcelli.cxx
+++ b/sc/source/filter/xml/xmlcelli.cxx
@@ -352,9 +352,13 @@ SvXMLImportContext *ScXMLTableRowCellContext::CreateChildContext( sal_uInt16 nPr
 
             ScAddress aCellPos = rXMLImport.GetTables().GetCurrentCellPos();
 
-            if( ((nCellType == util::NumberFormat::TEXT) || bFormulaTextResult) )
+            if( ((nCellType == util::NumberFormat::TEXT) || pOUFormula) )
             {
-                if (!bHasTextImport)
+                if ( pOUFormula )
+                {
+                    pContext = new ScXMLTextPContext(rXMLImport, nPrefix, rLName, xAttrList, this);
+                }
+                else if (!bHasTextImport)
                 {
                     bIsFirstTextImport = true;
                     bHasTextImport = true;
@@ -733,11 +737,13 @@ void ScXMLTableRowCellContext::SetFormulaCell(ScFormulaCell* pFCell) const
         }
         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.
     }
 }
 


More information about the Libreoffice-commits mailing list