1 11 package org.eclipse.ui.internal.operations; 12 13 import java.lang.reflect.InvocationTargetException ; 14 15 import org.eclipse.core.commands.ExecutionException; 16 import org.eclipse.core.commands.operations.IAdvancedUndoableOperation; 17 import org.eclipse.core.commands.operations.IAdvancedUndoableOperation2; 18 import org.eclipse.core.commands.operations.IOperationApprover; 19 import org.eclipse.core.commands.operations.IOperationApprover2; 20 import org.eclipse.core.commands.operations.IOperationHistory; 21 import org.eclipse.core.commands.operations.IUndoContext; 22 import org.eclipse.core.commands.operations.IUndoableOperation; 23 import org.eclipse.core.runtime.IAdaptable; 24 import org.eclipse.core.runtime.IProgressMonitor; 25 import org.eclipse.core.runtime.IStatus; 26 import org.eclipse.core.runtime.OperationCanceledException; 27 import org.eclipse.core.runtime.Status; 28 import org.eclipse.jface.dialogs.ErrorDialog; 29 import org.eclipse.jface.dialogs.IDialogConstants; 30 import org.eclipse.jface.dialogs.MessageDialog; 31 import org.eclipse.jface.operation.IRunnableWithProgress; 32 import org.eclipse.jface.window.Window; 33 import org.eclipse.osgi.util.NLS; 34 import org.eclipse.swt.widgets.Shell; 35 import org.eclipse.ui.PlatformUI; 36 import org.eclipse.ui.internal.Workbench; 37 import org.eclipse.ui.internal.WorkbenchMessages; 38 import org.eclipse.ui.internal.WorkbenchPlugin; 39 import org.eclipse.ui.internal.misc.StatusUtil; 40 import org.eclipse.ui.internal.util.Util; 41 42 59 public class AdvancedValidationUserApprover implements IOperationApprover, 60 IOperationApprover2 { 61 62 67 public static boolean AUTOMATED_MODE = false; 68 69 private IUndoContext context; 70 71 private static final int EXECUTING = 1; 72 73 private static final int UNDOING = 2; 74 75 private static final int REDOING = 3; 76 77 private class StatusReportingRunnable implements IRunnableWithProgress { 78 IStatus status; 79 80 int doing; 81 82 IUndoableOperation operation; 83 84 IOperationHistory history; 85 86 IAdaptable uiInfo; 87 88 StatusReportingRunnable(IUndoableOperation operation, 89 IOperationHistory history, IAdaptable uiInfo, int doing) { 90 super(); 91 this.operation = operation; 92 this.history = history; 93 this.doing = doing; 94 this.uiInfo = uiInfo; 95 } 96 97 public void run(IProgressMonitor pm) { 101 try { 102 switch (doing) { 103 case UNDOING: 104 status = ((IAdvancedUndoableOperation) operation) 105 .computeUndoableStatus(pm); 106 break; 107 case REDOING: 108 status = ((IAdvancedUndoableOperation) operation) 109 .computeRedoableStatus(pm); 110 break; 111 case EXECUTING: 112 status = ((IAdvancedUndoableOperation2) operation) 113 .computeExecutionStatus(pm); 114 break; 115 } 116 117 } catch (ExecutionException e) { 118 reportException(e, uiInfo); 119 status = IOperationHistory.OPERATION_INVALID_STATUS; 120 } 121 } 122 123 IStatus getStatus() { 124 return status; 125 } 126 } 127 128 136 public AdvancedValidationUserApprover(IUndoContext context) { 137 super(); 138 this.context = context; 139 } 140 141 148 public IStatus proceedRedoing(IUndoableOperation operation, 149 IOperationHistory history, IAdaptable uiInfo) { 150 return proceedWithOperation(operation, history, uiInfo, REDOING); 151 } 152 153 160 public IStatus proceedUndoing(IUndoableOperation operation, 161 IOperationHistory history, IAdaptable uiInfo) { 162 163 return proceedWithOperation(operation, history, uiInfo, UNDOING); 164 } 165 166 173 public IStatus proceedExecuting(IUndoableOperation operation, 174 IOperationHistory history, IAdaptable uiInfo) { 175 return proceedWithOperation(operation, history, uiInfo, EXECUTING); 176 } 177 178 181 private IStatus proceedWithOperation(final IUndoableOperation operation, 182 final IOperationHistory history, final IAdaptable uiInfo, 183 final int doing) { 184 185 if (!operation.hasContext(context)) { 187 return Status.OK_STATUS; 188 } 189 190 if (doing == EXECUTING) { 193 if (!(operation instanceof IAdvancedUndoableOperation2)) { 194 return Status.OK_STATUS; 195 } 196 } else { 197 if (!(operation instanceof IAdvancedUndoableOperation)) { 198 return Status.OK_STATUS; 199 } 200 } 201 202 final IStatus[] status = new IStatus[1]; 205 Workbench.getInstance().getDisplay().syncExec(new Runnable () { 206 public void run() { 207 status[0] = computeOperationStatus(operation, history, uiInfo, 209 doing); 210 211 if (!status[0].isOK()) { 215 status[0] = reportAndInterpretStatus(status[0], uiInfo, 216 operation, doing); 217 } 218 219 } 220 }); 221 222 if (!status[0].isOK()) { 228 history.operationChanged(operation); 229 } 230 return status[0]; 231 } 232 233 private IStatus computeOperationStatus(IUndoableOperation operation, 234 IOperationHistory history, IAdaptable uiInfo, int doing) { 235 try { 236 StatusReportingRunnable runnable = new StatusReportingRunnable( 237 operation, history, uiInfo, doing); 238 TimeTriggeredProgressMonitorDialog progressDialog = new TimeTriggeredProgressMonitorDialog( 239 getShell(uiInfo), PlatformUI.getWorkbench() 240 .getProgressService().getLongOperationTime()); 241 242 progressDialog.run(false, true, runnable); 243 return runnable.getStatus(); 244 } catch (OperationCanceledException e) { 245 return Status.CANCEL_STATUS; 246 } catch (InvocationTargetException e) { 247 reportException(e, uiInfo); 248 return IOperationHistory.OPERATION_INVALID_STATUS; 249 } catch (InterruptedException e) { 250 return Status.CANCEL_STATUS; 253 } 254 } 255 256 259 private void reportException(Exception e, IAdaptable uiInfo) { 260 Throwable nestedException = StatusUtil.getCause(e); 261 Throwable exception = (nestedException == null) ? e : nestedException; 262 String title = WorkbenchMessages.Error; 263 String message = WorkbenchMessages.WorkbenchWindow_exceptionMessage; 264 String exceptionMessage = exception.getMessage(); 265 if (exceptionMessage == null) { 266 exceptionMessage = message; 267 } 268 IStatus status = new Status(IStatus.ERROR, 269 WorkbenchPlugin.PI_WORKBENCH, 0, exceptionMessage, exception); 270 WorkbenchPlugin.log(message, status); 271 272 boolean createdShell = false; 273 Shell shell = getShell(uiInfo); 274 if (shell == null) { 275 createdShell = true; 276 shell = new Shell(); 277 } 278 ErrorDialog.openError(shell, title, message, status); 279 if (createdShell) { 280 shell.dispose(); 281 } 282 } 283 284 287 private IStatus reportAndInterpretStatus(IStatus status, IAdaptable uiInfo, 288 IUndoableOperation operation, int doing) { 289 if (AUTOMATED_MODE) { 292 if (status.getSeverity() == IStatus.WARNING) { 293 return Status.OK_STATUS; 294 } 295 return status; 296 } 297 298 if (status.getSeverity() == IStatus.CANCEL) { 301 return status; 302 } 303 304 boolean createdShell = false; 307 IStatus reportedStatus = status; 308 309 Shell shell = getShell(uiInfo); 310 if (shell == null) { 311 createdShell = true; 312 shell = new Shell(); 313 } 314 315 318 if (!(status.getSeverity() == IStatus.ERROR)) { 319 String warning, title; 320 switch (doing) { 321 case UNDOING: 322 warning = WorkbenchMessages.Operations_proceedWithNonOKUndoStatus; 323 if (status.getSeverity() == IStatus.INFO) { 324 title = WorkbenchMessages.Operations_undoInfo; 325 } else { 326 title = WorkbenchMessages.Operations_undoWarning; 327 } 328 break; 329 case REDOING: 330 warning = WorkbenchMessages.Operations_proceedWithNonOKRedoStatus; 331 if (status.getSeverity() == IStatus.INFO) { 332 title = WorkbenchMessages.Operations_redoInfo; 333 } else { 334 title = WorkbenchMessages.Operations_redoWarning; 335 } 336 break; 337 default: warning = WorkbenchMessages.Operations_proceedWithNonOKExecuteStatus; 339 if (status.getSeverity() == IStatus.INFO) { 340 title = WorkbenchMessages.Operations_executeInfo; 341 } else { 342 title = WorkbenchMessages.Operations_executeWarning; 343 } 344 break; 345 } 346 347 String message = NLS.bind(warning, new Object [] { status.getMessage(), operation.getLabel() }); 348 String [] buttons = new String [] { IDialogConstants.YES_LABEL, 349 IDialogConstants.NO_LABEL }; 350 MessageDialog dialog = new MessageDialog(shell, title, null, 351 message, MessageDialog.WARNING, buttons, 0); 352 int dialogAnswer = dialog.open(); 353 if (dialogAnswer == Window.OK) { 357 reportedStatus = Status.OK_STATUS; 358 } else { 359 reportedStatus = Status.CANCEL_STATUS; 360 } 361 } else { 362 String title, stopped; 363 switch (doing) { 364 case UNDOING: 365 title = WorkbenchMessages.Operations_undoProblem; 366 stopped = WorkbenchMessages.Operations_stoppedOnUndoErrorStatus; 367 break; 368 case REDOING: 369 title = WorkbenchMessages.Operations_redoProblem; 370 stopped = WorkbenchMessages.Operations_stoppedOnRedoErrorStatus; 371 break; 372 default: title = WorkbenchMessages.Operations_executeProblem; 374 stopped = WorkbenchMessages.Operations_stoppedOnExecuteErrorStatus; 375 376 break; 377 } 378 379 383 String message = NLS.bind(stopped, status.getMessage(), operation 384 .getLabel()); 385 386 MessageDialog dialog = new MessageDialog(shell, title, null, 387 message, MessageDialog.WARNING, 388 new String [] { IDialogConstants.OK_LABEL }, 0); dialog.open(); 390 } 391 392 if (createdShell) { 393 shell.dispose(); 394 } 395 396 return reportedStatus; 397 398 } 399 400 404 Shell getShell(IAdaptable uiInfo) { 405 if (uiInfo != null) { 406 Shell shell = (Shell) Util.getAdapter(uiInfo, Shell.class); 407 if (shell != null) { 408 return shell; 409 } 410 } 411 return null; 412 } 413 } 414 | Popular Tags |