KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > infoviews > SourceView


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 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.infoviews;
12
13 import java.io.IOException JavaDoc;
14
15 import org.eclipse.core.runtime.Assert;
16
17 import org.eclipse.swt.SWT;
18 import org.eclipse.swt.custom.StyledText;
19 import org.eclipse.swt.graphics.Color;
20 import org.eclipse.swt.graphics.Font;
21 import org.eclipse.swt.graphics.Point;
22 import org.eclipse.swt.widgets.Composite;
23 import org.eclipse.swt.widgets.Control;
24
25 import org.eclipse.jface.action.Action;
26 import org.eclipse.jface.action.IAction;
27 import org.eclipse.jface.action.IMenuListener;
28 import org.eclipse.jface.action.IMenuManager;
29 import org.eclipse.jface.preference.IPreferenceStore;
30 import org.eclipse.jface.resource.JFaceResources;
31 import org.eclipse.jface.util.IPropertyChangeListener;
32 import org.eclipse.jface.util.PropertyChangeEvent;
33 import org.eclipse.jface.viewers.ISelection;
34 import org.eclipse.jface.viewers.IStructuredSelection;
35 import org.eclipse.jface.viewers.StructuredSelection;
36
37 import org.eclipse.jface.text.BadLocationException;
38 import org.eclipse.jface.text.Document;
39 import org.eclipse.jface.text.IDocument;
40 import org.eclipse.jface.text.IRegion;
41 import org.eclipse.jface.text.ITextOperationTarget;
42 import org.eclipse.jface.text.ITextSelection;
43 import org.eclipse.jface.text.TextViewer;
44 import org.eclipse.jface.text.source.SourceViewer;
45
46 import org.eclipse.ui.IActionBars;
47 import org.eclipse.ui.PlatformUI;
48 import org.eclipse.ui.texteditor.IAbstractTextEditorHelpContextIds;
49
50 import org.eclipse.jdt.core.ICodeAssist;
51 import org.eclipse.jdt.core.IJavaElement;
52 import org.eclipse.jdt.core.IJavaProject;
53 import org.eclipse.jdt.core.ISourceRange;
54 import org.eclipse.jdt.core.ISourceReference;
55 import org.eclipse.jdt.core.JavaModelException;
56
57 import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
58 import org.eclipse.jdt.internal.corext.util.Strings;
59
60 import org.eclipse.jdt.ui.IContextMenuConstants;
61 import org.eclipse.jdt.ui.actions.IJavaEditorActionDefinitionIds;
62 import org.eclipse.jdt.ui.actions.JdtActionConstants;
63 import org.eclipse.jdt.ui.actions.OpenAction;
64 import org.eclipse.jdt.ui.text.IJavaPartitions;
65 import org.eclipse.jdt.ui.text.JavaSourceViewerConfiguration;
66
67 import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
68 import org.eclipse.jdt.internal.ui.JavaPlugin;
69 import org.eclipse.jdt.internal.ui.javaeditor.JavaSourceViewer;
70 import org.eclipse.jdt.internal.ui.text.JavaCodeReader;
71 import org.eclipse.jdt.internal.ui.text.SimpleJavaSourceViewerConfiguration;
72
73 /**
74  * View which shows source for a given Java element.
75  *
76  * @since 3.0
77  */

78 public class SourceView extends AbstractInfoView implements IMenuListener {
79
80     /** Symbolic Java editor font name. */
81     private static final String JavaDoc SYMBOLIC_FONT_NAME= "org.eclipse.jdt.ui.editors.textfont"; //$NON-NLS-1$
82

83     /**
84      * Internal property change listener for handling changes in the editor's preferences.
85      *
86      * @since 3.0
87      */

88     class PropertyChangeListener implements IPropertyChangeListener {
89         /*
90          * @see IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
91          */

92         public void propertyChange(PropertyChangeEvent event) {
93             if (fViewer == null)
94                 return;
95
96             if (fViewerConfiguration.affectsTextPresentation(event)) {
97                 fViewerConfiguration.handlePropertyChangeEvent(event);
98                 fViewer.invalidateTextPresentation();
99             }
100         }
101     }
102
103     /**
104      * Internal property change listener for handling workbench font changes.
105      */

106     class FontPropertyChangeListener implements IPropertyChangeListener {
107         /*
108          * @see IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
109          */

110         public void propertyChange(PropertyChangeEvent event) {
111             if (fViewer == null)
112                 return;
113
114             String JavaDoc property= event.getProperty();
115
116             if (SYMBOLIC_FONT_NAME.equals(property))
117                 setViewerFont();
118         }
119     }
120
121     /**
122      * The Javadoc view's select all action.
123      */

124     private static class SelectAllAction extends Action {
125
126         private TextViewer fTextViewer;
127
128         /**
129          * Creates the action.
130          *
131          * @param textViewer the text viewer
132          */

133         public SelectAllAction(TextViewer textViewer) {
134             super("selectAll"); //$NON-NLS-1$
135

136             Assert.isNotNull(textViewer);
137             fTextViewer= textViewer;
138
139             setText(InfoViewMessages.SelectAllAction_label);
140             setToolTipText(InfoViewMessages.SelectAllAction_tooltip);
141             setDescription(InfoViewMessages.SelectAllAction_description);
142
143             PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IAbstractTextEditorHelpContextIds.SELECT_ALL_ACTION);
144         }
145
146         /**
147          * Selects all in the viewer.
148          */

149         public void run() {
150             fTextViewer.doOperation(ITextOperationTarget.SELECT_ALL);
151         }
152     }
153
154     /** This view's source viewer */
155     private SourceViewer fViewer;
156     /** The viewers configuration */
157     private JavaSourceViewerConfiguration fViewerConfiguration;
158     /** The viewer's font properties change listener. */
159     private IPropertyChangeListener fFontPropertyChangeListener= new FontPropertyChangeListener();
160     /**
161      * The editor's property change listener.
162      * @since 3.0
163      */

