1 11 package org.eclipse.jdt.internal.ui.text; 12 13 import java.util.List ; 14 15 import org.eclipse.core.runtime.CoreException; 16 17 import org.eclipse.swt.SWT; 18 import org.eclipse.swt.events.DisposeEvent; 19 import org.eclipse.swt.events.DisposeListener; 20 import org.eclipse.swt.events.FocusListener; 21 import org.eclipse.swt.events.KeyEvent; 22 import org.eclipse.swt.events.KeyListener; 23 import org.eclipse.swt.events.ModifyEvent; 24 import org.eclipse.swt.events.ModifyListener; 25 import org.eclipse.swt.events.MouseAdapter; 26 import org.eclipse.swt.events.MouseEvent; 27 import org.eclipse.swt.events.MouseMoveListener; 28 import org.eclipse.swt.events.SelectionEvent; 29 import org.eclipse.swt.events.SelectionListener; 30 import org.eclipse.swt.graphics.Color; 31 import org.eclipse.swt.graphics.Point; 32 import org.eclipse.swt.layout.GridData; 33 import org.eclipse.swt.widgets.Composite; 34 import org.eclipse.swt.widgets.Control; 35 import org.eclipse.swt.widgets.Item; 36 import org.eclipse.swt.widgets.Label; 37 import org.eclipse.swt.widgets.Shell; 38 import org.eclipse.swt.widgets.Text; 39 import org.eclipse.swt.widgets.Tree; 40 import org.eclipse.swt.widgets.TreeItem; 41 42 import org.eclipse.jface.action.Action; 43 import org.eclipse.jface.action.IAction; 44 import org.eclipse.jface.action.IMenuManager; 45 import org.eclipse.jface.dialogs.Dialog; 46 import org.eclipse.jface.dialogs.IDialogSettings; 47 import org.eclipse.jface.dialogs.PopupDialog; 48 import org.eclipse.jface.viewers.ILabelProvider; 49 import org.eclipse.jface.viewers.IStructuredSelection; 50 import org.eclipse.jface.viewers.ITreeContentProvider; 51 import org.eclipse.jface.viewers.StructuredSelection; 52 import org.eclipse.jface.viewers.TreeViewer; 53 import org.eclipse.jface.viewers.Viewer; 54 import org.eclipse.jface.viewers.ViewerFilter; 55 56 import org.eclipse.jface.text.IInformationControl; 57 import org.eclipse.jface.text.IInformationControlExtension; 58 import org.eclipse.jface.text.IInformationControlExtension2; 59 60 import org.eclipse.ui.IEditorPart; 61 import org.eclipse.ui.PlatformUI; 62 import org.eclipse.ui.commands.ActionHandler; 63 import org.eclipse.ui.commands.HandlerSubmission; 64 import org.eclipse.ui.commands.ICommand; 65 import org.eclipse.ui.commands.ICommandManager; 66 import org.eclipse.ui.commands.IKeySequenceBinding; 67 import org.eclipse.ui.commands.Priority; 68 import org.eclipse.ui.keys.KeySequence; 69 70 import org.eclipse.jdt.core.IJavaElement; 71 import org.eclipse.jdt.core.IParent; 72 73 import org.eclipse.jdt.ui.actions.CustomFiltersActionGroup; 74 75 import org.eclipse.jdt.internal.ui.JavaPlugin; 76 import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility; 77 import org.eclipse.jdt.internal.ui.util.StringMatcher; 78 79 84 public abstract class AbstractInformationControl extends PopupDialog implements IInformationControl, IInformationControlExtension, IInformationControlExtension2, DisposeListener { 85 86 92 protected class NamePatternFilter extends ViewerFilter { 93 94 public NamePatternFilter() { 95 } 96 97 100 public boolean select(Viewer viewer, Object parentElement, Object element) { 101 StringMatcher matcher= getMatcher(); 102 if (matcher == null || !(viewer instanceof TreeViewer)) 103 return true; 104 TreeViewer treeViewer= (TreeViewer) viewer; 105 106 String matchName= ((ILabelProvider) treeViewer.getLabelProvider()).getText(element); 107 if (matchName != null && matcher.match(matchName)) 108 return true; 109 110 return hasUnfilteredChild(treeViewer, element); 111 } 112 113 private boolean hasUnfilteredChild(TreeViewer viewer, Object element) { 114 if (element instanceof IParent) { 115 Object [] children= ((ITreeContentProvider) viewer.getContentProvider()).getChildren(element); 116 for (int i= 0; i < children.length; i++) 117 if (select(viewer, element, children[i])) 118 return true; 119 } 120 return false; 121 } 122 } 123 124 125 private Text fFilterText; 126 127 private TreeViewer fTreeViewer; 128 129 protected StringMatcher fStringMatcher; 130 private ICommand fInvokingCommand; 131 private KeySequence[] fInvokingCommandKeySequences; 132 133 138 private Composite fViewMenuButtonComposite; 139 140 private CustomFiltersActionGroup fCustomFiltersActionGroup; 141 142 private IAction fShowViewMenuAction; 143 private HandlerSubmission fShowViewMenuHandlerSubmission; 144 145 150 private int fTreeStyle; 151 152 162 public AbstractInformationControl(Shell parent, int shellStyle, int treeStyle, String invokingCommandId, boolean showStatusField) { 163 super(parent, shellStyle, true, true, true, true, null, null); 164 if (invokingCommandId != null) { 165 ICommandManager commandManager= PlatformUI.getWorkbench().getCommandSupport().getCommandManager(); 166 fInvokingCommand= commandManager.getCommand(invokingCommandId); 167 if (fInvokingCommand != null && !fInvokingCommand.isDefined()) 168 fInvokingCommand= null; 169 else 170 getInvokingCommandKeySequences(); 172 } 173 fTreeStyle= treeStyle; 174 if (hasHeader()) 176 setTitleText(""); setInfoText(""); 179 create(); 181 182 setInfoText(getStatusFieldText()); 184 } 185 186 193 protected Control createDialogArea(Composite parent) { 194 fTreeViewer= createTreeViewer(parent, fTreeStyle); 195 196 fCustomFiltersActionGroup= new CustomFiltersActionGroup(getId(), fTreeViewer); 197 198 final Tree tree= fTreeViewer.getTree(); 199 tree.addKeyListener(new KeyListener() { 200 public void keyPressed(KeyEvent e) { 201 if (e.character == 0x1B) dispose(); 203 } 204 public void keyReleased(KeyEvent e) { 205 } 207 }); 208 209 tree.addSelectionListener(new SelectionListener() { 210 public void widgetSelected(SelectionEvent e) { 211 } 213 public void widgetDefaultSelected(SelectionEvent e) { 214 gotoSelectedElement(); 215 } 216 }); 217 218 tree.addMouseMoveListener(new MouseMoveListener() { 219 TreeItem fLastItem= null; 220 public void mouseMove(MouseEvent e) { 221 if (tree.equals(e.getSource())) { 222 Object o= tree.getItem(new Point(e.x, e.y)); 223 if (o instanceof TreeItem) { 224 if (!o.equals(fLastItem)) { 225 fLastItem= (TreeItem)o; 226 tree.setSelection(new TreeItem[] { fLastItem }); 227 } else if (e.y < tree.getItemHeight() / 4) { 228 Point p= tree.toDisplay(e.x, e.y); 230 Item item= fTreeViewer.scrollUp(p.x, p.y); 231 if (item instanceof TreeItem) { 232 fLastItem= (TreeItem)item; 233 tree.setSelection(new TreeItem[] { fLastItem }); 234 } 235 } else if (e.y > tree.getBounds().height - tree.getItemHeight() / 4) { 236 Point p= tree.toDisplay(e.x, e.y); 238 Item item= fTreeViewer.scrollDown(p.x, p.y); 239 if (item instanceof TreeItem) { 240 fLastItem= (TreeItem)item; 241 tree.setSelection(new TreeItem[] { fLastItem }); 242 } 243 } 244 } 245 } 246 } 247 }); 248 249 tree.addMouseListener(new MouseAdapter() { 250 public void mouseUp(MouseEvent e) { 251 252 if (tree.getSelectionCount() < 1) 253 return; 254 255 if (e.button != 1) 256 return; 257 258 if (tree.equals(e.getSource())) { 259 Object o= tree.getItem(new Point(e.x, e.y)); 260 TreeItem selection= tree.getSelection()[0]; 261 if (selection.equals(o)) 262 gotoSelectedElement(); 263 } 264 } 265 }); 266 267 installFilter(); 268 269 addDisposeListener(this); 270 return fTreeViewer.getControl(); 271 } 272 273 281 public AbstractInformationControl(Shell parent, int shellStyle, int treeStyle) { 282 this(parent, shellStyle, treeStyle, null, false); 283 } 284 285 protected abstract TreeViewer createTreeViewer(Composite parent, int style); 286 287 292 protected abstract String getId(); 293 294 protected TreeViewer getTreeViewer() { 295 return fTreeViewer; 296 } 297 298 306 protected boolean hasHeader() { 307 return false; 309 } 310 311 protected Text getFilterText() { 312 return fFilterText; 313 } 314 315 protected Text createFilterText(Composite parent) { 316 fFilterText= new Text(parent, SWT.NONE); 317 Dialog.applyDialogFont(fFilterText); 318 319 GridData data= new GridData(GridData.FILL_HORIZONTAL); 320 data.horizontalAlignment= GridData.FILL; 321 data.verticalAlignment= GridData.CENTER; 322 fFilterText.setLayoutData(data); 323 324 fFilterText.addKeyListener(new KeyListener() { 325 public void keyPressed(KeyEvent e) { 326 if (e.keyCode == 0x0D) gotoSelectedElement(); 328 if (e.keyCode == SWT.ARROW_DOWN) 329 fTreeViewer.getTree().setFocus(); 330 if (e.keyCode == SWT.ARROW_UP) 331 fTreeViewer.getTree().setFocus(); 332 if (e.character == 0x1B) dispose(); 334 } 335 public void keyReleased(KeyEvent e) { 336 } 338 }); 339 340 return fFilterText; 341 } 342 343 protected void createHorizontalSeparator(Composite parent) { 344 Label separator= new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL | SWT.LINE_DOT); 345 separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 346 } 347 348 protected void updateStatusFieldText() { 349 setInfoText(getStatusFieldText()); 350 } 351 352 358 protected void handleStatusFieldClicked() { 359 } 360 361 protected String getStatusFieldText() { 362 return ""; } 364 365 private void installFilter() { 366 fFilterText.setText(""); 368 fFilterText.addModifyListener(new ModifyListener() { 369 public void modifyText(ModifyEvent e) { 370 String text= ((Text) e.widget).getText(); 371 int length= text.length(); 372 if (length > 0 && text.charAt(length -1 ) != '*') { 373 text= text + '*'; 374 } 375 setMatcherString(text, true); 376 } 377 }); 378 } 379 380 384 protected void stringMatcherUpdated() { 385 fTreeViewer.getControl().setRedraw(false); 387 fTreeViewer.refresh(); 388 fTreeViewer.expandAll(); 389 selectFirstMatch(); 390 fTreeViewer.getControl().setRedraw(true); 391 } 392 393 404 protected void setMatcherString(String pattern, boolean update) { 405 if (pattern.length() == 0) { 406 fStringMatcher= null; 407 } else { 408 boolean ignoreCase= pattern.toLowerCase().equals(pattern); 409 fStringMatcher= new StringMatcher(pattern, ignoreCase, false); 410 } 411 412 if (update) 413 stringMatcherUpdated(); 414 } 415 416 protected StringMatcher getMatcher() { 417 return fStringMatcher; 418 } 419 420 425 protected Object getSelectedElement() { 426 if (fTreeViewer == null) 427 return null; 428 429 return ((IStructuredSelection) fTreeViewer.getSelection()).getFirstElement(); 430 } 431 432 private void gotoSelectedElement() { 433 Object selectedElement= getSelectedElement(); 434 if (selectedElement != null) { 435 try { 436 dispose(); 437 IEditorPart part= EditorUtility.openInEditor(selectedElement, true); 438 if (part != null && selectedElement instanceof IJavaElement) 439 EditorUtility.revealInEditor(part, (IJavaElement) selectedElement); 440 } catch (CoreException ex) { 441 JavaPlugin.log(ex); 442 } 443 } 444 } 445 446 450 protected void selectFirstMatch() { 451 Tree tree= fTreeViewer.getTree(); 452 Object element= findElement(tree.getItems()); 453 if (element != null) 454 fTreeViewer.setSelection(new StructuredSelection(element), true); 455 else 456 fTreeViewer.setSelection(StructuredSelection.EMPTY); 457 } 458 459 private IJavaElement findElement(TreeItem[] items) { 460 ILabelProvider labelProvider= (ILabelProvider)fTreeViewer.getLabelProvider(); 461 for (int i= 0; i < items.length; i++) { 462 IJavaElement element= (IJavaElement)items[i].getData(); 463 if (fStringMatcher == null) 464 return element; 465 466 if (element != null) { 467 String label= labelProvider.getText(element); 468 if (fStringMatcher.match(label)) 469 return element; 470 } 471 472 element= findElement(items[i].getItems()); 473 if (element != null) 474 return element; 475 } 476 return null; 477 } 478 479 482 public void setInformation(String information) { 483 } 485 486 489 public abstract void setInput(Object information); 490 491 498 protected void fillViewMenu(IMenuManager viewMenu) { 499 fCustomFiltersActionGroup.fillViewMenu(viewMenu); 500 } 501 502 508 protected void fillDialogMenu(IMenuManager dialogMenu) { 509 super.fillDialogMenu(dialogMenu); 510 fillViewMenu(dialogMenu); 511 } 512 513 protected void inputChanged(Object newInput, Object newSelection) { 514 fFilterText.setText(""); fTreeViewer.setInput(newInput); 516 if (newSelection != null) { 517 fTreeViewer.setSelection(new StructuredSelection(newSelection)); 518 } 519 } 520 521 524 public void setVisible(boolean visible) { 525 if (visible) { 526 open(); 527 } else { 528 removeHandlerAndKeyBindingSupport(); 529 saveDialogBounds(getShell()); 530 getShell().setVisible(false); 531 removeHandlerAndKeyBindingSupport(); 532 } 533 } 534 535 539 public int open() { 540 addHandlerAndKeyBindingSupport(); 541 return super.open(); 542 } 543 544 547 public final void dispose() { 548 close(); 549 } 550 551 558 public void widgetDisposed(DisposeEvent event) { 559 removeHandlerAndKeyBindingSupport(); 560 fTreeViewer= null; 561 fFilterText= null; 562 } 563 564 569 protected void addHandlerAndKeyBindingSupport() { 570 if (fShowViewMenuHandlerSubmission == null) { 572 fShowViewMenuHandlerSubmission= new HandlerSubmission(null, getShell(), null, fShowViewMenuAction.getActionDefinitionId(), new ActionHandler(fShowViewMenuAction), Priority.MEDIUM); 573 PlatformUI.getWorkbench().getCommandSupport().addHandlerSubmission(fShowViewMenuHandlerSubmission); 574 } 575 } 576 577 582 protected void removeHandlerAndKeyBindingSupport() { 583 if (fShowViewMenuHandlerSubmission != null) 585 PlatformUI.getWorkbench().getCommandSupport().removeHandlerSubmission(fShowViewMenuHandlerSubmission); 586 587 } 588 589 592 public boolean hasContents() { 593 return fTreeViewer != null && fTreeViewer.getInput() != null; 594 } 595 596 599 public void setSizeConstraints(int maxWidth, int maxHeight) { 600 } 602 603 606 public Point computeSizeHint() { 607 return getShell().getSize(); 610 } 611 612 615 public void setLocation(Point location) { 616 627 if (!getPersistBounds() || getDialogSettings() == null) 628 getShell().setLocation(location); 629 } 630 631 634 public void setSize(int width, int height) { 635 getShell().setSize(width, height); 636 } 637 638 641 public void addDisposeListener(DisposeListener listener) { 642 getShell().addDisposeListener(listener); 643 } 644 645 648 public void removeDisposeListener(DisposeListener listener) { 649 getShell().removeDisposeListener(listener); 650 } 651 652 655 public void setForegroundColor(Color foreground) { 656 applyForegroundColor(foreground, getContents()); 657 } 658 659 662 public void setBackgroundColor(Color background) { 663 applyBackgroundColor(background, getContents()); 664 } 665 666 669 public boolean isFocusControl() { 670 return fTreeViewer.getControl().isFocusControl() || fFilterText.isFocusControl(); 671 } 672 673 676 public void setFocus() { 677 getShell().forceFocus(); 678 fFilterText.setFocus(); 679 } 680 681 684 public void addFocusListener(FocusListener listener) { 685 getShell().addFocusListener(listener); 686 } 687 688 691 public void removeFocusListener(FocusListener listener) { 692 getShell().removeFocusListener(listener); 693 } 694 695 final protected ICommand getInvokingCommand() { 696 return fInvokingCommand; 697 } 698 699 final protected KeySequence[] getInvokingCommandKeySequences() { 700 if (fInvokingCommandKeySequences == null) { 701 if (getInvokingCommand() != null) { 702 List list= getInvokingCommand().getKeySequenceBindings(); 703 if (!list.isEmpty()) { 704 fInvokingCommandKeySequences= new KeySequence[list.size()]; 705 for (int i= 0; i < fInvokingCommandKeySequences.length; i++) { 706 fInvokingCommandKeySequences[i]= ((IKeySequenceBinding) list.get(i)).getKeySequence(); 707 } 708 return fInvokingCommandKeySequences; 709 } 710 } 711 } 712 return fInvokingCommandKeySequences; 713 } 714 715 718 protected IDialogSettings getDialogSettings() { 719 String sectionName= getId(); 720 721 IDialogSettings settings= JavaPlugin.getDefault().getDialogSettings().getSection(sectionName); 722 if (settings == null) 723 settings= JavaPlugin.getDefault().getDialogSettings().addNewSection(sectionName); 724 725 return settings; 726 } 727 728 733 protected Control createTitleMenuArea(Composite parent) { 734 fViewMenuButtonComposite= (Composite) super.createTitleMenuArea(parent); 735 736 739 if (hasHeader()) { 740 fFilterText= createFilterText(parent); 741 } 742 743 fShowViewMenuAction= new Action("showViewMenu") { 748 public void run() { 749 showDialogMenu(); 750 } 751 }; 752 fShowViewMenuAction.setEnabled(true); 753 fShowViewMenuAction.setActionDefinitionId("org.eclipse.ui.window.showViewMenu"); 755 return fViewMenuButtonComposite; 756 } 757 758 763 protected Control createTitleControl(Composite parent) { 764 if (hasHeader()) { 765 return super.createTitleControl(parent); 766 } 767 fFilterText= createFilterText(parent); 768 return fFilterText; 769 } 770 771 774 protected void setTabOrder(Composite composite) { 775 if (hasHeader()) { 776 composite.setTabList(new Control[] { fFilterText, fTreeViewer.getTree() }); 777 } else { 778 fViewMenuButtonComposite.setTabList(new Control[] { fFilterText }); 779 composite.setTabList(new Control[] { fViewMenuButtonComposite, fTreeViewer.getTree() }); 780 } 781 } 782 } 783 | Popular Tags |