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