1 11 package org.eclipse.core.commands.operations; 12 13 import java.util.ArrayList ; 14 import java.util.List ; 15 16 import org.eclipse.core.commands.ExecutionException; 17 import org.eclipse.core.runtime.IAdaptable; 18 import org.eclipse.core.runtime.IProgressMonitor; 19 import org.eclipse.core.runtime.IStatus; 20 import org.eclipse.core.runtime.OperationCanceledException; 21 import org.eclipse.core.runtime.Status; 22 23 38 public final class TriggeredOperations extends AbstractOperation implements 39 ICompositeOperation, IAdvancedUndoableOperation, 40 IContextReplacingOperation { 41 42 private IUndoableOperation triggeringOperation; 43 44 private IOperationHistory history; 45 46 private List children = new ArrayList (); 47 48 58 public TriggeredOperations(IUndoableOperation operation, 59 IOperationHistory history) { 60 super(operation.getLabel()); 61 triggeringOperation = operation; 62 recomputeContexts(); 63 this.history = history; 64 } 65 66 71 public void add(IUndoableOperation operation) { 72 children.add(operation); 73 recomputeContexts(); 74 } 75 76 81 public void remove(IUndoableOperation operation) { 82 if (operation == triggeringOperation) { 83 triggeringOperation = null; 86 List childrenToRestore = new ArrayList (children); 91 children = new ArrayList (0); 92 recomputeContexts(); 93 operation.dispose(); 94 history.replaceOperation(this, 96 (IUndoableOperation[]) childrenToRestore 97 .toArray(new IUndoableOperation[childrenToRestore 98 .size()])); 99 } else { 100 children.remove(operation); 101 operation.dispose(); 102 recomputeContexts(); 103 } 104 } 105 106 119 public void removeContext(IUndoContext context) { 120 121 boolean recompute = false; 122 if (triggeringOperation != null 125 && triggeringOperation.hasContext(context)) { 126 if (triggeringOperation.getContexts().length == 1) { 127 remove(triggeringOperation); 128 return; 129 } 130 triggeringOperation.removeContext(context); 131 recompute = true; 132 } 133 ArrayList toBeRemoved = new ArrayList (); 135 for (int i = 0; i < children.size(); i++) { 136 IUndoableOperation child = (IUndoableOperation) children.get(i); 137 if (child.hasContext(context)) { 138 if (child.getContexts().length == 1) { 139 toBeRemoved.add(child); 140 } else { 141 child.removeContext(context); 142 } 143 recompute = true; 144 } 145 } 146 for (int i = 0; i < toBeRemoved.size(); i++) { 147 remove((IUndoableOperation) toBeRemoved.get(i)); 148 } 149 if (recompute) { 150 recomputeContexts(); 151 } 152 } 153 154 160 public IStatus execute(IProgressMonitor monitor, IAdaptable info) 161 throws ExecutionException { 162 if (triggeringOperation != null) { 163 history.openOperation(this, IOperationHistory.EXECUTE); 164 try { 165 IStatus status = triggeringOperation.execute(monitor, info); 166 history.closeOperation(status.isOK(), false, 167 IOperationHistory.EXECUTE); 168 return status; 169 } catch (ExecutionException e) { 170 history.closeOperation(false, false, IOperationHistory.EXECUTE); 171 throw e; 172 } catch (RuntimeException e) { 173 history.closeOperation(false, false, IOperationHistory.EXECUTE); 174 throw e; 175 } 176 177 } 178 return IOperationHistory.OPERATION_INVALID_STATUS; 179 } 180 181 187 public IStatus redo(IProgressMonitor monitor, IAdaptable info) 188 throws ExecutionException { 189 if (triggeringOperation != null) { 190 history.openOperation(this, IOperationHistory.REDO); 191 List childrenToRestore = new ArrayList (children); 192 try { 193 removeAllChildren(); 194 IStatus status = triggeringOperation.redo(monitor, info); 195 if (!status.isOK()) { 196 children = childrenToRestore; 197 } 198 history.closeOperation(status.isOK(), false, 199 IOperationHistory.REDO); 200 return status; 201 } catch (ExecutionException e) { 202 children = childrenToRestore; 203 history.closeOperation(false, false, IOperationHistory.REDO); 204 throw e; 205 } catch (RuntimeException e) { 206 children = childrenToRestore; 207 history.closeOperation(false, false, IOperationHistory.REDO); 208 throw e; 209 } 210 } 211 return IOperationHistory.OPERATION_INVALID_STATUS; 212 } 213 214 220 public IStatus undo(IProgressMonitor monitor, IAdaptable info) 221 throws ExecutionException { 222 if (triggeringOperation != null) { 223 history.openOperation(this, IOperationHistory.UNDO); 224 List childrenToRestore = new ArrayList (children); 225 try { 226 removeAllChildren(); 227 IStatus status = triggeringOperation.undo(monitor, info); 228 if (!status.isOK()) { 229 children = childrenToRestore; 230 } 231 history.closeOperation(status.isOK(), false, 232 IOperationHistory.UNDO); 233 return status; 234 } catch (ExecutionException e) { 235 children = childrenToRestore; 236 history.closeOperation(false, false, IOperationHistory.UNDO); 237 throw e; 238 } catch (RuntimeException e) { 239 children = childrenToRestore; 240 history.closeOperation(false, false, IOperationHistory.UNDO); 241 throw e; 242 } 243 } 244 return IOperationHistory.OPERATION_INVALID_STATUS; 245 } 246 247 252 public boolean canUndo() { 253 if (triggeringOperation != null) { 254 return triggeringOperation.canUndo(); 255 } 256 return false; 257 } 258 259 264 public boolean canExecute() { 265 if (triggeringOperation != null) { 266 return triggeringOperation.canExecute(); 267 } 268 return false; 269 } 270 271 276 public boolean canRedo() { 277 if (triggeringOperation != null) { 278 return triggeringOperation.canRedo(); 279 } 280 return false; 281 } 282 283 286 public void dispose() { 287 for (int i = 0; i < children.size(); i++) { 288 ((IUndoableOperation) (children.get(i))).dispose(); 289 } 290 if (triggeringOperation != null) { 291 triggeringOperation.dispose(); 292 } 293 } 294 295 298 private void recomputeContexts() { 299 ArrayList allContexts = new ArrayList (); 300 if (triggeringOperation != null) { 301 IUndoContext[] contexts = triggeringOperation.getContexts(); 302 for (int i = 0; i < contexts.length; i++) { 303 allContexts.add(contexts[i]); 304 } 305 } 306 for (int i = 0; i < children.size(); i++) { 307 IUndoContext[] contexts = ((IUndoableOperation) children.get(i)) 308 .getContexts(); 309 for (int j = 0; j < contexts.length; j++) { 310 if (!allContexts.contains(contexts[j])) { 311 allContexts.add(contexts[j]); 312 } 313 } 314 } 315 contexts = allContexts; 316 317 } 318 319 322 private void removeAllChildren() { 323 IUndoableOperation[] nonTriggers = (IUndoableOperation[]) children 324 .toArray(new IUndoableOperation[children.size()]); 325 for (int i = 0; i < nonTriggers.length; i++) { 326 children.remove(nonTriggers[i]); 327 nonTriggers[i].dispose(); 328 } 329 } 330 331 337 public IUndoableOperation getTriggeringOperation() { 338 return triggeringOperation; 339 } 340 341 346 public Object [] getAffectedObjects() { 347 if (triggeringOperation instanceof IAdvancedUndoableOperation) { 348 return ((IAdvancedUndoableOperation) triggeringOperation) 349 .getAffectedObjects(); 350 } 351 return null; 352 } 353 354 359 public void aboutToNotify(OperationHistoryEvent event) { 360 if (triggeringOperation instanceof IAdvancedUndoableOperation) { 361 ((IAdvancedUndoableOperation) triggeringOperation) 362 .aboutToNotify(event); 363 } 364 } 365 366 371 public IStatus computeUndoableStatus(IProgressMonitor monitor) 372 throws ExecutionException { 373 if (triggeringOperation instanceof IAdvancedUndoableOperation) { 374 try { 375 return ((IAdvancedUndoableOperation) triggeringOperation) 376 .computeUndoableStatus(monitor); 377 } catch (OperationCanceledException e) { 378 return Status.CANCEL_STATUS; 379 } 380 } 381 return Status.OK_STATUS; 382 383 } 384 385 390 public IStatus computeRedoableStatus(IProgressMonitor monitor) 391 throws ExecutionException { 392 if (triggeringOperation instanceof IAdvancedUndoableOperation) { 393 try { 394 return ((IAdvancedUndoableOperation) triggeringOperation) 395 .computeRedoableStatus(monitor); 396 } catch (OperationCanceledException e) { 397 return Status.CANCEL_STATUS; 398 } 399 } 400 return Status.OK_STATUS; 401 402 } 403 404 419 public void replaceContext(IUndoContext original, IUndoContext replacement) { 420 421 if (triggeringOperation != null 423 && triggeringOperation.hasContext(original)) { 424 if (triggeringOperation instanceof IContextReplacingOperation) { 425 ((IContextReplacingOperation) triggeringOperation) 426 .replaceContext(original, replacement); 427 } else { 428 triggeringOperation.removeContext(original); 429 triggeringOperation.addContext(replacement); 430 } 431 } 432 for (int i = 0; i < children.size(); i++) { 434 IUndoableOperation child = (IUndoableOperation) children.get(i); 435 if (child.hasContext(original)) { 436 if (child instanceof IContextReplacingOperation) { 437 ((IContextReplacingOperation) child).replaceContext( 438 original, replacement); 439 } else { 440 child.removeContext(original); 441 child.addContext(replacement); 442 } 443 } 444 } 445 recomputeContexts(); 446 } 447 448 458 public void addContext(IUndoContext context) { 459 if (triggeringOperation != null) { 460 triggeringOperation.addContext(context); 461 recomputeContexts(); 462 } 463 } 464 465 } 466 | Popular Tags |