Changeset 967 in josm


Ignore:
Timestamp:
2008-09-14T17:02:09+02:00 (16 years ago)
Author:
stoecker
Message:

added search and selection improvements by Jan Peter Stotz. Closes #1306

Location:
trunk/src/org/openstreetmap/josm
Files:
2 edited

Legend:

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

    r939 r967  
    88import java.awt.event.KeyEvent;
    99import java.util.Collection;
     10import java.util.LinkedList;
    1011
    1112import javax.swing.ButtonGroup;
     
    2324
    2425public class SearchAction extends JosmAction {
    25         public static enum SearchMode {replace, add, remove}
    2626
    27     private String lastSearch = "";
     27    public static final int SEARCH_HISTORY_SIZE = 10;
     28
     29    public static enum SearchMode {
     30        replace, add, remove
     31    }
     32
     33    public static final LinkedList<SearchSetting> searchHistory = new LinkedList<SearchSetting>();
     34
     35    private static SearchSetting lastSearch = null;
    2836
    2937    public SearchAction() {
    30         super(tr("Search ..."), "dialogs/search", tr("Search for objects."), KeyEvent.VK_F, KeyEvent.CTRL_DOWN_MASK, true);
     38        super(tr("Search ..."), "dialogs/search", tr("Search for objects."), KeyEvent.VK_F, KeyEvent.CTRL_DOWN_MASK,
     39                true);
    3140    }
    3241
    3342    public void actionPerformed(ActionEvent e) {
    34         if (Main.map == null) {
    35                 JOptionPane.showMessageDialog(Main.parent, tr("No data loaded."));
    36                 return;
    37         }
    38         JLabel label = new JLabel(tr("Please enter a search string."));
    39         final JTextField input = new JTextField(lastSearch);
    40         input.setToolTipText(tr("<html>Fulltext search:<ul>" +
    41                         "<li><b>Baker Street</b> - 'Baker' and 'Street' in any key or name.</li>" +
    42                         "<li><b>\"Baker Street\"</b> - 'Baker Street' in any key or name.</li>" +
    43                         "<li><b>name:Bak</b> - 'Bak' anywhere in the name.</li>" +
    44                         "<li><b>-name:Bak</b> - not 'Bak' in the name.</li>" +
    45                         "<li><b>foot:</b> - key=foot set to any value.</li>" +
    46                         "<li>Special targets:</li>" +
    47                         "<li><b>type:</b> - type of the object (<b>node</b>, <b>way</b>, <b>relation</b>)</li>" +
    48                         "<li><b>user:</b>... - all objects changed by user</li>" +
    49                         "<li><b>id:</b>... - object with given ID</li>" +
    50                         "<li><b>nodes:</b>... - object with given number of nodes</li>" +
    51                         "<li><b>modified</b> - all changed objects</li>" +
    52                         "<li><b>incomplete</b> - all incomplete objects</li>" +
    53                         "<li>Use <b>|</b> or <b>OR</b> to combine with logical or</li>" +
    54                         "<li>Use <b>\"</b> to quote operators (e.g. if key contains :)</li>" +
    55                         "<li>Use <b>(</b> and <b>)</b> to group expressions</li>" +
    56         "</ul></html>"));
    57    
    58         JRadioButton replace = new JRadioButton(tr("replace selection"), true);
    59         JRadioButton add = new JRadioButton(tr("add to selection"), false);
    60         JRadioButton remove = new JRadioButton(tr("remove from selection"), false);
    61         ButtonGroup bg = new ButtonGroup();
    62         bg.add(replace);
    63         bg.add(add);
    64         bg.add(remove);
    65        
    66         JCheckBox caseSensitive = new JCheckBox(tr("case sensitive"), false);
    67    
    68         JPanel p = new JPanel(new GridBagLayout());
    69         p.add(label, GBC.eop());
    70         p.add(input, GBC.eop().fill(GBC.HORIZONTAL));
    71         p.add(replace, GBC.eol());
    72         p.add(add, GBC.eol());
    73         p.add(remove, GBC.eop());
    74         p.add(caseSensitive, GBC.eol());
    75         JOptionPane pane = new JOptionPane(p, JOptionPane.INFORMATION_MESSAGE, JOptionPane.OK_CANCEL_OPTION, null){
    76                 @Override public void selectInitialValue() {
    77                         input.requestFocusInWindow();
    78                         input.selectAll();
    79                 }
    80         };
    81         pane.createDialog(Main.parent,tr("Search")).setVisible(true);
    82         if (!Integer.valueOf(JOptionPane.OK_OPTION).equals(pane.getValue()))
    83                 return;
    84         lastSearch = input.getText();
    85         SearchAction.SearchMode mode = replace.isSelected() ? SearchAction.SearchMode.replace : (add.isSelected() ? SearchAction.SearchMode.add : SearchAction.SearchMode.remove);
    86         search(lastSearch, mode, caseSensitive.isSelected());
     43        if (Main.map == null) {
     44            JOptionPane.showMessageDialog(Main.parent, tr("No data loaded."));
     45            return;
     46        }
     47        SearchSetting s = lastSearch;
     48        if (s == null)
     49            s = new SearchSetting("", false, SearchMode.replace);
     50        showSearchDialog(s);
    8751    }
    8852
    89         public static void search(String search, SearchMode mode, boolean caseSensitive) {
    90         if (search.startsWith("http://") || search.startsWith("ftp://") || search.startsWith("https://") || search.startsWith("file:/")) {
    91                 SelectionWebsiteLoader loader = new SelectionWebsiteLoader(search, mode);
    92                 if (loader.url != null) {
    93                         Main.worker.execute(loader);
    94                         return;
    95                 }
    96         }
    97                 try {
    98                         Collection<OsmPrimitive> sel = Main.ds.getSelected();
    99                         SearchCompiler.Match matcher = SearchCompiler.compile(search, caseSensitive);
    100                         int foundMatches = 0;
    101                         for (OsmPrimitive osm : Main.ds.allNonDeletedCompletePrimitives()) {
    102                                 if (mode == SearchMode.replace)
    103                                 {
    104                                         if (matcher.match(osm))
    105                                         {
    106                                                 sel.add(osm);
    107                                                 ++foundMatches;
    108                                         }
    109                                         else
    110                                                 sel.remove(osm);
    111                                 }
    112                                 else if (mode == SearchMode.add && !osm.selected && matcher.match(osm))
    113                                 {
    114                                         sel.add(osm);
    115                                         ++foundMatches;
    116                                 }
    117                                 else if (mode == SearchMode.remove && osm.selected && matcher.match(osm))
    118                                 {
    119                                         sel.remove(osm);
    120                                         ++foundMatches;
    121                                 }
    122                         }
    123                         Main.ds.setSelected(sel);
    124                         if(foundMatches == 0)
    125                         {
    126                                 String msg = null;
    127                                 if (mode == SearchMode.replace)
    128                                         msg = tr("No match found for ''{0}''", search);
    129                                 else if (mode == SearchMode.add)
    130                                         msg = tr("Nothing added to selection by searching for ''{0}''", search);
    131                                 else if (mode == SearchMode.remove)
    132                                         msg = tr("Nothing removed from selection by searching for ''{0}''", search);
    133                                 Main.map.statusLine.setHelpText(msg);
    134                                 JOptionPane.showMessageDialog(Main.parent, msg);
    135                         }
    136                         else
    137                                 Main.map.statusLine.setHelpText(tr("Found {0} matches", foundMatches));
    138                 } catch (SearchCompiler.ParseError e) {
    139                         JOptionPane.showMessageDialog(Main.parent, e.getMessage());
    140                 }
     53    public void showSearchDialog(SearchSetting initialValues) {
     54        JLabel label = new JLabel(tr("Please enter a search string."));
     55        final JTextField input = new JTextField(initialValues.text);
     56        input.setToolTipText(tr("<html>Fulltext search:<ul>"
     57                + "<li><b>Baker Street</b> - 'Baker' and 'Street' in any key or name.</li>"
     58                + "<li><b>\"Baker Street\"</b> - 'Baker Street' in any key or name.</li>"
     59                + "<li><b>name:Bak</b> - 'Bak' anywhere in the name.</li>"
     60                + "<li><b>-name:Bak</b> - not 'Bak' in the name.</li>"
     61                + "<li><b>foot:</b> - key=foot set to any value.</li>" + "<li>Special targets:</li>"
     62                + "<li><b>type:</b> - type of the object (<b>node</b>, <b>way</b>, <b>relation</b>)</li>"
     63                + "<li><b>user:</b>... - all objects changed by user</li>"
     64                + "<li><b>id:</b>... - object with given ID</li>"
     65                + "<li><b>nodes:</b>... - object with given number of nodes</li>"
     66                + "<li><b>modified</b> - all changed objects</li>"
     67                + "<li><b>incomplete</b> - all incomplete objects</li>"
     68                + "<li>Use <b>|</b> or <b>OR</b> to combine with logical or</li>"
     69                + "<li>Use <b>\"</b> to quote operators (e.g. if key contains :)</li>"
     70                + "<li>Use <b>(</b> and <b>)</b> to group expressions</li>" + "</ul></html>"));
     71
     72        JRadioButton replace = new JRadioButton(tr("replace selection"), initialValues.mode == SearchMode.replace);
     73        JRadioButton add = new JRadioButton(tr("add to selection"), initialValues.mode == SearchMode.add);
     74        JRadioButton remove = new JRadioButton(tr("remove from selection"), initialValues.mode == SearchMode.remove);
     75        ButtonGroup bg = new ButtonGroup();
     76        bg.add(replace);
     77        bg.add(add);
     78        bg.add(remove);
     79
     80        JCheckBox caseSensitive = new JCheckBox(tr("case sensitive"), initialValues.caseSensitive);
     81
     82        JPanel p = new JPanel(new GridBagLayout());
     83        p.add(label, GBC.eop());
     84        p.add(input, GBC.eop().fill(GBC.HORIZONTAL));
     85        p.add(replace, GBC.eol());
     86        p.add(add, GBC.eol());
     87        p.add(remove, GBC.eop());
     88        p.add(caseSensitive, GBC.eol());
     89        JOptionPane pane = new JOptionPane(p, JOptionPane.INFORMATION_MESSAGE, JOptionPane.OK_CANCEL_OPTION, null) {
     90            @Override
     91            public void selectInitialValue() {
     92                input.requestFocusInWindow();
     93                input.selectAll();
     94            }
     95        };
     96        pane.createDialog(Main.parent, tr("Search")).setVisible(true);
     97        if (!Integer.valueOf(JOptionPane.OK_OPTION).equals(pane.getValue()))
     98            return;
     99        // User pressed OK - let's perform the search
     100        SearchMode mode = replace.isSelected() ? SearchAction.SearchMode.replace
     101                : (add.isSelected() ? SearchAction.SearchMode.add : SearchAction.SearchMode.remove);
     102        SearchSetting setting = new SearchSetting(input.getText(), caseSensitive.isSelected(), mode);
     103        searchWithHistory(setting);
     104    }
     105
     106    /**
     107     * Adds the search specified by the settings in <code>s</code> to the
     108     * search history and performs the search.
     109     *
     110     * @param s
     111     */
     112    public static void searchWithHistory(SearchSetting s) {
     113        searchHistory.addFirst(s);
     114        while (searchHistory.size() > SEARCH_HISTORY_SIZE)
     115            searchHistory.removeLast();
     116        lastSearch = s;
     117        search(s.text, s.mode, s.caseSensitive);
     118    }
     119
     120    public static void searchWithoutHistory(SearchSetting s) {
     121        lastSearch = s;
     122        search(s.text, s.mode, s.caseSensitive);
     123    }
     124
     125    public static void search(String search, SearchMode mode, boolean caseSensitive) {
     126        if (search.startsWith("http://") || search.startsWith("ftp://") || search.startsWith("https://")
     127                || search.startsWith("file:/")) {
     128            SelectionWebsiteLoader loader = new SelectionWebsiteLoader(search, mode);
     129            if (loader.url != null) {
     130                Main.worker.execute(loader);
     131                return;
     132            }
     133        }
     134        try {
     135            Collection<OsmPrimitive> sel = Main.ds.getSelected();
     136            SearchCompiler.Match matcher = SearchCompiler.compile(search, caseSensitive);
     137            int foundMatches = 0;
     138            for (OsmPrimitive osm : Main.ds.allNonDeletedCompletePrimitives()) {
     139                if (mode == SearchMode.replace) {
     140                    if (matcher.match(osm)) {
     141                        sel.add(osm);
     142                        ++foundMatches;
     143                    } else
     144                        sel.remove(osm);
     145                } else if (mode == SearchMode.add && !osm.selected && matcher.match(osm)) {
     146                    sel.add(osm);
     147                    ++foundMatches;
     148                } else if (mode == SearchMode.remove && osm.selected && matcher.match(osm)) {
     149                    sel.remove(osm);
     150                    ++foundMatches;
     151                }
     152            }
     153            Main.ds.setSelected(sel);
     154            if (foundMatches == 0) {
     155                String msg = null;
     156                if (mode == SearchMode.replace)
     157                    msg = tr("No match found for ''{0}''", search);
     158                else if (mode == SearchMode.add)
     159                    msg = tr("Nothing added to selection by searching for ''{0}''", search);
     160                else if (mode == SearchMode.remove)
     161                    msg = tr("Nothing removed from selection by searching for ''{0}''", search);
     162                Main.map.statusLine.setHelpText(msg);
     163                JOptionPane.showMessageDialog(Main.parent, msg);
     164            } else
     165                Main.map.statusLine.setHelpText(tr("Found {0} matches", foundMatches));
     166        } catch (SearchCompiler.ParseError e) {
     167            JOptionPane.showMessageDialog(Main.parent, e.getMessage());
     168        }
     169    }
     170
     171    public static class SearchSetting {
     172        String text;
     173        SearchMode mode;
     174        boolean caseSensitive;
     175
     176        public SearchSetting(String text, boolean caseSensitive, SearchMode mode) {
     177            super();
     178            this.caseSensitive = caseSensitive;
     179            this.mode = mode;
     180            this.text = text;
     181        }
     182
     183        @Override
     184        public String toString() {
     185            String cs = caseSensitive ? tr("CI") : tr("CS");
     186            return "\"" + text + "\" (" + cs + ", " + mode + ")";
     187        }
     188
    141189    }
    142190}
  • trunk/src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java

    r758 r967  
    22package org.openstreetmap.josm.gui.dialogs;
    33
     4import static org.openstreetmap.josm.tools.I18n.marktr;
    45import static org.openstreetmap.josm.tools.I18n.tr;
    5 import static org.openstreetmap.josm.tools.I18n.marktr;
    66
    77import java.awt.BorderLayout;
     8import java.awt.Color;
    89import java.awt.GridLayout;
     10import java.awt.Rectangle;
    911import java.awt.event.ActionEvent;
    1012import java.awt.event.ActionListener;
     
    1214import java.awt.event.MouseAdapter;
    1315import java.awt.event.MouseEvent;
    14 import java.util.Arrays;
    1516import java.util.Collection;
    1617import java.util.LinkedList;
    17 
     18import java.util.NoSuchElementException;
     19
     20import javax.swing.BorderFactory;
    1821import javax.swing.DefaultListModel;
    1922import javax.swing.JList;
     23import javax.swing.JMenuItem;
    2024import javax.swing.JPanel;
     25import javax.swing.JPopupMenu;
    2126import javax.swing.JScrollPane;
    2227import javax.swing.ListSelectionModel;
     28import javax.swing.SwingConstants;
     29import javax.swing.plaf.basic.BasicArrowButton;
    2330
    2431import org.openstreetmap.josm.Main;
     32import org.openstreetmap.josm.actions.AutoScaleAction;
     33import org.openstreetmap.josm.actions.search.SearchAction;
     34import org.openstreetmap.josm.actions.search.SearchAction.SearchSetting;
    2535import org.openstreetmap.josm.data.SelectionChangedListener;
    2636import org.openstreetmap.josm.data.osm.DataSet;
     37import org.openstreetmap.josm.data.osm.Node;
    2738import org.openstreetmap.josm.data.osm.OsmPrimitive;
     39import org.openstreetmap.josm.data.osm.Way;
     40import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
    2841import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
    2942import org.openstreetmap.josm.gui.SideButton;
     
    3851public class SelectionListDialog extends ToggleDialog implements SelectionChangedListener {
    3952
    40         /**
    41          * The selection's list data.
    42          */
    43         private final DefaultListModel list = new DefaultListModel();
    44         /**
    45          * The display list.
    46          */
    47         private JList displaylist = new JList(list);
    48 
    49         public SelectionListDialog() {
    50                 super(tr("Current Selection"), "selectionlist", tr("Open a selection list window."), KeyEvent.VK_T, 150);
    51                 displaylist.setCellRenderer(new OsmPrimitivRenderer());
    52                 displaylist.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    53                 displaylist.addMouseListener(new MouseAdapter(){
    54                         @Override public void mouseClicked(MouseEvent e) {
    55                                 if (e.getClickCount() < 2)
    56                                         return;
    57                                 updateMap();
    58                         }
    59                 });
    60 
    61                 add(new JScrollPane(displaylist), BorderLayout.CENTER);
    62 
    63                 JPanel buttonPanel = new JPanel(new GridLayout(1,2));
    64 
    65                 buttonPanel.add(new SideButton(marktr("Select"), "select", "SelectionList",
    66                 tr("Set the selected elements on the map to the selected items in the list above."), new ActionListener(){
    67                         public void actionPerformed(ActionEvent e) {
    68                                 updateMap();
    69                         }
    70                 }));
    71 
    72                 buttonPanel.add(new SideButton(marktr("Reload"), "refresh", "SelectionList", tr("Refresh the selection list."), new ActionListener(){
    73                         public void actionPerformed(ActionEvent e) {
    74                                 selectionChanged(Main.ds.getSelected());
    75             }
    76                 }));
    77 
    78                 buttonPanel.add(new SideButton(marktr("Search"), "search", "SelectionList", tr("Search for objects."), Main.main.menu.search));
    79 
    80                 add(buttonPanel, BorderLayout.SOUTH);
    81                 selectionChanged(Main.ds.getSelected());
    82 
    83                 DataSet.selListeners.add(this);
    84         }
    85 
    86         @Override public void setVisible(boolean b) {
    87                 super.setVisible(b);
    88                 if (b)
    89                         selectionChanged(Main.ds.getSelected());
    90         }
    91 
    92 
    93         /**
    94          * Called when the selection in the dataset changed.
    95          * @param newSelection The new selection array.
    96          */
    97         public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
    98                 if (list == null || !isVisible())
    99                         return; // selection changed may be received in base class constructor before init
    100                 OsmPrimitive selArr[] = Main.ds.sort(newSelection);
    101                 list.setSize(selArr.length);
    102                 int i = 0;
    103                 for (OsmPrimitive osm : selArr)
    104                         list.setElementAt(osm, i++);
    105         }
    106 
    107         /**
    108          * Sets the selection of the map to the current selected items.
    109          */
    110         public void updateMap() {
    111                 Collection<OsmPrimitive> sel = new LinkedList<OsmPrimitive>();
    112                 for (int i = 0; i < list.getSize(); ++i)
    113                         if (displaylist.isSelectedIndex(i))
    114                                 sel.add((OsmPrimitive)list.get(i));
    115                 Main.ds.setSelected(sel);
    116         }
     53    private static final int SELECTION_HISTORY_SIZE = 10;
     54
     55    /**
     56     * The selection's list data.
     57     */
     58    private final DefaultListModel list = new DefaultListModel();
     59
     60    private LinkedList<Collection<? extends OsmPrimitive>> selectionHistory;
     61
     62    /**
     63     * The display list.
     64     */
     65    private JList displaylist = new JList(list);
     66    private SideButton selectButton;
     67    private SideButton searchButton;
     68    private JPopupMenu popupMenu;
     69    private JMenuItem zoomToElement;
     70
     71    /**
     72     * If the selection changed event is triggered with newSelection equals
     73     * this element, the newSelection will not be added to the selection history
     74     */
     75    private Collection<? extends OsmPrimitive> historyIgnoreSelection = null;
     76
     77    public SelectionListDialog() {
     78        super(tr("Current Selection"), "selectionlist", tr("Open a selection list window."), KeyEvent.VK_T, 150);
     79
     80        selectionHistory = new LinkedList<Collection<? extends OsmPrimitive>>();
     81        popupMenu = new JPopupMenu();
     82        displaylist.setCellRenderer(new OsmPrimitivRenderer());
     83        displaylist.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
     84        displaylist.addMouseListener(new MouseAdapter() {
     85            @Override
     86            public void mouseClicked(MouseEvent e) {
     87                if (e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1)
     88                    updateMap();
     89            }
     90
     91            @Override
     92            public void mousePressed(MouseEvent e) {
     93                showPopupMenu(e);
     94            }
     95
     96            @Override
     97            public void mouseReleased(MouseEvent e) {
     98                showPopupMenu(e);
     99            }
     100
     101        });
     102
     103        add(new JScrollPane(displaylist), BorderLayout.CENTER);
     104
     105        JPanel buttonPanel = new JPanel(new GridLayout(1, 2));
     106
     107        selectButton = new SideButton(marktr("Select"), "select", "SelectionList",
     108                tr("Set the selected elements on the map to the selected items in the list above."),
     109                new ActionListener() {
     110                    public void actionPerformed(ActionEvent e) {
     111                        updateMap();
     112                    }
     113                });
     114        buttonPanel.add(selectButton);
     115        BasicArrowButton selectionHistoryMenuButton = createArrowButton(selectButton);
     116        selectionHistoryMenuButton.addActionListener(new ActionListener() {
     117            public void actionPerformed(ActionEvent e) {
     118                showSelectionHistoryMenu();
     119            }
     120        });
     121        add(buttonPanel, BorderLayout.SOUTH);
     122
     123        zoomToElement = new JMenuItem(tr("Zoom to selected element(s)"));
     124        zoomToElement.addActionListener(new ActionListener() {
     125            public void actionPerformed(ActionEvent e) {
     126                zoomToSelectedElement();
     127            }
     128        });
     129
     130        buttonPanel.add(new SideButton(marktr("Reload"), "refresh", "SelectionList", tr("Refresh the selection list."),
     131                new ActionListener() {
     132                    public void actionPerformed(ActionEvent e) {
     133                        selectionChanged(Main.ds.getSelected());
     134                    }
     135                }));
     136
     137        searchButton = new SideButton(marktr("Search"), "search", "SelectionList", tr("Search for objects."),
     138                Main.main.menu.search);
     139        buttonPanel.add(searchButton);
     140
     141        BasicArrowButton searchHistoryMenuButton = createArrowButton(searchButton);
     142        searchHistoryMenuButton.addActionListener(new ActionListener() {
     143            public void actionPerformed(ActionEvent e) {
     144                showSearchHistoryMenu();
     145            }
     146        });
     147
     148        popupMenu.add(zoomToElement);
     149        JMenuItem zoomToSelection = new JMenuItem(tr("Zoom to selection"));
     150        zoomToSelection.addActionListener(new ActionListener() {
     151            public void actionPerformed(ActionEvent e) {
     152                zoomToSelection();
     153            }
     154        });
     155        popupMenu.add(zoomToSelection);
     156
     157        selectionChanged(Main.ds.getSelected());
     158
     159        DataSet.selListeners.add(this);
     160    }
     161
     162    private BasicArrowButton createArrowButton(SideButton parentButton) {
     163        BasicArrowButton arrowButton = new BasicArrowButton(SwingConstants.SOUTH, null, null, Color.BLACK, null);
     164        arrowButton.setBorder(BorderFactory.createEmptyBorder());
     165        //        selectionHistoryMenuButton.setContentAreaFilled(false);
     166        //        selectionHistoryMenuButton.setOpaque(false);
     167        //        selectionHistoryMenuButton.setBorderPainted(false);
     168        //        selectionHistoryMenuButton.setBackground(null);
     169        parentButton.setLayout(new BorderLayout());
     170        parentButton.add(arrowButton, BorderLayout.EAST);
     171        return arrowButton;
     172    }
     173
     174    @Override
     175    public void setVisible(boolean b) {
     176        super.setVisible(b);
     177        if (b)
     178            selectionChanged(Main.ds.getSelected());
     179    }
     180
     181    protected void showPopupMenu(MouseEvent e) {
     182        if (e.isPopupTrigger()) {
     183            zoomToElement.setVisible(displaylist.getSelectedIndex() >= 0);
     184            popupMenu.show(e.getComponent(), e.getX(), e.getY());
     185        }
     186    }
     187
     188    public void zoomToSelection() {
     189        new AutoScaleAction("selection").actionPerformed(null);
     190    }
     191
     192    /**
     193     * Zooms to the element(s) selected in {@link #displaylist}
     194     */
     195    public void zoomToSelectedElement() {
     196        BoundingXYVisitor box = new BoundingXYVisitor();
     197        int[] selected = displaylist.getSelectedIndices();
     198        if (selected.length == 0)
     199            return;
     200        for (int i = 0; i < selected.length; i++) {
     201            Object o = list.get(selected[i]);
     202            if (o instanceof OsmPrimitive)
     203                ((OsmPrimitive) o).visit(box);
     204        }
     205        if (box.max == null || box.min == null)
     206            return;
     207        box.enlargeBoundingBox();
     208        Main.map.mapView.recalculateCenterScale(box);
     209    }
     210
     211    private void showSelectionHistoryMenu() {
     212        if (selectionHistory.size() == 0)
     213            return;
     214        JPopupMenu historyMenu = new JPopupMenu();
     215        for (Collection<? extends OsmPrimitive> sel : selectionHistory) {
     216            SelectionMenuItem item = new SelectionMenuItem(sel);
     217            historyMenu.add(item);
     218        }
     219        Rectangle r = selectButton.getBounds();
     220        historyMenu.show(selectButton, r.x, r.y + r.height);
     221    }
     222
     223    private void showSearchHistoryMenu() {
     224        if (SearchAction.searchHistory.size() == 0)
     225            return;
     226        JPopupMenu historyMenu = new JPopupMenu();
     227        for (SearchAction.SearchSetting s : SearchAction.searchHistory) {
     228            SearchMenuItem item = new SearchMenuItem(s);
     229            historyMenu.add(item);
     230        }
     231        Rectangle r = searchButton.getBounds();
     232        historyMenu.show(searchButton, r.x, r.y + r.height);
     233    }
     234
     235    /**
     236     * Called when the selection in the dataset changed.
     237     * @param newSelection The new selection array.
     238     */
     239    public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
     240        if (list == null || !isVisible())
     241            return; // selection changed may be received in base class constructor before init
     242        OsmPrimitive selArr[] = DataSet.sort(newSelection);
     243        list.setSize(selArr.length);
     244        int i = 0;
     245        for (OsmPrimitive osm : selArr)
     246            list.setElementAt(osm, i++);
     247        if (selectionHistory != null && newSelection.size() > 0 && !newSelection.equals(historyIgnoreSelection)) {
     248            historyIgnoreSelection = null;
     249            try {
     250                // Check if the newSelection has already been added to the history
     251                Collection<? extends OsmPrimitive> first = selectionHistory.getFirst();
     252                if (first.equals(newSelection))
     253                    return;
     254            } catch (NoSuchElementException e) {
     255            }
     256            selectionHistory.addFirst(newSelection);
     257            while (selectionHistory.size() > SELECTION_HISTORY_SIZE)
     258                selectionHistory.removeLast();
     259        }
     260    }
     261
     262    /**
     263     * Sets the selection of the map to the current selected items.
     264     */
     265    public void updateMap() {
     266        Collection<OsmPrimitive> sel = new LinkedList<OsmPrimitive>();
     267        for (int i = 0; i < list.getSize(); ++i)
     268            if (displaylist.isSelectedIndex(i))
     269                sel.add((OsmPrimitive) list.get(i));
     270        Main.ds.setSelected(sel);
     271    }
     272
     273    /**
     274     * A specialized {@link JMenuItem} for presenting one entry of the selection history
     275     *   
     276     * @author Jan Peter Stotz
     277     */
     278    protected class SelectionMenuItem extends JMenuItem implements ActionListener {
     279        protected Collection<? extends OsmPrimitive> sel;
     280
     281        public SelectionMenuItem(Collection<? extends OsmPrimitive> sel) {
     282            super();
     283            this.sel = sel;
     284            int ways = 0;
     285            int nodes = 0;
     286            for (OsmPrimitive o : sel) {
     287                if (o instanceof Way)
     288                    ways++;
     289                else if (o instanceof Node)
     290                    nodes++;
     291            }
     292            setText(String.format(tr("Selection: %d way(s) and %d node(s)"), new Object[] { ways, nodes }));
     293            addActionListener(this);
     294        }
     295
     296        public void actionPerformed(ActionEvent e) {
     297            historyIgnoreSelection = sel;
     298            Main.ds.setSelected(sel);
     299        }
     300
     301    }
     302
     303    /**
     304     * A specialized {@link JMenuItem} for presenting one entry of the search history
     305     *   
     306     * @author Jan Peter Stotz
     307     */
     308    protected class SearchMenuItem extends JMenuItem implements ActionListener {
     309        protected SearchSetting s;
     310
     311        public SearchMenuItem(SearchSetting s) {
     312            super(s.toString());
     313            this.s = s;
     314            addActionListener(this);
     315        }
     316
     317        public void actionPerformed(ActionEvent e) {
     318            SearchAction.searchWithoutHistory(s);
     319        }
     320
     321    }
    117322}
Note: See TracChangeset for help on using the changeset viewer.