New node information dialog to display general, usage and command line information.

Ref https://github.com/GNS3/gns3-gui/issues/2662 https://github.com/GNS3/gns3-gui/issues/2656
This commit is contained in:
grossmj
2018-12-30 19:35:25 +07:00
parent ed88eaa620
commit ec334508a6
35 changed files with 87313 additions and 86197 deletions

View File

@@ -0,0 +1,56 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2018 GNS3 Technologies Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
Dialog to show node information.
"""
from ..qt import QtWidgets
from ..ui.node_info_dialog_ui import Ui_NodeInfoDialog
class NodeInfoDialog(QtWidgets.QDialog, Ui_NodeInfoDialog):
"""
Node information dialog.
:param parent: parent widget
"""
def __init__(self, node, parent):
super().__init__(parent)
self.setupUi(self)
general_info = node.info()
usage_info = node.usage()
command_line_info = node.commandLine()
self.setWindowTitle(node.name())
# General tab
self.uiGeneralTextBrowser.setPlainText(general_info)
# Usage tab
if not usage_info:
usage_info = "No usage information has been provided for this node."
self.uiUsageTextBrowser.setPlainText(usage_info)
# Command line tab
if command_line_info is None:
command_line_info = "Command line information is not supported for this type of node."
elif len(command_line_info) == 0:
command_line_info = "Please start the node in order to get the command line information."
self.uiCommandLineTextBrowser.setPlainText(command_line_info)

View File

@@ -41,6 +41,7 @@ from .dialogs.symbol_selection_dialog import SymbolSelectionDialog
from .dialogs.idlepc_dialog import IdlePCDialog
from .dialogs.console_command_dialog import ConsoleCommandDialog
from .dialogs.file_editor_dialog import FileEditorDialog
from .dialogs.node_info_dialog import NodeInfoDialog
from .local_config import LocalConfig
from .progress import Progress
from .utils.server_select import server_select
@@ -755,7 +756,15 @@ class GraphicsView(QtWidgets.QGraphicsView):
else:
style_dir = ":/icons/"
if True in list(map(lambda item: isinstance(item, NodeItem) and hasattr(item.node(), "info"), items)):
# Action: Show node information
show_node_info_action = QtWidgets.QAction("Show node information", menu)
show_node_info_action.setIcon(self._getIcon(style_dir, "help.svg"))
show_node_info_action.triggered.connect(self.showNodeInfoSlot)
menu.addAction(show_node_info_action)
if True in list(map(lambda item: isinstance(item, NodeItem) and hasattr(item.node(), "configPage"), items)):
# Action: Configure node
configure_action = QtWidgets.QAction("Configure", menu)
configure_action.setIcon(self._getIcon(style_dir, "configuration.svg"))
configure_action.triggered.connect(self.configureActionSlot)
@@ -885,13 +894,6 @@ class GraphicsView(QtWidgets.QGraphicsView):
style_action.triggered.connect(self.styleActionSlot)
menu.addAction(style_action)
if True in list(map(lambda item: isinstance(item, NodeItem) and hasattr(item.node(), "commandLine"), items)):
# Action: Get command line
show_in_file_manager_action = QtWidgets.QAction("Command line", menu)
show_in_file_manager_action.setIcon(self._getIcon(style_dir, "command_line.svg"))
show_in_file_manager_action.triggered.connect(self.getCommandLineSlot)
menu.addAction(show_in_file_manager_action)
if True in list(map(lambda item: isinstance(item, LabelItem), items)) and False in list(map(lambda item: item.parentItem() is None, items)):
# action only for port labels
reset_label_position_action = QtWidgets.QAction("Reset position", menu)
@@ -1271,30 +1273,21 @@ class GraphicsView(QtWidgets.QGraphicsView):
self._export_config_directory = os.path.dirname(path)
item.node().exportFile(config_file, path)
def getCommandLineSlot(self):
def showNodeInfoSlot(self):
"""
Slot to receive events from the get command line action in the
Slot to receive events from the show node info action in the
contextual menu.
"""
items = self.scene().selectedItems()
if len(items) != 1:
QtWidgets.QMessageBox.critical(self, "Command line", "Please select only one router")
QtWidgets.QMessageBox.critical(self, "Show node information", "Please select only one node")
return
item = items[0]
if isinstance(item, NodeItem) and hasattr(item.node(), "commandLine"):
router = item.node()
if router.commandLine() is None:
QtWidgets.QMessageBox.warning(self, "Command line", "Get command line is not supported for this type of node.")
elif router.commandLine() == '':
QtWidgets.QMessageBox.warning(self, "Command line", "Please start the node in order to get the command line.")
else:
dialog = QtWidgets.QInputDialog(self)
dialog.setOptions(QtWidgets.QInputDialog.NoButtons)
dialog.setLabelText("Command used to start the VM:")
dialog.setTextValue(router.commandLine())
dialog.show()
dialog.exec_()
if isinstance(item, NodeItem):
dialog = NodeInfoDialog(item.node(), parent=self)
dialog.show()
dialog.exec_()
def bringToFrontSlot(self):
"""

