package org.limewire.ui.swing.options; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.io.IOException; import javax.swing.ButtonGroup; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JRadioButton; import com.google.inject.Inject; import net.miginfocom.swing.MigLayout; import org.limewire.core.api.network.NetworkManager; import org.limewire.core.settings.ConnectionSettings; import org.limewire.core.settings.NetworkSettings; import org.limewire.ui.swing.components.FocusJOptionPane; import org.limewire.ui.swing.components.MultiLineLabel; import org.limewire.ui.swing.components.NumericTextField; import org.limewire.ui.swing.util.I18n; /** * Firewall Option Panel. */ public class FirewallOptionPanel extends OptionPanel { private NetworkManager networkManager; private ListeningPortPanel listeningPortPanel; private RouterConfigPanel routerConfigPanel; @Inject public FirewallOptionPanel(NetworkManager networkManager) { super(); this.networkManager = networkManager; setLayout(new MigLayout("insets 10 10 10 10, fillx, wrap", "", "")); setOpaque(false); add(getListeningPortPanel(), "pushx, growx"); add(getRouterConfigPanel(), "pushx, growx"); } private OptionPanel getListeningPortPanel() { if(listeningPortPanel == null) { listeningPortPanel = new ListeningPortPanel(); } return listeningPortPanel; } private OptionPanel getRouterConfigPanel() { if(routerConfigPanel == null) { routerConfigPanel = new RouterConfigPanel(); } return routerConfigPanel; } @Override boolean applyOptions() { boolean restart = getListeningPortPanel().applyOptions(); restart |= getRouterConfigPanel().applyOptions(); return restart; } @Override boolean hasChanged() { return getListeningPortPanel().hasChanged() || getRouterConfigPanel().hasChanged(); } @Override public void initOptions() { getListeningPortPanel().initOptions(); getRouterConfigPanel().initOptions(); } private class ListeningPortPanel extends OptionPanel { private final String description = I18n.tr("You can set the local network port that listens for incoming connections. This port may be changed in case of conflict with another program or if a specific port number is required for direct incoming connections by your firewall."); private NumericTextField portField; private int port; public ListeningPortPanel() { super(I18n.tr("Listening Port")); portField = new NumericTextField(5, 1, 0xFFFF); add(new MultiLineLabel(description, ReallyAdvancedOptionPanel.MULTI_LINE_LABEL_WIDTH), "wrap"); add(new JLabel(I18n.tr("Listen on port:")), "split"); add(portField); } @Override boolean applyOptions() { int newPort = portField.getValue(port); if(newPort != port) { try { NetworkSettings.PORT.setValue(newPort); networkManager.setListeningPort(newPort); port = newPort; networkManager.portChanged(); } catch(IOException ioe) { FocusJOptionPane.showMessageDialog(FirewallOptionPanel.this, I18n.tr("The port chosen {0}, is already in use.", newPort), I18n.tr("Network Port Error"), JOptionPane.ERROR_MESSAGE); NetworkSettings.PORT.setValue(port); portField.setValue(port); } } return false; } @Override boolean hasChanged() { int portSetting = NetworkSettings.PORT.getValue(); return portSetting != portField.getValue(portSetting); } @Override public void initOptions() { port = NetworkSettings.PORT.getValue(); portField.setValue(port); } } private class RouterConfigPanel extends OptionPanel { private final String description = I18n.tr("Using Universal Plug n' Play, LimeWire can automatically configure your router or firewall for optimal performance. If your router does not support Universal Plug n' Play, LimeWire can be set to advertise an external port manually."); private final JRadioButton plugAndPlayRadioButton; private final JRadioButton portForwardRadioButton; private final NumericTextField portTextField; private final JLabel starLabel; private final JRadioButton doNothingRadioButton; private final ButtonGroup buttonGroup; public RouterConfigPanel() { super(I18n.tr("Router Configuration")); plugAndPlayRadioButton = new JRadioButton(I18n.tr("Use Universal Plug n' Play (Recommended)")); portForwardRadioButton = new JRadioButton(I18n.tr("Manual Port Forward:")); doNothingRadioButton = new JRadioButton(I18n.tr("Do Nothing")); plugAndPlayRadioButton.setOpaque(false); portForwardRadioButton.setOpaque(false); doNothingRadioButton.setOpaque(false); buttonGroup = new ButtonGroup(); buttonGroup.add(plugAndPlayRadioButton); buttonGroup.add(portForwardRadioButton); buttonGroup.add(doNothingRadioButton); portTextField = new NumericTextField(5, 1, 0xFFFF); starLabel = new JLabel(I18n.tr("* You must also configure your router")); starLabel.setVisible(false); add(new MultiLineLabel(description, ReallyAdvancedOptionPanel.MULTI_LINE_LABEL_WIDTH), "wrap"); add(plugAndPlayRadioButton, "split, wrap"); add(portForwardRadioButton, "split"); add(portTextField,"split"); add(starLabel, "wrap"); add(doNothingRadioButton, "split"); portForwardRadioButton.addItemListener(new ItemListener(){ @Override public void itemStateChanged(ItemEvent e) { updateTextField(); } }); } @Override boolean applyOptions() { boolean restart = false; boolean oldUPNP = ConnectionSettings.DISABLE_UPNP.getValue(); int oldPort = ConnectionSettings.FORCED_PORT.getValue(); boolean oldForce = ConnectionSettings.FORCE_IP_ADDRESS.getValue(); if(plugAndPlayRadioButton.isSelected()) { if(!ConnectionSettings.UPNP_IN_USE.getValue()) { ConnectionSettings.FORCE_IP_ADDRESS.setValue(false); } ConnectionSettings.DISABLE_UPNP.setValue(false); if(oldUPNP || oldForce) { restart = true; } } else if(doNothingRadioButton.isSelected()) { ConnectionSettings.FORCE_IP_ADDRESS.setValue(false); ConnectionSettings.DISABLE_UPNP.setValue(true); } else { // PORT.isSelected() int forcedPort = portTextField.getValue(oldPort); ConnectionSettings.DISABLE_UPNP.setValue(false); ConnectionSettings.FORCE_IP_ADDRESS.setValue(true); ConnectionSettings.UPNP_IN_USE.setValue(false); ConnectionSettings.FORCED_PORT.setValue(forcedPort); } // Notify that the address changed if: // 1) The 'forced address' status changed. // or 2) We're forcing and the ports are different. boolean newForce = ConnectionSettings.FORCE_IP_ADDRESS.getValue(); int newPort = ConnectionSettings.FORCED_PORT.getValue(); if(oldForce != newForce) networkManager.addressChanged(); if(newForce && (oldPort != newPort)) networkManager.portChanged(); return restart; } @Override boolean hasChanged() { if(ConnectionSettings.FORCE_IP_ADDRESS.getValue() && !ConnectionSettings.UPNP_IN_USE.getValue()) { if (!portForwardRadioButton.isSelected()) return true; } else if(ConnectionSettings.DISABLE_UPNP.getValue()) { if (!doNothingRadioButton.isSelected()) return true; } else { if (!plugAndPlayRadioButton.isSelected()) return true; } int forcedPortSetting = ConnectionSettings.FORCED_PORT.getValue(); return portForwardRadioButton.isSelected() && portTextField.getValue(forcedPortSetting) != forcedPortSetting; } @Override public void initOptions() { if(ConnectionSettings.FORCE_IP_ADDRESS.getValue() && !ConnectionSettings.UPNP_IN_USE.getValue()) portForwardRadioButton.setSelected(true); else if(ConnectionSettings.DISABLE_UPNP.getValue()) doNothingRadioButton.setSelected(true); else plugAndPlayRadioButton.setSelected(true); portTextField.setValue(ConnectionSettings.FORCED_PORT.getValue()); updateTextField(); } private void updateTextField() { portTextField.setEnabled(portForwardRadioButton.isSelected()); portTextField.setEditable(portForwardRadioButton.isSelected()); starLabel.setVisible(portForwardRadioButton.isSelected()); } } }