Changeset 967 in josm


Ignore:
Timestamp:
Sep 14, 2008 5:02:09 PM (5 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.