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

Last change on this file since 32395 was 32395, checked in by donvip, 9 years ago

checkstyle, update to JOSM 10279

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