Changeset 4773 in josm


Ignore:
Timestamp:
2012-01-08T17:38:25+01:00 (12 years ago)
Author:
bastiK
Message:

applied #6883 - property toggle dialog: possibility to select and perform actions on several entries at once. (patch by joshdoe)

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

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/command/ChangePropertyCommand.java

    r4302 r4773  
    55import static org.openstreetmap.josm.tools.I18n.tr;
    66
     7import java.util.AbstractMap;
    78import java.util.ArrayList;
    89import java.util.Arrays;
    910import java.util.Collection;
    1011import java.util.Collections;
     12import java.util.HashMap;
    1113import java.util.LinkedList;
    1214import java.util.List;
     15import java.util.Map;
    1316
    1417import javax.swing.JLabel;
     
    3235    private final List<OsmPrimitive> objects;
    3336    /**
    34      * The key that is subject to change.
    35      */
    36     private final String key;
    37     /**
    38      * The key value. If it is <code>null</code>, delete all key references with the given
     37     * Key and value pairs. If value is <code>null</code>, delete all key references with the given
    3938     * key. Otherwise, change the properties of all objects to the given value or create keys of
    4039     * those objects that do not have the key yet.
    4140     */
    42     private final String value;
    43 
    44     public ChangePropertyCommand(Collection<? extends OsmPrimitive> objects, String key, String value) {
     41    private final AbstractMap<String, String> tags;
     42
     43    /**
     44     * Creates a command to change multiple properties of multiple objects
     45     *
     46     * @param objects the objects to modify
     47     * @param tags the properties to set
     48     */
     49    public ChangePropertyCommand(Collection<? extends OsmPrimitive> objects, AbstractMap<String, String> tags) {
    4550        super();
    4651        this.objects = new LinkedList<OsmPrimitive>();
    47         this.key = key;
    48         this.value = (value == null || value.isEmpty()) ? null : value;
    49         if (this.value == null) {
    50             for (OsmPrimitive osm : objects) {
    51                 if(osm.get(key) != null) {
    52                     this.objects.add(osm);
    53                 }
    54             }
    55         } else {
    56             for (OsmPrimitive osm : objects) {
    57                 String val = osm.get(key);
    58                 if (val == null || !this.value.equals(val)) {
    59                     this.objects.add(osm);
    60                 }
    61             }
    62         }
    63     }
    64 
     52        this.tags = tags;
     53        init(objects);
     54    }
     55
     56    /**
     57     * Creates a command to change one property of multiple objects
     58     *
     59     * @param objects the objects to modify
     60     * @param key the key of the property to set
     61     * @param value the value of the key to set
     62     */
     63    public ChangePropertyCommand(Collection<? extends OsmPrimitive> objects, String key, String value) {
     64        this.objects = new LinkedList<OsmPrimitive>();
     65        this.tags = new HashMap<String, String>(1);
     66        this.tags.put(key, value);
     67        init(objects);
     68    }
     69
     70    /**
     71     * Creates a command to change on property of one object
     72     *
     73     * @param object the object to modify
     74     * @param key the key of the property to set
     75     * @param value the value of the key to set
     76     */
    6577    public ChangePropertyCommand(OsmPrimitive object, String key, String value) {
    6678        this(Arrays.asList(object), key, value);
     79    }
     80
     81    /**
     82     * Initialize the instance by finding what objects will be modified
     83     *
     84     * @param objects the objects to (possibly) modify
     85     */
     86    private void init(Collection<? extends OsmPrimitive> objects) {
     87        // determine what objects will be modified
     88        for (OsmPrimitive osm : objects) {
     89            boolean modified = false;
     90
     91            // loop over all tags
     92            for (Map.Entry<String, String> tag : this.tags.entrySet()) {
     93                String oldVal = osm.get(tag.getKey());
     94                String newVal = tag.getValue();
     95
     96                if (newVal == null || newVal.isEmpty()) {
     97                    if (oldVal != null)
     98                        // new value is null and tag exists (will delete tag)
     99                        modified = true;
     100                }
     101                else if (oldVal == null || !newVal.equals(oldVal))
     102                    // new value is not null and is different from current value
     103                    modified = true;
     104            }
     105            if (modified)
     106                this.objects.add(osm);
     107        }
    67108    }
    68109
     
    71112        try {
    72113            super.executeCommand(); // save old
    73             if (value == null) {
    74                 for (OsmPrimitive osm : objects) {
     114
     115            for (OsmPrimitive osm : objects) {
     116                boolean modified = false;
     117
     118                 // loop over all tags
     119                for (Map.Entry<String, String> tag : this.tags.entrySet()) {
     120                    String oldVal = osm.get(tag.getKey());
     121                    String newVal = tag.getValue();
     122
     123                    if (newVal == null || newVal.isEmpty()) {
     124                        if (oldVal != null) {
     125                            osm.remove(tag.getKey());
     126                            modified = true;
     127                        }
     128                    }
     129                    else if (oldVal == null || !newVal.equals(oldVal))
     130                        osm.put(tag.getKey(), newVal);
     131                        modified = true;
     132                }
     133                if (modified)
    75134                    osm.setModified(true);
    76                     osm.remove(key);
    77                 }
    78             } else {
    79                 for (OsmPrimitive osm : objects) {
    80                     osm.setModified(true);
    81                     osm.put(key, value);
    82                 }
    83135            }
    84136            return true;
     
    95147    @Override public JLabel getDescription() {
    96148        String text;
    97         if (objects.size() == 1) {
     149        if (objects.size() == 1 && tags.size() == 1) {
    98150            OsmPrimitive primitive = objects.iterator().next();
    99151            String msg = "";
    100             if (value == null) {
     152            Map.Entry<String, String> entry = tags.entrySet().iterator().next();
     153            if (entry.getValue() == null) {
    101154                switch(OsmPrimitiveType.from(primitive)) {
    102155                case NODE: msg = marktr("Remove \"{0}\" for node ''{1}''"); break;
     
    104157                case RELATION: msg = marktr("Remove \"{0}\" for relation ''{1}''"); break;
    105158                }
    106                 text = tr(msg, key, primitive.getDisplayName(DefaultNameFormatter.getInstance()));
     159                text = tr(msg, entry.getKey(), primitive.getDisplayName(DefaultNameFormatter.getInstance()));
    107160            } else {
    108161                switch(OsmPrimitiveType.from(primitive)) {
     
    111164                case RELATION: msg = marktr("Set {0}={1} for relation ''{2}''"); break;
    112165                }
    113                 text = tr(msg, key, value, primitive.getDisplayName(DefaultNameFormatter.getInstance()));
    114             }
    115         } else {
    116             text = value == null
    117             ? tr("Remove \"{0}\" for {1} objects", key, objects.size())
    118                     : tr("Set {0}={1} for {2} objects", key, value, objects.size());
     166                text = tr(msg, entry.getKey(), entry.getValue(), primitive.getDisplayName(DefaultNameFormatter.getInstance()));
     167            }
     168        } else if (objects.size() > 1 && tags.size() == 1) {
     169            Map.Entry<String, String> entry = tags.entrySet().iterator().next();
     170            if (entry.getValue() == null)
     171                text = tr("Remove \"{0}\" for {1} objects", entry.getKey(), objects.size());
     172            else
     173                text = tr("Set {0}={1} for {2} objects", entry.getKey(), entry.getValue(), objects.size());
     174        }
     175        else {
     176            boolean allnull = true;
     177            for (Map.Entry<String, String> tag : this.tags.entrySet()) {
     178                if (tag.getValue() != null) {
     179                    allnull = false;
     180                    break;
     181                }
     182            }
     183           
     184            if (allnull) {
     185                text = tr("Deleted {0} properties for {1} objects", tags.size(), objects.size());
     186            } else
     187                text = tr("Set {0} properties for {1} objects", tags.size(), objects.size());
    119188        }
    120189        return new JLabel(text, ImageProvider.get("data", "key"), JLabel.HORIZONTAL);
  • trunk/src/org/openstreetmap/josm/gui/dialogs/properties/PropertiesDialog.java

    r4697 r4773  
    10451045        }
    10461046
    1047         protected void deleteProperty(int row){
    1048             String key = propertyData.getValueAt(row, 0).toString();
    1049 
     1047        protected void deleteProperties(int[] rows){
     1048            // convert list of rows to HashMap (and find gap for nextKey)
     1049            HashMap<String, String> tags = new HashMap<String, String>(rows.length);
     1050            int nextKeyIndex = rows[0];
     1051            for (int row : rows) {
     1052                String key = propertyData.getValueAt(row, 0).toString();
     1053                if (row == nextKeyIndex + 1)
     1054                    nextKeyIndex = row; // no gap yet
     1055                tags.put(key, null);
     1056            }
     1057
     1058            // find key to select after deleting other properties
    10501059            String nextKey = null;
    10511060            int rowCount = propertyData.getRowCount();
    1052             if (rowCount > 1) {
    1053                 nextKey = (String)propertyData.getValueAt((row + 1 < rowCount ? row + 1 : row - 1), 0);
     1061            if (rowCount > rows.length) {
     1062                if (nextKeyIndex == rows[rows.length-1])
     1063                    // no gap found, pick next or previous key in list
     1064                    nextKeyIndex = (nextKeyIndex + 1 < rowCount ? nextKeyIndex + 1 : rows[0] - 1);
     1065                else
     1066                    // gap found
     1067                    nextKeyIndex++;
     1068                nextKey = (String)propertyData.getValueAt(nextKeyIndex, 0);
    10541069            }
    10551070
    10561071            Collection<OsmPrimitive> sel = Main.main.getCurrentDataSet().getSelected();
    1057             Main.main.undoRedo.add(new ChangePropertyCommand(sel, key, null));
     1072            Main.main.undoRedo.add(new ChangePropertyCommand(sel, tags));
    10581073
    10591074            membershipTable.clearSelection();
     
    11001115            if (propertyTable.getSelectedRowCount() > 0) {
    11011116                int[] rows = propertyTable.getSelectedRows();
    1102                 for (int i = rows.length - 1; i >= 0; i--) {
    1103                     deleteProperty(rows[i]);
    1104                 }
     1117                deleteProperties(rows);
    11051118            } else if (membershipTable.getSelectedRowCount() > 0) {
    11061119                int row = membershipTable.getSelectedRow();
Note: See TracChangeset for help on using the changeset viewer.