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