1 /******************************************************************************* 2 * Copyright (c) 2000, 2018 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 * Benjamin Muskalla - bug 105041 14 * Remy Chi Jian Suen - bug 144102 15 * Lars Vogel <Lars.Vogel@gmail.com> - Bug 440810 16 * Andrey Loskutov <loskutov@gmx.de> - generified interface, bug 461762 17 * Mickael Istria (Red Hat Inc.) - Bug 486901 18 *******************************************************************************/ 19 20 package org.eclipse.ui.views.navigator; 21 22 import java.util.ArrayList; 23 import java.util.Arrays; 24 import java.util.Iterator; 25 import java.util.List; 26 import java.util.Objects; 27 28 import org.eclipse.core.resources.IContainer; 29 import org.eclipse.core.resources.IFile; 30 import org.eclipse.core.resources.IMarker; 31 import org.eclipse.core.resources.IResource; 32 import org.eclipse.core.resources.IWorkspace; 33 import org.eclipse.core.resources.ResourcesPlugin; 34 import org.eclipse.core.runtime.Adapters; 35 import org.eclipse.core.runtime.IAdaptable; 36 import org.eclipse.core.runtime.IPath; 37 import org.eclipse.jface.action.IMenuManager; 38 import org.eclipse.jface.action.MenuManager; 39 import org.eclipse.jface.commands.ActionHandler; 40 import org.eclipse.jface.dialogs.IDialogSettings; 41 import org.eclipse.jface.preference.IPreferenceStore; 42 import org.eclipse.jface.util.IPropertyChangeListener; 43 import org.eclipse.jface.viewers.DecoratingLabelProvider; 44 import org.eclipse.jface.viewers.DoubleClickEvent; 45 import org.eclipse.jface.viewers.ILabelDecorator; 46 import org.eclipse.jface.viewers.ILabelProvider; 47 import org.eclipse.jface.viewers.ISelection; 48 import org.eclipse.jface.viewers.IStructuredSelection; 49 import org.eclipse.jface.viewers.OpenEvent; 50 import org.eclipse.jface.viewers.SelectionChangedEvent; 51 import org.eclipse.jface.viewers.StructuredSelection; 52 import org.eclipse.jface.viewers.TreeViewer; 53 import org.eclipse.jface.viewers.ViewerComparator; 54 import org.eclipse.jface.viewers.ViewerSorter; 55 import org.eclipse.osgi.util.NLS; 56 import org.eclipse.swt.SWT; 57 import org.eclipse.swt.dnd.DND; 58 import org.eclipse.swt.dnd.FileTransfer; 59 import org.eclipse.swt.dnd.Transfer; 60 import org.eclipse.swt.events.KeyEvent; 61 import org.eclipse.swt.events.KeyListener; 62 import org.eclipse.swt.widgets.Composite; 63 import org.eclipse.swt.widgets.Control; 64 import org.eclipse.swt.widgets.Listener; 65 import org.eclipse.swt.widgets.Menu; 66 import org.eclipse.swt.widgets.Shell; 67 import org.eclipse.ui.IEditorInput; 68 import org.eclipse.ui.IEditorPart; 69 import org.eclipse.ui.IMemento; 70 import org.eclipse.ui.IPartListener; 71 import org.eclipse.ui.IViewSite; 72 import org.eclipse.ui.IWorkbenchCommandConstants; 73 import org.eclipse.ui.IWorkbenchPage; 74 import org.eclipse.ui.IWorkbenchPart; 75 import org.eclipse.ui.IWorkbenchPreferenceConstants; 76 import org.eclipse.ui.IWorkingSet; 77 import org.eclipse.ui.IWorkingSetManager; 78 import org.eclipse.ui.OpenAndLinkWithEditorHelper; 79 import org.eclipse.ui.PartInitException; 80 import org.eclipse.ui.PlatformUI; 81 import org.eclipse.ui.ResourceWorkingSetFilter; 82 import org.eclipse.ui.actions.ActionContext; 83 import org.eclipse.ui.actions.OpenResourceAction; 84 import org.eclipse.ui.handlers.CollapseAllHandler; 85 import org.eclipse.ui.handlers.IHandlerService; 86 import org.eclipse.ui.ide.ResourceUtil; 87 import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; 88 import org.eclipse.ui.internal.views.helpers.EmptyWorkspaceHelper; 89 import org.eclipse.ui.internal.views.navigator.ResourceNavigatorMessages; 90 import org.eclipse.ui.model.WorkbenchContentProvider; 91 import org.eclipse.ui.model.WorkbenchLabelProvider; 92 import org.eclipse.ui.part.FileEditorInput; 93 import org.eclipse.ui.part.ISetSelectionTarget; 94 import org.eclipse.ui.part.IShowInSource; 95 import org.eclipse.ui.part.IShowInTarget; 96 import org.eclipse.ui.part.PluginTransfer; 97 import org.eclipse.ui.part.ResourceTransfer; 98 import org.eclipse.ui.part.ShowInContext; 99 import org.eclipse.ui.part.ViewPart; 100 import org.eclipse.ui.plugin.AbstractUIPlugin; 101 import org.eclipse.ui.views.framelist.FrameList; 102 import org.eclipse.ui.views.framelist.TreeFrame; 103 104 /** 105 * Implements the Resource Navigator view. 106 * 107 * @noextend This class is not intended to be subclassed by clients. 108 * @noinstantiate This class is not intended to be instantiated by clients. 109 * @noreference This class is not intended to be referenced by clients. 110 * 111 * Planned to be deleted, please see Bug 112 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=549953 113 * 114 * @deprecated as of 3.5, use the Common Navigator Framework classes instead 115 */ 116 @Deprecated 117 public class ResourceNavigator extends ViewPart implements ISetSelectionTarget, IResourceNavigator { 118 119 private TreeViewer viewer; 120 121 private IDialogSettings settings; 122 123 private IMemento memento; 124 125 private FrameList frameList; 126 127 private ResourceNavigatorActionGroup actionGroup; 128 129 private ResourcePatternFilter patternFilter = new ResourcePatternFilter(); 130 131 private ResourceWorkingSetFilter workingSetFilter = new ResourceWorkingSetFilter(); 132 133 private boolean linkingEnabled; 134 135 private boolean dragDetected; 136 137 private Listener dragDetectListener; 138 /** 139 * Remembered working set. 140 */ 141 private IWorkingSet workingSet; 142 143 /** 144 * Marks whether the working set we're using is currently empty. In this event 145 * we're effectively not using a working set. 146 */ 147 private boolean emptyWorkingSet = false; 148 149 /** 150 * Settings constant for section name (value <code>ResourceNavigator</code>). 151 */ 152 private static final String STORE_SECTION = "ResourceNavigator"; //$NON-NLS-1$ 153 154 /** 155 * Settings constant for sort order (value 156 * <code>ResourceViewer.STORE_SORT_TYPE</code>). 157 */ 158 private static final String STORE_SORT_TYPE = "ResourceViewer.STORE_SORT_TYPE"; //$NON-NLS-1$ 159 160 /** 161 * Settings constant for working set (value 162 * <code>ResourceWorkingSetFilter.STORE_WORKING_SET</code>). 163 */ 164 private static final String STORE_WORKING_SET = "ResourceWorkingSetFilter.STORE_WORKING_SET"; //$NON-NLS-1$ 165 166 /** 167 * @deprecated No longer used but preserved to avoid an api change. 168 */ 169 @Deprecated 170 public static final String NAVIGATOR_VIEW_HELP_ID = INavigatorHelpContextIds.RESOURCE_VIEW; 171 172 /** 173 * True iff we've already scheduled an asynchronous call to linkToEditor 174 */ 175 private boolean linkScheduled = false; 176 177 private EmptyWorkspaceHelper emptyWorkspaceHelper; 178 179 // Persistance tags. 180 private static final String TAG_SORTER = "sorter"; //$NON-NLS-1$ 181 182 private static final String TAG_FILTERS = "filters"; //$NON-NLS-1$ 183 184 private static final String TAG_FILTER = "filter"; //$NON-NLS-1$ 185 186 private static final String TAG_SELECTION = "selection"; //$NON-NLS-1$ 187 188 private static final String TAG_EXPANDED = "expanded"; //$NON-NLS-1$ 189 190 private static final String TAG_ELEMENT = "element"; //$NON-NLS-1$ 191 192 private static final String TAG_IS_ENABLED = "isEnabled"; //$NON-NLS-1$ 193 194 private static final String TAG_PATH = "path"; //$NON-NLS-1$ 195 196 private static final String TAG_CURRENT_FRAME = "currentFrame"; //$NON-NLS-1$ 197 198 private IPartListener partListener = new IPartListener() { 199 @Override 200 public void partActivated(IWorkbenchPart part) { 201 if (part instanceof IEditorPart) { 202 editorActivated((IEditorPart) part); 203 } 204 } 205 206 @Override 207 public void partBroughtToTop(IWorkbenchPart part) { 208 if (part instanceof IEditorPart) { 209 editorActivated((IEditorPart) part); 210 } 211 } 212 213 @Override 214 public void partClosed(IWorkbenchPart part) { 215 } 216 217 @Override 218 public void partDeactivated(IWorkbenchPart part) { 219 } 220 221 @Override 222 public void partOpened(IWorkbenchPart part) { 223 } 224 }; 225 226 private IPropertyChangeListener propertyChangeListener = event -> { 227 String property = event.getProperty(); 228 Object newValue = event.getNewValue(); 229 Object oldValue = event.getOldValue(); 230 231 if (IWorkingSetManager.CHANGE_WORKING_SET_REMOVE.equals(property) && oldValue == workingSet) { 232 setWorkingSet(null); 233 } else if (IWorkingSetManager.CHANGE_WORKING_SET_NAME_CHANGE.equals(property) && newValue == workingSet) { 234 updateTitle(); 235 } else if (IWorkingSetManager.CHANGE_WORKING_SET_CONTENT_CHANGE.equals(property) && newValue == workingSet) { 236 if (workingSet.isAggregateWorkingSet() && workingSet.isEmpty()) { 237 // act as if the working set has been made null 238 if (!emptyWorkingSet) { 239 emptyWorkingSet = true; 240 workingSetFilter.setWorkingSet(null); 241 } 242 } else { 243 // we've gone from empty to non-empty on our set. 244 // Restore it. 245 if (emptyWorkingSet) { 246 emptyWorkingSet = false; 247 workingSetFilter.setWorkingSet(workingSet); 248 } 249 } 250 getViewer().refresh(); 251 } 252 }; 253 254 private CollapseAllHandler collapseAllHandler; 255 256 /** 257 * Helper to open and activate editors. 258 * 259 * @since 3.5 260 */ 261 private OpenAndLinkWithEditorHelper openAndLinkWithEditorHelper; 262 263 /** 264 * Constructs a new resource navigator view. 265 */ ResourceNavigator()266 public ResourceNavigator() { 267 IDialogSettings viewsSettings = getPlugin().getDialogSettings(); 268 269 settings = viewsSettings.getSection(STORE_SECTION); 270 if (settings == null) { 271 settings = viewsSettings.addNewSection(STORE_SECTION); 272 } 273 274 initLinkingEnabled(); 275 } 276 277 /** 278 * Converts the given selection into a form usable by the viewer, where the 279 * elements are resources. 280 */ convertSelection(ISelection selection)281 private StructuredSelection convertSelection(ISelection selection) { 282 ArrayList<IResource> list = new ArrayList<>(); 283 if (selection instanceof IStructuredSelection) { 284 IStructuredSelection ssel = (IStructuredSelection) selection; 285 for (Object o : ssel) { 286 IResource resource = Adapters.adapt(o, IResource.class); 287 if (resource != null) { 288 list.add(resource); 289 } 290 } 291 } 292 return new StructuredSelection(list); 293 } 294 295 @Override createPartControl(Composite parent)296 public void createPartControl(Composite parent) { 297 emptyWorkspaceHelper = new EmptyWorkspaceHelper(); 298 Composite displayArea = emptyWorkspaceHelper.getComposite(parent); 299 300 TreeViewer viewer = createViewer(displayArea); 301 this.viewer = viewer; 302 303 emptyWorkspaceHelper.setNonEmptyControl(viewer.getControl()); 304 305 if (memento != null) { 306 restoreFilters(); 307 restoreLinkingEnabled(); 308 } 309 frameList = createFrameList(); 310 initDragAndDrop(); 311 updateTitle(); 312 313 initContextMenu(); 314 315 initResourceComparator(); 316 initWorkingSetFilter(); 317 318 // make sure input is set after sorters and filters, 319 // to avoid unnecessary refreshes 320 viewer.setInput(getInitialInput()); 321 322 // make actions after setting input, because some actions 323 // look at the viewer for enablement (e.g. the Up action) 324 makeActions(); 325 326 // Fill the action bars and update the global action handlers' 327 // enabled state to match the current selection. 328 getActionGroup().fillActionBars(getViewSite().getActionBars()); 329 updateActionBars(viewer.getStructuredSelection()); 330 331 getSite().setSelectionProvider(viewer); 332 getSite().getPage().addPartListener(partListener); 333 IWorkingSetManager workingSetManager = PlatformUI.getWorkbench().getWorkingSetManager(); 334 workingSetManager.addPropertyChangeListener(propertyChangeListener); 335 336 if (memento != null) { 337 restoreState(memento); 338 } 339 memento = null; 340 341 // Set help for the view 342 getSite().getWorkbenchWindow().getWorkbench().getHelpSystem().setHelp(viewer.getControl(), getHelpContextId()); 343 } 344 345 /** 346 * Returns the help context id to use for this view. 347 * 348 * @since 2.0 349 */ getHelpContextId()350 protected String getHelpContextId() { 351 return INavigatorHelpContextIds.RESOURCE_VIEW; 352 } 353 354 /** 355 * Initializes and registers the context menu. 356 * 357 * @since 2.0 358 */ initContextMenu()359 protected void initContextMenu() { 360 MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$ 361 menuMgr.setRemoveAllWhenShown(true); 362 menuMgr.addMenuListener(manager -> ResourceNavigator.this.fillContextMenu(manager)); 363 TreeViewer viewer = getTreeViewer(); 364 Menu menu = menuMgr.createContextMenu(viewer.getTree()); 365 viewer.getTree().setMenu(menu); 366 getSite().registerContextMenu(menuMgr, viewer); 367 } 368 369 /** 370 * Creates the viewer. 371 * 372 * @param parent the parent composite 373 * @since 2.0 374 */ createViewer(Composite parent)375 protected TreeViewer createViewer(Composite parent) { 376 TreeViewer viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); 377 viewer.setUseHashlookup(true); 378 initContentProvider(viewer); 379 initLabelProvider(viewer); 380 initFilters(viewer); 381 initListeners(viewer); 382 383 return viewer; 384 } 385 386 /** 387 * Sets the content provider for the viewer. 388 * 389 * @param viewer the viewer 390 * @since 2.0 391 */ initContentProvider(TreeViewer viewer)392 protected void initContentProvider(TreeViewer viewer) { 393 viewer.setContentProvider(new WorkbenchContentProvider()); 394 } 395 396 /** 397 * Sets the label provider for the viewer. 398 * 399 * @param viewer the viewer 400 * @since 2.0 401 */ initLabelProvider(TreeViewer viewer)402 protected void initLabelProvider(TreeViewer viewer) { 403 viewer.setLabelProvider(new DecoratingLabelProvider(new WorkbenchLabelProvider(), 404 PlatformUI.getWorkbench().getDecoratorManager().getLabelDecorator())); 405 } 406 407 /** 408 * Adds the filters to the viewer. 409 * 410 * @param viewer the viewer 411 * @since 2.0 412 */ initFilters(TreeViewer viewer)413 protected void initFilters(TreeViewer viewer) { 414 viewer.addFilter(patternFilter); 415 viewer.addFilter(workingSetFilter); 416 } 417 418 /** 419 * Initializes the linking enabled setting from the preference store. 420 */ initLinkingEnabled()421 private void initLinkingEnabled() { 422 // Try the dialog settings first, which remember the last choice. 423 String setting = settings.get(IWorkbenchPreferenceConstants.LINK_NAVIGATOR_TO_EDITOR); 424 if (setting != null) { 425 linkingEnabled = setting.equals("true"); //$NON-NLS-1$ 426 return; 427 } 428 // If not in the dialog settings, check the preference store for the default 429 // setting. 430 // Use the UI plugin's preference store since this is a public preference. 431 linkingEnabled = PlatformUI.getPreferenceStore() 432 .getBoolean(IWorkbenchPreferenceConstants.LINK_NAVIGATOR_TO_EDITOR); 433 } 434 435 /** 436 * Adds the listeners to the viewer. 437 * 438 * @param viewer the viewer 439 * @since 2.0 440 */ initListeners(final TreeViewer viewer)441 protected void initListeners(final TreeViewer viewer) { 442 viewer.addSelectionChangedListener(event -> handleSelectionChanged(event)); 443 viewer.addDoubleClickListener(event -> handleDoubleClick(event)); 444 445 openAndLinkWithEditorHelper = new OpenAndLinkWithEditorHelper(viewer) { 446 @Override 447 protected void activate(ISelection selection) { 448 Object selectedElement = getSingleElement(selection); 449 if (selectedElement instanceof IFile) { 450 IEditorInput input = new FileEditorInput((IFile) selectedElement); 451 final IWorkbenchPage page = getSite().getPage(); 452 IEditorPart editor = page.findEditor(input); 453 if (editor != null) { 454 page.activate(editor); 455 } 456 } 457 458 } 459 460 @Override 461 protected void linkToEditor(ISelection selection) { 462 if (!linkScheduled) { 463 // Ensure that if another selection change arrives while we're waiting for the 464 // *syncExec, 465 // we only do this work once. 466 linkScheduled = true; 467 getSite().getShell().getDisplay().asyncExec(() -> { 468 // There's no telling what might have changed since the syncExec was scheduled. 469 // Check to make sure that the widgets haven't been disposed. 470 linkScheduled = false; 471 472 if (viewer == null || viewer.getControl() == null || viewer.getControl().isDisposed()) { 473 return; 474 } 475 476 if (dragDetected == false) { 477 // only synchronize with editor when the selection is not the result 478 // of a drag. Fixes bug 22274. 479 ResourceNavigator.this.linkToEditor(viewer.getSelection()); 480 } 481 }); 482 } 483 } 484 485 @Override 486 protected void open(ISelection selection, boolean activate) { 487 handleOpen(selection); 488 } 489 490 }; 491 492 viewer.getControl().addKeyListener(new KeyListener() { 493 @Override 494 public void keyPressed(KeyEvent event) { 495 handleKeyPressed(event); 496 } 497 498 @Override 499 public void keyReleased(KeyEvent event) { 500 handleKeyReleased(event); 501 } 502 }); 503 504 openAndLinkWithEditorHelper.setLinkWithEditor(linkingEnabled); 505 } 506 507 @Override dispose()508 public void dispose() { 509 getSite().getPage().removePartListener(partListener); 510 511 IWorkingSetManager workingSetManager = PlatformUI.getWorkbench().getWorkingSetManager(); 512 workingSetManager.removePropertyChangeListener(propertyChangeListener); 513 514 if (collapseAllHandler != null) { 515 collapseAllHandler.dispose(); 516 } 517 518 if (getActionGroup() != null) { 519 getActionGroup().dispose(); 520 } 521 Control control = viewer.getControl(); 522 if (dragDetectListener != null && control != null && control.isDisposed() == false) { 523 control.removeListener(SWT.DragDetect, dragDetectListener); 524 } 525 526 super.dispose(); 527 } 528 529 /** 530 * An editor has been activated. Sets the selection in this navigator to be the 531 * editor's input, if linking is enabled. 532 * 533 * @param editor the active editor 534 * @since 2.0 535 */ editorActivated(IEditorPart editor)536 protected void editorActivated(IEditorPart editor) { 537 if (!isLinkingEnabled()) { 538 return; 539 } 540 541 IFile file = ResourceUtil.getFile(editor.getEditorInput()); 542 if (file != null) { 543 ISelection newSelection = new StructuredSelection(file); 544 if (getTreeViewer().getStructuredSelection().equals(newSelection)) { 545 getTreeViewer().getTree().showSelection(); 546 } else { 547 getTreeViewer().setSelection(newSelection, true); 548 } 549 } 550 } 551 552 /** 553 * Called when the context menu is about to open. Delegates to the action group 554 * using the viewer's selection as the action context. 555 * 556 * @since 2.0 557 */ fillContextMenu(IMenuManager menu)558 protected void fillContextMenu(IMenuManager menu) { 559 IStructuredSelection selection = getViewer().getStructuredSelection(); 560 getActionGroup().setContext(new ActionContext(selection)); 561 getActionGroup().fillContextMenu(menu); 562 } 563 564 @Override getFrameList()565 public FrameList getFrameList() { 566 return frameList; 567 } 568 569 /** 570 * Returns the initial input for the viewer. Tries to convert the page input to 571 * a resource, either directly or via IAdaptable. If the resource is a 572 * container, it uses that. If the resource is a file, it uses its parent 573 * folder. If a resource could not be obtained, it uses the workspace root. 574 * 575 * @since 2.0 576 */ getInitialInput()577 protected IAdaptable getInitialInput() { 578 IResource resource = Adapters.adapt(getSite().getPage().getInput(), IResource.class); 579 if (resource != null) { 580 switch (resource.getType()) { 581 case IResource.FILE: 582 return resource.getParent(); 583 case IResource.FOLDER: 584 case IResource.PROJECT: 585 case IResource.ROOT: 586 return resource; 587 default: 588 // Unknown resource type. Fall through. 589 break; 590 } 591 } 592 return ResourcesPlugin.getWorkspace().getRoot(); 593 } 594 595 /** 596 * Returns the pattern filter for this view. 597 * 598 * @return the pattern filter 599 * @since 2.0 600 */ 601 @Override getPatternFilter()602 public ResourcePatternFilter getPatternFilter() { 603 return this.patternFilter; 604 } 605 606 /** 607 * Returns the working set for this view. 608 * 609 * @return the working set 610 * @since 2.0 611 */ 612 @Override getWorkingSet()613 public IWorkingSet getWorkingSet() { 614 return workingSetFilter.getWorkingSet(); 615 } 616 617 /** 618 * Returns the navigator's plugin. 619 * 620 * @return the UI plugin for this bundle 621 */ getPlugin()622 public AbstractUIPlugin getPlugin() { 623 return IDEWorkbenchPlugin.getDefault(); 624 } 625 626 /** 627 * Return the sorter. If a comparator was set using 628 * {@link #setComparator(ResourceComparator)}, this method will return 629 * <code>null</code>. 630 * 631 * @since 2.0 632 * @deprecated as of 3.3, use {@link ResourceNavigator#getComparator()} 633 */ 634 @Deprecated 635 @Override getSorter()636 public ResourceSorter getSorter() { 637 ViewerSorter sorter = getTreeViewer().getSorter(); 638 if (sorter instanceof ResourceSorter) { 639 return (ResourceSorter) sorter; 640 } 641 return null; 642 } 643 644 /** 645 * Returns the comparator. If a sorter was set using 646 * {@link #setSorter(ResourceSorter)}, this method will return 647 * <code>null</code>. 648 * 649 * @return the <code>ResourceComparator</code> 650 * @since 3.3 651 */ 652 653 @Override getComparator()654 public ResourceComparator getComparator() { 655 ViewerComparator comparator = getTreeViewer().getComparator(); 656 if (comparator instanceof ResourceComparator) { 657 return (ResourceComparator) comparator; 658 } 659 return null; 660 } 661 662 /** 663 * Returns the resource viewer which shows the resource hierarchy. 664 * 665 * @since 2.0 666 */ 667 @Override getViewer()668 public TreeViewer getViewer() { 669 return viewer; 670 } 671 672 /** 673 * Returns the tree viewer which shows the resource hierarchy. 674 * 675 * @return the tree viewer 676 * @since 2.0 677 */ getTreeViewer()678 public TreeViewer getTreeViewer() { 679 return viewer; 680 } 681 682 /** 683 * Returns the shell to use for opening dialogs. Used in this class, and in the 684 * actions. 685 * 686 * @return the shell 687 * @deprecated use getViewSite().getShell() 688 */ 689 @Deprecated getShell()690 public Shell getShell() { 691 return getViewSite().getShell(); 692 } 693 694 /** 695 * Returns the message to show in the status line. 696 * 697 * @param selection the current selection 698 * @return the status line message 699 * @since 2.0 700 */ getStatusLineMessage(IStructuredSelection selection)701 protected String getStatusLineMessage(IStructuredSelection selection) { 702 if (selection.size() == 1) { 703 Object o = selection.getFirstElement(); 704 if (o instanceof IResource) { 705 return ((IResource) o).getFullPath().makeRelative().toString(); 706 } 707 return ResourceNavigatorMessages.ResourceNavigator_oneItemSelected; 708 } 709 if (selection.size() > 1) { 710 return NLS.bind(ResourceNavigatorMessages.ResourceNavigator_statusLine, String.valueOf(selection.size())); 711 } 712 return ""; //$NON-NLS-1$ 713 } 714 715 /** 716 * Returns the name for the given element. Used as the name for the current 717 * frame. 718 */ getFrameName(Object element)719 String getFrameName(Object element) { 720 if (element instanceof IResource) { 721 return ((IResource) element).getName(); 722 } 723 String text = ((ILabelProvider) getTreeViewer().getLabelProvider()).getText(element); 724 if (text == null) { 725 return "";//$NON-NLS-1$ 726 } 727 return text; 728 } 729 730 /** 731 * Returns the tool tip text for the given element. Used as the tool tip text 732 * for the current frame, and for the view title tooltip. 733 */ getFrameToolTipText(Object element)734 String getFrameToolTipText(Object element) { 735 if (element instanceof IResource) { 736 IPath path = ((IResource) element).getFullPath(); 737 if (path.isRoot()) { 738 return ResourceNavigatorMessages.ResourceManager_toolTip; 739 } 740 return path.makeRelative().toString(); 741 } 742 743 String text = ((ILabelProvider) getTreeViewer().getLabelProvider()).getText(element); 744 if (text == null) { 745 return "";//$NON-NLS-1$ 746 } 747 return text; 748 } 749 750 /** 751 * Handles an open event from the viewer. Opens an editor on the selected file. 752 * 753 * @param event the open event 754 * @since 2.0 755 * @deprecated As of 3.5, replaced by {@link #handleOpen(ISelection)} 756 */ 757 @Deprecated handleOpen(OpenEvent event)758 protected void handleOpen(OpenEvent event) { 759 handleOpen(event.getSelection()); 760 } 761 762 /** 763 * Handles an open event from the viewer. Opens an editor on the selected file. 764 * 765 * @param selection the selection 766 * @since 3.5 767 */ handleOpen(ISelection selection)768 protected void handleOpen(ISelection selection) { 769 if (selection instanceof IStructuredSelection) { 770 getActionGroup().runDefaultAction((IStructuredSelection) selection); 771 } 772 } 773 774 /** 775 * Handles a double-click event from the viewer. Expands or collapses a folder 776 * when double-clicked. 777 * 778 * @param event the double-click event 779 * @since 2.0 780 */ handleDoubleClick(DoubleClickEvent event)781 protected void handleDoubleClick(DoubleClickEvent event) { 782 IStructuredSelection selection = (IStructuredSelection) event.getSelection(); 783 Object element = selection.getFirstElement(); 784 785 // 1GBZIA0: ITPUI:WIN2000 - Double-clicking in navigator should expand/collapse 786 // containers 787 TreeViewer viewer = getTreeViewer(); 788 if (viewer.isExpandable(element)) { 789 viewer.setExpandedState(element, !viewer.getExpandedState(element)); 790 } else if (selection.size() == 1 && (element instanceof IResource) 791 && ((IResource) element).getType() == IResource.PROJECT) { 792 OpenResourceAction ora = new OpenResourceAction(getSite()); 793 ora.selectionChanged((IStructuredSelection) viewer.getSelection()); 794 if (ora.isEnabled()) { 795 ora.run(); 796 } 797 } 798 799 } 800 801 /** 802 * Handles a selection changed event from the viewer. Updates the status line 803 * and the action bars, and links to editor (if option enabled). 804 * 805 * @param event the selection event 806 * @since 2.0 807 */ handleSelectionChanged(SelectionChangedEvent event)808 protected void handleSelectionChanged(SelectionChangedEvent event) { 809 final IStructuredSelection sel = event.getStructuredSelection(); 810 updateStatusLine(sel); 811 updateActionBars(sel); 812 dragDetected = false; 813 } 814 815 /** 816 * Handles a key press event from the viewer. Delegates to the action group. 817 * 818 * @param event the key event 819 * @since 2.0 820 */ handleKeyPressed(KeyEvent event)821 protected void handleKeyPressed(KeyEvent event) { 822 getActionGroup().handleKeyPressed(event); 823 } 824 825 /** 826 * Handles a key release in the viewer. Does nothing by default. 827 * 828 * @param event the key event 829 * @since 2.0 830 */ handleKeyReleased(KeyEvent event)831 protected void handleKeyReleased(KeyEvent event) { 832 } 833 834 @Override init(IViewSite site, IMemento memento)835 public void init(IViewSite site, IMemento memento) throws PartInitException { 836 super.init(site, memento); 837 this.memento = memento; 838 } 839 840 /** 841 * Adds drag and drop support to the navigator. 842 * 843 * @since 2.0 844 */ initDragAndDrop()845 protected void initDragAndDrop() { 846 int ops = DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK; 847 Transfer[] transfers = new Transfer[] { LocalSelectionTransfer.getInstance(), ResourceTransfer.getInstance(), 848 FileTransfer.getInstance(), PluginTransfer.getInstance() }; 849 TreeViewer viewer = getTreeViewer(); 850 viewer.addDragSupport(ops, transfers, new NavigatorDragAdapter(viewer)); 851 NavigatorDropAdapter adapter = new NavigatorDropAdapter(viewer); 852 adapter.setFeedbackEnabled(false); 853 viewer.addDropSupport(ops | DND.DROP_DEFAULT, transfers, adapter); 854 dragDetectListener = event -> dragDetected = true; 855 viewer.getControl().addListener(SWT.DragDetect, dragDetectListener); 856 } 857 858 /** 859 * Creates the frame source and frame list, and connects them. 860 * 861 * @since 2.0 862 */ createFrameList()863 protected FrameList createFrameList() { 864 NavigatorFrameSource frameSource = new NavigatorFrameSource(this); 865 FrameList frameList = new FrameList(frameSource); 866 frameSource.connectTo(frameList); 867 return frameList; 868 } 869 870 /** 871 * Initializes the sorter. 872 * 873 * @deprecated as of 3.3, use {@link ResourceNavigator#initResourceComparator()} 874 * instead 875 */ 876 @Deprecated initResourceSorter()877 protected void initResourceSorter() { 878 int sortType = ResourceSorter.NAME; 879 try { 880 int sortInt = 0; 881 if (memento != null) { 882 String sortStr = memento.getString(TAG_SORTER); 883 if (sortStr != null) { 884 sortInt = Integer.parseInt(sortStr); 885 } 886 } else { 887 sortInt = settings.getInt(STORE_SORT_TYPE); 888 } 889 if (sortInt == ResourceSorter.NAME || sortInt == ResourceSorter.TYPE) { 890 sortType = sortInt; 891 } 892 } catch (NumberFormatException e) { 893 } 894 setSorter(new ResourceSorter(sortType)); 895 } 896 897 /** 898 * Initializes the comparator. 899 * 900 * @since 3.3 901 */ initResourceComparator()902 protected void initResourceComparator() { 903 int sortType = ResourceComparator.NAME; 904 try { 905 int sortInt = 0; 906 if (memento != null) { 907 String sortStr = memento.getString(TAG_SORTER); 908 if (sortStr != null) { 909 sortInt = Integer.parseInt(sortStr); 910 } 911 } else { 912 sortInt = settings.getInt(STORE_SORT_TYPE); 913 } 914 if (sortInt == ResourceComparator.NAME || sortInt == ResourceComparator.TYPE) { 915 sortType = sortInt; 916 } 917 } catch (NumberFormatException e) { 918 } 919 setComparator(new ResourceComparator(sortType)); 920 } 921 922 /** 923 * Restores the working set filter from the persistence store. 924 */ initWorkingSetFilter()925 protected void initWorkingSetFilter() { 926 String workingSetName = settings.get(STORE_WORKING_SET); 927 928 IWorkingSet workingSet = null; 929 930 if (workingSetName != null && workingSetName.isEmpty() == false) { 931 IWorkingSetManager workingSetManager = PlatformUI.getWorkbench().getWorkingSetManager(); 932 workingSet = workingSetManager.getWorkingSet(workingSetName); 933 } else if (PlatformUI.getPreferenceStore() 934 .getBoolean(IWorkbenchPreferenceConstants.USE_WINDOW_WORKING_SET_BY_DEFAULT)) { 935 // use the window set by default if the global preference is set 936 workingSet = getSite().getPage().getAggregateWorkingSet(); 937 } 938 939 if (workingSet != null) { 940 // Only initialize filter. Don't set working set into viewer. 941 // Working set is set via WorkingSetFilterActionGroup 942 // during action creation. 943 workingSetFilter.setWorkingSet(workingSet); 944 internalSetWorkingSet(workingSet); 945 } 946 } 947 948 /** 949 * Returns whether the navigator selection automatically tracks the active 950 * editor. 951 * 952 * @return <code>true</code> if linking is enabled, <code>false</code> if not 953 * @since 2.0 (this was protected in 2.0, but was made public in 2.1) 954 */ 955 @Override isLinkingEnabled()956 public boolean isLinkingEnabled() { 957 return linkingEnabled; 958 } 959 960 /** 961 * Brings the corresponding editor to top if the selected resource is open. 962 * 963 * @since 2.0 964 * @deprecated As of 3.5, replaced by {@link #linkToEditor(ISelection)} 965 */ 966 @Deprecated linkToEditor(IStructuredSelection selection)967 protected void linkToEditor(IStructuredSelection selection) { 968 linkToEditor((ISelection) selection); 969 } 970 971 /** 972 * Brings the corresponding editor to top if the selected resource is open. 973 * 974 * @since 3.5 975 */ linkToEditor(ISelection selection)976 protected void linkToEditor(ISelection selection) { 977 978 if (this != this.getSite().getPage().getActivePart()) 979 return; 980 981 Object obj = getSingleElement(selection); 982 if (obj instanceof IFile) { 983 IFile file = (IFile) obj; 984 IWorkbenchPage page = getSite().getPage(); 985 IEditorPart editor = ResourceUtil.findEditor(page, file); 986 if (editor != null) { 987 page.bringToTop(editor); 988 return; 989 } 990 } 991 } 992 993 /** 994 * Creates the action group, which encapsulates all actions for the view. 995 */ makeActions()996 protected void makeActions() { 997 MainActionGroup group = new MainActionGroup(this); 998 setActionGroup(group); 999 1000 IHandlerService service = getSite().getService(IHandlerService.class); 1001 service.activateHandler(IWorkbenchCommandConstants.NAVIGATE_TOGGLE_LINK_WITH_EDITOR, 1002 new ActionHandler(group.toggleLinkingAction)); 1003 collapseAllHandler = new CollapseAllHandler(viewer); 1004 service.activateHandler(CollapseAllHandler.COMMAND_ID, collapseAllHandler); 1005 } 1006 1007 /** 1008 * Restores the saved filter settings. 1009 */ restoreFilters()1010 private void restoreFilters() { 1011 IMemento filtersMem = memento.getChild(TAG_FILTERS); 1012 1013 if (filtersMem != null) { // filters have been defined 1014 IMemento children[] = filtersMem.getChildren(TAG_FILTER); 1015 1016 // check if first element has new tag defined, indicates new version 1017 if (children.length > 0 && children[0].getString(TAG_IS_ENABLED) != null) { 1018 ArrayList<String> selectedFilters = new ArrayList<>(); 1019 ArrayList unSelectedFilters = new ArrayList(); 1020 for (IMemento memento : children) { 1021 if (memento.getString(TAG_IS_ENABLED).equals(String.valueOf(true))) { 1022 selectedFilters.add(memento.getString(TAG_ELEMENT)); 1023 } else { 1024 // enabled == false 1025 unSelectedFilters.add(memento.getString(TAG_ELEMENT)); 1026 } 1027 } 1028 1029 /* 1030 * merge filters from Memento with selected = true filters from plugins ensure 1031 * there are no duplicates & don't override user preferences 1032 */ 1033 List pluginFilters = FiltersContentProvider.getDefaultFilters(); 1034 for (Iterator iter = pluginFilters.iterator(); iter.hasNext();) { 1035 String element = (String) iter.next(); 1036 if (!selectedFilters.contains(element) && !unSelectedFilters.contains(element)) { 1037 selectedFilters.add(element); 1038 } 1039 } 1040 1041 // Convert to an array of Strings 1042 String[] patternArray = new String[selectedFilters.size()]; 1043 selectedFilters.toArray(patternArray); 1044 getPatternFilter().setPatterns(patternArray); 1045 1046 } else { // filters defined, old version: ignore filters from plugins 1047 String filters[] = new String[children.length]; 1048 for (int i = 0; i < children.length; i++) { 1049 filters[i] = children[i].getString(TAG_ELEMENT); 1050 } 1051 getPatternFilter().setPatterns(filters); 1052 } 1053 } else { // no filters defined, old version: ignore filters from plugins 1054 getPatternFilter().setPatterns(new String[0]); 1055 } 1056 } 1057 1058 /** 1059 * Restores the state of the receiver to the state described in the specified 1060 * memento. 1061 * 1062 * @param memento the memento 1063 * @since 2.0 1064 */ restoreState(IMemento memento)1065 protected void restoreState(IMemento memento) { 1066 TreeViewer viewer = getTreeViewer(); 1067 IMemento frameMemento = memento.getChild(TAG_CURRENT_FRAME); 1068 1069 if (frameMemento != null) { 1070 TreeFrame frame = new TreeFrame(viewer); 1071 frame.restoreState(frameMemento); 1072 frame.setName(getFrameName(frame.getInput())); 1073 frame.setToolTipText(getFrameToolTipText(frame.getInput())); 1074 viewer.setSelection(new StructuredSelection(frame.getInput())); 1075 frameList.gotoFrame(frame); 1076 } else { 1077 IContainer container = ResourcesPlugin.getWorkspace().getRoot(); 1078 IMemento childMem = memento.getChild(TAG_EXPANDED); 1079 if (childMem != null) { 1080 ArrayList elements = new ArrayList(); 1081 for (IMemento mem : childMem.getChildren(TAG_ELEMENT)) { 1082 Object element = container.findMember(mem.getString(TAG_PATH)); 1083 if (element != null) { 1084 elements.add(element); 1085 } 1086 } 1087 viewer.setExpandedElements(elements.toArray()); 1088 } 1089 childMem = memento.getChild(TAG_SELECTION); 1090 if (childMem != null) { 1091 ArrayList list = new ArrayList(); 1092 for (IMemento mem : childMem.getChildren(TAG_ELEMENT)) { 1093 Object element = container.findMember(mem.getString(TAG_PATH)); 1094 if (element != null) { 1095 list.add(element); 1096 } 1097 } 1098 viewer.setSelection(new StructuredSelection(list)); 1099 } 1100 } 1101 } 1102 1103 /** 1104 * Restores the linking enabled state. 1105 */ restoreLinkingEnabled()1106 private void restoreLinkingEnabled() { 1107 Integer val = memento.getInteger(IWorkbenchPreferenceConstants.LINK_NAVIGATOR_TO_EDITOR); 1108 if (val != null) { 1109 linkingEnabled = val.intValue() != 0; 1110 } 1111 } 1112 1113 /** 1114 * @see ViewPart#saveState 1115 */ 1116 @Override saveState(IMemento memento)1117 public void saveState(IMemento memento) { 1118 TreeViewer viewer = getTreeViewer(); 1119 if (viewer == null) { 1120 if (this.memento != null) { 1121 memento.putMemento(this.memento); 1122 } 1123 return; 1124 } 1125 1126 // save sorter 1127 if (getComparator() != null) { 1128 memento.putInteger(TAG_SORTER, getComparator().getCriteria()); 1129 } else if (getSorter() != null) { 1130 memento.putInteger(TAG_SORTER, getSorter().getCriteria()); 1131 } 1132 1133 // save filters 1134 String filters[] = getPatternFilter().getPatterns(); 1135 List selectedFilters = Arrays.asList(filters); 1136 List allFilters = FiltersContentProvider.getDefinedFilters(); 1137 IMemento filtersMem = memento.createChild(TAG_FILTERS); 1138 for (Iterator iter = allFilters.iterator(); iter.hasNext();) { 1139 String element = (String) iter.next(); 1140 IMemento child = filtersMem.createChild(TAG_FILTER); 1141 child.putString(TAG_ELEMENT, element); 1142 child.putString(TAG_IS_ENABLED, String.valueOf(selectedFilters.contains(element))); 1143 } 1144 1145 if (frameList.getCurrentIndex() > 0) { 1146 // save frame, it's not the "home"/workspace frame 1147 TreeFrame currentFrame = (TreeFrame) frameList.getCurrentFrame(); 1148 IMemento frameMemento = memento.createChild(TAG_CURRENT_FRAME); 1149 currentFrame.saveState(frameMemento); 1150 } else { 1151 // save visible expanded elements 1152 Object expandedElements[] = viewer.getVisibleExpandedElements(); 1153 if (expandedElements.length > 0) { 1154 IMemento expandedMem = memento.createChild(TAG_EXPANDED); 1155 for (Object expandedElement : expandedElements) { 1156 if (expandedElement instanceof IResource) { 1157 IMemento elementMem = expandedMem.createChild(TAG_ELEMENT); 1158 elementMem.putString(TAG_PATH, ((IResource) expandedElement).getFullPath().toString()); 1159 } 1160 } 1161 } 1162 // save selection 1163 Object elements[] = viewer.getStructuredSelection().toArray(); 1164 if (elements.length > 0) { 1165 IMemento selectionMem = memento.createChild(TAG_SELECTION); 1166 for (Object selectionElement : elements) { 1167 if (selectionElement instanceof IResource) { 1168 IMemento elementMem = selectionMem.createChild(TAG_ELEMENT); 1169 elementMem.putString(TAG_PATH, ((IResource) selectionElement).getFullPath().toString()); 1170 } 1171 } 1172 } 1173 } 1174 1175 saveLinkingEnabled(memento); 1176 } 1177 1178 /** 1179 * Saves the linking enabled state. 1180 */ saveLinkingEnabled(IMemento memento)1181 private void saveLinkingEnabled(IMemento memento) { 1182 memento.putInteger(IWorkbenchPreferenceConstants.LINK_NAVIGATOR_TO_EDITOR, linkingEnabled ? 1 : 0); 1183 } 1184 1185 /** 1186 * Selects and reveals the specified elements. 1187 */ 1188 @Override selectReveal(ISelection selection)1189 public void selectReveal(ISelection selection) { 1190 StructuredSelection ssel = convertSelection(selection); 1191 if (!ssel.isEmpty()) { 1192 getViewer().getControl().setRedraw(false); 1193 getViewer().setSelection(ssel, true); 1194 getViewer().getControl().setRedraw(true); 1195 } 1196 } 1197 1198 /** 1199 * Saves the filters defined as strings in <code>patterns</code> in the 1200 * preference store. 1201 */ 1202 @Override setFiltersPreference(String[] patterns)1203 public void setFiltersPreference(String[] patterns) { 1204 1205 StringBuilder sb = new StringBuilder(); 1206 1207 for (int i = 0; i < patterns.length; i++) { 1208 if (i != 0) { 1209 sb.append(ResourcePatternFilter.COMMA_SEPARATOR); 1210 } 1211 sb.append(patterns[i]); 1212 } 1213 1214 getPlugin().getPreferenceStore().setValue(ResourcePatternFilter.FILTERS_TAG, sb.toString()); 1215 1216 // remove value in old workbench preference store location 1217 IPreferenceStore preferenceStore = IDEWorkbenchPlugin.getDefault().getPreferenceStore(); 1218 String storedPatterns = preferenceStore.getString(ResourcePatternFilter.FILTERS_TAG); 1219 if (storedPatterns.length() > 0) { 1220 preferenceStore.setValue(ResourcePatternFilter.FILTERS_TAG, ""); //$NON-NLS-1$ 1221 } 1222 } 1223 1224 /** 1225 * @see IWorkbenchPart#setFocus() 1226 */ 1227 @Override setFocus()1228 public void setFocus() { 1229 getTreeViewer().getTree().setFocus(); 1230 } 1231 1232 /** 1233 * Note: For experimental use only. Sets the decorator for the navigator. 1234 * <p> 1235 * As of 2.0, this method no longer has any effect. 1236 * </p> 1237 * 1238 * @param decorator a label decorator or <code>null</code> for no decorations. 1239 * @deprecated use the decorators extension point instead; see 1240 * IWorkbench.getDecoratorManager() 1241 */ 1242 @Deprecated setLabelDecorator(ILabelDecorator decorator)1243 public void setLabelDecorator(ILabelDecorator decorator) { 1244 // do nothing 1245 } 1246 1247 /** 1248 * @see IResourceNavigator#setLinkingEnabled(boolean) 1249 * @since 2.1 1250 */ 1251 @Override setLinkingEnabled(boolean enabled)1252 public void setLinkingEnabled(boolean enabled) { 1253 this.linkingEnabled = enabled; 1254 1255 // remember the last setting in the dialog settings 1256 settings.put(IWorkbenchPreferenceConstants.LINK_NAVIGATOR_TO_EDITOR, enabled); 1257 1258 // if turning linking on, update the selection to correspond to the active 1259 // editor 1260 if (enabled) { 1261 IEditorPart editor = getSite().getPage().getActiveEditor(); 1262 if (editor != null) { 1263 editorActivated(editor); 1264 } 1265 } 1266 openAndLinkWithEditorHelper.setLinkWithEditor(enabled); 1267 } 1268 1269 /** 1270 * Sets the resource sorter. 1271 * 1272 * @param sorter the resource sorter 1273 * @since 2.0 1274 * @deprecated as of 3.3, use 1275 * {@link ResourceNavigator#setComparator(ResourceComparator)} 1276 */ 1277 @Deprecated 1278 @Override setSorter(ResourceSorter sorter)1279 public void setSorter(ResourceSorter sorter) { 1280 TreeViewer viewer = getTreeViewer(); 1281 ViewerSorter viewerSorter = viewer.getSorter(); 1282 1283 viewer.getControl().setRedraw(false); 1284 if (viewerSorter == sorter) { 1285 viewer.refresh(); 1286 } else { 1287 viewer.setSorter(sorter); 1288 } 1289 viewer.getControl().setRedraw(true); 1290 settings.put(STORE_SORT_TYPE, sorter.getCriteria()); 1291 1292 // update the sort actions' checked state 1293 updateActionBars((IStructuredSelection) viewer.getSelection()); 1294 } 1295 1296 /** 1297 * Sets the resource comparator 1298 * 1299 * @param comparator the resource comparator 1300 * @since 3.3 1301 */ 1302 @Override setComparator(ResourceComparator comparator)1303 public void setComparator(ResourceComparator comparator) { 1304 TreeViewer viewer = getTreeViewer(); 1305 ViewerComparator viewerComparator = viewer.getComparator(); 1306 1307 viewer.getControl().setRedraw(false); 1308 if (viewerComparator == comparator) { 1309 viewer.refresh(); 1310 } else { 1311 viewer.setComparator(comparator); 1312 } 1313 viewer.getControl().setRedraw(true); 1314 settings.put(STORE_SORT_TYPE, comparator.getCriteria()); 1315 1316 // update the sort actions' checked state 1317 updateActionBars(viewer.getStructuredSelection()); 1318 } 1319 1320 @Override setWorkingSet(IWorkingSet workingSet)1321 public void setWorkingSet(IWorkingSet workingSet) { 1322 TreeViewer treeViewer = getTreeViewer(); 1323 Object[] expanded = treeViewer.getExpandedElements(); 1324 IStructuredSelection structuredSelection = treeViewer.getStructuredSelection(); 1325 1326 boolean refreshNeeded = internalSetWorkingSet(workingSet); 1327 1328 workingSetFilter.setWorkingSet(emptyWorkingSet ? null : workingSet); 1329 if (workingSet != null) { 1330 settings.put(STORE_WORKING_SET, workingSet.getName()); 1331 } else { 1332 settings.put(STORE_WORKING_SET, ""); //$NON-NLS-1$ 1333 } 1334 updateTitle(); 1335 if (refreshNeeded) { 1336 treeViewer.refresh(); 1337 } 1338 treeViewer.setExpandedElements(expanded); 1339 if (structuredSelection.isEmpty() == false) { 1340 treeViewer.reveal(structuredSelection.getFirstElement()); 1341 } 1342 } 1343 1344 /** 1345 * Set the internal working set fields specific to the navigator. 1346 * 1347 * @param workingSet the new working set 1348 * @since 3.2 1349 */ internalSetWorkingSet(IWorkingSet workingSet)1350 private boolean internalSetWorkingSet(IWorkingSet workingSet) { 1351 boolean refreshNeeded = !Objects.equals(this.workingSet, workingSet); 1352 this.workingSet = workingSet; 1353 emptyWorkingSet = workingSet != null && workingSet.isAggregateWorkingSet() && workingSet.isEmpty(); 1354 return refreshNeeded; 1355 } 1356 1357 /** 1358 * Updates the action bar actions. 1359 * 1360 * @param selection the current selection 1361 * @since 2.0 1362 */ updateActionBars(IStructuredSelection selection)1363 protected void updateActionBars(IStructuredSelection selection) { 1364 ResourceNavigatorActionGroup group = getActionGroup(); 1365 if (group != null) { 1366 group.setContext(new ActionContext(selection)); 1367 group.updateActionBars(); 1368 } 1369 } 1370 1371 /** 1372 * Updates the message shown in the status line. 1373 * 1374 * @param selection the current selection 1375 */ updateStatusLine(IStructuredSelection selection)1376 protected void updateStatusLine(IStructuredSelection selection) { 1377 String msg = getStatusLineMessage(selection); 1378 getViewSite().getActionBars().getStatusLineManager().setMessage(msg); 1379 } 1380 1381 /** 1382 * Updates the title text and title tool tip. Called whenever the input of the 1383 * viewer changes. Called whenever the input of the viewer changes. 1384 * 1385 * @since 2.0 1386 */ updateTitle()1387 public void updateTitle() { 1388 Object input = getViewer().getInput(); 1389 IWorkspace workspace = ResourcesPlugin.getWorkspace(); 1390 IWorkingSet workingSet = workingSetFilter.getWorkingSet(); 1391 1392 if (input == null || input.equals(workspace) || input.equals(workspace.getRoot())) { 1393 setContentDescription(""); //$NON-NLS-1$ 1394 if (workingSet != null) { 1395 setTitleToolTip( 1396 NLS.bind(ResourceNavigatorMessages.ResourceNavigator_workingSetToolTip, workingSet.getLabel())); 1397 } else { 1398 setTitleToolTip(""); //$NON-NLS-1$ 1399 } 1400 } else { 1401 ILabelProvider labelProvider = (ILabelProvider) getTreeViewer().getLabelProvider(); 1402 String inputToolTip = getFrameToolTipText(input); 1403 String text = labelProvider.getText(input); 1404 if (text != null) { 1405 setContentDescription(text); 1406 } 1407 if (workingSet != null) { 1408 setTitleToolTip(NLS.bind(ResourceNavigatorMessages.ResourceNavigator_workingSetInputToolTip, 1409 inputToolTip, workingSet.getLabel())); 1410 } else { 1411 setTitleToolTip(inputToolTip); 1412 } 1413 } 1414 } 1415 1416 /** 1417 * Returns the action group. 1418 * 1419 * @return the action group 1420 */ getActionGroup()1421 protected ResourceNavigatorActionGroup getActionGroup() { 1422 return actionGroup; 1423 } 1424 1425 /** 1426 * Sets the action group. 1427 * 1428 * @param actionGroup the action group 1429 */ setActionGroup(ResourceNavigatorActionGroup actionGroup)1430 protected void setActionGroup(ResourceNavigatorActionGroup actionGroup) { 1431 this.actionGroup = actionGroup; 1432 } 1433 1434 @Override getAdapter(Class<T> adapter)1435 public <T> T getAdapter(Class<T> adapter) { 1436 if (adapter == IShowInSource.class) { 1437 return adapter.cast(getShowInSource()); 1438 } 1439 if (adapter == IShowInTarget.class) { 1440 return adapter.cast(getShowInTarget()); 1441 } 1442 return null; 1443 } 1444 1445 /** 1446 * Returns the <code>IShowInSource</code> for this view. 1447 */ getShowInSource()1448 protected IShowInSource getShowInSource() { 1449 return () -> new ShowInContext(getViewer().getInput(), getViewer().getSelection()); 1450 } 1451 1452 /** 1453 * Returns the <code>IShowInTarget</code> for this view. 1454 */ getShowInTarget()1455 protected IShowInTarget getShowInTarget() { 1456 return context -> { 1457 ArrayList<IResource> toSelect = new ArrayList<>(); 1458 ISelection sel = context.getSelection(); 1459 if (sel instanceof IStructuredSelection) { 1460 IStructuredSelection ssel = (IStructuredSelection) sel; 1461 for (Object o1 : ssel) { 1462 1463 IResource resource = Adapters.adapt(o1, IResource.class); 1464 if (resource != null) { 1465 toSelect.add(resource); 1466 } 1467 1468 IMarker marker = Adapters.adapt(o1, IMarker.class); 1469 if (marker != null) { 1470 IResource r2 = marker.getResource(); 1471 if (r2.getType() != IResource.ROOT) { 1472 toSelect.add(r2); 1473 } 1474 } 1475 } 1476 } 1477 if (toSelect.isEmpty()) { 1478 Object input = context.getInput(); 1479 IResource resource = Adapters.adapt(input, IResource.class); 1480 if (resource != null) { 1481 toSelect.add(resource); 1482 } 1483 } 1484 if (!toSelect.isEmpty()) { 1485 selectReveal(new StructuredSelection(toSelect)); 1486 return true; 1487 } 1488 return false; 1489 }; 1490 } 1491 1492 /** 1493 * Returns the selected element if the selection consists of a single element 1494 * only. 1495 * 1496 * @param s the selection 1497 * @return the selected first element or null 1498 * @since 3.5 1499 */ getSingleElement(ISelection s)1500 protected static final Object getSingleElement(ISelection s) { 1501 if (!(s instanceof IStructuredSelection)) 1502 return null; 1503 1504 IStructuredSelection selection = (IStructuredSelection) s; 1505 if (selection.size() != 1) 1506 return null; 1507 1508 return selection.getFirstElement(); 1509 } 1510 1511 } 1512