001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.actions.relation; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.awt.GridBagLayout; 007import java.awt.event.ActionEvent; 008 009import javax.swing.JOptionPane; 010import javax.swing.JPanel; 011 012import org.openstreetmap.josm.data.osm.DefaultNameFormatter; 013import org.openstreetmap.josm.data.osm.IRelation; 014import org.openstreetmap.josm.data.osm.Relation; 015import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil; 016import org.openstreetmap.josm.gui.MainApplication; 017import org.openstreetmap.josm.gui.dialogs.relation.RelationEditor; 018import org.openstreetmap.josm.gui.widgets.JMultilineLabel; 019import org.openstreetmap.josm.tools.ImageProvider; 020 021/** 022 * Creates a new relation with a copy of the current editor state 023 * @since 5799 024 */ 025public class DuplicateRelationAction extends AbstractRelationAction { 026 027 /** 028 * Constructs a new {@code DuplicateRelationAction}. 029 */ 030 public DuplicateRelationAction() { 031 putValue(SHORT_DESCRIPTION, tr("Create a copy of this relation and open it in another editor window")); 032 new ImageProvider("duplicate").getResource().attachImageIcon(this, true); 033 putValue(NAME, tr("Duplicate")); 034 } 035 036 /** 037 * Duplicates the given relation and launches the relation editor for the created copy. 038 * @param original The relation to duplicate 039 */ 040 public static void duplicateRelationAndLaunchEditor(Relation original) { 041 if (!confirmRelationDuplicate(original)) { 042 return; 043 } 044 Relation copy = new Relation(original, true); 045 copy.setModified(true); 046 RelationEditor editor = RelationEditor.getEditor( 047 MainApplication.getLayerManager().getEditLayer(), 048 copy, 049 null /* no selected members */ 050 ); 051 editor.setVisible(true); 052 } 053 054 @Override 055 public void actionPerformed(ActionEvent e) { 056 if (!isEnabled() || relations.isEmpty()) 057 return; 058 IRelation<?> r = relations.iterator().next(); 059 if (r instanceof Relation) { 060 duplicateRelationAndLaunchEditor((Relation) r); 061 } 062 } 063 064 private static boolean isEditableRelation(IRelation<?> r) { 065 return r instanceof Relation && r.getDataSet() != null && !r.getDataSet().isLocked(); 066 } 067 068 @Override 069 protected void updateEnabledState() { 070 // only one selected relation can be edited 071 setEnabled(relations.size() == 1 072 && isEditableRelation(relations.iterator().next())); 073 } 074 075 private static boolean confirmRelationDuplicate(Relation relation) { 076 JPanel msg = new JPanel(new GridBagLayout()); 077 msg.add(new JMultilineLabel("<html>" + tr( 078 "You are about to duplicate {0} relation: {1}" 079 + "<br/>" 080 + "This step is rarely necessary. Do you really want to duplicate?", 081 1, DefaultNameFormatter.getInstance().formatAsHtmlUnorderedList(relation)) 082 + "</html>")); 083 return ConditionalOptionPaneUtil.showConfirmationDialog( 084 "delete_relations", 085 MainApplication.getMainFrame(), 086 msg, 087 tr("Duplicate relation?"), 088 JOptionPane.YES_NO_OPTION, 089 JOptionPane.QUESTION_MESSAGE, 090 JOptionPane.YES_OPTION); 091 } 092}