Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: bdee80b98a78041ff49bb59d3776ab98de0cc07c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*******************************************************************************
 * Copyright (c) 2000, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.team.internal.ui.actions;

import java.lang.reflect.InvocationTargetException;

import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.progress.IProgressService;

/**
 * This CVS runnable context blocks the UI and can therfore have a shell assigned to
 * it (since the shell won't be closed by the user before the runnable completes.
 */
public class ProgressDialogRunnableContext implements ITeamRunnableContext {

	private Shell shell;
	private IRunnableContext runnableContext;
	private ISchedulingRule schedulingRule;
	private boolean postponeBuild;
	
	public ProgressDialogRunnableContext(Shell shell) {
		this.shell = shell;
	}

	/**
	 * Returns whether the auto-build will be postponed while this
	 * context is executing a runnable.
	 * @return whether the auto-build will be postponed while this
	 * context is executing a runnable.
	 */
	public boolean isPostponeBuild() {
		return postponeBuild;
	}
	
	/**
	 * Set whether the auto-build will be postponed while this
	 * context is executing a runnable.
	 * @param postponeBuild whether to postpone the auto-build.
	 */
	public void setPostponeBuild(boolean postponeBuild) {
		this.postponeBuild = postponeBuild;
	}
	
	/**
	 * Return the scheduling rule that will be obtained before the context
	 * executes a runnable or <code>null</code> if no scheduling rule is to be onbtained.
	 * @return the schedulingRule to be obtained or <code>null</code>.
	 */
	public ISchedulingRule getSchedulingRule() {
		return schedulingRule;
	}
	
	/**
	 * Set the scheduling rule that will be obtained before the context
	 * executes a runnable or <code>null</code> if no scheduling rule is to be onbtained.
	 * @param schedulingRule The schedulingRule to be obtained or <code>null</code>.
	 */
	public void setSchedulingRule(ISchedulingRule schedulingRule) {
		this.schedulingRule = schedulingRule;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.team.internal.ccvs.ui.operations.CVSRunnableContext#getShell()
	 */
	public Shell getShell() {
		return shell;
	}

	/**
	 * Set the runnable context that is used to execute the runnable. By default,
	 * the workbench's progress service is used by clients can provide their own.
	 * @param runnableContext the runnable contentx used to execute runnables.
	 */
	public void setRunnableContext(IRunnableContext runnableContext) {
		this.runnableContext = runnableContext;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.team.internal.ui.actions.ITeamRunnableContext#run(org.eclipse.jface.operation.IRunnableWithProgress)
	 */
	public void run(IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException {
		getRunnableContext().run(true /* fork */, true /* cancelable */, wrapRunnable(runnable));
	}

	private IRunnableContext getRunnableContext() {
		if (runnableContext == null) {
			return new IRunnableContext() {
				public void run(boolean fork, boolean cancelable, IRunnableWithProgress runnable)
						throws InvocationTargetException, InterruptedException {
					IProgressService manager = PlatformUI.getWorkbench().getProgressService();
					manager.busyCursorWhile(runnable);
				}
			};
		}
		return runnableContext;
	}

	/*
	 * Return an IRunnableWithProgress that sets the task name for the progress monitor
	 * and runs in a workspace modify operation if requested.
	 */
	private IRunnableWithProgress wrapRunnable(final IRunnableWithProgress runnable) {
		return new IRunnableWithProgress() {
			public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
				try {
					if (schedulingRule == null && !postponeBuild) {
						runnable.run(monitor);
					} else {
						final Exception[] exception = new Exception[] { null };
						ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
							public void run(IProgressMonitor pm) throws CoreException {
								try {
									runnable.run(pm);
								} catch (InvocationTargetException e) {
									exception[0] = e;
								} catch (InterruptedException e) {
									exception[0] = e;
								}
							}
						}, schedulingRule, 0 /* allow updates */, monitor);
						if (exception[0] != null) {
							if (exception[0] instanceof InvocationTargetException) {
								throw (InvocationTargetException)exception[0];
							} else if (exception[0] instanceof InterruptedException) {
								throw (InterruptedException)exception[0];	
							}
						}
					}
				} catch (CoreException e) {
					throw new InvocationTargetException(e);
				}
			}
		};
	}

}

Back to the top