diff options
| author | Eric Moffatt | 2013-01-07 19:23:14 +0000 |
|---|---|---|
| committer | Eric Moffatt | 2013-01-07 19:24:39 +0000 |
| commit | 645c6b57845a594c7f0dc0c04a0b98ef88638464 (patch) | |
| tree | 77b488475cc03c59a7066b867f753fb614e03c25 | |
| parent | 36492244b6c538bd51ff1268b245f45a182fb81e (diff) | |
| download | eclipse.platform.ui-645c6b57845a594c7f0dc0c04a0b98ef88638464.tar.gz eclipse.platform.ui-645c6b57845a594c7f0dc0c04a0b98ef88638464.tar.xz eclipse.platform.ui-645c6b57845a594c7f0dc0c04a0b98ef88638464.zip | |
Fix for Bug 397612 - Need support for multi-instance viewsv20130107-192439
9 files changed, 163 insertions, 145 deletions
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 ab28c2e45bc..86548e27219 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 @@ -18,6 +18,7 @@ import org.eclipse.e4.core.contexts.IEclipseContext; import org.eclipse.e4.core.services.events.IEventBroker; import org.eclipse.e4.ui.model.application.MApplication; import org.eclipse.e4.ui.model.application.MApplicationElement; +import org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptor; import org.eclipse.e4.ui.model.application.ui.MElementContainer; import org.eclipse.e4.ui.model.application.ui.MGenericTile; import org.eclipse.e4.ui.model.application.ui.MSnippetContainer; @@ -57,6 +58,8 @@ import org.osgi.service.event.EventHandler; public class ModelServiceImpl implements EModelService { private static String HOSTED_ELEMENT = "HostedElement"; //$NON-NLS-1$ + private IEclipseContext appContext; + // Cleans up after a hosted element is disposed private EventHandler hostedElementHandler = new EventHandler() { @@ -88,6 +91,7 @@ public class ModelServiceImpl implements EModelService { if (appContext == null) return; + this.appContext = appContext; IEventBroker eventBroker = appContext.get(IEventBroker.class); eventBroker.subscribe(UIEvents.UIElement.TOPIC_WIDGET, hostedElementHandler); } @@ -1018,6 +1022,26 @@ public class ModelServiceImpl implements EModelService { /* * (non-Javadoc) * + * @see org.eclipse.e4.ui.workbench.modeling.EModelService#getPartDescriptor(java.lang.String) + */ + public MPartDescriptor getPartDescriptor(String id) { + MApplication application = appContext.get(MApplication.class); + + // If the id contains a ':' use the part before it as the descriptor id + int colonIndex = id.indexOf(':'); + String descId = colonIndex == -1 ? id : id.substring(0, colonIndex); + + for (MPartDescriptor descriptor : application.getDescriptors()) { + if (descriptor.getElementId().equals(descId)) { + return descriptor; + } + } + return null; + } + + /* + * (non-Javadoc) + * * @see * org.eclipse.e4.ui.workbench.modeling.EModelService#removeLocalPlaceholders(org.eclipse.e4 * .ui.model.application.ui.basic.MWindow, diff --git a/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/PartServiceImpl.java b/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/PartServiceImpl.java index 75fc4cb2955..f318b2964da 100644 --- a/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/PartServiceImpl.java +++ b/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/PartServiceImpl.java @@ -643,15 +643,6 @@ public class PartServiceImpl implements EPartService { return activePart; } - private MPartDescriptor findDescriptor(String id) { - for (MPartDescriptor descriptor : application.getDescriptors()) { - if (descriptor.getElementId().equals(id)) { - return descriptor; - } - } - return null; - } - private MPart createPart(MPartDescriptor descriptor) { if (descriptor == null) { return null; @@ -676,7 +667,7 @@ public class PartServiceImpl implements EPartService { } public MPart createPart(String id) { - MPartDescriptor descriptor = findDescriptor(id); + MPartDescriptor descriptor = modelService.getPartDescriptor(id); return createPart(descriptor); } @@ -700,12 +691,15 @@ public class PartServiceImpl implements EPartService { } if (sharedPart == null) { - MPartDescriptor descriptor = findDescriptor(id); + MPartDescriptor descriptor = modelService.getPartDescriptor(id); sharedPart = createPart(descriptor); if (sharedPart == null) { return null; } + // Replace the id to ensure that multi-instance parts work correctly + sharedPart.setElementId(id); + sharedWindow.getSharedElements().add(sharedPart); } @@ -736,7 +730,30 @@ public class PartServiceImpl implements EPartService { * @see MPartDescriptor#isAllowMultiple() */ private MPart addPart(MPart providedPart, MPart localPart) { - MPartDescriptor descriptor = findDescriptor(providedPart.getElementId()); + + // If this is a multi-instance view see if there's a placeholder + int colonIndex = providedPart.getElementId().indexOf(':'); + if (colonIndex >= 0) { + String descId = providedPart.getElementId().substring(0, colonIndex); + descId += ":*"; //$NON-NLS-1$ + List<MPlaceholder> phList = modelService.findElements(workbenchWindow, descId, + MPlaceholder.class, null); + if (phList.size() > 0) { + MUIElement phParent = phList.get(0).getParent(); + if (phParent instanceof MPartStack) { + MPartStack theStack = (MPartStack) phParent; + adjustPlaceholder(providedPart); + MPlaceholder placeholder = providedPart.getCurSharedRef(); + if (placeholder == null) { + theStack.getChildren().add(providedPart); + } else { + theStack.getChildren().add(placeholder); + } + + } + } + } + MPartDescriptor descriptor = modelService.getPartDescriptor(providedPart.getElementId()); if (descriptor == null) { // there is no part descriptor backing the provided part, just add it to the container // if it's not already there @@ -965,7 +982,7 @@ public class PartServiceImpl implements EPartService { MPart part = findPart(id); if (part == null) { - MPartDescriptor descriptor = findDescriptor(id); + MPartDescriptor descriptor = modelService.getPartDescriptor(id); part = createPart(descriptor); if (part == null) { return null; diff --git a/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/workbench/modeling/EModelService.java b/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/workbench/modeling/EModelService.java index d31219e07e5..b2f7015cac7 100644 --- a/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/workbench/modeling/EModelService.java +++ b/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/workbench/modeling/EModelService.java @@ -13,6 +13,7 @@ package org.eclipse.e4.ui.workbench.modeling; import java.util.List; import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptor; import org.eclipse.e4.ui.model.application.ui.MElementContainer; import org.eclipse.e4.ui.model.application.ui.MSnippetContainer; import org.eclipse.e4.ui.model.application.ui.MUIElement; @@ -444,6 +445,23 @@ public interface EModelService { public int getElementLocation(MUIElement element); /** + * Returns the descriptor for the given part id. + * <p> + * <b>NOTE:</b> In order to support multiple instance parts there is a convention where the + * part's id may be in the form 'partId:secondaryId'. If the given id contains a ':' then only + * the substring before the ':' will be used to find the descriptor. + * </p> + * <p> + * In order to support this convention it's required that no descriptor contain a ':' in its id + * </p> + * + * @param id + * The id of the descriptor to return + * @return The descriptor matching the id or <code>null</code> if none exists + */ + public MPartDescriptor getPartDescriptor(String id); + + /** * This method ensures that there will never be two placeholders for the same referenced element * visible in the presentation at the same time. It does this by hiding placeholders which are * contained in any MPerspective if there is a placeholder for the element in any 'shared' area diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ViewReference.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ViewReference.java index f6fcaed5398..c6774941128 100644 --- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ViewReference.java +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ViewReference.java @@ -78,12 +78,12 @@ public class ViewReference extends WorkbenchPartReference implements IViewRefere public String getSecondaryId() { MPart part = getModel(); - for (String tag : part.getTags()) { - if (tag.startsWith(WorkbenchPage.SECONDARY_ID_HEADER)) { - return tag.substring(WorkbenchPage.SECONDARY_ID_HEADER.length()); - } - } - return null; + + int colonIndex = part.getElementId().indexOf(':'); + if (colonIndex == -1 || colonIndex == (part.getElementId().length() - 1)) + return null; + + return part.getElementId().substring(colonIndex + 1); } public IViewPart getView(boolean restore) { diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ViewSite.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ViewSite.java index 770719b76d5..de8e8019265 100644 --- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ViewSite.java +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/ViewSite.java @@ -37,13 +37,13 @@ public class ViewSite extends PartSite implements IViewSite { * @see org.eclipse.ui.IViewSite#getSecondaryId() */ public String getSecondaryId() { - for (String tag : model.getTags()) { - if (tag.startsWith(WorkbenchPage.SECONDARY_ID_HEADER)) { - return tag.substring(WorkbenchPage.SECONDARY_ID_HEADER.length()); - } + MPart part = getModel(); - } - return null; + int colonIndex = part.getElementId().indexOf(':'); + if (colonIndex == -1 || colonIndex == (part.getElementId().length() - 1)) + return null; + + return part.getElementId().substring(colonIndex + 1); } @Override diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/Workbench.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/Workbench.java index 39a1a89bd86..1cae7615e1f 100644 --- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/Workbench.java +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/Workbench.java @@ -1771,7 +1771,16 @@ UIEvents.Context.TOPIC_CONTEXT, private ViewReference createViewReference(MPart part, WorkbenchPage page) { WorkbenchWindow window = (WorkbenchWindow) page.getWorkbenchWindow(); - IViewDescriptor desc = window.getWorkbench().getViewRegistry().find(part.getElementId()); + + // If the partId contains a ':' then only use the substring before it to + // fine the descriptor + String partId = part.getElementId(); + + // If the id contains a ':' use the part before it as the descriptor id + int colonIndex = partId.indexOf(':'); + String descId = colonIndex == -1 ? partId : partId.substring(0, colonIndex); + + IViewDescriptor desc = window.getWorkbench().getViewRegistry().find(descId); ViewReference ref = new ViewReference(window.getModel().getContext(), page, part, (ViewDescriptor) desc); page.addViewReference(ref); diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPage.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPage.java index 41380c353bf..135cda9250b 100644 --- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPage.java +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPage.java @@ -159,8 +159,6 @@ import org.osgi.service.event.EventHandler; */ public class WorkbenchPage extends CompatibleWorkbenchPage implements IWorkbenchPage { - - static final String SECONDARY_ID_HEADER = "3x-secondary:"; //$NON-NLS-1$ class E4PartListener implements org.eclipse.e4.ui.workbench.modeling.IPartListener { @@ -1056,11 +1054,8 @@ public class WorkbenchPage extends CompatibleWorkbenchPage implements } private boolean contains(ViewReference reference) { - String id = reference.getId(); - String secondaryId = reference.getSecondaryId(); for (ViewReference viewReference : viewReferences) { - if (id.equals(viewReference.getId()) - && Util.equals(secondaryId, viewReference.getSecondaryId())) { + if (reference.getId().equals(viewReference.getId())) { return true; } } @@ -1078,12 +1073,7 @@ public class WorkbenchPage extends CompatibleWorkbenchPage implements } MPartDescriptor findDescriptor(String id) { - for (MPartDescriptor descriptor : application.getDescriptors()) { - if (descriptor.getElementId().equals(id)) { - return descriptor; - } - } - return null; + return modelService.getPartDescriptor(id); } /** @@ -1102,28 +1092,12 @@ public class WorkbenchPage extends CompatibleWorkbenchPage implements * workbench window * @see EModelService#findElements(MUIElement, String, Class, List, int) */ - private MPart findPart(String viewId, String secondaryId, int searchFlags) { - Collection<MPart> parts = modelService.findElements(getWindowModel(), viewId, MPart.class, - null, searchFlags); - if (secondaryId == null) { - partsLoop: for (MPart part : parts) { - if (part.getElementId().equals(viewId)) { - for (String tag : part.getTags()) { - if (tag.startsWith(SECONDARY_ID_HEADER)) { - continue partsLoop; - } - } + private MPart findPart(String viewId, int searchFlags) { + List<MPart> parts = modelService.findElements(getWindowModel(), viewId, MPart.class, null, + searchFlags); + if (parts.size() > 0) + return parts.get(0); - return part; - } - } - } - - for (MPart part : parts) { - if (part.getTags().contains(secondaryId)) { - return part; - } - } return null; } @@ -1139,14 +1113,13 @@ public class WorkbenchPage extends CompatibleWorkbenchPage implements throw new IllegalArgumentException(WorkbenchMessages.WorkbenchPage_IllegalViewMode); } - /** - * Shows a view. - * - * Assumes that a busy cursor is active. - */ - protected IViewPart busyShowView(String viewId, String secondaryId, int mode) - throws PartInitException { - switch (mode) { + /** + * Shows a view. + * + * Assumes that a busy cursor is active. + */ + protected IViewPart busyShowView(String viewId, int mode) throws PartInitException { + switch (mode) { case VIEW_ACTIVATE: case VIEW_VISIBLE: case VIEW_CREATE: @@ -1155,27 +1128,9 @@ public class WorkbenchPage extends CompatibleWorkbenchPage implements throw new IllegalArgumentException(WorkbenchMessages.WorkbenchPage_IllegalViewMode); } - if (secondaryId != null) { - if (secondaryId.length() == 0 || secondaryId.indexOf(':') != -1) { - throw new IllegalArgumentException( - WorkbenchMessages.WorkbenchPage_IllegalSecondaryId); - } - - secondaryId = SECONDARY_ID_HEADER + secondaryId; - - MPartDescriptor descriptor = findDescriptor(viewId); - if (descriptor == null) { - throw new PartInitException(NLS.bind(WorkbenchMessages.ViewFactory_couldNotCreate, - viewId)); - } else if (!descriptor.isAllowMultiple()) { - throw new PartInitException(NLS.bind(WorkbenchMessages.ViewFactory_noMultiple, - viewId)); - } - } - - MPart part = findPart(viewId, secondaryId, EModelService.ANYWHERE); + MPart part = findPart(viewId, EModelService.ANYWHERE); if (part == null) { - MPlaceholder ph = partService.createSharedPart(viewId, secondaryId != null); + MPlaceholder ph = partService.createSharedPart(viewId, false); if (ph == null) { throw new PartInitException(NLS.bind(WorkbenchMessages.ViewFactory_couldNotCreate, viewId)); @@ -1184,10 +1139,6 @@ public class WorkbenchPage extends CompatibleWorkbenchPage implements part = (MPart) ph.getRef(); part.setCurSharedRef(ph); - if (secondaryId != null) { - part.getTags().add(secondaryId); - } - part = showPart(mode, part); CompatibilityView compatibilityView = (CompatibilityView) part.getObject(); @@ -1203,10 +1154,6 @@ public class WorkbenchPage extends CompatibleWorkbenchPage implements part = showPart(mode, part); - if (secondaryId != null) { - part.getTags().add(secondaryId); - } - CompatibilityView compatibilityView = (CompatibilityView) part.getObject(); if (compatibilityView != null) { @@ -1216,9 +1163,8 @@ public class WorkbenchPage extends CompatibleWorkbenchPage implements legacyWindow.firePerspectiveChanged(this, getPerspective(), CHANGE_VIEW_SHOW); } return compatibilityView.getView(); - - } + } private MPart showPart(int mode, MPart part) { switch (mode) { case VIEW_ACTIVATE: @@ -1956,7 +1902,11 @@ public class WorkbenchPage extends CompatibleWorkbenchPage implements } public void createViewReferenceForPart(final MPart part, String viewId) { - IViewDescriptor desc = getWorkbenchWindow().getWorkbench().getViewRegistry().find(viewId); + // If the id contains a ':' use the part before it as the descriptor id + int colonIndex = viewId.indexOf(':'); + String descId = colonIndex == -1 ? viewId : viewId.substring(0, colonIndex); + + IViewDescriptor desc = getWorkbenchWindow().getWorkbench().getViewRegistry().find(descId); final ViewReference ref = new ViewReference(window.getContext(), this, part, (ViewDescriptor) desc); if (contains(ref)) { @@ -1972,7 +1922,6 @@ public class WorkbenchPage extends CompatibleWorkbenchPage implements addViewReference(ref); } - /** * Notify property change listeners about a property change. * @@ -3770,38 +3719,39 @@ public class WorkbenchPage extends CompatibleWorkbenchPage implements * @see org.eclipse.ui.IWorkbenchPage#showView(java.lang.String, * java.lang.String, int) */ - public IViewPart showView(final String viewID, final String secondaryID, - final int mode) throws PartInitException { - - if (secondaryID != null) { - if (secondaryID.length() == 0 - || secondaryID.indexOf(":") != -1) { //$NON-NLS-1$ - throw new IllegalArgumentException(WorkbenchMessages.WorkbenchPage_IllegalSecondaryId); - } - } - if (!certifyMode(mode)) { + public IViewPart showView(final String viewID, final String secondaryID, final int mode) + throws PartInitException { + + if (secondaryID != null) { + if (secondaryID.length() == 0 || secondaryID.indexOf(":") != -1) { //$NON-NLS-1$ + throw new IllegalArgumentException( + WorkbenchMessages.WorkbenchPage_IllegalSecondaryId); + } + } + if (!certifyMode(mode)) { throw new IllegalArgumentException(WorkbenchMessages.WorkbenchPage_IllegalViewMode); } - // Run op in busy cursor. - final Object[] result = new Object[1]; - BusyIndicator.showWhile(null, new Runnable() { - public void run() { - try { - result[0] = busyShowView(viewID, secondaryID, mode); - } catch (PartInitException e) { - result[0] = e; - } - } - }); - if (result[0] instanceof IViewPart) { + // Run op in busy cursor. + final String compoundId = secondaryID != null ? viewID + ':' + secondaryID : viewID; + final Object[] result = new Object[1]; + BusyIndicator.showWhile(null, new Runnable() { + public void run() { + try { + result[0] = busyShowView(compoundId, mode); + } catch (PartInitException e) { + result[0] = e; + } + } + }); + if (result[0] instanceof IViewPart) { return (IViewPart) result[0]; } else if (result[0] instanceof PartInitException) { throw (PartInitException) result[0]; } else { throw new PartInitException(WorkbenchMessages.WorkbenchPage_AbnormalWorkbenchCondition); - } - } + } + } /** * @param mode the mode to test 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 6bd08d1d066..3efe1c3a108 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 @@ -354,28 +354,28 @@ public class ModeledPageLayout implements IPageLayout { public static MStackElement createViewModel(MApplication application, String id, boolean visible, WorkbenchPage page, EPartService partService, boolean createReferences) { - for (MPartDescriptor descriptor : application.getDescriptors()) { - if (descriptor.getElementId().equals(id)) { - MPlaceholder ph = partService.createSharedPart(id); - ph.setToBeRendered(visible); - - MPart part = (MPart) (ph.getRef()); - // as a shared part, this should be true, actual un/rendering - // will be dependent on any placeholders that are referencing - // this part - part.setToBeRendered(true); - - // there should only be view references for 3.x views that are - // visible to the end user, that is, the tab items are being - // drawn - if (visible - && createReferences - && CompatibilityPart.COMPATIBILITY_VIEW_URI.equals(descriptor - .getContributionURI())) { - page.createViewReferenceForPart(part, id); - } - return ph; + EModelService ms = application.getContext().get(EModelService.class); + MPartDescriptor partDesc = ms.getPartDescriptor(id); + if (partDesc != null) { + MPlaceholder ph = partService.createSharedPart(id); + ph.setToBeRendered(visible); + + MPart part = (MPart) (ph.getRef()); + // as a shared part, this should be true, actual un/rendering + // will be dependent on any placeholders that are referencing + // this part + part.setToBeRendered(true); + + // there should only be view references for 3.x views that are + // visible to the end user, that is, the tab items are being + // drawn + if (visible + && createReferences + && CompatibilityPart.COMPATIBILITY_VIEW_URI.equals(partDesc + .getContributionURI())) { + page.createViewReferenceForPart(part, id); } + return ph; } return null; } diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/compatibility/ModeledPlaceholderFolderLayout.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/compatibility/ModeledPlaceholderFolderLayout.java index 2c3f687049e..f385fe687df 100644 --- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/compatibility/ModeledPlaceholderFolderLayout.java +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/e4/compatibility/ModeledPlaceholderFolderLayout.java @@ -34,7 +34,7 @@ public class ModeledPlaceholderFolderLayout implements IPlaceholderFolderLayout } public void addPlaceholder(String viewId) { - boolean containsWildcards = viewId.indexOf('*') != -1 || viewId.indexOf('?') != -1; + boolean containsWildcards = viewId.indexOf('?') != -1; if (containsWildcards) { E4Util.unsupported("IPageLayout.addPlacehoder(): wildcard in view id: " + viewId); //$NON-NLS-1$ return; |
