Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Lorenzo2022-06-08 07:43:59 +0000
committerPatrick Tessier2022-06-16 14:30:16 +0000
commit1524f6fc1c517425dd33930a92ef067547600aa3 (patch)
treef3d215090d453838b06f682f1c7edae2245022d2
parentff8622656df9b07dddcd168c72df9c2385b44774 (diff)
downloadorg.eclipse.papyrus-1524f6fc1c517425dd33930a92ef067547600aa3.tar.gz
org.eclipse.papyrus-1524f6fc1c517425dd33930a92ef067547600aa3.tar.xz
org.eclipse.papyrus-1524f6fc1c517425dd33930a92ef067547600aa3.zip
Bug 580115: [Editor][XText] The Undo/Redo doesn't work for XText editor opened as nested Papyrus editor
- wrap the text editor Undo/Redo into the Papyrus CommandStack - add api analysis nature and builder into .project - increase feature version Change-Id: I72f1d05988adef822789e2f22964fc902526c698 Signed-off-by: Vincent Lorenzo <vincent.lorenzo@cea.fr>
-rwxr-xr-xexamples/uml/org.eclipse.papyrus.examples.uml.textedit.property.xtext.architecture/.project6
-rwxr-xr-xfeatures/papyrus-main-features/org.eclipse.papyrus.infra.textedit.feature/feature.xml2
-rwxr-xr-xfeatures/papyrus-main-features/org.eclipse.papyrus.infra.textedit.feature/pom.xml2
-rwxr-xr-xplugins/infra/textedit/org.eclipse.papyrus.infra.textedit.edit/.project6
-rwxr-xr-xplugins/infra/textedit/org.eclipse.papyrus.infra.textedit.modelexplorer/.project6
-rwxr-xr-xplugins/infra/textedit/org.eclipse.papyrus.infra.textedit.properties/.project6
-rwxr-xr-xplugins/infra/textedit/org.eclipse.papyrus.infra.textedit.representation.architecture/.project6
-rwxr-xr-xplugins/infra/textedit/org.eclipse.papyrus.infra.textedit.representation.edit/.project6
-rwxr-xr-xplugins/infra/textedit/org.eclipse.papyrus.infra.textedit.representation/.project6
-rwxr-xr-xplugins/infra/textedit/org.eclipse.papyrus.infra.textedit.types/.project6
-rwxr-xr-xplugins/infra/textedit/org.eclipse.papyrus.infra.textedit.ui/.project6
-rwxr-xr-xplugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/.project6
-rwxr-xr-xplugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/META-INF/MANIFEST.MF2
-rwxr-xr-xplugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/api/org/eclipse/papyrus/infra/textedit/xtext/custom/PapyrusXTextDocumentProvider.java35
-rwxr-xr-xplugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/api/org/eclipse/papyrus/infra/textedit/xtext/nested/editor/PapyrusXTextEditor.java154
-rwxr-xr-xplugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/pom.xml2
-rwxr-xr-xplugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/src/org/eclipse/papyrus/infra/textedit/xtext/internal/command/TextUndoRedoCommandWrapper.java130
-rwxr-xr-xplugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/src/org/eclipse/papyrus/infra/textedit/xtext/internal/listeners/UndoableTextChangeListener.java135
-rwxr-xr-xplugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/usecase.md15
-rwxr-xr-xplugins/infra/textedit/org.eclipse.papyrus.infra.textedit/.project6
-rw-r--r--releng/toolsmiths/site/category.xml4
21 files changed, 494 insertions, 53 deletions
diff --git a/examples/uml/org.eclipse.papyrus.examples.uml.textedit.property.xtext.architecture/.project b/examples/uml/org.eclipse.papyrus.examples.uml.textedit.property.xtext.architecture/.project
index 9342ffac1e9..ffd658e3c06 100755
--- a/examples/uml/org.eclipse.papyrus.examples.uml.textedit.property.xtext.architecture/.project
+++ b/examples/uml/org.eclipse.papyrus.examples.uml.textedit.property.xtext.architecture/.project
@@ -20,9 +20,15 @@
<arguments>
</arguments>
</buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
</natures>
</projectDescription>
diff --git a/features/papyrus-main-features/org.eclipse.papyrus.infra.textedit.feature/feature.xml b/features/papyrus-main-features/org.eclipse.papyrus.infra.textedit.feature/feature.xml
index 841fa29f1e7..e06c53c51c3 100755
--- a/features/papyrus-main-features/org.eclipse.papyrus.infra.textedit.feature/feature.xml
+++ b/features/papyrus-main-features/org.eclipse.papyrus.infra.textedit.feature/feature.xml
@@ -2,7 +2,7 @@
<feature
id="org.eclipse.papyrus.infra.textedit.feature"
label="%featureName"
- version="1.0.0.qualifier"
+ version="1.1.0.qualifier"
provider-name="%providerName"
license-feature="org.eclipse.license"
license-feature-version="2.0.2">
diff --git a/features/papyrus-main-features/org.eclipse.papyrus.infra.textedit.feature/pom.xml b/features/papyrus-main-features/org.eclipse.papyrus.infra.textedit.feature/pom.xml
index e279af9aea0..0c3e33a71b9 100755
--- a/features/papyrus-main-features/org.eclipse.papyrus.infra.textedit.feature/pom.xml
+++ b/features/papyrus-main-features/org.eclipse.papyrus.infra.textedit.feature/pom.xml
@@ -9,6 +9,6 @@
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>org.eclipse.papyrus.infra.textedit.feature</artifactId>
- <version>1.0.0-SNAPSHOT</version>
+ <version>1.1.0-SNAPSHOT</version>
<packaging>eclipse-feature</packaging>
</project>
diff --git a/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.edit/.project b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.edit/.project
index fedc1c56b8b..2667d7019b4 100755
--- a/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.edit/.project
+++ b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.edit/.project
@@ -20,9 +20,15 @@
<arguments>
</arguments>
</buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
</natures>
</projectDescription>
diff --git a/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.modelexplorer/.project b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.modelexplorer/.project
index fbb6ed37938..f208e0971e1 100755
--- a/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.modelexplorer/.project
+++ b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.modelexplorer/.project
@@ -20,9 +20,15 @@
<arguments>
</arguments>
</buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
</natures>
</projectDescription>
diff --git a/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.properties/.project b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.properties/.project
index 89484cab4dc..c7d5debb6fd 100755
--- a/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.properties/.project
+++ b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.properties/.project
@@ -20,9 +20,15 @@
<arguments>
</arguments>
</buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
</natures>
</projectDescription>
diff --git a/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.representation.architecture/.project b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.representation.architecture/.project
index 9405bab1a09..8689400abb7 100755
--- a/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.representation.architecture/.project
+++ b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.representation.architecture/.project
@@ -20,9 +20,15 @@
<arguments>
</arguments>
</buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
</natures>
</projectDescription>
diff --git a/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.representation.edit/.project b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.representation.edit/.project
index ea21b3a5147..f10c3607e79 100755
--- a/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.representation.edit/.project
+++ b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.representation.edit/.project
@@ -20,9 +20,15 @@
<arguments>
</arguments>
</buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
</natures>
</projectDescription>
diff --git a/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.representation/.project b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.representation/.project
index 04a0d4a1d50..fc648c70308 100755
--- a/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.representation/.project
+++ b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.representation/.project
@@ -20,9 +20,15 @@
<arguments>
</arguments>
</buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
</natures>
</projectDescription>
diff --git a/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.types/.project b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.types/.project
index bef472e20db..9d6aa71e306 100755
--- a/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.types/.project
+++ b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.types/.project
@@ -20,9 +20,15 @@
<arguments>
</arguments>
</buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
</natures>
</projectDescription>
diff --git a/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.ui/.project b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.ui/.project
index 367ae42f8c5..9c9ff0b79ce 100755
--- a/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.ui/.project
+++ b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.ui/.project
@@ -20,9 +20,15 @@
<arguments>
</arguments>
</buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
</natures>
</projectDescription>
diff --git a/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/.project b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/.project
index 62eae2fe130..eaef2ca8fad 100755
--- a/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/.project
+++ b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/.project
@@ -20,9 +20,15 @@
<arguments>
</arguments>
</buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
</natures>
</projectDescription>
diff --git a/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/META-INF/MANIFEST.MF b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/META-INF/MANIFEST.MF
index 1665b4aa5f4..e8c19ec5089 100755
--- a/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/META-INF/MANIFEST.MF
+++ b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %Bundle-Name
Bundle-SymbolicName: org.eclipse.papyrus.infra.textedit.xtext;singleton:=true
-Bundle-Version: 1.0.100.qualifier
+Bundle-Version: 1.1.0.qualifier
Bundle-Activator: org.eclipse.papyrus.infra.textedit.xtext.Activator
Bundle-Vendor: %Bundle-Vendor
Require-Bundle: org.eclipse.ui;bundle-version="[3.119.0,4.0.0)",
diff --git a/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/api/org/eclipse/papyrus/infra/textedit/xtext/custom/PapyrusXTextDocumentProvider.java b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/api/org/eclipse/papyrus/infra/textedit/xtext/custom/PapyrusXTextDocumentProvider.java
index 4648efd3fa3..379598c2fbb 100755
--- a/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/api/org/eclipse/papyrus/infra/textedit/xtext/custom/PapyrusXTextDocumentProvider.java
+++ b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/api/org/eclipse/papyrus/infra/textedit/xtext/custom/PapyrusXTextDocumentProvider.java
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2021 CEA LIST and others.
+ * Copyright (c) 2021-2022 CEA LIST and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -10,7 +10,7 @@
*
* Contributors:
* Vincent Lorenzo (CEA LIST) <vincent.lorenzo@cea.fr> - Initial API and implementation
- *
+ * Vincent Lorenzo (CEA LIST) <vincent.lorenzo@cea.fr> - Bug 580115
*****************************************************************************/
package org.eclipse.papyrus.infra.textedit.xtext.custom;
@@ -30,6 +30,7 @@ import org.eclipse.papyrus.infra.emf.utils.ServiceUtilsForEObject;
import org.eclipse.papyrus.infra.gmfdiag.extensionpoints.editors.configuration.ICustomDirectEditorConfiguration;
import org.eclipse.papyrus.infra.textedit.xtext.Activator;
import org.eclipse.papyrus.infra.textedit.xtext.nested.editor.NestedXTextEditorInput;
+import org.eclipse.xtext.ui.editor.model.IXtextDocument;
import org.eclipse.xtext.ui.editor.model.XtextDocumentProvider;
/**
@@ -38,6 +39,18 @@ import org.eclipse.xtext.ui.editor.model.XtextDocumentProvider;
public class PapyrusXTextDocumentProvider extends XtextDocumentProvider {
/**
+ * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#getDocument(java.lang.Object)
+ *
+ * @param element
+ * @return
+ * @since 1.1
+ */
+ @Override
+ public IXtextDocument getDocument(Object element) {
+ return (IXtextDocument) super.getDocument(element);
+ }
+
+ /**
* @see org.eclipse.xtext.ui.editor.model.XtextDocumentProvider#doSaveDocument(org.eclipse.core.runtime.IProgressMonitor, java.lang.Object, org.eclipse.jface.text.IDocument, boolean)
*
* @param monitor
@@ -72,13 +85,29 @@ public class PapyrusXTextDocumentProvider extends XtextDocumentProvider {
if (newText.equals(initialText)) {
return;
}
-
ICommand cmd = getParseCommand(input.getDirectEditorConfiguration(), semanticElement, newText);
final TransactionalEditingDomain domain = getEditingDomain(semanticElement);
domain.getCommandStack().execute(new GMFtoEMFCommandWrapper(cmd));
}
/**
+ * This method is used to update the editor content when the value has been edited outside of the current editor
+ *
+ * @param editorInput
+ * the editor input
+ * @param document
+ * the edited document
+ * @since 1.1
+ */
+ public void updateTextEditorContent(final NestedXTextEditorInput editorInput, final IDocument document) {
+ final String oldText = document.get();
+ final String newText = editorInput.getTextToEdit();
+ if (!oldText.equals(newText)) {
+ document.set(newText);
+ }
+ }
+
+ /**
*
* @param configuration
* the editor configuration
diff --git a/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/api/org/eclipse/papyrus/infra/textedit/xtext/nested/editor/PapyrusXTextEditor.java b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/api/org/eclipse/papyrus/infra/textedit/xtext/nested/editor/PapyrusXTextEditor.java
index 0414b874411..6d6c13d441c 100755
--- a/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/api/org/eclipse/papyrus/infra/textedit/xtext/nested/editor/PapyrusXTextEditor.java
+++ b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/api/org/eclipse/papyrus/infra/textedit/xtext/nested/editor/PapyrusXTextEditor.java
@@ -10,7 +10,7 @@
*
* Contributors:
* Vincent Lorenzo (CEA LIST) <vincent.lorenzo@cea.fr> - Initial API and implementation
- * Vincent Lorenzo (CEA LIST) <vincent.lorenzo@cea.fr> - Bug 578648, 579033
+ * Vincent Lorenzo (CEA LIST) <vincent.lorenzo@cea.fr> - Bug 578648, 579033, 580115
*****************************************************************************/
package org.eclipse.papyrus.infra.textedit.xtext.nested.editor;
@@ -18,9 +18,13 @@ package org.eclipse.papyrus.infra.textedit.xtext.nested.editor;
import java.io.IOException;
import java.util.EventObject;
+import org.eclipse.core.commands.operations.IOperationHistory;
+import org.eclipse.core.commands.operations.OperationHistoryFactory;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.CommandStack;
import org.eclipse.emf.common.command.CommandStackListener;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
@@ -32,12 +36,16 @@ import org.eclipse.papyrus.infra.core.sasheditor.editor.ISashWindowsContainer;
import org.eclipse.papyrus.infra.core.services.ServiceException;
import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
import org.eclipse.papyrus.infra.core.utils.ServiceUtils;
+import org.eclipse.papyrus.infra.emf.gmf.command.NotifyingWorkspaceCommandStack;
import org.eclipse.papyrus.infra.gmfdiag.extensionpoints.editors.configuration.ICustomDirectEditorConfiguration;
import org.eclipse.papyrus.infra.textedit.textdocument.TextDocument;
import org.eclipse.papyrus.infra.textedit.textdocument.TextDocumentPackage;
import org.eclipse.papyrus.infra.textedit.xtext.Activator;
+import org.eclipse.papyrus.infra.textedit.xtext.custom.PapyrusXTextDocumentProvider;
+import org.eclipse.papyrus.infra.textedit.xtext.internal.command.TextUndoRedoCommandWrapper;
import org.eclipse.papyrus.infra.textedit.xtext.internal.listeners.SaveTextOnFocusLostPageLifeCycleEventsListener;
import org.eclipse.papyrus.infra.textedit.xtext.internal.listeners.SaveTextOnFocusLostPartListener;
+import org.eclipse.papyrus.infra.textedit.xtext.internal.listeners.UndoableTextChangeListener;
import org.eclipse.papyrus.infra.ui.lifecycleevents.ISaveAndDirtyService;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
@@ -45,6 +53,7 @@ import org.eclipse.ui.IPartListener2;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.xtext.ui.editor.XtextEditor;
+import org.eclipse.xtext.ui.editor.model.IXtextDocument;
/**
* This Customization of the {@link XtextEditor} allows us to open an XtextEditor in the Papyrus sash editor
@@ -54,27 +63,12 @@ public class PapyrusXTextEditor extends XtextEditor {
/**
* the listener on the command stack
*/
- private final CommandStackListener listener = new CommandStackListener() {
-
- @Override
- public void commandStackChanged(EventObject event) {
- resetInput();
- }
- };
+ private CommandStackListener commandStackListener;
/**
* a listener on the semanticContext of the {@link TextDocument}
*/
- private final Adapter textDocumentListener = new AdapterImpl() {
-
- @Override
- public void notifyChanged(org.eclipse.emf.common.notify.Notification msg) {
- if (TextDocumentPackage.eINSTANCE.getTextDocument_SemanticContext().equals(msg.getFeature())) {
- resetInput();
- }
- };
-
- };
+ private Adapter textDocumentListener;
/**
* the part listener. This listener is used to be able to save the editor contents on the focus lost
@@ -131,6 +125,11 @@ public class PapyrusXTextEditor extends XtextEditor {
private SaveTextOnFocusLostPageLifeCycleEventsListener sashWindowsContainerListener = null;
/**
+ * listener on the IOperationHistory
+ */
+ private UndoableTextChangeListener historyListener;
+
+ /**
*
* Constructor.
*
@@ -222,27 +221,16 @@ public class PapyrusXTextEditor extends XtextEditor {
/**
* This method is called to re-set the editor input
*/
- private void resetInput() {
- int currentCaretOffset = -1;
- if (getSourceViewer() != null
- && getSourceViewer().getTextWidget() != null
- && !getSourceViewer().getTextWidget().isDisposed()) {
- currentCaretOffset = getSourceViewer().getTextWidget().getCaretOffset();
- }
- try {
- // TODO maybe better to call setInput directly!
- // setInput(null);
- doSetInput(null);
- } catch (CoreException e) {
- Activator.log.error(e);
- }
- if (currentCaretOffset != -1 && getSourceViewer() != null
- && getSourceViewer().getTextWidget() != null
- && !getSourceViewer().getTextWidget().isDisposed()) {
- getSourceViewer().getTextWidget().setCaretOffset(currentCaretOffset);
- }
- }
+ private void updateEditorContent() {
+ final PapyrusXTextDocumentProvider provider = getDocumentProvider();
+ final IXtextDocument document = provider.getDocument(this.input);
+
+ // we need to disable the listener in order to not add a new command into the commandstack!
+ this.historyListener.disable();
+ provider.updateTextEditorContent(this.input, document);
+ this.historyListener.enable();
+ }
/**
* This method allows to save the typed text in the edited model
@@ -255,13 +243,21 @@ public class PapyrusXTextEditor extends XtextEditor {
* this method registers the listeners
*/
protected void registerListeners() {
- this.domain.getCommandStack().addCommandStackListener(this.listener);
- this.textDocument.eAdapters().add(this.textDocumentListener);
+ this.commandStackListener = createCommandStackListener();
+ if (this.commandStackListener != null) {
+ this.domain.getCommandStack().addCommandStackListener(this.commandStackListener);
+ }
+ this.textDocumentListener = createTextDocumentListener();
+ if (this.textDocumentListener != null) {
+ this.textDocument.eAdapters().add(this.textDocumentListener);
+ }
if (this.saveAndDirtyService != null) {
this.saveAndDirtyService.registerIsaveablePart(this);
}
final IWorkbenchPage page = getEditorSite().getPage();
page.addPartListener(this.partListener);
+ this.historyListener = new UndoableTextChangeListener(this.domain, getDocumentProvider().getDocument(this.input));
+ getOperationHistory().addOperationHistoryListener(this.historyListener);
}
@@ -270,10 +266,15 @@ public class PapyrusXTextEditor extends XtextEditor {
*/
protected void unregisterListeners() {
unregisterSashWindowsContainerListener();
+ getOperationHistory().removeOperationHistoryListener(this.historyListener);
final IWorkbenchPage page = getEditorSite().getPage();
page.removePartListener(this.partListener);
- this.domain.getCommandStack().removeCommandStackListener(this.listener);
- this.textDocument.eAdapters().remove(this.textDocumentListener);
+ if (this.commandStackListener != null) {
+ this.domain.getCommandStack().removeCommandStackListener(this.commandStackListener);
+ }
+ if (this.textDocumentListener != null) {
+ this.textDocument.eAdapters().remove(this.textDocumentListener);
+ }
if (this.saveAndDirtyService != null) {
this.saveAndDirtyService.removeIsaveablePart(this);
}
@@ -325,6 +326,9 @@ public class PapyrusXTextEditor extends XtextEditor {
if (this.textDocument != null
&& this.textDocument.eResource() != null) {// resource can be null when we are destroying the TextDocument
super.doSetInput(this.input);
+ if (this.historyListener != null) {
+ this.historyListener.updateXTextDocument(getDocumentProvider().getDocument(this.input));
+ }
}
}
@@ -377,6 +381,70 @@ public class PapyrusXTextEditor extends XtextEditor {
*/
@Override
protected void createUndoRedoActions() {
- // do nothing to preserve papyrus Undo/Redo feature/keybinding
+ // do nothing to preserve Papyrus Undo/Redo feature/keybinding
+ }
+
+ /**
+ *
+ * @return
+ * the {@link IOperationHistory}
+ */
+ private IOperationHistory getOperationHistory() {
+ return OperationHistoryFactory.getOperationHistory();
+ }
+
+ /**
+ * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#getDocumentProvider()
+ *
+ * @return
+ * @since 1.1
+ */
+ @Override
+ public PapyrusXTextDocumentProvider getDocumentProvider() {
+ return (PapyrusXTextDocumentProvider) super.getDocumentProvider();
+ }
+
+ /**
+ *
+ * @return
+ * the listener for the {@link CommandStack}, can be <code>null</code>
+ * @since 1.1
+ */
+ protected CommandStackListener createCommandStackListener() {
+ return new CommandStackListener() {
+
+ @Override
+ public void commandStackChanged(EventObject event) {
+ final Object source = event.getSource();
+ if (source instanceof NotifyingWorkspaceCommandStack) {
+ NotifyingWorkspaceCommandStack stack = (NotifyingWorkspaceCommandStack) source;
+ final Command cmd = stack.getMostRecentCommand();
+
+ if (cmd instanceof TextUndoRedoCommandWrapper) {
+ // there is nothing to do in this case, because this notification has been sent by ourself!
+ return;
+ }
+ }
+ updateEditorContent();
+ }
+ };
+ }
+
+ /**
+ *
+ * @return
+ * the listener for {@link TextDocument}, can be <code>null</code>
+ * @since 1.1
+ */
+ protected Adapter createTextDocumentListener() {
+ return new AdapterImpl() {
+
+ @Override
+ public void notifyChanged(org.eclipse.emf.common.notify.Notification msg) {
+ if (TextDocumentPackage.eINSTANCE.getTextDocument_SemanticContext().equals(msg.getFeature())) {
+ updateEditorContent();
+ }
+ };
+ };
}
}
diff --git a/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/pom.xml b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/pom.xml
index be0b2b2a1d9..49e3b773d1b 100755
--- a/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/pom.xml
+++ b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/pom.xml
@@ -9,6 +9,6 @@
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>org.eclipse.papyrus.infra.textedit.xtext</artifactId>
- <version>1.0.100-SNAPSHOT</version>
+ <version>1.1.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project> \ No newline at end of file
diff --git a/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/src/org/eclipse/papyrus/infra/textedit/xtext/internal/command/TextUndoRedoCommandWrapper.java b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/src/org/eclipse/papyrus/infra/textedit/xtext/internal/command/TextUndoRedoCommandWrapper.java
new file mode 100755
index 00000000000..ba1a4d995c2
--- /dev/null
+++ b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/src/org/eclipse/papyrus/infra/textedit/xtext/internal/command/TextUndoRedoCommandWrapper.java
@@ -0,0 +1,130 @@
+/*****************************************************************************
+ * Copyright (c) 2022 CEA LIST and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Vincent Lorenzo (CEA LIST) <vincent.lorenzo@cea.fr> - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.textedit.xtext.internal.command;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.operations.IOperationHistory;
+import org.eclipse.core.commands.operations.IUndoableOperation;
+import org.eclipse.core.commands.operations.OperationHistoryFactory;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.emf.common.command.AbstractCommand;
+import org.eclipse.papyrus.infra.textedit.xtext.Activator;
+import org.eclipse.ui.editors.text.TextEditor;
+
+/**
+ * This command is used to wrap an already executed {@link IUndoableOperation} used in the context of a {@link TextEditor}
+ */
+public class TextUndoRedoCommandWrapper extends AbstractCommand {
+
+ /**
+ * the wrapped operation
+ */
+ private IUndoableOperation operation;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param operation
+ * the wrapped operation
+ */
+ public TextUndoRedoCommandWrapper(final IUndoableOperation operation) {
+ super("Wrapped Papyrus Text Edit Operation"); //$NON-NLS-1$
+ this.operation = operation;
+
+ }
+
+ /**
+ * @see org.eclipse.emf.common.command.Command#execute()
+ *
+ */
+ @Override
+ public void execute() {
+ // do nothing, already executed by XText
+ }
+
+ /**
+ *
+ * @see org.eclipse.emf.common.command.AbstractCommand#canExecute()
+ *
+ * @return
+ */
+ @Override
+ public boolean canExecute() {
+ return true;
+ };
+
+ /**
+ *
+ * @see org.eclipse.emf.common.command.AbstractCommand#prepare()
+ *
+ * @return
+ */
+ @Override
+ protected boolean prepare() {
+ return true;
+ };
+
+ /**
+ * @see org.eclipse.emf.common.command.AbstractCommand#undo()
+ *
+ */
+ @Override
+ public void undo() {
+ try {
+ if (operation != null) {
+ getOperationHistory().undoOperation(this.operation, new NullProgressMonitor(), null);
+ }
+ } catch (ExecutionException e) {
+ Activator.log.error(e);
+ }
+ }
+
+ /**
+ * @see org.eclipse.emf.common.command.AbstractCommand#canUndo()
+ *
+ * @return
+ */
+ @Override
+ public boolean canUndo() {
+ return true;
+ }
+
+
+ /**
+ * @see org.eclipse.emf.common.command.Command#redo()
+ *
+ */
+ @Override
+ public void redo() {
+ try {
+ if (this.operation != null) {
+ getOperationHistory().redoOperation(operation, new NullProgressMonitor(), null);
+ }
+ } catch (ExecutionException e) {
+ Activator.log.error(e);
+ }
+ }
+
+ /**
+ *
+ * @return
+ * the {@link IOperationHistory}
+ */
+ private IOperationHistory getOperationHistory() {
+ return OperationHistoryFactory.getOperationHistory();
+ }
+}
diff --git a/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/src/org/eclipse/papyrus/infra/textedit/xtext/internal/listeners/UndoableTextChangeListener.java b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/src/org/eclipse/papyrus/infra/textedit/xtext/internal/listeners/UndoableTextChangeListener.java
new file mode 100755
index 00000000000..7b1ce8f245d
--- /dev/null
+++ b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/src/org/eclipse/papyrus/infra/textedit/xtext/internal/listeners/UndoableTextChangeListener.java
@@ -0,0 +1,135 @@
+/*****************************************************************************
+ * Copyright (c) 2022 CEA LIST and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Vincent Lorenzo (CEA LIST) <vincent.lorenzo@cea.fr> - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.textedit.xtext.internal.listeners;
+
+import org.eclipse.core.commands.operations.IOperationHistoryListener;
+import org.eclipse.core.commands.operations.IUndoContext;
+import org.eclipse.core.commands.operations.IUndoableOperation;
+import org.eclipse.core.commands.operations.ObjectUndoContext;
+import org.eclipse.core.commands.operations.OperationHistoryEvent;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.papyrus.infra.textedit.xtext.internal.command.TextUndoRedoCommandWrapper;
+import org.eclipse.xtext.ui.editor.model.IXtextDocument;
+
+/**
+ * This class is in charge of listening the change of the Eclipse OperationHistory and to propagate the changes concerning a text edition from Papyrus
+ * inside the Papyrus CommandStack
+ */
+public class UndoableTextChangeListener implements IOperationHistoryListener {
+
+ private static final String UNDOABLE_TEXT_CHANGE_CLASS = "org.eclipse.text.undo.DocumentUndoManager.UndoableTextChange"; //$NON-NLS-1$
+
+ private static final String UNDOABLE_COMPOUND_TEXT_CHANGE_CLASS = "org.eclipse.text.undo.DocumentUndoManager.UndoableCompoundTextChange"; //$NON-NLS-1$
+
+ /**
+ * the editing domain to use
+ */
+ private TransactionalEditingDomain domain;
+
+ /**
+ * the edited {@link IXtextDocument}
+ */
+ private IXtextDocument xTextDocument;
+
+ /**
+ * boolean indicating if we must listen or not the changes
+ */
+ private boolean active = true;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param domain
+ * the editing domain used to by the Papyrus editor
+ * @param xTextDocument
+ * the edited {@link IXtextDocument}
+ */
+ public UndoableTextChangeListener(final TransactionalEditingDomain domain, final IXtextDocument xTextDocument) {
+ this.domain = domain;
+ this.xTextDocument = xTextDocument;
+ }
+
+ /**
+ * This method allows to update the concerned XtextDocument because we create a new one after each new setInput
+ *
+ * @param xTextDocument
+ */
+ public void updateXTextDocument(final IXtextDocument xTextDocument) {
+ this.xTextDocument = xTextDocument;
+ }
+
+ /**
+ * enable the listener
+ */
+ public void enable() {
+ this.active = true;
+ }
+
+ /**
+ * disable the listener
+ */
+ public void disable() {
+ this.active = false;
+ }
+
+ /**
+ * @see org.eclipse.core.commands.operations.IOperationHistoryListener#historyNotification(org.eclipse.core.commands.operations.OperationHistoryEvent)
+ *
+ * @param event
+ */
+ @Override
+ public void historyNotification(final OperationHistoryEvent event) {
+
+ final int eventType = event.getEventType();
+ final IUndoableOperation operation = event.getOperation();
+ final String operationClassName = operation.getClass().getCanonicalName();
+ if (UNDOABLE_TEXT_CHANGE_CLASS.equals(operationClassName)
+ || UNDOABLE_COMPOUND_TEXT_CHANGE_CLASS.equals(operationClassName)) {
+
+ if (eventType == OperationHistoryEvent.OPERATION_ADDED) {
+ if (!active) {
+ return;
+ }
+ // we check the notification concerns the document for which we installed this listener
+ if (this.xTextDocument == extractCurrentXTextDocument(operation)) {
+ // we wrap the action and we add it to the papyrus command stack
+ final TextUndoRedoCommandWrapper lastCreatedWrapper = new TextUndoRedoCommandWrapper(operation);
+ this.domain.getCommandStack().execute(lastCreatedWrapper);
+ }
+ }
+ }
+ }
+
+ /**
+ *
+ * @param operation
+ * an operation
+ * @return
+ * the xtext document or <code>null</code> for the current operation
+ */
+ private IXtextDocument extractCurrentXTextDocument(final IUndoableOperation operation) {
+ for (final IUndoContext ctx : operation.getContexts()) {
+ if (ctx instanceof ObjectUndoContext) {
+ final ObjectUndoContext undoContext = (ObjectUndoContext) ctx;
+ if (undoContext.getObject() instanceof IXtextDocument) {
+ return (IXtextDocument) undoContext.getObject();
+ }
+ }
+ }
+ return null;
+ }
+}
diff --git a/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/usecase.md b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/usecase.md
index 986801fa7e3..3e4bb8fa874 100755
--- a/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/usecase.md
+++ b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit.xtext/usecase.md
@@ -11,4 +11,17 @@ For the "focus lost", we must consider several case:
Custom implementation of the dispose method (close method is never called by Papyrus)
5. We have several PapyrusXtextEditor open side by side, we must save the first one each time the user click in another one
- we use the SaveTextOnFocusLostPageLifeCycleEventsListener \ No newline at end of file
+ we use the SaveTextOnFocusLostPageLifeCycleEventsListener
+
+##Undo/Redo
+bug 580115 : the Undo/Redo of the text editor must be accessible to the user.
+Undo/Redo of TextEditor is not compliant with the Papyrus Undo/Redo mechanism which uses an EMF Command Stack. Nevertheless we find a way to propagate Text changes inside the Papyrus Undo/Redo command stack.
+We listen the Eclipse Operation History (class org.eclipse.papyrus.infra.textedit.xtext.internal.listeners.UndoableTextChangeListener) to detect TextEdition action from a Papyrus nested TextEditor,
+then we wrap the UndoableTextChange/UndoableCompoundTextChange (already executed) into an EMF Command (class TextUndoRedoCommandWrapper) and we add this command into the Papyrus CommandStack.
+
+The CommandStack listener is used to update the editor contents when a new command is executed inside the Command Stack:
+- TextUndoRedoCommandWrapper can be ignored, because the editor is already up to date
+- the CommandStackListener calls org.eclipse.papyrus.infra.textedit.xtext.nested.editor.PapyrusXTextEditor.updateEditorContent()
+- updateEditorContent disables the UndoableTextChangeListener before updating the contents. this steps is required. If we don't disable the listener, the update will add a new TextUndoRedoCommandWrapper inside the Papyrus CommandStack and it should not!
+
+ \ No newline at end of file
diff --git a/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit/.project b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit/.project
index ad4bb1562aa..ca6d97a1307 100755
--- a/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit/.project
+++ b/plugins/infra/textedit/org.eclipse.papyrus.infra.textedit/.project
@@ -20,9 +20,15 @@
<arguments>
</arguments>
</buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
</natures>
</projectDescription>
diff --git a/releng/toolsmiths/site/category.xml b/releng/toolsmiths/site/category.xml
index 027f54ca33b..7581266383b 100644
--- a/releng/toolsmiths/site/category.xml
+++ b/releng/toolsmiths/site/category.xml
@@ -48,10 +48,10 @@
<feature url="features/org.eclipse.papyrus.toolsmiths.builder.feature.source_1.0.0.qualifier.jar" id="org.eclipse.papyrus.toolsmiths.builder.feature" version="1.0.0.qualifier">
<category name="org.eclipse.papyrus.toolsmiths.category"/>
</feature>
- <feature url="features/org.eclipse.papyrus.infra.textedit.feature_1.0.0.qualifier.jar" id="org.eclipse.papyrus.infra.textedit.feature" version="1.0.0.qualifier">
+ <feature url="features/org.eclipse.papyrus.infra.textedit.feature_1.1.0.qualifier.jar" id="org.eclipse.papyrus.infra.textedit.feature" version="1.1.0.qualifier">
<category name="org.eclipse.papyrus.toolsmiths.category"/>
</feature>
- <feature url="features/org.eclipse.papyrus.infra.textedit.feature.source_1.0.0.qualifier.jar" id="org.eclipse.papyrus.infra.textedit.feature.source" version="1.0.0.qualifier">
+ <feature url="features/org.eclipse.papyrus.infra.textedit.feature.source_1.1.0.qualifier.jar" id="org.eclipse.papyrus.infra.textedit.feature.source" version="1.1.0.qualifier">
<category name="org.eclipse.papyrus.toolsmiths.category"/>
</feature>
<category-def name="org.eclipse.papyrus.toolsmiths.category" label="Papyrus Toolsmiths">

Back to the top