source: josm/trunk/src/org/openstreetmap/josm/gui/preferences/AdvancedPreference.java@ 3895

Last change on this file since 3895 was 3536, checked in by stoecker, 14 years ago

improve advanced preferences

  • Property svn:eol-style set to native
File size: 11.5 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.gui.preferences;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.Component;
7import java.awt.Dimension;
8import java.awt.GridBagLayout;
9import java.awt.event.ActionEvent;
10import java.awt.event.ActionListener;
11import java.awt.event.MouseAdapter;
12import java.awt.event.MouseEvent;
13import java.util.Arrays;
14import java.util.ArrayList;
15import java.util.Map;
16import java.util.TreeMap;
17import java.util.TreeSet;
18import java.util.Map.Entry;
19
20import javax.swing.Box;
21import javax.swing.JButton;
22import javax.swing.JLabel;
23import javax.swing.JOptionPane;
24import javax.swing.JPanel;
25import javax.swing.JScrollPane;
26import javax.swing.JTable;
27import javax.swing.JTextField;
28import javax.swing.event.DocumentEvent;
29import javax.swing.event.DocumentListener;
30import javax.swing.table.DefaultTableCellRenderer;
31import javax.swing.table.DefaultTableModel;
32
33import org.openstreetmap.josm.Main;
34import org.openstreetmap.josm.gui.ExtendedDialog;
35import org.openstreetmap.josm.tools.GBC;
36
37public class AdvancedPreference implements PreferenceSetting {
38
39 public static class Factory implements PreferenceSettingFactory {
40 public PreferenceSetting createPreferenceSetting() {
41 return new AdvancedPreference();
42 }
43 }
44
45 private Map<String,String> orig;
46 private Map<String,String> defaults;
47 private DefaultTableModel model;
48 protected Map<String, String> data;
49 protected JTextField txtFilter;
50
51 public void addGui(final PreferenceTabbedPane gui) {
52 JPanel p = gui.createPreferenceTab("advanced", tr("Advanced Preferences"),
53 tr("Setting Preference entries directly. Use with caution!"), false);
54
55 txtFilter = new JTextField();
56 JLabel lbFilter = new JLabel(tr("Search: "));
57 lbFilter.setLabelFor(txtFilter);
58 p.add(lbFilter);
59 p.add(txtFilter, GBC.eol().fill(GBC.HORIZONTAL));
60 txtFilter.getDocument().addDocumentListener(new DocumentListener(){
61 public void changedUpdate(DocumentEvent e) {
62 action();
63 }
64
65 public void insertUpdate(DocumentEvent e) {
66 action();
67 }
68
69 public void removeUpdate(DocumentEvent e) {
70 action();
71 }
72
73 private void action() {
74 dataToModel();
75 }
76 });
77
78 model = new DefaultTableModel(new String[]{tr("Key"), tr("Value")},0) {
79 @Override public boolean isCellEditable(int row, int column) {
80 return column != 0;
81 }
82 @Override public void fireTableCellUpdated(int row, int column)
83 {
84 super.fireTableCellUpdated(row, column);
85 if(column == 1)
86 {
87 data.put((String) model.getValueAt(row, 0),
88 (String) model.getValueAt(row, 1));
89 }
90 }
91
92 };
93 DefaultTableCellRenderer renderer = new DefaultTableCellRenderer(){
94 @Override
95 public Component getTableCellRendererComponent(JTable table, Object value,
96 boolean isSelected, boolean hasFocus, int row, int column)
97 {
98 JLabel label=new JLabel();
99 String s = defaults.get(value);
100 if(s != null)
101 {
102 if(s.equals(model.getValueAt(row, 1))) {
103 label.setToolTipText(tr("Current value is default."));
104 } else {
105 label.setToolTipText(tr("Default value is ''{0}''.", s));
106 }
107 } else {
108 label.setToolTipText(tr("Default value currently unknown (setting has not been used yet)."));
109 }
110 label.setText((String)value);
111 return label;
112 }
113 };
114 final JTable list = new JTable(model);
115 list.putClientProperty("terminateEditOnFocusLost", true);
116 list.getColumn(tr("Key")).setCellRenderer(renderer);
117 JScrollPane scroll = new JScrollPane(list);
118 p.add(scroll, GBC.eol().fill(GBC.BOTH));
119 scroll.setPreferredSize(new Dimension(400,200));
120
121 orig = Main.pref.getAllPrefix("");
122 defaults = Main.pref.getDefaults();
123 orig.remove("osm-server.password");
124 defaults.remove("osm-server.password");
125 prepareData();
126 dataToModel();
127
128 JButton add = new JButton(tr("Add"));
129 p.add(Box.createHorizontalGlue(), GBC.std().fill(GBC.HORIZONTAL));
130 p.add(add, GBC.std().insets(0,5,0,0));
131 add.addActionListener(new ActionListener(){
132 public void actionPerformed(ActionEvent e) {
133 addPreference(gui);
134 }
135 });
136
137 JButton edit = new JButton(tr("Edit"));
138 p.add(edit, GBC.std().insets(5,5,5,0));
139 edit.addActionListener(new ActionListener(){
140 public void actionPerformed(ActionEvent e) {
141 editPreference(gui, list);
142 }
143 });
144
145 JButton delete = new JButton(tr("Delete"));
146 p.add(delete, GBC.std().insets(0,5,0,0));
147 delete.addActionListener(new ActionListener(){
148 public void actionPerformed(ActionEvent e) {
149 removePreference(gui, list);
150 }
151 });
152
153 list.addMouseListener(new MouseAdapter(){
154 @Override public void mouseClicked(MouseEvent e) {
155 if (e.getClickCount() == 2) {
156 editPreference(gui, list);
157 }
158 }
159 });
160 }
161
162 private void prepareData() {
163 TreeSet<String> ts = new TreeSet<String>(orig.keySet());
164 for (String s : defaults.keySet())
165 {
166 if(!ts.contains(s)) {
167 ts.add(s);
168 }
169 }
170 data = new TreeMap<String, String>();
171 for (String s : ts)
172 {
173 String val = Main.pref.get(s);
174 if(val == null) {
175 val = "";
176 }
177 data.put(s, val);
178 }
179 }
180
181 private void dataToModel() {
182 while (model.getRowCount() > 0) {
183 model.removeRow(0);
184 }
185 for (String prefKey : data.keySet()) {
186 String prefValue = data.get(prefKey);
187 String input[] = txtFilter.getText().split("\\s+");
188 boolean canHas = true;
189
190 // Make 'wmsplugin cache' search for e.g. 'cache.wmsplugin'
191 for (String bit : input) {
192 if (!prefKey.contains(bit) && !prefValue.contains(bit)) {
193 canHas = false;
194 }
195 }
196
197 if (canHas) {
198 model.addRow(new String[] {prefKey, prefValue});
199 }
200 }
201 }
202
203 public boolean ok() {
204 for (String key : data.keySet()) {
205 String value = data.get(key);
206 if(value.length() != 0)
207 {
208 String origValue = orig.get(key);
209 if (origValue == null || !origValue.equals(value)) {
210 Main.pref.put(key, value);
211 }
212 orig.remove(key); // processed.
213 }
214 }
215 for (Entry<String, String> e : orig.entrySet()) {
216 Main.pref.put(e.getKey(), null);
217 }
218 return false;
219 }
220
221 private void removePreference(final PreferenceTabbedPane gui, final JTable list) {
222 if (list.getSelectedRowCount() == 0) {
223 JOptionPane.showMessageDialog(
224 gui,
225 tr("Please select the row to delete."),
226 tr("Warning"),
227 JOptionPane.WARNING_MESSAGE
228 );
229 return;
230 }
231 for(int row: list.getSelectedRows()) {
232 data.put((String) model.getValueAt(row, 0), "");
233 model.setValueAt("", row, 1);
234 }
235 }
236
237 private void addPreference(final PreferenceTabbedPane gui) {
238 String s[] = showEditDialog(gui, tr("Enter a new key/value pair"),
239 "", "");
240 if(s != null && !s[0].isEmpty() && !s[1].isEmpty()) {
241 data.put(s[0], s[1]);
242 dataToModel();
243 }
244 }
245
246 private void editPreference(final PreferenceTabbedPane gui, final JTable list) {
247 if (list.getSelectedRowCount() != 1) {
248 JOptionPane.showMessageDialog(
249 gui,
250 tr("Please select the row to edit."),
251 tr("Warning"),
252 JOptionPane.WARNING_MESSAGE
253 );
254 return;
255 }
256 String key = (String)model.getValueAt(list.getSelectedRow(), 0);
257 String value = data.get(key);
258 if(value.isEmpty())
259 value = defaults.get(key);
260 String s[] = showEditDialog(gui, tr("Change a key/value pair"),
261 key, value);
262 if(s != null && !s[0].isEmpty()) {
263 data.put(s[0], s[1]);
264 if(!s[0].equals(key))
265 data.put(key,"");
266 dataToModel();
267 }
268 }
269
270 private String[] showEditDialog(final PreferenceTabbedPane gui, String title,
271 String key, String value) {
272 JPanel p = new JPanel(new GridBagLayout());
273 p.add(new JLabel(tr("Key")), GBC.std().insets(0,0,5,0));
274 JTextField tkey = new JTextField(key, 50);
275 JTextField tvalue = new JTextField(value, 50);
276 p.add(tkey, GBC.eop().insets(5,0,0,0).fill(GBC.HORIZONTAL));
277 PrefValueTableModel model = new PrefValueTableModel(value);
278 p.add(new JLabel(tr("Values")), GBC.std().insets(0,0,5,0));
279 JTable table = new JTable(model);
280 table.putClientProperty("terminateEditOnFocusLost", true);
281 table.getTableHeader().setVisible(false);
282 JScrollPane pane = new JScrollPane(table);
283 Dimension d = pane.getPreferredSize();
284 d.height = (d.height/20)*(model.getRowCount()+4);
285 pane.setPreferredSize(d);
286 p.add(pane, GBC.eol().insets(5,10,0,0).fill(GBC.HORIZONTAL));
287 ExtendedDialog ed = new ExtendedDialog(gui, title,
288 new String[] {tr("OK"), tr("Cancel")});
289 ed.setButtonIcons(new String[] {"ok.png", "cancel.png"});
290 ed.setContent(p);
291 ed.showDialog();
292 if(ed.getValue() == 1) {
293 return new String[]{tkey.getText(), model.getText()};
294 }
295 return null;
296 }
297 class PrefValueTableModel extends DefaultTableModel {
298 private final ArrayList<String> data = new ArrayList<String>();
299 public PrefValueTableModel(String val) {
300 data.addAll(Arrays.asList(val.split("\u001e")));
301 setColumnIdentifiers(new String[]{""});
302 }
303
304 public String getText() {
305 String s = null;
306 for(String a : data)
307 {
308 if(s == null) {
309 s = a;
310 } else {
311 s += "\u001e" + a;
312 }
313 }
314 return s == null ? "" : s;
315 }
316
317 @Override
318 public int getRowCount() {
319 return data == null ? 1 : data.size()+1;
320 }
321
322 @Override
323 public Object getValueAt(int row, int column) {
324 return data.size() == row ? "" : data.get(row);
325 }
326
327 @Override
328 public void setValueAt(Object o, int row, int column) {
329 String s = (String)o;
330 if(row == data.size()) {
331 data.add(s);
332 fireTableRowsInserted(row+1, row+1);
333 } else {
334 data.set(row, s);
335 }
336 fireTableCellUpdated(row, column);
337 }
338
339 @Override
340 public boolean isCellEditable(int row, int column) {
341 return true;
342 }
343 }
344}
Note: See TracBrowser for help on using the repository browser.