diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2016-12-02 11:20:59 +0300 |
---|---|---|
committer | Kohei Yoshida <libreoffice@kohei.us> | 2016-12-05 22:12:00 +0000 |
commit | da54ed01e4814290299ebf6a0c5d472cb827f77d (patch) | |
tree | 0b7e51cba2e939ecea740824ab63f3236fcddab9 | |
parent | b6e90a4fdcf6d367a7e754fa12add9c8d1e1aed9 (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.cxx | 1 | ||||
-rw-r--r-- | oox/source/core/xmlfilterbase.cxx | 5 | ||||
-rw-r--r-- | oox/source/token/namespaces-strict.txt | 1 | ||||
-rw-r--r-- | oox/source/token/namespaces.hxx.tail | 1 | ||||
-rw-r--r-- | oox/source/token/namespaces.txt | 1 | ||||
-rw-r--r-- | oox/source/token/tokens.txt | 1 | ||||
-rw-r--r-- | sc/qa/unit/bugfix-test.cxx | 98 | ||||
-rw-r--r-- | sc/qa/unit/data/xlsx/tdf104310-2.xlsx | bin | 0 -> 8103 bytes | |||
-rw-r--r-- | sc/qa/unit/data/xlsx/tdf104310.xlsx | bin | 0 -> 4668 bytes | |||
-rw-r--r-- | sc/source/filter/inc/worksheetfragment.hxx | 77 | ||||
-rw-r--r-- | sc/source/filter/oox/extlstcontext.cxx | 8 | ||||
-rw-r--r-- | sc/source/filter/oox/worksheetfragment.cxx | 266 |
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 Binary files differnew file mode 100644 index 000000000000..dc5e9ac36bb5 --- /dev/null +++ b/sc/qa/unit/data/xlsx/tdf104310-2.xlsx diff --git a/sc/qa/unit/data/xlsx/tdf104310.xlsx b/sc/qa/unit/data/xlsx/tdf104310.xlsx Binary files differnew file mode 100644 index 000000000000..95570d39ff9f --- /dev/null +++ b/sc/qa/unit/data/xlsx/tdf104310.xlsx 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 ) : |