diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/.ratings b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/.ratings index 1261d17460077cfb5a3faca399aa9f9321a5e0ac..ef8aadc0677a7162ed8e0097cccf227e2fbd2fc4 100644 --- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/.ratings +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/.ratings @@ -1,4 +1,4 @@ -ContextMenuUtil.java 36184cc3f383d294463336a8318c61e98fd7d2d4 YELLOW +ContextMenuUtil.java 405387151d45b09dffb3b6ba44f980313c8edcaf GREEN EObjectDiagramController.java 9af59e8e586c8251d174108a2ce2fcdee5e75782 YELLOW EObjectModelChangeProvider.java f4b60cebb088a5c81ca92a41614e1a5d40030502 YELLOW EObjectRectangularResizableContentControllerBase.java f4a967591a60fadb20550ec3eaabccf240c9ec0d YELLOW diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/ContextMenuUtil.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/ContextMenuUtil.java index 36184cc3f383d294463336a8318c61e98fd7d2d4..405387151d45b09dffb3b6ba44f980313c8edcaf 100644 --- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/ContextMenuUtil.java +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/ContextMenuUtil.java @@ -39,7 +39,7 @@ import javafx.scene.control.MenuItem; * * @author hoelzl */ -final class ContextMenuUtil { +public final class ContextMenuUtil { /** Creates the menu populated with composable prototypes. */ public static List<MenuItem> createPrototypeMenu(EObject target, IElementCompositionContext context) { diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/.ratings b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/.ratings index 1d719596aadb4771c489581b90bd5a6dcde4f410..4850e6d5cc854062f8760986309dc09fbbc41974 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/.ratings +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/.ratings @@ -1,7 +1,7 @@ -DynamicTreeContentProviderBase.java dff437afeaf7486af05460fa54eca4fa61d7eae6 GREEN -DynamicTreeItem.java afc105cf5acf3d2506d89e0892555100c234ce5b GREEN -DynamicTreeTableUIProviderBase.java fd9fce19a65eb1006ceacb0d869bbe90a8c578b3 GREEN -DynamicTreeTableViewer.java 4f278387dd90542adc07bf0da12e92d4eaad79c4 GREEN +DynamicTreeContentProviderBase.java e801da995a1b6e5a1b757247c1638bafb6073e6d GREEN +DynamicTreeItem.java 75dc5534b119ffdb3c10a65810c2a0f330b7955e GREEN +DynamicTreeTableUIProviderBase.java 7bfc1395283d3dc10026aff5e2e65df88d25f3a7 GREEN +DynamicTreeTableViewer.java 43757359b3071192ae79710bcbc0e9577bb6f62d GREEN DynamicTreeUIProviderBase.java 56fe4df4577b35f1e5e6e4c4be189b706c852d52 GREEN DynamicTreeViewer.java da5e24ae57777a482d8e12c8262513d8143bfa93 GREEN DynamicTreeViewerBase.java 47124c847de322a0ae26eb7a114f85ce4bd02d7e GREEN diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeContentProviderBase.java b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeContentProviderBase.java index dff437afeaf7486af05460fa54eca4fa61d7eae6..e801da995a1b6e5a1b757247c1638bafb6073e6d 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeContentProviderBase.java +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeContentProviderBase.java @@ -30,13 +30,43 @@ public abstract class DynamicTreeContentProviderBase<T> { /** Returns the children of the given parent in the tree. */ protected abstract Collection<? extends T> getChildren(T parent); - /** Returns the filer predicate. */ - protected Predicate<Object> getFilterPredicate() { + /** The current filter expression. */ + private String filterExpression = null; + + /** Sets the filter expression. */ + public void setFilterExpression(String filterExpression) { + this.filterExpression = filterExpression; + } + + /** + * Returns the filter expression. Sub-classes may override or simply use + * {@link #setFilterExpression(String)} + */ + protected String getFilterExpression() { + return filterExpression; + } + + /** + * Returns the filter predicate for the given filter value. The default checks if the object's + * toString() contains the filter value. Sub-classes may override or implement + * {@link #filter(Object, String)}. + */ + protected Predicate<T> getFilterPredicate(String filterValue) { + if(filterValue != null && !"".equals(filterValue.trim())) { + return (o) -> { + return filter(o, filterValue); + }; + } return (o) -> true; } + /** Sub-classes may override to implement simple filter behavior. */ + protected boolean filter(T element, String filterValue) { + return element != null && element.toString().contains(filterValue); + } + /** Returns the sorter comparator. */ - protected Comparator<Object> getSortingComparator() { + protected Comparator<T> getSortingComparator() { return (o1, o2) -> 0; } @@ -46,7 +76,7 @@ public abstract class DynamicTreeContentProviderBase<T> { if(l == null) { return emptyList(); } - return l.stream().filter(getFilterPredicate()).sorted(getSortingComparator()) - .collect(toList()); + return l.stream().filter(getFilterPredicate(getFilterExpression())) + .sorted(getSortingComparator()).collect(toList()); } } diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeItem.java b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeItem.java index afc105cf5acf3d2506d89e0892555100c234ce5b..75dc5534b119ffdb3c10a65810c2a0f330b7955e 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeItem.java +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeItem.java @@ -21,8 +21,8 @@ import java.util.HashMap; import javafx.scene.control.TreeItem; /** - * {@link TreeItem} with support for dynamic children using the {@link DynamicTreeItem#update()} - * method. + * {@link TreeItem} with support for dynamic children using the + * {@link DynamicTreeItem#update()} method. */ public class DynamicTreeItem<T> extends TreeItem<T> { /** The viewer. */ @@ -45,7 +45,8 @@ public class DynamicTreeItem<T> extends TreeItem<T> { } // get list of children and create tree items getChildren().clear(); - for(T element : viewer.getContentProvider().getFilteredSortedChildren(getValue())) { + DynamicTreeContentProviderBase<T> cp = viewer.getContentProvider(); + for(T element : cp.getFilteredSortedChildren(getValue())) { DynamicTreeItem<T> dti; if(expanded.containsKey(element)) { dti = (DynamicTreeItem<T>)expanded.get(element); diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableUIProviderBase.java b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableUIProviderBase.java index fd9fce19a65eb1006ceacb0d869bbe90a8c578b3..7bfc1395283d3dc10026aff5e2e65df88d25f3a7 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableUIProviderBase.java +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableUIProviderBase.java @@ -13,14 +13,19 @@ *******************************************************************************/ package org.fortiss.tooling.common.ui.javafx.control.treetableview; +import static javafx.scene.control.cell.TextFieldTreeTableCell.forTreeTableColumn; + import javafx.scene.Node; import javafx.scene.control.ContextMenu; +import javafx.scene.control.TreeTableCell; +import javafx.scene.control.TreeTableColumn; +import javafx.util.Callback; /** * This UI provider is responsible to return the label, the icon, and the context menu for each cell * in the {@link DynamicTreeTableViewer} based on the data object and the column. */ -public abstract class DynamicTreeTableUIProviderBase { +public abstract class DynamicTreeTableUIProviderBase<T> { /** * @param element * the element to be displayed in the current row @@ -28,7 +33,7 @@ public abstract class DynamicTreeTableUIProviderBase { * the current column * @return the label to be displayed in the given column */ - public String getLabel(Object element, int column) { + public String getLabel(T element, int column) { return ""; } @@ -39,7 +44,7 @@ public abstract class DynamicTreeTableUIProviderBase { * the current column * @return the node to be displayed as the icon in the given column */ - public Node getIconNode(Object element, int column) { + public Node getIconNode(T element, int column) { return null; } @@ -50,7 +55,94 @@ public abstract class DynamicTreeTableUIProviderBase { * the current column * @return the context menu in the given column */ - public ContextMenu createContextMenu(Object element, int column) { + public ContextMenu createContextMenu(T element, int column) { return null; } + + /** + * Returns whether the given column is editable. + * + * @param column + * the column index + * @return whether the column is editable + */ + public boolean isEditable(int column) { + return false; + } + + /** + * Updates the value after the given column was edited for the given element. + * + * @param element + * the element to be edited in the current row + * @param column + * the currently edited column + * @param value + * the edited value + */ + public void updateValue(T element, int column, String value) { + // ignored, since not editable + } + + /** + * Notifies the provider about the selection of the given new value (and the deselection of the + * given old value. + * + * @param oldValue + * unselected value + * @param newValue + * the selected value + */ + public void select(T oldValue, T newValue) { + // ignored + } + + /** Applies the editing support to the given column. */ + /* package */ final void applyToColumn(int i, TreeTableColumn<T, String> column) { + if(!isEditable(i)) { + column.setCellFactory(createReadOnlyCellFactory(i)); + column.setEditable(false); + column.setOnEditCommit(null); + return; + } + column.setCellFactory(createEditableCellFactory()); + column.setEditable(true); + column.setOnEditCommit(event -> { + T element = event.getRowValue().getValue(); + int colIndex = event.getTreeTablePosition().getColumn(); + String value = event.getNewValue(); + updateValue(element, colIndex, value); + column.getTreeTableView().refresh(); + }); + } + + /** Creates a cell factory for editable cells. */ + private Callback<TreeTableColumn<T, String>, TreeTableCell<T, String>> + createEditableCellFactory() { + return forTreeTableColumn(); + } + + /** Creates a cell factory for read-only cells. */ + private Callback<TreeTableColumn<T, String>, TreeTableCell<T, String>> + createReadOnlyCellFactory(int colIndex) { + return param -> { + TreeTableCell<T, String> cell = new TreeTableCell<T, String>() { + @Override + protected void updateItem(String item, boolean empty) { + super.updateItem(item, empty); + ContextMenu menu = null; + Node icon = null; + if(!empty && item != null) { + T data = this.getTreeTableRow().getItem(); + menu = createContextMenu(data, colIndex); + icon = getIconNode(data, colIndex); + } + this.setContextMenu(menu); + this.setGraphic(icon); + } + }; + cell.textProperty().bind(cell.itemProperty()); + return cell; + }; + } } diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableViewer.java b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableViewer.java index 4f278387dd90542adc07bf0da12e92d4eaad79c4..43757359b3071192ae79710bcbc0e9577bb6f62d 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableViewer.java +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableViewer.java @@ -15,17 +15,12 @@ *******************************************************************************/ package org.fortiss.tooling.common.ui.javafx.control.treetableview; -import static javafx.scene.control.cell.TextFieldTreeTableCell.forTreeTableColumn; - import javafx.beans.property.SimpleObjectProperty; -import javafx.scene.Node; -import javafx.scene.control.ContextMenu; import javafx.scene.control.SelectionMode; import javafx.scene.control.TreeItem; -import javafx.scene.control.TreeTableCell; import javafx.scene.control.TreeTableColumn; import javafx.scene.control.TreeTableView; -import javafx.util.Callback; +import javafx.scene.control.TreeTableView.TreeTableViewSelectionModel; /** * A JavaFX {@link TreeTableView} based on an {@link DynamicTreeContentProviderBase} and @@ -42,12 +37,12 @@ public final class DynamicTreeTableViewer<T> extends DynamicTreeViewerBase<T> { /** The {@link TreeTableView} control to be managed. */ private final TreeTableView<T> view; /** The UI provider of this tree-table. */ - private final DynamicTreeTableUIProviderBase uiProvider; + private final DynamicTreeTableUIProviderBase<T> uiProvider; /** Constructor. */ public DynamicTreeTableViewer(TreeTableView<T> view, T root, boolean showRoot, int revealLevel, DynamicTreeContentProviderBase<T> contentProvider, - DynamicTreeTableUIProviderBase uiProvider) { + DynamicTreeTableUIProviderBase<T> uiProvider) { super(contentProvider); this.uiProvider = uiProvider; // construct view @@ -56,7 +51,14 @@ public final class DynamicTreeTableViewer<T> extends DynamicTreeViewerBase<T> { view.setRoot(rootItem); view.setShowRoot(showRoot); view.setEditable(true); - view.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE); + TreeTableViewSelectionModel<T> selectionModel = view.getSelectionModel(); + selectionModel.setSelectionMode(SelectionMode.MULTIPLE); + selectionModel.selectedItemProperty().addListener((obs, oVal, nVal) -> { + T ov = (oVal != null) ? oVal.getValue() : null; + T nv = (nVal != null) ? nVal.getValue() : null; + uiProvider.select(ov, nv); + }); + rootItem.update(); // expand to reveal (+1 if root node is not shown expandItem(rootItem, showRoot ? revealLevel : revealLevel + 1); @@ -65,7 +67,7 @@ public final class DynamicTreeTableViewer<T> extends DynamicTreeViewerBase<T> { /** Constructor. */ public DynamicTreeTableViewer(T root, boolean showRoot, int revealLevel, DynamicTreeContentProviderBase<T> contentProvider, - DynamicTreeTableUIProviderBase uiProvider) { + DynamicTreeTableUIProviderBase<T> uiProvider) { this(new TreeTableView<T>(), root, showRoot, revealLevel, contentProvider, uiProvider); } @@ -74,6 +76,7 @@ public final class DynamicTreeTableViewer<T> extends DynamicTreeViewerBase<T> { // wild cast works: see constructor DynamicTreeItem<T> rootItem = (DynamicTreeItem<T>)view.getRoot(); rootItem.update(); + view.refresh(); } /** Expands items up to the given level. */ @@ -92,51 +95,33 @@ public final class DynamicTreeTableViewer<T> extends DynamicTreeViewerBase<T> { * Adds a column to the table part of the view. The labels, context menus and icons are shown as * defined in the {@link DynamicTreeTableUIProviderBase}. */ - public TreeTableColumn<T, String> addColumn(String headerLabel, int prefWidth, - boolean readOnly) { + public TreeTableColumn<T, String> addColumn(String headerLabel, int prefWidth) { int num = view.getColumns().size(); TreeTableColumn<T, String> column = new TreeTableColumn<>(headerLabel); column.setPrefWidth(prefWidth); column.setCellValueFactory(param -> { - Object data = param.getValue().getValue(); + T data = param.getValue().getValue(); return new SimpleObjectProperty<String>(uiProvider.getLabel(data, num)); }); - Callback<TreeTableColumn<T, String>, TreeTableCell<T, String>> cellFactory; - if(readOnly) { - // Read only cell with the icon and context menu as specified in the UI provider - cellFactory = param -> { - TreeTableCell<T, String> cell = new TreeTableCell<T, String>() { - @Override - protected void updateItem(String item, boolean empty) { - super.updateItem(item, empty); - ContextMenu menu = null; - Node icon = null; - int index = view.getColumns().size() - 1; - if(!empty && item != null) { - T data = this.getTreeTableRow().getItem(); - menu = uiProvider.createContextMenu(data, index); - icon = uiProvider.getIconNode(data, index); - } - this.setContextMenu(menu); - this.setGraphic(icon); - } - }; - cell.textProperty().bind(cell.itemProperty()); - return cell; - }; - } else { - // Editable text field - cellFactory = forTreeTableColumn(); - } - column.setCellFactory(cellFactory); - + uiProvider.applyToColumn(num, column); view.getColumns().add(column); - return column; } + /** + * Adds a column to the table part of the view. The labels, context menus and icons are shown as + * defined in the {@link DynamicTreeTableUIProviderBase}. + * + * @deprecated use {@link DynamicTreeTableUIProviderBase} + */ + @Deprecated + public TreeTableColumn<T, String> addColumn(String headerLabel, int prefWidth, + @SuppressWarnings("unused") boolean readOnly) { + return addColumn(headerLabel, prefWidth); + } + /** Returns the underlying {@link TreeTableView}. */ public TreeTableView<T> getControl() { return view; diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/util/.ratings b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/util/.ratings index 1922ed59e6f776adeb20031a9a89f3ef591ddfc5..d8aad1a695ee70a33a9224b9196e6a220822fcaf 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/util/.ratings +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/util/.ratings @@ -1,2 +1,2 @@ -GraphicUtils.java 4d471a310a52bda1c090f956dcdbe90775b12cb8 GREEN +GraphicUtils.java 46cfc991cd3ef787fec3f95751bc680d68479e26 GREEN JavaFXUtils.java db3cf28289109ffec64c8f96c7b2de779a977b3b GREEN diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/util/GraphicUtils.java b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/util/GraphicUtils.java index 4d471a310a52bda1c090f956dcdbe90775b12cb8..46cfc991cd3ef787fec3f95751bc680d68479e26 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/util/GraphicUtils.java +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/util/GraphicUtils.java @@ -28,21 +28,28 @@ import javafx.scene.paint.Color; * @author munaro */ public class GraphicUtils { - /** The image cache of loaded images. */ private static final HashMap<String, Image> imageCache = new HashMap<>(); /** Returns the plugin-local URI string for the given resource. */ public static String getURIString(String pluginId, String localPath) { + if(!pluginId.endsWith("/") && !localPath.startsWith("/")) { + localPath = "/" + localPath; + } return "platform:/plugin/" + pluginId + localPath; } - /** Returns the Java FX Image load from the local path. */ + /** Returns the Java FX Image loaded from the plugin's local path. */ public static Image getFXImage(String pluginId, String localPath) { String uri = getURIString(pluginId, localPath); if(uri == null) { return null; } + return getFXImageFromURI(uri); + } + + /** Returns the Java FX Image loaded from the given URI. */ + public static Image getFXImageFromURI(String uri) { Image cacheImage = imageCache.get(uri); if(cacheImage == null) { InputStream in = null; diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/.ratings b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/.ratings index 62c4ab516cd12fe289a932734684368e00f044be..e039d39f894c2359d5eec38e68a158d58f1e65fa 100644 --- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/.ratings +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/.ratings @@ -3,8 +3,8 @@ IContextMenuContributor.java 0f09c76662c154cf52ddab61b417e82a42854162 GREEN IContextMenuMultiSelectionContributor.java 125b31dd38009bc2095b7e6bc860e946e39f58c4 GREEN IEditPartFactory.java 5729715847f553d95a5bad4a9211c7e6f458badd GREEN IModelEditor.java 962d7f7758abc88bbc6064c8b4eb32da00abf8e8 GREEN -IModelEditorBinding.java 844865d93252b6c4a648c23ff28bb28fd42c17aa YELLOW -IModelElementHandler.java 21b4a96251e0267f156b4b8f2b95a97f6e81e646 GREEN +IModelEditorBinding.java 844865d93252b6c4a648c23ff28bb28fd42c17aa GREEN +IModelElementHandler.java 86a8ec88b9679bbe7f53cfa8d1592bd862873f80 GREEN ITutorialStepUI.java b8aee2b95857484ab6ad9ecd55b5de9f0ea158e5 GREEN ITutorialUIProvider.java aa0ff5db4d7ba0953e34edeb99f3e8279567e18f GREEN ITutorialUIWhitelistProvider.java d703c1531c6ae7677c2d94cbc95d498dfa4a7e9b GREEN diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/IModelElementHandler.java b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/IModelElementHandler.java index 21b4a96251e0267f156b4b8f2b95a97f6e81e646..86a8ec88b9679bbe7f53cfa8d1592bd862873f80 100644 --- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/IModelElementHandler.java +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/IModelElementHandler.java @@ -25,6 +25,8 @@ import org.fortiss.tooling.kernel.ui.extension.base.ModelElementHandlerBase; import org.fortiss.tooling.kernel.ui.extension.base.NamedCommentedModelElementHandlerBase; import org.fortiss.tooling.kernel.ui.service.IModelElementHandlerService; +import javafx.scene.Node; + /** * A model element handler provides information about a specific type of model * elements like name, description, icon and certain kinds of sub-elements. @@ -49,6 +51,9 @@ public interface IModelElementHandler<T extends EObject> extends IEObjectAware<T /** Returns image descriptor to be used as icon image. */ ImageDescriptor getIconImageDescriptor(T element); + /** Returns the JavaFX icon of the model element. */ + Node getFXIcon(T element); + /** * Returns all children acting as nodes, which are usually displayed as edit * parts by graphical editors and entries in the navigator tree. diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/.ratings b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/.ratings index 3747d405583494626be4fdece7f4d8e8214f2f49..b57e572ddef97543ad02e1f91fca7eee0f6531c2 100644 --- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/.ratings +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/.ratings @@ -4,11 +4,11 @@ EObjectActionBase.java 4ef9f8be59e64d4838acc9e268d418ba5d94fa1a GREEN EReferenceListPropertySectionBase.java 7390dd7bfdc979e8ff0c5c30c67ab7b6c9d70c92 GREEN EReferencePropertySectionBase.java 0548da6778516003257f59d0b4c2b60d458be3b6 GREEN EditorBase.java 9c09fff92945256bb8680992ae7bb2c78f47b150 GREEN -FXEditorBase.java 2e520be0bbae7d0aebdff70218a124dbe0896ce2 GREEN +FXEditorBase.java 545085c3270f09d69b609f328792e904ebda23ff GREEN IListPropertySection.java 8bb00fe7959583e794ff9437b7a77404c9a9e70f GREEN -LWFXEFEditorBase.java 72a0735d0a516e53f34e485039471512c8ac6577 YELLOW -ModelEditorBindingBase.java b9b1a1c5a48a6e677d1f57ad55a6126d9703c4b5 YELLOW -ModelElementHandlerBase.java 384727748f125c9d43f19d9c0eba4ba1be5a7a26 GREEN +LWFXEFEditorBase.java f6b160b700a0287021402b5702beb2bfdce3dc2e GREEN +ModelEditorBindingBase.java b9b1a1c5a48a6e677d1f57ad55a6126d9703c4b5 GREEN +ModelElementHandlerBase.java d08583ffdf78938a14caeb46124eda4ce5cac3e4 GREEN MultiEObjectActionBase.java 9e237d8ea640c4194e4877af4a9cfce88698e543 GREEN NamedCommentedModelElementHandlerBase.java 681b98b50b362f01abb7a36f108f4f11b9e51829 GREEN PropertySectionBase.java 20fb1daea544123ea941743aafeb9ac59daf5356 GREEN diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/FXEditorBase.java b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/FXEditorBase.java index 2e520be0bbae7d0aebdff70218a124dbe0896ce2..545085c3270f09d69b609f328792e904ebda23ff 100644 --- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/FXEditorBase.java +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/FXEditorBase.java @@ -15,7 +15,15 @@ +--------------------------------------------------------------------------*/ package org.fortiss.tooling.kernel.ui.extension.base; +import java.util.ArrayList; +import java.util.List; + import org.eclipse.emf.ecore.EObject; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; @@ -28,15 +36,50 @@ import javafx.scene.Scene; * * @author hoelzlf */ -public abstract class FXEditorBase<T extends EObject> extends EditorBase<T> { +public abstract class FXEditorBase<T extends EObject> extends EditorBase<T> + implements ISelectionProvider { + /** The list of {@link ISelectionChangedListener}s. */ + private final List<ISelectionChangedListener> selectionListeners = new ArrayList<>(); + /** {@inheritDoc} */ @Override public final void createPartControl(Composite parent) { FXCanvas canvas = new FXCanvas(parent, SWT.NONE); Scene scene = new Scene(createSceneRoot()); canvas.setScene(scene); + + getSite().setSelectionProvider(this); } /** Creates the root node of the scene. */ protected abstract Parent createSceneRoot(); + + /** {@inheritDoc} */ + @Override + public final void addSelectionChangedListener(ISelectionChangedListener listener) { + if(!selectionListeners.contains(listener)) { + selectionListeners.add(listener); + } + } + + /** {@inheritDoc} */ + @Override + public final void removeSelectionChangedListener(ISelectionChangedListener listener) { + selectionListeners.remove(listener); + } + + /** {@inheritDoc} */ + @Override + public final void setSelection(ISelection selection) { + SelectionChangedEvent evt = new SelectionChangedEvent(this, selection); + for(ISelectionChangedListener scl : selectionListeners) { + scl.selectionChanged(evt); + } + } + + /** {@inheritDoc} */ + @Override + public ISelection getSelection() { + return StructuredSelection.EMPTY; + } } diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/LWFXEFEditorBase.java b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/LWFXEFEditorBase.java index 72a0735d0a516e53f34e485039471512c8ac6577..f6b160b700a0287021402b5702beb2bfdce3dc2e 100644 --- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/LWFXEFEditorBase.java +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/LWFXEFEditorBase.java @@ -23,10 +23,7 @@ import java.util.Objects; import org.eclipse.emf.ecore.EObject; import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.ui.IEditorPart; import org.fortiss.tooling.common.ui.javafx.lwfxef.DiagramViewer; @@ -51,12 +48,9 @@ import javafx.scene.Parent; * @author hoelzl * @author diewald */ -public abstract class LWFXEFEditorBase<T extends EObject> extends FXEditorBase<T> - implements ISelectionProvider { +public abstract class LWFXEFEditorBase<T extends EObject> extends FXEditorBase<T> { /** The diagram viewer. */ protected DiagramViewer viewer; - /** The list of {@link ISelectionChangedListener}s. */ - private final List<ISelectionChangedListener> selectionListeners = new ArrayList<>(); /** References the delegating {@link IModelFactory} of this JavaFX {@link IEditorPart}. */ private IModelFactory delegatingModelFactory; @@ -75,7 +69,6 @@ public abstract class LWFXEFEditorBase<T extends EObject> extends FXEditorBase<T viewer = new DiagramViewer(delegatingModelFactory, delegatingVisualFactory, delegatingControllerFactory, cb -> modelSelected(), chg -> applyModelChange(chg)); customizeViewer(); - getSite().setSelectionProvider(this); return viewer.getVisualNode(); } @@ -117,29 +110,6 @@ public abstract class LWFXEFEditorBase<T extends EObject> extends FXEditorBase<T ICommandStackService.getInstance().runAsCommand(editedObject, () -> chg.applyChange()); } - /** {@inheritDoc} */ - @Override - public void addSelectionChangedListener(ISelectionChangedListener listener) { - if(!selectionListeners.contains(listener)) { - selectionListeners.add(listener); - } - } - - /** {@inheritDoc} */ - @Override - public void removeSelectionChangedListener(ISelectionChangedListener listener) { - selectionListeners.remove(listener); - } - - /** {@inheritDoc} */ - @Override - public void setSelection(ISelection selection) { - SelectionChangedEvent evt = new SelectionChangedEvent(this, selection); - for(ISelectionChangedListener scl : selectionListeners) { - scl.selectionChanged(evt); - } - } - /** {@inheritDoc} */ @Override public ISelection getSelection() { diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/ModelElementHandlerBase.java b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/ModelElementHandlerBase.java index 384727748f125c9d43f19d9c0eba4ba1be5a7a26..d08583ffdf78938a14caeb46124eda4ce5cac3e4 100644 --- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/ModelElementHandlerBase.java +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/ModelElementHandlerBase.java @@ -16,6 +16,7 @@ package org.fortiss.tooling.kernel.ui.extension.base; import static java.util.Collections.emptyList; +import static org.fortiss.tooling.common.ui.javafx.util.GraphicUtils.getFXImageFromURI; import java.util.HashMap; import java.util.List; @@ -28,6 +29,9 @@ import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.fortiss.tooling.kernel.ui.extension.IModelElementHandler; +import javafx.scene.Node; +import javafx.scene.image.ImageView; + /** * Base implementation for {@link IModelElementHandler}s. * @@ -40,7 +44,6 @@ import org.fortiss.tooling.kernel.ui.extension.IModelElementHandler; */ public abstract class ModelElementHandlerBase<T extends EObject> implements IModelElementHandler<T> { - /** Stores the icon image. */ private Map<ImageDescriptor, Image> iconImages = new HashMap<ImageDescriptor, Image>(); @@ -76,6 +79,28 @@ public abstract class ModelElementHandlerBase<T extends EObject> return iconImage; } + /** + * Returns the URL to the JavaFX icon image. + * + * @param element + * the model element + * @return the URL of the icon + */ + protected String getFXIconURL(T element) { + return "platform:/plugin/org.fortiss.tooling.kernel.ui/icons/fix.png"; + } + + /** {@inheritDoc} */ + @Override + public Node getFXIcon(T element) { + String uri = getFXIconURL(element); + if(uri == null) { + return null; + } + javafx.scene.image.Image img = getFXImageFromURI(uri); + return new ImageView(img); + } + /** The default implementation forwards the request by ignoring the model element. */ @Override public ImageDescriptor getIconImageDescriptor(T element) { diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/.ratings b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/.ratings index 5d72fbf78d3b4ebb888b9c985348f093a1e4bc05..1839610604b2b2454a1733315ab3e0df276d8df4 100644 --- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/.ratings +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/.ratings @@ -1,4 +1,4 @@ -DelegatingControllerFactory.java be19395684645d79d892e5caed079d4b7f5cb5b0 YELLOW +DelegatingControllerFactory.java 50b2a5057794d6df22649e267d282ca3aa16797c GREEN DelegatingFactoryBase.java f421742267610f41bb6196346026d2f239d90ed0 GREEN -DelegatingModelFactory.java f94ca989a5b97ad3f073040bb46b9c0a87e35d6d YELLOW -DelegatingVisualFactory.java 8bb82e9d48b2577655e577e7e807629c6fd6f2db YELLOW +DelegatingModelFactory.java 09919cf0cdd95ce500ffc1083899d29b89efb5b2 GREEN +DelegatingVisualFactory.java 17bd4a6bbd3b9f9f8f9104d8cd9b239ef4bac759 GREEN diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingControllerFactory.java b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingControllerFactory.java index be19395684645d79d892e5caed079d4b7f5cb5b0..50b2a5057794d6df22649e267d282ca3aa16797c 100644 --- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingControllerFactory.java +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingControllerFactory.java @@ -28,9 +28,10 @@ import org.fortiss.tooling.common.ui.javafx.lwfxef.mvc.ILinkMVCBundle; import org.fortiss.tooling.common.ui.javafx.lwfxef.mvc.IMVCBundle; /** - * Delegates the creational calls to concrete {@link IControllerFactory}s. The first non-null - * element returned by the factories of the initially given list is returned. If no element is - * created (all delegates returned null), this factory throws a {@link RuntimeException}. + * Delegates the creational calls to concrete {@link IControllerFactory}s. The first + * non-{@code null} element returned by the factories of the initially given list is returned. If no + * element is created (all delegates returned {@code null}), this factory throws a + * {@link RuntimeException}. * * @author hoelzl * @author diewald diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingModelFactory.java b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingModelFactory.java index f94ca989a5b97ad3f073040bb46b9c0a87e35d6d..09919cf0cdd95ce500ffc1083899d29b89efb5b2 100644 --- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingModelFactory.java +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingModelFactory.java @@ -15,6 +15,7 @@ +--------------------------------------------------------------------------*/ package org.fortiss.tooling.kernel.ui.extension.base.factory; +import static java.util.Optional.empty; import static java.util.stream.Collectors.toList; import static org.apache.commons.lang3.reflect.ConstructorUtils.getMatchingAccessibleConstructor; import static org.conqat.lib.commons.collections.CollectionUtils.isNullOrEmpty; @@ -32,9 +33,9 @@ import org.fortiss.tooling.common.ui.javafx.lwfxef.model.IModelFactory; import org.fortiss.tooling.kernel.ui.ToolingKernelUIActivator; /** - * Delegates the creational and getter calls to concrete {@link IModelFactory}s. The first non-null - * element returned by the factories of the initially given list is returned. If no element is - * created (all delegates returned null), this factory also returns null. + * Delegates the creational and getter calls to concrete {@link IModelFactory}s. The first + * non-{@code null} element returned by the factories of the initially given list is returned. If no + * element is created (all delegates returned {@code null}), this factory also returns {@code null}. * <p> * Only the root model must be identical for all delegate factories. Hence, the root element of the * first delegate is returned. @@ -65,7 +66,7 @@ public class DelegatingModelFactory extends DelegatingFactoryBase<IModelFactory> InvocationTargetException e) { error(ToolingKernelUIActivator.getDefault(), "Failed to instantiate the factory " + delegateFactory.getSimpleName() + "."); - return Optional.empty(); + return empty(); } } catch(NullPointerException | SecurityException e1) { error(ToolingKernelUIActivator.getDefault(), "The factory " + @@ -73,7 +74,7 @@ public class DelegatingModelFactory extends DelegatingFactoryBase<IModelFactory> " is missing a single argument Constructor accepting the edited model." + " Only such constructors are allowed for " + IModelFactory.class.getSimpleName() + "s."); - return Optional.empty(); + return empty(); } } diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingVisualFactory.java b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingVisualFactory.java index 8bb82e9d48b2577655e577e7e807629c6fd6f2db..17bd4a6bbd3b9f9f8f9104d8cd9b239ef4bac759 100644 --- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingVisualFactory.java +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingVisualFactory.java @@ -32,9 +32,9 @@ import org.fortiss.tooling.kernel.ui.extension.base.LWFXEFEditorBase; /** * Base class for {@link IVisualFactory}s of extendable {@link LWFXEFEditorBase} - * {@link IEditorPart}s.The first non-null element returned by the factories of the initially given - * list is returned. If no element is - * created (all delegates returned null), this factory also returns null. + * {@link IEditorPart}s.The first non-{@code null} element returned by the factories of the + * initially given list is returned. If no element is created (all delegates returned null), this + * factory also returns {@code null}. * <P> * This class uses the {@link ITransformationService} to find a delegate visual factory for the * model elements in question. diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/.ratings b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/.ratings index 4fe5ae19062526bb33cd7efe44bd12d9d85587b6..47d763c0b8c828c45fb79c3acb051e06400a72bd 100644 --- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/.ratings +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/.ratings @@ -3,8 +3,8 @@ AllocationEditPartFactoryService.java 81bd227736013f1157ba9d0f79a9f3deefe10064 G ContextMenuService.java ca3c899293f25b70ce8e5f0d86ca2f9683329d81 GREEN EditPartFactoryService.java e9180c0020f1769d9e24ef3c08f9ca5599dbc5c3 GREEN MarkerService.java 208f97f3ccabf0947702a17ddca23d8766a268f4 GREEN -ModelEditorBindingService.java 948fcdc298a74e366351ad8835a145af6cd238be GREEN -ModelElementHandlerService.java 07a30545ad687ff0fe13bf7a9348c41fb03e0b2c GREEN +ModelEditorBindingService.java 577f5db41abf240291434dbad6bc6b0fde1eeb2b GREEN +ModelElementHandlerService.java eeb07f6926012aa98256d452d1e554a5486dc657 GREEN NavigatorService.java 2b1361eac805996e22e5409dafff9707fbac3376 GREEN ToolingKernelUIInternal.java a70d19883dfb315d860233156d8524cf1ac2952f GREEN TutorialUIService.java b1d632eca91b4feb583f3930cd6ee4722dd9bfed GREEN diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/ModelElementHandlerService.java b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/ModelElementHandlerService.java index 07a30545ad687ff0fe13bf7a9348c41fb03e0b2c..eeb07f6926012aa98256d452d1e554a5486dc657 100644 --- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/ModelElementHandlerService.java +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/ModelElementHandlerService.java @@ -33,6 +33,8 @@ import org.fortiss.tooling.kernel.ui.extension.IModelElementHandler; import org.fortiss.tooling.kernel.ui.internal.introspection.items.ModelElementHandlerServiceIntrospectionDetailsItem; import org.fortiss.tooling.kernel.ui.service.IModelElementHandlerService; +import javafx.scene.Node; + /** * This class implements the {@link IModelElementHandlerService} interface. It * requires a unique and singleton model element handler per model element @@ -145,6 +147,13 @@ public class ModelElementHandlerService return handler == null ? null : handler.getIcon(modelElement); } + /** {@inheritDoc} */ + @Override + public Node getFXIcon(EObject modelElement) { + IModelElementHandler<EObject> handler = getModelElementHandler(modelElement); + return handler == null ? null : handler.getFXIcon(modelElement); + } + /** {@inheritDoc} */ @Override public String getWrappedNameDescription(EObject modelElement) { diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/service/.ratings b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/service/.ratings index ac88577cf756cac95c8f570ad76c78098a9ea3ba..86599ae4e07d82e60443af868fe84e8d057ae40e 100644 --- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/service/.ratings +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/service/.ratings @@ -4,6 +4,6 @@ IContextMenuService.java cfb6b8237b6cd2b0e461991a9ceb95969f330265 GREEN IEditPartFactoryService.java c448bff63fb81f57037c9f1dc5319859c12d0c4d GREEN IMarkerService.java d433e838e387dd2fe61b8dea7395ebb7203ae39b GREEN IModelEditorBindingService.java ce2ae1957e2232bb0fac1d1d262103f9adfc5266 GREEN -IModelElementHandlerService.java c04c2876ccb8b3f8597c8e443f9c7c3db0945430 GREEN +IModelElementHandlerService.java 1ff2bda9054f6bbd4017fc0ddc118b7702196815 GREEN INavigatorService.java 8d2ffeb6f075d3abea904b84d8a40090d97837fd GREEN ITutorialUIService.java 72707c60c3d23d8ffc5c579cb9b022bb614eb094 GREEN diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/service/IModelElementHandlerService.java b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/service/IModelElementHandlerService.java index c04c2876ccb8b3f8597c8e443f9c7c3db0945430..1ff2bda9054f6bbd4017fc0ddc118b7702196815 100644 --- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/service/IModelElementHandlerService.java +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/service/IModelElementHandlerService.java @@ -20,6 +20,8 @@ import org.eclipse.swt.graphics.Image; import org.fortiss.tooling.kernel.ui.extension.IModelElementHandler; import org.fortiss.tooling.kernel.ui.internal.ModelElementHandlerService; +import javafx.scene.Node; + /** * The model element handler service provides access to registered model element * handlers. @@ -63,6 +65,12 @@ public interface IModelElementHandlerService { */ Image getIcon(EObject modelElement); + /** + * Returns the (JavaFX) icon of the model element (or <code>null</code> if no handler + * was found). + */ + Node getFXIcon(EObject modelElement); + /** * Returns a wrapped string built from the name and description returned by * the underlying handler. diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/.ratings b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/.ratings index 8fb040ffbf08c91fe3c8dea473975346c23c28b3..87159f5430ed08dd71e893efd81e7542dab16d2a 100644 --- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/.ratings +++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/.ratings @@ -7,6 +7,7 @@ HierarchicalNameComparator.java 6face1b673126701a0721af48ead2f9766c17d46 GREEN IdentifierUtils.java fff43dc4e84cdd89c3ece4f5d9d89aec4b0749c2 GREEN JavaUtils.java 65cdadfb9137a240ad59992eacf53a15b7f20804 GREEN KernelModelElementUtils.java fded09befe7e543fc04ea5184ffc1c8a309d7a66 GREEN +KernelServiceBasedModelListenerBase.java 8d916509ae75f7118ce72564ee715c46556fb709 GREEN LoggingUtils.java 0e0aa5d466d80ea29cfc7e91178b23a5cdd4ddf7 GREEN PrototypesUtils.java ec75bed75cfc5103f1f38e3a29df86f729428775 GREEN ResourceUtils.java 7f4941a83115dfbed75eb58b79c0a372fe1cbb94 GREEN diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/KernelServiceBasedModelListenerBase.java b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/KernelServiceBasedModelListenerBase.java new file mode 100644 index 0000000000000000000000000000000000000000..8d916509ae75f7118ce72564ee715c46556fb709 --- /dev/null +++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/KernelServiceBasedModelListenerBase.java @@ -0,0 +1,116 @@ +/*-------------------------------------------------------------------------+ +| Copyright 2019 fortiss GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.kernel.utils; + +import java.util.ArrayList; +import java.util.EventObject; +import java.util.List; + +import org.eclipse.emf.common.command.CommandStackListener; +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.util.EContentAdapter; +import org.fortiss.tooling.kernel.extension.data.ITopLevelElement; +import org.fortiss.tooling.kernel.service.ICommandStackService; +import org.fortiss.tooling.kernel.service.IPersistencyService; + +/** + * Base class for listeners using EMF {@link Adapter}s and {@link ICommandStackService}. + * <P> + * Sub-classes should override {@link #updateComplete(List)} in order to be notified when an + * update cycle has completed (one or more EMF notifications followed by a command stack + * change). + * <P> + * Sub-classes may also provide their custom EMF {@link Adapter}, but must call + * {@link #addNotification(Notification)} whenever a relevant EMF notification occurs. + * + * @author hoelzl + */ +public abstract class KernelServiceBasedModelListenerBase<T extends EObject> + implements CommandStackListener { + /** The persistency service reference. */ + private static final IPersistencyService persistencyService = IPersistencyService.getInstance(); + /** The command stack service. */ + private static final ICommandStackService commandStackService = + ICommandStackService.getInstance(); + /** List of relevant {@link Notification}s recorded during a change transaction. */ + private final List<Notification> notifications = new ArrayList<>(); + + /** The model element. */ + private final T modelElement; + /** The EMF notification listener. */ + private Adapter emfAdapter = new EContentAdapter() { + /** {@inheritDoc} */ + @Override + public void notifyChanged(Notification notification) { + super.notifyChanged(notification); + addNotification(notification); + } + }; + + /** Constructor. */ + public KernelServiceBasedModelListenerBase(T modelElement, Adapter emfAdapter) { + this.modelElement = modelElement; + this.emfAdapter = emfAdapter; + } + + /** Constructor. */ + public KernelServiceBasedModelListenerBase(T modelElement) { + this.modelElement = modelElement; + } + + /** + * Called when the update cycle is completed. + * + * @param notifications + * the list of notifications of the completed cycle + */ + public void updateComplete(List<Notification> notifications) { + // default does nothing. + } + + /** Adds the given {@link Notification} to list of notifications. */ + protected final void addNotification(Notification event) { + notifications.add(event); + } + + /** Registers the listener with the model and the command stack service. */ + public final void register() { + notifications.clear(); + ITopLevelElement root = persistencyService.getTopLevelElementFor(modelElement); + commandStackService.addCommandStackListener(root, this); + modelElement.eAdapters().add(emfAdapter); + } + + /** Unregisters the listener from the model and the command stack service. */ + public final void unregister() { + modelElement.eAdapters().remove(emfAdapter); + ITopLevelElement root = persistencyService.getTopLevelElementFor(modelElement); + commandStackService.removeCommandStackListener(root, this); + notifications.clear(); + } + + /** {@inheritDoc} */ + @Override + public void commandStackChanged(EventObject event) { + if(notifications.isEmpty()) { + return; + } + updateComplete(notifications); + notifications.clear(); + } +}