KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > editors > text > TextSourceViewerConfiguration


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 package org.eclipse.ui.editors.text;
12
13 import java.util.HashMap JavaDoc;
14 import java.util.Iterator JavaDoc;
15 import java.util.Map JavaDoc;
16 import java.util.StringTokenizer JavaDoc;
17 import java.util.Map.Entry;
18
19 import org.eclipse.swt.SWT;
20 import org.eclipse.swt.widgets.Shell;
21
22 import org.eclipse.core.runtime.Assert;
23 import org.eclipse.core.runtime.IAdaptable;
24 import org.eclipse.core.runtime.NullProgressMonitor;
25
26 import org.eclipse.jface.action.Action;
27 import org.eclipse.jface.internal.text.html.HTMLTextPresenter;
28 import org.eclipse.jface.preference.IPreferenceStore;
29
30 import org.eclipse.jface.text.DefaultInformationControl;
31 import org.eclipse.jface.text.DefaultTextHover;
32 import org.eclipse.jface.text.IInformationControl;
33 import org.eclipse.jface.text.IInformationControlCreator;
34 import org.eclipse.jface.text.ITextHover;
35 import org.eclipse.jface.text.ITextHoverExtension;
36 import org.eclipse.jface.text.ITextViewerExtension2;
37 import org.eclipse.jface.text.IUndoManager;
38 import org.eclipse.jface.text.TextViewerUndoManager;
39 import org.eclipse.jface.text.hyperlink.DefaultHyperlinkPresenter;
40 import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
41 import org.eclipse.jface.text.hyperlink.IHyperlinkPresenter;
42 import org.eclipse.jface.text.quickassist.IQuickAssistAssistant;
43 import org.eclipse.jface.text.quickassist.QuickAssistAssistant;
44 import org.eclipse.jface.text.reconciler.IReconciler;
45 import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
46 import org.eclipse.jface.text.reconciler.MonoReconciler;
47 import org.eclipse.jface.text.source.Annotation;
48 import org.eclipse.jface.text.source.DefaultAnnotationHover;
49 import org.eclipse.jface.text.source.IAnnotationHover;
50 import org.eclipse.jface.text.source.ISourceViewer;
51 import org.eclipse.jface.text.source.SourceViewerConfiguration;
52
53 import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
54 import org.eclipse.ui.texteditor.AnnotationPreference;
55 import org.eclipse.ui.texteditor.HyperlinkDetectorRegistry;
56 import org.eclipse.ui.texteditor.spelling.SpellingCorrectionProcessor;
57 import org.eclipse.ui.texteditor.spelling.SpellingReconcileStrategy;
58 import org.eclipse.ui.texteditor.spelling.SpellingService;
59
60
61 /**
62  * Source viewer configuration for the text editor.
63  *
64  * @since 3.0
65  */

