| /******************************************************************************* |
| * 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.reorder.command; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.stream.Collectors; |
| |
| import org.eclipse.nebula.widgets.nattable.command.ILayerCommand; |
| import org.eclipse.nebula.widgets.nattable.command.LayerCommandUtil; |
| import org.eclipse.nebula.widgets.nattable.coordinate.ColumnPositionCoordinate; |
| import org.eclipse.nebula.widgets.nattable.layer.ILayer; |
| |
| /** |
| * Command to reorder multiple columns at once. |
| */ |
| public class MultiColumnReorderCommand implements ILayerCommand { |
| |
| private List<ColumnPositionCoordinate> fromColumnPositionCoordinates; |
| /** |
| * @since 1.6 |
| */ |
| protected ColumnPositionCoordinate toColumnPositionCoordinate; |
| private boolean reorderToLeftEdge; |
| private boolean reorderByIndex = false; |
| |
| /** |
| * |
| * @param layer |
| * The layer to which the column positions match. |
| * @param fromColumnPositions |
| * The column positions to reorder. |
| * @param toColumnPosition |
| * The target column position to reorder to. |
| */ |
| public MultiColumnReorderCommand(ILayer layer, List<Integer> fromColumnPositions, int toColumnPosition) { |
| this(layer, |
| fromColumnPositions.stream().mapToInt(Integer::intValue).toArray(), |
| toColumnPosition < layer.getColumnCount() ? toColumnPosition : toColumnPosition - 1, |
| toColumnPosition < layer.getColumnCount()); |
| } |
| |
| /** |
| * |
| * @param layer |
| * The layer to which the column positions match. |
| * @param fromColumnPositions |
| * The column positions to reorder. |
| * @param toColumnPosition |
| * The target column position to reorder to. |
| * @param reorderToLeftEdge |
| * <code>true</code> if the reorder operation should be done on |
| * the left edge of the toColumnPosition, <code>false</code> if |
| * it should be reordered to the right edge. |
| */ |
| public MultiColumnReorderCommand( |
| ILayer layer, |
| List<Integer> fromColumnPositions, |
| int toColumnPosition, |
| boolean reorderToLeftEdge) { |
| |
| this(layer, |
| fromColumnPositions.stream().mapToInt(Integer::intValue).toArray(), |
| toColumnPosition, |
| reorderToLeftEdge); |
| } |
| |
| /** |
| * |
| * @param layer |
| * The layer to which the column positions match. |
| * @param fromColumnPositions |
| * The column positions to reorder. |
| * @param toColumnPosition |
| * The target column position to reorder to. |
| * |
| * @since 2.0 |
| */ |
| public MultiColumnReorderCommand(ILayer layer, int[] fromColumnPositions, int toColumnPosition) { |
| this(layer, |
| fromColumnPositions, |
| toColumnPosition < layer.getColumnCount() ? toColumnPosition : toColumnPosition - 1, |
| toColumnPosition < layer.getColumnCount()); |
| } |
| |
| /** |
| * |
| * @param layer |
| * The layer to which the column positions match. |
| * @param fromColumnPositions |
| * The column positions to reorder. |
| * @param toColumnPosition |
| * The target column position to reorder to. |
| * @param reorderToLeftEdge |
| * <code>true</code> if the reorder operation should be done on |
| * the left edge of the toColumnPosition, <code>false</code> if |
| * it should be reordered to the right edge. |
| * |
| * @since 2.0 |
| */ |
| public MultiColumnReorderCommand( |
| ILayer layer, |
| int[] fromColumnPositions, |
| int toColumnPosition, |
| boolean reorderToLeftEdge) { |
| |
| this.fromColumnPositionCoordinates = new ArrayList<>(fromColumnPositions.length); |
| for (Integer fromColumnPosition : fromColumnPositions) { |
| this.fromColumnPositionCoordinates.add(new ColumnPositionCoordinate(layer, fromColumnPosition)); |
| } |
| |
| this.toColumnPositionCoordinate = new ColumnPositionCoordinate(layer, toColumnPosition); |
| |
| this.reorderToLeftEdge = reorderToLeftEdge; |
| } |
| |
| /** |
| * Clone constructor. |
| * |
| * @param command |
| * The command to clone. |
| */ |
| protected MultiColumnReorderCommand(MultiColumnReorderCommand command) { |
| this.fromColumnPositionCoordinates = new ArrayList<>(command.fromColumnPositionCoordinates); |
| this.toColumnPositionCoordinate = command.toColumnPositionCoordinate; |
| this.reorderToLeftEdge = command.reorderToLeftEdge; |
| this.reorderByIndex = command.reorderByIndex; |
| } |
| |
| /** |
| * Returns the column positions that should be reordered on the layer where |
| * this command is processed. Can be the column indexes if |
| * {@link #reorderByIndex} is set to <code>true</code>. |
| * |
| * @return The column positions that should be reordered. |
| */ |
| public List<Integer> getFromColumnPositions() { |
| return this.fromColumnPositionCoordinates.stream() |
| .map(ColumnPositionCoordinate::getColumnPosition) |
| .collect(Collectors.toList()); |
| } |
| |
| /** |
| * Returns the column positions that should be reordered on the layer where |
| * this command is processed. Can be the column indexes if |
| * {@link #reorderByIndex} is set to <code>true</code>. |
| * |
| * @return The column positions that should be reordered. |
| * @since 2.0 |
| */ |
| public int[] getFromColumnPositionsArray() { |
| return this.fromColumnPositionCoordinates.stream() |
| .mapToInt(ColumnPositionCoordinate::getColumnPosition) |
| .sorted() |
| .toArray(); |
| } |
| |
| /** |
| * |
| * @return The column position to which the columns should be reordered. |
| */ |
| public int getToColumnPosition() { |
| return this.toColumnPositionCoordinate.getColumnPosition(); |
| } |
| |
| /** |
| * |
| * @return <code>true</code> if the reorder operation should be done on the |
| * left edge of the toColumnPosition, <code>false</code> if it |
| * should be reordered to the right edge. |
| */ |
| public boolean isReorderToLeftEdge() { |
| return this.reorderToLeftEdge; |
| } |
| |
| /** |
| * |
| * @return <code>true</code> if the carried from columns are treated as |
| * indexes, <code>false</code> if they are treated as positions. |
| * Default is <code>false</code>. |
| * @since 1.6 |
| */ |
| public boolean isReorderByIndex() { |
| return this.reorderByIndex; |
| } |
| |
| /** |
| * Configure how the carried columns should be treated. By default they are |
| * treated as positions and converted to the local layer. Setting this value |
| * to <code>true</code> will treat the columns as indexes which will avoid |
| * conversion. This can be useful to reorder hidden columns for example. |
| * |
| * @param reorderByIndex |
| * <code>true</code> if the carried from columns should be |
| * treated as indexes, <code>false</code> if they should be |
| * treated as positions. |
| * @since 1.6 |
| */ |
| public void setReorderByIndex(boolean reorderByIndex) { |
| this.reorderByIndex = reorderByIndex; |
| } |
| |
| /** |
| * Toggles the coordinate from left edge to right edge and vice versa. Will |
| * not toggle if the coordinate is right edge of the last column or the left |
| * edge of the first column. |
| * |
| * @since 1.6 |
| */ |
| public void toggleCoordinateByEdge() { |
| if (this.reorderToLeftEdge |
| && this.toColumnPositionCoordinate.columnPosition > 0) { |
| this.toColumnPositionCoordinate.columnPosition--; |
| this.reorderToLeftEdge = false; |
| } else if (!this.reorderToLeftEdge |
| && this.toColumnPositionCoordinate.columnPosition < this.toColumnPositionCoordinate.getLayer().getColumnCount() - 1) { |
| this.toColumnPositionCoordinate.columnPosition++; |
| this.reorderToLeftEdge = true; |
| } |
| } |
| |
| /** |
| * |
| * @param fromPositions |
| * The new fromColumnPositions. |
| * |
| * @since 2.0 |
| */ |
| public void updateFromColumnPositions(int... fromPositions) { |
| this.fromColumnPositionCoordinates = new ArrayList<>(fromPositions.length); |
| for (int fromColumnPosition : fromPositions) { |
| this.fromColumnPositionCoordinates.add( |
| new ColumnPositionCoordinate(this.toColumnPositionCoordinate.getLayer(), fromColumnPosition)); |
| } |
| } |
| |
| /** |
| * |
| * @param toPosition |
| * The new toColumnPosition. |
| * |
| * @since 2.0 |
| */ |
| public void updateToColumnPosition(int toPosition) { |
| this.toColumnPositionCoordinate.columnPosition = toPosition; |
| } |
| |
| @Override |
| public boolean convertToTargetLayer(ILayer targetLayer) { |
| List<ColumnPositionCoordinate> convertedFromColumnPositionCoordinates = new ArrayList<>(this.fromColumnPositionCoordinates.size()); |
| |
| for (ColumnPositionCoordinate fromColumnPositionCoordinate : this.fromColumnPositionCoordinates) { |
| if (!this.reorderByIndex) { |
| ColumnPositionCoordinate convertedFromColumnPositionCoordinate = |
| LayerCommandUtil.convertColumnPositionToTargetContext(fromColumnPositionCoordinate, targetLayer); |
| if (convertedFromColumnPositionCoordinate != null) { |
| convertedFromColumnPositionCoordinates.add(convertedFromColumnPositionCoordinate); |
| } |
| } else { |
| convertedFromColumnPositionCoordinates.add(fromColumnPositionCoordinate); |
| } |
| } |
| |
| ColumnPositionCoordinate targetToColumnPositionCoordinate = |
| LayerCommandUtil.convertColumnPositionToTargetContext(this.toColumnPositionCoordinate, targetLayer); |
| |
| if (!convertedFromColumnPositionCoordinates.isEmpty() |
| && targetToColumnPositionCoordinate != null) { |
| this.fromColumnPositionCoordinates = convertedFromColumnPositionCoordinates; |
| this.toColumnPositionCoordinate = targetToColumnPositionCoordinate; |
| return true; |
| } else { |
| return false; |
| } |
| } |
| |
| @Override |
| public MultiColumnReorderCommand cloneCommand() { |
| return new MultiColumnReorderCommand(this); |
| } |
| |
| } |