summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sc/source/filter/inc/workbookhelper.hxx2
-rw-r--r--sc/source/filter/oox/formulabuffer.cxx32
-rw-r--r--sc/source/filter/oox/workbookhelper.cxx17
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 );