KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > editors > text > SpellingConfigurationBlock


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11
12 package org.eclipse.ui.internal.editors.text;
13
14 import java.util.ArrayList JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.Map JavaDoc;
18
19 import org.eclipse.swt.SWT;
20 import org.eclipse.swt.custom.StackLayout;
21 import org.eclipse.swt.events.SelectionEvent;
22 import org.eclipse.swt.events.SelectionListener;
23 import org.eclipse.swt.graphics.Image;
24 import org.eclipse.swt.layout.FillLayout;
25 import org.eclipse.swt.layout.GridData;
26 import org.eclipse.swt.layout.GridLayout;
27 import org.eclipse.swt.widgets.Button;
28 import org.eclipse.swt.widgets.Combo;
29 import org.eclipse.swt.widgets.Composite;
30 import org.eclipse.swt.widgets.Control;
31 import org.eclipse.swt.widgets.Label;
32 import org.eclipse.swt.widgets.Shell;
33
34 import org.eclipse.core.runtime.Assert;
35 import org.eclipse.core.runtime.CoreException;
36 import org.eclipse.core.runtime.ISafeRunnable;
37 import org.eclipse.core.runtime.IStatus;
38 import org.eclipse.core.runtime.SafeRunner;
39 import org.eclipse.core.runtime.Status;
40
41 import org.eclipse.jface.dialogs.Dialog;
42 import org.eclipse.jface.dialogs.IDialogConstants;
43 import org.eclipse.jface.dialogs.MessageDialog;
44 import org.eclipse.jface.viewers.ComboViewer;
45 import org.eclipse.jface.viewers.ISelectionChangedListener;
46 import org.eclipse.jface.viewers.IStructuredContentProvider;
47 import org.eclipse.jface.viewers.IStructuredSelection;
48 import org.eclipse.jface.viewers.LabelProvider;
49 import org.eclipse.jface.viewers.SelectionChangedEvent;
50 import org.eclipse.jface.viewers.StructuredSelection;
51 import org.eclipse.jface.viewers.Viewer;
52
53
54 import org.eclipse.ui.editors.text.EditorsUI;
55
56 import org.eclipse.ui.texteditor.spelling.IPreferenceStatusMonitor;
57 import org.eclipse.ui.texteditor.spelling.ISpellingPreferenceBlock;
58 import org.eclipse.ui.texteditor.spelling.SpellingEngineDescriptor;
59 import org.eclipse.ui.texteditor.spelling.SpellingService;
60
61 /**
62  * Configures spelling preferences.
63  *
64  * @since 3.1
65  */

