blob: fb9757e2670fc727db851964f856b8ed1f881a20 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2014, 2020 Roman Flueckiger.
*
* 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:
* Roman Flueckiger <roman.flueckiger@mac.com> - initial API and implementation
******************************************************************************/
package org.eclipse.nebula.widgets.nattable.ui.matcher;
import org.eclipse.nebula.widgets.nattable.coordinate.PositionCoordinate;
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.selection.SelectionLayer;
import org.eclipse.swt.events.KeyEvent;
/**
* This class allows checking the current selection anchor's cell for a matching
* label. Only labels from the given {@link IUniqueIndexLayer} downwards are
* considered. Optionally the matcher can be chained with an additional
* {@link IKeyEventMatcher} (results are and'ed).
*/
public class SelectionAnchorCellLabelKeyEventMatcher implements IKeyEventMatcher {
protected final SelectionLayer selectionLayer;
protected final IUniqueIndexLayer layer;
protected final String labelToMatch;
protected final IKeyEventMatcher aggregate;
/**
* Create a {@link SelectionAnchorCellLabelKeyEventMatcher} that checks only
* if the given label is assigned to the selection anchor's cell, while the
* label stack is retrieved from the given layer.
*
* @param selectionLayer
* the {@link SelectionLayer} used to get the current selection
* anchor's position.
* @param layer
* the layer used to retrieve the label stack at the selection
* anchor's position.
* @param labelToMatch
* the label that should be part of the label stack at the
* selection anchor's position.
*/
public SelectionAnchorCellLabelKeyEventMatcher(SelectionLayer selectionLayer, IUniqueIndexLayer layer, String labelToMatch) {
this(selectionLayer, layer, labelToMatch, null);
}
/**
* Create a {@link SelectionAnchorCellLabelKeyEventMatcher} that checks if
* the aggregate matches as well as if the given label is assigned to the
* selection anchor's cell, while the label stack is retrieved from the
* given layer.
*
* @param selectionLayer
* the {@link SelectionLayer} used to get the current selection
* anchor's position.
* @param layer
* the layer used to retrieve the label stack at the selection
* anchor's position.
* @param labelToMatch
* the label that should be part of the label stack at the
* selection anchor's position.
* @param aggregate
* (optional) an additional {@link IKeyEventMatcher} to be
* chained with the result of this matcher (results are and'ed).
*/
public SelectionAnchorCellLabelKeyEventMatcher(SelectionLayer selectionLayer, IUniqueIndexLayer layer, String labelToMatch, IKeyEventMatcher aggregate) {
if (selectionLayer == null) {
throw new IllegalArgumentException("selectionLayer must not be null."); //$NON-NLS-1$
}
if (layer == null) {
throw new IllegalArgumentException("layer must not be null."); //$NON-NLS-1$
}
if (labelToMatch == null || labelToMatch.length() == 0) {
throw new IllegalArgumentException("labelToMatch must not be blank."); //$NON-NLS-1$
}
this.selectionLayer = selectionLayer;
this.layer = layer;
this.labelToMatch = labelToMatch;
this.aggregate = aggregate;
}
@Override
public boolean matches(KeyEvent event) {
PositionCoordinate anchorPosition = this.selectionLayer.getSelectionAnchor();
if (anchorPosition.rowPosition != SelectionLayer.NO_SELECTION && anchorPosition.columnPosition != SelectionLayer.NO_SELECTION) {
int layerColumnPosition = LayerUtil.convertColumnPosition(this.selectionLayer, anchorPosition.columnPosition, this.layer);
int layerRowPosition = LayerUtil.convertRowPosition(this.selectionLayer, anchorPosition.rowPosition, this.layer);
LabelStack labels = this.layer.getConfigLabelsByPosition(layerColumnPosition, layerRowPosition);
boolean labelMatches = labels.hasLabel(this.labelToMatch);
if (this.aggregate != null) {
return labelMatches && this.aggregate.matches(event);
}
return labelMatches;
}
return false;
}
/**
* Create a {@link SelectionAnchorCellLabelKeyEventMatcher} that checks only
* if the given label is assigned to the selection anchor's cell, while the
* label stack is retrieved from the given layer.
*
* @param selectionLayer
* the {@link SelectionLayer} used to get the current selection
* anchor's position.
* @param layer
* the layer used to retrieve the label stack at the selection
* anchor's position.
* @param labelToMatch
* the label that should be part of the label stack at the
* selection anchor's position.
*/
public static SelectionAnchorCellLabelKeyEventMatcher anchorLabel(SelectionLayer selectionLayer, IUniqueIndexLayer layer, String labelToMatch) {
return anchorLabel(selectionLayer, layer, labelToMatch, null);
}
/**
* Create a {@link SelectionAnchorCellLabelKeyEventMatcher} that checks if
* the aggregate matches as well as if the given label is assigned to the
* selection anchor's cell, while the label stack is retrieved from the
* given layer.
*
* @param selectionLayer
* the {@link SelectionLayer} used to get the current selection
* anchor's position.
* @param layer
* the layer used to retrieve the label stack at the selection
* anchor's position.
* @param labelToMatch
* the label that should be part of the label stack at the
* selection anchor's position.
* @param aggregate
* (optional) an additional {@link IKeyEventMatcher} to be
* chained with the result of this matcher (results are and'ed).
*/
public static SelectionAnchorCellLabelKeyEventMatcher anchorLabel(SelectionLayer selectionLayer, IUniqueIndexLayer layer, String labelToMatch, IKeyEventMatcher aggregate) {
return new SelectionAnchorCellLabelKeyEventMatcher(selectionLayer, layer, labelToMatch, aggregate);
}
}