Changeset 7210 in josm for trunk/src/org/openstreetmap/josm


Ignore:
Timestamp:
2014-06-02T20:51:37+02:00 (10 years ago)
Author:
simon04
Message:

see #10092 - Refactor and test preset filtering

File:
1 edited

Legend:

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

    r7207 r7210  
    2020import java.util.EnumSet;
    2121import java.util.HashSet;
     22import java.util.Iterator;
    2223import java.util.List;
    2324
     
    4243import org.openstreetmap.josm.Main;
    4344import org.openstreetmap.josm.data.SelectionChangedListener;
    44 import org.openstreetmap.josm.data.osm.Node;
    4545import org.openstreetmap.josm.data.osm.OsmPrimitive;
    46 import org.openstreetmap.josm.data.osm.Relation;
    47 import org.openstreetmap.josm.data.osm.Way;
    4846import org.openstreetmap.josm.data.preferences.BooleanProperty;
    4947import org.openstreetmap.josm.gui.tagging.TaggingPresetItems.Key;
     
    7674    private final EnumSet<TaggingPresetType> typesInSelection = EnumSet.noneOf(TaggingPresetType.class);
    7775    private boolean typesInSelectionDirty = true;
    78     private final List<PresetClassification> classifications = new ArrayList<>();
     76    private final PresetClassifications classifications = new PresetClassifications();
    7977    private ResultListModel lsResultModel = new ResultListModel();
    8078
     
    117115    }
    118116
    119     private static class PresetClassification implements Comparable<PresetClassification> {
     117    /**
     118     * Computes the match ration of a {@link TaggingPreset} wrt. a searchString.
     119     */
     120    static class PresetClassification implements Comparable<PresetClassification> {
    120121        public final TaggingPreset preset;
    121122        public int classification;
     
    209210    public TaggingPresetSelector(boolean displayOnlyApplicable, boolean displaySearchInTags) {
    210211        super(new BorderLayout());
    211         loadPresets(TaggingPresets.getTaggingPresets());
     212        classifications.loadPresets(TaggingPresets.getTaggingPresets());
    212213
    213214        edSearchText = new JosmTextField();
     
    321322        //TODO Save favorites to file
    322323        String text = edSearchText.getText().toLowerCase();
    323 
    324         String[] groupWords;
    325         String[] nameWords;
    326 
    327         if (text.contains("/")) {
    328             groupWords = text.substring(0, text.lastIndexOf('/')).split("[\\s/]");
    329             nameWords = text.substring(text.indexOf('/') + 1).split("\\s");
    330         } else {
    331             groupWords = null;
    332             nameWords = text.split("\\s");
    333         }
    334 
    335324        boolean onlyApplicable = ckOnlyApplicable != null && ckOnlyApplicable.isSelected();
    336325        boolean inTags = ckSearchInTags != null && ckSearchInTags.isSelected();
    337326
    338         final List<PresetClassification> result = new ArrayList<>();
    339         for (PresetClassification presetClassification : classifications) {
    340             TaggingPreset preset = presetClassification.preset;
    341             presetClassification.classification = 0;
    342 
    343             if (onlyApplicable) {
    344                 boolean suitable = preset.typeMatches(getTypesInSelection());
    345 
    346                 if (!suitable && preset.types.contains(TaggingPresetType.RELATION) && preset.roles != null) {
    347                     final Predicate<Role> memberExpressionMatchesOnePrimitive = new Predicate<Role>() {
    348                         final Collection<OsmPrimitive> selected = Main.main.getCurrentDataSet().getSelected();
    349                         @Override public boolean evaluate(Role object) {
    350                             return object.memberExpression != null
    351                                     && Utils.exists(selected, object.memberExpression);
     327        final List<PresetClassification> result = classifications.getMatchingPresets(
     328                text, onlyApplicable, inTags, getTypesInSelection(), Main.main.getCurrentDataSet().getSelected());
     329
     330        lsResultModel.setPresets(result);
     331
     332    }
     333
     334    /**
     335     * A collection of {@link PresetClassification}s with the functionality of filtering wrt. searchString.
     336     */
     337    static class PresetClassifications implements Iterable<PresetClassification> {
     338
     339        private final List<PresetClassification> classifications = new ArrayList<>();
     340
     341        public List<PresetClassification> getMatchingPresets(String searchText, boolean onlyApplicable, boolean inTags, EnumSet<TaggingPresetType> presetTypes, final Collection<? extends OsmPrimitive> selectedPrimitives) {
     342            final String[] groupWords;
     343            final String[] nameWords;
     344
     345            if (searchText.contains("/")) {
     346                groupWords = searchText.substring(0, searchText.lastIndexOf('/')).split("[\\s/]");
     347                nameWords = searchText.substring(searchText.indexOf('/') + 1).split("\\s");
     348            } else {
     349                groupWords = null;
     350                nameWords = searchText.split("\\s");
     351            }
     352
     353            return getMatchingPresets(groupWords, nameWords, onlyApplicable, inTags, presetTypes, selectedPrimitives);
     354        }
     355
     356        public List<PresetClassification> getMatchingPresets(String[] groupWords, String[] nameWords, boolean onlyApplicable, boolean inTags, EnumSet<TaggingPresetType> presetTypes, final Collection<? extends OsmPrimitive> selectedPrimitives) {
     357
     358            final List<PresetClassification> result = new ArrayList<>();
     359            for (PresetClassification presetClassification : classifications) {
     360                TaggingPreset preset = presetClassification.preset;
     361                presetClassification.classification = 0;
     362
     363                if (onlyApplicable) {
     364                    boolean suitable = preset.typeMatches(presetTypes);
     365
     366                    if (!suitable && preset.types.contains(TaggingPresetType.RELATION) && preset.roles != null && !preset.roles.roles.isEmpty()) {
     367                        final Predicate<Role> memberExpressionMatchesOnePrimitive = new Predicate<Role>() {
     368
     369                            @Override
     370                            public boolean evaluate(Role object) {
     371                                return object.memberExpression != null
     372                                        && Utils.exists(selectedPrimitives, object.memberExpression);
     373                            }
     374                        };
     375                        suitable = Utils.exists(preset.roles.roles, memberExpressionMatchesOnePrimitive);
     376                        // keep the preset to allow the creation of new relations
     377                    }
     378                    if (!suitable) {
     379                        continue;
     380                    }
     381                }
     382
     383                if (groupWords != null && presetClassification.isMatchingGroup(groupWords) == 0) {
     384                    continue;
     385                }
     386
     387                int matchName = presetClassification.isMatchingName(nameWords);
     388
     389                if (matchName == 0) {
     390                    if (groupWords == null) {
     391                        int groupMatch = presetClassification.isMatchingGroup(nameWords);
     392                        if (groupMatch > 0) {
     393                            presetClassification.classification = CLASSIFICATION_GROUP_MATCH + groupMatch;
    352394                        }
    353                     };
    354                     suitable = Utils.exists(preset.roles.roles, memberExpressionMatchesOnePrimitive);
    355                     // keep the preset to allow the creation of new relations
    356                 }
    357                 if (!suitable) {
     395                    }
     396                    if (presetClassification.classification == 0 && inTags) {
     397                        int tagsMatch = presetClassification.isMatchingTags(nameWords);
     398                        if (tagsMatch > 0) {
     399                            presetClassification.classification = CLASSIFICATION_TAGS_MATCH + tagsMatch;
     400                        }
     401                    }
     402                } else {
     403                    presetClassification.classification = CLASSIFICATION_NAME_MATCH + matchName;
     404                }
     405
     406                if (presetClassification.classification > 0) {
     407                    presetClassification.classification += presetClassification.favoriteIndex;
     408                    result.add(presetClassification);
     409                }
     410            }
     411
     412            Collections.sort(result);
     413            return result;
     414
     415        }
     416
     417        public void clear() {
     418            classifications.clear();
     419        }
     420
     421        public void loadPresets(Collection<TaggingPreset> presets) {
     422            for (TaggingPreset preset : presets) {
     423                if (preset instanceof TaggingPresetSeparator || preset instanceof TaggingPresetMenu) {
    358424                    continue;
    359425                }
    360             }
    361 
    362             if (groupWords != null && presetClassification.isMatchingGroup(groupWords) == 0) {
    363                 continue;
    364             }
    365 
    366             int matchName = presetClassification.isMatchingName(nameWords);
    367 
    368             if (matchName == 0) {
    369                 if (groupWords == null) {
    370                     int groupMatch = presetClassification.isMatchingGroup(nameWords);
    371                     if (groupMatch > 0) {
    372                         presetClassification.classification = CLASSIFICATION_GROUP_MATCH + groupMatch;
    373                     }
    374                 }
    375                 if (presetClassification.classification == 0 && inTags) {
    376                     int tagsMatch = presetClassification.isMatchingTags(nameWords);
    377                     if (tagsMatch > 0) {
    378                         presetClassification.classification = CLASSIFICATION_TAGS_MATCH + tagsMatch;
    379                     }
    380                 }
    381             } else {
    382                 presetClassification.classification = CLASSIFICATION_NAME_MATCH + matchName;
    383             }
    384 
    385             if (presetClassification.classification > 0) {
    386                 presetClassification.classification += presetClassification.favoriteIndex;
    387                 result.add(presetClassification);
    388             }
    389         }
    390 
    391         Collections.sort(result);
    392         lsResultModel.setPresets(result);
    393 
     426                classifications.add(new PresetClassification(preset));
     427            }
     428        }
     429
     430        @Override
     431        public Iterator<PresetClassification> iterator() {
     432            return classifications.iterator();
     433        }
    394434    }
    395435
     
    401441                if (Main.main==null || Main.main.getCurrentDataSet() == null) return typesInSelection;
    402442                for (OsmPrimitive primitive : Main.main.getCurrentDataSet().getSelected()) {
    403                     if (primitive instanceof Node) {
    404                         typesInSelection.add(TaggingPresetType.NODE);
    405                     } else if (primitive instanceof Way) {
    406                         if (((Way) primitive).isClosed()) {
    407                             typesInSelection.add(TaggingPresetType.CLOSEDWAY);
    408                         } else {
    409                             // closedway is not a way for preset checking, the types are mutually exclusive
    410                             typesInSelection.add(TaggingPresetType.WAY);
    411                         }
    412                     } else if (primitive instanceof Relation) {
    413                         typesInSelection.add(TaggingPresetType.RELATION);
    414                     }
     443                    typesInSelection.add(TaggingPresetType.forPrimitive(primitive));
    415444                }
    416445            }
     
    435464    public void init(Collection<TaggingPreset> presets) {
    436465        classifications.clear();
    437         loadPresets(presets);
     466        classifications.loadPresets(presets);
    438467        init();
    439468    }
     
    477506    }
    478507
    479     private void loadPresets(Collection<TaggingPreset> presets) {
    480         for (TaggingPreset preset: presets) {
    481             if (preset instanceof TaggingPresetSeparator || preset instanceof TaggingPresetMenu) {
    482                 continue;
    483             }
    484             classifications.add(new PresetClassification(preset));
    485         }
    486     }
    487 
    488508    public void setSelectedPreset(TaggingPreset p) {
    489509        lsResult.setSelectedValue(p, true);
Note: See TracChangeset for help on using the changeset viewer.