001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.data.osm;
003
004import java.util.Comparator;
005import java.util.Objects;
006
007import org.openstreetmap.josm.data.StructUtils.StructEntry;
008import org.openstreetmap.josm.data.StructUtils.WriteExplicitly;
009import org.openstreetmap.josm.data.osm.search.SearchMode;
010import org.openstreetmap.josm.data.osm.search.SearchSetting;
011
012/**
013 * Data class representing one entry in the filter dialog.
014 *
015 * @author Petr_DlouhĂ˝
016 * @since 2125
017 */
018public class Filter extends SearchSetting implements Comparable<Filter> {
019    private static final String version = "1";
020
021    /**
022     * Enabled status.
023     * @see FilterPreferenceEntry#enable
024     */
025    public boolean enable = true;
026
027    /**
028     * If this option is activated, the chosen objects are completely hidden.
029     * Otherwise they are disabled and shown in a shade of gray.
030     * @see FilterPreferenceEntry#hiding
031     */
032    public boolean hiding;
033
034    /**
035     * Normally, the specified objects are hidden and the rest is shown.
036     * If this option is activated, only the specified objects are shown and the rest is hidden.
037     * @see FilterPreferenceEntry#inverted
038     */
039    public boolean inverted;
040
041    /**
042     * Constructs a new {@code Filter}.
043     */
044    public Filter() {
045        super();
046        mode = SearchMode.add;
047    }
048
049    /**
050     * Constructs a new {@code Filter} from a {@code SearchSetting}
051     * @param setting {@code SearchSetting} to construct information from
052     * @since 14932
053     */
054    public Filter(SearchSetting setting) {
055        super(setting);
056    }
057
058    /**
059     * Constructs a new {@code Filter} from a preference entry.
060     * @param e preference entry
061     */
062    public Filter(FilterPreferenceEntry e) {
063        this();
064        text = e.text;
065        if ("replace".equals(e.mode)) {
066            mode = SearchMode.replace;
067        } else if ("add".equals(e.mode)) {
068            mode = SearchMode.add;
069        } else if ("remove".equals(e.mode)) {
070            mode = SearchMode.remove;
071        } else if ("in_selection".equals(e.mode)) {
072            mode = SearchMode.in_selection;
073        }
074        caseSensitive = e.case_sensitive;
075        regexSearch = e.regex_search;
076        mapCSSSearch = e.mapCSS_search;
077        enable = e.enable;
078        hiding = e.hiding;
079        inverted = e.inverted;
080    }
081
082    public static class FilterPreferenceEntry {
083        @WriteExplicitly
084        @StructEntry public String version = "1";
085
086        @StructEntry public String text;
087
088        /**
089         * Mode selector which defines how a filter is combined with the previous one:<ul>
090         * <li>replace: replace selection</li>
091         * <li>add: add to selection</li>
092         * <li>remove: remove from selection</li>
093         * <li>in_selection: find in selection</li>
094         * </ul>
095         * @see SearchMode
096         */
097        @WriteExplicitly
098        @StructEntry public String mode = "add";
099
100        @StructEntry public boolean case_sensitive;
101
102        @StructEntry public boolean regex_search;
103
104        @StructEntry public boolean mapCSS_search;
105
106        /**
107         * Enabled status.
108         * @see Filter#enable
109         */
110        @WriteExplicitly
111        @StructEntry public boolean enable = true;
112
113        /**
114         * If this option is activated, the chosen objects are completely hidden.
115         * Otherwise they are disabled and shown in a shade of gray.
116         * @see Filter#hiding
117         */
118        @WriteExplicitly
119        @StructEntry public boolean hiding;
120
121        /**
122         * Normally, the specified objects are hidden and the rest is shown.
123         * If this option is activated, only the specified objects are shown and the rest is hidden.
124         * @see Filter#inverted
125         */
126        @WriteExplicitly
127        @StructEntry public boolean inverted;
128
129        @Override
130        public int hashCode() {
131            return Objects.hash(case_sensitive, enable, hiding, inverted, mapCSS_search, mode, regex_search, text, version);
132        }
133
134        @Override
135        public boolean equals(Object obj) {
136            if (this == obj)
137                return true;
138            if (obj == null || getClass() != obj.getClass())
139                return false;
140            FilterPreferenceEntry other = (FilterPreferenceEntry) obj;
141            return case_sensitive == other.case_sensitive
142                    && enable == other.enable
143                    && hiding == other.hiding
144                    && inverted == other.inverted
145                    && mapCSS_search == other.mapCSS_search
146                    && regex_search == other.regex_search
147                    && Objects.equals(mode, other.mode)
148                    && Objects.equals(text, other.text)
149                    && Objects.equals(version, other.version);
150        }
151    }
152
153    /**
154     * Returns a new preference entry for this filter.
155     * @return preference entry
156     */
157    public FilterPreferenceEntry getPreferenceEntry() {
158        FilterPreferenceEntry e = new FilterPreferenceEntry();
159        e.version = version;
160        e.text = text;
161        e.mode = mode.name();
162        e.case_sensitive = caseSensitive;
163        e.regex_search = regexSearch;
164        e.mapCSS_search = mapCSSSearch;
165        e.enable = enable;
166        e.hiding = hiding;
167        e.inverted = inverted;
168        return e;
169    }
170
171    @Override
172    public int compareTo(Filter o) {
173        return Comparator
174                .<Filter, String>comparing(f -> f.text)
175                .thenComparing(f -> f.mode)
176                .thenComparing(f -> f.caseSensitive)
177                .thenComparing(f -> f.regexSearch)
178                .thenComparing(f -> f.mapCSSSearch)
179                .thenComparing(f -> f.enable)
180                .thenComparing(f -> f.hiding)
181                .thenComparing(f -> f.inverted)
182                .compare(this, o);
183    }
184}