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


Ignore:
Timestamp:
2010-06-29T08:52:59+02:00 (14 years ago)
Author:
jttt
Message:

Simplify/optimize filters implementation

Location:
trunk/src/org/openstreetmap/josm
Files:
1 added
6 edited

Legend:

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

    r3317 r3355  
    3030import org.openstreetmap.josm.actions.ParameterizedAction;
    3131import org.openstreetmap.josm.actions.ActionParameter.SearchSettingsActionParameter;
     32import org.openstreetmap.josm.actions.search.SearchCompiler.ParseError;
    3233import org.openstreetmap.josm.data.osm.DataSet;
    3334import org.openstreetmap.josm.data.osm.Filter;
     
    157158        bg.add(in_selection);
    158159
    159         JCheckBox caseSensitive = new JCheckBox(tr("case sensitive"), initialValues.caseSensitive);
     160        final JCheckBox caseSensitive = new JCheckBox(tr("case sensitive"), initialValues.caseSensitive);
    160161        JCheckBox allElements = new JCheckBox(tr("all objects"), initialValues.allElements);
    161162        allElements.setToolTipText(tr("Also include incomplete and deleted objects in search."));
    162         JCheckBox regexSearch   = new JCheckBox(tr("regular expression"), initialValues.regexSearch);
     163        final JCheckBox regexSearch   = new JCheckBox(tr("regular expression"), initialValues.regexSearch);
    163164
    164165        JPanel left = new JPanel(new GridBagLayout());
     
    218219                    initialValues instanceof Filter ? tr("Submit filter") : tr("Start Search"),
    219220                            tr("Cancel")}
    220         );
     221        ) {
     222            @Override
     223            protected void buttonAction(int buttonIndex, ActionEvent evt) {
     224                if (buttonIndex == 0) {
     225                    try {
     226                        SearchCompiler.compile(hcbSearchString.getText(), caseSensitive.isSelected(), regexSearch.isSelected());
     227                        super.buttonAction(buttonIndex, evt);
     228                    } catch (ParseError e) {
     229                        JOptionPane.showMessageDialog(
     230                                Main.parent,
     231                                tr("Search expression is not valid: \n\n {0}", e.getMessage()),
     232                                tr("Invalid search expression"),
     233                                JOptionPane.ERROR_MESSAGE);
     234                    }
     235                } else {
     236                    super.buttonAction(buttonIndex, evt);
     237                }
     238            }
     239        };
    221240        dialog.setButtonIcons(new String[] {"dialogs/search.png", "cancel.png"});
    222241        dialog.configureContextsensitiveHelp("/Action/Search", true /* show help button */);
     
    282301
    283302            Collection<OsmPrimitive> all;
    284             if(s.allElements)
     303            if(s.allElements) {
    285304                all = Main.main.getCurrentDataSet().allPrimitives();
    286             else
     305            } else {
    287306                all = Main.main.getCurrentDataSet().allNonDeletedCompletePrimitives();
     307            }
    288308            for (OsmPrimitive osm : all) {
    289309                if (s.mode == SearchMode.replace) {
     
    415435        public SearchSetting() {
    416436            this("", SearchMode.replace, false /* case insensitive */,
    417             false /* no regexp */, false /* only useful primitives */);
     437                    false /* no regexp */, false /* only useful primitives */);
    418438        }
    419439
    420440        public SearchSetting(String text, SearchMode mode, boolean caseSensitive,
    421         boolean regexSearch, boolean allElements) {
     441                boolean regexSearch, boolean allElements) {
    422442            this.caseSensitive = caseSensitive;
    423443            this.regexSearch = regexSearch;
     
    429449        public SearchSetting(SearchSetting original) {
    430450            this(original.text, original.mode, original.caseSensitive,
    431             original.regexSearch, original.allElements);
     451                    original.regexSearch, original.allElements);
    432452        }
    433453
     
    436456            String cs = caseSensitive ?
    437457                    /*case sensitive*/  trc("search", "CS") :
    438                     /*case insensitive*/  trc("search", "CI");
    439             String rx = regexSearch ? (", " +
    440                     /*regex search*/ trc("search", "RX")) : "";
    441             String all = allElements ? (", " +
    442                     /*all elements*/ trc("search", "A")) : "";
    443             return "\"" + text + "\" (" + cs + rx + all + ", " + mode + ")";
     458                        /*case insensitive*/  trc("search", "CI");
     459                    String rx = regexSearch ? (", " +
     460                            /*regex search*/ trc("search", "RX")) : "";
     461                    String all = allElements ? (", " +
     462                            /*all elements*/ trc("search", "A")) : "";
     463                    return "\"" + text + "\" (" + cs + rx + all + ", " + mode + ")";
    444464        }
    445465
  • trunk/src/org/openstreetmap/josm/actions/search/SearchCompiler.java

    r3336 r3355  
    7575    }
    7676
    77     private static class Not extends Match {
     77    public static class Not extends Match {
    7878        private final Match match;
    7979        public Not(Match match) {this.match = match;}
  • trunk/src/org/openstreetmap/josm/data/osm/Filter.java

    r3317 r3355  
    1111    private static final String version = "1";
    1212
    13     public Boolean enable = true;
    14     public Boolean hiding = false;
    15     public Boolean inverted = false;
     13    public boolean enable = true;
     14    public boolean hiding = false;
     15    public boolean inverted = false;
     16
    1617    public Filter() {
    1718        super("", SearchMode.add, false, false, false);
    1819    }
    1920    public Filter(String text, SearchMode mode, boolean caseSensitive,
    20     boolean regexSearch, boolean allElements) {
     21            boolean regexSearch, boolean allElements) {
    2122        super(text, mode, caseSensitive, regexSearch, allElements);
    2223    }
    2324
    24     public Filter(String prefText){
     25    public Filter(String prefText) {
    2526        super("", SearchMode.add, false, false, false);
    2627        String[] prfs = prefText.split(";");
     
    4950    public String getPrefString(){
    5051        return version + ";" +
    51             text + ";" + mode + ";" + caseSensitive + ";" + regexSearch + ";" +
    52             "legacy" + ";" + enable + ";" + hiding + ";" +
    53             inverted + ";" +
    54             "false"; // last parameter is not used any more (was: applyForChildren)
     52        text + ";" + mode + ";" + caseSensitive + ";" + regexSearch + ";" +
     53        "legacy" + ";" + enable + ";" + hiding + ";" +
     54        inverted + ";" +
     55        "false"; // last parameter is not used any more (was: applyForChildren)
    5556    }
    5657}
  • trunk/src/org/openstreetmap/josm/data/osm/Filters.java

    r3354 r3355  
    1616import javax.swing.BorderFactory;
    1717import javax.swing.JLabel;
     18import javax.swing.JOptionPane;
    1819import javax.swing.table.AbstractTableModel;
    1920
    2021import org.openstreetmap.josm.Main;
    21 import org.openstreetmap.josm.actions.search.SearchAction;
    22 import org.openstreetmap.josm.tools.Property;
     22import org.openstreetmap.josm.actions.search.SearchCompiler.ParseError;
    2323
    2424/**
     
    3737    }
    3838
    39     private List<Filter> filters = new LinkedList<Filter>();
     39    private final List<Filter> filters = new LinkedList<Filter>();
     40    private final FilterMatcher filterMatcher = new FilterMatcher();
     41
     42    private void updateFilters() {
     43        try {
     44            filterMatcher.update(filters);
     45            executeFilters();
     46        } catch (ParseError e) {
     47            JOptionPane.showMessageDialog(
     48                    Main.parent,
     49                    e.getMessage(),
     50                    tr("Error in filter"),
     51                    JOptionPane.ERROR_MESSAGE);
     52        }
     53    }
     54
    4055
    4156    /**
     
    6984
    7085        final Collection<OsmPrimitive> all = ds.allNonDeletedCompletePrimitives();
    71         // temporary set to collect the primitives returned by the search engine
    72         final Collection<OsmPrimitive> collect = new HashSet<OsmPrimitive>();
    73 
    74         // an auxiliary property to collect the results of the search engine
    75         class CollectProperty implements Property<OsmPrimitive,Boolean> {
    76             boolean collectValue;
    77             boolean hidden;
    78 
    79             /**
    80              * Depending on the parameters, there are 4 different instances
    81              * of this class.
    82              *
    83              * @param collectValue
    84              *          If true: collect only those primitives that are added
    85              *              by the search engine.
    86              *          If false: Collect only those primitives that are removed
    87              *              by the search engine.
    88              * @param hidden Whether the property refers to primitives that
    89              *          are disabled and hidden or to primitives
    90              *          that are disabled only.
    91              */
    92             public CollectProperty(boolean collectValue, boolean hidden) {
    93                 this.collectValue = collectValue;
    94                 this.hidden = hidden;
    95             }
    96 
    97             public Boolean get(OsmPrimitive osm) {
    98                 if (hidden)
    99                     return osm.isDisabledAndHidden();
    100                 else
    101                     return osm.isDisabled();
    102             }
    103 
    104             public void set(OsmPrimitive osm, Boolean value) {
    105                 if (collectValue == value.booleanValue()) {
    106                     collect.add(osm);
    107                 }
    108             }
    109         }
    110 
    111         clearFilterFlags();
    112 
    113         for (Filter flt : filters){
    114             if (flt.enable) {
    115                 collect.clear();
    116                 // Decide, whether primitives are collected that are added to the current
    117                 // selection or those that are removed from the current selection
    118                 boolean collectValue = flt.mode == SearchAction.SearchMode.replace || flt.mode == SearchAction.SearchMode.add;
    119                 Property<OsmPrimitive,Boolean> collectProp = new CollectProperty(collectValue, flt.hiding);
    120 
    121                 SearchAction.getSelection(flt, all, collectProp);
    122 
    123                 switch (flt.mode) {
    124                 case replace:
    125                     for (OsmPrimitive osm : all) {
    126                         osm.unsetDisabledState();
     86
     87        for (OsmPrimitive primitive: all) {
     88            if (filterMatcher.isHidden(primitive)) {
     89                primitive.setDisabledState(true);
     90            } else if (filterMatcher.isDisabled(primitive)) {
     91                primitive.setDisabledState(false);
     92            } else {
     93                primitive.unsetDisabledState();
     94            }
     95        }
     96
     97        for (OsmPrimitive primitive: all) {
     98            if (primitive instanceof Way && primitive.isDisabled()) {
     99                Way w = (Way)primitive;
     100                for (Node n: w.getNodes()) {
     101
     102                    if (n.isTagged()) {
     103                        continue;
    127104                    }
    128                 case add:
    129                     if (!flt.inverted) {
    130                         for (OsmPrimitive osm : collect) {
    131                             osm.setDisabledState(flt.hiding);
    132                         }
    133 
    134                         // Find child nodes of hidden ways and add them to the hidden nodes
    135                         for (OsmPrimitive osm : collect) {
    136                             if (osm instanceof Way) {
    137                                 nodes:
    138                                     for (Node n : ((Way)osm).getNodes()) {
    139                                         // if node is already disabled, there is nothing to do
    140                                         if (n.isDisabledAndHidden() || (!flt.hiding && n.isDisabled())) {
    141                                             continue;
    142                                         }
    143 
    144                                         // if the node is tagged, don't disable it
    145                                         if (n.isTagged()) {
    146                                             continue;
    147                                         }
    148 
    149                                         // if the node has undisabled parent ways, don't disable it
    150                                         for (OsmPrimitive ref : n.getReferrers()) {
    151                                             if (ref instanceof Way) {
    152                                                 if (!ref.isDisabled()) {
    153                                                     continue nodes;
    154                                                 }
    155                                                 if (flt.hiding && !ref.isDisabledAndHidden()) {
    156                                                     continue nodes;
    157                                                 }
    158                                             }
    159                                         }
    160                                         n.setDisabledState(flt.hiding);
    161                                     }
    162                             }
    163                         }
    164                     } else { // inverted filter in add mode
    165                         // update flags, except for nodes
    166                         for (OsmPrimitive osm : collect) {
    167                             if (!(osm instanceof Node)) {
    168                                 osm.setDisabledState(flt.hiding);
    169                             }
    170                         }
    171 
    172                         // update flags for nodes
    173                         nodes:
    174                             for (OsmPrimitive osm : collect) {
    175                                 if (osm instanceof Node) {
    176                                     // if node is already disabled, there is nothing to do
    177                                     if (osm.isDisabledAndHidden() || (!flt.hiding && osm.isDisabled())) {
    178                                         continue;
    179                                     }
    180 
    181                                     // if the node has undisabled parent ways, don't disable it
    182                                     for (OsmPrimitive ref : osm.getReferrers()) {
    183                                         if (ref instanceof Way) {
    184                                             if (!ref.isDisabled()) {
    185                                                 continue nodes;
    186                                             }
    187                                             if (flt.hiding && !ref.isDisabledAndHidden()) {
    188                                                 continue nodes;
    189                                             }
    190                                         }
    191                                     }
    192                                     osm.setDisabledState(flt.hiding);
    193                                 }
    194                             }
    195                     }
    196                     break;
    197                 case remove:
    198                 case in_selection:
    199                     if (!flt.inverted) {
    200                         // make the described primitive undisabled again
    201                         for (OsmPrimitive osm : collect) {
    202                             osm.unsetDisabledState();
    203                         }
    204 
    205                         // Undisable the child nodes of undisabled ways
    206                         for (OsmPrimitive osm : collect) {
    207                             if (osm instanceof Way) {
    208                                 for (Node n : ((Way) osm).getNodes()) {
    209                                     n.unsetDisabledState();
    210                                 }
    211                             }
    212                         }
    213                     } else { // inverted filter in remove mode
    214                         // make the described primitive undisabled again
    215                         for (OsmPrimitive osm : collect) {
    216                             osm.unsetDisabledState();
    217                         }
    218 
    219                         // Undisable the child nodes of undisabled ways
    220                         for (OsmPrimitive osm : collect) {
    221                             if (osm instanceof Way) {
    222                                 for (Node n : ((Way) osm).getNodes()) {
    223                                     n.unsetDisabledState();
    224                                 }
    225                             }
     105
     106                    boolean disabled = w.isDisabled();
     107                    boolean hidden = w.isDisabledAndHidden();
     108                    for (OsmPrimitive ref: n.getReferrers()) {
     109                        if (ref instanceof Way) {
     110                            disabled = disabled && ref.isDisabled();
     111                            hidden = hidden && ref.isDisabledAndHidden();
    226112                        }
    227113                    }
    228                     break;
    229                 default:
    230                     throw new IllegalStateException();
     114
     115                    if (disabled) {
     116                        n.setDisabledState(hidden);
     117                    }
    231118                }
    232119            }
     
    269156
    270157    private void loadPrefs() {
    271         Map<String,String> prefs = Main.pref.getAllPrefix("filters.filter");
     158        Map<String, String> prefs = Main.pref.getAllPrefix("filters.filter");
    272159        for (String value : prefs.values()) {
    273160            filters.add(new Filter(value));
    274161        }
    275     }
    276 
    277     private void savePrefs(){
    278         Map<String,String> prefs = Main.pref.getAllPrefix("filters.filter");
     162        updateFilters();
     163    }
     164
     165    private void savePrefs() {
     166        Map<String, String> prefs = Main.pref.getAllPrefix("filters.filter");
    279167        for (String key : prefs.keySet()) {
    280168            String[] sts = key.split("\\.");
    281             if (sts.length != 3)throw new Error("Incompatible filter preferences");
     169            if (sts.length != 3)
     170                throw new Error("Incompatible filter preferences");
    282171            Main.pref.put("filters.filter." + sts[2], null);
    283172        }
    284173
    285174        int i = 0;
    286         for (Filter flt : filters){
     175        for (Filter flt : filters) {
    287176            Main.pref.put("filters.filter." + i++, flt.getPrefString());
    288177        }
    289178    }
    290179
    291     private void savePref(int i){
    292         if(i >= filters.size()) {
     180    private void savePref(int i) {
     181        if (i >= filters.size()) {
    293182            Main.pref.put("filters.filter." + i, null);
    294183        } else {
     
    297186    }
    298187
    299     public void addFilter(Filter f){
     188    public void addFilter(Filter f) {
    300189        filters.add(f);
    301         savePref(filters.size()-1);
    302         executeFilters();
    303         fireTableRowsInserted(filters.size()-1, filters.size()-1);
    304     }
    305 
    306     public void moveDownFilter(int i){
    307         if(i >= filters.size()-1) return;
    308         filters.add(i+1, filters.remove(i));
     190        savePref(filters.size() - 1);
     191        updateFilters();
     192        fireTableRowsInserted(filters.size() - 1, filters.size() - 1);
     193    }
     194
     195    public void moveDownFilter(int i) {
     196        if (i >= filters.size() - 1)
     197            return;
     198        filters.add(i + 1, filters.remove(i));
    309199        savePref(i);
    310         savePref(i+1);
    311         executeFilters();
    312         fireTableRowsUpdated(i, i+1);
    313     }
    314 
    315     public void moveUpFilter(int i){
    316         if(i == 0) return;
    317         filters.add(i-1, filters.remove(i));
     200        savePref(i + 1);
     201        updateFilters();
     202        fireTableRowsUpdated(i, i + 1);
     203    }
     204
     205    public void moveUpFilter(int i) {
     206        if (i == 0)
     207            return;
     208        filters.add(i - 1, filters.remove(i));
    318209        savePref(i);
    319         savePref(i-1);
    320         executeFilters();
    321         fireTableRowsUpdated(i-1, i);
    322     }
    323 
    324     public void removeFilter(int i){
     210        savePref(i - 1);
     211        updateFilters();
     212        fireTableRowsUpdated(i - 1, i);
     213    }
     214
     215    public void removeFilter(int i) {
    325216        filters.remove(i);
    326217        savePrefs();
    327         executeFilters();
     218        updateFilters();
    328219        fireTableRowsDeleted(i, i);
    329220    }
    330221
    331     public void setFilter(int i, Filter f){
     222    public void setFilter(int i, Filter f) {
    332223        filters.set(i, f);
    333224        savePref(i);
    334         executeFilters();
     225        updateFilters();
    335226        fireTableRowsUpdated(i, i);
    336227    }
    337228
    338     public Filter getFilter(int i){
     229    public Filter getFilter(int i) {
    339230        return filters.get(i);
    340231    }
    341232
    342     public int getRowCount(){
     233    public int getRowCount() {
    343234        return filters.size();
    344235    }
    345236
    346     public int getColumnCount(){
     237    public int getColumnCount() {
    347238        return 5;
    348239    }
    349240
    350241    @Override
    351     public String getColumnName(int column){
     242    public String getColumnName(int column) {
    352243        String[] names = { /* translators notes must be in front */
    353                 /* column header: enable filter */             trc("filter","E"),
    354                 /* column header: hide filter */               trc("filter", "H"),
    355                 /* column header: filter text */               trc("filter", "Text"),
    356                 /* column header: inverted filter */           trc("filter", "I"),
    357                 /* column header: filter mode */               trc("filter", "M")
    358         };
     244                /* column header: enable filter */trc("filter", "E"),
     245                /* column header: hide filter */trc("filter", "H"),
     246                /* column header: filter text */trc("filter", "Text"),
     247                /* column header: inverted filter */trc("filter", "I"),
     248                /* column header: filter mode */trc("filter", "M") };
    359249        return names[column];
    360250    }
    361251
    362252    @Override
    363     public Class<?> getColumnClass(int column){
     253    public Class<?> getColumnClass(int column) {
    364254        Class<?>[] classes = { Boolean.class, Boolean.class, String.class, Boolean.class, String.class };
    365255        return classes[column];
    366256    }
    367257
    368     public boolean isCellEnabled(int row, int column){
    369         if(!filters.get(row).enable && column!=0) return false;
     258    public boolean isCellEnabled(int row, int column) {
     259        if (!filters.get(row).enable && column != 0)
     260            return false;
    370261        return true;
    371262    }
    372263
    373264    @Override
    374     public boolean isCellEditable(int row, int column){
    375         if(!filters.get(row).enable && column!=0) return false;
    376         if(column < 4)return true;
     265    public boolean isCellEditable(int row, int column) {
     266        if (!filters.get(row).enable && column != 0)
     267            return false;
     268        if (column < 4)
     269            return true;
    377270        return false;
    378271    }
    379272
    380273    @Override
    381     public void setValueAt(Object aValue, int row, int column){
     274    public void setValueAt(Object aValue, int row, int column) {
    382275        Filter f = filters.get(row);
    383         switch(column){
     276        switch (column) {
    384277        case 0:
    385             f.enable = (Boolean)aValue;
     278            f.enable = (Boolean) aValue;
    386279            savePref(row);
    387             executeFilters();
     280            updateFilters();
    388281            fireTableRowsUpdated(row, row);
    389282            break;
    390283        case 1:
    391             f.hiding = (Boolean)aValue;
     284            f.hiding = (Boolean) aValue;
    392285            savePref(row);
    393             executeFilters();
     286            updateFilters();
    394287            break;
    395288        case 2:
    396             f.text = (String)aValue;
     289            f.text = (String) aValue;
    397290            savePref(row);
    398291            break;
    399292        case 3:
    400             f.inverted = (Boolean)aValue;
     293            f.inverted = (Boolean) aValue;
    401294            savePref(row);
    402             executeFilters();
     295            updateFilters();
    403296            break;
    404297        }
    405         if(column!=0) {
     298        if (column != 0) {
    406299            fireTableCellUpdated(row, column);
    407300        }
    408301    }
    409302
    410     public Object getValueAt(int row, int column){
     303    public Object getValueAt(int row, int column) {
    411304        Filter f = filters.get(row);
    412         switch(column){
    413         case 0: return f.enable;
    414         case 1: return f.hiding;
    415         case 2: return f.text;
    416         case 3: return f.inverted;
     305        switch (column) {
     306        case 0:
     307            return f.enable;
     308        case 1:
     309            return f.hiding;
     310        case 2:
     311            return f.text;
     312        case 3:
     313            return f.inverted;
    417314        case 4:
    418             switch(f.mode){ /* translators notes must be in front */
    419             case replace:      /* filter mode: replace */      return trc("filter", "R");
    420             case add:          /* filter mode: add */          return trc("filter", "A");
    421             case remove:       /* filter mode: remove */       return trc("filter", "D");
    422             case in_selection: /* filter mode: in selection */ return trc("filter", "F");
     315            switch (f.mode) { /* translators notes must be in front */
     316            case replace: /* filter mode: replace */
     317                return trc("filter", "R");
     318            case add: /* filter mode: add */
     319                return trc("filter", "A");
     320            case remove: /* filter mode: remove */
     321                return trc("filter", "D");
     322            case in_selection: /* filter mode: in selection */
     323                return trc("filter", "F");
    423324            }
    424325        }
     
    434335            setOpaque(true);
    435336            setForeground(Color.black);
    436             setBackground(new Color(0,0,0,0));
     337            setBackground(new Color(0, 0, 0, 0));
    437338            setFont(getFont().deriveFont(Font.PLAIN));
    438339            setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10));
     
    450351
    451352    public void drawOSDText(Graphics2D g) {
    452         String message = "<html>"+tr("<h2>Filter active</h2>");
     353        String message = "<html>" + tr("<h2>Filter active</h2>");
    453354
    454355        if (disabledCount == 0 && disabledAndHiddenCount == 0)
  • trunk/src/org/openstreetmap/josm/gui/ExtendedDialog.java

    r3351 r3355  
    291291     * @param evt the button event
    292292     */
    293     protected void buttonAction(int i, ActionEvent evt) {
     293    protected void buttonAction(int buttonIndex, ActionEvent evt) {
    294294        String a = evt.getActionCommand();
    295         result = i+1;
     295        result = buttonIndex+1;
    296296        setVisible(false);
    297297    }
  • trunk/src/org/openstreetmap/josm/gui/dialogs/FilterDialog.java

    r3346 r3355  
    8080                if(filter != null){
    8181                    filters.addFilter(filter);
    82                     filters.executeFilters();
    8382                }
    8483            }
     
    9594                if(filter != null){
    9695                    filters.setFilter(index, filter);
    97                     filters.executeFilters();
    9896                }
    9997            }
Note: See TracChangeset for help on using the changeset viewer.