donderdag 26 maart 2009

Perspective lifecycle

Some actions need to appear in every view, like a help button that will open a page on an online help system like a Wiki.
You can add that action programmatically by intercepting perspective lifecyle events using a PerspectiveAdapter.

Set up a help listener in ApplicationWorkbenchWindowAdvisor.postWindowOpen():
public void postWindowOpen() {
// setup perspective change listener
HelpManager.setUpHelpListener();
}

In the HelpManager class you add the listener:
public static void setUpHelpListener() {
Display display = Display.getDefault();
if (null != display) {
display.asyncExec(new Runnable() {
public void run() {
scanAllViews();
final IWorkbench workbench = PlatformUI.getWorkbench();
// listen for changes that may occur
workbench.getActiveWorkbenchWindow().
addPerspectiveListener(new PerspectiveAdapter() {

@Override
public void perspectiveChanged(IWorkbenchPage page,
IPerspectiveDescriptor perspective,
IWorkbenchPartReference partRef, String changeId) {

if ((partRef instanceof IViewReference)
&& (changeId == IWorkbenchPage.CHANGE_VIEW_SHOW)) {
IViewReference viewRef = (IViewReference) partRef;
String id = viewRef.getId();
addhelpAction(workbench, id);
}

if (changeId == IWorkbenchPage.CHANGE_RESET_COMPLETE) {
scanAllViews();
}
}

@Override
public void perspectiveOpened(IWorkbenchPage page,
IPerspectiveDescriptor perspective) {
scanAllViews();
}

@Override
public void perspectiveActivated(IWorkbenchPage page,
IPerspectiveDescriptor perspective) {
scanAllViews();
}
});
// System.out.println("PerspectiveChangeListener installed");
}


});
} else {
// TODO error handling
// System.out.println("PerspectiveChangeListener installation failed");
}
}

And in scanAllViews you scan the registered views:
private void IWorkbench scanAllViews() {
final IWorkbench workbench = PlatformUI.getWorkbench();
// add to all existing views
IViewDescriptor[] views = workbench.getViewRegistry().getViews();
for (IViewDescriptor view : views) {
String id = view.getId();
addhelpAction(workbench, id);
}
}

Setting up the help actions can be done like this:
private static void addhelpAction(final IWorkbench workbench, String id) {
IWorkbenchWindow activeWorkbenchWindow = workbench.getActiveWorkbenchWindow();
if(null == activeWorkbenchWindow)
return;
IWorkbenchPage activePage = activeWorkbenchWindow.getActivePage();
if(null == activePage)
return;
IViewPart viewPart = activePage.findView(id);
if (null == viewPart)
return;
IToolBarManager toolBarManager = viewPart.getViewSite().
getActionBars().getToolBarManager();
IAction action = ViewHelpUrlAction.createInstance(viewPart);
if (null == toolBarManager.find(ViewHelpUrlAction.ID)) {
// System.out.println("ADDING TB: " + id);
if (null == toolBarManager.find(IWorkbenchActionConstants.MB_ADDITIONS)) {
toolBarManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
}
toolBarManager.appendToGroup(IWorkbenchActionConstants.MB_ADDITIONS, action);
toolBarManager.update(true);
}
IMenuManager menuManager = viewPart.getViewSite().getActionBars().getMenuManager();
if (null == menuManager.find(ViewHelpUrlAction.ID)) {
// System.out.println("ADDING MB: " + id);
if (null == menuManager.find(IWorkbenchActionConstants.MB_ADDITIONS)) {
menuManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
}
menuManager.appendToGroup(IWorkbenchActionConstants.MB_ADDITIONS, action);
menuManager.update(true);
}
}

That's it! Your action can then take the desired action, like opening a page on a Wiki with the view name as key.