1 package org.eclipse.ui.internal.progress; 2 3 13 import java.net.URL ; 14 import java.util.ArrayList ; 15 import java.util.Date ; 16 import java.util.Iterator ; 17 import java.util.List ; 18 19 import org.eclipse.core.runtime.IProgressMonitor; 20 import org.eclipse.core.runtime.IStatus; 21 import org.eclipse.core.runtime.jobs.Job; 22 import org.eclipse.jface.action.IAction; 23 import org.eclipse.jface.dialogs.Dialog; 24 import org.eclipse.jface.dialogs.IDialogConstants; 25 import org.eclipse.jface.resource.ImageDescriptor; 26 import org.eclipse.jface.resource.JFaceResources; 27 import org.eclipse.osgi.util.NLS; 28 import org.eclipse.swt.SWT; 29 import org.eclipse.swt.events.MouseAdapter; 30 import org.eclipse.swt.events.MouseEvent; 31 import org.eclipse.swt.events.SelectionAdapter; 32 import org.eclipse.swt.events.SelectionEvent; 33 import org.eclipse.swt.graphics.Color; 34 import org.eclipse.swt.graphics.Image; 35 import org.eclipse.swt.layout.FormAttachment; 36 import org.eclipse.swt.layout.FormData; 37 import org.eclipse.swt.layout.FormLayout; 38 import org.eclipse.swt.layout.GridData; 39 import org.eclipse.swt.widgets.Canvas; 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 import com.ibm.icu.text.DateFormat; 54 55 62 class VirtualInfoItem extends Canvas { 63 64 static String STOP_IMAGE_KEY = "org.eclipse.ui.internal.progress.PROGRESS_STOP"; 66 static String DISABLED_STOP_IMAGE_KEY = "org.eclipse.ui.internal.progress.DISABLED_PROGRESS_STOP"; 68 static String CLEAR_FINISHED_JOB_KEY = "org.eclipse.ui.internal.progress.CLEAR_FINISHED_JOB"; 70 static String DISABLED_CLEAR_FINISHED_JOB_KEY = "org.eclipse.ui.internal.progress.DISABLED_CLEAR_FINISHED_JOB"; 72 static String DEFAULT_JOB_KEY = "org.eclipse.ui.internal.progress.PROGRESS_DEFAULT"; 74 static String DARK_COLOR_KEY = "org.eclipse.ui.internal.progress.PROGRESS_DARK_COLOR"; 76 JobTreeElement info; 77 78 Label progressLabel; 79 80 ToolBar actionBar; 81 82 ToolItem actionButton; 83 84 List taskEntries = new ArrayList (0); 85 86 private ProgressBar progressBar; 87 88 private Label jobImageLabel; 89 90 static final int MAX_PROGRESS_HEIGHT = 12; 91 92 static final int MIN_ICON_SIZE = 16; 93 94 private static final String EMPTY_STRING = ""; 96 private static final String TEXT_KEY = "Text"; 98 private static final String ACTION_KEY = "Action"; 100 interface IndexListener { 101 104 public void selectPrevious(); 105 106 109 public void selectNext(); 110 111 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")); 135 JFaceResources 136 .getImageRegistry() 137 .put( 138 DISABLED_STOP_IMAGE_KEY, 139 WorkbenchImages 140 .getWorkbenchImageDescriptor("dlcl16/progress_stop.gif")); 142 JFaceResources 143 .getImageRegistry() 144 .put( 145 DEFAULT_JOB_KEY, 146 WorkbenchImages 147 .getWorkbenchImageDescriptor("progress/progress_task.gif")); 149 JFaceResources 150 .getImageRegistry() 151 .put( 152 CLEAR_FINISHED_JOB_KEY, 153 WorkbenchImages 154 .getWorkbenchImageDescriptor("elcl16/progress_rem.gif")); 156 JFaceResources 157 .getImageRegistry() 158 .put( 159 DISABLED_CLEAR_FINISHED_JOB_KEY, 160 WorkbenchImages 161 .getWorkbenchImageDescriptor("dlcl16/progress_rem.gif")); 163 int shift = "carbon".equals(SWT.getPlatform()) ? -25 : -10; 166 Color lightColor = PlatformUI.getWorkbench().getDisplay() 167 .getSystemColor(SWT.COLOR_LIST_BACKGROUND); 168 169 Color darkColor = new Color(PlatformUI.getWorkbench().getDisplay(), 171 Math.max(0, lightColor.getRed() + shift), Math.max(0, 172 lightColor.getGreen() + shift), Math.max(0, lightColor 173 .getBlue() 174 + shift)); 175 JFaceResources.getColorRegistry().put(DARK_COLOR_KEY, 176 darkColor.getRGB()); 177 } 178 179 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 199 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(IDialogConstants.VERTICAL_SPACING); 211 imageData.left = new FormAttachment( 212 IDialogConstants.HORIZONTAL_SPACING / 2); 213 jobImageLabel.setLayoutData(imageData); 214 215 progressLabel = new Label(this, SWT.NONE); 216 progressLabel.setFont(JFaceResources.getFontRegistry().getBold( 217 JFaceResources.DEFAULT_FONT)); 218 progressLabel.setText(getMainTitle()); 219 220 actionBar = new ToolBar(this, SWT.FLAT); 221 actionBar.setCursor(getDisplay().getSystemCursor(SWT.CURSOR_ARROW)); 228 actionButton = new ToolItem(actionBar, SWT.NONE); 230 actionButton 231 .setToolTipText(ProgressMessages.NewProgressView_CancelJobToolTip); 232 actionButton.addSelectionListener(new SelectionAdapter() { 233 public void widgetSelected(SelectionEvent e) { 234 actionButton.setEnabled(false); 235 cancelOrRemove(); 236 } 237 238 }); 239 actionBar.addListener(SWT.Traverse, new Listener() { 240 245 public void handleEvent(Event event) { 246 if (indexListener == null) { 247 return; 248 } 249 int detail = event.detail; 250 if (detail == SWT.TRAVERSE_ARROW_NEXT) { 251 indexListener.selectNext(); 252 } 253 if (detail == SWT.TRAVERSE_ARROW_PREVIOUS) { 254 indexListener.selectPrevious(); 255 } 256 257 } 258 }); 259 updateToolBarValues(); 260 261 FormData progressData = new FormData(); 262 progressData.top = new FormAttachment(IDialogConstants.VERTICAL_SPACING); 263 progressData.left = new FormAttachment(jobImageLabel, 264 IDialogConstants.HORIZONTAL_SPACING / 2); 265 progressData.right = new FormAttachment(actionBar, 266 IDialogConstants.HORIZONTAL_SPACING); 267 progressLabel.setLayoutData(progressData); 268 269 mouseListener = new MouseAdapter() { 270 275 public void mouseDown(MouseEvent e) { 276 if (indexListener != null) { 277 indexListener.select(); 278 } 279 } 280 }; 281 addMouseListener(mouseListener); 282 jobImageLabel.addMouseListener(mouseListener); 283 progressLabel.addMouseListener(mouseListener); 284 285 setLayoutsForNoProgress(); 286 287 refresh(); 288 } 289 290 294 private void setLayoutsForNoProgress() { 295 296 FormData buttonData = new FormData(); 297 buttonData.top = new FormAttachment(progressLabel, 0, SWT.TOP); 298 buttonData.right = new FormAttachment(100, 299 IDialogConstants.HORIZONTAL_SPACING * -1); 300 301 actionBar.setLayoutData(buttonData); 302 if (taskEntries.size() > 0) { 303 FormData linkData = new FormData(); 304 linkData.top = new FormAttachment(progressLabel, 305 IDialogConstants.VERTICAL_SPACING); 306 linkData.left = new FormAttachment(progressLabel, 0, SWT.LEFT); 307 linkData.right = new FormAttachment(actionBar, 0, SWT.LEFT); 308 ((Link) taskEntries.get(0)).setLayoutData(linkData); 309 310 } 311 } 312 313 317 protected void cancelOrRemove() { 318 319 if (FinishedJobs.getInstance().isFinished(info)) { 320 FinishedJobs.getInstance().remove(info); 321 } else { 322 info.cancel(); 323 } 324 325 } 326 327 332 private Image getInfoImage() { 333 334 if (!info.isJobInfo()) { 335 return JFaceResources.getImage(DEFAULT_JOB_KEY); 336 } 337 338 JobInfo jobInfo = (JobInfo) info; 339 340 ImageDescriptor descriptor = null; 341 Object property = jobInfo.getJob().getProperty( 342 IProgressConstants.ICON_PROPERTY); 343 344 if (property instanceof ImageDescriptor) { 345 descriptor = (ImageDescriptor) property; 346 } else if (property instanceof URL ) { 347 descriptor = ImageDescriptor.createFromURL((URL ) property); 348 } 349 350 Image image = null; 351 if (descriptor == null) { 352 image = ProgressManager.getInstance().getIconFor(jobInfo.getJob()); 353 } else { 354 image = JFaceResources.getResources().createImageWithDefault( 355 descriptor); 356 } 357 358 if (image == null) 359 image = jobInfo.getDisplayImage(); 360 361 return image; 362 } 363 364 369 private String getMainTitle() { 370 if (info.isJobInfo()) { 371 return getJobNameAndStatus(); 372 } 373 if (info.hasChildren()) { 374 return ((GroupInfo) info).getTaskName(); 375 } 376 return info.getDisplayString(); 377 378 } 379 380 385 protected String getJobNameAndStatus() { 386 387 JobInfo jobInfo = (JobInfo) info; 388 Job job = jobInfo.getJob(); 389 390 String name = job.getName(); 391 392 if (job.isSystem()) { 393 name = NLS.bind(ProgressMessages.JobInfo_System, name); 394 } 395 396 if (jobInfo.isCanceled()) { 397 return NLS.bind(ProgressMessages.JobInfo_Cancelled, name); 398 } 399 400 if (jobInfo.isBlocked()) { 401 IStatus blockedStatus = jobInfo.getBlockedStatus(); 402 return NLS.bind(ProgressMessages.JobInfo_Blocked, name, 403 blockedStatus.getMessage()); 404 } 405 406 switch (job.getState()) { 407 case Job.RUNNING: 408 return name; 409 case Job.SLEEPING: { 410 return NLS.bind(ProgressMessages.JobInfo_Sleeping, name); 411 412 } 413 case Job.NONE: return getJobInfoFinishedString(job, true); 415 default: 416 return NLS.bind(ProgressMessages.JobInfo_Waiting, name); 417 } 418 } 419 420 428 String getJobInfoFinishedString(Job job, boolean withTime) { 429 String time = null; 430 if (withTime) { 431 time = getTimeString(); 432 } 433 if (time != null) { 434 return NLS.bind(ProgressMessages.JobInfo_FinishedAt, job.getName(), 435 time); 436 } 437 return NLS.bind(ProgressMessages.JobInfo_Finished, job.getName()); 438 } 439 440 446 private String getTimeString() { 447 Date date = FinishedJobs.getInstance().getFinishDate(info); 448 if (date != null) { 449 return DateFormat.getTimeInstance(DateFormat.SHORT).format(date); 450 } 451 return null; 452 } 453 454 458 void refresh() { 459 460 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 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 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) { 519 taskString = subTaskString; 520 } else { 521 taskString = NLS.bind( 522 ProgressMessages.JobInfo_DoneNoProgressMessage, 523 taskString, subTaskString); 524 } 525 } 526 if (taskString != null) { 527 setLinkText(infos[i].getJob(), taskString, i); 528 } 529 } else { Job job = jobInfo.getJob(); 531 if (job.getResult() != null) { 532 IStatus result = job.getResult(); 533 String message = EMPTY_STRING; 534 if (result != null) { 535 message = result.getMessage(); 536 } 537 setLinkText(job, message, i); 538 } 539 } 540 setColor(currentIndex); 541 } 542 543 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 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 return infos.length > 0; 573 } 574 575 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 595 private boolean isRunning() { 596 JobInfo[] infos = getJobInfos(); 597 for (int i = 0; i < infos.length; i++) { 598 int state = infos[i].getJob().getState(); 599 if (state == Job.RUNNING) { 600 continue; 601 } 602 return false; 603 } 604 return infos.length > 0; 606 } 607 608 613 private int getPercentDone() { 614 if (info.isJobInfo()) { 615 return ((JobInfo) info).getPercentDone(); 616 } 617 618 if (info.hasChildren()) { 619 Object [] roots = ((GroupInfo) info).getChildren(); 620 if (roots.length == 1 && roots[0] instanceof JobTreeElement) { 621 TaskInfo ti = ((JobInfo) roots[0]).getTaskInfo(); 622 if (ti != null) { 623 return ti.getPercentDone(); 624 } 625 } 626 return ((GroupInfo) info).getPercentDone(); 627 } 628 return 0; 629 } 630 631 636 private void updateToolBarValues() { 637 if (isCompleted()) { 638 actionButton.setImage(JFaceResources 639 .getImage(CLEAR_FINISHED_JOB_KEY)); 640 actionButton.setDisabledImage(JFaceResources 641 .getImage(DISABLED_CLEAR_FINISHED_JOB_KEY)); 642 actionButton 643 .setToolTipText(ProgressMessages.NewProgressView_ClearJobToolTip); 644 } else { 645 actionButton.setImage(JFaceResources.getImage(STOP_IMAGE_KEY)); 646 actionButton.setDisabledImage(JFaceResources 647 .getImage(DISABLED_STOP_IMAGE_KEY)); 648 649 } 650 JobInfo[] infos = getJobInfos(); 651 652 for (int i = 0; i < infos.length; i++) { 653 if (infos[i].isCanceled() && !isCompleted()) { 655 actionButton.setEnabled(false); 656 return; 657 } 658 } 659 actionButton.setEnabled(true); 660 } 661 662 667 void createProgressBar(int style) { 668 669 FormData buttonData = new FormData(); 670 buttonData.top = new FormAttachment(progressLabel, 0); 671 buttonData.right = new FormAttachment(100, 672 IDialogConstants.HORIZONTAL_SPACING * -1); 673 674 actionBar.setLayoutData(buttonData); 675 676 progressBar = new ProgressBar(this, SWT.HORIZONTAL | style); 677 FormData barData = new FormData(); 678 barData.top = new FormAttachment(actionBar, 679 IDialogConstants.VERTICAL_SPACING, SWT.TOP); 680 barData.left = new FormAttachment(progressLabel, 0, SWT.LEFT); 681 barData.right = new FormAttachment(actionBar, 682 IDialogConstants.HORIZONTAL_SPACING * -1); 683 barData.height = MAX_PROGRESS_HEIGHT; 684 barData.width = 0; progressBar.setLayoutData(barData); 686 687 if (taskEntries.size() > 0) { 688 FormData linkData = new FormData(); 690 linkData.top = new FormAttachment(progressBar, 691 IDialogConstants.VERTICAL_SPACING); 692 linkData.left = new FormAttachment( 693 IDialogConstants.HORIZONTAL_SPACING); 694 linkData.right = new FormAttachment(100); 695 696 ((Link) taskEntries.get(0)).setLayoutData(linkData); 697 } 698 } 699 700 705 void setLinkText(Job linkJob, String taskString, int index) { 706 707 Link link; 708 if (index >= taskEntries.size()) { link = new Link(this, SWT.NONE); 710 711 FormData linkData = new FormData(); 712 if (index == 0 || taskEntries.size() == 0) { 713 Control top = progressBar; 714 if (top == null) { 715 top = progressLabel; 716 } 717 linkData.top = new FormAttachment(top, 718 IDialogConstants.VERTICAL_SPACING); 719 linkData.left = new FormAttachment(top, 0, SWT.LEFT); 720 } else { 721 Link previous = (Link) taskEntries.get(index - 1); 722 linkData.top = new FormAttachment(previous, 723 IDialogConstants.VERTICAL_SPACING); 724 linkData.left = new FormAttachment(previous, 0, SWT.LEFT); 725 } 726 727 linkData.right = new FormAttachment(progressBar, 0, SWT.RIGHT); 728 link.setLayoutData(linkData); 729 730 final Link finalLink = link; 731 732 link.addSelectionListener(new SelectionAdapter() { 733 738 public void widgetSelected(SelectionEvent e) { 739 ((IAction) finalLink.getData(ACTION_KEY)).run(); 740 } 741 }); 742 743 link.addListener(SWT.Resize, new Listener() { 744 749 public void handleEvent(Event event) { 750 updateText((String ) finalLink.getData(TEXT_KEY), finalLink); 751 752 } 753 }); 754 taskEntries.add(link); 755 } else { 756 link = (Link) taskEntries.get(index); 757 } 758 759 link.setToolTipText(taskString); 760 link.setData(TEXT_KEY, taskString); 761 762 Object property = linkJob 764 .getProperty(IProgressConstants.ACTION_PROPERTY); 765 if (property instanceof IAction) { 766 link.setData(ACTION_KEY, property); 767 } 768 769 updateText(taskString, link); 770 771 } 772 773 779 private void updateText(String taskString, Link link) { 780 taskString = Dialog.shortenText(taskString, link); 781 782 link.setText(link.getData(ACTION_KEY) == null ? taskString : NLS.bind( 784 "<a>{0}</a>", taskString)); } 786 787 792 public void setColor(int i) { 793 currentIndex = i; 794 795 if (selected) { 796 setAllBackgrounds(getDisplay().getSystemColor( 797 SWT.COLOR_LIST_SELECTION)); 798 setAllForegrounds(getDisplay().getSystemColor( 799 SWT.COLOR_LIST_SELECTION_TEXT)); 800 return; 801 } 802 803 if (i % 2 == 0) { 804 setAllBackgrounds(JFaceResources.getColorRegistry().get( 805 DARK_COLOR_KEY)); 806 } else { 807 setAllBackgrounds(getDisplay().getSystemColor( 808 SWT.COLOR_LIST_BACKGROUND)); 809 } 810 setAllForegrounds(getDisplay() 811 .getSystemColor(SWT.COLOR_LIST_FOREGROUND)); 812 } 813 814 819 private void setAllForegrounds(Color color) { 820 setForeground(color); 821 progressLabel.setForeground(color); 822 823 Iterator taskEntryIterator = taskEntries.iterator(); 824 while (taskEntryIterator.hasNext()) { 825 ((Link) taskEntryIterator.next()).setForeground(color); 826 } 827 828 } 829 830 835 private void setAllBackgrounds(Color color) { 836 setBackground(color); 837 progressLabel.setBackground(color); 838 actionBar.setBackground(color); 839 jobImageLabel.setBackground(color); 840 841 Iterator taskEntryIterator = taskEntries.iterator(); 842 while (taskEntryIterator.hasNext()) { 843 ((Link) taskEntryIterator.next()).setBackground(color); 844 } 845 846 } 847 848 852 void setButtonFocus() { 853 actionBar.setFocus(); 854 } 855 856 862 void selectWidgets(boolean select) { 863 if (select) { 864 setButtonFocus(); 865 } 866 selected = select; 867 setColor(currentIndex); 868 } 869 870 875 void setIndexListener(IndexListener indexListener) { 876 this.indexListener = indexListener; 877 } 878 879 884 boolean isSelected() { 885 return selected; 886 } 887 888 895 void setDisplayed(int top, int bottom) { 896 int itemTop = getLocation().y; 897 int itemBottom = itemTop + getBounds().height; 898 setDisplayed(itemTop <= bottom && itemBottom > top); 899 900 } 901 902 907 private void setDisplayed(boolean displayed) { 908 boolean refresh = !isShowing && displayed; 910 isShowing = displayed; 911 if (refresh) 912 refresh(); 913 } 914 } 915 | Popular Tags |