

---

 core-dave/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java |   40 +++++-----
 core-dave/src/org/openstreetmap/josm/data/osm/DataSet.java             |   34 +++++---
 2 files changed, 43 insertions(+), 31 deletions(-)

diff -puN src/org/openstreetmap/josm/gui/SelectionManager.java~fix-shift-selection src/org/openstreetmap/josm/gui/SelectionManager.java
diff -puN src/org/openstreetmap/josm/actions/mapmode/SelectAction.java~fix-shift-selection src/org/openstreetmap/josm/actions/mapmode/SelectAction.java
--- core/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java~fix-shift-selection	2009-10-28 11:32:40.000000000 -0700
+++ core-dave/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java	2009-10-28 12:56:28.000000000 -0700
@@ -498,7 +498,7 @@ public class SelectAction extends MapMod
                         }
                     }
                 }
-                DataSet.fireSelectionChanged(selection);
+                getCurrentDataSet().fireSelectionChanged();
             }
         }
 
@@ -514,30 +514,30 @@ public class SelectAction extends MapMod
 
     public void selectPrims(Collection<OsmPrimitive> selectionList, boolean shift,
             boolean ctrl, boolean released, boolean area) {
+        DataSet ds = getCurrentDataSet();
         if ((shift && ctrl) || (ctrl && !released))
             return; // not allowed together
 
-        Collection<OsmPrimitive> curSel;
-        if (!ctrl && !shift) {
-            curSel = new LinkedList<OsmPrimitive>(); // new selection will replace the old.
+        // plain clicks with no modifiers clear the selection
+        if (!ctrl && !shift)
+            ds.clearSelection();
+
+        if (ctrl) {
+            // Ctrl on an item toggles its selection status,
+            // but Ctrl on an *area* just clears those items
+            // out of the selection.
+            if (area)
+                ds.clearSelection(selectionList);
+            else
+                ds.toggleSelected(selectionList);
         } else {
-            curSel = getCurrentDataSet().getSelected();
+            // This is either a plain click (which means we
+            // previously cleared the selection), or a
+            // shift-click where we are adding things to an
+            // existing selection.
+            ds.addSelected(selectionList);
         }
-
-        for (OsmPrimitive osm : selectionList)
-        {
-            if (ctrl)
-            {
-                if(curSel.contains(osm)) {
-                    curSel.remove(osm);
-                } else if(!area) {
-                    curSel.add(osm);
-                }
-            } else {
-                curSel.add(osm);
-            }
-        }
-        getCurrentDataSet().setSelected(curSel);
+        ds.fireSelectionChanged();
         Main.map.mapView.repaint();
     }
 
diff -puN src/org/openstreetmap/josm/data/osm/DataSet.java~fix-shift-selection src/org/openstreetmap/josm/data/osm/DataSet.java
--- core/src/org/openstreetmap/josm/data/osm/DataSet.java~fix-shift-selection	2009-10-28 11:33:04.000000000 -0700
+++ core-dave/src/org/openstreetmap/josm/data/osm/DataSet.java	2009-10-28 13:20:15.000000000 -0700
@@ -241,7 +241,16 @@ public class DataSet implements Cloneabl
 
     LinkedHashSet<OsmPrimitive> selectedPrimitives = new LinkedHashSet<OsmPrimitive>();
 
-    public boolean toggleSelected(OsmPrimitive osm) {
+    public boolean toggleSelected(Collection<OsmPrimitive> osm) {
+        for (OsmPrimitive o : osm)
+            this.__toggleSelected(o);
+        fireSelectionChanged();
+        return true;
+    }
+    public boolean toggleSelected(OsmPrimitive... osm) {
+        return this.toggleSelected(Arrays.asList(osm));
+    }
+    private boolean __toggleSelected(OsmPrimitive osm) {
         if (!selectedPrimitives.remove(osm)) {
             selectedPrimitives.add(osm);
         }
@@ -275,7 +284,7 @@ public class DataSet implements Cloneabl
     public void setSelected(Collection<? extends OsmPrimitive> selection, boolean fireSelectionChangeEvent) {
         selectedPrimitives = new LinkedHashSet<OsmPrimitive>(selection);
         if (fireSelectionChangeEvent) {
-            fireSelectionChanged(selection);
+            fireSelectionChanged();
         }
     }
 
@@ -313,7 +322,7 @@ public class DataSet implements Cloneabl
     public void addSelected(Collection<? extends OsmPrimitive> selection, boolean fireSelectionChangeEvent) {
         selectedPrimitives.addAll(selection);
         if (fireSelectionChangeEvent) {
-            fireSelectionChanged(selection);
+            fireSelectionChanged();
         }
     }
 
@@ -325,7 +334,7 @@ public class DataSet implements Cloneabl
         }
         List<OsmPrimitive> list = Arrays.asList(osm);
         setSelected(list);
-        fireSelectionChanged(list);
+        fireSelectionChanged();
     }
 
     /**
@@ -358,11 +367,14 @@ public class DataSet implements Cloneabl
     public void clearSelection(OsmPrimitive... osm) {
         clearSelection(Arrays.asList(osm));
     }
-    private void clearSelection(Collection<? extends OsmPrimitive> list) {
+    public void clearSelection(Collection<? extends OsmPrimitive> list) {
         if (list == null)
             return;
         selectedPrimitives.removeAll(list);
     }
+    public void clearSelection() {
+        selectedPrimitives = new LinkedHashSet<OsmPrimitive>();
+    }
 
     /**
      * Return all selected items in the collection.
@@ -379,12 +391,12 @@ public class DataSet implements Cloneabl
         return sel;
     }
 
-    /**
-     * Remember to fire an selection changed event. A call to this will not fire the event
-     * immediately. For more,
-     * @see SelectionChangedListener
-     */
-    public static void fireSelectionChanged(Collection<? extends OsmPrimitive> sel) {
+    public void fireSelectionChanged()
+    {
+        __fireSelectionChanged(selectedPrimitives);
+    }
+
+    public static void __fireSelectionChanged(Collection<? extends OsmPrimitive> sel) {
         for (SelectionChangedListener l : selListeners) {
             l.selectionChanged(sel);
         }
_
Index: src/org/openstreetmap/josm/actions/ReverseWayAction.java
===================================================================
--- josm/src/org/openstreetmap/josm/actions/ReverseWayAction.java	(revision 2340)
+++ /src/org/openstreetmap/josm/actions/ReverseWayAction.java	(working copy)
@@ -80,7 +80,7 @@
         }
         Main.main.undoRedo.add(new SequenceCommand(tr("Reverse ways"), c));
         if (propertiesUpdated) {
-            DataSet.fireSelectionChanged(getCurrentDataSet().getSelected());
+            getCurrentDataSet().fireSelectionChanged();
         }
         Main.map.repaint();
     }
Index: src/org/openstreetmap/josm/actions/mapmode/DrawAction.java
===================================================================
--- josm/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java	(revision 2340)
+++ /src/org/openstreetmap/josm/actions/mapmode/DrawAction.java	(working copy)
@@ -244,7 +244,7 @@
         // when exiting we let everybody know about the currently selected
         // primitives
         //
-        DataSet.fireSelectionChanged(getCurrentDataSet().getSelected());
+        getCurrentDataSet().fireSelectionChanged();
     }
 
     /**
@@ -271,7 +271,7 @@
 
     private void tryAgain(MouseEvent e) {
         getCurrentDataSet().setSelected();
-        DataSet.fireSelectionChanged(getCurrentDataSet().getSelected());
+        Main.main.getCurrentDataSet().fireSelectionChanged();
         mouseClicked(e);
     }
 
@@ -283,7 +283,7 @@
     private void finishDrawing() {
         // let everybody else know about the current selection
         //
-        DataSet.fireSelectionChanged(getCurrentDataSet().getSelected());
+        Main.main.getCurrentDataSet().fireSelectionChanged();
         lastUsedNode = null;
         wayIsFinished = true;
         Main.map.selectSelectTool(true);
@@ -584,7 +584,7 @@
                     (posn0 >= 1                             && targetNode.equals(selectedWay.getNode(posn0-1))) || // previous node
                     (posn0 < selectedWay.getNodesCount()-1) && targetNode.equals(selectedWay.getNode(posn0+1))) {  // next node
                 getCurrentDataSet().setSelected(targetNode);
-                DataSet.fireSelectionChanged(getCurrentDataSet().getSelected());
+                getCurrentDataSet().fireSelectionChanged();
                 lastUsedNode = targetNode;
                 return true;
             }
Index: src/org/openstreetmap/josm/actions/UploadAction.java
===================================================================
--- josm/src/org/openstreetmap/josm/actions/UploadAction.java	(revision 2340)
+++ /src/org/openstreetmap/josm/actions/UploadAction.java	(working copy)
@@ -687,7 +687,7 @@
             // partially uploaded
             //
             layer.cleanupAfterUpload(processedPrimitives);
-            DataSet.fireSelectionChanged(layer.data.getSelected());
+            layer.data.fireSelectionChanged();
             layer.fireDataChange();
             if (lastException != null) {
                 handleFailedUpload(lastException);
Index: src/org/openstreetmap/josm/gui/dialogs/RelationListDialog.java
===================================================================
--- josm/src/org/openstreetmap/josm/gui/dialogs/RelationListDialog.java	(revision 2340)
+++ /src/org/openstreetmap/josm/gui/dialogs/RelationListDialog.java	(working copy)
@@ -516,7 +516,7 @@
                 selection.add(model.getRelation(i));
             }
             Main.map.mapView.getEditLayer().data.setSelected(selection);
-            DataSet.fireSelectionChanged(selection);
+            Main.map.mapView.getEditLayer().data.fireSelectionChanged();
         }
 
         public void valueChanged(ListSelectionEvent e) {
@@ -544,7 +544,6 @@
                 members.addAll(r.getMemberPrimitives());
             }
             Main.map.mapView.getEditLayer().data.setSelected(members);
-            DataSet.fireSelectionChanged(members);
         }
 
         protected void updateEnabledState() {
Index: src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java
===================================================================
--- josm/src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java	(revision 2340)
+++ /src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java	(working copy)
@@ -266,7 +266,7 @@
                             commands));
         }
 
-        DataSet.fireSelectionChanged(sel);
+        Main.main.getCurrentDataSet().fireSelectionChanged();
         selectionChanged(sel); // update whole table
         Main.parent.repaint(); // repaint all - drawing could have been changed
 
@@ -354,7 +354,7 @@
         if (value.equals(""))
             return;
         Main.main.undoRedo.add(new ChangePropertyCommand(sel, key, value));
-        DataSet.fireSelectionChanged(sel);
+        Main.main.getCurrentDataSet().fireSelectionChanged();
         selectionChanged(sel); // update table
         Main.parent.repaint(); // repaint all - drawing could have been changed
     }
@@ -825,7 +825,7 @@
             String key = propertyData.getValueAt(row, 0).toString();
             Collection<OsmPrimitive> sel = Main.main.getCurrentDataSet().getSelected();
             Main.main.undoRedo.add(new ChangePropertyCommand(sel, key, null));
-            DataSet.fireSelectionChanged(sel);
+            Main.main.getCurrentDataSet().fireSelectionChanged();
             selectionChanged(sel); // update table
 
             int rowCount = propertyTable.getRowCount();
@@ -851,7 +851,7 @@
                 rel.removeMembersFor(primitive);
             }
             Main.main.undoRedo.add(new ChangeCommand(cur, rel));
-            DataSet.fireSelectionChanged(sel);
+            Main.main.getCurrentDataSet().fireSelectionChanged();
             selectionChanged(sel); // update whole table
         }
 
Index: src/org/openstreetmap/josm/gui/dialogs/relation/MemberTable.java
===================================================================
--- josm/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTable.java	(revision 2340)
+++ /src/org/openstreetmap/josm/gui/dialogs/relation/MemberTable.java	(working copy)
@@ -203,7 +203,6 @@
             int row = rows[0];
             OsmPrimitive primitive = getMemberTableModel().getReferredPrimitive(row);
             layer.data.setSelected(primitive);
-            DataSet.fireSelectionChanged(layer.data.getSelected());
             AutoScaleAction action = new AutoScaleAction("selection");
             action.autoScale();
         }
Index: src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java
===================================================================
--- josm/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java	(revision 2340)
+++ /src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java	(working copy)
@@ -882,7 +882,6 @@
 
         public void actionPerformed(ActionEvent e) {
             getLayer().data.setSelected(memberTableModel.getSelectedChildPrimitives());
-            DataSet.fireSelectionChanged(getLayer().data.getSelected());
         }
 
         public void valueChanged(ListSelectionEvent e) {
@@ -1005,7 +1004,7 @@
 
             // make sure everybody is notified about the changes
             //
-            DataSet.fireSelectionChanged(getLayer().data.getSelected());
+            getLayer().data.fireSelectionChanged();
             getLayer().fireDataChange();
             GenericRelationEditor.this.setRelation(newRelation);
             RelationDialogManager.getRelationDialogManager().updateContext(
@@ -1038,7 +1037,7 @@
             tagEditorPanel.getModel().applyToPrimitive(editedRelation);
             memberTableModel.applyToRelation(editedRelation);
             Main.main.undoRedo.add(new ChangeCommand(getRelation(), editedRelation));
-            DataSet.fireSelectionChanged(getLayer().data.getSelected());
+            getLayer().data.fireSelectionChanged();
             getLayer().fireDataChange();
             // this will refresh the snapshot and update the dialog title
             //
Index: src/org/openstreetmap/josm/gui/MapView.java
===================================================================
--- josm/src/org/openstreetmap/josm/gui/MapView.java	(revision 2340)
+++ /src/org/openstreetmap/josm/gui/MapView.java	(working copy)
@@ -502,7 +502,7 @@
         if (! (layer instanceof OsmDataLayer)) {
             if (getCurrentDataSet() != null) {
                 getCurrentDataSet().setSelected();
-                DataSet.fireSelectionChanged(getCurrentDataSet().getSelected());
+                getCurrentDataSet().fireSelectionChanged();
             }
         }
         Layer old = activeLayer;
Index: src/org/openstreetmap/josm/gui/MapStatus.java
===================================================================
--- josm/src/org/openstreetmap/josm/gui/MapStatus.java	(revision 2340)
+++ /src/org/openstreetmap/josm/gui/MapStatus.java	(working copy)
@@ -332,7 +332,7 @@
                     ds.addSelected(nextSelected);
                 }
             }
-            DataSet.fireSelectionChanged(ds.getSelected());
+            ds.fireSelectionChanged();
         }
 
         /**
@@ -462,7 +462,6 @@
                     DataSet ds = Main.main.getCurrentDataSet();
                     // Let the user toggle the selection
                     ds.toggleSelected(osm);
-                    DataSet.fireSelectionChanged(ds.getSelected());
                     l.validate();
                 }
             });
Index: src/org/openstreetmap/josm/gui/io/UploadLayerTask.java
===================================================================
--- josm/src/org/openstreetmap/josm/gui/io/UploadLayerTask.java	(revision 2340)
+++ /src/org/openstreetmap/josm/gui/io/UploadLayerTask.java	(working copy)
@@ -143,7 +143,7 @@
         if (isCancelled())
             return;
         layer.cleanupAfterUpload(processedPrimitives);
-        DataSet.fireSelectionChanged(layer.data.getSelected());
+        layer.data.fireSelectionChanged();;
         layer.fireDataChange();
         layer.onPostUploadToServer();
 
@@ -158,4 +158,4 @@
             writer.cancel();
         }
     }
-}
\ No newline at end of file
+}
Index: src/org/openstreetmap/josm/data/UndoRedoHandler.java
===================================================================
--- josm/src/org/openstreetmap/josm/data/UndoRedoHandler.java	(revision 2340)
+++ /src/org/openstreetmap/josm/data/UndoRedoHandler.java	(working copy)
@@ -49,7 +49,7 @@
         fireCommandsChanged();
 
         // the command may have changed the selection so tell the listeners about the current situation
-        DataSet.fireSelectionChanged(Main.main.getCurrentDataSet().getSelected());
+        Main.main.getCurrentDataSet().fireSelectionChanged();
     }
 
     /**
