blob: 1490c577a92dd397699c79d14a3478979d644581 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2013, 2020 Dirk Fauth and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Dirk Fauth <dirk.fauth@googlemail.com> - initial API and implementation
*******************************************************************************/
package org.eclipse.nebula.widgets.nattable.extension.glazedlists.filterrow;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.eclipse.nebula.widgets.nattable.command.DisposeResourcesCommand;
import org.eclipse.nebula.widgets.nattable.command.ILayerCommand;
import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
import org.eclipse.nebula.widgets.nattable.data.IColumnAccessor;
import org.eclipse.nebula.widgets.nattable.data.IDataProvider;
import org.eclipse.nebula.widgets.nattable.edit.EditConstants;
import org.eclipse.nebula.widgets.nattable.filterrow.FilterRowDataLayer;
import org.eclipse.nebula.widgets.nattable.filterrow.FilterRowDataProvider;
import org.eclipse.nebula.widgets.nattable.filterrow.combobox.ComboBoxFilterRowConfiguration;
import org.eclipse.nebula.widgets.nattable.filterrow.combobox.FilterRowComboBoxDataProvider;
import org.eclipse.nebula.widgets.nattable.filterrow.combobox.FilterRowComboUpdateEvent;
import org.eclipse.nebula.widgets.nattable.filterrow.combobox.IFilterRowComboUpdateListener;
import org.eclipse.nebula.widgets.nattable.filterrow.command.ClearAllFiltersCommand;
import org.eclipse.nebula.widgets.nattable.filterrow.command.ClearFilterCommand;
import org.eclipse.nebula.widgets.nattable.filterrow.command.ToggleFilterRowCommand;
import org.eclipse.nebula.widgets.nattable.grid.GridRegion;
import org.eclipse.nebula.widgets.nattable.layer.CompositeLayer;
import org.eclipse.nebula.widgets.nattable.layer.ILayer;
import org.eclipse.nebula.widgets.nattable.layer.event.RowStructuralRefreshEvent;
import ca.odell.glazedlists.FilterList;
import ca.odell.glazedlists.matchers.CompositeMatcherEditor;
/**
* CompositeLayer that is build out of the columnheader layer stack and a filter
* row layer. The column header layer stack needs to be provided at creation
* time while the filter row layer is created in here.
* <p>
* The special about this ComboBoxFilterRowHeaderComposite is that it creates a
* filter row that behaves and looks like the Excel filter. So it doesn't
* provide text fields for free filtering but adds comboboxes for all columns
* that contain all available values for that column that can be de-/selected
* via checkboxes.
*/
public class ComboBoxFilterRowHeaderComposite<T> extends CompositeLayer implements IFilterRowComboUpdateListener {
/**
* The FilterRowDataLayer which serves as the filter row layer.
*/
protected final FilterRowDataLayer<T> filterRowDataLayer;
/**
* Flag that allows to set the filter row visible or invisible.
*/
protected boolean filterRowVisible = true;
/**
* The IComboBoxDataProvider that is used to fill the filter row comboboxes.
*/
protected final FilterRowComboBoxDataProvider<T> comboBoxDataProvider;
/**
* The IFilterStrategy that is used by this
* ComboBoxFilterRowHeaderComposite.
*/
protected final ComboBoxGlazedListsFilterStrategy<T> filterStrategy;
/**
* Creates a new ComboBoxFilterRowHeaderComposite based on the given
* informations. Using this constructor will create the
* FilterRowComboBoxDataProvider needed for filtering and add the default
* ComboBoxFilterRowConfiguration.
*
* @param filterList
* The FilterList that will be used for filtering.
* @param bodyLayer
* A layer in the body region. Usually the DataLayer or a layer
* that is responsible for list event handling. Needed for
* creation of the FilterRowComboBoxDataProvider.
* @param baseCollection
* The base collection that is used to fill the body. Needed to
* determine the values to show in the filter comboboxes and
* initially pre-select them.
* @param bodyDataColumnAccessor
* The IColumnAccessor that is needed by the IFilterStrategy to
* perform filtering.
* @param columnHeaderLayer
* The columnheader layer the filter row layer is related to.
* Needed for building this CompositeLayer, dimensionally connect
* the filter row to and retrieve information and perform actions
* related to filtering.
* @param columnHeaderDataProvider
* The {@link IDataProvider} of the column header needed to
* retrieve the real column count of the column header and not a
* transformed one.
* @param configRegistry
* The {@link IConfigRegistry} needed to retrieve various
* configurations.
*/
public ComboBoxFilterRowHeaderComposite(
FilterList<T> filterList,
ILayer bodyLayer,
Collection<T> baseCollection,
IColumnAccessor<T> bodyDataColumnAccessor,
ILayer columnHeaderLayer,
IDataProvider columnHeaderDataProvider,
IConfigRegistry configRegistry) {
this(filterList,
bodyLayer,
baseCollection,
bodyDataColumnAccessor,
columnHeaderLayer,
columnHeaderDataProvider,
configRegistry,
true);
}
/**
* Creates a new ComboBoxFilterRowHeaderComposite based on the given
* informations. Using this constructor will create the
* FilterRowComboBoxDataProvider needed for filtering .
*
* @param filterList
* The FilterList that will be used for filtering.
* @param bodyLayer
* A layer in the body region. Usually the DataLayer or a layer
* that is responsible for list event handling. Needed for
* creation of the FilterRowComboBoxDataProvider.
* @param baseCollection
* The base collection that is used to fill the body. Needed to
* determine the values to show in the filter comboboxes and
* initially pre-select them.
* @param bodyDataColumnAccessor
* The IColumnAccessor that is needed by the IFilterStrategy to
* perform filtering.
* @param columnHeaderLayer
* The columnheader layer the filter row layer is related to.
* Needed for building this CompositeLayer, dimensionally connect
* the filter row to and retrieve information and perform actions
* related to filtering.
* @param columnHeaderDataProvider
* The {@link IDataProvider} of the column header needed to
* retrieve the real column count of the column header and not a
* transformed one.
* @param configRegistry
* The {@link IConfigRegistry} needed to retrieve various
* configurations.
* @param useDefaultConfiguration
* Tell whether the default configuration should be used or not.
* If not you need to ensure to add a configuration that adds at
* least the needed configuration specified in
* ComboBoxFilterRowConfiguration
*/
public ComboBoxFilterRowHeaderComposite(
FilterList<T> filterList,
ILayer bodyLayer,
Collection<T> baseCollection,
IColumnAccessor<T> bodyDataColumnAccessor,
ILayer columnHeaderLayer,
IDataProvider columnHeaderDataProvider,
IConfigRegistry configRegistry,
boolean useDefaultConfiguration) {
this(filterList,
new GlazedListsFilterRowComboBoxDataProvider<T>(
bodyLayer,
baseCollection,
bodyDataColumnAccessor),
bodyDataColumnAccessor,
columnHeaderLayer,
columnHeaderDataProvider,
configRegistry,
useDefaultConfiguration);
}
/**
* Creates a new ComboBoxFilterRowHeaderComposite based on the given
* informations. Using this constructor will create the
* FilterRowComboBoxDataProvider needed for filtering .
*
* @param filterList
* The FilterList that will be used for filtering.
* @param bodyLayer
* A layer in the body region. Usually the DataLayer or a layer
* that is responsible for list event handling. Needed for
* creation of the FilterRowComboBoxDataProvider.
* @param baseCollection
* The base collection that is used to fill the body. Needed to
* determine the values to show in the filter comboboxes and
* initially pre-select them.
* @param bodyDataColumnAccessor
* The IColumnAccessor that is needed by the IFilterStrategy to
* perform filtering.
* @param lazyLoading
* Flag to configure whether the content of the comboboxes should
* be loaded lazily or not. Default is <code>true</code>
* @param columnHeaderLayer
* The columnheader layer the filter row layer is related to.
* Needed for building this CompositeLayer, dimensionally connect
* the filter row to and retrieve information and perform actions
* related to filtering.
* @param columnHeaderDataProvider
* The {@link IDataProvider} of the column header needed to
* retrieve the real column count of the column header and not a
* transformed one.
* @param configRegistry
* The {@link IConfigRegistry} needed to retrieve various
* configurations.
* @param useDefaultConfiguration
* Tell whether the default configuration should be used or not.
* If not you need to ensure to add a configuration that adds at
* least the needed configuration specified in
* ComboBoxFilterRowConfiguration
*/
public ComboBoxFilterRowHeaderComposite(
FilterList<T> filterList,
ILayer bodyLayer,
Collection<T> baseCollection,
IColumnAccessor<T> bodyDataColumnAccessor,
boolean lazyLoading,
ILayer columnHeaderLayer,
IDataProvider columnHeaderDataProvider,
IConfigRegistry configRegistry,
boolean useDefaultConfiguration) {
this(filterList,
new GlazedListsFilterRowComboBoxDataProvider<T>(
bodyLayer,
baseCollection,
bodyDataColumnAccessor,
lazyLoading),
bodyDataColumnAccessor,
columnHeaderLayer,
columnHeaderDataProvider,
configRegistry,
useDefaultConfiguration);
}
/**
* Creates a new ComboBoxFilterRowHeaderComposite based on the given
* informations. Using this constructor will create the
* FilterRowComboBoxDataProvider needed for filtering .
* <p>
* <b>Note:</b>This constructor should only be used in cases where it is
* absolutely necessary to use a custom CompositeMatcherEditor. This could
* be for example to create a complex NatTable instance where several filter
* rows need to be combined.
*
* @param filterList
* The FilterList that will be used for filtering.
* @param matcherEditor
* The CompositeMatcherEditor that is set to the FilterList and
* needs to be used by the ComboBoxGlazedListsFilterStrategy to
* apply the filters via filter row.
* @param bodyLayer
* A layer in the body region. Usually the DataLayer or a layer
* that is responsible for list event handling. Needed for
* creation of the FilterRowComboBoxDataProvider.
* @param baseCollection
* The base collection that is used to fill the body. Needed to
* determine the values to show in the filter comboboxes and
* initially pre-select them.
* @param bodyDataColumnAccessor
* The IColumnAccessor that is needed by the IFilterStrategy to
* perform filtering.
* @param columnHeaderLayer
* The columnheader layer the filter row layer is related to.
* Needed for building this CompositeLayer, dimensionally connect
* the filter row to and retrieve information and perform actions
* related to filtering.
* @param columnHeaderDataProvider
* The {@link IDataProvider} of the column header needed to
* retrieve the real column count of the column header and not a
* transformed one.
* @param configRegistry
* The {@link IConfigRegistry} needed to retrieve various
* configurations.
* @param useDefaultConfiguration
* Tell whether the default configuration should be used or not.
* If not you need to ensure to add a configuration that adds at
* least the needed configuration specified in
* ComboBoxFilterRowConfiguration
*/
public ComboBoxFilterRowHeaderComposite(
FilterList<T> filterList,
CompositeMatcherEditor<T> matcherEditor,
ILayer bodyLayer,
Collection<T> baseCollection,
IColumnAccessor<T> bodyDataColumnAccessor,
ILayer columnHeaderLayer,
IDataProvider columnHeaderDataProvider,
IConfigRegistry configRegistry,
boolean useDefaultConfiguration) {
this(filterList,
matcherEditor,
new GlazedListsFilterRowComboBoxDataProvider<T>(
bodyLayer,
baseCollection,
bodyDataColumnAccessor),
bodyDataColumnAccessor,
columnHeaderLayer,
columnHeaderDataProvider,
configRegistry,
useDefaultConfiguration);
}
/**
* Creates a new ComboBoxFilterRowHeaderComposite based on the given
* informations. Using this constructor will create the
* FilterRowComboBoxDataProvider needed for filtering .
* <p>
* <b>Note:</b>This constructor should only be used in cases where it is
* absolutely necessary to use a custom CompositeMatcherEditor. This could
* be for example to create a complex NatTable instance where several filter
* rows need to be combined.
*
* @param filterList
* The FilterList that will be used for filtering.
* @param matcherEditor
* The CompositeMatcherEditor that is set to the FilterList and
* needs to be used by the ComboBoxGlazedListsFilterStrategy to
* apply the filters via filter row.
* @param bodyLayer
* A layer in the body region. Usually the DataLayer or a layer
* that is responsible for list event handling. Needed for
* creation of the FilterRowComboBoxDataProvider.
* @param baseCollection
* The base collection that is used to fill the body. Needed to
* determine the values to show in the filter comboboxes and
* initially pre-select them.
* @param bodyDataColumnAccessor
* The IColumnAccessor that is needed by the IFilterStrategy to
* perform filtering.
* @param lazyLoading
* Flag to configure whether the content of the comboboxes should
* be loaded lazily or not. Default is <code>true</code>
* @param columnHeaderLayer
* The columnheader layer the filter row layer is related to.
* Needed for building this CompositeLayer, dimensionally connect
* the filter row to and retrieve information and perform actions
* related to filtering.
* @param columnHeaderDataProvider
* The {@link IDataProvider} of the column header needed to
* retrieve the real column count of the column header and not a
* transformed one.
* @param configRegistry
* The {@link IConfigRegistry} needed to retrieve various
* configurations.
* @param useDefaultConfiguration
* Tell whether the default configuration should be used or not.
* If not you need to ensure to add a configuration that adds at
* least the needed configuration specified in
* ComboBoxFilterRowConfiguration
*/
public ComboBoxFilterRowHeaderComposite(
FilterList<T> filterList,
CompositeMatcherEditor<T> matcherEditor,
ILayer bodyLayer,
Collection<T> baseCollection,
IColumnAccessor<T> bodyDataColumnAccessor,
boolean lazyLoading,
ILayer columnHeaderLayer,
IDataProvider columnHeaderDataProvider,
IConfigRegistry configRegistry,
boolean useDefaultConfiguration) {
this(filterList,
matcherEditor,
new GlazedListsFilterRowComboBoxDataProvider<T>(
bodyLayer,
baseCollection,
bodyDataColumnAccessor,
lazyLoading),
bodyDataColumnAccessor,
columnHeaderLayer,
columnHeaderDataProvider,
configRegistry,
useDefaultConfiguration);
}
/**
* Creates a new ComboBoxFilterRowHeaderComposite based on the given
* informations. Using this constructor will add the default
* ComboBoxFilterRowConfiguration.
*
* @param filterList
* The FilterList that will be used for filtering.
* @param comboBoxDataProvider
* The FilterRowComboBoxDataProvider that should be used to fill
* the filter comboboxes.
* @param bodyDataColumnAccessor
* The IColumnAccessor that is needed by the IFilterStrategy to
* perform filtering.
* @param columnHeaderLayer
* The columnheader layer the filter row layer is related to.
* Needed for building this CompositeLayer, dimensionally connect
* the filter row to and retrieve information and perform actions
* related to filtering.
* @param columnHeaderDataProvider
* The {@link IDataProvider} of the column header needed to
* retrieve the real column count of the column header and not a
* transformed one.
* @param configRegistry
* The {@link IConfigRegistry} needed to retrieve various
* configurations.
*/
public ComboBoxFilterRowHeaderComposite(
FilterList<T> filterList,
FilterRowComboBoxDataProvider<T> comboBoxDataProvider,
IColumnAccessor<T> bodyDataColumnAccessor,
ILayer columnHeaderLayer,
IDataProvider columnHeaderDataProvider,
IConfigRegistry configRegistry) {
this(filterList,
comboBoxDataProvider,
bodyDataColumnAccessor,
columnHeaderLayer,
columnHeaderDataProvider,
configRegistry,
true);
}
/**
* Creates a new ComboBoxFilterRowHeaderComposite based on the given
* informations. Will use the given FilterList for creating the
* ComboBoxGlazedListsFilterStrategy and the given
* FilterRowComboBoxDataProvider instead of creating a new one.
*
* @param filterList
* The FilterList that will be used for filtering.
* @param comboBoxDataProvider
* The FilterRowComboBoxDataProvider that should be used to fill
* the filter comboboxes.
* @param bodyDataColumnAccessor
* The IColumnAccessor that is needed by the IFilterStrategy to
* perform filtering.
* @param columnHeaderLayer
* The columnheader layer the filter row layer is related to.
* Needed for building this CompositeLayer, dimensionally connect
* the filter row to and retrieve information and perform actions
* related to filtering.
* @param columnHeaderDataProvider
* The {@link IDataProvider} of the column header needed to
* retrieve the real column count of the column header and not a
* transformed one.
* @param configRegistry
* The {@link IConfigRegistry} needed to retrieve various
* configurations.
* @param useDefaultConfiguration
* Tell whether the default configuration should be used or not.
* If not you need to ensure to add a configuration that adds at
* least the needed configuration specified in
* ComboBoxFilterRowConfiguration
*/
public ComboBoxFilterRowHeaderComposite(
FilterList<T> filterList,
FilterRowComboBoxDataProvider<T> comboBoxDataProvider,
IColumnAccessor<T> bodyDataColumnAccessor,
ILayer columnHeaderLayer,
IDataProvider columnHeaderDataProvider,
IConfigRegistry configRegistry,
boolean useDefaultConfiguration) {
this(
new ComboBoxGlazedListsFilterStrategy<T>(
comboBoxDataProvider,
filterList,
bodyDataColumnAccessor,
configRegistry),
comboBoxDataProvider,
columnHeaderLayer,
columnHeaderDataProvider,
configRegistry,
useDefaultConfiguration);
}
/**
* Creates a new ComboBoxFilterRowHeaderComposite based on the given
* informations. Will use the given FilterList and MatcherEditor for
* creating the ComboBoxGlazedListsFilterStrategy and the given
* FilterRowComboBoxDataProvider instead of creating a new one.
* <p>
* <b>Note:</b>This constructor should only be used in cases where it is
* absolutely necessary to use a custom CompositeMatcherEditor. This could
* be for example to create a complex NatTable instance where several filter
* rows need to be combined.
*
* @param filterList
* The FilterList that will be used for filtering.
* @param matcherEditor
* The CompositeMatcherEditor that is set to the FilterList and
* needs to be used by the ComboBoxGlazedListsFilterStrategy to
* apply the filters via filter row.
* @param comboBoxDataProvider
* The FilterRowComboBoxDataProvider that should be used to fill
* the filter comboboxes.
* @param bodyDataColumnAccessor
* The IColumnAccessor that is needed by the IFilterStrategy to
* perform filtering.
* @param columnHeaderLayer
* The columnheader layer the filter row layer is related to.
* Needed for building this CompositeLayer, dimensionally connect
* the filter row to and retrieve information and perform actions
* related to filtering.
* @param columnHeaderDataProvider
* The {@link IDataProvider} of the column header needed to
* retrieve the real column count of the column header and not a
* transformed one.
* @param configRegistry
* The {@link IConfigRegistry} needed to retrieve various
* configurations.
* @param useDefaultConfiguration
* Tell whether the default configuration should be used or not.
* If not you need to ensure to add a configuration that adds at
* least the needed configuration specified in
* ComboBoxFilterRowConfiguration
*/
public ComboBoxFilterRowHeaderComposite(
FilterList<T> filterList,
CompositeMatcherEditor<T> matcherEditor,
FilterRowComboBoxDataProvider<T> comboBoxDataProvider,
IColumnAccessor<T> bodyDataColumnAccessor,
ILayer columnHeaderLayer,
IDataProvider columnHeaderDataProvider,
IConfigRegistry configRegistry,
boolean useDefaultConfiguration) {
this(
new ComboBoxGlazedListsFilterStrategy<T>(
comboBoxDataProvider,
filterList,
matcherEditor,
bodyDataColumnAccessor,
configRegistry),
comboBoxDataProvider,
columnHeaderLayer,
columnHeaderDataProvider,
configRegistry,
useDefaultConfiguration);
}
/**
* Creates a new ComboBoxFilterRowHeaderComposite based on the given
* informations. Will use the given ComboBoxGlazedListsFilterStrategy
* instead of creating a new one.
*
* @param filterStrategy
* The ComboBoxGlazedListsFilterStrategy that should be used for
* filtering.
* @param comboBoxDataProvider
* The FilterRowComboBoxDataProvider that should be used to fill
* the filter comboboxes.
* @param columnHeaderLayer
* The columnheader layer the filter row layer is related to.
* Needed for building this CompositeLayer, dimensionally connect
* the filter row to and retrieve information and perform actions
* related to filtering.
* @param columnHeaderDataProvider
* The {@link IDataProvider} of the column header needed to
* retrieve the real column count of the column header and not a
* transformed one.
* @param configRegistry
* The {@link IConfigRegistry} needed to retrieve various
* configurations.
* @param useDefaultConfiguration
* Tell whether the default configuration should be used or not.
* If not you need to ensure to add a configuration that adds at
* least the needed configuration specified in
* ComboBoxFilterRowConfiguration
*/
public ComboBoxFilterRowHeaderComposite(
ComboBoxGlazedListsFilterStrategy<T> filterStrategy,
FilterRowComboBoxDataProvider<T> comboBoxDataProvider,
ILayer columnHeaderLayer,
IDataProvider columnHeaderDataProvider,
IConfigRegistry configRegistry,
boolean useDefaultConfiguration) {
super(1, 2);
setChildLayer("columnHeader", columnHeaderLayer, 0, 0); //$NON-NLS-1$
this.filterStrategy = filterStrategy;
this.comboBoxDataProvider = comboBoxDataProvider;
this.comboBoxDataProvider.addCacheUpdateListener(this);
this.filterRowDataLayer =
new FilterRowDataLayer<T>(
this.filterStrategy,
columnHeaderLayer,
columnHeaderDataProvider,
configRegistry);
setAllValuesSelected();
setChildLayer(GridRegion.FILTER_ROW, this.filterRowDataLayer, 0, 1);
if (useDefaultConfiguration) {
addConfiguration(new ComboBoxFilterRowConfiguration(this.comboBoxDataProvider));
}
}
@Override
public void loadState(String prefix, Properties properties) {
this.comboBoxDataProvider.disableUpdateEvents();
super.loadState(prefix, properties);
this.comboBoxDataProvider.enableUpdateEvents();
}
/**
* @return The FilterRowDataLayer which serves as the filter row layer.
*/
public FilterRowDataLayer<T> getFilterRowDataLayer() {
return this.filterRowDataLayer;
}
/**
* @return The CompositeMatcherEditor that is used for filtering. As this
* one is filled with MatcherEditors by the IFilterStrategy, direct
* modifications may be overridden on changing cell values in the
* filter row.
*/
public CompositeMatcherEditor<T> getMatcherEditor() {
return this.filterStrategy.getMatcherEditor();
}
/**
* Returns the IFilterStrategy that is used by this
* ComboBoxFilterRowHeaderComposite. This is needed to integrate static
* filters, e.g. using GlazedListsRowHideShowLayer together with this
* ComboBoxFilterRowHeaderComposite by adding the MatcherEditor as static
* filter to the ComboBoxGlazedListsFilterStrategy.
*
* @return The IFilterStrategy that is used by this
* ComboBoxFilterRowHeaderComposite.
*/
public ComboBoxGlazedListsFilterStrategy<T> getFilterStrategy() {
return this.filterStrategy;
}
/**
* @return The IComboBoxDataProvider that is used to fill the filter row
* comboboxes.
*/
public FilterRowComboBoxDataProvider<T> getComboBoxDataProvider() {
return this.comboBoxDataProvider;
}
/**
* @return <code>true</code> if the filter row is visible,
* <code>false</code> if not.
*/
public boolean isFilterRowVisible() {
return this.filterRowVisible;
}
/**
* Sets the visibility state of the filter row.
*
* @param filterRowVisible
* <code>true</code> to set the filter row visible,
* <code>false</code> to hide it.
*/
public void setFilterRowVisible(boolean filterRowVisible) {
this.filterRowVisible = filterRowVisible;
fireLayerEvent(new RowStructuralRefreshEvent(this.filterRowDataLayer));
}
/**
* Sets all values for all comboboxes as selected. This is needed because
* selecting all items in the comboboxes mean to have no filter applied.
* <p>
* Note: The filter row IDataProvider is filled by modifying the Map of
* filter objects directly instead of calling setDataValue(). This is
* because calling setDataValue() will transform indexes which is not
* necessary on initialization and causes strange behaviour in some
* compositions.
*/
public void setAllValuesSelected() {
FilterRowDataProvider<T> dataProvider = this.filterRowDataLayer.getFilterRowDataProvider();
for (int i = 0; i < dataProvider.getColumnCount(); i++) {
dataProvider.getFilterIndexToObjectMap().put(i, EditConstants.SELECT_ALL_ITEMS_VALUE);
}
getFilterStrategy().applyFilter(dataProvider.getFilterIndexToObjectMap());
}
@Override
public int getHeight() {
if (this.filterRowVisible) {
return super.getHeight();
} else {
return getHeightOffset(1);
}
}
@Override
public int getRowCount() {
if (this.filterRowVisible) {
return super.getRowCount();
} else {
return super.getRowCount() - 1;
}
}
@Override
public boolean doCommand(ILayerCommand command) {
boolean handled = false;
if (command instanceof ToggleFilterRowCommand) {
setFilterRowVisible(!this.filterRowVisible);
return true;
}
// as clearing the filter means to select all items in the combo, we
// need to handle clear filter commands in here instead of delegating it
// to the FilterRowDataLayer
else if (command instanceof ClearFilterCommand
&& command.convertToTargetLayer(this)) {
int columnPosition = ((ClearFilterCommand) command).getColumnPosition();
this.filterRowDataLayer.setDataValueByPosition(
columnPosition,
0,
getComboBoxDataProvider().getValues(columnPosition, 0));
handled = true;
} else if (command instanceof ClearAllFiltersCommand) {
setAllValuesSelected();
handled = true;
} else if (command instanceof DisposeResourcesCommand) {
this.comboBoxDataProvider.dispose();
}
if (handled) {
fireLayerEvent(new RowStructuralRefreshEvent(this));
return true;
} else {
return super.doCommand(command);
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public void handleEvent(FilterRowComboUpdateEvent event) {
Map<Integer, Object> filterIndexToObjectMap =
this.filterRowDataLayer.getFilterRowDataProvider().getFilterIndexToObjectMap();
Object filterObject = filterIndexToObjectMap.get(event.getColumnIndex());
if (filterObject != null && filterObject instanceof Collection) {
Collection filterCollection = (Collection) filterObject;
// if a new value was added than ensure it is also added to the
// filter
if (event.getAddedItems() != null
&& !event.getAddedItems().isEmpty()) {
// as the filter collection is a list, we need to ensure that no
// double values are added
List itemsToAdd = new ArrayList(event.getAddedItems());
itemsToAdd.removeAll(filterCollection);
filterCollection.addAll(itemsToAdd);
}
// if a value was removed than ensure it is also removed from the
// filter
if (event.getRemovedItems() != null
&& !event.getRemovedItems().isEmpty()) {
filterCollection.removeAll(event.getRemovedItems());
}
}
// apply the filter to be sure filter row and applied filter are the
// same
getFilterStrategy().applyFilter(
this.filterRowDataLayer.getFilterRowDataProvider().getFilterIndexToObjectMap());
}
}