diff --git a/platform/lang-impl/src/com/intellij/ide/actions/ViewStructureAction.java b/platform/lang-impl/src/com/intellij/ide/actions/ViewStructureAction.java index 07720a7c5028..931db8fa241a 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/ViewStructureAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/ViewStructureAction.java @@ -21,12 +21,14 @@ import com.intellij.ide.structureView.StructureView; import com.intellij.ide.structureView.StructureViewBuilder; import com.intellij.ide.structureView.StructureViewModel; import com.intellij.ide.util.FileStructureDialog; +import com.intellij.ide.util.FileStructurePopup; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.pom.Navigatable; import com.intellij.psi.PsiDocumentManager; @@ -55,13 +57,24 @@ public class ViewStructureAction extends AnAction { FeatureUsageTracker.getInstance().triggerFeatureUsed("navigation.popup.file.structure"); Navigatable navigatable = e.getData(PlatformDataKeys.NAVIGATABLE); - DialogWrapper dialog = createDialog(editor, project, navigatable, fileEditor); - if (dialog != null) { - final VirtualFile virtualFile = psiFile.getVirtualFile(); - if (virtualFile != null) { - dialog.setTitle(virtualFile.getName()); + if (Registry.is("file.structure.tree.mode")) { + FileStructurePopup popup = createPopup(editor, project, navigatable, fileEditor); + if (popup != null) { + final VirtualFile virtualFile = psiFile.getVirtualFile(); + if (virtualFile != null) { + popup.setTitle(virtualFile.getName()); + } + popup.show(); + } + } else { + DialogWrapper dialog = createDialog(editor, project, navigatable, fileEditor); + if (dialog != null) { + final VirtualFile virtualFile = psiFile.getVirtualFile(); + if (virtualFile != null) { + dialog.setTitle(virtualFile.getName()); + } + dialog.show(); } - dialog.show(); } } @@ -72,6 +85,14 @@ public class ViewStructureAction extends AnAction { StructureView structureView = structureViewBuilder.createStructureView(fileEditor, project); return createStructureViewBasedDialog(structureView.getTreeModel(), editor, project, navigatable, structureView); } + + @Nullable + private static FileStructurePopup createPopup(final Editor editor, Project project, Navigatable navigatable, final FileEditor fileEditor) { + final StructureViewBuilder structureViewBuilder = fileEditor.getStructureViewBuilder(); + if (structureViewBuilder == null) return null; + StructureView structureView = structureViewBuilder.createStructureView(fileEditor, project); + return createStructureViewPopup(structureView.getTreeModel(), editor, project, navigatable, structureView); + } public static FileStructureDialog createStructureViewBasedDialog(final StructureViewModel structureViewModel, final Editor editor, @@ -80,7 +101,14 @@ public class ViewStructureAction extends AnAction { final @NotNull Disposable alternativeDisposable) { return new FileStructureDialog(structureViewModel, editor, project, navigatable, alternativeDisposable, true); } - + public static FileStructurePopup createStructureViewPopup(final StructureViewModel structureViewModel, + final Editor editor, + final Project project, + final Navigatable navigatable, + final @NotNull Disposable alternativeDisposable) { + return new FileStructurePopup(structureViewModel, editor, project, navigatable, alternativeDisposable, true); + } + public void update(AnActionEvent event) { Presentation presentation = event.getPresentation(); DataContext dataContext = event.getDataContext(); diff --git a/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureTreeBuilder.java b/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureTreeBuilder.java index 17f9d5b83d1f..1e0f4a6c369d 100644 --- a/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureTreeBuilder.java +++ b/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureTreeBuilder.java @@ -36,7 +36,7 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.tree.DefaultTreeModel; -class StructureTreeBuilder extends AbstractTreeBuilder { +public class StructureTreeBuilder extends AbstractTreeBuilder { private final Project myProject; private final StructureViewModel myStructureModel; diff --git a/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java b/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java index 4edfba6bfad5..ce609a0c88c8 100644 --- a/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java +++ b/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java @@ -733,7 +733,7 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre } //todo [kirillk] dirty hack for discovering invalid psi elements, to delegate it to a proper place after 8.1 - private static boolean isValid(Object treeElement) { + public static boolean isValid(Object treeElement) { if (treeElement instanceof StructureViewTreeElementWrapper) { final StructureViewTreeElementWrapper wrapper = (StructureViewTreeElementWrapper)treeElement; if (wrapper.getValue() instanceof PsiTreeElementBase) { @@ -744,7 +744,7 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre return true; } - static class StructureViewTreeElementWrapper extends TreeElementWrapper implements NodeDescriptorProvidingKey { + public static class StructureViewTreeElementWrapper extends TreeElementWrapper implements NodeDescriptorProvidingKey { private long childrenStamp = -1; private long modificationCountForChildren = ourSettingsModificationCount; diff --git a/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java b/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java new file mode 100644 index 000000000000..b15e84286078 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java @@ -0,0 +1,528 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ide.util; + +import com.intellij.ide.IdeBundle; +import com.intellij.ide.commander.CommanderPanel; +import com.intellij.ide.commander.ProjectListBuilder; +import com.intellij.ide.structureView.StructureViewBuilder; +import com.intellij.ide.structureView.StructureViewModel; +import com.intellij.ide.structureView.StructureViewTreeElement; +import com.intellij.ide.structureView.TreeBasedStructureViewBuilder; +import com.intellij.ide.structureView.newStructureView.StructureTreeBuilder; +import com.intellij.ide.structureView.newStructureView.StructureViewComponent; +import com.intellij.ide.structureView.newStructureView.TreeActionsOwner; +import com.intellij.ide.structureView.newStructureView.TreeModelWrapper; +import com.intellij.ide.util.treeView.AbstractTreeBuilder; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.ide.util.treeView.smartTree.*; +import com.intellij.lang.LanguageStructureViewBuilder; +import com.intellij.openapi.Disposable; +import com.intellij.openapi.MnemonicHelper; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory; +import com.intellij.openapi.keymap.KeymapUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.popup.JBPopup; +import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.util.Ref; +import com.intellij.openapi.wm.IdeFocusManager; +import com.intellij.pom.Navigatable; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.ui.ListScrollingUtil; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.ui.SpeedSearchBase; +import com.intellij.ui.TreeSpeedSearch; +import com.intellij.ui.docking.DockManager; +import com.intellij.ui.speedSearch.SpeedSearchSupply; +import com.intellij.ui.treeStructure.Tree; +import com.intellij.util.ArrayUtil; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.HashSet; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +/** + * @author Konstantin Bulenkov + */ +public class FileStructurePopup implements Disposable { + private final Editor myEditor; + private final Navigatable myNavigatable; + private final Project myProject; + private final StructureViewModel myTreeModel; + private final StructureViewModel myBaseTreeModel; + private final MyTreeActionsOwner myTreeActionsOwner; + private JBPopup myPopup; + + @NonNls private static final String ourPropertyKey = "FileStructure.narrowDown"; + private boolean myShouldNarrowDown = false; + private Tree myTree; + private AbstractTreeBuilder myAbstractTreeBuilder; + private String myTitle; + + public FileStructurePopup(StructureViewModel structureViewModel, + @Nullable Editor editor, + Project project, + Navigatable navigatable, + @NotNull final Disposable auxDisposable, + final boolean applySortAndFilter) { + myProject = project; + myEditor = editor; + myNavigatable = navigatable; + myBaseTreeModel = structureViewModel; + if (applySortAndFilter) { + myTreeActionsOwner = new MyTreeActionsOwner(); + myTreeModel = new TreeModelWrapper(structureViewModel, myTreeActionsOwner); + } + else { + myTreeActionsOwner = null; + myTreeModel = structureViewModel; + } + + PsiFile psiFile = getPsiFile(project); + + final PsiElement psiElement = getCurrentElement(psiFile); + + //myDialog.setUndecorated(true); + + if (psiElement != null) { + if (structureViewModel.shouldEnterElement(psiElement)) { + //myCommanderPanel.getBuilder().enterElement(psiElement, PsiUtilBase.getVirtualFile(psiElement)); + } + else { + //myCommanderPanel.getBuilder().selectElement(psiElement, PsiUtilBase.getVirtualFile(psiElement)); + } + } + + SmartTreeStructure treeStructure = new SmartTreeStructure(project, myTreeModel){ + public void rebuildTree() { + if (!myPopup.isDisposed()) { + super.rebuildTree(); + } + } + + public boolean isToBuildChildrenInBackground(final Object element) { + return getRootElement() == element; + } + + protected TreeElementWrapper createTree() { + return new StructureViewComponent.StructureViewTreeElementWrapper(myProject, myModel.getRoot(), myModel); + } + + @Override + public String toString() { + return "structure view tree structure(model=" + myTreeModel + ")"; + } + }; + + final DefaultTreeModel model = new DefaultTreeModel(new DefaultMutableTreeNode(treeStructure.getRootElement())); + myTree = new Tree(model); + myTree.setRootVisible(false); + myTree.setShowsRootHandles(true); + + myAbstractTreeBuilder = new StructureTreeBuilder(project, myTree, + (DefaultTreeModel)myTree.getModel(),treeStructure, myTreeModel) { + @Override + protected boolean validateNode(Object child) { + return StructureViewComponent.isValid(child); + } + }; + + } + + public void show() { + final JComponent panel = createCenterPanel(); + new MnemonicHelper().register(panel); + myPopup = JBPopupFactory.getInstance().createComponentPopupBuilder(panel, null) + .setTitle(myTitle) + .setResizable(true) + .setFocusable(true) + .setMovable(true) + .setDimensionServiceKey(null, getDimensionServiceKey(), false) + .createPopup(); + myPopup.showInCenterOf(myEditor.getContentComponent()); + new TreeSpeedSearch(myTree, TreeSpeedSearch.NODE_DESCRIPTOR_TOSTRING, true); + myAbstractTreeBuilder.expandAll(new Runnable() { + @Override + public void run() { + IdeFocusManager.getInstance(myProject).requestFocus(myTree, true); + myAbstractTreeBuilder.queueUpdate().doWhenDone(new Runnable() { + @Override + public void run() { + myAbstractTreeBuilder.expandAll(null); + } + }); + } + }); + + } + + protected PsiFile getPsiFile(final Project project) { + return PsiDocumentManager.getInstance(project).getPsiFile(myEditor.getDocument()); + } + + @Nullable + protected Border createContentPaneBorder() { + return null; + } + + public void dispose() { + } + + protected String getDimensionServiceKey() { + return DockManager.getInstance(myProject).getDimensionKeyForFocus("#com.intellij.ide.util.FileStructureDialog"); + } + + @Nullable + protected PsiElement getCurrentElement(@Nullable final PsiFile psiFile) { + if (psiFile == null) return null; + + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + + Object elementAtCursor = myTreeModel.getCurrentEditorElement(); + if (elementAtCursor instanceof PsiElement) { + return (PsiElement)elementAtCursor; + } + + return null; + } + + protected JComponent createCenterPanel() { + List fileStructureFilters = new ArrayList(); + List fileStructureNodeProviders = new ArrayList(); + if (myTreeActionsOwner != null) { + for(Filter filter: myBaseTreeModel.getFilters()) { + if (filter instanceof FileStructureFilter) { + final FileStructureFilter fsFilter = (FileStructureFilter)filter; + myTreeActionsOwner.setActionIncluded(fsFilter, true); + fileStructureFilters.add(fsFilter); + } + } + + if (myBaseTreeModel instanceof ProvidingTreeModel) { + for (NodeProvider provider : ((ProvidingTreeModel)myBaseTreeModel).getNodeProviders()) { + if (provider instanceof FileStructureNodeProvider) { + fileStructureNodeProviders.add((FileStructureNodeProvider)provider); + } + } + } + } + + //new AnAction() { + // public void actionPerformed(AnActionEvent e) { + // final boolean succeeded = myCommanderPanel.navigateSelectedElement(); + // if (succeeded) { + // unregisterCustomShortcutSet(myCommanderPanel); + // } + // } + //}.registerCustomShortcutSet(ActionManager.getInstance().getAction(IdeActions.ACTION_EDIT_SOURCE).getShortcutSet(), myCommanderPanel); + + //myCommanderPanel.setPreferredSize(new Dimension(400, 500)); + + JPanel panel = new JPanel(new BorderLayout()); + JPanel comboPanel = new JPanel(new GridLayout(0, 2, 0, 0)); + + addNarrowDownCheckbox(comboPanel); + + for(FileStructureFilter filter: fileStructureFilters) { + addCheckbox(comboPanel, filter); + } + + for (FileStructureNodeProvider provider : fileStructureNodeProviders) { + addCheckbox(comboPanel, provider); + } + + //myCommanderPanel.setBorder(IdeBorderFactory.createBorder(SideBorder.TOP)); + panel.add(comboPanel, BorderLayout.NORTH); + panel.add(ScrollPaneFactory.createScrollPane(myAbstractTreeBuilder.getTree()), BorderLayout.CENTER); + //new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1, 1, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + + return panel; + } + + protected boolean isShowRoot(final PsiFile psiFile) { + StructureViewBuilder viewBuilder = LanguageStructureViewBuilder.INSTANCE.getStructureViewBuilder(psiFile); + return viewBuilder instanceof TreeBasedStructureViewBuilder && ((TreeBasedStructureViewBuilder)viewBuilder).isRootNodeShown(); + } + + private void addNarrowDownCheckbox(final JPanel panel) { + final JCheckBox checkBox = new JCheckBox(IdeBundle.message("checkbox.narrow.down.the.list.on.typing")); + checkBox.setSelected(PropertiesComponent.getInstance().isTrueValue(ourPropertyKey)); + checkBox.addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + myShouldNarrowDown = checkBox.isSelected(); + PropertiesComponent.getInstance().setValue(ourPropertyKey, Boolean.toString(myShouldNarrowDown)); + + myAbstractTreeBuilder.queueUpdate(); + } + }); + + checkBox.setFocusable(false); + panel.add(checkBox); + //,new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 5, 0, 5), 0, 0)); + } + + private void addCheckbox(final JPanel panel, final TreeAction action) { + String text = action instanceof FileStructureFilter ? ((FileStructureFilter)action).getCheckBoxText() : + action instanceof FileStructureNodeProvider ? ((FileStructureNodeProvider)action).getCheckBoxText() : null; + + if (text == null) return; + + Shortcut[] shortcuts = action instanceof FileStructureFilter ? + ((FileStructureFilter)action).getShortcut() : ((FileStructureNodeProvider)action).getShortcut(); + + + final JCheckBox chkFilter = new JCheckBox(); + chkFilter.addActionListener(new ActionListener() { + public void actionPerformed(final ActionEvent e) { + PsiElement currentParent = null; + final AbstractTreeNode parentNode = null;//todo myAbstractTreeBuilder.getUi().getRootNode().; + final Object value = null; //todo parentNode.getValue(); + if (value instanceof StructureViewTreeElement) { + final Object elementValue = ((StructureViewTreeElement)value).getValue(); + if (elementValue instanceof PsiElement) { + currentParent = (PsiElement) elementValue; + } + } + final boolean state = chkFilter.isSelected(); + myTreeActionsOwner.setActionIncluded(action, action instanceof FileStructureFilter ? !state : state); + myAbstractTreeBuilder.queueUpdate(); + if (currentParent != null) { + boolean oldNarrowDown = myShouldNarrowDown; + myShouldNarrowDown = false; + try { + //todo builder.enterElement(currentParent, PsiUtilBase.getVirtualFile(currentParent)); + } + finally { + myShouldNarrowDown = oldNarrowDown; + } + } + myAbstractTreeBuilder.queueUpdate(); + + if (SpeedSearchBase.hasActiveSpeedSearch(myTree)) { + final SpeedSearchSupply supply = SpeedSearchSupply.getSupply(myTree); + if (supply != null && supply.isPopupActive()) supply.refreshSelection(); + } + } + }); + chkFilter.setFocusable(false); + + if (shortcuts.length > 0) { + text += " (" + KeymapUtil.getShortcutText(shortcuts[0]) + ")"; + new AnAction() { + public void actionPerformed(final AnActionEvent e) { + chkFilter.doClick(); + } + }.registerCustomShortcutSet(new CustomShortcutSet(shortcuts), myTree); + } + chkFilter.setText(text); + panel.add(chkFilter); + //,new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 5, 0, 5), 0, 0)); + } + + @Nullable + protected JComponent createSouthPanel() { + return null; + } + + public void setTitle(String title) { + myTitle = title; + } + + private class MyCommanderPanel extends CommanderPanel implements DataProvider { + @Override + protected boolean shouldDrillDownOnEmptyElement(final AbstractTreeNode node) { + return false; + } + + public MyCommanderPanel(Project _project) { + super(_project, false, true); + myList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + myListSpeedSearch.addChangeListener(new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent evt) { + ProjectListBuilder builder = (ProjectListBuilder)getBuilder(); + if (builder == null) { + return; + } + builder.addUpdateRequest(hasPrefixShortened(evt)); + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + int index = myList.getSelectedIndex(); + if (index != -1 && index < myList.getModel().getSize()) { + myList.clearSelection(); + ListScrollingUtil.selectItem(myList, index); + } + else { + ListScrollingUtil.ensureSelectionExists(myList); + } + } + }); + + myList.repaint(); // to update match highlighting + } + }); + myListSpeedSearch.setComparator(createSpeedSearchComparator()); + } + + private boolean hasPrefixShortened(final PropertyChangeEvent evt) { + return evt.getNewValue() != null && evt.getOldValue() != null && + ((String)evt.getNewValue()).length() < ((String)evt.getOldValue()).length(); + } + + public boolean navigateSelectedElement() { + final Ref succeeded = new Ref(); + final CommandProcessor commandProcessor = CommandProcessor.getInstance(); + commandProcessor.executeCommand(myProject, new Runnable() { + public void run() { + succeeded.set(MyCommanderPanel.super.navigateSelectedElement()); + IdeDocumentHistory.getInstance(myProject).includeCurrentCommandAsNavigation(); + } + }, "Navigate", null); + if (succeeded.get()) { + myPopup.cancel(); + } + return succeeded.get(); + } + + public Object getData(String dataId) { + Object selectedElement = ContainerUtil.getFirstItem(myAbstractTreeBuilder.getSelectedElements()); + + if (selectedElement instanceof TreeElement) selectedElement = ((StructureViewTreeElement)selectedElement).getValue(); + + if (PlatformDataKeys.NAVIGATABLE.is(dataId)) { + return selectedElement instanceof Navigatable ? selectedElement : myNavigatable; + } + + if (OpenFileDescriptor.NAVIGATE_IN_EDITOR.is(dataId)) return myEditor; + + return getDataImpl(dataId); + } + + public String getEnteredPrefix() { + return myListSpeedSearch.getEnteredPrefix(); + } + + public void updateSpeedSearch() { + myListSpeedSearch.refreshSelection(); + } + + public void scrollSelectionInView() { + int selectedIndex = myList.getSelectedIndex(); + if (selectedIndex >= 0) { + ListScrollingUtil.ensureIndexIsVisible(myList, selectedIndex, 0); + } + } + } + + private class MyStructureTreeStructure extends SmartTreeStructure { + public MyStructureTreeStructure(Project project) { + super(project, myTreeModel); + } + + public Object[] getChildElements(Object element) { + Object[] childElements = super.getChildElements(element); + + if (!myShouldNarrowDown) { + return childElements; + } + + String enteredPrefix = null;//todo myCommanderPanel.getEnteredPrefix(); + if (enteredPrefix == null) { + return childElements; + } + + ArrayList filteredElements = new ArrayList(childElements.length); + SpeedSearchBase.SpeedSearchComparator speedSearchComparator = createSpeedSearchComparator(); + + for (Object child : childElements) { + if (child instanceof AbstractTreeNode) { + Object value = ((AbstractTreeNode)child).getValue(); + if (value instanceof TreeElement) { + String name = ((TreeElement)value).getPresentation().getPresentableText(); + if (name == null) { + continue; + } + if (speedSearchComparator.matchingFragments(enteredPrefix, name) == null) { + continue; + } + } + } + filteredElements.add(child); + } + return ArrayUtil.toObjectArray(filteredElements); + } + + public void rebuildTree() { + getChildElements(getRootElement()); // for some reason necessary to rebuild tree correctly + super.rebuildTree(); + } + } + + private static SpeedSearchBase.SpeedSearchComparator createSpeedSearchComparator() { + return new SpeedSearchBase.SpeedSearchComparator(false); + } + + private class MyTreeActionsOwner implements TreeActionsOwner { + private final Set myActions = new HashSet(); + + public void setActionActive(String name, boolean state) { + } + + public boolean isActionActive(String name) { + for (final Sorter sorter : myBaseTreeModel.getSorters()) { + if (sorter.getName().equals(name)) { + if (!sorter.isVisible()) return true; + } + } + for(TreeAction action: myActions) { + if (action.getName().equals(name)) return true; + } + return Sorter.ALPHA_SORTER_ID.equals(name); + } + + public void setActionIncluded(final TreeAction filter, final boolean selected) { + if (selected) { + myActions.add(filter); + } + else { + myActions.remove(filter); + } + } + } + +} diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties index 8e919fa85bad..9aa929eeb832 100644 --- a/platform/platform-resources-en/src/misc/registry.properties +++ b/platform/platform-resources-en/src/misc/registry.properties @@ -169,3 +169,4 @@ show.anonymous.in.structure.view.description=Enables Java anonymous classes in S enable.groovy.hotswap=true enable.groovy.hotswap.description=Whether IDEA should add a special java agent to the debugged process which allows to hot-swap Groovy changes in some cases +file.structure.tree.mode=false