diff options
Diffstat (limited to 'oox/source/xls/autofiltercontext.cxx')
-rw-r--r-- | oox/source/xls/autofiltercontext.cxx | 734 |
1 files changed, 71 insertions, 663 deletions
diff --git a/oox/source/xls/autofiltercontext.cxx b/oox/source/xls/autofiltercontext.cxx index 4ae31fc94c56..81327944fc05 100644 --- a/oox/source/xls/autofiltercontext.cxx +++ b/oox/source/xls/autofiltercontext.cxx @@ -26,750 +26,158 @@ ************************************************************************/ #include "oox/xls/autofiltercontext.hxx" -#include <rtl/ustrbuf.hxx> -#include <com/sun/star/container/XNameAccess.hpp> -#include <com/sun/star/container/XNamed.hpp> -#include <com/sun/star/table/XCellRange.hpp> -#include <com/sun/star/sheet/XDatabaseRange.hpp> -#include <com/sun/star/sheet/XDatabaseRanges.hpp> -#include <com/sun/star/sheet/XSheetFilterDescriptor.hpp> -#include <com/sun/star/sheet/FilterOperator.hpp> -#include <com/sun/star/sheet/FilterConnection.hpp> -#include <com/sun/star/i18n/XLocaleData.hpp> -#include "properties.hxx" -#include "oox/helper/attributelist.hxx" -#include "oox/helper/propertyset.hxx" -#include "oox/core/filterbase.hxx" -#include "oox/xls/addressconverter.hxx" -#define DEBUG_OOX_AUTOFILTER 0 - -#if USE_SC_MULTI_STRING_FILTER_PATCH -#include <com/sun/star/sheet/XExtendedSheetFilterDescriptor.hpp> -#include <com/sun/star/sheet/TableFilterFieldNormal.hpp> -#include <com/sun/star/sheet/TableFilterFieldMultiString.hpp> -using ::com::sun::star::sheet::TableFilterFieldNormal; -using ::com::sun::star::sheet::TableFilterFieldMultiString; -using ::com::sun::star::sheet::XExtendedSheetFilterDescriptor; -#else -#include <com/sun/star/sheet/TableFilterField.hpp> -using ::com::sun::star::sheet::TableFilterField; -#endif - -#if DEBUG_OOX_AUTOFILTER -#include <stdio.h> -#endif - -using ::rtl::OUString; -using ::rtl::OUStringBuffer; -using ::com::sun::star::uno::Reference; -using ::com::sun::star::uno::Exception; -using ::com::sun::star::uno::Sequence; -using ::com::sun::star::uno::UNO_QUERY; -using ::com::sun::star::uno::UNO_QUERY_THROW; -using ::com::sun::star::container::XNameAccess; -using ::com::sun::star::container::XNamed; -using ::com::sun::star::table::CellRangeAddress; -using ::com::sun::star::table::XCellRange; -using ::com::sun::star::sheet::XDatabaseRange; -using ::com::sun::star::sheet::XDatabaseRanges; -using ::com::sun::star::sheet::XSheetFilterDescriptor; -using ::com::sun::star::i18n::LocaleDataItem; -using ::com::sun::star::i18n::XLocaleData; -using ::com::sun::star::lang::Locale; -using ::oox::core::ContextHandlerRef; +#include "oox/xls/autofilterbuffer.hxx" +#include "oox/xls/biffinputstream.hxx" namespace oox { namespace xls { -// ============================================================================ - -FilterFieldItem::FilterFieldItem() : -#if USE_SC_MULTI_STRING_FILTER_PATCH - mpField(new TableFilterFieldNormal), -#else - mpField(new TableFilterField), -#endif - meType(NORMAL) -{ -} - -FilterFieldItem::FilterFieldItem(Type eType) : - meType(eType) -{ -#if USE_SC_MULTI_STRING_FILTER_PATCH - switch ( eType ) - { - case MULTI_STRING: - mpField.reset(new TableFilterFieldMultiString); - break; - case NORMAL: - mpField.reset(new TableFilterFieldNormal); - break; - default: - mpField.reset(new TableFilterFieldNormal); - } -#else - mpField.reset(new TableFilterField); - meType = NORMAL; -#endif -} +using ::oox::core::ContextHandlerRef; +using ::rtl::OUString; // ============================================================================ -OoxAutoFilterContext::OoxAutoFilterContext( OoxWorksheetFragmentBase& rFragment ) : - OoxWorksheetContextBase( rFragment ), - mbValidAddress( false ), - mbUseRegex( false ), - mbShowBlank( false ), - mbConnectionAnd( false ) +FilterSettingsContext::FilterSettingsContext( WorksheetContextBase& rParent, FilterSettingsBase& rFilterSettings ) : + WorksheetContextBase( rParent ), + mrFilterSettings( rFilterSettings ) { } -// oox.core.ContextHandler2Helper interface ----------------------------------- - -ContextHandlerRef OoxAutoFilterContext::onCreateContext( sal_Int32 nElement, const AttributeList& ) +ContextHandlerRef FilterSettingsContext::onCreateContext( sal_Int32 nElement, const AttributeList& /*rAttribs*/ ) { switch( getCurrentElement() ) { - case XLS_TOKEN( autoFilter ): - switch( nElement ) - { - case XLS_TOKEN( filterColumn ): return this; - } - break; - - case XLS_TOKEN( filterColumn ): - switch( nElement ) - { - case XLS_TOKEN( filters ): - case XLS_TOKEN( customFilters ): - case XLS_TOKEN( top10 ): - case XLS_TOKEN( dynamicFilter ): return this; - } - break; - case XLS_TOKEN( filters ): - switch( nElement ) - { - case XLS_TOKEN( filter ): return this; - } + if( nElement == XLS_TOKEN( filter ) ) return this; break; - case XLS_TOKEN( customFilters ): - switch( nElement ) - { - case XLS_TOKEN( customFilter ): return this; - } + if( nElement == XLS_TOKEN( customFilter ) ) return this; break; } return 0; } -void OoxAutoFilterContext::onStartElement( const AttributeList& rAttribs ) +void FilterSettingsContext::onStartElement( const AttributeList& rAttribs ) { - switch( getCurrentElement() ) - { - case XLS_TOKEN( autoFilter ): - importAutoFilter( rAttribs ); - break; - case XLS_TOKEN( filterColumn ): - if ( mbValidAddress ) - importFilterColumn( rAttribs ); - break; - case XLS_TOKEN( filters ): - if ( mbValidAddress ) - importFilters( rAttribs ); - break; - case XLS_TOKEN( filter ): - if ( mbValidAddress ) - importFilter( rAttribs ); - break; - case XLS_TOKEN( customFilters ): - if ( mbValidAddress ) - importCustomFilters( rAttribs ); - break; - case XLS_TOKEN( customFilter ): - if ( mbValidAddress ) - importCustomFilter( rAttribs ); - break; - case XLS_TOKEN( top10 ): - if ( mbValidAddress ) - importTop10( rAttribs ); - break; - case XLS_TOKEN( dynamicFilter ): - if ( mbValidAddress ) - importDynamicFilter( rAttribs ); - break; - } + mrFilterSettings.importAttribs( getCurrentElement(), rAttribs ); } -void OoxAutoFilterContext::onEndElement( const OUString& /*rChars*/ ) +ContextHandlerRef FilterSettingsContext::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& /*rStrm*/ ) { switch( getCurrentElement() ) { - case XLS_TOKEN( autoFilter ): - maybeShowBlank(); - setAutoFilter(); + case BIFF12_ID_DISCRETEFILTERS: + if( nRecId == BIFF12_ID_DISCRETEFILTER ) return this; break; - case XLS_TOKEN( filters ): - setFilterNames(); + case BIFF12_ID_CUSTOMFILTERS: + if( nRecId == BIFF12_ID_CUSTOMFILTER ) return this; break; } + return 0; } -#if DEBUG_OOX_AUTOFILTER -static void lclPrintNormalField( -#if USE_SC_MULTI_STRING_FILTER_PATCH - TableFilterFieldNormal* pField -#else - TableFilterField* pField -#endif -) +void FilterSettingsContext::onStartRecord( SequenceInputStream& rStrm ) { - using namespace ::com::sun::star::sheet; - - printf(" Operator: "); - switch ( pField->Operator ) - { - case FilterOperator_EQUAL: - printf("EQUAL"); - break; - case FilterOperator_NOT_EQUAL: - printf("NOT_EQUAL"); - break; - case com::sun::star::sheet::FilterOperator_GREATER: - printf("GREATER"); - break; - case com::sun::star::sheet::FilterOperator_GREATER_EQUAL: - printf("GREATER_EQUAL"); - break; - case FilterOperator_LESS: - printf("LESS"); - break; - case FilterOperator_LESS_EQUAL: - printf("LESS_EQUAL"); - break; - case FilterOperator_NOT_EMPTY: - printf("NOT_EMPTY"); - break; - case FilterOperator_EMPTY: - printf("EMPTY"); - break; - case FilterOperator_BOTTOM_PERCENT: - printf("BOTTOM_PERCENT"); - break; - case FilterOperator_BOTTOM_VALUES: - printf("BOTTOM_VALUES"); - break; - case FilterOperator_TOP_PERCENT: - printf("TOP_PERCENT"); - break; - case FilterOperator_TOP_VALUES: - printf("TOP_VALUES"); - break; - default: - printf("other"); - } - printf("\n"); - - printf(" StringValue: %s\n", - OUStringToOString(pField->StringValue, RTL_TEXTENCODING_UTF8).getStr()); - - printf(" NumericValue: %g\n", pField->NumericValue); - - printf(" IsNumeric: "); - if (pField->IsNumeric) - printf("yes\n"); - else - printf("no\n"); + mrFilterSettings.importRecord( getCurrentElement(), rStrm ); } -static void lclPrintFieldConnection( ::com::sun::star::sheet::FilterConnection eConn ) -{ - using namespace ::com::sun::star::sheet; +// ============================================================================ - printf(" Connection: "); - switch ( eConn ) - { - case FilterConnection_AND: - printf("AND"); - break; - case FilterConnection_OR: - printf("OR"); - break; - case FilterConnection_MAKE_FIXED_SIZE: - printf("MAKE_FIXED_SIZE"); - break; - default: - printf("other"); - } - printf("\n"); +FilterColumnContext::FilterColumnContext( WorksheetContextBase& rParent, FilterColumn& rFilterColumn ) : + WorksheetContextBase( rParent ), + mrFilterColumn( rFilterColumn ) +{ } -static void lclPrintFilterField( const FilterFieldItem& aItem ) +ContextHandlerRef FilterColumnContext::onCreateContext( sal_Int32 nElement, const AttributeList& /*rAttribs*/ ) { - using namespace ::com::sun::star::sheet; - - printf("----------------------------------------\n"); -#if USE_SC_MULTI_STRING_FILTER_PATCH + if( getCurrentElement() == XLS_TOKEN( filterColumn ) ) switch( nElement ) { - // Print common fields first. - - TableFilterFieldBase* pField = aItem.mpField.get(); - printf(" Field: %ld\n", pField->Field); - lclPrintFieldConnection(pField->Connection); - } - switch ( aItem.meType ) - { - case FilterFieldItem::NORMAL: - { - TableFilterFieldNormal* pField = static_cast<TableFilterFieldNormal*>(aItem.mpField.get()); - lclPrintNormalField(pField); - } - break; - case FilterFieldItem::MULTI_STRING: - { - TableFilterFieldMultiString* pMultiStrField = static_cast<TableFilterFieldMultiString*>(aItem.mpField.get()); - sal_Int32 nSize = pMultiStrField->StringSet.getLength(); - printf(" StringSet:\n"); - for ( sal_Int32 i = 0; i < nSize; ++i ) - { - printf(" * %s\n", - OUStringToOString(pMultiStrField->StringSet[i], RTL_TEXTENCODING_UTF8).getStr()); - } - } - break; + case XLS_TOKEN( filters ): + return new FilterSettingsContext( *this, mrFilterColumn.createFilterSettings< DiscreteFilter >() ); + case XLS_TOKEN( top10 ): + return new FilterSettingsContext( *this, mrFilterColumn.createFilterSettings< Top10Filter >() ); + case XLS_TOKEN( customFilters ): + return new FilterSettingsContext( *this, mrFilterColumn.createFilterSettings< CustomFilter >() ); } -#else - TableFilterField* pField = aItem.mpField.get(); - printf(" Field: %ld\n", pField->Field); - lclPrintFieldConnection(pField->Connection); - lclPrintNormalField(pField); - -#endif - fflush(stdout); + return 0; } -#endif -void OoxAutoFilterContext::initialize() +void FilterColumnContext::onStartElement( const AttributeList& rAttribs ) { - maFields.clear(); - maFilterNames.clear(); - mbValidAddress = mbShowBlank = mbUseRegex = mbConnectionAnd = false; + mrFilterColumn.importFilterColumn( rAttribs ); } -void OoxAutoFilterContext::setAutoFilter() +ContextHandlerRef FilterColumnContext::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& /*rStrm*/ ) { - using namespace ::com::sun::star::sheet; - - // Name this built-in database. - OUStringBuffer sDataAreaNameBuf( CREATE_OUSTRING("Excel_BuiltIn__FilterDatabase_ ") ); - sDataAreaNameBuf.append( static_cast<sal_Int32>(getSheetIndex()+1) ); - - OUString sDataAreaName = sDataAreaNameBuf.makeStringAndClear(); - Reference< XCellRange > xCellRange = getCellRange( maAutoFilterRange ); - - // Create a new database range, add filters to it and refresh the database - // for that to take effect. - - Reference< XDatabaseRanges > xDBRanges = getDatabaseRanges(); - if ( !xDBRanges.is() ) + if( getCurrentElement() == BIFF12_ID_FILTERCOLUMN ) switch( nRecId ) { - OSL_ENSURE( false, "OoxAutoFilterContext::setAutoFilter: DBRange empty" ); - return; + case BIFF12_ID_DISCRETEFILTERS: + return new FilterSettingsContext( *this, mrFilterColumn.createFilterSettings< DiscreteFilter >() ); + case BIFF12_ID_TOP10FILTER: + return new FilterSettingsContext( *this, mrFilterColumn.createFilterSettings< Top10Filter >() ); + case BIFF12_ID_CUSTOMFILTERS: + return new FilterSettingsContext( *this, mrFilterColumn.createFilterSettings< CustomFilter >() ); } - - Reference< XNameAccess > xNA( xDBRanges, UNO_QUERY_THROW ); - if ( !xNA->hasByName( sDataAreaName ) ) - xDBRanges->addNewByName( sDataAreaName, maAutoFilterRange ); - - Reference< XDatabaseRange > xDB( xNA->getByName( sDataAreaName ), UNO_QUERY ); - if ( xDB.is() ) - { - PropertySet aProp( xDB ); - aProp.setProperty( PROP_AutoFilter, true ); - } - - sal_Int32 nSize = maFields.size(); - sal_Int32 nMaxFieldCount = nSize; - Reference< XSheetFilterDescriptor > xDescriptor = xDB->getFilterDescriptor(); - if ( xDescriptor.is() ) - { - PropertySet aProp( xDescriptor ); - aProp.setProperty( PROP_ContainsHeader, true ); - aProp.setProperty( PROP_UseRegularExpressions, mbUseRegex ); - aProp.getProperty( nMaxFieldCount, PROP_MaxFieldCount ); - } - else - { - OSL_ENSURE(false, "OoxAutoFilterContext::setAutoFilter: descriptor is empty"); - return; - } - - // Unpack all column field items into a sequence. -#if USE_SC_MULTI_STRING_FILTER_PATCH - Reference< XExtendedSheetFilterDescriptor > xExtDescriptor( xDescriptor, UNO_QUERY ); - if ( !xExtDescriptor.is() ) - { - OSL_ENSURE(false, "OoxAutoFilterContext::setAutoFilter: extended descriptor is empty"); - return; - } - - xExtDescriptor->begin(); - - ::std::list< FilterFieldItem >::const_iterator itr = maFields.begin(), itrEnd = maFields.end(); - for (sal_Int32 i = 0; itr != itrEnd && i < nMaxFieldCount; ++itr, ++i) - { -#if DEBUG_OOX_AUTOFILTER - lclPrintFilterField(*itr); -#endif - switch ( itr->meType ) - { - case oox::xls::FilterFieldItem::MULTI_STRING: - { - // multi-string filter type - TableFilterFieldMultiString* pField = static_cast<TableFilterFieldMultiString*>( itr->mpField.get() ); - xExtDescriptor->addFilterFieldMultiString( *pField ); - } - break; - case oox::xls::FilterFieldItem::NORMAL: - default: - // normal filter type - TableFilterFieldNormal* pField = static_cast<TableFilterFieldNormal*>( itr->mpField.get() ); - xExtDescriptor->addFilterFieldNormal( *pField ); - } - } - xExtDescriptor->commit(); - -#else - Sequence< TableFilterField > aFields(nSize); - ::std::list< FilterFieldItem >::const_iterator itr = maFields.begin(), itrEnd = maFields.end(); - for (sal_Int32 i = 0; itr != itrEnd && i < nMaxFieldCount; ++itr, ++i) - { -#if DEBUG_OOX_AUTOFILTER - lclPrintFilterField( *itr ); -#endif - aFields[i] = *itr->mpField; - } - xDescriptor->setFilterFields( aFields ); -#endif - xDB->refresh(); + return 0; } -void OoxAutoFilterContext::maybeShowBlank() +void FilterColumnContext::onStartRecord( SequenceInputStream& rStrm ) { - using namespace ::com::sun::star::sheet; - - if ( !mbShowBlank ) - return; - -#if USE_SC_MULTI_STRING_FILTER_PATCH - FilterFieldItem aItem(FilterFieldItem::NORMAL); - TableFilterFieldNormal* pField = static_cast<TableFilterFieldNormal*>(aItem.mpField.get()); - pField->Field = mnCurColID; - pField->Operator = FilterOperator_EMPTY; - pField->Connection = FilterConnection_AND; - pField->IsNumeric = false; -#else - FilterFieldItem aItem; - aItem.mpField->Field = mnCurColID; - aItem.mpField->Operator = FilterOperator_EMPTY; - aItem.mpField->Connection = FilterConnection_AND; - aItem.mpField->IsNumeric = false; -#endif - maFields.push_back(aItem); + mrFilterColumn.importFilterColumn( rStrm ); } -void OoxAutoFilterContext::setFilterNames() -{ - using namespace ::com::sun::star::sheet; - - - sal_Int32 size = maFilterNames.size(); - if ( !size ) - return; - -#if USE_SC_MULTI_STRING_FILTER_PATCH - Sequence< OUString > aStrList(size); - ::std::list< OUString >::const_iterator itr = maFilterNames.begin(), itrEnd = maFilterNames.end(); - for (sal_Int32 i = 0; itr != itrEnd; ++itr, ++i) - aStrList[i] = *itr; - - FilterFieldItem aItem(FilterFieldItem::MULTI_STRING); - TableFilterFieldMultiString* pField = static_cast<TableFilterFieldMultiString*>( aItem.mpField.get() ); - pField->Field = mnCurColID; - pField->Connection = FilterConnection_AND; - pField->StringSet = aStrList; - - maFields.push_back(aItem); -#else - static const OUString sSep = CREATE_OUSTRING("|"); - - OUStringBuffer buf; - if ( size > 1 ) - { - buf.append( CREATE_OUSTRING("^(") ); - mbUseRegex = true; - } - - ::std::list< OUString >::const_iterator itr = maFilterNames.begin(), itrEnd = maFilterNames.end(); - bool bFirst = true; - for (; itr != itrEnd; ++itr) - { - if (bFirst) - bFirst = false; - else - buf.append( sSep ); - buf.append( *itr ); - } - if ( size > 1 ) - buf.append( CREATE_OUSTRING(")$") ); - - FilterFieldItem aItem; - aItem.mpField->Field = mnCurColID; - aItem.mpField->StringValue = buf.makeStringAndClear(); - aItem.mpField->Operator = FilterOperator_EQUAL; - aItem.mpField->Connection = FilterConnection_AND; - aItem.mpField->IsNumeric = false; - maFields.push_back(aItem); -#endif -} +// ============================================================================ -void OoxAutoFilterContext::importAutoFilter( const AttributeList& rAttribs ) +AutoFilterContext::AutoFilterContext( WorksheetFragmentBase& rFragment, AutoFilter& rAutoFilter ) : + WorksheetContextBase( rFragment ), + mrAutoFilter( rAutoFilter ) { - initialize(); - - mbValidAddress = getAddressConverter().convertToCellRange( - maAutoFilterRange, rAttribs.getString( XML_ref, OUString() ), getSheetIndex(), true, true ); } -void OoxAutoFilterContext::importFilterColumn( const AttributeList& rAttribs ) +ContextHandlerRef AutoFilterContext::onCreateContext( sal_Int32 nElement, const AttributeList& /*rAttribs*/ ) { - // hiddenButton and showButton attributes are not used for now. - mnCurColID = rAttribs.getInteger( XML_colId, -1 ); + if( (getCurrentElement() == XLS_TOKEN( autoFilter )) && (nElement == XLS_TOKEN( filterColumn )) ) + return new FilterColumnContext( *this, mrAutoFilter.createFilterColumn() ); + return 0; } -void OoxAutoFilterContext::importTop10( const AttributeList& rAttribs ) +void AutoFilterContext::onStartElement( const AttributeList& rAttribs ) { - using namespace ::com::sun::star::sheet; - - // filterVal attribute is not necessarily, since Calc also supports top 10 - // and top 10% filter type. - FilterFieldItem aItem; -#if USE_SC_MULTI_STRING_FILTER_PATCH - TableFilterFieldNormal* pField = static_cast<TableFilterFieldNormal*>(aItem.mpField.get()); -#else - TableFilterField* pField = aItem.mpField.get(); -#endif - pField->Field = mnCurColID; - - bool bPercent = rAttribs.getBool( XML_percent, false ); - bool bTop = rAttribs.getBool( XML_top, true ); - pField->NumericValue = rAttribs.getDouble( XML_val, 0.0 ); - pField->IsNumeric = true; - - // When top10 filter item is present, that's the only filter item for that column. - if ( bTop ) - if ( bPercent ) - pField->Operator = FilterOperator_TOP_PERCENT; - else - pField->Operator = FilterOperator_TOP_VALUES; - else - if ( bPercent ) - pField->Operator = FilterOperator_BOTTOM_PERCENT; - else - pField->Operator = FilterOperator_BOTTOM_VALUES; - - maFields.push_back(aItem); + mrAutoFilter.importAutoFilter( rAttribs, getSheetIndex() ); } -void OoxAutoFilterContext::importCustomFilters( const AttributeList& rAttribs ) +ContextHandlerRef AutoFilterContext::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& /*rStrm*/ ) { - // OR is default when the 'and' attribute is absent. - mbConnectionAnd = rAttribs.getBool( XML_and, false ); + if( (getCurrentElement() == BIFF12_ID_AUTOFILTER) && (nRecId == BIFF12_ID_FILTERCOLUMN) ) + return new FilterColumnContext( *this, mrAutoFilter.createFilterColumn() ); + return 0; } -/** Do a best-effort guess of whether or not the given string is numerical. */ -static bool lclIsNumeric( const OUString& _str, const LocaleDataItem& aLocaleItem ) +void AutoFilterContext::onStartRecord( SequenceInputStream& rStrm ) { - OUString str = _str.trim(); - sal_Int32 size = str.getLength(); - - if ( !size ) - // Empty string. This can't be a number. - return false; - - // Get the decimal separator for the current locale. - const OUString& sep = aLocaleItem.decimalSeparator; - - bool bDecimalSep = false; - for (sal_Int32 i = 0; i < size; ++i) - { - OUString c = str.copy(i, 1); - if ( !c.compareTo(sep) ) - { - if ( bDecimalSep ) - return false; - else - { - bDecimalSep = true; - continue; - } - } - if ( (0 > c.compareToAscii("0") || 0 < c.compareToAscii("9")) ) - return false; - } - - return true; + mrAutoFilter.importAutoFilter( rStrm, getSheetIndex() ); } -/** Convert wildcard characters to regex equivalent. Returns true if any - wildcard character is found. */ -static bool lclWildcard2Regex( OUString& str ) -{ - bool bWCFound = false; - OUStringBuffer buf; - sal_Int32 size = str.getLength(); - buf.ensureCapacity(size + 6); // pure heuristics. - - sal_Unicode dot = '.', star = '*', hat = '^', dollar = '$'; - buf.append(hat); - for (sal_Int32 i = 0; i < size; ++i) - { - OUString c = str.copy(i, 1); - if ( !c.compareToAscii("?") ) - { - buf.append(dot); - bWCFound = true; - } - else if ( !c.compareToAscii("*") ) - { - buf.append(dot); - buf.append(star); - bWCFound = true; - } - else - buf.append(c); - } - buf.append(dollar); - - if (bWCFound) - str = buf.makeStringAndClear(); - - return bWCFound; -} +// ============================================================================ -/** Translate Excel's filter operator to Calc's. */ -static ::com::sun::star::sheet::FilterOperator lclTranslateFilterOp( sal_Int32 nToken ) +BiffAutoFilterContext::BiffAutoFilterContext( const WorksheetHelper& rHelper, AutoFilter& rAutoFilter ) : + BiffWorksheetContextBase( rHelper ), + mrAutoFilter( rAutoFilter ) { - using namespace ::com::sun::star::sheet; - - switch ( nToken ) - { - case XML_equal: - return FilterOperator_EQUAL; - case XML_notEqual: - return FilterOperator_NOT_EQUAL; - case XML_greaterThan: - return FilterOperator_GREATER; - case XML_greaterThanOrEqual: - return FilterOperator_GREATER_EQUAL; - case XML_lessThan: - return FilterOperator_LESS; - case XML_lessThanOrEqual: - return FilterOperator_LESS_EQUAL; - } - return FilterOperator_EQUAL; } -void OoxAutoFilterContext::importCustomFilter( const AttributeList& rAttribs ) +void BiffAutoFilterContext::importRecord( BiffInputStream& rStrm ) { - using namespace ::com::sun::star::sheet; - - sal_Int32 nToken = rAttribs.getToken( XML_operator, XML_equal ); -#if USE_SC_MULTI_STRING_FILTER_PATCH - FilterFieldItem aItem(FilterFieldItem::NORMAL); - TableFilterFieldNormal* pField = static_cast<TableFilterFieldNormal*>(aItem.mpField.get()); -#else - FilterFieldItem aItem; - TableFilterField* pField = aItem.mpField.get(); -#endif - pField->Field = mnCurColID; - pField->StringValue = rAttribs.getString( XML_val, OUString() ); - pField->NumericValue = pField->StringValue.toDouble(); - pField->Operator = lclTranslateFilterOp( nToken ); - - if ( nToken == XML_notEqual && !pField->StringValue.compareToAscii(" ") ) + switch( rStrm.getRecId() ) { - // Special case for hiding blanks. Excel translates "hide blanks" to - // (filter if notEqual " "). So, we need to translate it back. - pField->Operator = FilterOperator_NOT_EMPTY; - pField->IsNumeric = false; - maFields.push_back(aItem); - return; + // nothing to read for BIFF_ID_AUTOFILTER + case BIFF_ID_FILTERCOLUMN: mrAutoFilter.createFilterColumn().importFilterColumn( rStrm ); break; } - - switch ( nToken ) - { - case XML_equal: - case XML_notEqual: - { - Reference< XLocaleData > xLocale( getGlobalFactory()->createInstance( - CREATE_OUSTRING("com.sun.star.i18n.LocaleData") ), UNO_QUERY ); - - if ( !xLocale.is() ) - return; - - LocaleDataItem aLocaleItem = xLocale->getLocaleItem( ::com::sun::star::lang::Locale() ); - pField->IsNumeric = lclIsNumeric(pField->StringValue, aLocaleItem); - - if ( !pField->IsNumeric && lclWildcard2Regex(pField->StringValue) ) - mbUseRegex = true; - - maFields.push_back(aItem); - } - break; - - case XML_greaterThan: - case XML_greaterThanOrEqual: - case XML_lessThan: - case XML_lessThanOrEqual: - { - pField->IsNumeric = true; - maFields.push_back(aItem); - } - break; - default: - OSL_ENSURE( false, "OoxAutoFilterContext::importCustomFilter: unhandled case" ); - } -} - -void OoxAutoFilterContext::importFilters( const AttributeList& rAttribs ) -{ - // blank (boolean) and calendarType attributes can be present, but not used for now. - - mbShowBlank = rAttribs.getBool( XML_blank, false ); - maFilterNames.clear(); -} - -void OoxAutoFilterContext::importFilter( const AttributeList& rAttribs ) -{ - if (mnCurColID == -1) - return; - - OUString value = rAttribs.getString( XML_val, OUString() ); - if ( value.getLength() ) - maFilterNames.push_back(value); -} - -void OoxAutoFilterContext::importDynamicFilter( const AttributeList& /*rAttribs*/ ) -{ - // not implemented yet - Calc doesn't support this. } // ============================================================================ } // namespace xls } // namespace oox - |