| /******************************************************************************* |
| * Copyright (c) 2009, 2015 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 |
| * Lars Vogel <Lars.Vogel@vogella.com> - Bug 472654 |
| *******************************************************************************/ |
| package org.eclipse.e4.ui.workbench.renderers.swt; |
| |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import javax.inject.Inject; |
| import javax.inject.Named; |
| import org.eclipse.e4.core.contexts.IEclipseContext; |
| import org.eclipse.e4.ui.model.application.ui.MContext; |
| import org.eclipse.e4.ui.model.application.ui.MUIElement; |
| import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder; |
| import org.eclipse.e4.ui.model.application.ui.basic.MPart; |
| import org.eclipse.e4.ui.workbench.IPresentationEngine; |
| import org.eclipse.e4.ui.workbench.modeling.EModelService; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.layout.FillLayout; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| |
| /** |
| * Create an element from a reference |
| */ |
| public class ElementReferenceRenderer extends SWTPartRenderer { |
| @Inject |
| @Named(WorkbenchRendererFactory.SHARED_ELEMENTS_STORE) |
| private Map<MUIElement, Set<MPlaceholder>> renderedMap; |
| |
| @Inject |
| private IPresentationEngine renderingEngine; |
| |
| @Override |
| public Object createWidget(final MUIElement element, Object parent) { |
| MPlaceholder ph = (MPlaceholder) element; |
| final MUIElement ref = ph.getRef(); |
| ref.setCurSharedRef(ph); |
| |
| Set<MPlaceholder> renderedRefs = renderedMap.get(ref); |
| if (renderedRefs == null) { |
| renderedRefs = new HashSet<>(); |
| renderedMap.put(ref, renderedRefs); |
| } |
| |
| if (!renderedRefs.contains(ph)) |
| renderedRefs.add(ph); |
| |
| Composite newComp = new Composite((Composite) parent, SWT.NONE); |
| newComp.setLayout(new FillLayout()); |
| |
| // if the placeholder is *not* in the currently active perspective |
| // then don't re-parent the current view |
| int phLoc = modelService.getElementLocation(ph); |
| if (phLoc == EModelService.IN_ACTIVE_PERSPECTIVE |
| || phLoc == EModelService.IN_SHARED_AREA |
| || phLoc == EModelService.OUTSIDE_PERSPECTIVE) { |
| Control refWidget = (Control) ref.getWidget(); |
| if (refWidget == null) { |
| ref.setToBeRendered(true); |
| refWidget = (Control) renderingEngine.createGui(ref, newComp, |
| getContextForParent(ref)); |
| } else { |
| if (refWidget.getParent() != newComp) { |
| refWidget.setParent(newComp); |
| } |
| } |
| |
| if (ref instanceof MContext) { |
| IEclipseContext context = ((MContext) ref).getContext(); |
| IEclipseContext newParentContext = getContext(ph); |
| if (context.getParent() != newParentContext) { |
| context.setParent(newParentContext); |
| } |
| } |
| } |
| |
| return newComp; |
| } |
| |
| @Override |
| public void disposeWidget(MUIElement element) { |
| MPlaceholder ph = (MPlaceholder) element; |
| MUIElement refElement = ph.getRef(); |
| Control refCtrl = (Control) refElement.getWidget(); |
| |
| // Remove the element ref from the rendered list |
| Set<MPlaceholder> refs = renderedMap.get(refElement); |
| refs.remove(ph); |
| |
| IEclipseContext curContext = modelService.getContainingContext(ph); |
| |
| if (refs.isEmpty()) { |
| // Ensure that the image is the 'original' image for this |
| // part. See bug 347471 for details |
| if (refElement instanceof MPart) { |
| MPart thePart = (MPart) refElement; |
| String imageURI = thePart.getIconURI(); |
| thePart.setIconURI(null); |
| thePart.setIconURI(imageURI); |
| } |
| |
| renderingEngine.removeGui(refElement); |
| renderedMap.remove(refElement); |
| } else { |
| // Ensure that the dispose of the element reference doesn't cascade |
| // to dispose the 'real' part |
| if (refCtrl != null && !refCtrl.isDisposed()) { |
| MPlaceholder currentRef = refElement.getCurSharedRef(); |
| if (currentRef == ph) { |
| // Find another *rendered* ref to pass the part on to |
| for (MPlaceholder aPH : refs) { |
| Composite phComp = (Composite) aPH.getWidget(); |
| if (phComp == null || phComp.isDisposed()) |
| continue; |
| |
| // Reparent the context(s) (if any) |
| IEclipseContext newParentContext = modelService |
| .getContainingContext(aPH); |
| List<MContext> allContexts = modelService.findElements( |
| refElement, null, MContext.class, null); |
| for (MContext ctxtElement : allContexts) { |
| IEclipseContext theContext = ctxtElement |
| .getContext(); |
| // this may be null if it hasn't been rendered yet |
| if (theContext != null) { |
| if (theContext.getParent() == curContext) { |
| // about to reparent the context, if we're |
| // the active child of the current parent, |
| // deactivate ourselves first |
| if (curContext.getActiveChild() == theContext) { |
| theContext.deactivate(); |
| } |
| theContext.setParent(newParentContext); |
| } |
| } |
| } |
| |
| // reset the 'cur' ref |
| refElement.setCurSharedRef(aPH); |
| |
| // Reparent the widget |
| refCtrl.setParent(phComp); |
| break; |
| } |
| } else if (currentRef != null) { |
| Composite phComp = (Composite) currentRef.getWidget(); |
| if (phComp == null || phComp.isDisposed()) { |
| super.disposeWidget(element); |
| return; |
| } |
| |
| // Reparent the context(s) (if any) |
| IEclipseContext newParentContext = modelService |
| .getContainingContext(currentRef); |
| List<MContext> allContexts = modelService.findElements( |
| refElement, null, MContext.class, null); |
| for (MContext ctxtElement : allContexts) { |
| IEclipseContext theContext = ctxtElement.getContext(); |
| // this may be null if it hasn't been rendered yet |
| if (theContext != null |
| && theContext.getParent() == curContext) { |
| // about to reparent the context, if we're the |
| // active child of the current parent, deactivate |
| // ourselves first |
| if (curContext.getActiveChild() == theContext) { |
| theContext.deactivate(); |
| } |
| theContext.setParent(newParentContext); |
| } |
| } |
| } |
| } |
| } |
| |
| super.disposeWidget(element); |
| } |
| } |