Issue #808 create API for managing floating views and made CaveDetachedWindow more robust.
Former-commit-id:8984b35ff8
[formerlyea0c7046af
[formerly 1f9b6d2a0b7d45f68bda57c6fcaeec493cbb835a]] Former-commit-id:ea0c7046af
Former-commit-id:45a1cc1997
This commit is contained in:
parent
81dd57d347
commit
e565237b63
3 changed files with 476 additions and 145 deletions
|
@ -37,13 +37,13 @@ import org.eclipse.ui.IPropertyListener;
|
||||||
import org.eclipse.ui.ISaveablePart;
|
import org.eclipse.ui.ISaveablePart;
|
||||||
import org.eclipse.ui.IViewPart;
|
import org.eclipse.ui.IViewPart;
|
||||||
import org.eclipse.ui.IViewReference;
|
import org.eclipse.ui.IViewReference;
|
||||||
import org.eclipse.ui.IWorkbenchPage;
|
|
||||||
import org.eclipse.ui.IWorkbenchPartConstants;
|
import org.eclipse.ui.IWorkbenchPartConstants;
|
||||||
import org.eclipse.ui.IWorkbenchPartReference;
|
import org.eclipse.ui.IWorkbenchPartReference;
|
||||||
import org.eclipse.ui.IWorkbenchWindow;
|
import org.eclipse.ui.IWorkbenchWindow;
|
||||||
import org.eclipse.ui.contexts.IContextService;
|
import org.eclipse.ui.contexts.IContextService;
|
||||||
import org.eclipse.ui.internal.DetachedWindow;
|
import org.eclipse.ui.internal.DetachedWindow;
|
||||||
import org.eclipse.ui.internal.EditorManager;
|
import org.eclipse.ui.internal.EditorManager;
|
||||||
|
import org.eclipse.ui.internal.ILayoutContainer;
|
||||||
import org.eclipse.ui.internal.IWorkbenchConstants;
|
import org.eclipse.ui.internal.IWorkbenchConstants;
|
||||||
import org.eclipse.ui.internal.IWorkbenchHelpContextIds;
|
import org.eclipse.ui.internal.IWorkbenchHelpContextIds;
|
||||||
import org.eclipse.ui.internal.LayoutPart;
|
import org.eclipse.ui.internal.LayoutPart;
|
||||||
|
@ -56,6 +56,7 @@ import org.eclipse.ui.internal.dnd.DragUtil;
|
||||||
import org.eclipse.ui.internal.dnd.IDragOverListener;
|
import org.eclipse.ui.internal.dnd.IDragOverListener;
|
||||||
import org.eclipse.ui.internal.dnd.IDropTarget;
|
import org.eclipse.ui.internal.dnd.IDropTarget;
|
||||||
import org.eclipse.ui.internal.presentations.PresentationFactoryUtil;
|
import org.eclipse.ui.internal.presentations.PresentationFactoryUtil;
|
||||||
|
import org.eclipse.ui.presentations.IPresentablePart;
|
||||||
import org.eclipse.ui.presentations.StackDropResult;
|
import org.eclipse.ui.presentations.StackDropResult;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -84,6 +85,13 @@ public class CaveDetachedWindow extends DetachedWindow implements
|
||||||
// wasn't canceled
|
// wasn't canceled
|
||||||
e.doit = handleClose();
|
e.doit = handleClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shellActivated(ShellEvent e) {
|
||||||
|
page.getPartService().setActivePart(
|
||||||
|
folder.getSelection().getPartReference());
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private Listener resizeListener = new Listener() {
|
private Listener resizeListener = new Listener() {
|
||||||
|
@ -119,7 +127,111 @@ public class CaveDetachedWindow extends DetachedWindow implements
|
||||||
this.page = workbenchPage;
|
this.page = workbenchPage;
|
||||||
|
|
||||||
folder = new ViewStack(page, false, PresentationFactoryUtil.ROLE_VIEW,
|
folder = new ViewStack(page, false, PresentationFactoryUtil.ROLE_VIEW,
|
||||||
null);
|
null) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override close because super.close expects to find the view in
|
||||||
|
* the page.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void close(IPresentablePart part) {
|
||||||
|
if (!presentationSite.isCloseable(part)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LayoutPart layoutPart = getPaneFor(part);
|
||||||
|
if (layoutPart != null && layoutPart instanceof PartPane) {
|
||||||
|
PartPane viewPane = (PartPane) layoutPart;
|
||||||
|
IViewReference ref = (IViewReference) viewPane
|
||||||
|
.getPartReference();
|
||||||
|
CaveWorkbenchPageManager.getInstance(page).hideView(ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override paneDragStart so we can check if the stack is empty and
|
||||||
|
* close the window
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void paneDragStart(LayoutPart pane, Point initialLocation,
|
||||||
|
boolean keyboard) {
|
||||||
|
super.paneDragStart(pane, initialLocation, keyboard);
|
||||||
|
if (pane == null) {
|
||||||
|
// This means the whole stack is getting dragged:
|
||||||
|
for (LayoutPart lpart : getChildren()) {
|
||||||
|
checkChild(lpart);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
checkChild(pane);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this after dragging to check if I still only my children,
|
||||||
|
* normally the page removes them but that doesn't work for
|
||||||
|
* CaveDetachedWindows so this removes it from the stack when
|
||||||
|
* someone else gets it.
|
||||||
|
*
|
||||||
|
* @param pane
|
||||||
|
*/
|
||||||
|
private void checkChild(LayoutPart pane) {
|
||||||
|
if (pane.getContainer() != this) {
|
||||||
|
// the part does nto get properly dereferenced since it is
|
||||||
|
// not part of the page
|
||||||
|
ILayoutContainer newContainer = pane.getContainer();
|
||||||
|
newContainer.remove(pane);
|
||||||
|
remove(pane);
|
||||||
|
newContainer.add(pane);
|
||||||
|
if (this.getItemCount() == 0 && windowShell != null) {
|
||||||
|
windowShell.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override add so we can change floating status
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void add(LayoutPart child, Object cookie) {
|
||||||
|
super.add(child, cookie);
|
||||||
|
setFloating(child, true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override remove so we can change floating status
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void remove(LayoutPart child) {
|
||||||
|
super.remove(child);
|
||||||
|
setFloating(child, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setFloating(LayoutPart child, boolean floating) {
|
||||||
|
if (child instanceof ViewPane) {
|
||||||
|
ViewPane pane = (ViewPane) child;
|
||||||
|
IViewPart view = pane.getViewReference().getView(false);
|
||||||
|
if (view instanceof CaveFloatingView) {
|
||||||
|
((CaveFloatingView) view).setFloating(floating);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override set selection so we can fire appropriate activation
|
||||||
|
* listeners.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setSelection(LayoutPart part) {
|
||||||
|
super.setSelection(part);
|
||||||
|
if (part instanceof PartPane) {
|
||||||
|
page.getPartService().setActivePart(
|
||||||
|
((PartPane) part).getPartReference());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
folder.addListener(propertyListener);
|
folder.addListener(propertyListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,6 +292,7 @@ public class CaveDetachedWindow extends DetachedWindow implements
|
||||||
|
|
||||||
public void create() {
|
public void create() {
|
||||||
windowShell = new Shell(Display.getCurrent(), SWT.SHELL_TRIM);
|
windowShell = new Shell(Display.getCurrent(), SWT.SHELL_TRIM);
|
||||||
|
windowShell.addShellListener(shellListener);
|
||||||
windowShell.setData(this);
|
windowShell.setData(this);
|
||||||
windowShell.setText("Detached Window");
|
windowShell.setText("Detached Window");
|
||||||
DragUtil.addDragTarget(windowShell, this);
|
DragUtil.addDragTarget(windowShell, this);
|
||||||
|
@ -214,33 +327,6 @@ public class CaveDetachedWindow extends DetachedWindow implements
|
||||||
folder.setBounds(windowShell.getClientArea());
|
folder.setBounds(windowShell.getClientArea());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a visual part to this window. Supports reparenting.
|
|
||||||
*/
|
|
||||||
public void add(ViewPane part) {
|
|
||||||
|
|
||||||
Shell shell = getShell();
|
|
||||||
if (shell != null) {
|
|
||||||
part.reparent(shell);
|
|
||||||
}
|
|
||||||
folder.add(part);
|
|
||||||
updateMinimumSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean belongsToWorkbenchPage(IWorkbenchPage workbenchPage) {
|
|
||||||
return (this.page == workbenchPage);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean close() {
|
|
||||||
hideViewsOnClose = false;
|
|
||||||
Shell shell = getShell();
|
|
||||||
if (shell != null && !shell.isDisposed()) {
|
|
||||||
shell.removeShellListener(shellListener);
|
|
||||||
shell.close();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes this window and disposes its shell.
|
* Closes this window and disposes its shell.
|
||||||
*/
|
*/
|
||||||
|
@ -262,7 +348,8 @@ public class CaveDetachedWindow extends DetachedWindow implements
|
||||||
|
|
||||||
// Only close if closable...
|
// Only close if closable...
|
||||||
if (child.isCloseable()) {
|
if (child.isCloseable()) {
|
||||||
page.hideView(child.getViewReference());
|
CaveWorkbenchPageManager.getInstance(page).hideView(
|
||||||
|
child.getViewReference());
|
||||||
|
|
||||||
// Was the close cancelled?
|
// Was the close cancelled?
|
||||||
if (child.getContainer() != null)
|
if (child.getContainer() != null)
|
||||||
|
@ -352,34 +439,36 @@ public class CaveDetachedWindow extends DetachedWindow implements
|
||||||
public IDropTarget drag(Control currentControl, Object draggedObject,
|
public IDropTarget drag(Control currentControl, Object draggedObject,
|
||||||
Point position, Rectangle dragRectangle) {
|
Point position, Rectangle dragRectangle) {
|
||||||
|
|
||||||
if (!(draggedObject instanceof PartPane)) {
|
if (!(draggedObject instanceof ViewPane)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final PartPane sourcePart = (PartPane) draggedObject;
|
ViewPane sourcePart = (ViewPane) draggedObject;
|
||||||
|
|
||||||
if (sourcePart.getWorkbenchWindow() != page.getWorkbenchWindow()) {
|
if (sourcePart.getWorkbenchWindow() != page.getWorkbenchWindow()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only handle the event if the source part is acceptable to the
|
// If you put views in a CaveDetachedWindow then you can't find them
|
||||||
// particular PartStack
|
// using the workbenchPage, this is expected for FLoatingViews but
|
||||||
IDropTarget target = null;
|
// puttiing other views in the detached window would cause API problems
|
||||||
if (sourcePart instanceof ViewPane) {
|
// by unexpectedly losing views.
|
||||||
target = folder.getDropTarget(draggedObject, position);
|
if (!(sourcePart.getViewReference().getPart(false) instanceof CaveFloatingView)) {
|
||||||
|
return null;
|
||||||
if (target == null) {
|
|
||||||
Rectangle displayBounds = DragUtil.getDisplayBounds(folder
|
|
||||||
.getControl());
|
|
||||||
if (displayBounds.contains(position)) {
|
|
||||||
target = folder.createDropTarget(sourcePart,
|
|
||||||
new StackDropResult(displayBounds, null));
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IDropTarget target = folder.getDropTarget(draggedObject, position);
|
||||||
|
|
||||||
|
if (target == null) {
|
||||||
|
Rectangle displayBounds = DragUtil.getDisplayBounds(folder
|
||||||
|
.getControl());
|
||||||
|
if (displayBounds.contains(position)) {
|
||||||
|
target = folder.createDropTarget(sourcePart,
|
||||||
|
new StackDropResult(displayBounds, null));
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,35 +530,6 @@ public class CaveDetachedWindow extends DetachedWindow implements
|
||||||
return this.page;
|
return this.page;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see IPersistablePart
|
|
||||||
*/
|
|
||||||
public void restoreState(IMemento memento) {
|
|
||||||
// Read the bounds.
|
|
||||||
Integer bigInt;
|
|
||||||
bigInt = memento.getInteger(IWorkbenchConstants.TAG_X);
|
|
||||||
int x = bigInt.intValue();
|
|
||||||
bigInt = memento.getInteger(IWorkbenchConstants.TAG_Y);
|
|
||||||
int y = bigInt.intValue();
|
|
||||||
bigInt = memento.getInteger(IWorkbenchConstants.TAG_WIDTH);
|
|
||||||
int width = bigInt.intValue();
|
|
||||||
bigInt = memento.getInteger(IWorkbenchConstants.TAG_HEIGHT);
|
|
||||||
int height = bigInt.intValue();
|
|
||||||
bigInt = memento.getInteger(IWorkbenchConstants.TAG_FLOAT);
|
|
||||||
|
|
||||||
// Set the bounds.
|
|
||||||
bounds = new Rectangle(x, y, width, height);
|
|
||||||
if (getShell() != null) {
|
|
||||||
getShell().setBounds(bounds);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the folder.
|
|
||||||
IMemento childMem = memento.getChild(IWorkbenchConstants.TAG_FOLDER);
|
|
||||||
if (childMem != null) {
|
|
||||||
folder.restoreState(childMem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see IPersistablePart
|
* @see IPersistablePart
|
||||||
*/
|
*/
|
||||||
|
@ -517,4 +577,8 @@ public class CaveDetachedWindow extends DetachedWindow implements
|
||||||
return Window.OK;
|
return Window.OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setBounds(Rectangle bounds) {
|
||||||
|
this.bounds = bounds;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,19 +24,7 @@ import java.io.File;
|
||||||
import org.eclipse.jface.action.Action;
|
import org.eclipse.jface.action.Action;
|
||||||
import org.eclipse.jface.action.IToolBarManager;
|
import org.eclipse.jface.action.IToolBarManager;
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.graphics.Point;
|
|
||||||
import org.eclipse.swt.graphics.Rectangle;
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.eclipse.swt.widgets.Display;
|
|
||||||
import org.eclipse.swt.widgets.Event;
|
|
||||||
import org.eclipse.ui.IViewPart;
|
|
||||||
import org.eclipse.ui.PlatformUI;
|
|
||||||
import org.eclipse.ui.internal.ILayoutContainer;
|
|
||||||
import org.eclipse.ui.internal.PartPane;
|
|
||||||
import org.eclipse.ui.internal.ViewPane;
|
|
||||||
import org.eclipse.ui.internal.ViewSite;
|
|
||||||
import org.eclipse.ui.internal.WorkbenchPage;
|
|
||||||
import org.eclipse.ui.internal.dnd.DragUtil;
|
|
||||||
import org.eclipse.ui.part.ViewPart;
|
import org.eclipse.ui.part.ViewPart;
|
||||||
|
|
||||||
import com.raytheon.viz.ui.UiPlugin;
|
import com.raytheon.viz.ui.UiPlugin;
|
||||||
|
@ -61,13 +49,7 @@ import com.raytheon.viz.ui.UiPlugin;
|
||||||
|
|
||||||
public abstract class CaveFloatingView extends ViewPart {
|
public abstract class CaveFloatingView extends ViewPart {
|
||||||
|
|
||||||
private boolean detached;
|
protected FloatAction floatAction;
|
||||||
|
|
||||||
private CaveDetachedWindow window;
|
|
||||||
|
|
||||||
private ILayoutContainer container;
|
|
||||||
|
|
||||||
private Rectangle bounds;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs the view
|
* Constructs the view
|
||||||
|
@ -81,8 +63,13 @@ public abstract class CaveFloatingView extends ViewPart {
|
||||||
createToolbarButton();
|
createToolbarButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IViewPart getPart() {
|
public void setFloating(boolean floating) {
|
||||||
return this;
|
floatAction.setChecked(floating);
|
||||||
|
if (floating) {
|
||||||
|
floatAction.setToolTipText("Dock");
|
||||||
|
} else {
|
||||||
|
floatAction.setToolTipText("Float");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -90,57 +77,31 @@ public abstract class CaveFloatingView extends ViewPart {
|
||||||
*/
|
*/
|
||||||
protected void createToolbarButton() {
|
protected void createToolbarButton() {
|
||||||
IToolBarManager mgr = getViewSite().getActionBars().getToolBarManager();
|
IToolBarManager mgr = getViewSite().getActionBars().getToolBarManager();
|
||||||
final Action floatAction = new Action("Float", SWT.TOGGLE) {
|
floatAction = new FloatAction();
|
||||||
@Override
|
mgr.add(floatAction);
|
||||||
public void run() {
|
|
||||||
// should only run when the user is currently attached to cave
|
|
||||||
// (or detached, but not a floating dialog)
|
|
||||||
this.setToolTipText("Dock");
|
|
||||||
setChecked(true);
|
|
||||||
detached = true;
|
|
||||||
WorkbenchPage page = (WorkbenchPage) PlatformUI.getWorkbench()
|
|
||||||
.getActiveWorkbenchWindow().getActivePage();
|
|
||||||
bounds = ((ViewSite) ((ViewPart) getPart()).getViewSite())
|
|
||||||
.getPane().getBounds();
|
|
||||||
|
|
||||||
container = ((ViewSite) ((ViewPart) getPart()).getViewSite())
|
}
|
||||||
.getPane().getStack();
|
|
||||||
window = new CaveDetachedWindow(page);
|
|
||||||
window.create();
|
|
||||||
window.open();
|
|
||||||
|
|
||||||
bounds.x += PlatformUI.getWorkbench()
|
private class FloatAction extends Action {
|
||||||
.getActiveWorkbenchWindow().getShell().getMonitor()
|
|
||||||
.getBounds().x;
|
|
||||||
ViewPane pane = (ViewPane) ((ViewSite) getPart().getViewSite())
|
|
||||||
.getPane();
|
|
||||||
container = pane.getContainer();
|
|
||||||
window.drop(pane);
|
|
||||||
window.getShell().setBounds(bounds);
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
public FloatAction() {
|
||||||
public void runWithEvent(Event event) {
|
super("Float", SWT.TOGGLE);
|
||||||
if (!detached) {
|
setImageDescriptor(UiPlugin.getImageDescriptor("icons"
|
||||||
run();
|
+ File.separator + "float.gif"));
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
setToolTipText("Float");
|
@Override
|
||||||
setChecked(false);
|
public void run() {
|
||||||
detached = false;
|
if (isChecked()) {
|
||||||
WorkbenchPage page = (WorkbenchPage) PlatformUI.getWorkbench()
|
CaveWorkbenchPageManager manager = CaveWorkbenchPageManager
|
||||||
.getActiveWorkbenchWindow().getActivePage();
|
.getInstance(getSite().getPage());
|
||||||
PartPane layoutPart = ((ViewSite) getPart().getViewSite())
|
manager.floatView(CaveFloatingView.this);
|
||||||
.getPane();
|
} else {
|
||||||
Point point = new Point(bounds.x + bounds.width / 2, bounds.y
|
CaveWorkbenchPageManager manager = CaveWorkbenchPageManager
|
||||||
+ bounds.height / 2);
|
.getInstance(getSite().getPage());
|
||||||
window.getShell().setVisible(false);
|
manager.dockView(CaveFloatingView.this);
|
||||||
window = null;
|
|
||||||
DragUtil.dragTo(Display.getCurrent(), layoutPart, point, bounds);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
floatAction.setImageDescriptor(UiPlugin.getImageDescriptor("icons"
|
|
||||||
+ File.separator + "float.gif"));
|
|
||||||
mgr.add(floatAction);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,306 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.viz.ui.views;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.swt.events.ShellAdapter;
|
||||||
|
import org.eclipse.swt.events.ShellEvent;
|
||||||
|
import org.eclipse.swt.graphics.Point;
|
||||||
|
import org.eclipse.swt.graphics.Rectangle;
|
||||||
|
import org.eclipse.swt.widgets.Control;
|
||||||
|
import org.eclipse.ui.IPageListener;
|
||||||
|
import org.eclipse.ui.IViewPart;
|
||||||
|
import org.eclipse.ui.IViewReference;
|
||||||
|
import org.eclipse.ui.IWorkbenchPage;
|
||||||
|
import org.eclipse.ui.IWorkbenchPartReference;
|
||||||
|
import org.eclipse.ui.PartInitException;
|
||||||
|
import org.eclipse.ui.PlatformUI;
|
||||||
|
import org.eclipse.ui.internal.ILayoutContainer;
|
||||||
|
import org.eclipse.ui.internal.LayoutPart;
|
||||||
|
import org.eclipse.ui.internal.PartPane;
|
||||||
|
import org.eclipse.ui.internal.PartStack;
|
||||||
|
import org.eclipse.ui.internal.ViewPane;
|
||||||
|
import org.eclipse.ui.internal.ViewSite;
|
||||||
|
import org.eclipse.ui.internal.WorkbenchPage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Eclipse WorkbenchPage has lots of nifty functions for dealing with views,
|
||||||
|
* but unfortunately it fails to take into account CaveFloatingViews that are in
|
||||||
|
* CaveDetachedWindows, the goal of this class is to provide an API of equal
|
||||||
|
* niftosity that works for CaveFloatingViews.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Jul 11, 2012 bsteffen Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author bsteffen
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class CaveWorkbenchPageManager {
|
||||||
|
|
||||||
|
private static Map<IWorkbenchPage, CaveWorkbenchPageManager> instanceMap = new HashMap<IWorkbenchPage, CaveWorkbenchPageManager>();
|
||||||
|
|
||||||
|
public static CaveWorkbenchPageManager getInstance(IWorkbenchPage page) {
|
||||||
|
synchronized (instanceMap) {
|
||||||
|
CaveWorkbenchPageManager instance = instanceMap.get(page);
|
||||||
|
if (instance == null) {
|
||||||
|
instance = new CaveWorkbenchPageManager(page);
|
||||||
|
instanceMap.put(page, instance);
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CaveWorkbenchPageManager getActiveInstance() {
|
||||||
|
synchronized (instanceMap) {
|
||||||
|
return getInstance(PlatformUI.getWorkbench()
|
||||||
|
.getActiveWorkbenchWindow().getActivePage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final IWorkbenchPage workbenchPage;
|
||||||
|
|
||||||
|
private List<CaveDetachedWindow> detachedWindows = new ArrayList<CaveDetachedWindow>();
|
||||||
|
|
||||||
|
private CaveWorkbenchPageManager(IWorkbenchPage workbenchPage) {
|
||||||
|
this.workbenchPage = workbenchPage;
|
||||||
|
workbenchPage.getWorkbenchWindow().addPageListener(
|
||||||
|
new PageListener(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
public IWorkbenchPage getWorkbenchPage() {
|
||||||
|
return workbenchPage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IViewReference[] getViewReferences() {
|
||||||
|
if (detachedWindows.isEmpty()) {
|
||||||
|
return workbenchPage.getViewReferences();
|
||||||
|
}
|
||||||
|
List<IViewReference> result = Arrays.asList(workbenchPage
|
||||||
|
.getViewReferences());
|
||||||
|
result = new ArrayList<IViewReference>(result);
|
||||||
|
for (CaveDetachedWindow window : detachedWindows) {
|
||||||
|
for (LayoutPart part : window.getChildren()) {
|
||||||
|
if (part instanceof ViewPane) {
|
||||||
|
result.add(((ViewPane) part).getViewReference());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toArray(new IViewReference[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IViewPart showView(String viewID) throws PartInitException {
|
||||||
|
return showView(viewID, null, IWorkbenchPage.VIEW_ACTIVATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IViewPart showView(String viewId, String secondaryId, int mode)
|
||||||
|
throws PartInitException {
|
||||||
|
IViewReference ref = findDetachedViewReference(viewId, secondaryId);
|
||||||
|
if (ref != null) {
|
||||||
|
IViewPart view = ref.getView(true);
|
||||||
|
if (mode == IWorkbenchPage.VIEW_ACTIVATE) {
|
||||||
|
activate(view);
|
||||||
|
} else if (mode == IWorkbenchPage.VIEW_VISIBLE) {
|
||||||
|
workbenchPage.bringToTop(view);
|
||||||
|
}
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
return workbenchPage.showView(viewId, secondaryId, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void activate(IViewPart view) {
|
||||||
|
for (CaveDetachedWindow window : detachedWindows) {
|
||||||
|
for (LayoutPart part : window.getChildren()) {
|
||||||
|
if (((ViewPane) part).getPartReference().getPart(false) == view) {
|
||||||
|
window.getShell().forceActive();
|
||||||
|
ILayoutContainer container = part.getContainer();
|
||||||
|
if (container != null && container instanceof PartStack) {
|
||||||
|
PartStack folder = (PartStack) container;
|
||||||
|
if (folder.getSelection() != part) {
|
||||||
|
folder.setSelection(part);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
workbenchPage.activate(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bringToTop(IViewPart view) {
|
||||||
|
for (CaveDetachedWindow window : detachedWindows) {
|
||||||
|
for (LayoutPart part : window.getChildren()) {
|
||||||
|
if (((ViewPane) part).getPartReference().getPart(false) == view) {
|
||||||
|
window.getShell().moveAbove(null);
|
||||||
|
ILayoutContainer container = part.getContainer();
|
||||||
|
if (container != null && container instanceof PartStack) {
|
||||||
|
PartStack folder = (PartStack) container;
|
||||||
|
if (folder.getSelection() != part) {
|
||||||
|
folder.setSelection(part);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
workbenchPage.bringToTop(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IViewReference findViewReference(String viewId) {
|
||||||
|
return findViewReference(viewId, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IViewReference findViewReference(String viewId, String secondaryId) {
|
||||||
|
IViewReference ref = findDetachedViewReference(viewId, secondaryId);
|
||||||
|
if (ref == null) {
|
||||||
|
ref = workbenchPage.findViewReference(viewId, secondaryId);
|
||||||
|
}
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IViewReference findDetachedViewReference(String viewId,
|
||||||
|
String secondaryId) {
|
||||||
|
for (CaveDetachedWindow window : detachedWindows) {
|
||||||
|
for (LayoutPart part : window.getChildren()) {
|
||||||
|
if (part instanceof ViewPane) {
|
||||||
|
IViewReference ref = ((ViewPane) part).getViewReference();
|
||||||
|
if (ref.getId().equals(viewId)
|
||||||
|
&& ((secondaryId == null && ref.getSecondaryId() == null) || secondaryId
|
||||||
|
.equals(ref.getSecondaryId()))) {
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void hideView(IViewReference view) {
|
||||||
|
for (CaveDetachedWindow window : detachedWindows) {
|
||||||
|
for (LayoutPart part : window.getChildren()) {
|
||||||
|
if (part instanceof ViewPane) {
|
||||||
|
if (((ViewPane) part).getPartReference() == view) {
|
||||||
|
WorkbenchPage page = (WorkbenchPage) workbenchPage;
|
||||||
|
if (page.getActivePartReference() == view) {
|
||||||
|
// You cannot hide the active part, normally the
|
||||||
|
// page changes the active part but since we bypass
|
||||||
|
// the page we need to choose a new active part
|
||||||
|
for (IWorkbenchPartReference wbRef : page
|
||||||
|
.getSortedParts()) {
|
||||||
|
if (wbRef != view) {
|
||||||
|
page.activate(wbRef.getPart(false));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
page.getActivePerspective().hideView(view);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
workbenchPage.hideView(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void floatView(IViewPart part) {
|
||||||
|
ViewSite site = ((ViewSite) part.getViewSite());
|
||||||
|
WorkbenchPage page = (WorkbenchPage) site.getPage();
|
||||||
|
PartPane pane = site.getPane();
|
||||||
|
Control control = pane.getStack().getControl();
|
||||||
|
Rectangle bounds = control.getBounds();
|
||||||
|
Point corner = control.getParent().toDisplay(bounds.x, bounds.y);
|
||||||
|
bounds.x = corner.x;
|
||||||
|
bounds.y = corner.y;
|
||||||
|
CaveDetachedWindow window = new CaveDetachedWindow(page);
|
||||||
|
window.setBounds(bounds);
|
||||||
|
window.create();
|
||||||
|
window.drop(pane);
|
||||||
|
window.getShell().setBounds(bounds);
|
||||||
|
window.getShell().addShellListener(new ShellListener(this, window));
|
||||||
|
window.open();
|
||||||
|
window.getShell().forceActive();
|
||||||
|
detachedWindows.add(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dockView(IViewPart part) {
|
||||||
|
WorkbenchPage page = (WorkbenchPage) part.getSite().getPage();
|
||||||
|
IViewReference ref = (IViewReference) page.getReference(part);
|
||||||
|
page.attachView(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ShellListener extends ShellAdapter {
|
||||||
|
|
||||||
|
private final CaveWorkbenchPageManager manager;
|
||||||
|
|
||||||
|
private final CaveDetachedWindow window;
|
||||||
|
|
||||||
|
public ShellListener(CaveWorkbenchPageManager manager,
|
||||||
|
CaveDetachedWindow window) {
|
||||||
|
this.manager = manager;
|
||||||
|
this.window = window;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shellClosed(ShellEvent e) {
|
||||||
|
manager.detachedWindows.remove(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class PageListener implements IPageListener {
|
||||||
|
|
||||||
|
private final CaveWorkbenchPageManager manager;
|
||||||
|
|
||||||
|
public PageListener(CaveWorkbenchPageManager manager) {
|
||||||
|
this.manager = manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void pageActivated(IWorkbenchPage page) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void pageClosed(IWorkbenchPage page) {
|
||||||
|
if (page == manager.getWorkbenchPage()) {
|
||||||
|
page.getWorkbenchWindow().removePageListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void pageOpened(IWorkbenchPage page) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue