/******************************************************************************* * Copyright (c) 2009 the CHISEL group and contributors. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Del Myers -- initial API and implementation *******************************************************************************/ package org.eclipse.zest.custom.sequence.internal; import java.lang.reflect.InvocationTargetException; import java.util.Timer; import java.util.TimerTask; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.IconAndMessageDialog; import org.eclipse.jface.dialogs.ProgressIndicator; import org.eclipse.swt.SWT; import org.eclipse.swt.SWTException; import org.eclipse.swt.graphics.Cursor; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.zest.custom.sequence.widgets.internal.ThrownErrorDialog; /** * A progress monitor dialog that will update progress in a runnable. We have to use custom * interfaces in order to remove dependencies from the Eclipse runtime. * @author Del Myers * */ public class DelayedProgressMonitorDialog extends IconAndMessageDialog implements IUIProgressService { /** * Constants for label and monitor size */ private static int LABEL_DLUS = 21; private static int BAR_DLUS = 9; private ProgressIndicator progressIndicator; private Label subTaskLabel; private Button cancel; private Cursor arrowCursor; private boolean enableCancelButton; private int work; private double worked; volatile boolean isOpenned; private SimpleProgressMonitor monitor; public DelayedProgressMonitorDialog(Shell parentShell) { super(parentShell); } public void setSubTask(String messageString) { if (getContents() == null) return; // must not set null text in a label String message = messageString == null ? "" : messageString; //$NON-NLS-1$ if (messageLabel == null || messageLabel.isDisposed()) { return; } if (subTaskLabel.isVisible()) { subTaskLabel.setToolTipText(message); subTaskLabel.setText(shortenText(message, subTaskLabel)); } } public void setMainTask(String task) { if (getContents() == null) return; setMessage(task, true); } @Override protected Control createDialogArea(Composite parent) { setMessage("", false); createMessageArea(parent); // Only set for backwards compatibility // progress indicator progressIndicator = new ProgressIndicator(parent); GridData gd = new GridData(); gd.heightHint = convertVerticalDLUsToPixels(BAR_DLUS); gd.horizontalAlignment = GridData.FILL; gd.grabExcessHorizontalSpace = true; gd.horizontalSpan = 2; progressIndicator.setLayoutData(gd); // label showing current task subTaskLabel = new Label(parent, SWT.LEFT | SWT.WRAP); gd = new GridData(GridData.FILL_HORIZONTAL); gd.heightHint = convertVerticalDLUsToPixels(LABEL_DLUS); gd.horizontalSpan = 2; subTaskLabel.setLayoutData(gd); subTaskLabel.setFont(parent.getFont()); return parent; } /** * Set the message in the message label. * * @param messageString * The string for the new message. * @param force * If force is true then always set the message text. */ private void setMessage(String messageString, boolean force) { // must not set null text in a label message = messageString == null ? "" : messageString; //$NON-NLS-1$ if (messageLabel == null || messageLabel.isDisposed()) { return; } if (force || messageLabel.isVisible()) { messageLabel.setToolTipText(message); messageLabel.setText(shortenText(message, messageLabel)); } } void setWork(int work) { if (getShell().isDisposed()) return; if (work == IUIProgressService.UNKNOWN_WORK) { progressIndicator.beginAnimatedTask(); } else { progressIndicator.beginTask(work); } this.work = work; } public void setWorked(int totalWork) { if (getContents() == null) return; if (getShell() == null || getShell().isDisposed()) { return; } if (totalWork == WORKED_DONE) { if (isOpenned) { close(); } return; } if (totalWork > work) { progressIndicator.sendRemainingWork(); } else { double diff = totalWork-this.worked; progressIndicator.worked(diff); } } /* * (non-Javadoc) Method declared on Dialog. */ protected void createButtonsForButtonBar(Composite parent) { // cancel button createCancelButton(parent); } /** * Creates the cancel button. * * @param parent * the parent composite * @since 3.0 */ protected void createCancelButton(Composite parent) { cancel = createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, true); if (arrowCursor == null) { arrowCursor = new Cursor(cancel.getDisplay(), SWT.CURSOR_ARROW); } cancel.setCursor(arrowCursor); cancel.setEnabled(enableCancelButton); // if (enableCancelButton) { // cancel.addSelectionListener(new SelectionListener(){ // @Override // public void widgetDefaultSelected(SelectionEvent e) { // cancel(); // } // // @Override // public void widgetSelected(SelectionEvent e) { // cancel(); // }}); // } } @Override protected Image getImage() { return getInfoImage(); } public void runInUIThread(final AbstractSimpleProgressRunnable runnable, boolean enableCancelButton) throws InvocationTargetException { setBlockOnOpen(false); if (Display.getCurrent() == null) { throw new SWTException(SWT.ERROR_THREAD_INVALID_ACCESS); } final Display finalDisplay = Display.getCurrent(); this.enableCancelButton = enableCancelButton; create(); this.monitor = new SimpleProgressMonitor(this, enableCancelButton); new Timer("Delayed Progress Service").schedule(new TimerTask(){ public void run() { finalDisplay.asyncExec(new Runnable(){ public void run() { if (!(monitor.isCancelled() || monitor.isDone())) { open(); } } }); } }, 1500); progressIndicator.beginAnimatedTask(); runnable.runInUIThread(monitor); if (isOpenned) { close(); } } @Override protected void cancelPressed() { if (monitor != null && !monitor.isCancelled()) { monitor.cancel(); } super.cancelPressed(); } @Override public synchronized int open() { this.isOpenned = true; return super.open(); } @Override public synchronized boolean close() { this.isOpenned = false; return super.close(); } @Override protected void configureShell(Shell newShell) { super.configureShell(newShell); newShell.setText("Working..."); } public void setTask(String taskName, int totalWork) { if (getContents() == null) return; setMainTask(taskName); setWork(totalWork); } public void setTaskName(String taskName) { if (getContents() == null) return; setMainTask(taskName); } /* (non-Javadoc) * @see org.eclipse.zest.custom.sequence.internal.IUIProgressService#handleException(java.lang.Throwable) */ public void handleException(Throwable t) { new ThrownErrorDialog(getShell()).open(t); } }