diff options
author | Gabriel Pascual | 2014-04-29 16:24:08 +0000 |
---|---|---|
committer | Gabriel Pascual | 2014-04-30 12:54:50 +0000 |
commit | a174352dd68d69367bcb468722a0bd0938802e2a (patch) | |
tree | 14fc0e595c8b9bdb1528dda11783bd4e8f994509 /plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties | |
parent | e770c8764a6f9a9c60315a689d5fc583286616c1 (diff) | |
download | org.eclipse.papyrus-a174352dd68d69367bcb468722a0bd0938802e2a.tar.gz org.eclipse.papyrus-a174352dd68d69367bcb468722a0bd0938802e2a.tar.xz org.eclipse.papyrus-a174352dd68d69367bcb468722a0bd0938802e2a.zip |
430079: [CSS] Papyrus shall provide features to define local theme
https://bugs.eclipse.org/bugs/show_bug.cgi?id=430079
Patch 3 :
- Fix major issue
- Fix comment's remarks
Patch 2 :
- Rebase to pass hudson verification
Pathch 1 :
- Use workspace relative path for selected css files during CSS theme
edition
- Fix "restore default" button action in CSS preference page
- Harmonisation of all UI for theme icon selection
- Add dialog to confirm theme deletion
- Refactor to resolve some dependency problems
- Creation of widget for XWT theme view
- Add embedded style sheets in CSS Workspace engine working
- Fix problems of label provider for CSS themes properties view
- Add workspace themes preference page
- Add definition of theme property view
- Fix saving step of an edited theme from workspace
- Fix loading of theme icon in label provider - Fix behavior of theme
edition dialog fields
- Add edition action on style sheets list
- Add move up and move down actions in edition dialog
- Add actions (add and delete) to dialog
- Resolution staying conflicts after last merge
- Add edition theme dialog from project explorer
- Minor modification of Style sheet metamodel
- Modify CSS engine and theme manager to look at workspace theme
contributions
- Add theme creation by selecting one or more CSS files
- Add dialog to define theme from CSS file in workspace
- Create one menu for two actions to manage local theme
- Manage command ID in handler
- Fix containment relationship in model
- Add draft of theme creation from a CSS selection
- Modification of style sheets model
- Add popup menu on CSS file
Change-Id: Ie46281e334252bfbed727c18a431677761db2a45
Signed-off-by: Gabriel Pascual <gabriel.pascual@all4tec.net>
Diffstat (limited to 'plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties')
14 files changed, 3767 insertions, 155 deletions
diff --git a/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/model/Environment.xmi b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/model/Environment.xmi index 4f5fe3cf2fa..d610db8ed4e 100644 --- a/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/model/Environment.xmi +++ b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/model/Environment.xmi @@ -1,19 +1,8 @@ -<?xml version="1.0" encoding="ASCII"?>
-<environment:Environment
- xmi:version="2.0"
- xmlns:xmi="http://www.omg.org/XMI"
- xmlns:environment="http://www.eclipse.org/papyrus/properties/environment/0.9">
- <modelElementFactories
- name="CSS CustomStyle Factory"
- factoryClass="org.eclipse.papyrus.infra.gmfdiag.css.properties.modelelement.CSSModelElementFactory"/>
- <modelElementFactories
- name="CSS Preferences"
- factoryClass="org.eclipse.papyrus.infra.gmfdiag.css.properties.modelelement.CSSPreferencesModelElementFactory"/>
- <widgetTypes
- label="CSS ResetStyle Button"
- widgetClass="ResetStyleWidget"
- namespace="//@namespaces.0"/>
- <namespaces
- name="css"
- value="org.eclipse.papyrus.infra.gmfdiag.css.properties.widgets"/>
-</environment:Environment>
+<?xml version="1.0" encoding="ASCII"?> +<environment:Environment xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:environment="http://www.eclipse.org/papyrus/properties/environment/0.9"> + <modelElementFactories name="CSS CustomStyle Factory" factoryClass="org.eclipse.papyrus.infra.gmfdiag.css.properties.modelelement.CSSModelElementFactory"/> + <modelElementFactories name="CSS Preferences" factoryClass="org.eclipse.papyrus.infra.gmfdiag.css.properties.modelelement.CSSPreferencesModelElementFactory"/> + <modelElementFactories name="CSS Themes" factoryClass="org.eclipse.papyrus.infra.gmfdiag.css.properties.modelelement.CSSThemesModelElementFactory"/> + <widgetTypes label="CSS ResetStyle Button" widgetClass="ResetStyleWidget" namespace="//@namespaces.0"/> + <namespaces name="css" value="org.eclipse.papyrus.infra.gmfdiag.css.properties.widgets"/> +</environment:Environment> diff --git a/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/model/properties/css.ctx b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/model/properties/css.ctx index 6b4fb350795..f8cbcf7a6f6 100644 --- a/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/model/properties/css.ctx +++ b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/model/properties/css.ctx @@ -1,88 +1,106 @@ -<?xml version="1.0" encoding="UTF-8"?>
-<contexts:Context xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:constraints="http://www.eclipse.org/papyrus/constraints/0.9" xmlns:contexts="http://www.eclipse.org/papyrus/properties/contexts/0.9" name="CSS">
- <tabs label="Style" id="style" category="org.eclipse.papyrus" image="" priority="70">
- <sections name="SingleStylableElement" sectionFile="ui/SingleStylableElement.xwt">
- <widget href="ui/SingleStylableElement.xwt#/"/>
- </sections>
- <sections name="MultipleStylableElement" sectionFile="ui/MultipleStylableElement.xwt">
- <widget href="ui/MultipleStylableElement.xwt#/"/>
- </sections>
- <sections name="SingleDiagram" sectionFile="ui/SingleDiagram.xwt">
- <widget href="ui/SingleDiagram.xwt#/"/>
- </sections>
- <sections name="SingleStyleSheetReference" sectionFile="ui/SingleStyleSheetReference.xwt">
- <widget href="ui/SingleStyleSheetReference.xwt#//@widgets.0"/>
- </sections>
- <sections name="SingleEmbeddedStyleSheet" sectionFile="ui/SingleEmbeddedStyleSheet.xwt">
- <widget href="ui/SingleEmbeddedStyleSheet.xwt#//@widgets.0"/>
- </sections>
- </tabs>
- <views name="SingleStylableElement" sections="//@tabs.0/@sections.0">
- <constraints xsi:type="constraints:SimpleConstraint" name="isSingleStylableElement" overrideable="false" overriddenConstraints="//@views.1/@constraints.0">
- <constraintType href="ppe:/environment/org.eclipse.papyrus.infra.gmfdiag.properties/model/Environment.xmi#//@constraintTypes.0"/>
- <properties xsi:type="constraints:ValueProperty" name="nsUri" value="http://www.eclipse.org/gmf/runtime/1.0.2/notation"/>
- <properties xsi:type="constraints:ValueProperty" name="className" value="View"/>
- </constraints>
- </views>
- <views elementMultiplicity="-1" name="MultipleStylableElement" sections="//@tabs.0/@sections.1">
- <constraints xsi:type="constraints:SimpleConstraint" name="isMultipleStylableElement" overrideable="false">
- <constraintType href="ppe:/environment/org.eclipse.papyrus.infra.gmfdiag.properties/model/Environment.xmi#//@constraintTypes.0"/>
- <properties xsi:type="constraints:ValueProperty" name="nsUri" value="http://www.eclipse.org/gmf/runtime/1.0.2/notation"/>
- <properties xsi:type="constraints:ValueProperty" name="className" value="View"/>
- </constraints>
- </views>
- <views name="Diagram" sections="//@tabs.0/@sections.2">
- <constraints xsi:type="constraints:SimpleConstraint" name="isDiagram" overrideable="false" overriddenConstraints="//@views.0/@constraints.0 //@views.1/@constraints.0">
- <constraintType href="ppe:/environment/org.eclipse.papyrus.infra.gmfdiag.properties/model/Environment.xmi#//@constraintTypes.0"/>
- <properties xsi:type="constraints:ValueProperty" name="nsUri" value="http://www.eclipse.org/gmf/runtime/1.0.2/notation"/>
- <properties xsi:type="constraints:ValueProperty" name="className" value="Diagram"/>
- </constraints>
- </views>
- <views name="SingleStyleSheetReference" sections="//@tabs.0/@sections.3">
- <constraints xsi:type="constraints:SimpleConstraint" name="isStyleSheetReference">
- <constraintType href="ppe:/environment/org.eclipse.papyrus.infra.constraints/Model/ConstraintEnvironment.xmi#//@constraintTypes.0"/>
- <properties xsi:type="constraints:ValueProperty" name="nsUri" value="http://www.eclipse.org/papyrus/infra/gmfdiag/css"/>
- <properties xsi:type="constraints:ValueProperty" name="className" value="StyleSheetReference"/>
- </constraints>
- </views>
- <views name="SingleEmbeddedStyleSheet" sections="//@tabs.0/@sections.4">
- <constraints xsi:type="constraints:SimpleConstraint" name="isEmbeddedStyleSheet">
- <constraintType href="ppe:/environment/org.eclipse.papyrus.infra.constraints/Model/ConstraintEnvironment.xmi#//@constraintTypes.0"/>
- <properties xsi:type="constraints:ValueProperty" name="nsUri" value="http://www.eclipse.org/papyrus/infra/gmfdiag/css"/>
- <properties xsi:type="constraints:ValueProperty" name="className" value="EmbeddedStyleSheet"/>
- </constraints>
- </views>
- <dataContexts name="CSS" label="CSS">
- <elements name="PapyrusCSSStyle">
- <properties name="cssId" label="CSS ID" description="The CSS ID of this element. The ID should be unique within a Diagram. It can be used to retrieve the style properties applied to this element."/>
- <properties name="cssClass" label="CSS Classes" multiplicity="-1" description="The list of CSS Classes associated to this element. Classes are string identifiers, used by the CSS Stylesheets to identify a set of elements on which styles should be applied."/>
- <properties name="cssStyle" label="CSS Style" description="The list of CSS properties applied to this element. This is a local style, which will only be applied on the selected element."/>
- </elements>
- <elements name="DiagramStyle" supertypes="//@dataContexts.0/@elements.0">
- <properties name="css_stylesheets" label="Diagram style sheets" type="Reference" multiplicity="-1" description="The style sheets associated to this diagram"/>
- </elements>
- <elements name="ModelStyle">
- <properties name="modelStyleSheets" label="Model style sheets" type="Reference" multiplicity="-1" description="The style sheets associated to this model"/>
- </elements>
- <modelElementFactory href="ppe:/environment/org.eclipse.papyrus.infra.gmfdiag.css.properties/model/Environment.xmi#//@modelElementFactories.0"/>
- </dataContexts>
- <dataContexts name="modelstylesheets" label="StyleSheets">
- <elements name="StyleSheetReference">
- <properties name="path" label="Path" description="The path to an external style sheet file"/>
- </elements>
- <elements name="EmbeddedStyleSheet">
- <properties name="label" label="" description="The stylesheet's label"/>
- <properties name="content" label="Contents" description="The style sheet contents"/>
- </elements>
- <elements name="ModelStyleSheet">
- <properties name="stylesheets" label="Model style sheets" type="Reference" multiplicity="-1" description="The style sheets associated to the model"/>
- </elements>
- <modelElementFactory href="ppe:/environment/org.eclipse.papyrus.views.properties/model/Environment.xmi#//@modelElementFactories.0"/>
- </dataContexts>
- <dataContexts name="Preferences" label="Preferences">
- <elements name="org.eclipse.papyrus.infra.gmfdiag.css">
- <properties name="currentTheme" label="" description="The theme currently applied to all Papyrus Diagrams in your workspace. The theme can be changed in the preferences."/>
- </elements>
- <modelElementFactory href="ppe:/environment/org.eclipse.papyrus.infra.gmfdiag.css.properties/model/Environment.xmi#//@modelElementFactories.1"/>
- </dataContexts>
-</contexts:Context>
+<?xml version="1.0" encoding="UTF-8"?> +<contexts:Context xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:constraints="http://www.eclipse.org/papyrus/constraints/0.9" xmlns:contexts="http://www.eclipse.org/papyrus/properties/contexts/0.9" name="CSS"> + <tabs label="Style" id="style" category="org.eclipse.papyrus" image="" priority="70"> + <sections name="SingleStylableElement" sectionFile="ui/SingleStylableElement.xwt"> + <widget href="ui/SingleStylableElement.xwt#/"/> + </sections> + <sections name="MultipleStylableElement" sectionFile="ui/MultipleStylableElement.xwt"> + <widget href="ui/MultipleStylableElement.xwt#/"/> + </sections> + <sections name="SingleDiagram" sectionFile="ui/SingleDiagram.xwt"> + <widget href="ui/SingleDiagram.xwt#/"/> + </sections> + <sections name="SingleStyleSheetReference" sectionFile="ui/SingleStyleSheetReference.xwt"> + <widget href="ui/SingleStyleSheetReference.xwt#//@widgets.0"/> + </sections> + <sections name="SingleEmbeddedStyleSheet" sectionFile="ui/SingleEmbeddedStyleSheet.xwt"> + <widget href="ui/SingleEmbeddedStyleSheet.xwt#//@widgets.0"/> + </sections> + <sections name="SingleTheme" sectionFile="ui/SingleTheme.xwt"> + <widget href="ui/SingleTheme.xwt#/"/> + </sections> + </tabs> + <views name="SingleStylableElement" sections="//@tabs.0/@sections.0"> + <constraints xsi:type="constraints:SimpleConstraint" name="isSingleStylableElement" overrideable="false" overriddenConstraints="//@views.1/@constraints.0"> + <constraintType href="ppe:/environment/org.eclipse.papyrus.infra.gmfdiag.properties/model/Environment.xmi#//@constraintTypes.0"/> + <properties xsi:type="constraints:ValueProperty" name="nsUri" value="http://www.eclipse.org/gmf/runtime/1.0.2/notation"/> + <properties xsi:type="constraints:ValueProperty" name="className" value="View"/> + </constraints> + </views> + <views elementMultiplicity="-1" name="MultipleStylableElement" sections="//@tabs.0/@sections.1"> + <constraints xsi:type="constraints:SimpleConstraint" name="isMultipleStylableElement" overrideable="false"> + <constraintType href="ppe:/environment/org.eclipse.papyrus.infra.gmfdiag.properties/model/Environment.xmi#//@constraintTypes.0"/> + <properties xsi:type="constraints:ValueProperty" name="nsUri" value="http://www.eclipse.org/gmf/runtime/1.0.2/notation"/> + <properties xsi:type="constraints:ValueProperty" name="className" value="View"/> + </constraints> + </views> + <views name="Diagram" sections="//@tabs.0/@sections.2"> + <constraints xsi:type="constraints:SimpleConstraint" name="isDiagram" overrideable="false" overriddenConstraints="//@views.0/@constraints.0 //@views.1/@constraints.0"> + <constraintType href="ppe:/environment/org.eclipse.papyrus.infra.gmfdiag.properties/model/Environment.xmi#//@constraintTypes.0"/> + <properties xsi:type="constraints:ValueProperty" name="nsUri" value="http://www.eclipse.org/gmf/runtime/1.0.2/notation"/> + <properties xsi:type="constraints:ValueProperty" name="className" value="Diagram"/> + </constraints> + </views> + <views name="SingleStyleSheetReference" sections="//@tabs.0/@sections.3"> + <constraints xsi:type="constraints:SimpleConstraint" name="isStyleSheetReference"> + <constraintType href="ppe:/environment/org.eclipse.papyrus.infra.constraints/Model/ConstraintEnvironment.xmi#//@constraintTypes.0"/> + <properties xsi:type="constraints:ValueProperty" name="nsUri" value="http://www.eclipse.org/papyrus/infra/gmfdiag/css"/> + <properties xsi:type="constraints:ValueProperty" name="className" value="StyleSheetReference"/> + </constraints> + </views> + <views name="SingleEmbeddedStyleSheet" sections="//@tabs.0/@sections.4"> + <constraints xsi:type="constraints:SimpleConstraint" name="isEmbeddedStyleSheet"> + <constraintType href="ppe:/environment/org.eclipse.papyrus.infra.constraints/Model/ConstraintEnvironment.xmi#//@constraintTypes.0"/> + <properties xsi:type="constraints:ValueProperty" name="nsUri" value="http://www.eclipse.org/papyrus/infra/gmfdiag/css"/> + <properties xsi:type="constraints:ValueProperty" name="className" value="EmbeddedStyleSheet"/> + </constraints> + </views> + <views name="SingleTheme" sections="//@tabs.0/@sections.5"> + <constraints xsi:type="constraints:SimpleConstraint" name="isTheme"> + <constraintType href="ppe:/environment/org.eclipse.papyrus.infra.constraints/Model/ConstraintEnvironment.xmi#//@constraintTypes.0"/> + <properties xsi:type="constraints:ValueProperty" name="nsUri" value="http://www.eclipse.org/papyrus/infra/gmfdiag/css"/> + <properties xsi:type="constraints:ValueProperty" name="className" value="Theme"/> + </constraints> + </views> + <dataContexts name="CSS" label="CSS"> + <elements name="PapyrusCSSStyle"> + <properties name="cssId" label="CSS ID" description="The CSS ID of this element. The ID should be unique within a Diagram. It can be used to retrieve the style properties applied to this element."/> + <properties name="cssClass" label="CSS Classes" multiplicity="-1" description="The list of CSS Classes associated to this element. Classes are string identifiers, used by the CSS Stylesheets to identify a set of elements on which styles should be applied."/> + <properties name="cssStyle" label="CSS Style" description="The list of CSS properties applied to this element. This is a local style, which will only be applied on the selected element."/> + </elements> + <elements name="DiagramStyle" supertypes="//@dataContexts.0/@elements.0"> + <properties name="css_stylesheets" label="Diagram style sheets" type="Reference" multiplicity="-1" description="The style sheets associated to this diagram"/> + </elements> + <elements name="ModelStyle"> + <properties name="modelStyleSheets" label="Model style sheets" type="Reference" multiplicity="-1" description="The style sheets associated to this model"/> + </elements> + <modelElementFactory href="ppe:/environment/org.eclipse.papyrus.infra.gmfdiag.css.properties/model/Environment.xmi#//@modelElementFactories.0"/> + </dataContexts> + <dataContexts name="WorkspaceThemes" label="Themes"> + <elements name="Theme"> + <properties name="label" label="Label" description="Theme label"/> + <properties name="icon" label="Icon" description="Theme icon"/> + <properties name="stylesheets" label="Theme style sheets" type="Reference" multiplicity="-1"/> + </elements> + <modelElementFactory href="ppe:/environment/org.eclipse.papyrus.infra.gmfdiag.css.properties/model/Environment.xmi#//@modelElementFactories.2"/> + </dataContexts> + <dataContexts name="modelstylesheets" label="StyleSheets"> + <elements name="StyleSheetReference"> + <properties name="path" label="Path" description="The path to an external style sheet file"/> + </elements> + <elements name="EmbeddedStyleSheet"> + <properties name="label" label="" description="The stylesheet's label"/> + <properties name="content" label="Contents" description="The style sheet contents"/> + </elements> + <elements name="ModelStyleSheet"> + <properties name="stylesheets" label="Model style sheets" type="Reference" multiplicity="-1" description="The style sheets associated to the model"/> + </elements> + <modelElementFactory href="ppe:/environment/org.eclipse.papyrus.views.properties/model/Environment.xmi#//@modelElementFactories.0"/> + </dataContexts> + <dataContexts name="Preferences" label="Preferences"> + <elements name="org.eclipse.papyrus.infra.gmfdiag.css"> + <properties name="currentTheme" label="" description="The theme currently applied to all Papyrus Diagrams in your workspace. The theme can be changed in the preferences."/> + </elements> + <modelElementFactory href="ppe:/environment/org.eclipse.papyrus.infra.gmfdiag.css.properties/model/Environment.xmi#//@modelElementFactories.1"/> + </dataContexts> +</contexts:Context> diff --git a/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/model/properties/ui/SingleTheme.xwt b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/model/properties/ui/SingleTheme.xwt new file mode 100644 index 00000000000..ddcb484a7ef --- /dev/null +++ b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/model/properties/ui/SingleTheme.xwt @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Composite xmlns="http://www.eclipse.org/xwt/presentation" + xmlns:css="clr-namespace:org.eclipse.papyrus.infra.gmfdiag.css.properties.widgets" + xmlns:ppel="clr-namespace:org.eclipse.papyrus.views.properties.widgets.layout" + xmlns:j="clr-namespace:java.lang" xmlns:ppe="clr-namespace:org.eclipse.papyrus.views.properties.widgets" + xmlns:x="http://www.eclipse.org/xwt"> + <Composite.layout> + <ppel:PropertiesLayout numColumns="1"></ppel:PropertiesLayout> + </Composite.layout> + <ppe:StringEditor input="{Binding}" property="WorkspaceThemes:Theme:label"></ppe:StringEditor> + <ppe:BrowseFilePropertyEditor input="{Binding}" + buttonLabel="Browse..." property="WorkspaceThemes:Theme:icon"> + <ppe:BrowseFilePropertyEditor.filterNames> + <x:Array Type="j:String"> + <j:String>All images</j:String> + <j:String>PNG Icon</j:String> + <j:String>GIF Icon</j:String> + <j:String>JPEG Icon</j:String> + </x:Array> + </ppe:BrowseFilePropertyEditor.filterNames> + <ppe:BrowseFilePropertyEditor.filterExtensions> + <x:Array Type="j:String"> + <j:String>*.gif;*.png;*.jpeg</j:String> + <j:String>*.png</j:String> + <j:String>*.gif</j:String> + <j:String>*.jpeg</j:String> + </x:Array> + </ppe:BrowseFilePropertyEditor.filterExtensions> + </ppe:BrowseFilePropertyEditor> + <ppe:MultiReference input="{Binding}" + property="WorkspaceThemes:Theme:stylesheets"></ppe:MultiReference> +</Composite>
\ No newline at end of file diff --git a/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/plugin.xml b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/plugin.xml index ca63aef4b60..9875e752e98 100644 --- a/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/plugin.xml +++ b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/plugin.xml @@ -13,6 +13,103 @@ environmentModel="model/Environment.xmi"> </environment> </extension> + <extension + point="org.eclipse.ui.handlers"> + <handler + class="org.eclipse.papyrus.infra.gmfdiag.css.properties.handler.CSSFileHandler" + commandId="org.eclipse.papyrus.infra.gmfdiag.css.theme.define"> + <enabledWhen> + <with + variable="selection"> + <iterate> + <adapt + type="org.eclipse.core.resources.IResource"> + <test + property="org.eclipse.core.resources.extension" + value="css"> + </test> + </adapt> + </iterate> + </with> + </enabledWhen> + </handler> + <handler + class="org.eclipse.papyrus.infra.gmfdiag.css.properties.handler.CSSFileHandler" + commandId="org.eclipse.papyrus.infra.gmfdiag.css.theme.edit"> + <enabledWhen> + <with + variable="selection"> + <iterate> + <adapt + type="org.eclipse.core.resources.IResource"> + <test + property="org.eclipse.core.resources.extension" + value="css"> + </test> + </adapt> + </iterate> + </with> + </enabledWhen> + </handler> + </extension> + <extension + point="org.eclipse.ui.commands"> + <command + categoryId="org.eclipse.papyrus.infra.gmfdiag.css.theme.category" + id="org.eclipse.papyrus.infra.gmfdiag.css.theme.define" + name="Define theme"> + </command> + <command + categoryId="org.eclipse.papyrus.infra.gmfdiag.css.theme.category" + id="org.eclipse.papyrus.infra.gmfdiag.css.theme.edit" + name="Edit theme"> + </command> + <category + id="org.eclipse.papyrus.infra.gmfdiag.css.theme.category" + name="CSS Theme"> + </category> + </extension> + <extension + point="org.eclipse.ui.menus"> + <menuContribution + allPopups="false" + locationURI="popup:org.eclipse.ui.popup.any?after=additions"> + <menu + id="org.eclipse.papyrus.infra.gmfdiag.css.theme.menu" + label="CSS Theme"> + <visibleWhen + checkEnabled="true"> + <with + variable="activePartId"> + <equals + value="org.eclipse.ui.navigator.ProjectExplorer"> + </equals> + </with> + </visibleWhen> + </menu> + </menuContribution> + <menuContribution + allPopups="false" + locationURI="popup:org.eclipse.papyrus.infra.gmfdiag.css.theme.menu"> + <command + commandId="org.eclipse.papyrus.infra.gmfdiag.css.theme.define" + style="push"> + </command> + <command + commandId="org.eclipse.papyrus.infra.gmfdiag.css.theme.edit" + style="push"> + </command> + </menuContribution> + </extension> + <extension + point="org.eclipse.ui.preferencePages"> + <page + category="org.eclipse.papyrus.infra.core.sasheditor.preferences.generalcategory" + class="org.eclipse.papyrus.infra.gmfdiag.css.properties.preferences.ThemePreferencesPage" + id="org.eclipse.papyrus.infra.gmfdiag.css.theme" + name="CSS Theme"> + </page> + </extension> <extension point="org.eclipse.ui.propertyPages"> <page diff --git a/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/src/org/eclipse/papyrus/infra/gmfdiag/css/properties/creation/ThemePropertyEditorFactory.java b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/src/org/eclipse/papyrus/infra/gmfdiag/css/properties/creation/ThemePropertyEditorFactory.java new file mode 100644 index 00000000000..bf877c5c8fb --- /dev/null +++ b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/src/org/eclipse/papyrus/infra/gmfdiag/css/properties/creation/ThemePropertyEditorFactory.java @@ -0,0 +1,58 @@ +/***************************************************************************** + * Copyright (c) 2014 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: + * Gabriel Pascual (ALL4TEC) gabriel.pascual@all4tec.net - Initial API and implementation + *****************************************************************************/ +package org.eclipse.papyrus.infra.gmfdiag.css.properties.creation; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.papyrus.infra.gmfdiag.css.stylesheets.Theme; +import org.eclipse.papyrus.views.properties.creation.EcorePropertyEditorFactory; +import org.eclipse.swt.widgets.Control; + + +/** + * Editor factor for workspace theme. + * + * @author gpascual + * + */ +public class ThemePropertyEditorFactory extends EcorePropertyEditorFactory { + + /** + * Default constructor. + * + * @param referenceIn + */ + public ThemePropertyEditorFactory(EReference referenceIn) { + super(referenceIn); + } + + + /** + * @see org.eclipse.papyrus.views.properties.creation.EcorePropertyEditorFactory#simpleCreateObject(org.eclipse.swt.widgets.Control) + * + * @param widget + * @return + */ + @Override + protected EObject simpleCreateObject(Control widget) { + EObject createdObject = super.simpleCreateObject(widget); + + //Generate an unique ID for created theme + if(createdObject instanceof Theme) { + ((Theme)createdObject).setId(EcoreUtil.generateUUID()); + } + + return createdObject; + } + +} diff --git a/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/src/org/eclipse/papyrus/infra/gmfdiag/css/properties/dialog/CSSThemeCreationDialog.java b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/src/org/eclipse/papyrus/infra/gmfdiag/css/properties/dialog/CSSThemeCreationDialog.java new file mode 100644 index 00000000000..b7f9e830e90 --- /dev/null +++ b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/src/org/eclipse/papyrus/infra/gmfdiag/css/properties/dialog/CSSThemeCreationDialog.java @@ -0,0 +1,559 @@ +/***************************************************************************** + * Copyright (c) 2014 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: + * Gabriel Pascual (ALL4TEC) gabriel.pascual@all4tec.net - Initial API and implementation + *****************************************************************************/ +package org.eclipse.papyrus.infra.gmfdiag.css.properties.dialog; + +import java.io.File; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; + +import org.eclipse.core.resources.IFile; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.viewers.BaseLabelProvider; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.window.Window; +import org.eclipse.papyrus.infra.core.services.ServiceException; +import org.eclipse.papyrus.infra.core.utils.PapyrusImageUtils; +import org.eclipse.papyrus.infra.emf.providers.EMFContentProvider; +import org.eclipse.papyrus.infra.gmfdiag.css.Activator; +import org.eclipse.papyrus.infra.gmfdiag.css.stylesheets.StyleSheetReference; +import org.eclipse.papyrus.infra.gmfdiag.css.stylesheets.StylesheetsPackage; +import org.eclipse.papyrus.infra.gmfdiag.css.stylesheets.Theme; +import org.eclipse.papyrus.infra.services.labelprovider.service.LabelProviderService; +import org.eclipse.papyrus.infra.services.labelprovider.service.impl.LabelProviderServiceImpl; +import org.eclipse.papyrus.infra.widgets.editors.TreeSelectorDialog; +import org.eclipse.papyrus.infra.widgets.providers.AbstractStaticContentProvider; +import org.eclipse.papyrus.infra.widgets.providers.WorkspaceContentProvider; +import org.eclipse.papyrus.infra.widgets.util.FileUtil; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.Tree; + + +/** + * Dialog to define a local theme from a selected CSS style. + * + * @author gpascual + */ +public class CSSThemeCreationDialog extends Dialog { + + /** Title for icon selection dialog. */ + private static final String ICON_SELECTION_DIALOG_TITLE = "Icon selection"; + + /** Label for workspace menu. */ + private static final String WORKSPACE_MENU_LABEL = "Workspace"; + + /** Label for file system menu. */ + private static final String FILE_SYSTEM_MENU_LABEL = "File System"; + + /** Id for file system menu item. */ + private static final int FILESYSTEM_MENU_ID = 15; + + /** Id for workspace menu item. */ + private static final int WORKSPACE_MENU_ID = 12; + + /** Label for browse button to select theme icon. */ + private static final String BROWSE_BUTTON_LABEL = "Browse..."; + + /** List of valid extensions for an icon. */ + private static List<String> filterExtensions = Arrays.asList(new String[]{ "*.gif;*.png;*.jpeg", "*.gif", "*.png", "*.jpeg" }); + + /** List of name associated to valid extensions. */ + private List<String> filterNames = Arrays.asList(new String[]{ "All images", "GIF Icon", "PNG Icon", "JPEG Icon" }); + + /** Text for dialog title. */ + private static final String DIALOG_TITLE = "CSS Theme Definition"; + + /** Text for theme icon field. */ + private static final String ICON_PATH_LABEL = "Icon"; + + /** Text for theme label field. */ + private static final String THEME_NAME_LABEL = "Label"; + + /** Id of browse button. */ + private static final int BROWSE_BUTTON_ID = 13; + + /** Theme to definr with dialog. */ + private Theme theme = null; + + /** Theme label field. */ + private Text themeLabelField = null; + + /** Theme icon path field. */ + private Text iconPathField = null; + + /** Theme style sheets viewer. */ + private TreeViewer styleSheetsViewer = null; + + /** Menu of browse button to select theme icon. */ + private Menu browseMenu = null; + + /** + * Default constructor. + * + * @param parentShell + * shell of parent widget + * @param theme + * theme to edit + */ + public CSSThemeCreationDialog(Shell parentShell, Theme theme) { + super(parentShell); + + // Set theme to edit + this.theme = theme; + initialiseFilterLabels(filterNames, filterExtensions); + } + + /** + * Gets the filter labels. + * + * @param filterNames + * the filter names + * @param filterExtensions + * the filter extensions + */ + private void initialiseFilterLabels(List<String> filterNames, List<String> filterExtensions) { + int size = Math.min(filterNames.size(), filterExtensions.size()); + String[] filters = new String[size]; + for(int i = 0; i < size; i++) { + filters[i] = filterNames.get(i) + " (" + filterExtensions.get(i) + ")"; + } + + this.filterNames = Arrays.asList(filters); + } + + /** + * @see org.eclipse.jface.dialogs.Dialog#getInitialSize() + * + * @return + */ + @Override + protected Point getInitialSize() { + return new Point(320, 360); + } + + /** + * @see org.eclipse.jface.dialogs.Dialog#isResizable() + * + * @return + */ + @Override + protected boolean isResizable() { + + // Set dialog resizable + return true; + } + + /** + * + * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell) + * + * @param newShell + */ + @Override + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + + // Add title and icon to dialog + newShell.setText(DIALOG_TITLE); + newShell.setImage(PapyrusImageUtils.getDefaultIcon()); + } + + + /** + * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite) + * + * @param parent + * @return + */ + @Override + protected Control createDialogArea(Composite parent) { + + // Create main container to dialog + Composite mainComposite = (Composite)super.createDialogArea(parent); + mainComposite.setLayout(new GridLayout(2, false)); + + // Add different parts to dialog + createThemeLabelPart(mainComposite); + createThemeIconPart(mainComposite); + createStyleSheetsTreeComposite(mainComposite); + + // Initialise tree viewer + initialiseTree(); + + return mainComposite; + } + + /** + * Create all components for theme label. + * + * @param parent + * Composite where components will be added + */ + private void createThemeLabelPart(Composite parent) { + + // Label for theme name field + Label themeNameLabel = new Label(parent, SWT.NONE); + themeNameLabel.setText(THEME_NAME_LABEL); + + // Field to edit theme label + themeLabelField = new Text(parent, SWT.BORDER); + GridData layoutData = new GridData(SWT.FILL, SWT.CENTER, true, false); + layoutData.horizontalSpan = 2; + themeLabelField.setLayoutData(layoutData); + + // Add behavior to text field + themeLabelField.addModifyListener(new ModifyListener() { + + public void modifyText(ModifyEvent e) { + theme.setLabel(themeLabelField.getText()); + } + }); + } + + /** + * Create all components for theme icon. + * + * @param parent + * Composite where components will be added + */ + private void createThemeIconPart(Composite parent) { + + //Label for theme icon field + Label themeIconLabel = new Label(parent, SWT.NONE); + themeIconLabel.setText(ICON_PATH_LABEL); + + // Field to edit icon path for theme + iconPathField = new Text(parent, SWT.BORDER); + iconPathField.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + + // Add behavior to text field + iconPathField.addModifyListener(new ModifyListener() { + + public void modifyText(ModifyEvent e) { + theme.setIcon(iconPathField.getText()); + } + }); + + + // Add browse button to help user + Button browseButton = createButton(parent, BROWSE_BUTTON_ID, BROWSE_BUTTON_LABEL, false); + + browseMenu = new Menu(browseButton); + + createMenuItem(browseMenu, FILE_SYSTEM_MENU_LABEL, FILESYSTEM_MENU_ID); + createMenuItem(browseMenu, WORKSPACE_MENU_LABEL, WORKSPACE_MENU_ID); + + } + + /** + * Create menu item. + * + * @param parentMenu + * Menu where it will be added + * @param label + * Label of menu item + * @param menuId + */ + private void createMenuItem(Menu parentMenu, String label, int menuId) { + + MenuItem menuItem = new MenuItem(parentMenu, SWT.NONE); + menuItem.setText(label); + menuItem.setData(new Integer(menuId)); + menuItem.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + menuSelected(((Integer)e.widget.getData()).intValue()); + } + }); + + + } + + /** + * Action to run when a menu is slected. + * + * @param menuId + * ID of selected menu + */ + private void menuSelected(int menuId) { + switch(menuId) { + case WORKSPACE_MENU_ID: + browseWorkspace(); + break; + case FILESYSTEM_MENU_ID: + browseFileSytem(); + break; + default: + // Nothing to do + break; + } + } + + /** + * Browse file in file system. + */ + private void browseFileSytem() { + File file = getFile(iconPathField.getText()); + + FileDialog dialog = new FileDialog(getShell()); + dialog.setText(ICON_SELECTION_DIALOG_TITLE); + + dialog.setFileName(file.getAbsolutePath()); + dialog.setFilterExtensions(filterExtensions.toArray(new String[filterExtensions.size()])); + dialog.setFilterNames(filterNames.toArray(new String[filterNames.size()])); + + String result = dialog.open(); + if(result == null) { //Cancel + return; + } + setResult(result); + } + + /** + * Browse file in workspace. + */ + private void browseWorkspace() { + LabelProviderService labelProviderService = new LabelProviderServiceImpl(); + try { + labelProviderService.startService(); + } catch (ServiceException ex) { + Activator.log.error(ex); + } + + ILabelProvider labelProvider = labelProviderService.getLabelProvider(); + + IFile currentFile = getIFile(iconPathField.getText()); + + TreeSelectorDialog dialog = new TreeSelectorDialog(getShell()); + dialog.setTitle(ICON_SELECTION_DIALOG_TITLE); + + + WorkspaceContentProvider contentProvider = new WorkspaceContentProvider(); + + + if(!(filterExtensions.isEmpty() || filterNames.isEmpty())) { + //The filters have been defined + contentProvider.setExtensionFilters(new LinkedHashMap<String, String>()); //Reset the default filters + + //Use our own filters + for(int i = 0; i < Math.min(filterNames.size(), filterExtensions.size()); i++) { + contentProvider.addExtensionFilter(filterExtensions.get(i), filterNames.get(i)); + } + } + + dialog.setContentProvider(contentProvider); + dialog.setLabelProvider(labelProvider); + + + if(currentFile != null && currentFile.exists()) { + dialog.setInitialSelections(new IFile[]{ currentFile }); + } + + int code = dialog.open(); + if(code == Window.OK) { + Object[] result = dialog.getResult(); + if(result.length > 0) { + Object file = result[0]; + if(file instanceof IFile) { + setResult((IFile)file); + } + } + } + } + + /** + * @see org.eclipse.jface.dialogs.Dialog#buttonPressed(int) + * + * @param buttonId + */ + @Override + protected void buttonPressed(int buttonId) { + + switch(buttonId) { + case BROWSE_BUTTON_ID: + browseMenu.setVisible(true); + break; + default: + super.buttonPressed(buttonId); + break; + } + + } + + + + /** + * Sets the result. + * + * @param file + * the new result + */ + protected void setResult(IFile file) { + iconPathField.setText(file.getFullPath().toString()); + } + + /** + * Sets the result. + * + * @param file + * the new result + */ + protected void setResult(File file) { + iconPathField.setText(file.getAbsolutePath()); + + } + + /** + * Sets the result. + * + * @param path + * the new result + */ + protected void setResult(String path) { + iconPathField.setText(path); + + } + + /** + * Gets the file. + * + * @param path + * the path + * @return the i file + */ + protected IFile getIFile(String path) { + return FileUtil.getIFile(path); + } + + /** + * Gets the file. + * + * @param path + * the path + * @return the file + */ + protected File getFile(String path) { + return FileUtil.getFile(path); + } + + + + /** + * Create composite containing style sheets viewer. + * + * @param parent + * Composite where components will be added + */ + private void createStyleSheetsTreeComposite(Composite parent) { + + styleSheetsViewer = new TreeViewer(parent, SWT.BORDER); + Tree tree = styleSheetsViewer.getTree(); + tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1)); + } + + /** + * Initialise display of style sheets tree viewer. + */ + private void initialiseTree() { + styleSheetsViewer.setContentProvider(new EMFContentProvider(theme, StylesheetsPackage.eINSTANCE.getTheme_Stylesheets()) { + + @Override + protected IStructuredContentProvider getSemanticProvider(final EObject editedEObject, final EStructuralFeature feature) { + + // Use a standard content provider + return new AbstractStaticContentProvider() { + + public Object[] getElements() { + List<Object> result = new LinkedList<Object>(); + if(editedEObject instanceof Theme) { + result.addAll(theme.getStylesheets()); + } + return result.toArray(); + } + }; + + } + }); + + styleSheetsViewer.setLabelProvider(new StyleSheetLabelProvider()); + styleSheetsViewer.setInput(theme.getStylesheets()); + } + + + /** + * Label provider for style sheets tree viwer. + * + * @author gpascual + * + */ + private class StyleSheetLabelProvider extends BaseLabelProvider implements ILabelProvider { + + /** + * Default constructor. + * + */ + public StyleSheetLabelProvider() { + super(); + } + + /** + * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object) + * + * @param element + * @return + */ + public Image getImage(Object element) { + return null; + } + + /** + * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object) + * + * @param element + * @return + */ + public String getText(Object element) { + String text = element.toString(); + + if(element instanceof StyleSheetReference) { + text = ((StyleSheetReference)element).getPath(); + } + + return text; + } + + } + +} diff --git a/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/src/org/eclipse/papyrus/infra/gmfdiag/css/properties/dialog/CSSThemeEditionDialog.java b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/src/org/eclipse/papyrus/infra/gmfdiag/css/properties/dialog/CSSThemeEditionDialog.java new file mode 100644 index 00000000000..d25c0f16e51 --- /dev/null +++ b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/src/org/eclipse/papyrus/infra/gmfdiag/css/properties/dialog/CSSThemeEditionDialog.java @@ -0,0 +1,1133 @@ +/***************************************************************************** + * Copyright (c) 2014 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: + * Gabriel Pascual (ALL4TEC) gabriel.pascual@all4tec.net - Initial API and implementation + *****************************************************************************/ +package org.eclipse.papyrus.infra.gmfdiag.css.properties.dialog; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.Assert; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.viewers.ComboViewer; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.window.Window; +import org.eclipse.papyrus.infra.core.services.ServiceException; +import org.eclipse.papyrus.infra.core.utils.PapyrusImageUtils; +import org.eclipse.papyrus.infra.emf.providers.EMFContentProvider; +import org.eclipse.papyrus.infra.gmfdiag.css.Activator; +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.stylesheets.StylesheetsPackage; +import org.eclipse.papyrus.infra.gmfdiag.css.stylesheets.Theme; +import org.eclipse.papyrus.infra.gmfdiag.css.stylesheets.WorkspaceThemes; +import org.eclipse.papyrus.infra.services.labelprovider.service.LabelProviderService; +import org.eclipse.papyrus.infra.services.labelprovider.service.impl.LabelProviderServiceImpl; +import org.eclipse.papyrus.infra.widgets.editors.MultipleValueSelectorDialog; +import org.eclipse.papyrus.infra.widgets.editors.TreeSelectorDialog; +import org.eclipse.papyrus.infra.widgets.providers.AbstractStaticContentProvider; +import org.eclipse.papyrus.infra.widgets.providers.CollectionContentProvider; +import org.eclipse.papyrus.infra.widgets.providers.WorkspaceContentProvider; +import org.eclipse.papyrus.infra.widgets.selectors.ReferenceSelector; +import org.eclipse.papyrus.infra.widgets.util.FileUtil; +import org.eclipse.papyrus.views.properties.creation.EcorePropertyEditorFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.ui.plugin.AbstractUIPlugin; + +/** + * Dialog to edit theme from an initial selection in workspace. + * + * @author gpascual + * + */ +public class CSSThemeEditionDialog extends Dialog { + + /** Title for icon selection dialog. */ + private static final String ICON_SELECTION_DIALOG_TITLE = "Icon selection"; + + /** Label for workspace menu. */ + private static final String WORKSPACE_MENU_LABEL = "Workspace"; + + /** Label for file system menu. */ + private static final String FILESYSTEM_MENU_LABEL = "File System"; + + /** Id of workspace menu. */ + private static final int WORKSPACE_MENU_ID = 23; + + /** Id of of file system menu */ + private static final int FILESYSTEM_MENU_ID = 22; + + /** Id of edit button. */ + private static final int EDIT_BUTTON_ID = 19; + + /** Id of down button. */ + private static final int DOWN_BUTTON_ID = 18; + + /** Id of up button. */ + private static final int UP_BUTTON_ID = 17; + + /** ID of delete button. */ + private static final int DELETE_BUTTON_ID = 15; + + /** ID of add button. */ + private static final int ADD_BUTTON_ID = 14; + + /** ID of browse buton. */ + private static final int BROWSE_BUTTON_ID = 16; + + /** Array of all id's buttons which were added in dialog. */ + private static int[] actionIdList = new int[]{ DOWN_BUTTON_ID, UP_BUTTON_ID, DELETE_BUTTON_ID, ADD_BUTTON_ID, BROWSE_BUTTON_ID, EDIT_BUTTON_ID }; + + /** Title for add action dialog. */ + private static final String ADD_DIALOG_TITLE = "Style sheets selection"; + + /** Icon for edit action button. */ + private static final Image EDIT_ICON = AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.papyrus.infra.widgets", "icons/Edit_12x12.gif").createImage(); //$NON-NLS-1$ //$NON-NLS-2$ + + /** Icon for delete action button. */ + private static final Image DELETE_ICON = AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.papyrus.infra.widgets", "icons/Delete_12x12.gif").createImage(); //$NON-NLS-1$ //$NON-NLS-2$ + + /** Icon for add action button. */ + private static final Image ADD_ICON = AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.papyrus.infra.widgets", "icons/Add_12x12.gif").createImage(); //$NON-NLS-1$ //$NON-NLS-2$ + + /** Icon for up action button. */ + private static final Image UP_ICON = AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.papyrus.infra.widgets", "icons/Up_12x12.gif").createImage(); //$NON-NLS-1$ //$NON-NLS-2$ + + /** Icon for down action button. */ + private static final Image DOWN_ICON = AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.papyrus.infra.widgets", "icons/Down_12x12.gif").createImage(); //$NON-NLS-1$ //$NON-NLS-2$ + + /** Text for style sheets list label. */ + private static final String STYLE_SHEETS_LABEL = "Style sheets"; + + /** Text for browse button. */ + private static final String BROWSE_BUTTON_LABEL = "Browse..."; + + /** Text for theme icon label. */ + private static final String THEME_ICON_LABEL = "Icon"; + + /** Text for theme name label. */ + private static final String THEME_NAME_LABEL = "Label"; + + /** Text for theme combo label. */ + private static final String THEME_COMBO_LABEL = "Theme"; + + /** Title of dialog. */ + private static final String DIALOG_TITLE = "CSS Theme Edition"; + + /** List of valid extensions for an icon. */ + private List<String> filterExtensions = Arrays.asList(new String[]{ "*.gif;*.png;*.jpeg", "*.gif", "*.png", "*.jpeg" }); + + /** List of name associated to valid extensions. */ + private List<String> filterNames = Arrays.asList(new String[]{ "All images", "GIF Icon", "PNG Icon", "JPEG Icon" }); + + /** Field for theme label. */ + private Text themeLabelField = null; + + /** Field for theme icon path. */ + private Text iconPathfield = null; + + /** Workspace themes from preference file. */ + private WorkspaceThemes workspaceThemes = null; + + /** Initial selection in workspace. */ + private List<StyleSheet> selectedStyleSheetsList = null; + + /** Viewer for style sheets of current theme. */ + private TreeViewer themeStyleSheetsViewer = null; + + /** Factory to edit contents of dialog. */ + private EcorePropertyEditorFactory editorFactory = new EcorePropertyEditorFactory(StylesheetsPackage.eINSTANCE.getTheme_Stylesheets()); + + /** Current edited theme. */ + private Theme currentTheme = null; + + /** Label provider for different composites. */ + private LabelProvider labelProvider = null; + + /** Menu for browse button. */ + private Menu browseMenu = null; + + + /** + * Default constructor. + * + * @param parentShell + */ + public CSSThemeEditionDialog(Shell parentShell, WorkspaceThemes themes, IStructuredSelection parentSelection) { + super(parentShell); + workspaceThemes = themes; + initialiseFilterLabels(filterNames, filterExtensions); + initialiseWithSelection(parentSelection); + } + + + /** + * Gets the filter labels. + * + * @param filterNames + * the filter names + * @param filterExtensions + * the filter extensions + */ + private void initialiseFilterLabels(List<String> filterNames, List<String> filterExtensions) { + int size = Math.min(filterNames.size(), filterExtensions.size()); + String[] filters = new String[size]; + for(int i = 0; i < size; i++) { + filters[i] = filterNames.get(i) + " (" + filterExtensions.get(i) + ")"; + } + this.filterNames = Arrays.asList(filters); + } + + /** + * Initialise selected style sheets list with selection. + * + * @param selection + * Source to extract style sheets + */ + private void initialiseWithSelection(IStructuredSelection selection) { + Assert.isNotNull(selection); + + // Instantiate an empty list + selectedStyleSheetsList = new ArrayList<StyleSheet>(); + + // Create iterator and factory for initialisation + Iterator<?> selectionIterator = selection.iterator(); + StylesheetsFactory styleSheetsFactory = StylesheetsFactory.eINSTANCE; + + // Explore selection + while(selectionIterator.hasNext()) { + + // Check only file from selection + Object object = selectionIterator.next(); + if(object instanceof IFile) { + + // Create a style sheet reference and add it to list + StyleSheetReference reference = styleSheetsFactory.createStyleSheetReference(); + reference.setPath(((IFile)object).getFullPath().toString()); + + selectedStyleSheetsList.add(reference); + } + } + + + } + + /** + * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell) + * + * @param newShell + */ + @Override + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + + // Set title and icon of dialog + newShell.setText(DIALOG_TITLE); + newShell.setImage(PapyrusImageUtils.getDefaultIcon()); + } + + /** + * Create contents of the dialog. + * + * @param parent + */ + @Override + protected Control createDialogArea(Composite parent) { + Composite container = (Composite)super.createDialogArea(parent); + container.setLayout(new GridLayout(2, false)); + + createEditedThemeComposite(container); + createThemeLabelPart(container); + createThemeIconPart(container); + createTreeActionButtons(container); + createThemeStyleSheetsPart(container); + + refreshDialogContent(null); + + return container; + } + + /** + * Create composite whith that can select theme to edit. + * + * @param parent + * Parent composite where components will be added + */ + private void createEditedThemeComposite(Composite parent) { + + // Label for combo of themes + Label themeLabel = new Label(parent, SWT.NONE); + themeLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false)); + themeLabel.setText(THEME_COMBO_LABEL); + + // Create a combo so that user can choice theme to edit + ComboViewer comboViewer = new ComboViewer(parent, SWT.READ_ONLY); + comboViewer.addSelectionChangedListener(new ISelectionChangedListener() { + + /** + * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent) + * + * @param event + */ + public void selectionChanged(SelectionChangedEvent event) { + + // Refresh content of dialog + refreshDialogContent(event.getSelection()); + + } + }); + + // Add label provider to combo viewer + comboViewer.setLabelProvider(new LabelProvider() { + + /** + * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object) + * + * @param element + * @return + */ + @Override + public String getText(Object element) { + + // Super return as default result + String text = super.getText(element); + + // Display label of theme in combo viewer + if(element instanceof Theme) { + text = ((Theme)element).getLabel(); + } + + + return text; + } + }); + + comboViewer.setContentProvider(new EMFContentProvider(workspaceThemes, StylesheetsPackage.eINSTANCE.getWorkspaceThemes_Themes()) { + + /** + * @see org.eclipse.papyrus.infra.emf.providers.EMFContentProvider#getSemanticProvider(org.eclipse.emf.ecore.EObject, + * org.eclipse.emf.ecore.EStructuralFeature) + * + * @param editedEObject + * @param feature + * @return + */ + @Override + protected IStructuredContentProvider getSemanticProvider(final EObject editedEObject, final EStructuralFeature feature) { + + // Use a standard content provider + return new AbstractStaticContentProvider() { + + public Object[] getElements() { + + List<Object> result = new LinkedList<Object>(); + + // Create list with workspace themes + if(editedEObject instanceof WorkspaceThemes) { + result.addAll(workspaceThemes.getThemes()); + } + + return result.toArray(); + } + }; + + } + }); + + comboViewer.setInput(workspaceThemes.getThemes()); + Combo combo = comboViewer.getCombo(); + combo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); + } + + /** + * Create theme label composite. + * + * @param parent + * Parent composite where components will be added + */ + private void createThemeLabelPart(Composite parent) { + + // Create label for label field + Label themeNameLabel = new Label(parent, SWT.NONE); + themeNameLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false)); + themeNameLabel.setText(THEME_NAME_LABEL); + + // Add theme label field + themeLabelField = new Text(parent, SWT.BORDER); + GridData gd_text = new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1); + themeLabelField.setLayoutData(gd_text); + + themeLabelField.addModifyListener(new ModifyListener() { + + public void modifyText(ModifyEvent e) { + currentTheme.setLabel(themeLabelField.getText()); + + } + }); + } + + /** + * Create theme icon part. + * + * @param parent + * Parent composite where components will be added + */ + private void createThemeIconPart(Composite parent) { + Label iconLabel = new Label(parent, SWT.NONE); + iconLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false)); + iconLabel.setText(THEME_ICON_LABEL); + + iconPathfield = new Text(parent, SWT.BORDER); + iconPathfield.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + iconPathfield.addModifyListener(new ModifyListener() { + + public void modifyText(ModifyEvent e) { + currentTheme.setIcon(iconPathfield.getText()); + + } + }); + Button browseButton = createButton(parent, BROWSE_BUTTON_ID, BROWSE_BUTTON_LABEL, false); + browseMenu = new Menu(browseButton); + + createMenuItem(browseMenu, FILESYSTEM_MENU_LABEL, FILESYSTEM_MENU_ID); + createMenuItem(browseMenu, WORKSPACE_MENU_LABEL, WORKSPACE_MENU_ID); + } + + /** + * Create menu item. + * + * @param parentMenu + * Menu where it will be added + * @param label + * Label of menu item + * @param menuId + */ + private void createMenuItem(Menu parentMenu, String label, int menuId) { + + MenuItem menuItem = new MenuItem(browseMenu, SWT.NONE); + menuItem.setText(label); + menuItem.setData(new Integer(menuId)); + menuItem.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + menuSelected(((Integer)e.widget.getData()).intValue()); + } + }); + + + } + + /** + * Action to run when a menu is slected. + * + * @param menuId + * ID of selected menu + */ + private void menuSelected(int menuId) { + switch(menuId) { + case WORKSPACE_MENU_ID: + browseWorkspace(); + break; + case FILESYSTEM_MENU_ID: + browseFileSytem(); + break; + default: + // Nothing to do + break; + } + } + + /** + * Browse file in file system. + */ + private void browseFileSytem() { + File file = getFile(iconPathfield.getText()); + + FileDialog dialog = new FileDialog(getShell()); + dialog.setText(ICON_SELECTION_DIALOG_TITLE); + + dialog.setFileName(file.getAbsolutePath()); + dialog.setFilterExtensions(filterExtensions.toArray(new String[filterExtensions.size()])); + dialog.setFilterNames(filterNames.toArray(new String[filterNames.size()])); + String result = dialog.open(); + if(result == null) { //Cancel + return; + } + setResult(result); + } + + /** + * Browse file in workspace. + */ + private void browseWorkspace() { + LabelProviderService labelProviderService = new LabelProviderServiceImpl(); + try { + labelProviderService.startService(); + } catch (ServiceException ex) { + Activator.log.error(ex); + } + + ILabelProvider labelProvider = labelProviderService.getLabelProvider(); + + IFile currentFile = getIFile(iconPathfield.getText()); + + TreeSelectorDialog dialog = new TreeSelectorDialog(getShell()); + dialog.setTitle(ICON_SELECTION_DIALOG_TITLE); + + + WorkspaceContentProvider contentProvider = new WorkspaceContentProvider(); + + + if(!(filterExtensions.isEmpty() || filterNames.isEmpty())) { + //The filters have been defined + contentProvider.setExtensionFilters(new LinkedHashMap<String, String>()); //Reset the default filters + + //Use our own filters + for(int i = 0; i < Math.min(filterNames.size(), filterExtensions.size()); i++) { + contentProvider.addExtensionFilter(filterExtensions.get(i), filterNames.get(i)); + } + } + + dialog.setContentProvider(contentProvider); + dialog.setLabelProvider(labelProvider); + + + if(currentFile != null && currentFile.exists()) { + dialog.setInitialSelections(new IFile[]{ currentFile }); + } + + int code = dialog.open(); + if(code == Window.OK) { + Object[] result = dialog.getResult(); + if(result.length > 0) { + Object file = result[0]; + if(file instanceof IFile) { + setResult((IFile)file); + } + } + } + } + + + /** + * Sets the result. + * + * @param file + * the new result + */ + protected void setResult(IFile file) { + iconPathfield.setText(file.getFullPath().toString()); + } + + /** + * Sets the result. + * + * @param file + * the new result + */ + protected void setResult(File file) { + iconPathfield.setText(file.getAbsolutePath()); + + } + + /** + * Sets the result. + * + * @param path + * the new result + */ + protected void setResult(String path) { + iconPathfield.setText(path); + + } + + /** + * Gets the file. + * + * @param path + * the path + * @return the i file + */ + protected IFile getIFile(String path) { + return FileUtil.getIFile(path); + } + + /** + * Gets the file. + * + * @param path + * the path + * @return the file + */ + protected File getFile(String path) { + return FileUtil.getFile(path); + } + + + /** + * Create theme style sheets part. + * + * @param parent + * Parent composite where components will be added + */ + private void createThemeStyleSheetsPart(Composite parent) { + + // Create viewer + themeStyleSheetsViewer = new TreeViewer(parent, SWT.BORDER); + + // Set standard collection content provider + themeStyleSheetsViewer.setContentProvider(CollectionContentProvider.instance); + + labelProvider = new LabelProvider() { + + /** + * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object) + * + * @param element + * @return + */ + @Override + public String getText(Object element) { + + // Use ancestor result as default + String text = super.getText(element); + + // Display path of style sheet reference + if(element instanceof StyleSheetReference) { + text = ((StyleSheetReference)element).getPath(); + } else if(element instanceof EmbeddedStyleSheet) { + text = ((EmbeddedStyleSheet)element).getLabel(); + } + + return text; + } + }; + themeStyleSheetsViewer.setLabelProvider(labelProvider); + + // Set layout + Tree tree = themeStyleSheetsViewer.getTree(); + tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1)); + + + } + + /** + * Create actions associate to tree viewer. + * + * @param parent + * Composite where action buttons will be added + */ + private void createTreeActionButtons(Composite parent) { + Label labelViewer = new Label(parent, SWT.NONE); + labelViewer.setText(STYLE_SHEETS_LABEL); + + Composite buttonsPanel = new Composite(parent, SWT.NONE); + buttonsPanel.setLayout(new GridLayout()); + buttonsPanel.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, true, false, 2, 1)); + + createButton(buttonsPanel, ADD_BUTTON_ID, ADD_ICON, false); + createButton(buttonsPanel, DELETE_BUTTON_ID, DELETE_ICON, false); + createButton(buttonsPanel, UP_BUTTON_ID, UP_ICON, false); + createButton(buttonsPanel, DOWN_BUTTON_ID, DOWN_ICON, false); + createButton(buttonsPanel, EDIT_BUTTON_ID, EDIT_ICON, false); + + } + + + /** + * Override method to create a button with an icon and no label. + * + * @see org.eclipse.jface.dialogs.Dialog#createButton(Composite, int, String, boolean) + * + * @param parent + * @param id + * @param icon + * @return + */ + protected Button createButton(Composite parent, int id, Image icon, boolean defaultButton) { + Button button = super.createButton(parent, id, "", defaultButton); + button.setImage(icon); + return button; + } + + /** + * + * Override method to define specific data layout for own dialog's buttons. + * + * @see org.eclipse.jface.dialogs.Dialog#setButtonLayoutData(org.eclipse.swt.widgets.Button) + * + * @param button + */ + @Override + protected void setButtonLayoutData(Button button) { + + // Determine id of button + Object data = button.getData(); + int buttonId = -1; + if(data instanceof Integer) { + buttonId = (Integer)data; + } + + //Filter specific button to set data layout + switch(buttonId) { + case ADD_BUTTON_ID: + case DELETE_BUTTON_ID: + case UP_BUTTON_ID: + case DOWN_BUTTON_ID: + case EDIT_BUTTON_ID: + button.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); + break; + default: + super.setButtonLayoutData(button); + break; + } + + + } + + /** + * Delete current selection of tree viewer. + */ + private void deleteAction() { + ISelection selection = themeStyleSheetsViewer.getSelection(); + + if(selection instanceof IStructuredSelection) { + Object selectedElement = ((IStructuredSelection)selection).getFirstElement(); + if(selectedElement instanceof StyleSheet) { + currentTheme.getStylesheets().remove(selectedElement); + } + + themeStyleSheetsViewer.setInput(currentTheme.getStylesheets()); + refreshTreeviewer(currentTheme); + } + + } + + + /** + * Open a dialog to add a style sheet to current selected theme. + */ + private void addAction() { + + + ReferenceSelector selector = new ReferenceSelector(true); + selector.setContentProvider(new EMFContentProvider(currentTheme, StylesheetsPackage.eINSTANCE.getTheme_Stylesheets()) { + + @Override + protected IStructuredContentProvider getSemanticProvider(final EObject editedEObject, final EStructuralFeature feature) { + + // Use a standard content provider + return new AbstractStaticContentProvider() { + + public Object[] getElements() { + List<Object> result = new LinkedList<Object>(); + if(editedEObject instanceof Theme) { + result.addAll(currentTheme.getStylesheets()); + } + return result.toArray(); + } + }; + } + }); + selector.setLabelProvider(labelProvider); + + // Use common component for add dialog and parameterize it + MultipleValueSelectorDialog vDialog = new MultipleValueSelectorDialog(getShell(), selector, ADD_DIALOG_TITLE); + vDialog.setContextElement(currentTheme); + vDialog.setLabelProvider(labelProvider); + vDialog.setFactory(new EcorePropertyEditorFactory(StylesheetsPackage.Literals.THEME__STYLESHEETS)); + + // Handle dialog result + int result = vDialog.open(); + if(result == Dialog.OK) { + + Object[] resultArray = vDialog.getResult(); + refreshStyleSheets(resultArray); + + } + } + + + /** + * Move up the selected style sheet in list. + */ + private void upAction() { + + // Handle selection to extract selected style sheet + ISelection selection = themeStyleSheetsViewer.getSelection(); + if(selection instanceof IStructuredSelection) { + Object selectedElement = ((IStructuredSelection)selection).getFirstElement(); + + if(selectedElement instanceof StyleSheet) { + + // Get index of selected style sheet in list + EList<StyleSheet> stylesheetsList = currentTheme.getStylesheets(); + int index = stylesheetsList.indexOf(selectedElement); + + // Check if selected style sheet is not at top of list + if(index > 0) { + stylesheetsList.move(--index, (StyleSheet)selectedElement); + themeStyleSheetsViewer.setInput(stylesheetsList); + } + } + } + } + + /** + * Move down the selected style sheet in list. + */ + private void downAction() { + + // Handle selection to extract selected style sheet + ISelection selection = themeStyleSheetsViewer.getSelection(); + + if(selection instanceof IStructuredSelection) { + Object selectedElement = ((IStructuredSelection)selection).getFirstElement(); + + if(selectedElement instanceof StyleSheet) { + + // Get index of selected style sheet in list + EList<StyleSheet> stylesheetsList = currentTheme.getStylesheets(); + int index = stylesheetsList.indexOf(selectedElement); + + // Check if selected style sheet is not at bottom of list + if(index < stylesheetsList.size() - 1) { + stylesheetsList.move(++index, (StyleSheet)selectedElement); + themeStyleSheetsViewer.setInput(stylesheetsList); + } + } + } + } + + + /** + * Edit action on selected style sheet in tree viewer. + */ + private void editAction() { + + ISelection selection = themeStyleSheetsViewer.getSelection(); + + if(selection instanceof IStructuredSelection) { + Object selectedObject = ((IStructuredSelection)selection).getFirstElement(); + if(selectedObject instanceof StyleSheet) { + // Use editor factory + editorFactory.edit(getContents(), selectedObject); + } + } + + + } + + + /** + * Fill style sheets viewer with selected style sheets. + * + * @param result + * Result from dialog selection + */ + private void refreshStyleSheets(Object[] result) { + + // Complete current theme with dialog result + for(Object object : result) { + + // Check if this is a style sheet + if(object instanceof StyleSheet) + currentTheme.getStylesheets().add((StyleSheet)object); + } + + refreshTreeviewer(currentTheme); + } + + + /** + * Refresh content of tree viewer according to selected theme/ + * + * @param currentTheme + * Current theme + */ + private void refreshTreeviewer(Theme currentTheme) { + + if(currentTheme != null) { + + EList<StyleSheet> themeStyleSheetsList = currentTheme.getStylesheets(); + + + // For each selected reference, check match with existing reference in theme + for(StyleSheet basereference : selectedStyleSheetsList) { + + // Flag for search + boolean found = false; + int i = 0; + + // Explore theme style s + while(i < themeStyleSheetsList.size() && !found) { + + // Use own comparator to determine if style sheet reference exist + found = StylesheetsComparator.instance.compare(themeStyleSheetsList.get(i), basereference) == 0; + i++; + } + + // Add selected reference only if it don't exist in theme + if(!found) { + themeStyleSheetsList.add(basereference); + } + } + + // Set mirroring list as viewer input + themeStyleSheetsViewer.setInput(themeStyleSheetsList); + } + + updateButtons(currentTheme); + + } + + + /** + * + * Update state of dialog buttons. + * + * @param currentTheme + * Selected theme which determine state of different buttons. + */ + private void updateButtons(Theme currentTheme) { + boolean editionEnable = currentTheme != null; + + for(int buttonId : actionIdList) { + switch(buttonId) { + case ADD_BUTTON_ID: + case BROWSE_BUTTON_ID: + getButton(buttonId).setEnabled(editionEnable); + break; + case DELETE_BUTTON_ID: + case EDIT_BUTTON_ID: + getButton(buttonId).setEnabled(editionEnable && !currentTheme.getStylesheets().isEmpty()); + break; + case UP_BUTTON_ID: + case DOWN_BUTTON_ID: + getButton(buttonId).setEnabled(editionEnable && (currentTheme.getStylesheets().size() > 1)); + default: + break; + } + + } + + } + + /** + * Refresh dialog area according to combo selection. + * + * @param selection + * selection which comes from combo viewer + */ + protected void refreshDialogContent(ISelection selection) { + + // Current selected theme + currentTheme = null; + + // Get selected theme from combo + if(selection instanceof IStructuredSelection) { + Object selectedElement = ((IStructuredSelection)selection).getFirstElement(); + + if(selectedElement instanceof Theme) { + currentTheme = (Theme)selectedElement; + } + } + + + + boolean editionEnable = currentTheme != null; + themeLabelField.setEditable(editionEnable); + iconPathfield.setEditable(editionEnable); + + if(editionEnable) { + + // Refresh text field (label, icon path, ...) + String themeLabel = currentTheme.getLabel(); + if(themeLabel == null) { + themeLabel = ""; + } + themeLabelField.setText(themeLabel); + + + String iconPath = currentTheme.getIcon(); + if(iconPath == null) { + iconPath = ""; + } + iconPathfield.setText(iconPath); + } + + // Tree viewer + refreshTreeviewer(currentTheme); + + } + + + /** + * Create contents of the button bar. + * + * @param parent + */ + @Override + protected void createButtonsForButtonBar(Composite parent) { + createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true); + createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); + } + + /** + * @see org.eclipse.jface.dialogs.Dialog#buttonPressed(int) + * + * @param buttonId + */ + @Override + protected void buttonPressed(int buttonId) { + switch(buttonId) { + case ADD_BUTTON_ID: + addAction(); + break; + case DELETE_BUTTON_ID: + deleteAction(); + break; + case BROWSE_BUTTON_ID: + browseMenu.setVisible(true); + break; + case UP_BUTTON_ID: + upAction(); + break; + case DOWN_BUTTON_ID: + downAction(); + break; + case EDIT_BUTTON_ID: + editAction(); + default: + super.buttonPressed(buttonId); + } + } + + + + /** + * Return the initial size of the dialog. + */ + @Override + protected Point getInitialSize() { + return new Point(450, 300); + } + + /** + * @see org.eclipse.jface.dialogs.Dialog#isResizable() + * + * @return + */ + @Override + protected boolean isResizable() { + return true; + } + + /** + * @return last selected theme for edition + */ + public Theme getEditedTheme() { + return currentTheme; + } + + /** + * Comparator basic for style sheets. It compare path for reference and label for embedded. + */ + public static class StylesheetsComparator implements Comparator<StyleSheet> { + + public static final Comparator<StyleSheet> instance = new StylesheetsComparator(); + + /** + * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) + * + * @param firstStyleSheet + * @param secondStyleSheet + * @return + */ + public int compare(StyleSheet firstStyleSheet, StyleSheet secondStyleSheet) { + + // Default result for comparison + boolean comparisonResult = false; + String rightOperand = null; + String leftOperand = null; + + if(firstStyleSheet instanceof StyleSheetReference && secondStyleSheet instanceof StyleSheetReference) { + + // Get both compared reference path + rightOperand = ((StyleSheetReference)firstStyleSheet).getPath(); + leftOperand = ((StyleSheetReference)secondStyleSheet).getPath(); + + // Use standard string comparison + comparisonResult = rightOperand.equals(leftOperand); + + } else if(firstStyleSheet instanceof EmbeddedStyleSheet && secondStyleSheet instanceof EmbeddedStyleSheet) { + + // Get both of compared embedded label + rightOperand = ((EmbeddedStyleSheet)firstStyleSheet).getLabel(); + leftOperand = ((EmbeddedStyleSheet)secondStyleSheet).getLabel(); + + // Use standard string comparison + comparisonResult = rightOperand.equals(leftOperand); + } + + // Final comparison value + int comparisonValue = -1; + if(comparisonResult) { + comparisonValue = 0; + } + + return comparisonValue; + } + + + + } + +} diff --git a/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/src/org/eclipse/papyrus/infra/gmfdiag/css/properties/fieldeditor/IDynamicFieldEditor.java b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/src/org/eclipse/papyrus/infra/gmfdiag/css/properties/fieldeditor/IDynamicFieldEditor.java new file mode 100644 index 00000000000..6e5def40a0d --- /dev/null +++ b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/src/org/eclipse/papyrus/infra/gmfdiag/css/properties/fieldeditor/IDynamicFieldEditor.java @@ -0,0 +1,41 @@ +/***************************************************************************** + * Copyright (c) 2014 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: + * Gabriel Pascual (ALL4TEC) gabriel.pascual@all4tec.net - Initial API and implementation + *****************************************************************************/ +package org.eclipse.papyrus.infra.gmfdiag.css.properties.fieldeditor; + + +/** + * Interface for dynamic field editor. Standard field editors don't permit to update its input or set current selection. + * + * @author gpascual + */ +public interface IDynamicFieldEditor { + + + /** + * Set input to field editor. + * + * @param input + * New value of field editor input + */ + void setInput(Object input); + + /** + * Set current selection to field editor. + * + * @param selectedValue + * Value of selected element + * + */ + void setSelection(String selectedValue); + + +} diff --git a/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/src/org/eclipse/papyrus/infra/gmfdiag/css/properties/fieldeditor/InputComboFieldEditor.java b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/src/org/eclipse/papyrus/infra/gmfdiag/css/properties/fieldeditor/InputComboFieldEditor.java new file mode 100644 index 00000000000..76d8e9515ac --- /dev/null +++ b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/src/org/eclipse/papyrus/infra/gmfdiag/css/properties/fieldeditor/InputComboFieldEditor.java @@ -0,0 +1,279 @@ +/***************************************************************************** + * Copyright (c) 2014 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: + * Gabriel Pascual (ALL4TEC) gabriel.pascual@all4tec.net - Initial API and implementation + *****************************************************************************/ +package org.eclipse.papyrus.infra.gmfdiag.css.properties.fieldeditor; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.preference.FieldEditor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + + +/** + * Implementation of dynamic combo field editor. Add {@link IDynamicFieldEditor} interface behavior to standard combo field editor. + * + * @see org.eclipse.jface.preference.ComboFieldEditor + * + * @author gpascual + * + */ +public class InputComboFieldEditor extends FieldEditor implements IDynamicFieldEditor { + + /** + * The <code>Combo</code> widget. + */ + private Combo combo = null; + + /** + * The value (not the name) of the currently selected item in the Combo widget. + */ + private String value = null; + + /** + * The names (labels) and underlying values to populate the combo widget. These should be + * arranged as: { {name1, value1}, {name2, value2}, ...} + */ + private String[][] fEntryNamesAndValues = null; + + /** + * Create the combo box field editor. + * + * @param name + * the name of the preference this field editor works on + * @param labelText + * the label text of the field editor + * @param entryNamesAndValues + * the names (labels) and underlying values to populate the combo widget. These should be + * arranged as: { {name1, value1}, {name2, value2}, ...} + * @param parent + * the parent composite + */ + public InputComboFieldEditor(String name, String labelText, String[][] entryNamesAndValues, Composite parent) { + init(name, labelText); + Assert.isTrue(checkArray(entryNamesAndValues)); + fEntryNamesAndValues = entryNamesAndValues; + createControl(parent); + } + + /** + * Checks whether given <code>String[][]</code> is of "type" <code>String[][2]</code>. + * + * @return <code>true</code> if it is ok, and <code>false</code> otherwise + */ + private boolean checkArray(String[][] table) { + if(table == null) { + return false; + } + for(int i = 0; i < table.length; i++) { + String[] array = table[i]; + if(array == null || array.length != 2) { + return false; + } + } + return true; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.preference.FieldEditor#adjustForNumColumns(int) + */ + @Override + protected void adjustForNumColumns(int numColumns) { + if(numColumns > 1) { + Control control = getLabelControl(); + int left = numColumns; + if(control != null) { + ((GridData)control.getLayoutData()).horizontalSpan = 1; + left = left - 1; + } + ((GridData)combo.getLayoutData()).horizontalSpan = left; + } else { + Control control = getLabelControl(); + if(control != null) { + ((GridData)control.getLayoutData()).horizontalSpan = 1; + } + ((GridData)combo.getLayoutData()).horizontalSpan = 1; + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.preference.FieldEditor#doFillIntoGrid(org.eclipse.swt.widgets.Composite, int) + */ + @Override + protected void doFillIntoGrid(Composite parent, int numColumns) { + int comboC = 1; + if(numColumns > 1) { + comboC = numColumns - 1; + } + Control control = getLabelControl(parent); + GridData gd = new GridData(); + gd.horizontalSpan = 1; + control.setLayoutData(gd); + control = getComboBoxControl(parent); + gd = new GridData(); + gd.horizontalSpan = comboC; + gd.horizontalAlignment = GridData.FILL; + control.setLayoutData(gd); + control.setFont(parent.getFont()); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.preference.FieldEditor#doLoad() + */ + @Override + protected void doLoad() { + updateComboForValue(getPreferenceStore().getString(getPreferenceName())); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.preference.FieldEditor#doLoadDefault() + */ + @Override + protected void doLoadDefault() { + updateComboForValue(getPreferenceStore().getDefaultString(getPreferenceName())); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.preference.FieldEditor#doStore() + */ + @Override + protected void doStore() { + if(value == null) { + getPreferenceStore().setToDefault(getPreferenceName()); + return; + } + getPreferenceStore().setValue(getPreferenceName(), value); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.preference.FieldEditor#getNumberOfControls() + */ + @Override + public int getNumberOfControls() { + return 2; + } + + /* + * Lazily create and return the Combo control. + */ + private Combo getComboBoxControl(Composite parent) { + if(combo == null) { + combo = new Combo(parent, SWT.READ_ONLY); + combo.setFont(parent.getFont()); + for(int i = 0; i < fEntryNamesAndValues.length; i++) { + combo.add(fEntryNamesAndValues[i][0], i); + } + + combo.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent evt) { + String oldValue = value; + String name = combo.getText(); + value = getValueForName(name); + setPresentsDefaultValue(false); + fireValueChanged(VALUE, oldValue, value); + } + }); + } + return combo; + } + + /* + * Given the name (label) of an entry, return the corresponding value. + */ + private String getValueForName(String name) { + for(int i = 0; i < fEntryNamesAndValues.length; i++) { + String[] entry = fEntryNamesAndValues[i]; + if(name.equals(entry[0])) { + return entry[1]; + } + } + return fEntryNamesAndValues[0][0]; + } + + /* + * Set the name in the combo widget to match the specified value. + */ + private void updateComboForValue(String value) { + this.value = value; + for(int i = 0; i < fEntryNamesAndValues.length; i++) { + if(value.equals(fEntryNamesAndValues[i][1])) { + combo.setText(fEntryNamesAndValues[i][0]); + return; + } + } + if(fEntryNamesAndValues.length > 0) { + value = fEntryNamesAndValues[0][1]; + combo.setText(fEntryNamesAndValues[0][0]); + } + } + + /** + * @see org.eclipse.jface.preference.FieldEditor#setEnabled(boolean, org.eclipse.swt.widgets.Composite) + * + * @param enabled + * @param parent + */ + @Override + public void setEnabled(boolean enabled, Composite parent) { + super.setEnabled(enabled, parent); + getComboBoxControl(parent).setEnabled(enabled); + } + + /** + * @see org.eclipse.papyrus.infra.gmfdiag.css.properties.fieldeditor.IDynamicFieldEditor#setInput(java.lang.Object) + * + * @param input + */ + public void setInput(Object input) { + + if(input.getClass().equals(fEntryNamesAndValues.getClass())) { + fEntryNamesAndValues = (String[][])input; + } + + combo.removeAll(); + for(int i = 0; i < fEntryNamesAndValues.length; i++) { + combo.add(fEntryNamesAndValues[i][0], i); + } + + doLoad(); + + } + + /** + * @see org.eclipse.papyrus.infra.gmfdiag.css.properties.fieldeditor.IDynamicFieldEditor#setSelection(java.lang.String) + * + * @param newValue + */ + public void setSelection(String newValue) { + String oldValue = this.value; + updateComboForValue(newValue); + fireValueChanged(VALUE, oldValue, newValue); + + } +} diff --git a/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/src/org/eclipse/papyrus/infra/gmfdiag/css/properties/handler/CSSFileHandler.java b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/src/org/eclipse/papyrus/infra/gmfdiag/css/properties/handler/CSSFileHandler.java new file mode 100644 index 00000000000..482a0806b93 --- /dev/null +++ b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/src/org/eclipse/papyrus/infra/gmfdiag/css/properties/handler/CSSFileHandler.java @@ -0,0 +1,135 @@ +/***************************************************************************** + * Copyright (c) 2014 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: + * Gabriel Pascual (ALL4TEC) gabriel.pascual@all4tec.net - Initial API and implementation + *****************************************************************************/ + +package org.eclipse.papyrus.infra.gmfdiag.css.properties.handler; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; +import org.eclipse.core.runtime.IPath; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.papyrus.infra.gmfdiag.css.helper.WorkspaceThemesHelper; +import org.eclipse.papyrus.infra.gmfdiag.css.properties.dialog.CSSThemeCreationDialog; +import org.eclipse.papyrus.infra.gmfdiag.css.properties.dialog.CSSThemeEditionDialog; +import org.eclipse.papyrus.infra.gmfdiag.css.stylesheets.StylesheetsPackage; +import org.eclipse.papyrus.infra.gmfdiag.css.stylesheets.Theme; +import org.eclipse.papyrus.infra.gmfdiag.css.stylesheets.WorkspaceThemes; +import org.eclipse.papyrus.infra.gmfdiag.css.theme.ThemeManager; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.handlers.HandlerUtil; + + +/** + * + * Handler to define a CSS style sheet file as local theme. + * + * @author gpascual + * + */ +public class CSSFileHandler extends AbstractHandler implements IHandler { + + /** ID of command to edit existing theme. */ + private static final String THEME_EDIT_COMMAND_ID = "org.eclipse.papyrus.infra.gmfdiag.css.theme.edit"; //$NON-NLS-1$ + + /** ID of command to define theme. */ + private static final String THEME_DEFINE_COMMAND_ID = "org.eclipse.papyrus.infra.gmfdiag.css.theme.define"; //$NON-NLS-1$ + + /** */ + private WorkspaceThemesHelper cssHelper = new WorkspaceThemesHelper(); + + /** + * Default constructor. + * + */ + public CSSFileHandler() { + super(); + } + + /** + * @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands.ExecutionEvent) + * + * @param event + * @return + * @throws ExecutionException + */ + public Object execute(ExecutionEvent event) throws ExecutionException { + + Theme theme = null; + int dialogResult = -1; + + + // Get current selection + ISelection selection = HandlerUtil.getCurrentSelection(event); + + // Get selected file from selection + if(selection instanceof IStructuredSelection) { + + // Get executed command ID + String commandID = event.getCommand().getId(); + Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); + + if(THEME_DEFINE_COMMAND_ID.equals(commandID)) { + + // Get theme initialise with slected elements + theme = cssHelper.defineCSSStyleSheetFilesAsTheme((IStructuredSelection)selection); + // Open a specific dialog to define theme according to selection + Dialog dialog = new CSSThemeCreationDialog(shell, theme); + dialogResult = dialog.open(); + + + } else if(THEME_EDIT_COMMAND_ID.equals(commandID)) { + IPath workspaceThemesFilePath = cssHelper.getThemeWorkspacePreferenceFilePath(); + + WorkspaceThemes workspaceThemes = null; + if(workspaceThemesFilePath.toFile().exists()) { + ResourceSet resourceSet = new ResourceSetImpl(); + Resource resource = resourceSet.getResource(URI.createFileURI(workspaceThemesFilePath.toOSString()), true); + workspaceThemes = (WorkspaceThemes)EcoreUtil.getObjectByType(resource.getContents(), StylesheetsPackage.Literals.WORKSPACE_THEMES); + } + + // Open a specific dialog to edit existing theme according to selection + CSSThemeEditionDialog dialog = new CSSThemeEditionDialog(shell, workspaceThemes, (IStructuredSelection)selection); + dialogResult = dialog.open(); + + theme = dialog.getEditedTheme(); + + + + } + + // Save and reload themes list only if user has validated + if(dialogResult == Dialog.OK) { + + if(THEME_DEFINE_COMMAND_ID.equals(commandID)) { + cssHelper.saveNewThemeWorkspacePreference(theme); + } else if(THEME_EDIT_COMMAND_ID.equals(commandID)) { + cssHelper.saveWorkspaceThemesPreferenceResource(theme); + } + + ThemeManager.instance.reloadThemes(); + } + + } + + + return null; + } +} diff --git a/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/src/org/eclipse/papyrus/infra/gmfdiag/css/properties/modelelement/CSSThemesModelElement.java b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/src/org/eclipse/papyrus/infra/gmfdiag/css/properties/modelelement/CSSThemesModelElement.java new file mode 100644 index 00000000000..6d54d2890d9 --- /dev/null +++ b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/src/org/eclipse/papyrus/infra/gmfdiag/css/properties/modelelement/CSSThemesModelElement.java @@ -0,0 +1,69 @@ +/***************************************************************************** + * Copyright (c) 2014 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: + * Gabriel Pascual (ALL4TEC) gabriel.pascual@all4tec.net - Initial API and implementation + *****************************************************************************/ + +package org.eclipse.papyrus.infra.gmfdiag.css.properties.modelelement; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.edit.domain.EditingDomain; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.papyrus.infra.gmfdiag.css.properties.provider.CSSStyleSheetLabelProvider; +import org.eclipse.papyrus.views.properties.modelelement.EMFModelElement; +import org.eclipse.papyrus.views.properties.modelelement.ModelElement; + + +/** + * Theme ModelElement to provide corresponding label provider because EMF model + * is not register in service registry. + * + * @author gpascual + * + */ +public class CSSThemesModelElement extends EMFModelElement implements ModelElement { + + /** UI view path for theme style sheets. */ + private static final String THEME_STYLESHEETS_PATH = "stylesheets"; //$NON-NLS-1$ + + /** + * Default constructor. + * + * @param source + * @param domain + */ + public CSSThemesModelElement(EObject source, EditingDomain domain) { + super(source, domain); + } + + /** + * @see org.eclipse.papyrus.views.properties.modelelement.EMFModelElement#getLabelProvider(java.lang.String) + * + * @param propertyPath + * @return + */ + @Override + public ILabelProvider getLabelProvider(String propertyPath) { + + ILabelProvider labelProvider = null; + + + if(THEME_STYLESHEETS_PATH.equals(propertyPath)) { + labelProvider = new CSSStyleSheetLabelProvider(); + } + + // If label provider was not instantiated, we use this ancestor one + if(labelProvider == null) { + labelProvider = super.getLabelProvider(propertyPath); + } + + return labelProvider; + } + +} diff --git a/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/src/org/eclipse/papyrus/infra/gmfdiag/css/properties/modelelement/CSSThemesModelElementFactory.java b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/src/org/eclipse/papyrus/infra/gmfdiag/css/properties/modelelement/CSSThemesModelElementFactory.java new file mode 100644 index 00000000000..ade28c59815 --- /dev/null +++ b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/src/org/eclipse/papyrus/infra/gmfdiag/css/properties/modelelement/CSSThemesModelElementFactory.java @@ -0,0 +1,65 @@ +/***************************************************************************** + * Copyright (c) 2014 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: + * Gabriel Pascual (ALL4TEC) gabriel.pascual@all4tec.net - Initial API and implementation + *****************************************************************************/ + +package org.eclipse.papyrus.infra.gmfdiag.css.properties.modelelement; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.edit.domain.EditingDomain; +import org.eclipse.papyrus.infra.emf.utils.EMFHelper; +import org.eclipse.papyrus.views.properties.Activator; +import org.eclipse.papyrus.views.properties.contexts.DataContextElement; +import org.eclipse.papyrus.views.properties.modelelement.ModelElement; +import org.eclipse.papyrus.views.properties.modelelement.ModelElementFactory; + + +/** + * Themes ModelElement factory to provide label provider because + * CSS EMF model is not in Service registry. + * + * @author gpascual + * + */ +public class CSSThemesModelElementFactory implements ModelElementFactory { + + + /** + * Default constructor. + * + */ + public CSSThemesModelElementFactory() { + super(); + } + + /** + * @see org.eclipse.papyrus.views.properties.modelelement.ModelElementFactory#createFromSource(java.lang.Object, + * org.eclipse.papyrus.views.properties.contexts.DataContextElement) + * + * @param sourceElement + * @param context + * @return + */ + public ModelElement createFromSource(Object sourceElement, DataContextElement context) { + + EObject source = EMFHelper.getEObject(sourceElement); + if(source == null) { + Activator.log.warn("Unable to resolve the selected element to an EObject"); //$NON-NLS-1$ + return null; + } + + EditingDomain domain = EMFHelper.resolveEditingDomain(source); + + // Create CSS themes ModelElement + return new CSSThemesModelElement(source, domain); + } + + +} diff --git a/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/src/org/eclipse/papyrus/infra/gmfdiag/css/properties/preferences/ThemePreferencesPage.java b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/src/org/eclipse/papyrus/infra/gmfdiag/css/properties/preferences/ThemePreferencesPage.java new file mode 100644 index 00000000000..bb1dcb561e5 --- /dev/null +++ b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/src/org/eclipse/papyrus/infra/gmfdiag/css/properties/preferences/ThemePreferencesPage.java @@ -0,0 +1,1134 @@ +/***************************************************************************** + * Copyright (c) 2014 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 + * Gabriel Pascual (ALL4TEC) gabriel.pascual@all4tec.net - Initial API and implementation + *****************************************************************************/ +package org.eclipse.papyrus.infra.gmfdiag.css.properties.preferences; + +import java.io.File; +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.resources.IFile; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.preference.FieldEditor; +import org.eclipse.jface.preference.FieldEditorPreferencePage; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.window.Window; +import org.eclipse.papyrus.infra.core.services.ServiceException; +import org.eclipse.papyrus.infra.emf.providers.EMFContentProvider; +import org.eclipse.papyrus.infra.gmfdiag.common.helper.DiagramHelper; +import org.eclipse.papyrus.infra.gmfdiag.css.Activator; +import org.eclipse.papyrus.infra.gmfdiag.css.engine.WorkspaceCSSEngine; +import org.eclipse.papyrus.infra.gmfdiag.css.preferences.ThemePreferences; +import org.eclipse.papyrus.infra.gmfdiag.css.properties.creation.ThemePropertyEditorFactory; +import org.eclipse.papyrus.infra.gmfdiag.css.properties.fieldeditor.IDynamicFieldEditor; +import org.eclipse.papyrus.infra.gmfdiag.css.properties.fieldeditor.InputComboFieldEditor; +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.StylesheetsPackage; +import org.eclipse.papyrus.infra.gmfdiag.css.stylesheets.Theme; +import org.eclipse.papyrus.infra.gmfdiag.css.theme.ThemeManager; +import org.eclipse.papyrus.infra.services.labelprovider.service.LabelProviderService; +import org.eclipse.papyrus.infra.services.labelprovider.service.impl.LabelProviderServiceImpl; +import org.eclipse.papyrus.infra.widgets.editors.MultipleValueSelectorDialog; +import org.eclipse.papyrus.infra.widgets.editors.TreeSelectorDialog; +import org.eclipse.papyrus.infra.widgets.providers.AbstractStaticContentProvider; +import org.eclipse.papyrus.infra.widgets.providers.CollectionContentProvider; +import org.eclipse.papyrus.infra.widgets.providers.WorkspaceContentProvider; +import org.eclipse.papyrus.infra.widgets.selectors.ReferenceSelector; +import org.eclipse.papyrus.infra.widgets.util.FileUtil; +import org.eclipse.papyrus.views.properties.creation.EcorePropertyEditorFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.eclipse.ui.plugin.AbstractUIPlugin; + +/** + * A Preference page for selecting the Workspace CSS Theme + * + * @author Camille Letavernier + */ +public class ThemePreferencesPage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage { + + /** Title for icon selection dialog. */ + private static final String ICON_SELECTION_DIALOG_TITLE = "Icon selection"; + + /** Label for workspace menu. */ + private static final String WORKSPACE_MENU_LABEL = "Workspace"; + + /** Label for file system menu. */ + private static final String FILE_SYSTEM_MENU_LABEL = "File System"; + + /** Id of workspace menu item. */ + private static final int WORKSPACE_MENU_ID = 12; + + /** Id of file system menu item. */ + private static final int FILESYSTEM_MENU_ID = 25; + + /** Label of theme field editor. */ + private static final String CURRENT_THEME_FIELD_LABEL = "Current theme:"; + + /** Title of preference page. */ + private static final String PAGE_TITLE = "CSS Theme"; + + /** Id of delete theme button. */ + private static final int DELETE_THEME_BUTTON_ID = 46; + + /** Id of new button. */ + private static final int NEW_THEME_BUTTON_ID = 45; + + /** Id of edit button. */ + private static final int EDIT_BUTTON_ID = 19; + + /** Id of down button. */ + private static final int DOWN_BUTTON_ID = 18; + + /** Id of up button. */ + private static final int UP_BUTTON_ID = 17; + + /** ID of delete button. */ + private static final int DELETE_BUTTON_ID = 15; + + /** ID of add button. */ + private static final int ADD_BUTTON_ID = 14; + + /** ID of browse buton. */ + private static final int BROWSE_BUTTON_ID = 16; + + /** Title for add action dialog. */ + private static final String ADD_DIALOG_TITLE = "Style sheets selection"; + + private static final Image EDIT_ICON = AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.papyrus.infra.widgets", "icons/Edit_12x12.gif").createImage(); //$NON-NLS-1$ //$NON-NLS-2$ + + /** Icon for delete action button. */ + private static final Image DELETE_ICON = AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.papyrus.infra.widgets", "icons/Delete_12x12.gif").createImage(); //$NON-NLS-1$ //$NON-NLS-2$ + + /** Icon for add action button. */ + private static final Image ADD_ICON = AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.papyrus.infra.widgets", "icons/Add_12x12.gif").createImage(); //$NON-NLS-1$ //$NON-NLS-2$ + + /** Icon for up action button. */ + private static final Image UP_ICON = AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.papyrus.infra.widgets", "icons/Up_12x12.gif").createImage(); //$NON-NLS-1$ //$NON-NLS-2$ + + /** Icon for down action button. */ + private static final Image DOWN_ICON = AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.papyrus.infra.widgets", "icons/Down_12x12.gif").createImage(); //$NON-NLS-1$ //$NON-NLS-2$ + + /** Text for style sheets list label. */ + private static final String STYLE_SHEETS_LABEL = "Style sheets"; + + /** Text for browse button. */ + private static final String BROWSE_BUTTON_LABEL = "Browse..."; + + /** Text for theme icon label. */ + private static final String THEME_ICON_LABEL = "Icon"; + + /** Text for theme name label. */ + private static final String THEME_NAME_LABEL = "Label"; + + /** List of valid extensions for an icon. */ + private List<String> filterExtensions = Arrays.asList(new String[]{ "*.gif;*.png;*.jpeg", "*.gif", "*.png", "*.jpeg" }); + + /** List of name associated to valid extensions. */ + private List<String> filterNames = Arrays.asList(new String[]{ "All images", "GIF Icon", "PNG Icon", "JPEG Icon" }); + + /** Flag to define if refresh must be done. */ + public boolean needsRefresh = false; + + /** Main composite of preference page. */ + private Composite mainContainer = null; + + /** Field for label of theme. */ + private Text themeLabelField = null; + + /** Current selected theme. */ + protected Theme currentTheme = null; + + /** Field for icon path of theme. */ + private Text iconPathfield = null; + + /** Viewer for style sheets of current theme. */ + private TreeViewer themeStyleSheetsViewer = null; + + /** Label provider for treeviewer. */ + private LabelProvider labelProvider = null; + + /** Dynamic combo editor for select theme preference. */ + private IDynamicFieldEditor themesCombo = null; + + /** Array of all id's buttons which were added in dialog. */ + private Map<Integer, Button> buttonsMap = new HashMap<Integer, Button>(); + + /** Editor factory for theme. */ + private EcorePropertyEditorFactory editorFactory = new ThemePropertyEditorFactory(StylesheetsPackage.Literals.WORKSPACE_THEMES__THEMES); + + /** Menu of icon browse button. */ + private Menu browseMenu = null; + + + /** + * + * Default constructor. + * + */ + public ThemePreferencesPage() { + super(PAGE_TITLE, org.eclipse.papyrus.infra.widgets.Activator.getDefault().getImageDescriptor("/icons/papyrus.png"), FieldEditorPreferencePage.GRID); + initialiseFilterLabels(filterNames, filterExtensions); + } + + /** + * Gets the filter labels. + * + * @param filterNames + * the filter names + * @param filterExtensions + * the filter extensions + */ + private void initialiseFilterLabels(List<String> filterNames, List<String> filterExtensions) { + int size = Math.min(filterNames.size(), filterExtensions.size()); + String[] filters = new String[size]; + + for(int i = 0; i < size; i++) { + filters[i] = filterNames.get(i) + " (" + filterExtensions.get(i) + ")"; + } + + this.filterNames = Arrays.asList(filters); + } + + /** + * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench) + * + * @param workbench + */ + public void init(IWorkbench workbench) { + + //Used default preference store to save current theme + setPreferenceStore(Activator.getDefault().getPreferenceStore()); + + // Set description for page + setDescription("Papyrus Theme preferences"); + } + + + /** + * @see org.eclipse.jface.preference.FieldEditorPreferencePage#createContents(org.eclipse.swt.widgets.Composite) + * + * @param parent + * @return + */ + @Override + protected Control createContents(Composite parent) { + + // Create principal layout + mainContainer = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.numColumns = 3; + layout.marginHeight = 0; + layout.marginWidth = 0; + mainContainer.setLayout(layout); + mainContainer.setFont(parent.getFont()); + + // Populate preference page + createPreferenceThemePart(mainContainer); + createThemeLabelPart(mainContainer); + createThemeIconPart(mainContainer); + createTreeActionButtons(mainContainer); + createThemeStyleSheetsPart(mainContainer); + + // Initialize step + initialize(); + checkState(); + + + return mainContainer; + } + + /** + * Create part of page to select, add and remove theme. + * + * @param parent + * Parent composite where components will be added + */ + private void createPreferenceThemePart(Composite parent) { + + // Add theme field editor + createFieldEditors(); + Composite buttonsPanel = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.marginLeft = 0; + layout.marginRight = 0; + buttonsPanel.setLayout(layout); + buttonsPanel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); + + // Add buttons to delete and add theme + createButton(buttonsPanel, NEW_THEME_BUTTON_ID, ADD_ICON, null); + createButton(buttonsPanel, DELETE_THEME_BUTTON_ID, DELETE_ICON, null); + + } + + /** + * @see org.eclipse.jface.preference.FieldEditorPreferencePage#createFieldEditors() + * + */ + @Override + protected void createFieldEditors() { + //Get all themes define in application instance + String[][] themes = getFieldThemes(); + + themesCombo = new InputComboFieldEditor(ThemePreferences.CURRENT_THEME, CURRENT_THEME_FIELD_LABEL, themes, mainContainer); + + + addField((FieldEditor)themesCombo); + + + } + + /** + * Create theme label composite. + * + * @param parent + * Parent composite where components will be added + */ + private void createThemeLabelPart(Composite parent) { + + // Create label for label field + Label themeNameLabel = new Label(parent, SWT.NONE); + themeNameLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false)); + themeNameLabel.setText(THEME_NAME_LABEL); + + // Add theme label field + themeLabelField = new Text(parent, SWT.BORDER); + GridData gd_text = new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1); + themeLabelField.setLayoutData(gd_text); + + themeLabelField.addModifyListener(new ModifyListener() { + + public void modifyText(ModifyEvent e) { + currentTheme.setLabel(themeLabelField.getText()); + } + + + }); + } + + + /** + * Create theme icon part. + * + * @param parent + * Parent composite where components will be added + */ + private void createThemeIconPart(Composite parent) { + Label iconLabel = new Label(parent, SWT.NONE); + iconLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false)); + iconLabel.setText(THEME_ICON_LABEL); + + iconPathfield = new Text(parent, SWT.BORDER); + iconPathfield.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + iconPathfield.addModifyListener(new ModifyListener() { + + + public void modifyText(ModifyEvent e) { + currentTheme.setIcon(iconPathfield.getText()); + + } + }); + + // Create browse button and its menu + Button browseButton = createButton(parent, BROWSE_BUTTON_ID, null, BROWSE_BUTTON_LABEL); + browseMenu = new Menu(browseButton); + createMenuItem(browseMenu, FILE_SYSTEM_MENU_LABEL, FILESYSTEM_MENU_ID); + createMenuItem(browseMenu, WORKSPACE_MENU_LABEL, WORKSPACE_MENU_ID); + } + + /** + * Create menu item. + * + * @param parentMenu + * Menu where it will be added + * @param label + * Label of menu item + * @param menuId + */ + private void createMenuItem(Menu parentMenu, String label, int menuId) { + + MenuItem menuItem = new MenuItem(parentMenu, SWT.NONE); + menuItem.setText(label); + menuItem.setData(new Integer(menuId)); + menuItem.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + menuSelected(((Integer)e.widget.getData()).intValue()); + } + }); + + + } + + /** + * Action to run when a menu is slected. + * + * @param menuId + * ID of selected menu + */ + private void menuSelected(int menuId) { + switch(menuId) { + case WORKSPACE_MENU_ID: + browseWorkspace(); + break; + case FILESYSTEM_MENU_ID: + browseFileSytem(); + break; + default: + // Nothing to do + break; + } + } + + /** + * Browse file in file system. + */ + private void browseFileSytem() { + File file = getFile(iconPathfield.getText()); + + FileDialog dialog = new FileDialog(getShell()); + dialog.setText(ICON_SELECTION_DIALOG_TITLE); + + dialog.setFileName(file.getAbsolutePath()); + dialog.setFilterExtensions(filterExtensions.toArray(new String[filterExtensions.size()])); + dialog.setFilterNames(filterNames.toArray(new String[filterNames.size()])); + String result = dialog.open(); + if(result == null) { //Cancel + return; + } + setResult(result); + } + + /** + * Browse file in workspace. + */ + private void browseWorkspace() { + LabelProviderService labelProviderService = new LabelProviderServiceImpl(); + try { + labelProviderService.startService(); + } catch (ServiceException ex) { + Activator.log.error(ex); + } + + ILabelProvider labelProvider = labelProviderService.getLabelProvider(); + + IFile currentFile = getIFile(iconPathfield.getText()); + + TreeSelectorDialog dialog = new TreeSelectorDialog(getShell()); + dialog.setTitle(ICON_SELECTION_DIALOG_TITLE); + + + WorkspaceContentProvider contentProvider = new WorkspaceContentProvider(); + + + if(!(filterExtensions.isEmpty() || filterNames.isEmpty())) { + //The filters have been defined + contentProvider.setExtensionFilters(new LinkedHashMap<String, String>()); //Reset the default filters + + //Use our own filters + for(int i = 0; i < Math.min(filterNames.size(), filterExtensions.size()); i++) { + contentProvider.addExtensionFilter(filterExtensions.get(i), filterNames.get(i)); + } + } + + dialog.setContentProvider(contentProvider); + dialog.setLabelProvider(labelProvider); + + + if(currentFile != null && currentFile.exists()) { + dialog.setInitialSelections(new IFile[]{ currentFile }); + } + + int code = dialog.open(); + if(code == Window.OK) { + Object[] result = dialog.getResult(); + if(result.length > 0) { + Object file = result[0]; + if(file instanceof IFile) { + setResult((IFile)file); + } + } + } + } + + + /** + * Sets the result. + * + * @param file + * the new result + */ + protected void setResult(IFile file) { + iconPathfield.setText(file.getFullPath().toString()); + } + + /** + * Sets the result. + * + * @param file + * the new result + */ + protected void setResult(File file) { + iconPathfield.setText(file.getAbsolutePath()); + + } + + /** + * Sets the result. + * + * @param path + * the new result + */ + protected void setResult(String path) { + iconPathfield.setText(path); + + } + + /** + * Gets the file. + * + * @param path + * the path + * @return the i file + */ + protected IFile getIFile(String path) { + return FileUtil.getIFile(path); + } + + /** + * Gets the file. + * + * @param path + * the path + * @return the file + */ + protected File getFile(String path) { + return FileUtil.getFile(path); + } + + /** + * Create theme style sheets part. + * + * @param parent + * Parent composite where components will be added + */ + private void createThemeStyleSheetsPart(Composite parent) { + + // Create viewer + themeStyleSheetsViewer = new TreeViewer(parent, SWT.BORDER); + + // Set standard collection content provider + themeStyleSheetsViewer.setContentProvider(CollectionContentProvider.instance); + + labelProvider = new LabelProvider() { + + /** + * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object) + * + * @param element + * @return + */ + @Override + public String getText(Object element) { + + // Use ancestor result as default + String text = super.getText(element); + + // Display path of style sheet reference + if(element instanceof StyleSheetReference) { + text = ((StyleSheetReference)element).getPath(); + } else if(element instanceof EmbeddedStyleSheet) { + text = ((EmbeddedStyleSheet)element).getLabel(); + } + + return text; + } + }; + themeStyleSheetsViewer.setLabelProvider(labelProvider); + + // Set layout + Tree tree = themeStyleSheetsViewer.getTree(); + tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1)); + + + } + + + /** + * Create actions associate to tree viewer. + * + * @param parent + * Composite where action buttons will be added + */ + private void createTreeActionButtons(Composite parent) { + Label labelViewer = new Label(parent, SWT.NONE); + labelViewer.setText(STYLE_SHEETS_LABEL); + + Composite buttonsPanel = new Composite(parent, SWT.NONE); + buttonsPanel.setLayout(new GridLayout()); + buttonsPanel.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, true, false, 2, 1)); + + createButton(buttonsPanel, ADD_BUTTON_ID, ADD_ICON, null); + createButton(buttonsPanel, DELETE_BUTTON_ID, DELETE_ICON, null); + createButton(buttonsPanel, UP_BUTTON_ID, UP_ICON, null); + createButton(buttonsPanel, DOWN_BUTTON_ID, DOWN_ICON, null); + createButton(buttonsPanel, EDIT_BUTTON_ID, EDIT_ICON, null); + + } + + /** + * Override method to create a button with an icon and no label. + * + * @see org.eclipse.jface.dialogs.Dialog#createButton(Composite, int, String, boolean) + * + * @param parent + * @param id + * @param icon + * @return + */ + protected Button createButton(Composite parent, int id, Image icon, String label) { + ((GridLayout)parent.getLayout()).numColumns++; + Button button = new Button(parent, SWT.PUSH); + button.setFont(JFaceResources.getDialogFont()); + button.setData(new Integer(id)); + button.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent event) { + buttonPressed(((Integer)event.widget.getData()).intValue()); + } + }); + + if(label != null) { + button.setText(label); + } + if(icon != null) { + button.setImage(icon); + } + buttonsMap.put(new Integer(id), button); + setButtonLayoutData(button); + return button; + } + + /** + * @see org.eclipse.jface.dialogs.Dialog#buttonPressed(int) + * + * @param buttonId + */ + protected void buttonPressed(int buttonId) { + switch(buttonId) { + case ADD_BUTTON_ID: + addAction(); + break; + case DELETE_BUTTON_ID: + deleteAction(); + break; + case BROWSE_BUTTON_ID: + browseMenu.setVisible(true); + break; + case UP_BUTTON_ID: + upAction(); + break; + case DOWN_BUTTON_ID: + downAction(); + break; + case EDIT_BUTTON_ID: + editAction(); + break; + case NEW_THEME_BUTTON_ID: + addThemeAction(); + break; + case DELETE_THEME_BUTTON_ID: + deleteThemeAction(); + break; + default: + //Nothing to do + } + } + + + /** + * Delete current selection of tree viewer. + */ + private void deleteAction() { + ISelection selection = themeStyleSheetsViewer.getSelection(); + + if(selection instanceof IStructuredSelection) { + Object selectedElement = ((IStructuredSelection)selection).getFirstElement(); + if(selectedElement instanceof StyleSheet) { + currentTheme.getStylesheets().remove(selectedElement); + } + + themeStyleSheetsViewer.setInput(currentTheme.getStylesheets()); + refreshTreeviewer(currentTheme); + } + + } + + + /** + * Open a dialog to add a style sheet to current selected theme. + */ + private void addAction() { + + + ReferenceSelector selector = new ReferenceSelector(true); + selector.setContentProvider(new EMFContentProvider(currentTheme, StylesheetsPackage.eINSTANCE.getTheme_Stylesheets()) { + + @Override + protected IStructuredContentProvider getSemanticProvider(final EObject editedEObject, final EStructuralFeature feature) { + + // Use a standard content provider + return new AbstractStaticContentProvider() { + + public Object[] getElements() { + List<Object> result = new LinkedList<Object>(); + if(editedEObject instanceof Theme) { + result.addAll(currentTheme.getStylesheets()); + } + return result.toArray(); + } + }; + } + }); + selector.setLabelProvider(labelProvider); + + // Use common component for add dialog and parameterize it + MultipleValueSelectorDialog vDialog = new MultipleValueSelectorDialog(getShell(), selector, ADD_DIALOG_TITLE); + vDialog.setContextElement(currentTheme); + vDialog.setLabelProvider(labelProvider); + vDialog.setFactory(new EcorePropertyEditorFactory(StylesheetsPackage.Literals.THEME__STYLESHEETS)); + + // Handle dialog result + int result = vDialog.open(); + if(result == Dialog.OK) { + + Object[] resultArray = vDialog.getResult(); + refreshStyleSheets(resultArray); + + } + + } + + + /** + * Fill style sheets viewer with selected style sheets. + * + * @param result + * Result from dialog selection + */ + private void refreshStyleSheets(Object[] result) { + + // Complete current theme with dialog result + for(Object object : result) { + + // Check if this is a style sheet + if(object instanceof StyleSheet) + currentTheme.getStylesheets().add((StyleSheet)object); + } + + needsRefresh = true; + + refreshTreeviewer(currentTheme); + } + + /** + * Refresh content of tree viewer according to selected theme/ + * + * @param currentTheme + * Current theme + */ + private void refreshTreeviewer(Theme currentTheme) { + + + boolean isEditatble = ThemeManager.instance.isEditable(currentTheme.getId()); + + EList<StyleSheet> themeStyleSheetsList = currentTheme.getStylesheets(); + + + // Set mirroring list as viewer input + themeStyleSheetsViewer.getTree().setEnabled(isEditatble); + themeStyleSheetsViewer.setInput(themeStyleSheetsList); + + + updateButtons(currentTheme); + + } + + + /** + * Move up the selected style sheet in list. + */ + private void upAction() { + + // Handle selection to extract selected style sheet + ISelection selection = themeStyleSheetsViewer.getSelection(); + if(selection instanceof IStructuredSelection) { + Object selectedElement = ((IStructuredSelection)selection).getFirstElement(); + + if(selectedElement instanceof StyleSheet) { + + // Get index of selected style sheet in list + EList<StyleSheet> stylesheetsList = currentTheme.getStylesheets(); + int index = stylesheetsList.indexOf(selectedElement); + + // Check if selected style sheet is not at top of list + if(index > 0) { + stylesheetsList.move(--index, (StyleSheet)selectedElement); + themeStyleSheetsViewer.setInput(stylesheetsList); + } + + needsRefresh = true; + } + } + } + + /** + * Move down the selected style sheet in list. + */ + private void downAction() { + + // Handle selection to extract selected style sheet + ISelection selection = themeStyleSheetsViewer.getSelection(); + + if(selection instanceof IStructuredSelection) { + Object selectedElement = ((IStructuredSelection)selection).getFirstElement(); + + if(selectedElement instanceof StyleSheet) { + + // Get index of selected style sheet in list + EList<StyleSheet> stylesheetsList = currentTheme.getStylesheets(); + int index = stylesheetsList.indexOf(selectedElement); + + // Check if selected style sheet is not at bottom of list + if(index < stylesheetsList.size() - 1) { + stylesheetsList.move(++index, (StyleSheet)selectedElement); + themeStyleSheetsViewer.setInput(stylesheetsList); + } + + needsRefresh = true; + } + } + } + + + /** + * Edit action on selected style sheet in tree viewer. + */ + private void editAction() { + + ISelection selection = themeStyleSheetsViewer.getSelection(); + + if(selection instanceof IStructuredSelection) { + Object selectedObject = ((IStructuredSelection)selection).getFirstElement(); + if(selectedObject instanceof StyleSheet) { + // Use editor factory + editorFactory.edit(buttonsMap.get(EDIT_BUTTON_ID), selectedObject); + needsRefresh = true; + } + } + + + } + + /** + * Create a theme. + */ + private void addThemeAction() { + + ThemeManager themeManager = ThemeManager.instance; + Object createdObject = editorFactory.createObject(buttonsMap.get(NEW_THEME_BUTTON_ID), themeManager.getWorkspaceThemesPreferences()); + + if(createdObject instanceof Theme) { + + themeManager.addTemporaryTheme((Theme)createdObject); + currentTheme = (Theme)createdObject; + + themesCombo.setInput(getFieldThemes()); + themesCombo.setSelection(((Theme)createdObject).getId()); + + } + } + + /** + * Delete selected theme. + */ + private void deleteThemeAction() { + boolean confirm = MessageDialog.openConfirm(getShell(), "Delete CSS theme", "WARNING! Deletion will be difinitive.\nDo you really want to delete this theme ?"); + if(confirm) { + ThemeManager themeManager = ThemeManager.instance; + themeManager.delete(currentTheme); + String[][] fieldThemes = getFieldThemes(); + themesCombo.setInput(fieldThemes); + currentTheme = themeManager.getTheme(fieldThemes[0][1]); + themesCombo.setSelection(currentTheme.getId()); + } + + } + + /** + * + * Update state of dialog buttons. + * + * @param currentTheme + * Selected theme which determine state of different buttons. + */ + private void updateButtons(Theme currentTheme) { + boolean editionEnable = ThemeManager.instance.isEditable(currentTheme.getId()); + + for(int buttonId : buttonsMap.keySet()) { + switch(buttonId) { + case ADD_BUTTON_ID: + case BROWSE_BUTTON_ID: + buttonsMap.get(buttonId).setEnabled(editionEnable); + break; + case DELETE_BUTTON_ID: + case EDIT_BUTTON_ID: + buttonsMap.get(buttonId).setEnabled(editionEnable && !currentTheme.getStylesheets().isEmpty()); + break; + case UP_BUTTON_ID: + case DOWN_BUTTON_ID: + buttonsMap.get(buttonId).setEnabled(editionEnable && (currentTheme.getStylesheets().size() > 1)); + case DELETE_THEME_BUTTON_ID: + buttonsMap.get(buttonId).setEnabled(ThemeManager.instance.isEditable(currentTheme.getId())); + default: + break; + } + + } + } + + + /** + * @see org.eclipse.jface.dialogs.DialogPage#setButtonLayoutData(org.eclipse.swt.widgets.Button) + * + * @param button + * @return + */ + @Override + protected GridData setButtonLayoutData(Button button) { + GridData layoutData = null; + + // Determine id of button + Object data = button.getData(); + int buttonId = -1; + if(data instanceof Integer) { + buttonId = (Integer)data; + } + + //Filter specific button to set data layout + switch(buttonId) { + case ADD_BUTTON_ID: + case DELETE_BUTTON_ID: + case UP_BUTTON_ID: + case DOWN_BUTTON_ID: + case EDIT_BUTTON_ID: + case DELETE_THEME_BUTTON_ID: + case NEW_THEME_BUTTON_ID: + layoutData = new GridData(SWT.FILL, SWT.FILL, false, false); + button.setLayoutData(layoutData); + break; + default: + layoutData = super.setButtonLayoutData(button); + break; + } + + return layoutData; + } + + /** + * @see org.eclipse.jface.preference.FieldEditorPreferencePage#propertyChange(org.eclipse.jface.util.PropertyChangeEvent) + * + * @param event + */ + + @Override + public void propertyChange(PropertyChangeEvent event) { + super.propertyChange(event); + if(ThemePreferences.CURRENT_THEME.equals(event.getProperty())) { + needsRefresh = true; + } + if(FieldEditor.VALUE.equals(event.getProperty())) { + FieldEditor fieldEditor = (FieldEditor)event.getSource(); + if(ThemePreferences.CURRENT_THEME.equals(fieldEditor.getPreferenceName())) { + + Object newValue = event.getNewValue(); + ThemeManager themeManager = ThemeManager.instance; + + currentTheme = themeManager.getTheme(String.valueOf(newValue)); + refreshPreferencePage(); + + } + } + } + + /** + * Refresh dialog area according to combo selection. + * + * @param selection + * selection which comes from combo viewer + */ + protected void refreshPreferencePage() { + + // Refresh text field (label, icon path, ...) + String themeLabel = currentTheme.getLabel(); + boolean editableTheme = ThemeManager.instance.isEditable(currentTheme.getId()); + needsRefresh = true; + + if(themeLabel == null) { + themeLabel = ""; + } + themeLabelField.setEnabled(editableTheme); + themeLabelField.setText(themeLabel); + + + String iconPath = currentTheme.getIcon(); + if(iconPath == null) { + iconPath = ""; + } + iconPathfield.setEnabled(editableTheme); + iconPathfield.setText(iconPath); + + + // Tree viewer + refreshTreeviewer(currentTheme); + + } + + /** + * @see org.eclipse.jface.preference.FieldEditorPreferencePage#initialize() + * + */ + @Override + protected void initialize() { + String prefrenceValue = getPreferenceStore().getString(ThemePreferences.CURRENT_THEME); + currentTheme = ThemeManager.instance.getTheme(prefrenceValue); + refreshPreferencePage(); + super.initialize(); + } + + /** + * @see org.eclipse.jface.preference.PreferencePage#performApply() + * + */ + @Override + protected void performApply() { + super.performApply(); + themesCombo.setInput(getFieldThemes()); + refreshPreferencePage(); + + } + + /** + * @see org.eclipse.jface.preference.FieldEditorPreferencePage#performOk() + * + * @return + */ + @Override + public boolean performOk() { + boolean result = super.performOk(); + if(needsRefresh) { + WorkspaceCSSEngine.instance.reset(); + DiagramHelper.setNeedsRefresh(); + DiagramHelper.refreshDiagrams(); + } + + + ThemeManager themeManager = ThemeManager.instance; + themeManager.persist(); + return result; + } + + /** + * + * @see org.eclipse.jface.preference.PreferencePage#performCancel() + * + * @return + */ + @Override + public boolean performCancel() { + ThemeManager.instance.reloadThemes(); + ThemeManager.instance.clearTemporaryThemes(); + ThemeManager.instance.clearDeletedThemes(); + + return super.performCancel(); + } + + @Override + protected void performDefaults() { + super.performDefaults(); + + currentTheme = ThemeManager.instance.getTheme(getPreferenceStore().getDefaultString(ThemePreferences.CURRENT_THEME)); + refreshPreferencePage(); + } + + + /** + * @return Formatted themes list for combo field editor + */ + protected String[][] getFieldThemes() { + + // Use a manager to get all theme in application + ThemeManager themeManager = ThemeManager.instance; + themeManager.refreshThemes(); + List<Theme> themes = themeManager.getThemes(); + + // Build theme list for combo editor + String[][] result = new String[themes.size()][2]; + int i = 0; + for(Theme theme : themes) { + result[i][0] = theme.getLabel(); + result[i][1] = theme.getId(); + i++; + } + + return result; + } + + + +} diff --git a/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/src/org/eclipse/papyrus/infra/gmfdiag/css/properties/provider/CSSThemeLabelProvider.java b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/src/org/eclipse/papyrus/infra/gmfdiag/css/properties/provider/CSSThemeLabelProvider.java index 288dba9c4be..72ff34250b6 100644 --- a/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/src/org/eclipse/papyrus/infra/gmfdiag/css/properties/provider/CSSThemeLabelProvider.java +++ b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css.properties/src/org/eclipse/papyrus/infra/gmfdiag/css/properties/provider/CSSThemeLabelProvider.java @@ -1,48 +1,51 @@ -/*****************************************************************************
- * 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.properties.provider;
-
-import org.eclipse.jface.viewers.LabelProvider;
-import org.eclipse.papyrus.infra.gmfdiag.css.theme.Theme;
-import org.eclipse.papyrus.infra.gmfdiag.css.theme.ThemeManager;
-import org.eclipse.swt.graphics.Image;
-
-
-public class CSSThemeLabelProvider extends LabelProvider {
-
- @Override
- public String getText(Object value) {
- Theme theme = getTheme(value);
- if(theme != null) {
- return theme.getLabel();
- }
- return super.getText(value);
- }
-
- @Override
- public Image getImage(Object value) {
- Theme theme = getTheme(value);
- if(theme != null) {
- return theme.getIcon();
- }
- return super.getImage(value);
- }
-
- protected Theme getTheme(Object value) {
- if(value instanceof String) {
- String themeId = (String)value;
- Theme theme = ThemeManager.instance.getTheme(themeId);
- return theme;
- }
- return null;
- }
-}
+/***************************************************************************** + * 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 + * Gabriel Pascual (ALL4TEC) gabriel.pascual@all4tec.net - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.gmfdiag.css.properties.provider; + +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.papyrus.infra.gmfdiag.css.stylesheets.Theme; +import org.eclipse.papyrus.infra.gmfdiag.css.theme.ThemeManager; +import org.eclipse.swt.graphics.Image; + + +public class CSSThemeLabelProvider extends LabelProvider { + + @Override + public String getText(Object value) { + Theme theme = getTheme(value); + if(theme != null) { + return theme.getLabel(); + } + return super.getText(value); + } + + @Override + public Image getImage(Object value) { + Theme theme = getTheme(value); + if(theme != null) { + Image icon = ThemeManager.instance.getThemeIcon(theme); + return icon; + } + return super.getImage(value); + } + + protected Theme getTheme(Object value) { + if(value instanceof String) { + String themeId = (String)value; + Theme theme = ThemeManager.instance.getTheme(themeId); + return theme; + } + return null; + } +} |