summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAxel Richard2013-01-25 06:20:07 (EST)
committer Axel Richard2013-01-29 09:33:39 (EST)
commit1ec1442bda02cacf1332fc94def28214856e25cb (patch)
tree5e80c5910eba71e4cc78d7ece2f6e08011db6e5e
parent3675b2c9c730d52d29a48cff25cb46e4d0fb75bd (diff)
downloadorg.eclipse.emf.compare-1ec1442bda02cacf1332fc94def28214856e25cb.zip
org.eclipse.emf.compare-1ec1442bda02cacf1332fc94def28214856e25cb.tar.gz
org.eclipse.emf.compare-1ec1442bda02cacf1332fc94def28214856e25cb.tar.bz2
[398360] Provide content merge viewer for resource attachment changesrefs/changes/30/9930/4
Currently there is no content merge viewers for the resource attachment changes. EMF compare will provide a specific one close to the content merge viewer on non containment reference changes, but displaying the direct contents of the changed resource. Change-Id: I2158e4ba9dc8b60b3da3f6ce989faef07ea41cb1
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/plugin.xml12
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/EMFCompareContentMergeViewer.java1118
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/ContentMergeViewerConstants.java54
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/IDEResourceContentsAccessorImpl.java78
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/factory/IDEResourceContentsAccessorFactory.java68
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/table/TableContentMergeViewer.java742
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/table/TableContentMergeViewerContentProvider.java414
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/MergeViewerInfoViewer.java368
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/TableMergeViewer.java620
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/BasicResourceContentsAccessorImpl.java186
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/BasicStructuralFeatureAccessorImpl.java316
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/ICompareAccessor.java28
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/IResourceContentsAccessor.java22
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/IStructuralFeatureAccessor.java62
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/ResourceContentsAccessorImpl.java233
15 files changed, 2483 insertions, 1838 deletions
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/plugin.xml b/plugins/org.eclipse.emf.compare.ide.ui/plugin.xml
index 3e13bdb..6b23253 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/plugin.xml
+++ b/plugins/org.eclipse.emf.compare.ide.ui/plugin.xml
@@ -2,7 +2,7 @@
<?eclipse version="3.4"?>
<!--
- 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
@@ -51,6 +51,12 @@
id="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.text.EMFCompareTextContentMergeViewer"
label="EMFCompare Text Merge Viewer">
</viewer>
+ <viewer
+ class="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.table.TableContentMergeViewerCreator"
+ extensions="resource_contents"
+ id="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.text.EMFCompareResourceContentsContentMergeViewer"
+ label="EMFCompare Resource Contents Merge Viewer">
+ </viewer>
</extension>
<extension
point="org.eclipse.emf.edit.itemProviderAdapterFactories">
@@ -78,6 +84,10 @@
class="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.factory.IDEStringAttributeChangeAccessorFactory"
ranking="10">
</factory>
+ <factory
+ class="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.factory.IDEResourceContentsAccessorFactory"
+ ranking="10">
+ </factory>
</extension>
<extension
point="org.eclipse.ui.commands">
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/EMFCompareContentMergeViewer.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/EMFCompareContentMergeViewer.java
index 903166a..91dfb66 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/EMFCompareContentMergeViewer.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/EMFCompareContentMergeViewer.java
@@ -1,559 +1,559 @@
-/*******************************************************************************
- * 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.contentmergeviewer;
-
-import java.util.EventObject;
-import java.util.Iterator;
-import java.util.ResourceBundle;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.eclipse.compare.CompareConfiguration;
-import org.eclipse.compare.CompareNavigator;
-import org.eclipse.compare.ICompareNavigator;
-import org.eclipse.compare.contentmergeviewer.ContentMergeViewer;
-import org.eclipse.compare.internal.CompareHandlerService;
-import org.eclipse.compare.internal.Utilities;
-import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.emf.common.command.Command;
-import org.eclipse.emf.common.command.CommandStackListener;
-import org.eclipse.emf.common.util.EList;
-import org.eclipse.emf.compare.Comparison;
-import org.eclipse.emf.compare.Diff;
-import org.eclipse.emf.compare.domain.ICompareEditingDomain;
-import org.eclipse.emf.compare.ide.EMFCompareIDEPlugin;
-import org.eclipse.emf.compare.ide.ui.internal.EMFCompareConstants;
-import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util.DynamicObject;
-import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util.EMFCompareColor;
-import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util.RedoAction;
-import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util.UndoAction;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.ICompareColor;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.ICompareColorProvider;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewerItem;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.IStructuralFeatureAccessor;
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.ActionContributionItem;
-import org.eclipse.jface.action.ToolBarManager;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.ISelectionProvider;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.events.PaintEvent;
-import org.eclipse.swt.events.PaintListener;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.ui.actions.ActionFactory;
-
-/**
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- */
-public abstract class EMFCompareContentMergeViewer extends ContentMergeViewer implements ISelectionChangedListener, ICompareColorProvider, IAdaptable {
-
- private static final String HANDLER_SERVICE = "fHandlerService";
-
- protected static final int HORIZONTAL = 1;
-
- protected static final int VERTICAL = 2;
-
- protected static final double HSPLIT = 0.5;
-
- protected static final double VSPLIT = 0.3;
-
- /**
- * Width of center bar
- */
- protected static final int CENTER_WIDTH = 34;
-
- private IMergeViewer fAncestor;
-
- private IMergeViewer fLeft;
-
- private IMergeViewer fRight;
-
- private ActionContributionItem fCopyDiffLeftToRightItem;
-
- private ActionContributionItem fCopyDiffRightToLeftItem;
-
- private final AtomicBoolean fSyncingSelections = new AtomicBoolean(false);
-
- private EMFCompareColor fColors;
-
- private final DynamicObject fDynamicObject;
-
- private CommandStackListener fCommandStackListener;
-
- private UndoAction undoAction;
-
- private RedoAction redoAction;
-
- /**
- * @param style
- * @param bundle
- * @param cc
- */
- protected EMFCompareContentMergeViewer(int style, ResourceBundle bundle, CompareConfiguration cc) {
- super(style, bundle, cc);
- fDynamicObject = new DynamicObject(this);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.ICompareColorProvider#getCompareColor()
- */
- public ICompareColor getCompareColor() {
- return fColors;
- }
-
- /**
- * @return the fEditingDomain
- */
- protected final ICompareEditingDomain getEditingDomain() {
- return (ICompareEditingDomain)getCompareConfiguration().getProperty(
- EMFCompareConstants.EDITING_DOMAIN);
- }
-
- /**
- * @return the fComparison
- */
- protected final Comparison getComparison() {
- return (Comparison)getCompareConfiguration().getProperty(EMFCompareConstants.COMPARE_RESULT);
- }
-
- /**
- * {@inheritDoc}
- * <p>
- * Overriden to enhance visibility.
- * </p>
- *
- * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#isThreeWay()
- */
- @Override
- public boolean isThreeWay() {
- // enhances visibility
- return super.isThreeWay();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#updateContent(java.lang.Object,
- * java.lang.Object, java.lang.Object)
- */
- @Override
- protected void updateContent(Object ancestor, Object left, Object right) {
- undoAction.setEditingDomain(getEditingDomain());
- redoAction.setEditingDomain(getEditingDomain());
-
- if (getEditingDomain() != null && fCommandStackListener == null) {
- fCommandStackListener = installCommandStackListener(undoAction, redoAction);
- }
-
- fAncestor.setInput(ancestor);
- fLeft.setInput(left);
- fRight.setInput(right);
- // must update selection after the three viewers input has been set
- // to avoid some NPE/AssertionError (they are calling each other on selectionChanged event to
- // synchronize their selection)
-
- IMergeViewerItem leftInitialItem = null;
- if (left instanceof IStructuralFeatureAccessor) {
- leftInitialItem = ((IStructuralFeatureAccessor)left).getInitialItem();
- }
-
- ISelection leftSelection = createSelectionOrEmpty(leftInitialItem);
- fLeft.setSelection(leftSelection, true); // others will synchronize on this one :)
-
- getCenterControl().redraw();
- }
-
- private ISelection createSelectionOrEmpty(final Object o) {
- final ISelection selection;
- if (o != null) {
- selection = new StructuredSelection(o);
- } else {
- selection = StructuredSelection.EMPTY;
- }
- return selection;
- }
-
- /**
- * Inhibits this method to avoid asking to save on each input change!!
- *
- * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#doSave(java.lang.Object,
- * java.lang.Object)
- */
- @Override
- protected boolean doSave(Object newInput, Object oldInput) {
- return false;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#createControls(org.eclipse.swt.widgets.Composite)
- */
- @Override
- protected void createControls(Composite composite) {
- fAncestor = createMergeViewer(composite, MergeViewerSide.ANCESTOR);
- fAncestor.addSelectionChangedListener(this);
-
- fLeft = createMergeViewer(composite, MergeViewerSide.LEFT);
- fLeft.addSelectionChangedListener(this);
-
- fRight = createMergeViewer(composite, MergeViewerSide.RIGHT);
- fRight.addSelectionChangedListener(this);
-
- fColors = new EMFCompareColor(this, null, getCompareConfiguration());
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#createToolItems(org.eclipse.jface.action.ToolBarManager)
- */
- @Override
- protected void createToolItems(ToolBarManager toolBarManager) {
- // Copy actions
- CompareConfiguration cc = getCompareConfiguration();
- if (cc.isRightEditable()) {
- Action copyLeftToRight = new Action() {
- @Override
- public void run() {
- copyDiff(true);
- // Select next diff
- navigate(true);
- }
- };
- Utilities.initAction(copyLeftToRight, getResourceBundle(), "action.CopyDiffLeftToRight."); //$NON-NLS-1$
- copyLeftToRight.setEnabled(false);
- fCopyDiffLeftToRightItem = new ActionContributionItem(copyLeftToRight);
- fCopyDiffLeftToRightItem.setVisible(true);
- toolBarManager.appendToGroup("merge", fCopyDiffLeftToRightItem); //$NON-NLS-1$
- getHandlerService().registerAction(copyLeftToRight, "org.eclipse.compare.copyLeftToRight"); //$NON-NLS-1$
- }
-
- if (cc.isLeftEditable()) {
- Action copyRightToLeft = new Action() {
- @Override
- public void run() {
- copyDiff(false);
- // Select next diff
- navigate(true);
- }
- };
- Utilities.initAction(copyRightToLeft, getResourceBundle(), "action.CopyDiffRightToLeft."); //$NON-NLS-1$
- copyRightToLeft.setEnabled(false);
- fCopyDiffRightToLeftItem = new ActionContributionItem(copyRightToLeft);
- fCopyDiffRightToLeftItem.setVisible(true);
- toolBarManager.appendToGroup("merge", fCopyDiffRightToLeftItem); //$NON-NLS-1$
- getHandlerService().registerAction(copyRightToLeft, "org.eclipse.compare.copyRightToLeft"); //$NON-NLS-1$
- }
-
- // Navigation
- final Action nextDiff = new Action() {
- @Override
- public void run() {
- navigate(true);
- }
- };
- Utilities.initAction(nextDiff, getResourceBundle(), "action.NextDiff.");
- ActionContributionItem contributionNextDiff = new ActionContributionItem(nextDiff);
- contributionNextDiff.setVisible(true);
- toolBarManager.appendToGroup("navigation", contributionNextDiff);
-
- final Action previousDiff = new Action() {
- @Override
- public void run() {
- navigate(false);
- }
- };
- Utilities.initAction(previousDiff, getResourceBundle(), "action.PrevDiff.");
- ActionContributionItem contributionPreviousDiff = new ActionContributionItem(previousDiff);
- contributionPreviousDiff.setVisible(true);
- toolBarManager.appendToGroup("navigation", contributionPreviousDiff);
-
- undoAction = new UndoAction(getEditingDomain());
- redoAction = new RedoAction(getEditingDomain());
-
- if (getEditingDomain() != null && fCommandStackListener == null) {
- fCommandStackListener = installCommandStackListener(undoAction, redoAction);
- }
-
- getHandlerService().setGlobalActionHandler(ActionFactory.UNDO.getId(), undoAction);
- getHandlerService().setGlobalActionHandler(ActionFactory.REDO.getId(), redoAction);
- }
-
- private CommandStackListener installCommandStackListener(final UndoAction undoAction,
- final RedoAction redoAction) {
- CommandStackListener commandStackListener = new CommandStackListener() {
- public void commandStackChanged(EventObject event) {
- undoAction.update();
- redoAction.update();
- setLeftDirty(getEditingDomain().getCommandStack().isLeftSaveNeeded());
- setRightDirty(getEditingDomain().getCommandStack().isRightSaveNeeded());
- refresh();
- }
- };
- getEditingDomain().getCommandStack().addCommandStackListener(commandStackListener);
- return commandStackListener;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#copy(boolean)
- */
- @Override
- protected void copy(boolean leftToRight) {
- EList<Diff> differences = getComparison().getDifferences();
-
- final Command copyCommand = getEditingDomain().createCopyAllNonConflictingCommand(differences,
- leftToRight, EMFCompareIDEPlugin.getDefault().getMergerRegistry());
-
- getEditingDomain().getCommandStack().execute(copyCommand);
-
- // if (leftToRight) {
- // setRightDirty(true);
- // } else {
- // setLeftDirty(true);
- // }
- refresh();
- }
-
- /**
- * Called by the framework to navigate to the next (or previous) difference. This will open the content
- * viewer for the next (or previous) diff displayed in the structure viewer.
- *
- * @param next
- * <code>true</code> if we are to open the next structure viewer's diff, <code>false</code> if
- * we should go to the previous instead.
- */
- protected void navigate(boolean next) {
- final Control control = getControl();
- if (control != null && !control.isDisposed()) {
- final ICompareNavigator navigator = getCompareConfiguration().getContainer().getNavigator();
- if (navigator instanceof CompareNavigator && ((CompareNavigator)navigator).hasChange(next)) {
- navigator.selectChange(next);
- }
- }
- }
-
- /**
- *
- */
- protected abstract void copyDiff(boolean leftToRight);
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#handleResizeAncestor(int, int, int, int)
- */
- @Override
- protected void handleResizeAncestor(int x, int y, int width, int height) {
- if (width > 0) {
- getAncestorMergeViewer().getControl().setVisible(true);
- getAncestorMergeViewer().getControl().setBounds(x, y, width, height);
- } else {
- getAncestorMergeViewer().getControl().setVisible(false);
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#handleResizeLeftRight(int, int, int,
- * int, int, int)
- */
- @Override
- protected void handleResizeLeftRight(int x, int y, int width1, int centerWidth, int width2, int height) {
- fLeft.getControl().setBounds(x, y, width1, height);
- fRight.getControl().setBounds(x + width1 + centerWidth, y, width2, height);
- }
-
- protected abstract IMergeViewer createMergeViewer(Composite parent, MergeViewerSide side);
-
- @Override
- protected final int getCenterWidth() {
- return CENTER_WIDTH;
- }
-
- protected final CompareHandlerService getHandlerService() {
- return (CompareHandlerService)fDynamicObject.get(HANDLER_SERVICE);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#getControl()
- */
- @Override
- public Composite getControl() {
- return (Composite)super.getControl();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#createCenterControl(org.eclipse.swt.widgets.Composite)
- */
- @Override
- protected Control createCenterControl(Composite parent) {
- final Control ret = super.createCenterControl(parent);
-
- final PaintListener paintListener = new PaintListener() {
- public void paintControl(PaintEvent e) {
- paintCenter(e.gc);
- }
- };
- ret.addPaintListener(paintListener);
-
- ret.addDisposeListener(new DisposeListener() {
- public void widgetDisposed(DisposeEvent e) {
- ret.removePaintListener(paintListener);
- }
- });
-
- return ret;
- }
-
- protected abstract void paintCenter(GC g);
-
- public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) {
- if (adapter == CompareHandlerService.class) {
- return getHandlerService();
- }
- if (adapter == CompareHandlerService[].class) {
- return new CompareHandlerService[] {getHandlerService(), };
- }
- return null;
- }
-
- /**
- * @return the fAncestor
- */
- protected IMergeViewer getAncestorMergeViewer() {
- return fAncestor;
- }
-
- /**
- * @return the fLeft
- */
- protected IMergeViewer getLeftMergeViewer() {
- return fLeft;
- }
-
- /**
- * @return the fRight
- */
- protected IMergeViewer getRightMergeViewer() {
- return fRight;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
- */
- public void selectionChanged(SelectionChangedEvent event) {
- if (fSyncingSelections.compareAndSet(false, true)) { // prevents stack overflow :)
- try {
- ISelectionProvider selectionProvider = event.getSelectionProvider();
- ISelection selection = event.getSelection();
- synchronizeSelection(selectionProvider, selection);
- updateToolItems();
- } finally {
- fSyncingSelections.set(false);
- }
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#updateToolItems()
- */
- @Override
- protected void updateToolItems() {
- super.updateToolItems();
-
- Diff diff = getDiffFrom(getRightMergeViewer());
- if (diff == null) {
- diff = getDiffFrom(getLeftMergeViewer());
- }
- boolean enableCopy = false;
- if (diff != null) {
- enableCopy = true;
- }
-
- if (fCopyDiffLeftToRightItem != null) {
- fCopyDiffLeftToRightItem.getAction().setEnabled(enableCopy);
- }
- if (fCopyDiffRightToLeftItem != null) {
- fCopyDiffRightToLeftItem.getAction().setEnabled(enableCopy);
- }
- }
-
- /**
- * Checks the element selected in the given viewer in order to determine whether it can be adapted into a
- * Diff.
- *
- * @param viewer
- * The viewer which selection is to be checked.
- * @return The first of the Diffs selected in the given viewer, if any.
- */
- protected Diff getDiffFrom(IMergeViewer viewer) {
- Diff diff = null;
- final ISelection selection = viewer.getSelection();
- if (selection instanceof IStructuredSelection && !selection.isEmpty()) {
- final Iterator<?> selectedElements = ((IStructuredSelection)selection).iterator();
- while (diff == null && selectedElements.hasNext()) {
- final Object element = selectedElements.next();
- if (element instanceof IMergeViewerItem) {
- diff = ((IMergeViewerItem)element).getDiff();
- }
- }
- }
- return diff;
- }
-
- private void synchronizeSelection(final ISelectionProvider selectionProvider, final ISelection selection) {
- if (selectionProvider == fLeft) {
- fRight.setSelection(selection, true);
- fAncestor.setSelection(selection, true);
- } else if (selectionProvider == fRight) {
- fLeft.setSelection(selection, true);
- fAncestor.setSelection(selection, true);
- } else { // selectionProvider == fAncestor
- fLeft.setSelection(selection, true);
- fRight.setSelection(selection, true);
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#handleDispose(org.eclipse.swt.events.DisposeEvent)
- */
- @Override
- protected void handleDispose(DisposeEvent event) {
- if (fCommandStackListener != null && getEditingDomain() != null) {
- getEditingDomain().getCommandStack().removeCommandStackListener(fCommandStackListener);
- }
- super.handleDispose(event);
- }
-}
+/*******************************************************************************
+ * 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.contentmergeviewer;
+
+import java.util.EventObject;
+import java.util.Iterator;
+import java.util.ResourceBundle;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.eclipse.compare.CompareConfiguration;
+import org.eclipse.compare.CompareNavigator;
+import org.eclipse.compare.ICompareNavigator;
+import org.eclipse.compare.contentmergeviewer.ContentMergeViewer;
+import org.eclipse.compare.internal.CompareHandlerService;
+import org.eclipse.compare.internal.Utilities;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.CommandStackListener;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.domain.ICompareEditingDomain;
+import org.eclipse.emf.compare.ide.EMFCompareIDEPlugin;
+import org.eclipse.emf.compare.ide.ui.internal.EMFCompareConstants;
+import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util.DynamicObject;
+import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util.EMFCompareColor;
+import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util.RedoAction;
+import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util.UndoAction;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.ICompareColor;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.ICompareColorProvider;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewerItem;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.ICompareAccessor;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.ActionContributionItem;
+import org.eclipse.jface.action.ToolBarManager;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.actions.ActionFactory;
+
+/**
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public abstract class EMFCompareContentMergeViewer extends ContentMergeViewer implements ISelectionChangedListener, ICompareColorProvider, IAdaptable {
+
+ private static final String HANDLER_SERVICE = "fHandlerService";
+
+ protected static final int HORIZONTAL = 1;
+
+ protected static final int VERTICAL = 2;
+
+ protected static final double HSPLIT = 0.5;
+
+ protected static final double VSPLIT = 0.3;
+
+ /**
+ * Width of center bar
+ */
+ protected static final int CENTER_WIDTH = 34;
+
+ private IMergeViewer fAncestor;
+
+ private IMergeViewer fLeft;
+
+ private IMergeViewer fRight;
+
+ private ActionContributionItem fCopyDiffLeftToRightItem;
+
+ private ActionContributionItem fCopyDiffRightToLeftItem;
+
+ private final AtomicBoolean fSyncingSelections = new AtomicBoolean(false);
+
+ private EMFCompareColor fColors;
+
+ private final DynamicObject fDynamicObject;
+
+ private CommandStackListener fCommandStackListener;
+
+ private UndoAction undoAction;
+
+ private RedoAction redoAction;
+
+ /**
+ * @param style
+ * @param bundle
+ * @param cc
+ */
+ protected EMFCompareContentMergeViewer(int style, ResourceBundle bundle, CompareConfiguration cc) {
+ super(style, bundle, cc);
+ fDynamicObject = new DynamicObject(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.ICompareColorProvider#getCompareColor()
+ */
+ public ICompareColor getCompareColor() {
+ return fColors;
+ }
+
+ /**
+ * @return the fEditingDomain
+ */
+ protected final ICompareEditingDomain getEditingDomain() {
+ return (ICompareEditingDomain)getCompareConfiguration().getProperty(
+ EMFCompareConstants.EDITING_DOMAIN);
+ }
+
+ /**
+ * @return the fComparison
+ */
+ protected final Comparison getComparison() {
+ return (Comparison)getCompareConfiguration().getProperty(EMFCompareConstants.COMPARE_RESULT);
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Overriden to enhance visibility.
+ * </p>
+ *
+ * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#isThreeWay()
+ */
+ @Override
+ public boolean isThreeWay() {
+ // enhances visibility
+ return super.isThreeWay();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#updateContent(java.lang.Object,
+ * java.lang.Object, java.lang.Object)
+ */
+ @Override
+ protected void updateContent(Object ancestor, Object left, Object right) {
+ undoAction.setEditingDomain(getEditingDomain());
+ redoAction.setEditingDomain(getEditingDomain());
+
+ if (getEditingDomain() != null && fCommandStackListener == null) {
+ fCommandStackListener = installCommandStackListener(undoAction, redoAction);
+ }
+
+ fAncestor.setInput(ancestor);
+ fLeft.setInput(left);
+ fRight.setInput(right);
+ // must update selection after the three viewers input has been set
+ // to avoid some NPE/AssertionError (they are calling each other on selectionChanged event to
+ // synchronize their selection)
+
+ IMergeViewerItem leftInitialItem = null;
+ if (left instanceof ICompareAccessor) {
+ leftInitialItem = ((ICompareAccessor)left).getInitialItem();
+ }
+
+ ISelection leftSelection = createSelectionOrEmpty(leftInitialItem);
+ fLeft.setSelection(leftSelection, true); // others will synchronize on this one :)
+
+ getCenterControl().redraw();
+ }
+
+ private ISelection createSelectionOrEmpty(final Object o) {
+ final ISelection selection;
+ if (o != null) {
+ selection = new StructuredSelection(o);
+ } else {
+ selection = StructuredSelection.EMPTY;
+ }
+ return selection;
+ }
+
+ /**
+ * Inhibits this method to avoid asking to save on each input change!!
+ *
+ * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#doSave(java.lang.Object,
+ * java.lang.Object)
+ */
+ @Override
+ protected boolean doSave(Object newInput, Object oldInput) {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#createControls(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ protected void createControls(Composite composite) {
+ fAncestor = createMergeViewer(composite, MergeViewerSide.ANCESTOR);
+ fAncestor.addSelectionChangedListener(this);
+
+ fLeft = createMergeViewer(composite, MergeViewerSide.LEFT);
+ fLeft.addSelectionChangedListener(this);
+
+ fRight = createMergeViewer(composite, MergeViewerSide.RIGHT);
+ fRight.addSelectionChangedListener(this);
+
+ fColors = new EMFCompareColor(this, null, getCompareConfiguration());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#createToolItems(org.eclipse.jface.action.ToolBarManager)
+ */
+ @Override
+ protected void createToolItems(ToolBarManager toolBarManager) {
+ // Copy actions
+ CompareConfiguration cc = getCompareConfiguration();
+ if (cc.isRightEditable()) {
+ Action copyLeftToRight = new Action() {
+ @Override
+ public void run() {
+ copyDiff(true);
+ // Select next diff
+ navigate(true);
+ }
+ };
+ Utilities.initAction(copyLeftToRight, getResourceBundle(), "action.CopyDiffLeftToRight."); //$NON-NLS-1$
+ copyLeftToRight.setEnabled(false);
+ fCopyDiffLeftToRightItem = new ActionContributionItem(copyLeftToRight);
+ fCopyDiffLeftToRightItem.setVisible(true);
+ toolBarManager.appendToGroup("merge", fCopyDiffLeftToRightItem); //$NON-NLS-1$
+ getHandlerService().registerAction(copyLeftToRight, "org.eclipse.compare.copyLeftToRight"); //$NON-NLS-1$
+ }
+
+ if (cc.isLeftEditable()) {
+ Action copyRightToLeft = new Action() {
+ @Override
+ public void run() {
+ copyDiff(false);
+ // Select next diff
+ navigate(true);
+ }
+ };
+ Utilities.initAction(copyRightToLeft, getResourceBundle(), "action.CopyDiffRightToLeft."); //$NON-NLS-1$
+ copyRightToLeft.setEnabled(false);
+ fCopyDiffRightToLeftItem = new ActionContributionItem(copyRightToLeft);
+ fCopyDiffRightToLeftItem.setVisible(true);
+ toolBarManager.appendToGroup("merge", fCopyDiffRightToLeftItem); //$NON-NLS-1$
+ getHandlerService().registerAction(copyRightToLeft, "org.eclipse.compare.copyRightToLeft"); //$NON-NLS-1$
+ }
+
+ // Navigation
+ final Action nextDiff = new Action() {
+ @Override
+ public void run() {
+ navigate(true);
+ }
+ };
+ Utilities.initAction(nextDiff, getResourceBundle(), "action.NextDiff.");
+ ActionContributionItem contributionNextDiff = new ActionContributionItem(nextDiff);
+ contributionNextDiff.setVisible(true);
+ toolBarManager.appendToGroup("navigation", contributionNextDiff);
+
+ final Action previousDiff = new Action() {
+ @Override
+ public void run() {
+ navigate(false);
+ }
+ };
+ Utilities.initAction(previousDiff, getResourceBundle(), "action.PrevDiff.");
+ ActionContributionItem contributionPreviousDiff = new ActionContributionItem(previousDiff);
+ contributionPreviousDiff.setVisible(true);
+ toolBarManager.appendToGroup("navigation", contributionPreviousDiff);
+
+ undoAction = new UndoAction(getEditingDomain());
+ redoAction = new RedoAction(getEditingDomain());
+
+ if (getEditingDomain() != null && fCommandStackListener == null) {
+ fCommandStackListener = installCommandStackListener(undoAction, redoAction);
+ }
+
+ getHandlerService().setGlobalActionHandler(ActionFactory.UNDO.getId(), undoAction);
+ getHandlerService().setGlobalActionHandler(ActionFactory.REDO.getId(), redoAction);
+ }
+
+ private CommandStackListener installCommandStackListener(final UndoAction undoAction,
+ final RedoAction redoAction) {
+ CommandStackListener commandStackListener = new CommandStackListener() {
+ public void commandStackChanged(EventObject event) {
+ undoAction.update();
+ redoAction.update();
+ setLeftDirty(getEditingDomain().getCommandStack().isLeftSaveNeeded());
+ setRightDirty(getEditingDomain().getCommandStack().isRightSaveNeeded());
+ refresh();
+ }
+ };
+ getEditingDomain().getCommandStack().addCommandStackListener(commandStackListener);
+ return commandStackListener;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#copy(boolean)
+ */
+ @Override
+ protected void copy(boolean leftToRight) {
+ EList<Diff> differences = getComparison().getDifferences();
+
+ final Command copyCommand = getEditingDomain().createCopyAllNonConflictingCommand(differences,
+ leftToRight, EMFCompareIDEPlugin.getDefault().getMergerRegistry());
+
+ getEditingDomain().getCommandStack().execute(copyCommand);
+
+ // if (leftToRight) {
+ // setRightDirty(true);
+ // } else {
+ // setLeftDirty(true);
+ // }
+ refresh();
+ }
+
+ /**
+ * Called by the framework to navigate to the next (or previous) difference. This will open the content
+ * viewer for the next (or previous) diff displayed in the structure viewer.
+ *
+ * @param next
+ * <code>true</code> if we are to open the next structure viewer's diff, <code>false</code> if
+ * we should go to the previous instead.
+ */
+ protected void navigate(boolean next) {
+ final Control control = getControl();
+ if (control != null && !control.isDisposed()) {
+ final ICompareNavigator navigator = getCompareConfiguration().getContainer().getNavigator();
+ if (navigator instanceof CompareNavigator && ((CompareNavigator)navigator).hasChange(next)) {
+ navigator.selectChange(next);
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ protected abstract void copyDiff(boolean leftToRight);
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#handleResizeAncestor(int, int, int, int)
+ */
+ @Override
+ protected void handleResizeAncestor(int x, int y, int width, int height) {
+ if (width > 0) {
+ getAncestorMergeViewer().getControl().setVisible(true);
+ getAncestorMergeViewer().getControl().setBounds(x, y, width, height);
+ } else {
+ getAncestorMergeViewer().getControl().setVisible(false);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#handleResizeLeftRight(int, int, int,
+ * int, int, int)
+ */
+ @Override
+ protected void handleResizeLeftRight(int x, int y, int width1, int centerWidth, int width2, int height) {
+ fLeft.getControl().setBounds(x, y, width1, height);
+ fRight.getControl().setBounds(x + width1 + centerWidth, y, width2, height);
+ }
+
+ protected abstract IMergeViewer createMergeViewer(Composite parent, MergeViewerSide side);
+
+ @Override
+ protected final int getCenterWidth() {
+ return CENTER_WIDTH;
+ }
+
+ protected final CompareHandlerService getHandlerService() {
+ return (CompareHandlerService)fDynamicObject.get(HANDLER_SERVICE);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#getControl()
+ */
+ @Override
+ public Composite getControl() {
+ return (Composite)super.getControl();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#createCenterControl(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ protected Control createCenterControl(Composite parent) {
+ final Control ret = super.createCenterControl(parent);
+
+ final PaintListener paintListener = new PaintListener() {
+ public void paintControl(PaintEvent e) {
+ paintCenter(e.gc);
+ }
+ };
+ ret.addPaintListener(paintListener);
+
+ ret.addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ ret.removePaintListener(paintListener);
+ }
+ });
+
+ return ret;
+ }
+
+ protected abstract void paintCenter(GC g);
+
+ public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) {
+ if (adapter == CompareHandlerService.class) {
+ return getHandlerService();
+ }
+ if (adapter == CompareHandlerService[].class) {
+ return new CompareHandlerService[] {getHandlerService(), };
+ }
+ return null;
+ }
+
+ /**
+ * @return the fAncestor
+ */
+ protected IMergeViewer getAncestorMergeViewer() {
+ return fAncestor;
+ }
+
+ /**
+ * @return the fLeft
+ */
+ protected IMergeViewer getLeftMergeViewer() {
+ return fLeft;
+ }
+
+ /**
+ * @return the fRight
+ */
+ protected IMergeViewer getRightMergeViewer() {
+ return fRight;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
+ */
+ public void selectionChanged(SelectionChangedEvent event) {
+ if (fSyncingSelections.compareAndSet(false, true)) { // prevents stack overflow :)
+ try {
+ ISelectionProvider selectionProvider = event.getSelectionProvider();
+ ISelection selection = event.getSelection();
+ synchronizeSelection(selectionProvider, selection);
+ updateToolItems();
+ } finally {
+ fSyncingSelections.set(false);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#updateToolItems()
+ */
+ @Override
+ protected void updateToolItems() {
+ super.updateToolItems();
+
+ Diff diff = getDiffFrom(getRightMergeViewer());
+ if (diff == null) {
+ diff = getDiffFrom(getLeftMergeViewer());
+ }
+ boolean enableCopy = false;
+ if (diff != null) {
+ enableCopy = true;
+ }
+
+ if (fCopyDiffLeftToRightItem != null) {
+ fCopyDiffLeftToRightItem.getAction().setEnabled(enableCopy);
+ }
+ if (fCopyDiffRightToLeftItem != null) {
+ fCopyDiffRightToLeftItem.getAction().setEnabled(enableCopy);
+ }
+ }
+
+ /**
+ * Checks the element selected in the given viewer in order to determine whether it can be adapted into a
+ * Diff.
+ *
+ * @param viewer
+ * The viewer which selection is to be checked.
+ * @return The first of the Diffs selected in the given viewer, if any.
+ */
+ protected Diff getDiffFrom(IMergeViewer viewer) {
+ Diff diff = null;
+ final ISelection selection = viewer.getSelection();
+ if (selection instanceof IStructuredSelection && !selection.isEmpty()) {
+ final Iterator<?> selectedElements = ((IStructuredSelection)selection).iterator();
+ while (diff == null && selectedElements.hasNext()) {
+ final Object element = selectedElements.next();
+ if (element instanceof IMergeViewerItem) {
+ diff = ((IMergeViewerItem)element).getDiff();
+ }
+ }
+ }
+ return diff;
+ }
+
+ private void synchronizeSelection(final ISelectionProvider selectionProvider, final ISelection selection) {
+ if (selectionProvider == fLeft) {
+ fRight.setSelection(selection, true);
+ fAncestor.setSelection(selection, true);
+ } else if (selectionProvider == fRight) {
+ fLeft.setSelection(selection, true);
+ fAncestor.setSelection(selection, true);
+ } else { // selectionProvider == fAncestor
+ fLeft.setSelection(selection, true);
+ fRight.setSelection(selection, true);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#handleDispose(org.eclipse.swt.events.DisposeEvent)
+ */
+ @Override
+ protected void handleDispose(DisposeEvent event) {
+ if (fCommandStackListener != null && getEditingDomain() != null) {
+ getEditingDomain().getCommandStack().removeCommandStackListener(fCommandStackListener);
+ }
+ super.handleDispose(event);
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/ContentMergeViewerConstants.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/ContentMergeViewerConstants.java
index bf46c80..90b146f 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/ContentMergeViewerConstants.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/ContentMergeViewerConstants.java
@@ -1,26 +1,28 @@
-/*******************************************************************************
- * 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.contentmergeviewer.accessor;
-
-/**
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- */
-public final class ContentMergeViewerConstants {
-
- public static final String DIFF_NODE_TYPE = "emfcompare_diff"; //$NON-NLS-1$
-
- public static final String TEXT_DIFF_NODE_TYPE = "eText"; //$NON-NLS-1$
-
- public static final String EOBJECT_NODE_TYPE = "eobject"; //$NON-NLS-1$
-
- private ContentMergeViewerConstants() {
- }
-}
+/*******************************************************************************
+ * 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.contentmergeviewer.accessor;
+
+/**
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public final class ContentMergeViewerConstants {
+
+ public static final String DIFF_NODE_TYPE = "emfcompare_diff"; //$NON-NLS-1$
+
+ public static final String TEXT_DIFF_NODE_TYPE = "eText"; //$NON-NLS-1$
+
+ public static final String EOBJECT_NODE_TYPE = "eobject"; //$NON-NLS-1$
+
+ public static final String RESOURCE_CONTENTS_NODE_TYPE = "resource_contents"; //$NON-NLS-1$
+
+ private ContentMergeViewerConstants() {
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/IDEResourceContentsAccessorImpl.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/IDEResourceContentsAccessorImpl.java
new file mode 100644
index 0000000..e865b8f
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/IDEResourceContentsAccessorImpl.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * 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.ide.ui.internal.contentmergeviewer.accessor;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import org.eclipse.compare.IStreamContentAccessor;
+import org.eclipse.compare.ITypedElement;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.ResourceContentsAccessorImpl;
+import org.eclipse.emf.ecore.provider.EcoreEditPlugin;
+import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ */
+public class IDEResourceContentsAccessorImpl extends ResourceContentsAccessorImpl implements ITypedElement, IStreamContentAccessor {
+
+ public IDEResourceContentsAccessorImpl(Diff diff, MergeViewerSide side) {
+ super(diff, side);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.ITypedElement#getName()
+ */
+ public String getName() {
+ return this.getClass().getName();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.ITypedElement#getImage()
+ */
+ public Image getImage() {
+ return ExtendedImageRegistry.getInstance().getImage(
+ EcoreEditPlugin.getPlugin().getImage("full/obj16/EObject")); //$NON-NLS-1$
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.ITypedElement#getType()
+ */
+ public String getType() {
+ return ContentMergeViewerConstants.RESOURCE_CONTENTS_NODE_TYPE;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.IStreamContentAccessor#getContents()
+ */
+ public InputStream getContents() throws CoreException {
+ /*
+ * #293926 : Whatever we return has no importance as long as it is not "null", this is only to make
+ * CompareUIPlugin#guessType happy. However, it is only happy if what we return resembles a text. Note
+ * that this bug has been fixed in 3.7.1, we're keeping this around for the compatibility with 3.5 and
+ * 3.6.
+ */
+ return new ByteArrayInputStream(new byte[] {' ' });
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/factory/IDEResourceContentsAccessorFactory.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/factory/IDEResourceContentsAccessorFactory.java
new file mode 100644
index 0000000..e47535a
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/factory/IDEResourceContentsAccessorFactory.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * 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.ide.ui.internal.contentmergeviewer.accessor.factory;
+
+import org.eclipse.compare.ITypedElement;
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.ResourceAttachmentChange;
+import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.IAccessorFactory.AbstractAccessorFactory;
+import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.IDEResourceContentsAccessorImpl;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
+
+/**
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ */
+public class IDEResourceContentsAccessorFactory extends AbstractAccessorFactory {
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.IAccessorFactory#isFactoryFor(java.lang.Object)
+ */
+ public boolean isFactoryFor(Object target) {
+ if (target instanceof ResourceAttachmentChange) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.IAccessorFactory#createLeft(org.eclipse.emf.common.notify.AdapterFactory,
+ * java.lang.Object)
+ */
+ public ITypedElement createLeft(AdapterFactory adapterFactory, Object target) {
+ return new IDEResourceContentsAccessorImpl((Diff)target, MergeViewerSide.LEFT);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.IAccessorFactory#createRight(org.eclipse.emf.common.notify.AdapterFactory,
+ * java.lang.Object)
+ */
+ public ITypedElement createRight(AdapterFactory adapterFactory, Object target) {
+ return new IDEResourceContentsAccessorImpl((Diff)target, MergeViewerSide.RIGHT);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.IAccessorFactory#createAncestor(org.eclipse.emf.common.notify.AdapterFactory,
+ * java.lang.Object)
+ */
+ public ITypedElement createAncestor(AdapterFactory adapterFactory, Object target) {
+ return new IDEResourceContentsAccessorImpl((Diff)target, MergeViewerSide.ANCESTOR);
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/table/TableContentMergeViewer.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/table/TableContentMergeViewer.java
index 6704543..6f4bfa1 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/table/TableContentMergeViewer.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/table/TableContentMergeViewer.java
@@ -1,371 +1,371 @@
-/*******************************************************************************
- * 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.contentmergeviewer.table;
-
-import java.util.ResourceBundle;
-
-import org.eclipse.compare.CompareConfiguration;
-import org.eclipse.emf.common.command.Command;
-import org.eclipse.emf.compare.Diff;
-import org.eclipse.emf.compare.DifferenceState;
-import org.eclipse.emf.compare.ide.EMFCompareIDEPlugin;
-import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EMFCompareContentMergeViewer;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewerItem;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.MatchedObject;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.MergeViewer;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.TableMergeViewer;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.IStructuralFeatureAccessor;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.InternalEObject;
-import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
-import org.eclipse.emf.edit.provider.IItemFontProvider;
-import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory;
-import org.eclipse.emf.edit.provider.resource.ResourceItemProviderAdapterFactory;
-import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
-import org.eclipse.jface.viewers.ArrayContentProvider;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseWheelListener;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableItem;
-
-/**
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- */
-public class TableContentMergeViewer extends EMFCompareContentMergeViewer {
-
- /**
- * Bundle name of the property file containing all displayed strings.
- */
- private static final String BUNDLE_NAME = TableContentMergeViewer.class.getName();
-
- private final ComposedAdapterFactory fAdapterFactory;
-
- private double[] fBasicCenterCurve;
-
- /**
- * Call the super constructor.
- *
- * @see TableContentMergeViewer
- */
- protected TableContentMergeViewer(Composite parent, CompareConfiguration config) {
- super(SWT.NONE, ResourceBundle.getBundle(BUNDLE_NAME), config);
- fAdapterFactory = new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
- fAdapterFactory.addAdapterFactory(new ReflectiveItemProviderAdapterFactory());
- fAdapterFactory.addAdapterFactory(new ResourceItemProviderAdapterFactory());
-
- buildControl(parent);
- setContentProvider(new TableContentMergeViewerContentProvider(config));
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#handleDispose(org.eclipse.swt.events.DisposeEvent)
- */
- @Override
- protected void handleDispose(DisposeEvent event) {
- fAdapterFactory.dispose();
- super.handleDispose(event);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#getContents(boolean)
- */
- @Override
- protected byte[] getContents(boolean left) {
- return null;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EMFCompareContentMergeViewer#copyDiff(boolean)
- */
- @Override
- protected void copyDiff(boolean leftToRight) {
- final Diff diffToCopy = getDiffToCopy(getRightMergeViewer());
- if (diffToCopy != null) {
- Command copyCommand = getEditingDomain().createCopyCommand(diffToCopy, leftToRight,
- EMFCompareIDEPlugin.getDefault().getMergerRegistry());
- getEditingDomain().getCommandStack().execute(copyCommand);
-
- refresh();
- }
- }
-
- private Diff getDiffToCopy(MergeViewer mergeViewer) {
- Diff diffToCopy = null;
- ISelection selection = mergeViewer.getSelection();
- if (selection instanceof IStructuredSelection && !selection.isEmpty()) {
- Object firstElement = ((IStructuredSelection)selection).getFirstElement();
- if (firstElement instanceof IMergeViewerItem) {
- diffToCopy = ((IMergeViewerItem)firstElement).getDiff();
- }
- }
- return diffToCopy;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EMFCompareContentMergeViewer#getLeftMergeViewer()
- */
- @Override
- protected TableMergeViewer getLeftMergeViewer() {
- return (TableMergeViewer)super.getLeftMergeViewer();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EMFCompareContentMergeViewer#getRightMergeViewer()
- */
- @Override
- protected TableMergeViewer getRightMergeViewer() {
- return (TableMergeViewer)super.getRightMergeViewer();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EMFCompareContentMergeViewer#getAncestorMergeViewer()
- */
- @Override
- protected TableMergeViewer getAncestorMergeViewer() {
- return (TableMergeViewer)super.getAncestorMergeViewer();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EMFCompareContentMergeViewer#createMergeViewer(org.eclipse.swt.widgets.Composite,
- * org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.IMergeViewer.MergeViewerSide)
- */
- @Override
- protected MergeViewer createMergeViewer(Composite parent, final MergeViewerSide side) {
- TableMergeViewer ret = new TableMergeViewer(parent, side, this);
- ret.getStructuredViewer().getTable().getVerticalBar().setVisible(false);
-
- ret.setContentProvider(new ArrayContentProvider() {
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.ArrayContentProvider#getElements(java.lang.Object)
- */
- @Override
- public Object[] getElements(Object inputElement) {
- if (inputElement instanceof IStructuralFeatureAccessor) {
- return super.getElements(((IStructuralFeatureAccessor)inputElement).getItems());
- }
- return super.getElements(inputElement);
- }
- });
- ret.setLabelProvider(new AdapterFactoryLabelProvider.FontAndColorProvider(fAdapterFactory, ret
- .getStructuredViewer()) {
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#getFont(java.lang.Object,
- * int)
- */
- @Override
- public Font getFont(Object object, int columnIndex) {
- if (object instanceof MatchedObject) {
- final Object value = ((MatchedObject)object).getSideValue(side);
- if (value instanceof EObject && ((EObject)value).eIsProxy()) {
- return getFontFromObject(IItemFontProvider.ITALIC_FONT);
- }
- }
- return super.getFont(object, columnIndex);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#getColumnText(java.lang.Object,
- * int)
- */
- @Override
- public String getColumnText(Object object, int columnIndex) {
- if (object instanceof MatchedObject) {
- final String text;
- final Object value = ((MatchedObject)object).getSideValue(side);
- if (value instanceof EObject && ((EObject)value).eIsProxy()) {
- text = "proxy : " + ((InternalEObject)value).eProxyURI().toString();
- } else {
- text = super.getColumnText(value, columnIndex);
- }
- return text;
- }
- return super.getColumnText(object, columnIndex);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#getColumnImage(java.lang.Object,
- * int)
- */
- @Override
- public Image getColumnImage(Object object, int columnIndex) {
- if (object instanceof MatchedObject) {
- return super.getColumnImage(((MatchedObject)object).getSideValue(side), columnIndex);
- }
- return super.getColumnImage(object, columnIndex);
- }
- });
- ret.getStructuredViewer().getTable().getVerticalBar().addListener(SWT.Selection, new Listener() {
- public void handleEvent(Event event) {
- redrawCenterControl();
- }
- });
-
- ret.getStructuredViewer().getTable().addMouseWheelListener(new MouseWheelListener() {
- public void mouseScrolled(MouseEvent e) {
- redrawCenterControl();
- }
- });
- ret.addSelectionChangedListener(new ISelectionChangedListener() {
- public void selectionChanged(SelectionChangedEvent event) {
- redrawCenterControl();
- }
- });
- return ret;
- }
-
- protected void redrawCenterControl() {
- getCenterControl().redraw();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EMFCompareContentMergeViewer#paintCenter(org.eclipse.swt.widgets.Canvas,
- * org.eclipse.swt.graphics.GC)
- */
- @Override
- protected void paintCenter(GC g) {
- TableMergeViewer leftMergeViewer = getLeftMergeViewer();
- TableMergeViewer rightMergeViewer = getRightMergeViewer();
-
- Table leftTable = leftMergeViewer.getStructuredViewer().getTable();
- Table rightTable = rightMergeViewer.getStructuredViewer().getTable();
-
- Rectangle leftClientArea = leftTable.getClientArea();
- Rectangle rightClientArea = rightTable.getClientArea();
-
- TableItem[] leftItems = leftTable.getItems();
- TableItem[] rightItems = rightTable.getItems();
-
- TableItem[] selection = leftTable.getSelection();
-
- for (TableItem leftItem : leftItems) {
- final boolean selected;
- if (selection.length > 0) {
- selected = leftItem == selection[0];
- } else {
- selected = false;
- }
- final Diff leftDiff = ((IMergeViewerItem)leftItem.getData()).getDiff();
-
- if (leftDiff != null && leftDiff.getState() == DifferenceState.UNRESOLVED) {
- TableItem rightItem = findRightTableItemFromLeftDiff(rightItems, leftDiff);
-
- if (rightItem != null) {
- Color strokeColor = getCompareColor().getStrokeColor(leftDiff, isThreeWay(), false,
- selected);
- g.setForeground(strokeColor);
- drawCenterLine(g, leftClientArea, rightClientArea, leftItem, rightItem);
- }
- }
- }
- }
-
- private void drawCenterLine(GC g, Rectangle leftClientArea, Rectangle rightClientArea,
- TableItem leftItem, TableItem rightItem) {
- Control control = getCenterControl();
- Point from = new Point(0, 0);
- Point to = new Point(0, 0);
-
- Rectangle leftBounds = leftItem.getBounds();
- Rectangle rightBounds = rightItem.getBounds();
-
- from.y = leftBounds.y + (leftBounds.height / 2) - leftClientArea.y + 1
- + getLeftMergeViewer().getVerticalOffset();
-
- to.x = control.getBounds().width;
- to.y = rightBounds.y + (rightBounds.height / 2) - rightClientArea.y + 1
- + getRightMergeViewer().getVerticalOffset();
-
- int[] points = getCenterCurvePoints(from, to);
- for (int i = 1; i < points.length; i++) {
- g.drawLine(from.x + i - 1, points[i - 1], i, points[i]);
- }
- }
-
- private TableItem findRightTableItemFromLeftDiff(TableItem[] rightItems, Diff leftDiff) {
- TableItem ret = null;
- for (int i = 0; i < rightItems.length && ret == null; i++) {
- TableItem rightItem = rightItems[i];
- final Diff rightDiff = ((IMergeViewerItem)rightItem.getData()).getDiff();
- if (leftDiff == rightDiff) {
- ret = rightItem;
- }
- }
- return ret;
- }
-
- private int[] getCenterCurvePoints(Point from, Point to) {
- int startx = from.x;
- int starty = from.y;
- int endx = to.x;
- int endy = to.y;
- if (fBasicCenterCurve == null) {
- buildBaseCenterCurve(endx - startx);
- }
- double height = endy - starty;
- height = height / 2;
- int width = endx - startx;
- int[] points = new int[width];
- for (int i = 0; i < width; i++) {
- points[i] = (int)(-height * fBasicCenterCurve[i] + height + starty);
- }
- return points;
- }
-
- private void buildBaseCenterCurve(int w) {
- double width = w;
- fBasicCenterCurve = new double[getCenterWidth()];
- for (int i = 0; i < getCenterWidth(); i++) {
- double r = i / width;
- fBasicCenterCurve[i] = Math.cos(Math.PI * r);
- }
- }
-}
+/*******************************************************************************
+ * 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.contentmergeviewer.table;
+
+import java.util.ResourceBundle;
+
+import org.eclipse.compare.CompareConfiguration;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.DifferenceState;
+import org.eclipse.emf.compare.ide.EMFCompareIDEPlugin;
+import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EMFCompareContentMergeViewer;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewerItem;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.MatchedObject;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.MergeViewer;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.TableMergeViewer;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.ICompareAccessor;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
+import org.eclipse.emf.edit.provider.IItemFontProvider;
+import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory;
+import org.eclipse.emf.edit.provider.resource.ResourceItemProviderAdapterFactory;
+import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseWheelListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+
+/**
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public class TableContentMergeViewer extends EMFCompareContentMergeViewer {
+
+ /**
+ * Bundle name of the property file containing all displayed strings.
+ */
+ private static final String BUNDLE_NAME = TableContentMergeViewer.class.getName();
+
+ private final ComposedAdapterFactory fAdapterFactory;
+
+ private double[] fBasicCenterCurve;
+
+ /**
+ * Call the super constructor.
+ *
+ * @see TableContentMergeViewer
+ */
+ protected TableContentMergeViewer(Composite parent, CompareConfiguration config) {
+ super(SWT.NONE, ResourceBundle.getBundle(BUNDLE_NAME), config);
+ fAdapterFactory = new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
+ fAdapterFactory.addAdapterFactory(new ReflectiveItemProviderAdapterFactory());
+ fAdapterFactory.addAdapterFactory(new ResourceItemProviderAdapterFactory());
+
+ buildControl(parent);
+ setContentProvider(new TableContentMergeViewerContentProvider(config));
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#handleDispose(org.eclipse.swt.events.DisposeEvent)
+ */
+ @Override
+ protected void handleDispose(DisposeEvent event) {
+ fAdapterFactory.dispose();
+ super.handleDispose(event);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#getContents(boolean)
+ */
+ @Override
+ protected byte[] getContents(boolean left) {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EMFCompareContentMergeViewer#copyDiff(boolean)
+ */
+ @Override
+ protected void copyDiff(boolean leftToRight) {
+ final Diff diffToCopy = getDiffToCopy(getRightMergeViewer());
+ if (diffToCopy != null) {
+ Command copyCommand = getEditingDomain().createCopyCommand(diffToCopy, leftToRight,
+ EMFCompareIDEPlugin.getDefault().getMergerRegistry());
+ getEditingDomain().getCommandStack().execute(copyCommand);
+
+ refresh();
+ }
+ }
+
+ private Diff getDiffToCopy(MergeViewer mergeViewer) {
+ Diff diffToCopy = null;
+ ISelection selection = mergeViewer.getSelection();
+ if (selection instanceof IStructuredSelection && !selection.isEmpty()) {
+ Object firstElement = ((IStructuredSelection)selection).getFirstElement();
+ if (firstElement instanceof IMergeViewerItem) {
+ diffToCopy = ((IMergeViewerItem)firstElement).getDiff();
+ }
+ }
+ return diffToCopy;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EMFCompareContentMergeViewer#getLeftMergeViewer()
+ */
+ @Override
+ protected TableMergeViewer getLeftMergeViewer() {
+ return (TableMergeViewer)super.getLeftMergeViewer();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EMFCompareContentMergeViewer#getRightMergeViewer()
+ */
+ @Override
+ protected TableMergeViewer getRightMergeViewer() {
+ return (TableMergeViewer)super.getRightMergeViewer();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EMFCompareContentMergeViewer#getAncestorMergeViewer()
+ */
+ @Override
+ protected TableMergeViewer getAncestorMergeViewer() {
+ return (TableMergeViewer)super.getAncestorMergeViewer();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EMFCompareContentMergeViewer#createMergeViewer(org.eclipse.swt.widgets.Composite,
+ * org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.IMergeViewer.MergeViewerSide)
+ */
+ @Override
+ protected MergeViewer createMergeViewer(Composite parent, final MergeViewerSide side) {
+ TableMergeViewer ret = new TableMergeViewer(parent, side, this);
+ ret.getStructuredViewer().getTable().getVerticalBar().setVisible(false);
+
+ ret.setContentProvider(new ArrayContentProvider() {
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.ArrayContentProvider#getElements(java.lang.Object)
+ */
+ @Override
+ public Object[] getElements(Object inputElement) {
+ if (inputElement instanceof ICompareAccessor) {
+ return super.getElements(((ICompareAccessor)inputElement).getItems());
+ }
+ return super.getElements(inputElement);
+ }
+ });
+ ret.setLabelProvider(new AdapterFactoryLabelProvider.FontAndColorProvider(fAdapterFactory, ret
+ .getStructuredViewer()) {
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#getFont(java.lang.Object,
+ * int)
+ */
+ @Override
+ public Font getFont(Object object, int columnIndex) {
+ if (object instanceof MatchedObject) {
+ final Object value = ((MatchedObject)object).getSideValue(side);
+ if (value instanceof EObject && ((EObject)value).eIsProxy()) {
+ return getFontFromObject(IItemFontProvider.ITALIC_FONT);
+ }
+ }
+ return super.getFont(object, columnIndex);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#getColumnText(java.lang.Object,
+ * int)
+ */
+ @Override
+ public String getColumnText(Object object, int columnIndex) {
+ if (object instanceof MatchedObject) {
+ final String text;
+ final Object value = ((MatchedObject)object).getSideValue(side);
+ if (value instanceof EObject && ((EObject)value).eIsProxy()) {
+ text = "proxy : " + ((InternalEObject)value).eProxyURI().toString();
+ } else {
+ text = super.getColumnText(value, columnIndex);
+ }
+ return text;
+ }
+ return super.getColumnText(object, columnIndex);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#getColumnImage(java.lang.Object,
+ * int)
+ */
+ @Override
+ public Image getColumnImage(Object object, int columnIndex) {
+ if (object instanceof MatchedObject) {
+ return super.getColumnImage(((MatchedObject)object).getSideValue(side), columnIndex);
+ }
+ return super.getColumnImage(object, columnIndex);
+ }
+ });
+ ret.getStructuredViewer().getTable().getVerticalBar().addListener(SWT.Selection, new Listener() {
+ public void handleEvent(Event event) {
+ redrawCenterControl();
+ }
+ });
+
+ ret.getStructuredViewer().getTable().addMouseWheelListener(new MouseWheelListener() {
+ public void mouseScrolled(MouseEvent e) {
+ redrawCenterControl();
+ }
+ });
+ ret.addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ redrawCenterControl();
+ }
+ });
+ return ret;
+ }
+
+ protected void redrawCenterControl() {
+ getCenterControl().redraw();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EMFCompareContentMergeViewer#paintCenter(org.eclipse.swt.widgets.Canvas,
+ * org.eclipse.swt.graphics.GC)
+ */
+ @Override
+ protected void paintCenter(GC g) {
+ TableMergeViewer leftMergeViewer = getLeftMergeViewer();
+ TableMergeViewer rightMergeViewer = getRightMergeViewer();
+
+ Table leftTable = leftMergeViewer.getStructuredViewer().getTable();
+ Table rightTable = rightMergeViewer.getStructuredViewer().getTable();
+
+ Rectangle leftClientArea = leftTable.getClientArea();
+ Rectangle rightClientArea = rightTable.getClientArea();
+
+ TableItem[] leftItems = leftTable.getItems();
+ TableItem[] rightItems = rightTable.getItems();
+
+ TableItem[] selection = leftTable.getSelection();
+
+ for (TableItem leftItem : leftItems) {
+ final boolean selected;
+ if (selection.length > 0) {
+ selected = leftItem == selection[0];
+ } else {
+ selected = false;
+ }
+ final Diff leftDiff = ((IMergeViewerItem)leftItem.getData()).getDiff();
+
+ if (leftDiff != null && leftDiff.getState() == DifferenceState.UNRESOLVED) {
+ TableItem rightItem = findRightTableItemFromLeftDiff(rightItems, leftDiff);
+
+ if (rightItem != null) {
+ Color strokeColor = getCompareColor().getStrokeColor(leftDiff, isThreeWay(), false,
+ selected);
+ g.setForeground(strokeColor);
+ drawCenterLine(g, leftClientArea, rightClientArea, leftItem, rightItem);
+ }
+ }
+ }
+ }
+
+ private void drawCenterLine(GC g, Rectangle leftClientArea, Rectangle rightClientArea,
+ TableItem leftItem, TableItem rightItem) {
+ Control control = getCenterControl();
+ Point from = new Point(0, 0);
+ Point to = new Point(0, 0);
+
+ Rectangle leftBounds = leftItem.getBounds();
+ Rectangle rightBounds = rightItem.getBounds();
+
+ from.y = leftBounds.y + (leftBounds.height / 2) - leftClientArea.y + 1
+ + getLeftMergeViewer().getVerticalOffset();
+
+ to.x = control.getBounds().width;
+ to.y = rightBounds.y + (rightBounds.height / 2) - rightClientArea.y + 1
+ + getRightMergeViewer().getVerticalOffset();
+
+ int[] points = getCenterCurvePoints(from, to);
+ for (int i = 1; i < points.length; i++) {
+ g.drawLine(from.x + i - 1, points[i - 1], i, points[i]);
+ }
+ }
+
+ private TableItem findRightTableItemFromLeftDiff(TableItem[] rightItems, Diff leftDiff) {
+ TableItem ret = null;
+ for (int i = 0; i < rightItems.length && ret == null; i++) {
+ TableItem rightItem = rightItems[i];
+ final Diff rightDiff = ((IMergeViewerItem)rightItem.getData()).getDiff();
+ if (leftDiff == rightDiff) {
+ ret = rightItem;
+ }
+ }
+ return ret;
+ }
+
+ private int[] getCenterCurvePoints(Point from, Point to) {
+ int startx = from.x;
+ int starty = from.y;
+ int endx = to.x;
+ int endy = to.y;
+ if (fBasicCenterCurve == null) {
+ buildBaseCenterCurve(endx - startx);
+ }
+ double height = endy - starty;
+ height = height / 2;
+ int width = endx - startx;
+ int[] points = new int[width];
+ for (int i = 0; i < width; i++) {
+ points[i] = (int)(-height * fBasicCenterCurve[i] + height + starty);
+ }
+ return points;
+ }
+
+ private void buildBaseCenterCurve(int w) {
+ double width = w;
+ fBasicCenterCurve = new double[getCenterWidth()];
+ for (int i = 0; i < getCenterWidth(); i++) {
+ double r = i / width;
+ fBasicCenterCurve[i] = Math.cos(Math.PI * r);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/table/TableContentMergeViewerContentProvider.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/table/TableContentMergeViewerContentProvider.java
index e2346f2..26e71fc 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/table/TableContentMergeViewerContentProvider.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/table/TableContentMergeViewerContentProvider.java
@@ -1,207 +1,207 @@
-/*******************************************************************************
- * 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.contentmergeviewer.table;
-
-import static org.eclipse.emf.compare.ide.utils.ResourceUtil.saveAllResources;
-
-import com.google.common.collect.ImmutableMap;
-
-import org.eclipse.compare.CompareConfiguration;
-import org.eclipse.compare.ITypedElement;
-import org.eclipse.compare.contentmergeviewer.IMergeViewerContentProvider;
-import org.eclipse.compare.structuremergeviewer.ICompareInput;
-import org.eclipse.emf.common.util.EList;
-import org.eclipse.emf.compare.Comparison;
-import org.eclipse.emf.compare.Match;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.IStructuralFeatureAccessor;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.resource.Resource;
-import org.eclipse.emf.ecore.resource.ResourceSet;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.graphics.Image;
-
-/**
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- */
-public class TableContentMergeViewerContentProvider implements IMergeViewerContentProvider {
-
- public static final char ANCESTOR_CONTRIBUTOR = 'A';
-
- public static final char RIGHT_CONTRIBUTOR = 'R';
-
- public static final char LEFT_CONTRIBUTOR = 'L';
-
- private CompareConfiguration fCompareConfiguration;
-
- private String fAncestorError;
-
- private String fLeftError;
-
- private String fRightError;
-
- public TableContentMergeViewerContentProvider(CompareConfiguration cc) {
- fCompareConfiguration = cc;
- }
-
- public void dispose() {
- // empty default implementation
- }
-
- public void inputChanged(Viewer v, Object o1, Object o2) {
- // we are not interested since we have no state
- }
-
- // ---- ancestor
-
- public void setAncestorError(String errorMessage) {
- fAncestorError = errorMessage;
- }
-
- public String getAncestorLabel(Object element) {
- if (fAncestorError != null) {
- return fAncestorError;
- }
- return fCompareConfiguration.getAncestorLabel(element);
- }
-
- public Image getAncestorImage(Object element) {
- if (fAncestorError != null) {
- return null;
- }
- return fCompareConfiguration.getAncestorImage(element);
- }
-
- public Object getAncestorContent(Object element) {
- if (element instanceof ICompareInput) {
- return ((ICompareInput)element).getAncestor();
- }
- return null;
- }
-
- public boolean showAncestor(Object element) {
- if (element instanceof ICompareInput) {
- return true; // fix for #45239: Show ancestor for incoming and outgoing changes
- }
- // return (((ICompareInput)element).getKind() & Differencer.DIRECTION_MASK) ==
- // Differencer.CONFLICTING;
- return false;
- }
-
- // ---- left
-
- public void setLeftError(String errorMessage) {
- fLeftError = errorMessage;
- }
-
- public String getLeftLabel(Object element) {
- if (fLeftError != null) {
- return fLeftError;
- }
- return fCompareConfiguration.getLeftLabel(element);
- }
-
- public Image getLeftImage(Object element) {
- if (fLeftError != null) {
- return null;
- }
- return fCompareConfiguration.getLeftImage(element);
- }
-
- public Object getLeftContent(Object element) {
- if (element instanceof ICompareInput) {
- return ((ICompareInput)element).getLeft();
- }
- return null;
- }
-
- public boolean isLeftEditable(Object element) {
- return fCompareConfiguration.isLeftEditable();
- }
-
- public void saveLeftContent(Object element, byte[] bytes) {
- if (element instanceof ICompareInput) {
- ICompareInput node = (ICompareInput)element;
- ITypedElement left = node.getLeft();
- if (left instanceof IStructuralFeatureAccessor) {
- Comparison comparison = ((IStructuralFeatureAccessor)left).getComparison();
- EList<Match> matches = comparison.getMatches();
- EObject leftEObject = null;
- for (Match match : matches) {
- leftEObject = match.getLeft();
- if (leftEObject != null) {
- break;
- }
- }
- if (leftEObject != null) {
- Resource eResource = leftEObject.eResource();
- ResourceSet resourceSet = eResource.getResourceSet();
- saveAllResources(resourceSet, ImmutableMap.of(Resource.OPTION_SAVE_ONLY_IF_CHANGED,
- Resource.OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER));
- }
- }
- }
- }
-
- // ---- right
-
- public void setRightError(String errorMessage) {
- fRightError = errorMessage;
- }
-
- public String getRightLabel(Object element) {
- if (fRightError != null) {
- return fRightError;
- }
- return fCompareConfiguration.getRightLabel(element);
- }
-
- public Image getRightImage(Object element) {
- if (fRightError != null) {
- return null;
- }
- return fCompareConfiguration.getRightImage(element);
- }
-
- public Object getRightContent(Object element) {
- if (element instanceof ICompareInput) {
- return ((ICompareInput)element).getRight();
- }
- return null;
- }
-
- public boolean isRightEditable(Object element) {
- return fCompareConfiguration.isRightEditable();
- }
-
- public void saveRightContent(Object element, byte[] bytes) {
- if (element instanceof ICompareInput) {
- ICompareInput node = (ICompareInput)element;
- ITypedElement right = node.getRight();
- if (right instanceof IStructuralFeatureAccessor) {
- Comparison comparison = ((IStructuralFeatureAccessor)right).getComparison();
- EList<Match> matches = comparison.getMatches();
- EObject rightEObject = null;
- for (Match match : matches) {
- rightEObject = match.getRight();
- if (rightEObject != null) {
- break;
- }
- }
- if (rightEObject != null) {
- Resource eResource = rightEObject.eResource();
- ResourceSet resourceSet = eResource.getResourceSet();
- saveAllResources(resourceSet, ImmutableMap.of(Resource.OPTION_SAVE_ONLY_IF_CHANGED,
- Resource.OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER));
- }
- }
- }
- }
-}
+/*******************************************************************************
+ * 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.contentmergeviewer.table;
+
+import static org.eclipse.emf.compare.ide.utils.ResourceUtil.saveAllResources;
+
+import com.google.common.collect.ImmutableMap;
+
+import org.eclipse.compare.CompareConfiguration;
+import org.eclipse.compare.ITypedElement;
+import org.eclipse.compare.contentmergeviewer.IMergeViewerContentProvider;
+import org.eclipse.compare.structuremergeviewer.ICompareInput;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Match;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.ICompareAccessor;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public class TableContentMergeViewerContentProvider implements IMergeViewerContentProvider {
+
+ public static final char ANCESTOR_CONTRIBUTOR = 'A';
+
+ public static final char RIGHT_CONTRIBUTOR = 'R';
+
+ public static final char LEFT_CONTRIBUTOR = 'L';
+
+ private CompareConfiguration fCompareConfiguration;
+
+ private String fAncestorError;
+
+ private String fLeftError;
+
+ private String fRightError;
+
+ public TableContentMergeViewerContentProvider(CompareConfiguration cc) {
+ fCompareConfiguration = cc;
+ }
+
+ public void dispose() {
+ // empty default implementation
+ }
+
+ public void inputChanged(Viewer v, Object o1, Object o2) {
+ // we are not interested since we have no state
+ }
+
+ // ---- ancestor
+
+ public void setAncestorError(String errorMessage) {
+ fAncestorError = errorMessage;
+ }
+
+ public String getAncestorLabel(Object element) {
+ if (fAncestorError != null) {
+ return fAncestorError;
+ }
+ return fCompareConfiguration.getAncestorLabel(element);
+ }
+
+ public Image getAncestorImage(Object element) {
+ if (fAncestorError != null) {
+ return null;
+ }
+ return fCompareConfiguration.getAncestorImage(element);
+ }
+
+ public Object getAncestorContent(Object element) {
+ if (element instanceof ICompareInput) {
+ return ((ICompareInput)element).getAncestor();
+ }
+ return null;
+ }
+
+ public boolean showAncestor(Object element) {
+ if (element instanceof ICompareInput) {
+ return true; // fix for #45239: Show ancestor for incoming and outgoing changes
+ }
+ // return (((ICompareInput)element).getKind() & Differencer.DIRECTION_MASK) ==
+ // Differencer.CONFLICTING;
+ return false;
+ }
+
+ // ---- left
+
+ public void setLeftError(String errorMessage) {
+ fLeftError = errorMessage;
+ }
+
+ public String getLeftLabel(Object element) {
+ if (fLeftError != null) {
+ return fLeftError;
+ }
+ return fCompareConfiguration.getLeftLabel(element);
+ }
+
+ public Image getLeftImage(Object element) {
+ if (fLeftError != null) {
+ return null;
+ }
+ return fCompareConfiguration.getLeftImage(element);
+ }
+
+ public Object getLeftContent(Object element) {
+ if (element instanceof ICompareInput) {
+ return ((ICompareInput)element).getLeft();
+ }
+ return null;
+ }
+
+ public boolean isLeftEditable(Object element) {
+ return fCompareConfiguration.isLeftEditable();
+ }
+
+ public void saveLeftContent(Object element, byte[] bytes) {
+ if (element instanceof ICompareInput) {
+ ICompareInput node = (ICompareInput)element;
+ ITypedElement left = node.getLeft();
+ if (left instanceof ICompareAccessor) {
+ Comparison comparison = ((ICompareAccessor)left).getComparison();
+ EList<Match> matches = comparison.getMatches();
+ EObject leftEObject = null;
+ for (Match match : matches) {
+ leftEObject = match.getLeft();
+ if (leftEObject != null) {
+ break;
+ }
+ }
+ if (leftEObject != null) {
+ Resource eResource = leftEObject.eResource();
+ ResourceSet resourceSet = eResource.getResourceSet();
+ saveAllResources(resourceSet, ImmutableMap.of(Resource.OPTION_SAVE_ONLY_IF_CHANGED,
+ Resource.OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER));
+ }
+ }
+ }
+ }
+
+ // ---- right
+
+ public void setRightError(String errorMessage) {
+ fRightError = errorMessage;
+ }
+
+ public String getRightLabel(Object element) {
+ if (fRightError != null) {
+ return fRightError;
+ }
+ return fCompareConfiguration.getRightLabel(element);
+ }
+
+ public Image getRightImage(Object element) {
+ if (fRightError != null) {
+ return null;
+ }
+ return fCompareConfiguration.getRightImage(element);
+ }
+
+ public Object getRightContent(Object element) {
+ if (element instanceof ICompareInput) {
+ return ((ICompareInput)element).getRight();
+ }
+ return null;
+ }
+
+ public boolean isRightEditable(Object element) {
+ return fCompareConfiguration.isRightEditable();
+ }
+
+ public void saveRightContent(Object element, byte[] bytes) {
+ if (element instanceof ICompareInput) {
+ ICompareInput node = (ICompareInput)element;
+ ITypedElement right = node.getRight();
+ if (right instanceof ICompareAccessor) {
+ Comparison comparison = ((ICompareAccessor)right).getComparison();
+ EList<Match> matches = comparison.getMatches();
+ EObject rightEObject = null;
+ for (Match match : matches) {
+ rightEObject = match.getRight();
+ if (rightEObject != null) {
+ break;
+ }
+ }
+ if (rightEObject != null) {
+ Resource eResource = rightEObject.eResource();
+ ResourceSet resourceSet = eResource.getResourceSet();
+ saveAllResources(resourceSet, ImmutableMap.of(Resource.OPTION_SAVE_ONLY_IF_CHANGED,
+ Resource.OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER));
+ }
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/MergeViewerInfoViewer.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/MergeViewerInfoViewer.java
index 1881166..ebd4bfb 100644
--- a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/MergeViewerInfoViewer.java
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/MergeViewerInfoViewer.java
@@ -1,176 +1,192 @@
-/*******************************************************************************
- * 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;
-
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.IStructuralFeatureAccessor;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EStructuralFeature;
-import org.eclipse.jface.viewers.ContentViewer;
-import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-
-/**
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- */
-public class MergeViewerInfoViewer extends ContentViewer {
-
- private final MergeViewerSide fSide;
-
- private final Composite fControl;
-
- private final Label fEObjectIcon;
-
- private final Label fEObjectLabel;
-
- private final Label fFeatureIcon;
-
- private final Label fFeatureLabel;
-
- private ISelection fSelection;
-
- private Object fInput;
-
- /**
- *
- */
- public MergeViewerInfoViewer(Composite parent, MergeViewerSide side) {
- this.fControl = new Composite(parent, SWT.BORDER);
- this.fSide = side;
-
- fControl.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
- GridLayout layout = new GridLayout(3, false);
- layout.verticalSpacing = 0;
- layout.horizontalSpacing = 0;
- layout.marginLeft = 1;
- layout.marginHeight = 0;
- layout.marginWidth = 0;
- layout.marginBottom = 0;
- fControl.setLayout(layout);
-
- Composite eObjectComposite = new Composite(fControl, SWT.NONE);
- GridLayout eObjectCompositelayout = new GridLayout(2, false);
- eObjectCompositelayout.verticalSpacing = 0;
- eObjectCompositelayout.horizontalSpacing = 0;
- eObjectCompositelayout.marginLeft = 0;
- eObjectCompositelayout.marginHeight = 0;
- eObjectCompositelayout.marginWidth = 0;
- eObjectCompositelayout.marginBottom = 0;
- eObjectComposite.setLayout(eObjectCompositelayout);
- fEObjectIcon = new Label(eObjectComposite, SWT.NONE);
- fEObjectIcon.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1));
- fEObjectLabel = new Label(eObjectComposite, SWT.NONE);
- fEObjectLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
- eObjectComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, true, 3, 1));
-
- Label lblIn = new Label(fControl, SWT.NONE);
- lblIn.setText(" "); //$NON-NLS-1$
-
- fFeatureIcon = new Label(fControl, SWT.NONE);
- fFeatureIcon.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1));
- fFeatureLabel = new Label(fControl, SWT.NONE);
- fFeatureLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
-
- hookControl(fControl);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.Viewer#getControl()
- */
- @Override
- public Control getControl() {
- return fControl;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.Viewer#inputChanged(java.lang.Object, java.lang.Object)
- */
- @Override
- protected void inputChanged(Object input, Object oldInput) {
- fInput = input;
- fControl.setRedraw(false);
- try {
- refresh();
- } finally {
- fControl.setRedraw(true);
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.Viewer#getSelection()
- */
- @Override
- public ISelection getSelection() {
- return fSelection;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.Viewer#refresh()
- */
- @Override
- public void refresh() {
- if (fInput instanceof IStructuralFeatureAccessor) {
- IStructuralFeatureAccessor featureAccessor = (IStructuralFeatureAccessor)fInput;
-
- EObject eObject = featureAccessor.getEObject(fSide);
- if (eObject == null) {
- if (fSide != MergeViewerSide.ANCESTOR) {
- eObject = featureAccessor.getEObject(MergeViewerSide.ANCESTOR);
- if (eObject == null) {
- eObject = featureAccessor.getEObject(fSide.opposite());
- }
- } else {
- eObject = featureAccessor.getEObject(MergeViewerSide.LEFT);
- if (eObject == null) {
- eObject = featureAccessor.getEObject(MergeViewerSide.RIGHT);
- }
- }
- }
- EStructuralFeature structuralFeature = featureAccessor.getStructuralFeature();
-
- if (getLabelProvider() instanceof ILabelProvider) {
- ILabelProvider labelProvider = (ILabelProvider)getLabelProvider();
- fFeatureIcon.setImage(labelProvider.getImage(structuralFeature));
- fFeatureLabel.setText(labelProvider.getText(structuralFeature));
-
- fEObjectIcon.setImage(labelProvider.getImage(eObject));
- fEObjectLabel.setText(labelProvider.getText(eObject));
- }
-
- fControl.layout(true);
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.Viewer#setSelection(org.eclipse.jface.viewers.ISelection, boolean)
- */
- @Override
- public void setSelection(ISelection selection, boolean reveal) {
- fSelection = selection;
- }
-
-}
+/*******************************************************************************
+ * 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.mergeviewer;
+
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.IStructuralFeatureAccessor;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.ResourceContentsAccessorImpl;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.jface.viewers.ContentViewer;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+
+/**
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public class MergeViewerInfoViewer extends ContentViewer {
+
+ private final MergeViewerSide fSide;
+
+ private final Composite fControl;
+
+ private final Label fEObjectIcon;
+
+ private final Label fEObjectLabel;
+
+ private final Label fFeatureIcon;
+
+ private final Label fFeatureLabel;
+
+ private ISelection fSelection;
+
+ private Object fInput;
+
+ /**
+ *
+ */
+ public MergeViewerInfoViewer(Composite parent, MergeViewerSide side) {
+ this.fControl = new Composite(parent, SWT.BORDER);
+ this.fSide = side;
+
+ fControl.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
+ GridLayout layout = new GridLayout(3, false);
+ layout.verticalSpacing = 0;
+ layout.horizontalSpacing = 0;
+ layout.marginLeft = 1;
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ layout.marginBottom = 0;
+ fControl.setLayout(layout);
+
+ Composite eObjectComposite = new Composite(fControl, SWT.NONE);
+ GridLayout eObjectCompositelayout = new GridLayout(2, false);
+ eObjectCompositelayout.verticalSpacing = 0;
+ eObjectCompositelayout.horizontalSpacing = 0;
+ eObjectCompositelayout.marginLeft = 0;
+ eObjectCompositelayout.marginHeight = 0;
+ eObjectCompositelayout.marginWidth = 0;
+ eObjectCompositelayout.marginBottom = 0;
+ eObjectComposite.setLayout(eObjectCompositelayout);
+ fEObjectIcon = new Label(eObjectComposite, SWT.NONE);
+ fEObjectIcon.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1));
+ fEObjectLabel = new Label(eObjectComposite, SWT.NONE);
+ fEObjectLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+ eObjectComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, true, 3, 1));
+
+ Label lblIn = new Label(fControl, SWT.NONE);
+ lblIn.setText(" "); //$NON-NLS-1$
+
+ fFeatureIcon = new Label(fControl, SWT.NONE);
+ fFeatureIcon.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1));
+ fFeatureLabel = new Label(fControl, SWT.NONE);
+ fFeatureLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
+
+ hookControl(fControl);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.Viewer#getControl()
+ */
+ @Override
+ public Control getControl() {
+ return fControl;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.Viewer#inputChanged(java.lang.Object, java.lang.Object)
+ */
+ @Override
+ protected void inputChanged(Object input, Object oldInput) {
+ fInput = input;
+ fControl.setRedraw(false);
+ try {
+ refresh();
+ } finally {
+ fControl.setRedraw(true);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.Viewer#getSelection()
+ */
+ @Override
+ public ISelection getSelection() {
+ return fSelection;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.Viewer#refresh()
+ */
+ @Override
+ public void refresh() {
+ if (fInput instanceof IStructuralFeatureAccessor) {
+ IStructuralFeatureAccessor featureAccessor = (IStructuralFeatureAccessor)fInput;
+
+ EObject eObject = featureAccessor.getEObject(fSide);
+ if (eObject == null) {
+ if (fSide != MergeViewerSide.ANCESTOR) {
+ eObject = featureAccessor.getEObject(MergeViewerSide.ANCESTOR);
+ if (eObject == null) {
+ eObject = featureAccessor.getEObject(fSide.opposite());
+ }
+ } else {
+ eObject = featureAccessor.getEObject(MergeViewerSide.LEFT);
+ if (eObject == null) {
+ eObject = featureAccessor.getEObject(MergeViewerSide.RIGHT);
+ }
+ }
+ }
+ EStructuralFeature structuralFeature = featureAccessor.getStructuralFeature();
+
+ if (getLabelProvider() instanceof ILabelProvider) {
+ ILabelProvider labelProvider = (ILabelProvider)getLabelProvider();
+
+ fFeatureIcon.setImage(labelProvider.getImage(structuralFeature));
+ fFeatureLabel.setText(labelProvider.getText(structuralFeature));
+
+ fEObjectIcon.setImage(labelProvider.getImage(eObject));
+ fEObjectLabel.setText(labelProvider.getText(eObject));
+ }
+
+ fControl.layout(true);
+ } else if (fInput instanceof ResourceContentsAccessorImpl) {
+ final ResourceContentsAccessorImpl resourceContentAccessor = (ResourceContentsAccessorImpl)fInput;
+ final Resource resource = resourceContentAccessor.getResource(fSide);
+
+ if (getLabelProvider() instanceof ILabelProvider) {
+ ILabelProvider labelProvider = (ILabelProvider)getLabelProvider();
+ fFeatureLabel.setText("resource contents"); //$NON-NLS-1$
+
+ fEObjectIcon.setImage(labelProvider.getImage(resource));
+ fEObjectLabel.setText(labelProvider.getText(resource));
+ }
+
+ fControl.layout(true);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.Viewer#setSelection(org.eclipse.jface.viewers.ISelection, boolean)
+ */
+ @Override
+ public void setSelection(ISelection selection, boolean reveal) {
+ fSelection = selection;
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/TableMergeViewer.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/TableMergeViewer.java
index 3cff358..0b3cdaa 100644
--- a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/TableMergeViewer.java
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/TableMergeViewer.java
@@ -1,310 +1,310 @@
-/*******************************************************************************
- * 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;
-
-import org.eclipse.emf.compare.Comparison;
-import org.eclipse.emf.compare.Diff;
-import org.eclipse.emf.compare.DifferenceState;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.IStructuralFeatureAccessor;
-import org.eclipse.jface.viewers.IBaseLabelProvider;
-import org.eclipse.jface.viewers.IContentProvider;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.graphics.Region;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableItem;
-import org.eclipse.swt.widgets.Widget;
-
-/**
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- */
-public class TableMergeViewer extends StructuredMergeViewer {
-
- private final ICompareColorProvider fColorProvider;
-
- private TableViewer fTableViewer;
-
- private MergeViewerInfoViewer fInfoViewer;
-
- public TableMergeViewer(Composite parent, MergeViewerSide side, ICompareColorProvider colorProvider) {
- super(parent, side);
- fColorProvider = colorProvider;
-
- getStructuredViewer().getTable().addListener(SWT.EraseItem, new Listener() {
- public void handleEvent(Event event) {
- TableMergeViewer.this.handleEraseItemEvent(event);
- }
- });
-
- getStructuredViewer().getTable().addListener(SWT.MeasureItem, new ItemResizeListener());
-
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.MergeViewer#createControl(org.eclipse.swt.widgets.Composite)
- */
- @Override
- protected Control createControl(Composite parent) {
- Composite composite = new Composite(parent, SWT.NONE);
- GridLayout layout = new GridLayout(1, false);
- layout.marginLeft = -1;
- layout.marginRight = -1;
- layout.marginTop = -1;
- layout.marginBottom = 0;
- layout.horizontalSpacing = 0;
- layout.verticalSpacing = 0;
- layout.marginWidth = 0;
- layout.marginHeight = 0;
- composite.setLayout(layout);
-
- fInfoViewer = new MergeViewerInfoViewer(composite, getSide());
- fInfoViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1));
-
- fTableViewer = new TableViewer(composite, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL
- | SWT.FULL_SELECTION);
- fTableViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
-
- return composite;
- }
-
- public final int getVerticalOffset() {
- return fInfoViewer.getControl().getSize().y - 2;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.MergeViewer.ui.internal.contentmergeviewer.AbstractMergeViewer#getStructuredViewer()
- */
- @Override
- public final TableViewer getStructuredViewer() {
- return fTableViewer;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.MergeViewer#setContentProvider(org.eclipse.jface.viewers.IContentProvider)
- */
- @Override
- public void setContentProvider(IContentProvider contentProvider) {
- super.setContentProvider(contentProvider);
- fInfoViewer.setContentProvider(contentProvider);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.MergeViewer#setLabelProvider(org.eclipse.jface.viewers.IBaseLabelProvider)
- */
- @Override
- public void setLabelProvider(IBaseLabelProvider labelProvider) {
- super.setLabelProvider(labelProvider);
- fInfoViewer.setLabelProvider(labelProvider);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.Viewer#inputChanged(java.lang.Object, java.lang.Object)
- */
- @Override
- protected void inputChanged(Object input, Object oldInput) {
- fTableViewer.setInput(input);
- fInfoViewer.setInput(input);
- ((Composite)getControl()).layout(true);
- }
-
- private void handleEraseItemEvent(Event event) {
- TableItem tableItem = (TableItem)event.item;
- Object data = tableItem.getData();
-
- if (data instanceof InsertionPoint) {
- InsertionPoint insertionPoint = (InsertionPoint)data;
- paintItemDiffBox(event, insertionPoint.getDiff(), getBoundsForInsertionPoint(event));
- } else if (data instanceof IMergeViewerItem) {
- Diff diff = ((IMergeViewerItem)data).getDiff();
- if (diff != null) {
- paintItemDiffBox(event, diff, getBounds(event));
- }
- }
- }
-
- private void paintItemDiffBox(Event event, Diff diff, Rectangle bounds) {
- event.detail &= ~SWT.HOT;
-
- if (diff.getState() == DifferenceState.DISCARDED || diff.getState() == DifferenceState.MERGED) {
- return;
- }
-
- GC g = event.gc;
- Color oldBackground = g.getBackground();
- Color oldForeground = g.getForeground();
-
- setDiffColorsToGC(g, diff, isSelected(event));
- g.fillRectangle(bounds);
- g.drawRectangle(bounds);
-
- if (getSide() == MergeViewerSide.LEFT) {
- drawLineFromBoxToCenter(event, bounds, g);
- } else {
- drawLineFromCenterToBox(event, bounds, g);
- }
-
- if (isSelected(event)) {
- g.setForeground(event.display.getSystemColor(SWT.COLOR_LIST_FOREGROUND));
- g.setBackground(event.display.getSystemColor(SWT.COLOR_LIST_BACKGROUND));
- event.detail &= ~SWT.SELECTED;
- } else {
- g.setBackground(oldBackground);
- g.setForeground(oldForeground);
- }
- }
-
- private void drawLineFromCenterToBox(Event event, Rectangle boxBounds, GC g) {
- TableItem tableItem = (TableItem)event.item;
- Rectangle itemBounds = tableItem.getBounds();
- Point from = new Point(0, 0);
- from.y = itemBounds.y + (itemBounds.height / 2);
- Point to = new Point(boxBounds.x, from.y);
- g.drawLine(from.x, from.y, to.x, to.y);
- }
-
- private void drawLineFromBoxToCenter(Event event, Rectangle boxBounds, GC g) {
- TableItem tableItem = (TableItem)event.item;
- Rectangle itemBounds = tableItem.getBounds();
- Rectangle clientArea = tableItem.getParent().getClientArea();
- Point from = new Point(0, 0);
- from.x = boxBounds.x + boxBounds.width;
- from.y = itemBounds.y + (itemBounds.height / 2);
- Point to = new Point(0, from.y);
- to.x = clientArea.x + clientArea.width;
- g.drawLine(from.x, from.y, to.x, to.y);
- }
-
- static boolean isSelected(Event event) {
- return (event.detail & SWT.SELECTED) != 0;
- }
-
- private static Rectangle getBounds(Event event) {
- TableItem tableItem = (TableItem)event.item;
- Table table = tableItem.getParent();
- Rectangle tableBounds = table.getClientArea();
- Rectangle itemBounds = tableItem.getBounds();
-
- Rectangle fill = new Rectangle(0, 0, 0, 0);
- fill.x = 2;
- fill.y = itemBounds.y + 2;
- // +x to add the icon and the expand "+" if we are in a tree
- fill.width = itemBounds.width + itemBounds.x;
- fill.height = itemBounds.height - 3;
-
- final GC g = event.gc;
- // If you wish to paint the selection beyond the end of last column, you must change the clipping
- // region.
- int columnCount = table.getColumnCount();
- if (event.index == columnCount - 1 || columnCount == 0) {
- int width = tableBounds.x + tableBounds.width - event.x;
- if (width > 0) {
- Region region = new Region();
- g.getClipping(region);
- region.add(event.x, event.y, width, event.height);
- g.setClipping(region);
- region.dispose();
- }
- }
- g.setAdvanced(true);
-
- return fill;
- }
-
- private static Rectangle getBoundsForInsertionPoint(Event event) {
- Rectangle fill = getBounds(event);
- TableItem tableItem = (TableItem)event.item;
- Rectangle tableBounds = tableItem.getParent().getClientArea();
- fill.y = fill.y + 6;
- fill.width = tableBounds.width / 4;
- fill.height = fill.height - 12;
-
- return fill;
- }
-
- private void setDiffColorsToGC(GC g, Diff diff, boolean selected) {
- boolean isThreeWay = false;
- if (getInput() instanceof IStructuralFeatureAccessor) {
- Comparison comparison = ((IStructuralFeatureAccessor)getInput()).getComparison();
- isThreeWay = comparison.isThreeWay();
- }
- g.setForeground(fColorProvider.getCompareColor().getStrokeColor(diff, isThreeWay, false, selected));
- g.setBackground(fColorProvider.getCompareColor().getFillColor(diff, isThreeWay, false, selected));
- }
-
- /**
- * This will be used in order to resize the table items to an even height. Otherwise the lines we draw
- * around it look somewhat flattened.
- *
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- */
- private static class ItemResizeListener implements Listener {
- /** The last item we resized. Will be used to workaround a windows-specific bug. */
- private Widget fLastWidget;
-
- /**
- * The height to which we've resized the last item. Will be used to workaround a windows-specific bug.
- */
- private int fLastHeight;
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
- */
- public void handleEvent(Event event) {
- // Windows bug: prevents StackOverflow
- if (event.item == fLastWidget && event.height == fLastHeight) {
- return;
- }
-
- fLastWidget = event.item;
- fLastHeight = event.height;
- int newHeight = (int)(event.gc.getFontMetrics().getHeight() * 1.33d);
- // If odd, make even
- if ((newHeight & 1) == 1) {
- newHeight += 1;
- }
- event.height = newHeight;
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.Viewer#refresh()
- */
- @Override
- public void refresh() {
- fInfoViewer.refresh();
- fTableViewer.refresh();
- }
-
-}
+/*******************************************************************************
+ * 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.mergeviewer;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.DifferenceState;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.ICompareAccessor;
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.IContentProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.graphics.Region;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.widgets.Widget;
+
+/**
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public class TableMergeViewer extends StructuredMergeViewer {
+
+ private final ICompareColorProvider fColorProvider;
+
+ private TableViewer fTableViewer;
+
+ private MergeViewerInfoViewer fInfoViewer;
+
+ public TableMergeViewer(Composite parent, MergeViewerSide side, ICompareColorProvider colorProvider) {
+ super(parent, side);
+ fColorProvider = colorProvider;
+
+ getStructuredViewer().getTable().addListener(SWT.EraseItem, new Listener() {
+ public void handleEvent(Event event) {
+ TableMergeViewer.this.handleEraseItemEvent(event);
+ }
+ });
+
+ getStructuredViewer().getTable().addListener(SWT.MeasureItem, new ItemResizeListener());
+
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.MergeViewer#createControl(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ protected Control createControl(Composite parent) {
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(1, false);
+ layout.marginLeft = -1;
+ layout.marginRight = -1;
+ layout.marginTop = -1;
+ layout.marginBottom = 0;
+ layout.horizontalSpacing = 0;
+ layout.verticalSpacing = 0;
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ composite.setLayout(layout);
+
+ fInfoViewer = new MergeViewerInfoViewer(composite, getSide());
+ fInfoViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1));
+
+ fTableViewer = new TableViewer(composite, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL
+ | SWT.FULL_SELECTION);
+ fTableViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
+
+ return composite;
+ }
+
+ public final int getVerticalOffset() {
+ return fInfoViewer.getControl().getSize().y - 2;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.MergeViewer.ui.internal.contentmergeviewer.AbstractMergeViewer#getStructuredViewer()
+ */
+ @Override
+ public final TableViewer getStructuredViewer() {
+ return fTableViewer;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.MergeViewer#setContentProvider(org.eclipse.jface.viewers.IContentProvider)
+ */
+ @Override
+ public void setContentProvider(IContentProvider contentProvider) {
+ super.setContentProvider(contentProvider);
+ fInfoViewer.setContentProvider(contentProvider);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.MergeViewer#setLabelProvider(org.eclipse.jface.viewers.IBaseLabelProvider)
+ */
+ @Override
+ public void setLabelProvider(IBaseLabelProvider labelProvider) {
+ super.setLabelProvider(labelProvider);
+ fInfoViewer.setLabelProvider(labelProvider);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.Viewer#inputChanged(java.lang.Object, java.lang.Object)
+ */
+ @Override
+ protected void inputChanged(Object input, Object oldInput) {
+ fTableViewer.setInput(input);
+ fInfoViewer.setInput(input);
+ ((Composite)getControl()).layout(true);
+ }
+
+ private void handleEraseItemEvent(Event event) {
+ TableItem tableItem = (TableItem)event.item;
+ Object data = tableItem.getData();
+
+ if (data instanceof InsertionPoint) {
+ InsertionPoint insertionPoint = (InsertionPoint)data;
+ paintItemDiffBox(event, insertionPoint.getDiff(), getBoundsForInsertionPoint(event));
+ } else if (data instanceof IMergeViewerItem) {
+ Diff diff = ((IMergeViewerItem)data).getDiff();
+ if (diff != null) {
+ paintItemDiffBox(event, diff, getBounds(event));
+ }
+ }
+ }
+
+ private void paintItemDiffBox(Event event, Diff diff, Rectangle bounds) {
+ event.detail &= ~SWT.HOT;
+
+ if (diff.getState() == DifferenceState.DISCARDED || diff.getState() == DifferenceState.MERGED) {
+ return;
+ }
+
+ GC g = event.gc;
+ Color oldBackground = g.getBackground();
+ Color oldForeground = g.getForeground();
+
+ setDiffColorsToGC(g, diff, isSelected(event));
+ g.fillRectangle(bounds);
+ g.drawRectangle(bounds);
+
+ if (getSide() == MergeViewerSide.LEFT) {
+ drawLineFromBoxToCenter(event, bounds, g);
+ } else {
+ drawLineFromCenterToBox(event, bounds, g);
+ }
+
+ if (isSelected(event)) {
+ g.setForeground(event.display.getSystemColor(SWT.COLOR_LIST_FOREGROUND));
+ g.setBackground(event.display.getSystemColor(SWT.COLOR_LIST_BACKGROUND));
+ event.detail &= ~SWT.SELECTED;
+ } else {
+ g.setBackground(oldBackground);
+ g.setForeground(oldForeground);
+ }
+ }
+
+ private void drawLineFromCenterToBox(Event event, Rectangle boxBounds, GC g) {
+ TableItem tableItem = (TableItem)event.item;
+ Rectangle itemBounds = tableItem.getBounds();
+ Point from = new Point(0, 0);
+ from.y = itemBounds.y + (itemBounds.height / 2);
+ Point to = new Point(boxBounds.x, from.y);
+ g.drawLine(from.x, from.y, to.x, to.y);
+ }
+
+ private void drawLineFromBoxToCenter(Event event, Rectangle boxBounds, GC g) {
+ TableItem tableItem = (TableItem)event.item;
+ Rectangle itemBounds = tableItem.getBounds();
+ Rectangle clientArea = tableItem.getParent().getClientArea();
+ Point from = new Point(0, 0);
+ from.x = boxBounds.x + boxBounds.width;
+ from.y = itemBounds.y + (itemBounds.height / 2);
+ Point to = new Point(0, from.y);
+ to.x = clientArea.x + clientArea.width;
+ g.drawLine(from.x, from.y, to.x, to.y);
+ }
+
+ static boolean isSelected(Event event) {
+ return (event.detail & SWT.SELECTED) != 0;
+ }
+
+ private static Rectangle getBounds(Event event) {
+ TableItem tableItem = (TableItem)event.item;
+ Table table = tableItem.getParent();
+ Rectangle tableBounds = table.getClientArea();
+ Rectangle itemBounds = tableItem.getBounds();
+
+ Rectangle fill = new Rectangle(0, 0, 0, 0);
+ fill.x = 2;
+ fill.y = itemBounds.y + 2;
+ // +x to add the icon and the expand "+" if we are in a tree
+ fill.width = itemBounds.width + itemBounds.x;
+ fill.height = itemBounds.height - 3;
+
+ final GC g = event.gc;
+ // If you wish to paint the selection beyond the end of last column, you must change the clipping
+ // region.
+ int columnCount = table.getColumnCount();
+ if (event.index == columnCount - 1 || columnCount == 0) {
+ int width = tableBounds.x + tableBounds.width - event.x;
+ if (width > 0) {
+ Region region = new Region();
+ g.getClipping(region);
+ region.add(event.x, event.y, width, event.height);
+ g.setClipping(region);
+ region.dispose();
+ }
+ }
+ g.setAdvanced(true);
+
+ return fill;
+ }
+
+ private static Rectangle getBoundsForInsertionPoint(Event event) {
+ Rectangle fill = getBounds(event);
+ TableItem tableItem = (TableItem)event.item;
+ Rectangle tableBounds = tableItem.getParent().getClientArea();
+ fill.y = fill.y + 6;
+ fill.width = tableBounds.width / 4;
+ fill.height = fill.height - 12;
+
+ return fill;
+ }
+
+ private void setDiffColorsToGC(GC g, Diff diff, boolean selected) {
+ boolean isThreeWay = false;
+ if (getInput() instanceof ICompareAccessor) {
+ Comparison comparison = ((ICompareAccessor)getInput()).getComparison();
+ isThreeWay = comparison.isThreeWay();
+ }
+ g.setForeground(fColorProvider.getCompareColor().getStrokeColor(diff, isThreeWay, false, selected));
+ g.setBackground(fColorProvider.getCompareColor().getFillColor(diff, isThreeWay, false, selected));
+ }
+
+ /**
+ * This will be used in order to resize the table items to an even height. Otherwise the lines we draw
+ * around it look somewhat flattened.
+ *
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+ private static class ItemResizeListener implements Listener {
+ /** The last item we resized. Will be used to workaround a windows-specific bug. */
+ private Widget fLastWidget;
+
+ /**
+ * The height to which we've resized the last item. Will be used to workaround a windows-specific bug.
+ */
+ private int fLastHeight;
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
+ */
+ public void handleEvent(Event event) {
+ // Windows bug: prevents StackOverflow
+ if (event.item == fLastWidget && event.height == fLastHeight) {
+ return;
+ }
+
+ fLastWidget = event.item;
+ fLastHeight = event.height;
+ int newHeight = (int)(event.gc.getFontMetrics().getHeight() * 1.33d);
+ // If odd, make even
+ if ((newHeight & 1) == 1) {
+ newHeight += 1;
+ }
+ event.height = newHeight;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.Viewer#refresh()
+ */
+ @Override
+ public void refresh() {
+ fInfoViewer.refresh();
+ fTableViewer.refresh();
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/BasicResourceContentsAccessorImpl.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/BasicResourceContentsAccessorImpl.java
new file mode 100644
index 0000000..1201c2d
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/BasicResourceContentsAccessorImpl.java
@@ -0,0 +1,186 @@
+/*******************************************************************************
+ * 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.mergeviewer.accessor;
+
+import static com.google.common.base.Predicates.and;
+import static com.google.common.base.Predicates.instanceOf;
+import static com.google.common.base.Predicates.not;
+import static com.google.common.collect.Iterables.concat;
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.transform;
+import static org.eclipse.emf.compare.utils.EMFComparePredicates.hasConflict;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+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.Match;
+import org.eclipse.emf.compare.MatchResource;
+import org.eclipse.emf.compare.ResourceAttachmentChange;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewerItem;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+
+/**
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ */
+public abstract class BasicResourceContentsAccessorImpl implements IResourceContentsAccessor {
+
+ /** The difference performed. */
+ private final Diff fDiff;
+
+ /** The side on which the difference is located. */
+ private final MergeViewerSide fSide;
+
+ /** The match associated to the performed difference. */
+ private final Match fOwnerMatch;
+
+ /** The list of sibling differences of the performed difference. */
+ private final ImmutableList<Diff> fDifferences;
+
+ /**
+ * @param diff
+ * The difference performed.
+ * @param side
+ * The side on which the difference is located.
+ */
+ public BasicResourceContentsAccessorImpl(Diff diff, MergeViewerSide side) {
+ fDiff = diff;
+ fSide = side;
+ fOwnerMatch = diff.getMatch();
+ fDifferences = computeDifferences();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.IResourceContentsAccessor#getComparison()
+ */
+ public Comparison getComparison() {
+ return fOwnerMatch.getComparison();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.IResourceContentsAccessor#getInitialItem()
+ */
+ public IMergeViewerItem getInitialItem() {
+ IMergeViewerItem ret = null;
+ ImmutableList<? extends IMergeViewerItem> items = getItems();
+ for (IMergeViewerItem item : items) {
+ Diff diff = item.getDiff();
+ if (diff == fDiff) {
+ ret = item;
+ }
+ }
+ return ret;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.IResourceContentsAccessor#getResource(org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide)
+ */
+ public Resource getResource(MergeViewerSide side) {
+ Resource resource = null;
+ Collection<MatchResource> matchResources = fOwnerMatch.getComparison().getMatchedResources();
+ Iterator<MatchResource> it = matchResources.iterator();
+ if (it.hasNext()) {
+ MatchResource matchResource = it.next();
+ switch (side) {
+ case ANCESTOR:
+ resource = matchResource.getOrigin();
+ break;
+ case LEFT:
+ resource = matchResource.getLeft();
+ break;
+ case RIGHT:
+ resource = matchResource.getRight();
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ }
+ return resource;
+ }
+
+ /**
+ * Returns the contents of the current resource on the given side.
+ *
+ * @param side
+ * The given side.
+ * @return The contents of the current resource on the given side.
+ */
+ public List<EObject> getResourceContents(MergeViewerSide side) {
+ Resource resource = getResource(side);
+ if (resource != null) {
+ return resource.getContents();
+ }
+ return Collections.emptyList();
+
+ }
+
+ /**
+ * Returns the side of the content merge viewer on which the difference is performed.
+ *
+ * @return The side of the content merge viewer on which the difference is performed.
+ */
+ protected final MergeViewerSide getSide() {
+ return fSide;
+ }
+
+ /**
+ * Returns the list of sibling differences of the current difference.
+ *
+ * @return The list of sibling differences of the current difference.
+ */
+ protected final ImmutableList<Diff> getDifferences() {
+ return fDifferences;
+ }
+
+ /**
+ * Computes the list of sibling differences of the current difference.
+ *
+ * @return The list of sibling differences of the current difference.
+ */
+ protected ImmutableList<Diff> computeDifferences() {
+ Iterable<EObject> concat = Iterables.concat(getResourceContents(MergeViewerSide.LEFT),
+ getResourceContents(MergeViewerSide.RIGHT), getResourceContents(MergeViewerSide.ANCESTOR));
+
+ final Comparison comparison = fOwnerMatch.getComparison();
+ Iterable<Match> matches = transform(concat, new Function<EObject, Match>() {
+ public Match apply(EObject eObject) {
+ return comparison.getMatch(eObject);
+ }
+ });
+ Iterable<Diff> siblingDifferences = concat(transform(matches, new Function<Match, List<Diff>>() {
+ public List<Diff> apply(Match match) {
+ return match.getDifferences();
+ }
+ }));
+ Predicate<? super Diff> diffFilter = and(instanceOf(ResourceAttachmentChange.class),
+ not(hasConflict(ConflictKind.PSEUDO)));
+ return ImmutableSet.<Diff> copyOf(filter(siblingDifferences, diffFilter)).asList();
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/BasicStructuralFeatureAccessorImpl.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/BasicStructuralFeatureAccessorImpl.java
index a04ff7a..20be707 100644
--- a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/BasicStructuralFeatureAccessorImpl.java
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/BasicStructuralFeatureAccessorImpl.java
@@ -1,152 +1,164 @@
-/*******************************************************************************
-
- * 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 static com.google.common.base.Predicates.and;
-import static com.google.common.base.Predicates.not;
-import static com.google.common.collect.Iterables.filter;
-import static org.eclipse.emf.compare.utils.EMFComparePredicates.hasConflict;
-import static org.eclipse.emf.compare.utils.EMFComparePredicates.onFeature;
-
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableList;
-
-import java.util.List;
-
-import org.eclipse.emf.compare.AttributeChange;
-import org.eclipse.emf.compare.Comparison;
-import org.eclipse.emf.compare.ConflictKind;
-import org.eclipse.emf.compare.Diff;
-import org.eclipse.emf.compare.Match;
-import org.eclipse.emf.compare.ReferenceChange;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewerItem;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EStructuralFeature;
-
-/**
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- */
-public abstract class BasicStructuralFeatureAccessorImpl implements IStructuralFeatureAccessor {
-
- private final Diff fDiff;
-
- private final MergeViewerSide fSide;
-
- private final Match fOwnerMatch;
-
- private final EStructuralFeature fStructuralFeature;
-
- private final ImmutableList<Diff> fDifferences;
-
- public BasicStructuralFeatureAccessorImpl(Diff diff, MergeViewerSide side) {
- fDiff = diff;
- fSide = side;
- fOwnerMatch = diff.getMatch();
- fStructuralFeature = getAffectedFeature(diff);
- fDifferences = computeDifferences();
- }
-
- public Comparison getComparison() {
- return fOwnerMatch.getComparison();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.provider.IStructuralFeatureAccessor#getInitialItem()
- */
- public IMergeViewerItem getInitialItem() {
- IMergeViewerItem ret = null;
- ImmutableList<? extends IMergeViewerItem> items = getItems();
- for (IMergeViewerItem item : items) {
- Diff diff = item.getDiff();
- if (diff == fDiff) {
- ret = item;
- }
- }
- return ret;
- }
-
- public 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;
- }
-
- /**
- * @return the fStructuralFeature
- */
- public EStructuralFeature getStructuralFeature() {
- return fStructuralFeature;
- }
-
- /**
- * @return the fSide
- */
- protected final MergeViewerSide getSide() {
- return fSide;
- }
-
- /**
- * @return the fDifferences
- */
- protected final ImmutableList<Diff> getDifferences() {
- return fDifferences;
- }
-
- protected ImmutableList<Diff> computeDifferences() {
- List<Diff> siblingDifferences = fOwnerMatch.getDifferences();
- // We'll display all diffs on the same reference, excluding the pseudo conflicts.
- Predicate<? super Diff> diffFilter = and(onFeature(fStructuralFeature.getName()),
- not(hasConflict(ConflictKind.PSEUDO)));
- return ImmutableList.copyOf(filter(siblingDifferences, diffFilter));
- }
-
- /**
- * Returns the structural feature affected by the given diff, if any.
- *
- * @param diff
- * The diff from which we need to retrieve a feature.
- * @return The feature affected by this {@code diff}, if any. <code>null</code> if none.
- */
- protected EStructuralFeature getAffectedFeature(Diff diff) {
- final EStructuralFeature feature;
- if (diff instanceof ReferenceChange) {
- feature = ((ReferenceChange)diff).getReference();
- } else if (diff instanceof AttributeChange) {
- feature = ((AttributeChange)diff).getAttribute();
- } else {
- feature = null;
- }
- return feature;
- }
-
- /**
- * @return the fDiff
- */
- protected final Diff getInitialDiff() {
- return fDiff;
- }
-}
+/*******************************************************************************
+
+ * 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 static com.google.common.base.Predicates.and;
+import static com.google.common.base.Predicates.not;
+import static com.google.common.collect.Iterables.filter;
+import static org.eclipse.emf.compare.utils.EMFComparePredicates.hasConflict;
+import static org.eclipse.emf.compare.utils.EMFComparePredicates.onFeature;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+
+import org.eclipse.emf.compare.AttributeChange;
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.ConflictKind;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.Match;
+import org.eclipse.emf.compare.ReferenceChange;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewerItem;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+/**
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public abstract class BasicStructuralFeatureAccessorImpl implements IStructuralFeatureAccessor {
+
+ private final Diff fDiff;
+
+ private final MergeViewerSide fSide;
+
+ private final Match fOwnerMatch;
+
+ private final EStructuralFeature fStructuralFeature;
+
+ private final ImmutableList<Diff> fDifferences;
+
+ public BasicStructuralFeatureAccessorImpl(Diff diff, MergeViewerSide side) {
+ fDiff = diff;
+ fSide = side;
+ fOwnerMatch = diff.getMatch();
+ fStructuralFeature = getAffectedFeature(diff);
+ fDifferences = computeDifferences();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.IStructuralFeatureAccessor#getComparison()
+ */
+ public Comparison getComparison() {
+ return fOwnerMatch.getComparison();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.IStructuralFeatureAccessor#getInitialItem()
+ */
+ public IMergeViewerItem getInitialItem() {
+ IMergeViewerItem ret = null;
+ ImmutableList<? extends IMergeViewerItem> items = getItems();
+ for (IMergeViewerItem item : items) {
+ Diff diff = item.getDiff();
+ if (diff == fDiff) {
+ ret = item;
+ }
+ }
+ return ret;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.IStructuralFeatureAccessor#getInitialItem()
+ */
+ public 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.emf.compare.rcp.ui.mergeviewer.accessor.IStructuralFeatureAccessor#getStructuralFeature()
+ */
+ public EStructuralFeature getStructuralFeature() {
+ return fStructuralFeature;
+ }
+
+ /**
+ * @return the fSide
+ */
+ protected final MergeViewerSide getSide() {
+ return fSide;
+ }
+
+ /**
+ * @return the fDifferences
+ */
+ protected final ImmutableList<Diff> getDifferences() {
+ return fDifferences;
+ }
+
+ protected ImmutableList<Diff> computeDifferences() {
+ List<Diff> siblingDifferences = fOwnerMatch.getDifferences();
+ // We'll display all diffs on the same reference, excluding the pseudo conflicts.
+ Predicate<? super Diff> diffFilter = and(onFeature(fStructuralFeature.getName()),
+ not(hasConflict(ConflictKind.PSEUDO)));
+ return ImmutableList.copyOf(filter(siblingDifferences, diffFilter));
+ }
+
+ /**
+ * Returns the structural feature affected by the given diff, if any.
+ *
+ * @param diff
+ * The diff from which we need to retrieve a feature.
+ * @return The feature affected by this {@code diff}, if any. <code>null</code> if none.
+ */
+ protected EStructuralFeature getAffectedFeature(Diff diff) {
+ final EStructuralFeature feature;
+ if (diff instanceof ReferenceChange) {
+ feature = ((ReferenceChange)diff).getReference();
+ } else if (diff instanceof AttributeChange) {
+ feature = ((AttributeChange)diff).getAttribute();
+ } else {
+ feature = null;
+ }
+ return feature;
+ }
+
+ /**
+ * @return the fDiff
+ */
+ protected final Diff getInitialDiff() {
+ return fDiff;
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/ICompareAccessor.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/ICompareAccessor.java
new file mode 100644
index 0000000..6835ea0
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/ICompareAccessor.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * 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.mergeviewer.accessor;
+
+import com.google.common.collect.ImmutableList;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewerItem;
+
+/**
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ */
+public interface ICompareAccessor {
+
+ Comparison getComparison();
+
+ IMergeViewerItem getInitialItem();
+
+ ImmutableList<? extends IMergeViewerItem> getItems();
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/IResourceContentsAccessor.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/IResourceContentsAccessor.java
new file mode 100644
index 0000000..0ec9964
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/IResourceContentsAccessor.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * 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.mergeviewer.accessor;
+
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
+import org.eclipse.emf.ecore.resource.Resource;
+
+/**
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ */
+public interface IResourceContentsAccessor extends ICompareAccessor {
+
+ Resource getResource(MergeViewerSide side);
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/IStructuralFeatureAccessor.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/IStructuralFeatureAccessor.java
index 8993bc0..59b6bb5 100644
--- a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/IStructuralFeatureAccessor.java
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/IStructuralFeatureAccessor.java
@@ -1,36 +1,26 @@
-/*******************************************************************************
- * 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.ImmutableList;
-
-import org.eclipse.emf.compare.Comparison;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewerItem;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EStructuralFeature;
-
-/**
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- */
-public interface IStructuralFeatureAccessor {
-
- EStructuralFeature getStructuralFeature();
-
- EObject getEObject(MergeViewerSide side);
-
- Comparison getComparison();
-
- IMergeViewerItem getInitialItem();
-
- ImmutableList<? extends IMergeViewerItem> getItems();
-
-}
+/*******************************************************************************
+ * 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.mergeviewer.accessor;
+
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+/**
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public interface IStructuralFeatureAccessor extends ICompareAccessor {
+
+ EStructuralFeature getStructuralFeature();
+
+ EObject getEObject(MergeViewerSide side);
+
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/ResourceContentsAccessorImpl.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/ResourceContentsAccessorImpl.java
new file mode 100644
index 0000000..bb1a6ad
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/ResourceContentsAccessorImpl.java
@@ -0,0 +1,233 @@
+/*******************************************************************************
+ * 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.mergeviewer.accessor;
+
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.size;
+import static com.google.common.collect.Lists.newArrayList;
+import static com.google.common.collect.Lists.newArrayListWithCapacity;
+
+import com.google.common.collect.ImmutableList;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.Match;
+import org.eclipse.emf.compare.ResourceAttachmentChange;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewerItem;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.InsertionPoint;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.MatchedObject;
+import org.eclipse.emf.compare.utils.DiffUtil;
+import org.eclipse.emf.compare.utils.IEqualityHelper;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+
+/**
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ */
+public class ResourceContentsAccessorImpl extends BasicResourceContentsAccessorImpl {
+
+ /**
+ * @param diff
+ * The difference performed.
+ * @param side
+ * The side on which the difference is located.
+ */
+ public ResourceContentsAccessorImpl(Diff diff, MergeViewerSide side) {
+ super(diff, side);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.IResourceContentsAccessor#getItems()
+ */
+ public ImmutableList<? extends IMergeViewerItem> getItems() {
+ List<? extends IMergeViewerItem> ret;
+ List<?> list = getResourceContents(getSide());
+ ret = createMergeViewerItemFrom(list);
+
+ if (getSide() != MergeViewerSide.ANCESTOR) {
+ ret = createInsertionPoints(ret);
+ }
+
+ return ImmutableList.copyOf(ret);
+ }
+
+ private List<? extends IMergeViewerItem> createMergeViewerItemFrom(List<?> values) {
+ List<IMergeViewerItem> ret = newArrayListWithCapacity(values.size());
+ for (Object value : values) {
+ IMergeViewerItem valueToAdd = createMergeViewerItemFrom(value);
+ ret.add(valueToAdd);
+ }
+ return ret;
+ }
+
+ private IMergeViewerItem createMergeViewerItemFrom(Object object) {
+ Diff diff = getDiffWithValue(object);
+ Object left = matchingValue(object, MergeViewerSide.LEFT);
+ Object right = matchingValue(object, MergeViewerSide.RIGHT);
+ Object ancestor = matchingValue(object, MergeViewerSide.ANCESTOR);
+ return new MatchedObject(diff, left, right, ancestor);
+ }
+
+ private List<? extends IMergeViewerItem> createInsertionPoints(
+ final List<? extends IMergeViewerItem> values) {
+ List<IMergeViewerItem> ret = newArrayList(values);
+ for (Diff diff : getDifferences().reverse()) {
+ boolean rightToLeft = (getSide() == MergeViewerSide.LEFT);
+ Object left = getValueFromDiff(diff, MergeViewerSide.LEFT);
+ Object right = getValueFromDiff(diff, MergeViewerSide.RIGHT);
+
+ if (left == null && right == null) {
+ // Do not display anything
+ } else {
+ final boolean leftEmptyBox = getSide() == MergeViewerSide.LEFT
+ && (left == null || !getResourceContents(getSide()).contains(left));
+ final boolean rightEmptyBox = getSide() == MergeViewerSide.RIGHT
+ && (right == null || !getResourceContents(getSide()).contains(right));
+ if (leftEmptyBox || rightEmptyBox) {
+ Object ancestor = getValueFromDiff(diff, MergeViewerSide.ANCESTOR);
+
+ InsertionPoint insertionPoint = new InsertionPoint(diff, left, right, ancestor);
+
+ final int insertionIndex = Math.min(findInsertionIndex(diff, rightToLeft), ret.size());
+ List<IMergeViewerItem> subList = ret.subList(0, insertionIndex);
+ final int nbInsertionPointBefore = size(filter(subList, InsertionPoint.class));
+
+ int index = Math.min(insertionIndex + nbInsertionPointBefore, ret.size());
+ ret.add(index, insertionPoint);
+ }
+ }
+ }
+ return ret;
+ }
+
+ protected int findInsertionIndex(Diff diff, boolean rightToLeft) {
+ final Match valueMatch = diff.getMatch();
+ final Comparison comparison = valueMatch.getComparison();
+
+ final EObject expectedValue;
+ if (valueMatch.getLeft() != null) {
+ expectedValue = valueMatch.getLeft();
+ } else {
+ expectedValue = valueMatch.getRight();
+ }
+
+ final Resource initialResource;
+ final Resource expectedResource;
+ if (rightToLeft) {
+ initialResource = getResource(MergeViewerSide.RIGHT);
+ expectedResource = getResource(MergeViewerSide.LEFT);
+ } else {
+ initialResource = getResource(MergeViewerSide.LEFT);
+ expectedResource = getResource(MergeViewerSide.RIGHT);
+ }
+ final List<EObject> sourceList = initialResource.getContents();
+ final List<EObject> targetList = expectedResource.getContents();
+
+ return DiffUtil.findInsertionIndex(comparison, sourceList, targetList, expectedValue);
+ }
+
+ private Diff getDiffWithValue(Object value) {
+ Diff ret = null;
+ for (Diff diff : getDifferences()) {
+ Object valueOfDiff = getValueFromDiff(diff, getSide());
+ if (valueOfDiff == value) {
+ ret = diff;
+ break;
+ }
+ }
+ return ret;
+ }
+
+ protected Object getValueFromDiff(final Diff diff, MergeViewerSide side) {
+ Object diffValue = getDiffValue(diff, side);
+ Object ret = matchingValue(diffValue, side);
+ return ret;
+ }
+
+ private Object matchingValue(Object object, MergeViewerSide side) {
+ final Object ret;
+ if (object instanceof EObject) {
+ final Match matchOfValue = getComparison().getMatch((EObject)object);
+ if (matchOfValue != null) {
+ switch (side) {
+ case ANCESTOR:
+ ret = matchOfValue.getOrigin();
+ break;
+ case LEFT:
+ ret = matchOfValue.getLeft();
+ break;
+ case RIGHT:
+ ret = matchOfValue.getRight();
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ } else {
+ ret = matchingValue(object, getResourceContents(side));
+ }
+ } else {
+ ret = matchingValue(object, getResourceContents(side));
+ }
+ return ret;
+ }
+
+ private Object matchingValue(Object value, List<?> in) {
+ Object ret = null;
+ IEqualityHelper equalityHelper = getComparison().getEqualityHelper();
+ Iterator<?> valuesIterator = in.iterator();
+ while (valuesIterator.hasNext() && ret == null) {
+ Object object = valuesIterator.next();
+ if (equalityHelper.matchingValues(object, value)) {
+ ret = object;
+ }
+ }
+ return ret;
+ }
+
+ protected Object getDiffValue(Diff diff, MergeViewerSide side) {
+ final Object ret;
+ if (diff instanceof ResourceAttachmentChange) {
+ Match match = ((ResourceAttachmentChange)diff).getMatch();
+ switch (side) {
+ case ANCESTOR:
+ switch (diff.getSource()) {
+ case LEFT:
+ ret = match.getRight();
+ break;
+ case RIGHT:
+ ret = match.getLeft();
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ break;
+ case LEFT:
+ ret = match.getLeft();
+ break;
+ case RIGHT:
+ ret = match.getRight();
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ } else {
+ ret = null;
+ }
+ return ret;
+ }
+
+}