Another day (uhm... night), another bug fix.

The attached patch fixes #485, but might need a bit of explanation to the user.

In the search-gui, I have introduced a new CheckBox, labelled "use = instead of : for key/value separation". If checked, the search works slighty different. "=" instead of ":" is used as a token to separate key and value.

So, if you have a tagging a) "test1:test2=yo"  and b) "test1=test2"

searching can be done by ticking the checkbox. Searches for "test1:test2" will find tagging a) if the new checkbox is clicked and tagging b) ("classic" search) if you don't click the box. Searching for "test1:test2=yo" with the new way will of course find tagging a) as well.


Regards, Florian.
Index: src/org/openstreetmap/josm/actions/search/SearchCompiler.java
===================================================================
--- src/org/openstreetmap/josm/actions/search/SearchCompiler.java       
(revision 775)
+++ src/org/openstreetmap/josm/actions/search/SearchCompiler.java       
(working copy)
@@ -19,10 +19,12 @@
 
        private boolean caseSensitive = false;
        private PushbackTokenizer tokenizer;
+       private boolean alternateTokenizing = false;
 
-       public SearchCompiler(boolean caseSensitive, PushbackTokenizer 
tokenizer) {
+       public SearchCompiler(boolean caseSensitive, boolean 
alternateTokenizing, PushbackTokenizer tokenizer) {
                this.caseSensitive = caseSensitive;
                this.tokenizer = tokenizer;
+               this.alternateTokenizing = alternateTokenizing;
        }
        
        abstract public static class Match {
@@ -177,11 +179,11 @@
                }
        }
        
-       public static Match compile(String searchStr, boolean caseSensitive)
+       public static Match compile(String searchStr, boolean caseSensitive, 
boolean alternateTokenizing)
                        throws ParseError {
-               return new SearchCompiler(caseSensitive,
+               return new SearchCompiler(caseSensitive, alternateTokenizing,
                                new PushbackTokenizer(
-                                       new PushbackReader(new 
StringReader(searchStr))))
+                                       new PushbackReader(new 
StringReader(searchStr)), alternateTokenizing))
                        .parse();
        }
 
