org.eclipse.ui.internal.PartPane Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of workbench Show documentation
Show all versions of workbench Show documentation
This plug-in contains the bulk of the Workbench implementation, and depends on JFace, SWT, and Core Runtime. It cannot be used independently from org.eclipse.ui. Workbench client plug-ins should not depend directly on this plug-in.
The newest version!
/*******************************************************************************
* Copyright (c) 2000, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ui.internal;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Sash;
import org.eclipse.ui.IPropertyListener;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.internal.dnd.SwtUtil;
import org.eclipse.ui.part.MultiEditor;
import org.eclipse.ui.presentations.IPresentablePart;
/**
* Provides the common behavior for both views
* and editor panes.
*
* TODO: Delete ViewPane and EditorPane, and make this class non-abstract.
*
* TODO: Stop subclassing LayoutPart. This class cannot be interchanged with other LayoutParts.
* Pointers that refer to PartPane instances should do so directly rather than referring to
* LayoutPart and downcasting. The getPresentablePart() method only applies to PartPanes, and
* should be removed from LayoutPart.
*/
public abstract class PartPane extends LayoutPart implements IPropertyListener,
Listener, IPropertyChangeListener {
public static final String PROP_ZOOMED = "zoomed"; //$NON-NLS-1$
private boolean isZoomed = false;
private MenuManager paneMenuManager;
private ListenerList listeners = new ListenerList();
private ListenerList partListeners = new ListenerList();
protected IWorkbenchPartReference partReference;
protected WorkbenchPage page;
protected Composite control;
private boolean inLayout = true;
private TraverseListener traverseListener = new TraverseListener() {
/* (non-Javadoc)
* @see org.eclipse.swt.events.TraverseListener#keyTraversed(org.eclipse.swt.events.TraverseEvent)
*/
public void keyTraversed(TraverseEvent e) {
// Hack: Currently, SWT sets focus whenever we call Control.traverse. This doesn't
// cause too much of a problem for ctrl-pgup and ctrl-pgdn, but it is seriously unexpected
// for other traversal events. When (and if) it becomes possible to call traverse() without
// forcing a focus change, this if statement should be removed and ALL events should be
// forwarded to the container.
if (e.detail == SWT.TRAVERSE_PAGE_NEXT
|| e.detail == SWT.TRAVERSE_PAGE_PREVIOUS) {
ILayoutContainer container = getContainer();
if (container != null && container instanceof LayoutPart) {
LayoutPart parent = (LayoutPart) container;
Control parentControl = parent.getControl();
if (parentControl != null && !parentControl.isDisposed()) {
e.doit = parentControl.traverse(e.detail);
if (e.doit) {
e.detail = SWT.TRAVERSE_NONE;
}
}
}
}
}
};
private boolean busy;
public static class Sashes {
public Sash left;
public Sash right;
public Sash top;
public Sash bottom;
}
/**
* Construct a pane for a part.
*/
public PartPane(IWorkbenchPartReference partReference,
WorkbenchPage workbenchPage) {
super(partReference.getId());
this.partReference = partReference;
this.page = workbenchPage;
}
public void addSizeMenuItem(Menu menu, int index) {
//Add size menu
MenuItem item = new MenuItem(menu, SWT.CASCADE, index);
item.setText(WorkbenchMessages.PartPane_size);
Menu sizeMenu = new Menu(menu);
item.setMenu(sizeMenu);
addSizeItems(sizeMenu);
}
/**
*
*/
public void createControl(Composite parent) {
if (getControl() != null) {
return;
}
partReference.addPropertyListener(this);
partReference.addPartPropertyListener(this);
// Create view form.
control = new Composite(parent, SWT.NONE);
control.setLayout(new FillLayout());
// the part should never be visible by default. It will be made visible
// by activation. This allows us to have views appear in tabs without
// becoming active by default.
control.setVisible(false);
control.moveAbove(null);
// Create a title bar.
createTitleBar();
// When the pane or any child gains focus, notify the workbench.
control.addListener(SWT.Activate, this);
control.addTraverseListener(traverseListener);
}
/**
* Create a title bar for the pane if required.
*/
protected abstract void createTitleBar();
/**
* @private
*/
public void dispose() {
super.dispose();
if ((control != null) && (!control.isDisposed())) {
control.removeListener(SWT.Activate, this);
control.removeTraverseListener(traverseListener);
control.dispose();
control = null;
}
if ((paneMenuManager != null)) {
paneMenuManager.dispose();
paneMenuManager = null;
}
partReference.removePropertyListener(this);
partReference.removePartPropertyListener(this);
}
/**
* User has requested to close the pane.
* Take appropriate action depending on type.
*/
abstract public void doHide();
/**
* Zooms in on the part contained in this pane.
*/
protected void doZoom() {
if (isDocked()) {
page.toggleZoom(partReference);
}
}
/**
* Gets the presentation bounds.
*/
public Rectangle getBounds() {
return getControl().getBounds();
}
/**
* Get the control.
*/
public Control getControl() {
return control;
}
/**
* Answer the part child.
*/
public IWorkbenchPartReference getPartReference() {
return partReference;
}
/**
* @see Listener
*/
public void handleEvent(Event event) {
if (event.type == SWT.Activate) {
if (inLayout) {
requestActivation();
}
}
}
/**
* Return whether the pane is zoomed or not
*/
public boolean isZoomed() {
return isZoomed;
}
/**
* Move the control over another one.
*/
public void moveAbove(Control refControl) {
if (getControl() != null) {
getControl().moveAbove(refControl);
}
}
/**
* Notify the workbook page that the part pane has
* been activated by the user.
*/
public void requestActivation() {
IWorkbenchPart part = partReference.getPart(true);
// Cannot activate the outer bit of a MultiEditor. In previous versions of the
// workbench, MultiEditors had their own implementation of EditorPane for the purpose
// of overriding requestActivation with a NOP... however, keeping the old pattern would
// mean it is necessary to eagerly activate an editor's plugin in order to determine
// what type of pane to create.
if (part instanceof MultiEditor) {
return;
}
this.page.requestActivation(part);
}
/**
* Sets the parent for this part.
*/
public void setContainer(ILayoutContainer container) {
if (container instanceof LayoutPart) {
LayoutPart part = (LayoutPart) container;
Control containerControl = part.getControl();
if (containerControl != null) {
Control control = getControl();
Composite newParent = containerControl.getParent();
if (control != null && newParent != control.getParent()) {
reparent(newParent);
}
}
}
super.setContainer(container);
}
/**
* Shows the receiver if visible
is true otherwise hide it.
*/
public void setVisible(boolean makeVisible) {
// Avoid redundant visibility changes
if (makeVisible == getVisible()) {
return;
}
if (makeVisible) {
partReference.getPart(true);
}
super.setVisible(makeVisible);
((WorkbenchPartReference) partReference).fireVisibilityChange();
}
/**
* Sets focus to this part.
*/
public void setFocus() {
requestActivation();
IWorkbenchPart part = partReference.getPart(true);
if (part != null) {
Control control = getControl();
if (!SwtUtil.isFocusAncestor(control)) {
// First try to call part.setFocus
part.setFocus();
}
}
}
/**
* Sets the workbench page of the view.
*/
public void setWorkbenchPage(WorkbenchPage workbenchPage) {
this.page = workbenchPage;
}
/**
* Set whether the pane is zoomed or not
*/
public void setZoomed(boolean isZoomed) {
if (this.isZoomed == isZoomed) {
return; // do nothing if we're already in the right state.
}
super.setZoomed(isZoomed);
this.isZoomed = isZoomed;
((WorkbenchPartReference) partReference).fireZoomChange();
}
/**
* Informs the pane that it's window shell has
* been activated.
*/
/* package */abstract void shellActivated();
/**
* Informs the pane that it's window shell has
* been deactivated.
*/
/* package */abstract void shellDeactivated();
/**
* Indicate focus in part.
*/
public abstract void showFocus(boolean inFocus);
/**
* @see IPartDropTarget::targetPartFor
*/
public LayoutPart targetPartFor(LayoutPart dragSource) {
return this;
}
/**
* Returns the PartStack that contains this PartPane, or null if none.
*
* @return
*/
public PartStack getStack() {
ILayoutContainer container = getContainer();
if (container instanceof PartStack) {
return (PartStack) container;
}
return null;
}
/**
* Show a title label menu for this pane.
*/
public void showPaneMenu() {
PartStack folder = getStack();
if (folder != null) {
folder.showPaneMenu();
}
}
/**
* Show the context menu for this part.
*/
public void showSystemMenu() {
PartStack folder = getStack();
if (folder != null) {
folder.showSystemMenu();
}
}
/**
* Finds and return the sashes around this part.
*/
protected Sashes findSashes() {
Sashes result = new Sashes();
ILayoutContainer container = getContainer();
if (container == null) {
return result;
}
container.findSashes(this, result);
return result;
}
/**
* Enable the user to resize this part using
* the keyboard to move the specified sash
*/
protected void moveSash(final Sash sash) {
moveSash(sash, this);
}
public static void moveSash(final Sash sash,
final LayoutPart toGetFocusWhenDone) {
final KeyListener listener = new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.character == SWT.ESC || e.character == '\r') {
if (toGetFocusWhenDone != null) {
toGetFocusWhenDone.setFocus();
}
}
}
};
sash.addFocusListener(new FocusAdapter() {
public void focusGained(FocusEvent e) {
sash.setBackground(sash.getDisplay().getSystemColor(
SWT.COLOR_LIST_SELECTION));
sash.addKeyListener(listener);
}
public void focusLost(FocusEvent e) {
sash.setBackground(null);
sash.removeKeyListener(listener);
}
});
sash.setFocus();
}
/**
* Add a menu item to the Size Menu
*/
protected void addSizeItem(Menu sizeMenu, String labelMessage,
final Sash sash) {
MenuItem item = new MenuItem(sizeMenu, SWT.NONE);
item.setText(labelMessage);
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
moveSash(sash);
}
});
item.setEnabled(!isZoomed() && sash != null);
}
/**
* Returns the workbench page of this pane.
*/
public WorkbenchPage getPage() {
return page;
}
/**
* Add the Left,Right,Up,Botton menu items to the Size menu.
*/
protected void addSizeItems(Menu sizeMenu) {
Sashes sashes = findSashes();
addSizeItem(sizeMenu,
WorkbenchMessages.PartPane_sizeLeft, sashes.left);
addSizeItem(sizeMenu,
WorkbenchMessages.PartPane_sizeRight, sashes.right);
addSizeItem(sizeMenu,
WorkbenchMessages.PartPane_sizeTop, sashes.top);
addSizeItem(sizeMenu, WorkbenchMessages.PartPane_sizeBottom, sashes.bottom);
}
/**
* Pin this part.
*/
protected void doDock() {
// do nothing
}
/**
* Set the busy state of the pane.
*/
public void setBusy(boolean isBusy) {
if (isBusy != busy) {
busy = isBusy;
firePropertyChange(IPresentablePart.PROP_BUSY);
}
}
/**
* Show a highlight for the receiver if it is
* not currently the part in the front of its
* presentation.
*
*/
public void showHighlight() {
//No nothing by default
}
/**
* @return
*/
public abstract Control getToolBar();
/**
* @return
*/
public boolean hasViewMenu() {
return false;
}
/**
* @param location
*/
public void showViewMenu(Point location) {
}
public boolean isBusy() {
return busy;
}
/**
* Writes a description of the layout to the given string buffer.
* This is used for drag-drop test suites to determine if two layouts are the
* same. Like a hash code, the description should compare as equal iff the
* layouts are the same. However, it should be user-readable in order to
* help debug failed tests. Although these are english readable strings,
* they do not need to be translated.
*
* @param buf
*/
public void describeLayout(StringBuffer buf) {
IWorkbenchPartReference part = getPartReference();
if (part != null) {
buf.append(part.getPartName());
return;
}
}
/**
* @return
* @since 3.1
*/
public abstract boolean isCloseable();
public void setInLayout(boolean inLayout) {
this.inLayout = inLayout;
}
public boolean getInLayout() {
return inLayout;
}
public boolean allowsAutoFocus() {
if (!inLayout) {
return false;
}
return super.allowsAutoFocus();
}
/**
* Clears all contribution items from the contribution managers (this is done separately
* from dispose() since it is done after the part is disposed). This is a bit of a hack.
* Really, the contribution managers should be part of the site, not the PartPane. If these
* were moved elsewhere, then disposal of the PartPane would be atomic and this method could
* be removed.
*/
public void removeContributions() {
}
public void addPropertyListener(IPropertyListener listener) {
listeners.add(listener);
}
public void removePropertyListener(IPropertyListener listener) {
listeners.remove(listener);
}
public void firePropertyChange(int propertyId) {
Object listeners[] = this.listeners.getListeners();
for (int i = 0; i < listeners.length; i++) {
((IPropertyListener) listeners[i]).propertyChanged(this, propertyId);
}
}
public void propertyChanged(Object source, int propId) {
firePropertyChange(propId);
}
public void addPartPropertyListener(IPropertyChangeListener listener) {
partListeners.add(listener);
}
public void removePartPropertyListener(IPropertyChangeListener listener) {
partListeners.remove(listener);
}
public void firePartPropertyChange(PropertyChangeEvent event) {
Object[] l = partListeners.getListeners();
for (int i = 0; i < l.length; i++) {
((IPropertyChangeListener)l[i]).propertyChange(event);
}
}
/* (non-Javadoc)
* @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
*/
public void propertyChange(PropertyChangeEvent event) {
firePartPropertyChange(event);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy