Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMathieu Cartaud2015-07-17 07:35:01 +0000
committerAxel RICHARD2015-09-03 07:49:14 +0000
commit54f662646eb4ab26ab9db705353e208d86dddcc9 (patch)
tree8eb2360074e24f2c2a2317c14c51dbc2fcc01d7f /plugins/org.eclipse.emf.compare.ide.ui
parentcbcf4cee26550619875225a30418aaa186627fdf (diff)
downloadorg.eclipse.emf.compare-54f662646eb4ab26ab9db705353e208d86dddcc9.tar.gz
org.eclipse.emf.compare-54f662646eb4ab26ab9db705353e208d86dddcc9.tar.xz
org.eclipse.emf.compare-54f662646eb4ab26ab9db705353e208d86dddcc9.zip
Implementation of contextual tooltips
1) add tooltips for CHANGE, ADD, DELETE, MOVE actions 2) add adapter for semantic object to compute labels 3) add unit tests Change-Id: I808c8931e79fc4e10ea0778272b8478e6b1340e0 Signed-off-by: Mathieu Cartaud <mathieu.cartaud@obeo.fr>
Diffstat (limited to 'plugins/org.eclipse.emf.compare.ide.ui')
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/ide_ui_messages.properties109
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewer.java3
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/AbstractTooltipManager.java187
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/AddTooltipManager.java257
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/ChangeTooltipManager.java383
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/DeleteTooltipManager.java194
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MergeAction.java93
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MoveTooltipManager.java271
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/TooltipFactory.java94
9 files changed, 1584 insertions, 7 deletions
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/ide_ui_messages.properties b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/ide_ui_messages.properties
index a15124569..461acec4e 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/ide_ui_messages.properties
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/ide_ui_messages.properties
@@ -30,15 +30,19 @@ save.model.tooltip = Save Comparison Model
next.diff.tooltip = Next Difference
previous.diff.tooltip = Previous Difference
accept.change.tooltip = Accept Change
-accept.all.changes.tooltip = Accept All Non-Conflicting Changes
+accept.multiple.changes.tooltip = Accept non-conflicting changes from the current selection
+accept.all.changes.tooltip = Accept All Non-Conflicting Changes. The left changes will be accepted and the right changes will be merged into the left-hand side
accept.contained.changes.tooltip = Accept Contained Non-Conflicting Changes
reject.change.tooltip = Reject Change
-reject.all.changes.tooltip = Reject All Non-Conflicting Changes
+reject.multiple.changes.tooltip = Reject non-conflicting changes from the current selection
+reject.all.changes.tooltip = Reject All Non-Conflicting Changes. The left changes will be rejected and the right changes will not be used
reject.contained.changes.tooltip = Reject Contained Non-Conflicting Changes
merged.to.left.tooltip = Copy Current Change From Right To Left
+merged.multiple.to.left.tooltip = Apply on the left-hand side all non-conflicting changes from the current selection
merged.to.right.tooltip = Copy Current Change From Left To Right
-merged.all.to.left.tooltip = Copy All Non-Conflicting Changes From Right To Left
-merged.all.to.right.tooltip = Copy All Non-Conflicting Changes From Left To Right
+merged.multiple.to.right.tooltip = Apply on the right-hand side all non-conflicting changes from the current selection
+merged.all.to.left.tooltip = Apply all right changes on the left-hand side. The right-hand side will remain unchanged
+merged.all.to.right.tooltip = Apply all left changes on the right-hand side. The left-hand side will remain unchanged
merged.contained.to.left.tooltip = Apply Contained Non-conflicting Right Changes on the Left-hand Side
merged.contained.to.right.tooltip = Apply Contained Non-conflicting Left Changes on the Right-hand Side
dropdown.left.to.right.text = Show consequences of merging from left to right
@@ -116,3 +120,100 @@ LogicalModelView.listPresentation.title = List
LogicalModelView.treePresentation.title = Tree
LogicalModelView.errorDialog.title = EMF Compare - Logical Model View
LogicalModelView.errorDialog.message = Error while computing logical models. See error log for more details.
+
+ContextualTooltip.acceptChange = Accept the change.
+ContextualTooltip.rejectChange = Reject the change.
+ContextualTooltip.readonly.leftUnchanged = The left-hand side will remain unchanged.
+ContextualTooltip.readonly.leftChanged = The left-hand side will be modified.
+ContextualTooltip.editable.rightChanged = The left-hand side will remain unchanged.\nThe right-hand side will be modified.
+ContextualTooltip.editable.rightUnchanged = The left-hand side will be modified.\nThe right-hand side will remain unchanged.
+
+# Accept contextual tooltips
+ContextualTooltip.set.left.accept = Keep ''{0}'' in ''{1}'' of this ''{2}'' on the left-hand side.
+ContextualTooltip.set.right.accept = Set the ''{0}'' of this ''{1}'' to ''{2}'' (instead of ''{3}'') on the left-hand side.
+ContextualTooltip.set.right.accept.empty = Set the ''{0}'' of this ''{1}'' to ''{2}'' on the left-hand side.
+ContextualTooltip.unset.left.accept = Keep the ''{0}'' of this ''{1}'' unset on the left-hand side.
+ContextualTooltip.unset.right.accept = Unset the ''{0}'' of this ''{1}'' (currently ''{2}'') on the left-hand side.
+ContextualTooltip.move.container.left.accept = Keep ''{0}'' in ''{1}'' on the left-hand side.
+ContextualTooltip.move.position.left.container.accept = Keep ''{0}'' at its current position in ''{1}'' on the left-hand side.
+ContextualTooltip.move.position.left.accept = Keep ''{0}'' at its current position on the left-hand side.
+ContextualTooltip.move.container.right.accept = Move ''{0}'' in ''{1}'' (currently in ''{2}'') on the left-hand side.
+ContextualTooltip.move.position.right.container.accept = Move the position of ''{0}'' in ''{1}'' on the left-hand side.
+ContextualTooltip.move.position.right.accept = Move the position of ''{0}'' on the left-hand side.
+ContextualTooltip.add.containment.left.accept = Keep ''{0}'' in ''{1}'' on the left-hand side.
+ContextualTooltip.add.nonContainment.left.accept = Keep ''{0}'' on the left-hand side.
+ContextualTooltip.add.attribute.left.accept = Keep ''{0}'' in ''{1}'' on the left-hand side.
+ContextualTooltip.add.containment.right.accept = Add ''{0}'' in ''{1}'' on the left-hand side.
+ContextualTooltip.add.nonContainment.right.accept = Add ''{0}'' on the left-hand side.
+ContextualTooltip.add.attribute.right.accept = Add ''{0}'' in ''{1}'' on the left-hand side.
+ContextualTooltip.delete.containment.left.accept = Keep the deletion of ''{0}'' from ''{1}'' on the left-hand side.
+ContextualTooltip.delete.nonContainment.left.accept = Keep the deletion of ''{0}'' on the left-hand side.
+ContextualTooltip.delete.containment.right.accept = Delete ''{0}'' in ''{1}'' on the left-hand side.
+ContextualTooltip.delete.nonContainment.right.accept = Delete ''{0}'' on the left-hand side.
+
+# Reject contextual tooltips
+ContextualTooltip.set.left.reject = Restore the ''{0}'' of this ''{1}'' to ''{2}'' (instead of ''{3}'') on the left-hand side.
+ContextualTooltip.set.left.reject.empty = Clear the ''{0}'' of this ''{1}'' (currently ''{2}'') on the left-hand side.
+ContextualTooltip.set.right.reject = Keep ''{0}'' in ''{1}'' of this ''{2}'' on the left-hand side.
+ContextualTooltip.set.right.reject.empty = Keep the ''{0}'' of this ''{1}'' empty on the left-hand side.
+ContextualTooltip.unset.left.reject = Restore the ''{0}'' of this ''{1}'' to ''{2}'' on the left-hand side.
+ContextualTooltip.unset.right.reject = Keep the ''{0}'' of this ''{1}'' set to ''{2}'' on the left-hand side.
+ContextualTooltip.move.container.left.reject = Restore ''{0}'' in ''{1}'' (currently in ''{2}'') on the left-hand side.
+ContextualTooltip.move.position.left.reject = Restore the original position of ''{0}'' on the left-hand side.
+ContextualTooltip.move.container.right.reject = Keep ''{0}'' in ''{1}'' on the left-hand side.
+ContextualTooltip.move.position.right.reject = Keep ''{0}'' at its current position on the left-hand side.
+ContextualTooltip.move.position.right.container.reject = Keep ''{0}'' at its current position under ''{1}'' on the left-hand side.
+ContextualTooltip.add.containment.left.reject = Delete ''{0}'' in ''{1}'' on the left-hand side.
+ContextualTooltip.add.nonContainment.left.reject = Delete ''{0}'' on the left-hand side.
+ContextualTooltip.add.attribute.left.reject = Delete ''{0}'' from ''{1}'' on the left-hand side.
+ContextualTooltip.add.containment.right.reject = Do not add ''{0}'' in ''{1}'' on the left-hand side.
+ContextualTooltip.add.nonContainment.right.reject = Do not add ''{0}'' on the left-hand side.
+ContextualTooltip.add.attribute.right.reject = Do not add ''{0}'' in ''{1}'' on the left-hand side.
+ContextualTooltip.delete.containment.left.reject = Restore ''{0}'' in ''{1}'' on the left-hand side.
+ContextualTooltip.delete.nonContainment.left.reject = Restore ''{0}'' on the left-hand side.
+ContextualTooltip.delete.containment.right.reject = Keep ''{0}'' in ''{1}'' on the left-hand side.
+ContextualTooltip.delete.nonContainment.right.reject = Keep ''{0}'' on the left-hand side.
+
+# Copy from left to right contextual tooltips
+ContextualTooltip.set.left.leftToRight = Set the ''{0}'' of this ''{1}'' to ''{2}'' on the right-hand side (currently ''{3}'').
+ContextualTooltip.set.left.leftToRight.empty = Set the ''{0}'' of this ''{1}'' to ''{2}'' on the right-hand side.
+ContextualTooltip.set.right.leftToRight = Set the ''{0}'' of this ''{1}'' to ''{2}'' on the right-hand side (instead of ''{3}'').
+ContextualTooltip.set.right.leftToRight.empty = Unset the ''{0}'' of this ''{1}'' (currently ''{2}'') on the right-hand side.
+ContextualTooltip.unset.left.leftToRight = Unset the ''{0}'' of this ''{1}'' on the right-hand side (currently ''{2}'').
+ContextualTooltip.unset.right.leftToRight = Restore the ''{0}'' of this ''{1}'' to ''{2}'' on the right-hand side.
+ContextualTooltip.move.container.left.leftToRight = Move ''{0}'' in ''{1}'' (currently in ''{2}'') on the right-hand side.
+ContextualTooltip.move.container.right.leftToRight = Move ''{0}'' in ''{1}'' (currently in ''{2}'') on the right-hand side.
+ContextualTooltip.move.position.left.leftToRight = Move ''{0}'' on the right-hand side to match its left-hand side position.
+ContextualTooltip.move.position.right.leftToRight = Move ''{0}'' on the right-hand side to match its left-hand side position.
+ContextualTooltip.add.containment.left.leftToRight = Add ''{0}'' in ''{1}'' on the right-hand side.
+ContextualTooltip.add.nonContainment.left.leftToRight = Add ''{0}'' on the right-hand side.
+ContextualTooltip.add.attribute.left.leftToRight = Add ''{0}'' in ''{1}'' on the right-hand side.
+ContextualTooltip.add.containment.right.leftToRight = Delete ''{0}'' in ''{1}'' on the right-hand side.
+ContextualTooltip.add.nonContainment.right.leftToRight = Remove ''{0}'' on the right-hand side.
+ContextualTooltip.add.attribute.right.leftToRight = Delete ''{0}'' in ''{1}'' on the right-hand side.
+ContextualTooltip.delete.containment.left.leftToRight = Delete ''{0}'' from ''{1}'' on the right-hand side.
+ContextualTooltip.delete.nonContainment.left.leftToRight = Delete ''{0}'' on the right-hand side.
+ContextualTooltip.delete.containment.right.leftToRight = Undo the deletion of ''{0}'' from ''{1}'' on the right-hand side.
+ContextualTooltip.delete.nonContainment.right.leftToRight = Undo the deletion of ''{0}'' on the right-hand side.
+
+# Copy from right to left contextual tooltips
+ContextualTooltip.set.right.rightToLeft = Set the ''{0}'' of this ''{1}'' to ''{2}'' on the left-hand side (instead of ''{3}'').
+ContextualTooltip.set.right.rightToLeft.empty = Set the ''{0}'' of this ''{1}'' to ''{2}'' on the left-hand side.
+ContextualTooltip.set.left.rightToLeft = Set the ''{0}'' of this ''{1}'' to ''{2}'' on the left-hand side (instead of ''{3}'').
+ContextualTooltip.set.left.rightToLeft.empty = Clear the ''{0}'' of this ''{1}'' on the left-hand side (currently ''{2}'').
+ContextualTooltip.unset.right.rightToLeft = Unset the ''{0}'' of this ''{1}'' on the left-hand side (currently ''{2}'').
+ContextualTooltip.unset.left.rightToLeft = Restore the ''{0}'' of this ''{1}'' to ''{2}'' on the left-hand side.
+ContextualTooltip.move.container.right.rightToLeft = Move ''{0}'' in ''{1}'' (currently in ''{2}'') on the left-hand side.
+ContextualTooltip.move.position.right.rightToLeft = Move ''{0}'' on the left-hand side to match its right-hand side position.
+ContextualTooltip.move.container.left.rightToLeft = Move ''{0}'' in ''{1}'' (currently in ''{2}'') on the left-hand side.
+ContextualTooltip.move.position.left.rightToLeft = Move ''{0}'' on the left-hand side to match its right-hand side position.
+ContextualTooltip.add.containment.right.rightToLeft = Add ''{0}'' in ''{1}'' on the left-hand side.
+ContextualTooltip.add.nonContainment.right.rightToLeft = Add ''{0}'' on the left-hand side.
+ContextualTooltip.add.attribute.left.rightToLeft = Delete ''{0}'' in ''{1}'' on the left-hand side.
+ContextualTooltip.add.containment.left.rightToLeft = Delete ''{0}'' in ''{1}'' on the left-hand side.
+ContextualTooltip.add.nonContainment.left.rightToLeft = Remove ''{0}'' on the left-hand side.
+ContextualTooltip.add.attribute.right.rightToLeft = Add ''{0}'' in ''{1}'' on the left-hand side.
+ContextualTooltip.delete.containment.right.rightToLeft = Delete ''{0}'' in ''{1}'' on the left-hand side.
+ContextualTooltip.delete.containment.left.rightToLeft = Undo the deletion of ''{0}'' in ''{1}'' on the left-hand side.
+ContextualTooltip.delete.nonContainment.right.rightToLeft = Delete ''{0}'' on the left-hand side.
+ContextualTooltip.delete.nonContainment.left.rightToLeft = Undo the deletion of ''{0}'' on the left-hand side. \ No newline at end of file
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 539e8a4bd..7020a3877 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
@@ -1130,8 +1130,6 @@ public class EMFCompareStructureMergeViewer extends AbstractStructuredViewerWrap
((NotLoadingResourceSet)originResourceSet).setAllowResourceLoad(true);
}
- initToolbar();
-
IStorage leftStorage = PlatformElementUtil.findFile(left);
if (leftStorage == null) {
leftStorage = StreamAccessorStorage.fromTypedElement(left);
@@ -1144,6 +1142,7 @@ public class EMFCompareStructureMergeViewer extends AbstractStructuredViewerWrap
EMFCompareRCPUIPlugin.getDefault().setEMFCompareConfiguration(compareConfiguration);
}
+ initToolbar();
compareInputChanged(scope, compareResult);
}
// Protect compare actions from over-enthusiast users
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/AbstractTooltipManager.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/AbstractTooltipManager.java
new file mode 100644
index 000000000..093c35ac2
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/AbstractTooltipManager.java
@@ -0,0 +1,187 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Obeo and others.
+ * 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.actions;
+
+import static org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIMessages.getString;
+
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.ReferenceChange;
+import org.eclipse.emf.compare.provider.ISemanticObjectLabelProvider;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
+
+/**
+ * This class defines usual methods for contextual tooltips.
+ *
+ * @author <a href="mailto:mathieu.cartaud@obeo.fr">Mathieu Cartaud</a>
+ */
+public abstract class AbstractTooltipManager {
+
+ /**
+ * The line separator used to compute tooltips.
+ */
+ private static final String LINE_SEPARATOR = "\n"; //$NON-NLS-1$
+
+ /**
+ * The adapter factory.
+ */
+ protected AdapterFactory adapterFactory;
+
+ /**
+ * The label provider.
+ */
+ protected AdapterFactoryLabelProvider labelProvider;
+
+ /**
+ * Check if the given diff is a reference change.
+ *
+ * @param diff
+ * The given diff
+ * @return <code>true</code> if the diff is a containment reference change <code>false</code> otherwise
+ */
+ protected boolean isContainmentReferenceChange(Diff diff) {
+ boolean isContainmentReference = false;
+ if (diff instanceof ReferenceChange) {
+ if (((ReferenceChange)diff).getReference().isContainment()) {
+ isContainmentReference = true;
+ }
+ }
+ return isContainmentReference;
+ }
+
+ /**
+ * Create the final tooltip for an accepted change which lead to a modification of the left side.
+ *
+ * @param value
+ * The body of the tooltip
+ * @return the complete tooltip
+ */
+ protected String acceptAndChanged(String value) {
+ String accept = getString("ContextualTooltip.acceptChange"); //$NON-NLS-1$
+ String modify = getString("ContextualTooltip.readonly.leftChanged"); //$NON-NLS-1$
+
+ StringBuilder builder = new StringBuilder();
+ builder.append(accept).append(LINE_SEPARATOR).append(value).append(LINE_SEPARATOR).append(modify);
+ return builder.toString();
+ }
+
+ /**
+ * Create the final tooltip for an accepted change which don't lead to a modification of the left side.
+ *
+ * @param value
+ * The body of the tooltip
+ * @return the complete tooltip
+ */
+ protected String acceptAndUnchanged(String value) {
+ String accept = getString("ContextualTooltip.acceptChange"); //$NON-NLS-1$
+ String modify = getString("ContextualTooltip.readonly.leftUnchanged"); //$NON-NLS-1$
+
+ StringBuilder builder = new StringBuilder();
+ builder.append(accept).append(LINE_SEPARATOR).append(value).append(LINE_SEPARATOR).append(modify);
+ return builder.toString();
+ }
+
+ /**
+ * Create the final tooltip for a rejected change which lead to a modification of the left side.
+ *
+ * @param value
+ * The body of the tooltip
+ * @return the complete tooltip
+ */
+ protected String rejectAndChanged(String value) {
+ String accept = getString("ContextualTooltip.rejectChange"); //$NON-NLS-1$
+ String modify = getString("ContextualTooltip.readonly.leftChanged"); //$NON-NLS-1$
+
+ StringBuilder builder = new StringBuilder();
+ builder.append(accept).append(LINE_SEPARATOR).append(value).append(LINE_SEPARATOR).append(modify);
+ return builder.toString();
+ }
+
+ /**
+ * Create the final tooltip for a rejected change which don't lead to a modification of the left side.
+ *
+ * @param value
+ * The body of the tooltip
+ * @return the complete tooltip
+ */
+ protected String rejectAndUnchanged(String value) {
+ String accept = getString("ContextualTooltip.rejectChange"); //$NON-NLS-1$
+ String modify = getString("ContextualTooltip.readonly.leftUnchanged"); //$NON-NLS-1$
+
+ StringBuilder builder = new StringBuilder();
+ builder.append(accept).append(LINE_SEPARATOR).append(value).append(LINE_SEPARATOR).append(modify);
+ return builder.toString();
+ }
+
+ /**
+ * Create the final tooltip for a change with two editable files which don't lead to a modification of the
+ * right side.
+ *
+ * @param value
+ * The body of the tooltip
+ * @return the complete tooltip
+ */
+ protected String rightUnchanged(String value) {
+ String modify = getString("ContextualTooltip.editable.rightUnchanged"); //$NON-NLS-1$
+
+ StringBuilder builder = new StringBuilder();
+ builder.append(value).append(LINE_SEPARATOR).append(modify);
+ return builder.toString();
+ }
+
+ /**
+ * Create the final tooltip for a change with two editable files which lead to a modification of the right
+ * side.
+ *
+ * @param value
+ * The body of the tooltip
+ * @return the complete tooltip
+ */
+ protected String rightChanged(String value) {
+ String modify = getString("ContextualTooltip.editable.rightChanged"); //$NON-NLS-1$
+
+ StringBuilder builder = new StringBuilder();
+ builder.append(value).append(LINE_SEPARATOR).append(modify);
+ return builder.toString();
+ }
+
+ /**
+ * Returns the label of the given <code>object</code> by adapting it to
+ * {@link ISemanticObjectLabelProvider} and asking for its
+ * {@link ISemanticObjectLabelProvider#getSemanticObjectLabel(Object) text}. Returns null if
+ * <code>object</code> is null.
+ *
+ * @param eObject
+ * The object
+ * @return the label of the object
+ */
+ protected String getLabel(EObject eObject) {
+ if (eObject != null) {
+ Object adapter = adapterFactory.adapt(eObject, ISemanticObjectLabelProvider.class);
+ if (adapter instanceof ISemanticObjectLabelProvider) {
+ return ((ISemanticObjectLabelProvider)adapter).getSemanticObjectLabel(eObject);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the label of the given <code>object</code> by using the label provider.
+ *
+ * @param eObject
+ * The object
+ * @return the label of the object
+ */
+ protected String getLabelFromObject(EObject eObject) {
+ return this.labelProvider.getText(eObject);
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/AddTooltipManager.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/AddTooltipManager.java
new file mode 100644
index 000000000..6fc5b8c9f
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/AddTooltipManager.java
@@ -0,0 +1,257 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Obeo and others.
+ * 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.actions;
+
+import static org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIMessages.getString;
+
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.compare.AttributeChange;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.internal.merge.MergeMode;
+import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
+
+/**
+ * This class is used to handle creation tooltips for ADD modifications.
+ *
+ * @author <a href="mailto:mathieu.cartaud@obeo.fr">Mathieu Cartaud</a>
+ */
+public class AddTooltipManager extends AbstractTooltipManager {
+
+ /**
+ * The constructor.
+ *
+ * @param adapterFactory
+ * The given adapter factory.
+ */
+ public AddTooltipManager(AdapterFactory adapterFactory) {
+ this.adapterFactory = adapterFactory;
+ this.labelProvider = new AdapterFactoryLabelProvider(adapterFactory);
+ }
+
+ /**
+ * Entry point for the computation of ADD tooltips.
+ *
+ * @param mode
+ * The comparison mode
+ * @param diff
+ * The diff
+ * @param isFromLeft
+ * True if the modification come from the left side
+ * @return the tooltip
+ */
+ public String setAddTooltip(MergeMode mode, Diff diff, boolean isFromLeft) {
+ String tooltip;
+
+ boolean isContainmentReference = isContainmentReferenceChange(diff);
+
+ // Three different case are handled : add in a non-containment reference, add in a containment
+ // reference, add of an attribute
+ if (diff instanceof AttributeChange) {
+ tooltip = setAddAttributeTooltip(mode, diff, isFromLeft);
+ } else if (isContainmentReference) {
+ tooltip = setAddContainmentTooltip(mode, diff, isFromLeft);
+ } else {
+ tooltip = setAddNonContainmentTooltip(mode, diff, isFromLeft);
+ }
+
+ return tooltip;
+ }
+
+ /**
+ * Compute the tooltip for an addition in a non-containment reference.
+ *
+ * @param mode
+ * The comparison mode
+ * @param diff
+ * The diff
+ * @param isFromLeft
+ * True if the modification come from the left side
+ * @return the tooltip
+ */
+ private String setAddNonContainmentTooltip(MergeMode mode, Diff diff, boolean isFromLeft) {
+ String value = getLabel(diff);
+ String tooltip;
+ String body;
+
+ switch (mode) {
+ case LEFT_TO_RIGHT:
+ if (isFromLeft) {
+ body = getString("ContextualTooltip.add.nonContainment.left.leftToRight", value); //$NON-NLS-1$
+ } else {
+ body = getString("ContextualTooltip.add.nonContainment.right.leftToRight", value); //$NON-NLS-1$
+ }
+ tooltip = rightChanged(body);
+ break;
+ case RIGHT_TO_LEFT:
+ if (isFromLeft) {
+ body = getString("ContextualTooltip.add.nonContainment.left.rightToLeft", value); //$NON-NLS-1$
+ } else {
+ body = getString("ContextualTooltip.add.nonContainment.right.rightToLeft", value); //$NON-NLS-1$
+ }
+ tooltip = rightUnchanged(body);
+ break;
+ case ACCEPT:
+ if (isFromLeft) {
+ body = getString("ContextualTooltip.add.nonContainment.left.accept", value); //$NON-NLS-1$
+ tooltip = acceptAndUnchanged(body);
+ } else {
+ body = getString("ContextualTooltip.add.nonContainment.right.accept", value); //$NON-NLS-1$
+ tooltip = acceptAndChanged(body);
+ }
+ break;
+ case REJECT:
+ if (isFromLeft) {
+ body = getString("ContextualTooltip.add.nonContainment.left.reject", value); //$NON-NLS-1$
+ tooltip = rejectAndChanged(body);
+ } else {
+ body = getString("ContextualTooltip.add.nonContainment.right.reject", value); //$NON-NLS-1$
+ tooltip = rejectAndUnchanged(body);
+ }
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ return tooltip;
+ }
+
+ /**
+ * Compute the tooltip for an addition in a containment reference.
+ *
+ * @param mode
+ * The comparison mode
+ * @param diff
+ * The diff
+ * @param isFromLeft
+ * True if the modification come from the left side
+ * @return the tooltip
+ */
+ private String setAddContainmentTooltip(MergeMode mode, Diff diff, boolean isFromLeft) {
+ String value = getLabel(diff);
+ String containerValue = getLabel(diff.getMatch());
+
+ String tooltip;
+ String body;
+ switch (mode) {
+ case LEFT_TO_RIGHT:
+ if (isFromLeft) {
+ body = getString("ContextualTooltip.add.containment.left.leftToRight", value, //$NON-NLS-1$
+ containerValue);
+ } else {
+ body = getString("ContextualTooltip.add.containment.right.leftToRight", value, //$NON-NLS-1$
+ containerValue);
+ }
+ tooltip = rightChanged(body);
+ break;
+ case RIGHT_TO_LEFT:
+ if (isFromLeft) {
+ body = getString("ContextualTooltip.add.containment.left.rightToLeft", value, //$NON-NLS-1$
+ containerValue);
+ } else {
+ body = getString("ContextualTooltip.add.containment.right.rightToLeft", value, //$NON-NLS-1$
+ containerValue);
+ }
+ tooltip = rightUnchanged(body);
+ break;
+ case ACCEPT:
+ if (isFromLeft) {
+ body = getString("ContextualTooltip.add.containment.left.accept", value, //$NON-NLS-1$
+ containerValue);
+ tooltip = acceptAndUnchanged(body);
+ } else {
+ body = getString("ContextualTooltip.add.containment.right.accept", value, //$NON-NLS-1$
+ containerValue);
+ tooltip = acceptAndChanged(body);
+ }
+ break;
+ case REJECT:
+ if (isFromLeft) {
+ body = getString("ContextualTooltip.add.containment.left.reject", value, //$NON-NLS-1$
+ containerValue);
+ tooltip = rejectAndChanged(body);
+ } else {
+ body = getString("ContextualTooltip.add.containment.right.reject", value, //$NON-NLS-1$
+ containerValue);
+ tooltip = rejectAndUnchanged(body);
+ }
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ return tooltip;
+ }
+
+ /**
+ * Compute the tooltip for an attribute addition.
+ *
+ * @param mode
+ * The comparison mode
+ * @param diff
+ * The diff
+ * @param isFromLeft
+ * True if the modification come from the left side
+ * @return the tooltip
+ */
+ private String setAddAttributeTooltip(MergeMode mode, Diff diff, boolean isFromLeft) {
+ String value = getLabel(diff);
+ String containerValue = getLabel(diff.getMatch());
+
+ String tooltip;
+ String body;
+ switch (mode) {
+ case LEFT_TO_RIGHT:
+ if (isFromLeft) {
+ body = getString("ContextualTooltip.add.attribute.left.leftToRight", value, //$NON-NLS-1$
+ containerValue);
+ } else {
+ body = getString("ContextualTooltip.add.attribute.right.leftToRight", value, //$NON-NLS-1$
+ containerValue);
+ }
+ tooltip = rightChanged(body);
+ break;
+ case RIGHT_TO_LEFT:
+ if (isFromLeft) {
+ body = getString("ContextualTooltip.add.attribute.left.rightToLeft", value, //$NON-NLS-1$
+ containerValue);
+ } else {
+ body = getString("ContextualTooltip.add.attribute.right.rightToLeft", value, //$NON-NLS-1$
+ containerValue);
+ }
+ tooltip = rightUnchanged(body);
+ break;
+ case ACCEPT:
+ if (isFromLeft) {
+ body = getString("ContextualTooltip.add.attribute.left.accept", value, //$NON-NLS-1$
+ containerValue);
+ tooltip = acceptAndUnchanged(body);
+ } else {
+ body = getString("ContextualTooltip.add.attribute.right.accept", value, //$NON-NLS-1$
+ containerValue);
+ tooltip = acceptAndChanged(body);
+ }
+ break;
+ case REJECT:
+ if (isFromLeft) {
+ body = getString("ContextualTooltip.add.attribute.left.reject", value, //$NON-NLS-1$
+ containerValue);
+ tooltip = rejectAndChanged(body);
+ } else {
+ body = getString("ContextualTooltip.add.attribute.right.reject", value, //$NON-NLS-1$
+ containerValue);
+ tooltip = rejectAndUnchanged(body);
+ }
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ return tooltip;
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/ChangeTooltipManager.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/ChangeTooltipManager.java
new file mode 100644
index 000000000..0abc193dc
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/ChangeTooltipManager.java
@@ -0,0 +1,383 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Obeo and others.
+ * 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.actions;
+
+import static org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIMessages.getString;
+import static org.eclipse.emf.compare.utils.ReferenceUtil.safeEGet;
+
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.compare.AttributeChange;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.DifferenceSource;
+import org.eclipse.emf.compare.Match;
+import org.eclipse.emf.compare.ReferenceChange;
+import org.eclipse.emf.compare.internal.merge.MergeMode;
+import org.eclipse.emf.compare.utils.MatchUtil;
+import org.eclipse.emf.compare.utils.ReferenceUtil;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
+
+/**
+ * This class is used to handle creation tooltips for CHANGE (SET and UNSET) modifications.
+ *
+ * @author <a href="mailto:mathieu.cartaud@obeo.fr">Mathieu Cartaud</a>
+ */
+public class ChangeTooltipManager extends AbstractTooltipManager {
+
+ /**
+ * The constructor.
+ *
+ * @param adapterFactory
+ * The given adapter factory
+ */
+ public ChangeTooltipManager(AdapterFactory adapterFactory) {
+ this.adapterFactory = adapterFactory;
+ this.labelProvider = new AdapterFactoryLabelProvider(adapterFactory);
+ }
+
+ /**
+ * Entry point for the computation of CHANGE tooltips.
+ *
+ * @param mode
+ * The comparison mode
+ * @param diff
+ * The diff
+ * @param isFromLeft
+ * True if the modification come from the left side
+ * @return the tooltip
+ */
+ public String setChangeTooltip(MergeMode mode, Diff diff, boolean isFromLeft) {
+ boolean isUnset = isUnset(diff);
+ String tooltip;
+
+ // Two case are handled : set and unset
+ if (isUnset) {
+ tooltip = setUnsetTooltip(mode, diff, isFromLeft);
+ } else {
+ tooltip = setSetTooltip(mode, diff, isFromLeft);
+ }
+ return tooltip;
+ }
+
+ /**
+ * Returns the changed value, as it is right now stored in the model, of the attribute that is affected by
+ * the given {@code diff}.
+ *
+ * @param diff
+ * The diff to get the changed value for.
+ * @return The changed value.
+ */
+ private String getChangedValueFromModel(AttributeChange diff) {
+ final EAttribute attribute = diff.getAttribute();
+ final EObject changedContainer;
+ switch (diff.getSource()) {
+ case LEFT:
+ changedContainer = diff.getMatch().getLeft();
+ break;
+ case RIGHT:
+ changedContainer = diff.getMatch().getRight();
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+ return (String)safeEGet(changedContainer, attribute);
+ }
+
+ /**
+ * Check if the change in a given diff is a set or an unset.
+ *
+ * @param diff
+ * The given diff
+ * @return <code>true</code> if the diff is an unset, <code>false</code> otherwise
+ */
+ private boolean isUnset(Diff diff) {
+ boolean isUnset = false;
+ if (diff instanceof ReferenceChange) {
+ if (isUnset((ReferenceChange)diff)) {
+ isUnset = true;
+ }
+ } else if (diff instanceof AttributeChange) {
+ AttributeChange change = (AttributeChange)diff;
+ if (isUnset(change, getChangedValueFromModel(change))) {
+ isUnset = true;
+ }
+ }
+ return isUnset;
+ }
+
+ /**
+ * Specifies whether the given {@code diff} unsets the reference value.
+ *
+ * @param diff
+ * The difference to check
+ * @return <code>true</code> if setting {@code targetValue} is an unset, <code>false</code> otherwise.
+ */
+ private boolean isUnset(ReferenceChange diff) {
+ boolean isUnset = false;
+ final Match match = diff.getMatch();
+ final EObject container;
+ if (diff.getSource() == DifferenceSource.LEFT) {
+ container = match.getLeft();
+ } else {
+ container = match.getRight();
+ }
+
+ if (container == null) {
+ isUnset = true;
+ } else {
+ if (!ReferenceUtil.safeEIsSet(container, diff.getReference())) {
+ isUnset = true;
+ }
+ }
+
+ return isUnset;
+ }
+
+ /**
+ * Specifies whether the given {@code diff} unsets the attribute value when updating the attribute with
+ * the given {@code targetValue}.
+ *
+ * @param diff
+ * The difference to check.
+ * @param targetValue
+ * The value to be set.
+ * @return <code>true</code> if setting {@code targetValue} is an unset, <code>false</code> otherwise.
+ */
+ private boolean isUnset(AttributeChange diff, Object targetValue) {
+ final Object defaultValue = diff.getAttribute().getDefaultValue();
+ return targetValue == null || targetValue.equals(defaultValue)
+ || (defaultValue == null && "".equals(targetValue)); //$NON-NLS-1$
+ }
+
+ /**
+ * Get the label for the structuralFeature of the given eObject.
+ *
+ * @param eStructuralFeature
+ * The eStructuralFeature
+ * @param eObject
+ * The eObject
+ * @return the label of the eStructuralFeature
+ */
+ private String getPreviousValue(EStructuralFeature eStructuralFeature, EObject eObject) {
+ Object ancestor = eObject.eGet(eStructuralFeature);
+ String value = ""; //$NON-NLS-1$
+ if (ancestor instanceof EObject) {
+ value = getLabelFromObject((EObject)ancestor);
+ } else if (ancestor != null) {
+ value = ancestor.toString();
+ }
+ return value;
+ }
+
+ /**
+ * Compute the tooltip for the set of a value.
+ *
+ * @param mode
+ * The comparison mode
+ * @param diff
+ * The diff
+ * @param isFromLeft
+ * True if the modification come from the left side
+ * @return the tooltip
+ */
+ private String setSetTooltip(MergeMode mode, Diff diff, boolean isFromLeft) {
+ // compute the name of the structural feature modified
+ EStructuralFeature eStructuralFeature = MatchUtil.getStructuralFeature(diff);
+ String structuralFeatureName = eStructuralFeature.getName();
+
+ // The name of the container of the structural feature
+ String containerName = diff.getMatch().getLeft().eClass().getName();
+
+ String rightValue = getPreviousValue(eStructuralFeature, diff.getMatch().getRight());
+ String leftValue = getPreviousValue(eStructuralFeature, diff.getMatch().getLeft());
+ String tooltip;
+ String body;
+ switch (mode) {
+ case LEFT_TO_RIGHT:
+ if (isFromLeft) {
+ if ("".equals(rightValue)) { //$NON-NLS-1$
+ body = getString(
+ "ContextualTooltip.set.left.leftToRight.empty", structuralFeatureName, //$NON-NLS-1$
+ containerName, leftValue);
+
+ } else {
+ body = getString("ContextualTooltip.set.left.leftToRight", structuralFeatureName, //$NON-NLS-1$
+ containerName, leftValue, rightValue);
+ }
+ } else {
+ // if previous value cannot be displayed
+ if ("".equals(leftValue)) { //$NON-NLS-1$
+ body = getString("ContextualTooltip.set.right.leftToRight.empty", //$NON-NLS-1$
+ structuralFeatureName, containerName, rightValue);
+ } else {
+ body = getString("ContextualTooltip.set.right.leftToRight", structuralFeatureName, //$NON-NLS-1$
+ containerName, leftValue, rightValue);
+ }
+ }
+ tooltip = rightChanged(body);
+ break;
+ case RIGHT_TO_LEFT:
+ if (isFromLeft) {
+ // if previous value cannot be displayed
+ if ("".equals(rightValue)) { //$NON-NLS-1$
+ body = getString("ContextualTooltip.set.left.rightToLeft.empty", //$NON-NLS-1$
+ structuralFeatureName, containerName, leftValue);
+ } else {
+ body = getString("ContextualTooltip.set.left.rightToLeft", structuralFeatureName, //$NON-NLS-1$
+ containerName, rightValue, leftValue);
+ }
+ } else {
+ if ("".equals(leftValue)) { //$NON-NLS-1$
+ body = getString(
+ "ContextualTooltip.set.right.rightToLeft.empty", structuralFeatureName, //$NON-NLS-1$
+ containerName, rightValue);
+ } else {
+ body = getString("ContextualTooltip.set.right.rightToLeft", structuralFeatureName, //$NON-NLS-1$
+ containerName, rightValue, leftValue);
+ }
+ }
+ tooltip = rightUnchanged(body);
+ break;
+ case ACCEPT:
+ if (isFromLeft) {
+ body = getString("ContextualTooltip.set.left.accept", leftValue, structuralFeatureName, //$NON-NLS-1$
+ containerName);
+ tooltip = acceptAndUnchanged(body);
+ } else {
+ if ("".equals(leftValue)) { //$NON-NLS-1$
+ body = getString("ContextualTooltip.set.right.accept.empty", structuralFeatureName, //$NON-NLS-1$
+ containerName, rightValue);
+ } else {
+ body = getString("ContextualTooltip.set.right.accept", structuralFeatureName, //$NON-NLS-1$
+ containerName, rightValue, leftValue);
+ }
+ tooltip = acceptAndChanged(body);
+ }
+ break;
+ case REJECT:
+ // get the value of the structural feature in the origin side if it is a three way comparison,
+ // get the value of the left side otherwise
+ String previousValue;
+ if (diff.getMatch().getComparison().isThreeWay()) {
+ previousValue = getPreviousValue(eStructuralFeature, diff.getMatch().getOrigin());
+ } else {
+ previousValue = rightValue;
+ }
+
+ if (isFromLeft) {
+ // if previous value cannot be displayed
+ if ("".equals(previousValue)) { //$NON-NLS-1$
+ body = getString("ContextualTooltip.set.left.reject.empty", structuralFeatureName, //$NON-NLS-1$
+ containerName, leftValue);
+ } else {
+ body = getString("ContextualTooltip.set.left.reject", structuralFeatureName, //$NON-NLS-1$
+ containerName, previousValue, leftValue);
+ }
+ tooltip = rejectAndChanged(body);
+ } else {
+ if (diff.getMatch().getComparison().isThreeWay()) {
+ previousValue = getPreviousValue(eStructuralFeature, diff.getMatch().getOrigin());
+ } else {
+ previousValue = leftValue;
+ }
+ // if previous value cannot be displayed
+ if ("".equals(previousValue)) { //$NON-NLS-1$
+ body = getString("ContextualTooltip.set.right.reject.empty", structuralFeatureName, //$NON-NLS-1$
+ containerName);
+ } else {
+ body = getString(
+ "ContextualTooltip.set.right.reject", previousValue, structuralFeatureName, //$NON-NLS-1$
+ containerName);
+ }
+ tooltip = rejectAndUnchanged(body);
+ }
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ return tooltip;
+ }
+
+ /**
+ * Compute the tooltip for the unset of a value.
+ *
+ * @param mode
+ * The comparison mode
+ * @param diff
+ * The diff
+ * @param isFromLeft
+ * True if the modification come from the left side
+ * @return the tooltip
+ */
+ private String setUnsetTooltip(MergeMode mode, Diff diff, boolean isFromLeft) {
+ String value = getLabel(diff);
+
+ // compute the name of the structural feature modified
+ EStructuralFeature structuralFeature = MatchUtil.getStructuralFeature(diff);
+ String structuralFeatureName = structuralFeature.getName();
+
+ // The name of the container of the structural feature
+ String containerName = diff.getMatch().getLeft().eClass().getName();
+
+ String tooltip;
+ String body;
+ switch (mode) {
+ case LEFT_TO_RIGHT:
+ if (isFromLeft) {
+ body = getString("ContextualTooltip.unset.left.leftToRight", structuralFeatureName, //$NON-NLS-1$
+ containerName, value);
+ } else {
+ body = getString("ContextualTooltip.unset.right.leftToRight", structuralFeatureName, //$NON-NLS-1$
+ containerName, value);
+ }
+ tooltip = rightChanged(body);
+ break;
+ case RIGHT_TO_LEFT:
+ if (isFromLeft) {
+ body = getString("ContextualTooltip.unset.left.rightToLeft", structuralFeatureName, //$NON-NLS-1$
+ containerName, value);
+ } else {
+ body = getString("ContextualTooltip.unset.right.rightToLeft", structuralFeatureName, //$NON-NLS-1$
+ containerName, value);
+ }
+ tooltip = rightUnchanged(body);
+ break;
+ case ACCEPT:
+ if (isFromLeft) {
+ body = getString("ContextualTooltip.unset.left.accept", structuralFeatureName, //$NON-NLS-1$
+ containerName);
+ tooltip = acceptAndUnchanged(body);
+ } else {
+ body = getString("ContextualTooltip.unset.right.accept", structuralFeatureName, //$NON-NLS-1$
+ containerName, value);
+ tooltip = acceptAndChanged(body);
+ }
+ break;
+ case REJECT:
+ if (isFromLeft) {
+ body = getString("ContextualTooltip.unset.left.reject", structuralFeatureName, //$NON-NLS-1$
+ containerName, value);
+ tooltip = rejectAndChanged(body);
+ } else {
+ body = getString("ContextualTooltip.unset.right.reject", structuralFeatureName, //$NON-NLS-1$
+ containerName, value);
+ tooltip = rejectAndUnchanged(body);
+ }
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ return tooltip;
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/DeleteTooltipManager.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/DeleteTooltipManager.java
new file mode 100644
index 000000000..8f83f9593
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/DeleteTooltipManager.java
@@ -0,0 +1,194 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Obeo and others.
+ * 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.actions;
+
+import static org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIMessages.getString;
+
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.ReferenceChange;
+import org.eclipse.emf.compare.internal.merge.MergeMode;
+import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
+
+/**
+ * This class is used to compute tooltips for DELETE modifications.
+ *
+ * @author <a href="mailto:mathieu.cartaud@obeo.fr">Mathieu Cartaud</a>
+ */
+public class DeleteTooltipManager extends AbstractTooltipManager {
+
+ /**
+ * The constructor.
+ *
+ * @param adapterFactory
+ * The given adapter factory
+ */
+ public DeleteTooltipManager(AdapterFactory adapterFactory) {
+ this.adapterFactory = adapterFactory;
+ this.labelProvider = new AdapterFactoryLabelProvider(adapterFactory);
+ }
+
+ /**
+ * This method is the entry point of tooltip creation for a DELETE mode difference.
+ *
+ * @param mode
+ * The comparison mode
+ * @param diff
+ * The diff
+ * @param isFromLeft
+ * True if the modification come from the left side
+ * @return the tooltip
+ */
+ public String setDeleteTooltip(MergeMode mode, Diff diff, boolean isFromLeft) {
+ String tooltip;
+
+ boolean isContainmentReference = false;
+ if (diff instanceof ReferenceChange) {
+ if (((ReferenceChange)diff).getReference().isContainment()) {
+ isContainmentReference = true;
+ }
+ }
+
+ // Two different case are handled : deletion on an element referenced by a non-containment reference,
+ // deletion of an element referenced by a containment reference
+ if (isContainmentReference) {
+ tooltip = setDeleteContainmentTooltip(mode, diff, isFromLeft);
+ } else {
+ tooltip = setDeleteNonContainmentTooltip(mode, diff, isFromLeft);
+ }
+
+ return tooltip;
+ }
+
+ /**
+ * Compute the tooltip for an deletion in a non-containment reference.
+ *
+ * @param mode
+ * The comparison mode
+ * @param diff
+ * The diff
+ * @param isFromLeft
+ * True if the modification come from the left side
+ * @return the tooltip
+ */
+ private String setDeleteNonContainmentTooltip(MergeMode mode, Diff diff, boolean isFromLeft) {
+ String value = getLabel(diff);
+ String tooltip;
+ String body;
+
+ switch (mode) {
+ case LEFT_TO_RIGHT:
+ if (isFromLeft) {
+ body = getString("ContextualTooltip.delete.nonContainment.left.leftToRight", value); //$NON-NLS-1$
+ } else {
+ body = getString("ContextualTooltip.delete.nonContainment.right.leftToRight", value); //$NON-NLS-1$
+ }
+ tooltip = rightChanged(body);
+ break;
+ case RIGHT_TO_LEFT:
+ if (isFromLeft) {
+ body = getString("ContextualTooltip.delete.nonContainment.left.rightToLeft", value); //$NON-NLS-1$
+ } else {
+ body = getString("ContextualTooltip.delete.nonContainment.right.rightToLeft", value); //$NON-NLS-1$
+ }
+ tooltip = rightUnchanged(body);
+ break;
+ case ACCEPT:
+ if (isFromLeft) {
+ body = getString("ContextualTooltip.delete.nonContainment.left.accept", value); //$NON-NLS-1$
+ tooltip = acceptAndUnchanged(body);
+ } else {
+ body = getString("ContextualTooltip.delete.nonContainment.right.accept", value); //$NON-NLS-1$
+ tooltip = acceptAndChanged(body);
+ }
+ break;
+ case REJECT:
+ if (isFromLeft) {
+ body = getString("ContextualTooltip.delete.nonContainment.left.reject", value); //$NON-NLS-1$
+ tooltip = rejectAndChanged(body);
+ } else {
+ body = getString("ContextualTooltip.delete.nonContainment.right.reject", value); //$NON-NLS-1$
+ tooltip = rejectAndUnchanged(body);
+ }
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ return tooltip;
+ }
+
+ /**
+ * Compute the tooltip for an deletion in a containment reference.
+ *
+ * @param mode
+ * The comparison mode
+ * @param diff
+ * The diff
+ * @param isFromLeft
+ * True if the modification come from the left side
+ * @return the tooltip
+ */
+ private String setDeleteContainmentTooltip(MergeMode mode, Diff diff, boolean isFromLeft) {
+ String value = getLabel(diff);
+ String containerValue = getLabel(diff.getMatch());
+ String tooltip;
+ String body;
+
+ switch (mode) {
+ case LEFT_TO_RIGHT:
+ if (isFromLeft) {
+ body = getString("ContextualTooltip.delete.containment.left.leftToRight", value, //$NON-NLS-1$
+ containerValue);
+ } else {
+ body = getString("ContextualTooltip.delete.containment.right.leftToRight", value, //$NON-NLS-1$
+ containerValue);
+ }
+ tooltip = rightChanged(body);
+ break;
+ case RIGHT_TO_LEFT:
+ if (isFromLeft) {
+ body = getString("ContextualTooltip.delete.containment.left.rightToLeft", value, //$NON-NLS-1$
+ containerValue);
+ } else {
+ body = getString("ContextualTooltip.delete.containment.right.rightToLeft", value, //$NON-NLS-1$
+ containerValue);
+ }
+ tooltip = rightUnchanged(body);
+ break;
+ case ACCEPT:
+ if (isFromLeft) {
+ body = getString("ContextualTooltip.delete.containment.left.accept", value, //$NON-NLS-1$
+ containerValue);
+ tooltip = acceptAndUnchanged(body);
+ } else {
+ body = getString("ContextualTooltip.delete.containment.right.accept", value, //$NON-NLS-1$
+ containerValue);
+ tooltip = acceptAndChanged(body);
+ }
+ break;
+ case REJECT:
+ if (isFromLeft) {
+ body = getString("ContextualTooltip.delete.containment.left.reject", value, //$NON-NLS-1$
+ containerValue);
+ tooltip = rejectAndChanged(body);
+ } else {
+ body = getString("ContextualTooltip.delete.containment.right.reject", value, //$NON-NLS-1$
+ containerValue);
+ tooltip = rejectAndUnchanged(body);
+ }
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ return tooltip;
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MergeAction.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MergeAction.java
index 0734373da..457e2c807 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MergeAction.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MergeAction.java
@@ -26,8 +26,10 @@ import java.util.Set;
import org.eclipse.compare.INavigatable;
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.Diff;
+import org.eclipse.emf.compare.DifferenceSource;
import org.eclipse.emf.compare.command.ICompareCopyCommand;
import org.eclipse.emf.compare.domain.ICompareEditingDomain;
import org.eclipse.emf.compare.domain.IMergeRunnable;
@@ -39,6 +41,8 @@ import org.eclipse.emf.compare.internal.utils.ComparisonUtil;
import org.eclipse.emf.compare.merge.IMerger;
import org.eclipse.emf.compare.merge.IMerger.Registry;
import org.eclipse.emf.compare.merge.IMerger2;
+import org.eclipse.emf.compare.rcp.ui.EMFCompareRCPUIPlugin;
+import org.eclipse.emf.compare.rcp.ui.internal.configuration.IEMFCompareConfiguration;
import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroup;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.tree.TreeNode;
@@ -75,6 +79,16 @@ public class MergeAction extends BaseSelectionListenerAction {
private final INavigatable navigatable;
/**
+ * The merge mode used for the comparison.
+ */
+ private MergeMode selectedMode;
+
+ /**
+ * The adapter factory for the comparison.
+ */
+ private AdapterFactory adapterFactory;
+
+ /**
* Constructor.
*
* @param configuration
@@ -83,8 +97,13 @@ public class MergeAction extends BaseSelectionListenerAction {
public MergeAction(ICompareEditingDomain editingDomain, IMerger.Registry mergerRegistry, MergeMode mode,
boolean isLeftEditable, boolean isRightEditable, INavigatable navigatable) {
super(""); //$NON-NLS-1$
- this.navigatable = navigatable;
+ IEMFCompareConfiguration emfCompareConfiguration = EMFCompareRCPUIPlugin.getDefault()
+ .getEMFCompareConfiguration();
+ if (emfCompareConfiguration != null) {
+ adapterFactory = emfCompareConfiguration.getAdapterFactory();
+ }
+ this.navigatable = navigatable;
Preconditions.checkNotNull(mode);
// at least should be editable
Preconditions.checkState(isLeftEditable || isRightEditable);
@@ -103,6 +122,7 @@ public class MergeAction extends BaseSelectionListenerAction {
this.leftToRight = mode.isLeftToRight(isLeftEditable, isRightEditable);
this.mergeRunnable = createMergeRunnable(mode, isLeftEditable, isRightEditable);
this.selectedDifferences = newArrayList();
+ this.selectedMode = mode;
initToolTipAndImage(mode);
}
@@ -151,6 +171,74 @@ public class MergeAction extends BaseSelectionListenerAction {
}
/**
+ * This method is used to created contextual tooltips.
+ */
+ protected void contextualizeTooltip() {
+
+ if (this.selectedDifferences.size() > 1) {
+ // multiple selection
+ setMultipleTooltip(this.selectedMode);
+ } else if (this.selectedDifferences.isEmpty()) {
+ // no selection
+ initToolTipAndImage(this.selectedMode);
+ } else {
+ String tooltip;
+ Diff diff = this.selectedDifferences.get(0);
+ boolean isFromLeft = diff.getSource().equals(DifferenceSource.LEFT);
+ switch (diff.getKind()) {
+ case ADD:
+ AddTooltipManager addTooltipManager = (AddTooltipManager)TooltipFactory
+ .getTooltipManager(this.adapterFactory, diff);
+ tooltip = addTooltipManager.setAddTooltip(this.selectedMode, diff, isFromLeft);
+ break;
+ case CHANGE:
+ ChangeTooltipManager changeTooltipManager = (ChangeTooltipManager)TooltipFactory
+ .getTooltipManager(this.adapterFactory, diff);
+ tooltip = changeTooltipManager.setChangeTooltip(this.selectedMode, diff, isFromLeft);
+ break;
+ case DELETE:
+ DeleteTooltipManager deleteTooltipManager = (DeleteTooltipManager)TooltipFactory
+ .getTooltipManager(this.adapterFactory, diff);
+ tooltip = deleteTooltipManager.setDeleteTooltip(this.selectedMode, diff, isFromLeft);
+ break;
+ case MOVE:
+ MoveTooltipManager moveTooltipManager = (MoveTooltipManager)TooltipFactory
+ .getTooltipManager(this.adapterFactory, diff);
+ tooltip = moveTooltipManager.setMoveTooltip(this.selectedMode, diff, isFromLeft);
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ setToolTipText(tooltip);
+ }
+ }
+
+ /**
+ * Set the tooltips for multiple selection.
+ *
+ * @param mode
+ * The comparison mode
+ */
+ private void setMultipleTooltip(MergeMode mode) {
+ switch (mode) {
+ case LEFT_TO_RIGHT:
+ setToolTipText(EMFCompareIDEUIMessages.getString("merged.multiple.to.right.tooltip")); //$NON-NLS-1$
+ break;
+ case RIGHT_TO_LEFT:
+ setToolTipText(EMFCompareIDEUIMessages.getString("merged.multiple.to.left.tooltip")); //$NON-NLS-1$
+ break;
+ case ACCEPT:
+ setToolTipText(EMFCompareIDEUIMessages.getString("accept.multiple.changes.tooltip")); //$NON-NLS-1$
+ break;
+ case REJECT:
+ setToolTipText(EMFCompareIDEUIMessages.getString("reject.multiple.changes.tooltip")); //$NON-NLS-1$
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
* {@inheritDoc}
*
* @see org.eclipse.jface.action.Action#run()
@@ -200,6 +288,9 @@ public class MergeAction extends BaseSelectionListenerAction {
@Override
protected boolean updateSelection(IStructuredSelection selection) {
addAll(selectedDifferences, getSelectedDifferences(selection));
+ if (this.adapterFactory != null) {
+ contextualizeTooltip();
+ }
return selection.toList().size() == selectedDifferences.size();
}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MoveTooltipManager.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MoveTooltipManager.java
new file mode 100644
index 000000000..8e8ae37e6
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/MoveTooltipManager.java
@@ -0,0 +1,271 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Obeo and others.
+ * 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.actions;
+
+import static org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIMessages.getString;
+
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.Match;
+import org.eclipse.emf.compare.ReferenceChange;
+import org.eclipse.emf.compare.internal.merge.MergeMode;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
+
+/**
+ * This class is used to handle creation tooltips for MOVE modifications.
+ *
+ * @author <a href="mailto:mathieu.cartaud@obeo.fr">Mathieu Cartaud</a>
+ */
+public class MoveTooltipManager extends AbstractTooltipManager {
+
+ /**
+ * The constructor.
+ *
+ * @param adapterFactory
+ * The given adapter factory.
+ */
+ public MoveTooltipManager(AdapterFactory adapterFactory) {
+ this.adapterFactory = adapterFactory;
+ this.labelProvider = new AdapterFactoryLabelProvider(adapterFactory);
+ }
+
+ /**
+ * Entry point for the computation of MOVE tooltips.
+ *
+ * @param mode
+ * The comparison mode
+ * @param diff
+ * The diff
+ * @param isFromLeft
+ * True if the modification come from the left side
+ * @return the tooltip
+ */
+ public String setMoveTooltip(MergeMode mode, Diff diff, boolean isFromLeft) {
+ EObject right = null;
+ EObject left = null;
+ EObject ancestor = null;
+ String tooltip;
+
+ boolean isContainmentReference = isContainmentReferenceChange(diff);
+ if (isContainmentReference) {
+ Match valueMatch = diff.getMatch().getComparison().getMatch(((ReferenceChange)diff).getValue());
+ left = valueMatch.getLeft();
+ right = valueMatch.getRight();
+ ancestor = valueMatch.getOrigin();
+ }
+
+ // Two case are handled : move of an element in another container, position move of an element inside
+ // the same container
+ if (isContainmentReference && isContainerMove(isFromLeft, ancestor, right, left)) {
+ tooltip = setMoveContainerTooltip(mode, diff, isFromLeft, left, right, ancestor);
+ } else {
+ tooltip = setMovePositionTooltip(mode, diff, isFromLeft);
+ }
+ return tooltip;
+ }
+
+ /**
+ * This method verify if the container (left and right) of an element are the same in order to detect move
+ * from a container to another.
+ *
+ * @param isFromLeft
+ * True if the change comes from the left side, false otherwise
+ * @param origin
+ * The origin container
+ * @param right
+ * The right container
+ * @param left
+ * The left container
+ * @return true if the two containers are different
+ */
+ private boolean isContainerMove(boolean isFromLeft, EObject origin, EObject right, EObject left) {
+ boolean isContainerMove = false;
+ if (isFromLeft) {
+ if (left != null && origin != null) {
+ // if the label of the container of an element is different of the label of it ancestor
+ // or if the containing feature between an element and its container are different
+ // We consider that it is a container move
+ if (!getLabelFromObject(left.eContainer()).equals(getLabelFromObject(origin.eContainer()))
+ || left.eContainingFeature() != origin.eContainingFeature()) {
+ isContainerMove = true;
+ }
+ }
+ } else {
+ if (right != null && origin != null) {
+ if (!getLabelFromObject(right.eContainer()).equals(getLabelFromObject(origin.eContainer()))
+ || right.eContainingFeature() != origin.eContainingFeature()) {
+ isContainerMove = true;
+ }
+ }
+ }
+ return isContainerMove;
+ }
+
+ /**
+ * Compute the tooltip for the move (position) of an element inside the same container.
+ *
+ * @param mode
+ * The comparison mode
+ * @param diff
+ * The diff
+ * @param isFromLeft
+ * True if the modification come from the left side
+ * @return the tooltip
+ */
+ private String setMovePositionTooltip(MergeMode mode, Diff diff, boolean isFromLeft) {
+ String value = getLabel(diff);
+ String containerValue = getLabel(diff.getMatch());
+ String tooltip;
+ String body;
+
+ switch (mode) {
+ case LEFT_TO_RIGHT:
+ if (isFromLeft) {
+ body = getString("ContextualTooltip.move.position.left.leftToRight", value); //$NON-NLS-1$
+ } else {
+ body = getString("ContextualTooltip.move.position.right.leftToRight", value); //$NON-NLS-1$
+ }
+ tooltip = rightChanged(body);
+ break;
+ case RIGHT_TO_LEFT:
+ if (isFromLeft) {
+ body = getString("ContextualTooltip.move.position.left.rightToLeft", value); //$NON-NLS-1$
+ } else {
+ body = getString("ContextualTooltip.move.position.right.rightToLeft", value); //$NON-NLS-1$
+ }
+ tooltip = rightUnchanged(body);
+ break;
+ case ACCEPT:
+ if (isFromLeft) {
+ // display container label only if the element is inside a container
+ if (diff instanceof ReferenceChange
+ && ((ReferenceChange)diff).getReference().isContainment()) {
+ body = getString(
+ "ContextualTooltip.move.position.left.container.accept", value, containerValue); //$NON-NLS-1$
+ } else {
+ body = getString("ContextualTooltip.move.position.left.accept", value); //$NON-NLS-1$
+ }
+ tooltip = acceptAndUnchanged(body);
+ } else {
+ if (diff instanceof ReferenceChange
+ && ((ReferenceChange)diff).getReference().isContainment()) {
+ body = getString(
+ "ContextualTooltip.move.position.right.container.accept", value, containerValue); //$NON-NLS-1$
+ } else {
+ body = getString("ContextualTooltip.move.position.right.accept", value); //$NON-NLS-1$
+ }
+ tooltip = acceptAndChanged(body);
+ }
+ break;
+ case REJECT:
+ if (isFromLeft) {
+ body = getString("ContextualTooltip.move.position.left.reject", value); //$NON-NLS-1$
+ tooltip = rejectAndChanged(body);
+ } else {
+ // display container label only if the element is inside a container
+ if (diff instanceof ReferenceChange
+ && ((ReferenceChange)diff).getReference().isContainment()) {
+ body = getString(
+ "ContextualTooltip.move.position.right.container.reject", value, containerValue); //$NON-NLS-1$
+ } else {
+ body = getString("ContextualTooltip.move.position.right.reject", value); //$NON-NLS-1$
+ }
+ tooltip = rejectAndUnchanged(body);
+ }
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ return tooltip;
+ }
+
+ /**
+ * Compute the tooltip for the move of an element from a container to another.
+ *
+ * @param mode
+ * The comparison mode
+ * @param diff
+ * The diff
+ * @param isFromLeft
+ * True if the modification come from the left side
+ * @param left
+ * The modified element in the left model
+ * @param right
+ * The modified element in the right model
+ * @param ancestor
+ * The modified element in the left model
+ * @return the tooltip
+ */
+ private String setMoveContainerTooltip(MergeMode mode, Diff diff, boolean isFromLeft, EObject left,
+ EObject right, EObject ancestor) {
+ String value = getLabel(diff);
+ String leftContainerValue = getLabelFromObject(left.eContainer());
+ String rightContainerValue = getLabelFromObject(right.eContainer());
+ String ancestorContainerValue;
+ if (diff.getMatch().getComparison().isThreeWay() && ancestor != null) {
+ ancestorContainerValue = getLabelFromObject(ancestor.eContainer());
+ } else {
+ ancestorContainerValue = rightContainerValue;
+ }
+ String tooltip;
+ String body;
+
+ switch (mode) {
+ case LEFT_TO_RIGHT:
+ if (isFromLeft) {
+ body = getString("ContextualTooltip.move.container.left.leftToRight", value, //$NON-NLS-1$
+ leftContainerValue, rightContainerValue);
+ } else {
+ body = getString("ContextualTooltip.move.container.right.leftToRight", value, //$NON-NLS-1$
+ leftContainerValue, rightContainerValue);
+ }
+ tooltip = rightChanged(body);
+ break;
+ case RIGHT_TO_LEFT:
+ if (isFromLeft) {
+ body = getString("ContextualTooltip.move.container.left.rightToLeft", value, //$NON-NLS-1$
+ rightContainerValue, leftContainerValue);
+ } else {
+ body = getString("ContextualTooltip.move.container.right.rightToLeft", value, //$NON-NLS-1$
+ rightContainerValue, leftContainerValue);
+ }
+ tooltip = rightUnchanged(body);
+ break;
+ case ACCEPT:
+ if (isFromLeft) {
+ body = getString("ContextualTooltip.move.container.left.accept", value, //$NON-NLS-1$
+ leftContainerValue);
+ tooltip = acceptAndUnchanged(body);
+ } else {
+ body = getString("ContextualTooltip.move.container.right.accept", value, //$NON-NLS-1$
+ rightContainerValue, leftContainerValue);
+ tooltip = acceptAndChanged(body);
+ }
+ break;
+ case REJECT:
+ if (isFromLeft) {
+ body = getString("ContextualTooltip.move.container.left.reject", value, //$NON-NLS-1$
+ ancestorContainerValue, leftContainerValue);
+ tooltip = rejectAndChanged(body);
+ } else {
+ body = getString("ContextualTooltip.move.container.right.reject", value, //$NON-NLS-1$
+ leftContainerValue);
+ tooltip = rejectAndUnchanged(body);
+ }
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ return tooltip;
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/TooltipFactory.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/TooltipFactory.java
new file mode 100644
index 000000000..6d0f719a6
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/actions/TooltipFactory.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Obeo and others.
+ * 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.actions;
+
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.compare.Diff;
+
+/**
+ * Factory for the tooltip managers.
+ *
+ * @author <a href="mailto:mathieu.cartaud@obeo.fr">Mathieu Cartaud</a>
+ */
+public final class TooltipFactory {
+
+ /**
+ * The AddTooltipManager instance.
+ */
+ private static AddTooltipManager addTooltipManager;
+
+ /**
+ * The ChangeTooltipManager instance.
+ */
+ private static ChangeTooltipManager changeTooltipManager;
+
+ /**
+ * The DeleteTooltipManager instance.
+ */
+ private static DeleteTooltipManager deleteTooltipManager;
+
+ /**
+ * The MoveTooltipManager instance.
+ */
+ private static MoveTooltipManager moveTooltipManager;
+
+ /**
+ * The constructor.
+ */
+ private TooltipFactory() {
+ // Prevent instanciation.
+ }
+
+ /**
+ * Create a new instance of the right type or return the existing one for the given diff.
+ *
+ * @param adapterFactory
+ * The given adapter factory
+ * @param diff
+ * The diff which which the tooltip will be computed
+ * @return an instance of the good AbstractTooltipManager
+ */
+ public static AbstractTooltipManager getTooltipManager(AdapterFactory adapterFactory, Diff diff) {
+ AbstractTooltipManager manager = null;
+
+ switch (diff.getKind()) {
+ case ADD:
+ if (addTooltipManager == null) {
+ addTooltipManager = new AddTooltipManager(adapterFactory);
+ }
+ manager = addTooltipManager;
+ break;
+ case CHANGE:
+ if (changeTooltipManager == null) {
+ changeTooltipManager = new ChangeTooltipManager(adapterFactory);
+ }
+ manager = changeTooltipManager;
+ break;
+ case DELETE:
+ if (deleteTooltipManager == null) {
+ deleteTooltipManager = new DeleteTooltipManager(adapterFactory);
+ }
+ manager = deleteTooltipManager;
+ break;
+ case MOVE:
+ if (moveTooltipManager == null) {
+ moveTooltipManager = new MoveTooltipManager(adapterFactory);
+ }
+ manager = moveTooltipManager;
+ break;
+ default:
+ // Do nothing
+ }
+
+ return manager;
+ }
+
+}

Back to the top