Ignore:
Timestamp:
2015-10-17T01:33:47+02:00 (4 years ago)
Author:
simon04
Message:

fix #11911 - SearchAction: show progress and allow to cancel operation

File:
1 edited

Legend:

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

    r8846 r8883  
    55import static org.openstreetmap.josm.tools.I18n.tr;
    66import static org.openstreetmap.josm.tools.I18n.trc;
     7import static org.openstreetmap.josm.tools.I18n.trn;
    78
    89import java.awt.Cursor;
     
    4445import org.openstreetmap.josm.data.osm.OsmPrimitive;
    4546import org.openstreetmap.josm.gui.ExtendedDialog;
     47import org.openstreetmap.josm.gui.PleaseWaitRunnable;
    4648import org.openstreetmap.josm.gui.preferences.ToolbarPreferences;
    4749import org.openstreetmap.josm.gui.preferences.ToolbarPreferences.ActionParser;
     50import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    4851import org.openstreetmap.josm.gui.widgets.HistoryComboBox;
    4952import org.openstreetmap.josm.tools.GBC;
    5053import org.openstreetmap.josm.tools.Predicate;
    51 import org.openstreetmap.josm.tools.Property;
    5254import org.openstreetmap.josm.tools.Shortcut;
    5355import org.openstreetmap.josm.tools.Utils;
     
    465467    }
    466468
    467     public static int getSelection(SearchSetting s, Collection<OsmPrimitive> sel, Predicate<OsmPrimitive> p) {
    468         int foundMatches = 0;
    469         try {
    470             SearchCompiler.Match matcher = SearchCompiler.compile(s);
    471 
    472             if (s.mode == SearchMode.replace) {
    473                 sel.clear();
    474             } else if (s.mode == SearchMode.in_selection) {
    475                 foundMatches = sel.size();
    476             }
    477 
    478             Collection<OsmPrimitive> all;
    479             if (s.allElements) {
    480                 all = Main.main.getCurrentDataSet().allPrimitives();
    481             } else {
    482                 all = Main.main.getCurrentDataSet().allNonDeletedCompletePrimitives();
    483             }
    484 
    485             for (OsmPrimitive osm : all) {
    486                 if (s.mode == SearchMode.replace) {
    487                     if (matcher.match(osm)) {
    488                         sel.add(osm);
    489                         ++foundMatches;
    490                     }
    491                 } else if (s.mode == SearchMode.add && !p.evaluate(osm) && matcher.match(osm)) {
    492                     sel.add(osm);
    493                     ++foundMatches;
    494                 } else if (s.mode == SearchMode.remove && p.evaluate(osm) && matcher.match(osm)) {
    495                     sel.remove(osm);
    496                     ++foundMatches;
    497                 } else if (s.mode == SearchMode.in_selection && p.evaluate(osm) && !matcher.match(osm)) {
    498                     sel.remove(osm);
    499                     --foundMatches;
    500                 }
    501             }
    502         } catch (SearchCompiler.ParseError e) {
    503             JOptionPane.showMessageDialog(
    504                     Main.parent,
    505                     e.getMessage(),
    506                     tr("Error"),
    507                     JOptionPane.ERROR_MESSAGE
    508 
    509             );
    510         }
    511         return foundMatches;
    512     }
    513 
    514469    /**
    515      * Version of getSelection that is customized for filter, but should also work in other context.
     470     * Performs the search specified by the search string {@code search} and the search mode {@code mode}.
    516471     *
    517      * @param s the search settings
    518      * @param all the collection of all the primitives that should be considered
    519      * @param p the property that should be set/unset if something is found
     472     * @param search the search string to use
     473     * @param mode the search mode to use
    520474     */
    521     public static void getSelection(SearchSetting s, Collection<OsmPrimitive> all, Property<OsmPrimitive, Boolean> p) {
    522         try {
    523             if (s instanceof Filter && ((Filter) s).inverted) {
    524                 s = new SearchSetting(s);
    525                 s.text = String.format("-(%s)", s.text);
    526             }
    527             SearchCompiler.Match matcher = SearchCompiler.compile(s);
    528 
    529             for (OsmPrimitive osm : all) {
    530                 if (s.mode == SearchMode.replace) {
    531                     if (matcher.match(osm)) {
    532                         p.set(osm, Boolean.TRUE);
    533                     } else {
    534                         p.set(osm, Boolean.FALSE);
    535                     }
    536                 } else if (s.mode == SearchMode.add && !p.get(osm) && matcher.match(osm)) {
    537                     p.set(osm, Boolean.TRUE);
    538                 } else if (s.mode == SearchMode.remove && p.get(osm) && matcher.match(osm)) {
    539                     p.set(osm, Boolean.FALSE);
    540                 } else if (s.mode == SearchMode.in_selection && p.get(osm) && !matcher.match(osm)) {
    541                     p.set(osm, Boolean.FALSE);
    542                 }
    543             }
    544         } catch (SearchCompiler.ParseError e) {
    545             JOptionPane.showMessageDialog(
    546                     Main.parent,
    547                     e.getMessage(),
    548                     tr("Error"),
    549                     JOptionPane.ERROR_MESSAGE
    550             );
    551         }
    552     }
    553 
    554475    public static void search(String search, SearchMode mode) {
    555476        final SearchSetting searchSetting = new SearchSetting();
     
    559480    }
    560481
    561     public static void search(SearchSetting s) {
    562 
    563         final DataSet ds = Main.main.getCurrentDataSet();
    564         Collection<OsmPrimitive> sel = new HashSet<>(ds.getAllSelected());
    565         int foundMatches = getSelection(s, sel, new Predicate<OsmPrimitive>() {
    566             @Override
    567             public boolean evaluate(OsmPrimitive o) {
    568                 return ds.isSelected(o);
    569             }
    570         });
    571         ds.setSelected(sel);
    572         if (foundMatches == 0) {
    573             String msg = null;
    574             final String text = Utils.shortenString(s.text, MAX_LENGTH_SEARCH_EXPRESSION_DISPLAY);
    575             if (s.mode == SearchMode.replace) {
    576                 msg = tr("No match found for ''{0}''", text);
    577             } else if (s.mode == SearchMode.add) {
    578                 msg = tr("Nothing added to selection by searching for ''{0}''", text);
    579             } else if (s.mode == SearchMode.remove) {
    580                 msg = tr("Nothing removed from selection by searching for ''{0}''", text);
    581             } else if (s.mode == SearchMode.in_selection) {
    582                 msg = tr("Nothing found in selection by searching for ''{0}''", text);
    583             }
    584             Main.map.statusLine.setHelpText(msg);
    585             JOptionPane.showMessageDialog(
    586                     Main.parent,
    587                     msg,
    588                     tr("Warning"),
    589                     JOptionPane.WARNING_MESSAGE
    590             );
    591         } else {
    592             Main.map.statusLine.setHelpText(tr("Found {0} matches", foundMatches));
     482    static void search(SearchSetting s) {
     483        SearchTask.newSearchTask(s).run();
     484    }
     485
     486    static class SearchTask extends PleaseWaitRunnable {
     487        private final DataSet ds;
     488        private final SearchSetting setting;
     489        private final Collection<OsmPrimitive> selection;
     490        private final Predicate<OsmPrimitive> predicate;
     491        private boolean canceled;
     492        private int foundMatches;
     493
     494        private SearchTask(DataSet ds, SearchSetting setting, Collection<OsmPrimitive> selection, Predicate<OsmPrimitive> predicate) {
     495            super(tr("Searching"));
     496            this.ds = ds;
     497            this.setting = setting;
     498            this.selection = selection;
     499            this.predicate = predicate;
     500        }
     501
     502        static SearchTask newSearchTask(SearchSetting setting) {
     503            final DataSet ds = Main.main.getCurrentDataSet();
     504            final Collection<OsmPrimitive> selection = new HashSet<>(ds.getAllSelected());
     505            return new SearchTask(ds, setting, selection, new Predicate<OsmPrimitive>() {
     506                @Override
     507                public boolean evaluate(OsmPrimitive o) {
     508                    return ds.isSelected(o);
     509                }
     510            });
     511        }
     512
     513        @Override
     514        protected void cancel() {
     515            this.canceled = true;
     516        }
     517
     518        @Override
     519        protected void realRun() {
     520            try {
     521                foundMatches = 0;
     522                SearchCompiler.Match matcher = SearchCompiler.compile(setting);
     523
     524                if (setting.mode == SearchMode.replace) {
     525                    selection.clear();
     526                } else if (setting.mode == SearchMode.in_selection) {
     527                    foundMatches = selection.size();
     528                }
     529
     530                Collection<OsmPrimitive> all;
     531                if (setting.allElements) {
     532                    all = Main.main.getCurrentDataSet().allPrimitives();
     533                } else {
     534                    all = Main.main.getCurrentDataSet().allNonDeletedCompletePrimitives();
     535                }
     536                final ProgressMonitor subMonitor = getProgressMonitor().createSubTaskMonitor(all.size(), false);
     537                subMonitor.beginTask(trn("Searching in {0} object", "Searching in {0} objects", all.size(), all.size()));
     538
     539                for (OsmPrimitive osm : all) {
     540                    if (canceled) {
     541                        return;
     542                    }
     543                    if (setting.mode == SearchMode.replace) {
     544                        if (matcher.match(osm)) {
     545                            selection.add(osm);
     546                            ++foundMatches;
     547                        }
     548                    } else if (setting.mode == SearchMode.add && !predicate.evaluate(osm) && matcher.match(osm)) {
     549                        selection.add(osm);
     550                        ++foundMatches;
     551                    } else if (setting.mode == SearchMode.remove && predicate.evaluate(osm) && matcher.match(osm)) {
     552                        selection.remove(osm);
     553                        ++foundMatches;
     554                    } else if (setting.mode == SearchMode.in_selection && predicate.evaluate(osm) && !matcher.match(osm)) {
     555                        selection.remove(osm);
     556                        --foundMatches;
     557                    }
     558                    subMonitor.worked(1);
     559                }
     560                subMonitor.finishTask();
     561            } catch (SearchCompiler.ParseError e) {
     562                JOptionPane.showMessageDialog(
     563                        Main.parent,
     564                        e.getMessage(),
     565                        tr("Error"),
     566                        JOptionPane.ERROR_MESSAGE
     567
     568                );
     569            }
     570        }
     571
     572        @Override
     573        protected void finish() {
     574            if (canceled) {
     575                return;
     576            }
     577            ds.setSelected(selection);
     578            if (foundMatches == 0) {
     579                final String msg;
     580                final String text = Utils.shortenString(setting.text, MAX_LENGTH_SEARCH_EXPRESSION_DISPLAY);
     581                if (setting.mode == SearchMode.replace) {
     582                    msg = tr("No match found for ''{0}''", text);
     583                } else if (setting.mode == SearchMode.add) {
     584                    msg = tr("Nothing added to selection by searching for ''{0}''", text);
     585                } else if (setting.mode == SearchMode.remove) {
     586                    msg = tr("Nothing removed from selection by searching for ''{0}''", text);
     587                } else if (setting.mode == SearchMode.in_selection) {
     588                    msg = tr("Nothing found in selection by searching for ''{0}''", text);
     589                } else {
     590                    msg = null;
     591                }
     592                Main.map.statusLine.setHelpText(msg);
     593                JOptionPane.showMessageDialog(
     594                        Main.parent,
     595                        msg,
     596                        tr("Warning"),
     597                        JOptionPane.WARNING_MESSAGE
     598                );
     599            } else {
     600                Main.map.statusLine.setHelpText(tr("Found {0} matches", foundMatches));
     601            }
    593602        }
    594603    }
Note: See TracChangeset for help on using the changeset viewer.