Ticket #12300: 12300-v3.patch
| File 12300-v3.patch, 17.3 KB (added by , 10 years ago) |
|---|
-
new file src/org/openstreetmap/josm/gui/datatransfer/PrimitiveTransferable.java
diff --git a/src/org/openstreetmap/josm/gui/datatransfer/PrimitiveTransferable.java b/src/org/openstreetmap/josm/gui/datatransfer/PrimitiveTransferable.java new file mode 100644 index 0000000..06befa9
- + 1 // License: GPL. For details, see LICENSE file. 2 package org.openstreetmap.josm.gui.datatransfer; 3 4 import java.awt.datatransfer.DataFlavor; 5 import java.awt.datatransfer.Transferable; 6 import java.awt.datatransfer.UnsupportedFlavorException; 7 import java.util.ArrayList; 8 import java.util.Collection; 9 10 import org.openstreetmap.josm.data.osm.OsmPrimitive; 11 import org.openstreetmap.josm.data.osm.PrimitiveData; 12 import org.openstreetmap.josm.gui.DefaultNameFormatter; 13 14 public class PrimitiveTransferable implements Transferable { 15 16 public static final DataFlavor PRIMITIVE_DATA = new DataFlavor(PrimitiveData.class, PrimitiveData.class.getName()); 17 private final Collection<OsmPrimitive> primitives; 18 19 public PrimitiveTransferable(Collection<OsmPrimitive> members) { 20 this.primitives = members; 21 } 22 23 @Override 24 public DataFlavor[] getTransferDataFlavors() { 25 return new DataFlavor[]{PRIMITIVE_DATA, DataFlavor.stringFlavor}; 26 } 27 28 @Override 29 public boolean isDataFlavorSupported(DataFlavor flavor) { 30 return flavor == PRIMITIVE_DATA; 31 } 32 33 @Override 34 public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException { 35 if (DataFlavor.stringFlavor.equals(flavor)) { 36 return getStringData(); 37 } else if (PRIMITIVE_DATA.equals(flavor)) { 38 return getRelationMemberData(); 39 } 40 throw new UnsupportedFlavorException(flavor); 41 } 42 43 protected String getStringData() { 44 final StringBuilder sb = new StringBuilder(); 45 for (OsmPrimitive primitive : primitives) { 46 sb.append(primitive.getType()); 47 sb.append(" ").append(primitive.getUniqueId()); 48 sb.append(" #").append(primitive.getDisplayName(DefaultNameFormatter.getInstance())); 49 sb.append("\n"); 50 } 51 return sb.toString().replace("\u200E", "").replace("\u200F", ""); 52 } 53 54 protected Collection<PrimitiveData> getRelationMemberData() { 55 final Collection<PrimitiveData> r = new ArrayList<>(primitives.size()); 56 for (OsmPrimitive primitive : primitives) { 57 r.add(primitive.save()); 58 } 59 return r; 60 } 61 } -
new file src/org/openstreetmap/josm/gui/datatransfer/RelationMemberTransferable.java
diff --git a/src/org/openstreetmap/josm/gui/datatransfer/RelationMemberTransferable.java b/src/org/openstreetmap/josm/gui/datatransfer/RelationMemberTransferable.java new file mode 100644 index 0000000..b8afcd1
- + 1 // License: GPL. For details, see LICENSE file. 2 package org.openstreetmap.josm.gui.datatransfer; 3 4 import java.awt.datatransfer.DataFlavor; 5 import java.awt.datatransfer.Transferable; 6 import java.awt.datatransfer.UnsupportedFlavorException; 7 import java.util.ArrayList; 8 import java.util.Collection; 9 10 import org.openstreetmap.josm.data.osm.RelationMember; 11 import org.openstreetmap.josm.data.osm.RelationMemberData; 12 import org.openstreetmap.josm.gui.DefaultNameFormatter; 13 14 public class RelationMemberTransferable implements Transferable { 15 16 public static final DataFlavor RELATION_MEMBER_DATA = new DataFlavor(RelationMemberData.class, RelationMemberData.class.getName()); 17 private final Collection<RelationMember> members; 18 19 public RelationMemberTransferable(Collection<RelationMember> members) { 20 this.members = members; 21 } 22 23 @Override 24 public DataFlavor[] getTransferDataFlavors() { 25 return new DataFlavor[]{RELATION_MEMBER_DATA, DataFlavor.stringFlavor}; 26 } 27 28 @Override 29 public boolean isDataFlavorSupported(DataFlavor flavor) { 30 return flavor == RELATION_MEMBER_DATA; 31 } 32 33 @Override 34 public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException { 35 if (DataFlavor.stringFlavor.equals(flavor)) { 36 return getStringData(); 37 } else if (RELATION_MEMBER_DATA.equals(flavor)) { 38 return getRelationMemberData(); 39 } 40 throw new UnsupportedFlavorException(flavor); 41 } 42 43 protected String getStringData() { 44 final StringBuilder sb = new StringBuilder(); 45 for (RelationMember member : members) { 46 sb.append(member.getType()); 47 sb.append(" ").append(member.getUniqueId()); 48 sb.append(" ").append(member.getRole()); 49 sb.append(" #").append(member.getMember().getDisplayName(DefaultNameFormatter.getInstance())); 50 sb.append("\n"); 51 } 52 return sb.toString().replace("\u200E", "").replace("\u200F", ""); 53 } 54 55 protected Collection<RelationMemberData> getRelationMemberData() { 56 final Collection<RelationMemberData> r = new ArrayList<>(members.size()); 57 for (RelationMember member : members) { 58 r.add(new RelationMemberData(member.getRole(), member.getType(), member.getUniqueId())); 59 } 60 return r; 61 } 62 } -
src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java
diff --git a/src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java b/src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java index f9cdafd..9c9ec79 100644
a b 6 6 7 7 import java.awt.Component; 8 8 import java.awt.Rectangle; 9 import java.awt.datatransfer.Transferable; 9 10 import java.awt.event.ActionEvent; 10 11 import java.awt.event.ActionListener; 11 12 import java.awt.event.KeyEvent; … … 23 24 import javax.swing.AbstractAction; 24 25 import javax.swing.AbstractListModel; 25 26 import javax.swing.DefaultListSelectionModel; 27 import javax.swing.JComponent; 26 28 import javax.swing.JList; 27 29 import javax.swing.JMenuItem; 28 30 import javax.swing.JPopupMenu; 29 31 import javax.swing.ListSelectionModel; 32 import javax.swing.TransferHandler; 30 33 import javax.swing.event.ListDataEvent; 31 34 import javax.swing.event.ListDataListener; 32 35 import javax.swing.event.ListSelectionEvent; … … 65 68 import org.openstreetmap.josm.gui.OsmPrimitivRenderer; 66 69 import org.openstreetmap.josm.gui.PopupMenuHandler; 67 70 import org.openstreetmap.josm.gui.SideButton; 71 import org.openstreetmap.josm.gui.datatransfer.PrimitiveTransferable; 68 72 import org.openstreetmap.josm.gui.history.HistoryBrowserDialogManager; 69 73 import org.openstreetmap.josm.gui.layer.OsmDataLayer; 70 74 import org.openstreetmap.josm.gui.util.GuiHelper; … … protected void buildContentPanel() { 107 111 lstPrimitives.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 108 112 lstPrimitives.setSelectionModel(selectionModel); 109 113 lstPrimitives.setCellRenderer(new OsmPrimitivRenderer()); 110 // Fix #6290. Drag & Drop is not supported anyway and Copy/Paste is better propagated to main window111 lstPrimitives.set TransferHandler(null);114 lstPrimitives.setTransferHandler(new SelectionTransferHandler()); 115 lstPrimitives.setDragEnabled(true); 112 116 113 117 lstPrimitives.getSelectionModel().addListSelectionListener(actSelect); 114 118 lstPrimitives.getSelectionModel().addListSelectionListener(actShowHistory); … … public SelectionHistoryPopup(Collection<Collection<? extends OsmPrimitive>> hist 854 858 } 855 859 } 856 860 } 861 862 /** 863 * A transfer handler class for drag-and-drop support. 864 */ 865 protected class SelectionTransferHandler extends TransferHandler { 866 867 @Override 868 public int getSourceActions(JComponent c) { 869 return COPY; 870 } 871 872 @Override 873 protected Transferable createTransferable(JComponent c) { 874 return new PrimitiveTransferable(getSelectedPrimitives()); 875 } 876 } 857 877 } -
src/org/openstreetmap/josm/gui/dialogs/relation/MemberTable.java
diff --git a/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTable.java b/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTable.java index 3d41fd3..9eb25c7 100644
a b 14 14 import java.util.List; 15 15 16 16 import javax.swing.AbstractAction; 17 import javax.swing.DropMode; 17 18 import javax.swing.JComponent; 18 19 import javax.swing.JPopupMenu; 19 20 import javax.swing.JTable; … … protected void init() { 82 83 // 83 84 getActionMap().put("selectNextColumnCell", new SelectNextColumnCellAction()); 84 85 getActionMap().put("selectPreviousColumnCell", new SelectPreviousColumnCellAction()); 86 87 setTransferHandler(new MemberTransferHandler()); 88 setFillsViewportHeight(true); // allow drop on empty table 89 setDragEnabled(true); 90 setDropMode(DropMode.INSERT_ROWS); 85 91 } 86 92 87 93 @Override -
src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java
diff --git a/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java b/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java index f87ef71..7564a7e 100644
a b public boolean hasIncompleteSelectedMembers() { 422 422 } 423 423 424 424 private void addMembersAtIndex(List<? extends OsmPrimitive> primitives, int index) { 425 final Collection<TaggingPreset> presets = TaggingPresets.getMatchingPresets(EnumSet.of(TaggingPresetType.RELATION),426 presetHandler.getSelection().iterator().next().getKeys(), false);427 425 if (primitives == null) 428 426 return; 429 427 int idx = index; 430 428 for (OsmPrimitive primitive : primitives) { 431 Set<String> potentialRoles = new TreeSet<>(); 432 for (TaggingPreset tp : presets) { 433 String suggestedRole = tp.suggestRoleForOsmPrimitive(primitive); 434 if (suggestedRole != null) { 435 potentialRoles.add(suggestedRole); 436 } 437 } 438 // TODO: propose user to choose role among potential ones instead of picking first one 439 final String role = potentialRoles.isEmpty() ? null : potentialRoles.iterator().next(); 440 RelationMember member = new RelationMember(role == null ? "" : role, primitive); 429 final RelationMember member = getRelationMemberForPrimitive(primitive); 441 430 members.add(idx++, member); 442 431 } 443 432 fireTableDataChanged(); … … private void addMembersAtIndex(List<? extends OsmPrimitive> primitives, int inde 446 435 fireMakeMemberVisible(index); 447 436 } 448 437 438 RelationMember getRelationMemberForPrimitive(final OsmPrimitive primitive) { 439 final Collection<TaggingPreset> presets = TaggingPresets.getMatchingPresets(EnumSet.of(TaggingPresetType.RELATION), 440 presetHandler.getSelection().iterator().next().getKeys(), false); 441 Collection<String> potentialRoles = new TreeSet<>(); 442 for (TaggingPreset tp : presets) { 443 String suggestedRole = tp.suggestRoleForOsmPrimitive(primitive); 444 if (suggestedRole != null) { 445 potentialRoles.add(suggestedRole); 446 } 447 } 448 // TODO: propose user to choose role among potential ones instead of picking first one 449 final String role = potentialRoles.isEmpty() ? "" : potentialRoles.iterator().next(); 450 return new RelationMember(role == null ? "" : role, primitive); 451 } 452 453 void addMembersAtIndex(final Iterable<RelationMember> newMembers, final int index) { 454 int idx = index; 455 for (RelationMember member : newMembers) { 456 members.add(idx++, member); 457 } 458 fireTableRowsInserted(index, idx - 1); 459 } 460 449 461 public void addMembersAtBeginning(List<? extends OsmPrimitive> primitives) { 450 462 addMembersAtIndex(primitives, 0); 451 463 } -
new file src/org/openstreetmap/josm/gui/dialogs/relation/MemberTransferHandler.java
diff --git a/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTransferHandler.java b/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTransferHandler.java new file mode 100644 index 0000000..b4c42c7
- + 1 // License: GPL. For details, see LICENSE file. 2 package org.openstreetmap.josm.gui.dialogs.relation; 3 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 6 import java.awt.datatransfer.Transferable; 7 import java.awt.datatransfer.UnsupportedFlavorException; 8 import java.io.IOException; 9 import java.util.ArrayList; 10 import java.util.Collection; 11 12 import javax.swing.JComponent; 13 import javax.swing.JTable; 14 import javax.swing.TransferHandler; 15 16 import org.openstreetmap.josm.Main; 17 import org.openstreetmap.josm.data.osm.OsmPrimitive; 18 import org.openstreetmap.josm.data.osm.PrimitiveData; 19 import org.openstreetmap.josm.data.osm.RelationMember; 20 import org.openstreetmap.josm.data.osm.RelationMemberData; 21 import org.openstreetmap.josm.gui.datatransfer.PrimitiveTransferable; 22 import org.openstreetmap.josm.gui.datatransfer.RelationMemberTransferable; 23 import org.openstreetmap.josm.tools.Utils.Function; 24 25 class MemberTransferHandler extends TransferHandler { 26 27 @Override 28 public int getSourceActions(JComponent c) { 29 return COPY_OR_MOVE; 30 } 31 32 @Override 33 protected Transferable createTransferable(JComponent c) { 34 final MemberTable source = (MemberTable) c; 35 return new RelationMemberTransferable(source.getMemberTableModel().getSelectedMembers()); 36 } 37 38 @Override 39 public boolean canImport(TransferSupport support) { 40 support.setShowDropLocation(true); 41 return support.isDataFlavorSupported(RelationMemberTransferable.RELATION_MEMBER_DATA) 42 || support.isDataFlavorSupported(PrimitiveTransferable.PRIMITIVE_DATA); 43 } 44 45 @Override 46 public boolean importData(TransferSupport support) { 47 final MemberTable destination = (MemberTable) support.getComponent(); 48 final int insertRow = ((JTable.DropLocation) support.getDropLocation()).getRow(); 49 50 try { 51 if (support.isDataFlavorSupported(RelationMemberTransferable.RELATION_MEMBER_DATA)) { 52 importRelationMemberData(support, destination, insertRow); 53 } else if (support.isDataFlavorSupported(PrimitiveTransferable.PRIMITIVE_DATA)) { 54 importPrimitiveData(support, destination, insertRow); 55 } 56 } catch (Exception e) { 57 Main.warn(e); 58 return false; 59 } 60 61 return true; 62 } 63 64 protected void importRelationMemberData(TransferSupport support, final MemberTable destination, int insertRow) 65 throws UnsupportedFlavorException, IOException { 66 //noinspection unchecked 67 final Collection<RelationMemberData> memberData = (Collection<RelationMemberData>) 68 support.getTransferable().getTransferData(RelationMemberTransferable.RELATION_MEMBER_DATA); 69 importData(destination, insertRow, memberData, new Function<RelationMemberData, RelationMember>() { 70 @Override 71 public RelationMember apply(RelationMemberData member) { 72 final OsmPrimitive p = destination.getLayer().data.getPrimitiveById(member.getUniqueId(), member.getType()); 73 if (p == null) { 74 Main.warn(tr("Cannot add {0} since it is not part of dataset", member)); 75 return null; 76 } else { 77 return new RelationMember(member.getRole(), p); 78 } 79 } 80 }); 81 } 82 83 protected void importPrimitiveData(TransferSupport support, final MemberTable destination, int insertRow) 84 throws UnsupportedFlavorException, IOException { 85 //noinspection unchecked 86 final Collection<PrimitiveData> data = (Collection<PrimitiveData>) 87 support.getTransferable().getTransferData(PrimitiveTransferable.PRIMITIVE_DATA); 88 importData(destination, insertRow, data, new Function<PrimitiveData, RelationMember>() { 89 @Override 90 public RelationMember apply(PrimitiveData data) { 91 final OsmPrimitive p = destination.getLayer().data.getPrimitiveById(data); 92 if (p == null) { 93 Main.warn(tr("Cannot add {0} since it is not part of dataset", data)); 94 return null; 95 } else { 96 return destination.getMemberTableModel().getRelationMemberForPrimitive(p); 97 } 98 } 99 }); 100 } 101 102 protected <T> void importData(MemberTable destination, int insertRow, Collection<T> memberData, Function<T, RelationMember> toMemberFunction) { 103 final Collection<RelationMember> membersToAdd = new ArrayList<>(memberData.size()); 104 for (T i : memberData) { 105 final RelationMember member = toMemberFunction.apply(i); 106 if (member != null) { 107 membersToAdd.add(member); 108 } 109 } 110 destination.getMemberTableModel().addMembersAtIndex(membersToAdd, insertRow); 111 } 112 113 @Override 114 protected void exportDone(JComponent sourceComponent, Transferable data, int action) { 115 if (action != MOVE) { 116 return; 117 } 118 final MemberTable source = (MemberTable) sourceComponent; 119 final MemberTableModel model = source.getMemberTableModel(); 120 model.remove(source.getSelectedRows()); 121 model.selectionChanged(null); 122 } 123 }
