/* ****************************************************************************** * Copyright (c) 2006-2012 XMind Ltd. and others. * * This file is a part of XMind 3. XMind releases 3 and * above are dual-licensed under the Eclipse Public License (EPL), * which is available at http://www.eclipse.org/legal/epl-v10.html * and the GNU Lesser General Public License (LGPL), * which is available at http://www.gnu.org/licenses/lgpl.html * See http://www.xmind.net/license.html for details. * * Contributors: * XMind Ltd. - initial API and implementation *******************************************************************************/ package org.xmind.ui.internal.spelling; import java.io.File; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import net.xmind.signin.XMindNet; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.SafeRunner; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.preference.BooleanFieldEditor; import org.eclipse.jface.preference.FieldEditor; import org.eclipse.jface.preference.FieldEditorPreferencePage; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.util.SafeRunnable; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredContentProvider; 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.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; 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.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Listener; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPreferencePage; import org.eclipse.ui.forms.events.HyperlinkEvent; import org.eclipse.ui.forms.events.IHyperlinkListener; import org.eclipse.ui.forms.widgets.Hyperlink; import org.xmind.core.util.FileUtils; import com.swabunga.spell.engine.Configuration; public class SpellingCheckPrefPage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage { private static final Object DEFAULT_PLACEHOLDER = Messages.defaultDictionary; private class DictionaryContentProvider implements IStructuredContentProvider { public Object[] getElements(Object inputElement) { Object[] descriptors = SpellCheckerRegistry.getInstance() .getDescriptors().toArray(); if (getPreferenceStore().getBoolean( SpellingPlugin.DEFAULT_SPELLING_CHECKER_DISABLED)) return descriptors; Object[] elements = new Object[descriptors.length + 1]; elements[0] = DEFAULT_PLACEHOLDER; System.arraycopy(descriptors, 0, elements, 1, descriptors.length); return elements; } public void dispose() { } public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { } } private static class DictionaryLabelProvider extends LabelProvider { /* * (non-Javadoc) * * @see * org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object) */ @Override public String getText(Object element) { if (element instanceof ISpellCheckerDescriptor) return ((ISpellCheckerDescriptor) element).getName(); return super.getText(element); } } private static class DictionaryComparator extends ViewerComparator { /** * */ public DictionaryComparator() { super(new Comparator<String>() { public int compare(String n1, String n2) { n1 = FileUtils.getNoExtensionFileName(n1); n2 = FileUtils.getNoExtensionFileName(n2); return n1.compareToIgnoreCase(n2); } }); } /* * (non-Javadoc) * * @see * org.eclipse.jface.viewers.ViewerComparator#category(java.lang.Object) */ @Override public int category(Object element) { if (element == DEFAULT_PLACEHOLDER) return 0; return 1; } } private class DictionarySelectionListener implements ISelectionChangedListener { /* * (non-Javadoc) * * @see * org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged * (org.eclipse.jface.viewers.SelectionChangedEvent) */ public void selectionChanged(SelectionChangedEvent event) { updateDictionaryControls(); } } private List<FieldEditor> settingFields = new ArrayList<FieldEditor>(); private Composite settingsParent; private ListViewer dictionaryViewer; private Button addButton; private Button removeButton; public SpellingCheckPrefPage() { super(Messages.SpellingPrefPage_title, FLAT); } public void init(IWorkbench workbench) { setPreferenceStore(SpellingPlugin.getDefault().getPreferenceStore()); } protected void createFieldEditors() { addField(new BooleanFieldEditor(SpellingPlugin.SPELLING_CHECK_ENABLED, Messages.enableSpellCheck, getFieldEditorParent())); addSpellingSettings(getFieldEditorParent()); addDictionariesPanel(getFieldEditorParent()); updateOptions(SpellingPlugin.isSpellingCheckEnabled()); updateDictionaryControls(); } private void addSpellingSettings(Composite composite) { settingsParent = createSettingsParent(composite); addSettingField(Configuration.SPELL_IGNOREUPPERCASE, Messages.ignoreAllCapital); addSettingField(Configuration.SPELL_IGNOREMIXEDCASE, Messages.ignoreMultiCapital); addSettingField(Configuration.SPELL_IGNOREINTERNETADDRESSES, Messages.ignoreWebAddress); addSettingField(Configuration.SPELL_IGNOREDIGITWORDS, Messages.ignoreNumberousAppendix); addSettingField(Configuration.SPELL_IGNORESENTENCECAPITALIZATION, Messages.ignoreFirstLowercaseSentences); } private void addSettingField(String name, String label) { FieldEditor field = new BooleanFieldEditor(name, label, settingsParent); addField(field); settingFields.add(field); } private Composite createSettingsParent(Composite parent) { GridLayout layout = new GridLayout(1, false); layout.marginTop = 7; layout.marginWidth = 0; layout.marginHeight = 0; layout.verticalSpacing = 0; layout.horizontalSpacing = 0; parent.setLayout(layout); Group group = new Group(parent, SWT.NONE); group.setText(Messages.options); group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); GridLayout groupLayout = new GridLayout(1, false); groupLayout.marginWidth = 5; groupLayout.marginHeight = 5; groupLayout.verticalSpacing = 5; groupLayout.horizontalSpacing = 0; group.setLayout(groupLayout); return group; } private void updateOptions(boolean enabled) { settingsParent.setEnabled(enabled); for (FieldEditor field : settingFields) { field.setEnabled(enabled, settingsParent); } } private void addDictionariesPanel(Composite parent) { GridLayout layout = new GridLayout(1, false); layout.marginTop = 7; layout.marginWidth = 0; layout.marginHeight = 0; layout.verticalSpacing = 0; layout.horizontalSpacing = 0; parent.setLayout(layout); parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); Group group = new Group(parent, SWT.NONE); group.setText(Messages.dictionaries); group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); GridLayout groupLayout = new GridLayout(2, false); groupLayout.marginWidth = 5; groupLayout.marginHeight = 5; groupLayout.verticalSpacing = 5; groupLayout.horizontalSpacing = 5; group.setLayout(groupLayout); createDictionaryViewer(group); createDictionaryControls(group); createDetailsLink(group); } private void createDictionaryViewer(Composite parent) { dictionaryViewer = new ListViewer(parent, SWT.SINGLE | SWT.BORDER); dictionaryViewer.getControl().setLayoutData( new GridData(SWT.FILL, SWT.FILL, true, true)); dictionaryViewer.setContentProvider(new DictionaryContentProvider()); dictionaryViewer.setLabelProvider(new DictionaryLabelProvider()); dictionaryViewer.setComparator(new DictionaryComparator()); dictionaryViewer .addSelectionChangedListener(new DictionarySelectionListener()); dictionaryViewer.setInput(SpellCheckerRegistry.getInstance()); } private void createDictionaryControls(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true)); GridLayout layout = new GridLayout(1, true); layout.marginHeight = 0; layout.marginWidth = 0; layout.verticalSpacing = 0; layout.horizontalSpacing = 0; composite.setLayout(layout); Composite buttonBar = new Composite(composite, SWT.NONE); buttonBar.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true)); GridLayout buttonBarLayout = new GridLayout(1, true); buttonBarLayout.marginWidth = 0; buttonBarLayout.marginHeight = 0; buttonBarLayout.verticalSpacing = 10; buttonBarLayout.horizontalSpacing = 0; buttonBar.setLayout(buttonBarLayout); createAddDictionaryButton(buttonBar); createRemoveDictionaryButton(buttonBar); //createDictionaryInfoPanel(composite); } private void createDetailsLink(Composite parent) { Hyperlink hyperlink = new Hyperlink(parent, SWT.SINGLE); hyperlink .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); ((GridData) hyperlink.getLayoutData()).horizontalSpan = 2; hyperlink.setText(Messages.detailsLink_text); hyperlink.setForeground(parent.getDisplay().getSystemColor( SWT.COLOR_BLUE)); hyperlink.addHyperlinkListener(new IHyperlinkListener() { public void linkExited(HyperlinkEvent e) { } public void linkEntered(HyperlinkEvent e) { } public void linkActivated(HyperlinkEvent e) { XMindNet.gotoURL(true, "http://www.xmind.net/xmind/help/language-dic.html"); //$NON-NLS-1$ } }); } private void createAddDictionaryButton(Composite parent) { addButton = new Button(parent, SWT.PUSH); addButton .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); addButton.setText(Messages.dictionaries_add); addButton.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { addDictionary(); } }); } private void createRemoveDictionaryButton(Composite parent) { removeButton = new Button(parent, SWT.PUSH); removeButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); removeButton.setText(Messages.dictionaries_remove); removeButton.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { removeSelectedDictionary(); } }); } private void addDictionary() { FileDialog dialog = new FileDialog(getShell(), SWT.OPEN); dialog.setFilterExtensions(new String[] { "*.dic;*.dict;*.txt;*.*" }); //$NON-NLS-1$ final String path = dialog.open(); if (path == null) return; final Display display = Display.getCurrent(); try { ProgressMonitorDialog progress = new ProgressMonitorDialog( getShell()); progress.setOpenOnRun(false); progress.run(true, false, new IRunnableWithProgress() { public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { monitor.beginTask(Messages.addingDictionary, 1); SafeRunner.run(new SafeRunnable() { public void run() throws Exception { SpellCheckerRegistry.getInstance().importDictFile( new File(path)); } }); display.asyncExec(new Runnable() { public void run() { dictionaryViewer.refresh(); } }); monitor.done(); } }); } catch (InvocationTargetException e) { } catch (InterruptedException e) { } } private void removeSelectedDictionary() { Object selection = ((IStructuredSelection) dictionaryViewer .getSelection()).getFirstElement(); if (selection == null) return; // Confirm remove String name = ((ILabelProvider) dictionaryViewer.getLabelProvider()) .getText(selection); if (!MessageDialog.openConfirm(getShell(), Messages.dictionaries_remove_confirm_title, NLS.bind(Messages.dictionaries_remove_confirm_message, name))) return; // Default dictionary? if (selection == DEFAULT_PLACEHOLDER) { getPreferenceStore().setValue( SpellingPlugin.DEFAULT_SPELLING_CHECKER_DISABLED, true); dictionaryViewer.refresh(); return; } // Remove dictionary descriptor and local file final ISpellCheckerDescriptor descriptor = (ISpellCheckerDescriptor) selection; final Display display = Display.getCurrent(); try { ProgressMonitorDialog progress = new ProgressMonitorDialog( getShell()); progress.setOpenOnRun(false); progress.run(true, false, new IRunnableWithProgress() { public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { monitor.beginTask(Messages.removingDictionary, 1); SafeRunner.run(new SafeRunnable() { public void run() throws Exception { SpellCheckerRegistry.getInstance() .removeDictionary(descriptor); } }); display.asyncExec(new Runnable() { public void run() { dictionaryViewer.refresh(); } }); monitor.done(); } }); } catch (InvocationTargetException e) { } catch (InterruptedException e) { } } private void updateDictionaryControls() { removeButton.setEnabled(!dictionaryViewer.getSelection().isEmpty()); } // /** // * @param composite // */ // private void createDictionaryInfoPanel(Composite composite) { // // } public void propertyChange(PropertyChangeEvent event) { FieldEditor field = (FieldEditor) event.getSource(); if (SpellingPlugin.SPELLING_CHECK_ENABLED.equals(field .getPreferenceName())) { updateOptions(((BooleanFieldEditor) field).getBooleanValue()); } super.propertyChange(event); } }