blob: f39949102dc9c7bad414647eb6e82d8962f02606 [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
* Jonas Hugo <Jonas.Hugo@jeppesen.com>,
* Markus Wahl <Markus.Wahl@jeppesen.com> - Use getters and setters for
* the markers of SelectionLayer instead of the fields.
* Vincent Lorenzo <vincent.lorenzo@cea.fr> - Bug 478622
******************************************************************************/
package org.eclipse.nebula.widgets.nattable.selection;
import static org.eclipse.nebula.widgets.nattable.selection.SelectionUtils.bothShiftAndControl;
import static org.eclipse.nebula.widgets.nattable.selection.SelectionUtils.isControlOnly;
import static org.eclipse.nebula.widgets.nattable.selection.SelectionUtils.isShiftOnly;
import static org.eclipse.nebula.widgets.nattable.selection.SelectionUtils.noShiftOrControl;
import org.eclipse.nebula.widgets.nattable.command.ILayerCommandHandler;
import org.eclipse.nebula.widgets.nattable.layer.ILayer;
import org.eclipse.nebula.widgets.nattable.selection.command.SelectColumnCommand;
import org.eclipse.nebula.widgets.nattable.selection.event.ColumnSelectionEvent;
import org.eclipse.swt.graphics.Rectangle;
public class SelectColumnCommandHandler implements ILayerCommandHandler<SelectColumnCommand> {
/**
* @since 1.6
*/
protected final SelectionLayer selectionLayer;
public SelectColumnCommandHandler(SelectionLayer selectionLayer) {
this.selectionLayer = selectionLayer;
}
@Override
public boolean doCommand(ILayer targetLayer, SelectColumnCommand command) {
if (command.convertToTargetLayer(this.selectionLayer)) {
selectColumn(
command.getColumnPosition(),
command.getRowPosition(),
command.isWithShiftMask(),
command.isWithControlMask());
return true;
}
return false;
}
protected void selectColumn(int columnPosition, int rowPosition,
boolean withShiftMask, boolean withControlMask) {
if (noShiftOrControl(withShiftMask, withControlMask)) {
this.selectionLayer.clear(false);
this.selectionLayer.selectCell(columnPosition, 0, false, false);
this.selectionLayer.selectRegion(columnPosition, 0, 1, Integer.MAX_VALUE);
this.selectionLayer.moveSelectionAnchor(columnPosition, rowPosition);
} else if (bothShiftAndControl(withShiftMask, withControlMask)) {
selectColumnWithShiftKey(columnPosition);
} else if (isShiftOnly(withShiftMask, withControlMask)) {
selectColumnWithShiftKey(columnPosition);
} else if (isControlOnly(withShiftMask, withControlMask)) {
selectColumnWithCtrlKey(columnPosition, rowPosition);
}
// Set last selected column position to the recently clicked column
this.selectionLayer.setLastSelectedCell(columnPosition, this.selectionLayer.getRowCount() - 1);
this.selectionLayer.fireLayerEvent(
new ColumnSelectionEvent(
this.selectionLayer,
columnPosition,
withShiftMask,
withControlMask));
}
private void selectColumnWithCtrlKey(int columnPosition, int rowPosition) {
Rectangle selectedColumnRectangle = new Rectangle(columnPosition, 0, 1, Integer.MAX_VALUE);
if (this.selectionLayer.isColumnPositionFullySelected(columnPosition)) {
this.selectionLayer.clearSelection(selectedColumnRectangle);
this.selectionLayer.setLastSelectedRegion(null);
// if there is still a column selected but no selection anchor, we
// need to set one for a consistent state
int[] selectedColumns = this.selectionLayer.getFullySelectedColumnPositions();
if (selectedColumns.length > 0
&& this.selectionLayer.getSelectionAnchor().columnPosition == SelectionLayer.NO_SELECTION) {
// determine column to move the anchor to
int toPos = selectedColumns[0];
for (int i = 0; i < selectedColumns.length; i++) {
if (selectedColumns[i] < columnPosition) {
toPos = selectedColumns[i];
} else {
break;
}
}
this.selectionLayer.moveSelectionAnchor(toPos, rowPosition);
}
} else {
if (this.selectionLayer.getLastSelectedRegion() != null) {
// Preserve last selected region
this.selectionLayer.selectRegion(
this.selectionLayer.getLastSelectedRegion().x,
this.selectionLayer.getLastSelectedRegion().y,
this.selectionLayer.getLastSelectedRegion().width,
this.selectionLayer.getLastSelectedRegion().height);
}
this.selectionLayer.selectRegion(columnPosition, 0, 1, Integer.MAX_VALUE);
this.selectionLayer.moveSelectionAnchor(columnPosition, rowPosition);
}
}
private void selectColumnWithShiftKey(int columnPosition) {
int numOfColumnsToInclude = 1;
int startColumnPosition = columnPosition;
// This method selects the range based on the selection anchor and the
// clicked position. Therefore the selection prior adding the newly
// calculated selection needs to be cleared in advance.
Rectangle lastSelectedRegion = this.selectionLayer.getLastSelectedRegion();
if (lastSelectedRegion != null) {
this.selectionLayer.getSelectionModel().clearSelection(lastSelectedRegion);
} else {
this.selectionLayer.getSelectionModel().clearSelection();
}
// move the selection anchor if multiple selection is disabled or there
// is no selection anchor active already
if (!this.selectionLayer.getSelectionModel().isMultipleSelectionAllowed()
|| this.selectionLayer.getSelectionAnchor().columnPosition == SelectionLayer.NO_SELECTION) {
this.selectionLayer.moveSelectionAnchor(columnPosition, 0);
}
if (this.selectionLayer.getSelectionAnchor().columnPosition != SelectionLayer.NO_SELECTION) {
numOfColumnsToInclude = Math.abs(this.selectionLayer.getSelectionAnchor().columnPosition - columnPosition) + 1;
if (this.selectionLayer.getSelectionAnchor().columnPosition < columnPosition) {
startColumnPosition = this.selectionLayer.getSelectionAnchor().columnPosition;
}
}
this.selectionLayer.selectRegion(startColumnPosition, 0, numOfColumnsToInclude, Integer.MAX_VALUE);
}
@Override
public Class<SelectColumnCommand> getCommandClass() {
return SelectColumnCommand.class;
}
}