source: josm/trunk/src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java@ 1722

Last change on this file since 1722 was 1722, checked in by stoecker, 15 years ago

Large rework in projection handling - now allows only switching and more specific projections
TODO:

  • allow subprojections (i.e. settings for projections)
  • setup preferences for subprojections
  • better support of the new projection depending world bounds (how to handle valid data outside of world)
  • do not allow to zoom out of the world - zoom should stop when whole world is displayed
  • fix Lambert and SwissGrid to handle new OutOfWorld style and subprojections
  • fix new UTM projection
  • handle layers with fixed projection on projection change
  • allow easier projection switching (e.g. in menu)

NOTE:
This checkin very likely will cause problems. Please report or fix them. Older plugins may have trouble. The SVN plugins
have been fixed but may have problems nevertheless. This is a BIG change, but will make JOSMs internal structure much cleaner
and reduce lots of projection related problems.

  • Property svn:eol-style set to native
File size: 12.9 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.gui.dialogs;
3
4import static org.openstreetmap.josm.tools.I18n.marktr;
5import static org.openstreetmap.josm.tools.I18n.tr;
6import static org.openstreetmap.josm.tools.I18n.trn;
7
8import java.awt.BorderLayout;
9import java.awt.Color;
10import java.awt.GridLayout;
11import java.awt.Rectangle;
12import java.awt.event.ActionEvent;
13import java.awt.event.ActionListener;
14import java.awt.event.KeyEvent;
15import java.awt.event.MouseAdapter;
16import java.awt.event.MouseEvent;
17import java.util.Collection;
18import java.util.LinkedList;
19import java.util.NoSuchElementException;
20
21import javax.swing.BorderFactory;
22import javax.swing.DefaultListModel;
23import javax.swing.JList;
24import javax.swing.JMenuItem;
25import javax.swing.JPanel;
26import javax.swing.JPopupMenu;
27import javax.swing.JScrollPane;
28import javax.swing.ListSelectionModel;
29import javax.swing.SwingConstants;
30import javax.swing.plaf.basic.BasicArrowButton;
31
32import org.openstreetmap.josm.Main;
33import org.openstreetmap.josm.actions.AutoScaleAction;
34import org.openstreetmap.josm.actions.search.SearchAction;
35import org.openstreetmap.josm.actions.search.SearchAction.SearchSetting;
36import org.openstreetmap.josm.data.SelectionChangedListener;
37import org.openstreetmap.josm.data.osm.DataSet;
38import org.openstreetmap.josm.data.osm.Node;
39import org.openstreetmap.josm.data.osm.OsmPrimitive;
40import org.openstreetmap.josm.data.osm.Relation;
41import org.openstreetmap.josm.data.osm.Way;
42import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
43import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
44import org.openstreetmap.josm.gui.SideButton;
45import org.openstreetmap.josm.tools.Shortcut;
46
47/**
48 * A small tool dialog for displaying the current selection. The selection manager
49 * respects clicks into the selection list. Ctrl-click will remove entries from
50 * the list while single click will make the clicked entry the only selection.
51 *
52 * @author imi
53 */
54public class SelectionListDialog extends ToggleDialog implements SelectionChangedListener {
55
56 private static final int SELECTION_HISTORY_SIZE = 10;
57
58 /**
59 * The selection's list data.
60 */
61 private final DefaultListModel list = new DefaultListModel();
62
63 private LinkedList<Collection<? extends OsmPrimitive>> selectionHistory;
64
65 /**
66 * The display list.
67 */
68 private JList displaylist = new JList(list);
69 private SideButton selectButton;
70 private SideButton searchButton;
71 private JPopupMenu popupMenu;
72 private JMenuItem zoomToElement;
73
74 /**
75 * If the selection changed event is triggered with newSelection equals
76 * this element, the newSelection will not be added to the selection history
77 */
78 private Collection<? extends OsmPrimitive> historyIgnoreSelection = null;
79
80 public SelectionListDialog() {
81 super(tr("Current Selection"), "selectionlist", tr("Open a selection list window."),
82 Shortcut.registerShortcut("subwindow:selection", tr("Toggle: {0}", tr("Current Selection")), KeyEvent.VK_T, Shortcut.GROUP_LAYER, Shortcut.SHIFT_DEFAULT), 150);
83
84 selectionHistory = new LinkedList<Collection<? extends OsmPrimitive>>();
85 popupMenu = new JPopupMenu();
86 displaylist.setCellRenderer(new OsmPrimitivRenderer());
87 displaylist.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
88 displaylist.addMouseListener(new MouseAdapter() {
89 @Override
90 public void mouseClicked(MouseEvent e) {
91 if (e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1)
92 updateMap();
93 }
94
95 @Override
96 public void mousePressed(MouseEvent e) {
97 showPopupMenu(e);
98 }
99
100 @Override
101 public void mouseReleased(MouseEvent e) {
102 showPopupMenu(e);
103 }
104
105 });
106
107 add(new JScrollPane(displaylist), BorderLayout.CENTER);
108
109 JPanel buttonPanel = new JPanel(new GridLayout(1, 2));
110
111 selectButton = new SideButton(marktr("Select"), "select", "SelectionList",
112 tr("Set the selected elements on the map to the selected items in the list above."),
113 new ActionListener() {
114 public void actionPerformed(ActionEvent e) {
115 updateMap();
116 }
117 });
118 buttonPanel.add(selectButton);
119 BasicArrowButton selectionHistoryMenuButton = createArrowButton(selectButton);
120 selectionHistoryMenuButton.addActionListener(new ActionListener() {
121 public void actionPerformed(ActionEvent e) {
122 showSelectionHistoryMenu();
123 }
124 });
125 add(buttonPanel, BorderLayout.SOUTH);
126
127 zoomToElement = new JMenuItem(tr("Zoom to selected element(s)"));
128 zoomToElement.addActionListener(new ActionListener() {
129 public void actionPerformed(ActionEvent e) {
130 zoomToSelectedElement();
131 }
132 });
133
134 buttonPanel.add(new SideButton(marktr("Reload"), "refresh", "SelectionList", tr("Refresh the selection list."),
135 new ActionListener() {
136 public void actionPerformed(ActionEvent e) {
137 selectionChanged(Main.ds.getSelected());
138 }
139 }));
140
141 searchButton = new SideButton(marktr("Search"), "search", "SelectionList", tr("Search for objects."),
142 Main.main.menu.search);
143 buttonPanel.add(searchButton);
144
145 BasicArrowButton searchHistoryMenuButton = createArrowButton(searchButton);
146 searchHistoryMenuButton.addActionListener(new ActionListener() {
147 public void actionPerformed(ActionEvent e) {
148 showSearchHistoryMenu();
149 }
150 });
151
152 popupMenu.add(zoomToElement);
153 JMenuItem zoomToSelection = new JMenuItem(tr("Zoom to selection"));
154 zoomToSelection.addActionListener(new ActionListener() {
155 public void actionPerformed(ActionEvent e) {
156 zoomToSelection();
157 }
158 });
159 popupMenu.add(zoomToSelection);
160
161 selectionChanged(Main.ds.getSelected());
162
163 DataSet.selListeners.add(this);
164 }
165
166 private BasicArrowButton createArrowButton(SideButton parentButton) {
167 BasicArrowButton arrowButton = new BasicArrowButton(SwingConstants.SOUTH, null, null, Color.BLACK, null);
168 arrowButton.setBorder(BorderFactory.createEmptyBorder());
169 // selectionHistoryMenuButton.setContentAreaFilled(false);
170 // selectionHistoryMenuButton.setOpaque(false);
171 // selectionHistoryMenuButton.setBorderPainted(false);
172 // selectionHistoryMenuButton.setBackground(null);
173 parentButton.setLayout(new BorderLayout());
174 parentButton.add(arrowButton, BorderLayout.EAST);
175 return arrowButton;
176 }
177
178 @Override
179 public void setVisible(boolean b) {
180 super.setVisible(b);
181 if (b)
182 selectionChanged(Main.ds.getSelected());
183 }
184
185 protected void showPopupMenu(MouseEvent e) {
186 if (e.isPopupTrigger()) {
187 zoomToElement.setVisible(displaylist.getSelectedIndex() >= 0);
188 popupMenu.show(e.getComponent(), e.getX(), e.getY());
189 }
190 }
191
192 public void zoomToSelection() {
193 new AutoScaleAction("selection").actionPerformed(null);
194 }
195
196 /**
197 * Zooms to the element(s) selected in {@link #displaylist}
198 */
199 public void zoomToSelectedElement() {
200 BoundingXYVisitor box = new BoundingXYVisitor();
201 int[] selected = displaylist.getSelectedIndices();
202 if (selected.length == 0)
203 return;
204 for (int i = 0; i < selected.length; i++) {
205 Object o = list.get(selected[i]);
206 if (o instanceof OsmPrimitive)
207 ((OsmPrimitive) o).visit(box);
208 }
209 if (box.getBounds() == null)
210 return;
211 box.enlargeBoundingBox();
212 Main.map.mapView.recalculateCenterScale(box);
213 }
214
215 private void showSelectionHistoryMenu() {
216 if (selectionHistory.size() == 0)
217 return;
218 JPopupMenu historyMenu = new JPopupMenu();
219 for (Collection<? extends OsmPrimitive> sel : selectionHistory) {
220 SelectionMenuItem item = new SelectionMenuItem(sel);
221 historyMenu.add(item);
222 }
223 Rectangle r = selectButton.getBounds();
224 historyMenu.show(selectButton, r.x, r.y + r.height);
225 }
226
227 private void showSearchHistoryMenu() {
228 if (SearchAction.searchHistory.size() == 0)
229 return;
230 JPopupMenu historyMenu = new JPopupMenu();
231 for (SearchAction.SearchSetting s : SearchAction.searchHistory) {
232 SearchMenuItem item = new SearchMenuItem(s);
233 historyMenu.add(item);
234 }
235 Rectangle r = searchButton.getBounds();
236 historyMenu.show(searchButton, r.x, r.y + r.height);
237 }
238
239 /**
240 * Called when the selection in the dataset changed.
241 * @param newSelection The new selection array.
242 */
243 public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
244 if (list == null || !isVisible())
245 return; // selection changed may be received in base class constructor before init
246 OsmPrimitive selArr[] = DataSet.sort(newSelection);
247 list.setSize(selArr.length);
248 int i = 0;
249 for (OsmPrimitive osm : selArr)
250 list.setElementAt(osm, i++);
251 if (selectionHistory != null && newSelection.size() > 0 && !newSelection.equals(historyIgnoreSelection)) {
252 historyIgnoreSelection = null;
253 try {
254 // Check if the newSelection has already been added to the history
255 Collection<? extends OsmPrimitive> first = selectionHistory.getFirst();
256 if (first.equals(newSelection))
257 return;
258 } catch (NoSuchElementException e) {
259 }
260 selectionHistory.addFirst(newSelection);
261 while (selectionHistory.size() > SELECTION_HISTORY_SIZE)
262 selectionHistory.removeLast();
263 }
264
265 int ways = 0;
266 int nodes = 0;
267 int relations = 0;
268 for (OsmPrimitive o : newSelection) {
269 if (o instanceof Way)
270 ways++;
271 else if (o instanceof Node)
272 nodes++;
273 else if (o instanceof Relation)
274 relations++;
275 }
276
277 if( (nodes+ways+relations) != 0) {
278 setTitle(tr("Sel.: Rel.:{0} / Ways:{1} / Nodes:{2}", relations, ways, nodes), true);
279 } else {
280 setTitle(tr("Selection"), false);
281 }
282 }
283
284 /**
285 * Sets the selection of the map to the current selected items.
286 */
287 public void updateMap() {
288 Collection<OsmPrimitive> sel = new LinkedList<OsmPrimitive>();
289 for (int i = 0; i < list.getSize(); ++i)
290 if (displaylist.isSelectedIndex(i))
291 sel.add((OsmPrimitive) list.get(i));
292 Main.ds.setSelected(sel);
293 }
294
295 /**
296 * A specialized {@link JMenuItem} for presenting one entry of the selection history
297 *
298 * @author Jan Peter Stotz
299 */
300 protected class SelectionMenuItem extends JMenuItem implements ActionListener {
301 protected Collection<? extends OsmPrimitive> sel;
302
303 public SelectionMenuItem(Collection<? extends OsmPrimitive> sel) {
304 super();
305 this.sel = sel;
306 int ways = 0;
307 int nodes = 0;
308 int relations = 0;
309 for (OsmPrimitive o : sel) {
310 if (o instanceof Way)
311 ways++;
312 else if (o instanceof Node)
313 nodes++;
314 else if (o instanceof Relation)
315 relations++;
316 }
317 String text = "";
318 if(ways != 0)
319 text += (text.length() > 0 ? ", " : "")
320 + trn("{0} way", "{0} ways", ways, ways);
321 if(nodes != 0)
322 text += (text.length() > 0 ? ", " : "")
323 + trn("{0} node", "{0} nodes", nodes, nodes);
324 if(relations != 0)
325 text += (text.length() > 0 ? ", " : "")
326 + trn("{0} relation", "{0} relations", relations, relations);
327 setText(tr("Selection: {0}", text));
328 addActionListener(this);
329 }
330
331 public void actionPerformed(ActionEvent e) {
332 historyIgnoreSelection = sel;
333 Main.ds.setSelected(sel);
334 }
335
336 }
337
338 /**
339 * A specialized {@link JMenuItem} for presenting one entry of the search history
340 *
341 * @author Jan Peter Stotz
342 */
343 protected class SearchMenuItem extends JMenuItem implements ActionListener {
344 protected SearchSetting s;
345
346 public SearchMenuItem(SearchSetting s) {
347 super(s.toString());
348 this.s = s;
349 addActionListener(this);
350 }
351
352 public void actionPerformed(ActionEvent e) {
353 SearchAction.searchWithoutHistory(s);
354 }
355
356 }
357}
Note: See TracBrowser for help on using the repository browser.