@@ -240,8 +242,9 @@
 
        private Match parsePat() {
                String tok = tokenizer.readText();
+               String token = alternateTokenizing ? "=" : ":";
 
-               if (tokenizer.readIfEqual(":")) {
+               if (tokenizer.readIfEqual(token)) {
                        String tok2 = tokenizer.readText();
                        if (tok == null) tok = "";
                        if (tok2 == null) tok2 = "";
Index: src/org/openstreetmap/josm/actions/search/SearchAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/search/SearchAction.java (revision 775)
+++ src/org/openstreetmap/josm/actions/search/SearchAction.java (working copy)
@@ -54,6 +54,7 @@
        bg.add(remove);
        
        JCheckBox caseSensitive = new JCheckBox(tr("case sensitive"), false);
+       JCheckBox alternateTokenizing = new JCheckBox(tr("use = instead of : 
for key/value separation"), false);
     
        JPanel p = new JPanel(new GridBagLayout());
        p.add(label, GBC.eop());
@@ -62,6 +63,7 @@
        p.add(add, GBC.eol());
        p.add(remove, GBC.eop());
        p.add(caseSensitive, GBC.eol());
+       p.add(alternateTokenizing, GBC.eol());
        JOptionPane pane = new JOptionPane(p, JOptionPane.INFORMATION_MESSAGE, 
JOptionPane.OK_CANCEL_OPTION, null){
                @Override public void selectInitialValue() {
                        input.requestFocusInWindow();
@@ -73,10 +75,26 @@
                return;
        lastSearch = input.getText();
        SearchAction.SearchMode mode = replace.isSelected() ? 
SearchAction.SearchMode.replace : (add.isSelected() ? 
SearchAction.SearchMode.add : SearchAction.SearchMode.remove);
-       search(lastSearch, mode, caseSensitive.isSelected());
+       search(lastSearch, mode, caseSensitive.isSelected(), 
alternateTokenizing.isSelected());
     }
 
-       public static void search(String search, SearchMode mode, boolean 
caseSensitive) {
+    /**
+     * To stay compatible, the old call
+     * @param search Text to search for
+     * @param mode what to do with the search result
+     * @param caseSensitive switch case sensitivity
+     */
+    public static void search(String search, SearchMode mode, boolean 
caseSensitive) {
+       search (search, mode, caseSensitive, false);
+    }
+    
+    /**
+     * @param search Text to search for
+     * @param mode what to do with the search result
+     * @param caseSensitive switch case sensitivity
+     * @param alternateTokenizing if set, a = separates key and value, else it 
stays a :.
+     */
+    public static void search(String search, SearchMode mode, boolean 
caseSensitive, boolean alternateTokenizing) {
        if (search.startsWith("http://";) || search.startsWith("ftp://";) || 
search.startsWith("https://";) || search.startsWith("file:/")) {
                SelectionWebsiteLoader loader = new 
SelectionWebsiteLoader(search, mode);
                if (loader.url != null) {
@@ -86,7 +104,7 @@
        }
                try {
                        Collection<OsmPrimitive> sel = Main.ds.getSelected();
-                       SearchCompiler.Match matcher = 
SearchCompiler.compile(search, caseSensitive);
+                       SearchCompiler.Match matcher = 
SearchCompiler.compile(search, caseSensitive, alternateTokenizing);
                        for (OsmPrimitive osm : 
Main.ds.allNonDeletedCompletePrimitives()) {
                                if (mode == SearchMode.replace) {
                                        if (matcher.match(osm))
Index: src/org/openstreetmap/josm/actions/search/PushbackTokenizer.java
===================================================================
--- src/org/openstreetmap/josm/actions/search/PushbackTokenizer.java    
(revision 775)
+++ src/org/openstreetmap/josm/actions/search/PushbackTokenizer.java    
(working copy)
@@ -7,17 +7,33 @@
 
 public class PushbackTokenizer {
        private PushbackReader search;
+       private boolean alternateTokenizing;
 
        private LinkedList<String> pushBackBuf = new LinkedList<String>();
 
+       /**
+        * The 'classic' interface, a : separates key and value
+        * @param search datasource to sift through
+        */
        public PushbackTokenizer(PushbackReader search) {
                this.search = search;
+               this.alternateTokenizing = false;
        }
 
        /**
+        * The new interface, key/value separation is switchable
+        * @param search datasource to sift through
+        * @param alternateTokenizing switches between : (false) and = (true) 
as key/value token
+        */
+       public PushbackTokenizer(PushbackReader search, boolean 
alternateTokenizing) {
+               this.search = search;
+               this.alternateTokenizing = alternateTokenizing;
+       }
+
+       /**
         * The token returned is <code>null</code> or starts with an identifier 
character:
         * - for an '-'. This will be the only character
-        * : for an key. The value is the next token
+        * : or = for an key (depending on alternateTokenizing in the 
constructor. The value is the next token
         * | for "OR"
         * ' ' for anything else.
         * @return The next token in the stream.
@@ -38,15 +54,32 @@
                        }
                        StringBuilder s;
                        switch (c) {
-                       case ':':
-                               next = search.read();
-                               c = (char) next;
-                               if (next == -1 || c == ' ' || c == '\t') {
-                                       pushBack(" ");
-                               } else {
-                                       search.unread(next);
+                       case ':' :
+                               if(!alternateTokenizing) {
+                                       next = search.read();
+                                       c = (char) next;
+                                       if (next == -1 || c == ' ' || c == 
'\t') {
+                                               pushBack(" ");
+                                       } else {
+                                               search.unread(next);
+                                       }
+                                       return ":";
                                }
-                               return ":";
+                               s = new StringBuilder ();
+                               break;
+                       case '=' :
+                               if(alternateTokenizing) {
+                                       next = search.read();
+                                       c = (char) next;
+                                       if (next == -1 || c == ' ' || c == 
'\t') {
+                                               pushBack(" ");
+                                       } else {
+                                               search.unread(next);
+                                       }
+                                       return "=";
+                               }
+                               s = new StringBuilder ();
+                               break;
                        case '-':
                                return "-";
                        case '(':
@@ -60,6 +93,8 @@
                                return s.toString();
                        default:
                                s = new StringBuilder();
+                               break;
+                       }
                        for (;;) {
                                s.append(c);
                                next = search.read();
@@ -69,14 +104,14 @@
                                        return " "+s.toString();
                                }
                                c = (char)next;
-                               if (c == ' ' || c == '\t' || c == '"' || c == 
':' || c == '(' || c == ')') {
+                               if (c == ' ' || c == '\t' || c == '"' || c == 
(alternateTokenizing ? '=' : ':')  || c == '(' || c == ')') {
                                        search.unread(next);
                                        if (s.toString().equals("OR"))
                                                return "|";
                                        return " "+s.toString();
                                }
                        }
-                       }
+
                } catch (IOException e) {
                        throw new RuntimeException(e.getMessage(), e);
                }               
_______________________________________________
josm-dev mailing list
[email protected]
http://lists.openstreetmap.org/listinfo/josm-dev

Reply via email to