001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.tagging.presets; 003 004import java.util.ArrayList; 005import java.util.Collection; 006import java.util.HashMap; 007import java.util.Map; 008 009import javax.swing.JMenu; 010import javax.swing.JMenuItem; 011import javax.swing.JSeparator; 012 013import org.openstreetmap.josm.Main; 014import org.openstreetmap.josm.data.osm.OsmPrimitive; 015import org.openstreetmap.josm.gui.MenuScroller; 016import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionManager; 017import org.openstreetmap.josm.tools.Predicate; 018import org.openstreetmap.josm.tools.Utils; 019 020/** 021 * Class holding Tagging Presets and allowing to manage them. 022 * @since 7100 023 */ 024public final class TaggingPresets { 025 026 /** The collection of tagging presets */ 027 private static final Collection<TaggingPreset> taggingPresets = new ArrayList<>(); 028 029 /** The collection of listeners */ 030 private static final Collection<TaggingPresetListener> listeners = new ArrayList<>(); 031 032 private TaggingPresets() { 033 // Hide constructor for utility classes 034 } 035 036 /** 037 * Initializes tagging presets from preferences. 038 */ 039 public static void readFromPreferences() { 040 taggingPresets.clear(); 041 taggingPresets.addAll(TaggingPresetReader.readFromPreferences(false, false)); 042 } 043 044 /** 045 * Initialize the tagging presets (load and may display error) 046 */ 047 public static void initialize() { 048 readFromPreferences(); 049 for (TaggingPreset tp: taggingPresets) { 050 if (!(tp instanceof TaggingPresetSeparator)) { 051 Main.toolbar.register(tp); 052 } 053 } 054 if (taggingPresets.isEmpty()) { 055 Main.main.menu.presetsMenu.setVisible(false); 056 } else { 057 AutoCompletionManager.cachePresets(taggingPresets); 058 Map<TaggingPresetMenu, JMenu> submenus = new HashMap<>(); 059 for (final TaggingPreset p : taggingPresets) { 060 JMenu m = p.group != null ? submenus.get(p.group) : Main.main.menu.presetsMenu; 061 if (m == null && p.group != null) { 062 Main.error("No tagging preset submenu for " + p.group); 063 } else if (m == null) { 064 Main.error("No tagging preset menu. Tagging preset " + p + " won't be available there"); 065 } else if (p instanceof TaggingPresetSeparator) { 066 m.add(new JSeparator()); 067 } else if (p instanceof TaggingPresetMenu) { 068 JMenu submenu = new JMenu(p); 069 submenu.setText(p.getLocaleName()); 070 ((TaggingPresetMenu) p).menu = submenu; 071 submenus.put((TaggingPresetMenu) p, submenu); 072 m.add(submenu); 073 } else { 074 JMenuItem mi = new JMenuItem(p); 075 mi.setText(p.getLocaleName()); 076 m.add(mi); 077 } 078 } 079 for (JMenu submenu : submenus.values()) { 080 if (submenu.getItemCount() >= Main.pref.getInteger("taggingpreset.min-elements-for-scroller", 15)) { 081 MenuScroller.setScrollerFor(submenu); 082 } 083 } 084 } 085 if (Main.pref.getBoolean("taggingpreset.sortmenu")) { 086 TaggingPresetMenu.sortMenu(Main.main.menu.presetsMenu); 087 } 088 } 089 090 /** 091 * Replies a new collection containing all tagging presets. 092 * @return a new collection containing all tagging presets. Empty if presets are not initialized (never null) 093 */ 094 public static Collection<TaggingPreset> getTaggingPresets() { 095 return new ArrayList<>(taggingPresets); 096 } 097 098 /** 099 * Replies a new collection of all presets matching the parameters. 100 * 101 * @param t the preset types to include 102 * @param tags the tags to perform matching on, see {@link TaggingPresetItem#matches(Map)} 103 * @param onlyShowable whether only {@link TaggingPreset#isShowable() showable} presets should be returned 104 * @return a new collection of all presets matching the parameters. 105 * @see TaggingPreset#matches(Collection, Map, boolean) 106 * @since 9266 107 */ 108 public static Collection<TaggingPreset> getMatchingPresets(final Collection<TaggingPresetType> t, 109 final Map<String, String> tags, final boolean onlyShowable) { 110 return Utils.filter(getTaggingPresets(), new Predicate<TaggingPreset>() { 111 @Override 112 public boolean evaluate(TaggingPreset object) { 113 return object.matches(t, tags, onlyShowable); 114 } 115 }); 116 } 117 118 /** 119 * Replies a new collection of all presets matching the given preset. 120 * 121 * @param primitive the primitive 122 * @return a new collection of all presets matching the given preset. 123 * @see TaggingPreset#evaluate(OsmPrimitive) 124 * @since 9265 125 */ 126 public static Collection<TaggingPreset> getMatchingPresets(final OsmPrimitive primitive) { 127 return Utils.filter(getTaggingPresets(), new Predicate<TaggingPreset>() { 128 @Override 129 public boolean evaluate(TaggingPreset object) { 130 return object.evaluate(primitive); 131 } 132 }); 133 } 134 135 /** 136 * Adds a list of tagging presets to the current list. 137 * @param presets The tagging presets to add 138 */ 139 public static void addTaggingPresets(Collection<TaggingPreset> presets) { 140 if (presets != null) { 141 if (taggingPresets.addAll(presets)) { 142 for (TaggingPresetListener listener : listeners) { 143 listener.taggingPresetsModified(); 144 } 145 } 146 } 147 } 148 149 /** 150 * Adds a tagging preset listener. 151 * @param listener The listener to add 152 */ 153 public static void addListener(TaggingPresetListener listener) { 154 if (listener != null) { 155 listeners.add(listener); 156 } 157 } 158 159 /** 160 * Removes a tagging preset listener. 161 * @param listener The listener to remove 162 */ 163 public static void removeListener(TaggingPresetListener listener) { 164 if (listener != null) { 165 listeners.remove(listener); 166 } 167 } 168}