IDEA-82047 Search action by name in Add Actions to Quick Lists dialog & IDEA-82050 Add action by doubleclick Add Actions to Quick Lists. [reviewed by Konstantin Bulenkov]

This commit is contained in:
Evgeny Zakrevsky
2012-03-21 01:38:33 +04:00
parent ac2eca6b52
commit 9aaa9a6aa3
2 changed files with 239 additions and 30 deletions
@@ -19,41 +19,85 @@
*/
package com.intellij.openapi.keymap.impl.ui;
import com.intellij.ide.CommonActionsManager;
import com.intellij.ide.TreeExpander;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.QuickList;
import com.intellij.openapi.keymap.KeyMapBundle;
import com.intellij.openapi.keymap.Keymap;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.IconLoader;
import com.intellij.packageDependencies.ui.TreeExpansionMonitor;
import com.intellij.ui.DocumentAdapter;
import com.intellij.ui.FilterComponent;
import com.intellij.util.Alarm;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IJSwingUtilities;
import com.intellij.util.ui.FormBuilder;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.tree.TreeUtil;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
public class ChooseActionsDialog extends DialogWrapper {
private final ActionsTree myActionsTree;
private FilterComponent myFilterComponent;
private TreeExpansionMonitor myTreeExpansionMonitor;
private Keymap myKeymap;
private QuickList[] myQuicklists;
private JBPopup myPopup;
public ChooseActionsDialog(Component parent, Keymap keymap, QuickList[] quicklists) {
super(parent, true);
myKeymap = keymap;
myQuicklists = quicklists;
myActionsTree = new ActionsTree();
myActionsTree.reset(keymap, quicklists);
myActionsTree.getTree().getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
myActionsTree.getTree().addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
doOKAction();
}
}
});
myTreeExpansionMonitor = TreeExpansionMonitor.install(myActionsTree.getTree());
setTitle("Add Actions to Quick List");
init();
}
@Override
protected JComponent createNorthPanel() {
return createToolbarPanel();
}
@Override
protected JComponent createCenterPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.add(myActionsTree.getComponent());
panel.setPreferredSize(new Dimension(400, 500));
return panel;
}
public String[] getTreeSelectedActionIds() {
TreePath[] paths = myActionsTree.getTree().getSelectionPaths();
if (paths == null) return ArrayUtil.EMPTY_STRING_ARRAY;
@@ -74,4 +118,160 @@ public class ChooseActionsDialog extends DialogWrapper {
}
return ArrayUtil.toStringArray(actions);
}
private JPanel createToolbarPanel() {
final JPanel panel = new JPanel(new BorderLayout());
DefaultActionGroup group = new DefaultActionGroup();
final JComponent toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, true).getComponent();
final CommonActionsManager commonActionsManager = CommonActionsManager.getInstance();
final TreeExpander treeExpander = new TreeExpander() {
public void expandAll() {
TreeUtil.expandAll(myActionsTree.getTree());
}
public boolean canExpand() {
return true;
}
public void collapseAll() {
TreeUtil.collapseAll(myActionsTree.getTree(), 0);
}
public boolean canCollapse() {
return true;
}
};
group.add(commonActionsManager.createExpandAllAction(treeExpander, myActionsTree.getTree()));
group.add(commonActionsManager.createCollapseAllAction(treeExpander, myActionsTree.getTree()));
panel.add(toolbar, BorderLayout.WEST);
group = new DefaultActionGroup();
final JComponent searchToolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, true).getComponent();
final Alarm alarm = new Alarm();
myFilterComponent = new FilterComponent("KEYMAP_IN_QUICK_LISTS", 5) {
public void filter() {
alarm.cancelAllRequests();
alarm.addRequest(new Runnable() {
public void run() {
if (!myFilterComponent.isShowing()) return;
if (!myTreeExpansionMonitor.isFreeze()) myTreeExpansionMonitor.freeze();
final String filter = getFilter();
myActionsTree.filter(filter, myQuicklists);
final JTree tree = myActionsTree.getTree();
TreeUtil.expandAll(tree);
if (filter == null || filter.length() == 0) {
TreeUtil.collapseAll(tree, 0);
myTreeExpansionMonitor.restore();
}
}
}, 300);
}
};
myFilterComponent.reset();
panel.add(myFilterComponent, BorderLayout.CENTER);
group.add(new AnAction(KeyMapBundle.message("filter.shortcut.action.text"),
KeyMapBundle.message("filter.shortcut.action.text"),
IconLoader.getIcon("/ant/shortcutFilter.png")) {
public void actionPerformed(AnActionEvent e) {
myFilterComponent.reset();
if (myPopup == null || myPopup.getContent() == null) {
myPopup = JBPopupFactory.getInstance().createComponentPopupBuilder(createFilteringPanel(), null)
.setRequestFocus(true)
.setTitle(KeyMapBundle.message("filter.settings.popup.title"))
.setMovable(true)
.createPopup();
}
myPopup.showUnderneathOf(searchToolbar);
}
});
group.add(new AnAction(KeyMapBundle.message("filter.clear.action.text"),
KeyMapBundle.message("filter.clear.action.text"), IconLoader.getIcon("/actions/gc.png")) {
public void actionPerformed(AnActionEvent e) {
myActionsTree.filter(null, myQuicklists); //clear filtering
TreeUtil.collapseAll(myActionsTree.getTree(), 0);
myTreeExpansionMonitor.restore();
}
});
panel.add(searchToolbar, BorderLayout.EAST);
return panel;
}
private void filterTreeByShortcut(final ShortcutTextField firstShortcut,
final JCheckBox enable2Shortcut,
final ShortcutTextField secondShortcut) {
final KeyStroke keyStroke = firstShortcut.getKeyStroke();
if (keyStroke != null) {
if (!myTreeExpansionMonitor.isFreeze()) myTreeExpansionMonitor.freeze();
myActionsTree.filterTree(new KeyboardShortcut(keyStroke, enable2Shortcut.isSelected() ? secondShortcut.getKeyStroke() : null),
myQuicklists);
final JTree tree = myActionsTree.getTree();
TreeUtil.expandAll(tree);
}
}
private JPanel createFilteringPanel() {
myActionsTree.reset(myKeymap, myQuicklists);
final JLabel firstLabel = new JLabel(KeyMapBundle.message("filter.first.stroke.input"));
final JCheckBox enable2Shortcut = new JCheckBox(KeyMapBundle.message("filter.second.stroke.input"));
final ShortcutTextField firstShortcut = new ShortcutTextField();
firstShortcut.setColumns(10);
final ShortcutTextField secondShortcut = new ShortcutTextField();
secondShortcut.setColumns(10);
enable2Shortcut.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
secondShortcut.setEnabled(enable2Shortcut.isSelected());
if (enable2Shortcut.isSelected()) {
secondShortcut.requestFocusInWindow();
}
}
});
firstShortcut.getDocument().addDocumentListener(new DocumentAdapter() {
protected void textChanged(DocumentEvent e) {
filterTreeByShortcut(firstShortcut, enable2Shortcut, secondShortcut);
}
});
secondShortcut.getDocument().addDocumentListener(new DocumentAdapter() {
protected void textChanged(DocumentEvent e) {
filterTreeByShortcut(firstShortcut, enable2Shortcut, secondShortcut);
}
});
IJSwingUtilities.adjustComponentsOnMac(firstLabel, firstShortcut);
JPanel filterComponent = FormBuilder.createFormBuilder()
.addLabeledComponent(firstLabel, firstShortcut, true)
.addComponent(enable2Shortcut)
.setVerticalGap(0)
.setIndent(5)
.addComponent(secondShortcut)
.getPanel();
filterComponent.setBorder(new EmptyBorder(UIUtil.PANEL_SMALL_INSETS));
enable2Shortcut.setSelected(false);
secondShortcut.setEnabled(false);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
firstShortcut.requestFocus();
}
});
return filterComponent;
}
public void dispose() {
super.dispose();
if (myPopup != null && myPopup.isVisible()) {
myPopup.cancel();
}
if (myFilterComponent != null) {
myFilterComponent.dispose();
}
}
}
@@ -50,12 +50,16 @@ import com.intellij.ui.DocumentAdapter;
import com.intellij.ui.FilterComponent;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.util.Alarm;
import com.intellij.util.IJSwingUtilities;
import com.intellij.util.containers.HashMap;
import com.intellij.util.ui.FormBuilder;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.tree.TreeUtil;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import java.awt.*;
import java.awt.event.*;
@@ -119,7 +123,7 @@ public class KeymapPanel extends JPanel implements SearchableConfigurable, Confi
if (shortcuts != null) {
for (Shortcut shortcut : shortcuts) {
impl.removeShortcut(actionId, shortcut);
impl.removeShortcut(actionId, shortcut);
impl.addShortcut(newActionId, shortcut);
}
}
@@ -270,7 +274,7 @@ public class KeymapPanel extends JPanel implements SearchableConfigurable, Confi
importButton.setMargin(insets);
panel.add(importButton,gc);
}
@@ -376,7 +380,7 @@ public class KeymapPanel extends JPanel implements SearchableConfigurable, Confi
};
group.add(commonActionsManager.createExpandAllAction(treeExpander, myActionsTree.getTree()));
group.add(commonActionsManager.createCollapseAllAction(treeExpander, myActionsTree.getTree()));
group.add(new AnAction("Edit Shortcut", "Edit Shortcut", IconLoader.getIcon("/actions/properties.png")) {
{
registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0)), myActionsTree.getTree());
@@ -459,40 +463,45 @@ public class KeymapPanel extends JPanel implements SearchableConfigurable, Confi
private JPanel createFilteringPanel() {
myActionsTree.reset(getSelectedKeymap(), getCurrentQuickListIds());
JPanel filterComponent = new JPanel(new GridBagLayout());
filterComponent.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
final JLabel firstLabel = new JLabel(KeyMapBundle.message("filter.first.stroke.input"));
final JCheckBox enable2Shortcut = new JCheckBox(KeyMapBundle.message("filter.second.stroke.input"));
final ShortcutTextField firstShortcut = new ShortcutTextField();
final ShortcutTextField secondShortcut = new ShortcutTextField();
final JCheckBox enable2Shortcut = new JCheckBox(KeyMapBundle.message("filter.enable.second.stroke.checkbox"));
firstShortcut.getDocument().addDocumentListener(new DocumentAdapter() {
protected void textChanged(DocumentEvent e) {
filterTreeByShortcut(firstShortcut, enable2Shortcut, secondShortcut);
}
});
secondShortcut.getDocument().addDocumentListener(new DocumentAdapter() {
protected void textChanged(DocumentEvent e) {
filterTreeByShortcut(firstShortcut, enable2Shortcut, secondShortcut);
}
});
final JLabel firstLabel = new JLabel(KeyMapBundle.message("filter.first.stroke.input"));
final JLabel secondLabel = new JLabel(KeyMapBundle.message("filter.second.stroke.input"));
filterComponent.add(firstLabel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 2, 1, 1, 0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(5,2,0,0),0,0));
filterComponent.add(firstShortcut, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 2, 1, 1, 0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0,2,0,0),0,0));
enable2Shortcut.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
secondShortcut.setEnabled(enable2Shortcut.isSelected());
secondLabel.setEnabled(enable2Shortcut.isSelected());
if (enable2Shortcut.isSelected()){
secondShortcut.requestFocusInWindow();
}
}
});
filterComponent.add(enable2Shortcut, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 2, 1, 1, 0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0,0,0,0),0,0));
filterComponent.add(secondLabel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 2, 1, 1, 0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0,2,0,0),0,0));
filterComponent.add(secondShortcut, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 2, 1, 1, 0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0,2,0,0),0,0));
firstShortcut.getDocument().addDocumentListener(new DocumentAdapter() {
protected void textChanged(DocumentEvent e) {
filterTreeByShortcut(firstShortcut, enable2Shortcut, secondShortcut);
}
});
secondShortcut.getDocument().addDocumentListener(new DocumentAdapter() {
protected void textChanged(DocumentEvent e) {
filterTreeByShortcut(firstShortcut, enable2Shortcut, secondShortcut);
}
});
IJSwingUtilities.adjustComponentsOnMac(firstLabel, firstShortcut);
JPanel filterComponent = FormBuilder.createFormBuilder()
.addLabeledComponent(firstLabel, firstShortcut, true)
.addComponent(enable2Shortcut)
.setVerticalGap(0)
.setIndent(5)
.addComponent(secondShortcut)
.getPanel();
filterComponent.setBorder(new EmptyBorder(UIUtil.PANEL_SMALL_INSETS));
enable2Shortcut.setSelected(false);
secondLabel.setEnabled(false);
secondShortcut.setEnabled(false);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
@@ -938,7 +947,7 @@ public class KeymapPanel extends JPanel implements SearchableConfigurable, Confi
DefaultActionGroup group = new DefaultActionGroup();
final Shortcut[] shortcuts = mySelectedKeymap.getShortcuts(actionId);
group.add(new AnAction("Add Keyboard Shortcut") {
@Override
public void actionPerformed(AnActionEvent e) {
@@ -953,7 +962,7 @@ public class KeymapPanel extends JPanel implements SearchableConfigurable, Confi
addKeyboardShortcut(firstKeyboard);
}
});
group.add(new AnAction("Add Mouse Shortcut") {
@Override
public void actionPerformed(AnActionEvent e) {
@@ -991,7 +1000,7 @@ public class KeymapPanel extends JPanel implements SearchableConfigurable, Confi
dataContext,
JBPopupFactory.ActionSelectionAid.SPEEDSEARCH,
true);
if (e instanceof MouseEvent) {
popup.show(new RelativePoint((MouseEvent)e));
}