[Libreoffice-commits] core.git: sc/qa sc/source

Mike Kaganski mike.kaganski at collabora.com
Thu Dec 1 17:38:11 UTC 2016


 sc/qa/unit/bugfix-test.cxx                 |   76 ++--------
 sc/qa/unit/data/xlsx/tdf104310.xlsx        |binary
 sc/source/filter/inc/worksheetfragment.hxx |   36 ++++-
 sc/source/filter/oox/extlstcontext.cxx     |    8 -
 sc/source/filter/oox/worksheetfragment.cxx |  203 ++++++++++++++++++++---------
 5 files changed, 199 insertions(+), 124 deletions(-)

New commits:
commit 0afbe8d5ca17c4e24bb49272dc6711925f82f5d5
Author: Mike Kaganski <mike.kaganski at collabora.com>
Date:   Thu Dec 1 07:38:32 2016 +0300

    tdf#104310: Accept also x14-style dataValidations
    
    See https://msdn.microsoft.com/en-us/library/dd921584
    
    Change-Id: I66c9474cbf83cea10ab0e7c2b44592673c8b683f
    Reviewed-on: https://gerrit.libreoffice.org/31456
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Markus Mohrhard <markus.mohrhard at googlemail.com>

diff --git a/sc/qa/unit/bugfix-test.cxx b/sc/qa/unit/bugfix-test.cxx
index 649eba9..9b7f2b7 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;
@@ -91,6 +35,7 @@ public:
     void testTdf88821_2();
     void testTdf103960();
     void testRhbz1390776();
+    void testTdf104310();
 
     CPPUNIT_TEST_SUITE(ScFiltersTest);
     CPPUNIT_TEST(testTdf64229);
@@ -104,6 +49,7 @@ public:
     CPPUNIT_TEST(testTdf88821_2);
     CPPUNIT_TEST(testTdf103960);
     CPPUNIT_TEST(testRhbz1390776);
+    CPPUNIT_TEST(testTdf104310);
     CPPUNIT_TEST_SUITE_END();
 private:
     uno::Reference<uno::XInterface> m_xCalcComponent;
@@ -294,6 +240,24 @@ void ScFiltersTest::testRhbz1390776()
     xDocSh->DoClose();
 }
 
+void ScFiltersTest::testTdf104310()
+{
+    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();
+}
+
 ScFiltersTest::ScFiltersTest()
       : ScBootstrapFixture( "/sc/qa/unit/data" )
 {
diff --git a/sc/qa/unit/data/xlsx/tdf104310.xlsx b/sc/qa/unit/data/xlsx/tdf104310.xlsx
new file mode 100644
index 0000000..95570d3
Binary files /dev/null and b/sc/qa/unit/data/xlsx/tdf104310.xlsx differ
diff --git a/sc/source/filter/inc/worksheetfragment.hxx b/sc/source/filter/inc/worksheetfragment.hxx
index 0cd02b3..2fb52cb 100644
--- a/sc/source/filter/inc/worksheetfragment.hxx
+++ b/sc/source/filter/inc/worksheetfragment.hxx
@@ -25,7 +25,25 @@
 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);
+private:
+    ::std::unique_ptr< ValidationModel > mxValModel;
+    OUString                             mSqref;
+    OUString                             mFormula1;
+    OUString                             mFormula2;
+};
+
+class DataValidationsContext : public WorksheetContextBase, private DataValidationsContext_Base
 {
 public:
     explicit            DataValidationsContext( WorksheetFragmentBase& rFragment );
@@ -36,15 +54,19 @@ 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 );
+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 023c27d..54f332a 100644
--- a/sc/source/filter/oox/extlstcontext.cxx
+++ b/sc/source/filter/oox/extlstcontext.cxx
@@ -229,9 +229,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 c8aa6c6..30872d8 100644
--- a/sc/source/filter/oox/worksheetfragment.cxx
+++ b/sc/source/filter/oox/worksheetfragment.cxx
@@ -75,6 +75,84 @@ 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);
+    OUString aSqref = rAttribs.getString(XML_sqref, OUString());
+    // Only set mSqref if it is set in attributes, to avoid owerwriting already set using SetSqref
+    if (!aSqref.isEmpty())
+    {
+        mSqref = aSqref;
+    }
+    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 at 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();
+    ScAddress 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 )
 {
@@ -105,89 +183,98 @@ ContextHandlerRef DataValidationsContext::onCreateContext( sal_Int32 nElement, c
 
 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;
     }
 }
 
 void DataValidationsContext::onEndElement()
 {
-    if( isCurrentElement( XLS_TOKEN( dataValidation ) ) && mxValModel.get() )
+    if( isCurrentElement( 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 at 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();
-    ScAddress 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 ) :


More information about the Libreoffice-commits mailing list