1 11 12 package org.eclipse.jface.action; 13 14 import org.eclipse.core.runtime.IProgressMonitor; 15 import org.eclipse.jface.dialogs.ProgressIndicator; 16 import org.eclipse.jface.resource.ImageDescriptor; 17 import org.eclipse.jface.resource.JFaceColors; 18 import org.eclipse.jface.resource.JFaceResources; 19 import org.eclipse.swt.SWT; 20 import org.eclipse.swt.custom.CLabel; 21 import org.eclipse.swt.events.DisposeEvent; 22 import org.eclipse.swt.events.DisposeListener; 23 import org.eclipse.swt.events.SelectionAdapter; 24 import org.eclipse.swt.events.SelectionEvent; 25 import org.eclipse.swt.graphics.Cursor; 26 import org.eclipse.swt.graphics.Font; 27 import org.eclipse.swt.graphics.Image; 28 import org.eclipse.swt.graphics.Point; 29 import org.eclipse.swt.graphics.Rectangle; 30 import org.eclipse.swt.layout.GridData; 31 import org.eclipse.swt.layout.GridLayout; 32 import org.eclipse.swt.widgets.Composite; 33 import org.eclipse.swt.widgets.Control; 34 import org.eclipse.swt.widgets.Display; 35 import org.eclipse.swt.widgets.Layout; 36 import org.eclipse.swt.widgets.ToolBar; 37 import org.eclipse.swt.widgets.ToolItem; 38 39 51 class StatusLine extends Composite implements IProgressMonitor { 52 53 54 public static final int GAP = 3; 55 56 57 public static final int DELAY_PROGRESS = 500; 58 59 60 protected boolean fProgressIsVisible = false; 61 62 63 protected boolean fCancelButtonIsVisible = false; 64 65 66 protected boolean fCancelEnabled = false; 67 68 69 protected String fTaskName; 70 71 72 protected boolean fIsCanceled; 73 74 75 protected long fStartTime; 76 77 private Cursor fStopButtonCursor; 78 79 80 protected String fMessageText; 81 82 83 protected Image fMessageImage; 84 85 86 protected String fErrorText; 87 88 89 protected Image fErrorImage; 90 91 92 protected CLabel fMessageLabel; 93 94 95 protected Composite fProgressBarComposite; 96 97 98 protected ProgressIndicator fProgressBar; 99 100 101 protected ToolBar fToolBar; 102 103 104 protected ToolItem fCancelButton; 105 106 107 protected static ImageDescriptor fgStopImage = ImageDescriptor 108 .createFromFile(StatusLine.class, "images/stop.gif"); static { 110 JFaceResources.getImageRegistry().put( 111 "org.eclipse.jface.parts.StatusLine.stopImage", fgStopImage); } 113 114 117 public class StatusLineLayout extends Layout { 118 private final StatusLineLayoutData DEFAULT_DATA = new StatusLineLayoutData(); 119 120 public Point computeSize(Composite composite, int wHint, int hHint, 121 boolean changed) { 122 123 if (wHint != SWT.DEFAULT && hHint != SWT.DEFAULT) { 124 return new Point(wHint, hHint); 125 } 126 127 Control[] children = composite.getChildren(); 128 int totalWidth = 0; 129 int maxHeight = 0; 130 int totalCnt = 0; 131 for (int i = 0; i < children.length; i++) { 132 boolean useWidth = true; 133 Control w = children[i]; 134 if (w == fProgressBarComposite && !fProgressIsVisible) { 135 useWidth = false; 136 } else if (w == fToolBar && !fCancelButtonIsVisible) { 137 useWidth = false; 138 } 139 StatusLineLayoutData data = (StatusLineLayoutData) w 140 .getLayoutData(); 141 if (data == null) { 142 data = DEFAULT_DATA; 143 } 144 Point e = w.computeSize(data.widthHint, data.heightHint, 145 changed); 146 if (useWidth) { 147 totalWidth += e.x; 148 totalCnt++; 149 } 150 maxHeight = Math.max(maxHeight, e.y); 151 } 152 if (totalCnt > 0) { 153 totalWidth += (totalCnt - 1) * GAP; 154 } 155 if (totalWidth <= 0) { 156 totalWidth = maxHeight * 4; 157 } 158 return new Point(totalWidth, maxHeight); 159 } 160 161 public void layout(Composite composite, boolean flushCache) { 162 163 if (composite == null) { 164 return; 165 } 166 167 171 fMessageLabel.moveAbove(null); 173 fToolBar.moveBelow(fMessageLabel); 174 fProgressBarComposite.moveBelow(fToolBar); 175 176 Rectangle rect = composite.getClientArea(); 177 Control[] children = composite.getChildren(); 178 int count = children.length; 179 180 int ws[] = new int[count]; 181 182 int h = rect.height; 183 int totalWidth = -GAP; 184 for (int i = 0; i < count; i++) { 185 Control w = children[i]; 186 if (w == fProgressBarComposite && !fProgressIsVisible) { 187 continue; 188 } 189 if (w == fToolBar && !fCancelButtonIsVisible) { 190 continue; 191 } 192 StatusLineLayoutData data = (StatusLineLayoutData) w 193 .getLayoutData(); 194 if (data == null) { 195 data = DEFAULT_DATA; 196 } 197 int width = w.computeSize(data.widthHint, h, flushCache).x; 198 ws[i] = width; 199 totalWidth += width + GAP; 200 } 201 202 int diff = rect.width - totalWidth; 203 ws[0] += diff; 205 final int msgMinWidth = rect.width / 3; 207 if (ws[0] < msgMinWidth) { 208 diff = ws[0] - msgMinWidth; 209 ws[0] = msgMinWidth; 210 } else { 211 diff = 0; 212 } 213 214 for (int i = count - 1; i >= 0 && diff < 0; --i) { 216 int min = Math.min(ws[i], -diff); 217 ws[i] -= min; 218 diff += min + GAP; 219 } 220 221 int x = rect.x; 222 int y = rect.y; 223 for (int i = 0; i < count; i++) { 224 Control w = children[i]; 225 235 if (w == fProgressBarComposite && !fProgressIsVisible 236 || w == fToolBar && !fCancelButtonIsVisible) { 237 w.setBounds(x + rect.width, y, ws[i], h); 238 continue; 239 } 240 w.setBounds(x, y, ws[i], h); 241 if (ws[i] > 0) { 242 x += ws[i] + GAP; 243 } 244 } 245 } 246 } 247 248 254 public StatusLine(Composite parent, int style) { 255 super(parent, style); 256 257 addDisposeListener(new DisposeListener() { 258 public void widgetDisposed(DisposeEvent e) { 259 handleDispose(); 260 } 261 }); 262 263 268 setLayout(new StatusLineLayout()); 269 270 fMessageLabel = new CLabel(this, SWT.NONE); 277 fProgressIsVisible = false; 278 fCancelEnabled = false; 279 280 fToolBar = new ToolBar(this, SWT.FLAT); 281 fCancelButton = new ToolItem(fToolBar, SWT.PUSH); 282 fCancelButton.setImage(fgStopImage.createImage()); 283 fCancelButton.setToolTipText(JFaceResources 284 .getString("Cancel_Current_Operation")); fCancelButton.addSelectionListener(new SelectionAdapter() { 286 public void widgetSelected(SelectionEvent e) { 287 setCanceled(true); 288 } 289 }); 290 fCancelButton.addDisposeListener(new DisposeListener() { 291 public void widgetDisposed(DisposeEvent e) { 292 Image i = fCancelButton.getImage(); 293 if ((i != null) && (!i.isDisposed())) { 294 i.dispose(); 295 } 296 } 297 }); 298 299 fProgressBarComposite = new Composite(this, SWT.NONE); 302 GridLayout layout = new GridLayout(); 303 layout.horizontalSpacing = 0; 304 layout.verticalSpacing = 0; 305 layout.marginHeight = 0; 306 layout.marginWidth = 0; 307 fProgressBarComposite.setLayout(layout); 308 fProgressBar = new ProgressIndicator(fProgressBarComposite); 309 fProgressBar.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL 310 | GridData.GRAB_VERTICAL)); 311 312 fStopButtonCursor = new Cursor(getDisplay(), SWT.CURSOR_ARROW); 313 } 314 315 326 public void beginTask(String name, int totalWork) { 327 final long timestamp = System.currentTimeMillis(); 328 fStartTime = timestamp; 329 final boolean animated = (totalWork == UNKNOWN || totalWork == 0); 330 Runnable timer = new Runnable () { 333 public void run() { 334 StatusLine.this.startTask(timestamp, animated); 335 } 336 }; 337 if (fProgressBar == null) { 338 return; 339 } 340 341 fProgressBar.getDisplay().timerExec(DELAY_PROGRESS, timer); 342 if (!animated) { 343 fProgressBar.beginTask(totalWork); 344 } 345 if (name == null) { 346 fTaskName = ""; } else { 348 fTaskName = name; 349 } 350 setMessage(fTaskName); 351 } 352 353 359 public void done() { 360 361 fStartTime = 0; 362 363 if (fProgressBar != null) { 364 fProgressBar.sendRemainingWork(); 365 fProgressBar.done(); 366 } 367 setMessage(null); 368 369 hideProgress(); 370 } 371 372 376 public IProgressMonitor getProgressMonitor() { 377 return this; 378 } 379 380 383 protected void handleDispose() { 384 if (fStopButtonCursor != null) { 385 fStopButtonCursor.dispose(); 386 fStopButtonCursor = null; 387 } 388 if (fProgressBar != null) { 389 fProgressBar.dispose(); 390 fProgressBar = null; 391 } 392 } 393 394 398 protected void hideProgress() { 399 400 if (fProgressIsVisible && !isDisposed()) { 401 fProgressIsVisible = false; 402 fCancelEnabled = false; 403 fCancelButtonIsVisible = false; 404 if (fToolBar != null && !fToolBar.isDisposed()) { 405 fToolBar.setVisible(false); 406 } 407 if (fProgressBarComposite != null 408 && !fProgressBarComposite.isDisposed()) { 409 fProgressBarComposite.setVisible(false); 410 } 411 layout(); 412 } 413 } 414 415 418 public void internalWorked(double work) { 419 if (!fProgressIsVisible) { 420 if (System.currentTimeMillis() - fStartTime > DELAY_PROGRESS) { 421 showProgress(); 422 } 423 } 424 425 if (fProgressBar != null) { 426 fProgressBar.worked(work); 427 } 428 } 429 430 435 public boolean isCanceled() { 436 return fIsCanceled; 437 } 438 439 444 public boolean isCancelEnabled() { 445 return fCancelEnabled; 446 } 447 448 452 public void setCanceled(boolean b) { 453 fIsCanceled = b; 454 if (fCancelButton != null) { 455 fCancelButton.setEnabled(!b); 456 } 457 } 458 459 467 public void setCancelEnabled(boolean enabled) { 468 fCancelEnabled = enabled; 469 if (fProgressIsVisible && !fCancelButtonIsVisible && enabled) { 470 showButton(); 471 layout(); 472 } 473 if (fCancelButton != null && !fCancelButton.isDisposed()) { 474 fCancelButton.setEnabled(enabled); 475 } 476 } 477 478 484 public void setErrorMessage(String message) { 485 setErrorMessage(null, message); 486 } 487 488 494 public void setErrorMessage(Image image, String message) { 495 fErrorText = trim(message); 496 fErrorImage = image; 497 updateMessageLabel(); 498 } 499 500 503 public void setFont(Font font) { 504 super.setFont(font); 505 Control[] children = getChildren(); 506 for (int i = 0; i < children.length; i++) { 507 children[i].setFont(font); 508 } 509 } 510 511 517 public void setMessage(String message) { 518 setMessage(null, message); 519 } 520 521 527 public void setMessage(Image image, String message) { 528 fMessageText = trim(message); 529 fMessageImage = image; 530 updateMessageLabel(); 531 } 532 533 536 public void setTaskName(String name) { 537 fTaskName = name; 538 } 539 540 544 protected void showButton() { 545 if (fToolBar != null && !fToolBar.isDisposed()) { 546 fToolBar.setVisible(true); 547 fToolBar.setEnabled(true); 548 fToolBar.setCursor(fStopButtonCursor); 549 fCancelButtonIsVisible = true; 550 } 551 } 552 553 557 protected void showProgress() { 558 if (!fProgressIsVisible && !isDisposed()) { 559 fProgressIsVisible = true; 560 if (fCancelEnabled) { 561 showButton(); 562 } 563 if (fProgressBarComposite != null 564 && !fProgressBarComposite.isDisposed()) { 565 fProgressBarComposite.setVisible(true); 566 } 567 layout(); 568 } 569 } 570 571 574 void startTask(final long timestamp, final boolean animated) { 575 if (!fProgressIsVisible && fStartTime == timestamp) { 576 showProgress(); 577 if (animated) { 578 if (fProgressBar != null && !fProgressBar.isDisposed()) { 579 fProgressBar.beginAnimatedTask(); 580 } 581 } 582 } 583 } 584 585 591 public void subTask(String name) { 592 String text; 593 if (fTaskName.length() == 0) { 594 text = name; 595 } else { 596 text = JFaceResources.format( 597 "Set_SubTask", new Object [] { fTaskName, name }); } 599 setMessage(text); 600 } 601 602 607 String trim(String message) { 608 if (message == null) { 609 return null; 610 } 611 int cr = message.indexOf('\r'); 612 int lf = message.indexOf('\n'); 613 if (cr == -1 && lf == -1) { 614 return message; 615 } 616 int len; 617 if (cr == -1) { 618 len = lf; 619 } else if (lf == -1) { 620 len = cr; 621 } else { 622 len = Math.min(cr, lf); 623 } 624 return message.substring(0, len); 625 } 626 627 630 protected void updateMessageLabel() { 631 if (fMessageLabel != null && !fMessageLabel.isDisposed()) { 632 Display display = fMessageLabel.getDisplay(); 633 if ((fErrorText != null && fErrorText.length() > 0) 634 || fErrorImage != null) { 635 fMessageLabel.setForeground(JFaceColors.getErrorText(display)); 636 fMessageLabel.setText(fErrorText); 637 fMessageLabel.setImage(fErrorImage); 638 } else { 639 fMessageLabel.setForeground(display 640 .getSystemColor(SWT.COLOR_WIDGET_FOREGROUND)); 641 fMessageLabel.setText(fMessageText == null ? "" : fMessageText); fMessageLabel.setImage(fMessageImage); 643 } 644 } 645 } 646 647 650 public void worked(int work) { 651 internalWorked(work); 652 } 653 } 654 | Popular Tags |