blob: 6d6bbb23cc92b02e97f311eca251edc7b1e32e73 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ui.internal.colors;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.ResourceBundle;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.preference.ColorSelector;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.resource.StringConverter;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.ListViewer;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
/**
* Preference page for management of system colors defined in the
* <code>org.eclipse.ui.colorDefinitions</code> extension point.
*
* @since 3.0
*/
public class ColorsPreferencePage
extends PreferencePage
implements IWorkbenchPreferencePage {
/**
* Comparator used in <code>ColorDefinition</code> [] searching.
*/
private static final Comparator COMPARATOR = new Comparator() {
/* (non-Javadoc)
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
public int compare(Object arg0, Object arg1) {
String str0 = getCompareString(arg0);
String str1 = getCompareString(arg1);
return str0.compareTo(str1);
}
/**
* @param object
* @return <code>String</code> representation of the object.
*/
private String getCompareString(Object object) {
if (object instanceof String)
return (String) object;
else
return ((ColorDefinition) object).getId();
}
};
/**
* The translation bundle in which to look up internationalized text.
*/
private final static ResourceBundle RESOURCE_BUNDLE =
ResourceBundle.getBundle(ColorsPreferencePage.class.getName());
private ListViewer colorList;
private ColorSelector colorSelector;
private Text commentText;
private Text descriptionText;
private Button resetButton;
/**
* Map of defintion id->RGB objects that map to changes expressed in this
* UI session.
*/
private Map valuesToSet = new HashMap(7);
/**
* Create a new instance of the receiver.
*/
public ColorsPreferencePage() {
}
/**
* Create the color selection control.
*
* @param parent the parent <code>Composite</code>.
*/
private void createColorControl(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout(2, false);
layout.marginHeight = 0;
layout.marginWidth = 0;
composite.setLayout(layout);
Label label = new Label(composite, SWT.LEFT);
label.setText(RESOURCE_BUNDLE.getString("ColorsPreferencePage.value")); //$NON-NLS-1$
Dialog.applyDialogFont(label);
GridData data = new GridData(GridData.FILL_HORIZONTAL);
data.horizontalSpan = 2;
label.setLayoutData(data);
colorSelector = new ColorSelector(composite);
colorSelector.getButton().setLayoutData(new GridData());
colorSelector.setEnabled(false);
resetButton = new Button(composite, SWT.PUSH);
resetButton.setText(RESOURCE_BUNDLE.getString("ColorsPreferencePage.reset")); //$NON-NLS-1$
resetButton.setEnabled(false);
}
/**
* Create the <code>ListViewer</code> that will contain all color
* definitions as defined in the extension point.
*
* @param parent the parent <code>Composite</code>.
*/
private void createColorList(Composite parent) {
Composite composite = new Composite(parent, SWT.NULL);
GridLayout layout = new GridLayout();
layout.marginWidth = 0;
layout.marginHeight = 0;
composite.setLayout(layout);
GridData data = new GridData(GridData.FILL_BOTH);
data.grabExcessHorizontalSpace = true;
composite.setLayoutData(data);
Label label = new Label(composite, SWT.LEFT);
label.setText(RESOURCE_BUNDLE.getString("ColorsPreferencePage.colors")); //$NON-NLS-1$
Dialog.applyDialogFont(label);
colorList =
new ListViewer(
composite,
SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
colorList.setContentProvider(new ArrayContentProvider());
colorList.setInput(ColorDefinition.getDefinitions());
colorList.setLabelProvider(new LabelProvider() {
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
*/
public String getText(Object element) {
return ((ColorDefinition) element).getLabel();
}
});
colorList.getControl().setFont(JFaceResources.getViewerFont());
data =
new GridData(
GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_BOTH);
data.grabExcessHorizontalSpace = true;
colorList.getControl().setLayoutData(data);
}
/**
* Create the text box that will contain the current colors comment text
* (if any). This includes whether the color is set to its default value or
* and what that might be in the case of a mapping.
*
* @param parent the parent <code>Composite</code>.
*/
private void createCommentControl(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.marginWidth = 0;
layout.marginHeight = 0;
composite.setLayout(layout);
GridData data = new GridData(GridData.FILL_BOTH);
composite.setLayoutData(data);
Label label = new Label(composite, SWT.LEFT);
label.setText(RESOURCE_BUNDLE.getString("ColorsPreferencePage.comment")); //$NON-NLS-1$
Dialog.applyDialogFont(label);
commentText =
new Text(composite, SWT.READ_ONLY | SWT.BORDER | SWT.WRAP);
commentText.setLayoutData(new GridData(GridData.FILL_BOTH));
}
/* (non-Javadoc)
* @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)
*/
protected Control createContents(Composite parent) {
Composite mainColumn = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.numColumns = 2;
layout.marginWidth = 0;
layout.marginHeight = 0;
mainColumn.setFont(parent.getFont());
mainColumn.setLayout(layout);
createColorList(mainColumn);
Composite controlColumn = new Composite(mainColumn, SWT.NONE);
controlColumn.setLayoutData(new GridData(GridData.FILL_BOTH));
layout = new GridLayout();
layout.marginHeight = 0;
layout.marginWidth = 0;
controlColumn.setLayout(layout);
createColorControl(controlColumn);
createCommentControl(controlColumn);
createDescriptionControl(mainColumn);
hookListeners();
return mainColumn;
}
/**
* Create the text box that will contain the current colors description
* text (if any).
*
* @param parent the parent <code>Composite</code>.
*/
private void createDescriptionControl(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.marginWidth = 0;
layout.marginHeight = 0;
composite.setLayout(layout);
GridData data = new GridData(GridData.FILL_BOTH);
data.horizontalSpan = 2;
composite.setLayoutData(data);
Label label = new Label(composite, SWT.LEFT);
label.setText(RESOURCE_BUNDLE.getString("ColorsPreferencePage.description")); //$NON-NLS-1$
Dialog.applyDialogFont(label);
descriptionText =
new Text(composite, SWT.READ_ONLY | SWT.BORDER | SWT.WRAP);
data = new GridData(GridData.FILL_BOTH);
descriptionText.setLayoutData(data);
}
/**
* Hook all control listeners.
*/
private void hookListeners() {
colorSelector.addListener(new IPropertyChangeListener() {
/* (non-Javadoc)
* @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
*/
public void propertyChange(PropertyChangeEvent event) {
ColorDefinition definition =
(ColorDefinition) ((IStructuredSelection) colorList
.getSelection())
.getFirstElement();
RGB newRGB = (RGB) event.getNewValue();
if (definition != null && newRGB != null) {
valuesToSet.put(definition.getId(), newRGB);
}
updateControls(definition);
}
});
colorList.addSelectionChangedListener(new ISelectionChangedListener() {
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
*/
public void selectionChanged(SelectionChangedEvent event) {
if (event.getSelection().isEmpty()) {
updateControls(null);
} else {
updateControls(
(ColorDefinition) ((IStructuredSelection) event
.getSelection())
.getFirstElement());
}
}
});
resetButton.addSelectionListener(new SelectionAdapter() {
/* (non-Javadoc)
* @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
*/
public void widgetSelected(SelectionEvent e) {
ColorDefinition definition =
(ColorDefinition) ((IStructuredSelection) colorList
.getSelection())
.getFirstElement();
if (resetColor(definition))
updateControls(definition);
}
});
}
/* (non-Javadoc)
* @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
*/
public void init(IWorkbench workbench) {
setPreferenceStore(workbench.getPreferenceStore());
}
/**
* Answers whether the definition is currently set to the default value.
*
* @param definition the <code>ColorDefinition</code> to check.
* @return Return whether the definition is currently mapped to the default
* value, either in the preference store or in the local change record
* of this preference page.
*/
private boolean isDefault(ColorDefinition definition) {
String id = definition.getId();
if (valuesToSet.containsKey(id)) {
if (valuesToSet
.get(id)
.equals(
StringConverter.asRGB(
getPreferenceStore().getDefaultString(id),
null)))
return true;
return false;
}
if (getPreferenceStore().isDefault(id))
return true;
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jface.preference.PreferencePage#performDefaults()
*/
protected void performDefaults() {
ColorDefinition[] definitions = ColorDefinition.getDefinitions();
for (int i = 0; i < definitions.length; i++) {
resetColor(definitions[i]);
}
updateControls(
(ColorDefinition) ((IStructuredSelection) colorList.getSelection())
.getFirstElement());
}
/* (non-Javadoc)
* @see org.eclipse.jface.preference.IPreferencePage#performOk()
*/
public boolean performOk() {
for (Iterator i = valuesToSet.keySet().iterator(); i.hasNext();) {
String id = (String) i.next();
RGB rgb = (RGB) valuesToSet.get(id);
String rgbString = StringConverter.asString(rgb);
String storeString = getPreferenceStore().getString(id);
if (!rgbString.equals(storeString)) {
JFaceResources.getColorRegistry().put(id, rgb);
getPreferenceStore().setValue(id, rgbString);
}
}
valuesToSet.clear();
return true;
}
/**
* Resets the supplied definition to its default value.
*
* @param definition the <code>ColorDefinition</code> to reset.
* @return whether any change was made.
*/
private boolean resetColor(ColorDefinition definition) {
if (!isDefault(definition)) {
RGB newRGB =
StringConverter.asRGB(
getPreferenceStore().getDefaultString(definition.getId()),
null);
if (newRGB != null) {
valuesToSet.put(definition.getId(), newRGB);
return true;
}
}
return false;
}
/**
* Update the color controls based on the supplied definition.
*
* @param definition The currently selected <code>ColorDefinition</code>.
*/
private void updateControls(ColorDefinition definition) {
if (definition != null) {
RGB updatedRGB = (RGB) valuesToSet.get(definition.getId());
if (updatedRGB == null)
updatedRGB =
JFaceResources.getColorRegistry().getRGB(
definition.getId());
colorSelector.setColorValue(updatedRGB);
}
if (definition != null) {
resetButton.setEnabled(true);
colorSelector.setEnabled(true);
if (isDefault(definition)) {
if (definition.getDefaultsTo() != null) {
int idx =
Arrays.binarySearch(
ColorDefinition.getDefinitions(),
definition.getDefaultsTo(),
COMPARATOR);
if (idx >= 0) {
commentText.setText(MessageFormat.format(RESOURCE_BUNDLE.getString("ColorsPreferencePage.currentlyMappedTo"), //$NON-NLS-1$
new Object[] {
ColorDefinition
.getDefinitions()[idx]
.getLabel()}));
} else
commentText.setText(""); //$NON-NLS-1$
} else
commentText.setText(RESOURCE_BUNDLE.getString("ColorsPreferencePage.currentlyDefault")); //$NON-NLS-1$
} else
commentText.setText(RESOURCE_BUNDLE.getString("ColorsPreferencePage.customValue")); //$NON-NLS-1$
String description = definition.getDescription();
descriptionText.setText(description == null ? "" : description); //$NON-NLS-1$
} else {
resetButton.setEnabled(false);
colorSelector.setEnabled(false);
commentText.setText(""); //$NON-NLS-1$
descriptionText.setText(""); //$NON-NLS-1$
}
}
}