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