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

Last change on this file since 36102 was 36102, checked in by taylor.smock, 2 years ago

reltoolbox: Clean up a bunch of lint warnings

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