001: package org.eclipse.ui.internal.progress;
002:
003: /*******************************************************************************
004: * Copyright (c) 2005, 2006 IBM Corporation and others.
005: * All rights reserved. This program and the accompanying materials
006: * are made available under the terms of the Eclipse Public License v1.0
007: * which accompanies this distribution, and is available at
008: * http://www.eclipse.org/legal/epl-v10.html
009: *
010: * Contributors:
011: * IBM Corporation - initial API and implementation
012: *******************************************************************************/
013: import java.net.URL;
014: import java.util.ArrayList;
015: import java.util.Date;
016: import java.util.Iterator;
017: import java.util.List;
018:
019: import org.eclipse.core.runtime.IProgressMonitor;
020: import org.eclipse.core.runtime.IStatus;
021: import org.eclipse.core.runtime.jobs.Job;
022: import org.eclipse.jface.action.IAction;
023: import org.eclipse.jface.dialogs.Dialog;
024: import org.eclipse.jface.dialogs.IDialogConstants;
025: import org.eclipse.jface.resource.ImageDescriptor;
026: import org.eclipse.jface.resource.JFaceResources;
027: import org.eclipse.osgi.util.NLS;
028: import org.eclipse.swt.SWT;
029: import org.eclipse.swt.events.MouseAdapter;
030: import org.eclipse.swt.events.MouseEvent;
031: import org.eclipse.swt.events.SelectionAdapter;
032: import org.eclipse.swt.events.SelectionEvent;
033: import org.eclipse.swt.graphics.Color;
034: import org.eclipse.swt.graphics.Image;
035: import org.eclipse.swt.layout.FormAttachment;
036: import org.eclipse.swt.layout.FormData;
037: import org.eclipse.swt.layout.FormLayout;
038: import org.eclipse.swt.layout.GridData;
039: import org.eclipse.swt.widgets.Canvas;
040: import org.eclipse.swt.widgets.Composite;
041: import org.eclipse.swt.widgets.Control;
042: import org.eclipse.swt.widgets.Event;
043: import org.eclipse.swt.widgets.Label;
044: import org.eclipse.swt.widgets.Link;
045: import org.eclipse.swt.widgets.Listener;
046: import org.eclipse.swt.widgets.ProgressBar;
047: import org.eclipse.swt.widgets.ToolBar;
048: import org.eclipse.swt.widgets.ToolItem;
049: import org.eclipse.ui.PlatformUI;
050: import org.eclipse.ui.internal.WorkbenchImages;
051: import org.eclipse.ui.progress.IProgressConstants;
052:
053: import com.ibm.icu.text.DateFormat;
054:
055: /**
056: * VirtualInfoItem is the item used to show jobs which only displays when it is
057: * visible.
058: *
059: * @since 3.1
060: *
061: */
062: class VirtualInfoItem extends Canvas {
063:
064: static String STOP_IMAGE_KEY = "org.eclipse.ui.internal.progress.PROGRESS_STOP"; //$NON-NLS-1$
065:
066: static String DISABLED_STOP_IMAGE_KEY = "org.eclipse.ui.internal.progress.DISABLED_PROGRESS_STOP"; //$NON-NLS-1$
067:
068: static String CLEAR_FINISHED_JOB_KEY = "org.eclipse.ui.internal.progress.CLEAR_FINISHED_JOB"; //$NON-NLS-1$
069:
070: static String DISABLED_CLEAR_FINISHED_JOB_KEY = "org.eclipse.ui.internal.progress.DISABLED_CLEAR_FINISHED_JOB"; //$NON-NLS-1$
071:
072: static String DEFAULT_JOB_KEY = "org.eclipse.ui.internal.progress.PROGRESS_DEFAULT"; //$NON-NLS-1$
073:
074: static String DARK_COLOR_KEY = "org.eclipse.ui.internal.progress.PROGRESS_DARK_COLOR"; //$NON-NLS-1$
075:
076: JobTreeElement info;
077:
078: Label progressLabel;
079:
080: ToolBar actionBar;
081:
082: ToolItem actionButton;
083:
084: List taskEntries = new ArrayList(0);
085:
086: private ProgressBar progressBar;
087:
088: private Label jobImageLabel;
089:
090: static final int MAX_PROGRESS_HEIGHT = 12;
091:
092: static final int MIN_ICON_SIZE = 16;
093:
094: private static final String EMPTY_STRING = "";//$NON-NLS-1$
095:
096: private static final String TEXT_KEY = "Text"; //$NON-NLS-1$
097:
098: private static final String ACTION_KEY = "Action";//$NON-NLS-1$
099:
100: interface IndexListener {
101: /**
102: * Select the item previous to the receiver.
103: */
104: public void selectPrevious();
105:
106: /**
107: * Select the next previous to the receiver.
108: */
109: public void selectNext();
110:
111: /**
112: * Select the receiver.
113: */
114: public void select();
115: }
116:
117: IndexListener indexListener;
118:
119: private int currentIndex;
120:
121: private boolean selected;
122:
123: private MouseAdapter mouseListener;
124:
125: private boolean isShowing = true;
126:
127: static {
128: JFaceResources
129: .getImageRegistry()
130: .put(
131: STOP_IMAGE_KEY,
132: WorkbenchImages
133: .getWorkbenchImageDescriptor("elcl16/progress_stop.gif"));//$NON-NLS-1$
134:
135: JFaceResources
136: .getImageRegistry()
137: .put(
138: DISABLED_STOP_IMAGE_KEY,
139: WorkbenchImages
140: .getWorkbenchImageDescriptor("dlcl16/progress_stop.gif"));//$NON-NLS-1$
141:
142: JFaceResources
143: .getImageRegistry()
144: .put(
145: DEFAULT_JOB_KEY,
146: WorkbenchImages
147: .getWorkbenchImageDescriptor("progress/progress_task.gif")); //$NON-NLS-1$
148:
149: JFaceResources
150: .getImageRegistry()
151: .put(
152: CLEAR_FINISHED_JOB_KEY,
153: WorkbenchImages
154: .getWorkbenchImageDescriptor("elcl16/progress_rem.gif")); //$NON-NLS-1$
155:
156: JFaceResources
157: .getImageRegistry()
158: .put(
159: DISABLED_CLEAR_FINISHED_JOB_KEY,
160: WorkbenchImages
161: .getWorkbenchImageDescriptor("dlcl16/progress_rem.gif")); //$NON-NLS-1$
162:
163: // Mac has different Gamma value
164: int shift = "carbon".equals(SWT.getPlatform()) ? -25 : -10;//$NON-NLS-1$
165:
166: Color lightColor = PlatformUI.getWorkbench().getDisplay()
167: .getSystemColor(SWT.COLOR_LIST_BACKGROUND);
168:
169: // Determine a dark color by shifting the list color
170: Color darkColor = new Color(PlatformUI.getWorkbench()
171: .getDisplay(),
172: Math.max(0, lightColor.getRed() + shift), Math.max(0,
173: lightColor.getGreen() + shift), Math.max(0,
174: lightColor.getBlue() + shift));
175: JFaceResources.getColorRegistry().put(DARK_COLOR_KEY,
176: darkColor.getRGB());
177: }
178:
179: /**
180: * Create a new instance of the receiver with the specified parent, style
181: * and info object/
182: *
183: * @param parent
184: * @param style
185: * @param progressInfo
186: */
187: public VirtualInfoItem(Composite parent, int style,
188: JobTreeElement progressInfo) {
189: super (parent, style);
190: info = progressInfo;
191: createChildren();
192: setData(info);
193: setLayoutData(new GridData(SWT.FILL, SWT.NONE, true, false));
194: }
195:
196: /**
197: * Create the child widgets of the receiver.
198: */
199: /**
200: *
201: */
202: protected void createChildren() {
203:
204: FormLayout layout = new FormLayout();
205: setLayout(layout);
206:
207: jobImageLabel = new Label(this , SWT.NONE);
208: jobImageLabel.setImage(getInfoImage());
209: FormData imageData = new FormData();
210: imageData.top = new FormAttachment(
211: IDialogConstants.VERTICAL_SPACING);
212: imageData.left = new FormAttachment(
213: IDialogConstants.HORIZONTAL_SPACING / 2);
214: jobImageLabel.setLayoutData(imageData);
215:
216: progressLabel = new Label(this , SWT.NONE);
217: progressLabel.setFont(JFaceResources.getFontRegistry().getBold(
218: JFaceResources.DEFAULT_FONT));
219: progressLabel.setText(getMainTitle());
220:
221: actionBar = new ToolBar(this , SWT.FLAT);
222: actionBar.setCursor(getDisplay().getSystemCursor(
223: SWT.CURSOR_ARROW)); // set
224: // cursor
225: // to
226: // overwrite
227: // any
228: // busy
229:
230: // cursor we might have
231: actionButton = new ToolItem(actionBar, SWT.NONE);
232: actionButton
233: .setToolTipText(ProgressMessages.NewProgressView_CancelJobToolTip);
234: actionButton.addSelectionListener(new SelectionAdapter() {
235: public void widgetSelected(SelectionEvent e) {
236: actionButton.setEnabled(false);
237: cancelOrRemove();
238: }
239:
240: });
241: actionBar.addListener(SWT.Traverse, new Listener() {
242: /*
243: * (non-Javadoc)
244: *
245: * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
246: */
247: public void handleEvent(Event event) {
248: if (indexListener == null) {
249: return;
250: }
251: int detail = event.detail;
252: if (detail == SWT.TRAVERSE_ARROW_NEXT) {
253: indexListener.selectNext();
254: }
255: if (detail == SWT.TRAVERSE_ARROW_PREVIOUS) {
256: indexListener.selectPrevious();
257: }
258:
259: }
260: });
261: updateToolBarValues();
262:
263: FormData progressData = new FormData();
264: progressData.top = new FormAttachment(
265: IDialogConstants.VERTICAL_SPACING);
266: progressData.left = new FormAttachment(jobImageLabel,
267: IDialogConstants.HORIZONTAL_SPACING / 2);
268: progressData.right = new FormAttachment(actionBar,
269: IDialogConstants.HORIZONTAL_SPACING);
270: progressLabel.setLayoutData(progressData);
271:
272: mouseListener = new MouseAdapter() {
273: /*
274: * (non-Javadoc)
275: *
276: * @see org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent)
277: */
278: public void mouseDown(MouseEvent e) {
279: if (indexListener != null) {
280: indexListener.select();
281: }
282: }
283: };
284: addMouseListener(mouseListener);
285: jobImageLabel.addMouseListener(mouseListener);
286: progressLabel.addMouseListener(mouseListener);
287:
288: setLayoutsForNoProgress();
289:
290: refresh();
291: }
292:
293: /**
294: * Set the layout of the widgets for the no progress case.
295: *
296: */
297: private void setLayoutsForNoProgress() {
298:
299: FormData buttonData = new FormData();
300: buttonData.top = new FormAttachment(progressLabel, 0, SWT.TOP);
301: buttonData.right = new FormAttachment(100,
302: IDialogConstants.HORIZONTAL_SPACING * -1);
303:
304: actionBar.setLayoutData(buttonData);
305: if (taskEntries.size() > 0) {
306: FormData linkData = new FormData();
307: linkData.top = new FormAttachment(progressLabel,
308: IDialogConstants.VERTICAL_SPACING);
309: linkData.left = new FormAttachment(progressLabel, 0,
310: SWT.LEFT);
311: linkData.right = new FormAttachment(actionBar, 0, SWT.LEFT);
312: ((Link) taskEntries.get(0)).setLayoutData(linkData);
313:
314: }
315: }
316:
317: /**
318: * Cancel or remove the reciever.
319: *
320: */
321: protected void cancelOrRemove() {
322:
323: if (FinishedJobs.getInstance().isFinished(info)) {
324: FinishedJobs.getInstance().remove(info);
325: } else {
326: info.cancel();
327: }
328:
329: }
330:
331: /**
332: * Get the image for the info.
333: *
334: * @return Image
335: */
336: private Image getInfoImage() {
337:
338: if (!info.isJobInfo()) {
339: return JFaceResources.getImage(DEFAULT_JOB_KEY);
340: }
341:
342: JobInfo jobInfo = (JobInfo) info;
343:
344: ImageDescriptor descriptor = null;
345: Object property = jobInfo.getJob().getProperty(
346: IProgressConstants.ICON_PROPERTY);
347:
348: if (property instanceof ImageDescriptor) {
349: descriptor = (ImageDescriptor) property;
350: } else if (property instanceof URL) {
351: descriptor = ImageDescriptor.createFromURL((URL) property);
352: }
353:
354: Image image = null;
355: if (descriptor == null) {
356: image = ProgressManager.getInstance().getIconFor(
357: jobInfo.getJob());
358: } else {
359: image = JFaceResources.getResources()
360: .createImageWithDefault(descriptor);
361: }
362:
363: if (image == null)
364: image = jobInfo.getDisplayImage();
365:
366: return image;
367: }
368:
369: /**
370: * Get the main title for the receiver.
371: *
372: * @return String
373: */
374: private String getMainTitle() {
375: if (info.isJobInfo()) {
376: return getJobNameAndStatus();
377: }
378: if (info.hasChildren()) {
379: return ((GroupInfo) info).getTaskName();
380: }
381: return info.getDisplayString();
382:
383: }
384:
385: /**
386: * Get the name and status for the main label.
387: *
388: * @return String
389: */
390: protected String getJobNameAndStatus() {
391:
392: JobInfo jobInfo = (JobInfo) info;
393: Job job = jobInfo.getJob();
394:
395: String name = job.getName();
396:
397: if (job.isSystem()) {
398: name = NLS.bind(ProgressMessages.JobInfo_System, name);
399: }
400:
401: if (jobInfo.isCanceled()) {
402: return NLS.bind(ProgressMessages.JobInfo_Cancelled, name);
403: }
404:
405: if (jobInfo.isBlocked()) {
406: IStatus blockedStatus = jobInfo.getBlockedStatus();
407: return NLS.bind(ProgressMessages.JobInfo_Blocked, name,
408: blockedStatus.getMessage());
409: }
410:
411: switch (job.getState()) {
412: case Job.RUNNING:
413: return name;
414: case Job.SLEEPING: {
415: return NLS.bind(ProgressMessages.JobInfo_Sleeping, name);
416:
417: }
418: case Job.NONE: // Only happens for kept jobs
419: return getJobInfoFinishedString(job, true);
420: default:
421: return NLS.bind(ProgressMessages.JobInfo_Waiting, name);
422: }
423: }
424:
425: /**
426: * Return the finished String for a job.
427: *
428: * @param job
429: * the completed Job
430: * @param withTime
431: * @return String
432: */
433: String getJobInfoFinishedString(Job job, boolean withTime) {
434: String time = null;
435: if (withTime) {
436: time = getTimeString();
437: }
438: if (time != null) {
439: return NLS.bind(ProgressMessages.JobInfo_FinishedAt, job
440: .getName(), time);
441: }
442: return NLS.bind(ProgressMessages.JobInfo_Finished, job
443: .getName());
444: }
445:
446: /**
447: * Get the time string the finished job
448: *
449: * @return String or <code>null</code> if this is not one of the finished
450: * jobs.
451: */
452: private String getTimeString() {
453: Date date = FinishedJobs.getInstance().getFinishDate(info);
454: if (date != null) {
455: return DateFormat.getTimeInstance(DateFormat.SHORT).format(
456: date);
457: }
458: return null;
459: }
460:
461: /**
462: * Refresh the contents of the receiver.
463: *
464: */
465: void refresh() {
466:
467: // Don't refresh if not visible
468: if (isDisposed() || !isShowing)
469: return;
470:
471: progressLabel.setText(getMainTitle());
472: int percentDone = getPercentDone();
473:
474: JobInfo[] infos = getJobInfos();
475: if (isRunning()) {
476: if (progressBar == null) {
477: if (percentDone == IProgressMonitor.UNKNOWN) {
478: // Only do it if there is an indeterminate task
479: // There may be no task so we don't want to create it
480: // until we know for sure
481: for (int i = 0; i < infos.length; i++) {
482: if (infos[i].hasTaskInfo()
483: && infos[i].getTaskInfo().totalWork == IProgressMonitor.UNKNOWN) {
484: createProgressBar(SWT.INDETERMINATE);
485: break;
486: }
487: }
488: } else {
489: createProgressBar(SWT.NONE);
490: progressBar.setMinimum(0);
491: progressBar.setMaximum(100);
492: }
493: }
494:
495: // Protect against bad counters
496: if (percentDone >= 0 && percentDone <= 100
497: && percentDone != progressBar.getSelection()) {
498: progressBar.setSelection(percentDone);
499: }
500: }
501:
502: else if (isCompleted()) {
503:
504: if (progressBar != null) {
505: progressBar.dispose();
506: progressBar = null;
507: }
508: setLayoutsForNoProgress();
509:
510: }
511:
512: for (int i = 0; i < infos.length; i++) {
513: JobInfo jobInfo = infos[i];
514: if (jobInfo.hasTaskInfo()) {
515:
516: String taskString = jobInfo.getTaskInfo().getTaskName();
517: String subTaskString = null;
518: Object[] jobChildren = jobInfo.getChildren();
519: if (jobChildren.length > 0) {
520: subTaskString = ((JobTreeElement) jobChildren[0])
521: .getDisplayString();
522: }
523:
524: if (subTaskString != null) {
525: if (taskString == null) {
526: taskString = subTaskString;
527: } else {
528: taskString = NLS
529: .bind(
530: ProgressMessages.JobInfo_DoneNoProgressMessage,
531: taskString, subTaskString);
532: }
533: }
534: if (taskString != null) {
535: setLinkText(infos[i].getJob(), taskString, i);
536: }
537: } else {// Check for the finished job state
538: Job job = jobInfo.getJob();
539: if (job.getResult() != null) {
540: IStatus result = job.getResult();
541: String message = EMPTY_STRING;
542: if (result != null) {
543: message = result.getMessage();
544: }
545: setLinkText(job, message, i);
546: }
547: }
548: setColor(currentIndex);
549: }
550:
551: // Remove completed tasks
552: if (infos.length < taskEntries.size()) {
553: for (int i = infos.length; i < taskEntries.size(); i++) {
554: ((Link) taskEntries.get(i)).dispose();
555:
556: }
557: if (infos.length > 1)
558: taskEntries = taskEntries.subList(0, infos.length - 1);
559: else
560: taskEntries.clear();
561: }
562:
563: updateToolBarValues();
564: }
565:
566: /**
567: * Return whether or not the receiver is a completed job.
568: *
569: * @return boolean <code>true</code> if the state is Job#NONE.
570: */
571: private boolean isCompleted() {
572:
573: JobInfo[] infos = getJobInfos();
574: for (int i = 0; i < infos.length; i++) {
575: if (infos[i].getJob().getState() != Job.NONE) {
576: return false;
577: }
578: }
579: // Only completed if there are any jobs
580: return infos.length > 0;
581: }
582:
583: /**
584: * Return the job infos in the receiver.
585: *
586: * @return JobInfo[]
587: */
588: private JobInfo[] getJobInfos() {
589: if (info.isJobInfo()) {
590: return new JobInfo[] { (JobInfo) info };
591: }
592: Object[] children = info.getChildren();
593: JobInfo[] infos = new JobInfo[children.length];
594: System.arraycopy(children, 0, infos, 0, children.length);
595: return infos;
596: }
597:
598: /**
599: * Return whether or not the receiver is being displayed as running.
600: *
601: * @return boolean
602: */
603: private boolean isRunning() {
604: JobInfo[] infos = getJobInfos();
605: for (int i = 0; i < infos.length; i++) {
606: int state = infos[i].getJob().getState();
607: if (state == Job.RUNNING) {
608: continue;
609: }
610: return false;
611: }
612: // Only completed if there are any jobs
613: return infos.length > 0;
614: }
615:
616: /**
617: * Get the current percent done.
618: *
619: * @return int
620: */
621: private int getPercentDone() {
622: if (info.isJobInfo()) {
623: return ((JobInfo) info).getPercentDone();
624: }
625:
626: if (info.hasChildren()) {
627: Object[] roots = ((GroupInfo) info).getChildren();
628: if (roots.length == 1 && roots[0] instanceof JobTreeElement) {
629: TaskInfo ti = ((JobInfo) roots[0]).getTaskInfo();
630: if (ti != null) {
631: return ti.getPercentDone();
632: }
633: }
634: return ((GroupInfo) info).getPercentDone();
635: }
636: return 0;
637: }
638:
639: /**
640: * Set the images in the toolbar based on whether the receiver is finished
641: * or not. Also update tooltips if required.
642: *
643: */
644: private void updateToolBarValues() {
645: if (isCompleted()) {
646: actionButton.setImage(JFaceResources
647: .getImage(CLEAR_FINISHED_JOB_KEY));
648: actionButton.setDisabledImage(JFaceResources
649: .getImage(DISABLED_CLEAR_FINISHED_JOB_KEY));
650: actionButton
651: .setToolTipText(ProgressMessages.NewProgressView_ClearJobToolTip);
652: } else {
653: actionButton.setImage(JFaceResources
654: .getImage(STOP_IMAGE_KEY));
655: actionButton.setDisabledImage(JFaceResources
656: .getImage(DISABLED_STOP_IMAGE_KEY));
657:
658: }
659: JobInfo[] infos = getJobInfos();
660:
661: for (int i = 0; i < infos.length; i++) {
662: // Only disable if there is an unresponsive operation
663: if (infos[i].isCanceled() && !isCompleted()) {
664: actionButton.setEnabled(false);
665: return;
666: }
667: }
668: actionButton.setEnabled(true);
669: }
670:
671: /**
672: * Create the progress bar and apply any style bits from style.
673: *
674: * @param style
675: */
676: void createProgressBar(int style) {
677:
678: FormData buttonData = new FormData();
679: buttonData.top = new FormAttachment(progressLabel, 0);
680: buttonData.right = new FormAttachment(100,
681: IDialogConstants.HORIZONTAL_SPACING * -1);
682:
683: actionBar.setLayoutData(buttonData);
684:
685: progressBar = new ProgressBar(this , SWT.HORIZONTAL | style);
686: FormData barData = new FormData();
687: barData.top = new FormAttachment(actionBar,
688: IDialogConstants.VERTICAL_SPACING, SWT.TOP);
689: barData.left = new FormAttachment(progressLabel, 0, SWT.LEFT);
690: barData.right = new FormAttachment(actionBar,
691: IDialogConstants.HORIZONTAL_SPACING * -1);
692: barData.height = MAX_PROGRESS_HEIGHT;
693: barData.width = 0;// default is too large
694: progressBar.setLayoutData(barData);
695:
696: if (taskEntries.size() > 0) {
697: // Reattach the link label if there is one
698: FormData linkData = new FormData();
699: linkData.top = new FormAttachment(progressBar,
700: IDialogConstants.VERTICAL_SPACING);
701: linkData.left = new FormAttachment(
702: IDialogConstants.HORIZONTAL_SPACING);
703: linkData.right = new FormAttachment(100);
704:
705: ((Link) taskEntries.get(0)).setLayoutData(linkData);
706: }
707: }
708:
709: /**
710: * Set the text of the link to the taskString.
711: *
712: * @param taskString
713: */
714: void setLinkText(Job linkJob, String taskString, int index) {
715:
716: Link link;
717: if (index >= taskEntries.size()) {// Is it new?
718: link = new Link(this , SWT.NONE);
719:
720: FormData linkData = new FormData();
721: if (index == 0 || taskEntries.size() == 0) {
722: Control top = progressBar;
723: if (top == null) {
724: top = progressLabel;
725: }
726: linkData.top = new FormAttachment(top,
727: IDialogConstants.VERTICAL_SPACING);
728: linkData.left = new FormAttachment(top, 0, SWT.LEFT);
729: } else {
730: Link previous = (Link) taskEntries.get(index - 1);
731: linkData.top = new FormAttachment(previous,
732: IDialogConstants.VERTICAL_SPACING);
733: linkData.left = new FormAttachment(previous, 0,
734: SWT.LEFT);
735: }
736:
737: linkData.right = new FormAttachment(progressBar, 0,
738: SWT.RIGHT);
739: link.setLayoutData(linkData);
740:
741: final Link finalLink = link;
742:
743: link.addSelectionListener(new SelectionAdapter() {
744: /*
745: * (non-Javadoc)
746: *
747: * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
748: */
749: public void widgetSelected(SelectionEvent e) {
750: ((IAction) finalLink.getData(ACTION_KEY)).run();
751: }
752: });
753:
754: link.addListener(SWT.Resize, new Listener() {
755: /*
756: * (non-Javadoc)
757: *
758: * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
759: */
760: public void handleEvent(Event event) {
761: updateText((String) finalLink.getData(TEXT_KEY),
762: finalLink);
763:
764: }
765: });
766: taskEntries.add(link);
767: } else {
768: link = (Link) taskEntries.get(index);
769: }
770:
771: link.setToolTipText(taskString);
772: link.setData(TEXT_KEY, taskString);
773:
774: // check for action property
775: Object property = linkJob
776: .getProperty(IProgressConstants.ACTION_PROPERTY);
777: if (property instanceof IAction) {
778: link.setData(ACTION_KEY, property);
779: }
780:
781: updateText(taskString, link);
782:
783: }
784:
785: /**
786: * Update the text in the link
787: *
788: * @param taskString
789: * @param link
790: */
791: private void updateText(String taskString, Link link) {
792: taskString = Dialog.shortenText(taskString, link);
793:
794: // Put in a hyperlink if there is an action
795: link.setText(link.getData(ACTION_KEY) == null ? taskString
796: : NLS.bind("<a>{0}</a>", taskString));//$NON-NLS-1$
797: }
798:
799: /**
800: * Set the color base on the index
801: *
802: * @param i
803: */
804: public void setColor(int i) {
805: currentIndex = i;
806:
807: if (selected) {
808: setAllBackgrounds(getDisplay().getSystemColor(
809: SWT.COLOR_LIST_SELECTION));
810: setAllForegrounds(getDisplay().getSystemColor(
811: SWT.COLOR_LIST_SELECTION_TEXT));
812: return;
813: }
814:
815: if (i % 2 == 0) {
816: setAllBackgrounds(JFaceResources.getColorRegistry().get(
817: DARK_COLOR_KEY));
818: } else {
819: setAllBackgrounds(getDisplay().getSystemColor(
820: SWT.COLOR_LIST_BACKGROUND));
821: }
822: setAllForegrounds(getDisplay().getSystemColor(
823: SWT.COLOR_LIST_FOREGROUND));
824: }
825:
826: /**
827: * Set the foreground of all widgets to the supplied color.
828: *
829: * @param color
830: */
831: private void setAllForegrounds(Color color) {
832: setForeground(color);
833: progressLabel.setForeground(color);
834:
835: Iterator taskEntryIterator = taskEntries.iterator();
836: while (taskEntryIterator.hasNext()) {
837: ((Link) taskEntryIterator.next()).setForeground(color);
838: }
839:
840: }
841:
842: /**
843: * Set the background of all widgets to the supplied color.
844: *
845: * @param color
846: */
847: private void setAllBackgrounds(Color color) {
848: setBackground(color);
849: progressLabel.setBackground(color);
850: actionBar.setBackground(color);
851: jobImageLabel.setBackground(color);
852:
853: Iterator taskEntryIterator = taskEntries.iterator();
854: while (taskEntryIterator.hasNext()) {
855: ((Link) taskEntryIterator.next()).setBackground(color);
856: }
857:
858: }
859:
860: /**
861: * Set the focus to the button.
862: *
863: */
864: void setButtonFocus() {
865: actionBar.setFocus();
866: }
867:
868: /**
869: * Set the selection colors.
870: *
871: * @param select
872: * boolean that indicates whether or not to show selection.
873: */
874: void selectWidgets(boolean select) {
875: if (select) {
876: setButtonFocus();
877: }
878: selected = select;
879: setColor(currentIndex);
880: }
881:
882: /**
883: * Set the listener for index changes.
884: *
885: * @param indexListener
886: */
887: void setIndexListener(IndexListener indexListener) {
888: this .indexListener = indexListener;
889: }
890:
891: /**
892: * Return whether or not the receiver is selected.
893: *
894: * @return boolean
895: */
896: boolean isSelected() {
897: return selected;
898: }
899:
900: /**
901: * Set whether or not the receiver is being displayed based on the top and
902: * bottom of the currently visible area.
903: *
904: * @param top
905: * @param bottom
906: */
907: void setDisplayed(int top, int bottom) {
908: int itemTop = getLocation().y;
909: int itemBottom = itemTop + getBounds().height;
910: setDisplayed(itemTop <= bottom && itemBottom > top);
911:
912: }
913:
914: /**
915: * Set whether or not the receiver is being displayed
916: *
917: * @param displayed
918: */
919: private void setDisplayed(boolean displayed) {
920: // See if this element has been turned off
921: boolean refresh = !isShowing && displayed;
922: isShowing = displayed;
923: if (refresh)
924: refresh();
925: }
926: }
|