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

Last change on this file since 26837 was 25727, checked in by zverik, 15 years ago

replaced some shortcuts, added ones for create relation and multipolygon (reltoolbox plugin)

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.GROUP_HOTKEY), true);
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.