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 447296c3c2676c855d98200b03bcec15310629bc
Author:     Eike Rathke <er...@redhat.com>
AuthorDate: Thu Feb 23 01:22:16 2023 +0100
Commit:     Aron Budea <aron.bu...@collabora.com>
CommitDate: Sat Jun 24 12:28:48 2023 +0200

    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>
    (cherry picked from commit 816b0e97f32df82a1ffc23950d5bf21760a4cd39)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153546
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Aron Budea <aron.bu...@collabora.com>

diff --git a/include/formula/tokenarray.hxx b/include/formula/tokenarray.hxx
index 6b373ff44e15..e3c44e934a11 100644
--- a/include/formula/tokenarray.hxx
+++ b/include/formula/tokenarray.hxx
@@ -429,6 +429,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 4f06b4b6473b..1188bbd9da2c 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1226,7 +1226,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 013a0058ba5d..6c1bca21f035 100644
--- a/sc/inc/formulacell.hxx
+++ b/sc/inc/formulacell.hxx
@@ -443,7 +443,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 93cc0697090d..9547dcf8c072 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 7fcc4f5e259f..c858be2b1142 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;
@@ -153,20 +154,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());
@@ -192,6 +214,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 df447744e56e..302f2db07a01 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -1529,9 +1529,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;
@@ -1559,11 +1565,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