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.DataSet; 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; 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 (relations.stream().map(Relation::getDataSet).noneMatch(DataSet::isLocked)) { 092 for (Relation r : relations) { 093 if (!r.isDeleted()) { 094 enabled = true; 095 break; 096 } 097 } 098 } 099 setEnabled(enabled); 100 } 101}