[Libreoffice-commits] core.git: Branch 'libreoffice-6-1' - sc/inc sc/source

Dennis Francis dennis.francis at collabora.co.uk
Wed Jun 13 09:47:13 UTC 2018


 sc/inc/column.hxx                   |    6 ++++--
 sc/source/core/data/column3.cxx     |   14 +++++++++-----
 sc/source/core/data/formulacell.cxx |    2 +-
 3 files changed, 14 insertions(+), 8 deletions(-)

New commits:
commit b87791384558c970707c6b24656779be88f2de17
Author: Dennis Francis <dennis.francis at collabora.co.uk>
Date:   Sun Jun 10 15:23:39 2018 +0530

    tdf#114710 : Fixes crash when pasting as GDI metafile
    
    The bug document has a formula cell (at O7) that depends on cells with
    non-default number formats, but this cell's number format was force
    set by the user to the default. So the mbNeedsNumberFormat for this
    ScFormulaCell object is now false. But when a copy to clip
    and paste as GDI metafile is made, this subtle information about
    the "user forced default number format" is lost.
    ScColumn::SetFormulaCell() is used while making the copies of the
    original formula cell to clipdoc and then to another document, where
    it sets the field mbNeedsNumberFormat of the formulacell to true if the
    number-format of the target cell is default. Note that the
    number-formats along with all attributes of the target cells are
    copied from the source before copying the actual cell contents.
    As a result, after copy pasting, the formulacell at O7 of the new
    document will have mbNeedsNumberFormat = true. This causes the
    attribute modification (in ScAttrArray of corresponding column)
    while Interpret()'ing the cell. Unfortunately this Interpret() happens
    while in a call to ScRefCellValue::hasNumeric() while in the middle of
    rendering the cell of the new document (in ScOutputData::LayoutStrings()),
    and naturally this messes up the ScPatternAttr references the view has been
    caching, hence the crash.
    
    The steps involved in the fix are :-
    1. Carry around the state of mbNeedsNumberFormat in
       the copy-constructor of ScFormulaCell, in case the src formula-cell
       is not yet Interpret()'ed. Note that after Interpret() is done, the
       mbNeedsNumberFormat is set back to false and inherited numfmt is
       applied to attributes data structure.
    
    2. In ScColumn::SetFormulaCell(), allow an optional param
       bInheritNumFormatIfNeeded (default = true). In that method,
       the mbNeedNumberFormat is set to true only if this flag is true
       and the cell format is default. So when the copy/paste operation
       is going on, we pass the mbNeedNumberFormat of the source
       formula-cell for the new parameter to SetFormulaCell().
    
    Change-Id: I535e413d4bde4c33a5f6ad3ce01536d0e94e7074
    Reviewed-on: https://gerrit.libreoffice.org/55555
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Eike Rathke <erack at redhat.com>
    (cherry picked from commit 37f6e5de1e72d209b0892734f4de5c4d8a849885)
    Reviewed-on: https://gerrit.libreoffice.org/55618
    Reviewed-by: Dennis Francis <dennis.francis at collabora.co.uk>

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 3f7493ea5fbd..bff5e621160e 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -331,10 +331,12 @@ public:
      */
     ScFormulaCell* SetFormulaCell(
         SCROW nRow, ScFormulaCell* pCell,
-        sc::StartListeningType eListenType = sc::SingleCellListening );
+        sc::StartListeningType eListenType = sc::SingleCellListening,
+        bool bInheritNumFormatIfNeeded = true);
     void SetFormulaCell(
         sc::ColumnBlockPosition& rBlockPos, SCROW nRow, ScFormulaCell* pCell,
-        sc::StartListeningType eListenType = sc::SingleCellListening );
+        sc::StartListeningType eListenType = sc::SingleCellListening,
+        bool bInheritNumFormatIfNeeded = true);
 
     bool SetFormulaCells( SCROW nRow, std::vector<ScFormulaCell*>& rCells );
 
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index fc9f253e72fd..a3b3ca5efc3e 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -1003,7 +1003,9 @@ public:
                         {
                             mrDestCol.SetFormulaCell(
                                 maDestBlockPos, nSrcRow + mnRowOffset,
-                                new ScFormulaCell(rSrcCell, *mrDestCol.GetDoc(), aDestPos));
+                                new ScFormulaCell(rSrcCell, *mrDestCol.GetDoc(), aDestPos),
+                                sc::SingleCellListening,
+                                rSrcCell.NeedsNumberFormat());
                         }
                     }
                     else if (bNumeric || bDateTime || bString)
@@ -1969,11 +1971,12 @@ void ScColumn::SetFormula( SCROW nRow, const OUString& rFormula, formula::Formul
 }
 
 ScFormulaCell* ScColumn::SetFormulaCell(
-    SCROW nRow, ScFormulaCell* pCell, sc::StartListeningType eListenType )
+    SCROW nRow, ScFormulaCell* pCell, sc::StartListeningType eListenType,
+    bool bInheritNumFormatIfNeeded )
 {
     sc::CellStoreType::iterator it = GetPositionToInsert(nRow);
     sal_uInt32 nCellFormat = GetNumberFormat(GetDoc()->GetNonThreadedContext(), nRow);
-    if( (nCellFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0)
+    if( (nCellFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0 && bInheritNumFormatIfNeeded )
         pCell->SetNeedNumberFormat(true);
     it = maCells.set(it, nRow, pCell);
     maCellTextAttrs.set(nRow, sc::CellTextAttr());
@@ -1986,11 +1989,12 @@ ScFormulaCell* ScColumn::SetFormulaCell(
 
 void ScColumn::SetFormulaCell(
     sc::ColumnBlockPosition& rBlockPos, SCROW nRow, ScFormulaCell* pCell,
-    sc::StartListeningType eListenType )
+    sc::StartListeningType eListenType,
+    bool bInheritNumFormatIfNeeded )
 {
     rBlockPos.miCellPos = GetPositionToInsert(rBlockPos.miCellPos, nRow);
     sal_uInt32 nCellFormat = GetNumberFormat(GetDoc()->GetNonThreadedContext(), nRow);
-    if( (nCellFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0)
+    if( (nCellFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0 && bInheritNumFormatIfNeeded )
         pCell->SetNeedNumberFormat(true);
     rBlockPos.miCellPos = maCells.set(rBlockPos.miCellPos, nRow, pCell);
     rBlockPos.miCellTextAttrPos = maCellTextAttrs.set(
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index e1a80effa3b3..40f5cbbd3ba6 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -817,7 +817,7 @@ ScFormulaCell::ScFormulaCell(const ScFormulaCell& rCell, ScDocument& rDoc, const
     bInChangeTrack( false ),
     bTableOpDirty( false ),
     bNeedListening( false ),
-    mbNeedsNumberFormat( false ),
+    mbNeedsNumberFormat( rCell.mbNeedsNumberFormat ),
     mbAllowNumberFormatChange(false),
     mbPostponedDirty(false),
     mbIsExtRef(false),


More information about the Libreoffice-commits mailing list