Mercurial > projects > dwt-addons
comparison dwtx/jface/text/contentassist/CompletionProposalPopup.d @ 140:26688fec6d23
Following dsss compile errors
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sun, 24 Aug 2008 03:23:46 +0200 |
parents | b6bad70d540a |
children | 75302ef3f92f |
comparison
equal
deleted
inserted
replaced
139:93a6ec48fd28 | 140:26688fec6d23 |
---|---|
135 private static final bool USE_VIRTUAL= !"motif".equals(DWT.getPlatform()); //$NON-NLS-1$ | 135 private static final bool USE_VIRTUAL= !"motif".equals(DWT.getPlatform()); //$NON-NLS-1$ |
136 | 136 |
137 | 137 |
138 /** | 138 /** |
139 * Completion proposal selection handler. | 139 * Completion proposal selection handler. |
140 * | 140 * |
141 * @since 3.4 | 141 * @since 3.4 |
142 */ | 142 */ |
143 final class ProposalSelectionHandler : AbstractHandler { | 143 final class ProposalSelectionHandler : AbstractHandler { |
144 | 144 |
145 /** | 145 /** |
146 * Selection operation codes. | 146 * Selection operation codes. |
147 */ | 147 */ |
148 static final int SELECT_NEXT= 1; | 148 static final int SELECT_NEXT= 1; |
149 static final int SELECT_PREVIOUS= 2; | 149 static final int SELECT_PREVIOUS= 2; |
150 | 150 |
151 | 151 |
152 private int fOperationCode; | 152 private int fOperationCode; |
153 | 153 |
154 /** | 154 /** |
155 * Creates a new selection handler. | 155 * Creates a new selection handler. |
156 * | 156 * |
157 * @param operationCode the operation code | 157 * @param operationCode the operation code |
158 * @since 3.4 | 158 * @since 3.4 |
159 */ | 159 */ |
160 public this(int operationCode) { | 160 public this(int operationCode) { |
161 Assert.isLegal(operationCode is SELECT_NEXT || operationCode is SELECT_PREVIOUS); | 161 Assert.isLegal(operationCode is SELECT_NEXT || operationCode is SELECT_PREVIOUS); |
184 selectProposal(selectionIndex, false); | 184 selectProposal(selectionIndex, false); |
185 return null; | 185 return null; |
186 } | 186 } |
187 | 187 |
188 } | 188 } |
189 | 189 |
190 | 190 |
191 /** | 191 /** |
192 * The empty proposal displayed if there is nothing else to show. | 192 * The empty proposal displayed if there is nothing else to show. |
193 * | 193 * |
194 * @since 3.2 | 194 * @since 3.2 |
195 */ | 195 */ |
196 private static final class EmptyProposal : ICompletionProposal, ICompletionProposalExtension { | 196 private static final class EmptyProposal : ICompletionProposal, ICompletionProposalExtension { |
197 | 197 |
198 String fDisplayString; | 198 String fDisplayString; |
292 } | 292 } |
293 } | 293 } |
294 | 294 |
295 private final class CommandKeyListener : KeyAdapter { | 295 private final class CommandKeyListener : KeyAdapter { |
296 private KeySequence fCommandSequence; | 296 private KeySequence fCommandSequence; |
297 | 297 |
298 private this(KeySequence keySequence) { | 298 private this(KeySequence keySequence) { |
299 fCommandSequence= keySequence; | 299 fCommandSequence= keySequence; |
300 } | 300 } |
301 | 301 |
302 public void keyPressed(KeyEvent e) { | 302 public void keyPressed(KeyEvent e) { |
303 if (!Helper.okToUse(fProposalShell)) | 303 if (!Helper.okToUse(fProposalShell)) |
304 return; | 304 return; |
305 | 305 |
306 int accelerator= SWTKeySupport.convertEventToUnmodifiedAccelerator(e); | 306 int accelerator= SWTKeySupport.convertEventToUnmodifiedAccelerator(e); |
307 KeySequence sequence= KeySequence.getInstance(SWTKeySupport.convertAcceleratorToKeyStroke(accelerator)); | 307 KeySequence sequence= KeySequence.getInstance(SWTKeySupport.convertAcceleratorToKeyStroke(accelerator)); |
308 if (sequence.equals(fCommandSequence)) | 308 if (sequence.equals(fCommandSequence)) |
309 if (fContentAssistant.isPrefixCompletionEnabled()) | 309 if (fContentAssistant.isPrefixCompletionEnabled()) |
310 incrementalComplete(); | 310 incrementalComplete(); |
311 else | 311 else |
312 showProposals(false); | 312 showProposals(false); |
313 | 313 |
314 } | 314 } |
315 } | 315 } |
316 | 316 |
317 | 317 |
318 /** The associated text viewer. */ | 318 /** The associated text viewer. */ |
319 private ITextViewer fViewer; | 319 private ITextViewer fViewer; |
320 /** The associated content assistant. */ | 320 /** The associated content assistant. */ |
321 private ContentAssistant fContentAssistant; | 321 private ContentAssistant fContentAssistant; |
322 /** The used additional info controller. */ | 322 /** The used additional info controller. */ |
380 * @since 3.1 | 380 * @since 3.1 |
381 */ | 381 */ |
382 private bool fIsFilteredSubset; | 382 private bool fIsFilteredSubset; |
383 /** | 383 /** |
384 * The filter runnable. | 384 * The filter runnable. |
385 * | 385 * |
386 * @since 3.1.1 | 386 * @since 3.1.1 |
387 */ | 387 */ |
388 private final Runnable fFilterRunnable= new class() Runnable { | 388 private final Runnable fFilterRunnable= new class() Runnable { |
389 public void run() { | 389 public void run() { |
390 if (!fIsFilterPending) | 390 if (!fIsFilterPending) |
391 return; | 391 return; |
392 | 392 |
393 fIsFilterPending= false; | 393 fIsFilterPending= false; |
394 | 394 |
395 if (!Helper.okToUse(fContentAssistSubjectControlAdapter.getControl())) | 395 if (!Helper.okToUse(fContentAssistSubjectControlAdapter.getControl())) |
396 return; | 396 return; |
397 | 397 |
415 } | 415 } |
416 }; | 416 }; |
417 /** | 417 /** |
418 * <code>true</code> if <code>fFilterRunnable</code> has been | 418 * <code>true</code> if <code>fFilterRunnable</code> has been |
419 * posted, <code>false</code> if not. | 419 * posted, <code>false</code> if not. |
420 * | 420 * |
421 * @since 3.1.1 | 421 * @since 3.1.1 |
422 */ | 422 */ |
423 private bool fIsFilterPending= false; | 423 private bool fIsFilterPending= false; |
424 /** | 424 /** |
425 * The info message at the bottom of the popup, or <code>null</code> for no popup (if | 425 * The info message at the bottom of the popup, or <code>null</code> for no popup (if |
426 * ContentAssistant does not provide one). | 426 * ContentAssistant does not provide one). |
427 * | 427 * |
428 * @since 3.2 | 428 * @since 3.2 |
429 */ | 429 */ |
430 private Label fMessageText; | 430 private Label fMessageText; |
431 /** | 431 /** |
432 * The font used for <code>fMessageText</code> or null; dispose when done. | 432 * The font used for <code>fMessageText</code> or null; dispose when done. |
433 * | 433 * |
434 * @since 3.2 | 434 * @since 3.2 |
435 */ | 435 */ |
436 private Font fMessageTextFont; | 436 private Font fMessageTextFont; |
437 /** | 437 /** |
438 * The most recent completion offset (used to determine repeated invocation) | 438 * The most recent completion offset (used to determine repeated invocation) |
439 * | 439 * |
440 * @since 3.2 | 440 * @since 3.2 |
441 */ | 441 */ |
442 private int fLastCompletionOffset; | 442 private int fLastCompletionOffset; |
443 /** | 443 /** |
444 * The (reusable) empty proposal. | 444 * The (reusable) empty proposal. |
445 * | 445 * |
446 * @since 3.2 | 446 * @since 3.2 |
447 */ | 447 */ |
448 private final EmptyProposal fEmptyProposal= new EmptyProposal(); | 448 private final EmptyProposal fEmptyProposal= new EmptyProposal(); |
449 /** | 449 /** |
450 * The text for the empty proposal, or <code>null</code> to use the default text. | 450 * The text for the empty proposal, or <code>null</code> to use the default text. |
451 * | 451 * |
452 * @since 3.2 | 452 * @since 3.2 |
453 */ | 453 */ |
454 private String fEmptyMessage= null; | 454 private String fEmptyMessage= null; |
455 /** | 455 /** |
456 * Tells whether colored labels support is enabled. | 456 * Tells whether colored labels support is enabled. |
457 * Only valid while the popup is active. | 457 * Only valid while the popup is active. |
458 * | 458 * |
459 * @since 3.4 | 459 * @since 3.4 |
460 */ | 460 */ |
461 private bool fIsColoredLabelsSupportEnabled= false; | 461 private bool fIsColoredLabelsSupportEnabled= false; |
462 | 462 |
463 | 463 |
464 /** | 464 /** |
465 * Creates a new completion proposal popup for the given elements. | 465 * Creates a new completion proposal popup for the given elements. |
466 * | 466 * |
467 * @param contentAssistant the content assistant feeding this popup | 467 * @param contentAssistant the content assistant feeding this popup |
468 * @param viewer the viewer on top of which this popup appears | 468 * @param viewer the viewer on top of which this popup appears |
519 fComputedProposals= computeProposals(fInvocationOffset); | 519 fComputedProposals= computeProposals(fInvocationOffset); |
520 | 520 |
521 int count= (fComputedProposals is null ? 0 : fComputedProposals.length); | 521 int count= (fComputedProposals is null ? 0 : fComputedProposals.length); |
522 if (count is 0 && hideWhenNoProposals(autoActivated)) | 522 if (count is 0 && hideWhenNoProposals(autoActivated)) |
523 return; | 523 return; |
524 | 524 |
525 if (count is 1 && !autoActivated && canAutoInsert(fComputedProposals[0])) { | 525 if (count is 1 && !autoActivated && canAutoInsert(fComputedProposals[0])) { |
526 insertProposal(fComputedProposals[0], cast(wchar) 0, 0, fInvocationOffset); | 526 insertProposal(fComputedProposals[0], cast(wchar) 0, 0, fInvocationOffset); |
527 hide(); | 527 hide(); |
528 } else { | 528 } else { |
529 createProposalSelector(); | 529 createProposalSelector(); |
537 handleRepeatedInvocation(); | 537 handleRepeatedInvocation(); |
538 } | 538 } |
539 | 539 |
540 return getErrorMessage(); | 540 return getErrorMessage(); |
541 } | 541 } |
542 | 542 |
543 /** | 543 /** |
544 * Hides the popup and returns <code>true</code> if the popup is configured | 544 * Hides the popup and returns <code>true</code> if the popup is configured |
545 * to never display an empty list. Returns <code>false</code> otherwise. | 545 * to never display an empty list. Returns <code>false</code> otherwise. |
546 * | 546 * |
547 * @param autoActivated whether the invocation was auto-activated | 547 * @param autoActivated whether the invocation was auto-activated |
548 * @return <code>false</code> if an empty list should be displayed, <code>true</code> otherwise | 548 * @return <code>false</code> if an empty list should be displayed, <code>true</code> otherwise |
549 * @since 3.2 | 549 * @since 3.2 |
550 */ | 550 */ |
551 private bool hideWhenNoProposals(bool autoActivated) { | 551 private bool hideWhenNoProposals(bool autoActivated) { |
562 } | 562 } |
563 | 563 |
564 /** | 564 /** |
565 * If content assist is set up to handle cycling, then the proposals are recomputed. Otherwise, | 565 * If content assist is set up to handle cycling, then the proposals are recomputed. Otherwise, |
566 * nothing happens. | 566 * nothing happens. |
567 * | 567 * |
568 * @since 3.2 | 568 * @since 3.2 |
569 */ | 569 */ |
570 private void handleRepeatedInvocation() { | 570 private void handleRepeatedInvocation() { |
571 if (fContentAssistant.isRepeatedInvocationMode()) { | 571 if (fContentAssistant.isRepeatedInvocationMode()) { |
572 fComputedProposals= computeProposals(fFilterOffset); | 572 fComputedProposals= computeProposals(fFilterOffset); |
604 return; | 604 return; |
605 | 605 |
606 Control control= fContentAssistSubjectControlAdapter.getControl(); | 606 Control control= fContentAssistSubjectControlAdapter.getControl(); |
607 fProposalShell= new Shell(control.getShell(), DWT.ON_TOP | DWT.RESIZE ); | 607 fProposalShell= new Shell(control.getShell(), DWT.ON_TOP | DWT.RESIZE ); |
608 fProposalShell.setFont(JFaceResources.getDefaultFont()); | 608 fProposalShell.setFont(JFaceResources.getDefaultFont()); |
609 if cast(USE_VIRTUAL) { | 609 if (USE_VIRTUAL) { |
610 fProposalTable= new Table(fProposalShell, DWT.H_SCROLL | DWT.V_SCROLL | DWT.VIRTUAL); | 610 fProposalTable= new Table(fProposalShell, DWT.H_SCROLL | DWT.V_SCROLL | DWT.VIRTUAL); |
611 | 611 |
612 Listener listener= new class() Listener { | 612 Listener listener= new class() Listener { |
613 public void handleEvent(Event event) { | 613 public void handleEvent(Event event) { |
614 handleSetData(event); | 614 handleSetData(event); |
616 }; | 616 }; |
617 fProposalTable.addListener(DWT.SetData, listener); | 617 fProposalTable.addListener(DWT.SetData, listener); |
618 } else { | 618 } else { |
619 fProposalTable= new Table(fProposalShell, DWT.H_SCROLL | DWT.V_SCROLL); | 619 fProposalTable= new Table(fProposalShell, DWT.H_SCROLL | DWT.V_SCROLL); |
620 } | 620 } |
621 | 621 |
622 fIsColoredLabelsSupportEnabled= fContentAssistant.isColoredLabelsSupportEnabled(); | 622 fIsColoredLabelsSupportEnabled= fContentAssistant.isColoredLabelsSupportEnabled(); |
623 if (fIsColoredLabelsSupportEnabled) | 623 if (fIsColoredLabelsSupportEnabled) |
624 TableOwnerDrawSupport.install(fProposalTable); | 624 TableOwnerDrawSupport.install(fProposalTable); |
625 | 625 |
626 fProposalTable.setLocation(0, 0); | 626 fProposalTable.setLocation(0, 0); |
630 GridLayout layout= new GridLayout(); | 630 GridLayout layout= new GridLayout(); |
631 layout.marginWidth= 0; | 631 layout.marginWidth= 0; |
632 layout.marginHeight= 0; | 632 layout.marginHeight= 0; |
633 layout.verticalSpacing= 1; | 633 layout.verticalSpacing= 1; |
634 fProposalShell.setLayout(layout); | 634 fProposalShell.setLayout(layout); |
635 | 635 |
636 if (fContentAssistant.isStatusLineVisible()) { | 636 if (fContentAssistant.isStatusLineVisible()) { |
637 createMessageText(); | 637 createMessageText(); |
638 } | 638 } |
639 | 639 |
640 GridData data= new GridData(GridData.FILL_BOTH); | 640 GridData data= new GridData(GridData.FILL_BOTH); |
667 } | 667 } |
668 | 668 |
669 fSize= fProposalShell.getSize(); | 669 fSize= fProposalShell.getSize(); |
670 } | 670 } |
671 }); | 671 }); |
672 | 672 |
673 fProposalShell.setBackground(control.getDisplay().getSystemColor(DWT.COLOR_GRAY)); | 673 fProposalShell.setBackground(control.getDisplay().getSystemColor(DWT.COLOR_GRAY)); |
674 | 674 |
675 Color c= getBackgroundColor(control); | 675 Color c= getBackgroundColor(control); |
676 fProposalTable.setBackground(c); | 676 fProposalTable.setBackground(c); |
677 | 677 |
694 unregister(); // but don't dispose the shell, since we're being called from its disposal event! | 694 unregister(); // but don't dispose the shell, since we're being called from its disposal event! |
695 } | 695 } |
696 }); | 696 }); |
697 | 697 |
698 fProposalTable.setHeaderVisible(false); | 698 fProposalTable.setHeaderVisible(false); |
699 | 699 |
700 addCommandSupport(fProposalTable); | 700 addCommandSupport(fProposalTable); |
701 } | 701 } |
702 | 702 |
703 /** | 703 /** |
704 * Returns the minimal required height for the proposal, may return 0 if the popup has not been | 704 * Returns the minimal required height for the proposal, may return 0 if the popup has not been |
705 * created yet. | 705 * created yet. |
706 * | 706 * |
707 * @return the minimal height | 707 * @return the minimal height |
708 * @since 3.3 | 708 * @since 3.3 |
709 */ | 709 */ |
710 int getMinimalHeight() { | 710 int getMinimalHeight() { |
711 int height= 0; | 711 int height= 0; |
719 return height; | 719 return height; |
720 } | 720 } |
721 | 721 |
722 /** | 722 /** |
723 * Adds command support to the given control. | 723 * Adds command support to the given control. |
724 * | 724 * |
725 * @param control the control to watch for focus | 725 * @param control the control to watch for focus |
726 * @since 3.2 | 726 * @since 3.2 |
727 */ | 727 */ |
728 private void addCommandSupport(final Control control) { | 728 private void addCommandSupport(final Control control) { |
729 final KeySequence commandSequence= fContentAssistant.getRepeatedInvocationKeySequence(); | 729 final KeySequence commandSequence= fContentAssistant.getRepeatedInvocationKeySequence(); |
775 }); | 775 }); |
776 } | 776 } |
777 | 777 |
778 /** | 778 /** |
779 * Returns the background color to use. | 779 * Returns the background color to use. |
780 * | 780 * |
781 * @param control the control to get the display from | 781 * @param control the control to get the display from |
782 * @return the background color | 782 * @return the background color |
783 * @since 3.2 | 783 * @since 3.2 |
784 */ | 784 */ |
785 private Color getBackgroundColor(Control control) { | 785 private Color getBackgroundColor(Control control) { |
789 return c; | 789 return c; |
790 } | 790 } |
791 | 791 |
792 /** | 792 /** |
793 * Returns the foreground color to use. | 793 * Returns the foreground color to use. |
794 * | 794 * |
795 * @param control the control to get the display from | 795 * @param control the control to get the display from |
796 * @return the foreground color | 796 * @return the foreground color |
797 * @since 3.2 | 797 * @since 3.2 |
798 */ | 798 */ |
799 private Color getForegroundColor(Control control) { | 799 private Color getForegroundColor(Control control) { |
800 Color c= fContentAssistant.getProposalSelectorForeground(); | 800 Color c= fContentAssistant.getProposalSelectorForeground(); |
801 if (c is null) | 801 if (c is null) |
802 c= JFaceResources.getColorRegistry().get(JFacePreferences.CONTENT_ASSIST_FOREGROUND_COLOR); | 802 c= JFaceResources.getColorRegistry().get(JFacePreferences.CONTENT_ASSIST_FOREGROUND_COLOR); |
803 return c; | 803 return c; |
804 } | 804 } |
805 | 805 |
806 /** | 806 /** |
807 * Creates the caption line under the proposal table. | 807 * Creates the caption line under the proposal table. |
808 * | 808 * |
809 * @since 3.2 | 809 * @since 3.2 |
810 */ | 810 */ |
811 private void createMessageText() { | 811 private void createMessageText() { |
812 if (fMessageText is null) { | 812 if (fMessageText is null) { |
813 fMessageText= new Label(fProposalShell, DWT.RIGHT); | 813 fMessageText= new Label(fProposalShell, DWT.RIGHT); |
852 if (0 <= index && index < fFilteredProposals.length) { | 852 if (0 <= index && index < fFilteredProposals.length) { |
853 ICompletionProposal current= fFilteredProposals[index]; | 853 ICompletionProposal current= fFilteredProposals[index]; |
854 | 854 |
855 String displayString; | 855 String displayString; |
856 StyleRange[] styleRanges= null; | 856 StyleRange[] styleRanges= null; |
857 if (fIsColoredLabelsSupportEnabled && current instanceof ICompletionProposalExtension6) { | 857 if (fIsColoredLabelsSupportEnabled && cast(ICompletionProposalExtension6)current ) { |
858 StyledString styledString= (cast(ICompletionProposalExtension6)current).getStyledDisplayString(); | 858 StyledString styledString= (cast(ICompletionProposalExtension6)current).getStyledDisplayString(); |
859 displayString= styledString.getString(); | 859 displayString= styledString.getString(); |
860 styleRanges= styledString.getStyleRanges(); | 860 styleRanges= styledString.getStyleRanges(); |
861 } else | 861 } else |
862 displayString= current.getDisplayString(); | 862 displayString= current.getDisplayString(); |
863 | 863 |
864 item.setText(displayString); | 864 item.setText(displayString); |
865 if (fIsColoredLabelsSupportEnabled) | 865 if (fIsColoredLabelsSupportEnabled) |
866 TableOwnerDrawSupport.storeStyleRanges(item, 0, styleRanges); | 866 TableOwnerDrawSupport.storeStyleRanges(item, 0, styleRanges); |
867 | 867 |
868 item.setImage(current.getImage()); | 868 item.setImage(current.getImage()); |
869 item.setData(current); | 869 item.setData(current); |
870 } else { | 870 } else { |
871 // this should not happen, but does on win32 | 871 // this should not happen, but does on win32 |
872 } | 872 } |
882 /* Make sure that there is no filter runnable pending. | 882 /* Make sure that there is no filter runnable pending. |
883 * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=31427 | 883 * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=31427 |
884 */ | 884 */ |
885 if (fIsFilterPending) | 885 if (fIsFilterPending) |
886 fFilterRunnable.run(); | 886 fFilterRunnable.run(); |
887 | 887 |
888 // filter runnable may have hidden the proposals | 888 // filter runnable may have hidden the proposals |
889 if (!Helper.okToUse(fProposalTable)) | 889 if (!Helper.okToUse(fProposalTable)) |
890 return null; | 890 return null; |
891 | 891 |
892 int i= fProposalTable.getSelectionIndex(); | 892 int i= fProposalTable.getSelectionIndex(); |
893 if (fFilteredProposals is null || i < 0 || i >= fFilteredProposals.length) | 893 if (fFilteredProposals is null || i < 0 || i >= fFilteredProposals.length) |
894 return null; | 894 return null; |
895 return fFilteredProposals[i]; | 895 return fFilteredProposals[i]; |
896 } | 896 } |
950 IEditingSupportRegistry registry= cast(IEditingSupportRegistry) fViewer; | 950 IEditingSupportRegistry registry= cast(IEditingSupportRegistry) fViewer; |
951 registry.register(helper); | 951 registry.register(helper); |
952 } | 952 } |
953 | 953 |
954 | 954 |
955 if (p instanceof ICompletionProposalExtension2 && fViewer !is null) { | 955 if (cast(ICompletionProposalExtension2)p && fViewer !is null) { |
956 ICompletionProposalExtension2 e= cast(ICompletionProposalExtension2) p; | 956 ICompletionProposalExtension2 e= cast(ICompletionProposalExtension2) p; |
957 e.apply(fViewer, trigger, stateMask, offset); | 957 e.apply(fViewer, trigger, stateMask, offset); |
958 } else if ( cast(ICompletionProposalExtension)p ) { | 958 } else if ( cast(ICompletionProposalExtension)p ) { |
959 ICompletionProposalExtension e= cast(ICompletionProposalExtension) p; | 959 ICompletionProposalExtension e= cast(ICompletionProposalExtension) p; |
960 e.apply(document, trigger, offset); | 960 e.apply(document, trigger, offset); |
1048 fPopupCloser.uninstall(); | 1048 fPopupCloser.uninstall(); |
1049 fProposalShell.setVisible(false); | 1049 fProposalShell.setVisible(false); |
1050 fProposalShell.dispose(); | 1050 fProposalShell.dispose(); |
1051 fProposalShell= null; | 1051 fProposalShell= null; |
1052 } | 1052 } |
1053 | 1053 |
1054 if (fMessageTextFont !is null) { | 1054 if (fMessageTextFont !is null) { |
1055 fMessageTextFont.dispose(); | 1055 fMessageTextFont.dispose(); |
1056 fMessageTextFont= null; | 1056 fMessageTextFont= null; |
1057 } | 1057 } |
1058 | 1058 |
1059 if (fMessageText !is null) { | 1059 if (fMessageText !is null) { |
1060 fMessageText= null; | 1060 fMessageText= null; |
1061 } | 1061 } |
1062 | 1062 |
1063 fEmptyMessage= null; | 1063 fEmptyMessage= null; |
1064 | 1064 |
1065 fLastCompletionOffset= -1; | 1065 fLastCompletionOffset= -1; |
1066 | 1066 |
1067 fContentAssistant.fireSessionEndEvent(); | 1067 fContentAssistant.fireSessionEndEvent(); |
1068 } | 1068 } |
1069 | 1069 |
1070 /** | 1070 /** |
1071 * Unregister this completion proposal popup. | 1071 * Unregister this completion proposal popup. |
1085 fContentAssistSubjectControlAdapter.removeKeyListener(fKeyListener); | 1085 fContentAssistSubjectControlAdapter.removeKeyListener(fKeyListener); |
1086 fKeyListener= null; | 1086 fKeyListener= null; |
1087 } | 1087 } |
1088 | 1088 |
1089 if (fLastProposal !is null) { | 1089 if (fLastProposal !is null) { |
1090 if (fLastProposal instanceof ICompletionProposalExtension2 && fViewer !is null) { | 1090 if (cast(ICompletionProposalExtension2)fLastProposal && fViewer !is null) { |
1091 ICompletionProposalExtension2 extension= cast(ICompletionProposalExtension2) fLastProposal; | 1091 ICompletionProposalExtension2 extension= cast(ICompletionProposalExtension2) fLastProposal; |
1092 extension.unselected(fViewer); | 1092 extension.unselected(fViewer); |
1093 } | 1093 } |
1094 fLastProposal= null; | 1094 fLastProposal= null; |
1095 } | 1095 } |
1121 ICompletionProposal oldProposal= getSelectedProposal(); // may trigger filtering and a reentrant call to setProposals() | 1121 ICompletionProposal oldProposal= getSelectedProposal(); // may trigger filtering and a reentrant call to setProposals() |
1122 if (oldProposals !is fFilteredProposals) // reentrant call was first - abort | 1122 if (oldProposals !is fFilteredProposals) // reentrant call was first - abort |
1123 return; | 1123 return; |
1124 | 1124 |
1125 if (Helper.okToUse(fProposalTable)) { | 1125 if (Helper.okToUse(fProposalTable)) { |
1126 if (oldProposal instanceof ICompletionProposalExtension2 && fViewer !is null) | 1126 if (cast(ICompletionProposalExtension2)oldProposal && fViewer !is null) |
1127 (cast(ICompletionProposalExtension2) oldProposal).unselected(fViewer); | 1127 (cast(ICompletionProposalExtension2) oldProposal).unselected(fViewer); |
1128 | 1128 |
1129 if (proposals is null || proposals.length is 0) { | 1129 if (proposals is null || proposals.length is 0) { |
1130 fEmptyProposal.fOffset= fFilterOffset; | 1130 fEmptyProposal.fOffset= fFilterOffset; |
1131 fEmptyProposal.fDisplayString= fEmptyMessage !is null ? fEmptyMessage : JFaceTextMessages.getString("CompletionProposalPopup.no_proposals"); //$NON-NLS-1$ | 1131 fEmptyProposal.fDisplayString= fEmptyMessage !is null ? fEmptyMessage : JFaceTextMessages.getString("CompletionProposalPopup.no_proposals"); //$NON-NLS-1$ |
1132 proposals= new ICompletionProposal[] { fEmptyProposal }; | 1132 proposals= [ fEmptyProposal ]; |
1133 } | 1133 } |
1134 | 1134 |
1135 fFilteredProposals= proposals; | 1135 fFilteredProposals= proposals; |
1136 final int newLen= proposals.length; | 1136 final int newLen= proposals.length; |
1137 if cast(USE_VIRTUAL) { | 1137 if (USE_VIRTUAL) { |
1138 fProposalTable.setItemCount(newLen); | 1138 fProposalTable.setItemCount(newLen); |
1139 fProposalTable.clearAll(); | 1139 fProposalTable.clearAll(); |
1140 } else { | 1140 } else { |
1141 fProposalTable.setRedraw(false); | 1141 fProposalTable.setRedraw(false); |
1142 fProposalTable.setItemCount(newLen); | 1142 fProposalTable.setItemCount(newLen); |
1191 return; | 1191 return; |
1192 | 1192 |
1193 if (fContentAssistant.addContentAssistListener(this, ContentAssistant.PROPOSAL_SELECTOR)) { | 1193 if (fContentAssistant.addContentAssistListener(this, ContentAssistant.PROPOSAL_SELECTOR)) { |
1194 | 1194 |
1195 ensureDocumentListenerInstalled(); | 1195 ensureDocumentListenerInstalled(); |
1196 | 1196 |
1197 if (fFocusHelper is null) { | 1197 if (fFocusHelper is null) { |
1198 fFocusHelper= new class() IEditingSupport { | 1198 fFocusHelper= new class() IEditingSupport { |
1199 | 1199 |
1200 public bool isOriginator(DocumentEvent event, IRegion focus) { | 1200 public bool isOriginator(DocumentEvent event, IRegion focus) { |
1201 return false; // this helper just covers the focus change to the proposal shell, no remote editions | 1201 return false; // this helper just covers the focus change to the proposal shell, no remote editions |
1365 * @since 2.1 | 1365 * @since 2.1 |
1366 */ | 1366 */ |
1367 private void selectProposal(int index, bool smartToggle) { | 1367 private void selectProposal(int index, bool smartToggle) { |
1368 | 1368 |
1369 ICompletionProposal oldProposal= getSelectedProposal(); | 1369 ICompletionProposal oldProposal= getSelectedProposal(); |
1370 if (oldProposal instanceof ICompletionProposalExtension2 && fViewer !is null) | 1370 if (cast(ICompletionProposalExtension2)oldProposal && fViewer !is null) |
1371 (cast(ICompletionProposalExtension2) oldProposal).unselected(fViewer); | 1371 (cast(ICompletionProposalExtension2) oldProposal).unselected(fViewer); |
1372 | 1372 |
1373 if (fFilteredProposals is null) { | 1373 if (fFilteredProposals is null) { |
1374 fireSelectionEvent(null, smartToggle); | 1374 fireSelectionEvent(null, smartToggle); |
1375 return; | 1375 return; |
1376 } | 1376 } |
1377 | 1377 |
1378 ICompletionProposal proposal= fFilteredProposals[index]; | 1378 ICompletionProposal proposal= fFilteredProposals[index]; |
1379 if (proposal instanceof ICompletionProposalExtension2 && fViewer !is null) | 1379 if (cast(ICompletionProposalExtension2)proposal && fViewer !is null) |
1380 (cast(ICompletionProposalExtension2) proposal).selected(fViewer, smartToggle); | 1380 (cast(ICompletionProposalExtension2) proposal).selected(fViewer, smartToggle); |
1381 | 1381 |
1382 fireSelectionEvent(proposal, smartToggle); | 1382 fireSelectionEvent(proposal, smartToggle); |
1383 | 1383 |
1384 fLastProposal= proposal; | 1384 fLastProposal= proposal; |
1385 | 1385 |
1386 fProposalTable.setSelection(index); | 1386 fProposalTable.setSelection(index); |
1389 fAdditionalInfoController.handleTableSelectionChanged(); | 1389 fAdditionalInfoController.handleTableSelectionChanged(); |
1390 } | 1390 } |
1391 | 1391 |
1392 /** | 1392 /** |
1393 * Fires a selection event, see {@link ICompletionListener}. | 1393 * Fires a selection event, see {@link ICompletionListener}. |
1394 * | 1394 * |
1395 * @param proposal the selected proposal, possibly <code>null</code> | 1395 * @param proposal the selected proposal, possibly <code>null</code> |
1396 * @param smartToggle true if the smart toggle is on | 1396 * @param smartToggle true if the smart toggle is on |
1397 * @since 3.2 | 1397 * @since 3.2 |
1398 */ | 1398 */ |
1399 private void fireSelectionEvent(ICompletionProposal proposal, bool smartToggle) { | 1399 private void fireSelectionEvent(ICompletionProposal proposal, bool smartToggle) { |
1481 IDocument document= fContentAssistSubjectControlAdapter.getDocument(); | 1481 IDocument document= fContentAssistSubjectControlAdapter.getDocument(); |
1482 int length= proposals.length; | 1482 int length= proposals.length; |
1483 List filtered= new ArrayList(length); | 1483 List filtered= new ArrayList(length); |
1484 for (int i= 0; i < length; i++) { | 1484 for (int i= 0; i < length; i++) { |
1485 | 1485 |
1486 if (proposals[i] instanceof ICompletionProposalExtension2) { | 1486 if (cast(ICompletionProposalExtension2)proposals[i] ) { |
1487 | 1487 |
1488 ICompletionProposalExtension2 p= cast(ICompletionProposalExtension2) proposals[i]; | 1488 ICompletionProposalExtension2 p= cast(ICompletionProposalExtension2) proposals[i]; |
1489 if (p.validate(document, offset, event)) | 1489 if (p.validate(document, offset, event)) |
1490 filtered.add(p); | 1490 filtered.add(p); |
1491 | 1491 |
1492 } else if (proposals[i] instanceof ICompletionProposalExtension) { | 1492 } else if (cast(ICompletionProposalExtension)proposals[i] ) { |
1493 | 1493 |
1494 ICompletionProposalExtension p= cast(ICompletionProposalExtension) proposals[i]; | 1494 ICompletionProposalExtension p= cast(ICompletionProposalExtension) proposals[i]; |
1495 if (p.isValidFor(document, offset)) | 1495 if (p.isValidFor(document, offset)) |
1496 filtered.add(p); | 1496 filtered.add(p); |
1497 | 1497 |
1516 public void setFocus() { | 1516 public void setFocus() { |
1517 if (Helper.okToUse(fProposalShell)) { | 1517 if (Helper.okToUse(fProposalShell)) { |
1518 fProposalShell.setFocus(); | 1518 fProposalShell.setFocus(); |
1519 } | 1519 } |
1520 } | 1520 } |
1521 | 1521 |
1522 /** | 1522 /** |
1523 * Returns <code>true</code> if <code>proposal</code> should be auto-inserted, | 1523 * Returns <code>true</code> if <code>proposal</code> should be auto-inserted, |
1524 * <code>false</code> otherwise. | 1524 * <code>false</code> otherwise. |
1525 * | 1525 * |
1526 * @param proposal the single proposal that might be automatically inserted | 1526 * @param proposal the single proposal that might be automatically inserted |
1527 * @return <code>true</code> if <code>proposal</code> can be inserted automatically, | 1527 * @return <code>true</code> if <code>proposal</code> can be inserted automatically, |
1528 * <code>false</code> otherwise | 1528 * <code>false</code> otherwise |
1529 * @since 3.1 | 1529 * @since 3.1 |
1530 */ | 1530 */ |
1572 fFilteredProposals= computeProposals(fInvocationOffset); | 1572 fFilteredProposals= computeProposals(fInvocationOffset); |
1573 | 1573 |
1574 int count= (fFilteredProposals is null ? 0 : fFilteredProposals.length); | 1574 int count= (fFilteredProposals is null ? 0 : fFilteredProposals.length); |
1575 if (count is 0 && hideWhenNoProposals(false)) | 1575 if (count is 0 && hideWhenNoProposals(false)) |
1576 return; | 1576 return; |
1577 | 1577 |
1578 if (count is 1 && canAutoInsert(fFilteredProposals[0])) { | 1578 if (count is 1 && canAutoInsert(fFilteredProposals[0])) { |
1579 insertProposal(fFilteredProposals[0], cast(wchar) 0, 0, fInvocationOffset); | 1579 insertProposal(fFilteredProposals[0], cast(wchar) 0, 0, fInvocationOffset); |
1580 hide(); | 1580 hide(); |
1581 } else { | 1581 } else { |
1582 ensureDocumentListenerInstalled(); | 1582 ensureDocumentListenerInstalled(); |
1598 /** | 1598 /** |
1599 * Acts upon <code>fFilteredProposals</code>: if there is just one valid | 1599 * Acts upon <code>fFilteredProposals</code>: if there is just one valid |
1600 * proposal, it is inserted, otherwise, the common prefix of all proposals | 1600 * proposal, it is inserted, otherwise, the common prefix of all proposals |
1601 * is inserted into the document. If there is no common prefix, nothing | 1601 * is inserted into the document. If there is no common prefix, nothing |
1602 * happens and <code>false</code> is returned. | 1602 * happens and <code>false</code> is returned. |
1603 * | 1603 * |
1604 * @return <code>true</code> if a single proposal was inserted and the | 1604 * @return <code>true</code> if a single proposal was inserted and the |
1605 * selector can be closed, <code>false</code> otherwise | 1605 * selector can be closed, <code>false</code> otherwise |
1606 * @since 3.0 | 1606 * @since 3.0 |
1607 */ | 1607 */ |
1608 private bool completeCommonPrefix() { | 1608 private bool completeCommonPrefix() { |
1623 // contains the common postfix in the case that there are any proposals matching our LHS | 1623 // contains the common postfix in the case that there are any proposals matching our LHS |
1624 StringBuffer rightCasePostfix= null; | 1624 StringBuffer rightCasePostfix= null; |
1625 List rightCase= new ArrayList(); | 1625 List rightCase= new ArrayList(); |
1626 | 1626 |
1627 bool isWrongCaseMatch= false; | 1627 bool isWrongCaseMatch= false; |
1628 | 1628 |
1629 // the prefix of all case insensitive matches. This differs from the document | 1629 // the prefix of all case insensitive matches. This differs from the document |
1630 // contents and will be replaced. | 1630 // contents and will be replaced. |
1631 CharSequence wrongCasePrefix= null; | 1631 CharSequence wrongCasePrefix= null; |
1632 int wrongCasePrefixStart= 0; | 1632 int wrongCasePrefixStart= 0; |
1633 // contains the common postfix of all case-insensitive matches | 1633 // contains the common postfix of all case-insensitive matches |
1634 StringBuffer wrongCasePostfix= null; | 1634 StringBuffer wrongCasePostfix= null; |
1635 List wrongCase= new ArrayList(); | 1635 List wrongCase= new ArrayList(); |
1636 | 1636 |
1637 for (int i= 0; i < fFilteredProposals.length; i++) { | 1637 for (int i= 0; i < fFilteredProposals.length; i++) { |
1638 ICompletionProposal proposal= fFilteredProposals[i]; | 1638 ICompletionProposal proposal= fFilteredProposals[i]; |
1639 | 1639 |
1640 if (!( cast(ICompletionProposalExtension3)proposal )) | 1640 if (!( cast(ICompletionProposalExtension3)proposal )) |
1641 return false; | 1641 return false; |
1642 | 1642 |
1643 int start= (cast(ICompletionProposalExtension3)proposal).getPrefixCompletionStart(fContentAssistSubjectControlAdapter.getDocument(), fFilterOffset); | 1643 int start= (cast(ICompletionProposalExtension3)proposal).getPrefixCompletionStart(fContentAssistSubjectControlAdapter.getDocument(), fFilterOffset); |
1644 CharSequence insertion= (cast(ICompletionProposalExtension3)proposal).getPrefixCompletionText(fContentAssistSubjectControlAdapter.getDocument(), fFilterOffset); | 1644 CharSequence insertion= (cast(ICompletionProposalExtension3)proposal).getPrefixCompletionText(fContentAssistSubjectControlAdapter.getDocument(), fFilterOffset); |
1645 if (insertion is null) | 1645 if (insertion is null) |
1646 insertion= proposal.getDisplayString(); | 1646 insertion= proposal.getDisplayString(); |
1647 try { | 1647 try { |
1767 private void truncatePostfix(StringBuffer buffer, CharSequence sequence) { | 1767 private void truncatePostfix(StringBuffer buffer, CharSequence sequence) { |
1768 // find common prefix | 1768 // find common prefix |
1769 int min= Math.min(buffer.length(), sequence.length()); | 1769 int min= Math.min(buffer.length(), sequence.length()); |
1770 for (int c= 0; c < min; c++) { | 1770 for (int c= 0; c < min; c++) { |
1771 if (sequence.charAt(c) !is buffer.charAt(c)) { | 1771 if (sequence.charAt(c) !is buffer.charAt(c)) { |
1772 buffer.delete(c, buffer.length()); | 1772 buffer.delete_(c, buffer.length()); |
1773 return; | 1773 return; |
1774 } | 1774 } |
1775 } | 1775 } |
1776 | 1776 |
1777 // all equal up to minimum | 1777 // all equal up to minimum |
1778 buffer.delete(min, buffer.length()); | 1778 buffer.delete_(min, buffer.length()); |
1779 } | 1779 } |
1780 | 1780 |
1781 /** | 1781 /** |
1782 * Sets the message for the repetition affordance text at the bottom of the proposal. Only has | 1782 * Sets the message for the repetition affordance text at the bottom of the proposal. Only has |
1783 * an effect if {@link ContentAssistant#isRepeatedInvocationMode()} returns <code>true</code>. | 1783 * an effect if {@link ContentAssistant#isRepeatedInvocationMode()} returns <code>true</code>. |
1784 * | 1784 * |
1785 * @param message the new caption | 1785 * @param message the new caption |
1786 * @since 3.2 | 1786 * @since 3.2 |
1787 */ | 1787 */ |
1788 void setMessage(String message) { | 1788 void setMessage(String message) { |
1789 Assert.isNotNull(message); | 1789 Assert.isNotNull(message); |
1792 } | 1792 } |
1793 | 1793 |
1794 /** | 1794 /** |
1795 * Sets the text to be displayed if no proposals are available. Only has an effect if | 1795 * Sets the text to be displayed if no proposals are available. Only has an effect if |
1796 * {@link ContentAssistant#isShowEmptyList()} returns <code>true</code>. | 1796 * {@link ContentAssistant#isShowEmptyList()} returns <code>true</code>. |
1797 * | 1797 * |
1798 * @param message the empty message | 1798 * @param message the empty message |
1799 * @since 3.2 | 1799 * @since 3.2 |
1800 */ | 1800 */ |
1801 void setEmptyMessage(String message) { | 1801 void setEmptyMessage(String message) { |
1802 Assert.isNotNull(message); | 1802 Assert.isNotNull(message); |
1803 fEmptyMessage= message; | 1803 fEmptyMessage= message; |
1804 } | 1804 } |
1805 | 1805 |
1806 /** | 1806 /** |
1807 * Enables or disables showing of the caption line. See also {@link #setMessage(String)}. | 1807 * Enables or disables showing of the caption line. See also {@link #setMessage(String)}. |
1808 * | 1808 * |
1809 * @param show | 1809 * @param show |
1810 * @since 3.2 | 1810 * @since 3.2 |
1811 */ | 1811 */ |
1812 public void setStatusLineVisible(bool show) { | 1812 public void setStatusLineVisible(bool show) { |
1813 if (!isActive() || show is (fMessageText !is null)) | 1813 if (!isActive() || show is (fMessageText !is null)) |
1814 return; // nothing to do | 1814 return; // nothing to do |
1815 | 1815 |
1816 if (show) { | 1816 if (show) { |
1817 createMessageText(); | 1817 createMessageText(); |
1818 } else { | 1818 } else { |
1819 fMessageText.dispose(); | 1819 fMessageText.dispose(); |
1820 fMessageText= null; | 1820 fMessageText= null; |
1822 fProposalShell.layout(); | 1822 fProposalShell.layout(); |
1823 } | 1823 } |
1824 | 1824 |
1825 /** | 1825 /** |
1826 * Informs the popup that it is being placed above the caret line instead of below. | 1826 * Informs the popup that it is being placed above the caret line instead of below. |
1827 * | 1827 * |
1828 * @param above <code>true</code> if the location of the popup is above the caret line, <code>false</code> if it is below | 1828 * @param above <code>true</code> if the location of the popup is above the caret line, <code>false</code> if it is below |
1829 * @since 3.3 | 1829 * @since 3.3 |
1830 */ | 1830 */ |
1831 void switchedPositionToAbove(bool above) { | 1831 void switchedPositionToAbove(bool above) { |
1832 if (fAdditionalInfoController !is null) { | 1832 if (fAdditionalInfoController !is null) { |
1833 fAdditionalInfoController.setFallbackAnchors(new Anchor[] { | 1833 fAdditionalInfoController.setFallbackAnchors([ |
1834 AbstractInformationControlManager.ANCHOR_RIGHT, | 1834 AbstractInformationControlManager.ANCHOR_RIGHT, |
1835 AbstractInformationControlManager.ANCHOR_LEFT, | 1835 AbstractInformationControlManager.ANCHOR_LEFT, |
1836 above ? AbstractInformationControlManager.ANCHOR_TOP : AbstractInformationControlManager.ANCHOR_BOTTOM | 1836 above ? AbstractInformationControlManager.ANCHOR_TOP : AbstractInformationControlManager.ANCHOR_BOTTOM |
1837 }); | 1837 ]); |
1838 } | 1838 } |
1839 } | 1839 } |
1840 | 1840 |
1841 /** | 1841 /** |
1842 * Returns a new proposal selection handler. | 1842 * Returns a new proposal selection handler. |
1843 * | 1843 * |
1844 * @param operationCode the operation code | 1844 * @param operationCode the operation code |
1845 * @return the handler | 1845 * @return the handler |
1846 * @since 3.4 | 1846 * @since 3.4 |
1847 */ | 1847 */ |
1848 IHandler createProposalSelectionHandler(int operationCode) { | 1848 IHandler createProposalSelectionHandler(int operationCode) { |