package net.i2p.desktopgui;
import java.awt.Desktop;
import java.awt.Desktop.Action;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.SwingWorker;
import net.i2p.data.DataHelper;
import net.i2p.desktopgui.router.RouterManager;
import net.i2p.desktopgui.util.BrowseException;
import net.i2p.desktopgui.util.I2PDesktop;
import net.i2p.router.RouterContext;
import net.i2p.util.Log;
import net.i2p.util.PortMapper;
import net.i2p.util.Translate;
/**
* java -cp i2p.jar:router.jar:desktopgui.jar net.i2p.desktopgui.Main
*
* Full access to router context.
*/
class InternalTrayManager extends TrayManager {
private final RouterContext _context;
private final Log log;
private MenuItem _statusItem, _browserItem, _configItem, _restartItem, _stopItem,
_restartHardItem, _stopHardItem, _cancelItem;
private JMenuItem _jstatusItem, _jbrowserItem, _jconfigItem, _jrestartItem, _jstopItem,
_jrestartHardItem, _jstopHardItem, _jcancelItem;
private static final boolean CONSOLE_ENABLED = Desktop.isDesktopSupported() &&
Desktop.getDesktop().isSupported(Action.BROWSE);
private static final String CONSOLE_BUNDLE_NAME = "net.i2p.router.web.messages";
public InternalTrayManager(RouterContext ctx, Main main, boolean useSwing) {
super(ctx, main, useSwing);
_context = ctx;
log = ctx.logManager().getLog(InternalTrayManager.class);
}
public synchronized PopupMenu getMainMenu() {
PopupMenu popup = new PopupMenu();
final MenuItem statusItem = new MenuItem("");
final MenuItem browserLauncher;
if (CONSOLE_ENABLED) {
browserLauncher = new MenuItem(_t("Launch I2P Browser"));
browserLauncher.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
return null;
}
@Override
protected void done() {
launchBrowser();
}
}.execute();
}
});
} else {
browserLauncher = null;
}
PopupMenu desktopguiConfigurationLauncher = new PopupMenu(_t("Configure I2P System Tray"));
MenuItem configSubmenu = new MenuItem(_t("Disable"));
configSubmenu.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
configureDesktopgui(false);
return null;
}
}.execute();
}
});
final MenuItem restartItem;
if (_context.hasWrapper()) {
restartItem = new MenuItem(_t("Restart I2P"));
restartItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
RouterManager.restartGracefully(_context);
return null;
}
}.execute();
}
});
} else {
restartItem = null;
}
final MenuItem stopItem = new MenuItem(_t("Stop I2P"));
stopItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
RouterManager.shutDownGracefully(_context);
return null;
}
}.execute();
}
});
final MenuItem restartItem2;
if (_context.hasWrapper()) {
restartItem2 = new MenuItem(_t("Restart I2P Immediately"));
restartItem2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
RouterManager.restart(_context);
return null;
}
}.execute();
}
});
} else {
restartItem2 = null;
}
final MenuItem stopItem2 = new MenuItem(_t("Stop I2P Immediately"));
stopItem2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
RouterManager.shutDown(_context);
return null;
}
}.execute();
}
});
final MenuItem cancelItem = new MenuItem(_t("Cancel I2P Shutdown"));
cancelItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
RouterManager.cancelShutdown(_context);
return null;
}
}.execute();
}
});
popup.add(statusItem);
popup.addSeparator();
if (CONSOLE_ENABLED) {
popup.add(browserLauncher);
popup.addSeparator();
}
desktopguiConfigurationLauncher.add(configSubmenu);
popup.add(desktopguiConfigurationLauncher);
popup.addSeparator();
if (_context.hasWrapper())
popup.add(restartItem);
popup.add(stopItem);
if (_context.hasWrapper())
popup.add(restartItem2);
popup.add(stopItem2);
popup.add(cancelItem);
_statusItem = statusItem;
_browserItem = browserLauncher;
_configItem = desktopguiConfigurationLauncher;
_restartItem = restartItem;
_stopItem = stopItem;
_restartHardItem = restartItem2;
_stopHardItem = stopItem2;
_cancelItem = cancelItem;
return popup;
}
public synchronized JPopupMenu getSwingMainMenu() {
JPopupMenu popup = new JPopupMenu();
final JMenuItem statusItem = new JMenuItem("");
final JMenuItem browserLauncher;
if (CONSOLE_ENABLED) {
browserLauncher = new JMenuItem(_t("Launch I2P Browser"));
browserLauncher.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
return null;
}
@Override
protected void done() {
launchBrowser();
}
}.execute();
}
});
} else {
browserLauncher = null;
}
JMenu desktopguiConfigurationLauncher = new JMenu(_t("Configure I2P System Tray"));
JMenuItem configSubmenu = new JMenuItem(_t("Disable"));
configSubmenu.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
configureDesktopgui(false);
return null;
}
}.execute();
}
});
final JMenuItem restartItem;
if (_context.hasWrapper()) {
restartItem = new JMenuItem(_t("Restart I2P"));
restartItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
RouterManager.restartGracefully(_context);
return null;
}
}.execute();
}
});
} else {
restartItem = null;
}
final JMenuItem stopItem = new JMenuItem(_t("Stop I2P"));
stopItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
RouterManager.shutDownGracefully(_context);
return null;
}
}.execute();
}
});
final JMenuItem restartItem2;
if (_context.hasWrapper()) {
restartItem2 = new JMenuItem(_t("Restart I2P Immediately"));
restartItem2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
RouterManager.restart(_context);
return null;
}
}.execute();
}
});
} else {
restartItem2 = null;
}
final JMenuItem stopItem2 = new JMenuItem(_t("Stop I2P Immediately"));
stopItem2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
RouterManager.shutDown(_context);
return null;
}
}.execute();
}
});
final JMenuItem cancelItem = new JMenuItem(_t("Cancel I2P Shutdown"));
cancelItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
RouterManager.cancelShutdown(_context);
return null;
}
}.execute();
}
});
popup.add(statusItem);
popup.addSeparator();
if (CONSOLE_ENABLED) {
popup.add(browserLauncher);
popup.addSeparator();
}
desktopguiConfigurationLauncher.add(configSubmenu);
popup.add(desktopguiConfigurationLauncher);
popup.addSeparator();
if (_context.hasWrapper())
popup.add(restartItem);
popup.add(stopItem);
if (_context.hasWrapper())
popup.add(restartItem2);
popup.add(stopItem2);
popup.add(cancelItem);
_jstatusItem = statusItem;
_jbrowserItem = browserLauncher;
_jconfigItem = desktopguiConfigurationLauncher;
_jrestartItem = restartItem;
_jstopItem = stopItem;
_jrestartHardItem = restartItem2;
_jstopHardItem = stopItem2;
_jcancelItem = cancelItem;
return popup;
}
/**
* Update the menu
* @since 0.9.26
*/
protected synchronized void updateMenu() {
boolean x = RouterManager.isShutdownInProgress(_context);
boolean imminent = false;
String status;
if (x) {
long time = RouterManager.getShutdownTimeRemaining(_context);
if (time > 5000) {
status = _t("Shutdown in {0}", DataHelper.formatDuration2(time).replace(" ", " "));
} else {
status = _t("Shutdown imminent");
imminent = true;
}
} else {
// status translations are in the console bundle
status = _t("Network") + ": " +
Translate.getString(RouterManager.getStatus(_context), _context, CONSOLE_BUNDLE_NAME);
}
PopupMenu awt = trayIcon.getPopupMenu();
if (awt != null) {
MenuItem item = awt.getItem(0);
String oldStatus = item.getLabel();
if (!status.equals(oldStatus))
item.setLabel(status);
}
if (_browserItem != null)
_browserItem.setEnabled(!imminent);
if (_configItem != null)
_configItem.setEnabled(!imminent);
if (_restartItem != null)
_restartItem.setEnabled(!x);
if (_stopItem != null)
_stopItem.setEnabled(!x);
if (_restartHardItem != null)
_restartHardItem.setEnabled(!imminent);
if (_stopHardItem != null)
_stopHardItem.setEnabled(!imminent);
if (_cancelItem != null)
_cancelItem.setEnabled(x && !imminent);
if (_jstatusItem != null)
_jstatusItem.setText(status);
if (_jbrowserItem != null)
_jbrowserItem.setVisible(!imminent);
if (_jconfigItem != null)
_jconfigItem.setVisible(!imminent);
if (_jrestartItem != null)
_jrestartItem.setVisible(!x);
if (_jstopItem != null)
_jstopItem.setVisible(!x);
if (_jrestartHardItem != null)
_jrestartHardItem.setVisible(!imminent);
if (_jstopHardItem != null)
_jstopHardItem.setVisible(!imminent);
if (_jcancelItem != null)
_jcancelItem.setVisible(x && !imminent);
}
/**
* @since 0.9.26 from removed gui/DesktopguiConfigurationFrame
*/
private void configureDesktopgui(boolean enable) {
String property = Main.PROP_ENABLE;
String value = Boolean.toString(enable);
try {
_context.router().saveConfig(property, value);
if (!enable) {
// TODO popup that explains how to re-enable in console
_main.shutdown(null);
}
} catch (Exception ex) {
log.error("Error saving config", ex);
}
}
/**
* Build the console URL with info from the port mapper,
* and launch the browser at it.
*
* Modified from I2PTunnelHTTPClientBase.
* TODO perhaps move this to a new PortMapper method.
*
* @since 0.9.26
*/
private void launchBrowser() {
String unset = "*unset*";
PortMapper pm = _context.portMapper();
String httpHost = pm.getActualHost(PortMapper.SVC_CONSOLE, unset);
String httpsHost = pm.getActualHost(PortMapper.SVC_HTTPS_CONSOLE, unset);
int httpPort = pm.getPort(PortMapper.SVC_CONSOLE, 7657);
int httpsPort = pm.getPort(PortMapper.SVC_HTTPS_CONSOLE, -1);
boolean httpsOnly = httpsPort > 0 && httpHost.equals(unset) && !httpsHost.equals(unset);
String url;
if (httpsOnly) {
url = "https://" + httpsHost + ':' + httpsPort + '/';
} else {
if (httpHost.equals(unset))
httpHost = "127.0.0.1";
url = "http://" + httpHost + ':' + httpPort + '/';
}
try {
I2PDesktop.browse(url);
} catch (BrowseException e1) {
log.log(Log.WARN, "Failed to open browser!", e1);
}
}
}