001: /*******************************************************************************
002: * Copyright (c) 2004, 2007 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.ui.internal.progress;
011:
012: import org.eclipse.core.runtime.IStatus;
013: import org.eclipse.core.runtime.jobs.Job;
014: import org.eclipse.jface.action.IAction;
015: import org.eclipse.osgi.util.NLS;
016: import org.eclipse.swt.SWT;
017: import org.eclipse.swt.events.DisposeEvent;
018: import org.eclipse.swt.events.DisposeListener;
019: import org.eclipse.swt.events.MouseAdapter;
020: import org.eclipse.swt.events.MouseEvent;
021: import org.eclipse.swt.events.MouseListener;
022: import org.eclipse.swt.events.SelectionAdapter;
023: import org.eclipse.swt.events.SelectionEvent;
024: import org.eclipse.swt.graphics.Image;
025: import org.eclipse.swt.layout.GridData;
026: import org.eclipse.swt.layout.GridLayout;
027: import org.eclipse.swt.widgets.Composite;
028: import org.eclipse.swt.widgets.Control;
029: import org.eclipse.swt.widgets.Display;
030: import org.eclipse.swt.widgets.Label;
031: import org.eclipse.swt.widgets.ProgressBar;
032: import org.eclipse.swt.widgets.ToolBar;
033: import org.eclipse.swt.widgets.ToolItem;
034: import org.eclipse.ui.PlatformUI;
035: import org.eclipse.ui.internal.WorkbenchImages;
036: import org.eclipse.ui.progress.IProgressConstants;
037: import org.eclipse.ui.statushandlers.StatusAdapter;
038: import org.eclipse.ui.statushandlers.StatusManager;
039:
040: /**
041: * The ProgressAnimationItem is the animation items that uses
042: * the progress bar.
043: */
044: public class ProgressAnimationItem extends AnimationItem implements
045: FinishedJobs.KeptJobsListener {
046:
047: ProgressBar bar;
048:
049: MouseListener mouseListener;
050:
051: Composite top;
052:
053: ToolBar toolbar;
054:
055: ToolItem toolButton;
056:
057: ProgressRegion progressRegion;
058:
059: Image noneImage, okImage, errorImage;
060:
061: boolean animationRunning;
062:
063: JobInfo lastJobInfo;
064:
065: // ProgressBar flags
066: private int flags;
067:
068: /**
069: * Create an instance of the receiver in the supplied region.
070: *
071: * @param region The ProgressRegion that contains the receiver.
072: * @param flags flags to use for creation of the progress bar
073: */
074: ProgressAnimationItem(ProgressRegion region, int flags) {
075: super (region.workbenchWindow);
076: this .flags = flags;
077: FinishedJobs.getInstance().addListener(this );
078:
079: progressRegion = region;
080: mouseListener = new MouseAdapter() {
081: public void mouseDoubleClick(MouseEvent e) {
082: doAction();
083: }
084: };
085: }
086:
087: void doAction() {
088:
089: JobTreeElement[] jobTreeElements = FinishedJobs.getInstance()
090: .getJobInfos();
091: // search from end (youngest)
092: for (int i = jobTreeElements.length - 1; i >= 0; i--) {
093: if (jobTreeElements[i] instanceof JobInfo) {
094: JobInfo ji = (JobInfo) jobTreeElements[i];
095: Job job = ji.getJob();
096: if (job != null) {
097:
098: IStatus status = job.getResult();
099: if (status != null
100: && status.getSeverity() == IStatus.ERROR) {
101: StatusAdapter statusAdapter = StatusAdapterHelper
102: .getInstance().getStatusAdapter(ji);
103:
104: StatusManager.getManager().handle(
105: statusAdapter, StatusManager.SHOW);
106:
107: JobTreeElement topElement = (JobTreeElement) ji
108: .getParent();
109: if (topElement == null) {
110: topElement = ji;
111: }
112: FinishedJobs.getInstance().remove(topElement);
113: }
114:
115: IAction action = null;
116: Object property = job
117: .getProperty(IProgressConstants.ACTION_PROPERTY);
118: if (property instanceof IAction) {
119: action = (IAction) property;
120: }
121: if (action != null && action.isEnabled()) {
122: action.run();
123: JobTreeElement topElement = (JobTreeElement) ji
124: .getParent();
125: if (topElement == null) {
126: topElement = ji;
127: }
128: FinishedJobs.getInstance().remove(topElement);
129: return;
130: }
131: }
132: }
133: }
134:
135: progressRegion.processDoubleClick();
136: refresh();
137: }
138:
139: private IAction getAction(Job job) {
140: Object property = job
141: .getProperty(IProgressConstants.ACTION_PROPERTY);
142: if (property instanceof IAction) {
143: return (IAction) property;
144: }
145: return null;
146: }
147:
148: private void refresh() {
149:
150: // Abort the refresh if we are in the process of shutting down
151: if (!PlatformUI.isWorkbenchRunning()) {
152: return;
153: }
154:
155: if (toolbar == null || toolbar.isDisposed()) {
156: return;
157: }
158:
159: lastJobInfo = null;
160:
161: JobTreeElement[] jobTreeElements = FinishedJobs.getInstance()
162: .getJobInfos();
163: // search from end (youngest)
164: for (int i = jobTreeElements.length - 1; i >= 0; i--) {
165: if (jobTreeElements[i] instanceof JobInfo) {
166: JobInfo ji = (JobInfo) jobTreeElements[i];
167: lastJobInfo = ji;
168: Job job = ji.getJob();
169: if (job != null) {
170: IStatus status = job.getResult();
171: if (status != null
172: && status.getSeverity() == IStatus.ERROR) {
173: // green arrow with error overlay
174: initButton(
175: errorImage,
176: NLS
177: .bind(
178: ProgressMessages.ProgressAnimationItem_error,
179: job.getName()));
180: return;
181: }
182: IAction action = getAction(job);
183: if (action != null && action.isEnabled()) {
184: // green arrow with exclamation mark
185: String tt = action.getToolTipText();
186: if (tt == null || tt.trim().length() == 0) {
187: tt = NLS
188: .bind(
189: ProgressMessages.ProgressAnimationItem_ok,
190: job.getName());
191: }
192: initButton(okImage, tt);
193: return;
194: }
195: // just the green arrow
196: initButton(
197: noneImage,
198: ProgressMessages.ProgressAnimationItem_tasks);
199: return;
200: }
201: }
202: }
203:
204: if (animationRunning) {
205: initButton(noneImage,
206: ProgressMessages.ProgressAnimationItem_tasks);
207: return;
208: }
209:
210: // if nothing found hide tool item
211: toolbar.setVisible(false);
212: }
213:
214: private void initButton(Image im, String tt) {
215: toolButton.setImage(im);
216: toolButton.setToolTipText(tt);
217: toolbar.setVisible(true);
218: toolbar.getParent().layout(); // must layout
219: }
220:
221: /*
222: * (non-Javadoc)
223: *
224: * @see org.eclipse.ui.internal.progress.AnimationItem#createAnimationItem(org.eclipse.swt.widgets.Composite)
225: */
226: protected Control createAnimationItem(Composite parent) {
227:
228: if (okImage == null) {
229: Display display = parent.getDisplay();
230: noneImage = WorkbenchImages.getWorkbenchImageDescriptor(
231: "progress/progress_none.gif").createImage(display); //$NON-NLS-1$
232: okImage = WorkbenchImages.getWorkbenchImageDescriptor(
233: "progress/progress_ok.gif").createImage(display); //$NON-NLS-1$
234: errorImage = WorkbenchImages.getWorkbenchImageDescriptor(
235: "progress/progress_error.gif").createImage(display); //$NON-NLS-1$
236: }
237:
238: top = new Composite(parent, SWT.NULL);
239: top.addDisposeListener(new DisposeListener() {
240: public void widgetDisposed(DisposeEvent e) {
241: FinishedJobs.getInstance().removeListener(
242: ProgressAnimationItem.this );
243: noneImage.dispose();
244: okImage.dispose();
245: errorImage.dispose();
246: }
247: });
248:
249: boolean isCarbon = "carbon".equals(SWT.getPlatform()); //$NON-NLS-1$
250:
251: GridLayout gl = new GridLayout();
252: if (isHorizontal())
253: gl.numColumns = isCarbon ? 3 : 2;
254: gl.marginHeight = 0;
255: gl.marginWidth = 0;
256: if (isHorizontal()) {
257: gl.horizontalSpacing = 2;
258: } else {
259: gl.verticalSpacing = 2;
260: }
261: top.setLayout(gl);
262:
263: bar = new ProgressBar(top, flags | SWT.INDETERMINATE);
264: bar.setVisible(false);
265: bar.addMouseListener(mouseListener);
266:
267: GridData gd;
268: int hh = 12;
269: if (isHorizontal()) {
270: gd = new GridData(SWT.BEGINNING, SWT.CENTER, true, false);
271: gd.heightHint = hh;
272: } else {
273: gd = new GridData(SWT.CENTER, SWT.BEGINNING, false, true);
274: gd.widthHint = hh;
275: }
276:
277: bar.setLayoutData(gd);
278:
279: toolbar = new ToolBar(top, SWT.FLAT);
280: toolbar.setVisible(false);
281:
282: toolButton = new ToolItem(toolbar, SWT.NONE);
283: toolButton.addSelectionListener(new SelectionAdapter() {
284: public void widgetSelected(SelectionEvent e) {
285: doAction();
286: }
287: });
288:
289: if (isCarbon) {
290: new Label(top, SWT.NONE).setLayoutData(new GridData(4, 4));
291: }
292:
293: refresh();
294:
295: return top;
296: }
297:
298: /**
299: * @return <code>true</code> if the control is horizontally oriented
300: */
301: private boolean isHorizontal() {
302: return (flags & SWT.HORIZONTAL) != 0;
303: }
304:
305: /*
306: * (non-Javadoc)
307: *
308: * @see org.eclipse.ui.internal.progress.AnimationItem#getControl()
309: */
310: public Control getControl() {
311: return top;
312: }
313:
314: /*
315: * (non-Javadoc)
316: *
317: * @see org.eclipse.ui.internal.progress.AnimationItem#animationDone()
318: */
319: void animationDone() {
320: super .animationDone();
321: animationRunning = false;
322: if (bar.isDisposed()) {
323: return;
324: }
325: bar.setVisible(false);
326: refresh();
327: }
328:
329: /**
330: * @return <code>true</code> when the animation is running
331: */
332: public boolean animationRunning() {
333: return animationRunning;
334: }
335:
336: /*
337: * (non-Javadoc)
338: *
339: * @see org.eclipse.ui.internal.progress.AnimationItem#animationStart()
340: */
341: void animationStart() {
342: super .animationStart();
343: animationRunning = true;
344: if (bar.isDisposed()) {
345: return;
346: }
347: bar.setVisible(true);
348: refresh();
349: }
350:
351: public void removed(JobTreeElement info) {
352: final Display display = Display.getDefault();
353: display.asyncExec(new Runnable() {
354: public void run() {
355: refresh();
356: }
357: });
358: }
359:
360: public void finished(final JobTreeElement jte) {
361: final Display display = Display.getDefault();
362: display.asyncExec(new Runnable() {
363: public void run() {
364: refresh();
365: }
366: });
367: }
368:
369: }
|