summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2016-12-02 11:20:59 +0300
committerKohei Yoshida <libreoffice@kohei.us>2016-12-05 22:12:00 +0000
commitda54ed01e4814290299ebf6a0c5d472cb827f77d (patch)
tree0b7e51cba2e939ecea740824ab63f3236fcddab9
parentb6e90a4fdcf6d367a7e754fa12add9c8d1e1aed9 (diff)
tdf#104310: Accept x12ac and x14 extensions in dataValidations
This is backport of commits 0afbe8d5 and ce17ebb6 from master. Change-Id: I155d160a0d19b037e6e765d960daf4545535c0ed Reviewed-on: https://gerrit.libreoffice.org/31527 Reviewed-by: Kohei Yoshida <libreoffice@kohei.us> Tested-by: Kohei Yoshida <libreoffice@kohei.us>
-rw-r--r--oox/source/core/fragmenthandler2.cxx1
-rw-r--r--oox/source/core/xmlfilterbase.cxx5
-rw-r--r--oox/source/token/namespaces-strict.txt1
-rw-r--r--oox/source/token/namespaces.hxx.tail1
-rw-r--r--oox/source/token/namespaces.txt1
-rw-r--r--oox/source/token/tokens.txt1
-rw-r--r--sc/qa/unit/bugfix-test.cxx98
-rw-r--r--sc/qa/unit/data/xlsx/tdf104310-2.xlsxbin0 -> 8103 bytes
-rw-r--r--sc/qa/unit/data/xlsx/tdf104310.xlsxbin0 -> 4668 bytes
-rw-r--r--sc/source/filter/inc/worksheetfragment.hxx77
-rw-r--r--sc/source/filter/oox/extlstcontext.cxx8
-rw-r--r--sc/source/filter/oox/worksheetfragment.cxx266
12 files changed, 333 insertions, 126 deletions
diff --git a/oox/source/core/fragmenthandler2.cxx b/oox/source/core/fragmenthandler2.cxx
index f9040697d204..0e64bb2cb8b0 100644
--- a/oox/source/core/fragmenthandler2.cxx
+++ b/oox/source/core/fragmenthandler2.cxx
@@ -73,6 +73,7 @@ bool FragmentHandler2::prepareMceContext( sal_Int32 nElement, const AttributeLis
{
"p14",
"p15",
+ "x12ac",
};
if (std::find(aSupportedNS.begin(), aSupportedNS.end(), aRequires) != aSupportedNS.end())
diff --git a/oox/source/core/xmlfilterbase.cxx b/oox/source/core/xmlfilterbase.cxx
index a2c3b9bf8203..3cda81ec77a2 100644
--- a/oox/source/core/xmlfilterbase.cxx
+++ b/oox/source/core/xmlfilterbase.cxx
@@ -137,7 +137,10 @@ struct NamespaceIds: public rtl::StaticWithInit<
{"http://schemas.microsoft.com/office/powerpoint/2010/main",
NMSP_p14},
{"http://schemas.microsoft.com/office/powerpoint/2012/main",
- NMSP_p15}};
+ NMSP_p15},
+ {"http://schemas.microsoft.com/office/spreadsheetml/2011/1/ac",
+ NMSP_x12ac},
+ };
}
};
diff --git a/oox/source/token/namespaces-strict.txt b/oox/source/token/namespaces-strict.txt
index f9a4633488c7..0f606f775213 100644
--- a/oox/source/token/namespaces-strict.txt
+++ b/oox/source/token/namespaces-strict.txt
@@ -83,6 +83,7 @@ p14 http://schemas.microsoft.com/office/powerpoint/2010/main
# MSO 2012/2013 extensions ---------------------------------------------------------
p15 http://schemas.microsoft.com/office/powerpoint/2012/main
+x12ac http://schemas.microsoft.com/office/spreadsheetml/2011/1/ac
# extlst namespaces
diff --git a/oox/source/token/namespaces.hxx.tail b/oox/source/token/namespaces.hxx.tail
index 89f8c1c4d10b..17770dcbbdae 100644
--- a/oox/source/token/namespaces.hxx.tail
+++ b/oox/source/token/namespaces.hxx.tail
@@ -46,6 +46,7 @@ inline sal_Int32 getNamespace( sal_Int32 nToken ) { return nToken & NMSP_MASK; }
#define R_TOKEN( token ) OOX_TOKEN( officeRel, token )
#define VML_TOKEN( token ) OOX_TOKEN( vml, token )
#define VMLX_TOKEN( token ) OOX_TOKEN( vmlExcel, token )
+#define X12AC_TOKEN( token ) OOX_TOKEN( x12ac, token )
#define XDR_TOKEN( token ) OOX_TOKEN( dmlSpreadDr, token )
#define XLS_TOKEN( token ) OOX_TOKEN( xls, token )
#define XLS14_TOKEN( token ) OOX_TOKEN( xls14Lst, token )
diff --git a/oox/source/token/namespaces.txt b/oox/source/token/namespaces.txt
index 792057256e81..4b6f49a56ef8 100644
--- a/oox/source/token/namespaces.txt
+++ b/oox/source/token/namespaces.txt
@@ -83,6 +83,7 @@ p14 http://schemas.microsoft.com/office/powerpoint/2010/main
# MSO 2012/2013 extensions ---------------------------------------------------------
p15 http://schemas.microsoft.com/office/powerpoint/2012/main
+x12ac http://schemas.microsoft.com/office/spreadsheetml/2011/1/ac
# extlst namespaces
diff --git a/oox/source/token/tokens.txt b/oox/source/token/tokens.txt
index b113c84ee209..6d4fcb8a47f5 100644
--- a/oox/source/token/tokens.txt
+++ b/oox/source/token/tokens.txt
@@ -5781,6 +5781,7 @@ writeProtection
wsDr
wsp
x
+x12ac
x14
xAlign
xIllusions
diff --git a/sc/qa/unit/bugfix-test.cxx b/sc/qa/unit/bugfix-test.cxx
index b137cf72c6ef..21e66c7d204d 100644
--- a/sc/qa/unit/bugfix-test.cxx
+++ b/sc/qa/unit/bugfix-test.cxx
@@ -7,66 +7,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-#include <sal/config.h>
-#include <unotest/filters-test.hxx>
-#include <test/bootstrapfixture.hxx>
-#include <rtl/strbuf.hxx>
-#include <osl/file.hxx>
-
-#include <sfx2/app.hxx>
-#include <sfx2/docfilt.hxx>
-#include <sfx2/docfile.hxx>
-#include <sfx2/sfxmodelfactory.hxx>
-#include <svl/stritem.hxx>
-#include <svx/svdograf.hxx>
-
-#include "drwlayer.hxx"
-#include <svx/svdpage.hxx>
-#include <svx/svdoole2.hxx>
-#include <editeng/wghtitem.hxx>
-#include <editeng/postitem.hxx>
-#include <editeng/udlnitem.hxx>
-#include <editeng/editobj.hxx>
-#include <editeng/borderline.hxx>
-#include <editeng/flditem.hxx>
-#include <dbdata.hxx>
#include "validat.hxx"
-#include "formulacell.hxx"
-#include "userdat.hxx"
-#include "dpobject.hxx"
-#include "dpsave.hxx"
-#include "stlsheet.hxx"
-#include "docfunc.hxx"
-#include "markdata.hxx"
-#include "colorscale.hxx"
-#include "olinetab.hxx"
-#include "patattr.hxx"
-#include "scitems.hxx"
-#include "docsh.hxx"
-#include "editutil.hxx"
-#include "cellvalue.hxx"
-#include "attrib.hxx"
-#include "dpshttab.hxx"
#include "tabvwsh.hxx"
-#include <scopetools.hxx>
-#include <columnspanset.hxx>
-#include <tokenstringcontext.hxx>
-
-#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
-#include <com/sun/star/drawing/XControlShape.hpp>
-#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
-#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
-#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
-#include <com/sun/star/sheet/GeneralFunction.hpp>
-#include <com/sun/star/container/XIndexAccess.hpp>
-#include <com/sun/star/frame/XModel.hpp>
-#include <com/sun/star/text/textfield/Type.hpp>
-#include <com/sun/star/chart2/XChartDocument.hpp>
-#include <com/sun/star/chart2/data/XDataReceiver.hpp>
#include <com/sun/star/frame/Desktop.hpp>
-
#include "helper/qahelper.hxx"
-#include "helper/shared_test_impl.hxx"
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
@@ -90,6 +34,7 @@ public:
void testTdf88821();
void testTdf88821_2();
void testTdf103960();
+ void testTdf104310();
CPPUNIT_TEST_SUITE(ScFiltersTest);
CPPUNIT_TEST(testTdf64229);
@@ -102,6 +47,7 @@ public:
CPPUNIT_TEST(testTdf88821);
CPPUNIT_TEST(testTdf88821_2);
CPPUNIT_TEST(testTdf103960);
+ CPPUNIT_TEST(testTdf104310);
CPPUNIT_TEST_SUITE_END();
private:
uno::Reference<uno::XInterface> m_xCalcComponent;
@@ -282,6 +228,46 @@ void ScFiltersTest::testTdf103960()
xDocSh->DoClose();
}
+void ScFiltersTest::testTdf104310()
+{
+ // 1. Test x14 extension
+ {
+ ScDocShellRef xDocSh = loadDoc("tdf104310.", FORMAT_XLSX);
+ ScDocument& rDoc = xDocSh->GetDocument();
+
+ const ScValidationData* pData = rDoc.GetValidationEntry(1);
+ CPPUNIT_ASSERT(pData);
+
+ // Make sure the list is correct.
+ std::vector<ScTypedStrData> aList;
+ pData->FillSelectionList(aList, ScAddress(0, 1, 0));
+ CPPUNIT_ASSERT_EQUAL(size_t(5), aList.size());
+ for (size_t i = 0; i < 5; ++i)
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(double(i + 1), aList[i].GetValue(), 1e-8);
+
+ xDocSh->DoClose();
+ }
+
+ // 2. Test x12ac extension
+ {
+ ScDocShellRef xDocSh = loadDoc("tdf104310-2.", FORMAT_XLSX);
+ ScDocument& rDoc = xDocSh->GetDocument();
+
+ const ScValidationData* pData = rDoc.GetValidationEntry(1);
+ CPPUNIT_ASSERT(pData);
+
+ // Make sure the list is correct.
+ std::vector<ScTypedStrData> aList;
+ pData->FillSelectionList(aList, ScAddress(0, 1, 0));
+ CPPUNIT_ASSERT_EQUAL(size_t(3), aList.size());
+ CPPUNIT_ASSERT_EQUAL(OUString("1"), aList[0].GetString());
+ CPPUNIT_ASSERT_EQUAL(OUString("2,3"), aList[1].GetString());
+ CPPUNIT_ASSERT_EQUAL(OUString("4"), aList[2].GetString());
+
+ xDocSh->DoClose();
+ }
+}
+
ScFiltersTest::ScFiltersTest()
: ScBootstrapFixture( "/sc/qa/unit/data" )
{
diff --git a/sc/qa/unit/data/xlsx/tdf104310-2.xlsx b/sc/qa/unit/data/xlsx/tdf104310-2.xlsx
new file mode 100644
index 000000000000..dc5e9ac36bb5
--- /dev/null
+++ b/sc/qa/unit/data/xlsx/tdf104310-2.xlsx
Binary files differ
diff --git a/sc/qa/unit/data/xlsx/tdf104310.xlsx b/sc/qa/unit/data/xlsx/tdf104310.xlsx
new file mode 100644
index 000000000000..95570d39ff9f
--- /dev/null
+++ b/sc/qa/unit/data/xlsx/tdf104310.xlsx
Binary files differ
diff --git a/sc/source/filter/inc/worksheetfragment.hxx b/sc/source/filter/inc/worksheetfragment.hxx
index 0cd02b3f5d74..9fc348bf73a8 100644
--- a/sc/source/filter/inc/worksheetfragment.hxx
+++ b/sc/source/filter/inc/worksheetfragment.hxx
@@ -25,7 +25,51 @@
namespace oox {
namespace xls {
-class DataValidationsContext : public WorksheetContextBase
+class DataValidationsContext_Base {
+public:
+ DataValidationsContext_Base() {}
+ void SetSqref(const OUString& rChars) { mSqref = rChars; }
+ void SetFormula1(const OUString& rChars) { mFormula1 = rChars; }
+ void SetFormula2(const OUString& rChars) { mFormula2 = rChars; }
+ void SetValidation(::oox::xls::WorksheetHelper& rTarget);
+ /** Imports the dataValidation element containing data validation settings. */
+ void importDataValidation(const AttributeList& rAttribs);
+ /** Imports the DATAVALIDATION record containing data validation settings. */
+ static void importDataValidation(SequenceInputStream& rStrm, ::oox::xls::WorksheetHelper& rTarget);
+ bool isFormula1Set() const { return !mFormula1.isEmpty(); }
+ bool isFormula2Set() const { return !mFormula2.isEmpty(); }
+private:
+ ::std::unique_ptr< ValidationModel > mxValModel;
+ OUString mSqref;
+ OUString mFormula1;
+ OUString mFormula2;
+};
+
+// For following types of validations:
+//
+// <dataValidations count="1">
+// <dataValidation allowBlank="true" operator="equal" showDropDown="false" showErrorMessage="true" showInputMessage="false" sqref="C1:C5" type="list">
+// <formula1>Sheet1!$A$1:$A$5</formula1>
+// <formula2>0</formula2>
+// </dataValidation>
+// </dataValidations>
+//
+// or
+//
+// <dataValidations count="1">
+// <dataValidation type="list" operator="equal" allowBlank="1" showErrorMessage="1" sqref="A1">
+// <mc:AlternateContent xmlns:x12ac="http://schemas.microsoft.com/office/spreadsheetml/2011/1/ac" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
+// <mc:Choice Requires="x12ac">
+// <x12ac:list>1,"2,3",4</x12ac:list>
+// </mc:Choice>
+// <mc:Fallback>
+// <formula1>"1,2,3,4"</formula1>
+// </mc:Fallback>
+// </mc:AlternateContent>
+// </dataValidation>
+// </dataValidations>
+
+class DataValidationsContext : public WorksheetContextBase, private DataValidationsContext_Base
{
public:
explicit DataValidationsContext( WorksheetFragmentBase& rFragment );
@@ -36,15 +80,34 @@ protected:
virtual void onEndElement() override;
virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm ) override;
+};
-private:
- /** Imports the dataValidation element containing data validation settings. */
- void importDataValidation( const AttributeList& rAttribs );
- /** Imports the DATAVALIDATION record containing data validation settings. */
- void importDataValidation( SequenceInputStream& rStrm );
+// For following types of validations:
+//
+// <extLst>
+// <ext uri="{CCE6A557-97BC-4b89-ADB6-D9C93CAAB3DF}" xmlns:x14="http://schemas.microsoft.com/office/spreadsheetml/2009/9/main">
+// <x14:dataValidations count="1" xmlns:xm="http://schemas.microsoft.com/office/excel/2006/main">
+// <x14:dataValidation type="list" allowBlank="1" showInputMessage="1" showErrorMessage="1">
+// <x14:formula1>
+// <xm:f>Sheet1!$A$2:$A$272</xm:f>
+// </x14:formula1>
+// <xm:sqref>A6:A22</xm:sqref>
+// </x14:dataValidation>
+// </x14:dataValidations>
+// </ext>
+// </extLst>
+
+class ExtDataValidationsContext : public WorksheetContextBase, private DataValidationsContext_Base
+{
+public:
+ explicit ExtDataValidationsContext( WorksheetContextBase& rFragment );
+protected:
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) override;
+ virtual void onCharacters( const OUString& rChars ) override;
+ virtual void onEndElement() override;
private:
- ::std::unique_ptr< ValidationModel > mxValModel;
+ sal_Int32 mCurrFormula;
};
class WorksheetFragment : public WorksheetFragmentBase
diff --git a/sc/source/filter/oox/extlstcontext.cxx b/sc/source/filter/oox/extlstcontext.cxx
index 1739bcb3348c..0633ccb107f9 100644
--- a/sc/source/filter/oox/extlstcontext.cxx
+++ b/sc/source/filter/oox/extlstcontext.cxx
@@ -226,9 +226,11 @@ ExtGlobalContext::ExtGlobalContext( WorksheetContextBase& rFragment ):
ContextHandlerRef ExtGlobalContext::onCreateContext( sal_Int32 nElement, const AttributeList& /*rAttribs*/ )
{
- if (nElement == XLS14_TOKEN(conditionalFormatting))
- return new ExtConditionalFormattingContext(*this);
-
+ switch (nElement)
+ {
+ case XLS14_TOKEN(conditionalFormatting): return new ExtConditionalFormattingContext(*this);
+ case XLS14_TOKEN(dataValidations): return new ExtDataValidationsContext(*this);
+ }
return this;
}
diff --git a/sc/source/filter/oox/worksheetfragment.cxx b/sc/source/filter/oox/worksheetfragment.cxx
index cf783211b4d1..660d3ad16571 100644
--- a/sc/source/filter/oox/worksheetfragment.cxx
+++ b/sc/source/filter/oox/worksheetfragment.cxx
@@ -75,6 +75,81 @@ const sal_uInt16 BIFF12_OLEOBJECT_AUTOLOAD = 0x0002;
} // namespace
+void DataValidationsContext_Base::SetValidation(::oox::xls::WorksheetHelper& rTarget)
+{
+ if (!mxValModel.get())
+ return;
+
+ rTarget.getAddressConverter().convertToCellRangeList(mxValModel->maRanges, mSqref, rTarget.getSheetIndex(), true);
+ mxValModel->msRef = mSqref;
+
+ mxValModel->maTokens1 = rTarget.getFormulaParser().importFormula(mxValModel->maRanges.getBaseAddress(), mFormula1);
+ // process string list of a list validation (convert to list of string tokens)
+ if (mxValModel->mnType == XML_list)
+ rTarget.getFormulaParser().convertStringToStringList(mxValModel->maTokens1, ',', true);
+
+ mxValModel->maTokens2 = rTarget.getFormulaParser().importFormula(mxValModel->maRanges.getBaseAddress(), mFormula2);
+
+ rTarget.setValidation(*mxValModel);
+ mxValModel.reset();
+}
+
+void DataValidationsContext_Base::importDataValidation(const AttributeList& rAttribs)
+{
+ mxValModel.reset(new ValidationModel);
+ mFormula1.clear();
+ mFormula2.clear();
+ mSqref = rAttribs.getString(XML_sqref, OUString());
+ mxValModel->maInputTitle = rAttribs.getXString(XML_promptTitle, OUString());
+ mxValModel->maInputMessage = rAttribs.getXString(XML_prompt, OUString());
+ mxValModel->maErrorTitle = rAttribs.getXString(XML_errorTitle, OUString());
+ mxValModel->maErrorMessage = rAttribs.getXString(XML_error, OUString());
+ mxValModel->mnType = rAttribs.getToken(XML_type, XML_none);
+ mxValModel->mnOperator = rAttribs.getToken(XML_operator, XML_between);
+ mxValModel->mnErrorStyle = rAttribs.getToken(XML_errorStyle, XML_stop);
+ mxValModel->mbShowInputMsg = rAttribs.getBool(XML_showInputMessage, false);
+ mxValModel->mbShowErrorMsg = rAttribs.getBool(XML_showErrorMessage, false);
+ /* The attribute showDropDown@dataValidation is in fact a "suppress
+ dropdown" flag, as it was in the BIFF format! ECMA specification
+ and attribute name are plain wrong! */
+ mxValModel->mbNoDropDown = rAttribs.getBool(XML_showDropDown, false);
+ mxValModel->mbAllowBlank = rAttribs.getBool(XML_allowBlank, false);
+}
+
+void DataValidationsContext_Base::importDataValidation(SequenceInputStream& rStrm, ::oox::xls::WorksheetHelper& rTarget)
+{
+ ValidationModel aModel;
+
+ sal_uInt32 nFlags;
+ BinRangeList aRanges;
+ nFlags = rStrm.readuInt32();
+ rStrm >> aRanges >> aModel.maErrorTitle >> aModel.maErrorMessage >> aModel.maInputTitle >> aModel.maInputMessage;
+
+ // equal flags in all BIFFs
+ aModel.setBiffType(extractValue< sal_uInt8 >(nFlags, 0, 4));
+ aModel.setBiffOperator(extractValue< sal_uInt8 >(nFlags, 20, 4));
+ aModel.setBiffErrorStyle(extractValue< sal_uInt8 >(nFlags, 4, 3));
+ aModel.mbAllowBlank = getFlag(nFlags, BIFF_DATAVAL_ALLOWBLANK);
+ aModel.mbNoDropDown = getFlag(nFlags, BIFF_DATAVAL_NODROPDOWN);
+ aModel.mbShowInputMsg = getFlag(nFlags, BIFF_DATAVAL_SHOWINPUT);
+ aModel.mbShowErrorMsg = getFlag(nFlags, BIFF_DATAVAL_SHOWERROR);
+
+ // cell range list
+ rTarget.getAddressConverter().convertToCellRangeList(aModel.maRanges, aRanges, rTarget.getSheetIndex(), true);
+
+ // condition formula(s)
+ FormulaParser& rParser = rTarget.getFormulaParser();
+ CellAddress aBaseAddr = aModel.maRanges.getBaseAddress();
+ aModel.maTokens1 = rParser.importFormula(aBaseAddr, FORMULATYPE_VALIDATION, rStrm);
+ aModel.maTokens2 = rParser.importFormula(aBaseAddr, FORMULATYPE_VALIDATION, rStrm);
+ // process string list of a list validation (convert to list of string tokens)
+ if ((aModel.mnType == XML_list) && getFlag(nFlags, BIFF_DATAVAL_STRINGLIST))
+ rParser.convertStringToStringList(aModel.maTokens1, ',', true);
+
+ // set validation data
+ rTarget.setValidation(aModel);
+}
+
DataValidationsContext::DataValidationsContext( WorksheetFragmentBase& rFragment ) :
WorksheetContextBase( rFragment )
{
@@ -82,7 +157,7 @@ DataValidationsContext::DataValidationsContext( WorksheetFragmentBase& rFragment
ContextHandlerRef DataValidationsContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
{
- switch( getCurrentElement() )
+ switch( getCurrentElementWithMce() )
{
case XLS_TOKEN( dataValidations ):
if( nElement == XLS_TOKEN( dataValidation ) )
@@ -94,100 +169,173 @@ ContextHandlerRef DataValidationsContext::onCreateContext( sal_Int32 nElement, c
case XLS_TOKEN( dataValidation ):
switch( nElement )
{
+ case MCE_TOKEN( AlternateContent ):
case XLS_TOKEN( formula1 ):
case XLS_TOKEN( formula2 ):
return this; // collect formulas in onCharacters()
}
break;
+ case MCE_TOKEN( AlternateContent ):
+ switch( nElement )
+ {
+ case MCE_TOKEN( Choice ):
+ case MCE_TOKEN( Fallback ):
+ return this;
+ }
+ break;
+ case MCE_TOKEN( Choice ):
+ switch( nElement )
+ {
+ case X12AC_TOKEN( list ):
+ return this;
+ }
+ break;
+ case MCE_TOKEN( Fallback ):
+ switch( nElement )
+ {
+ case XLS_TOKEN( formula1 ):
+ if (!isFormula1Set()) // only if more preferable choice was not used
+ return this; // collect formulas in onCharacters()
+ break;
+ case XLS_TOKEN( formula2 ):
+ if (!isFormula2Set()) // only if more preferable choice was not used
+ return this; // collect formulas in onCharacters()
+ break;
+ }
+ break;
}
return nullptr;
}
+namespace {
+// Convert strings like 1,"2,3",4 to form "1","2,3","4"
+OUString NormalizeOoxList(const OUString& aList)
+{
+ OUStringBuffer aResult("\"");
+ bool bInsideQuotes = false;
+ const sal_Int32 nLen = aList.getLength();
+ for (sal_Int32 i = 0; i < nLen; ++i)
+ {
+ sal_Unicode ch = aList[i];
+
+ switch (ch)
+ {
+ case L'"':
+ bInsideQuotes = !bInsideQuotes;
+ break;
+ case L',':
+ if (!bInsideQuotes)
+ {
+ aResult.append("\",\"");
+ break;
+ }
+ SAL_FALLTHROUGH;
+ default:
+ aResult.append(ch);
+ break;
+ }
+ }
+ return aResult.append('"').makeStringAndClear();
+}
+}
+
void DataValidationsContext::onCharacters( const OUString& rChars )
{
- if( mxValModel.get() ) switch( getCurrentElement() )
+ switch( getCurrentElement() )
{
case XLS_TOKEN( formula1 ):
- mxValModel->maTokens1 = getFormulaParser().importFormula( mxValModel->maRanges.getBaseAddress(), rChars );
- // process string list of a list validation (convert to list of string tokens)
- if( mxValModel->mnType == XML_list )
- getFormulaParser().convertStringToStringList( mxValModel->maTokens1, ',', true );
+ SetFormula1( rChars );
break;
case XLS_TOKEN( formula2 ):
- mxValModel->maTokens2 = getFormulaParser().importFormula( mxValModel->maRanges.getBaseAddress(), rChars );
+ SetFormula2( rChars );
+ break;
+ case X12AC_TOKEN( list ):
+ SetFormula1( NormalizeOoxList( rChars ) );
break;
}
}
void DataValidationsContext::onEndElement()
{
- if( isCurrentElement( XLS_TOKEN( dataValidation ) ) && mxValModel.get() )
+ if( getCurrentElementWithMce() == XLS_TOKEN( dataValidation ) )
{
- setValidation( *mxValModel );
- mxValModel.reset();
+ SetValidation( *this );
}
}
ContextHandlerRef DataValidationsContext::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
{
if( nRecId == BIFF12_ID_DATAVALIDATION )
- importDataValidation( rStrm );
+ importDataValidation( rStrm, *this );
return nullptr;
}
-void DataValidationsContext::importDataValidation( const AttributeList& rAttribs )
-{
- mxValModel.reset( new ValidationModel );
- getAddressConverter().convertToCellRangeList( mxValModel->maRanges, rAttribs.getString( XML_sqref, OUString() ), getSheetIndex(), true );
- mxValModel->msRef = rAttribs.getString( XML_sqref, OUString() );
- mxValModel->maInputTitle = rAttribs.getXString( XML_promptTitle, OUString() );
- mxValModel->maInputMessage = rAttribs.getXString( XML_prompt, OUString() );
- mxValModel->maErrorTitle = rAttribs.getXString( XML_errorTitle, OUString() );
- mxValModel->maErrorMessage = rAttribs.getXString( XML_error, OUString() );
- mxValModel->mnType = rAttribs.getToken( XML_type, XML_none );
- mxValModel->mnOperator = rAttribs.getToken( XML_operator, XML_between );
- mxValModel->mnErrorStyle = rAttribs.getToken( XML_errorStyle, XML_stop );
- mxValModel->mbShowInputMsg = rAttribs.getBool( XML_showInputMessage, false );
- mxValModel->mbShowErrorMsg = rAttribs.getBool( XML_showErrorMessage, false );
- /* The attribute showDropDown@dataValidation is in fact a "suppress
- dropdown" flag, as it was in the BIFF format! ECMA specification
- and attribute name are plain wrong! */
- mxValModel->mbNoDropDown = rAttribs.getBool( XML_showDropDown, false );
- mxValModel->mbAllowBlank = rAttribs.getBool( XML_allowBlank, false );
+ExtDataValidationsContext::ExtDataValidationsContext( WorksheetContextBase& rFragment ) :
+ WorksheetContextBase( rFragment ), mCurrFormula( 0 )
+{
}
-void DataValidationsContext::importDataValidation( SequenceInputStream& rStrm )
+ContextHandlerRef ExtDataValidationsContext::onCreateContext(sal_Int32 nElement, const AttributeList& rAttribs)
{
- ValidationModel aModel;
-
- sal_uInt32 nFlags;
- BinRangeList aRanges;
- nFlags = rStrm.readuInt32();
- rStrm >> aRanges >> aModel.maErrorTitle >> aModel.maErrorMessage >> aModel.maInputTitle >> aModel.maInputMessage;
-
- // equal flags in all BIFFs
- aModel.setBiffType( extractValue< sal_uInt8 >( nFlags, 0, 4 ) );
- aModel.setBiffOperator( extractValue< sal_uInt8 >( nFlags, 20, 4 ) );
- aModel.setBiffErrorStyle( extractValue< sal_uInt8 >( nFlags, 4, 3 ) );
- aModel.mbAllowBlank = getFlag( nFlags, BIFF_DATAVAL_ALLOWBLANK );
- aModel.mbNoDropDown = getFlag( nFlags, BIFF_DATAVAL_NODROPDOWN );
- aModel.mbShowInputMsg = getFlag( nFlags, BIFF_DATAVAL_SHOWINPUT );
- aModel.mbShowErrorMsg = getFlag( nFlags, BIFF_DATAVAL_SHOWERROR );
-
- // cell range list
- getAddressConverter().convertToCellRangeList( aModel.maRanges, aRanges, getSheetIndex(), true );
+ switch( getCurrentElement() )
+ {
+ case XLS14_TOKEN( dataValidations ):
+ if ( nElement == XLS14_TOKEN( dataValidation ) )
+ {
+ importDataValidation( rAttribs );
+ return this;
+ }
+ break;
+ case XLS14_TOKEN( dataValidation ):
+ switch ( nElement )
+ {
+ case XLS14_TOKEN( formula1 ):
+ case XLS14_TOKEN( formula2 ):
+ mCurrFormula = nElement;
+ return this;
+ case XM_TOKEN( sqref ):
+ return this; // collect sqref in onCharacters()
+ }
+ break;
+ case XLS14_TOKEN( formula1 ):
+ case XLS14_TOKEN( formula2 ):
+ switch( nElement )
+ {
+ case XM_TOKEN( f ):
+ return this; // collect formulas in onCharacters()
+ }
+ break;
+ }
+ return nullptr;
+}
- // condition formula(s)
- FormulaParser& rParser = getFormulaParser();
- CellAddress aBaseAddr = aModel.maRanges.getBaseAddress();
- aModel.maTokens1 = rParser.importFormula( aBaseAddr, FORMULATYPE_VALIDATION, rStrm );
- aModel.maTokens2 = rParser.importFormula( aBaseAddr, FORMULATYPE_VALIDATION, rStrm );
- // process string list of a list validation (convert to list of string tokens)
- if( (aModel.mnType == XML_list) && getFlag( nFlags, BIFF_DATAVAL_STRINGLIST ) )
- rParser.convertStringToStringList( aModel.maTokens1, ',', true );
+void ExtDataValidationsContext::onCharacters( const OUString& rChars )
+{
+ switch( getCurrentElement() )
+ {
+ case XM_TOKEN( f ):
+ switch( mCurrFormula )
+ {
+ case XLS14_TOKEN( formula1 ):
+ SetFormula1( rChars );
+ break;
+ case XLS14_TOKEN( formula2 ):
+ SetFormula2( rChars );
+ break;
+ }
+ break;
+ case XM_TOKEN( sqref ):
+ SetSqref( rChars );
+ break;
+ }
+}
- // set validation data
- setValidation( aModel );
+void ExtDataValidationsContext::onEndElement()
+{
+ if( isCurrentElement( XLS14_TOKEN( dataValidation ) ) )
+ {
+ SetValidation( *this );
+ }
}
WorksheetFragment::WorksheetFragment( const WorksheetHelper& rHelper, const OUString& rFragmentPath ) :