KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > javaeditor > JavaEditor


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.jdt.internal.ui.javaeditor;
12
13 import com.ibm.icu.text.BreakIterator;
14
15 import java.text.CharacterIterator JavaDoc;
16 import java.util.ArrayList JavaDoc;
17 import java.util.HashMap JavaDoc;
18 import java.util.Iterator JavaDoc;
19 import java.util.List JavaDoc;
20 import java.util.Map JavaDoc;
21
22 import org.eclipse.core.commands.operations.IOperationApprover;
23 import org.eclipse.core.commands.operations.IUndoContext;
24
25 import org.eclipse.core.runtime.CoreException;
26 import org.eclipse.core.runtime.IProgressMonitor;
27 import org.eclipse.core.runtime.IStatus;
28 import org.eclipse.core.runtime.ListenerList;
29 import org.eclipse.core.runtime.NullProgressMonitor;
30 import org.eclipse.core.runtime.Status;
31 import org.eclipse.core.runtime.jobs.Job;
32 import org.eclipse.core.runtime.preferences.IEclipsePreferences;
33 import org.eclipse.core.runtime.preferences.IScopeContext;
34
35 import org.eclipse.core.resources.IResource;
36 import org.eclipse.core.resources.ProjectScope;
37
38 import org.eclipse.swt.SWT;
39 import org.eclipse.swt.custom.ST;
40 import org.eclipse.swt.custom.StyledText;
41 import org.eclipse.swt.graphics.Image;
42 import org.eclipse.swt.graphics.Point;
43 import org.eclipse.swt.widgets.Composite;
44 import org.eclipse.swt.widgets.Display;
45 import org.eclipse.swt.widgets.Shell;
46
47 import org.eclipse.help.IContextProvider;
48
49 import org.eclipse.jface.action.Action;
50 import org.eclipse.jface.action.GroupMarker;
51 import org.eclipse.jface.action.IAction;
52 import org.eclipse.jface.action.IMenuManager;
53 import org.eclipse.jface.action.MenuManager;
54 import org.eclipse.jface.preference.IPreferenceStore;
55 import org.eclipse.jface.util.IPropertyChangeListener;
56 import org.eclipse.jface.util.PropertyChangeEvent;
57 import org.eclipse.jface.viewers.DoubleClickEvent;
58 import org.eclipse.jface.viewers.IDoubleClickListener;
59 import org.eclipse.jface.viewers.IPostSelectionProvider;
60 import org.eclipse.jface.viewers.ISelection;
61 import org.eclipse.jface.viewers.ISelectionChangedListener;
62 import org.eclipse.jface.viewers.ISelectionProvider;
63 import org.eclipse.jface.viewers.IStructuredSelection;
64 import org.eclipse.jface.viewers.SelectionChangedEvent;
65 import org.eclipse.jface.viewers.StructuredSelection;
66
67 import org.eclipse.jface.text.BadLocationException;
68 import org.eclipse.jface.text.DocumentEvent;
69 import org.eclipse.jface.text.IDocument;
70 import org.eclipse.jface.text.IDocumentExtension4;
71 import org.eclipse.jface.text.IDocumentListener;
72 import org.eclipse.jface.text.IInformationControl;
73 import org.eclipse.jface.text.IInformationControlCreator;
74 import org.eclipse.jface.text.IRegion;
75 import org.eclipse.jface.text.ISelectionValidator;
76 import org.eclipse.jface.text.ISynchronizable;
77 import org.eclipse.jface.text.ITextHover;
78 import org.eclipse.jface.text.ITextInputListener;
79 import org.eclipse.jface.text.ITextOperationTarget;
80 import org.eclipse.jface.text.ITextSelection;
81 import org.eclipse.jface.text.ITextViewer;
82 import org.eclipse.jface.text.ITextViewerExtension2;
83 import org.eclipse.jface.text.ITextViewerExtension5;
84 import org.eclipse.jface.text.Position;
85 import org.eclipse.jface.text.Region;
86 import org.eclipse.jface.text.TextUtilities;
87 import org.eclipse.jface.text.link.LinkedModeModel;
88 import org.eclipse.jface.text.link.LinkedPosition;
89 import org.eclipse.jface.text.reconciler.IReconciler;
90 import org.eclipse.jface.text.source.Annotation;
91 import org.eclipse.jface.text.source.AnnotationRulerColumn;
92 import org.eclipse.jface.text.source.CompositeRuler;
93 import org.eclipse.jface.text.source.IAnnotationModel;
94 import org.eclipse.jface.text.source.IAnnotationModelExtension;
95 import org.eclipse.jface.text.source.ICharacterPairMatcher;
96 import org.eclipse.jface.text.source.IOverviewRuler;
97 import org.eclipse.jface.text.source.ISourceViewer;
98 import org.eclipse.jface.text.source.ISourceViewerExtension2;
99 import org.eclipse.jface.text.source.IVerticalRuler;
100 import org.eclipse.jface.text.source.IVerticalRulerColumn;
101 import org.eclipse.jface.text.source.LineChangeHover;
102 import org.eclipse.jface.text.source.SourceViewerConfiguration;
103 import org.eclipse.jface.text.source.projection.ProjectionSupport;
104 import org.eclipse.jface.text.source.projection.ProjectionViewer;
105
106 import org.eclipse.ui.IEditorInput;
107 import org.eclipse.ui.IEditorPart;
108 import org.eclipse.ui.IPageLayout;
109 import org.eclipse.ui.IPartListener2;
110 import org.eclipse.ui.IPartService;
111 import org.eclipse.ui.ISelectionListener;
112 import org.eclipse.ui.IWindowListener;
113 import org.eclipse.ui.IWorkbenchPage;
114 import org.eclipse.ui.IWorkbenchPart;
115 import org.eclipse.ui.IWorkbenchPartReference;
116 import org.eclipse.ui.IWorkbenchPartSite;
117 import org.eclipse.ui.IWorkbenchWindow;
118 import org.eclipse.ui.PlatformUI;
119 import org.eclipse.ui.actions.ActionContext;
120 import org.eclipse.ui.actions.ActionGroup;
121 import org.eclipse.ui.operations.NonLocalUndoUserApprover;
122 import org.eclipse.ui.part.IShowInSource;
123 import org.eclipse.ui.part.IShowInTargetList;
124 import org.eclipse.ui.part.ShowInContext;
125 import org.eclipse.ui.texteditor.AbstractDecoratedTextEditor;
126 import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
127 import org.eclipse.ui.texteditor.AnnotationPreference;
128 import org.eclipse.ui.texteditor.ChainedPreferenceStore;
129 import org.eclipse.ui.texteditor.IDocumentProvider;
130 import org.eclipse.ui.texteditor.ITextEditorActionConstants;
131 import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
132 import org.eclipse.ui.texteditor.IUpdate;
133 import org.eclipse.ui.texteditor.MarkerAnnotation;
134 import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;
135 import org.eclipse.ui.texteditor.TextNavigationAction;
136 import org.eclipse.ui.texteditor.TextOperationAction;
137
138 import org.eclipse.ui.editors.text.DefaultEncodingSupport;
139 import org.eclipse.ui.editors.text.EditorsUI;
140 import org.eclipse.ui.editors.text.IEncodingSupport;
141
142 import org.eclipse.ui.views.contentoutline.ContentOutline;
143 import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
144
145 import org.eclipse.jdt.core.IClassFile;
146 import org.eclipse.jdt.core.ICompilationUnit;
147 import org.eclipse.jdt.core.IImportContainer;
148 import org.eclipse.jdt.core.IImportDeclaration;
149 import org.eclipse.jdt.core.IJavaElement;
150 import org.eclipse.jdt.core.IJavaProject;
151 import org.eclipse.jdt.core.ILocalVariable;
152 import org.eclipse.jdt.core.IMember;
153 import org.eclipse.jdt.core.IPackageDeclaration;
154 import org.eclipse.jdt.core.ISourceRange;
155 import org.eclipse.jdt.core.ISourceReference;
156 import org.eclipse.jdt.core.ITypeParameter;
157 import org.eclipse.jdt.core.JavaCore;
158 import org.eclipse.jdt.core.JavaModelException;
159 import org.eclipse.jdt.core.dom.ASTNode;
160 import org.eclipse.jdt.core.dom.CompilationUnit;
161 import org.eclipse.jdt.core.dom.IBinding;
162 import org.eclipse.jdt.core.dom.IVariableBinding;
163 import org.eclipse.jdt.core.dom.Name;
164 import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
165 import org.eclipse.jdt.core.util.IModifierConstants;
166
167 import org.eclipse.jdt.internal.corext.dom.NodeFinder;
168 import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
169
170 import org.eclipse.jdt.ui.IContextMenuConstants;
171 import org.eclipse.jdt.ui.JavaUI;
172 import org.eclipse.jdt.ui.PreferenceConstants;
173 import org.eclipse.jdt.ui.actions.IJavaEditorActionDefinitionIds;
174 import org.eclipse.jdt.ui.actions.JavaSearchActionGroup;
175 import org.eclipse.jdt.ui.actions.OpenEditorActionGroup;
176 import org.eclipse.jdt.ui.actions.OpenViewActionGroup;
177 import org.eclipse.jdt.ui.actions.ShowInPackageViewAction;
178 import org.eclipse.jdt.ui.text.IJavaPartitions;
179 import org.eclipse.jdt.ui.text.JavaSourceViewerConfiguration;
180 import org.eclipse.jdt.ui.text.JavaTextTools;
181 import org.eclipse.jdt.ui.text.folding.IJavaFoldingStructureProvider;
182 import org.eclipse.jdt.ui.text.folding.IJavaFoldingStructureProviderExtension;
183
184 import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
185 import org.eclipse.jdt.internal.ui.JavaPlugin;
186 import org.eclipse.jdt.internal.ui.actions.CompositeActionGroup;
187 import org.eclipse.jdt.internal.ui.actions.CopyQualifiedNameAction;
188 import org.eclipse.jdt.internal.ui.actions.FoldingActionGroup;
189 import org.eclipse.jdt.internal.ui.actions.SelectionConverter;
190 import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.GoToNextPreviousMemberAction;
191 import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.SelectionHistory;
192 import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectEnclosingAction;
193 import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectHistoryAction;
194 import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectNextAction;
195 import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectPreviousAction;
196 import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectionAction;
197 import org.eclipse.jdt.internal.ui.search.BreakContinueTargetFinder;
198 import org.eclipse.jdt.internal.ui.search.ExceptionOccurrencesFinder;
199 import org.eclipse.jdt.internal.ui.search.ImplementOccurrencesFinder;
200 import org.eclipse.jdt.internal.ui.search.MethodExitsFinder;
201 import org.eclipse.jdt.internal.ui.search.OccurrencesFinder;
202 import org.eclipse.jdt.internal.ui.text.DocumentCharacterIterator;
203 import org.eclipse.jdt.internal.ui.text.JavaChangeHover;
204 import org.eclipse.jdt.internal.ui.text.JavaPairMatcher;
205 import org.eclipse.jdt.internal.ui.text.JavaWordFinder;
206 import org.eclipse.jdt.internal.ui.text.JavaWordIterator;
207 import org.eclipse.jdt.internal.ui.text.PreferencesAdapter;
208 import org.eclipse.jdt.internal.ui.text.java.hover.JavaExpandHover;
209 import org.eclipse.jdt.internal.ui.text.java.hover.SourceViewerInformationControl;
210 import org.eclipse.jdt.internal.ui.util.JavaUIHelp;
211 import org.eclipse.jdt.internal.ui.viewsupport.ISelectionListenerWithAST;
212 import org.eclipse.jdt.internal.ui.viewsupport.IViewPartInputProvider;
213 import org.eclipse.jdt.internal.ui.viewsupport.SelectionListenerWithASTManager;
214
215 import org.osgi.service.prefs.BackingStoreException;
216
217 /**
218  * Java specific text editor.
219  */