66 class SpellingConfigurationBlock implements IPreferenceConfigurationBlock {
67
68     /**
69      * Error preferences block.
70      */

71     private static class ErrorPreferences implements ISpellingPreferenceBlock {
72
73         /** Error message */
74         private String JavaDoc fMessage;
75
76         /** Error label */
77         private Label fLabel;
78
79         /**
80          * Initialize with the given error message.
81          *
82          * @param message the error message
83          */

84         protected ErrorPreferences(String JavaDoc message) {
85             fMessage= message;
86         }
87
88         /*
89          * @see org.eclipse.ui.texteditor.spelling.ISpellingPreferenceBlock#createControl(org.eclipse.swt.widgets.Composite)
90          */

91         public Control createControl(Composite composite) {
92             Composite inner= new Composite(composite, SWT.NONE);
93             inner.setLayout(new FillLayout(SWT.VERTICAL));
94
95             fLabel= new Label(inner, SWT.CENTER);
96             fLabel.setText(fMessage);
97
98             return inner;
99         }
100
101         /*
102          * @see org.eclipse.ui.texteditor.spelling.ISpellingPreferenceBlock#initialize(org.eclipse.ui.texteditor.spelling.IStatusMonitor)
103          */

104         public void initialize(IPreferenceStatusMonitor statusMonitor) {
105         }
106
107         /*
108          * @see org.eclipse.ui.texteditor.spelling.ISpellingPreferenceBlock#canPerformOk()
109          */

110         public boolean canPerformOk() {
111             return true;
112         }
113
114         /*
115          * @see org.eclipse.ui.texteditor.spelling.ISpellingPreferenceBlock#performOk()
116          */

117         public void performOk() {
118         }
119
120         /*
121          * @see org.eclipse.ui.texteditor.spelling.ISpellingPreferenceBlock#performDefaults()
122          */

123         public void performDefaults() {
124         }
125
126         /*
127          * @see org.eclipse.ui.texteditor.spelling.ISpellingPreferenceBlock#performRevert()
128          */

129         public void performRevert() {
130         }
131
132         /*
133          * @see org.eclipse.ui.texteditor.spelling.ISpellingPreferenceBlock#dispose()
134          */

135         public void dispose() {
136         }
137
138         /*
139          * @see org.eclipse.ui.texteditor.spelling.ISpellingPreferenceBlock#setEnabled(boolean)
140          */

141         public void setEnabled(boolean enabled) {
142             fLabel.setEnabled(enabled);
143         }
144     }
145
146     /**
147      * Forwarding status monitor for accessing the current status.
148      */

149     private static class ForwardingStatusMonitor implements IPreferenceStatusMonitor {
150
151         /** Status monitor to which status changes are forwarded */
152         private IPreferenceStatusMonitor fForwardedMonitor;
153
154         /** Latest reported status */
155         private IStatus fStatus;
156
157         /**
158          * Initializes with the given status monitor to which status
159          * changes are forwarded.
160          *
161          * @param forwardedMonitor
162          */

163         public ForwardingStatusMonitor(IPreferenceStatusMonitor forwardedMonitor) {
164             fForwardedMonitor= forwardedMonitor;
165         }
166
167         /*
168          * @see org.eclipse.ui.texteditor.spelling.IPreferenceStatusMonitor#statusChanged(org.eclipse.core.runtime.IStatus)
169          */

170         public void statusChanged(IStatus status) {
171             fStatus= status;
172             fForwardedMonitor.statusChanged(status);
173         }
174
175         /**
176          * Returns the latest reported status.
177          *
178          * @return the latest reported status, can be <code>null</code>
179          */

180         public IStatus getStatus() {
181             return fStatus;
182         }
183     }
184
185     /** The overlay preference store. */
186     private final OverlayPreferenceStore fStore;
187
188     /* The controls */
189     private Combo fProviderCombo;
190     private Button fEnablementCheckbox;
191     private ComboViewer fProviderViewer;
192     private Composite fComboGroup;
193     private Composite fGroup;
194     private StackLayout fStackLayout;
195
196     /* the model */
197     private final Map JavaDoc fProviderDescriptors;
198     private final Map JavaDoc fProviderPreferences;
199     private final Map JavaDoc fProviderControls;
200
201     private ForwardingStatusMonitor fStatusMonitor;
202
203     private ISpellingPreferenceBlock fCurrentBlock;
204
205
206     public SpellingConfigurationBlock(OverlayPreferenceStore store, IPreferenceStatusMonitor statusMonitor) {
207         Assert.isNotNull(store);
208         fStore= store;
209         fStore.addKeys(createOverlayStoreKeys());
210         fStatusMonitor= new ForwardingStatusMonitor(statusMonitor);
211         fProviderDescriptors= createListModel();
212         fProviderPreferences= new HashMap JavaDoc();
213         fProviderControls= new HashMap JavaDoc();
214     }
215
216     private Map JavaDoc createListModel() {
217         SpellingEngineDescriptor[] descs= EditorsUI.getSpellingService().getSpellingEngineDescriptors();
218         Map JavaDoc map= new HashMap JavaDoc();
219         for (int i= 0; i < descs.length; i++) {
220             map.put(descs[i].getId(), descs[i]);
221         }
222         return map;
223     }
224
225     private OverlayPreferenceStore.OverlayKey[] createOverlayStoreKeys() {
226
227         ArrayList JavaDoc overlayKeys= new ArrayList JavaDoc();
228
229         overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, SpellingService.PREFERENCE_SPELLING_ENABLED));
230         overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, SpellingService.PREFERENCE_SPELLING_ENGINE));
231
232         OverlayPreferenceStore.OverlayKey[] keys= new OverlayPreferenceStore.OverlayKey[overlayKeys.size()];
233         overlayKeys.toArray(keys);
234         return keys;
235     }
236
237     /**
238      * Creates page for spelling preferences.
239      *
240      * @param parent the parent composite
241      * @return the control for the preference page
242      */

