KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > text > correction > PropertiesFileCorrectionAssistant


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.text.correction;
12
13 import java.util.Iterator JavaDoc;
14
15 import org.eclipse.core.runtime.CoreException;
16 import org.eclipse.core.runtime.IPath;
17
18 import org.eclipse.core.filebuffers.FileBuffers;
19 import org.eclipse.core.filebuffers.ITextFileBufferManager;
20
21 import org.eclipse.swt.graphics.Color;
22 import org.eclipse.swt.graphics.Point;
23 import org.eclipse.swt.graphics.RGB;
24 import org.eclipse.swt.widgets.Shell;
25
26 import org.eclipse.jface.preference.IPreferenceStore;
27 import org.eclipse.jface.preference.PreferenceConverter;
28 import org.eclipse.jface.util.Assert;
29
30 import org.eclipse.jface.text.BadLocationException;
31 import org.eclipse.jface.text.DefaultInformationControl;
32 import org.eclipse.jface.text.IInformationControl;
33 import org.eclipse.jface.text.IInformationControlCreator;
34 import org.eclipse.jface.text.IRegion;
35 import org.eclipse.jface.text.ITextViewer;
36 import org.eclipse.jface.text.Position;
37 import org.eclipse.jface.text.quickassist.QuickAssistAssistant;
38 import org.eclipse.jface.text.source.Annotation;
39 import org.eclipse.jface.text.source.IAnnotationModel;
40 import org.eclipse.jface.text.source.ISourceViewer;
41
42 import org.eclipse.ui.IEditorInput;
43 import org.eclipse.ui.IEditorPart;
44 import org.eclipse.ui.IStorageEditorInput;
45 import org.eclipse.ui.texteditor.ITextEditor;
46
47 import org.eclipse.jdt.ui.PreferenceConstants;
48 import org.eclipse.jdt.ui.text.IColorManager;
49 import org.eclipse.jdt.ui.text.JavaTextTools;
50
51 import org.eclipse.jdt.internal.ui.JavaPlugin;
52 import org.eclipse.jdt.internal.ui.text.HTMLTextPresenter;
53
54
55 /**
56  * PropertiesFileCorrectionAssistant.
57  *
58  * @since 3.1
59  */

