source: josm/trunk/src/org/openstreetmap/josm/gui/dialogs/OsmIdSelectionDialog.java@ 8308

Last change on this file since 8308 was 8308, checked in by Don-vip, 9 years ago

fix potential NPEs and Sonar issues related to serialization

  • Property svn:eol-style set to native
File size: 10.3 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.dialogs;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5import static org.openstreetmap.josm.tools.I18n.trc;
6
7import java.awt.Component;
8import java.awt.Dimension;
9import java.awt.event.ItemEvent;
10import java.awt.event.ItemListener;
11import java.awt.event.KeyEvent;
12import java.awt.event.WindowEvent;
13import java.awt.event.WindowListener;
14import java.util.Arrays;
15import java.util.Collection;
16import java.util.Collections;
17import java.util.HashSet;
18import java.util.LinkedList;
19import java.util.List;
20import java.util.Set;
21
22import javax.swing.BorderFactory;
23import javax.swing.GroupLayout;
24import javax.swing.JLabel;
25import javax.swing.JOptionPane;
26import javax.swing.JPanel;
27import javax.swing.KeyStroke;
28import javax.swing.border.EtchedBorder;
29import javax.swing.plaf.basic.BasicComboBoxEditor;
30
31import org.openstreetmap.josm.Main;
32import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
33import org.openstreetmap.josm.data.osm.PrimitiveId;
34import org.openstreetmap.josm.data.osm.SimplePrimitiveId;
35import org.openstreetmap.josm.gui.ExtendedDialog;
36import org.openstreetmap.josm.gui.widgets.HistoryComboBox;
37import org.openstreetmap.josm.gui.widgets.HtmlPanel;
38import org.openstreetmap.josm.gui.widgets.JosmTextField;
39import org.openstreetmap.josm.gui.widgets.OsmIdTextField;
40import org.openstreetmap.josm.gui.widgets.OsmPrimitiveTypesComboBox;
41import org.openstreetmap.josm.tools.Utils;
42
43/**
44 * Dialog prompt to user to let him choose OSM primitives by specifying their type and IDs.
45 * @since 6448, split from DownloadObjectDialog
46 */
47public class OsmIdSelectionDialog extends ExtendedDialog implements WindowListener {
48
49 protected final JPanel panel = new JPanel();
50 protected final OsmPrimitiveTypesComboBox cbType = new OsmPrimitiveTypesComboBox();
51 protected final OsmIdTextField tfId = new OsmIdTextField();
52 protected final HistoryComboBox cbId = new HistoryComboBox();
53 protected final transient GroupLayout layout = new GroupLayout(panel);
54
55 public OsmIdSelectionDialog(Component parent, String title, String[] buttonTexts) {
56 super(parent, title, buttonTexts);
57 }
58
59 public OsmIdSelectionDialog(Component parent, String title, String[] buttonTexts, boolean modal) {
60 super(parent, title, buttonTexts, modal);
61 }
62
63 public OsmIdSelectionDialog(Component parent, String title, String[] buttonTexts, boolean modal, boolean disposeOnClose) {
64 super(parent, title, buttonTexts, modal, disposeOnClose);
65 }
66
67 protected void init() {
68 panel.setLayout(layout);
69 layout.setAutoCreateGaps(true);
70 layout.setAutoCreateContainerGaps(true);
71
72 JLabel lbl1 = new JLabel(tr("Object type:"));
73
74 cbType.addItem(trc("osm object types", "mixed"));
75 cbType.setToolTipText(tr("Choose the OSM object type"));
76 JLabel lbl2 = new JLabel(tr("Object ID:"));
77
78 cbId.setEditor(new BasicComboBoxEditor() {
79 @Override
80 protected JosmTextField createEditorComponent() {
81 return tfId;
82 }
83 });
84 cbId.setToolTipText(tr("Enter the ID of the object that should be downloaded"));
85 restorePrimitivesHistory(cbId);
86
87 // forward the enter key stroke to the download button
88 tfId.getKeymap().removeKeyStrokeBinding(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, false));
89 tfId.setPreferredSize(new Dimension(400, tfId.getPreferredSize().height));
90
91 HtmlPanel help = new HtmlPanel(/* I18n: {0} and {1} contains example strings not meant for translation. {2}=n, {3}=w, {4}=r. */
92 tr("Object IDs can be separated by comma or space.<br/>"
93 + "Examples: {0}<br/>"
94 + "In mixed mode, specify objects like this: {1}<br/>"
95 + "({2} stands for <i>node</i>, {3} for <i>way</i>, and {4} for <i>relation</i>)",
96 "<b>" + Utils.joinAsHtmlUnorderedList(Arrays.asList("1 2 5", "1,2,5")) + "</b>",
97 "<b>w123, n110, w12, r15</b>",
98 "<b>n</b>", "<b>w</b>", "<b>r</b>"
99 ));
100 help.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
101
102 cbType.addItemListener(new ItemListener() {
103 @Override
104 public void itemStateChanged(ItemEvent e) {
105 tfId.setType(cbType.getType());
106 tfId.performValidation();
107 }
108 });
109
110 final GroupLayout.SequentialGroup sequentialGroup = layout.createSequentialGroup()
111 .addGroup(layout.createParallelGroup()
112 .addComponent(lbl1)
113 .addComponent(cbType, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE))
114 .addGroup(layout.createParallelGroup()
115 .addComponent(lbl2)
116 .addComponent(cbId, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE));
117
118 final GroupLayout.ParallelGroup parallelGroup = layout.createParallelGroup()
119 .addGroup(layout.createSequentialGroup()
120 .addGroup(layout.createParallelGroup()
121 .addComponent(lbl1)
122 .addComponent(lbl2)
123 )
124 .addGroup(layout.createParallelGroup()
125 .addComponent(cbType)
126 .addComponent(cbId))
127 );
128
129 for (Component i : getComponentsBeforeHelp()) {
130 sequentialGroup.addComponent(i);
131 parallelGroup.addComponent(i);
132 }
133
134 layout.setVerticalGroup(sequentialGroup.addComponent(help));
135 layout.setHorizontalGroup(parallelGroup.addComponent(help));
136 }
137
138 /**
139 * Let subclasses add custom components between the id input field and the help text
140 * @return the collections to add
141 */
142 protected Collection<Component> getComponentsBeforeHelp() {
143 return Collections.emptySet();
144 }
145
146 /**
147 * Allows subclasses to specify a different continue button index. If this button is pressed, the history is updated.
148 * @return the button index
149 */
150 public int getContinueButtonIndex() {
151 return 1;
152 }
153
154 /**
155 * Restore the current history from the preferences
156 *
157 * @param cbHistory the {@link HistoryComboBox} to which the history is restored to
158 */
159 protected void restorePrimitivesHistory(HistoryComboBox cbHistory) {
160 java.util.List<String> cmtHistory = new LinkedList<>(Main.pref.getCollection(getClass().getName() + ".primitivesHistory", new LinkedList<String>()));
161 // we have to reverse the history, because ComboBoxHistory will reverse it again in addElement()
162 Collections.reverse(cmtHistory);
163 cbHistory.setPossibleItems(cmtHistory);
164 }
165
166 /**
167 * Remind the current history in the preferences
168 *
169 * @param cbHistory the {@link HistoryComboBox} of which to restore the history
170 */
171 protected void remindPrimitivesHistory(HistoryComboBox cbHistory) {
172 cbHistory.addCurrentItemToHistory();
173 Main.pref.putCollection(getClass().getName() + ".primitivesHistory", cbHistory.getHistory());
174 }
175
176 /**
177 * Gets the requested OSM object IDs.
178 *
179 * @return The list of requested OSM object IDs
180 */
181 public final List<PrimitiveId> getOsmIds() {
182 return tfId.getIds();
183 }
184
185 @Override
186 public void setupDialog() {
187 setContent(panel, false);
188 cbType.setSelectedIndex(Main.pref.getInteger("downloadprimitive.lasttype", 0));
189 tfId.setType(cbType.getType());
190 if (Main.pref.getBoolean("downloadprimitive.autopaste", true)) {
191 tryToPasteFromClipboard(tfId, cbType);
192 }
193 setDefaultButton(getContinueButtonIndex());
194 addWindowListener(this);
195 super.setupDialog();
196 }
197
198 protected void tryToPasteFromClipboard(OsmIdTextField tfId, OsmPrimitiveTypesComboBox cbType) {
199 String buf = Utils.getClipboardContent();
200 if (buf == null || buf.isEmpty()) return;
201 if (buf.length() > Main.pref.getInteger("downloadprimitive.max-autopaste-length", 2000)) return;
202 final List<SimplePrimitiveId> ids = SimplePrimitiveId.fuzzyParse(buf);
203 if (!ids.isEmpty()) {
204 final String parsedText = Utils.join(", ", Utils.transform(ids, new Utils.Function<SimplePrimitiveId, String>() {
205 @Override
206 public String apply(SimplePrimitiveId x) {
207 return x.getType().getAPIName().charAt(0) + String.valueOf(x.getUniqueId());
208 }
209 }));
210 tfId.tryToPasteFrom(parsedText);
211 final Set<OsmPrimitiveType> types = new HashSet<>(Utils.transform(ids, new Utils.Function<SimplePrimitiveId, OsmPrimitiveType>() {
212 @Override
213 public OsmPrimitiveType apply(SimplePrimitiveId x) {
214 return x.getType();
215 }
216 }));
217 if (types.size() == 1) {
218 // select corresponding type
219 cbType.setSelectedItem(types.iterator().next());
220 } else {
221 // select "mixed"
222 cbType.setSelectedIndex(3);
223 }
224 } else if (buf.matches("[\\d,v\\s]+")) {
225 //fallback solution for id1,id2,id3 format
226 tfId.tryToPasteFrom(buf);
227 }
228 }
229
230 @Override public void windowClosed(WindowEvent e) {
231 if (e != null && e.getComponent() == this && getValue() == getContinueButtonIndex()) {
232 Main.pref.putInteger("downloadprimitive.lasttype", cbType.getSelectedIndex());
233
234 if (!tfId.readIds()) {
235 JOptionPane.showMessageDialog(getParent(),
236 tr("Invalid ID list specified\n"
237 + "Cannot continue."),
238 tr("Information"),
239 JOptionPane.INFORMATION_MESSAGE
240 );
241 return;
242 }
243
244 remindPrimitivesHistory(cbId);
245 }
246 }
247
248 @Override public void windowOpened(WindowEvent e) {}
249 @Override public void windowClosing(WindowEvent e) {}
250 @Override public void windowIconified(WindowEvent e) {}
251 @Override public void windowDeiconified(WindowEvent e) {}
252 @Override public void windowActivated(WindowEvent e) {}
253 @Override public void windowDeactivated(WindowEvent e) {}
254}
Note: See TracBrowser for help on using the repository browser.