Redesign appliance handling part 1. Ref #2490

- Removed appliance templates from device dock
 - Use new controller notification stream
 - Fixed device update and remove from device dock
This commit is contained in:
grossmj
2018-08-16 21:47:52 +07:00
parent bb013804d4
commit 3d8bd16536
10 changed files with 136 additions and 233 deletions

View File

@@ -29,6 +29,7 @@ class ApplianceManager(QtCore.QObject):
"""
appliances_changed_signal = QtCore.Signal()
appliance_templates_changed_signal = QtCore.Signal()
def __init__(self):
@@ -38,7 +39,7 @@ class ApplianceManager(QtCore.QObject):
self._controller = Controller.instance()
self._controller.connected_signal.connect(self.refresh)
self._controller.disconnected_signal.connect(self._controllerDisconnectedSlot)
self.refresh()
#self.refresh()
def refresh(self):
"""
@@ -109,7 +110,7 @@ class ApplianceManager(QtCore.QObject):
log.error("Error while getting appliance templates list: {}".format(result["message"]))
return
self._appliance_templates = result
self.appliances_changed_signal.emit()
self.appliance_templates_changed_signal.emit()
def createNodeFromApplianceId(self, project, appliance_id, x, y):
"""

View File

@@ -18,11 +18,13 @@
import os
import hashlib
import tempfile
import json
from .qt import QtCore, QtGui, QtWidgets, qpartial, qslot
from .qt import QtCore, QtNetwork, QtGui, QtWidgets, qpartial, qslot
from .symbol import Symbol
from .local_server_config import LocalServerConfig
from .settings import LOCAL_SERVER_SETTINGS
from gns3.utils import parse_version
import logging
log = logging.getLogger(__name__)
@@ -128,6 +130,7 @@ class Controller(QtCore.QObject):
self._connected = False
self.disconnected_signal.emit()
self._connectingToServer()
self.stopListenNotifications()
def _versionGetSlot(self, result, error=False, **kwargs):
"""
@@ -161,6 +164,7 @@ class Controller(QtCore.QObject):
self._connecting = False
self.connected_signal.emit()
self.refreshProjectList()
self._startListenNotifications()
def post(self, *args, **kwargs):
return self.createHTTPQuery("POST", *args, **kwargs)
@@ -362,3 +366,77 @@ class Controller(QtCore.QObject):
def projects(self):
return self._projects
def _startListenNotifications(self):
if not self.connected():
return
# Due to bug in Qt on some version we need a dedicated network manager
self._notification_network_manager = QtNetwork.QNetworkAccessManager()
self._notification_stream = None
# Qt websocket before Qt 5.6 doesn't support auth
if parse_version(QtCore.QT_VERSION_STR) < parse_version("5.6.0") or parse_version(QtCore.PYQT_VERSION_STR) < parse_version("5.6.0"):
self._notification_stream = Controller.instance().createHTTPQuery("GET", "/notifications", self._endListenNotificationCallback,
downloadProgressCallback=self._event_received,
networkManager=self._notification_network_manager,
timeout=None,
showProgress=False,
ignoreErrors=True)
else:
self._notification_stream = Controller.instance().connectWebSocket("/notifications/ws")
self._notification_stream.textMessageReceived.connect(self._websocket_event_received)
self._notification_stream.error.connect(self._websocket_error)
def stopListenNotifications(self):
if self._notification_stream:
log.debug("Stop listening for notifications from controller")
stream = self._notification_stream
self._notification_stream = None
self._notification_network_manager = None
stream.abort()
def _endListenNotificationCallback(self, result, error=False, **kwargs):
"""
If notification stream disconnect we reconnect to it
"""
if self._notification_stream:
self._notification_stream = None
self._startListenNotifications()
@qslot
def _websocket_error(self, error):
if self._notification_stream:
log.error(self._notification_stream.errorString())
self._notification_stream = None
self._startListenNotifications()
@qslot
def _websocket_event_received(self, event):
try:
self._event_received(json.loads(event))
except ValueError as e:
log.error("Invalid event received: {}".format(e))
def _event_received(self, result, *args, **kwargs):
# Log only relevant events
if result["action"] not in ("ping", "compute.updated"):
log.debug("Event received from controller stream: {}".format(result))
if result["action"] == "settings.updated":
from gns3.local_config import LocalConfig
from gns3.appliance_manager import ApplianceManager
LocalConfig.instance().refreshConfigFromController()
ApplianceManager.instance().refresh()
elif result["action"] == "compute.created" or result["action"] == "compute.updated":
from .compute_manager import ComputeManager
ComputeManager.instance().computeDataReceivedCallback(result["event"])
elif result["action"] == "log.error":
log.error(result["event"]["message"])
elif result["action"] == "log.warning":
log.warning(result["event"]["message"])
elif result["action"] == "log.info":
log.info(result["event"]["message"], extra={"show": True})
elif result["action"] == "ping":
pass

