- Timestamp:
- 2008-08-17T12:36:04+02:00 (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/dialogs/RelationEditor.java
r792 r803 1 1 package org.openstreetmap.josm.gui.dialogs; 2 2 3 import static org.openstreetmap.josm.tools.I18n.marktr; 3 4 import static org.openstreetmap.josm.tools.I18n.tr; 4 import static org.openstreetmap.josm.tools.I18n.marktr;5 5 6 6 import java.awt.BorderLayout; … … 14 14 import java.beans.PropertyChangeListener; 15 15 import java.io.IOException; 16 import java.text.Collator; 16 17 import java.util.ArrayList; 18 import java.util.Collections; 19 import java.util.Comparator; 17 20 import java.util.Map.Entry; 18 21 19 22 import javax.swing.JButton; 20 import javax.swing.JDialog;21 23 import javax.swing.JFrame; 22 24 import javax.swing.JLabel; … … 48 50 /** 49 51 * This dialog is for editing relations. 50 * 52 * 51 53 * In the basic form, it provides two tables, one with the relation tags 52 * and one with the relation members. (Relation tags can be edited through 53 * the normal properties dialog as well, if you manage to get a relation 54 * and one with the relation members. (Relation tags can be edited through 55 * the normal properties dialog as well, if you manage to get a relation 54 56 * selected!) 55 * 57 * 56 58 * @author Frederik Ramm <frederik@remote.org> 57 59 * … … 66 68 private final Relation clone; 67 69 private JLabel status; 68 70 69 71 /** 70 72 * The property data. … … 90 92 } 91 93 }; 92 94 93 95 /** 94 96 * The properties and membership lists. … … 96 98 private final JTable propertyTable = new JTable(propertyData); 97 99 private final JTable memberTable = new JTable(memberData); 98 100 101 /** 102 * Collator for sorting the roles and entries of the member table. 103 */ 104 private static final Collator collator; 105 static { 106 collator = Collator.getInstance(); 107 collator.setStrength(Collator.PRIMARY); 108 } 109 110 /** 111 * Compare role strings. 112 */ 113 private static int compareRole(String s1, String s2) { 114 int last1 = s1.lastIndexOf('_'); 115 if (last1 > 0) { 116 int last2 = s2.lastIndexOf('_'); 117 if (last2 == last1) { 118 String prefix1 = s1.substring(0, last1); 119 String prefix2 = s2.substring(0, last2); 120 121 if (prefix1.equalsIgnoreCase(prefix2)) { 122 // Both roles have the same prefix, now determine the 123 // suffix. 124 String suffix1 = s1.substring(last1 + 1, s1.length()); 125 String suffix2 = s2.substring(last2 + 1, s2.length()); 126 127 if (suffix1.matches("\\d+") && suffix2.matches("\\d+")) { 128 // Suffix is an number -> compare it. 129 int i1 = Integer.parseInt(suffix1); 130 int i2 = Integer.parseInt(suffix2); 131 132 return i1 - i2; 133 } 134 } 135 } 136 } 137 138 // Default handling if the role name is nothing like "stop_xx" 139 return collator.compare(s1, s2); 140 } 141 142 143 /** 144 * Compare two OsmPrimitives. 145 */ 146 private static int compareMemebers(OsmPrimitive o1, OsmPrimitive o2) { 147 return collator.compare(o1.getName(), o2.getName()); 148 } 149 150 private final Comparator<RelationMember> memberComparator = new Comparator<RelationMember>() { 151 public int compare(RelationMember r1, RelationMember r2) { 152 int roleResult = compareRole(r1.role, r2.role); 153 154 if (roleResult == 0) { 155 return compareMemebers(r1.member, r2.member); 156 } 157 158 return roleResult; 159 } 160 }; 161 99 162 /** 100 163 * Creates a new relation editor for the given relation. The relation 101 164 * will be saved if the user selects "ok" in the editor. 102 * 165 * 103 166 * If no relation is given, will create an editor for a new relation. 104 * 167 * 105 168 * @param relation relation to edit, or null to create a new one. 106 169 */ 107 170 public RelationEditor(Relation relation) 108 171 { 109 super(relation == null ? tr("Create new relation") : 172 super(relation == null ? tr("Create new relation") : 110 173 relation.id == 0 ? tr ("Edit new relation") : 111 174 tr("Edit relation #{0}", relation.id)); 112 175 this.relation = relation; 113 176 114 177 if (relation == null) { 115 178 // create a new relation … … 117 180 } else { 118 181 // edit an existing relation 119 this.clone = new Relation(relation); 120 } 121 182 this.clone = new Relation(relation); 183 Collections.sort(this.clone.members, memberComparator); 184 } 185 122 186 getContentPane().setLayout(new BorderLayout()); 123 187 JTabbedPane tabPane = new JTabbedPane(); 124 188 getContentPane().add(tabPane, BorderLayout.CENTER); 125 189 126 190 // (ab)use JOptionPane to make this look familiar; 127 191 // hook up with JOptionPane's property change event 128 192 // to detect button click 129 final JOptionPane okcancel = new JOptionPane("", 193 final JOptionPane okcancel = new JOptionPane("", 130 194 JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION, null); 131 195 getContentPane().add(okcancel, BorderLayout.SOUTH); 132 196 133 197 okcancel.addPropertyChangeListener(new PropertyChangeListener() { 134 198 public void propertyChange(PropertyChangeEvent event) { … … 155 219 getContentPane().add(help, BorderLayout.NORTH); 156 220 try { setAlwaysOnTop(true); } catch (SecurityException sx) {} 157 158 // Basic Editor panel has two blocks; 221 222 // Basic Editor panel has two blocks; 159 223 // a tag table at the top and a membership list below. 160 224 161 225 // setting up the properties table 162 226 163 227 propertyData.setColumnIdentifiers(new String[]{tr("Key"),tr("Value")}); 164 228 propertyTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); … … 167 231 if (tme.getType() == TableModelEvent.UPDATE) { 168 232 int row = tme.getFirstRow(); 169 233 170 234 if (!(tme.getColumn() == 0 && row == propertyData.getRowCount() -1)) { 171 235 clone.entrySet().clear(); … … 181 245 }); 182 246 propertyTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE); 183 247 184 248 // setting up the member table 185 249 186 250 memberData.setColumnIdentifiers(new String[]{tr("Role"),tr("Occupied By")}); 187 251 memberTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 188 252 memberTable.getColumnModel().getColumn(1).setCellRenderer(new OsmPrimitivRenderer()); 189 /*190 memberTable.getColumnModel().getColumn(1).setCellRenderer(new DefaultTableCellRenderer() {191 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {192 Component c = super.getTableCellRendererComponent(table, value, isSelected, false, row, column);193 if (c instanceof JLabel) {194 ((OsmPrimitive)value).visit(nameVisitor);195 ((JLabel)c).setText(nameVisitor.name);196 }197 return c;198 }199 });200 */201 253 memberData.addTableModelListener(new TableModelListener() { 202 254 public void tableChanged(TableModelEvent tme) { … … 209 261 memberTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE); 210 262 211 263 212 264 // combine both tables and wrap them in a scrollPane 213 265 JPanel bothTables = new JPanel(); … … 217 269 bothTables.add(status = new JLabel(tr("Members")), GBC.eol().fill(GBC.HORIZONTAL)); 218 270 bothTables.add(new JScrollPane(memberTable), GBC.eol().fill(GBC.BOTH)); 219 271 220 272 JPanel buttonPanel = new JPanel(new GridLayout(1,3)); 221 222 buttonPanel.add(createButton(marktr("Add Selected"),"addselected", tr("Add all currently selected objects as members"), KeyEvent.VK_A, new ActionListener() { 273 274 buttonPanel.add(createButton(marktr("Add Selected"),"addselected", 275 tr("Add all currently selected objects as members"), KeyEvent.VK_A, new ActionListener() { 223 276 public void actionPerformed(ActionEvent e) { 224 277 addSelected(); … … 226 279 })); 227 280 228 buttonPanel.add(createButton(marktr("Delete Selected"),"deleteselected", tr("Delete all currently selected objects from releation"), KeyEvent.VK_R, new ActionListener() { 281 buttonPanel.add(createButton(marktr("Delete Selected"),"deleteselected", 282 tr("Delete all currently selected objects from releation"), KeyEvent.VK_R, new ActionListener() { 229 283 public void actionPerformed(ActionEvent e) { 230 284 deleteSelected(); … … 232 286 })); 233 287 234 buttonPanel.add(createButton(marktr("Delete"),"delete", tr("Remove the member in the current table row from this relation"), KeyEvent.VK_D, new ActionListener() { 288 buttonPanel.add(createButton(marktr("Delete"),"delete", 289 tr("Remove the member in the current table row from this relation"), KeyEvent.VK_D, new ActionListener() { 235 290 public void actionPerformed(ActionEvent e) { 236 291 int[] rows = memberTable.getSelectedRows(); … … 245 300 })); 246 301 247 buttonPanel.add(createButton(marktr("Select"),"select", tr("Highlight the member from the current table row as JOSM's selection"), KeyEvent.VK_S, new ActionListener() { 302 buttonPanel.add(createButton(marktr("Select"),"select", 303 tr("Highlight the member from the current table row as JOSM's selection"), KeyEvent.VK_S, new ActionListener() { 248 304 public void actionPerformed(ActionEvent e) { 249 305 int[] rows = memberTable.getSelectedRows(); … … 253 309 } 254 310 })); 255 buttonPanel.add(createButton(marktr("Download Members"),"down", tr("Download all incomplete ways and nodes in relation"), KeyEvent.VK_L, new ActionListener() { 311 buttonPanel.add(createButton(marktr("Download Members"),"down", 312 tr("Download all incomplete ways and nodes in relation"), KeyEvent.VK_L, new ActionListener() { 256 313 public void actionPerformed(ActionEvent e) { 257 314 downloadRelationMembers(); … … 269 326 setLocationRelativeTo(Main.parent); 270 327 } 271 328 272 329 private void refreshTables() { 273 274 330 // re-load property data 275 331 276 332 propertyData.setRowCount(0); 277 333 for (Entry<String, String> e : clone.entrySet()) { … … 279 335 } 280 336 propertyData.addRow(new Object[]{"", ""}); 281 337 282 338 // re-load membership data 283 339 284 340 memberData.setRowCount(0); 285 341 for (RelationMember em : clone.members) { … … 288 344 status.setText(tr("Members: {0}", clone.members.size())); 289 345 } 290 346 291 347 private JButton createButton(String name, String iconName, String tooltip, int mnemonic, ActionListener actionListener) { 292 348 JButton b = new JButton(tr(name), ImageProvider.get("dialogs", iconName)); … … 298 354 return b; 299 355 } 300 356 301 357 private void addSelected() { 302 358 for (OsmPrimitive p : Main.ds.getSelected()) { … … 336 392 } 337 393 338 private void downloadRelationMembers(){339 340 boolean download = false; 341 for (RelationMember member : clone.members) {342 if (member.member.incomplete) { 343 download = true;344 break; 345 346 } 347 if (download) { 348 OsmServerObjectReader reader = new OsmServerObjectReader(); 349 try { 350 DataSet dataSet = reader.parseOsm(clone.id, 351 OsmServerObjectReader.TYPE_REL, true); 352 if (dataSet != null) { 353 final MergeVisitor visitor = new MergeVisitor(Main.main 354 .editLayer().data, dataSet); 355 for (final OsmPrimitive osm : dataSet.allPrimitives()) 356 osm.visit(visitor);357 visitor.fixReferences(); 358 359 // copy the merged layer's data source info 360 for (DataSource src : dataSet.dataSources) 361 Main.main.editLayer().data.dataSources.add(src);362 Main.main.editLayer().fireDataChange(); 363 364 if (visitor.conflicts.isEmpty()) 365 return;366 final ConflictDialog dlg = Main.map.conflictDialog;367 dlg.add(visitor.conflicts); 368 JOptionPane.showMessageDialog(Main.parent, 369 tr("There were conflicts during import.")); 370 if (!dlg.isVisible()) 371 dlg.action 372 .actionPerformed(new ActionEvent(this, 0, "")); 373 } 374 375 } catch (SAXException e) { 376 e.printStackTrace(); 377 JOptionPane.showMessageDialog(this,tr("Error parsing server response.")+": "+e.getMessage(), tr("Error"), JOptionPane.ERROR_MESSAGE); 378 379 e.printStackTrace(); 380 JOptionPane.showMessageDialog(this,tr("Cannot connect to server.")+": "+e.getMessage(), tr("Error"), JOptionPane.ERROR_MESSAGE); 381 } 382 383 384 394 private void downloadRelationMembers() { 395 boolean download = false; 396 for (RelationMember member : clone.members) { 397 if (member.member.incomplete) { 398 download = true; 399 break; 400 } 401 } 402 if (download) { 403 OsmServerObjectReader reader = new OsmServerObjectReader(); 404 try { 405 DataSet dataSet = reader.parseOsm(clone.id, 406 OsmServerObjectReader.TYPE_REL, true); 407 if (dataSet != null) { 408 final MergeVisitor visitor = new MergeVisitor(Main.main 409 .editLayer().data, dataSet); 410 for (final OsmPrimitive osm : dataSet.allPrimitives()) 411 osm.visit(visitor); 412 visitor.fixReferences(); 413 414 // copy the merged layer's data source info 415 for (DataSource src : dataSet.dataSources) 416 Main.main.editLayer().data.dataSources.add(src); 417 Main.main.editLayer().fireDataChange(); 418 419 if (visitor.conflicts.isEmpty()) 420 return; 421 final ConflictDialog dlg = Main.map.conflictDialog; 422 dlg.add(visitor.conflicts); 423 JOptionPane.showMessageDialog(Main.parent, 424 tr("There were conflicts during import.")); 425 if (!dlg.isVisible()) 426 dlg.action 427 .actionPerformed(new ActionEvent(this, 0, "")); 428 } 429 430 } catch (SAXException e) { 431 e.printStackTrace(); 432 JOptionPane.showMessageDialog(this,tr("Error parsing server response.")+": "+e.getMessage(), 433 tr("Error"), JOptionPane.ERROR_MESSAGE); 434 } catch (IOException e) { 435 e.printStackTrace(); 436 JOptionPane.showMessageDialog(this,tr("Cannot connect to server.")+": "+e.getMessage(), 437 tr("Error"), JOptionPane.ERROR_MESSAGE); 438 } 439 } 440 } 385 441 }
Note:
See TracChangeset
for help on using the changeset viewer.