diff options
author | Christian W. Damus | 2014-03-20 17:26:03 +0000 |
---|---|---|
committer | Christian W. Damus | 2014-03-20 17:26:03 +0000 |
commit | c027351edc871fae98fc6d1e20d93c102ccbc4d6 (patch) | |
tree | 4b9e882cbd3e29ae40bf74f4c2baa45a43bab3fe /plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.commands | |
parent | cfc467ce62b6bfc0b74985fba1d699974ea18fde (diff) | |
download | org.eclipse.papyrus-c027351edc871fae98fc6d1e20d93c102ccbc4d6.tar.gz org.eclipse.papyrus-c027351edc871fae98fc6d1e20d93c102ccbc4d6.tar.xz org.eclipse.papyrus-c027351edc871fae98fc6d1e20d93c102ccbc4d6.zip |
430648: [Copy & Paste] Copying an element in Papyrus makes model dirty
https://bugs.eclipse.org/bugs/show_bug.cgi?id=430648
Handle non-dirtying commands (such as Copy to Clipboard) in the operation history when computing the editor's dirty state.
Diffstat (limited to 'plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.commands')
3 files changed, 114 insertions, 1 deletions
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.commands/META-INF/MANIFEST.MF b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.commands/META-INF/MANIFEST.MF index c11ef9925eb..648ffa8741c 100644 --- a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.commands/META-INF/MANIFEST.MF +++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.commands/META-INF/MANIFEST.MF @@ -15,6 +15,7 @@ Require-Bundle: org.eclipse.ui.workbench, org.eclipse.core.expressions;bundle-version="3.4.500",
org.eclipse.gmf.runtime.diagram.ui.resources.editor
Export-Package: org.eclipse.papyrus.commands,
+ org.eclipse.papyrus.commands.util,
org.eclipse.papyrus.commands.wrappers
Bundle-Vendor: %providerName
Bundle-ActivationPolicy: lazy
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.commands/src/org/eclipse/papyrus/commands/NotifyingWorkspaceCommandStack.java b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.commands/src/org/eclipse/papyrus/commands/NotifyingWorkspaceCommandStack.java index da6fbbfae6d..d480a176e4e 100644 --- a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.commands/src/org/eclipse/papyrus/commands/NotifyingWorkspaceCommandStack.java +++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.commands/src/org/eclipse/papyrus/commands/NotifyingWorkspaceCommandStack.java @@ -11,10 +11,14 @@ * Arthur Daussy (Atos) - 363826: [Model Explorer] Drag and drop and undo, incorrect behavior
* Christian W. Damus (CEA) - 404220: Add contexts for tracking objects changed by operations (CDO)
* Christian W. Damus (CEA) - bug 402525
+ * Christian W. Damus (CEA) - bug 430648
*
*****************************************************************************/
package org.eclipse.papyrus.commands;
+import static org.eclipse.papyrus.commands.util.OperationUtils.anyDirtying;
+import static org.eclipse.papyrus.commands.util.OperationUtils.anyDirtyingAfter;
+
import java.util.Collection;
import java.util.EventObject;
import java.util.HashMap;
@@ -624,7 +628,7 @@ implements IWorkspaceCommandStack { // return savedContext != null;
return super.isSaveNeeded();
}
- return savedContext != null ? !nextUndoableOperation.hasContext(getSavedContext()) : true;
+ return savedContext != null ? !nextUndoableOperation.hasContext(getSavedContext()) && anyDirtyingAfter(history.getUndoHistory(getDefaultUndoContext()), history.getUndoOperation(savedContext)) : anyDirtying(history.getUndoHistory(getDefaultUndoContext()));
}
@Override
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.commands/src/org/eclipse/papyrus/commands/util/OperationUtils.java b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.commands/src/org/eclipse/papyrus/commands/util/OperationUtils.java new file mode 100644 index 00000000000..8ed4352936b --- /dev/null +++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.commands/src/org/eclipse/papyrus/commands/util/OperationUtils.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2014 CEA and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus (CEA) - Initial API and implementation + * + */ +package org.eclipse.papyrus.commands.util; + +import org.eclipse.core.commands.operations.IUndoableOperation; +import org.eclipse.emf.common.command.AbstractCommand; +import org.eclipse.emf.common.command.Command; +import org.eclipse.emf.workspace.EMFCommandOperation; +import org.eclipse.papyrus.commands.wrappers.EMFtoGMFCommandWrapper; + + +/** + * Utilities for working with undoable operations. + */ +public class OperationUtils { + + /** + * Not instantiable by clients. + */ + private OperationUtils() { + super(); + } + + public static boolean anyDirtying(IUndoableOperation[] undoHistory) { + boolean result = false; + + if((undoHistory != null) && (undoHistory.length > 0)) { + for(int i = 0; i < undoHistory.length; i++) { + if(!isNonDirtying(undoHistory[i])) { + result = true; + break; + } + } + } + + return result; + } + + /** + * Queries whether an operation is non-dirtying. The only known non-dirtying operations, currently, are those that wrap a + * {@link AbstractCommand.NonDirtying}. + * + * @param operation + * an undoable operation + * + * @return whether it is a non-dirtying operation + */ + public static boolean isNonDirtying(IUndoableOperation operation) { + Command command = unwrap(operation); + return command instanceof AbstractCommand.NonDirtying; + } + + /** + * Obtains the singular EMF {@link Command} that is wrapped by an {@code operation}, if it is a command wrapper of some kind. + * + * @param operation + * an operation + * + * @return the {@link Command} that it wraps, or {@code null} if it does not wrap a singular EMF command + */ + public static Command unwrap(IUndoableOperation operation) { + Command result = null; + + if(operation instanceof EMFCommandOperation) { + result = ((EMFCommandOperation)operation).getCommand(); + } else if(operation instanceof EMFtoGMFCommandWrapper) { + result = ((EMFtoGMFCommandWrapper)operation).getEMFCommand(); + } + + return result; + } + + public static boolean anyDirtyingAfter(IUndoableOperation[] undoHistory, IUndoableOperation savepoint) { + boolean result = false; + + if(savepoint == null) { + result = anyDirtying(undoHistory); + } else if((undoHistory != null) && (undoHistory.length > 0)) { + int i = 0; + + for(i = 0; i < undoHistory.length; i++) { + if(undoHistory[i] == savepoint) { + i++; // Advance over the save point to start testing + break; + } + } + + for(; i < undoHistory.length; i++) { + if(!isNonDirtying(undoHistory[i])) { + result = true; + break; + } + } + } + + return result; + } +} |