blob: b84f840b5d1a1e206a0bde10119e9300153baaa5 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012, 2020 Original authors 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:
* Original authors and others - initial API and implementation
* Dirk Fauth <dirk.fauth@googlemail.com> - Bug 453177
******************************************************************************/
package org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy;
import org.eclipse.nebula.widgets.nattable.data.IDataProvider;
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy.command.GroupByColumnCommandHandler;
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy.command.UngroupByColumnCommandHandler;
import org.eclipse.nebula.widgets.nattable.grid.layer.ColumnHeaderLayer;
import org.eclipse.nebula.widgets.nattable.grid.layer.DimensionallyDependentLayer;
import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
import org.eclipse.nebula.widgets.nattable.layer.ILayer;
import org.eclipse.nebula.widgets.nattable.layer.cell.ILayerCell;
import org.eclipse.nebula.widgets.nattable.layer.cell.LayerCell;
import org.eclipse.nebula.widgets.nattable.layer.event.RowStructuralRefreshEvent;
/**
* The layer that is used to render the groupBy region where columns can be
* dragged from to perform grouping and ungrouping actions.
*/
public class GroupByHeaderLayer extends DimensionallyDependentLayer {
public static final String GROUP_BY_REGION = "GROUP_BY_REGION"; //$NON-NLS-1$
private final GroupByModel groupByModel;
private GroupByHeaderPainter groupByHeaderPainter;
private boolean visible = true;
/**
* Create a {@link GroupByHeaderLayer} that uses the default
* {@link GroupByHeaderConfiguration}.
*
* @param groupByModel
* The {@link GroupByModel} needed for grouping operations.
* @param horizontalLayerDependency
* The {@link ILayer} to which this header layer is horizontally
* dependent.
* @param columnHeaderDataProvider
* The {@link IDataProvider} of the column header which is needed
* to create the {@link GroupByHeaderConfiguration}
*/
public GroupByHeaderLayer(
GroupByModel groupByModel, ILayer horizontalLayerDependency,
IDataProvider columnHeaderDataProvider) {
this(groupByModel, horizontalLayerDependency, columnHeaderDataProvider, null, null);
}
/**
* Create a {@link GroupByHeaderLayer} that uses the default
* {@link GroupByHeaderConfiguration}.
*
* @param groupByModel
* The {@link GroupByModel} needed for grouping operations.
* @param horizontalLayerDependency
* The {@link ILayer} to which this header layer is horizontally
* dependent.
* @param columnHeaderDataProvider
* The {@link IDataProvider} of the column header which is needed
* to create the {@link GroupByHeaderConfiguration}
* @param columnHeaderLayer
* The {@link ColumnHeaderLayer} which should be used to create
* the {@link GroupByHeaderConfiguration} if it should support
* showing the renamed column headers. Can be <code>null</code>
* which results in using either the given
* columnHeaderDataProvider or the given
* {@link GroupByHeaderConfiguration}.
*
* @since 1.5
*/
public GroupByHeaderLayer(
GroupByModel groupByModel, ILayer horizontalLayerDependency,
IDataProvider columnHeaderDataProvider, ColumnHeaderLayer columnHeaderLayer) {
this(groupByModel, horizontalLayerDependency, columnHeaderDataProvider, columnHeaderLayer, null);
}
/**
* Create a {@link GroupByHeaderLayer} that uses the given
* {@link GroupByHeaderConfiguration}.
*
* @param groupByModel
* The {@link GroupByModel} needed for grouping operations.
* @param horizontalLayerDependency
* The {@link ILayer} to which this header layer is horizontally
* dependent.
* @param groupByHeaderConfiguration
* The {@link GroupByHeaderConfiguration} that should be added to
* this {@link GroupByHeaderLayer}. Needs to be a
* {@link GroupByHeaderConfiguration} because we retrieve the
* necessary {@link GroupByHeaderPainter} out of the
* configuration to setup this layer accordingly.
*/
public GroupByHeaderLayer(
GroupByModel groupByModel, ILayer horizontalLayerDependency,
GroupByHeaderConfiguration groupByHeaderConfiguration) {
this(groupByModel, horizontalLayerDependency, null, groupByHeaderConfiguration);
}
/**
* Create a {@link GroupByHeaderLayer} by either using the given
* {@link GroupByHeaderConfiguration} or creating a new
* {@link GroupByHeaderConfiguration} using the given column header
* {@link IDataProvider}. Note that either the {@link IDataProvider} or the
* {@link GroupByHeaderConfiguration} parameter must be set. If both are
* <code>null</code> an {@link IllegalArgumentException} will be thrown.
*
* @param groupByModel
* The {@link GroupByModel} needed for grouping operations.
* @param horizontalLayerDependency
* The {@link ILayer} to which this header layer is horizontally
* dependent.
* @param columnHeaderDataProvider
* The {@link IDataProvider} of the column header which is needed
* to create the {@link GroupByHeaderConfiguration}. Can be
* <code>null</code> if groupByHeaderConfiguration is not
* <code>null</code>.
* @param groupByHeaderConfiguration
* The {@link GroupByHeaderConfiguration} that should be added to
* this {@link GroupByHeaderLayer}. Needs to be a
* {@link GroupByHeaderConfiguration} because we retrieve the
* necessary {@link GroupByHeaderPainter} out of the
* configuration to setup this layer accordingly. Can be
* <code>null</code> if columnHeaderDataProvider is not
* <code>null</code>.
*/
public GroupByHeaderLayer(
GroupByModel groupByModel, ILayer horizontalLayerDependency,
IDataProvider columnHeaderDataProvider,
GroupByHeaderConfiguration groupByHeaderConfiguration) {
this(groupByModel, horizontalLayerDependency, columnHeaderDataProvider, null, groupByHeaderConfiguration);
}
/**
* Create a {@link GroupByHeaderLayer} by either using the given
* {@link GroupByHeaderConfiguration} or creating a new
* {@link GroupByHeaderConfiguration} using the given column header
* {@link IDataProvider}. Note that either the {@link IDataProvider} or the
* {@link GroupByHeaderConfiguration} parameter must be set. If both are
* <code>null</code> an {@link IllegalArgumentException} will be thrown.
*
* @param groupByModel
* The {@link GroupByModel} needed for grouping operations.
* @param horizontalLayerDependency
* The {@link ILayer} to which this header layer is horizontally
* dependent.
* @param columnHeaderDataProvider
* The {@link IDataProvider} of the column header which is needed
* to create the {@link GroupByHeaderConfiguration}. Can be
* <code>null</code> if groupByHeaderConfiguration is not
* <code>null</code>.
* @param columnHeaderLayer
* The {@link ColumnHeaderLayer} which should be used to create
* the {@link GroupByHeaderConfiguration} if it should support
* showing the renamed column headers. Can be <code>null</code>
* which results in using either the given
* columnHeaderDataProvider or the given
* {@link GroupByHeaderConfiguration}.
* @param groupByHeaderConfiguration
* The {@link GroupByHeaderConfiguration} that should be added to
* this {@link GroupByHeaderLayer}. Needs to be a
* {@link GroupByHeaderConfiguration} because we retrieve the
* necessary {@link GroupByHeaderPainter} out of the
* configuration to setup this layer accordingly. Can be
* <code>null</code> if columnHeaderDataProvider is not
* <code>null</code>.
*
* @since 1.5
*/
public GroupByHeaderLayer(
GroupByModel groupByModel, ILayer horizontalLayerDependency,
IDataProvider columnHeaderDataProvider, ColumnHeaderLayer columnHeaderLayer,
GroupByHeaderConfiguration groupByHeaderConfiguration) {
super(new DataLayer(new IDataProvider() {
@Override
public Object getDataValue(int columnIndex, int rowIndex) {
return null;
}
@Override
public void setDataValue(int columnIndex, int rowIndex, Object newValue) {
// no local data storage
}
@Override
public int getRowCount() {
return 1;
}
@Override
public int getColumnCount() {
return 1;
}
}));
if (groupByModel == null) {
throw new IllegalArgumentException("GroupByModel can not be null!"); //$NON-NLS-1$
}
if (columnHeaderDataProvider == null && groupByHeaderConfiguration == null) {
throw new IllegalArgumentException("You must either specify a GroupByHeaderConfiguration " //$NON-NLS-1$
+ "or a columnHeaderDataProvider to be able to create an internal GroupByHeaderConfiguration!"); //$NON-NLS-1$
}
setHorizontalLayerDependency(horizontalLayerDependency);
setVerticalLayerDependency(getBaseLayer());
this.groupByModel = groupByModel;
registerPersistable(this.groupByModel);
registerCommandHandler(new GroupByColumnCommandHandler(this));
registerCommandHandler(new UngroupByColumnCommandHandler(this));
GroupByHeaderConfiguration configuration = null;
if (groupByHeaderConfiguration != null) {
configuration = groupByHeaderConfiguration;
} else {
configuration = new GroupByHeaderConfiguration(groupByModel, columnHeaderDataProvider, columnHeaderLayer);
}
addConfiguration(configuration);
this.groupByHeaderPainter = configuration.getGroupByHeaderPainter();
((DataLayer) getBaseLayer()).setRowHeightByPosition(0, this.groupByHeaderPainter.getPreferredHeight());
}
public GroupByModel getGroupByModel() {
return this.groupByModel;
}
public void setVisible(boolean visible) {
this.visible = visible;
fireLayerEvent(new RowStructuralRefreshEvent(getBaseLayer()));
}
public boolean isVisible() {
return this.visible;
}
@Override
public int getHeight() {
if (this.visible) {
return super.getHeight();
}
return 0;
}
@Override
public int getRowHeightByPosition(int rowPosition) {
if (this.visible) {
return super.getRowHeightByPosition(rowPosition);
}
return 0;
}
@Override
public ILayerCell getCellByPosition(int columnPosition, int rowPosition) {
return new LayerCell(this, 0, 0, 0, 0, getColumnCount(), 1);
}
public int getGroupByColumnIndexAtXY(int x, int y) {
return this.groupByHeaderPainter.getGroupByColumnIndexAtXY(x, y);
}
}