org.eclipse.ui.internal.CycleBaseHandler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of workbench Show documentation
Show all versions of workbench Show documentation
This plug-in contains the bulk of the Workbench implementation, and depends on JFace, SWT, and Core Runtime. It cannot be used independently from org.eclipse.ui. Workbench client plug-ins should not depend directly on this plug-in.
The newest version!
/*******************************************************************************
* Copyright (c) 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
******************************************************************************/
package org.eclipse.ui.internal;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.ParameterizedCommand;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExecutableExtension;
import org.eclipse.jface.bindings.Trigger;
import org.eclipse.jface.bindings.TriggerSequence;
import org.eclipse.jface.bindings.keys.KeyStroke;
import org.eclipse.jface.bindings.keys.SWTKeySupport;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IPerspectiveDescriptor;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.contexts.IContextService;
import org.eclipse.ui.handlers.HandlerUtil;
import org.eclipse.ui.keys.IBindingService;
/**
* Its a base class for switching between views/editors/perspectives.
*
* @since 3.3
*
*/
public abstract class CycleBaseHandler extends AbstractHandler implements
IExecutableExtension {
private Object selection;
protected IWorkbenchWindow window;
// true to go to next and false to go to previous part
protected boolean gotoDirection;
protected IWorkbenchPart activePart;
/**
* The list of key bindings for the backward command when it is open. This
* value is null
if the dialog is not open.
*/
private TriggerSequence[] backwardTriggerSequences = null;
protected ParameterizedCommand commandBackward = null;
protected ParameterizedCommand commandForward = null;
/**
* The list of key bindings for the forward command when it is open. This
* value is null
if the dialog is not open.
*/
private TriggerSequence[] forwardTriggerSequences = null;
/*
* (non-Javadoc)
*
* @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands.ExecutionEvent)
*/
/**
* Add all items to the dialog in the activation order
*/
protected abstract void addItems(Table table, WorkbenchPage page);
/**
* Get the backward command.
*/
protected abstract ParameterizedCommand getBackwardCommand();
/**
* Get the forward command.
*/
protected abstract ParameterizedCommand getForwardCommand();
public Object execute(ExecutionEvent event) throws ExecutionException {
window = HandlerUtil.getActiveWorkbenchWindowChecked(event);
IWorkbenchPage page = window.getActivePage();
activePart = page.getActivePart();
openDialog((WorkbenchPage) page);
activate(page, selection);
return null;
}
/*
* Open a dialog showing all views in the activation order
*/
protected void openDialog(WorkbenchPage page) {
final int MAX_ITEMS = 22;
selection = null;
final Shell dialog = new Shell(window.getShell(), SWT.MODELESS);
Display display = dialog.getDisplay();
dialog.setLayout(new FillLayout());
final Table table = new Table(dialog, SWT.SINGLE | SWT.FULL_SELECTION);
table.setHeaderVisible(true);
table.setLinesVisible(true);
TableColumn tc = new TableColumn(table, SWT.NONE);
tc.setResizable(false);
tc.setText(getTableHeader());
addItems(table, page);
int tableItemCount = table.getItemCount();
switch (tableItemCount) {
case 0:
// do nothing;
break;
case 1:
table.setSelection(0);
break;
default:
table.setSelection(gotoDirection ? 1 : table.getItemCount() - 1);
}
tc.pack();
table.pack();
dialog.pack();
Rectangle tableBounds = table.getBounds();
tableBounds.height = Math.min(tableBounds.height, table.getItemHeight()
* MAX_ITEMS);
table.setBounds(tableBounds);
dialog.setBounds(dialog.computeTrim(tableBounds.x, tableBounds.y,
tableBounds.width, tableBounds.height));
tc.setWidth(table.getClientArea().width);
table.setFocus();
table.addFocusListener(new FocusListener() {
public void focusGained(FocusEvent e) {
// Do nothing
}
public void focusLost(FocusEvent e) {
cancel(dialog);
}
});
Rectangle dialogBounds = dialog.getBounds();
Rectangle parentBounds = dialog.getParent().getBounds();
// the bounds of the monitor that contains the currently active part.
Rectangle monitorBounds = activePart == null ? display
.getPrimaryMonitor().getBounds() : ((PartSite) activePart
.getSite()).getPane().getControl().getMonitor().getBounds();
// Place it in the center of its parent;
dialogBounds.x = parentBounds.x
+ ((parentBounds.width - dialogBounds.width) / 2);
dialogBounds.y = parentBounds.y
+ ((parentBounds.height - dialogBounds.height) / 2);
if (!monitorBounds.contains(dialogBounds.x, dialogBounds.y)
|| !monitorBounds.contains(dialogBounds.x + dialogBounds.width,
dialogBounds.y + dialogBounds.height)) {
// Place it in the center of the monitor if it is not visible
// when placed in the center of its parent;
dialogBounds.x = monitorBounds.x
+ (monitorBounds.width - dialogBounds.width) / 2;
dialogBounds.y = monitorBounds.y
+ (monitorBounds.height - dialogBounds.height) / 2;
}
dialog.setLocation(dialogBounds.x, dialogBounds.y);
/*
* Fetch the key bindings for the forward and backward commands. They
* will not change while the dialog is open, but the context will. Bug
* 55581.
*/
commandForward = getForwardCommand();
commandBackward = getBackwardCommand();
/*
* Fetch the key bindings for the forward and backward commands. They
* will not change while the dialog is open, but the context will. Bug
* 55581.
*/
final IBindingService bindingService = (IBindingService) window
.getWorkbench().getService(IBindingService.class);
forwardTriggerSequences = bindingService
.getActiveBindingsFor(commandForward);
backwardTriggerSequences = bindingService
.getActiveBindingsFor(commandBackward);
final IContextService contextService = (IContextService) window
.getWorkbench().getService(IContextService.class);
try {
dialog.open();
addMouseListener(table, dialog);
contextService.registerShell(dialog, IContextService.TYPE_NONE);
addKeyListener(table, dialog);
addTraverseListener(table);
while (!dialog.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
} finally {
if (!dialog.isDisposed()) {
cancel(dialog);
}
contextService.unregisterShell(dialog);
forwardTriggerSequences = null;
backwardTriggerSequences = null;
}
}
protected void addKeyListener(final Table table, final Shell dialog) {
table.addKeyListener(new KeyListener() {
private boolean firstKey = true;
private boolean quickReleaseMode = false;
public void keyPressed(KeyEvent e) {
int keyCode = e.keyCode;
char character = e.character;
int accelerator = SWTKeySupport
.convertEventToUnmodifiedAccelerator(e);
KeyStroke keyStroke = SWTKeySupport
.convertAcceleratorToKeyStroke(accelerator);
boolean acceleratorForward = false;
boolean acceleratorBackward = false;
if (commandForward != null) {
if (forwardTriggerSequences != null) {
final int forwardCount = forwardTriggerSequences.length;
for (int i = 0; i < forwardCount; i++) {
final TriggerSequence triggerSequence = forwardTriggerSequences[i];
// Compare the last key stroke of the binding.
final Trigger[] triggers = triggerSequence
.getTriggers();
final int triggersLength = triggers.length;
if ((triggersLength > 0)
&& (triggers[triggersLength - 1]
.equals(keyStroke))) {
acceleratorForward = true;
break;
}
}
}
}
if (commandBackward != null) {
if (backwardTriggerSequences != null) {
final int backwardCount = backwardTriggerSequences.length;
for (int i = 0; i < backwardCount; i++) {
final TriggerSequence triggerSequence = backwardTriggerSequences[i];
// Compare the last key stroke of the binding.
final Trigger[] triggers = triggerSequence
.getTriggers();
final int triggersLength = triggers.length;
if ((triggersLength > 0)
&& (triggers[triggersLength - 1]
.equals(keyStroke))) {
acceleratorBackward = true;
break;
}
}
}
}
if (character == SWT.CR || character == SWT.LF) {
ok(dialog, table);
} else if (acceleratorForward) {
if (firstKey && e.stateMask != 0) {
quickReleaseMode = true;
}
int index = table.getSelectionIndex();
table.setSelection((index + 1) % table.getItemCount());
} else if (acceleratorBackward) {
if (firstKey && e.stateMask != 0) {
quickReleaseMode = true;
}
int index = table.getSelectionIndex();
table.setSelection(index >= 1 ? index - 1 : table
.getItemCount() - 1);
} else if (keyCode != SWT.ALT && keyCode != SWT.COMMAND
&& keyCode != SWT.CTRL && keyCode != SWT.SHIFT
&& keyCode != SWT.ARROW_DOWN && keyCode != SWT.ARROW_UP
&& keyCode != SWT.ARROW_LEFT
&& keyCode != SWT.ARROW_RIGHT) {
cancel(dialog);
}
firstKey = false;
}
public void keyReleased(KeyEvent e) {
int keyCode = e.keyCode;
int stateMask = e.stateMask;
final IPreferenceStore store = WorkbenchPlugin.getDefault()
.getPreferenceStore();
final boolean stickyCycle = store
.getBoolean(IPreferenceConstants.STICKY_CYCLE);
if ((!stickyCycle && (firstKey || quickReleaseMode))
&& keyCode == stateMask) {
ok(dialog, table);
}
}
});
}
/**
* Adds a listener to the given table that blocks all traversal operations.
*
* @param table
* The table to which the traversal suppression should be added;
* must not be null
.
*/
protected final void addTraverseListener(final Table table) {
table.addTraverseListener(new TraverseListener() {
/**
* Blocks all key traversal events.
*
* @param event
* The trigger event; must not be null
.
*/
public final void keyTraversed(final TraverseEvent event) {
event.doit = false;
}
});
}
/**
* Activate the selected item.
*
* @param page
* the page
* @param selectedItem
* the selected item
*/
protected void activate(IWorkbenchPage page, Object selectedItem) {
if (selectedItem != null) {
if (selectedItem instanceof IEditorReference) {
page.setEditorAreaVisible(true);
}
if (selectedItem instanceof IWorkbenchPartReference) {
IWorkbenchPart part = ((IWorkbenchPartReference) selectedItem)
.getPart(true);
if (part != null) {
page.activate(part);
}
}
if (selectedItem instanceof IPerspectiveDescriptor){
IPerspectiveDescriptor persp = (IPerspectiveDescriptor) selectedItem;
page.setPerspective(persp);
}
}
}
/*
* Close the dialog and set selection to null.
*/
protected void cancel(Shell dialog) {
selection = null;
dialog.close();
}
/*
* Close the dialog saving the selection
*/
protected void ok(Shell dialog, final Table table) {
TableItem[] items = table.getSelection();
if (items != null && items.length == 1) {
selection = items[0].getData();
}
dialog.close();
}
/*
* Add mouse listener to the table closing it when the mouse is pressed.
*/
protected void addMouseListener(final Table table, final Shell dialog) {
table.addMouseListener(new MouseListener() {
public void mouseDoubleClick(MouseEvent e) {
ok(dialog, table);
}
public void mouseDown(MouseEvent e) {
ok(dialog, table);
}
public void mouseUp(MouseEvent e) {
ok(dialog, table);
}
});
}
protected abstract String getTableHeader();
// return WorkbenchMessages.CyclePartAction_header;
public Object getSelection() {
return selection;
}
public IWorkbenchWindow getWindow() {
return window;
}
public TriggerSequence[] getBackwardTriggerSequences() {
return backwardTriggerSequences;
}
public TriggerSequence[] getForwardTriggerSequences() {
return forwardTriggerSequences;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.runtime.IExecutableExtension#setInitializationData(org.eclipse.core.runtime.IConfigurationElement,
* java.lang.String, java.lang.Object)
*/
public void setInitializationData(IConfigurationElement config,
String propertyName, Object data) throws CoreException {
gotoDirection = "true".equals(data); //$NON-NLS-1$
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy