1 11 12 package org.eclipse.ui.internal.keys; 13 14 import java.util.ArrayList ; 15 import java.util.List ; 16 17 import org.eclipse.core.runtime.IProgressMonitor; 18 import org.eclipse.core.runtime.IStatus; 19 import org.eclipse.core.runtime.Status; 20 import org.eclipse.core.runtime.jobs.Job; 21 import org.eclipse.jface.action.Action; 22 import org.eclipse.jface.action.IAction; 23 import org.eclipse.jface.action.ToolBarManager; 24 import org.eclipse.jface.dialogs.IDialogSettings; 25 import org.eclipse.jface.resource.JFaceResources; 26 import org.eclipse.jface.viewers.TableTreeViewer; 27 import org.eclipse.swt.SWT; 28 import org.eclipse.swt.accessibility.AccessibleAdapter; 29 import org.eclipse.swt.accessibility.AccessibleEvent; 30 import org.eclipse.swt.events.ControlAdapter; 31 import org.eclipse.swt.events.ControlEvent; 32 import org.eclipse.swt.events.DisposeEvent; 33 import org.eclipse.swt.events.DisposeListener; 34 import org.eclipse.swt.events.KeyAdapter; 35 import org.eclipse.swt.events.KeyEvent; 36 import org.eclipse.swt.events.SelectionAdapter; 37 import org.eclipse.swt.events.SelectionEvent; 38 import org.eclipse.swt.events.TraverseEvent; 39 import org.eclipse.swt.events.TraverseListener; 40 import org.eclipse.swt.graphics.Point; 41 import org.eclipse.swt.graphics.Rectangle; 42 import org.eclipse.swt.layout.GridData; 43 import org.eclipse.swt.layout.GridLayout; 44 import org.eclipse.swt.widgets.Composite; 45 import org.eclipse.swt.widgets.Display; 46 import org.eclipse.swt.widgets.Event; 47 import org.eclipse.swt.widgets.Listener; 48 import org.eclipse.swt.widgets.Shell; 49 import org.eclipse.swt.widgets.Table; 50 import org.eclipse.swt.widgets.TableItem; 51 import org.eclipse.swt.widgets.Text; 52 import org.eclipse.swt.widgets.ToolBar; 53 import org.eclipse.ui.internal.WorkbenchMessages; 54 import org.eclipse.ui.internal.WorkbenchPlugin; 55 import org.eclipse.ui.internal.dialogs.PatternFilter; 56 import org.eclipse.ui.internal.dialogs.PreferenceNodeFilter; 57 import org.eclipse.ui.progress.WorkbenchJob; 58 59 69 public final class DougsSuperFilteredTableTree extends Composite { 70 71 private static final String CLEAR_ICON = "org.eclipse.ui.internal.dialogs.CLEAR_ICON"; 73 private static final String DCLEAR_ICON = "org.eclipse.ui.internal.dialogs.DCLEAR_ICON"; 75 78 private static final String SEARCHHISTORY = "search"; 80 private String cachedTitle; 81 82 protected Text filterText; 83 84 private ToolBarManager filterToolBar; 85 86 protected String initialText = ""; 88 private PatternFilter patternFilter; 89 90 private PreferenceNodeFilter preferenceFilter; 91 92 95 private Job refreshJob; 96 97 100 private List searchHistory; 101 102 protected TableTreeViewer viewer; 103 104 113 public DougsSuperFilteredTableTree(final Composite parent, final int style) { 114 super(parent, style); 115 116 GridData gridData; 117 118 final Composite treeComposite = new Composite(this, SWT.NONE); 120 GridLayout layout = new GridLayout(2, false); 121 layout.marginHeight = 0; 122 layout.marginWidth = 0; 123 treeComposite.setLayout(layout); 124 treeComposite.setFont(parent.getFont()); 125 gridData = new GridData(); 126 gridData.grabExcessHorizontalSpace = true; 127 gridData.grabExcessVerticalSpace = true; 128 gridData.horizontalAlignment = SWT.FILL; 129 gridData.verticalAlignment = SWT.FILL; 130 treeComposite.setLayoutData(gridData); 131 132 createFilterControl(treeComposite); 134 gridData = new GridData(); 135 gridData.grabExcessHorizontalSpace = true; 136 gridData.horizontalAlignment = SWT.FILL; 137 getFilterControl().setLayoutData(gridData); 138 139 final ToolBar toolBar = new ToolBar(treeComposite, SWT.FLAT 141 | SWT.HORIZONTAL); 142 filterToolBar = new ToolBarManager(toolBar); 143 createClearText(filterToolBar); 144 filterToolBar.update(false); 145 filterToolBar.getControl().setVisible(false); 146 filterToolBar.getControl().setLayoutData(new GridData()); 147 148 viewer = new TableTreeViewer(treeComposite, SWT.SINGLE 150 | SWT.FULL_SELECTION); 151 viewer.getControl().addDisposeListener(new DisposeListener() { 152 157 public void widgetDisposed(DisposeEvent e) { 158 refreshJob.cancel(); 159 160 } 161 }); 162 gridData = new GridData(); 163 gridData.grabExcessHorizontalSpace = true; 164 gridData.grabExcessVerticalSpace = true; 165 gridData.horizontalAlignment = SWT.FILL; 166 gridData.verticalAlignment = SWT.FILL; 167 gridData.horizontalSpan = 2; 168 viewer.getControl().setLayoutData(gridData); 169 170 174 patternFilter = new PatternFilter(); 175 viewer.addFilter(patternFilter); 176 createRefreshJob(); 177 } 178 179 182 protected void clearText() { 183 setFilterText(""); 185 if (preferenceFilter != null) { 186 getViewer().removeFilter(preferenceFilter); 187 preferenceFilter = null; 188 getShell().setText(cachedTitle); 189 } 190 191 textChanged(); 192 } 193 194 199 private void createClearText(ToolBarManager filterToolBar) { 200 201 IAction clearTextAction = new Action("", IAction.AS_PUSH_BUTTON) { 207 public void run() { 208 clearText(); 209 } 210 }; 211 212 clearTextAction 213 .setToolTipText(WorkbenchMessages.FilteredTree_ClearToolTip); 214 clearTextAction.setImageDescriptor(JFaceResources.getImageRegistry() 215 .getDescriptor(CLEAR_ICON)); 216 clearTextAction.setDisabledImageDescriptor(JFaceResources 217 .getImageRegistry().getDescriptor(DCLEAR_ICON)); 218 219 filterToolBar.add(clearTextAction); 220 } 221 222 229 public void createFilterControl(final Composite parent) { 230 filterText = new Text(parent, SWT.DROP_DOWN | SWT.BORDER); 231 filterText.setFont(parent.getFont()); 232 searchHistory = getPreferenceSearchHistory(); 233 234 final Shell shell = new Shell(parent.getShell(), SWT.NO_TRIM); 235 shell 236 .setBackground(parent.getDisplay().getSystemColor( 237 SWT.COLOR_WHITE)); 238 GridLayout shellGL = new GridLayout(); 239 shellGL.marginHeight = 0; 240 shellGL.marginWidth = 0; 241 shell.setLayout(shellGL); 242 shell.setLayoutData(new GridData( 243 (GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL))); 244 245 final Table currentSeachTable = new Table(shell, SWT.SINGLE 246 | SWT.BORDER); 247 currentSeachTable.setLayoutData(new GridData( 248 (GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL))); 249 250 filterText.addTraverseListener(new TraverseListener() { 251 public void keyTraversed(TraverseEvent e) { 252 if (e.detail == SWT.TRAVERSE_RETURN) { 253 e.doit = false; 254 shell.setVisible(false); 255 if (getViewer().getTableTree().getItemCount() == 0) { 256 Display.getCurrent().beep(); 257 setFilterText(""); } else { 259 getViewer().getTableTree().setFocus(); 260 } 261 } 262 } 263 }); 264 265 filterText.addKeyListener(new KeyAdapter() { 266 271 public void keyReleased(KeyEvent e) { 272 273 if (e.keyCode == SWT.ARROW_DOWN) { 274 if (currentSeachTable.isVisible()) { 275 if (currentSeachTable.getSelectionCount() < 1) 277 currentSeachTable.setSelection(0); 278 currentSeachTable.setFocus(); 279 } else 280 getViewer().getTableTree().setFocus(); 282 } else { 283 if (e.character == SWT.CR) 284 return; 285 286 textChanged(); 287 List result = new ArrayList (); 288 result = reduceSearch(searchHistory, filterText.getText()); 289 updateTable(currentSeachTable, result); 290 291 if (currentSeachTable.getItemCount() > 0) { 292 Rectangle textBounds = filterText.getBounds(); 293 Point point = getDisplay().map(parent, null, 294 textBounds.x, textBounds.y); 295 int space = currentSeachTable.getItemHeight(); 296 shell.setBounds(point.x, point.y + textBounds.height, 297 textBounds.width, currentSeachTable 298 .getItemHeight() 299 * currentSeachTable.getItemCount() 300 + space); 301 302 if (shell.isDisposed()) 303 shell.open(); 304 305 if (!shell.getVisible()) { 306 shell.setVisible(true); 307 filterText.setFocus(); 308 } 309 310 } else 311 shell.setVisible(false); 312 } 313 314 } 315 }); 316 317 parent.getDisplay().addFilter(SWT.MouseDown, new Listener() { 318 323 public void handleEvent(Event event) { 324 if (!shell.isDisposed()) 325 shell.setVisible(false); 326 } 327 }); 328 329 getShell().addControlListener(new ControlAdapter() { 330 335 public void controlMoved(ControlEvent e) { 336 shell.setVisible(false); 337 } 338 }); 339 340 currentSeachTable.addSelectionListener(new SelectionAdapter() { 341 public void widgetDefaultSelected(SelectionEvent e) { 342 shell.setVisible(false); 343 } 344 345 350 public void widgetSelected(SelectionEvent e) { 351 352 setFilterText(currentSeachTable.getSelection()[0].getText()); 353 textChanged(); 354 } 355 }); 356 357 filterText.addDisposeListener(new DisposeListener() { 358 363 public void widgetDisposed(DisposeEvent e) { 364 saveDialogSettings(); 365 } 366 }); 367 368 filterText.getAccessible().addAccessibleListener( 369 getAccessibleListener()); 370 371 } 372 373 377 private void createRefreshJob() { 378 refreshJob = new WorkbenchJob("Refresh Filter") { 384 public IStatus runInUIThread(IProgressMonitor monitor) { 385 if (getViewer().getControl().isDisposed()) 386 return Status.CANCEL_STATUS; 387 388 String filterText = getFilterText(); 389 boolean initial = initialText != null 390 && filterText.equals(initialText); 391 if (initial) { 392 patternFilter.setPattern(null); 393 } else { 394 patternFilter.setPattern(getFilterText()); 395 } 396 getViewer().getControl().setRedraw(false); 397 getViewer().refresh(true); 398 getViewer().getControl().setRedraw(true); 399 400 if (filterText.length() > 0 && !initial) { 401 getViewer().expandAll(); 402 filterToolBar.getControl().setVisible(true); 405 } else { 406 filterToolBar.getControl().setVisible( 409 preferenceFilter != null); 410 } 411 return Status.OK_STATUS; 412 } 413 414 }; 415 refreshJob.setSystem(true); 416 } 417 418 protected AccessibleAdapter getAccessibleListener() { 419 return new AccessibleAdapter() { 420 425 public void getName(AccessibleEvent e) { 426 String filterTextString = getFilterText(); 427 if (filterTextString.length() == 0) { 428 e.result = initialText; 429 } else 430 e.result = filterTextString; 431 } 432 433 }; 434 } 435 436 441 private final IDialogSettings getDialogSettings() { 442 final IDialogSettings settings = WorkbenchPlugin.getDefault() 443 .getDialogSettings(); 444 IDialogSettings thisSettings = settings 445 .getSection(getClass().getName()); 446 if (thisSettings == null) 447 thisSettings = settings.addNewSection(getClass().getName()); 448 449 return thisSettings; 450 } 451 452 457 public Text getFilterControl() { 458 return filterText; 459 } 460 461 466 protected String getFilterText() { 467 return filterText.getText(); 468 } 469 470 476 public final List getPreferenceSearchHistory() { 477 final List searchList = new ArrayList (); 478 final IDialogSettings settings = getDialogSettings(); 479 final String [] search = settings.getArray(SEARCHHISTORY); 481 if (search != null) { 482 for (int i = 0; i < search.length; i++) 483 searchList.add(search[i]); 484 } 485 486 return searchList; 487 } 488 489 494 public final TableTreeViewer getViewer() { 495 return viewer; 496 } 497 498 private void listToArray(List list, String [] string) { 499 int size = list.size(); 500 for (int i = 0; i < size; i++) 501 string[i] = (String ) list.get(i); 502 } 503 504 514 public List reduceSearch(List list, String wordsEntered) { 515 List result = new ArrayList (); 516 if (list == null) 517 return result; 518 for (int i = 0; i < list.size(); i++) { 519 if (filterText.getText() == "") return result; 521 else if (((String ) list.get(i)).startsWith(wordsEntered)) 522 result.add(list.get(i)); 523 } 524 525 return result; 526 } 527 528 531 private void saveDialogSettings() { 532 IDialogSettings settings = getDialogSettings(); 533 534 String [] result = new String [searchHistory.size()]; 537 listToArray(searchHistory, result); 538 settings.put(SEARCHHISTORY, result); 539 } 540 541 protected void selectAll() { 542 filterText.selectAll(); 543 } 544 545 550 protected void setFilterText(String string) { 551 filterText.setText(string); 552 selectAll(); 553 } 554 555 558 protected void textChanged() { 559 refreshJob.schedule(200); 560 } 561 562 568 public void updateTable(Table table, List list) { 569 table.removeAll(); 570 if (list.size() > 0) { 571 TableItem newItem; 572 for (int i = 0; i < list.size(); i++) { 573 newItem = new TableItem(table, SWT.NULL, i); 574 newItem.setText((String ) list.get(i)); 575 576 } 577 } 578 579 } 580 } 581 | Popular Tags |