-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Impl #106 - [Fill Handle] Add double click action
- Loading branch information
Showing
8 changed files
with
455 additions
and
111 deletions.
There are no files selected for viewing
142 changes: 142 additions & 0 deletions
142
...ore/src/org/eclipse/nebula/widgets/nattable/fillhandle/action/FillHandleActionHelper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2024 Dirk Fauth. | ||
* | ||
* 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 <[email protected]> - initial API and implementation | ||
******************************************************************************/ | ||
package org.eclipse.nebula.widgets.nattable.fillhandle.action; | ||
|
||
import java.util.Date; | ||
import java.util.function.Consumer; | ||
import java.util.function.Supplier; | ||
|
||
import org.eclipse.nebula.widgets.nattable.Messages; | ||
import org.eclipse.nebula.widgets.nattable.NatTable; | ||
import org.eclipse.nebula.widgets.nattable.copy.InternalCellClipboard; | ||
import org.eclipse.nebula.widgets.nattable.fillhandle.command.FillHandlePasteCommand; | ||
import org.eclipse.nebula.widgets.nattable.fillhandle.command.FillHandlePasteCommand.FillHandleOperation; | ||
import org.eclipse.nebula.widgets.nattable.layer.cell.ILayerCell; | ||
import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer.MoveDirectionEnum; | ||
import org.eclipse.swt.SWT; | ||
import org.eclipse.swt.events.MenuAdapter; | ||
import org.eclipse.swt.events.MenuEvent; | ||
import org.eclipse.swt.events.SelectionAdapter; | ||
import org.eclipse.swt.events.SelectionEvent; | ||
import org.eclipse.swt.widgets.Display; | ||
import org.eclipse.swt.widgets.Menu; | ||
import org.eclipse.swt.widgets.MenuItem; | ||
|
||
/** | ||
* Helper class for the fill handle actions. | ||
* | ||
* @since 2.5 | ||
*/ | ||
public final class FillHandleActionHelper { | ||
|
||
private FillHandleActionHelper() { | ||
// private default constructor for helper class | ||
} | ||
|
||
/** | ||
* Check if the menu should be shown for selecting copy or series fill | ||
* operation. | ||
* | ||
* @param natTable | ||
* The NatTable instance on which the operation is performed. | ||
* @param clipboard | ||
* The internal clipboard that carries the cells for the copy | ||
* & paste operation triggered by using the fill handle. | ||
* @return <code>true</code> if the menu should be shown, <code>false</code> | ||
* if not. | ||
*/ | ||
public static boolean showMenu(NatTable natTable, InternalCellClipboard clipboard) { | ||
if (clipboard == null || clipboard.getCopiedCells() == null) { | ||
return false; | ||
} | ||
|
||
Class<?> type = null; | ||
for (ILayerCell[] cells : clipboard.getCopiedCells()) { | ||
for (ILayerCell cell : cells) { | ||
if (cell.getDataValue() == null) { | ||
return false; | ||
} else { | ||
if (type == null) { | ||
type = cell.getDataValue().getClass(); | ||
if (!Number.class.isAssignableFrom(type) | ||
&& !Date.class.isAssignableFrom(type)) { | ||
return false; | ||
} | ||
} else if (type != cell.getDataValue().getClass()) { | ||
return false; | ||
} | ||
} | ||
} | ||
} | ||
return true; | ||
} | ||
|
||
/** | ||
* Create the menu that should be opened on a fill operation. | ||
* | ||
* @param natTable | ||
* The NatTable instance on which the operation is performed and | ||
* the menu should be connected to. | ||
* @param directionProvider | ||
* The {@link Supplier} that provides the The direction in which | ||
* the fill handle was dragged. | ||
* @param resetRunnable | ||
* The {@link Runnable} that should be executed when the menu is | ||
* hidden. | ||
* @return The menu that should be opened on a fill operation. | ||
*/ | ||
public static Menu createFillHandleMenu(NatTable natTable, Supplier<MoveDirectionEnum> directionProvider, Consumer<NatTable> resetRunnable) { | ||
Menu menu = new Menu(natTable); | ||
MenuItem copyItem = new MenuItem(menu, SWT.PUSH); | ||
copyItem.setText(Messages.getLocalizedMessage("%FillHandleDragMode.menu.item.copy")); //$NON-NLS-1$ | ||
copyItem.addSelectionListener(new SelectionAdapter() { | ||
@Override | ||
public void widgetSelected(SelectionEvent e) { | ||
natTable.doCommand( | ||
new FillHandlePasteCommand( | ||
FillHandleOperation.COPY, | ||
directionProvider.get(), | ||
natTable.getConfigRegistry())); | ||
} | ||
}); | ||
MenuItem seriesItem = new MenuItem(menu, SWT.PUSH); | ||
seriesItem.setText(Messages.getLocalizedMessage("%FillHandleDragMode.menu.item.series")); //$NON-NLS-1$ | ||
seriesItem.addSelectionListener(new SelectionAdapter() { | ||
@Override | ||
public void widgetSelected(SelectionEvent e) { | ||
natTable.doCommand( | ||
new FillHandlePasteCommand( | ||
FillHandleOperation.SERIES, | ||
directionProvider.get(), | ||
natTable.getConfigRegistry())); | ||
} | ||
}); | ||
|
||
// add a menu listener to reset the fill state when the menu is | ||
// closed | ||
menu.addMenuListener(new MenuAdapter() { | ||
@Override | ||
public void menuHidden(MenuEvent e) { | ||
// perform the reset operation asynchronously because on | ||
// several OS the hide event is processed BEFORE the | ||
// selection event | ||
Display.getDefault().asyncExec(() -> resetRunnable.accept(natTable)); | ||
} | ||
}); | ||
|
||
// add the dispose listener for disposing the menu | ||
natTable.addDisposeListener(e -> menu.dispose()); | ||
|
||
return menu; | ||
} | ||
} |
148 changes: 148 additions & 0 deletions
148
...ore/src/org/eclipse/nebula/widgets/nattable/fillhandle/action/FillHandleColumnAction.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2024 Dirk Fauth. | ||
* | ||
* 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 <[email protected]> - initial API and implementation | ||
******************************************************************************/ | ||
package org.eclipse.nebula.widgets.nattable.fillhandle.action; | ||
|
||
import org.eclipse.nebula.widgets.nattable.NatTable; | ||
import org.eclipse.nebula.widgets.nattable.copy.InternalCellClipboard; | ||
import org.eclipse.nebula.widgets.nattable.copy.command.CopyDataToClipboardCommand; | ||
import org.eclipse.nebula.widgets.nattable.fillhandle.command.FillHandlePasteCommand; | ||
import org.eclipse.nebula.widgets.nattable.fillhandle.command.FillHandlePasteCommand.FillHandleOperation; | ||
import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer; | ||
import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer.MoveDirectionEnum; | ||
import org.eclipse.nebula.widgets.nattable.ui.action.IMouseAction; | ||
import org.eclipse.swt.events.MouseEvent; | ||
import org.eclipse.swt.graphics.Rectangle; | ||
import org.eclipse.swt.widgets.Menu; | ||
|
||
/** | ||
* {@link IMouseAction} that can be registered on double clicks on the fill | ||
* handle to trigger an automatic fill operation for the whole column. | ||
* | ||
* @since 2.5 | ||
*/ | ||
public class FillHandleColumnAction implements IMouseAction { | ||
|
||
protected SelectionLayer selectionLayer; | ||
protected InternalCellClipboard clipboard; | ||
|
||
protected Menu menu; | ||
|
||
/** | ||
* | ||
* @param selectionLayer | ||
* The {@link SelectionLayer} needed to determine the fill handle | ||
* region and perform the update command. | ||
* @param clipboard | ||
* The internal clipboard that carries the cells for the copy | ||
* & paste operation triggered by using the fill handle. | ||
*/ | ||
public FillHandleColumnAction(SelectionLayer selectionLayer, InternalCellClipboard clipboard) { | ||
if (selectionLayer == null) { | ||
throw new IllegalArgumentException("SelectionLayer can not be null"); //$NON-NLS-1$ | ||
} | ||
this.selectionLayer = selectionLayer; | ||
this.clipboard = clipboard; | ||
} | ||
|
||
@Override | ||
public void run(NatTable natTable, MouseEvent event) { | ||
if (this.selectionLayer.hasColumnSelection()) { | ||
|
||
if (natTable.doCommand( | ||
new CopyDataToClipboardCommand( | ||
"\t", //$NON-NLS-1$ | ||
System.getProperty("line.separator"), //$NON-NLS-1$ | ||
natTable.getConfigRegistry()))) { | ||
|
||
// set the fill handle region to be the whole column | ||
int startRow = this.selectionLayer.getSelectedRowPositions().iterator().next().start; | ||
Rectangle region = new Rectangle( | ||
this.selectionLayer.getSelectedColumnPositions()[0], | ||
startRow, | ||
this.selectionLayer.getSelectedColumnPositions().length, | ||
this.selectionLayer.getRowCount() - startRow); | ||
this.selectionLayer.setFillHandleRegion(region); | ||
|
||
if (this.clipboard != null) { | ||
if (showMenu(natTable)) { | ||
openMenu(natTable); | ||
} else { | ||
natTable.doCommand( | ||
new FillHandlePasteCommand( | ||
FillHandleOperation.COPY, | ||
MoveDirectionEnum.DOWN, | ||
natTable.getConfigRegistry())); | ||
reset(natTable); | ||
} | ||
} else { | ||
natTable.doCommand( | ||
new FillHandlePasteCommand( | ||
FillHandleOperation.COPY, | ||
MoveDirectionEnum.DOWN, | ||
natTable.getConfigRegistry())); | ||
reset(natTable); | ||
} | ||
} else { | ||
reset(natTable); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Check if the menu should be shown for selecting copy or series fill | ||
* operation. | ||
* | ||
* @param natTable | ||
* The NatTable instance on which the operation is performed. | ||
* @return <code>true</code> if the menu should be shown, <code>false</code> | ||
* if not. | ||
*/ | ||
protected boolean showMenu(final NatTable natTable) { | ||
return FillHandleActionHelper.showMenu(natTable, this.clipboard); | ||
} | ||
|
||
/** | ||
* Opens a menu that enables a user to select whether values should simply | ||
* be copied or if a series should be filled. | ||
* | ||
* @param natTable | ||
* The NatTable instance on which the operation is performed. | ||
*/ | ||
protected void openMenu(final NatTable natTable) { | ||
// lazily create the menu | ||
if (this.menu == null || this.menu.isDisposed()) { | ||
this.menu = FillHandleActionHelper.createFillHandleMenu( | ||
natTable, | ||
() -> MoveDirectionEnum.DOWN, | ||
(n) -> reset(n)); | ||
} | ||
|
||
this.menu.setVisible(true); | ||
} | ||
|
||
/** | ||
* Reset the fill handle region in the {@link SelectionLayer}, clear the | ||
* clipboard and redraw the given NatTable. | ||
* | ||
* @param natTable | ||
* The NatTable instance on which the operation is performed. | ||
*/ | ||
protected void reset(NatTable natTable) { | ||
this.selectionLayer.setFillHandleRegion(null); | ||
this.clipboard.clear(); | ||
if (!natTable.isDisposed()) { | ||
natTable.redraw(); | ||
} | ||
} | ||
|
||
} |
Oops, something went wrong.