Skip to content

Commit

Permalink
Merge pull request #2677 from GNS3/svg-symbols-fixes
Browse files Browse the repository at this point in the history
Resize SVG node symbols that are too big. Fixes #2674
  • Loading branch information
grossmj authored Jan 22, 2019
2 parents cf73db2 + c6594d4 commit 911f630
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 11 deletions.
2 changes: 1 addition & 1 deletion gns3/dialogs/symbol_selection_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ def _symbolBrowserSlot(self):

def _finishSymbolUpload(self, path, result, error=False, **kwargs):
if error:
log.error("Error while uploading symbol: {}".format(path))
log.error("Error while uploading symbol: {}: {}".format(path, result.get("message", "unknown")))
return
self.uiSymbolLineEdit.clear()
self.uiSymbolLineEdit.setText(path)
Expand Down
5 changes: 5 additions & 0 deletions gns3/items/node_item.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,14 @@ def symbol(self):

@qslot
def _symbolLoadedCallback(self, path, *args):

renderer = QImageSvgRenderer(path, fallback=":/icons/cancel.svg")
renderer.setObjectName(path)
self.setSharedRenderer(renderer)
if self._settings["limit_size_node_symbols"] is True and renderer.defaultSize().height() > 80:
# resize the SVG
renderer.resize(80)
self.setSharedRenderer(renderer)
if self._node.settings().get("symbol") != self._symbol:
self.updateNode()
if not self._initialized:
Expand Down
2 changes: 2 additions & 0 deletions gns3/pages/general_preferences_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ def _populateGraphicsViewSettingWidgets(self, settings):
self.uiRectangleSelectedItemCheckBox.setChecked(settings["draw_rectangle_selected_item"])
self.uiDrawLinkStatusPointsCheckBox.setChecked(settings["draw_link_status_points"])
self.uiShowInterfaceLabelsOnNewProject.setChecked(settings["show_interface_labels_on_new_project"])
self.uiLimitSizeNodeSymbolCheckBox.setChecked(settings["limit_size_node_symbols"])

qt_font = QtGui.QFont()
if qt_font.fromString(settings["default_label_font"]):
Expand Down Expand Up @@ -384,6 +385,7 @@ def savePreferences(self):
"draw_rectangle_selected_item": self.uiRectangleSelectedItemCheckBox.isChecked(),
"draw_link_status_points": self.uiDrawLinkStatusPointsCheckBox.isChecked(),
"show_interface_labels_on_new_project": self.uiShowInterfaceLabelsOnNewProject.isChecked(),
"limit_size_node_symbols": self.uiLimitSizeNodeSymbolCheckBox.isChecked(),
"default_label_font": self.uiDefaultLabelStylePlainTextEdit.font().toString(),
"default_label_color": self._default_label_color.name()}
MainWindow.instance().uiGraphicsView.setSettings(new_graphics_view_settings)
40 changes: 40 additions & 0 deletions gns3/qt/qimage_svg_renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import os
import re
import xml.etree.ElementTree as ET

