blob: 815c2023ad52dce03429a9d7ad8cdeaf0e344c75 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2005 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.presentations;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.swt.graphics.Image;
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.ui.IPropertyListener;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.PartPane;
import org.eclipse.ui.internal.WorkbenchPartReference;
import org.eclipse.ui.internal.dnd.SwtUtil;
import org.eclipse.ui.presentations.IPartMenu;
import org.eclipse.ui.presentations.IPresentablePart;
/**
* This is a lightweight adapter that allows PartPanes to be used by a StackPresentation. All methods
* either redirect directly to PartPane or do trivial type conversions. All listeners registered by
* the presentation are kept here rather than registering them directly on the PartPane. This allows
* us to remove all listeners registered by a presentation that has been disposed, offering some
* protection against memory leaks.
*/
public class PresentablePart implements IPresentablePart {
private PartPane part;
/**
* Local listener list -- we use this rather than registering listeners directly on the part
* in order to protect against memory leaks in badly behaved presentations.
*/
private List listeners = new ArrayList();
// Lazily initialized. Use getPropertyListenerProxy() to access.
private IPropertyListener lazyPropertyListenerProxy;
// Lazily initialized. Use getMenu() to access
private IPartMenu viewMenu;
// True iff the "set" methods on this object are talking to the real part (disabled
// if the part is currently being managed by another presentation stack)
private boolean enableInputs = true;
// True iff the "get" methods are returning up-to-date info from the real part (disabled
// for efficency if the presentation is invisible)
private boolean enableOutputs = true;
private Rectangle savedBounds = new Rectangle(0,0,0,0);
private boolean isVisible = false;
// Saved state (only used when the part is inactive)
private String name = ""; //$NON-NLS-1$
private String titleStatus = ""; //$NON-NLS-1$
private boolean isDirty = false;
private boolean isBusy = false;
private boolean hasViewMenu = false;
/**
* Constructor
*
* @param part
*/
public PresentablePart(PartPane part, Composite parent) {
this.part = part;
getPane().addPropertyListener(getPropertyListenerProxy());
}
public PartPane getPane() {
return part;
}
private IPropertyListener getPropertyListenerProxy() {
if (lazyPropertyListenerProxy == null) {
lazyPropertyListenerProxy = new IPropertyListener() {
public void propertyChanged(Object source, int propId) {
firePropertyChange(propId);
}
};
}
return lazyPropertyListenerProxy;
}
/**
* Detach this PresentablePart from the real part. No further methods should be invoked
* on this object.
*/
public void dispose() {
// Ensure that the property listener is detached (necessary to prevent leaks)
getPane().removePropertyListener(getPropertyListenerProxy());
// Null out the various fields to ease garbage collection (optional)
part = null;
listeners.clear();
listeners = null;
}
public void firePropertyChange(int propertyId) {
for (int i = 0; i < listeners.size(); i++) {
((IPropertyListener) listeners.get(i)).propertyChanged(this, propertyId);
}
}
public void addPropertyListener(final IPropertyListener listener) {
listeners.add(listener);
}
public void removePropertyListener(final IPropertyListener listener) {
listeners.remove(listener);
}
/* (non-Javadoc)
* @see org.eclipse.ui.presentations.IPresentablePart#setBounds(org.eclipse.swt.graphics.Rectangle)
*/
public void setBounds(Rectangle bounds) {
savedBounds = bounds;
if (enableInputs && !SwtUtil.isDisposed(part.getControl())) {
part.setBounds(bounds);
}
}
/* (non-Javadoc)
* @see org.eclipse.ui.presentations.IPresentablePart#setVisible(boolean)
*/
public void setVisible(boolean isVisible) {
this.isVisible = isVisible;
if (enableInputs) {
part.setVisible(isVisible);
}
}
/* (non-Javadoc)
* @see org.eclipse.ui.presentations.IPresentablePart#setFocus()
*/
public void setFocus() {
if (!SwtUtil.isDisposed(part.getControl())) {
if (part.getPage().getActivePart() == part.getPartReference().getPart(false)) {
part.setFocus();
} else {
part.requestActivation();
}
}
}
private WorkbenchPartReference getPartReference() {
return (WorkbenchPartReference) part.getPartReference();
}
/* (non-Javadoc)
* @see org.eclipse.ui.presentations.IPresentablePart#getName()
*/
public String getName() {
if (enableOutputs) {
return getPartReference().getPartName();
}
return name;
}
/* (non-Javadoc)
* @see org.eclipse.ui.presentations.IPresentablePart#getTitle()
*/
public String getTitle() {
return getPartReference().getTitle();
}
/* (non-Javadoc)
* @see org.eclipse.ui.presentations.IPresentablePart#getTitleStatus()
*/
public String getTitleStatus() {
if (enableOutputs) {
return getPartReference().getContentDescription();
}
return titleStatus;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.presentations.IPresentablePart#getTitleImage()
*/
public Image getTitleImage() {
//
// return PlatformUI.getWorkbench().getSharedImages().getImage(
// ISharedImages.IMG_DEF_VIEW);
//
if (enableOutputs) {
return getPartReference().getTitleImage();
}
return PlatformUI.getWorkbench().getSharedImages().getImage(
ISharedImages.IMG_DEF_VIEW);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.presentations.IPresentablePart#getTitleToolTip()
*/
public String getTitleToolTip() {
return getPartReference().getTitleToolTip();
}
/* (non-Javadoc)
* @see org.eclipse.ui.presentations.IPresentablePart#isDirty()
*/
public boolean isDirty() {
if (enableOutputs) {
return getPartReference().isDirty();
}
return isDirty;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.presentations.IPresentablePart#isBusy()
*/
public boolean isBusy() {
if (enableOutputs) {
return part.isBusy();
}
return isBusy;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.presentations.IPresentablePart#getToolBar()
*/
public Control getToolBar() {
if (enableOutputs) {
return getPane().getToolBar();
}
return null;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.presentations.IPresentablePart#getMenu()
*/
public IPartMenu getMenu() {
boolean hasMenu;
if (enableOutputs) {
hasMenu = part.hasViewMenu();
} else {
hasMenu = this.hasViewMenu;
}
if (!hasMenu) {
return null;
}
if (viewMenu == null) {
viewMenu = new IPartMenu() {
public void showMenu(Point location) {
part.showViewMenu(location);
}
};
}
return viewMenu;
}
/* (non-Javadoc)
* @see org.eclipse.ui.presentations.IPresentablePart#isCloseable()
*/
public boolean isCloseable() {
return part.isCloseable();
}
/* (non-Javadoc)
* @see org.eclipse.ui.presentations.IPresentablePart#getControl()
*/
public Control getControl() {
return part.getControl();
}
public void enableOutputs(boolean isActive) {
if (isActive == this.enableOutputs) {
return;
}
this.enableOutputs = isActive;
if (isActive) {
if (isBusy != getPane().isBusy()) {
firePropertyChange(PROP_BUSY);
}
if (isDirty != isDirty()) {
firePropertyChange(PROP_DIRTY);
}
if (!name.equals(getName())) {
firePropertyChange(PROP_PART_NAME);
}
if (!titleStatus.equals(getTitleStatus())) {
firePropertyChange(PROP_CONTENT_DESCRIPTION);
}
if (hasViewMenu != getPane().hasViewMenu()) {
firePropertyChange(PROP_PANE_MENU);
}
// Always assume that the toolbar and title has changed (keeping track of this for real
// would be too expensive)
firePropertyChange(PROP_TOOLBAR);
firePropertyChange(PROP_TITLE);
getPane().addPropertyListener(getPropertyListenerProxy());
} else {
getPane().removePropertyListener(getPropertyListenerProxy());
WorkbenchPartReference ref = getPartReference();
isBusy = getPane().isBusy();
isDirty = ref.isDirty();
name = ref.getPartName();
titleStatus = ref.getContentDescription();
hasViewMenu = getPane().hasViewMenu();
firePropertyChange(PROP_TITLE);
firePropertyChange(PROP_TOOLBAR);
}
}
public void enableInputs(boolean isActive) {
if (isActive == this.enableInputs) {
return;
}
this.enableInputs = isActive;
if (isActive) {
if (isActive && !SwtUtil.isDisposed(part.getControl())) {
part.setBounds(savedBounds);
}
part.setVisible(isVisible);
}
}
}