001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jface.action;
011:
012: import org.eclipse.core.runtime.IProgressMonitor;
013: import org.eclipse.core.runtime.IProgressMonitorWithBlocking;
014: import org.eclipse.core.runtime.IStatus;
015: import org.eclipse.swt.SWT;
016: import org.eclipse.swt.graphics.Image;
017: import org.eclipse.swt.widgets.Composite;
018: import org.eclipse.swt.widgets.Control;
019:
020: /**
021: * A status line manager is a contribution manager which realizes itself and its items
022: * in a status line control.
023: * <p>
024: * This class may be instantiated; it may also be subclassed if a more
025: * sophisticated layout is required.
026: * </p>
027: */
028: public class StatusLineManager extends ContributionManager implements
029: IStatusLineManager {
030:
031: /**
032: * Identifier of group marker used to position contributions at the beginning
033: * of the status line.
034: *
035: * @since 3.0
036: */
037: public static final String BEGIN_GROUP = "BEGIN_GROUP"; //$NON-NLS-1$
038:
039: /**
040: * Identifier of group marker used to position contributions in the middle
041: * of the status line.
042: *
043: * @since 3.0
044: */
045: public static final String MIDDLE_GROUP = "MIDDLE_GROUP"; //$NON-NLS-1$
046:
047: /**
048: * Identifier of group marker used to position contributions at the end
049: * of the status line.
050: *
051: * @since 3.0
052: */
053: public static final String END_GROUP = "END_GROUP"; //$NON-NLS-1$
054:
055: /**
056: * The status line control; <code>null</code> before
057: * creation and after disposal.
058: */
059: private Composite statusLine = null;
060:
061: /**
062: * Creates a new status line manager.
063: * Use the <code>createControl</code> method to create the
064: * status line control.
065: */
066: public StatusLineManager() {
067: add(new GroupMarker(BEGIN_GROUP));
068: add(new GroupMarker(MIDDLE_GROUP));
069: add(new GroupMarker(END_GROUP));
070: }
071:
072: /**
073: * Creates and returns this manager's status line control.
074: * Does not create a new control if one already exists.
075: * <p>
076: * Note: Since 3.0 the return type is <code>Control</code>. Before 3.0, the return type was
077: * the package-private class <code>StatusLine</code>.
078: * </p>
079: *
080: * @param parent the parent control
081: * @return the status line control
082: */
083: public Control createControl(Composite parent) {
084: return createControl(parent, SWT.NONE);
085: }
086:
087: /**
088: * Creates and returns this manager's status line control.
089: * Does not create a new control if one already exists.
090: *
091: * @param parent the parent control
092: * @param style the style for the control
093: * @return the status line control
094: * @since 3.0
095: */
096: public Control createControl(Composite parent, int style) {
097: if (!statusLineExist() && parent != null) {
098: statusLine = new StatusLine(parent, style);
099: update(false);
100: }
101: return statusLine;
102: }
103:
104: /**
105: * Disposes of this status line manager and frees all allocated SWT resources.
106: * Notifies all contribution items of the dispose. Note that this method does
107: * not clean up references between this status line manager and its associated
108: * contribution items. Use <code>removeAll</code> for that purpose.
109: */
110: public void dispose() {
111: if (statusLineExist()) {
112: statusLine.dispose();
113: }
114: statusLine = null;
115:
116: IContributionItem items[] = getItems();
117: for (int i = 0; i < items.length; i++) {
118: items[i].dispose();
119: }
120: }
121:
122: /**
123: * Returns the control used by this StatusLineManager.
124: *
125: * @return the control used by this manager
126: */
127: public Control getControl() {
128: return statusLine;
129: }
130:
131: /**
132: * Returns the progress monitor delegate. Override this method
133: * to provide your own object used to handle progress.
134: *
135: * @return the IProgressMonitor delegate
136: * @since 3.0
137: */
138: protected IProgressMonitor getProgressMonitorDelegate() {
139: return (IProgressMonitor) getControl();
140: }
141:
142: /*
143: * (non-Javadoc)
144: * Method declared on IStatusLineManager
145: */
146: public IProgressMonitor getProgressMonitor() {
147:
148: return new IProgressMonitorWithBlocking() {
149:
150: IProgressMonitor progressDelegate = getProgressMonitorDelegate();
151:
152: /* (non-Javadoc)
153: * @see org.eclipse.core.runtime.IProgressMonitor#beginTask(java.lang.String, int)
154: */
155: public void beginTask(String name, int totalWork) {
156: progressDelegate.beginTask(name, totalWork);
157:
158: }
159:
160: /* (non-Javadoc)
161: * @see org.eclipse.core.runtime.IProgressMonitor#done()
162: */
163: public void done() {
164: progressDelegate.done();
165: }
166:
167: /* (non-Javadoc)
168: * @see org.eclipse.core.runtime.IProgressMonitor#internalWorked(double)
169: */
170: public void internalWorked(double work) {
171: progressDelegate.internalWorked(work);
172:
173: }
174:
175: /* (non-Javadoc)
176: * @see org.eclipse.core.runtime.IProgressMonitor#isCanceled()
177: */
178: public boolean isCanceled() {
179: return progressDelegate.isCanceled();
180: }
181:
182: /* (non-Javadoc)
183: * @see org.eclipse.core.runtime.IProgressMonitor#setCanceled(boolean)
184: */
185: public void setCanceled(boolean value) {
186: //Don't bother updating for disposed status
187: if (statusLine.isDisposed()) {
188: return;
189: }
190: progressDelegate.setCanceled(value);
191:
192: }
193:
194: /* (non-Javadoc)
195: * @see org.eclipse.core.runtime.IProgressMonitor#setTaskName(java.lang.String)
196: */
197: public void setTaskName(String name) {
198: progressDelegate.setTaskName(name);
199:
200: }
201:
202: /* (non-Javadoc)
203: * @see org.eclipse.core.runtime.IProgressMonitor#subTask(java.lang.String)
204: */
205: public void subTask(String name) {
206: progressDelegate.subTask(name);
207:
208: }
209:
210: /* (non-Javadoc)
211: * @see org.eclipse.core.runtime.IProgressMonitor#worked(int)
212: */
213: public void worked(int work) {
214: progressDelegate.worked(work);
215: }
216:
217: /* (non-Javadoc)
218: * @see org.eclipse.core.runtime.IProgressMonitorWithBlocking#clearBlocked()
219: */
220: public void clearBlocked() {
221: //Do nothing here as we let the modal context handle it
222: }
223:
224: /* (non-Javadoc)
225: * @see org.eclipse.core.runtime.IProgressMonitorWithBlocking#setBlocked(org.eclipse.core.runtime.IStatus)
226: */
227: public void setBlocked(IStatus reason) {
228: // Do nothing here as we let the modal context handle it
229: }
230: };
231: }
232:
233: /* (non-Javadoc)
234: * Method declared on IStatueLineManager
235: */
236: public boolean isCancelEnabled() {
237: return statusLineExist()
238: && ((StatusLine) statusLine).isCancelEnabled();
239: }
240:
241: /* (non-Javadoc)
242: * Method declared on IStatueLineManager
243: */
244: public void setCancelEnabled(boolean enabled) {
245: if (statusLineExist()) {
246: ((StatusLine) statusLine).setCancelEnabled(enabled);
247: }
248: }
249:
250: /* (non-Javadoc)
251: * Method declared on IStatusLineManager.
252: */
253: public void setErrorMessage(String message) {
254: if (statusLineExist()) {
255: ((StatusLine) statusLine).setErrorMessage(message);
256: }
257: }
258:
259: /* (non-Javadoc)
260: * Method declared on IStatusLineManager.
261: */
262: public void setErrorMessage(Image image, String message) {
263: if (statusLineExist()) {
264: ((StatusLine) statusLine).setErrorMessage(image, message);
265: }
266: }
267:
268: /* (non-Javadoc)
269: * Method declared on IStatusLineManager.
270: */
271: public void setMessage(String message) {
272: if (statusLineExist()) {
273: ((StatusLine) statusLine).setMessage(message);
274: }
275: }
276:
277: /* (non-Javadoc)
278: * Method declared on IStatusLineManager.
279: */
280: public void setMessage(Image image, String message) {
281: if (statusLineExist()) {
282: ((StatusLine) statusLine).setMessage(image, message);
283: }
284: }
285:
286: /**
287: * Returns whether the status line control is created
288: * and not disposed.
289: *
290: * @return <code>true</code> if the control is created
291: * and not disposed, <code>false</code> otherwise
292: */
293: private boolean statusLineExist() {
294: return statusLine != null && !statusLine.isDisposed();
295: }
296:
297: /* (non-Javadoc)
298: * Method declared on IContributionManager.
299: */
300: public void update(boolean force) {
301:
302: //boolean DEBUG= false;
303:
304: if (isDirty() || force) {
305:
306: if (statusLineExist()) {
307: statusLine.setRedraw(false);
308:
309: // NOTE: the update algorithm is non-incremental.
310: // An incremental algorithm requires that SWT items can be created in the middle of the list
311: // but the ContributionItem.fill(Composite) method used here does not take an index, so this
312: // is not possible.
313:
314: Control ws[] = statusLine.getChildren();
315: for (int i = 0; i < ws.length; i++) {
316: Control w = ws[i];
317: Object data = w.getData();
318: if (data instanceof IContributionItem) {
319: w.dispose();
320: }
321: }
322:
323: int oldChildCount = statusLine.getChildren().length;
324: IContributionItem[] items = getItems();
325: for (int i = 0; i < items.length; ++i) {
326: IContributionItem ci = items[i];
327: if (ci.isVisible()) {
328: ci.fill(statusLine);
329: // associate controls with contribution item
330: Control[] newChildren = statusLine
331: .getChildren();
332: for (int j = oldChildCount; j < newChildren.length; j++) {
333: newChildren[j].setData(ci);
334: }
335: oldChildCount = newChildren.length;
336: }
337: }
338:
339: setDirty(false);
340:
341: statusLine.layout();
342: statusLine.setRedraw(true);
343: }
344: }
345: }
346:
347: }
|