60 public class PropertiesFileCorrectionAssistant extends QuickAssistAssistant {
61
62     private ITextViewer fViewer;
63     private ITextEditor fEditor;
64     private Position fPosition;
65
66
67     /**
68      * Constructor for PropertiesFileCorrectionAssistant.
69      */

70     public PropertiesFileCorrectionAssistant(ITextEditor editor) {
71         Assert.isNotNull(editor);
72         fEditor= editor;
73
74         setQuickAssistProcessor(new PropertiesFileCorrectionProcessor(this));
75
76         setInformationControlCreator(getInformationControlCreator());
77
78         JavaTextTools textTools= JavaPlugin.getDefault().getJavaTextTools();
79         IColorManager manager= textTools.getColorManager();
80
81         IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore();
82
83         Color c= getColor(store, PreferenceConstants.CODEASSIST_PROPOSALS_FOREGROUND, manager);
84         setProposalSelectorForeground(c);
85
86         c= getColor(store, PreferenceConstants.CODEASSIST_PROPOSALS_BACKGROUND, manager);
87         setProposalSelectorBackground(c);
88     }
89
90     public IEditorPart getEditor() {
91         return fEditor;
92     }
93
94
95     private IInformationControlCreator getInformationControlCreator() {
96         return new IInformationControlCreator() {
97             public IInformationControl createInformationControl(Shell parent) {
98                 return new DefaultInformationControl(parent, new HTMLTextPresenter());
99             }
100         };
101     }
102
103     private static Color getColor(IPreferenceStore store, String JavaDoc key, IColorManager manager) {
104         RGB rgb= PreferenceConverter.getColor(store, key);
105         return manager.getColor(rgb);
106     }
107
108     /*
109      * @see org.eclipse.jface.text.contentassist.IContentAssistant#install(org.eclipse.jface.text.ITextViewer)
110      */

111     public void install(ISourceViewer sourceViewer) {
112         super.install(sourceViewer);
113         fViewer= sourceViewer;
114     }
115
116
117
118     /*
119      * @see org.eclipse.jface.text.contentassist.ContentAssistant#uninstall()
120      */

121     public void uninstall() {
122         fViewer= null;
123     }
124
125     /**
126      * Show completions at caret position. If current
127      * position does not contain quick fixes look for
128      * next quick fix on same line by moving from left
129      * to right and restarting at end of line if the
130      * beginning of the line is reached.
131      *
132      * @see org.eclipse.jface.text.contentassist.IContentAssistant#showPossibleCompletions()
133      */

134     public String JavaDoc showPossibleCompletions() {
135         if (fViewer == null || fViewer.getDocument() == null)
136             // Let superclass deal with this
137
return super.showPossibleQuickAssists();
138
139         Point selectedRange= fViewer.getSelectedRange();
140         fPosition= null;
141
142         if (selectedRange.y == 0) {
143             int invocationOffset= computeOffsetWithCorrection(selectedRange.x);
144             if (invocationOffset != -1) {
145                 storePosition();
146                 fViewer.setSelectedRange(invocationOffset, 0);
147                 fViewer.revealRange(invocationOffset, 0);
148             }
149         }
150         return super.showPossibleQuickAssists();
151     }
152
153     /**
154      * Find offset which contains corrections.
155      * Search on same line by moving from left
156      * to right and restarting at end of line if the
157      * beginning of the line is reached.
158      *
159      * @return an offset where corrections are available or -1 if none
160      */

161     private int computeOffsetWithCorrection(int initalOffset) {
162         IRegion lineInfo= null;
163         try {
164             lineInfo= fViewer.getDocument().getLineInformationOfOffset(initalOffset);
165         } catch (BadLocationException ex) {
166             return -1;
167         }
168         int startOffset= lineInfo.getOffset();
169         int endOffset= startOffset + lineInfo.getLength();
170
171         int result= computeOffsetWithCorrection(startOffset, endOffset, initalOffset);
172         if (result > 0 && result != initalOffset)
173             return result;
174         else
175             return -1;
176     }
177
178     /**
179      * @return the best matching offset with corrections or -1 if nothing is found
180      */

181     private int computeOffsetWithCorrection(int startOffset, int endOffset, int initialOffset) {
182         IAnnotationModel model= null;
183         IEditorInput input= fEditor.getEditorInput();
184         if (!(input instanceof IStorageEditorInput))
185             return -1;
186
187         ITextFileBufferManager manager= FileBuffers.getTextFileBufferManager();
188         IPath path= null;
189         try {
190             path= ((IStorageEditorInput)input).getStorage().getFullPath();
191             if (path == null)
192                 return -1;
193             manager.connect(path, null);
194         } catch (CoreException e) {
195             JavaPlugin.log(e.getStatus());
196             return -1;
197         }
198
199         try {
200             model= manager.getTextFileBuffer(path).getAnnotationModel();
201
202             int invocationOffset= -1;
203             int offsetOfFirstProblem= Integer.MAX_VALUE;
204
205             Iterator JavaDoc iter= model.getAnnotationIterator();
206             while (iter.hasNext()) {
207                 Annotation annot= (Annotation) iter.next();
208                 if (JavaCorrectionProcessor.isQuickFixableType(annot)) {
209                     Position pos= model.getPosition(annot);
210                     if (isIncluded(pos, startOffset, endOffset)) {
211                         if (PropertiesFileCorrectionProcessor.hasCorrections(annot)) {
212                             offsetOfFirstProblem= Math.min(offsetOfFirstProblem, pos.getOffset());
213                             invocationOffset= computeBestOffset(invocationOffset, pos, initialOffset);
214                             if (initialOffset == invocationOffset)
215                                 return initialOffset;
216                         }
217                     }
218                 }
219             }
220             if (initialOffset < offsetOfFirstProblem && offsetOfFirstProblem != Integer.MAX_VALUE)
221                 return offsetOfFirstProblem;
222             else
223                 return invocationOffset;
224         } finally {
225             try {
226                 manager.disconnect(path, null);
227             } catch (CoreException e) {
228                 JavaPlugin.log(e.getStatus());
229             }
230         }
231     }
232
233     private boolean isIncluded(Position pos, int lineStart, int lineEnd) {
234         return (pos != null) && (pos.getOffset() >= lineStart && (pos.getOffset() + pos.getLength() <= lineEnd));
235     }
236
237     /**
238      * Computes and returns the invocation offset given a new
239      * position, the initial offset and the best invocation offset
240      * found so far.
241      * <p>
242      * The closest offset to the left of the initial offset is the
243      * best. If there is no offset on the left, the closest on the
244      * right is the best.</p>
245      */

246     private int computeBestOffset(int invocationOffset, Position pos, int initalOffset) {
247         int newOffset= pos.offset;
248         if (newOffset <= initalOffset && initalOffset <= newOffset + pos.length)
249             return initalOffset;
250
251         if (invocationOffset < 0)
252             return newOffset;
253
254         if (newOffset <= initalOffset && invocationOffset >= initalOffset)
255             return newOffset;
256
257         if (newOffset <= initalOffset && invocationOffset < initalOffset)
258             return Math.max(invocationOffset, newOffset);
259
260         if (invocationOffset <= initalOffset)
261             return invocationOffset;
262
263         return Math.max(invocationOffset, newOffset);
264     }
265
266     /*
267      * @see org.eclipse.jface.text.contentassist.ContentAssistant#possibleCompletionsClosed()
268      */

269     protected void possibleCompletionsClosed() {
270         super.possibleCompletionsClosed();
271         restorePosition();
272     }
273
274     private void storePosition() {
275         int initalOffset= fViewer.getSelectedRange().x;
276         int length= fViewer.getSelectedRange().y;
277         fPosition= new Position(initalOffset, length);
278     }
279
280     private void restorePosition() {
281         if (fPosition != null && !fPosition.isDeleted() && fViewer.getDocument() != null) {
282             fViewer.setSelectedRange(fPosition.offset, fPosition.length);
283             fViewer.revealRange(fPosition.offset, fPosition.length);
284         }
285         fPosition= null;
286     }
287
288     /**
289      * Returns true if the last invoked completion was called with an updated offset.
290      */

291     public boolean isUpdatedOffset() {
292         return fPosition != null;
293     }
294     
295 }
296
Popular Tags