Changeset 1916 in josm for trunk/src/org
- Timestamp:
- 2009-08-05T21:35:30+02:00 (15 years ago)
- Location:
- trunk/src/org/openstreetmap/josm/gui/dialogs
- Files:
-
- 1 added
- 6 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/dialogs/RelationListDialog.java
r1897 r1916 19 19 import javax.swing.JScrollPane; 20 20 import javax.swing.ListSelectionModel; 21 import javax.swing.SwingUtilities; 21 22 import javax.swing.event.ListSelectionEvent; 22 23 import javax.swing.event.ListSelectionListener; … … 77 78 displaylist.setCellRenderer(new OsmPrimitivRenderer()); 78 79 displaylist.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 79 displaylist.addMouseListener(new MouseAdapter(){ 80 @Override public void mouseClicked(MouseEvent e) { 81 if (e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1) { 82 Main.main.getCurrentDataSet().setSelected((Relation)displaylist.getSelectedValue()); 83 } 84 } 85 }); 80 displaylist.addMouseListener(new DoubleClickAdapter()); 86 81 add(new JScrollPane(displaylist), BorderLayout.CENTER); 87 82 … … 101 96 displaylist.addListSelectionListener(editAction); 102 97 buttonPanel.add(new SideButton(editAction), GBC.std()); 98 99 // the edit action 100 // 101 DuplicateAction duplicateAction = new DuplicateAction(); 102 displaylist.addListSelectionListener(duplicateAction); 103 buttonPanel.add(new SideButton(duplicateAction), GBC.std()); 103 104 104 105 // the delete action … … 235 236 } 236 237 238 class DoubleClickAdapter extends MouseAdapter { 239 protected void setCurrentRelationAsSelection() { 240 Main.main.getCurrentDataSet().setSelected((Relation)displaylist.getSelectedValue()); 241 } 242 243 protected void editCurrentRelation() { 244 new EditAction().launchEditor(getSelected()); 245 } 246 247 @Override public void mouseClicked(MouseEvent e) { 248 if (e.getClickCount() == 2 && SwingUtilities.isLeftMouseButton(e)) { 249 if (e.isControlDown()) { 250 editCurrentRelation(); 251 } else { 252 setCurrentRelationAsSelection(); 253 } 254 } 255 } 256 } 257 237 258 /** 238 259 * The edit action 239 260 * 240 261 */ 241 class EditAction extends AbstractAction implements ListSelectionListener , Runnable{262 class EditAction extends AbstractAction implements ListSelectionListener{ 242 263 public EditAction() { 243 264 putValue(SHORT_DESCRIPTION,tr( "Open an editor for the selected relation")); … … 257 278 } 258 279 259 public void run() { 260 if (!isEnabled()) return; 261 Relation toEdit = getSelected(); 280 public void launchEditor(Relation toEdit) { 262 281 if (toEdit == null) 263 282 return; … … 266 285 267 286 public void actionPerformed(ActionEvent e) { 268 run(); 287 if (!isEnabled()) 288 return; 289 launchEditor(getSelected()); 269 290 } 270 291 … … 344 365 } 345 366 } 367 368 /** 369 * Creates a new relation with a copy of the current editor state 370 * 371 */ 372 class DuplicateAction extends AbstractAction implements ListSelectionListener { 373 public DuplicateAction() { 374 putValue(SHORT_DESCRIPTION, tr("Create a copy of this relation and open it in another editor window")); 375 // FIXME provide an icon 376 putValue(SMALL_ICON, ImageProvider.get("duplicate")); 377 putValue(NAME, tr("Duplicate")); 378 updateEnabledState(); 379 } 380 381 public void launchEditorForDuplicate(Relation original) { 382 Relation copy = new Relation(); 383 copy.cloneFrom(original); 384 copy.id = 0; 385 copy.modified = true; 386 RelationEditor editor = RelationEditor.getEditor( 387 Main.main.getEditLayer(), 388 copy, 389 null /* no selected members */ 390 ); 391 editor.setVisible(true); 392 } 393 394 public void actionPerformed(ActionEvent e) { 395 if (!isEnabled()) 396 return; 397 launchEditorForDuplicate(getSelected()); 398 } 399 400 protected void updateEnabledState() { 401 setEnabled(displaylist.getSelectedIndices() != null && displaylist.getSelectedIndices().length == 1); 402 } 403 404 public void valueChanged(ListSelectionEvent e) { 405 updateEnabledState(); 406 } 407 } 346 408 } -
trunk/src/org/openstreetmap/josm/gui/dialogs/relation/AutoCompletingTextField.java
r1910 r1916 17 17 18 18 /** 19 * TagFieldEditor is an editor for tag names or tag values. It supports auto completion 20 * from a list of auto completion items. 19 * AutoCompletingTextField is an text field with autocompletion behaviour. It 20 * can be used as table cell editor in {@see JTable}s. 21 * 22 * Autocompletion is controlled by a list of {@see AutoCompletionListItem}s 23 * managed in a {@see AutoCompletionList}. 24 * 21 25 * 22 26 */ 23 public class TagFieldEditorextends JTextField {27 public class AutoCompletingTextField extends JTextField { 24 28 25 static private Logger logger = Logger.getLogger( TagFieldEditor.class.getName());29 static private Logger logger = Logger.getLogger(AutoCompletingTextField.class.getName()); 26 30 27 31 /** … … 89 93 } 90 94 91 /** 92 * constructor 93 */ 94 public TagFieldEditor() { 95 95 protected void init() { 96 96 addFocusListener( 97 97 new FocusAdapter() { … … 114 114 } 115 115 ); 116 } 117 118 /** 119 * constructor 120 */ 121 public AutoCompletingTextField() { 122 init(); 123 } 124 125 public AutoCompletingTextField(int columns) { 126 super(columns); 127 init(); 116 128 } 117 129 -
trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java
r1890 r1916 27 27 import java.util.Iterator; 28 28 import java.util.List; 29 import java.util.Set; 29 30 import java.util.logging.Logger; 30 31 … … 106 107 private SelectionTableModel selectionTableModel; 107 108 108 private JTextField tfRole;109 private AutoCompletingTextField tfRole; 109 110 110 111 /** … … 124 125 // initialize the autocompletion infrastructure 125 126 // 126 acCache = AutoCompletionCache.getCacheForLayer(Main.map.mapView.getEditLayer()); 127 acCache = AutoCompletionCache.getCacheForLayer(getLayer()); 128 acCache.initFromJOSMDataset(); 127 129 acList = new AutoCompletionList(); 128 130 … … 130 132 // 131 133 tagEditorModel = new TagEditorModel(); 132 memberTableModel = new MemberTableModel( );134 memberTableModel = new MemberTableModel(getLayer()); 133 135 selectionTableModel = new SelectionTableModel(getLayer()); 134 136 referrerModel = new ReferringRelationsBrowserModel(relation); … … 198 200 199 201 memberTableModel.setSelectedMembers(selectedMembers); 202 DataSet.selListeners.add(memberTableModel); 200 203 } 201 204 … … 266 269 // 267 270 tagTable = new TagTable(tagEditorModel); 268 acCache.initFromJOSMDataset();269 271 TagCellEditor editor = ((TagCellEditor) tagTable.getColumnModel().getColumn(0).getCellEditor()); 270 272 editor.setAutoCompletionCache(acCache); … … 330 332 // setting up the member table 331 333 memberTable = new MemberTable(getLayer(),memberTableModel); 334 MemberRoleCellEditor editor = ((MemberRoleCellEditor) memberTable.getColumnModel().getColumn(0).getCellEditor()); 335 editor.setAutoCompletionCache(acCache); 336 editor.setAutoCompletionList(acList); 332 337 333 338 memberTable.getSelectionModel().addListSelectionListener(new SelectionSynchronizer()); … … 592 597 // --- role editing 593 598 buttonPanel.add(new JLabel(tr("Role:"))); 594 tfRole = new JTextField(10);599 tfRole = new AutoCompletingTextField(10); 595 600 tfRole.addFocusListener(new FocusAdapter() { 596 601 @Override … … 599 604 } 600 605 }); 606 tfRole.setAutoCompletionList(acList); 607 tfRole.addFocusListener( 608 new FocusAdapter() { 609 @Override 610 public void focusGained(FocusEvent e) { 611 acCache.populateWithMemberRoles(acList); 612 } 613 } 614 ); 615 601 616 buttonPanel.add(tfRole); 602 617 SetRoleAction setRoleAction = new SetRoleAction(); … … 626 641 public void dispose() { 627 642 selectionTableModel.unregister(); 643 DataSet.selListeners.remove(memberTableModel); 628 644 super.dispose(); 629 645 } … … 1432 1448 } 1433 1449 1450 /** 1451 * Updates the selection in the current data set with the selected referers in 1452 * in the member table. 1453 * 1454 */ 1434 1455 class SelectionSynchronizer implements ListSelectionListener { 1435 1456 public void valueChanged(ListSelectionEvent e) { 1436 ArrayList<OsmPrimitive> sel; 1437 int cnt = memberTable.getSelectedRowCount(); 1438 if (cnt <= 0) 1457 if (e.getValueIsAdjusting()) 1439 1458 return; 1440 sel = new ArrayList<OsmPrimitive>(cnt); 1441 for (int i : memberTable.getSelectedRows()) { 1442 sel.add(memberTableModel.getReferredPrimitive(i)); 1443 } 1444 getLayer().data.setSelected(sel); 1459 1460 // Avoid endless loops. memberTableModel is registered as SelectionChangeListener 1461 // too. Only update the selection if it is not in sync with what is already 1462 // selected. 1463 // 1464 if (!memberTableModel.selectionsAreInSync()) { 1465 getLayer().data.setSelected(memberTableModel.getSelectedReferers()); 1466 } 1445 1467 } 1446 1468 } … … 1448 1470 /** 1449 1471 * The asynchronous task for downloading relation members. 1450 *1451 1472 * 1452 1473 */ -
trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableColumnModel.java
r1822 r1916 17 17 col.setResizable(true); 18 18 col.setCellRenderer(new MemberTableRoleCellRenderer()); 19 19 col.setCellEditor(new MemberRoleCellEditor()); 20 20 addColumn(col); 21 21 -
trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java
r1886 r1916 1 // License: GPL. For details, see LICENSE file.2 1 package org.openstreetmap.josm.gui.dialogs.relation; 3 2 … … 10 9 import java.util.LinkedList; 11 10 import java.util.List; 11 import java.util.Set; 12 12 import java.util.Vector; 13 13 import java.util.concurrent.CopyOnWriteArrayList; … … 17 17 import javax.swing.table.AbstractTableModel; 18 18 19 import org.openstreetmap.josm.Main; 20 import org.openstreetmap.josm.data.SelectionChangedListener; 19 21 import org.openstreetmap.josm.data.osm.DataSet; 20 22 import org.openstreetmap.josm.data.osm.Node; … … 23 25 import org.openstreetmap.josm.data.osm.RelationMember; 24 26 import org.openstreetmap.josm.data.osm.Way; 25 26 public class MemberTableModel extends AbstractTableModel { 27 import org.openstreetmap.josm.gui.layer.OsmDataLayer; 28 29 public class MemberTableModel extends AbstractTableModel implements SelectionChangedListener{ 27 30 28 31 private ArrayList<RelationMember> members; 29 32 private DefaultListSelectionModel listSelectionModel; 30 33 private CopyOnWriteArrayList<IMemberModelListener> listeners; 34 private OsmDataLayer layer; 31 35 32 36 /** 33 37 * constructor 34 38 */ 35 public MemberTableModel( ) {39 public MemberTableModel(OsmDataLayer layer) { 36 40 members = new ArrayList<RelationMember>(); 37 41 listeners = new CopyOnWriteArrayList<IMemberModelListener>(); 42 this.layer = layer; 38 43 } 39 44 … … 82 87 public Object getValueAt(int rowIndex, int columnIndex) { 83 88 switch (columnIndex) { 84 case 0:85 return members.get(rowIndex).role;86 case 1:87 return members.get(rowIndex).member;88 case 2:89 return linked(rowIndex);89 case 0: 90 return members.get(rowIndex).role; 91 case 1: 92 return members.get(rowIndex).member; 93 case 2: 94 return linked(rowIndex); 90 95 } 91 96 // should not happen … … 119 124 } 120 125 fireTableDataChanged(); 121 getSelectionModel() ;122 listSelectionModel.clearSelection();126 getSelectionModel().setValueIsAdjusting(true); 127 getSelectionModel().clearSelection(); 123 128 for (int row : selectedRows) { 124 129 row--; 125 listSelectionModel.addSelectionInterval(row, row); 126 } 130 getSelectionModel().addSelectionInterval(row, row); 131 } 132 getSelectionModel().setValueIsAdjusting(false); 127 133 fireMakeMemberVisible(selectedRows[0] - 1); 128 134 } … … 141 147 fireTableDataChanged(); 142 148 getSelectionModel(); 143 listSelectionModel.clearSelection(); 149 getSelectionModel().setValueIsAdjusting(true); 150 getSelectionModel().clearSelection(); 144 151 for (int row : selectedRows) { 145 152 row++; 146 listSelectionModel.addSelectionInterval(row, row); 147 } 153 getSelectionModel().addSelectionInterval(row, row); 154 } 155 getSelectionModel().setValueIsAdjusting(false); 148 156 fireMakeMemberVisible(selectedRows[0] + 1); 149 157 } … … 290 298 } 291 299 fireTableDataChanged(); 300 getSelectionModel().setValueIsAdjusting(true); 292 301 getSelectionModel().clearSelection(); 293 302 for (int i = 0; i < primitives.size(); i++) { 294 303 getSelectionModel().addSelectionInterval(idx + i, idx + i); 295 304 } 305 getSelectionModel().setValueIsAdjusting(false); 296 306 fireMakeMemberVisible(idx); 297 307 } … … 307 317 } 308 318 fireTableDataChanged(); 319 getSelectionModel().setValueIsAdjusting(true); 309 320 getSelectionModel().clearSelection(); 310 321 for (int i = 0; i < primitives.size(); i++) { 311 322 getSelectionModel().addSelectionInterval(idx + 1 + i, idx + 1 + i); 312 323 } 324 getSelectionModel().setValueIsAdjusting(false); 313 325 fireMakeMemberVisible(idx + 1); 314 326 } … … 361 373 } 362 374 375 /** 376 * Replies the set of selected referers. Never null, but may be empty. 377 * 378 * @return the set of selected referers 379 */ 380 public Set<OsmPrimitive> getSelectedReferers() { 381 HashSet<OsmPrimitive> ret = new HashSet<OsmPrimitive>(); 382 for (RelationMember m: getSelectedMembers()) { 383 ret.add(m.member); 384 } 385 return ret; 386 } 387 388 /** 389 * Replies true, if the selected {@see OsmPrimitive}s in the layer belonging 390 * to this model are in sync with the selected referers in this model. 391 * 392 * @return 393 */ 394 public boolean selectionsAreInSync() { 395 HashSet<OsmPrimitive> s1 = new HashSet<OsmPrimitive>(getSelectedReferers()); 396 if (s1.size() > layer.data.getSelected().size()) return false; 397 s1.removeAll(layer.data.getSelected()); 398 return s1.isEmpty(); 399 } 363 400 /** 364 401 * Selects the members in the collection selectedMembers … … 386 423 // 387 424 Collections.sort(selectedIndices); 425 getSelectionModel().setValueIsAdjusting(true); 388 426 getSelectionModel().clearSelection(); 389 427 for (int row : selectedIndices) { 390 428 getSelectionModel().addSelectionInterval(row, row); 391 429 } 430 getSelectionModel().setValueIsAdjusting(false); 392 431 393 432 // make the first selected member visible … … 441 480 } 442 481 return false; 482 } 483 484 /** 485 * Selects all mebers which refer to {@see OsmPrimitive}s in the collections 486 * <code>primitmives</code>. Does nothing is primitives is null. 487 * 488 * @param primitives the collection of primitives 489 */ 490 public void selectMembersReferringTo(Collection<? extends OsmPrimitive> primitives) { 491 if (primitives == null || primitives.isEmpty()) return; 492 getSelectionModel().setValueIsAdjusting(true); 493 getSelectionModel().clearSelection(); 494 for (int i=0; i< members.size();i++) { 495 RelationMember m = members.get(i); 496 if (primitives.contains(m.member)) { 497 this.getSelectionModel().addSelectionInterval(i,i); 498 } 499 } 500 getSelectionModel().setValueIsAdjusting(false); 501 if (getSelectedIndices().size() > 0) { 502 fireMakeMemberVisible(getSelectedIndices().get(0)); 503 } 504 } 505 506 /** 507 * Replies true if the layer this model belongs to is equal to the active 508 * layer 509 * 510 * @return true if the layer this model belongs to is equal to the active 511 * layer 512 */ 513 protected boolean isActiveLayer() { 514 if (Main.map == null || Main.map.mapView == null) return false; 515 return Main.map.mapView.getActiveLayer() == layer; 516 } 517 518 519 /* ------------------------------------------------------------------------- */ 520 /* Interface SelectionChangedListener */ 521 /* ------------------------------------------------------------------------- */ 522 public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) { 523 // ignore selection change events if they happen for a dataset in another 524 // layer 525 if (!isActiveLayer()) return; 526 selectMembersReferringTo(newSelection); 443 527 } 444 528 -
trunk/src/org/openstreetmap/josm/gui/dialogs/relation/TagCellEditor.java
r1762 r1916 24 24 static private Logger logger = Logger.getLogger(TagCellEditor.class.getName()); 25 25 26 private TagFieldEditoreditor = null;26 private AutoCompletingTextField editor = null; 27 27 private TagModel currentTag = null; 28 28 private TagEditorModel tagEditorModel = null; … … 39 39 */ 40 40 public TagCellEditor() { 41 editor = new TagFieldEditor();41 editor = new AutoCompletingTextField(); 42 42 acCache = new AutoCompletionCache(); 43 43 } … … 59 59 return; 60 60 } 61 62 61 autoCompletionList.clear(); 63 62 … … 90 89 */ 91 90 protected void initAutoCompletionListForValues(String forKey) { 92 93 91 if (autoCompletionList == null) { 94 92 logger.warning("autoCompletionList is null. Make sure an instance of AutoCompletionList is injected into TableCellEditor."); … … 96 94 } 97 95 autoCompletionList.clear(); 98 99 96 for (String value : acCache.getValues(forKey)) { 100 97 autoCompletionList.add( … … 193 190 } 194 191 195 public TagFieldEditorgetEditor() {192 public AutoCompletingTextField getEditor() { 196 193 return editor; 197 194 } -
trunk/src/org/openstreetmap/josm/gui/dialogs/relation/ac/AutoCompletionCache.java
r1762 r1916 3 3 import java.util.ArrayList; 4 4 import java.util.Collection; 5 import java.util.Collections; 5 6 import java.util.HashMap; 6 7 import java.util.List; 8 import java.util.logging.Logger; 7 9 8 10 import org.openstreetmap.josm.data.osm.OsmPrimitive; 11 import org.openstreetmap.josm.data.osm.Relation; 12 import org.openstreetmap.josm.data.osm.RelationMember; 9 13 import org.openstreetmap.josm.gui.layer.Layer; 10 14 import org.openstreetmap.josm.gui.layer.OsmDataLayer; … … 29 33 */ 30 34 public class AutoCompletionCache { 35 static private final Logger logger = Logger.getLogger(AutoCompletionCache.class.getName()); 31 36 32 37 private static HashMap<OsmDataLayer, AutoCompletionCache> caches; 38 33 39 static { 34 40 caches = new HashMap<OsmDataLayer, AutoCompletionCache>(); … … 63 69 /** the cache */ 64 70 private HashMap<String, ArrayList<String>> cache; 71 private ArrayList<String> roleCache; 65 72 private OsmDataLayer layer; 66 73 … … 70 77 public AutoCompletionCache(OsmDataLayer layer) { 71 78 cache = new HashMap<String, ArrayList<String>>(); 79 roleCache = new ArrayList<String>(); 72 80 this.layer = layer; 73 81 } … … 114 122 String value = primitive.get(key); 115 123 cacheValue(key, value); 124 } 125 } 126 127 /** 128 * Caches all member roles of the relation <code>relation</code> 129 * 130 * @param relation the relation 131 */ 132 protected void cacheRelationMemberRoles(Relation relation){ 133 for (RelationMember m: relation.members) { 134 if (m.role == null || m.role.trim().equals("")) { 135 continue; 136 } 137 if (!roleCache.contains(m.role)) { 138 roleCache.add(m.role); 139 } 116 140 } 117 141 } … … 130 154 cachePrimitive(primitive); 131 155 } 156 for (Relation relation : layer.data.relations) { 157 if (relation.incomplete || relation.deleted) { 158 continue; 159 } 160 cacheRelationMemberRoles(relation); 161 Collections.sort(roleCache); 162 } 132 163 } 133 164 … … 151 182 if (!cache.containsKey(key)) 152 183 return new ArrayList<String>(); 153 else 154 return cache.get(key); 184 return cache.get(key); 185 } 186 187 /** 188 * Replies the list of member roles 189 * 190 * @return the list of member roles 191 */ 192 public List<String> getMemberRoles() { 193 return roleCache; 194 } 195 196 /** 197 * Populates the an {@see AutoCompletionList} with the currently cached 198 * member roles. 199 * 200 * @param list the list to populate 201 */ 202 public void populateWithMemberRoles(AutoCompletionList list) { 203 list.clear(); 204 for (String role: roleCache) { 205 list.add(new AutoCompletionListItem(role, AutoCompletionItemPritority.IS_IN_DATASET)); 206 } 155 207 } 156 208 }
Note:
See TracChangeset
for help on using the changeset viewer.