From 5de27a95f901bb977cb32b160ba996b43d89ed71 Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Wed, 17 Aug 2016 17:12:23 +0200 Subject: [PATCH] Center label when hostname change Fix #1404 --- gns3server/controller/node.py | 29 +++++++++++++++------- gns3server/controller/topology.py | 17 +++---------- gns3server/schemas/label.py | 4 ++-- gns3server/utils/qt.py | 40 +++++++++++++++++++++++++++++++ tests/controller/test_node.py | 24 +++++++++++++++++++ 5 files changed, 90 insertions(+), 24 deletions(-) create mode 100644 gns3server/utils/qt.py diff --git a/gns3server/controller/node.py b/gns3server/controller/node.py index 24751a97..7a105b53 100644 --- a/gns3server/controller/node.py +++ b/gns3server/controller/node.py @@ -23,6 +23,7 @@ import os from .compute import ComputeConflict from ..utils.images import images_directories +from ..utils.qt import qt_font_to_style import logging @@ -54,13 +55,7 @@ class Node: self._compute = compute self._node_type = node_type - self._label = { - "y": -25, - "text": "", - "style": "font-size: 10;font-familly: Verdana", - "x": -17, - "rotation": 0 - } + self._label = None self._name = None self.name = name self._console = None @@ -106,7 +101,9 @@ class Node: def name(self, new_name): self._name = self._project.update_node_name(self, new_name) # The text in label need to be always the node name - self._label["text"] = self._name + if self.label and self._label["text"] != self._name: + self._label["text"] = self._name + self._label["x"] = None # Center text @property def node_type(self): @@ -195,6 +192,22 @@ class Node: # If symbol is invalid we replace it by default except (ValueError, OSError): self.symbol = ":/symbols/computer.svg" + if self._label is None: + # Apply to label user style or default + try: + style = qt_font_to_style( + self._project.controller.settings["GraphicsView"]["default_label_font"], + self._project.controller.settings["GraphicsView"]["default_label_color"]) + except KeyError: + style = "font-size: 10;font-familly: Verdana" + + self._label = { + "y": round(self._height / 2 + 10) * -1, + "text": self._name, + "style": style, + "x": None, # None: mean the client should center it + "rotation": 0 + } @property def label(self): diff --git a/gns3server/controller/topology.py b/gns3server/controller/topology.py index b2f1cc52..5805c846 100644 --- a/gns3server/controller/topology.py +++ b/gns3server/controller/topology.py @@ -26,6 +26,8 @@ import jsonschema from ..version import __version__ from ..schemas.topology import TOPOLOGY_SCHEMA +from ..utils.qt import qt_font_to_style + import logging log = logging.getLogger(__name__) @@ -403,20 +405,7 @@ def _convert_label(label): """ Convert a label from 1.X to the new format """ - font_info = label["font"].split(",") - style = "font-family: {};font-size: {};".format(font_info[0], font_info[1]) - if font_info[4] == "75": - style += "font-weight: bold;" - if font_info[5] == "1": - style += "font-style: italic;" - color = label["color"] - - if len(color) == 9: - style += "fill: #" + color[-6:] + ";" - style += "fill-opacity: {};".format(round(1.0 / 255 * int(color[:3][-2:], base=16), 2)) - else: - style += "fill: #" + color[-6:] + ";" - style += "fill-opacity: {};".format(1.0) + style = qt_font_to_style(label["font"], label["color"]) return { "text": label["text"], "rotation": 0, diff --git a/gns3server/schemas/label.py b/gns3server/schemas/label.py index 9aca610c..61a0a227 100644 --- a/gns3server/schemas/label.py +++ b/gns3server/schemas/label.py @@ -24,8 +24,8 @@ LABEL_OBJECT_SCHEMA = { "type": "string" }, "x": { - "description": "Relative X position of the label", - "type": "integer" + "description": "Relative X position of the label. If null center it", + "type": ["integer", "null"] }, "y": { "description": "Relative Y position of the label", diff --git a/gns3server/utils/qt.py b/gns3server/utils/qt.py new file mode 100644 index 00000000..adb15124 --- /dev/null +++ b/gns3server/utils/qt.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python +# +# Copyright (C) 2016 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 . + +""" +Helper for conversion of Qt stuff +""" + + +def qt_font_to_style(font, color): + """ + Convert a Qt font to CSS style + """ + font_info = font.split(",") + style = "font-family: {};font-size: {};".format(font_info[0], font_info[1]) + if font_info[4] == "75": + style += "font-weight: bold;" + if font_info[5] == "1": + style += "font-style: italic;" + + if len(color) == 9: + style += "fill: #" + color[-6:] + ";" + style += "fill-opacity: {};".format(round(1.0 / 255 * int(color[:3][-2:], base=16), 2)) + else: + style += "fill: #" + color[-6:] + ";" + style += "fill-opacity: {};".format(1.0) + return style diff --git a/tests/controller/test_node.py b/tests/controller/test_node.py index f33c0485..edb7887d 100644 --- a/tests/controller/test_node.py +++ b/tests/controller/test_node.py @@ -179,11 +179,35 @@ def test_symbol(node): assert node.symbol == ":/symbols/dslam.svg" assert node.width == 50 assert node.height == 53 + assert node.label["x"] is None + assert node.label["y"] == -40 + node.symbol = ":/symbols/cloud.svg" assert node.symbol == ":/symbols/cloud.svg" assert node.width == 159 assert node.height == 71 + assert node.label["x"] is None + assert node.label["y"] == -40 + assert node.label["style"] == "font-size: 10;font-familly: Verdana" + + +def test_label_with_default_label_font(node): + """ + If user has changed the font we need to have the node label using + the correct color + """ + node.project.controller.settings = { + "GraphicsView": { + "default_label_color": "#ff0000", + "default_label_font": "TypeWriter,10,-1,5,75,0,0,0,0,0" + } + } + + node._label = None + node.symbol = ":/symbols/dslam.svg" + assert node.label["style"] == "font-family: TypeWriter;font-size: 10;font-weight: bold;fill: #ff0000;fill-opacity: 1.0;" + def test_update(node, compute, project, async_run, controller): response = MagicMock()