Changeset 9940 in josm


Ignore:
Timestamp:
2016-03-06T17:12:42+01:00 (4 years ago)
Author:
simon04
Message:

see #12554 - Allow to ignore keys/tags from recent tags

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/search/SearchAction.java

    r9696 r9940  
    773773        return Collections.<ActionParameter<?>>singletonList(new SearchSettingsActionParameter(SEARCH_EXPRESSION));
    774774    }
    775 
    776     public static String escapeStringForSearch(String s) {
    777         return s.replace("\\", "\\\\").replace("\"", "\\\"");
    778     }
    779775}
  • trunk/src/org/openstreetmap/josm/actions/search/SearchCompiler.java

    r9930 r9940  
    17451745        return searchFlags;
    17461746    }
     1747
     1748    static String escapeStringForSearch(String s) {
     1749        return s.replace("\\", "\\\\").replace("\"", "\\\"");
     1750    }
     1751
     1752    /**
     1753     * Builds a search string for the given tag. If value is empty, the existence of the key is checked.
     1754     *
     1755     * @param key   the tag key
     1756     * @param value the tag value
     1757     * @return a search string for the given tag
     1758     */
     1759    public static String buildSearchStringForTag(String key, String value) {
     1760        final String forKey = '"' + escapeStringForSearch(key) + '"' + '=';
     1761        if (value == null || value.isEmpty()) {
     1762            return forKey + "*";
     1763        } else {
     1764            return forKey + '"' + escapeStringForSearch(value) + '"';
     1765        }
     1766    }
    17471767}
  • trunk/src/org/openstreetmap/josm/gui/dialogs/properties/PropertiesDialog.java

    r9894 r9940  
    14011401            String token = new StringBuilder(t).append(val).toString();
    14021402            if (consideredTokens.add(token)) {
    1403                 s.append(sep).append('(').append(t).append('"').append(
    1404                         org.openstreetmap.josm.actions.search.SearchAction.escapeStringForSearch(key)).append("\"=\"").append(
    1405                         org.openstreetmap.josm.actions.search.SearchAction.escapeStringForSearch(val)).append("\")");
     1403                s.append(sep).append('(').append(t).append(SearchCompiler.buildSearchStringForTag(key, val)).append(")");
    14061404                sep = " OR ";
    14071405            }
  • trunk/src/org/openstreetmap/josm/gui/dialogs/properties/RecentTagCollection.java

    r9939 r9940  
    88import java.util.Map;
    99
     10import org.openstreetmap.josm.actions.search.SearchAction;
     11import org.openstreetmap.josm.actions.search.SearchCompiler;
    1012import org.openstreetmap.josm.data.osm.Tag;
    1113import org.openstreetmap.josm.data.preferences.CollectionProperty;
     
    1416
    1517    private final Map<Tag, Void> recentTags;
     18    private SearchCompiler.Match tagsToIgnore;
    1619
    1720    RecentTagCollection(final int capacity) {
     
    2326            }
    2427        };
     28        tagsToIgnore = new SearchCompiler.Never();
    2529    }
    2630
     
    3135            String key = it.next();
    3236            String value = it.next();
    33             recentTags.put(new Tag(key, value), null);
     37            add(new Tag(key, value));
    3438        }
    3539    }
     
    4448    }
    4549
    46     public void add(Tag key) {
    47         recentTags.put(key, null);
     50    public void add(Tag tag) {
     51        if (!tagsToIgnore.match(tag)) {
     52            recentTags.put(tag, null);
     53        }
    4854    }
    4955
     
    5561        return new ArrayList<>(recentTags.keySet());
    5662    }
     63
     64    public void setTagsToIgnore(SearchCompiler.Match tagsToIgnore) {
     65        this.tagsToIgnore = tagsToIgnore;
     66        final Iterator<Tag> it = recentTags.keySet().iterator();
     67        while (it.hasNext()) {
     68            if (tagsToIgnore.match(it.next())) {
     69                it.remove();
     70            }
     71        }
     72    }
     73
     74    public void setTagsToIgnore(SearchAction.SearchSetting tagsToIgnore) throws SearchCompiler.ParseError {
     75        setTagsToIgnore(tagsToIgnore.text.isEmpty() ? new SearchCompiler.Never() : SearchCompiler.compile(tagsToIgnore));
     76    }
     77
     78    public SearchAction.SearchSetting ignoreTag(Tag tagToIgnore, SearchAction.SearchSetting settingToUpdate) throws SearchCompiler.ParseError {
     79        final String forTag = SearchCompiler.buildSearchStringForTag(tagToIgnore.getKey(), tagToIgnore.getValue());
     80        settingToUpdate.text = settingToUpdate.text.isEmpty()
     81                ? forTag
     82                : settingToUpdate.text + " OR " + forTag;
     83        setTagsToIgnore(settingToUpdate);
     84        return settingToUpdate;
     85    }
    5786}
  • trunk/src/org/openstreetmap/josm/gui/dialogs/properties/TagEditHelper.java

    r9939 r9940  
    3737import java.util.List;
    3838import java.util.Map;
     39import java.util.Objects;
    3940import java.util.TreeMap;
    4041
     
    5758import javax.swing.KeyStroke;
    5859import javax.swing.ListCellRenderer;
     60import javax.swing.SwingUtilities;
    5961import javax.swing.table.DefaultTableModel;
    6062import javax.swing.text.JTextComponent;
     
    6264import org.openstreetmap.josm.Main;
    6365import org.openstreetmap.josm.actions.JosmAction;
     66import org.openstreetmap.josm.actions.search.SearchAction;
     67import org.openstreetmap.josm.actions.search.SearchCompiler;
    6468import org.openstreetmap.josm.command.ChangePropertyCommand;
    6569import org.openstreetmap.josm.command.Command;
     
    7175import org.openstreetmap.josm.data.preferences.EnumProperty;
    7276import org.openstreetmap.josm.data.preferences.IntegerProperty;
     77import org.openstreetmap.josm.data.preferences.StringProperty;
    7378import org.openstreetmap.josm.gui.ExtendedDialog;
    7479import org.openstreetmap.josm.gui.mappaint.MapPaintStyles;
     
    125130            DEFAULT_LRU_TAGS_NUMBER);
    126131    /** The preference storage of recent tags */
    127     public static final CollectionProperty COLLECTION_PROPERTY = new CollectionProperty("properties.recent-tags",
     132    public static final CollectionProperty PROPERTY_RECENT_TAGS = new CollectionProperty("properties.recent-tags",
    128133            Collections.<String>emptyList());
     134    public static final StringProperty PROPERTY_TAGS_TO_IGNORE = new StringProperty("properties.recent-tags.ignore",
     135            new SearchAction.SearchSetting().writeToString());
    129136
    130137    /**
     
    159166
    160167    final RecentTagCollection recentTags = new RecentTagCollection(MAX_LRU_TAGS_NUMBER);
     168    SearchAction.SearchSetting tagsToIgnore;
    161169
    162170    // Copy of recently added tags, used to cache initial status
     
    286294     */
    287295    public void loadTagsIfNeeded() {
     296        loadTagsToIgnore();
    288297        if (PROPERTY_REMEMBER_TAGS.get() && recentTags.isEmpty()) {
    289             recentTags.loadFromPreference(COLLECTION_PROPERTY);
    290         }
     298            recentTags.loadFromPreference(PROPERTY_RECENT_TAGS);
     299        }
     300    }
     301
     302    void loadTagsToIgnore() {
     303        final SearchAction.SearchSetting searchSetting = Utils.firstNonNull(
     304                SearchAction.SearchSetting.readFromString(PROPERTY_TAGS_TO_IGNORE.get()), new SearchAction.SearchSetting());
     305        if (!Objects.equals(tagsToIgnore, searchSetting)) {
     306            try {
     307                tagsToIgnore = searchSetting;
     308                recentTags.setTagsToIgnore(tagsToIgnore);
     309            } catch (SearchCompiler.ParseError parseError) {
     310                warnAboutParseError(parseError);
     311                tagsToIgnore = new SearchAction.SearchSetting();
     312                recentTags.setTagsToIgnore(new SearchCompiler.Never());
     313            }
     314        }
     315    }
     316
     317    private void warnAboutParseError(SearchCompiler.ParseError parseError) {
     318        Main.warn(parseError);
     319        JOptionPane.showMessageDialog(
     320                Main.parent,
     321                parseError.getMessage(),
     322                tr("Error"),
     323                JOptionPane.ERROR_MESSAGE
     324        );
    291325    }
    292326
     
    296330    public void saveTagsIfNeeded() {
    297331        if (PROPERTY_REMEMBER_TAGS.get() && !recentTags.isEmpty()) {
    298             recentTags.saveToPreference(COLLECTION_PROPERTY);
     332            recentTags.saveToPreference(PROPERTY_RECENT_TAGS);
    299333        }
    300334    }
     
    924958                        public void mouseClicked(MouseEvent e) {
    925959                            action.actionPerformed(null);
    926                             if (e.isShiftDown()) {
     960                            if (SwingUtilities.isRightMouseButton(e)) {
     961                                new TagPopupMenu(t).show(e.getComponent(), e.getX(), e.getY());
     962                            } else if (e.isShiftDown()) {
    927963                                // add tags on Shift-Click
    928964                                performTagAdding();
     
    952988        }
    953989
     990        class TagPopupMenu extends JPopupMenu {
     991
     992            TagPopupMenu(Tag t) {
     993                add(new IgnoreTagAction(tr("Ignore key ''{0}''", t.getKey()), new Tag(t.getKey(), "")));
     994                add(new IgnoreTagAction(tr("Ignore tag ''{0}''", t), t));
     995                add(new EditIgnoreTagsAction());
     996            }
     997        }
     998
     999        class IgnoreTagAction extends AbstractAction {
     1000            final Tag tag;
     1001
     1002            IgnoreTagAction(String name, Tag tag) {
     1003                super(name);
     1004                this.tag = tag;
     1005            }
     1006
     1007            @Override
     1008            public void actionPerformed(ActionEvent e) {
     1009                try {
     1010                    recentTags.ignoreTag(tag, tagsToIgnore);
     1011                    PROPERTY_TAGS_TO_IGNORE.put(tagsToIgnore.writeToString());
     1012                } catch (SearchCompiler.ParseError parseError) {
     1013                    throw new IllegalStateException(parseError);
     1014                }
     1015            }
     1016        }
     1017
     1018        class EditIgnoreTagsAction extends AbstractAction {
     1019
     1020            EditIgnoreTagsAction() {
     1021                super(tr("Edit ignore list"));
     1022            }
     1023
     1024            @Override
     1025            public void actionPerformed(ActionEvent e) {
     1026                final SearchAction.SearchSetting newTagsToIngore = SearchAction.showSearchDialog(tagsToIgnore);
     1027                if (newTagsToIngore == null) {
     1028                    return;
     1029                }
     1030                try {
     1031                    tagsToIgnore = newTagsToIngore;
     1032                    recentTags.setTagsToIgnore(tagsToIgnore);
     1033                    PROPERTY_TAGS_TO_IGNORE.put(tagsToIgnore.writeToString());
     1034                } catch (SearchCompiler.ParseError parseError) {
     1035                    warnAboutParseError(parseError);
     1036                }
     1037            }
     1038        }
     1039
    9541040        public void destroyActions() {
    9551041            for (JosmAction action : recentTagsActions) {
  • trunk/test/unit/org/openstreetmap/josm/actions/search/SearchCompilerTest.java

    r9930 r9940  
    1919import org.openstreetmap.josm.data.osm.RelationData;
    2020import org.openstreetmap.josm.data.osm.RelationMember;
     21import org.openstreetmap.josm.data.osm.Tag;
    2122import org.openstreetmap.josm.data.osm.User;
    2223import org.openstreetmap.josm.data.osm.Way;
     
    427428        assertEquals("foo1 || (bar1 && bar2 && (baz1 ^ baz2)) || foo2", c4.toString());
    428429    }
     430
     431    /**
     432     * Tests {@code buildSearchStringForTag}.
     433     * @throws ParseError if an error has been encountered while compiling
     434     */
     435    @Test
     436    public void testBuildSearchStringForTag() throws ParseError {
     437        final Tag tag1 = new Tag("foo=", "bar\"");
     438        final Tag tag2 = new Tag("foo=", "=bar");
     439        final String search1 = SearchCompiler.buildSearchStringForTag(tag1.getKey(), tag1.getValue());
     440        assertEquals("\"foo=\"=\"bar\\\"\"", search1);
     441        assertTrue(SearchCompiler.compile(search1).match(tag1));
     442        assertFalse(SearchCompiler.compile(search1).match(tag2));
     443        final String search2 = SearchCompiler.buildSearchStringForTag(tag1.getKey(), "");
     444        assertEquals("\"foo=\"=*", search2);
     445        assertTrue(SearchCompiler.compile(search2).match(tag1));
     446        assertTrue(SearchCompiler.compile(search2).match(tag2));
     447    }
    429448}
  • trunk/test/unit/org/openstreetmap/josm/gui/dialogs/properties/RecentTagCollectionTest.java

    r9939 r9940  
    1212import org.junit.Test;
    1313import org.openstreetmap.josm.JOSMFixture;
     14import org.openstreetmap.josm.actions.search.SearchAction;
     15import org.openstreetmap.josm.actions.search.SearchCompiler;
    1416import org.openstreetmap.josm.data.osm.Tag;
    1517import org.openstreetmap.josm.data.preferences.CollectionProperty;
     
    3032    /**
    3133     * Performs various tests on a {@link RecentTagCollection}.
    32       */
     34     *
     35     * @throws SearchCompiler.ParseError if an error has been encountered while compiling
     36     */
    3337    @Test
    34     public void test() {
     38    public void test() throws SearchCompiler.ParseError {
    3539        final RecentTagCollection recentTags = new RecentTagCollection(2);
    3640        assertTrue(recentTags.isEmpty());
     
    5559        assertEquals(Collections.singletonList(new Tag("key=", "=value")), recentTags.toList());
    5660
     61        recentTags.add(foo);
     62        recentTags.add(bar);
     63        recentTags.add(baz);
     64        final SearchAction.SearchSetting searchSetting = new SearchAction.SearchSetting();
     65        recentTags.ignoreTag(baz, searchSetting);
     66        recentTags.ignoreTag(new Tag("something", "else"), searchSetting);
     67        assertEquals("\"name\"=\"baz\" OR \"something\"=\"else\"", searchSetting.text);
     68        assertEquals(Collections.singletonList(bar), recentTags.toList());
     69        recentTags.add(baz);
     70        assertEquals(Collections.singletonList(bar), recentTags.toList());
     71        searchSetting.text = "";
     72        recentTags.setTagsToIgnore(searchSetting);
     73        assertEquals(Collections.singletonList(bar), recentTags.toList());
     74        recentTags.add(baz);
     75        assertEquals(Arrays.asList(bar, baz), recentTags.toList());
     76        recentTags.ignoreTag(new Tag("name", /*all values */""), searchSetting);
     77        assertEquals(Collections.emptyList(), recentTags.toList());
     78
    5779    }
    5880}
Note: See TracChangeset for help on using the changeset viewer.