220 public abstract class JavaEditor extends AbstractDecoratedTextEditor implements IViewPartInputProvider {
221
222     /**
223      * Internal implementation class for a change listener.
224      * @since 3.0
225      */

226     protected abstract class AbstractSelectionChangedListener implements ISelectionChangedListener {
227
228         /**
229          * Installs this selection changed listener with the given selection provider. If
230          * the selection provider is a post selection provider, post selection changed
231          * events are the preferred choice, otherwise normal selection changed events
232          * are requested.
233          *
234          * @param selectionProvider
235          */

236         public void install(ISelectionProvider selectionProvider) {
237             if (selectionProvider == null)
238                 return;
239
240             if (selectionProvider instanceof IPostSelectionProvider) {
241                 IPostSelectionProvider provider= (IPostSelectionProvider) selectionProvider;
242                 provider.addPostSelectionChangedListener(this);
243             } else {
244                 selectionProvider.addSelectionChangedListener(this);
245             }
246         }
247
248         /**
249          * Removes this selection changed listener from the given selection provider.
250          *
251          * @param selectionProvider the selection provider
252          */

253         public void uninstall(ISelectionProvider selectionProvider) {
254             if (selectionProvider == null)
255                 return;
256
257             if (selectionProvider instanceof IPostSelectionProvider) {
258                 IPostSelectionProvider provider= (IPostSelectionProvider) selectionProvider;
259                 provider.removePostSelectionChangedListener(this);
260             } else {
261                 selectionProvider.removeSelectionChangedListener(this);
262             }
263         }
264     }
265
266     /**
267      * Updates the Java outline page selection and this editor's range indicator.
268      *
269      * @since 3.0
270      */

271     private class EditorSelectionChangedListener extends AbstractSelectionChangedListener {
272
273         /*
274          * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
275          */

276         public void selectionChanged(SelectionChangedEvent event) {
277             // XXX: see https://bugs.eclipse.org/bugs/show_bug.cgi?id=56161
278
JavaEditor.this.selectionChanged();
279         }
280     }
281
282     /**
283      * Updates the selection in the editor's widget with the selection of the outline page.
284      */

285     class OutlineSelectionChangedListener extends AbstractSelectionChangedListener {
286         public void selectionChanged(SelectionChangedEvent event) {
287             doSelectionChanged(event);
288         }
289     }
290
291
292     /**
293      * Adapts an options {@link IEclipsePreferences} to {@link org.eclipse.jface.preference.IPreferenceStore}.
294      * <p>
295      * This preference store is read-only i.e. write access
296      * throws an {@link java.lang.UnsupportedOperationException}.
297      * </p>
298      *
299      * @since 3.1
300      */

301     private static class EclipsePreferencesAdapter implements IPreferenceStore {
302
303         /**
304          * Preference change listener. Listens for events preferences
305          * fires a {@link org.eclipse.jface.util.PropertyChangeEvent}
306          * on this adapter with arguments from the received event.
307          */

308         private class PreferenceChangeListener implements IEclipsePreferences.IPreferenceChangeListener {
309
310             /**
311              * {@inheritDoc}
312              */

313             public void preferenceChange(final IEclipsePreferences.PreferenceChangeEvent event) {
314                 if (Display.getCurrent() == null) {
315                     Display.getDefault().asyncExec(new Runnable JavaDoc() {
316                         public void run() {
317                             firePropertyChangeEvent(event.getKey(), event.getOldValue(), event.getNewValue());
318                         }
319                     });
320                 } else {
321                     firePropertyChangeEvent(event.getKey(), event.getOldValue(), event.getNewValue());
322                 }
323             }
324         }
325
326         /** Listeners on on this adapter */
327         private ListenerList fListeners= new ListenerList(ListenerList.IDENTITY);
328
329         /** Listener on the node */
330         private IEclipsePreferences.IPreferenceChangeListener fListener= new PreferenceChangeListener();
331
332         /** wrapped node */
333         private final IScopeContext fContext;
334         private final String JavaDoc fQualifier;
335
336         /**
337          * Initialize with the node to wrap
338          *
339          * @param context the context to access
340          * @param qualifier the qualifier
341          */

342         public EclipsePreferencesAdapter(IScopeContext context, String JavaDoc qualifier) {
343             fContext= context;
344             fQualifier= qualifier;
345         }
346
347         private IEclipsePreferences getNode() {
348             return fContext.getNode(fQualifier);
349         }
350
351         /**
352          * {@inheritDoc}
353          */

354         public void addPropertyChangeListener(IPropertyChangeListener listener) {
355             if (fListeners.size() == 0)
356                 getNode().addPreferenceChangeListener(fListener);
357             fListeners.add(listener);
358         }
359
360         /**
361          * {@inheritDoc}
362          */

363         public void removePropertyChangeListener(IPropertyChangeListener listener) {
364             fListeners.remove(listener);
365             if (fListeners.size() == 0) {
366                 getNode().removePreferenceChangeListener(fListener);
367             }
368         }
369
370         /**
371          * {@inheritDoc}
372          */

373         public boolean contains(String JavaDoc name) {
374             return getNode().get(name, null) != null;
375         }
376
377         /**
378          * {@inheritDoc}
379          */

380         public void firePropertyChangeEvent(String JavaDoc name, Object JavaDoc oldValue, Object JavaDoc newValue) {
381             PropertyChangeEvent event= new PropertyChangeEvent(this, name, oldValue, newValue);
382             Object JavaDoc[] listeners= fListeners.getListeners();
383             for (int i= 0; i < listeners.length; i++)
384                 ((IPropertyChangeListener) listeners[i]).propertyChange(event);
385         }
386
387         /**
388          * {@inheritDoc}
389          */

390         public boolean getBoolean(String JavaDoc name) {
391             return getNode().getBoolean(name, BOOLEAN_DEFAULT_DEFAULT);
392         }
393
394         /**
395          * {@inheritDoc}
396          */

397         public boolean getDefaultBoolean(String JavaDoc name) {
398             return BOOLEAN_DEFAULT_DEFAULT;
399         }
400
401         /**
402          * {@inheritDoc}
403          */

404         public double getDefaultDouble(String JavaDoc name) {
405             return DOUBLE_DEFAULT_DEFAULT;
406         }
407
408         /**
409          * {@inheritDoc}
410          */

411         public float getDefaultFloat(String JavaDoc name) {
412             return FLOAT_DEFAULT_DEFAULT;
413         }
414
415         /**
416          * {@inheritDoc}
417          */

418         public int getDefaultInt(String JavaDoc name) {
419             return INT_DEFAULT_DEFAULT;
420         }
421
422         /**
423          * {@inheritDoc}
424          */

425         public long getDefaultLong(String JavaDoc name) {
426             return LONG_DEFAULT_DEFAULT;
427         }
428
429         /**
430          * {@inheritDoc}
431          */

432         public String JavaDoc getDefaultString(String JavaDoc name) {
433             return STRING_DEFAULT_DEFAULT;
434         }
435
436         /**
437          * {@inheritDoc}
438          */

439         public double getDouble(String JavaDoc name) {
440             return getNode().getDouble(name, DOUBLE_DEFAULT_DEFAULT);
441         }
442
443         /**
444          * {@inheritDoc}
445          */

446         public float getFloat(String JavaDoc name) {
447             return getNode().getFloat(name, FLOAT_DEFAULT_DEFAULT);
448         }
449
450         /**
451          * {@inheritDoc}
452          */

453         public int getInt(String JavaDoc name) {
454             return getNode().getInt(name, INT_DEFAULT_DEFAULT);
455         }
456
457         /**
458          * {@inheritDoc}
459          */

460         public long getLong(String JavaDoc name) {
461             return getNode().getLong(name, LONG_DEFAULT_DEFAULT);
462         }
463
464         /**
465          * {@inheritDoc}
466          */

467         public String JavaDoc getString(String JavaDoc name) {
468             return getNode().get(name, STRING_DEFAULT_DEFAULT);
469         }
470
471         /**
472          * {@inheritDoc}
473          */

474         public boolean isDefault(String JavaDoc name) {
475             return false;
476         }
477
478         /**
479          * {@inheritDoc}
480          */

481         public boolean needsSaving() {
482             try {
483                 return getNode().keys().length > 0;
484             } catch (BackingStoreException e) {
485                 // ignore
486
}
487             return true;
488         }
489
490         /**
491          * {@inheritDoc}
492          */

493         public void putValue(String JavaDoc name, String JavaDoc value) {
494             throw new UnsupportedOperationException JavaDoc();
495         }
496
497         /**
498          * {@inheritDoc}
499          */

500         public void setDefault(String JavaDoc name, double value) {
501             throw new UnsupportedOperationException JavaDoc();
502         }
503
504         /**
505          * {@inheritDoc}
506          */

507         public void setDefault(String JavaDoc name, float value) {
508             throw new UnsupportedOperationException JavaDoc();
509         }
510
511         /**
512          * {@inheritDoc}
513          */

514         public void setDefault(String JavaDoc name, int value) {
515             throw new UnsupportedOperationException JavaDoc();
516         }
517
518         /**
519          * {@inheritDoc}
520          */

521         public void setDefault(String JavaDoc name, long value) {
522             throw new UnsupportedOperationException JavaDoc();
523         }
524
525         /**
526          * {@inheritDoc}
527          */

528         public void setDefault(String JavaDoc name, String JavaDoc defaultObject) {
529             throw new UnsupportedOperationException JavaDoc();
530         }
531
532         /**
533          * {@inheritDoc}
534          */

535         public void setDefault(String JavaDoc name, boolean value) {
536             throw new UnsupportedOperationException JavaDoc();
537         }
538
539         /**
540          * {@inheritDoc}
541          */

542         public void setToDefault(String JavaDoc name) {
543             throw new UnsupportedOperationException JavaDoc();
544         }
545
546         /**
547          * {@inheritDoc}
548          */

549         public void setValue(String JavaDoc name, double value) {
550             throw new UnsupportedOperationException JavaDoc();
551         }
552
553         /**
554          * {@inheritDoc}
555          */

556         public void setValue(String JavaDoc name, float value) {
557             throw new UnsupportedOperationException JavaDoc();
558         }
559
560         /**
561          * {@inheritDoc}
562          */

563         public void setValue(String JavaDoc name, int value) {
564             throw new UnsupportedOperationException JavaDoc();
565         }
566
567         /**
568          * {@inheritDoc}
569          */

570         public void setValue(String JavaDoc name, long value) {
571             throw new UnsupportedOperationException JavaDoc();
572         }
573
574         /**
575          * {@inheritDoc}
576          */

577         public void setValue(String JavaDoc name, String JavaDoc value) {
578             throw new UnsupportedOperationException JavaDoc();
579         }
580
581         /**
582          * {@inheritDoc}
583          */

584         public void setValue(String JavaDoc name, boolean value) {
585             throw new UnsupportedOperationException JavaDoc();
586         }
587
588     }
589
590
591     /**
592      * Cancels the occurrences finder job upon document changes.
593      *
594      * @since 3.0
595      */

596     class OccurrencesFinderJobCanceler implements IDocumentListener, ITextInputListener {
597
598         public void install() {
599             ISourceViewer sourceViewer= getSourceViewer();
600             if (sourceViewer == null)
601                 return;
602
603             StyledText text= sourceViewer.getTextWidget();
604             if (text == null || text.isDisposed())
605                 return;
606
607             sourceViewer.addTextInputListener(this);
608
609             IDocument document= sourceViewer.getDocument();
610             if (document != null)
611                 document.addDocumentListener(this);
612         }
613
614         public void uninstall() {
615             ISourceViewer sourceViewer= getSourceViewer();
616             if (sourceViewer != null)
617                 sourceViewer.removeTextInputListener(this);
618
619             IDocumentProvider documentProvider= getDocumentProvider();
620             if (documentProvider != null) {
621                 IDocument document= documentProvider.getDocument(getEditorInput());
622                 if (document != null)
623                     document.removeDocumentListener(this);
624             }
625         }
626
627
628         /*
629          * @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent)
630          */

631         public void documentAboutToBeChanged(DocumentEvent event) {
632             if (fOccurrencesFinderJob != null)
633                 fOccurrencesFinderJob.doCancel();
634         }
635
636         /*
637          * @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent)
638          */

639         public void documentChanged(DocumentEvent event) {
640         }
641
642         /*
643          * @see org.eclipse.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IDocument)
644          */

645         public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
646             if (oldInput == null)
647                 return;
648
649             oldInput.removeDocumentListener(this);
650         }
651
652         /*
653          * @see org.eclipse.jface.text.ITextInputListener#inputDocumentChanged(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IDocument)
654          */

655         public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
656             if (newInput == null)
657                 return;
658             newInput.addDocumentListener(this);
659         }
660     }
661
662     /**
663      * This action implements smart home.
664      *
665      * Instead of going to the start of a line it does the following:
666      *
667      * - if smart home/end is enabled and the caret is after the line's first non-whitespace then the caret is moved directly before it, taking JavaDoc and multi-line comments into account.
668      * - if the caret is before the line's first non-whitespace the caret is moved to the beginning of the line
669      * - if the caret is at the beginning of the line see first case.
670      *
671      * @since 3.0
672      */

