Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/contentmergeviewer/ContentMergeViewer.java')
-rw-r--r--bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/contentmergeviewer/ContentMergeViewer.java1343
1 files changed, 0 insertions, 1343 deletions
diff --git a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/contentmergeviewer/ContentMergeViewer.java b/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/contentmergeviewer/ContentMergeViewer.java
deleted file mode 100644
index b47931690..000000000
--- a/bundles/org.eclipse.compare/plugins/org.eclipse.compare/compare/org/eclipse/compare/contentmergeviewer/ContentMergeViewer.java
+++ /dev/null
@@ -1,1343 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.compare.contentmergeviewer;
-
-import java.util.ResourceBundle;
-
-import org.eclipse.compare.CompareConfiguration;
-import org.eclipse.compare.CompareEditorInput;
-import org.eclipse.compare.CompareUI;
-import org.eclipse.compare.CompareViewerPane;
-import org.eclipse.compare.ICompareContainer;
-import org.eclipse.compare.ICompareInputLabelProvider;
-import org.eclipse.compare.IPropertyChangeNotifier;
-import org.eclipse.compare.internal.ChangePropertyAction;
-import org.eclipse.compare.internal.CompareEditor;
-import org.eclipse.compare.internal.CompareHandlerService;
-import org.eclipse.compare.internal.CompareMessages;
-import org.eclipse.compare.internal.ICompareUIConstants;
-import org.eclipse.compare.internal.IFlushable2;
-import org.eclipse.compare.internal.ISavingSaveable;
-import org.eclipse.compare.internal.MergeViewerContentProvider;
-import org.eclipse.compare.internal.Utilities;
-import org.eclipse.compare.internal.ViewerSwitchingCancelled;
-import org.eclipse.compare.structuremergeviewer.Differencer;
-import org.eclipse.compare.structuremergeviewer.ICompareInput;
-import org.eclipse.compare.structuremergeviewer.ICompareInputChangeListener;
-import org.eclipse.core.runtime.Assert;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.ListenerList;
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.ActionContributionItem;
-import org.eclipse.jface.action.IToolBarManager;
-import org.eclipse.jface.action.LegacyActionTools;
-import org.eclipse.jface.action.Separator;
-import org.eclipse.jface.action.ToolBarManager;
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.util.IPropertyChangeListener;
-import org.eclipse.jface.util.PropertyChangeEvent;
-import org.eclipse.jface.viewers.ContentViewer;
-import org.eclipse.jface.viewers.IContentProvider;
-import org.eclipse.jface.viewers.ILabelProviderListener;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.LabelProviderChangedEvent;
-import org.eclipse.jface.window.Window;
-import org.eclipse.osgi.util.TextProcessor;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.CLabel;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.events.MouseAdapter;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseMoveListener;
-import org.eclipse.swt.graphics.Cursor;
-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.Layout;
-import org.eclipse.swt.widgets.Sash;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.ISaveablesSource;
-import org.eclipse.ui.IWorkbenchPart;
-import org.eclipse.ui.Saveable;
-
-/**
- * An abstract compare and merge viewer with two side-by-side content areas
- * and an optional content area for the ancestor. The implementation makes no
- * assumptions about the content type.
- * <p>
- * <code>ContentMergeViewer</code>
- * <ul>
- * <li>implements the overall layout and defines hooks so that subclasses
- * can easily provide an implementation for a specific content type,
- * <li>implements the UI for making the areas resizable,
- * <li>has an action for controlling whether the ancestor area is visible or not,
- * <li>has actions for copying one side of the input to the other side,
- * <li>tracks the dirty state of the left and right sides and send out notification
- * on state changes.
- * </ul>
- * A <code>ContentMergeViewer</code> accesses its
- * model by means of a content provider which must implement the
- * <code>IMergeViewerContentProvider</code> interface.
- * </p>
- * <p>
- * Clients may wish to use the standard concrete subclass <code>TextMergeViewer</code>,
- * or define their own subclass.
- *
- * @see IMergeViewerContentProvider
- * @see TextMergeViewer
- */
-public abstract class ContentMergeViewer extends ContentViewer
- implements IPropertyChangeNotifier, IFlushable, IFlushable2 {
-
- /* package */ static final int HORIZONTAL= 1;
- /* package */ static final int VERTICAL= 2;
-
- static final double HSPLIT= 0.5;
- static final double VSPLIT= 0.3;
-
- private class ContentMergeViewerLayout extends Layout {
-
- public Point computeSize(Composite c, int w, int h, boolean force) {
- return new Point(100, 100);
- }
-
- public void layout(Composite composite, boolean force) {
-
- // determine some derived sizes
- int headerHeight= fLeftLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).y;
- Rectangle r= composite.getClientArea();
-
- int centerWidth= getCenterWidth();
- int width1= (int)((r.width-centerWidth)*getHorizontalSplitRatio());
- int width2= r.width-width1-centerWidth;
-
- int height1= 0;
- int height2= 0;
- if (fIsThreeWay && fAncestorVisible) {
- height1= (int)((r.height-(2*headerHeight))*fVSplit);
- height2= r.height-(2*headerHeight)-height1;
- } else {
- height1= 0;
- height2= r.height-headerHeight;
- }
-
- int y= 0;
-
- if (fIsThreeWay && fAncestorVisible) {
- fAncestorLabel.setBounds(0, y, r.width, headerHeight);
- fAncestorLabel.setVisible(true);
- y+= headerHeight;
- handleResizeAncestor(0, y, r.width, height1);
- y+= height1;
- } else {
- fAncestorLabel.setVisible(false);
- handleResizeAncestor(0, 0, 0, 0);
- }
-
- fLeftLabel.getSize(); // without this resizing would not always work
-
- if (centerWidth > 3) {
- fLeftLabel.setBounds(0, y, width1+1, headerHeight);
- fDirectionLabel.setVisible(true);
- fDirectionLabel.setBounds(width1+1, y, centerWidth-1, headerHeight);
- fRightLabel.setBounds(width1+centerWidth, y, width2, headerHeight);
- } else {
- fLeftLabel.setBounds(0, y, width1, headerHeight);
- fDirectionLabel.setVisible(false);
- fRightLabel.setBounds(width1, y, r.width-width1, headerHeight);
- }
-
- y+= headerHeight;
-
- if (fCenter != null && !fCenter.isDisposed())
- fCenter.setBounds(width1, y, centerWidth, height2);
-
- handleResizeLeftRight(0, y, width1, centerWidth, width2, height2);
- }
-
- private double getHorizontalSplitRatio() {
- if (fHSplit < 0) {
- Object input = getInput();
- if (input instanceof ICompareInput) {
- ICompareInput ci = (ICompareInput) input;
- if (ci.getLeft() == null)
- return 0.1;
- if (ci.getRight() == null)
- return 0.9;
- }
- return HSPLIT;
- }
- return fHSplit;
- }
- }
-
- class Resizer extends MouseAdapter implements MouseMoveListener {
-
- Control fControl;
- int fX, fY;
- int fWidth1, fWidth2;
- int fHeight1, fHeight2;
- int fDirection;
- boolean fLiveResize;
- boolean fIsDown;
-
- public Resizer(Control c, int dir) {
- fDirection= dir;
- fControl= c;
- fLiveResize= !(fControl instanceof Sash);
- updateCursor(c, dir);
- fControl.addMouseListener(this);
- fControl.addMouseMoveListener(this);
- fControl.addDisposeListener(
- new DisposeListener() {
- public void widgetDisposed(DisposeEvent e) {
- fControl= null;
- }
- }
- );
- }
-
- public void mouseDoubleClick(MouseEvent e) {
- if ((fDirection & HORIZONTAL) != 0)
- fHSplit= -1;
- if ((fDirection & VERTICAL) != 0)
- fVSplit= VSPLIT;
- fComposite.layout(true);
- }
-
- public void mouseDown(MouseEvent e) {
- Composite parent= fControl.getParent();
-
- Point s= parent.getSize();
- Point as= fAncestorLabel.getSize();
- Point ys= fLeftLabel.getSize();
- Point ms= fRightLabel.getSize();
-
- fWidth1= ys.x;
- fWidth2= ms.x;
- fHeight1= fLeftLabel.getLocation().y-as.y;
- fHeight2= s.y-(fLeftLabel.getLocation().y+ys.y);
-
- fX= e.x;
- fY= e.y;
- fIsDown= true;
- }
-
- public void mouseUp(MouseEvent e) {
- fIsDown= false;
- if (!fLiveResize)
- resize(e);
- }
-
- public void mouseMove(MouseEvent e) {
- if (fIsDown && fLiveResize)
- resize(e);
- }
-
- private void resize(MouseEvent e) {
- int dx= e.x-fX;
- int dy= e.y-fY;
-
- int centerWidth= fCenter.getSize().x;
-
- if (fWidth1 + dx > centerWidth && fWidth2 - dx > centerWidth) {
- fWidth1+= dx;
- fWidth2-= dx;
- if ((fDirection & HORIZONTAL) != 0)
- fHSplit= (double)fWidth1/(double)(fWidth1+fWidth2);
- }
- if (fHeight1 + dy > centerWidth && fHeight2 - dy > centerWidth) {
- fHeight1+= dy;
- fHeight2-= dy;
- if ((fDirection & VERTICAL) != 0)
- fVSplit= (double)fHeight1/(double)(fHeight1+fHeight2);
- }
-
- fComposite.layout(true);
- fControl.getDisplay().update();
- }
- }
-
- /** Style bits for top level composite */
- private int fStyles;
- private ResourceBundle fBundle;
- private final CompareConfiguration fCompareConfiguration;
- private IPropertyChangeListener fPropertyChangeListener;
- private ICompareInputChangeListener fCompareInputChangeListener;
- private ListenerList fListenerList;
- boolean fConfirmSave= true;
-
- private double fHSplit= -1; // width ratio of left and right panes
- private double fVSplit= VSPLIT; // height ratio of ancestor and bottom panes
-
- private boolean fIsThreeWay; // whether their is an ancestor
- private boolean fAncestorVisible; // whether the ancestor pane is visible
- private ActionContributionItem fAncestorItem;
-
- private Action fCopyLeftToRightAction; // copy from left to right
- private Action fCopyRightToLeftAction; // copy from right to left
-
- private boolean fIsLeftDirty;
- private boolean fIsRightDirty;
-
- private CompareHandlerService fHandlerService;
-
- // SWT widgets
- /* package */ Composite fComposite;
- private CLabel fAncestorLabel;
- private CLabel fLeftLabel;
- private CLabel fRightLabel;
- /* package */ CLabel fDirectionLabel;
- /* package */ Control fCenter;
-
- //---- SWT resources to be disposed
- private Image fRightArrow;
- private Image fLeftArrow;
- private Image fBothArrow;
- Cursor fNormalCursor;
- private Cursor fHSashCursor;
- private Cursor fVSashCursor;
- private Cursor fHVSashCursor;
-
- private ILabelProviderListener labelChangeListener = new ILabelProviderListener() {
- public void labelProviderChanged(LabelProviderChangedEvent event) {
- Object[] elements = event.getElements();
- for (int i = 0; i < elements.length; i++) {
- Object object = elements[i];
- if (object == getInput())
- updateHeader();
- }
- }
- };
-
- //---- end
-
- /**
- * Creates a new content merge viewer and initializes with a resource bundle and a
- * configuration.
- *
- * @param style SWT style bits
- * @param bundle the resource bundle
- * @param cc the configuration object
- */
- protected ContentMergeViewer(int style, ResourceBundle bundle, CompareConfiguration cc) {
-
- fStyles= style & ~(SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT); // remove BIDI direction bits
- fBundle= bundle;
-
- fAncestorVisible= Utilities.getBoolean(cc, ICompareUIConstants.PROP_ANCESTOR_VISIBLE, fAncestorVisible);
- fConfirmSave= Utilities.getBoolean(cc, CompareEditor.CONFIRM_SAVE_PROPERTY, fConfirmSave);
-
- setContentProvider(new MergeViewerContentProvider(cc));
-
- fCompareInputChangeListener= new ICompareInputChangeListener() {
- public void compareInputChanged(ICompareInput input) {
- if (input == getInput()) {
- handleCompareInputChange();
- }
- }
- };
-
- // Make sure the compare configuration is not null
- if (cc == null)
- fCompareConfiguration = new CompareConfiguration();
- else
- fCompareConfiguration= cc;
- fPropertyChangeListener= new IPropertyChangeListener() {
- public void propertyChange(PropertyChangeEvent event) {
- ContentMergeViewer.this.handlePropertyChangeEvent(event);
- }
- };
- fCompareConfiguration.addPropertyChangeListener(fPropertyChangeListener);
-
- fIsLeftDirty = false;
- fIsRightDirty = false;
- }
-
- //---- hooks ---------------------
-
- /**
- * Returns the viewer's name.
- *
- * @return the viewer's name
- */
- public String getTitle() {
- return Utilities.getString(getResourceBundle(), "title"); //$NON-NLS-1$
- }
-
- /**
- * Creates the SWT controls for the ancestor, left, and right
- * content areas of this compare viewer.
- * Implementations typically hold onto the controls
- * so that they can be initialized with the input objects in method
- * <code>updateContent</code>.
- *
- * @param composite the container for the three areas
- */
- abstract protected void createControls(Composite composite);
-
- /**
- * Lays out the ancestor area of the compare viewer.
- * It is called whenever the viewer is resized or when the sashes between
- * the areas are moved to adjust the size of the areas.
- *
- * @param x the horizontal position of the ancestor area within its container
- * @param y the vertical position of the ancestor area within its container
- * @param width the width of the ancestor area
- * @param height the height of the ancestor area
- */
- abstract protected void handleResizeAncestor(int x, int y, int width, int height);
-
- /**
- * Lays out the left and right areas of the compare viewer.
- * It is called whenever the viewer is resized or when the sashes between
- * the areas are moved to adjust the size of the areas.
- *
- * @param x the horizontal position of the left area within its container
- * @param y the vertical position of the left and right area within its container
- * @param leftWidth the width of the left area
- * @param centerWidth the width of the gap between the left and right areas
- * @param rightWidth the width of the right area
- * @param height the height of the left and right areas
- */
- abstract protected void handleResizeLeftRight(int x, int y, int leftWidth, int centerWidth,
- int rightWidth, int height);
-
- /**
- * Contributes items to the given <code>ToolBarManager</code>.
- * It is called when this viewer is installed in its container and if the container
- * has a <code>ToolBarManager</code>.
- * The <code>ContentMergeViewer</code> implementation of this method does nothing.
- * Subclasses may reimplement.
- *
- * @param toolBarManager the toolbar manager to contribute to
- */
- protected void createToolItems(ToolBarManager toolBarManager) {
- // empty implementation
- }
-
- /**
- * Initializes the controls of the three content areas with the given input objects.
- *
- * @param ancestor the input for the ancestor area
- * @param left the input for the left area
- * @param right the input for the right area
- */
- abstract protected void updateContent(Object ancestor, Object left, Object right);
-
- /**
- * Copies the content of one side to the other side.
- * Called from the (internal) actions for copying the sides of the viewer's input object.
- *
- * @param leftToRight if <code>true</code>, the left side is copied to the right side;
- * if <code>false</code>, the right side is copied to the left side
- */
- abstract protected void copy(boolean leftToRight);
-
- /**
- * Returns the byte contents of the left or right side. If the viewer
- * has no editable content <code>null</code> can be returned.
- *
- * @param left if <code>true</code>, the byte contents of the left area is returned;
- * if <code>false</code>, the byte contents of the right area
- * @return the content as an array of bytes, or <code>null</code>
- */
- abstract protected byte[] getContents(boolean left);
-
- //----------------------------
-
- /**
- * Returns the resource bundle of this viewer.
- *
- * @return the resource bundle
- */
- protected ResourceBundle getResourceBundle() {
- return fBundle;
- }
-
- /**
- * Returns the compare configuration of this viewer,
- * or <code>null</code> if this viewer does not yet have a configuration.
- *
- * @return the compare configuration, or <code>null</code> if none
- */
- protected CompareConfiguration getCompareConfiguration() {
- return fCompareConfiguration;
- }
-
- /**
- * The <code>ContentMergeViewer</code> implementation of this
- * <code>ContentViewer</code> method
- * checks to ensure that the content provider is an <code>IMergeViewerContentProvider</code>.
- * @param contentProvider the content provider to set. Must implement IMergeViewerContentProvider.
- */
- public void setContentProvider(IContentProvider contentProvider) {
- Assert.isTrue(contentProvider instanceof IMergeViewerContentProvider);
- super.setContentProvider(contentProvider);
- }
-
- /* package */ IMergeViewerContentProvider getMergeContentProvider() {
- return (IMergeViewerContentProvider) getContentProvider();
- }
-
- /**
- * The <code>ContentMergeViewer</code> implementation of this
- * <code>Viewer</code> method returns the empty selection. Subclasses may override.
- * @return empty selection.
- */
- public ISelection getSelection() {
- return new ISelection() {
- public boolean isEmpty() {
- return true;
- }
- };
- }
-
- /**
- * The <code>ContentMergeViewer</code> implementation of this
- * <code>Viewer</code> method does nothing. Subclasses may reimplement.
- * @see org.eclipse.jface.viewers.Viewer#setSelection(org.eclipse.jface.viewers.ISelection, boolean)
- */
- public void setSelection(ISelection selection, boolean reveal) {
- // empty implementation
- }
-
- /**
- * Callback that is invoked when a property in the compare configuration
- * ({@link #getCompareConfiguration()} changes.
- * @param event the property change event
- * @since 3.3
- */
- protected void handlePropertyChangeEvent(PropertyChangeEvent event) {
-
- String key= event.getProperty();
-
- if (key.equals(ICompareUIConstants.PROP_ANCESTOR_VISIBLE)) {
- fAncestorVisible= Utilities.getBoolean(getCompareConfiguration(), ICompareUIConstants.PROP_ANCESTOR_VISIBLE, fAncestorVisible);
- fComposite.layout(true);
-
- updateCursor(fLeftLabel, VERTICAL);
- updateCursor(fDirectionLabel, HORIZONTAL | VERTICAL);
- updateCursor(fRightLabel, VERTICAL);
-
- return;
- }
-
- if (key.equals(ICompareUIConstants.PROP_IGNORE_ANCESTOR)) {
- setAncestorVisibility(false, !Utilities.getBoolean(getCompareConfiguration(), ICompareUIConstants.PROP_IGNORE_ANCESTOR, false));
- return;
- }
- }
-
- void updateCursor(Control c, int dir) {
- if (!(c instanceof Sash)) {
- Cursor cursor= null;
- switch (dir) {
- case VERTICAL:
- if (fAncestorVisible) {
- if (fVSashCursor == null) fVSashCursor= new Cursor(c.getDisplay(), SWT.CURSOR_SIZENS);
- cursor= fVSashCursor;
- } else {
- if (fNormalCursor == null) fNormalCursor= new Cursor(c.getDisplay(), SWT.CURSOR_ARROW);
- cursor= fNormalCursor;
- }
- break;
- case HORIZONTAL:
- if (fHSashCursor == null) fHSashCursor= new Cursor(c.getDisplay(), SWT.CURSOR_SIZEWE);
- cursor= fHSashCursor;
- break;
- case VERTICAL + HORIZONTAL:
- if (fAncestorVisible) {
- if (fHVSashCursor == null) fHVSashCursor= new Cursor(c.getDisplay(), SWT.CURSOR_SIZEALL);
- cursor= fHVSashCursor;
- } else {
- if (fHSashCursor == null) fHSashCursor= new Cursor(c.getDisplay(), SWT.CURSOR_SIZEWE);
- cursor= fHSashCursor;
- }
- break;
- }
- if (cursor != null)
- c.setCursor(cursor);
- }
- }
-
- private void setAncestorVisibility(boolean visible, boolean enabled) {
- if (fAncestorItem != null) {
- Action action= (Action) fAncestorItem.getAction();
- if (action != null) {
- action.setChecked(visible);
- action.setEnabled(enabled);
- }
- }
- getCompareConfiguration().setProperty(ICompareUIConstants.PROP_ANCESTOR_VISIBLE, new Boolean(visible));
- }
-
- //---- input
-
- /**
- * Return whether the input is a three-way comparison.
- * @return whether the input is a three-way comparison
- * @since 3.3
- */
- protected boolean isThreeWay() {
- return fIsThreeWay;
- }
-
- /**
- * Internal hook method called when the input to this viewer is
- * initially set or subsequently changed.
- * <p>
- * The <code>ContentMergeViewer</code> implementation of this <code>Viewer</code>
- * method tries to save the old input by calling <code>doSave(...)</code> and
- * then calls <code>internalRefresh(...)</code>.
- *
- * @param input the new input of this viewer, or <code>null</code> if there is no new input
- * @param oldInput the old input element, or <code>null</code> if there was previously no input
- */
- protected final void inputChanged(Object input, Object oldInput) {
-
- if (input != oldInput && oldInput != null) {
- ICompareInputLabelProvider lp = getCompareConfiguration().getLabelProvider();
- if (lp != null)
- lp.removeListener(labelChangeListener);
- }
-
- if (input != oldInput && oldInput instanceof ICompareInput) {
- ICompareContainer container = getCompareConfiguration().getContainer();
- container.removeCompareInputChangeListener((ICompareInput)oldInput, fCompareInputChangeListener);
- }
-
- boolean success= doSave(input, oldInput);
-
- if (input != oldInput && input instanceof ICompareInput) {
- ICompareContainer container = getCompareConfiguration().getContainer();
- container.addCompareInputChangeListener((ICompareInput)input, fCompareInputChangeListener);
- }
-
- if (input != oldInput && input != null) {
- ICompareInputLabelProvider lp = getCompareConfiguration().getLabelProvider();
- if (lp != null)
- lp.addListener(labelChangeListener);
- }
-
- if (success) {
- setLeftDirty(false);
- setRightDirty(false);
- }
-
- if (input != oldInput)
- internalRefresh(input);
- }
-
- /**
- * This method is called from the <code>Viewer</code> method <code>inputChanged</code>
- * to save any unsaved changes of the old input.
- * <p>
- * The <code>ContentMergeViewer</code> implementation of this
- * method calls <code>saveContent(...)</code>. If confirmation has been turned on
- * with <code>setConfirmSave(true)</code>, a confirmation alert is posted before saving.
- * </p>
- * Clients can override this method and are free to decide whether
- * they want to call the inherited method.
- * @param newInput the new input of this viewer, or <code>null</code> if there is no new input
- * @param oldInput the old input element, or <code>null</code> if there was previously no input
- * @return <code>true</code> if saving was successful, or if the user didn't want to save (by pressing 'NO' in the confirmation dialog).
- * @since 2.0
- */
- protected boolean doSave(Object newInput, Object oldInput) {
-
- // before setting the new input we have to save the old
- if (isLeftDirty() || isRightDirty()) {
-
-
- if (Utilities.RUNNING_TESTS) {
- if (Utilities.TESTING_FLUSH_ON_COMPARE_INPUT_CHANGE) {
- flushContent(oldInput, null);
- }
- } else if (fConfirmSave) {
- // post alert
- Shell shell= fComposite.getShell();
-
- MessageDialog dialog= new MessageDialog(shell,
- Utilities.getString(getResourceBundle(), "saveDialog.title"), //$NON-NLS-1$
- null, // accept the default window icon
- Utilities.getString(getResourceBundle(), "saveDialog.message"), //$NON-NLS-1$
- MessageDialog.QUESTION,
- new String[] {
- IDialogConstants.YES_LABEL,
- IDialogConstants.NO_LABEL,
- },
- 0); // default button index
-
- switch (dialog.open()) { // open returns index of pressed button
- case 0:
- flushContent(oldInput, null);
- break;
- case 1:
- setLeftDirty(false);
- setRightDirty(false);
- break;
- case 2:
- throw new ViewerSwitchingCancelled();
- }
- } else
- flushContent(oldInput, null);
- return true;
- }
- return false;
- }
-
- /**
- * Controls whether <code>doSave(Object, Object)</code> asks for confirmation before saving
- * the old input with <code>saveContent(Object)</code>.
- * @param enable a value of <code>true</code> enables confirmation
- * @since 2.0
- */
- public void setConfirmSave(boolean enable) {
- fConfirmSave= enable;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jface.viewers.Viewer#refresh()
- */
- public void refresh() {
- internalRefresh(getInput());
- }
-
- private void internalRefresh(Object input) {
-
- IMergeViewerContentProvider content= getMergeContentProvider();
- if (content != null) {
- Object ancestor= content.getAncestorContent(input);
- boolean oldFlag = fIsThreeWay;
- if (Utilities.isHunk(input)) {
- fIsThreeWay = true;
- } else if (input instanceof ICompareInput)
- fIsThreeWay= (((ICompareInput)input).getKind() & Differencer.DIRECTION_MASK) != 0;
- else
- fIsThreeWay= ancestor != null;
-
- if (fAncestorItem != null)
- fAncestorItem.setVisible(fIsThreeWay);
-
- if (fAncestorVisible && oldFlag != fIsThreeWay)
- fComposite.layout(true);
-
-
- Object left= content.getLeftContent(input);
- Object right= content.getRightContent(input);
- updateContent(ancestor, left, right);
-
- updateHeader();
- if (Utilities.okToUse(fComposite) && Utilities.okToUse(fComposite.getParent())) {
- ToolBarManager tbm = (ToolBarManager) getToolBarManager(fComposite.getParent());
- if (tbm != null ) {
- updateToolItems();
- tbm.update(true);
- tbm.getControl().getParent().layout(true);
- }
- }
- }
- }
-
- //---- layout & SWT control creation
-
- /**
- * Builds the SWT controls for the three areas of a compare/merge viewer.
- * <p>
- * Calls the hooks <code>createControls</code> and <code>createToolItems</code>
- * to let subclasses build the specific content areas and to add items to
- * an enclosing toolbar.
- * <p>
- * This method must only be called in the constructor of subclasses.
- *
- * @param parent the parent control
- * @return the new control
- */
- protected final Control buildControl(Composite parent) {
-
- fComposite= new Composite(parent, fStyles | SWT.LEFT_TO_RIGHT) { // we force a specific direction
- public boolean setFocus() {
- return ContentMergeViewer.this.handleSetFocus();
- }
- };
- fComposite.setData(CompareUI.COMPARE_VIEWER_TITLE, getTitle());
-
- hookControl(fComposite); // hook help & dispose listener
-
- fComposite.setLayout(new ContentMergeViewerLayout());
-
- int style= SWT.SHADOW_OUT;
- fAncestorLabel= new CLabel(fComposite, style | Window.getDefaultOrientation());
-
- fLeftLabel= new CLabel(fComposite, style | Window.getDefaultOrientation());
- new Resizer(fLeftLabel, VERTICAL);
-
- fDirectionLabel= new CLabel(fComposite, style);
- fDirectionLabel.setAlignment(SWT.CENTER);
- new Resizer(fDirectionLabel, HORIZONTAL | VERTICAL);
-
- fRightLabel= new CLabel(fComposite, style | Window.getDefaultOrientation());
- new Resizer(fRightLabel, VERTICAL);
-
- if (fCenter == null || fCenter.isDisposed())
- fCenter= createCenterControl(fComposite);
-
- createControls(fComposite);
-
- fHandlerService= CompareHandlerService.createFor(getCompareConfiguration().getContainer(), fComposite.getShell());
-
- initializeToolbars(parent);
-
- return fComposite;
- }
-
- /**
- * Returns the toolbar manager for this viewer.
- *
- * Subclasses may extend this method and use either the toolbar manager
- * provided by the inherited method by calling
- * super.getToolBarManager(parent) or provide an alternate toolbar manager.
- *
- * @param parent
- * a <code>Composite</code> or <code>null</code>
- * @return a <code>IToolBarManager</code>
- * @since 3.4
- */
- protected IToolBarManager getToolBarManager(Composite parent) {
- return CompareViewerPane.getToolBarManager(parent);
- }
-
- private void initializeToolbars(Composite parent) {
- ToolBarManager tbm = (ToolBarManager) getToolBarManager(parent);
- if (tbm != null) {
- tbm.removeAll();
-
- // define groups
- tbm.add(new Separator("modes")); //$NON-NLS-1$
- tbm.add(new Separator("merge")); //$NON-NLS-1$
- tbm.add(new Separator("navigation")); //$NON-NLS-1$
-
- CompareConfiguration cc= getCompareConfiguration();
-
- if (cc.isRightEditable()) {
- fCopyLeftToRightAction=
- new Action() {
- public void run() {
- copy(true);
- }
- };
- Utilities.initAction(fCopyLeftToRightAction, getResourceBundle(), "action.CopyLeftToRight."); //$NON-NLS-1$
- tbm.appendToGroup("merge", fCopyLeftToRightAction); //$NON-NLS-1$
- fHandlerService.registerAction(fCopyLeftToRightAction, "org.eclipse.compare.copyAllLeftToRight"); //$NON-NLS-1$
- }
-
- if (cc.isLeftEditable()) {
- fCopyRightToLeftAction=
- new Action() {
- public void run() {
- copy(false);
- }
- };
- Utilities.initAction(fCopyRightToLeftAction, getResourceBundle(), "action.CopyRightToLeft."); //$NON-NLS-1$
- tbm.appendToGroup("merge", fCopyRightToLeftAction); //$NON-NLS-1$
- fHandlerService.registerAction(fCopyRightToLeftAction, "org.eclipse.compare.copyAllRightToLeft"); //$NON-NLS-1$
- }
-
- final ChangePropertyAction a= new ChangePropertyAction(fBundle, getCompareConfiguration(), "action.EnableAncestor.", ICompareUIConstants.PROP_ANCESTOR_VISIBLE); //$NON-NLS-1$
- a.setChecked(fAncestorVisible);
- fAncestorItem= new ActionContributionItem(a);
- fAncestorItem.setVisible(false);
- tbm.appendToGroup("modes", fAncestorItem); //$NON-NLS-1$
- tbm.getControl().addDisposeListener(a);
-
- createToolItems(tbm);
- updateToolItems();
-
- tbm.update(true);
- }
- }
-
- /**
- * Callback that is invoked when the control of this merge viewer is given focus.
- * This method should return <code>true</code> if a particular widget was given focus
- * and false otherwise. By default, <code>false</code> is returned. Subclasses may override.
- * @return whether particular widget was given focus
- * @since 3.3
- */
- protected boolean handleSetFocus() {
- return false;
- }
-
- /**
- * Return the desired width of the center control. This width is used
- * to calculate the values used to layout the ancestor, left and right sides.
- * @return the desired width of the center control
- * @see #handleResizeLeftRight(int, int, int, int, int, int)
- * @see #handleResizeAncestor(int, int, int, int)
- * @since 3.3
- */
- protected int getCenterWidth() {
- return 3;
- }
-
- /**
- * Return whether the ancestor pane is visible or not.
- * @return whether the ancestor pane is visible or not
- * @since 3.3
- */
- protected boolean isAncestorVisible() {
- return fAncestorVisible;
- }
-
- /**
- * Create the control that divides the left and right sides of the merge viewer.
- * @param parent the parent composite
- * @return the center control
- * @since 3.3
- */
- protected Control createCenterControl(Composite parent) {
- Sash sash= new Sash(parent, SWT.VERTICAL);
- new Resizer(sash, HORIZONTAL);
- return sash;
- }
-
- /**
- * Return the center control that divides the left and right sides of the merge viewer.
- * This method returns the control that was created by calling {@link #createCenterControl(Composite)}.
- * @see #createCenterControl(Composite)
- * @return the center control
- * @since 3.3
- */
- protected Control getCenterControl() {
- return fCenter;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jface.viewers.Viewer#getControl()
- */
- public Control getControl() {
- return fComposite;
- }
-
- /**
- * Called on the viewer disposal.
- * Unregisters from the compare configuration.
- * Clients may extend if they have to do additional cleanup.
- * @see org.eclipse.jface.viewers.ContentViewer#handleDispose(org.eclipse.swt.events.DisposeEvent)
- */
- protected void handleDispose(DisposeEvent event) {
-
- if (fHandlerService != null)
- fHandlerService.dispose();
-
- Object input= getInput();
- if (input instanceof ICompareInput) {
- ICompareContainer container = getCompareConfiguration().getContainer();
- container.removeCompareInputChangeListener((ICompareInput)input, fCompareInputChangeListener);
- }
- if (input != null) {
- ICompareInputLabelProvider lp = getCompareConfiguration().getLabelProvider();
- if (lp != null)
- lp.removeListener(labelChangeListener);
- }
-
- if (fPropertyChangeListener != null) {
- fCompareConfiguration.removePropertyChangeListener(fPropertyChangeListener);
- fPropertyChangeListener= null;
- }
-
- fAncestorLabel= null;
- fLeftLabel= null;
- fDirectionLabel= null;
- fRightLabel= null;
- fCenter= null;
-
- if (fRightArrow != null) {
- fRightArrow.dispose();
- fRightArrow= null;
- }
- if (fLeftArrow != null) {
- fLeftArrow.dispose();
- fLeftArrow= null;
- }
- if (fBothArrow != null) {
- fBothArrow.dispose();
- fBothArrow= null;
- }
-
- if (fNormalCursor != null) {
- fNormalCursor.dispose();
- fNormalCursor= null;
- }
- if (fHSashCursor != null) {
- fHSashCursor.dispose();
- fHSashCursor= null;
- }
- if (fVSashCursor != null) {
- fVSashCursor.dispose();
- fVSashCursor= null;
- }
- if (fHVSashCursor != null) {
- fHVSashCursor.dispose();
- fHVSashCursor= null;
- }
-
- super.handleDispose(event);
- }
-
- /**
- * Updates the enabled state of the toolbar items.
- * <p>
- * This method is called whenever the state of the items needs updating.
- * <p>
- * Subclasses may extend this method, although this is generally not required.
- */
- protected void updateToolItems() {
-
- IMergeViewerContentProvider content= getMergeContentProvider();
-
- Object input= getInput();
-
- if (fCopyLeftToRightAction != null) {
- boolean enable= content.isRightEditable(input);
-// if (enable && input instanceof ICompareInput) {
-// ITypedElement e= ((ICompareInput) input).getLeft();
-// if (e == null)
-// enable= false;
-// }
- fCopyLeftToRightAction.setEnabled(enable);
- }
-
- if (fCopyRightToLeftAction != null) {
- boolean enable= content.isLeftEditable(input);
-// if (enable && input instanceof ICompareInput) {
-// ITypedElement e= ((ICompareInput) input).getRight();
-// if (e == null)
-// enable= false;
-// }
- fCopyRightToLeftAction.setEnabled(enable);
- }
- }
-
- /**
- * Updates the headers of the three areas
- * by querying the content provider for a name and image for
- * the three sides of the input object.
- * <p>
- * This method is called whenever the header must be updated.
- * <p>
- * Subclasses may extend this method, although this is generally not required.
- */
- protected void updateHeader() {
-
- IMergeViewerContentProvider content= getMergeContentProvider();
- Object input= getInput();
-
- // Only change a label if there is a new label available
- if (fAncestorLabel != null) {
- Image ancestorImage = content.getAncestorImage(input);
- if (ancestorImage != null)
- fAncestorLabel.setImage(ancestorImage);
- String ancestorLabel = content.getAncestorLabel(input);
- if (ancestorLabel != null)
- fAncestorLabel.setText(LegacyActionTools.escapeMnemonics(TextProcessor.process(ancestorLabel)));
- }
- if (fLeftLabel != null) {
- Image leftImage = content.getLeftImage(input);
- if (leftImage != null)
- fLeftLabel.setImage(leftImage);
- String leftLabel = content.getLeftLabel(input);
- if (leftLabel != null)
- fLeftLabel.setText(LegacyActionTools.escapeMnemonics(leftLabel));
- }
- if (fRightLabel != null) {
- Image rightImage = content.getRightImage(input);
- if (rightImage != null)
- fRightLabel.setImage(rightImage);
- String rightLabel = content.getRightLabel(input);
- if (rightLabel != null)
- fRightLabel.setText(LegacyActionTools.escapeMnemonics(rightLabel));
- }
- }
-
- /*
- * Calculates the height of the header.
- */
- /* package */ int getHeaderHeight() {
- int headerHeight= fLeftLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).y;
- headerHeight= Math.max(headerHeight, fDirectionLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).y);
- return headerHeight;
- }
-
- //---- dirty state & saving state
-
- /* (non-Javadoc)
- * @see org.eclipse.compare.IPropertyChangeNotifier#addPropertyChangeListener(org.eclipse.jface.util.IPropertyChangeListener)
- */
- public void addPropertyChangeListener(IPropertyChangeListener listener) {
- if (fListenerList == null)
- fListenerList= new ListenerList();
- fListenerList.add(listener);
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.compare.IPropertyChangeNotifier#removePropertyChangeListener(org.eclipse.jface.util.IPropertyChangeListener)
- */
- public void removePropertyChangeListener(IPropertyChangeListener listener) {
- if (fListenerList != null) {
- fListenerList.remove(listener);
- if (fListenerList.isEmpty())
- fListenerList= null;
- }
- }
-
- private void fireDirtyState(boolean state) {
- Utilities.firePropertyChange(fListenerList, this, CompareEditorInput.DIRTY_STATE, null, new Boolean(state));
- }
-
- /**
- * Sets the dirty state of the left side of this viewer.
- * If the new value differs from the old
- * all registered listener are notified with
- * a <code>PropertyChangeEvent</code> with the
- * property name <code>CompareEditorInput.DIRTY_STATE</code>.
- *
- * @param dirty the state of the left side dirty flag
- */
- protected void setLeftDirty(boolean dirty) {
- if (isLeftDirty() != dirty) {
- fIsLeftDirty = dirty;
- // Always fire the event if the dirty state has changed
- fireDirtyState(dirty);
- }
- }
-
- /**
- * Sets the dirty state of the right side of this viewer.
- * If the new value differs from the old
- * all registered listener are notified with
- * a <code>PropertyChangeEvent</code> with the
- * property name <code>CompareEditorInput.DIRTY_STATE</code>.
- *
- * @param dirty the state of the right side dirty flag
- */
- protected void setRightDirty(boolean dirty) {
- if (isRightDirty() != dirty) {
- fIsRightDirty = dirty;
- // Always fire the event if the dirty state has changed
- fireDirtyState(dirty);
- }
- }
-
- /**
- * Method from the old internal <code>ISavable</code> interface
- * Save the viewers's content.
- * Note: this method is for internal use only. Clients should not call this method.
- * @param monitor a progress monitor
- * @throws CoreException
- * @deprecated use {@link IFlushable#flush(IProgressMonitor)}.
- */
- public void save(IProgressMonitor monitor) throws CoreException {
- flush(monitor);
- }
-
- /**
- * Flush any modifications made in the viewer into the compare input. This method
- * calls {@link #flushContent(Object, IProgressMonitor)} with the compare input
- * of the viewer as the first parameter.
- * @param monitor a progress monitor
- * @see org.eclipse.compare.contentmergeviewer.IFlushable#flush(org.eclipse.core.runtime.IProgressMonitor)
- * @since 3.3
- */
- public final void flush(IProgressMonitor monitor) {
- flushContent(getInput(), monitor);
- }
-
- /**
- * Flush the modified content back to input elements via the content provider.
- * The provided input may be the current input of the viewer or it may be
- * the previous input (i.e. this method may be called to flush modified content
- * during an input change).
- * @param input the compare input
- * @param monitor a progress monitor or <code>null</code> if the method
- * was call from a place where a progress monitor was not available.
- * @since 3.3
- */
- protected void flushContent(Object input, IProgressMonitor monitor) {
- flushLeftSide(input, monitor);
- flushRightSide(input, monitor);
- }
-
-
- void flushLeftSide(Object input, IProgressMonitor monitor) {
- IMergeViewerContentProvider content = (IMergeViewerContentProvider) getContentProvider();
-
- boolean rightEmpty = content.getRightContent(input) == null;
-
- if (getCompareConfiguration().isLeftEditable() && isLeftDirty()) {
- byte[] bytes = getContents(true);
- if (rightEmpty && bytes != null && bytes.length == 0)
- bytes = null;
- setLeftDirty(false);
- content.saveLeftContent(input, bytes);
- }
- }
-
- void flushRightSide(Object input, IProgressMonitor monitor) {
- IMergeViewerContentProvider content = (IMergeViewerContentProvider) getContentProvider();
-
- boolean leftEmpty = content.getLeftContent(input) == null;
-
- if (getCompareConfiguration().isRightEditable() && isRightDirty()) {
- byte[] bytes = getContents(false);
- if (leftEmpty && bytes != null && bytes.length == 0)
- bytes = null;
- setRightDirty(false);
- content.saveRightContent(input, bytes);
- }
- }
-
- /**
- * @param monitor
- * @noreference This method is not intended to be referenced by clients.
- */
- public void flushLeft(IProgressMonitor monitor) {
- flushLeftSide(getInput(), monitor);
- }
-
- /**
- * @param monitor
- * @noreference This method is not intended to be referenced by clients.
- */
- public void flushRight(IProgressMonitor monitor) {
- flushRightSide(getInput(), monitor);
- }
-
- /**
- * Return the dirty state of the right side of this viewer.
- * @return the dirty state of the right side of this viewer
- * @since 3.3
- */
- protected boolean isRightDirty() {
- return fIsRightDirty;
- }
-
- /**
- * @return the dirty state of the right side of this viewer
- * @since 3.7
- * @noreference This method is not intended to be referenced by clients.
- */
- public boolean internalIsRightDirty() {
- return isRightDirty();
- }
-
- /**
- * Return the dirty state of the left side of this viewer.
- * @return the dirty state of the left side of this viewer
- * @since 3.3
- */
- protected boolean isLeftDirty() {
- return fIsLeftDirty;
- }
-
- /**
- * @return the dirty state of the left side of this viewer
- * @since 3.7
- * @noreference This method is not intended to be referenced by clients.
- */
- public boolean internalIsLeftDirty() {
- return isLeftDirty();
- }
-
- /**
- * Handle a change to the given input reported from an {@link org.eclipse.compare.structuremergeviewer.ICompareInputChangeListener}.
- * This class registers a listener with its input and reports any change events through
- * this method. By default, this method prompts for any unsaved changes and then refreshes
- * the viewer. Subclasses may override.
- * @since 3.3
- */
- protected void handleCompareInputChange() {
- // before setting the new input we have to save the old
- Object input = getInput();
- if (!isSaving() && (isLeftDirty() || isRightDirty())) {
-
- if (Utilities.RUNNING_TESTS) {
- if (Utilities.TESTING_FLUSH_ON_COMPARE_INPUT_CHANGE) {
- flushContent(input, null);
- }
- } else {
- // post alert
- Shell shell= fComposite.getShell();
-
- MessageDialog dialog= new MessageDialog(shell,
- CompareMessages.ContentMergeViewer_resource_changed_title,
- null, // accept the default window icon
- CompareMessages.ContentMergeViewer_resource_changed_description,
- MessageDialog.QUESTION,
- new String[] {
- IDialogConstants.YES_LABEL, // 0
- IDialogConstants.NO_LABEL, // 1
- },
- 0); // default button index
-
- switch (dialog.open()) { // open returns index of pressed button
- case 0:
- flushContent(input, null);
- break;
- case 1:
- setLeftDirty(false);
- setRightDirty(false);
- break;
- }
- }
- }
- refresh();
- }
-
- CompareHandlerService getCompareHandlerService() {
- return fHandlerService;
- }
-
- /**
- * @return true if any of the Saveables is being saved
- */
- private boolean isSaving() {
- ICompareContainer container = fCompareConfiguration.getContainer();
- ISaveablesSource source = null;
- if (container instanceof ISaveablesSource) {
- source = (ISaveablesSource) container;
- } else {
- IWorkbenchPart part = container.getWorkbenchPart();
- if (part instanceof ISaveablesSource) {
- source = (ISaveablesSource) part;
- }
- }
- if (source != null) {
- Saveable[] saveables = source.getSaveables();
- for (int i = 0; i < saveables.length; i++) {
- if (saveables[i] instanceof ISavingSaveable) {
- ISavingSaveable saveable = (ISavingSaveable) saveables[i];
- if (saveable.isSaving())
- return true;
- }
- }
- }
- return false;
- }
-
-}

Back to the top