Have icon for "reset" entry in reflog
[egit/eclipse.git] / org.eclipse.egit.ui / src / org / eclipse / egit / ui / internal / jobs / RepositoryJob.java
blobeadbce43a5b3a45f7a68939dfd513f4002de26f2
1 /*******************************************************************************
2 * Copyright (c) 2016, 2017 Thomas Wolf <thomas.wolf@paranor.ch>
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License 2.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/legal/epl-2.0/
8 * SPDX-License-Identifier: EPL-2.0
9 *******************************************************************************/
10 package org.eclipse.egit.ui.internal.jobs;
12 import java.text.MessageFormat;
14 import org.eclipse.core.runtime.IProgressMonitor;
15 import org.eclipse.core.runtime.IStatus;
16 import org.eclipse.core.runtime.Status;
17 import org.eclipse.core.runtime.jobs.Job;
18 import org.eclipse.egit.ui.Activator;
19 import org.eclipse.egit.ui.internal.UIText;
20 import org.eclipse.jface.action.IAction;
21 import org.eclipse.jgit.annotations.NonNull;
22 import org.eclipse.swt.SWT;
23 import org.eclipse.swt.widgets.Display;
24 import org.eclipse.swt.widgets.Shell;
25 import org.eclipse.ui.PlatformUI;
26 import org.eclipse.ui.progress.IProgressConstants;
27 import org.eclipse.ui.progress.WorkbenchJob;
29 /**
30 * A {@link Job} operating (solely) on a repository, reporting some result
31 * beyond a mere {@link IStatus} back to the user via an {@link IAction}. If a
32 * dialog preference is given, the result dialog is shown only if it is
33 * {@code true}, otherwise the job's {@link IProgressConstants#ACTION_PROPERTY}
34 * is used to associate the action with the finished job and eventual display of
35 * the result is left to the progress reporting framework.
37 public abstract class RepositoryJob extends Job {
39 private final String dialogPreference;
41 /**
42 * Creates a new {@link RepositoryJob}.
44 * @param name
45 * of the job.
46 * @param dialogPreference
47 * key of the preference governing the showing of the result
48 * dialog on success; may be {@code null} if the dialog shall be
49 * shown unconditionally
51 public RepositoryJob(String name, String dialogPreference) {
52 super(name);
53 this.dialogPreference = dialogPreference;
56 @Override
57 protected final IStatus run(IProgressMonitor monitor) {
58 try {
59 IStatus status = performJob(monitor);
60 if (status == null) {
61 return Activator.createErrorStatus(MessageFormat
62 .format(UIText.RepositoryJob_NullStatus, getName()),
63 new NullPointerException());
64 } else if (!status.isOK()) {
65 return status;
67 IAction action = getAction();
68 if (action != null) {
69 boolean showDialog = dialogPreference == null
70 || Activator.getDefault().getPreferenceStore()
71 .getBoolean(dialogPreference);
72 if (showDialog) {
73 if (isModal()) {
74 showResult(action);
75 } else {
76 showResultDeferred(action);
78 } else {
79 setProperty(IProgressConstants.KEEP_PROPERTY, Boolean.TRUE);
80 setProperty(IProgressConstants.ACTION_PROPERTY, action);
81 IStatus finalStatus = getDeferredStatus();
82 String msg = finalStatus.getMessage();
83 if (msg == null || msg.isEmpty()) {
84 return new Status(finalStatus.getSeverity(),
85 finalStatus.getPlugin(), finalStatus.getCode(),
86 action.getText(), finalStatus.getException());
88 return finalStatus;
91 return status;
92 } finally {
93 monitor.done();
97 /**
98 * Performs the actual work of the job.
100 * @param monitor
101 * for progress reporting and cancellation.
102 * @return an {@link IStatus} describing the outcome of the job
104 abstract protected IStatus performJob(IProgressMonitor monitor);
107 * Obtains an {@link IAction} to report the full job result if
108 * {@link #performJob(IProgressMonitor)} returned an {@link IStatus#isOK()
109 * isOK()} status.
111 * @return the action, or {@code null} if no action is to be taken
113 abstract protected IAction getAction();
116 * Obtains an {@link IStatus} describing the final outcome of the operation.
117 * This default implementation returns an {@link IStatus#OK OK} status.
119 * @return an {@link IStatus} describing the outcome of the job
121 @NonNull
122 protected IStatus getDeferredStatus() {
123 return new Status(IStatus.OK, Activator.getPluginId(), IStatus.OK, "", //$NON-NLS-1$
124 null);
127 private boolean isModal() {
128 Boolean modal = (Boolean) getProperty(
129 IProgressConstants.PROPERTY_IN_DIALOG);
130 return modal != null && modal.booleanValue();
133 private void showResult(final IAction action) {
134 final Display display = PlatformUI.getWorkbench().getDisplay();
135 if (display != null) {
136 display.asyncExec(new Runnable() {
138 @Override
139 public void run() {
140 if (!display.isDisposed()) {
141 action.run();
148 private void showResultDeferred(final IAction action) {
149 WorkbenchJob dialogJob = new WorkbenchJob(action.getText()) {
151 private boolean isModal(Shell shell) {
152 return (shell.getStyle() & (SWT.APPLICATION_MODAL
153 | SWT.PRIMARY_MODAL | SWT.SYSTEM_MODAL)) != 0;
156 @Override
157 public IStatus runInUIThread(IProgressMonitor monitor) {
158 Shell shell = PlatformUI.getWorkbench()
159 .getModalDialogShellProvider().getShell();
160 if (shell == null) {
161 return Status.CANCEL_STATUS;
163 if (isModal(shell)) {
164 // Don't try to show the result dialog now -- it might
165 // produce a UI deadlock. Try again after a short while.
166 schedule(PlatformUI.getWorkbench().getProgressService()
167 .getLongOperationTime());
168 return Status.CANCEL_STATUS;
170 if (monitor.isCanceled()) {
171 return Status.CANCEL_STATUS;
173 // There is no modal shell: it's safe to open the result dialog.
174 action.run();
175 return Status.OK_STATUS;
178 dialogJob.setSystem(true);
179 dialogJob.schedule();