1 11 package org.eclipse.ui.internal.progress; 12 13 import java.lang.reflect.InvocationTargetException ; 14 import java.util.Collection ; 15 import java.util.Collections ; 16 import java.util.HashSet ; 17 18 import org.eclipse.core.runtime.Assert; 19 import org.eclipse.core.runtime.IProgressMonitor; 20 import org.eclipse.core.runtime.IStatus; 21 import org.eclipse.core.runtime.Status; 22 import org.eclipse.core.runtime.jobs.IJobChangeEvent; 23 import org.eclipse.core.runtime.jobs.IJobChangeListener; 24 import org.eclipse.core.runtime.jobs.ISchedulingRule; 25 import org.eclipse.core.runtime.jobs.Job; 26 import org.eclipse.core.runtime.jobs.JobChangeAdapter; 27 import org.eclipse.jface.operation.IRunnableContext; 28 import org.eclipse.jface.operation.IRunnableWithProgress; 29 import org.eclipse.jface.resource.ImageDescriptor; 30 import org.eclipse.jface.util.IPropertyChangeListener; 31 import org.eclipse.swt.SWT; 32 import org.eclipse.swt.graphics.Cursor; 33 import org.eclipse.swt.graphics.Image; 34 import org.eclipse.swt.widgets.Control; 35 import org.eclipse.swt.widgets.Display; 36 import org.eclipse.swt.widgets.Shell; 37 import org.eclipse.ui.IWorkbenchPart; 38 import org.eclipse.ui.PlatformUI; 39 import org.eclipse.ui.internal.PartSite; 40 import org.eclipse.ui.internal.WorkbenchPlugin; 41 import org.eclipse.ui.part.WorkbenchPart; 42 import org.eclipse.ui.progress.IProgressService; 43 import org.eclipse.ui.progress.IWorkbenchSiteProgressService; 44 import org.eclipse.ui.progress.WorkbenchJob; 45 46 50 public class WorkbenchSiteProgressService implements 51 IWorkbenchSiteProgressService, IJobBusyListener { 52 PartSite site; 53 54 private Collection busyJobs = Collections.synchronizedSet(new HashSet ()); 55 56 private Object busyLock = new Object (); 57 58 IJobChangeListener listener; 59 60 IPropertyChangeListener[] changeListeners = new IPropertyChangeListener[0]; 61 62 private Cursor waitCursor; 63 64 private SiteUpdateJob updateJob; 65 66 69 private int busyCount = 0; 70 71 private class SiteUpdateJob extends WorkbenchJob { 72 private boolean busy; 73 74 private boolean useWaitCursor = false; 75 76 Object lock = new Object (); 77 78 83 void setBusy(boolean cursorState) { 84 synchronized (lock) { 85 busy = cursorState; 86 } 87 } 88 89 private SiteUpdateJob() { 90 super(ProgressMessages.WorkbenchSiteProgressService_CursorJob); 91 } 92 93 98 private Cursor getWaitCursor(Display display) { 99 if (waitCursor == null) { 100 waitCursor = new Cursor(display, SWT.CURSOR_APPSTARTING); 101 } 102 return waitCursor; 103 } 104 105 110 public IStatus runInUIThread(IProgressMonitor monitor) { 111 Control control = site.getPane().getControl(); 112 if (control == null || control.isDisposed()) { 113 return Status.CANCEL_STATUS; 114 } 115 synchronized (lock) { 116 if (useWaitCursor) { 118 Cursor cursor = null; 119 if (busy) { 120 cursor = getWaitCursor(control.getDisplay()); 121 } 122 control.setCursor(cursor); 123 } 124 site.getPane().setBusy(busy); 125 IWorkbenchPart part = site.getPart(); 126 if (part instanceof WorkbenchPart) { 127 ((WorkbenchPart) part).showBusy(busy); 128 } 129 } 130 return Status.OK_STATUS; 131 } 132 133 void clearCursors() { 134 if (waitCursor != null) { 135 waitCursor.dispose(); 136 waitCursor = null; 137 } 138 } 139 } 140 141 147 public WorkbenchSiteProgressService(final PartSite partSite) { 148 site = partSite; 149 updateJob = new SiteUpdateJob(); 150 updateJob.setSystem(true); 151 } 152 153 157 public void dispose() { 158 if (updateJob != null) { 159 updateJob.cancel(); 160 } 161 162 ProgressManager.getInstance().removeListener(this); 163 164 if (waitCursor == null) { 165 return; 166 } 167 waitCursor.dispose(); 168 waitCursor = null; 169 } 170 171 176 public void busyCursorWhile(IRunnableWithProgress runnable) 177 throws InvocationTargetException , InterruptedException { 178 getWorkbenchProgressService().busyCursorWhile(runnable); 179 } 180 181 187 public void schedule(Job job, long delay, boolean useHalfBusyCursor) { 188 job.addJobChangeListener(getJobChangeListener(job, useHalfBusyCursor)); 189 job.schedule(delay); 190 } 191 192 198 public void schedule(Job job, long delay) { 199 schedule(job, delay, false); 200 } 201 202 207 public void schedule(Job job) { 208 schedule(job, 0L, false); 209 } 210 211 216 public void showBusyForFamily(Object family) { 217 ProgressManager.getInstance().addListenerToFamily(family, this); 218 } 219 220 227 public IJobChangeListener getJobChangeListener(final Job job, 228 boolean useHalfBusyCursor) { 229 if (listener == null) { 230 updateJob.useWaitCursor = useHalfBusyCursor; 231 listener = new JobChangeAdapter() { 232 237 public void aboutToRun(IJobChangeEvent event) { 238 incrementBusy(event.getJob()); 239 } 240 241 246 public void done(IJobChangeEvent event) { 247 decrementBusy(event.getJob()); 248 } 249 }; 250 } 251 return listener; 252 } 253 254 259 public void decrementBusy(Job job) { 260 synchronized (busyLock) { 261 if (!busyJobs.contains(job)) { 262 return; 263 } 264 busyJobs.remove(job); 265 } 266 try { 267 decrementBusy(); 268 } catch (Exception ex) { 269 WorkbenchPlugin.log(ex); 271 } 272 } 273 274 279 public void incrementBusy(Job job) { 280 synchronized (busyLock) { 281 if (busyJobs.contains(job)) { 282 return; 283 } 284 busyJobs.add(job); 285 } 286 incrementBusy(); 287 } 288 289 294 public void warnOfContentChange() { 295 site.getPane().showHighlight(); 296 } 297 298 304 public void showInDialog(Shell shell, Job job) { 305 getWorkbenchProgressService().showInDialog(shell, job); 306 } 307 308 313 private IProgressService getWorkbenchProgressService() { 314 return site.getWorkbenchWindow().getWorkbench().getProgressService(); 315 } 316 317 323 public void run(boolean fork, boolean cancelable, 324 IRunnableWithProgress runnable) throws InvocationTargetException , 325 InterruptedException { 326 getWorkbenchProgressService().run(fork, cancelable, runnable); 327 } 328 329 333 public void runInUI(IRunnableContext context, 334 IRunnableWithProgress runnable, ISchedulingRule rule) 335 throws InvocationTargetException , InterruptedException { 336 getWorkbenchProgressService().runInUI(context, runnable, rule); 337 } 338 339 342 public int getLongOperationTime() { 343 return getWorkbenchProgressService().getLongOperationTime(); 344 } 345 346 349 public void registerIconForFamily(ImageDescriptor icon, Object family) { 350 getWorkbenchProgressService().registerIconForFamily(icon, family); 351 } 352 353 356 public Image getIconFor(Job job) { 357 return getWorkbenchProgressService().getIconFor(job); 358 } 359 360 363 public void incrementBusy() { 364 synchronized (busyLock) { 365 this.busyCount++; 366 if (busyCount != 1) { 367 return; 368 } 369 updateJob.setBusy(true); 370 } 371 if (PlatformUI.isWorkbenchRunning()) { 372 updateJob.schedule(100); 373 } else { 374 updateJob.cancel(); 375 } 376 } 377 380 public void decrementBusy() { 381 synchronized (busyLock) { 382 Assert 383 .isTrue( 384 busyCount > 0, 385 "Ignoring unexpected call to IWorkbenchSiteProgressService.decrementBusy(). This might be due to an earlier call to this method."); this.busyCount--; 387 if (busyCount != 0) { 388 return; 389 } 390 updateJob.setBusy(false); 391 } 392 if (PlatformUI.isWorkbenchRunning()) { 393 updateJob.schedule(100); 394 } else { 395 updateJob.cancel(); 396 } 397 } 398 } 399 | Popular Tags |