Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian W. Damus2016-04-12 19:37:45 +0000
committerGerrit Code Review @ Eclipse.org2016-04-18 17:57:00 +0000
commit928852a40e704d8d53906edfe78f27f5e66c6c95 (patch)
tree867c1e4b425a81a5936d56b669035bcc8c475dd1 /plugins/infra/emf
parent89480a4d658a3ae3c5cc7b9be54bdbfc60eba49d (diff)
downloadorg.eclipse.papyrus-928852a40e704d8d53906edfe78f27f5e66c6c95.tar.gz
org.eclipse.papyrus-928852a40e704d8d53906edfe78f27f5e66c6c95.tar.xz
org.eclipse.papyrus-928852a40e704d8d53906edfe78f27f5e66c6c95.zip
Bug 491542: [All Diagrams] Undo doesn't work with RuntimeValuesAdvice
dialog for creation https://bugs.eclipse.org/bugs/show_bug.cgi?id=491542 Support re-entrant command execution in the CheckedOperationHistory, which is used by both the CheckedDiagramCommandStack (used by the diagrams) and the NestingNotifyingWorkspaceCommandStack (used by everything else), in much the same way as the latter supports nested execution. This ensures that, in the case where the execution of a top-level operation in the diagram triggers nested execution of operations in the EMF editing domain, which both delegate to the same CheckedOperationHistory, the nested operations are executed strictly within the context of the root operation, not separately as a sequence of operations in the history. Change-Id: I0967a62940d5c1030edf14d39994eeda2d3bdf9b
Diffstat (limited to 'plugins/infra/emf')
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.gmf/src/org/eclipse/papyrus/infra/emf/gmf/command/CheckedOperationHistory.java49
1 files changed, 47 insertions, 2 deletions
diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.gmf/src/org/eclipse/papyrus/infra/emf/gmf/command/CheckedOperationHistory.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.gmf/src/org/eclipse/papyrus/infra/emf/gmf/command/CheckedOperationHistory.java
index a9cc62ba62a..41dba170748 100644
--- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.gmf/src/org/eclipse/papyrus/infra/emf/gmf/command/CheckedOperationHistory.java
+++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.gmf/src/org/eclipse/papyrus/infra/emf/gmf/command/CheckedOperationHistory.java
@@ -9,7 +9,7 @@
* Contributors:
* Mathieu Velten (Atos) - Initial API and implementation
* Christian W. Damus (CEA) - bugs 357250, 323802
- * Christian W. Damus - bug 485220
+ * Christian W. Damus - bugs 485220, 491542
*
*****************************************************************************/
package org.eclipse.papyrus.infra.emf.gmf.command;
@@ -56,6 +56,9 @@ public class CheckedOperationHistory implements IOperationHistory {
protected IOperationHistory history;
+ // Whether the current thread is executing an operation
+ private ThreadLocal<IUndoableOperation> executing = new ThreadLocal<>();
+
private static class ApproverPriorityPair implements Comparable<ApproverPriorityPair> {
public IOperationApprover2 approver;
@@ -189,7 +192,49 @@ public class CheckedOperationHistory implements IOperationHistory {
// not approved. No notifications are sent, just return the status.
return status;
}
- return history.execute(operation, monitor, info);
+ return doExecute(operation, monitor, info);
+ }
+
+ protected IStatus doExecute(IUndoableOperation operation, IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
+ IStatus result;
+
+ final IUndoableOperation current = executing.get();
+ if (current == null) {
+ // Initial execution. Fine
+ executing.set(operation);
+ try {
+ result = history.execute(operation, monitor, info);
+ } finally {
+ executing.remove();
+ }
+ } else {
+ // Re-entrant operation execution is done free-floating
+ try {
+ // Don't notify start/done events because the reconciliation
+ // between resource-set changes and operation contexts
+ // performed by various listeners will lose information or
+ // it won't bubble up to the top operation where it belongs
+ result = operation.execute(monitor, info);
+
+ // On successful execution, propagate any contexts that may
+ // not already be on currently executing operation
+ if (result.isOK()) {
+ for (IUndoContext next : operation.getContexts()) {
+ if (!current.hasContext(next)) {
+ current.addContext(next);
+ }
+ }
+ }
+ } finally {
+ // Dispose the operation because we're not adding it
+ // to the history. Recorded EMF operations that know
+ // they are not the root operation will not dispose
+ // their change-descriptions, so they are safe
+ operation.dispose();
+ }
+ }
+
+ return result;
}
@Override

Back to the top