blob: bd07f38430211f55c3d50905b368c807e5ffc2d8 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2004 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.jface.action;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IProgressMonitorWithBlocking;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
/**
* A status line manager is a contribution manager which realizes itself and its items
* in a status line control.
* <p>
* This class may be instantiated; it may also be subclassed if a more
* sophisticated layout is required.
* </p>
*/
public class StatusLineManager extends ContributionManager implements
IStatusLineManager {
/**
* Identifier of group marker used to position contributions at the beginning
* of the status line.
*
* @since 3.0
*/
public static final String BEGIN_GROUP = "BEGIN_GROUP"; //$NON-NLS-1$
/**
* Identifier of group marker used to position contributions in the middle
* of the status line.
*
* @since 3.0
*/
public static final String MIDDLE_GROUP = "MIDDLE_GROUP"; //$NON-NLS-1$
/**
* Identifier of group marker used to position contributions at the end
* of the status line.
*
* @since 3.0
*/
public static final String END_GROUP = "END_GROUP"; //$NON-NLS-1$
/**
* The status line control; <code>null</code> before
* creation and after disposal.
*/
private Composite statusLine = null;
/**
* Creates a new status line manager.
* Use the <code>createControl</code> method to create the
* status line control.
*/
public StatusLineManager() {
add(new GroupMarker(BEGIN_GROUP));
add(new GroupMarker(MIDDLE_GROUP));
add(new GroupMarker(END_GROUP));
}
/**
* Creates and returns this manager's status line control.
* Does not create a new control if one already exists.
* <p>
* Note: Since 3.0 the return type is <code>Control</code>. Before 3.0, the return type was
* the package-private class <code>StatusLine</code>.
* </p>
*
* @param parent the parent control
* @return the status line control
*/
public Control createControl(Composite parent) {
return createControl(parent, SWT.NONE);
}
/**
* Creates and returns this manager's status line control.
* Does not create a new control if one already exists.
*
* @param parent the parent control
* @param style the style for the control
* @return the status line control
* @since 3.0
*/
public Control createControl(Composite parent, int style) {
if (!statusLineExist() && parent != null) {
statusLine = new StatusLine(parent, style);
update(false);
}
return statusLine;
}
/**
* Disposes of this status line manager and frees all allocated SWT resources.
* Notifies all contribution items of the dispose. Note that this method does
* not clean up references between this status line manager and its associated
* contribution items. Use <code>removeAll</code> for that purpose.
*/
public void dispose() {
if (statusLineExist())
statusLine.dispose();
statusLine = null;
IContributionItem items[] = getItems();
for (int i = 0; i < items.length; i++) {
items[i].dispose();
}
}
/**
* Returns the control used by this StatusLineManager.
*
* @return the control used by this manager
*/
public Control getControl() {
return statusLine;
}
/**
* Returns the progress monitor delegate. Override this method
* to provide your own object used to handle progress.
*
* @return the IProgressMonitor delegate
* @since 3.0
*/
protected IProgressMonitor getProgressMonitorDelegate() {
return (IProgressMonitor) getControl();
}
/*
* (non-Javadoc)
* Method declared on IStatusLineManager
*/
public IProgressMonitor getProgressMonitor() {
return new IProgressMonitorWithBlocking() {
IProgressMonitor progressDelegate = getProgressMonitorDelegate();
/* (non-Javadoc)
* @see org.eclipse.core.runtime.IProgressMonitor#beginTask(java.lang.String, int)
*/
public void beginTask(String name, int totalWork) {
progressDelegate.beginTask(name, totalWork);
}
/* (non-Javadoc)
* @see org.eclipse.core.runtime.IProgressMonitor#done()
*/
public void done() {
progressDelegate.done();
}
/* (non-Javadoc)
* @see org.eclipse.core.runtime.IProgressMonitor#internalWorked(double)
*/
public void internalWorked(double work) {
progressDelegate.internalWorked(work);
}
/* (non-Javadoc)
* @see org.eclipse.core.runtime.IProgressMonitor#isCanceled()
*/
public boolean isCanceled() {
return progressDelegate.isCanceled();
}
/* (non-Javadoc)
* @see org.eclipse.core.runtime.IProgressMonitor#setCanceled(boolean)
*/
public void setCanceled(boolean value) {
//Don't bother updating for disposed status
if (statusLine.isDisposed())
return;
progressDelegate.setCanceled(value);
}
/* (non-Javadoc)
* @see org.eclipse.core.runtime.IProgressMonitor#setTaskName(java.lang.String)
*/
public void setTaskName(String name) {
progressDelegate.setTaskName(name);
}
/* (non-Javadoc)
* @see org.eclipse.core.runtime.IProgressMonitor#subTask(java.lang.String)
*/
public void subTask(String name) {
progressDelegate.subTask(name);
}
/* (non-Javadoc)
* @see org.eclipse.core.runtime.IProgressMonitor#worked(int)
*/
public void worked(int work) {
progressDelegate.worked(work);
}
/* (non-Javadoc)
* @see org.eclipse.core.runtime.IProgressMonitorWithBlocking#clearBlocked()
*/
public void clearBlocked() {
//Do nothing here as we let the modal context handle it
}
/* (non-Javadoc)
* @see org.eclipse.core.runtime.IProgressMonitorWithBlocking#setBlocked(org.eclipse.core.runtime.IStatus)
*/
public void setBlocked(IStatus reason) {
// Do nothing here as we let the modal context handle it
}
};
}
/* (non-Javadoc)
* Method declared on IStatueLineManager
*/
public boolean isCancelEnabled() {
return statusLineExist() && ((StatusLine) statusLine).isCancelEnabled();
}
/* (non-Javadoc)
* Method declared on IStatueLineManager
*/
public void setCancelEnabled(boolean enabled) {
if (statusLineExist())
((StatusLine) statusLine).setCancelEnabled(enabled);
}
/* (non-Javadoc)
* Method declared on IStatusLineManager.
*/
public void setErrorMessage(String message) {
if (statusLineExist())
((StatusLine) statusLine).setErrorMessage(message);
}
/* (non-Javadoc)
* Method declared on IStatusLineManager.
*/
public void setErrorMessage(Image image, String message) {
if (statusLineExist())
((StatusLine) statusLine).setErrorMessage(image, message);
}
/* (non-Javadoc)
* Method declared on IStatusLineManager.
*/
public void setMessage(String message) {
if (statusLineExist())
((StatusLine) statusLine).setMessage(message);
}
/* (non-Javadoc)
* Method declared on IStatusLineManager.
*/
public void setMessage(Image image, String message) {
if (statusLineExist())
((StatusLine) statusLine).setMessage(image, message);
}
/**
* Returns whether the status line control is created
* and not disposed.
*
* @return <code>true</code> if the control is created
* and not disposed, <code>false</code> otherwise
*/
private boolean statusLineExist() {
return statusLine != null && !statusLine.isDisposed();
}
/* (non-Javadoc)
* Method declared on IContributionManager.
*/
public void update(boolean force) {
//boolean DEBUG= false;
if (isDirty() || force) {
if (statusLineExist()) {
statusLine.setRedraw(false);
// NOTE: the update algorithm is non-incremental.
// An incremental algorithm requires that SWT items can be created in the middle of the list
// but the ContributionItem.fill(Composite) method used here does not take an index, so this
// is not possible.
Control ws[] = statusLine.getChildren();
for (int i = 0; i < ws.length; i++) {
Control w = ws[i];
Object data = w.getData();
if (data instanceof IContributionItem) {
w.dispose();
}
}
int oldChildCount = statusLine.getChildren().length;
IContributionItem[] items = getItems();
for (int i = 0; i < items.length; ++i) {
IContributionItem ci = items[i];
if (ci.isVisible()) {
ci.fill(statusLine);
// associate controls with contribution item
Control[] newChildren = statusLine.getChildren();
for (int j = oldChildCount; j < newChildren.length; j++) {
newChildren[j].setData(ci);
}
oldChildCount = newChildren.length;
}
}
setDirty(false);
statusLine.layout();
statusLine.setRedraw(true);
}
}
}
}