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.gui.MenuScroller;
015import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionManager;
016
017/**
018 * Class holding Tagging Presets and allowing to manage them.
019 * @since 7100
020 */
021public final class TaggingPresets {
022
023    /** The collection of tagging presets */
024    private static final Collection<TaggingPreset> taggingPresets = new ArrayList<>();
025
026    /** The collection of listeners */
027    private static final Collection<TaggingPresetListener> listeners = new ArrayList<>();
028
029    private TaggingPresets() {
030        // Hide constructor for utility classes
031    }
032
033    /**
034     * Initializes tagging presets from preferences.
035     */
036    public static void readFromPreferences() {
037        taggingPresets.clear();
038        taggingPresets.addAll(TaggingPresetReader.readFromPreferences(false, false));
039    }
040
041    /**
042     * Initialize the tagging presets (load and may display error)
043     */
044    public static void initialize() {
045        readFromPreferences();
046        for (TaggingPreset tp: taggingPresets) {
047            if (!(tp instanceof TaggingPresetSeparator)) {
048                Main.toolbar.register(tp);
049            }
050        }
051        if (taggingPresets.isEmpty()) {
052            Main.main.menu.presetsMenu.setVisible(false);
053        } else {
054            AutoCompletionManager.cachePresets(taggingPresets);
055            Map<TaggingPresetMenu, JMenu> submenus = new HashMap<>();
056            for (final TaggingPreset p : taggingPresets) {
057                JMenu m = p.group != null ? submenus.get(p.group) : Main.main.menu.presetsMenu;
058                if (m == null && p.group != null) {
059                    Main.error("No tagging preset submenu for " + p.group);
060                } else if (m == null) {
061                    Main.error("No tagging preset menu. Tagging preset " + p + " won't be available there");
062                } else if (p instanceof TaggingPresetSeparator) {
063                    m.add(new JSeparator());
064                } else if (p instanceof TaggingPresetMenu) {
065                    JMenu submenu = new JMenu(p);
066                    submenu.setText(p.getLocaleName());
067                    ((TaggingPresetMenu) p).menu = submenu;
068                    submenus.put((TaggingPresetMenu) p, submenu);
069                    m.add(submenu);
070                } else {
071                    JMenuItem mi = new JMenuItem(p);
072                    mi.setText(p.getLocaleName());
073                    m.add(mi);
074                }
075            }
076            for (JMenu submenu : submenus.values()) {
077                if (submenu.getItemCount() >= Main.pref.getInteger("taggingpreset.min-elements-for-scroller", 15)) {
078                    MenuScroller.setScrollerFor(submenu);
079                }
080            }
081        }
082        if (Main.pref.getBoolean("taggingpreset.sortmenu")) {
083            TaggingPresetMenu.sortMenu(Main.main.menu.presetsMenu);
084        }
085    }
086
087    /**
088     * Replies a new collection containing all tagging presets.
089     * @return a new collection containing all tagging presets. Empty if presets are not initialized (never null)
090     */
091    public static Collection<TaggingPreset> getTaggingPresets() {
092        return new ArrayList<>(taggingPresets);
093    }
094
095    /**
096     * Adds a list of tagging presets to the current list.
097     * @param presets The tagging presets to add
098     */
099    public static void addTaggingPresets(Collection<TaggingPreset> presets) {
100        if (presets != null) {
101            if (taggingPresets.addAll(presets)) {
102                for (TaggingPresetListener listener : listeners) {
103                    listener.taggingPresetsModified();
104                }
105            }
106        }
107    }
108
109    /**
110     * Adds a tagging preset listener.
111     * @param listener The listener to add
112     */
113    public static void addListener(TaggingPresetListener listener) {
114        if (listener != null) {
115            listeners.add(listener);
116        }
117    }
118
119    /**
120     * Removes a tagging preset listener.
121     * @param listener The listener to remove
122     */
123    public static void removeListener(TaggingPresetListener listener) {
124        if (listener != null) {
125            listeners.remove(listener);
126        }
127    }
128}