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.HashSet;
010import java.util.Set;
011
012import javax.swing.JOptionPane;
013
014import org.openstreetmap.josm.Main;
015import org.openstreetmap.josm.data.osm.OsmPrimitive;
016import org.openstreetmap.josm.data.osm.OsmUtils;
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;
024
025/**
026 * The action for editing a relation.
027 * @since 5793
028 */
029public class EditRelationAction extends AbstractRelationAction {
030
031    /**
032     * Constructs a new <code>EditRelationAction</code>.
033     */
034    public EditRelationAction() {
035        putValue(NAME, tr("Edit"));
036        putValue(SHORT_DESCRIPTION, tr("Call relation editor for selected relation"));
037        new ImageProvider("dialogs", "edit").getResource().attachImageIcon(this, true);
038    }
039
040    /**
041     * Returns the set of currently selected relation members for the given relation.
042     * @param r The relation to inspect
043     * @return The set of currently selected relation members for the given relation.
044     */
045    public static Set<RelationMember> getMembersForCurrentSelection(Relation r) {
046        Set<RelationMember> members = new HashSet<>();
047        if (MainApplication.isDisplayingMapView()) {
048            OsmDataLayer editLayer = MainApplication.getLayerManager().getEditLayer();
049            if (editLayer != null && editLayer.data != null) {
050                Collection<OsmPrimitive> selection = editLayer.data.getSelected();
051                for (RelationMember member: r.getMembers()) {
052                    if (selection.contains(member.getMember())) {
053                        members.add(member);
054                    }
055                }
056            }
057        }
058        return members;
059    }
060
061    /**
062     * Launches relation editor for the given relation.
063     * @param toEdit The relation to edit
064     */
065    public static void launchEditor(Relation toEdit) {
066        if (toEdit == null || toEdit.isDeleted() || !MainApplication.isDisplayingMapView()) return;
067        RelationEditor.getEditor(MainApplication.getLayerManager().getEditLayer(), toEdit,
068                getMembersForCurrentSelection(toEdit)).setVisible(true);
069    }
070
071    @Override
072    public void actionPerformed(ActionEvent e) {
073        if (!isEnabled() || relations.isEmpty()) return;
074        if (relations.size() > Config.getPref().getInt("warn.open.maxrelations", 5) &&
075            /* I18N english text for value 1 makes no real sense, never called for values <= maxrel (usually 5) */
076            JOptionPane.OK_OPTION != JOptionPane.showConfirmDialog(Main.parent,
077                    "<html>"+trn("You are about to open <b>{0}</b> different relation editor simultaneously.<br/>Do you want to continue?",
078                            "You are about to open <b>{0}</b> different relation editors simultaneously.<br/>Do you want to continue?",
079                            relations.size(), relations.size())+"</html>",
080                    tr("Confirmation"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE)) {
081            return;
082        }
083        for (Relation r : relations) {
084            launchEditor(r);
085        }
086    }
087
088    @Override
089    protected void updateEnabledState() {
090        boolean enabled = false;
091        if (OsmUtils.isOsmCollectionEditable(relations)) {
092            for (Relation r : relations) {
093                if (!r.isDeleted()) {
094                    enabled = true;
095                    break;
096                }
097            }
098        }
099        setEnabled(enabled);
100    }
101}