| /******************************************************************************* |
| * 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 |
| ******************************************************************************/ |
| package org.eclipse.nebula.widgets.nattable.grid.layer; |
| |
| import java.util.Collection; |
| |
| import org.eclipse.nebula.widgets.nattable.columnRename.DisplayColumnRenameDialogCommandHandler; |
| import org.eclipse.nebula.widgets.nattable.columnRename.RenameColumnHeaderCommandHandler; |
| import org.eclipse.nebula.widgets.nattable.columnRename.RenameColumnHelper; |
| import org.eclipse.nebula.widgets.nattable.columnRename.event.RenameColumnHeaderEvent; |
| import org.eclipse.nebula.widgets.nattable.layer.ILayer; |
| import org.eclipse.nebula.widgets.nattable.layer.IUniqueIndexLayer; |
| import org.eclipse.nebula.widgets.nattable.layer.LabelStack; |
| import org.eclipse.nebula.widgets.nattable.layer.LayerUtil; |
| import org.eclipse.nebula.widgets.nattable.layer.config.DefaultColumnHeaderLayerConfiguration; |
| import org.eclipse.nebula.widgets.nattable.layer.event.ILayerEvent; |
| import org.eclipse.nebula.widgets.nattable.layer.event.IStructuralChangeEvent; |
| import org.eclipse.nebula.widgets.nattable.layer.event.StructuralChangeEventHelper; |
| import org.eclipse.nebula.widgets.nattable.layer.event.StructuralDiff; |
| import org.eclipse.nebula.widgets.nattable.painter.layer.ILayerPainter; |
| import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer; |
| import org.eclipse.nebula.widgets.nattable.style.DisplayMode; |
| import org.eclipse.nebula.widgets.nattable.style.SelectionStyleLabels; |
| |
| /** |
| * Responsible for rendering, event handling etc on the column headers. |
| */ |
| public class ColumnHeaderLayer extends DimensionallyDependentLayer { |
| |
| private final SelectionLayer[] selectionLayer; |
| |
| protected RenameColumnHelper renameColumnHelper; |
| |
| /** |
| * Creates a column header layer using the default configuration and painter |
| * |
| * @param baseLayer |
| * The base layer for this layer, typically a DataLayer. |
| * @param horizontalLayerDependency |
| * The layer to link the horizontal dimension to, typically the |
| * body layer. |
| * @param selectionLayer |
| * The SelectionLayer needed to respond to selection events. |
| */ |
| public ColumnHeaderLayer( |
| IUniqueIndexLayer baseLayer, |
| ILayer horizontalLayerDependency, |
| SelectionLayer selectionLayer) { |
| |
| this(baseLayer, horizontalLayerDependency, selectionLayer, true); |
| } |
| |
| /** |
| * Creates a column header layer using the default configuration and painter |
| * |
| * @param baseLayer |
| * The base layer for this layer, typically a DataLayer. |
| * @param horizontalLayerDependency |
| * The layer to link the horizontal dimension to, typically the |
| * body layer. |
| * @param selectionLayer |
| * 0 to multiple SelectionLayer needed to respond to selection |
| * events. |
| * @since 1.4 |
| */ |
| public ColumnHeaderLayer( |
| IUniqueIndexLayer baseLayer, |
| ILayer horizontalLayerDependency, |
| SelectionLayer... selectionLayer) { |
| |
| this(baseLayer, horizontalLayerDependency, selectionLayer, true); |
| } |
| |
| /** |
| * Creates a row header layer using the default painter. |
| * |
| * @param baseLayer |
| * The base layer for this layer, typically a DataLayer. |
| * @param horizontalLayerDependency |
| * The layer to link the horizontal dimension to, typically the |
| * body layer. |
| * @param selectionLayer |
| * The SelectionLayer needed to respond to selection events. |
| * @param useDefaultConfiguration |
| * Flag to configure whether to use the default configuration or |
| * not. |
| */ |
| public ColumnHeaderLayer( |
| IUniqueIndexLayer baseLayer, |
| ILayer horizontalLayerDependency, |
| SelectionLayer selectionLayer, |
| boolean useDefaultConfiguration) { |
| |
| this(baseLayer, horizontalLayerDependency, selectionLayer, useDefaultConfiguration, null); |
| } |
| |
| /** |
| * Creates a row header layer using the default painter. |
| * |
| * @param baseLayer |
| * The base layer for this layer, typically a DataLayer. |
| * @param horizontalLayerDependency |
| * The layer to link the horizontal dimension to, typically the |
| * body layer. |
| * @param selectionLayer |
| * 0 to multiple SelectionLayer needed to respond to selection |
| * events. |
| * @param useDefaultConfiguration |
| * Flag to configure whether to use the default configuration or |
| * not. |
| * @since 1.4 |
| */ |
| public ColumnHeaderLayer( |
| IUniqueIndexLayer baseLayer, |
| ILayer horizontalLayerDependency, |
| SelectionLayer[] selectionLayer, |
| boolean useDefaultConfiguration) { |
| |
| this(baseLayer, horizontalLayerDependency, selectionLayer, useDefaultConfiguration, null); |
| } |
| |
| /** |
| * @param baseLayer |
| * The base layer for this layer, typically a DataLayer. |
| * @param horizontalLayerDependency |
| * The layer to link the horizontal dimension to, typically the |
| * body layer. |
| * @param selectionLayer |
| * The SelectionLayer needed to respond to selection events. |
| * @param useDefaultConfiguration |
| * Flag to configure whether to use the default configuration or |
| * not. |
| * @param layerPainter |
| * The painter for this layer or <code>null</code> to use the |
| * painter of the base layer. |
| */ |
| public ColumnHeaderLayer( |
| IUniqueIndexLayer baseLayer, |
| ILayer horizontalLayerDependency, |
| SelectionLayer selectionLayer, |
| boolean useDefaultConfiguration, |
| ILayerPainter layerPainter) { |
| |
| this(baseLayer, horizontalLayerDependency, |
| selectionLayer != null ? new SelectionLayer[] { selectionLayer } : new SelectionLayer[] {}, |
| useDefaultConfiguration, layerPainter); |
| } |
| |
| /** |
| * |
| * @param baseLayer |
| * The base layer for this layer, typically a DataLayer. |
| * @param horizontalLayerDependency |
| * The layer to link the horizontal dimension to, typically the |
| * body layer. |
| * @param selectionLayer |
| * 0 to multiple SelectionLayer needed to respond to selection |
| * events. |
| * @param useDefaultConfiguration |
| * Flag to configure whether to use the default configuration or |
| * not. |
| * @param layerPainter |
| * The painter for this layer or <code>null</code> to use the |
| * painter of the base layer. |
| * @since 1.4 |
| */ |
| public ColumnHeaderLayer( |
| IUniqueIndexLayer baseLayer, |
| ILayer horizontalLayerDependency, |
| SelectionLayer[] selectionLayer, |
| boolean useDefaultConfiguration, |
| ILayerPainter layerPainter) { |
| |
| super(baseLayer, horizontalLayerDependency, baseLayer); |
| |
| if (selectionLayer == null) { |
| this.selectionLayer = new SelectionLayer[] {}; |
| } else { |
| this.selectionLayer = selectionLayer; |
| } |
| |
| this.layerPainter = layerPainter; |
| |
| this.renameColumnHelper = new RenameColumnHelper(this); |
| registerPersistable(this.renameColumnHelper); |
| |
| for (SelectionLayer sl : this.selectionLayer) { |
| sl.addLayerListener(new ColumnHeaderSelectionListener(this)); |
| } |
| registerCommandHandlers(); |
| |
| if (useDefaultConfiguration) { |
| addConfiguration(new DefaultColumnHeaderLayerConfiguration()); |
| } |
| } |
| |
| @Override |
| public String getDisplayModeByPosition(int columnPosition, int rowPosition) { |
| String displayMode = super.getDisplayModeByPosition(columnPosition, rowPosition); |
| if (this.selectionLayer.length > 0) { |
| int selectionLayerColumnPosition = LayerUtil.convertColumnPosition(this, columnPosition, this.selectionLayer[0]); |
| for (SelectionLayer sl : this.selectionLayer) { |
| if (sl.isColumnPositionSelected(selectionLayerColumnPosition)) { |
| if (DisplayMode.HOVER.equals(displayMode)) { |
| return DisplayMode.SELECT_HOVER; |
| } |
| return DisplayMode.SELECT; |
| } |
| } |
| } |
| return displayMode; |
| } |
| |
| @Override |
| public LabelStack getConfigLabelsByPosition(int columnPosition, int rowPosition) { |
| LabelStack labelStack = super.getConfigLabelsByPosition(columnPosition, rowPosition); |
| |
| if (this.selectionLayer.length > 0) { |
| final int selectionLayerColumnPosition = LayerUtil.convertColumnPosition(this, columnPosition, this.selectionLayer[0]); |
| boolean fullySelected = true; |
| for (SelectionLayer sl : this.selectionLayer) { |
| if (!sl.isColumnPositionFullySelected(selectionLayerColumnPosition)) { |
| fullySelected = false; |
| break; |
| } |
| } |
| |
| if (fullySelected) { |
| labelStack.addLabel(SelectionStyleLabels.COLUMN_FULLY_SELECTED_STYLE); |
| } |
| } |
| |
| return labelStack; |
| } |
| |
| @Override |
| public Object getDataValueByPosition(int columnPosition, int rowPosition) { |
| int columnIndex = getColumnIndexByPosition(columnPosition); |
| if (isColumnRenamed(columnIndex)) { |
| return getRenamedColumnLabelByIndex(columnIndex); |
| } |
| return super.getDataValueByPosition(columnPosition, rowPosition); |
| } |
| |
| // Configuration |
| |
| @Override |
| protected void registerCommandHandlers() { |
| registerCommandHandler(new RenameColumnHeaderCommandHandler(this)); |
| registerCommandHandler(new DisplayColumnRenameDialogCommandHandler(this)); |
| } |
| |
| // Column header renaming |
| |
| @Override |
| public void handleLayerEvent(ILayerEvent event) { |
| if (event instanceof IStructuralChangeEvent) { |
| IStructuralChangeEvent structuralChangeEvent = (IStructuralChangeEvent) event; |
| if (structuralChangeEvent.isHorizontalStructureChanged()) { |
| Collection<StructuralDiff> columnDiffs = structuralChangeEvent.getColumnDiffs(); |
| |
| if (columnDiffs != null && !columnDiffs.isEmpty() |
| && !StructuralChangeEventHelper.isReorder(columnDiffs)) { |
| this.renameColumnHelper.handleStructuralChanges(columnDiffs); |
| } |
| } |
| } |
| super.handleLayerEvent(event); |
| } |
| |
| /** |
| * @param columnPosition |
| * the column position for which the original label is requested |
| * @return column header as defined by the data source |
| */ |
| public String getOriginalColumnLabel(int columnPosition) { |
| Object dataValue = super.getDataValueByPosition(columnPosition, 0); |
| return dataValue != null ? dataValue.toString() : ""; //$NON-NLS-1$ |
| } |
| |
| /** |
| * @param columnPosition |
| * the column position for which the renamed label is requested |
| * @return renamed column header if the column has been renamed, NULL |
| * otherwise |
| */ |
| public String getRenamedColumnLabel(int columnPosition) { |
| int index = getColumnIndexByPosition(columnPosition); |
| return getRenamedColumnLabelByIndex(index); |
| } |
| |
| /** |
| * @param columnIndex |
| * the column index for which the renamed label is requested |
| * @return renamed column header if the column has been renamed, NULL |
| * otherwise |
| */ |
| public String getRenamedColumnLabelByIndex(int columnIndex) { |
| return this.renameColumnHelper.getRenamedColumnLabel(columnIndex); |
| } |
| |
| /** |
| * @param columnIndex |
| * the column index that should be checked |
| * @return <code>true</code> if the column at the given index has been given |
| * a custom name by the user. |
| */ |
| public boolean isColumnRenamed(int columnIndex) { |
| return this.renameColumnHelper.isColumnRenamed(columnIndex); |
| } |
| |
| public boolean renameColumnPosition(int columnPosition, String customColumnName) { |
| boolean renamed = this.renameColumnHelper.renameColumnPosition(columnPosition, customColumnName); |
| if (renamed) { |
| fireLayerEvent(new RenameColumnHeaderEvent(this, columnPosition)); |
| } |
| return renamed; |
| } |
| |
| public boolean renameColumnIndex(int columnIndex, String customColumnName) { |
| boolean renamed = this.renameColumnHelper.renameColumnIndex(columnIndex, customColumnName); |
| if (renamed) { |
| // search for the bottom layer in the horizontal dependency to |
| // create the event for index and correct layer |
| ILayer baseLayer = getHorizontalLayerDependency(); |
| while (baseLayer.getUnderlyingLayerByPosition(0, 0) != null) { |
| baseLayer = baseLayer.getUnderlyingLayerByPosition(0, 0); |
| } |
| |
| baseLayer.fireLayerEvent(new RenameColumnHeaderEvent(baseLayer, columnIndex)); |
| } |
| return renamed; |
| } |
| |
| } |