| /******************************************************************************* |
| * 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; |
| } |
| |
| } |