/******************************************************************************* * 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.e4.launcher.listener; import java.util.List; import javax.inject.Inject; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.e4.core.contexts.ContextInjectionFactory; import org.eclipse.e4.core.contexts.IEclipseContext; import org.eclipse.e4.ui.model.application.MApplication; 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.advanced.MAdvancedFactory; import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective; import org.eclipse.e4.ui.model.application.ui.basic.MBasicFactory; import org.eclipse.e4.ui.model.application.ui.basic.MPart; import org.eclipse.e4.ui.model.application.ui.basic.MPartStack; import org.eclipse.e4.ui.workbench.modeling.EModelService; import org.eclipse.riena.e4.launcher.Activator; import org.eclipse.riena.e4.launcher.E4XMIConstants; import org.eclipse.riena.e4.launcher.binder.SubApplicationBinder; import org.eclipse.riena.e4.launcher.part.NavigationPart; import org.eclipse.riena.navigation.ISubApplicationNode; import org.eclipse.riena.navigation.listener.SubApplicationNodeListener; import org.eclipse.riena.navigation.ui.controllers.SubApplicationController; import org.eclipse.riena.navigation.ui.swt.presentation.SwtViewProvider; import org.eclipse.riena.navigation.ui.swt.views.NavigationViewPart; /** * This listener of a sub application shows the according perspective. */ @SuppressWarnings("restriction") public class PerspectiveSubApplicationNodeListener extends SubApplicationNodeListener { private static final String PERSPECTIVES_EXT_POINT = "org.eclipse.ui.perspectives"; //$NON-NLS-1$ private final PrepareNodeDelegate<ISubApplicationNode> prepareNodeDelegate = new PrepareNodeDelegate<ISubApplicationNode>(); @Inject private IEclipseContext context; /** * {@inheritDoc} * <p> * Shows the specified perspective (sub-application). */ @Override public void activated(final ISubApplicationNode source) { if (source != null) { showPerspective(source); if (source.getNavigationNodeController() == null) { createNodeController(source); } prepareNodeDelegate.prepare(source); } } /** * Creates the {@link SubApplicationController} and binds it to {@link ISubApplicationNode} */ private void createNodeController(final ISubApplicationNode source) { final SubApplicationBinder binder = new SubApplicationBinder(source); ContextInjectionFactory.inject(binder, context); binder.bind(); } private void showPerspective(final ISubApplicationNode source) { final String perspectiveId = SwtViewProvider.getInstance().getSwtViewId(source).getId(); MPerspective perspective = findPerspective(perspectiveId); if (perspective == null) { final IExtensionRegistry extensionRegistry = context.get(IExtensionRegistry.class); final EModelService modelService = context.get(EModelService.class); final MApplication searchRoot = context.get(MApplication.class); final MElementContainer perspectiveStack = (MElementContainer) modelService.find(E4XMIConstants.PERSPECTIVE_STACK_ID, searchRoot); for (final IConfigurationElement e : extensionRegistry.getConfigurationElementsFor(PERSPECTIVES_EXT_POINT)) { if (perspectiveId.equals(e.getAttribute("id"))) { // create perspective of sub-application final MElementContainer newPerspective = MAdvancedFactory.INSTANCE.createPerspective(); newPerspective.setElementId(e.getAttribute("id")); perspectiveStack.getChildren().add(newPerspective); newPerspective.setParent(perspectiveStack); // create part of navigation and added to the new perspective final MPart navigationPart = MBasicFactory.INSTANCE.createPart(); navigationPart.setElementId(NavigationViewPart.ID); // construct the String as in Application.e4xmi final String pluginId = Activator.getDefault().getBundleContext().getBundle().getSymbolicName(); navigationPart.setContributionURI("bundleclass://" + pluginId + "/" + NavigationPart.class.getName()); newPerspective.getChildren().add(navigationPart); navigationPart.setParent(newPerspective); // create part stack of working area and added to the new perspective final MPartStack partStack = MBasicFactory.INSTANCE.createPartStack(); partStack.setElementId(E4XMIConstants.CONTENT_PART_STACK_ID); newPerspective.getChildren().add(partStack); partStack.setParent(newPerspective); perspective = (MPerspective) newPerspective; } } } if (perspective == null) { throw new IllegalStateException("Perspective not found, id: " + perspectiveId); } perspective.getParent().setSelectedElement(perspective); // final EPartService partService = context.get(EPartService.class); // partService.switchPerspective(perspective); } /** * Returns the perspective with the given ID * * @param perspectiveId * ID of the perspective * @return perspective or {@code null} if perspective doesn't exist */ private MPerspective findPerspective(final String perspectiveId) { final EModelService modelService = context.get(EModelService.class); final MApplication searchRoot = context.get(MApplication.class); final List<MPerspective> perspectives = modelService .findElements(searchRoot, perspectiveId, MPerspective.class, null, EModelService.IN_ANY_PERSPECTIVE); if (perspectives.isEmpty()) { return null; } else { return perspectives.get(0); } } /** * {@inheritDoc} * <p> * Remove the perspective of the given sub-application ({@code source}) from the perspective stack. */ @Override public void disposed(final ISubApplicationNode source) { final SwtViewProvider viewProvider = SwtViewProvider.getInstance(); final String perspectiveId = viewProvider.getSwtViewId(source).getId(); final MPerspective perspective = findPerspective(perspectiveId); if (perspective != null) { final MElementContainer<MUIElement> perspectiveStack = perspective.getParent(); if (perspectiveStack != null) { perspectiveStack.getChildren().remove(perspective); } } viewProvider.unregisterSwtViewId(source); } }