- Timestamp:
- 2012-12-28T19:07:59+01:00 (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/dialogs/properties/TagEditHelper.java
r5640 r5642 66 66 import org.openstreetmap.josm.tools.GBC; 67 67 import org.openstreetmap.josm.tools.Shortcut; 68 import org.openstreetmap.josm.tools.WindowGeometry; 68 69 69 70 /** … … 76 77 private String changedKey; 77 78 78 private String lastAddKey = null; 79 private String lastAddValue = null; 80 81 public static final int DEFAULT_LRU_TAGS_NUMBER = 5; 82 public static final int MAX_LRU_TAGS_NUMBER = 9; 83 79 84 80 private String objKey; 85 81 … … 90 86 }; 91 87 92 93 // LRU cache for recently added tags (http://java-planet.blogspot.com/2005/08/how-to-set-up-simple-lru-cache-using.html) 94 private final Map<Tag, Void> recentTags = new LinkedHashMap<Tag, Void>(MAX_LRU_TAGS_NUMBER+1, 1.1f, true) { 95 @Override 96 protected boolean removeEldestEntry(Map.Entry<Tag, Void> eldest) { 97 return size() > MAX_LRU_TAGS_NUMBER; 98 } 99 }; 88 Collection<OsmPrimitive> sel; 89 90 private String lastAddKey = null; 91 private String lastAddValue = null; 92 93 public static final int DEFAULT_LRU_TAGS_NUMBER = 5; 94 public static final int MAX_LRU_TAGS_NUMBER = 9; 95 96 // LRU cache for recently added tags (http://java-planet.blogspot.com/2005/08/how-to-set-up-simple-lru-cache-using.html) 97 private final Map<Tag, Void> recentTags = new LinkedHashMap<Tag, Void>(MAX_LRU_TAGS_NUMBER+1, 1.1f, true) { 98 @Override 99 protected boolean removeEldestEntry(Map.Entry<Tag, Void> eldest) { 100 return size() > MAX_LRU_TAGS_NUMBER; 101 } 102 }; 100 103 101 104 TagEditHelper(DefaultTableModel propertyData, Map<String, Map<String, Integer>> valueCount) { … … 110 113 public void addProperty() { 111 114 changedKey = null; 112 Collection<OsmPrimitive> sel;113 115 if (Main.map.mapMode instanceof DrawAction) { 114 116 sel = ((DrawAction) Main.map.mapMode).getInProgressSelection(); … … 120 122 if (sel.isEmpty()) return; 121 123 122 final AddTagsPanel p = new AddTagsPanel(sel); 123 124 final JOptionPane optionPane = new JOptionPane(p, JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION){ 125 @Override public void selectInitialValue() { 126 // save unix system selection (middle mouse paste) 127 Clipboard sysSel = Toolkit.getDefaultToolkit().getSystemSelection(); 128 if(sysSel != null) { 129 Transferable old = sysSel.getContents(null); 130 p.keys.requestFocusInWindow(); 131 p.keys.getEditor().selectAll(); 132 sysSel.setContents(old, null); 133 } else { 134 p.keys.requestFocusInWindow(); 135 p.keys.getEditor().selectAll(); 136 } 137 } 138 }; 139 final JDialog dialog = optionPane.createDialog(Main.parent, tr("Add value?")); 140 dialog.setModalityType(Dialog.ModalityType.DOCUMENT_MODAL); 141 // We specify what to do if panel wants to close the entire dialog 142 p.setCloseActionListener(new ActionListener() { 143 public void actionPerformed(ActionEvent e) { 144 dialog.setVisible(false); 145 optionPane.setValue(JOptionPane.OK_OPTION); 146 } 147 }); 148 dialog.setVisible(true); 149 150 p.destroyActions(); 151 152 if (!Integer.valueOf(JOptionPane.OK_OPTION).equals(optionPane.getValue())) 153 return; 154 p.performTagAdding(); 124 final AddTagsDialog addDialog = new AddTagsDialog(); 125 126 addDialog.showDialog(); 127 128 addDialog.destroyActions(); 129 if (addDialog.getValue() == 1) 130 addDialog.performTagAdding(); 131 else 132 addDialog.undoAllTagsAdding(); 155 133 } 156 134 135 /** 136 * Edit the value in the properties table row 137 * @param row The row of the table from which the value is edited. 138 */ 139 public void editProperty(final int row) { 140 changedKey = null; 141 Collection<OsmPrimitive> sel = Main.main.getCurrentDataSet().getSelected(); 142 if (sel.isEmpty()) return; 143 144 String key = propertyData.getValueAt(row, 0).toString(); 145 objKey=key; 146 147 final EditTagDialog editDialog = new EditTagDialog(key, row, 148 (Map<String, Integer>) propertyData.getValueAt(row, 1)); 149 editDialog.showDialog(); 150 if (editDialog.getValue() !=1 ) return; 151 editDialog.performTagEdit(); 152 } 153 /** 154 * If during last editProperty call user changed the key name, this key will be returned 155 * Elsewhere, returns null. 156 */ 157 public String getChangedKey() { 158 return changedKey; 159 } 160 161 public void resetChangedKey() { 162 changedKey = null; 163 } 164 165 /** 166 * For a given key k, return a list of keys which are used as keys for 167 * auto-completing values to increase the search space. 168 * @param key the key k 169 * @return a list of keys 170 */ 171 private static List<String> getAutocompletionKeys(String key) { 172 if ("name".equals(key) || "addr:street".equals(key)) 173 return Arrays.asList("addr:street", "name"); 174 else 175 return Arrays.asList(key); 176 } 177 157 178 /** 158 179 * Create a focus handling adapter and apply in to the editor component of value … … 185 206 } 186 207 187 /** 188 * Edit the value in the properties table row 189 * @param row The row of the table from which the value is edited. 190 */ 191 public void editProperty(final int row) { 192 changedKey = null; 193 Collection<OsmPrimitive> sel = Main.main.getCurrentDataSet().getSelected(); 194 if (sel.isEmpty()) return; 195 196 String key = propertyData.getValueAt(row, 0).toString(); 197 objKey=key; 198 199 @SuppressWarnings("unchecked") 200 final EditTagsPanel p = new EditTagsPanel(key, row, sel, 201 (Map<String, Integer>) propertyData.getValueAt(row, 1)); 202 203 final JOptionPane optionPane = new JOptionPane(p, JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION) { 204 @Override public void selectInitialValue() { 205 // save unix system selection (middle mouse paste) 206 Clipboard sysSel = Toolkit.getDefaultToolkit().getSystemSelection(); 207 if(sysSel != null) { 208 Transferable old = sysSel.getContents(null); 209 p.values.requestFocusInWindow(); 210 p.values.getEditor().selectAll(); 211 sysSel.setContents(old, null); 212 } else { 213 p.values.requestFocusInWindow(); 214 p.values.getEditor().selectAll(); 215 } 216 } 217 }; 218 219 final JDialog dialog = optionPane.createDialog(Main.parent, trn("Change value?", "Change values?", p.getValueCount())); 220 dialog.setModalityType(Dialog.ModalityType.DOCUMENT_MODAL); 221 Dimension dlgSize = dialog.getSize(); 222 if(dlgSize.width > Main.parent.getSize().width) { 223 dlgSize.width = Math.max(250, Main.parent.getSize().width); 224 dialog.setSize(dlgSize); 225 } 226 dialog.setLocationRelativeTo(Main.parent); 227 228 // Auto-close dialog when user selects a value from list 229 p.values.getEditor().addActionListener(new ActionListener() { 230 public void actionPerformed(ActionEvent e) { 231 dialog.setVisible(false); 232 optionPane.setValue(JOptionPane.OK_OPTION); 233 } 234 }); 235 236 dialog.setVisible(true); 237 238 if (!Integer.valueOf(JOptionPane.OK_OPTION).equals(optionPane.getValue())) { 239 return; 240 } 241 242 p.performTagEdit(); 243 244 } 245 246 /** 247 * If during last editProperty call user changed the key name, this key will be returned 248 * Elsewhere, returns null. 249 */ 250 public String getChangedKey() { 251 return changedKey; 252 } 253 254 public void resetChangedKey() { 255 changedKey = null; 256 } 257 258 /** 259 * For a given key k, return a list of keys which are used as keys for 260 * auto-completing values to increase the search space. 261 * @param key the key k 262 * @return a list of keys 263 */ 264 private static List<String> getAutocompletionKeys(String key) { 265 if ("name".equals(key) || "addr:street".equals(key)) 266 return Arrays.asList("addr:street", "name"); 267 else 268 return Arrays.asList(key); 269 } 270 271 272 class EditTagsPanel extends JPanel { 273 final AutoCompletingComboBox keys; 274 final AutoCompletingComboBox values; 208 209 public class EditTagDialog extends ExtendedDialog { 210 AutoCompletingComboBox keys; 211 AutoCompletingComboBox values; 275 212 String oldValue; 276 final String key; 277 final Collection<OsmPrimitive> sel; 278 final Map<String, Integer> m; 279 280 public EditTagsPanel(final String key, final int row, Collection<OsmPrimitive> sel, Map<String, Integer> countMap) { 281 super(new BorderLayout()); 282 this.key = key; 283 this.sel = sel; 284 m = countMap; 285 286 287 String msg = "<html>"+trn("This will change {0} object.", 288 "This will change up to {0} objects.", sel.size(), sel.size()) 289 +"<br><br>("+tr("An empty value deletes the tag.", key)+")</html>"; 290 291 add(new JLabel(msg), BorderLayout.NORTH); 292 293 JPanel p = new JPanel(new GridBagLayout()); 294 add(p, BorderLayout.CENTER); 295 296 AutoCompletionManager autocomplete = Main.main.getEditLayer().data.getAutoCompletionManager(); 297 List<AutoCompletionListItem> keyList = autocomplete.getKeys(); 298 Collections.sort(keyList, defaultACItemComparator); 299 300 keys = new AutoCompletingComboBox(key); 301 keys.setPossibleACItems(keyList); 302 keys.setEditable(true); 303 keys.setSelectedItem(key); 304 305 p.add(new JLabel(tr("Key")), GBC.std()); 306 p.add(Box.createHorizontalStrut(10), GBC.std()); 307 p.add(keys, GBC.eol().fill(GBC.HORIZONTAL)); 308 309 310 Comparator<AutoCompletionListItem> usedValuesAwareComparator = new Comparator<AutoCompletionListItem>() { 311 213 String key; 214 Map<String, Integer> m; 215 int row; 216 217 Comparator<AutoCompletionListItem> usedValuesAwareComparator = new Comparator<AutoCompletionListItem>() { 312 218 @Override 313 219 public int compare(AutoCompletionListItem o1, AutoCompletionListItem o2) { … … 322 228 } 323 229 }; 324 325 List<AutoCompletionListItem> valueList = autocomplete.getValues(getAutocompletionKeys(key)); 326 Collections.sort(valueList, usedValuesAwareComparator); 327 328 final String selection= m.size()!=1?tr("<different>"):m.entrySet().iterator().next().getKey(); 329 330 values = new AutoCompletingComboBox(selection); 331 values.setRenderer(new DefaultListCellRenderer() { 230 231 DefaultListCellRenderer cellRenderer = new DefaultListCellRenderer() { 332 232 @Override public Component getListCellRendererComponent(JList list, 333 233 Object value, int index, boolean isSelected, boolean cellHasFocus){ … … 347 247 return c; 348 248 } 349 }); 249 }; 250 251 private EditTagDialog(String key, int row, Map<String, Integer> map) { 252 super(Main.parent, trn("Change value?", "Change values?", map.size()), new String[] {tr("OK"),tr("Cancel")}); 253 setButtonIcons(new String[] {"ok","cancel"}); 254 setCancelButton(2); 255 setIcon(JOptionPane.QUESTION_MESSAGE); 256 this.key = key; 257 this.row = row; 258 this.m = map; 259 260 // TODO : How to remember position, allowing autosizing? 261 // setRememberWindowGeometry(getClass().getName() + ".geometry", 262 // WindowGeometry.centerInWindow(Main.parent, new Dimension(270, 180))); 263 //setRememberWindowGeometry(getClass().getName() + ".geometry", 264 // WindowGeometry.centerInWindow(Main.parent, new Dimension(270, 180))); 265 266 JPanel mainPanel = new JPanel(new BorderLayout()); 267 268 String msg = "<html>"+trn("This will change {0} object.", 269 "This will change up to {0} objects.", sel.size(), sel.size()) 270 +"<br><br>("+tr("An empty value deletes the tag.", key)+")</html>"; 271 272 mainPanel.add(new JLabel(msg), BorderLayout.NORTH); 273 274 JPanel p = new JPanel(new GridBagLayout()); 275 mainPanel.add(p, BorderLayout.CENTER); 276 277 AutoCompletionManager autocomplete = Main.main.getEditLayer().data.getAutoCompletionManager(); 278 List<AutoCompletionListItem> keyList = autocomplete.getKeys(); 279 Collections.sort(keyList, defaultACItemComparator); 280 281 keys = new AutoCompletingComboBox(key); 282 keys.setPossibleACItems(keyList); 283 keys.setEditable(true); 284 keys.setSelectedItem(key); 285 286 p.add(new JLabel(tr("Key")), GBC.std()); 287 p.add(Box.createHorizontalStrut(10), GBC.std()); 288 p.add(keys, GBC.eol().fill(GBC.HORIZONTAL)); 289 290 List<AutoCompletionListItem> valueList = autocomplete.getValues(getAutocompletionKeys(key)); 291 Collections.sort(valueList, usedValuesAwareComparator); 292 293 final String selection= m.size()!=1?tr("<different>"):m.entrySet().iterator().next().getKey(); 294 295 values = new AutoCompletingComboBox(selection); 296 values.setRenderer(cellRenderer); 350 297 351 298 values.setEditable(true); … … 356 303 p.add(Box.createHorizontalStrut(10), GBC.std()); 357 304 p.add(values, GBC.eol().fill(GBC.HORIZONTAL)); 305 values.getEditor().addActionListener(new ActionListener() { 306 public void actionPerformed(ActionEvent e) { 307 buttonAction(0, null); // emulate OK button click 308 } 309 }); 358 310 addFocusAdapter(keys, values, autocomplete, usedValuesAwareComparator); 359 311 360 } 361 362 private int getValueCount() { 363 return m.size(); 364 } 365 366 /** 312 setContent(mainPanel, false); 313 314 // TODO: Is it correct place for thois code - was in 315 // new JOptionPane(p, JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION) { 316 // @Override public void selectInitialValue() { 317 Clipboard sysSel = Toolkit.getDefaultToolkit().getSystemSelection(); 318 if(sysSel != null) { 319 Transferable old = sysSel.getContents(null); 320 values.requestFocusInWindow(); 321 values.getEditor().selectAll(); 322 sysSel.setContents(old, null); 323 } else { 324 values.requestFocusInWindow(); 325 values.getEditor().selectAll(); 326 } 327 } 328 329 /** 367 330 * Edit tags of multiple selected objects according to selected ComboBox values 368 331 * If value == "", tag will be deleted … … 436 399 changedKey = newkey; 437 400 } 438 439 440 401 } 441 402 442 class AddTags Panel extends JPanel{443 final AutoCompletingComboBox keys = new AutoCompletingComboBox();444 final AutoCompletingComboBox values = new AutoCompletingComboBox();403 class AddTagsDialog extends ExtendedDialog { 404 AutoCompletingComboBox keys; 405 AutoCompletingComboBox values; 445 406 List<JosmAction> recentTagsActions = new ArrayList<JosmAction>(); 446 Collection<OsmPrimitive> sel; 447 private ActionListener autoCloseActionListener; 448 449 public AddTagsPanel(Collection<OsmPrimitive> sel) { 450 super(new GridBagLayout()); 451 this.sel = sel; 452 add(new JLabel("<html>"+trn("This will change up to {0} object.", 407 408 // Counter of added commands for possible undo 409 private int commandCount; 410 411 public AddTagsDialog() { 412 super(Main.parent, tr("Add value?"), new String[] {tr("OK"),tr("Cancel")}); 413 setButtonIcons(new String[] {"ok","cancel"}); 414 setCancelButton(2); 415 416 // TODO : How to remember position, allowing autosizing? 417 // setRememberWindowGeometry(getClass().getName() + ".geometry", 418 // WindowGeometry.centerInWindow(Main.parent, new Dimension(270, 180))); 419 420 JPanel mainPanel = new JPanel(new GridBagLayout()); 421 keys = new AutoCompletingComboBox(); 422 values = new AutoCompletingComboBox(); 423 424 mainPanel.add(new JLabel("<html>"+trn("This will change up to {0} object.", 453 425 "This will change up to {0} objects.", sel.size(),sel.size()) 454 426 +"<br><br>"+tr("Please select a key")), GBC.eol().fill(GBC.HORIZONTAL)); … … 480 452 keys.setEditable(true); 481 453 482 add(keys, GBC.eop().fill());483 484 add(new JLabel(tr("Please select a value")), GBC.eol());454 mainPanel.add(keys, GBC.eop().fill()); 455 456 mainPanel.add(new JLabel(tr("Please select a value")), GBC.eol()); 485 457 values.setEditable(true); 486 add(values, GBC.eop().fill());458 mainPanel.add(values, GBC.eop().fill()); 487 459 if (itemToSelect != null) { 488 460 keys.setSelectedItem(itemToSelect); … … 500 472 recentTagsToShow = MAX_LRU_TAGS_NUMBER; 501 473 } 502 suggestRecentlyAddedTags(recentTagsToShow, focus); 503 } 504 505 private void suggestRecentlyAddedTags(int tagsToShow, final FocusAdapter focus) { 474 suggestRecentlyAddedTags(mainPanel, recentTagsToShow, focus); 475 476 setContent(mainPanel, false); 477 478 // TODO: Is it correct place for thois code - was in 479 // new JOptionPane(p, JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION) { 480 // @Override public void selectInitialValue() { 481 Clipboard sysSel = Toolkit.getDefaultToolkit().getSystemSelection(); 482 if(sysSel != null) { 483 Transferable old = sysSel.getContents(null); 484 values.requestFocusInWindow(); 485 values.getEditor().selectAll(); 486 sysSel.setContents(old, null); 487 } else { 488 values.requestFocusInWindow(); 489 values.getEditor().selectAll(); 490 } 491 492 493 } 494 495 private void suggestRecentlyAddedTags(JPanel mainPanel, int tagsToShow, final FocusAdapter focus) { 506 496 if (!(tagsToShow > 0 && !recentTags.isEmpty())) 507 497 return; 508 498 509 add(new JLabel(tr("Recently added tags")), GBC.eol());499 mainPanel.add(new JLabel(tr("Recently added tags")), GBC.eol()); 510 500 511 501 int count = 1; … … 538 528 GridBagConstraints gbc = new GridBagConstraints(); 539 529 gbc.ipadx = 5; 540 add(new JLabel(action.isEnabled() ? icon : GuiHelper.getDisabledIcon(icon)), gbc);530 mainPanel.add(new JLabel(action.isEnabled() ? icon : GuiHelper.getDisabledIcon(icon)), gbc); 541 531 // Create tag label 542 532 final String color = action.isEnabled() ? "" : "; color:gray"; … … 546 536 if (action.isEnabled()) { 547 537 // Register action 548 getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(sc.getKeyStroke(), actionShortcutKey);549 getActionMap().put(actionShortcutKey, action);538 mainPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(sc.getKeyStroke(), actionShortcutKey); 539 mainPanel.getActionMap().put(actionShortcutKey, action); 550 540 // Make the tag label clickable and set tooltip to the action description (this displays also the keyboard shortcut) 551 541 tagLabel.setToolTipText((String) action.getValue(Action.SHORT_DESCRIPTION)); … … 558 548 if (e.getClickCount()>1) { 559 549 performTagAdding(); 560 if (autoCloseActionListener!=null) 561 autoCloseActionListener.actionPerformed(null); 550 buttonAction(0, null); // emulate OK click and close the dialog 562 551 } 563 552 // add tags on Shift-Click … … 576 565 JPanel tagPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); 577 566 tagPanel.add(tagLabel); 578 add(tagPanel, GBC.eol().fill(GBC.HORIZONTAL));567 mainPanel.add(tagPanel, GBC.eol().fill(GBC.HORIZONTAL)); 579 568 } 580 569 } … … 597 586 lastAddValue = value; 598 587 recentTags.put(new Tag(key, value), null); 588 commandCount++; 599 589 Main.main.undoRedo.add(new ChangePropertyCommand(sel, key, value)); 600 590 changedKey = key; 601 591 } 592 593 594 public void undoAllTagsAdding() { 595 Main.main.undoRedo.undo(commandCount); 596 } 597 602 598 603 599 private void disableTagIfNeeded(final Tag t, final JosmAction action) { … … 612 608 } 613 609 614 /** 615 * @param autoCloseActionListener will be called when we need to close the entire dialog 616 */ 617 public void setCloseActionListener(ActionListener autoCloseActionListener) { 618 this.autoCloseActionListener = autoCloseActionListener; 619 } 620 } 621 } 622 623 610 } 611 }
Note:
See TracChangeset
for help on using the changeset viewer.