[Libreoffice-commits] .: 7 commits - offapi/com offapi/UnoApi_offapi.mk oox/inc oox/source sc/inc sc/source

Kohei Yoshida kohei at kemper.freedesktop.org
Tue Nov 29 19:35:58 PST 2011


 offapi/UnoApi_offapi.mk                               |    3 
 offapi/com/sun/star/sheet/FilterFieldValue.idl        |   54 ++
 offapi/com/sun/star/sheet/TableFilterField3.idl       |   62 +++
 offapi/com/sun/star/sheet/XSelectedSheetsSupplier.idl |    3 
 offapi/com/sun/star/sheet/XSheetFilterDescriptor3.idl |   65 +++
 oox/inc/oox/xls/autofilterbuffer.hxx                  |   15 
 oox/source/xls/autofilterbuffer.cxx                   |   44 +-
 sc/inc/datauno.hxx                                    |   17 
 sc/source/filter/excel/excrecds.cxx                   |   89 +++-
 sc/source/filter/inc/excrecds.hxx                     |   31 -
 sc/source/ui/unoobj/datauno.cxx                       |  330 ++++++++++++------
 11 files changed, 551 insertions(+), 162 deletions(-)

New commits:
commit 7f2fcde9e12164b72f775fa4e2b30bebe7c37311
Author: Kohei Yoshida <kohei.yoshida at suse.com>
Date:   Tue Nov 29 22:35:15 2011 -0500

    Export multi-value filters to xlsx.

diff --git a/sc/source/filter/excel/excrecds.cxx b/sc/source/filter/excel/excrecds.cxx
index 8036821..ebd2b4e 100644
--- a/sc/source/filter/excel/excrecds.cxx
+++ b/sc/source/filter/excel/excrecds.cxx
@@ -652,6 +652,7 @@ void ExcFilterCondition::SaveText( XclExpStream& rStrm )
 XclExpAutofilter::XclExpAutofilter( const XclExpRoot& rRoot, sal_uInt16 nC ) :
     XclExpRecord( EXC_ID_AUTOFILTER, 24 ),
     XclExpRoot( rRoot ),
