summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJayant Gupta2012-08-06 13:23:40 (EDT)
committer Jayant Gupta2012-08-20 14:49:41 (EDT)
commitad11ea0ca47da9d3f8090d08d05c8e6dc519e17c (patch)
treefdaba1064fdb318d97de03dbc2f41009466a6bd3
parent157c33f899e16f0745df0689730aa4c1c250ef6e (diff)
downloadorg.eclipse.etrice-ad11ea0ca47da9d3f8090d08d05c8e6dc519e17c.zip
org.eclipse.etrice-ad11ea0ca47da9d3f8090d08d05c8e6dc519e17c.tar.gz
org.eclipse.etrice-ad11ea0ca47da9d3f8090d08d05c8e6dc519e17c.tar.bz2
Adds preference pages for configuring default layout options.(New)refs/changes/19/7119/2
1. Adds three preference pages :- - Layout : for general layout options - Behavior : for behavior diagrams - Structure ; for structure diagrams 2. Few Features :- - Domain specific preference pages - Option also configurable from KIELER > Layout Preference Page - Domain Model options set via a new tree dialog showing hierarchy Change-Id: Ie9cb175704377e7cf186d4e3480d8b8000532c59
-rw-r--r--plugins/org.eclipse.etrice.ui.layout/META-INF/MANIFEST.MF2
-rw-r--r--plugins/org.eclipse.etrice.ui.layout/plugin.xml27
-rw-r--r--plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/Activator.java70
-rw-r--r--plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/ETriceDiagramLayoutManager.java2
-rw-r--r--plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/ETriceSemanticLayoutConfig.java8
-rw-r--r--plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/preferences/ETriceBehaviorPreferencePage.java475
-rw-r--r--plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/preferences/ETriceDomainModelElement.java306
-rw-r--r--plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/preferences/ETriceLayoutPreferencePage.java183
-rw-r--r--plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/preferences/ETricePreferenceUtil.java800
-rw-r--r--plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/preferences/EtriceStructurePreferencePage.java470
-rw-r--r--plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/preferences/PreferenceInitializer.java31
11 files changed, 2369 insertions, 5 deletions
diff --git a/plugins/org.eclipse.etrice.ui.layout/META-INF/MANIFEST.MF b/plugins/org.eclipse.etrice.ui.layout/META-INF/MANIFEST.MF
index 66e3cd8..b94c4f6 100644
--- a/plugins/org.eclipse.etrice.ui.layout/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.etrice.ui.layout/META-INF/MANIFEST.MF
@@ -22,3 +22,5 @@ Require-Bundle: org.eclipse.graphiti;bundle-version="0.8.1",
org.eclipse.etrice.ui.common;bundle-version="0.2.0",
org.eclipse.etrice.core.room;bundle-version="0.2.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Bundle-ActivationPolicy: lazy
+Bundle-Activator: org.eclipse.etrice.ui.layout.Activator
diff --git a/plugins/org.eclipse.etrice.ui.layout/plugin.xml b/plugins/org.eclipse.etrice.ui.layout/plugin.xml
index 8df4cb9..a2865dd 100644
--- a/plugins/org.eclipse.etrice.ui.layout/plugin.xml
+++ b/plugins/org.eclipse.etrice.ui.layout/plugin.xml
@@ -61,5 +61,32 @@
value="50">
</option>
</extension>
+ <extension
+ point="org.eclipse.core.runtime.preferences">
+ <initializer
+ class="org.eclipse.etrice.ui.layout.preferences.PreferenceInitializer">
+ </initializer>
+ </extension>
+ <extension
+ point="org.eclipse.ui.preferencePages">
+ <page
+ category="org.eclipse.etrice.ui.common.preferences.ETricePreferencePage"
+ class="org.eclipse.etrice.ui.layout.preferences.ETriceLayoutPreferencePage"
+ id="org.eclipse.etrice.ui.layout.preferences.ETriceLayoutPreferencePage"
+ name="Layout">
+ </page>
+ <page
+ category="org.eclipse.etrice.ui.layout.preferences.ETriceLayoutPreferencePage"
+ class="org.eclipse.etrice.ui.layout.preferences.ETriceBehaviorPreferencePage"
+ id="org.eclipse.etrice.ui.layout.ETriceBehaviorPreferencePage"
+ name="Behavior">
+ </page>
+ <page
+ category="org.eclipse.etrice.ui.layout.preferences.ETriceLayoutPreferencePage"
+ class="org.eclipse.etrice.ui.layout.preferences.EtriceStructurePreferencePage"
+ id="org.eclipse.etrice.ui.layout.ETriceStructurePreferencePage"
+ name="Structure">
+ </page>
+ </extension>
</plugin>
diff --git a/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/Activator.java b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/Activator.java
new file mode 100644
index 0000000..c3e810a
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/Activator.java
@@ -0,0 +1,70 @@
+package org.eclipse.etrice.ui.layout;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+import de.cau.cs.kieler.kiml.ui.KimlUiPlugin;
+
+public class Activator extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.etrice.ui.layout";
+
+ // The shared instance
+ private static Activator plugin;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext
+ * )
+ */
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext
+ * )
+ */
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+ /**
+ * Gets the common Preference Store which is shared with KIELER Preference page as well.
+ *
+ * @return the shared preference store
+ *
+ * @author jayant
+ *
+ */
+ public IPreferenceStore getSharedPreferenceStore(){
+ return (KimlUiPlugin.getDefault().getPreferenceStore());
+
+ }
+}
diff --git a/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/ETriceDiagramLayoutManager.java b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/ETriceDiagramLayoutManager.java
index 09f22f2..18aeb56 100644
--- a/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/ETriceDiagramLayoutManager.java
+++ b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/ETriceDiagramLayoutManager.java
@@ -236,7 +236,7 @@ public abstract class ETriceDiagramLayoutManager extends
if (workbenchPart instanceof BehaviorEditor)
staticConfig.setValue(LayoutOptions.DIAGRAM_TYPE, diagramNode,
LayoutContext.GRAPH_ELEM,
- ETriceSemanticLayoutConfig.BEHAVIOR_DAGRAM_TYPE);
+ ETriceSemanticLayoutConfig.BEHAVIOR_DIAGRAM_TYPE);
// Node creation for currently visible top-level Container
// Shape(Bounding Box) in
diff --git a/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/ETriceSemanticLayoutConfig.java b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/ETriceSemanticLayoutConfig.java
index d9e21ee..d4db0c0 100644
--- a/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/ETriceSemanticLayoutConfig.java
+++ b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/ETriceSemanticLayoutConfig.java
@@ -29,13 +29,13 @@ public class ETriceSemanticLayoutConfig extends SemanticLayoutConfig {
* The diagram type for the top-level bounding box containers in eTrice
* Behavior Diagram.
*/
- public static final String BEHAVIOR_DAGRAM_TYPE = "org.eclipse.etrice.ui.layout.eTriceBehaviorDiagram";
+ public static final String BEHAVIOR_DIAGRAM_TYPE = "org.eclipse.etrice.ui.layout.eTriceBehaviorDiagram";
/**
* The diagram type for the top-level bounding box containers in eTrice
* Structure Diagram.
*/
- public static final String STRUCTURE_DAGRAM_TYPE = "org.eclipse.etrice.ui.layout.eTriceStructureDiagram";
+ public static final String STRUCTURE_DIAGRAM_TYPE = "org.eclipse.etrice.ui.layout.eTriceStructureDiagram";
/** the priority for eTrice Semantic layout configurations. */
public static final int PRIORITY = 20;
@@ -72,9 +72,9 @@ public class ETriceSemanticLayoutConfig extends SemanticLayoutConfig {
LayoutOptionData<?> layoutOption) {
if (layoutOption.getId().equals(LayoutOptions.DIAGRAM_TYPE.getId())) {
if (semanticElem instanceof ActorContainerClass)
- return STRUCTURE_DAGRAM_TYPE;
+ return STRUCTURE_DIAGRAM_TYPE;
else if (semanticElem instanceof StateGraph)
- return BEHAVIOR_DAGRAM_TYPE;
+ return BEHAVIOR_DIAGRAM_TYPE;
else
return "de.cau.cs.kieler.layout.diagrams.general";
}
diff --git a/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/preferences/ETriceBehaviorPreferencePage.java b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/preferences/ETriceBehaviorPreferencePage.java
new file mode 100644
index 0000000..723c5aa
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/preferences/ETriceBehaviorPreferencePage.java
@@ -0,0 +1,475 @@
+/*******************************************************************************
+ * 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:
+ * Jayant Gupta (initial contribution)
+ *
+ *******************************************************************************/
+package org.eclipse.etrice.ui.layout.preferences;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.etrice.ui.layout.Activator;
+import org.eclipse.etrice.ui.layout.preferences.ETricePreferenceUtil.ElementType;
+import org.eclipse.etrice.ui.layout.preferences.ETricePreferenceUtil.NewOptionDialog;
+import org.eclipse.etrice.ui.layout.preferences.ETricePreferenceUtil.OptionsTableProvider;
+import org.eclipse.graphiti.mm.pictograms.PictogramElement;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TreeNode;
+import org.eclipse.jface.viewers.TreeNodeContentProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.FillLayout;
+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.Group;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
+import org.eclipse.ui.dialogs.ListDialog;
+
+import de.cau.cs.kieler.core.util.Pair;
+import de.cau.cs.kieler.kiml.LayoutDataService;
+import de.cau.cs.kieler.kiml.LayoutOptionData;
+import de.cau.cs.kieler.kiml.ui.Messages;
+import de.cau.cs.kieler.kiml.ui.service.EclipseLayoutInfoService;
+import de.cau.cs.kieler.kiml.ui.views.LayoutViewPart;
+
+/**
+ * Preference page for eTrice Behavior preferences
+ *
+ * @author jayant
+ */
+public class ETriceBehaviorPreferencePage extends PreferencePage implements
+ IWorkbenchPreferencePage {
+
+ /**
+ * Creates the behavior layout preference page.
+ *
+ * @author jayant
+ */
+ public ETriceBehaviorPreferencePage() {
+ super();
+ setDescription("Preference Page for configuring layout options specific to eTrice Behavior diagrams");
+ }
+
+ /** table viewer to refresh after changes to the option table data. */
+ private TableViewer optionTableViewer;
+
+ /** list of layout option entries. */
+ private List<OptionsTableProvider.DataEntry> optionEntries;
+
+ /**
+ * {@inheritDoc}
+ *
+ * @author jayant
+ */
+ @Override
+ protected Control createContents(Composite parent) {
+ Group optionsGroup = createOptionsGroup(parent);
+ optionsGroup
+ .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ return optionsGroup;
+ }
+
+ /**
+ * Creates the group that holds the diagram element options table.
+ *
+ * @param parent
+ * the parent control
+ * @return a group with the diagram element options table
+ */
+ protected Group createOptionsGroup(final Composite parent) {
+ Group elementGroup = new Group(parent, SWT.NONE);
+ elementGroup.setText(Messages.getString("kiml.ui.28")); //$NON-NLS-1$
+ IPreferenceStore preferenceStore = getPreferenceStore();
+ LayoutDataService dataService = LayoutDataService.getInstance();
+ Collection<LayoutOptionData<?>> layoutOptionData = dataService
+ .getOptionData();
+ optionEntries = new LinkedList<OptionsTableProvider.DataEntry>();
+
+ // add options for edit parts and behavior domain model elements
+ Set<String> elements = EclipseLayoutInfoService.getInstance()
+ .getRegisteredElements();
+
+ for (String element : elements) {
+
+ //Finding whether diagram element is an Edit Part or Model Element
+ Class<?> elementClass = null;
+ ElementType type;
+ try {
+ elementClass = Class.forName(element);
+ try {
+ type = PictogramElement.class.isAssignableFrom(elementClass)
+ ? ElementType.EDIT_PART : ElementType.MODEL_ELEM;
+ } catch (NullPointerException e) {
+ type = ElementType.MODEL_ELEM;
+ }
+ } catch (ClassNotFoundException e) {
+ type = ElementType.MODEL_ELEM;
+ }
+
+ //Making the element name more presentable
+ int dotIndex = element.lastIndexOf('.');
+ String partName = element.substring(dotIndex + 1);
+ if (partName.endsWith("Impl")) {
+ partName = partName.substring(0,
+ partName.length() - "Impl".length());
+ }
+
+ for (LayoutOptionData<?> data : layoutOptionData) {
+ String preference = EclipseLayoutInfoService.getPreferenceName(
+ element, data.getId());
+ if (preferenceStore.contains(preference)) {
+ Object value = data.parseValue(preferenceStore
+ .getString(preference));
+ if (value != null) {
+ // If element is edit part or behavior model element,
+ // then add to the option table
+ if (type == ElementType.EDIT_PART
+ || ETriceDomainModelElement
+ .isBehaviorModelElement(element))
+ optionEntries
+ .add(new OptionsTableProvider.DataEntry(
+ partName, element, type, data,
+ value));
+ }
+ }
+ }
+ }
+
+ // add options for diagram types(only those which are relevant to eTrice
+ // Behavior Diagram)
+ for (Pair<String, String> diagramType : ETriceDomainModelElement.BEHAVIOR_DIAGRAM_TYPES) {
+ for (LayoutOptionData<?> data : layoutOptionData) {
+ String preference = EclipseLayoutInfoService.getPreferenceName(
+ diagramType.getFirst(), data.getId());
+ if (preferenceStore.contains(preference)) {
+ Object value = data.parseValue(preferenceStore
+ .getString(preference));
+ if (value != null) {
+ optionEntries.add(new OptionsTableProvider.DataEntry(
+ diagramType.getSecond(),
+ diagramType.getFirst(), ElementType.DIAG_TYPE,
+ data, value));
+ }
+ }
+ }
+ }
+
+ // create the table and actions to edit layout option values
+ addOptionTable(elementGroup, optionEntries);
+
+ elementGroup.setLayout(new GridLayout(2, false));
+ return elementGroup;
+ }
+
+ /**
+ * Adds a table to display options and buttons to edit the options.
+ *
+ * @param parent
+ * the parent to which controls are added
+ * @param entries
+ * the list of table entries
+ */
+ private void addOptionTable(final Composite parent,
+ final List<OptionsTableProvider.DataEntry> entries) {
+ // construct the options table
+ final Table table = new Table(parent, SWT.BORDER);
+ final TableColumn column1 = new TableColumn(table, SWT.NONE);
+ column1.setText(Messages.getString("kiml.ui.29")); //$NON-NLS-1$
+ final TableColumn column2 = new TableColumn(table, SWT.NONE);
+ column2.setText(Messages.getString("kiml.ui.9")); //$NON-NLS-1$
+ final TableColumn column3 = new TableColumn(table, SWT.NONE);
+ column3.setText(Messages.getString("kiml.ui.19")); //$NON-NLS-1$
+ final TableColumn column4 = new TableColumn(table, SWT.NONE);
+ column4.setText(Messages.getString("kiml.ui.20")); //$NON-NLS-1$
+ table.setHeaderVisible(true);
+ final TableViewer tableViewer = new TableViewer(table);
+ OptionsTableProvider optionsTableProvider = new OptionsTableProvider();
+ tableViewer.setContentProvider(optionsTableProvider);
+ tableViewer.setLabelProvider(optionsTableProvider);
+ tableViewer.setInput(entries);
+ optionTableViewer = tableViewer;
+
+ column1.pack();
+ column2.pack();
+ column3.pack();
+ column4.pack();
+ GridData tableLayoutData = new GridData(SWT.FILL, SWT.FILL, true, true,
+ 1, 1);
+ table.setLayoutData(tableLayoutData);
+ table.pack();
+ tableLayoutData.heightHint = ETricePreferenceUtil.OPTIONS_TABLE_HEIGHT;
+
+ // add button to add new options
+ Composite composite = new Composite(parent, SWT.NONE);
+ final Button newButton = new Button(composite, SWT.PUSH | SWT.CENTER);
+ newButton.setText(Messages.getString("kiml.ui.41")); //$NON-NLS-1$
+
+ // add button to edit the options
+ final Button editButton = new Button(composite, SWT.PUSH | SWT.CENTER);
+ editButton.setText(Messages.getString("kiml.ui.21")); //$NON-NLS-1$
+ editButton.setEnabled(false);
+ editButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(final SelectionEvent event) {
+ OptionsTableProvider.DataEntry entry = ETricePreferenceUtil
+ .getEntry(entries, table.getSelectionIndex());
+ if (entry != null) {
+ ETricePreferenceUtil.showEditDialog(parent.getShell(),
+ entry);
+ tableViewer.refresh();
+ }
+ }
+ });
+
+ // add button to remove an option
+ final Button removeButton = new Button(composite, SWT.PUSH | SWT.CENTER);
+ removeButton.setText(Messages.getString("kiml.ui.22")); //$NON-NLS-1$
+ removeButton.setEnabled(false);
+ removeButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(final SelectionEvent event) {
+ OptionsTableProvider.DataEntry entry = ETricePreferenceUtil
+ .getEntry(entries, table.getSelectionIndex());
+ if (entry != null) {
+ entry.setValue(null);
+ tableViewer.refresh();
+ int count = 0;
+ for (OptionsTableProvider.DataEntry e : entries) {
+ if (e.getValue() != null) {
+ count++;
+ }
+ }
+ if (count == 0) {
+ editButton.setEnabled(false);
+ removeButton.setEnabled(false);
+ }
+ }
+ }
+ });
+
+ // react on selection changes of the options table
+ table.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(final SelectionEvent event) {
+ if (!entries.isEmpty() && event.item != null) {
+ editButton.setEnabled(true);
+ removeButton.setEnabled(true);
+ } else {
+ editButton.setEnabled(false);
+ removeButton.setEnabled(false);
+ }
+ }
+ });
+ newButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(final SelectionEvent event) {
+ int newIndex = showNewDialog(parent.getShell(), entries);
+ if (newIndex >= 0) {
+ tableViewer.refresh();
+ tableViewer.setSelection(new StructuredSelection(entries
+ .get(newIndex)));
+ editButton.setEnabled(true);
+ removeButton.setEnabled(true);
+ column1.pack();
+ column2.pack();
+ column3.pack();
+ column4.pack();
+ }
+ }
+ });
+
+ composite.setLayout(new FillLayout(SWT.VERTICAL));
+ GridData compositeLayoutData = new GridData(SWT.LEFT, SWT.TOP, false,
+ false, 1, 1);
+ composite.setLayoutData(compositeLayoutData);
+ }
+
+ /**
+ * Shows an input dialog to add a new layout option to the list.
+ *
+ * @param shell
+ * the current shell
+ * @param entries
+ * the list of table entries
+ * @return the table index to put focus on, or -1 if the focus should not be
+ * changed
+ */
+ private int showNewDialog(final Shell shell,
+ final List<OptionsTableProvider.DataEntry> entries) {
+
+ NewOptionDialog dialog = new NewOptionDialog(shell) {
+ // Overriding the function for Behavior diagrams specific
+ // implementation
+
+ /**
+ * @author jayant
+ */
+ @Override
+ protected String showBrowseModelElementDialog() {
+ ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(
+ this.getShell(), new LabelProvider(),
+ new TreeNodeContentProvider());
+ dialog.setTitle("Select Behavior Model Element");
+
+ TreeNode[] input = ETriceDomainModelElement.BEHAVIOR_MODEL
+ .getChildren();
+ dialog.setInput(input);
+
+ if (dialog.open() == ElementTreeSelectionDialog.OK) {
+ Object[] result = dialog.getResult();
+ if (result != null && result.length > 0) {
+ return ((ETriceDomainModelElement) result[0]).getId();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @author jayant
+ */
+ @Override
+ protected String showBrowseDiagtDialog() {
+ ListDialog dialog = new ListDialog(this.getShell());
+ dialog.setTitle(Messages.getString("kiml.ui.57")); //$NON-NLS-1$
+ dialog.setContentProvider(ArrayContentProvider.getInstance());
+ dialog.setLabelProvider(new LabelProvider());
+
+ SelectionData[] input = new SelectionData[ETriceDomainModelElement.BEHAVIOR_DIAGRAM_TYPES
+ .size()];
+ int i = 0;
+ for (Pair<String, String> type : ETriceDomainModelElement.BEHAVIOR_DIAGRAM_TYPES) {
+ SelectionData seld = new SelectionData(type);
+ input[i++] = seld;
+ }
+ Arrays.sort(input);
+ dialog.setInput(input);
+ if (dialog.open() == ListDialog.OK) {
+ Object[] result = dialog.getResult();
+ if (result != null && result.length > 0) {
+ return ((SelectionData) result[0]).getId();
+ }
+ }
+ return null;
+ }
+ };
+
+ if (dialog.open() == NewOptionDialog.OK) {
+ OptionsTableProvider.DataEntry newEntry = dialog.createDataEntry();
+ if (newEntry == null) {
+ MessageDialog.openError(shell,
+ Messages.getString("kiml.ui.51"),
+ Messages.getString("kiml.ui.52"));
+ } else {
+ // look for an existing entry with same identifiers
+ int oldIndex = 0;
+ OptionsTableProvider.DataEntry oldEntry = null;
+ for (OptionsTableProvider.DataEntry e : entries) {
+ if (e.getValue() != null) {
+ if (e.equals(newEntry)) {
+ oldEntry = e;
+ break;
+ }
+ oldIndex++;
+ }
+ }
+ if (oldEntry != null) {
+ return oldIndex;
+ } else {
+ entries.add(newEntry);
+ return entries.size() - 1;
+ }
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @author jayant
+ */
+ public void init(final IWorkbench workbench) {
+ setPreferenceStore(Activator.getDefault().getSharedPreferenceStore());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @author jayant
+ */
+ @Override
+ protected void performDefaults() {
+ super.performDefaults();
+
+ // clear the layout options table
+ for (OptionsTableProvider.DataEntry entry : optionEntries) {
+ entry.setValue(null);
+ }
+ optionTableViewer.refresh();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @author jayant
+ */
+ @Override
+ public boolean performOk() {
+ EclipseLayoutInfoService infoService = EclipseLayoutInfoService
+ .getInstance();
+ IPreferenceStore preferenceStore = getPreferenceStore();
+
+ // store data for the diagram element and diagram type options
+ for (OptionsTableProvider.DataEntry entry : optionEntries) {
+ Object oldValue = infoService.getOptionValue(entry.getElementId(),
+ entry.getOptionData().getId());
+ Object newValue = entry.getValue();
+ if (oldValue == null && newValue != null
+ || !oldValue.equals(newValue)) {
+ String preference = EclipseLayoutInfoService.getPreferenceName(
+ entry.getElementId(), entry.getOptionData().getId());
+ if (newValue == null) {
+ infoService.removeOptionValue(entry.getElementId(), entry
+ .getOptionData().getId());
+ preferenceStore.setToDefault(preference);
+ infoService.getRegisteredElements().remove(
+ entry.getElementId());
+ } else {
+ infoService.addOptionValue(entry.getElementId(), entry
+ .getOptionData().getId(), newValue);
+ preferenceStore.setValue(preference, newValue.toString());
+ if (entry.getType() != ElementType.DIAG_TYPE) {
+ infoService.getRegisteredElements().add(
+ entry.getElementId());
+ }
+ }
+ }
+ }
+
+ LayoutViewPart layoutView = LayoutViewPart.findView();
+ if (layoutView != null) {
+ layoutView.refresh();
+ }
+ return true;
+ }
+
+}
diff --git a/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/preferences/ETriceDomainModelElement.java b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/preferences/ETriceDomainModelElement.java
new file mode 100644
index 0000000..1276dbd
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/preferences/ETriceDomainModelElement.java
@@ -0,0 +1,306 @@
+/*******************************************************************************
+ * 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:
+ * Jayant Gupta (initial contribution)
+ *
+ *******************************************************************************/
+package org.eclipse.etrice.ui.layout.preferences;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.jface.util.Util;
+import org.eclipse.jface.viewers.TreeNode;
+
+import de.cau.cs.kieler.core.util.Pair;
+
+/**
+ * A class to represent Domain Model Elements(classes of eTrice). The class
+ * extends {@code TreeNode} which helps in :
+ * <ul>
+ * <li>Representing the class hierarchy
+ * <li>Making it a valid object to be passes to {@code TreeNodeContentProvider},
+ * thus eliminates the need of a custom Content Provider.
+ * </ul>
+ *
+ * @author jayant
+ *
+ */
+public class ETriceDomainModelElement extends TreeNode {
+
+ /**
+ * Constructs a new instance of {@code ETriceDomainModelElement} with the
+ * given id and no children.
+ *
+ * @param id
+ * The String which represents the Fully Qualified Domain Name of
+ * the Class
+ *
+ * @author jayant
+ */
+ public ETriceDomainModelElement(String id) {
+ super(id.substring(id.lastIndexOf('.') + 1));
+ this.id = id;
+ }
+
+ /**
+ * Constructs a new instance of {@code ETriceDomainModelElement} with given
+ * id and array of children
+ *
+ * @param id
+ * The String which represents the Fully Qualified Domain Name of
+ * the Class
+ * @param children
+ * The array of children fo this element(node)
+ *
+ * @author jayant
+ */
+ public ETriceDomainModelElement(String id,
+ ETriceDomainModelElement[] children) {
+ super(id.substring(id.lastIndexOf('.') + 1));
+ this.id = id;
+ setChildren(children);
+ }
+
+ /**
+ * The id of the Domain Model Class. This is a string which is the Fully
+ * Qualified Domain Name of the class.
+ */
+ private String id;
+
+ /**
+ * The public instance of {@code ETriceDomainModelElement} which encompasses
+ * the complete class hierarchy of configurable Structure diagram elements
+ */
+ public static final ETriceDomainModelElement STRUCTURE_MODEL = new ETriceDomainModelElement(
+ "StructureRoot",
+ new ETriceDomainModelElement[] {
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.ActorContainerRef",
+ new ETriceDomainModelElement[] {
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.ActorRef"),
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.SubSystemRef") }),
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.InterfaceItem",
+ new ETriceDomainModelElement[] {
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.Port"),
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.SAPRef"),
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.SPPRef") }),
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.StructureClass",
+ new ETriceDomainModelElement[] {
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.ActorContainerClass",
+ new ETriceDomainModelElement[] {
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.ActorClass"),
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.SubSystemClass") }),
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.LogicalSystem") }),
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.SAPoint",
+ new ETriceDomainModelElement[] {
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.RefSAPoint"),
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.RelaySAPoint") }),
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.SPPoint"),
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.Binding") });
+
+ /**
+ * The public instance of {@code ETriceDomainModelElement} which encompasses
+ * the complete class hierarchy of configurable Behavior diagram elements
+ */
+ public static final ETriceDomainModelElement BEHAVIOR_MODEL = new ETriceDomainModelElement(
+ "BehaviorRoot",
+ new ETriceDomainModelElement[] {
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.StateGraph"),
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.StateGraphItem",
+ new ETriceDomainModelElement[] {
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.StateGraphNode",
+ new ETriceDomainModelElement[] {
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.ChoicePoint"),
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.State",
+ new ETriceDomainModelElement[] {
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.RefinedState"),
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.SimpleState") }),
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.TrPoint",
+ new ETriceDomainModelElement[] {
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.EntryPoint"),
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.ExitPoint"),
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.TransitionPoint") }) }),
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.Transition",
+ new ETriceDomainModelElement[] {
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.InitialTransition"),
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.NonInitialTransition",
+ new ETriceDomainModelElement[] {
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.ContinuationTransition"),
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.CPBranchTransition"),
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.TransitionChainStartTransition",
+ new ETriceDomainModelElement[] {
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.GuardedTransition"),
+ new ETriceDomainModelElement(
+ "org.eclipse.etrice.core.room.TriggeredTransition") }) }) }) }), });
+
+ /**
+ * public list of {@code Pair<String, <String>>} enumerating all diagram
+ * types relevant for Structure Diagrams
+ */
+ @SuppressWarnings("unchecked")
+ public static final List<Pair<String, String>> STRUCTURE_DIAGRAM_TYPES = new ArrayList<Pair<String, String>>(
+ Arrays.asList(
+ new Pair<String, String>(
+ "de.cau.cs.kieler.layout.diagrams.gereral",
+ "General"),
+ new Pair<String, String>(
+ "org.eclipse.etrice.ui.layout.eTriceStructureDiagram",
+ "eTrice Structure Diagram")));
+
+ /**
+ * public list of {@code Pair<String, <String>>} enumerating all diagram
+ * types relevant for Behavior Diagrams
+ */
+ @SuppressWarnings("unchecked")
+ public static final List<Pair<String, String>> BEHAVIOR_DIAGRAM_TYPES = new ArrayList<Pair<String, String>>(
+ Arrays.asList(
+ new Pair<String, String>(
+ "de.cau.cs.kieler.layout.diagrams.gereral",
+ "General"),
+ new Pair<String, String>(
+ "org.eclipse.etrice.ui.layout.eTriceBehaviorDiagram",
+ "eTrice Behavior Diagram")));
+
+ /**
+ * Finds whether the given id belongs to a particular domain model class
+ * (for behavior diagram elements)
+ *
+ * @param id
+ * The id to be checked (found)
+ * @return true, if there is a class in behavior model hierarchy with same
+ * id, otherwise false
+ */
+ public static boolean isBehaviorModelElement(String id) {
+ return (BEHAVIOR_MODEL.traverseModel(id));
+ }
+
+ /**
+ * Finds whether the given id belongs to a particular domain model class
+ * (for structure diagram elements)
+ *
+ * @param id
+ * The id to be found
+ * @return true, if there is a class in structure model hierarchy with same
+ * id, otherwise false
+ */
+ public static boolean isStructureModelElement(String id) {
+ return (STRUCTURE_MODEL.traverseModel(id));
+ }
+
+ /**
+ * Traverses the n-ary tree recursively from the invoking node and try to
+ * find the given id.
+ *
+ * @param findId
+ * The id to be found
+ * @return true, if id matches with any node of the tree (with root as the
+ * invoking node), otherwise false
+ */
+ public boolean traverseModel(final String findId) {
+
+ if (Util.equals(this.id, findId)) {
+ return true;
+ } else {
+ TreeNode[] children = getChildren();
+ if (children != null) {
+ for (TreeNode child : children) {
+ if (((ETriceDomainModelElement) child)
+ .traverseModel(findId))
+ return true;
+ }
+ }
+
+ return false;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @author jayant
+ */
+ @Override
+ public boolean equals(final Object object) {
+ if (object instanceof ETriceDomainModelElement) {
+ return Util.equals(this.id, ((ETriceDomainModelElement) object).id);
+ }
+
+ return false;
+ }
+
+ /**
+ * Getter for id
+ *
+ * @return the id
+ *
+ * @author jayant
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * Setter for id
+ *
+ * @param id
+ * the id to set
+ *
+ * @author jayant
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Useful for using this class with default {@code LabelProvider}
+ *
+ * @author jayant
+ */
+ @Override
+ public String toString() {
+ return ((String) value + " (" + id + ")");
+ }
+
+}
diff --git a/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/preferences/ETriceLayoutPreferencePage.java b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/preferences/ETriceLayoutPreferencePage.java
new file mode 100644
index 0000000..abdb1ae
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/preferences/ETriceLayoutPreferencePage.java
@@ -0,0 +1,183 @@
+/*******************************************************************************
+ * 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:
+ * Jayant Gupta (initial contribution)
+ *
+ *******************************************************************************/
+package org.eclipse.etrice.ui.layout.preferences;
+
+import org.eclipse.etrice.ui.layout.Activator;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+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.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+
+import de.cau.cs.kieler.kiml.ui.Messages;
+import de.cau.cs.kieler.kiml.ui.diagram.LayoutHandler;
+import de.cau.cs.kieler.kiml.ui.service.EclipseLayoutInfoService;
+import de.cau.cs.kieler.kiml.ui.views.LayoutViewPart;
+
+/**
+ * Preference page for common KIML preferences.
+ *
+ * @author jayant
+ */
+public class ETriceLayoutPreferencePage extends PreferencePage implements
+ IWorkbenchPreferencePage {
+
+ /** checkbox for animation. */
+ private Button animationCheckBox;
+ /** checkbox for zoom-to-fit. */
+ private Button zoomCheckBox;
+ /** checkbox for progress dialog. */
+ private Button progressCheckBox;
+ /** checkbox for edge routing style. */
+ private Button obliqueCheckBox;
+
+ /**
+ * Creates the layout preference page.
+ *
+ * @author jayant
+ */
+ public ETriceLayoutPreferencePage() {
+ super();
+ setDescription("Preferences for eTrice automatic diagram layout");
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @author jayant
+ */
+ protected Control createContents(final Composite parent) {
+ Composite composite = new Composite(parent, SWT.NONE);
+
+ Group generalGroup = createGeneralGroup(composite);
+ generalGroup
+ .setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+
+ Label redirectionText = new Label(composite, SWT.WRAP);
+ redirectionText.setAlignment(SWT.LEFT);
+ redirectionText
+ .setText("Use sub-pages to set Diagram specific preferences");
+
+ GridLayout compositeLayout = new GridLayout(1, false);
+ composite.setLayout(compositeLayout);
+
+ return composite;
+ }
+
+ /** margin width for layouts. */
+ private static final int MARGIN_WIDTH = 10;
+ /** margin height for layouts. */
+ private static final int MARGIN_HEIGHT = 5;
+
+ /**
+ * Creates the group for general options.
+ *
+ * @param parent
+ * the parent control
+ * @return a group with general options
+ */
+ private Group createGeneralGroup(final Composite parent) {
+ Group generalGroup = new Group(parent, SWT.NONE);
+ generalGroup.setText(Messages.getString("kiml.ui.35")); //$NON-NLS-1$
+
+ // add check box for animation
+ animationCheckBox = new Button(generalGroup, SWT.CHECK | SWT.LEFT);
+ animationCheckBox.setText(Messages.getString("kiml.ui.64")); //$NON-NLS-1$
+ animationCheckBox.setSelection(getPreferenceStore().getBoolean(
+ LayoutHandler.PREF_ANIMATION));
+
+ // add check box for zoom-to-fit
+ zoomCheckBox = new Button(generalGroup, SWT.CHECK | SWT.LEFT);
+ zoomCheckBox.setText(Messages.getString("kiml.ui.65")); //$NON-NLS-1$
+ zoomCheckBox.setSelection(getPreferenceStore().getBoolean(
+ LayoutHandler.PREF_ZOOM));
+
+ // add check box for progress dialog
+ progressCheckBox = new Button(generalGroup, SWT.CHECK | SWT.LEFT);
+ progressCheckBox.setText(Messages.getString("kiml.ui.66")); //$NON-NLS-1$
+ progressCheckBox.setSelection(getPreferenceStore().getBoolean(
+ LayoutHandler.PREF_PROGRESS));
+
+ // add check box for oblique routing
+ obliqueCheckBox = new Button(generalGroup, SWT.CHECK | SWT.LEFT);
+ obliqueCheckBox.setText(Messages.getString("kiml.ui.36")); //$NON-NLS-1$
+ obliqueCheckBox.setSelection(getPreferenceStore().getBoolean(
+ EclipseLayoutInfoService.PREF_OBLIQUE_ROUTE));
+
+ FillLayout layout = new FillLayout(SWT.VERTICAL);
+ layout.marginWidth = MARGIN_WIDTH;
+ layout.marginHeight = MARGIN_HEIGHT;
+ generalGroup.setLayout(layout);
+ return generalGroup;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @author jayant
+ */
+ public void init(final IWorkbench workbench) {
+ setPreferenceStore(Activator.getDefault().getSharedPreferenceStore());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void performDefaults() {
+ super.performDefaults();
+ IPreferenceStore preferenceStore = getPreferenceStore();
+
+ // set default values for the general options
+ animationCheckBox.setSelection(preferenceStore
+ .getDefaultBoolean(LayoutHandler.PREF_ANIMATION));
+ zoomCheckBox.setSelection(preferenceStore
+ .getDefaultBoolean(LayoutHandler.PREF_ZOOM));
+ progressCheckBox.setSelection(preferenceStore
+ .getDefaultBoolean(LayoutHandler.PREF_PROGRESS));
+ obliqueCheckBox
+ .setSelection(preferenceStore
+ .getDefaultBoolean(EclipseLayoutInfoService.PREF_OBLIQUE_ROUTE));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean performOk() {
+ IPreferenceStore preferenceStore = getPreferenceStore();
+
+ // set new values for the general options
+ preferenceStore.setValue(LayoutHandler.PREF_ANIMATION,
+ animationCheckBox.getSelection());
+ preferenceStore.setValue(LayoutHandler.PREF_ZOOM,
+ zoomCheckBox.getSelection());
+ preferenceStore.setValue(LayoutHandler.PREF_PROGRESS,
+ progressCheckBox.getSelection());
+ preferenceStore.setValue(EclipseLayoutInfoService.PREF_OBLIQUE_ROUTE,
+ obliqueCheckBox.getSelection());
+
+ LayoutViewPart layoutView = LayoutViewPart.findView();
+ if (layoutView != null) {
+ layoutView.refresh();
+ }
+ return true;
+ }
+
+}
diff --git a/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/preferences/ETricePreferenceUtil.java b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/preferences/ETricePreferenceUtil.java
new file mode 100644
index 0000000..7d1a770
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/preferences/ETricePreferenceUtil.java
@@ -0,0 +1,800 @@
+/*******************************************************************************
+ * 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:
+ * Jayant Gupta (initial contribution)
+ *
+ *******************************************************************************/
+package org.eclipse.etrice.ui.layout.preferences;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+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.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.dialogs.ListDialog;
+
+import de.cau.cs.kieler.core.util.Pair;
+import de.cau.cs.kieler.kiml.LayoutDataService;
+import de.cau.cs.kieler.kiml.LayoutOptionData;
+import de.cau.cs.kieler.kiml.options.LayoutOptions;
+import de.cau.cs.kieler.kiml.ui.KimlUiPlugin;
+import de.cau.cs.kieler.kiml.ui.LayoutOptionValidator;
+import de.cau.cs.kieler.kiml.ui.LayouterHintDialog;
+import de.cau.cs.kieler.kiml.ui.Messages;
+import de.cau.cs.kieler.kiml.ui.service.EclipseLayoutDataService;
+import de.cau.cs.kieler.kiml.ui.service.EclipseLayoutInfoService;
+
+/**
+ * The Utility class for eTrice Preference Pages.
+ * <p>
+ * This class provides a few useful methods, an enumerated type and two static nested class :
+ * <ul>
+ * <li>{@link ElementType}</li>
+ * <li>{@link NewOptionDialog}</li>
+ * <li>{@link OptionsTableProvider}</li>
+ * </ul>
+ *
+ * @author jayant
+ */
+public final class ETricePreferenceUtil {
+
+ /**
+ * Hidden constructor to avoid instantiation.
+ *
+ * @author jayant
+ */
+ private ETricePreferenceUtil() {
+
+ }
+
+ /** fixed height of the options table. */
+ public static final int OPTIONS_TABLE_HEIGHT = 300;
+
+ /**
+ * Fetches the entry with given index of a list of data entry, bypassing
+ * elements whose value was set to {@code null}.
+ *
+ * @param entries
+ * list of data entries
+ * @param index
+ * index of the entry to look up
+ * @return the entry at the given index
+ */
+ public static OptionsTableProvider.DataEntry getEntry(
+ final List<OptionsTableProvider.DataEntry> entries, final int index) {
+ ListIterator<OptionsTableProvider.DataEntry> entryIter = entries
+ .listIterator();
+ int i = 0;
+ while (entryIter.hasNext()) {
+ OptionsTableProvider.DataEntry entry = entryIter.next();
+ if (entry.getValue() != null) {
+ if (i == index) {
+ return entry;
+ }
+ i++;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Shows an input dialog to edit the given option table entry.
+ *
+ * @param shell
+ * the current shell
+ * @param entry
+ * an option table entry
+ */
+ public static void showEditDialog(final Shell shell,
+ final OptionsTableProvider.DataEntry entry) {
+ LayoutOptionData<?> optionData = entry.getOptionData();
+ if (entry.getValue() != null) {
+ if (optionData.equals(LayoutOptions.ALGORITHM)) {
+ // show a selection dialog for a layouter hint
+ LayouterHintDialog dialog = new LayouterHintDialog(shell, null);
+ if (dialog.open() == LayouterHintDialog.OK) {
+ String result = dialog.getSelectedHint();
+ if (result != null) {
+ entry.setValue(result);
+ }
+ }
+ } else {
+ // show an input dialog for some other option
+ String value = entry.getValue().toString();
+ InputDialog dialog = new InputDialog(shell,
+ Messages.getString("kiml.ui.23"),
+ Messages.getString("kiml.ui.24"), value,
+ new LayoutOptionValidator(optionData));
+ if (dialog.open() == InputDialog.OK) {
+ String result = dialog.getValue().trim();
+ switch (optionData.getType()) {
+ case REMOTE_ENUM:
+ case ENUM:
+ entry.setValue(optionData.parseValue(result
+ .toUpperCase()));
+ break;
+ default:
+ entry.setValue(optionData.parseValue(result));
+ }
+ }
+ }
+ }
+ }
+
+
+
+ /**
+ * Enumeration of element types that can receive default options.
+ *
+ * @author msp
+ */
+ public static enum ElementType {
+
+ /** highest priority: edit parts of specific diagram editors. */
+ EDIT_PART,
+
+ /** medium priority: domain model elements. */
+ MODEL_ELEM,
+
+ /** lowest priority: diagram type definition (contributed via extension point). */
+ DIAG_TYPE;
+
+ /**
+ * Returns a description for the element type.
+ *
+ * @return a user-friendly description
+ */
+ public String getDescription() {
+ switch (this) {
+ case EDIT_PART:
+ return Messages.getString("kiml.ui.54");
+ case MODEL_ELEM:
+ return Messages.getString("kiml.ui.55");
+ case DIAG_TYPE:
+ return Messages.getString("kiml.ui.56");
+ }
+ return null;
+ }
+
+ }
+
+
+
+ /**
+ * A dialog to add new default layout options in the preference page.
+ *
+ * @author msp
+ * @author jayant (adapted it for eTrice)
+ */
+ public static class NewOptionDialog extends Dialog {
+
+ /** the currently selected element type. */
+ private ElementType elementType;
+ /** the text for selection of a specific element. */
+ private Text elementText;
+ /** the value of the specific element or diagram type. */
+ private String elementValue;
+ /** the browse button for element selection. */
+ private Button elementBrowseButton;
+ /** the text for selection of a layout option. */
+ private Text optionText;
+ /** the value of the layout option identifier. */
+ private String optionValue;
+
+ /**
+ * Creates a new option dialog.
+ *
+ * @param parentShell
+ * the parent shell
+ */
+ protected NewOptionDialog(final Shell parentShell) {
+ super(parentShell);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void configureShell(final Shell shell) {
+ super.configureShell(shell);
+ shell.setText(Messages.getString("kiml.ui.46")); //$NON-NLS-1$
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean close() {
+ elementValue = elementText.getText();
+ optionValue = optionText.getText();
+ return super.close();
+ }
+
+ /** gap between label and control. */
+ private static final int HORIZONTAL_GAP = 8;
+ /** minimum width of each group. */
+ private static final int MINIMUM_WIDTH = 500;
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected Control createDialogArea(final Composite parent) {
+ Composite composite = (Composite) super.createDialogArea(parent);
+ createTypeGroup(composite);
+ createElementGroup(composite);
+ createOptionGroup(composite);
+ return composite;
+ }
+
+ /**
+ * Create group for element type selection.
+ *
+ * @param parent
+ * the parent control
+ */
+ protected void createTypeGroup(final Composite parent) {
+ Group group = new Group(parent, SWT.NONE);
+ group.setText(Messages.getString("kiml.ui.42")); //$NON-NLS-1$
+ GridLayout layout = new GridLayout(1, false);
+ layout.horizontalSpacing = HORIZONTAL_GAP;
+ group.setLayout(layout);
+ String[][] labelsAndValues = new String[][] {
+ {
+ Messages.getString("kiml.ui.43"), ElementType.EDIT_PART.toString() }, //$NON-NLS-1$
+ {
+ Messages.getString("kiml.ui.44"), ElementType.MODEL_ELEM.toString() }, //$NON-NLS-1$
+ {
+ Messages.getString("kiml.ui.45"), ElementType.DIAG_TYPE.toString() } //$NON-NLS-1$
+ };
+ for (int i = 0; i < labelsAndValues.length; i++) {
+ Button radio = new Button(group, SWT.RADIO | SWT.LEFT);
+ radio.setSelection(i == 0);
+ String[] labelAndValue = labelsAndValues[i];
+ radio.setText(labelAndValue[0]);
+ radio.setData(labelAndValue[1]);
+ radio.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(final SelectionEvent event) {
+ elementType = ElementType.valueOf((String) event.widget
+ .getData());
+ elementBrowseButton
+ .setEnabled(elementType == ElementType.DIAG_TYPE
+ || elementType == ElementType.MODEL_ELEM);
+ }
+ });
+ }
+ elementType = ElementType.EDIT_PART;
+ GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
+ gridData.minimumWidth = MINIMUM_WIDTH;
+ group.setLayoutData(gridData);
+ }
+
+ /**
+ * Create group for selection of specific element.
+ *
+ * @param parent
+ * the parent control
+ */
+ protected void createElementGroup(final Composite parent) {
+ Group group = new Group(parent, SWT.NONE);
+ group.setText(Messages.getString("kiml.ui.47")); //$NON-NLS-1$
+ group.setLayout(new GridLayout(2, false));
+ Label label = new Label(group, SWT.WRAP);
+ label.setText(Messages.getString("kiml.ui.53")); //$NON-NLS-1$
+ GridData labelLayoutData = new GridData(SWT.LEFT, SWT.FILL, false,
+ false, 2, 1);
+ labelLayoutData.widthHint = MINIMUM_WIDTH - HORIZONTAL_GAP;
+ label.setLayoutData(labelLayoutData);
+ elementText = new Text(group, SWT.SINGLE | SWT.BORDER);
+ elementText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true,
+ false));
+ elementBrowseButton = new Button(group, SWT.PUSH | SWT.CENTER);
+ elementBrowseButton.setEnabled(false);
+ elementBrowseButton.setText(Messages.getString("kiml.ui.48")); //$NON-NLS-1$
+ elementBrowseButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(final SelectionEvent e) {
+ String id = (elementType == ElementType.DIAG_TYPE) ? showBrowseDiagtDialog()
+ : showBrowseModelElementDialog();
+ if (id != null) {
+ elementText.setText(id);
+ }
+ }
+ });
+ GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
+ gridData.minimumWidth = MINIMUM_WIDTH;
+ group.setLayoutData(gridData);
+ }
+
+ /**
+ * Create group for selection of a layout option.
+ *
+ * @param parent
+ * the parent control
+ */
+ protected void createOptionGroup(final Composite parent) {
+ Group group = new Group(parent, SWT.NONE);
+ group.setText(Messages.getString("kiml.ui.49")); //$NON-NLS-1$
+ group.setLayout(new GridLayout(2, false));
+ optionText = new Text(group, SWT.SINGLE | SWT.BORDER);
+ optionText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true,
+ false));
+ Button browseButton = new Button(group, SWT.PUSH | SWT.CENTER);
+ browseButton.setText(Messages.getString("kiml.ui.48")); //$NON-NLS-1$
+ browseButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(final SelectionEvent e) {
+ String id = showBrowseOptionDialog();
+ if (id != null) {
+ optionText.setText(id);
+ }
+ }
+ });
+ GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
+ gridData.minimumWidth = MINIMUM_WIDTH;
+ group.setLayoutData(gridData);
+
+ }
+
+ /** data holder class for selection of a layout option or diagram type. */
+ protected static final class SelectionData implements
+ Comparable<SelectionData> {
+ private String id;
+
+ /**
+ * @return the id
+ */
+ public String getId() {
+ return id;
+ }
+
+ private String name;
+ private LayoutOptionData.Type type;
+
+ /**
+ * Create a selection data object from a layout option data.
+ *
+ * @param optionData
+ * a layout option data
+ */
+ public SelectionData(final LayoutOptionData<?> optionData) {
+ this.id = optionData.getId();
+ this.name = optionData.getName();
+ this.type = optionData.getType();
+ }
+
+ /**
+ * Create a selection data object from a diagram type.
+ *
+ * @param diagramType
+ * a pair with the diagram type identifier as first
+ * element and the name as second element
+ */
+ public SelectionData(final Pair<String, String> diagramType) {
+ this.id = diagramType.getFirst();
+ this.name = diagramType.getSecond();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(final Object object) {
+ if (object instanceof SelectionData) {
+ SelectionData other = (SelectionData) object;
+ return this.id.equals(other.id)
+ && this.name.equals(other.name);
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ return id.hashCode() + name.hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return name + " (" + id + ")";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int compareTo(final SelectionData other) {
+ int nameComp = this.name.compareTo(other.name);
+ if (nameComp == 0) {
+ return this.id.compareTo(other.id);
+ } else {
+ return nameComp;
+ }
+ }
+ }
+
+ /**
+ * Open a dialog to browse diagram types.
+ *
+ * @return the selected diagram type
+ */
+ protected String showBrowseDiagtDialog() {
+ ListDialog dialog = new ListDialog(this.getShell());
+ dialog.setTitle(Messages.getString("kiml.ui.57")); //$NON-NLS-1$
+ dialog.setContentProvider(ArrayContentProvider.getInstance());
+ dialog.setLabelProvider(new LabelProvider());
+ List<Pair<String, String>> diagramTypes = EclipseLayoutInfoService
+ .getInstance().getDiagramTypes();
+ SelectionData[] input = new SelectionData[diagramTypes.size()];
+ int i = 0;
+ for (Pair<String, String> type : diagramTypes) {
+ SelectionData seld = new SelectionData(type);
+ input[i++] = seld;
+ }
+ Arrays.sort(input);
+ dialog.setInput(input);
+ if (dialog.open() == ListDialog.OK) {
+ Object[] result = dialog.getResult();
+ if (result != null && result.length > 0) {
+ return ((SelectionData) result[0]).id;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Open a dialog to browse Domain Model Elements (Classes).
+ *
+ * @return the selected Model Element
+ *
+ * @author jayant
+ */
+ protected String showBrowseModelElementDialog() {
+ // The Exact Implementation depends on the respective preference
+ // classes
+ // from which the New Dialog is invoked
+
+ return "null";
+ }
+
+ /**
+ * Open a dialog to browse layout options.
+ *
+ * @return the selected layout option
+ */
+ protected String showBrowseOptionDialog() {
+ ListDialog dialog = new ListDialog(this.getShell());
+ dialog.setTitle(Messages.getString("kiml.ui.50")); //$NON-NLS-1$
+ dialog.setContentProvider(ArrayContentProvider.getInstance());
+ dialog.setLabelProvider(new LabelProvider() {
+ public Image getImage(final Object element) {
+ if (element instanceof SelectionData) {
+ KimlUiPlugin.Images images = KimlUiPlugin.getDefault()
+ .getImages();
+ switch (((SelectionData) element).type) {
+ case OBJECT:
+ case STRING:
+ return images.getPropText();
+ case BOOLEAN:
+ return images.getPropTrue();
+ case REMOTE_ENUM:
+ case ENUM:
+ return images.getPropChoice();
+ case INT:
+ return images.getPropInt();
+ case FLOAT:
+ return images.getPropFloat();
+ }
+ }
+ return null;
+ }
+ });
+ Collection<LayoutOptionData<?>> data = EclipseLayoutDataService
+ .getInstance().getOptionData();
+ ArrayList<SelectionData> inputList = new ArrayList<SelectionData>(
+ data.size());
+ for (LayoutOptionData<?> optionData : data) {
+ // layout options without target definition are now shown to the
+ // user
+ if (!optionData.getTargets().isEmpty()) {
+ inputList.add(new SelectionData(optionData));
+ }
+ }
+ SelectionData[] input = inputList.toArray(new SelectionData[0]);
+ Arrays.sort(input);
+ dialog.setInput(input);
+ if (dialog.open() == ListDialog.OK) {
+ Object[] result = dialog.getResult();
+ if (result != null && result.length > 0) {
+ return ((SelectionData) result[0]).id;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Create a new data entry for the layout option.
+ *
+ * @return a new data entry, or {@code null} if the dialog contents are
+ * invalid
+ */
+ public OptionsTableProvider.DataEntry createDataEntry() {
+ if (elementValue != null && optionValue != null) {
+ String name;
+ if (elementType == ElementType.DIAG_TYPE) {
+ name = EclipseLayoutInfoService.getInstance()
+ .getDiagramTypeName(elementValue);
+ } else {
+ int dotIndex = elementValue.lastIndexOf('.');
+ name = elementValue.substring(dotIndex + 1);
+ }
+ LayoutOptionData<?> optionData = LayoutDataService
+ .getInstance().getOptionData(optionValue);
+ if (optionData != null) {
+ Object value = optionData.getDefault();
+ if (value == null) {
+ value = optionData.getDefaultDefault();
+ }
+ if (name != null && value != null) {
+ return new OptionsTableProvider.DataEntry(name,
+ elementValue, elementType, optionData, value);
+ }
+ }
+ }
+ return null;
+ }
+
+ }
+
+ /**
+ * Provider class for the options tables. Contains a label provider and a
+ * content provider.
+ *
+ * @author msp
+ */
+ public static class OptionsTableProvider extends LabelProvider implements
+ ITableLabelProvider, IStructuredContentProvider {
+
+ /** data type for row entries in the table. */
+ public static class DataEntry {
+ /** name of the associated diagram type or element. */
+ private String elementName;
+ /** identifier of the associated diagram type or element type. */
+ private String elementId;
+ /** type of element (diagram type / model element / edit part). */
+ private ElementType type;
+ /** layout option data. */
+ private LayoutOptionData<?> optionData;
+ /** the current value. */
+ private Object value;
+
+ /**
+ * Creates a data entry.
+ *
+ * @param name
+ * name of the associated diagram type or element
+ * @param id
+ * identifier of the associated diagram type or element
+ * type
+ * @param thetype
+ * type of element (diagram type / model element / edit
+ * part)
+ * @param theoptionData
+ * layout option data
+ * @param thevalue
+ * the current value
+ */
+ public DataEntry(final String name, final String id,
+ final ElementType thetype,
+ final LayoutOptionData<?> theoptionData,
+ final Object thevalue) {
+ this.elementName = name;
+ this.elementId = id;
+ this.type = thetype;
+ this.optionData = theoptionData;
+ this.value = thevalue;
+ }
+
+ /**
+ * Returns the associated element name.
+ *
+ * @return the name of the associated element
+ */
+ public String getElementName() {
+ return elementName;
+ }
+
+ /**
+ * Returns the associated element identifier.
+ *
+ * @return the identifier of the associated element
+ */
+ public String getElementId() {
+ return elementId;
+ }
+
+ /**
+ * Returns the type of element (diagram type / model element / edit
+ * part).
+ *
+ * @return the element type
+ */
+ public ElementType getType() {
+ return type;
+ }
+
+ /**
+ * Returns the option data.
+ *
+ * @return the option data
+ */
+ public LayoutOptionData<?> getOptionData() {
+ return optionData;
+ }
+
+ /**
+ * Returns the value.
+ *
+ * @return the value
+ */
+ public Object getValue() {
+ return value;
+ }
+
+ /**
+ * Sets the value.
+ *
+ * @param thevalue
+ * the new value
+ */
+ public void setValue(final Object thevalue) {
+ this.value = thevalue;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(final Object object) {
+ if (object instanceof DataEntry) {
+ DataEntry other = (DataEntry) object;
+ return this.elementId.equals(other.elementId)
+ && this.optionData.equals(other.optionData);
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ return elementId.hashCode() + optionData.hashCode();
+ }
+ }
+
+ /** the "Element" column. */
+ private static final int COL_ELEMENT = 0;
+ /** the "Type" column. */
+ private static final int COL_TYPE = 1;
+ /** the "Option" column. */
+ private static final int COL_OPTION = 2;
+ /** the "Value" column. */
+ private static final int COL_VALUE = 3;
+
+ /**
+ * {@inheritDoc}
+ */
+ public Image getColumnImage(final Object element, final int columnIndex) {
+ if (element instanceof DataEntry && columnIndex == COL_VALUE) {
+ DataEntry entry = (DataEntry) element;
+ KimlUiPlugin.Images images = KimlUiPlugin.getDefault()
+ .getImages();
+ switch (entry.optionData.getType()) {
+ case STRING:
+ return images.getPropText();
+ case BOOLEAN:
+ if ((Boolean) entry.value) {
+ return images.getPropTrue();
+ } else {
+ return images.getPropFalse();
+ }
+ case REMOTE_ENUM:
+ case ENUM:
+ return images.getPropChoice();
+ case INT:
+ return images.getPropInt();
+ case FLOAT:
+ return images.getPropFloat();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getColumnText(final Object element, final int columnIndex) {
+ if (element instanceof DataEntry) {
+ DataEntry entry = (DataEntry) element;
+ switch (columnIndex) {
+ case COL_ELEMENT:
+ return entry.elementName;
+ case COL_TYPE:
+ return entry.type.getDescription();
+ case COL_OPTION:
+ return entry.optionData.getName();
+ case COL_VALUE:
+ if (entry.optionData.getType() == LayoutOptionData.Type.ENUM
+ && entry.value instanceof Integer) {
+ return entry.optionData.getEnumValue(
+ (Integer) entry.value).toString();
+ } else {
+ return entry.value.toString();
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object[] getElements(final Object inputElement) {
+ if (inputElement instanceof List<?>) {
+ @SuppressWarnings("unchecked")
+ List<DataEntry> list = new ArrayList<DataEntry>(
+ (List<DataEntry>) inputElement);
+ ListIterator<DataEntry> listIter = list.listIterator();
+ while (listIter.hasNext()) {
+ DataEntry next = listIter.next();
+ if (next.value == null) {
+ listIter.remove();
+ }
+ }
+ return list.toArray();
+ } else if (inputElement instanceof Object[]) {
+ return (Object[]) inputElement;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void inputChanged(final Viewer viewer, final Object oldInput,
+ final Object newInput) {
+ }
+
+ }
+
+}
diff --git a/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/preferences/EtriceStructurePreferencePage.java b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/preferences/EtriceStructurePreferencePage.java
new file mode 100644
index 0000000..678c9f2
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/preferences/EtriceStructurePreferencePage.java
@@ -0,0 +1,470 @@
+/*******************************************************************************
+ * 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:
+ * Jayant Gupta (initial contribution)
+ *
+ *******************************************************************************/
+package org.eclipse.etrice.ui.layout.preferences;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.etrice.ui.layout.Activator;
+import org.eclipse.etrice.ui.layout.preferences.ETricePreferenceUtil.ElementType;
+import org.eclipse.etrice.ui.layout.preferences.ETricePreferenceUtil.NewOptionDialog;
+import org.eclipse.etrice.ui.layout.preferences.ETricePreferenceUtil.OptionsTableProvider;
+import org.eclipse.graphiti.mm.pictograms.PictogramElement;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TreeNode;
+import org.eclipse.jface.viewers.TreeNodeContentProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.FillLayout;
+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.Group;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
+import org.eclipse.ui.dialogs.ListDialog;
+
+import de.cau.cs.kieler.core.util.Pair;
+import de.cau.cs.kieler.kiml.LayoutDataService;
+import de.cau.cs.kieler.kiml.LayoutOptionData;
+import de.cau.cs.kieler.kiml.ui.Messages;
+import de.cau.cs.kieler.kiml.ui.service.EclipseLayoutInfoService;
+import de.cau.cs.kieler.kiml.ui.views.LayoutViewPart;
+
+/**
+ * Preference page for eTrice Behavior preferences
+ *
+ * @author jayant
+ */
+public class EtriceStructurePreferencePage extends ETriceLayoutPreferencePage {
+
+ /**
+ * Creates the behavior layout preference page.
+ *
+ * @author jayant
+ */
+ public EtriceStructurePreferencePage() {
+ super();
+ setDescription("Preference Page for configuring layout options specific to eTrice Structure diagrams");
+ }
+
+ /** table viewer to refresh after changes to the option table data. */
+ private TableViewer optionTableViewer;
+
+ /** list of layout option entries. */
+ private List<OptionsTableProvider.DataEntry> optionEntries;
+
+ /**
+ * {@inheritDoc}
+ *
+ * @author jayant
+ */
+ @Override
+ protected Control createContents(Composite parent) {
+ Group optionsGroup = createOptionsGroup(parent);
+ optionsGroup
+ .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ return optionsGroup;
+ }
+
+ /**
+ * Creates the group that holds the diagram element options table.
+ *
+ * @param parent
+ * the parent control
+ * @return a group with the diagram element options table
+ */
+ protected Group createOptionsGroup(final Composite parent) {
+ Group elementGroup = new Group(parent, SWT.NONE);
+ elementGroup.setText(Messages.getString("kiml.ui.28")); //$NON-NLS-1$
+ IPreferenceStore preferenceStore = getPreferenceStore();
+ LayoutDataService dataService = LayoutDataService.getInstance();
+ Collection<LayoutOptionData<?>> layoutOptionData = dataService
+ .getOptionData();
+ optionEntries = new LinkedList<OptionsTableProvider.DataEntry>();
+
+ // add options for edit parts and structure domain model elements
+ Set<String> elements = EclipseLayoutInfoService.getInstance()
+ .getRegisteredElements();
+
+ for (String element : elements) {
+
+ //Finding whether diagram element is an Edit Part or Model Element
+ Class<?> elementClass = null;
+ ElementType type;
+ try {
+ elementClass = Class.forName(element);
+ try {
+ type = PictogramElement.class.isAssignableFrom(elementClass)
+ ? ElementType.EDIT_PART : ElementType.MODEL_ELEM;
+ } catch (NullPointerException e) {
+ type = ElementType.MODEL_ELEM;
+ }
+ } catch (ClassNotFoundException e) {
+ type = ElementType.MODEL_ELEM;
+ }
+
+ //Making the element name more presentable
+ int dotIndex = element.lastIndexOf('.');
+ String partName = element.substring(dotIndex + 1);
+ if (partName.endsWith("Impl")) {
+ partName = partName.substring(0,
+ partName.length() - "Impl".length());
+ }
+
+ for (LayoutOptionData<?> data : layoutOptionData) {
+ String preference = EclipseLayoutInfoService.getPreferenceName(
+ element, data.getId());
+ if (preferenceStore.contains(preference)) {
+ Object value = data.parseValue(preferenceStore
+ .getString(preference));
+ if (value != null) {
+ // If element is edit part or structure model element,
+ // then add to the option table
+ if (type == ElementType.EDIT_PART
+ || ETriceDomainModelElement
+ .isStructureModelElement(element))
+ optionEntries
+ .add(new OptionsTableProvider.DataEntry(
+ partName, element, type, data,
+ value));
+ }
+ }
+ }
+ }
+
+ // add options for diagram types(only those which are relevant to eTrice
+ // Structure Diagram)
+ for (Pair<String, String> diagramType : ETriceDomainModelElement.STRUCTURE_DIAGRAM_TYPES) {
+ for (LayoutOptionData<?> data : layoutOptionData) {
+ String preference = EclipseLayoutInfoService.getPreferenceName(
+ diagramType.getFirst(), data.getId());
+ if (preferenceStore.contains(preference)) {
+ Object value = data.parseValue(preferenceStore
+ .getString(preference));
+ if (value != null) {
+ optionEntries.add(new OptionsTableProvider.DataEntry(
+ diagramType.getSecond(),
+ diagramType.getFirst(), ElementType.DIAG_TYPE,
+ data, value));
+ }
+ }
+ }
+ }
+
+ // create the table and actions to edit layout option values
+ addOptionTable(elementGroup, optionEntries);
+
+ elementGroup.setLayout(new GridLayout(2, false));
+ return elementGroup;
+ }
+
+ /**
+ * Adds a table to display options and buttons to edit the options.
+ *
+ * @param parent
+ * the parent to which controls are added
+ * @param entries
+ * the list of table entries
+ */
+ private void addOptionTable(final Composite parent,
+ final List<OptionsTableProvider.DataEntry> entries) {
+ // construct the options table
+ final Table table = new Table(parent, SWT.BORDER);
+ final TableColumn column1 = new TableColumn(table, SWT.NONE);
+ column1.setText(Messages.getString("kiml.ui.29")); //$NON-NLS-1$
+ final TableColumn column2 = new TableColumn(table, SWT.NONE);
+ column2.setText(Messages.getString("kiml.ui.9")); //$NON-NLS-1$
+ final TableColumn column3 = new TableColumn(table, SWT.NONE);
+ column3.setText(Messages.getString("kiml.ui.19")); //$NON-NLS-1$
+ final TableColumn column4 = new TableColumn(table, SWT.NONE);
+ column4.setText(Messages.getString("kiml.ui.20")); //$NON-NLS-1$
+ table.setHeaderVisible(true);
+ final TableViewer tableViewer = new TableViewer(table);
+ OptionsTableProvider optionsTableProvider = new OptionsTableProvider();
+ tableViewer.setContentProvider(optionsTableProvider);
+ tableViewer.setLabelProvider(optionsTableProvider);
+ tableViewer.setInput(entries);
+ optionTableViewer = tableViewer;
+
+ column1.pack();
+ column2.pack();
+ column3.pack();
+ column4.pack();
+ GridData tableLayoutData = new GridData(SWT.FILL, SWT.FILL, true, true,
+ 1, 1);
+ table.setLayoutData(tableLayoutData);
+ table.pack();
+ tableLayoutData.heightHint = ETricePreferenceUtil.OPTIONS_TABLE_HEIGHT;
+
+ // add button to add new options
+ Composite composite = new Composite(parent, SWT.NONE);
+ final Button newButton = new Button(composite, SWT.PUSH | SWT.CENTER);
+ newButton.setText(Messages.getString("kiml.ui.41")); //$NON-NLS-1$
+
+ // add button to edit the options
+ final Button editButton = new Button(composite, SWT.PUSH | SWT.CENTER);
+ editButton.setText(Messages.getString("kiml.ui.21")); //$NON-NLS-1$
+ editButton.setEnabled(false);
+ editButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(final SelectionEvent event) {
+ OptionsTableProvider.DataEntry entry = ETricePreferenceUtil
+ .getEntry(entries, table.getSelectionIndex());
+ if (entry != null) {
+ ETricePreferenceUtil.showEditDialog(parent.getShell(),
+ entry);
+ tableViewer.refresh();
+ }
+ }
+ });
+
+ // add button to remove an option
+ final Button removeButton = new Button(composite, SWT.PUSH | SWT.CENTER);
+ removeButton.setText(Messages.getString("kiml.ui.22")); //$NON-NLS-1$
+ removeButton.setEnabled(false);
+ removeButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(final SelectionEvent event) {
+ OptionsTableProvider.DataEntry entry = ETricePreferenceUtil
+ .getEntry(entries, table.getSelectionIndex());
+ if (entry != null) {
+ entry.setValue(null);
+ tableViewer.refresh();
+ int count = 0;
+ for (OptionsTableProvider.DataEntry e : entries) {
+ if (e.getValue() != null) {
+ count++;
+ }
+ }
+ if (count == 0) {
+ editButton.setEnabled(false);
+ removeButton.setEnabled(false);
+ }
+ }
+ }
+ });
+
+ // react on selection changes of the options table
+ table.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(final SelectionEvent event) {
+ if (!entries.isEmpty() && event.item != null) {
+ editButton.setEnabled(true);
+ removeButton.setEnabled(true);
+ } else {
+ editButton.setEnabled(false);
+ removeButton.setEnabled(false);
+ }
+ }
+ });
+ newButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(final SelectionEvent event) {
+ int newIndex = showNewDialog(parent.getShell(), entries);
+ if (newIndex >= 0) {
+ tableViewer.refresh();
+ tableViewer.setSelection(new StructuredSelection(entries
+ .get(newIndex)));
+ editButton.setEnabled(true);
+ removeButton.setEnabled(true);
+ column1.pack();
+ column2.pack();
+ column3.pack();
+ column4.pack();
+ }
+ }
+ });
+
+ composite.setLayout(new FillLayout(SWT.VERTICAL));
+ GridData compositeLayoutData = new GridData(SWT.LEFT, SWT.TOP, false,
+ false, 1, 1);
+ composite.setLayoutData(compositeLayoutData);
+ }
+
+ /**
+ * Shows an input dialog to add a new layout option to the list.
+ *
+ * @param shell
+ * the current shell
+ * @param entries
+ * the list of table entries
+ * @return the table index to put focus on, or -1 if the focus should not be
+ * changed
+ */
+ private int showNewDialog(final Shell shell,
+ final List<OptionsTableProvider.DataEntry> entries) {
+ NewOptionDialog dialog = new NewOptionDialog(shell) {
+ // Overriding the function for Behavior diagrams specific
+ // implementation
+
+ /**
+ * @author jayant
+ */
+ @Override
+ protected String showBrowseModelElementDialog() {
+ ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(
+ this.getShell(), new LabelProvider(),
+ new TreeNodeContentProvider());
+ dialog.setTitle("Select Structure Model Element");
+
+ TreeNode[] input = ETriceDomainModelElement.STRUCTURE_MODEL
+ .getChildren();
+ dialog.setInput(input);
+
+ if (dialog.open() == ElementTreeSelectionDialog.OK) {
+ Object[] result = dialog.getResult();
+ if (result != null && result.length > 0) {
+ return ((ETriceDomainModelElement) result[0]).getId();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @author jayant
+ */
+ @Override
+ protected String showBrowseDiagtDialog() {
+ ListDialog dialog = new ListDialog(this.getShell());
+ dialog.setTitle(Messages.getString("kiml.ui.57")); //$NON-NLS-1$
+ dialog.setContentProvider(ArrayContentProvider.getInstance());
+ dialog.setLabelProvider(new LabelProvider());
+
+ SelectionData[] input = new SelectionData[ETriceDomainModelElement.STRUCTURE_DIAGRAM_TYPES
+ .size()];
+ int i = 0;
+ for (Pair<String, String> type : ETriceDomainModelElement.STRUCTURE_DIAGRAM_TYPES) {
+ SelectionData seld = new SelectionData(type);
+ input[i++] = seld;
+ }
+ Arrays.sort(input);
+ dialog.setInput(input);
+ if (dialog.open() == ListDialog.OK) {
+ Object[] result = dialog.getResult();
+ if (result != null && result.length > 0) {
+ return ((SelectionData) result[0]).getId();
+ }
+ }
+ return null;
+ }
+ };
+ if (dialog.open() == NewOptionDialog.OK) {
+ OptionsTableProvider.DataEntry newEntry = dialog.createDataEntry();
+ if (newEntry == null) {
+ MessageDialog.openError(shell,
+ Messages.getString("kiml.ui.51"),
+ Messages.getString("kiml.ui.52"));
+ } else {
+ // look for an existing entry with same identifiers
+ int oldIndex = 0;
+ OptionsTableProvider.DataEntry oldEntry = null;
+ for (OptionsTableProvider.DataEntry e : entries) {
+ if (e.getValue() != null) {
+ if (e.equals(newEntry)) {
+ oldEntry = e;
+ break;
+ }
+ oldIndex++;
+ }
+ }
+ if (oldEntry != null) {
+ return oldIndex;
+ } else {
+ entries.add(newEntry);
+ return entries.size() - 1;
+ }
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @author jayant
+ */
+ public void init(final IWorkbench workbench) {
+ setPreferenceStore(Activator.getDefault().getSharedPreferenceStore());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @author jayant
+ */
+ @Override
+ protected void performDefaults() {
+ super.performDefaults();
+
+ // clear the layout options table
+ for (OptionsTableProvider.DataEntry entry : optionEntries) {
+ entry.setValue(null);
+ }
+ optionTableViewer.refresh();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @author jayant
+ */
+ @Override
+ public boolean performOk() {
+ EclipseLayoutInfoService infoService = EclipseLayoutInfoService
+ .getInstance();
+ IPreferenceStore preferenceStore = getPreferenceStore();
+
+ // store data for the diagram element and diagram type options
+ for (OptionsTableProvider.DataEntry entry : optionEntries) {
+ Object oldValue = infoService.getOptionValue(entry.getElementId(),
+ entry.getOptionData().getId());
+ Object newValue = entry.getValue();
+ if (oldValue == null && newValue != null
+ || !oldValue.equals(newValue)) {
+ String preference = EclipseLayoutInfoService.getPreferenceName(
+ entry.getElementId(), entry.getOptionData().getId());
+ if (newValue == null) {
+ infoService.removeOptionValue(entry.getElementId(), entry
+ .getOptionData().getId());
+ preferenceStore.setToDefault(preference);
+ infoService.getRegisteredElements().remove(
+ entry.getElementId());
+ } else {
+ infoService.addOptionValue(entry.getElementId(), entry
+ .getOptionData().getId(), newValue);
+ preferenceStore.setValue(preference, newValue.toString());
+ if (entry.getType() != ElementType.DIAG_TYPE) {
+ infoService.getRegisteredElements().add(
+ entry.getElementId());
+ }
+ }
+ }
+ }
+
+ LayoutViewPart layoutView = LayoutViewPart.findView();
+ if (layoutView != null) {
+ layoutView.refresh();
+ }
+ return true;
+ }
+
+}
diff --git a/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/preferences/PreferenceInitializer.java b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/preferences/PreferenceInitializer.java
new file mode 100644
index 0000000..a5e95ed
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/preferences/PreferenceInitializer.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * 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:
+ * Jayant Gupta (initial contribution)
+ *
+ *******************************************************************************/
+package org.eclipse.etrice.ui.layout.preferences;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+
+/**
+ * Class used to initialize default preference values.
+ *
+ */
+public class PreferenceInitializer extends AbstractPreferenceInitializer {
+
+ /**
+ * {@inheritDoc}
+ *
+ * @author jayant
+ */
+ public void initializeDefaultPreferences() {
+ // No Default initializations need to be made in the shared Preference
+ // Store (already made by kiml.ui.preferences.PreferenceInitializer)
+ }
+
+}