summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDennis Francis <dennis.francis@collabora.co.uk>2018-06-10 15:23:39 +0530
committerDennis Francis <dennis.francis@collabora.co.uk>2018-06-13 11:47:47 +0200
commit5ddeed368855eb1bde1d9e972896bb774c71f277 (patch)
tree380472db65019688c939f74f0fae2149ff146c85
parentee912a0ff9543452ae65585f6de622356613f0a7 (diff)
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(). Reviewed-on: https://gerrit.libreoffice.org/55555 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Eike Rathke <erack@redhat.com> (cherry picked from commit 37f6e5de1e72d209b0892734f4de5c4d8a849885) Change-Id: I535e413d4bde4c33a5f6ad3ce01536d0e94e7074 Reviewed-on: https://gerrit.libreoffice.org/55693 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Dennis Francis <dennis.francis@collabora.co.uk>
-rw-r--r--sc/inc/column.hxx6
-rw-r--r--sc/source/core/data/column3.cxx14
-rw-r--r--sc/source/core/data/formulacell.cxx2
3 files changed, 14 insertions, 8 deletions
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 3e8ccee3cee2..7eeefd6e96b7 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -340,10 +340,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 855f82c39423..63fd08498d59 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -998,7 +998,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)
@@ -1963,11 +1965,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(pDocument->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());
@@ -1980,11 +1983,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(pDocument->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 5b8e6d1d36e9..0d1ca1bf7f6d 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -815,7 +815,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),