include/formula/tokenarray.hxx         |    5 +++++
 sc/inc/document.hxx                    |    2 +-
 sc/inc/formulacell.hxx                 |    3 ++-
 sc/source/core/data/formulacell.cxx    |    8 +++-----
 sc/source/filter/oox/formulabuffer.cxx |   31 ++++++++++++++++++++++++++++---
 sc/source/ui/view/output2.cxx          |   13 +++++++------
 6 files changed, 46 insertions(+), 16 deletions(-)

New commits:
commit 816b0e97f32df82a1ffc23950d5bf21760a4cd39
Author:     Eike Rathke <er...@redhat.com>
AuthorDate: Thu Feb 23 01:22:16 2023 +0100
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Wed Mar 1 10:20:40 2023 +0000

    Resolves: tdf#153767 Try harder to import OOXML bool shared formula result
    
    ... by setting the result value or if necessary recalculating even if
    AutoCalc is turned off for the document. Similar for other implicitly
    recalculating formula types.
    Also set a boolean number format if none.
    
    Change-Id: I2f75735707180eccf4b2c525738ac0b763901230
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147425
    Reviewed-by: Eike Rathke <er...@redhat.com>
    Tested-by: Jenkins
    (cherry picked from commit 05ac57f85eb622b798719db03bbdd07b79e1703a)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147444
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/include/formula/tokenarray.hxx b/include/formula/tokenarray.hxx
index cbff6a3e469d..330543d427dc 100644
--- a/include/formula/tokenarray.hxx
+++ b/include/formula/tokenarray.hxx
@@ -430,6 +430,11 @@ public:
                         example OOXML. */
     bool            IsRecalcModeMustAfterImport() const
                                 { return (nMode & ScRecalcMode::EMask) <= 
ScRecalcMode::ONLOAD_ONCE; }
+    void            ClearRecalcModeMustAfterImport()
+                                {
+                                    if (IsRecalcModeMustAfterImport() && 
!IsRecalcModeAlways())
+                                        SetExclusiveRecalcModeNormal();
+                                }
 
                             /** Get OpCode of the most outer function */
     inline OpCode           GetOuterFuncOpCode() const;
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 4873307ea01d..092d9ba0d9a9 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1224,7 +1224,7 @@ public:
     SC_DLLPUBLIC sal_uInt32                   GetNumberFormat( SCCOL nCol, 
SCROW nRow, SCTAB nTab ) const;
     sal_uInt32                                GetNumberFormat( const ScRange& 
rRange ) const;
     SC_DLLPUBLIC sal_uInt32                   GetNumberFormat( const 
ScInterpreterContext& rContext, const ScAddress& ) const;
-    void                                      SetNumberFormat( const 
ScAddress& rPos, sal_uInt32 nNumberFormat );
+    SC_DLLPUBLIC void                         SetNumberFormat( const 
ScAddress& rPos, sal_uInt32 nNumberFormat );
 
     void                                      GetNumberFormatInfo( const 
ScInterpreterContext& rContext, SvNumFormatType& nType, sal_uInt32& nIndex, 
const ScAddress& rPos ) const;
     SC_DLLPUBLIC const ScFormulaCell*         GetFormulaCell( const ScAddress& 
rPos ) const;
diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx
index e4bc41772e0e..42b7f6120149 100644
--- a/sc/inc/formulacell.hxx
+++ b/sc/inc/formulacell.hxx
@@ -445,7 +445,8 @@ public:
         if (!IsDirtyOrInTableOpDirty())
             return false;
 
-        return (rDocument.GetAutoCalc() || (cMatrixFlag != 
ScMatrixMode::NONE));
+        return rDocument.GetAutoCalc() || (cMatrixFlag != ScMatrixMode::NONE)
+            || (pCode->IsRecalcModeMustAfterImport() && 
!pCode->IsRecalcModeAlways());
     }
 
     void MaybeInterpret()
diff --git a/sc/source/core/data/formulacell.cxx 
b/sc/source/core/data/formulacell.cxx
index 023a4214bd93..9b065329ba26 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -2331,6 +2331,8 @@ void ScFormulaCell::InterpretTail( ScInterpreterContext& 
rContext, ScInterpretTa
         OSL_ENSURE( pCode->GetCodeError() != FormulaError::NONE, "no RPN code 
and no errors ?!?!" );
         ResetDirty();
     }
+
+    pCode->ClearRecalcModeMustAfterImport();
 }
 
 void ScFormulaCell::HandleStuffAfterParallelCalculation(ScInterpreter* 
pInterpreter)
@@ -2546,7 +2548,7 @@ void ScFormulaCell::SetDirty( bool bDirtyFlag )
         // the FormulaTree, once in there it would be assumed that its
         // dependents already had been tracked and it would be skipped on a
         // subsequent notify. Postpone tracking until all listeners are set.
-        if (!rDocument.IsImportingXML())
+        if (!rDocument.IsImportingXML() && 
!rDocument.IsInsertingFromOtherDoc())
             rDocument.TrackFormulas();
     }
 
@@ -2647,10 +2649,6 @@ void ScFormulaCell::AddRecalcMode( ScRecalcMode nBits )
 {
     if ( (nBits & ScRecalcMode::EMask) != ScRecalcMode::NORMAL )
         SetDirtyVar();
-    if ( nBits & ScRecalcMode::ONLOAD_ONCE )
-    {   // OnLoadOnce is used only to set Dirty after filter import.
-        nBits = (nBits & ~ScRecalcMode::EMask) | ScRecalcMode::NORMAL;
-    }
     pCode->AddRecalcMode( nBits );
 }
 
