Ignore:
Timestamp:
2014-11-15T21:45:22+01:00 (9 years ago)
Author:
bastiK
Message:

autocomplete: remember user input and prefer recently entered strings

It bugged my, that in tag add dialog, JOSM always autocompletes addr:h to
addr:housename. But addr:housenumber is what I want.

Now it remembers the last tags that have been entered in a session
and gives those the highest priority in autocompletion.
More recent entries are preferred.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletionManager.java

    r7556 r7725  
    77import java.util.Collections;
    88import java.util.HashSet;
     9import java.util.LinkedHashSet;
    910import java.util.List;
    1011import java.util.Map;
    1112import java.util.Map.Entry;
     13import java.util.Objects;
    1214import java.util.Set;
    1315
     
    5456public class AutoCompletionManager implements DataSetListener {
    5557
     58    /**
     59     * Data class to remember tags that the user has entered.
     60     */
     61    public static class UserInputTag {
     62        public String key;
     63        public String value;
     64        public boolean defaultKey;
     65
     66        /**
     67         * Constructor.
     68         *
     69         * @param key the tag key
     70         * @param value the tag value
     71         * @param defaultKey true, if the key was not really entered by the
     72         * user, e.g. for preset text fields.
     73         * In this case, the key will not get any higher priority, just the value.
     74         */
     75        public UserInputTag(String key, String value, boolean defaultKey) {
     76            this.key = key;
     77            this.value = value;
     78            this.defaultKey = defaultKey;
     79        }
     80
     81        @Override
     82        public int hashCode() {
     83            int hash = 7;
     84            hash = 59 * hash + Objects.hashCode(this.key);
     85            hash = 59 * hash + Objects.hashCode(this.value);
     86            hash = 59 * hash + (this.defaultKey ? 1 : 0);
     87            return hash;
     88        }
     89
     90        @Override
     91        public boolean equals(Object obj) {
     92            if (obj == null) {
     93                return false;
     94            }
     95            if (getClass() != obj.getClass()) {
     96                return false;
     97            }
     98            final UserInputTag other = (UserInputTag) obj;
     99            if (!Objects.equals(this.key, other.key)) {
     100                return false;
     101            }
     102            if (!Objects.equals(this.value, other.value)) {
     103                return false;
     104            }
     105            if (this.defaultKey != other.defaultKey) {
     106                return false;
     107            }
     108            return true;
     109        }
     110    }
     111
    56112    /** If the dirty flag is set true, a rebuild is necessary. */
    57113    protected boolean dirty;
     
    70126     */
    71127    protected static final MultiMap<String, String> presetTagCache = new MultiMap<>();
     128    /**
     129     * Cache for tags that have been entered by the user.
     130     */
     131    protected static final Set<UserInputTag> userInputTagCache = new LinkedHashSet<>();
     132   
    72133    /**
    73134     * the cached list of member roles
     
    174235        }
    175236    }
     237   
     238   
     239    public static void rememberUserInput(String key, String value, boolean defaultKey) {
     240        UserInputTag tag = new UserInputTag(key, value, defaultKey);
     241        userInputTagCache.remove(tag); // re-add, so it gets to the last position of the LinkedHashSet
     242        userInputTagCache.add(tag);
     243    }
    176244
    177245    /**
     
    187255        return new ArrayList<>(presetTagCache.keySet());
    188256    }
     257   
     258    protected Collection<String> getUserInputKeys() {
     259        List<String> keys = new ArrayList<>();
     260        for (UserInputTag tag : userInputTagCache) {
     261            if (!tag.defaultKey) {
     262                keys.add(tag.key);
     263            }
     264        }
     265        Collections.reverse(keys);
     266        return new LinkedHashSet<>(keys);
     267    }
    189268
    190269    /**
     
    201280    protected static List<String> getPresetValues(String key) {
    202281        return new ArrayList<>(presetTagCache.getValues(key));
     282    }
     283
     284    protected static Collection<String> getUserInputValues(String key) {
     285        ArrayList<String> values = new ArrayList<>();
     286        for (UserInputTag tag : userInputTagCache) {
     287            if (key.equals(tag.key)) {
     288                values.add(tag.value);
     289            }
     290        }
     291        Collections.reverse(values);
     292        return new LinkedHashSet<>(values);
    203293    }
    204294
     
    261351        list.add(new AutoCompletionListItem("source", AutoCompletionItemPriority.IS_IN_STANDARD));
    262352        list.add(getDataKeys(), AutoCompletionItemPriority.IS_IN_DATASET);
     353        list.addUserInput(getUserInputKeys());
    263354    }
    264355
     
    285376            list.add(getPresetValues(key), AutoCompletionItemPriority.IS_IN_STANDARD);
    286377            list.add(getDataValues(key), AutoCompletionItemPriority.IS_IN_DATASET);
     378            list.addUserInput(getUserInputValues(key));
    287379        }
    288380    }
Note: See TracChangeset for help on using the changeset viewer.