@Override public boolean isPartVisible(MPart part) { if (isInContainer(part)) { MUIElement element = part; MElementContainer<?> parent = part.getParent(); if (parent == null) { // might be a shared part element = part.getCurSharedRef(); if (element == null) { return false; } parent = element.getParent(); if (parent == null) { return false; } } if (parent instanceof MPartStack) { return parent.getSelectedElement() == element; } return element.isVisible(); } return false; }
@Override public MPart showPart(MPart part, PartState partState) { Assert.isNotNull(part); Assert.isNotNull(partState); MPart addedPart = addPart(part); MPlaceholder localPlaceholder = getLocalPlaceholder(addedPart); // correct the placeholder setting if necessary if (localPlaceholder != null && addedPart.getCurSharedRef() != localPlaceholder) { addedPart.setCurSharedRef(localPlaceholder); } switch (partState) { case ACTIVATE: activate(addedPart); return addedPart; case VISIBLE: MPart activePart = getActivePart(); if (activePart == null || (activePart != addedPart && getParent(activePart) == getParent(addedPart))) { delegateBringToTop(addedPart); activate(addedPart); } else { bringToTop(addedPart); } return addedPart; case CREATE: createElement(addedPart); return addedPart; } return addedPart; }
private void addToLastContainer(String category, MPart part) { // OK, we haven't found an explicit placeholder; // If this is a multi-instance view see if there's a 'global' placeholder String partId = part.getElementId(); int colonIndex = partId == null ? -1 : partId.indexOf(':'); if (colonIndex >= 0) { String descId = part.getElementId().substring(0, colonIndex); descId += ":*"; // $NON-NLS-1$ List<MPlaceholder> phList = modelService.findElements( workbenchWindow, descId, MPlaceholder.class, null, EModelService.PRESENTATION); if (phList.size() > 0) { MUIElement phParent = phList.get(0).getParent(); if (phParent instanceof MPartStack) { MPartStack theStack = (MPartStack) phParent; int phIndex = theStack.getChildren().indexOf(phList.get(0)); adjustPlaceholder(part); MPlaceholder placeholder = part.getCurSharedRef(); if (placeholder == null) { theStack.getChildren().add(phIndex, part); } else { theStack.getChildren().add(phIndex, placeholder); } return; } } } @SuppressWarnings("unchecked") MElementContainer<MUIElement> lastContainer = (MElementContainer<MUIElement>) getLastContainer(); MPlaceholder placeholder = part.getCurSharedRef(); if (placeholder == null) { lastContainer.getChildren().add(part); } else { lastContainer.getChildren().add(placeholder); } if (category != null) { lastContainer.getTags().add(category); } }
private void adjustPlaceholder(MPart part) { if (isShared(part)) { MPlaceholder placeholder = part.getCurSharedRef(); // if this part doesn't have any placeholders, we need to make one if (placeholder == null // alternatively, if it has one but it's not in the current container, then we // need to spawn another one as we don't want to reuse the same one and end up // shifting that placeholder to the current container during the add operation || (placeholder.getParent() != null && !isInContainer(placeholder))) { placeholder = createSharedPart(part); part.setCurSharedRef(placeholder); } } }
/** * Records the specified parent part's selected element in the activation history if the parent is * a stack. * * @param part the part whose parent's selected element should be checked for activation history * recording */ private void recordStackActivation(MPart part) { MElementContainer<? extends MUIElement> parent = part.getParent(); if (parent instanceof MGenericStack) { recordSelectedActivation(parent); } else if (parent == null) { MPlaceholder placeholder = part.getCurSharedRef(); if (placeholder != null) { parent = placeholder.getParent(); if (parent instanceof MGenericStack) { recordSelectedActivation(parent); } } } }
/** * Adds a part to the current container if it isn't already in the container. The part may still * be added to the container if the part supports having multiple copies of itself in a given * container. * * @param providedPart the part to add * @param localPart a part that shares attributes with <code>providedPart</code>, for example, it * may have been backed by the same part descriptor, this part may already be in the current * container * @return a part that has been added to the current container, note that this may not necessarily * be <code>providedPart</code> * @see MPartDescriptor#isAllowMultiple() */ private MPart addPart(MPart providedPart, MPart localPart) { 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 if (!isInContainer(providedPart)) { adjustPlaceholder(providedPart); addToLastContainer(null, providedPart); } } else { if (providedPart != localPart && !descriptor.isAllowMultiple()) { // multiple copies of this part are not allowed, just return the local one return localPart; } // already in the container, return as is if (isInContainer(providedPart)) { return providedPart; } // corrects this part's placeholder if necessary adjustPlaceholder(providedPart); String category = descriptor.getCategory(); if (category == null) { // no category, just add it to the end addToLastContainer(null, providedPart); } else { if ("org.eclipse.e4.primaryDataStack".equals(category)) { // $NON-NLS-1$ MElementContainer<? extends MUIElement> container = getContainer(); MUIElement area = modelService.find("org.eclipse.ui.editorss", container); // $NON-NLS-1$ MPartStack activeStack = null; if (area instanceof MPlaceholder && ((MPlaceholder) area).getRef() instanceof MArea) { // Find the currently 'active' stack in the area MArea a = (MArea) ((MPlaceholder) area).getRef(); MUIElement curActive = a.getSelectedElement(); while (curActive instanceof MElementContainer<?>) { if (curActive instanceof MPartStack) { activeStack = (MPartStack) curActive; break; } MElementContainer<?> curContainer = (MElementContainer<?>) curActive; curActive = curContainer.getSelectedElement(); } } if (activeStack != null) { activeStack.getChildren().add(providedPart); } else { // Find the first visible stack in the area List<MPartStack> sharedStacks = modelService.findElements(area, null, MPartStack.class, null); if (sharedStacks.size() > 0) { for (MPartStack stack : sharedStacks) { if (stack.isToBeRendered()) { stack.getChildren().add(providedPart); break; } } } else { addToLastContainer(null, providedPart); } } } else { @SuppressWarnings("rawtypes") List<MElementContainer> containers = modelService.findElements( getContainer(), null, MElementContainer.class, Collections.singletonList(category), EModelService.PRESENTATION); if (containers.isEmpty()) { // couldn't find any containers with the specified tag, just add it to the // end addToLastContainer(category, providedPart); } else { // add the part to the container MElementContainer<MPartSashContainerElement> container = containers.get(0); MPlaceholder placeholder = providedPart.getCurSharedRef(); if (placeholder == null) { container.getChildren().add(providedPart); } else { container.getChildren().add(placeholder); } } } } } return providedPart; }
@Override public void hidePart(MPart part, boolean force) { if (isInContainer(part)) { MPlaceholder sharedRef = part.getCurSharedRef(); MUIElement toBeRemoved = getRemoveTarget(part); MElementContainer<MUIElement> parent = getParent(toBeRemoved); List<MUIElement> children = parent.getChildren(); // check if we're a placeholder but not actually the shared ref of the part if (toBeRemoved != part && toBeRemoved instanceof MPlaceholder && sharedRef != toBeRemoved) { toBeRemoved.setToBeRendered(false); // if so, not much to do, remove ourselves if necessary but that's it if (force || part.getTags().contains(REMOVE_ON_HIDE_TAG)) { parent.getChildren().remove(toBeRemoved); } return; } boolean isActiveChild = isActiveChild(part); MPart activationCandidate = null; // check if we're the active child if (isActiveChild) { // get the activation candidate if we are activationCandidate = partActivationHistory.getNextActivationCandidate(getParts(), part); } MPerspective thePersp = modelService.getPerspectiveFor(toBeRemoved); boolean needNewSel = thePersp == null || !thePersp.getTags().contains("PerspClosing"); // $NON-NLS-1$ if (needNewSel) { if (parent.getSelectedElement() == toBeRemoved) { // if we're the selected element and we're going to be hidden, need to select // something else MUIElement candidate = partActivationHistory.getSiblingSelectionCandidate(part); candidate = candidate == null ? null : candidate.getCurSharedRef() == null ? candidate : candidate.getCurSharedRef(); if (candidate != null && children.contains(candidate)) { parent.setSelectedElement(candidate); } else { for (MUIElement child : children) { if (child != toBeRemoved && child.isToBeRendered()) { parent.setSelectedElement(child); break; } } } } if (activationCandidate == null) { // nothing else to activate and we're the active child, deactivate if (isActiveChild) { part.getContext().deactivate(); } } else { // activate our candidate activate(activationCandidate); } } if (toBeRemoved != null) { toBeRemoved.setToBeRendered(false); } else { part.setToBeRendered(false); } if (parent.getSelectedElement() == toBeRemoved) { parent.setSelectedElement(null); } if (force || part.getTags().contains(REMOVE_ON_HIDE_TAG)) { children.remove(toBeRemoved); } // remove ourselves from the activation history also since we're being hidden partActivationHistory.forget(getWindow(), part, toBeRemoved == part); } }