- Timestamp:
- 2009-12-03T19:02:25+01:00 (15 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 3 added
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/actions/OpenFileAction.java
r2512 r2563 2 2 package org.openstreetmap.josm.actions; 3 3 4 import static org.openstreetmap.josm.gui.help.HelpUtil.ht; 4 5 import static org.openstreetmap.josm.tools.I18n.tr; 5 import static org.openstreetmap.josm.gui.help.HelpUtil.ht;6 6 7 7 import java.awt.event.ActionEvent; … … 86 86 for (File f : files) { 87 87 if (cancelled) return; 88 getProgressMonitor(). subTask(tr("Opening file ''{0}'' ...", f.getAbsolutePath()));88 getProgressMonitor().indeterminateSubTask(tr("Opening file ''{0}'' ...", f.getAbsolutePath())); 89 89 try { 90 90 System.out.println("Open file: " + f.getAbsolutePath() + " (" + f.length() + " bytes)"); -
trunk/src/org/openstreetmap/josm/data/osm/DataSetMerger.java
r2512 r2563 38 38 * to relation members) after the first phase of merging 39 39 */ 40 private Set< Long> childrenToMerge;40 private Set<PrimitiveId> objectsWithChildrenToMerge; 41 41 private Set<OsmPrimitive> deletedObjectsToUnlink; 42 42 … … 57 57 conflicts = new ConflictCollection(); 58 58 mergedMap = new HashMap<Long, Long>(); 59 childrenToMerge = new HashSet<Long>();59 objectsWithChildrenToMerge = new HashSet<PrimitiveId>(); 60 60 deletedObjectsToUnlink = new HashSet<OsmPrimitive>(); 61 61 } … … 75 75 * @param source the other primitive 76 76 */ 77 protected <P extends OsmPrimitive> void mergePrimitive(Psource) {77 protected void mergePrimitive(OsmPrimitive source) { 78 78 if (!source.isNew() ) { 79 79 // try to merge onto a matching primitive with the same … … 112 112 target.setTimestamp(source.getTimestamp()); 113 113 target.setModified(source.isModified()); 114 childrenToMerge.add(source.getUniqueId());114 objectsWithChildrenToMerge.add(source.getPrimitiveId()); 115 115 } 116 116 return; … … 131 131 targetDataSet.addPrimitive(target); 132 132 mergedMap.put(source.getUniqueId(), target.getUniqueId()); 133 childrenToMerge.add(source.getUniqueId());133 objectsWithChildrenToMerge.add(source.getPrimitiveId()); 134 134 } 135 135 … … 154 154 155 155 /** 156 * A way in the target dataset might be incomplete because at least of of its nodes is incomplete. 157 * The nodes might have become complete because a complete node was merged onto into in the 158 * merge operation. 159 * 160 * This method loops over all parent ways of such nodes and turns them into complete ways 161 * if necessary. 162 * 163 * @param other 164 */ 165 protected void fixIncompleteParentWays(Node other) { 166 Node myNode = (Node)getMergeTarget(other); 167 if (myNode == null) 168 throw new RuntimeException(tr("Missing merge target for node with id {0}", other.getUniqueId())); 169 if (myNode.incomplete || myNode.isDeleted() || !myNode.isVisible()) return; 170 wayloop: for (Way w: OsmPrimitive.getFilteredList(myNode.getReferrers(), Way.class)) { 171 if (w.isDeleted() || ! w.isVisible() || ! w.incomplete) { 172 continue; 173 } 174 for (Node n: w.getNodes()) { 175 if (n.incomplete) { 176 continue wayloop; 177 } 178 } 179 // all nodes are complete - set the way complete too 180 w.incomplete = false; 181 } 182 } 183 184 /** 156 185 * Postprocess the dataset and fix all merged references to point to the actual 157 186 * data. … … 159 188 public void fixReferences() { 160 189 for (Way w : sourceDataSet.getWays()) { 161 if (!conflicts.hasConflictForTheir(w) && childrenToMerge.contains(w.getUniqueId())) {190 if (!conflicts.hasConflictForTheir(w) && objectsWithChildrenToMerge.contains(w.getPrimitiveId())) { 162 191 mergeNodeList(w); 163 192 fixIncomplete(w); … … 165 194 } 166 195 for (Relation r : sourceDataSet.getRelations()) { 167 if (!conflicts.hasConflictForTheir(r) && childrenToMerge.contains(r.getUniqueId())) {196 if (!conflicts.hasConflictForTheir(r) && objectsWithChildrenToMerge.contains(r.getPrimitiveId())) { 168 197 mergeRelationMembers(r); 169 198 } … … 175 204 targetDataSet.unlinkReferencesToPrimitive(target); 176 205 } 206 // objectsWithChildrenToMerge also includes complete nodes which have 207 // been merged into their incomplete equivalents. 208 // 209 for (PrimitiveId id: objectsWithChildrenToMerge) { 210 if (!id.getType().equals(OsmPrimitiveType.NODE)) { 211 continue; 212 } 213 Node n = (Node)sourceDataSet.getPrimitiveById(id); 214 if (!conflicts.hasConflictForTheir(n)) { 215 fixIncompleteParentWays(n); 216 } 217 } 218 177 219 } 178 220 … … 269 311 // 270 312 target.mergeFrom(source); 271 childrenToMerge.add(source.getUniqueId());313 objectsWithChildrenToMerge.add(source.getPrimitiveId()); 272 314 } else if (!target.incomplete && source.incomplete) { 273 315 // target is complete and source is incomplete … … 282 324 // otherwise too many conflicts when refreshing from the server 283 325 } else if (target.isDeleted() != source.isDeleted()) { 284 // differences in deleted state have to be resolved manually 326 // differences in deleted state have to be resolved manually. This can 327 // happen if one layer is merged onto another layer 285 328 // 286 329 conflicts.add(target,source); … … 288 331 // target not modified. We can assume that source is the most recent version. 289 332 // clone it into target. But check first, whether source is deleted. if so, 290 // make sure that target is not referenced any more in myDataSet.333 // make sure that target is not referenced any more in myDataSet. 291 334 // 292 335 if (source.isDeleted()) { … … 294 337 } 295 338 target.mergeFrom(source); 296 childrenToMerge.add(source.getUniqueId());339 objectsWithChildrenToMerge.add(source.getPrimitiveId()); 297 340 } else if (! target.isModified() && !source.isModified() && target.getVersion() == source.getVersion()) { 298 341 // both not modified. Keep mine … … 302 345 // 303 346 target.mergeFrom(source); 304 childrenToMerge.add(source.getUniqueId());347 objectsWithChildrenToMerge.add(source.getPrimitiveId()); 305 348 } else if (target.isModified() && ! source.isModified() && target.getVersion() == source.getVersion()) { 306 349 // target is same as source but target is modified … … 318 361 target.mergeFrom(source); 319 362 target.setModified(true); 320 childrenToMerge.add(source.getUniqueId());363 objectsWithChildrenToMerge.add(source.getPrimitiveId()); 321 364 } 322 365 return true; -
trunk/src/org/openstreetmap/josm/gui/DefaultNameFormatter.java
r2512 r2563 7 7 import java.util.ArrayList; 8 8 import java.util.Arrays; 9 import java.util.Collections; 9 10 import java.util.HashSet; 10 11 import java.util.List; … … 199 200 return tr("Changeset {0}",changeset.getId()); 200 201 } 202 203 /** 204 * Builds a default tooltip text for the primitive <code>primitive</code>. 205 * 206 * @param primitive the primitmive 207 * @return the tooltip text 208 */ 209 public String buildDefaultToolTip(OsmPrimitive primitive) { 210 StringBuilder sb = new StringBuilder(); 211 sb.append("<html>"); 212 sb.append("<strong>id</strong>=") 213 .append(primitive.getId()) 214 .append("<br>"); 215 ArrayList<String> keyList = new ArrayList<String>(primitive.keySet()); 216 Collections.sort(keyList); 217 for (int i = 0; i < keyList.size(); i++) { 218 if (i > 0) { 219 sb.append("<br>"); 220 } 221 String key = keyList.get(i); 222 sb.append("<strong>") 223 .append(key) 224 .append("</strong>") 225 .append("="); 226 String value = primitive.get(key); 227 while(value.length() != 0) { 228 sb.append(value.substring(0,Math.min(50, value.length()))); 229 if (value.length() > 50) { 230 sb.append("<br>"); 231 value = value.substring(50); 232 } else { 233 value = ""; 234 } 235 } 236 } 237 sb.append("</html>"); 238 return sb.toString(); 239 } 201 240 } -
trunk/src/org/openstreetmap/josm/gui/dialogs/RelationListDialog.java
r2514 r2563 43 43 import org.openstreetmap.josm.gui.OsmPrimitivRenderer; 44 44 import org.openstreetmap.josm.gui.SideButton; 45 import org.openstreetmap.josm.gui.dialogs.relation. GenericRelationEditor;45 import org.openstreetmap.josm.gui.dialogs.relation.DownloadRelationTask; 46 46 import org.openstreetmap.josm.gui.dialogs.relation.RelationEditor; 47 47 import org.openstreetmap.josm.gui.layer.DataChangeListener; … … 248 248 displaylist.setSelectedIndex(index); 249 249 } 250 popupMenu.show( RelationListDialog.this, p.x, p.y-3);250 popupMenu.show(displaylist, p.x, p.y-3); 251 251 } 252 252 @Override public void mousePressed(MouseEvent e) { … … 500 500 if (relations.isEmpty()) 501 501 return; 502 Main.worker.submit(new GenericRelationEditor.DownloadTask(502 Main.worker.submit(new DownloadRelationTask( 503 503 model.getSelectedNonNewRelations(), 504 Main.map.mapView.getEditLayer(), null)); 504 Main.map.mapView.getEditLayer()) 505 ); 505 506 } 506 507 } -
trunk/src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java
r2243 r2563 169 169 BasicArrowButton arrowButton = new BasicArrowButton(SwingConstants.SOUTH, null, null, Color.BLACK, null); 170 170 arrowButton.setBorder(BorderFactory.createEmptyBorder()); 171 // selectionHistoryMenuButton.setContentAreaFilled(false);172 // selectionHistoryMenuButton.setOpaque(false);173 // selectionHistoryMenuButton.setBorderPainted(false);174 // selectionHistoryMenuButton.setBackground(null);175 171 parentButton.setLayout(new BorderLayout()); 176 172 parentButton.add(arrowButton, BorderLayout.EAST); -
trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java
r2512 r2563 5 5 6 6 import java.awt.BorderLayout; 7 import java.awt.Dialog;8 7 import java.awt.Dimension; 9 8 import java.awt.FlowLayout; 10 9 import java.awt.GridBagConstraints; 11 10 import java.awt.GridBagLayout; 12 import java.awt.Insets;13 11 import java.awt.event.ActionEvent; 14 12 import java.awt.event.FocusAdapter; … … 19 17 import java.awt.event.WindowAdapter; 20 18 import java.awt.event.WindowEvent; 21 import java.io.IOException; 19 import java.beans.PropertyChangeEvent; 20 import java.beans.PropertyChangeListener; 22 21 import java.util.ArrayList; 23 22 import java.util.Collection; … … 30 29 import javax.swing.AbstractAction; 31 30 import javax.swing.BorderFactory; 32 import javax.swing.JButton;33 31 import javax.swing.JComponent; 34 32 import javax.swing.JLabel; … … 38 36 import javax.swing.JSplitPane; 39 37 import javax.swing.JTabbedPane; 40 import javax.swing.JT able;38 import javax.swing.JToolBar; 41 39 import javax.swing.KeyStroke; 42 import javax.swing.SwingUtilities;43 40 import javax.swing.event.ChangeEvent; 44 41 import javax.swing.event.ChangeListener; … … 57 54 import org.openstreetmap.josm.data.osm.DataSet; 58 55 import org.openstreetmap.josm.data.osm.OsmPrimitive; 59 import org.openstreetmap.josm.data.osm.OsmPrimitiveType;60 56 import org.openstreetmap.josm.data.osm.Relation; 61 57 import org.openstreetmap.josm.data.osm.RelationMember; 62 58 import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil; 63 59 import org.openstreetmap.josm.gui.DefaultNameFormatter; 64 import org.openstreetmap.josm.gui.ExceptionDialogUtil;65 60 import org.openstreetmap.josm.gui.HelpAwareOptionPane; 66 import org.openstreetmap.josm.gui.PleaseWaitRunnable;67 61 import org.openstreetmap.josm.gui.SideButton; 68 62 import org.openstreetmap.josm.gui.HelpAwareOptionPane.ButtonSpec; … … 70 64 import org.openstreetmap.josm.gui.help.HelpUtil; 71 65 import org.openstreetmap.josm.gui.layer.OsmDataLayer; 72 import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor;73 import org.openstreetmap.josm.gui.progress.ProgressMonitor;74 66 import org.openstreetmap.josm.gui.tagging.AutoCompletingTextField; 75 67 import org.openstreetmap.josm.gui.tagging.TagEditorPanel; 76 68 import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionCache; 77 69 import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionList; 78 import org.openstreetmap.josm.io.OsmServerBackreferenceReader;79 import org.openstreetmap.josm.io.OsmServerObjectReader;80 import org.openstreetmap.josm.io.OsmTransferException;81 70 import org.openstreetmap.josm.tools.ImageProvider; 82 71 import org.openstreetmap.josm.tools.Shortcut; 83 import org.xml.sax.SAXException;84 72 85 73 /** … … 125 113 // 126 114 memberTableModel = new MemberTableModel(getLayer()); 115 DataSet.selListeners.add(memberTableModel); 116 getLayer().data.addDataSetListener(memberTableModel); 117 getLayer().listenerDataChanged.add(memberTableModel); 127 118 selectionTableModel = new SelectionTableModel(getLayer()); 119 DataSet.selListeners.add(selectionTableModel); 128 120 referrerModel = new ReferringRelationsBrowserModel(relation); 129 121 … … 173 165 ); 174 166 167 getContentPane().add(buildToolBar(), BorderLayout.NORTH); 175 168 getContentPane().add(tabbedPane, BorderLayout.CENTER); 176 169 getContentPane().add(buildOkCancelButtonPanel(), BorderLayout.SOUTH); … … 189 182 memberTableModel.setSelectedMembers(selectedMembers); 190 183 HelpUtil.setHelpContext(getRootPane(),ht("/Dialog/RelationEditor")); 184 } 185 186 /** 187 * Creates the toolbar 188 * 189 * @return the toolbar 190 */ 191 protected JToolBar buildToolBar() { 192 JToolBar tb = new JToolBar(); 193 tb.setFloatable(false); 194 tb.add(new ApplyAction()); 195 tb.add(new DuplicateRelationAction()); 196 DeleteCurrentRelationAction deleteAction = new DeleteCurrentRelationAction(); 197 addPropertyChangeListener(deleteAction); 198 tb.add(deleteAction); 199 return tb; 191 200 } 192 201 … … 280 289 pnl.add(scrollPane, gc); 281 290 291 // --- role editing 292 JPanel p3 = new JPanel(new FlowLayout(FlowLayout.LEFT)); 293 p3.add(new JLabel(tr("Apply Role:"))); 294 tfRole = new AutoCompletingTextField(10); 295 tfRole.setToolTipText(tr("Enter a role and apply it to the selected relation members")); 296 tfRole.addFocusListener(new FocusAdapter() { 297 @Override 298 public void focusGained(FocusEvent e) { 299 tfRole.selectAll(); 300 } 301 }); 302 tfRole.setAutoCompletionList(new AutoCompletionList()); 303 tfRole.addFocusListener( 304 new FocusAdapter() { 305 @Override 306 public void focusGained(FocusEvent e) { 307 AutoCompletionList list = tfRole.getAutoCompletionList(); 308 AutoCompletionCache.getCacheForLayer(Main.main.getEditLayer()).populateWithMemberRoles(list); 309 } 310 } 311 ); 312 p3.add(tfRole); 313 SetRoleAction setRoleAction = new SetRoleAction(); 314 memberTableModel.getSelectionModel().addListSelectionListener(setRoleAction); 315 tfRole.getDocument().addDocumentListener(setRoleAction); 316 tfRole.addActionListener(setRoleAction); 317 memberTableModel.getSelectionModel().addListSelectionListener( 318 new ListSelectionListener() { 319 public void valueChanged(ListSelectionEvent e) { 320 tfRole.setEnabled(memberTable.getSelectedRowCount() > 0); 321 } 322 } 323 ); 324 tfRole.setEnabled(memberTable.getSelectedRowCount() > 0); 325 326 gc.gridx = 1; 327 gc.gridy = 2; 328 gc.fill = GridBagConstraints.BOTH; 329 gc.anchor = GridBagConstraints.CENTER; 330 gc.weightx = 1.0; 331 gc.weighty = 0.0; 332 pnl.add(p3, gc); 333 282 334 JPanel pnl2 = new JPanel(); 283 335 pnl2.setLayout(new GridBagLayout()); … … 326 378 pnl3.setLayout(new BorderLayout()); 327 379 pnl3.add(splitPane, BorderLayout.CENTER); 328 pnl3.add(buildButtonPanel(), BorderLayout.SOUTH);329 380 return pnl3; 330 381 } … … 338 389 JPanel pnl = new JPanel(); 339 390 pnl.setLayout(new BorderLayout()); 340 JTable tbl = new JTable(selectionTableModel, new SelectionTableColumnModel(memberTableModel));341 tbl.set Enabled(false);391 SelectionTable tbl = new SelectionTable(selectionTableModel, new SelectionTableColumnModel(memberTableModel)); 392 tbl.setMemberTableModel(memberTableModel); 342 393 JScrollPane pane = new JScrollPane(tbl); 343 394 pnl.add(pane, BorderLayout.CENTER); … … 371 422 * @return 372 423 */ 373 protected JPanel buildLeftButtonPanel() { 374 JPanel pnl = new JPanel(); 375 pnl.setLayout(new GridBagLayout()); 376 377 GridBagConstraints gc = new GridBagConstraints(); 378 gc.gridx = 0; 379 gc.gridy = 0; 380 gc.gridheight = 1; 381 gc.gridwidth = 1; 382 gc.insets = new Insets(0, 5, 0, 5); 383 gc.fill = GridBagConstraints.HORIZONTAL; 384 gc.anchor = GridBagConstraints.CENTER; 385 gc.weightx = 0.0; 386 gc.weighty = 0.0; 387 388 // ----- 389 gc.gridy = 0; 424 protected JToolBar buildLeftButtonPanel() { 425 JToolBar tb = new JToolBar(); 426 tb.setOrientation(JToolBar.VERTICAL); 427 tb.setFloatable(false); 428 429 // -- move up action 390 430 MoveUpAction moveUpAction = new MoveUpAction(); 391 431 memberTableModel.getSelectionModel().addListSelectionListener(moveUpAction); 392 pnl.add(new JButton(moveUpAction), gc); 393 394 // ----- 395 gc.gridy = 1; 432 tb.add(moveUpAction); 433 434 // -- move down action 396 435 MoveDownAction moveDownAction = new MoveDownAction(); 397 436 memberTableModel.getSelectionModel().addListSelectionListener(moveDownAction); 398 pnl.add(new JButton(moveDownAction), gc); 437 tb.add(moveDownAction); 438 439 tb.addSeparator(); 399 440 400 441 // -- edit action 401 gc.gridy = 2;402 442 EditAction editAction = new EditAction(); 403 443 memberTableModel.getSelectionModel().addListSelectionListener(editAction); 404 pnl.add(new JButton(editAction),gc); 405 406 // ------ 407 gc.gridy = 3; 444 tb.add(editAction); 445 446 // -- delete action 408 447 RemoveAction removeSelectedAction = new RemoveAction(); 409 448 memberTable.getSelectionModel().addListSelectionListener(removeSelectedAction); 410 pnl.add(new JButton(removeSelectedAction), gc); 411 412 // ------ 413 gc.gridy = 4; 414 SelectPrimitivesForSelectedMembersAction selectAction = new SelectPrimitivesForSelectedMembersAction(); 415 memberTable.getSelectionModel().addListSelectionListener(selectAction); 416 pnl.add(new JButton(selectAction), gc); 417 418 // ------ 419 gc.gridy = 5; 449 tb.add(removeSelectedAction); 450 451 tb.addSeparator(); 452 // -- sort action 420 453 SortAction sortAction = new SortAction(); 421 pnl.add(new JButton(sortAction), gc); 422 423 // ------ 424 // just grab the remaining space 425 gc.gridy = 6; 426 gc.weighty = 1.0; 427 gc.fill = GridBagConstraints.BOTH; 428 pnl.add(new JPanel(), gc); 429 return pnl; 454 tb.add(sortAction); 455 456 tb.addSeparator(); 457 458 // -- download action 459 DownloadIncompleteMembersAction downloadIncompleteMembersAction = new DownloadIncompleteMembersAction(); 460 memberTable.getModel().addTableModelListener(downloadIncompleteMembersAction); 461 tb.add(downloadIncompleteMembersAction); 462 463 // -- download selected action 464 DownloadSelectedIncompleteMembersAction downloadSelectedIncompleteMembersAction = new DownloadSelectedIncompleteMembersAction(); 465 memberTable.getModel().addTableModelListener(downloadSelectedIncompleteMembersAction); 466 memberTable.getSelectionModel().addListSelectionListener(downloadSelectedIncompleteMembersAction); 467 tb.add(downloadSelectedIncompleteMembersAction); 468 469 return tb; 430 470 } 431 471 … … 435 475 * @return 436 476 */ 437 protected JPanel buildSelectionControlButtonPanel() { 438 JPanel pnl = new JPanel(); 439 pnl.setLayout(new GridBagLayout()); 440 441 GridBagConstraints gc = new GridBagConstraints(); 442 gc.gridx = 0; 443 gc.gridy = 0; 444 gc.gridheight = 1; 445 gc.gridwidth = 1; 446 gc.insets = new Insets(0, 5, 0, 5); 447 gc.fill = GridBagConstraints.HORIZONTAL; 448 gc.anchor = GridBagConstraints.CENTER; 449 gc.weightx = 0.0; 450 gc.weighty = 0.0; 477 protected JToolBar buildSelectionControlButtonPanel() { 478 JToolBar tb = new JToolBar(JToolBar.VERTICAL); 479 tb.setFloatable(false); 480 481 482 // -- add at end action 451 483 AddSelectedAtEndAction addSelectedAtEndAction = new AddSelectedAtEndAction(); 452 484 selectionTableModel.addTableModelListener(addSelectedAtEndAction); 453 pnl.add(new JButton(addSelectedAtEndAction), gc); 454 455 // ----- 456 gc.gridy = 1; 485 tb.add(addSelectedAtEndAction); 486 487 // -- select members action 457 488 SelectedMembersForSelectionAction selectMembersForSelectionAction = new SelectedMembersForSelectionAction(); 458 489 selectionTableModel.addTableModelListener(selectMembersForSelectionAction); 459 490 memberTableModel.addTableModelListener(selectMembersForSelectionAction); 460 pnl.add(new JButton(selectMembersForSelectionAction), gc); 461 462 // ----- 463 gc.gridy = 2; 491 tb.add(selectMembersForSelectionAction); 492 493 tb.addSeparator(); 494 495 // -- remove selected action 464 496 RemoveSelectedAction removeSelectedAction = new RemoveSelectedAction(); 465 497 selectionTableModel.addTableModelListener(removeSelectedAction); 466 pnl.add(new JButton(removeSelectedAction), gc); 467 468 // ------ 469 // just grab the remaining space 470 gc.gridy = 3; 471 gc.weighty = 1.0; 472 gc.fill = GridBagConstraints.BOTH; 473 pnl.add(new JPanel(), gc); 474 475 // ----- 476 gc.gridy = 4; 477 gc.weighty = 0.0; 498 tb.add(removeSelectedAction); 499 500 // -- select action 501 SelectPrimitivesForSelectedMembersAction selectAction = new SelectPrimitivesForSelectedMembersAction(); 502 memberTable.getSelectionModel().addListSelectionListener(selectAction); 503 tb.add(selectAction); 504 505 tb.addSeparator(); 506 507 // -- add at start action 478 508 AddSelectedAtStartAction addSelectionAction = new AddSelectedAtStartAction(); 479 509 selectionTableModel.addTableModelListener(addSelectionAction); 480 pnl.add(new JButton(addSelectionAction), gc); 481 482 // ----- 483 gc.gridy = 5; 510 tb.add(addSelectionAction); 511 512 // -- add before selected action 484 513 AddSelectedBeforeSelection addSelectedBeforeSelectionAction = new AddSelectedBeforeSelection(); 485 514 selectionTableModel.addTableModelListener(addSelectedBeforeSelectionAction); 486 515 memberTableModel.getSelectionModel().addListSelectionListener(addSelectedBeforeSelectionAction); 487 pnl.add(new JButton(addSelectedBeforeSelectionAction), gc); 488 489 // ----- 490 gc.gridy = 6; 516 tb.add(addSelectedBeforeSelectionAction); 517 518 // -- add after selected action 491 519 AddSelectedAfterSelection addSelectedAfterSelectionAction = new AddSelectedAfterSelection(); 492 520 selectionTableModel.addTableModelListener(addSelectedAfterSelectionAction); 493 521 memberTableModel.getSelectionModel().addListSelectionListener(addSelectedAfterSelectionAction); 494 pnl.add(new JButton(addSelectedAfterSelectionAction), gc); 495 496 return pnl; 497 } 498 499 /** 500 * Creates the buttons for the basic editing layout 501 * @return {@see JPanel} with basic buttons 502 */ 503 protected JPanel buildButtonPanel() { 504 JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); 505 506 // --- download members 507 buttonPanel.add(new SideButton(new DownlaodAction())); 508 509 // --- role editing 510 buttonPanel.add(new JLabel(tr("Role:"))); 511 tfRole = new AutoCompletingTextField(10); 512 tfRole.addFocusListener(new FocusAdapter() { 513 @Override 514 public void focusGained(FocusEvent e) { 515 tfRole.selectAll(); 516 } 517 }); 518 tfRole.setAutoCompletionList(new AutoCompletionList()); 519 tfRole.addFocusListener( 520 new FocusAdapter() { 521 @Override 522 public void focusGained(FocusEvent e) { 523 AutoCompletionList list = tfRole.getAutoCompletionList(); 524 AutoCompletionCache.getCacheForLayer(Main.main.getEditLayer()).populateWithMemberRoles(list); 525 } 526 } 527 ); 528 529 buttonPanel.add(tfRole); 530 SetRoleAction setRoleAction = new SetRoleAction(); 531 memberTableModel.getSelectionModel().addListSelectionListener(setRoleAction); 532 buttonPanel.add(new SideButton(setRoleAction)); 533 tfRole.getDocument().addDocumentListener(setRoleAction); 534 tfRole.addActionListener(setRoleAction); 535 536 // --- copy relation action 537 buttonPanel.add(new SideButton(new DuplicateRelationAction())); 538 539 // --- apply relation action 540 buttonPanel.add(new SideButton(new ApplyAction())); 541 542 // --- delete relation action 543 buttonPanel.add(new SideButton(new DeleteCurrentRelationAction())); 544 return buttonPanel; 522 tb.add(addSelectedAfterSelectionAction); 523 524 return tb; 545 525 } 546 526 … … 548 528 protected Dimension findMaxDialogSize() { 549 529 // FIXME: Make it remember dialog size 550 return new Dimension(700, 500); 551 } 552 553 @Override 554 public void dispose() { 555 selectionTableModel.unregister(); 556 DataSet.selListeners.remove(memberTableModel); 557 super.dispose(); 530 return new Dimension(700, 650); 558 531 } 559 532 … … 561 534 public void setVisible(boolean visible) { 562 535 if (visible) { 563 tagEditorPanel.initAutoCompletion( Main.main.getEditLayer());536 tagEditorPanel.initAutoCompletion(getLayer()); 564 537 } 565 538 super.setVisible(visible); 566 539 if (!visible) { 540 // make sure all registered listeners are unregistered 541 // 542 selectionTableModel.unregister(); 543 DataSet.selListeners.remove(memberTableModel); 544 DataSet.selListeners.remove(selectionTableModel); 545 getLayer().data.removeDataSetListener(memberTableModel); 546 getLayer().listenerDataChanged.remove(memberTableModel); 567 547 dispose(); 568 548 } … … 888 868 } 889 869 890 class SortAction extends AbstractAction {870 class SortAction extends AbstractAction implements ListSelectionListener { 891 871 public SortAction() { 892 872 putValue(SHORT_DESCRIPTION, tr("Sort the relation members")); 893 873 putValue(SMALL_ICON, ImageProvider.get("dialogs", "sort")); 894 //putValue(NAME, tr("Sort"));874 putValue(NAME, tr("Sort")); 895 875 Shortcut.registerShortcut("relationeditor:sort", tr("Relation Editor: Sort"), KeyEvent.VK_T, 896 876 Shortcut.GROUP_MNEMONIC); 897 //setEnabled(false);877 updateEnabledState(); 898 878 } 899 879 900 880 public void actionPerformed(ActionEvent e) { 901 881 memberTableModel.sort(); 882 } 883 884 protected void updateEnabledState() { 885 setEnabled(memberTable.getSelectedRowCount() > 0); 886 } 887 888 public void valueChanged(ListSelectionEvent e) { 889 updateEnabledState(); 902 890 } 903 891 } … … 960 948 } 961 949 962 class DeleteCurrentRelationAction extends AbstractAction {950 class DeleteCurrentRelationAction extends AbstractAction implements PropertyChangeListener{ 963 951 public DeleteCurrentRelationAction() { 964 952 putValue(SHORT_DESCRIPTION, tr("Delete the currently edited relation")); … … 983 971 984 972 protected void updateEnabledState() { 985 setEnabled(getRelation() != null); 973 setEnabled(getRelationSnapshot() != null); 974 } 975 976 public void propertyChange(PropertyChangeEvent evt) { 977 if (evt.getPropertyName().equals(RELATION_SNAPSHOT_PROP)) { 978 updateEnabledState(); 979 } 986 980 } 987 981 } … … 1187 1181 } 1188 1182 1189 class Downl aodAction extends AbstractAction{1190 public Downl aodAction() {1191 putValue(SHORT_DESCRIPTION, tr("Download all incomplete ways and nodes in relation"));1192 putValue(SMALL_ICON, ImageProvider.get("dialogs ", "downloadincomplete"));1183 class DownloadIncompleteMembersAction extends AbstractAction implements TableModelListener { 1184 public DownloadIncompleteMembersAction() { 1185 putValue(SHORT_DESCRIPTION, tr("Download all incomplete members")); 1186 putValue(SMALL_ICON, ImageProvider.get("dialogs/relation", "downloadincomplete")); 1193 1187 putValue(NAME, tr("Download Members")); 1194 1188 Shortcut.registerShortcut("relationeditor:downloadincomplete", tr("Relation Editor: Download Members"), … … 1200 1194 if (!isEnabled()) 1201 1195 return; 1202 Main.worker.submit(new DownloadTask( 1203 Collections.singletonList(getRelation()), 1196 Main.worker.submit(new DownloadRelationMemberTask( 1197 getRelation(), 1198 memberTableModel.getIncompleteMemberPrimitives(), 1204 1199 getLayer(), 1205 1200 memberTableModel, … … 1209 1204 1210 1205 protected void updateEnabledState() { 1211 setEnabled(getRelation() != null && !getRelation().isNew()); 1206 setEnabled( 1207 getRelation() != null 1208 && !getRelation().isNew() 1209 && memberTableModel.hasIncompleteMembers() 1210 ); 1211 } 1212 1213 public void tableChanged(TableModelEvent e) { 1214 updateEnabledState(); 1215 } 1216 } 1217 1218 class DownloadSelectedIncompleteMembersAction extends AbstractAction implements ListSelectionListener, TableModelListener{ 1219 public DownloadSelectedIncompleteMembersAction() { 1220 putValue(SHORT_DESCRIPTION, tr("Download selected incomplete members")); 1221 putValue(SMALL_ICON, ImageProvider.get("dialogs/relation", "downloadincompleteselected")); 1222 putValue(NAME, tr("Download Members")); 1223 Shortcut.registerShortcut("relationeditor:downloadincomplete", tr("Relation Editor: Download Members"), 1224 KeyEvent.VK_K, Shortcut.GROUP_MNEMONIC); 1225 updateEnabledState(); 1226 } 1227 1228 public void actionPerformed(ActionEvent e) { 1229 if (!isEnabled()) 1230 return; 1231 Main.worker.submit(new DownloadRelationMemberTask( 1232 getRelation(), 1233 memberTableModel.getSelectedIncompleteMemberPrimitives(), 1234 getLayer(), 1235 memberTableModel, 1236 GenericRelationEditor.this) 1237 ); 1238 } 1239 1240 protected void updateEnabledState() { 1241 setEnabled( 1242 getRelation() != null 1243 && !getRelation().isNew() 1244 && memberTableModel.hasIncompleteSelectedMembers() 1245 ); 1246 } 1247 1248 public void valueChanged(ListSelectionEvent e) { 1249 updateEnabledState(); 1250 } 1251 1252 public void tableChanged(TableModelEvent e) { 1253 updateEnabledState(); 1212 1254 } 1213 1255 } … … 1366 1408 } 1367 1409 } 1368 1369 /**1370 * The asynchronous task for downloading relation members.1371 *1372 */1373 public static class DownloadTask extends PleaseWaitRunnable {1374 private boolean cancelled;1375 private Exception lastException;1376 private List<Relation> relations;1377 private OsmDataLayer curLayer;1378 private MemberTableModel memberTableModel;1379 private OsmServerObjectReader objectReader;1380 private OsmServerBackreferenceReader parentReader;1381 1382 public DownloadTask(List<Relation> relations, OsmDataLayer curLayer, MemberTableModel memberTableModel, Dialog parent) {1383 super(tr("Download relation members"), new PleaseWaitProgressMonitor(parent), false /* don't ignore exception */);1384 this.relations = relations;1385 this.curLayer = curLayer;1386 this.memberTableModel = memberTableModel;1387 }1388 1389 public DownloadTask(List<Relation> relations, OsmDataLayer curLayer, MemberTableModel memberTableModel) {1390 super(tr("Download relation members"), new PleaseWaitProgressMonitor(), false /* don't ignore exception */);1391 this.relations = relations;1392 this.curLayer = curLayer;1393 this.memberTableModel = memberTableModel;1394 }1395 1396 @Override1397 protected void cancel() {1398 cancelled = true;1399 synchronized(this) {1400 if (objectReader != null) {1401 objectReader.cancel();1402 } else if (parentReader != null) {1403 parentReader.cancel();1404 }1405 }1406 }1407 1408 @Override1409 protected void finish() {1410 Main.map.repaint();1411 if (cancelled)1412 return;1413 if (memberTableModel != null) {1414 memberTableModel.fireTableDataChanged();1415 }1416 if (lastException != null) {1417 ExceptionDialogUtil.explainException(lastException);1418 }1419 }1420 1421 @Override1422 protected void realRun() throws SAXException, IOException, OsmTransferException {1423 try {1424 for (Relation relation : relations) {1425 // download the relation1426 //1427 progressMonitor.indeterminateSubTask(tr("Downloading relation ''{0}''", relation.getDisplayName(DefaultNameFormatter.getInstance())));1428 synchronized(this) {1429 if (cancelled) return;1430 objectReader = new OsmServerObjectReader(relation.getId(), OsmPrimitiveType.RELATION, true /* full download */);1431 }1432 final DataSet dataSet = objectReader.parseOsm(progressMonitor1433 .createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));1434 if (dataSet == null)1435 return;1436 synchronized (this) {1437 if (cancelled) return;1438 objectReader = null;1439 }1440 1441 // download referring objects of the downloaded member objects1442 //1443 // asked for in #3999, but uncommented for the time being. Could be used1444 // later, perhaps if user explicity requests so (for instance by checking1445 // a checkbox)1446 // for (OsmPrimitive p: relation.getMemberPrimitives()) {1447 // synchronized(this) {1448 // if (cancelled) return;1449 // parentReader = new OsmServerBackreferenceReader(p);1450 // }1451 // DataSet parents = parentReader.parseOsm(progressMonitor.createSubTaskMonitor(1, false));1452 // synchronized(this) {1453 // if (cancelled) return;1454 // parentReader = null;1455 // }1456 // DataSetMerger merger = new DataSetMerger(dataSet, parents);1457 // merger.merge();1458 // }1459 // if (cancelled) return;1460 1461 // has to run on the EDT because mergeFrom may trigger events1462 // which update the UI1463 //1464 SwingUtilities.invokeAndWait(1465 new Runnable() {1466 public void run() {1467 curLayer.mergeFrom(dataSet);1468 curLayer.fireDataChange();1469 curLayer.onPostDownloadFromServer();1470 }1471 }1472 );1473 }1474 } catch (Exception e) {1475 if (cancelled) {1476 System.out.println(tr("Warning: ignoring exception because task is cancelled. Exception: {0}", e1477 .toString()));1478 return;1479 }1480 lastException = e;1481 }1482 }1483 }1484 1410 } -
trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTable.java
r2512 r2563 18 18 import javax.swing.KeyStroke; 19 19 import javax.swing.ListSelectionModel; 20 import javax.swing.SwingUtilities; 20 21 import javax.swing.event.ListSelectionEvent; 21 22 import javax.swing.event.ListSelectionListener; … … 71 72 72 73 addMouseListener(new PopupListener()); 74 addMouseListener(new DblClickHandler()); 73 75 } 74 76 … … 241 243 return (MemberTableModel) getModel(); 242 244 } 245 246 class DblClickHandler extends MouseAdapter { 247 protected void setSelection(MouseEvent e) { 248 int row = rowAtPoint(e.getPoint()); 249 if (row < 0) return; 250 OsmPrimitive primitive = getMemberTableModel().getReferredPrimitive(row); 251 getMemberTableModel().getLayer().data.setSelected(primitive.getPrimitiveId()); 252 } 253 254 protected void addSelection(MouseEvent e) { 255 int row = rowAtPoint(e.getPoint()); 256 if (row < 0) return; 257 OsmPrimitive primitive = getMemberTableModel().getReferredPrimitive(row); 258 getMemberTableModel().getSelectionModel().addSelectionInterval(row, row); 259 getMemberTableModel().getLayer().data.addSelected(primitive.getPrimitiveId()); 260 261 } 262 263 @Override 264 public void mouseClicked(MouseEvent e) { 265 if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() > 1) { 266 if (e.isControlDown()) { 267 addSelection(e); 268 } else { 269 setSelection(e); 270 } 271 } 272 } 273 } 243 274 } -
trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableCellRenderer.java
r2512 r2563 4 4 import java.awt.Color; 5 5 import java.awt.Component; 6 import java.util.ArrayList;7 import java.util.Collections;8 6 9 7 import javax.swing.JLabel; 10 8 import javax.swing.JTable; 9 import javax.swing.UIManager; 11 10 import javax.swing.table.TableCellRenderer; 12 11 … … 18 17 */ 19 18 public abstract class MemberTableCellRenderer extends JLabel implements TableCellRenderer { 20 public final static Color BGCOLOR_SELECTED = new Color(143, 170, 255);21 19 public final static Color BGCOLOR_EMPTY_ROW = new Color(234, 234, 234); 20 public final static Color BGCOLOR_IN_JOSM_SELECTION = new Color(235,255,177); 22 21 23 22 public final static Color BGCOLOR_NOT_IN_OPPOSITE = new Color(255, 197, 197); 24 public final static Color BGCOLOR_DOUBLE_ENTRY = new Color(25 5, 234, 213);23 public final static Color BGCOLOR_DOUBLE_ENTRY = new Color(254,226,214); 25 24 26 25 /** … … 32 31 } 33 32 34 public String buildToolTipText(OsmPrimitive primitive) {35 StringBuilder sb = new StringBuilder();36 sb.append("<html>");37 sb.append("<strong>id</strong>=").append(primitive.getId()).append("<br>");38 ArrayList<String> keyList = new ArrayList<String>(primitive.keySet());39 Collections.sort(keyList);40 for (int i = 0; i < keyList.size(); i++) {41 if (i > 0) {42 sb.append("<br>");43 }44 String key = keyList.get(i);45 sb.append("<strong>").append(key).append("</strong>").append("=");46 String value = primitive.get(key);47 while (value.length() != 0) {48 sb.append(value.substring(0, Math.min(50, value.length())));49 if (value.length() > 50) {50 sb.append("<br>");51 value = value.substring(50);52 } else {53 value = "";54 }55 }56 }57 sb.append("</html>");58 return sb.toString();59 }60 61 33 /** 62 34 * reset the renderer 63 35 */ 64 36 protected void reset() { 65 setBackground( Color.WHITE);66 setForeground( Color.BLACK);37 setBackground(UIManager.getColor("Table.background")); 38 setForeground(UIManager.getColor("Table.foreground")); 67 39 setBorder(null); 68 40 setIcon(null); … … 71 43 72 44 protected void renderBackground(MemberTableModel model, OsmPrimitive primitive, boolean isSelected) { 73 Color bgc = Color.WHITE;45 Color bgc = UIManager.getColor("Table.background"); 74 46 if (isSelected) { 75 bgc = BGCOLOR_SELECTED; 47 bgc = UIManager.getColor("Table.selectionBackground"); 48 } else if (primitive != null && model.isInJosmSelection(primitive)) { 49 bgc = BGCOLOR_IN_JOSM_SELECTION; 76 50 } else if (primitive != null && model.getNumMembersWithPrimitive(primitive) > 1) { 77 51 bgc = BGCOLOR_DOUBLE_ENTRY; … … 81 55 82 56 protected void renderForeground(boolean isSelected) { 83 Color fgc = Color.BLACK; 57 Color fgc; 58 if (isSelected) { 59 fgc = UIManager.getColor("Table.selectionForeground"); 60 } else { 61 fgc = UIManager.getColor("Table.foreground"); 62 } 84 63 setForeground(fgc); 85 64 } -
trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableMemberCellRenderer.java
r2512 r2563 3 3 4 4 import java.awt.Component; 5 import java.util.HashMap;6 5 7 import javax.swing.ImageIcon;8 6 import javax.swing.JTable; 9 7 10 8 import org.openstreetmap.josm.data.osm.OsmPrimitive; 11 import org.openstreetmap.josm.data.osm.OsmPrimitiveType;12 9 import org.openstreetmap.josm.gui.DefaultNameFormatter; 13 10 import org.openstreetmap.josm.tools.ImageProvider; 14 11 15 12 public class MemberTableMemberCellRenderer extends MemberTableCellRenderer { 16 private HashMap<OsmPrimitiveType, ImageIcon> icons;17 13 18 14 public MemberTableMemberCellRenderer() { 19 15 super(); 20 loadIcons();21 }22 23 /**24 * Load the image icon for an OSM primitive of type node25 *26 * @return the icon; null, if not found27 */28 protected void loadIcons() {29 icons = new HashMap<OsmPrimitiveType, ImageIcon>();30 icons.put(OsmPrimitiveType.NODE, ImageProvider.get("data", "node"));31 icons.put(OsmPrimitiveType.WAY, ImageProvider.get("data", "way"));32 icons.put(OsmPrimitiveType.RELATION, ImageProvider.get("data", "relation"));33 16 } 34 17 35 18 protected void renderPrimitive(OsmPrimitive primitive) { 36 setIcon( icons.get(OsmPrimitiveType.from(primitive)));19 setIcon(ImageProvider.get(primitive.getPrimitiveId().getType())); 37 20 setText(primitive.getDisplayName(DefaultNameFormatter.getInstance())); 38 setToolTipText( buildToolTipText(primitive));21 setToolTipText(DefaultNameFormatter.getInstance().buildDefaultToolTip(primitive)); 39 22 } 40 23 -
trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java
r2512 r2563 26 26 27 27 import org.openstreetmap.josm.Main; 28 import org.openstreetmap.josm.data.SelectionChangedListener; 28 29 import org.openstreetmap.josm.data.coor.EastNorth; 30 import org.openstreetmap.josm.data.osm.DataSetListener; 29 31 import org.openstreetmap.josm.data.osm.Node; 30 32 import org.openstreetmap.josm.data.osm.OsmPrimitive; … … 33 35 import org.openstreetmap.josm.data.osm.Way; 34 36 import org.openstreetmap.josm.gui.dialogs.relation.WayConnectionType.Direction; 37 import org.openstreetmap.josm.gui.layer.DataChangeListener; 35 38 import org.openstreetmap.josm.gui.layer.OsmDataLayer; 36 39 37 public class MemberTableModel extends AbstractTableModel implements TableModelListener 40 public class MemberTableModel extends AbstractTableModel implements TableModelListener, SelectionChangedListener, DataChangeListener, DataSetListener{ 38 41 39 42 /** … … 56 59 addTableModelListener(this); 57 60 } 61 62 public OsmDataLayer getLayer() { 63 return layer; 64 } 65 66 /* --------------------------------------------------------------------------- */ 67 /* Interface SelectionChangedListener */ 68 /* --------------------------------------------------------------------------- */ 69 public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) { 70 if (Main.main.getEditLayer() != this.layer) return; 71 // just trigger a repaint 72 Collection<RelationMember> sel = getSelectedMembers(); 73 fireTableDataChanged(); 74 setSelectedMembers(sel); 75 } 76 77 /* --------------------------------------------------------------------------- */ 78 /* Interface DataChangeListener */ 79 /* --------------------------------------------------------------------------- */ 80 public void dataChanged(OsmDataLayer l) { 81 if (l != this.layer) return; 82 // just trigger a repaint 83 Collection<RelationMember> sel = getSelectedMembers(); 84 fireTableDataChanged(); 85 setSelectedMembers(sel); 86 } 87 /* --------------------------------------------------------------------------- */ 88 /* Interface DataSetListener */ 89 /* --------------------------------------------------------------------------- */ 90 public void dataChanged() { 91 // just trigger a repaint - the display name of the relation members may 92 // have changed 93 Collection<RelationMember> sel = getSelectedMembers(); 94 fireTableDataChanged(); 95 setSelectedMembers(sel); 96 } 97 98 public void nodeMoved(Node node) {/* ignore */} 99 public void primtivesAdded(Collection<? extends OsmPrimitive> added) {/* ignore */} 100 101 public void primtivesRemoved(Collection<? extends OsmPrimitive> removed) { 102 // ignore - the relation in the editor might become out of sync with the relation 103 // in the dataset. We will deal with it when the relation editor is closed or 104 // when the changes in the editor are applied. 105 } 106 107 public void relationMembersChanged(Relation r) { 108 // ignore - the relation in the editor might become out of sync with the relation 109 // in the dataset. We will deal with it when the relation editor is closed or 110 // when the changes in the editor are applied. 111 } 112 113 public void tagsChanged(OsmPrimitive prim) { 114 // just refresh the respective table cells 115 // 116 Collection<RelationMember> sel = getSelectedMembers(); 117 for (int i=0; i < members.size();i++) { 118 if (members.get(i).getMember() == prim) { 119 fireTableCellUpdated(i, 1 /* the column with the primitive name */); 120 } 121 } 122 setSelectedMembers(sel); 123 } 124 125 public void wayNodesChanged(Way way) {/* ignore */} 126 /* --------------------------------------------------------------------------- */ 58 127 59 128 public void addMemberModelListener(IMemberModelListener listener) { … … 242 311 } 243 312 313 /** 314 * Replies the set of incomplete primitives 315 * 316 * @return the set of incomplete primitives 317 */ 318 public Set<OsmPrimitive> getIncompleteMemberPrimitives() { 319 Set<OsmPrimitive> ret = new HashSet<OsmPrimitive>(); 320 for (RelationMember member : members) { 321 if (member.getMember().incomplete) { 322 ret.add(member.getMember()); 323 } 324 } 325 return ret; 326 } 327 328 /** 329 * Replies the set of selected incomplete primitives 330 * 331 * @return the set of selected incomplete primitives 332 */ 333 public Set<OsmPrimitive> getSelectedIncompleteMemberPrimitives() { 334 Set<OsmPrimitive> ret = new HashSet<OsmPrimitive>(); 335 for (RelationMember member : getSelectedMembers()) { 336 if (member.getMember().incomplete) { 337 ret.add(member.getMember()); 338 } 339 } 340 return ret; 341 } 342 343 /** 344 * Replies true if at least one the relation members is incomplete 345 * 346 * @return true if at least one the relation members is incomplete 347 */ 244 348 public boolean hasIncompleteMembers() { 245 349 for (RelationMember member : members) { 350 if (member.getMember().incomplete) 351 return true; 352 } 353 return false; 354 } 355 356 /** 357 * Replies true if at least one of the selected members is incomplete 358 * 359 * @return true if at least one of the selected members is incomplete 360 */ 361 public boolean hasIncompleteSelectedMembers() { 362 for (RelationMember member : getSelectedMembers()) { 246 363 if (member.getMember().incomplete) 247 364 return true; … … 408 525 409 526 /** 410 * Replies true, if the selected {@see OsmPrimitive}s in the layer belonging411 * to this model are in sync with the selected referers in this model.412 *413 * @return414 */415 public boolean selectionsAreInSync() {416 HashSet<OsmPrimitive> s1 = new HashSet<OsmPrimitive>(getSelectedChildPrimitives());417 if (s1.size() != layer.data.getSelected().size()) return false;418 s1.removeAll(layer.data.getSelected());419 return s1.isEmpty();420 }421 /**422 527 * Selects the members in the collection selectedMembers 423 528 * … … 425 530 */ 426 531 public void setSelectedMembers(Collection<RelationMember> selectedMembers) { 427 if (selectedMembers == null || selectedMembers.isEmpty()) 532 if (selectedMembers == null || selectedMembers.isEmpty()) { 533 getSelectionModel().clearSelection(); 428 534 return; 535 } 429 536 430 537 // lookup the indices for the respective members 431 538 // 432 ArrayList<Integer> selectedIndices = new ArrayList<Integer>();539 Set<Integer> selectedIndices = new HashSet<Integer>(); 433 540 for (RelationMember member : selectedMembers) { 434 for (int idx = 0; idx < members.size(); idx ++) { 435 if (members.get(idx).equals(member)) { 436 if (!selectedIndices.contains(idx)) { 437 selectedIndices.add(idx); 438 } 439 } 541 int idx = members.indexOf(member); 542 if ( idx >= 0) { 543 selectedIndices.add(idx); 440 544 } 441 545 } … … 443 547 // select the members 444 548 // 445 Collections.sort(selectedIndices);446 549 getSelectionModel().setValueIsAdjusting(true); 447 550 getSelectionModel().clearSelection(); … … 450 553 } 451 554 getSelectionModel().setValueIsAdjusting(false); 452 453 555 // make the first selected member visible 454 556 // 455 557 if (selectedIndices.size() > 0) { 456 fireMakeMemberVisible( selectedIndices.get(0));558 fireMakeMemberVisible(Collections.min(selectedIndices)); 457 559 } 458 560 } … … 523 625 fireMakeMemberVisible(getSelectedIndices().get(0)); 524 626 } 627 } 628 629 /** 630 * Replies true if <code>primitive</code> is currently selected in the layer this 631 * model is attached to 632 * 633 * @param primitive the primitive 634 * @return true if <code>primitive</code> is currently selected in the layer this 635 * model is attached to, false otherwise 636 */ 637 public boolean isInJosmSelection(OsmPrimitive primitive) { 638 return layer.data.isSelected(primitive); 525 639 } 526 640 -
trunk/src/org/openstreetmap/josm/gui/dialogs/relation/RelationEditor.java
r2512 r2563 4 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 5 6 import java.beans.PropertyChangeListener; 7 import java.beans.PropertyChangeSupport; 6 8 import java.lang.reflect.Constructor; 7 9 import java.lang.reflect.Method; … … 16 18 17 19 public abstract class RelationEditor extends ExtendedDialog { 20 /** the property name for the current relation. 21 * @see #setRelation(Relation) 22 * @see #getRelation() 23 */ 24 static public final String RELATION_PROP = RelationEditor.class.getName() + ".relation"; 25 26 /** the property name for the current relation snapshot 27 * @see #getRelationSnapshot() 28 */ 29 static public final String RELATION_SNAPSHOT_PROP = RelationEditor.class.getName() + ".relationSnapshot"; 18 30 19 31 /** the list of registered relation editor classes */ … … 62 74 * then an instance of that class will be used. 63 75 * 76 * @param layer the data layer the relation is a member of 64 77 * @param r the relation to be edited 78 * @param selectedMembers a collection of relation members which shall be selected when the 79 * editor is first launched 65 80 * @return an instance of RelationEditor suitable for editing that kind of relation 66 81 */ … … 139 154 */ 140 155 protected void setRelation(Relation relation) { 141 this.relationSnapshot = (relation == null) ? null : new Relation(relation); 156 setRelationSnapshot((relation == null) ? null : new Relation(relation)); 157 Relation oldValue = this.relation; 142 158 this.relation = relation; 159 if (this.relation != oldValue) { 160 support.firePropertyChange(RELATION_PROP, oldValue, this.relation); 161 } 143 162 updateTitle(); 144 163 } … … 164 183 } 165 184 185 protected void setRelationSnapshot(Relation snapshot) { 186 Relation oldValue = relationSnapshot; 187 relationSnapshot = snapshot; 188 if (relationSnapshot != oldValue) { 189 support.firePropertyChange(RELATION_SNAPSHOT_PROP, oldValue, relationSnapshot); 190 } 191 } 192 166 193 /** 167 194 * Replies true if the currently edited relation has been changed elsewhere. … … 175 202 return ! relation.hasEqualSemanticAttributes(relationSnapshot); 176 203 } 204 205 206 /* ----------------------------------------------------------------------- */ 207 /* property change support */ 208 /* ----------------------------------------------------------------------- */ 209 final private PropertyChangeSupport support = new PropertyChangeSupport(this); 210 211 @Override 212 public void addPropertyChangeListener(PropertyChangeListener listener) { 213 this.support.addPropertyChangeListener(listener); 214 } 215 216 @Override 217 public void removePropertyChangeListener(PropertyChangeListener listener) { 218 this.support.removePropertyChangeListener(listener); 219 } 177 220 } -
trunk/src/org/openstreetmap/josm/gui/dialogs/relation/SelectionTableCellRenderer.java
r2512 r2563 4 4 import java.awt.Color; 5 5 import java.awt.Component; 6 import java.util.ArrayList;7 import java.util.Collections;8 import java.util.HashMap;9 6 10 import javax.swing.ImageIcon;11 7 import javax.swing.JLabel; 12 8 import javax.swing.JTable; 9 import javax.swing.UIManager; 13 10 import javax.swing.table.TableCellRenderer; 14 11 15 12 import org.openstreetmap.josm.data.osm.OsmPrimitive; 16 import org.openstreetmap.josm.data.osm.OsmPrimitiveType;17 13 import org.openstreetmap.josm.gui.DefaultNameFormatter; 18 14 import org.openstreetmap.josm.tools.ImageProvider; 19 15 20 16 /** 21 * This is the {@see TableCellRenderer} used in the tables of {@see RelationMemberMerger}.17 * This is the {@see TableCellRenderer} used in {@see SelectionTable}. 22 18 * 23 19 */ 24 20 public class SelectionTableCellRenderer extends JLabel implements TableCellRenderer { 25 public final static Color BGCOLOR_ SELECTED = new Color(143,170,255);26 public final static Color BGCOLOR_ DOUBLE_ENTRY = new Color(255,234,213);21 public final static Color BGCOLOR_DOUBLE_ENTRY = new Color(254,226,214); 22 public final static Color BGCOLOR_SINGLE_ENTRY = new Color(235,255,177); 27 23 28 private HashMap<OsmPrimitiveType, ImageIcon> icons;29 24 /** 30 25 * reference to the member table model; required, in order to check whether a … … 35 30 36 31 /** 37 * Load the image icon for an OSM primitive of type node38 *39 * @return the icon; null, if not found40 */41 protected void loadIcons() {42 icons = new HashMap<OsmPrimitiveType, ImageIcon>();43 icons.put(OsmPrimitiveType.NODE,ImageProvider.get("data", "node"));44 icons.put(OsmPrimitiveType.WAY, ImageProvider.get("data", "way"));45 icons.put(OsmPrimitiveType.RELATION, ImageProvider.get("data", "relation"));46 }47 48 /**49 32 * constructor 50 33 */ … … 52 35 setIcon(null); 53 36 setOpaque(true); 54 loadIcons();55 }56 57 public String buildToolTipText(OsmPrimitive primitive) {58 StringBuilder sb = new StringBuilder();59 sb.append("<html>");60 sb.append("<strong>id</strong>=")61 .append(primitive.getId())62 .append("<br>");63 ArrayList<String> keyList = new ArrayList<String>(primitive.keySet());64 Collections.sort(keyList);65 for (int i = 0; i < keyList.size(); i++) {66 if (i > 0) {67 sb.append("<br>");68 }69 String key = keyList.get(i);70 sb.append("<strong>")71 .append(key)72 .append("</strong>")73 .append("=");74 String value = primitive.get(key);75 while(value.length() != 0) {76 sb.append(value.substring(0,Math.min(50, value.length())));77 if (value.length() > 50) {78 sb.append("<br>");79 value = value.substring(50);80 } else {81 value = "";82 }83 }84 }85 sb.append("</html>");86 return sb.toString();87 37 } 88 38 … … 91 41 */ 92 42 protected void reset() { 93 setBackground( Color.WHITE);94 setForeground( Color.BLACK);43 setBackground(UIManager.getColor("Table.background")); 44 setForeground(UIManager.getColor("Table.foreground")); 95 45 setBorder(null); 96 46 setIcon(null); … … 99 49 100 50 protected void renderBackground(OsmPrimitive primitive, boolean isSelected) { 101 Color bgc = Color.WHITE;102 if ( isSelected) {103 bgc = BGCOLOR_S ELECTED;104 } else if (primitive != null && model != null && model.getNumMembersWithPrimitive(primitive) > 0) {51 Color bgc = UIManager.getColor("Table.background"); 52 if (primitive != null && model != null && model.getNumMembersWithPrimitive(primitive) == 1) { 53 bgc = BGCOLOR_SINGLE_ENTRY; 54 } else if (primitive != null && model != null && model.getNumMembersWithPrimitive(primitive) > 1) { 105 55 bgc = BGCOLOR_DOUBLE_ENTRY; 106 56 } … … 108 58 } 109 59 110 protected void renderForeground(boolean isSelected) {111 Color fgc = Color.BLACK;112 setForeground(fgc);113 }114 60 115 61 protected void renderPrimitive(OsmPrimitive primitive) { 116 setIcon( icons.get(OsmPrimitiveType.from(primitive)));62 setIcon(ImageProvider.get(primitive.getPrimitiveId().getType())); 117 63 setText(primitive.getDisplayName(DefaultNameFormatter.getInstance())); 118 setToolTipText( buildToolTipText(primitive));64 setToolTipText(DefaultNameFormatter.getInstance().buildDefaultToolTip(primitive)); 119 65 } 120 66 … … 123 69 124 70 reset(); 125 renderForeground(isSelected);126 71 renderBackground((OsmPrimitive)value, isSelected); 127 72 renderPrimitive((OsmPrimitive)value); -
trunk/src/org/openstreetmap/josm/gui/dialogs/relation/SelectionTableModel.java
r2512 r2563 34 34 this.layer = layer; 35 35 cache = new ArrayList<OsmPrimitive>(); 36 DataSet.selListeners.add(this);37 36 Layer.listeners.add(this); 38 37 populateSelectedPrimitives(layer); … … 103 102 selectionChanged(layer.data.getSelected()); 104 103 } 104 105 /** 106 * Replies the primitive at row <code>row</code> in this model 107 * 108 * @param row the row 109 * @return the primitive at row <code>row</code> in this model 110 */ 111 public OsmPrimitive getPrimitive(int row) { 112 return cache.get(row); 113 } 105 114 } -
trunk/src/org/openstreetmap/josm/io/MultiFetchServerObjectReader.java
r2512 r2563 3 3 4 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 import static org.openstreetmap.josm.tools.I18n.trn; 5 6 6 7 import java.io.InputStream; … … 308 309 progressMonitor.subTask(tr("Downloading OSM data...")); 309 310 try { 310 311 merge( 312 OsmReader.parseDataSet(in, progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false)) 313 ); 311 DataSet loaded = OsmReader.parseDataSet(in, progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false)); 312 rememberNodesOfIncompleteWaysToLoad(loaded); 313 merge(loaded); 314 314 } catch(Exception e) { 315 315 throw new OsmTransferException(e); … … 333 333 progressMonitor.subTask(tr("Downloading OSM data...")); 334 334 try { 335 merge(336 OsmReader.parseDataSet(in, progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false))337 );335 DataSet loaded = OsmReader.parseDataSet(in, progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false)); 336 rememberNodesOfIncompleteWaysToLoad(loaded); 337 merge(loaded); 338 338 } catch(Exception e) { 339 339 throw new OsmTransferException(e); … … 376 376 } 377 377 378 protected void rememberNodesOfIncompleteWaysToLoad(DataSet from) { 379 for (Way w: from.getWays()) { 380 if (w.incomplete) { 381 for (Node n: w.getNodes()) { 382 if (n.incomplete) { 383 nodes.add(n.getId()); 384 } 385 } 386 } 387 } 388 } 389 378 390 /** 379 391 * merges the dataset <code>from</code> to {@see #outputDataSet}. … … 401 413 case RELATION: msg = tr("Fetching a package of relations from ''{0}''", OsmApi.getOsmApi().getBaseUrl()); break; 402 414 } 403 progressMonitor. setCustomText(msg);415 progressMonitor.indeterminateSubTask(msg); 404 416 Set<Long> toFetch = new HashSet<Long>(ids); 405 417 toFetch.addAll(ids); … … 428 440 * found on the server (the server response code was 404) 429 441 * 430 * Invoke {@see #getSkippedWay()} to get a list of ways which this reader could not build from431 * the fetched data because the ways refer to nodes which don't exist on the server.432 *433 442 * @return the parsed data 434 443 * @exception OsmTransferException thrown if an error occurs while communicating with the API server 435 444 * @see #getMissingPrimitives() 436 * @see #getSkippedWays() 437 * 438 445 * 439 446 */ 440 447 @Override 441 448 public DataSet parseOsm(ProgressMonitor progressMonitor) throws OsmTransferException { 442 progressMonitor.beginTask(""); 449 int n = nodes.size() + ways.size() + relations.size(); 450 progressMonitor.beginTask(trn("Downloading {0} object from ''{1}''", "Downloading {0} objects from ''{1}''", n, n, OsmApi.getOsmApi().getBaseUrl())); 443 451 try { 444 452 missingPrimitives = new HashSet<Long>(); 445 453 if (isCanceled())return null; 454 fetchPrimitives(ways,OsmPrimitiveType.WAY, progressMonitor); 455 if (isCanceled())return null; 446 456 fetchPrimitives(nodes,OsmPrimitiveType.NODE, progressMonitor); 447 if (isCanceled())return null;448 fetchPrimitives(ways,OsmPrimitiveType.WAY, progressMonitor);449 457 if (isCanceled())return null; 450 458 fetchPrimitives(relations,OsmPrimitiveType.RELATION, progressMonitor); -
trunk/src/org/openstreetmap/josm/io/OsmReader.java
r2512 r2563 12 12 import java.util.List; 13 13 import java.util.Map; 14 import java.util.logging.Level; 14 15 import java.util.logging.Logger; 15 16 … … 443 444 w.setNodes(wayNodes); 444 445 if (incomplete) { 445 logger.warning(tr("Marked way {0} with {1} nodes incomplete because at least one node was missing in the " + 446 "loaded data and is therefore incomplete too.", externalWayId, w.getNodesCount())); 446 if (logger.isLoggable(Level.FINE)) { 447 logger.fine(tr("Marked way {0} with {1} nodes incomplete because at least one node was missing in the " + 448 "loaded data and is therefore incomplete too.", externalWayId, w.getNodesCount())); 449 } 447 450 w.incomplete = true; 448 451 ds.addPrimitive(w); -
trunk/src/org/openstreetmap/josm/io/OsmServerObjectReader.java
r2484 r2563 9 9 import org.openstreetmap.josm.data.osm.DataSet; 10 10 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 11 import org.openstreetmap.josm.data.osm.PrimitiveId; 12 import org.openstreetmap.josm.data.osm.SimplePrimitiveId; 13 import org.openstreetmap.josm.gui.progress.NullProgressMonitor; 11 14 import org.openstreetmap.josm.gui.progress.ProgressMonitor; 12 15 import org.xml.sax.SAXException; 13 16 17 /** 18 * OsmServerObjectReader reads an individual object from the OSM server. 19 * 20 * It can either download the object including or not including its immediate children. 21 * The former case is called a "full download". 22 * 23 */ 14 24 public class OsmServerObjectReader extends OsmServerReader { 25 /** the id of the object to download */ 26 private PrimitiveId id; 27 /** true if a full download is required, i.e. a download including the immediate children */ 28 private boolean full; 15 29 16 long id; 17 OsmPrimitiveType type; 18 boolean full; 19 20 public OsmServerObjectReader(long id, OsmPrimitiveType type, boolean full) { 21 this.id = id; 22 this.type = type; 30 /** 31 * Creates a new server object reader for a given id and a primitive type. 32 * 33 * @param id the object id. > 0 required. 34 * @param type the type. Must not be null. 35 * @param full true, if a full download is requested (i.e. a download including 36 * immediate children); false, otherwise 37 * @throws IllegalArgumentException thrown if id <= 0 38 * @throws IllegalArgumentException thrown if type is null 39 */ 40 public OsmServerObjectReader(long id, OsmPrimitiveType type, boolean full) throws IllegalArgumentException { 41 if (id <= 0) 42 throw new IllegalArgumentException(tr("Expected value > 0 for parameter ''{0}'', got {1}", "id", id)); 43 if (type == null) 44 throw new IllegalArgumentException(tr("Parameter ''{0}'' must not be null", "type")); 45 this.id = new SimplePrimitiveId(id, type); 23 46 this.full = full; 24 47 } 48 25 49 /** 26 * Method to download single objects from OSM server. ways, relations, nodes 27 * @return the data requested 50 * Creates a new server object reader for an object with the given <code>id</code> 51 * 52 * @param id the object id. Must not be null. Unique id > 0 required. 53 * @param full true, if a full download is requested (i.e. a download including 54 * immediate children); false, otherwise 55 * @throws IllegalArgumentException thrown if id is null 56 * @throws IllegalArgumentException thrown if id.getUniqueId() <= 0 57 */ 58 public OsmServerObjectReader(PrimitiveId id, boolean full) { 59 if (id == null) 60 throw new IllegalArgumentException(tr("Parameter ''{0}'' must not be null", "id")); 61 if (id.getUniqueId() <= 0) 62 throw new IllegalArgumentException(tr("Expected value > 0 for parameter ''{0}'', got {1}", "id.getUniqueId()", id.getUniqueId())); 63 this.id = id; 64 this.full = full; 65 } 66 67 /** 68 * Downloads and parses the data. 69 * 70 * @param progressMonitor the progress monitor. Set to {@see NullProgressMonitor#INSTANCE} if 71 * null 72 * @return the downloaded data 28 73 * @throws SAXException 29 74 * @throws IOException … … 31 76 @Override 32 77 public DataSet parseOsm(ProgressMonitor progressMonitor) throws OsmTransferException { 78 if (progressMonitor == null) { 79 progressMonitor = NullProgressMonitor.INSTANCE; 80 } 33 81 progressMonitor.beginTask("", 1); 34 82 InputStream in = null; … … 36 84 progressMonitor.indeterminateSubTask(tr("Downloading OSM data...")); 37 85 StringBuffer sb = new StringBuffer(); 38 sb.append( type.getAPIName());86 sb.append(id.getType().getAPIName()); 39 87 sb.append("/"); 40 sb.append(id );41 if (full && ! type.equals(OsmPrimitiveType.NODE)) {88 sb.append(id.getUniqueId()); 89 if (full && ! id.getType().equals(OsmPrimitiveType.NODE)) { 42 90 sb.append("/full"); 43 91 } … … 59 107 try { 60 108 in.close(); 61 } catch(Exception e) { }109 } catch(Exception e) {/* ignore this exception */} 62 110 } 63 111 activeConnection = null; 64 112 } 65 113 } 66 67 114 }
Note:
See TracChangeset
for help on using the changeset viewer.