001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.tagging;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.awt.Component;
007import java.awt.MouseInfo;
008import java.awt.Point;
009import java.awt.event.ActionEvent;
010import java.util.ArrayList;
011import java.util.Collections;
012import java.util.List;
013
014import javax.swing.Action;
015import javax.swing.JMenu;
016import javax.swing.JMenuItem;
017import javax.swing.JPopupMenu;
018import javax.swing.JSeparator;
019
020import org.openstreetmap.josm.Main;
021import org.openstreetmap.josm.tools.PresetTextComparator;
022
023public class TaggingPresetMenu extends TaggingPreset {
024    public JMenu menu = null; // set by TaggingPresetPreferences
025    
026    @Override
027    public void setDisplayName() {
028        putValue(Action.NAME, getName());
029        /** Tooltips should be shown for the toolbar buttons, but not in the menu. */
030        putValue(OPTIONAL_TOOLTIP_TEXT, (group != null ?
031                tr("Preset group {1} / {0}", getLocaleName(), group.getName()) :
032                    tr("Preset group {0}", getLocaleName())));
033        putValue("toolbar", "tagginggroup_" + getRawName());
034    }
035
036    private Component copyMenuComponent(Component menuComponent) {
037        if (menuComponent instanceof JMenu) {
038            JMenu menu = (JMenu)menuComponent;
039            JMenu result = new JMenu(menu.getAction());
040            for (Component item:menu.getMenuComponents()) {
041                result.add(copyMenuComponent(item));
042            }
043            result.setText(menu.getText());
044            return result;
045        } else if (menuComponent instanceof JMenuItem) {
046            JMenuItem menuItem = (JMenuItem)menuComponent;
047            JMenuItem result = new JMenuItem(menuItem.getAction());
048            result.setText(menuItem.getText());
049            return result;
050        } else if(menuComponent instanceof JSeparator) {
051            return new JSeparator();
052        } else {
053            return menuComponent;
054        }
055    }
056
057    @Override
058    public void actionPerformed(ActionEvent e) {
059        Object s = e.getSource();
060        if (menu != null && s instanceof Component) {
061            JPopupMenu pm = new JPopupMenu(getName());
062            for (Component c : menu.getMenuComponents()) {
063                pm.add(copyMenuComponent(c));
064            }
065            Point p = MouseInfo.getPointerInfo().getLocation();
066            pm.show(Main.parent, p.x-Main.parent.getX(), p.y-Main.parent.getY());
067        }
068    }
069    
070    /**
071     * Sorts the menu items using the translated item text
072     */
073    public void sortMenu(){
074        TaggingPresetMenu.sortMenu(this.menu);
075    }
076
077    /**
078     * Sorts the menu items using the translated item text
079     */
080    public static void sortMenu(JMenu menu){
081        Component[] items = menu.getMenuComponents();
082        PresetTextComparator comp = new PresetTextComparator();
083        List<JMenuItem> sortarray = new ArrayList<JMenuItem>();
084        int lastSeparator = 0;
085        for (int i = 0; i < items.length; i++) {
086            Object item = items[i];
087            if (item instanceof JMenu){
088                sortMenu((JMenu)item);
089            }
090            if (item instanceof JMenuItem){
091                sortarray.add((JMenuItem)item);
092                if (i == items.length-1){
093                    Collections.sort(sortarray, comp);
094                    int pos = 0;
095                    for (JMenuItem menuItem : sortarray) {
096                        int oldPos;
097                        if (lastSeparator == 0){
098                            oldPos=pos;
099                        } else {
100                            oldPos = pos+lastSeparator+1;
101                        }
102                        menu.add(menuItem, oldPos);
103                        pos++;
104                    }
105                    sortarray = new ArrayList<JMenuItem>();
106                    lastSeparator = 0;
107                }
108            } else if (item instanceof JSeparator){
109                Collections.sort(sortarray, comp);
110                int pos = 0;
111                for (JMenuItem menuItem : sortarray) {
112                    int oldPos;
113                    if(lastSeparator == 0){
114                        oldPos=pos;
115                    }else {
116                        oldPos = pos+lastSeparator+1;
117                    }
118                    menu.add(menuItem, oldPos);
119                    pos++;
120                }
121                sortarray = new ArrayList<JMenuItem>();
122                lastSeparator = i;
123            }
124        }
125    }
126}