diff --git a/sc/source/filter/oox/formulabuffer.cxx 
b/sc/source/filter/oox/formulabuffer.cxx
index 3b81e89e45c2..dc934d1d41a4 100644
--- a/sc/source/filter/oox/formulabuffer.cxx
+++ b/sc/source/filter/oox/formulabuffer.cxx
@@ -22,6 +22,7 @@
 #include <oox/token/tokens.hxx>
 #include <oox/helper/progressbar.hxx>
 #include <svl/sharedstringpool.hxx>
+#include <svl/numformat.hxx>
 #include <sal/log.hxx>
 
 using namespace ::com::sun::star::uno;
@@ -154,20 +155,41 @@ void applySharedFormulas(
                 pCell = new ScFormulaCell(rDoc.getDoc(), aPos, *pArray);
 
             rDoc.setFormulaCell(aPos, pCell);
-            if (rDoc.getDoc().GetNumberFormat(aPos.Col(), aPos.Row(), 
aPos.Tab()) % SV_COUNTRY_LANGUAGE_OFFSET == 0)
+            const bool bNeedNumberFormat = ((rDoc.getDoc().GetNumberFormat(
+                            aPos.Col(), aPos.Row(), aPos.Tab()) % 
SV_COUNTRY_LANGUAGE_OFFSET) == 0);
+            if (bNeedNumberFormat)
                 pCell->SetNeedNumberFormat(true);
 
             if (rDesc.maCellValue.isEmpty())
             {
                 // No cached cell value. Mark it for re-calculation.
                 pCell->SetDirty();
+                // Recalc even if AutoCalc is disabled. Must be after
+                // SetDirty() as it also calls SetDirtyVar().
+                pCell->AddRecalcMode( ScRecalcMode::ONLOAD_ONCE);
                 continue;
             }
 
-            // Set cached formula results. For now, we only use numeric and 
string-formula
-            // results. Find out how to utilize cached results of other types.
+            // Set cached formula results. For now, we only use boolean,
+            // numeric and string-formula results. Find out how to utilize
+            // cached results of other types.
             switch (rDesc.mnValueType)
             {
+                case XML_b:
+                    // boolean value.
+                    if (bNeedNumberFormat)
+                    {
+                        rDoc.getDoc().SetNumberFormat( aPos,
+                                
rDoc.getDoc().GetFormatTable()->GetStandardFormat( SvNumFormatType::LOGICAL));
+                    }
+                    if (rDesc.maCellValue == "1" || rDesc.maCellValue == "0")
+                        pCell->SetResultDouble(rDesc.maCellValue == "1" ? 1.0 
: 0.0);
+                    else
+                    {
+                        // Recalc even if AutoCalc is disabled.
+                        pCell->AddRecalcMode( ScRecalcMode::ONLOAD_ONCE);
+                    }
+                break;
                 case XML_n:
                     // numeric value.
                     pCell->SetResultDouble(rDesc.maCellValue.toDouble());
@@ -193,6 +215,9 @@ void applySharedFormulas(
                 default:
                     // Mark it for re-calculation.
                     pCell->SetDirty();
+                    // Recalc even if AutoCalc is disabled. Must be after
+                    // SetDirty() as it also calls SetDirtyVar().
+                    pCell->AddRecalcMode( ScRecalcMode::ONLOAD_ONCE);
             }
         }
     }
diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
index 5f09c292c176..649ccdd7349e 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -1484,9 +1484,15 @@ tools::Rectangle ScOutputData::LayoutStrings(bool 
bPixelToLogic, bool bPaint, co
                 mpDev->GetMapMode().GetMapUnit() == 
mpRefDevice->GetMapMode().GetMapUnit(),
                 "LayoutStrings: different MapUnits ?!?!" );
 
+    sc::IdleSwitch aIdleSwitch(*mpDoc, false);
+
+    // Try to limit interpreting to only visible cells. Calling e.g. IsValue()
+    // on a formula cell that needs interpreting would call Interpret()
+    // for the entire formula group, which could be large.
+    mpDoc->InterpretCellsIfNeeded( ScRange( nX1, nY1, nTab, nX2, nY2, nTab ));
+
     vcl::PDFExtOutDevData* pPDFData = dynamic_cast< vcl::PDFExtOutDevData* 
>(mpDev->GetExtOutDevData() );
 
-    sc::IdleSwitch aIdleSwitch(*mpDoc, false);
     ScDrawStringsVars aVars( this, bPixelToLogic );
 
     bool bProgress = false;
@@ -1514,11 +1520,6 @@ tools::Rectangle ScOutputData::LayoutStrings(bool 
bPixelToLogic, bool bPaint, co
     const SfxItemSet* pOldCondSet = nullptr;
     SvtScriptType nOldScript = SvtScriptType::NONE;
 
-    // Try to limit interpreting to only visible cells. Calling e.g. IsValue()
-    // on a formula cell that needs interpreting would call Interpret()
-    // for the entire formula group, which could be large.
-    mpDoc->InterpretCellsIfNeeded( ScRange( nX1, nY1, nTab, nX2, nY2, nTab ));
-
     // alternative pattern instances in case we need to modify the pattern
     // before processing the cell value.
     std::vector<std::unique_ptr<ScPatternAttr> > aAltPatterns;

Reply via email to