blob: 7e702bd6e05d327303f3b8de2dd3fd7a3e558165 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2005 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.jdt.internal.ui.preferences;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;
import org.eclipse.jdt.internal.corext.util.Messages;
import org.eclipse.jdt.ui.PreferenceConstants;
import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
import org.eclipse.jdt.internal.ui.dialogs.StatusInfo;
import org.eclipse.jdt.internal.ui.dialogs.StatusUtil;
import org.eclipse.jdt.internal.ui.text.spelling.SpellCheckEngine;
import org.eclipse.jdt.internal.ui.util.PixelConverter;
import org.eclipse.jdt.internal.ui.util.SWTUtil;
import org.eclipse.jdt.internal.ui.wizards.IStatusChangeListener;
/**
* Options configuration block for spell-check related settings.
*
* @since 3.0
*/
public class SpellingConfigurationBlock extends OptionsConfigurationBlock {
/** Preference keys for the preferences in this block */
private static final Key PREF_SPELLING_IGNORE_DIGITS= getJDTUIKey(PreferenceConstants.SPELLING_IGNORE_DIGITS);
private static final Key PREF_SPELLING_IGNORE_MIXED= getJDTUIKey(PreferenceConstants.SPELLING_IGNORE_MIXED);
private static final Key PREF_SPELLING_IGNORE_SENTENCE= getJDTUIKey(PreferenceConstants.SPELLING_IGNORE_SENTENCE);
private static final Key PREF_SPELLING_IGNORE_UPPER= getJDTUIKey(PreferenceConstants.SPELLING_IGNORE_UPPER);
private static final Key PREF_SPELLING_IGNORE_URLS= getJDTUIKey(PreferenceConstants.SPELLING_IGNORE_URLS);
private static final Key PREF_SPELLING_LOCALE= getJDTUIKey(PreferenceConstants.SPELLING_LOCALE);
private static final Key PREF_SPELLING_PROPOSAL_THRESHOLD= getJDTUIKey(PreferenceConstants.SPELLING_PROPOSAL_THRESHOLD);
private static final Key PREF_SPELLING_USER_DICTIONARY= getJDTUIKey(PreferenceConstants.SPELLING_USER_DICTIONARY);
private static final Key PREF_SPELLING_ENABLE_CONTENTASSIST= getJDTUIKey(PreferenceConstants.SPELLING_ENABLE_CONTENTASSIST);
/**
* Creates a selection dependency between a master and a slave control.
*
* @param master
* The master button that controls the state of the slave
* @param slave
* The slave control that is enabled only if the master is
* selected
*/
protected static void createSelectionDependency(final Button master, final Control slave) {
master.addSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent event) {
// Do nothing
}
public void widgetSelected(SelectionEvent event) {
slave.setEnabled(master.getSelection());
}
});
slave.setEnabled(master.getSelection());
}
/**
* Returns the locale codes for the locale list.
*
* @param locales
* The list of locales
* @return Array of locale codes for the list
*/
protected static String[] getDictionaryCodes(final Set locales) {
int index= 0;
Locale locale= null;
final String[] codes= new String[locales.size()];
for (final Iterator iterator= locales.iterator(); iterator.hasNext();) {
locale= (Locale)iterator.next();
codes[index++]= locale.toString();
}
return codes;
}
/**
* Returns the display labels for the locale list.
*
* @param locales
* The list of locales
* @return Array of display labels for the list
*/
protected static String[] getDictionaryLabels(final Set locales) {
int index= 0;
Locale locale= null;
final String[] labels= new String[locales.size()];
for (final Iterator iterator= locales.iterator(); iterator.hasNext();) {
locale= (Locale)iterator.next();
labels[index++]= locale.getDisplayName();
}
return labels;
}
/**
* Validates that the file with the specified absolute path exists and can
* be opened.
*
* @param path
* The path of the file to validate
* @return <code>true</code> iff the file exists and can be opened,
* <code>false</code> otherwise
*/
protected static IStatus validateAbsoluteFilePath(final String path) {
final StatusInfo status= new StatusInfo();
if (path.length() > 0) {
final File file= new File(path);
if (!file.isFile() || !file.isAbsolute() || !file.exists() || !file.canRead() || !file.canWrite())
status.setError(PreferencesMessages.SpellingPreferencePage_dictionary_error);
}
return status;
}
/**
* Validates that the specified locale is available.
*
* @param locale
* The locale to validate
* @return The status of the validation
*/
protected static IStatus validateLocale(final String locale) {
final StatusInfo status= new StatusInfo(IStatus.ERROR, PreferencesMessages.SpellingPreferencePage_locale_error);
final Set locales= SpellCheckEngine.getAvailableLocales();
Locale current= null;
for (final Iterator iterator= locales.iterator(); iterator.hasNext();) {
current= (Locale)iterator.next();
if (current.toString().equals(locale))
return new StatusInfo();
}
return status;
}
/**
* Validates that the specified number is positive.
*
* @param number
* The number to validate
* @return The status of the validation
*/
protected static IStatus validatePositiveNumber(final String number) {
final StatusInfo status= new StatusInfo();
if (number.length() == 0) {
status.setError(PreferencesMessages.SpellingPreferencePage_empty_threshold);
} else {
try {
final int value= Integer.parseInt(number);
if (value < 0) {
status.setError(Messages.format(PreferencesMessages.SpellingPreferencePage_invalid_threshold, number));
}
} catch (NumberFormatException exception) {
status.setError(Messages.format(PreferencesMessages.SpellingPreferencePage_invalid_threshold, number));
}
}
return status;
}
/** The dictionary path field */
private Text fDictionaryPath= null;
/** The status for the workspace dictionary file */
private IStatus fFileStatus= new StatusInfo();
/** The status for the proposal threshold */
private IStatus fThresholdStatus= new StatusInfo();
/**
* All controls
* @since 3.1
*/
private Control[] fAllControls;
/**
* All previously enabled controls
* @since 3.1
*/
private Control[] fEnabledControls;
/**
* Creates a new spelling configuration block.
*
* @param context
* The status change listener
* @param project
* The Java project
*/
public SpellingConfigurationBlock(final IStatusChangeListener context, final IProject project, IWorkbenchPreferenceContainer container) {
super(context, project, getAllKeys(), container);
IStatus status= validateAbsoluteFilePath(getValue(PREF_SPELLING_USER_DICTIONARY));
if (status.getSeverity() != IStatus.OK)
setValue(PREF_SPELLING_USER_DICTIONARY, ""); //$NON-NLS-1$
status= validateLocale(getValue(PREF_SPELLING_LOCALE));
if (status.getSeverity() != IStatus.OK)
setValue(PREF_SPELLING_LOCALE, SpellCheckEngine.getDefaultLocale().toString());
}
protected Combo addComboBox(Composite parent, String label, Key key, String[] values, String[] valueLabels, int indent) {
ControlData data= new ControlData(key, values);
GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
gd.horizontalIndent= indent;
Label labelControl= new Label(parent, SWT.LEFT | SWT.WRAP);
labelControl.setText(label);
labelControl.setLayoutData(gd);
Combo comboBox= new Combo(parent, SWT.READ_ONLY);
comboBox.setItems(valueLabels);
comboBox.setData(data);
gd= new GridData(GridData.HORIZONTAL_ALIGN_FILL);
gd.horizontalSpan= 2;
comboBox.setLayoutData(gd);
comboBox.addSelectionListener(getSelectionListener());
fLabels.put(comboBox, labelControl);
String currValue= getValue(key);
comboBox.select(data.getSelection(currValue));
fComboBoxes.add(comboBox);
return comboBox;
}
/*
* @see org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock#createContents(org.eclipse.swt.widgets.Composite)
*/
protected Control createContents(final Composite parent) {
Composite composite= new Composite(parent, SWT.NONE);
composite.setLayout(new GridLayout());
List allControls= new ArrayList();
final PixelConverter converter= new PixelConverter(parent);
final String[] trueFalse= new String[] { IPreferenceStore.TRUE, IPreferenceStore.FALSE };
Group user= new Group(composite, SWT.NONE);
user.setText(PreferencesMessages.SpellingPreferencePage_preferences_user);
user.setLayout(new GridLayout());
user.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
allControls.add(user);
String label= PreferencesMessages.SpellingPreferencePage_ignore_digits_label;
Control slave= addCheckBox(user, label, PREF_SPELLING_IGNORE_DIGITS, trueFalse, 0);
allControls.add(slave);
label= PreferencesMessages.SpellingPreferencePage_ignore_mixed_label;
slave= addCheckBox(user, label, PREF_SPELLING_IGNORE_MIXED, trueFalse, 0);
allControls.add(slave);
label= PreferencesMessages.SpellingPreferencePage_ignore_sentence_label;
slave= addCheckBox(user, label, PREF_SPELLING_IGNORE_SENTENCE, trueFalse, 0);
allControls.add(slave);
label= PreferencesMessages.SpellingPreferencePage_ignore_upper_label;
slave= addCheckBox(user, label, PREF_SPELLING_IGNORE_UPPER, trueFalse, 0);
allControls.add(slave);
label= PreferencesMessages.SpellingPreferencePage_ignore_url_label;
slave= addCheckBox(user, label, PREF_SPELLING_IGNORE_URLS, trueFalse, 0);
allControls.add(slave);
final Group engine= new Group(composite, SWT.NONE);
engine.setText(PreferencesMessages.SpellingPreferencePage_preferences_engine);
engine.setLayout(new GridLayout(4, false));
engine.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
allControls.add(engine);
label= PreferencesMessages.SpellingPreferencePage_dictionary_label;
final Set locales= SpellCheckEngine.getAvailableLocales();
Combo combo= addComboBox(engine, label, PREF_SPELLING_LOCALE, getDictionaryCodes(locales), getDictionaryLabels(locales), 0);
combo.setEnabled(locales.size() > 1);
allControls.add(combo);
allControls.add(fLabels.get(combo));
new Label(engine, SWT.NONE); // placeholder
label= PreferencesMessages.SpellingPreferencePage_workspace_dictionary_label;
fDictionaryPath= addTextField(engine, label, PREF_SPELLING_USER_DICTIONARY, 0, 0);
GridData gd= (GridData) fDictionaryPath.getLayoutData();
gd.grabExcessHorizontalSpace= true;
gd.widthHint= converter.convertWidthInCharsToPixels(40);
allControls.add(fDictionaryPath);
allControls.add(fLabels.get(fDictionaryPath));
Button button= new Button(engine, SWT.PUSH);
button.setText(PreferencesMessages.SpellingPreferencePage_browse_label);
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(final SelectionEvent event) {
handleBrowseButtonSelected();
}
});
button.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
SWTUtil.setButtonDimensionHint(button);
allControls.add(button);
Group advanced= new Group(composite, SWT.NONE);
advanced.setText(PreferencesMessages.SpellingPreferencePage_preferences_advanced);
advanced.setLayout(new GridLayout(3, false));
advanced.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
allControls.add(advanced);
label= PreferencesMessages.SpellingPreferencePage_proposals_threshold;
Text text= addTextField(advanced, label, PREF_SPELLING_PROPOSAL_THRESHOLD, 0, 0);
text.setTextLimit(3);
gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
gd.widthHint= converter.convertWidthInCharsToPixels(4);
text.setLayoutData(gd);
allControls.add(text);
allControls.add(fLabels.get(text));
label= PreferencesMessages.SpellingPreferencePage_enable_contentassist_label;
button= addCheckBox(advanced, label, PREF_SPELLING_ENABLE_CONTENTASSIST, trueFalse, 0);
allControls.add(button);
fAllControls= (Control[]) allControls.toArray(new Control[allControls.size()]);
PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, IJavaHelpContextIds.JAVA_EDITOR_PREFERENCE_PAGE);
return composite;
}
private static Key[] getAllKeys() {
return new Key[] { PREF_SPELLING_USER_DICTIONARY, PREF_SPELLING_IGNORE_DIGITS, PREF_SPELLING_IGNORE_MIXED, PREF_SPELLING_IGNORE_SENTENCE, PREF_SPELLING_IGNORE_UPPER, PREF_SPELLING_IGNORE_URLS, PREF_SPELLING_LOCALE, PREF_SPELLING_PROPOSAL_THRESHOLD, PREF_SPELLING_ENABLE_CONTENTASSIST };
}
/*
* @see org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock#getFullBuildDialogStrings(boolean)
*/
protected final String[] getFullBuildDialogStrings(final boolean workspace) {
return null;
}
/**
* Handles selections of the browse button.
*/
protected void handleBrowseButtonSelected() {
final FileDialog dialog= new FileDialog(fDictionaryPath.getShell(), SWT.OPEN);
dialog.setText(PreferencesMessages.SpellingPreferencePage_filedialog_title);
dialog.setFilterExtensions(new String[] { PreferencesMessages.SpellingPreferencePage_filter_dictionary_extension, PreferencesMessages.SpellingPreferencePage_filter_all_extension });
dialog.setFilterNames(new String[] { PreferencesMessages.SpellingPreferencePage_filter_dictionary_label, PreferencesMessages.SpellingPreferencePage_filter_all_label });
final String path= dialog.open();
if (path != null)
fDictionaryPath.setText(path);
}
/*
* @see org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock#validateSettings(java.lang.String,java.lang.String)
*/
protected void validateSettings(final Key key, final String oldValue, final String newValue) {
if (key == null || PREF_SPELLING_PROPOSAL_THRESHOLD.equals(key))
fThresholdStatus= validatePositiveNumber(getValue(PREF_SPELLING_PROPOSAL_THRESHOLD));
if (key == null || PREF_SPELLING_USER_DICTIONARY.equals(key))
fFileStatus= validateAbsoluteFilePath(getValue(PREF_SPELLING_USER_DICTIONARY));
fContext.statusChanged(StatusUtil.getMostSevere(new IStatus[] { fThresholdStatus, fFileStatus }));
}
/*
* @see org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock#updateCheckBox(org.eclipse.swt.widgets.Button)
* @since 3.1
*/
protected void updateCheckBox(Button curr) {
super.updateCheckBox(curr);
Event event= new Event();
event.type= SWT.Selection;
event.display= curr.getDisplay();
event.widget= curr;
curr.notifyListeners(SWT.Selection, event);
}
/**
* @since 3.1
*/
protected void setEnabled(boolean enabled) {
if (enabled && fEnabledControls != null) {
for (int i= fEnabledControls.length - 1; i >= 0; i--)
fEnabledControls[i].setEnabled(true);
fEnabledControls= null;
}
if (!enabled && fEnabledControls == null) {
List enabledControls= new ArrayList();
for (int i= fAllControls.length - 1; i >= 0; i--) {
Control control= fAllControls[i];
if (control.isEnabled()) {
enabledControls.add(control);
control.setEnabled(false);
}
}
fEnabledControls= (Control[]) enabledControls.toArray(new Control[enabledControls.size()]);
}
}
}