673     protected class SmartLineStartAction extends LineStartAction {
674
675         /**
676          * Creates a new smart line start action
677          *
678          * @param textWidget the styled text widget
679          * @param doSelect a boolean flag which tells if the text up to the beginning of the line should be selected
680          */

681         public SmartLineStartAction(final StyledText textWidget, final boolean doSelect) {
682             super(textWidget, doSelect);
683         }
684
685         /*
686          * @see org.eclipse.ui.texteditor.AbstractTextEditor.LineStartAction#getLineStartPosition(java.lang.String, int, java.lang.String)
687          */

688         protected int getLineStartPosition(final IDocument document, final String JavaDoc line, final int length, final int offset) {
689
690             String JavaDoc type= IDocument.DEFAULT_CONTENT_TYPE;
691             try {
692                 type= TextUtilities.getContentType(document, IJavaPartitions.JAVA_PARTITIONING, offset, true);
693             } catch (BadLocationException exception) {
694                 // Should not happen
695
}
696
697             int index= super.getLineStartPosition(document, line, length, offset);
698             if (type.equals(IJavaPartitions.JAVA_DOC) || type.equals(IJavaPartitions.JAVA_MULTI_LINE_COMMENT)) {
699                 if (index < length - 1 && line.charAt(index) == '*' && line.charAt(index + 1) != '/') {
700                     do {
701                         ++index;
702                     } while (index < length && Character.isWhitespace(line.charAt(index)));
703                 }
704             } else {
705                 if (index < length - 1 && line.charAt(index) == '/' && line.charAt(index + 1) == '/') {
706                     index++;
707                     do {
708                         ++index;
709                     } while (index < length && Character.isWhitespace(line.charAt(index)));
710                 }
711             }
712             return index;
713         }
714     }
715
716     /**
717      * Text navigation action to navigate to the next sub-word.
718      *
719      * @since 3.0
720      */

721     protected abstract class NextSubWordAction extends TextNavigationAction {
722
723         protected JavaWordIterator fIterator= new JavaWordIterator();
724
725         /**
726          * Creates a new next sub-word action.
727          *
728          * @param code Action code for the default operation. Must be an action code from @see org.eclipse.swt.custom.ST.
729          */

730         protected NextSubWordAction(int code) {
731             super(getSourceViewer().getTextWidget(), code);
732         }
733
734         /*
735          * @see org.eclipse.jface.action.IAction#run()
736          */

737         public void run() {
738             // Check whether we are in a java code partition and the preference is enabled
739
final IPreferenceStore store= getPreferenceStore();
740             if (!store.getBoolean(PreferenceConstants.EDITOR_SUB_WORD_NAVIGATION)) {
741        &