summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2016-10-15 16:42:42 +0200
committerCaolán McNamara <caolanm@redhat.com>2016-10-27 16:04:24 +0000
commitdac45f154a72e1bb35d7b0540ab5723390c11b30 (patch)
treeeb672fa2a3ec3dd6dfbad7cdeed907e90df38b8b
parent873929d14aa4013eb3dac216db9b828ff01e8d8f (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. (cherry picked from commit 2a45b26c619d1125419819d501a7653cf8d6e5ca) Backport. Also added to WorkerThread. Conflicts: sc/source/filter/oox/formulabuffer.cxx Change-Id: Ib89ba70fd7c3c515439498882fef90ca7c6e278d Reviewed-on: https://gerrit.libreoffice.org/29903 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r--sc/source/filter/inc/workbookhelper.hxx2
-rw-r--r--sc/source/filter/oox/formulabuffer.cxx43
-rw-r--r--sc/source/filter/oox/workbookhelper.cxx17
3 files changed, 47 insertions, 15 deletions
diff --git a/sc/source/filter/inc/workbookhelper.hxx b/sc/source/filter/inc/workbookhelper.hxx
index c314bf592939..59c5c56ba50b 100644
--- a/sc/source/filter/inc/workbookhelper.hxx
+++ b/sc/source/filter/inc/workbookhelper.hxx
@@ -136,6 +136,8 @@ public:
bool isWorkbookFile() 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 d7a574e39271..41c99f80062e 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);
}
class WorkerThread: public salhelper::Thread
@@ -317,6 +328,7 @@ class WorkerThread: public salhelper::Thread
FormulaBuffer::SheetItem& mrItem;
std::unique_ptr<SvNumberFormatter> mpFormatter;
const uno::Sequence<sheet::ExternalLinkInfo>& mrExternalLinks;
+ bool mbGeneratorKnownGood;
public:
WorkerThread(const WorkerThread&) = delete;
@@ -324,16 +336,17 @@ public:
WorkerThread(
ScDocumentImport& rDoc, FormulaBuffer::SheetItem& rItem, SvNumberFormatter* pFormatter,
- const uno::Sequence<sheet::ExternalLinkInfo>& rExternalLinks ) :
+ const uno::Sequence<sheet::ExternalLinkInfo>& rExternalLinks, bool bGeneratorKnownGood ) :
salhelper::Thread("xlsx-import-formula-buffer-worker-thread"),
- mrDoc(rDoc), mrItem(rItem), mpFormatter(pFormatter), mrExternalLinks(rExternalLinks) {}
+ mrDoc(rDoc), mrItem(rItem), mpFormatter(pFormatter), mrExternalLinks(rExternalLinks),
+ mbGeneratorKnownGood(bGeneratorKnownGood) {}
virtual ~WorkerThread() {}
protected:
virtual void execute() override
{
- processSheetFormulaCells(mrDoc, mrItem, *mpFormatter, mrExternalLinks);
+ processSheetFormulaCells(mrDoc, mrItem, *mpFormatter, mrExternalLinks, mbGeneratorKnownGood);
}
};
@@ -401,7 +414,8 @@ void FormulaBuffer::finalizeImport()
if (nThreadCount == 1)
{
for (; it != itEnd; ++it)
- processSheetFormulaCells(rDoc, *it, *rDoc.getDoc().GetFormatTable(), getExternalLinks().getLinkInfos());
+ processSheetFormulaCells(rDoc, *it, *rDoc.getDoc().GetFormatTable(), getExternalLinks().getLinkInfos(),
+ isGeneratorKnownGood());
}
else
{
@@ -419,7 +433,8 @@ void FormulaBuffer::finalizeImport()
if (it == itEnd)
break;
- WorkerThreadRef xThread(new WorkerThread(rDoc, *it, rDoc.getDoc().CreateFormatTable(), getExternalLinks().getLinkInfos()));
+ WorkerThreadRef xThread(new WorkerThread(rDoc, *it, rDoc.getDoc().CreateFormatTable(),
+ getExternalLinks().getLinkInfos(), isGeneratorKnownGood()));
++it;
aThreads.push_back(xThread);
xThread->launch();
diff --git a/sc/source/filter/oox/workbookhelper.cxx b/sc/source/filter/oox/workbookhelper.cxx
index a12491f299c1..736649d75d25 100644
--- a/sc/source/filter/oox/workbookhelper.cxx
+++ b/sc/source/filter/oox/workbookhelper.cxx
@@ -138,6 +138,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; }
@@ -277,6 +279,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;
@@ -541,6 +544,7 @@ void WorkbookGlobals::initialize()
maPageStyleServ = "com.sun.star.style.PageStyle";
mnCurrSheet = -1;
mbWorkbook = true;
+ mbGeneratorKnownGood = false;
meTextEnc = osl_getThreadTextEncoding();
mbHasCodePage = false;
@@ -562,13 +566,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));
@@ -704,6 +714,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 );