Fix for Bug 341009 - Can't drag Outline view back to its original position. Implement the 'drag last tab == drag stack' metaphor.
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 aa98678..63ac2a7 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
@@ -11,7 +11,6 @@
package org.eclipse.e4.ui.workbench.addons.cleanupaddon;
-import java.util.List;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
@@ -25,7 +24,6 @@
import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective;
import org.eclipse.e4.ui.model.application.ui.advanced.MPerspectiveStack;
import org.eclipse.e4.ui.model.application.ui.basic.MPartSashContainer;
-import org.eclipse.e4.ui.model.application.ui.basic.MPartStack;
import org.eclipse.e4.ui.model.application.ui.basic.MTrimBar;
import org.eclipse.e4.ui.model.application.ui.basic.MWindow;
import org.eclipse.e4.ui.model.application.ui.menu.MMenuElement;
@@ -300,24 +298,6 @@
}
boolean isLastEditorStack(MUIElement element) {
- if (!(element instanceof MPartStack))
- return false;
-
- // is it in the shared area?
- MUIElement parent = element.getParent();
- while (parent != null && !(parent instanceof MArea))
- parent = parent.getParent();
- if (parent == null)
- return false;
-
- // OK, it's in the area, is it the last TBR one ?
- MArea area = (MArea) parent;
- List<MPartStack> stacks = modelService.findElements(area, null, MPartStack.class, null);
- int count = 0;
- for (MPartStack stack : stacks) {
- if (stack.isToBeRendered())
- count++;
- }
- return count < 2;
+ return modelService.isLastEditorStack(element);
}
}
diff --git a/bundles/org.eclipse.e4.ui.workbench.addons.swt/src/org/eclipse/e4/ui/workbench/addons/dndaddon/PartDragAgent.java b/bundles/org.eclipse.e4.ui.workbench.addons.swt/src/org/eclipse/e4/ui/workbench/addons/dndaddon/PartDragAgent.java
index b860192..61f1dcf 100644
--- a/bundles/org.eclipse.e4.ui.workbench.addons.swt/src/org/eclipse/e4/ui/workbench/addons/dndaddon/PartDragAgent.java
+++ b/bundles/org.eclipse.e4.ui.workbench.addons.swt/src/org/eclipse/e4/ui/workbench/addons/dndaddon/PartDragAgent.java
@@ -12,10 +12,9 @@
package org.eclipse.e4.ui.workbench.addons.dndaddon;
import org.eclipse.e4.ui.model.application.ui.MUIElement;
-import org.eclipse.e4.ui.model.application.ui.advanced.MArea;
-import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.model.application.ui.basic.MPartStack;
+import org.eclipse.e4.ui.model.application.ui.basic.MStackElement;
import org.eclipse.e4.ui.widgets.CTabFolder;
import org.eclipse.e4.ui.workbench.IPresentationEngine;
import org.eclipse.e4.ui.workbench.modeling.EPartService;
@@ -38,43 +37,45 @@
*/
@Override
public MUIElement getElementToDrag(DnDInfo info) {
+ if (!(info.curElement instanceof MPartStack))
+ return null;
+
+ MPartStack stack = (MPartStack) info.curElement;
+
// Drag a part that is in a stack
- if (info.curElement instanceof MPartStack
- && (info.itemElement instanceof MPlaceholder || info.itemElement instanceof MPart)) {
+ if (info.itemElement instanceof MStackElement) {
// Prevent dragging 'No Move' parts
if (info.itemElement.getTags().contains(IPresentationEngine.NO_MOVE))
return null;
- dragElement = info.itemElement;
- return info.itemElement;
+ int tbrCount = dndManager.getModelService().countRenderableChildren(stack);
+ if (tbrCount > 1 || dndManager.getModelService().isLastEditorStack(stack)) {
+ dragElement = info.itemElement;
+ return info.itemElement;
+ }
}
// Drag a complete stack
- if (info.curElement instanceof MPartStack && info.itemElement == null) {
- // Only allow a drag to start if we're a CTabFolder
- if (!(info.curElement.getWidget() instanceof CTabFolder))
- return null;
+ // Only allow a drag to start if we're a CTabFolder
+ if (!(stack.getWidget() instanceof CTabFolder))
+ return null;
- // Only allow a drag to start if we're inside the 'tab area' of the CTF
- CTabFolder ctf = (CTabFolder) info.curElement.getWidget();
- Point ctfPos = ctf.getDisplay().map(null, ctf, info.cursorPos);
- if (ctfPos.y > ctf.getTabHeight())
- return null;
+ // Only allow a drag to start if we're inside the 'tab area' of the CTF
+ CTabFolder ctf = (CTabFolder) stack.getWidget();
+ Point ctfPos = ctf.getDisplay().map(null, ctf, info.cursorPos);
+ if (ctfPos.y > ctf.getTabHeight())
+ return null;
- // Prevent dragging 'No Move' stacks
- if (info.curElement.getTags().contains(IPresentationEngine.NO_MOVE))
- return null;
+ // Prevent dragging 'No Move' stacks
+ if (stack.getTags().contains(IPresentationEngine.NO_MOVE))
+ return null;
- // Prevent dragging the last stack out of the shared area
- MUIElement parent = info.curElement.getParent();
- if (parent instanceof MArea)
- return null;
+ // Prevent dragging the last stack out of the shared area
+ if (dndManager.getModelService().isLastEditorStack(stack))
+ return null;
- dragElement = info.curElement;
- return info.curElement;
- }
-
- return null;
+ dragElement = info.curElement;
+ return info.curElement;
}
/*
diff --git a/bundles/org.eclipse.e4.ui.workbench.addons.swt/src/org/eclipse/e4/ui/workbench/addons/dndaddon/SplitDropAgent.java b/bundles/org.eclipse.e4.ui.workbench.addons.swt/src/org/eclipse/e4/ui/workbench/addons/dndaddon/SplitDropAgent.java
index 5f9d3f8..cb3c8c2 100644
--- a/bundles/org.eclipse.e4.ui.workbench.addons.swt/src/org/eclipse/e4/ui/workbench/addons/dndaddon/SplitDropAgent.java
+++ b/bundles/org.eclipse.e4.ui.workbench.addons.swt/src/org/eclipse/e4/ui/workbench/addons/dndaddon/SplitDropAgent.java
@@ -59,20 +59,33 @@
if (!(dragElement instanceof MStackElement) && !(dragElement instanceof MPartStack))
return false;
- if (!(info.curElement instanceof MStackElement))
- return false;
+ dropStack = null;
- // Detect placeholders
- MUIElement parent = info.curElement.getParent();
- if (info.curElement instanceof MPart && info.curElement.getCurSharedRef() != null)
- parent = info.curElement.getCurSharedRef().getParent();
+ // Hack! allow splitting the 'empty' editor area stack
+ if (info.curElement instanceof MPartStack) {
+ MPartStack stack = (MPartStack) info.curElement;
+ if (dndManager.getModelService().isLastEditorStack(stack))
+ dropStack = stack;
+ }
- if (!(parent instanceof MPartStack) || !(parent.getWidget() instanceof CTabFolder))
- return false;
+ if (dropStack == null) {
+ if (!(info.curElement instanceof MStackElement)
+ && !dndManager.getModelService().isLastEditorStack(info.curElement))
+ return false;
- dropStack = (MPartStack) parent;
+ // Detect placeholders
+ MUIElement parent = info.curElement.getParent();
+ if (info.curElement instanceof MPart && info.curElement.getCurSharedRef() != null)
+ parent = info.curElement.getCurSharedRef().getParent();
+
+ if (!(parent instanceof MPartStack) || !(parent.getWidget() instanceof CTabFolder))
+ return false;
+
+ dropStack = (MPartStack) parent;
+ }
+
weight = dropStack.getContainerData();
- dropCTF = (CTabFolder) parent.getWidget();
+ dropCTF = (CTabFolder) dropStack.getWidget();
return true;
}
diff --git a/bundles/org.eclipse.e4.ui.workbench.addons.swt/src/org/eclipse/e4/ui/workbench/addons/dndaddon/StackDropAgent.java b/bundles/org.eclipse.e4.ui.workbench.addons.swt/src/org/eclipse/e4/ui/workbench/addons/dndaddon/StackDropAgent.java
index a5a34bf..9ea16ab 100644
--- a/bundles/org.eclipse.e4.ui.workbench.addons.swt/src/org/eclipse/e4/ui/workbench/addons/dndaddon/StackDropAgent.java
+++ b/bundles/org.eclipse.e4.ui.workbench.addons.swt/src/org/eclipse/e4/ui/workbench/addons/dndaddon/StackDropAgent.java
@@ -12,6 +12,7 @@
package org.eclipse.e4.ui.workbench.addons.dndaddon;
import java.util.ArrayList;
+import java.util.List;
import org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer;
import org.eclipse.e4.ui.model.application.ui.MUIElement;
import org.eclipse.e4.ui.model.application.ui.basic.MPartStack;
@@ -43,23 +44,34 @@
@Override
public boolean canDrop(MUIElement dragElement, DnDInfo info) {
- if (!(dragElement instanceof MStackElement))
+ // We only except stack elements and whole stacks
+ if (!(dragElement instanceof MStackElement) && !(dragElement instanceof MPartStack))
return false;
- if (info.curElement instanceof MPartStack
- && info.curElement.getWidget() instanceof CTabFolder) {
- Rectangle areaRect = getTabAreaRect((CTabFolder) info.curElement.getWidget());
- boolean inArea = areaRect.contains(info.cursorPos);
- if (inArea) {
- tabArea = areaRect;
- dropStack = (MPartStack) info.curElement;
- dropCTF = (CTabFolder) dropStack.getWidget();
- createInsertRects();
- }
- return inArea;
- }
+ // We have to be over a stack ourselves
+ if (!(info.curElement instanceof MPartStack))
+ return false;
- return false;
+ MPartStack stack = (MPartStack) info.curElement;
+
+ // We only work for CTabFolders
+ if (!(stack.getWidget() instanceof CTabFolder))
+ return false;
+
+ // We can't drop stacks onto itself
+ if (stack == dragElement)
+ return false;
+
+ // only allow dropping into the the area
+ Rectangle areaRect = getTabAreaRect((CTabFolder) stack.getWidget());
+ boolean inArea = areaRect.contains(info.cursorPos);
+ if (inArea) {
+ tabArea = areaRect;
+ dropStack = (MPartStack) info.curElement;
+ dropCTF = (CTabFolder) dropStack.getWidget();
+ createInsertRects();
+ }
+ return inArea;
}
private Rectangle getTabAreaRect(CTabFolder theCTF) {
@@ -175,7 +187,7 @@
itemBounds = Display.getCurrent().map(dropCTF, null, itemBounds);
dndManager.frameRect(itemBounds);
} else {
- Rectangle fr = tabArea;
+ Rectangle fr = new Rectangle(tabArea.x, tabArea.y, tabArea.width, tabArea.height);
fr.width = 2;
dndManager.frameRect(fr);
}
@@ -197,7 +209,7 @@
private void dock(MUIElement dragElement, int dropIndex) {
// Adjust the index if necessary
int elementIndex = dropStack.getChildren().indexOf(dragElement);
- if (elementIndex != -1) {
+ if (elementIndex != -1 && !(dragElement instanceof MPartStack)) {
// Get the index of this CTF entry
Control dragCtrl = (Control) dragElement.getWidget();
for (CTabItem cti : dropCTF.getItems()) {
@@ -209,13 +221,31 @@
}
}
- if (dragElement.getParent() != null)
- dragElement.getParent().getChildren().remove(dragElement);
- if (dropIndex >= 0 && dropIndex < dropStack.getChildren().size())
- dropStack.getChildren().add(dropIndex, (MStackElement) dragElement);
- else
- dropStack.getChildren().add((MStackElement) dragElement);
- dropStack.setSelectedElement((MStackElement) dragElement);
+ if (dragElement instanceof MStackElement) {
+ if (dragElement.getParent() != null)
+ dragElement.getParent().getChildren().remove(dragElement);
+ if (dropIndex >= 0 && dropIndex < dropStack.getChildren().size())
+ dropStack.getChildren().add(dropIndex, (MStackElement) dragElement);
+ else
+ dropStack.getChildren().add((MStackElement) dragElement);
+
+ // (Re)active the element being dropped
+ dropStack.setSelectedElement((MStackElement) dragElement);
+ } else {
+ MPartStack stack = (MPartStack) dragElement;
+ MStackElement curSel = stack.getSelectedElement();
+ List<MStackElement> kids = stack.getChildren();
+ while (kids.size() > 0) {
+ MStackElement lastChild = kids.remove(kids.size() - 1);
+ if (dropIndex >= 0 && dropIndex < dropStack.getChildren().size())
+ dropStack.getChildren().add(dropIndex, lastChild);
+ else
+ dropStack.getChildren().add(lastChild);
+ }
+
+ // (Re)active the element being dropped
+ dropStack.setSelectedElement(curSel);
+ }
}
/**
diff --git a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/SashRenderer.java b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/SashRenderer.java
index 684ab92..d9b1239 100644
--- a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/SashRenderer.java
+++ b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/SashRenderer.java
@@ -33,7 +33,7 @@
private IEventBroker eventBroker;
private static final int UNDEFINED_WEIGHT = -1;
- private static final int DEFAULT_WEIGHT = 100;
+ private static final int DEFAULT_WEIGHT = 5000;
private EventHandler sashOrientationHandler;
private EventHandler sashWeightHandler;
diff --git a/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/internal/workbench/swt/PartRenderingEngine.java b/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/internal/workbench/swt/PartRenderingEngine.java
index e5b2364..29712bf 100644
--- a/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/internal/workbench/swt/PartRenderingEngine.java
+++ b/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/internal/workbench/swt/PartRenderingEngine.java
@@ -261,7 +261,7 @@
}
}
} else {
- if (renderer != null)
+ if (renderer != null && added.isToBeRendered())
renderer.childRendered(changedElement, added);
}
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 e61d786..4ed4a70 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
@@ -943,4 +943,33 @@
}
parent.setToBeRendered(false);
}
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.e4.ui.workbench.modeling.EModelService#isLastEditorStack(org.eclipse.e4.ui.model
+ * .application.ui.MUIElement)
+ */
+ public boolean isLastEditorStack(MUIElement stack) {
+ if (!(stack instanceof MPartStack))
+ return false;
+
+ // is it in the shared area?
+ MUIElement parent = stack.getParent();
+ while (parent != null && !(parent instanceof MArea))
+ parent = parent.getParent();
+ if (parent == null)
+ return false;
+
+ // OK, it's in the area, is it the last TBR one ?
+ MArea area = (MArea) parent;
+ List<MPartStack> stacks = findElements(area, null, MPartStack.class, null);
+ int count = 0;
+ for (MPartStack aStack : stacks) {
+ if (aStack.isToBeRendered())
+ count++;
+ }
+ return count < 2;
+ }
}
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 8b25baf..66090cb 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
@@ -417,4 +417,15 @@
* perspectives in the window are checked
*/
public void hideLocalPlaceholders(MWindow window, MPerspective perspective);
+
+ /**
+ * Returns <code>true</code> iff the supplied element represents the single visible element in
+ * the shared area. This method is used to test for this condition since (by convention) there
+ * must be at least one stack in the shared area at all times.
+ *
+ * @param stack
+ * The element to test
+ * @return <code>true</code> iff the element is the last visible stack
+ */
+ public boolean isLastEditorStack(MUIElement stack);
}