Changeset 3384 in josm


Ignore:
Timestamp:
2010-07-25T15:56:14+02:00 (14 years ago)
Author:
jttt
Message:

Support Copy&Paste in relation editor

Location:
trunk/src/org/openstreetmap/josm
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/CopyAction.java

    r2892 r3384  
    33package org.openstreetmap.josm.actions;
    44
     5import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
    56import static org.openstreetmap.josm.tools.I18n.tr;
    6 import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
    77
    88import java.awt.Toolkit;
     
    1414import java.awt.event.KeyEvent;
    1515import java.util.Collection;
    16 import java.util.LinkedList;
    1716
    1817import javax.swing.JOptionPane;
     
    2019import org.openstreetmap.josm.Main;
    2120import org.openstreetmap.josm.data.osm.OsmPrimitive;
     21import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    2222import org.openstreetmap.josm.tools.Shortcut;
    2323
    2424public final class CopyAction extends JosmAction {
    25 
    26     private LinkedList<JosmAction> listeners;
    2725
    2826    public CopyAction() {
     
    3129                Shortcut.registerShortcut("system:copy", tr("Edit: {0}", tr("Copy")), KeyEvent.VK_C, Shortcut.GROUP_MENU), true);
    3230        putValue("help", ht("/Action/Copy"));
    33         listeners = new LinkedList<JosmAction>();
    34     }
    35 
    36     @Override public void addListener(JosmAction a) {
    37         listeners.add(a);
    3831    }
    3932
     
    4235        Collection<OsmPrimitive> selection = getCurrentDataSet().getSelected();
    4336
     37        copy(getEditLayer(), selection);
     38    }
     39
     40    public static void copy(OsmDataLayer source, Collection<OsmPrimitive> primitives) {
    4441        /* copy ids to the clipboard */
    4542        StringBuilder idsBuilder = new StringBuilder();
    46         for (OsmPrimitive p : selection) {
     43        for (OsmPrimitive p : primitives) {
    4744            idsBuilder.append(p.getId()+",");
    4845        }
     
    5653        }
    5754        catch (RuntimeException x) {}
    58        
    59         Main.pasteBuffer.makeCopy(selection);
    60         Main.pasteSource = getEditLayer();
    61         Main.main.menu.paste.setEnabled(true); /* now we have a paste buffer we can make paste available */
    6255
    63         for(JosmAction a : listeners) {
    64             a.pasteBufferChanged(Main.pasteBuffer);
    65         }
     56        Main.pasteBuffer.makeCopy(primitives);
     57        Main.pasteSource = source;
    6658    }
    6759
  • trunk/src/org/openstreetmap/josm/actions/JosmAction.java

    r3327 r3384  
    1212import org.openstreetmap.josm.data.osm.DataSet;
    1313import org.openstreetmap.josm.data.osm.OsmPrimitive;
    14 import org.openstreetmap.josm.data.osm.PrimitiveDeepCopy;
    1514import org.openstreetmap.josm.gui.MapView;
    1615import org.openstreetmap.josm.gui.layer.Layer;
     
    103102     * needs to be overridden to be useful
    104103     */
    105     public void pasteBufferChanged(PrimitiveDeepCopy newPasteBuffer) {
    106         return;
    107     }
    108 
    109     /**
    110      * needs to be overridden to be useful
    111      */
    112104    public void addListener(JosmAction a) {
    113105        return;
  • trunk/src/org/openstreetmap/josm/actions/PasteAction.java

    r2932 r3384  
    2323import org.openstreetmap.josm.data.osm.RelationMemberData;
    2424import org.openstreetmap.josm.data.osm.WayData;
     25import org.openstreetmap.josm.data.osm.PrimitiveDeepCopy.PasteBufferChangedListener;
    2526import org.openstreetmap.josm.gui.ExtendedDialog;
    2627import org.openstreetmap.josm.gui.layer.Layer;
    2728import org.openstreetmap.josm.tools.Shortcut;
    2829
    29 public final class PasteAction extends JosmAction {
     30public final class PasteAction extends JosmAction implements PasteBufferChangedListener {
    3031
    3132    public PasteAction() {
     
    3334                Shortcut.registerShortcut("system:paste", tr("Edit: {0}", tr("Paste")), KeyEvent.VK_V, Shortcut.GROUP_MENU), true);
    3435        putValue("help", ht("/Action/Paste"));
     36        Main.pasteBuffer.addPasteBufferChangedListener(this);
    3537    }
    3638
     
    167169        setEnabled(!Main.pasteBuffer.isEmpty());
    168170    }
     171
     172    @Override
     173    public void pasteBufferChanged(PrimitiveDeepCopy pasteBuffer) {
     174        updateEnabledState();
     175    }
    169176}
  • trunk/src/org/openstreetmap/josm/actions/PasteTagsAction.java

    r2512 r3384  
    33package org.openstreetmap.josm.actions;
    44
     5import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
    56import static org.openstreetmap.josm.tools.I18n.tr;
    6 import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
    77import static org.openstreetmap.josm.tools.I18n.trn;
    88
     
    2424import org.openstreetmap.josm.data.osm.PrimitiveDeepCopy;
    2525import org.openstreetmap.josm.data.osm.TagCollection;
     26import org.openstreetmap.josm.data.osm.PrimitiveDeepCopy.PasteBufferChangedListener;
    2627import org.openstreetmap.josm.gui.conflict.tags.PasteTagsConflictResolverDialog;
    2728import org.openstreetmap.josm.tools.Shortcut;
    2829
    29 public final class PasteTagsAction extends JosmAction {
     30public final class PasteTagsAction extends JosmAction implements PasteBufferChangedListener {
    3031
    3132    public PasteTagsAction(JosmAction copyAction) {
     
    3334                tr("Apply tags of contents of paste buffer to all selected items."),
    3435                Shortcut.registerShortcut("system:pastestyle", tr("Edit: {0}", tr("Paste Tags")), KeyEvent.VK_V, Shortcut.GROUP_MENU, Shortcut.SHIFT_DEFAULT), true);
    35         copyAction.addListener(this);
     36        Main.pasteBuffer.addPasteBufferChangedListener(this);
    3637        putValue("help", ht("/Action/PasteTags"));
    3738    }
  • trunk/src/org/openstreetmap/josm/data/osm/PrimitiveDeepCopy.java

    r3083 r3384  
    77import java.util.List;
    88import java.util.Set;
     9import java.util.concurrent.CopyOnWriteArrayList;
    910
    1011import org.openstreetmap.josm.data.osm.visitor.AbstractVisitor;
     
    1718public class PrimitiveDeepCopy {
    1819
     20    public interface PasteBufferChangedListener {
     21        void pasteBufferChanged(PrimitiveDeepCopy pasteBuffer);
     22    }
     23
    1924    private final List<PrimitiveData> directlyAdded = new ArrayList<PrimitiveData>();
    2025    private final List<PrimitiveData> referenced = new ArrayList<PrimitiveData>();
     26    private final CopyOnWriteArrayList<PasteBufferChangedListener> listeners = new CopyOnWriteArrayList<PasteBufferChangedListener>();
    2127
    2228    public PrimitiveDeepCopy() {
     
    7480            }
    7581        }.visitAll();
     82
     83        firePasteBufferChanged();
    7684    }
    7785
     
    95103    }
    96104
     105    private void firePasteBufferChanged() {
     106        for (PasteBufferChangedListener listener: listeners) {
     107            listener.pasteBufferChanged(this);
     108        }
     109    }
     110
     111    public void addPasteBufferChangedListener(PasteBufferChangedListener listener) {
     112        listeners.addIfAbsent(listener);
     113    }
     114
     115    public void removePasteBufferChangedListener(PasteBufferChangedListener listener) {
     116        listeners.remove(listener);
     117    }
     118
    97119}
  • trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java

    r3289 r3384  
    2727import java.util.Iterator;
    2828import java.util.List;
     29import java.util.Set;
    2930import java.util.logging.Logger;
    3031
     
    5051
    5152import org.openstreetmap.josm.Main;
     53import org.openstreetmap.josm.actions.CopyAction;
    5254import org.openstreetmap.josm.command.AddCommand;
    5355import org.openstreetmap.josm.command.ChangeCommand;
     
    5658import org.openstreetmap.josm.data.osm.DataSet;
    5759import org.openstreetmap.josm.data.osm.OsmPrimitive;
     60import org.openstreetmap.josm.data.osm.PrimitiveData;
    5861import org.openstreetmap.josm.data.osm.Relation;
    5962import org.openstreetmap.josm.data.osm.RelationMember;
     
    9194
    9295    /** the model for the selection table */
     96    private SelectionTable selectionTable;
    9397    private SelectionTableModel selectionTableModel;
    9498
     
    383387        pnl3.setLayout(new BorderLayout());
    384388        pnl3.add(splitPane, BorderLayout.CENTER);
     389
     390        new PasteMembersAction();
     391        new CopyMembersAction();
     392
    385393        return pnl3;
    386394    }
     
    394402        JPanel pnl = new JPanel();
    395403        pnl.setLayout(new BorderLayout());
    396         SelectionTable tbl = new SelectionTable(selectionTableModel, new SelectionTableColumnModel(memberTableModel));
    397         tbl.setMemberTableModel(memberTableModel);
    398         JScrollPane pane = new JScrollPane(tbl);
     404        selectionTable = new SelectionTable(selectionTableModel, new SelectionTableColumnModel(memberTableModel));
     405        selectionTable.setMemberTableModel(memberTableModel);
     406        JScrollPane pane = new JScrollPane(selectionTable);
    399407        pnl.add(pane, BorderLayout.CENTER);
    400408        return pnl;
     
    591599    }
    592600
     601    private void registerCopyPasteAction(AbstractAction action, Object actionName, KeyStroke shortcut) {
     602        getRootPane().getActionMap().put(actionName, action);
     603        getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(shortcut, actionName);
     604        // Assign also to JTables because they have their own Copy&Paste implementation (which is disabled in this case but eats key shortcuts anyway)
     605        memberTable.getInputMap(JComponent.WHEN_FOCUSED).put(shortcut, actionName);
     606        memberTable.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(shortcut, actionName);
     607        memberTable.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(shortcut, actionName);
     608        selectionTable.getInputMap(JComponent.WHEN_FOCUSED).put(shortcut, actionName);
     609        selectionTable.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(shortcut, actionName);
     610        selectionTable.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(shortcut, actionName);
     611    }
     612
    593613    static class AddAbortException extends Exception  {
    594614    }
     
    14421462    }
    14431463
     1464    class PasteMembersAction extends AddFromSelectionAction {
     1465
     1466        public PasteMembersAction() {
     1467            registerCopyPasteAction(this, "PASTE_MEMBERS", Shortcut.getPasteKeyStroke());
     1468        }
     1469
     1470        @Override
     1471        public void actionPerformed(ActionEvent e) {
     1472            try {
     1473                List<PrimitiveData> primitives = Main.pasteBuffer.getDirectlyAdded();
     1474                DataSet ds = getLayer().data;
     1475                List<OsmPrimitive> toAdd = new ArrayList<OsmPrimitive>();
     1476                boolean hasNewInOtherLayer = false;
     1477
     1478                for (PrimitiveData primitive: primitives) {
     1479                    OsmPrimitive primitiveInDs = ds.getPrimitiveById(primitive);
     1480                    if (primitiveInDs != null) {
     1481                        toAdd.add(primitiveInDs);
     1482                    } else if (!primitive.isNew()) {
     1483                        toAdd.add(ds.getPrimitiveById(primitive, true));
     1484                    } else {
     1485                        hasNewInOtherLayer = true;
     1486                        break;
     1487                    }
     1488                }
     1489
     1490                if (hasNewInOtherLayer) {
     1491                    JOptionPane.showMessageDialog(Main.parent, tr("Members from paste buffer cannot be added because they are not included in current layer"));
     1492                    return;
     1493                }
     1494
     1495                toAdd = filterConfirmedPrimitives(toAdd);
     1496                memberTableModel.addMembersAfterIdx(toAdd, memberTableModel
     1497                        .getSelectionModel().getMaxSelectionIndex());
     1498
     1499                tfRole.requestFocusInWindow();
     1500
     1501            } catch (AddAbortException ex) {
     1502                // Do nothing
     1503            }
     1504        }
     1505    }
     1506
     1507    class CopyMembersAction extends AbstractAction {
     1508
     1509        public CopyMembersAction() {
     1510            registerCopyPasteAction(this, "COPY_MEMBERS", Shortcut.getCopyKeyStroke());
     1511        }
     1512
     1513        @Override
     1514        public void actionPerformed(ActionEvent e) {
     1515            Set<OsmPrimitive> primitives = new HashSet<OsmPrimitive>();
     1516            for (RelationMember rm: memberTableModel.getSelectedMembers()) {
     1517                primitives.add(rm.getMember());
     1518            }
     1519            if (!primitives.isEmpty()) {
     1520                CopyAction.copy(getLayer(), primitives);
     1521            }
     1522        }
     1523
     1524    }
     1525
    14441526    class MemberTableDblClickAdapter extends MouseAdapter {
    14451527        @Override
Note: See TracChangeset for help on using the changeset viewer.