blob: 666f99e2690dcea81cb65d5cbfafe2dad0f58db8 [file] [log] [blame]
/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved.
*/
package org.eclipse.compare;
import java.util.HashMap;
import org.eclipse.swt.graphics.*;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.util.*;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.compare.internal.*;
import org.eclipse.compare.structuremergeviewer.Differencer;
/**
* A <code>CompareConfiguration</code> object
* controls various UI aspects of compare/merge viewers like
* title labels and images, or whether a side of a merge viewer is editable.
* In addition to these fixed properties <code>ICompareConfiguration</code> provides
* API for an open ended set of properties. Different viewers which share the same
* configuration can communicate via this mechanism. E.g. if a compare editor
* has a button for controlling whether compare viewers ignore white space,
* the button would trigger a change of the boolean <code>IGNORE_WHITESPACE</code> property
* and all interested viewers would receive notification.
* <p>
* Suitable default labels are provided (without images); both the left and right sides
* are editable.
* </p>
* <p>
* Clients may use this class as is, or subclass to add new state and behavior.
* </p>
*/
public class CompareConfiguration {
/**
* Name of the ignore whitespace property.
*/
public static final String IGNORE_WHITESPACE= "IGNORE_WHITESPACE"; //$NON-NLS-1$
/**
* Name of the show pseudo conflicts property.
*/
public static final String SHOW_PSEUDO_CONFLICTS= "SHOW_PSEUDO_CONFLICTS"; //$NON-NLS-1$
private static final int WIDTH= 22;
private static ImageDescriptor[] fgImages= new ImageDescriptor[16];
private static Object fgDummy= new Object();
private static HashMap fgMap= new HashMap(20);
private static boolean fLeftIsLocal= true;
static {
if (fLeftIsLocal) {
fgImages[Differencer.ADDITION]= CompareUIPlugin.getImageDescriptor("ovr16/del_ov.gif"); //$NON-NLS-1$
fgImages[Differencer.LEFT + Differencer.ADDITION]= CompareUIPlugin.getImageDescriptor("ovr16/r_inadd_ov.gif"); //$NON-NLS-1$
fgImages[Differencer.RIGHT + Differencer.ADDITION]= CompareUIPlugin.getImageDescriptor("ovr16/r_outadd_ov.gif"); //$NON-NLS-1$
fgImages[Differencer.DELETION]= CompareUIPlugin.getImageDescriptor("ovr16/add_ov.gif"); //$NON-NLS-1$
fgImages[Differencer.LEFT + Differencer.DELETION]= CompareUIPlugin.getImageDescriptor("ovr16/r_indel_ov.gif"); //$NON-NLS-1$
fgImages[Differencer.RIGHT + Differencer.DELETION]= CompareUIPlugin.getImageDescriptor("ovr16/r_outdel_ov.gif"); //$NON-NLS-1$
fgImages[Differencer.LEFT + Differencer.CHANGE]= CompareUIPlugin.getImageDescriptor("ovr16/r_inchg_ov.gif"); //$NON-NLS-1$
fgImages[Differencer.RIGHT + Differencer.CHANGE]= CompareUIPlugin.getImageDescriptor("ovr16/r_outchg_ov.gif"); //$NON-NLS-1$
} else {
fgImages[Differencer.ADDITION]= CompareUIPlugin.getImageDescriptor("ovr16/add_ov.gif"); //$NON-NLS-1$
fgImages[Differencer.LEFT + Differencer.ADDITION]= CompareUIPlugin.getImageDescriptor("ovr16/inadd_ov.gif"); //$NON-NLS-1$
fgImages[Differencer.RIGHT + Differencer.ADDITION]= CompareUIPlugin.getImageDescriptor("ovr16/outadd_ov.gif"); //$NON-NLS-1$
fgImages[Differencer.DELETION]= CompareUIPlugin.getImageDescriptor("ovr16/del_ov.gif"); //$NON-NLS-1$
fgImages[Differencer.LEFT + Differencer.DELETION]= CompareUIPlugin.getImageDescriptor("ovr16/indel_ov.gif"); //$NON-NLS-1$
fgImages[Differencer.RIGHT + Differencer.DELETION]= CompareUIPlugin.getImageDescriptor("ovr16/outdel_ov.gif"); //$NON-NLS-1$
fgImages[Differencer.LEFT + Differencer.CHANGE]= CompareUIPlugin.getImageDescriptor("ovr16/inchg_ov.gif"); //$NON-NLS-1$
fgImages[Differencer.RIGHT + Differencer.CHANGE]= CompareUIPlugin.getImageDescriptor("ovr16/outchg_ov.gif"); //$NON-NLS-1$
}
fgImages[Differencer.CONFLICTING + Differencer.ADDITION]= CompareUIPlugin.getImageDescriptor("ovr16/confadd_ov.gif"); //$NON-NLS-1$
fgImages[Differencer.CONFLICTING + Differencer.DELETION]= CompareUIPlugin.getImageDescriptor("ovr16/confdel_ov.gif"); //$NON-NLS-1$
fgImages[Differencer.CONFLICTING + Differencer.CHANGE]= CompareUIPlugin.getImageDescriptor("ovr16/confchg_ov.gif"); //$NON-NLS-1$
// ImageDescriptor tmp= fgImages[Differencer.ADDITION];
// fgImages[Differencer.ADDITION]= fgImages[Differencer.DELETION];
// fgImages[Differencer.DELETION]= tmp;
}
private IPreferenceStore fPreferenceStore;
private ListenerList fListeners= new ListenerList();
private HashMap fProperties= new HashMap();
private boolean fLeftEditable= true;
private boolean fRightEditable= true;
private String fAncestorLabel;
private String fLeftLabel;
private String fRightLabel;
private Image fAncestorImage;
private Image fRightImage;
private Image fLeftImage;
private Image[] fImages= new Image[16];
/**
* Creates a new configuration with editable left and right sides,
* suitable default labels, and no images.
*/
public CompareConfiguration(IPreferenceStore prefStore) {
setProperty("LEFT_IS_LOCAL", new Boolean(fLeftIsLocal)); //$NON-NLS-1$
fPreferenceStore= prefStore;
if (fPreferenceStore != null) {
boolean b= fPreferenceStore.getBoolean(ComparePreferencePage.INITIALLY_SHOW_ANCESTOR_PANE);
setProperty(ComparePreferencePage.INITIALLY_SHOW_ANCESTOR_PANE, new Boolean(b));
}
}
/**
* Creates a new configuration with editable left and right sides,
* suitable default labels, and no images.
*/
public CompareConfiguration() {
this(CompareUIPlugin.getDefault().getPreferenceStore());
}
/**
* Returns the preference store of this configuration.
* @return the preference store of this configuration.
*/
public IPreferenceStore getPreferenceStore() {
return fPreferenceStore;
}
/**
* Returns an image showing the specified change kind.
* The different kind of changes are defined in the <code>Differencer</code>.
* Newly created images are remembered by this class and
* disposed when the <code>dispose</code> method is called.
*
* @param kind the kind of change as defined in <code>Differencer</code>.
* @return an modification of the base image reflecting the kind of change.
* @see org.eclipse.compare.structuremergeviewer.Differencer
*/
public Image getImage(int kind) {
Image image= fImages[kind & 15];
if (image == null) {
ImageDescriptor id= fgImages[kind & 15];
if (id != null)
image= id.createImage();
fImages[kind & 15]= image;
}
return image;
}
/**
* Returns an image showing the specified change kind applied to a
* given base image. The different kind of changes are defined in the <code>Differencer</code>.
* Typically an implementation would build a composite image
* from the given base image and an image representing the change kind.
* Newly created images are remembered by this class and
* disposed when the <code>dispose</code> method is called.
*
* @param base the image which is modified to reflect the kind of change
* @param kind the kind of change as defined in <code>Differencer</code>.
* @return an modification of the base image reflecting the kind of change.
* @see org.eclipse.compare.structuremergeviewer.Differencer
*/
public Image getImage(Image base, int kind) {
Object key= base;
if (key == null)
key= fgDummy;
kind &= 15;
Image[] a= (Image[]) fgMap.get(key);
if (a == null) {
a= new Image[16];
fgMap.put(key, a);
}
Image b= a[kind];
if (b == null) {
b= new DiffImage(base, fgImages[kind], WIDTH, !fLeftIsLocal).createImage();
CompareUI.disposeOnShutdown(b);
a[kind]= b;
}
return b;
}
/**
* Dispose of this compare configuration.
* This method is called if the compare configuration is no longer used.
* An implementation must dispose of all resources.
*/
public void dispose() {
}
/**
* Fires a <code>PropertyChangeEvent</code> to registered listeners.
*
* @param propertyName the name of the property that has changed
* @param oldValue the property's old value
* @param newValue the property's new value
*/
private void fireChange(String propertyName, Object oldValue, Object newValue) {
PropertyChangeEvent event= null;
Object[] listeners= fListeners.getListeners();
if (listeners != null) {
for (int i= 0; i < listeners.length; i++) {
IPropertyChangeListener l= (IPropertyChangeListener) listeners[i];
if (event == null)
event= new PropertyChangeEvent(this, propertyName, oldValue, newValue);
l.propertyChange(event);
}
}
}
/* (non javadoc)
* see IPropertyChangeNotifier.addListener
*/
public void addPropertyChangeListener(IPropertyChangeListener listener) {
fListeners.add(listener);
}
/* (non javadoc)
* see IPropertyChangeNotifier.removeListener
*/
public void removePropertyChangeListener(IPropertyChangeListener listener) {
fListeners.remove(listener);
}
/**
* Sets the property with the given name.
* If the new value differs from the old a <code>PropertyChangeEvent</code>
* is sent to registered listeners.
*
* @param propertyName the name of the property to set
* @param value the new value of the property
*/
public void setProperty(String key, Object newValue) {
Object oldValue= fProperties.get(key);
fProperties.put(key, newValue);
if (oldValue == null || !oldValue.equals(newValue))
fireChange(key, oldValue, newValue);
}
/**
* Returns the property with the given name, or <code>null</code>
* if no such property exists.
*
* @param propertyName the name of the property to retrieve
* @return the property with the given name, or <code>null</code> if not found
*/
public Object getProperty(String key) {
return fProperties.get(key);
}
//---- ancestor
/**
* Sets the label to use for the ancestor of compare/merge viewers.
*
* @param label the new label for the ancestor of compare/merge viewers
*/
public void setAncestorLabel(String label) {
fAncestorLabel= label;
}
/**
* Returns the label for the ancestor side of compare/merge viewers.
* This label is typically shown in the title of the ancestor area in a compare viewer.
*
* @param element the input object of a compare/merge viewer or <code>null</code>
* @return the label for the ancestor side or <code>null</code>
*/
public String getAncestorLabel(Object element) {
return fAncestorLabel;
}
/**
* Sets the image to use for the ancestor of compare/merge viewers.
* The CompareConfiguration does not automatically dispose the old image.
*
* @param image the new image for the ancestor of compare/merge viewers
*/
public void setAncestorImage(Image image) {
fAncestorImage= image;
}
/**
* Returns the image for the ancestor side of compare/merge viewers.
* This image is typically shown in the title of the ancestor area in a compare viewer.
*
* @param element the input object of a compare/merge viewer or <code>null</code>
* @return the image for the ancestor side or <code>null</code>
*/
public Image getAncestorImage(Object element) {
return fAncestorImage;
}
//---- left side
/**
* Controls whether the left side of a merge viewer is editable.
*
* @param editable if the value is <code>true</code> left side is editable
*/
public void setLeftEditable(boolean editable) {
fLeftEditable= editable;
}
/**
* Returns whether the left hand side of a merge viewer is editable.
*
* @return <code>true</code> if the left hand side is editable
*/
public boolean isLeftEditable() {
return fLeftEditable;
}
/**
* Sets the label to use for the left side of compare/merge viewers.
*
* @param label the new label for the left side of compare/merge viewers
*/
public void setLeftLabel(String label) {
fLeftLabel= label;
}
/**
* Returns the label for the left hand side of compare/merge viewers.
* This label is typically shown in the title of the left side of a compare viewer.
*
* @param element the input object of a compare/merge viewer or <code>null</code>
* @return the label for the left hand side or <code>null</code>
*/
public String getLeftLabel(Object element) {
return fLeftLabel;
}
/**
* Sets the image to use for the left side of compare/merge viewers.
* The compare configuration does not automatically dispose the old image.
*
* @param image the new image for the left side of compare/merge viewers
*/
public void setLeftImage(Image image) {
fLeftImage= image;
}
/**
* Returns the image for the left hand side of compare/merge viewers.
* This image is typically shown in the title of the left side of a compare viewer.
*
* @param element the input object of a compare/merge viewer or <code>null</code>
* @return the image for the left hand side or <code>null</code>
*/
public Image getLeftImage(Object element) {
return fLeftImage;
}
//---- right side
/**
* Controls whether the right side of a merge viewer is editable.
*
* @param editable if the value is <code>true</code> right side is editable
*/
public void setRightEditable(boolean editable) {
fRightEditable= editable;
}
/**
* Returns whether the right hand side of a merge viewer is editable.
*
* @return <code>true</code> if the right hand side is editable
*/
public boolean isRightEditable() {
return fRightEditable;
}
/**
* Sets the label to use for the right side of compare/merge viewers.
*
* @param label the new label for the right side of compare/merge viewers
*/
public void setRightLabel(String label) {
fRightLabel= label;
}
/**
* Returns the label for the right hand side of compare/merge viewers.
* This label is typically shown in the title of the right side of a compare viewer.
*
* @param element the input object of a compare/merge viewer or <code>null</code>
* @return the label for the right hand side or <code>null</code>
*/
public String getRightLabel(Object element) {
return fRightLabel;
}
/**
* Sets the image to use for the right side of compare/merge viewers.
* The compare configuration does not automatically dispose the old image.
*
* @param image the new image for the right side of compare/merge viewers
*/
public void setRightImage(Image image) {
fRightImage= image;
}
/**
* Returns the image for the right hand side of compare/merge viewers.
* This image is typically shown in the title of the right side of a compare viewer.
*
* @param element the input object of a compare/merge viewer or <code>null</code>
* @return the image for the right hand side or <code>null</code>
*/
public Image getRightImage(Object element) {
return fRightImage;
}
}