Source Code Cross Referenced for HippieCompleteAction.java in  » IDE-Eclipse » ui-workbench » org » eclipse » ui » texteditor » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Eclipse » ui workbench » org.eclipse.ui.texteditor 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*******************************************************************************
002:         * Copyright (c) 2000, 2006 IBM Corporation and others.
003:         * All rights reserved. This program and the accompanying materials
004:         * are made available under the terms of the Eclipse Public License v1.0
005:         * which accompanies this distribution, and is available at
006:         * http://www.eclipse.org/legal/epl-v10.html
007:         *
008:         * Contributors:
009:         *     Genady Beryozkin, me@genady.org - initial API and implementation
010:         *     IBM Corporation - fixes and cleaning
011:         *******************************************************************************/package org.eclipse.ui.texteditor;
012:
013:        import java.util.ArrayList;
014:        import java.util.List;
015:        import java.util.ResourceBundle;
016:
017:        import org.eclipse.jface.text.BadLocationException;
018:        import org.eclipse.jface.text.IDocument;
019:        import org.eclipse.jface.text.IRewriteTarget;
020:        import org.eclipse.jface.text.ITextSelection;
021:        import org.eclipse.jface.text.source.ISourceViewer;
022:
023:        import org.eclipse.core.runtime.Assert;
024:        import org.eclipse.core.runtime.IStatus;
025:        import org.eclipse.core.runtime.Status;
026:        import org.eclipse.ui.IEditorInput;
027:        import org.eclipse.ui.IEditorPart;
028:        import org.eclipse.ui.IEditorReference;
029:        import org.eclipse.ui.IWorkbenchWindow;
030:        import org.eclipse.ui.internal.texteditor.CompoundEditExitStrategy;
031:        import org.eclipse.ui.internal.texteditor.HippieCompletionEngine;
032:        import org.eclipse.ui.internal.texteditor.ICompoundEditListener;
033:        import org.eclipse.ui.internal.texteditor.TextEditorPlugin;
034:
035:        /**
036:         * This class implements the emacs style completion action. Completion action is
037:         * a stateful action, as the user may invoke it several times in a row in order
038:         * to scroll the possible completions.
039:         *
040:         * TODO: Sort by editor type
041:         * TODO: Provide history option
042:         *
043:         * @since 3.1
044:         * @author Genady Beryozkin, me@genady.org
045:         */
046:        final class HippieCompleteAction extends TextEditorAction {
047:
048:            /**
049:             * This class represents the state of the last completion process. Each time
050:             * the user moves to a new position and calls this action an instance of
051:             * this inner class is created and saved in
052:             * {@link HippieCompleteAction#fLastCompletion}.
053:             */
054:            private static class CompletionState {
055:
056:                /** The length of the last suggestion string */
057:                int length;
058:
059:                /** The index of next suggestion (index into the suggestion array) */
060:                int nextSuggestion;
061:
062:                /** The caret position at which we insert the suggestions */
063:                final int startOffset;
064:
065:                /**
066:                 * The list of suggestions that was computed when the completion action
067:                 * was first invoked
068:                 */
069:                final String[] suggestions;
070:
071:                /**
072:                 * Create a new completion state object
073:                 *
074:                 * @param suggestions the array of possible completions
075:                 * @param startOffset the position in the parent document at which the
076:                 *        completions will be inserted.
077:                 */
078:                CompletionState(String[] suggestions, int startOffset) {
079:                    this .suggestions = suggestions;
080:                    this .startOffset = startOffset;
081:                    length = 0;
082:                    nextSuggestion = 0;
083:                }
084:
085:                /**
086:                 * Advances the completion state to represent the next completion.
087:                 */
088:                public void advance() {
089:                    length = suggestions[nextSuggestion].length();
090:                    nextSuggestion = (nextSuggestion + 1) % suggestions.length;
091:                }
092:            }
093:
094:            /**
095:             * The document that will be manipulated (currently open in the editor)
096:             */
097:            private IDocument fDocument;
098:
099:            /**
100:             * The completion state that is used to continue the iteration over
101:             * completion suggestions
102:             */
103:            private CompletionState fLastCompletion = null;
104:
105:            /**
106:             * The completion engine
107:             */
108:            private final HippieCompletionEngine fEngine = new HippieCompletionEngine();
109:
110:            /** The compound edit exit strategy. */
111:            private final CompoundEditExitStrategy fExitStrategy = new CompoundEditExitStrategy(
112:                    ITextEditorActionDefinitionIds.HIPPIE_COMPLETION);
113:
114:            /**
115:             * Creates a new action.
116:             *
117:             * @param bundle the resource bundle
118:             * @param prefix a prefix to be prepended to the various resource keys
119:             *        (described in <code>ResourceAction</code> constructor), or
120:             *        <code>null</code> if none
121:             * @param editor the text editor
122:             */
123:            HippieCompleteAction(ResourceBundle bundle, String prefix,
124:                    ITextEditor editor) {
125:                super (bundle, prefix, editor);
126:                fExitStrategy.addCompoundListener(new ICompoundEditListener() {
127:                    public void endCompoundEdit() {
128:                        clearState();
129:                    }
130:                });
131:            }
132:
133:            /**
134:             * Invalidates the cached completions, removes all registered listeners and
135:             * sets the cached document to <code>null</code>.
136:             */
137:            private void clearState() {
138:                fLastCompletion = null;
139:
140:                ITextEditor editor = getTextEditor();
141:
142:                if (editor != null) {
143:                    IRewriteTarget target = (IRewriteTarget) editor
144:                            .getAdapter(IRewriteTarget.class);
145:                    if (target != null) {
146:                        fExitStrategy.disarm();
147:                        target.endCompoundChange();
148:                    }
149:                }
150:
151:                fDocument = null;
152:            }
153:
154:            /**
155:             * Perform the next completion.
156:             */
157:            private void completeNext() {
158:                try {
159:                    fDocument
160:                            .replace(
161:                                    fLastCompletion.startOffset,
162:                                    fLastCompletion.length,
163:                                    fLastCompletion.suggestions[fLastCompletion.nextSuggestion]);
164:                } catch (BadLocationException e) {
165:                    // we should never get here. different from other places to notify the user.
166:                    log(e);
167:                    clearState();
168:                    return;
169:                }
170:
171:                // advance the suggestion state
172:                fLastCompletion.advance();
173:
174:                // move the caret to the insertion point
175:                ISourceViewer sourceViewer = ((AbstractTextEditor) getTextEditor())
176:                        .getSourceViewer();
177:                sourceViewer.setSelectedRange(fLastCompletion.startOffset
178:                        + fLastCompletion.length, 0);
179:                sourceViewer.revealRange(fLastCompletion.startOffset,
180:                        fLastCompletion.length);
181:
182:                fExitStrategy.arm(((AbstractTextEditor) getTextEditor())
183:                        .getSourceViewer());
184:            }
185:
186:            /**
187:             * Return the list of suggestions from the current document. First the
188:             * document is searched backwards from the caret position and then forwards.
189:             *
190:             * @param prefix the completion prefix
191:             * @return all possible completions that were found in the current document
192:             * @throws BadLocationException if accessing the document fails
193:             */
194:            private ArrayList createSuggestionsFromOpenDocument(String prefix)
195:                    throws BadLocationException {
196:                int selectionOffset = getSelectionOffset();
197:
198:                ArrayList completions = new ArrayList();
199:                completions.addAll(fEngine.getCompletionsBackwards(fDocument,
200:                        prefix, selectionOffset));
201:                completions.addAll(fEngine.getCompletionsForward(fDocument,
202:                        prefix, selectionOffset - prefix.length(), true));
203:
204:                return completions;
205:            }
206:
207:            /**
208:             * Returns the document currently displayed in the editor, or
209:             * <code>null</code>
210:             *
211:             * @return the document currently displayed in the editor, or
212:             *         <code>null</code>
213:             */
214:            private IDocument getCurrentDocument() {
215:                ITextEditor editor = getTextEditor();
216:                if (editor == null)
217:                    return null;
218:                IDocumentProvider provider = editor.getDocumentProvider();
219:                if (provider == null)
220:                    return null;
221:
222:                IDocument document = provider.getDocument(editor
223:                        .getEditorInput());
224:                return document;
225:            }
226:
227:            /**
228:             * Return the part of a word before the caret. If the caret is not at a
229:             * middle/end of a word, returns null.
230:             *
231:             * @return the prefix at the current cursor position that will be used in
232:             *         the search for possible completions
233:             * @throws BadLocationException if accessing the document fails
234:             */
235:            private String getCurrentPrefix() throws BadLocationException {
236:                ITextSelection selection = (ITextSelection) getTextEditor()
237:                        .getSelectionProvider().getSelection();
238:                if (selection.getLength() > 0) {
239:                    return null;
240:                }
241:                return fEngine
242:                        .getPrefixString(fDocument, selection.getOffset());
243:            }
244:
245:            /**
246:             * Returns the current selection (or caret) offset.
247:             *
248:             * @return the current selection (or caret) offset
249:             */
250:            private int getSelectionOffset() {
251:                return ((ITextSelection) getTextEditor().getSelectionProvider()
252:                        .getSelection()).getOffset();
253:            }
254:
255:            /**
256:             * Create the array of suggestions. It scans all open text editors and
257:             * prefers suggestions from the currently open editor. It also adds the
258:             * empty suggestion at the end.
259:             *
260:             * @param prefix the prefix to search for
261:             * @return the list of all possible suggestions in the currently open
262:             *         editors
263:             * @throws BadLocationException if accessing the current document fails
264:             */
265:            private String[] getSuggestions(String prefix)
266:                    throws BadLocationException {
267:
268:                ArrayList suggestions = createSuggestionsFromOpenDocument(prefix);
269:
270:                IWorkbenchWindow window = getTextEditor().getSite()
271:                        .getWorkbenchWindow();
272:                IEditorReference editorsArray[] = window.getActivePage()
273:                        .getEditorReferences();
274:
275:                for (int i = 0; i < editorsArray.length; i++) {
276:                    IEditorPart realEditor = editorsArray[i].getEditor(false);
277:                    if (realEditor instanceof  ITextEditor
278:                            && !realEditor.equals(getTextEditor())) { // realEditor != null
279:                        ITextEditor textEditor = (ITextEditor) realEditor;
280:                        IEditorInput input = textEditor.getEditorInput();
281:                        IDocument doc = textEditor.getDocumentProvider()
282:                                .getDocument(input);
283:
284:                        suggestions.addAll(fEngine.getCompletionsForward(doc,
285:                                prefix, 0, false));
286:                    }
287:                }
288:                // add the empty suggestion
289:                suggestions.add(""); //$NON-NLS-1$
290:
291:                List uniqueSuggestions = fEngine.makeUnique(suggestions);
292:
293:                return (String[]) uniqueSuggestions.toArray(new String[0]);
294:            }
295:
296:            /**
297:             * Returns <code>true</code> if the current completion state is still
298:             * valid given the current document and selection.
299:             *
300:             * @return <code>true</code> if the cached state is valid,
301:             *         <code>false</code> otherwise
302:             */
303:            private boolean isStateValid() {
304:                return fDocument != null
305:                        && fDocument.equals(getCurrentDocument())
306:                        && fLastCompletion != null
307:                        && fLastCompletion.startOffset + fLastCompletion.length == getSelectionOffset();
308:            }
309:
310:            /**
311:             * Notifies the user that there are no suggestions.
312:             */
313:            private void notifyUser() {
314:                // TODO notify via status line?
315:                getTextEditor().getSite().getShell().getDisplay().beep();
316:            }
317:
318:            /*
319:             * @see org.eclipse.jface.action.Action#run()
320:             */
321:            public void run() {
322:                if (!validateEditorInputState())
323:                    return;
324:
325:                if (!isStateValid())
326:                    updateState();
327:
328:                if (isStateValid())
329:                    completeNext();
330:            }
331:
332:            /*
333:             * @see org.eclipse.jface.action.IAction#isEnabled()
334:             */
335:            public boolean isEnabled() {
336:                return canModifyEditor();
337:            }
338:
339:            /*
340:             * @see org.eclipse.ui.texteditor.TextEditorAction#setEditor(org.eclipse.ui.texteditor.ITextEditor)
341:             */
342:            public void setEditor(ITextEditor editor) {
343:                clearState(); // make sure to remove listers before the editor changes!
344:                super .setEditor(editor);
345:            }
346:
347:            /**
348:             * Update the completion state. The completion cache is updated with the
349:             * completions based on the currently displayed document and the current
350:             * selection. To track the validity of the cached state, listeners are
351:             * registered with the editor and document, and the current document is
352:             * cached.
353:             */
354:            private void updateState() {
355:                Assert.isNotNull(getTextEditor());
356:
357:                clearState();
358:
359:                IDocument document = getCurrentDocument();
360:                if (document != null) {
361:                    fDocument = document;
362:
363:                    String[] suggestions;
364:                    try {
365:                        String prefix = getCurrentPrefix();
366:                        if (prefix == null) {
367:                            notifyUser();
368:                            return;
369:                        }
370:                        suggestions = getSuggestions(prefix);
371:                    } catch (BadLocationException e) {
372:                        log(e);
373:                        return;
374:                    }
375:
376:                    // if it is single empty suggestion
377:                    if (suggestions.length == 1) {
378:                        notifyUser();
379:                        return;
380:                    }
381:
382:                    IRewriteTarget target = (IRewriteTarget) getTextEditor()
383:                            .getAdapter(IRewriteTarget.class);
384:                    if (target != null)
385:                        target.beginCompoundChange();
386:
387:                    fLastCompletion = new CompletionState(suggestions,
388:                            getSelectionOffset());
389:                }
390:            }
391:
392:            /**
393:             * Logs the exception.
394:             *
395:             * @param e the exception
396:             */
397:            private void log(BadLocationException e) {
398:                String msg = e.getLocalizedMessage();
399:                if (msg == null)
400:                    msg = "unable to access the document"; //$NON-NLS-1$
401:                TextEditorPlugin.getDefault().getLog().log(
402:                        new Status(IStatus.ERROR, TextEditorPlugin.PLUGIN_ID,
403:                                IStatus.OK, msg, e));
404:            }
405:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.