001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.preferences.remotecontrol; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.awt.Color; 007import java.awt.Font; 008import java.awt.GridBagLayout; 009import java.awt.event.ActionListener; 010import java.util.LinkedHashMap; 011import java.util.Map; 012import java.util.Map.Entry; 013 014import javax.swing.BorderFactory; 015import javax.swing.Box; 016import javax.swing.JCheckBox; 017import javax.swing.JLabel; 018import javax.swing.JPanel; 019import javax.swing.JSeparator; 020 021import org.openstreetmap.josm.gui.help.HelpUtil; 022import org.openstreetmap.josm.gui.preferences.DefaultTabPreferenceSetting; 023import org.openstreetmap.josm.gui.preferences.PreferenceSetting; 024import org.openstreetmap.josm.gui.preferences.PreferenceSettingFactory; 025import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane; 026import org.openstreetmap.josm.gui.util.GuiHelper; 027import org.openstreetmap.josm.gui.widgets.VerticallyScrollablePanel; 028import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault; 029import org.openstreetmap.josm.io.remotecontrol.RemoteControl; 030import org.openstreetmap.josm.io.remotecontrol.handler.RequestHandler; 031import org.openstreetmap.josm.spi.preferences.Config; 032import org.openstreetmap.josm.tools.GBC; 033 034/** 035 * Preference settings for Remote Control. 036 * 037 * @author Frederik Ramm 038 */ 039public final class RemoteControlPreference extends DefaultTabPreferenceSetting { 040 041 /** 042 * Factory used to build a new instance of this preference setting 043 */ 044 public static class Factory implements PreferenceSettingFactory { 045 046 @Override 047 public PreferenceSetting createPreferenceSetting() { 048 return new RemoteControlPreference(); 049 } 050 } 051 052 private RemoteControlPreference() { 053 super(/* ICON(preferences/) */ "remotecontrol", tr("Remote Control"), tr("Settings for the remote control feature.")); 054 for (PermissionPrefWithDefault p : PermissionPrefWithDefault.getPermissionPrefs()) { 055 JCheckBox cb = new JCheckBox(p.preferenceText); 056 cb.setSelected(p.isAllowed()); 057 prefs.put(p, cb); 058 } 059 } 060 061 private final Map<PermissionPrefWithDefault, JCheckBox> prefs = new LinkedHashMap<>(); 062 private JCheckBox enableRemoteControl; 063 064 private final JCheckBox loadInNewLayer = new JCheckBox(tr("Download as new layer")); 065 private final JCheckBox alwaysAskUserConfirm = new JCheckBox(tr("Confirm all Remote Control actions manually")); 066 067 @Override 068 public void addGui(final PreferenceTabbedPane gui) { 069 070 JPanel remote = new VerticallyScrollablePanel(new GridBagLayout()); 071 072 final JLabel descLabel = new JLabel("<html>" 073 + tr("Allows JOSM to be controlled from other applications, e.g. from a web browser.") 074 + "</html>"); 075 descLabel.setFont(descLabel.getFont().deriveFont(Font.PLAIN)); 076 remote.add(descLabel, GBC.eol().insets(5, 5, 0, 10).fill(GBC.HORIZONTAL)); 077 078 final JLabel portLabel = new JLabel("<html>" 079 + tr("JOSM will always listen at <b>port {0}</b> (http) on localhost." 080 + "<br>This port is not configurable because it is referenced by external applications talking to JOSM.", 081 Config.getPref().get("remote.control.port", "8111")) + "</html>"); 082 portLabel.setFont(portLabel.getFont().deriveFont(Font.PLAIN)); 083 remote.add(portLabel, GBC.eol().insets(5, 5, 0, 10).fill(GBC.HORIZONTAL)); 084 085 enableRemoteControl = new JCheckBox(tr("Enable remote control"), RemoteControl.PROP_REMOTECONTROL_ENABLED.get()); 086 remote.add(enableRemoteControl, GBC.eol()); 087 088 final JPanel wrapper = new JPanel(new GridBagLayout()); 089 wrapper.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.gray))); 090 091 remote.add(wrapper, GBC.eol().fill(GBC.HORIZONTAL).insets(5, 5, 5, 5)); 092 093 wrapper.add(new JSeparator(), GBC.eop().fill(GBC.HORIZONTAL).insets(15, 5, 15, 5)); 094 095 wrapper.add(new JLabel(tr("Permitted actions:")), GBC.eol().insets(5, 0, 0, 0)); 096 for (JCheckBox p : prefs.values()) { 097 wrapper.add(p, GBC.eol().insets(15, 5, 0, 0).fill(GBC.HORIZONTAL)); 098 } 099 100 wrapper.add(new JSeparator(), GBC.eop().fill(GBC.HORIZONTAL).insets(15, 5, 15, 5)); 101 wrapper.add(loadInNewLayer, GBC.eol().fill(GBC.HORIZONTAL)); 102 wrapper.add(alwaysAskUserConfirm, GBC.eol().fill(GBC.HORIZONTAL)); 103 104 remote.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.VERTICAL)); 105 106 loadInNewLayer.setSelected(Config.getPref().getBoolean( 107 RequestHandler.loadInNewLayerKey, RequestHandler.loadInNewLayerDefault)); 108 alwaysAskUserConfirm.setSelected(Config.getPref().getBoolean( 109 RequestHandler.globalConfirmationKey, RequestHandler.globalConfirmationDefault)); 110 111 ActionListener remoteControlEnabled = e -> GuiHelper.setEnabledRec(wrapper, enableRemoteControl.isSelected()); 112 enableRemoteControl.addActionListener(remoteControlEnabled); 113 remoteControlEnabled.actionPerformed(null); 114 createPreferenceTabWithScrollPane(gui, remote); 115 } 116 117 @Override 118 public boolean ok() { 119 boolean enabled = enableRemoteControl.isSelected(); 120 boolean changed = RemoteControl.PROP_REMOTECONTROL_ENABLED.put(enabled); 121 if (enabled) { 122 for (Entry<PermissionPrefWithDefault, JCheckBox> p : prefs.entrySet()) { 123 Config.getPref().putBoolean(p.getKey().pref, p.getValue().isSelected()); 124 } 125 Config.getPref().putBoolean(RequestHandler.loadInNewLayerKey, loadInNewLayer.isSelected()); 126 Config.getPref().putBoolean(RequestHandler.globalConfirmationKey, alwaysAskUserConfirm.isSelected()); 127 } 128 if (changed) { 129 if (enabled) { 130 RemoteControl.start(); 131 } else { 132 RemoteControl.stop(); 133 } 134 } 135 return false; 136 } 137 138 @Override 139 public String getHelpContext() { 140 return HelpUtil.ht("/Preferences/RemoteControl"); 141 } 142}