Bug 400276 - Errors when removing or moving multiple parts from/between stacks
Fix StackRenderer to handle the case from an ADD_MANY where a
collection of new parts may have been added to a part stack. Fix
CleanupAddon to handle REMOVE_MANY.
Also fixed two other locations to do with ADD_MANY/REMOVE_MANY.
* Workbench to handle REMOVE_MANY for multiple perspectives
* MinMaxAddon to also handle REMOVE_MANY of multiple stacks
from the trim bars
Added references to UIEvents to ADD_MANY/REMOVE_MANY to hint
for developers to consider ADD/ADD_MANY and REMOVE/REMOVE_MANY.
diff --git a/bundles/org.eclipse.e4.ui.workbench.addons.swt/src/org/eclipse/e4/ui/workbench/addons/cleanupaddon/CleanupAddon.java b/bundles/org.eclipse.e4.ui.workbench.addons.swt/src/org/eclipse/e4/ui/workbench/addons/cleanupaddon/CleanupAddon.java
index 93f07e9..56fcc60 100644
--- a/bundles/org.eclipse.e4.ui.workbench.addons.swt/src/org/eclipse/e4/ui/workbench/addons/cleanupaddon/CleanupAddon.java
+++ b/bundles/org.eclipse.e4.ui.workbench.addons.swt/src/org/eclipse/e4/ui/workbench/addons/cleanupaddon/CleanupAddon.java
@@ -55,8 +55,7 @@
private EventHandler childrenHandler = new EventHandler() {
public void handleEvent(Event event) {
Object changedObj = event.getProperty(UIEvents.EventTags.ELEMENT);
- String eventType = (String) event.getProperty(UIEvents.EventTags.TYPE);
- if (UIEvents.EventTypes.REMOVE.equals(eventType)) {
+ if (UIEvents.isREMOVE(event)) {
final MElementContainer<?> container = (MElementContainer<?>) changedObj;
MUIElement containerParent = container.getParent();
diff --git a/bundles/org.eclipse.e4.ui.workbench.addons.swt/src/org/eclipse/e4/ui/workbench/addons/minmax/MinMaxAddon.java b/bundles/org.eclipse.e4.ui.workbench.addons.swt/src/org/eclipse/e4/ui/workbench/addons/minmax/MinMaxAddon.java
index 137457e..97c05bd 100644
--- a/bundles/org.eclipse.e4.ui.workbench.addons.swt/src/org/eclipse/e4/ui/workbench/addons/minmax/MinMaxAddon.java
+++ b/bundles/org.eclipse.e4.ui.workbench.addons.swt/src/org/eclipse/e4/ui/workbench/addons/minmax/MinMaxAddon.java
@@ -407,26 +407,28 @@
|| modelService.getTopLevelWindowFor(changedElement) == null)
return;
- String eventType = (String) event.getProperty(UIEvents.EventTags.TYPE);
- if (UIEvents.EventTypes.REMOVE.equals(eventType)) {
- MUIElement removed = (MUIElement) event.getProperty(UIEvents.EventTags.OLD_VALUE);
- String perspectiveId = removed.getElementId();
- MWindow window = modelService.getTopLevelWindowFor(changedElement);
- MTrimBar bar = modelService.getTrim((MTrimmedWindow) window, SideValue.TOP);
+ if (UIEvents.isREMOVE(event)) {
+ for (Object removedElement : UIEvents.asIterable(event,
+ UIEvents.EventTags.OLD_VALUE)) {
+ MUIElement removed = (MUIElement) removedElement;
+ String perspectiveId = removed.getElementId();
+ MWindow window = modelService.getTopLevelWindowFor(changedElement);
+ MTrimBar bar = modelService.getTrim((MTrimmedWindow) window, SideValue.TOP);
- // gather up any minimized stacks for this perspective...
- List<MToolControl> toRemove = new ArrayList<MToolControl>();
- for (MUIElement child : bar.getChildren()) {
- String trimElementId = child.getElementId();
- if (child instanceof MToolControl && trimElementId.contains(perspectiveId)) {
- toRemove.add((MToolControl) child);
+ // gather up any minimized stacks for this perspective...
+ List<MToolControl> toRemove = new ArrayList<MToolControl>();
+ for (MUIElement child : bar.getChildren()) {
+ String trimElementId = child.getElementId();
+ if (child instanceof MToolControl && trimElementId.contains(perspectiveId)) {
+ toRemove.add((MToolControl) child);
+ }
}
- }
- // ...and remove them
- for (MToolControl minStack : toRemove) {
- minStack.setToBeRendered(false);
- bar.getChildren().remove(minStack);
+ // ...and remove them
+ for (MToolControl minStack : toRemove) {
+ minStack.setToBeRendered(false);
+ bar.getChildren().remove(minStack);
+ }
}
}
}
diff --git a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/StackRenderer.java b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/StackRenderer.java
index a67d495..eb092f5 100644
--- a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/StackRenderer.java
+++ b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/StackRenderer.java
@@ -764,8 +764,9 @@
createFlags |= SWT.CLOSE;
}
- // Create the tab
- int index = calcIndexFor(stack, element);
+ // Create the tab; we may have more visible tabs than currently shown
+ // (e.g., a result of calling partStack.getChildren().addAll(partList))
+ int index = Math.min(calcIndexFor(stack, element), ctf.getItemCount());
cti = new CTabItem(ctf, createFlags, index);
cti.setData(OWNING_ME, element);
diff --git a/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/workbench/UIEvents.java b/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/workbench/UIEvents.java
index 2bd62a5..0e3f266 100644
--- a/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/workbench/UIEvents.java
+++ b/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/workbench/UIEvents.java
@@ -65,21 +65,29 @@
*/
public static final String SET = "SET"; //$NON-NLS-1$
/**
- * Add event: value added is {@link EventTags#NEW_VALUE}
+ * Add event: value added is {@link EventTags#NEW_VALUE}.
+ *
+ * @see UIEvents#isADD(Event)
*/
public static final String ADD = "ADD"; //$NON-NLS-1$
/**
* Add many items: values added are {@link EventTags#NEW_VALUE}
+ *
+ * @see UIEvents#isADD(Event)
*/
public static final String ADD_MANY = "ADD_MANY";//$NON-NLS-1$
/**
* Remove event: value removed is {@link EventTags#OLD_VALUE}
+ *
+ * @see UIEvents#isREMOVE(Event)
*/
public static final String REMOVE = "REMOVE"; //$NON-NLS-1$
/**
* Remove many event: the values removed are the {@link EventTags#OLD_VALUE} (a collection).
* The former positions of the removed values are provided as an integer array in
* {@link EventTags#POSITION}.
+ *
+ * @see UIEvents#isREMOVE(Event)
*/
public static final String REMOVE_MANY = "REMOVE_MANY"; //$NON-NLS-1$
/**
@@ -94,6 +102,8 @@
* An OSGI event representing a UIEvent
* @return true if it is an add event (i.e., {@link EventTypes#ADD} or
* {@link EventTypes#ADD_MANY}), or false otherwise.
+ * @see UIEvents.EventTags#NEW_VALUE
+ * @see #asIterable(Event, String)
*/
public static boolean isADD(Event event) {
Object type = event.getProperty(UIEvents.EventTags.TYPE);
@@ -105,6 +115,8 @@
* An OSGI event representing a UIEvent
* @return true if it is a remove event (i.e., {@link EventTypes#REMOVE} or
* {@link EventTypes#REMOVE_MANY}), or false otherwise.
+ * @see UIEvents.EventTags#OLD_VALUE
+ * @see #asIterable(Event, String)
*/
public static boolean isREMOVE(Event event) {
Object type = event.getProperty(UIEvents.EventTags.TYPE);
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 9763f83..a6694f6 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
@@ -1733,15 +1733,17 @@
eventBroker.subscribe(UIEvents.ElementContainer.TOPIC_CHILDREN, new EventHandler() {
public void handleEvent(org.osgi.service.event.Event event) {
if (application == event.getProperty(UIEvents.EventTags.ELEMENT)) {
- if (UIEvents.EventTypes.REMOVE.equals(event
- .getProperty(UIEvents.EventTags.TYPE))) {
- MWindow window = (MWindow) event.getProperty(UIEvents.EventTags.OLD_VALUE);
- IEclipseContext windowContext = window.getContext();
- if (windowContext != null) {
- IWorkbenchWindow wwindow = (IWorkbenchWindow) windowContext
- .get(IWorkbenchWindow.class.getName());
- if (wwindow != null) {
- fireWindowClosed(wwindow);
+ if (UIEvents.isREMOVE(event)) {
+ for (Object removed : UIEvents.asIterable(event,
+ UIEvents.EventTags.OLD_VALUE)) {
+ MWindow window = (MWindow) removed;
+ IEclipseContext windowContext = window.getContext();
+ if (windowContext != null) {
+ IWorkbenchWindow wwindow = (IWorkbenchWindow) windowContext
+ .get(IWorkbenchWindow.class.getName());
+ if (wwindow != null) {
+ fireWindowClosed(wwindow);
+ }
}
}
}