From 76ab673808ebdf525e0dbbab41445d2e6784d206 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Sat, 24 May 2008 18:43:42 +0200 Subject: [PATCH] rework node connection menus add node icons in status bar --- src/net/pterodactylus/jsite/gui/MainWindow.java | 112 +++++------ .../pterodactylus/jsite/gui/SwingInterface.java | 214 +++++++-------------- src/net/pterodactylus/jsite/i18n/jSite.properties | 9 + .../pterodactylus/jsite/i18n/jSite_de.properties | 9 + 4 files changed, 147 insertions(+), 197 deletions(-) diff --git a/src/net/pterodactylus/jsite/gui/MainWindow.java b/src/net/pterodactylus/jsite/gui/MainWindow.java index f582bb2..6a6e035 100644 --- a/src/net/pterodactylus/jsite/gui/MainWindow.java +++ b/src/net/pterodactylus/jsite/gui/MainWindow.java @@ -28,29 +28,33 @@ import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.util.HashMap; +import java.util.Map; import java.util.Timer; import java.util.TimerTask; import java.util.logging.Logger; -import javax.swing.Action; import javax.swing.Box; import javax.swing.BoxLayout; +import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JFrame; +import javax.swing.JMenu; import javax.swing.JMenuBar; -import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JTabbedPane; import javax.swing.JToolBar; import javax.swing.SwingConstants; import javax.swing.border.EmptyBorder; +import net.pterodactylus.jsite.core.Node; import net.pterodactylus.jsite.i18n.I18n; import net.pterodactylus.jsite.i18n.I18nable; import net.pterodactylus.jsite.i18n.gui.I18nAction; import net.pterodactylus.jsite.i18n.gui.I18nMenu; import net.pterodactylus.jsite.main.Version; import net.pterodactylus.jsite.project.Project; +import net.pterodactylus.util.image.IconLoader; import net.pterodactylus.util.logging.Logging; import net.pterodactylus.util.swing.StatusBar; import net.pterodactylus.util.swing.SwingUtils; @@ -82,6 +86,15 @@ public class MainWindow extends JFrame implements WindowListener, I18nable, Prop /** Delay (in seconds) after which to clear status bar. */ private int statusBarClearDelay = 5000; + /** The icon for offline nodes. */ + private Icon offlineIcon; + + /** The icon for online nodes. */ + private Icon onlineIcon; + + /** The icon for error nodes. */ + private Icon errorIcon; + /** The content pane. */ private JPanel contentPane = new JPanel(new BorderLayout(12, 12)); @@ -91,18 +104,6 @@ public class MainWindow extends JFrame implements WindowListener, I18nable, Prop /** The node menu. */ private I18nMenu nodeMenu; - /** The “connect” (advanced mode) menu. */ - private I18nMenu connectMenu; - - /** The “connect” (simple mode) menu. */ - private JMenuItem connectMenuItem; - - /** The “disconnect” (advanced mode) menu. */ - private I18nMenu disconnectMenu; - - /** The “diconnect” (simple mode) menu item. */ - private JMenuItem disconnectMenuItem; - /** The language menu. */ private I18nMenu languageMenu; @@ -115,6 +116,12 @@ public class MainWindow extends JFrame implements WindowListener, I18nable, Prop /** The project overview panel. */ private Box projectOverviewPanel; + /** Maps from node to menus. */ + private final Map nodeMenus = new HashMap(); + + /** Maps from nodes to node panels. */ + private final Map nodeLabels = new HashMap(); + /** * Creates a new main window that redirects all actions to the given swing * interface. @@ -189,10 +196,7 @@ public class MainWindow extends JFrame implements WindowListener, I18nable, Prop * false if the simple mode is activated */ public void setAdvancedMode(boolean advancedMode) { - connectMenu.setVisible(advancedMode); - connectMenuItem.setVisible(!advancedMode); - disconnectMenu.setVisible(advancedMode); - disconnectMenuItem.setVisible(!advancedMode); + /* doesn’t do anything right now. */ } /** @@ -217,27 +221,31 @@ public class MainWindow extends JFrame implements WindowListener, I18nable, Prop // /** - * Refreshes the menu items in the “connect” and “disconnect” menus. + * Adds a node to the menu. + * + * @param node + * The node to add */ - void refreshNodeMenuItems() { - connectMenu.removeAll(); - for (Action nodeConnectAction: swingInterface.getNodeConnectActions()) { - connectMenu.add(nodeConnectAction); - } - if (connectMenu.getMenuComponentCount() == 0) { - JMenuItem noNodeAvailableItem = new JMenuItem(I18n.get("mainWindow.menu.connectNoNodeAvailable.name")); - noNodeAvailableItem.setEnabled(false); - connectMenu.add(noNodeAvailableItem); - } - disconnectMenu.removeAll(); - for (Action nodeDisconnectAction: swingInterface.getNodeDisconnectActions()) { - disconnectMenu.add(nodeDisconnectAction); - } - if (disconnectMenu.getMenuComponentCount() == 0) { - JMenuItem noNodeAvailableItem = new JMenuItem(I18n.get("mainWindow.menu.disconnectNoNodeAvailable.name")); - noNodeAvailableItem.setEnabled(false); - disconnectMenu.add(noNodeAvailableItem); - } + void addNode(Node node) { + JMenu newNodeMenu = new JMenu(node.getName()); + nodeMenus.put(node, newNodeMenu); + newNodeMenu.add(swingInterface.getNodeConnectAction(node)); + newNodeMenu.add(swingInterface.getNodeDisconnectAction(node)); + nodeMenu.add(newNodeMenu); + NodeLabel nodeLabel = new NodeLabel(swingInterface, node, onlineIcon, offlineIcon, errorIcon); + nodeLabels.put(node, nodeLabel); + statusBar.addSideComponent(nodeLabel); + } + + /** + * Removes a node from the menu. + * + * @param node + * The node to remove + */ + void removeNode(Node node) { + nodeMenu.remove(nodeMenus.remove(node)); + statusBar.removeSideComponent(nodeLabels.remove(node)); } /** @@ -336,6 +344,10 @@ public class MainWindow extends JFrame implements WindowListener, I18nable, Prop * Initializes the window by creating all its components. */ private void initWindow() { + onlineIcon = IconLoader.loadIcon("/node-online.png"); + offlineIcon = IconLoader.loadIcon("/node-offline.png"); + errorIcon = IconLoader.loadIcon("/node-error.png"); + JMenuBar menuBar = new JMenuBar(); jSiteMenu = new I18nMenu("mainWindow.menu.jSite"); @@ -347,19 +359,11 @@ public class MainWindow extends JFrame implements WindowListener, I18nable, Prop jSiteMenu.addSeparator(); jSiteMenu.add(new FixedJMenuItem(swingInterface.getQuitAction())); - connectMenu = new I18nMenu("mainWindow.menu.connect"); - disconnectMenu = new I18nMenu("mainWindow.menu.disconnect"); - nodeMenu = new I18nMenu("mainWindow.menu.node"); menuBar.add(nodeMenu); nodeMenu.add(new FixedJMenuItem(swingInterface.getManageNodesAction())); nodeMenu.addSeparator(); - nodeMenu.add(connectMenuItem = new FixedJMenuItem(swingInterface.getNodeConnectAction())); - nodeMenu.add(connectMenu); - nodeMenu.add(disconnectMenuItem = new FixedJMenuItem(swingInterface.getNodeDisconnectAction())); - nodeMenu.add(disconnectMenu); - refreshNodeMenuItems(); languageMenu = new I18nMenu("mainWindow.menu.language"); menuBar.add(languageMenu); @@ -368,9 +372,7 @@ public class MainWindow extends JFrame implements WindowListener, I18nable, Prop languageMenu.add(new FixedJMenuItem(languageAction)); } - JPanel spacerPanel = new JPanel(); - spacerPanel.setOpaque(false); - menuBar.add(spacerPanel); + menuBar.add(Box.createHorizontalGlue()); helpMenu = new I18nMenu("mainWindow.menu.help"); menuBar.add(helpMenu); @@ -382,8 +384,7 @@ public class MainWindow extends JFrame implements WindowListener, I18nable, Prop JToolBar toolBar = new JToolBar(I18n.get("mainWindow.toolbar.name")); toolBar.add(swingInterface.getManageNodesAction()); toolBar.addSeparator(); - toolBar.add(swingInterface.getNodeConnectAction()); - toolBar.add(swingInterface.getNodeDisconnectAction()); + toolBar.add(swingInterface.getQuitAction()); super.getContentPane().add(toolBar, BorderLayout.PAGE_START); super.getContentPane().add(contentPane, BorderLayout.CENTER); @@ -443,10 +444,6 @@ public class MainWindow extends JFrame implements WindowListener, I18nable, Prop swingInterface.getImportConfigAction().updateI18n(); swingInterface.getQuitAction().updateI18n(); swingInterface.getManageNodesAction().updateI18n(); - swingInterface.getNodeConnectAction().updateI18n(); - connectMenu.updateI18n(); - swingInterface.getNodeDisconnectAction().updateI18n(); - disconnectMenu.updateI18n(); swingInterface.getAddProjectAction().updateI18n(); swingInterface.getCloneProjectAction().updateI18n(); swingInterface.getDeleteProjectAction().updateI18n(); @@ -454,6 +451,10 @@ public class MainWindow extends JFrame implements WindowListener, I18nable, Prop jSiteMenu.updateI18n(); nodeMenu.updateI18n(); languageMenu.updateI18n(); + for (Node node: swingInterface.getNodes()) { + swingInterface.getNodeConnectAction(node).updateI18n(); + swingInterface.getNodeDisconnectAction(node).updateI18n(); + } for (I18nAction languageAction: swingInterface.getLanguageActions()) { languageAction.updateI18n(); } @@ -466,7 +467,6 @@ public class MainWindow extends JFrame implements WindowListener, I18nable, Prop ((ProjectPanel) tabComponent).updateI18n(); } } - refreshNodeMenuItems(); SwingUtils.repackCentered(this); } diff --git a/src/net/pterodactylus/jsite/gui/SwingInterface.java b/src/net/pterodactylus/jsite/gui/SwingInterface.java index 4fb7139..fad301d 100644 --- a/src/net/pterodactylus/jsite/gui/SwingInterface.java +++ b/src/net/pterodactylus/jsite/gui/SwingInterface.java @@ -20,6 +20,8 @@ package net.pterodactylus.jsite.gui; import java.awt.event.ActionEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -38,7 +40,6 @@ import java.util.logging.Level; import java.util.logging.LogRecord; import java.util.logging.Logger; -import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.JOptionPane; import javax.swing.UIManager; @@ -62,7 +63,7 @@ import net.pterodactylus.util.logging.LoggingListener; * @author David ‘Bombe’ Roden <bombe@freenetproject.org> * @version $Id$ */ -public class SwingInterface implements CoreListener, LoggingListener { +public class SwingInterface implements CoreListener, LoggingListener, PropertyChangeListener { /** The logger. */ private static final Logger logger = Logging.getLogger(SwingInterface.class.getName()); @@ -94,29 +95,11 @@ public class SwingInterface implements CoreListener, LoggingListener { /** The “manage nodes” action. */ private I18nAction manageNodesAction; - /** The “connect to node” (simple mode) action. */ - private I18nAction nodeConnectAction; - - /** The “disconnect from node” (simple mode) action. */ - private I18nAction nodeDisconnectAction; - /** All node menu items. */ - private List nodeConnectActions = Collections.synchronizedList(new ArrayList()); - - /** Mapping from nodes to node connect actions. */ - private Map nodeNodeConnectActions = Collections.synchronizedMap(new HashMap()); - - /** Mapping from node connect actions to nodes. */ - private Map nodeConnectActionNodes = Collections.synchronizedMap(new HashMap()); + private Map nodeConnectActions = Collections.synchronizedMap(new HashMap()); /** All node disconnect actions. */ - private List nodeDisconnectActions = Collections.synchronizedList(new ArrayList()); - - /** Mapping from nodes to node disconnect actions. */ - private Map nodeNodeDisconnectActions = Collections.synchronizedMap(new HashMap()); - - /** Mapping from node disconnect actions to nodes. */ - private Map nodeDisconnectActionNodes = Collections.synchronizedMap(new HashMap()); + private Map nodeDisconnectActions = Collections.synchronizedMap(new HashMap()); /** The node manager dialog. */ private ManageNodesDialog manageNodesDialog; @@ -291,39 +274,25 @@ public class SwingInterface implements CoreListener, LoggingListener { } /** - * Returns the “connect to node” action. + * Returns the “connect to node” action for the given node. * + * @param node + * The node go get the “connect” action for * @return The “connect to node” action */ - I18nAction getNodeConnectAction() { - return nodeConnectAction; + I18nAction getNodeConnectAction(Node node) { + return nodeConnectActions.get(node); } /** - * Returns all “connect node” actions. - * - * @return All “connect node” actions - */ - List getNodeConnectActions() { - return nodeConnectActions; - } - - /** - * Returns the “disconnect from node” action. + * Returns the “disconnect from node” action for the given node. * + * @param node + * The node go get the “disconnect” action for * @return The “disconnect from node” action */ - I18nAction getNodeDisconnectAction() { - return nodeDisconnectAction; - } - - /** - * Returns all “disconnect node” actions. - * - * @return All “disconnect node” action - */ - List getNodeDisconnectActions() { - return nodeDisconnectActions; + I18nAction getNodeDisconnectAction(Node node) { + return nodeDisconnectActions.get(node); } /** @@ -371,6 +340,15 @@ public class SwingInterface implements CoreListener, LoggingListener { return deleteProjectAction; } + /** + * Returns all currently configured nodes. + * + * @return All configured nodes + */ + List getNodes() { + return nodeList; + } + // // ACTIONS // @@ -525,33 +503,6 @@ public class SwingInterface implements CoreListener, LoggingListener { manageNodes(); } }; - nodeConnectAction = new I18nAction("mainWindow.menu.node.item.connect", false) { - - @SuppressWarnings("synthetic-access") - public void actionPerformed(ActionEvent actionEvent) { - List nodes = core.getNodes(); - if (nodes.isEmpty()) { - return; - } - nodeConnect(nodes.get(0)); - } - - }; - nodeDisconnectAction = new I18nAction("mainWindow.menu.node.item.disconnect", false) { - - /** - * {@inheritDoc} - */ - @SuppressWarnings("synthetic-access") - public void actionPerformed(ActionEvent e) { - List nodes = core.getNodes(); - if (nodes.isEmpty()) { - return; - } - nodeDisconnect(nodes.get(0)); - } - }; - rebuildNodeActions(core.getNodes()); List availableLanguages = I18n.findAvailableLanguages(); for (final Locale locale: availableLanguages) { I18nAction languageAction = new I18nAction("general.language." + locale.getLanguage()) { @@ -668,53 +619,6 @@ public class SwingInterface implements CoreListener, LoggingListener { } /** - * Rebuilds all node connect and disconnect actions. - * - * @param nodes - * The list of nodes - */ - private void rebuildNodeActions(List nodes) { - logger.fine("rebuilding node actions…"); - nodeConnectActions.clear(); - nodeNodeConnectActions.clear(); - nodeConnectActionNodes.clear(); - nodeDisconnectActions.clear(); - nodeNodeDisconnectActions.clear(); - nodeDisconnectActionNodes.clear(); - for (Node node: nodes) { - logger.finer("adding node “" + node + "” to menus"); - Action nodeConnectAction = new AbstractAction(node.getName()) { - - /** - * {@inheritDoc} - */ - @SuppressWarnings("synthetic-access") - public void actionPerformed(ActionEvent e) { - Node node = nodeConnectActionNodes.get(this); - nodeConnect(node); - } - }; - nodeConnectActions.add(nodeConnectAction); - nodeConnectActionNodes.put(nodeConnectAction, node); - nodeNodeConnectActions.put(node, nodeConnectAction); - Action nodeDisconnectAction = new AbstractAction(node.getName()) { - - /** - * {@inheritDoc} - */ - @SuppressWarnings("synthetic-access") - public void actionPerformed(ActionEvent e) { - Node node = nodeDisconnectActionNodes.get(this); - nodeDisconnect(node); - } - }; - // nodeDisconnectActions.add(nodeDisconnectAction); - nodeDisconnectActionNodes.put(nodeDisconnectAction, node); - nodeNodeDisconnectActions.put(node, nodeDisconnectAction); - } - } - - /** * Pops up the “manage nodes” dialog. */ private void manageNodes() { @@ -722,8 +626,7 @@ public class SwingInterface implements CoreListener, LoggingListener { manageNodesDialog.setNodeList(nodeList); manageNodesDialog.setVisible(true); nodeList = manageNodesDialog.getNodeList(); - rebuildNodeActions(nodeList); - mainWindow.refreshNodeMenuItems(); + /* TODO - notify main window of changes */ } else { if (nodeList.isEmpty()) { Node newNode = new Node(); @@ -914,13 +817,34 @@ public class SwingInterface implements CoreListener, LoggingListener { /** * {@inheritDoc} */ - public void nodeAdded(Node node) { + public void nodeAdded(final Node node) { logger.log(Level.INFO, "node added: " + node); nodeList.add(node); + node.addPropertyChangeListener(this); logger.log(Level.FINE, "nodeList.size(): " + nodeList.size()); manageNodesDialog.setNodeList(nodeList); - rebuildNodeActions(nodeList); - mainWindow.refreshNodeMenuItems(); + nodeConnectActions.put(node, new I18nAction("mainWindow.menu.connect") { + + /** + * {@inheritDoc} + */ + @SuppressWarnings("synthetic-access") + public void actionPerformed(ActionEvent e) { + nodeConnect(node); + } + }); + nodeDisconnectActions.put(node, new I18nAction("mainWindow.menu.disconnect") { + + /** + * {@inheritDoc} + */ + @SuppressWarnings("synthetic-access") + public void actionPerformed(ActionEvent e) { + nodeDisconnect(node); + } + }); + nodeDisconnectActions.get(node).setEnabled(false); + mainWindow.addNode(node); } /** @@ -929,51 +853,44 @@ public class SwingInterface implements CoreListener, LoggingListener { public void nodeRemoved(Node node) { logger.log(Level.INFO, "node removed: " + node); nodeList.remove(node); - rebuildNodeActions(nodeList); - mainWindow.refreshNodeMenuItems(); + node.removePropertyChangeListener(this); + nodeConnectActions.remove(node); + nodeDisconnectActions.remove(node); + mainWindow.removeNode(node); } /** * {@inheritDoc} */ public void nodeConnecting(Node node) { - Action nodeConnectAction = nodeNodeConnectActions.get(node); - nodeConnectActions.remove(nodeConnectAction); + nodeConnectActions.get(node).setEnabled(false); mainWindow.setStatusBarText(I18n.get("mainWindow.statusBar.connectingToNode", node.getName(), node.getHostname(), node.getPort())); - mainWindow.refreshNodeMenuItems(); } /** * {@inheritDoc} */ public void nodeConnected(Node node) { - Action nodeDisconnectAction = nodeNodeDisconnectActions.get(node); - nodeDisconnectActions.add(nodeDisconnectAction); + nodeDisconnectActions.get(node).setEnabled(true); mainWindow.setStatusBarText(I18n.get("mainWindow.statusBar.connectedToNode", node.getName(), node.getHostname(), node.getPort())); - mainWindow.refreshNodeMenuItems(); } /** * {@inheritDoc} */ public void nodeConnectionFailed(Node node, Throwable cause) { - Action nodeConnectAction = nodeNodeConnectActions.get(node); - nodeConnectActions.add(nodeConnectAction); + nodeConnectActions.get(node).setEnabled(true); mainWindow.setStatusBarText(I18n.get("mainWindow.statusBar.connectionToNodeFailed", node.getName(), node.getHostname(), node.getPort(), (cause != null) ? cause.getMessage() : "no reason given")); JOptionPane.showMessageDialog(mainWindow, I18n.get("mainWindow.error.nodeConnectionFailed.message", node.getName(), node.getHostname(), node.getPort(), (cause != null) ? cause.getMessage() : "no reason given"), I18n.get("mainWindow.error.nodeConnectionFailed.title"), JOptionPane.ERROR_MESSAGE); - mainWindow.refreshNodeMenuItems(); } /** * {@inheritDoc} */ public void nodeDisconnected(Node node, Throwable throwable) { - Action nodeConnectAction = nodeNodeConnectActions.get(node); - nodeConnectActions.add(nodeConnectAction); - Action nodeDisconnectAction = nodeNodeDisconnectActions.get(node); - nodeDisconnectActions.remove(nodeDisconnectAction); + nodeDisconnectActions.get(node).setEnabled(false); + nodeConnectActions.get(node).setEnabled(true); mainWindow.setStatusBarText(I18n.get("mainWindow.statusBar.disconnectedFromNode", node.getName(), node.getHostname(), node.getPort())); - mainWindow.refreshNodeMenuItems(); } /** @@ -1018,4 +935,19 @@ public class SwingInterface implements CoreListener, LoggingListener { logWindow.logged(logRecord); } + // + // INTERFACE PropertyChangeListener + // + + /** + * {@inheritDoc} + */ + public void propertyChange(PropertyChangeEvent propertyChangeEvent) { + if (propertyChangeEvent.getSource() instanceof Node) { + Node changedNode = (Node) propertyChangeEvent.getSource(); + nodeConnectActions.get(changedNode).putValue(Action.NAME, changedNode.getName()); + nodeDisconnectActions.get(changedNode).putValue(Action.NAME, changedNode.getName()); + } + } + } diff --git a/src/net/pterodactylus/jsite/i18n/jSite.properties b/src/net/pterodactylus/jsite/i18n/jSite.properties index 5e10f82..d4e22b0 100644 --- a/src/net/pterodactylus/jsite/i18n/jSite.properties +++ b/src/net/pterodactylus/jsite/i18n/jSite.properties @@ -59,6 +59,9 @@ mainWindow.statusBar.connectedToNode: Connected to \u201c{0}\u201d (at {1}:{2,nu mainWindow.statusBar.connectionToNodeFailed: Connection to \u201c{0}\u201d (at {1}:{2,number,#}) failed: {3} mainWindow.statusBar.disconnectedFromNode: Disconnected from \u201c{0}\u201d (at {1}:{2,number,#}). +mainWindow.statusBar.nodeLabel.name: Node \u201c{0}\u201d +mainWindow.statusBar.nodeLabel.menmonic: VK_UNDEFINED + # main menus mainWindow.menu.jSite.name: jSite mainWindow.menu.jSite.mnemonic: VK_J @@ -68,9 +71,15 @@ mainWindow.menu.node.mnemonic: VK_N mainWindow.menu.connect.name: Connect mainWindow.menu.connect.mnemonic: VK_C +mainWindow.menu.connect.accelerator: VK_UNDEFINED +mainWindow.menu.connect.shortDescription: Connects to the node +mainWindow.menu.connect.longDescription: Connects to the node mainWindow.menu.disconnect.name: Disconnect mainWindow.menu.disconnect.mnemonic: VK_D +mainWindow.menu.disconnect.accelerator: VK_UNDEFINED +mainWindow.menu.disconnect.shortDescription: Disconnects from the node +mainWindow.menu.disconnect.longDescription: Disconnects from the node mainWindow.menu.connectNoNodeAvailable.name: No node available mainWindow.menu.disconnectNoNodeAvailable.name: No node connected diff --git a/src/net/pterodactylus/jsite/i18n/jSite_de.properties b/src/net/pterodactylus/jsite/i18n/jSite_de.properties index c026e62..fc12868 100644 --- a/src/net/pterodactylus/jsite/i18n/jSite_de.properties +++ b/src/net/pterodactylus/jsite/i18n/jSite_de.properties @@ -59,6 +59,9 @@ mainWindow.statusBar.connectedToNode: Verbindung zum Node \u201e{0}\u201c ({1}:{ mainWindow.statusBar.connectionToNodeFailed: Verbindung zu Node \u201e{0}\u201c ({1}:{2,number,#}) fehlgeschlagen: {3} mainWindow.statusBar.disconnectedFromNode: Verbindung von Node \u201e{0}\u201c ({1}:{2,number,#}) getrennt. +mainWindow.statusBar.nodeLabel.name: Node \u201e{0}\u201c +mainWindow.statusBar.nodeLabel.menmonic: VK_UNDEFINED + # main menus mainWindow.menu.jSite.name: jSite mainWindow.menu.jSite.mnemonic: VK_J @@ -68,9 +71,15 @@ mainWindow.menu.node.mnemonic: VK_N mainWindow.menu.connect.name: Verbindung herstellen mainWindow.menu.connect.mnemonic: VK_H +mainWindow.menu.connect.accelerator: VK_UNDEFINED +mainWindow.menu.connect.shortDescription: Stellt eine Verbindung zum Node her +mainWindow.menu.connect.longDescription: Stellt eine Verbindung zum Node her mainWindow.menu.disconnect.name: Verbindung trennen mainWindow.menu.disconnect.mnemonic: VK_T +mainWindow.menu.disconnect.accelerator: VK_UNDEFINED +mainWindow.menu.disconnect.shortDescription: Trennt die Verbindung vom Node +mainWindow.menu.disconnect.longDescription: Trennt die Verbindung vom Node mainWindow.menu.connectNoNodeAvailable.name: Kein Node verf\u00fcgbar mainWindow.menu.disconnectNoNodeAvailable.name: Kein Node verbunden -- 2.7.4