1 /*******************************************************************************
2 * Copyright (c) 2000, 2003 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
12 package net.sourceforge.phpdt.internal.ui.preferences;
15 import java.util.HashMap;
16 import java.util.Iterator;
17 import java.util.Locale;
21 import net.sourceforge.phpdt.core.IJavaProject;
22 import net.sourceforge.phpdt.internal.ui.dialogs.StatusInfo;
23 import net.sourceforge.phpdt.internal.ui.dialogs.StatusUtil;
24 import net.sourceforge.phpdt.internal.ui.text.spelling.SpellCheckEngine;
25 import net.sourceforge.phpdt.internal.ui.util.PixelConverter;
26 import net.sourceforge.phpdt.internal.ui.util.SWTUtil;
27 import net.sourceforge.phpdt.internal.ui.wizards.IStatusChangeListener;
28 import net.sourceforge.phpdt.ui.PreferenceConstants;
30 import org.eclipse.core.runtime.IStatus;
31 import org.eclipse.jface.preference.IPreferenceStore;
32 import org.eclipse.swt.SWT;
33 import org.eclipse.swt.events.SelectionAdapter;
34 import org.eclipse.swt.events.SelectionEvent;
35 import org.eclipse.swt.events.SelectionListener;
36 import org.eclipse.swt.layout.GridData;
37 import org.eclipse.swt.layout.GridLayout;
38 import org.eclipse.swt.widgets.Button;
39 import org.eclipse.swt.widgets.Combo;
40 import org.eclipse.swt.widgets.Composite;
41 import org.eclipse.swt.widgets.Control;
42 import org.eclipse.swt.widgets.FileDialog;
43 import org.eclipse.swt.widgets.Group;
44 import org.eclipse.swt.widgets.Label;
45 import org.eclipse.swt.widgets.Text;
48 * Options configuration block for spell-check related settings.
52 public class SpellingConfigurationBlock extends OptionsConfigurationBlock {
54 /** Preference keys for the preferences in this block */
55 private static final String PREF_SPELLING_CHECK_SPELLING= PreferenceConstants.SPELLING_CHECK_SPELLING;
56 private static final String PREF_SPELLING_IGNORE_DIGITS= PreferenceConstants.SPELLING_IGNORE_DIGITS;
57 private static final String PREF_SPELLING_IGNORE_MIXED= PreferenceConstants.SPELLING_IGNORE_MIXED;
58 private static final String PREF_SPELLING_IGNORE_SENTENCE= PreferenceConstants.SPELLING_IGNORE_SENTENCE;
59 private static final String PREF_SPELLING_IGNORE_UPPER= PreferenceConstants.SPELLING_IGNORE_UPPER;
60 private static final String PREF_SPELLING_IGNORE_URLS= PreferenceConstants.SPELLING_IGNORE_URLS;
61 private static final String PREF_SPELLING_LOCALE= PreferenceConstants.SPELLING_LOCALE;
62 private static final String PREF_SPELLING_PROPOSAL_THRESHOLD= PreferenceConstants.SPELLING_PROPOSAL_THRESHOLD;
63 private static final String PREF_SPELLING_USER_DICTIONARY= PreferenceConstants.SPELLING_USER_DICTIONARY;
64 private static final String PREF_SPELLING_ENABLE_CONTENTASSIST= PreferenceConstants.SPELLING_ENABLE_CONTENTASSIST;
67 * Creates a selection dependency between a master and a slave control.
70 * The master button that controls the state of the slave
72 * The slave control that is enabled only if the master is
75 protected static void createSelectionDependency(final Button master, final Control slave) {
77 master.addSelectionListener(new SelectionListener() {
79 public void widgetDefaultSelected(SelectionEvent event) {
83 public void widgetSelected(SelectionEvent event) {
84 slave.setEnabled(master.getSelection());
87 slave.setEnabled(master.getSelection());
91 * Returns the locale codes for the locale list.
95 * @return Array of locale codes for the list
97 protected static String[] getDictionaryCodes(final Set locales) {
102 final String[] codes= new String[locales.size()];
103 for (final Iterator iterator= locales.iterator(); iterator.hasNext();) {
105 locale= (Locale)iterator.next();
106 codes[index++]= locale.toString();
112 * Returns the display labels for the locale list.
115 * The list of locales
116 * @return Array of display labels for the list
118 protected static String[] getDictionaryLabels(final Set locales) {
123 final String[] labels= new String[locales.size()];
124 for (final Iterator iterator= locales.iterator(); iterator.hasNext();) {
126 locale= (Locale)iterator.next();
127 labels[index++]= locale.getDisplayName(SpellCheckEngine.getDefaultLocale());
133 * Validates that the file with the specified absolute path exists and can
137 * The path of the file to validate
138 * @return <code>true</code> iff the file exists and can be opened,
139 * <code>false</code> otherwise
141 protected static IStatus validateAbsoluteFilePath(final String path) {
143 final StatusInfo status= new StatusInfo();
144 if (path.length() > 0) {
146 final File file= new File(path);
147 if (!file.isFile() || !file.isAbsolute() || !file.exists() || !file.canRead() || !file.canWrite())
148 status.setError(PreferencesMessages.getString("SpellingPreferencePage.dictionary.error")); //$NON-NLS-1$
155 * Validates that the specified locale is available.
158 * The locale to validate
159 * @return The status of the validation
161 protected static IStatus validateLocale(final String locale) {
163 final StatusInfo status= new StatusInfo(IStatus.ERROR, PreferencesMessages.getString("SpellingPreferencePage.locale.error")); //$NON-NLS-1$
164 final Set locales= SpellCheckEngine.getAvailableLocales();
166 Locale current= null;
167 for (final Iterator iterator= locales.iterator(); iterator.hasNext();) {
169 current= (Locale)iterator.next();
170 if (current.toString().equals(locale))
171 return new StatusInfo();
177 * Validates that the specified number is positive.
180 * The number to validate
181 * @return The status of the validation
183 protected static IStatus validatePositiveNumber(final String number) {
185 final StatusInfo status= new StatusInfo();
186 if (number.length() == 0) {
187 status.setError(PreferencesMessages.getString("SpellingPreferencePage.empty_threshold")); //$NON-NLS-1$
190 final int value= Integer.parseInt(number);
192 status.setError(PreferencesMessages.getFormattedString("SpellingPreferencePage.invalid_threshold", number)); //$NON-NLS-1$
194 } catch (NumberFormatException exception) {
195 status.setError(PreferencesMessages.getFormattedString("SpellingPreferencePage.invalid_threshold", number)); //$NON-NLS-1$
201 /** The dictionary path field */
202 private Text fDictionaryPath= null;
204 /** The status for the workspace dictionary file */
205 private IStatus fFileStatus= new StatusInfo();
207 /** The status for the platform locale */
208 private IStatus fLocaleStatus= new StatusInfo();
210 /** The status for the proposal threshold */
211 private IStatus fThresholdStatus= new StatusInfo();
214 * Creates a new spelling configuration block.
217 * The status change listener
221 public SpellingConfigurationBlock(final IStatusChangeListener context, final IJavaProject project) {
222 super(context, project, getAllKeys());
224 IStatus status= validateAbsoluteFilePath((String)fWorkingValues.get(PREF_SPELLING_USER_DICTIONARY));
225 if (status.getSeverity() != IStatus.OK)
226 fWorkingValues.put(PREF_SPELLING_USER_DICTIONARY, ""); //$NON-NLS-1$
228 status= validateLocale((String)fWorkingValues.get(PREF_SPELLING_LOCALE));
229 if (status.getSeverity() != IStatus.OK)
230 fWorkingValues.put(PREF_SPELLING_LOCALE, SpellCheckEngine.getDefaultLocale().toString());
233 protected Combo addComboBox(Composite parent, String label, String key, String[] values, String[] valueLabels, int indent) {
234 ControlData data= new ControlData(key, values);
236 GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
237 gd.horizontalIndent= indent;
239 Label labelControl= new Label(parent, SWT.LEFT | SWT.WRAP);
240 labelControl.setText(label);
241 labelControl.setLayoutData(gd);
243 Combo comboBox= new Combo(parent, SWT.READ_ONLY);
244 comboBox.setItems(valueLabels);
245 comboBox.setData(data);
246 gd= new GridData(GridData.HORIZONTAL_ALIGN_FILL);
247 gd.horizontalSpan= 2;
248 comboBox.setLayoutData(gd);
249 comboBox.addSelectionListener(getSelectionListener());
251 fLabels.put(comboBox, labelControl);
253 String currValue= (String)fWorkingValues.get(key);
254 comboBox.select(data.getSelection(currValue));
256 fComboBoxes.add(comboBox);
261 * @see net.sourceforge.phpdt.internal.ui.preferences.OptionsConfigurationBlock#createContents(org.eclipse.swt.widgets.Composite)
263 protected Control createContents(final Composite parent) {
265 Composite composite= new Composite(parent, SWT.NONE);
266 GridLayout layout= new GridLayout(); layout.numColumns= 1;
267 composite.setLayout(layout);
269 final PixelConverter converter= new PixelConverter(parent);
271 layout= new GridLayout();
272 layout.numColumns= 3;
274 final String[] trueFalse= new String[] { IPreferenceStore.TRUE, IPreferenceStore.FALSE };
276 Group user= new Group(composite, SWT.NONE);
277 user.setText(PreferencesMessages.getString("SpellingPreferencePage.preferences.user")); //$NON-NLS-1$
278 user.setLayout(new GridLayout());
279 user.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
281 String label= PreferencesMessages.getString("SpellingPreferencePage.enable.label"); //$NON-NLS-1$
282 final Button master= addCheckBox(user, label, PREF_SPELLING_CHECK_SPELLING, trueFalse, 0);
284 label= PreferencesMessages.getString("SpellingPreferencePage.ignore.digits.label"); //$NON-NLS-1$
285 Control slave= addCheckBox(user, label, PREF_SPELLING_IGNORE_DIGITS, trueFalse, 20);
286 createSelectionDependency(master, slave);
288 label= PreferencesMessages.getString("SpellingPreferencePage.ignore.mixed.label"); //$NON-NLS-1$
289 slave= addCheckBox(user, label, PREF_SPELLING_IGNORE_MIXED, trueFalse, 20);
290 createSelectionDependency(master, slave);
292 label= PreferencesMessages.getString("SpellingPreferencePage.ignore.sentence.label"); //$NON-NLS-1$
293 slave= addCheckBox(user, label, PREF_SPELLING_IGNORE_SENTENCE, trueFalse, 20);
294 createSelectionDependency(master, slave);
296 label= PreferencesMessages.getString("SpellingPreferencePage.ignore.upper.label"); //$NON-NLS-1$
297 slave= addCheckBox(user, label, PREF_SPELLING_IGNORE_UPPER, trueFalse, 20);
298 createSelectionDependency(master, slave);
300 label= PreferencesMessages.getString("SpellingPreferencePage.ignore.url.label"); //$NON-NLS-1$
301 slave= addCheckBox(user, label, PREF_SPELLING_IGNORE_URLS, trueFalse, 20);
302 createSelectionDependency(master, slave);
304 final Group engine= new Group(composite, SWT.NONE);
305 engine.setText(PreferencesMessages.getString("SpellingPreferencePage.preferences.engine")); //$NON-NLS-1$
306 layout= new GridLayout();
307 layout.numColumns= 4;
308 engine.setLayout(layout);
309 engine.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
311 label= PreferencesMessages.getString("SpellingPreferencePage.dictionary.label"); //$NON-NLS-1$
312 final Set locales= SpellCheckEngine.getAvailableLocales();
314 Combo combo= addComboBox(engine, label, PREF_SPELLING_LOCALE, getDictionaryCodes(locales), getDictionaryLabels(locales), 0);
315 combo.setEnabled(locales.size() > 1);
317 new Label(engine, SWT.NONE); // placeholder
319 label= PreferencesMessages.getString("SpellingPreferencePage.workspace.dictionary.label"); //$NON-NLS-1$
320 fDictionaryPath= addTextField(engine, label, PREF_SPELLING_USER_DICTIONARY, 0, 0);
323 Button button= new Button(engine, SWT.PUSH);
324 button.setText(PreferencesMessages.getString("SpellingPreferencePage.browse.label")); //$NON-NLS-1$
325 button.addSelectionListener(new SelectionAdapter() {
327 public void widgetSelected(final SelectionEvent event) {
328 handleBrowseButtonSelected();
331 button.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
332 SWTUtil.setButtonDimensionHint(button);
334 layout= new GridLayout();
335 layout.numColumns= 3;
337 Group advanced= new Group(composite, SWT.NONE);
338 advanced.setText(PreferencesMessages.getString("SpellingPreferencePage.preferences.advanced")); //$NON-NLS-1$
339 layout= new GridLayout();
340 layout.numColumns= 3;
341 advanced.setLayout(layout);
342 advanced.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
344 label= PreferencesMessages.getString("SpellingPreferencePage.proposals.threshold"); //$NON-NLS-1$
345 Text text= addTextField(advanced, label, PREF_SPELLING_PROPOSAL_THRESHOLD, 0, 0);
346 text.setTextLimit(3);
347 GridData data= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
348 data.widthHint= converter.convertWidthInCharsToPixels(4);
349 text.setLayoutData(data);
351 label= PreferencesMessages.getString("SpellingPreferencePage.enable.contentassist.label"); //$NON-NLS-1$
352 addCheckBox(advanced, label, PREF_SPELLING_ENABLE_CONTENTASSIST, trueFalse, 0);
357 private static String[] getAllKeys() {
358 return new String[] { PREF_SPELLING_USER_DICTIONARY, PREF_SPELLING_CHECK_SPELLING, 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 };
362 * @see net.sourceforge.phpdt.internal.ui.preferences.OptionsConfigurationBlock#getDefaultOptions()
364 protected Map getDefaultOptions() {
366 final String[] keys= fAllKeys;
367 final Map options= new HashMap();
368 final IPreferenceStore store= PreferenceConstants.getPreferenceStore();
370 for (int index= 0; index < keys.length; index++)
371 options.put(keys[index], store.getDefaultString(keys[index]));
377 * @see net.sourceforge.phpdt.internal.ui.preferences.OptionsConfigurationBlock#getFullBuildDialogStrings(boolean)
379 protected final String[] getFullBuildDialogStrings(final boolean workspace) {
384 * @see net.sourceforge.phpdt.internal.ui.preferences.OptionsConfigurationBlock#getOptions(boolean)
386 protected Map getOptions(final boolean inherit) {
388 final String[] keys= fAllKeys;
389 final Map options= new HashMap();
390 final IPreferenceStore store= PreferenceConstants.getPreferenceStore();
392 for (int index= 0; index < keys.length; index++)
393 options.put(keys[index], store.getString(keys[index]));
399 * Handles selections of the browse button.
401 protected void handleBrowseButtonSelected() {
403 final FileDialog dialog= new FileDialog(fDictionaryPath.getShell(), SWT.OPEN);
404 dialog.setText(PreferencesMessages.getString("SpellingPreferencePage.filedialog.title")); //$NON-NLS-1$
405 dialog.setFilterExtensions(new String[] { PreferencesMessages.getString("SpellingPreferencePage.filter.dictionary.extension"), PreferencesMessages.getString("SpellingPreferencePage.filter.all.extension") }); //$NON-NLS-1$ //$NON-NLS-2$
406 dialog.setFilterNames(new String[] { PreferencesMessages.getString("SpellingPreferencePage.filter.dictionary.label"), PreferencesMessages.getString("SpellingPreferencePage.filter.all.label") }); //$NON-NLS-1$ //$NON-NLS-2$
408 final String path= dialog.open();
410 fDictionaryPath.setText(path);
414 * @see net.sourceforge.phpdt.internal.ui.preferences.OptionsConfigurationBlock#setOptions(java.util.Map)
416 protected void setOptions(final Map options) {
418 final String[] keys= fAllKeys;
419 final IPreferenceStore store= PreferenceConstants.getPreferenceStore();
421 for (int index= 0; index < keys.length; index++)
422 store.setValue(keys[index], (String)fWorkingValues.get(keys[index]));
426 * @see net.sourceforge.phpdt.internal.ui.preferences.OptionsConfigurationBlock#validateSettings(java.lang.String,java.lang.String)
428 protected void validateSettings(final String key, final String value) {
430 if (key == null || PREF_SPELLING_PROPOSAL_THRESHOLD.equals(key))
431 fThresholdStatus= validatePositiveNumber((String)fWorkingValues.get(PREF_SPELLING_PROPOSAL_THRESHOLD));
433 if (key == null || PREF_SPELLING_USER_DICTIONARY.equals(key))
434 fFileStatus= validateAbsoluteFilePath((String)fWorkingValues.get(PREF_SPELLING_USER_DICTIONARY));
436 if (key == null || PREF_SPELLING_LOCALE.equals(key))
437 fLocaleStatus= validateLocale((String)fWorkingValues.get(PREF_SPELLING_LOCALE));
439 fContext.statusChanged(StatusUtil.getMostSevere(new IStatus[] { fThresholdStatus, fFileStatus, fLocaleStatus }));