]> git.uio.no Git - ifi-stolz-refaktor.git/blob - case-study/jdt-after/ui/org/eclipse/jdt/internal/ui/infoviews/SourceView.java
Case Study: adding data and statistics
[ifi-stolz-refaktor.git] / case-study / jdt-after / ui / org / eclipse / jdt / internal / ui / infoviews / SourceView.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2011 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 org.eclipse.swt.SWT;
14 import org.eclipse.swt.custom.StyledText;
15 import org.eclipse.swt.graphics.Color;
16 import org.eclipse.swt.graphics.Font;
17 import org.eclipse.swt.graphics.Point;
18 import org.eclipse.swt.widgets.Composite;
19 import org.eclipse.swt.widgets.Control;
20
21 import org.eclipse.core.runtime.Assert;
22
23 import org.eclipse.jface.action.Action;
24 import org.eclipse.jface.action.IAction;
25 import org.eclipse.jface.action.IMenuManager;
26 import org.eclipse.jface.preference.IPreferenceStore;
27 import org.eclipse.jface.resource.JFaceResources;
28 import org.eclipse.jface.util.IPropertyChangeListener;
29 import org.eclipse.jface.util.PropertyChangeEvent;
30 import org.eclipse.jface.viewers.ISelection;
31 import org.eclipse.jface.viewers.IStructuredSelection;
32 import org.eclipse.jface.viewers.StructuredSelection;
33
34 import org.eclipse.jface.text.BadLocationException;
35 import org.eclipse.jface.text.Document;
36 import org.eclipse.jface.text.IDocument;
37 import org.eclipse.jface.text.IRegion;
38 import org.eclipse.jface.text.ITextOperationTarget;
39 import org.eclipse.jface.text.ITextSelection;
40 import org.eclipse.jface.text.TextViewer;
41 import org.eclipse.jface.text.source.SourceViewer;
42
43 import org.eclipse.ui.IActionBars;
44 import org.eclipse.ui.PlatformUI;
45
46 import org.eclipse.ui.texteditor.IAbstractTextEditorHelpContextIds;
47
48 import org.eclipse.jdt.core.ICodeAssist;
49 import org.eclipse.jdt.core.IJavaElement;
50 import org.eclipse.jdt.core.IJavaProject;
51 import org.eclipse.jdt.core.ISourceRange;
52 import org.eclipse.jdt.core.ISourceReference;
53 import org.eclipse.jdt.core.JavaModelException;
54
55 import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
56 import org.eclipse.jdt.internal.corext.util.Strings;
57
58 import org.eclipse.jdt.ui.IContextMenuConstants;
59 import org.eclipse.jdt.ui.actions.OpenAction;
60 import org.eclipse.jdt.ui.text.IJavaPartitions;
61 import org.eclipse.jdt.ui.text.JavaSourceViewerConfiguration;
62
63 import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
64 import org.eclipse.jdt.internal.ui.JavaPlugin;
65 import org.eclipse.jdt.internal.ui.javaeditor.JavaSourceViewer;
66 import org.eclipse.jdt.internal.ui.text.JavaCodeReader;
67 import org.eclipse.jdt.internal.ui.text.SimpleJavaSourceViewerConfiguration;
68
69 /**
70  * View which shows source for a given Java element.
71  *
72  * @since 3.0
73  */
74 public class SourceView extends AbstractInfoView {
75
76         /** Symbolic Java editor font name. */
77         private static final String SYMBOLIC_FONT_NAME= "org.eclipse.jdt.ui.editors.textfont"; //$NON-NLS-1$
78
79         /**
80          * Internal property change listener for handling changes in the editor's preferences.
81          *
82          * @since 3.0
83          */
84         class PropertyChangeListener implements IPropertyChangeListener {
85                 /*
86                  * @see IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
87                  */
88                 public void propertyChange(PropertyChangeEvent event) {
89                         if (fViewer == null)
90                                 return;
91
92                         if (fViewerConfiguration.affectsTextPresentation(event)) {
93                                 fViewerConfiguration.handlePropertyChangeEvent(event);
94                                 fViewer.invalidateTextPresentation();
95                         }
96                 }
97         }
98
99         /**
100          * Internal property change listener for handling workbench font changes.
101          */
102         class FontPropertyChangeListener implements IPropertyChangeListener {
103                 /*
104                  * @see IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
105                  */
106                 public void propertyChange(PropertyChangeEvent event) {
107                         if (fViewer == null)
108                                 return;
109
110                         String property= event.getProperty();
111
112                         if (SYMBOLIC_FONT_NAME.equals(property))
113                                 setViewerFont();
114                 }
115         }
116
117         /**
118          * The Javadoc view's select all action.
119          */
120         private static class SelectAllAction extends Action {
121
122                 private TextViewer fTextViewer;
123
124                 /**
125                  * Creates the action.
126                  *
127                  * @param textViewer the text viewer
128                  */
129                 public SelectAllAction(TextViewer textViewer) {
130                         super("selectAll"); //$NON-NLS-1$
131
132                         Assert.isNotNull(textViewer);
133                         fTextViewer= textViewer;
134
135                         setText(InfoViewMessages.SelectAllAction_label);
136                         setToolTipText(InfoViewMessages.SelectAllAction_tooltip);
137                         setDescription(InfoViewMessages.SelectAllAction_description);
138
139                         PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IAbstractTextEditorHelpContextIds.SELECT_ALL_ACTION);
140                 }
141
142                 /**
143                  * Selects all in the viewer.
144                  */
145                 @Override
146                 public void run() {
147                         fTextViewer.doOperation(ITextOperationTarget.SELECT_ALL);
148                 }
149         }
150
151         /** This view's source viewer */
152         private SourceViewer fViewer;
153         /** The viewers configuration */
154         private JavaSourceViewerConfiguration fViewerConfiguration;
155         /** The viewer's font properties change listener. */
156         private IPropertyChangeListener fFontPropertyChangeListener= new FontPropertyChangeListener();
157         /**
158          * The editor's property change listener.
159          * @since 3.0
160          */
161         private IPropertyChangeListener fPropertyChangeListener= new PropertyChangeListener();
162         /** The open action */
163         public OpenAction fOpen;
164         /** The number of removed leading comment lines. */
165         private int fCommentLineCount;
166         /** The select all action. */
167         private SelectAllAction fSelectAllAction;
168         /** Element opened by the open action. */
169         private IJavaElement fLastOpenedElement;
170
171
172         /*
173          * @see AbstractInfoView#internalCreatePartControl(Composite)
174          */
175         @Override
176         protected void internalCreatePartControl(Composite parent) {
177                 IPreferenceStore store= JavaPlugin.getDefault().getCombinedPreferenceStore();
178                 fViewer= new JavaSourceViewer(parent, null, null, false, SWT.V_SCROLL | SWT.H_SCROLL, store);
179                 fViewerConfiguration= new SimpleJavaSourceViewerConfiguration(JavaPlugin.getDefault().getJavaTextTools().getColorManager(), store, null, IJavaPartitions.JAVA_PARTITIONING, false);
180                 fViewer.configure(fViewerConfiguration);
181                 fViewer.setEditable(false);
182
183                 setViewerFont();
184                 JFaceResources.getFontRegistry().addListener(fFontPropertyChangeListener);
185
186                 store.addPropertyChangeListener(fPropertyChangeListener);
187
188                 getViewSite().setSelectionProvider(fViewer);
189         }
190
191         /*
192          * @see AbstractInfoView#internalCreatePartControl(Composite)
193          */
194         @Override
195         protected void createActions() {
196                 super.createActions();
197                 fSelectAllAction= new SelectAllAction(fViewer);
198
199                 // Setup OpenAction
200                 fOpen= new OpenAction(getViewSite()) {
201
202                         /*
203                          * @see org.eclipse.jdt.ui.actions.SelectionDispatchAction#getSelection()
204                          */
205                         @Override
206                         public ISelection getSelection() {
207                                 return convertToJavaElementSelection(fViewer.getSelection());
208                         }
209
210                         /*
211                          * @see org.eclipse.jdt.ui.actions.OpenAction#run(IStructuredSelection)
212                          */
213                         @Override
214                         public void run(IStructuredSelection selection) {
215                                 if (selection.isEmpty()) {
216                                         getShell().getDisplay().beep();
217                                         return;
218                                 }
219                                 super.run(selection);
220                         }
221
222                         /*
223                          * @see org.eclipse.jdt.ui.actions.OpenAction#getElementToOpen(Object)
224                          */
225                         @Override
226                         public Object getElementToOpen(Object object) throws JavaModelException {
227                                 if (object instanceof IJavaElement)
228                                         fLastOpenedElement= (IJavaElement)object;
229                                 else
230                                         fLastOpenedElement= null;
231                                 return super.getElementToOpen(object);
232                         }
233
234                         /*
235                          * @see org.eclipse.jdt.ui.actions.OpenAction#run(Object[])
236                          */
237                         @Override
238                         public void run(Object[] elements) {
239                                 stopListeningForSelectionChanges();
240                                 super.run(elements);
241                                 startListeningForSelectionChanges();
242                         }
243                 };
244         }
245
246
247         /*
248          * @see org.eclipse.jdt.internal.ui.infoviews.AbstractInfoView#getSelectAllAction()
249          * @since 3.0
250          */
251         @Override
252         protected IAction getSelectAllAction() {
253                 return fSelectAllAction;
254         }
255
256         /*
257          * @see AbstractInfoView#fillActionBars(IActionBars)
258          */
259         @Override
260         protected void fillActionBars(IActionBars actionBars) {
261                 super.fillActionBars(actionBars);
262                 fOpen.generated_5795278149633683358(actionBars);
263         }
264
265         /*
266          * @see AbstractInfoView#getControl()
267          */
268         @Override
269         protected Control getControl() {
270                 return fViewer.getControl();
271         }
272
273         /*
274          * @see AbstractInfoView#menuAboutToShow(IMenuManager)
275          */
276         @Override
277         public void menuAboutToShow(IMenuManager menu) {
278                 super.menuAboutToShow(menu);
279                 menu.appendToGroup(IContextMenuConstants.GROUP_OPEN, fOpen);
280         }
281
282         /*
283          * @see AbstractInfoView#setForeground(Color)
284          */
285         @Override
286         protected void setForeground(Color color) {
287                 fViewer.getTextWidget().setForeground(color);
288         }
289
290         /*
291          * @see AbstractInfoView#setBackground(Color)
292          */
293         @Override
294         protected void setBackground(Color color) {
295                 fViewer.getTextWidget().setBackground(color);
296         }
297
298         /*
299          * @see org.eclipse.jdt.internal.ui.infoviews.AbstractInfoView#getBackgroundColorKey()
300          * @since 3.2
301          */
302         @Override
303         protected String getBackgroundColorKey() {
304                 return "org.eclipse.jdt.ui.DeclarationView.backgroundColor";             //$NON-NLS-1$
305         }
306
307         /**
308          * Converts the given selection to a structured selection
309          * containing Java elements.
310          *
311          * @param selection the selection
312          * @return a structured selection with Java elements
313          */
314         private IStructuredSelection convertToJavaElementSelection(ISelection selection) {
315
316                 if (!(selection instanceof ITextSelection && fCurrentViewInput instanceof ISourceReference))
317                         return StructuredSelection.EMPTY;
318
319                 ITextSelection textSelection= (ITextSelection)selection;
320
321                 Object codeAssist= fCurrentViewInput.getAncestor(IJavaElement.COMPILATION_UNIT);
322                 if (codeAssist == null)
323                         codeAssist= fCurrentViewInput.getAncestor(IJavaElement.CLASS_FILE);
324
325                 if (codeAssist instanceof ICodeAssist) {
326                         IJavaElement[] elements= null;
327                         try {
328                                 ISourceRange range= ((ISourceReference)fCurrentViewInput).getSourceRange();
329                                 elements= ((ICodeAssist)codeAssist).codeSelect(range.getOffset() + getOffsetInUnclippedDocument(textSelection), textSelection.getLength());
330                         } catch (JavaModelException e) {
331                                 return StructuredSelection.EMPTY;
332                         }
333                         if (elements != null && elements.length > 0) {
334                                 return new StructuredSelection(elements[0]);
335                         } else
336                                 return StructuredSelection.EMPTY;
337                 }
338
339                 return StructuredSelection.EMPTY;
340         }
341
342         /**
343          * Computes and returns the offset in the unclipped document based on the given text selection
344          * from the clipped document.
345          *
346          * @param textSelection the text selection
347          * @return the offset in the unclipped document or <code>-1</code> if the offset cannot be
348          *         computed
349          */
350         private int getOffsetInUnclippedDocument(ITextSelection textSelection) {
351                 IDocument unclippedDocument= null;
352                 try {
353                         unclippedDocument= new Document(((ISourceReference)fCurrentViewInput).getSource());
354                 } catch (JavaModelException e) {
355                         return -1;
356                 }
357                 IDocument clippedDoc= (IDocument)fViewer.getInput();
358                 try {
359                         IRegion unclippedLineInfo= unclippedDocument.getLineInformation(fCommentLineCount + textSelection.getStartLine());
360                         IRegion clippedLineInfo= clippedDoc.getLineInformation(textSelection.getStartLine());
361                         int removedIndentation= unclippedLineInfo.getLength() - clippedLineInfo.getLength();
362                         int relativeLineOffset= textSelection.getOffset() - clippedLineInfo.getOffset();
363                         return unclippedLineInfo.getOffset() + removedIndentation + relativeLineOffset ;
364                 } catch (BadLocationException ex) {
365                         return -1;
366                 }
367         }
368
369         /*
370          * @see AbstractInfoView#internalDispose()
371          */
372         @Override
373         protected void internalDispose() {
374                 fViewer= null;
375                 fViewerConfiguration= null;
376                 JFaceResources.getFontRegistry().removeListener(fFontPropertyChangeListener);
377                 JavaPlugin.getDefault().getCombinedPreferenceStore().removePropertyChangeListener(fPropertyChangeListener);
378         }
379
380         /*
381          * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
382          */
383         @Override
384         public void setFocus() {
385                 fViewer.getTextWidget().setFocus();
386         }
387
388         /*
389          * @see AbstractInfoView#computeInput(Object)
390          */
391         @Override
392         protected Object computeInput(Object input) {
393
394                 if (fViewer == null || !(input instanceof ISourceReference))
395                         return null;
396
397                 ISourceReference sourceRef= (ISourceReference)input;
398
399                 if (fLastOpenedElement != null && input instanceof IJavaElement && ((IJavaElement)input).getHandleIdentifier().equals(fLastOpenedElement.getHandleIdentifier())) {
400                         fLastOpenedElement= null;
401                         return null;
402                 } else {
403                         fLastOpenedElement= null;
404                 }
405
406                 String source;
407                 try {
408                         source= sourceRef.getSource();
409                 } catch (JavaModelException ex) {
410                         return ""; //$NON-NLS-1$
411                 }
412
413                 if (source == null)
414                         return ""; //$NON-NLS-1$
415
416                 source= removeLeadingComments(source);
417                 String delim= StubUtility.getLineDelimiterUsed((IJavaElement) input);
418
419                 String[] sourceLines= Strings.convertIntoLines(source);
420                 if (sourceLines == null || sourceLines.length == 0)
421                         return ""; //$NON-NLS-1$
422
423                 String firstLine= sourceLines[0];
424                 boolean firstCharNotWhitespace= firstLine != null && firstLine.length() > 0 && !Character.isWhitespace(firstLine.charAt(0));
425                 if (firstCharNotWhitespace)
426                         sourceLines[0]= ""; //$NON-NLS-1$
427                 IJavaProject project;
428                 if (input instanceof IJavaElement)
429                         project= ((IJavaElement) input).getJavaProject();
430                 else
431                         project= null;
432                 Strings.trimIndentation(sourceLines, project);
433
434                 if (firstCharNotWhitespace)
435                         sourceLines[0]= firstLine;
436
437                 return Strings.concatenate(sourceLines, delim);
438         }
439
440         /*
441          * @see AbstractInfoView#doSetInput(Object)
442          */
443         @Override
444         protected void doSetInput(Object input) {
445                 if (input instanceof IDocument)
446                         fViewer.setInput(input);
447                 else if (input == null)
448                         fViewer.setInput(new Document("")); //$NON-NLS-1$
449                 else {
450                         IDocument document= new Document(input.toString());
451                         JavaPlugin.getDefault().getJavaTextTools().setupJavaDocumentPartitioner(document, IJavaPartitions.JAVA_PARTITIONING);
452                         fViewer.setInput(document);
453                 }
454         }
455
456         /**
457          * Removes the leading comments from the given source.
458          *
459          * @param source the string with the source
460          * @return the source without leading comments
461          */
462         private String removeLeadingComments(String source) {
463                 JavaCodeReader reader= new JavaCodeReader();
464                 IDocument document= new Document(source);
465                 int i;
466                 i= reader.generated_2147504054850208463(document);
467
468                 try {
469                         fCommentLineCount= document.getLineOfOffset(i);
470                 } catch (BadLocationException e) {
471                         fCommentLineCount= 0;
472                 }
473
474                 if (i < 0)
475                         return source;
476
477                 return source.substring(i);
478         }
479
480         /**
481          * Sets the font for this viewer sustaining selection and scroll position.
482          */
483         private void setViewerFont() {
484                 Font font= JFaceResources.getFont(SYMBOLIC_FONT_NAME);
485
486                 if (fViewer.getDocument() != null) {
487
488                         Point selection= fViewer.getSelectedRange();
489                         int topIndex= fViewer.getTopIndex();
490
491                         StyledText styledText= fViewer.getTextWidget();
492                         Control parent= fViewer.getControl();
493
494                         parent.setRedraw(false);
495
496                         styledText.setFont(font);
497
498                         fViewer.setSelectedRange(selection.x , selection.y);
499                         fViewer.setTopIndex(topIndex);
500
501                         if (parent instanceof Composite) {
502                                 Composite composite= (Composite) parent;
503                                 composite.layout(true);
504                         }
505
506                         parent.setRedraw(true);
507
508
509                 } else {
510                         StyledText styledText= fViewer.getTextWidget();
511                         styledText.setFont(font);
512                 }
513         }
514
515         /*
516          * @see org.eclipse.jdt.internal.ui.infoviews.AbstractInfoView#getHelpContextId()
517          * @since 3.1
518          */
519         @Override
520         protected String getHelpContextId() {
521                 return IJavaHelpContextIds.SOURCE_VIEW;
522         }
523 }