// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.gui.tagging.presets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JSeparator;
import org.openstreetmap.josm.Main;
import org.openstreetmap.josm.data.osm.OsmPrimitive;
import org.openstreetmap.josm.gui.MenuScroller;
import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionManager;
import org.openstreetmap.josm.tools.SubclassFilteredCollection;
/**
* Class holding Tagging Presets and allowing to manage them.
* @since 7100
*/
public final class TaggingPresets {
/** The collection of tagging presets */
private static final Collection<TaggingPreset> taggingPresets = new ArrayList<>();
/** The collection of listeners */
private static final Collection<TaggingPresetListener> listeners = new ArrayList<>();
private TaggingPresets() {
// Hide constructor for utility classes
}
/**
* Initializes tagging presets from preferences.
*/
public static void readFromPreferences() {
taggingPresets.clear();
taggingPresets.addAll(TaggingPresetReader.readFromPreferences(false, false));
}
/**
* Initialize the tagging presets (load and may display error)
*/
public static void initialize() {
readFromPreferences();
for (TaggingPreset tp: taggingPresets) {
if (!(tp instanceof TaggingPresetSeparator)) {
Main.toolbar.register(tp);
}
}
if (taggingPresets.isEmpty()) {
Main.main.menu.presetsMenu.setVisible(false);
} else {
AutoCompletionManager.cachePresets(taggingPresets);
Map<TaggingPresetMenu, JMenu> submenus = new HashMap<>();
for (final TaggingPreset p : taggingPresets) {
JMenu m = p.group != null ? submenus.get(p.group) : Main.main.menu.presetsMenu;
if (m == null && p.group != null) {
Main.error("No tagging preset submenu for " + p.group);
} else if (m == null) {
Main.error("No tagging preset menu. Tagging preset " + p + " won't be available there");
} else if (p instanceof TaggingPresetSeparator) {
m.add(new JSeparator());
} else if (p instanceof TaggingPresetMenu) {
JMenu submenu = new JMenu(p);
submenu.setText(p.getLocaleName());
((TaggingPresetMenu) p).menu = submenu;
submenus.put((TaggingPresetMenu) p, submenu);
m.add(submenu);
} else {
JMenuItem mi = new JMenuItem(p);
mi.setText(p.getLocaleName());
m.add(mi);
}
}
for (JMenu submenu : submenus.values()) {
if (submenu.getItemCount() >= Main.pref.getInteger("taggingpreset.min-elements-for-scroller", 15)) {
MenuScroller.setScrollerFor(submenu);
}
}
}
if (Main.pref.getBoolean("taggingpreset.sortmenu")) {
TaggingPresetMenu.sortMenu(Main.main.menu.presetsMenu);
}
}
/**
* Replies a new collection containing all tagging presets.
* @return a new collection containing all tagging presets. Empty if presets are not initialized (never null)
*/
public static Collection<TaggingPreset> getTaggingPresets() {
return new ArrayList<>(taggingPresets);
}
/**
* Replies a new collection of all presets matching the parameters.
*
* @param t the preset types to include
* @param tags the tags to perform matching on, see {@link TaggingPresetItem#matches(Map)}
* @param onlyShowable whether only {@link TaggingPreset#isShowable() showable} presets should be returned
* @return a new collection of all presets matching the parameters.
* @see TaggingPreset#matches(Collection, Map, boolean)
* @since 9266
*/
public static Collection<TaggingPreset> getMatchingPresets(final Collection<TaggingPresetType> t,
final Map<String, String> tags, final boolean onlyShowable) {
return SubclassFilteredCollection.filter(getTaggingPresets(), preset -> preset.matches(t, tags, onlyShowable));
}
/**
* Replies a new collection of all presets matching the given preset.
*
* @param primitive the primitive
* @return a new collection of all presets matching the given preset.
* @see TaggingPreset#test(OsmPrimitive)
* @since 9265
*/
public static Collection<TaggingPreset> getMatchingPresets(final OsmPrimitive primitive) {
return SubclassFilteredCollection.filter(getTaggingPresets(), preset -> preset.test(primitive));
}
/**
* Adds a list of tagging presets to the current list.
* @param presets The tagging presets to add
*/
public static void addTaggingPresets(Collection<TaggingPreset> presets) {
if (presets != null && taggingPresets.addAll(presets)) {
for (TaggingPresetListener listener : listeners) {
listener.taggingPresetsModified();
}
}
}
/**
* Adds a tagging preset listener.
* @param listener The listener to add
*/
public static void addListener(TaggingPresetListener listener) {
if (listener != null) {
listeners.add(listener);
}
}
/**
* Removes a tagging preset listener.
* @param listener The listener to remove
*/
public static void removeListener(TaggingPresetListener listener) {
if (listener != null) {
listeners.remove(listener);
}
}
}