diff options
author | Wojciech Sudol | 2015-10-15 12:33:59 +0000 |
---|---|---|
committer | Wojciech Sudol | 2015-11-19 18:31:29 +0000 |
commit | 807e99692a618dde238605b07c75084a29137d60 (patch) | |
tree | f0fbbbeb9176d57b59c4f69b19b81c5a347b419d | |
parent | f65b8ec46aa711e2e1b4960250a9222c11943b5f (diff) | |
download | eclipse.platform.ui-807e99692a618dde238605b07c75084a29137d60.tar.gz eclipse.platform.ui-807e99692a618dde238605b07c75084a29137d60.tar.xz eclipse.platform.ui-807e99692a618dde238605b07c75084a29137d60.zip |
Bug 378811 - [Perspectives] Can't export and import perspectives anymore
Backporting the Perspective import export changes to Eclipse 4.4.2
Change-Id: Id58520b5014790abd66024a7318d04f777244f65
Also-by: Kalyan Prasad <kalyan_prasad@in.ibm.com>
13 files changed, 1865 insertions, 111 deletions
diff --git a/bundles/org.eclipse.e4.ui.workbench/META-INF/MANIFEST.MF b/bundles/org.eclipse.e4.ui.workbench/META-INF/MANIFEST.MF index 26b1b711fcd..eeedc6f44bc 100644 --- a/bundles/org.eclipse.e4.ui.workbench/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.e4.ui.workbench/META-INF/MANIFEST.MF @@ -21,7 +21,8 @@ Require-Bundle: org.eclipse.e4.ui.model.workbench;bundle-version="1.0.0", org.eclipse.core.expressions;bundle-version="[3.4.200,4.0.0)", org.eclipse.e4.ui.di;bundle-version="0.9.0", org.eclipse.emf.ecore.xmi;bundle-version="2.7.0", - org.eclipse.e4.core.di.extensions + org.eclipse.e4.core.di.extensions, + org.eclipse.jface;bundle-version="3.10.2" Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Export-Package: org.eclipse.e4.ui.internal.workbench; diff --git a/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/ModelServiceImpl.java b/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/ModelServiceImpl.java index 99a9e30b848..121b0d0ee59 100644 --- a/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/ModelServiceImpl.java +++ b/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/ModelServiceImpl.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010, 2014 IBM Corporation and others. + * Copyright (c) 2010, 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 @@ -59,6 +59,7 @@ import org.eclipse.e4.ui.workbench.modeling.EPlaceholderResolver; import org.eclipse.e4.ui.workbench.modeling.ElementMatcher; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.jface.resource.ImageDescriptor; import org.osgi.service.event.Event; import org.osgi.service.event.EventHandler; @@ -68,6 +69,10 @@ import org.osgi.service.event.EventHandler; public class ModelServiceImpl implements EModelService { private static String HOSTED_ELEMENT = "HostedElement"; //$NON-NLS-1$ + private static final String COMPATIBILITY_VIEW_URI = "bundleclass://org.eclipse.ui.workbench/org.eclipse.ui.internal.e4.compatibility.CompatibilityView"; //$NON-NLS-1$ + + private static final String TAG_LABEL = "label"; //$NON-NLS-1$ + private IEclipseContext appContext; /** Factory which is able to create {@link MApplicationElement}s in a generic way. */ @@ -413,14 +418,50 @@ public class ModelServiceImpl implements EModelService { EPlaceholderResolver resolver = appContext.get(EPlaceholderResolver.class); // Re-resolve any placeholder references List<MPlaceholder> phList = findElements(element, null, MPlaceholder.class, null); + List<MPlaceholder> unresolved = new ArrayList<MPlaceholder>(); for (MPlaceholder ph : phList) { resolver.resolvePlaceholderRef(ph, refWin); + if (ph.getRef() == null) { + unresolved.add(ph); + } + } + for (MPlaceholder ph : unresolved) { + replacePlaceholder(ph); } } return element; } + private void replacePlaceholder(MPlaceholder ph) { + MPart part = createModelElement(MPart.class); + part.setElementId(ph.getElementId()); + part.getTransientData().put(IPresentationEngine.OVERRIDE_ICON_IMAGE_KEY, + ImageDescriptor.getMissingImageDescriptor().createImage()); + String label = (String) ph.getTransientData().get(TAG_LABEL); + if (label != null) { + part.setLabel(label); + } else { + part.setLabel(getLabel(ph.getElementId())); + } + part.setContributionURI(COMPATIBILITY_VIEW_URI); + part.setCloseable(true); + MElementContainer<MUIElement> curParent = ph.getParent(); + int curIndex = curParent.getChildren().indexOf(ph); + curParent.getChildren().remove(curIndex); + curParent.getChildren().add(curIndex, part); + if (curParent.getSelectedElement() == ph) { + curParent.setSelectedElement(part); + } + } + + private String getLabel(String str) { + int index = str.lastIndexOf('.'); + if (index == -1) + return str; + return str.substring(index + 1); + } + @Override public MUIElement findSnippet(MSnippetContainer snippetContainer, String id) { if (snippetContainer == null || id == null || id.length() == 0) { diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/compatibility/ModeledPageLayout.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/compatibility/ModeledPageLayout.java index b5c34c7343c..0ccb3de2418 100644 --- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/compatibility/ModeledPageLayout.java +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/compatibility/ModeledPageLayout.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009, 2013 IBM Corporation and others. + * 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 @@ -23,7 +23,6 @@ import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective; import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder; import org.eclipse.e4.ui.model.application.ui.advanced.impl.AdvancedFactoryImpl; import org.eclipse.e4.ui.model.application.ui.basic.MPart; -import org.eclipse.e4.ui.model.application.ui.basic.MPartSashContainer; import org.eclipse.e4.ui.model.application.ui.basic.MPartSashContainerElement; import org.eclipse.e4.ui.model.application.ui.basic.MPartStack; import org.eclipse.e4.ui.model.application.ui.basic.MStackElement; @@ -33,7 +32,6 @@ import org.eclipse.e4.ui.workbench.IPresentationEngine; import org.eclipse.e4.ui.workbench.modeling.EModelService; import org.eclipse.e4.ui.workbench.modeling.EPartService; import org.eclipse.osgi.util.NLS; -import org.eclipse.swt.SWT; import org.eclipse.ui.IFolderLayout; import org.eclipse.ui.IPageLayout; import org.eclipse.ui.IPerspectiveDescriptor; @@ -61,6 +59,7 @@ public class ModeledPageLayout implements IPageLayout { public static final String PERSP_SHORTCUT_TAG = "persp.perspSC:"; //$NON-NLS-1$ public static final String SHOW_IN_PART_TAG = "persp.showIn:"; //$NON-NLS-1$ public static final String SHOW_VIEW_TAG = "persp.viewSC:"; //$NON-NLS-1$ + public static final String EDITOR_STACK_TAG = "EditorStack"; //$NON-NLS-1$ public static final String HIDDEN_MENU_PREFIX = "persp.hideMenuSC:"; //$NON-NLS-1$ public static final String HIDDEN_TOOLBAR_PREFIX = "persp.hideToolbarSC:"; //$NON-NLS-1$ public static final String HIDDEN_ITEMS_KEY = "persp.hiddenItems"; //$NON-NLS-1$ @@ -95,6 +94,8 @@ public class ModeledPageLayout implements IPageLayout { private IViewRegistry viewRegistry; + private ModeledPageLayoutUtils layoutUtils; + private class ViewActivator implements IIdentifierListener { private MUIElement element; @@ -138,6 +139,7 @@ public class ModeledPageLayout implements IPageLayout { // Create the editor area stack this.perspModel = perspModel; this.descriptor = descriptor; + this.layoutUtils = new ModeledPageLayoutUtils(modelService); this.createReferences = createReferences; @@ -158,7 +160,7 @@ public class ModeledPageLayout implements IPageLayout { // temporary HACK for bug 303982 editorStack.getTags().add("newtablook"); //$NON-NLS-1$ editorStack.getTags().add("org.eclipse.e4.primaryDataStack"); //$NON-NLS-1$ - editorStack.getTags().add("EditorStack"); //$NON-NLS-1$ + editorStack.getTags().add(EDITOR_STACK_TAG); editorStack.setElementId("org.eclipse.e4.primaryDataStack"); //$NON-NLS-1$ sharedArea.getChildren().add(editorStack); sharedArea.setElementId(getEditorArea()); @@ -374,21 +376,6 @@ public class ModeledPageLayout implements IPageLayout { // perspModel.setFixed(isFixed); } - private static int plRelToSwt(int rel) { - switch (rel) { - case IPageLayout.BOTTOM: - return SWT.BOTTOM; - case IPageLayout.LEFT: - return SWT.LEFT; - case IPageLayout.RIGHT: - return SWT.RIGHT; - case IPageLayout.TOP: - return SWT.TOP; - default: - return 0; - } - } - public static MStackElement createViewModel(MApplication application, String id, boolean visible, WorkbenchPage page, EPartService partService, boolean createReferences) { @@ -418,15 +405,6 @@ public class ModeledPageLayout implements IPageLayout { return null; } - public static MPartStack createStack(String id, boolean visible) { - MPartStack newStack = BasicFactoryImpl.eINSTANCE.createPartStack(); - // temporary HACK for bug 303982 - newStack.getTags().add("newtablook"); //$NON-NLS-1$ - newStack.setElementId(id); - newStack.setToBeRendered(visible); - return newStack; - } - private MUIElement insertView(String viewId, int relationship, float ratio, String refId, boolean visible, boolean withStack) { @@ -446,7 +424,8 @@ public class ModeledPageLayout implements IPageLayout { stack.getChildren().add(viewModel); retVal = stack; } else { - insert(viewModel, findRefModel(refId), plRelToSwt(relationship), ratio); + layoutUtils.insert(viewModel, findRefModel(refId), + layoutUtils.plRelToSwt(relationship), ratio); } } @@ -508,8 +487,9 @@ public class ModeledPageLayout implements IPageLayout { MUIElement refModel = findElement(perspModel, refId); if (refModel == null) { WorkbenchPlugin.log(NLS.bind(WorkbenchMessages.PageLayout_missingRefPart, refId)); - MPartStack stack = createStack(stackId, visible); - insert(stack, getLastElement(), plRelToSwt(relationship), ratio); + MPartStack stack = layoutUtils.createStack(stackId, visible); + layoutUtils + .insert(stack, getLastElement(), layoutUtils.plRelToSwt(relationship), ratio); return stack; } // If the 'refModel' is -not- a stack then find one @@ -526,13 +506,13 @@ public class ModeledPageLayout implements IPageLayout { // return null; // } - MPartStack stack = createStack(stackId, visible); + MPartStack stack = layoutUtils.createStack(stackId, visible); MElementContainer<?> parent = refModel.getParent(); if (parent instanceof MPartStack) { // we don't want to put a stack in a stack refModel = parent; } - insert(stack, refModel, plRelToSwt(relationship), ratio); + layoutUtils.insert(stack, refModel, layoutUtils.plRelToSwt(relationship), ratio); return stack; } @@ -568,69 +548,6 @@ public class ModeledPageLayout implements IPageLayout { newParent.getChildren().add(relTo); } - public static void insert(MUIElement toInsert, MUIElement relTo, - int swtSide, int ratio) { - if (toInsert == null || relTo == null) - return; - - MElementContainer<MUIElement> relParent = relTo.getParent(); - if (relParent != null) { - List<MUIElement> children = relParent.getChildren(); - int index = children.indexOf(relTo); - MPartSashContainer psc = BasicFactoryImpl.eINSTANCE.createPartSashContainer(); - psc.setContainerData(relTo.getContainerData()); - relParent.getChildren().add(index + 1, psc); - - switch (swtSide) { - case SWT.LEFT: - psc.getChildren().add((MPartSashContainerElement) toInsert); - psc.getChildren().add((MPartSashContainerElement) relTo); - toInsert.setContainerData("" + ratio); //$NON-NLS-1$ - relTo.setContainerData("" + (10000 - ratio)); //$NON-NLS-1$ - psc.setHorizontal(true); - break; - case SWT.RIGHT: - psc.getChildren().add((MPartSashContainerElement) relTo); - psc.getChildren().add((MPartSashContainerElement) toInsert); - relTo.setContainerData("" + ratio); //$NON-NLS-1$ - toInsert.setContainerData("" + (10000 - ratio)); //$NON-NLS-1$ - psc.setHorizontal(true); - break; - case SWT.TOP: - psc.getChildren().add((MPartSashContainerElement) toInsert); - psc.getChildren().add((MPartSashContainerElement) relTo); - toInsert.setContainerData("" + ratio); //$NON-NLS-1$ - relTo.setContainerData("" + (10000 - ratio)); //$NON-NLS-1$ - psc.setHorizontal(false); - break; - case SWT.BOTTOM: - psc.getChildren().add((MPartSashContainerElement) relTo); - psc.getChildren().add((MPartSashContainerElement) toInsert); - relTo.setContainerData("" + ratio); //$NON-NLS-1$ - toInsert.setContainerData("" + (10000 - ratio)); //$NON-NLS-1$ - psc.setHorizontal(false); - break; - } - - if (relTo.isToBeRendered() || toInsert.isToBeRendered()) { - // one of the items to be inserted should be rendered, render - // all parent elements as well - resetToBeRenderedFlag(psc, true); - } else { - // no child elements need to be rendered, the parent part sash - // container does not need to be rendered either then - psc.setToBeRendered(false); - } - return; - } - } - - public static void insert(MUIElement toInsert, MUIElement relTo, - int swtSide, float ratio) { - int pct = (int) (ratio * 10000); - insert(toInsert, relTo, swtSide, pct); - } - MUIElement findElement(MUIElement toSearch, String id) { List<Object> found = modelService.findElements(toSearch, id, null, null, EModelService.IN_ANY_PERSPECTIVE); diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/compatibility/ModeledPageLayoutUtils.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/compatibility/ModeledPageLayoutUtils.java new file mode 100644 index 00000000000..a3115ac8fc6 --- /dev/null +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/compatibility/ModeledPageLayoutUtils.java @@ -0,0 +1,124 @@ +/******************************************************************************* + * Copyright (c) 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 + ******************************************************************************/ +package org.eclipse.ui.internal.e4.compatibility; + +import java.util.List; +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.MPerspective; +import org.eclipse.e4.ui.model.application.ui.basic.MPartSashContainer; +import org.eclipse.e4.ui.model.application.ui.basic.MPartSashContainerElement; +import org.eclipse.e4.ui.model.application.ui.basic.MPartStack; +import org.eclipse.e4.ui.workbench.modeling.EModelService; +import org.eclipse.swt.SWT; +import org.eclipse.ui.IPageLayout; + +public class ModeledPageLayoutUtils { + + private EModelService modelService; + + public ModeledPageLayoutUtils(EModelService modelService) { + this.modelService = modelService; + } + + public int plRelToSwt(int rel) { + switch (rel) { + case IPageLayout.BOTTOM: + return SWT.BOTTOM; + case IPageLayout.LEFT: + return SWT.LEFT; + case IPageLayout.RIGHT: + return SWT.RIGHT; + case IPageLayout.TOP: + return SWT.TOP; + default: + return 0; + } + } + + public void insert(MUIElement toInsert, MUIElement relTo, int swtSide, float ratio) { + int pct = (int) (ratio * 10000); + insert(toInsert, relTo, swtSide, pct); + } + + public void insert(MUIElement toInsert, MUIElement relTo, int swtSide, int ratio) { + if (toInsert == null || relTo == null) + return; + + MElementContainer<MUIElement> relParent = relTo.getParent(); + if (relParent != null) { + List<MUIElement> children = relParent.getChildren(); + int index = children.indexOf(relTo); + MPartSashContainer psc = modelService.createModelElement(MPartSashContainer.class); + psc.setContainerData(relTo.getContainerData()); + relParent.getChildren().add(index + 1, psc); + + switch (swtSide) { + case SWT.LEFT: + psc.getChildren().add((MPartSashContainerElement) toInsert); + psc.getChildren().add((MPartSashContainerElement) relTo); + toInsert.setContainerData("" + ratio); //$NON-NLS-1$ + relTo.setContainerData("" + (10000 - ratio)); //$NON-NLS-1$ + psc.setHorizontal(true); + break; + case SWT.RIGHT: + psc.getChildren().add((MPartSashContainerElement) relTo); + psc.getChildren().add((MPartSashContainerElement) toInsert); + relTo.setContainerData("" + ratio); //$NON-NLS-1$ + toInsert.setContainerData("" + (10000 - ratio)); //$NON-NLS-1$ + psc.setHorizontal(true); + break; + case SWT.TOP: + psc.getChildren().add((MPartSashContainerElement) toInsert); + psc.getChildren().add((MPartSashContainerElement) relTo); + toInsert.setContainerData("" + ratio); //$NON-NLS-1$ + relTo.setContainerData("" + (10000 - ratio)); //$NON-NLS-1$ + psc.setHorizontal(false); + break; + case SWT.BOTTOM: + psc.getChildren().add((MPartSashContainerElement) relTo); + psc.getChildren().add((MPartSashContainerElement) toInsert); + relTo.setContainerData("" + ratio); //$NON-NLS-1$ + toInsert.setContainerData("" + (10000 - ratio)); //$NON-NLS-1$ + psc.setHorizontal(false); + break; + } + + if (relTo.isToBeRendered() || toInsert.isToBeRendered()) { + // one of the items to be inserted should be rendered, render + // all parent elements as well + resetToBeRenderedFlag(psc, true); + } else { + // no child elements need to be rendered, the parent part sash + // container does not need to be rendered either then + psc.setToBeRendered(false); + } + return; + } + } + + public void resetToBeRenderedFlag(MUIElement element, boolean toBeRendered) { + MUIElement parent = element.getParent(); + while (parent != null && !(parent instanceof MPerspective)) { + parent.setToBeRendered(toBeRendered); + parent = parent.getParent(); + } + element.setToBeRendered(toBeRendered); + } + + public MPartStack createStack(String id, boolean visible) { + MPartStack newStack = modelService.createModelElement(MPartStack.class); + newStack.setElementId(id); + newStack.setToBeRendered(visible); + return newStack; + } + +} diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/migration/InfoReader.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/migration/InfoReader.java new file mode 100644 index 00000000000..1a02538099a --- /dev/null +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/migration/InfoReader.java @@ -0,0 +1,145 @@ +/******************************************************************************* + * Copyright (c) 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 + ******************************************************************************/ + +package org.eclipse.ui.internal.e4.migration; + +import java.util.ArrayList; +import java.util.List; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.internal.IWorkbenchConstants; + +public class InfoReader extends MementoReader { + + private List<PageReader> pages; + + private IMemento memFolder; + + InfoReader(IMemento memento) { + super(memento); + } + + String getId() { + return getString(IWorkbenchConstants.TAG_PART); + } + + boolean isRelativelyPositioned() { + return contains(IWorkbenchConstants.TAG_RATIO); + } + + boolean isFolder() { + return getBoolean(IWorkbenchConstants.TAG_FOLDER); + } + + boolean isEditorArea() { + String id = getId(); + return IPageLayout.ID_EDITOR_AREA.equals(id); + } + + private IMemento getFolder() { + if (memFolder == null) { + memFolder = memento.getChild(IWorkbenchConstants.TAG_FOLDER); + } + return memFolder; + } + + int[] getPartOrder() { + IMemento folder = getFolder(); + if (folder == null) { + return null; + } + + IMemento presentation = folder.getChild(IWorkbenchConstants.TAG_PRESENTATION); + if (presentation == null) { + return null; + } + + IMemento[] partPositions = presentation.getChildren(IWorkbenchConstants.TAG_PART); + int[] partOrder = new int[partPositions.length]; + for (int i = 0; i < partPositions.length; i++) { + partOrder[i] = partPositions[i].getInteger(IWorkbenchConstants.TAG_ID); + } + return partOrder; + } + + List<PageReader> getPages() { + if (pages != null) { + return pages; + } + + IMemento folder = getFolder(); + if (folder != null) { + IMemento[] pageMems = folder.getChildren(IWorkbenchConstants.TAG_PAGE); + pages = new ArrayList<PageReader>(pageMems.length); + for (IMemento pageMem : pageMems) { + pages.add(new PageReader(pageMem)); + } + } + return pages; + } + + String getActivePageId() { + String activePageId = null; + IMemento folder = getFolder(); + if (folder != null) { + activePageId = folder.getString(IWorkbenchConstants.TAG_ACTIVE_PAGE_ID); + } + return activePageId; + } + + float getRatio() { + return getFloat(IWorkbenchConstants.TAG_RATIO); + } + + int getRelationship() { + return getInteger(IWorkbenchConstants.TAG_RELATIONSHIP); + } + + String getRelative() { + return getString(IWorkbenchConstants.TAG_RELATIVE); + } + + public PartState getState() { + PartState state = PartState.RESTORED; + IMemento folder = getFolder(); + int value = folder.getInteger(IWorkbenchConstants.TAG_EXPANDED); + switch (value) { + case 0: + state = PartState.MINIMIZED; + break; + case 1: + state = PartState.MAXIMIZED; + break; + } + return state; + } + + public static enum PartState { + MINIMIZED, MAXIMIZED, RESTORED; + } + + static class PageReader extends MementoReader { + + PageReader(IMemento pageMemento) { + super(pageMemento); + } + + String getId() { + return getString(IWorkbenchConstants.TAG_CONTENT); + } + + String getLabel() { + return getString(IWorkbenchConstants.TAG_LABEL); + } + + } + +} diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/migration/MementoReader.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/migration/MementoReader.java new file mode 100644 index 00000000000..af3dea63df9 --- /dev/null +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/migration/MementoReader.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 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 + ******************************************************************************/ + +package org.eclipse.ui.internal.e4.migration; + +import java.util.Arrays; +import org.eclipse.ui.IMemento; + +public class MementoReader { + + protected IMemento memento; + + MementoReader() { + } + + MementoReader(IMemento memento) { + this.memento = memento; + } + + protected String getString(String attribute) { + return memento.getString(attribute); + } + + /** + * @param attribute + * @return value or false when attribute not found + */ + protected boolean getBoolean(String attribute) { + return Boolean.TRUE.equals(memento.getBoolean(attribute)); + } + + protected boolean getBoolean(String attribute, boolean defaultValue) { + Boolean value = memento.getBoolean(attribute); + return value == null ? defaultValue : value; + } + + protected Integer getInteger(String attribute) { + return memento.getInteger(attribute); + } + + protected Float getFloat(String attribute) { + return memento.getFloat(attribute); + } + + protected boolean contains(String attribute) { + return Arrays.asList(memento.getAttributeKeys()).contains(attribute); + } + + protected IMemento[] getChildren(String tagName) { + return memento.getChildren(tagName); + } + + protected IMemento getChild(String tagName) { + return memento.getChild(tagName); + } + + IMemento getMemento() { + return memento; + } + +} diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/migration/PerspectiveBuilder.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/migration/PerspectiveBuilder.java new file mode 100644 index 00000000000..4bd68038aff --- /dev/null +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/migration/PerspectiveBuilder.java @@ -0,0 +1,683 @@ +/******************************************************************************* + * Copyright (c) 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 + ******************************************************************************/ + +package org.eclipse.ui.internal.e4.migration; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.annotation.PostConstruct; +import javax.inject.Inject; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.Platform; +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.MPlaceholder; +import org.eclipse.e4.ui.model.application.ui.basic.MPartSashContainer; +import org.eclipse.e4.ui.model.application.ui.basic.MPartSashContainerElement; +import org.eclipse.e4.ui.model.application.ui.basic.MPartStack; +import org.eclipse.e4.ui.model.application.ui.basic.MStackElement; +import org.eclipse.e4.ui.model.application.ui.basic.MTrimmedWindow; +import org.eclipse.e4.ui.workbench.IPresentationEngine; +import org.eclipse.e4.ui.workbench.modeling.EModelService; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.internal.IWorkbenchConstants; +import org.eclipse.ui.internal.PerspectiveTagger; +import org.eclipse.ui.internal.e4.compatibility.ModeledPageLayout; +import org.eclipse.ui.internal.e4.compatibility.ModeledPageLayoutUtils; +import org.eclipse.ui.internal.e4.migration.InfoReader.PageReader; +import org.eclipse.ui.internal.e4.migration.InfoReader.PartState; +import org.eclipse.ui.internal.e4.migration.PerspectiveReader.DetachedWindowReader; +import org.eclipse.ui.internal.e4.migration.PerspectiveReader.ViewLayoutReader; +import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants; +import org.eclipse.ui.internal.registry.RegistryReader; +import org.eclipse.ui.internal.registry.StickyViewDescriptor; + +public class PerspectiveBuilder { + + static final String ORIGINAL_ID = "originalId"; //$NON-NLS-1$ + + static final String BASE_PERSPECTIVE_ID = "basePerspectiveId"; //$NON-NLS-1$ + + private static final String DEFAULT_FASTVIEW_STACK = "defaultFastViewStack"; //$NON-NLS-1$ + + private static final String ID_EDITOR_AREA = IPageLayout.ID_EDITOR_AREA; + + @Inject + private PerspectiveReader perspReader; + + @Inject + private EModelService modelService; + + private MPerspective perspective; + + private List<String> tags; + + private List<String> renderedViews; + + private List<String> defaultFastViews; + + private Map<String, MPlaceholder> viewPlaceholders = new HashMap<String, MPlaceholder>(); + + private Map<String, ViewLayoutReader> viewLayouts; + + private MPlaceholder editorAreaPlaceholder; + + private ModeledPageLayoutUtils layoutUtils; + + @PostConstruct + private void postConstruct() { + layoutUtils = new ModeledPageLayoutUtils(modelService); + } + + public MPerspective createPerspective() { + create(); + tags = perspective.getTags(); + populate(); + return perspective; + } + + private void create() { + perspective = modelService.createModelElement(MPerspective.class); + perspective.setElementId(perspReader.getId()); + String label = perspReader.getLabel(); + perspective.setLabel(label); + perspective.setTooltip(label); + if (perspReader.isCustom()) { + perspective.getTransientData().put(BASE_PERSPECTIVE_ID, perspReader.getBasicPerspectiveId()); + perspective.getTransientData().put(ORIGINAL_ID, perspReader.getOriginalId()); + } + } + + private void populate() { + addActionSetTags(); + addPerspectiveShortcutTags(); + addNewWizardTags(); + addShowViewTags(); + addHiddenItems(); + addShowInTags(); + + for (InfoReader info : perspReader.getInfos()) { + if (info.isEditorArea()) { + addEditorArea(info); + } else if (info.isFolder()) { + MPartStack stack = addPartStack(info); + populatePartStack(stack, info); + } + } + + addDefaultFastViewStack(); + setZoomState(); + addDetachedWindows(); + hideEmptyStacks(); + hideUrenderableSashes(); + hideInvisibleSashes(); + processStandaloneViews(); + correctSelectedElements(); + addTrimBars(); + PerspectiveTagger.tagPerspective(perspective, modelService); + } + + private void processStandaloneViews() { + Map<String, ViewLayoutReader> viewLayouts = perspReader.getViewLayouts(); + for (String viewId : viewLayouts.keySet()) { + MPlaceholder placeholder = viewPlaceholders.get(viewId); + if (placeholder == null) { + continue; + } + if (viewLayouts.get(viewId).isStandalone()) { + MElementContainer<MUIElement> parent = placeholder.getParent(); + placeholder.setContainerData(parent.getContainerData()); + parent.getChildren().remove(placeholder); + MElementContainer<MUIElement> grandParent = parent.getParent(); + int location = grandParent.getChildren().indexOf(parent); + grandParent.getChildren().add(location, placeholder); + grandParent.getChildren().remove(parent); + } + } + } + + private void addDetachedWindows() { + for (DetachedWindowReader detachedWindowReader : perspReader.getDetachedWindows()) { + MTrimmedWindow detachedWindow = modelService.createModelElement(MTrimmedWindow.class); + Rectangle bounds = detachedWindowReader.getBounds(); + detachedWindow.setX(bounds.x); + detachedWindow.setY(bounds.y); + detachedWindow.setWidth(bounds.width); + detachedWindow.setHeight(bounds.height); + MPartStack stack = modelService.createModelElement(MPartStack.class); + populatePartStack(stack, detachedWindowReader); + detachedWindow.getChildren().add(stack); + perspective.getWindows().add(detachedWindow); + } + } + + private void addTrimBars() { + Map<String, Integer> fastViewBars = perspReader.getFastViewBars(); + if (fastViewBars.size() == 0 && defaultFastViews.size() == 0) { + return; + } + + int topCounter = 0; + int bottomCounter = 0; + int rightCounter = 0; + int leftCounter = 0; + StringBuilder sb = new StringBuilder(); + + if (defaultFastViews.size() > 0) { + sb.append(DEFAULT_FASTVIEW_STACK).append(' '); + sb.append(SideValue.BOTTOM_VALUE).append(' ').append(bottomCounter++); + sb.append('#'); + } + + if (fastViewBars.size() > 0) { + for (InfoReader folder : perspReader.getInfos()) { + String folderId = folder.getId(); + if (!fastViewBars.containsKey(folderId)) { + continue; + } + + sb.append(folderId).append(' '); + + Integer side = fastViewBars.get(folderId); + if (side == null) { + side = SWT.LEFT; + } + + switch (side) { + case SWT.TOP: + sb.append(SideValue.TOP_VALUE).append(' ').append(topCounter++); + break; + case SWT.BOTTOM: + sb.append(SideValue.BOTTOM_VALUE).append(' ').append(bottomCounter++); + break; + case SWT.RIGHT: + sb.append(SideValue.RIGHT_VALUE).append(' ').append(rightCounter++); + break; + default: + sb.append(SideValue.LEFT_VALUE).append(' ').append(leftCounter++); + break; + } + + sb.append('#'); + } + } + perspective.getPersistedState().put("trims", sb.toString()); //$NON-NLS-1$ + } + + private void hideEmptyStacks() { + for (MPartStack stack : modelService.findElements(perspective, null, MPartStack.class, null)) { + if (ID_EDITOR_AREA.equals(stack.getElementId()) || ID_EDITOR_AREA.equals(stack.getParent().getElementId())) { + continue; + } + if (!hasRenderableContent(stack)) { + stack.setToBeRendered(false); + } + } + } + + private void setZoomState() { + List<MPartStack> stacks = modelService.findElements(perspective, null, MPartStack.class, null); + boolean isAnythingMaximized = isMaximized(editorAreaPlaceholder) || isAnyMaximized(stacks); + if (isAnythingMaximized) { + markMinimizedByZoom(editorAreaPlaceholder); + for (MPartStack stack : stacks) { + markMinimizedByZoom(stack); + } + } + } + + private void markMinimizedByZoom(MUIElement element) { + List<String> tags = element.getTags(); + if (tags.contains(IPresentationEngine.MINIMIZED)) { + tags.add(IPresentationEngine.MINIMIZED_BY_ZOOM); + } + } + + private boolean isAnyMaximized(List<MPartStack> stacks) { + for (MPartStack stack : stacks) { + if (isMaximized(stack)) { + return true; + } + } + return false; + } + + private boolean isMaximized(MUIElement element) { + return element.getTags().contains(IPresentationEngine.MAXIMIZED); + } + + private void hideUrenderableSashes() { + for (MPartSashContainer sash : modelService.findElements(perspective, null, MPartSashContainer.class, null)) { + hideUnrenderableSash(sash); + } + } + + private void hideInvisibleSashes() { + for (MPartSashContainer sash : modelService.findElements(perspective, null, MPartSashContainer.class, null)) { + hideInvisibleSash(sash); + } + } + + private void hideInvisibleSash(MElementContainer<?> container) { + if ((container instanceof MPartSashContainer) && container != perspective) { + if (!hasVisibleContent((MPartSashContainer) container)) { + container.setVisible(false); + hideInvisibleSash(container.getParent()); + } + } + } + + private boolean hasVisibleContent(MPartSashContainer sash) { + for (MPartSashContainerElement child : sash.getChildren()) { + if (child.isVisible()) { + return true; + } + } + return false; + } + + private void hideUnrenderableSash(MElementContainer<?> container) { + if ((container instanceof MPartSashContainer) && container != perspective) { + if (modelService.countRenderableChildren(container) == 0) { + container.setToBeRendered(false); + hideUnrenderableSash(container.getParent()); + } + } + } + + private boolean hasRenderableContent(MPartStack stack) { + for (MStackElement child : stack.getChildren()) { + if (child.isVisible() && child.isToBeRendered()) { + return true; + } + } + return false; + } + + private void correctSelectedElements() { + List<MPartSashContainerElement> perspChildren = perspective.getChildren(); + if (perspective.getSelectedElement() == null && !perspChildren.isEmpty()) { + for (MPartSashContainerElement child : perspChildren) { + if (child.isToBeRendered()) { + perspective.setSelectedElement(child); + break; + } + } + } + + for (MPartSashContainerElement child : perspChildren) { + correctSelectedElements(child); + } + } + + private void correctSelectedElements(MUIElement element) { + if (!(element instanceof MPartSashContainer || element instanceof MPartStack)) { + return; + } + @SuppressWarnings("unchecked") + MElementContainer<MUIElement> container = (MElementContainer<MUIElement>) element; + List<MUIElement> children = container.getChildren(); + if (container.getSelectedElement() == null && !children.isEmpty()) { + MUIElement firstRenderableElement = getFirstRenderableElement(children); + if (firstRenderableElement != null) { + container.setSelectedElement(firstRenderableElement); + } + } + for (MUIElement child : children) { + correctSelectedElements(child); + } + } + + private MUIElement getFirstRenderableElement(List<MUIElement> elements) { + for (MUIElement element : elements) { + if (element.isToBeRendered()) { + return element; + } + } + return null; + } + + private void addToPerspective(MPartSashContainerElement element, InfoReader info) { + if (info.isRelativelyPositioned()) { + insert(element, info); + } else { + perspective.getChildren().add(element); + } + } + + private void addEditorArea(InfoReader info) { + editorAreaPlaceholder = modelService.createModelElement(MPlaceholder.class); + editorAreaPlaceholder.setElementId(ID_EDITOR_AREA); + editorAreaPlaceholder.setToBeRendered(perspReader.isEditorAreaVisible()); + setPartState(editorAreaPlaceholder, perspReader.getEditorAreaState()); + addToPerspective(editorAreaPlaceholder, info); + } + + private MPartStack addPartStack(InfoReader info) { + MPartStack stack = createPartStack(info); + if (info.isRelativelyPositioned()) { + String refElementId = info.getRelative(); + MUIElement refElement = modelService.find(refElementId, perspective); + MElementContainer<?> parent = refElement.getParent(); + // don't put a stack in another stack + if (parent instanceof MPartStack) { + refElement = parent; + } + + insert(stack, refElement, info); + } else { + perspective.getChildren().add(stack); + } + setPartState(stack, info.getState()); + return stack; + } + + private MPartStack addDefaultFastViewStack() { + MPartStack stack = null; + List<String> views = perspReader.getDefaultFastViewBarViewIds(); + if (views.size() > 0) { + stack = layoutUtils.createStack(DEFAULT_FASTVIEW_STACK, true); + perspective.getChildren().add(stack); + setPartState(stack, org.eclipse.ui.internal.e4.migration.InfoReader.PartState.MINIMIZED); + + for (String view : views) { + addPlaceholderToDefaultFastViewStack(stack, view, null); + } + } + return stack; + } + + private void setPartState(MUIElement element, PartState state) { + List<String> tags = element.getTags(); + switch (state) { + case MINIMIZED: + tags.add(IPresentationEngine.MINIMIZED); + element.setVisible(false); + break; + case MAXIMIZED: + tags.add(IPresentationEngine.MAXIMIZED); + break; + default: + break; + } + } + + private void insert(MUIElement element, MUIElement refElement, InfoReader info) { + layoutUtils.insert(element, refElement, layoutUtils.plRelToSwt(info.getRelationship()), info.getRatio()); + } + + private void insert(MUIElement element, InfoReader info) { + insert(element, modelService.find(info.getRelative(), perspective), info); + } + + private MPartStack createPartStack(InfoReader info) { + String stackId = info.getId(); + if (stackId != null) { + if (stackId.equals(StickyViewDescriptor.STICKY_FOLDER_RIGHT)) { + stackId = "legacyStickyFolderRight"; //$NON-NLS-1$ + } + } + return layoutUtils.createStack(stackId, true); + } + + private void populatePartStack(MPartStack stack, InfoReader info) { + for (PageReader page : info.getPages()) { + addPlaceholderToStack(stack, page.getId(), page.getLabel()); + } + MStackElement selectedElement = (MStackElement) modelService.find(info.getActivePageId(), stack); + if (selectedElement != null) { + selectedElement.setToBeRendered(true); + selectedElement.setVisible(true); + } + stack.setSelectedElement(selectedElement); + + // restore order of views in the stacks + List<MStackElement> renderedViews = getRenderedViews(stack); + if (renderedViews.size() < 2) { + return; + } + + int[] partOrder = info.getPartOrder(); + List<MStackElement> stackChildren = stack.getChildren(); + // unexpected situation - don't order + if (partOrder == null || partOrder.length != renderedViews.size()) { + return; + } + List<MStackElement> originalOrder = new ArrayList<MStackElement>(renderedViews); + stackChildren.clear(); + for (int i = 0; i < partOrder.length; i++) { + stackChildren.add(originalOrder.get(partOrder[i])); + } + originalOrder.removeAll(stackChildren); + stackChildren.addAll(originalOrder); + } + + private List<MStackElement> getRenderedViews(MPartStack stack) { + List<MStackElement> renderedViews = new ArrayList<MStackElement>(); + for (MStackElement element : stack.getChildren()) { + if (element.isToBeRendered()) { + renderedViews.add(element); + } + } + return renderedViews; + } + + private void populatePartStack(MPartStack stack, DetachedWindowReader info) { + for (PageReader page : info.getPages()) { + addPlaceholderToStack(stack, page.getId(), page.getLabel()); + } + stack.setSelectedElement((MStackElement) modelService.find(info.getActivePageId(), stack)); + } + + private void addPlaceholderToStack(MPartStack stack, String partId, String label) { + if (partId == null || isDefaultFastView(partId)) { + return; + } + MPlaceholder placeholder = createPlaceHolder(partId, label); + if (!isToBeRendered(placeholder)) { + placeholder.setToBeRendered(false); + } + addLayoutTagsToPlaceholder(placeholder, partId); + stack.getChildren().add(placeholder); + viewPlaceholders.put(partId, placeholder); + } + + private void addPlaceholderToDefaultFastViewStack(MPartStack stack, String partId, String label) { + MPlaceholder placeholder = createPlaceHolder(partId, label); + if (!isDefaultFastView(placeholder)) { + placeholder.setToBeRendered(false); + } + addLayoutTagsToPlaceholder(placeholder, partId); + stack.getChildren().add(placeholder); + if (viewPlaceholders.get(partId) != null) { + viewPlaceholders.put(partId, placeholder); + } + } + + private void addLayoutTagsToPlaceholder(MPlaceholder placeholder, String partId) { + ViewLayoutReader viewLayout = getViewLayout(partId); + if (viewLayout == null) { + return; + } + List<String> tags = placeholder.getTags(); + if (!viewLayout.isCloseable()) { + tags.add(IPresentationEngine.NO_CLOSE); + } + if (viewLayout.isStandalone()) { + tags.add(IPresentationEngine.STANDALONE); + } + } + + private boolean isToBeRendered(MPlaceholder placeholder) { + if (renderedViews == null) { + renderedViews = perspReader.getRenderedViewIds(); + } + return renderedViews.contains(placeholder.getElementId()); + } + + private boolean isDefaultFastView(MPlaceholder placeholder) { + if (defaultFastViews == null) { + defaultFastViews = perspReader.getDefaultFastViewBarViewIds(); + } + return defaultFastViews.contains(placeholder.getElementId()); + } + + private boolean isDefaultFastView(String placeholderId) { + if (defaultFastViews == null) { + defaultFastViews = perspReader.getDefaultFastViewBarViewIds(); + } + return defaultFastViews.contains(placeholderId); + } + + private void addPerspectiveShortcutTags() { + for (String shortcutId : perspReader.getPerspectiveShortcutIds()) { + tags.add(ModeledPageLayout.PERSP_SHORTCUT_TAG + shortcutId); + } + } + + private void addActionSetTags() { + for (String actionSetId : perspReader.getActionSetIds()) { + tags.add(ModeledPageLayout.ACTION_SET_TAG + actionSetId); + } + } + + private void addShowInTags() { + String origId = null; + if (perspReader.isCustom()) { + origId = perspReader.getBasicPerspectiveId(); + } else { + origId = perspReader.getId(); + } + ArrayList<String> list = getShowInPartFromRegistry(origId); + if (list != null) { + for (String showIn : list) { + tags.add(ModeledPageLayout.SHOW_IN_PART_TAG + showIn); + } + } + return; + } + + public static ArrayList<String> getShowInPartFromRegistry(String targetId) { + ArrayList<String> list = new ArrayList<String>(); + IExtension[] extensions = getPerspectiveExtensions(); + if (extensions != null) { + for (int i = 0; i < extensions.length; i++) { + list.addAll(getExtensionShowInPartFromRegistry(extensions[i], targetId)); + } + } + return list; + } + + private static IExtension[] getPerspectiveExtensions() { + IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(PlatformUI.PLUGIN_ID, + IWorkbenchRegistryConstants.PL_PERSPECTIVE_EXTENSIONS); + if (point == null) { + return null; + } + IExtension[] extensions = point.getExtensions(); + extensions = RegistryReader.orderExtensions(extensions); + return extensions; + } + + private static ArrayList<String> getExtensionShowInPartFromRegistry(IExtension extension, String targetId) { + ArrayList<String> list = new ArrayList<String>(); + IConfigurationElement[] configElements = extension.getConfigurationElements(); + for (int j = 0; j < configElements.length; j++) { + String type = configElements[j].getName(); + if (type.equals(IWorkbenchRegistryConstants.TAG_PERSPECTIVE_EXTENSION)) { + String id = configElements[j].getAttribute(IWorkbenchRegistryConstants.ATT_TARGET_ID); + if (targetId.equals(id) || "*".equals(id)) { //$NON-NLS-1$ + list.addAll(getConfigElementShowInPartsFromRegistry(configElements[j])); + } + } + } + return list; + } + + private static ArrayList<String> getConfigElementShowInPartsFromRegistry(IConfigurationElement configElement) { + ArrayList<String> list = new ArrayList<String>(); + String tag = IWorkbenchRegistryConstants.TAG_SHOW_IN_PART; + IConfigurationElement[] children = configElement.getChildren(); + for (int nX = 0; nX < children.length; nX++) { + IConfigurationElement child = children[nX]; + String ctype = child.getName(); + if (tag.equals(ctype)) { + String tid = child.getAttribute(IWorkbenchRegistryConstants.ATT_ID); + if (tid != null) { + list.add(tid); + } + } + } + return list; + } + + private void addNewWizardTags() { + for (String actionId : perspReader.getNewWizardActionIds()) { + tags.add(ModeledPageLayout.NEW_WIZARD_TAG + actionId); + } + } + + private void addShowViewTags() { + for (String actionId : perspReader.getShowViewActionIds()) { + tags.add(ModeledPageLayout.SHOW_VIEW_TAG + actionId); + } + } + + private void addHiddenItems() { + String comma = ","; //$NON-NLS-1$ + StringBuilder persistedValue = new StringBuilder(); + for (String elementId : perspReader.getHiddenMenuItemIds()) { + persistedValue.append(ModeledPageLayout.HIDDEN_MENU_PREFIX); + persistedValue.append(elementId).append(comma); + } + for (String elementId : perspReader.getHiddenToolbarItemIds()) { + persistedValue.append(ModeledPageLayout.HIDDEN_TOOLBAR_PREFIX); + persistedValue.append(elementId).append(comma); + } + perspective.getPersistedState().put(ModeledPageLayout.HIDDEN_ITEMS_KEY, persistedValue.toString()); + } + + private ViewLayoutReader getViewLayout(String viewId) { + if (viewLayouts == null) { + viewLayouts = perspReader.getViewLayouts(); + } + return viewLayouts.get(viewId); + } + + Collection<MPlaceholder> getPlaceholders() { + return viewPlaceholders.values(); + } + + MPlaceholder getEditorAreaPlaceholder() { + return editorAreaPlaceholder; + } + + MPlaceholder createPlaceHolder(String str, String label) { + MPlaceholder placeholder = null; + placeholder = modelService.createModelElement(MPlaceholder.class); + placeholder.setElementId(str); + if (modelService.getPartDescriptor(str) == null) { + placeholder.getTransientData().put(IWorkbenchConstants.TAG_LABEL, label); + } + return placeholder; + } + +} diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/migration/PerspectiveReader.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/migration/PerspectiveReader.java new file mode 100644 index 00000000000..0e49b7d692f --- /dev/null +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/migration/PerspectiveReader.java @@ -0,0 +1,336 @@ +/******************************************************************************* + * Copyright (c) 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 + ******************************************************************************/ + +package org.eclipse.ui.internal.e4.migration; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.internal.IWorkbenchConstants; +import org.eclipse.ui.internal.e4.migration.InfoReader.PageReader; +import org.eclipse.ui.internal.e4.migration.InfoReader.PartState; + +public class PerspectiveReader extends MementoReader { + + private DescriptorReader descriptor; + + public PerspectiveReader(IMemento memento) { + super(memento); + } + + String getId() { + return getDescriptor().getId(); + } + + String getLabel() { + return getDescriptor().getLabel(); + } + + private DescriptorReader getDescriptor() { + if (descriptor == null) { + IMemento desriptorMem = getChild(IWorkbenchConstants.TAG_DESCRIPTOR); + if (desriptorMem == null) { + throw new NullPointerException("Perspective descriptor not found"); //$NON-NLS-1$ + } + descriptor = new DescriptorReader(desriptorMem); + } + return descriptor; + } + + List<InfoReader> getInfos() { + IMemento[] infoMems = getInfoMems(); + List<InfoReader> infos = new ArrayList<InfoReader>(infoMems.length); + for (IMemento infoMem : infoMems) { + infos.add(new InfoReader(infoMem)); + } + return infos; + } + + private IMemento[] getInfoMems() { + IMemento[] infoMems = null; + IMemento layout = getLayout(); + if (layout != null) { + IMemento mainWindow = layout.getChild(IWorkbenchConstants.TAG_MAIN_WINDOW); + if (mainWindow != null) { + infoMems = mainWindow.getChildren(IWorkbenchConstants.TAG_INFO); + } + } + if (infoMems == null) { + infoMems = new IMemento[0]; + } + return infoMems; + } + + Map<String, ViewLayoutReader> getViewLayouts() { + IMemento[] viewLayoutMems = getChildren(IWorkbenchConstants.TAG_VIEW_LAYOUT_REC); + Map<String, ViewLayoutReader> viewLayouts = new HashMap<String, ViewLayoutReader>( + viewLayoutMems.length); + for (IMemento memento : viewLayoutMems) { + ViewLayoutReader viewLayout = new ViewLayoutReader(memento); + viewLayouts.put(viewLayout.getViewId(), viewLayout); + } + return viewLayouts; + } + + private IMemento getLayout() { + return getChild(IWorkbenchConstants.TAG_LAYOUT); + } + + List<String> getPerspectiveShortcutIds() { + return getChildrenIds(IWorkbenchConstants.TAG_PERSPECTIVE_ACTION); + } + + List<String> getActionSetIds() { + return getChildrenIds(IWorkbenchConstants.TAG_ALWAYS_ON_ACTION_SET); + } + + List<String> getShowViewActionIds() { + return getChildrenIds(IWorkbenchConstants.TAG_SHOW_VIEW_ACTION); + } + + List<String> getNewWizardActionIds() { + return getChildrenIds(IWorkbenchConstants.TAG_NEW_WIZARD_ACTION); + } + + List<String> getRenderedViewIds() { + List<String> viewIds = getChildrenIds(IWorkbenchConstants.TAG_VIEW); + viewIds.addAll(getFastViewIds()); + return viewIds; + } + + /** + * @return map of fast view bar's ID and side + */ + Map<String, Integer> getFastViewBars() { + Map<String, Integer> bars = new HashMap<String, Integer>(); + for (IMemento bar : getFastViewBarMems()) { + bars.put(bar.getString(IWorkbenchConstants.TAG_ID), + bar.getInteger(IWorkbenchConstants.TAG_FAST_VIEW_SIDE)); + } + return bars; + } + + private List<String> getFastViewIds() { + List<String> fastViewIds = new ArrayList<String>(); + + IMemento fastViews = getChild(IWorkbenchConstants.TAG_FAST_VIEWS); + if (fastViews != null) { + for (IMemento view : fastViews.getChildren(IWorkbenchConstants.TAG_VIEW)) { + fastViewIds.add(view.getString(IWorkbenchConstants.TAG_ID)); + } + } + + IMemento[] fastViewBarArr = getFastViewBarMems(); + for (IMemento fastViewBar : fastViewBarArr) { + IMemento fastViewsInBar = fastViewBar.getChild(IWorkbenchConstants.TAG_FAST_VIEWS); + if (fastViewsInBar != null) { + for (IMemento view : fastViewsInBar.getChildren(IWorkbenchConstants.TAG_VIEW)) { + fastViewIds.add(view.getString(IWorkbenchConstants.TAG_ID)); + } + } + } + return fastViewIds; + } + + List<String> getDefaultFastViewBarViewIds() { + List<String> fastViewIds = new ArrayList<String>(); + IMemento fastViews = getChild(IWorkbenchConstants.TAG_FAST_VIEWS); + if (fastViews != null) { + for (IMemento view : fastViews.getChildren(IWorkbenchConstants.TAG_VIEW)) { + fastViewIds.add(view.getString(IWorkbenchConstants.TAG_ID)); + } + } + + return fastViewIds; + } + + private IMemento[] getFastViewBarMems() { + IMemento[] emptyArr = new IMemento[0]; + IMemento fastViewBars = getChild(IWorkbenchConstants.TAG_FAST_VIEW_BARS); + if (fastViewBars == null) { + return emptyArr; + } + IMemento[] fastViewBarArr = fastViewBars.getChildren(IWorkbenchConstants.TAG_FAST_VIEW_BAR); + return fastViewBarArr == null ? emptyArr : fastViewBarArr; + } + + List<String> getHiddenMenuItemIds() { + return getChildrenIds(IWorkbenchConstants.TAG_HIDE_MENU); + } + + List<String> getHiddenToolbarItemIds() { + return getChildrenIds(IWorkbenchConstants.TAG_HIDE_TOOLBAR); + } + + private List<String> getChildrenIds(String tag) { + IMemento[] idMemArr = getChildren(tag); + List<String> idList = new ArrayList<String>(idMemArr.length); + for (IMemento idMem : idMemArr) { + idList.add(idMem.getString(IWorkbenchConstants.TAG_ID)); + } + return idList; + } + + List<DetachedWindowReader> getDetachedWindows() { + List<DetachedWindowReader> readers = new ArrayList<DetachedWindowReader>(); + IMemento layout = getLayout(); + if (layout != null) { + IMemento[] mems = layout.getChildren(IWorkbenchConstants.TAG_DETACHED_WINDOW); + for (IMemento mem : mems) { + readers.add(new DetachedWindowReader(mem)); + } + } + return readers; + } + + boolean isCustom() { + return getDescriptor().isCustom(); + } + + String getBasicPerspectiveId() { + return getDescriptor().getBasicPerspectiveId(); + } + + String getOriginalId() { + return getDescriptor().getOriginalId(); + } + + boolean isEditorAreaVisible() { + return Integer.valueOf(1).equals(getInteger(IWorkbenchConstants.TAG_AREA_VISIBLE)); + } + + PartState getEditorAreaState() { + PartState state = PartState.RESTORED; + int value = getInteger(IWorkbenchConstants.TAG_AREA_TRIM_STATE); + switch (value) { + case 0: + case 4: // minimized by zoom + state = PartState.MINIMIZED; + break; + case 1: + state = PartState.MAXIMIZED; + break; + } + return state; + } + + static class DetachedWindowReader extends MementoReader { + + private DetachedWindowReader(IMemento memento) { + super(memento); + } + + Rectangle getBounds() { + Rectangle windowBounds = new Rectangle(0, 0, 0, 0); + Integer bigInt = getInteger(IWorkbenchConstants.TAG_X); + windowBounds.x = bigInt == null ? 0 : bigInt.intValue(); + bigInt = getInteger(IWorkbenchConstants.TAG_Y); + windowBounds.y = bigInt == null ? 0 : bigInt.intValue(); + bigInt = getInteger(IWorkbenchConstants.TAG_WIDTH); + windowBounds.width = bigInt == null ? 0 : bigInt.intValue(); + bigInt = getInteger(IWorkbenchConstants.TAG_HEIGHT); + windowBounds.height = bigInt == null ? 0 : bigInt.intValue(); + return windowBounds; + } + + String getActivePageId() { + String activePageId = null; + IMemento folder = getFolder(); + if (folder != null) { + activePageId = folder.getString(IWorkbenchConstants.TAG_ACTIVE_PAGE_ID); + } + return activePageId; + } + + List<PageReader> getPages() { + IMemento folder = getFolder(); + List<PageReader> pages = new ArrayList<PageReader>(); + if (folder != null) { + IMemento[] pageMems = folder.getChildren(IWorkbenchConstants.TAG_PAGE); + for (IMemento pageMem : pageMems) { + pages.add(new PageReader(pageMem)); + } + } + return pages; + } + + private IMemento getFolder() { + return getChild(IWorkbenchConstants.TAG_FOLDER); + } + + } + + private static class DescriptorReader extends MementoReader { + + private static final String TAG_DESCRIPTOR = IWorkbenchConstants.TAG_DESCRIPTOR; + + DescriptorReader(IMemento memento) { + super(memento); + } + + String getId() { + String id = getOriginalId(); + if (isCustom()) { + id = getBasicPerspectiveId() + "." + id; //$NON-NLS-1$ + } + return id; + } + + String getOriginalId() { + String id = getString(IWorkbenchConstants.TAG_ID); + if (id == null) { + throw new NullPointerException("Perspective ID not found"); //$NON-NLS-1$ + } + return id; + } + + boolean isCustom() { + return contains(TAG_DESCRIPTOR); + } + + String getBasicPerspectiveId() { + String id = getString(TAG_DESCRIPTOR); + if (id == null) { + throw new NullPointerException("Basic perspective ID not found"); //$NON-NLS-1$ + } + return id; + } + + String getLabel() { + return getString(IWorkbenchConstants.TAG_LABEL); + } + + } + + static class ViewLayoutReader extends MementoReader { + + private ViewLayoutReader(IMemento memento) { + super(memento); + } + + String getViewId() { + return getString(IWorkbenchConstants.TAG_ID); + } + + boolean isCloseable() { + return getBoolean(IWorkbenchConstants.TAG_CLOSEABLE, true); + } + + boolean isStandalone() { + return getBoolean(IWorkbenchConstants.TAG_STANDALONE); + } + + } + +} diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/ImportExportPespectiveHandler.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/ImportExportPespectiveHandler.java new file mode 100644 index 00000000000..72fe8103b87 --- /dev/null +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/ImportExportPespectiveHandler.java @@ -0,0 +1,362 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.ui.internal.registry; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.inject.Inject; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener; +import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent; +import org.eclipse.e4.core.contexts.ContextInjectionFactory; +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.e4.core.di.extensions.Preference; +import org.eclipse.e4.core.services.events.IEventBroker; +import org.eclipse.e4.core.services.log.Logger; +import org.eclipse.e4.ui.internal.workbench.E4XMIResourceFactory; +import org.eclipse.e4.ui.model.application.MAddon; +import org.eclipse.e4.ui.model.application.MApplication; +import org.eclipse.e4.ui.model.application.ui.MUIElement; +import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective; +import org.eclipse.e4.ui.workbench.modeling.EModelService; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.ui.IPerspectiveDescriptor; +import org.eclipse.ui.WorkbenchException; +import org.eclipse.ui.XMLMemento; +import org.eclipse.ui.internal.e4.compatibility.ModeledPageLayout; +import org.eclipse.ui.internal.e4.migration.PerspectiveBuilder; +import org.eclipse.ui.internal.e4.migration.PerspectiveReader; +import org.eclipse.ui.internal.wizards.preferences.PreferencesExportWizard; +import org.eclipse.ui.internal.wizards.preferences.PreferencesImportWizard; +import org.osgi.service.event.Event; +import org.osgi.service.event.EventHandler; + +@SuppressWarnings("restriction") +public class ImportExportPespectiveHandler { + + private static final String PERSPECTIVE_SUFFIX_4X = "_e4persp"; //$NON-NLS-1$ + + private static final String PERSPECTIVE_SUFFIX_3X = "_persp"; //$NON-NLS-1$ + + private static final String ASCII_ENCODING = "ASCII"; //$NON-NLS-1$ + + private static final String TRIMS_KEY = "trims"; //$NON-NLS-1$ + + @Inject + private EModelService modelService; + + @Inject + private MApplication application; + + @Inject + private IEventBroker eventBroker; + + @Inject + private Logger logger; + + @Inject @Preference(nodePath="org.eclipse.ui.workbench") + private IEclipsePreferences preferences; + + @Inject + private IEclipseContext context; + + @Inject + private PerspectiveRegistry perspectiveRegistry; + + private EventHandler importPreferencesEnd; + private EventHandler exportPreferencesBegin; + private EventHandler exportPreferencesEnd; + private IPreferenceChangeListener preferenceListener; + private boolean ignoreEvents; + + private List<MPerspective> exportedPersps = new ArrayList<MPerspective>(); + private List<String> importedPersps = new ArrayList<String>(); + private Map<String, String> minMaxPersistedState; + + private Boolean impExpEnabled; + + @PostConstruct + private void init() { + if (!isImpExpEnabled()) { + return; + } + + initializeEventHandlers(); + preferences.addPreferenceChangeListener(preferenceListener); + eventBroker.subscribe(PreferencesExportWizard.EVENT_EXPORT_BEGIN, exportPreferencesBegin); + eventBroker.subscribe(PreferencesExportWizard.EVENT_EXPORT_END, exportPreferencesEnd); + eventBroker.subscribe(PreferencesImportWizard.EVENT_IMPORT_END, importPreferencesEnd); + } + + @PreDestroy + private void dispose() { + if (!isImpExpEnabled()) { + return; + } + + preferences.removePreferenceChangeListener(preferenceListener); + eventBroker.unsubscribe(exportPreferencesBegin); + eventBroker.unsubscribe(exportPreferencesEnd); + eventBroker.unsubscribe(importPreferencesEnd); + } + + private void importPerspective4x(PreferenceChangeEvent event) { + importedPersps.add(event.getKey()); + MPerspective perspective = null; + try { + perspective = perspFromString((String) event.getNewValue()); + addShowInTags(perspective); + } catch (IOException e) { + logError(event, e); + } + addPerspectiveToWorkbench(perspective); + } + + private void addShowInTags(MPerspective perspective) { + if (perspective != null) { + String targetId = getOriginalId(perspective.getElementId()); + ArrayList<String> showInTags = PerspectiveBuilder.getShowInPartFromRegistry(targetId); + if (showInTags != null) { + List<String> newTags = new ArrayList<String>(); + for (String showIn : showInTags) { + newTags.add(ModeledPageLayout.SHOW_IN_PART_TAG + showIn); + } + perspective.getTags().addAll(newTags); + } + } + } + + private String getOriginalId(String id) { + int index = id.lastIndexOf('.'); + if (index == -1) + return id; + return id.substring(0, index); + } + + private void importPerspective3x(PreferenceChangeEvent event) { + importedPersps.add(event.getKey()); + StringReader reader = new StringReader((String) event.getNewValue()); + MPerspective perspective = null; + IEclipseContext childContext = context.createChild(); + try { + childContext.set(PerspectiveReader.class, new PerspectiveReader(XMLMemento.createReadRoot(reader))); + perspective = ContextInjectionFactory.make(PerspectiveBuilder.class, childContext).createPerspective(); + } catch (WorkbenchException e) { + logError(event, e); + } finally { + reader.close(); + childContext.dispose(); + } + addPerspectiveToWorkbench(perspective); + } + + private void addPerspectiveToWorkbench(MPerspective perspective) { + if (perspective == null) { + return; + } + + IPerspectiveDescriptor perspToOverwrite = perspectiveRegistry.findPerspectiveWithLabel(perspective.getLabel()); + + // a new perspective + if (perspToOverwrite == null) { + perspectiveRegistry.addPerspective(perspective); + importToolbarsLocation(perspective); + return; + } + + String perspToOverwriteId = perspToOverwrite.getId(); + // a perspective with the same label exists, but has different ID + if (!perspective.getElementId().equals(perspToOverwriteId)) { + perspective.setElementId(perspToOverwriteId); + } + perspectiveRegistry.deletePerspective(perspToOverwrite); + perspectiveRegistry.addPerspective(perspective); + importToolbarsLocation(perspective); + } + + private void logError(PreferenceChangeEvent event, Exception e) { + logger.error(e, String.format("Cannot read perspective \"%s\" from preferences", event.getKey())); //$NON-NLS-1$ + } + + private void copyPerspToPreferences(MPerspective persp) throws IOException { + MPerspective perspClone = (MPerspective) modelService.cloneElement(persp, null); + exportToolbarsLocation(perspClone); + String perspAsString = perspToString(perspClone); + preferences.put(perspClone.getLabel() + PERSPECTIVE_SUFFIX_4X, perspAsString); + } + + private void exportToolbarsLocation(MPerspective persp) { + Map<String, String> minMaxPersState = getMinMaxPersistedState(); + if (minMaxPersState == null) { + return; + } + String trimsData = minMaxPersState.get(persp.getElementId()); + persp.getPersistedState().put(TRIMS_KEY, trimsData); + } + + private void importToolbarsLocation(MPerspective persp) { + String trimsData = persp.getPersistedState().get(TRIMS_KEY); + if (trimsData == null || trimsData.trim().isEmpty()) { + return; + } + persp.getPersistedState().remove(TRIMS_KEY); + Map<String, String> minMaxPersState = getMinMaxPersistedState(); + if (minMaxPersState == null) { + return; + } + minMaxPersState.put(persp.getElementId(), trimsData); + } + + private Map<String, String> getMinMaxPersistedState() { + if (minMaxPersistedState != null) { + return minMaxPersistedState; + } + for (MAddon addon : application.getAddons()) { + if ("MinMax Addon".equals(addon.getElementId())) { //$NON-NLS-1$ + minMaxPersistedState = addon.getPersistedState(); + break; + } + } + return minMaxPersistedState; + } + + private String perspToString(MPerspective persp) throws IOException { + Resource resource = new E4XMIResourceFactory().createResource(null); + resource.getContents().add((EObject) persp); + ByteArrayOutputStream output = new ByteArrayOutputStream(); + try { + resource.save(output, null); + } finally { + try { + output.close(); + } catch (IOException e) { + logger.error(e, "Cannot close output stream"); //$NON-NLS-1$ + } + } + resource.getContents().clear(); + return new String(output.toByteArray(), ASCII_ENCODING); + } + + private MPerspective perspFromString(String perspAsString) throws IOException { + Resource resource = new E4XMIResourceFactory().createResource(null); + InputStream input = new ByteArrayInputStream(perspAsString.getBytes(ASCII_ENCODING)); + try { + resource.load(input, null); + } finally { + try { + input.close(); + } catch (IOException e) { + logger.error(e, "Cannot close input stream"); //$NON-NLS-1$ + } + } + MPerspective perspective = (MPerspective) resource.getContents().get(0); + resource.getContents().clear(); + return perspective; + } + + private void copyPerspsToPreferences() { + for (MUIElement snippet : application.getSnippets()) { + if (snippet instanceof MPerspective) { + MPerspective persp = (MPerspective) snippet; + exportedPersps.add(persp); + } + } + ignoreEvents = true; + for (MPerspective persp : exportedPersps) { + try { + copyPerspToPreferences(persp); + } catch (IOException e) { + logger.error(e, String.format("Cannot save perspective \"%s\" to preferences", persp.getElementId())); //$NON-NLS-1$ + } + } + ignoreEvents = false; + } + + private void removeExportedPreferences() { + ignoreEvents = true; + for (MPerspective persp : exportedPersps) { + preferences.remove(persp.getLabel() + PERSPECTIVE_SUFFIX_4X); + } + ignoreEvents = false; + exportedPersps.clear(); + } + + private void removeImportedPreferences() { + ignoreEvents = true; + for (String key : importedPersps) { + preferences.remove(key); + } + ignoreEvents = false; + importedPersps.clear(); + + // remove unused preference imported from Eclipse 3.x + preferences.remove("perspectives"); //$NON-NLS-1$ + } + + private void initializeEventHandlers() { + + importPreferencesEnd = new EventHandler() { + @Override + public void handleEvent(Event event) { + removeImportedPreferences(); + } + }; + + exportPreferencesBegin = new EventHandler() { + @Override + public void handleEvent(Event event) { + copyPerspsToPreferences(); + } + }; + + exportPreferencesEnd = new EventHandler() { + @Override + public void handleEvent(Event event) { + removeExportedPreferences(); + } + }; + + preferenceListener = new IPreferenceChangeListener() { + @Override + public void preferenceChange(PreferenceChangeEvent event) { + if (ignoreEvents) { + return; + } + + if (event.getKey().endsWith(PERSPECTIVE_SUFFIX_4X)) { + importPerspective4x(event); + } else if (event.getKey().endsWith(PERSPECTIVE_SUFFIX_3X)) { + importPerspective3x(event); + } + } + }; + + } + + private boolean isImpExpEnabled() { + impExpEnabled = true; + // if (impExpEnabled == null) { + //impExpEnabled = Boolean.parseBoolean(System.getProperty("e4.impExpPerspectiveEnabled")); //$NON-NLS-1$ + // } + // return impExpEnabled; + return impExpEnabled; + } + +} diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/PerspectiveRegistry.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/PerspectiveRegistry.java index 57bc3116b20..9372f3557a2 100644 --- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/PerspectiveRegistry.java +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/registry/PerspectiveRegistry.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 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 @@ -24,6 +24,9 @@ import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.core.runtime.dynamichelpers.IExtensionChangeHandler; import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker; +import org.eclipse.e4.core.contexts.ContextInjectionFactory; +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.e4.core.services.log.Logger; import org.eclipse.e4.ui.model.application.MApplication; import org.eclipse.e4.ui.model.application.ui.MSnippetContainer; import org.eclipse.e4.ui.model.application.ui.MUIElement; @@ -52,6 +55,14 @@ public class PerspectiveRegistry implements IPerspectiveRegistry, IExtensionChan @Inject MApplication application; + @Inject + IEclipseContext context; + + private IEclipseContext impExpHandlerContext; + + @Inject + Logger logger; + private Map<String, PerspectiveDescriptor> descriptors = new HashMap<String, PerspectiveDescriptor>(); @PostConstruct @@ -73,18 +84,45 @@ public class PerspectiveRegistry implements IPerspectiveRegistry, IExtensionChan if (existingDescriptor == null) { // A custom perspective with its own name. - String label = perspective.getLabel(); - String originalId = getOriginalId(perspective.getElementId()); - PerspectiveDescriptor originalDescriptor = descriptors.get(originalId); - PerspectiveDescriptor newDescriptor = new PerspectiveDescriptor(id, label, - originalDescriptor); - descriptors.put(id, newDescriptor); + createDescriptor(perspective); } else { // A custom perspecitve with a name of a pre-defined perspective existingDescriptor.setHasCustomDefinition(true); } } } + + impExpHandlerContext = context.createChild(); + impExpHandlerContext.set(PerspectiveRegistry.class, this); + ContextInjectionFactory.make(ImportExportPespectiveHandler.class, impExpHandlerContext); + } + + public void addPerspective(MPerspective perspective) { + application.getSnippets().add(perspective); + createDescriptor(perspective); + } + + private void createDescriptor(MPerspective perspective) { + String label = perspective.getLocalizedLabel(); + String originalId = getOriginalId(perspective.getElementId()); + PerspectiveDescriptor originalDescriptor = descriptors.get(originalId); + String id = perspective.getElementId(); + PerspectiveDescriptor newDescriptor = new PerspectiveDescriptor(id, label, originalDescriptor); + + /* + * if (perspective.getIconURI() != null) { try { ImageDescriptor img = + * ImageDescriptor.createFromURL(new + * URI(perspective.getIconURI()).toURL()); + * newDescriptor.setImageDescriptor(img); } catch (MalformedURLException + * e) { logger.warn(e, + * MessageFormat.format("Error on applying configured perspective icon: {0}" + * , //$NON-NLS-1$ perspective.getIconURI())); } catch + * (URISyntaxException e) { logger.warn(e, + * MessageFormat.format("Error on applying configured perspective icon: {0}" + * , //$NON-NLS-1$ perspective.getIconURI())); } } + */ + + descriptors.put(id, newDescriptor); } /** @@ -270,6 +308,9 @@ public class PerspectiveRegistry implements IPerspectiveRegistry, IExtensionChan * Dispose the receiver. */ public void dispose() { + if (impExpHandlerContext != null) { + impExpHandlerContext.dispose(); + } PlatformUI.getWorkbench().getExtensionTracker().unregisterHandler(this); // FIXME: what was this listener for? // WorkbenchPlugin.getDefault().getPreferenceStore().removePropertyChangeListener( diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/wizards/preferences/PreferencesExportWizard.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/wizards/preferences/PreferencesExportWizard.java index 46cd9f03f28..7e0a126ba01 100644 --- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/wizards/preferences/PreferencesExportWizard.java +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/wizards/preferences/PreferencesExportWizard.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2006 IBM Corporation and others. + * Copyright (c) 2000, 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 @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.ui.internal.wizards.preferences; +import org.eclipse.e4.core.services.events.IEventBroker; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.wizard.Wizard; @@ -45,8 +46,16 @@ import org.eclipse.ui.internal.WorkbenchPlugin; */ public class PreferencesExportWizard extends Wizard implements IExportWizard { + private static final String EVENT_TOPIC_BASE = "org/eclipse/ui/internal/wizards/preferences/export/"; //$NON-NLS-1$ + + public static final String EVENT_EXPORT_BEGIN = EVENT_TOPIC_BASE + "begin"; //$NON-NLS-1$ + + public static final String EVENT_EXPORT_END = EVENT_TOPIC_BASE + "end"; //$NON-NLS-1$ + private WizardPreferencesExportPage1 mainPage; + private IEventBroker eventBroker; + /** * Creates a wizard for exporting workspace preferences to the local file system. */ @@ -75,6 +84,7 @@ public class PreferencesExportWizard extends Wizard implements IExportWizard { */ @Override public void init(IWorkbench workbench, IStructuredSelection currentSelection) { + eventBroker = workbench.getService(IEventBroker.class); setWindowTitle(PreferencesMessages.PreferencesExportWizard_export); setDefaultPageImageDescriptor(WorkbenchImages .getImageDescriptor(IWorkbenchGraphicConstants.IMG_WIZBAN_EXPORT_PREF_WIZ)); @@ -86,7 +96,16 @@ public class PreferencesExportWizard extends Wizard implements IExportWizard { */ @Override public boolean performFinish() { - return mainPage.finish(); + sendEvent(EVENT_EXPORT_BEGIN); + boolean success = mainPage.finish(); + sendEvent(EVENT_EXPORT_END); + return success; + } + + private void sendEvent(String topic) { + if (eventBroker != null) { + eventBroker.send(topic, null); + } } diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/wizards/preferences/PreferencesImportWizard.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/wizards/preferences/PreferencesImportWizard.java index 4a779377ae7..adcc5b0cd1f 100644 --- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/wizards/preferences/PreferencesImportWizard.java +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/wizards/preferences/PreferencesImportWizard.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2006 IBM Corporation and others. + * Copyright (c) 2000, 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 @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.ui.internal.wizards.preferences; +import org.eclipse.e4.core.services.events.IEventBroker; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.wizard.Wizard; @@ -46,8 +47,12 @@ import org.eclipse.ui.internal.WorkbenchPlugin; */ public class PreferencesImportWizard extends Wizard implements IImportWizard { - private WizardPreferencesImportPage1 mainPage; + public static final String EVENT_IMPORT_END = "org/eclipse/ui/internal/wizards/preferences/import/end"; //$NON-NLS-1$ + + private WizardPreferencesImportPage1 mainPage; + private IEventBroker eventBroker; + /** * Creates a wizard for importing resources into the workspace from * the file system. @@ -77,6 +82,7 @@ public class PreferencesImportWizard extends Wizard implements IImportWizard { */ @Override public void init(IWorkbench workbench, IStructuredSelection currentSelection) { + eventBroker = workbench.getService(IEventBroker.class); setWindowTitle(PreferencesMessages.PreferencesImportWizard_import); setDefaultPageImageDescriptor(WorkbenchImages .getImageDescriptor(IWorkbenchGraphicConstants.IMG_WIZBAN_IMPORT_PREF_WIZ)); @@ -88,6 +94,14 @@ public class PreferencesImportWizard extends Wizard implements IImportWizard { */ @Override public boolean performFinish() { - return mainPage.finish(); + boolean success = mainPage.finish(); + sendEvent(EVENT_IMPORT_END); + return success; } + + private void sendEvent(String topic) { + if (eventBroker != null) { + eventBroker.send(topic, null); + } + } } diff --git a/bundles/org.eclipse.ui.workbench/META-INF/MANIFEST.MF b/bundles/org.eclipse.ui.workbench/META-INF/MANIFEST.MF index 21df995da0f..4524328c0b1 100644 --- a/bundles/org.eclipse.ui.workbench/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.ui.workbench/META-INF/MANIFEST.MF @@ -107,7 +107,9 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.6.0,4.0.0)", org.eclipse.e4.ui.css.core;bundle-version="0.9.0", org.eclipse.e4.ui.workbench3;bundle-version="0.12.0";visibility:=reexport, org.eclipse.e4.ui.workbench.addons.swt;bundle-version="0.10.0", - org.eclipse.emf.ecore;bundle-version="2.7.0" + org.eclipse.emf.ecore;bundle-version="2.7.0", + org.eclipse.e4.core.di.extensions;bundle-version="0.12.0", + org.eclipse.emf.ecore.xmi;bundle-version="2.10.2" Import-Package: com.ibm.icu.text, com.ibm.icu.util, javax.annotation;version="1.0.0", |