source: osm/applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/FindRelationAction.java@ 28857

Last change on this file since 28857 was 28857, checked in by larry0ua, 12 years ago

'RelToolbox: make natural sort for relation and find relation lists'

File size: 8.4 KB
Line 
1package relcontext.actions;
2
3import java.awt.BorderLayout;
4import java.awt.Dialog.ModalityType;
5import java.awt.Dimension;
6import java.awt.event.*;
7import static org.openstreetmap.josm.tools.I18n.tr;
8import java.util.*;
9import java.util.ArrayList;
10import javax.swing.*;
11import org.openstreetmap.josm.Main;
12import org.openstreetmap.josm.actions.JosmAction;
13import org.openstreetmap.josm.data.osm.Relation;
14import org.openstreetmap.josm.gui.DefaultNameFormatter;
15import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
16import org.openstreetmap.josm.tools.Shortcut;
17import relcontext.ChosenRelation;
18
19/**
20 * Opens a list of all relations with keyword search field. Choose selected relation.
21 *
22 * @author Zverik
23 */
24public class FindRelationAction extends JosmAction {
25 protected ChosenRelation chRel;
26
27 public FindRelationAction( ChosenRelation chRel ) {
28 super(tr("Find"), "relcontext/find", tr("Find a relation"),
29 Shortcut.registerShortcut("reltoolbox:find", tr("Relation Toolbox: {0}", tr("Find a relation")),
30 KeyEvent.VK_F, Shortcut.ALT_CTRL), false);
31 this.chRel = chRel;
32 }
33
34 public void actionPerformed( ActionEvent e ) {
35 JPanel panel = new JPanel(new BorderLayout());
36 final JTextField searchField = new JTextField();
37 panel.add(searchField, BorderLayout.NORTH);
38 final FindRelationListModel relationsData = new FindRelationListModel();
39 final JList relationsList = new JList(relationsData);
40 relationsList.setSelectionModel(relationsData.getSelectionModel());
41 relationsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
42 relationsList.setCellRenderer(new OsmPrimitivRenderer());
43 panel.add(new JScrollPane(relationsList, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER), BorderLayout.CENTER);
44 panel.setPreferredSize(new Dimension(400, 400));
45
46 final JOptionPane optionPane = new JOptionPane(panel, JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION) {
47 @Override
48 public void selectInitialValue() {
49 searchField.requestFocusInWindow();
50 }
51 };
52 final JDialog dlg = optionPane.createDialog(Main.parent, tr("Find a relation"));
53 dlg.setModalityType(ModalityType.DOCUMENT_MODAL);
54
55 relationsList.addMouseListener(new MouseAdapter() {
56 @Override
57 public void mouseClicked( MouseEvent e ) {
58 if( e.getClickCount() >= 2 && !relationsList.isSelectionEmpty() ) {
59 dlg.setVisible(false);
60 optionPane.setValue(JOptionPane.OK_OPTION);
61 }
62 }
63 });
64
65 searchField.addActionListener(new ActionListener() {
66 public void actionPerformed( ActionEvent e ) {
67 if( !relationsList.isSelectionEmpty() ) {
68 dlg.setVisible(false);
69 optionPane.setValue(JOptionPane.OK_OPTION);
70 }
71 }
72 });
73
74 searchField.addKeyListener(new KeyAdapter() {
75 @Override
76 public void keyTyped( KeyEvent e ) {
77 SwingUtilities.invokeLater(new Runnable() {
78 public void run() {
79 updateRelationData(relationsData, searchField.getText());
80 }
81 });
82 }
83
84 @Override
85 public void keyPressed( KeyEvent e ) {
86 if( shouldForward(e) )
87 relationsList.dispatchEvent(e);
88 }
89
90 @Override
91 public void keyReleased( KeyEvent e ) {
92 if( shouldForward(e) )
93 relationsList.dispatchEvent(e);
94 }
95
96 private boolean shouldForward( KeyEvent e ) {
97 return e.getKeyCode() == KeyEvent.VK_UP || e.getKeyCode() == KeyEvent.VK_DOWN
98 || e.getKeyCode() == KeyEvent.VK_PAGE_DOWN || e.getKeyCode() == KeyEvent.VK_PAGE_UP
99 || e.getKeyCode() == KeyEvent.VK_HOME || e.getKeyCode() == KeyEvent.VK_END;
100 }
101 });
102
103 updateRelationData(relationsData, null);
104 dlg.setVisible(true);
105
106 Object answer = optionPane.getValue();
107 if( answer == null || answer == JOptionPane.UNINITIALIZED_VALUE
108 || (answer instanceof Integer && (Integer)answer != JOptionPane.OK_OPTION) ) {
109 return;
110 }
111
112 Relation r = (Relation)relationsList.getSelectedValue();
113 if( r != null )
114 chRel.set(r);
115 }
116
117 @Override
118 protected void updateEnabledState() {
119 setEnabled(getCurrentDataSet() != null);
120 }
121
122 protected void updateRelationData( FindRelationListModel data, String filter ) {
123 String[] keywords = filter == null ? new String[0] : filter.split("\\s+");
124 if( keywords.length > 0 ) {
125 List<String> filteredKeywords = new ArrayList<String>(keywords.length);
126 for( String s : keywords )
127 if( s.length() > 0 )
128 filteredKeywords.add(s.trim().toLowerCase());
129 keywords = filteredKeywords.toArray(new String[0]);
130 }
131
132 System.out.println("keywords.length = " + keywords.length);
133 for( int i = 0; i < keywords.length; i++ )
134 System.out.println("keyword["+i+"] = " + keywords[i]);
135
136 List<Relation> relations = new ArrayList<Relation>();
137 if( getEditLayer() != null ) {
138 for( Relation r : getEditLayer().data.getRelations() ) {
139 if( !r.isDeleted() && r.isVisible() && !r.isIncomplete() ) {
140 boolean add = true;
141 for( int i = 0; i < keywords.length && add; i++ ) {
142 boolean ok = false;
143 if( String.valueOf(r.getPrimitiveId().getUniqueId()).contains(keywords[i]) )
144 ok = true;
145 else {
146 for( String key : r.keySet() ) {
147 if( key.contains(keywords[i]) || r.get(key).toLowerCase().contains(keywords[i])
148 || tr(r.get(key)).toLowerCase().contains(keywords[i]) ) {
149 ok = true;
150 break;
151 }
152 }
153 }
154 if( !ok ) add = false;
155 }
156 if( add )
157 relations.add(r);
158 }
159 }
160 }
161
162 Collections.sort(relations, DefaultNameFormatter.getInstance().getRelationComparator());
163 data.setRelations(relations);
164 }
165
166 /**
167 * I admit, some of it was copypasted from {@link org.openstreetmap.josm.gui.dialogs.RelationListDialog.RelationListModel}.
168 */
169 protected class FindRelationListModel extends AbstractListModel {
170 private final ArrayList<Relation> relations = new ArrayList<Relation>();
171 private DefaultListSelectionModel selectionModel;
172
173 public FindRelationListModel( DefaultListSelectionModel selectionModel ) {
174 super();
175 this.selectionModel = selectionModel;
176 }
177
178 public FindRelationListModel() {
179 this(new DefaultListSelectionModel());
180 }
181
182 public DefaultListSelectionModel getSelectionModel() {
183 return selectionModel;
184 }
185
186 public Relation getRelation( int idx ) {
187 return relations.get(idx);
188 }
189
190 public int getSize() {
191 return relations.size();
192 }
193
194 public Object getElementAt( int index ) {
195 return getRelation(index);
196 }
197
198 public void setRelations(Collection<Relation> relations) {
199 int selectedIndex = selectionModel.getMinSelectionIndex();
200 Relation sel = selectedIndex < 0 ? null : getRelation(selectedIndex);
201
202 this.relations.clear();
203 selectionModel.clearSelection();
204 if( relations != null )
205 this.relations.addAll(relations);
206 fireIntervalAdded(this, 0, getSize());
207
208 if( sel != null ) {
209 selectedIndex = this.relations.indexOf(sel);
210 if( selectedIndex >= 0 )
211 selectionModel.addSelectionInterval(selectedIndex, selectedIndex);
212 }
213 if( selectionModel.isSelectionEmpty() && !this.relations.isEmpty() )
214 selectionModel.addSelectionInterval(0, 0);
215 }
216 }
217}
Note: See TracBrowser for help on using the repository browser.