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;
57 private static final String PREF_SPELLING_IGNORE_DIGITS = PreferenceConstants.SPELLING_IGNORE_DIGITS;
59 private static final String PREF_SPELLING_IGNORE_MIXED = PreferenceConstants.SPELLING_IGNORE_MIXED;
61 private static final String PREF_SPELLING_IGNORE_SENTENCE = PreferenceConstants.SPELLING_IGNORE_SENTENCE;
63 private static final String PREF_SPELLING_IGNORE_UPPER = PreferenceConstants.SPELLING_IGNORE_UPPER;
65 private static final String PREF_SPELLING_IGNORE_URLS = PreferenceConstants.SPELLING_IGNORE_URLS;
67 private static final String PREF_SPELLING_LOCALE = PreferenceConstants.SPELLING_LOCALE;
69 private static final String PREF_SPELLING_PROPOSAL_THRESHOLD = PreferenceConstants.SPELLING_PROPOSAL_THRESHOLD;
71 private static final String PREF_SPELLING_USER_DICTIONARY = PreferenceConstants.SPELLING_USER_DICTIONARY;
73 private static final String PREF_SPELLING_ENABLE_CONTENTASSIST = PreferenceConstants.SPELLING_ENABLE_CONTENTASSIST;
76 * Creates a selection dependency between a master and a slave control.
79 * The master button that controls the state of the slave
81 * The slave control that is enabled only if the master is
84 protected static void createSelectionDependency(final Button master,
85 final Control slave) {
87 master.addSelectionListener(new SelectionListener() {
89 public void widgetDefaultSelected(SelectionEvent event) {
93 public void widgetSelected(SelectionEvent event) {
94 slave.setEnabled(master.getSelection());
97 slave.setEnabled(master.getSelection());
101 * Returns the locale codes for the locale list.
104 * The list of locales
105 * @return Array of locale codes for the list
107 protected static String[] getDictionaryCodes(final Set locales) {
110 Locale locale = null;
112 final String[] codes = new String[locales.size()];
113 for (final Iterator iterator = locales.iterator(); iterator.hasNext();) {
115 locale = (Locale) iterator.next();
116 codes[index++] = locale.toString();
122 * Returns the display labels for the locale list.
125 * The list of locales
126 * @return Array of display labels for the list
128 protected static String[] getDictionaryLabels(final Set locales) {
131 Locale locale = null;
133 final String[] labels = new String[locales.size()];
134 for (final Iterator iterator = locales.iterator(); iterator.hasNext();) {
136 locale = (Locale) iterator.next();
137 labels[index++] = locale.getDisplayName(SpellCheckEngine
138 .getDefaultLocale());
144 * Validates that the file with the specified absolute path exists and can
148 * The path of the file to validate
149 * @return <code>true</code> iff the file exists and can be opened,
150 * <code>false</code> otherwise
152 protected static IStatus validateAbsoluteFilePath(final String path) {
154 final StatusInfo status = new StatusInfo();
155 if (path.length() > 0) {
157 final File file = new File(path);
158 if (!file.isFile() || !file.isAbsolute() || !file.exists()
159 || !file.canRead() || !file.canWrite())
160 status.setError(PreferencesMessages
161 .getString("SpellingPreferencePage.dictionary.error")); //$NON-NLS-1$
168 * Validates that the specified locale is available.
171 * The locale to validate
172 * @return The status of the validation
174 protected static IStatus validateLocale(final String locale) {
176 final StatusInfo status = new StatusInfo(IStatus.ERROR,
178 .getString("SpellingPreferencePage.locale.error")); //$NON-NLS-1$
179 final Set locales = SpellCheckEngine.getAvailableLocales();
181 Locale current = null;
182 for (final Iterator iterator = locales.iterator(); iterator.hasNext();) {
184 current = (Locale) iterator.next();
185 if (current.toString().equals(locale))
186 return new StatusInfo();
192 * Validates that the specified number is positive.
195 * The number to validate
196 * @return The status of the validation
198 protected static IStatus validatePositiveNumber(final String number) {
200 final StatusInfo status = new StatusInfo();
201 if (number.length() == 0) {
202 status.setError(PreferencesMessages
203 .getString("SpellingPreferencePage.empty_threshold")); //$NON-NLS-1$
206 final int value = Integer.parseInt(number);
209 .setError(PreferencesMessages
211 "SpellingPreferencePage.invalid_threshold", number)); //$NON-NLS-1$
213 } catch (NumberFormatException exception) {
214 status.setError(PreferencesMessages.getFormattedString(
215 "SpellingPreferencePage.invalid_threshold", number)); //$NON-NLS-1$
221 /** The dictionary path field */
222 private Text fDictionaryPath = null;
224 /** The status for the workspace dictionary file */
225 private IStatus fFileStatus = new StatusInfo();
227 /** The status for the platform locale */
228 private IStatus fLocaleStatus = new StatusInfo();
230 /** The status for the proposal threshold */
231 private IStatus fThresholdStatus = new StatusInfo();
234 * Creates a new spelling configuration block.
237 * The status change listener
241 public SpellingConfigurationBlock(final IStatusChangeListener context,
242 final IJavaProject project) {
243 super(context, project, getAllKeys());
245 IStatus status = validateAbsoluteFilePath((String) fWorkingValues
246 .get(PREF_SPELLING_USER_DICTIONARY));
247 if (status.getSeverity() != IStatus.OK)
248 fWorkingValues.put(PREF_SPELLING_USER_DICTIONARY, ""); //$NON-NLS-1$
250 status = validateLocale((String) fWorkingValues
251 .get(PREF_SPELLING_LOCALE));
252 if (status.getSeverity() != IStatus.OK)
253 fWorkingValues.put(PREF_SPELLING_LOCALE, SpellCheckEngine
254 .getDefaultLocale().toString());
257 protected Combo addComboBox(Composite parent, String label, String key,
258 String[] values, String[] valueLabels, int indent) {
259 ControlData data = new ControlData(key, values);
261 GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
262 gd.horizontalIndent = indent;
264 Label labelControl = new Label(parent, SWT.LEFT | SWT.WRAP);
265 labelControl.setText(label);
266 labelControl.setLayoutData(gd);
268 Combo comboBox = new Combo(parent, SWT.READ_ONLY);
269 comboBox.setItems(valueLabels);
270 comboBox.setData(data);
271 gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
272 gd.horizontalSpan = 2;
273 comboBox.setLayoutData(gd);
274 comboBox.addSelectionListener(getSelectionListener());
276 fLabels.put(comboBox, labelControl);
278 String currValue = (String) fWorkingValues.get(key);
279 comboBox.select(data.getSelection(currValue));
281 fComboBoxes.add(comboBox);
286 * @see net.sourceforge.phpdt.internal.ui.preferences.OptionsConfigurationBlock#createContents(org.eclipse.swt.widgets.Composite)
288 protected Control createContents(final Composite parent) {
290 Composite composite = new Composite(parent, SWT.NONE);
291 GridLayout layout = new GridLayout();
292 layout.numColumns = 1;
293 composite.setLayout(layout);
295 final PixelConverter converter = new PixelConverter(parent);
297 layout = new GridLayout();
298 layout.numColumns = 3;
300 final String[] trueFalse = new String[] { IPreferenceStore.TRUE,
301 IPreferenceStore.FALSE };
303 Group user = new Group(composite, SWT.NONE);
304 user.setText(PreferencesMessages
305 .getString("SpellingPreferencePage.preferences.user")); //$NON-NLS-1$
306 user.setLayout(new GridLayout());
307 user.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
309 String label = PreferencesMessages
310 .getString("SpellingPreferencePage.enable.label"); //$NON-NLS-1$
311 final Button master = addCheckBox(user, label,
312 PREF_SPELLING_CHECK_SPELLING, trueFalse, 0);
314 label = PreferencesMessages
315 .getString("SpellingPreferencePage.ignore.digits.label"); //$NON-NLS-1$
316 Control slave = addCheckBox(user, label, PREF_SPELLING_IGNORE_DIGITS,
318 createSelectionDependency(master, slave);
320 label = PreferencesMessages
321 .getString("SpellingPreferencePage.ignore.mixed.label"); //$NON-NLS-1$
322 slave = addCheckBox(user, label, PREF_SPELLING_IGNORE_MIXED, trueFalse,
324 createSelectionDependency(master, slave);
326 label = PreferencesMessages
327 .getString("SpellingPreferencePage.ignore.sentence.label"); //$NON-NLS-1$
328 slave = addCheckBox(user, label, PREF_SPELLING_IGNORE_SENTENCE,
330 createSelectionDependency(master, slave);
332 label = PreferencesMessages
333 .getString("SpellingPreferencePage.ignore.upper.label"); //$NON-NLS-1$
334 slave = addCheckBox(user, label, PREF_SPELLING_IGNORE_UPPER, trueFalse,
336 createSelectionDependency(master, slave);
338 label = PreferencesMessages
339 .getString("SpellingPreferencePage.ignore.url.label"); //$NON-NLS-1$
340 slave = addCheckBox(user, label, PREF_SPELLING_IGNORE_URLS, trueFalse,
342 createSelectionDependency(master, slave);
344 final Group engine = new Group(composite, SWT.NONE);
345 engine.setText(PreferencesMessages
346 .getString("SpellingPreferencePage.preferences.engine")); //$NON-NLS-1$
347 layout = new GridLayout();
348 layout.numColumns = 4;
349 engine.setLayout(layout);
350 engine.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
352 label = PreferencesMessages
353 .getString("SpellingPreferencePage.dictionary.label"); //$NON-NLS-1$
354 final Set locales = SpellCheckEngine.getAvailableLocales();
356 Combo combo = addComboBox(engine, label, PREF_SPELLING_LOCALE,
357 getDictionaryCodes(locales), getDictionaryLabels(locales), 0);
358 combo.setEnabled(locales.size() > 1);
360 new Label(engine, SWT.NONE); // placeholder
362 label = PreferencesMessages
363 .getString("SpellingPreferencePage.workspace.dictionary.label"); //$NON-NLS-1$
364 fDictionaryPath = addTextField(engine, label,
365 PREF_SPELLING_USER_DICTIONARY, 0, 0);
367 Button button = new Button(engine, SWT.PUSH);
368 button.setText(PreferencesMessages
369 .getString("SpellingPreferencePage.browse.label")); //$NON-NLS-1$
370 button.addSelectionListener(new SelectionAdapter() {
372 public void widgetSelected(final SelectionEvent event) {
373 handleBrowseButtonSelected();
376 button.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
377 SWTUtil.setButtonDimensionHint(button);
379 layout = new GridLayout();
380 layout.numColumns = 3;
382 Group advanced = new Group(composite, SWT.NONE);
383 advanced.setText(PreferencesMessages
384 .getString("SpellingPreferencePage.preferences.advanced")); //$NON-NLS-1$
385 layout = new GridLayout();
386 layout.numColumns = 3;
387 advanced.setLayout(layout);
388 advanced.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
390 label = PreferencesMessages
391 .getString("SpellingPreferencePage.proposals.threshold"); //$NON-NLS-1$
392 Text text = addTextField(advanced, label,
393 PREF_SPELLING_PROPOSAL_THRESHOLD, 0, 0);
394 text.setTextLimit(3);
395 GridData data = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
396 data.widthHint = converter.convertWidthInCharsToPixels(4);
397 text.setLayoutData(data);
399 label = PreferencesMessages
400 .getString("SpellingPreferencePage.enable.contentassist.label"); //$NON-NLS-1$
401 addCheckBox(advanced, label, PREF_SPELLING_ENABLE_CONTENTASSIST,
407 private static String[] getAllKeys() {
408 return new String[] { PREF_SPELLING_USER_DICTIONARY,
409 PREF_SPELLING_CHECK_SPELLING, PREF_SPELLING_IGNORE_DIGITS,
410 PREF_SPELLING_IGNORE_MIXED, PREF_SPELLING_IGNORE_SENTENCE,
411 PREF_SPELLING_IGNORE_UPPER, PREF_SPELLING_IGNORE_URLS,
412 PREF_SPELLING_LOCALE, PREF_SPELLING_PROPOSAL_THRESHOLD,
413 PREF_SPELLING_ENABLE_CONTENTASSIST };
417 * @see net.sourceforge.phpdt.internal.ui.preferences.OptionsConfigurationBlock#getDefaultOptions()
419 protected Map getDefaultOptions() {
421 final String[] keys = fAllKeys;
422 final Map options = new HashMap();
423 final IPreferenceStore store = PreferenceConstants.getPreferenceStore();
425 for (int index = 0; index < keys.length; index++)
426 options.put(keys[index], store.getDefaultString(keys[index]));
432 * @see net.sourceforge.phpdt.internal.ui.preferences.OptionsConfigurationBlock#getFullBuildDialogStrings(boolean)
434 protected final String[] getFullBuildDialogStrings(final boolean workspace) {
439 * @see net.sourceforge.phpdt.internal.ui.preferences.OptionsConfigurationBlock#getOptions(boolean)
441 protected Map getOptions(final boolean inherit) {
443 final String[] keys = fAllKeys;
444 final Map options = new HashMap();
445 final IPreferenceStore store = PreferenceConstants.getPreferenceStore();
447 for (int index = 0; index < keys.length; index++)
448 options.put(keys[index], store.getString(keys[index]));
454 * Handles selections of the browse button.
456 protected void handleBrowseButtonSelected() {
458 final FileDialog dialog = new FileDialog(fDictionaryPath.getShell(),
460 dialog.setText(PreferencesMessages
461 .getString("SpellingPreferencePage.filedialog.title")); //$NON-NLS-1$
463 .setFilterExtensions(new String[] {
465 .getString("SpellingPreferencePage.filter.dictionary.extension"), PreferencesMessages.getString("SpellingPreferencePage.filter.all.extension") }); //$NON-NLS-1$ //$NON-NLS-2$
467 .setFilterNames(new String[] {
469 .getString("SpellingPreferencePage.filter.dictionary.label"), PreferencesMessages.getString("SpellingPreferencePage.filter.all.label") }); //$NON-NLS-1$ //$NON-NLS-2$
471 final String path = dialog.open();
473 fDictionaryPath.setText(path);
477 * @see net.sourceforge.phpdt.internal.ui.preferences.OptionsConfigurationBlock#setOptions(java.util.Map)
479 protected void setOptions(final Map options) {
481 final String[] keys = fAllKeys;
482 final IPreferenceStore store = PreferenceConstants.getPreferenceStore();
484 for (int index = 0; index < keys.length; index++)
485 store.setValue(keys[index], (String) fWorkingValues
490 * @see net.sourceforge.phpdt.internal.ui.preferences.OptionsConfigurationBlock#validateSettings(java.lang.String,java.lang.String)
492 protected void validateSettings(final String key, final String value) {
494 if (key == null || PREF_SPELLING_PROPOSAL_THRESHOLD.equals(key))
495 fThresholdStatus = validatePositiveNumber((String) fWorkingValues
496 .get(PREF_SPELLING_PROPOSAL_THRESHOLD));
498 if (key == null || PREF_SPELLING_USER_DICTIONARY.equals(key))
499 fFileStatus = validateAbsoluteFilePath((String) fWorkingValues
500 .get(PREF_SPELLING_USER_DICTIONARY));
502 if (key == null || PREF_SPELLING_LOCALE.equals(key))
503 fLocaleStatus = validateLocale((String) fWorkingValues
504 .get(PREF_SPELLING_LOCALE));
506 fContext.statusChanged(StatusUtil.getMostSevere(new IStatus[] {
507 fThresholdStatus, fFileStatus, fLocaleStatus }));