source: josm/src/org/openstreetmap/josm/gui/PreferenceDialog.java@ 134

Last change on this file since 134 was 134, checked in by imi, 18 years ago

fixed wrongly translated "OptionPane.okButtonText"

File size: 20.3 KB
Line 
1package org.openstreetmap.josm.gui;
2
3import static org.openstreetmap.josm.tools.I18n.tr;
4
5import java.awt.Color;
6import java.awt.Component;
7import java.awt.Dimension;
8import java.awt.Font;
9import java.awt.GridBagLayout;
10import java.awt.event.ActionEvent;
11import java.awt.event.ActionListener;
12import java.util.Locale;
13import java.util.Map;
14import java.util.StringTokenizer;
15import java.util.TreeMap;
16import java.util.Vector;
17import java.util.Map.Entry;
18
19import javax.swing.AbstractAction;
20import javax.swing.BorderFactory;
21import javax.swing.Box;
22import javax.swing.DefaultListCellRenderer;
23import javax.swing.DefaultListModel;
24import javax.swing.JButton;
25import javax.swing.JCheckBox;
26import javax.swing.JColorChooser;
27import javax.swing.JComboBox;
28import javax.swing.JDialog;
29import javax.swing.JLabel;
30import javax.swing.JList;
31import javax.swing.JOptionPane;
32import javax.swing.JPanel;
33import javax.swing.JPasswordField;
34import javax.swing.JScrollPane;
35import javax.swing.JTabbedPane;
36import javax.swing.JTable;
37import javax.swing.JTextField;
38import javax.swing.ListCellRenderer;
39import javax.swing.ListSelectionModel;
40import javax.swing.UIManager;
41import javax.swing.UIManager.LookAndFeelInfo;
42import javax.swing.table.TableCellRenderer;
43
44import org.openstreetmap.josm.Main;
45import org.openstreetmap.josm.data.projection.Projection;
46import org.openstreetmap.josm.tools.ColorHelper;
47import org.openstreetmap.josm.tools.GBC;
48import org.openstreetmap.josm.tools.ImageProvider;
49
50/**
51 * The preference settings.
52 *
53 * @author imi
54 */
55public class PreferenceDialog extends JDialog {
56
57 private final class RequireRestartAction implements ActionListener {
58 public void actionPerformed(ActionEvent e) {
59 requiresRestart = true;
60 }
61 }
62 private RequireRestartAction requireRestartAction = new RequireRestartAction();
63
64 /**
65 * Action to take place when user pressed the ok button.
66 */
67 class OkAction extends AbstractAction {
68 private static final String OKBUTTON_PROP = "OptionPane.okButtonText";
69
70 public OkAction() {
71 super(UIManager.getString(OKBUTTON_PROP), UIManager.getIcon("OptionPane.okIcon"));
72 try {
73 putValue(MNEMONIC_KEY, new Integer((String)UIManager.get("OptionPane.okButtonMnemonic")));
74 } catch (NumberFormatException e) {
75 // just don't set the mnemonic
76 }
77 }
78 public void actionPerformed(ActionEvent e) {
79 Main.pref.put("laf", ((LookAndFeelInfo)lafCombo.getSelectedItem()).getClassName());
80 Main.pref.put("language", languages.getSelectedItem().toString());
81 Main.pref.put("projection", projectionCombo.getSelectedItem().getClass().getName());
82 Main.pref.put("osm-server.url", osmDataServer.getText());
83 Main.pref.put("osm-server.username", osmDataUsername.getText());
84 String pwd = String.valueOf(osmDataPassword.getPassword());
85 if (pwd.equals(""))
86 pwd = null;
87 Main.pref.put("osm-server.password", pwd);
88 Main.pref.put("wms.baseurl", wmsServerBaseUrl.getText());
89 Main.pref.put("csv.importstring", csvImportString.getText());
90 Main.pref.put("draw.rawgps.lines", drawRawGpsLines.isSelected());
91 Main.pref.put("draw.rawgps.lines.force", forceRawGpsLines.isSelected());
92 Main.pref.put("draw.rawgps.large", largeGpsPoints.isSelected());
93 Main.pref.put("draw.segment.direction", directionHint.isSelected());
94
95 if (annotationSources.getModel().getSize() > 0) {
96 StringBuilder sb = new StringBuilder();
97 for (int i = 0; i < annotationSources.getModel().getSize(); ++i)
98 sb.append(";"+annotationSources.getModel().getElementAt(i));
99 Main.pref.put("annotation.sources", sb.toString().substring(1));
100 } else
101 Main.pref.put("annotation.sources", null);
102
103 for (int i = 0; i < colors.getRowCount(); ++i) {
104 String name = (String)colors.getValueAt(i, 0);
105 Color col = (Color)colors.getValueAt(i, 1);
106 Main.pref.put("color."+name, ColorHelper.color2html(col));
107 }
108
109 if (requiresRestart)
110 JOptionPane.showMessageDialog(PreferenceDialog.this,tr("You have to restart JOSM for some settings to take effect."));
111 Main.parent.repaint();
112 setVisible(false);
113 }
114 }
115
116 /**
117 * Action to take place when user pressed the cancel button.
118 */
119 class CancelAction extends AbstractAction {
120 private static final String CANCELBUTTON_PROP = "OptionPane.cancelButtonText";
121 public CancelAction() {
122 super(UIManager.getString(CANCELBUTTON_PROP),
123 UIManager.getIcon("OptionPane.cancelIcon"));
124 try {
125 putValue(MNEMONIC_KEY, new Integer((String)UIManager.get("OptionPane.cancelButtonMnemonic")));
126 } catch (NumberFormatException e) {
127 // just don't set the mnemonic
128 }
129 }
130 public void actionPerformed(ActionEvent e) {
131 setVisible(false);
132 }
133 }
134
135 /**
136 * Indicate, that the application has to be restarted for the settings to take effect.
137 */
138 private boolean requiresRestart = false;
139 /**
140 * ComboBox with all look and feels.
141 */
142 private JComboBox lafCombo = new JComboBox(UIManager.getInstalledLookAndFeels());
143 private JComboBox languages = new JComboBox(new Locale[]{
144 new Locale("en", "US"),
145 new Locale("en", "GB"),
146 Locale.GERMAN,
147 Locale.FRENCH,
148 new Locale("ro", "RO")});
149 /**
150 * The main tab panel.
151 */
152 private JTabbedPane tabPane = new JTabbedPane(JTabbedPane.LEFT);
153
154 /**
155 * Editfield for the Base url to the REST API from OSM.
156 */
157 private JTextField osmDataServer = new JTextField(20);
158 /**
159 * Editfield for the username to the OSM account.
160 */
161 private JTextField osmDataUsername = new JTextField(20);
162 /**
163 * Passwordfield for the userpassword of the REST API.
164 */
165 private JPasswordField osmDataPassword = new JPasswordField(20);
166 /**
167 * Base url of the WMS server. Holds everything except the bbox= argument.
168 */
169 private JTextField wmsServerBaseUrl = new JTextField(20);
170 /**
171 * Comma seperated import string specifier or <code>null</code> if the first
172 * data line should be interpreted as one.
173 */
174 private JTextField csvImportString = new JTextField(20);
175 /**
176 * The checkbox stating whether nodes should be merged together.
177 */
178 private JCheckBox drawRawGpsLines = new JCheckBox(tr("Draw lines between raw gps points."));
179 /**
180 * The checkbox stating whether raw gps lines should be forced.
181 */
182 private JCheckBox forceRawGpsLines = new JCheckBox(tr("Force lines if no segments imported."));
183 private JCheckBox largeGpsPoints = new JCheckBox(tr("Draw large GPS points."));
184 private JCheckBox directionHint = new JCheckBox(tr("Draw Direction Arrows"));
185 private JTable colors;
186
187 /**
188 * Combobox with all projections available
189 */
190 private JComboBox projectionCombo = new JComboBox(Projection.allProjections);
191 private JList annotationSources = new JList(new DefaultListModel());
192
193
194 /**
195 * Create a preference setting dialog from an preferences-file. If the file does not
196 * exist, it will be created.
197 * If the dialog is closed with Ok, the preferences will be stored to the preferences-
198 * file, otherwise no change of the file happens.
199 */
200 public PreferenceDialog() {
201 super(JOptionPane.getFrameForComponent(Main.parent), tr("Preferences"));
202
203 // look and feel combo box
204 String laf = Main.pref.get("laf");
205 for (int i = 0; i < lafCombo.getItemCount(); ++i) {
206 if (((LookAndFeelInfo)lafCombo.getItemAt(i)).getClassName().equals(laf)) {
207 lafCombo.setSelectedIndex(i);
208 break;
209 }
210 }
211 final ListCellRenderer oldRenderer = lafCombo.getRenderer();
212 lafCombo.setRenderer(new DefaultListCellRenderer(){
213 @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
214 return oldRenderer.getListCellRendererComponent(list, ((LookAndFeelInfo)value).getName(), index, isSelected, cellHasFocus);
215 }
216 });
217 lafCombo.addActionListener(requireRestartAction);
218
219 // language
220 String lang = Main.pref.get("language");
221 for (int i = 0; i < languages.getItemCount(); ++i) {
222 if (languages.getItemAt(i).toString().equals(lang)) {
223 languages.setSelectedIndex(i);
224 break;
225 }
226 }
227 languages.setRenderer(new DefaultListCellRenderer(){
228 @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
229 return super.getListCellRendererComponent(list, ((Locale)value).getDisplayName(), index, isSelected, cellHasFocus);
230 }
231 });
232 languages.addActionListener(requireRestartAction);
233
234 // projection combo box
235 for (int i = 0; i < projectionCombo.getItemCount(); ++i) {
236 if (projectionCombo.getItemAt(i).getClass().getName().equals(Main.pref.get("projection"))) {
237 projectionCombo.setSelectedIndex(i);
238 break;
239 }
240 }
241 projectionCombo.addActionListener(requireRestartAction);
242
243 drawRawGpsLines.addActionListener(new ActionListener(){
244 public void actionPerformed(ActionEvent e) {
245 if (!drawRawGpsLines.isSelected())
246 forceRawGpsLines.setSelected(false);
247 forceRawGpsLines.setEnabled(drawRawGpsLines.isSelected());
248 }
249 });
250
251 osmDataServer.setText(Main.pref.get("osm-server.url"));
252 osmDataUsername.setText(Main.pref.get("osm-server.username"));
253 osmDataPassword.setText(Main.pref.get("osm-server.password"));
254 wmsServerBaseUrl.setText(Main.pref.get("wms.baseurl", "http://wms.jpl.nasa.gov/wms.cgi?request=GetMap&width=512&height=512&layers=global_mosaic&styles=&srs=EPSG:4326&format=image/jpeg&"));
255 csvImportString.setText(Main.pref.get("csv.importstring"));
256 drawRawGpsLines.setSelected(Main.pref.getBoolean("draw.rawgps.lines"));
257 forceRawGpsLines.setToolTipText(tr("Force drawing of lines if the imported data contain no line information."));
258 forceRawGpsLines.setSelected(Main.pref.getBoolean("draw.rawgps.lines.force"));
259 forceRawGpsLines.setEnabled(drawRawGpsLines.isSelected());
260 largeGpsPoints.setSelected(Main.pref.getBoolean("draw.rawgps.large"));
261 largeGpsPoints.setToolTipText(tr("Draw larger dots for the GPS points."));
262 directionHint.setToolTipText(tr("Draw direction hints for all segments."));
263 directionHint.setSelected(Main.pref.getBoolean("draw.segment.direction"));
264
265 String annos = Main.pref.get("annotation.sources");
266 StringTokenizer st = new StringTokenizer(annos, ";");
267 while (st.hasMoreTokens())
268 ((DefaultListModel)annotationSources.getModel()).addElement(st.nextToken());
269
270
271 Map<String,String> allColors = new TreeMap<String, String>(Main.pref.getAllPrefix("color."));
272
273 Vector<Vector<Object>> rows = new Vector<Vector<Object>>();
274 for (Entry<String,String> e : allColors.entrySet()) {
275 Vector<Object> row = new Vector<Object>(2);
276 row.add(tr(e.getKey().substring("color.".length())));
277 row.add(ColorHelper.html2color(e.getValue()));
278 rows.add(row);
279 }
280 Vector<Object> cols = new Vector<Object>(2);
281 cols.add(tr("Color"));
282 cols.add(tr("Name"));
283 colors = new JTable(rows, cols){
284 @Override public boolean isCellEditable(int row, int column) {
285 return false;
286 }
287 };
288 colors.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
289 final TableCellRenderer oldColorsRenderer = colors.getDefaultRenderer(Object.class);
290 colors.setDefaultRenderer(Object.class, new TableCellRenderer(){
291 public Component getTableCellRendererComponent(JTable t, Object o, boolean selected, boolean focus, int row, int column) {
292 if (column == 1) {
293 JLabel l = new JLabel(ColorHelper.color2html((Color)o));
294 l.setBackground((Color)o);
295 l.setOpaque(true);
296 return l;
297 }
298 return oldColorsRenderer.getTableCellRendererComponent(t,o,selected,focus,row,column);
299 }
300 });
301 colors.getColumnModel().getColumn(1).setWidth(100);
302
303 JButton colorEdit = new JButton(tr("Choose"));
304 colorEdit.addActionListener(new ActionListener(){
305 public void actionPerformed(ActionEvent e) {
306 if (colors.getSelectedRowCount() == 0) {
307 JOptionPane.showMessageDialog(PreferenceDialog.this, tr("Please select a color."));
308 return;
309 }
310 int sel = colors.getSelectedRow();
311 JColorChooser chooser = new JColorChooser((Color)colors.getValueAt(sel, 1));
312 int answer = JOptionPane.showConfirmDialog(PreferenceDialog.this, chooser, tr("Choose a color for {0}", colors.getValueAt(sel, 0)), JOptionPane.OK_CANCEL_OPTION);
313 if (answer == JOptionPane.OK_OPTION)
314 colors.setValueAt(chooser.getColor(), sel, 1);
315 }
316 });
317
318 // Annotation source panels
319 JButton addAnno = new JButton(tr("Add"));
320 addAnno.addActionListener(new ActionListener(){
321 public void actionPerformed(ActionEvent e) {
322 String source = JOptionPane.showInputDialog(Main.parent, tr("Annotation preset source"));
323 if (source == null)
324 return;
325 ((DefaultListModel)annotationSources.getModel()).addElement(source);
326 requiresRestart = true;
327 }
328 });
329
330 JButton editAnno = new JButton(tr("Edit"));
331 editAnno.addActionListener(new ActionListener(){
332 public void actionPerformed(ActionEvent e) {
333 if (annotationSources.getSelectedIndex() == -1)
334 JOptionPane.showMessageDialog(Main.parent, tr("Please select the row to edit."));
335 else {
336 String source = JOptionPane.showInputDialog(Main.parent, tr("Annotation preset source"), annotationSources.getSelectedValue());
337 if (source == null)
338 return;
339 ((DefaultListModel)annotationSources.getModel()).setElementAt(source, annotationSources.getSelectedIndex());
340 requiresRestart = true;
341 }
342 }
343 });
344
345 JButton deleteAnno = new JButton(tr("Delete"));
346 deleteAnno.addActionListener(new ActionListener(){
347 public void actionPerformed(ActionEvent e) {
348 if (annotationSources.getSelectedIndex() == -1)
349 JOptionPane.showMessageDialog(Main.parent, tr("Please select the row to delete."));
350 else {
351 ((DefaultListModel)annotationSources.getModel()).remove(annotationSources.getSelectedIndex());
352 requiresRestart = true;
353 }
354 }
355 });
356 annotationSources.setVisibleRowCount(3);
357
358
359
360 // setting tooltips
361 osmDataServer.setToolTipText(tr("The base URL to the OSM server (REST API)"));
362 osmDataUsername.setToolTipText(tr("Login name (email) to the OSM account."));
363 osmDataPassword.setToolTipText(tr("Login password to the OSM account. Leave blank to not store any password."));
364 wmsServerBaseUrl.setToolTipText(tr("The base URL to the server retrieving WMS background pictures from."));
365 csvImportString.setToolTipText(tr("<html>Import string specification. lat/lon and time are imported.<br>" +
366 "<b>lat</b>: The latitude coordinate<br>" +
367 "<b>lon</b>: The longitude coordinate<br>" +
368 "<b>time</b>: The measured time as string<br>" +
369 "<b>ignore</b>: Skip this field<br>" +
370 "An example: \"ignore ignore lat lon\" will use ' ' as delimiter, skip the first two values and read then lat/lon.<br>" +
371 "Other example: \"lat,lon\" will just read lat/lon values comma seperated.</html>"));
372 drawRawGpsLines.setToolTipText(tr("If your gps device draw to few lines, select this to draw lines along your way."));
373 colors.setToolTipText(tr("Colors used by different objects in JOSM."));
374 annotationSources.setToolTipText(tr("The sources (url or filename) of annotation preset definition files. See http://josm.eigenheimstrasse.de/wiki/AnnotationPresets for help."));
375 addAnno.setToolTipText(tr("Add a new annotation preset source to the list."));
376 deleteAnno.setToolTipText(tr("Delete the selected source from the list."));
377
378 // creating the gui
379
380 // Display tab
381 JPanel display = createPreferenceTab("display", tr("Display Settings"), tr("Various settings that influence the visual representation of the whole program."));
382 display.add(new JLabel(tr("Look and Feel")), GBC.std());
383 display.add(GBC.glue(5,0), GBC.std().fill(GBC.HORIZONTAL));
384 display.add(lafCombo, GBC.eol().fill(GBC.HORIZONTAL));
385 display.add(new JLabel(tr("Language")), GBC.std());
386 display.add(GBC.glue(5,0), GBC.std().fill(GBC.HORIZONTAL));
387 display.add(languages, GBC.eol().fill(GBC.HORIZONTAL));
388 display.add(drawRawGpsLines, GBC.eol().insets(20,0,0,0));
389 display.add(forceRawGpsLines, GBC.eop().insets(40,0,0,0));
390 display.add(largeGpsPoints, GBC.eop().insets(20,0,0,0));
391 display.add(directionHint, GBC.eop().insets(20,0,0,0));
392 display.add(new JLabel(tr("Colors")), GBC.eol());
393 colors.setPreferredScrollableViewportSize(new Dimension(100,112));
394 display.add(new JScrollPane(colors), GBC.eol().fill(GBC.BOTH));
395 display.add(colorEdit, GBC.eol().anchor(GBC.EAST));
396 //display.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.VERTICAL));
397
398 // Connection tab
399 JPanel con = createPreferenceTab("connection", tr("Connection Settings"), tr("Connection Settings to the OSM server."));
400 con.add(new JLabel(tr("Base Server URL")), GBC.std());
401 con.add(osmDataServer, GBC.eol().fill(GBC.HORIZONTAL).insets(5,0,0,5));
402 con.add(new JLabel(tr("OSM username (email)")), GBC.std());
403 con.add(osmDataUsername, GBC.eol().fill(GBC.HORIZONTAL).insets(5,0,0,5));
404 con.add(new JLabel(tr("OSM password")), GBC.std());
405 con.add(osmDataPassword, GBC.eol().fill(GBC.HORIZONTAL).insets(5,0,0,0));
406 JLabel warning = new JLabel(tr("<html>" +
407 "WARNING: The password is stored in plain text in the preferences file.<br>" +
408 "The password is transfered in plain text to the server, encoded in the url.<br>" +
409 "<b>Do not use a valuable Password.</b></html>"));
410 warning.setFont(warning.getFont().deriveFont(Font.ITALIC));
411 con.add(warning, GBC.eop().fill(GBC.HORIZONTAL));
412 //con.add(new JLabel("WMS server base url (everything except bbox-parameter)"), GBC.eol());
413 //con.add(wmsServerBaseUrl, GBC.eop().fill(GBC.HORIZONTAL));
414 //con.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.VERTICAL));
415 con.add(new JLabel(tr("CSV import specification (empty: read from first line in data)")), GBC.eol());
416 con.add(csvImportString, GBC.eop().fill(GBC.HORIZONTAL));
417 con.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.VERTICAL));
418
419 // Map tab
420 JPanel map = createPreferenceTab("map", tr("Map Settings"), tr("Settings for the map projection and data interpretation."));
421 map.add(new JLabel(tr("Projection method")), GBC.std());
422 map.add(GBC.glue(5,0), GBC.std().fill(GBC.HORIZONTAL));
423 map.add(projectionCombo, GBC.eop().fill(GBC.HORIZONTAL).insets(0,0,0,5));
424 map.add(new JLabel(tr("Annotation preset sources")), GBC.eol().insets(0,5,0,0));
425 map.add(new JScrollPane(annotationSources), GBC.eol().fill(GBC.BOTH));
426 map.add(GBC.glue(5, 0), GBC.std().fill(GBC.HORIZONTAL));
427 map.add(addAnno, GBC.std());
428 map.add(editAnno, GBC.std().insets(5,0,5,0));
429 map.add(deleteAnno, GBC.std());
430
431 // I HATE SWING!
432 map.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.VERTICAL));
433 map.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.VERTICAL));
434 map.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.VERTICAL));
435 map.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.VERTICAL));
436 map.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.VERTICAL));
437
438
439 tabPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
440
441 // OK/Cancel panel at bottom
442 JPanel okPanel = new JPanel(new GridBagLayout());
443 okPanel.add(Box.createHorizontalGlue(), GBC.std().fill(GBC.HORIZONTAL));
444 okPanel.add(new JButton(new OkAction()), GBC.std());
445 okPanel.add(new JButton(new CancelAction()), GBC.std());
446 okPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
447
448 // merging all in the content pane
449 getContentPane().setLayout(new GridBagLayout());
450 getContentPane().add(tabPane, GBC.eol().fill());
451 getContentPane().add(okPanel, GBC.eol().fill(GBC.HORIZONTAL));
452
453 setModal(true);
454 pack();
455 setLocationRelativeTo(Main.parent);
456 }
457
458 /**
459 * Construct a JPanel for the preference settings. Layout is GridBagLayout
460 * and a centered title label and the description are added.
461 * @param icon The name of the icon.
462 * @param title The title of this preference tab.
463 * @param desc A description in one sentence for this tab. Will be displayed
464 * italic under the title.
465 * @return The created panel ready to add other controls.
466 */
467 private JPanel createPreferenceTab(String icon, String title, String desc) {
468 JPanel p = new JPanel(new GridBagLayout());
469 p.add(new JLabel(title), GBC.eol().anchor(GBC.CENTER).insets(0,5,0,10));
470
471 JLabel descLabel = new JLabel("<html>"+desc+"</html>");
472 descLabel.setFont(descLabel.getFont().deriveFont(Font.ITALIC));
473 p.add(descLabel, GBC.eol().insets(5,0,5,20).fill(GBC.HORIZONTAL));
474
475 tabPane.addTab(null, ImageProvider.get("preferences", icon), p);
476 tabPane.setToolTipTextAt(tabPane.getTabCount()-1, desc);
477 return p;
478 }
479}
Note: See TracBrowser for help on using the repository browser.