| /******************************************************************************* |
| * Copyright (c) 2013, 2020 Dirk Fauth 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: |
| * Dirk Fauth <dirk.fauth@googlemail.com> - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.nebula.widgets.nattable.reorder.command; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.nebula.widgets.nattable.command.ILayerCommand; |
| import org.eclipse.nebula.widgets.nattable.command.LayerCommandUtil; |
| import org.eclipse.nebula.widgets.nattable.coordinate.RowPositionCoordinate; |
| import org.eclipse.nebula.widgets.nattable.layer.ILayer; |
| |
| /** |
| * Command for reordering rows. |
| */ |
| public class MultiRowReorderCommand implements ILayerCommand { |
| |
| /** |
| * The coordinates of the rows that should be reordered |
| */ |
| private List<RowPositionCoordinate> fromRowPositionCoordinates; |
| /** |
| * The coordinate of the row to which the dragged rows should be dropped. |
| * |
| * @since 1.6 |
| */ |
| protected RowPositionCoordinate toRowPositionCoordinate; |
| /** |
| * Flag to indicate if the row is dragged to the top edge of the layer. |
| * Needed for the special case when the reordering is performed to the |
| * bottom edge. |
| */ |
| private boolean reorderToTopEdge; |
| /** |
| * Flag to indicate if the carried from rows are treated as indexes, or if |
| * they are treated as positions. |
| */ |
| private boolean reorderByIndex = false; |
| |
| /** |
| * |
| * @param layer |
| * The layer the positions are related to |
| * @param fromRowPositions |
| * The positions of the rows that should be reordered |
| * @param toRowPosition |
| * The position of the row to which the dragged row should be |
| * dropped |
| */ |
| public MultiRowReorderCommand(ILayer layer, List<Integer> fromRowPositions, int toRowPosition) { |
| this(layer, |
| fromRowPositions.stream().mapToInt(Integer::intValue).toArray(), |
| toRowPosition < layer.getRowCount() ? toRowPosition : toRowPosition - 1, |
| toRowPosition < layer.getRowCount()); |
| } |
| |
| /** |
| * |
| * @param layer |
| * The layer the positions are related to |
| * @param fromRowPositions |
| * The positions of the rows that should be reordered |
| * @param toRowPosition |
| * The position of the row to which the dragged row should be |
| * dropped |
| * @param reorderToTopEdge |
| * Flag to indicate if the row is dragged to the top edge of the |
| * layer |
| */ |
| public MultiRowReorderCommand(ILayer layer, |
| List<Integer> fromRowPositions, |
| int toRowPosition, |
| boolean reorderToTopEdge) { |
| |
| this(layer, |
| fromRowPositions.stream().mapToInt(Integer::intValue).toArray(), |
| toRowPosition, |
| reorderToTopEdge); |
| } |
| |
| /** |
| * |
| * @param layer |
| * The layer the positions are related to |
| * @param fromRowPositions |
| * The positions of the rows that should be reordered |
| * @param toRowPosition |
| * The position of the row to which the dragged row should be |
| * dropped |
| * |
| * @since 2.0 |
| */ |
| public MultiRowReorderCommand(ILayer layer, int[] fromRowPositions, int toRowPosition) { |
| this(layer, |
| fromRowPositions, |
| toRowPosition < layer.getRowCount() ? toRowPosition : toRowPosition - 1, |
| toRowPosition < layer.getRowCount()); |
| } |
| |
| /** |
| * |
| * @param layer |
| * The layer the positions are related to |
| * @param fromRowPositions |
| * The positions of the rows that should be reordered |
| * @param toRowPosition |
| * The position of the row to which the dragged row should be |
| * dropped |
| * @param reorderToTopEdge |
| * Flag to indicate if the row is dragged to the top edge of the |
| * layer |
| * |
| * @since 2.0 |
| */ |
| public MultiRowReorderCommand(ILayer layer, |
| int[] fromRowPositions, |
| int toRowPosition, |
| boolean reorderToTopEdge) { |
| |
| this.fromRowPositionCoordinates = new ArrayList<>(fromRowPositions.length); |
| for (int fromRowPosition : fromRowPositions) { |
| this.fromRowPositionCoordinates.add(new RowPositionCoordinate(layer, fromRowPosition)); |
| } |
| |
| this.toRowPositionCoordinate = new RowPositionCoordinate(layer, toRowPosition); |
| |
| this.reorderToTopEdge = reorderToTopEdge; |
| } |
| |
| /** |
| * Constructor used for cloning purposes |
| * |
| * @param command |
| * The command which is base for the new one |
| */ |
| protected MultiRowReorderCommand(MultiRowReorderCommand command) { |
| this.fromRowPositionCoordinates = new ArrayList<>(command.fromRowPositionCoordinates); |
| this.toRowPositionCoordinate = command.toRowPositionCoordinate; |
| this.reorderToTopEdge = command.reorderToTopEdge; |
| } |
| |
| /** |
| * @return The positions of the rows that should be reordered |
| */ |
| public List<Integer> getFromRowPositions() { |
| List<Integer> fromRowPositions = new ArrayList<>(this.fromRowPositionCoordinates.size()); |
| for (RowPositionCoordinate fromRowPositionCoordinate : this.fromRowPositionCoordinates) { |
| fromRowPositions.add(fromRowPositionCoordinate.getRowPosition()); |
| } |
| return fromRowPositions; |
| } |
| |
| /** |
| * @return The positions of the rows that should be reordered |
| * @since 2.0 |
| */ |
| public int[] getFromRowPositionsArray() { |
| return this.fromRowPositionCoordinates.stream() |
| .mapToInt(RowPositionCoordinate::getRowPosition) |
| .sorted() |
| .toArray(); |
| } |
| |
| /** |
| * @return The position of the row to which the dragged rows should be |
| * dropped |
| */ |
| public int getToRowPosition() { |
| return this.toRowPositionCoordinate.getRowPosition(); |
| } |
| |
| /** |
| * @return Flag to indicate if the row is dragged to the top edge of the |
| * layer. |
| */ |
| public boolean isReorderToTopEdge() { |
| return this.reorderToTopEdge; |
| } |
| |
| /** |
| * |
| * @return <code>true</code> if the carried from rows 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 rows 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 rows as indexes which will avoid |
| * conversion. This can be useful to reorder hidden rows 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 top edge to bottom edge and vice versa. Will |
| * not toggle if the coordinate is bottom edge of the last row or the top |
| * edge of the first row. |
| * |
| * @since 1.6 |
| */ |
| public void toggleCoordinateByEdge() { |
| if (this.reorderToTopEdge |
| && this.toRowPositionCoordinate.rowPosition > 0) { |
| this.toRowPositionCoordinate.rowPosition--; |
| this.reorderToTopEdge = false; |
| } else if (!this.reorderToTopEdge |
| && this.toRowPositionCoordinate.rowPosition < this.toRowPositionCoordinate.getLayer().getRowCount() - 1) { |
| this.toRowPositionCoordinate.rowPosition++; |
| this.reorderToTopEdge = true; |
| } |
| } |
| |
| /** |
| * |
| * @param fromPositions |
| * The new fromRowPositions. |
| * |
| * @since 2.0 |
| */ |
| public void updateFromRowPositions(int... fromPositions) { |
| this.fromRowPositionCoordinates = new ArrayList<>(fromPositions.length); |
| for (int fromRowPosition : fromPositions) { |
| this.fromRowPositionCoordinates.add( |
| new RowPositionCoordinate(this.toRowPositionCoordinate.getLayer(), fromRowPosition)); |
| } |
| } |
| |
| /** |
| * |
| * @param toPosition |
| * The new toRowPosition. |
| * |
| * @since 2.0 |
| */ |
| public void updateToRowPosition(int toPosition) { |
| this.toRowPositionCoordinate.rowPosition = toPosition; |
| } |
| |
| @Override |
| public boolean convertToTargetLayer(ILayer targetLayer) { |
| List<RowPositionCoordinate> convertedFromRowPositionCoordinates = |
| new ArrayList<>(this.fromRowPositionCoordinates.size()); |
| |
| for (RowPositionCoordinate fromRowPositionCoordinate : this.fromRowPositionCoordinates) { |
| if (!this.reorderByIndex) { |
| RowPositionCoordinate convertedFromRowPositionCoordinate = |
| LayerCommandUtil.convertRowPositionToTargetContext(fromRowPositionCoordinate, targetLayer); |
| if (convertedFromRowPositionCoordinate != null) { |
| convertedFromRowPositionCoordinates.add(convertedFromRowPositionCoordinate); |
| } |
| } else { |
| convertedFromRowPositionCoordinates.add(fromRowPositionCoordinate); |
| } |
| } |
| |
| RowPositionCoordinate targetToRowPositionCoordinate = |
| LayerCommandUtil.convertRowPositionToTargetContext(this.toRowPositionCoordinate, targetLayer); |
| |
| if (!convertedFromRowPositionCoordinates.isEmpty() |
| && targetToRowPositionCoordinate != null) { |
| this.fromRowPositionCoordinates = convertedFromRowPositionCoordinates; |
| this.toRowPositionCoordinate = targetToRowPositionCoordinate; |
| return true; |
| } else { |
| return false; |
| } |
| } |
| |
| @Override |
| public MultiRowReorderCommand cloneCommand() { |
| return new MultiRowReorderCommand(this); |
| } |
| |
| } |