View File

@@ -87,9 +87,6 @@ class DockerVM(Node):
port_name=port.name(),
port_description=port.description())
if self._settings["usage"]:
info += " Usage: {}\n".format(self._settings["usage"])
return info + port_info
def consoleHttpPath(self):

View File

@@ -149,6 +149,8 @@ class DockerVMConfigurationPage(QtWidgets.QWidget, Ui_dockerVMConfigPageWidget):
self.uiSymbolLineEdit.hide()
self.uiSymbolToolButton.hide()
self.uiUsageTextEdit.setPlainText(settings["usage"])
def _networkConfigEditSlot(self):
dialog = FileEditorDialog(self._node, self._node.configFiles()[0])
@@ -207,4 +209,6 @@ class DockerVMConfigurationPage(QtWidgets.QWidget, Ui_dockerVMConfigPageWidget):
symbol_path = self.uiSymbolLineEdit.text()
settings["symbol"] = symbol_path
settings["usage"] = self.uiUsageTextEdit.toPlainText()
return settings

View File

@@ -314,6 +314,16 @@ one per line)</string>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_3">
<attribute name="title">
<string>Usage</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QPlainTextEdit" name="uiUsageTextEdit"/>
</item>
</layout>
</widget>
</widget>
</item>
</layout>

View File

@@ -149,6 +149,14 @@ class Ui_dockerVMConfigPageWidget(object):
spacerItem = QtWidgets.QSpacerItem(20, 388, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.gridLayout_2.addItem(spacerItem, 1, 1, 1, 1)
self.uiTabWidget.addTab(self.tab_2, "")
self.tab_3 = QtWidgets.QWidget()
self.tab_3.setObjectName("tab_3")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.tab_3)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.uiUsageTextEdit = QtWidgets.QPlainTextEdit(self.tab_3)
self.uiUsageTextEdit.setObjectName("uiUsageTextEdit")
self.verticalLayout_2.addWidget(self.uiUsageTextEdit)
self.uiTabWidget.addTab(self.tab_3, "")
self.verticalLayout.addWidget(self.uiTabWidget)
self.retranslateUi(dockerVMConfigPageWidget)
@@ -194,4 +202,5 @@ class Ui_dockerVMConfigPageWidget(object):
"(hostname:IP\n"
"one per line)"))
self.uiTabWidget.setTabText(self.uiTabWidget.indexOf(self.tab_2), _translate("dockerVMConfigPageWidget", "Advanced"))
self.uiTabWidget.setTabText(self.uiTabWidget.indexOf(self.tab_3), _translate("dockerVMConfigPageWidget", "Usage"))

View File

@@ -268,9 +268,6 @@ class Router(Node):
# gather information about PA, their interfaces and connections
slot_info = self._slot_info()
if self._settings["usage"]:
info += " Usage: {}\n".format(self._settings["usage"])
return info + slot_info
def configFiles(self):

View File

