Custom patches for GNS3 network topology simulator & planning software.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

266 lines
10 KiB

Author: Pekka Helenius <pekka.helenius@fjordtek.com>
Date: Sun, 6 Jun 2021 15:15:14 +0200
Subject: [PATCH] GNS3 GUI: Link colors.
Add link color support for GNS3 GUI.
--- a/gns3/items/serial_link_item.py
+++ b/gns3/items/serial_link_item.py
@@ -50,10 +50,16 @@
LinkItem.adjust(self)
- if self._hovered:
- self.setPen(QtGui.QPen(QtCore.Qt.red, self._pen_width + 1, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin))
- else:
- self.setPen(QtGui.QPen(QtCore.Qt.darkRed, self._pen_width, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin))
+ try:
+ if self._hovered:
+ self.setPen(QtGui.QPen(QtCore.Qt.red, self._link._link_style["width"] + 1, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin))
+ else:
+ self.setPen(QtGui.QPen(QtGui.QColor(self._link._link_style["color"]), self._link._link_style["width"], self._link._link_style["type"], QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin))
+ except:
+ if self._hovered:
+ self.setPen(QtGui.QPen(QtCore.Qt.red, self._pen_width + 1, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin))
+ else:
+ self.setPen(QtGui.QPen(QtCore.Qt.darkRed, self._pen_width, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin))
# get source to destination angle
vector_angle = math.atan2(self.dy, self.dx)
--- a/gns3/items/link_item.py
+++ b/gns3/items/link_item.py
@@ -25,6 +25,7 @@
from ..packet_capture import PacketCapture
from ..dialogs.filter_dialog import FilterDialog
+from ..dialogs.style_editor_dialog_link import StyleEditorDialogLink
from ..utils.get_icon import get_icon
@@ -40,7 +41,6 @@
self.parentItem().mousePressEvent(event)
event.accept()
-
class LinkItem(QtWidgets.QGraphicsPathItem):
"""
@@ -137,6 +137,21 @@
def _suspendActionSlot(self, *args):
self._link.toggleSuspend()
+ @qslot
+ def _styleActionSlot(self, *args):
+ style_dialog = StyleEditorDialogLink(self, self._main_window)
+ style_dialog.show()
+ style_dialog.exec_()
+
+ def setLinkStyle(self, link_style):
+ self._link._link_style["color"] = link_style["color"]
+ self._link._link_style["width"] = link_style["width"]
+ self._link._link_style["type"] = link_style["type"]
+
+ # This refers to functions in link.py!
+ self._link.setLinkStyle(link_style)
+ self._link.update()
+
def delete(self):
"""
Delete this link
@@ -266,6 +281,12 @@
resume_action.triggered.connect(self._suspendActionSlot)
menu.addAction(resume_action)
+ # style
+ style_action = QtWidgets.QAction("Style", menu)
+ style_action.setIcon(get_icon("node_conception.svg"))
+ style_action.triggered.connect(self._styleActionSlot)
+ menu.addAction(style_action)
+
# delete
delete_action = QtWidgets.QAction("Delete", menu)
delete_action.setIcon(get_icon('delete.svg'))
--- a/gns3/items/ethernet_link_item.py
+++ b/gns3/items/ethernet_link_item.py
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
#
+# Copyright (C) 2019 Pekka Helenius
# Copyright (C) 2014 GNS3 Technologies Inc.
#
# This program is free software: you can redistribute it and/or modify
@@ -51,10 +52,16 @@
LinkItem.adjust(self)
- if self._hovered:
- self.setPen(QtGui.QPen(QtCore.Qt.red, self._pen_width + 1, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin))
- else:
- self.setPen(QtGui.QPen(QtCore.Qt.black, self._pen_width, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin))
+ try:
+ if self._hovered:
+ self.setPen(QtGui.QPen(QtCore.Qt.red, self._link._link_style["width"] + 1, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin))
+ else:
+ self.setPen(QtGui.QPen(QtGui.QColor(self._link._link_style["color"]), self._link._link_style["width"], self._link._link_style["type"], QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin))
+ except:
+ if self._hovered:
+ self.setPen(QtGui.QPen(QtCore.Qt.red, self._pen_width + 1, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin))
+ else:
+ self.setPen(QtGui.QPen(QtGui.QColor("#000000"), self._pen_width, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin))
# draw a line between nodes
path = QtGui.QPainterPath(self.source)
--- /dev/null 2019-05-22 14:27:07.219999993 +0300
+++ b/gns3/dialogs/style_editor_dialog_link.py
@@ -0,0 +1,112 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2019 Pekka Helenius
+# Copyright (C) 2014 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/>.
+
+"""
+Style editor to edit Link items.
+"""
+
+from ..qt import QtCore, QtWidgets, QtGui
+from ..ui.style_editor_dialog_ui import Ui_StyleEditorDialog
+
+
+class StyleEditorDialogLink(QtWidgets.QDialog, Ui_StyleEditorDialog):
+
+ """
+ Style editor dialog.
+
+ :param parent: parent widget
+ :param link: selected link
+ """
+
+ def __init__(self, link, parent):
+
+ super().__init__(parent)
+ self.setupUi(self)
+
+ self._link = link
+ self._link_style = {}
+
+ self.uiBorderColorPushButton.clicked.connect(self._setBorderColorSlot)
+ self.uiButtonBox.button(QtWidgets.QDialogButtonBox.Apply).clicked.connect(self._applyPreferencesSlot)
+
+ self.uiBorderStyleComboBox.addItem("Solid", QtCore.Qt.SolidLine)
+ self.uiBorderStyleComboBox.addItem("Dash", QtCore.Qt.DashLine)
+ self.uiBorderStyleComboBox.addItem("Dot", QtCore.Qt.DotLine)
+ self.uiBorderStyleComboBox.addItem("Dash Dot", QtCore.Qt.DashDotLine)
+ self.uiBorderStyleComboBox.addItem("Dash Dot Dot", QtCore.Qt.DashDotDotLine)
+
+ self.uiColorLabel.hide()
+ self.uiColorPushButton.hide()
+ self._color = None
+
+ self.uiRotationLabel.hide()
+ self.uiRotationSpinBox.hide()
+
+ pen = link.pen()
+
+ self._border_color = pen.color()
+ self.uiBorderColorPushButton.setStyleSheet("background-color: rgba({}, {}, {}, {});".format(self._border_color.red(),
+ self._border_color.green(),
+ self._border_color.blue(),
+ self._border_color.alpha()))
+ self.uiBorderWidthSpinBox.setValue(pen.width())
+ index = self.uiBorderStyleComboBox.findData(pen.style())
+ if index != -1:
+ self.uiBorderStyleComboBox.setCurrentIndex(index)
+
+ def _setBorderColorSlot(self):
+ """
+ Slot to select the border color.
+ """
+
+ color = QtWidgets.QColorDialog.getColor(self._border_color, self, "Select Color", QtWidgets.QColorDialog.ShowAlphaChannel)
+ if color.isValid():
+ self._border_color = color
+ self.uiBorderColorPushButton.setStyleSheet("background-color: rgba({}, {}, {}, {});".format(self._border_color.red(),
+ self._border_color.green(),
+ self._border_color.blue(),
+ self._border_color.alpha()))
+
+ def _applyPreferencesSlot(self):
+ """
+ Applies the new style settings.
+ """
+
+ border_style = QtCore.Qt.PenStyle(self.uiBorderStyleComboBox.itemData(self.uiBorderStyleComboBox.currentIndex()))
+ pen = QtGui.QPen(self._border_color, self.uiBorderWidthSpinBox.value(), border_style, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin)
+
+ self._link.setPen(pen)
+
+ new_link_style = {}
+ new_link_style["color"] = self._border_color.name()
+ new_link_style["width"] = self.uiBorderWidthSpinBox.value()
+ new_link_style["type"] = border_style
+
+ # Store values
+ self._link.setLinkStyle(new_link_style)
+
+ def done(self, result):
+ """
+ Called when the dialog is closed.
+
+ :param result: boolean (accepted or rejected)
+ """
+
+ if result:
+ self._applyPreferencesSlot()
+ super().done(result)
--- a/gns3/link.py
+++ b/gns3/link.py
@@ -90,6 +90,8 @@
self._nodes = []
+ self._link_style = {}
+
self._source_node.addLink(self)
self._destination_node.addLink(self)
@@ -127,6 +129,8 @@
self._updateLabels()
if "filters" in result:
self._filters = result["filters"]
+ if "link_style" in result:
+ self._link_style = result["link_style"]
if "suspend" in result:
self._suspend = result["suspend"]
self.updated_link_signal.emit(self._id)
@@ -209,6 +213,7 @@
}
],
"filters": self._filters,
+ "link_style": self._link_style,
"suspend": self._suspend
}
if self._source_port.label():
@@ -462,3 +467,9 @@
:params filters: List of filters
"""
self._filters = filters
+
+ def setLinkStyle(self, link_style):
+ """
+ :params _link_style: Set link style attributes
+ """
+ self._link_style = link_style