001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.actions.relation;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005import static org.openstreetmap.josm.tools.I18n.trn;
006
007import java.awt.event.ActionEvent;
008import java.util.Collection;
009import java.util.Collections;
010import java.util.Set;
011import java.util.stream.Collectors;
012
013import javax.swing.JOptionPane;
014
015import org.openstreetmap.josm.data.osm.IRelation;
016import org.openstreetmap.josm.data.osm.OsmPrimitive;
017import org.openstreetmap.josm.data.osm.Relation;
018import org.openstreetmap.josm.data.osm.RelationMember;
019import org.openstreetmap.josm.gui.MainApplication;
020import org.openstreetmap.josm.gui.dialogs.relation.RelationEditor;
021import org.openstreetmap.josm.gui.layer.OsmDataLayer;
022import org.openstreetmap.josm.spi.preferences.Config;
023import org.openstreetmap.josm.tools.ImageProvider;
024import org.openstreetmap.josm.tools.SubclassFilteredCollection;
025import org.openstreetmap.josm.tools.Utils;
026
027/**
028 * The action for editing a relation.
029 * @since 5793
030 */
031public class EditRelationAction extends AbstractRelationAction {
032
033    /**
034     * Constructs a new <code>EditRelationAction</code>.
035     */
036    public EditRelationAction() {
037        putValue(NAME, tr("Edit"));
038        putValue(SHORT_DESCRIPTION, tr("Call relation editor for selected relation"));
039        new ImageProvider("dialogs", "edit").getResource().attachImageIcon(this, true);
040    }
041
042    /**
043     * Returns the set of currently selected relation members for the given relation.
044     * @param r The relation to inspect
045     * @return The set of currently selected relation members for the given relation.
046     */
047    public static Set<RelationMember> getMembersForCurrentSelection(Relation r) {
048        if (MainApplication.isDisplayingMapView()) {
049            OsmDataLayer editLayer = MainApplication.getLayerManager().getEditLayer();
050            if (editLayer != null && editLayer.data != null) {
051                Collection<OsmPrimitive> selection = editLayer.data.getSelected();
052                return r.getMembers().stream().filter(m -> selection.contains(m.getMember())).collect(Collectors.toSet());
053            }
054        }
055        return Collections.emptySet();
056    }
057
058    /**
059     * Launches relation editor for the given relation.
060     * @param toEdit The relation to edit
061     */
062    public static void launchEditor(Relation toEdit) {
063        if (toEdit == null || toEdit.isDeleted() || !MainApplication.isDisplayingMapView()) return;
064        RelationEditor.getEditor(MainApplication.getLayerManager().getEditLayer(), toEdit,
065                getMembersForCurrentSelection(toEdit)).setVisible(true);
066    }
067
068    @Override
069    public void actionPerformed(ActionEvent e) {
070        SubclassFilteredCollection<IRelation<?>, Relation> filteredRelations = Utils.filteredCollection(relations, Relation.class);
071        if (!isEnabled() || filteredRelations.isEmpty()) return;
072        if (filteredRelations.size() > Config.getPref().getInt("warn.open.maxrelations", 5) &&
073            /* I18N english text for value 1 makes no real sense, never called for values <= maxrel (usually 5) */
074            JOptionPane.OK_OPTION != JOptionPane.showConfirmDialog(MainApplication.getMainFrame(),
075                    "<html>"+trn("You are about to open <b>{0}</b> different relation editor simultaneously.<br/>Do you want to continue?",
076                            "You are about to open <b>{0}</b> different relation editors simultaneously.<br/>Do you want to continue?",
077                            filteredRelations.size(), filteredRelations.size())+"</html>",
078                    tr("Confirmation"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE)) {
079            return;
080        }
081        for (Relation r : filteredRelations) {
082            launchEditor(r);
083        }
084    }
085
086    @Override
087    protected void updateEnabledState() {
088        setEnabled(canModify());
089    }
090}