mirror of
https://github.com/GNS3/gns3-gui.git
synced 2026-05-17 00:46:01 +03:00
Download custom appliance symbols from GitHub
Fix symbol cache issue. Ref https://github.com/GNS3/gns3-gui/issues/2671 Fix temporary directory for symbols was not deleted Fix temporary appliance file was not deleted
This commit is contained in:
@@ -19,6 +19,7 @@ import os
|
||||
import hashlib
|
||||
import tempfile
|
||||
import json
|
||||
import pathlib
|
||||
|
||||
from .qt import QtCore, QtNetwork, QtGui, QtWidgets, QtWebSockets, qpartial, qslot
|
||||
from .symbol import Symbol
|
||||
@@ -46,7 +47,7 @@ class Controller(QtCore.QObject):
|
||||
self._connected = False
|
||||
self._connecting = False
|
||||
self._version = None
|
||||
self._cache_directory = tempfile.mkdtemp()
|
||||
self._cache_directory = tempfile.TemporaryDirectory(suffix="-gns3")
|
||||
self._http_client = None
|
||||
self._first_error = True
|
||||
self._error_dialog = None
|
||||
@@ -274,12 +275,11 @@ class Controller(QtCore.QObject):
|
||||
if not self._http_client:
|
||||
return
|
||||
|
||||
|
||||
path = self.getStaticCachedPath(url)
|
||||
|
||||
if os.path.exists(path):
|
||||
callback(path)
|
||||
elif path in self._static_asset_download_queue:
|
||||
if path in self._static_asset_download_queue:
|
||||
self._static_asset_download_queue[path].append((callback, fallback, ))
|
||||
else:
|
||||
self._static_asset_download_queue[path] = [(callback, fallback, )]
|
||||
@@ -313,8 +313,8 @@ class Controller(QtCore.QObject):
|
||||
def getStaticCachedPath(self, url):
|
||||
"""
|
||||
Returns static cached (hashed) path
|
||||
|
||||
:param url:
|
||||
:return:
|
||||
"""
|
||||
m = hashlib.md5()
|
||||
m.update(url.encode())
|
||||
@@ -322,9 +322,22 @@ class Controller(QtCore.QObject):
|
||||
extension = ".svg"
|
||||
else:
|
||||
extension = ".png"
|
||||
path = os.path.join(self._cache_directory, m.hexdigest() + extension)
|
||||
path = os.path.join(self._cache_directory.name, m.hexdigest() + extension)
|
||||
return path
|
||||
|
||||
def clearStaticCache(self):
|
||||
"""
|
||||
Clear the cache directory.
|
||||
"""
|
||||
|
||||
for filename in os.listdir(self._cache_directory.name):
|
||||
if filename.endswith(".svg") or filename.endswith(".png"):
|
||||
try:
|
||||
os.remove(os.path.join(self._cache_directory.name, filename))
|
||||
except OSError as e:
|
||||
log.debug("Error deleting cached symbol '{}':{}".format(filename, e))
|
||||
continue
|
||||
|
||||
def getSymbolIcon(self, symbol_id, callback, fallback=None):
|
||||
"""
|
||||
Get a QIcon for a symbol from the controller
|
||||
@@ -341,10 +354,31 @@ class Controller(QtCore.QObject):
|
||||
self.getStatic(Symbol(symbol_id).url(), qpartial(self._getIconCallback, callback), fallback=fallback)
|
||||
|
||||
def _getIconCallback(self, callback, path):
|
||||
|
||||
pixmap = QtGui.QPixmap(path)
|
||||
if pixmap.isNull():
|
||||
log.debug("Invalid symbol {}".format(path))
|
||||
path = ":/icons/cancel.svg"
|
||||
icon = QtGui.QIcon()
|
||||
icon.addFile(path)
|
||||
callback(icon)
|
||||
|
||||
def uploadSymbol(self, symbol_id, path):
|
||||
|
||||
self.post("/symbols/" + symbol_id + "/raw",
|
||||
qpartial(self._finishSymbolUpload, path),
|
||||
body=pathlib.Path(path), progressText="Uploading {}".format(symbol_id), timeout=None)
|
||||
|
||||
def _finishSymbolUpload(self, path, result, error=False, **kwargs):
|
||||
|
||||
if error:
|
||||
log.error("Error while uploading symbol: {}: {}".format(path, result.get("message", "unknown")))
|
||||
return
|
||||
|
||||
# Refresh the templates list
|
||||
from .template_manager import TemplateManager
|
||||
TemplateManager.instance().templates_changed_signal.emit()
|
||||
|
||||
def getSymbols(self, callback):
|
||||
self.get('/symbols', callback=callback)
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import sys
|
||||
import tempfile
|
||||
import json
|
||||
import sip
|
||||
import os
|
||||
|
||||
from gns3.qt import QtCore, QtWidgets, qpartial
|
||||
from gns3.controller import Controller
|
||||
@@ -59,6 +60,7 @@ class NewTemplateWizard(QtWidgets.QWizard, Ui_NewTemplateWizard):
|
||||
"""
|
||||
|
||||
ApplianceManager.instance().refresh(update=True)
|
||||
Controller.instance().clearStaticCache()
|
||||
|
||||
def _appliancesChangedSlot(self):
|
||||
"""
|
||||
@@ -266,6 +268,7 @@ class NewTemplateWizard(QtWidgets.QWizard, Ui_NewTemplateWizard):
|
||||
|
||||
super().done(result)
|
||||
if result:
|
||||
ApplianceManager.instance().appliances_changed_signal.disconnect(self._appliancesChangedSlot)
|
||||
from gns3.main_window import MainWindow
|
||||
if self.currentPage() == self.uiApplianceFromServerWizardPage:
|
||||
items = self.uiAppliancesTreeWidget.selectedItems()
|
||||
@@ -274,6 +277,10 @@ class NewTemplateWizard(QtWidgets.QWizard, Ui_NewTemplateWizard):
|
||||
json.dump(item.data(0, QtCore.Qt.UserRole), f)
|
||||
f.close()
|
||||
MainWindow.instance().loadPath(f.name)
|
||||
try:
|
||||
os.remove(f.name)
|
||||
except OSError:
|
||||
pass
|
||||
elif self.uiCreateTemplateManuallyRadioButton.isChecked():
|
||||
MainWindow.instance().preferencesActionSlot()
|
||||
elif self.uiImportApplianceFromFileRadioButton.isChecked():
|
||||
|
||||
@@ -128,7 +128,7 @@ class PreferencesDialog(QtWidgets.QDialog, Ui_PreferencesDialog):
|
||||
|
||||
# Class name, changed signal
|
||||
widget_to_watch = {
|
||||
QtWidgets.QLineEdit: "textChanged",
|
||||
#QtWidgets.QLineEdit: "textChanged",
|
||||
QtWidgets.QPlainTextEdit: "textChanged",
|
||||
# QtWidgets.QTreeWidget: "itemChanged",
|
||||
QtWidgets.QComboBox: "currentIndexChanged",
|
||||
|
||||
@@ -25,7 +25,6 @@ import pathlib
|
||||
from ..qt import QtCore, QtGui, QtWidgets, qpartial, sip_is_deleted
|
||||
from ..qt.qimage_svg_renderer import QImageSvgRenderer
|
||||
from ..ui.symbol_selection_dialog_ui import Ui_SymbolSelectionDialog
|
||||
from ..local_server import LocalServer
|
||||
from ..controller import Controller
|
||||
from ..symbol import Symbol
|
||||
|
||||
@@ -56,7 +55,6 @@ class SymbolSelectionDialog(QtWidgets.QDialog, Ui_SymbolSelectionDialog):
|
||||
self.uiCustomSymbolRadioButton.toggled.connect(self._customSymbolToggledSlot)
|
||||
self.uiBuiltInSymbolRadioButton.toggled.connect(self._builtInSymbolToggledSlot)
|
||||
self.uiSearchLineEdit.textChanged.connect(self._searchTextChangedSlot)
|
||||
self.uiBuiltinSymbolOnlyCheckBox.toggled.connect(self._builtinSymbolOnlyToggledSlot)
|
||||
if not SymbolSelectionDialog._symbols_dir:
|
||||
SymbolSelectionDialog._symbols_dir = QtCore.QStandardPaths.writableLocation(QtCore.QStandardPaths.PicturesLocation)
|
||||
|
||||
@@ -64,9 +62,10 @@ class SymbolSelectionDialog(QtWidgets.QDialog, Ui_SymbolSelectionDialog):
|
||||
self.uiButtonBox.button(QtWidgets.QDialogButtonBox.Apply).hide()
|
||||
|
||||
self.uiBuiltInSymbolRadioButton.setChecked(True)
|
||||
self.uiSymbolListWidget.setFocus()
|
||||
self.uiSymbolListWidget.setIconSize(QtCore.QSize(64, 64))
|
||||
self.uiSymbolTreeWidget.setFocus()
|
||||
self.uiSymbolTreeWidget.setIconSize(QtCore.QSize(64, 64))
|
||||
self._symbol_items = []
|
||||
self._parents = {}
|
||||
|
||||
Controller.instance().get("/symbols", self._listSymbolsCallback)
|
||||
|
||||
@@ -78,17 +77,24 @@ class SymbolSelectionDialog(QtWidgets.QDialog, Ui_SymbolSelectionDialog):
|
||||
self._symbol_items = []
|
||||
for symbol in result:
|
||||
symbol = Symbol(**symbol)
|
||||
name = os.path.splitext(symbol.filename())[0]
|
||||
item = QtWidgets.QListWidgetItem(self.uiSymbolListWidget)
|
||||
item.setData(QtCore.Qt.UserRole, symbol)
|
||||
self._symbol_items.append(item)
|
||||
item.setText(name)
|
||||
theme = symbol.theme()
|
||||
if theme not in self._parents:
|
||||
parent = QtWidgets.QTreeWidgetItem(self.uiSymbolTreeWidget)
|
||||
parent.setText(0, theme)
|
||||
font = parent.font(0)
|
||||
font.setBold(True)
|
||||
parent.setFont(0, font)
|
||||
parent.setFlags(parent.flags() & ~QtCore.Qt.ItemIsSelectable)
|
||||
self._parents[theme] = parent
|
||||
else:
|
||||
parent = self._parents[theme]
|
||||
|
||||
image = QtGui.QImage(64, 64, QtGui.QImage.Format_ARGB32)
|
||||
# Set the ARGB to 0 to prevent rendering artifacts
|
||||
image.fill(0x00000000)
|
||||
icon = QtGui.QIcon(QtGui.QPixmap.fromImage(image))
|
||||
item.setIcon(icon)
|
||||
name = os.path.splitext(symbol.filename())[0]
|
||||
item = QtWidgets.QTreeWidgetItem(parent)
|
||||
item.setData(0, QtCore.Qt.UserRole, symbol)
|
||||
item.setToolTip(0, symbol.id())
|
||||
self._symbol_items.append(item)
|
||||
item.setText(0, name)
|
||||
|
||||
def render(item, path):
|
||||
if sip_is_deleted(item):
|
||||
@@ -99,14 +105,11 @@ class SymbolSelectionDialog(QtWidgets.QDialog, Ui_SymbolSelectionDialog):
|
||||
image.fill(0x00000000)
|
||||
svg_renderer.render(QtGui.QPainter(image))
|
||||
icon = QtGui.QIcon(QtGui.QPixmap.fromImage(image))
|
||||
item.setIcon(icon)
|
||||
item.setIcon(0, icon)
|
||||
|
||||
Controller.instance().getStatic(symbol.url(), qpartial(render, item))
|
||||
self.adjustSize()
|
||||
|
||||
def _builtinSymbolOnlyToggledSlot(self, checked):
|
||||
self._filter()
|
||||
|
||||
def _searchTextChangedSlot(self, text):
|
||||
self._filter()
|
||||
|
||||
@@ -116,10 +119,10 @@ class SymbolSelectionDialog(QtWidgets.QDialog, Ui_SymbolSelectionDialog):
|
||||
"""
|
||||
text = self.uiSearchLineEdit.text()
|
||||
for item in self._symbol_items:
|
||||
if self.uiBuiltinSymbolOnlyCheckBox.isChecked() and not item.data(QtCore.Qt.UserRole).builtin():
|
||||
if not item.data(0, QtCore.Qt.UserRole).builtin():
|
||||
item.setHidden(True)
|
||||
else:
|
||||
if len(text.strip()) == 0 or text.strip().lower() in item.text().lower():
|
||||
if len(text.strip()) == 0 or text.strip().lower() in item.text(0).lower():
|
||||
item.setHidden(False)
|
||||
else:
|
||||
item.setHidden(True)
|
||||
@@ -164,10 +167,10 @@ class SymbolSelectionDialog(QtWidgets.QDialog, Ui_SymbolSelectionDialog):
|
||||
|
||||
def getSymbol(self):
|
||||
|
||||
if self.uiSymbolListWidget.isEnabled():
|
||||
current = self.uiSymbolListWidget.currentItem()
|
||||
if self.uiSymbolTreeWidget.isEnabled():
|
||||
current = self.uiSymbolTreeWidget.currentItem()
|
||||
if current:
|
||||
return current.data(QtCore.Qt.UserRole).id()
|
||||
return current.data(0, QtCore.Qt.UserRole).id()
|
||||
else:
|
||||
return os.path.basename(self.uiSymbolLineEdit.text())
|
||||
return None
|
||||
|
||||
@@ -36,7 +36,8 @@ class SvgIconItem(QtSvg.QGraphicsSvgItem):
|
||||
|
||||
def mousePressEvent(self, event):
|
||||
|
||||
self.parentItem().mousePressEvent(event)
|
||||
if self.parentItem():
|
||||
self.parentItem().mousePressEvent(event)
|
||||
event.accept()
|
||||
|
||||
|
||||
|
||||
@@ -168,37 +168,38 @@ class ApplianceToTemplate:
|
||||
|
||||
return os.path.basename(path)
|
||||
|
||||
def _set_symbol(self, symbol, controller_symbols):
|
||||
def _set_symbol(self, symbol_id, controller_symbols):
|
||||
"""
|
||||
Check if exists on controller or download symbol from the web if needed
|
||||
"""
|
||||
|
||||
# GNS3 builtin symbol
|
||||
if symbol.startswith(":/symbols/"):
|
||||
return symbol
|
||||
if symbol_id.startswith(":/symbols/"):
|
||||
return symbol_id
|
||||
|
||||
path = os.path.join(Config().symbols_dir, symbol)
|
||||
path = os.path.join(Config().symbols_dir, symbol_id)
|
||||
if os.path.exists(path):
|
||||
return os.path.basename(path)
|
||||
|
||||
if controller_symbols:
|
||||
is_symbol_on_controller = len([s for s in controller_symbols
|
||||
if s['symbol_id'] == symbol]) > 0
|
||||
is_symbol_on_controller = len([s for s in controller_symbols if s['symbol_id'] == symbol_id]) > 0
|
||||
|
||||
if is_symbol_on_controller:
|
||||
cached = Controller.instance().getStaticCachedPath(symbol)
|
||||
cached = Controller.instance().getStaticCachedPath(symbol_id)
|
||||
if os.path.exists(cached):
|
||||
try:
|
||||
shutil.copy(cached, path)
|
||||
except IOError as e:
|
||||
log.warning("Cannot copy cached symbol from `{}` to `{}` due `{}`".format(
|
||||
cached, path, str(e)
|
||||
))
|
||||
return symbol
|
||||
log.warning("Cannot copy cached symbol from `{}` to `{}` due `{}`".format(cached, path, e))
|
||||
return symbol_id
|
||||
|
||||
url = "https://raw.githubusercontent.com/GNS3/gns3-registry/master/symbols/{}".format(symbol)
|
||||
url = "https://raw.githubusercontent.com/GNS3/gns3-registry/master/symbols/{}".format(symbol_id)
|
||||
try:
|
||||
urllib.request.urlretrieve(url, path)
|
||||
controller = Controller.instance()
|
||||
controller.clearStaticCache()
|
||||
if controller.isRemote():
|
||||
controller.uploadSymbol(symbol_id, path)
|
||||
return os.path.basename(path)
|
||||
except (OSError, CertificateError):
|
||||
return None
|
||||
|
||||
@@ -19,10 +19,11 @@ import urllib.parse
|
||||
|
||||
|
||||
class Symbol:
|
||||
def __init__(self, symbol_id=None, builtin=False, filename=None):
|
||||
def __init__(self, symbol_id=None, builtin=False, filename=None, theme=None):
|
||||
self._id = symbol_id
|
||||
self._builtin = builtin
|
||||
self._filename = filename
|
||||
self._theme = theme
|
||||
|
||||
def id(self):
|
||||
return self._id
|
||||
@@ -33,6 +34,9 @@ class Symbol:
|
||||
def builtin(self):
|
||||
return self._builtin
|
||||
|
||||
def theme(self):
|
||||
return self._theme
|
||||
|
||||
def url(self):
|
||||
return urllib.parse.quote("/symbols/" + self._id + "/raw")
|
||||
|
||||
|
||||
@@ -70,6 +70,9 @@
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||
</property>
|
||||
<property name="indentation">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
|
||||
@@ -37,6 +37,7 @@ class Ui_NewTemplateWizard(object):
|
||||
self.verticalLayout_2.addWidget(self.uiFilterLineEdit)
|
||||
self.uiAppliancesTreeWidget = QtWidgets.QTreeWidget(self.uiApplianceFromServerWizardPage)
|
||||
self.uiAppliancesTreeWidget.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
|
||||
self.uiAppliancesTreeWidget.setIndentation(10)
|
||||
self.uiAppliancesTreeWidget.setObjectName("uiAppliancesTreeWidget")
|
||||
self.uiAppliancesTreeWidget.header().setSortIndicatorShown(True)
|
||||
self.verticalLayout_2.addWidget(self.uiAppliancesTreeWidget)
|
||||
|
||||
@@ -53,13 +53,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLineEdit" name="uiCaptureReaderCommandLineEdit">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Command line replacements:</p><p>%c = capture file (PCAP format)</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="uiAutoStartCheckBox">
|
||||
<property name="enabled">
|
||||
@@ -80,9 +73,16 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<item row="6" column="0" colspan="2">
|
||||
<widget class="QLineEdit" name="uiCaptureAnalyzerCommandLineEdit"/>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QLineEdit" name="uiCaptureReaderCommandLineEdit">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Command line replacements:</p><p>%c = capture file (PCAP format)</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -36,9 +36,6 @@ class Ui_PacketCapturePreferencesPageWidget(object):
|
||||
self.uiCaptureReaderCommandLabel.setEnabled(True)
|
||||
self.uiCaptureReaderCommandLabel.setObjectName("uiCaptureReaderCommandLabel")
|
||||
self.gridLayout.addWidget(self.uiCaptureReaderCommandLabel, 2, 0, 1, 1)
|
||||
self.uiCaptureReaderCommandLineEdit = QtWidgets.QLineEdit(self.uiSettingsGroupBox)
|
||||
self.uiCaptureReaderCommandLineEdit.setObjectName("uiCaptureReaderCommandLineEdit")
|
||||
self.gridLayout.addWidget(self.uiCaptureReaderCommandLineEdit, 3, 0, 1, 1)
|
||||
self.uiAutoStartCheckBox = QtWidgets.QCheckBox(self.uiSettingsGroupBox)
|
||||
self.uiAutoStartCheckBox.setEnabled(True)
|
||||
self.uiAutoStartCheckBox.setChecked(False)
|
||||
@@ -49,7 +46,10 @@ class Ui_PacketCapturePreferencesPageWidget(object):
|
||||
self.gridLayout.addWidget(self.uiCaptureAnalyzerCommandLabel, 5, 0, 1, 1)
|
||||
self.uiCaptureAnalyzerCommandLineEdit = QtWidgets.QLineEdit(self.uiSettingsGroupBox)
|
||||
self.uiCaptureAnalyzerCommandLineEdit.setObjectName("uiCaptureAnalyzerCommandLineEdit")
|
||||
self.gridLayout.addWidget(self.uiCaptureAnalyzerCommandLineEdit, 6, 0, 1, 1)
|
||||
self.gridLayout.addWidget(self.uiCaptureAnalyzerCommandLineEdit, 6, 0, 1, 2)
|
||||
self.uiCaptureReaderCommandLineEdit = QtWidgets.QLineEdit(self.uiSettingsGroupBox)
|
||||
self.uiCaptureReaderCommandLineEdit.setObjectName("uiCaptureReaderCommandLineEdit")
|
||||
self.gridLayout.addWidget(self.uiCaptureReaderCommandLineEdit, 3, 0, 1, 2)
|
||||
self.verticalLayout.addWidget(self.uiSettingsGroupBox)
|
||||
self.horizontalLayout = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||
@@ -72,8 +72,8 @@ class Ui_PacketCapturePreferencesPageWidget(object):
|
||||
self.uiPreconfiguredCaptureReaderCommandLabel.setText(_translate("PacketCapturePreferencesPageWidget", "Preconfigured packet capture reader commands:"))
|
||||
self.uiPreconfiguredCaptureReaderCommandPushButton.setText(_translate("PacketCapturePreferencesPageWidget", "&Set"))
|
||||
self.uiCaptureReaderCommandLabel.setText(_translate("PacketCapturePreferencesPageWidget", "Packet capture reader command:"))
|
||||
self.uiCaptureReaderCommandLineEdit.setToolTip(_translate("PacketCapturePreferencesPageWidget", "<html><head/><body><p>Command line replacements:</p><p>%c = capture file (PCAP format)</p></body></html>"))
|
||||
self.uiAutoStartCheckBox.setText(_translate("PacketCapturePreferencesPageWidget", "Automatically start the packet capture application"))
|
||||
self.uiCaptureAnalyzerCommandLabel.setText(_translate("PacketCapturePreferencesPageWidget", "Packet capture analyzer command:"))
|
||||
self.uiCaptureReaderCommandLineEdit.setToolTip(_translate("PacketCapturePreferencesPageWidget", "<html><head/><body><p>Command line replacements:</p><p>%c = capture file (PCAP format)</p></body></html>"))
|
||||
self.uiRestoreDefaultsPushButton.setText(_translate("PacketCapturePreferencesPageWidget", "Restore defaults"))
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>718</width>
|
||||
<height>626</height>
|
||||
<width>610</width>
|
||||
<height>700</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -16,7 +16,7 @@
|
||||
<property name="modal">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
@@ -85,36 +85,36 @@
|
||||
<property name="title">
|
||||
<string>Symbols</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="uiBuiltinSymbolOnlyCheckBox">
|
||||
<property name="text">
|
||||
<string>Show only built-in symbols</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="uiSearchLabel">
|
||||
<property name="text">
|
||||
<string>Filter:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="uiSearchLineEdit"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListWidget" name="uiSymbolListWidget">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QTreeWidget" name="uiSymbolTreeWidget">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>300</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="indentation">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<attribute name="headerVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string notr="true">1</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="uiSearchLineEdit"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="uiSearchLabel">
|
||||
<property name="text">
|
||||
<string>Filter:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
||||
@@ -11,10 +11,10 @@ from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
class Ui_SymbolSelectionDialog(object):
|
||||
def setupUi(self, SymbolSelectionDialog):
|
||||
SymbolSelectionDialog.setObjectName("SymbolSelectionDialog")
|
||||
SymbolSelectionDialog.resize(718, 626)
|
||||
SymbolSelectionDialog.resize(610, 700)
|
||||
SymbolSelectionDialog.setModal(True)
|
||||
self.verticalLayout_2 = QtWidgets.QVBoxLayout(SymbolSelectionDialog)
|
||||
self.verticalLayout_2.setObjectName("verticalLayout_2")
|
||||
self.verticalLayout = QtWidgets.QVBoxLayout(SymbolSelectionDialog)
|
||||
self.verticalLayout.setObjectName("verticalLayout")
|
||||
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
|
||||
self.uiCustomSymbolRadioButton = QtWidgets.QRadioButton(SymbolSelectionDialog)
|
||||
@@ -26,7 +26,7 @@ class Ui_SymbolSelectionDialog(object):
|
||||
self.horizontalLayout_2.addWidget(self.uiBuiltInSymbolRadioButton)
|
||||
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
self.horizontalLayout_2.addItem(spacerItem)
|
||||
self.verticalLayout_2.addLayout(self.horizontalLayout_2)
|
||||
self.verticalLayout.addLayout(self.horizontalLayout_2)
|
||||
self.uiCustomSymbolGroupBox = QtWidgets.QGroupBox(SymbolSelectionDialog)
|
||||
self.uiCustomSymbolGroupBox.setObjectName("uiCustomSymbolGroupBox")
|
||||
self.gridLayout = QtWidgets.QGridLayout(self.uiCustomSymbolGroupBox)
|
||||
@@ -41,28 +41,25 @@ class Ui_SymbolSelectionDialog(object):
|
||||
self.uiSymbolLabel = QtWidgets.QLabel(self.uiCustomSymbolGroupBox)
|
||||
self.uiSymbolLabel.setObjectName("uiSymbolLabel")
|
||||
self.gridLayout.addWidget(self.uiSymbolLabel, 0, 0, 1, 1)
|
||||
self.verticalLayout_2.addWidget(self.uiCustomSymbolGroupBox)
|
||||
self.verticalLayout.addWidget(self.uiCustomSymbolGroupBox)
|
||||
self.uiBuiltInGroupBox = QtWidgets.QGroupBox(SymbolSelectionDialog)
|
||||
self.uiBuiltInGroupBox.setObjectName("uiBuiltInGroupBox")
|
||||
self.verticalLayout = QtWidgets.QVBoxLayout(self.uiBuiltInGroupBox)
|
||||
self.verticalLayout.setObjectName("verticalLayout")
|
||||
self.uiBuiltinSymbolOnlyCheckBox = QtWidgets.QCheckBox(self.uiBuiltInGroupBox)
|
||||
self.uiBuiltinSymbolOnlyCheckBox.setObjectName("uiBuiltinSymbolOnlyCheckBox")
|
||||
self.verticalLayout.addWidget(self.uiBuiltinSymbolOnlyCheckBox)
|
||||
self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
|
||||
self.uiSearchLabel = QtWidgets.QLabel(self.uiBuiltInGroupBox)
|
||||
self.uiSearchLabel.setObjectName("uiSearchLabel")
|
||||
self.horizontalLayout_3.addWidget(self.uiSearchLabel)
|
||||
self.gridLayout_2 = QtWidgets.QGridLayout(self.uiBuiltInGroupBox)
|
||||
self.gridLayout_2.setObjectName("gridLayout_2")
|
||||
self.uiSymbolTreeWidget = QtWidgets.QTreeWidget(self.uiBuiltInGroupBox)
|
||||
self.uiSymbolTreeWidget.setMinimumSize(QtCore.QSize(0, 300))
|
||||
self.uiSymbolTreeWidget.setIndentation(10)
|
||||
self.uiSymbolTreeWidget.setObjectName("uiSymbolTreeWidget")
|
||||
self.uiSymbolTreeWidget.headerItem().setText(0, "1")
|
||||
self.uiSymbolTreeWidget.header().setVisible(False)
|
||||
self.gridLayout_2.addWidget(self.uiSymbolTreeWidget, 1, 0, 1, 2)
|
||||
self.uiSearchLineEdit = QtWidgets.QLineEdit(self.uiBuiltInGroupBox)
|
||||
self.uiSearchLineEdit.setObjectName("uiSearchLineEdit")
|
||||
self.horizontalLayout_3.addWidget(self.uiSearchLineEdit)
|
||||
self.verticalLayout.addLayout(self.horizontalLayout_3)
|
||||
self.uiSymbolListWidget = QtWidgets.QListWidget(self.uiBuiltInGroupBox)
|
||||
self.uiSymbolListWidget.setMinimumSize(QtCore.QSize(0, 300))
|
||||
self.uiSymbolListWidget.setObjectName("uiSymbolListWidget")
|
||||
self.verticalLayout.addWidget(self.uiSymbolListWidget)
|
||||
self.verticalLayout_2.addWidget(self.uiBuiltInGroupBox)
|
||||
self.gridLayout_2.addWidget(self.uiSearchLineEdit, 0, 1, 1, 1)
|
||||
self.uiSearchLabel = QtWidgets.QLabel(self.uiBuiltInGroupBox)
|
||||
self.uiSearchLabel.setObjectName("uiSearchLabel")
|
||||
self.gridLayout_2.addWidget(self.uiSearchLabel, 0, 0, 1, 1)
|
||||
self.verticalLayout.addWidget(self.uiBuiltInGroupBox)
|
||||
self.horizontalLayout = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
@@ -72,7 +69,7 @@ class Ui_SymbolSelectionDialog(object):
|
||||
self.uiButtonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Apply|QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
|
||||
self.uiButtonBox.setObjectName("uiButtonBox")
|
||||
self.horizontalLayout.addWidget(self.uiButtonBox)
|
||||
self.verticalLayout_2.addLayout(self.horizontalLayout)
|
||||
self.verticalLayout.addLayout(self.horizontalLayout)
|
||||
self.uiBuiltInGroupBox.raise_()
|
||||
self.uiCustomSymbolGroupBox.raise_()
|
||||
|
||||
@@ -90,7 +87,6 @@ class Ui_SymbolSelectionDialog(object):
|
||||
self.uiSymbolToolButton.setText(_translate("SymbolSelectionDialog", "&Browse..."))
|
||||
self.uiSymbolLabel.setText(_translate("SymbolSelectionDialog", "Path:"))
|
||||
self.uiBuiltInGroupBox.setTitle(_translate("SymbolSelectionDialog", "Symbols"))
|
||||
self.uiBuiltinSymbolOnlyCheckBox.setText(_translate("SymbolSelectionDialog", "Show only built-in symbols"))
|
||||
self.uiSearchLabel.setText(_translate("SymbolSelectionDialog", "Filter:"))
|
||||
|
||||
from . import resources_rc
|
||||
|
||||
Reference in New Issue
Block a user