source: josm/trunk/src/org/openstreetmap/josm/actions/DeleteAction.java

Last change on this file was 19290, checked in by taylor.smock, 5 months ago

Fix #24093: Wrong page is linked for context sensitive help for Edit -> Delete action

  • Property svn:eol-style set to native
File size: 7.4 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.actions;
3
4import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
5import static org.openstreetmap.josm.tools.I18n.tr;
6import static org.openstreetmap.josm.tools.I18n.trn;
7
8import java.awt.GridBagLayout;
9import java.awt.event.ActionEvent;
10import java.awt.event.KeyEvent;
11import java.util.Collection;
12import java.util.Collections;
13
14import javax.swing.JOptionPane;
15import javax.swing.JPanel;
16
17import org.openstreetmap.josm.command.DeleteCommand.DeletionCallback;
18import org.openstreetmap.josm.data.osm.DefaultNameFormatter;
19import org.openstreetmap.josm.data.osm.INode;
20import org.openstreetmap.josm.data.osm.IRelation;
21import org.openstreetmap.josm.data.osm.IWay;
22import org.openstreetmap.josm.data.osm.OsmPrimitive;
23import org.openstreetmap.josm.data.osm.Relation;
24import org.openstreetmap.josm.data.osm.RelationToChildReference;
25import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil;
26import org.openstreetmap.josm.gui.MainApplication;
27import org.openstreetmap.josm.gui.MapFrame;
28import org.openstreetmap.josm.gui.dialogs.DeleteFromRelationConfirmationDialog;
29import org.openstreetmap.josm.gui.util.GuiHelper;
30import org.openstreetmap.josm.gui.widgets.JMultilineLabel;
31import org.openstreetmap.josm.tools.Pair;
32import org.openstreetmap.josm.tools.Shortcut;
33
34/**
35 * Action that deletes selected objects.
36 * @since 770
37 */
38public final class DeleteAction extends JosmAction {
39
40 /**
41 * The default {@link DeletionCallback} for {@code DeleteCommand}.
42 * @since 12760
43 */
44 public static final DeletionCallback defaultDeletionCallback = new DeletionCallback() {
45 @Override
46 public boolean checkAndConfirmOutlyingDelete(Collection<? extends OsmPrimitive> primitives,
47 Collection<? extends OsmPrimitive> ignore) {
48 return DeleteAction.checkAndConfirmOutlyingDelete(primitives, ignore);
49 }
50
51 @Override
52 public boolean confirmRelationDeletion(Collection<Relation> relations) {
53 return DeleteAction.confirmRelationDeletion(relations);
54 }
55
56 @Override
57 public boolean confirmDeletionFromRelation(Collection<RelationToChildReference> references) {
58 return this.confirmDeletionFromRelation(references, Collections.emptyList());
59 }
60
61 @Override
62 public boolean confirmDeletionFromRelation(Collection<RelationToChildReference> references,
63 Collection<Pair<Relation, Boolean>> parentsToDelete) {
64 DeleteFromRelationConfirmationDialog dialog = DeleteFromRelationConfirmationDialog.getInstance();
65 dialog.getModel().populate(references);
66 dialog.getDeletedRelationsModel().populate(parentsToDelete);
67 dialog.setVisible(true);
68 return !dialog.isCanceled();
69 }
70 };
71
72 /**
73 * Constructs a new {@code DeleteAction}.
74 */
75 public DeleteAction() {
76 super(tr("Delete"), "dialogs/delete", tr("Delete selected objects."),
77 Shortcut.registerShortcut("system:delete", tr("Edit: {0}", tr("Delete")), KeyEvent.VK_DELETE, Shortcut.DIRECT), true);
78 setHelpId(ht("/Action/EditDelete"));
79 }
80
81 @Override
82 public void actionPerformed(ActionEvent e) {
83 MapFrame map = MainApplication.getMap();
84 if (!isEnabled() || !map.mapView.isActiveLayerVisible())
85 return;
86 map.mapModeDelete.doActionPerformed(e);
87 }
88
89 @Override
90 protected void updateEnabledState() {
91 updateEnabledStateOnCurrentSelection();
92 }
93
94 @Override
95 protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
96 updateEnabledStateOnModifiableSelection(selection);
97 }
98
99 /**
100 * Check whether user is about to delete data outside of the download area.
101 * Request confirmation if he is.
102 * @param primitives the primitives to operate on
103 * @param ignore {@code null} or a primitive to be ignored
104 * @return true, if operating on outlying primitives is OK; false, otherwise
105 * @since 12749 (moved from DeleteCommand)
106 */
107 public static boolean checkAndConfirmOutlyingDelete(Collection<? extends OsmPrimitive> primitives,
108 Collection<? extends OsmPrimitive> ignore) {
109 final boolean nodes = primitives.stream().anyMatch(INode.class::isInstance);
110 final boolean ways = primitives.stream().anyMatch(IWay.class::isInstance);
111 final boolean relations = primitives.stream().anyMatch(IRelation.class::isInstance);
112 final String type;
113 if (nodes && !ways && !relations) {
114 type = tr("You are about to delete nodes which can have other referrers not yet downloaded.");
115 } else if (!nodes && ways && !relations) {
116 type = tr("You are about to delete ways which can have other referrers not yet downloaded.");
117 } else if (!nodes && !ways && relations) {
118 type = tr("You are about to delete relations which can have other referrers not yet downloaded.");
119 } else {
120 // OK. We have multiple types being deleted.
121 type = tr("You are about to delete primitives which can have other referrers not yet downloaded.");
122 }
123 return Boolean.TRUE.equals(GuiHelper.runInEDTAndWaitAndReturn(() -> checkAndConfirmOutlyingOperation("delete",
124 tr("Delete confirmation"),
125 tr("{0}"
126 + "<br>"
127 + "This can cause problems because other objects (that you do not see) might use them."
128 + "<br>"
129 + "Do you really want to delete?", type),
130 tr("You are about to delete incomplete objects."
131 + "<br>"
132 + "This will cause problems because you don''t see the real object."
133 + "<br>" + "Do you really want to delete?"),
134 primitives, ignore)));
135 }
136
137 /**
138 * Confirm before deleting a relation, as it is a common newbie error.
139 * @param relations relation to check for deletion
140 * @return {@code true} if user confirms the deletion
141 * @since 12760
142 */
143 public static boolean confirmRelationDeletion(Collection<Relation> relations) {
144 if (relations.stream().allMatch(Relation::isNew)) {
145 return true;
146 }
147 JPanel msg = new JPanel(new GridBagLayout());
148 msg.add(new JMultilineLabel("<html>" + trn(
149 "You are about to delete {0} relation: {1}"
150 + "<br/>"
151 + "This step is rarely necessary and cannot be undone easily after being uploaded to the server."
152 + "<br/>"
153 + "Do you really want to delete?",
154 "You are about to delete {0} relations: {1}"
155 + "<br/>"
156 + "This step is rarely necessary and cannot be undone easily after being uploaded to the server."
157 + "<br/>"
158 + "Do you really want to delete?",
159 relations.size(), relations.size(), DefaultNameFormatter.getInstance().formatAsHtmlUnorderedList(relations, 20))
160 + "</html>"));
161 return ConditionalOptionPaneUtil.showConfirmationDialog(
162 "delete_relations",
163 MainApplication.getMainFrame(),
164 msg,
165 tr("Delete relation?"),
166 JOptionPane.YES_NO_OPTION,
167 JOptionPane.QUESTION_MESSAGE,
168 JOptionPane.YES_OPTION);
169 }
170}
Note: See TracBrowser for help on using the repository browser.