Changeset 3908 in josm for trunk/src/org/openstreetmap
- Timestamp:
- 2011-02-16T16:39:09+01:00 (14 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/Preferences.java
r3848 r3908 13 13 import java.io.OutputStreamWriter; 14 14 import java.io.PrintWriter; 15 import java.lang.annotation.Retention; 16 import java.lang.annotation.RetentionPolicy; 17 import java.lang.reflect.Field; 15 18 import java.nio.channels.FileChannel; 16 19 import java.util.ArrayList; … … 736 739 } 737 740 741 @Retention(RetentionPolicy.RUNTIME) public @interface pref { } 742 @Retention(RetentionPolicy.RUNTIME) public @interface writeExplicitly { } 743 744 /** 745 * Get a list of hashes which are represented by a struct-like class. 746 * It reads lines of the form 747 * > key.0=prop:val \u001e prop:val \u001e ... \u001e prop:val 748 * > ... 749 * > key.N=prop:val \u001e prop:val \u001e ... \u001e prop:val 750 * Possible properties are given by fields of the class klass that have 751 * the @pref annotation. 752 * Default constructor is used to initialize the struct objects, properties 753 * then override some of these default values. 754 * @param key main preference key 755 * @param klass The struct class 756 * @return a list of objects of type T or an empty list if nothing was found 757 */ 758 public <T> List<T> getListOfStructs(String key, Class<T> klass) { 759 List<T> r = getListOfStructs(key, null, klass); 760 if (r == null) 761 return Collections.emptyList(); 762 else 763 return r; 764 } 765 766 /** 767 * same as above, but returns def if nothing was found 768 */ 769 public <T> List<T> getListOfStructs(String key, Collection<T> def, Class<T> klass) { 770 Collection<Collection<String>> array = 771 getArray(key, def == null ? null : serializeListOfStructs(def, klass)); 772 if (array == null) 773 return def == null ? null : new ArrayList<T>(def); 774 List<T> lst = new ArrayList<T>(); 775 for (Collection<String> entries : array) { 776 T struct = deserializeStruct(entries, klass); 777 lst.add(struct); 778 } 779 return lst; 780 } 781 782 /** 783 * Save a list of hashes represented by a struct-like class. 784 * Considers only fields that have the @pref annotation. 785 * In addition it does not write fields with null values. (Thus they are cleared) 786 * Default values are given by the field values after default constructor has 787 * been called. 788 * Fields equal to the default value are not written unless the field has 789 * the @writeExplicitly annotation. 790 * @param key main preference key 791 * @param val the list that is supposed to be saved 792 * @param klass The struct class 793 * @return true if something has changed 794 */ 795 public <T> boolean putListOfStructs(String key, Collection<T> val, Class<T> klass) { 796 return putArray(key, serializeListOfStructs(val, klass)); 797 } 798 799 private <T> Collection<Collection<String>> serializeListOfStructs(Collection<T> l, Class<T> klass) { 800 if (l == null) 801 return null; 802 Collection<Collection<String>> vals = new ArrayList<Collection<String>>(); 803 for (T struct : l) { 804 if (struct == null) 805 continue; 806 vals.add(serializeStruct(struct, klass)); 807 } 808 return vals; 809 } 810 811 private <T> Collection<String> serializeStruct(T struct, Class<T> klass) { 812 T structPrototype; 813 try { 814 structPrototype = klass.newInstance(); 815 } catch (InstantiationException ex) { 816 throw new RuntimeException(); 817 } catch (IllegalAccessException ex) { 818 throw new RuntimeException(); 819 } 820 821 Collection<String> hash = new ArrayList<String>(); 822 for (Field f : klass.getDeclaredFields()) { 823 if (f.getAnnotation(pref.class) == null) { 824 continue; 825 } 826 f.setAccessible(true); 827 try { 828 Object fieldValue = f.get(struct); 829 Object defaultFieldValue = f.get(structPrototype); 830 if (fieldValue != null) { 831 if (f.getAnnotation(writeExplicitly.class) != null || !Utils.equal(fieldValue, defaultFieldValue)) { 832 hash.add(String.format("%s:%s", f.getName().replace("_", "-"), fieldValue.toString())); 833 } 834 } 835 } catch (IllegalArgumentException ex) { 836 throw new RuntimeException(); 837 } catch (IllegalAccessException ex) { 838 throw new RuntimeException(); 839 } 840 } 841 return hash; 842 } 843 844 private <T> T deserializeStruct(Collection<String> hash, Class<T> klass) { 845 T struct = null; 846 try { 847 struct = klass.newInstance(); 848 } catch (InstantiationException ex) { 849 throw new RuntimeException(); 850 } catch (IllegalAccessException ex) { 851 throw new RuntimeException(); 852 } 853 for (String key_value : hash) { 854 final int i = key_value.indexOf(':'); 855 if (i == -1 || i == 0) { 856 continue; 857 } 858 String key = key_value.substring(0,i); 859 String valueString = key_value.substring(i+1); 860 861 Object value = null; 862 Field f; 863 try { 864 f = klass.getDeclaredField(key.replace("-", "_")); 865 } catch (NoSuchFieldException ex) { 866 continue; 867 } catch (SecurityException ex) { 868 throw new RuntimeException(); 869 } 870 if (f.getAnnotation(pref.class) == null) { 871 continue; 872 } 873 f.setAccessible(true); 874 if (f.getType() == Boolean.class || f.getType() == boolean.class) { 875 value = Boolean.parseBoolean(valueString); 876 } else if (f.getType() == Integer.class || f.getType() == int.class) { 877 try { 878 value = Integer.parseInt(valueString); 879 } catch (NumberFormatException nfe) { 880 continue; 881 } 882 } else if (f.getType() == String.class) { 883 value = valueString; 884 } else 885 throw new RuntimeException("unsupported preference primitive type"); 886 887 try { 888 f.set(struct, value); 889 } catch (IllegalArgumentException ex) { 890 throw new AssertionError(); 891 } catch (IllegalAccessException ex) { 892 throw new RuntimeException(); 893 } 894 } 895 return struct; 896 } 897 738 898 /** 739 899 * Updates system properties with the current values in the preferences. -
trunk/src/org/openstreetmap/josm/data/osm/Filter.java
r3719 r3908 2 2 package org.openstreetmap.josm.data.osm; 3 3 4 import static org.openstreetmap.josm.tools.Utils.equal; 5 4 6 import org.openstreetmap.josm.actions.search.SearchAction.SearchMode; 5 7 import org.openstreetmap.josm.actions.search.SearchAction.SearchSetting; 8 import org.openstreetmap.josm.data.Preferences.pref; 9 import org.openstreetmap.josm.data.Preferences.writeExplicitly; 10 import org.openstreetmap.josm.tools.Utils; 6 11 7 12 /** … … 24 29 } 25 30 31 @Deprecated 26 32 public Filter(String prefText) { 27 33 super("", SearchMode.add, false, false, false); … … 49 55 } 50 56 51 public String getPrefString(){ 52 return version + ";" + 53 text + ";" + mode + ";" + caseSensitive + ";" + regexSearch + ";" + 54 "legacy" + ";" + enable + ";" + hiding + ";" + 55 inverted + ";" + 56 "false"; // last parameter is not used any more (was: applyForChildren) 57 public Filter(FilterPreferenceEntry e) { 58 super(e.text, SearchMode.add, false, false, false); 59 if (equal(e.mode, "replace")) { 60 mode = SearchMode.replace; 61 } else if (equal(e.mode, "add")) { 62 mode = SearchMode.add; 63 } else if (equal(e.mode, "remove")) { 64 mode = SearchMode.remove; 65 } else if (equal(e.mode, "in_selection")) { 66 mode = SearchMode.in_selection; 67 } 68 caseSensitive = e.case_sensitive; 69 regexSearch = e.regex_search; 70 enable = e.enable; 71 hiding = e.hiding; 72 inverted = e.inverted; 73 } 74 75 public static class FilterPreferenceEntry { 76 @pref @writeExplicitly public String version = "1"; 77 @pref public String text = null; 78 @pref @writeExplicitly public String mode = "add"; 79 @pref public boolean case_sensitive = false; 80 @pref public boolean regex_search = false; 81 @pref @writeExplicitly public boolean enable = true; 82 @pref @writeExplicitly public boolean hiding = false; 83 @pref @writeExplicitly public boolean inverted = false; 84 } 85 86 public FilterPreferenceEntry getPreferenceEntry() { 87 FilterPreferenceEntry e = new FilterPreferenceEntry(); 88 e.version = version; 89 e.text = text; 90 e.mode = mode.toString(); 91 e.case_sensitive = caseSensitive; 92 e.regex_search = regexSearch; 93 e.enable = enable; 94 e.hiding = hiding; 95 e.inverted = inverted; 96 return e; 57 97 } 58 98 } -
trunk/src/org/openstreetmap/josm/gui/dialogs/FilterTableModel.java
r3719 r3908 25 25 import org.openstreetmap.josm.data.osm.DataSet; 26 26 import org.openstreetmap.josm.data.osm.Filter; 27 import org.openstreetmap.josm.data.osm.Filter.FilterPreferenceEntry; 27 28 import org.openstreetmap.josm.data.osm.FilterMatcher; 28 29 import org.openstreetmap.josm.data.osm.FilterWorker; … … 60 61 } 61 62 } 62 63 64 63 65 64 public void executeFilters() { … … 110 109 } 111 110 112 113 111 public void executeFilters(Collection<? extends OsmPrimitive> primitives) { 114 112 DataSet ds = Main.main.getCurrentDataSet(); … … 174 172 175 173 private void loadPrefs() { 174 if (!loadPrefsImpl()) { 175 loadPrefsOld(); 176 savePrefs(); 177 } 178 } 179 180 private boolean loadPrefsImpl() { 181 List<FilterPreferenceEntry> entries = Main.pref.getListOfStructs("filters.entries", null, FilterPreferenceEntry.class); 182 if (entries == null) 183 return false; 184 for (FilterPreferenceEntry e : entries) { 185 filters.add(new Filter(e)); 186 } 187 return true; 188 } 189 190 @Deprecated 191 private void loadPrefsOld() { 176 192 Map<String, String> prefs = Main.pref.getAllPrefix("filters.filter"); 177 193 for (String value : prefs.values()) { … … 182 198 183 199 private void savePrefs() { 184 Map<String, String> prefs = Main.pref.getAllPrefix("filters.filter"); 185 for (String key : prefs.keySet()) { 186 String[] sts = key.split("\\."); 187 if (sts.length != 3) 188 throw new Error("Incompatible filter preferences"); 189 Main.pref.put("filters.filter." + sts[2], null); 190 } 191 192 int i = 0; 200 Collection<FilterPreferenceEntry> entries = new ArrayList<FilterPreferenceEntry>(); 193 201 for (Filter flt : filters) { 194 Main.pref.put("filters.filter." + i++, flt.getPrefString()); 195 } 196 } 197 198 private void savePref(int i) { 199 if (i >= filters.size()) { 200 Main.pref.put("filters.filter." + i, null); 201 } else { 202 Main.pref.put("filters.filter." + i, filters.get(i).getPrefString()); 203 } 202 entries.add(flt.getPreferenceEntry()); 203 } 204 Main.pref.putListOfStructs("filters.entries", entries, FilterPreferenceEntry.class); 204 205 } 205 206 206 207 public void addFilter(Filter f) { 207 208 filters.add(f); 208 savePref (filters.size() - 1);209 savePrefs(); 209 210 updateFilters(); 210 211 fireTableRowsInserted(filters.size() - 1, filters.size() - 1); … … 215 216 return; 216 217 filters.add(i + 1, filters.remove(i)); 217 savePref(i); 218 savePref(i + 1); 218 savePrefs(); 219 219 updateFilters(); 220 220 fireTableRowsUpdated(i, i + 1); … … 225 225 return; 226 226 filters.add(i - 1, filters.remove(i)); 227 savePref(i); 228 savePref(i - 1); 227 savePrefs(); 229 228 updateFilters(); 230 229 fireTableRowsUpdated(i - 1, i); … … 240 239 public void setFilter(int i, Filter f) { 241 240 filters.set(i, f); 242 savePref (i);241 savePrefs(); 243 242 updateFilters(); 244 243 fireTableRowsUpdated(i, i); … … 295 294 case 0: 296 295 f.enable = (Boolean) aValue; 297 savePref (row);296 savePrefs(); 298 297 updateFilters(); 299 298 fireTableRowsUpdated(row, row); … … 301 300 case 1: 302 301 f.hiding = (Boolean) aValue; 303 savePref (row);302 savePrefs(); 304 303 updateFilters(); 305 304 break; 306 305 case 2: 307 306 f.text = (String) aValue; 308 savePref (row);307 savePrefs(); 309 308 break; 310 309 case 3: 311 310 f.inverted = (Boolean) aValue; 312 savePref (row);311 savePrefs(); 313 312 updateFilters(); 314 313 break;
Note:
See TracChangeset
for help on using the changeset viewer.