Changeset 18842 in josm
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/dialogs/properties/TagEditHelper.java
r18692 r18842 73 73 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 74 74 import org.openstreetmap.josm.data.osm.Tag; 75 import org.openstreetmap.josm.data.osm.Tagged; 75 76 import org.openstreetmap.josm.data.osm.search.SearchCompiler; 76 77 import org.openstreetmap.josm.data.osm.search.SearchParseError; … … 82 83 import org.openstreetmap.josm.data.preferences.StringProperty; 83 84 import org.openstreetmap.josm.data.tagging.ac.AutoCompletionItem; 85 import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil; 84 86 import org.openstreetmap.josm.gui.ExtendedDialog; 85 87 import org.openstreetmap.josm.gui.IExtendedDialog; … … 278 280 try { 279 281 activeDataSet.beginUpdate(); 280 sel = OsmDataManager.getInstance().getInProgressSelection(); 281 if (Utils.isEmpty(sel)) 282 Collection<OsmPrimitive> selection = OsmDataManager.getInstance().getInProgressSelection(); 283 this.sel = selection; 284 if (Utils.isEmpty(selection)) 282 285 return; 283 286 … … 287 290 288 291 addDialog.destroyActions(); 289 if (addDialog.getValue() == 1) 290 addDialog.performTagAdding(); 291 else 292 // Remote control can cause the selection to change, see #23191. 293 if (addDialog.getValue() == 1 && (selection == sel || warnSelectionChanged())) { 294 addDialog.performTagAdding(selection); 295 } else { 292 296 addDialog.undoAllTagsAdding(); 297 } 293 298 } finally { 294 299 activeDataSet.endUpdate(); … … 373 378 public void loadTagsIfNeeded() { 374 379 loadTagsToIgnore(); 375 if (PROPERTY_REMEMBER_TAGS.get() && recentTags.isEmpty()) { 380 if (Boolean.TRUE.equals(PROPERTY_REMEMBER_TAGS.get()) && recentTags.isEmpty()) { 376 381 recentTags.loadFromPreference(PROPERTY_RECENT_TAGS); 377 382 } … … 407 412 */ 408 413 public void saveTagsIfNeeded() { 409 if (PROPERTY_REMEMBER_TAGS.get() && !recentTags.isEmpty()) { 414 if (Boolean.TRUE.equals(PROPERTY_REMEMBER_TAGS.get()) && !recentTags.isEmpty()) { 410 415 recentTags.saveToPreference(PROPERTY_RECENT_TAGS); 411 416 } … … 449 454 return selectedItem.toString(); 450 455 return getEditItem(cb); 456 } 457 458 /** 459 * Warn user about a selection change 460 * @return {@code true} if the user wants to apply the tag change to the old selection 461 */ 462 private static boolean warnSelectionChanged() { 463 return ConditionalOptionPaneUtil.showConfirmationDialog("properties.selection-changed", 464 MainApplication.getMainFrame(), 465 tr("Data selection has changed since the dialog was opened"), 466 tr("Apply tag change to old selection?"), 467 JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, JOptionPane.YES_OPTION); 451 468 } 452 469 … … 506 523 /** 507 524 * This hack allows the comboboxes to have their own orientation. 508 * 525 * <p> 509 526 * The problem is that 510 527 * {@link org.openstreetmap.josm.gui.ExtendedDialog#showDialog ExtendedDialog} calls 511 528 * {@code applyComponentOrientation} very late in the dialog construction process 512 529 * thus overwriting the orientation the components have chosen for themselves. 513 * 530 * <p> 514 531 * This stops the propagation of {@code applyComponentOrientation}, thus all 515 532 * components may (and have to) set their own orientation. … … 794 811 /** 795 812 * This hack allows the comboboxes to have their own orientation. 796 * 813 * <p> 797 814 * The problem is that 798 815 * {@link org.openstreetmap.josm.gui.ExtendedDialog#showDialog ExtendedDialog} calls 799 816 * {@code applyComponentOrientation} very late in the dialog construction process 800 817 * thus overwriting the orientation the components have chosen for themselves. 801 * 818 * <p> 802 819 * This stops the propagation of {@code applyComponentOrientation}, thus all 803 820 * components may (and have to) set their own orientation. … … 1187 1204 */ 1188 1205 public final void performTagAdding() { 1206 Collection<OsmPrimitive> selection = sel; 1207 if (!Utils.isEmpty(selection)) { 1208 performTagAdding(selection); 1209 } 1210 } 1211 1212 /** 1213 * Read tags from comboboxes and add it to all selected objects 1214 * @param selection The selection to perform tag adding on 1215 * @since 18842 1216 */ 1217 private void performTagAdding(Collection<OsmPrimitive> selection) { 1189 1218 String key = getEditItem(keys); 1190 1219 String value = getEditItem(values); 1191 1220 if (key.isEmpty() || value.isEmpty()) 1192 1221 return; 1193 for ( OsmPrimitiveosm : sel) {1222 for (Tagged osm : selection) { 1194 1223 String val = osm.get(key); 1195 1224 if (val != null && !val.equals(value)) { … … 1203 1232 } 1204 1233 recentTags.add(new Tag(key, value)); 1205 valueCount.put(key, new TreeMap< String, Integer>());1234 valueCount.put(key, new TreeMap<>()); 1206 1235 AutoCompletionManager.rememberUserInput(key, value, false); 1207 1236 commandCount++; 1208 UndoRedoHandler.getInstance().add(new ChangePropertyCommand(sel, key, value)); 1237 UndoRedoHandler.getInstance().add(new ChangePropertyCommand(selection, key, value)); 1209 1238 changedKey = key; 1210 1239 clearEntries(); … … 1216 1245 } 1217 1246 1247 /** 1248 * Undo all tag add commands that this dialog has created 1249 */ 1218 1250 public void undoAllTagsAdding() { 1219 1251 UndoRedoHandler.getInstance().undo(commandCount); -
trunk/test/unit/org/openstreetmap/josm/gui/dialogs/properties/TagEditHelperTest.java
r18799 r18842 2 2 package org.openstreetmap.josm.gui.dialogs.properties; 3 3 4 import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; 4 5 import static org.junit.jupiter.api.Assertions.assertEquals; 5 6 import static org.junit.jupiter.api.Assertions.assertFalse; 6 7 import static org.junit.jupiter.api.Assertions.assertNotNull; 8 import static org.junit.jupiter.api.Assertions.assertTrue; 7 9 8 10 import java.awt.GraphicsEnvironment; … … 15 17 import java.util.List; 16 18 import java.util.Map; 19 import java.util.concurrent.Future; 20 import java.util.concurrent.atomic.AtomicBoolean; 17 21 import java.util.function.Function; 18 22 import java.util.stream.Collectors; 19 23 24 import javax.swing.JOptionPane; 20 25 import javax.swing.JTable; 21 26 import javax.swing.table.DefaultTableModel; 22 27 28 import org.awaitility.Awaitility; 29 import org.awaitility.Durations; 23 30 import org.junit.jupiter.api.Test; 24 31 import org.openstreetmap.josm.TestUtils; … … 30 37 import org.openstreetmap.josm.data.osm.Way; 31 38 import org.openstreetmap.josm.data.tagging.ac.AutoCompletionItem; 39 import org.openstreetmap.josm.gui.ExtendedDialog; 32 40 import org.openstreetmap.josm.gui.MainApplication; 33 41 import org.openstreetmap.josm.gui.dialogs.properties.TagEditHelper.AddTagsDialog; … … 35 43 import org.openstreetmap.josm.gui.mappaint.MapPaintStyles; 36 44 import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSStyleSource; 45 import org.openstreetmap.josm.spi.preferences.Config; 37 46 import org.openstreetmap.josm.testutils.annotations.Projection; 38 47 import org.openstreetmap.josm.testutils.annotations.Territories; 39 48 import org.openstreetmap.josm.testutils.mockers.WindowMocker; 49 import org.openstreetmap.josm.tools.JosmRuntimeException; 50 51 import mockit.Mock; 52 import mockit.MockUp; 40 53 41 54 /** … … 104 117 return node; 105 118 }, "junction", "roundabout"); 119 } 120 121 /** 122 * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/23191>#23191</a> 123 */ 124 @Test 125 void testTicket23191() { 126 TestUtils.assumeWorkingJMockit(); 127 final TagEditHelper tagEditHelper = newTagEditHelper(); 128 final DataSet original = new DataSet(); 129 MainApplication.getLayerManager().addLayer(new OsmDataLayer(original, "TagEditHelperTest.testTicket23191_1", null)); 130 final Node toSelect = TestUtils.newNode(""); 131 original.addPrimitive(toSelect); 132 original.setSelected(toSelect); 133 assertEquals(1, OsmDataManager.getInstance().getInProgressISelection().size()); 134 assertTrue(OsmDataManager.getInstance().getInProgressISelection().contains(toSelect)); 135 136 final AtomicBoolean canContinue = new AtomicBoolean(); 137 final AtomicBoolean showingDialog = new AtomicBoolean(); 138 139 // Instantiate the AddTagsDialog where we don't have to worry about race conditions 140 tagEditHelper.sel = OsmDataManager.getInstance().getInProgressSelection(); 141 final AddTagsDialog addTagsDialog = tagEditHelper.getAddTagsDialog(); 142 tagEditHelper.resetSelection(); 143 new MockUp<TagEditHelper>() { 144 @Mock 145 public AddTagsDialog getAddTagsDialog() { 146 return addTagsDialog; 147 } 148 }; 149 150 new MockUp<AddTagsDialog>() { 151 @Mock 152 public ExtendedDialog showDialog() { 153 showingDialog.set(true); 154 while (!canContinue.get()) { 155 synchronized (canContinue) { 156 try { 157 canContinue.wait(); 158 } catch (InterruptedException e) { 159 throw new JosmRuntimeException(e); 160 } 161 } 162 } 163 return null; 164 } 165 166 @Mock 167 public int getValue() { 168 return 1; 169 } 170 }; 171 172 // Avoid showing the JOption pane 173 Config.getPref().putBoolean("message.properties.selection-changed", false); 174 Config.getPref().putInt("message.properties.selection-changed.value", JOptionPane.YES_OPTION); 175 176 // "Open" the tag edit dialog -- this should technically be in the EDT, but we are mocking the UI parts out, 177 // since the EDT does allow new EDT runnables when showing the add tag dialog 178 Future<?> tagFuture = MainApplication.worker.submit(tagEditHelper::addTag); 179 180 Awaitility.await().atMost(Durations.ONE_SECOND).untilTrue(showingDialog); 181 // This is what remote control will effectively do 182 MainApplication.getLayerManager().addLayer(new OsmDataLayer(new DataSet(), "TagEditHelperTest.testTicket23191_2", null)); 183 tagEditHelper.resetSelection(); 184 185 // Enter key=value 186 addTagsDialog.keys.setText("building"); 187 addTagsDialog.values.setText("yes"); 188 189 // Close the tag edit dialog 190 synchronized (canContinue) { 191 canContinue.set(true); 192 canContinue.notifyAll(); 193 } 194 195 assertDoesNotThrow(() -> tagFuture.get()); 106 196 } 107 197
Note:
See TracChangeset
for help on using the changeset viewer.