1 package org.eclipse.ui.internal.progress; 2 3 13 import java.net.URL ; 14 import com.ibm.icu.text.DateFormat; 15 import java.util.ArrayList ; 16 import java.util.Date ; 17 import java.util.Iterator ; 18 import java.util.List ; 19 20 import org.eclipse.core.runtime.IProgressMonitor; 21 import org.eclipse.core.runtime.IStatus; 22 import org.eclipse.core.runtime.jobs.Job; 23 import org.eclipse.jface.action.IAction; 24 import org.eclipse.jface.dialogs.Dialog; 25 import org.eclipse.jface.dialogs.IDialogConstants; 26 import org.eclipse.jface.resource.ImageDescriptor; 27 import org.eclipse.jface.resource.JFaceResources; 28 import org.eclipse.osgi.util.NLS; 29 import org.eclipse.swt.SWT; 30 import org.eclipse.swt.events.MouseAdapter; 31 import org.eclipse.swt.events.MouseEvent; 32 import org.eclipse.swt.events.SelectionAdapter; 33 import org.eclipse.swt.events.SelectionEvent; 34 import org.eclipse.swt.graphics.Color; 35 import org.eclipse.swt.graphics.Image; 36 import org.eclipse.swt.layout.FormAttachment; 37 import org.eclipse.swt.layout.FormData; 38 import org.eclipse.swt.layout.FormLayout; 39 import org.eclipse.swt.layout.GridData; 40 import org.eclipse.swt.widgets.Composite; 41 import org.eclipse.swt.widgets.Control; 42 import org.eclipse.swt.widgets.Event; 43 import org.eclipse.swt.widgets.Label; 44 import org.eclipse.swt.widgets.Link; 45 import org.eclipse.swt.widgets.Listener; 46 import org.eclipse.swt.widgets.ProgressBar; 47 import org.eclipse.swt.widgets.ToolBar; 48 import org.eclipse.swt.widgets.ToolItem; 49 import org.eclipse.ui.PlatformUI; 50 import org.eclipse.ui.internal.WorkbenchImages; 51 import org.eclipse.ui.progress.IProgressConstants; 52 53 59 class ProgressInfoItem extends Composite { 60 61 static String STOP_IMAGE_KEY = "org.eclipse.ui.internal.progress.PROGRESS_STOP"; 63 static String DISABLED_STOP_IMAGE_KEY = "org.eclipse.ui.internal.progress.DISABLED_PROGRESS_STOP"; 65 static String CLEAR_FINISHED_JOB_KEY = "org.eclipse.ui.internal.progress.CLEAR_FINISHED_JOB"; 67 static String DISABLED_CLEAR_FINISHED_JOB_KEY = "org.eclipse.ui.internal.progress.DISABLED_CLEAR_FINISHED_JOB"; 69 static String DEFAULT_JOB_KEY = "org.eclipse.ui.internal.progress.PROGRESS_DEFAULT"; 71 static String DARK_COLOR_KEY = "org.eclipse.ui.internal.progress.PROGRESS_DARK_COLOR"; 73 JobTreeElement info; 74 75 Label progressLabel; 76 77 ToolBar actionBar; 78 79 ToolItem actionButton; 80 81 List taskEntries = new ArrayList (0); 82 83 private ProgressBar progressBar; 84 85 private Label jobImageLabel; 86 87 static final int MAX_PROGRESS_HEIGHT = 12; 88 89 static final int MIN_ICON_SIZE = 16; 90 91 private static final String TEXT_KEY = "Text"; 93 private static final String ACTION_KEY = "Action"; 95 interface IndexListener { 96 99 public void selectPrevious(); 100 101 104 public void selectNext(); 105 106 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")); 130 JFaceResources 131 .getImageRegistry() 132 .put( 133 DISABLED_STOP_IMAGE_KEY, 134 WorkbenchImages 135 .getWorkbenchImageDescriptor("dlcl16/progress_stop.gif")); 137 JFaceResources 138 .getImageRegistry() 139 .put( 140 DEFAULT_JOB_KEY, 141 WorkbenchImages 142 .getWorkbenchImageDescriptor("progress/progress_task.gif")); 144 JFaceResources 145 .getImageRegistry() 146 .put( 147 CLEAR_FINISHED_JOB_KEY, 148 WorkbenchImages 149 .getWorkbenchImageDescriptor("elcl16/progress_rem.gif")); 151 JFaceResources 152 .getImageRegistry() 153 .put( 154 DISABLED_CLEAR_FINISHED_JOB_KEY, 155 WorkbenchImages 156 .getWorkbenchImageDescriptor("dlcl16/progress_rem.gif")); 158 int shift = "carbon".equals(SWT.getPlatform()) ? -25 : -10; 161 Color lightColor = PlatformUI.getWorkbench().getDisplay() 162 .getSystemColor(SWT.COLOR_LIST_BACKGROUND); 163 164 Color darkColor = new Color(PlatformUI.getWorkbench().getDisplay(), 166 Math.max(0, lightColor.getRed() + shift), Math.max(0, 167 lightColor.getGreen() + shift), Math.max(0, lightColor 168 .getBlue() 169 + shift)); 170 JFaceResources.getColorRegistry().put(DARK_COLOR_KEY, 171 darkColor.getRGB()); 172 } 173 174 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 194 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(IDialogConstants.VERTICAL_SPACING); 206 imageData.left = new FormAttachment( 207 IDialogConstants.HORIZONTAL_SPACING / 2); 208 jobImageLabel.setLayoutData(imageData); 209 210 progressLabel = new Label(this, SWT.NONE); 211 progressLabel.setText(getMainTitle()); 212 213 actionBar = new ToolBar(this, SWT.FLAT); 214 actionBar.setCursor(getDisplay().getSystemCursor(SWT.CURSOR_ARROW)); 221 actionButton = new ToolItem(actionBar, SWT.NONE); 223 actionButton 224 .setToolTipText(ProgressMessages.NewProgressView_CancelJobToolTip); 225 actionButton.addSelectionListener(new SelectionAdapter() { 226 public void widgetSelected(SelectionEvent e) { 227 actionButton.setEnabled(false); 228 cancelOrRemove(); 229 } 230 231 }); 232 actionBar.addListener(SWT.Traverse, new Listener() { 233 238 public void handleEvent(Event event) { 239 if (indexListener == null) { 240 return; 241 } 242 int detail = event.detail; 243 if (detail == SWT.TRAVERSE_ARROW_NEXT) { 244 indexListener.selectNext(); 245 } 246 if (detail == SWT.TRAVERSE_ARROW_PREVIOUS) { 247 indexListener.selectPrevious(); 248 } 249 250 } 251 }); 252 updateToolBarValues(); 253 254 FormData progressData = new FormData(); 255 progressData.top = new FormAttachment(IDialogConstants.VERTICAL_SPACING); 256 progressData.left = new FormAttachment(jobImageLabel, 257 IDialogConstants.HORIZONTAL_SPACING / 2); 258 progressData.right = new FormAttachment(actionBar, 259 IDialogConstants.HORIZONTAL_SPACING); 260 progressLabel.setLayoutData(progressData); 261 262 mouseListener = new MouseAdapter() { 263 268 public void mouseDown(MouseEvent e) { 269 if (indexListener != null) { 270 indexListener.select(); 271 } 272 } 273 }; 274 addMouseListener(mouseListener); 275 jobImageLabel.addMouseListener(mouseListener); 276 progressLabel.addMouseListener(mouseListener); 277 278 setLayoutsForNoProgress(); 279 280 refresh(); 281 } 282 283 287 private void setLayoutsForNoProgress() { 288 289 FormData buttonData = new FormData(); 290 buttonData.top = new FormAttachment(progressLabel, 0, SWT.TOP); 291 buttonData.right = new FormAttachment(100, 292 IDialogConstants.HORIZONTAL_SPACING * -1); 293 294 actionBar.setLayoutData(buttonData); 295 if (taskEntries.size() > 0) { 296 FormData linkData = new FormData(); 297 linkData.top = new FormAttachment(progressLabel, 298 IDialogConstants.VERTICAL_SPACING); 299 linkData.left = new FormAttachment(progressLabel, 0, SWT.LEFT); 300 linkData.right = new FormAttachment(actionBar, 0, SWT.LEFT); 301 ((Link) taskEntries.get(0)).setLayoutData(linkData); 302 303 } 304 } 305 306 310 protected void cancelOrRemove() { 311 312 if (FinishedJobs.getInstance().isFinished(info)) { 313 FinishedJobs.getInstance().remove(info); 314 } else { 315 info.cancel(); 316 } 317 318 } 319 320 325 private Image getInfoImage() { 326 327 if (!info.isJobInfo()) { 328 return JFaceResources.getImage(DEFAULT_JOB_KEY); 329 } 330 331 JobInfo jobInfo = (JobInfo) info; 332 333 ImageDescriptor descriptor = null; 334 Object property = jobInfo.getJob().getProperty( 335 IProgressConstants.ICON_PROPERTY); 336 337 if (property instanceof ImageDescriptor) { 338 descriptor = (ImageDescriptor) property; 339 } else if (property instanceof URL ) { 340 descriptor = ImageDescriptor.createFromURL((URL ) property); 341 } 342 343 Image image = null; 344 if (descriptor == null) { 345 image = ProgressManager.getInstance().getIconFor(jobInfo.getJob()); 346 } else { 347 image = JFaceResources.getResources().createImageWithDefault( 348 descriptor); 349 } 350 351 if (image == null) 352 image = jobInfo.getDisplayImage(); 353 354 return image; 355 } 356 357 362 private String getMainTitle() { 363 if (info.isJobInfo()) { 364 return getJobNameAndStatus(); 365 } 366 if (info.hasChildren()) { 367 return ((GroupInfo) info).getTaskName(); 368 } 369 return info.getDisplayString(); 370 371 } 372 373 378 protected String getJobNameAndStatus() { 379 380 JobInfo jobInfo = (JobInfo) info; 381 Job job = jobInfo.getJob(); 382 383 String name = job.getName(); 384 385 if (job.isSystem()) { 386 name = NLS.bind(ProgressMessages.JobInfo_System, name); 387 } 388 389 if (jobInfo.isCanceled()) { 390 return NLS.bind(ProgressMessages.JobInfo_Cancelled, name); 391 } 392 393 if (jobInfo.isBlocked()) { 394 IStatus blockedStatus = jobInfo.getBlockedStatus(); 395 return NLS.bind(ProgressMessages.JobInfo_Blocked, name, 396 blockedStatus.getMessage()); 397 } 398 399 switch (job.getState()) { 400 case Job.RUNNING: 401 return name; 402 case Job.SLEEPING: { 403 return NLS.bind(ProgressMessages.JobInfo_Sleeping, name); 404 405 } 406 case Job.NONE: return getJobInfoFinishedString(job, true); 408 default: 409 return NLS.bind(ProgressMessages.JobInfo_Waiting, name); 410 } 411 } 412 413 421 String getJobInfoFinishedString(Job job, boolean withTime) { 422 String time = null; 423 if (withTime) { 424 time = getTimeString(); 425 } 426 if (time != null) { 427 return NLS.bind(ProgressMessages.JobInfo_FinishedAt, job.getName(), 428 time); 429 } 430 return NLS.bind(ProgressMessages.JobInfo_Finished, job.getName()); 431 } 432 433 439 private String getTimeString() { 440 Date date = FinishedJobs.getInstance().getFinishDate(info); 441 if (date != null) { 442 return DateFormat.getTimeInstance(DateFormat.SHORT).format(date); 443 } 444 return null; 445 } 446 447 451 void refresh() { 452 453 if (isDisposed() || !isShowing) 455 return; 456 457 progressLabel.setText(getMainTitle()); 458 int percentDone = getPercentDone(); 459 460 JobInfo[] infos = getJobInfos(); 461 if (isRunning()) { 462 if (progressBar == null) { 463 if (percentDone == IProgressMonitor.UNKNOWN) { 464 for (int i = 0; i < infos.length; i++) { 468 if (infos[i].hasTaskInfo() 469 && infos[i].getTaskInfo().totalWork == IProgressMonitor.UNKNOWN) { 470 createProgressBar(SWT.INDETERMINATE); 471 break; 472 } 473 } 474 } else { 475 createProgressBar(SWT.NONE); 476 progressBar.setMinimum(0); 477 progressBar.setMaximum(100); 478 } 479 } 480 481 if (percentDone >= 0 && percentDone <= 100 483 && percentDone != progressBar.getSelection()) { 484 progressBar.setSelection(percentDone); 485 } 486 } 487 488 else if (isCompleted()) { 489 490 if (progressBar != null) { 491 progressBar.dispose(); 492 progressBar = null; 493 } 494 setLayoutsForNoProgress(); 495 496 } 497 498 for (int i = 0; i < infos.length; i++) { 499 JobInfo jobInfo = infos[i]; 500 if (jobInfo.hasTaskInfo()) { 501 502 String taskString = jobInfo.getTaskInfo().getTaskName(); 503 String subTaskString = null; 504 Object [] jobChildren = jobInfo.getChildren(); 505 if (jobChildren.length > 0) { 506 subTaskString = ((JobTreeElement) jobChildren[0]) 507 .getDisplayString(); 508 } 509 510 if (subTaskString != null) { 511 if (taskString == null || taskString.length() == 0) { 512 taskString = subTaskString; 513 } else { 514 taskString = NLS.bind( 515 ProgressMessages.JobInfo_DoneNoProgressMessage, 516 taskString, subTaskString); 517 } 518 } 519 if (taskString != null) { 520 setLinkText(infos[i].getJob(), taskString, i); 521 } 522 } else { Job job = jobInfo.getJob(); 524 IStatus result = job.getResult(); 525 if (result == null) { if (job.getState() == Job.WAITING) 528 setLinkText(job, jobInfo.getDisplayString(), i); 529 } else 530 setLinkText(job, result.getMessage(), i); 531 } 532 setColor(currentIndex); 533 } 534 535 if (infos.length < taskEntries.size()) { 537 for (int i = infos.length; i < taskEntries.size(); i++) { 538 ((Link) taskEntries.get(i)).dispose(); 539 540 } 541 if (infos.length > 1) 542 taskEntries = taskEntries.subList(0, infos.length - 1); 543 else 544 taskEntries.clear(); 545 } 546 547 updateToolBarValues(); 548 } 549 550 555 private boolean isCompleted() { 556 557 JobInfo[] infos = getJobInfos(); 558 for (int i = 0; i < infos.length; i++) { 559 if (infos[i].getJob().getState() != Job.NONE) { 560 return false; 561 } 562 } 563 return infos.length > 0; 565 } 566 567 572 private JobInfo[] getJobInfos() { 573 if (info.isJobInfo()) { 574 return new JobInfo[] { (JobInfo) info }; 575 } 576 Object [] children = info.getChildren(); 577 JobInfo[] infos = new JobInfo[children.length]; 578 System.arraycopy(children, 0, infos, 0, children.length); 579 return infos; 580 } 581 582 587 private boolean isRunning() { 588 589 JobInfo[] infos = getJobInfos(); 590 for (int i = 0; i < infos.length; i++) { 591 int state = infos[i].getJob().getState(); 592 if (state == Job.WAITING || state == Job.RUNNING) 593 return true; 594 } 595 return false; 596 } 597 598 603 private int getPercentDone() { 604 if (info.isJobInfo()) { 605 return ((JobInfo) info).getPercentDone(); 606 } 607 608 if (info.hasChildren()) { 609 Object [] roots = ((GroupInfo) info).getChildren(); 610 if (roots.length == 1 && roots[0] instanceof JobTreeElement) { 611 TaskInfo ti = ((JobInfo) roots[0]).getTaskInfo(); 612 if (ti != null) { 613 return ti.getPercentDone(); 614 } 615 } 616 return ((GroupInfo) info).getPercentDone(); 617 } 618 return 0; 619 } 620 621 626 private void updateToolBarValues() { 627 if (isCompleted()) { 628 actionButton.setImage(JFaceResources 629 .getImage(CLEAR_FINISHED_JOB_KEY)); 630 actionButton.setDisabledImage(JFaceResources 631 .getImage(DISABLED_CLEAR_FINISHED_JOB_KEY)); 632 actionButton 633 .setToolTipText(ProgressMessages.NewProgressView_ClearJobToolTip); 634 } else { 635 actionButton.setImage(JFaceResources.getImage(STOP_IMAGE_KEY)); 636 actionButton.setDisabledImage(JFaceResources 637 .getImage(DISABLED_STOP_IMAGE_KEY)); 638 639 } 640 JobInfo[] infos = getJobInfos(); 641 642 for (int i = 0; i < infos.length; i++) { 643 if (infos[i].isCanceled() && !isCompleted()) { 645 actionButton.setEnabled(false); 646 return; 647 } 648 } 649 actionButton.setEnabled(true); 650 } 651 652 657 void createProgressBar(int style) { 658 659 FormData buttonData = new FormData(); 660 buttonData.top = new FormAttachment(progressLabel, 0); 661 buttonData.right = new FormAttachment(100, 662 IDialogConstants.HORIZONTAL_SPACING * -1); 663 664 actionBar.setLayoutData(buttonData); 665 666 progressBar = new ProgressBar(this, SWT.HORIZONTAL | style); 667 FormData barData = new FormData(); 668 barData.top = new FormAttachment(actionBar, 669 IDialogConstants.VERTICAL_SPACING, SWT.TOP); 670 barData.left = new FormAttachment(progressLabel, 0, SWT.LEFT); 671 barData.right = new FormAttachment(actionBar, 672 IDialogConstants.HORIZONTAL_SPACING * -1); 673 barData.height = MAX_PROGRESS_HEIGHT; 674 barData.width = 0; progressBar.setLayoutData(barData); 676 677 if (taskEntries.size() > 0) { 678 FormData linkData = new FormData(); 680 linkData.top = new FormAttachment(progressBar, 681 IDialogConstants.VERTICAL_SPACING); 682 linkData.left = new FormAttachment( 683 IDialogConstants.HORIZONTAL_SPACING); 684 linkData.right = new FormAttachment(100); 685 686 ((Link) taskEntries.get(0)).setLayoutData(linkData); 687 } 688 } 689 690 695 void setLinkText(Job linkJob, String taskString, int index) { 696 697 Link link; 698 if (index >= taskEntries.size()) { link = new Link(this, SWT.NONE); 700 701 FormData linkData = new FormData(); 702 if (index == 0 || taskEntries.size() == 0) { 703 Control top = progressBar; 704 if (top == null) { 705 top = progressLabel; 706 } 707 linkData.top = new FormAttachment(top, 708 IDialogConstants.VERTICAL_SPACING); 709 linkData.left = new FormAttachment(top, 0, SWT.LEFT); 710 } else { 711 Link previous = (Link) taskEntries.get(index - 1); 712 linkData.top = new FormAttachment(previous, 713 IDialogConstants.VERTICAL_SPACING); 714 linkData.left = new FormAttachment(previous, 0, SWT.LEFT); 715 } 716 717 linkData.right = new FormAttachment(progressBar, 0, SWT.RIGHT); 718 link.setLayoutData(linkData); 719 720 final Link finalLink = link; 721 722 link.addSelectionListener(new SelectionAdapter() { 723 728 public void widgetSelected(SelectionEvent e) { 729 ((IAction) finalLink.getData(ACTION_KEY)).run(); 730 } 731 }); 732 733 link.addListener(SWT.Resize, new Listener() { 734 739 public void handleEvent(Event event) { 740 updateText((String ) finalLink.getData(TEXT_KEY), finalLink); 741 742 } 743 }); 744 taskEntries.add(link); 745 } else { 746 link = (Link) taskEntries.get(index); 747 } 748 749 link.setToolTipText(taskString); 750 link.setData(TEXT_KEY, taskString); 751 752 Object property = linkJob 754 .getProperty(IProgressConstants.ACTION_PROPERTY); 755 if (property instanceof IAction) { 756 link.setData(ACTION_KEY, property); 757 } 758 759 updateText(taskString, link); 760 761 } 762 763 769 private void updateText(String taskString, Link link) { 770 taskString = Dialog.shortenText(taskString, link); 771 772 link.setText(link.getData(ACTION_KEY) == null ? taskString : NLS.bind( 774 "<a>{0}</a>", taskString)); } 776 777 782 public void setColor(int i) { 783 currentIndex = i; 784 785 if (selected) { 786 setAllBackgrounds(getDisplay().getSystemColor( 787 SWT.COLOR_LIST_SELECTION)); 788 setAllForegrounds(getDisplay().getSystemColor( 789 SWT.COLOR_LIST_SELECTION_TEXT)); 790 return; 791 } 792 793 if (i % 2 == 0) { 794 setAllBackgrounds(JFaceResources.getColorRegistry().get( 795 DARK_COLOR_KEY)); 796 } else { 797 setAllBackgrounds(getDisplay().getSystemColor( 798 SWT.COLOR_LIST_BACKGROUND)); 799 } 800 setAllForegrounds(getDisplay() 801 .getSystemColor(SWT.COLOR_LIST_FOREGROUND)); 802 } 803 804 809 private void setAllForegrounds(Color color) { 810 setForeground(color); 811 progressLabel.setForeground(color); 812 813 Iterator taskEntryIterator = taskEntries.iterator(); 814 while (taskEntryIterator.hasNext()) { 815 ((Link) taskEntryIterator.next()).setForeground(color); 816 } 817 818 } 819 820 825 private void setAllBackgrounds(Color color) { 826 setBackground(color); 827 progressLabel.setBackground(color); 828 actionBar.setBackground(color); 829 jobImageLabel.setBackground(color); 830 831 Iterator taskEntryIterator = taskEntries.iterator(); 832 while (taskEntryIterator.hasNext()) { 833 ((Link) taskEntryIterator.next()).setBackground(color); 834 } 835 836 } 837 838 842 void setButtonFocus() { 843 actionBar.setFocus(); 844 } 845 846 852 void selectWidgets(boolean select) { 853 if (select) { 854 setButtonFocus(); 855 } 856 selected = select; 857 setColor(currentIndex); 858 } 859 860 865 void setIndexListener(IndexListener indexListener) { 866 this.indexListener = indexListener; 867 } 868 869 874 boolean isSelected() { 875 return selected; 876 } 877 878 885 void setDisplayed(int top, int bottom) { 886 int itemTop = getLocation().y; 887 int itemBottom = itemTop + getBounds().height; 888 setDisplayed(itemTop <= bottom && itemBottom > top); 889 890 } 891 892 897 private void setDisplayed(boolean displayed) { 898 boolean refresh = !isShowing && displayed; 900 isShowing = displayed; 901 if (refresh) 902 refresh(); 903 } 904 } 905 | Popular Tags |