blob: 330909277dd73799bc492f9b87ba631c90255c54 [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
******************************************************************************/
package org.eclipse.nebula.widgets.nattable.columnCategories;
import static org.eclipse.nebula.widgets.nattable.columnChooser.ColumnChooserUtils.getHiddenColumnEntries;
import static org.eclipse.nebula.widgets.nattable.columnChooser.ColumnChooserUtils.getVisibleColumnsEntries;
import static org.eclipse.nebula.widgets.nattable.util.ObjectUtils.isNotNull;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.nebula.widgets.nattable.columnCategories.gui.ColumnCategoriesDialog;
import org.eclipse.nebula.widgets.nattable.columnChooser.ColumnChooserUtils;
import org.eclipse.nebula.widgets.nattable.command.AbstractLayerCommandHandler;
import org.eclipse.nebula.widgets.nattable.command.ILayerCommand;
import org.eclipse.nebula.widgets.nattable.coordinate.PositionUtil;
import org.eclipse.nebula.widgets.nattable.grid.layer.ColumnHeaderLayer;
import org.eclipse.nebula.widgets.nattable.hideshow.ColumnHideShowLayer;
import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
import org.eclipse.nebula.widgets.nattable.reorder.command.ColumnReorderCommand;
import org.eclipse.nebula.widgets.nattable.reorder.command.MultiColumnReorderCommand;
import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer.MoveDirectionEnum;
import org.eclipse.nebula.widgets.nattable.util.ObjectUtils;
public class ChooseColumnsFromCategoriesCommandHandler
extends AbstractLayerCommandHandler<ChooseColumnsFromCategoriesCommand>
implements IColumnCategoriesDialogListener {
private final ColumnHideShowLayer columnHideShowLayer;
private final ColumnHeaderLayer columnHeaderLayer;
private final DataLayer columnHeaderDataLayer;
private final ColumnCategoriesModel model;
private ColumnCategoriesDialog dialog;
public ChooseColumnsFromCategoriesCommandHandler(
ColumnHideShowLayer columnHideShowLayer,
ColumnHeaderLayer columnHeaderLayer,
DataLayer columnHeaderDataLayer,
ColumnCategoriesModel model) {
super();
this.columnHideShowLayer = columnHideShowLayer;
this.columnHeaderLayer = columnHeaderLayer;
this.columnHeaderDataLayer = columnHeaderDataLayer;
this.model = model;
}
@Override
protected boolean doCommand(ChooseColumnsFromCategoriesCommand command) {
this.dialog = new ColumnCategoriesDialog(
command.getShell(),
this.model,
getHiddenColumnEntries(this.columnHideShowLayer, this.columnHeaderLayer, this.columnHeaderDataLayer),
getVisibleColumnsEntries(this.columnHideShowLayer, this.columnHeaderLayer, this.columnHeaderDataLayer));
this.dialog.addListener(this);
this.dialog.open();
return true;
}
@Override
public Class<ChooseColumnsFromCategoriesCommand> getCommandClass() {
return ChooseColumnsFromCategoriesCommand.class;
}
// Listen and respond to the dialog events
@Override
public void itemsRemoved(List<Integer> removedColumnPositions) {
ColumnChooserUtils.hideColumnPositions(removedColumnPositions, this.columnHideShowLayer);
refreshDialog();
}
@Override
public void itemsSelected(List<Integer> addedColumnIndexes) {
ColumnChooserUtils.showColumnIndexes(addedColumnIndexes, this.columnHideShowLayer);
refreshDialog();
}
/**
* Moves the columns up or down by firing commands on the dialog.
*
* Individual columns are moved using the {@link ColumnReorderCommand}
* Contiguously selected columns are moved using the
* {@link MultiColumnReorderCommand}
*
* @param direction
* the direction to move
* @param selectedPositions
* the column positions to move
*/
@Override
public void itemsMoved(MoveDirectionEnum direction, List<Integer> selectedPositions) {
List<List<Integer>> fromPositions = PositionUtil.getGroupedByContiguous(selectedPositions);
List<Integer> toPositions = getDestinationPositions(direction, fromPositions);
for (int i = 0; i < fromPositions.size(); i++) {
boolean multipleColumnsMoved = fromPositions.get(i).size() > 1;
ILayerCommand command = null;
if (!multipleColumnsMoved) {
int fromPosition = fromPositions.get(i).get(0).intValue();
int toPosition = toPositions.get(i);
command = new ColumnReorderCommand(this.columnHideShowLayer, fromPosition, toPosition);
} else if (multipleColumnsMoved) {
command = new MultiColumnReorderCommand(this.columnHideShowLayer, fromPositions.get(i), toPositions.get(i));
}
this.columnHideShowLayer.doCommand(command);
}
refreshDialog();
}
/**
* Calculates the destination positions taking into account the move
* direction and single/contiguous selection.
*
* @param direction
* the direction to move
* @param selectedPositions
* grouped together if they are contiguous.
* <p>
* Example: if 2,3,4, 9, 12 are selected, they are grouped as
* [[2, 3, 4], 9, 12]
* <ul>
* <li>While moving up the destination position for [2, 3, 4] is
* 1</li>
* <li>While moving up the destination position for [2, 3, 4] is
* 6</li>
* </ul>
* @return a List of destination positions
*/
protected List<Integer> getDestinationPositions(MoveDirectionEnum direction, List<List<Integer>> selectedPositions) {
List<Integer> destinationPositions = new ArrayList<>();
for (List<Integer> contiguousPositions : selectedPositions) {
switch (direction) {
case UP:
destinationPositions.add(ObjectUtils.getFirstElement(contiguousPositions) - 1);
break;
case DOWN:
destinationPositions.add(ObjectUtils.getLastElement(contiguousPositions) + 2);
break;
default:
break;
}
}
return destinationPositions;
}
private void refreshDialog() {
if (isNotNull(this.dialog)) {
this.dialog.refresh(
ColumnChooserUtils.getHiddenColumnEntries(
this.columnHideShowLayer, this.columnHeaderLayer, this.columnHeaderDataLayer),
ColumnChooserUtils.getVisibleColumnsEntries(
this.columnHideShowLayer, this.columnHeaderLayer, this.columnHeaderDataLayer));
}
}
}