Changeset 4773 in josm


Ignore:
Timestamp:
Jan 8, 2012 5:38:25 PM (17 months 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.