243     public Control createControl(Composite parent) {
244
245         Composite composite= new Composite(parent, SWT.NULL);
246         // assume parent page uses grid-data
247
GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_CENTER | GridData.VERTICAL_ALIGN_FILL);
248         composite.setLayoutData(gd);
249         GridLayout layout= new GridLayout();
250         layout.numColumns= 2;
251         layout.marginHeight= 0;
252         layout.marginWidth= 0;
253         
254         PixelConverter pc= new PixelConverter(composite);
255         layout.verticalSpacing= pc.convertHeightInCharsToPixels(1) / 2;
256         composite.setLayout(layout);
257         
258         if (EditorsUI.getSpellingService().getSpellingEngineDescriptors().length == 0) {
259             Label label= new Label(composite, SWT.NONE);
260             label.setText(TextEditorMessages.SpellingConfigurationBlock_error_not_installed);
261             return composite;
262         }
263
264         /* check box for new editors */
265         fEnablementCheckbox= new Button(composite, SWT.CHECK);
266         fEnablementCheckbox.setText(TextEditorMessages.SpellingConfigurationBlock_enable);
267         gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING);
268         fEnablementCheckbox.setLayoutData(gd);
269         fEnablementCheckbox.addSelectionListener(new SelectionListener() {
270             public void widgetSelected(SelectionEvent e) {
271                 boolean enabled= fEnablementCheckbox.getSelection();
272                 fStore.setValue(SpellingService.PREFERENCE_SPELLING_ENABLED, enabled);
273                 updateCheckboxDependencies();
274             }
275
276             public void widgetDefaultSelected(SelectionEvent e) {
277             }
278         });
279
280         Label label= new Label(composite, SWT.CENTER);
281         gd= new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING);
282         label.setLayoutData(gd);
283         
284         if (fProviderDescriptors.size() > 1) {
285             fComboGroup= new Composite(composite, SWT.NONE);
286             gd= new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING);
287             gd.horizontalIndent= 10;
288             fComboGroup.setLayoutData(gd);
289             GridLayout gridLayout= new GridLayout(2, false);
290             gridLayout.marginWidth= 0;
291             fComboGroup.setLayout(gridLayout);
292
293             Label comboLabel= new Label(fComboGroup, SWT.CENTER);
294             gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_CENTER);
295             comboLabel.setLayoutData(gd);
296             comboLabel.setText(TextEditorMessages.SpellingConfigurationBlock_combo_caption);
297
298             label= new Label(composite, SWT.CENTER);
299             gd= new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING);
300             label.setLayoutData(gd);
301
302             fProviderCombo= new Combo(fComboGroup, SWT.READ_ONLY | SWT.DROP_DOWN);
303             gd= new GridData(GridData.HORIZONTAL_ALIGN_END | GridData.VERTICAL_ALIGN_CENTER);
304             fProviderCombo.setLayoutData(gd);
305
306             fProviderViewer= createProviderViewer();
307         }
308
309         Composite groupComp= new Composite(composite, SWT.NONE);
310         gd= new GridData(GridData.FILL_BOTH);
311         gd.horizontalSpan= 2;
312         groupComp.setLayoutData(gd);
313         GridLayout gridLayout= new GridLayout(1, false);
314         gridLayout.marginWidth= 0;
315         groupComp.setLayout(gridLayout);
316
317         /* contributed provider preferences. */
318         fGroup= new Composite(groupComp, SWT.NONE);
319         gd= new GridData(SWT.FILL, SWT.FILL, true, true);
320         gd.horizontalIndent= 10;
321         fGroup.setLayoutData(gd);
322         fStackLayout= new StackLayout();
323         fGroup.setLayout(fStackLayout);
324
325         return composite;
326     }
327
328     private ComboViewer createProviderViewer() {
329         /* list viewer */
330         final ComboViewer viewer= new ComboViewer(fProviderCombo);
331         viewer.setContentProvider(new IStructuredContentProvider() {
332
333             /*
334              * @see org.eclipse.jface.viewers.IContentProvider#dispose()
335              */

336             public void dispose() {
337             }
338
339             /*
340              * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
341              */

342             public void inputChanged(Viewer v, Object JavaDoc oldInput, Object JavaDoc newInput) {
343             }
344
345             /*
346              * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
347              */

348             public Object JavaDoc[] getElements(Object JavaDoc inputElement) {
349                 return fProviderDescriptors.values().toArray();
350             }
351         });
352         viewer.setLabelProvider(new LabelProvider() {
353             /*
354              * @see org.eclipse.jface.viewers.LabelProvider#getImage(java.lang.Object)
355              */

356             public Image getImage(Object JavaDoc element) {
357                 return null;
358             }
359
360             /*
361              * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
362              */

363             public String JavaDoc getText(Object JavaDoc element) {
364                 return ((SpellingEngineDescriptor) element).getLabel();
365             }
366         });
367         viewer.addSelectionChangedListener(new ISelectionChangedListener() {
368
369             public void selectionChanged(SelectionChangedEvent event) {
370                 IStructuredSelection sel= (IStructuredSelection) event.getSelection();
371                 if (sel.isEmpty())
372                     return;
373                 if (fCurrentBlock != null && fStatusMonitor.getStatus() != null && fStatusMonitor.getStatus().matches(IStatus.ERROR))
374                     if (isPerformRevert()) {
375                         ISafeRunnable runnable= new ISafeRunnable() {
376                             public void run() throws Exception JavaDoc {
377                                 fCurrentBlock.performRevert();
378                             }
379                             public void handleException(Throwable JavaDoc x) {
380                             }
381                         };
382                         SafeRunner.run(runnable);
383                     } else {
384                         revertSelection();
385                         return;
386                     }
387                 fStore.setValue(SpellingService.PREFERENCE_SPELLING_ENGINE, ((SpellingEngineDescriptor) sel.getFirstElement()).getId());
388                 updateListDependencies();
389             }
390
391             private boolean isPerformRevert() {
392                 Shell shell= viewer.getControl().getShell();
393                 MessageDialog dialog= new MessageDialog(shell, TextEditorMessages.SpellingConfigurationBlock_error_title, null, TextEditorMessages.SpellingConfigurationBlock_error_message, MessageDialog.QUESTION, new String JavaDoc[] { IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL }, 1);
394                 return dialog.open() == 0;
395             }
396
397             private void revertSelection() {
398                 try {
399                     viewer.removeSelectionChangedListener(this);
400                     SpellingEngineDescriptor desc= EditorsUI.getSpellingService().getActiveSpellingEngineDescriptor(fStore);
401                     if (desc != null)
402                         viewer.setSelection(new StructuredSelection(desc), true);
403                 } finally {
404                     viewer.addSelectionChangedListener(this);
405                 }
406             }
407         });
408         viewer.setInput(fProviderDescriptors);
409         viewer.refresh();
410
411         return viewer;
412     }
413
414     private void updateCheckboxDependencies() {
415         final boolean enabled= fEnablementCheckbox.getSelection();
416         if (fComboGroup != null)
417             setEnabled(fComboGroup, enabled);
418         SpellingEngineDescriptor desc= EditorsUI.getSpellingService().getActiveSpellingEngineDescriptor(fStore);
419         String JavaDoc id= desc != null ? desc.getId() : ""; //$NON-NLS-1$
420
final ISpellingPreferenceBlock preferenceBlock= (ISpellingPreferenceBlock) fProviderPreferences.get(id);
421         if (preferenceBlock != null) {
422             ISafeRunnable runnable= new ISafeRunnable() {
423                 public void run() throws Exception JavaDoc {
424                     preferenceBlock.setEnabled(enabled);
425                 }
426                 public void handleException(Throwable JavaDoc x) {
427                 }
428             };
429             SafeRunner.run(runnable);
430         }
431     }
432
433     private void setEnabled(Control control, boolean enabled) {
434         if (control instanceof Composite) {
435             Control[] children= ((Composite) control).getChildren();
436             for (int i= 0; i < children.length; i++)
437                 setEnabled(children[i], enabled);
438         }
439         control.setEnabled(enabled);
440     }
441
442     void updateListDependencies() {
443         SpellingEngineDescriptor desc= EditorsUI.getSpellingService().getActiveSpellingEngineDescriptor(fStore);
444         String JavaDoc id;
445         if (desc == null) {
446             // safety in case there is no such descriptor
447
id= ""; //$NON-NLS-1$
448
String JavaDoc message= TextEditorMessages.SpellingConfigurationBlock_error_not_exist;
449             EditorsPlugin.log(new Status(IStatus.WARNING, EditorsUI.PLUGIN_ID, IStatus.OK, message, null));
450             fCurrentBlock= new ErrorPreferences(message);
451         } else {
452             id= desc.getId();
453             fCurrentBlock= (ISpellingPreferenceBlock) fProviderPreferences.get(id);
454             if (fCurrentBlock == null) {
455                 try {
456                     fCurrentBlock= desc.createPreferences();
457                     fProviderPreferences.put(id, fCurrentBlock);
458                 } catch (CoreException e) {
459                     EditorsPlugin.log(e);
460                     fCurrentBlock= new ErrorPreferences(e.getLocalizedMessage());
461                 }
462             }
463         }
464
465         Control control= (Control) fProviderControls.get(id);
466         if (control == null) {
467             final Control[] result= new Control[1];
468             ISafeRunnable runnable= new ISafeRunnable() {
469                 public void run() throws Exception JavaDoc {
470                     result[0]= fCurrentBlock.createControl(fGroup);
471                 }
472                 public void handleException(Throwable JavaDoc x) {
473                 }
474             };
475             SafeRunner.run(runnable);
476             control= result[0];
477             if (control == null) {
478                 String JavaDoc message= TextEditorMessages.SpellingConfigurationBlock_info_no_preferences;
479                 EditorsPlugin.log(new Status(IStatus.WARNING, EditorsUI.PLUGIN_ID, IStatus.OK, message, null));
480                 control= new ErrorPreferences(message).createControl(fGroup);
481             } else {
482                 fProviderControls.put(id, control);
483             }
484         }
485         Dialog.applyDialogFont(control);
486         fStackLayout.topControl= control;
487         control.pack();
488         fGroup.layout();
489         fGroup.getParent().layout();
490
491         fStatusMonitor.statusChanged(new StatusInfo());
492         ISafeRunnable runnable= new ISafeRunnable() {
493             public void run() throws Exception JavaDoc {
494                 fCurrentBlock.initialize(fStatusMonitor);
495             }
496             public void handleException(Throwable JavaDoc x) {
497             }
498         };
499         SafeRunner.run(runnable);
500     }
501
502     public void initialize() {
503         restoreFromPreferences();
504     }
505
506     public boolean canPerformOk() {
507         SpellingEngineDescriptor desc= EditorsUI.getSpellingService().getActiveSpellingEngineDescriptor(fStore);
508         String JavaDoc id= desc != null ? desc.getId() : ""; //$NON-NLS-1$
509
final ISpellingPreferenceBlock block= (ISpellingPreferenceBlock) fProviderPreferences.get(id);
510         if (block == null)
511             return true;
512
513         final Boolean JavaDoc[] result= new Boolean JavaDoc[] { Boolean.TRUE };
514         ISafeRunnable runnable= new ISafeRunnable() {
515             public void run() throws Exception JavaDoc {
516                 result[0]= Boolean.valueOf(block.canPerformOk());
517             }
518             public void handleException(Throwable JavaDoc x) {
519             }
520         };
521         SafeRunner.run(runnable);
522         return result[0].booleanValue();
523     }
524
525     public void performOk() {
526         for (Iterator JavaDoc it= fProviderPreferences.values().iterator(); it.hasNext();) {
527             final ISpellingPreferenceBlock block= (ISpellingPreferenceBlock) it.next();
528             ISafeRunnable runnable= new ISafeRunnable() {
529                 public void run() throws Exception JavaDoc {
530                     block.performOk();
531                 }
532                 public void handleException(Throwable JavaDoc x) {
533                 }
534             };
535             SafeRunner.run(runnable);
536         }
537     }
538
539     public void performDefaults() {
540         restoreFromPreferences();
541         for (Iterator JavaDoc it= fProviderPreferences.values().iterator(); it.hasNext();) {
542             final ISpellingPreferenceBlock block= (ISpellingPreferenceBlock) it.next();
543             ISafeRunnable runnable= new ISafeRunnable() {
544                 public void run() throws Exception JavaDoc {
545                     block.performDefaults();
546                 }
547                 public void handleException(Throwable JavaDoc x) {
548                 }
549             };
550             SafeRunner.run(runnable);
551         }
552     }
553
554     public void dispose() {
555         for (Iterator JavaDoc it= fProviderPreferences.values().iterator(); it.hasNext();) {
556             final ISpellingPreferenceBlock block= (ISpellingPreferenceBlock) it.next();
557             ISafeRunnable runnable= new ISafeRunnable() {
558                 public void run() throws Exception JavaDoc {
559                     block.dispose();
560                 }
561                 public void handleException(Throwable JavaDoc x) {
562                 }
563             };
564             SafeRunner.run(runnable);
565         }
566     }
567
568     private void restoreFromPreferences() {
569         if (fEnablementCheckbox == null)
570             return;
571         
572         boolean enabled= fStore.getBoolean(SpellingService.PREFERENCE_SPELLING_ENABLED);
573         fEnablementCheckbox.setSelection(enabled);
574
575         if (fProviderViewer == null)
576             updateListDependencies();
577         else {
578             SpellingEngineDescriptor desc= EditorsUI.getSpellingService().getActiveSpellingEngineDescriptor(fStore);
579             if (desc != null)
580                 fProviderViewer.setSelection(new StructuredSelection(desc), true);
581         }
582
583         updateCheckboxDependencies();
584     }
585 }
586
Popular Tags