164     private IPropertyChangeListener fPropertyChangeListener= new PropertyChangeListener();
165     /** The open action */
166     private OpenAction fOpen;
167     /** The number of removed leading comment lines. */
168     private int fCommentLineCount;
169     /** The select all action. */
170     private SelectAllAction fSelectAllAction;
171     /** Element opened by the open action. */
172     private IJavaElement fLastOpenedElement;
173
174
175     /*
176      * @see AbstractInfoView#internalCreatePartControl(Composite)
177      */

178     protected void internalCreatePartControl(Composite parent) {
179         IPreferenceStore store= JavaPlugin.getDefault().getCombinedPreferenceStore();
180         fViewer= new JavaSourceViewer(parent, null, null, false, SWT.V_SCROLL | SWT.H_SCROLL, store);
181         fViewerConfiguration= new SimpleJavaSourceViewerConfiguration(JavaPlugin.getDefault().getJavaTextTools().getColorManager(), store, null, IJavaPartitions.JAVA_PARTITIONING, false);
182         fViewer.configure(fViewerConfiguration);
183         fViewer.setEditable(false);
184
185         setViewerFont();
186         JFaceResources.getFontRegistry().addListener(fFontPropertyChangeListener);
187
188         store.addPropertyChangeListener(fPropertyChangeListener);
189
190         getViewSite().setSelectionProvider(fViewer);
191     }
192
193     /*
194      * @see AbstractInfoView#internalCreatePartControl(Composite)
195      */

196     protected void createActions() {
197         super.createActions();
198         fSelectAllAction= new SelectAllAction(fViewer);
199
200         // Setup OpenAction
201
fOpen= new OpenAction(getViewSite()) {
202
203             /*
204              * @see org.eclipse.jdt.ui.actions.SelectionDispatchAction#getSelection()
205              */

206             public ISelection getSelection() {
207                 return convertToJavaElementSelection(fViewer.getSelection());
208             }
209
210             /*
211              * @see org.eclipse.jdt.ui.actions.OpenAction#run(IStructuredSelection)
212              */

213             public void run(IStructuredSelection selection) {
214                 if (selection.isEmpty()) {
215                     getShell().getDisplay().beep();
216                     return;
217                 }
218                 super.run(selection);
219             }
220
221             /*
222              * @see org.eclipse.jdt.ui.actions.OpenAction#getElementToOpen(Object)
223              */

224             public Object JavaDoc getElementToOpen(Object JavaDoc object) throws JavaModelException {
225                 if (object instanceof IJavaElement)
226                     fLastOpenedElement= (IJavaElement)object;
227                 else
228                     fLastOpenedElement= null;
229                 return super.getElementToOpen(object);
230             }
231
232             /*
233              * @see org.eclipse.jdt.ui.actions.OpenAction#run(Object[])
234              */

235             public void run(Object JavaDoc[] elements) {
236                 stopListeningForSelectionChanges();
237                 super.run(elements);
238                 startListeningForSelectionChanges();
239             }
240         };
241     }
242
243
244     /*
245      * @see org.eclipse.jdt.internal.ui.infoviews.AbstractInfoView#getSelectAllAction()
246      * @since 3.0
247      */

248     protected IAction getSelectAllAction() {
249         return fSelectAllAction;
250     }
251
252     /*
253      * @see AbstractInfoView#fillActionBars(IActionBars)
254      */

