// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.gui.dialogs;
import static org.openstreetmap.josm.tools.I18n.tr;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.Optional;
import javax.swing.JList;
import javax.swing.JMenuItem;
import javax.swing.ListCellRenderer;
import org.openstreetmap.josm.Main;
import org.openstreetmap.josm.actions.JosmAction;
import org.openstreetmap.josm.gui.ExtendedDialog;
import org.openstreetmap.josm.gui.MainMenu;
import org.openstreetmap.josm.gui.widgets.SearchTextResultListPanel;
import org.openstreetmap.josm.tools.Shortcut;
public final class MenuItemSearchDialog extends ExtendedDialog {
private final Selector selector;
private static final MenuItemSearchDialog INSTANCE = new MenuItemSearchDialog(Main.main.menu);
private MenuItemSearchDialog(MainMenu menu) {
super(Main.parent, tr("Search menu items"), new String[]{tr("Select"), tr("Cancel")});
this.selector = new Selector(menu);
this.selector.setDblClickListener(e -> buttonAction(0, null));
setContent(selector, false);
setPreferredSize(new Dimension(600, 300));
}
/**
* Returns the unique instance of {@code MenuItemSearchDialog}.
*
* @return the unique instance of {@code MenuItemSearchDialog}.
*/
public static synchronized MenuItemSearchDialog getInstance() {
return INSTANCE;
}
@Override
public ExtendedDialog showDialog() {
selector.init();
super.showDialog();
selector.clearSelection();
return this;
}
@Override
protected void buttonAction(int buttonIndex, ActionEvent evt) {
super.buttonAction(buttonIndex, evt);
if (buttonIndex == 0 && selector.getSelectedItem() != null && selector.getSelectedItem().isEnabled()) {
selector.getSelectedItem().getAction().actionPerformed(evt);
}
}
private static class Selector extends SearchTextResultListPanel<JMenuItem> {
private final MainMenu menu;
Selector(MainMenu menu) {
super();
this.menu = menu;
lsResult.setCellRenderer(new CellRenderer());
}
public JMenuItem getSelectedItem() {
final JMenuItem selected = lsResult.getSelectedValue();
if (selected != null) {
return selected;
} else if (!lsResultModel.isEmpty()) {
return lsResultModel.getElementAt(0);
} else {
return null;
}
}
@Override
protected void filterItems() {
lsResultModel.setItems(menu.findMenuItems(edSearchText.getText(), true));
}
}
private static class CellRenderer implements ListCellRenderer<JMenuItem> {
@Override
public Component getListCellRendererComponent(JList<? extends JMenuItem> list, JMenuItem value, int index,
boolean isSelected, boolean cellHasFocus) {
final JMenuItem item = new JMenuItem(value.getText());
item.setAction(value.getAction());
Optional.ofNullable(value.getAction())
.filter(JosmAction.class::isInstance)
.map(JosmAction.class::cast)
.map(JosmAction::getShortcut)
.map(Shortcut::getKeyStroke)
.ifPresent(item::setAccelerator);
if (isSelected) {
item.setBackground(list.getSelectionBackground());
item.setForeground(list.getSelectionForeground());
} else {
item.setBackground(list.getBackground());
item.setForeground(list.getForeground());
}
return item;
}
}
public static class Action extends JosmAction {
// CHECKSTYLE.OFF: LineLength
/** Action shortcut (ctrl / space by default */
public static final Shortcut SHORTCUT = Shortcut.registerShortcut("help:search-items", "Search menu items", KeyEvent.VK_SPACE, Shortcut.CTRL);
// CHECKSTYLE.ON: LineLength
/**
* Constructs a new {@code Action}.
*/
public Action() {
super(tr("Search menu items"), "dialogs/search", null,
SHORTCUT,
true, "dialogs/search-items", false);
}
@Override
public void actionPerformed(ActionEvent e) {
MenuItemSearchDialog.getInstance().showDialog();
}
}
}