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