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

Last change on this file since 27927 was 27927, checked in by akks, 13 years ago

reltoolbox, turnlanes: fix shortcut and toolbar warnings

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