blob: c86fc9b4717357e5ab737c0f793d4154a2f7137d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010, 2014 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
* Sopot Cela <sopotcela@gmail.com> - Bug 391961
******************************************************************************/
package org.eclipse.e4.ui.workbench.addons.perspectiveswitcher;
import java.io.IOException;
import java.net.URL;
import java.util.Collections;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.NotEnabledException;
import org.eclipse.core.commands.NotHandledException;
import org.eclipse.core.commands.ParameterizedCommand;
import org.eclipse.core.commands.common.NotDefinedException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.e4.core.commands.ECommandService;
import org.eclipse.e4.core.commands.EHandlerService;
import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.e4.core.services.log.Logger;
import org.eclipse.e4.ui.di.UIEventTopic;
import org.eclipse.e4.ui.model.application.ui.MElementContainer;
import org.eclipse.e4.ui.model.application.ui.MUIElement;
import org.eclipse.e4.ui.model.application.ui.SideValue;
import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective;
import org.eclipse.e4.ui.model.application.ui.advanced.MPerspectiveStack;
import org.eclipse.e4.ui.model.application.ui.basic.MTrimBar;
import org.eclipse.e4.ui.model.application.ui.basic.MWindow;
import org.eclipse.e4.ui.model.application.ui.menu.MToolControl;
import org.eclipse.e4.ui.workbench.UIEvents;
import org.eclipse.e4.ui.workbench.modeling.EModelService;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.accessibility.AccessibleAdapter;
import org.eclipse.swt.accessibility.AccessibleEvent;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.DragDetectEvent;
import org.eclipse.swt.events.DragDetectListener;
import org.eclipse.swt.events.MenuDetectEvent;
import org.eclipse.swt.events.MenuDetectListener;
import org.eclipse.swt.events.MenuEvent;
import org.eclipse.swt.events.MenuListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.graphics.Region;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.ui.IPerspectiveDescriptor;
import org.eclipse.ui.IPerspectiveRegistry;
import org.eclipse.ui.IWorkbenchCommandConstants;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPreferenceConstants;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.internal.IPreferenceConstants;
import org.eclipse.ui.internal.IWorkbenchGraphicConstants;
import org.eclipse.ui.internal.IWorkbenchHelpContextIds;
import org.eclipse.ui.internal.WorkbenchImages;
import org.eclipse.ui.internal.WorkbenchMessages;
import org.eclipse.ui.internal.WorkbenchPage;
import org.eclipse.ui.internal.e4.compatibility.E4Util;
import org.eclipse.ui.internal.registry.PerspectiveRegistry;
import org.eclipse.ui.internal.util.PrefUtil;
import org.eclipse.ui.statushandlers.StatusManager;
import org.osgi.service.event.Event;
public class PerspectiveSwitcher {
/**
*
*/
public static final String PERSPECTIVE_SWITCHER_ID = "org.eclipse.e4.ui.PerspectiveSwitcher"; //$NON-NLS-1$
@Inject
protected IEventBroker eventBroker;
@Inject
EModelService modelService;
@Inject
private EHandlerService handlerService;
@Inject
private ECommandService commandService;
@Inject
private MWindow window;
@Inject
private Logger logger;
private MToolControl psME;
private ToolBar psTB;
private Composite comp;
private Image backgroundImage;
private Image perspectiveImage;
Color borderColor, curveColor;
Control toolParent;
IPropertyChangeListener propertyChangeListener;
@Inject
void handleChildrenEvent(
@Optional @UIEventTopic(UIEvents.ElementContainer.TOPIC_CHILDREN) Event event) {
if (event == null)
return;
if (psTB.isDisposed()) {
return;
}
Object changedObj = event.getProperty(UIEvents.EventTags.ELEMENT);
if (psME == null || !(changedObj instanceof MPerspectiveStack))
return;
MWindow perspWin = modelService.getTopLevelWindowFor((MUIElement) changedObj);
MWindow switcherWin = modelService.getTopLevelWindowFor(psME);
if (perspWin != switcherWin)
return;
if (UIEvents.isADD(event)) {
for (Object o : UIEvents.asIterable(event, UIEvents.EventTags.NEW_VALUE)) {
MPerspective added = (MPerspective) o;
// Adding invisible elements is a NO-OP
if (!added.isToBeRendered())
continue;
addPerspectiveItem(added);
}
} else if (UIEvents.isREMOVE(event)) {
for (Object o : UIEvents.asIterable(event, UIEvents.EventTags.OLD_VALUE)) {
MPerspective removed = (MPerspective) o;
// Removing invisible elements is a NO-OP
if (!removed.isToBeRendered())
continue;
removePerspectiveItem(removed);
}
}
}
@Inject
void handleToBeRenderedEvent(
@Optional @UIEventTopic(UIEvents.UIElement.TOPIC_TOBERENDERED) Event event) {
if (event == null)
return;
if (psTB.isDisposed()) {
return;
}
MUIElement changedElement = (MUIElement) event.getProperty(UIEvents.EventTags.ELEMENT);
if (psME == null || !(changedElement instanceof MPerspective))
return;
MWindow perspWin = modelService.getTopLevelWindowFor(changedElement);
MWindow switcherWin = modelService.getTopLevelWindowFor(psME);
if (perspWin != switcherWin)
return;
MPerspective persp = (MPerspective) changedElement;
if (!persp.getParent().isToBeRendered())
return;
if (changedElement.isToBeRendered()) {
addPerspectiveItem(persp);
} else {
removePerspectiveItem(persp);
}
}
@Inject
void handleLabelEvent(@Optional @UIEventTopic(UIEvents.UILabel.TOPIC_ALL) Event event) {
if (event == null)
return;
if (psTB.isDisposed()) {
return;
}
MUIElement changedElement = (MUIElement) event.getProperty(UIEvents.EventTags.ELEMENT);
if (psME == null || !(changedElement instanceof MPerspective))
return;
String attName = (String) event.getProperty(UIEvents.EventTags.ATTNAME);
Object newValue = event.getProperty(UIEvents.EventTags.NEW_VALUE);
MWindow perspWin = modelService.getTopLevelWindowFor(changedElement);
MWindow switcherWin = modelService.getTopLevelWindowFor(psME);
if (perspWin != switcherWin)
return;
MPerspective perspective = (MPerspective) changedElement;
if (!perspective.isToBeRendered())
return;
for (ToolItem ti : psTB.getItems()) {
if (ti.getData() == perspective) {
updateToolItem(ti, attName, newValue);
}
}
// update the size
fixSize();
}
@Inject
void handleSelectionEvent(
@Optional @UIEventTopic(UIEvents.ElementContainer.TOPIC_SELECTEDELEMENT) Event event) {
if (event == null)
return;
if (psTB.isDisposed()) {
return;
}
MUIElement changedElement = (MUIElement) event.getProperty(UIEvents.EventTags.ELEMENT);
if (psME == null || !(changedElement instanceof MPerspectiveStack))
return;
MWindow perspWin = modelService.getTopLevelWindowFor(changedElement);
MWindow switcherWin = modelService.getTopLevelWindowFor(psME);
if (perspWin != switcherWin)
return;
MPerspectiveStack perspStack = (MPerspectiveStack) changedElement;
if (!perspStack.isToBeRendered())
return;
MPerspective selElement = perspStack.getSelectedElement();
for (ToolItem ti : psTB.getItems()) {
ti.setSelection(ti.getData() == selElement);
}
}
@PostConstruct
void init() {
setPropertyChangeListener();
}
@PreDestroy
void cleanUp() {
if (perspectiveImage != null) {
perspectiveImage.dispose();
perspectiveImage = null;
}
PrefUtil.getAPIPreferenceStore().removePropertyChangeListener(propertyChangeListener);
}
@PostConstruct
void createWidget(Composite parent, MToolControl toolControl) {
psME = toolControl;
MUIElement meParent = psME.getParent();
int orientation = SWT.HORIZONTAL;
if (meParent instanceof MTrimBar) {
MTrimBar bar = (MTrimBar) meParent;
if (bar.getSide() == SideValue.RIGHT || bar.getSide() == SideValue.LEFT)
orientation = SWT.VERTICAL;
}
comp = new Composite(parent, SWT.NONE);
RowLayout layout = new RowLayout(SWT.HORIZONTAL);
layout.marginLeft = layout.marginRight = 8;
layout.marginBottom = 4;
layout.marginTop = 6;
comp.setLayout(layout);
psTB = new ToolBar(comp, SWT.FLAT | SWT.WRAP | SWT.RIGHT + orientation);
comp.addPaintListener(new PaintListener() {
@Override
public void paintControl(PaintEvent e) {
paint(e);
}
});
toolParent = ((Control) toolControl.getParent().getWidget());
toolParent.addPaintListener(new PaintListener() {
@Override
public void paintControl(PaintEvent e) {
if (borderColor == null || borderColor.isDisposed()) {
borderColor = e.display.getSystemColor(SWT.COLOR_BLACK);
}
e.gc.setForeground(borderColor);
Rectangle bounds = ((Control) e.widget).getBounds();
e.gc.drawLine(0, bounds.height - 1, bounds.width, bounds.height - 1);
}
});
comp.addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
dispose();
}
});
psTB.addMenuDetectListener(new MenuDetectListener() {
@Override
public void menuDetected(MenuDetectEvent e) {
ToolBar tb = (ToolBar) e.widget;
Point p = new Point(e.x, e.y);
p = psTB.getDisplay().map(null, psTB, p);
ToolItem item = tb.getItem(p);
if (item == null)
E4Util.message(" ToolBar menu"); //$NON-NLS-1$
else {
MPerspective persp = (MPerspective) item.getData();
if (persp == null)
E4Util.message(" Add button Menu"); //$NON-NLS-1$
else
openMenuFor(item, persp);
}
}
});
psTB.addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
disposeTBImages();
}
});
psTB.getAccessible().addAccessibleListener(new AccessibleAdapter() {
@Override
public void getName(AccessibleEvent e) {
if (0 <= e.childID && e.childID < psTB.getItemCount()) {
ToolItem item = psTB.getItem(e.childID);
if (item != null) {
e.result = item.getToolTipText();
}
}
}
});
hookupDnD(psTB);
final ToolItem createItem = new ToolItem(psTB, SWT.PUSH);
createItem.setImage(getOpenPerspectiveImage());
createItem.setToolTipText(WorkbenchMessages.OpenPerspectiveDialogAction_tooltip);
createItem.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
selectPerspective();
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
selectPerspective();
}
});
new ToolItem(psTB, SWT.SEPARATOR);
MPerspectiveStack stack = getPerspectiveStack();
if (stack != null) {
// Create an item for each perspective that should show up
for (MPerspective persp : stack.getChildren()) {
if (persp.isToBeRendered()) {
addPerspectiveItem(persp);
}
}
}
}
protected Point downPos = null;
protected ToolItem dragItem = null;
protected boolean dragging = false;
protected Shell dragShell = null;
private void track(MouseEvent e) {
// Create and track the feedback overlay
if (dragShell == null)
createFeedback();
// Move the drag shell
Rectangle b = dragItem.getBounds();
Point p = new Point(e.x, e.y);
p = dragShell.getDisplay().map(dragItem.getParent(), null, p);
dragShell.setLocation(p.x - (b.width / 2), p.y - (b.height / 2));
// Set the cursor feedback
ToolBar bar = (ToolBar) e.widget;
ToolItem curItem = bar.getItem(new Point(e.x, e.y));
if (curItem != null && curItem.getData() instanceof MPerspective) {
psTB.setCursor(psTB.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
} else {
psTB.setCursor(psTB.getDisplay().getSystemCursor(SWT.CURSOR_NO));
}
}
private void createFeedback() {
dragShell = new Shell(SWT.NO_TRIM | SWT.NO_BACKGROUND);
dragShell.setAlpha(175);
ToolBar dragTB = new ToolBar(dragShell, SWT.RIGHT);
ToolItem newTI = new ToolItem(dragTB, SWT.RADIO);
newTI.setText(dragItem.getText());
newTI.setImage(dragItem.getImage());
dragTB.pack();
dragShell.pack();
dragShell.setVisible(true);
}
private void hookupDnD(ToolBar bar) {
bar.addMouseListener(new MouseListener() {
@Override
public void mouseUp(MouseEvent e) {
if (dragItem == null)
return;
ToolBar bar = (ToolBar) e.widget;
ToolItem curItem = bar.getItem(new Point(e.x, e.y));
if (curItem != null && curItem.getData() instanceof MPerspective) {
Rectangle bounds = curItem.getBounds();
Point center = new Point(bounds.x + (bounds.width / 2), bounds.y
+ (bounds.height / 2));
boolean atStart = (psTB.getStyle() & SWT.HORIZONTAL) != 0 ? e.x < center.x
: e.y < center.y;
// OK, Calculate the correct drop index
MPerspective dragPersp = (MPerspective) dragItem.getData();
int dragPerspIndex = dragPersp.getParent().getChildren().indexOf(dragPersp);
MPerspective dropPersp = (MPerspective) curItem.getData();
int dropPerspIndex = dropPersp.getParent().getChildren().indexOf(dropPersp);
if (!atStart)
dropPerspIndex++; // We're 'after' the item we're over
if (dropPerspIndex > dragPerspIndex)
dropPerspIndex--; // Need to account for the removal of
// the drag item itself
// If it's not a no-op move the perspective
if (dropPerspIndex != dragPerspIndex) {
MElementContainer<MUIElement> parent = dragPersp.getParent();
boolean selected = dragPersp == parent.getSelectedElement();
parent.getChildren().remove(dragPersp);
parent.getChildren().add(dropPerspIndex, dragPersp);
if (selected)
parent.setSelectedElement(dragPersp);
}
}
// Reset to the initial state
dragItem = null;
downPos = null;
dragging = false;
psTB.setCursor(null);
if (dragShell != null && !dragShell.isDisposed())
dragShell.dispose();
dragShell = null;
}
@Override
public void mouseDown(MouseEvent e) {
ToolBar bar = (ToolBar) e.widget;
downPos = new Point(e.x, e.y);
ToolItem downItem = bar.getItem(downPos);
// We're only interested if the button went down over a
// perspective item
if (downItem != null && downItem.getData() instanceof MPerspective)
dragItem = downItem;
}
@Override
public void mouseDoubleClick(MouseEvent e) {
}
});
bar.addDragDetectListener(new DragDetectListener() {
@Override
public void dragDetected(DragDetectEvent e) {
if (dragItem != null) {
dragging = true;
track(e);
}
}
});
bar.addMouseMoveListener(new MouseMoveListener() {
@Override
public void mouseMove(MouseEvent e) {
if (dragging) {
track(e);
}
}
});
}
private Image getOpenPerspectiveImage() {
if (perspectiveImage == null || perspectiveImage.isDisposed()) {
ImageDescriptor desc = WorkbenchImages
.getImageDescriptor(IWorkbenchGraphicConstants.IMG_ETOOL_NEW_PAGE);
perspectiveImage = desc.createImage();
}
return perspectiveImage;
}
MPerspectiveStack getPerspectiveStack() {
List<MPerspectiveStack> psList = modelService.findElements(window, null,
MPerspectiveStack.class, null);
if (psList.size() > 0)
return psList.get(0);
return null;
}
private ToolItem addPerspectiveItem(MPerspective persp) {
int perspIndex = persp.getParent().getChildren().indexOf(persp);
int index = perspIndex + 2; // HACK !! accounts for the 'open' and the
// separator
final ToolItem psItem = index < psTB.getItemCount() ? new ToolItem(psTB, SWT.RADIO, index)
: new ToolItem(psTB, SWT.RADIO);
psItem.setData(persp);
IPerspectiveDescriptor descriptor = getDescriptorFor(persp.getElementId());
boolean foundImage = false;
if (descriptor != null) {
ImageDescriptor desc = descriptor.getImageDescriptor();
if (desc != null) {
final Image image = desc.createImage(false);
if (image != null) {
psItem.setImage(image);
psItem.addListener(SWT.Dispose, new Listener() {
@Override
public void handleEvent(org.eclipse.swt.widgets.Event event) {
Image currentImage = psItem.getImage();
if (currentImage != null)
currentImage.dispose();
}
});
foundImage = true;
psItem.setToolTipText(persp.getLocalizedLabel());
}
}
}
if (!foundImage
|| PrefUtil.getAPIPreferenceStore().getBoolean(
IWorkbenchPreferenceConstants.SHOW_TEXT_ON_PERSPECTIVE_BAR)) {
psItem.setText(persp.getLocalizedLabel());
psItem.setToolTipText(persp.getLocalizedTooltip());
}
psItem.setSelection(persp == persp.getParent().getSelectedElement());
psItem.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
MPerspective persp = (MPerspective) e.widget.getData();
persp.getParent().setSelectedElement(persp);
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
MPerspective persp = (MPerspective) e.widget.getData();
persp.getParent().setSelectedElement(persp);
}
});
psItem.addListener(SWT.MenuDetect, new Listener() {
@Override
public void handleEvent(org.eclipse.swt.widgets.Event event) {
MPerspective persp = (MPerspective) event.widget.getData();
openMenuFor(psItem, persp);
}
});
// update the size
fixSize();
return psItem;
}
// FIXME see https://bugs.eclipse.org/bugs/show_bug.cgi?id=313771
private IPerspectiveDescriptor getDescriptorFor(String id) {
IPerspectiveRegistry perspectiveRegistry = PlatformUI.getWorkbench()
.getPerspectiveRegistry();
if (perspectiveRegistry instanceof PerspectiveRegistry) {
return ((PerspectiveRegistry) perspectiveRegistry).findPerspectiveWithId(id, false);
}
return perspectiveRegistry.findPerspectiveWithId(id);
}
private void selectPerspective() {
// let the handler perform the work to consolidate all the code
ParameterizedCommand command = commandService.createCommand(
IWorkbenchCommandConstants.PERSPECTIVES_SHOW_PERSPECTIVE, Collections.EMPTY_MAP);
handlerService.executeHandler(command);
}
private void openMenuFor(ToolItem item, MPerspective persp) {
final Menu menu = new Menu(psTB);
menu.setData(persp);
if (persp.getParent().getSelectedElement() == persp) {
addSaveAsItem(menu);
addResetItem(menu);
}
if (persp.isVisible()) {
addCloseItem(menu);
}
new MenuItem(menu, SWT.SEPARATOR);
// addDockOnSubMenu(menu);
addShowTextItem(menu);
Rectangle bounds = item.getBounds();
Point point = psTB.toDisplay(bounds.x, bounds.y + bounds.height);
menu.setLocation(point.x, point.y);
menu.setVisible(true);
menu.addMenuListener(new MenuListener() {
@Override
public void menuHidden(MenuEvent e) {
psTB.getDisplay().asyncExec(new Runnable() {
@Override
public void run() {
menu.dispose();
}
});
}
@Override
public void menuShown(MenuEvent e) {
// Nothing to do
}
});
}
private void addCloseItem(final Menu menu) {
MenuItem menuItem = new MenuItem(menu, SWT.NONE);
menuItem.setText(WorkbenchMessages.WorkbenchWindow_close);
menuItem.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
MPerspective persp = (MPerspective) menu.getData();
if (persp != null)
closePerspective(persp);
}
});
}
private void closePerspective(MPerspective persp) {
MWindow win = modelService.getTopLevelWindowFor(persp);
WorkbenchPage page = (WorkbenchPage) win.getContext().get(IWorkbenchPage.class);
String perspectiveId = persp.getElementId();
IPerspectiveDescriptor desc = getDescriptorFor(perspectiveId);
page.closePerspective(desc, perspectiveId, true, false);
// removePerspectiveItem(persp);
}
private void addSaveAsItem(final Menu menu) {
final MenuItem saveAsMenuItem = new MenuItem(menu, SWT.Activate);
saveAsMenuItem.setText(WorkbenchMessages.PerspectiveBar_saveAs);
final IWorkbenchWindow workbenchWindow = window.getContext().get(IWorkbenchWindow.class);
workbenchWindow.getWorkbench().getHelpSystem()
.setHelp(saveAsMenuItem, IWorkbenchHelpContextIds.SAVE_PERSPECTIVE_ACTION);
saveAsMenuItem.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
if (psTB.isDisposed())
return;
IHandlerService handlerService = (IHandlerService) workbenchWindow
.getService(IHandlerService.class);
IStatus status = Status.OK_STATUS;
try {
handlerService.executeCommand(
IWorkbenchCommandConstants.WINDOW_SAVE_PERSPECTIVE_AS, null);
} catch (ExecutionException e) {
status = new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, e.getMessage(), e);
} catch (NotDefinedException e) {
status = new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, e.getMessage(), e);
} catch (NotEnabledException e) {
status = new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, e.getMessage(), e);
} catch (NotHandledException e) {
}
if (!status.isOK())
StatusManager.getManager().handle(status,
StatusManager.SHOW | StatusManager.LOG);
}
});
}
private void addResetItem(final Menu menu) {
final MenuItem resetMenuItem = new MenuItem(menu, SWT.Activate);
resetMenuItem.setText(WorkbenchMessages.PerspectiveBar_reset);
final IWorkbenchWindow workbenchWindow = window.getContext().get(IWorkbenchWindow.class);
workbenchWindow.getWorkbench().getHelpSystem()
.setHelp(resetMenuItem, IWorkbenchHelpContextIds.RESET_PERSPECTIVE_ACTION);
resetMenuItem.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
if (psTB.isDisposed())
return;
IHandlerService handlerService = (IHandlerService) workbenchWindow
.getService(IHandlerService.class);
IStatus status = Status.OK_STATUS;
try {
handlerService.executeCommand(
IWorkbenchCommandConstants.WINDOW_RESET_PERSPECTIVE, null);
} catch (ExecutionException e) {
status = new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, e.getMessage(), e);
} catch (NotDefinedException e) {
status = new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, e.getMessage(), e);
} catch (NotEnabledException e) {
status = new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, e.getMessage(), e);
} catch (NotHandledException e) {
}
if (!status.isOK())
StatusManager.getManager().handle(status,
StatusManager.SHOW | StatusManager.LOG);
}
});
}
private void addShowTextItem(final Menu menu) {
final MenuItem showtextMenuItem = new MenuItem(menu, SWT.CHECK);
showtextMenuItem.setText(WorkbenchMessages.PerspectiveBar_showText);
showtextMenuItem.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
boolean preference = showtextMenuItem.getSelection();
if (preference != PrefUtil.getAPIPreferenceStore().getDefaultBoolean(
IWorkbenchPreferenceConstants.SHOW_TEXT_ON_PERSPECTIVE_BAR)) {
PrefUtil.getInternalPreferenceStore().setValue(
IPreferenceConstants.OVERRIDE_PRESENTATION, true);
}
PrefUtil.getAPIPreferenceStore().setValue(
IWorkbenchPreferenceConstants.SHOW_TEXT_ON_PERSPECTIVE_BAR, preference);
changeShowText(preference);
}
});
showtextMenuItem.setSelection(PrefUtil.getAPIPreferenceStore().getBoolean(
IWorkbenchPreferenceConstants.SHOW_TEXT_ON_PERSPECTIVE_BAR));
}
private void setPropertyChangeListener() {
propertyChangeListener = new IPropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent propertyChangeEvent) {
if (IWorkbenchPreferenceConstants.SHOW_TEXT_ON_PERSPECTIVE_BAR
.equals(propertyChangeEvent.getProperty())) {
Object newValue = propertyChangeEvent.getNewValue();
boolean showText = true; // default
if (newValue instanceof Boolean)
showText = ((Boolean) newValue).booleanValue();
else if ("false".equals(newValue)) //$NON-NLS-1$
showText = false;
changeShowText(showText);
}
}
};
PrefUtil.getAPIPreferenceStore().addPropertyChangeListener(propertyChangeListener);
}
private void changeShowText(boolean showText) {
ToolItem[] items = psTB.getItems();
for (int i = 0; i < items.length; i++) {
MPerspective persp = (MPerspective) items[i].getData();
if (persp != null)
if (showText) {
if (persp.getLabel() != null)
items[i].setText(persp.getLocalizedLabel());
items[i].setToolTipText(persp.getLocalizedTooltip());
} else {
Image image = items[i].getImage();
if (image != null) {
items[i].setText(""); //$NON-NLS-1$
items[i].setToolTipText(persp.getLocalizedLabel());
}
}
}
// update the size
fixSize();
}
private void fixSize() {
psTB.pack();
psTB.getParent().pack();
psTB.getShell().layout(new Control[] { psTB }, SWT.DEFER);
}
private void removePerspectiveItem(MPerspective toRemove) {
ToolItem psItem = getItemFor(toRemove);
if (psItem != null) {
psItem.dispose();
}
// update the size
fixSize();
}
protected ToolItem getItemFor(MPerspective persp) {
if (psTB == null)
return null;
for (ToolItem ti : psTB.getItems()) {
if (ti.getData() == persp)
return ti;
}
return null;
}
void paint(PaintEvent e) {
GC gc = e.gc;
Point size = comp.getSize();
if (curveColor == null || curveColor.isDisposed()) {
curveColor = e.display.getSystemColor(SWT.COLOR_BLACK);
}
int h = size.y;
int[] simpleCurve = new int[] { 0, h - 1, 1, h - 1, 2, h - 2, 2, 1, 3, 0 };
// draw border
gc.setForeground(curveColor);
gc.setAdvanced(true);
if (gc.getAdvanced()) {
gc.setAntialias(SWT.ON);
}
gc.drawPolyline(simpleCurve);
Rectangle bounds = ((Control) e.widget).getBounds();
bounds.x = bounds.y = 0;
Region r = new Region();
r.add(bounds);
int[] simpleCurveClose = new int[simpleCurve.length + 4];
System.arraycopy(simpleCurve, 0, simpleCurveClose, 0, simpleCurve.length);
int index = simpleCurve.length;
simpleCurveClose[index++] = bounds.width;
simpleCurveClose[index++] = 0;
simpleCurveClose[index++] = bounds.width;
simpleCurveClose[index++] = bounds.height;
r.subtract(simpleCurveClose);
Region clipping = new Region();
gc.getClipping(clipping);
r.intersect(clipping);
gc.setClipping(r);
Image b = toolParent.getBackgroundImage();
if (b != null && !b.isDisposed())
gc.drawImage(b, 0, 0);
r.dispose();
clipping.dispose();
// // gc.fillRectangle(bounds);
// Rectangle mappedBounds = e.display.map(comp, comp.getParent(),
// bounds);
// ((Composite) toolParent).drawBackground(gc, bounds.x, bounds.y,
// bounds.width,
// bounds.height, mappedBounds.x, mappedBounds.y);
}
void resize() {
Point size = comp.getSize();
Image oldBackgroundImage = backgroundImage;
backgroundImage = new Image(comp.getDisplay(), size.x, size.y);
GC gc = new GC(backgroundImage);
comp.getParent().drawBackground(gc, 0, 0, size.x, size.y, 0, 0);
Color background = comp.getBackground();
Color border = comp.getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
RGB backgroundRGB = background.getRGB();
// TODO naive and hard coded, doesn't deal with high contrast, etc.
Color gradientTop = new Color(comp.getDisplay(), backgroundRGB.red + 12,
backgroundRGB.green + 10, backgroundRGB.blue + 10);
int h = size.y;
int curveStart = 0;
int curve_width = 5;
int[] curve = new int[] { 0, h, 1, h, 2, h - 1, 3, h - 2, 3, 2, 4, 1, 5, 0, };
int[] line1 = new int[curve.length + 4];
int index = 0;
int x = curveStart;
line1[index++] = x + 1;
line1[index++] = h;
for (int i = 0; i < curve.length / 2; i++) {
line1[index++] = x + curve[2 * i];
line1[index++] = curve[2 * i + 1];
}
line1[index++] = x + curve_width;
line1[index++] = 0;
int[] line2 = new int[line1.length];
index = 0;
for (int i = 0; i < line1.length / 2; i++) {
line2[index] = line1[index++] - 1;
line2[index] = line1[index++];
}
// custom gradient
gc.setForeground(gradientTop);
gc.setBackground(background);
gc.drawLine(4, 0, size.x, 0);
gc.drawLine(3, 1, size.x, 1);
gc.fillGradientRectangle(2, 2, size.x - 2, size.y - 3, true);
gc.setForeground(background);
gc.drawLine(2, size.y - 1, size.x, size.y - 1);
gradientTop.dispose();
gc.setForeground(border);
gc.drawPolyline(line2);
gc.dispose();
comp.setBackgroundImage(backgroundImage);
if (oldBackgroundImage != null)
oldBackgroundImage.dispose();
}
void dispose() {
cleanUp();
if (backgroundImage != null) {
comp.setBackgroundImage(null);
backgroundImage.dispose();
backgroundImage = null;
}
}
void disposeTBImages() {
ToolItem[] items = psTB.getItems();
for (int i = 0; i < items.length; i++) {
Image image = items[i].getImage();
if (image != null) {
items[i].setImage(null);
image.dispose();
}
}
}
public void setKeylineColor(Color borderColor, Color curveColor) {
this.borderColor = borderColor;
this.curveColor = curveColor;
}
private void updateToolItem(ToolItem ti, String attName, Object newValue) {
boolean showText = PrefUtil.getAPIPreferenceStore().getBoolean(
IWorkbenchPreferenceConstants.SHOW_TEXT_ON_PERSPECTIVE_BAR);
if (showText && UIEvents.UILabel.LABEL.equals(attName)) {
String newName = (String) newValue;
ti.setText(newName);
} else if (UIEvents.UILabel.TOOLTIP.equals(attName)) {
String newTTip = (String) newValue;
ti.setToolTipText(newTTip);
} else if (UIEvents.UILabel.ICONURI.equals(attName)) {
Image currentImage = ti.getImage();
String uri = (String) newValue;
URL url = null;
try {
url = new URL(uri);
ImageDescriptor descriptor = ImageDescriptor.createFromURL(url);
if (descriptor == null) {
ti.setImage(null);
} else
ti.setImage(descriptor.createImage());
} catch (IOException e) {
ti.setImage(null);
logger.warn(e);
} finally {
if (currentImage != null)
currentImage.dispose();
}
}
}
}