255     protected void fillActionBars(IActionBars actionBars) {
256         super.fillActionBars(actionBars);
257         actionBars.setGlobalActionHandler(JdtActionConstants.OPEN, fOpen);
258         fOpen.setActionDefinitionId(IJavaEditorActionDefinitionIds.OPEN_EDITOR);
259     }
260
261     /*
262      * @see AbstractInfoView#getControl()
263      */

264     protected Control getControl() {
265         return fViewer.getControl();
266     }
267
268     /*
269      * @see AbstractInfoView#menuAboutToShow(IMenuManager)
270      */

271     public void menuAboutToShow(IMenuManager menu) {
272         super.menuAboutToShow(menu);
273         menu.appendToGroup(IContextMenuConstants.GROUP_OPEN, fOpen);
274     }
275
276     /*
277      * @see AbstractInfoView#setForeground(Color)
278      */

279     protected void setForeground(Color color) {
280         fViewer.getTextWidget().setForeground(color);
281     }
282
283     /*
284      * @see AbstractInfoView#setBackground(Color)
285      */

286     protected void setBackground(Color color) {
287         fViewer.getTextWidget().setBackground(color);
288     }
289     
290     /*
291      * @see org.eclipse.jdt.internal.ui.infoviews.AbstractInfoView#getBackgroundColorKey()
292      * @since 3.2
293      */

294     protected String JavaDoc getBackgroundColorKey() {
295         return "org.eclipse.jdt.ui.DeclarationView.backgroundColor"; //$NON-NLS-1$
296
}
297     
298     /**
299      * Converts the given selection to a structured selection
300      * containing Java elements.
301      *
302      * @param selection the selection
303      * @return a structured selection with Java elements
304      */

305     private IStructuredSelection convertToJavaElementSelection(ISelection selection) {
306
307         if (!(selection instanceof ITextSelection && fCurrentViewInput instanceof ISourceReference))
308             return StructuredSelection.EMPTY;
309
310         ITextSelection textSelection= (ITextSelection)selection;
311
312         Object JavaDoc codeAssist= fCurrentViewInput.getAncestor(IJavaElement.COMPILATION_UNIT);
313         if (codeAssist == null)
314             codeAssist= fCurrentViewInput.getAncestor(IJavaElement.CLASS_FILE);
315
316         if (codeAssist instanceof ICodeAssist) {
317             IJavaElement[] elements= null;
318             try {
319                 ISourceRange range= ((ISourceReference)fCurrentViewInput).getSourceRange();
320                 elements= ((ICodeAssist)codeAssist).codeSelect(range.getOffset() + getOffsetInUnclippedDocument(textSelection), textSelection.getLength());
321             } catch (JavaModelException e) {
322                 return StructuredSelection.EMPTY;
323             }
324             if (elements != null && elements.length > 0) {
325                 return new StructuredSelection(elements[0]);
326             } else
327                 return StructuredSelection.EMPTY;
328         }
329
330         return StructuredSelection.EMPTY;
331     }
332
333     /**
334      * Computes and returns the offset in the unclipped document
335      * based on the given text selection from the clipped
336      * document.
337      *
338      * @param textSelection
339      * @return the offest in the unclipped document or <code>-1</code> if the offset cannot be computed
340      */

341     private int getOffsetInUnclippedDocument(ITextSelection textSelection) {
342         IDocument unclippedDocument= null;
343         try {
344             unclippedDocument= new Document(((ISourceReference)fCurrentViewInput).getSource());
345         } catch (JavaModelException e) {
346             return -1;
347         }
348         IDocument clippedDoc= (IDocument)fViewer.getInput();
349         try {
350             IRegion unclippedLineInfo= unclippedDocument.getLineInformation(fCommentLineCount + textSelection.getStartLine());
351             IRegion clippedLineInfo= clippedDoc.getLineInformation(textSelection.getStartLine());
352             int removedIndentation= unclippedLineInfo.getLength() - clippedLineInfo.getLength();
353             int relativeLineOffset= textSelection.getOffset() - clippedLineInfo.getOffset();
354             return unclippedLineInfo.getOffset() + removedIndentation + relativeLineOffset ;
355         } catch (BadLocationException ex) {
356             return -1;
357         }
358     }
359
360     /*
361      * @see AbstractInfoView#internalDispose()
362      */

363     protected void internalDispose() {
364         fViewer= null;
365         fViewerConfiguration= null;
366         JFaceResources.getFontRegistry().removeListener(fFontPropertyChangeListener);
367         JavaPlugin.getDefault().getCombinedPreferenceStore().removePropertyChangeListener(fPropertyChangeListener);
368     }
369
370     /*
371      * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
372      */

373     public void setFocus() {
374         fViewer.getTextWidget().setFocus();
375     }
376
377     /*
378      * @see AbstractInfoView#computeInput(Object)
379      */

