summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAxel Richard2013-01-18 11:30:43 (EST)
committerAxel Richard2013-01-29 05:58:59 (EST)
commit7ea9ec7c40526ce1f2a312d7dc6bac4f346ad26b (patch)
tree89052f8ec873a4eedfe909a5ba8c58e30d7d47ce
parentf233e42b5df5377bc687ea0d7d551553c5f062f9 (diff)
downloadorg.eclipse.emf.compare-7ea9ec7c40526ce1f2a312d7dc6bac4f346ad26b.zip
org.eclipse.emf.compare-7ea9ec7c40526ce1f2a312d7dc6bac4f346ad26b.tar.gz
org.eclipse.emf.compare-7ea9ec7c40526ce1f2a312d7dc6bac4f346ad26b.tar.bz2
[398358] Extension point for filters and groupsrefs/changes/33/9833/6
Add an extension point to EMF Compare so that users and extenders can provide their own filters and groups. Rewrite the current filters as extension to the extension as examples of how to contribute these items. Add new group in case of 3-way comparison with 3 categories : left side, right side, and conflicts. Change-Id: I19975b7a0f8f9b66078a6082360716f1d9c0907a
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/META-INF/MANIFEST.MF87
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/plugin.xml378
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/pom.xml2
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/EMFCompareConstants.java100
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/EMFCompareIDEUIPlugin.java11
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/filter/FilterAction.java91
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/filter/FilterActionMenu.java108
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/DifferenceGroupProvider.java33
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/GroupActionMenu.java93
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/KindGroupProvider.java49
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/save/SaveComparisonModelAction.java196
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewer.java168
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewerContentProvider.java14
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewerLabelProvider.java298
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/META-INF/MANIFEST.MF16
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/build.properties19
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/icons/full/toolb16/filter.gif (renamed from plugins/org.eclipse.emf.compare.ide.ui/icons/full/toolb16/filter.gif)bin219 -> 219 bytes
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/icons/full/toolb16/group.gif (renamed from plugins/org.eclipse.emf.compare.ide.ui/icons/full/toolb16/group.gif)bin307 -> 307 bytes
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/plugin.xml64
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/pom.xml2
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/schema/filters.exsd116
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/schema/groups.exsd116
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/Activator.java133
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/EMFCompareRCPUIPlugin.java365
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/util/AbstractRegistryEventListener.java249
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/EObjectAccessor.java574
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/actions/FilterAction.java67
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/actions/FilterActionMenu.java104
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/actions/GroupAction.java (renamed from plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/GroupAction.java)107
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/actions/GroupActionMenu.java120
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/AddedElementsFilter.java114
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/ChangedElementsFilter.java114
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/IDifferenceFilter.java211
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/IDifferenceFilterSelectionChangeEvent.java94
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/MatchedResourcesFilter.java112
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/MovedElementsFilter.java115
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/RemovedElementsFilter.java115
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/StructureMergeViewerFilter.java (renamed from plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/filter/DifferenceFilter.java)375
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/DefaultDifferenceGroup.java (renamed from plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/DefaultDifferenceGroup.java)266
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/DefaultGroupProvider.java82
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/DifferenceGroup.java (renamed from plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/DifferenceGroup.java)107
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/IDifferenceGroupProvider.java220
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/KindGroupProvider.java105
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/MetamodelGroupProvider.java (renamed from plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/MetamodelGroupProvider.java)256
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/StructureMergeViewerGrouper.java (renamed from plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/DifferenceGrouper.java)278
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/ThreeWayComparisonGroupProvider.java110
46 files changed, 4347 insertions, 2007 deletions
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.compare.ide.ui/META-INF/MANIFEST.MF
index ccc3497..27b64a9 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.emf.compare.ide.ui/META-INF/MANIFEST.MF
@@ -1,44 +1,43 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: %pluginName
-Bundle-SymbolicName: org.eclipse.emf.compare.ide.ui;singleton:=true
-Bundle-Version: 2.1.0.qualifier
-Bundle-Activator: org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIPlugin
-Bundle-Vendor: %providerName
-Require-Bundle: org.eclipse.core.runtime,
- org.eclipse.core.resources;bundle-version="3.5.0",
- org.eclipse.compare;bundle-version="3.5.0",
- org.eclipse.emf.edit.ui;bundle-version="2.5.0",
- org.eclipse.emf.compare.edit;bundle-version="2.0.1",
- org.eclipse.emf.compare.ide;bundle-version="2.0.1",
- org.eclipse.jface.text;bundle-version="3.5.0",
- org.eclipse.emf.compare.rcp.ui;bundle-version="2.0.1",
- org.eclipse.core.filesystem,
- org.eclipse.team.core;bundle-version="3.5.0",
- org.eclipse.emf.ecore.xmi;bundle-version="2.5.0",
- org.eclipse.team.ui;bundle-version="3.5.0"
-Bundle-RequiredExecutionEnvironment: J2SE-1.5
-Bundle-ActivationPolicy: lazy
-Bundle-Localization: plugin
-Export-Package: org.eclipse.emf.compare.ide.ui.internal;x-internal:=true,
- org.eclipse.emf.compare.ide.ui.internal.actions.filter;x-internal:=true,
- org.eclipse.emf.compare.ide.ui.internal.actions.group;x-internal:=true,
- org.eclipse.emf.compare.ide.ui.internal.actions.save;x-internal:=true,
- org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer;x-internal:=true,
- org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor;x-internal:=true,
- org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.factory;x-internal:=true,
- org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.table;x-internal:=true,
- org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.text;x-internal:=true,
- org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.tree;x-internal:=true,
- org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util;x-internal:=true,
- org.eclipse.emf.compare.ide.ui.internal.editor;x-internal:=true,
- org.eclipse.emf.compare.ide.ui.internal.handler;x-internal:=true,
- org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer;x-internal:=true,
- org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.provider;x-internal:=true,
- org.eclipse.emf.compare.ide.ui.internal.util;x-internal:=true,
- org.eclipse.emf.compare.ide.ui.logical
-Import-Package: com.google.common.annotations;version="[10.0.0,11.0.0)",
- com.google.common.base;version="[10.0.0,11.0.0)",
- com.google.common.cache;version="[10.0.0,11.0.0)",
- com.google.common.collect;version="[10.0.0,11.0.0)",
- com.google.common.io;version="[10.0.0,11.0.0)"
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.emf.compare.ide.ui;singleton:=true
+Bundle-Version: 3.0.0.qualifier
+Bundle-Activator: org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIPlugin
+Bundle-Vendor: %providerName
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.core.resources;bundle-version="3.5.0",
+ org.eclipse.compare;bundle-version="3.5.0",
+ org.eclipse.emf.edit.ui;bundle-version="2.5.0",
+ org.eclipse.emf.compare.edit;bundle-version="2.0.1",
+ org.eclipse.emf.compare.ide;bundle-version="2.0.1",
+ org.eclipse.jface.text;bundle-version="3.5.0",
+ org.eclipse.emf.compare.rcp.ui;bundle-version="2.0.1",
+ org.eclipse.core.filesystem,
+ org.eclipse.team.core;bundle-version="3.5.0",
+ org.eclipse.emf.ecore.xmi;bundle-version="2.5.0",
+ org.eclipse.team.ui;bundle-version="3.5.0"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Bundle-Localization: plugin
+Export-Package: org.eclipse.emf.compare.ide.ui.internal;x-internal:=true,
+ org.eclipse.emf.compare.ide.ui.internal.actions.save;x-internal:=true,
+ org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer;x-internal:=true,
+ org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor;x-internal:=true,
+ org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.factory;x-internal:=true,
+ org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.table;x-internal:=true,
+ org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.text;x-internal:=true,
+ org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.tree;x-internal:=true,
+ org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util;x-internal:=true,
+ org.eclipse.emf.compare.ide.ui.internal.editor;x-internal:=true,
+ org.eclipse.emf.compare.ide.ui.internal.handler;x-internal:=true,
+ org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer;x-internal:=true,
+ org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.provider;x-internal:=true,
+ org.eclipse.emf.compare.ide.ui.internal.util;x-internal:=true,
+ org.eclipse.emf.compare.ide.ui.logical
+Import-Package: com.google.common.annotations;version="[10.0.0,11.0.0)",
+ com.google.common.base;version="[10.0.0,11.0.0)",
+ com.google.common.cache;version="[10.0.0,11.0.0)",
+ com.google.common.collect;version="[10.0.0,11.0.0)",
+ com.google.common.eventbus;version="[10.0.0,11.0.0)",
+ com.google.common.io;version="[10.0.0,11.0.0)"
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/plugin.xml b/plugins/org.eclipse.emf.compare.ide.ui/plugin.xml
index f5d8a4c..3e13bdb 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/plugin.xml
+++ b/plugins/org.eclipse.emf.compare.ide.ui/plugin.xml
@@ -1,19 +1,19 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<?eclipse version="3.4"?>
-
-<!--
- Copyright (c) 2012 Obeo.
- All rights reserved. This program and the accompanying materials
- are made available under the terms of the Eclipse Public License v1.0
- which accompanies this distribution, and is available at
- http://www.eclipse.org/legal/epl-v10.html
-
- Contributors:
- Obeo - initial API and implementation
--->
-
-<plugin>
- <extension-point id="accessor_factory" name="Accessor Factory" schema="schema/accessor_factory.exsd"/>
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+
+<!--
+ Copyright (c) 2012 Obeo.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Eclipse Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/epl-v10.html
+
+ Contributors:
+ Obeo - initial API and implementation
+-->
+
+<plugin>
+ <extension-point id="accessor_factory" name="Accessor Factory" schema="schema/accessor_factory.exsd"/>
<extension
point="org.eclipse.compare.structureMergeViewers">
<viewer
@@ -38,177 +38,177 @@
<contentTypeBinding
contentMergeViewerId="org.eclipse.emf.compare.ide.ui.internal.EObjectContentMergeViewer"
contentTypeId="org.eclipse.emf.ecore.xmi">
- </contentTypeBinding>
- <viewer
- class="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.table.TableContentMergeViewerCreator"
- extensions="emfcompare_diff"
- id="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EObjectListContentMergeViewer"
- label="EMFCompare Content Merge Viewer">
- </viewer>
- <viewer
- class="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.text.EMFCompareTextMergeViewerCreator"
- extensions="eText"
- id="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.text.EMFCompareTextContentMergeViewer"
- label="EMFCompare Text Merge Viewer">
+ </contentTypeBinding>
+ <viewer
+ class="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.table.TableContentMergeViewerCreator"
+ extensions="emfcompare_diff"
+ id="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EObjectListContentMergeViewer"
+ label="EMFCompare Content Merge Viewer">
+ </viewer>
+ <viewer
+ class="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.text.EMFCompareTextMergeViewerCreator"
+ extensions="eText"
+ id="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.text.EMFCompareTextContentMergeViewer"
+ label="EMFCompare Text Merge Viewer">
</viewer>
- </extension>
- <extension
- point="org.eclipse.emf.edit.itemProviderAdapterFactories">
- <factory
- class="org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.provider.CompareNodeAdapterFactory"
- supportedTypes="org.eclipse.compare.structuremergeviewer.ICompareInput"
- uri="http://www.eclipse.org/emf/compare">
- </factory>
- </extension>
- <extension
- point="org.eclipse.emf.compare.ide.ui.accessor_factory">
- <factory
- class="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.factory.IDEEObjectAccessorFactory"
- ranking="10">
- </factory>
- <factory
- class="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.factory.IDEManyStructuralFeatureAccessorFactory"
- ranking="10">
- </factory>
- <factory
- class="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.factory.IDESingleStructuralFeatureAccessorFactory"
- ranking="10">
- </factory>
- <factory
- class="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.factory.IDEStringAttributeChangeAccessorFactory"
- ranking="10">
- </factory>
- </extension>
- <extension
- point="org.eclipse.ui.commands">
- <command
- categoryId="org.eclipse.compare.ui.category.compare"
- id="org.eclipse.emf.compare.ide.ui.compareInDialog"
- name="Compare in Dialog">
- </command>
- <command
- categoryId="org.eclipse.compare.ui.category.compare"
- id="org.eclipse.emf.compare.ide.ui.compareInEditor"
- name="Compare in new Editor">
- </command>
- <command
- id="org.eclipse.team.ui.compareWithEachOther"
- name="Each Other">
- </command>
- </extension>
- <extension
- point="org.eclipse.ui.handlers">
- <handler
- class="org.eclipse.emf.compare.ide.ui.internal.handler.CompareInDialog"
- commandId="org.eclipse.emf.compare.ide.ui.compareInDialog">
- <activeWhen>
- <with
- variable="selection">
- <and>
- <iterate
- ifEmpty="false"
- operator="and">
- <instanceof
- value="org.eclipse.emf.ecore.EObject">
- </instanceof>
- </iterate>
- <or>
- <count
- value="2">
- </count>
- <count
- value="3">
- </count>
- </or>
- </and>
- </with>
- </activeWhen>
- </handler>
- <handler
- class="org.eclipse.emf.compare.ide.ui.internal.handler.CompareInNewEditor"
- commandId="org.eclipse.emf.compare.ide.ui.compareInEditor">
- <activeWhen>
- <with
- variable="selection">
- <and>
- <iterate
- ifEmpty="false"
- operator="and">
- <instanceof
- value="org.eclipse.emf.ecore.EObject">
- </instanceof>
- </iterate>
- <or>
- <count
- value="2">
- </count>
- <count
- value="3">
- </count>
- </or>
- </and>
- </with>
- </activeWhen>
- </handler>
- <handler
- class="org.eclipse.emf.compare.ide.ui.internal.handler.CompareInDialog"
- commandId="org.eclipse.team.ui.compareWithEachOther">
- <activeWhen>
- <with
- variable="selection">
- <and>
- <iterate
- ifEmpty="false"
- operator="and">
- <instanceof
- value="org.eclipse.emf.ecore.EObject">
- </instanceof>
- </iterate>
- <or>
- <count
- value="2">
- </count>
- <count
- value="3">
- </count>
- </or>
- </and>
- </with>
- </activeWhen>
- </handler>
- </extension>
- <extension
- point="org.eclipse.ui.menus">
- <menuContribution
- allPopups="true"
- locationURI="popup:compareWithMenu?after=compareWithGroup">
- <command
- commandId="org.eclipse.emf.compare.ide.ui.compareInDialog"
- label="Each Other &lt;EObject&gt; (in Dialog)"
- style="push">
- <visibleWhen
- checkEnabled="true">
- </visibleWhen>
- </command>
- <command
- commandId="org.eclipse.emf.compare.ide.ui.compareInEditor"
- label="Each Other &lt;EObject&gt; (in Editor)"
- style="push">
- <visibleWhen
- checkEnabled="true">
- </visibleWhen>
- </command>
- </menuContribution>
- <menuContribution
- allPopups="false"
- locationURI="popup:org.eclipse.ui.popup.any">
- <menu
- id="compareWithMenu"
- label="Compare With">
- <separator
- name="compareWithGroup">
- </separator>
- </menu>
- </menuContribution>
- </extension>
-</plugin>
+ </extension>
+ <extension
+ point="org.eclipse.emf.edit.itemProviderAdapterFactories">
+ <factory
+ class="org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.provider.CompareNodeAdapterFactory"
+ supportedTypes="org.eclipse.compare.structuremergeviewer.ICompareInput"
+ uri="http://www.eclipse.org/emf/compare">
+ </factory>
+ </extension>
+ <extension
+ point="org.eclipse.emf.compare.ide.ui.accessor_factory">
+ <factory
+ class="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.factory.IDEEObjectAccessorFactory"
+ ranking="10">
+ </factory>
+ <factory
+ class="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.factory.IDEManyStructuralFeatureAccessorFactory"
+ ranking="10">
+ </factory>
+ <factory
+ class="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.factory.IDESingleStructuralFeatureAccessorFactory"
+ ranking="10">
+ </factory>
+ <factory
+ class="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.factory.IDEStringAttributeChangeAccessorFactory"
+ ranking="10">
+ </factory>
+ </extension>
+ <extension
+ point="org.eclipse.ui.commands">
+ <command
+ categoryId="org.eclipse.compare.ui.category.compare"
+ id="org.eclipse.emf.compare.ide.ui.compareInDialog"
+ name="Compare in Dialog">
+ </command>
+ <command
+ categoryId="org.eclipse.compare.ui.category.compare"
+ id="org.eclipse.emf.compare.ide.ui.compareInEditor"
+ name="Compare in new Editor">
+ </command>
+ <command
+ id="org.eclipse.team.ui.compareWithEachOther"
+ name="Each Other">
+ </command>
+ </extension>
+ <extension
+ point="org.eclipse.ui.handlers">
+ <handler
+ class="org.eclipse.emf.compare.ide.ui.internal.handler.CompareInDialog"
+ commandId="org.eclipse.emf.compare.ide.ui.compareInDialog">
+ <activeWhen>
+ <with
+ variable="selection">
+ <and>
+ <iterate
+ ifEmpty="false"
+ operator="and">
+ <instanceof
+ value="org.eclipse.emf.ecore.EObject">
+ </instanceof>
+ </iterate>
+ <or>
+ <count
+ value="2">
+ </count>
+ <count
+ value="3">
+ </count>
+ </or>
+ </and>
+ </with>
+ </activeWhen>
+ </handler>
+ <handler
+ class="org.eclipse.emf.compare.ide.ui.internal.handler.CompareInNewEditor"
+ commandId="org.eclipse.emf.compare.ide.ui.compareInEditor">
+ <activeWhen>
+ <with
+ variable="selection">
+ <and>
+ <iterate
+ ifEmpty="false"
+ operator="and">
+ <instanceof
+ value="org.eclipse.emf.ecore.EObject">
+ </instanceof>
+ </iterate>
+ <or>
+ <count
+ value="2">
+ </count>
+ <count
+ value="3">
+ </count>
+ </or>
+ </and>
+ </with>
+ </activeWhen>
+ </handler>
+ <handler
+ class="org.eclipse.emf.compare.ide.ui.internal.handler.CompareInDialog"
+ commandId="org.eclipse.team.ui.compareWithEachOther">
+ <activeWhen>
+ <with
+ variable="selection">
+ <and>
+ <iterate
+ ifEmpty="false"
+ operator="and">
+ <instanceof
+ value="org.eclipse.emf.ecore.EObject">
+ </instanceof>
+ </iterate>
+ <or>
+ <count
+ value="2">
+ </count>
+ <count
+ value="3">
+ </count>
+ </or>
+ </and>
+ </with>
+ </activeWhen>
+ </handler>
+ </extension>
+ <extension
+ point="org.eclipse.ui.menus">
+ <menuContribution
+ allPopups="true"
+ locationURI="popup:compareWithMenu?after=compareWithGroup">
+ <command
+ commandId="org.eclipse.emf.compare.ide.ui.compareInDialog"
+ label="Each Other &lt;EObject&gt; (in Dialog)"
+ style="push">
+ <visibleWhen
+ checkEnabled="true">
+ </visibleWhen>
+ </command>
+ <command
+ commandId="org.eclipse.emf.compare.ide.ui.compareInEditor"
+ label="Each Other &lt;EObject&gt; (in Editor)"
+ style="push">
+ <visibleWhen
+ checkEnabled="true">
+ </visibleWhen>
+ </command>
+ </menuContribution>
+ <menuContribution
+ allPopups="false"
+ locationURI="popup:org.eclipse.ui.popup.any">
+ <menu
+ id="compareWithMenu"
+ label="Compare With">
+ <separator
+ name="compareWithGroup">
+ </separator>
+ </menu>
+ </menuContribution>
+ </extension>
+</plugin>
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/pom.xml b/plugins/org.eclipse.emf.compare.ide.ui/pom.xml
index c2b30b7..521a2e8 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/pom.xml
+++ b/plugins/org.eclipse.emf.compare.ide.ui/pom.xml
@@ -10,7 +10,7 @@
</parent>
<groupId>org.eclipse.emf.compare</groupId>
<artifactId>org.eclipse.emf.compare.ide.ui</artifactId>
- <version>2.1.0-SNAPSHOT</version>
+ <version>3.0.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
<build>
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/EMFCompareConstants.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/EMFCompareConstants.java
index c18aa40..b6affff 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/EMFCompareConstants.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/EMFCompareConstants.java
@@ -1,48 +1,52 @@
-/*******************************************************************************
- * Copyright (c) 2012 Obeo.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Obeo - initial API and implementation
- *******************************************************************************/
-package org.eclipse.emf.compare.ide.ui.internal;
-
-/**
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- */
-public final class EMFCompareConstants {
-
- private EMFCompareConstants() {
- // prevents instantiation
- }
-
- public static final int COMPARE_IMAGE_WIDTH = 22;
-
- public static final String INCOMING_COLOR = "INCOMING_COLOR"; //$NON-NLS-1$
-
- public static final String OUTGOING_COLOR = "OUTGOING_COLOR"; //$NON-NLS-1$
-
- public static final String CONFLICTING_COLOR = "CONFLICTING_COLOR"; //$NON-NLS-1$
-
- public static final String RESOLVED_COLOR = "RESOLVED_COLOR"; //$NON-NLS-1$
-
- // CompareConfiguration
-
- public static final String COMPARE_RESULT = EMFCompareIDEUIPlugin.PLUGIN_ID + ".COMPARE.RESULT"; //$NON-NLS-1$
-
- public static final String COMPARATOR = EMFCompareIDEUIPlugin.PLUGIN_ID + ".COMPARATOR"; //$NON-NLS-1$
-
- public static final String EDITING_DOMAIN = EMFCompareIDEUIPlugin.PLUGIN_ID + ".EDITING_DOMAIN"; //$NON-NLS-1$
-
- // ITypedElement#getType()
-
- public static final String NODE_TYPE__EMF_RESOURCESET = "NODE_TYPE__EMF_RESOURCESET"; //$NON-NLS-1$
-
- public static final String NODE_TYPE__EMF_RESOURCE = "NODE_TYPE__EMF_RESOURCE"; //$NON-NLS-1$
-
- public static final String NODE_TYPE__EMF_EOBJECT = "NODE_TYPE__EMF_EOBJECT"; //$NON-NLS-1$
-
-}
+/*******************************************************************************
+ * Copyright (c) 2012 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.ide.ui.internal;
+
+/**
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public final class EMFCompareConstants {
+
+ private EMFCompareConstants() {
+ // prevents instantiation
+ }
+
+ public static final int COMPARE_IMAGE_WIDTH = 22;
+
+ public static final String INCOMING_COLOR = "INCOMING_COLOR"; //$NON-NLS-1$
+
+ public static final String OUTGOING_COLOR = "OUTGOING_COLOR"; //$NON-NLS-1$
+
+ public static final String CONFLICTING_COLOR = "CONFLICTING_COLOR"; //$NON-NLS-1$
+
+ public static final String RESOLVED_COLOR = "RESOLVED_COLOR"; //$NON-NLS-1$
+
+ // CompareConfiguration
+
+ public static final String COMPARE_RESULT = EMFCompareIDEUIPlugin.PLUGIN_ID + ".COMPARE.RESULT"; //$NON-NLS-1$
+
+ public static final String COMPARATOR = EMFCompareIDEUIPlugin.PLUGIN_ID + ".COMPARATOR"; //$NON-NLS-1$
+
+ public static final String EDITING_DOMAIN = EMFCompareIDEUIPlugin.PLUGIN_ID + ".EDITING_DOMAIN"; //$NON-NLS-1$
+
+ public static final String SELECTED_FILTERS = EMFCompareIDEUIPlugin.PLUGIN_ID + ".SELECTED_FILTERS"; //$NON-NLS-1$
+
+ public static final String SELECTED_GROUP = EMFCompareIDEUIPlugin.PLUGIN_ID + ".SELECTED_GROUP"; //$NON-NLS-1$
+
+ // ITypedElement#getType()
+
+ public static final String NODE_TYPE__EMF_RESOURCESET = "NODE_TYPE__EMF_RESOURCESET"; //$NON-NLS-1$
+
+ public static final String NODE_TYPE__EMF_RESOURCE = "NODE_TYPE__EMF_RESOURCE"; //$NON-NLS-1$
+
+ public static final String NODE_TYPE__EMF_EOBJECT = "NODE_TYPE__EMF_EOBJECT"; //$NON-NLS-1$
+
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/EMFCompareIDEUIPlugin.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/EMFCompareIDEUIPlugin.java
index f2ef151..39ff1c2 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/EMFCompareIDEUIPlugin.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/EMFCompareIDEUIPlugin.java
@@ -67,7 +67,7 @@ public class EMFCompareIDEUIPlugin extends AbstractUIPlugin {
registry = new IAccessorFactory.RegistryImpl();
listener = new AccessorFactoryExtensionRegistryListener(PLUGIN_ID, ACCESSOR_FACTORY_PPID);
- extensionRegistry.addListener(listener, PLUGIN_ID + "." + ACCESSOR_FACTORY_PPID);
+ extensionRegistry.addListener(listener, PLUGIN_ID + "." + ACCESSOR_FACTORY_PPID); //$NON-NLS-1$
listener.readRegistry(extensionRegistry);
}
@@ -199,8 +199,8 @@ public class EMFCompareIDEUIPlugin extends AbstractUIPlugin {
try {
Integer.parseInt(rankingStr);
} catch (NumberFormatException nfe) {
- logError(element, "Attribute '" + ATT_RANKING
- + "' is malformed, should be an integer.");
+ logError(element, "Attribute '" + ATT_RANKING //$NON-NLS-1$
+ + "' is malformed, should be an integer."); //$NON-NLS-1$
}
logMissingAttribute(element, ATT_RANKING);
} else {
@@ -212,8 +212,8 @@ public class EMFCompareIDEUIPlugin extends AbstractUIPlugin {
factory.setRanking(Integer.parseInt(element.getAttribute(ATT_RANKING)));
IAccessorFactory previous = registry.add(factory);
if (previous != null) {
- log(IStatus.WARNING, "The factory '" + factory.getClass().getName()
- + "' is registered twice.");
+ log(IStatus.WARNING, "The factory '" + factory.getClass().getName() //$NON-NLS-1$
+ + "' is registered twice."); //$NON-NLS-1$
}
} catch (CoreException e) {
logError(element, e.getMessage());
@@ -240,4 +240,5 @@ public class EMFCompareIDEUIPlugin extends AbstractUIPlugin {
log(IStatus.ERROR, string);
}
}
+
}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/filter/FilterAction.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/filter/FilterAction.java
deleted file mode 100644
index e932180..0000000
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/filter/FilterAction.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2012 Obeo.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Obeo - initial API and implementation
- *******************************************************************************/
-package org.eclipse.emf.compare.ide.ui.internal.actions.filter;
-
-import com.google.common.base.Predicate;
-
-import org.eclipse.emf.compare.Diff;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.IAction;
-
-/**
- * These will be the actual actions displayed in the filter menu. Their sole purpose is to provide a Predicate
- * to the structure viewer's filter.
- * <p>
- * Do note that each distinct {@link FilterAction} in the {@link FilterActionMenu filter menu} is considered
- * as an "exclude" filter, and that they are OR'ed together (thus, any element must <b>not</b> meet the
- * selected filters' criteria in order to be displayed).
- * </p>
- *
- * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
- */
-public class FilterAction extends Action {
- /** The Predicate activate through this action. */
- private Predicate<? super EObject> predicate;
-
- /** The Filter that will be modified by the action. */
- private DifferenceFilter differenceFilter;
-
- /**
- * The "default" constructor for this action.
- * {@link #fromDiffPredicate(String, Predicate, DifferenceFilter)} can be used instead in order to create
- * an action which filter only aims at Diff elements.
- *
- * @param text
- * Will be used as the action's tooltip.
- * @param predicate
- * The predicate that this action will provide to the viewer's filter.
- * @param differenceFilter
- * The filter that this action will need to update.
- */
- public FilterAction(String text, Predicate<? super EObject> predicate, DifferenceFilter differenceFilter) {
- super(text, IAction.AS_CHECK_BOX);
- this.predicate = predicate;
- this.differenceFilter = differenceFilter;
- }
-
- /**
- * Constructs a filtering action that only aims at filtering out Diff elements from the view, ignoring all
- * other kind of objects.
- *
- * @param text
- * The tooltip of the new action.
- * @param diffPredicate
- * The predicate that this action will provide to the viewer's filter.
- * @param filter
- * The filter that this action will need to update.
- * @return The newly created action.
- */
- public static FilterAction fromDiffPredicate(String text, final Predicate<? super Diff> diffPredicate,
- DifferenceFilter filter) {
- final Predicate<? super EObject> actualPredicate = new Predicate<EObject>() {
- public boolean apply(EObject input) {
- return input instanceof Diff && diffPredicate.apply((Diff)input);
- }
- };
- return new FilterAction(text, actualPredicate, filter);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.action.Action#run()
- */
- @Override
- public void run() {
- if (isChecked()) {
- differenceFilter.addPredicate(predicate);
- } else {
- differenceFilter.removePredicate(predicate);
- }
- }
-}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/filter/FilterActionMenu.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/filter/FilterActionMenu.java
deleted file mode 100644
index 1888ee0..0000000
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/filter/FilterActionMenu.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2012 Obeo.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Obeo - initial API and implementation
- *******************************************************************************/
-package org.eclipse.emf.compare.ide.ui.internal.actions.filter;
-
-import static com.google.common.base.Predicates.instanceOf;
-import static org.eclipse.emf.compare.utils.EMFComparePredicates.ofKind;
-
-import org.eclipse.emf.compare.DifferenceKind;
-import org.eclipse.emf.compare.MatchResource;
-import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIPlugin;
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.action.IMenuCreator;
-import org.eclipse.jface.action.MenuManager;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Menu;
-import org.eclipse.ui.plugin.AbstractUIPlugin;
-
-/**
- * This will be displayed atop the structure viewer as the "filters" menu.
- *
- * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
- */
-public class FilterActionMenu extends Action implements IMenuCreator {
- /** The Filter that will be modified by this menu's actions. */
- private final DifferenceFilter differenceFilter;
-
- /** Menu Manager that will contain our menu. */
- private MenuManager menuManager;
-
- /**
- * Constructs our filtering menu.
- *
- * @param differenceFilter
- * The filter for which we'll create actions.
- */
- public FilterActionMenu(DifferenceFilter differenceFilter) {
- super("", IAction.AS_DROP_DOWN_MENU);
- this.menuManager = new MenuManager();
- this.differenceFilter = differenceFilter;
- setMenuCreator(this);
- setToolTipText("Filters");
- setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(EMFCompareIDEUIPlugin.PLUGIN_ID,
- "icons/full/toolb16/filter.gif")); //$NON-NLS-1$
- createActions(menuManager);
- }
-
- /**
- * Create all of our filtering actions into the given menu.
- *
- * @param menu
- * The menu in which we are to create filter actions.
- */
- public void createActions(MenuManager menu) {
- // TODO make this extensible and use the extension point. Hardcoded for now.
- // The four "difference of kind" predicate
- menu.add(FilterAction.fromDiffPredicate("Changed Elements", ofKind(DifferenceKind.CHANGE),
- differenceFilter));
- menu.add(FilterAction.fromDiffPredicate("Added Elements", ofKind(DifferenceKind.ADD),
- differenceFilter));
- menu.add(FilterAction.fromDiffPredicate("Removed Elements", ofKind(DifferenceKind.DELETE),
- differenceFilter));
- menu.add(FilterAction.fromDiffPredicate("Moved Elements", ofKind(DifferenceKind.MOVE),
- differenceFilter));
- // And one to remove the ResourceMatch from the view.
- final FilterAction matchResourceFilter = new FilterAction("Resource Mappings",
- instanceOf(MatchResource.class), differenceFilter);
- // Make it checked by default, we need to run it once for that
- matchResourceFilter.setChecked(true);
- matchResourceFilter.run();
- menu.add(matchResourceFilter);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see IMenuCreator#dispose()
- */
- public void dispose() {
- menuManager.dispose();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see IMenuCreator#getMenu(Control)
- */
- public Menu getMenu(Control parent) {
- return menuManager.createContextMenu(parent);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see IMenuCreator#getMenu(Menu)
- */
- public Menu getMenu(Menu parent) {
- return menuManager.getMenu();
- }
-}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/DifferenceGroupProvider.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/DifferenceGroupProvider.java
deleted file mode 100644
index 94465b0..0000000
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/DifferenceGroupProvider.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2012 Obeo.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Obeo - initial API and implementation
- *******************************************************************************/
-package org.eclipse.emf.compare.ide.ui.internal.actions.group;
-
-import org.eclipse.emf.compare.Comparison;
-
-/**
- * Instances of this class will be used by EMF Compare in order to provide difference grouping facilities to
- * the structural differences view.
- *
- * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
- */
-public interface DifferenceGroupProvider {
- /**
- * This will be called internally by the grouping actions in order to determine how the differences should
- * be grouped in the structural view.
- *
- * @param comparison
- * The comparison which is to be displayed in the structural view. By default, its containment
- * tree will be displayed.
- * @return The collection of difference groups that are to be displayed in the structural viewer. An empty
- * group will not be displayed at all. If {@code null}, we'll fall back to the default behavior.
- */
- Iterable<? extends DifferenceGroup> getGroups(Comparison comparison);
-}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/GroupActionMenu.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/GroupActionMenu.java
deleted file mode 100644
index f633010..0000000
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/GroupActionMenu.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2012 Obeo.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Obeo - initial API and implementation
- *******************************************************************************/
-package org.eclipse.emf.compare.ide.ui.internal.actions.group;
-
-import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIPlugin;
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.action.IMenuCreator;
-import org.eclipse.jface.action.MenuManager;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Menu;
-import org.eclipse.ui.plugin.AbstractUIPlugin;
-
-/**
- * This menu will display actions that will allow the user to group differences together.
- *
- * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
- */
-public class GroupActionMenu extends Action implements IMenuCreator {
- /** The difference grouper that will be affected by this menu's actions. */
- private final DifferenceGrouper differenceGrouper;
-
- /** Menu Manager that will contain our menu. */
- private MenuManager menuManager;
-
- /**
- * Constructs our grouping menu.
- *
- * @param tree
- * The tree viewer which will be used to display our groups.
- * @param comparison
- * The comparison which differences are to be split into groups.
- */
- public GroupActionMenu(DifferenceGrouper differenceGrouper) {
- super("", IAction.AS_DROP_DOWN_MENU); //$NON-NLS-1$
- this.menuManager = new MenuManager();
- this.differenceGrouper = differenceGrouper;
- setToolTipText("Groups");
- setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(EMFCompareIDEUIPlugin.PLUGIN_ID,
- "icons/full/toolb16/group.gif")); //$NON-NLS-1$
- setMenuCreator(this);
- createActions(menuManager);
- }
-
- /**
- * Create the grouping action in the given menu.
- *
- * @param menu
- */
- public void createActions(MenuManager menu) {
- // TODO make this extensible. we need to allow clients to add new groups to this list.
- final IAction defaultAction = new GroupAction("Default", differenceGrouper, null);
- defaultAction.setChecked(true);
- menu.add(defaultAction);
- menu.add(new GroupAction("By Kind", differenceGrouper, new KindGroupProvider()));
- menu.add(new GroupAction("By Metaclass", differenceGrouper, new MetamodelGroupProvider()));
- }
-
- /**
- * {@inheritDoc}
- *
- * @see IMenuCreator#dispose()
- */
- public void dispose() {
- menuManager.dispose();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see IMenuCreator#getMenu(Control)
- */
- public Menu getMenu(Control parent) {
- return menuManager.createContextMenu(parent);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see IMenuCreator#getMenu(Menu)
- */
- public Menu getMenu(Menu parent) {
- return menuManager.getMenu();
- }
-}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/KindGroupProvider.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/KindGroupProvider.java
deleted file mode 100644
index 1faa307..0000000
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/KindGroupProvider.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2012 Obeo.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Obeo - initial API and implementation
- *******************************************************************************/
-package org.eclipse.emf.compare.ide.ui.internal.actions.group;
-
-import static org.eclipse.emf.compare.utils.EMFComparePredicates.ofKind;
-
-import com.google.common.collect.ImmutableList;
-
-import java.util.List;
-
-import org.eclipse.emf.compare.Comparison;
-import org.eclipse.emf.compare.Diff;
-import org.eclipse.emf.compare.DifferenceKind;
-
-/**
- * This implementation of a {@link DifferenceGroupProvider} will be used to group the differences by their
- * {@link DifferenceKind kind} : additions, deletions, changes and moves.
- *
- * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
- */
-public class KindGroupProvider implements DifferenceGroupProvider {
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.actions.group.DifferenceGroupProvider#getGroups(org.eclipse.emf.compare.Comparison)
- */
- public Iterable<? extends DifferenceGroup> getGroups(Comparison comparison) {
- final List<Diff> diffs = comparison.getDifferences();
-
- final DifferenceGroup additions = new DefaultDifferenceGroup(comparison, diffs,
- ofKind(DifferenceKind.ADD), "Additions");
- final DifferenceGroup deletions = new DefaultDifferenceGroup(comparison, diffs,
- ofKind(DifferenceKind.DELETE), "Deletions");
- final DifferenceGroup changes = new DefaultDifferenceGroup(comparison, diffs,
- ofKind(DifferenceKind.CHANGE), "Changes");
- final DifferenceGroup moves = new DefaultDifferenceGroup(comparison, diffs,
- ofKind(DifferenceKind.MOVE), "Moves");
-
- return ImmutableList.of(additions, deletions, changes, moves);
- }
-}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/save/SaveComparisonModelAction.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/save/SaveComparisonModelAction.java
index 836e1db..53a71ad 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/save/SaveComparisonModelAction.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/save/SaveComparisonModelAction.java
@@ -1,98 +1,98 @@
-/*******************************************************************************
- * Copyright (c) 2012 Obeo.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Obeo - initial API and implementation
- *******************************************************************************/
-package org.eclipse.emf.compare.ide.ui.internal.actions.save;
-
-import static com.google.common.collect.Maps.newHashMap;
-
-import com.google.common.collect.ImmutableList;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.eclipse.compare.CompareConfiguration;
-import org.eclipse.emf.common.util.URI;
-import org.eclipse.emf.compare.Comparison;
-import org.eclipse.emf.compare.ide.ui.internal.EMFCompareConstants;
-import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIPlugin;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.resource.Resource;
-import org.eclipse.emf.ecore.util.EcoreUtil.Copier;
-import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.FileDialog;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.plugin.AbstractUIPlugin;
-
-/**
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- */
-public class SaveComparisonModelAction extends Action {
-
- /**
- *
- */
- private static final ImmutableList<String> DIALOG_BUTTON_LABELS = ImmutableList.of("Replace", "Cancel");
-
- private CompareConfiguration configuration;
-
- /**
- * @param parent
- */
- public SaveComparisonModelAction(CompareConfiguration configuration) {
- this.configuration = configuration;
- setToolTipText("Save Comparison Model");
- setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(EMFCompareIDEUIPlugin.PLUGIN_ID,
- "icons/full/toolb16/saveas_edit.gif")); //$NON-NLS-1$
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.action.Action#run()
- */
- @Override
- public void run() {
- Shell parent = configuration.getContainer().getWorkbenchPart().getSite().getShell();
-
- FileDialog fileDialog = new FileDialog(parent, SWT.SAVE);
- File file = new File(fileDialog.open());
- if (file.exists()) {
- MessageDialog messageDialog = new MessageDialog(parent, "File already exists", null, "File \""
- + file.toString() + "\" already exists. Do you want to replace the existing one?",
- MessageDialog.WARNING, DIALOG_BUTTON_LABELS.toArray(new String[0]), 1);
- int open = messageDialog.open();
- if (open == DIALOG_BUTTON_LABELS.indexOf("Replace")) {
- saveComparison(file);
- } // else do nothing
- } else {
- saveComparison(file);
- }
-
- super.run();
- }
-
- private void saveComparison(File file) {
- Comparison comparison = (Comparison)configuration.getProperty(EMFCompareConstants.COMPARE_RESULT);
- Resource resource = new XMIResourceImpl(URI.createFileURI(file.getAbsolutePath()));
- Copier copier = new Copier(false);
- EObject comparisonCopy = copier.copy(comparison);
- copier.copyReferences();
-
- resource.getContents().add(comparisonCopy);
- try {
- resource.save(newHashMap());
- } catch (IOException e) {
- EMFCompareIDEUIPlugin.getDefault().log(e);
- }
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2012 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.ide.ui.internal.actions.save;
+
+import static com.google.common.collect.Maps.newHashMap;
+
+import com.google.common.collect.ImmutableList;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.compare.CompareConfiguration;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.ide.ui.internal.EMFCompareConstants;
+import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIPlugin;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.util.EcoreUtil.Copier;
+import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+/**
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public class SaveComparisonModelAction extends Action {
+
+ /**
+ *
+ */
+ private static final ImmutableList<String> DIALOG_BUTTON_LABELS = ImmutableList.of("Replace", "Cancel");
+
+ private CompareConfiguration configuration;
+
+ /**
+ * @param parent
+ */
+ public SaveComparisonModelAction(CompareConfiguration configuration) {
+ this.configuration = configuration;
+ setToolTipText("Save Comparison Model");
+ setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(EMFCompareIDEUIPlugin.PLUGIN_ID,
+ "icons/full/toolb16/saveas_edit.gif")); //$NON-NLS-1$
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ @Override
+ public void run() {
+ Shell parent = configuration.getContainer().getWorkbenchPart().getSite().getShell();
+
+ FileDialog fileDialog = new FileDialog(parent, SWT.SAVE);
+ File file = new File(fileDialog.open());
+ if (file.exists()) {
+ MessageDialog messageDialog = new MessageDialog(parent, "File already exists", null, "File \""
+ + file.toString() + "\" already exists. Do you want to replace the existing one?",
+ MessageDialog.WARNING, DIALOG_BUTTON_LABELS.toArray(new String[0]), 1);
+ int open = messageDialog.open();
+ if (open == DIALOG_BUTTON_LABELS.indexOf("Replace")) {
+ saveComparison(file);
+ } // else do nothing
+ } else {
+ saveComparison(file);
+ }
+
+ super.run();
+ }
+
+ private void saveComparison(File file) {
+ Comparison comparison = (Comparison)configuration.getProperty(EMFCompareConstants.COMPARE_RESULT);
+ Resource resource = new XMIResourceImpl(URI.createFileURI(file.getAbsolutePath()));
+ Copier copier = new Copier(false);
+ EObject comparisonCopy = copier.copy(comparison);
+ copier.copyReferences();
+
+ resource.getContents().add(comparisonCopy);
+ try {
+ resource.save(newHashMap());
+ } catch (IOException e) {
+ EMFCompareIDEUIPlugin.getDefault().log(e);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewer.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewer.java
index c2563c6..d3be19c 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewer.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewer.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012 Obeo.
+ * Copyright (c) 2012, 2013 Obeo.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -12,9 +12,13 @@ package org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer;
import static com.google.common.collect.Lists.newArrayList;
+import com.google.common.eventbus.EventBus;
+import com.google.common.eventbus.Subscribe;
+
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.EventObject;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -40,14 +44,18 @@ import org.eclipse.emf.compare.domain.impl.EMFCompareEditingDomain;
import org.eclipse.emf.compare.ide.EMFCompareIDE;
import org.eclipse.emf.compare.ide.ui.internal.EMFCompareConstants;
import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIPlugin;
-import org.eclipse.emf.compare.ide.ui.internal.actions.filter.DifferenceFilter;
-import org.eclipse.emf.compare.ide.ui.internal.actions.filter.FilterActionMenu;
-import org.eclipse.emf.compare.ide.ui.internal.actions.group.DifferenceGrouper;
-import org.eclipse.emf.compare.ide.ui.internal.actions.group.GroupActionMenu;
import org.eclipse.emf.compare.ide.ui.internal.actions.save.SaveComparisonModelAction;
import org.eclipse.emf.compare.ide.ui.internal.editor.ComparisonScopeInput;
import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.provider.ComparisonNode;
import org.eclipse.emf.compare.ide.ui.logical.EMFSynchronizationModel;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.actions.FilterActionMenu;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.actions.GroupActionMenu;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilterSelectionChangeEvent;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.StructureMergeViewerFilter;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.DefaultGroupProvider;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.StructureMergeViewerGrouper;
import org.eclipse.emf.compare.scope.IComparisonScope;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
@@ -55,6 +63,7 @@ import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory;
import org.eclipse.emf.edit.provider.resource.ResourceItemProviderAdapterFactory;
+import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider;
@@ -85,14 +94,26 @@ public class EMFCompareStructureMergeViewer extends DiffTreeViewer implements Co
* from {@link #createToolItems(ToolBarManager)} since that method is called from the super-constructor
* and we cannot init ourselves beforehand.
*/
- private DifferenceFilter differenceFilter;
+ private StructureMergeViewerFilter structureMergeViewerFilter;
/**
* This will be used by our adapter factory in order to group together the differences located under the
* Comparison. Note that this will be initialized from {@link #createToolItems(ToolBarManager)} since that
* method is called from the super-constructor and we cannot init ourselves beforehand.
*/
- private DifferenceGrouper differenceGrouper;
+ private StructureMergeViewerGrouper structureMergeViewerGrouper;
+
+ private MenuManager groupsMenuManager;
+
+ private MenuManager filtersMenuManager;
+
+ private GroupActionMenu groupActionMenu;
+
+ private DefaultGroupProvider defaultGroupProvider;
+
+ private FilterActionMenu filterActionMenu;
+
+ private EventBus eventBus;
/**
* @param parent
@@ -108,7 +129,7 @@ public class EMFCompareStructureMergeViewer extends DiffTreeViewer implements Co
setLabelProvider(new DelegatingStyledCellLabelProvider(
new EMFCompareStructureMergeViewerLabelProvider(fAdapterFactory, this)));
setContentProvider(new EMFCompareStructureMergeViewerContentProvider(fAdapterFactory,
- differenceGrouper));
+ structureMergeViewerGrouper));
if (parent instanceof CompareViewerSwitchingPane) {
fParent = (CompareViewerSwitchingPane)parent;
@@ -124,6 +145,39 @@ public class EMFCompareStructureMergeViewer extends DiffTreeViewer implements Co
// Wrap the defined comparer in our own.
setComparer(new DiffNodeComparer(super.getComparer()));
+
+ if (eventBus == null) {
+ eventBus = new EventBus();
+ eventBus.register(this);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Subscribe
+ public void recordFilterSelectionChange(IDifferenceFilterSelectionChangeEvent event) {
+ final Object property = getCompareConfiguration().getProperty(EMFCompareConstants.SELECTED_FILTERS);
+ final Collection<IDifferenceFilter> selectedFilters;
+ if (property == null) {
+ selectedFilters = new HashSet<IDifferenceFilter>();
+ } else {
+ selectedFilters = (Collection<IDifferenceFilter>)property;
+ }
+ switch (event.getAction()) {
+ case ADD:
+ selectedFilters.add(event.getFilter());
+ break;
+ case REMOVE:
+ selectedFilters.remove(event.getFilter());
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ getCompareConfiguration().setProperty(EMFCompareConstants.SELECTED_FILTERS, selectedFilters);
+ }
+
+ @Subscribe
+ public void recordGroupProviderSelectionChange(IDifferenceGroupProvider differenceGroupProvider) {
+ getCompareConfiguration().setProperty(EMFCompareConstants.SELECTED_GROUP, differenceGroupProvider);
}
/**
@@ -210,7 +264,7 @@ public class EMFCompareStructureMergeViewer extends DiffTreeViewer implements Co
editingDomain.getCommandStack().addCommandStackListener(this);
- compareInputChanged(compareResult);
+ compareInputChanged(scope, compareResult);
}
} else {
ResourceSet leftResourceSet = null;
@@ -260,6 +314,8 @@ public class EMFCompareStructureMergeViewer extends DiffTreeViewer implements Co
unload(originResourceSet);
getCompareConfiguration().setProperty(EMFCompareConstants.COMPARE_RESULT, null);
+ getCompareConfiguration().setProperty(EMFCompareConstants.SELECTED_FILTERS, null);
+ getCompareConfiguration().setProperty(EMFCompareConstants.SELECTED_GROUP, null);
fRoot = null;
}
}
@@ -269,7 +325,7 @@ public class EMFCompareStructureMergeViewer extends DiffTreeViewer implements Co
EMFCompareConstants.EDITING_DOMAIN);
editingDomain.getCommandStack().addCommandStackListener(this);
- compareInputChanged(input.getTarget());
+ compareInputChanged(null, input.getTarget());
}
void compareInputChanged(ComparisonScopeInput input, IProgressMonitor monitor) {
@@ -281,7 +337,7 @@ public class EMFCompareStructureMergeViewer extends DiffTreeViewer implements Co
EMFCompareConstants.COMPARATOR);
Comparison comparison = comparator.compare(input.getComparisonScope(), BasicMonitor
.toMonitor(monitor));
- compareInputChanged(comparison);
+ compareInputChanged(null, comparison);
}
private static void unload(ResourceSet resourceSet) {
@@ -303,9 +359,11 @@ public class EMFCompareStructureMergeViewer extends DiffTreeViewer implements Co
return null;
}
- void compareInputChanged(final Comparison comparison) {
- getCompareConfiguration().setProperty(EMFCompareConstants.COMPARE_RESULT, comparison);
+ void compareInputChanged(final IComparisonScope scope, final Comparison comparison) {
fRoot = fAdapterFactory.adapt(comparison, ICompareInput.class);
+ groupActionMenu.createActions(scope, comparison);
+ filterActionMenu.createActions(scope, comparison);
+ getCompareConfiguration().setProperty(EMFCompareConstants.COMPARE_RESULT, comparison);
getCompareConfiguration().getContainer().runAsynchronously(new IRunnableWithProgress() {
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
@@ -359,44 +417,92 @@ public class EMFCompareStructureMergeViewer extends DiffTreeViewer implements Co
@Override
protected void createToolItems(ToolBarManager toolbarManager) {
super.createToolItems(toolbarManager);
-
+ groupActionMenu = new GroupActionMenu(getStructureMergeViewerGrouper(), getGroupsMenuManager(),
+ getDefaultGroupProvider());
+ filterActionMenu = new FilterActionMenu(getStructureMergeViewerFilter(), getFiltersMenuManager());
toolbarManager.add(new SaveComparisonModelAction(getCompareConfiguration()));
- toolbarManager.add(new GroupActionMenu(getDifferenceGrouper()));
- toolbarManager.add(new FilterActionMenu(getDifferenceFilter()));
+ toolbarManager.add(groupActionMenu);
+ toolbarManager.add(filterActionMenu);
}
/**
- * Returns the difference filter that is to be applied on the structure viewer.
+ * Returns the viewer filter that is to be applied on the structure viewer.
* <p>
* Note that this will be called from {@link #createToolItems(ToolBarManager)}, which is called from the
- * super-constructor, when we have had no time to initialize the {@link #differenceFilter} field.
+ * super-constructor, when we have had no time to initialize the {@link #structureMergeViewerFilter}
+ * field.
* </p>
*
* @return The difference filter that is to be applied on the structure viewer.
*/
- protected DifferenceFilter getDifferenceFilter() {
- if (differenceFilter == null) {
- differenceFilter = new DifferenceFilter();
- differenceFilter.install(this);
+ protected StructureMergeViewerFilter getStructureMergeViewerFilter() {
+ if (structureMergeViewerFilter == null) {
+ if (eventBus == null) {
+ eventBus = new EventBus();
+ eventBus.register(this);
+ }
+ structureMergeViewerFilter = new StructureMergeViewerFilter(eventBus);
+ structureMergeViewerFilter.install(this);
}
- return differenceFilter;
+ return structureMergeViewerFilter;
}
/**
- * Returns the difference grouper that is to be applied on the structure viewer.
+ * Returns the viewer grouper that is to be applied on the structure viewer.
* <p>
* Note that this will be called from {@link #createToolItems(ToolBarManager)}, which is called from the
- * super-constructor, when we have had no time to initialize the {@link #differenceGrouper} field.
+ * super-constructor, when we have had no time to initialize the {@link #structureMergeViewerGrouper}
+ * field.
* </p>
*
- * @return The difference grouper that is to be applied on the structure viewer.
+ * @return The viewer grouper grouper that is to be applied on the structure viewer.
+ */
+ protected StructureMergeViewerGrouper getStructureMergeViewerGrouper() {
+ if (structureMergeViewerGrouper == null) {
+ if (eventBus == null) {
+ eventBus = new EventBus();
+ eventBus.register(this);
+ }
+ structureMergeViewerGrouper = new StructureMergeViewerGrouper(eventBus);
+ structureMergeViewerGrouper.install(this);
+ }
+ return structureMergeViewerGrouper;
+ }
+
+ /**
+ * Returns the menu manager that is to be applied to groups on the structure viewer.
+ *
+ * @return The menu manager that is to be applied to groups on the structure viewer.
+ */
+ public MenuManager getGroupsMenuManager() {
+ if (groupsMenuManager == null) {
+ groupsMenuManager = new MenuManager();
+ }
+ return groupsMenuManager;
+ }
+
+ /**
+ * Returns the menu manager that is to be applied to filters on the structure viewer.
+ *
+ * @return The menu manager that is to be applied to filters on the structure viewer.
+ */
+ public MenuManager getFiltersMenuManager() {
+ if (filtersMenuManager == null) {
+ filtersMenuManager = new MenuManager();
+ }
+ return filtersMenuManager;
+ }
+
+ /**
+ * Returns the default group provider that is to be applied on the structure viewer.
+ *
+ * @return The default group provider that is to be applied on the structure viewer.
*/
- protected DifferenceGrouper getDifferenceGrouper() {
- if (differenceGrouper == null) {
- differenceGrouper = new DifferenceGrouper();
- differenceGrouper.install(this);
+ public DefaultGroupProvider getDefaultGroupProvider() {
+ if (defaultGroupProvider == null) {
+ defaultGroupProvider = new DefaultGroupProvider();
}
- return differenceGrouper;
+ return defaultGroupProvider;
}
/**
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewerContentProvider.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewerContentProvider.java
index 435ea02..562b32a 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewerContentProvider.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewerContentProvider.java
@@ -24,19 +24,19 @@ import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.compare.Comparison;
import org.eclipse.emf.compare.Diff;
-import org.eclipse.emf.compare.ide.ui.internal.actions.group.DifferenceGroup;
-import org.eclipse.emf.compare.ide.ui.internal.actions.group.DifferenceGrouper;
import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.provider.ComparisonNode;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.DifferenceGroup;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.StructureMergeViewerGrouper;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
class EMFCompareStructureMergeViewerContentProvider extends AdapterFactoryContentProvider {
- private final DifferenceGrouper fDifferenceGrouper;
+ private final StructureMergeViewerGrouper fViewerGrouper;
EMFCompareStructureMergeViewerContentProvider(AdapterFactory adapterFactory,
- DifferenceGrouper differenceGrouper) {
+ StructureMergeViewerGrouper structureMergeViewerGrouper) {
super(adapterFactory);
- this.fDifferenceGrouper = differenceGrouper;
+ this.fViewerGrouper = structureMergeViewerGrouper;
}
@Override
@@ -58,7 +58,7 @@ class EMFCompareStructureMergeViewerContentProvider extends AdapterFactoryConten
final boolean ret;
if (element instanceof ComparisonNode) {
Comparison target = ((ComparisonNode)element).getTarget();
- final Iterable<? extends DifferenceGroup> groups = fDifferenceGrouper.getGroups(target);
+ final Iterable<? extends DifferenceGroup> groups = fViewerGrouper.getGroups(target);
if (isEmpty(groups)) {
ret = super.hasChildren(((Adapter)element).getTarget());
} else {
@@ -79,7 +79,7 @@ class EMFCompareStructureMergeViewerContentProvider extends AdapterFactoryConten
final Object[] ret;
if (element instanceof ComparisonNode) {
Comparison target = ((ComparisonNode)element).getTarget();
- final Iterable<? extends DifferenceGroup> groups = fDifferenceGrouper.getGroups(target);
+ final Iterable<? extends DifferenceGroup> groups = fViewerGrouper.getGroups(target);
if (!isEmpty(groups)) {
ret = Iterables.toArray(groups, DifferenceGroup.class);
} else {
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewerLabelProvider.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewerLabelProvider.java
index 2d4fde5..a6d58f4 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewerLabelProvider.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewerLabelProvider.java
@@ -1,149 +1,149 @@
-/*******************************************************************************
- * Copyright (c) 2012 Obeo.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Obeo - initial API and implementation
- *******************************************************************************/
-package org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer;
-
-import com.google.common.base.Preconditions;
-
-import org.eclipse.emf.common.notify.Adapter;
-import org.eclipse.emf.common.notify.AdapterFactory;
-import org.eclipse.emf.common.notify.Notifier;
-import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIPlugin;
-import org.eclipse.emf.compare.ide.ui.internal.actions.group.DifferenceGroup;
-import org.eclipse.emf.compare.ide.ui.internal.util.StyledStringConverter;
-import org.eclipse.emf.compare.provider.IItemStyledLabelProvider;
-import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
-import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider;
-import org.eclipse.jface.viewers.StyledString;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.Image;
-
-class EMFCompareStructureMergeViewerLabelProvider extends AdapterFactoryLabelProvider.FontAndColorProvider implements IStyledLabelProvider {
-
- /**
- * @param adapterFactory
- */
- public EMFCompareStructureMergeViewerLabelProvider(AdapterFactory adapterFactory, Viewer viewer) {
- super(adapterFactory, viewer);
- }
-
- @Override
- public String getText(Object element) {
- return getStyledText(element).getString();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#getFont(java.lang.Object)
- */
- @Override
- public Font getFont(Object object) {
- if (object instanceof Adapter) {
- return super.getFont(((Adapter)object).getTarget());
- }
- return super.getFont(object);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#getForeground(java.lang.Object)
- */
- @Override
- public Color getForeground(Object object) {
- if (object instanceof Adapter) {
- return super.getForeground(((Adapter)object).getTarget());
- }
- return super.getForeground(object);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#getBackground(java.lang.Object)
- */
- @Override
- public Color getBackground(Object object) {
- if (object instanceof Adapter) {
- return super.getBackground(((Adapter)object).getTarget());
- }
- return super.getBackground(object);
- }
-
- @Override
- public Image getImage(Object element) {
- final Image ret;
- if (element instanceof Adapter) {
- ret = super.getImage(((Adapter)element).getTarget());
- } else if (element instanceof DifferenceGroup) {
- final Image groupImage = ((DifferenceGroup)element).getImage();
- if (groupImage != null) {
- ret = groupImage;
- } else {
- ret = EMFCompareIDEUIPlugin.getDefault().getImage("icons/full/toolb16/group.gif"); //$NON-NLS-1$
- }
- } else {
- ret = super.getImage(element);
- }
-
- return ret;
- }
-
- public StyledString getStyledText(Object element) {
- final StyledString ret;
- if (element instanceof Adapter) {
- Notifier target = ((Adapter)element).getTarget();
- StyledString styledText = getStyledText(getAdapterFactory(), target);
- if (styledText == null) {
- ret = new StyledString(super.getText(target));
- } else {
- ret = styledText;
- }
- } else if (element instanceof DifferenceGroup) {
- ret = new StyledString(((DifferenceGroup)element).getName());
- } else {
- ret = new StyledString(super.getText(element));
- }
- return ret;
-
- }
-
- /**
- * Returns the styled text string of the given <code>object</code> by adapting it to
- * {@link IItemStyledLabelProvider} and asking for its
- * {@link IItemStyledLabelProvider#getStyledText(Object) text}. Returns null if <code>object</code> is
- * null.
- *
- * @param adapterFactory
- * the adapter factory to adapt from
- * @param object
- * the object from which we want a text
- * @return the text, or null if object is null.
- * @throws NullPointerException
- * if <code>adapterFactory</code> is null.
- */
- private static StyledString getStyledText(final AdapterFactory adapterFactory, final Object object) {
- Preconditions.checkNotNull(adapterFactory);
- if (object == null) {
- return null;
- }
-
- Object itemStyledLabelProvider = adapterFactory.adapt(object, IItemStyledLabelProvider.class);
- if (itemStyledLabelProvider instanceof IItemStyledLabelProvider) {
- StyledStringConverter stringConverter = new StyledStringConverter();
- return stringConverter.toJFaceStyledString(((IItemStyledLabelProvider)itemStyledLabelProvider)
- .getStyledText(object));
- }
- return null;
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer;
+
+import com.google.common.base.Preconditions;
+
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.emf.compare.ide.ui.internal.util.StyledStringConverter;
+import org.eclipse.emf.compare.provider.IItemStyledLabelProvider;
+import org.eclipse.emf.compare.rcp.ui.EMFCompareRCPUIPlugin;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.DifferenceGroup;
+import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
+import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider;
+import org.eclipse.jface.viewers.StyledString;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+
+class EMFCompareStructureMergeViewerLabelProvider extends AdapterFactoryLabelProvider.FontAndColorProvider implements IStyledLabelProvider {
+
+ /**
+ * @param adapterFactory
+ */
+ public EMFCompareStructureMergeViewerLabelProvider(AdapterFactory adapterFactory, Viewer viewer) {
+ super(adapterFactory, viewer);
+ }
+
+ @Override
+ public String getText(Object element) {
+ return getStyledText(element).getString();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#getFont(java.lang.Object)
+ */
+ @Override
+ public Font getFont(Object object) {
+ if (object instanceof Adapter) {
+ return super.getFont(((Adapter)object).getTarget());
+ }
+ return super.getFont(object);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#getForeground(java.lang.Object)
+ */
+ @Override
+ public Color getForeground(Object object) {
+ if (object instanceof Adapter) {
+ return super.getForeground(((Adapter)object).getTarget());
+ }
+ return super.getForeground(object);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#getBackground(java.lang.Object)
+ */
+ @Override
+ public Color getBackground(Object object) {
+ if (object instanceof Adapter) {
+ return super.getBackground(((Adapter)object).getTarget());
+ }
+ return super.getBackground(object);
+ }
+
+ @Override
+ public Image getImage(Object element) {
+ final Image ret;
+ if (element instanceof Adapter) {
+ ret = super.getImage(((Adapter)element).getTarget());
+ } else if (element instanceof DifferenceGroup) {
+ final Image groupImage = ((DifferenceGroup)element).getImage();
+ if (groupImage != null) {
+ ret = groupImage;
+ } else {
+ ret = EMFCompareRCPUIPlugin.getImage("icons/full/toolb16/group.gif"); //$NON-NLS-1$
+ }
+ } else {
+ ret = super.getImage(element);
+ }
+
+ return ret;
+ }
+
+ public StyledString getStyledText(Object element) {
+ final StyledString ret;
+ if (element instanceof Adapter) {
+ Notifier target = ((Adapter)element).getTarget();
+ StyledString styledText = getStyledText(getAdapterFactory(), target);
+ if (styledText == null) {
+ ret = new StyledString(super.getText(target));
+ } else {
+ ret = styledText;
+ }
+ } else if (element instanceof DifferenceGroup) {
+ ret = new StyledString(((DifferenceGroup)element).getName());
+ } else {
+ ret = new StyledString(super.getText(element));
+ }
+ return ret;
+
+ }
+
+ /**
+ * Returns the styled text string of the given <code>object</code> by adapting it to
+ * {@link IItemStyledLabelProvider} and asking for its
+ * {@link IItemStyledLabelProvider#getStyledText(Object) text}. Returns null if <code>object</code> is
+ * null.
+ *
+ * @param adapterFactory
+ * the adapter factory to adapt from
+ * @param object
+ * the object from which we want a text
+ * @return the text, or null if object is null.
+ * @throws NullPointerException
+ * if <code>adapterFactory</code> is null.
+ */
+ private static StyledString getStyledText(final AdapterFactory adapterFactory, final Object object) {
+ Preconditions.checkNotNull(adapterFactory);
+ if (object == null) {
+ return null;
+ }
+
+ Object itemStyledLabelProvider = adapterFactory.adapt(object, IItemStyledLabelProvider.class);
+ if (itemStyledLabelProvider instanceof IItemStyledLabelProvider) {
+ StyledStringConverter stringConverter = new StyledStringConverter();
+ return stringConverter.toJFaceStyledString(((IItemStyledLabelProvider)itemStyledLabelProvider)
+ .getStyledText(object));
+ }
+ return null;
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.compare.rcp.ui/META-INF/MANIFEST.MF
index 0f4be94..5cea7b3 100644
--- a/plugins/org.eclipse.emf.compare.rcp.ui/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/META-INF/MANIFEST.MF
@@ -2,8 +2,8 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.emf.compare.rcp.ui;singleton:=true
-Bundle-Version: 2.1.0.qualifier
-Bundle-Activator: org.eclipse.emf.compare.rcp.ui.Activator
+Bundle-Version: 3.0.0.qualifier
+Bundle-Activator: org.eclipse.emf.compare.rcp.ui.EMFCompareRCPUIPlugin
Bundle-Vendor: %providerName
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Bundle-ActivationPolicy: lazy
@@ -11,10 +11,14 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="3.5.0",
org.eclipse.emf.edit.ui;bundle-version="2.5.0",
org.eclipse.emf.compare;bundle-version="2.0.1",
org.eclipse.emf.compare.edit;bundle-version="2.0.1",
- org.eclipse.ui,
org.eclipse.emf.ecore.xmi;bundle-version="2.5.0"
-Export-Package: org.eclipse.emf.compare.rcp.ui.mergeviewer,
- org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor
+Export-Package: org.eclipse.emf.compare.rcp.ui,
+ org.eclipse.emf.compare.rcp.ui.mergeviewer,
+ org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor,
+ org.eclipse.emf.compare.rcp.ui.structuremergeviewer.actions,
+ org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters,
+ org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups
Import-Package: com.google.common.base;version="[10.0.0,11.0.0)",
com.google.common.cache;version="[10.0.0,11.0.0)",
- com.google.common.collect;version="[10.0.0,11.0.0)"
+ com.google.common.collect;version="[10.0.0,11.0.0)",
+ com.google.common.eventbus;version="[10.0.0,11.0.0)"
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/build.properties b/plugins/org.eclipse.emf.compare.rcp.ui/build.properties
index 5ebcb2d..06dc0bb 100644
--- a/plugins/org.eclipse.emf.compare.rcp.ui/build.properties
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/build.properties
@@ -1,7 +1,12 @@
-source.. = src/
-output.. = bin/
-bin.includes = META-INF/,\
- plugin.properties,\
- .,\
- about.html
-src.includes = about.html
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ plugin.properties,\
+ .,\
+ about.html,\
+ plugin.xml,\
+ icons/,\
+ schema/
+src.includes = about.html,\
+ icons/,\
+ schema/
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/toolb16/filter.gif b/plugins/org.eclipse.emf.compare.rcp.ui/icons/full/toolb16/filter.gif
index 6fe6f0e..6fe6f0e 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/toolb16/filter.gif
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/icons/full/toolb16/filter.gif
Binary files differ
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/toolb16/group.gif b/plugins/org.eclipse.emf.compare.rcp.ui/icons/full/toolb16/group.gif
index 2e1e2b9..2e1e2b9 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/toolb16/group.gif
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/icons/full/toolb16/group.gif
Binary files differ
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/plugin.xml b/plugins/org.eclipse.emf.compare.rcp.ui/plugin.xml
new file mode 100644
index 0000000..bb20670
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/plugin.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+
+<!--
+ Copyright (c) 2013 Obeo.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Eclipse Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/epl-v10.html
+
+ Contributors:
+ Obeo - initial API and implementation
+-->
+
+<plugin>
+ <extension-point id="groups" name="EMF Compare Groups" schema="schema/groups.exsd"/>
+ <extension-point id="filters" name="EMF Compare Filters" schema="schema/filters.exsd"/>
+ <extension
+ point="org.eclipse.emf.compare.rcp.ui.groups">
+ <group
+ activeByDefault="false"
+ class="org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.KindGroupProvider"
+ label="By Kind">
+ </group>
+ <group
+ activeByDefault="false"
+ class="org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.MetamodelGroupProvider"
+ label="By Metaclass">
+ </group>
+ <group
+ activeByDefault="false"
+ class="org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.ThreeWayComparisonGroupProvider"
+ label="By Side">
+ </group>
+ </extension>
+ <extension
+ point="org.eclipse.emf.compare.rcp.ui.filters">
+ <filter
+ activeByDefault="false"
+ class="org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.ChangedElementsFilter"
+ label="Changed elements">
+ </filter>
+ <filter
+ activeByDefault="false"
+ class="org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.AddedElementsFilter"
+ label="Added elements">
+ </filter>
+ <filter
+ activeByDefault="false"
+ class="org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.RemovedElementsFilter"
+ label="Removed elements">
+ </filter>
+ <filter
+ activeByDefault="false"
+ class="org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.MovedElementsFilter"
+ label="Moved elements">
+ </filter>
+ <filter
+ activeByDefault="true"
+ class="org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.MatchedResourcesFilter"
+ label="Resource Mappings">
+ </filter>
+ </extension>
+</plugin>
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/pom.xml b/plugins/org.eclipse.emf.compare.rcp.ui/pom.xml
index c090d25..5ccefac 100644
--- a/plugins/org.eclipse.emf.compare.rcp.ui/pom.xml
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/pom.xml
@@ -10,7 +10,7 @@
</parent>
<groupId>org.eclipse.emf.compare</groupId>
<artifactId>org.eclipse.emf.compare.rcp.ui</artifactId>
- <version>2.1.0-SNAPSHOT</version>
+ <version>3.0.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
<build>
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/schema/filters.exsd b/plugins/org.eclipse.emf.compare.rcp.ui/schema/filters.exsd
new file mode 100644
index 0000000..01c561f
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/schema/filters.exsd
@@ -0,0 +1,116 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.emf.compare.rcp.ui" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.emf.compare.rcp.ui" id="filters" name="EMF Compare Filters"/>
+ </appinfo>
+ <documentation>
+ [Enter description of this extension point.]
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="filter" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute translatable="true"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="filter">
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ A class that implements org.eclipse.emf.compare.ide.ui.internal.actions.filter.FilterActionProvider.
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.emf.compare.ide.ui.internal.actions.filter.FilterActionProvider"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="label" type="string" use="required">
+ <annotation>
+ <documentation>
+ A human-readable label for this filter This will be displayed in the EMF Compare UI.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="activeByDefault" type="boolean" use="required">
+ <annotation>
+ <documentation>
+ The initial activation state of the filter.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="examples"/>
+ </appinfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="apiinfo"/>
+ </appinfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="implementation"/>
+ </appinfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+
+</schema>
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/schema/groups.exsd b/plugins/org.eclipse.emf.compare.rcp.ui/schema/groups.exsd
new file mode 100644
index 0000000..0a8b45f
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/schema/groups.exsd
@@ -0,0 +1,116 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.emf.compare.rcp.ui" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.emf.compare.rcp.ui" id="groups" name="EMF Compare Groups"/>
+ </appinfo>
+ <documentation>
+ [Enter description of this extension point.]
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="group" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute translatable="true"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="group">
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ A class that implements org.eclipse.emf.compare.ide.ui.internal.actions.group.DifferenceGroupProvider.
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.emf.compare.ide.ui.internal.actions.group.DifferenceGroupProvider"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="label" type="string" use="required">
+ <annotation>
+ <documentation>
+ A human-readable label for this group. This will be displayed in the EMF Compare UI.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="activeByDefault" type="boolean" use="required">
+ <annotation>
+ <documentation>
+ The initial activation state of the filter.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="examples"/>
+ </appinfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="apiinfo"/>
+ </appinfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="implementation"/>
+ </appinfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+
+</schema>
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/Activator.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/Activator.java
deleted file mode 100644
index f57c07f..0000000
--- a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/Activator.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/** ****************************************************************************
- * Copyright (c) 2012 Obeo.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Obeo - initial API and implementation
- *******************************************************************************/
-package org.eclipse.emf.compare.rcp.ui;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.ui.plugin.AbstractUIPlugin;
-import org.osgi.framework.BundleContext;
-
-/**
- * The activator class controls the plug-in life cycle.
- */
-public class Activator extends AbstractUIPlugin {
-
- /**
- * The plug-in ID.
- */
- public static final String PLUGIN_ID = "org.eclipse.emf.compare.rcp.ui"; //$NON-NLS-1$
-
- /**
- * the shared instance.
- */
- private static Activator plugin;
-
- /** keep track of resources that should be freed when exiting. */
- private static Map<String, Image> resourcesMapper = new HashMap<String, Image>();
-
- /**
- * 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;
- disposeCachedImages();
- super.stop(context);
- }
-
- /**
- * Returns the shared instance.
- *
- * @return the shared instance
- */
- public static Activator getDefault() {
- return plugin;
- }
-
- /**
- * <p>
- * returns a plugin image. The returned image does not need to be explicitly disposed.
- * </p>
- *
- * @param imagePath
- * : plugin relative path to the image
- * @return Image : plugin hosted image
- */
- public static Image getImage(String imagePath) {
- Image image = resourcesMapper.get(imagePath);
- if (image == null) {
- ImageDescriptor imageDescriptor = imageDescriptorFromPlugin(PLUGIN_ID, imagePath);
- image = imageDescriptor.createImage();
- resourcesMapper.put(imagePath, image);
- }
- return image;
- }
-
- /**
- * <p>
- * returns a plugin image descriptor.
- * </p>
- *
- * @param imagePath
- * : plugin relative path to the image
- * @return ImageDescriptor : image descriptor.
- */
- public static ImageDescriptor getImageDescriptor(String imagePath) {
- return imageDescriptorFromPlugin(PLUGIN_ID, imagePath);
- }
-
- /**
- * Dispose image with the given id.
- *
- * @param id
- * : dispose system resources associated with the image with the given id.
- */
- public static void disposeImage(String id) {
- Image image = resourcesMapper.remove(id);
- if (image != null) {
- image.dispose();
- }
- }
-
- /**
- * dispose system resources associated with cached images.
- */
- public static void disposeCachedImages() {
- Iterator<Image> iterator = resourcesMapper.values().iterator();
- while (iterator.hasNext()) {
- iterator.next().dispose();
- }
- resourcesMapper.clear();
- }
-
-}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/EMFCompareRCPUIPlugin.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/EMFCompareRCPUIPlugin.java
new file mode 100644
index 0000000..47c1831
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/EMFCompareRCPUIPlugin.java
@@ -0,0 +1,365 @@
+/** ****************************************************************************
+ * Copyright (c) 2012, 2013 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.rcp.ui;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.emf.compare.rcp.ui.internal.util.AbstractRegistryEventListener;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle.
+ *
+ * @since 3.0
+ */
+public class EMFCompareRCPUIPlugin extends AbstractUIPlugin {
+
+ /**
+ * The plug-in ID.
+ */
+ public static final String PLUGIN_ID = "org.eclipse.emf.compare.rcp.ui"; //$NON-NLS-1$
+
+ public static final String GROUP_PROVIDER_PPID = "groups"; //$NON-NLS-1$
+
+ public static final String FILTER_PROVIDER_PPID = "filters"; //$NON-NLS-1$
+
+ /**
+ * the shared instance.
+ */
+ private static EMFCompareRCPUIPlugin plugin;
+
+ /** keep track of resources that should be freed when exiting. */
+ private static Map<String, Image> resourcesMapper = new HashMap<String, Image>();
+
+ private AbstractRegistryEventListener groupProviderRegistryListener;
+
+ private IDifferenceGroupProvider.Registry groupProviderRegistry;
+
+ private AbstractRegistryEventListener filterRegistryListener;
+
+ private IDifferenceFilter.Registry filterRegistry;
+
+ /**
+ * The constructor.
+ */
+ public EMFCompareRCPUIPlugin() {
+
+ }
+
+ /*
+ * (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;
+
+ IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
+
+ groupProviderRegistry = new IDifferenceGroupProvider.RegistryImpl();
+
+ groupProviderRegistryListener = new DifferenceGroupProviderExtensionRegistryListener(PLUGIN_ID,
+ GROUP_PROVIDER_PPID);
+ extensionRegistry.addListener(groupProviderRegistryListener, PLUGIN_ID + "." + GROUP_PROVIDER_PPID); //$NON-NLS-1$
+ groupProviderRegistryListener.readRegistry(extensionRegistry);
+
+ filterRegistry = new IDifferenceFilter.RegistryImpl();
+
+ filterRegistryListener = new FilterExtensionRegistryListener(PLUGIN_ID, FILTER_PROVIDER_PPID);
+ extensionRegistry.addListener(filterRegistryListener, PLUGIN_ID + "." + FILTER_PROVIDER_PPID); //$NON-NLS-1$
+ filterRegistryListener.readRegistry(extensionRegistry);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ Platform.getExtensionRegistry().removeListener(filterRegistryListener);
+ filterRegistry = null;
+ Platform.getExtensionRegistry().removeListener(groupProviderRegistryListener);
+ groupProviderRegistry = null;
+
+ plugin = null;
+ disposeCachedImages();
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance.
+ *
+ * @return the shared instance
+ */
+ public static EMFCompareRCPUIPlugin getDefault() {
+ return plugin;
+ }
+
+ /**
+ * Log an {@link Exception} in the {@link #getLog() current logger}.
+ *
+ * @param e
+ * the exception to be logged.
+ */
+ public void log(Throwable e) {
+ getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, e.getMessage(), e));
+ }
+
+ /**
+ * Log the given message with the give severity level. Severity is one of {@link IStatus#INFO},
+ * {@link IStatus#WARNING} and {@link IStatus#ERROR}.
+ *
+ * @param severity
+ * the severity of the message
+ * @param message
+ * the message
+ */
+ public void log(int severity, String message) {
+ getLog().log(new Status(severity, PLUGIN_ID, message));
+ }
+
+ /**
+ * @return the groupProviderRegistry
+ */
+ public IDifferenceGroupProvider.Registry getDifferenceGroupProviderRegistry() {
+ return groupProviderRegistry;
+ }
+
+ public IDifferenceFilter.Registry getFilterActionRegistry() {
+ return filterRegistry;
+ }
+
+ /**
+ * <p>
+ * returns a plugin image. The returned image does not need to be explicitly disposed.
+ * </p>
+ *
+ * @param imagePath
+ * : plugin relative path to the image
+ * @return Image : plugin hosted image
+ */
+ public static Image getImage(String imagePath) {
+ Image image = resourcesMapper.get(imagePath);
+ if (image == null) {
+ ImageDescriptor imageDescriptor = imageDescriptorFromPlugin(PLUGIN_ID, imagePath);
+ image = imageDescriptor.createImage();
+ resourcesMapper.put(imagePath, image);
+ }
+ return image;
+ }
+
+ /**
+ * <p>
+ * returns a plugin image descriptor.
+ * </p>
+ *
+ * @param imagePath
+ * : plugin relative path to the image
+ * @return ImageDescriptor : image descriptor.
+ */
+ public static ImageDescriptor getImageDescriptor(String imagePath) {
+ return imageDescriptorFromPlugin(PLUGIN_ID, imagePath);
+ }
+
+ /**
+ * Dispose image with the given id.
+ *
+ * @param id
+ * : dispose system resources associated with the image with the given id.
+ */
+ public static void disposeImage(String id) {
+ Image image = resourcesMapper.remove(id);
+ if (image != null) {
+ image.dispose();
+ }
+ }
+
+ /**
+ * dispose system resources associated with cached images.
+ */
+ public static void disposeCachedImages() {
+ Iterator<Image> iterator = resourcesMapper.values().iterator();
+ while (iterator.hasNext()) {
+ iterator.next().dispose();
+ }
+ resourcesMapper.clear();
+ }
+
+ private class DifferenceGroupProviderExtensionRegistryListener extends AbstractRegistryEventListener {
+
+ static final String TAG_GROUP_PROVIDER = "group"; //$NON-NLS-1$
+
+ static final String ATT_CLASS = "class"; //$NON-NLS-1$
+
+ static final String ATT_LABEL = "label"; //$NON-NLS-1$
+
+ static final String ATT_ACTIVE = "activeByDefault"; //$NON-NLS-1$
+
+ /**
+ * @param pluginID
+ * @param extensionPointID
+ * @param registry
+ */
+ public DifferenceGroupProviderExtensionRegistryListener(String pluginID, String extensionPointID) {
+ super(pluginID, extensionPointID);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.internal.util.AbstractRegistryEventListener#readElement(org.eclipse.core.runtime.IConfigurationElement,
+ * org.eclipse.emf.compare.rcp.ui.internal.util.AbstractRegistryEventListener.Action)
+ */
+ @SuppressWarnings("boxing")
+ @Override
+ protected boolean readElement(IConfigurationElement element, Action b) {
+ if (element.getName().equals(TAG_GROUP_PROVIDER)) {
+ if (element.getAttribute(ATT_CLASS) == null) {
+ logMissingAttribute(element, ATT_CLASS);
+ } else if (element.getAttribute(ATT_LABEL) == null) {
+ logMissingAttribute(element, ATT_LABEL);
+ } else if (element.getAttribute(ATT_ACTIVE) == null) {
+ logMissingAttribute(element, ATT_ACTIVE);
+ } else {
+ switch (b) {
+ case ADD:
+ try {
+ IDifferenceGroupProvider provider = (IDifferenceGroupProvider)element
+ .createExecutableExtension(ATT_CLASS);
+ provider.setLabel(element.getAttribute(ATT_LABEL));
+ if (Boolean.valueOf(element.getAttribute(ATT_ACTIVE))) {
+ provider.setDefaultSelected(true);
+ } else {
+ provider.setDefaultSelected(false);
+ }
+ IDifferenceGroupProvider previous = groupProviderRegistry.add(provider);
+ if (previous != null) {
+ log(IStatus.WARNING, "The provider '" + provider.getClass().getName() //$NON-NLS-1$
+ + "' is registered twice."); //$NON-NLS-1$
+ }
+ } catch (CoreException e) {
+ logError(element, e.getMessage());
+ }
+ break;
+ case REMOVE:
+ groupProviderRegistry.remove(element.getAttribute(ATT_CLASS));
+ break;
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.internal.util.AbstractRegistryEventListener#logError(org.eclipse.core.runtime.IConfigurationElement,
+ * java.lang.String)
+ */
+ @Override
+ protected void logError(IConfigurationElement element, String string) {
+ log(IStatus.ERROR, string);
+ }
+ }
+
+ private class FilterExtensionRegistryListener extends AbstractRegistryEventListener {
+
+ static final String TAG_FILTER_ACTION = "filter"; //$NON-NLS-1$
+
+ static final String ATT_CLASS = "class"; //$NON-NLS-1$
+
+ static final String ATT_LABEL = "label"; //$NON-NLS-1$
+
+ static final String ATT_ACTIVE = "activeByDefault"; //$NON-NLS-1$
+
+ /**
+ * @param pluginID
+ * @param extensionPointID
+ * @param registry
+ */
+ public FilterExtensionRegistryListener(String pluginID, String extensionPointID) {
+ super(pluginID, extensionPointID);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.internal.util.AbstractRegistryEventListener#readElement(org.eclipse.core.runtime.IConfigurationElement,
+ * org.eclipse.emf.compare.rcp.ui.internal.util.AbstractRegistryEventListener.Action)
+ */
+ @SuppressWarnings("boxing")
+ @Override
+ protected boolean readElement(IConfigurationElement element, Action b) {
+ if (element.getName().equals(TAG_FILTER_ACTION)) {
+ if (element.getAttribute(ATT_CLASS) == null) {
+ logMissingAttribute(element, ATT_CLASS);
+ } else if (element.getAttribute(ATT_LABEL) == null) {
+ logMissingAttribute(element, ATT_LABEL);
+ } else if (element.getAttribute(ATT_ACTIVE) == null) {
+ logMissingAttribute(element, ATT_ACTIVE);
+ } else {
+ switch (b) {
+ case ADD:
+ try {
+ IDifferenceFilter filter = (IDifferenceFilter)element
+ .createExecutableExtension(ATT_CLASS);
+ filter.setLabel(element.getAttribute(ATT_LABEL));
+ if (Boolean.valueOf(element.getAttribute(ATT_ACTIVE))) {
+ filter.setDefaultSelected(true);
+ } else {
+ filter.setDefaultSelected(false);
+ }
+ IDifferenceFilter previous = filterRegistry.add(filter);
+ if (previous != null) {
+ log(IStatus.WARNING, "The filter '" + filter.getClass().getName() //$NON-NLS-1$
+ + "' is registered twice."); //$NON-NLS-1$
+ }
+ } catch (CoreException e) {
+ logError(element, e.getMessage());
+ }
+ break;
+ case REMOVE:
+ filterRegistry.remove(element.getAttribute(ATT_CLASS));
+ break;
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.internal.util.AbstractRegistryEventListener#logError(org.eclipse.core.runtime.IConfigurationElement,
+ * java.lang.String)
+ */
+ @Override
+ protected void logError(IConfigurationElement element, String string) {
+ log(IStatus.ERROR, string);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/util/AbstractRegistryEventListener.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/util/AbstractRegistryEventListener.java
new file mode 100644
index 0000000..f46606c
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/util/AbstractRegistryEventListener.java
@@ -0,0 +1,249 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.rcp.ui.internal.util;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IRegistryEventListener;
+
+/**
+ * Abstract utility class to listen to the {@link IExtensionRegistry}. It provides base implementation to
+ * {@link #added(IExtension[])} and {@link #removed(IExtension[])}. Users must implement
+ * {@link #readElement(IConfigurationElement, Action)} according to their extension schema.
+ * <p>
+ * The helper method {@link #readRegistry()} is browsing already registered extension to the extension
+ * registry making it easy to read the registry after having added the listener to it.
+ * <p>
+ * {@link #readRegistry()} is delegating to {@link #readElement(IConfigurationElement, Action)}.
+ *
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public abstract class AbstractRegistryEventListener implements IRegistryEventListener {
+
+ /**
+ * Enumeration that says if the {@link IConfigurationElement} is to be added or removed from the
+ * {@link IExtensionRegistry}.
+ *
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+ protected static enum Action {
+ /**
+ * The {@link IConfigurationElement} is to be added.
+ */
+ ADD,
+ /**
+ * The {@link IConfigurationElement} is to be removed.
+ */
+ REMOVE
+ }
+
+ /**
+ * The plugin ID which declare the extension point to be monitored.
+ */
+ private final String pluginID;
+
+ /**
+ * The extension point ID to be monitored.
+ */
+ private final String extensionPointID;
+
+ /**
+ * Creates a new registry event listener.
+ *
+ * @param pluginID
+ * The plugin ID which declare the extension point to be monitored.
+ * @param extensionPointID
+ * The extension point ID to be monitored
+ */
+ public AbstractRegistryEventListener(String pluginID, String extensionPointID) {
+ this.pluginID = pluginID;
+ this.extensionPointID = extensionPointID;
+ }
+
+ /**
+ * Reads the given registry and call {@link #readElement(IConfigurationElement, Action)} as the read
+ * {@link IConfigurationElement} were just added to it.
+ *
+ * @param extensionRegistry
+ * the registry to read.
+ */
+ public void readRegistry(IExtensionRegistry extensionRegistry) {
+ IExtensionPoint point = extensionRegistry.getExtensionPoint(pluginID, extensionPointID);
+ if (point != null) {
+ IConfigurationElement[] elements = point.getConfigurationElements();
+ for (int i = 0; i < elements.length; i++) {
+ internalReadElement(elements[i], Action.ADD);
+ }
+ }
+ }
+
+ /**
+ * Reads the given {@code element}. This method can be call when the element is added or remove. The
+ * {@code action} reflect it. It returns true if the element is recognized as valid regarding the
+ * monitored extension point. It will be call on sub elements recursively for all recognized ones.
+ *
+ * @param element
+ * the element to be read.
+ * @param action
+ * is the element added or removed.
+ * @return true if the element is recognized as valid regarding the monitored extension point.
+ */
+ protected abstract boolean readElement(IConfigurationElement element, Action action);
+
+ /**
+ * Reads the given element and, if recognized, browse recursively the children and try to read it.
+ *
+ * @param element
+ * the element to be read.
+ * @param action
+ * is the element added or removed.
+ */
+ private void internalReadElement(IConfigurationElement element, Action action) {
+ boolean recognized = readElement(element, action);
+ if (recognized) {
+ IConfigurationElement[] children = element.getChildren();
+ for (int i = 0; i < children.length; ++i) {
+ internalReadElement(children[i], action);
+ }
+ } else {
+ logError(element, "Error processing extension: " + element); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Delegates the logging of a missing attribute to {@link #logError(IConfigurationElement, String)} with a
+ * proper message.
+ *
+ * @param element
+ * the element to which an attribute is missing.
+ * @param attributeName
+ * the name of the missing attribute.
+ */
+ protected void logMissingAttribute(IConfigurationElement element, String attributeName) {
+ logError(element, "The required attribute '" + attributeName + "' not defined"); //$NON-NLS-1$//$NON-NLS-2$
+ }
+
+ /**
+ * Log the error to any mean (often the current plugin logger).
+ *
+ * @param element
+ * the element from which comes to the error.
+ * @param string
+ * the message to be logged.
+ */
+ protected abstract void logError(IConfigurationElement element, String string);
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.core.runtime.IRegistryEventListener#added(org.eclipse.core.runtime.IExtension[])
+ */
+ public void added(IExtension[] extensions) {
+ for (IExtension extension : extensions) {
+ if (extension.getExtensionPointUniqueIdentifier().equals(extensionPointID)) {
+ IConfigurationElement[] configurationElement = extension.getConfigurationElements();
+ for (int j = 0; j < configurationElement.length; ++j) {
+ internalReadElement(configurationElement[j], Action.ADD);
+ }
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.core.runtime.IRegistryEventListener#removed(org.eclipse.core.runtime.IExtension[])
+ */
+ public void removed(IExtension[] extensions) {
+ for (IExtension extension : extensions) {
+ if (extension.getExtensionPointUniqueIdentifier().equals(extensionPointID)) {
+ IConfigurationElement[] configurationElement = extension.getConfigurationElements();
+ for (int j = 0; j < configurationElement.length; ++j) {
+ internalReadElement(configurationElement[j], Action.REMOVE);
+ }
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.core.runtime.IRegistryEventListener#added(org.eclipse.core.runtime.IExtensionPoint[])
+ */
+ public void added(IExtensionPoint[] extensionPoints) {
+ // no need to listen to this.
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.core.runtime.IRegistryEventListener#removed(org.eclipse.core.runtime.IExtensionPoint[])
+ */
+ public void removed(IExtensionPoint[] extensionPoints) {
+ // no need to listen to this.
+ }
+
+ /**
+ * Simple utility class to create proxy of extension that are
+ * {@link IConfigurationElement#createExecutableExtension(String) instantiable}.
+ * <p>
+ * No test of the {@link IConfigurationElement#isValid() validity} of the wrapped
+ * {@link IConfigurationElement} is performed. As such you should always extend this class while listening
+ * to the {@link IExtensionRegistry} and react properly the removal of the wrapped
+ * {@link IConfigurationElement}.
+ *
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+ public static class PluginClassDescriptor {
+ /**
+ * The element from which create an instance.
+ */
+ protected IConfigurationElement element;
+
+ /**
+ * The name of the attribute that holds the class full name to be instantiated.
+ */
+ protected String attributeName;
+
+ /**
+ * Creates a new descriptor for given element keeping the class name to be instantiated in an
+ * attribute named {@code attributeName}.
+ *
+ * @param element
+ * The element from which create an instance.
+ * @param attributeName
+ * The name of the attribute that holds the class full name to be instantiated.
+ */
+ public PluginClassDescriptor(IConfigurationElement element, String attributeName) {
+ this.element = element;
+ this.attributeName = attributeName;
+ }
+
+ /**
+ * Creates a new instance.
+ *
+ * @return the new instance.
+ * @throws RuntimeException
+ * wraps a CoreException if an instance of the executable extension could not be created
+ * for any reason.
+ */
+ public Object createInstance() {
+ try {
+ return element.createExecutableExtension(attributeName);
+ } catch (CoreException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/EObjectAccessor.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/EObjectAccessor.java
index b79db66..6579c2a 100644
--- a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/EObjectAccessor.java
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/EObjectAccessor.java
@@ -1,287 +1,287 @@
-/*******************************************************************************
- * Copyright (c) 2012 Obeo.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Obeo - initial API and implementation
- *******************************************************************************/
-package org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor;
-
-import com.google.common.collect.Maps;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.StringWriter;
-import java.util.Iterator;
-import java.util.List;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.emf.common.notify.Adapter;
-import org.eclipse.emf.common.notify.AdapterFactory;
-import org.eclipse.emf.common.util.URI;
-import org.eclipse.emf.compare.Match;
-import org.eclipse.emf.compare.rcp.ui.Activator;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
-import org.eclipse.emf.compare.utils.ReferenceUtil;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EReference;
-import org.eclipse.emf.ecore.util.EcoreUtil;
-import org.eclipse.emf.ecore.util.InternalEList;
-import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
-import org.eclipse.emf.edit.provider.IItemLabelProvider;
-import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry;
-import org.eclipse.swt.graphics.Image;
-
-/**
- * A {@link ITypedElement} that can be used as input of TreeContentMergeViewer. It is implementing
- * {@link IStreamContentAccessor} to be able to compare XMI serialization of wrapped {@link EObject}.
- *
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- */
-public class EObjectAccessor implements IEObjectAccessor {
-
- /**
- * The wrapped {@link EObject}.
- */
- // private final EObject fEObject;
-
- /**
- * The adapter factory that will be used to get the name and the image of the wrapped EObject.
- */
- private final AdapterFactory fAdapterFactory;
-
- private final Match fOwnerMatch;
-
- private final MergeViewerSide fSide;
-
- /**
- * Creates a new object wrapping the given <code>eObject</code>.
- *
- * @param adapterFactory
- * the adapter factory to get the image from.
- * @param eObject
- * the {@link EObject} to wrap.
- */
- public EObjectAccessor(AdapterFactory adapterFactory, Match match, MergeViewerSide side) {
- fAdapterFactory = adapterFactory;
- fOwnerMatch = match;
- fSide = side;
- }
-
- /**
- * @return the fSide
- */
- protected final MergeViewerSide getSide() {
- return fSide;
- }
-
- protected EObject getEObject(MergeViewerSide side) {
- final EObject eObject;
- switch (side) {
- case ANCESTOR:
- eObject = fOwnerMatch.getOrigin();
- break;
- case LEFT:
- eObject = fOwnerMatch.getLeft();
- break;
- case RIGHT:
- eObject = fOwnerMatch.getRight();
- break;
- default:
- throw new IllegalStateException();
- }
- return eObject;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.compare.ITypedElement#getName()
- */
- public String getName() {
- return getEObject(getSide()).eClass().getName();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.compare.ITypedElement#getImage()
- */
- public Image getImage() {
- Adapter adapter = fAdapterFactory.adapt(getEObject(), IItemLabelProvider.class);
- if (adapter instanceof IItemLabelProvider) {
- Object image = ((IItemLabelProvider)adapter).getImage(getEObject());
- return ExtendedImageRegistry.getInstance().getImage(image);
- }
- return null;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.provider.IEObjectAccessor#getEObject()
- */
- public EObject getEObject() {
- return getEObject(getSide());
- }
-
- public InputStream getContents() throws CoreException {
- XMIResourceImpl r = new XMIResourceImpl(URI.createURI("dummy.xmi")); //$NON-NLS-1$
-
- final ProperContentCopier copier = new ProperContentCopier();
- final EObject copy = copier.copy(getEObject());
- copier.copyReferences();
-
- r.getContents().add(copy);
- StringWriter sw = new StringWriter();
- try {
- r.save(sw, Maps.newHashMap());
- } catch (IOException e) {
- throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e));
- }
- // Assume that the platform locale is appropriate.
- return new ByteArrayInputStream(sw.toString().getBytes());
- }
-
- private class ProperContentCopier extends EcoreUtil.Copier {
- /** Generated SUID. */
- private static final long serialVersionUID = -5458049632291531717L;
-
- public ProperContentCopier() {
- this.resolveProxies = false;
- }
-
- /**
- * {@inheritDoc}
- * <p>
- * Implementation mostly copy/pasted from EcoreUtil.Copier#copyContainment(EReference, EObject,
- * EObject). We're only making sure not to resolve any proxy to another resource.
- * </p>
- *
- * @see org.eclipse.emf.ecore.util.EcoreUtil.Copier#copyContainment(org.eclipse.emf.ecore.EReference,
- * org.eclipse.emf.ecore.EObject, org.eclipse.emf.ecore.EObject)
- */
- @Override
- protected void copyContainment(EReference eReference, EObject eObject, EObject copyEObject) {
- if (!eObject.eIsSet(eReference)) {
- return;
- }
-
- if (eReference.isMany()) {
- final Iterator<EObject> source = new BoundProperContentIterator(eObject, eReference);
- @SuppressWarnings("unchecked")
- List<EObject> target = (List<EObject>)copyEObject.eGet(getTarget(eReference), resolveProxies);
- if (!source.hasNext()) {
- target.clear();
- } else {
- while (source.hasNext()) {
- final EObject next = source.next();
- target.add(copy(next));
- }
- }
- } else {
- /*
- * TODO untested yet as this is a rare case. EMF ignors the "resolve" argument of eGet for
- * multi-valued containment features. Will it honor it for unique features?
- */
- EObject childEObject = (EObject)eObject.eGet(eReference, resolveProxies);
- if (childEObject == null) {
- copyEObject.eSet(getTarget(eReference), null);
- } else {
- copyEObject.eSet(getTarget(eReference), copy(childEObject));
- }
- }
- }
-
- /**
- * {@inheritDoc}
- * <p>
- * Implementation mostly copy/pasted from EcoreUtil.Copier#copyContainment(EReference, EObject,
- * EObject). We're only making sure not to resolve any proxy to another resource.
- * </p>
- *
- * @see org.eclipse.emf.ecore.util.EcoreUtil.Copier#copyReference(org.eclipse.emf.ecore.EReference,
- * org.eclipse.emf.ecore.EObject, org.eclipse.emf.ecore.EObject)
- */
- @Override
- protected void copyReference(EReference eReference, EObject eObject, EObject copyEObject) {
- if (!eObject.eIsSet(eReference)) {
- return;
- }
-
- if (eReference.isMany()) {
- final Iterator<EObject> source = new BoundProperContentIterator(eObject, eReference);
- @SuppressWarnings("unchecked")
- InternalEList<EObject> target = (InternalEList<EObject>)copyEObject.eGet(
- getTarget(eReference), false);
- if (!source.hasNext()) {
- target.clear();
- } else {
- boolean isBidirectional = eReference.getEOpposite() != null;
- int index = 0;
- while (source.hasNext()) {
- final EObject next = source.next();
- final EObject copyReferencedEObject = get(next);
-
- if (copyReferencedEObject == null) {
- if (useOriginalReferences && !isBidirectional) {
- target.addUnique(index, next);
- ++index;
- }
- } else {
- if (isBidirectional) {
- int position = target.indexOf(copyReferencedEObject);
- if (position == -1) {
- target.addUnique(index, copyReferencedEObject);
- } else if (index != position) {
- target.move(index, copyReferencedEObject);
- }
- } else {
- target.addUnique(index, copyReferencedEObject);
- }
- ++index;
- }
- }
- }
- } else {
- /*
- * TODO untested yet as this is a rare case. EMF ignors the "resolve" argument of eGet for
- * multi-valued containment features. Will it honor it for unique features?
- */
- final Object referencedEObject = eObject.eGet(eReference, resolveProxies);
- if (referencedEObject == null) {
- copyEObject.eSet(getTarget(eReference), null);
- } else {
- final Object copyReferencedEObject = get(referencedEObject);
- if (copyReferencedEObject == null) {
- if (useOriginalReferences && eReference.getEOpposite() == null) {
- copyEObject.eSet(getTarget(eReference), referencedEObject);
- }
- } else {
- copyEObject.eSet(getTarget(eReference), copyReferencedEObject);
- }
- }
- }
- }
- }
-
- private final class BoundProperContentIterator extends EcoreUtil.ProperContentIterator<EObject> {
- public BoundProperContentIterator(EObject eObject, EReference eReference) {
- super(eObject, false);
- // Calling super-constructor since we need to, but we'll override what it just did
- @SuppressWarnings("unchecked")
- final List<EObject> contents = (List<EObject>)ReferenceUtil.safeEGet(eObject, eReference);
- if (contents instanceof InternalEList<?>) {
- this.iterator = ((InternalEList<EObject>)contents).basicIterator();
- } else {
- this.iterator = contents.iterator();
- }
- }
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2012 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor;
+
+import com.google.common.collect.Maps;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.compare.Match;
+import org.eclipse.emf.compare.rcp.ui.EMFCompareRCPUIPlugin;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
+import org.eclipse.emf.compare.utils.ReferenceUtil;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.ecore.util.InternalEList;
+import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
+import org.eclipse.emf.edit.provider.IItemLabelProvider;
+import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * A {@link ITypedElement} that can be used as input of TreeContentMergeViewer. It is implementing
+ * {@link IStreamContentAccessor} to be able to compare XMI serialization of wrapped {@link EObject}.
+ *
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public class EObjectAccessor implements IEObjectAccessor {
+
+ /**
+ * The wrapped {@link EObject}.
+ */
+ // private final EObject fEObject;
+
+ /**
+ * The adapter factory that will be used to get the name and the image of the wrapped EObject.
+ */
+ private final AdapterFactory fAdapterFactory;
+
+ private final Match fOwnerMatch;
+
+ private final MergeViewerSide fSide;
+
+ /**
+ * Creates a new object wrapping the given <code>eObject</code>.
+ *
+ * @param adapterFactory
+ * the adapter factory to get the image from.
+ * @param eObject
+ * the {@link EObject} to wrap.
+ */
+ public EObjectAccessor(AdapterFactory adapterFactory, Match match, MergeViewerSide side) {
+ fAdapterFactory = adapterFactory;
+ fOwnerMatch = match;
+ fSide = side;
+ }
+
+ /**
+ * @return the fSide
+ */
+ protected final MergeViewerSide getSide() {
+ return fSide;
+ }
+
+ protected EObject getEObject(MergeViewerSide side) {
+ final EObject eObject;
+ switch (side) {
+ case ANCESTOR:
+ eObject = fOwnerMatch.getOrigin();
+ break;
+ case LEFT:
+ eObject = fOwnerMatch.getLeft();
+ break;
+ case RIGHT:
+ eObject = fOwnerMatch.getRight();
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ return eObject;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.ITypedElement#getName()
+ */
+ public String getName() {
+ return getEObject(getSide()).eClass().getName();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.ITypedElement#getImage()
+ */
+ public Image getImage() {
+ Adapter adapter = fAdapterFactory.adapt(getEObject(), IItemLabelProvider.class);
+ if (adapter instanceof IItemLabelProvider) {
+ Object image = ((IItemLabelProvider)adapter).getImage(getEObject());
+ return ExtendedImageRegistry.getInstance().getImage(image);
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.provider.IEObjectAccessor#getEObject()
+ */
+ public EObject getEObject() {
+ return getEObject(getSide());
+ }
+
+ public InputStream getContents() throws CoreException {
+ XMIResourceImpl r = new XMIResourceImpl(URI.createURI("dummy.xmi")); //$NON-NLS-1$
+
+ final ProperContentCopier copier = new ProperContentCopier();
+ final EObject copy = copier.copy(getEObject());
+ copier.copyReferences();
+
+ r.getContents().add(copy);
+ StringWriter sw = new StringWriter();
+ try {
+ r.save(sw, Maps.newHashMap());
+ } catch (IOException e) {
+ throw new CoreException(new Status(IStatus.ERROR, EMFCompareRCPUIPlugin.PLUGIN_ID, e.getMessage(), e));
+ }
+ // Assume that the platform locale is appropriate.
+ return new ByteArrayInputStream(sw.toString().getBytes());
+ }
+
+ private class ProperContentCopier extends EcoreUtil.Copier {
+ /** Generated SUID. */
+ private static final long serialVersionUID = -5458049632291531717L;
+
+ public ProperContentCopier() {
+ this.resolveProxies = false;
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Implementation mostly copy/pasted from EcoreUtil.Copier#copyContainment(EReference, EObject,
+ * EObject). We're only making sure not to resolve any proxy to another resource.
+ * </p>
+ *
+ * @see org.eclipse.emf.ecore.util.EcoreUtil.Copier#copyContainment(org.eclipse.emf.ecore.EReference,
+ * org.eclipse.emf.ecore.EObject, org.eclipse.emf.ecore.EObject)
+ */
+ @Override
+ protected void copyContainment(EReference eReference, EObject eObject, EObject copyEObject) {
+ if (!eObject.eIsSet(eReference)) {
+ return;
+ }
+
+ if (eReference.isMany()) {
+ final Iterator<EObject> source = new BoundProperContentIterator(eObject, eReference);
+ @SuppressWarnings("unchecked")
+ List<EObject> target = (List<EObject>)copyEObject.eGet(getTarget(eReference), resolveProxies);
+ if (!source.hasNext()) {
+ target.clear();
+ } else {
+ while (source.hasNext()) {
+ final EObject next = source.next();
+ target.add(copy(next));
+ }
+ }
+ } else {
+ /*
+ * TODO untested yet as this is a rare case. EMF ignors the "resolve" argument of eGet for
+ * multi-valued containment features. Will it honor it for unique features?
+ */
+ EObject childEObject = (EObject)eObject.eGet(eReference, resolveProxies);
+ if (childEObject == null) {
+ copyEObject.eSet(getTarget(eReference), null);
+ } else {
+ copyEObject.eSet(getTarget(eReference), copy(childEObject));
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Implementation mostly copy/pasted from EcoreUtil.Copier#copyContainment(EReference, EObject,
+ * EObject). We're only making sure not to resolve any proxy to another resource.
+ * </p>
+ *
+ * @see org.eclipse.emf.ecore.util.EcoreUtil.Copier#copyReference(org.eclipse.emf.ecore.EReference,
+ * org.eclipse.emf.ecore.EObject, org.eclipse.emf.ecore.EObject)
+ */
+ @Override
+ protected void copyReference(EReference eReference, EObject eObject, EObject copyEObject) {
+ if (!eObject.eIsSet(eReference)) {
+ return;
+ }
+
+ if (eReference.isMany()) {
+ final Iterator<EObject> source = new BoundProperContentIterator(eObject, eReference);
+ @SuppressWarnings("unchecked")
+ InternalEList<EObject> target = (InternalEList<EObject>)copyEObject.eGet(
+ getTarget(eReference), false);
+ if (!source.hasNext()) {
+ target.clear();
+ } else {
+ boolean isBidirectional = eReference.getEOpposite() != null;
+ int index = 0;
+ while (source.hasNext()) {
+ final EObject next = source.next();
+ final EObject copyReferencedEObject = get(next);
+
+ if (copyReferencedEObject == null) {
+ if (useOriginalReferences && !isBidirectional) {
+ target.addUnique(index, next);
+ ++index;
+ }
+ } else {
+ if (isBidirectional) {
+ int position = target.indexOf(copyReferencedEObject);
+ if (position == -1) {
+ target.addUnique(index, copyReferencedEObject);
+ } else if (index != position) {
+ target.move(index, copyReferencedEObject);
+ }
+ } else {
+ target.addUnique(index, copyReferencedEObject);
+ }
+ ++index;
+ }
+ }
+ }
+ } else {
+ /*
+ * TODO untested yet as this is a rare case. EMF ignors the "resolve" argument of eGet for
+ * multi-valued containment features. Will it honor it for unique features?
+ */
+ final Object referencedEObject = eObject.eGet(eReference, resolveProxies);
+ if (referencedEObject == null) {
+ copyEObject.eSet(getTarget(eReference), null);
+ } else {
+ final Object copyReferencedEObject = get(referencedEObject);
+ if (copyReferencedEObject == null) {
+ if (useOriginalReferences && eReference.getEOpposite() == null) {
+ copyEObject.eSet(getTarget(eReference), referencedEObject);
+ }
+ } else {
+ copyEObject.eSet(getTarget(eReference), copyReferencedEObject);
+ }
+ }
+ }
+ }
+ }
+
+ private final class BoundProperContentIterator extends EcoreUtil.ProperContentIterator<EObject> {
+ public BoundProperContentIterator(EObject eObject, EReference eReference) {
+ super(eObject, false);
+ // Calling super-constructor since we need to, but we'll override what it just did
+ @SuppressWarnings("unchecked")
+ final List<EObject> contents = (List<EObject>)ReferenceUtil.safeEGet(eObject, eReference);
+ if (contents instanceof InternalEList<?>) {
+ this.iterator = ((InternalEList<EObject>)contents).basicIterator();
+ } else {
+ this.iterator = contents.iterator();
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/actions/FilterAction.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/actions/FilterAction.java
new file mode 100644
index 0000000..4cb6e0f
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/actions/FilterAction.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.rcp.ui.structuremergeviewer.actions;
+
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.StructureMergeViewerFilter;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+
+/**
+ * These will be the actual actions displayed in the filter menu. Their sole purpose is to provide a Predicate
+ * to the structure viewer's filter.
+ * <p>
+ * Do note that each distinct {@link FilterAction} in the {@link FilterActionMenu filter menu} is considered
+ * as an "exclude" filter, and that they are OR'ed together (thus, any element must <b>not</b> meet the
+ * selected filters' criteria in order to be displayed).
+ * </p>
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ * @since 3.0
+ */
+public class FilterAction extends Action {
+
+ /** The filter associated with this action. */
+ private IDifferenceFilter filter;
+
+ /** The Filter that will be modified by the action. */
+ private StructureMergeViewerFilter structureMergeViewerFilter;
+
+ /**
+ * The "default" constructor for this action.
+ *
+ * @param text
+ * Will be used as the action's tooltip.
+ * @param structureMergeViewerFilter
+ * The viewer filter that this action will need to update.
+ * @param filter
+ * The filter associated with this action.
+ */
+ public FilterAction(String text, StructureMergeViewerFilter structureMergeViewerFilter, IDifferenceFilter filter) {
+ super(text, IAction.AS_CHECK_BOX);
+ this.structureMergeViewerFilter = structureMergeViewerFilter;
+ this.filter = filter;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ @Override
+ public void run() {
+ if (isChecked()) {
+ structureMergeViewerFilter.addFilter(filter);
+ } else {
+ structureMergeViewerFilter.removeFilter(filter);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/actions/FilterActionMenu.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/actions/FilterActionMenu.java
new file mode 100644
index 0000000..3e83bfd
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/actions/FilterActionMenu.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.rcp.ui.structuremergeviewer.actions;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.rcp.ui.EMFCompareRCPUIPlugin;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.StructureMergeViewerFilter;
+import org.eclipse.emf.compare.scope.IComparisonScope;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuCreator;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+/**
+ * This will be displayed atop the structure viewer as the "filters" menu.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ * @since 3.0
+ */
+public class FilterActionMenu extends Action implements IMenuCreator {
+ /** The viewer filter that will be modified by this menu's actions. */
+ private final StructureMergeViewerFilter structureMergeViewerFilter;
+
+ /** Menu Manager that will contain our menu. */
+ private MenuManager menuManager;
+
+ /**
+ * Constructs our filtering menu.
+ *
+ * @param structureMergeViewerFilter
+ * The viewer filter for which we'll create actions.
+ * @param menuManager
+ * The Menu Manager that will contain our menu.
+ */
+ public FilterActionMenu(StructureMergeViewerFilter structureMergeViewerFilter, MenuManager menuManager) {
+ super("", IAction.AS_DROP_DOWN_MENU); //$NON-NLS-1$
+ this.menuManager = menuManager;
+ this.structureMergeViewerFilter = structureMergeViewerFilter;
+ setMenuCreator(this);
+ setToolTipText("Filters"); //$NON-NLS-1$
+ setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(EMFCompareRCPUIPlugin.PLUGIN_ID,
+ "icons/full/toolb16/filter.gif")); //$NON-NLS-1$
+ }
+
+ /**
+ * Create all of our filtering actions into the given menu.
+ *
+ * @param scope
+ * The scope on which the filters will be applied.
+ * @param comparison
+ * The comparison on which the filters will be applied.
+ */
+ public void createActions(IComparisonScope scope, Comparison comparison) {
+ IDifferenceFilter.Registry registry = EMFCompareRCPUIPlugin.getDefault().getFilterActionRegistry();
+ for (IDifferenceFilter filterProvider : registry.getFilters(scope, comparison)) {
+ FilterAction action = new FilterAction(filterProvider.getLabel(), structureMergeViewerFilter,
+ filterProvider);
+ if (filterProvider.defaultSelected()) {
+ action.setChecked(true);
+ action.run();
+ }
+ menuManager.add(action);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see IMenuCreator#dispose()
+ */
+ public void dispose() {
+ menuManager.dispose();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see IMenuCreator#getMenu(Control)
+ */
+ public Menu getMenu(Control parent) {
+ return menuManager.createContextMenu(parent);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see IMenuCreator#getMenu(Menu)
+ */
+ public Menu getMenu(Menu parent) {
+ return menuManager.getMenu();
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/GroupAction.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/actions/GroupAction.java
index 6cfbdac..cba4f38 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/GroupAction.java
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/actions/GroupAction.java
@@ -1,50 +1,57 @@
-/*******************************************************************************
- * Copyright (c) 2012 Obeo.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Obeo - initial API and implementation
- *******************************************************************************/
-package org.eclipse.emf.compare.ide.ui.internal.actions.group;
-
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.IAction;
-
-/**
- * This action will allow us to group differences by their kind.
- *
- * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
- */
-public class GroupAction extends Action {
- /** The difference grouper that will be affected by this action. */
- private final DifferenceGrouper differenceGrouper;
-
- /** The actual instance that will provide groups if this action is used. */
- private final DifferenceGroupProvider provider;
-
- /**
- * Instantiates our action given its target grouper.
- *
- * @param differenceGrouper
- * The grouper to which we'll provide our DifferenceGroupProvider.
- */
- public GroupAction(String text, DifferenceGrouper differenceGrouper,
- DifferenceGroupProvider provider) {
- super(text, IAction.AS_RADIO_BUTTON);
- this.differenceGrouper = differenceGrouper;
- this.provider = provider;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.action.Action#run()
- */
- @Override
- public void run() {
- differenceGrouper.setProvider(provider);
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.rcp.ui.structuremergeviewer.actions;
+
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.StructureMergeViewerGrouper;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+
+/**
+ * This action will allow us to group differences by their kind.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ * @since 3.0
+ */
+public class GroupAction extends Action {
+ /** The viewer grouper that will be affected by this action. */
+ private final StructureMergeViewerGrouper structureMergeViewerGrouper;
+
+ /** The actual instance that will provide groups if this action is used. */
+ private final IDifferenceGroupProvider provider;
+
+ /**
+ * Instantiates our action given its target grouper.
+ *
+ * @param text
+ * Will be used as the action's tooltip.
+ * @param structureMergeViewerGrouper
+ * The grouper to which we'll provide our DifferenceGroupProvider.
+ * @param provider
+ * The group provider associated with this action.
+ */
+ public GroupAction(String text, StructureMergeViewerGrouper structureMergeViewerGrouper,
+ IDifferenceGroupProvider provider) {
+ super(text, IAction.AS_RADIO_BUTTON);
+ this.structureMergeViewerGrouper = structureMergeViewerGrouper;
+ this.provider = provider;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ @Override
+ public void run() {
+ structureMergeViewerGrouper.setProvider(provider);
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/actions/GroupActionMenu.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/actions/GroupActionMenu.java
new file mode 100644
index 0000000..90dc198
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/actions/GroupActionMenu.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.rcp.ui.structuremergeviewer.actions;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.rcp.ui.EMFCompareRCPUIPlugin;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.DefaultGroupProvider;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.StructureMergeViewerGrouper;
+import org.eclipse.emf.compare.scope.IComparisonScope;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuCreator;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+/**
+ * This menu will display actions that will allow the user to group differences together.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ * @since 3.0
+ */
+public class GroupActionMenu extends Action implements IMenuCreator {
+ /** The viewer grouper that will be affected by this menu's actions. */
+ private final StructureMergeViewerGrouper structureMergeViewerGrouper;
+
+ /** Menu Manager that will contain our menu. */
+ private MenuManager menuManager;
+
+ /** The default group provider. */
+ private DefaultGroupProvider defaultGroupProvider;
+
+ /**
+ * Constructs our grouping menu.
+ *
+ * @param structureMergeViewerGrouper
+ * The viewer grouper that will be affected by this menu's actions.
+ * @param menuManager
+ * The Menu Manager that will contain our menu.
+ * @param defaultGroupProvider
+ * The default group provider.
+ */
+ public GroupActionMenu(StructureMergeViewerGrouper structureMergeViewerGrouper, MenuManager menuManager,
+ DefaultGroupProvider defaultGroupProvider) {
+ super("", IAction.AS_DROP_DOWN_MENU); //$NON-NLS-1$
+ this.menuManager = menuManager;
+ this.structureMergeViewerGrouper = structureMergeViewerGrouper;
+ this.defaultGroupProvider = defaultGroupProvider;
+ setToolTipText("Groups"); //$NON-NLS-1$
+ setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(EMFCompareRCPUIPlugin.PLUGIN_ID,
+ "icons/full/toolb16/group.gif")); //$NON-NLS-1$
+ setMenuCreator(this);
+ }
+
+ /**
+ * Create the grouping action in the given menu.
+ *
+ * @param scope
+ * The scope on which the groups will be applied.
+ * @param comparison
+ * The comparison which differences are to be split into groups.
+ */
+ public void createActions(IComparisonScope scope, Comparison comparison) {
+ final IAction defaultAction = new GroupAction(defaultGroupProvider.getLabel(),
+ structureMergeViewerGrouper, defaultGroupProvider);
+ defaultAction.setChecked(true);
+ menuManager.add(defaultAction);
+ IDifferenceGroupProvider.Registry registry = EMFCompareRCPUIPlugin.getDefault()
+ .getDifferenceGroupProviderRegistry();
+ boolean alreadyChecked = false;
+ for (IDifferenceGroupProvider dgp : registry.getGroupProviders(scope, comparison)) {
+ GroupAction action = new GroupAction(dgp.getLabel(), structureMergeViewerGrouper, dgp);
+ menuManager.add(action);
+ if (dgp.defaultSelected() && !alreadyChecked) {
+ defaultAction.setChecked(false);
+ action.setChecked(true);
+ alreadyChecked = true;
+ action.run();
+ }
+
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see IMenuCreator#dispose()
+ */
+ public void dispose() {
+ menuManager.dispose();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see IMenuCreator#getMenu(Control)
+ */
+ public Menu getMenu(Control parent) {
+ return menuManager.createContextMenu(parent);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see IMenuCreator#getMenu(Menu)
+ */
+ public Menu getMenu(Menu parent) {
+ return menuManager.getMenu();
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/AddedElementsFilter.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/AddedElementsFilter.java
new file mode 100644
index 0000000..b8c8995
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/AddedElementsFilter.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters;
+
+import static org.eclipse.emf.compare.utils.EMFComparePredicates.ofKind;
+
+import com.google.common.base.Predicate;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.DifferenceKind;
+import org.eclipse.emf.compare.scope.IComparisonScope;
+import org.eclipse.emf.ecore.EObject;
+
+/**
+ * A filter used by default that filtered out added elements.
+ *
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ * @since 3.0
+ */
+public class AddedElementsFilter implements IDifferenceFilter {
+
+ /** A human-readable label for this filter. This will be displayed in the EMF Compare UI. */
+ private String label;
+
+ /** The initial activation state of the filter. */
+ private boolean activeByDefault;
+
+ /** The predicate activate through this filter. */
+ private Predicate<? super EObject> predicate;
+
+ /**
+ * Constructs the filter with the appropriate predicate.
+ */
+ public AddedElementsFilter() {
+ super();
+ setPredicate();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#getLabel()
+ */
+ public String getLabel() {
+ return label;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#setLabel(java.lang.String)
+ */
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#defaultSelected()
+ */
+ public boolean defaultSelected() {
+ return activeByDefault;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#setDefaultSelected(boolean)
+ */
+ public void setDefaultSelected(boolean activeByDefault) {
+ this.activeByDefault = activeByDefault;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#isEnabled(org.eclipse.emf.compare.scope.IComparisonScope,
+ * org.eclipse.emf.compare.Comparison)
+ */
+ public boolean isEnabled(IComparisonScope scope, Comparison comparison) {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#getPredicate()
+ */
+ public Predicate<? super EObject> getPredicate() {
+ return predicate;
+ }
+
+ /**
+ * Set the predicate that will be activate through this filter.
+ */
+ private void setPredicate() {
+ final Predicate<? super EObject> actualPredicate = new Predicate<EObject>() {
+ public boolean apply(EObject input) {
+ return input instanceof Diff && ofKind(DifferenceKind.ADD).apply((Diff)input);
+ }
+ };
+ predicate = actualPredicate;
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/ChangedElementsFilter.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/ChangedElementsFilter.java
new file mode 100644
index 0000000..dfa072d
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/ChangedElementsFilter.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters;
+
+import static org.eclipse.emf.compare.utils.EMFComparePredicates.ofKind;
+
+import com.google.common.base.Predicate;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.DifferenceKind;
+import org.eclipse.emf.compare.scope.IComparisonScope;
+import org.eclipse.emf.ecore.EObject;
+
+/**
+ * A filter used by default that filtered out changed elements.
+ *
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ * @since 3.0
+ */
+public class ChangedElementsFilter implements IDifferenceFilter {
+
+ /** A human-readable label for this filter. This will be displayed in the EMF Compare UI. */
+ private String label;
+
+ /** The initial activation state of the filter. */
+ private boolean activeByDefault;
+
+ /** The Predicate activate through this action. */
+ private Predicate<? super EObject> predicate;
+
+ /**
+ * Constructs the filter with the appropriate predicate.
+ */
+ public ChangedElementsFilter() {
+ super();
+ setPredicate();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#getLabel()
+ */
+ public String getLabel() {
+ return label;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#setLabel(java.lang.String)
+ */
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#defaultSelected()
+ */
+ public boolean defaultSelected() {
+ return activeByDefault;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#setDefaultSelected(boolean)
+ */
+ public void setDefaultSelected(boolean activeByDefault) {
+ this.activeByDefault = activeByDefault;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#isEnabled(org.eclipse.emf.compare.scope.IComparisonScope,
+ * org.eclipse.emf.compare.Comparison)
+ */
+ public boolean isEnabled(IComparisonScope scope, Comparison comparison) {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#getPredicate()
+ */
+ public Predicate<? super EObject> getPredicate() {
+ return predicate;
+ }
+
+ /**
+ * Set the predicate that will be activate through this filter.
+ */
+ private void setPredicate() {
+ final Predicate<? super EObject> actualPredicate = new Predicate<EObject>() {
+ public boolean apply(EObject input) {
+ return input instanceof Diff && ofKind(DifferenceKind.CHANGE).apply((Diff)input);
+ }
+ };
+ predicate = actualPredicate;
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/IDifferenceFilter.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/IDifferenceFilter.java
new file mode 100644
index 0000000..496e94b
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/IDifferenceFilter.java
@@ -0,0 +1,211 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters;
+
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Lists.newArrayList;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.scope.IComparisonScope;
+import org.eclipse.emf.ecore.EObject;
+
+/**
+ * Instances of this class will be used by EMF Compare in order to provide difference filter facilities to the
+ * structural differences view.
+ *
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ * @since 3.0
+ */
+public interface IDifferenceFilter {
+
+ /**
+ * The predicate that will filter out objects in the structural differences view.
+ *
+ * @return The predicate that will filter out objects in the structural differences view.
+ */
+ Predicate<? super EObject> getPredicate();
+
+ /**
+ * A human-readable label for this filter. This will be displayed in the EMF Compare UI.
+ *
+ * @return The label for this filter.
+ */
+ String getLabel();
+
+ /**
+ * Set the label for this filter. This will be displayed in the EMF Compare UI.
+ *
+ * @param label
+ * A human-readable label for this filter.
+ */
+ void setLabel(String label);
+
+ /**
+ * Returns the initial activation state that the filter should have.
+ *
+ * @return The initial activation state that the filter should have.
+ */
+ boolean defaultSelected();
+
+ /**
+ * Set the initial activation state that the filter should have.
+ *
+ * @param defaultSelected
+ * The initial activation state that the filter should have (true if the filter should be
+ * active by default).
+ */
+ void setDefaultSelected(boolean defaultSelected);
+
+ /**
+ * Returns the activation condition based on the scope and comparison objects.
+ *
+ * @param scope
+ * The scope on which the filter will be applied.
+ * @param comparison
+ * The comparison which is to be displayed in the structural view.
+ * @return The activation condition based on the scope and comparison objects.
+ */
+ boolean isEnabled(IComparisonScope scope, Comparison comparison);
+
+ /**
+ * A registry of {@link IDifferenceFilter}.
+ */
+ interface Registry {
+
+ /**
+ * Returns the list of {@link IDifferenceFilter} contained in the registry.
+ *
+ * @param scope
+ * The scope on which the filters will be applied.
+ * @param comparison
+ * The comparison which is to be displayed in the structural view.
+ * @return The list of {@link IDifferenceFilter} contained in the registry.
+ */
+ Collection<IDifferenceFilter> getFilters(IComparisonScope scope, Comparison comparison);
+
+ /**
+ * Add to the registry the given {@link IDifferenceFilter}.
+ *
+ * @param filter
+ * The given {@link IDifferenceFilter}.
+ * @return The previous value associated with the class name of the given {@link IDifferenceFilter},
+ * or null if there was no entry in the registry for the class name.
+ */
+ IDifferenceFilter add(IDifferenceFilter filter);
+
+ /**
+ * Remove from the registry the {@link IDifferenceFilter} designated by the given {@link String} .
+ *
+ * @param className
+ * The given {@link String} representing a {@link IDifferenceFilter}.
+ * @return The {@link IDifferenceFilter} designated by the given {@link String}.
+ */
+ IDifferenceFilter remove(String className);
+
+ /**
+ * Clear the registry.
+ */
+ void clear();
+ }
+
+ /**
+ * The default implementation of the {@link Registry}.
+ */
+ public class RegistryImpl implements Registry {
+
+ /** A map that associates the class name to theirs {@link IDifferenceFilter}s. */
+ private final Map<String, IDifferenceFilter> map;
+
+ /**
+ * Constructs the registry.
+ */
+ public RegistryImpl() {
+ map = new ConcurrentHashMap<String, IDifferenceFilter>();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter.Registry#getFilters(org.eclipse.emf.compare.scope.IComparisonScope,
+ * org.eclipse.emf.compare.Comparison)
+ */
+ public List<IDifferenceFilter> getFilters(IComparisonScope scope, Comparison comparison) {
+ Iterable<IDifferenceFilter> filters = filter(map.values(), isFilterActivable(scope, comparison));
+ List<IDifferenceFilter> ret = newArrayList();
+ for (IDifferenceFilter filter : filters) {
+ ret.add(filter);
+ }
+ return ret;
+ }
+
+ /**
+ * Returns a predicate that represents the activation condition based on the scope and comparison
+ * objects.
+ *
+ * @param scope
+ * The scope on which the group provider will be applied.
+ * @param comparison
+ * The comparison which is to be displayed in the structural view.
+ * @return A predicate that represents the activation condition based on the scope and comparison
+ * objects.
+ */
+ static final Predicate<IDifferenceFilter> isFilterActivable(final IComparisonScope scope,
+ final Comparison comparison) {
+ return new Predicate<IDifferenceFilter>() {
+ /**
+ * {@inheritDoc}
+ *
+ * @see com.google.common.base.Predicate#apply(java.lang.Object)
+ */
+ public boolean apply(IDifferenceFilter d) {
+ return d.isEnabled(scope, comparison);
+ }
+ };
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter.Registry#add(org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter)
+ */
+ public IDifferenceFilter add(IDifferenceFilter filter) {
+ Preconditions.checkNotNull(filter);
+ return map.put(filter.getClass().getName(), filter);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter.Registry#remove(java.lang.String)
+ */
+ public IDifferenceFilter remove(String className) {
+ return map.remove(className);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter.Registry#clear()
+ */
+ public void clear() {
+ map.clear();
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/IDifferenceFilterSelectionChangeEvent.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/IDifferenceFilterSelectionChangeEvent.java
new file mode 100644
index 0000000..4565236
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/IDifferenceFilterSelectionChangeEvent.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters;
+
+/**
+ * The {@link IDifferenceFilterSelectionChangeEvent} is type of event that will be posted through an event bus. When
+ * clicking on a filter through the EMF Compare UI in order to activate or deactivate it, an event of type
+ * {@link IDifferenceFilterSelectionChangeEvent} will be posted through an event bus.
+ *
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ * @since 3.0
+ */
+public interface IDifferenceFilterSelectionChangeEvent {
+
+ /**
+ * The {@link IDifferenceFilter} associated with this event.
+ *
+ * @return The {@link IDifferenceFilter} associated with this event.
+ */
+ IDifferenceFilter getFilter();
+
+ /**
+ * The {@link Action} associated with this event.
+ *
+ * @return The {@link Action} associated with this event.
+ */
+ Action getAction();
+
+ /**
+ * The types of actions which can be associated with the events.
+ *
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ */
+ enum Action {
+ /** Corresponding to an activation of an {@link IDifferenceFilter}. */
+ ADD,
+ /** Corresponding to a deactivation of an {@link IDifferenceFilter}. */
+ REMOVE,
+ }
+
+ /**
+ * A default implementation of the {@link IDifferenceFilterSelectionChangeEvent}.
+ *
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ */
+ class DefaultFilterSelectionChangeEvent implements IDifferenceFilterSelectionChangeEvent {
+
+ /** The {@link IDifferenceFilter} associated with this event. */
+ private final IDifferenceFilter filter;
+
+ /** The {@link Action} associated with this event. */
+ private final Action action;
+
+ /**
+ * Constructs the event.
+ *
+ * @param filter
+ * The {@link IDifferenceFilter} that will be associated with this event.
+ * @param action
+ * The {@link Action} that will be associated with this event.
+ */
+ public DefaultFilterSelectionChangeEvent(IDifferenceFilter filter, Action action) {
+ this.filter = filter;
+ this.action = action;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilterSelectionChangeEvent#getFilter()
+ */
+ public IDifferenceFilter getFilter() {
+ return filter;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilterSelectionChangeEvent#getAction()
+ */
+ public Action getAction() {
+ return action;
+ }
+
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/MatchedResourcesFilter.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/MatchedResourcesFilter.java
new file mode 100644
index 0000000..d0f181d
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/MatchedResourcesFilter.java
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters;
+
+import com.google.common.base.Predicate;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.MatchResource;
+import org.eclipse.emf.compare.scope.IComparisonScope;
+import org.eclipse.emf.ecore.EObject;
+
+/**
+ * A filter used by default that filtered out matched elements.
+ *
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ * @since 3.0
+ */
+public class MatchedResourcesFilter implements IDifferenceFilter {
+
+ /** A human-readable label for this filter. This will be displayed in the EMF Compare UI. */
+ private String label;
+
+ /** The initial activation state of the filter. */
+ private boolean activeByDefault;
+
+ /** The Predicate activate through this action. */
+ private Predicate<? super EObject> predicate;
+
+ /**
+ * Constructs the filter with the appropriate predicate.
+ */
+ public MatchedResourcesFilter() {
+ super();
+ setPredicate();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#getLabel()
+ */
+ public String getLabel() {
+ return label;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#setLabel(java.lang.String)
+ */
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#defaultSelected()
+ */
+ public boolean defaultSelected() {
+ return activeByDefault;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#setDefaultSelected(boolean)
+ */
+ public void setDefaultSelected(boolean activeByDefault) {
+ this.activeByDefault = activeByDefault;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#isEnabled(org.eclipse.emf.compare.scope.IComparisonScope,
+ * org.eclipse.emf.compare.Comparison)
+ */
+ public boolean isEnabled(IComparisonScope scope, Comparison comparison) {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#getPredicate()
+ */
+ public Predicate<? super EObject> getPredicate() {
+ return predicate;
+ }
+
+ /**
+ * Set the predicate that will be activate through this filter.
+ */
+ private void setPredicate() {
+ final Predicate<? super EObject> actualPredicate = new Predicate<EObject>() {
+ public boolean apply(EObject input) {
+ return input instanceof MatchResource;
+ }
+ };
+ predicate = actualPredicate;
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/MovedElementsFilter.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/MovedElementsFilter.java
new file mode 100644
index 0000000..ad9eed0
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/MovedElementsFilter.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters;
+
+import static org.eclipse.emf.compare.utils.EMFComparePredicates.ofKind;
+
+import com.google.common.base.Predicate;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.DifferenceKind;
+import org.eclipse.emf.compare.scope.IComparisonScope;
+import org.eclipse.emf.ecore.EObject;
+
+/**
+ * A filter used by default that filtered out moved elements.
+ *
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ * @since 3.0
+ */
+public class MovedElementsFilter implements IDifferenceFilter {
+
+ /** A human-readable label for this filter. This will be displayed in the EMF Compare UI. */
+ private String label;
+
+ /** The initial activation state of the filter. */
+ private boolean activeByDefault;
+
+ /** The Predicate activate through this action. */
+ private Predicate<? super EObject> predicate;
+
+ /**
+ * Constructs the filter with the appropriate predicate.
+ */
+ public MovedElementsFilter() {
+ super();
+ setPredicate();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#getLabel()
+ */
+ public String getLabel() {
+ return label;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#setLabel(java.lang.String)
+ */
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#defaultSelected()
+ */
+ public boolean defaultSelected() {
+ return activeByDefault;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#setDefaultSelected(boolean)
+ */
+ public void setDefaultSelected(boolean activeByDefault) {
+ this.activeByDefault = activeByDefault;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#isEnabled(org.eclipse.emf.compare.scope.IComparisonScope,
+ * org.eclipse.emf.compare.Comparison)
+ */
+ public boolean isEnabled(IComparisonScope scope, Comparison comparison) {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#getPredicate()
+ */
+ public Predicate<? super EObject> getPredicate() {
+ return predicate;
+ }
+
+ /**
+ * Set the predicate that will be activate through this filter.
+ */
+ private void setPredicate() {
+ final Predicate<? super EObject> actualPredicate = new Predicate<EObject>() {
+ public boolean apply(EObject input) {
+ return input instanceof Diff && ofKind(DifferenceKind.MOVE).apply((Diff)input);
+ }
+ };
+ predicate = actualPredicate;
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/RemovedElementsFilter.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/RemovedElementsFilter.java
new file mode 100644
index 0000000..2bf51be
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/RemovedElementsFilter.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters;
+
+import static org.eclipse.emf.compare.utils.EMFComparePredicates.ofKind;
+
+import com.google.common.base.Predicate;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.DifferenceKind;
+import org.eclipse.emf.compare.scope.IComparisonScope;
+import org.eclipse.emf.ecore.EObject;
+
+/**
+ * A filter used by default that filtered out removed elements.
+ *
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ * @since 3.0
+ */
+public class RemovedElementsFilter implements IDifferenceFilter {
+
+ /** A human-readable label for this filter. This will be displayed in the EMF Compare UI. */
+ private String label;
+
+ /** The initial activation state of the filter. */
+ private boolean activeByDefault;
+
+ /** The Predicate activate through this action. */
+ private Predicate<? super EObject> predicate;
+
+ /**
+ * Constructs the filter with the appropriate predicate.
+ */
+ public RemovedElementsFilter() {
+ super();
+ setPredicate();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#getLabel()
+ */
+ public String getLabel() {
+ return label;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#setLabel(java.lang.String)
+ */
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#defaultSelected()
+ */
+ public boolean defaultSelected() {
+ return activeByDefault;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#setDefaultSelected(boolean)
+ */
+ public void setDefaultSelected(boolean activeByDefault) {
+ this.activeByDefault = activeByDefault;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#isEnabled(org.eclipse.emf.compare.scope.IComparisonScope,
+ * org.eclipse.emf.compare.Comparison)
+ */
+ public boolean isEnabled(IComparisonScope scope, Comparison comparison) {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#getPredicate()
+ */
+ public Predicate<? super EObject> getPredicate() {
+ return predicate;
+ }
+
+ /**
+ * Set the predicate that will be activate through this filter.
+ */
+ private void setPredicate() {
+ final Predicate<? super EObject> actualPredicate = new Predicate<EObject>() {
+ public boolean apply(EObject input) {
+ return input instanceof Diff && ofKind(DifferenceKind.DELETE).apply((Diff)input);
+ }
+ };
+ predicate = actualPredicate;
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/filter/DifferenceFilter.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/StructureMergeViewerFilter.java
index 9e16ba0..5297665 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/filter/DifferenceFilter.java
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/StructureMergeViewerFilter.java
@@ -1,167 +1,208 @@
-/*******************************************************************************
- * Copyright (c) 2012 Obeo.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Obeo - initial API and implementation
- *******************************************************************************/
-package org.eclipse.emf.compare.ide.ui.internal.actions.filter;
-
-import static com.google.common.base.Predicates.not;
-
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.Iterators;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import org.eclipse.emf.common.notify.Adapter;
-import org.eclipse.emf.compare.Diff;
-import org.eclipse.emf.compare.ide.ui.internal.actions.group.DifferenceGroup;
-import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.provider.DiffNode;
-import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.provider.MatchNode;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.jface.viewers.TreePath;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.jface.viewers.ViewerFilter;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-
-/**
- * This will be used by the structure viewer to filter out its list of differences according to a number of
- * provided predicates.
- * <p>
- * <b>Note</b> that this filter acts as an "OR" predicate between all provided ones, and that filters are
- * "exclude" filters. Basically, that means if the user selects two filters, any difference that applies for
- * any of these two filters will be <i>hidden</i> from the view, contrarily to "classic" {@link ViewerFilter}
- * that act as "AND" predicates for "include" filters, forcing any displayed element to meet the criterion of
- * all provided filters.
- * </p>
- *
- * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
- */
-public class DifferenceFilter extends ViewerFilter {
- /** The set of predicates known by this filter. */
- private Set<Predicate<? super EObject>> predicates = Sets.newLinkedHashSet();
-
- /** List of all TreeViewers on which this filter is applied. */
- private List<TreeViewer> viewers = Lists.newArrayList();
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers.Viewer, java.lang.Object,
- * java.lang.Object)
- */
- @Override
- public boolean select(Viewer viewer, Object parentElement, Object element) {
- if (predicates.isEmpty()) {
- return true;
- }
- boolean result = false;
- final Predicate<? super EObject> predicate = Predicates.or(predicates);
-
- if (predicates.isEmpty()) {
- result = true;
- } else if (element instanceof DiffNode) {
- final Diff diff = ((DiffNode)element).getTarget();
- result = !predicate.apply(diff);
- } else if (element instanceof MatchNode) {
- final Iterator<Diff> differences = ((MatchNode)element).getTarget().getAllDifferences()
- .iterator();
- result = Iterators.any(differences, not(predicate));
- } else if (element instanceof DifferenceGroup) {
- final Iterator<? extends Diff> differences = ((DifferenceGroup)element).getDifferences()
- .iterator();
- result = Iterators.any(differences, not(predicate));
- } else if (element instanceof Adapter && ((Adapter)element).getTarget() instanceof EObject) {
- /*
- * Same code as the DiffNode case... extracted here as this is aimed at handling the cases not
- * known at the time of writing (and the case of the "MatchResource" elements).
- */
- final EObject target = (EObject)((Adapter)element).getTarget();
- result = !predicate.apply(target);
- }
-
- return result;
- }
-
- /**
- * Add a predicate to the set known by this filter.
- *
- * @param predicate
- * The new predicate for differences to be accepted by this viewer. No effect if already
- * accepted.
- */
- public void addPredicate(Predicate<? super EObject> predicate) {
- final boolean changed = predicates.add(predicate);
- if (changed) {
- refreshViewers();
- }
- }
-
- /**
- * Removes a predicate from those accepted by this filter.
- *
- * @param predicate
- * The predicate that should no longer by accepted by this filter. No effect if it was not one
- * of the accepted ones.
- */
- public void removePredicate(Predicate<? super EObject> predicate) {
- final boolean changed = predicates.remove(predicate);
- if (changed) {
- refreshViewers();
- }
- }
-
- /**
- * Refreshes the viewers registered with this filter. Will try and conserve the expanded tree paths when
- * possible.
- */
- private void refreshViewers() {
- for (TreeViewer viewer : viewers) {
- final TreePath[] paths = viewer.getExpandedTreePaths();
- viewer.refresh();
- viewer.setExpandedTreePaths(paths);
- }
- }
-
- /**
- * Install this filter on the given viewer.
- * <p>
- * Note that this will also install a dispose listener on that viewer in order to remove the filter
- * whenever the viewer is disposed.
- * </p>
- *
- * @param viewer
- * the viewer on which the filter will be installed
- */
- public void install(final TreeViewer viewer) {
- viewer.addFilter(this);
- viewer.getTree().addDisposeListener(new DisposeListener() {
- public void widgetDisposed(DisposeEvent e) {
- uninstall(viewer);
- }
- });
- viewers.add(viewer);
- }
-
- /**
- * Uninstall this filter from the given viewer.
- *
- * @param viewer
- * The viewer from which the filter should be removed.
- */
- public void uninstall(TreeViewer viewer) {
- viewer.removeFilter(this);
- viewers.remove(viewer);
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters;
+
+import static com.google.common.base.Predicates.not;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterators;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import com.google.common.eventbus.EventBus;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.Match;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilterSelectionChangeEvent.Action;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.DifferenceGroup;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.jface.viewers.TreePath;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+
+/**
+ * This will be used by the structure viewer to filter out its list of differences according to a number of
+ * provided predicates.
+ * <p>
+ * <b>Note</b> that this filter acts as an "OR" predicate between all provided ones, and that filters are
+ * "exclude" filters. Basically, that means if the user selects two filters, any difference that applies for
+ * any of these two filters will be <i>hidden</i> from the view, contrarily to "classic" {@link ViewerFilter}
+ * that act as "AND" predicates for "include" filters, forcing any displayed element to meet the criterion of
+ * all provided filters.
+ * </p>
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ * @since 3.0
+ */
+public class StructureMergeViewerFilter extends ViewerFilter {
+ /** The set of predicates known by this filter. */
+ private Set<Predicate<? super EObject>> predicates = Sets.newLinkedHashSet();
+
+ /** List of all TreeViewers on which this filter is applied. */
+ private List<TreeViewer> viewers = Lists.newArrayList();
+
+ /** The {@link EventBus} associated with this filter. */
+ private EventBus eventBus;
+
+ /**
+ * Constructs the difference filter.
+ *
+ * @param eventBus
+ * The {@link EventBus} which will be associated with this filter.
+ */
+ public StructureMergeViewerFilter(EventBus eventBus) {
+ this.eventBus = eventBus;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers.Viewer, java.lang.Object,
+ * java.lang.Object)
+ */
+ @Override
+ public boolean select(Viewer viewer, Object parentElement, Object element) {
+ if (predicates.isEmpty()) {
+ return true;
+ }
+ boolean result = false;
+ final Predicate<? super EObject> predicate = Predicates.or(predicates);
+
+ if (predicates.isEmpty()) {
+ result = true;
+ } else if (element instanceof Adapter) {
+ Notifier notifier = ((Adapter)element).getTarget();
+ if (notifier instanceof Diff) {
+ final Diff diff = (Diff)notifier;
+ result = !predicate.apply(diff);
+ } else if (notifier instanceof Match) {
+ final Iterator<Diff> differences = ((Match)notifier).getAllDifferences().iterator();
+ result = Iterators.any(differences, not(predicate));
+ }
+ } else if (element instanceof DifferenceGroup) {
+ final Iterator<? extends Diff> differences = ((DifferenceGroup)element).getDifferences()
+ .iterator();
+ result = Iterators.any(differences, not(predicate));
+ } else if (element instanceof Adapter && ((Adapter)element).getTarget() instanceof EObject) {
+ /*
+ * Same code as the DiffNode case... extracted here as this is aimed at handling the cases not
+ * known at the time of writing (and the case of the "MatchResource" elements).
+ */
+ final EObject target = (EObject)((Adapter)element).getTarget();
+ result = !predicate.apply(target);
+ }
+
+ return result;
+ }
+
+ /**
+ * Add the predicate of the given {@link IDifferenceFilter}.
+ *
+ * @param filter
+ * The given {@link IDifferenceFilter}.
+ */
+ public void addFilter(IDifferenceFilter filter) {
+ addPredicate(filter.getPredicate());
+ eventBus.post(new IDifferenceFilterSelectionChangeEvent.DefaultFilterSelectionChangeEvent(filter, Action.ADD));
+ }
+
+ /**
+ * Remove the predicate of the given {@link IDifferenceFilter}.
+ *
+ * @param filter
+ * The given {@link IDifferenceFilter}.
+ */
+ public void removeFilter(IDifferenceFilter filter) {
+ removePredicate(filter.getPredicate());
+ eventBus.post(new IDifferenceFilterSelectionChangeEvent.DefaultFilterSelectionChangeEvent(filter, Action.REMOVE));
+ }
+
+ /**
+ * Add a predicate to the set known by this filter.
+ *
+ * @param predicate
+ * The new predicate for differences to be accepted by this viewer. No effect if already
+ * accepted.
+ */
+ public void addPredicate(Predicate<? super EObject> predicate) {
+ final boolean changed = predicates.add(predicate);
+ if (changed) {
+ refreshViewers();
+ }
+ }
+
+ /**
+ * Removes a predicate from those accepted by this filter.
+ *
+ * @param predicate
+ * The predicate that should no longer by accepted by this filter. No effect if it was not one
+ * of the accepted ones.
+ */
+ public void removePredicate(Predicate<? super EObject> predicate) {
+ final boolean changed = predicates.remove(predicate);
+ if (changed) {
+ refreshViewers();
+ }
+ }
+
+ /**
+ * Refreshes the viewers registered with this filter. Will try and conserve the expanded tree paths when
+ * possible.
+ */
+ private void refreshViewers() {
+ for (TreeViewer viewer : viewers) {
+ final TreePath[] paths = viewer.getExpandedTreePaths();
+ viewer.refresh();
+ viewer.setExpandedTreePaths(paths);
+ }
+ }
+
+ /**
+ * Install this filter on the given viewer.
+ * <p>
+ * Note that this will also install a dispose listener on that viewer in order to remove the filter
+ * whenever the viewer is disposed.
+ * </p>
+ *
+ * @param viewer
+ * the viewer on which the filter will be installed
+ */
+ public void install(final TreeViewer viewer) {
+ viewer.addFilter(this);
+ viewer.getTree().addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ uninstall(viewer);
+ }
+ });
+ viewers.add(viewer);
+ }
+
+ /**
+ * Uninstall this filter from the given viewer.
+ *
+ * @param viewer
+ * The viewer from which the filter should be removed.
+ */
+ public void uninstall(TreeViewer viewer) {
+ viewer.removeFilter(this);
+ viewers.remove(viewer);
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/DefaultDifferenceGroup.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/DefaultDifferenceGroup.java
index 1ccb44c..1a98680 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/DefaultDifferenceGroup.java
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/DefaultDifferenceGroup.java
@@ -1,129 +1,137 @@
-/*******************************************************************************
- * Copyright (c) 2012 Obeo.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Obeo - initial API and implementation
- *******************************************************************************/
-package org.eclipse.emf.compare.ide.ui.internal.actions.group;
-
-import com.google.common.base.Predicate;
-import com.google.common.collect.Iterables;
-
-import org.eclipse.emf.compare.Comparison;
-import org.eclipse.emf.compare.Diff;
-import org.eclipse.swt.graphics.Image;
-
-/**
- * This implementation of a {@link DifferenceGroup} uses a predicate to filter the whole list of differences.
- * <p>
- * This can be subclasses or used directly instead of {@link DifferenceGroup}.
- * </p>
- *
- * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
- */
-public class DefaultDifferenceGroup implements DifferenceGroup {
- /** The whole unfiltered list of differences. */
- protected final Iterable<? extends Diff> candidates;
-
- /** The filter we'll use in order to filter the differences that are part of this group. */
- protected final Predicate<? super Diff> filter;
-
- /** The name that the EMF Compare UI will display for this group. */
- protected final String name;
-
- /** The icon that the EMF Compare UI will display for this group. */
- protected final Image image;
-
- /** The comparison that is the parent of this group. */
- protected final Comparison comparison;
-
- /**
- * Instantiates this group given the comparison and filter that should be used in order to determine its
- * list of differences.
- * <p>
- * This will use the default name and icon for the group.
- * </p>
- *
- * @param unfiltered
- * The whole unfiltered list of differences.
- * @param filter
- * The filter we'll use in order to filter the differences that are part of this group.
- */
- public DefaultDifferenceGroup(Comparison comparison, Iterable<? extends Diff> unfiltered,
- Predicate<? super Diff> filter) {
- this(comparison, unfiltered, filter, "Group", null);
- }
-
- /**
- * Instantiates this group given the comparison and filter that should be used in order to determine its
- * list of differences. It will be displayed in the UI with the default icon and the given name.
- *
- * @param unfiltered
- * The whole unfiltered list of differences.
- * @param filter
- * The filter we'll use in order to filter the differences that are part of this group.
- * @param name
- * The name that the EMF Compare UI will display for this group.
- */
- public DefaultDifferenceGroup(Comparison comparison, Iterable<? extends Diff> unfiltered,
- Predicate<? super Diff> filter, String name) {
- this(comparison, unfiltered, filter, name, null);
- }
-
- /**
- * Instantiates this group given the comparison and filter that should be used in order to determine its
- * list of differences. It will be displayed in the UI with the given icon and name.
- *
- * @param unfiltered
- * The whole unfiltered list of differences.
- * @param filter
- * The filter we'll use in order to filter the differences that are part of this group.
- * @param name
- * The name that the EMF Compare UI will display for this group.
- * @param image
- * The icon that the EMF Compare UI will display for this group.
- */
- public DefaultDifferenceGroup(Comparison comparison, Iterable<? extends Diff> unfiltered,
- Predicate<? super Diff> filter, String name, Image image) {
- this.comparison = comparison;
- this.candidates = unfiltered;
- this.filter = filter;
- this.name = name;
- this.image = image;
- }
-
- public Iterable<? extends Diff> getDifferences() {
- return Iterables.filter(candidates, filter);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.actions.group.DifferenceGroup#getComparison()
- */
- public Comparison getComparison() {
- return comparison;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.actions.group.DifferenceGroup#getName()
- */
- public String getName() {
- return name;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.actions.group.DifferenceGroup#getImage()
- */
- public Image getImage() {
- return image;
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * This implementation of a {@link DifferenceGroup} uses a predicate to filter the whole list of differences.
+ * <p>
+ * This can be subclasses or used directly instead of {@link DifferenceGroup}.
+ * </p>
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ * @since 3.0
+ */
+public class DefaultDifferenceGroup implements DifferenceGroup {
+ /** The whole unfiltered list of differences. */
+ protected final Iterable<? extends Diff> candidates;
+
+ /** The filter we'll use in order to filter the differences that are part of this group. */
+ protected final Predicate<? super Diff> filter;
+
+ /** The name that the EMF Compare UI will display for this group. */
+ protected final String name;
+
+ /** The icon that the EMF Compare UI will display for this group. */
+ protected final Image image;
+
+ /** The comparison that is the parent of this group. */
+ protected final Comparison comparison;
+
+ /**
+ * Instantiates this group given the comparison and filter that should be used in order to determine its
+ * list of differences.
+ * <p>
+ * This will use the default name and icon for the group.
+ * </p>
+ *
+ * @param comparison
+ * The comparison that is the parent of this group.
+ * @param unfiltered
+ * The whole unfiltered list of differences.
+ * @param filter
+ * The filter we'll use in order to filter the differences that are part of this group.
+ */
+ public DefaultDifferenceGroup(Comparison comparison, Iterable<? extends Diff> unfiltered,
+ Predicate<? super Diff> filter) {
+ this(comparison, unfiltered, filter, "Group", null); //$NON-NLS-1$
+ }
+
+ /**
+ * Instantiates this group given the comparison and filter that should be used in order to determine its
+ * list of differences. It will be displayed in the UI with the default icon and the given name. * @param
+ * comparison The comparison that is the parent of this group.
+ *
+ * @param comparison
+ * The comparison that is the parent of this group.*
+ * @param unfiltered
+ * The whole unfiltered list of differences.
+ * @param filter
+ * The filter we'll use in order to filter the differences that are part of this group.
+ * @param name
+ * The name that the EMF Compare UI will display for this group.
+ */
+ public DefaultDifferenceGroup(Comparison comparison, Iterable<? extends Diff> unfiltered,
+ Predicate<? super Diff> filter, String name) {
+ this(comparison, unfiltered, filter, name, null);
+ }
+
+ /**
+ * Instantiates this group given the comparison and filter that should be used in order to determine its
+ * list of differences. It will be displayed in the UI with the given icon and name.
+ *
+ * @param comparison
+ * The comparison that is the parent of this group.
+ * @param unfiltered
+ * The whole unfiltered list of differences.
+ * @param filter
+ * The filter we'll use in order to filter the differences that are part of this group.
+ * @param name
+ * The name that the EMF Compare UI will display for this group.
+ * @param image
+ * The icon that the EMF Compare UI will display for this group.
+ */
+ public DefaultDifferenceGroup(Comparison comparison, Iterable<? extends Diff> unfiltered,
+ Predicate<? super Diff> filter, String name, Image image) {
+ this.comparison = comparison;
+ this.candidates = unfiltered;
+ this.filter = filter;
+ this.name = name;
+ this.image = image;
+ }
+
+ public Iterable<? extends Diff> getDifferences() {
+ return Iterables.filter(candidates, filter);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.DifferenceGroup#getComparison()
+ */
+ public Comparison getComparison() {
+ return comparison;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.DifferenceGroup#getName()
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.DifferenceGroup#getImage()
+ */
+ public Image getImage() {
+ return image;
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/DefaultGroupProvider.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/DefaultGroupProvider.java
new file mode 100644
index 0000000..17a9960
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/DefaultGroupProvider.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups;
+
+import java.util.Collections;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.scope.IComparisonScope;
+
+/**
+ * This implementation of a {@link IDifferenceGroupProvider} will be used as the default group provider.
+ *
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ * @since 3.0
+ */
+public class DefaultGroupProvider implements IDifferenceGroupProvider {
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#getGroups(org.eclipse.emf.compare.Comparison)
+ */
+ public Iterable<? extends DifferenceGroup> getGroups(Comparison comparison) {
+
+ return Collections.emptyList();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#getLabel()
+ */
+ public String getLabel() {
+ return "Default"; //$NON-NLS-1$
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#setLabel(java.lang.String)
+ */
+ public void setLabel(String label) {
+
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#defaultSelected()
+ */
+ public boolean defaultSelected() {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#setDefaultSelected(boolean)
+ */
+ public void setDefaultSelected(boolean defaultSelected) {
+
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#isEnabled(org
+ * .eclipse.emf.compare.scope.IComparisonScope, org.eclipse.emf.compare.Comparison)
+ */
+ public boolean isEnabled(IComparisonScope scope, Comparison comparison) {
+ return true;
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/DifferenceGroup.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/DifferenceGroup.java
index 1dbc8bd..e265e7a 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/DifferenceGroup.java
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/DifferenceGroup.java
@@ -1,53 +1,54 @@
-/*******************************************************************************
- * Copyright (c) 2012 Obeo.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Obeo - initial API and implementation
- *******************************************************************************/
-package org.eclipse.emf.compare.ide.ui.internal.actions.group;
-
-import org.eclipse.emf.compare.Comparison;
-import org.eclipse.emf.compare.Diff;
-import org.eclipse.swt.graphics.Image;
-
-/**
- * This interface represents an EMF Compare "group" of differences that can be displayed in the structural
- * differences viewer of the UI.
- *
- * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
- * @see DefaultDifferenceGroup
- */
-public interface DifferenceGroup {
- /**
- * Returns all differences that should be considered a part of this group.
- *
- * @return All differences that should be considered a part of this group.
- */
- Iterable<? extends Diff> getDifferences();
-
- /**
- * Returns the {@link Comparison} in which this group is defined.
- *
- * @return The {@link Comparison} in which this group is defined.
- */
- Comparison getComparison();
-
- /**
- * A human-readable label for this group. This will be displayed in the EMF Compare UI.
- *
- * @return A human-readable label for this group that can be displayed to the user.
- */
- String getName();
-
- /**
- * The icon that is to be used for this group in the compare UI.
- *
- * @return Icon that is to be used for this group in the compare UI. If {@code null}, a default image will
- * be used instead.
- */
- Image getImage();
-}
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * This interface represents an EMF Compare "group" of differences that can be displayed in the structural
+ * differences viewer of the UI.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ * @see DefaultDifferenceGroup
+ * @since 3.0
+ */
+public interface DifferenceGroup {
+ /**
+ * Returns all differences that should be considered a part of this group.
+ *
+ * @return All differences that should be considered a part of this group.
+ */
+ Iterable<? extends Diff> getDifferences();
+
+ /**
+ * Returns the {@link Comparison} in which this group is defined.
+ *
+ * @return The {@link Comparison} in which this group is defined.
+ */
+ Comparison getComparison();
+
+ /**
+ * A human-readable label for this group. This will be displayed in the EMF Compare UI.
+ *
+ * @return A human-readable label for this group that can be displayed to the user.
+ */
+ String getName();
+
+ /**
+ * The icon that is to be used for this group in the compare UI.
+ *
+ * @return Icon that is to be used for this group in the compare UI. If {@code null}, a default image will
+ * be used instead.
+ */
+ Image getImage();
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/IDifferenceGroupProvider.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/IDifferenceGroupProvider.java
new file mode 100644
index 0000000..29ff8bb
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/IDifferenceGroupProvider.java
@@ -0,0 +1,220 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups;
+
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Lists.newArrayList;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.scope.IComparisonScope;
+
+/**
+ * Instances of this class will be used by EMF Compare in order to provide difference grouping facilities to
+ * the structural differences view.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ * @since 3.0
+ */
+public interface IDifferenceGroupProvider {
+
+ /**
+ * This will be called internally by the grouping actions in order to determine how the differences should
+ * be grouped in the structural view.
+ *
+ * @param comparison
+ * The comparison which is to be displayed in the structural view. By default, its containment
+ * tree will be displayed.
+ * @return The collection of difference groups that are to be displayed in the structural viewer. An empty
+ * group will not be displayed at all. If {@code null}, we'll fall back to the default behavior.
+ */
+ Iterable<? extends DifferenceGroup> getGroups(Comparison comparison);
+
+ /**
+ * A human-readable label for this group. This will be displayed in the EMF Compare UI.
+ *
+ * @return The label for this group.
+ */
+ String getLabel();
+
+ /**
+ * Set the label for this group. This will be displayed in the EMF Compare UI.
+ *
+ * @param label
+ * A human-readable label for this group.
+ */
+ void setLabel(String label);
+
+ /**
+ * Returns the initial activation state that the group should have.
+ *
+ * @return The initial activation state that the group should have.
+ */
+ boolean defaultSelected();
+
+ /**
+ * Set the initial activation state that the group should have.
+ *
+ * @param defaultSelected
+ * The initial activation state that the group should have (true if the group should be active
+ * by default).
+ */
+ void setDefaultSelected(boolean defaultSelected);
+
+ /**
+ * Returns the activation condition based on the scope and comparison objects.
+ *
+ * @param scope
+ * The scope on which the group provider will be applied.
+ * @param comparison
+ * The comparison which is to be displayed in the structural view.
+ * @return The activation condition based on the scope and comparison objects.
+ */
+ boolean isEnabled(IComparisonScope scope, Comparison comparison);
+
+ /**
+ * A registry of {@link IDifferenceGroupProvider}.
+ */
+ interface Registry {
+
+ /**
+ * Returns the list of {@link IDifferenceGroupProvider} contained in the registry.
+ *
+ * @param scope
+ * The scope on which the group providers will be applied.
+ * @param comparison
+ * The comparison which is to be displayed in the structural view.
+ * @return The list of {@link IDifferenceGroupProvider} contained in the registry.
+ */
+ Collection<IDifferenceGroupProvider> getGroupProviders(IComparisonScope scope, Comparison comparison);
+
+ /**
+ * Add to the registry the given {@link IDifferenceGroupProvider}.
+ *
+ * @param provider
+ * The given {@link IDifferenceGroupProvider}.
+ * @return The previous value associated with the class name of the given
+ * {@link IDifferenceGroupProvider}, or null if there was no entry in the registry for the
+ * class name.
+ */
+ IDifferenceGroupProvider add(IDifferenceGroupProvider provider);
+
+ /**
+ * Remove from the registry the {@link IDifferenceGroupProvider} designated by the given
+ * {@link String} .
+ *
+ * @param className
+ * The given {@link String} representing a {@link IDifferenceGroupProvider}.
+ * @return The {@link IDifferenceGroupProvider} designated by the given {@link String}.
+ */
+ IDifferenceGroupProvider remove(String className);
+
+ /**
+ * Clear the registry.
+ */
+ void clear();
+ }
+
+ /**
+ * The default implementation of the {@link Registry}.
+ */
+ public class RegistryImpl implements Registry {
+
+ /** A map that associates the class name to theirs {@link IDifferenceGroupProvider}s. */
+ private final Map<String, IDifferenceGroupProvider> map;
+
+ /**
+ * Constructs the registry.
+ */
+ public RegistryImpl() {
+ map = new ConcurrentHashMap<String, IDifferenceGroupProvider>();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider.Registry#getGroupProviders(IComparisonScope,
+ * Comparison)
+ */
+ public List<IDifferenceGroupProvider> getGroupProviders(IComparisonScope scope, Comparison comparison) {
+ Iterable<IDifferenceGroupProvider> providers = filter(map.values(), isGroupProviderActivable(
+ scope, comparison));
+ List<IDifferenceGroupProvider> ret = newArrayList();
+ for (IDifferenceGroupProvider provider : providers) {
+ ret.add(provider);
+ }
+ return ret;
+ }
+
+ /**
+ * Returns a predicate that represents the activation condition based on the scope and comparison
+ * objects.
+ *
+ * @param scope
+ * The scope on which the group provider will be applied.
+ * @param comparison
+ * The comparison which is to be displayed in the structural view.
+ * @return A predicate that represents the activation condition based on the scope and comparison
+ * objects.
+ */
+ static final Predicate<IDifferenceGroupProvider> isGroupProviderActivable(
+ final IComparisonScope scope, final Comparison comparison) {
+ return new Predicate<IDifferenceGroupProvider>() {
+ /**
+ * {@inheritDoc}
+ *
+ * @see com.google.common.base.Predicate#apply(java.lang.Object)
+ */
+ public boolean apply(IDifferenceGroupProvider d) {
+ return d.isEnabled(scope, comparison);
+ }
+ };
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider.Registry#add
+ * (org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider)
+ */
+ public IDifferenceGroupProvider add(IDifferenceGroupProvider provider) {
+ Preconditions.checkNotNull(provider);
+ return map.put(provider.getClass().getName(), provider);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider.Registry#remove(java.lang.String)
+ * )
+ */
+ public IDifferenceGroupProvider remove(String className) {
+ return map.remove(className);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider.Registry#clear()
+ */
+ public void clear() {
+ map.clear();
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/KindGroupProvider.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/KindGroupProvider.java
new file mode 100644
index 0000000..1ad4614
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/KindGroupProvider.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups;
+
+import static org.eclipse.emf.compare.utils.EMFComparePredicates.ofKind;
+
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.DifferenceKind;
+import org.eclipse.emf.compare.scope.IComparisonScope;
+
+/**
+ * This implementation of a {@link IDifferenceGroupProvider} will be used to group the differences by their
+ * {@link DifferenceKind kind} : additions, deletions, changes and moves.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ * @since 3.0
+ */
+public class KindGroupProvider implements IDifferenceGroupProvider {
+
+ /** A human-readable label for this group provider. This will be displayed in the EMF Compare UI. */
+ private String label;
+
+ /** The initial activation state of the group provider. */
+ private boolean activeByDefault;
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#getGroups(org.eclipse.emf.compare.Comparison)
+ */
+ public Iterable<? extends DifferenceGroup> getGroups(Comparison comparison) {
+ final List<Diff> diffs = comparison.getDifferences();
+
+ final DifferenceGroup additions = new DefaultDifferenceGroup(comparison, diffs,
+ ofKind(DifferenceKind.ADD), "Additions"); //$NON-NLS-1$
+ final DifferenceGroup deletions = new DefaultDifferenceGroup(comparison, diffs,
+ ofKind(DifferenceKind.DELETE), "Deletions"); //$NON-NLS-1$
+ final DifferenceGroup changes = new DefaultDifferenceGroup(comparison, diffs,
+ ofKind(DifferenceKind.CHANGE), "Changes"); //$NON-NLS-1$
+ final DifferenceGroup moves = new DefaultDifferenceGroup(comparison, diffs,
+ ofKind(DifferenceKind.MOVE), "Moves"); //$NON-NLS-1$
+
+ return ImmutableList.of(additions, deletions, changes, moves);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#getLabel()
+ */
+ public String getLabel() {
+ return label;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#setLabel(java.lang.String)
+ */
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#defaultSelected()
+ */
+ public boolean defaultSelected() {
+ return activeByDefault;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#setDefaultSelected(boolean)
+ */
+ public void setDefaultSelected(boolean activeByDefault) {
+ this.activeByDefault = activeByDefault;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#isEnabled(org
+ * .eclipse.emf.compare.scope.IComparisonScope, org.eclipse.emf.compare.Comparison)
+ */
+ public boolean isEnabled(IComparisonScope scope, Comparison comparison) {
+ return true;
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/MetamodelGroupProvider.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/MetamodelGroupProvider.java
index 3ad299a..3c61cc0 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/MetamodelGroupProvider.java
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/MetamodelGroupProvider.java
@@ -1,97 +1,159 @@
-/*******************************************************************************
- * Copyright (c) 2012 Obeo.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Obeo - initial API and implementation
- *******************************************************************************/
-package org.eclipse.emf.compare.ide.ui.internal.actions.group;
-
-import static com.google.common.base.Predicates.alwaysTrue;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.emf.compare.AttributeChange;
-import org.eclipse.emf.compare.Comparison;
-import org.eclipse.emf.compare.Diff;
-import org.eclipse.emf.compare.Match;
-import org.eclipse.emf.compare.ReferenceChange;
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EObject;
-
-/**
- * This implementation of a {@link DifferenceGroupProvider} will be used to group the differences by their
- * metamodel element : all diffs that apply to a Class, all diffs that apply on a reference...
- *
- * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
- */
-public class MetamodelGroupProvider implements DifferenceGroupProvider {
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.actions.group.DifferenceGroupProvider#getGroups(org.eclipse.emf.compare.Comparison)
- */
- public Iterable<? extends DifferenceGroup> getGroups(Comparison comparison) {
- final List<Diff> diffs = comparison.getDifferences();
-
- final Map<EClass, List<Diff>> diffByEClass = Maps.newLinkedHashMap();
- for (Diff candidate : diffs) {
- final EClass target;
- if (candidate instanceof ReferenceChange) {
- if (((ReferenceChange)candidate).getReference().isContainment()) {
- final EObject parentMatch = candidate.getMatch().eContainer();
- if (parentMatch instanceof Match) {
- target = findEClass((Match)parentMatch);
- } else {
- target = findEClass(candidate.getMatch());
- }
- } else {
- target = findEClass(candidate.getMatch());
- }
- } else if (candidate instanceof AttributeChange) {
- target = findEClass(candidate.getMatch());
- } else {
- // Ignore this possibility for now.
- continue;
- }
-
- List<Diff> diffsForEClass = diffByEClass.get(target);
- if (diffsForEClass == null) {
- diffsForEClass = Lists.newArrayList();
- diffByEClass.put(target, diffsForEClass);
- }
- diffsForEClass.add(candidate);
- }
-
- final List<DifferenceGroup> groups = Lists.newArrayList();
- for (Map.Entry<EClass, List<Diff>> entry : diffByEClass.entrySet()) {
- groups.add(new DefaultDifferenceGroup(comparison, entry.getValue(), alwaysTrue(), entry.getKey()
- .getName()));
- }
-
- return groups;
- }
-
- private EClass findEClass(Match match) {
- final EClass eClass;
- if (match.getOrigin() != null) {
- eClass = match.getOrigin().eClass();
- } else if (match.getRight() != null) {
- eClass = match.getRight().eClass();
- } else {
- /*
- * All three sides null means that something went awry. Might as well throw the exception from
- * here.
- */
- eClass = match.getLeft().eClass();
- }
- return eClass;
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups;
+
+import static com.google.common.base.Predicates.alwaysTrue;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.emf.compare.AttributeChange;
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.Match;
+import org.eclipse.emf.compare.ReferenceChange;
+import org.eclipse.emf.compare.scope.IComparisonScope;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+
+/**
+ * This implementation of a {@link IDifferenceGroupProvider} will be used to group the differences by their
+ * metamodel element : all diffs that apply to a Class, all diffs that apply on a reference...
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ * @since 3.0
+ */
+public class MetamodelGroupProvider implements IDifferenceGroupProvider {
+
+ /** A human-readable label for this group provider. This will be displayed in the EMF Compare UI. */
+ private String label;
+
+ /** The initial activation state of the group provider. */
+ private boolean activeByDefault;
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#getGroups(org.eclipse.emf.compare.Comparison)
+ */
+ public Iterable<? extends DifferenceGroup> getGroups(Comparison comparison) {
+ final List<Diff> diffs = comparison.getDifferences();
+
+ final Map<EClass, List<Diff>> diffByEClass = Maps.newLinkedHashMap();
+ for (Diff candidate : diffs) {
+ final EClass target;
+ if (candidate instanceof ReferenceChange) {
+ if (((ReferenceChange)candidate).getReference().isContainment()) {
+ final EObject parentMatch = candidate.getMatch().eContainer();
+ if (parentMatch instanceof Match) {
+ target = findEClass((Match)parentMatch);
+ } else {
+ target = findEClass(candidate.getMatch());
+ }
+ } else {
+ target = findEClass(candidate.getMatch());
+ }
+ } else if (candidate instanceof AttributeChange) {
+ target = findEClass(candidate.getMatch());
+ } else {
+ // Ignore this possibility for now.
+ continue;
+ }
+
+ List<Diff> diffsForEClass = diffByEClass.get(target);
+ if (diffsForEClass == null) {
+ diffsForEClass = Lists.newArrayList();
+ diffByEClass.put(target, diffsForEClass);
+ }
+ diffsForEClass.add(candidate);
+ }
+
+ final List<DifferenceGroup> groups = Lists.newArrayList();
+ for (Map.Entry<EClass, List<Diff>> entry : diffByEClass.entrySet()) {
+ groups.add(new DefaultDifferenceGroup(comparison, entry.getValue(), alwaysTrue(), entry.getKey()
+ .getName()));
+ }
+
+ return groups;
+ }
+
+ /**
+ * Returns the appropriate {@link EClass} associated with the given {@link Match}.
+ *
+ * @param match
+ * The given {@link Match}.
+ * @return the appropriate {@link EClass} associated with the given {@link Match}.
+ */
+ private EClass findEClass(Match match) {
+ final EClass eClass;
+ if (match.getOrigin() != null) {
+ eClass = match.getOrigin().eClass();
+ } else if (match.getRight() != null) {
+ eClass = match.getRight().eClass();
+ } else {
+ /*
+ * All three sides null means that something went awry. Might as well throw the exception from
+ * here.
+ */
+ eClass = match.getLeft().eClass();
+ }
+ return eClass;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#getLabel()
+ */
+ public String getLabel() {
+ return label;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#setLabel(java.lang.String)
+ */
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#defaultSelected()
+ */
+ public boolean defaultSelected() {
+ return activeByDefault;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#setDefaultSelected(boolean)
+ */
+ public void setDefaultSelected(boolean activeByDefault) {
+ this.activeByDefault = activeByDefault;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#isEnabled(org
+ * .eclipse.emf.compare.scope.IComparisonScope, org.eclipse.emf.compare.Comparison)
+ */
+ public boolean isEnabled(IComparisonScope scope, Comparison comparison) {
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/DifferenceGrouper.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/StructureMergeViewerGrouper.java
index a1c3182..0b8564d 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/DifferenceGrouper.java
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/StructureMergeViewerGrouper.java
@@ -1,131 +1,147 @@
-/*******************************************************************************
- * Copyright (c) 2012 Obeo.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Obeo - initial API and implementation
- *******************************************************************************/
-package org.eclipse.emf.compare.ide.ui.internal.actions.group;
-
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-
-import java.util.List;
-
-import org.eclipse.emf.compare.Comparison;
-import org.eclipse.jface.viewers.TreePath;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-
-/**
- * This class will be used by the EMF Compare UI to group differences together in the structural differences
- * tree viewer.
- *
- * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
- */
-public final class DifferenceGrouper {
- /**
- * The currently selected group provider. This is what will compute and give us the groups we need to
- * display.
- */
- private DifferenceGroupProvider provider;
-
- /** List of all TreeViewers on which this filter is applied. */
- private List<TreeViewer> viewers = Lists.newArrayList();
-
- /**
- * This will be called internally by the ComparisonNode in order to know how it should group its
- * differences.
- *
- * @param comparison
- * The comparison which differences need to be grouped.
- * @return The collection of groups we could retrieve from the currently selected group provider. Empty
- * {@link Iterable} if we have no group provider set.
- */
- public Iterable<? extends DifferenceGroup> getGroups(final Comparison comparison) {
- if (provider == null) {
- return ImmutableList.of();
- }
-
- final Iterable<? extends DifferenceGroup> groups = provider.getGroups(comparison);
- final Iterable<? extends DifferenceGroup> filteredGroups = Iterables.filter(groups,
- new NonEmptyGroup());
- return filteredGroups;
- }
-
- /**
- * Sets the instance that will provide the groups to be displayed in the structural differences view.
- *
- * @param provider
- * The provider that will be use to compute the groups that are to be displayed in the UI.
- */
- public void setProvider(DifferenceGroupProvider provider) {
- if (this.provider != provider) {
- this.provider = provider;
- refreshViewers();
- }
- }
-
- /**
- * Refreshes the viewers registered with this filter. Will try and conserve the expanded tree paths when
- * possible.
- */
- private void refreshViewers() {
- for (TreeViewer viewer : viewers) {
- final TreePath[] paths = viewer.getExpandedTreePaths();
- viewer.refresh();
- viewer.setExpandedTreePaths(paths);
- }
- }
-
- /**
- * Install this filter on the given viewer.
- * <p>
- * Note that this will also install a dispose listener on that viewer in order to remove the filter
- * whenever the viewer is disposed.
- * </p>
- *
- * @param viewer
- * the viewer on which the filter will be installed
- */
- public void install(final TreeViewer viewer) {
- viewer.getTree().addDisposeListener(new DisposeListener() {
- public void widgetDisposed(DisposeEvent e) {
- uninstall(viewer);
- }
- });
- viewers.add(viewer);
- }
-
- /**
- * Uninstall this filter from the given viewer.
- *
- * @param viewer
- * The viewer from which the filter should be removed.
- */
- public void uninstall(TreeViewer viewer) {
- viewers.remove(viewer);
- }
-
- /**
- * This predicate will be used to filter the empty groups out of the displayed list.
- *
- * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
- */
- private static class NonEmptyGroup implements Predicate<DifferenceGroup> {
- /**
- * {@inheritDoc}
- *
- * @see com.google.common.base.Predicate#apply(java.lang.Object)
- */
- public boolean apply(DifferenceGroup input) {
- return input != null && !Iterables.isEmpty(input.getDifferences());
- }
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2012 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.eventbus.EventBus;
+
+import java.util.List;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.jface.viewers.TreePath;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+
+/**
+ * This class will be used by the EMF Compare UI to group differences together in the structural differences
+ * tree viewer.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ * @since 3.0
+ */
+public final class StructureMergeViewerGrouper {
+ /**
+ * The currently selected group provider. This is what will compute and give us the groups we need to
+ * display.
+ */
+ private IDifferenceGroupProvider provider;
+
+ /** List of all TreeViewers on which this grouper is applied. */
+ private List<TreeViewer> viewers = Lists.newArrayList();
+
+ /** The {@link EventBus} associated with this grouper. */
+ private EventBus eventBus;
+
+ /**
+ * Constructs the difference grouper.
+ *
+ * @param eventBus
+ * The {@link EventBus} which will be associated with this difference grouper.
+ */
+ public StructureMergeViewerGrouper(EventBus eventBus) {
+ this.eventBus = eventBus;
+ }
+
+ /**
+ * This will be called internally by the ComparisonNode in order to know how it should group its
+ * differences.
+ *
+ * @param comparison
+ * The comparison which differences need to be grouped.
+ * @return The collection of groups we could retrieve from the currently selected group provider. Empty
+ * {@link Iterable} if we have no group provider set.
+ */
+ public Iterable<? extends DifferenceGroup> getGroups(final Comparison comparison) {
+ if (provider == null) {
+ return ImmutableList.of();
+ }
+
+ final Iterable<? extends DifferenceGroup> groups = provider.getGroups(comparison);
+ final Iterable<? extends DifferenceGroup> filteredGroups = Iterables.filter(groups,
+ new NonEmptyGroup());
+ return filteredGroups;
+ }
+
+ /**
+ * Sets the instance that will provide the groups to be displayed in the structural differences view.
+ *
+ * @param provider
+ * The provider that will be use to compute the groups that are to be displayed in the UI.
+ */
+ public void setProvider(IDifferenceGroupProvider provider) {
+ if (this.provider != provider) {
+ this.provider = provider;
+ eventBus.post(provider);
+ refreshViewers();
+ }
+ }
+
+ /**
+ * Refreshes the viewers registered with this grouper. Will try and conserve the expanded tree paths when
+ * possible.
+ */
+ private void refreshViewers() {
+ for (TreeViewer viewer : viewers) {
+ final TreePath[] paths = viewer.getExpandedTreePaths();
+ viewer.refresh();
+ viewer.setExpandedTreePaths(paths);
+ }
+ }
+
+ /**
+ * Install this grouper on the given viewer.
+ * <p>
+ * Note that this will also install a dispose listener on that viewer in order to remove the grouper
+ * whenever the viewer is disposed.
+ * </p>
+ *
+ * @param viewer
+ * The viewer on which the grouper will be installed.
+ */
+ public void install(final TreeViewer viewer) {
+ viewer.getTree().addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ uninstall(viewer);
+ }
+ });
+ viewers.add(viewer);
+ }
+
+ /**
+ * Uninstall this grouper from the given viewer.
+ *
+ * @param viewer
+ * The viewer from which the grouper should be removed.
+ */
+ public void uninstall(TreeViewer viewer) {
+ viewers.remove(viewer);
+ }
+
+ /**
+ * This predicate will be used to filter the empty groups out of the displayed list.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ */
+ private static class NonEmptyGroup implements Predicate<DifferenceGroup> {
+ /**
+ * {@inheritDoc}
+ *
+ * @see com.google.common.base.Predicate#apply(java.lang.Object)
+ */
+ public boolean apply(DifferenceGroup input) {
+ return input != null && !Iterables.isEmpty(input.getDifferences());
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/ThreeWayComparisonGroupProvider.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/ThreeWayComparisonGroupProvider.java
new file mode 100644
index 0000000..6e1f8ec
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/ThreeWayComparisonGroupProvider.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups;
+
+import static org.eclipse.emf.compare.utils.EMFComparePredicates.fromSide;
+import static org.eclipse.emf.compare.utils.EMFComparePredicates.hasConflict;
+
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.ConflictKind;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.DifferenceSource;
+import org.eclipse.emf.compare.scope.IComparisonScope;
+
+/**
+ * This implementation of a {@link IDifferenceGroupProvider} will be used to group the differences by their
+ * {@link DifferenceSource side} : left, right and conflicts.
+ *
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ * @since 3.0
+ */
+public class ThreeWayComparisonGroupProvider implements IDifferenceGroupProvider {
+
+ /** A human-readable label for this group provider. This will be displayed in the EMF Compare UI. */
+ private String label;
+
+ /** The initial activation state of the group provider. */
+ private boolean activeByDefault;
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#getGroups(org.eclipse.emf.compare.Comparison)
+ */
+ public Iterable<? extends DifferenceGroup> getGroups(Comparison comparison) {
+ final List<Diff> diffs = comparison.getDifferences();
+
+ final DifferenceGroup leftSide = new DefaultDifferenceGroup(comparison, diffs, Predicates.and(
+ fromSide(DifferenceSource.LEFT), Predicates.not(hasConflict(ConflictKind.REAL))), "Left side"); //$NON-NLS-1$
+ final DifferenceGroup rightSide = new DefaultDifferenceGroup(comparison, diffs, Predicates.and(
+ fromSide(DifferenceSource.RIGHT), Predicates.not(hasConflict(ConflictKind.REAL))),
+ "Right side"); //$NON-NLS-1$
+ final DifferenceGroup conflicts = new DefaultDifferenceGroup(comparison, diffs,
+ hasConflict(ConflictKind.REAL), "Conflicts"); //$NON-NLS-1$
+
+ return ImmutableList.of(leftSide, rightSide, conflicts);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#getLabel()
+ */
+ public String getLabel() {
+ return label;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#setLabel(java.lang.String)
+ */
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#defaultSelected()
+ */
+ public boolean defaultSelected() {
+ return activeByDefault;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#setDefaultSelected(boolean)
+ */
+ public void setDefaultSelected(boolean activeByDefault) {
+ this.activeByDefault = activeByDefault;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#isEnabled(org
+ * .eclipse.emf.compare.scope.IComparisonScope, org.eclipse.emf.compare.Comparison)
+ */
+ public boolean isEnabled(IComparisonScope scope, Comparison comparison) {
+ if (comparison != null && comparison.isThreeWay()) {
+ return true;
+ }
+ return false;
+ }
+
+}