Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnsgar Radermacher2016-01-16 23:21:13 +0000
committerAnsgar Radermacher2016-01-17 13:03:01 +0000
commit36b670f0a9f5dd59422a9f368dfe035d0b5f719c (patch)
tree7bb419a329ba5c568f5b3062b7661ed0b3e78d46 /extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org
parent47dd8f8ebd64192956b097cb70f783d7446138ab (diff)
downloadorg.eclipse.papyrus-36b670f0a9f5dd59422a9f368dfe035d0b5f719c.tar.gz
org.eclipse.papyrus-36b670f0a9f5dd59422a9f368dfe035d0b5f719c.tar.xz
org.eclipse.papyrus-36b670f0a9f5dd59422a9f368dfe035d0b5f719c.zip
Bug 484701 - [QDesigner] Refactoring - code generators, architecture exploration and component based design should be organised in common directory
Bug 478797 - [model library] Decide which model library to use for C++ primitive types Change-Id: Idade4edfcf803da3528c0873aa04b754915866fd
Diffstat (limited to 'extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org')
-rw-r--r--extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/Activator.java71
-rw-r--r--extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/AddProfileAndModelLibsHandler.java144
-rw-r--r--extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/CommandSupport.java75
-rw-r--r--extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/TextEditorConstants.java23
-rw-r--r--extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/Utils.java187
-rw-r--r--extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/editor/DelegatingSourceViewer.java400
-rw-r--r--extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/editor/PapyrusCDTEditor.java395
-rw-r--r--extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/factory/PapyrusCDTEditorFactory.java210
-rw-r--r--extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/handler/PapyrusCDTEditorHandler.java308
-rw-r--r--extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/listener/ChangeKind.java7
-rw-r--r--extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/listener/Closure.java81
-rw-r--r--extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/listener/ModelListener.java135
-rw-r--r--extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/listener/OperationHistoryListener.java76
-rw-r--r--extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/modelresource/TextEditorModelSharedResource.java120
-rw-r--r--extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/preferences/CDTPreferenceConstants.java33
-rw-r--r--extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/preferences/CDTPreferenceInitializer.java39
-rw-r--r--extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/preferences/CDTPreferencePage.java64
-rw-r--r--extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/sync/FindTransition.java47
-rw-r--r--extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/sync/ObtainICElement.java129
-rw-r--r--extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/sync/ParameterModifiers.java45
-rw-r--r--extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/sync/RevealCurrentOperation.java128
-rw-r--r--extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/sync/SyncCDTtoModel.java635
-rw-r--r--extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/sync/SyncModelToCDT.java80
23 files changed, 3432 insertions, 0 deletions
diff --git a/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/Activator.java b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/Activator.java
new file mode 100644
index 00000000000..f69ef78e6f2
--- /dev/null
+++ b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/Activator.java
@@ -0,0 +1,71 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.texteditor.cdt;
+
+import org.eclipse.papyrus.infra.core.log.LogHelper;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.papyrus.texteditor.cdt"; //$NON-NLS-1$
+
+ // The shared instance
+ private static Activator plugin;
+
+ public static LogHelper log;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ log = new LogHelper(this);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+}
diff --git a/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/AddProfileAndModelLibsHandler.java b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/AddProfileAndModelLibsHandler.java
new file mode 100644
index 00000000000..fa0e02c1594
--- /dev/null
+++ b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/AddProfileAndModelLibsHandler.java
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * Copyright (c) 2015 CEA LIST.
+ * 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:
+ * Ansgar Radermacher - ansgar.radermacher@cea.fr CEA LIST - initial API and implementation
+ *
+ *******************************************************************************/
+
+package org.eclipse.papyrus.texteditor.cdt;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.emf.common.command.CommandStack;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.emf.transaction.RecordingCommand;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.emf.transaction.util.TransactionUtil;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.Package;
+import org.eclipse.uml2.uml.PackageImport;
+import org.eclipse.uml2.uml.Profile;
+import org.eclipse.uml2.uml.UMLFactory;
+import org.eclipse.uml2.uml.resource.UMLResource;
+
+/**
+ * This class adds the C++ profile as well as the ANSI-C library to your model.
+ *
+ * TODO: currently not used.
+ */
+public class AddProfileAndModelLibsHandler {
+
+ static final String CPP_PROFILE_URI = "pathmap://CPP_PROFILES/C_Cpp.profile.uml"; //$NON-NLS-1$
+
+ static final String ANSIC_LIBRARY_URI = "pathmap://CPP_LIBRARIES/Ansi_C.library.uml"; //$NON-NLS-1$
+
+ /**
+ * Retrieve a model library from the repository
+ *
+ * @param uri
+ * the URI of the repository
+ *
+ * @return
+ */
+ public PackageImport getModelLibraryImportFromURI(URI uri, EditingDomain domain) {
+ // Try to reach model
+ Element root = getContent(uri, domain);
+ if (root instanceof Package) {
+
+ // Import model library
+ Package libToImport = (Package) root;
+ // create import package
+ PackageImport modelLibImport = UMLFactory.eINSTANCE.createPackageImport();
+ modelLibImport.setImportedPackage(libToImport);
+
+ return modelLibImport;
+ }
+ return null;
+ }
+
+ public static Element getContent(URI uri, EditingDomain domain) {
+ // Resource resource = getTransactionalEditingDomain ().getResourceSet().getResource (uri, true);
+ Resource resource = domain.getResourceSet().getResource(uri, true);
+ return getContent(resource);
+ }
+
+ public static Element getContent(Resource resource) {
+ EList<EObject> contentObj = resource.getContents();
+ if ((contentObj.size() > 0) && (contentObj.get(0) instanceof Element)) {
+ return (Element) contentObj.get(0);
+ }
+ return null;
+ }
+
+ /**
+ * Check whether a package import is already done
+ *
+ * @param selectedPkg
+ * @param pi
+ * @return
+ */
+ boolean isAlreadyImported(Package selectedPkg, PackageImport pi) {
+ for (PackageImport existingPI : selectedPkg.getPackageImports()) {
+ if ((existingPI.getImportedPackage() == null) ||
+ (pi.getImportedPackage() == null)) {
+ // import package are null (should not happen?!)
+ continue;
+ }
+ if ((existingPI.getImportedPackage().getName() == null) ||
+ (pi.getImportedPackage().getName() == null)) {
+ // import package name not set (should not happen?!)
+ continue;
+ } else if (existingPI.getImportedPackage().getName().equals(pi.getImportedPackage().getName())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
+ */
+ /**
+ * {@inheritDoc}
+ */
+ public void addProfileAndImport(final Package selectedPkg) throws ExecutionException {
+
+ final TransactionalEditingDomain domain = TransactionUtil.getEditingDomain(selectedPkg);
+ CommandStack stack = domain.getCommandStack();
+ stack.execute(new RecordingCommand(domain, "Add C++ profile & ANSI-C library") { //$NON-NLS-1$
+ @Override
+ public void doExecute() {
+ // add primitive types
+ // create import package to primitiveType
+ PackageImport pi = getModelLibraryImportFromURI(URI.createURI(UMLResource.UML_PRIMITIVE_TYPES_LIBRARY_URI), domain);
+ selectedPkg.getPackageImports().add(pi);
+ addCppProfile(selectedPkg, domain);
+ };
+ });
+ }
+
+ public static void addCppProfile(Package selectedPkg, TransactionalEditingDomain domain) {
+
+ // Retrieve C++ profile
+ Profile cppProfile =
+ (Profile) getContent(URI.createURI(CPP_PROFILE_URI), domain);
+
+ // Apply C++ profile to model
+ if (cppProfile instanceof Profile) {
+ Profile profile = selectedPkg.getAppliedProfile(cppProfile.getQualifiedName());
+ if ((profile == null) && (!cppProfile.getOwnedStereotypes().isEmpty())) {
+ selectedPkg.applyProfile(cppProfile);
+ }
+ }
+ }
+}
diff --git a/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/CommandSupport.java b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/CommandSupport.java
new file mode 100644
index 00000000000..a3e32434420
--- /dev/null
+++ b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/CommandSupport.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2015 CEA LIST.
+ * 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:
+ * Ansgar Radermacher - ansgar.radermacher@cea.fr CEA LIST - initial API and implementation
+ *
+ *******************************************************************************/
+
+package org.eclipse.papyrus.texteditor.cdt;
+
+import java.util.Collections;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.operations.IOperationHistory;
+import org.eclipse.core.commands.operations.OperationHistoryFactory;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.common.core.command.CommandResult;
+import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.core.utils.ServiceUtilsForActionHandlers;
+
+/**
+ * Utility function. Allow execution of commands on a transactional command stack
+ */
+public class CommandSupport {
+
+ /**
+ * Execute the passed Runnable within a command
+ *
+ * @param label
+ * @param command
+ */
+ public static void exec(String label, final Runnable command) {
+ ServiceUtilsForActionHandlers serviceUtils = ServiceUtilsForActionHandlers.getInstance();
+ try {
+ exec(serviceUtils.getTransactionalEditingDomain(), label, command);
+ } catch (ServiceException e) {
+ // Log.log(Log.ERROR_MSG, Log.UTILS, "Can not get editing domain");
+ }
+ }
+
+ /**
+ * Execute the passed Runnable within a command
+ *
+ * @param label
+ * @param command
+ */
+ public static void exec(TransactionalEditingDomain domain, String label, final Runnable command) {
+ if (domain == null) {
+ command.run();
+ }
+ else {
+ IOperationHistory history = OperationHistoryFactory.getOperationHistory();
+ try {
+ history.execute(new AbstractTransactionalCommand(domain, label, Collections.EMPTY_LIST) {
+
+ @Override
+ public CommandResult doExecuteWithResult(IProgressMonitor dummy, IAdaptable info) {
+ command.run();
+ return CommandResult.newOKCommandResult();
+ }
+ }, null, null);
+ } catch (ExecutionException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+}
diff --git a/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/TextEditorConstants.java b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/TextEditorConstants.java
new file mode 100644
index 00000000000..2436b7373b5
--- /dev/null
+++ b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/TextEditorConstants.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2013 CEA LIST.
+ * 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:
+ * Ansgar Radermacher - ansgar.radermacher@cea.fr CEA LIST - initial API and implementation
+ *
+ *******************************************************************************/
+
+package org.eclipse.papyrus.texteditor.cdt;
+
+import java.util.regex.Pattern;
+
+public class TextEditorConstants {
+
+ /**
+ * Regular expression for accepted language for compatible CDT code generators
+ */
+ public static final Pattern CPP = Pattern.compile("C\\+\\+|c\\+\\+|CPP|cpp|C|c"); //$NON-NLS-1$
+}
diff --git a/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/Utils.java b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/Utils.java
new file mode 100644
index 00000000000..2beb89ab936
--- /dev/null
+++ b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/Utils.java
@@ -0,0 +1,187 @@
+/*******************************************************************************
+ * Copyright (c) 2015 CEA LIST.
+ * 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:
+ * Ansgar Radermacher - ansgar.radermacher@cea.fr CEA LIST - initial API and implementation
+ *
+ *******************************************************************************/
+
+package org.eclipse.papyrus.texteditor.cdt;
+
+import org.eclipse.papyrus.codegen.extensionpoints.GenerationConstants;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.Package;
+
+/**
+ * Collection of utility operations that are used by the CDT editor.
+ */
+public class Utils {
+
+ public static final String nsSep = "::"; //$NON-NLS-1$
+
+ /**
+ * Decrease the indentation of a text block. This function is used during synchronization, since
+ * the code within an opaque behavior is not indented, whereas the code of an operation within a
+ * file is indented with a tab.
+ */
+ public static String decreaseIndent(char[] contents, int start, int end) {
+ String newBlock = ""; //$NON-NLS-1$
+ boolean newLine = true;
+ int consume = 0;
+ for (int i = start; i < end; i++) {
+ char c = contents[i];
+
+ // consume either a tab or 4 spaces;
+ if (newLine && (c == '\t')) {
+ consume = 1;
+ }
+ if (newLine && (c == ' ')) {
+ consume = 4;
+ }
+
+ if (consume == 0) {
+ newBlock += c;
+ }
+ else if (c == ' ') {
+ consume--;
+ }
+ else {
+ consume = 0;
+ }
+ if ((c == '\n') || (c == '\r')) {
+ newLine = true;
+ }
+ else {
+ newLine = false;
+ }
+ }
+ return newBlock;
+ }
+
+ /**
+ * Get an element via its qualified name. Will find elements from the root
+ * model and elements in imported models. Also supports target model in
+ * which imports have been copied (while keeping the top-level name)
+ *
+ * @param root
+ * @param qualifiedName
+ * @return
+ */
+ public static NamedElement getQualifiedElement(Package root,
+ String qualifiedName) {
+ NamedElement namedElement = null;
+ int index = qualifiedName.indexOf(nsSep);
+ if (index != -1) {
+ // first try using a path without top element (since
+ // getQualifiedElement is typically used for
+ // imported elements)
+ String remainder = qualifiedName.substring(index + 2);
+ namedElement = getQualifiedElement(root, remainder, qualifiedName);
+ }
+ if (namedElement == null) {
+ // try with complete name as path name, but assume that the element
+ // has been copied into the model,
+ // i.e. qualifiedName is prefixed by model name
+ namedElement = getQualifiedElement(root, qualifiedName,
+ root.getName() + nsSep + qualifiedName);
+ }
+ return namedElement;
+ }
+
+ /**
+ * Retrieve an element via its qualified name within a package The segments
+ * of the package may be non unique due to imports
+ *
+ * @return the found element, if it exists
+ */
+ public static NamedElement getQualifiedElement(Package root,
+ String remainingPath, String qualifiedName) {
+ if (root == null) {
+ return null;
+ }
+ if (!remainingPath.contains(nsSep)) {
+ for (NamedElement candidate : root.getMembers()) {
+ String name = candidate.getName();
+ if ((name != null) && name.equals(remainingPath)) {
+ if (candidate.getQualifiedName().equals(qualifiedName)) {
+ return candidate;
+ }
+ }
+ }
+ } else {
+ String segment = remainingPath.split(nsSep)[0];
+ String remainder = remainingPath.substring(segment.length() + 2);
+ for (Element element : root.getMembers()) {
+ if (element instanceof Package) {
+ if (((NamedElement) element).getName().equals(segment)) {
+ NamedElement foundElement = getQualifiedElement(
+ (Package) element, remainder, qualifiedName);
+ // return, if not found
+ if (foundElement != null) {
+ return foundElement;
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * return the top-level owner of an element. This function returns the same
+ * value as getModel, if the top-level element is a model. While this is the
+ * case for models, model libraries have a top-level package (not a model).
+ * In this case, getTop returns the top-level package whereas getModel would
+ * return null.
+ *
+ * @param element
+ * @return the top-level owning package
+ */
+ public static Package getTop(Element element) {
+ while (element != null) {
+ Element owner = element.getOwner();
+ if (owner == null) {
+ if (element instanceof Package) {
+ return (Package) element;
+ }
+ }
+ element = owner;
+ }
+ return null;
+ }
+
+ /**
+ * Remove generated code from a body (everything between the GENERATED_START flag
+ *
+ * @param bodyStr
+ * @return
+ */
+ public static String removeGenerated(String bodyStr) {
+ for (;;) {
+ int startPos = bodyStr.indexOf(GenerationConstants.GENERATED_START);
+ if (startPos == -1) {
+ break;
+ }
+ // search line break of previous line (if any)
+ while ((startPos > 0) && bodyStr.charAt(startPos) != '\r' && bodyStr.charAt(startPos) != '\n') {
+ startPos--;
+ }
+ int endPos = bodyStr.indexOf(GenerationConstants.GENERATED_END, startPos);
+ if (endPos == -1) {
+ break;
+ }
+ endPos += GenerationConstants.GENERATED_END.length();
+ // stop at first non white-space character after comment.
+ while ((endPos < bodyStr.length()) && Character.isWhitespace(bodyStr.charAt(endPos))) {
+ endPos++;
+ }
+ bodyStr = bodyStr.substring(0, startPos) + bodyStr.substring(endPos);
+ }
+ return bodyStr;
+ }
+}
diff --git a/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/editor/DelegatingSourceViewer.java b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/editor/DelegatingSourceViewer.java
new file mode 100644
index 00000000000..f5d61481370
--- /dev/null
+++ b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/editor/DelegatingSourceViewer.java
@@ -0,0 +1,400 @@
+/*****************************************************************************
+ * Copyright (c) 2013 CEA LIST.
+ *
+ *
+ * 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:
+ * Ansgar Radermacher (CEA LIST) Ansgar.Radermacher@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.texteditor.cdt.editor;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.emf.common.util.BasicEList;
+import org.eclipse.jface.text.IAutoIndentStrategy;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IEventConsumer;
+import org.eclipse.jface.text.IFindReplaceTarget;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextDoubleClickStrategy;
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.ITextInputListener;
+import org.eclipse.jface.text.ITextListener;
+import org.eclipse.jface.text.ITextOperationTarget;
+import org.eclipse.jface.text.IUndoManager;
+import org.eclipse.jface.text.IViewportListener;
+import org.eclipse.jface.text.TextPresentation;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationHover;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.uml2.uml.Classifier;
+
+/**
+ * Unsuccessful attempt to create a delegating source viewer that changes the implementation of
+ * the operation getSelectionProvider of a source viewer. This does not work in case of CDT since the
+ * source viewer is cast to CSourceViewer later.
+ *
+ * CURRENTLY NOT USED
+ */
+@Deprecated
+public class DelegatingSourceViewer implements ISourceViewer {
+
+ public DelegatingSourceViewer(ISourceViewer delegationTarget, Classifier classifier) {
+ // super(null, null, null, false, 0, null);
+ this.dt = delegationTarget;
+ this.cl = classifier;
+
+ sp = new ISelectionProvider() {
+
+ @Override
+ public void setSelection(ISelection selection) {
+ }
+
+ @Override
+ public void removeSelectionChangedListener(
+ ISelectionChangedListener listener) {
+ System.err.println("removeSelectionChangedListener");
+ }
+
+ @Override
+ public ISelection getSelection() {
+ return new IStructuredSelection() {
+
+ @Override
+ public boolean isEmpty() {
+ return false;
+ }
+
+ @Override
+ public List toList() {
+ List l = new BasicEList<Object>();
+ l.add(cl);
+ return l;
+ }
+
+ @Override
+ public Object[] toArray() {
+ return new Object[] { cl };
+ }
+
+ @Override
+ public int size() {
+ // TODO Auto-generated method stub
+ return 1;
+ }
+
+ @Override
+ public Iterator iterator() {
+ return null;
+ }
+
+ @Override
+ public Object getFirstElement() {
+ return cl;
+ }
+ };
+ }
+
+ @Override
+ public void addSelectionChangedListener(ISelectionChangedListener listener) {
+ // TODO Auto-generated method stub
+ System.err.println("add SelectionChangedListener");
+
+ }
+ };
+ }
+
+ ISourceViewer dt;
+
+ Classifier cl;
+
+ ISelectionProvider sp;
+
+ @Override
+ public StyledText getTextWidget() {
+ return dt.getTextWidget();
+ }
+
+ @Override
+ public void setUndoManager(IUndoManager undoManager) {
+ dt.setUndoManager(undoManager);
+ }
+
+ @Override
+ public void setTextDoubleClickStrategy(
+ ITextDoubleClickStrategy strategy, String contentType) {
+ dt.setTextDoubleClickStrategy(strategy, contentType);
+ }
+
+ @Override
+ public void setAutoIndentStrategy(IAutoIndentStrategy strategy,
+ String contentType) {
+ dt.setAutoIndentStrategy(strategy, contentType);
+ }
+
+ @Override
+ public void setTextHover(ITextHover textViewerHover,
+ String contentType) {
+ dt.setTextHover(textViewerHover, contentType);
+ }
+
+ @Override
+ public void activatePlugins() {
+ dt.activatePlugins();
+ }
+
+ @Override
+ public void resetPlugins() {
+ dt.resetPlugins();
+ }
+
+ @Override
+ public void addViewportListener(IViewportListener listener) {
+ dt.addViewportListener(listener);
+ }
+
+ @Override
+ public void removeViewportListener(IViewportListener listener) {
+ dt.removeViewportListener(listener);
+ }
+
+ @Override
+ public void addTextListener(ITextListener listener) {
+ dt.addTextListener(listener);
+ }
+
+ @Override
+ public void removeTextListener(ITextListener listener) {
+ dt.removeTextListener(listener);
+ }
+
+ @Override
+ public void addTextInputListener(ITextInputListener listener) {
+ dt.addTextInputListener(listener);
+ }
+
+ @Override
+ public void removeTextInputListener(ITextInputListener listener) {
+ dt.removeTextInputListener(listener);
+ }
+
+ @Override
+ public void setDocument(IDocument document) {
+ dt.setDocument(document);
+ }
+
+ @Override
+ public IDocument getDocument() {
+ return dt.getDocument();
+ }
+
+ @Override
+ public void setEventConsumer(IEventConsumer consumer) {
+ dt.setEventConsumer(consumer);
+
+ }
+
+ @Override
+ public void setEditable(boolean editable) {
+ dt.setEditable(editable);
+ }
+
+ @Override
+ public boolean isEditable() {
+ return dt.isEditable();
+ }
+
+ @Override
+ public void setDocument(IDocument document, int modelRangeOffset,
+ int modelRangeLength) {
+ dt.setDocument(document, modelRangeOffset, modelRangeLength);
+ }
+
+ @Override
+ public void setVisibleRegion(int offset, int length) {
+ dt.setVisibleRegion(offset, length);
+ }
+
+ @Override
+ public void resetVisibleRegion() {
+ dt.resetVisibleRegion();
+ }
+
+ @Override
+ public IRegion getVisibleRegion() {
+ return dt.getVisibleRegion();
+ }
+
+ @Override
+ public boolean overlapsWithVisibleRegion(int offset, int length) {
+ return dt.overlapsWithVisibleRegion(offset, length);
+ }
+
+ @Override
+ public void changeTextPresentation(TextPresentation presentation,
+ boolean controlRedraw) {
+ dt.changeTextPresentation(presentation, controlRedraw);
+ }
+
+ @Override
+ public void invalidateTextPresentation() {
+ dt.invalidateTextPresentation();
+
+ }
+
+ @Override
+ public void setTextColor(Color color) {
+ dt.setTextColor(color);
+ }
+
+ @Override
+ public void setTextColor(Color color, int offset, int length,
+ boolean controlRedraw) {
+ dt.setTextColor(color, offset, length, controlRedraw);
+ }
+
+ @Override
+ public ITextOperationTarget getTextOperationTarget() {
+ return dt.getTextOperationTarget();
+ }
+
+ @Override
+ public IFindReplaceTarget getFindReplaceTarget() {
+ return dt.getFindReplaceTarget();
+ }
+
+ @Override
+ public void setDefaultPrefixes(String[] defaultPrefixes,
+ String contentType) {
+ dt.setDefaultPrefixes(defaultPrefixes, contentType);
+
+ }
+
+ @Override
+ public void setIndentPrefixes(String[] indentPrefixes,
+ String contentType) {
+ dt.setIndentPrefixes(indentPrefixes, contentType);
+ }
+
+ @Override
+ public void setSelectedRange(int offset, int length) {
+ dt.setSelectedRange(offset, length);
+ }
+
+ @Override
+ public Point getSelectedRange() {
+ return dt.getSelectedRange();
+ }
+
+ @Override
+ public ISelectionProvider getSelectionProvider() {
+ return dt.getSelectionProvider();
+ }
+
+ @Override
+ public void revealRange(int offset, int length) {
+ dt.revealRange(offset, length);
+ }
+
+ @Override
+ public void setTopIndex(int index) {
+ dt.setTopIndex(index);
+ }
+
+ @Override
+ public int getTopIndex() {
+ return dt.getTopIndex();
+ }
+
+ @Override
+ public int getTopIndexStartOffset() {
+ return dt.getTopIndexStartOffset();
+ }
+
+ @Override
+ public int getBottomIndex() {
+ return dt.getBottomIndex();
+ }
+
+ @Override
+ public int getBottomIndexEndOffset() {
+ return dt.getBottomIndexEndOffset();
+ }
+
+ @Override
+ public int getTopInset() {
+ return dt.getTopInset();
+ }
+
+ @Override
+ public void configure(SourceViewerConfiguration configuration) {
+ dt.configure(configuration);
+ }
+
+ @Override
+ public void setAnnotationHover(IAnnotationHover annotationHover) {
+ dt.setAnnotationHover(annotationHover);
+ }
+
+ @Override
+ public void setDocument(IDocument document,
+ IAnnotationModel annotationModel) {
+ dt.setDocument(document, annotationModel);
+ }
+
+ @Override
+ public void setDocument(IDocument document,
+ IAnnotationModel annotationModel, int modelRangeOffset,
+ int modelRangeLength) {
+ dt.setDocument(document, annotationModel, modelRangeOffset, modelRangeLength);
+
+ }
+
+ @Override
+ public IAnnotationModel getAnnotationModel() {
+ return dt.getAnnotationModel();
+ }
+
+ @Override
+ public void setRangeIndicator(Annotation rangeIndicator) {
+ dt.setRangeIndicator(rangeIndicator);
+
+ }
+
+ @Override
+ public void setRangeIndication(int offset, int length,
+ boolean moveCursor) {
+ dt.setRangeIndication(offset, length, moveCursor);
+ }
+
+ @Override
+ public IRegion getRangeIndication() {
+ return dt.getRangeIndication();
+ }
+
+ @Override
+ public void removeRangeIndication() {
+ dt.removeRangeIndication();
+ }
+
+ @Override
+ public void showAnnotations(boolean show) {
+ dt.showAnnotations(show);
+ }
+}
diff --git a/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/editor/PapyrusCDTEditor.java b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/editor/PapyrusCDTEditor.java
new file mode 100644
index 00000000000..4ae37530cac
--- /dev/null
+++ b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/editor/PapyrusCDTEditor.java
@@ -0,0 +1,395 @@
+/*****************************************************************************
+ * Copyright (c) 2013 CEA LIST.
+ *
+ *
+ * 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:
+ * Ansgar Radermacher (CEA LIST) Ansgar.Radermacher@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.texteditor.cdt.editor;
+
+import org.eclipse.cdt.codan.internal.ui.cxx.CodanCReconciler;
+import org.eclipse.cdt.core.model.ICElement;
+import org.eclipse.cdt.core.model.ISourceRange;
+import org.eclipse.cdt.core.model.ISourceReference;
+import org.eclipse.cdt.core.model.ITranslationUnit;
+import org.eclipse.cdt.internal.ui.editor.CEditor;
+import org.eclipse.cdt.ui.CDTUITools;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EValidator;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.IVerticalRuler;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.papyrus.infra.core.lifecycleevents.DoSaveEvent;
+import org.eclipse.papyrus.infra.core.lifecycleevents.ILifeCycleEventsProvider;
+import org.eclipse.papyrus.infra.core.lifecycleevents.ISaveAndDirtyService;
+import org.eclipse.papyrus.infra.core.lifecycleevents.ISaveEventListener;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
+import org.eclipse.papyrus.texteditor.cdt.Activator;
+import org.eclipse.papyrus.texteditor.cdt.sync.ObtainICElement;
+import org.eclipse.papyrus.texteditor.cdt.sync.RevealCurrentOperation;
+import org.eclipse.papyrus.texteditor.cdt.sync.SyncCDTtoModel;
+import org.eclipse.papyrus.texteditor.cdt.sync.SyncModelToCDT;
+import org.eclipse.papyrus.texteditor.model.texteditormodel.TextEditorModel;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.ide.IGotoMarker;
+import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.ui.texteditor.ITextEditorActionConstants;
+import org.eclipse.uml2.uml.Classifier;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.NamedElement;
+
+/**
+ * A specialization of the CDT editor made for integration into Papyrus
+ *
+ */
+public class PapyrusCDTEditor extends CEditor {
+
+ /** the service registry */
+ protected final ServicesRegistry registry;
+
+ /** the papyrus text instance */
+ protected final TextEditorModel papyrusTextInstance;
+
+ /** the text listener */
+ protected FocusListener focusListener;
+
+ public static final String EDITOR_DEFAULT_NAME = "CDT Editor";
+
+ public static final String EDITOR_TYPE = "CDTEditorInPapyrus"; //$NON-NLS-1$
+
+ protected SyncCDTtoModel syncCpp;
+
+ protected RevealCurrentOperation reveal;
+
+ protected Adapter gotoListener;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param registry
+ * @param papyrusTextInstance
+ */
+ public PapyrusCDTEditor(final ServicesRegistry registry, final TextEditorModel papyrusTextInstance) {
+ super();
+ gotoListener = null;
+ this.registry = registry;
+ this.papyrusTextInstance = papyrusTextInstance;
+ try {
+ saveAndDirtyService = registry.getService(ISaveAndDirtyService.class);
+ saveAndDirtyService.registerIsaveablePart(this);
+ ILifeCycleEventsProvider lifeCycleEvents = registry.getService(ILifeCycleEventsProvider.class);
+ ISaveEventListener preSaveEvent = new ISaveEventListener() {
+
+ @Override
+ public void doSaveAs(DoSaveEvent event) {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public void doSave(DoSaveEvent event) {
+ syncCpp.syncCDTtoModel();
+ }
+ };
+ lifeCycleEvents.addAboutToDoSaveListener(preSaveEvent);
+ } catch (ServiceException e) {
+ Activator.log.error(e);
+ }
+ }
+
+ /**
+ * override method in order to save & restore action bars entries
+ */
+ @Override
+ public void createPartControl(Composite parent) {
+ // save Papyrus (GMF) handlers
+ IActionBars actionBars = getEditorSite().getActionBars();
+ if ((actionBars != null) && (gmfUndo == null)) {
+ gmfUndo = actionBars.getGlobalActionHandler(ITextEditorActionConstants.UNDO);
+ gmfRedo = actionBars.getGlobalActionHandler(ITextEditorActionConstants.REDO);
+ }
+
+ super.createPartControl(parent);
+
+ if (actionBars != null) {
+ // save CDT (textEditor) handlers
+ textUndo = actionBars.getGlobalActionHandler(ITextEditorActionConstants.UNDO);
+ textRedo = actionBars.getGlobalActionHandler(ITextEditorActionConstants.REDO);
+ // & restore Papyrus bar
+ actionBars.setGlobalActionHandler(ITextEditorActionConstants.UNDO, gmfUndo);
+ actionBars.setGlobalActionHandler(ITextEditorActionConstants.REDO, gmfRedo);
+ actionBars.updateActionBars();
+ }
+
+ gotoListener = new Adapter() {
+
+ // assure that gotoElement is called, if the element in the model gets updated
+ @Override
+ public void notifyChanged(Notification notification) {
+ if (notification.getEventType() == Notification.SET) {
+ Object newValue = notification.getNewValue();
+ if (newValue instanceof NamedElement) {
+ gotoElement((NamedElement) newValue);
+ }
+
+ }
+ }
+
+ @Override
+ public Notifier getTarget() {
+ return null;
+ }
+
+ @Override
+ public void setTarget(Notifier newTarget) {
+ }
+
+ @Override
+ public boolean isAdapterForType(Object type) {
+ return false;
+ }
+ };
+ papyrusTextInstance.eAdapters().add(gotoListener);
+
+ if (papyrusTextInstance.getSelectedObject() instanceof NamedElement) {
+ gotoElement((NamedElement) papyrusTextInstance.getSelectedObject());
+ }
+ }
+
+ /**
+ *
+ * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#createSourceViewer(org.eclipse.swt.widgets.Composite, org.eclipse.jface.text.source.IVerticalRuler, int)
+ *
+ * @param parent
+ * @param ruler
+ * @param styles
+ * @return
+ */
+ @Override
+ public ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles) {
+
+ final ISourceViewer viewer = super.createSourceViewer(parent, ruler, styles);
+ // ISourceViewer viewer = new DelegatingSourceViewer(origViewer, (Classifier)papyrusTextInstance.getEditedObject());
+ focusListener = new FocusListener() {
+
+ @Override
+ public void focusLost(FocusEvent e) {
+ // potential problem for undo/redo!!
+ if (isDirty()) {
+ doSave(new NullProgressMonitor());
+ syncCpp.syncCDTtoModel();
+ Classifier classifier = (Classifier) papyrusTextInstance.getEditedObject();
+ // regenerate code. TODO: raises update dialog
+ // SyncModelToCDT.syncModelToCDT(classifier);
+ }
+ // restore handlers
+ IActionBars actionBars = getEditorSite().getActionBars();
+ if (actionBars != null) {
+ if ((gmfUndo != null) && (gmfRedo != null)) {
+ actionBars.setGlobalActionHandler(ITextEditorActionConstants.UNDO, gmfUndo);
+ actionBars.setGlobalActionHandler(ITextEditorActionConstants.REDO, gmfRedo);
+ actionBars.updateActionBars();
+ }
+ }
+ }
+
+ @Override
+ public void focusGained(FocusEvent e) {
+ // restore handlers
+ IActionBars actionBars = getEditorSite().getActionBars();
+ if (actionBars != null) {
+ if ((textUndo != null) && (textRedo != null)) {
+ actionBars.setGlobalActionHandler(ITextEditorActionConstants.UNDO, textUndo);
+ actionBars.setGlobalActionHandler(ITextEditorActionConstants.REDO, textRedo);
+ actionBars.updateActionBars();
+ }
+ }
+ }
+ };
+ // register focus listener
+ viewer.getTextWidget().addFocusListener(focusListener);
+ SelectionListener selectionListener = new SelectionListener() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ IEditorPart ep = getEditorSite().getPage().getActiveEditor();
+ ISelection selection = getSelectionProvider().getSelection();
+ if ((ep instanceof IGotoMarker) && (selection instanceof ITextSelection)) {
+ if (((ITextSelection) selection).getLength() > 0) {
+ // don't try to navigate during selection of a chunk of text.
+ return;
+ }
+ IMarker marker;
+ /*
+ * create a temporary validation marker on the
+ * srcFile file, call the gotoMarker operation of the editor
+ * and remove the marker afterwards.
+ * TODO: operation activates the model-explorer
+ */
+ try {
+ Element element = reveal.obtainSelectedElement((ITextSelection) selection);
+ String modelURI = EcoreUtil.getURI(element).toString();
+ marker = srcFile.createMarker(EValidator.MARKER);
+ marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_INFO); // set severity before URI to avoid marker update without associated icon
+ marker.setAttribute(EValidator.URI_ATTRIBUTE, modelURI);
+ IWorkbenchPage wbpage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ IWorkbenchPart activePart = wbpage.getActivePart();
+ ((IGotoMarker) ep).gotoMarker(marker);
+ // reactivate this editor
+ wbpage.activate(activePart);
+ marker.delete();
+ } catch (CoreException e1) {
+ // TODO Auto-generated catch block
+ e1.printStackTrace();
+ }
+ }
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ }
+ };
+
+ // TODO: don't add selection listener for the moment. It can cause deadlocks (setting a marker attribute while file is locked, reproducible with cut (^X) on selection)
+ // viewer.getTextWidget().addSelectionListener(selectionListener);
+
+ return viewer;
+ }
+
+ /**
+ * Goto a specific element within the text editor. Currently, only methods are supported.
+ *
+ * @param element
+ * @throws CoreException
+ */
+ public void gotoElement(NamedElement element) {
+ ICElement ice = CDTUITools.getEditorInputCElement(m_input);
+
+ if (ice instanceof ITranslationUnit) {
+ ITranslationUnit itu = (ITranslationUnit) ice;
+ ICElement icElement = ObtainICElement.getICElement(syncCpp.getCodeGen(), itu, element);
+ if (icElement instanceof ISourceReference) {
+ try {
+ ISourceRange range = ((ISourceReference) icElement).getSourceRange();
+
+ ISourceViewer viewer = getSourceViewer();
+ viewer.revealRange(range.getStartPos(), 1);
+ viewer.setSelectedRange(range.getStartPos(), range.getLength());
+ return;
+ } catch (CoreException e) {
+ Activator.log.error(e);
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean isDirty() {
+ boolean isDirty = super.isDirty();
+ if (isDirty != oldDirty) {
+ oldDirty = isDirty;
+ // hack. Normally, the saveAndDirtyService detects this itself (should find a solution how it can do that)
+ // ((SaveAndDirtyService) saveAndDirtyService).fireIsDirtyChanged();
+ }
+ return isDirty;
+ }
+
+ /**
+ * We override this method because setInput can't be overriden for TextEditor.
+ * We replace the default Papyrus input with the CPP file
+ *
+ * @see org.eclipse.ui.editors.text.TextEditor#doSetInput(org.eclipse.ui.IEditorInput)
+ *
+ * @param input
+ * @throws CoreException
+ */
+ @Override
+ protected void doSetInput(IEditorInput input) throws CoreException {
+
+ URI uri = papyrusTextInstance.eResource().getURI();
+ Classifier classifier = (Classifier) papyrusTextInstance.getEditedObject();
+ String generatorID = papyrusTextInstance.getGeneratorID();
+ srcFile = SyncModelToCDT.syncModelToCDT(classifier, generatorID);
+ if (srcFile == null || !srcFile.exists()) {
+ throw new PartInitException("Code generation before editing failed. Please check error log");
+ }
+ IEditorInput newInput = new FileEditorInput(srcFile);
+
+ // IStorage storage = new TextStorage(string);
+ super.doSetInput(newInput);
+
+ syncCpp = new SyncCDTtoModel(newInput, classifier, uri.segment(1), generatorID);
+ m_input = newInput;
+ reveal = new RevealCurrentOperation(newInput, classifier, uri.segment(1));
+
+ // add the reconciler to get syntax check and completion. (still no full checks)
+ addReconcileListener(new CodanCReconciler());
+ }
+
+ /**
+ *
+ * @see org.eclipse.ui.editors.text.TextEditor#dispose()
+ *
+ */
+ @Override
+ public void dispose() {
+
+ saveAndDirtyService.removeIsaveablePart(this);
+ if (gotoListener != null) {
+ papyrusTextInstance.eAdapters().remove(gotoListener);
+ }
+
+ // we remove the listener
+ StyledText st = getSourceViewer().getTextWidget();
+ st.removeFocusListener(focusListener);
+ super.dispose();
+ // assure that embedded text widget is disposed now. Otherwise, it will be closed
+ // later, when the editorSite is already set to null by Papyrus (mainEditorSite attribute in MultiPageEditorSite4x)
+ // resulting in a null pointer exception and resulting inconsistencies in the Papyrus editor.
+ st.dispose();
+ }
+
+ protected IAction gmfUndo, gmfRedo;
+
+ protected IAction textUndo, textRedo;
+
+ protected boolean oldDirty;
+
+ protected ISaveAndDirtyService saveAndDirtyService;
+
+ protected IFile srcFile;
+
+ protected ISelectionProvider sp;
+
+ protected IEditorInput m_input;
+}
diff --git a/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/factory/PapyrusCDTEditorFactory.java b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/factory/PapyrusCDTEditorFactory.java
new file mode 100644
index 00000000000..f4f552858e7
--- /dev/null
+++ b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/factory/PapyrusCDTEditorFactory.java
@@ -0,0 +1,210 @@
+/*****************************************************************************
+ * Copyright (c) 2013, 2014 CEA LIST 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ * Ansgar Radermacher (CEA LIST) - Minor adaptations
+ * Christian W. Damus (CEA) - bug 392301
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.texteditor.cdt.factory;
+
+import org.eclipse.papyrus.infra.core.editor.BackboneException;
+import org.eclipse.papyrus.infra.core.extension.diagrameditor.AbstractEditorFactory;
+import org.eclipse.papyrus.infra.core.multidiagram.actionbarcontributor.ActionBarContributorRegistry;
+import org.eclipse.papyrus.infra.core.sasheditor.contentprovider.IEditorModel;
+import org.eclipse.papyrus.infra.core.sasheditor.contentprovider.IPageModel;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.texteditor.cdt.Activator;
+import org.eclipse.papyrus.texteditor.cdt.editor.PapyrusCDTEditor;
+import org.eclipse.papyrus.texteditor.model.texteditormodel.TextEditorModel;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.part.EditorActionBarContributor;
+
+
+public class PapyrusCDTEditorFactory extends AbstractEditorFactory {
+
+ /**
+ * Constructor.
+ */
+ public PapyrusCDTEditorFactory() {
+ super(PapyrusCDTEditor.class, PapyrusCDTEditor.EDITOR_TYPE);
+ }
+
+ /**
+ * Create the IPageModel that is used by the SashWindows to manage the editor.
+ *
+ * @see org.eclipse.papyrus.infra.core.editorsfactory.IEditorFactory#createIPageModel(java.lang.Object)
+ *
+ * @param pageIdentifier
+ * The model pushed in the sashmodel by the creation command
+ * @return A model implementing the IPageModel
+ */
+ @Override
+ public IPageModel createIPageModel(Object pageIdentifier) {
+ return new TextEditorModelDelegate(pageIdentifier);
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.core.editorsfactory.IEditorFactory#isPageModelFactoryFor(java.lang.Object)
+ *
+ * @param pageIdentifier
+ * @return
+ */
+ @Override
+ public boolean isPageModelFactoryFor(Object pageIdentifier) {
+ if (pageIdentifier instanceof TextEditorModel) {
+ return ((TextEditorModel) pageIdentifier).getType().equals(this.getExpectedType());
+ }
+ return false;
+ }
+
+ /**
+ * IEditorModel used internally by the SashContainer. This model know how to handle IEditor creation.
+ *
+ */
+ class TextEditorModelDelegate implements IEditorModel {
+
+ /**
+ * The created editor.
+ */
+ private IEditorPart editor;
+
+ /**
+ * The raw model stored in the SashProvider.
+ */
+ private TextEditorModel rawEditorModel;
+
+ /**
+ *
+ * Constructor.
+ */
+ public TextEditorModelDelegate(Object pageIdentifier) {
+ rawEditorModel = (TextEditorModel) pageIdentifier;
+ }
+
+ /**
+ * Create the IEditor for the diagram.
+ *
+ * @see org.eclipse.papyrus.infra.core.sasheditor.contentprovider.IEditorModel#createIEditorPart()
+ * @return
+ * @throws PartInitException
+ *
+ */
+ @Override
+ public IEditorPart createIEditorPart() throws PartInitException {
+ try {
+ // we use this way when there is one factory for several editor types
+ // Constructor<?> c = getDiagramClass().getConstructor(ServicesRegistry.class, TextEditorModel.class);
+ // editor = (IEditorPart)c.newInstance(servicesRegistry, rawModel);
+
+ // we use this way when there is only one editor type
+ editor = new PapyrusCDTEditor(getServiceRegistry(), rawEditorModel);
+ return editor;
+
+ } catch (Exception e) {
+ // Lets propagate. This is an implementation problem that should be solved by
+ // programmer.
+ throw new PartInitException("Can't create TextEditor", e);
+ }
+
+ }
+
+ /**
+ * Get the action bar requested by the Editor.
+ *
+ * @see org.eclipse.papyrus.infra.core.sasheditor.contentprovider.IEditorModel#getActionBarContributor()
+ * @return
+ *
+ */
+ @Override
+ public EditorActionBarContributor getActionBarContributor() {
+
+ String actionBarId = editorDescriptor.getActionBarContributorId();
+
+ // Do nothing if no EditorActionBarContributor is specify.
+ if (actionBarId == null || actionBarId.length() == 0) {
+ return null;
+ }
+
+ // Try to get it.
+
+ // Get ServiceRegistry
+ // ServicesRegistry serviceRegistry = getServicesRegistry();
+ ActionBarContributorRegistry registry;
+ try {
+ registry = getServiceRegistry().getService(ActionBarContributorRegistry.class);
+ } catch (ServiceException e) {
+ // Service not found
+ Activator.log.error(e);
+ return null;
+ }
+
+ try {
+ return registry.getActionBarContributor(actionBarId);
+ } catch (BackboneException e) {
+ Activator.log.error(e);
+ return null;
+ }
+ }
+
+ /**
+ * Get the underlying RawModel. Return the TextEditor (normally returns a diagram)
+ *
+ * @see org.eclipse.papyrus.infra.core.sasheditor.contentprovider.IPageModel#getRawModel()
+ * @return
+ *
+ */
+ @Override
+ public Object getRawModel() {
+ return rawEditorModel;
+ }
+
+ /**
+ * Get the icon to be shown by Tabs
+ *
+ * @see org.eclipse.papyrus.infra.core.sasheditor.contentprovider.IPageModel#getTabIcon()
+ * @return
+ *
+ */
+ @Override
+ public Image getTabIcon() {
+ org.eclipse.papyrus.infra.widgets.Activator widgetsActivator =
+ org.eclipse.papyrus.infra.widgets.Activator.getDefault();
+ if (widgetsActivator == null) {
+ return null;
+ }
+ String path = getEditorDescriptor().getIconURL();
+ if (path.startsWith(Activator.PLUGIN_ID)) {
+ // remove PLUGIN-ID prefix from the path (since the image will be searched relative to plugin)
+ path = path.substring(Activator.PLUGIN_ID.length());
+ }
+ return widgetsActivator.getImage(Activator.PLUGIN_ID, path);
+ }
+
+ /**
+ * Get the title of the Diagram.
+ *
+ * @see org.eclipse.papyrus.infra.core.sasheditor.contentprovider.IPageModel#getTabTitle()
+ * @return
+ *
+ */
+ @Override
+ public String getTabTitle() {
+ return rawEditorModel.getName();
+ }
+
+ @Override
+ public void dispose() {
+ // Pass. The tab icon is a plugin-shared image
+ }
+ }
+}
diff --git a/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/handler/PapyrusCDTEditorHandler.java b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/handler/PapyrusCDTEditorHandler.java
new file mode 100644
index 00000000000..7d6df1edfc4
--- /dev/null
+++ b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/handler/PapyrusCDTEditorHandler.java
@@ -0,0 +1,308 @@
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ * Ansgar Radermacher (CEA LIST) ansgar.radermacher@cea.fr
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.texteditor.cdt.handler;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.emf.workspace.AbstractEMFOperation;
+import org.eclipse.papyrus.codegen.extensionpoints.ILangCodegen;
+import org.eclipse.papyrus.codegen.extensionpoints.LanguageCodegen;
+import org.eclipse.papyrus.commands.CheckedOperationHistory;
+import org.eclipse.papyrus.infra.core.resource.NotFoundException;
+import org.eclipse.papyrus.infra.core.sasheditor.contentprovider.IPageManager;
+import org.eclipse.papyrus.infra.core.sasheditor.contentprovider.ISashWindowsContentProvider;
+import org.eclipse.papyrus.infra.core.sasheditor.di.contentprovider.DiSashModelManager;
+import org.eclipse.papyrus.infra.core.sasheditor.editor.ISashWindowsContainer;
+import org.eclipse.papyrus.infra.core.sashwindows.di.PageRef;
+import org.eclipse.papyrus.infra.core.sashwindows.di.SashPanel;
+import org.eclipse.papyrus.infra.core.sashwindows.di.TabFolder;
+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.utils.ServiceUtilsForHandlers;
+import org.eclipse.papyrus.texteditor.cdt.Activator;
+import org.eclipse.papyrus.texteditor.cdt.TextEditorConstants;
+import org.eclipse.papyrus.texteditor.cdt.editor.PapyrusCDTEditor;
+import org.eclipse.papyrus.texteditor.cdt.modelresource.TextEditorModelSharedResource;
+import org.eclipse.papyrus.texteditor.model.texteditormodel.TextEditorModel;
+import org.eclipse.papyrus.texteditor.model.texteditormodel.TextEditorModelFactory;
+import org.eclipse.papyrus.uml.diagram.common.handlers.CmdHandler;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.uml2.uml.Behavior;
+import org.eclipse.uml2.uml.Class;
+import org.eclipse.uml2.uml.Classifier;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.Operation;
+import org.eclipse.uml2.uml.Transition;
+import org.eclipse.uml2.uml.UMLPackage;
+
+
+/**
+ * The handler creates a new CDT editor
+ */
+public class PapyrusCDTEditorHandler extends CmdHandler {
+
+
+ public PapyrusCDTEditorHandler() {
+ }
+
+ /**
+ *
+ * @see org.eclipse.infra.core.commands.AbstractHandler#isEnabled()
+ *
+ * @return
+ */
+ @Override
+ public boolean isEnabled() {
+ updateSelectedEObject();
+ // Filter Classes (including Behaviors, since Behavior inherits from Class), Operation and Transition
+ if (selectedEObject instanceof Class ||
+ selectedEObject instanceof Operation ||
+ selectedEObject instanceof Transition)
+ {
+ URI uri = selectedEObject.eResource().getURI();
+
+ // URIConverter uriConverter = resource.getResourceSet().getURIConverter();
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+ if (uri.segmentCount() < 2) {
+ return false;
+ }
+ IProject modelProject = root.getProject(uri.segment(1));
+ return modelProject.exists();
+ }
+ return false;
+ }
+
+ /**
+ * @see org.eclipse.infra.core.commands.IHandler#execute(org.eclipse.infra.core.commands.ExecutionEvent)
+ *
+ * @param event
+ * @return
+ * @throws ExecutionException
+ */
+ @Override
+ public Object execute(final ExecutionEvent event) throws ExecutionException {
+ try {
+ final ServicesRegistry serviceRegistry = ServiceUtilsForHandlers.getInstance().getServiceRegistry(event);
+ TransactionalEditingDomain domain = ServiceUtils.getInstance().getTransactionalEditingDomain(serviceRegistry);
+
+ // Create the transactional command
+ AbstractEMFOperation command = new AbstractEMFOperation(domain, "Create CDT editor") {
+
+ @Override
+ protected IStatus doExecute(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
+ try {
+ PapyrusCDTEditorHandler.this.doExecute(serviceRegistry);
+ } catch (ServiceException e) {
+ Activator.log.error(e);
+ return Status.CANCEL_STATUS;
+ } catch (NotFoundException e) {
+ Activator.log.error(e);
+ return Status.CANCEL_STATUS;
+ }
+ return Status.OK_STATUS;
+ }
+ };
+
+ // Execute the command
+ CheckedOperationHistory.getInstance().execute(command, new NullProgressMonitor(), null);
+ } catch (ExecutionException e) {
+ Activator.log.error("Can't create a CDT editor", e);
+ } catch (ServiceException e) {
+ Activator.log.error("Service exception during creation of CDT editor", e);
+ }
+ return null;
+ }
+
+
+ /**
+ * Do the execution of the command.
+ *
+ * @param serviceRegistry
+ * @throws ServiceException
+ * @throws NotFoundException
+ */
+ public void doExecute(final ServicesRegistry serviceRegistry) throws ServiceException, NotFoundException {
+ // Get the page manager allowing to add/open an editor.
+ final IPageManager pageMngr = ServiceUtils.getInstance().getIPageManager(serviceRegistry);
+
+ Classifier classifierToEdit = getClassifierToEdit();
+ TextEditorModel editorModel = getEditorModel(serviceRegistry, classifierToEdit);
+ if (editorModel == null) {
+ // no editor exist for the given file => create
+ editorModel = createEditorModel(serviceRegistry, classifierToEdit);
+ if (editorModel == null) {
+ return;
+ }
+ }
+ ILangCodegen codegen = LanguageCodegen.getGenerator(TextEditorConstants.CPP, editorModel.getGeneratorID());
+
+ if (codegen.getTargetProject(classifierToEdit, true) == null) {
+ return;
+ }
+
+ if (selectedEObject instanceof Transition) {
+ Transition transition = (Transition) selectedEObject;
+ if (transition.getEffect() == null) {
+ Behavior effect = transition.createEffect("effectOf" + transition.getName(), UMLPackage.eINSTANCE.getOpaqueBehavior()); //$NON-NLS-1$
+ }
+ }
+ // add the new editor model to the sash.
+ editorModel.setSelectedObject(selectedEObject);
+
+ final TextEditorModel editorModelFinal = editorModel;
+ // open asynchronously to prevent handler cycles, see bug 434484
+ Display.getDefault().asyncExec(new Runnable() {
+
+ @Override
+ public void run() {
+ if (pageMngr.isOpen(editorModelFinal)) {
+ // select existing editor
+ pageMngr.selectPage(editorModelFinal);
+ }
+ else {
+ pageMngr.openPage(editorModelFinal);
+ }
+ try {
+ // move page to the RIGHT
+ DiSashModelManager modelMngr = ServiceUtils.getInstance().getService(DiSashModelManager.class, serviceRegistry);
+ ISashWindowsContentProvider sashContentProvider = modelMngr.getISashWindowsContentProvider();
+ Object rootModel = sashContentProvider.getRootModel();
+
+ if (rootModel instanceof TabFolder) {
+ // root = tabFolder, i.e. there is a single folder
+ ISashWindowsContainer sashContainer = ServiceUtils.getInstance().getISashWindowsContainer(serviceRegistry);
+ int index = lookupIndex((TabFolder) rootModel, editorModelFinal);
+ if (index != -1) {
+ sashContentProvider.createFolder(sashContainer.getSelectedTabFolderModel(), index, sashContainer.getSelectedTabFolderModel(), SWT.RIGHT);
+ }
+ }
+ else if (rootModel instanceof SashPanel) {
+ // multiple tab-folders exist. Find existing one and move editorModel to other
+ // TODO
+ // ISashWindowsContainer sashContainer = ServiceUtils.getInstance().getISashWindowsContainer(serviceRegistry);
+ // sashContentProvider.movePage(sashContainer.getSelectedTabFolderModel(), lookupIndex(sourceTab, editorModel), targetTabModel, -1);
+ }
+ } catch (ServiceException e) {
+
+ }
+ }
+
+ });
+
+ }
+
+ /**
+ * Create a model identifying the editor. This model will be saved with the sash
+ *
+ * @return
+ * @throws ServiceException
+ * @throws NotFoundException
+ * The model where to save the TableInstance is not found.
+ */
+ protected TextEditorModel createEditorModel(final ServicesRegistry serviceRegistry, Classifier classifierToEdit) throws ServiceException, NotFoundException {
+ TextEditorModel editorModel = TextEditorModelFactory.eINSTANCE.createTextEditorModel();
+
+ editorModel.setEditedObject(classifierToEdit);
+ editorModel.setType(PapyrusCDTEditor.EDITOR_TYPE);
+ editorModel.setName("CDT " + classifierToEdit.getName()); //$NON-NLS-1$
+ ILangCodegen codegen = LanguageCodegen.chooseGenerator(TextEditorConstants.CPP, classifierToEdit);
+ if (codegen == null) {
+ return null;
+ }
+ editorModel.setGeneratorID(LanguageCodegen.getID(codegen));
+ TextEditorModelSharedResource model = (TextEditorModelSharedResource)
+ ServiceUtils.getInstance().getModelSet(serviceRegistry).getModelChecked(TextEditorModelSharedResource.MODEL_ID);
+ model.addTextEditorModel(editorModel);
+
+ return editorModel;
+ }
+
+ /**
+ * The classifier to edit - corresponding to the selected object.
+ *
+ * @return
+ */
+ protected Classifier getClassifierToEdit() {
+ if (selectedEObject instanceof Operation) {
+ return ((Operation) selectedEObject).getFeaturingClassifiers().get(0);
+ }
+ else if (selectedEObject instanceof Transition) {
+ return ((Transition) selectedEObject).getContainer().getStateMachine().getContext();
+ }
+ else if (selectedEObject instanceof Behavior) {
+ Element owner = (Behavior) selectedEObject;
+ while (owner != null) {
+ owner = owner.getOwner();
+ if ((owner instanceof Classifier) && !(owner instanceof Behavior)) {
+ return (Classifier) owner;
+ }
+ }
+ return null;
+ }
+ else if (selectedEObject instanceof Classifier) {
+ // must be class or datatype
+ return (Classifier) selectedEObject;
+ }
+ return null;
+ }
+
+ /**
+ * return the editor model corresponding to an EObject
+ *
+ * @param serviceRegistry
+ * the service registry
+ * @param classifierToEdit
+ * The classifier for which a CDT editor should be opened
+ * @return
+ * @throws ServiceException
+ * @throws NotFoundException
+ */
+ protected TextEditorModel getEditorModel(final ServicesRegistry serviceRegistry, Classifier classifierToEdit) throws ServiceException, NotFoundException {
+ TextEditorModelSharedResource model = (TextEditorModelSharedResource)
+ ServiceUtils.getInstance().getModelSet(serviceRegistry).getModelChecked(TextEditorModelSharedResource.MODEL_ID);
+ return model.getTextEditorModel(classifierToEdit);
+ }
+
+ /**
+ * Recursively search in sash models for a FolderModel.
+ * Return the first encountered folder.
+ *
+ * @param panelModel
+ * @return
+ */
+ public static int lookupIndex(TabFolder folder, Object model) {
+
+ int index = 0;
+ for (PageRef pr : folder.getChildren()) {
+ if (pr.getPageIdentifier() == model) {
+ return index;
+ }
+ index++;
+ }
+ return -1;
+ }
+}
diff --git a/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/listener/ChangeKind.java b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/listener/ChangeKind.java
new file mode 100644
index 00000000000..c6e407ed35f
--- /dev/null
+++ b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/listener/ChangeKind.java
@@ -0,0 +1,7 @@
+package org.eclipse.papyrus.texteditor.cdt.listener;
+
+public enum ChangeKind {
+ INTERFACE,
+ IMPLEMENTATION,
+ OPERATION
+};
diff --git a/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/listener/Closure.java b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/listener/Closure.java
new file mode 100644
index 00000000000..b81203d94bc
--- /dev/null
+++ b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/listener/Closure.java
@@ -0,0 +1,81 @@
+/*****************************************************************************
+ * Copyright (c) 2013 CEA LIST.
+ *
+ *
+ * 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:
+ * Ansgar Radermacher (CEA LIST) Ansgar.Radermacher@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.texteditor.cdt.listener;
+
+import org.eclipse.emf.common.util.BasicEList;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature.Setting;
+import org.eclipse.uml2.common.util.UML2Util;
+import org.eclipse.uml2.uml.Association;
+import org.eclipse.uml2.uml.Classifier;
+import org.eclipse.uml2.uml.Element;
+
+/**
+ * Calculate the closure of classifiers that need to be re-generated, if a
+ * classifier changes
+ *
+ * There are two different reasons for the need to re-generate a classifier:
+ * (1) one of the elements that it contains has changed
+ * (2) an element outside the containment close is changed. An example is a superclass
+ * that changes its name or an association target. In many cases, classifier depend
+ * on names of outside elements, but the also require a regeneration if the element
+ * is deleted.
+ * We need to take the change-kind into account. E.g. if the name of an operation in A changes, we need to
+ * re-generate class A, but we only need to regenerate class B (inheriting from A), if it actually
+ * redefines that operation.
+ */
+public class Closure {
+ public static EList<Classifier> calc(Classifier cl) {
+ EList<Classifier> list = new BasicEList<Classifier>();
+ calc(cl, list);
+ return list;
+ }
+
+ public static void calc(Classifier cl, EList<Classifier> list) {
+ if (cl != null) {
+ for (Setting setting : UML2Util.getNonNavigableInverseReferences(cl)) {
+ EObject eObj = setting.getEObject();
+ if (eObj instanceof Element) {
+ Classifier referencedCl = nearestClassifier(eObj);
+ if (!list.contains(referencedCl) && (!(referencedCl instanceof Association))) {
+ list.add(referencedCl);
+ calc(referencedCl, list);
+ }
+ }
+ }
+ }
+ }
+
+ public static boolean isContained(EObject parent, EObject possibleChild) {
+ while (possibleChild != null) {
+ if (parent == possibleChild) {
+ return true;
+ }
+ possibleChild = possibleChild.eContainer();
+ }
+ return false;
+ }
+
+ public static Classifier nearestClassifier(EObject eObj) {
+ while (eObj != null) {
+ if (eObj instanceof Classifier) {
+ return (Classifier) eObj;
+ }
+ eObj = eObj.eContainer();
+ }
+ return null;
+ }
+}
diff --git a/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/listener/ModelListener.java b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/listener/ModelListener.java
new file mode 100644
index 00000000000..18bc74c536e
--- /dev/null
+++ b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/listener/ModelListener.java
@@ -0,0 +1,135 @@
+/*****************************************************************************
+ * Copyright (c) 2013 CEA LIST.
+ *
+ *
+ * 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:
+ * Ansgar Radermacher (CEA LIST) Ansgar.Radermacher@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.texteditor.cdt.listener;
+
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.UniqueEList;
+import org.eclipse.papyrus.infra.core.listenerservice.IPapyrusListener;
+import org.eclipse.papyrus.uml.tools.listeners.PapyrusStereotypeListener;
+import org.eclipse.uml2.uml.Behavior;
+import org.eclipse.uml2.uml.Classifier;
+import org.eclipse.uml2.uml.DirectedRelationship;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.Feature;
+import org.eclipse.uml2.uml.Package;
+import org.eclipse.uml2.uml.Parameter;
+
+/**
+ * Main listener for model changes (registered via plugin.xml). It will delegate
+ * to the sub-listeners for specific sub-elements (type, operation, port, ...) that
+ * can be found in this package
+ *
+ * @author ansgar
+ *
+ */
+public class ModelListener implements IPapyrusListener {
+
+ /**
+ * set to true, if a synchronization from an CDT editor to the model is active
+ */
+ public static boolean syncFromEditor;
+
+ @Override
+ public void notifyChanged(Notification notification) {
+ Object notifier = notification.getNotifier();
+ int eventType = notification.getEventType();
+ if (syncFromEditor) {
+ return;
+ }
+ if ((eventType == Notification.REMOVING_ADAPTER) ||
+ (eventType == Notification.RESOLVE)) {
+ // does not indicate a modification of the element
+ return;
+ }
+ // System.err.println(eventType + ": " + notifier);
+
+ OperationHistoryListener.init();
+ try {
+ // TODO: kind of get nearest classifier
+
+ if (notifier instanceof Classifier) {
+ Classifier classifier = (Classifier) notifier;
+ if ((eventType == Notification.REMOVE) ||
+ (eventType == PapyrusStereotypeListener.MODIFIED_STEREOTYPE)) {
+ regenList.add(classifier);
+ }
+ // don't treat addition here, since operations/properties do not have their final names yet
+ // IStorage storage = new TextStorage(string);
+ }
+ if (notifier instanceof Behavior) {
+ Behavior behavior = (Behavior) notifier;
+ if (eventType == Notification.SET) {
+ // name modification
+ if (behavior.getSpecification() == null) {
+ }
+ }
+ else if (eventType == Notification.ADD) {
+ // modification of an opaque behavior in Papyrus implied remove&add operations
+ Classifier nearestCl = getNearestClassifier(behavior);
+ if (nearestCl != null) {
+ regenList.add(nearestCl);
+ }
+ }
+ }
+
+ else if (notifier instanceof Feature) {
+ // if a feature is added, it is first generated with a dummy name, then the name is corrected.
+ Feature feature = (Feature) notifier;
+ Element owner = feature.getOwner();
+ if (owner instanceof Classifier) {
+ // System.out.println(owner);
+ regenList.add((Classifier) owner);
+ }
+ }
+ else if (notifier instanceof Parameter) {
+ Parameter parameter = (Parameter) notifier;
+ if (parameter.getOperation() != null) {
+ Element owner = parameter.getOperation().getOwner();
+ if (owner instanceof Classifier) {
+ // System.out.println(owner);
+ regenList.add((Classifier) owner);
+ }
+ }
+ }
+ else if (notifier instanceof DirectedRelationship) {
+ // if a feature is added, it is first generated with a dummy name, then the name is corrected.
+ DirectedRelationship dr = (DirectedRelationship) notifier;
+ for (Element client : dr.getSources()) {
+ if (client instanceof Classifier) {
+ // System.out.println(client);
+ regenList.add((Classifier) client);
+ }
+ }
+ }
+ else if (notifier instanceof Package) {
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static Classifier getNearestClassifier(Element element) {
+ while (element != null) {
+ if (!(element instanceof Behavior) && (element instanceof Classifier)) {
+ return (Classifier) element;
+ }
+ element = element.getOwner();
+ }
+ return null;
+ }
+
+ static EList<Classifier> regenList = new UniqueEList<Classifier>();
+}
diff --git a/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/listener/OperationHistoryListener.java b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/listener/OperationHistoryListener.java
new file mode 100644
index 00000000000..ca34d6ab0ba
--- /dev/null
+++ b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/listener/OperationHistoryListener.java
@@ -0,0 +1,76 @@
+/*****************************************************************************
+ * Copyright (c) 2013 CEA LIST.
+ *
+ *
+ * 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:
+ * Ansgar Radermacher (CEA LIST) Ansgar.Radermacher@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.texteditor.cdt.listener;
+
+import org.eclipse.core.commands.operations.IOperationHistoryListener;
+import org.eclipse.core.commands.operations.OperationHistoryEvent;
+import org.eclipse.core.commands.operations.OperationHistoryFactory;
+import org.eclipse.emf.common.util.BasicEList;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.papyrus.infra.core.resource.NotFoundException;
+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.utils.ServiceUtilsForEObject;
+import org.eclipse.papyrus.texteditor.cdt.Activator;
+import org.eclipse.papyrus.texteditor.cdt.modelresource.TextEditorModelSharedResource;
+import org.eclipse.papyrus.texteditor.cdt.sync.SyncModelToCDT;
+import org.eclipse.papyrus.texteditor.model.texteditormodel.TextEditorModel;
+import org.eclipse.uml2.uml.Classifier;
+
+public class OperationHistoryListener implements IOperationHistoryListener {
+
+ public static void init() {
+ if (ohl == null) {
+ ohl = new OperationHistoryListener();
+ OperationHistoryFactory.getOperationHistory().addOperationHistoryListener(ohl);
+ }
+ }
+
+ private static OperationHistoryListener ohl = null;
+
+ @Override
+ public void historyNotification(OperationHistoryEvent event) {
+ int eventType = event.getEventType();
+ if (eventType == OperationHistoryEvent.OPERATION_ADDED || eventType == OperationHistoryEvent.REDONE
+ || eventType == OperationHistoryEvent.UNDONE) {
+
+ EList<Classifier> regenListCopy = new BasicEList<Classifier>(ModelListener.regenList);
+ ModelListener.regenList.clear();
+
+ // re-generate files from list - if they are still in a resource
+ for (Classifier cl : regenListCopy) {
+ if (cl.eResource() != null) {
+ try {
+ ServicesRegistry serviceRegistry = ServiceUtilsForEObject.getInstance().getServiceRegistry(cl);
+ TextEditorModelSharedResource model = (TextEditorModelSharedResource) ServiceUtils.getInstance()
+ .getModelSet(serviceRegistry).getModelChecked(TextEditorModelSharedResource.MODEL_ID);
+
+ if (model != null) {
+ TextEditorModel tem = model.getTextEditorModel(cl);
+ if (tem != null) {
+ SyncModelToCDT.syncModelToCDT(cl, tem.getGeneratorID());
+ }
+ }
+ } catch (ServiceException e) {
+ Activator.log.error(e);
+ } catch (NotFoundException e) {
+ Activator.log.error(e);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/modelresource/TextEditorModelSharedResource.java b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/modelresource/TextEditorModelSharedResource.java
new file mode 100644
index 00000000000..7781972dd12
--- /dev/null
+++ b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/modelresource/TextEditorModelSharedResource.java
@@ -0,0 +1,120 @@
+/*****************************************************************************
+ * Copyright (c) 2013 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.texteditor.cdt.modelresource;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.papyrus.infra.core.resource.AbstractModelWithSharedResource;
+import org.eclipse.papyrus.infra.core.resource.IModel;
+import org.eclipse.papyrus.texteditor.model.texteditormodel.TextEditorModel;
+
+
+public class TextEditorModelSharedResource extends AbstractModelWithSharedResource<TextEditorModel> implements IModel {
+
+
+ /**
+ * File extension used for notation.
+ */
+ public static final String NOTATION_FILE_EXTENSION = "notation"; //$NON-NLS-1$
+
+ /**
+ * Model ID.
+ */
+ public static final String MODEL_ID = "org.eclipse.papyrus.exteditor.cdt.CDTEditorModelSharedResource"; //$NON-NLS-1$
+
+
+ /**
+ *
+ * Constructor.
+ *
+ */
+ public TextEditorModelSharedResource() {
+
+ }
+
+
+ /**
+ * Get the file extension used for this model.
+ *
+ * @see org.eclipse.papyrus.infra.core.resource.AbstractBaseModel#getModelFileExtension()
+ *
+ * @return
+ */
+ @Override
+ protected String getModelFileExtension() {
+ return NOTATION_FILE_EXTENSION;
+ }
+
+ /**
+ * Get the identifier used to register this model.
+ *
+ * @see org.eclipse.papyrus.infra.core.resource.AbstractBaseModel#getIdentifier()
+ *
+ * @return
+ */
+ @Override
+ public String getIdentifier() {
+ return MODEL_ID;
+ }
+
+
+ /**
+ * Add a new initialized {@link TextEditorModel} to the model.
+ *
+ * @param textInstance
+ * The textInstance to add.
+ */
+ public void addTextEditorModel(TextEditorModel textInstance) {
+ getResource().getContents().add(textInstance);
+ }
+
+ /**
+ * Add a new initialized {@link PapyrustextInstance} to the model.
+ *
+ * @param textInstance
+ * The textInstance to add.
+ */
+ public void removeTextEditorModel(TextEditorModel textInstance) {
+ getResource().getContents().remove(textInstance);
+ }
+
+ /**
+ * @param editedObject
+ * an edited element
+ * @return an editor reference for a given object if an editor exists, or null
+ */
+ public TextEditorModel getTextEditorModel(EObject editedObject) {
+ for (EObject textInstanceEO : getResource().getContents()) {
+ if (textInstanceEO instanceof TextEditorModel) {
+ TextEditorModel textInstance = (TextEditorModel) textInstanceEO;
+ if (textInstance.getEditedObject() == editedObject) {
+ return textInstance;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.core.resource.AbstractModelWithSharedResource#isModelRoot(org.eclipse.emf.ecore.EObject)
+ *
+ * @param object
+ * @return
+ */
+ @Override
+ protected boolean isModelRoot(EObject object) {
+ return false;
+ }
+
+}
diff --git a/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/preferences/CDTPreferenceConstants.java b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/preferences/CDTPreferenceConstants.java
new file mode 100644
index 00000000000..ca20cafca87
--- /dev/null
+++ b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/preferences/CDTPreferenceConstants.java
@@ -0,0 +1,33 @@
+/*****************************************************************************
+ * Copyright (c) 2013 CEA LIST.
+ *
+ *
+ * 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:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.texteditor.cdt.preferences;
+
+/**
+ * Constant definitions for plug-in preferences
+ */
+public class CDTPreferenceConstants {
+
+ /**
+ * Default option for opening the editor at a specified location. Store uses directly the SWT constants
+ */
+ public static final String P_OPEN_LOCATION = "openLocation"; //$NON-NLS-1$
+
+ /**
+ * For attributes, the default "aggregation kind" value is "none". When this option is set
+ * it will be treated as composite
+ */
+ public static final String P_SYNC_PERMANENTLY = "syncPermanently"; //$NON-NLS-1$
+
+ public static final String P_SYNC_ALL_FILES = "syncAllFiles"; //$NON-NLS-1$
+}
diff --git a/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/preferences/CDTPreferenceInitializer.java b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/preferences/CDTPreferenceInitializer.java
new file mode 100644
index 00000000000..494838690c5
--- /dev/null
+++ b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/preferences/CDTPreferenceInitializer.java
@@ -0,0 +1,39 @@
+/*****************************************************************************
+ * Copyright (c) 2013 CEA LIST.
+ *
+ *
+ * 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:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.texteditor.cdt.preferences;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.papyrus.texteditor.cdt.Activator;
+import org.eclipse.swt.SWT;
+
+/**
+ * Class used to initialize default preference values.
+ */
+public class CDTPreferenceInitializer extends AbstractPreferenceInitializer {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#initializeDefaultPreferences()
+ */
+ @Override
+ public void initializeDefaultPreferences() {
+ IPreferenceStore store = Activator.getDefault().getPreferenceStore();
+ store.setDefault(CDTPreferenceConstants.P_OPEN_LOCATION, SWT.RIGHT);
+ store.setDefault(CDTPreferenceConstants.P_SYNC_ALL_FILES, false);
+ store.setDefault(CDTPreferenceConstants.P_SYNC_PERMANENTLY, false);
+ }
+}
diff --git a/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/preferences/CDTPreferencePage.java b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/preferences/CDTPreferencePage.java
new file mode 100644
index 00000000000..efc94febace
--- /dev/null
+++ b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/preferences/CDTPreferencePage.java
@@ -0,0 +1,64 @@
+/*****************************************************************************
+ * Copyright (c) 2013 CEA LIST.
+ *
+ *
+ * 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:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.texteditor.cdt.preferences;
+
+import org.eclipse.jface.preference.BooleanFieldEditor;
+import org.eclipse.jface.preference.FieldEditorPreferencePage;
+import org.eclipse.papyrus.texteditor.cdt.Activator;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+
+
+/**
+ * This class represents the EC3M preference page
+ * <p>
+ * This page is used to modify preferences only. They are stored in the preference store that belongs to the main plug-in class. That way, preferences can be accessed directly via the preference store.
+ */
+
+public class CDTPreferencePage
+ extends FieldEditorPreferencePage
+ implements IWorkbenchPreferencePage {
+
+ public CDTPreferencePage() {
+ super(GRID);
+ setPreferenceStore(Activator.getDefault().getPreferenceStore());
+ setDescription("CDT editor integration options"); //$NON-NLS-1$
+ }
+
+ /**
+ * Creates the field editors. Field editors are abstractions of
+ * the common GUI blocks needed to manipulate various types
+ * of preferences. Each field editor knows how to save and
+ * restore itself.
+ */
+ @Override
+ public void createFieldEditors() {
+ addField(new BooleanFieldEditor(
+ CDTPreferenceConstants.P_SYNC_PERMANENTLY, "&Synchronize permanently (otherwise only on demand)", //$NON-NLS-1$
+ getFieldEditorParent()));
+
+ addField(new BooleanFieldEditor(
+ CDTPreferenceConstants.P_SYNC_ALL_FILES, "Synchronize all classes (otherwise synchronize only classes with open editor)", //$NON-NLS-1$
+ getFieldEditorParent()));
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
+ */
+ @Override
+ public void init(IWorkbench workbench) {
+ }
+}
diff --git a/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/sync/FindTransition.java b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/sync/FindTransition.java
new file mode 100644
index 00000000000..e737e45abf3
--- /dev/null
+++ b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/sync/FindTransition.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2013 CEA LIST.
+ * 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:
+ * Ansgar Radermacher - ansgar.radermacher@cea.fr CEA LIST - initial API and implementation
+ *
+ *******************************************************************************/
+
+package org.eclipse.papyrus.texteditor.cdt.sync;
+
+import org.eclipse.uml2.uml.Behavior;
+import org.eclipse.uml2.uml.Classifier;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.Transition;
+
+/**
+ * Find the behavior in the model from a given method in the code. Used during the
+ * back synchronization from code to model.
+ */
+public class FindTransition {
+
+ private static final String UNDERSCORE = "_"; //$NON-NLS-1$
+
+ public static Behavior findBehavior(Classifier cl, String methodName) {
+ for (Element element : cl.allOwnedElements()) {
+ if (element instanceof Transition) {
+ Transition transition = (Transition) element;
+ Behavior effect = transition.getEffect();
+ if ((effect != null) && behaviorMatches(effect, methodName)) {
+ return transition.getEffect();
+ }
+ }
+ }
+ return null;
+ }
+
+ public static boolean behaviorMatches(Behavior behavior, String methodName) {
+ return
+ methodName.endsWith(NamedElement.SEPARATOR + behavior.getName()) ||
+ methodName.endsWith(UNDERSCORE + behavior.getName());
+ }
+}
diff --git a/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/sync/ObtainICElement.java b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/sync/ObtainICElement.java
new file mode 100644
index 00000000000..e5457380c45
--- /dev/null
+++ b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/sync/ObtainICElement.java
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright (c) 2015 CEA LIST.
+ * 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:
+ * Ansgar Radermacher - ansgar.radermacher@cea.fr CEA LIST - initial API and implementation
+ *
+ *******************************************************************************/
+
+package org.eclipse.papyrus.texteditor.cdt.sync;
+
+import java.util.Iterator;
+
+import org.eclipse.cdt.core.model.ICElement;
+import org.eclipse.cdt.core.model.IFunctionDeclaration;
+import org.eclipse.cdt.core.model.IParent;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.papyrus.codegen.extensionpoints.ILangCodegen;
+import org.eclipse.papyrus.codegen.extensionpoints.ILangCodegen2;
+import org.eclipse.papyrus.codegen.extensionpoints.MethodInfo;
+import org.eclipse.uml2.uml.Behavior;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.Operation;
+import org.eclipse.uml2.uml.Parameter;
+import org.eclipse.uml2.uml.ParameterDirectionKind;
+import org.eclipse.uml2.uml.Transition;
+
+
+/**
+ * This class is used to select the operation the user wants to edit after opening the editor.
+ * In case of transition, the selection is based on simple name only (either prefixed with the name separator or with an
+ * underscore - based on the assumption that scoped names are either kept or flattened using underscore as separator
+ *
+ */
+public class ObtainICElement {
+
+ /**
+ * Return the ICelement associated with a UML element. Currently, only methods are supported.
+ *
+ * @param parent
+ * the parent (typically the translation unit of a CDT file)
+ * @param element
+ * A named UML element
+ * @throws CoreException
+ */
+ public static ICElement getICElement(ILangCodegen codegen, IParent parent, NamedElement element) {
+ MethodInfo methodInfo = null;
+ NamedElement operationOrBehavior = element;
+ if (element instanceof Transition) {
+ operationOrBehavior = ((Transition) element).getEffect();
+ }
+
+ // no behavior found => not possible to locate element
+ if (operationOrBehavior == null) {
+ return null;
+ }
+
+ if (codegen instanceof ILangCodegen2) {
+ // get generator specific method info.
+ methodInfo = ((ILangCodegen2) codegen).getMethodInfo(operationOrBehavior);
+ }
+ if (methodInfo == null) {
+ // use default behavior.
+ if (element instanceof Behavior) {
+ methodInfo = MethodInfo.fromBehavior((Behavior) operationOrBehavior);
+ }
+ else if (element instanceof Operation) {
+ methodInfo = MethodInfo.fromOperation((Operation) operationOrBehavior);
+ }
+ else {
+ return null;
+ }
+ }
+
+ try {
+ for (ICElement child : parent.getChildren()) {
+ if (child instanceof IParent) {
+ return getICElement(codegen, (IParent) child, element);
+ }
+ if (child instanceof IFunctionDeclaration) {
+ IFunctionDeclaration function = (IFunctionDeclaration) child;
+
+ // does the element name match? (CDT provides className::methodName information). Since we are in the scope of
+ // the class, we only verify the postfix part of the name
+ if (child.getElementName().endsWith(NamedElement.SEPARATOR + methodInfo.getName())) {
+ // check, if parameters match. This handles most common overloading cases (it does not handle functions that
+ // only differ with respect to the modifiers
+ Iterator<String> paramIter = methodInfo.getParameterTypes().iterator();
+ boolean match = methodInfo.getParameterTypes().size() == function.getParameterTypes().length;
+ if (match) {
+ for (String cdtParamType : function.getParameterTypes()) {
+ String umlParamType = paramIter.next();
+ if (!cdtParamType.equals(umlParamType)) {
+ match = false;
+ break;
+ }
+ }
+ if (match) {
+ return child;
+ }
+ }
+ }
+ }
+ }
+ } catch (CoreException e) {
+ }
+ return null;
+ }
+
+ /**
+ * Count the number of parameters without taking the return parameter into account
+ *
+ * @param list
+ * @return
+ */
+ public static int countParameters(EList<Parameter> list) {
+ int params = 0;
+ for (Parameter par : list) {
+ if (par.getDirection() != ParameterDirectionKind.RETURN_LITERAL) {
+ params++;
+ }
+ }
+ return params;
+ }
+}
diff --git a/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/sync/ParameterModifiers.java b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/sync/ParameterModifiers.java
new file mode 100644
index 00000000000..8601ac73484
--- /dev/null
+++ b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/sync/ParameterModifiers.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2013 CEA LIST.
+ * 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:
+ * Ansgar Radermacher - ansgar.radermacher@cea.fr CEA LIST - initial API and implementation
+ *
+ *******************************************************************************/
+
+package org.eclipse.papyrus.texteditor.cdt.sync;
+
+/**
+ * Simple grouping of modifier related parameters
+ */
+public class ParameterModifiers {
+ public ParameterModifiers() {
+ isPointer = false;
+ isRef = false;
+ isRegister = false;
+ array = ""; //$NON-NLS-1$
+ }
+
+ /**
+ * true, if parameter is a pointer
+ */
+ boolean isPointer;
+
+ /**
+ * true, if parameter is a reference
+ */
+ boolean isRef;
+
+ /**
+ * true, if parameter is a register
+ */
+ boolean isRegister;
+
+ /**
+ * value of array modifiers (e.g. [2])
+ */
+ String array ;
+}
diff --git a/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/sync/RevealCurrentOperation.java b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/sync/RevealCurrentOperation.java
new file mode 100644
index 00000000000..cf53a0b5468
--- /dev/null
+++ b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/sync/RevealCurrentOperation.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (c) 2015 CEA LIST.
+ * 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:
+ * Ansgar Radermacher - ansgar.radermacher@cea.fr CEA LIST - initial API and implementation
+ *
+ *******************************************************************************/
+
+package org.eclipse.papyrus.texteditor.cdt.sync;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.dom.ast.IASTNodeSelector;
+import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
+import org.eclipse.cdt.core.index.IIndex;
+import org.eclipse.cdt.core.model.CModelException;
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.model.ICElement;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.core.model.IFunctionDeclaration;
+import org.eclipse.cdt.core.model.IParent;
+import org.eclipse.cdt.core.model.ISourceRange;
+import org.eclipse.cdt.core.model.ISourceReference;
+import org.eclipse.cdt.core.model.ITranslationUnit;
+import org.eclipse.cdt.ui.CDTUITools;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.papyrus.infra.core.Activator;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.uml2.uml.Classifier;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.Operation;
+
+
+public class RevealCurrentOperation {
+
+ public RevealCurrentOperation(IEditorInput input, Classifier classifier, String projectName) {
+ m_input = input;
+ m_classifier = classifier;
+ m_projectName = projectName;
+ }
+
+ public Element obtainSelectedElement(ITextSelection selection) {
+ ICElement ice = CDTUITools.getEditorInputCElement(m_input);
+
+ if (ice instanceof ITranslationUnit) {
+ ICProject project = CoreModel.getDefault().getCModel().getCProject(m_projectName);
+
+ IIndex index = null;
+ try {
+ index = CCorePlugin.getIndexManager().getIndex(project);
+ index.acquireReadLock();
+
+ // index = CCorePlugin.getIndexManager().getIndex(project);
+ ITranslationUnit itu = (ITranslationUnit) ice;
+ // hack: force re-evaluation of AST node, requires modified CDT!
+ // Seems to be no longer required.
+ // ASTProvider.getASTProvider().fCache.setActiveElement(itu);
+
+ IASTTranslationUnit ast = itu.getAST(index, ITranslationUnit.AST_SKIP_INDEXED_HEADERS);
+ IASTNodeSelector selector = ast.getNodeSelector(null);
+
+ String opName = findOperation(itu, selector, itu, selection);
+ if (opName != null) {
+ int sep = opName.lastIndexOf("::"); //$NON-NLS-1$
+ if (sep != -1) {
+ opName = opName.substring(sep + 2);
+ }
+ Operation operation = m_classifier.getOperation(opName, null, null);
+ if (operation != null) {
+ return operation;
+ }
+ }
+
+ } catch (CModelException e) {
+ Activator.getDefault().getLog().log(e.getStatus());
+ } catch (Exception e) {
+ System.err.println(e);
+ } finally {
+ if (index != null) {
+ index.releaseReadLock();
+ }
+ }
+ }
+ return m_classifier;
+ }
+
+ /**
+ * Examine the children of a translation unit in order to extract the methods that are defined within
+ * the unit
+ *
+ * @param itu
+ * @param selector
+ * @param parent
+ * @throws CModelException
+ */
+ public String findOperation(ITranslationUnit itu, IASTNodeSelector selector, IParent parent, ITextSelection selection) throws CModelException {
+
+ for (ICElement child : parent.getChildren()) {
+ if (child instanceof IParent) {
+ return findOperation(itu, selector, (IParent) child, selection);
+ }
+ ISourceRange range = null;
+ if (child instanceof ISourceReference) {
+ range = ((ISourceReference) child).getSourceRange();
+ }
+ if (child instanceof IFunctionDeclaration) {
+ // function declaration is a superclass for method declaration (but need to trace functions differently?)
+ String name = ((IFunctionDeclaration) child).getElementName();
+ int pos = selection.getOffset();
+ if ((pos >= range.getStartPos()) && (pos < range.getStartPos() + range.getLength())) {
+ return name;
+ }
+ }
+ }
+ return null;
+ }
+
+
+
+ protected IEditorInput m_input;
+
+ protected Classifier m_classifier;
+
+ protected String m_projectName;
+}
diff --git a/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/sync/SyncCDTtoModel.java b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/sync/SyncCDTtoModel.java
new file mode 100644
index 00000000000..1a0d635b974
--- /dev/null
+++ b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/sync/SyncCDTtoModel.java
@@ -0,0 +1,635 @@
+/*******************************************************************************
+ * Copyright (c) 2013 CEA LIST.
+ * 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:
+ * Ansgar Radermacher - ansgar.radermacher@cea.fr CEA LIST - initial API and implementation
+ *
+ *******************************************************************************/
+
+package org.eclipse.papyrus.texteditor.cdt.sync;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.dom.ast.ExpansionOverlapsBoundaryException;
+import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
+import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
+import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
+import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
+import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
+import org.eclipse.cdt.core.dom.ast.IASTName;
+import org.eclipse.cdt.core.dom.ast.IASTNode;
+import org.eclipse.cdt.core.dom.ast.IASTNodeSelector;
+import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
+import org.eclipse.cdt.core.dom.ast.IASTStatement;
+import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
+import org.eclipse.cdt.core.index.IIndex;
+import org.eclipse.cdt.core.model.CModelException;
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.model.ICElement;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.core.model.IFunctionDeclaration;
+import org.eclipse.cdt.core.model.IMethodDeclaration;
+import org.eclipse.cdt.core.model.IParent;
+import org.eclipse.cdt.core.model.ISourceRange;
+import org.eclipse.cdt.core.model.ISourceReference;
+import org.eclipse.cdt.core.model.ITranslationUnit;
+import org.eclipse.cdt.core.model.IWorkingCopy;
+import org.eclipse.cdt.core.parser.IToken;
+import org.eclipse.cdt.ui.CDTUITools;
+import org.eclipse.cdt.ui.CUIPlugin;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.papyrus.C_Cpp.Array;
+import org.eclipse.papyrus.C_Cpp.Const;
+import org.eclipse.papyrus.C_Cpp.EStorageClass;
+import org.eclipse.papyrus.C_Cpp.Include;
+import org.eclipse.papyrus.C_Cpp.Ptr;
+import org.eclipse.papyrus.C_Cpp.Ref;
+import org.eclipse.papyrus.C_Cpp.StorageClass;
+import org.eclipse.papyrus.C_Cpp.Volatile;
+import org.eclipse.papyrus.codegen.extensionpoints.ILangCodegen;
+import org.eclipse.papyrus.codegen.extensionpoints.ILangCodegen2;
+import org.eclipse.papyrus.codegen.extensionpoints.LanguageCodegen;
+import org.eclipse.papyrus.codegen.extensionpoints.SyncInformation;
+import org.eclipse.papyrus.cpp.codegen.Constants;
+import org.eclipse.papyrus.infra.core.Activator;
+import org.eclipse.papyrus.texteditor.cdt.CommandSupport;
+import org.eclipse.papyrus.texteditor.cdt.TextEditorConstants;
+import org.eclipse.papyrus.texteditor.cdt.Utils;
+import org.eclipse.papyrus.texteditor.cdt.listener.ModelListener;
+import org.eclipse.papyrus.uml.tools.utils.StereotypeUtil;
+import org.eclipse.papyrus.uml.tools.utils.UMLUtil;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.uml2.uml.Behavior;
+import org.eclipse.uml2.uml.BehavioralFeature;
+import org.eclipse.uml2.uml.Class;
+import org.eclipse.uml2.uml.Classifier;
+import org.eclipse.uml2.uml.Comment;
+import org.eclipse.uml2.uml.DataType;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.OpaqueBehavior;
+import org.eclipse.uml2.uml.Operation;
+import org.eclipse.uml2.uml.Parameter;
+import org.eclipse.uml2.uml.Type;
+import org.eclipse.uml2.uml.UMLPackage;
+
+public class SyncCDTtoModel implements Runnable {
+
+ public static final String REGISTER = "register"; //$NON-NLS-1$
+
+ public static final String CONST = "const"; //$NON-NLS-1$
+
+ public static final String VOLATILE = "volatile"; //$NON-NLS-1$
+
+ public static final String sAtParam = "@param"; //$NON-NLS-1$
+
+ public static final String ansiCLib = "AnsiCLibrary"; //$NON-NLS-1$
+
+ public SyncCDTtoModel(IEditorInput input, Classifier classifier, String projectName, String generatorID) {
+ m_input = input;
+ m_classifier = classifier;
+ m_projectName = projectName;
+ m_codegen = LanguageCodegen.getGenerator(TextEditorConstants.CPP, generatorID);
+ }
+
+
+ public final String c_cpp_langID = "C/C++"; //$NON-NLS-1$
+
+ public void syncCDTtoModel() {
+ CommandSupport.exec("update model from CDT", this);
+ }
+
+ @Override
+ public void run() {
+ ICElement ice = CDTUITools.getEditorInputCElement(m_input);
+ ModelListener.syncFromEditor = true;
+
+ if (ice instanceof ITranslationUnit) {
+ ICProject project = CoreModel.getDefault().getCModel().getCProject(m_projectName);
+
+ IIndex index = null;
+ try {
+ index = CCorePlugin.getIndexManager().getIndex(project);
+ index.acquireReadLock();
+
+ // index = CCorePlugin.getIndexManager().getIndex(project);
+ ITranslationUnit itu = (ITranslationUnit) ice;
+ // hack: force re-evaluation of AST node, requires modified CDT!
+ // Seems to be no longer required.
+ // ASTProvider.getASTProvider().fCache.setActiveElement(itu);
+
+ IASTTranslationUnit ast = itu.getAST(index, ITranslationUnit.AST_SKIP_INDEXED_HEADERS);
+ IASTNodeSelector selector = ast.getNodeSelector(null);
+
+ examineChildren(itu, selector, itu);
+ updateCppInclude(itu);
+
+ CUIPlugin.getDefault().getProblemMarkerManager();
+ if (itu instanceof IWorkingCopy) {
+ // ((IWorkingCopy)itu).commit(true, new
+ // NullProgressMonitor());
+ // ((IWorkingCopy)itu).reconcile();
+ ((IWorkingCopy) itu).reconcile(true, new NullProgressMonitor());
+ // ((IWorkingCopy)itu).reconcile(true, true, new
+ // NullProgressMonitor());
+ }
+
+ } catch (CModelException e) {
+ Activator.getDefault().getLog().log(e.getStatus());
+ } catch (Exception e) {
+ System.err.println(e);
+ } finally {
+ if (index != null) {
+ index.releaseReadLock();
+ }
+ }
+ }
+ ModelListener.syncFromEditor = false;
+ }
+
+ /**
+ * Examine the children of a translation unit in order to extract the
+ * methods that are defined within hte unit
+ *
+ * @param itu
+ * @param selector
+ * @param parent
+ * @throws CModelException
+ */
+ public void examineChildren(ITranslationUnit itu, IASTNodeSelector selector, IParent parent)
+ throws CModelException {
+
+ int position = 0;
+ // if (parent instanceof Namespace) {
+ for (ICElement child : parent.getChildren()) {
+ if (child instanceof IParent) {
+ examineChildren(itu, selector, (IParent) child);
+ }
+ ISourceRange range = null;
+ if (child instanceof ISourceReference) {
+ range = ((ISourceReference) child).getSourceRange();
+ }
+ if (child instanceof IFunctionDeclaration) {
+ // function declaration is a superclass for method declaration
+ // (but need to trace functions differently?)
+ String name = ((IFunctionDeclaration) child).getElementName();
+ IASTNode node = selector.findEnclosingNode(range.getStartPos(), range.getLength());
+ if (node instanceof IASTFunctionDefinition) {
+ IASTFunctionDefinition definition = (IASTFunctionDefinition) node;
+ IASTFunctionDeclarator declarator = definition.getDeclarator();
+ String unfilteredBody = getBody(itu, definition);
+ // get additional information about method synchronization from generator
+ SyncInformation syncInfo = null;
+ if (m_codegen instanceof ILangCodegen2) {
+ syncInfo = ((ILangCodegen2) m_codegen).getSyncInformation(name, unfilteredBody);
+ }
+ String body = Utils.removeGenerated(unfilteredBody);
+ if (syncInfo == null || !syncInfo.isGenerated) {
+ // only update method, if it is not generated
+ NamedElement ne = updateMethod(position, parent, name, body, declarator, syncInfo);
+ updateComment(itu, definition, ne);
+ }
+ // System.err.println("body source <" + body + ">");
+ }
+ position++;
+ }
+ }
+ }
+
+ /**
+ * update the contents of the CppInclude directive
+ *
+ * @param itu
+ * the translation unit
+ */
+ public void updateCppInclude(ITranslationUnit itu) {
+ String contents = new String(itu.getContents());
+ int preBodyStart = contents.indexOf(Constants.cppIncPreBodyStart);
+ int preBodyEnd = contents.indexOf(Constants.cppIncPreBodyEnd);
+ String preBody = ""; //$NON-NLS-1$
+ String body = ""; //$NON-NLS-1$
+ if (preBodyStart != -1) {
+ preBodyStart += Constants.cppIncPreBodyStart.length();
+ if (preBodyEnd > preBodyStart) {
+ preBody = contents.substring(preBodyStart, preBodyEnd).trim();
+ }
+ }
+
+ int bodyStart = contents.indexOf(Constants.cppIncBodyStart);
+ int bodyEnd = contents.indexOf(Constants.cppIncBodyEnd);
+
+ if (bodyStart != -1) {
+ bodyStart += Constants.cppIncBodyStart.length() + 1;
+ if (bodyEnd > bodyStart) {
+ body = contents.substring(bodyStart, bodyEnd).trim();
+ }
+ }
+ if (body.length() > 0 || preBody.length() > 0) {
+ Include include = StereotypeUtil.applyApp(m_classifier, Include.class);
+ if (include != null) {
+ include.setPreBody(preBody);
+ include.setBody(body);
+ }
+ }
+ }
+
+ /**
+ * Update a method in the model based on the qualified name.
+ *
+ * @param position
+ * The position of the method within the file. Used to identify
+ * renaming operations
+ * @param parent
+ * the CDT parent which is used to get a list of children
+ * @param qualifiedName
+ * the qualified name of a method
+ * @param body
+ * the method body
+ * @param declarator
+ * the declarator for the method
+ * @return the operation or the behavior within the model that got updated. The latter is returned in
+ * case of behaviors that do not have a specification (e.g. the effect of a transition).
+ */
+ public NamedElement updateMethod(int position, IParent parent, String qualifiedName, String body,
+ IASTFunctionDeclarator declarator, SyncInformation syncInfo) {
+
+ String names[] = qualifiedName.split(Utils.nsSep);
+ String name = names[names.length - 1];
+
+ Operation operation = null;
+ Behavior behavior = null;
+
+ if (syncInfo == null || (syncInfo.behavior == null && syncInfo.createBehaviorName == null)) {
+ operation = getModelOperationFromName(name, parent, position);
+ if (operation != null) {
+ operation.setName(name);
+ } else {
+ // it is possible that the C++ method corresponds to the effect
+ // of a transition. try to locate the behavior (without using an operation)
+ behavior = FindTransition.findBehavior(m_classifier, name);
+ if (behavior == null) {
+ // still null => create new operation in model
+ if (m_classifier instanceof Class) {
+ operation = ((Class) m_classifier).createOwnedOperation(name, null, null);
+ } else if (m_classifier instanceof DataType) {
+ operation = ((DataType) m_classifier).createOwnedOperation(name, null, null);
+ }
+ }
+ }
+ }
+ else if (syncInfo.behavior != null) {
+ // operation is still null (=> does not enter operation != null case below)
+ behavior = syncInfo.behavior;
+ }
+ else if ((syncInfo.createBehaviorName != null) && (m_classifier instanceof Class)) {
+ Class clazz = (Class) m_classifier;
+ behavior = (OpaqueBehavior) clazz.createOwnedBehavior(syncInfo.createBehaviorName,
+ UMLPackage.eINSTANCE.getOpaqueBehavior().eClass());
+ }
+
+ if (operation != null) {
+ if (operation.getMethods().size() == 0) {
+ // operation exists, but does not have any method => create
+
+ if (m_classifier instanceof Class) {
+ behavior = ((Class) m_classifier).createOwnedBehavior(name, UMLPackage.eINSTANCE.getOpaqueBehavior());
+ } else if (m_classifier instanceof DataType) {
+ // ob = (OpaqueBehavior) ((DataType)
+ // m_classifier).createOwnedBehavior(name,
+ // UMLPackage.eINSTANCE.getOpaqueBehavior());
+ }
+ behavior.setSpecification(operation);
+ behavior.setIsReentrant(false);
+ }
+ else {
+ behavior = operation.getMethods().get(0);
+ // operation has at least one method, this may not be null.
+ if (!behavior.getName().equals(name)) {
+ behavior.setName(name);
+ }
+ }
+ }
+
+ // assertions: operation can be null, behavior is always non-null
+
+ // Remove all parameters from operation / behavior (they will be added later).
+ // Calling parameters.clear() is not sufficient. Otherwise stereotype
+ // applications to unresolved elements remain in the model
+ if (operation != null) {
+ UMLUtil.destroyElements(operation.getOwnedParameters());
+ }
+ UMLUtil.destroyElements(behavior.getOwnedParameters());
+
+ for (IASTNode declaratorChild : declarator.getChildren()) {
+ if (declaratorChild instanceof IASTParameterDeclaration) {
+ IASTParameterDeclaration parameter = (IASTParameterDeclaration) declaratorChild;
+ IASTName parameterName = parameter.getDeclarator().getName();
+ IASTDeclSpecifier parameterType = parameter.getDeclSpecifier();
+ ParameterModifiers modifiers = new ParameterModifiers();
+ String parameterTypeName = ""; //$NON-NLS-1$
+ try {
+ IToken token = parameter.getDeclarator().getSyntax();
+ while (token != null) {
+ String tokenStr = token.toString();
+ if (tokenStr.equals("*")) { //$NON-NLS-1$
+ modifiers.isPointer = true;
+ } else if (tokenStr.equals("&")) { //$NON-NLS-1$
+ modifiers.isRef = true;
+ } else if (tokenStr.equals("[")) { //$NON-NLS-1$
+ while (token != null) {
+ modifiers.array += token.toString();
+ token = token.getNext();
+ }
+ if (token == null) {
+ break;
+ }
+ }
+ token = token.getNext();
+ }
+
+ token = parameterType.getSyntax();
+ while (token != null) {
+ String tokenStr = token.toString();
+ if (tokenStr.equals("*")) { //$NON-NLS-1$
+ // TODO: check, if this can be called (depending on
+ // * position with different semantics?)
+ modifiers.isPointer = true;
+ } else if (tokenStr.equals("&")) { //$NON-NLS-1$
+ modifiers.isRef = true;
+ } else if (tokenStr.equals(REGISTER)) {
+ modifiers.isRegister = true;
+ } else if (tokenStr.equals(CONST) || tokenStr.equals(VOLATILE)) {
+ // do nothing (use isConst() or isVolatile() operation of parameterType)
+ // is not part of parameter type
+ } else {
+ if (parameterTypeName.length() > 0) {
+ parameterTypeName += " "; //$NON-NLS-1$
+ }
+ parameterTypeName += tokenStr;
+ }
+ token = token.getNext();
+ }
+ } catch (ExpansionOverlapsBoundaryException e) {
+ }
+
+ NamedElement namedElemParamType = Utils.getQualifiedElement(Utils.getTop(m_classifier),
+ parameterTypeName);
+ if (namedElemParamType == null) {
+ namedElemParamType = Utils.getQualifiedElement(Utils.getTop(m_classifier),
+ ansiCLib + Utils.nsSep + parameterTypeName);
+ }
+ if (parameterType.isRestrict()) {
+ }
+ Parameter umlParameter = null;
+ Type paramType = namedElemParamType instanceof Type ? (Type) namedElemParamType : null;
+ if (operation != null) {
+ umlParameter = operation.createOwnedParameter(parameterName.toString(), paramType);
+ applyParameterModifiers(parameterType, umlParameter, modifiers);
+ }
+ umlParameter = behavior.createOwnedParameter(parameterName.toString(), paramType);
+ applyParameterModifiers(parameterType, umlParameter, modifiers);
+ }
+ }
+
+ if (behavior instanceof OpaqueBehavior) {
+ OpaqueBehavior ob = (OpaqueBehavior) behavior;
+ if (ob.getBodies().size() == 0) {
+ ob.getLanguages().add(c_cpp_langID);
+ ob.getBodies().add(""); //$NON-NLS-1$
+ }
+ for (int i = 0; i < ob.getLanguages().size(); i++) {
+ // update first body of one of the languages supported by CDT. This implies that
+ // it is actually not possible to have separate C and C++ bodes in the same opaque
+ // behavior (which is rarely a good idea).
+ String language = ob.getLanguages().get(i);
+ if (TextEditorConstants.CPP.matcher(language).matches() || c_cpp_langID.equals(language)) {
+ if (i < ob.getBodies().size()) {
+ // should always be true, unless sync between
+ // languages/bodies is lost
+ ob.getBodies().set(i, body);
+ }
+ }
+ }
+ }
+ if (operation != null) {
+ return operation;
+ }
+ else {
+ return behavior;
+ }
+ }
+
+ /**
+ * Apply the modifiers for a parameter, notably the stereotypes of the C++ profile
+ *
+ * @param parameterType the CDT AST parameter specification
+ * @param umlParameter the UML parameter (to which a stereotype should be applied)
+ * @param modifiers the modifiers that should be applied (stored in an instance of class ParameterModifiers)
+ */
+ public void applyParameterModifiers(IASTDeclSpecifier parameterType, Parameter umlParameter, ParameterModifiers modifiers) {
+ if (parameterType.isConst()) {
+ StereotypeUtil.apply(umlParameter, Const.class);
+ }
+ if (parameterType.isVolatile()) {
+ StereotypeUtil.apply(umlParameter, Volatile.class);
+ }
+ if (modifiers.isRegister) {
+ StorageClass sc = StereotypeUtil.applyApp(umlParameter, StorageClass.class);
+ if (sc != null) {
+ sc.setStorageClass(EStorageClass.REGISTER);
+ }
+ }
+ if (modifiers.isPointer) {
+ StereotypeUtil.apply(umlParameter, Ptr.class);
+ } else if (modifiers.isRef) {
+ StereotypeUtil.apply(umlParameter, Ref.class);
+ }
+ if (modifiers.array.length() > 0) {
+ Array arraySt = StereotypeUtil.applyApp(umlParameter, Array.class);
+ if (arraySt != null && !modifiers.array.equals("[]") && (!modifiers.array.equals("[ ]"))) { //$NON-NLS-1$//$NON-NLS-2$
+ arraySt.setDefinition(modifiers.array);
+ }
+ }
+ }
+
+ /**
+ * Obtain an operation from the model by using the name of a CDT method.
+ * If an operation of the given name does not exist, it might indicate that
+ * the method has been renamed.
+ *
+ * @param name the operation name within CDT
+ * @param parent the parent of the CDT method within CDT editor model
+ * @param position the position within the other methods. This information is used to locate methods
+ * within the model that might have been renamed in the CDT editor.
+ * @return
+ */
+ public Operation getModelOperationFromName(String name, IParent parent, int position) {
+ Operation operation = m_classifier.getOperation(name, null, null);
+
+ if (operation == null) {
+ // operation is not found via name in the model. try to locate the operation in the model at the same
+ // "position" as the method in the file and
+ // verify that this method does not have the same name as any method
+ // in the CDT file.
+ if (position < m_classifier.getOperations().size()) {
+ operation = m_classifier.getOperations().get(position);
+ String modelName = operation.getName();
+ try {
+ for (ICElement child : parent.getChildren()) {
+ if (child instanceof IMethodDeclaration) {
+ String cdtName = ((IMethodDeclaration) child).getElementName();
+ if (cdtName.equals(modelName)) {
+ // an existing operation in the CDT file already
+ // has this name
+ operation = null;
+ break;
+ }
+ }
+ }
+ } catch (CModelException e) {
+ }
+ }
+ }
+ return operation;
+ }
+
+ public static String getBody(ITranslationUnit itu, IASTFunctionDefinition definition) {
+ IASTStatement body = definition.getBody();
+
+ if (body instanceof IASTCompoundStatement) {
+ IASTCompoundStatement bodyComp = (IASTCompoundStatement) body;
+
+ IASTFileLocation bodyLoc = bodyComp.getFileLocation();
+ int start = bodyLoc.getNodeOffset();
+ int end = start + bodyLoc.getNodeLength();
+ char contents[] = itu.getContents();
+ // body contains enclosing { } which we need to remove (+2, -2). We
+ // cannot use the
+ // first and last statement, since leading and trailing comments are
+ // not part of the AST tree.
+ return Utils.decreaseIndent(contents, start + 2, end - 2);
+ }
+ return ""; //$NON-NLS-1$
+ }
+
+ /**
+ * update a comment of a named element. Besides the comment of the element itself, comments on contained
+ * parameters are handled.
+ *
+ * @param itu a translation unit
+ * @param definition
+ * @param ne a named element that is either an operation or a behavior (in order to update parameters)
+ */
+ public void updateComment(ITranslationUnit itu, IASTFunctionDefinition definition, NamedElement ne) {
+ IASTFileLocation bodyLoc = definition.getFileLocation();
+ int start = bodyLoc.getNodeOffset() - 1;
+ int end = start;
+ char contents[] = itu.getContents();
+ String comment = ""; //$NON-NLS-1$
+ // backward scan for beginning /*
+ while (start > 0) {
+ if (contents[start] == '/' && contents[start + 1] == '*') {
+ start += "/**".length(); // TODO: common string //$NON-NLS-1$
+ // constants with generator
+ for (int i = start; i < end; i++) {
+ comment += contents[i];
+ }
+ comment = comment.replace("\n * ", "\n"). //$NON-NLS-1$//$NON-NLS-2$
+ replace("*/", "").trim(); //$NON-NLS-1$//$NON-NLS-2$
+ break;
+ }
+ start--;
+ }
+ if (comment.length() > 0) {
+ // filter @param
+ int atParam = comment.indexOf(sAtParam);
+ String commentMethodOnly = (atParam != -1) ? comment.substring(0, atParam).trim() : comment;
+
+ EList<Comment> commentsUML = ne.getOwnedComments();
+ Comment commentUML;
+ if (commentsUML.size() == 0) {
+ commentUML = ne.createOwnedComment();
+ commentUML.getAnnotatedElements().add(commentUML);
+ } else {
+ commentUML = commentsUML.get(0);
+ }
+ while (atParam != -1) {
+ int currentAtParam = atParam;
+ atParam = comment.indexOf(sAtParam, atParam + 1);
+ String commentParam = (atParam != -1) ? comment.substring(currentAtParam, atParam)
+ : comment.substring(currentAtParam);
+ Comment commentParamUML;
+ int atParamName = sAtParam.length();
+
+ while ((atParamName < commentParam.length())
+ && Character.isWhitespace(commentParam.charAt(atParamName))) {
+ atParamName++;
+ }
+ int atParamNameEnd = atParamName;
+ while ((atParamNameEnd < commentParam.length())
+ && !Character.isWhitespace(commentParam.charAt(atParamNameEnd))) {
+ atParamNameEnd++;
+ }
+ if (atParamNameEnd < commentParam.length() - 1) {
+ String parameterName = commentParam.substring(atParamName, atParamNameEnd);
+ String commentParamText = commentParam.substring(atParamNameEnd).trim();
+ Parameter parameter = null;
+ if (ne instanceof BehavioralFeature) {
+ parameter = ((BehavioralFeature) ne).getOwnedParameter(parameterName, null, false, false);
+ }
+ else if (ne instanceof Behavior) {
+ parameter = ((Behavior) ne).getOwnedParameter(parameterName, null, false, false);
+ }
+ if (parameter != null) {
+ EList<Comment> commentsParamUML = parameter.getOwnedComments();
+ if (commentsParamUML.size() == 0) {
+ commentParamUML = parameter.createOwnedComment();
+ commentParamUML.getAnnotatedElements().add(commentParamUML);
+ } else {
+ commentParamUML = commentsParamUML.get(0);
+ }
+ commentParamUML.setBody(commentParamText);
+ } else {
+ // parameter is not found in model, e.g. either renamed
+ // or not yet existing
+ // store comment in operation comment
+ commentMethodOnly += "\n " + sAtParam + parameterName + //$NON-NLS-1$
+ " not found(!) " + commentParamText; //$NON-NLS-1$
+ }
+ }
+ }
+ commentUML.setBody(commentMethodOnly);
+ }
+ }
+
+ /**
+ * Accessor
+ * @return value of codegen attribute
+ */
+ public ILangCodegen getCodeGen() {
+ return m_codegen;
+ }
+
+ /**
+ * input of the CDT editor. Used to obtain code within editor.
+ */
+ protected IEditorInput m_input;
+
+ /**
+ * The classifier (class) that is currently edited
+ */
+ protected Classifier m_classifier;
+
+ /**
+ * name of CDT project in which the generated code is stored.
+ */
+ protected String m_projectName;
+
+ /**
+ * reference to code generator
+ */
+ protected ILangCodegen m_codegen;
+}
diff --git a/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/sync/SyncModelToCDT.java b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/sync/SyncModelToCDT.java
new file mode 100644
index 00000000000..207dfa013c9
--- /dev/null
+++ b/extraplugins/qompass/codegen/cpp/org.eclipse.papyrus.texteditor.cdt/src/org/eclipse/papyrus/texteditor/cdt/sync/SyncModelToCDT.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2013 CEA LIST.
+ * 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:
+ * Ansgar Radermacher - ansgar.radermacher@cea.fr CEA LIST - initial API and implementation
+ *
+ *******************************************************************************/
+
+package org.eclipse.papyrus.texteditor.cdt.sync;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.papyrus.codegen.extensionpoints.ILangCodegen;
+import org.eclipse.papyrus.codegen.extensionpoints.ILangCodegen.FILE_KIND;
+import org.eclipse.papyrus.codegen.extensionpoints.ILangCodegen2;
+import org.eclipse.papyrus.codegen.extensionpoints.LanguageCodegen;
+import org.eclipse.papyrus.cpp.codegen.Constants;
+import org.eclipse.papyrus.infra.core.Activator;
+import org.eclipse.papyrus.texteditor.cdt.TextEditorConstants;
+import org.eclipse.uml2.uml.Classifier;
+
+/**
+ * Main listener for model changes (registered via plugin.xml). It will delegate
+ * to the sub-listeners for specific sub-elements (type, operation, port, ...) that
+ * can be found in this package
+ *
+ */
+public class SyncModelToCDT {
+
+ private static final String CPP_SUFFIX = "cpp"; //$NON-NLS-1$
+ /**
+ * set to true, if a synchronization from an CDT editor to the model is active
+ */
+ public static boolean syncFromEditor;
+
+ public static IFile syncModelToCDT(Classifier classifier, String generatorID) {
+ if ((classifier == null) || (classifier.eResource() == null)) {
+ return null;
+ }
+
+ ILangCodegen codegen = LanguageCodegen.getGenerator(TextEditorConstants.CPP, generatorID);
+
+ IProject modelProject = codegen.getTargetProject(classifier, false);
+ if (modelProject == null) {
+ return null;
+ }
+
+ IContainer srcPkg = null;
+ IFile cppFile = null;
+ try {
+ codegen.generateCode(modelProject, classifier, null); // need listener for sync in both directions!
+
+ String suffix = (codegen instanceof ILangCodegen2) ?
+ suffix = ((ILangCodegen2) codegen).getSuffix(FILE_KIND.BODY) : CPP_SUFFIX;
+
+ cppFile = modelProject.getFile(new Path(codegen.getFileName(modelProject, classifier) + Constants.DOT + suffix));
+
+ // IStorage storage = new TextStorage(string);
+ } finally {
+ // Refresh the container for the newly created files. This needs to be done even
+ // during error because of the possibility for partial results.
+ try {
+ if (srcPkg != null) {
+ srcPkg.refreshLocal(IResource.DEPTH_INFINITE, null);
+ }
+ } catch (CoreException e) {
+ Activator.log.error(e);
+ }
+ }
+ return cppFile;
+ }
+}

Back to the top