blob: 31accb39507b04c543a755953f730dff55277f6c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2009 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
* Cagatay Kavukcuoglu <cagatayk@acm.org>
* - Fix for bug 10025 - Resizing views should not use height ratios
*******************************************************************************/
package org.eclipse.ui.internal;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.internal.provisional.action.IToolBarManager2;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.internal.dnd.DragUtil;
import org.eclipse.ui.internal.provisional.presentations.IActionBarPresentationFactory;
import org.eclipse.ui.presentations.IPresentablePart;
import org.eclipse.ui.presentations.StackPresentation;
/**
* Provides a wrapper for the view's widgetry.
*
* TODO: Delete ViewPane and EditorPane, and make PartPane non-abstract.
*/
public class ViewPane extends PartPane {
// create initially toolbarless bar manager so that actions may be added in the
// init method of the view.
private IToolBarManager2 isvToolBarMgr = null;
private MenuManager isvMenuMgr;
boolean hasFocus;
/**
* Indicates whether a toolbar button is shown for the view local menu.
*/
private boolean hadViewMenu = false;
/**
* Toolbar manager for the ISV toolbar.
*/
private class ISVPropListener implements IPropertyChangeListener {
private Control toolBar;
/**
* Constructor
* @param toolBar
*/
public ISVPropListener (Control toolBar) {
this.toolBar = toolBar;
}
/* (non-Javadoc)
* @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
*/
public void propertyChange(PropertyChangeEvent event) {
String property = event.getProperty();
Integer newValue = (Integer)event.getNewValue();
if (IToolBarManager2.PROP_LAYOUT.equals(property)) {
toolBarResized(toolBar, newValue != null ? newValue.intValue() : 0);
if (toolBar instanceof Composite) {
((Composite)toolBar).layout();
} else {
toolBar.getParent().layout();
}
}
}
}
/**
* Menu manager for view local menu.
*/
class PaneMenuManager extends MenuManager {
public PaneMenuManager() {
super("View Local Menu"); //$NON-NLS-1$
}
protected void update(boolean force, boolean recursive) {
super.update(force, recursive);
boolean hasMenu = !isEmpty();
if (hasMenu != hadViewMenu) {
hadViewMenu = hasMenu;
firePropertyChange(IPresentablePart.PROP_PANE_MENU);
}
}
}
/**
* Constructs a view pane for a view part.
*/
public ViewPane(IViewReference ref, WorkbenchPage page) {
super(ref, page);
IActionBarPresentationFactory actionBarPresentation = ((WorkbenchWindow) page
.getWorkbenchWindow()).getActionBarPresentationFactory();
isvToolBarMgr = actionBarPresentation.createViewToolBarManager();
}
/**
* Create control. Add the title bar.
*/
public void createControl(Composite parent) {
// Only do this once.
if (getControl() != null && !getControl().isDisposed()) {
return;
}
super.createControl(parent);
}
/**
* Create a title bar for the pane.
* - the view icon and title to the far left
* - the view toolbar appears in the middle.
* - the view pulldown menu, pin button, and close button to the far right.
*/
protected void createTitleBar() {
// Only do this once.
updateTitles();
// Listen to title changes.
getPartReference().addPropertyListener(this);
createToolBars();
}
private void toolBarResized(Control toolBar, int newSize) {
Control toolbar = isvToolBarMgr.getControl2();
if (toolbar != null) {
Control ctrl = getControl();
boolean visible = ctrl != null && ctrl.isVisible()
&& toolbarIsVisible();
if (toolbar.isVisible() != visible)
toolbar.setVisible(visible);
}
firePropertyChange(IPresentablePart.PROP_TOOLBAR);
}
/**
*
*/
private void createToolBars() {
Composite parentControl = control;
// ISV toolbar.
// // 1GD0ISU: ITPUI:ALL - Dbl click on view tool cause zoom
final Control isvToolBar = isvToolBarMgr.createControl2(parentControl.getParent());
isvToolBar.setVisible(false);
isvToolBarMgr.addPropertyChangeListener(new ISVPropListener(isvToolBar));
isvToolBar.addMouseListener(new MouseAdapter() {
public void mouseDoubleClick(MouseEvent event) {
if (event.widget instanceof ToolBar) {
if (((ToolBar)event.widget).getItem(new Point(event.x, event.y)) == null) {
doZoom();
}
}
}
});
isvToolBar.addListener(SWT.Activate, this);
isvToolBar.moveAbove(control);
}
public void dispose() {
super.dispose();
/* Bug 42684. The ViewPane instance has been disposed, but an attempt is
* then made to remove focus from it. This happens because the ViewPane is
* still viewed as the active part. In general, when disposed, the control
* containing the titleLabel will also disappear (disposing of the
* titleLabel). As a result, the reference to titleLabel should be dropped.
*/
if (isvMenuMgr != null) {
isvMenuMgr.dispose();
}
if (isvToolBarMgr != null) {
isvToolBarMgr.dispose();
}
}
/**
* @see PartPane#doHide
*/
public void doHide() {
getPage().hideView(getViewReference());
}
/*package*/Rectangle getParentBounds() {
Control ctrl = getControl();
if (getContainer() != null && getContainer() instanceof LayoutPart) {
LayoutPart part = (LayoutPart) getContainer();
if (part.getControl() != null) {
ctrl = part.getControl();
}
}
return DragUtil.getDisplayBounds(ctrl);
}
/**
* Make this view pane a fast view
*/
public void doMakeFast() {
WorkbenchWindow window = (WorkbenchWindow) getPage()
.getWorkbenchWindow();
FastViewBar fastViewBar = window.getFastViewBar();
if (fastViewBar == null || getPage().getActivePerspective() == null)
return;
Shell shell = window.getShell();
// Animate the operation
AnimationEngine.createTweakedAnimation(shell, 400, getParentBounds(),
fastViewBar.getLocationOfNextIcon());
FastViewManager fvm = getPage().getActivePerspective().getFastViewManager();
fvm.addViewReference(FastViewBar.FASTVIEWBAR_ID, -1, getViewReference(), true);
}
public void doRemoveFast() {
if (getPage().getActivePerspective() == null)
return;
Shell shell = getControl().getShell();
Rectangle initialBounds = getParentBounds();
FastViewManager fvm = getPage().getActivePerspective().getFastViewManager();
fvm.removeViewReference(getViewReference(), true, true);
IWorkbenchPart toActivate = getViewReference().getPart(true);
if (toActivate != null) {
getPage().activate(toActivate);
}
Rectangle finalBounds = getParentBounds();
// Animate the operation
AnimationEngine.createTweakedAnimation(shell, 400, initialBounds, finalBounds);
}
/**
* Pin the view.
*/
protected void doDock() {
Perspective persp = getPage().getActivePerspective();
if (persp != null) {
persp.getFastViewManager().removeViewReference(getViewReference(), true, true);
}
}
public void doDetach() {
getPage().detachView(getViewReference());
}
public void doAttach() {
getPage().attachView(getViewReference());
}
/* (non-Javadoc)
* @see org.eclipse.ui.internal.LayoutPart#getCompoundId()
*/
public String getCompoundId() {
IViewReference ref = getViewReference();
if (ref != null) {
return ViewFactory.getKey(ref);
}
return super.getCompoundId();
}
/**
* Returns the drag control.
*/
public Control getDragHandle() {
return control;
}
/**
* @see ViewActionBars
*/
public MenuManager getMenuManager() {
if (isvMenuMgr == null) {
isvMenuMgr = new PaneMenuManager();
}
return isvMenuMgr;
}
/**
* Returns the tab list to use when this part is active.
* Includes the view and its tab (if applicable), in the appropriate order.
*/
public Control[] getTabList() {
Control c = getControl();
if (getContainer() instanceof ViewStack) {
ViewStack tf = (ViewStack) getContainer();
return tf.getTabList(this);
}
return new Control[] { c };
}
/**
* @see ViewActionBars
*/
public IToolBarManager2 getToolBarManager() {
return isvToolBarMgr;
}
/**
* Answer the view part child.
*/
public IViewReference getViewReference() {
return (IViewReference) getPartReference();
}
/**
* Sets the fast view state. If this view is a fast view then
* various controls like pin and minimize are added to the
* system bar.
*/
public void setFast(boolean b) {
}
/* (non-Javadoc)
* Method declared on PartPane.
*/
/* package */
void shellActivated() {
}
/* (non-Javadoc)
* Method declared on PartPane.
*/
/* package */
void shellDeactivated() {
}
/**
* Set the active border.
* @param active
*/
void setActive(boolean active) {
hasFocus = active;
if (getContainer() instanceof PartStack) {
((PartStack) getContainer())
.setActive(active ? StackPresentation.AS_ACTIVE_FOCUS
: StackPresentation.AS_INACTIVE);
}
}
/**
* Indicate focus in part.
*/
public void showFocus(boolean inFocus) {
setActive(inFocus);
}
/**
* Return true if this view is a fast view.
*/
private boolean isFastView() {
return page.isFastView(getViewReference());
}
/**
* Return true if the view may be moved.
*/
boolean isMoveable() {
return !page.isFixedLayout();
}
/**
* Return if there should be a view menu at all.
* There is no view menu if there is no menu manager,
* no pull down button or if the receiver is an
* inactive fast view.
*/
public boolean hasViewMenu() {
if (isvMenuMgr != null) {
return !isvMenuMgr.isEmpty();
}
return false;
}
public void showViewMenu(Point location) {
if (!hasViewMenu()) {
return;
}
// If this is a fast view, it may have been minimized. Do nothing in this case.
if (isFastView() && (page.getActiveFastView() != getViewReference())) {
return;
}
Menu aMenu = isvMenuMgr.createContextMenu(getControl().getParent());
aMenu.setLocation(location.x, location.y);
aMenu.setVisible(true);
}
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode()); //$NON-NLS-1$
}
/**
* @see ViewActionBars
*/
public void updateActionBars() {
if (isvMenuMgr != null) {
isvMenuMgr.update(false);
}
if (isvToolBarMgr != null) {
isvToolBarMgr.update(false);
}
}
/**
* Update the title attributes.
*/
public void updateTitles() {
firePropertyChange(IPresentablePart.PROP_TITLE);
}
/* (non-Javadoc)
* @see org.eclipse.ui.internal.PartPane#addSizeMenuItem(org.eclipse.swt.widgets.Menu)
*/
public void addSizeMenuItem(Menu menu, int index) {
if (isMoveable()) {
super.addSizeMenuItem(menu, index);
}
}
/* (non-Javadoc)
* @see org.eclipse.ui.internal.PartPane#doZoom()
*/
protected void doZoom() {
if (isMoveable()) {
super.doZoom();
}
}
/* (non-Javadoc)
* @see org.eclipse.ui.internal.LayoutPart#setContainer(org.eclipse.ui.internal.ILayoutContainer)
*/
public void setContainer(ILayoutContainer container) {
ILayoutContainer oldContainer = getContainer();
if (hasFocus) {
if (oldContainer != null && oldContainer instanceof PartStack) {
((PartStack) oldContainer)
.setActive(StackPresentation.AS_INACTIVE);
}
if (container != null && container instanceof PartStack) {
((PartStack) container)
.setActive(StackPresentation.AS_ACTIVE_FOCUS);
}
}
super.setContainer(container);
}
/* (non-Javadoc)
* @see org.eclipse.ui.internal.LayoutPart#reparent(org.eclipse.swt.widgets.Composite)
*/
public void reparent(Composite newParent) {
super.reparent(newParent);
if (isvToolBarMgr != null) {
Control bar = isvToolBarMgr.getControl2();
if (bar != null) {
bar.setParent(newParent);
bar.moveAbove(control);
}
}
}
/* (non-Javadoc)
* @see org.eclipse.ui.internal.LayoutPart#moveAbove(org.eclipse.swt.widgets.Control)
*/
public void moveAbove(Control refControl) {
super.moveAbove(refControl);
Control toolbar = internalGetToolbar();
if (toolbar != null) {
toolbar.moveAbove(control);
}
}
/* (non-Javadoc)
* @see org.eclipse.ui.internal.LayoutPart#setVisible(boolean)
*/
public void setVisible(boolean makeVisible) {
super.setVisible(makeVisible);
Control toolbar = internalGetToolbar();
if (toolbar != null) {
boolean visible = makeVisible && toolbarIsVisible();
toolbar.setVisible(visible);
}
}
public boolean toolbarIsVisible() {
IToolBarManager2 toolbarManager = getToolBarManager();
if (toolbarManager == null) {
return false;
}
Control control = toolbarManager.getControl2();
if (control == null || control.isDisposed()) {
return false;
}
return toolbarManager.getItemCount() > 0;
}
/* (non-Javadoc)
* @see org.eclipse.ui.internal.PartPane#showHighlight()
*/
public void showHighlight() {
firePropertyChange(IPresentablePart.PROP_HIGHLIGHT_IF_BACK);
}
/* (non-Javadoc)
* @see org.eclipse.ui.internal.LayoutPart#getPlaceHolderId()
*/
public String getPlaceHolderId() {
return ViewFactory.getKey(getViewReference());
}
/* (non-Javadoc)
* @see org.eclipse.ui.internal.PartPane#getToolBar()
*/
public Control getToolBar() {
if (!toolbarIsVisible()) {
return null;
}
return internalGetToolbar();
}
private Control internalGetToolbar() {
if (isvToolBarMgr == null) {
return null;
}
return isvToolBarMgr.getControl2();
}
/* (non-Javadoc)
* @see org.eclipse.ui.internal.PartPane#isCloseable()
*/
public boolean isCloseable() {
Perspective perspective = page.getActivePerspective();
if (perspective == null) {
// Shouldn't happen -- can't have a ViewStack without a
// perspective
return true;
}
return perspective.isCloseable(getViewReference());
}
public void showSystemMenu() {
if (isFastView()) {
Perspective perspective = page.getActivePerspective();
if (perspective != null) {
perspective.getFastViewPane().showSystemMenu();
}
} else {
super.showSystemMenu();
}
}
public void showPaneMenu() {
if (isFastView()) {
Perspective perspective = page.getActivePerspective();
if (perspective != null) {
perspective.getFastViewPane().showPaneMenu();
}
} else {
super.showPaneMenu();
}
}
public void removeContributions() {
super.removeContributions();
if (isvMenuMgr != null) {
isvMenuMgr.removeAll();
}
if (isvToolBarMgr != null) {
isvToolBarMgr.removeAll();
}
}
}