from . import QtCore
Expand All @@ -35,12 +36,14 @@ class QImageSvgRenderer(QtSvg.QSvgRenderer):
"""

def __init__(self, path_or_data=None, fallback=None):

super().__init__()
self._fallback = fallback
self._svg = """<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="{width}" height="{height}"></svg>"""
self.load(path_or_data)

def load(self, path_or_data):

try:
path_exists = os.path.exists(path_or_data)
except ValueError: # On windows we can get an error because the path is too long (it's the svg data)
Expand Down Expand Up @@ -92,6 +95,43 @@ def load(self, path_or_data):
res = super().load(self._svg.encode())
return res

def resize(self, new_height, new_width=None):

if not self.isValid():
log.error("QSvgRenderer is not valid")
return

size = self.defaultSize()
height = size.height()
width = size.width()

if not new_width:
new_width = round(width / height * new_height)

add_attr = []
svg_header, svg_tag, svg_data = re.split(r'(<svg[^>]*>)', self._svg, maxsplit=1)

attr = 'height="{}"'.format(new_height)
svg_tag, count = re.subn(r'height="[^"]*"', attr, svg_tag, count=1)
if not count:
add_attr.append(attr)

attr = 'width="{}"'.format(new_width)
svg_tag, count = re.subn(r'width="[^"]*"', attr, svg_tag, count=1)
if not count:
add_attr.append(attr)

if 'viewBox="' not in svg_tag:
add_attr.append('viewBox="0 0 {} {}"'.format(width, height))

if add_attr:
svg_tag = svg_tag.replace('<svg', '<svg ' + ' '.join(add_attr), 1)

svg_image = svg_header + svg_tag + svg_data
res = super().load(svg_image.encode())
if res is False:
log.error("Could not resize QSvgRenderer")

def svg(self):
"""
:returns: SVG source code
Expand Down
3 changes: 2 additions & 1 deletion gns3/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,8 @@
"snap_to_grid": False,
"show_grid": False,
"show_interface_labels": False,
"show_interface_labels_on_new_project": False
"show_interface_labels_on_new_project": False,
"limit_size_node_symbols": True
}