66 public class TextSourceViewerConfiguration extends SourceViewerConfiguration {
67
68     /**
69      * The preference store used to initialize this configuration.
70      * <p>
71      * Note: protected since 3.1
72      * </p>
73      */

74     protected IPreferenceStore fPreferenceStore;
75
76     /**
77      * Creates a text source viewer configuration.
78      */

79     public TextSourceViewerConfiguration() {
80     }
81
82     /**
83      * Creates a text source viewer configuration and
84      * initializes it with the given preference store.
85      *
86      * @param preferenceStore the preference store used to initialize this configuration
87      */

88     public TextSourceViewerConfiguration(IPreferenceStore preferenceStore) {
89         fPreferenceStore= preferenceStore;
90     }
91
92     /*
93      * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getAnnotationHover(org.eclipse.jface.text.source.ISourceViewer)
94      */

95     public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {
96         return new DefaultAnnotationHover() {
97             protected boolean isIncluded(Annotation annotation) {
98                 return isShowInVerticalRuler(annotation);
99             }
100         };
101     }
102
103     /*
104      * @see DefaultAnnotationHover#isIncluded(Annotation)
105      * @since 3.2
106      */

107     protected boolean isShowInVerticalRuler(Annotation annotation) {
108         AnnotationPreference preference= getAnnotationPreference(annotation);
109         if (preference == null)
110             return true;
111         String JavaDoc key= preference.getVerticalRulerPreferenceKey();
112         // backward compatibility
113
if (key != null && !fPreferenceStore.getBoolean(key))
114             return false;
115         
116         return true;
117     }
118
119     /*
120      * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getOverviewRulerAnnotationHover(org.eclipse.jface.text.source.ISourceViewer)
121      * @since 3.2
122      */

123     public IAnnotationHover getOverviewRulerAnnotationHover(ISourceViewer sourceViewer) {
124         return new DefaultAnnotationHover() {
125             protected boolean isIncluded(Annotation annotation) {
126                 return isShowInOverviewRuler(annotation);
127             }
128         };
129     }
130
131     /*
132      * @see DefaultAnnotationHover#isIncluded(Annotation)
133      * @since 3.2
134      */

135     protected boolean isShowInOverviewRuler(Annotation annotation) {
136         AnnotationPreference preference= getAnnotationPreference(annotation);
137         if (preference == null)
138             return true;
139         String JavaDoc key= preference.getOverviewRulerPreferenceKey();
140         if (key == null || !fPreferenceStore.getBoolean(key))
141             return false;
142         
143         return true;
144     }
145
146     /*
147      * @see SourceViewerConfiguration#getConfiguredTextHoverStateMasks(ISourceViewer, String)
148      * @since 3.2
149      */

150     public int[] getConfiguredTextHoverStateMasks(ISourceViewer sourceViewer, String JavaDoc contentType) {
151         return new int[] { ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK };
152     }
153
154     /*
155      * @see SourceViewerConfiguration#getTextHover(ISourceViewer, String)
156      * @since 3.2
157      */

158     public ITextHover getTextHover(ISourceViewer sourceViewer, String JavaDoc contentType) {
159         return new TextHover(sourceViewer);
160     }
161
162     /*
163      * @see DefaultTextHover#isIncluded(Annotation)
164      * @since 3.2
165      */

166     protected boolean isShownInText(Annotation annotation) {
167         AnnotationPreference preference= getAnnotationPreference(annotation);
168         if (preference == null)
169             return false;
170         String JavaDoc key= preference.getTextPreferenceKey();
171         if (key != null) {
172             if (!fPreferenceStore.getBoolean(key))
173                 return false;
174         } else {
175             key= preference.getHighlightPreferenceKey();
176             if (key == null || !fPreferenceStore.getBoolean(key))
177                 return false;
178         }
179         return true;
180     }
181     
182     /**
183      * Returns the annotation preference for the given annotation.
184      *
185      * @param annotation the annotation
186      * @return the annotation preference or <code>null</code> if none
187      * @since 3.2
188      */

189     private AnnotationPreference getAnnotationPreference(Annotation annotation) {
190         if (annotation == null || fPreferenceStore == null)
191             return null;
192         return EditorsUI.getAnnotationPreferenceLookup().getAnnotationPreference(annotation);
193     }
194
195     /*
196      * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getTabWidth(org.eclipse.jface.text.source.ISourceViewer)
197      */

198     public int getTabWidth(ISourceViewer sourceViewer) {
199         if (fPreferenceStore == null)
200             return super.getTabWidth(sourceViewer);
201         return fPreferenceStore.getInt(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH);
202     }
203
204     /*
205      * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getIndentPrefixes(org.eclipse.jface.text.source.ISourceViewer, java.lang.String)
206      * @since 3.3
207      */

208     public String JavaDoc[] getIndentPrefixes(ISourceViewer sourceViewer, String JavaDoc contentType) {
209         String JavaDoc[] indentPrefixes= getIndentPrefixesForTab(getTabWidth(sourceViewer));
210         if (indentPrefixes == null)
211             return null;
212
213         int length= indentPrefixes.length;
214         if (length > 2 && fPreferenceStore != null && fPreferenceStore.getBoolean(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SPACES_FOR_TABS)) {
215             // Swap first with second last
216
String JavaDoc first= indentPrefixes[0];
217             indentPrefixes[0]= indentPrefixes[length - 2];
218             indentPrefixes[length - 2]= first;
219         }
220
221         return indentPrefixes;
222     }
223
224     /*
225      * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getHyperlinkDetectors(org.eclipse.jface.text.source.ISourceViewer)
226      * @since 3.1
227      */

228     public IHyperlinkDetector[] getHyperlinkDetectors(ISourceViewer sourceViewer) {
229         if (sourceViewer == null || fPreferenceStore == null)
230             return super.getHyperlinkDetectors(sourceViewer);
231
232         if (!fPreferenceStore.getBoolean(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_HYPERLINKS_ENABLED))
233             return null;
234         
235         return getRegisteredHyperlinkDetectors(sourceViewer);
236     }
237
238     /**
239      * Returns the registered hyperlink detectors which are used to detect
240      * hyperlinks in the given source viewer.
241      *
242      * @param sourceViewer the source viewer to be configured by this configuration
243      * @return an array with hyperlink detectors or <code>null</code> if no hyperlink detectors are registered
244      * @since 3.3
245      */

246     protected final IHyperlinkDetector[] getRegisteredHyperlinkDetectors(ISourceViewer sourceViewer) {
247         HyperlinkDetectorRegistry registry= EditorsUI.getHyperlinkDetectorRegistry();
248
249         Map JavaDoc targets= getHyperlinkDetectorTargets(sourceViewer);
250         Assert.isNotNull(targets);
251         
252         IHyperlinkDetector[] result= null;
253         Iterator JavaDoc iter= targets.entrySet().iterator();
254         while (iter.hasNext()) {
255             Entry target= (Entry)iter.next();
256             String JavaDoc targetId= (String JavaDoc)target.getKey();
257             IAdaptable context= (IAdaptable)target.getValue();
258             result= merge(result, registry.createHyperlinkDetectors(targetId, context));
259         }
260         return result;
261     }
262
263     /**
264      * Returns the hyperlink detector targets supported by the
265      * given source viewer.
266      * <p>
267      * Subclasses are allowed to modify the returned map.
268      * </p>
269      *
270      * @param sourceViewer the source viewer to be configured by this configuration
271      * @return the hyperlink detector targets with target id (<code>String</code>) as key
272      * and the target context (<code>IAdaptable</code>) as value
273      * @since 3.3
274      */

275     protected Map JavaDoc getHyperlinkDetectorTargets(ISourceViewer sourceViewer) {
276         Map JavaDoc targets= new HashMap JavaDoc();
277         targets.put("org.eclipse.ui.DefaultTextEditor", null); //$NON-NLS-1$
278
return targets;
279     }
280
281     /*
282      * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getHyperlinkStateMask(org.eclipse.jface.text.source.ISourceViewer)
283      * @since 3.1
284      */

285     public int getHyperlinkStateMask(ISourceViewer sourceViewer) {
286         if (fPreferenceStore == null)
287             return super.getHyperlinkStateMask(sourceViewer);
288
289         String JavaDoc modifiers= fPreferenceStore.getString(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_HYPERLINK_KEY_MODIFIER);
290         int modifierMask= computeStateMask(modifiers);
291         if (modifierMask == -1) {
292             // Fall back to stored state mask
293
modifierMask= fPreferenceStore.getInt(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_HYPERLINK_KEY_MODIFIER_MASK);
294         }
295         return modifierMask;
296     }
297
298     /*
299      * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getHyperlinkPresenter(org.eclipse.jface.text.source.ISourceViewer)
300      * @since 3.1
301      */

302     public IHyperlinkPresenter getHyperlinkPresenter(ISourceViewer sourceViewer) {
303         if (fPreferenceStore == null)
304             return super.getHyperlinkPresenter(sourceViewer);
305
306         return new DefaultHyperlinkPresenter(fPreferenceStore);
307     }
308
309     /**
310      * Maps the localized modifier name to a code in the same
311      * manner as #findModifier.
312      *
313      * @param modifierName the modifier name
314      * @return the SWT modifier bit, or <code>0</code> if no match was found
315      * @since 3.1
316      */

317     protected static final int findLocalizedModifier(String JavaDoc modifierName) {
318         if (modifierName == null)
319             return 0;
320
321         if (modifierName.equalsIgnoreCase(Action.findModifierString(SWT.CTRL)))
322             return SWT.CTRL;
323         if (modifierName.equalsIgnoreCase(Action.findModifierString(SWT.SHIFT)))
324             return SWT.SHIFT;
325         if (modifierName.equalsIgnoreCase(Action.findModifierString(SWT.ALT)))
326             return SWT.ALT;
327         if (modifierName.equalsIgnoreCase(Action.findModifierString(SWT.COMMAND)))
328             return SWT.COMMAND;
329
330         return 0;
331     }
332
333     /**
334      * Computes the state mask out of the given modifiers string.
335      *
336      * @param modifiers a string containing modifiers
337      * @return the state mask
338      * @since 3.1
339      */

340     protected static final int computeStateMask(String JavaDoc modifiers) {
341         if (modifiers == null)
342             return -1;
343
344         if (modifiers.length() == 0)
345             return SWT.NONE;
346
347         int stateMask= 0;
348         StringTokenizer JavaDoc modifierTokenizer= new StringTokenizer JavaDoc(modifiers, ",;.:+-* "); //$NON-NLS-1$
349
while (modifierTokenizer.hasMoreTokens()) {
350             int modifier= findLocalizedModifier(modifierTokenizer.nextToken());
351             if (modifier == 0 || (stateMask & modifier) == modifier)
352                 return -1;
353             stateMask= stateMask | modifier;
354         }
355         return stateMask;
356     }
357
358     /*
359      * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getUndoManager(org.eclipse.jface.text.source.ISourceViewer)
360      * @since 3.1
361      */

362     public IUndoManager getUndoManager(ISourceViewer sourceViewer) {
363         if (fPreferenceStore == null || !fPreferenceStore.contains(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_UNDO_HISTORY_SIZE))
364             return super.getUndoManager(sourceViewer);
365
366         int undoHistorySize= fPreferenceStore.getInt(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_UNDO_HISTORY_SIZE);
367         return new TextViewerUndoManager(undoHistorySize);
368     }
369
370     /**
371      * Returns the reconciler ready to be used with the given source viewer.
372      * <p>
373      * This implementation currently returns a {@link MonoReconciler} which
374      * is responsible for spell checking. In the future a different reconciler
375      * taking over more responsibilities might be returned.</p>
376      *
377      * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getReconciler(org.eclipse.jface.text.source.ISourceViewer)
378      * @since 3.3
379      */

380     public IReconciler getReconciler(ISourceViewer sourceViewer) {
381         if (fPreferenceStore == null || !fPreferenceStore.getBoolean(SpellingService.PREFERENCE_SPELLING_ENABLED))
382             return null;
383
384         SpellingService spellingService= EditorsUI.getSpellingService();
385         if (spellingService.getActiveSpellingEngineDescriptor(fPreferenceStore) == null)
386             return null;
387         
388         IReconcilingStrategy strategy= new SpellingReconcileStrategy(sourceViewer, spellingService);
389         MonoReconciler reconciler= new MonoReconciler(strategy, false);
390         reconciler.setIsIncrementalReconciler(false);
391         reconciler.setProgressMonitor(new NullProgressMonitor());
392         reconciler.setDelay(500);
393         return reconciler;
394     }
395
396     /*
397      * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getQuickAssistAssistant(org.eclipse.jface.text.source.ISourceViewer)
398      * @since 3.3
399      */

400     public IQuickAssistAssistant getQuickAssistAssistant(ISourceViewer sourceViewer) {
401         if (fPreferenceStore == null || !fPreferenceStore.getBoolean(SpellingService.PREFERENCE_SPELLING_ENABLED))
402             return null;
403
404         IQuickAssistAssistant assistant= new QuickAssistAssistant();
405         assistant.setQuickAssistProcessor(new SpellingCorrectionProcessor());
406         assistant.setInformationControlCreator(getQuickAssistAssistantInformationControlCreator());
407         
408         // Waiting for color preferences, see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=133731
409
assistant.setProposalSelectorBackground(sourceViewer.getTextWidget().getDisplay().getSystemColor(SWT.COLOR_WHITE));
410         assistant.setProposalSelectorForeground(sourceViewer.getTextWidget().getDisplay().getSystemColor(SWT.COLOR_BLACK));
411         
412         return assistant;
413     }
414
415     /**
416      * Returns the information control creator for the quick assist assistant.
417      *
418      * @return the information control creator
419      * @since 3.3
420      */

421     private IInformationControlCreator getQuickAssistAssistantInformationControlCreator() {
422         return new IInformationControlCreator() {
423             public IInformationControl createInformationControl(Shell parent) {
424                 return new DefaultInformationControl(parent, SWT.NONE, new HTMLTextPresenter(true));
425             }
426         };
427     }
428
429     /**
430      * Helper method to merge two {@link IHyperlinkDetector} arrays.
431      *
432      * @param array1 an array of hyperlink detectors or <code>null</code>
433      * @param array2 an array of hyperlink detectors or <code>null</code>
434      * @return an array with the merged hyperlink detectors or <code>null</code> if both given arrays are <code>null</code>
435      * @since 3.3
436      */

437     private IHyperlinkDetector[] merge(IHyperlinkDetector[] array1, IHyperlinkDetector[] array2) {
438         if (array1 == null && array2 == null)
439             return null;
440         else if (array1 == null)
441             return array2;
442         else if (array2 == null)
443             return array1;
444         else {
445             IHyperlinkDetector[] allHyperlinkDetectors;
446             int size= array1.length + array2.length;
447             allHyperlinkDetectors= new IHyperlinkDetector[size];
448             System.arraycopy(array1, 0, allHyperlinkDetectors, 0, array1.length);
449             System.arraycopy(array2, 0, allHyperlinkDetectors, array1.length, array2.length);
450             return allHyperlinkDetectors;
451         }
452     }
453
454     /**
455      * Text hover with custom control creator that
456      * can show the tool tip affordance.
457      *
458      * @since 3.3
459      */

460     private final class TextHover extends DefaultTextHover implements ITextHoverExtension {
461         public TextHover(ISourceViewer sourceViewer) {
462             super(sourceViewer);
463         }
464
465         protected boolean isIncluded(Annotation annotation) {
466             return isShownInText(annotation);
467         }
468
469         /*
470          * @see org.eclipse.jface.text.ITextHoverExtension#getHoverControlCreator()
471          */

472         public IInformationControlCreator getHoverControlCreator() {
473             return new IInformationControlCreator() {
474                 public IInformationControl createInformationControl(Shell parent) {
475                     return new DefaultInformationControl(parent, SWT.NONE, new HTMLTextPresenter(true), EditorsUI.getTooltipAffordanceString());
476                 }
477             };
478         }
479     }
480
481 }
482
Popular Tags