/*******************************************************************************
* Copyright (c) 2007, 2014 compeople AG 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:
* compeople AG - initial API and implementation
*******************************************************************************/
package org.eclipse.riena.navigation.ui.swt.views;
import java.util.ArrayList;
import java.util.List;
import org.osgi.service.log.LogService;
import org.eclipse.core.runtime.Assert;
import org.eclipse.equinox.log.Logger;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.IContributionManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.CoolBar;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IPerspectiveDescriptor;
import org.eclipse.ui.IPerspectiveRegistry;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.WorkbenchException;
import org.eclipse.ui.application.ActionBarAdvisor;
import org.eclipse.ui.application.IActionBarConfigurer;
import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
import org.eclipse.ui.application.WorkbenchWindowAdvisor;
import org.eclipse.ui.internal.WorkbenchWindow;
import org.eclipse.riena.core.Log4r;
import org.eclipse.riena.core.wire.InjectExtension;
import org.eclipse.riena.internal.navigation.ui.swt.Activator;
import org.eclipse.riena.internal.navigation.ui.swt.CoolbarUtils;
import org.eclipse.riena.internal.navigation.ui.swt.IAdvisorHelper;
import org.eclipse.riena.internal.navigation.ui.swt.RestoreFocusOnEscListener;
import org.eclipse.riena.navigation.IApplicationNode;
import org.eclipse.riena.navigation.IModuleGroupNode;
import org.eclipse.riena.navigation.IModuleNode;
import org.eclipse.riena.navigation.INavigationNode;
import org.eclipse.riena.navigation.ISubApplicationNode;
import org.eclipse.riena.navigation.ISubModuleNode;
import org.eclipse.riena.navigation.listener.ApplicationNodeListener;
import org.eclipse.riena.navigation.listener.ModuleGroupNodeListener;
import org.eclipse.riena.navigation.listener.ModuleNodeListener;
import org.eclipse.riena.navigation.listener.NavigationTreeObserver;
import org.eclipse.riena.navigation.listener.SubApplicationNodeListener;
import org.eclipse.riena.navigation.listener.SubModuleNodeListener;
import org.eclipse.riena.navigation.model.ApplicationNode;
import org.eclipse.riena.navigation.ui.controllers.ApplicationController;
import org.eclipse.riena.navigation.ui.swt.binding.InjectSwtViewBindingDelegate;
import org.eclipse.riena.navigation.ui.swt.component.IEntriesProvider;
import org.eclipse.riena.navigation.ui.swt.component.MenuCoolBarComposite;
import org.eclipse.riena.navigation.ui.swt.component.TitleComposite;
import org.eclipse.riena.navigation.ui.swt.lnf.renderer.ShellBorderRenderer;
import org.eclipse.riena.navigation.ui.swt.lnf.renderer.ShellRenderer;
import org.eclipse.riena.navigation.ui.swt.presentation.SwtViewProvider;
import org.eclipse.riena.navigation.ui.swt.presentation.stack.TitlelessStackPresentation;
import org.eclipse.riena.navigation.ui.swt.presentation.stack.common.TitlelessStackPresentation3xRAP;
import org.eclipse.riena.navigation.ui.swt.statusline.IStatuslineContentFactoryExtension;
import org.eclipse.riena.ui.core.resource.IconSize;
import org.eclipse.riena.ui.filter.IUIFilter;
import org.eclipse.riena.ui.ridgets.swt.uibinding.AbstractViewBindingDelegate;
import org.eclipse.riena.ui.swt.DefaultStatuslineContentFactory;
import org.eclipse.riena.ui.swt.IStatusLineContentFactory;
import org.eclipse.riena.ui.swt.InfoFlyout;
import org.eclipse.riena.ui.swt.Statusline;
import org.eclipse.riena.ui.swt.StatuslineSpacer;
import org.eclipse.riena.ui.swt.facades.SWTFacade;
import org.eclipse.riena.ui.swt.lnf.LnFUpdater;
import org.eclipse.riena.ui.swt.lnf.LnfKeyConstants;
import org.eclipse.riena.ui.swt.lnf.LnfManager;
import org.eclipse.riena.ui.swt.lnf.rienadefault.RienaDefaultLnf;
import org.eclipse.riena.ui.swt.utils.ImageStore;
import org.eclipse.riena.ui.swt.utils.ShellHelper;
import org.eclipse.riena.ui.swt.utils.SwtUtilities;
import org.eclipse.riena.ui.swt.utils.TestingSupport;
import org.eclipse.riena.ui.swt.utils.UIControlsFactory;
import org.eclipse.riena.ui.swt.utils.WidgetIdentificationSupport;
import org.eclipse.riena.ui.workarea.IWorkareaDefinition;
import org.eclipse.riena.ui.workarea.WorkareaManager;
public class ApplicationViewAdvisor3xRAP extends WorkbenchWindowAdvisor {
private static final Logger LOGGER = Log4r.getLogger(Activator.getDefault(), ApplicationViewAdvisor3xRAP.class);
/**
* Binding ID
*/
private static final String INFO_FLYOUT_BINDING_ID = "infoFlyout"; //$NON-NLS-1$
/**
* System property defining the initial width of the application window.
*/
private static final String PROPERTY_RIENA_APPLICATION_WIDTH = "riena.application.width"; //$NON-NLS-1$
/**
* System property defining the initial height of the application window.
*/
private static final String PROPERTY_RIENA_APPLICATION_HEIGHT = "riena.application.height"; //$NON-NLS-1$
/**
* System property defining the minimum width of the application window.
*/
private static final String PROPERTY_RIENA_APPLICATION_MINIMUM_WIDTH = "riena.application.minimum.width"; //$NON-NLS-1$
/**
* System property defining the minimum height of the application window.
*/
private static final String PROPERTY_RIENA_APPLICATION_MINIMUM_HEIGHT = "riena.application.minimum.height"; //$NON-NLS-1$
private static final int DEFAULT_COOLBAR_TOP_MARGIN = 2;
enum BtnState {
NONE, HOVER, HOVER_SELECTED;
}
private final ApplicationController controller;
private final AbstractViewBindingDelegate binding;
private final IAdvisorHelper advisorHelper;
private TitleComposite titleComposite;
// content factory for delegation of content creation from the statusline
private IStatusLineContentFactory statuslineContentFactory;
private IWindowNavigator windowNavigator;
/**
* The application window size minimum.
*/
private Point applicationSizeMinimum;
/**
* @noreference This constructor is not intended to be referenced by clients.
*/
public ApplicationViewAdvisor3xRAP(final IWorkbenchWindowConfigurer configurer, final ApplicationController pController, final IAdvisorHelper helper) {
super(configurer);
controller = pController;
binding = createBinding();
advisorHelper = helper;
initializeListener();
}
public void addUIControl(final Composite control, final String propertyName) {
binding.addUIControl(control, propertyName);
}
/**
* @since 4.0
*/
@InjectExtension(min = 0, max = 1)
public void updateStatuslineContentFactory(final IStatuslineContentFactoryExtension statuslineContentFactoryExtension) {
this.statuslineContentFactory = statuslineContentFactoryExtension == null ? new DefaultStatuslineContentFactory() : statuslineContentFactoryExtension
.createFactory();
}
public IStatusLineContentFactory getStatuslineContentFactory() {
return statuslineContentFactory;
}
/**
* @since 4.0
*/
@InjectExtension(min = 0, max = 1)
public void updateWindowNavigator(final IWindowNavigatorExtension windowNavigatorExtension) {
this.windowNavigator = windowNavigatorExtension == null ? new DefaultWindowNavigator() : windowNavigatorExtension.createWindowNavigator();
}
private IWindowNavigator getWindowNavigator() {
return windowNavigator;
}
@Override
public final ActionBarAdvisor createActionBarAdvisor(final IActionBarConfigurer configurer) {
return advisorHelper.createActionBarAdvisor(configurer);
}
@Override
public void createWindowContents(final Shell shell) {
initShell(shell);
// create and layouts the composite of switcher, menu, tool bar etc.
shell.setLayout(new FormLayout());
final Composite grabCorner = createGrabCorner(shell);
createStatusLine(shell, grabCorner);
titleComposite = createTitleComposite(shell);
final Composite menuBarComposite = createMenuBarComposite(shell, titleComposite);
final Composite coolBarComposite = createCoolBarComposite(shell, menuBarComposite);
final Composite mainComposite = createMainComposite(shell, coolBarComposite);
createInfoFlyout(mainComposite);
final RestoreFocusOnEscListener focusListener = new RestoreFocusOnEscListener(shell);
focusListener.addControl(RestoreFocusOnEscListener.findCoolBar(menuBarComposite));
focusListener.addControl(RestoreFocusOnEscListener.findCoolBar(coolBarComposite));
}
private void createInfoFlyout(final Composite mainComposite) {
final InfoFlyout flyout = UIControlsFactory.createInfoFlyout(mainComposite);
binding.addUIControl(flyout, INFO_FLYOUT_BINDING_ID);
}
@Override
public void dispose() {
super.dispose();
if (titleComposite != null) {
titleComposite.dispose();
titleComposite = null;
}
}
@Override
public void preWindowOpen() {
configureWindow();
}
@Override
public void postWindowCreate() {
super.postWindowCreate();
final Shell shell = getWindowConfigurer().getWindow().getShell();
if (SWTFacade.isRAP()) {
shell.setMaximized(true);
} else {
getWindowNavigator().beforeOpen(shell);
}
}
@Override
public void postWindowOpen() {
super.postWindowOpen();
doInitialBinding();
final IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
updateApplicationSize(configurer);
if (titleComposite != null) {
// Redraw so that the active tab is displayed correct
titleComposite.setRedraw(false);
titleComposite.setRedraw(true);
}
}
@Override
public boolean preWindowShellClose() {
getWindowNavigator().beforeClose(getWindowConfigurer().getWindow().getShell());
return super.preWindowShellClose();
}
/**
* Updates the size of the application window (if necessary) according to the dimension of the display.
*
* @param configurer
*/
private void updateApplicationSize(final IWorkbenchWindowConfigurer configurer) {
final Shell shell = configurer.getWindow().getShell();
final Rectangle maxBounds = ShellHelper.calcMaxBounds(shell);
boolean update = false;
int x = shell.getLocation().x;
int width = shell.getBounds().width;
if (width > maxBounds.width) {
x = maxBounds.x;
width = maxBounds.width;
LOGGER.log(LogService.LOG_WARNING, "The width of the application is greater than the maximum width which is " //$NON-NLS-1$
+ width);
update = true;
}
int y = shell.getLocation().y;
int height = shell.getBounds().height;
if (height > maxBounds.height) {
y = maxBounds.y;
height = maxBounds.height;
LOGGER.log(LogService.LOG_WARNING, "The height of the application is greater than the maximum height which is " //$NON-NLS-1$
+ height);
update = true;
}
final Point minSize = shell.getMinimumSize();
if (minSize.x > maxBounds.width) {
minSize.x = maxBounds.width;
update = true;
}
if (minSize.y > maxBounds.height) {
minSize.y = maxBounds.height;
update = true;
}
if (update) {
shell.setLocation(x, y);
shell.setMinimumSize(minSize);
shell.setSize(width, height);
}
}
/**
* Creates a delegate for the binding of view and controller.
*
* @return delegate for binding
*/
protected AbstractViewBindingDelegate createBinding() {
return new InjectSwtViewBindingDelegate();
}
// helping methods
//////////////////
private void initializeListener() {
final NavigationTreeObserver navigationTreeObserver = new NavigationTreeObserver();
navigationTreeObserver.addListener(new MyApplicationNodeListener());
navigationTreeObserver.addListener(new MySubApplicationNodeListener());
navigationTreeObserver.addListener(new MyModuleGroupNodeListener());
navigationTreeObserver.addListener(new MyModuleNodeListener());
navigationTreeObserver.addListener(new MySubModuleNodeListener());
navigationTreeObserver.addListenerTo(controller.getNavigationNode());
}
/**
* Configures the window of the application.
*/
private void configureWindow() {
final IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
final String label = controller.getNavigationNode().getLabel();
if (label != null) {
configurer.setTitle(label);
}
initApplicationSize(configurer);
if (LnfManager.getLnf().getBooleanSetting(LnfKeyConstants.SHELL_HIDE_OS_BORDER) && !TestingSupport.isTestingEnabled()) { // some testing UI tools might not work with windows w/o real decorations(menu, border, etc){
// don't show the shell border (with the minimize, maximize and
// close buttons) of the operation system
configurer.setShellStyle(SWT.NO_TRIM | SWT.DOUBLE_BUFFERED);
}
}
/**
* Reads the two properties for the initial width and the initial height of the application.
*
* @param configurer
*/
private void initApplicationSize(final IWorkbenchWindowConfigurer configurer) {
int width = Integer.getInteger(PROPERTY_RIENA_APPLICATION_WIDTH, getApplicationSizeMinimum().x);
if (width < getApplicationSizeMinimum().x) {
width = getApplicationSizeMinimum().x;
LOGGER.log(LogService.LOG_WARNING, "The initial width of the application is less than the minimum width which is " //$NON-NLS-1$
+ getApplicationSizeMinimum().x);
}
int height = Integer.getInteger(PROPERTY_RIENA_APPLICATION_HEIGHT, getApplicationSizeMinimum().y);
if (height < getApplicationSizeMinimum().y) {
height = getApplicationSizeMinimum().y;
LOGGER.log(LogService.LOG_WARNING, "The initial height of the application is less than the minimum height which is " //$NON-NLS-1$
+ getApplicationSizeMinimum().y);
}
width = SwtUtilities.convertXToDpi(width);
height = SwtUtilities.convertYToDpi(height);
configurer.setInitialSize(new Point(width, height));
}
private void initApplicationSizeMinimum() {
final int widthMinimum = Integer.getInteger(PROPERTY_RIENA_APPLICATION_MINIMUM_WIDTH, getApplicationDefaultSizeMinimum().x);
final int heightMinimum = Integer.getInteger(PROPERTY_RIENA_APPLICATION_MINIMUM_HEIGHT, getApplicationDefaultSizeMinimum().y);
applicationSizeMinimum = new Point(widthMinimum, heightMinimum);
}
private Point getApplicationSizeMinimum() {
if (applicationSizeMinimum == null) {
initApplicationSizeMinimum();
}
return applicationSizeMinimum;
}
private Point getApplicationDefaultSizeMinimum() {
return (Point) LnfManager.getLnf().getSetting(LnfKeyConstants.APPLICATION_MIN_SIZE);
}
private void doInitialBinding() {
binding.injectAndBind(controller);
controller.afterBind();
}
private void createStatusLine(final Composite shell, final Composite grabCorner) {
final IStatusLineContentFactory statusLineFactory = getStatuslineContentFactory();
final Statusline statusLine = new Statusline(shell, SWT.None, StatuslineSpacer.class, statusLineFactory);
final FormData fd = new FormData();
fd.height = SwtUtilities.convertYToDpi(LnfManager.getLnf().getIntegerSetting(LnfKeyConstants.STATUSLINE_HEIGHT));
final Rectangle navigationBounds = TitlelessStackPresentation3xRAP.calcNavigationBounds(shell);
fd.left = new FormAttachment(0, navigationBounds.x);
if (grabCorner != null) {
fd.right = new FormAttachment(grabCorner, 0);
} else {
final int padding = getShellPadding();
fd.right = new FormAttachment(100, -padding);
}
fd.bottom = new FormAttachment(100, SwtUtilities.convertYToDpiTruncate(-5));
statusLine.setLayoutData(fd);
addUIControl(statusLine, "statusline"); //$NON-NLS-1$
LnFUpdater.getInstance().updateUIControls(statusLine, true);
}
/**
* Initializes the given shell.
*
* @param shell
* shell to initialize
*/
private void initShell(final Shell shell) {
shell.setBackground(LnfManager.getLnf().getColor(LnfKeyConstants.TITLELESS_SHELL_BACKGROUND));
shell.addPaintListener(new ShellPaintListener());
final String iconName = controller.getNavigationNode().getIcon();
shell.setImage(ImageStore.getInstance().getImage(iconName));
Point minimum = getApplicationSizeMinimum();
minimum = new Point(SwtUtilities.convertXToDpi(minimum.x), SwtUtilities.convertXToDpi(minimum.y));
shell.setMinimumSize(minimum);
// prepare shell for binding
addUIControl(shell, ApplicationViewAdvisor.SHELL_RIDGET_PROPERTY);
if (getShellRenderer() != null) {
getShellRenderer().setShell(shell);
}
// TODO check if this is the main window. maybe support more then one workbench window.
WidgetIdentificationSupport.setIdentification(shell);
}
/**
* Create the composite that contains the:
* <ul>
* <li>shell title and title buttons</li>
* <li>the logo</li>
* <li>the sub application switcher</li>
* </ul>
*
* @param parentShell
* the parent shell (non null)
* @return the title composite (never null)
*/
private TitleComposite createTitleComposite(final Shell parentShell) {
final ApplicationNode node = (ApplicationNode) controller.getNavigationNode();
return new TitleComposite(parentShell, node);
}
/**
* Creates and positions the corner to grab.
*
* @param shell
*/
private org.eclipse.riena.ui.swt.GrabCorner createGrabCorner(final Shell shell) {
if (org.eclipse.riena.ui.swt.GrabCorner.isResizeable() && LnfManager.getLnf().getBooleanSetting(LnfKeyConstants.SHELL_HIDE_OS_BORDER)) {
return new org.eclipse.riena.ui.swt.GrabCorner(shell, SWT.DOUBLE_BUFFERED);
}
return null;
}
/**
* Creates and positions the composite for the menu bar.
*
* @param parent
* parent of composite
* @param previous
* previous composite in the layout
* @return composite
*/
private Composite createMenuBarComposite(final Composite parent, final Composite previous) {
Assert.isTrue(parent.getLayout() instanceof FormLayout);
final int padding = getShellPadding();
// menu bar
final IWorkbenchWindow window = getWindowConfigurer().getWindow();
final IEntriesProvider entriesProvider = new IEntriesProvider() {
/**
* Returns the top-level menu entries.
*/
@SuppressWarnings("restriction")
public IContributionItem[] getTopLevelEntries() {
if (window instanceof WorkbenchWindow) {
final MenuManager menuManager = ((WorkbenchWindow) window).getMenuManager();
ImageReplacer.getInstance().replaceImagesOfManager(menuManager,((IconSize)LnfManager.getLnf().getSetting(LnfKeyConstants.MENUBAR_ICON_SIZE)));
return menuManager.getItems();
}
return new IContributionItem[0];
}
};
final MenuCoolBarComposite composite = new MenuCoolBarComposite(parent, SWT.NONE, entriesProvider);
final FormData formData = new FormData();
formData.top = new FormAttachment(previous, getMenuBarTopMargin());
formData.left = new FormAttachment(0, padding);
formData.right = new FormAttachment(100, -padding);
composite.setLayoutData(formData);
return composite;
}
/**
* Creates and positions the composite for the cool bar.
*
* @param parent
* parent of composite
* @param previous
* previous composite in the layout
* @return composite
*/
private Composite createCoolBarComposite(final Composite parent, Composite previous) {
Assert.isTrue(parent.getLayout() instanceof FormLayout);
final Composite separator = UIControlsFactory.createSeparator(parent, SWT.HORIZONTAL);
FormData formData = new FormData();
formData.top = new FormAttachment(previous);
formData.left = new FormAttachment(0, getBorderWidth());
formData.right = new FormAttachment(100, -getBorderWidth());
formData.height = SwtUtilities.convertYToDpi(2);
separator.setLayoutData(formData);
previous = separator;
final int padding = getShellPadding();
final Composite result = new Composite(parent, SWT.NONE);
result.setLayout(new FillLayout());
formData = new FormData();
formData.top = new FormAttachment(previous, getToolBarTopMargin());
formData.left = new FormAttachment(0, padding);
formData.right = new FormAttachment(100, -padding);
result.setLayoutData(formData);
replaceImagesOfCoolBar();
final Control control = getWindowConfigurer().createCoolBarControl(result);
if (control instanceof CoolBar) {
final CoolBar coolbar = (CoolBar) control;
CoolbarUtils.initCoolBar(coolbar, getToolbarFont());
}
return result;
}
/**
* Replaces all not scaled images of the cool bar items, if necessary.
*/
private void replaceImagesOfCoolBar() {
final IWorkbenchWindow window = getWindowConfigurer().getWindow();
if (window instanceof ApplicationWindow) {
final IContributionManager coolBarManager = ((ApplicationWindow) window).getCoolBarManager();
ImageReplacer.getInstance().replaceImagesOfManager(coolBarManager,((IconSize)LnfManager.getLnf().getSetting(LnfKeyConstants.TOOLBAR_ICON_SIZE)));
}
}
private int getBorderWidth() {
int width = 2;
final ShellBorderRenderer shellBorderRenderer = (ShellBorderRenderer) LnfManager.getLnf().getRenderer(LnfKeyConstants.TITLELESS_SHELL_BORDER_RENDERER);
if (shellBorderRenderer != null) {
width = shellBorderRenderer.getBorderWidth(); // don't scale!
}
return width;
}
private static Font getToolbarFont() {
return LnfManager.getLnf().getFont(LnfKeyConstants.TOOLBAR_FONT);
}
/**
* Creates the main composite.
*
* @param parent
* parent of composite
* @param previous
* previous composite in the layout
* @return composite
*/
private Composite createMainComposite(final Composite parent, final Composite previous) {
Assert.isTrue(parent.getLayout() instanceof FormLayout);
final int padding = getShellPadding();
final Composite composite = new Composite(parent, SWT.DOUBLE_BUFFERED);
composite.setLayout(new FillLayout());
final FormData formData = new FormData();
formData.top = new FormAttachment(previous, LnfManager.getLnf().getIntegerSetting(LnfKeyConstants.TOOLBAR_WORK_AREA_VERTICAL_GAP), 0);
formData.bottom = new FormAttachment(100, -padding);
formData.left = new FormAttachment(0, padding);
formData.right = new FormAttachment(100, -padding);
composite.setLayoutData(formData);
getWindowConfigurer().createPageComposite(composite);
return composite;
}
/**
* Returns the padding between shell border and content.
*
* @return padding
*/
private int getShellPadding() {
final ShellBorderRenderer borderRenderer = (ShellBorderRenderer) LnfManager.getLnf().getRenderer(LnfKeyConstants.TITLELESS_SHELL_BORDER_RENDERER);
return borderRenderer.getCompleteBorderWidth();
}
/**
* Returns the renderer of the shell.
*
* @return renderer
*/
private ShellRenderer getShellRenderer() {
final ShellRenderer shellRenderer = (ShellRenderer) LnfManager.getLnf().getRenderer(LnfKeyConstants.TITLELESS_SHELL_RENDERER);
return shellRenderer;
}
/**
* Returns the margin above the menu bar.
*
* @return top margin
*/
private int getMenuBarTopMargin() {
final RienaDefaultLnf lnf = LnfManager.getLnf();
return lnf.getIntegerSetting(LnfKeyConstants.MENUBAR_TOP_MARGIN, DEFAULT_COOLBAR_TOP_MARGIN);
}
/**
* Returns the margin above the tool bar.
*
* @return top margin
*/
private int getToolBarTopMargin() {
final RienaDefaultLnf lnf = LnfManager.getLnf();
return lnf.getIntegerSetting(LnfKeyConstants.TOOLBAR_TOP_MARGIN, DEFAULT_COOLBAR_TOP_MARGIN);
}
private IWorkbenchPage getActivePage() {
return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
}
// helping classes
//////////////////
private class MyApplicationNodeListener extends ApplicationNodeListener {
@Override
public void filterAdded(final IApplicationNode source, final IUIFilter filter) {
show();
}
@Override
public void filterRemoved(final IApplicationNode source, final IUIFilter filter) {
show();
}
private void show() {
if (controller == null || controller.getNavigationNode() == null || controller.getNavigationNode().isDisposed()) {
return;
}
try {
final IViewPart vp = getNavigationViewPart();
if (vp == null) {
final NavigationViewPart navi = (NavigationViewPart) getActivePage().showView(NavigationViewPart.ID);
navi.updateNavigationSize();
}
} catch (final PartInitException e) {
throw new UIViewFailure(e.getMessage(), e);
}
}
/**
* Returns the view part of the navigation.
*
* @return view part of the navigation or
*/
private IViewPart getNavigationViewPart() {
final IViewReference[] references = getActivePage().getViewReferences();
for (final IViewReference viewReference : references) {
if (viewReference.getId().equals(NavigationViewPart.ID)) {
return viewReference.getView(true);
}
}
return null;
}
}
private class MySubApplicationNodeListener extends SubApplicationNodeListener {
/**
* {@inheritDoc}
* <p>
* Shows the specified perspective (sub-application).
*/
@Override
public void activated(final ISubApplicationNode source) {
if (source != null) {
showPerspective(source);
if (titleComposite != null) {
// Redraw so that the active tab is displayed correct
titleComposite.setRedraw(false);
titleComposite.setRedraw(true);
}
prepare(source);
}
super.activated(source);
}
private void showPerspective(final ISubApplicationNode source) {
try {
final IWorkbench workbench = PlatformUI.getWorkbench();
workbench.showPerspective(SwtViewProvider.getInstance().getSwtViewId(source).getId(), workbench.getActiveWorkbenchWindow());
} catch (final WorkbenchException e) {
throw new UIViewFailure(e.getMessage(), e);
}
}
@Override
public void disposed(final ISubApplicationNode source) {
final SwtViewProvider viewProvider = SwtViewProvider.getInstance();
final String id = viewProvider.getSwtViewId(source).getId();
final IWorkbench workbench = PlatformUI.getWorkbench();
final IPerspectiveRegistry registry = workbench.getPerspectiveRegistry();
final IPerspectiveDescriptor perspDesc = registry.findPerspectiveWithId(id);
getActivePage().closePerspective(perspDesc, false, false);
viewProvider.unregisterSwtViewId(source);
}
}
/**
* This listener of a module group ensures the preparation of nodes (if necessary).
*/
private class MyModuleGroupNodeListener extends ModuleGroupNodeListener {
/**
* {@inheritDoc}
* <p>
* After activation of a module group prepare - if necessary - every child (sub module) node.
*/
@Override
public void activated(final IModuleGroupNode source) {
prepare(source);
super.activated(source);
}
/**
* {@inheritDoc}
* <p>
* After the parent of a module group changed prepare - if necessary - every child node.
*/
@Override
public void parentChanged(final IModuleGroupNode source) {
super.parentChanged(source);
prepare(source);
}
}
/**
* This listener of a module ensures the preparation of nodes (if necessary).
*/
private class MyModuleNodeListener extends ModuleNodeListener {
/**
* {@inheritDoc}
* <p>
* After activation of a module prepare - if necessary - every child (sub module) node.
*/
@Override
public void activated(final IModuleNode source) {
prepare(source);
super.activated(source);
}
/**
* {@inheritDoc}
* <p>
* After the parent of a module changed prepare - if necessary - every child node.
*/
@Override
public void parentChanged(final IModuleNode source) {
super.parentChanged(source);
prepare(source);
}
}
/**
* This listener of a sub module ensures the preparation of nodes (if necessary).
*/
private class MySubModuleNodeListener extends SubModuleNodeListener {
/**
* {@inheritDoc}
* <p>
* After activation of a sub module prepare - if necessary - every child node.
*/
@Override
public void activated(final ISubModuleNode source) {
prepare(source);
super.activated(source);
}
/**
* {@inheritDoc}
* <p>
* After the parent of a sub module changed prepare - if necessary - every child node.
*/
@Override
public void parentChanged(final ISubModuleNode source) {
super.parentChanged(source);
prepare(source);
}
}
/**
* Prepares every sub-module whose definition requires preparation.
*
* @param node
* navigation node
*/
private void prepare(final INavigationNode<?> node) {
if ((node == null) || (node.getParent() == null)) {
return;
}
if (node instanceof ISubModuleNode) {
final ISubModuleNode subModuleNode = (ISubModuleNode) node;
final IWorkareaDefinition definition = WorkareaManager.getInstance().getDefinition(subModuleNode);
if ((definition != null) && definition.isRequiredPreparation() && subModuleNode.isCreated()) {
subModuleNode.prepare();
}
}
/*
* The number of children can change while iterating. Only observe the node children !before! the iteration begins. Any child added while iterating will
* be handled automatically if preparation is required. Just ensure that there will be no concurrent modification of the children list while iterating
* over it. Conclusion is a copy..
*/
final List<INavigationNode<?>> children = new ArrayList<INavigationNode<?>>(node.getChildren());
for (final INavigationNode<?> child : children) {
prepare(child);
}
}
}