LOCAL_SERVER_SETTINGS = {
Expand Down
15 changes: 11 additions & 4 deletions gns3/ui/general_preferences_page.ui
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,7 @@
</property>
</widget>
</item>
<item row="11" column="0" colspan="2">
<item row="12" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QPushButton" name="uiDefaultLabelFontPushButton">
Expand Down Expand Up @@ -721,7 +721,7 @@
</property>
</widget>
</item>
<item row="9" column="0">
<item row="10" column="0">
<widget class="QLabel" name="uiLabelPreviewLabel">
<property name="text">
<string>Default label style:</string>
Expand All @@ -738,7 +738,7 @@
</property>
</widget>
</item>
<item row="10" column="0" colspan="2">
<item row="11" column="0" colspan="2">
<widget class="QPlainTextEdit" name="uiDefaultLabelStylePlainTextEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding">
Expand All @@ -760,7 +760,7 @@
</property>
</widget>
</item>
<item row="12" column="0">
<item row="13" column="0">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
Expand Down Expand Up @@ -822,6 +822,13 @@
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QCheckBox" name="uiLimitSizeNodeSymbolCheckBox">
<property name="text">
<string>Limit the size of node symbols</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="uiMiscTab">
Expand Down
14 changes: 9 additions & 5 deletions gns3/ui/general_preferences_page_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# Form implementation generated from reading ui file '/home/grossmj/PycharmProjects/gns3-gui/gns3/ui/general_preferences_page.ui'
#
# Created by: PyQt5 UI code generator 5.5.1
# Created by: PyQt5 UI code generator 5.11.3
#
# WARNING! All changes made in this file will be lost!

Expand Down Expand Up @@ -324,7 +324,7 @@ def setupUi(self, GeneralPreferencesPageWidget):
self.horizontalLayout_5.addWidget(self.uiDefaultLabelColorPushButton)
spacerItem6 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_5.addItem(spacerItem6)
self.gridLayout_8.addLayout(self.horizontalLayout_5, 11, 0, 1, 2)
self.gridLayout_8.addLayout(self.horizontalLayout_5, 12, 0, 1, 2)
self.uiSceneHeightLabel = QtWidgets.QLabel(self.uiSceneTab)
self.uiSceneHeightLabel.setObjectName("uiSceneHeightLabel")
self.gridLayout_8.addWidget(self.uiSceneHeightLabel, 2, 0, 1, 1)
Expand All @@ -337,7 +337,7 @@ def setupUi(self, GeneralPreferencesPageWidget):
self.gridLayout_8.addWidget(self.uiSceneHeightSpinBox, 3, 0, 1, 2)
self.uiLabelPreviewLabel = QtWidgets.QLabel(self.uiSceneTab)
self.uiLabelPreviewLabel.setObjectName("uiLabelPreviewLabel")
self.gridLayout_8.addWidget(self.uiLabelPreviewLabel, 9, 0, 1, 1)
self.gridLayout_8.addWidget(self.uiLabelPreviewLabel, 10, 0, 1, 1)
self.uiDrawLinkStatusPointsCheckBox = QtWidgets.QCheckBox(self.uiSceneTab)
self.uiDrawLinkStatusPointsCheckBox.setChecked(True)
self.uiDrawLinkStatusPointsCheckBox.setObjectName("uiDrawLinkStatusPointsCheckBox")
Expand All @@ -351,9 +351,9 @@ def setupUi(self, GeneralPreferencesPageWidget):
self.uiDefaultLabelStylePlainTextEdit.setMaximumSize(QtCore.QSize(16777215, 50))
self.uiDefaultLabelStylePlainTextEdit.setReadOnly(True)
self.uiDefaultLabelStylePlainTextEdit.setObjectName("uiDefaultLabelStylePlainTextEdit")
self.gridLayout_8.addWidget(self.uiDefaultLabelStylePlainTextEdit, 10, 0, 1, 2)
self.gridLayout_8.addWidget(self.uiDefaultLabelStylePlainTextEdit, 11, 0, 1, 2)
spacerItem7 = QtWidgets.QSpacerItem(20, 5, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.gridLayout_8.addItem(spacerItem7, 12, 0, 1, 1)
self.gridLayout_8.addItem(spacerItem7, 13, 0, 1, 1)
self.uiSceneWidthSpinBox = QtWidgets.QSpinBox(self.uiSceneTab)
self.uiSceneWidthSpinBox.setMinimum(500)
self.uiSceneWidthSpinBox.setMaximum(1000000)
Expand All @@ -374,6 +374,9 @@ def setupUi(self, GeneralPreferencesPageWidget):
self.uiGridSizeSpinBox.setProperty("value", 75)
self.uiGridSizeSpinBox.setObjectName("uiGridSizeSpinBox")
self.gridLayout_8.addWidget(self.uiGridSizeSpinBox, 5, 0, 1, 2)
self.uiLimitSizeNodeSymbolCheckBox = QtWidgets.QCheckBox(self.uiSceneTab)
self.uiLimitSizeNodeSymbolCheckBox.setObjectName("uiLimitSizeNodeSymbolCheckBox")
self.gridLayout_8.addWidget(self.uiLimitSizeNodeSymbolCheckBox, 9, 0, 1, 1)
self.uiMiscTabWidget.addTab(self.uiSceneTab, "")
self.uiMiscTab = QtWidgets.QWidget()
self.uiMiscTab.setObjectName("uiMiscTab")
Expand Down Expand Up @@ -513,6 +516,7 @@ def retranslateUi(self, GeneralPreferencesPageWidget):
self.uiSceneWidthSpinBox.setSuffix(_translate("GeneralPreferencesPageWidget", " pixels"))
self.uiShowInterfaceLabelsOnNewProject.setText(_translate("GeneralPreferencesPageWidget", "Show interface labels on new project"))
self.uiGridSizeLabel.setText(_translate("GeneralPreferencesPageWidget", "Grid size:"))
self.uiLimitSizeNodeSymbolCheckBox.setText(_translate("GeneralPreferencesPageWidget", "Limit the size of node symbols"))
self.uiMiscTabWidget.setTabText(self.uiMiscTabWidget.indexOf(self.uiSceneTab), _translate("GeneralPreferencesPageWidget", "Topology view"))
self.uiCheckForUpdateCheckBox.setText(_translate("GeneralPreferencesPageWidget", "Automatically check for update"))
self.uiCrashReportCheckBox.setText(_translate("GeneralPreferencesPageWidget", "Send anonymous crash reports"))
Expand Down

0 comments on commit 911f630

Please sign in to comment.