public void calcData(DataKey key, DataSink sink) { if (OpenFileDescriptor.NAVIGATE_IN_EDITOR == key) { sink.put(OpenFileDescriptor.NAVIGATE_IN_EDITOR, myConsoleEditor); return; } else if (getProject().isInitialized()) { FileEditorManager editorManager = FileEditorManager.getInstance(getProject()); final Object o = ((FileEditorManagerImpl) editorManager) .getData(key.getName(), myConsoleEditor, myVirtualFile); sink.put(key, o); } }
@Override public void calcData(final DataKey key, final DataSink sink) { Node node = getSelectedNode(); if (key == PlatformDataKeys.PROJECT) { sink.put(PlatformDataKeys.PROJECT, myProject); } else if (key == USAGE_VIEW_KEY) { sink.put(USAGE_VIEW_KEY, UsageViewImpl.this); } else if (key == PlatformDataKeys.NAVIGATABLE_ARRAY) { sink.put(PlatformDataKeys.NAVIGATABLE_ARRAY, getNavigatablesForNodes(getSelectedNodes())); } else if (key == PlatformDataKeys.EXPORTER_TO_TEXT_FILE) { sink.put(PlatformDataKeys.EXPORTER_TO_TEXT_FILE, myTextFileExporter); } else if (key == USAGES_KEY) { final Set<Usage> selectedUsages = getSelectedUsages(); sink.put( USAGES_KEY, selectedUsages != null ? selectedUsages.toArray(new Usage[selectedUsages.size()]) : null); } else if (key == USAGE_TARGETS_KEY) { sink.put(USAGE_TARGETS_KEY, getSelectedUsageTargets()); } else if (key == PlatformDataKeys.VIRTUAL_FILE_ARRAY) { final Set<Usage> usages = getSelectedUsages(); Usage[] ua = usages != null ? usages.toArray(new Usage[usages.size()]) : null; VirtualFile[] data = UsageDataUtil.provideVirtualFileArray(ua, getSelectedUsageTargets()); sink.put(PlatformDataKeys.VIRTUAL_FILE_ARRAY, data); } else if (key == PlatformDataKeys.HELP_ID) { sink.put(PlatformDataKeys.HELP_ID, HELP_ID); } else if (key == PlatformDataKeys.COPY_PROVIDER) { sink.put(PlatformDataKeys.COPY_PROVIDER, this); } else if (node != null) { Object userObject = node.getUserObject(); if (userObject instanceof TypeSafeDataProvider) { ((TypeSafeDataProvider) userObject).calcData(key, sink); } else if (userObject instanceof DataProvider) { DataProvider dataProvider = (DataProvider) userObject; Object data = dataProvider.getData(key.getName()); if (data != null) { sink.put(key, data); } } } }
public class DomModelTreeView extends Wrapper implements DataProvider, Disposable { public static final DataKey<DomModelTreeView> DATA_KEY = DataKey.create("DOM_MODEL_TREE_VIEW_KEY"); @Deprecated @NonNls public static String DOM_MODEL_TREE_VIEW_KEY = DATA_KEY.getName(); @NonNls public static String DOM_MODEL_TREE_VIEW_POPUP = "DOM_MODEL_TREE_VIEW_POPUP"; private final SimpleTree myTree; private final AbstractTreeBuilder myBuilder; private DomManager myDomManager; @Nullable private DomElement myRootElement; public DomModelTreeView(@NotNull DomElement rootElement) { this(rootElement, rootElement.getManager(), new DomModelTreeStructure(rootElement)); } protected DomModelTreeView( DomElement rootElement, DomManager manager, SimpleTreeStructure treeStructure) { myDomManager = manager; myRootElement = rootElement; myTree = new SimpleTree(new DefaultTreeModel(new DefaultMutableTreeNode())); myTree.setRootVisible(isRootVisible()); myTree.setShowsRootHandles(true); myTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); ToolTipManager.sharedInstance().registerComponent(myTree); TreeUtil.installActions(myTree); myBuilder = new AbstractTreeBuilder( myTree, (DefaultTreeModel) myTree.getModel(), treeStructure, WeightBasedComparator.INSTANCE, false); Disposer.register(this, myBuilder); myBuilder.setNodeDescriptorComparator(null); myBuilder.initRootNode(); add(myTree, BorderLayout.CENTER); myTree.addTreeExpansionListener( new TreeExpansionListener() { @Override public void treeExpanded(TreeExpansionEvent event) { final SimpleNode simpleNode = myTree.getNodeFor(event.getPath()); if (simpleNode instanceof AbstractDomElementNode) { ((AbstractDomElementNode) simpleNode).setExpanded(true); } } @Override public void treeCollapsed(TreeExpansionEvent event) { final SimpleNode simpleNode = myTree.getNodeFor(event.getPath()); if (simpleNode instanceof AbstractDomElementNode) { ((AbstractDomElementNode) simpleNode).setExpanded(false); simpleNode.update(); } } }); myDomManager.addDomEventListener( new DomChangeAdapter() { @Override protected void elementChanged(DomElement element) { if (element.isValid()) { queueUpdate(DomUtil.getFile(element).getVirtualFile()); } else if (element instanceof DomFileElement) { final XmlFile xmlFile = ((DomFileElement) element).getFile(); queueUpdate(xmlFile.getVirtualFile()); } } }, this); final Project project = myDomManager.getProject(); DomElementAnnotationsManager.getInstance(project) .addHighlightingListener( new DomElementAnnotationsManager.DomHighlightingListener() { @Override public void highlightingFinished(@NotNull DomFileElement element) { if (element.isValid()) { queueUpdate(DomUtil.getFile(element).getVirtualFile()); } } }, this); myTree.setPopupGroup(getPopupActions(), DOM_MODEL_TREE_VIEW_POPUP); } protected boolean isRightFile(final VirtualFile file) { return myRootElement == null || (myRootElement.isValid() && file.equals(DomUtil.getFile(myRootElement).getVirtualFile())); } private void queueUpdate(final VirtualFile file) { if (file == null) return; if (getProject().isDisposed()) return; ApplicationManager.getApplication() .invokeLater( () -> { if (getProject().isDisposed()) return; if (!file.isValid() || isRightFile(file)) { myBuilder.updateFromRoot(); } }); } protected boolean isRootVisible() { return true; } public final void updateTree() { myBuilder.updateFromRoot(); } public DomElement getRootElement() { return myRootElement; } protected final Project getProject() { return myDomManager.getProject(); } public AbstractTreeBuilder getBuilder() { return myBuilder; } @Override public void dispose() {} public SimpleTree getTree() { return myTree; } protected ActionGroup getPopupActions() { DefaultActionGroup group = new DefaultActionGroup(); group.add(ActionManager.getInstance().getAction("DomElementsTreeView.TreePopup")); group.addSeparator(); group.add(new ExpandAllAction(myTree)); group.add(new CollapseAllAction(myTree)); return group; } @Override @Nullable public Object getData(String dataId) { if (DATA_KEY.is(dataId)) { return this; } final SimpleNode simpleNode = getTree().getSelectedNode(); if (simpleNode instanceof AbstractDomElementNode) { final DomElement domElement = ((AbstractDomElementNode) simpleNode).getDomElement(); if (domElement != null && domElement.isValid()) { if (CommonDataKeys.NAVIGATABLE.is(dataId)) { final XmlElement tag = domElement.getXmlElement(); if (tag instanceof Navigatable) { return tag; } } } } return null; } public void setSelectedDomElement(final DomElement domElement) { if (domElement == null) return; final SimpleNode node = getNodeFor(domElement); if (node != null) { getTree().setSelectedNode(getBuilder(), node, true); } } @Nullable private SimpleNode getNodeFor(final DomElement domElement) { return visit((SimpleNode) myBuilder.getTreeStructure().getRootElement(), domElement); } @Nullable private SimpleNode visit(SimpleNode simpleNode, DomElement domElement) { boolean validCandidate = false; if (simpleNode instanceof AbstractDomElementNode) { final DomElement nodeElement = ((AbstractDomElementNode) simpleNode).getDomElement(); if (nodeElement != null) { validCandidate = !(simpleNode instanceof DomElementsGroupNode); if (validCandidate && nodeElement.equals(domElement)) { return simpleNode; } if (!(nodeElement instanceof MergedObject) && !isParent(nodeElement, domElement)) { return null; } } } final Object[] childElements = myBuilder.getTreeStructure().getChildElements(simpleNode); if (childElements.length == 0 && validCandidate) { // leaf return simpleNode; } for (Object child : childElements) { SimpleNode result = visit((SimpleNode) child, domElement); if (result != null) { return result; } } return validCandidate ? simpleNode : null; } private static boolean isParent(final DomElement potentialParent, final DomElement domElement) { DomElement currParent = domElement; while (currParent != null) { if (currParent.equals(potentialParent)) return true; currParent = currParent.getParent(); } return false; } }
public class FavoritesTreeViewPanel extends JPanel implements DataProvider { @NonNls public static final String ABSTRACT_TREE_NODE_TRANSFERABLE = "AbstractTransferable"; private final FavoritesTreeStructure myFavoritesTreeStructure; private FavoritesViewTreeBuilder myBuilder; private final CopyPasteDelegator myCopyPasteDelegator; private final MouseListener myTreePopupHandler; public static final DataKey<FavoritesTreeNodeDescriptor[]> CONTEXT_FAVORITES_ROOTS_DATA_KEY = DataKey.create("FavoritesRoot"); @Deprecated public static final String CONTEXT_FAVORITES_ROOTS = CONTEXT_FAVORITES_ROOTS_DATA_KEY.getName(); public static final DataKey<String> FAVORITES_LIST_NAME_DATA_KEY = DataKey.create("FavoritesListName"); @Deprecated public static final String FAVORITES_LIST_NAME = FAVORITES_LIST_NAME_DATA_KEY.getName(); protected Project myProject; private final String myHelpId; protected DnDAwareTree myTree; private final MyDeletePSIElementProvider myDeletePSIElementProvider = new MyDeletePSIElementProvider(); private final ModuleDeleteProvider myDeleteModuleProvider = new ModuleDeleteProvider(); private String myListName; private final IdeView myIdeView = new MyIdeView(); public FavoritesTreeViewPanel(Project project, String helpId, String name) { super(new BorderLayout()); myProject = project; myHelpId = helpId; myListName = name; myFavoritesTreeStructure = new FavoritesTreeStructure(project, myListName); DefaultMutableTreeNode root = new DefaultMutableTreeNode(); root.setUserObject(myFavoritesTreeStructure.getRootElement()); final DefaultTreeModel treeModel = new DefaultTreeModel(root); myTree = new DnDAwareTree(treeModel); myBuilder = new FavoritesViewTreeBuilder( myProject, myTree, treeModel, myFavoritesTreeStructure, myListName); TreeUtil.installActions(myTree); UIUtil.setLineStyleAngled(myTree); myTree.setRootVisible(false); myTree.setShowsRootHandles(true); myTree.setLargeModel(true); new TreeSpeedSearch(myTree); ToolTipManager.sharedInstance().registerComponent(myTree); myTree.setCellRenderer( new NodeRenderer() { public void customizeCellRenderer( JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { super.customizeCellRenderer(tree, value, selected, expanded, leaf, row, hasFocus); if (value instanceof DefaultMutableTreeNode) { final DefaultMutableTreeNode node = (DefaultMutableTreeNode) value; // only favorites roots to explain final Object userObject = node.getUserObject(); if (userObject instanceof FavoritesTreeNodeDescriptor) { final FavoritesTreeNodeDescriptor favoritesTreeNodeDescriptor = (FavoritesTreeNodeDescriptor) userObject; AbstractTreeNode treeNode = favoritesTreeNodeDescriptor.getElement(); final ItemPresentation presentation = treeNode.getPresentation(); String locationString = presentation.getLocationString(); if (locationString != null && locationString.length() > 0) { append(" (" + locationString + ")", SimpleTextAttributes.GRAY_ATTRIBUTES); } else if (node.getParent() != null && node.getParent().getParent() == null) { final String location = favoritesTreeNodeDescriptor.getLocation(); if (location != null && location.length() > 0) { append(" (" + location + ")", SimpleTextAttributes.GRAY_ATTRIBUTES); } } } } } }); JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTree); myTreePopupHandler = CustomizationUtil.installPopupHandler( myTree, IdeActions.GROUP_FAVORITES_VIEW_POPUP, ActionPlaces.FAVORITES_VIEW_POPUP); add(scrollPane, BorderLayout.CENTER); // add(createActionsToolbar(), BorderLayout.NORTH); EditSourceOnDoubleClickHandler.install(myTree); EditSourceOnEnterKeyHandler.install(myTree); myCopyPasteDelegator = new CopyPasteDelegator(myProject, this) { @NotNull protected PsiElement[] getSelectedElements() { return getSelectedPsiElements(); } }; } public void selectElement( final Object selector, final VirtualFile file, final boolean requestFocus) { myBuilder.select(selector, file, requestFocus); } public void dispose() { Disposer.dispose(myBuilder); myBuilder = null; } public DnDAwareTree getTree() { return myTree; } public String getName() { return myListName; } public void setName(String name) { myListName = name; } @NotNull private PsiElement[] getSelectedPsiElements() { final Object[] elements = getSelectedNodeElements(); if (elements == null) { return PsiElement.EMPTY_ARRAY; } ArrayList<PsiElement> result = new ArrayList<PsiElement>(); for (Object element : elements) { if (element instanceof PsiElement) { result.add((PsiElement) element); } else if (element instanceof SmartPsiElementPointer) { PsiElement psiElement = ((SmartPsiElementPointer) element).getElement(); if (psiElement != null) { result.add(psiElement); } } else { for (FavoriteNodeProvider provider : Extensions.getExtensions(FavoriteNodeProvider.EP_NAME, myProject)) { final PsiElement psiElement = provider.getPsiElement(element); if (psiElement != null) { result.add(psiElement); break; } } } } return result.toArray(new PsiElement[result.size()]); } public FavoritesTreeStructure getFavoritesTreeStructure() { return myFavoritesTreeStructure; } public Object getData(String dataId) { if (PlatformDataKeys.PROJECT.is(dataId)) { return myProject; } if (PlatformDataKeys.NAVIGATABLE.is(dataId)) { final FavoritesTreeNodeDescriptor[] selectedNodeDescriptors = getSelectedNodeDescriptors(); return selectedNodeDescriptors.length == 1 ? selectedNodeDescriptors[0].getElement() : null; } if (PlatformDataKeys.NAVIGATABLE_ARRAY.is(dataId)) { final List<Navigatable> selectedElements = getSelectedElements(Navigatable.class); return selectedElements.toArray(new Navigatable[selectedElements.size()]); } if (PlatformDataKeys.CUT_PROVIDER.is(dataId)) { return myCopyPasteDelegator.getCutProvider(); } if (PlatformDataKeys.COPY_PROVIDER.is(dataId)) { return myCopyPasteDelegator.getCopyProvider(); } if (PlatformDataKeys.PASTE_PROVIDER.is(dataId)) { return myCopyPasteDelegator.getPasteProvider(); } if (PlatformDataKeys.HELP_ID.is(dataId)) { return myHelpId; } if (LangDataKeys.PSI_ELEMENT.is(dataId)) { PsiElement[] elements = getSelectedPsiElements(); if (elements.length != 1) { return null; } return elements[0] != null && elements[0].isValid() ? elements[0] : null; } if (LangDataKeys.PSI_ELEMENT_ARRAY.is(dataId)) { final PsiElement[] elements = getSelectedPsiElements(); ArrayList<PsiElement> result = new ArrayList<PsiElement>(); for (PsiElement element : elements) { if (element.isValid()) { result.add(element); } } return result.isEmpty() ? null : result.toArray(new PsiElement[result.size()]); } if (LangDataKeys.IDE_VIEW.is(dataId)) { return myIdeView; } if (LangDataKeys.TARGET_PSI_ELEMENT.is(dataId)) { return null; } if (LangDataKeys.MODULE_CONTEXT.is(dataId)) { Module[] selected = getSelectedModules(); return selected != null && selected.length == 1 ? selected[0] : null; } if (LangDataKeys.MODULE_CONTEXT_ARRAY.is(dataId)) { return getSelectedModules(); } if (PlatformDataKeys.DELETE_ELEMENT_PROVIDER.is(dataId)) { final Object[] elements = getSelectedNodeElements(); return elements != null && elements.length >= 1 && elements[0] instanceof Module ? myDeleteModuleProvider : myDeletePSIElementProvider; } if (ModuleGroup.ARRAY_DATA_KEY.is(dataId)) { final List<ModuleGroup> selectedElements = getSelectedElements(ModuleGroup.class); return selectedElements.isEmpty() ? null : selectedElements.toArray(new ModuleGroup[selectedElements.size()]); } if (LibraryGroupElement.ARRAY_DATA_KEY.is(dataId)) { final List<LibraryGroupElement> selectedElements = getSelectedElements(LibraryGroupElement.class); return selectedElements.isEmpty() ? null : selectedElements.toArray(new LibraryGroupElement[selectedElements.size()]); } if (NamedLibraryElement.ARRAY_DATA_KEY.is(dataId)) { final List<NamedLibraryElement> selectedElements = getSelectedElements(NamedLibraryElement.class); return selectedElements.isEmpty() ? null : selectedElements.toArray(new NamedLibraryElement[selectedElements.size()]); } if (CONTEXT_FAVORITES_ROOTS_DATA_KEY.is(dataId)) { List<FavoritesTreeNodeDescriptor> result = new ArrayList<FavoritesTreeNodeDescriptor>(); FavoritesTreeNodeDescriptor[] selectedNodeDescriptors = getSelectedNodeDescriptors(); for (FavoritesTreeNodeDescriptor selectedNodeDescriptor : selectedNodeDescriptors) { FavoritesTreeNodeDescriptor root = selectedNodeDescriptor.getFavoritesRoot(); if (root != null && !(root.getElement().getValue() instanceof String)) { result.add(root); } } return result.toArray(new FavoritesTreeNodeDescriptor[result.size()]); } if (FAVORITES_LIST_NAME_DATA_KEY.is(dataId)) { return myListName; } FavoritesTreeNodeDescriptor[] descriptors = getSelectedNodeDescriptors(); if (descriptors.length > 0) { List<AbstractTreeNode> nodes = new ArrayList<AbstractTreeNode>(); for (FavoritesTreeNodeDescriptor descriptor : descriptors) { nodes.add(descriptor.getElement()); } return myFavoritesTreeStructure.getDataFromProviders(nodes, dataId); } return null; } private <T> List<T> getSelectedElements(Class<T> klass) { final Object[] elements = getSelectedNodeElements(); ArrayList<T> result = new ArrayList<T>(); if (elements == null) { return result; } for (Object element : elements) { if (element == null) continue; if (klass.isAssignableFrom(element.getClass())) { result.add((T) element); } } return result; } private Module[] getSelectedModules() { final Object[] elements = getSelectedNodeElements(); if (elements == null) { return null; } ArrayList<Module> result = new ArrayList<Module>(); for (Object element : elements) { if (element instanceof Module) { result.add((Module) element); } else if (element instanceof ModuleGroup) { result.addAll(((ModuleGroup) element).modulesInGroup(myProject, true)); } } return result.isEmpty() ? null : result.toArray(new Module[result.size()]); } private Object[] getSelectedNodeElements() { final FavoritesTreeNodeDescriptor[] selectedNodeDescriptors = getSelectedNodeDescriptors(); ArrayList<Object> result = new ArrayList<Object>(); for (FavoritesTreeNodeDescriptor selectedNodeDescriptor : selectedNodeDescriptors) { if (selectedNodeDescriptor != null) { Object value = selectedNodeDescriptor.getElement().getValue(); if (value instanceof SmartPsiElementPointer) { value = ((SmartPsiElementPointer) value).getElement(); } result.add(value); } } return ArrayUtil.toObjectArray(result); } @NotNull public FavoritesTreeNodeDescriptor[] getSelectedNodeDescriptors() { TreePath[] path = myTree.getSelectionPaths(); if (path == null) { return FavoritesTreeNodeDescriptor.EMPTY_ARRAY; } ArrayList<FavoritesTreeNodeDescriptor> result = new ArrayList<FavoritesTreeNodeDescriptor>(); for (TreePath treePath : path) { DefaultMutableTreeNode lastPathNode = (DefaultMutableTreeNode) treePath.getLastPathComponent(); Object userObject = lastPathNode.getUserObject(); if (!(userObject instanceof FavoritesTreeNodeDescriptor)) { continue; } FavoritesTreeNodeDescriptor treeNodeDescriptor = (FavoritesTreeNodeDescriptor) userObject; result.add(treeNodeDescriptor); } return result.toArray(new FavoritesTreeNodeDescriptor[result.size()]); } public static String getQualifiedName(final VirtualFile file) { return file.getPresentableUrl(); } public FavoritesViewTreeBuilder getBuilder() { return myBuilder; } private final class MyDeletePSIElementProvider implements DeleteProvider { public boolean canDeleteElement(DataContext dataContext) { final PsiElement[] elements = getElementsToDelete(); return DeleteHandler.shouldEnableDeleteAction(elements); } public void deleteElement(DataContext dataContext) { List<PsiElement> allElements = Arrays.asList(getElementsToDelete()); List<PsiElement> validElements = new ArrayList<PsiElement>(); for (PsiElement psiElement : allElements) { if (psiElement != null && psiElement.isValid()) validElements.add(psiElement); } final PsiElement[] elements = validElements.toArray(new PsiElement[validElements.size()]); LocalHistoryAction a = LocalHistory.getInstance().startAction(IdeBundle.message("progress.deleting")); try { DeleteHandler.deletePsiElement(elements, myProject); } finally { a.finish(); } } private PsiElement[] getElementsToDelete() { ArrayList<PsiElement> result = new ArrayList<PsiElement>(); Object[] elements = getSelectedNodeElements(); for (int idx = 0; elements != null && idx < elements.length; idx++) { if (elements[idx] instanceof PsiElement) { final PsiElement element = (PsiElement) elements[idx]; result.add(element); if (element instanceof PsiDirectory) { final VirtualFile virtualFile = ((PsiDirectory) element).getVirtualFile(); final String path = virtualFile.getPath(); if (path.endsWith(JarFileSystem.JAR_SEPARATOR)) { // if is jar-file root final VirtualFile vFile = LocalFileSystem.getInstance() .findFileByPath( path.substring(0, path.length() - JarFileSystem.JAR_SEPARATOR.length())); if (vFile != null) { final PsiFile psiFile = PsiManager.getInstance(myProject).findFile(vFile); if (psiFile != null) { elements[idx] = psiFile; } } } } } } return result.toArray(new PsiElement[result.size()]); } } private final class MyIdeView implements IdeView { public void selectElement(final PsiElement element) { if (element != null) { selectPsiElement(element, false); boolean requestFocus = true; final boolean isDirectory = element instanceof PsiDirectory; if (!isDirectory) { Editor editor = EditorHelper.openInEditor(element); if (editor != null) { ToolWindowManager.getInstance(myProject).activateEditorComponent(); requestFocus = false; } } if (requestFocus) { selectPsiElement(element, true); } } } private void selectPsiElement(PsiElement element, boolean requestFocus) { VirtualFile virtualFile = PsiUtilBase.getVirtualFile(element); FavoritesTreeViewPanel.this.selectElement(element, virtualFile, requestFocus); } @Nullable private PsiDirectory[] getSelectedDirectories() { if (myBuilder == null) return null; final Object[] selectedNodeElements = getSelectedNodeElements(); if (selectedNodeElements.length != 1) return null; for (FavoriteNodeProvider nodeProvider : Extensions.getExtensions(FavoriteNodeProvider.EP_NAME, myProject)) { final PsiElement psiElement = nodeProvider.getPsiElement(selectedNodeElements[0]); if (psiElement instanceof PsiDirectory) { return new PsiDirectory[] {(PsiDirectory) psiElement}; } else if (psiElement instanceof PsiDirectoryContainer) { final String moduleName = nodeProvider.getElementModuleName(selectedNodeElements[0]); GlobalSearchScope searchScope = GlobalSearchScope.projectScope(myProject); if (moduleName != null) { final Module module = ModuleManager.getInstance(myProject).findModuleByName(moduleName); if (module != null) { searchScope = GlobalSearchScope.moduleScope(module); } } return ((PsiDirectoryContainer) psiElement).getDirectories(searchScope); } } return selectedNodeElements[0] instanceof PsiDirectory ? new PsiDirectory[] {(PsiDirectory) selectedNodeElements[0]} : null; } public PsiDirectory[] getDirectories() { final PsiDirectory[] directories = getSelectedDirectories(); return directories == null ? PsiDirectory.EMPTY_ARRAY : directories; } public PsiDirectory getOrChooseDirectory() { return DirectoryChooserUtil.getOrChooseDirectory(this); } } }