Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcletavernie2012-04-02 09:33:06 +0000
committercletavernie2012-04-02 09:33:06 +0000
commit1c348bb3ee551cbe290aa2e7a122df180bdd57df (patch)
tree0c07cf9a229d3fd80b9d462351ef27dbf8e90253 /plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.configuration/src/org/eclipse/papyrus/infra/gmfdiag
parent306629adcd6d43ad6688a3c5ead5ebbedc50b81c (diff)
downloadorg.eclipse.papyrus-1c348bb3ee551cbe290aa2e7a122df180bdd57df.tar.gz
org.eclipse.papyrus-1c348bb3ee551cbe290aa2e7a122df180bdd57df.tar.xz
org.eclipse.papyrus-1c348bb3ee551cbe290aa2e7a122df180bdd57df.zip
370797: [Theme] Papyrus should provide a support for CSS files on its diagrams
https://bugs.eclipse.org/bugs/show_bug.cgi?id=370797
Diffstat (limited to 'plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.configuration/src/org/eclipse/papyrus/infra/gmfdiag')
-rw-r--r--plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.configuration/src/org/eclipse/papyrus/infra/gmfdiag/css/configuration/Activator.java69
-rw-r--r--plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.configuration/src/org/eclipse/papyrus/infra/gmfdiag/css/configuration/handler/CreateStyleHandler.java339
-rw-r--r--plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.configuration/src/org/eclipse/papyrus/infra/gmfdiag/css/configuration/handler/EditStyleHandler.java32
-rw-r--r--plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.configuration/src/org/eclipse/papyrus/infra/gmfdiag/css/configuration/handler/GMFToCSSConverter.java133
-rw-r--r--plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.configuration/src/org/eclipse/papyrus/infra/gmfdiag/css/configuration/handler/StyleCreationDialog.java393
5 files changed, 966 insertions, 0 deletions
diff --git a/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.configuration/src/org/eclipse/papyrus/infra/gmfdiag/css/configuration/Activator.java b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.configuration/src/org/eclipse/papyrus/infra/gmfdiag/css/configuration/Activator.java
new file mode 100644
index 00000000000..aac4232ff39
--- /dev/null
+++ b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.configuration/src/org/eclipse/papyrus/infra/gmfdiag/css/configuration/Activator.java
@@ -0,0 +1,69 @@
+/*****************************************************************************
+ * 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:
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.gmfdiag.css.configuration;
+
+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.infra.gmfdiag.css.configuration"; //$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/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.configuration/src/org/eclipse/papyrus/infra/gmfdiag/css/configuration/handler/CreateStyleHandler.java b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.configuration/src/org/eclipse/papyrus/infra/gmfdiag/css/configuration/handler/CreateStyleHandler.java
new file mode 100644
index 00000000000..81ede998d5f
--- /dev/null
+++ b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.configuration/src/org/eclipse/papyrus/infra/gmfdiag/css/configuration/handler/CreateStyleHandler.java
@@ -0,0 +1,339 @@
+/*****************************************************************************
+ * 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:
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.gmfdiag.css.configuration.handler;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.emf.common.util.Enumerator;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EDataType;
+import org.eclipse.emf.ecore.EEnum;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.gmf.runtime.draw2d.ui.figures.FigureUtilities;
+import org.eclipse.gmf.runtime.notation.Diagram;
+import org.eclipse.gmf.runtime.notation.NamedStyle;
+import org.eclipse.gmf.runtime.notation.NotationPackage;
+import org.eclipse.gmf.runtime.notation.Style;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.gmf.runtime.notation.datatype.GradientData;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.core.utils.ServiceUtilsForActionHandlers;
+import org.eclipse.papyrus.infra.gmfdiag.common.helper.NotationHelper;
+import org.eclipse.papyrus.infra.gmfdiag.css.ATTRIBUTE_OP;
+import org.eclipse.papyrus.infra.gmfdiag.css.Attribute;
+import org.eclipse.papyrus.infra.gmfdiag.css.AttributeValue;
+import org.eclipse.papyrus.infra.gmfdiag.css.CompositeSelector;
+import org.eclipse.papyrus.infra.gmfdiag.css.CssFactory;
+import org.eclipse.papyrus.infra.gmfdiag.css.Declaration;
+import org.eclipse.papyrus.infra.gmfdiag.css.Ruleset;
+import org.eclipse.papyrus.infra.gmfdiag.css.SelectorCondition;
+import org.eclipse.papyrus.infra.gmfdiag.css.SimpleSelector;
+import org.eclipse.papyrus.infra.gmfdiag.css.Stylesheet;
+import org.eclipse.papyrus.infra.gmfdiag.css.configuration.Activator;
+import org.eclipse.papyrus.infra.gmfdiag.css.handler.CSSRefreshHandler;
+import org.eclipse.papyrus.infra.gmfdiag.css.stylesheets.StyleSheet;
+import org.eclipse.papyrus.infra.gmfdiag.css.stylesheets.StyleSheetReference;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.xtext.resource.XtextResourceSet;
+
+
+public class CreateStyleHandler extends AbstractHandler {
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ ISelection selection;
+ try {
+ selection = ServiceUtilsForActionHandlers.getInstance().getNestedActiveIEditorPart().getSite().getSelectionProvider().getSelection();
+ if(selection.isEmpty()) {
+ return null;
+ }
+ } catch (ServiceException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ return null;
+ }
+
+ if(!(selection instanceof IStructuredSelection)) {
+ return null;
+ }
+
+ IStructuredSelection sSelection = (IStructuredSelection)selection;
+ Object element = sSelection.getFirstElement();
+
+ View view = NotationHelper.findView(element);
+ if(view == null) {
+ Activator.log.warn("Cannot create a Style from the selected element ; the element is not a View");
+ return null;
+ }
+
+ Shell parentShell = ((Event)event.getTrigger()).widget.getDisplay().getActiveShell();
+
+ if(view.getElement() == null || view instanceof Diagram) {
+ MessageDialog.open(MessageDialog.WARNING, parentShell, "Style error", "The selected element's style cannot be exported", SWT.NONE);
+ return null;
+ }
+
+ Map<Declaration, Boolean> declarations = handleStyles(view);
+ Map<SelectorCondition, Boolean> conditions = handleSemantic(view);
+
+ String selectorName = view.getElement().eClass().getName();
+
+ StyleCreationDialog dialog = new StyleCreationDialog(parentShell, conditions, declarations, selectorName, view);
+ if(dialog.open() != Dialog.OK) {
+ return null;
+ }
+
+ Ruleset ruleset = CssFactory.eINSTANCE.createRuleset();
+ SimpleSelector selector = CssFactory.eINSTANCE.createSimpleSelector();
+
+ if(dialog.useSelectorName()) {
+ selector.setElementName(selectorName);
+ } else {
+ selector.setElementName("*"); //$NON-NLS-1$
+ }
+
+ if(dialog.getDiagramRestriction()) {
+ String diagramType = view.getDiagram().getType();
+ CompositeSelector compositeSelector = CssFactory.eINSTANCE.createCompositeSelector();
+ compositeSelector.setRight(selector);
+
+ SimpleSelector diagramSelector = CssFactory.eINSTANCE.createSimpleSelector();
+ diagramSelector.setElementName(diagramType);
+ compositeSelector.setLeft(diagramSelector);
+
+ ruleset.getSelectors().add(compositeSelector);
+ } else {
+ ruleset.getSelectors().add(selector);
+ }
+
+ if(dialog.getCSSClass() != null) {
+ String cssClass = dialog.getCSSClass();
+ org.eclipse.papyrus.infra.gmfdiag.css.Class classCondition = CssFactory.eINSTANCE.createClass();
+ classCondition.setClass(cssClass);
+ selector.getCondition().add(classCondition);
+ }
+
+ for(SelectorCondition condition : conditions.keySet()) {
+ if(conditions.get(condition)) {
+ selector.getCondition().add(condition);
+ }
+ }
+
+ for(Declaration declaration : declarations.keySet()) {
+ if(declarations.get(declaration)) {
+ ruleset.getProperties().add(declaration);
+ }
+ }
+
+ StyleSheet styleSheet = dialog.getStylesheet();
+ if(styleSheet == null) {
+ MessageDialog.open(MessageDialog.ERROR, parentShell, "Stylesheet error", "Invalid stylesheet", SWT.NONE);
+ return null;
+ }
+
+ ResourceSet resourceSet = new XtextResourceSet();
+ Resource resource;
+
+ if(styleSheet instanceof StyleSheetReference) {
+ //Supported pathes:
+ // /<plugin>/path/file.css (Workspace, platform:/resource/)
+ // relative/path/file.css (Relative)
+ String path = ((StyleSheetReference)styleSheet).getPath();
+ if(!path.endsWith(".css")) {
+ //FIXME: The X-Text editor supports CSS Content Types, but it is not yet configured
+ //to automatically accept other extensions than *.css
+ //The parser should rely on the file's content type instead of the file extension
+ //Attemps to serialize to a custom extension (even an extension compatible with CSS Content Type)
+ //would result in xmi serialization. We'd better stop here.
+ MessageDialog.open(MessageDialog.ERROR, parentShell, "Stylesheet error", "The stylesheet must have the *.css extension", SWT.NONE);
+ return null;
+ }
+ URI uri;
+ if(path.startsWith("/")) {
+ uri = URI.createPlatformResourceURI(path, true);
+ } else {
+ uri = URI.createURI(path);
+ uri = uri.resolve(view.eResource().getURI());
+ }
+
+ try {
+ resource = resourceSet.getResource(uri, true);
+ } catch (Exception ex) {
+ resource = resourceSet.createResource(uri, "org.eclipse.wst.css.core.csssource");
+ }
+ } else {
+ MessageDialog.open(MessageDialog.ERROR, parentShell, "Stylesheet error", "Embedded stylesheets are not yet supported", SWT.NONE);
+ return null;
+ }
+
+ Stylesheet xtextStylesheet;
+
+ if(resource.getContents().isEmpty()) {
+ xtextStylesheet = CssFactory.eINSTANCE.createStylesheet();
+ xtextStylesheet.setCharset("UTF-8");
+ resource.getContents().add(xtextStylesheet);
+ } else {
+ xtextStylesheet = (Stylesheet)resource.getContents().get(0);
+ }
+
+ xtextStylesheet.getContents().add(ruleset);
+
+ try {
+ resource.save(new HashMap<Object, Object>());
+ (new CSSRefreshHandler()).execute(null);
+ } catch (IOException ex) {
+ Activator.log.error(ex);
+ MessageDialog.open(MessageDialog.ERROR, parentShell, "Style error", "An unexpected error occured while trying to save the Stylesheet", SWT.NONE);
+ } catch (Exception ex) {
+ Activator.log.error(ex);
+ MessageDialog.open(MessageDialog.ERROR, parentShell, "Style error", "An unexpected error occured while trying to save the Stylesheet", SWT.NONE);
+ }
+
+ return null;
+ }
+
+ private Map<Declaration, Boolean> handleStyles(View view) {
+ Map<Declaration, Boolean> declarations = new LinkedHashMap<Declaration, Boolean>();
+
+ for(Object styleObject : view.getStyles()) {
+ Style style = (Style)styleObject;
+ declarations.putAll(handleStyle(style));
+ }
+
+ if(view instanceof Style) {
+ declarations.putAll(handleStyle((Style)view));
+ }
+
+ return declarations;
+ }
+
+ private Map<SelectorCondition, Boolean> handleSemantic(View view) {
+ Map<SelectorCondition, Boolean> result = new LinkedHashMap<SelectorCondition, Boolean>();
+
+ EObject semanticElement = view.getElement();
+
+ for(EStructuralFeature feature : semanticElement.eClass().getEAllStructuralFeatures()) {
+ if(isBoolean(feature) || isInteger(feature) || feature.getEType() instanceof EEnum) {
+ Attribute attributeCondition = CssFactory.eINSTANCE.createAttribute();
+ attributeCondition.setName(feature.getName());
+
+ AttributeValue attributeValue = CssFactory.eINSTANCE.createAttributeValue();
+ attributeValue.setOperator(ATTRIBUTE_OP.EQUALS);
+ attributeValue.setValue(semanticElement.eGet(feature).toString());
+ attributeCondition.setValue(attributeValue);
+
+ boolean check = semanticElement.eGet(feature) != feature.getDefaultValue();
+
+ result.put(attributeCondition, check);
+ }
+ }
+
+ return result;
+ }
+
+ private boolean isBoolean(EStructuralFeature feature) {
+ if(feature.getEType() == EcorePackage.eINSTANCE.getEBoolean() || feature.getEType() == EcorePackage.eINSTANCE.getEBooleanObject()) {
+ return true;
+ }
+
+ if(feature.getEType() instanceof EDataType) {
+ EDataType datatype = (EDataType)feature.getEType();
+ return datatype.getName().equals("Boolean");
+ }
+
+ return false;
+ }
+
+ private boolean isString(EStructuralFeature feature) {
+ return feature.getEType() == EcorePackage.eINSTANCE.getEString();
+ }
+
+ private boolean isInteger(EStructuralFeature feature) {
+ if(feature.getEType() == EcorePackage.eINSTANCE.getEInt() || feature.getEType() == EcorePackage.eINSTANCE.getEIntegerObject()) {
+ return true;
+ }
+
+ if(feature.getEType() instanceof EDataType) {
+ EDataType datatype = (EDataType)feature.getEType();
+ return datatype.getName().equals("Integer");
+ }
+
+ return false;
+ }
+
+ private Map<Declaration, Boolean> handleStyle(Style style) {
+ if(style instanceof NamedStyle) {
+ return Collections.emptyMap();
+ }
+
+ Map<Declaration, Boolean> declarations = new LinkedHashMap<Declaration, Boolean>();
+
+ for(EStructuralFeature feature : style.eClass().getEAllStructuralFeatures()) {
+ if(NotationPackage.eINSTANCE.getStyle().isSuperTypeOf(feature.getEContainingClass())) {
+ boolean check = style.eGet(feature) != feature.getDefaultValue();
+ declarations.put(handleStyleFeature(style, feature), check);
+ }
+ }
+
+ return declarations;
+ }
+
+ private Declaration handleStyleFeature(Style style, EStructuralFeature feature) {
+ Declaration declaration = CssFactory.eINSTANCE.createDeclaration();
+ declaration.setProperty(feature.getName());
+
+ GMFToCSSConverter converter = GMFToCSSConverter.instance;
+
+ if(isString(feature)) {
+ declaration.setExpression(converter.convert((String)style.eGet(feature)));
+ }
+
+ if(isInteger(feature)) {
+ if(feature.getName().endsWith("Color")) {
+ declaration.setExpression(converter.convert(FigureUtilities.integerToColor((Integer)style.eGet(feature))));
+ } else {
+ declaration.setExpression(converter.convert((Integer)style.eGet(feature)));
+ }
+ }
+
+ if(feature.getEType() == NotationPackage.eINSTANCE.getGradientData()) {
+ declaration.setExpression(converter.convert((GradientData)style.eGet(feature)));
+ }
+
+ if(feature.getEType() instanceof EEnum) {
+ declaration.setExpression(converter.convert((Enumerator)style.eGet(feature)));
+ }
+
+ if(isBoolean(feature)) {
+ declaration.setExpression(converter.convert((Boolean)style.eGet(feature)));
+ }
+
+ return declaration;
+ }
+
+}
diff --git a/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.configuration/src/org/eclipse/papyrus/infra/gmfdiag/css/configuration/handler/EditStyleHandler.java b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.configuration/src/org/eclipse/papyrus/infra/gmfdiag/css/configuration/handler/EditStyleHandler.java
new file mode 100644
index 00000000000..7932fbe9665
--- /dev/null
+++ b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.configuration/src/org/eclipse/papyrus/infra/gmfdiag/css/configuration/handler/EditStyleHandler.java
@@ -0,0 +1,32 @@
+/*****************************************************************************
+ * 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:
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.gmfdiag.css.configuration.handler;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Shell;
+
+
+public class EditStyleHandler extends AbstractHandler {
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ //TODO
+ Shell parentShell = ((Event)event.getTrigger()).widget.getDisplay().getActiveShell();
+ MessageDialog.open(MessageDialog.WARNING, parentShell, "Edit style error", "This action is not yet supported", SWT.NONE);
+ return null;
+ }
+
+}
diff --git a/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.configuration/src/org/eclipse/papyrus/infra/gmfdiag/css/configuration/handler/GMFToCSSConverter.java b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.configuration/src/org/eclipse/papyrus/infra/gmfdiag/css/configuration/handler/GMFToCSSConverter.java
new file mode 100644
index 00000000000..fdacd0d7190
--- /dev/null
+++ b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.configuration/src/org/eclipse/papyrus/infra/gmfdiag/css/configuration/handler/GMFToCSSConverter.java
@@ -0,0 +1,133 @@
+/*****************************************************************************
+ * 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:
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.gmfdiag.css.configuration.handler;
+
+import org.eclipse.emf.common.util.Enumerator;
+import org.eclipse.gmf.runtime.draw2d.ui.figures.FigureUtilities;
+import org.eclipse.gmf.runtime.notation.GradientStyle;
+import org.eclipse.gmf.runtime.notation.datatype.GradientData;
+import org.eclipse.papyrus.infra.gmfdiag.css.CssFactory;
+import org.eclipse.papyrus.infra.gmfdiag.css.Expression;
+import org.eclipse.papyrus.infra.gmfdiag.css.HexColor;
+import org.eclipse.papyrus.infra.gmfdiag.css.Name;
+import org.eclipse.papyrus.infra.gmfdiag.css.Number;
+import org.eclipse.papyrus.infra.gmfdiag.css.StringValue;
+import org.eclipse.papyrus.infra.gmfdiag.css.Subterm;
+import org.eclipse.papyrus.infra.gmfdiag.css.Term;
+import org.eclipse.papyrus.infra.gmfdiag.css.UNARY;
+import org.eclipse.papyrus.infra.gmfdiag.css.UnaryOperator;
+import org.eclipse.swt.graphics.Color;
+
+
+public class GMFToCSSConverter {
+
+ public static final GMFToCSSConverter instance = new GMFToCSSConverter();
+
+ private GMFToCSSConverter() {
+
+ }
+
+ public Expression convert(Color color) {
+ HexColor hexColor = getColor(color);
+ return getExpression(hexColor);
+ }
+
+ private HexColor getColor(Color color) {
+ HexColor hexColor = CssFactory.eINSTANCE.createHexColor();
+
+ String hexString = twoDigitsHexString(color.getRed()) + twoDigitsHexString(color.getGreen()) + twoDigitsHexString(color.getBlue());
+ hexColor.setValue(hexString.toUpperCase());
+ return hexColor;
+ }
+
+ private HexColor getColor(int color) {
+ return getColor(FigureUtilities.integerToColor(color));
+ }
+
+ private String twoDigitsHexString(int color) {
+ String hexString = Integer.toHexString(color);
+ if(hexString.length() < 2) {
+ hexString = "0" + hexString;
+ }
+ return hexString;
+ }
+
+ public Expression convert(GradientData gradient) {
+ if(gradient == null) {
+ Name noGradient = CssFactory.eINSTANCE.createName();
+ noGradient.setValue("none");
+ return getExpression(noGradient);
+ }
+
+ HexColor gradientColor = getColor(gradient.getGradientColor1());
+
+ Name gradientStyle = CssFactory.eINSTANCE.createName();
+ int style = gradient.getGradientStyle();
+
+ if(style == GradientStyle.HORIZONTAL) {
+ gradientStyle.setValue("horizontal");
+ } else {
+ gradientStyle.setValue("vertical");
+ }
+
+ return getExpression(gradientColor, gradientStyle);
+ }
+
+ public Expression convert(String string) {
+ StringValue stringValue = CssFactory.eINSTANCE.createStringValue();
+ stringValue.setValue(string);
+ return getExpression(stringValue);
+ }
+
+ public Expression convert(Integer intValue) {
+ Number numberValue = CssFactory.eINSTANCE.createNumber();
+ numberValue.setValue(Integer.toString(Math.abs(intValue)));
+ if(intValue < 0) {
+ UnaryOperator operator = CssFactory.eINSTANCE.createUnaryOperator();
+ operator.setOperator(UNARY.NEG);
+ numberValue.setOp(operator);
+ }
+
+ return getExpression(numberValue);
+ }
+
+ public Expression convert(Enumerator enumerated) {
+ Name literalValue = CssFactory.eINSTANCE.createName();
+
+ literalValue.setValue(enumerated.getName());
+
+ return getExpression(literalValue);
+ }
+
+ private Expression getExpression(Term... values) {
+ if(values.length == 0) {
+ throw new IllegalArgumentException("An expression must contain at least one value");
+ }
+
+ Expression result = CssFactory.eINSTANCE.createExpression();
+ result.setTerms(values[0]);
+
+ for(int i = 1; i < values.length; i++) {
+ Subterm subterm = CssFactory.eINSTANCE.createSubterm();
+ subterm.setTerm(values[i]);
+ result.getSubterms().add(subterm);
+ }
+
+ return result;
+ }
+
+ public Expression convert(boolean booleanValue) {
+ Name nameValue = CssFactory.eINSTANCE.createName();
+ nameValue.setValue(booleanValue ? "true" : "false");
+ return getExpression(nameValue);
+ }
+}
diff --git a/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.configuration/src/org/eclipse/papyrus/infra/gmfdiag/css/configuration/handler/StyleCreationDialog.java b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.configuration/src/org/eclipse/papyrus/infra/gmfdiag/css/configuration/handler/StyleCreationDialog.java
new file mode 100644
index 00000000000..5a0eda76c54
--- /dev/null
+++ b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.configuration/src/org/eclipse/papyrus/infra/gmfdiag/css/configuration/handler/StyleCreationDialog.java
@@ -0,0 +1,393 @@
+/*****************************************************************************
+ * 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:
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.gmfdiag.css.configuration.handler;
+
+import java.util.Map;
+
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.jface.dialogs.TrayDialog;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.papyrus.infra.gmfdiag.css.Attribute;
+import org.eclipse.papyrus.infra.gmfdiag.css.Declaration;
+import org.eclipse.papyrus.infra.gmfdiag.css.Expression;
+import org.eclipse.papyrus.infra.gmfdiag.css.HexColor;
+import org.eclipse.papyrus.infra.gmfdiag.css.Name;
+import org.eclipse.papyrus.infra.gmfdiag.css.Number;
+import org.eclipse.papyrus.infra.gmfdiag.css.SelectorCondition;
+import org.eclipse.papyrus.infra.gmfdiag.css.StringValue;
+import org.eclipse.papyrus.infra.gmfdiag.css.Subterm;
+import org.eclipse.papyrus.infra.gmfdiag.css.Term;
+import org.eclipse.papyrus.infra.gmfdiag.css.properties.provider.CSSStyleSheetContentProvider;
+import org.eclipse.papyrus.infra.gmfdiag.css.properties.provider.CSSStyleSheetLabelProvider;
+import org.eclipse.papyrus.infra.gmfdiag.css.stylesheets.EmbeddedStyleSheet;
+import org.eclipse.papyrus.infra.gmfdiag.css.stylesheets.StyleSheet;
+import org.eclipse.papyrus.infra.gmfdiag.css.stylesheets.StyleSheetReference;
+import org.eclipse.papyrus.infra.gmfdiag.css.stylesheets.StylesheetsFactory;
+import org.eclipse.papyrus.infra.gmfdiag.css.util.CssSwitch;
+import org.eclipse.papyrus.infra.widgets.editors.AbstractEditor;
+import org.eclipse.papyrus.infra.widgets.editors.BooleanCheckbox;
+import org.eclipse.papyrus.infra.widgets.editors.EnumRadio;
+import org.eclipse.papyrus.infra.widgets.editors.ICommitListener;
+import org.eclipse.papyrus.infra.widgets.editors.ReferenceDialog;
+import org.eclipse.papyrus.infra.widgets.editors.StringEditor;
+import org.eclipse.papyrus.infra.widgets.editors.StringFileSelector;
+import org.eclipse.papyrus.infra.widgets.providers.StaticContentProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CTabFolder;
+import org.eclipse.swt.custom.CTabItem;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+
+
+public class StyleCreationDialog extends TrayDialog {
+
+ private final Map<SelectorCondition, Boolean> conditions;
+
+ private final Map<Declaration, Boolean> declarations;
+
+ private final String selectorName;
+
+ private boolean useSelectorName = true;
+
+ private boolean diagramRestriction = false;
+
+ private String cssClass;
+
+ private View contextView;
+
+ private StyleSheet stylesheet;
+
+ /**
+ *
+ * @param shell
+ * @param conditions
+ * inout
+ * @param declarations
+ * inout
+ * @param selectorName
+ */
+ public StyleCreationDialog(Shell shell, Map<SelectorCondition, Boolean> conditions, Map<Declaration, Boolean> declarations, String selectorName, View context) {
+ super(shell);
+ this.conditions = conditions;
+ this.declarations = declarations;
+ this.selectorName = selectorName;
+ this.contextView = context;
+ }
+
+ @Override
+ public void create() {
+ super.create();
+ Composite parent = getDialogArea();
+
+ CTabFolder tabFolder = new CTabFolder(parent, SWT.BORDER);
+ tabFolder.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ CTabItem conditionsTab = new CTabItem(tabFolder, SWT.NONE);
+ CTabItem declarationsTab = new CTabItem(tabFolder, SWT.NONE);
+ CTabItem stylesheetTab = new CTabItem(tabFolder, SWT.NONE);
+
+ conditionsTab.setText("Conditions");
+ declarationsTab.setText("Properties");
+ stylesheetTab.setText("Stylesheet");
+
+ Composite conditionsContainer = new Composite(tabFolder, SWT.NONE);
+ conditionsContainer.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, true, true));
+ conditionsContainer.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE));
+ conditionsContainer.setBackgroundMode(SWT.INHERIT_DEFAULT);
+
+ conditionsTab.setControl(conditionsContainer);
+
+ Composite declarationsContainer = new Composite(tabFolder, SWT.NONE);
+ declarationsContainer.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, true, true));
+ declarationsContainer.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE));
+ declarationsContainer.setBackgroundMode(SWT.INHERIT_DEFAULT);
+
+ declarationsTab.setControl(declarationsContainer);
+
+ Composite stylesheetContainer = new Composite(tabFolder, SWT.NONE);
+ stylesheetContainer.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, true, true));
+ stylesheetContainer.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE));
+ stylesheetContainer.setBackgroundMode(SWT.INHERIT_DEFAULT);
+
+ stylesheetTab.setControl(stylesheetContainer);
+
+ createConditions(conditionsContainer);
+ createDeclarations(declarationsContainer);
+ createStylesheet(stylesheetContainer);
+
+ getShell().setText("New Style");
+ getShell().pack();
+ }
+
+ protected void createConditions(Composite parent) {
+ parent.setLayout(new GridLayout(3, false));
+
+ Label conditionsLabel = new Label(parent, SWT.WRAP);
+ conditionsLabel.setText("Select the condition(s) under which the style will be applied.");
+ conditionsLabel.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false, 3, 1));
+
+ createElementNameSection(parent);
+ createAttributeSelectorsSection(parent);
+ createStyleNameSection(parent);
+ }
+
+ protected void createElementNameSection(Composite parent) {
+ EnumRadio diagramRestrictionWidget = new EnumRadio(parent, SWT.NONE, "Diagram:");
+ diagramRestrictionWidget.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false, 3, 1));
+
+ ILabelProvider labelProvider = new LabelProvider() {
+
+ @Override
+ public String getText(Object element) {
+ Boolean value = (Boolean)element;
+ return value ? contextView.getDiagram().getType() + " only" : "Any diagram";
+ }
+ };
+
+ diagramRestrictionWidget.setProviders(new StaticContentProvider(new Boolean[]{ true, false }), labelProvider);
+ diagramRestrictionWidget.setValue(this.diagramRestriction);
+ diagramRestrictionWidget.addCommitListener(new ICommitListener() {
+
+ public void commit(AbstractEditor editor) {
+ diagramRestriction = (Boolean)((EnumRadio)editor).getValue();
+ }
+ });
+
+ EnumRadio selectorNameWidget = new EnumRadio(parent, SWT.NONE, "Applies to:");
+ selectorNameWidget.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false, 3, 1));
+
+ labelProvider = new LabelProvider() {
+
+ @Override
+ public String getText(Object element) {
+ Boolean value = (Boolean)element;
+ return value ? selectorName + " only" : "Any kind of element";
+ }
+ };
+
+ selectorNameWidget.setProviders(new StaticContentProvider(new Boolean[]{ true, false }), labelProvider);
+ selectorNameWidget.setValue(this.useSelectorName);
+ selectorNameWidget.addCommitListener(new ICommitListener() {
+
+ public void commit(AbstractEditor editor) {
+ useSelectorName = (Boolean)((EnumRadio)editor).getValue();
+ }
+ });
+ }
+
+ protected void createAttributeSelectorsSection(Composite parent) {
+ if(conditions.isEmpty()) {
+ return;
+ }
+
+ Label detailLabel = new Label(parent, SWT.NONE);
+ detailLabel.setText("If the following properties are matched:");
+ detailLabel.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false, 3, 1));
+
+ for(SelectorCondition condition : conditions.keySet()) {
+ final Attribute currentCondition = (Attribute)condition;
+
+ String attributeLabel = currentCondition.getName();
+ if(currentCondition.getValue() != null) {
+ attributeLabel += " " + currentCondition.getValue().getOperator() + " " + currentCondition.getValue().getValue();
+ }
+
+ BooleanCheckbox checkbox = new BooleanCheckbox(parent, SWT.NONE, attributeLabel);
+ checkbox.setValue(conditions.get(currentCondition));
+
+ checkbox.addCommitListener(new ICommitListener() {
+
+ public void commit(AbstractEditor editor) {
+ conditions.put(currentCondition, ((BooleanCheckbox)editor).getValue());
+ }
+ });
+ }
+ }
+
+ protected void createStyleNameSection(Composite parent) {
+ Label styleNameLabel = new Label(parent, SWT.WRAP);
+
+ String label = "If a name is used for this style, it will have to be applied manually:";
+
+ styleNameLabel.setText(label);
+ styleNameLabel.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false, 3, 1));
+
+ StringEditor styleNameEditor = new StringEditor(parent, SWT.NONE, "Style name:");
+ styleNameEditor.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false, 3, 1));
+ // styleNameEditor.setToolTipText(label);
+ styleNameEditor.addCommitListener(new ICommitListener() {
+
+ public void commit(AbstractEditor editor) {
+ cssClass = (String)((StringEditor)editor).getValue();
+ }
+
+ });
+ }
+
+ protected void createDeclarations(Composite parent) {
+ parent.setLayout(new GridLayout(3, false));
+ // parent.setLayout(new FillLayout());
+
+ Label declarationsLabel = new Label(parent, SWT.WRAP);
+ declarationsLabel.setText("Select the properties you want to set. Unchecked properties will keep their default value (Which might be inherited from another style).");
+ declarationsLabel.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false, 3, 1));
+
+ for(Declaration declaration : declarations.keySet()) {
+ String label = declaration.getProperty() + ": " + getLabel(declaration.getExpression());
+ BooleanCheckbox checkbox = new BooleanCheckbox(parent, SWT.NONE, label);
+ checkbox.setValue(declarations.get(declaration));
+
+ final Declaration currentDeclaration = declaration;
+ checkbox.addCommitListener(new ICommitListener() {
+
+ public void commit(AbstractEditor editor) {
+ declarations.put(currentDeclaration, ((BooleanCheckbox)editor).getValue());
+ }
+ });
+ }
+ }
+
+ protected void createStylesheet(Composite parent) {
+ //TODO: Use a preference to remember the last edited Stylesheet (Per model? Diagram? Workspace? With user choice?)
+
+ parent.setLayout(new GridLayout(1, false));
+
+ //Create or use an existing External Stylesheet
+ StringFileSelector externalStylesheet = new StringFileSelector(parent, SWT.NONE);
+ externalStylesheet.setAllowFileSystem(false);
+ externalStylesheet.setLabel("External stylesheet:");
+ externalStylesheet.setToolTipText("Create or use an existing external CSS Stylesheet");
+ externalStylesheet.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
+ externalStylesheet.addCommitListener(new ICommitListener() {
+
+ public void commit(AbstractEditor editor) {
+ String path = (String)((StringEditor)editor).getValue();
+ StyleSheetReference stylesheetReference = StylesheetsFactory.eINSTANCE.createStyleSheetReference();
+ stylesheetReference.setPath(path);
+ stylesheet = stylesheetReference;
+ }
+ });
+
+ Label orLabel = new Label(parent, SWT.NONE);
+ orLabel.setText("-- OR --");
+
+ //Create a new Embedded Stylesheet
+ StringEditor embeddedStylesheet = new StringEditor(parent, SWT.NONE);
+ embeddedStylesheet.setLabel("New local stylesheet:");
+ embeddedStylesheet.setToolTipText("Create a new local stylesheet. The stylesheet will be embedded in the current model. Unsupported yet");
+ embeddedStylesheet.setReadOnly(true);
+ embeddedStylesheet.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
+ embeddedStylesheet.addCommitListener(new ICommitListener() {
+
+ public void commit(AbstractEditor editor) {
+ String name = (String)((StringEditor)editor).getValue();
+ EmbeddedStyleSheet embeddedStylesheet = StylesheetsFactory.eINSTANCE.createEmbeddedStyleSheet();
+ embeddedStylesheet.setLabel(name);
+ stylesheet = embeddedStylesheet;
+ }
+ });
+
+ orLabel = new Label(parent, SWT.NONE);
+ orLabel.setText("-- OR --");
+
+ //Use an existing applied stylesheet (Either Reference or Embedded)
+ ReferenceDialog appliedStylesheet = new ReferenceDialog(parent, SWT.NONE);
+ appliedStylesheet.setLabel("Applied stylesheet:");
+ appliedStylesheet.setToolTipText("Use an existing stylesheet, from the stylesheets applied to the current model");
+ appliedStylesheet.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
+ appliedStylesheet.setContentProvider(new CSSStyleSheetContentProvider(contextView));
+ appliedStylesheet.setLabelProvider(new CSSStyleSheetLabelProvider());
+ appliedStylesheet.addCommitListener(new ICommitListener() {
+
+ public void commit(AbstractEditor editor) {
+ StyleSheet value = (StyleSheet)((ReferenceDialog)editor).getValue();
+ stylesheet = value;
+ }
+ });
+
+ }
+
+ public String getCSSClass() {
+ if(cssClass != null) {
+ return cssClass.trim().equals("") ? null : cssClass.trim();
+ }
+ return null;
+ }
+
+ protected String getLabel(Expression expression) {
+ String label = getLabel(expression.getTerms());
+ for(Subterm subTerm : expression.getSubterms()) {
+ if(subTerm.getOperator() != null) {
+ label += subTerm.getOperator();
+ }
+ label += " " + getLabel(subTerm.getTerm());
+ }
+ return label;
+ }
+
+ protected String getLabel(Term term) {
+ return (new CssSwitch<String>() {
+
+ @Override
+ public String caseHexColor(HexColor term) {
+ return '#' + term.getValue();
+ }
+
+ @Override
+ public String caseName(Name term) {
+ return term.getValue();
+ }
+
+ @Override
+ public String caseStringValue(StringValue term) {
+ return "\"" + term.getValue() + "\"";
+ }
+
+ @Override
+ public String caseNumber(Number term) {
+ String label = "";
+ if(term.getOp() != null) {
+ label += term.getOp().getOperator();
+ }
+ label += term.getValue();
+ return label;
+ }
+ }).doSwitch(term);
+ }
+
+ public StyleSheet getStylesheet() {
+ return stylesheet;
+ }
+
+ @Override
+ protected boolean isResizable() {
+ return true;
+ }
+
+ @Override
+ public Composite getDialogArea() {
+ return (Composite)super.getDialogArea();
+ }
+
+ public boolean useSelectorName() {
+ return useSelectorName;
+ }
+
+ public boolean getDiagramRestriction() {
+ return diagramRestriction;
+ }
+
+}

Back to the top