+    meType(FilterCondition),
     nCol( nC ),
     nFlags( 0 )
 {
@@ -674,14 +675,26 @@ bool XclExpAutofilter::AddCondition( ScQueryConnect eConn, sal_uInt8 nType, sal_
 
     AddRecSize( aCond[ nInd ].GetTextBytes() );
 
-    return sal_True;
+    return true;
+}
+
+bool XclExpAutofilter::HasCondition() const
+{
+    return !aCond[0].IsEmpty();
 }
 
 bool XclExpAutofilter::AddEntry( const ScQueryEntry& rEntry )
 {
+    const ScQueryEntry::QueryItemsType& rItems = rEntry.GetQueryItems();
+    if (rItems.empty())
+        return true;
+
+    if (GetOutput() != EXC_OUTPUT_BINARY && rItems.size() > 1)
+        return AddMultiValueEntry(rEntry);
+
     bool bConflict = false;
     String  sText;
-    const ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
+    const ScQueryEntry::Item& rItem = rItems[0];
     const rtl::OUString& rQueryStr = rItem.maString;
     if (!rQueryStr.isEmpty())
     {
@@ -785,6 +798,17 @@ bool XclExpAutofilter::AddEntry( const ScQueryEntry& rEntry )
     return bConflict;
 }
 
+bool XclExpAutofilter::AddMultiValueEntry( const ScQueryEntry& rEntry )
+{
+    meType = MultiValue;
+    const ScQueryEntry::QueryItemsType& rItems = rEntry.GetQueryItems();
+    ScQueryEntry::QueryItemsType::const_iterator itr = rItems.begin(), itrEnd = rItems.end();
+    for (; itr != itrEnd; ++itr)
+        maMultiValues.push_back(itr->maString);
+
+    return false;
+}
+
 void XclExpAutofilter::WriteBody( XclExpStream& rStrm )
 {
     rStrm << nCol << nFlags;
@@ -796,7 +820,7 @@ void XclExpAutofilter::WriteBody( XclExpStream& rStrm )
 
 void XclExpAutofilter::SaveXml( XclExpXmlStream& rStrm )
 {
-    if( !HasCondition() )
+    if (meType == FilterCondition && !HasCondition())
         return;
 
     sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
@@ -807,24 +831,43 @@ void XclExpAutofilter::SaveXml( XclExpXmlStream& rStrm )
             // OOXTODO: XML_showButton,
             FSEND );
 
-    if( HasTop10() )
+    switch (meType)
     {
-        rWorksheet->singleElement( XML_top10,
-                XML_top,        XclXmlUtils::ToPsz( get_flag( nFlags, EXC_AFFLAG_TOP10TOP ) ),
-                XML_percent,    XclXmlUtils::ToPsz( get_flag( nFlags, EXC_AFFLAG_TOP10PERC ) ),
-                XML_val,        OString::valueOf( (sal_Int32) (nFlags >> 7 ) ).getStr(),
-                // OOXTODO: XML_filterVal,
-                FSEND );
-    }
+        case FilterCondition:
+        {
+            if( HasTop10() )
+            {
+                rWorksheet->singleElement( XML_top10,
+                        XML_top,        XclXmlUtils::ToPsz( get_flag( nFlags, EXC_AFFLAG_TOP10TOP ) ),
+                        XML_percent,    XclXmlUtils::ToPsz( get_flag( nFlags, EXC_AFFLAG_TOP10PERC ) ),
+                        XML_val,        OString::valueOf( (sal_Int32) (nFlags >> 7 ) ).getStr(),
+                        // OOXTODO: XML_filterVal,
+                        FSEND );
+            }
 
-    rWorksheet->startElement( XML_customFilters,
-            XML_and,    XclXmlUtils::ToPsz( (nFlags & EXC_AFFLAG_ANDORMASK) == EXC_AFFLAG_AND ),
-            FSEND );
-    aCond[ 0 ].SaveXml( rStrm );
-    aCond[ 1 ].SaveXml( rStrm );
-    rWorksheet->endElement( XML_customFilters );
-    // OOXTODO: XLM_colorFilter, XML_dynamicFilter,
-    // XML_extLst, XML_filters, XML_iconFilter, XML_top10
+            rWorksheet->startElement( XML_customFilters,
+                    XML_and,    XclXmlUtils::ToPsz( (nFlags & EXC_AFFLAG_ANDORMASK) == EXC_AFFLAG_AND ),
+                    FSEND );
+            aCond[ 0 ].SaveXml( rStrm );
+            aCond[ 1 ].SaveXml( rStrm );
+            rWorksheet->endElement( XML_customFilters );
+            // OOXTODO: XLM_colorFilter, XML_dynamicFilter,
+            // XML_extLst, XML_filters, XML_iconFilter, XML_top10
+        }
+        break;
+        case MultiValue:
+        {
+            rWorksheet->startElement(XML_filters, FSEND);
+            std::vector<rtl::OUString>::const_iterator itr = maMultiValues.begin(), itrEnd = maMultiValues.end();
+            for (; itr != itrEnd; ++itr)
+            {
+                const char* pz = rtl::OUStringToOString(*itr, RTL_TEXTENCODING_UTF8).getStr();
+                rWorksheet->singleElement(XML_filter, XML_val, pz, FSEND);
+            }
+            rWorksheet->endElement(XML_filters);
+        }
+        break;
+    }
     rWorksheet->endElement( XML_filterColumn );
 }
 
diff --git a/sc/source/filter/inc/excrecds.hxx b/sc/source/filter/inc/excrecds.hxx
index 2c6b1fb..6274bd8 100644
--- a/sc/source/filter/inc/excrecds.hxx
+++ b/sc/source/filter/inc/excrecds.hxx
@@ -402,9 +402,12 @@ public:
 class XclExpAutofilter : public XclExpRecord, protected XclExpRoot
 {
 private:
+    enum FilterType { FilterCondition, MultiValue };
+    FilterType              meType;
     sal_uInt16              nCol;
     sal_uInt16              nFlags;
     ExcFilterCondition      aCond[ 2 ];
+    std::vector<rtl::OUString> maMultiValues;
 
     bool                    AddCondition( ScQueryConnect eConn, sal_uInt8 nType,
                                 sal_uInt8 nOp, double fVal, String* pText,
@@ -416,10 +419,11 @@ public:
                             XclExpAutofilter( const XclExpRoot& rRoot, sal_uInt16 nC );
 
     inline sal_uInt16       GetCol() const          { return nCol; }
-    inline bool             HasCondition() const    { return !aCond[ 0 ].IsEmpty(); }
     inline bool             HasTop10() const        { return ::get_flag( nFlags, EXC_AFFLAG_TOP10 ); }
 
+    bool                    HasCondition() const;
     bool                    AddEntry( const ScQueryEntry& rEntry );
+    bool                    AddMultiValueEntry( const ScQueryEntry& rEntry );
 
     virtual void            SaveXml( XclExpXmlStream& rStrm );
 };
commit 5b033d425cebe2fc031172c2c3bc9b6a7a784369
Author: Kohei Yoshida <kohei.yoshida at suse.com>
Date:   Tue Nov 29 21:31:29 2011 -0500

    sal_Bool to bool.

diff --git a/sc/source/filter/excel/excrecds.cxx b/sc/source/filter/excel/excrecds.cxx
index b28a1bf..8036821 100644
--- a/sc/source/filter/excel/excrecds.cxx
+++ b/sc/source/filter/excel/excrecds.cxx
@@ -657,8 +657,8 @@ XclExpAutofilter::XclExpAutofilter( const XclExpRoot& rRoot, sal_uInt16 nC ) :
 {
 }
 
-sal_Bool XclExpAutofilter::AddCondition( ScQueryConnect eConn, sal_uInt8 nType, sal_uInt8 nOp,
-                                    double fVal, String* pText, sal_Bool bSimple )
+bool XclExpAutofilter::AddCondition( ScQueryConnect eConn, sal_uInt8 nType, sal_uInt8 nOp,
+                                     double fVal, String* pText, bool bSimple )
 {
     if( !aCond[ 1 ].IsEmpty() )
         return false;
@@ -949,11 +949,11 @@ XclExpAutofilter* ExcAutoFilterRecs::GetByCol( SCCOL nCol )
     return xFilter.get();
 }
 
-sal_Bool ExcAutoFilterRecs::IsFiltered( SCCOL nCol )
+bool ExcAutoFilterRecs::IsFiltered( SCCOL nCol )
 {
     for( size_t nPos = 0, nSize = maFilterList.GetSize(); nPos < nSize; ++nPos )
         if( maFilterList.GetRecord( nPos )->GetCol() == static_cast<sal_uInt16>(nCol) )
-            return sal_True;
+            return true;
     return false;
 }
 
diff --git a/sc/source/filter/inc/excrecds.hxx b/sc/source/filter/inc/excrecds.hxx
index 2d15ba4..2c6b1fb 100644
--- a/sc/source/filter/inc/excrecds.hxx
+++ b/sc/source/filter/inc/excrecds.hxx
@@ -376,8 +376,8 @@ private:
 class ExcFilterCondition
 {
 private:
-    sal_uInt8                   nType;
-    sal_uInt8                   nOper;
+    sal_uInt8               nType;
+    sal_uInt8               nOper;
     double                  fVal;
     XclExpString*           pText;
 
@@ -386,9 +386,9 @@ public:
                             ExcFilterCondition();
                             ~ExcFilterCondition();
 
-    inline sal_Bool             IsEmpty() const     { return (nType == EXC_AFTYPE_NOTUSED); }
-    inline sal_Bool             HasEqual() const    { return (nOper == EXC_AFOPER_EQUAL); }
-    sal_uLong                   GetTextBytes() const;
+    inline bool             IsEmpty() const     { return (nType == EXC_AFTYPE_NOTUSED); }
+    inline bool             HasEqual() const    { return (nOper == EXC_AFOPER_EQUAL); }
+    sal_uLong               GetTextBytes() const;
 
     void                    SetCondition( sal_uInt8 nTp, sal_uInt8 nOp, double fV, String* pT );
 
@@ -402,23 +402,22 @@ public:
 class XclExpAutofilter : public XclExpRecord, protected XclExpRoot
 {
 private:
-    sal_uInt16                  nCol;
-    sal_uInt16                  nFlags;
+    sal_uInt16              nCol;
+    sal_uInt16              nFlags;
     ExcFilterCondition      aCond[ 2 ];
 
-    sal_Bool                    AddCondition( ScQueryConnect eConn, sal_uInt8 nType,
+    bool                    AddCondition( ScQueryConnect eConn, sal_uInt8 nType,
                                 sal_uInt8 nOp, double fVal, String* pText,
-                                sal_Bool bSimple = false );
+                                bool bSimple = false );
 
     virtual void            WriteBody( XclExpStream& rStrm );
 
-protected:
 public:
                             XclExpAutofilter( const XclExpRoot& rRoot, sal_uInt16 nC );
 
-    inline sal_uInt16           GetCol() const          { return nCol; }
-    inline sal_Bool             HasCondition() const    { return !aCond[ 0 ].IsEmpty(); }
-    inline sal_Bool             HasTop10() const        { return ::get_flag( nFlags, EXC_AFFLAG_TOP10 ); }
+    inline sal_uInt16       GetCol() const          { return nCol; }
+    inline bool             HasCondition() const    { return !aCond[ 0 ].IsEmpty(); }
+    inline bool             HasTop10() const        { return ::get_flag( nFlags, EXC_AFFLAG_TOP10 ); }
 
     bool                    AddEntry( const ScQueryEntry& rEntry );
 
@@ -442,7 +441,7 @@ public:
 
 private:
     XclExpAutofilter*   GetByCol( SCCOL nCol ); // always 0-based
-    sal_Bool                IsFiltered( SCCOL nCol );
+    bool                IsFiltered( SCCOL nCol );
 
 private:
     typedef XclExpRecordList< XclExpAutofilter >    XclExpAutofilterList;
commit d4a51391d32d9c1f53dcdcc48aeb7a0c63f6c374
Author: Kohei Yoshida <kohei.yoshida at suse.com>
Date:   Tue Nov 29 21:08:36 2011 -0500

    Correctly import multi-value filter settings.
    
    We are still not 100% compatible, e.g. Excel's "show blanks" setting
    is not cleanly mapped (partly due to ODF's limitation).  But that's
    a future TODO.

diff --git a/oox/inc/oox/xls/autofilterbuffer.hxx b/oox/inc/oox/xls/autofilterbuffer.hxx
index 869c211..493c512 100644
--- a/oox/inc/oox/xls/autofilterbuffer.hxx
+++ b/oox/inc/oox/xls/autofilterbuffer.hxx
@@ -54,8 +54,9 @@ struct ApiFilterSettings
 
     explicit            ApiFilterSettings();
 
-    void                appendField( bool bAnd, sal_Int32 nOperator, double fValue );
-    void                appendField( bool bAnd, sal_Int32 nOperator, const ::rtl::OUString& rValue );
+    void appendField( bool bAnd, sal_Int32 nOperator, double fValue );
+    void appendField( bool bAnd, sal_Int32 nOperator, const ::rtl::OUString& rValue );
+    void appendField( bool bAnd, const std::vector<rtl::OUString>& rValues );
 };
 
 // ============================================================================
diff --git a/oox/source/xls/autofilterbuffer.cxx b/oox/source/xls/autofilterbuffer.cxx
index dd3fc5a..7a3e6fa 100644
--- a/oox/source/xls/autofilterbuffer.cxx
+++ b/oox/source/xls/autofilterbuffer.cxx
@@ -189,6 +189,21 @@ void ApiFilterSettings::appendField( bool bAnd, sal_Int32 nOperator, const OUStr
     rFilterField.Values[0].StringValue = rValue;
 }
 
+void ApiFilterSettings::appendField( bool bAnd, const std::vector<rtl::OUString>& rValues )
+{
+    maFilterFields.resize( maFilterFields.size() + 1 );
+    TableFilterField3& rFilterField = maFilterFields.back();
+    rFilterField.Connection = bAnd ? FilterConnection_AND : FilterConnection_OR;
+    rFilterField.Operator = FilterOperator2::EQUAL;
+    size_t n = rValues.size();
+    rFilterField.Values.realloc(n);
+    for (size_t i = 0; i < n; ++i)
+    {
+        rFilterField.Values[i].IsNumeric = false;
+        rFilterField.Values[i].StringValue = rValues[i];
+    }
+}
+
 // ============================================================================
 
 FilterSettingsBase::FilterSettingsBase( const WorkbookHelper& rHelper ) :
@@ -276,8 +291,7 @@ ApiFilterSettings DiscreteFilter::finalizeImport( sal_Int32 nMaxCount )
         aSettings.maFilterFields.reserve( maValues.size() );
 
         // insert all filter values
-        for( FilterValueVector::iterator aIt = maValues.begin(), aEnd = maValues.end(); aIt != aEnd; ++aIt )
-            aSettings.appendField( false, FilterOperator2::EQUAL, *aIt );
+        aSettings.appendField( true, maValues );
 
         // extra field for 'show empty'
         if( mbShowBlank )
commit af4435c5a4964a86457fe61c3bade42ca3cf236d
Author: Kohei Yoshida <kohei.yoshida at suse.com>
Date:   Tue Nov 29 17:17:59 2011 -0500

    Switch to TableFilterField3, but no other changes.

diff --git a/oox/inc/oox/xls/autofilterbuffer.hxx b/oox/inc/oox/xls/autofilterbuffer.hxx
index bc2a986..869c211 100644
--- a/oox/inc/oox/xls/autofilterbuffer.hxx
+++ b/oox/inc/oox/xls/autofilterbuffer.hxx
@@ -34,9 +34,9 @@
 #include "oox/xls/workbookhelper.hxx"
 
 namespace com { namespace sun { namespace star {
-    namespace sheet { struct TableFilterField2; }
+    namespace sheet { struct TableFilterField3; }
     namespace sheet { class XDatabaseRange; }
-    namespace sheet { class XSheetFilterDescriptor2; }
+    namespace sheet { class XSheetFilterDescriptor3; }
 } } }
 
 namespace oox {
@@ -47,7 +47,7 @@ namespace xls {
 /** Contains UNO API filter settings for a column in a filtered range. */
 struct ApiFilterSettings
 {
-    typedef ::std::vector< ::com::sun::star::sheet::TableFilterField2 > FilterFieldVector;
+    typedef ::std::vector<com::sun::star::sheet::TableFilterField3> FilterFieldVector;
 
     FilterFieldVector   maFilterFields;     /// List of UNO API filter settings.
     OptValue< bool >    mobNeedsRegExp;     /// If set, requires regular expressions to be enabled/disabled.
@@ -236,7 +236,9 @@ public:
     FilterColumn&       createFilterColumn();
 
     /** Applies the filter to the passed filter descriptor. */
-    void                finalizeImport( const ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSheetFilterDescriptor2 >& rxFilterDesc );
+    void                finalizeImport(
+        const ::com::sun::star::uno::Reference<
+            ::com::sun::star::sheet::XSheetFilterDescriptor3>& rxFilterDesc );
 
 private:
     typedef RefVector< FilterColumn > FilterColumnVector;
diff --git a/oox/source/xls/autofilterbuffer.cxx b/oox/source/xls/autofilterbuffer.cxx
index 0ffcdf6..dd3fc5a 100644
--- a/oox/source/xls/autofilterbuffer.cxx
+++ b/oox/source/xls/autofilterbuffer.cxx
@@ -30,9 +30,9 @@
 
 #include <com/sun/star/sheet/FilterConnection.hpp>
 #include <com/sun/star/sheet/FilterOperator2.hpp>
-#include <com/sun/star/sheet/TableFilterField2.hpp>
+#include <com/sun/star/sheet/TableFilterField3.hpp>
 #include <com/sun/star/sheet/XDatabaseRange.hpp>
-#include <com/sun/star/sheet/XSheetFilterDescriptor2.hpp>
+#include <com/sun/star/sheet/XSheetFilterDescriptor3.hpp>
 #include <com/sun/star/table/TableOrientation.hpp>
 #include <rtl/ustrbuf.hxx>
 #include "oox/helper/attributelist.hxx"
@@ -170,21 +170,23 @@ ApiFilterSettings::ApiFilterSettings()
 void ApiFilterSettings::appendField( bool bAnd, sal_Int32 nOperator, double fValue )
 {
     maFilterFields.resize( maFilterFields.size() + 1 );
-    TableFilterField2& rFilterField = maFilterFields.back();
+    TableFilterField3& rFilterField = maFilterFields.back();
     rFilterField.Connection = bAnd ? FilterConnection_AND : FilterConnection_OR;
     rFilterField.Operator = nOperator;
-    rFilterField.IsNumeric = sal_True;
-    rFilterField.NumericValue = fValue;
+    rFilterField.Values.realloc(1);
+    rFilterField.Values[0].IsNumeric = true;
+    rFilterField.Values[0].NumericValue = fValue;
 }
 
 void ApiFilterSettings::appendField( bool bAnd, sal_Int32 nOperator, const OUString& rValue )
 {
     maFilterFields.resize( maFilterFields.size() + 1 );
-    TableFilterField2& rFilterField = maFilterFields.back();
+    TableFilterField3& rFilterField = maFilterFields.back();
     rFilterField.Connection = bAnd ? FilterConnection_AND : FilterConnection_OR;
     rFilterField.Operator = nOperator;
-    rFilterField.IsNumeric = sal_False;
-    rFilterField.StringValue = rValue;
+    rFilterField.Values.realloc(1);
+    rFilterField.Values[0].IsNumeric = false;
+    rFilterField.Values[0].StringValue = rValue;
 }
 
 // ============================================================================
@@ -669,7 +671,7 @@ FilterColumn& AutoFilter::createFilterColumn()
     return *xFilterColumn;
 }
 
-void AutoFilter::finalizeImport( const Reference< XSheetFilterDescriptor2 >& rxFilterDesc )
+void AutoFilter::finalizeImport( const Reference<XSheetFilterDescriptor3>& rxFilterDesc )
 {
     if( rxFilterDesc.is() )
     {
@@ -687,7 +689,7 @@ void AutoFilter::finalizeImport( const Reference< XSheetFilterDescriptor2 >& rxF
         OSL_ENSURE( nMaxCount > 0, "AutoFilter::finalizeImport - invalid maximum filter field count" );
 
         // resulting list of all UNO API filter fields
-        ::std::vector< TableFilterField2 > aFilterFields;
+        ::std::vector<TableFilterField3> aFilterFields;
 
         // track if columns require to enable or disable regular expressions
         OptValue< bool > obNeedsRegExp;
@@ -742,7 +744,7 @@ void AutoFilter::finalizeImport( const Reference< XSheetFilterDescriptor2 >& rxF
 
         // insert all filter fields to the filter descriptor
         if( !aFilterFields.empty() )
-            rxFilterDesc->setFilterFields2( ContainerHelper::vectorToSequence( aFilterFields ) );
+            rxFilterDesc->setFilterFields3( ContainerHelper::vectorToSequence( aFilterFields ) );
 
         // regular expressions
         bool bUseRegExp = obNeedsRegExp.get( false );
@@ -828,7 +830,7 @@ bool AutoFilterBuffer::finalizeImport( const Reference< XDatabaseRange >& rxData
         PropertySet aRangeProps( rxDatabaseRange );
         aRangeProps.setProperty( PROP_AutoFilter, true );
         // convert filter settings using the filter descriptor of the database range
-        Reference< XSheetFilterDescriptor2 > xFilterDesc( rxDatabaseRange->getFilterDescriptor(), UNO_QUERY_THROW );
+        Reference< XSheetFilterDescriptor3 > xFilterDesc( rxDatabaseRange->getFilterDescriptor(), UNO_QUERY_THROW );
         pAutoFilter->finalizeImport( xFilterDesc );
         // return true to indicate enabled autofilter
         return true;
commit 24497be46946032324aade1eeaed6cf0b87a610a
Author: Kohei Yoshida <kohei.yoshida at suse.com>
Date:   Tue Nov 29 16:02:35 2011 -0500

    Removed duplicate code block.

diff --git a/sc/source/ui/unoobj/datauno.cxx b/sc/source/ui/unoobj/datauno.cxx
index 8d601b4..960ac08 100644
--- a/sc/source/ui/unoobj/datauno.cxx
+++ b/sc/source/ui/unoobj/datauno.cxx
@@ -1181,6 +1181,43 @@ void convertQueryEntryToUno(const ScQueryEntry& rEntry, T& rField)
     }
 }
 
+template<typename T>
+void convertUnoToQueryEntry(const T& rField, ScQueryEntry& rEntry)
+{
+    rEntry.bDoQuery = true;
+    rEntry.eConnect = (rField.Connection == sheet::FilterConnection_AND) ? SC_AND : SC_OR;
+    rEntry.nField   = rField.Field;
+
+    switch (rField.Operator)           // FilterOperator
+    {
+    case sheet::FilterOperator2::EQUAL:                 rEntry.eOp = SC_EQUAL;              break;
+    case sheet::FilterOperator2::LESS:                  rEntry.eOp = SC_LESS;               break;
+    case sheet::FilterOperator2::GREATER:               rEntry.eOp = SC_GREATER;            break;
+    case sheet::FilterOperator2::LESS_EQUAL:            rEntry.eOp = SC_LESS_EQUAL;         break;
+    case sheet::FilterOperator2::GREATER_EQUAL:         rEntry.eOp = SC_GREATER_EQUAL;      break;
+    case sheet::FilterOperator2::NOT_EQUAL:             rEntry.eOp = SC_NOT_EQUAL;          break;
+    case sheet::FilterOperator2::TOP_VALUES:            rEntry.eOp = SC_TOPVAL;             break;
+    case sheet::FilterOperator2::BOTTOM_VALUES:         rEntry.eOp = SC_BOTVAL;             break;
+    case sheet::FilterOperator2::TOP_PERCENT:           rEntry.eOp = SC_TOPPERC;            break;
+    case sheet::FilterOperator2::BOTTOM_PERCENT:        rEntry.eOp = SC_BOTPERC;            break;
+    case sheet::FilterOperator2::CONTAINS:              rEntry.eOp = SC_CONTAINS;           break;
+    case sheet::FilterOperator2::DOES_NOT_CONTAIN:      rEntry.eOp = SC_DOES_NOT_CONTAIN;   break;
+    case sheet::FilterOperator2::BEGINS_WITH:           rEntry.eOp = SC_BEGINS_WITH;        break;
+    case sheet::FilterOperator2::DOES_NOT_BEGIN_WITH:   rEntry.eOp = SC_DOES_NOT_BEGIN_WITH;break;
+    case sheet::FilterOperator2::ENDS_WITH:             rEntry.eOp = SC_ENDS_WITH;          break;
+    case sheet::FilterOperator2::DOES_NOT_END_WITH:     rEntry.eOp = SC_DOES_NOT_END_WITH;  break;
+    case sheet::FilterOperator2::EMPTY:
+        rEntry.SetQueryByEmpty();
+        break;
+    case sheet::FilterOperator2::NOT_EMPTY:
+        rEntry.SetQueryByNonEmpty();
+        break;
+    default:
+        OSL_FAIL("Unknown filter operator type.");
+        rEntry.eOp = SC_EQUAL;
+    }
+}
+
 void fillQueryParam(
     ScQueryParam& rParam, ScDocument* pDoc,
     const uno::Sequence<sheet::TableFilterField2>& aFilterFields)
@@ -1192,39 +1229,7 @@ void fillQueryParam(
     for (size_t i = 0; i < nCount; ++i)
     {
         ScQueryEntry& rEntry = rParam.GetEntry(i);
-
-        rEntry.bDoQuery = true;
-        rEntry.eConnect = (pAry[i].Connection == sheet::FilterConnection_AND) ? SC_AND : SC_OR;
-        rEntry.nField   = pAry[i].Field;
-
-        switch (pAry[i].Operator)           // FilterOperator
-        {
-        case sheet::FilterOperator2::EQUAL:                 rEntry.eOp = SC_EQUAL;              break;
-        case sheet::FilterOperator2::LESS:                  rEntry.eOp = SC_LESS;               break;
-        case sheet::FilterOperator2::GREATER:               rEntry.eOp = SC_GREATER;            break;
-        case sheet::FilterOperator2::LESS_EQUAL:            rEntry.eOp = SC_LESS_EQUAL;         break;
-        case sheet::FilterOperator2::GREATER_EQUAL:         rEntry.eOp = SC_GREATER_EQUAL;      break;
-        case sheet::FilterOperator2::NOT_EQUAL:             rEntry.eOp = SC_NOT_EQUAL;          break;
-        case sheet::FilterOperator2::TOP_VALUES:            rEntry.eOp = SC_TOPVAL;             break;
-        case sheet::FilterOperator2::BOTTOM_VALUES:         rEntry.eOp = SC_BOTVAL;             break;
-        case sheet::FilterOperator2::TOP_PERCENT:           rEntry.eOp = SC_TOPPERC;            break;
-        case sheet::FilterOperator2::BOTTOM_PERCENT:        rEntry.eOp = SC_BOTPERC;            break;
-        case sheet::FilterOperator2::CONTAINS:              rEntry.eOp = SC_CONTAINS;           break;
-        case sheet::FilterOperator2::DOES_NOT_CONTAIN:      rEntry.eOp = SC_DOES_NOT_CONTAIN;   break;
-        case sheet::FilterOperator2::BEGINS_WITH:           rEntry.eOp = SC_BEGINS_WITH;        break;
-        case sheet::FilterOperator2::DOES_NOT_BEGIN_WITH:   rEntry.eOp = SC_DOES_NOT_BEGIN_WITH;break;
-        case sheet::FilterOperator2::ENDS_WITH:             rEntry.eOp = SC_ENDS_WITH;          break;
-        case sheet::FilterOperator2::DOES_NOT_END_WITH:     rEntry.eOp = SC_DOES_NOT_END_WITH;  break;
-        case sheet::FilterOperator2::EMPTY:
-            rEntry.SetQueryByEmpty();
-            break;
-        case sheet::FilterOperator2::NOT_EMPTY:
-            rEntry.SetQueryByNonEmpty();
-            break;
-        default:
-            OSL_FAIL("Falscher Query-enum");
-            rEntry.eOp = SC_EQUAL;
-        }
+        convertUnoToQueryEntry(pAry[i], rEntry);
 
         if (pAry[i].Operator != sheet::FilterOperator2::EMPTY && pAry[i].Operator != sheet::FilterOperator2::NOT_EMPTY)
         {
@@ -1254,39 +1259,7 @@ void fillQueryParam(
     for (size_t i = 0; i < nCount; ++i)
     {
         ScQueryEntry& rEntry = rParam.GetEntry(i);
-
-        rEntry.bDoQuery = true;
-        rEntry.eConnect = (pAry[i].Connection == sheet::FilterConnection_AND) ? SC_AND : SC_OR;
-        rEntry.nField   = pAry[i].Field;
-
-        switch (pAry[i].Operator)           // FilterOperator
-        {
-        case sheet::FilterOperator2::EQUAL:                 rEntry.eOp = SC_EQUAL;              break;
-        case sheet::FilterOperator2::LESS:                  rEntry.eOp = SC_LESS;               break;
-        case sheet::FilterOperator2::GREATER:               rEntry.eOp = SC_GREATER;            break;
-        case sheet::FilterOperator2::LESS_EQUAL:            rEntry.eOp = SC_LESS_EQUAL;         break;
-        case sheet::FilterOperator2::GREATER_EQUAL:         rEntry.eOp = SC_GREATER_EQUAL;      break;
-        case sheet::FilterOperator2::NOT_EQUAL:             rEntry.eOp = SC_NOT_EQUAL;          break;
-        case sheet::FilterOperator2::TOP_VALUES:            rEntry.eOp = SC_TOPVAL;             break;
-        case sheet::FilterOperator2::BOTTOM_VALUES:         rEntry.eOp = SC_BOTVAL;             break;
-        case sheet::FilterOperator2::TOP_PERCENT:           rEntry.eOp = SC_TOPPERC;            break;
-        case sheet::FilterOperator2::BOTTOM_PERCENT:        rEntry.eOp = SC_BOTPERC;            break;
-        case sheet::FilterOperator2::CONTAINS:              rEntry.eOp = SC_CONTAINS;           break;
-        case sheet::FilterOperator2::DOES_NOT_CONTAIN:      rEntry.eOp = SC_DOES_NOT_CONTAIN;   break;
-        case sheet::FilterOperator2::BEGINS_WITH:           rEntry.eOp = SC_BEGINS_WITH;        break;
-        case sheet::FilterOperator2::DOES_NOT_BEGIN_WITH:   rEntry.eOp = SC_DOES_NOT_BEGIN_WITH;break;
-        case sheet::FilterOperator2::ENDS_WITH:             rEntry.eOp = SC_ENDS_WITH;          break;
-        case sheet::FilterOperator2::DOES_NOT_END_WITH:     rEntry.eOp = SC_DOES_NOT_END_WITH;  break;
-        case sheet::FilterOperator2::EMPTY:
-            rEntry.SetQueryByEmpty();
-            break;
-        case sheet::FilterOperator2::NOT_EMPTY:
-            rEntry.SetQueryByNonEmpty();
-            break;
-        default:
-            OSL_FAIL("Unknown filter operator type.");
-            rEntry.eOp = SC_EQUAL;
-        }
+        convertUnoToQueryEntry(pAry[i], rEntry);
 
         if (pAry[i].Operator != sheet::FilterOperator2::EMPTY && pAry[i].Operator != sheet::FilterOperator2::NOT_EMPTY)
         {
commit 0278ebc50e4f1b34657f1e7d51b44b4e73858399
Author: Kohei Yoshida <kohei.yoshida at suse.com>
Date:   Tue Nov 29 15:58:51 2011 -0500

    Implemented the new multi-value filter API.

diff --git a/sc/inc/datauno.hxx b/sc/inc/datauno.hxx
index 94bdfa6..732dd80 100644
--- a/sc/inc/datauno.hxx
+++ b/sc/inc/datauno.hxx
@@ -37,6 +37,8 @@
 #include <com/sun/star/sheet/GeneralFunction.hpp>
 #include <com/sun/star/sheet/XCellRangeReferrer.hpp>
 #include <com/sun/star/sheet/XSheetFilterDescriptor.hpp>
+#include <com/sun/star/sheet/XSheetFilterDescriptor2.hpp>
+#include <com/sun/star/sheet/XSheetFilterDescriptor3.hpp>
 #include <com/sun/star/sheet/XConsolidationDescriptor.hpp>
 #include <com/sun/star/sheet/XDatabaseRanges.hpp>
 #include <com/sun/star/sheet/XDatabaseRange.hpp>
@@ -50,7 +52,6 @@
 #include <com/sun/star/lang/XUnoTunnel.hpp>
 #include <com/sun/star/container/XNamed.hpp>
 #include <com/sun/star/util/XRefreshable.hpp>
-#include <com/sun/star/sheet/XSheetFilterDescriptor2.hpp>
 #include <cppuhelper/implbase2.hxx>
 #include <cppuhelper/implbase3.hxx>
 #include <cppuhelper/implbase4.hxx>
@@ -342,9 +343,10 @@ public:
 
 //  to uno, all three look the same
 
-class ScFilterDescriptorBase : public cppu::WeakImplHelper4<
+class ScFilterDescriptorBase : public cppu::WeakImplHelper5<
                                     com::sun::star::sheet::XSheetFilterDescriptor,
                                     com::sun::star::sheet::XSheetFilterDescriptor2,
+                                    com::sun::star::sheet::XSheetFilterDescriptor3,
                                     com::sun::star::beans::XPropertySet,
                                     com::sun::star::lang::XServiceInfo >,
                                public SfxListener
@@ -354,10 +356,6 @@ private:
     ScDocShell*             pDocSh;
 
 public:
-    static void fillQueryParam(
-        ScQueryParam& rParam, ScDocument* pDoc,
-        const ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::TableFilterField2>& aFilterFields);
-
                             ScFilterDescriptorBase(ScDocShell* pDocShell);
     virtual                 ~ScFilterDescriptorBase();
 
@@ -382,6 +380,13 @@ public:
                                 ::com::sun::star::sheet::TableFilterField2 >& aFilterFields )
                                     throw(::com::sun::star::uno::RuntimeException);
 
+                            // XSheetFilterDescriptor3
+    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::TableFilterField3 > SAL_CALL
+                            getFilterFields3() throw(::com::sun::star::uno::RuntimeException);
+    virtual void SAL_CALL   setFilterFields3( const ::com::sun::star::uno::Sequence<
+                                ::com::sun::star::sheet::TableFilterField3 >& aFilterFields )
+                                    throw(::com::sun::star::uno::RuntimeException);
+
                             // XPropertySet
     virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo >
                             SAL_CALL getPropertySetInfo()
diff --git a/sc/source/ui/unoobj/datauno.cxx b/sc/source/ui/unoobj/datauno.cxx
index 5b10f13..8d601b4 100644
--- a/sc/source/ui/unoobj/datauno.cxx
+++ b/sc/source/ui/unoobj/datauno.cxx
@@ -1058,67 +1058,6 @@ void SAL_CALL ScConsolidationDescriptor::setInsertLinks( sal_Bool bInsertLinks )
     aParam.bReferenceData = bInsertLinks;
 }
 
-//------------------------------------------------------------------------
-
-void ScFilterDescriptorBase::fillQueryParam(
-    ScQueryParam& rParam, ScDocument* pDoc,
-    const uno::Sequence<sheet::TableFilterField2>& aFilterFields)
-{
-    SCSIZE nCount = static_cast<SCSIZE>(aFilterFields.getLength());
-    rParam.Resize( nCount );
-
-    const sheet::TableFilterField2* pAry = aFilterFields.getConstArray();
-    SCSIZE i;
-    for (i=0; i<nCount; i++)
-    {
-        ScQueryEntry& rEntry = rParam.GetEntry(i);
-        ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
-
-        rEntry.bDoQuery = true;
-        rEntry.eConnect = (pAry[i].Connection == sheet::FilterConnection_AND) ? SC_AND : SC_OR;
-        rEntry.nField   = pAry[i].Field;
-        rItem.meType    = pAry[i].IsNumeric ? ScQueryEntry::ByValue : ScQueryEntry::ByString;
-        rItem.mfVal     = pAry[i].NumericValue;
-        rItem.maString  = pAry[i].StringValue;
-
-        if (rItem.meType == ScQueryEntry::ByValue && pDoc)
-            pDoc->GetFormatTable()->GetInputLineString(rItem.mfVal, 0, rItem.maString);
-
-        switch (pAry[i].Operator)           // FilterOperator
-        {
-        case sheet::FilterOperator2::EQUAL:                 rEntry.eOp = SC_EQUAL;              break;
-        case sheet::FilterOperator2::LESS:                  rEntry.eOp = SC_LESS;               break;
-        case sheet::FilterOperator2::GREATER:               rEntry.eOp = SC_GREATER;            break;
-        case sheet::FilterOperator2::LESS_EQUAL:            rEntry.eOp = SC_LESS_EQUAL;         break;
-        case sheet::FilterOperator2::GREATER_EQUAL:         rEntry.eOp = SC_GREATER_EQUAL;      break;
-        case sheet::FilterOperator2::NOT_EQUAL:             rEntry.eOp = SC_NOT_EQUAL;          break;
-        case sheet::FilterOperator2::TOP_VALUES:            rEntry.eOp = SC_TOPVAL;             break;
-        case sheet::FilterOperator2::BOTTOM_VALUES:         rEntry.eOp = SC_BOTVAL;             break;
-        case sheet::FilterOperator2::TOP_PERCENT:           rEntry.eOp = SC_TOPPERC;            break;
-        case sheet::FilterOperator2::BOTTOM_PERCENT:        rEntry.eOp = SC_BOTPERC;            break;
-        case sheet::FilterOperator2::CONTAINS:              rEntry.eOp = SC_CONTAINS;           break;
-        case sheet::FilterOperator2::DOES_NOT_CONTAIN:      rEntry.eOp = SC_DOES_NOT_CONTAIN;   break;
-        case sheet::FilterOperator2::BEGINS_WITH:           rEntry.eOp = SC_BEGINS_WITH;        break;
-        case sheet::FilterOperator2::DOES_NOT_BEGIN_WITH:   rEntry.eOp = SC_DOES_NOT_BEGIN_WITH;break;
-        case sheet::FilterOperator2::ENDS_WITH:             rEntry.eOp = SC_ENDS_WITH;          break;
-        case sheet::FilterOperator2::DOES_NOT_END_WITH:     rEntry.eOp = SC_DOES_NOT_END_WITH;  break;
-        case sheet::FilterOperator2::EMPTY:
-            rEntry.SetQueryByEmpty();
-            break;
-        case sheet::FilterOperator2::NOT_EMPTY:
-            rEntry.SetQueryByNonEmpty();
-            break;
-        default:
-            OSL_FAIL("Falscher Query-enum");
-            rEntry.eOp = SC_EQUAL;
-        }
-    }
-
-    SCSIZE nParamCount = rParam.GetEntryCount();    // Param wird nicht unter 8 resized
-    for (i=nCount; i<nParamCount; i++)
-        rParam.GetEntry(i).bDoQuery = false;        // ueberzaehlige Felder zuruecksetzen
-}
-
 ScFilterDescriptorBase::ScFilterDescriptorBase(ScDocShell* pDocShell) :
     aPropSet( lcl_GetFilterPropertyMap() ),
     pDocSh(pDocShell)
@@ -1210,6 +1149,172 @@ uno::Sequence<sheet::TableFilterField> SAL_CALL ScFilterDescriptorBase::getFilte
     return aSeq;
 }
 
+namespace {
+
+template<typename T>
+void convertQueryEntryToUno(const ScQueryEntry& rEntry, T& rField)
+{
+    rField.Connection = (rEntry.eConnect == SC_AND) ? sheet::FilterConnection_AND : sheet::FilterConnection_OR;
+    rField.Field = rEntry.nField;
+
+    switch (rEntry.eOp)             // ScQueryOp
+    {
+    case SC_EQUAL:                  rField.Operator = sheet::FilterOperator2::EQUAL;                break;
+    case SC_LESS:                   rField.Operator = sheet::FilterOperator2::LESS;                 break;
+    case SC_GREATER:                rField.Operator = sheet::FilterOperator2::GREATER;              break;
+    case SC_LESS_EQUAL:             rField.Operator = sheet::FilterOperator2::LESS_EQUAL;           break;
+    case SC_GREATER_EQUAL:          rField.Operator = sheet::FilterOperator2::GREATER_EQUAL;        break;
+    case SC_NOT_EQUAL:              rField.Operator = sheet::FilterOperator2::NOT_EQUAL;            break;
+    case SC_TOPVAL:                 rField.Operator = sheet::FilterOperator2::TOP_VALUES;           break;
+    case SC_BOTVAL:                 rField.Operator = sheet::FilterOperator2::BOTTOM_VALUES;        break;
+    case SC_TOPPERC:                rField.Operator = sheet::FilterOperator2::TOP_PERCENT;          break;
+    case SC_BOTPERC:                rField.Operator = sheet::FilterOperator2::BOTTOM_PERCENT;       break;
+    case SC_CONTAINS:               rField.Operator = sheet::FilterOperator2::CONTAINS;             break;
+    case SC_DOES_NOT_CONTAIN:       rField.Operator = sheet::FilterOperator2::DOES_NOT_CONTAIN;     break;
+    case SC_BEGINS_WITH:            rField.Operator = sheet::FilterOperator2::BEGINS_WITH;          break;
+    case SC_DOES_NOT_BEGIN_WITH:    rField.Operator = sheet::FilterOperator2::DOES_NOT_BEGIN_WITH;  break;
+    case SC_ENDS_WITH:              rField.Operator = sheet::FilterOperator2::ENDS_WITH;            break;
+    case SC_DOES_NOT_END_WITH:      rField.Operator = sheet::FilterOperator2::DOES_NOT_END_WITH;    break;
+    default:
+        OSL_FAIL("Unknown filter operator value.");
+        rField.Operator = sheet::FilterOperator2::EMPTY;
+    }
+}
+
+void fillQueryParam(
+    ScQueryParam& rParam, ScDocument* pDoc,
+    const uno::Sequence<sheet::TableFilterField2>& aFilterFields)
+{
+    size_t nCount = static_cast<size_t>(aFilterFields.getLength());
+    rParam.Resize(nCount);
+
+    const sheet::TableFilterField2* pAry = aFilterFields.getConstArray();
+    for (size_t i = 0; i < nCount; ++i)
+    {
+        ScQueryEntry& rEntry = rParam.GetEntry(i);
+
+        rEntry.bDoQuery = true;
+        rEntry.eConnect = (pAry[i].Connection == sheet::FilterConnection_AND) ? SC_AND : SC_OR;
+        rEntry.nField   = pAry[i].Field;
+
+        switch (pAry[i].Operator)           // FilterOperator
+        {
+        case sheet::FilterOperator2::EQUAL:                 rEntry.eOp = SC_EQUAL;              break;
+        case sheet::FilterOperator2::LESS:                  rEntry.eOp = SC_LESS;               break;
+        case sheet::FilterOperator2::GREATER:               rEntry.eOp = SC_GREATER;            break;
+        case sheet::FilterOperator2::LESS_EQUAL:            rEntry.eOp = SC_LESS_EQUAL;         break;
+        case sheet::FilterOperator2::GREATER_EQUAL:         rEntry.eOp = SC_GREATER_EQUAL;      break;
+        case sheet::FilterOperator2::NOT_EQUAL:             rEntry.eOp = SC_NOT_EQUAL;          break;
+        case sheet::FilterOperator2::TOP_VALUES:            rEntry.eOp = SC_TOPVAL;             break;
+        case sheet::FilterOperator2::BOTTOM_VALUES:         rEntry.eOp = SC_BOTVAL;             break;
+        case sheet::FilterOperator2::TOP_PERCENT:           rEntry.eOp = SC_TOPPERC;            break;
+        case sheet::FilterOperator2::BOTTOM_PERCENT:        rEntry.eOp = SC_BOTPERC;            break;
+        case sheet::FilterOperator2::CONTAINS:              rEntry.eOp = SC_CONTAINS;           break;
+        case sheet::FilterOperator2::DOES_NOT_CONTAIN:      rEntry.eOp = SC_DOES_NOT_CONTAIN;   break;
+        case sheet::FilterOperator2::BEGINS_WITH:           rEntry.eOp = SC_BEGINS_WITH;        break;
+        case sheet::FilterOperator2::DOES_NOT_BEGIN_WITH:   rEntry.eOp = SC_DOES_NOT_BEGIN_WITH;break;
+        case sheet::FilterOperator2::ENDS_WITH:             rEntry.eOp = SC_ENDS_WITH;          break;
+        case sheet::FilterOperator2::DOES_NOT_END_WITH:     rEntry.eOp = SC_DOES_NOT_END_WITH;  break;
+        case sheet::FilterOperator2::EMPTY:
+            rEntry.SetQueryByEmpty();
+            break;
+        case sheet::FilterOperator2::NOT_EMPTY:
+            rEntry.SetQueryByNonEmpty();
+            break;
+        default:
+            OSL_FAIL("Falscher Query-enum");
+            rEntry.eOp = SC_EQUAL;
+        }
+
+        if (pAry[i].Operator != sheet::FilterOperator2::EMPTY && pAry[i].Operator != sheet::FilterOperator2::NOT_EMPTY)
+        {
+            ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
+            rItem.meType    = pAry[i].IsNumeric ? ScQueryEntry::ByValue : ScQueryEntry::ByString;
+            rItem.mfVal     = pAry[i].NumericValue;
+            rItem.maString  = pAry[i].StringValue;
+
+            if (rItem.meType == ScQueryEntry::ByValue && pDoc)
+                pDoc->GetFormatTable()->GetInputLineString(rItem.mfVal, 0, rItem.maString);
+        }
+    }
+
+    size_t nParamCount = rParam.GetEntryCount();    // Param wird nicht unter 8 resized
+    for (size_t i = nCount; i < nParamCount; ++i)
+        rParam.GetEntry(i).bDoQuery = false;        // ueberzaehlige Felder zuruecksetzen
+}
+
+void fillQueryParam(
+    ScQueryParam& rParam, ScDocument* pDoc,
+    const uno::Sequence<sheet::TableFilterField3>& aFilterFields)
+{
+    size_t nCount = static_cast<size_t>(aFilterFields.getLength());
+    rParam.Resize(nCount);
+
+    const sheet::TableFilterField3* pAry = aFilterFields.getConstArray();
+    for (size_t i = 0; i < nCount; ++i)
+    {
+        ScQueryEntry& rEntry = rParam.GetEntry(i);
+
+        rEntry.bDoQuery = true;
+        rEntry.eConnect = (pAry[i].Connection == sheet::FilterConnection_AND) ? SC_AND : SC_OR;
+        rEntry.nField   = pAry[i].Field;
+
+        switch (pAry[i].Operator)           // FilterOperator
+        {
+        case sheet::FilterOperator2::EQUAL:                 rEntry.eOp = SC_EQUAL;              break;
+        case sheet::FilterOperator2::LESS:                  rEntry.eOp = SC_LESS;               break;
+        case sheet::FilterOperator2::GREATER:               rEntry.eOp = SC_GREATER;            break;
+        case sheet::FilterOperator2::LESS_EQUAL:            rEntry.eOp = SC_LESS_EQUAL;         break;
+        case sheet::FilterOperator2::GREATER_EQUAL:         rEntry.eOp = SC_GREATER_EQUAL;      break;
+        case sheet::FilterOperator2::NOT_EQUAL:             rEntry.eOp = SC_NOT_EQUAL;          break;
+        case sheet::FilterOperator2::TOP_VALUES:            rEntry.eOp = SC_TOPVAL;             break;
+        case sheet::FilterOperator2::BOTTOM_VALUES:         rEntry.eOp = SC_BOTVAL;             break;
+        case sheet::FilterOperator2::TOP_PERCENT:           rEntry.eOp = SC_TOPPERC;            break;
+        case sheet::FilterOperator2::BOTTOM_PERCENT:        rEntry.eOp = SC_BOTPERC;            break;
+        case sheet::FilterOperator2::CONTAINS:              rEntry.eOp = SC_CONTAINS;           break;
+        case sheet::FilterOperator2::DOES_NOT_CONTAIN:      rEntry.eOp = SC_DOES_NOT_CONTAIN;   break;
+        case sheet::FilterOperator2::BEGINS_WITH:           rEntry.eOp = SC_BEGINS_WITH;        break;
+        case sheet::FilterOperator2::DOES_NOT_BEGIN_WITH:   rEntry.eOp = SC_DOES_NOT_BEGIN_WITH;break;
+        case sheet::FilterOperator2::ENDS_WITH:             rEntry.eOp = SC_ENDS_WITH;          break;
+        case sheet::FilterOperator2::DOES_NOT_END_WITH:     rEntry.eOp = SC_DOES_NOT_END_WITH;  break;
+        case sheet::FilterOperator2::EMPTY:
+            rEntry.SetQueryByEmpty();
+            break;
+        case sheet::FilterOperator2::NOT_EMPTY:
+            rEntry.SetQueryByNonEmpty();
+            break;
+        default:
+            OSL_FAIL("Unknown filter operator type.");
+            rEntry.eOp = SC_EQUAL;
+        }
+
+        if (pAry[i].Operator != sheet::FilterOperator2::EMPTY && pAry[i].Operator != sheet::FilterOperator2::NOT_EMPTY)
+        {
+            ScQueryEntry::QueryItemsType& rItems = rEntry.GetQueryItems();
+            rItems.clear();
+            const uno::Sequence<sheet::FilterFieldValue>& rVals = pAry[i].Values;
+            for (sal_Int32 j = 0, n = rVals.getLength(); j < n; ++j)
+            {
+                ScQueryEntry::Item aItem;
+                aItem.meType   = rVals[j].IsNumeric ? ScQueryEntry::ByValue : ScQueryEntry::ByString;
+                aItem.mfVal    = rVals[j].NumericValue;
+                aItem.maString = rVals[j].StringValue;
+
+                if (aItem.meType == ScQueryEntry::ByValue && pDoc)
+                    pDoc->GetFormatTable()->GetInputLineString(aItem.mfVal, 0, aItem.maString);
+
+                rItems.push_back(aItem);
+            }
+        }
+    }
+
+    size_t nParamCount = rParam.GetEntryCount();    // Param wird nicht unter 8 resized
+    for (size_t i = nCount; i < nParamCount; ++i)
+        rParam.GetEntry(i).bDoQuery = false;        // ueberzaehlige Felder zuruecksetzen
+}
+
+}
+
 uno::Sequence<sheet::TableFilterField2> SAL_CALL ScFilterDescriptorBase::getFilterFields2()
 throw(uno::RuntimeException)
 {
@@ -1229,50 +1334,93 @@ throw(uno::RuntimeException)
     for (SCSIZE i=0; i<nCount; i++)
     {
         const ScQueryEntry& rEntry = aParam.GetEntry(i);
-        const ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
+        convertQueryEntryToUno(rEntry, aField);
 
-        aField.Connection    = (rEntry.eConnect == SC_AND) ? sheet::FilterConnection_AND : sheet::FilterConnection_OR;
-        aField.Field         = rEntry.nField;
-        aField.IsNumeric     = !rItem.meType != ScQueryEntry::ByString;
-        aField.StringValue   = rItem.maString;
-        aField.NumericValue  = rItem.mfVal;
+        bool bByEmpty = false;
+        if (aField.Operator == sheet::FilterOperator2::EQUAL)
+        {
+            if (rEntry.IsQueryByEmpty())
+            {
+                aField.Operator = sheet::FilterOperator2::EMPTY;
+                aField.NumericValue = 0;
+                bByEmpty = true;
+            }
+            else if (rEntry.IsQueryByNonEmpty())
+            {
+                aField.Operator = sheet::FilterOperator2::NOT_EMPTY;
+                aField.NumericValue = 0;
+                bByEmpty = true;
+            }
+        }
 
-        switch (rEntry.eOp)             // ScQueryOp
+        if (!bByEmpty)
         {
-        case SC_EQUAL:
+            const ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
+            aField.IsNumeric     = !rItem.meType != ScQueryEntry::ByString;
+            aField.StringValue   = rItem.maString;
+            aField.NumericValue  = rItem.mfVal;
+        }
+
+        pAry[i] = aField;
+    }
+    return aSeq;
+}
+
+uno::Sequence<sheet::TableFilterField3> SAL_CALL ScFilterDescriptorBase::getFilterFields3()
+    throw(uno::RuntimeException)
+{
+    SolarMutexGuard aGuard;
+    ScQueryParam aParam;
+    GetData(aParam);
+
+    SCSIZE nEntries = aParam.GetEntryCount();   // allozierte Eintraege im Param
+    SCSIZE nCount = 0;                          // aktive
+    while ( nCount < nEntries &&
+        aParam.GetEntry(nCount).bDoQuery )
+        ++nCount;
+
+    sheet::TableFilterField3 aField;
+    uno::Sequence<sheet::TableFilterField3> aSeq(static_cast<sal_Int32>(nCount));
+    sheet::TableFilterField3* pAry = aSeq.getArray();
+    for (SCSIZE i = 0; i < nCount; ++i)
+    {
+        const ScQueryEntry& rEntry = aParam.GetEntry(i);
+        convertQueryEntryToUno(rEntry, aField);
+
+        bool bByEmpty = false;
+        if (aField.Operator == sheet::FilterOperator2::EQUAL)
+        {
+            if (rEntry.IsQueryByEmpty())
             {
-                aField.Operator = sheet::FilterOperator2::EQUAL;
-                if (rEntry.IsQueryByEmpty())
-                {
-                    aField.Operator = sheet::FilterOperator2::EMPTY;
-                    aField.NumericValue = 0;
-                }
-                else if (rEntry.IsQueryByNonEmpty())
-                {
-                    aField.Operator = sheet::FilterOperator2::NOT_EMPTY;
-                    aField.NumericValue = 0;
-                }
+                aField.Operator = sheet::FilterOperator2::EMPTY;
+                aField.Values.realloc(1);
+                aField.Values[0].NumericValue = 0;
+                bByEmpty = true;
+            }
+            else if (rEntry.IsQueryByNonEmpty())
+            {
+                aField.Operator = sheet::FilterOperator2::NOT_EMPTY;
+                aField.Values.realloc(1);
+                aField.Values[0].NumericValue = 0;
+                bByEmpty = true;
             }
-            break;
-        case SC_LESS:                   aField.Operator = sheet::FilterOperator2::LESS;                 break;
-        case SC_GREATER:                aField.Operator = sheet::FilterOperator2::GREATER;              break;
-        case SC_LESS_EQUAL:             aField.Operator = sheet::FilterOperator2::LESS_EQUAL;           break;
-        case SC_GREATER_EQUAL:          aField.Operator = sheet::FilterOperator2::GREATER_EQUAL;        break;
-        case SC_NOT_EQUAL:              aField.Operator = sheet::FilterOperator2::NOT_EQUAL;            break;
-        case SC_TOPVAL:                 aField.Operator = sheet::FilterOperator2::TOP_VALUES;           break;
-        case SC_BOTVAL:                 aField.Operator = sheet::FilterOperator2::BOTTOM_VALUES;        break;
-        case SC_TOPPERC:                aField.Operator = sheet::FilterOperator2::TOP_PERCENT;          break;
-        case SC_BOTPERC:                aField.Operator = sheet::FilterOperator2::BOTTOM_PERCENT;       break;
-        case SC_CONTAINS:               aField.Operator = sheet::FilterOperator2::CONTAINS;             break;
-        case SC_DOES_NOT_CONTAIN:       aField.Operator = sheet::FilterOperator2::DOES_NOT_CONTAIN;     break;
-        case SC_BEGINS_WITH:            aField.Operator = sheet::FilterOperator2::BEGINS_WITH;          break;
-        case SC_DOES_NOT_BEGIN_WITH:    aField.Operator = sheet::FilterOperator2::DOES_NOT_BEGIN_WITH;  break;
-        case SC_ENDS_WITH:              aField.Operator = sheet::FilterOperator2::ENDS_WITH;            break;
-        case SC_DOES_NOT_END_WITH:      aField.Operator = sheet::FilterOperator2::DOES_NOT_END_WITH;    break;
-        default:
-            OSL_FAIL("Falscher Filter-enum");
-            aField.Operator = sheet::FilterOperator2::EMPTY;
         }
+
+        if (!bByEmpty)
+        {
+            const ScQueryEntry::QueryItemsType& rItems = rEntry.GetQueryItems();
+            size_t nItemCount = rItems.size();
+            aField.Values.realloc(nItemCount);
+            ScQueryEntry::QueryItemsType::const_iterator itr = rItems.begin(), itrEnd = rItems.end();
+            for (size_t j = 0; itr != itrEnd; ++itr, ++j)
+            {
+                aField.Values[j].IsNumeric = itr->meType != ScQueryEntry::ByString;
+                aField.Values[j].StringValue = itr->maString;
+                aField.Values[j].NumericValue = itr->mfVal;
+
+            }
+        }
+
         pAry[i] = aField;
     }
     return aSeq;
@@ -1347,6 +1495,17 @@ void SAL_CALL ScFilterDescriptorBase::setFilterFields2(
     PutData(aParam);
 }
 
+void SAL_CALL ScFilterDescriptorBase::setFilterFields3(
+    const uno::Sequence<sheet::TableFilterField3>& aFilterFields )
+    throw(uno::RuntimeException)
+{
+    SolarMutexGuard aGuard;
+    ScQueryParam aParam;
+    GetData(aParam);
+    fillQueryParam(aParam, pDocSh->GetDocument(), aFilterFields);
+    PutData(aParam);
+}
+
 // Rest sind Properties
 
 // XPropertySet
commit 34493546d62eff44c2a0f8111551ce50695e054b
Author: Kohei Yoshida <kohei.yoshida at suse.com>
Date:   Tue Nov 29 14:27:04 2011 -0500

    New UNO API to handle multi-value filters.

diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk
index 5fe45e9..0391056 100644
--- a/offapi/UnoApi_offapi.mk
+++ b/offapi/UnoApi_offapi.mk
@@ -3318,6 +3318,7 @@ $(eval $(call gb_UnoApiTarget_add_idlfiles,offapi,offapi/com/sun/star/sheet,\
 	FillDirection \
 	FillMode \
 	FilterConnection \
+	FilterFieldValue \
 	FilterOperator \
 	FilterOperator2 \
 	FormulaLanguage \
@@ -3350,6 +3351,7 @@ $(eval $(call gb_UnoApiTarget_add_idlfiles,offapi,offapi/com/sun/star/sheet,\
 	SubTotalColumn \
 	TableFilterField \
 	TableFilterField2 \
+	TableFilterField3 \
 	TableOperationMode \
 	TablePageBreakData \
 	TableValidationVisibility \
@@ -3445,6 +3447,7 @@ $(eval $(call gb_UnoApiTarget_add_idlfiles,offapi,offapi/com/sun/star/sheet,\
 	XSheetConditionalEntry \
 	XSheetFilterDescriptor \
 	XSheetFilterDescriptor2 \
+	XSheetFilterDescriptor3 \
 	XSheetFilterable \
 	XSheetFilterableEx \
 	XSheetLinkable \
diff --git a/offapi/com/sun/star/sheet/FilterFieldValue.idl b/offapi/com/sun/star/sheet/FilterFieldValue.idl
new file mode 100644
index 0000000..1e157fb
--- /dev/null
+++ b/offapi/com/sun/star/sheet/FilterFieldValue.idl
@@ -0,0 +1,54 @@
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License or as specified alternatively below. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Major Contributor(s):
+ *   Copyright (C) 2011 Kohei Yoshida <kohei.yoshida at suse.com>
+ *
+ * All Rights Reserved.
+ *
+ * For minor contributions see the git repository.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+#ifndef __com_sun_star_sheet_FilterFieldValue_idl__
+#define __com_sun_star_sheet_FilterFieldValue_idl__
+
+module com {  module sun {  module star {  module sheet {
+
+/**
+ * @since LibreOffice 3.5
+ */
+struct FilterFieldValue
+{
+    /** selects whether the <member>TableFilterFieldValue::NumericValue</member>
+        or the <member>TableFilterFieldValue::StringValue</member> is used.
+     */
+    boolean IsNumeric;
+
+    /** specifies a numeric value for the condition.
+     */
+    double NumericValue;
+
+    /** specifies a string value for the condition.
+     */
+    string StringValue;
+};
+
+}; }; }; };
+
+#endif
diff --git a/offapi/com/sun/star/sheet/TableFilterField3.idl b/offapi/com/sun/star/sheet/TableFilterField3.idl
new file mode 100644
index 0000000..8ddd2a9
--- /dev/null
+++ b/offapi/com/sun/star/sheet/TableFilterField3.idl
@@ -0,0 +1,62 @@
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License or as specified alternatively below. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Major Contributor(s):
+ *   Copyright (C) 2011 Kohei Yoshida <kohei.yoshida at suse.com>
+ *
+ * All Rights Reserved.
+ *
+ * For minor contributions see the git repository.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+#ifndef __com_sun_star_sheet_TableFilterField3_idl__
+#define __com_sun_star_sheet_TableFilterField3_idl__
+
+#include <com/sun/star/sheet/FilterConnection.idl>
+#include <com/sun/star/sheet/FilterOperator2.idl>
+#include <com/sun/star/sheet/FilterFieldValue.idl>
+
+module com {  module sun {  module star {  module sheet {
+
+/**
+ * @since LibreOffice 3.5
+ */
+struct TableFilterField3
+{
+    /** specifies how the condition is connected to the previous condition.
+     */
+    FilterConnection Connection;
+
+    /** specifies which field (column) is used for the condition.
+     */
+    long Field;
+
+    /** specifies the type of the condition as defined in
+        <type>FilterOperator2</type>.
+    */
+    long Operator;
+
+    /** specifies values to match against.  Each filter field may have one or
+        more values.*/
+    sequence<FilterFieldValue> Values;
+};
+
+}; }; }; };
+
+#endif
diff --git a/offapi/com/sun/star/sheet/XSelectedSheetsSupplier.idl b/offapi/com/sun/star/sheet/XSelectedSheetsSupplier.idl
index fe49579..6b16af5 100644
--- a/offapi/com/sun/star/sheet/XSelectedSheetsSupplier.idl
+++ b/offapi/com/sun/star/sheet/XSelectedSheetsSupplier.idl
@@ -32,6 +32,9 @@
 
 module com { module sun { module star { module sheet {
 
+/**
+ * @since LibreOffice 3.5
+ */
 interface XSelectedSheetsSupplier: com::sun::star::uno::XInterface
 {
     /**
diff --git a/offapi/com/sun/star/sheet/XSheetFilterDescriptor3.idl b/offapi/com/sun/star/sheet/XSheetFilterDescriptor3.idl
new file mode 100644
index 0000000..58f7ef8
--- /dev/null
+++ b/offapi/com/sun/star/sheet/XSheetFilterDescriptor3.idl
@@ -0,0 +1,65 @@
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License or as specified alternatively below. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Major Contributor(s):
+ *   Copyright (C) 2011 Kohei Yoshida <kohei.yoshida at suse.com>
+ *
+ * All Rights Reserved.
+ *
+ * For minor contributions see the git repository.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+#ifndef __com_sun_star_sheet_XSheetFilterDescriptor3_idl__
+#define __com_sun_star_sheet_XSheetFilterDescriptor3_idl__
+
+#include <com/sun/star/sheet/TableFilterField3.idl>
+#include <com/sun/star/uno/XInterface.idl>
+
+module com {  module sun {  module star {  module sheet {
+
+/** provides access to a collection of filter conditions (filter fields).
+
+    <p>This interface uses the <type>TableFilterField3</type> struct.
+    whereas the <type>XSheetFilterDescriptor2</type> interface uses the
+    <type>TableFilterField2</type> struct.</p>
+
+    @see SheetFilterDescriptor2
+
+    @since LibreOffice 3.5
+ */
+interface XSheetFilterDescriptor3: com::sun::star::uno::XInterface
+{
+    //-------------------------------------------------------------------------
+
+    /** returns the collection of filter fields.
+     */
+    sequence<TableFilterField3> getFilterFields3();
+
+    //-------------------------------------------------------------------------
+
+    /** sets a new collection of filter fields.
+     */
+    void setFilterFields3( [in] sequence<TableFilterField3> aFilterFields );
+
+};
+
+}; }; }; };
+
+#endif
+


More information about the Libreoffice-commits mailing list