1 15 16 package org.eclipse.ant.internal.ui.editor.outline; 17 18 import java.util.List ; 19 20 import org.apache.tools.ant.Target; 21 import org.eclipse.ant.internal.ui.AntUIPlugin; 22 import org.eclipse.ant.internal.ui.IAntUIConstants; 23 import org.eclipse.ant.internal.ui.IAntUIPreferenceConstants; 24 import org.eclipse.ant.internal.ui.editor.AntEditor; 25 import org.eclipse.ant.internal.ui.editor.actions.TogglePresentationAction; 26 import org.eclipse.ant.internal.ui.model.AntElementNode; 27 import org.eclipse.ant.internal.ui.model.AntImportNode; 28 import org.eclipse.ant.internal.ui.model.AntModel; 29 import org.eclipse.ant.internal.ui.model.AntModelChangeEvent; 30 import org.eclipse.ant.internal.ui.model.AntModelContentProvider; 31 import org.eclipse.ant.internal.ui.model.AntModelCore; 32 import org.eclipse.ant.internal.ui.model.AntModelLabelProvider; 33 import org.eclipse.ant.internal.ui.model.AntProjectNode; 34 import org.eclipse.ant.internal.ui.model.AntPropertyNode; 35 import org.eclipse.ant.internal.ui.model.AntTargetNode; 36 import org.eclipse.ant.internal.ui.model.AntTaskNode; 37 import org.eclipse.ant.internal.ui.model.IAntModel; 38 import org.eclipse.ant.internal.ui.model.IAntModelListener; 39 import org.eclipse.ant.internal.ui.views.actions.AntOpenWithMenu; 40 import org.eclipse.core.resources.IFile; 41 import org.eclipse.core.runtime.IAdaptable; 42 import org.eclipse.core.runtime.ListenerList; 43 import org.eclipse.jface.action.IMenuListener; 44 import org.eclipse.jface.action.IMenuManager; 45 import org.eclipse.jface.action.IToolBarManager; 46 import org.eclipse.jface.action.MenuManager; 47 import org.eclipse.jface.action.Separator; 48 import org.eclipse.jface.viewers.ISelection; 49 import org.eclipse.jface.viewers.ISelectionChangedListener; 50 import org.eclipse.jface.viewers.IStructuredSelection; 51 import org.eclipse.jface.viewers.SelectionChangedEvent; 52 import org.eclipse.jface.viewers.StructuredSelection; 53 import org.eclipse.jface.viewers.TreeViewer; 54 import org.eclipse.jface.viewers.Viewer; 55 import org.eclipse.jface.viewers.ViewerComparator; 56 import org.eclipse.jface.viewers.ViewerFilter; 57 import org.eclipse.swt.widgets.Composite; 58 import org.eclipse.swt.widgets.Control; 59 import org.eclipse.swt.widgets.Menu; 60 import org.eclipse.ui.IWorkbenchActionConstants; 61 import org.eclipse.ui.part.IPageSite; 62 import org.eclipse.ui.part.IShowInSource; 63 import org.eclipse.ui.part.ShowInContext; 64 import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds; 65 import org.eclipse.ui.views.contentoutline.ContentOutlinePage; 66 67 70 public class AntEditorContentOutlinePage extends ContentOutlinePage implements IShowInSource, IAdaptable { 71 72 private static final int EXPAND_TO_LEVEL= 2; 73 74 private Menu fMenu; 75 private AntOpenWithMenu fOpenWithMenu; 76 77 private IAntModelListener fListener; 78 private IAntModel fModel; 79 private AntModelCore fCore; 80 private ListenerList fPostSelectionChangedListeners= new ListenerList(); 81 private boolean fIsModelEmpty= true; 82 private boolean fFilterInternalTargets; 83 private boolean fFilterImportedElements; 84 private boolean fFilterProperties; 85 private boolean fFilterTopLevel; 86 private boolean fSort; 87 88 private ViewerComparator fComparator; 89 90 private AntEditor fEditor; 91 92 private TogglePresentationAction fTogglePresentation; 93 94 97 private class AntOutlineFilter extends ViewerFilter { 98 99 public boolean select(Viewer viewer, Object parentElement, Object element) { 100 if (element instanceof AntElementNode) { 101 AntElementNode node = (AntElementNode) element; 102 if (fFilterTopLevel && (node instanceof AntTaskNode && parentElement instanceof AntProjectNode)) { 103 return false; 104 } 105 if (fFilterImportedElements && (node.getImportNode() != null || node.isExternal())) { 106 if (node instanceof AntTargetNode && ((AntTargetNode)node).isDefaultTarget()) { 107 return true; 108 } 109 return false; 110 } 111 if (fFilterInternalTargets && node instanceof AntTargetNode) { 112 Target target= ((AntTargetNode)node).getTarget(); 113 if (target.getDescription() == null && !((AntTargetNode)node).isDefaultTarget()) { 114 return false; 115 } 116 return true; 117 } 118 if (fFilterProperties && node instanceof AntPropertyNode) { 119 return false; 120 } 121 if (!node.isStructuralNode()) { 122 return false; 123 } 124 } 125 return true; 126 } 127 } 128 129 private class AntOutlineComparator extends ViewerComparator { 130 133 public int compare(Viewer viewer, Object e1, Object e2) { 134 if (!(e1 instanceof AntElementNode && e2 instanceof AntElementNode)) { 135 return super.compare(viewer, e1, e2); 136 } 137 String name1= ((AntElementNode) e1).getLabel(); 138 String name2= ((AntElementNode) e2).getLabel(); 139 return getComparator().compare(name1, name2); 140 } 141 } 142 143 148 protected void setFilterInternalTargets(boolean filter) { 149 fFilterInternalTargets= filter; 150 setFilter(filter, IAntUIPreferenceConstants.ANTEDITOR_FILTER_INTERNAL_TARGETS); 151 } 152 153 158 protected void setFilterImportedElements(boolean filter) { 159 fFilterImportedElements= filter; 160 setFilter(filter, IAntUIPreferenceConstants.ANTEDITOR_FILTER_IMPORTED_ELEMENTS); 161 } 162 163 private void setFilter(boolean filter, String name) { 164 if (name != null) { 165 AntUIPlugin.getDefault().getPreferenceStore().setValue(name, filter); 166 } 167 getTreeViewer().refresh(); 169 } 170 171 176 protected void setFilterProperties(boolean filter) { 177 fFilterProperties= filter; 178 setFilter(filter, IAntUIPreferenceConstants.ANTEDITOR_FILTER_PROPERTIES); 179 } 180 181 186 protected void setFilterTopLevel(boolean filter) { 187 fFilterTopLevel= filter; 188 setFilter(filter, IAntUIPreferenceConstants.ANTEDITOR_FILTER_TOP_LEVEL); 189 } 190 191 197 protected boolean filterInternalTargets() { 198 return fFilterInternalTargets; 199 } 200 201 207 protected boolean filterImportedElements() { 208 return fFilterImportedElements; 209 } 210 211 217 protected boolean filterProperties() { 218 return fFilterProperties; 219 } 220 221 227 protected boolean filterTopLevel() { 228 return fFilterTopLevel; 229 } 230 231 236 protected void setSort(boolean sort) { 237 fSort= sort; 238 if (sort) { 239 if (fComparator == null) { 240 fComparator= new AntOutlineComparator(); 241 } 242 getTreeViewer().setComparator(fComparator); 243 } else { 244 getTreeViewer().setComparator(null); 245 } 246 AntUIPlugin.getDefault().getPreferenceStore().setValue(IAntUIPreferenceConstants.ANTEDITOR_SORT, sort); 247 } 248 249 254 protected boolean isSort() { 255 return fSort; 256 } 257 258 261 public AntEditorContentOutlinePage(AntModelCore core, AntEditor editor) { 262 super(); 263 fCore= core; 264 fFilterInternalTargets= AntUIPlugin.getDefault().getPreferenceStore().getBoolean(IAntUIPreferenceConstants.ANTEDITOR_FILTER_INTERNAL_TARGETS); 265 fFilterImportedElements= AntUIPlugin.getDefault().getPreferenceStore().getBoolean(IAntUIPreferenceConstants.ANTEDITOR_FILTER_IMPORTED_ELEMENTS); 266 fFilterProperties= AntUIPlugin.getDefault().getPreferenceStore().getBoolean(IAntUIPreferenceConstants.ANTEDITOR_FILTER_PROPERTIES); 267 fFilterTopLevel= AntUIPlugin.getDefault().getPreferenceStore().getBoolean(IAntUIPreferenceConstants.ANTEDITOR_FILTER_TOP_LEVEL); 268 fSort= AntUIPlugin.getDefault().getPreferenceStore().getBoolean(IAntUIPreferenceConstants.ANTEDITOR_SORT); 269 fEditor= editor; 270 271 fTogglePresentation= new TogglePresentationAction(); 272 fTogglePresentation.setEditor(editor); 273 } 274 275 278 public void dispose() { 279 if (fMenu != null) { 280 fMenu.dispose(); 281 } 282 if (fOpenWithMenu != null) { 283 fOpenWithMenu.dispose(); 284 } 285 if (fListener != null) { 286 fCore.removeAntModelListener(fListener); 287 fListener= null; 288 } 289 fTogglePresentation.setEditor(null); 290 291 super.dispose(); 292 } 293 294 297 public void createControl(Composite parent) { 298 super.createControl(parent); 299 300 TreeViewer viewer = getTreeViewer(); 301 302 viewer.setContentProvider(new AntModelContentProvider()); 303 setSort(fSort); 304 305 viewer.setLabelProvider(new AntModelLabelProvider()); 306 viewer.addFilter(new AntOutlineFilter()); 307 if (fModel != null) { 308 setViewerInput(fModel); 309 } 310 311 MenuManager manager= new MenuManager("#PopUp"); manager.setRemoveAllWhenShown(true); 313 manager.addMenuListener(new IMenuListener() { 314 public void menuAboutToShow(IMenuManager menuManager) { 315 contextMenuAboutToShow(menuManager); 316 } 317 }); 318 fMenu= manager.createContextMenu(viewer.getTree()); 319 viewer.getTree().setMenu(fMenu); 320 321 IPageSite site= getSite(); 322 site.registerContextMenu(IAntUIConstants.PLUGIN_ID + ".antEditorOutline", manager, viewer); 324 IToolBarManager tbm= site.getActionBars().getToolBarManager(); 325 tbm.add(new ToggleSortAntOutlineAction(this)); 326 tbm.add(new FilterInternalTargetsAction(this)); 327 tbm.add(new FilterPropertiesAction(this)); 328 tbm.add(new FilterImportedElementsAction(this)); 329 tbm.add(new FilterTopLevelAction(this)); 330 331 IMenuManager viewMenu= site.getActionBars().getMenuManager(); 332 viewMenu.add(new ToggleLinkWithEditorAction(fEditor)); 333 334 fOpenWithMenu= new AntOpenWithMenu(this.getSite().getPage()); 335 336 viewer.addPostSelectionChangedListener(new ISelectionChangedListener() { 337 public void selectionChanged(SelectionChangedEvent event) { 338 firePostSelectionChanged(event.getSelection()); 339 } 340 }); 341 342 site.getActionBars().setGlobalActionHandler(ITextEditorActionDefinitionIds.TOGGLE_SHOW_SELECTED_ELEMENT_ONLY, fTogglePresentation); 343 } 344 345 private void setViewerInput(Object newInput) { 346 TreeViewer tree= getTreeViewer(); 347 Object oldInput= tree.getInput(); 348 349 boolean isAntModel= (newInput instanceof AntModel); 350 boolean wasAntModel= (oldInput instanceof AntModel); 351 352 if (isAntModel && !wasAntModel) { 353 if (fListener == null) { 354 fListener= createAntModelChangeListener(); 355 } 356 fCore.addAntModelListener(fListener); 357 } else if (!isAntModel && wasAntModel && fListener != null) { 358 fCore.removeAntModelListener(fListener); 359 fListener= null; 360 } 361 362 363 tree.setInput(newInput); 364 365 if (isAntModel) { 366 updateTreeExpansion(); 367 } 368 } 369 370 public void setPageInput(AntModel xmlModel) { 371 fModel= xmlModel; 372 if (getTreeViewer() != null) { 373 setViewerInput(fModel); 374 } 375 } 376 377 private IAntModelListener createAntModelChangeListener() { 378 return new IAntModelListener() { 379 public void antModelChanged(final AntModelChangeEvent event) { 380 if (event.getModel() == fModel && !getControl().isDisposed()) { 381 getControl().getDisplay().asyncExec(new Runnable () { 382 public void run() { 383 Control ctrl= getControl(); 384 if (ctrl != null && !ctrl.isDisposed()) { 385 getTreeViewer().refresh(); 386 updateTreeExpansion(); 387 } 388 } 389 }); 390 } 391 } 392 }; 393 } 394 395 public void addPostSelectionChangedListener(ISelectionChangedListener listener) { 396 fPostSelectionChangedListeners.add(listener); 397 } 398 399 public void removePostSelectionChangedListener(ISelectionChangedListener listener) { 400 fPostSelectionChangedListeners.remove(listener); 401 } 402 403 private void updateTreeExpansion() { 404 boolean wasModelEmpty= fIsModelEmpty; 405 fIsModelEmpty= fModel == null || fModel.getProjectNode() == null; 406 if (wasModelEmpty && !fIsModelEmpty) { 407 getTreeViewer().expandToLevel(EXPAND_TO_LEVEL); 408 } 409 } 410 411 private void firePostSelectionChanged(ISelection selection) { 412 SelectionChangedEvent event= new SelectionChangedEvent(this, selection); 414 415 Object [] listeners= fPostSelectionChangedListeners.getListeners(); 417 for (int i= 0; i < listeners.length; ++i) { 418 ((ISelectionChangedListener) listeners[i]).selectionChanged(event); 419 } 420 } 421 422 private void contextMenuAboutToShow(IMenuManager menuManager) { 423 if (shouldAddOpenWithMenu()) { 424 addOpenWithMenu(menuManager); 425 } 426 menuManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); 427 } 428 429 private void addOpenWithMenu(IMenuManager menuManager) { 430 AntElementNode element= getSelectedNode(); 431 IFile file = null; 432 if (element != null) { 433 file = element.getIFile(); 434 } 435 if (file != null) { 436 menuManager.add(new Separator("group.open")); IMenuManager submenu= new MenuManager(AntOutlineMessages.AntEditorContentOutlinePage_Open_With_1); 438 fOpenWithMenu.setNode(element); 439 submenu.add(fOpenWithMenu); 440 menuManager.appendToGroup("group.open", submenu); } 442 } 443 444 private boolean shouldAddOpenWithMenu() { 445 AntElementNode node= getSelectedNode(); 446 if (node instanceof AntImportNode) { 447 return true; 448 } 449 if (node != null && node.isExternal()) { 450 String path = node.getFilePath(); 451 if (path != null && path.length() > 0) { 452 return true; 453 } 454 } 455 return false; 456 } 457 458 private AntElementNode getSelectedNode() { 459 ISelection iselection= getSelection(); 460 if (iselection instanceof IStructuredSelection) { 461 IStructuredSelection selection= (IStructuredSelection)iselection; 462 if (selection.size() == 1) { 463 Object selected= selection.getFirstElement(); 464 if (selected instanceof AntElementNode) { 465 return (AntElementNode)selected; 466 } 467 } 468 } 469 return null; 470 } 471 472 475 public Object getAdapter(Class key) { 476 if (key == IShowInSource.class) { 477 return this; 478 } 479 return null; 480 } 481 482 485 public ShowInContext getShowInContext() { 486 IFile file= null; 487 if (fModel != null) { 488 AntElementNode node= getSelectedNode(); 489 if (node != null) { 490 file= node.getIFile(); 491 } 492 } 493 if (file != null) { 494 ISelection selection= new StructuredSelection(file); 495 return new ShowInContext(null, selection); 496 } 497 return null; 498 } 499 500 public void select(AntElementNode node) { 501 if (getTreeViewer() != null) { 502 ISelection s= getTreeViewer().getSelection(); 503 if (s instanceof IStructuredSelection) { 504 IStructuredSelection ss= (IStructuredSelection) s; 505 List nodes= ss.toList(); 506 if (!nodes.contains(node)) { 507 s= (node == null ? StructuredSelection.EMPTY : new StructuredSelection(node)); 508 getTreeViewer().setSelection(s, true); 509 } 510 } 511 } 512 } 513 } 514 | Popular Tags |