mirror of
https://github.com/GNS3/gns3-gui.git
synced 2026-05-17 00:46:01 +03:00
Merge branch '2.1' into 2.2
# Conflicts: # gns3/ui/resources_rc.py
This commit is contained in:
@@ -11,6 +11,8 @@ before_deploy:
|
||||
- sudo pip install urllib3[secure]
|
||||
deploy:
|
||||
provider: pypi
|
||||
edge:
|
||||
branch: v1.8.45
|
||||
user: noplay
|
||||
password:
|
||||
secure: FofcqlJjgqf2jaDaXpLHeigVoexbrOz3WwnDuiJpwJxeFUlPY8s2cQs/Bm+dzxzZaOaGiVE0A83v/Xa10yD5tflThHt4sqYJK3iQCinA7wgeAlDimB4xrWUNplfNJZ/Eod5Ssa++E02W+3i29PxpXY//mjCY7qDxaoxul1gnFJY=
|
||||
|
||||
@@ -319,7 +319,7 @@ class LocalConfig(QtCore.QObject):
|
||||
"""
|
||||
if Controller.instance().connected() and self._settings_retrieved_from_controller:
|
||||
# We save only non user specific sections
|
||||
section_to_save_on_controller = ["Builtin", "Docker", "IOU", "Qemu", "VMware", "VPCS", "VirtualBox", "GraphicsView", "Dynamips"]
|
||||
section_to_save_on_controller = ["Builtin", "Docker", "IOU", "Qemu", "VMware", "VPCS", "TraceNG", "VirtualBox", "GraphicsView", "Dynamips"]
|
||||
controller_settings = {}
|
||||
for key, val in self._settings.items():
|
||||
if key in section_to_save_on_controller:
|
||||
|
||||
@@ -145,7 +145,8 @@ def main():
|
||||
frozen_dirs = [
|
||||
frozen_dir,
|
||||
os.path.normpath(os.path.join(frozen_dir, 'dynamips')),
|
||||
os.path.normpath(os.path.join(frozen_dir, 'vpcs'))
|
||||
os.path.normpath(os.path.join(frozen_dir, 'vpcs')),
|
||||
os.path.normpath(os.path.join(frozen_dir, 'traceng'))
|
||||
]
|
||||
|
||||
os.environ["PATH"] = os.pathsep.join(frozen_dirs) + os.pathsep + os.environ.get("PATH", "")
|
||||
|
||||
@@ -19,9 +19,10 @@ from gns3.modules.builtin import Builtin
|
||||
from gns3.modules.dynamips import Dynamips
|
||||
from gns3.modules.iou import IOU
|
||||
from gns3.modules.vpcs import VPCS
|
||||
from gns3.modules.traceng import TraceNG
|
||||
from gns3.modules.virtualbox import VirtualBox
|
||||
from gns3.modules.qemu import Qemu
|
||||
from gns3.modules.vmware import VMware
|
||||
from gns3.modules.docker import Docker
|
||||
|
||||
MODULES = [Builtin, VPCS, Dynamips, IOU, Qemu, VirtualBox, VMware, Docker]
|
||||
MODULES = [Builtin, VPCS, Dynamips, IOU, Qemu, VirtualBox, VMware, Docker, TraceNG]
|
||||
|
||||
249
gns3/modules/traceng/__init__.py
Normal file
249
gns3/modules/traceng/__init__.py
Normal file
@@ -0,0 +1,249 @@
|
||||
# -*- 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/>.
|
||||
|
||||
"""
|
||||
TraceNG module implementation.
|
||||
"""
|
||||
|
||||
import os
|
||||
import copy
|
||||
import shutil
|
||||
|
||||
from gns3.local_config import LocalConfig
|
||||
from gns3.local_server_config import LocalServerConfig
|
||||
|
||||
from ..module import Module
|
||||
from .traceng_node import TraceNGNode
|
||||
from .settings import TRACENG_SETTINGS
|
||||
from .settings import TRACENG_NODES_SETTINGS
|
||||
|
||||
import logging
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TraceNG(Module):
|
||||
|
||||
"""
|
||||
TraceNG module.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
self._settings = {}
|
||||
self._nodes = []
|
||||
self._traceng_nodes = {}
|
||||
self._working_dir = ""
|
||||
self._loadSettings()
|
||||
|
||||
def configChangedSlot(self):
|
||||
# load the settings
|
||||
self._loadSettings()
|
||||
|
||||
def _loadSettings(self):
|
||||
"""
|
||||
Loads the settings from the persistent settings file.
|
||||
"""
|
||||
|
||||
self._settings = LocalConfig.instance().loadSectionSettings(self.__class__.__name__, TRACENG_SETTINGS)
|
||||
if not os.path.exists(self._settings["traceng_path"]):
|
||||
traceng_path = shutil.which("traceng")
|
||||
if traceng_path:
|
||||
self._settings["traceng_path"] = os.path.abspath(traceng_path)
|
||||
else:
|
||||
self._settings["traceng_path"] = ""
|
||||
|
||||
self._loadTraceNGNodes()
|
||||
|
||||
def _saveSettings(self):
|
||||
"""
|
||||
Saves the settings to the persistent settings file.
|
||||
"""
|
||||
|
||||
# save the settings
|
||||
LocalConfig.instance().saveSectionSettings(self.__class__.__name__, self._settings)
|
||||
|
||||
server_settings = {}
|
||||
if self._settings["traceng_path"]:
|
||||
# save some settings to the server config file
|
||||
server_settings["traceng_path"] = os.path.normpath(self._settings["traceng_path"])
|
||||
|
||||
config = LocalServerConfig.instance()
|
||||
config.saveSettings(self.__class__.__name__, server_settings)
|
||||
|
||||
def _loadTraceNGNodes(self):
|
||||
"""
|
||||
Load the TraceNG nodes from the persistent settings file.
|
||||
"""
|
||||
|
||||
self._traceng_nodes = {}
|
||||
settings = LocalConfig.instance().settings()
|
||||
if "nodes" in settings.get(self.__class__.__name__, {}):
|
||||
for node in settings[self.__class__.__name__]["nodes"]:
|
||||
name = node.get("name")
|
||||
server = node.get("server")
|
||||
key = "{server}:{name}".format(server=server, name=name)
|
||||
if key in self._traceng_nodes or not name or not server:
|
||||
continue
|
||||
node_settings = TRACENG_NODES_SETTINGS.copy()
|
||||
node_settings.update(node)
|
||||
self._traceng_nodes[key] = node_settings
|
||||
|
||||
def _saveTraceNGNodes(self):
|
||||
"""
|
||||
Saves the TraceNG nodes to the persistent settings file.
|
||||
"""
|
||||
|
||||
self._settings["nodes"] = list(self._traceng_nodes.values())
|
||||
self._saveSettings()
|
||||
|
||||
def addNode(self, node):
|
||||
"""
|
||||
Adds a node to this module.
|
||||
|
||||
:param node: Node instance
|
||||
"""
|
||||
|
||||
self._nodes.append(node)
|
||||
|
||||
def removeNode(self, node):
|
||||
"""
|
||||
Removes a node from this module.
|
||||
|
||||
:param node: Node instance
|
||||
"""
|
||||
|
||||
if node in self._nodes:
|
||||
self._nodes.remove(node)
|
||||
|
||||
def settings(self):
|
||||
"""
|
||||
Returns the module settings
|
||||
|
||||
:returns: module settings (dictionary)
|
||||
"""
|
||||
|
||||
return self._settings
|
||||
|
||||
def setSettings(self, settings):
|
||||
"""
|
||||
Sets the module settings
|
||||
|
||||
:param settings: module settings (dictionary)
|
||||
"""
|
||||
|
||||
self._settings.update(settings)
|
||||
self._saveSettings()
|
||||
|
||||
def instantiateNode(self, node_class, server, project):
|
||||
"""
|
||||
Instantiate a new node.
|
||||
|
||||
:param node_class: Node object
|
||||
:param server: HTTPClient instance
|
||||
:param project: Project instance
|
||||
"""
|
||||
|
||||
# create an instance of the node class
|
||||
return node_class(self, server, project)
|
||||
|
||||
def reset(self):
|
||||
"""
|
||||
Resets the module.
|
||||
"""
|
||||
|
||||
self._nodes.clear()
|
||||
|
||||
@staticmethod
|
||||
def getNodeType(name, platform=None):
|
||||
if name == "traceng":
|
||||
return TraceNGNode
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def vmConfigurationPage():
|
||||
from .pages.traceng_node_configuration_page import TraceNGNodeConfigurationPage
|
||||
return TraceNGNodeConfigurationPage
|
||||
|
||||
def VMs(self):
|
||||
"""
|
||||
Returns list of TraceNG nodes
|
||||
"""
|
||||
|
||||
return self._traceng_nodes
|
||||
|
||||
def setVMs(self, new_traceng_nodes):
|
||||
"""
|
||||
Sets TraceNG list
|
||||
|
||||
:param new_traceng_vms: TraceNG node list
|
||||
"""
|
||||
|
||||
self._traceng_nodes = new_traceng_nodes.copy()
|
||||
self._saveTraceNGNodes()
|
||||
|
||||
@staticmethod
|
||||
def classes():
|
||||
"""
|
||||
Returns all the node classes supported by this module.
|
||||
|
||||
:returns: list of classes
|
||||
"""
|
||||
|
||||
return [TraceNGNode]
|
||||
|
||||
def nodes(self):
|
||||
"""
|
||||
Returns all the node data necessary to represent a node
|
||||
in the nodes view and create a node on the scene.
|
||||
"""
|
||||
|
||||
nodes = []
|
||||
|
||||
# Add a default TraceNG not linked to a specific server
|
||||
nodes.append(
|
||||
{
|
||||
"class": TraceNGNode.__name__,
|
||||
"name": "TraceNG",
|
||||
"categories": [TraceNGNode.end_devices],
|
||||
"symbol": TraceNGNode.defaultSymbol(),
|
||||
"builtin": True
|
||||
}
|
||||
)
|
||||
return nodes
|
||||
|
||||
@staticmethod
|
||||
def preferencePages():
|
||||
"""
|
||||
:returns: QWidget object list
|
||||
"""
|
||||
|
||||
from .pages.traceng_preferences_page import TraceNGPreferencesPage
|
||||
from .pages.traceng_node_preferences_page import TraceNGNodePreferencesPage
|
||||
return [TraceNGPreferencesPage, TraceNGNodePreferencesPage]
|
||||
|
||||
@staticmethod
|
||||
def instance():
|
||||
"""
|
||||
Singleton to return only on instance of TraceNG module.
|
||||
|
||||
:returns: instance of TraceNG
|
||||
"""
|
||||
|
||||
if not hasattr(TraceNG, "_instance"):
|
||||
TraceNG._instance = TraceNG()
|
||||
return TraceNG._instance
|
||||
0
gns3/modules/traceng/dialogs/__init__.py
Normal file
0
gns3/modules/traceng/dialogs/__init__.py
Normal file
86
gns3/modules/traceng/dialogs/traceng_node_wizard.py
Normal file
86
gns3/modules/traceng/dialogs/traceng_node_wizard.py
Normal file
@@ -0,0 +1,86 @@
|
||||
# -*- 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/>.
|
||||
|
||||
"""
|
||||
Wizard for TraceNG nodes.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import ipaddress
|
||||
|
||||
from gns3.qt import QtGui, QtWidgets
|
||||
from gns3.node import Node
|
||||
from gns3.dialogs.vm_wizard import VMWizard
|
||||
|
||||
from ..ui.traceng_node_wizard_ui import Ui_TraceNGNodeWizard
|
||||
|
||||
|
||||
class TraceNGNodeWizard(VMWizard, Ui_TraceNGNodeWizard):
|
||||
|
||||
"""
|
||||
Wizard to create a TraceNG node template.
|
||||
|
||||
:param parent: parent widget
|
||||
"""
|
||||
|
||||
def __init__(self, traceng_nodes, parent):
|
||||
|
||||
super().__init__(traceng_nodes, parent)
|
||||
self.setPixmap(QtWidgets.QWizard.LogoPixmap, QtGui.QPixmap(":/icons/traceng.png"))
|
||||
self.uiNameWizardPage.registerField("name*", self.uiNameLineEdit)
|
||||
|
||||
# TraceNG is only supported on a local server
|
||||
self.uiRemoteRadioButton.setEnabled(False)
|
||||
self.uiVMRadioButton.setEnabled(False)
|
||||
|
||||
def validateCurrentPage(self):
|
||||
"""
|
||||
Validates the server.
|
||||
"""
|
||||
|
||||
if super().validateCurrentPage() is False:
|
||||
return False
|
||||
|
||||
if self.currentPage() == self.uiNameWizardPage:
|
||||
|
||||
if not sys.platform.startswith("win"):
|
||||
QtWidgets.QMessageBox.critical(self, "TraceNG", "TraceNG can only run on Windows with a local server")
|
||||
return False
|
||||
|
||||
ip_address = self.uiIPAddressLineEdit.text()
|
||||
if ip_address:
|
||||
try:
|
||||
ipaddress.IPv4Address(ip_address)
|
||||
except ipaddress.AddressValueError:
|
||||
QtWidgets.QMessageBox.critical(self, "IP address", "Invalid IP address format")
|
||||
return False
|
||||
return True
|
||||
|
||||
def getSettings(self):
|
||||
"""
|
||||
Returns the settings set in this Wizard.
|
||||
|
||||
:return: settings dict
|
||||
"""
|
||||
|
||||
settings = {"name": self.uiNameLineEdit.text(),
|
||||
"ip_address": self.uiIPAddressLineEdit.text(),
|
||||
"symbol": ":/symbols/traceng.svg",
|
||||
"category": Node.end_devices,
|
||||
"server": self._compute_id}
|
||||
|
||||
return settings
|
||||
0
gns3/modules/traceng/pages/__init__.py
Normal file
0
gns3/modules/traceng/pages/__init__.py
Normal file
150
gns3/modules/traceng/pages/traceng_node_configuration_page.py
Normal file
150
gns3/modules/traceng/pages/traceng_node_configuration_page.py
Normal file
@@ -0,0 +1,150 @@
|
||||
# -*- 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/>.
|
||||
|
||||
"""
|
||||
Configuration page for TraceNG nodes
|
||||
"""
|
||||
|
||||
import ipaddress
|
||||
|
||||
from gns3.qt import QtWidgets
|
||||
from gns3.local_server import LocalServer
|
||||
from gns3.node import Node
|
||||
from gns3.controller import Controller
|
||||
|
||||
from ..ui.traceng_node_configuration_page_ui import Ui_TraceNGNodeConfigPageWidget
|
||||
from gns3.dialogs.symbol_selection_dialog import SymbolSelectionDialog
|
||||
from gns3.dialogs.node_properties_dialog import ConfigurationError
|
||||
|
||||
class TraceNGNodeConfigurationPage(QtWidgets.QWidget, Ui_TraceNGNodeConfigPageWidget):
|
||||
|
||||
"""
|
||||
QWidget configuration page for TraceNG nodes.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
|
||||
super().__init__()
|
||||
self.setupUi(self)
|
||||
|
||||
self.uiSymbolToolButton.clicked.connect(self._symbolBrowserSlot)
|
||||
self._default_configs_dir = LocalServer.instance().localServerSettings()["configs_path"]
|
||||
if Controller.instance().isRemote():
|
||||
self.uiScriptFileToolButton.hide()
|
||||
|
||||
# add the categories
|
||||
for name, category in Node.defaultCategories().items():
|
||||
self.uiCategoryComboBox.addItem(name, category)
|
||||
|
||||
def _symbolBrowserSlot(self):
|
||||
"""
|
||||
Slot to open the symbol browser and select a new symbol.
|
||||
"""
|
||||
|
||||
symbol_path = self.uiSymbolLineEdit.text()
|
||||
dialog = SymbolSelectionDialog(self, symbol=symbol_path)
|
||||
dialog.show()
|
||||
if dialog.exec_():
|
||||
new_symbol_path = dialog.getSymbol()
|
||||
self.uiSymbolLineEdit.setText(new_symbol_path)
|
||||
self.uiSymbolLineEdit.setToolTip('<img src="{}"/>'.format(new_symbol_path))
|
||||
|
||||
def loadSettings(self, settings, node=None, group=False):
|
||||
"""
|
||||
Loads the TraceNG node settings.
|
||||
|
||||
:param settings: the settings (dictionary)
|
||||
:param node: Node instance
|
||||
:param group: indicates the settings apply to a group of routers
|
||||
"""
|
||||
|
||||
if not group:
|
||||
self.uiNameLineEdit.setText(settings["name"])
|
||||
self.uiIPAddressLineEdit.setText(settings["ip_address"])
|
||||
else:
|
||||
self.uiIPAddressLabel.hide()
|
||||
self.uiIPAddressLineEdit.hide()
|
||||
self.uiNameLabel.hide()
|
||||
self.uiNameLineEdit.hide()
|
||||
|
||||
if not node:
|
||||
# these are template settings
|
||||
|
||||
# rename the label from "Name" to "Template name"
|
||||
self.uiNameLabel.setText("Template name:")
|
||||
|
||||
# load the default name format
|
||||
self.uiDefaultNameFormatLineEdit.setText(settings["default_name_format"])
|
||||
|
||||
# load the symbol
|
||||
self.uiSymbolLineEdit.setText(settings["symbol"])
|
||||
self.uiSymbolLineEdit.setToolTip('<img src="{}"/>'.format(settings["symbol"]))
|
||||
|
||||
# load the category
|
||||
index = self.uiCategoryComboBox.findData(settings["category"])
|
||||
if index != -1:
|
||||
self.uiCategoryComboBox.setCurrentIndex(index)
|
||||
else:
|
||||
self.uiDefaultNameFormatLabel.hide()
|
||||
self.uiDefaultNameFormatLineEdit.hide()
|
||||
self.uiSymbolLabel.hide()
|
||||
self.uiSymbolLineEdit.hide()
|
||||
self.uiSymbolToolButton.hide()
|
||||
self.uiCategoryComboBox.hide()
|
||||
self.uiCategoryLabel.hide()
|
||||
self.uiCategoryComboBox.hide()
|
||||
|
||||
def saveSettings(self, settings, node=None, group=False):
|
||||
"""
|
||||
Saves the TraceNG node settings.
|
||||
|
||||
:param settings: the settings (dictionary)
|
||||
:param node: Node instance
|
||||
:param group: indicates the settings apply to a group of routers
|
||||
"""
|
||||
|
||||
# these settings cannot be shared by nodes and updated
|
||||
# in the node properties dialog.
|
||||
if not group:
|
||||
# set the node name
|
||||
name = self.uiNameLineEdit.text()
|
||||
if not name:
|
||||
QtWidgets.QMessageBox.critical(self, "Name", "TraceNG node name cannot be empty!")
|
||||
else:
|
||||
settings["name"] = name
|
||||
|
||||
ip_address = self.uiIPAddressLineEdit.text()
|
||||
if ip_address:
|
||||
try:
|
||||
ipaddress.IPv4Address(ip_address)
|
||||
settings["ip_address"] = ip_address
|
||||
except ipaddress.AddressValueError:
|
||||
QtWidgets.QMessageBox.critical(self, "IP address", "Invalid IP address format")
|
||||
if node:
|
||||
raise ConfigurationError()
|
||||
|
||||
if not node:
|
||||
default_name_format = self.uiDefaultNameFormatLineEdit.text().strip()
|
||||
if '{0}' not in default_name_format and '{id}' not in default_name_format:
|
||||
QtWidgets.QMessageBox.critical(self, "Default name format", "The default name format must contain at least {0} or {id}")
|
||||
else:
|
||||
settings["default_name_format"] = default_name_format
|
||||
|
||||
symbol_path = self.uiSymbolLineEdit.text()
|
||||
settings["symbol"] = symbol_path
|
||||
settings["category"] = self.uiCategoryComboBox.itemData(self.uiCategoryComboBox.currentIndex())
|
||||
return settings
|
||||
189
gns3/modules/traceng/pages/traceng_node_preferences_page.py
Normal file
189
gns3/modules/traceng/pages/traceng_node_preferences_page.py
Normal file
@@ -0,0 +1,189 @@
|
||||
# -*- 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/>.
|
||||
|
||||
"""
|
||||
Configuration page for TraceNG node preferences.
|
||||
"""
|
||||
|
||||
import copy
|
||||
|
||||
from gns3.qt import QtCore, QtWidgets, qpartial
|
||||
|
||||
from gns3.main_window import MainWindow
|
||||
from gns3.dialogs.configuration_dialog import ConfigurationDialog
|
||||
from gns3.compute_manager import ComputeManager
|
||||
from gns3.controller import Controller
|
||||
|
||||
from .. import TraceNG
|
||||
from ..settings import TRACENG_NODES_SETTINGS
|
||||
from ..ui.traceng_node_preferences_page_ui import Ui_TraceNGNodePageWidget
|
||||
from ..pages.traceng_node_configuration_page import TraceNGNodeConfigurationPage
|
||||
from ..dialogs.traceng_node_wizard import TraceNGNodeWizard
|
||||
|
||||
|
||||
class TraceNGNodePreferencesPage(QtWidgets.QWidget, Ui_TraceNGNodePageWidget):
|
||||
"""
|
||||
QWidget preference page for TraceNG node preferences.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.setupUi(self)
|
||||
|
||||
self._main_window = MainWindow.instance()
|
||||
self._traceng_nodes = {}
|
||||
self._items = []
|
||||
|
||||
self.uiNewTraceNGPushButton.clicked.connect(self._newTraceNGSlot)
|
||||
self.uiEditTraceNGPushButton.clicked.connect(self._editTraceNGSlot)
|
||||
self.uiDeleteTraceNGPushButton.clicked.connect(self._deleteTraceNGSlot)
|
||||
self.uiTraceNGTreeWidget.itemSelectionChanged.connect(self._tracengChangedSlot)
|
||||
|
||||
def _createSectionItem(self, name):
|
||||
|
||||
section_item = QtWidgets.QTreeWidgetItem(self.uiTraceNGInfoTreeWidget)
|
||||
section_item.setText(0, name)
|
||||
font = section_item.font(0)
|
||||
font.setBold(True)
|
||||
section_item.setFont(0, font)
|
||||
return section_item
|
||||
|
||||
def _refreshInfo(self, traceng_node):
|
||||
|
||||
self.uiTraceNGInfoTreeWidget.clear()
|
||||
|
||||
# fill out the General section
|
||||
section_item = self._createSectionItem("General")
|
||||
QtWidgets.QTreeWidgetItem(section_item, ["Template name:", traceng_node["name"]])
|
||||
QtWidgets.QTreeWidgetItem(section_item, ["IP address:", traceng_node["ip_address"]])
|
||||
QtWidgets.QTreeWidgetItem(section_item, ["Default name format:", traceng_node["default_name_format"]])
|
||||
try:
|
||||
QtWidgets.QTreeWidgetItem(section_item, ["Server:", ComputeManager.instance().getCompute(traceng_node["server"]).name()])
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
self.uiTraceNGInfoTreeWidget.expandAll()
|
||||
self.uiTraceNGInfoTreeWidget.resizeColumnToContents(0)
|
||||
self.uiTraceNGInfoTreeWidget.resizeColumnToContents(1)
|
||||
self.uiTraceNGTreeWidget.setMaximumWidth(self.uiTraceNGTreeWidget.sizeHintForColumn(0) + 20)
|
||||
|
||||
def _tracengChangedSlot(self):
|
||||
"""
|
||||
Loads a selected TraceNG node template from the tree widget.
|
||||
"""
|
||||
|
||||
selection = self.uiTraceNGTreeWidget.selectedItems()
|
||||
self.uiDeleteTraceNGPushButton.setEnabled(len(selection) != 0)
|
||||
single_selected = len(selection) == 1
|
||||
self.uiEditTraceNGPushButton.setEnabled(single_selected)
|
||||
|
||||
if single_selected:
|
||||
key = selection[0].data(0, QtCore.Qt.UserRole)
|
||||
traceng_node = self._traceng_nodes[key]
|
||||
self._refreshInfo(traceng_node)
|
||||
else:
|
||||
self.uiTraceNGInfoTreeWidget.clear()
|
||||
|
||||
def _newTraceNGSlot(self):
|
||||
"""
|
||||
Creates a new TraceNG node template.
|
||||
"""
|
||||
|
||||
wizard = TraceNGNodeWizard(self._traceng_nodes, parent=self)
|
||||
wizard.show()
|
||||
if wizard.exec_():
|
||||
new_traceng_node_settings = wizard.getSettings()
|
||||
key = "{server}:{name}".format(server=new_traceng_node_settings["server"], name=new_traceng_node_settings["name"])
|
||||
self._traceng_nodes[key] = TRACENG_NODES_SETTINGS.copy()
|
||||
self._traceng_nodes[key].update(new_traceng_node_settings)
|
||||
|
||||
item = QtWidgets.QTreeWidgetItem(self.uiTraceNGTreeWidget)
|
||||
item.setText(0, self._traceng_nodes[key]["name"])
|
||||
Controller.instance().getSymbolIcon(self._traceng_nodes[key]["symbol"], qpartial(self._setItemIcon, item))
|
||||
item.setData(0, QtCore.Qt.UserRole, key)
|
||||
self._items.append(item)
|
||||
self.uiTraceNGTreeWidget.setCurrentItem(item)
|
||||
|
||||
def _editTraceNGSlot(self):
|
||||
"""
|
||||
Edits a TraceNG node template.
|
||||
"""
|
||||
|
||||
item = self.uiTraceNGTreeWidget.currentItem()
|
||||
if item:
|
||||
key = item.data(0, QtCore.Qt.UserRole)
|
||||
traceng_node = self._traceng_nodes[key]
|
||||
dialog = ConfigurationDialog(traceng_node["name"], traceng_node, TraceNGNodeConfigurationPage(), parent=self)
|
||||
dialog.show()
|
||||
if dialog.exec_():
|
||||
# update the icon
|
||||
Controller.instance().getSymbolIcon(traceng_node["symbol"], qpartial(self._setItemIcon, item))
|
||||
if traceng_node["name"] != item.text(0):
|
||||
new_key = "{server}:{name}".format(server=traceng_node["server"], name=traceng_node["name"])
|
||||
if new_key in self._traceng_nodes:
|
||||
QtWidgets.QMessageBox.critical(self, "TraceNG node", "TraceNG node name {} already exists for server {}".format(traceng_node["name"],
|
||||
traceng_node["server"]))
|
||||
traceng_node["name"] = item.text(0)
|
||||
return
|
||||
self._traceng_nodes[new_key] = self._traceng_nodes[key]
|
||||
del self._traceng_nodes[key]
|
||||
item.setText(0, traceng_node["name"])
|
||||
item.setData(0, QtCore.Qt.UserRole, new_key)
|
||||
self._refreshInfo(traceng_node)
|
||||
|
||||
def _deleteTraceNGSlot(self):
|
||||
"""
|
||||
Deletes a TraceNG node template.
|
||||
"""
|
||||
|
||||
for item in self.uiTraceNGTreeWidget.selectedItems():
|
||||
if item:
|
||||
key = item.data(0, QtCore.Qt.UserRole)
|
||||
del self._traceng_nodes[key]
|
||||
self.uiTraceNGTreeWidget.takeTopLevelItem(self.uiTraceNGTreeWidget.indexOfTopLevelItem(item))
|
||||
|
||||
def loadPreferences(self):
|
||||
"""
|
||||
Loads the TraceNG node preferences.
|
||||
"""
|
||||
|
||||
traceng_module = TraceNG.instance()
|
||||
self._traceng_nodes = copy.deepcopy(traceng_module.VMs())
|
||||
self._items.clear()
|
||||
|
||||
for key, node in self._traceng_nodes.items():
|
||||
item = QtWidgets.QTreeWidgetItem(self.uiTraceNGTreeWidget)
|
||||
item.setText(0, node["name"])
|
||||
Controller.instance().getSymbolIcon(node["symbol"], qpartial(self._setItemIcon, item))
|
||||
item.setData(0, QtCore.Qt.UserRole, key)
|
||||
self._items.append(item)
|
||||
|
||||
if self._items:
|
||||
self.uiTraceNGTreeWidget.setCurrentItem(self._items[0])
|
||||
self.uiTraceNGTreeWidget.sortByColumn(0, QtCore.Qt.AscendingOrder)
|
||||
self.uiTraceNGTreeWidget.setMaximumWidth(self.uiTraceNGTreeWidget.sizeHintForColumn(0) + 20)
|
||||
|
||||
def _setItemIcon(self, item, icon):
|
||||
item.setIcon(0, icon)
|
||||
self.uiTraceNGTreeWidget.setMaximumWidth(self.uiTraceNGTreeWidget.sizeHintForColumn(0) + 20)
|
||||
|
||||
def savePreferences(self):
|
||||
"""
|
||||
Saves the TraceNG node preferences.
|
||||
"""
|
||||
|
||||
TraceNG.instance().setVMs(self._traceng_nodes)
|
||||
127
gns3/modules/traceng/pages/traceng_preferences_page.py
Normal file
127
gns3/modules/traceng/pages/traceng_preferences_page.py
Normal file
@@ -0,0 +1,127 @@
|
||||
# -*- 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/>.
|
||||
|
||||
"""
|
||||
Configuration page for TraceNG preferences.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
|
||||
from gns3.qt import QtWidgets
|
||||
|
||||
from .. import TraceNG
|
||||
from ..ui.traceng_preferences_page_ui import Ui_TraceNGPreferencesPageWidget
|
||||
from ..settings import TRACENG_SETTINGS
|
||||
|
||||
|
||||
class TraceNGPreferencesPage(QtWidgets.QWidget, Ui_TraceNGPreferencesPageWidget):
|
||||
|
||||
"""
|
||||
QWidget preference page for TraceNG
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
|
||||
super().__init__()
|
||||
self.setupUi(self)
|
||||
|
||||
# connect signals
|
||||
self.uiRestoreDefaultsPushButton.clicked.connect(self._restoreDefaultsSlot)
|
||||
self.uiTraceNGPathToolButton.clicked.connect(self._tracengPathBrowserSlot)
|
||||
|
||||
def _tracengPathBrowserSlot(self):
|
||||
"""
|
||||
Slot to open a file browser and select traceng
|
||||
"""
|
||||
|
||||
filter = ""
|
||||
if sys.platform.startswith("win"):
|
||||
filter = "Executable (*.exe);;All files (*.*)"
|
||||
traceng_path = shutil.which("traceng")
|
||||
path, _ = QtWidgets.QFileDialog.getOpenFileName(self, "Select TraceNG", traceng_path, filter)
|
||||
if not path:
|
||||
return
|
||||
|
||||
if self._checkTraceNGPath(path):
|
||||
self.uiTraceNGPathLineEdit.setText(os.path.normpath(path))
|
||||
|
||||
def _checkTraceNGPath(self, path):
|
||||
"""
|
||||
Checks that the TraceNG path is valid.
|
||||
|
||||
:param path: TraceNG path
|
||||
:returns: boolean
|
||||
"""
|
||||
|
||||
if not os.path.exists(path):
|
||||
QtWidgets.QMessageBox.critical(self, "TraceNG", '"{}" does not exist'.format(path))
|
||||
return False
|
||||
|
||||
if not os.access(path, os.X_OK):
|
||||
QtWidgets.QMessageBox.critical(self, "TraceNG", "{} is not an executable".format(os.path.basename(path)))
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def _restoreDefaultsSlot(self):
|
||||
"""
|
||||
Slot to populate the page widgets with the default settings.
|
||||
"""
|
||||
|
||||
self._populateWidgets(TRACENG_SETTINGS)
|
||||
|
||||
def _useLocalServerSlot(self, state):
|
||||
"""
|
||||
Slot to enable or not local server settings.
|
||||
"""
|
||||
|
||||
if state:
|
||||
self.uiTraceNGPathLineEdit.setEnabled(True)
|
||||
self.uiTraceNGPathToolButton.setEnabled(True)
|
||||
else:
|
||||
self.uiTraceNGPathLineEdit.setEnabled(False)
|
||||
self.uiTraceNGPathToolButton.setEnabled(False)
|
||||
|
||||
def _populateWidgets(self, settings):
|
||||
"""
|
||||
Populates the widgets with the settings.
|
||||
|
||||
:param settings: TraceNG settings
|
||||
"""
|
||||
|
||||
self.uiTraceNGPathLineEdit.setText(settings["traceng_path"])
|
||||
|
||||
def loadPreferences(self):
|
||||
"""
|
||||
Loads TraceNG preferences.
|
||||
"""
|
||||
|
||||
traceng_settings = TraceNG.instance().settings()
|
||||
self._populateWidgets(traceng_settings)
|
||||
|
||||
def savePreferences(self):
|
||||
"""
|
||||
Saves TraceNG preferences.
|
||||
"""
|
||||
|
||||
traceng_path = self.uiTraceNGPathLineEdit.text().strip()
|
||||
if traceng_path and not self._checkTraceNGPath(traceng_path):
|
||||
return
|
||||
new_settings = {"traceng_path": traceng_path}
|
||||
TraceNG.instance().setSettings(new_settings)
|
||||
35
gns3/modules/traceng/settings.py
Normal file
35
gns3/modules/traceng/settings.py
Normal file
@@ -0,0 +1,35 @@
|
||||
# -*- 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/>.
|
||||
|
||||
"""
|
||||
Default TraceNG settings.
|
||||
"""
|
||||
|
||||
from gns3.node import Node
|
||||
|
||||
TRACENG_SETTINGS = {
|
||||
"traceng_path": "",
|
||||
}
|
||||
|
||||
TRACENG_NODES_SETTINGS = {
|
||||
"name": "",
|
||||
"ip_address": "",
|
||||
"default_name_format": "TraceNG{0}",
|
||||
"console_type": "none",
|
||||
"symbol": ":/symbols/traceng.svg",
|
||||
"category": Node.end_devices,
|
||||
}
|
||||
161
gns3/modules/traceng/traceng_node.py
Normal file
161
gns3/modules/traceng/traceng_node.py
Normal file
@@ -0,0 +1,161 @@
|
||||
# -*- 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/>.
|
||||
|
||||
"""
|
||||
TraceNG node implementation.
|
||||
"""
|
||||
|
||||
from gns3.node import Node
|
||||
from gns3.qt import QtWidgets
|
||||
|
||||
import logging
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TraceNGNode(Node):
|
||||
"""
|
||||
TraceNG node.
|
||||
|
||||
:param module: parent module for this node
|
||||
:param server: GNS3 server instance
|
||||
:param project: Project instance
|
||||
"""
|
||||
URL_PREFIX = "traceng"
|
||||
|
||||
def __init__(self, module, server, project):
|
||||
super().__init__(module, server, project)
|
||||
|
||||
traceng_settings = {"console_host": None,
|
||||
"console": None,
|
||||
"console_type": "none",
|
||||
"ip_address": ""}
|
||||
|
||||
self.settings().update(traceng_settings)
|
||||
|
||||
def update(self, new_settings):
|
||||
"""
|
||||
Updates the settings for this TraceNG node.
|
||||
|
||||
:param new_settings: settings dictionary
|
||||
"""
|
||||
|
||||
params = {}
|
||||
for name, value in new_settings.items():
|
||||
if name in self._settings and self._settings[name] != value:
|
||||
params[name] = value
|
||||
|
||||
if params:
|
||||
self._update(params)
|
||||
|
||||
def start(self):
|
||||
"""
|
||||
Starts this node instance.
|
||||
"""
|
||||
|
||||
if self.isStarted():
|
||||
log.debug("{} is already running".format(self.name()))
|
||||
return
|
||||
|
||||
destination, ok = QtWidgets.QInputDialog.getText(self.parent(), "TraceNG", "Destination host or IP address:")
|
||||
if ok:
|
||||
if not destination:
|
||||
QtWidgets.QMessageBox.critical(self, "TraceNG", "Please provide a host or IP address to trace")
|
||||
return
|
||||
params = {"destination": destination}
|
||||
log.debug("{} is starting".format(self.name()))
|
||||
self.controllerHttpPost("/nodes/{node_id}/start".format(node_id=self._node_id), self._startCallback, body=params, timeout=None, progressText="{} is starting".format(self.name()))
|
||||
|
||||
def info(self):
|
||||
"""
|
||||
Returns information about this TraceNG node.
|
||||
|
||||
:returns: formatted string
|
||||
"""
|
||||
|
||||
if self.status() == Node.started:
|
||||
state = "started"
|
||||
else:
|
||||
state = "stopped"
|
||||
|
||||
info = """Node {name} is {state}
|
||||
Local node ID is {id}
|
||||
Server's VPCS node ID is {node_id}
|
||||
TraceNG's server runs on {host}, console is on port {console}
|
||||
""".format(name=self.name(),
|
||||
id=self.id(),
|
||||
node_id=self._node_id,
|
||||
state=state,
|
||||
host=self.compute().name(),
|
||||
console=self._settings["console"])
|
||||
|
||||
port_info = ""
|
||||
for port in self._ports:
|
||||
if port.isFree():
|
||||
port_info += " {port_name} is empty\n".format(port_name=port.name())
|
||||
else:
|
||||
port_info += " {port_name} {port_description}\n".format(port_name=port.name(),
|
||||
port_description=port.description())
|
||||
|
||||
return info + port_info
|
||||
|
||||
def console(self):
|
||||
"""
|
||||
Returns the console port for this TraceNG node.
|
||||
|
||||
:returns: port (integer)
|
||||
"""
|
||||
|
||||
return self._settings["console"]
|
||||
|
||||
def configPage(self):
|
||||
"""
|
||||
Returns the configuration page widget to be used by the node properties dialog.
|
||||
|
||||
:returns: QWidget object
|
||||
"""
|
||||
|
||||
from .pages.traceng_node_configuration_page import TraceNGNodeConfigurationPage
|
||||
return TraceNGNodeConfigurationPage
|
||||
|
||||
@staticmethod
|
||||
def defaultSymbol():
|
||||
"""
|
||||
Returns the default symbol path for this node.
|
||||
|
||||
:returns: symbol path (or resource).
|
||||
"""
|
||||
|
||||
return ":/symbols/traceng.svg"
|
||||
|
||||
@staticmethod
|
||||
def symbolName():
|
||||
|
||||
return "TraceNG"
|
||||
|
||||
@staticmethod
|
||||
def categories():
|
||||
"""
|
||||
Returns the node categories the node is part of (used by the node panel).
|
||||
|
||||
:returns: list of node categories
|
||||
"""
|
||||
|
||||
return [Node.end_devices]
|
||||
|
||||
def __str__(self):
|
||||
|
||||
return "TraceNG node"
|
||||
0
gns3/modules/traceng/ui/__init__.py
Normal file
0
gns3/modules/traceng/ui/__init__.py
Normal file
109
gns3/modules/traceng/ui/traceng_node_configuration_page.ui
Executable file
109
gns3/modules/traceng/ui/traceng_node_configuration_page.ui
Executable file
@@ -0,0 +1,109 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TraceNGNodeConfigPageWidget</class>
|
||||
<widget class="QWidget" name="TraceNGNodeConfigPageWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>565</width>
|
||||
<height>390</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>TraceNG node configuration</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="uiNameLabel">
|
||||
<property name="text">
|
||||
<string>Name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLineEdit" name="uiNameLineEdit"/>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QLabel" name="uiIPAddressLabel">
|
||||
<property name="text">
|
||||
<string>IP address:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLineEdit" name="uiIPAddressLineEdit"/>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QLabel" name="uiDefaultNameFormatLabel">
|
||||
<property name="text">
|
||||
<string>Default name format:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLineEdit" name="uiDefaultNameFormatLineEdit"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="uiSymbolLabel">
|
||||
<property name="text">
|
||||
<string>Symbol:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="uiSymbolLineEdit"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="uiSymbolToolButton">
|
||||
<property name="text">
|
||||
<string>&Browse...</string>
|
||||
</property>
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonTextOnly</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="uiCategoryLabel">
|
||||
<property name="text">
|
||||
<string>Category:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QComboBox" name="uiCategoryComboBox"/>
|
||||
</item>
|
||||
<item row="5" column="1" colspan="2">
|
||||
<spacer name="spacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>263</width>
|
||||
<height>212</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
<zorder>uiNameLabel</zorder>
|
||||
<zorder>uiNameLineEdit</zorder>
|
||||
<zorder>uiDefaultNameFormatLabel</zorder>
|
||||
<zorder>uiDefaultNameFormatLineEdit</zorder>
|
||||
<zorder>uiSymbolLabel</zorder>
|
||||
<zorder>uiCategoryLabel</zorder>
|
||||
<zorder>uiCategoryComboBox</zorder>
|
||||
<zorder>uiSymbolLineEdit</zorder>
|
||||
<zorder>uiSymbolToolButton</zorder>
|
||||
<zorder>uiIPAddressLabel</zorder>
|
||||
<zorder>uiIPAddressLineEdit</zorder>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -0,0 +1,80 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file '/home/grossmj/PycharmProjects/gns3-gui/gns3/modules/traceng/ui/traceng_node_configuration_page.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.5.1
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
class Ui_TraceNGNodeConfigPageWidget(object):
|
||||
def setupUi(self, TraceNGNodeConfigPageWidget):
|
||||
TraceNGNodeConfigPageWidget.setObjectName("TraceNGNodeConfigPageWidget")
|
||||
TraceNGNodeConfigPageWidget.resize(565, 390)
|
||||
self.gridLayout = QtWidgets.QGridLayout(TraceNGNodeConfigPageWidget)
|
||||
self.gridLayout.setObjectName("gridLayout")
|
||||
self.uiNameLabel = QtWidgets.QLabel(TraceNGNodeConfigPageWidget)
|
||||
self.uiNameLabel.setObjectName("uiNameLabel")
|
||||
self.gridLayout.addWidget(self.uiNameLabel, 0, 0, 1, 1)
|
||||
self.uiNameLineEdit = QtWidgets.QLineEdit(TraceNGNodeConfigPageWidget)
|
||||
self.uiNameLineEdit.setObjectName("uiNameLineEdit")
|
||||
self.gridLayout.addWidget(self.uiNameLineEdit, 0, 2, 1, 1)
|
||||
self.uiIPAddressLabel = QtWidgets.QLabel(TraceNGNodeConfigPageWidget)
|
||||
self.uiIPAddressLabel.setObjectName("uiIPAddressLabel")
|
||||
self.gridLayout.addWidget(self.uiIPAddressLabel, 1, 0, 1, 2)
|
||||
self.uiIPAddressLineEdit = QtWidgets.QLineEdit(TraceNGNodeConfigPageWidget)
|
||||
self.uiIPAddressLineEdit.setObjectName("uiIPAddressLineEdit")
|
||||
self.gridLayout.addWidget(self.uiIPAddressLineEdit, 1, 2, 1, 1)
|
||||
self.uiDefaultNameFormatLabel = QtWidgets.QLabel(TraceNGNodeConfigPageWidget)
|
||||
self.uiDefaultNameFormatLabel.setObjectName("uiDefaultNameFormatLabel")
|
||||
self.gridLayout.addWidget(self.uiDefaultNameFormatLabel, 2, 0, 1, 2)
|
||||
self.uiDefaultNameFormatLineEdit = QtWidgets.QLineEdit(TraceNGNodeConfigPageWidget)
|
||||
self.uiDefaultNameFormatLineEdit.setObjectName("uiDefaultNameFormatLineEdit")
|
||||
self.gridLayout.addWidget(self.uiDefaultNameFormatLineEdit, 2, 2, 1, 1)
|
||||
self.uiSymbolLabel = QtWidgets.QLabel(TraceNGNodeConfigPageWidget)
|
||||
self.uiSymbolLabel.setObjectName("uiSymbolLabel")
|
||||
self.gridLayout.addWidget(self.uiSymbolLabel, 3, 0, 1, 1)
|
||||
self.horizontalLayout_7 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_7.setObjectName("horizontalLayout_7")
|
||||
self.uiSymbolLineEdit = QtWidgets.QLineEdit(TraceNGNodeConfigPageWidget)
|
||||
self.uiSymbolLineEdit.setObjectName("uiSymbolLineEdit")
|
||||
self.horizontalLayout_7.addWidget(self.uiSymbolLineEdit)
|
||||
self.uiSymbolToolButton = QtWidgets.QToolButton(TraceNGNodeConfigPageWidget)
|
||||
self.uiSymbolToolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextOnly)
|
||||
self.uiSymbolToolButton.setObjectName("uiSymbolToolButton")
|
||||
self.horizontalLayout_7.addWidget(self.uiSymbolToolButton)
|
||||
self.gridLayout.addLayout(self.horizontalLayout_7, 3, 2, 1, 1)
|
||||
self.uiCategoryLabel = QtWidgets.QLabel(TraceNGNodeConfigPageWidget)
|
||||
self.uiCategoryLabel.setObjectName("uiCategoryLabel")
|
||||
self.gridLayout.addWidget(self.uiCategoryLabel, 4, 0, 1, 1)
|
||||
self.uiCategoryComboBox = QtWidgets.QComboBox(TraceNGNodeConfigPageWidget)
|
||||
self.uiCategoryComboBox.setObjectName("uiCategoryComboBox")
|
||||
self.gridLayout.addWidget(self.uiCategoryComboBox, 4, 2, 1, 1)
|
||||
spacerItem = QtWidgets.QSpacerItem(263, 212, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
||||
self.gridLayout.addItem(spacerItem, 5, 1, 1, 2)
|
||||
self.uiNameLabel.raise_()
|
||||
self.uiNameLineEdit.raise_()
|
||||
self.uiDefaultNameFormatLabel.raise_()
|
||||
self.uiDefaultNameFormatLineEdit.raise_()
|
||||
self.uiSymbolLabel.raise_()
|
||||
self.uiCategoryLabel.raise_()
|
||||
self.uiCategoryComboBox.raise_()
|
||||
self.uiSymbolLineEdit.raise_()
|
||||
self.uiSymbolToolButton.raise_()
|
||||
self.uiIPAddressLabel.raise_()
|
||||
self.uiIPAddressLineEdit.raise_()
|
||||
|
||||
self.retranslateUi(TraceNGNodeConfigPageWidget)
|
||||
QtCore.QMetaObject.connectSlotsByName(TraceNGNodeConfigPageWidget)
|
||||
|
||||
def retranslateUi(self, TraceNGNodeConfigPageWidget):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
TraceNGNodeConfigPageWidget.setWindowTitle(_translate("TraceNGNodeConfigPageWidget", "TraceNG node configuration"))
|
||||
self.uiNameLabel.setText(_translate("TraceNGNodeConfigPageWidget", "Name:"))
|
||||
self.uiIPAddressLabel.setText(_translate("TraceNGNodeConfigPageWidget", "IP address:"))
|
||||
self.uiDefaultNameFormatLabel.setText(_translate("TraceNGNodeConfigPageWidget", "Default name format:"))
|
||||
self.uiSymbolLabel.setText(_translate("TraceNGNodeConfigPageWidget", "Symbol:"))
|
||||
self.uiSymbolToolButton.setText(_translate("TraceNGNodeConfigPageWidget", "&Browse..."))
|
||||
self.uiCategoryLabel.setText(_translate("TraceNGNodeConfigPageWidget", "Category:"))
|
||||
|
||||
160
gns3/modules/traceng/ui/traceng_node_preferences_page.ui
Normal file
160
gns3/modules/traceng/ui/traceng_node_preferences_page.ui
Normal file
@@ -0,0 +1,160 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TraceNGNodePageWidget</class>
|
||||
<widget class="QWidget" name="TraceNGNodePageWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>546</width>
|
||||
<height>455</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>TraceNG nodes</string>
|
||||
</property>
|
||||
<property name="accessibleName">
|
||||
<string>TraceNG node templates</string>
|
||||
</property>
|
||||
<property name="accessibleDescription">
|
||||
<string/>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="QTreeWidget" name="uiTraceNGTreeWidget">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>160</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="rootIsDecorated">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<attribute name="headerVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string notr="true">1</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
<widget class="QWidget" name="layoutWidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTreeWidget" name="uiTraceNGInfoTreeWidget">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="indentation">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="allColumnsShowFocus">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="headerVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>1</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>2</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QPushButton" name="uiNewTraceNGPushButton">
|
||||
<property name="text">
|
||||
<string>&New</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="uiEditTraceNGPushButton">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Edit</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="uiDeleteTraceNGPushButton">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Delete</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>uiNewTraceNGPushButton</tabstop>
|
||||
<tabstop>uiDeleteTraceNGPushButton</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
<designerdata>
|
||||
<property name="gridDeltaX">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="gridDeltaY">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="gridSnapX">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="gridSnapY">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="gridVisible">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</designerdata>
|
||||
</ui>
|
||||
83
gns3/modules/traceng/ui/traceng_node_preferences_page_ui.py
Normal file
83
gns3/modules/traceng/ui/traceng_node_preferences_page_ui.py
Normal file
@@ -0,0 +1,83 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file '/home/grossmj/PycharmProjects/gns3-gui/gns3/modules/traceng/ui/traceng_node_preferences_page.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.5.1
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
class Ui_TraceNGNodePageWidget(object):
|
||||
def setupUi(self, TraceNGNodePageWidget):
|
||||
TraceNGNodePageWidget.setObjectName("TraceNGNodePageWidget")
|
||||
TraceNGNodePageWidget.resize(546, 455)
|
||||
TraceNGNodePageWidget.setAccessibleDescription("")
|
||||
self.verticalLayout_2 = QtWidgets.QVBoxLayout(TraceNGNodePageWidget)
|
||||
self.verticalLayout_2.setObjectName("verticalLayout_2")
|
||||
self.splitter = QtWidgets.QSplitter(TraceNGNodePageWidget)
|
||||
self.splitter.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.splitter.setObjectName("splitter")
|
||||
self.uiTraceNGTreeWidget = QtWidgets.QTreeWidget(self.splitter)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.uiTraceNGTreeWidget.sizePolicy().hasHeightForWidth())
|
||||
self.uiTraceNGTreeWidget.setSizePolicy(sizePolicy)
|
||||
self.uiTraceNGTreeWidget.setMaximumSize(QtCore.QSize(160, 16777215))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(11)
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.uiTraceNGTreeWidget.setFont(font)
|
||||
self.uiTraceNGTreeWidget.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
|
||||
self.uiTraceNGTreeWidget.setIconSize(QtCore.QSize(32, 32))
|
||||
self.uiTraceNGTreeWidget.setRootIsDecorated(False)
|
||||
self.uiTraceNGTreeWidget.setObjectName("uiTraceNGTreeWidget")
|
||||
self.uiTraceNGTreeWidget.headerItem().setText(0, "1")
|
||||
self.uiTraceNGTreeWidget.header().setVisible(False)
|
||||
self.layoutWidget = QtWidgets.QWidget(self.splitter)
|
||||
self.layoutWidget.setObjectName("layoutWidget")
|
||||
self.verticalLayout = QtWidgets.QVBoxLayout(self.layoutWidget)
|
||||
self.verticalLayout.setObjectName("verticalLayout")
|
||||
self.uiTraceNGInfoTreeWidget = QtWidgets.QTreeWidget(self.layoutWidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Expanding)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.uiTraceNGInfoTreeWidget.sizePolicy().hasHeightForWidth())
|
||||
self.uiTraceNGInfoTreeWidget.setSizePolicy(sizePolicy)
|
||||
self.uiTraceNGInfoTreeWidget.setIndentation(10)
|
||||
self.uiTraceNGInfoTreeWidget.setAllColumnsShowFocus(True)
|
||||
self.uiTraceNGInfoTreeWidget.setObjectName("uiTraceNGInfoTreeWidget")
|
||||
self.uiTraceNGInfoTreeWidget.header().setVisible(False)
|
||||
self.verticalLayout.addWidget(self.uiTraceNGInfoTreeWidget)
|
||||
self.horizontalLayout_5 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_5.setObjectName("horizontalLayout_5")
|
||||
self.uiNewTraceNGPushButton = QtWidgets.QPushButton(self.layoutWidget)
|
||||
self.uiNewTraceNGPushButton.setObjectName("uiNewTraceNGPushButton")
|
||||
self.horizontalLayout_5.addWidget(self.uiNewTraceNGPushButton)
|
||||
self.uiEditTraceNGPushButton = QtWidgets.QPushButton(self.layoutWidget)
|
||||
self.uiEditTraceNGPushButton.setEnabled(False)
|
||||
self.uiEditTraceNGPushButton.setObjectName("uiEditTraceNGPushButton")
|
||||
self.horizontalLayout_5.addWidget(self.uiEditTraceNGPushButton)
|
||||
self.uiDeleteTraceNGPushButton = QtWidgets.QPushButton(self.layoutWidget)
|
||||
self.uiDeleteTraceNGPushButton.setEnabled(False)
|
||||
self.uiDeleteTraceNGPushButton.setObjectName("uiDeleteTraceNGPushButton")
|
||||
self.horizontalLayout_5.addWidget(self.uiDeleteTraceNGPushButton)
|
||||
self.verticalLayout.addLayout(self.horizontalLayout_5)
|
||||
self.verticalLayout_2.addWidget(self.splitter)
|
||||
|
||||
self.retranslateUi(TraceNGNodePageWidget)
|
||||
QtCore.QMetaObject.connectSlotsByName(TraceNGNodePageWidget)
|
||||
TraceNGNodePageWidget.setTabOrder(self.uiNewTraceNGPushButton, self.uiDeleteTraceNGPushButton)
|
||||
|
||||
def retranslateUi(self, TraceNGNodePageWidget):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
TraceNGNodePageWidget.setWindowTitle(_translate("TraceNGNodePageWidget", "TraceNG nodes"))
|
||||
TraceNGNodePageWidget.setAccessibleName(_translate("TraceNGNodePageWidget", "TraceNG node templates"))
|
||||
self.uiTraceNGInfoTreeWidget.headerItem().setText(0, _translate("TraceNGNodePageWidget", "1"))
|
||||
self.uiTraceNGInfoTreeWidget.headerItem().setText(1, _translate("TraceNGNodePageWidget", "2"))
|
||||
self.uiNewTraceNGPushButton.setText(_translate("TraceNGNodePageWidget", "&New"))
|
||||
self.uiEditTraceNGPushButton.setText(_translate("TraceNGNodePageWidget", "&Edit"))
|
||||
self.uiDeleteTraceNGPushButton.setText(_translate("TraceNGNodePageWidget", "&Delete"))
|
||||
|
||||
140
gns3/modules/traceng/ui/traceng_node_wizard.ui
Normal file
140
gns3/modules/traceng/ui/traceng_node_wizard.ui
Normal file
@@ -0,0 +1,140 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TraceNGNodeWizard</class>
|
||||
<widget class="QWizard" name="TraceNGNodeWizard">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>706</width>
|
||||
<height>452</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>New TraceNG node template</string>
|
||||
</property>
|
||||
<property name="modal">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWizardPage" name="uiServerWizardPage">
|
||||
<property name="title">
|
||||
<string>Server</string>
|
||||
</property>
|
||||
<property name="subTitle">
|
||||
<string>Please choose a server type to run your new TraceNG node.</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="uiServerTypeGroupBox">
|
||||
<property name="title">
|
||||
<string>Server type</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="uiRemoteRadioButton">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Run the TraceNG node on a remote computer</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="uiVMRadioButton">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Run the TraceNG node on the GNS3 VM</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="uiLocalRadioButton">
|
||||
<property name="text">
|
||||
<string>Run the TraceNG node on your local computer</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QGroupBox" name="uiRemoteServersGroupBox">
|
||||
<property name="title">
|
||||
<string>Remote server</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_7">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="uiRemoteServersLabel">
|
||||
<property name="text">
|
||||
<string>Run on:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="uiRemoteServersComboBox">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWizardPage" name="uiNameWizardPage">
|
||||
<property name="title">
|
||||
<string>Name and IP address</string>
|
||||
</property>
|
||||
<property name="subTitle">
|
||||
<string>Please choose a descriptive name and IP address for the new TraceNG node.</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="uiNameLabel">
|
||||
<property name="text">
|
||||
<string>Name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="uiNameLineEdit"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="uiIPAddressLabel">
|
||||
<property name="text">
|
||||
<string>IP address:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="uiIPAddressLineEdit">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>uiNameLineEdit</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
93
gns3/modules/traceng/ui/traceng_node_wizard_ui.py
Normal file
93
gns3/modules/traceng/ui/traceng_node_wizard_ui.py
Normal file
@@ -0,0 +1,93 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file '/home/grossmj/PycharmProjects/gns3-gui/gns3/modules/traceng/ui/traceng_node_wizard.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.5.1
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
class Ui_TraceNGNodeWizard(object):
|
||||
def setupUi(self, TraceNGNodeWizard):
|
||||
TraceNGNodeWizard.setObjectName("TraceNGNodeWizard")
|
||||
TraceNGNodeWizard.resize(706, 452)
|
||||
TraceNGNodeWizard.setModal(True)
|
||||
self.uiServerWizardPage = QtWidgets.QWizardPage()
|
||||
self.uiServerWizardPage.setObjectName("uiServerWizardPage")
|
||||
self.gridLayout_2 = QtWidgets.QGridLayout(self.uiServerWizardPage)
|
||||
self.gridLayout_2.setObjectName("gridLayout_2")
|
||||
self.uiServerTypeGroupBox = QtWidgets.QGroupBox(self.uiServerWizardPage)
|
||||
self.uiServerTypeGroupBox.setObjectName("uiServerTypeGroupBox")
|
||||
self.verticalLayout = QtWidgets.QVBoxLayout(self.uiServerTypeGroupBox)
|
||||
self.verticalLayout.setObjectName("verticalLayout")
|
||||
self.uiRemoteRadioButton = QtWidgets.QRadioButton(self.uiServerTypeGroupBox)
|
||||
self.uiRemoteRadioButton.setEnabled(False)
|
||||
self.uiRemoteRadioButton.setChecked(False)
|
||||
self.uiRemoteRadioButton.setObjectName("uiRemoteRadioButton")
|
||||
self.verticalLayout.addWidget(self.uiRemoteRadioButton)
|
||||
self.uiVMRadioButton = QtWidgets.QRadioButton(self.uiServerTypeGroupBox)
|
||||
self.uiVMRadioButton.setEnabled(False)
|
||||
self.uiVMRadioButton.setObjectName("uiVMRadioButton")
|
||||
self.verticalLayout.addWidget(self.uiVMRadioButton)
|
||||
self.uiLocalRadioButton = QtWidgets.QRadioButton(self.uiServerTypeGroupBox)
|
||||
self.uiLocalRadioButton.setChecked(True)
|
||||
self.uiLocalRadioButton.setObjectName("uiLocalRadioButton")
|
||||
self.verticalLayout.addWidget(self.uiLocalRadioButton)
|
||||
self.gridLayout_2.addWidget(self.uiServerTypeGroupBox, 0, 0, 1, 1)
|
||||
self.uiRemoteServersGroupBox = QtWidgets.QGroupBox(self.uiServerWizardPage)
|
||||
self.uiRemoteServersGroupBox.setObjectName("uiRemoteServersGroupBox")
|
||||
self.gridLayout_7 = QtWidgets.QGridLayout(self.uiRemoteServersGroupBox)
|
||||
self.gridLayout_7.setObjectName("gridLayout_7")
|
||||
self.uiRemoteServersLabel = QtWidgets.QLabel(self.uiRemoteServersGroupBox)
|
||||
self.uiRemoteServersLabel.setObjectName("uiRemoteServersLabel")
|
||||
self.gridLayout_7.addWidget(self.uiRemoteServersLabel, 0, 0, 1, 1)
|
||||
self.uiRemoteServersComboBox = QtWidgets.QComboBox(self.uiRemoteServersGroupBox)
|
||||
self.uiRemoteServersComboBox.setEnabled(False)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.uiRemoteServersComboBox.sizePolicy().hasHeightForWidth())
|
||||
self.uiRemoteServersComboBox.setSizePolicy(sizePolicy)
|
||||
self.uiRemoteServersComboBox.setObjectName("uiRemoteServersComboBox")
|
||||
self.gridLayout_7.addWidget(self.uiRemoteServersComboBox, 0, 1, 1, 1)
|
||||
self.gridLayout_2.addWidget(self.uiRemoteServersGroupBox, 1, 0, 1, 1)
|
||||
TraceNGNodeWizard.addPage(self.uiServerWizardPage)
|
||||
self.uiNameWizardPage = QtWidgets.QWizardPage()
|
||||
self.uiNameWizardPage.setObjectName("uiNameWizardPage")
|
||||
self.gridLayout = QtWidgets.QGridLayout(self.uiNameWizardPage)
|
||||
self.gridLayout.setObjectName("gridLayout")
|
||||
self.uiNameLabel = QtWidgets.QLabel(self.uiNameWizardPage)
|
||||
self.uiNameLabel.setObjectName("uiNameLabel")
|
||||
self.gridLayout.addWidget(self.uiNameLabel, 0, 0, 1, 1)
|
||||
self.uiNameLineEdit = QtWidgets.QLineEdit(self.uiNameWizardPage)
|
||||
self.uiNameLineEdit.setObjectName("uiNameLineEdit")
|
||||
self.gridLayout.addWidget(self.uiNameLineEdit, 0, 1, 1, 1)
|
||||
self.uiIPAddressLabel = QtWidgets.QLabel(self.uiNameWizardPage)
|
||||
self.uiIPAddressLabel.setObjectName("uiIPAddressLabel")
|
||||
self.gridLayout.addWidget(self.uiIPAddressLabel, 1, 0, 1, 1)
|
||||
self.uiIPAddressLineEdit = QtWidgets.QLineEdit(self.uiNameWizardPage)
|
||||
self.uiIPAddressLineEdit.setText("")
|
||||
self.uiIPAddressLineEdit.setObjectName("uiIPAddressLineEdit")
|
||||
self.gridLayout.addWidget(self.uiIPAddressLineEdit, 1, 1, 1, 1)
|
||||
TraceNGNodeWizard.addPage(self.uiNameWizardPage)
|
||||
|
||||
self.retranslateUi(TraceNGNodeWizard)
|
||||
QtCore.QMetaObject.connectSlotsByName(TraceNGNodeWizard)
|
||||
|
||||
def retranslateUi(self, TraceNGNodeWizard):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
TraceNGNodeWizard.setWindowTitle(_translate("TraceNGNodeWizard", "New TraceNG node template"))
|
||||
self.uiServerWizardPage.setTitle(_translate("TraceNGNodeWizard", "Server"))
|
||||
self.uiServerWizardPage.setSubTitle(_translate("TraceNGNodeWizard", "Please choose a server type to run your new TraceNG node."))
|
||||
self.uiServerTypeGroupBox.setTitle(_translate("TraceNGNodeWizard", "Server type"))
|
||||
self.uiRemoteRadioButton.setText(_translate("TraceNGNodeWizard", "Run the TraceNG node on a remote computer"))
|
||||
self.uiVMRadioButton.setText(_translate("TraceNGNodeWizard", "Run the TraceNG node on the GNS3 VM"))
|
||||
self.uiLocalRadioButton.setText(_translate("TraceNGNodeWizard", "Run the TraceNG node on your local computer"))
|
||||
self.uiRemoteServersGroupBox.setTitle(_translate("TraceNGNodeWizard", "Remote server"))
|
||||
self.uiRemoteServersLabel.setText(_translate("TraceNGNodeWizard", "Run on:"))
|
||||
self.uiNameWizardPage.setTitle(_translate("TraceNGNodeWizard", "Name and IP address"))
|
||||
self.uiNameWizardPage.setSubTitle(_translate("TraceNGNodeWizard", "Please choose a descriptive name and IP address for the new TraceNG node."))
|
||||
self.uiNameLabel.setText(_translate("TraceNGNodeWizard", "Name:"))
|
||||
self.uiIPAddressLabel.setText(_translate("TraceNGNodeWizard", "IP address:"))
|
||||
|
||||
126
gns3/modules/traceng/ui/traceng_preferences_page.ui
Executable file
126
gns3/modules/traceng/ui/traceng_preferences_page.ui
Executable file
@@ -0,0 +1,126 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TraceNGPreferencesPageWidget</class>
|
||||
<widget class="QWidget" name="TraceNGPreferencesPageWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>623</width>
|
||||
<height>280</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>TraceNG</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QTabWidget" name="uiTabWidget">
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::CustomContextMenu</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="uiGeneralSettingsTabWidget">
|
||||
<attribute name="title">
|
||||
<string>Local settings</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="margin">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="uiTraceNGPathLabel">
|
||||
<property name="text">
|
||||
<string>Path to TraceNG executable:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="uiTraceNGPathLineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="uiTraceNGPathToolButton">
|
||||
<property name="text">
|
||||
<string>&Browse...</string>
|
||||
</property>
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonTextOnly</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="spacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>5</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>138</width>
|
||||
<height>17</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="uiRestoreDefaultsPushButton">
|
||||
<property name="text">
|
||||
<string>Restore defaults</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
<designerdata>
|
||||
<property name="gridDeltaX">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="gridDeltaY">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="gridSnapX">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="gridSnapY">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="gridVisible">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</designerdata>
|
||||
</ui>
|
||||
67
gns3/modules/traceng/ui/traceng_preferences_page_ui.py
Normal file
67
gns3/modules/traceng/ui/traceng_preferences_page_ui.py
Normal file
@@ -0,0 +1,67 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file '/home/grossmj/PycharmProjects/gns3-gui/gns3/modules/traceng/ui/traceng_preferences_page.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.5.1
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
class Ui_TraceNGPreferencesPageWidget(object):
|
||||
def setupUi(self, TraceNGPreferencesPageWidget):
|
||||
TraceNGPreferencesPageWidget.setObjectName("TraceNGPreferencesPageWidget")
|
||||
TraceNGPreferencesPageWidget.resize(623, 280)
|
||||
self.verticalLayout_2 = QtWidgets.QVBoxLayout(TraceNGPreferencesPageWidget)
|
||||
self.verticalLayout_2.setObjectName("verticalLayout_2")
|
||||
self.uiTabWidget = QtWidgets.QTabWidget(TraceNGPreferencesPageWidget)
|
||||
self.uiTabWidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
|
||||
self.uiTabWidget.setObjectName("uiTabWidget")
|
||||
self.uiGeneralSettingsTabWidget = QtWidgets.QWidget()
|
||||
self.uiGeneralSettingsTabWidget.setObjectName("uiGeneralSettingsTabWidget")
|
||||
self.verticalLayout = QtWidgets.QVBoxLayout(self.uiGeneralSettingsTabWidget)
|
||||
self.verticalLayout.setContentsMargins(10, 10, 10, 10)
|
||||
self.verticalLayout.setObjectName("verticalLayout")
|
||||
self.uiTraceNGPathLabel = QtWidgets.QLabel(self.uiGeneralSettingsTabWidget)
|
||||
self.uiTraceNGPathLabel.setObjectName("uiTraceNGPathLabel")
|
||||
self.verticalLayout.addWidget(self.uiTraceNGPathLabel)
|
||||
self.horizontalLayout_5 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_5.setObjectName("horizontalLayout_5")
|
||||
self.uiTraceNGPathLineEdit = QtWidgets.QLineEdit(self.uiGeneralSettingsTabWidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.uiTraceNGPathLineEdit.sizePolicy().hasHeightForWidth())
|
||||
self.uiTraceNGPathLineEdit.setSizePolicy(sizePolicy)
|
||||
self.uiTraceNGPathLineEdit.setObjectName("uiTraceNGPathLineEdit")
|
||||
self.horizontalLayout_5.addWidget(self.uiTraceNGPathLineEdit)
|
||||
self.uiTraceNGPathToolButton = QtWidgets.QToolButton(self.uiGeneralSettingsTabWidget)
|
||||
self.uiTraceNGPathToolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextOnly)
|
||||
self.uiTraceNGPathToolButton.setObjectName("uiTraceNGPathToolButton")
|
||||
self.horizontalLayout_5.addWidget(self.uiTraceNGPathToolButton)
|
||||
self.verticalLayout.addLayout(self.horizontalLayout_5)
|
||||
spacerItem = QtWidgets.QSpacerItem(20, 5, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
||||
self.verticalLayout.addItem(spacerItem)
|
||||
self.uiTabWidget.addTab(self.uiGeneralSettingsTabWidget, "")
|
||||
self.verticalLayout_2.addWidget(self.uiTabWidget)
|
||||
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
|
||||
spacerItem1 = QtWidgets.QSpacerItem(138, 17, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
self.horizontalLayout_2.addItem(spacerItem1)
|
||||
self.uiRestoreDefaultsPushButton = QtWidgets.QPushButton(TraceNGPreferencesPageWidget)
|
||||
self.uiRestoreDefaultsPushButton.setObjectName("uiRestoreDefaultsPushButton")
|
||||
self.horizontalLayout_2.addWidget(self.uiRestoreDefaultsPushButton)
|
||||
self.verticalLayout_2.addLayout(self.horizontalLayout_2)
|
||||
|
||||
self.retranslateUi(TraceNGPreferencesPageWidget)
|
||||
self.uiTabWidget.setCurrentIndex(0)
|
||||
QtCore.QMetaObject.connectSlotsByName(TraceNGPreferencesPageWidget)
|
||||
|
||||
def retranslateUi(self, TraceNGPreferencesPageWidget):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
TraceNGPreferencesPageWidget.setWindowTitle(_translate("TraceNGPreferencesPageWidget", "TraceNG"))
|
||||
self.uiTraceNGPathLabel.setText(_translate("TraceNGPreferencesPageWidget", "Path to TraceNG executable:"))
|
||||
self.uiTraceNGPathToolButton.setText(_translate("TraceNGPreferencesPageWidget", "&Browse..."))
|
||||
self.uiTabWidget.setTabText(self.uiTabWidget.indexOf(self.uiGeneralSettingsTabWidget), _translate("TraceNGPreferencesPageWidget", "Local settings"))
|
||||
self.uiRestoreDefaultsPushButton.setText(_translate("TraceNGPreferencesPageWidget", "Restore defaults"))
|
||||
|
||||
@@ -77,10 +77,10 @@ class VPCS(Module):
|
||||
# save the settings
|
||||
LocalConfig.instance().saveSectionSettings(self.__class__.__name__, self._settings)
|
||||
|
||||
server_settings = copy.copy(self._settings)
|
||||
if server_settings["vpcs_path"]:
|
||||
server_settings = {}
|
||||
if self._settings["vpcs_path"]:
|
||||
# save some settings to the server config file
|
||||
server_settings["vpcs_path"] = os.path.normpath(server_settings["vpcs_path"])
|
||||
server_settings["vpcs_path"] = os.path.normpath(self._settings["vpcs_path"])
|
||||
config = LocalServerConfig.instance()
|
||||
config.saveSettings(self.__class__.__name__, server_settings)
|
||||
|
||||
|
||||
BIN
resources/icons/traceng.png
Normal file
BIN
resources/icons/traceng.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.7 KiB |
@@ -64,6 +64,7 @@
|
||||
<file>icons/virtualbox.png</file>
|
||||
<file>icons/qemu.svg</file>
|
||||
<file>icons/rtv.png</file>
|
||||
<file>icons/traceng.png</file>
|
||||
<file>icons/image.svg</file>
|
||||
<file>icons/node_conception.svg</file>
|
||||
<file>icons/raise_z_value.svg</file>
|
||||
|
||||
Reference in New Issue
Block a user