diff options
author | Eike Rathke <erack@redhat.com> | 2016-10-15 16:42:42 +0200 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2016-10-15 16:49:57 +0200 |
commit | 2a45b26c619d1125419819d501a7653cf8d6e5ca (patch) | |
tree | 364c94f0b2f01be9ef71a8d6dd36970a77f4ef39 /sc | |
parent | 7125de1cdb4d29cc3763147571808033ee207777 (diff) |
Resolves: tdf#98481 Google Sheets uses OOXML t="str" differently
Set string results only for known good generators, otherwise
recalculate. See source code comment.
Change-Id: Ib89ba70fd7c3c515439498882fef90ca7c6e278d
Diffstat (limited to 'sc')
-rw-r--r-- | sc/source/filter/inc/workbookhelper.hxx | 2 | ||||
-rw-r--r-- | sc/source/filter/oox/formulabuffer.cxx | 32 | ||||
-rw-r--r-- | sc/source/filter/oox/workbookhelper.cxx | 17 |
3 files changed, 40 insertions, 11 deletions
diff --git a/sc/source/filter/inc/workbookhelper.hxx b/sc/source/filter/inc/workbookhelper.hxx index c3af3dd47ba5..13f0b1ce9711 100644 --- a/sc/source/filter/inc/workbookhelper.hxx +++ b/sc/source/filter/inc/workbookhelper.hxx @@ -122,6 +122,8 @@ public: SegmentProgressBar& getProgressBar() const; /** Returns the index of the current Calc sheet, if filter currently processes a sheet. */ sal_Int16 getCurrentSheetIndex() const; + /** Returns true when reading a file generated by a known good generator. */ + bool isGeneratorKnownGood() const; /** Sets the VBA project storage used to import VBA source code and forms. */ void setVbaProjectStorage( const StorageRef& rxVbaPrjStrg ); diff --git a/sc/source/filter/oox/formulabuffer.cxx b/sc/source/filter/oox/formulabuffer.cxx index 73d01e748cd7..bed3f5ff2600 100644 --- a/sc/source/filter/oox/formulabuffer.cxx +++ b/sc/source/filter/oox/formulabuffer.cxx @@ -255,7 +255,7 @@ void applyArrayFormulas( } void applyCellFormulaValues( - ScDocumentImport& rDoc, const std::vector<FormulaBuffer::FormulaValue>& rVector ) + ScDocumentImport& rDoc, const std::vector<FormulaBuffer::FormulaValue>& rVector, bool bGeneratorKnownGood ) { svl::SharedStringPool& rStrPool = rDoc.getDoc().GetSharedStringPool(); @@ -278,12 +278,23 @@ void applyCellFormulaValues( } break; case XML_str: - { - svl::SharedString aSS = rStrPool.intern(rValueStr); - pCell->SetResultToken(new formula::FormulaStringToken(aSS)); - pCell->ResetDirty(); - pCell->SetChanged(false); - } + // Excel uses t="str" for string results (per definition + // ECMA-376 18.18.11 ST_CellType (Cell Type) "Cell containing a + // formula string.", but that 't' Cell Data Type attribute, "an + // enumeration representing the cell's data type", is meant for + // the content of the <v> element). We follow that. Other + // applications might not and instead use t="str" for the cell + // content if formula. Setting an otherwise numeric result as + // string result fouls things up, set result strings only for + // documents claiming to be generated by a known good + // generator. See tdf#98481 + if (bGeneratorKnownGood) + { + svl::SharedString aSS = rStrPool.intern(rValueStr); + pCell->SetResultToken(new formula::FormulaStringToken(aSS)); + pCell->ResetDirty(); + pCell->SetChanged(false); + } break; default: ; @@ -293,7 +304,7 @@ void applyCellFormulaValues( void processSheetFormulaCells( ScDocumentImport& rDoc, FormulaBuffer::SheetItem& rItem, SvNumberFormatter& rFormatter, - const uno::Sequence<sheet::ExternalLinkInfo>& rExternalLinks ) + const uno::Sequence<sheet::ExternalLinkInfo>& rExternalLinks, bool bGeneratorKnownGood ) { if (rItem.mpSharedFormulaEntries && rItem.mpSharedFormulaIDs) applySharedFormulas(rDoc, rFormatter, *rItem.mpSharedFormulaEntries, *rItem.mpSharedFormulaIDs); @@ -308,7 +319,7 @@ void processSheetFormulaCells( applyArrayFormulas(rDoc, rFormatter, *rItem.mpArrayFormulas); if (rItem.mpCellFormulaValues) - applyCellFormulaValues(rDoc, *rItem.mpCellFormulaValues); + applyCellFormulaValues(rDoc, *rItem.mpCellFormulaValues, bGeneratorKnownGood); } } @@ -362,7 +373,8 @@ void FormulaBuffer::finalizeImport() std::vector<SheetItem>::iterator it = aSheetItems.begin(), itEnd = aSheetItems.end(); for (; it != itEnd; ++it) - processSheetFormulaCells(rDoc, *it, *rDoc.getDoc().GetFormatTable(), getExternalLinks().getLinkInfos()); + processSheetFormulaCells(rDoc, *it, *rDoc.getDoc().GetFormatTable(), getExternalLinks().getLinkInfos(), + isGeneratorKnownGood()); rDoc.getDoc().SetAutoNameCache(nullptr); diff --git a/sc/source/filter/oox/workbookhelper.cxx b/sc/source/filter/oox/workbookhelper.cxx index 44425e3cdb13..20bfade03e5d 100644 --- a/sc/source/filter/oox/workbookhelper.cxx +++ b/sc/source/filter/oox/workbookhelper.cxx @@ -132,6 +132,8 @@ public: const StorageRef& getVbaProjectStorage() const { return mxVbaPrjStrg; } /** Returns the index of the current Calc sheet, if filter currently processes a sheet. */ inline sal_Int16 getCurrentSheetIndex() const { return mnCurrSheet; } + /** Returns true when reading a file generated by a known good generator. */ + inline bool isGeneratorKnownGood() const { return mbGeneratorKnownGood; } /** Sets the VBA project storage used to import VBA source code and forms. */ inline void setVbaProjectStorage( const StorageRef& rxVbaPrjStrg ) { mxVbaPrjStrg = rxVbaPrjStrg; } @@ -265,6 +267,7 @@ private: StorageRef mxVbaPrjStrg; /// Storage containing the VBA project. sal_Int16 mnCurrSheet; /// Current sheet index in Calc document. bool mbWorkbook; /// True = multi-sheet file. + bool mbGeneratorKnownGood; /// Whether reading a file generated by Excel or Calc. // buffers FormulaBufferPtr mxFormulaBuffer; @@ -524,6 +527,7 @@ void WorkbookGlobals::initialize() maPageStyleServ = "com.sun.star.style.PageStyle"; mnCurrSheet = -1; mbWorkbook = true; + mbGeneratorKnownGood = false; meTextEnc = osl_getThreadTextEncoding(); // the spreadsheet document @@ -544,13 +548,19 @@ void WorkbookGlobals::initialize() Reference< XDocumentPropertiesSupplier > xPropSupplier( mxDoc, UNO_QUERY); Reference< XDocumentProperties > xDocProps = xPropSupplier->getDocumentProperties(); + const OUString aGenerator( xDocProps->getGenerator()); - if (xDocProps->getGenerator().startsWithIgnoreAsciiCase("Microsoft")) + if (aGenerator.startsWithIgnoreAsciiCase("Microsoft")) { + mbGeneratorKnownGood = true; ScCalcConfig aCalcConfig = mpDoc->GetCalcConfig(); aCalcConfig.SetStringRefSyntax( formula::FormulaGrammar::CONV_XL_A1 ) ; mpDoc->SetCalcConfig(aCalcConfig); } + else if (aGenerator.startsWithIgnoreAsciiCase("LibreOffice")) + { + mbGeneratorKnownGood = true; + } mxDocImport.reset(new ScDocumentImport(*mpDoc)); @@ -663,6 +673,11 @@ sal_Int16 WorkbookHelper::getCurrentSheetIndex() const return mrBookGlob.getCurrentSheetIndex(); } +bool WorkbookHelper::isGeneratorKnownGood() const +{ + return mrBookGlob.isGeneratorKnownGood(); +} + void WorkbookHelper::setVbaProjectStorage( const StorageRef& rxVbaPrjStrg ) { mrBookGlob.setVbaProjectStorage( rxVbaPrjStrg ); |