Source Code Cross Referenced for ContextInformationPopup.java in  » IDE-Eclipse » jface » org » eclipse » jface » text » contentassist » 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 » jface » org.eclipse.jface.text.contentassist 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*******************************************************************************
002:         * Copyright (c) 2000, 2007 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:         *     IBM Corporation - initial API and implementation
010:         *******************************************************************************/package org.eclipse.jface.text.contentassist;
011:
012:        import java.util.Iterator;
013:        import java.util.Stack;
014:
015:        import org.eclipse.swt.SWT;
016:        import org.eclipse.swt.custom.BusyIndicator;
017:        import org.eclipse.swt.custom.StyledText;
018:        import org.eclipse.swt.events.KeyEvent;
019:        import org.eclipse.swt.events.SelectionAdapter;
020:        import org.eclipse.swt.events.SelectionEvent;
021:        import org.eclipse.swt.events.SelectionListener;
022:        import org.eclipse.swt.events.VerifyEvent;
023:        import org.eclipse.swt.graphics.Color;
024:        import org.eclipse.swt.graphics.Point;
025:        import org.eclipse.swt.graphics.Rectangle;
026:        import org.eclipse.swt.layout.GridData;
027:        import org.eclipse.swt.layout.GridLayout;
028:        import org.eclipse.swt.widgets.Control;
029:        import org.eclipse.swt.widgets.Display;
030:        import org.eclipse.swt.widgets.Shell;
031:        import org.eclipse.swt.widgets.Table;
032:        import org.eclipse.swt.widgets.TableItem;
033:
034:        import org.eclipse.jface.contentassist.IContentAssistSubjectControl;
035:
036:        import org.eclipse.jface.text.ITextViewer;
037:        import org.eclipse.jface.text.TextPresentation;
038:
039:        /**
040:         * This class is used to present context information to the user.
041:         * If multiple contexts are valid at the current cursor location,
042:         * a list is presented from which the user may choose one context.
043:         * Once the user makes their choice, or if there was only a single
044:         * possible context, the context information is shown in a tool tip like popup. <p>
045:         * If the tool tip is visible and the user wants to see context information of
046:         * a context embedded into the one for which context information is displayed,
047:         * context information for the embedded context is shown. As soon as the
048:         * cursor leaves the embedded context area, the context information for
049:         * the embedding context is shown again.
050:         *
051:         * @see IContextInformation
052:         * @see IContextInformationValidator
053:         */
054:        class ContextInformationPopup implements  IContentAssistListener {
055:
056:            /**
057:             * Represents the state necessary for embedding contexts.
058:             *
059:             * @since 2.0
060:             */
061:            static class ContextFrame {
062:
063:                final int fBeginOffset;
064:                final int fOffset;
065:                final int fVisibleOffset;
066:                final IContextInformation fInformation;
067:                final IContextInformationValidator fValidator;
068:                final IContextInformationPresenter fPresenter;
069:
070:                /*
071:                 * @since 3.1
072:                 */
073:                public ContextFrame(IContextInformation information,
074:                        int beginOffset, int offset, int visibleOffset,
075:                        IContextInformationValidator validator,
076:                        IContextInformationPresenter presenter) {
077:                    fInformation = information;
078:                    fBeginOffset = beginOffset;
079:                    fOffset = offset;
080:                    fVisibleOffset = visibleOffset;
081:                    fValidator = validator;
082:                    fPresenter = presenter;
083:                }
084:
085:                /*
086:                 * @see java.lang.Object#equals(java.lang.Object)
087:                 * @since 3.0
088:                 */
089:                public boolean equals(Object obj) {
090:                    if (obj instanceof  ContextFrame) {
091:                        ContextFrame frame = (ContextFrame) obj;
092:                        return fInformation.equals(frame.fInformation)
093:                                && fBeginOffset == frame.fBeginOffset;
094:                    }
095:                    return super .equals(obj);
096:                }
097:
098:                /*
099:                 * @see java.lang.Object#hashCode()
100:                 * @since 3.1
101:                 */
102:                public int hashCode() {
103:                    return (fInformation.hashCode() << 16) | fBeginOffset;
104:                }
105:            }
106:
107:            private ITextViewer fViewer;
108:            private ContentAssistant fContentAssistant;
109:
110:            private PopupCloser fPopupCloser = new PopupCloser();
111:            private Shell fContextSelectorShell;
112:            private Table fContextSelectorTable;
113:            private IContextInformation[] fContextSelectorInput;
114:            private String fLineDelimiter = null;
115:
116:            private Shell fContextInfoPopup;
117:            private StyledText fContextInfoText;
118:            private TextPresentation fTextPresentation;
119:
120:            private Stack fContextFrameStack = new Stack();
121:            /**
122:             * The content assist subject control.
123:             *
124:             * @since 3.0
125:             */
126:            private IContentAssistSubjectControl fContentAssistSubjectControl;
127:            /**
128:             * The content assist subject control adapter.
129:             *
130:             * @since 3.0
131:             */
132:            private ContentAssistSubjectControlAdapter fContentAssistSubjectControlAdapter;
133:
134:            /**
135:             * Selection listener on the text widget which is active
136:             * while a context information pop up is shown.
137:             *
138:             * @since 3.0
139:             */
140:            private SelectionListener fTextWidgetSelectionListener;
141:
142:            /**
143:             * The last removed context frame is remembered in order to not re-query the
144:             * user about which context should be used.
145:             *
146:             * @since 3.0
147:             */
148:            private ContextFrame fLastContext = null;
149:
150:            /**
151:             * Creates a new context information popup.
152:             *
153:             * @param contentAssistant the content assist for computing the context information
154:             * @param viewer the viewer on top of which the context information is shown
155:             */
156:            public ContextInformationPopup(ContentAssistant contentAssistant,
157:                    ITextViewer viewer) {
158:                fContentAssistant = contentAssistant;
159:                fViewer = viewer;
160:                fContentAssistSubjectControlAdapter = new ContentAssistSubjectControlAdapter(
161:                        fViewer);
162:            }
163:
164:            /**
165:             * Creates a new context information popup.
166:             *
167:             * @param contentAssistant the content assist for computing the context information
168:             * @param contentAssistSubjectControl the content assist subject control on top of which the context information is shown
169:             * @since 3.0
170:             */
171:            public ContextInformationPopup(ContentAssistant contentAssistant,
172:                    IContentAssistSubjectControl contentAssistSubjectControl) {
173:                fContentAssistant = contentAssistant;
174:                fContentAssistSubjectControl = contentAssistSubjectControl;
175:                fContentAssistSubjectControlAdapter = new ContentAssistSubjectControlAdapter(
176:                        fContentAssistSubjectControl);
177:            }
178:
179:            /**
180:             * Shows all possible contexts for the given cursor position of the viewer.
181:             *
182:             * @param autoActivated <code>true</code>  if auto activated
183:             * @return  a potential error message or <code>null</code> in case of no error
184:             */
185:            public String showContextProposals(final boolean autoActivated) {
186:                final Control control = fContentAssistSubjectControlAdapter
187:                        .getControl();
188:                BusyIndicator.showWhile(control.getDisplay(), new Runnable() {
189:                    public void run() {
190:
191:                        int offset = fContentAssistSubjectControlAdapter
192:                                .getSelectedRange().x;
193:
194:                        IContextInformation[] contexts = computeContextInformation(offset);
195:                        int count = (contexts == null ? 0 : contexts.length);
196:                        if (count == 1) {
197:
198:                            ContextFrame frame = createContextFrame(
199:                                    contexts[0], offset);
200:                            if (isDuplicate(frame))
201:                                validateContextInformation();
202:                            else
203:                                // Show context information directly
204:                                internalShowContextInfo(frame);
205:
206:                        } else if (count > 0) {
207:
208:                            // if any of the proposed context matches any of the contexts on the stack,
209:                            // assume that one (so, if context info is invoked repeatedly, the current
210:                            // info is kept)
211:                            for (int i = 0; i < contexts.length; i++) {
212:                                IContextInformation info = contexts[i];
213:                                ContextFrame frame = createContextFrame(info,
214:                                        offset);
215:
216:                                // check top of stack and stored context
217:                                if (isDuplicate(frame)) {
218:                                    validateContextInformation();
219:                                    return;
220:                                }
221:
222:                                if (isLastFrame(frame)) {
223:                                    internalShowContextInfo(frame);
224:                                    return;
225:                                }
226:
227:                                // also check all other contexts
228:                                for (Iterator it = fContextFrameStack
229:                                        .iterator(); it.hasNext();) {
230:                                    ContextFrame stackFrame = (ContextFrame) it
231:                                            .next();
232:                                    if (stackFrame.equals(frame)) {
233:                                        validateContextInformation();
234:                                        return;
235:                                    }
236:                                }
237:                            }
238:
239:                            // otherwise:
240:                            // Precise context must be selected
241:
242:                            if (fLineDelimiter == null)
243:                                fLineDelimiter = fContentAssistSubjectControlAdapter
244:                                        .getLineDelimiter();
245:
246:                            createContextSelector();
247:                            setContexts(contexts);
248:                            displayContextSelector();
249:                        }
250:                    }
251:                });
252:
253:                return getErrorMessage();
254:            }
255:
256:            /**
257:             * Displays the given context information for the given offset.
258:             *
259:             * @param info the context information
260:             * @param offset the offset
261:             * @since 2.0
262:             */
263:            public void showContextInformation(final IContextInformation info,
264:                    final int offset) {
265:                Control control = fContentAssistSubjectControlAdapter
266:                        .getControl();
267:                BusyIndicator.showWhile(control.getDisplay(), new Runnable() {
268:                    public void run() {
269:                        if (info == null)
270:                            validateContextInformation();
271:                        else {
272:                            ContextFrame frame = createContextFrame(info,
273:                                    offset);
274:                            if (isDuplicate(frame))
275:                                validateContextInformation();
276:                            else
277:                                internalShowContextInfo(frame);
278:                            hideContextSelector();
279:                        }
280:                    }
281:                });
282:            }
283:
284:            /**
285:             * Displays the given context information for the given offset.
286:             *
287:             * @param frame the context frame to display, or <code>null</code>
288:             * @since 3.0
289:             */
290:            private void internalShowContextInfo(ContextFrame frame) {
291:                if (frame != null) {
292:                    fContextFrameStack.push(frame);
293:                    if (fContextFrameStack.size() == 1)
294:                        fLastContext = null;
295:                    internalShowContextFrame(frame,
296:                            fContextFrameStack.size() == 1);
297:                    validateContextInformation();
298:                }
299:            }
300:
301:            /**
302:             * Creates a context frame for the given offset.
303:             *
304:             * @param information the context information
305:             * @param offset the offset
306:             * @return the created context frame
307:             * @since 3.0
308:             */
309:            private ContextFrame createContextFrame(
310:                    IContextInformation information, int offset) {
311:                IContextInformationValidator validator = fContentAssistSubjectControlAdapter
312:                        .getContextInformationValidator(fContentAssistant,
313:                                offset);
314:
315:                if (validator != null) {
316:                    int beginOffset = (information instanceof  IContextInformationExtension) ? ((IContextInformationExtension) information)
317:                            .getContextInformationPosition()
318:                            : offset;
319:                    if (beginOffset == -1)
320:                        beginOffset = offset;
321:                    int visibleOffset = fContentAssistSubjectControlAdapter
322:                            .getWidgetSelectionRange().x
323:                            - (offset - beginOffset);
324:                    IContextInformationPresenter presenter = fContentAssistSubjectControlAdapter
325:                            .getContextInformationPresenter(fContentAssistant,
326:                                    offset);
327:                    return new ContextFrame(information, beginOffset, offset,
328:                            visibleOffset, validator, presenter);
329:                }
330:
331:                return null;
332:            }
333:
334:            /**
335:             * Compares <code>frame</code> with the top of the stack, returns <code>true</code>
336:             * if the frames are the same.
337:             *
338:             * @param frame the frame to check
339:             * @return <code>true</code> if <code>frame</code> matches the top of the stack
340:             * @since 3.0
341:             */
342:            private boolean isDuplicate(ContextFrame frame) {
343:                if (frame == null)
344:                    return false;
345:                if (fContextFrameStack.isEmpty())
346:                    return false;
347:                // stack not empty
348:                ContextFrame top = (ContextFrame) fContextFrameStack.peek();
349:                return frame.equals(top);
350:            }
351:
352:            /**
353:             * Compares <code>frame</code> with most recently removed context frame, returns <code>true</code>
354:             * if the frames are the same.
355:             *
356:             * @param frame the frame to check
357:             * @return <code>true</code> if <code>frame</code> matches the most recently removed
358:             * @since 3.0
359:             */
360:            private boolean isLastFrame(ContextFrame frame) {
361:                return frame != null && frame.equals(fLastContext);
362:            }
363:
364:            /**
365:             * Shows the given context frame.
366:             *
367:             * @param frame the frame to display
368:             * @param initial <code>true</code> if this is the first frame to be displayed
369:             * @since 2.0
370:             */
371:            private void internalShowContextFrame(ContextFrame frame,
372:                    boolean initial) {
373:
374:                fContentAssistSubjectControlAdapter.installValidator(frame);
375:
376:                if (frame.fPresenter != null) {
377:                    if (fTextPresentation == null)
378:                        fTextPresentation = new TextPresentation();
379:                    fContentAssistSubjectControlAdapter
380:                            .installContextInformationPresenter(frame);
381:                    frame.fPresenter.updatePresentation(frame.fOffset,
382:                            fTextPresentation);
383:                }
384:
385:                createContextInfoPopup();
386:
387:                fContextInfoText.setText(frame.fInformation
388:                        .getInformationDisplayString());
389:                if (fTextPresentation != null)
390:                    TextPresentation.applyTextPresentation(fTextPresentation,
391:                            fContextInfoText);
392:                resize(frame.fVisibleOffset);
393:
394:                if (initial) {
395:                    if (fContentAssistant.addContentAssistListener(this ,
396:                            ContentAssistant.CONTEXT_INFO_POPUP)) {
397:                        if (fContentAssistSubjectControlAdapter.getControl() != null) {
398:                            fTextWidgetSelectionListener = new SelectionAdapter() {
399:                                /*
400:                                 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
401:                                 */
402:                                public void widgetSelected(SelectionEvent e) {
403:                                    validateContextInformation();
404:                                }
405:                            };
406:                            fContentAssistSubjectControlAdapter
407:                                    .addSelectionListener(fTextWidgetSelectionListener);
408:                        }
409:                        fContentAssistant
410:                                .addToLayout(
411:                                        this ,
412:                                        fContextInfoPopup,
413:                                        ContentAssistant.LayoutManager.LAYOUT_CONTEXT_INFO_POPUP,
414:                                        frame.fVisibleOffset);
415:                        fContextInfoPopup.setVisible(true);
416:                    }
417:                } else {
418:                    fContentAssistant
419:                            .layout(
420:                                    ContentAssistant.LayoutManager.LAYOUT_CONTEXT_INFO_POPUP,
421:                                    frame.fVisibleOffset);
422:                }
423:            }
424:
425:            /**
426:             * Computes all possible context information for the given offset.
427:             *
428:             * @param offset the offset
429:             * @return all possible context information for the given offset
430:             * @since 2.0
431:             */
432:            private IContextInformation[] computeContextInformation(int offset) {
433:                return fContentAssistSubjectControlAdapter
434:                        .computeContextInformation(fContentAssistant, offset);
435:            }
436:
437:            /**
438:             *Returns the error message generated while computing context information.
439:             *
440:             * @return the error message
441:             */
442:            private String getErrorMessage() {
443:                return fContentAssistant.getErrorMessage();
444:            }
445:
446:            /**
447:             * Creates the context information popup. This is the tool tip like overlay window.
448:             */
449:            private void createContextInfoPopup() {
450:                if (Helper.okToUse(fContextInfoPopup))
451:                    return;
452:
453:                Control control = fContentAssistSubjectControlAdapter
454:                        .getControl();
455:                Display display = control.getDisplay();
456:
457:                fContextInfoPopup = new Shell(control.getShell(), SWT.NO_TRIM
458:                        | SWT.ON_TOP);
459:                fContextInfoPopup.setBackground(display
460:                        .getSystemColor(SWT.COLOR_BLACK));
461:
462:                fContextInfoText = new StyledText(fContextInfoPopup, SWT.MULTI
463:                        | SWT.READ_ONLY | SWT.WRAP);
464:
465:                Color c = fContentAssistant
466:                        .getContextInformationPopupBackground();
467:                if (c == null)
468:                    c = display.getSystemColor(SWT.COLOR_INFO_BACKGROUND);
469:                fContextInfoText.setBackground(c);
470:
471:                c = fContentAssistant.getContextInformationPopupForeground();
472:                if (c == null)
473:                    c = display.getSystemColor(SWT.COLOR_INFO_FOREGROUND);
474:                fContextInfoText.setForeground(c);
475:            }
476:
477:            /**
478:             * Resizes the context information popup.
479:             *
480:             * @param offset the caret offset in widget coordinates
481:             * @since 2.0
482:             */
483:            private void resize(int offset) {
484:                Point size = fContextInfoText.computeSize(SWT.DEFAULT,
485:                        SWT.DEFAULT, true);
486:                final int TEXT_PAD = 0;
487:                final int BORDER_PAD = 2;
488:                final int PAD = TEXT_PAD + BORDER_PAD;
489:                size.x += PAD;
490:                Rectangle bounds = fContentAssistant.getLayoutManager()
491:                        .computeBoundsAboveBelow(fContextInfoPopup, size,
492:                                offset);
493:                if (bounds.width < size.x)
494:                    // we don't fit on the screen - try again and wrap
495:                    size = fContextInfoText.computeSize(bounds.width - PAD,
496:                            SWT.DEFAULT, true);
497:
498:                size.x += TEXT_PAD;
499:                fContextInfoText.setSize(size);
500:                fContextInfoText.setLocation(1, 1);
501:                size.x += BORDER_PAD;
502:                size.y += BORDER_PAD;
503:                fContextInfoPopup.setSize(size);
504:            }
505:
506:            /**
507:             * Hides the context information popup.
508:             */
509:            private void hideContextInfoPopup() {
510:
511:                if (Helper.okToUse(fContextInfoPopup)) {
512:
513:                    int size = fContextFrameStack.size();
514:                    if (size > 0) {
515:                        fLastContext = (ContextFrame) fContextFrameStack.pop();
516:                        --size;
517:                    }
518:
519:                    if (size > 0) {
520:                        ContextFrame current = (ContextFrame) fContextFrameStack
521:                                .peek();
522:                        internalShowContextFrame(current, false);
523:                    } else {
524:
525:                        fContentAssistant.removeContentAssistListener(this ,
526:                                ContentAssistant.CONTEXT_INFO_POPUP);
527:
528:                        if (fContentAssistSubjectControlAdapter.getControl() != null)
529:                            fContentAssistSubjectControlAdapter
530:                                    .removeSelectionListener(fTextWidgetSelectionListener);
531:                        fTextWidgetSelectionListener = null;
532:
533:                        fContextInfoPopup.setVisible(false);
534:                        fContextInfoPopup.dispose();
535:                        fContextInfoPopup = null;
536:
537:                        if (fTextPresentation != null) {
538:                            fTextPresentation.clear();
539:                            fTextPresentation = null;
540:                        }
541:                    }
542:                }
543:
544:                if (fContextInfoPopup == null)
545:                    fContentAssistant.contextInformationClosed();
546:            }
547:
548:            /**
549:             * Creates the context selector in case the user has the choice between multiple valid contexts
550:             * at a given offset.
551:             */
552:            private void createContextSelector() {
553:                if (Helper.okToUse(fContextSelectorShell))
554:                    return;
555:
556:                Control control = fContentAssistSubjectControlAdapter
557:                        .getControl();
558:                fContextSelectorShell = new Shell(control.getShell(),
559:                        SWT.ON_TOP | SWT.RESIZE);
560:                GridLayout layout = new GridLayout();
561:                layout.marginWidth = 0;
562:                layout.marginHeight = 0;
563:                fContextSelectorShell.setLayout(layout);
564:                fContextSelectorShell.setBackground(control.getDisplay()
565:                        .getSystemColor(SWT.COLOR_BLACK));
566:
567:                fContextSelectorTable = new Table(fContextSelectorShell,
568:                        SWT.H_SCROLL | SWT.V_SCROLL);
569:                fContextSelectorTable.setLocation(1, 1);
570:                GridData gd = new GridData(GridData.FILL_BOTH);
571:                gd.heightHint = fContextSelectorTable.getItemHeight() * 10;
572:                gd.widthHint = 300;
573:                fContextSelectorTable.setLayoutData(gd);
574:
575:                fContextSelectorShell.pack(true);
576:
577:                Color c = fContentAssistant.getContextSelectorBackground();
578:                if (c == null)
579:                    c = control.getDisplay().getSystemColor(
580:                            SWT.COLOR_INFO_BACKGROUND);
581:                fContextSelectorTable.setBackground(c);
582:
583:                c = fContentAssistant.getContextSelectorForeground();
584:                if (c == null)
585:                    c = control.getDisplay().getSystemColor(
586:                            SWT.COLOR_INFO_FOREGROUND);
587:                fContextSelectorTable.setForeground(c);
588:
589:                fContextSelectorTable
590:                        .addSelectionListener(new SelectionListener() {
591:                            public void widgetSelected(SelectionEvent e) {
592:                            }
593:
594:                            public void widgetDefaultSelected(SelectionEvent e) {
595:                                insertSelectedContext();
596:                                hideContextSelector();
597:                            }
598:                        });
599:
600:                fPopupCloser.install(fContentAssistant, fContextSelectorTable);
601:
602:                fContextSelectorTable.setHeaderVisible(false);
603:                fContentAssistant.addToLayout(this , fContextSelectorShell,
604:                        ContentAssistant.LayoutManager.LAYOUT_CONTEXT_SELECTOR,
605:                        fContentAssistant.getSelectionOffset());
606:            }
607:
608:            /**
609:             * Returns the minimal required height for the popup, may return 0 if the popup has not been
610:             * created yet.
611:             * 
612:             * @return the minimal height
613:             * @since 3.3
614:             */
615:            int getMinimalHeight() {
616:                int height = 0;
617:                if (Helper.okToUse(fContextSelectorTable)) {
618:                    int items = fContextSelectorTable.getItemHeight() * 10;
619:                    Rectangle trim = fContextSelectorTable.computeTrim(0, 0,
620:                            SWT.DEFAULT, items);
621:                    height = trim.height;
622:                }
623:                return height;
624:            }
625:
626:            /**
627:             * Causes the context information of the context selected in the context selector
628:             * to be displayed in the context information popup.
629:             */
630:            private void insertSelectedContext() {
631:                int i = fContextSelectorTable.getSelectionIndex();
632:
633:                if (i < 0 || i >= fContextSelectorInput.length)
634:                    return;
635:
636:                int offset = fContentAssistSubjectControlAdapter
637:                        .getSelectedRange().x;
638:                internalShowContextInfo(createContextFrame(
639:                        fContextSelectorInput[i], offset));
640:            }
641:
642:            /**
643:             * Sets the contexts in the context selector to the given set.
644:             *
645:             * @param contexts the possible contexts
646:             */
647:            private void setContexts(IContextInformation[] contexts) {
648:                if (Helper.okToUse(fContextSelectorTable)) {
649:
650:                    fContextSelectorInput = contexts;
651:
652:                    fContextSelectorTable.setRedraw(false);
653:                    fContextSelectorTable.removeAll();
654:
655:                    TableItem item;
656:                    IContextInformation t;
657:                    for (int i = 0; i < contexts.length; i++) {
658:                        t = contexts[i];
659:                        item = new TableItem(fContextSelectorTable, SWT.NULL);
660:                        if (t.getImage() != null)
661:                            item.setImage(t.getImage());
662:                        item.setText(t.getContextDisplayString());
663:                    }
664:
665:                    fContextSelectorTable.select(0);
666:                    fContextSelectorTable.setRedraw(true);
667:                }
668:            }
669:
670:            /**
671:             * Displays the context selector.
672:             */
673:            private void displayContextSelector() {
674:                if (fContentAssistant.addContentAssistListener(this ,
675:                        ContentAssistant.CONTEXT_SELECTOR))
676:                    fContextSelectorShell.setVisible(true);
677:            }
678:
679:            /**
680:             * Hides the context selector.
681:             */
682:            private void hideContextSelector() {
683:                if (Helper.okToUse(fContextSelectorShell)) {
684:                    fContentAssistant.removeContentAssistListener(this ,
685:                            ContentAssistant.CONTEXT_SELECTOR);
686:
687:                    fPopupCloser.uninstall();
688:                    fContextSelectorShell.setVisible(false);
689:                    fContextSelectorShell.dispose();
690:                    fContextSelectorShell = null;
691:                }
692:
693:                if (!Helper.okToUse(fContextInfoPopup))
694:                    fContentAssistant.contextInformationClosed();
695:            }
696:
697:            /**
698:             *Returns whether the context selector has the focus.
699:             *
700:             * @return <code>true</code> if the context selector has the focus
701:             */
702:            public boolean hasFocus() {
703:                if (Helper.okToUse(fContextSelectorShell))
704:                    return (fContextSelectorShell.isFocusControl() || fContextSelectorTable
705:                            .isFocusControl());
706:
707:                return false;
708:            }
709:
710:            /**
711:             * Hides context selector and context information popup.
712:             */
713:            public void hide() {
714:                hideContextSelector();
715:                hideContextInfoPopup();
716:            }
717:
718:            /**
719:             * Returns whether this context information popup is active. I.e., either
720:             * a context selector or context information is displayed.
721:             *
722:             * @return <code>true</code> if the context selector is active
723:             */
724:            public boolean isActive() {
725:                return (Helper.okToUse(fContextInfoPopup) || Helper
726:                        .okToUse(fContextSelectorShell));
727:            }
728:
729:            /*
730:             * @see IContentAssistListener#verifyKey(VerifyEvent)
731:             */
732:            public boolean verifyKey(VerifyEvent e) {
733:                if (Helper.okToUse(fContextSelectorShell))
734:                    return contextSelectorKeyPressed(e);
735:                if (Helper.okToUse(fContextInfoPopup))
736:                    return contextInfoPopupKeyPressed(e);
737:                return true;
738:            }
739:
740:            /**
741:             * Processes a key stroke in the context selector.
742:             *
743:             * @param e the verify event describing the key stroke
744:             * @return <code>true</code> if processing can be stopped
745:             */
746:            private boolean contextSelectorKeyPressed(VerifyEvent e) {
747:
748:                char key = e.character;
749:                if (key == 0) {
750:
751:                    int newSelection = fContextSelectorTable
752:                            .getSelectionIndex();
753:                    int visibleRows = (fContextSelectorTable.getSize().y / fContextSelectorTable
754:                            .getItemHeight()) - 1;
755:                    int itemCount = fContextSelectorTable.getItemCount();
756:                    switch (e.keyCode) {
757:                    case SWT.ARROW_UP:
758:                        newSelection -= 1;
759:                        if (newSelection < 0)
760:                            newSelection = itemCount - 1;
761:                        break;
762:
763:                    case SWT.ARROW_DOWN:
764:                        newSelection += 1;
765:                        if (newSelection > itemCount - 1)
766:                            newSelection = 0;
767:                        break;
768:
769:                    case SWT.PAGE_DOWN:
770:                        newSelection += visibleRows;
771:                        if (newSelection >= itemCount)
772:                            newSelection = itemCount - 1;
773:                        break;
774:
775:                    case SWT.PAGE_UP:
776:                        newSelection -= visibleRows;
777:                        if (newSelection < 0)
778:                            newSelection = 0;
779:                        break;
780:
781:                    case SWT.HOME:
782:                        newSelection = 0;
783:                        break;
784:
785:                    case SWT.END:
786:                        newSelection = itemCount - 1;
787:                        break;
788:
789:                    default:
790:                        if (e.keyCode != SWT.CAPS_LOCK && e.keyCode != SWT.MOD1
791:                                && e.keyCode != SWT.MOD2
792:                                && e.keyCode != SWT.MOD3
793:                                && e.keyCode != SWT.MOD4)
794:                            hideContextSelector();
795:                        return true;
796:                    }
797:
798:                    fContextSelectorTable.setSelection(newSelection);
799:                    fContextSelectorTable.showSelection();
800:                    e.doit = false;
801:                    return false;
802:
803:                } else if ('\t' == key) {
804:                    // switch focus to selector shell
805:                    e.doit = false;
806:                    fContextSelectorShell.setFocus();
807:                    return false;
808:                } else if (key == 0x1B) {
809:                    // terminate on Esc
810:                    hideContextSelector();
811:                }
812:
813:                return true;
814:            }
815:
816:            /**
817:             * Processes a key stroke while the info popup is up.
818:             *
819:             * @param e the verify event describing the key stroke
820:             * @return <code>true</code> if processing can be stopped
821:             */
822:            private boolean contextInfoPopupKeyPressed(KeyEvent e) {
823:
824:                char key = e.character;
825:                if (key == 0) {
826:
827:                    switch (e.keyCode) {
828:
829:                    case SWT.ARROW_LEFT:
830:                    case SWT.ARROW_RIGHT:
831:                        validateContextInformation();
832:                        break;
833:                    default:
834:                        if (e.keyCode != SWT.CAPS_LOCK && e.keyCode != SWT.MOD1
835:                                && e.keyCode != SWT.MOD2
836:                                && e.keyCode != SWT.MOD3
837:                                && e.keyCode != SWT.MOD4)
838:                            hideContextInfoPopup();
839:                        break;
840:                    }
841:
842:                } else if (key == 0x1B) {
843:                    // terminate on Esc
844:                    hideContextInfoPopup();
845:                } else {
846:                    validateContextInformation();
847:                }
848:                return true;
849:            }
850:
851:            /*
852:             * @see IEventConsumer#processEvent(VerifyEvent)
853:             */
854:            public void processEvent(VerifyEvent event) {
855:                if (Helper.okToUse(fContextSelectorShell))
856:                    contextSelectorProcessEvent(event);
857:                if (Helper.okToUse(fContextInfoPopup))
858:                    contextInfoPopupProcessEvent(event);
859:            }
860:
861:            /**
862:             * Processes a key stroke in the context selector.
863:             *
864:             * @param e the verify event describing the key stroke
865:             */
866:            private void contextSelectorProcessEvent(VerifyEvent e) {
867:
868:                if (e.start == e.end && e.text != null
869:                        && e.text.equals(fLineDelimiter)) {
870:                    e.doit = false;
871:                    insertSelectedContext();
872:                }
873:
874:                hideContextSelector();
875:            }
876:
877:            /**
878:             * Processes a key stroke while the info popup is up.
879:             *
880:             * @param e the verify event describing the key stroke
881:             */
882:            private void contextInfoPopupProcessEvent(VerifyEvent e) {
883:                if (e.start != e.end
884:                        && (e.text == null || e.text.length() == 0))
885:                    validateContextInformation();
886:            }
887:
888:            /**
889:             * Validates the context information for the viewer's actual cursor position.
890:             */
891:            private void validateContextInformation() {
892:                /*
893:                 * Post the code in the event queue in order to ensure that the
894:                 * action described by this verify key event has already been executed.
895:                 * Otherwise, we'd validate the context information based on the
896:                 * pre-key-stroke state.
897:                 */
898:                if (!Helper.okToUse(fContextInfoPopup))
899:                    return;
900:
901:                fContextInfoPopup.getDisplay().asyncExec(new Runnable() {
902:
903:                    private ContextFrame fFrame = (ContextFrame) fContextFrameStack
904:                            .peek();
905:
906:                    public void run() {
907:                        // only do this if no other frames have been added in between
908:                        if (!fContextFrameStack.isEmpty()
909:                                && fFrame == fContextFrameStack.peek()) {
910:                            int offset = fContentAssistSubjectControlAdapter
911:                                    .getSelectedRange().x;
912:
913:                            // iterate all contexts on the stack
914:                            while (Helper.okToUse(fContextInfoPopup)
915:                                    && !fContextFrameStack.isEmpty()) {
916:                                ContextFrame top = (ContextFrame) fContextFrameStack
917:                                        .peek();
918:                                if (top.fValidator == null
919:                                        || !top.fValidator
920:                                                .isContextInformationValid(offset)) {
921:                                    hideContextInfoPopup(); // loop variant: reduces the number of contexts on the stack
922:                                } else if (top.fPresenter != null
923:                                        && top.fPresenter.updatePresentation(
924:                                                offset, fTextPresentation)) {
925:                                    int widgetOffset = fContentAssistSubjectControlAdapter
926:                                            .getWidgetSelectionRange().x;
927:                                    TextPresentation
928:                                            .applyTextPresentation(
929:                                                    fTextPresentation,
930:                                                    fContextInfoText);
931:                                    resize(widgetOffset);
932:                                    break;
933:                                } else
934:                                    break;
935:                            }
936:                        }
937:                    }
938:                });
939:            }
940:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.