001: /*******************************************************************************
002: * Copyright (c) 2005, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM - Initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.internal.operations;
011:
012: import java.lang.reflect.InvocationTargetException;
013:
014: import org.eclipse.core.runtime.IProgressMonitor;
015: import org.eclipse.jface.dialogs.ProgressMonitorDialog;
016: import org.eclipse.jface.operation.IRunnableWithProgress;
017: import org.eclipse.swt.custom.BusyIndicator;
018: import org.eclipse.swt.widgets.Display;
019: import org.eclipse.swt.widgets.Shell;
020: import org.eclipse.ui.PlatformUI;
021:
022: /**
023: * The TimeTriggeredProgressMonitorDialog is a progress monitor dialog that only
024: * opens if the runnable provided exceeds the specified long operation time.
025: *
026: * @since 3.1
027: */
028: public class TimeTriggeredProgressMonitorDialog extends
029: ProgressMonitorDialog {
030:
031: /**
032: * The time considered to be the long operation time.
033: */
034: private int longOperationTime;
035:
036: /**
037: * The time at which the dialog should be opened.
038: */
039: private long triggerTime = -1;
040:
041: /**
042: * Whether or not we've already opened a dialog.
043: */
044: private boolean dialogOpened = false;
045:
046: /**
047: * Wrappered monitor so we can check ticks and open the dialog when
048: * appropriate
049: */
050: private IProgressMonitor wrapperedMonitor;
051:
052: /**
053: * Create a new instance of the receiver.
054: *
055: * @param parent
056: * the parent of the dialog
057: * @param longOperationTime
058: * the time (in milliseconds) considered to be a long enough
059: * execution time to warrant opening a dialog.
060: */
061: public TimeTriggeredProgressMonitorDialog(Shell parent,
062: int longOperationTime) {
063: super (parent);
064: setOpenOnRun(false);
065: this .longOperationTime = longOperationTime;
066: }
067:
068: /**
069: * Create a monitor for the receiver that wrappers the superclasses monitor.
070: *
071: */
072: public void createWrapperedMonitor() {
073: wrapperedMonitor = new IProgressMonitor() {
074:
075: IProgressMonitor super Monitor = TimeTriggeredProgressMonitorDialog.super
076: .getProgressMonitor();
077:
078: /*
079: * (non-Javadoc)
080: *
081: * @see org.eclipse.core.runtime.IProgressMonitor#beginTask(java.lang.String,
082: * int)
083: */
084: public void beginTask(String name, int totalWork) {
085: super Monitor.beginTask(name, totalWork);
086: checkTicking();
087: }
088:
089: /**
090: * Check if we have ticked in the last 800ms.
091: */
092: private void checkTicking() {
093: if (triggerTime < 0) {
094: triggerTime = System.currentTimeMillis()
095: + longOperationTime;
096: }
097: if (!dialogOpened
098: && System.currentTimeMillis() > triggerTime) {
099: open();
100: dialogOpened = true;
101: }
102: }
103:
104: /*
105: * (non-Javadoc)
106: *
107: * @see org.eclipse.core.runtime.IProgressMonitor#done()
108: */
109: public void done() {
110: super Monitor.done();
111: checkTicking();
112: }
113:
114: /*
115: * (non-Javadoc)
116: *
117: * @see org.eclipse.core.runtime.IProgressMonitor#internalWorked(double)
118: */
119: public void internalWorked(double work) {
120: super Monitor.internalWorked(work);
121: checkTicking();
122: }
123:
124: /*
125: * (non-Javadoc)
126: *
127: * @see org.eclipse.core.runtime.IProgressMonitor#isCanceled()
128: */
129: public boolean isCanceled() {
130: return super Monitor.isCanceled();
131: }
132:
133: /*
134: * (non-Javadoc)
135: *
136: * @see org.eclipse.core.runtime.IProgressMonitor#setCanceled(boolean)
137: */
138: public void setCanceled(boolean value) {
139: super Monitor.setCanceled(value);
140:
141: }
142:
143: /*
144: * (non-Javadoc)
145: *
146: * @see org.eclipse.core.runtime.IProgressMonitor#setTaskName(java.lang.String)
147: */
148: public void setTaskName(String name) {
149: super Monitor.setTaskName(name);
150: checkTicking();
151:
152: }
153:
154: /*
155: * (non-Javadoc)
156: *
157: * @see org.eclipse.core.runtime.IProgressMonitor#subTask(java.lang.String)
158: */
159: public void subTask(String name) {
160: super Monitor.subTask(name);
161: checkTicking();
162: }
163:
164: /*
165: * (non-Javadoc)
166: *
167: * @see org.eclipse.core.runtime.IProgressMonitor#worked(int)
168: */
169: public void worked(int work) {
170: super Monitor.worked(work);
171: checkTicking();
172:
173: }
174: };
175: }
176:
177: /*
178: * (non-Javadoc)
179: *
180: * @see org.eclipse.jface.dialogs.ProgressMonitorDialog#getProgressMonitor()
181: */
182: public IProgressMonitor getProgressMonitor() {
183: if (wrapperedMonitor == null) {
184: createWrapperedMonitor();
185: }
186: return wrapperedMonitor;
187: }
188:
189: /*
190: * (non-Javadoc)
191: *
192: * @see org.eclipse.jface.operations.IRunnableContext#run(boolean, boolean, IRunnableWithProgress)
193: */
194: public void run(final boolean fork, final boolean cancelable,
195: final IRunnableWithProgress runnable)
196: throws InvocationTargetException, InterruptedException {
197: final InvocationTargetException[] invokes = new InvocationTargetException[1];
198: final InterruptedException[] interrupt = new InterruptedException[1];
199: Runnable dialogWaitRunnable = new Runnable() {
200: public void run() {
201: try {
202: TimeTriggeredProgressMonitorDialog.super .run(fork,
203: cancelable, runnable);
204: } catch (InvocationTargetException e) {
205: invokes[0] = e;
206: } catch (InterruptedException e) {
207: interrupt[0] = e;
208: }
209: }
210: };
211: final Display display = PlatformUI.getWorkbench().getDisplay();
212: if (display == null) {
213: return;
214: }
215: //show a busy cursor until the dialog opens
216: BusyIndicator.showWhile(display, dialogWaitRunnable);
217: if (invokes[0] != null) {
218: throw invokes[0];
219: }
220: if (interrupt[0] != null) {
221: throw interrupt[0];
222: }
223: }
224: }
|