View File

@@ -44,7 +44,7 @@ class LocalConfig(QtCore.QObject):
def __init__(self, config_file=None):
"""
:param config_file: Path to the config file (override all other config, usefull for tests)
:param config_file: Path to the config file (override all other config, useful for tests)
"""
super().__init__()

View File

@@ -109,7 +109,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
self.recent_project_actions = []
self._start_time = time.time()
local_config = LocalConfig.instance()
local_config.config_changed_signal.connect(self._localConfigChangedSlot)
#local_config.config_changed_signal.connect(self._localConfigChangedSlot)
self._local_config_timer = QtCore.QTimer(self)
self._local_config_timer.timeout.connect(local_config.checkConfigChanged)
self._local_config_timer.start(1000) # milliseconds
@@ -426,7 +426,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
directory = self._appliance_dir
if not os.path.exists(self._appliance_dir):
directory = Topology.instance().projectsDirPath()
path, _ = QtWidgets.QFileDialog.getOpenFileName(self, "Open appliance", directory,
path, _ = QtWidgets.QFileDialog.getOpenFileName(self, "Import appliance", directory,
"All files (*.*);;GNS3 Appliance (*.gns3appliance *.gns3a)",
"GNS3 Appliance (*.gns3appliance *.gns3a)")
if path:
@@ -543,8 +543,9 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
# It covers case when project is not set
# and we need to refresh appliance manager
project = Topology.instance().project()
if project is None:
self._appliance_manager.instance().refresh()
#if project is None:
# self._appliance_manager.instance().refresh()
def _refreshVisibleWidgets(self):
"""

View File

@@ -30,33 +30,8 @@ class NodesDockWidget(QtWidgets.QDockWidget):
self.parent().uiNodesView.setCurrentSearch(text)
self.parent().uiNodesView.refresh()
def _filterIndexChangedSlot(self, index):
self._settings["nodes_view_filter"] = index
LocalConfig.instance().saveSectionSettings("NodesView", self._settings)
if index == 0:
self.parent().uiNodesView.setShowInstalledAppliances(True)
self.parent().uiNodesView.setShowBuiltinAvailableAppliances(True)
self.parent().uiNodesView.setShowMyAvailableAppliances(True)
elif index == 1:
self.parent().uiNodesView.setShowInstalledAppliances(True)
self.parent().uiNodesView.setShowBuiltinAvailableAppliances(False)
self.parent().uiNodesView.setShowMyAvailableAppliances(False)
elif index == 2:
self.parent().uiNodesView.setShowInstalledAppliances(False)
self.parent().uiNodesView.setShowBuiltinAvailableAppliances(True)
self.parent().uiNodesView.setShowMyAvailableAppliances(True)
else:
self.parent().uiNodesView.setShowInstalledAppliances(False)
self.parent().uiNodesView.setShowBuiltinAvailableAppliances(False)
self.parent().uiNodesView.setShowMyAvailableAppliances(True)
self.parent().uiNodesView.refresh()
def populateNodesView(self, category):
if self.parent().uiNodesFilterComboBox.currentIndex() != self._settings["nodes_view_filter"]:
self.parent().uiNodesFilterComboBox.setCurrentIndex(self._settings["nodes_view_filter"])
self._filterIndexChangedSlot(self._settings["nodes_view_filter"])
self.parent().uiNodesFilterComboBox.activated.connect(self._filterIndexChangedSlot)
self.parent().uiNodesFilterLineEdit.textChanged.connect(self._filterTextChangedSlot)
self.parent().uiNodesView.clear()
text = self.parent().uiNodesFilterLineEdit.text().strip().lower()

View File

@@ -29,7 +29,9 @@ from .modules import MODULES
from .controller import Controller
from .appliance_manager import ApplianceManager
from .dialogs.configuration_dialog import ConfigurationDialog
from .local_config import LocalConfig
import logging
log = logging.getLogger(__name__)
CATEGORY_TO_ID = {
@@ -52,30 +54,19 @@ class NodesView(QtWidgets.QTreeWidget):
def __init__(self, parent=None):
super().__init__(parent)
self._current_category = None
self._current_search = ""
self._show_installed_appliances = True
self._show_builtin_available_appliances = True
self._show_my_available_appliances = True
# enables the possibility to drag items.
self.setDragEnabled(True)
ApplianceManager.instance().appliances_changed_signal.connect(self.refresh)
def setCurrentSearch(self, search):
self._current_search = search
def setShowInstalledAppliances(self, value):
self._show_installed_appliances = value
def setShowBuiltinAvailableAppliances(self, value):
self._show_builtin_available_appliances = value
def setShowMyAvailableAppliances(self, value):
self._show_my_available_appliances = value
def refresh(self):
self.clear()
self.populateNodesView(self._current_category, self._current_search)
@@ -89,48 +80,28 @@ class NodesView(QtWidgets.QTreeWidget):
"""
if not Controller.instance().connected():
log.debug("Could not retrieve templates because there is no connection to the controller")
return
self.setIconSize(QtCore.QSize(32, 32))
self._current_category = category
self._current_search = search
display_appliances = set()
if self._show_installed_appliances:
for appliance in ApplianceManager.instance().appliances():
if category is not None and category != CATEGORY_TO_ID[appliance["category"]]:
continue
if search != "" and search.lower() not in appliance["name"].lower():
continue
display_appliances.add(appliance["name"])
item = QtWidgets.QTreeWidgetItem(self)
item.setText(0, appliance["name"])
item.setData(0, QtCore.Qt.UserRole, appliance["appliance_id"])
item.setData(1, QtCore.Qt.UserRole, "appliance")
item.setSizeHint(0, QtCore.QSize(32, 32))
Controller.instance().getSymbolIcon(appliance.get("symbol"), qpartial(self._setItemIcon, item), fallback=":/symbols/" + appliance["category"] + ".svg")
for appliance in ApplianceManager.instance().applianceTemplates():
if not appliance["builtin"] and not self._show_my_available_appliances:
continue
if appliance["builtin"] and not self._show_builtin_available_appliances:
continue
for appliance in ApplianceManager.instance().appliances():
if category is not None and category != CATEGORY_TO_ID[appliance["category"]]:
continue
if search != "" and search.lower() not in appliance["name"].lower():
continue
if appliance["name"] in display_appliances:
continue
display_appliances.add(appliance["name"])
item = QtWidgets.QTreeWidgetItem(self)
item.setForeground(0, QtGui.QBrush(QtGui.QColor("gray")))
item.setText(0, appliance["name"])
item.setData(0, QtCore.Qt.UserRole, appliance)
item.setData(1, QtCore.Qt.UserRole, "appliance_template")
item.setData(0, QtCore.Qt.UserRole, appliance["appliance_id"])
item.setData(1, QtCore.Qt.UserRole, "appliance")
item.setSizeHint(0, QtCore.QSize(32, 32))
Controller.instance().getSymbolIcon(appliance.get("symbol"), qpartial(self._setItemIcon, item), fallback=":/symbols/" + appliance["category"] + ".svg")
self.sortByColumn(0, QtCore.Qt.AscendingOrder)
def _setItemIcon(self, item, icon):
@@ -211,8 +182,7 @@ class NodesView(QtWidgets.QTreeWidget):
if node_class:
break
# We can not edit stuff like EthernetSwitch
# or without config template like VPCS
# We can not edit devices like EthernetSwitch or device without config templates
if not node["builtin"] and hasattr(module, "configurationPage"):
vm = None
for vm_key, vm in module.instance().nodeTemplates().items():
@@ -230,7 +200,6 @@ class NodesView(QtWidgets.QTreeWidget):
configuration.setIcon(QtGui.QIcon(":/icons/delete.svg"))
configuration.triggered.connect(qpartial(self._deleteSlot, vm_key, vm, module))
menu.addAction(configuration)
menu.exec_(QtGui.QCursor.pos())
def _configurationSlot(self, vm, module, source):
@@ -238,15 +207,8 @@ class NodesView(QtWidgets.QTreeWidget):
dialog = ConfigurationDialog(vm["name"], vm, module.configurationPage()(), parent=self)
dialog.show()
if dialog.exec_():
# update appliance list, refresh is triggered by appliances_changed_signal
module.instance().setNodeTemplates(module.instance().nodeTemplates())
LocalConfig.instance().writeConfig()
#self.refresh()
# FIXME: temporary fix: close the nodes dock to refresh the node list
from .main_window import MainWindow
main_window = MainWindow.instance()
main_window.uiNodesDockWidget.setVisible(False)
main_window.uiNodesDockWidget.setWindowTitle("")
def _deleteSlot(self, vm_key, vm, module, source):
@@ -255,12 +217,5 @@ class NodesView(QtWidgets.QTreeWidget):
if reply == QtWidgets.QMessageBox.Yes:
vms = module.instance().nodeTemplates()
vms.pop(vm_key)
# update appliance list, refresh is triggered by appliances_changed_signal
module.instance().setNodeTemplates(vms)
LocalConfig.instance().writeConfig()
#self.refresh()
# FIXME: temporary fix: close the nodes dock to refresh the node list
from .main_window import MainWindow
main_window = MainWindow.instance()
main_window.uiNodesDockWidget.setVisible(False)
main_window.uiNodesDockWidget.setWindowTitle("")

View File

@@ -636,8 +636,8 @@ class Project(QtCore.QObject):
def _event_received(self, result, *args, **kwargs):
# Log only relevant events
if result["action"] not in ("ping", "compute.updated"):
log.debug("Event received: %s", result)
if result["action"] not in ("ping"):
log.debug("Event received from project stream: {}".format(result))
if result["action"] == "node.created":
node = Topology.instance().getNodeFromUuid(result["event"]["node_id"])
if node is None:
@@ -686,11 +686,5 @@ class Project(QtCore.QObject):
log.warning(result["event"]["message"])
elif result["action"] == "log.info":
log.info(result["event"]["message"], extra={"show": True})
elif result["action"] == "compute.created" or result["action"] == "compute.updated":
cm = ComputeManager.instance()
cm.computeDataReceivedCallback(result["event"])
elif result["action"] == "settings.updated":
LocalConfig.instance().refreshConfigFromController()
ApplianceManager.instance().refresh()
elif result["action"] == "ping":
pass

View File

@@ -38,16 +38,7 @@ background-none;
</property>
<widget class="QWidget" name="uiCentralWidget">
<layout class="QGridLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<property name="margin">
<number>0</number>
</property>
<property name="spacing">
@@ -71,7 +62,7 @@ background-none;
<x>0</x>
<y>0</y>
<width>986</width>
<height>27</height>
<height>40</height>
</rect>
</property>
<widget class="QMenu" name="uiEditMenu">
@@ -237,64 +228,15 @@ background-none;
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<property name="margin">
<number>0</number>
</property>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>3</number>
<widget class="QLineEdit" name="uiNodesFilterLineEdit">
<property name="placeholderText">
<string>Filter</string>
</property>
<property name="leftMargin">
<number>5</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<widget class="QComboBox" name="uiNodesFilterComboBox">
<item>
<property name="text">
<string>Installed &amp; Available appliances</string>
</property>
</item>
<item>
<property name="text">
<string>Installed appliances</string>
</property>
</item>
<item>
<property name="text">
<string>Available appliances</string>
</property>
</item>
<item>
<property name="text">
<string>Custom appliances</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QLineEdit" name="uiNodesFilterLineEdit">
<property name="placeholderText">
<string>Filter</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="NodesView" name="uiNodesView">
@@ -430,16 +372,7 @@ background-none;
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<property name="margin">
<number>0</number>
</property>
<item>
@@ -505,16 +438,7 @@ background-none;
</sizepolicy>
</property>
<layout class="QGridLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<property name="margin">
<number>0</number>
</property>
<property name="spacing">
@@ -558,16 +482,7 @@ background-none;
</attribute>
<widget class="QWidget" name="dockWidgetContents">
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<property name="margin">
<number>0</number>
</property>
<property name="spacing">

View File

@@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file '/home/dominik/projects/gns3-gui-2.2/gns3/ui/main_window.ui'
# Form implementation generated from reading ui file '/home/grossmj/PycharmProjects/gns3-gui/gns3/ui/main_window.ui'
#
# Created by: PyQt5 UI code generator 5.10
# Created by: PyQt5 UI code generator 5.5.1
#
# WARNING! All changes made in this file will be lost!
@@ -46,7 +46,7 @@ class Ui_MainWindow(object):
self.gridlayout.addWidget(self.uiGraphicsView, 0, 0, 1, 1)
MainWindow.setCentralWidget(self.uiCentralWidget)
self.uiMenuBar = QtWidgets.QMenuBar(MainWindow)
self.uiMenuBar.setGeometry(QtCore.QRect(0, 0, 986, 27))
self.uiMenuBar.setGeometry(QtCore.QRect(0, 0, 986, 40))
self.uiMenuBar.setObjectName("uiMenuBar")
self.uiEditMenu = QtWidgets.QMenu(self.uiMenuBar)
self.uiEditMenu.setObjectName("uiEditMenu")
@@ -89,21 +89,9 @@ class Ui_MainWindow(object):
self.vboxlayout.setContentsMargins(0, 0, 0, 0)
self.vboxlayout.setSpacing(0)
self.vboxlayout.setObjectName("vboxlayout")
self.verticalLayout = QtWidgets.QVBoxLayout()
self.verticalLayout.setContentsMargins(5, -1, 5, 5)
self.verticalLayout.setSpacing(3)
self.verticalLayout.setObjectName("verticalLayout")
self.uiNodesFilterComboBox = QtWidgets.QComboBox(self.uiNodesDockWidgetContents)
self.uiNodesFilterComboBox.setObjectName("uiNodesFilterComboBox")
self.uiNodesFilterComboBox.addItem("")
self.uiNodesFilterComboBox.addItem("")
self.uiNodesFilterComboBox.addItem("")
self.uiNodesFilterComboBox.addItem("")
self.verticalLayout.addWidget(self.uiNodesFilterComboBox)
self.uiNodesFilterLineEdit = QtWidgets.QLineEdit(self.uiNodesDockWidgetContents)
self.uiNodesFilterLineEdit.setObjectName("uiNodesFilterLineEdit")
self.verticalLayout.addWidget(self.uiNodesFilterLineEdit)
self.vboxlayout.addLayout(self.verticalLayout)
self.vboxlayout.addWidget(self.uiNodesFilterLineEdit)
self.uiNodesView = NodesView(self.uiNodesDockWidgetContents)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
@@ -226,22 +214,22 @@ class Ui_MainWindow(object):
self.uiOnlineHelpAction.setObjectName("uiOnlineHelpAction")
self.uiScreenshotAction = QtWidgets.QAction(MainWindow)
icon4 = QtGui.QIcon()
icon4.addPixmap(QtGui.QPixmap(":/icons/camera-photo.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
icon4.addPixmap(QtGui.QPixmap(":/icons/camera-photo-hover.svg"), QtGui.QIcon.Active, QtGui.QIcon.Off)
icon4.addPixmap(QtGui.QPixmap(":/icons/camera-photo.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.uiScreenshotAction.setIcon(icon4)
self.uiScreenshotAction.setObjectName("uiScreenshotAction")
self.uiStartAllAction = QtWidgets.QAction(MainWindow)
self.uiStartAllAction.setEnabled(True)
icon5 = QtGui.QIcon()
icon5.addPixmap(QtGui.QPixmap(":/icons/start.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
icon5.addPixmap(QtGui.QPixmap(":/icons/start-hover.svg"), QtGui.QIcon.Active, QtGui.QIcon.Off)
icon5.addPixmap(QtGui.QPixmap(":/icons/start.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.uiStartAllAction.setIcon(icon5)
self.uiStartAllAction.setObjectName("uiStartAllAction")
self.uiStopAllAction = QtWidgets.QAction(MainWindow)
self.uiStopAllAction.setEnabled(True)
icon6 = QtGui.QIcon()
icon6.addPixmap(QtGui.QPixmap(":/icons/stop.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
icon6.addPixmap(QtGui.QPixmap(":/icons/stop-hover.svg"), QtGui.QIcon.Active, QtGui.QIcon.Off)
icon6.addPixmap(QtGui.QPixmap(":/icons/stop.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.uiStopAllAction.setIcon(icon6)
self.uiStopAllAction.setObjectName("uiStopAllAction")
self.uiConsoleAllAction = QtWidgets.QAction(MainWindow)
@@ -255,14 +243,14 @@ class Ui_MainWindow(object):
self.uiAboutQtAction.setObjectName("uiAboutQtAction")
self.uiZoomInAction = QtWidgets.QAction(MainWindow)
icon8 = QtGui.QIcon()
icon8.addPixmap(QtGui.QPixmap(":/icons/zoom-in.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
icon8.addPixmap(QtGui.QPixmap(":/icons/zoom-in-hover.png"), QtGui.QIcon.Active, QtGui.QIcon.Off)
icon8.addPixmap(QtGui.QPixmap(":/icons/zoom-in.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.uiZoomInAction.setIcon(icon8)
self.uiZoomInAction.setObjectName("uiZoomInAction")
self.uiZoomOutAction = QtWidgets.QAction(MainWindow)
icon9 = QtGui.QIcon()
icon9.addPixmap(QtGui.QPixmap(":/icons/zoom-out.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
icon9.addPixmap(QtGui.QPixmap(":/icons/zoom-out-hover.png"), QtGui.QIcon.Active, QtGui.QIcon.Off)
icon9.addPixmap(QtGui.QPixmap(":/icons/zoom-out.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.uiZoomOutAction.setIcon(icon9)
self.uiZoomOutAction.setObjectName("uiZoomOutAction")
self.uiZoomResetAction = QtWidgets.QAction(MainWindow)
@@ -279,8 +267,8 @@ class Ui_MainWindow(object):
self.uiPreferencesAction.setObjectName("uiPreferencesAction")
self.uiSuspendAllAction = QtWidgets.QAction(MainWindow)
icon11 = QtGui.QIcon()
icon11.addPixmap(QtGui.QPixmap(":/icons/pause.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
icon11.addPixmap(QtGui.QPixmap(":/icons/pause-hover.svg"), QtGui.QIcon.Active, QtGui.QIcon.Off)
icon11.addPixmap(QtGui.QPixmap(":/icons/pause.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.uiSuspendAllAction.setIcon(icon11)
self.uiSuspendAllAction.setObjectName("uiSuspendAllAction")
self.uiAddNoteAction = QtWidgets.QAction(MainWindow)
@@ -308,15 +296,15 @@ class Ui_MainWindow(object):
self.uiDrawRectangleAction = QtWidgets.QAction(MainWindow)
self.uiDrawRectangleAction.setCheckable(True)
icon16 = QtGui.QIcon()
icon16.addPixmap(QtGui.QPixmap(":/icons/rectangle.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
icon16.addPixmap(QtGui.QPixmap(":/icons/rectangle-hover.svg"), QtGui.QIcon.Active, QtGui.QIcon.Off)
icon16.addPixmap(QtGui.QPixmap(":/icons/rectangle.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.uiDrawRectangleAction.setIcon(icon16)
self.uiDrawRectangleAction.setObjectName("uiDrawRectangleAction")
self.uiDrawEllipseAction = QtWidgets.QAction(MainWindow)
self.uiDrawEllipseAction.setCheckable(True)
icon17 = QtGui.QIcon()
icon17.addPixmap(QtGui.QPixmap(":/icons/ellipse.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
icon17.addPixmap(QtGui.QPixmap(":/icons/ellipse-hover.svg"), QtGui.QIcon.Active, QtGui.QIcon.Off)
icon17.addPixmap(QtGui.QPixmap(":/icons/ellipse.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.uiDrawEllipseAction.setIcon(icon17)
self.uiDrawEllipseAction.setObjectName("uiDrawEllipseAction")
self.uiShowPortNamesAction = QtWidgets.QAction(MainWindow)
@@ -358,40 +346,40 @@ class Ui_MainWindow(object):
self.uiCheckForUpdateAction.setObjectName("uiCheckForUpdateAction")
self.uiBrowseRoutersAction = QtWidgets.QAction(MainWindow)
icon23 = QtGui.QIcon()
icon23.addPixmap(QtGui.QPixmap(":/icons/router.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
icon23.addPixmap(QtGui.QPixmap(":/icons/router-hover.png"), QtGui.QIcon.Active, QtGui.QIcon.Off)
icon23.addPixmap(QtGui.QPixmap(":/icons/router.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.uiBrowseRoutersAction.setIcon(icon23)
self.uiBrowseRoutersAction.setObjectName("uiBrowseRoutersAction")
self.uiBrowseSwitchesAction = QtWidgets.QAction(MainWindow)
icon24 = QtGui.QIcon()
icon24.addPixmap(QtGui.QPixmap(":/icons/switch.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
icon24.addPixmap(QtGui.QPixmap(":/icons/switch-hover.png"), QtGui.QIcon.Active, QtGui.QIcon.Off)
icon24.addPixmap(QtGui.QPixmap(":/icons/switch.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.uiBrowseSwitchesAction.setIcon(icon24)
self.uiBrowseSwitchesAction.setObjectName("uiBrowseSwitchesAction")
self.uiBrowseEndDevicesAction = QtWidgets.QAction(MainWindow)
icon25 = QtGui.QIcon()
icon25.addPixmap(QtGui.QPixmap(":/icons/PC.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
icon25.addPixmap(QtGui.QPixmap(":/icons/PC-hover.png"), QtGui.QIcon.Active, QtGui.QIcon.Off)
icon25.addPixmap(QtGui.QPixmap(":/icons/PC.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.uiBrowseEndDevicesAction.setIcon(icon25)
self.uiBrowseEndDevicesAction.setObjectName("uiBrowseEndDevicesAction")
self.uiBrowseSecurityDevicesAction = QtWidgets.QAction(MainWindow)
icon26 = QtGui.QIcon()
icon26.addPixmap(QtGui.QPixmap(":/icons/firewall.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
icon26.addPixmap(QtGui.QPixmap(":/icons/firewall-hover.png"), QtGui.QIcon.Active, QtGui.QIcon.Off)
icon26.addPixmap(QtGui.QPixmap(":/icons/firewall.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.uiBrowseSecurityDevicesAction.setIcon(icon26)
self.uiBrowseSecurityDevicesAction.setObjectName("uiBrowseSecurityDevicesAction")
self.uiBrowseAllDevicesAction = QtWidgets.QAction(MainWindow)
icon27 = QtGui.QIcon()
icon27.addPixmap(QtGui.QPixmap(":/icons/browse-all-icons.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
icon27.addPixmap(QtGui.QPixmap(":/icons/browse-all-icons-hover.png"), QtGui.QIcon.Active, QtGui.QIcon.Off)
icon27.addPixmap(QtGui.QPixmap(":/icons/browse-all-icons.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.uiBrowseAllDevicesAction.setIcon(icon27)
self.uiBrowseAllDevicesAction.setObjectName("uiBrowseAllDevicesAction")
self.uiAddLinkAction = QtWidgets.QAction(MainWindow)
self.uiAddLinkAction.setCheckable(True)
icon28 = QtGui.QIcon()
icon28.addPixmap(QtGui.QPixmap(":/icons/connection-new.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
icon28.addPixmap(QtGui.QPixmap(":/icons/connection-new-hover.svg"), QtGui.QIcon.Active, QtGui.QIcon.Off)
icon28.addPixmap(QtGui.QPixmap(":/icons/cancel-connection.svg"), QtGui.QIcon.Normal, QtGui.QIcon.On)
icon28.addPixmap(QtGui.QPixmap(":/icons/connection-new.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
icon28.addPixmap(QtGui.QPixmap(":/icons/cancel-connection.svg"), QtGui.QIcon.Active, QtGui.QIcon.On)
self.uiAddLinkAction.setIcon(icon28)
self.uiAddLinkAction.setObjectName("uiAddLinkAction")
@@ -449,9 +437,9 @@ class Ui_MainWindow(object):
self.uiLockAllAction.setCheckable(True)
self.uiLockAllAction.setChecked(False)
icon34 = QtGui.QIcon()
icon34.addPixmap(QtGui.QPixmap(":/icons/unlock.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
icon34.addPixmap(QtGui.QPixmap(":/icons/unlock.svg"), QtGui.QIcon.Active, QtGui.QIcon.Off)
icon34.addPixmap(QtGui.QPixmap(":/icons/lock.svg"), QtGui.QIcon.Normal, QtGui.QIcon.On)
icon34.addPixmap(QtGui.QPixmap(":/icons/unlock.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
icon34.addPixmap(QtGui.QPixmap(":/icons/lock.svg"), QtGui.QIcon.Active, QtGui.QIcon.On)
self.uiLockAllAction.setIcon(icon34)
self.uiLockAllAction.setObjectName("uiLockAllAction")
@@ -573,10 +561,6 @@ class Ui_MainWindow(object):
self.uiToolsMenu.setTitle(_translate("MainWindow", "&Tools"))
self.uiGeneralToolBar.setWindowTitle(_translate("MainWindow", "General"))
self.uiNodesDockWidget.setWindowTitle(_translate("MainWindow", "All devices"))
self.uiNodesFilterComboBox.setItemText(0, _translate("MainWindow", "Installed & Available appliances"))
self.uiNodesFilterComboBox.setItemText(1, _translate("MainWindow", "Installed appliances"))
self.uiNodesFilterComboBox.setItemText(2, _translate("MainWindow", "Available appliances"))
self.uiNodesFilterComboBox.setItemText(3, _translate("MainWindow", "Custom appliances"))
self.uiNodesFilterLineEdit.setPlaceholderText(_translate("MainWindow", "Filter"))
self.uiNodesView.setToolTip(_translate("MainWindow", "Drag a node to the workspace (Press SHIFT while dragging to add multiple identical nodes)."))
self.uiNodesView.headerItem().setText(0, _translate("MainWindow", "1"))

View File

@@ -23,7 +23,7 @@
# or negative for a release candidate or beta (after the base version
# number has been incremented)
__version__ = "2.2.0dev2"
__version__ = "2.2.0dev3"
__version_info__ = (2, 2, 0, 99)
# If it's a git checkout try to add the commit