blob: 6c0a1eba46f41a6e42afdff4e73d0f964578db1c [file] [log] [blame]
package org.eclipse.ui.internal;
/**********************************************************************
Copyright (c) 2000, 2001, 2002, International Business Machines Corp and others.
All rights reserved.   This program and the accompanying materials
are made available under the terms of the Common Public License v0.5
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/cpl-v05.html
 
Contributors:
Cagatay Kavukcuoglu <cagatayk@acm.org>
- Fix for bug 10025 - Resizing views should not use height ratios
**********************************************************************/
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.action.*;
import org.eclipse.jface.resource.JFaceColors;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.*;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.part.WorkbenchPart;
/**
* Provides support for a title bar where the
* title and icon of the view can be displayed.
* Along with an X icon to close the view, and
* a pin icon to attach the view back to the
* main layout.
*
* Also provides support to add tool icons and menu
* icon on the system bar if required by the view
* part.
*/
public class ViewPane extends PartPane
implements IPropertyListener
{
private CLabel titleLabel;
private boolean fast = false;
private boolean showFocus = false;
private ToolBar viewToolBar;
private ToolBarManager viewToolBarMgr;
private ToolBar isvToolBar;
private ToolBarManager isvToolBarMgr;
private MenuManager isvMenuMgr;
private ToolItem pullDownButton;
/**
* Indicates whether a toolbar button is shown for the view local menu.
*/
private boolean showMenuButton = false;
//Created in o.e.ui.Perspective, disposed there.
private Sash fastViewSash;
/**
* Toolbar manager for the ISV toolbar.
*/
class PaneToolBarManager extends ToolBarManager {
public PaneToolBarManager(ToolBar paneToolBar) {
super(paneToolBar);
}
protected void relayout(ToolBar toolBar, int oldCount, int newCount) {
toolBar.layout();
Composite parent = toolBar.getParent();
parent.layout();
if (parent.getParent() != null)
parent.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) {
// Changes to the menu can affect whether the toolbar has a menu button.
// Update it if necessary.
if (showMenuButton != !isEmpty()) {
viewToolBarMgr.update(true);
}
super.update(force, recursive);
}
}
/**
* Contributes system actions to toolbar.
*/
class SystemContribution extends ContributionItem {
public boolean isDynamic() {
return true;
}
public void fill(ToolBar toolbar, int index) {
showMenuButton = (isvMenuMgr != null && !isvMenuMgr.isEmpty());
if (showMenuButton) {
pullDownButton = new ToolItem(toolbar, SWT.PUSH, index++);
Image img = WorkbenchImages.getImage(IWorkbenchGraphicConstants.IMG_LCL_VIEW_MENU);
pullDownButton.setDisabledImage(img); // PR#1GE56QT - Avoid creation of unnecessary image.
pullDownButton.setImage(img);
pullDownButton.setToolTipText(WorkbenchMessages.getString("Menu")); //$NON-NLS-1$
pullDownButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
showViewMenu();
}
});
}
else {
// clear out the button if we don't need it anymore
pullDownButton = null;
}
// check the current internal fast view state
if (fast) {
ToolItem dockButton = new ToolItem(toolbar, SWT.CHECK, index++);
dockButton.setSelection(true);
Image img = WorkbenchImages.getImage(IWorkbenchGraphicConstants.IMG_LCL_PIN_VIEW);
dockButton.setDisabledImage(img); // PR#1GE56QT - Avoid creation of unnecessary image.
dockButton.setImage(img);
dockButton.setToolTipText(WorkbenchMessages.getString("ViewPane.pin")); //$NON-NLS-1$
dockButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
doDock();
}
});
ToolItem minimizeButton = new ToolItem(toolbar, SWT.PUSH, index++);
img = WorkbenchImages.getImage(IWorkbenchGraphicConstants.IMG_LCL_MIN_VIEW);
minimizeButton.setDisabledImage(img); // PR#1GE56QT - Avoid creation of unnecessary image.
minimizeButton.setImage(img);
minimizeButton.setToolTipText(WorkbenchMessages.getString("ViewPane.minimize")); //$NON-NLS-1$
minimizeButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
doMinimize();
}
});
}
ToolItem closeButton= new ToolItem(toolbar, SWT.PUSH, index++);
Image img = WorkbenchImages.getImage(IWorkbenchGraphicConstants.IMG_LCL_CLOSE_VIEW);
closeButton.setDisabledImage(img); // PR#1GE56QT - Avoid creation of unnecessary image.
closeButton.setImage(img);
closeButton.setToolTipText(WorkbenchMessages.getString("Close")); //$NON-NLS-1$
closeButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
doHide();
}
});
}
}
private SystemContribution systemContribution = new SystemContribution();
/**
* Constructs a view pane for a view part.
*/
public ViewPane(IViewReference ref, WorkbenchPage page) {
super(ref, page);
}
/**
* Create control. Add the title bar.
*/
public void createControl(Composite parent) {
// Only do this once.
if (getControl() != null && !getControl().isDisposed())
return;
super.createControl(parent);
// Only include the ISV toolbar and the content in the tab list.
// All actions on the System toolbar should be accessible on the pane menu.
if (control.getContent() == null) {
// content can be null if view creation failed
control.setTabList(new Control[] { isvToolBar, viewToolBar });
}
else {
control.setTabList(new Control[] { isvToolBar, viewToolBar, control.getContent() });
}
}
protected void createChildControl() {
final IWorkbenchPart part[] = new IWorkbenchPart[]{partReference.getPart(false)};
if(part[0] == null)
return;
if(control == null || control.getContent() != null)
return;
super.createChildControl();
Platform.run(new SafeRunnable() {
public void run() {
// Install the part's tools and menu
ViewActionBuilder builder = new ViewActionBuilder();
IViewPart part = (IViewPart)getViewReference().getPart(true);
if(part != null) {
builder.readActionExtensions(part);
ActionDescriptor[] extendedActions = builder.getExtendedActions();
KeyBindingService keyBindingService = (KeyBindingService)part.getSite().getKeyBindingService();
keyBindingService.registerExtendedActions(extendedActions);
}
updateActionBars();
}
public void handleException(Throwable e) {
//Just have it logged.
}
});
}
protected WorkbenchPart createErrorPart(WorkbenchPart oldPart) {
class ErrorViewPart extends ViewPart {
private Text text;
public void createPartControl(Composite parent) {
text = new Text(parent,SWT.MULTI|SWT.READ_ONLY|SWT.WRAP);
text.setForeground(JFaceColors.getErrorText(text.getDisplay()));
text.setBackground(text.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
text.setText(WorkbenchMessages.getString("ViewPane.errorMessage")); //$NON-NLS-1$
}
public void setFocus() {
if (text != null) text.setFocus();
}
public void setSite(IWorkbenchPartSite site) {
super.setSite(site);
}
public void setTitle(String title) {
super.setTitle(title);
}
}
ErrorViewPart newPart = new ErrorViewPart();
PartSite site = (PartSite)oldPart.getSite();
newPart.setSite(site);
newPart.setTitle(site.getRegisteredName());
site.setPart(newPart);
return newPart;
}
/**
* See LayoutPart
*/
public boolean isDragAllowed(Point p) {
// See also similar restrictions in addMoveItems method
// No need to worry about fast views as they do not
// register for D&D operations
return !overImage(p.x) && !isZoomed();
}
/*
* Return true if <code>x</code> is over the label image.
*/
private boolean overImage(int x) {
return x < titleLabel.getImage().getBounds().width;
}
/**
* 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.
if (titleLabel != null)
return;
// Title.
titleLabel = new CLabel(control, SWT.SHADOW_NONE);
titleLabel.setAlignment(SWT.LEFT);
titleLabel.setBackground(null, null);
titleLabel.addMouseListener(new MouseAdapter() {
public void mouseDown(MouseEvent e) {
if (e.button == 3)
showPaneMenu(titleLabel,new Point(e.x, e.y));
else if ((e.button == 1) && overImage(e.x))
showPaneMenu();
}
public void mouseDoubleClick(MouseEvent event){
doZoom();
}
});
updateTitles();
control.setTopLeft(titleLabel);
// Listen to title changes.
getPartReference().addPropertyListener(this);
// View toolbar
viewToolBar = new ToolBar(control, SWT.FLAT | SWT.WRAP);
control.setTopRight(viewToolBar);
viewToolBar.addMouseListener(new MouseAdapter(){
public void mouseDoubleClick(MouseEvent event) {
// 1GD0ISU: ITPUI:ALL - Dbl click on view tool cause zoom
if (viewToolBar.getItem(new Point(event.x, event.y)) == null)
doZoom();
}
});
viewToolBarMgr = new PaneToolBarManager(viewToolBar);
viewToolBarMgr.add(systemContribution);
// ISV toolbar.
isvToolBar = new ToolBar(control, SWT.FLAT | SWT.WRAP);
control.setTopCenter(isvToolBar);
isvToolBar.addMouseListener(new MouseAdapter(){
public void mouseDoubleClick(MouseEvent event) {
// 1GD0ISU: ITPUI:ALL - Dbl click on view tool cause zoom
if (isvToolBar.getItem(new Point(event.x, event.y)) == null)
doZoom();
}
});
isvToolBarMgr = new PaneToolBarManager(isvToolBar);
}
/**
* @see PartPane#doHide
*/
public void doHide() {
getPage().hideView(getViewReference());
}
/**
* Make this view pane a fast view
*/
protected void doMakeFast() {
getPage().addFastView(getViewReference());
}
/**
* Hide the fast view
*/
protected void doMinimize() {
getPage().toggleFastView(getViewReference());
}
/**
* Pin the view.
*/
protected void doDock() {
getPage().removeFastView(getViewReference());
}
/**
* Draws the applicable gradient on the view's title area
*/
/* package */ void drawGradient() {
if (titleLabel == null || viewToolBar == null || isvToolBar == null)
return;
if (showFocus) {
if (getShellActivated()) {
titleLabel.setBackground(WorkbenchColors.getActiveViewGradient(), WorkbenchColors.getActiveViewGradientPercents());
titleLabel.setForeground(WorkbenchColors.getSystemColor(SWT.COLOR_TITLE_FOREGROUND));
titleLabel.update();
viewToolBar.setBackground(WorkbenchColors.getActiveViewGradientEnd());
isvToolBar.setBackground(WorkbenchColors.getActiveViewGradientEnd());
}
else {
titleLabel.setBackground(WorkbenchColors.getDeactivatedViewGradient(), WorkbenchColors.getDeactivatedViewGradientPercents());
titleLabel.setForeground(WorkbenchColors.getSystemColor(SWT.COLOR_TITLE_INACTIVE_FOREGROUND));
titleLabel.update();
viewToolBar.setBackground(WorkbenchColors.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
isvToolBar.setBackground(WorkbenchColors.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
}
}
else {
titleLabel.setBackground(null, null);
titleLabel.setForeground(null);
titleLabel.update();
viewToolBar.setBackground(WorkbenchColors.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
isvToolBar.setBackground(WorkbenchColors.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
}
}
/**
* Returns the drag control.
*/
public Control getDragHandle() {
return titleLabel;
}
/**
* @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 PartTabFolder) {
PartTabFolder tf = (PartTabFolder) getContainer();
CTabFolder f = (CTabFolder) tf.getControl();
if (f.getItemCount() > 1) {
if ((f.getStyle() & SWT.TOP) != 0) {
return new Control[] { f, c };
}
else {
return new Control[] { c, f };
}
}
}
return new Control[] { c };
}
/**
* @see ViewActionBars
*/
public ToolBarManager getToolBarManager() {
return isvToolBarMgr;
}
/**
* Answer the view part child.
*/
public IViewReference getViewReference() {
return (IViewReference)getPartReference();
}
/**
* Indicates that a property has changed.
*
* @param source the object whose property has changed
* @param propId the id of the property which has changed; property ids
* are generally defined as constants on the source class
*/
public void propertyChanged(Object source, int propId) {
if (propId == IWorkbenchPart.PROP_TITLE)
updateTitles();
}
/**
* 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) {
fast = b;
if (viewToolBarMgr != null) {
viewToolBarMgr.update(true);
}
}
public void setFastViewSash(Sash s) {
fastViewSash = s;
}
/* (non-Javadoc)
* Method declared on PartPane.
*/
/* package */ void shellActivated() {
drawGradient();
}
/* (non-Javadoc)
* Method declared on PartPane.
*/
/* package */ void shellDeactivated() {
drawGradient();
}
/**
* Indicate focus in part.
*/
public void showFocus(boolean inFocus) {
if (titleLabel == null)
return;
showFocus = inFocus;
drawGradient();
}
/**
* Shows the pane menu (system menu) for this pane.
*/
public void showPaneMenu() {
// If this is a fast view, it may have been minimized. Do nothing in this case.
if(isFastView() && (page.getActiveFastView() != getViewReference()))
return;
Rectangle bounds = titleLabel.getBounds();
showPaneMenu(titleLabel,new Point(0,bounds.height));
}
/**
* Return true if this view is a fast view.
*/
private boolean isFastView() {
return page.isFastView(getViewReference());
}
/**
* Finds and return the sashes around this part.
*/
protected Sashes findSashes() {
Sashes result = new Sashes();
if(isFastView()) {
result.right = fastViewSash;
return result;
}
RootLayoutContainer container = getRootContainer();
if(container == null)
return result;
if (this.getContainer() instanceof PartTabFolder)
container.findSashes((PartTabFolder)this.getContainer(),result);
else
container.findSashes(this,result);
return result;
}
/**
* Add the Fast View menu item to the view title menu.
*/
protected void addFastViewMenuItem(Menu parent,boolean isFastView) {
// add fast view item
MenuItem item = new MenuItem(parent, SWT.CHECK);
item.setText(WorkbenchMessages.getString("ViewPane.fastView")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
if (isFastView())
doDock();
else
doMakeFast();
}
});
item.setSelection(isFastView);
if(isFastView) {
item = new MenuItem(parent, SWT.NONE);
item.setText(WorkbenchMessages.getString("ViewPane.minimizeView")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
doMinimize();
}
});
item.setEnabled(true);
}
}
/**
* Add the View and Tab Group items to the Move menu.
*/
protected void addMoveItems(Menu moveMenu) {
// See also similar restrictions in isDragAllowed method.
// No need to worry about mouse cursor over image, just
// fast views.
boolean moveAllowed = !isZoomed() && !isFastView();
// Add move view only menu item
MenuItem item = new MenuItem(moveMenu, SWT.NONE);
item.setText(WorkbenchMessages.getString("ViewPane.moveView")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
page.openTracker(ViewPane.this);
}
});
item.setEnabled(moveAllowed);
// Add move view's tab folder menu item
item = new MenuItem(moveMenu, SWT.NONE);
item.setText(WorkbenchMessages.getString("ViewPane.moveFolder")); //$NON-NLS-1$
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
ILayoutContainer container = getContainer();
if (container instanceof PartTabFolder)
((PartTabFolder)container).openTracker((PartTabFolder)container);
}
});
item.setEnabled(moveAllowed && (getContainer() instanceof PartTabFolder));
}
/**
* 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 false;
//If there is no pull down button there is no associated menu
if(pullDownButton == null || pullDownButton.isDisposed())
return false;
return true;
}
/**
* Show the view menu for this window.
*/
public void showViewMenu() {
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());
Rectangle bounds = pullDownButton.getBounds();
Point topLeft = new Point(bounds.x, bounds.y + bounds.height);
topLeft = viewToolBar.toDisplay(topLeft);
aMenu.setLocation(topLeft.x, topLeft.y);
aMenu.setVisible(true);
}
/**
* @see IPartDropTarget::targetPartFor
*/
public LayoutPart targetPartFor(LayoutPart dragSource) {
// When zoomed, its like we are not part of the
// tab folder so return the view.
if (isZoomed())
return this;
// Make use of the container if a tab folder
ILayoutContainer container = getContainer();
if (container instanceof PartTabFolder)
return (PartTabFolder) container;
else
return this;
}
public String toString() {
String label = "disposed";//$NON-NLS-1$
if((titleLabel != null) && (!titleLabel.isDisposed()))
label = titleLabel.getText();
return getClass().getName() + "@" + Integer.toHexString(hashCode()) + //$NON-NLS-1$
"(" + label + ")";//$NON-NLS-2$//$NON-NLS-1$
}
/**
* @see ViewActionBars
*/
public void updateActionBars() {
if (isvMenuMgr != null)
isvMenuMgr.updateAll(false);
if (viewToolBarMgr != null)
viewToolBarMgr.update(false);
if (isvToolBarMgr != null)
isvToolBarMgr.update(false);
}
/**
* Update the title attributes.
*/
public void updateTitles() {
IViewReference ref = getViewReference();
String text = ref.getTitle();
if (text == null)
text = "";//$NON-NLS-1$
Image image = ref.getTitleImage();
// only update and relayout if text or image has changed
if (!text.equals(titleLabel.getText()) || image != titleLabel.getImage()) {
titleLabel.setText(text);
titleLabel.setImage(image);
((Composite) getControl()).layout();
}
titleLabel.setToolTipText(ref.getTitleToolTip());
// XXX: Workaround for 1GCGA89: SWT:ALL - CLabel tool tip does not always update properly
titleLabel.update();
// notify the page that this view's title has changed
// in case it needs to update its fast view button
page.updateTitle(ref);
}
}