@@ -422,6 +422,8 @@ class IOSRouterConfigurationPage(QtWidgets.QWidget, Ui_iosRouterConfigPageWidget
else:
self.uiSparseMemoryCheckBox.hide()
self.uiUsageTextEdit.setPlainText(settings["usage"])
def _checkForLinkConnectedToAdapter(self, slot_number, settings, node):
"""
Checks if links are connected to an adapter.
@@ -639,6 +641,8 @@ class IOSRouterConfigurationPage(QtWidgets.QWidget, Ui_iosRouterConfigPageWidget
if node:
self._checkForLinkConnectedToWIC(wic_number, settings, node)
settings["wic" + str(wic_number)] = ""
settings["usage"] = self.uiUsageTextEdit.toPlainText()
return settings
def _configFileValid(self, path):

View File

@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>795</width>
<height>727</height>
<width>980</width>
<height>734</height>
</rect>
</property>
<property name="windowTitle">
@@ -1016,6 +1016,16 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="uiUsageTab">
<attribute name="title">
<string>Usage</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QPlainTextEdit" name="uiUsageTextEdit"/>
</item>
</layout>
</widget>
</widget>
</item>
</layout>

View File

@@ -2,7 +2,7 @@
# Form implementation generated from reading ui file '/home/grossmj/PycharmProjects/gns3-gui/gns3/modules/dynamips/ui/ios_router_configuration_page.ui'
#
# Created by: PyQt5 UI code generator 5.5.1
# Created by: PyQt5 UI code generator 5.9
#
# WARNING! All changes made in this file will be lost!
@@ -11,7 +11,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_iosRouterConfigPageWidget(object):
def setupUi(self, iosRouterConfigPageWidget):
iosRouterConfigPageWidget.setObjectName("iosRouterConfigPageWidget")
iosRouterConfigPageWidget.resize(795, 727)
iosRouterConfigPageWidget.resize(980, 734)
self.vboxlayout = QtWidgets.QVBoxLayout(iosRouterConfigPageWidget)
self.vboxlayout.setObjectName("vboxlayout")
self.uiTabWidget = QtWidgets.QTabWidget(iosRouterConfigPageWidget)
@@ -531,6 +531,14 @@ class Ui_iosRouterConfigPageWidget(object):
spacerItem4 = QtWidgets.QSpacerItem(20, 194, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout_3.addItem(spacerItem4)
self.uiTabWidget.addTab(self.uiEnvironmentPageWidget, "")
self.uiUsageTab = QtWidgets.QWidget()
self.uiUsageTab.setObjectName("uiUsageTab")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.uiUsageTab)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.uiUsageTextEdit = QtWidgets.QPlainTextEdit(self.uiUsageTab)
self.uiUsageTextEdit.setObjectName("uiUsageTextEdit")
self.verticalLayout_2.addWidget(self.uiUsageTextEdit)
self.uiTabWidget.addTab(self.uiUsageTab, "")
self.vboxlayout.addWidget(self.uiTabWidget)
self.retranslateUi(iosRouterConfigPageWidget)
@@ -630,4 +638,5 @@ class Ui_iosRouterConfigPageWidget(object):
self.uiSensor4Label.setText(_translate("iosRouterConfigPageWidget", "NPE outlet:"))
self.uiSensor4SpinBox.setSuffix(_translate("iosRouterConfigPageWidget", " C"))
self.uiTabWidget.setTabText(self.uiTabWidget.indexOf(self.uiEnvironmentPageWidget), _translate("iosRouterConfigPageWidget", "Environment"))
self.uiTabWidget.setTabText(self.uiTabWidget.indexOf(self.uiUsageTab), _translate("iosRouterConfigPageWidget", "Usage"))

View File

@@ -99,9 +99,6 @@ class IOUDevice(Node):
port_info += " {port_name} {port_description}\n".format(port_name=port.name(),
port_description=port.description())
if self._settings["usage"]:
info += " Usage: {}\n".format(self._settings["usage"])
return info + port_info
def configFiles(self):

View File

@@ -226,6 +226,7 @@ class iouDeviceConfigurationPage(QtWidgets.QWidget, Ui_iouDeviceConfigPageWidget
# load the number of adapters
self.uiEthernetAdaptersSpinBox.setValue(settings["ethernet_adapters"])
self.uiSerialAdaptersSpinBox.setValue(settings["serial_adapters"])
self.uiUsageTextEdit.setPlainText(settings["usage"])
def saveSettings(self, settings, node=None, group=False):
"""
@@ -312,6 +313,7 @@ class iouDeviceConfigurationPage(QtWidgets.QWidget, Ui_iouDeviceConfigPageWidget
# save console type
settings["console_type"] = self.uiConsoleTypeComboBox.currentText().lower()
settings["console_auto_start"] = self.uiConsoleAutoStartCheckBox.isChecked()
settings["usage"] = self.uiUsageTextEdit.toPlainText()
return settings
def _configFileValid(self, path):

View File

@@ -399,6 +399,16 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_3">
<attribute name="title">
<string>Usage</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QPlainTextEdit" name="uiUsageTextEdit"/>
</item>
</layout>
</widget>
</widget>
</item>
</layout>

View File

@@ -2,7 +2,7 @@
# Form implementation generated from reading ui file '/home/grossmj/PycharmProjects/gns3-gui/gns3/modules/iou/ui/iou_device_configuration_page.ui'
#
# Created by: PyQt5 UI code generator 5.5.1
# Created by: PyQt5 UI code generator 5.9
#
# WARNING! All changes made in this file will be lost!
@@ -199,6 +199,14 @@ class Ui_iouDeviceConfigPageWidget(object):
spacerItem1 = QtWidgets.QSpacerItem(20, 347, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.gridLayout_5.addItem(spacerItem1, 1, 0, 1, 1)
self.uiTabWidget.addTab(self.tab_2, "")
self.tab_3 = QtWidgets.QWidget()
self.tab_3.setObjectName("tab_3")
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.tab_3)
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.uiUsageTextEdit = QtWidgets.QPlainTextEdit(self.tab_3)
self.uiUsageTextEdit.setObjectName("uiUsageTextEdit")
self.verticalLayout_3.addWidget(self.uiUsageTextEdit)
self.uiTabWidget.addTab(self.tab_3, "")
self.verticalLayout.addWidget(self.uiTabWidget)
self.retranslateUi(iouDeviceConfigPageWidget)
@@ -238,4 +246,5 @@ class Ui_iouDeviceConfigPageWidget(object):
self.uiSerialAdaptersLabel.setText(_translate("iouDeviceConfigPageWidget", "Serial adapters:"))
self.uiSerialAdaptersSpinBox.setToolTip(_translate("iouDeviceConfigPageWidget", "1 adapter equals 4 serial interfaces"))
self.uiTabWidget.setTabText(self.uiTabWidget.indexOf(self.tab_2), _translate("iouDeviceConfigPageWidget", "Network"))
self.uiTabWidget.setTabText(self.uiTabWidget.indexOf(self.tab_3), _translate("iouDeviceConfigPageWidget", "Usage"))

View File

@@ -541,6 +541,7 @@ class QemuVMConfigurationPage(QtWidgets.QWidget, Ui_QemuVMConfigPageWidget):
if index != -1:
self.uiProcessPriorityComboBox.setCurrentIndex(index)
self.uiQemuOptionsLineEdit.setText(settings["options"])
self.uiUsageTextEdit.setPlainText(settings["usage"])
def saveSettings(self, settings, node=None, group=False):
"""
@@ -651,4 +652,5 @@ class QemuVMConfigurationPage(QtWidgets.QWidget, Ui_QemuVMConfigPageWidget):
settings["cpu_throttling"] = 0
settings["process_priority"] = self.uiProcessPriorityComboBox.currentText().lower()
settings["options"] = self.uiQemuOptionsLineEdit.text()
settings["usage"] = self.uiUsageTextEdit.toPlainText()
return settings

View File

@@ -130,9 +130,6 @@ class QemuVM(Node):
if port.macAddress():
port_info += " MAC address is {mac_address}\n".format(mac_address=port.macAddress())
if self._settings["usage"]:
info += " Usage: {}\n".format(self._settings["usage"])
return info + port_info
def configPage(self):

View File

@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>888</width>
<height>882</height>
<width>941</width>
<height>877</height>
</rect>
</property>
<property name="windowTitle">
@@ -658,7 +658,7 @@
</widget>
<widget class="QWidget" name="uiAdvancedSettingsTab">
<attribute name="title">
<string>Advanced settings</string>
<string>Advanced</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
@@ -896,6 +896,16 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="uiUsageTab">
<attribute name="title">
<string>Usage</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QPlainTextEdit" name="uiUsageTextEdit"/>
</item>
</layout>
</widget>
</widget>
</item>
</layout>

View File

@@ -2,7 +2,7 @@
# Form implementation generated from reading ui file '/home/grossmj/PycharmProjects/gns3-gui/gns3/modules/qemu/ui/qemu_vm_configuration_page.ui'
#
# Created by: PyQt5 UI code generator 5.5.1
# Created by: PyQt5 UI code generator 5.9
#
# WARNING! All changes made in this file will be lost!
@@ -11,7 +11,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_QemuVMConfigPageWidget(object):
def setupUi(self, QemuVMConfigPageWidget):
QemuVMConfigPageWidget.setObjectName("QemuVMConfigPageWidget")
QemuVMConfigPageWidget.resize(888, 882)
QemuVMConfigPageWidget.resize(941, 877)
self.verticalLayout = QtWidgets.QVBoxLayout(QemuVMConfigPageWidget)
self.verticalLayout.setObjectName("verticalLayout")
self.uiQemutabWidget = QtWidgets.QTabWidget(QemuVMConfigPageWidget)
@@ -436,6 +436,14 @@ class Ui_QemuVMConfigPageWidget(object):
spacerItem4 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout_2.addItem(spacerItem4)
self.uiQemutabWidget.addTab(self.uiAdvancedSettingsTab, "")
self.uiUsageTab = QtWidgets.QWidget()
self.uiUsageTab.setObjectName("uiUsageTab")
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.uiUsageTab)
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.uiUsageTextEdit = QtWidgets.QPlainTextEdit(self.uiUsageTab)
self.uiUsageTextEdit.setObjectName("uiUsageTextEdit")
self.verticalLayout_3.addWidget(self.uiUsageTextEdit)
self.uiQemutabWidget.addTab(self.uiUsageTab, "")
self.verticalLayout.addWidget(self.uiQemutabWidget)
self.retranslateUi(QemuVMConfigPageWidget)
@@ -536,5 +544,6 @@ class Ui_QemuVMConfigPageWidget(object):
"</ul>\n"
"</body></html>"))
self.uiBaseVMCheckBox.setText(_translate("QemuVMConfigPageWidget", "Use as a linked base VM"))
self.uiQemutabWidget.setTabText(self.uiQemutabWidget.indexOf(self.uiAdvancedSettingsTab), _translate("QemuVMConfigPageWidget", "Advanced settings"))
self.uiQemutabWidget.setTabText(self.uiQemutabWidget.indexOf(self.uiAdvancedSettingsTab), _translate("QemuVMConfigPageWidget", "Advanced"))
self.uiQemutabWidget.setTabText(self.uiQemutabWidget.indexOf(self.uiUsageTab), _translate("QemuVMConfigPageWidget", "Usage"))

View File

@@ -198,6 +198,8 @@ class VirtualBoxVMConfigurationPage(QtWidgets.QWidget, Ui_virtualBoxVMConfigPage
if index != -1:
self.uiOnCloseComboBox.setCurrentIndex(index)
self.uiUsageTextEdit.setPlainText(settings["usage"])
def saveSettings(self, settings, node=None, group=False):
"""
Saves the VirtualBox VM settings.
@@ -268,4 +270,5 @@ class VirtualBoxVMConfigurationPage(QtWidgets.QWidget, Ui_virtualBoxVMConfigPage
raise ConfigurationError()
settings["adapters"] = adapters
settings["custom_adapters"] = self._custom_adapters.copy()
settings["usage"] = self.uiUsageTextEdit.toPlainText()
return settings

View File

@@ -314,6 +314,16 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_3">
<attribute name="title">
<string>Usage</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QPlainTextEdit" name="uiUsageTextEdit"/>
</item>
</layout>
</widget>
</widget>
</item>
</layout>

View File

@@ -2,7 +2,7 @@
# Form implementation generated from reading ui file '/home/grossmj/PycharmProjects/gns3-gui/gns3/modules/virtualbox/ui/virtualbox_vm_configuration_page.ui'
#
# Created by: PyQt5 UI code generator 5.5.1
# Created by: PyQt5 UI code generator 5.9
#
# WARNING! All changes made in this file will be lost!
@@ -161,6 +161,14 @@ class Ui_virtualBoxVMConfigPageWidget(object):
self.uiAdaptersSpinBox.setObjectName("uiAdaptersSpinBox")
self.gridLayout_2.addWidget(self.uiAdaptersSpinBox, 0, 2, 1, 1)
self.uiTabWidget.addTab(self.tab_2, "")
self.tab_3 = QtWidgets.QWidget()
self.tab_3.setObjectName("tab_3")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.tab_3)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.uiUsageTextEdit = QtWidgets.QPlainTextEdit(self.tab_3)
self.uiUsageTextEdit.setObjectName("uiUsageTextEdit")
self.verticalLayout_2.addWidget(self.uiUsageTextEdit)
self.uiTabWidget.addTab(self.tab_3, "")
self.verticalLayout.addWidget(self.uiTabWidget)
self.retranslateUi(virtualBoxVMConfigPageWidget)
@@ -196,4 +204,5 @@ class Ui_virtualBoxVMConfigPageWidget(object):
self.uiCustomAdaptersConfigurationPushButton.setText(_translate("virtualBoxVMConfigPageWidget", "&Configure custom adapters"))
self.uiUseAnyAdapterCheckBox.setText(_translate("virtualBoxVMConfigPageWidget", "Allow GNS3 to use any configured VirtualBox adapter"))
self.uiTabWidget.setTabText(self.uiTabWidget.indexOf(self.tab_2), _translate("virtualBoxVMConfigPageWidget", "Network"))
self.uiTabWidget.setTabText(self.uiTabWidget.indexOf(self.tab_3), _translate("virtualBoxVMConfigPageWidget", "Usage"))

View File

@@ -92,9 +92,6 @@ class VirtualBoxVM(Node):
port_info += " {port_name} {port_description}\n".format(port_name=port.name(),
port_description=port.description())
if self._settings["usage"]:
info += " Usage: {}\n".format(self._settings["usage"])
return info + port_info
def bringToFront(self):

View File

@@ -197,6 +197,8 @@ class VMwareVMConfigurationPage(QtWidgets.QWidget, Ui_VMwareVMConfigPageWidget):
if index != -1:
self.uiOnCloseComboBox.setCurrentIndex(index)
self.uiUsageTextEdit.setPlainText(settings["usage"])
def saveSettings(self, settings, node=None, group=False):
"""
Saves the VMware VM settings.
@@ -266,4 +268,5 @@ class VMwareVMConfigurationPage(QtWidgets.QWidget, Ui_VMwareVMConfigPageWidget):
raise ConfigurationError()
settings["adapters"] = adapters
settings["custom_adapters"] = self._custom_adapters.copy()
settings["usage"] = self.uiUsageTextEdit.toPlainText()
return settings

View File

@@ -277,6 +277,16 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_3">
<attribute name="title">
<string>Usage</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QPlainTextEdit" name="uiUsageTextEdit"/>
</item>
</layout>
</widget>
</widget>
</item>
</layout>

View File

@@ -2,7 +2,7 @@
# Form implementation generated from reading ui file '/home/grossmj/PycharmProjects/gns3-gui/gns3/modules/vmware/ui/vmware_vm_configuration_page.ui'
#
# Created by: PyQt5 UI code generator 5.5.1
# Created by: PyQt5 UI code generator 5.9
#
# WARNING! All changes made in this file will be lost!
@@ -138,6 +138,14 @@ class Ui_VMwareVMConfigPageWidget(object):
self.uiAdaptersSpinBox.setObjectName("uiAdaptersSpinBox")
self.gridLayout_2.addWidget(self.uiAdaptersSpinBox, 0, 2, 1, 1)
self.uiTabWidget.addTab(self.tab_2, "")
self.tab_3 = QtWidgets.QWidget()
self.tab_3.setObjectName("tab_3")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.tab_3)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.uiUsageTextEdit = QtWidgets.QPlainTextEdit(self.tab_3)
self.uiUsageTextEdit.setObjectName("uiUsageTextEdit")
self.verticalLayout_2.addWidget(self.uiUsageTextEdit)
self.uiTabWidget.addTab(self.tab_3, "")
self.verticalLayout.addWidget(self.uiTabWidget)
self.retranslateUi(VMwareVMConfigPageWidget)
@@ -171,4 +179,5 @@ class Ui_VMwareVMConfigPageWidget(object):
self.uiUseAnyAdapterCheckBox.setToolTip(_translate("VMwareVMConfigPageWidget", "<html><head/><body><p>This option will allow GNS3 to replace all adapters of the VM. This allow you to use any interface of the VM in GNS3.</p></body></html>"))
self.uiUseAnyAdapterCheckBox.setText(_translate("VMwareVMConfigPageWidget", "Allow GNS3 to override non custom VMware adapter"))
self.uiTabWidget.setTabText(self.uiTabWidget.indexOf(self.tab_2), _translate("VMwareVMConfigPageWidget", "Network"))
self.uiTabWidget.setTabText(self.uiTabWidget.indexOf(self.tab_3), _translate("VMwareVMConfigPageWidget", "Usage"))

View File

@@ -89,9 +89,6 @@ class VMwareVM(Node):
port_info += " {port_name} {port_description}\n".format(port_name=port.name(),
port_description=port.description())
if self._settings["usage"]:
info += " Usage: {}\n".format(self._settings["usage"])
return info + port_info
def allocateVMnetInterface(self, port_id):

View File

@@ -94,6 +94,15 @@ class Node(BaseNode):
return self._settings["name"]
def usage(self):
"""
Returns the usage info for this node.
:returns: usage (string)
"""
return self._settings.get("usage")
def nodeDir(self):
"""
Return the working directory of this node

106
gns3/ui/node_info_dialog.ui Executable file
View File

@@ -0,0 +1,106 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>NodeInfoDialog</class>
<widget class="QDialog" name="NodeInfoDialog">
<property name="windowModality">
<enum>Qt::WindowModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1243</width>
<height>872</height>
</rect>
</property>
<property name="windowTitle">
<string>Node information</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTabWidget" name="uiTabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="uiGeneralTab">
<attribute name="title">
<string>General information</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QTextBrowser" name="uiGeneralTextBrowser"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="uiUsageTab">
<attribute name="title">
<string>Usage instructions</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QTextBrowser" name="uiUsageTextBrowser"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="uiCommandLineTab">
<attribute name="title">
<string>Command line</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QTextBrowser" name="uiCommandLineTextBrowser"/>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../../resources/resources.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>NodeInfoDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>NodeInfoDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -0,0 +1,64 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file '/home/grossmj/PycharmProjects/gns3-gui/gns3/ui/node_info_dialog.ui'
#
# Created by: PyQt5 UI code generator 5.9
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_NodeInfoDialog(object):
def setupUi(self, NodeInfoDialog):
NodeInfoDialog.setObjectName("NodeInfoDialog")
NodeInfoDialog.setWindowModality(QtCore.Qt.WindowModal)
NodeInfoDialog.resize(1243, 872)
self.verticalLayout = QtWidgets.QVBoxLayout(NodeInfoDialog)
self.verticalLayout.setObjectName("verticalLayout")
self.uiTabWidget = QtWidgets.QTabWidget(NodeInfoDialog)
self.uiTabWidget.setObjectName("uiTabWidget")
self.uiGeneralTab = QtWidgets.QWidget()
self.uiGeneralTab.setObjectName("uiGeneralTab")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.uiGeneralTab)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.uiGeneralTextBrowser = QtWidgets.QTextBrowser(self.uiGeneralTab)
self.uiGeneralTextBrowser.setObjectName("uiGeneralTextBrowser")
self.verticalLayout_2.addWidget(self.uiGeneralTextBrowser)
self.uiTabWidget.addTab(self.uiGeneralTab, "")
self.uiUsageTab = QtWidgets.QWidget()
self.uiUsageTab.setObjectName("uiUsageTab")
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.uiUsageTab)
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.uiUsageTextBrowser = QtWidgets.QTextBrowser(self.uiUsageTab)
self.uiUsageTextBrowser.setObjectName("uiUsageTextBrowser")
self.verticalLayout_3.addWidget(self.uiUsageTextBrowser)
self.uiTabWidget.addTab(self.uiUsageTab, "")
self.uiCommandLineTab = QtWidgets.QWidget()
self.uiCommandLineTab.setObjectName("uiCommandLineTab")
self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.uiCommandLineTab)
self.verticalLayout_4.setObjectName("verticalLayout_4")
self.uiCommandLineTextBrowser = QtWidgets.QTextBrowser(self.uiCommandLineTab)
self.uiCommandLineTextBrowser.setObjectName("uiCommandLineTextBrowser")
self.verticalLayout_4.addWidget(self.uiCommandLineTextBrowser)
self.uiTabWidget.addTab(self.uiCommandLineTab, "")
self.verticalLayout.addWidget(self.uiTabWidget)
self.buttonBox = QtWidgets.QDialogButtonBox(NodeInfoDialog)
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Ok)
self.buttonBox.setObjectName("buttonBox")
self.verticalLayout.addWidget(self.buttonBox)
self.retranslateUi(NodeInfoDialog)
self.uiTabWidget.setCurrentIndex(0)
self.buttonBox.accepted.connect(NodeInfoDialog.accept)
self.buttonBox.rejected.connect(NodeInfoDialog.reject)
QtCore.QMetaObject.connectSlotsByName(NodeInfoDialog)
def retranslateUi(self, NodeInfoDialog):
_translate = QtCore.QCoreApplication.translate
NodeInfoDialog.setWindowTitle(_translate("NodeInfoDialog", "Node information"))
self.uiTabWidget.setTabText(self.uiTabWidget.indexOf(self.uiGeneralTab), _translate("NodeInfoDialog", "General information"))
self.uiTabWidget.setTabText(self.uiTabWidget.indexOf(self.uiUsageTab), _translate("NodeInfoDialog", "Usage instructions"))
self.uiTabWidget.setTabText(self.uiTabWidget.indexOf(self.uiCommandLineTab), _translate("NodeInfoDialog", "Command line"))
from . import resources_rc

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
width="100%"
height="100%"
viewBox="0 0 288 288"
id="svg7631"
xml:space="preserve"
inkscape:version="0.91 r13725"
sodipodi:docname="reset-hover.svg"><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2340"
inkscape:window-height="1385"
id="namedview18"
showgrid="false"
inkscape:zoom="2.3177389"
inkscape:cx="-16.399118"
inkscape:cy="126.68664"
inkscape:window-x="340"
inkscape:window-y="185"
inkscape:window-maximized="0"
inkscape:current-layer="svg7631" /><metadata
id="metadata33"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
id="defs31" /><path
d="M 147.26705,91.986922 146.18863,37.277276 21.300414,139.87236 150.26787,232.17374 148.83585,165.7999 c 47.34134,-36.57823 109.19862,2.9535 109.19862,2.9535 l 17.49555,13.08544 C 253.04664,104.77424 181.80723,92.973331 147.26705,91.986922 Z"
id="path7"
inkscape:connector-curvature="0"
style="fill:#231f20" /><path
d="M 143.00332,104.25026 141.92489,49.540624 16.996448,152.2514 145.9639,244.55278 144.53188,178.17894 c 47.34134,-36.57823 109.19864,2.9535 109.19864,2.9535 l 17.49553,13.08544 c -22.48336,-77.0646 -93.68256,-88.9812 -128.22273,-89.96762 z"
id="path9"
inkscape:connector-curvature="0"
style="fill:#b3b3b3;fill-opacity:1" /></svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
width="100%"
height="100%"
viewBox="0 0 288 288"
id="svg7631"
xml:space="preserve"
inkscape:version="0.91 r13725"
sodipodi:docname="reset.svg"><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2340"
inkscape:window-height="1385"
id="namedview18"
showgrid="false"
inkscape:zoom="2.3177389"
inkscape:cx="-114.12367"
inkscape:cy="126.68664"
inkscape:window-x="429"
inkscape:window-y="269"
inkscape:window-maximized="0"
inkscape:current-layer="svg7631" /><metadata
id="metadata33"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
id="defs31" /><path
d="M 147.26705,91.986922 146.18863,37.277276 21.300414,139.87236 150.26787,232.17374 148.83585,165.7999 c 47.34134,-36.57823 109.19862,2.9535 109.19862,2.9535 l 17.49555,13.08544 C 253.04664,104.77424 181.80723,92.973331 147.26705,91.986922 Z"
id="path7"
inkscape:connector-curvature="0"
style="fill:#231f20" /><path
d="M 143.00332,104.25026 141.92489,49.540624 16.996448,152.2514 145.9639,244.55278 144.53188,178.17894 c 47.34134,-36.57823 109.19864,2.9535 109.19864,2.9535 l 17.49553,13.08544 c -22.48336,-77.0646 -93.68256,-88.9812 -128.22273,-89.96762 z"
id="path9"
inkscape:connector-curvature="0"
style="fill:#999999;fill-opacity:1" /></svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
width="100%"
height="100%"
viewBox="0 0 288 288"
id="svg7631"
xml:space="preserve"
inkscape:version="0.91 r13725"
sodipodi:docname="reset-hover.svg"><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2340"
inkscape:window-height="1385"
id="namedview18"
showgrid="false"
inkscape:zoom="2.3177389"
inkscape:cx="81.325436"
inkscape:cy="126.68664"
inkscape:window-x="340"
inkscape:window-y="185"
inkscape:window-maximized="0"
inkscape:current-layer="svg7631" /><metadata
id="metadata33"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
id="defs31" /><path
d="M 147.26705,91.986922 146.18863,37.277276 21.300414,139.87236 150.26787,232.17374 148.83585,165.7999 c 47.34134,-36.57823 109.19862,2.9535 109.19862,2.9535 l 17.49555,13.08544 C 253.04664,104.77424 181.80723,92.973331 147.26705,91.986922 Z"
id="path7"
inkscape:connector-curvature="0"
style="fill:#231f20" /><path
d="M 143.00332,104.25026 141.92489,49.540624 16.996448,152.2514 145.9639,244.55278 144.53188,178.17894 c 47.34134,-36.57823 109.19864,2.9535 109.19864,2.9535 l 17.49553,13.08544 c -22.48336,-77.0646 -93.68256,-88.9812 -128.22273,-89.96762 z"
id="path9"
inkscape:connector-curvature="0"
style="fill:#808080;fill-opacity:1" /></svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
width="100%"
height="100%"
viewBox="0 0 288 288"
id="svg7631"
xml:space="preserve"
inkscape:version="0.91 r13725"
sodipodi:docname="reset.svg"><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2340"
inkscape:window-height="1385"
id="namedview18"
showgrid="false"
inkscape:zoom="2.3177389"
inkscape:cx="179.04999"
inkscape:cy="126.68664"
inkscape:window-x="429"
inkscape:window-y="269"
inkscape:window-maximized="0"
inkscape:current-layer="svg7631" /><metadata
id="metadata33"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
id="defs31" /><path
d="M 147.26705,91.986922 146.18863,37.277276 21.300414,139.87236 150.26787,232.17374 148.83585,165.7999 c 47.34134,-36.57823 109.19862,2.9535 109.19862,2.9535 l 17.49555,13.08544 C 253.04664,104.77424 181.80723,92.973331 147.26705,91.986922 Z"
id="path7"
inkscape:connector-curvature="0"
style="fill:#231f20" /><path
d="M 143.00332,104.25026 141.92489,49.540624 16.996448,152.2514 145.9639,244.55278 144.53188,178.17894 c 47.34134,-36.57823 109.19864,2.9535 109.19864,2.9535 l 17.49553,13.08544 c -22.48336,-77.0646 -93.68256,-88.9812 -128.22273,-89.96762 z"
id="path9"
inkscape:connector-curvature="0"
style="fill:#666666;fill-opacity:1" /></svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -155,6 +155,8 @@
<file>classic_icons/pause-hover.svg</file>
<file>classic_icons/pc.svg</file>
<file>classic_icons/pc-hover.svg</file>
<file>classic_icons/reset.svg</file>
<file>classic_icons/reset-hover.svg</file>
<file>classic_icons/minus.svg</file>
<file>classic_icons/minus-hover.svg</file>
<file>classic_icons/plus.svg</file>
@@ -256,6 +258,8 @@
<file>charcoal_icons/minus-hover.svg</file>
<file>charcoal_icons/plus.svg</file>
<file>charcoal_icons/plus-hover.svg</file>
<file>charcoal_icons/reset.svg</file>
<file>charcoal_icons/reset-hover.svg</file>
<file>charcoal_icons/rectangle.svg</file>
<file>charcoal_icons/rectangle-hover.svg</file>
<file>charcoal_icons/line.svg</file>