Author: Pekka Helenius 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 . + +""" +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