1 | package org.openstreetmap.josm.gui;
|
---|
2 |
|
---|
3 | import java.awt.Component;
|
---|
4 | import java.awt.Dimension;
|
---|
5 | import java.awt.Font;
|
---|
6 | import java.awt.GridBagLayout;
|
---|
7 | import java.awt.event.ActionEvent;
|
---|
8 | import java.awt.event.ActionListener;
|
---|
9 |
|
---|
10 | import javax.swing.AbstractAction;
|
---|
11 | import javax.swing.BorderFactory;
|
---|
12 | import javax.swing.Box;
|
---|
13 | import javax.swing.DefaultListCellRenderer;
|
---|
14 | import javax.swing.JButton;
|
---|
15 | import javax.swing.JCheckBox;
|
---|
16 | import javax.swing.JComboBox;
|
---|
17 | import javax.swing.JComponent;
|
---|
18 | import javax.swing.JDialog;
|
---|
19 | import javax.swing.JLabel;
|
---|
20 | import javax.swing.JList;
|
---|
21 | import javax.swing.JOptionPane;
|
---|
22 | import javax.swing.JPanel;
|
---|
23 | import javax.swing.JPasswordField;
|
---|
24 | import javax.swing.JTabbedPane;
|
---|
25 | import javax.swing.JTextField;
|
---|
26 | import javax.swing.ListCellRenderer;
|
---|
27 | import javax.swing.UIManager;
|
---|
28 | import javax.swing.UIManager.LookAndFeelInfo;
|
---|
29 |
|
---|
30 | import org.openstreetmap.josm.Main;
|
---|
31 | import org.openstreetmap.josm.data.Preferences;
|
---|
32 | import org.openstreetmap.josm.data.Preferences.PreferencesException;
|
---|
33 | import org.openstreetmap.josm.data.projection.Projection;
|
---|
34 |
|
---|
35 | /**
|
---|
36 | * The preference settings.
|
---|
37 | *
|
---|
38 | * @author imi
|
---|
39 | */
|
---|
40 | public class PreferenceDialog extends JDialog {
|
---|
41 |
|
---|
42 | /**
|
---|
43 | * Action to take place when user pressed the ok button.
|
---|
44 | */
|
---|
45 | class OkAction extends AbstractAction {
|
---|
46 | public OkAction() {
|
---|
47 | super(UIManager.getString("OptionPane.okButtonText"),
|
---|
48 | UIManager.getIcon("OptionPane.okIcon"));
|
---|
49 | putValue(MNEMONIC_KEY, new Integer((String)UIManager.get("OptionPane.okButtonMnemonic")));
|
---|
50 | }
|
---|
51 | public void actionPerformed(ActionEvent e) {
|
---|
52 | Main.pref.laf = (LookAndFeelInfo)lafCombo.getSelectedItem();
|
---|
53 | Projection projection = (Projection)projectionCombo.getSelectedItem();
|
---|
54 | projection.commitConfigurationPanel();
|
---|
55 | Main.pref.setProjection(projection);
|
---|
56 | Main.pref.osmDataServer = osmDataServer.getText();
|
---|
57 | Main.pref.osmDataUsername = osmDataUsername.getText();
|
---|
58 | Main.pref.osmDataPassword = String.valueOf(osmDataPassword.getPassword());
|
---|
59 | if (Main.pref.osmDataPassword == "")
|
---|
60 | Main.pref.osmDataPassword = null;
|
---|
61 | Main.pref.setDrawRawGpsLines(drawRawGpsLines.isSelected());
|
---|
62 | Main.pref.setForceRawGpsLines(forceRawGpsLines.isSelected());
|
---|
63 | try {
|
---|
64 | Main.pref.save();
|
---|
65 | } catch (PreferencesException x) {
|
---|
66 | x.printStackTrace();
|
---|
67 | JOptionPane.showMessageDialog(PreferenceDialog.this, "Could not save preferences:\n"+x.getMessage());
|
---|
68 | }
|
---|
69 | if (requiresRestart)
|
---|
70 | JOptionPane.showMessageDialog(PreferenceDialog.this, "You have to restart JOSM for some settings to take effect.");
|
---|
71 | setVisible(false);
|
---|
72 | }
|
---|
73 | }
|
---|
74 |
|
---|
75 | /**
|
---|
76 | * Action to take place when user pressed the cancel button.
|
---|
77 | */
|
---|
78 | class CancelAction extends AbstractAction {
|
---|
79 | public CancelAction() {
|
---|
80 | super(UIManager.getString("OptionPane.cancelButtonText"),
|
---|
81 | UIManager.getIcon("OptionPane.cancelIcon"));
|
---|
82 | putValue(MNEMONIC_KEY, new Integer((String)UIManager.get("OptionPane.cancelButtonMnemonic")));
|
---|
83 | }
|
---|
84 | public void actionPerformed(ActionEvent e) {
|
---|
85 | setVisible(false);
|
---|
86 | }
|
---|
87 | }
|
---|
88 |
|
---|
89 | /**
|
---|
90 | * Indicate, that the application has to be restarted for the settings to take effect.
|
---|
91 | */
|
---|
92 | boolean requiresRestart = false;
|
---|
93 | /**
|
---|
94 | * ComboBox with all look and feels.
|
---|
95 | */
|
---|
96 | JComboBox lafCombo = new JComboBox(UIManager.getInstalledLookAndFeels());
|
---|
97 | /**
|
---|
98 | * Combobox with all projections available
|
---|
99 | */
|
---|
100 | JComboBox projectionCombo = new JComboBox(Preferences.allProjections.clone());
|
---|
101 | /**
|
---|
102 | * The main tab panel.
|
---|
103 | */
|
---|
104 | private JTabbedPane tabPane = new JTabbedPane(JTabbedPane.LEFT);
|
---|
105 |
|
---|
106 | /**
|
---|
107 | * Editfield for the Base url to the REST API from OSM.
|
---|
108 | */
|
---|
109 | JTextField osmDataServer = new JTextField(20);
|
---|
110 | /**
|
---|
111 | * Editfield for the username to the OSM account.
|
---|
112 | */
|
---|
113 | JTextField osmDataUsername = new JTextField(20);
|
---|
114 | /**
|
---|
115 | * Passwordfield for the userpassword of the REST API.
|
---|
116 | */
|
---|
117 | JPasswordField osmDataPassword = new JPasswordField(20);
|
---|
118 | /**
|
---|
119 | * The checkbox stating whether nodes should be merged together.
|
---|
120 | */
|
---|
121 | JCheckBox drawRawGpsLines = new JCheckBox("Draw lines between raw gps points.");
|
---|
122 | /**
|
---|
123 | * The checkbox stating whether raw gps lines should be forced.
|
---|
124 | */
|
---|
125 | JCheckBox forceRawGpsLines = new JCheckBox("Force lines if no line segments imported.");
|
---|
126 |
|
---|
127 | /**
|
---|
128 | * Create a preference setting dialog from an preferences-file. If the file does not
|
---|
129 | * exist, it will be created.
|
---|
130 | * If the dialog is closed with Ok, the preferences will be stored to the preferences-
|
---|
131 | * file, otherwise no change of the file happens.
|
---|
132 | */
|
---|
133 | public PreferenceDialog() {
|
---|
134 | super(Main.main, "Preferences");
|
---|
135 |
|
---|
136 | // look and feel combo box
|
---|
137 | final ListCellRenderer oldRenderer = lafCombo.getRenderer();
|
---|
138 | lafCombo.setRenderer(new DefaultListCellRenderer(){
|
---|
139 | @Override
|
---|
140 | public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
---|
141 | return oldRenderer.getListCellRendererComponent(list, ((LookAndFeelInfo)value).getName(), index, isSelected, cellHasFocus);
|
---|
142 | }});
|
---|
143 | lafCombo.setSelectedItem(Main.pref.laf);
|
---|
144 | lafCombo.addActionListener(new ActionListener(){
|
---|
145 | public void actionPerformed(ActionEvent e) {
|
---|
146 | setRequiresRestart();
|
---|
147 | }});
|
---|
148 |
|
---|
149 | // projection combo box
|
---|
150 | for (int i = 0; i < projectionCombo.getItemCount(); ++i) {
|
---|
151 | if (projectionCombo.getItemAt(i).getClass().equals(Main.pref.getProjection().getClass())) {
|
---|
152 | projectionCombo.setSelectedIndex(i);
|
---|
153 | break;
|
---|
154 | }
|
---|
155 | }
|
---|
156 | JButton projectionDetail = new JButton("Configure");
|
---|
157 | projectionDetail.addActionListener(new ActionListener(){
|
---|
158 | public void actionPerformed(ActionEvent e) {
|
---|
159 | Projection p = (Projection)projectionCombo.getSelectedItem();
|
---|
160 | JComponent configurationPanel = p.getConfigurationPanel();
|
---|
161 | if (configurationPanel == null) {
|
---|
162 | JOptionPane.showMessageDialog(PreferenceDialog.this,
|
---|
163 | "This projection does not need any configuration.");
|
---|
164 | return;
|
---|
165 | }
|
---|
166 | JPanel detail = new JPanel(new GridBagLayout());
|
---|
167 | detail.setLayout(new GridBagLayout());
|
---|
168 | detail.add(configurationPanel, GBC.eop().fill());
|
---|
169 | int result = JOptionPane.showConfirmDialog(
|
---|
170 | PreferenceDialog.this, detail, "Configuration of "+p,
|
---|
171 | JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
|
---|
172 | if (result != JOptionPane.OK_OPTION)
|
---|
173 | p.getConfigurationPanel(); // rollback
|
---|
174 | }
|
---|
175 | });
|
---|
176 |
|
---|
177 | // drawRawGpsLines
|
---|
178 | drawRawGpsLines.addActionListener(new ActionListener(){
|
---|
179 | public void actionPerformed(ActionEvent e) {
|
---|
180 | if (!drawRawGpsLines.isSelected())
|
---|
181 | forceRawGpsLines.setSelected(false);
|
---|
182 | forceRawGpsLines.setEnabled(drawRawGpsLines.isSelected());
|
---|
183 | }
|
---|
184 | });
|
---|
185 |
|
---|
186 |
|
---|
187 | osmDataServer.setToolTipText("The base URL to the OSM server (REST API)");
|
---|
188 | osmDataUsername.setToolTipText("Login name (email) to the OSM account.");
|
---|
189 | osmDataPassword.setToolTipText("Login password to the OSM account. Leave blank to not store any password.");
|
---|
190 | drawRawGpsLines.setToolTipText("If your gps device draw to few lines, select this to draw lines along your track.");
|
---|
191 | drawRawGpsLines.setSelected(Main.pref.isDrawRawGpsLines());
|
---|
192 | forceRawGpsLines.setToolTipText("Force drawing of lines if the imported data contain no line information.");
|
---|
193 | forceRawGpsLines.setSelected(Main.pref.isForceRawGpsLines());
|
---|
194 | forceRawGpsLines.setEnabled(drawRawGpsLines.isSelected());
|
---|
195 |
|
---|
196 | osmDataServer.setText(Main.pref.osmDataServer);
|
---|
197 | osmDataUsername.setText(Main.pref.osmDataUsername);
|
---|
198 | osmDataPassword.setText(Main.pref.osmDataPassword);
|
---|
199 |
|
---|
200 | // Display tab
|
---|
201 | JPanel display = createPreferenceTab("display", "Display Settings", "Various settings that influence the visual representation of the whole program.");
|
---|
202 | display.add(new JLabel("Look and Feel"), GBC.std());
|
---|
203 | display.add(GBC.glue(5,0), GBC.std().fill(GBC.HORIZONTAL));
|
---|
204 | display.add(lafCombo, GBC.eol().fill(GBC.HORIZONTAL));
|
---|
205 | display.add(drawRawGpsLines, GBC.eol().insets(20,0,0,0));
|
---|
206 | display.add(forceRawGpsLines, GBC.eol().insets(40,0,0,0));
|
---|
207 | display.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.VERTICAL));
|
---|
208 |
|
---|
209 | // Connection tab
|
---|
210 | JPanel con = createPreferenceTab("connection", "Connection Settings", "Connection Settings to the OSM server.");
|
---|
211 | con.add(new JLabel("Base Server URL"), GBC.std());
|
---|
212 | con.add(osmDataServer, GBC.eol().fill(GBC.HORIZONTAL).insets(5,0,0,5));
|
---|
213 | con.add(new JLabel("OSM username (email)"), GBC.std());
|
---|
214 | con.add(osmDataUsername, GBC.eol().fill(GBC.HORIZONTAL).insets(5,0,0,5));
|
---|
215 | con.add(new JLabel("OSM password"), GBC.std());
|
---|
216 | con.add(osmDataPassword, GBC.eol().fill(GBC.HORIZONTAL).insets(5,0,0,0));
|
---|
217 | JLabel warning = new JLabel("<html>" +
|
---|
218 | "WARNING: The password is stored in plain text in the preferences file.<br>" +
|
---|
219 | "The password is transfered in plain text to the server, encoded in the url.<br>" +
|
---|
220 | "<b>Do not use a valuable Password.</b></html>");
|
---|
221 | warning.setFont(warning.getFont().deriveFont(Font.ITALIC));
|
---|
222 | con.add(warning, GBC.eop().fill(GBC.HORIZONTAL));
|
---|
223 |
|
---|
224 |
|
---|
225 | // Map tab
|
---|
226 | JPanel map = createPreferenceTab("map", "Map Settings", "Settings for the map projection and data interpretation.");
|
---|
227 | map.add(new JLabel("Projection method"), GBC.std());
|
---|
228 | map.add(GBC.glue(5,0), GBC.std().fill(GBC.HORIZONTAL));
|
---|
229 | map.add(projectionCombo, GBC.eol().fill(GBC.HORIZONTAL).insets(0,0,0,5));
|
---|
230 | map.add(new JLabel("Projection details:"), GBC.std());
|
---|
231 | map.add(GBC.glue(5,0), GBC.std().fill(GBC.HORIZONTAL));
|
---|
232 | map.add(projectionDetail, GBC.eop());
|
---|
233 | map.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.VERTICAL));
|
---|
234 |
|
---|
235 |
|
---|
236 | tabPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
|
---|
237 |
|
---|
238 | // OK/Cancel panel at bottom
|
---|
239 | JPanel okPanel = new JPanel(new GridBagLayout());
|
---|
240 | okPanel.add(Box.createHorizontalGlue(), GBC.std().fill(GBC.HORIZONTAL));
|
---|
241 | okPanel.add(new JButton(new OkAction()), GBC.std());
|
---|
242 | okPanel.add(new JButton(new CancelAction()), GBC.std());
|
---|
243 | okPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
|
---|
244 |
|
---|
245 | // merging all in the content pane
|
---|
246 | getContentPane().setLayout(new GridBagLayout());
|
---|
247 | getContentPane().add(tabPane, GBC.eol().fill());
|
---|
248 | getContentPane().add(okPanel, GBC.eol().fill(GBC.HORIZONTAL));
|
---|
249 |
|
---|
250 | setModal(true);
|
---|
251 | pack();
|
---|
252 | Dimension s = Main.main.getSize();
|
---|
253 | setLocation(Main.main.getX()+s.width/2-getWidth()/2, Main.main.getY()+s.height/2-getHeight()/2);
|
---|
254 | }
|
---|
255 |
|
---|
256 | /**
|
---|
257 | * Construct a JPanel for the preference settings. Layout is GridBagLayout
|
---|
258 | * and a centered title label and the description are added.
|
---|
259 | * @param icon The name of the icon.
|
---|
260 | * @param title The title of this preference tab.
|
---|
261 | * @param desc A description in one sentence for this tab. Will be displayed
|
---|
262 | * italic under the title.
|
---|
263 | * @return The created panel ready to add other controls.
|
---|
264 | */
|
---|
265 | private JPanel createPreferenceTab(String icon, String title, String desc) {
|
---|
266 | JPanel p = new JPanel(new GridBagLayout());
|
---|
267 | p.add(new JLabel(title), GBC.eol().anchor(GBC.CENTER).insets(0,5,0,10));
|
---|
268 |
|
---|
269 | JLabel descLabel = new JLabel("<html>"+desc+"</html>");
|
---|
270 | descLabel.setFont(descLabel.getFont().deriveFont(Font.ITALIC));
|
---|
271 | p.add(descLabel, GBC.eol().insets(5,0,5,20).fill(GBC.HORIZONTAL));
|
---|
272 |
|
---|
273 | tabPane.addTab(null, ImageProvider.get("preferences", icon), p);
|
---|
274 | tabPane.setToolTipTextAt(tabPane.getTabCount()-1, desc);
|
---|
275 | return p;
|
---|
276 | }
|
---|
277 |
|
---|
278 | /**
|
---|
279 | * Remember, that the settings made requires a restart of the application.
|
---|
280 | * Called from various actionListener - classes
|
---|
281 | */
|
---|
282 | protected void setRequiresRestart() {
|
---|
283 | requiresRestart = true;
|
---|
284 | }
|
---|
285 | }
|
---|