// License: GPL. Copyright 2007 by Immanuel Scholz and others package org.openstreetmap.josm.gui.preferences; import static org.openstreetmap.josm.tools.I18n.tr; import java.awt.Component; import java.awt.Dimension; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.Map; import java.util.TreeMap; import java.util.TreeSet; import java.util.Map.Entry; import javax.swing.Box; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JTextField; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableModel; import org.openstreetmap.josm.Main; import org.openstreetmap.josm.tools.GBC; public class AdvancedPreference implements PreferenceSetting { public static class Factory implements PreferenceSettingFactory { public PreferenceSetting createPreferenceSetting() { return new AdvancedPreference(); } } private Map<String,String> orig; private Map<String,String> defaults; private DefaultTableModel model; protected Map<String, String> data; protected JTextField txtFilter; public void addGui(final PreferenceTabbedPane gui) { JPanel p = gui.createPreferenceTab("advanced", tr("Advanced Preferences"), tr("Setting Preference entries directly. Use with caution!"), false); txtFilter = new JTextField(); JLabel lbFilter = new JLabel(tr("Search: ")); lbFilter.setLabelFor(txtFilter); p.add(lbFilter); p.add(txtFilter, GBC.eol().fill(GBC.HORIZONTAL)); txtFilter.getDocument().addDocumentListener(new DocumentListener(){ public void changedUpdate(DocumentEvent e) { action(); } public void insertUpdate(DocumentEvent e) { action(); } public void removeUpdate(DocumentEvent e) { action(); } private void action() { dataToModel(); } }); model = new DefaultTableModel(new String[]{tr("Key"), tr("Value")},0) { @Override public boolean isCellEditable(int row, int column) { return column != 0; } @Override public void fireTableCellUpdated(int row, int column) { super.fireTableCellUpdated(row, column); if(column == 1) { data.put((String) model.getValueAt(row, 0), (String) model.getValueAt(row, 1)); } } }; DefaultTableCellRenderer renderer = new DefaultTableCellRenderer(){ @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { JLabel label=new JLabel(); String s = defaults.get(value); if(s != null) { if(s.equals(model.getValueAt(row, 1))) { label.setToolTipText(tr("Current value is default.")); } else { label.setToolTipText(tr("Default value is ''{0}''.", s)); } } else { label.setToolTipText(tr("Default value currently unknown (setting has not been used yet).")); } label.setText((String)value); return label; } }; final JTable list = new JTable(model); list.putClientProperty("terminateEditOnFocusLost", true); list.getColumn(tr("Key")).setCellRenderer(renderer); JScrollPane scroll = new JScrollPane(list); p.add(scroll, GBC.eol().fill(GBC.BOTH)); scroll.setPreferredSize(new Dimension(400,200)); orig = Main.pref.getAllPrefix(""); defaults = Main.pref.getDefaults(); orig.remove("osm-server.password"); defaults.remove("osm-server.password"); prepareData(); dataToModel(); JButton add = new JButton(tr("Add")); p.add(Box.createHorizontalGlue(), GBC.std().fill(GBC.HORIZONTAL)); p.add(add, GBC.std().insets(0,5,0,0)); add.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { addPreference(gui); } }); JButton edit = new JButton(tr("Edit")); p.add(edit, GBC.std().insets(5,5,5,0)); edit.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { editPreference(gui, list); } }); JButton delete = new JButton(tr("Delete")); p.add(delete, GBC.std().insets(0,5,0,0)); delete.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { removePreference(gui, list); } }); list.addMouseListener(new MouseAdapter(){ @Override public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 2) { editPreference(gui, list); } } }); } private void prepareData() { TreeSet<String> ts = new TreeSet<String>(orig.keySet()); for (String s : defaults.keySet()) { if(!ts.contains(s)) { ts.add(s); } } data = new TreeMap<String, String>(); for (String s : ts) { String val = Main.pref.get(s); if(val == null) { val = ""; } data.put(s, val); } } private void dataToModel() { while (model.getRowCount() > 0) { model.removeRow(0); } for (String prefKey : data.keySet()) { String prefValue = data.get(prefKey); String input[] = txtFilter.getText().split("\\s+"); boolean canHas = true; // Make 'wmsplugin cache' search for e.g. 'cache.wmsplugin' for (String bit : input) { if (!prefKey.contains(bit) && !prefValue.contains(bit)) { canHas = false; } } if (canHas) { model.addRow(new String[] {prefKey, prefValue}); } } } public boolean ok() { for (String key : data.keySet()) { String value = data.get(key); if(value.length() != 0) { String origValue = orig.get(key); if (origValue == null || !origValue.equals(value)) { Main.pref.put(key, value); } orig.remove(key); // processed. } } for (Entry<String, String> e : orig.entrySet()) { Main.pref.put(e.getKey(), null); } return false; } private void editPreference(final PreferenceTabbedPane gui, final JTable list) { if (list.getSelectedRowCount() != 1) { JOptionPane.showMessageDialog( gui, tr("Please select the row to edit."), tr("Warning"), JOptionPane.WARNING_MESSAGE ); return; } String v = (String) JOptionPane.showInputDialog( Main.parent, tr("New value for {0}", model.getValueAt(list.getSelectedRow(), 0)), tr("New value"), JOptionPane.QUESTION_MESSAGE, null, null, model.getValueAt(list.getSelectedRow(), 1) ); if (v != null) { data.put((String) model.getValueAt(list.getSelectedRow(), 0), v); model.setValueAt(v, list.getSelectedRow(), 1); } } private void removePreference(final PreferenceTabbedPane gui, final JTable list) { if (list.getSelectedRowCount() == 0) { JOptionPane.showMessageDialog( gui, tr("Please select the row to delete."), tr("Warning"), JOptionPane.WARNING_MESSAGE ); return; } for(int row: list.getSelectedRows()) { data.put((String) model.getValueAt(row, 0), ""); model.setValueAt("", row, 1); } } private void addPreference(final PreferenceTabbedPane gui) { JPanel p = new JPanel(new GridBagLayout()); p.add(new JLabel(tr("Key")), GBC.std().insets(0,0,5,0)); JTextField key = new JTextField(10); JTextField value = new JTextField(10); p.add(key, GBC.eop().insets(5,0,0,0).fill(GBC.HORIZONTAL)); p.add(new JLabel(tr("Value")), GBC.std().insets(0,0,5,0)); p.add(value, GBC.eol().insets(5,0,0,0).fill(GBC.HORIZONTAL)); int answer = JOptionPane.showConfirmDialog( gui, p, tr("Enter a new key/value pair"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE ); if (answer == JOptionPane.OK_OPTION) { data.put(key.getText(), value.getText()); model.addRow(new String[]{key.getText(), value.getText()}); } } }