Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.e4.ui.progress/src/org/eclipse/e4/ui/progress/internal/ProgressServiceImpl.java')
-rw-r--r--bundles/org.eclipse.e4.ui.progress/src/org/eclipse/e4/ui/progress/internal/ProgressServiceImpl.java353
1 files changed, 353 insertions, 0 deletions
diff --git a/bundles/org.eclipse.e4.ui.progress/src/org/eclipse/e4/ui/progress/internal/ProgressServiceImpl.java b/bundles/org.eclipse.e4.ui.progress/src/org/eclipse/e4/ui/progress/internal/ProgressServiceImpl.java
new file mode 100644
index 00000000000..48942809f68
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.progress/src/org/eclipse/e4/ui/progress/internal/ProgressServiceImpl.java
@@ -0,0 +1,353 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2014 IBM Corporation and others.
+ * 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:
+ * IBM Corporation - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.e4.ui.progress.internal;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import javax.inject.Inject;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.IJobManager;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.e4.core.di.annotations.Optional;
+import org.eclipse.e4.ui.di.UISynchronize;
+import org.eclipse.e4.ui.progress.IProgressConstants;
+import org.eclipse.e4.ui.progress.IProgressService;
+import org.eclipse.e4.ui.progress.UIJob;
+import org.eclipse.e4.ui.progress.internal.legacy.EventLoopProgressMonitor;
+import org.eclipse.e4.ui.progress.internal.legacy.PlatformUI;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+public class ProgressServiceImpl implements IProgressService {
+
+ private static final String IMAGE_KEY = "org.eclipse.ui.progress.images"; //$NON-NLS-1$
+
+ private Hashtable imageKeyTable = new Hashtable();
+
+ @Inject
+ @Optional
+ ProgressManager progressManager;
+
+ @Inject
+ @Optional
+ FinishedJobs finishedJobs;
+
+ @Inject
+ @Optional
+ ContentProviderFactory contentProviderFactory;
+
+ @Inject
+ @Optional
+ UISynchronize uiSynchronize;
+
+ @Override
+ public int getLongOperationTime() {
+ return 800;
+ }
+
+ @Override
+ public void registerIconForFamily(ImageDescriptor icon, Object family) {
+ String key = IMAGE_KEY + String.valueOf(imageKeyTable.size());
+ imageKeyTable.put(family, key);
+ ImageRegistry registry = JFaceResources.getImageRegistry();
+
+ // Avoid registering twice
+ if (registry.getDescriptor(key) == null) {
+ registry.put(key, icon);
+ }
+ }
+
+ @Override
+ public void runInUI(IRunnableContext context,
+ IRunnableWithProgress runnable, ISchedulingRule rule)
+ throws InvocationTargetException, InterruptedException {
+ final RunnableWithStatus runnableWithStatus = new RunnableWithStatus(
+ context,
+ runnable, rule);
+ uiSynchronize.syncExec(new Runnable() {
+ public void run() {
+ BusyIndicator.showWhile(getDisplay(), runnableWithStatus);
+ }
+
+ });
+
+ IStatus status = runnableWithStatus.getStatus();
+ if (!status.isOK()) {
+ Throwable exception = status.getException();
+ if (exception instanceof InvocationTargetException)
+ throw (InvocationTargetException) exception;
+ else if (exception instanceof InterruptedException)
+ throw (InterruptedException) exception;
+ else // should be OperationCanceledException
+ throw new InterruptedException(exception.getMessage());
+ }
+ }
+
+ @Override
+ public Image getIconFor(Job job) {
+ Enumeration families = imageKeyTable.keys();
+ while (families.hasMoreElements()) {
+ Object next = families.nextElement();
+ if (job.belongsTo(next)) {
+ return JFaceResources.getImageRegistry().get(
+ (String) imageKeyTable.get(next));
+ }
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.progress.IProgressService#busyCursorWhile(org.eclipse.jface.operation.IRunnableWithProgress)
+ */
+ @Override
+ public void busyCursorWhile(final IRunnableWithProgress runnable)
+ throws InvocationTargetException, InterruptedException {
+ final ProgressMonitorJobsDialog dialog = new ProgressMonitorJobsDialog(
+ ProgressManagerUtil.getDefaultParent(), this, progressManager,
+ contentProviderFactory, finishedJobs);
+ dialog.setOpenOnRun(false);
+ final InvocationTargetException[] invokes = new InvocationTargetException[1];
+ final InterruptedException[] interrupt = new InterruptedException[1];
+ // show a busy cursor until the dialog opens
+ Runnable dialogWaitRunnable = new Runnable() {
+ public void run() {
+ try {
+ dialog.setOpenOnRun(false);
+ setUserInterfaceActive(false);
+ dialog.run(true, true, runnable);
+ } catch (InvocationTargetException e) {
+ invokes[0] = e;
+ } catch (InterruptedException e) {
+ interrupt[0] = e;
+ } finally {
+ setUserInterfaceActive(true);
+ }
+ }
+ };
+ busyCursorWhile(dialogWaitRunnable, dialog);
+ if (invokes[0] != null) {
+ throw invokes[0];
+ }
+ if (interrupt[0] != null) {
+ throw interrupt[0];
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.operation.IRunnableContext#run(boolean, boolean,
+ * org.eclipse.jface.operation.IRunnableWithProgress)
+ */
+ public void run(boolean fork, boolean cancelable,
+ IRunnableWithProgress runnable) throws InvocationTargetException,
+ InterruptedException {
+ if (fork == false || cancelable == false) {
+ // backward compatible code
+ final ProgressMonitorJobsDialog dialog = new ProgressMonitorJobsDialog(
+ null, this, progressManager, contentProviderFactory,
+ finishedJobs);
+ dialog.run(fork, cancelable, runnable);
+ return;
+ }
+
+ busyCursorWhile(runnable);
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.progress.IProgressService#showInDialog(org.eclipse.swt.widgets.Shell,
+ * org.eclipse.core.runtime.jobs.Job)
+ */
+ @Override
+ public void showInDialog(Shell shell, Job job) {
+ if (shouldRunInBackground()) {
+ return;
+ }
+
+ final ProgressMonitorFocusJobDialog dialog = new ProgressMonitorFocusJobDialog(
+ shell, this, progressManager, contentProviderFactory,
+ finishedJobs);
+ dialog.show(job, shell);
+ }
+
+ /**
+ * Return whether or not dialogs should be run in the background
+ *
+ * @return <code>true</code> if the dialog should not be shown.
+ */
+ protected boolean shouldRunInBackground() {
+ return Preferences.getBoolean(IProgressConstants.RUN_IN_BACKGROUND);
+ }
+
+ private class RunnableWithStatus implements Runnable {
+
+ IStatus status = Status.OK_STATUS;
+ private final IRunnableContext context;
+ private final IRunnableWithProgress runnable;
+ private final ISchedulingRule rule;
+
+ public RunnableWithStatus(IRunnableContext context,
+ IRunnableWithProgress runnable, ISchedulingRule rule) {
+ this.context = context;
+ this.runnable = runnable;
+ this.rule = rule;
+ }
+
+ public void run() {
+ IJobManager manager = Job.getJobManager();
+ try {
+ manager.beginRule(rule, getEventLoopMonitor());
+ context.run(false, false, runnable);
+ } catch (InvocationTargetException e) {
+ status = new Status(IStatus.ERROR, IProgressConstants.PLUGIN_ID, e
+ .getMessage(), e);
+ } catch (InterruptedException e) {
+ status = new Status(IStatus.ERROR, IProgressConstants.PLUGIN_ID, e
+ .getMessage(), e);
+ } catch (OperationCanceledException e) {
+ status = new Status(IStatus.ERROR, IProgressConstants.PLUGIN_ID, e
+ .getMessage(), e);
+ } finally {
+ manager.endRule(rule);
+ }
+ }
+
+ /**
+ * Get a progress monitor that forwards to an event loop monitor.
+ * Override #setBlocked() so that we always open the blocked dialog.
+ *
+ * @return the monitor on the event loop
+ */
+ private IProgressMonitor getEventLoopMonitor() {
+
+ if (PlatformUI.isWorkbenchStarting())
+ return new NullProgressMonitor();
+
+ return new EventLoopProgressMonitor(new NullProgressMonitor()) {
+
+ public void setBlocked(IStatus reason) {
+
+ // Set a shell to open with as we want to create
+ // this
+ // even if there is a modal shell.
+ Dialog.getBlockedHandler().showBlocked(
+ ProgressManagerUtil.getDefaultParent(), this,
+ reason, getTaskName());
+ }
+ };
+ }
+
+ public IStatus getStatus() {
+ return status;
+ }
+
+ }
+
+ /**
+ * Show the busy cursor while the runnable is running. Schedule a job to
+ * replace it with a progress dialog.
+ *
+ * @param dialogWaitRunnable
+ * @param dialog
+ */
+ private void busyCursorWhile(Runnable dialogWaitRunnable,
+ ProgressMonitorJobsDialog dialog) {
+ // create the job that will open the dialog after a delay
+ scheduleProgressMonitorJob(dialog);
+ final Display display = getDisplay();
+ if (display == null) {
+ return;
+ }
+ // show a busy cursor until the dialog opens
+ BusyIndicator.showWhile(display, dialogWaitRunnable);
+ }
+
+ /**
+ * Schedule the job that will open the progress monitor dialog
+ *
+ * @param dialog
+ * the dialog to open
+ */
+ private void scheduleProgressMonitorJob(
+ final ProgressMonitorJobsDialog dialog) {
+
+ final Job updateJob = new UIJob(
+ ProgressMessages.ProgressManager_openJobName) {
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ public IStatus runInUIThread(IProgressMonitor monitor) {
+ setUserInterfaceActive(true);
+ if (ProgressManagerUtil.safeToOpen(dialog, null)) {
+ dialog.open();
+ }
+ return Status.OK_STATUS;
+ }
+ };
+ updateJob.setSystem(true);
+ updateJob.schedule(getLongOperationTime());
+
+ }
+
+ /**
+ * Iterate through all of the windows and set them to be disabled or enabled
+ * as appropriate.'
+ *
+ * @param active
+ * The set the windows will be set to.
+ */
+ private void setUserInterfaceActive(boolean active) {
+ Shell[] shells = getDisplay().getShells();
+ if (active) {
+ for (int i = 0; i < shells.length; i++) {
+ if (!shells[i].isDisposed()) {
+ shells[i].setEnabled(active);
+ }
+ }
+ } else {
+ // Deactive shells in reverse order
+ for (int i = shells.length - 1; i >= 0; i--) {
+ if (!shells[i].isDisposed()) {
+ shells[i].setEnabled(active);
+ }
+ }
+ }
+ }
+
+ protected Display getDisplay() {
+ return Services.getInstance().getDisplay();
+ }
+
+}

Back to the top