380     protected Object JavaDoc computeInput(Object JavaDoc input) {
381
382         if (fViewer == null || !(input instanceof ISourceReference))
383             return null;
384
385         ISourceReference sourceRef= (ISourceReference)input;
386
387         if (fLastOpenedElement != null && input instanceof IJavaElement && ((IJavaElement)input).getHandleIdentifier().equals(fLastOpenedElement.getHandleIdentifier())) {
388             fLastOpenedElement= null;
389             return null;
390         } else {
391             fLastOpenedElement= null;
392         }
393
394         String JavaDoc source;
395         try {
396             source= sourceRef.getSource();
397         } catch (JavaModelException ex) {
398             return ""; //$NON-NLS-1$
399
}
400
401         if (source == null)
402             return ""; //$NON-NLS-1$
403

404         source= removeLeadingComments(source);
405         String JavaDoc delim= StubUtility.getLineDelimiterUsed((IJavaElement) input);
406
407         String JavaDoc[] sourceLines= Strings.convertIntoLines(source);
408         if (sourceLines == null || sourceLines.length == 0)
409             return ""; //$NON-NLS-1$
410

411         String JavaDoc firstLine= sourceLines[0];
412         boolean firstCharNotWhitespace= firstLine != null && firstLine.length() > 0 && !Character.isWhitespace(firstLine.charAt(0));
413         if (firstCharNotWhitespace)
414             sourceLines[0]= ""; //$NON-NLS-1$
415
IJavaProject project;
416         if (input instanceof IJavaElement)
417             project= ((IJavaElement) input).getJavaProject();
418         else
419             project= null;
420         Strings.trimIndentation(sourceLines, project);
421
422         if (firstCharNotWhitespace)
423             sourceLines[0]= firstLine;
424
425         return Strings.concatenate(sourceLines, delim);
426     }
427
428     /*
429      * @see AbstractInfoView#setInput(Object)
430      */

431     protected void setInput(Object JavaDoc input) {
432         if (input instanceof IDocument)
433             fViewer.setInput(input);
434         else if (input == null)
435             fViewer.setInput(new Document("")); //$NON-NLS-1$
436
else {
437             IDocument document= new Document(input.toString());
438             JavaPlugin.getDefault().getJavaTextTools().setupJavaDocumentPartitioner(document, IJavaPartitions.JAVA_PARTITIONING);
439             fViewer.setInput(document);
440         }
441     }
442
443     /**
444      * Removes the leading comments from the given source.
445      *
446      * @param source the string with the source
447      * @return the source without leading comments
448      */

449     private String JavaDoc removeLeadingComments(String JavaDoc source) {
450         JavaCodeReader reader= new JavaCodeReader();
451         IDocument document= new Document(source);
452         int i;
453         try {
454             reader.configureForwardReader(document, 0, document.getLength(), true, false);
455             int c= reader.read();
456             while (c != -1 && (c == '\r' || c == '\n' || c == '\t')) {
457                 c= reader.read();
458             }
459             i= reader.getOffset();
460             reader.close();
461         } catch (IOException JavaDoc ex) {
462             i= 0;
463         } finally {
464             try {
465                 if (reader != null)
466                     reader.close();
467             } catch (IOException JavaDoc ex) {
468                 JavaPlugin.log(ex);
469             }
470         }
471
472         try {
473             fCommentLineCount= document.getLineOfOffset(i);
474         } catch (BadLocationException e) {
475             fCommentLineCount= 0;
476         }
477
478         if (i < 0)
479             return source;
480
481         return source.substring(i);
482     }
483
484     /**
485      * Sets the font for this viewer sustaining selection and scroll position.
486      */

487     private void setViewerFont() {
488         Font font= JFaceResources.getFont(SYMBOLIC_FONT_NAME);
489
490         if (fViewer.getDocument() != null) {
491
492             Point selection= fViewer.getSelectedRange();
493             int topIndex= fViewer.getTopIndex();
494
495             StyledText styledText= fViewer.getTextWidget();
496             Control parent= fViewer.getControl();
497
498             parent.setRedraw(false);
499
500             styledText.setFont(font);
501
502             fViewer.setSelectedRange(selection.x , selection.y);
503             fViewer.setTopIndex(topIndex);
504
505             if (parent instanceof Composite) {
506                 Composite composite= (Composite) parent;
507                 composite.layout(true);
508             }
509
510             parent.setRedraw(true);
511
512
513         } else {
514             StyledText styledText= fViewer.getTextWidget();
515             styledText.setFont(font);
516         }
517     }
518
519     /*
520      * @see org.eclipse.jdt.internal.ui.infoviews.AbstractInfoView#getHelpContextId()
521      * @since 3.1
522      */

523     protected String JavaDoc getHelpContextId() {
524         return IJavaHelpContextIds.SOURCE_VIEW;
525     }
526 }
527
Popular Tags