New python supervision (#2863)
@@ -11,7 +11,7 @@ env['PAPARAZZI_HOME'] = PAPARAZZI_HOME
|
||||
env['PAPARAZZI_SRC'] = PAPARAZZI_SRC
|
||||
|
||||
if len(sys.argv) > 1 and sys.argv[1] == "-python":
|
||||
path = os.path.normpath(os.path.join(dirname, 'sw', 'supervision', 'python', 'main.py'))
|
||||
path = os.path.normpath(os.path.join(dirname, 'sw', 'supervision', 'python', 'paparazzicenter.py'))
|
||||
os.execve(path, sys.argv, env)
|
||||
else:
|
||||
path = os.path.normpath(os.path.join(dirname, 'sw', 'supervision', 'paparazzicenter'))
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
<!ELEMENT cache (system|data)*>
|
||||
<!ELEMENT system (window|filters)*>
|
||||
<!ELEMENT window (x|y|width|height)*>
|
||||
<!ELEMENT x (#PCDATA)>
|
||||
<!ATTLIST x
|
||||
value CDATA #REQUIRED>
|
||||
<!ELEMENT y (#PCDATA)>
|
||||
<!ATTLIST y
|
||||
value CDATA #REQUIRED>
|
||||
<!ELEMENT width (#PCDATA)>
|
||||
<!ATTLIST width
|
||||
value CDATA #REQUIRED>
|
||||
<!ELEMENT height (#PCDATA)>
|
||||
<!ATTLIST height
|
||||
value CDATA #REQUIRED>
|
||||
<!ELEMENT filters (level|info|warning|error)*>
|
||||
<!ELEMENT level (#PCDATA)>
|
||||
<!ATTLIST level
|
||||
value CDATA #REQUIRED>
|
||||
<!ELEMENT info (#PCDATA)>
|
||||
<!ATTLIST info
|
||||
value CDATA #REQUIRED>
|
||||
<!ELEMENT warning (#PCDATA)>
|
||||
<!ATTLIST warning
|
||||
value CDATA #REQUIRED>
|
||||
<!ELEMENT error (#PCDATA)>
|
||||
<!ATTLIST error
|
||||
value CDATA #REQUIRED>
|
||||
<!ELEMENT data (set|config|target|device|session)*>
|
||||
<!ELEMENT set (#PCDATA)>
|
||||
<!ATTLIST set
|
||||
value CDATA #REQUIRED>
|
||||
<!ELEMENT config (#PCDATA)>
|
||||
<!ATTLIST config
|
||||
value CDATA #REQUIRED>
|
||||
<!ELEMENT target (#PCDATA)>
|
||||
<!ATTLIST target
|
||||
value CDATA #REQUIRED>
|
||||
<!ELEMENT device (#PCDATA)>
|
||||
<!ATTLIST device
|
||||
value CDATA #REQUIRED>
|
||||
<!ELEMENT session (#PCDATA)>
|
||||
<!ATTLIST session
|
||||
value CDATA #REQUIRED>
|
||||
@@ -0,0 +1,18 @@
|
||||
# Copyright (C) 2008-2022 The Paparazzi Team
|
||||
# released under GNU GPLv2 or later. See COPYING file.
|
||||
all:
|
||||
mkdir -p generated
|
||||
pyuic5 ui/conf_header.ui -o generated/ui_conf_header.py
|
||||
pyuic5 ui/conf_item.ui -o generated/ui_conf_item.py
|
||||
pyuic5 ui/build.ui -o generated/ui_build.py
|
||||
pyuic5 ui/configuration_panel.ui -o generated/ui_configuration_panel.py
|
||||
pyuic5 ui/new_ac_dialog.ui -o generated/ui_new_ac_dialog.py
|
||||
pyuic5 ui/session.ui -o generated/ui_session.py
|
||||
pyuic5 ui/program.ui -o generated/ui_program.py
|
||||
pyuic5 ui/operation_panel.ui -o generated/ui_operation_panel.py
|
||||
pyuic5 ui/console.ui -o generated/ui_console.py
|
||||
pyuic5 ui/tools_list.ui -o generated/ui_tools_list.py
|
||||
pyuic5 ui/app_settings.ui -o generated/ui_app_settings.py
|
||||
|
||||
clean:
|
||||
rm -r generated
|
||||
@@ -1,69 +0,0 @@
|
||||
###############################################################################
|
||||
# Welcome in the future Paparazzi Center ! #
|
||||
###############################################################################
|
||||
|
||||
1) Run instructions :
|
||||
|
||||
To run the new Paparazzi Center, you need :
|
||||
|
||||
> A Linux or IOS system
|
||||
|
||||
> A correctly installed version of Paparazzi UAV software
|
||||
|
||||
> Python 3.4 (install package 'python3')
|
||||
|
||||
> PyQt5 (install package 'python3-pyqt5')
|
||||
|
||||
First "git pull" my part of code or copy the current "./sw/supervision/python"
|
||||
version into your own "./sw/supervision" directory. No installation nor
|
||||
compilation is needed.
|
||||
Then, make the 'main.py' file executable ('chmod +x main.py') and launch the
|
||||
program in a terminal ('./main.py') or from the paparazzi launcher (soon).
|
||||
|
||||
###############################################################################
|
||||
|
||||
2) Feedback :
|
||||
|
||||
I'm an intern student at the ENAC and my mission is to reconceive the Paparazzi
|
||||
Center in Python/Qt to make it more intuitive and 'maintainable' (that can
|
||||
evolve easily). So I'd really like to have your feeling about my propositions !
|
||||
|
||||
If you have any question or comment about it, please contact me by
|
||||
Github (my pseudo is 'floienac' and I use Gitter) or by mail
|
||||
('f.bitard@gmail.com').
|
||||
I'd be glad to be criticized, especially if you're directly concerned as a
|
||||
final user or a developer of Paparazzi UAV.
|
||||
|
||||
Thanks by advance :)
|
||||
|
||||
Florian BITARD - intern student at the ENAC's drones lab
|
||||
(February to June 2016)
|
||||
|
||||
http://wiki.paparazziuav.org/wiki/Paparazzi_Center/Evolutions
|
||||
###############################################################################
|
||||
|
||||
3) GNU License :
|
||||
|
||||
As this new Paparazzi Center is a free and open source software part, feel
|
||||
free to correct bugs, improve the functions and add new ones to it.
|
||||
|
||||
# Paparazzi center utilities
|
||||
#
|
||||
# Copyright (C) 2016 ENAC, Florian BITARD (intern student)
|
||||
#
|
||||
# This file is part of paparazzi.
|
||||
#
|
||||
# paparazzi 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 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
# Boston, MA 02111-1307, USA.
|
||||
@@ -0,0 +1,10 @@
|
||||
# Paparazzi Center
|
||||
|
||||
The Paparazzi Center is the home application for Paparazzi UAV.
|
||||
|
||||
|
||||
|
||||
Install the package `pyqt5-dev-tools` and run `make` to generate python ui files.
|
||||
|
||||
Install python dependencies:
|
||||
`python3 -m pip install -r requirements.txt`
|
||||
@@ -0,0 +1,28 @@
|
||||
# Copyright (C) 2008-2022 The Paparazzi Team
|
||||
# released under GNU GPLv2 or later. See COPYING file.
|
||||
from PyQt5.QtWidgets import *
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
from generated.ui_app_settings import Ui_AppSettingsDialog
|
||||
import utils
|
||||
|
||||
|
||||
class AppSettings(QDialog, Ui_AppSettingsDialog):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
QWidget.__init__(self, parent=parent)
|
||||
self.setupUi(self)
|
||||
settings = utils.get_settings()
|
||||
self.text_editor_edit.setText(settings.value("text_editor", "", str))
|
||||
self.terminal_emulator_edit.setText(settings.value("terminal_emulator", "", str))
|
||||
self.keep_changes_checkbox.setChecked(settings.value("always_keep_changes", False, bool))
|
||||
self.finished.connect(self.handle_finished)
|
||||
|
||||
def handle_finished(self, result):
|
||||
if result:
|
||||
settings = utils.get_settings()
|
||||
text_editor = self.text_editor_edit.text()
|
||||
settings.setValue("text_editor", text_editor)
|
||||
terminal_emulator = self.terminal_emulator_edit.text()
|
||||
settings.setValue("terminal_emulator", terminal_emulator)
|
||||
keep_changes = self.keep_changes_checkbox.isChecked()
|
||||
settings.setValue("always_keep_changes", keep_changes)
|
||||
@@ -0,0 +1,119 @@
|
||||
# Copyright (C) 2008-2022 The Paparazzi Team
|
||||
# released under GNU GPLv2 or later. See COPYING file.
|
||||
from PyQt5.QtWidgets import *
|
||||
from PyQt5 import QtCore
|
||||
from generated.ui_build import Ui_Build
|
||||
import lxml.etree as ET
|
||||
import os
|
||||
import utils
|
||||
from conf import Aircraft, Conf
|
||||
from typing import List, Dict
|
||||
from dataclasses import dataclass, field
|
||||
import re
|
||||
|
||||
|
||||
@dataclass
|
||||
class FlashMode:
|
||||
name: str
|
||||
vars: Dict[str, str] = field(default_factory=dict)
|
||||
boards: List[str] = field(default_factory=list)
|
||||
|
||||
def match(self, board):
|
||||
for regex in self.boards:
|
||||
if re.match(regex, board) is not None:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class BuildWidget(Ui_Build, QWidget):
|
||||
|
||||
spawn_program = QtCore.pyqtSignal(str, list, str)
|
||||
|
||||
def __init__(self, parent=None):
|
||||
QWidget.__init__(self, parent=parent)
|
||||
self.setupUi(self)
|
||||
# uic.loadUi("ui/build.ui", self)
|
||||
self.ac: Aircraft = None
|
||||
self.conf: Conf = None # to save conf before building
|
||||
self.flash_modes: List[FlashMode] = self.parse_flash_modes()
|
||||
self.build_button.clicked.connect(self.build)
|
||||
self.clean_button.clicked.connect(self.clean)
|
||||
self.flash_button.clicked.connect(self.flash)
|
||||
self.target_combo.currentTextChanged.connect(self.update_flash_mode)
|
||||
|
||||
def set_conf(self, conf: Conf):
|
||||
self.conf = conf
|
||||
|
||||
@staticmethod
|
||||
def parse_flash_modes() -> List[FlashMode]:
|
||||
flash_xml = ET.parse(os.path.join(utils.CONF_DIR, "flash_modes.xml"))
|
||||
modes = []
|
||||
for xml_mode in flash_xml.getroot().findall("mode"):
|
||||
mode_name = xml_mode.get("name")
|
||||
vars = {}
|
||||
for xml_var in xml_mode.findall("variable"):
|
||||
var_name = xml_var.get("name")
|
||||
var_value = xml_var.get("value")
|
||||
vars[var_name] = var_value
|
||||
mode = FlashMode(mode_name, vars)
|
||||
for xml_board in xml_mode.find("boards").findall("board"):
|
||||
board = xml_board.get("name")
|
||||
mode.boards.append(board)
|
||||
modes.append(mode)
|
||||
return modes
|
||||
|
||||
def get_flash_modes(self, board):
|
||||
modes = filter(lambda fm: fm.match(board), self.flash_modes)
|
||||
mode_names = [mode.name for mode in modes]
|
||||
return mode_names
|
||||
|
||||
def update_targets(self, ac: Aircraft):
|
||||
self.ac = ac
|
||||
self.target_combo.clear()
|
||||
|
||||
for target in ac.boards.keys():
|
||||
self.target_combo.addItem(target)
|
||||
|
||||
def update_flash_mode(self, target):
|
||||
self.device_combo.clear()
|
||||
if target != "":
|
||||
self.device_combo.addItem("Default")
|
||||
board = self.ac.boards[target]
|
||||
flash_modes = self.get_flash_modes(board)
|
||||
self.device_combo.addItems(flash_modes)
|
||||
|
||||
def get_current_target(self) -> str:
|
||||
return self.target_combo.currentText()
|
||||
|
||||
def build(self):
|
||||
target = self.target_combo.currentText()
|
||||
cmd = ["make", "-C", utils.PAPARAZZI_HOME, "-f", "Makefile.ac",
|
||||
"AIRCRAFT={}".format(self.ac.name), "{}.compile".format(target)]
|
||||
if self.print_config_checkbox.isChecked():
|
||||
cmd.append("PRINT_CONFIG=1")
|
||||
shortname = "Build {}".format(self.ac.name)
|
||||
self.conf.save(False)
|
||||
self.spawn_program.emit(shortname, cmd, None)
|
||||
|
||||
def clean(self):
|
||||
cmd = ["make", "-C", utils.PAPARAZZI_HOME, "-f", "Makefile.ac",
|
||||
"AIRCRAFT={}".format(self.ac.name), "clean_ac"]
|
||||
shortname = "Clean {}".format(self.ac.name)
|
||||
self.spawn_program.emit(shortname, cmd, None)
|
||||
|
||||
def flash(self):
|
||||
target = self.target_combo.currentText()
|
||||
vars = []
|
||||
flash_mode = self.device_combo.currentText()
|
||||
if flash_mode != "Default":
|
||||
for mode in self.flash_modes:
|
||||
if mode.name == flash_mode:
|
||||
vars = ["{}={}".format(var_name, var_value) for (var_name, var_value) in mode.vars.items()]
|
||||
break
|
||||
else:
|
||||
raise Exception("Flash mode {} not found!".format(flash_mode))
|
||||
cmd = ["make", "-C", utils.PAPARAZZI_HOME, "-f", "Makefile.ac",
|
||||
"AIRCRAFT={}".format(self.ac.name)] + vars + ["{}.upload".format(target)]
|
||||
shortname = "Flash {}".format(self.ac.name)
|
||||
self.spawn_program.emit(shortname, cmd, None)
|
||||
|
||||
@@ -0,0 +1,247 @@
|
||||
from dataclasses import dataclass, field
|
||||
from typing import List, Dict
|
||||
import lxml.etree as ET
|
||||
import os
|
||||
import subprocess
|
||||
import utils
|
||||
|
||||
MOD_DEP = os.path.join(utils.PAPARAZZI_SRC, "sw", "tools", "generators", "dump_modules_list.out")
|
||||
CONF = os.path.join(utils.PAPARAZZI_HOME, "conf", "conf.xml")
|
||||
|
||||
|
||||
@dataclass
|
||||
class Setting:
|
||||
name: str
|
||||
enabled: bool
|
||||
|
||||
def __str__(self):
|
||||
if self.enabled:
|
||||
return self.name
|
||||
else:
|
||||
return f"[{self.name}]"
|
||||
|
||||
|
||||
@dataclass
|
||||
class Aircraft:
|
||||
name: str = ""
|
||||
ac_id: int = 0
|
||||
airframe: str = ""
|
||||
radio: str = ""
|
||||
telemetry: str = ""
|
||||
flight_plan: str = ""
|
||||
gui_color: str = "red"
|
||||
settings: List[Setting] = field(default_factory=list)
|
||||
settings_modules: List[Setting] = field(default_factory=list)
|
||||
boards: Dict[str, str] = field(default_factory=dict, init=False) # {target: board}
|
||||
|
||||
def __post_init__(self):
|
||||
self.update_targets()
|
||||
|
||||
def get_color(self) -> str:
|
||||
if self.gui_color.startswith("#"):
|
||||
r = self.gui_color[1:3]
|
||||
g = self.gui_color[5:7]
|
||||
b = self.gui_color[9:11]
|
||||
color = "#{}{}{}".format(r, g, b)
|
||||
return color
|
||||
|
||||
else:
|
||||
return self.gui_color
|
||||
|
||||
def set_color(self, color: str):
|
||||
if color.startswith("#"):
|
||||
r = color[1:3]
|
||||
g = color[3:5]
|
||||
b = color[5:7]
|
||||
self.gui_color = "#{}00{}00{}00".format(r, g, b)
|
||||
else:
|
||||
self.gui_color = color
|
||||
|
||||
def update(self):
|
||||
self.update_targets()
|
||||
return self.update_settings()
|
||||
|
||||
def update_settings(self):
|
||||
completed = subprocess.run([MOD_DEP, "-ac", self.name, "-af", self.airframe, "-fp", self.flight_plan],
|
||||
capture_output=True)
|
||||
if completed.returncode == 0:
|
||||
def remove_prefix(s):
|
||||
if s.startswith(utils.CONF_DIR):
|
||||
return s[len(utils.CONF_DIR):]
|
||||
else:
|
||||
return s
|
||||
|
||||
def make_setting(m):
|
||||
setting = Setting(m, True)
|
||||
for s in self.settings_modules:
|
||||
if m == s.name and not s.enabled:
|
||||
setting.enabled = False
|
||||
return setting
|
||||
|
||||
new_settings_modules = []
|
||||
for module_path in completed.stdout.decode().strip().split():
|
||||
module = remove_prefix(module_path)
|
||||
xml = ET.parse(module_path)
|
||||
for xml_setting in xml.getroot().findall("settings"):
|
||||
name = xml_setting.get("name")
|
||||
if name is None:
|
||||
txt = module
|
||||
else:
|
||||
txt = "{}~{}~".format(module, name)
|
||||
setting = make_setting(txt)
|
||||
new_settings_modules.append(setting)
|
||||
|
||||
self.settings_modules = new_settings_modules
|
||||
|
||||
return completed.returncode, completed.stderr
|
||||
|
||||
def to_xml(self) -> ET.Element:
|
||||
xml = ET.Element("aircraft")
|
||||
xml.set("name", self.name)
|
||||
xml.set("ac_id", str(self.ac_id))
|
||||
xml.set("airframe", self.airframe)
|
||||
xml.set("radio", self.radio)
|
||||
xml.set("telemetry", self.telemetry)
|
||||
xml.set("flight_plan", self.flight_plan)
|
||||
settings_modules = " ".join(str(setting) for setting in self.settings_modules)
|
||||
settings = " ".join(str(setting) for setting in self.settings)
|
||||
xml.set("settings", settings)
|
||||
xml.set("settings_modules", settings_modules)
|
||||
xml.set("gui_color", self.gui_color)
|
||||
return xml
|
||||
|
||||
def to_string(self):
|
||||
xml = " <aircraft\n"
|
||||
xml += " name=\"{}\"\n".format(self.name)
|
||||
xml += " ac_id=\"{}\"\n".format(self.ac_id)
|
||||
xml += " airframe=\"{}\"\n".format(self.airframe)
|
||||
xml += " radio=\"{}\"\n".format(self.radio)
|
||||
xml += " telemetry=\"{}\"\n".format(self.telemetry)
|
||||
xml += " flight_plan=\"{}\"\n".format(self.flight_plan)
|
||||
xml += " settings=\"{}\"\n".format(" ".join(str(setting) for setting in self.settings))
|
||||
xml += " settings_modules=\"{}\"\n".format(" ".join(str(setting) for setting in self.settings_modules))
|
||||
xml += " gui_color=\"{}\"\n".format(self.gui_color)
|
||||
xml += " />"
|
||||
return xml
|
||||
|
||||
def update_targets(self):
|
||||
self.boards = {}
|
||||
try:
|
||||
airframe_xml = ET.parse(os.path.join(utils.CONF_DIR, self.airframe))
|
||||
for firmware_xml in airframe_xml.getroot().findall("firmware"):
|
||||
for target_xml in firmware_xml.findall("target"):
|
||||
target = target_xml.get("name")
|
||||
board = target_xml.get("board")
|
||||
self.boards[target] = board
|
||||
except OSError as e:
|
||||
print("OSError, file {} probably not found!".format(self.airframe))
|
||||
print(e)
|
||||
except ET.XMLSyntaxError as e:
|
||||
print("XMLSyntaxError, file {} is illformed !".format(self.airframe))
|
||||
print(e)
|
||||
|
||||
|
||||
class Conf:
|
||||
def __init__(self, file: str):
|
||||
self.file = file # type: str
|
||||
self.aircrafts = [] # type: List[Aircraft]
|
||||
xml = ET.parse(os.path.join(utils.CONF_DIR, file))
|
||||
self.parse(xml)
|
||||
self.tree_orig = self.to_xml_tree()
|
||||
|
||||
def parse(self, conf_tree):
|
||||
self.aircrafts.clear()
|
||||
for ac_xml in conf_tree.getroot().findall("aircraft"):
|
||||
name = ac_xml.attrib["name"]
|
||||
ac_id = int(ac_xml.attrib["ac_id"])
|
||||
airframe = ac_xml.attrib["airframe"]
|
||||
radio = ac_xml.attrib["radio"]
|
||||
telemetry = ac_xml.attrib["telemetry"]
|
||||
flight_plan = ac_xml.attrib["flight_plan"]
|
||||
gui_color = ac_xml.attrib["gui_color"]
|
||||
|
||||
def make_setting(txt):
|
||||
name = txt.strip('[]')
|
||||
enabled = True if len(name) == len(txt) else False
|
||||
return Setting(name, enabled)
|
||||
|
||||
settings = list(map(make_setting, ac_xml.attrib["settings"].split()))
|
||||
settings_modules = list(map(make_setting, ac_xml.attrib["settings_modules"].split()))
|
||||
ac = Aircraft(name, ac_id, airframe, radio, telemetry, flight_plan,
|
||||
gui_color, settings, settings_modules)
|
||||
self.aircrafts.append(ac)
|
||||
|
||||
def __getitem__(self, item):
|
||||
for ac in self.aircrafts:
|
||||
if (isinstance(item, int) and item == ac.ac_id) or (isinstance(item, str) and item == ac.name):
|
||||
return ac
|
||||
|
||||
def __len__(self):
|
||||
return len(self.aircrafts)
|
||||
|
||||
def remove(self, ac: Aircraft):
|
||||
self.aircrafts.remove(ac)
|
||||
|
||||
def append(self, ac: Aircraft):
|
||||
self.aircrafts.append(ac)
|
||||
|
||||
def get_all(self, id):
|
||||
acs = []
|
||||
for ac in self.aircrafts:
|
||||
if id == ac.ac_id or id == ac.name:
|
||||
acs.append(ac)
|
||||
return acs
|
||||
|
||||
def get_free_id(self):
|
||||
ids = [ac.ac_id for ac in self.aircrafts]
|
||||
for i in range(1, 256):
|
||||
if i not in ids:
|
||||
return i
|
||||
|
||||
def to_xml_tree(self):
|
||||
conf_xml = ET.Element("conf")
|
||||
for ac in self.aircrafts:
|
||||
ac_xml = ac.to_xml()
|
||||
conf_xml.append(ac_xml)
|
||||
tree = ET.ElementTree(conf_xml)
|
||||
return tree
|
||||
|
||||
def save(self, refresh_orig=True):
|
||||
conf_path = os.path.join(utils.CONF_DIR, self.file)
|
||||
with open(conf_path, "w") as fic:
|
||||
fic.write(self.to_string())
|
||||
print("conf saved to {}".format(conf_path))
|
||||
if refresh_orig:
|
||||
self.tree_orig = self.to_xml_tree()
|
||||
|
||||
def restore_conf(self):
|
||||
self.parse(self.tree_orig)
|
||||
|
||||
def to_string(self):
|
||||
xml = "<conf>\n"
|
||||
xml += "\n".join([ac.to_string() for ac in self.aircrafts])
|
||||
xml += "\n</conf>\n"
|
||||
return xml
|
||||
|
||||
@staticmethod
|
||||
def get_current_conf():
|
||||
if os.path.islink(CONF):
|
||||
#return os.path.realpath(CONF)
|
||||
return os.readlink(CONF)
|
||||
else:
|
||||
return CONF
|
||||
|
||||
@staticmethod
|
||||
def set_current_conf(conf: str):
|
||||
if not os.path.islink(CONF):
|
||||
print("your conf.xml is not a link, it will be overwritten.")
|
||||
try:
|
||||
os.symlink(conf, CONF)
|
||||
except OSError as e:
|
||||
os.remove(CONF)
|
||||
os.symlink(conf, CONF)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import os.path
|
||||
|
||||
from generated.ui_conf_item import Ui_FileConf
|
||||
from PyQt5.QtWidgets import *
|
||||
from PyQt5 import QtCore
|
||||
import utils
|
||||
|
||||
|
||||
class ConfFileWidget(QWidget, Ui_FileConf):
|
||||
|
||||
file_changed = QtCore.pyqtSignal()
|
||||
edit_alt = QtCore.pyqtSignal(str)
|
||||
|
||||
def __init__(self, title: str, parent=None):
|
||||
QWidget.__init__(self, parent=parent)
|
||||
self.nature = title.lower().replace(" ", "_") + "s"
|
||||
self.path = None
|
||||
self.setupUi(self)
|
||||
self.edit_alt_button.hide()
|
||||
self.title_label.setText(title)
|
||||
self.edit_button.clicked.connect(self.edit)
|
||||
self.select_button.clicked.connect(self.select_file)
|
||||
self.edit_alt_button.clicked.connect(lambda: self.edit_alt.emit(self.path_label.text()))
|
||||
|
||||
def set_path(self, path):
|
||||
self.path = path
|
||||
self.path_label.setText(path)
|
||||
|
||||
def edit(self):
|
||||
if self.path != "":
|
||||
utils.edit_file(self.path)
|
||||
|
||||
def select_file(self):
|
||||
base_path = os.path.join(utils.CONF_DIR, self.nature)
|
||||
print(base_path)
|
||||
(path, _) = QFileDialog().getOpenFileName(self, "Select {} file".format(self.nature),
|
||||
base_path, "Xml (*.xml)")
|
||||
if path != "":
|
||||
self.path = os.path.relpath(path, utils.CONF_DIR)
|
||||
self.path_label.setText(self.path)
|
||||
self.file_changed.emit()
|
||||
@@ -0,0 +1,62 @@
|
||||
from PyQt5.QtWidgets import *
|
||||
from PyQt5 import QtCore
|
||||
|
||||
import conf
|
||||
import utils
|
||||
from conf_file_widget import ConfFileWidget
|
||||
|
||||
|
||||
class ConfWidget(QWidget):
|
||||
|
||||
conf_changed = QtCore.pyqtSignal()
|
||||
setting_changed = QtCore.pyqtSignal()
|
||||
|
||||
def __init__(self, parent=None):
|
||||
QWidget.__init__(self, parent=parent)
|
||||
lay = QVBoxLayout(self)
|
||||
self.airframe = ConfFileWidget("Airframe", self)
|
||||
self.airframe.file_changed.connect(self.conf_changed)
|
||||
self.flight_plan = ConfFileWidget("Flight Plan", self)
|
||||
self.flight_plan.file_changed.connect(self.conf_changed)
|
||||
self.flight_plan.edit_alt_button.show()
|
||||
self.flight_plan.edit_alt_button.setText("Edit GCS")
|
||||
self.settings = QListWidget(self)
|
||||
self.radio = ConfFileWidget("Radio", self)
|
||||
self.radio.file_changed.connect(self.conf_changed)
|
||||
self.telemetry = ConfFileWidget("Telemetry", self)
|
||||
self.telemetry.file_changed.connect(self.conf_changed)
|
||||
self.settings.itemDoubleClicked.connect(self.edit_setting)
|
||||
self.settings.itemChanged.connect(self.setting_changed)
|
||||
|
||||
vb = QVBoxLayout()
|
||||
settings_label = QLabel("Settings", self)
|
||||
settings_label.setStyleSheet("font-weight: bold;")
|
||||
vb.addWidget(settings_label)
|
||||
vb.addWidget(self.settings)
|
||||
lay.addWidget(self.airframe)
|
||||
lay.addWidget(self.flight_plan)
|
||||
lay.addItem(vb)
|
||||
lay.addWidget(self.radio)
|
||||
lay.addWidget(self.telemetry)
|
||||
|
||||
def set_ac(self, ac: conf.Aircraft):
|
||||
self.airframe.set_path(ac.airframe)
|
||||
self.telemetry.set_path(ac.telemetry)
|
||||
self.radio.set_path(ac.radio)
|
||||
self.flight_plan.set_path(ac.flight_plan)
|
||||
self.settings.clear()
|
||||
for setting in ac.settings + ac.settings_modules:
|
||||
item = QListWidgetItem(setting.name)
|
||||
item.setCheckState(QtCore.Qt.Checked if setting.enabled else QtCore.Qt.Unchecked)
|
||||
self.settings.addItem(item)
|
||||
|
||||
def edit_setting(self, item: QListWidgetItem):
|
||||
utils.edit_file(item.text())
|
||||
|
||||
def reset(self):
|
||||
self.airframe.set_path("")
|
||||
self.flight_plan.set_path("")
|
||||
self.telemetry.set_path("")
|
||||
self.radio.set_path("")
|
||||
self.settings.clear()
|
||||
|
||||
@@ -0,0 +1,293 @@
|
||||
import os, sys, copy
|
||||
from PyQt5.QtWidgets import *
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
import utils
|
||||
from generated.ui_configuration_panel import Ui_ConfigurationPanel
|
||||
from generated.ui_new_ac_dialog import Ui_Dialog
|
||||
from program_widget import ProgramWidget
|
||||
from conf import *
|
||||
from programs_conf import parse_tools
|
||||
import subprocess
|
||||
|
||||
PAPARAZZI_SRC = os.getenv("PAPARAZZI_SRC")
|
||||
PAPARAZZI_HOME = os.getenv("PAPARAZZI_HOME", PAPARAZZI_SRC)
|
||||
lib_path = os.path.normpath(os.path.join(PAPARAZZI_SRC, 'sw', 'lib', 'python'))
|
||||
sys.path.append(lib_path)
|
||||
import paparazzi
|
||||
|
||||
# TODO make a setting ?
|
||||
REMOVE_PROGRAMS_FINISHED = True
|
||||
|
||||
|
||||
class ConfigurationPanel(QWidget, Ui_ConfigurationPanel):
|
||||
|
||||
msg_error = QtCore.pyqtSignal(str)
|
||||
clear_error = QtCore.pyqtSignal()
|
||||
ac_changed = QtCore.pyqtSignal(Aircraft)
|
||||
|
||||
def __init__(self, parent=None, *args, **kwargs):
|
||||
QWidget.__init__(self, parent=parent, *args, **kwargs)
|
||||
self.setupUi(self)
|
||||
self.console_widget.filter_widget.hide()
|
||||
self.conf = None # type: conf.Conf
|
||||
self.currentAC = None # type: str
|
||||
self.flight_plan_editor = None
|
||||
self.header.set_changed.connect(self.handle_set_changed)
|
||||
self.header.ac_changed.connect(self.update_ac)
|
||||
self.header.id_changed.connect(self.handle_id_changed)
|
||||
self.header.refresh_button.clicked.connect(self.refresh_ac)
|
||||
self.header.color_button.clicked.connect(self.change_color)
|
||||
self.header.save_button.clicked.connect(lambda: self.conf.save())
|
||||
self.addAction(self.save_conf_action)
|
||||
self.save_conf_action.triggered.connect(lambda: self.conf.save())
|
||||
self.conf_widget.conf_changed.connect(self.handle_conf_changed)
|
||||
self.conf_widget.setting_changed.connect(self.handle_setting_changed)
|
||||
self.conf_widget.flight_plan.edit_alt.connect(self.edit_flightplan_gcs)
|
||||
self.header.rename_action.triggered.connect(self.rename_ac)
|
||||
self.header.new_ac_action.triggered.connect(self.new_ac)
|
||||
self.header.duplicate_action.triggered.connect(self.duplicate_ac)
|
||||
self.header.remove_ac_action.triggered.connect(self.remove_ac)
|
||||
self.build_widget.spawn_program.connect(self.launch_program)
|
||||
|
||||
def init(self):
|
||||
sets = paparazzi.get_list_of_conf_files()
|
||||
settings = utils.get_settings()
|
||||
self.header.set_sets(sets, conf_init=Conf.get_current_conf())
|
||||
last_ac: QtCore.QVariant = settings.value("ui/last_AC", None, str)
|
||||
last_target: QtCore.QVariant = settings.value("ui/last_target", None, str)
|
||||
if last_ac is not None:
|
||||
self.header.ac_combo.setCurrentText(last_ac)
|
||||
if last_target is not None:
|
||||
self.build_widget.target_combo.setCurrentText(last_target)
|
||||
window_size: QtCore.QSize = settings.value("ui/window_size", QtCore.QSize(1000, 600), QtCore.QSize)
|
||||
lpw = settings.value("ui/left_pane_width", 100, int)
|
||||
self.splitter.setSizes([lpw, window_size.width() - lpw])
|
||||
|
||||
def handle_set_changed(self, conf_file):
|
||||
self.conf = Conf(conf_file)
|
||||
Conf.set_current_conf(conf_file)
|
||||
self.build_widget.set_conf(self.conf)
|
||||
acs = [ac.name for ac in self.conf.aircrafts]
|
||||
self.header.set_acs(acs)
|
||||
|
||||
def disable_sets(self):
|
||||
self.header.set_combo.setDisabled(True)
|
||||
|
||||
def enable_sets(self):
|
||||
self.header.set_combo.setDisabled(False)
|
||||
|
||||
def update_ac(self, ac_name):
|
||||
ac = self.conf[ac_name]
|
||||
if ac_name != "" and ac is not None:
|
||||
self.conf_widget.setDisabled(False)
|
||||
self.currentAC = ac_name
|
||||
status, stderr = ac.update()
|
||||
if status != 0:
|
||||
self.msg_error.emit(stderr.decode().strip())
|
||||
else:
|
||||
self.clear_error.emit()
|
||||
self.header.set_ac(ac)
|
||||
self.conf_widget.set_ac(ac)
|
||||
self.build_widget.update_targets(self.conf[ac_name])
|
||||
self.ac_changed.emit(self.conf[ac_name])
|
||||
else:
|
||||
# self.conf_widget.reset()
|
||||
self.conf_widget.setDisabled(True)
|
||||
|
||||
def get_current_ac(self) -> str:
|
||||
"""
|
||||
:return: name of the current AC
|
||||
"""
|
||||
return self.currentAC
|
||||
|
||||
def refresh_ac(self):
|
||||
self.update_ac(self.currentAC)
|
||||
|
||||
def handle_id_changed(self, id):
|
||||
self.conf[self.currentAC].ac_id = id
|
||||
if len(self.conf.get_all(id)) > 1:
|
||||
self.header.id_spinBox.setStyleSheet("background-color: red;")
|
||||
else:
|
||||
self.header.id_spinBox.setStyleSheet("background-color: white;")
|
||||
|
||||
def handle_setting_changed(self):
|
||||
def make_setting(item: QListWidgetItem):
|
||||
name = item.text()
|
||||
state = True if item.checkState() == QtCore.Qt.Checked else False
|
||||
return Setting(name, state)
|
||||
|
||||
modules, settings = [], []
|
||||
for i in range(self.conf_widget.settings.count()):
|
||||
item = self.conf_widget.settings.item(i)
|
||||
s = make_setting(item)
|
||||
if item.text().startswith("module"):
|
||||
modules.append(s)
|
||||
else:
|
||||
settings.append(s)
|
||||
|
||||
self.conf[self.currentAC].settings_modules = modules
|
||||
self.conf[self.currentAC].settings = settings
|
||||
# should we save each time a tiny change is made ? very inefficient !
|
||||
# self.conf.save()
|
||||
|
||||
def handle_conf_changed(self):
|
||||
self.conf[self.currentAC].airframe = self.conf_widget.airframe.path
|
||||
self.conf[self.currentAC].flight_plan = self.conf_widget.flight_plan.path
|
||||
self.conf[self.currentAC].radio = self.conf_widget.radio.path
|
||||
self.conf[self.currentAC].telemetry = self.conf_widget.telemetry.path
|
||||
# reload settings modules, and update UI
|
||||
self.update_ac(self.currentAC)
|
||||
|
||||
def add_ac(self, ac: Aircraft):
|
||||
self.conf.append(ac)
|
||||
self.header.add_ac(ac.name)
|
||||
|
||||
def new_ac(self):
|
||||
orig = Aircraft()
|
||||
self.create_ac(orig)
|
||||
|
||||
def remove_ac(self):
|
||||
button = QMessageBox.question(self, "Remove AC", "Remove AC <strong>{}</strong>?".format(self.currentAC))
|
||||
if button == QMessageBox.Yes:
|
||||
self.conf.remove(self.conf[self.currentAC])
|
||||
self.header.remove_current()
|
||||
|
||||
def duplicate_ac(self):
|
||||
orig = self.conf[self.currentAC]
|
||||
self.create_ac(orig)
|
||||
|
||||
def create_ac(self, orig):
|
||||
ui_dialog = Ui_Dialog()
|
||||
dialog = QDialog(parent=self)
|
||||
ui_dialog.setupUi(dialog)
|
||||
|
||||
def verify():
|
||||
ok = True
|
||||
id = ui_dialog.id_spinbox.value()
|
||||
name = ui_dialog.name_edit.text()
|
||||
if self.conf[id] is not None or id == 0:
|
||||
ui_dialog.id_spinbox.setStyleSheet("background-color: red;")
|
||||
ok = False
|
||||
else:
|
||||
ui_dialog.id_spinbox.setStyleSheet("")
|
||||
|
||||
if self.conf[name] is not None or name == "":
|
||||
ui_dialog.name_edit.setStyleSheet("background-color: red;")
|
||||
ok = False
|
||||
else:
|
||||
ui_dialog.name_edit.setStyleSheet("")
|
||||
|
||||
return ok
|
||||
|
||||
def accept():
|
||||
if verify():
|
||||
dialog.accept()
|
||||
|
||||
def reject():
|
||||
dialog.reject()
|
||||
|
||||
def duplicate(result):
|
||||
if result:
|
||||
new_ac = copy.deepcopy(orig)
|
||||
name = ui_dialog.name_edit.text()
|
||||
ac_id = ui_dialog.id_spinbox.value()
|
||||
new_ac.name = name
|
||||
new_ac.ac_id = ac_id
|
||||
self.add_ac(new_ac)
|
||||
self.header.set_current(name)
|
||||
|
||||
ui_dialog.id_spinbox.setValue(self.conf.get_free_id())
|
||||
ui_dialog.buttonBox.accepted.connect(accept)
|
||||
ui_dialog.buttonBox.rejected.connect(reject)
|
||||
ui_dialog.id_spinbox.valueChanged.connect(verify)
|
||||
ui_dialog.name_edit.textChanged.connect(verify)
|
||||
dialog.finished.connect(duplicate)
|
||||
dialog.open()
|
||||
|
||||
def rename_ac(self):
|
||||
orig = self.conf[self.currentAC]
|
||||
ui_dialog = Ui_Dialog()
|
||||
dialog = QDialog(parent=self)
|
||||
ui_dialog.setupUi(dialog)
|
||||
ui_dialog.name_edit.setText(orig.name)
|
||||
ui_dialog.id_spinbox.setValue(orig.ac_id)
|
||||
|
||||
def verify():
|
||||
ok = True
|
||||
id = ui_dialog.id_spinbox.value()
|
||||
name = ui_dialog.name_edit.text()
|
||||
|
||||
acs_name = self.conf.get_all(name)
|
||||
if len(acs_name) > 1 or (len(acs_name) == 1 and acs_name[0] != orig):
|
||||
ui_dialog.name_edit.setStyleSheet("background-color: red;")
|
||||
ok = False
|
||||
else:
|
||||
ui_dialog.name_edit.setStyleSheet("")
|
||||
|
||||
acs_id = self.conf.get_all(id)
|
||||
if len(acs_id) > 1 or (len(acs_id) == 1 and acs_id[0] != orig):
|
||||
ui_dialog.id_spinbox.setStyleSheet("background-color: red;")
|
||||
ok = False
|
||||
else:
|
||||
ui_dialog.id_spinbox.setStyleSheet("")
|
||||
|
||||
return ok
|
||||
|
||||
def accept():
|
||||
if verify():
|
||||
dialog.accept()
|
||||
|
||||
def reject():
|
||||
dialog.reject()
|
||||
|
||||
def rename(result):
|
||||
if result:
|
||||
orig.name = ui_dialog.name_edit.text()
|
||||
orig.ac_id = ui_dialog.id_spinbox.value()
|
||||
self.header.rename_ac(orig.name)
|
||||
|
||||
ui_dialog.buttonBox.accepted.connect(accept)
|
||||
ui_dialog.buttonBox.rejected.connect(reject)
|
||||
ui_dialog.id_spinbox.valueChanged.connect(verify)
|
||||
ui_dialog.name_edit.textChanged.connect(verify)
|
||||
dialog.finished.connect(rename)
|
||||
dialog.open()
|
||||
|
||||
def change_color(self):
|
||||
ac = self.conf[self.currentAC]
|
||||
initial = QtGui.QColor(ac.get_color())
|
||||
color = QColorDialog.getColor(initial, self, "AC color")
|
||||
if color.isValid():
|
||||
color_name = color.name()
|
||||
ac.set_color(color_name)
|
||||
self.header.set_color(color_name)
|
||||
|
||||
def edit_flightplan_gcs(self, path):
|
||||
if self.flight_plan_editor is None:
|
||||
tools = parse_tools()
|
||||
if "Flight Plan Editor" in tools:
|
||||
self.flight_plan_editor = tools["Flight Plan Editor"]
|
||||
|
||||
if self.flight_plan_editor is not None:
|
||||
cmd = [os.path.join(utils.PAPARAZZI_SRC, self.flight_plan_editor.command)]
|
||||
for arg in self.flight_plan_editor.args:
|
||||
cmd += arg.args()
|
||||
cmd.append(os.path.join(utils.CONF_DIR, path))
|
||||
subprocess.Popen(cmd)
|
||||
# self.launch_program(self.flight_plan_editor.name, cmd, self.flight_plan_editor.icon)
|
||||
|
||||
def launch_program(self, shortname, cmd, icon):
|
||||
pw = ProgramWidget(shortname, cmd, icon, self.programs_widget)
|
||||
self.programs_widget.layout().addWidget(pw)
|
||||
pw.ready_read_stderr.connect(lambda: self.console_widget.handle_stderr(pw))
|
||||
pw.ready_read_stdout.connect(lambda: self.console_widget.handle_stdout(pw))
|
||||
pw.finished.connect(lambda c, s: self.console_widget.handle_program_finished(pw, c, s))
|
||||
pw.remove.connect(lambda: self.remove_program(pw))
|
||||
if REMOVE_PROGRAMS_FINISHED:
|
||||
pw.finished.connect(lambda: self.remove_program(pw))
|
||||
pw.start_program()
|
||||
|
||||
def remove_program(self, pw: ProgramWidget):
|
||||
self.programs_widget.layout().removeWidget(pw)
|
||||
self.console_widget.remove_program(pw)
|
||||
pw.deleteLater()
|
||||
@@ -0,0 +1,189 @@
|
||||
# Copyright (C) 2008-2022 The Paparazzi Team
|
||||
# released under GNU GPLv2 or later. See COPYING file.
|
||||
from generated.ui_console import Ui_Console
|
||||
from PyQt5.QtWidgets import *
|
||||
from PyQt5.QtCore import QProcess, QByteArray, Qt
|
||||
from PyQt5.QtGui import QTextCursor
|
||||
import utils
|
||||
from program_widget import ProgramWidget
|
||||
from dataclasses import dataclass
|
||||
from enum import Enum
|
||||
from typing import Dict, List
|
||||
|
||||
|
||||
class Level(Enum):
|
||||
ERROR = 0
|
||||
WARNING = 1
|
||||
INFO = 2
|
||||
ALL = 3
|
||||
|
||||
|
||||
class Channel(Enum):
|
||||
STDOUT = 0
|
||||
STDERR = 1
|
||||
MANAGEMENT = 2
|
||||
|
||||
|
||||
@dataclass
|
||||
class Record:
|
||||
level: Level
|
||||
data: str
|
||||
emitter: ProgramWidget
|
||||
channel: Channel
|
||||
|
||||
|
||||
class ConsoleWidget(QWidget, Ui_Console):
|
||||
|
||||
LEVELS_REG = {
|
||||
Level.ERROR: ["error:", "error ", "no such file", "undefined reference", "failure", "multiple definition"],
|
||||
Level.WARNING: ["warning", "no srtm data found"],
|
||||
Level.INFO: ["pragma message", "info:", "paparazzi version", "build aircraft"]
|
||||
}
|
||||
|
||||
def __init__(self, parent=None):
|
||||
QWidget.__init__(self, parent=parent)
|
||||
self.setupUi(self)
|
||||
self.records: List[Record] = []
|
||||
self.p_checkboxes: Dict[ProgramWidget, QCheckBox] = {}
|
||||
self.programs_checkbox.stateChanged.connect(self.handle_check_all)
|
||||
self.log_level_slider.valueChanged.connect(self.log_level_changed)
|
||||
self.clear_button.clicked.connect(self.clear)
|
||||
self.splitter.setSizes([500, 100])
|
||||
|
||||
def display_record(self, record):
|
||||
if record.level == Level.ERROR:
|
||||
bg = "background-color:red;"
|
||||
elif record.level == Level.WARNING:
|
||||
bg = "background-color:orange;"
|
||||
elif record.level == Level.INFO:
|
||||
bg = "background-color:lime;"
|
||||
else:
|
||||
bg = ""
|
||||
|
||||
if record.channel == Channel.STDOUT:
|
||||
ch = ""
|
||||
elif record.channel == Channel.STDERR:
|
||||
ch = "font-style: italic;"
|
||||
else:
|
||||
ch = "font-weight: bold;"
|
||||
|
||||
data = "<span style=\"{}{}\">{}</span>".format(bg, ch, record.data)
|
||||
self.console_textedit.append(data)
|
||||
|
||||
def classify(self, line: str):
|
||||
for level, regs in self.LEVELS_REG.items():
|
||||
for reg in regs:
|
||||
if reg in line.lower():
|
||||
return level
|
||||
return Level.ALL
|
||||
|
||||
def handle_data(self, pw: ProgramWidget, data: QByteArray, channel: Channel):
|
||||
if pw not in self.p_checkboxes:
|
||||
self.new_program(pw)
|
||||
if data.endsWith(b'\n'):
|
||||
data = data[:-1]
|
||||
lines = data.split(b'\n')
|
||||
for line in lines:
|
||||
line = line.data().decode()
|
||||
level = self.classify(line)
|
||||
r = Record(level, line, pw, channel)
|
||||
self.records.append(r)
|
||||
self.display_record(r)
|
||||
|
||||
def handle_stdout(self, pw: ProgramWidget):
|
||||
data = pw.process.readAllStandardOutput()
|
||||
self.handle_data(pw, data, Channel.STDOUT)
|
||||
|
||||
def handle_stderr(self, pw: ProgramWidget):
|
||||
data = pw.process.readAllStandardError()
|
||||
self.handle_data(pw, data, Channel.STDERR)
|
||||
|
||||
def handle_program_finished(self, pw: ProgramWidget, exit_code: int, exit_status: QProcess.ExitStatus):
|
||||
if exit_code == 0:
|
||||
self.post_message(pw, "{} Done".format(pw.shortname))
|
||||
else:
|
||||
self.post_message(pw, "{} terminated with code {}".format(pw.shortname, exit_code))
|
||||
|
||||
def post_message(self, pw: ProgramWidget, msg):
|
||||
r = Record(Level.ALL, msg, pw, Channel.MANAGEMENT)
|
||||
self.records.append(r)
|
||||
self.display_record(r)
|
||||
|
||||
def new_program(self, pw: ProgramWidget):
|
||||
chk = QCheckBox(pw.shortname, self.programs_widget)
|
||||
chk.setToolTip(" ".join(pw.cmd))
|
||||
self.p_checkboxes[pw] = chk
|
||||
index = self.programs_widget.layout().count() - 1
|
||||
lay: QVBoxLayout = self.programs_widget.layout()
|
||||
lay.insertWidget(index, chk)
|
||||
chk.stateChanged.connect(self.handle_program_checked)
|
||||
self.handle_program_checked()
|
||||
|
||||
def remove_program(self, pw: ProgramWidget):
|
||||
chk = self.p_checkboxes.pop(pw)
|
||||
if chk is not None:
|
||||
for r in self.records:
|
||||
if r.emitter == pw:
|
||||
r.emitter = None
|
||||
self.programs_widget.layout().removeWidget(chk)
|
||||
chk.deleteLater()
|
||||
self.update_content()
|
||||
|
||||
def handle_check_all(self, state):
|
||||
if state == Qt.PartiallyChecked:
|
||||
state = Qt.Checked
|
||||
for chk in self.p_checkboxes.values():
|
||||
chk.blockSignals(True)
|
||||
chk.setCheckState(state)
|
||||
chk.blockSignals(False)
|
||||
self.update_content()
|
||||
|
||||
def handle_program_checked(self):
|
||||
chks = list(self.p_checkboxes.values())
|
||||
if len(chks) > 0:
|
||||
state = chks[0].checkState()
|
||||
for s in chks[1:]:
|
||||
if s.checkState() != state:
|
||||
self.programs_checkbox.blockSignals(True)
|
||||
self.programs_checkbox.setCheckState(Qt.PartiallyChecked)
|
||||
self.programs_checkbox.blockSignals(False)
|
||||
break
|
||||
else:
|
||||
self.programs_checkbox.blockSignals(True)
|
||||
self.programs_checkbox.setCheckState(state)
|
||||
self.programs_checkbox.blockSignals(False)
|
||||
self.update_content()
|
||||
|
||||
def log_level_changed(self, value):
|
||||
if value == Level.ERROR.value:
|
||||
self.log_level_label.setText("Errors")
|
||||
elif value == Level.WARNING.value:
|
||||
self.log_level_label.setText("Warnings")
|
||||
elif value == Level.INFO.value:
|
||||
self.log_level_label.setText("Info")
|
||||
elif value == Level.ALL.value:
|
||||
self.log_level_label.setText("All")
|
||||
self.update_content()
|
||||
|
||||
def filter(self, r: Record):
|
||||
log_level = self.log_level_slider.value()
|
||||
if r.level.value > log_level:
|
||||
return False
|
||||
# if any program is checked, display only those that are checked
|
||||
if self.programs_checkbox.checkState() != Qt.Unchecked:
|
||||
if r.emitter is None:
|
||||
return False
|
||||
if self.p_checkboxes[r.emitter].checkState() != Qt.Checked:
|
||||
return False
|
||||
return True
|
||||
|
||||
def update_content(self):
|
||||
self.console_textedit.clear()
|
||||
for r in self.records:
|
||||
if self.filter(r):
|
||||
self.display_record(r)
|
||||
|
||||
def clear(self):
|
||||
# TODO remove only filtered ? plus trashed ?
|
||||
self.records.clear()
|
||||
self.update_content()
|
||||
@@ -1,103 +0,0 @@
|
||||
# Paparazzi center utilities
|
||||
#
|
||||
# Copyright (C) 2016 ENAC, Florian BITARD (intern student)
|
||||
#
|
||||
# This file is part of paparazzi.
|
||||
#
|
||||
# paparazzi 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 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
# Boston, MA 02111-1307, USA.
|
||||
|
||||
###############################################################################
|
||||
# [Imports]
|
||||
|
||||
import ui.set_manager as manager
|
||||
import ui.popup as popup
|
||||
|
||||
import PyQt5.QtWidgets as Widgets
|
||||
import logging
|
||||
import os
|
||||
|
||||
|
||||
###############################################################################
|
||||
# [Constants]
|
||||
|
||||
LOGGER = logging.getLogger("[DIALOGS]")
|
||||
|
||||
UI_DIR = "ui"
|
||||
|
||||
DATA_CHANGED_POPUP_TYPE = "data changed"
|
||||
DATA_CHANGED_POPUP_HTML = "data_changed.html"
|
||||
CREDITS_POPUP_TYPE = "credits"
|
||||
CREDITS_POPUP_HTML = "credits.html"
|
||||
TUTORIAL_POPUP_TYPE = "tutorial"
|
||||
TUTORIAL_POPUP_HTML = "tutorial.html"
|
||||
|
||||
|
||||
###############################################################################
|
||||
# [SettingsManager class]
|
||||
|
||||
class SettingsManager(Widgets.QDialog):
|
||||
"""Class to manage the settings manager HMI."""
|
||||
def __init__(self):
|
||||
super(SettingsManager, self).__init__()
|
||||
self.ui = manager.Ui_Dialog()
|
||||
self.ui.setupUi(self)
|
||||
|
||||
|
||||
###############################################################################
|
||||
# [SettingsManager class]
|
||||
|
||||
class Popup(Widgets.QDialog):
|
||||
"""Class to manage the settings manager HMI."""
|
||||
def __init__(self, popup_type=None):
|
||||
super(Popup, self).__init__()
|
||||
self.ui = popup.Ui_Dialog()
|
||||
self.ui.setupUi(self)
|
||||
self.ui.textBrowser.setOpenExternalLinks(True)
|
||||
|
||||
self.type = popup_type
|
||||
|
||||
self.set_popup_details()
|
||||
|
||||
def set_popup_details(self):
|
||||
"""
|
||||
-> Set the title, the text and the dialog buttons of the popup window
|
||||
according to its type.
|
||||
"""
|
||||
if self.type == DATA_CHANGED_POPUP_TYPE:
|
||||
self.setWindowTitle("/!\ Some unsaved data found !")
|
||||
self.ui.buttonBox.setStandardButtons(
|
||||
Widgets.QDialogButtonBox.Cancel | Widgets.QDialogButtonBox.Save)
|
||||
html_file = DATA_CHANGED_POPUP_HTML
|
||||
elif self.type == CREDITS_POPUP_TYPE:
|
||||
self.setWindowTitle("Paparazzi UAV Center credits "
|
||||
"(Python/Qt version)")
|
||||
self.ui.buttonBox.setStandardButtons(Widgets.QDialogButtonBox.Close)
|
||||
html_file = CREDITS_POPUP_HTML
|
||||
elif self.type == TUTORIAL_POPUP_TYPE:
|
||||
self.setWindowTitle("Tutorials and documents")
|
||||
self.ui.buttonBox.setStandardButtons(Widgets.QDialogButtonBox.Close)
|
||||
html_file = TUTORIAL_POPUP_HTML
|
||||
else:
|
||||
self.setWindowTitle("Popup without specific type.")
|
||||
html_file = "none.html"
|
||||
|
||||
try:
|
||||
html_config_path = os.path.join(UI_DIR, html_file)
|
||||
with open(html_config_path, 'r') as popup_html_content:
|
||||
self.ui.textBrowser.setHtml(popup_html_content.read())
|
||||
except FileNotFoundError:
|
||||
print("Popup HTML configuration file not found ! "
|
||||
"('%s' should be in 'ui' directory.)" % html_file)
|
||||
@@ -0,0 +1,54 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'ui/app_settings.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.14.1
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_AppSettingsDialog(object):
|
||||
def setupUi(self, AppSettingsDialog):
|
||||
AppSettingsDialog.setObjectName("AppSettingsDialog")
|
||||
AppSettingsDialog.resize(381, 131)
|
||||
self.gridLayout = QtWidgets.QGridLayout(AppSettingsDialog)
|
||||
self.gridLayout.setObjectName("gridLayout")
|
||||
self.label = QtWidgets.QLabel(AppSettingsDialog)
|
||||
self.label.setObjectName("label")
|
||||
self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
|
||||
self.text_editor_edit = QtWidgets.QLineEdit(AppSettingsDialog)
|
||||
self.text_editor_edit.setObjectName("text_editor_edit")
|
||||
self.gridLayout.addWidget(self.text_editor_edit, 0, 1, 1, 1)
|
||||
self.label_2 = QtWidgets.QLabel(AppSettingsDialog)
|
||||
self.label_2.setObjectName("label_2")
|
||||
self.gridLayout.addWidget(self.label_2, 1, 0, 1, 1)
|
||||
self.terminal_emulator_edit = QtWidgets.QLineEdit(AppSettingsDialog)
|
||||
self.terminal_emulator_edit.setObjectName("terminal_emulator_edit")
|
||||
self.gridLayout.addWidget(self.terminal_emulator_edit, 1, 1, 1, 1)
|
||||
self.label_3 = QtWidgets.QLabel(AppSettingsDialog)
|
||||
self.label_3.setObjectName("label_3")
|
||||
self.gridLayout.addWidget(self.label_3, 2, 0, 1, 1)
|
||||
self.keep_changes_checkbox = QtWidgets.QCheckBox(AppSettingsDialog)
|
||||
self.keep_changes_checkbox.setText("")
|
||||
self.keep_changes_checkbox.setObjectName("keep_changes_checkbox")
|
||||
self.gridLayout.addWidget(self.keep_changes_checkbox, 2, 1, 1, 1)
|
||||
self.buttonBox = QtWidgets.QDialogButtonBox(AppSettingsDialog)
|
||||
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
|
||||
self.buttonBox.setObjectName("buttonBox")
|
||||
self.gridLayout.addWidget(self.buttonBox, 3, 0, 1, 2)
|
||||
|
||||
self.retranslateUi(AppSettingsDialog)
|
||||
self.buttonBox.accepted.connect(AppSettingsDialog.accept)
|
||||
self.buttonBox.rejected.connect(AppSettingsDialog.reject)
|
||||
QtCore.QMetaObject.connectSlotsByName(AppSettingsDialog)
|
||||
|
||||
def retranslateUi(self, AppSettingsDialog):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
AppSettingsDialog.setWindowTitle(_translate("AppSettingsDialog", "Settings"))
|
||||
self.label.setText(_translate("AppSettingsDialog", "Text editor"))
|
||||
self.label_2.setText(_translate("AppSettingsDialog", "Terminal Emulator"))
|
||||
self.label_3.setText(_translate("AppSettingsDialog", "Keep changes on exit"))
|
||||
@@ -0,0 +1,95 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'ui/build.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.14.1
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_Build(object):
|
||||
def setupUi(self, Build):
|
||||
Build.setObjectName("Build")
|
||||
Build.resize(437, 87)
|
||||
self.horizontalLayout = QtWidgets.QHBoxLayout(Build)
|
||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||
self.groupBox = QtWidgets.QGroupBox(Build)
|
||||
self.groupBox.setObjectName("groupBox")
|
||||
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.groupBox)
|
||||
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
|
||||
self.label_14 = QtWidgets.QLabel(self.groupBox)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.label_14.sizePolicy().hasHeightForWidth())
|
||||
self.label_14.setSizePolicy(sizePolicy)
|
||||
self.label_14.setObjectName("label_14")
|
||||
self.horizontalLayout_2.addWidget(self.label_14)
|
||||
self.target_combo = QtWidgets.QComboBox(self.groupBox)
|
||||
self.target_combo.setCurrentText("")
|
||||
self.target_combo.setDuplicatesEnabled(False)
|
||||
self.target_combo.setObjectName("target_combo")
|
||||
self.horizontalLayout_2.addWidget(self.target_combo)
|
||||
self.clean_button = QtWidgets.QToolButton(self.groupBox)
|
||||
icon = QtGui.QIcon.fromTheme("edit-clear")
|
||||
self.clean_button.setIcon(icon)
|
||||
self.clean_button.setObjectName("clean_button")
|
||||
self.horizontalLayout_2.addWidget(self.clean_button)
|
||||
self.build_button = QtWidgets.QToolButton(self.groupBox)
|
||||
icon = QtGui.QIcon.fromTheme("system-run")
|
||||
self.build_button.setIcon(icon)
|
||||
self.build_button.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly)
|
||||
self.build_button.setObjectName("build_button")
|
||||
self.horizontalLayout_2.addWidget(self.build_button)
|
||||
self.print_config_checkbox = QtWidgets.QCheckBox(self.groupBox)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.print_config_checkbox.sizePolicy().hasHeightForWidth())
|
||||
self.print_config_checkbox.setSizePolicy(sizePolicy)
|
||||
self.print_config_checkbox.setText("")
|
||||
self.print_config_checkbox.setObjectName("print_config_checkbox")
|
||||
self.horizontalLayout_2.addWidget(self.print_config_checkbox)
|
||||
self.horizontalLayout.addWidget(self.groupBox)
|
||||
self.groupBox_2 = QtWidgets.QGroupBox(Build)
|
||||
self.groupBox_2.setObjectName("groupBox_2")
|
||||
self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.groupBox_2)
|
||||
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
|
||||
self.label_15 = QtWidgets.QLabel(self.groupBox_2)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.label_15.sizePolicy().hasHeightForWidth())
|
||||
self.label_15.setSizePolicy(sizePolicy)
|
||||
self.label_15.setObjectName("label_15")
|
||||
self.horizontalLayout_3.addWidget(self.label_15)
|
||||
self.device_combo = QtWidgets.QComboBox(self.groupBox_2)
|
||||
self.device_combo.setObjectName("device_combo")
|
||||
self.horizontalLayout_3.addWidget(self.device_combo)
|
||||
self.flash_button = QtWidgets.QToolButton(self.groupBox_2)
|
||||
icon = QtGui.QIcon.fromTheme("emblem-downloads")
|
||||
self.flash_button.setIcon(icon)
|
||||
self.flash_button.setObjectName("flash_button")
|
||||
self.horizontalLayout_3.addWidget(self.flash_button)
|
||||
self.horizontalLayout.addWidget(self.groupBox_2)
|
||||
|
||||
self.retranslateUi(Build)
|
||||
QtCore.QMetaObject.connectSlotsByName(Build)
|
||||
|
||||
def retranslateUi(self, Build):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
Build.setWindowTitle(_translate("Build", "Form"))
|
||||
self.groupBox.setTitle(_translate("Build", "Build"))
|
||||
self.label_14.setText(_translate("Build", "Target"))
|
||||
self.clean_button.setToolTip(_translate("Build", "Clean"))
|
||||
self.clean_button.setText(_translate("Build", "..."))
|
||||
self.build_button.setToolTip(_translate("Build", "Build"))
|
||||
self.build_button.setText(_translate("Build", "..."))
|
||||
self.print_config_checkbox.setToolTip(_translate("Build", "print config at build time"))
|
||||
self.groupBox_2.setTitle(_translate("Build", "Flash"))
|
||||
self.label_15.setText(_translate("Build", "Device"))
|
||||
self.flash_button.setToolTip(_translate("Build", "Upload"))
|
||||
self.flash_button.setText(_translate("Build", "Flash"))
|
||||
@@ -0,0 +1,94 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'ui/conf_header.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.14.1
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_ConfHeader(object):
|
||||
def setupUi(self, ConfHeader):
|
||||
ConfHeader.setObjectName("ConfHeader")
|
||||
ConfHeader.resize(664, 192)
|
||||
self.horizontalLayout = QtWidgets.QHBoxLayout(ConfHeader)
|
||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||
self.id_spinBox = QtWidgets.QSpinBox(ConfHeader)
|
||||
self.id_spinBox.setMaximum(255)
|
||||
self.id_spinBox.setObjectName("id_spinBox")
|
||||
self.horizontalLayout.addWidget(self.id_spinBox)
|
||||
self.color_button = QtWidgets.QToolButton(ConfHeader)
|
||||
self.color_button.setStyleSheet("")
|
||||
self.color_button.setText("")
|
||||
self.color_button.setObjectName("color_button")
|
||||
self.horizontalLayout.addWidget(self.color_button)
|
||||
self.ac_combo = QtWidgets.QComboBox(ConfHeader)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.ac_combo.sizePolicy().hasHeightForWidth())
|
||||
self.ac_combo.setSizePolicy(sizePolicy)
|
||||
self.ac_combo.setEditable(False)
|
||||
self.ac_combo.setObjectName("ac_combo")
|
||||
self.horizontalLayout.addWidget(self.ac_combo)
|
||||
self.menu_button = QtWidgets.QToolButton(ConfHeader)
|
||||
self.menu_button.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
|
||||
self.menu_button.setText("")
|
||||
icon = QtGui.QIcon.fromTheme("format-justify-fill")
|
||||
self.menu_button.setIcon(icon)
|
||||
self.menu_button.setObjectName("menu_button")
|
||||
self.horizontalLayout.addWidget(self.menu_button)
|
||||
self.refresh_button = QtWidgets.QToolButton(ConfHeader)
|
||||
icon = QtGui.QIcon.fromTheme("view-refresh")
|
||||
self.refresh_button.setIcon(icon)
|
||||
self.refresh_button.setObjectName("refresh_button")
|
||||
self.horizontalLayout.addWidget(self.refresh_button)
|
||||
self.save_button = QtWidgets.QToolButton(ConfHeader)
|
||||
icon = QtGui.QIcon.fromTheme("document-save")
|
||||
self.save_button.setIcon(icon)
|
||||
self.save_button.setObjectName("save_button")
|
||||
self.horizontalLayout.addWidget(self.save_button)
|
||||
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
self.horizontalLayout.addItem(spacerItem)
|
||||
self.label_4 = QtWidgets.QLabel(ConfHeader)
|
||||
self.label_4.setObjectName("label_4")
|
||||
self.horizontalLayout.addWidget(self.label_4)
|
||||
self.set_combo = QtWidgets.QComboBox(ConfHeader)
|
||||
self.set_combo.setObjectName("set_combo")
|
||||
self.horizontalLayout.addWidget(self.set_combo)
|
||||
self.new_ac_action = QtWidgets.QAction(ConfHeader)
|
||||
icon = QtGui.QIcon.fromTheme("document-new")
|
||||
self.new_ac_action.setIcon(icon)
|
||||
self.new_ac_action.setObjectName("new_ac_action")
|
||||
self.remove_ac_action = QtWidgets.QAction(ConfHeader)
|
||||
icon = QtGui.QIcon.fromTheme("edit-delete")
|
||||
self.remove_ac_action.setIcon(icon)
|
||||
self.remove_ac_action.setObjectName("remove_ac_action")
|
||||
self.duplicate_action = QtWidgets.QAction(ConfHeader)
|
||||
icon = QtGui.QIcon.fromTheme("edit-copy")
|
||||
self.duplicate_action.setIcon(icon)
|
||||
self.duplicate_action.setObjectName("duplicate_action")
|
||||
self.rename_action = QtWidgets.QAction(ConfHeader)
|
||||
icon = QtGui.QIcon.fromTheme("format-text-italic")
|
||||
self.rename_action.setIcon(icon)
|
||||
self.rename_action.setObjectName("rename_action")
|
||||
|
||||
self.retranslateUi(ConfHeader)
|
||||
self.menu_button.clicked.connect(self.menu_button.showMenu)
|
||||
QtCore.QMetaObject.connectSlotsByName(ConfHeader)
|
||||
|
||||
def retranslateUi(self, ConfHeader):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
ConfHeader.setWindowTitle(_translate("ConfHeader", "Form"))
|
||||
self.refresh_button.setToolTip(_translate("ConfHeader", "refresh Aircraft"))
|
||||
self.refresh_button.setText(_translate("ConfHeader", "..."))
|
||||
self.save_button.setToolTip(_translate("ConfHeader", "save conf"))
|
||||
self.save_button.setText(_translate("ConfHeader", "..."))
|
||||
self.label_4.setText(_translate("ConfHeader", "Set"))
|
||||
self.new_ac_action.setText(_translate("ConfHeader", "New AC"))
|
||||
self.remove_ac_action.setText(_translate("ConfHeader", "Remove"))
|
||||
self.duplicate_action.setText(_translate("ConfHeader", "Duplicate"))
|
||||
self.rename_action.setText(_translate("ConfHeader", "Rename"))
|
||||
@@ -0,0 +1,52 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'ui/conf_item.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.14.1
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_FileConf(object):
|
||||
def setupUi(self, FileConf):
|
||||
FileConf.setObjectName("FileConf")
|
||||
FileConf.resize(306, 129)
|
||||
self.verticalLayout = QtWidgets.QVBoxLayout(FileConf)
|
||||
self.verticalLayout.setObjectName("verticalLayout")
|
||||
self.horizontalLayout_5 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_5.setObjectName("horizontalLayout_5")
|
||||
self.title_label = QtWidgets.QLabel(FileConf)
|
||||
self.title_label.setStyleSheet("font-weight: bold;")
|
||||
self.title_label.setObjectName("title_label")
|
||||
self.horizontalLayout_5.addWidget(self.title_label)
|
||||
self.edit_alt_button = QtWidgets.QPushButton(FileConf)
|
||||
self.edit_alt_button.setObjectName("edit_alt_button")
|
||||
self.horizontalLayout_5.addWidget(self.edit_alt_button)
|
||||
self.edit_button = QtWidgets.QToolButton(FileConf)
|
||||
self.edit_button.setObjectName("edit_button")
|
||||
self.horizontalLayout_5.addWidget(self.edit_button)
|
||||
self.select_button = QtWidgets.QToolButton(FileConf)
|
||||
self.select_button.setObjectName("select_button")
|
||||
self.horizontalLayout_5.addWidget(self.select_button)
|
||||
self.verticalLayout.addLayout(self.horizontalLayout_5)
|
||||
self.path_label = QtWidgets.QLabel(FileConf)
|
||||
self.path_label.setWordWrap(True)
|
||||
self.path_label.setOpenExternalLinks(False)
|
||||
self.path_label.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByKeyboard|QtCore.Qt.TextSelectableByMouse)
|
||||
self.path_label.setObjectName("path_label")
|
||||
self.verticalLayout.addWidget(self.path_label)
|
||||
|
||||
self.retranslateUi(FileConf)
|
||||
QtCore.QMetaObject.connectSlotsByName(FileConf)
|
||||
|
||||
def retranslateUi(self, FileConf):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
FileConf.setWindowTitle(_translate("FileConf", "Form"))
|
||||
self.title_label.setText(_translate("FileConf", "Flight Plan"))
|
||||
self.edit_alt_button.setText(_translate("FileConf", "Edit alt"))
|
||||
self.edit_button.setText(_translate("FileConf", "Edit"))
|
||||
self.select_button.setText(_translate("FileConf", "Select"))
|
||||
self.path_label.setText(_translate("FileConf", "/path/to/file.xml"))
|
||||
@@ -0,0 +1,77 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'ui/configuration_panel.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.14.1
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_ConfigurationPanel(object):
|
||||
def setupUi(self, ConfigurationPanel):
|
||||
ConfigurationPanel.setObjectName("ConfigurationPanel")
|
||||
ConfigurationPanel.resize(562, 480)
|
||||
self.verticalLayout_2 = QtWidgets.QVBoxLayout(ConfigurationPanel)
|
||||
self.verticalLayout_2.setObjectName("verticalLayout_2")
|
||||
self.header = HeaderWidget(ConfigurationPanel)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.header.sizePolicy().hasHeightForWidth())
|
||||
self.header.setSizePolicy(sizePolicy)
|
||||
self.header.setObjectName("header")
|
||||
self.verticalLayout_2.addWidget(self.header)
|
||||
self.line = QtWidgets.QFrame(ConfigurationPanel)
|
||||
self.line.setFrameShape(QtWidgets.QFrame.HLine)
|
||||
self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
|
||||
self.line.setObjectName("line")
|
||||
self.verticalLayout_2.addWidget(self.line)
|
||||
self.splitter = QtWidgets.QSplitter(ConfigurationPanel)
|
||||
self.splitter.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.splitter.setObjectName("splitter")
|
||||
self.conf_widget = ConfWidget(self.splitter)
|
||||
self.conf_widget.setObjectName("conf_widget")
|
||||
self.widget_2 = QtWidgets.QWidget(self.splitter)
|
||||
self.widget_2.setObjectName("widget_2")
|
||||
self.verticalLayout = QtWidgets.QVBoxLayout(self.widget_2)
|
||||
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.verticalLayout.setObjectName("verticalLayout")
|
||||
self.build_widget = BuildWidget(self.widget_2)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.build_widget.sizePolicy().hasHeightForWidth())
|
||||
self.build_widget.setSizePolicy(sizePolicy)
|
||||
self.build_widget.setMinimumSize(QtCore.QSize(0, 0))
|
||||
self.build_widget.setObjectName("build_widget")
|
||||
self.verticalLayout.addWidget(self.build_widget)
|
||||
self.programs_widget = QtWidgets.QFrame(self.widget_2)
|
||||
self.programs_widget.setFrameShape(QtWidgets.QFrame.StyledPanel)
|
||||
self.programs_widget.setFrameShadow(QtWidgets.QFrame.Raised)
|
||||
self.programs_widget.setObjectName("programs_widget")
|
||||
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.programs_widget)
|
||||
self.verticalLayout_3.setObjectName("verticalLayout_3")
|
||||
self.verticalLayout.addWidget(self.programs_widget)
|
||||
self.console_widget = ConsoleWidget(self.widget_2)
|
||||
self.console_widget.setObjectName("console_widget")
|
||||
self.verticalLayout.addWidget(self.console_widget)
|
||||
self.verticalLayout.setStretch(2, 1)
|
||||
self.verticalLayout_2.addWidget(self.splitter)
|
||||
self.save_conf_action = QtWidgets.QAction(ConfigurationPanel)
|
||||
self.save_conf_action.setObjectName("save_conf_action")
|
||||
|
||||
self.retranslateUi(ConfigurationPanel)
|
||||
QtCore.QMetaObject.connectSlotsByName(ConfigurationPanel)
|
||||
|
||||
def retranslateUi(self, ConfigurationPanel):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
ConfigurationPanel.setWindowTitle(_translate("ConfigurationPanel", "Form"))
|
||||
self.save_conf_action.setText(_translate("ConfigurationPanel", "Save configuration"))
|
||||
self.save_conf_action.setShortcut(_translate("ConfigurationPanel", "Ctrl+S"))
|
||||
from build_widget import BuildWidget
|
||||
from conf_widget import ConfWidget
|
||||
from console_widget import ConsoleWidget
|
||||
from header_widget import HeaderWidget
|
||||
@@ -0,0 +1,100 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'ui/console.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.14.1
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_Console(object):
|
||||
def setupUi(self, Console):
|
||||
Console.setObjectName("Console")
|
||||
Console.resize(709, 647)
|
||||
self.verticalLayout_2 = QtWidgets.QVBoxLayout(Console)
|
||||
self.verticalLayout_2.setObjectName("verticalLayout_2")
|
||||
self.splitter = QtWidgets.QSplitter(Console)
|
||||
self.splitter.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.splitter.setObjectName("splitter")
|
||||
self.console_textedit = QtWidgets.QTextEdit(self.splitter)
|
||||
self.console_textedit.setReadOnly(True)
|
||||
self.console_textedit.setObjectName("console_textedit")
|
||||
self.filter_widget = QtWidgets.QWidget(self.splitter)
|
||||
self.filter_widget.setObjectName("filter_widget")
|
||||
self.verticalLayout = QtWidgets.QVBoxLayout(self.filter_widget)
|
||||
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.verticalLayout.setObjectName("verticalLayout")
|
||||
self.label = QtWidgets.QLabel(self.filter_widget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.label.sizePolicy().hasHeightForWidth())
|
||||
self.label.setSizePolicy(sizePolicy)
|
||||
self.label.setObjectName("label")
|
||||
self.verticalLayout.addWidget(self.label)
|
||||
self.programs_checkbox = QtWidgets.QCheckBox(self.filter_widget)
|
||||
self.programs_checkbox.setChecked(False)
|
||||
self.programs_checkbox.setObjectName("programs_checkbox")
|
||||
self.verticalLayout.addWidget(self.programs_checkbox)
|
||||
self.scrollArea = QtWidgets.QScrollArea(self.filter_widget)
|
||||
self.scrollArea.setWidgetResizable(True)
|
||||
self.scrollArea.setObjectName("scrollArea")
|
||||
self.programs_widget = QtWidgets.QWidget()
|
||||
self.programs_widget.setGeometry(QtCore.QRect(0, 0, 382, 524))
|
||||
self.programs_widget.setObjectName("programs_widget")
|
||||
self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.programs_widget)
|
||||
self.verticalLayout_4.setObjectName("verticalLayout_4")
|
||||
spacerItem = QtWidgets.QSpacerItem(1, 167, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
||||
self.verticalLayout_4.addItem(spacerItem)
|
||||
self.scrollArea.setWidget(self.programs_widget)
|
||||
self.verticalLayout.addWidget(self.scrollArea)
|
||||
self.verticalLayout_2.addWidget(self.splitter)
|
||||
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
|
||||
self.label_3 = QtWidgets.QLabel(Console)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.label_3.sizePolicy().hasHeightForWidth())
|
||||
self.label_3.setSizePolicy(sizePolicy)
|
||||
self.label_3.setObjectName("label_3")
|
||||
self.horizontalLayout_2.addWidget(self.label_3)
|
||||
self.log_level_slider = QtWidgets.QSlider(Console)
|
||||
self.log_level_slider.setMaximumSize(QtCore.QSize(100, 16777215))
|
||||
self.log_level_slider.setMaximum(3)
|
||||
self.log_level_slider.setPageStep(1)
|
||||
self.log_level_slider.setProperty("value", 3)
|
||||
self.log_level_slider.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.log_level_slider.setTickPosition(QtWidgets.QSlider.TicksBelow)
|
||||
self.log_level_slider.setTickInterval(1)
|
||||
self.log_level_slider.setObjectName("log_level_slider")
|
||||
self.horizontalLayout_2.addWidget(self.log_level_slider)
|
||||
self.log_level_label = QtWidgets.QLabel(Console)
|
||||
self.log_level_label.setObjectName("log_level_label")
|
||||
self.horizontalLayout_2.addWidget(self.log_level_label)
|
||||
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
self.horizontalLayout_2.addItem(spacerItem1)
|
||||
self.clear_button = QtWidgets.QPushButton(Console)
|
||||
icon = QtGui.QIcon.fromTheme("edit-clear")
|
||||
self.clear_button.setIcon(icon)
|
||||
self.clear_button.setObjectName("clear_button")
|
||||
self.horizontalLayout_2.addWidget(self.clear_button)
|
||||
self.horizontalLayout_2.setStretch(1, 1)
|
||||
self.horizontalLayout_2.setStretch(3, 2)
|
||||
self.verticalLayout_2.addLayout(self.horizontalLayout_2)
|
||||
self.verticalLayout_2.setStretch(0, 1)
|
||||
|
||||
self.retranslateUi(Console)
|
||||
QtCore.QMetaObject.connectSlotsByName(Console)
|
||||
|
||||
def retranslateUi(self, Console):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
Console.setWindowTitle(_translate("Console", "Form"))
|
||||
self.label.setText(_translate("Console", "Filters"))
|
||||
self.programs_checkbox.setText(_translate("Console", "Programs"))
|
||||
self.label_3.setText(_translate("Console", "Log level:"))
|
||||
self.log_level_label.setText(_translate("Console", "All"))
|
||||
self.clear_button.setText(_translate("Console", "Clear console"))
|
||||
@@ -0,0 +1,47 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'ui/new_ac_dialog.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.14.1
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_Dialog(object):
|
||||
def setupUi(self, Dialog):
|
||||
Dialog.setObjectName("Dialog")
|
||||
Dialog.resize(187, 106)
|
||||
self.gridLayout = QtWidgets.QGridLayout(Dialog)
|
||||
self.gridLayout.setObjectName("gridLayout")
|
||||
self.label = QtWidgets.QLabel(Dialog)
|
||||
self.label.setObjectName("label")
|
||||
self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
|
||||
self.name_edit = QtWidgets.QLineEdit(Dialog)
|
||||
self.name_edit.setPlaceholderText("")
|
||||
self.name_edit.setObjectName("name_edit")
|
||||
self.gridLayout.addWidget(self.name_edit, 0, 1, 1, 1)
|
||||
self.label_2 = QtWidgets.QLabel(Dialog)
|
||||
self.label_2.setObjectName("label_2")
|
||||
self.gridLayout.addWidget(self.label_2, 1, 0, 1, 1)
|
||||
self.id_spinbox = QtWidgets.QSpinBox(Dialog)
|
||||
self.id_spinbox.setMinimum(1)
|
||||
self.id_spinbox.setMaximum(255)
|
||||
self.id_spinbox.setObjectName("id_spinbox")
|
||||
self.gridLayout.addWidget(self.id_spinbox, 1, 1, 1, 1)
|
||||
self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
|
||||
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
|
||||
self.buttonBox.setObjectName("buttonBox")
|
||||
self.gridLayout.addWidget(self.buttonBox, 2, 0, 1, 2)
|
||||
|
||||
self.retranslateUi(Dialog)
|
||||
QtCore.QMetaObject.connectSlotsByName(Dialog)
|
||||
|
||||
def retranslateUi(self, Dialog):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
|
||||
self.label.setText(_translate("Dialog", "Name"))
|
||||
self.label_2.setText(_translate("Dialog", "ID"))
|
||||
@@ -0,0 +1,35 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'ui/operation_panel.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.14.1
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_OperationPanel(object):
|
||||
def setupUi(self, OperationPanel):
|
||||
OperationPanel.setObjectName("OperationPanel")
|
||||
OperationPanel.resize(400, 300)
|
||||
self.verticalLayout = QtWidgets.QVBoxLayout(OperationPanel)
|
||||
self.verticalLayout.setObjectName("verticalLayout")
|
||||
self.splitter = QtWidgets.QSplitter(OperationPanel)
|
||||
self.splitter.setOrientation(QtCore.Qt.Vertical)
|
||||
self.splitter.setObjectName("splitter")
|
||||
self.session = SessionWidget(self.splitter)
|
||||
self.session.setObjectName("session")
|
||||
self.console = ConsoleWidget(self.splitter)
|
||||
self.console.setObjectName("console")
|
||||
self.verticalLayout.addWidget(self.splitter)
|
||||
|
||||
self.retranslateUi(OperationPanel)
|
||||
QtCore.QMetaObject.connectSlotsByName(OperationPanel)
|
||||
|
||||
def retranslateUi(self, OperationPanel):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
OperationPanel.setWindowTitle(_translate("OperationPanel", "Form"))
|
||||
from console_widget import ConsoleWidget
|
||||
from session_widget import SessionWidget
|
||||
@@ -0,0 +1,50 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'ui/program.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.14.1
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_Program(object):
|
||||
def setupUi(self, Program):
|
||||
Program.setObjectName("Program")
|
||||
Program.resize(374, 25)
|
||||
self.horizontalLayout = QtWidgets.QHBoxLayout(Program)
|
||||
self.horizontalLayout.setContentsMargins(-1, 0, -1, 0)
|
||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||
self.icon_label = QtWidgets.QLabel(Program)
|
||||
self.icon_label.setObjectName("icon_label")
|
||||
self.horizontalLayout.addWidget(self.icon_label)
|
||||
self.program_lineedit = QtWidgets.QLineEdit(Program)
|
||||
self.program_lineedit.setObjectName("program_lineedit")
|
||||
self.horizontalLayout.addWidget(self.program_lineedit)
|
||||
self.line = QtWidgets.QFrame(Program)
|
||||
self.line.setFrameShape(QtWidgets.QFrame.VLine)
|
||||
self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
|
||||
self.line.setObjectName("line")
|
||||
self.horizontalLayout.addWidget(self.line)
|
||||
self.run_button = QtWidgets.QToolButton(Program)
|
||||
icon = QtGui.QIcon.fromTheme("media-playback-stop")
|
||||
self.run_button.setIcon(icon)
|
||||
self.run_button.setObjectName("run_button")
|
||||
self.horizontalLayout.addWidget(self.run_button)
|
||||
self.remove_button = QtWidgets.QToolButton(Program)
|
||||
icon = QtGui.QIcon.fromTheme("list-remove")
|
||||
self.remove_button.setIcon(icon)
|
||||
self.remove_button.setObjectName("remove_button")
|
||||
self.horizontalLayout.addWidget(self.remove_button)
|
||||
|
||||
self.retranslateUi(Program)
|
||||
QtCore.QMetaObject.connectSlotsByName(Program)
|
||||
|
||||
def retranslateUi(self, Program):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
Program.setWindowTitle(_translate("Program", "Form"))
|
||||
self.icon_label.setText(_translate("Program", "..."))
|
||||
self.run_button.setText(_translate("Program", "..."))
|
||||
self.remove_button.setText(_translate("Program", "..."))
|
||||
@@ -0,0 +1,133 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'ui/session.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.14.1
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_Session(object):
|
||||
def setupUi(self, Session):
|
||||
Session.setObjectName("Session")
|
||||
Session.resize(400, 300)
|
||||
self.verticalLayout = QtWidgets.QVBoxLayout(Session)
|
||||
self.verticalLayout.setObjectName("verticalLayout")
|
||||
self.label_2 = QtWidgets.QLabel(Session)
|
||||
self.label_2.setObjectName("label_2")
|
||||
self.verticalLayout.addWidget(self.label_2)
|
||||
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
|
||||
self.sessions_combo = QtWidgets.QComboBox(Session)
|
||||
self.sessions_combo.setObjectName("sessions_combo")
|
||||
self.horizontalLayout_2.addWidget(self.sessions_combo)
|
||||
self.start_session_button = QtWidgets.QToolButton(Session)
|
||||
icon = QtGui.QIcon.fromTheme("media-playback-start")
|
||||
self.start_session_button.setIcon(icon)
|
||||
self.start_session_button.setObjectName("start_session_button")
|
||||
self.horizontalLayout_2.addWidget(self.start_session_button)
|
||||
self.menu_button = QtWidgets.QToolButton(Session)
|
||||
self.menu_button.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
|
||||
icon = QtGui.QIcon.fromTheme("format-justify-fill")
|
||||
self.menu_button.setIcon(icon)
|
||||
self.menu_button.setObjectName("menu_button")
|
||||
self.horizontalLayout_2.addWidget(self.menu_button)
|
||||
self.verticalLayout.addLayout(self.horizontalLayout_2)
|
||||
self.favorite_tools = QtWidgets.QWidget(Session)
|
||||
self.favorite_tools.setObjectName("favorite_tools")
|
||||
self.verticalLayout.addWidget(self.favorite_tools)
|
||||
self.horizontalLayout = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||
self.label = QtWidgets.QLabel(Session)
|
||||
self.label.setObjectName("label")
|
||||
self.horizontalLayout.addWidget(self.label)
|
||||
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
self.horizontalLayout.addItem(spacerItem)
|
||||
self.add_tool_button = QtWidgets.QToolButton(Session)
|
||||
icon = QtGui.QIcon.fromTheme("list-add")
|
||||
self.add_tool_button.setIcon(icon)
|
||||
self.add_tool_button.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
|
||||
self.add_tool_button.setAutoRaise(False)
|
||||
self.add_tool_button.setArrowType(QtCore.Qt.NoArrow)
|
||||
self.add_tool_button.setObjectName("add_tool_button")
|
||||
self.horizontalLayout.addWidget(self.add_tool_button)
|
||||
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
self.horizontalLayout.addItem(spacerItem1)
|
||||
self.line = QtWidgets.QFrame(Session)
|
||||
self.line.setFrameShape(QtWidgets.QFrame.VLine)
|
||||
self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
|
||||
self.line.setObjectName("line")
|
||||
self.horizontalLayout.addWidget(self.line)
|
||||
self.startall_button = QtWidgets.QToolButton(Session)
|
||||
icon = QtGui.QIcon.fromTheme("media-playback-start")
|
||||
self.startall_button.setIcon(icon)
|
||||
self.startall_button.setObjectName("startall_button")
|
||||
self.horizontalLayout.addWidget(self.startall_button)
|
||||
self.stopall_button = QtWidgets.QToolButton(Session)
|
||||
icon = QtGui.QIcon.fromTheme("media-playback-stop")
|
||||
self.stopall_button.setIcon(icon)
|
||||
self.stopall_button.setObjectName("stopall_button")
|
||||
self.horizontalLayout.addWidget(self.stopall_button)
|
||||
self.removeall_button = QtWidgets.QToolButton(Session)
|
||||
icon = QtGui.QIcon.fromTheme("list-remove")
|
||||
self.removeall_button.setIcon(icon)
|
||||
self.removeall_button.setObjectName("removeall_button")
|
||||
self.horizontalLayout.addWidget(self.removeall_button)
|
||||
self.verticalLayout.addLayout(self.horizontalLayout)
|
||||
self.scrollArea = QtWidgets.QScrollArea(Session)
|
||||
self.scrollArea.setWidgetResizable(True)
|
||||
self.scrollArea.setObjectName("scrollArea")
|
||||
self.programs_widget = QtWidgets.QWidget()
|
||||
self.programs_widget.setGeometry(QtCore.QRect(0, 0, 380, 176))
|
||||
self.programs_widget.setObjectName("programs_widget")
|
||||
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.programs_widget)
|
||||
self.verticalLayout_2.setObjectName("verticalLayout_2")
|
||||
spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
||||
self.verticalLayout_2.addItem(spacerItem2)
|
||||
self.scrollArea.setWidget(self.programs_widget)
|
||||
self.verticalLayout.addWidget(self.scrollArea)
|
||||
self.save_session_action = QtWidgets.QAction(Session)
|
||||
icon = QtGui.QIcon.fromTheme("document-save")
|
||||
self.save_session_action.setIcon(icon)
|
||||
self.save_session_action.setObjectName("save_session_action")
|
||||
self.save_as_action = QtWidgets.QAction(Session)
|
||||
icon = QtGui.QIcon.fromTheme("edit-copy")
|
||||
self.save_as_action.setIcon(icon)
|
||||
self.save_as_action.setObjectName("save_as_action")
|
||||
self.rename_session_action = QtWidgets.QAction(Session)
|
||||
icon = QtGui.QIcon.fromTheme("format-text-italic")
|
||||
self.rename_session_action.setIcon(icon)
|
||||
self.rename_session_action.setObjectName("rename_session_action")
|
||||
self.remove_session_action = QtWidgets.QAction(Session)
|
||||
icon = QtGui.QIcon.fromTheme("edit-delete")
|
||||
self.remove_session_action.setIcon(icon)
|
||||
self.remove_session_action.setObjectName("remove_session_action")
|
||||
|
||||
self.retranslateUi(Session)
|
||||
self.menu_button.clicked.connect(self.menu_button.showMenu)
|
||||
QtCore.QMetaObject.connectSlotsByName(Session)
|
||||
|
||||
def retranslateUi(self, Session):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
Session.setWindowTitle(_translate("Session", "Form"))
|
||||
self.label_2.setText(_translate("Session", "Session"))
|
||||
self.start_session_button.setToolTip(_translate("Session", "Start Session"))
|
||||
self.start_session_button.setText(_translate("Session", "..."))
|
||||
self.menu_button.setText(_translate("Session", "..."))
|
||||
self.label.setText(_translate("Session", "Programs"))
|
||||
self.add_tool_button.setToolTip(_translate("Session", "Add Tool"))
|
||||
self.add_tool_button.setText(_translate("Session", "Add tool"))
|
||||
self.startall_button.setToolTip(_translate("Session", "Start All"))
|
||||
self.startall_button.setText(_translate("Session", "..."))
|
||||
self.stopall_button.setToolTip(_translate("Session", "Stop All"))
|
||||
self.stopall_button.setText(_translate("Session", "..."))
|
||||
self.removeall_button.setToolTip(_translate("Session", "Remove All"))
|
||||
self.removeall_button.setText(_translate("Session", "..."))
|
||||
self.save_session_action.setText(_translate("Session", "Save session"))
|
||||
self.save_as_action.setText(_translate("Session", "Save as..."))
|
||||
self.save_as_action.setToolTip(_translate("Session", "Save session as..."))
|
||||
self.rename_session_action.setText(_translate("Session", "Rename session"))
|
||||
self.remove_session_action.setText(_translate("Session", "Remove session"))
|
||||
@@ -0,0 +1,39 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'ui/tools_list.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.14.1
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_ToolsList(object):
|
||||
def setupUi(self, ToolsList):
|
||||
ToolsList.setObjectName("ToolsList")
|
||||
ToolsList.resize(328, 357)
|
||||
self.verticalLayout = QtWidgets.QVBoxLayout(ToolsList)
|
||||
self.verticalLayout.setObjectName("verticalLayout")
|
||||
self.filter_lineedit = QtWidgets.QLineEdit(ToolsList)
|
||||
self.filter_lineedit.setClearButtonEnabled(True)
|
||||
self.filter_lineedit.setObjectName("filter_lineedit")
|
||||
self.verticalLayout.addWidget(self.filter_lineedit)
|
||||
self.scrollArea = QtWidgets.QScrollArea(ToolsList)
|
||||
self.scrollArea.setWidgetResizable(True)
|
||||
self.scrollArea.setObjectName("scrollArea")
|
||||
self.content_widget = QtWidgets.QWidget()
|
||||
self.content_widget.setGeometry(QtCore.QRect(0, 0, 308, 306))
|
||||
self.content_widget.setObjectName("content_widget")
|
||||
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.content_widget)
|
||||
self.verticalLayout_2.setObjectName("verticalLayout_2")
|
||||
self.scrollArea.setWidget(self.content_widget)
|
||||
self.verticalLayout.addWidget(self.scrollArea)
|
||||
|
||||
self.retranslateUi(ToolsList)
|
||||
QtCore.QMetaObject.connectSlotsByName(ToolsList)
|
||||
|
||||
def retranslateUi(self, ToolsList):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
ToolsList.setWindowTitle(_translate("ToolsList", "Form"))
|
||||
@@ -0,0 +1,55 @@
|
||||
# Copyright (C) 2008-2022 The Paparazzi Team
|
||||
# released under GNU GPLv2 or later. See COPYING file.
|
||||
from PyQt5.QtWidgets import *
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
from generated.ui_conf_header import Ui_ConfHeader
|
||||
import conf
|
||||
|
||||
|
||||
class HeaderWidget(QWidget, Ui_ConfHeader):
|
||||
|
||||
set_changed = QtCore.pyqtSignal(str)
|
||||
ac_changed = QtCore.pyqtSignal(str)
|
||||
id_changed = QtCore.pyqtSignal(int)
|
||||
|
||||
def __init__(self, parent=None):
|
||||
QWidget.__init__(self, parent=parent)
|
||||
self.setupUi(self)
|
||||
self.set_combo.currentTextChanged.connect(self.set_changed)
|
||||
self.ac_combo.currentTextChanged.connect(self.ac_changed)
|
||||
self.id_spinBox.valueChanged.connect(self.id_changed)
|
||||
self.menu_button.addAction(self.rename_action)
|
||||
self.menu_button.addAction(self.new_ac_action)
|
||||
self.menu_button.addAction(self.duplicate_action)
|
||||
self.menu_button.addAction(self.remove_ac_action)
|
||||
|
||||
def set_sets(self, sets, conf_init: str = None):
|
||||
self.set_combo.addItems(sets)
|
||||
if conf_init in sets:
|
||||
self.set_combo.setCurrentText(conf_init)
|
||||
|
||||
def set_acs(self, acs):
|
||||
self.ac_combo.clear()
|
||||
self.ac_combo.addItems(acs)
|
||||
|
||||
def set_ac(self, ac: conf.Aircraft):
|
||||
self.id_spinBox.setValue(ac.ac_id)
|
||||
self.set_color(ac.get_color())
|
||||
|
||||
def remove_current(self):
|
||||
i = self.ac_combo.currentIndex()
|
||||
self.ac_combo.removeItem(i)
|
||||
|
||||
def set_current(self, ac_name):
|
||||
self.ac_combo.setCurrentText(ac_name)
|
||||
|
||||
def add_ac(self, ac_name):
|
||||
self.ac_combo.addItem(ac_name)
|
||||
self.set_current(ac_name)
|
||||
|
||||
def rename_ac(self, new_name):
|
||||
i = self.ac_combo.currentIndex()
|
||||
self.ac_combo.setItemText(i, new_name)
|
||||
|
||||
def set_color(self, color: str):
|
||||
self.color_button.setStyleSheet("background-color: {};".format(color))
|
||||
@@ -1,107 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg id="svg7698" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs id="defs7700">
|
||||
<linearGradient id="linearGradient3140" y2="31.211" gradientUnits="userSpaceOnUse" x2="23.576" gradientTransform="matrix(.41578 -.41749 .51898 .51462 -15.747 2.6504)" y1="25.357" x1="23.576">
|
||||
<stop id="stop2541" style="stop-color:#181818" offset="0"/>
|
||||
<stop id="stop2543" style="stop-color:#dbdbdb" offset=".13483"/>
|
||||
<stop id="stop2545" style="stop-color:#a4a4a4" offset=".20224"/>
|
||||
<stop id="stop2547" style="stop-color:#fff" offset=".26966"/>
|
||||
<stop id="stop2549" style="stop-color:#8d8d8d" offset=".44650"/>
|
||||
<stop id="stop2551" style="stop-color:#959595" offset=".57114"/>
|
||||
<stop id="stop2553" style="stop-color:#cecece" offset=".72038"/>
|
||||
<stop id="stop2555" style="stop-color:#181818" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient3142" y2="30" gradientUnits="userSpaceOnUse" x2="30.038" gradientTransform="matrix(.40402 -.40569 .60738 .60227 -17.868 .69303)" y1="24.99" x1="30.038">
|
||||
<stop id="stop2559" style="stop-color:#565656" offset="0"/>
|
||||
<stop id="stop2561" style="stop-color:#9a9a9a" offset=".5"/>
|
||||
<stop id="stop2563" style="stop-color:#545454" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient3144" y2="30" gradientUnits="userSpaceOnUse" x2="30.038" gradientTransform="matrix(.40402 -.40569 .60738 .60227 -17.983 .80921)" y1="24.99" x1="30.038">
|
||||
<stop id="stop2567" style="stop-color:#b1b1b1" offset="0"/>
|
||||
<stop id="stop2569" style="stop-color:#fff" offset=".5"/>
|
||||
<stop id="stop2571" style="stop-color:#8f8f8f" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient3146" y2="30" gradientUnits="userSpaceOnUse" x2="30.038" gradientTransform="matrix(.40402 -.40569 .60738 .60227 -17.466 .28929)" y1="24.99" x1="30.038">
|
||||
<stop id="stop2575" style="stop-color:#565656" offset="0"/>
|
||||
<stop id="stop2577" style="stop-color:#9a9a9a" offset=".5"/>
|
||||
<stop id="stop2579" style="stop-color:#545454" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient3148" y2="30" gradientUnits="userSpaceOnUse" x2="30.038" gradientTransform="matrix(.40402 -.40569 .60738 .60227 -17.581 .40547)" y1="24.99" x1="30.038">
|
||||
<stop id="stop2583" style="stop-color:#b1b1b1" offset="0"/>
|
||||
<stop id="stop2585" style="stop-color:#fff" offset=".5"/>
|
||||
<stop id="stop2587" style="stop-color:#8f8f8f" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient3150" y2="30" gradientUnits="userSpaceOnUse" x2="30.038" gradientTransform="matrix(.40402 -.40569 .60738 .60227 -17.062 -.11641)" y1="24.99" x1="30.038">
|
||||
<stop id="stop2591" style="stop-color:#565656" offset="0"/>
|
||||
<stop id="stop2593" style="stop-color:#9a9a9a" offset=".5"/>
|
||||
<stop id="stop2595" style="stop-color:#545454" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient3152" y2="30" gradientUnits="userSpaceOnUse" x2="30.038" gradientTransform="matrix(.40402 -.40569 .60738 .60227 -17.177 -.00021970)" y1="24.99" x1="30.038">
|
||||
<stop id="stop2599" style="stop-color:#b1b1b1" offset="0"/>
|
||||
<stop id="stop2601" style="stop-color:#fff" offset=".5"/>
|
||||
<stop id="stop2603" style="stop-color:#8f8f8f" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient3154" y2="26.03" gradientUnits="userSpaceOnUse" x2="9" gradientTransform="matrix(.40402 -.40569 .60738 .60227 -17.637 .46249)" y1="29.057" x1="9">
|
||||
<stop id="stop2607" style="stop-color:#ece5a5" offset="0"/>
|
||||
<stop id="stop2609" style="stop-color:#fcfbf2" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient3156" y2="41.392" gradientUnits="userSpaceOnUse" x2="9.5221" gradientTransform="matrix(.37638 .036153 0.0367 .37487 -2.2183 -1.1331)" y1="37.372" x1="5.5179">
|
||||
<stop id="stop2613" style="stop-color:#dbce48" offset="0"/>
|
||||
<stop id="stop2615" style="stop-color:#c5b625" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient3735" y2="2.001" gradientUnits="userSpaceOnUse" x2="2" y1="18.001" x1="2">
|
||||
<stop id="stop3106-1" style="stop-color:#969696" offset="0"/>
|
||||
<stop id="stop3108-2" style="stop-color:#bebebe" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient3737" y2="17.001" gradientUnits="userSpaceOnUse" x2="6" y1="4.001" x1="6">
|
||||
<stop id="stop3602-9" style="stop-color:#fff" offset="0"/>
|
||||
<stop id="stop3604-4" style="stop-color:#e6e6e6" offset="1"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="g3433">
|
||||
<g id="layer1-3" transform="translate(0 -2.001)">
|
||||
<path id="path2855" style="stroke-linejoin:round;stroke:url(#linearGradient3735);stroke-linecap:round;fill:url(#linearGradient3737)" d="m0.54277 2.501 12.957 0.01 0.042 14.99h-12.999l-1e-8 -15z"/>
|
||||
<g id="g4198" style="fill:#999" transform="matrix(1.0195 0 0 1 29.21 6.7744)">
|
||||
<path id="path6035" style="opacity:.7;fill:#686868" d="m-25.666-1.7733h1.1241v1h-1.1241v-1z"/>
|
||||
<path id="path6033" style="opacity:.7;fill:#686868" d="m-24.388-1.7733h1.0606v1h-1.0606v-1z"/>
|
||||
<path id="path6031" style="opacity:.7;fill:#686868" d="m-23.175-1.7733h0.93368v1h-0.93368v-1z"/>
|
||||
<path id="path6029" style="opacity:.7;fill:#686868" d="m-22.088-1.7733h0.41011v1h-0.41011v-1z"/>
|
||||
<path id="path6027" style="opacity:.7;fill:#686868" d="m-21.525-1.7733h0.91782v1h-0.91782v-1z"/>
|
||||
<path id="path6025" style="opacity:.7;fill:#686868" d="m-20.454-1.7733h2.3775v1h-2.3775v-1z"/>
|
||||
<path id="path6017" style="opacity:.7;fill:#686868" d="m-25.666 4.2267h1.1241v1h-1.1241v-1z"/>
|
||||
<path id="path6015" style="opacity:.7;fill:#686868" d="m-24.388 4.2267h1.0606v1h-1.0606v-1z"/>
|
||||
<path id="path6013" style="opacity:.7;fill:#686868" d="m-23.175 4.2267h0.93368v1h-0.93368v-1z"/>
|
||||
<path id="path6011" style="opacity:.7;fill:#686868" d="m-22.088 4.2267h0.41011v1h-0.41011v-1z"/>
|
||||
<path id="path6009" style="opacity:.7;fill:#686868" d="m-21.525 4.2267h0.91781v1h-0.91781v-1z"/>
|
||||
<path id="path5999" style="opacity:.7;fill:#686868" d="m-25.666 0.22666h1.7428v1h-1.7428v-1z"/>
|
||||
<path id="path5997" style="opacity:.7;fill:#686868" d="m-23.764 0.22666h0.83849v1h-0.83849v-1z"/>
|
||||
<path id="path5995" style="opacity:.7;fill:#686868" d="m-22.766 0.22666h0.39424v1h-0.39424v-1z"/>
|
||||
<path id="path5993" style="opacity:.7;fill:#686868" d="m-22.213 0.22666h0.75916v1h-0.75916v-1z"/>
|
||||
<path id="path5991" style="opacity:.7;fill:#686868" d="m-21.295 0.22666h0.75916v1h-0.75916v-1z"/>
|
||||
<path id="path5989" style="opacity:.7;fill:#686868" d="m-20.376 0.22666h1.2193v1h-1.2193v-1z"/>
|
||||
<path id="path5981" style="opacity:.7;fill:#686868" d="m-25.666 2.2267h1.9967v1h-1.9967v-1z"/>
|
||||
<path id="path5979" style="opacity:.7;fill:#686868" d="m-23.512 2.2267h2.1395v1h-2.1395v-1z"/>
|
||||
<path id="path5977" style="opacity:.7;fill:#686868" d="m-21.216 2.2267h0.85436v1h-0.85436v-1z"/>
|
||||
<path id="path5975" style="opacity:.7;fill:#686868" d="m-20.205 2.2267h2.0125v1h-2.0125v-1z"/>
|
||||
<path id="path2916" style="opacity:.7;fill:#686868" d="m-25.666 6.2267h1.1241v1h-1.1241v-1z"/>
|
||||
<path id="path2918" style="opacity:.7;fill:#686868" d="m-24.388 6.2267h1.0606v1h-1.0606v-1z"/>
|
||||
<path id="path2920" style="opacity:.7;fill:#686868" d="m-23.175 6.2267h0.93368v1h-0.93368v-1z"/>
|
||||
</g>
|
||||
<path id="path2422" style="opacity:.15;fill:#0c0c0c;fill-rule:evenodd" d="m13.297 7.7055c-0.08415-0.04997-0.14927-0.03697-0.19229-0.0092l-5.7296 3.6801-1.0545 0.67922-0.03247 0.01374-1.2485 2.8377 3.0941 0.094 0.02569-0.01734 1.0613-0.67562 5.7281-3.7118c0.171-0.111-0.101-0.848-0.611-1.656-0.383-0.606-0.789-1.0846-1.041-1.2345z"/>
|
||||
</g>
|
||||
<g id="g8626" transform="matrix(.70258 0 0 .70426 5.0317 1.6629)">
|
||||
<path id="path3041" style="stroke-linejoin:round;stroke:#0c0c0c;stroke-width:.60798;fill:url(#linearGradient3140)" d="m2.0488 11.037c0.28654-0.20771 1.148 0.25639 1.9603 1.0619 0.81045 0.80363 1.2602 1.6413 1.0576 1.9306-0.0007708 0.0011 0.01977 0.01774 0.01898 0.01882l10.138-10.18c0.258-0.2581-0.213-1.1432-1.051-1.9744-0.838-0.8311-1.728-1.295-1.986-1.0366l-10.138 10.18z"/>
|
||||
<path id="path3043" style="opacity:.8;stroke-linejoin:round;stroke:#e28ccd;stroke-width:.60798;fill:#ffb6ed" d="m10.565 2.4841c0.28654-0.20771 1.148 0.25639 1.9603 1.0619 0.81044 0.80363 1.2602 1.6413 1.0576 1.9306-0.000769 0.0011 0.01977 0.017738 0.01898 0.018821l1.552-1.5571c0.409-0.4086-0.029-1.0928-0.981-2.0447-0.813-0.8055-1.674-1.2696-1.96-1.0619l-0.02525 0.025356-1.6218 1.6271z"/>
|
||||
<path id="path3045" style="opacity:.6;fill:#0c0c0c" d="m2.0488 11.037c0.28654-0.20771 1.148 0.25639 1.9603 1.0619 0.81044 0.80363 1.2602 1.6413 1.0576 1.9306-0.0007714 0.0011 0.01977 0.01774 0.01898 0.01882l6.982-7.0109 0.02525-0.025356c0.00079-0.00108-0.01975-0.01772-0.01898-0.01882 0.203-0.2885-0.247-1.1262-1.058-1.9298-0.812-0.8056-1.6734-1.2697-1.9599-1.062l-0.025251 0.025355-6.982 7.0109z"/>
|
||||
<path id="path3047" style="fill:url(#linearGradient3142)" d="m9.1785 3.8767c0.28654-0.20771 1.148 0.25639 1.9603 1.0619 0.81044 0.80363 1.2602 1.6413 1.0576 1.9306-0.000771 0.0011 0.01977 0.017736 0.01898 0.01882l0.12626-0.12678c0.00079-0.00108-0.01975-0.01772-0.01898-0.01882 0.203-0.2892-0.246-1.1269-1.057-1.9305-0.812-0.8056-1.6737-1.2697-1.9602-1.062l-0.12626 0.12678z"/>
|
||||
<path id="path3049" style="fill:url(#linearGradient3144)" d="m9.0628 3.9929c0.28654-0.20771 1.148 0.25639 1.9603 1.0619 0.81044 0.80363 1.2602 1.6413 1.0576 1.9306-0.000771 0.0011 0.01977 0.017738 0.01898 0.018822l0.126-0.1268c0.00079-0.00108-0.01975-0.017721-0.01898-0.018821 0.203-0.2892-0.247-1.1269-1.058-1.9305-0.812-0.8056-1.6734-1.2697-1.9599-1.062l-0.1263 0.1268z"/>
|
||||
<path id="path3051" style="fill:url(#linearGradient3146)" d="m9.5806 3.473c0.28654-0.20771 1.148 0.25639 1.9603 1.0619 0.81045 0.80363 1.2602 1.6413 1.0576 1.9306-0.000773 0.0011 0.01977 0.017737 0.01898 0.01882l0.12626-0.12678c0.000791-0.00108-0.01975-0.017721-0.01898-0.01882 0.202-0.2892-0.247-1.1269-1.058-1.9306-0.812-0.8055-1.6736-1.2696-1.9601-1.0619l-0.1263 0.1268z"/>
|
||||
<path id="path3053" style="fill:url(#linearGradient3148)" d="m9.4649 3.5891c0.28654-0.20771 1.148 0.25639 1.9603 1.0619 0.81045 0.80363 1.2602 1.6413 1.0576 1.9306-0.000769 0.0011 0.01977 0.017737 0.01898 0.018821l0.12626-0.12678c0.00079-0.00108-0.01975-0.01772-0.01898-0.01882 0.203-0.2892-0.247-1.1269-1.057-1.9305-0.813-0.8055-1.6743-1.2696-1.9608-1.0619l-0.1263 0.1267z"/>
|
||||
<path id="path3055" style="fill:url(#linearGradient3150)" d="m9.9846 3.0673c0.2864-0.2077 1.1484 0.2564 1.9604 1.0619 0.81045 0.80363 1.2602 1.6413 1.0576 1.9306-0.00077 0.0011 0.01977 0.017738 0.01898 0.018821l0.126-0.1268c0.000792-0.00108-0.01975-0.017721-0.01898-0.018821 0.202-0.2892-0.247-1.1269-1.058-1.9306-0.812-0.8055-1.674-1.2696-1.96-1.0619l-0.1264 0.1268z"/>
|
||||
<path id="path3057" style="fill:url(#linearGradient3152)" d="m9.8689 3.1835c0.28654-0.20771 1.148 0.25639 1.9603 1.0619 0.81044 0.80363 1.2602 1.6413 1.0576 1.9306-0.000771 0.0011 0.01977 0.017737 0.01898 0.018821l0.12626-0.12678c0.000789-0.00108-0.01975-0.017722-0.01898-0.018821 0.203-0.2892-0.247-1.1269-1.057-1.9306-0.813-0.8055-1.674-1.2696-1.9608-1.0619l-0.1263 0.1268z"/>
|
||||
<path id="path3059" style="fill-rule:evenodd;stroke:url(#linearGradient3156);stroke-width:.60798;fill:url(#linearGradient3154)" d="m0.25981 15.794 4.7719-1.7255 0.039308-0.03926c0.2026-0.289-0.2524-1.127-1.0629-1.93-0.8124-0.806-1.6727-1.268-1.9592-1.06l-1.7891 4.755z"/>
|
||||
<path id="path3061" style="fill-rule:evenodd;stroke:#0c0c0c;stroke-width:.60798;fill:#0c0c0c" d="m0.74443 14.506-0.48521 1.283 1.3014-0.473c-0.1137-0.134-0.2193-0.268-0.3544-0.402-0.1555-0.154-0.30705-0.281-0.46177-0.408z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 12 KiB |
@@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg id="svg2395" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs id="defs2397">
|
||||
<linearGradient id="linearGradient2427" y2="31.138" gradientUnits="userSpaceOnUse" x2="-93.088" gradientTransform="matrix(.42104 -.10139 .10080 .42350 44.055 -5.0894)" y1="2.0691" x1="-86.129">
|
||||
<stop id="stop2266" style="stop-color:#d7e866" offset="0"/>
|
||||
<stop id="stop2268" style="stop-color:#8cab2a" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient2431" y2="39.78" gradientUnits="userSpaceOnUse" x2="20.494" gradientTransform="matrix(.41388 0 0 .41629 -1.7222 -1.7776)" y1="7.044" x1="20.494">
|
||||
<stop id="stop3402" style="stop-color:#fff" offset="0"/>
|
||||
<stop id="stop3404" style="stop-color:#fff;stop-opacity:0" offset="1"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="layer1">
|
||||
<path id="path1542" style="stroke-linejoin:round;stroke:#699536;stroke-linecap:round;stroke-width:1.0028;fill:url(#linearGradient2427)" d="m12.262 0.50446c-0.232-0.02365-0.462 0.09048-0.581 0.30958l-5.0718 9.333-3.2606-2.6075c-0.2904-0.1597-0.6528-0.057-0.8115 0.2352l-1.4622 1.8882c-0.1587 0.29213-0.051938 0.6565 0.2385 0.81613 0 0 5.9534 4.9457 5.9608 4.9493 0.068071 0.03741 0.13926 0.05624 0.21162 0.06544 0.23638 0.03004 0.47828-0.08166 0.59979-0.30532l6.8394-12.586c0.1587-0.29213 0.05194-0.6565-0.2385-0.81613l-2.194-1.2118c-0.073-0.03986-0.153-0.06176-0.23-0.06964z"/>
|
||||
<path id="path2429" style="opacity:.4;stroke:url(#linearGradient2431);stroke-linecap:round;stroke-width:1.0028;fill:none" d="m12.312 1.6562-5.312 9.8128a0.15035 0.15035 0 0 1 0 0.031 0.15035 0.15035 0 0 1 -0.03125 0.03125 0.15035 0.15035 0 0 1 -0.03125 0 0.15035 0.15035 0 0 1 -0.03125 0.03125 0.15035 0.15035 0 0 1 -0.03125 0 0.15035 0.15035 0 0 1 -0.03125 0 0.15035 0.15035 0 0 1 -0.03125 -0.03125 0.15035 0.15035 0 0 1 -0.03125 0l-3.6562-2.906c-0.32388 0.40246-0.60092 0.77792-0.96875 1.25 0.1123 0.093077 1.303 1.09 2.625 2.1875 0.6912 0.57379 1.3815 1.1568 1.9062 1.5938 0.26235 0.21848 0.4994 0.39983 0.65625 0.53125 0.050142 0.04201 0.088455 0.06296 0.125 0.09375 0.052555-0.09355 0.10901-0.18055 0.25-0.4375 0.19196-0.34986 0.43971-0.83698 0.75-1.4062 0.62059-1.1385 1.4445-2.6103 2.25-4.0938 0.80552-1.4834 1.5812-2.9751 2.1875-4.0938 0.30316-0.55933 0.56868-1.0087 0.75-1.3438 0.14198-0.26236 0.21072-0.36449 0.25-0.4375-0.055-0.0314-0.1-0.0615-0.218-0.125-0.172-0.0919-0.379-0.1999-0.594-0.3126-0.215-0.1126-0.432-0.2271-0.594-0.3124-0.067-0.0354-0.141-0.0375-0.188-0.0626z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.6 KiB |
@@ -1,28 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg id="svg3251" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.0" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs id="defs3253">
|
||||
<linearGradient id="linearGradient2406" y2="5.4676" gradientUnits="userSpaceOnUse" x2="63.397" gradientTransform="matrix(.74324 0 0 .74322 -38.23 10.609)" y1="-12.489" x1="63.397">
|
||||
<stop id="stop4875" style="stop-color:#fff" offset="0"/>
|
||||
<stop id="stop4877" style="stop-color:#fff;stop-opacity:0" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient2411" y2="3.0816" gradientUnits="userSpaceOnUse" x2="18.379" gradientTransform="matrix(.36857 0 0 .36857 -.84577 -.84577)" y1="44.98" x1="18.379">
|
||||
<stop id="stop2492" style="stop-color:#791235" offset="0"/>
|
||||
<stop id="stop2494" style="stop-color:#dd3b27" offset="1"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="radialGradient2409" gradientUnits="userSpaceOnUse" cy="3.99" cx="23.896" gradientTransform="matrix(0 .87966 -1.1611 0 12.633 -21.084)" r="20.397">
|
||||
<stop id="stop3244" style="stop-color:#f8b17e" offset="0"/>
|
||||
<stop id="stop3246" style="stop-color:#e35d4f" offset=".26238"/>
|
||||
<stop id="stop3248" style="stop-color:#c6262e" offset=".66094"/>
|
||||
<stop id="stop3250" style="stop-color:#690b54" offset="1"/>
|
||||
</radialGradient>
|
||||
</defs>
|
||||
<g id="layer1">
|
||||
<g id="g3275">
|
||||
<path id="path2555" style="stroke-linejoin:round;stroke:url(#linearGradient2411);stroke-linecap:round;stroke-width:1.0037;fill:url(#radialGradient2409)" d="m8 0.50183c-4.1372 0-7.4982 3.361-7.4982 7.4982 0.00003 4.137 3.361 7.498 7.4982 7.498 4.137 0 7.498-3.361 7.498-7.498 0-4.1372-3.361-7.4982-7.498-7.4982z"/>
|
||||
<path id="path2463" style="opacity:.4;stroke:url(#linearGradient2406);fill:none" d="m14.5 7.9998c0 3.5902-2.91 6.5002-6.4999 6.5002s-6.5001-2.91-6.5001-6.5002c0-3.5898 2.9102-6.4998 6.5001-6.4998s6.4999 2.91 6.4999 6.4998z"/>
|
||||
</g>
|
||||
<path id="path3360" style="opacity:.2" d="m3 8h10v-2h-10v2z"/>
|
||||
<path id="path3249" style="fill:#fff" d="m3 9h10v-2h-10v2z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.1 KiB |
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg id="svg7384" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<metadata id="metadata90">
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title>Gnome Symbolic Icon Theme</dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<title id="title9167">Gnome Symbolic Icon Theme</title>
|
||||
<g id="layer9" transform="translate(-321,-257)">
|
||||
<path id="path18112" style="color:#bebebe;enable-background:new;fill:#bebebe" d="m328.92 257.09c-0.5255-0.0286-1.0382 0.28305-1.4375 0.96875l-6.25 11.594c-0.53 0.97 0.05 2.35 1.1 2.35h13.156c0.98172 0 1.9031-1.1594 1.2188-2.3438l-6.32-11.54c-0.39872-0.64617-0.94325-1.0026-1.4688-1.0312zm-0.0313 3.9375c0.54448-0.0172 1.0485 0.48677 1.0312 1.0312v3.9375c0.007 0.52831-0.47163 1.0142-1 1.0142-0.52836 0-1.0075-0.48593-1-1.0142v-3.9375c-0.008-0.4666 0.3541-0.91253 0.8125-1 0.0511-0.0145 0.10345-0.025 0.15625-0.0313zm-0.9687 6.9688h2v2h-2v-2z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 371 B |
@@ -1,16 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg id="svg4002" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.0" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs id="defs4004">
|
||||
<linearGradient id="linearGradient3645" y2="15" xlink:href="#linearGradient3587-6-5-3" gradientUnits="userSpaceOnUse" x2="7.9995" gradientTransform="translate(-.99952 1)" y1="1" x1="7.9995"/>
|
||||
<linearGradient id="linearGradient3653" y2="12" xlink:href="#linearGradient3587-6-5-3" gradientUnits="userSpaceOnUse" x2="8.9995" gradientTransform="translate(1.0005 1)" y1="3" x1="8.9995"/>
|
||||
<linearGradient id="linearGradient3587-6-5-3">
|
||||
<stop id="stop3589-9-2-2" offset="0"/>
|
||||
<stop id="stop3591-7-4-73" style="stop-color:#363636" offset="1"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path id="path3655" style="opacity:.6;block-progression:tb;text-indent:0;color:#000000;text-transform:none;fill:#fff" d="m4.2192 5.0003-0.03125 0.03125c-0.13929 0.056469-0.26082 0.1559-0.34375 0.28125l-3 4.25c-0.18164 0.25295-0.18164 0.62205 0 0.875l3 4.25c0.082937 0.12535 0.20446 0.22478 0.34375 0.28125l0.03125 0.03125h0.125 0.15625c0.020821 0.000868 0.041679 0.000868 0.0625 0h9.9375 0.5v-0.5-9-0.5h-0.5-9.875-0.0625c-0.020821-0.0008682-0.041679-0.0008682-0.0625 0h-0.1875-0.09375zm0.9375 1h8.8438v8h-8.8125c-0.031927-0.06831-0.074226-0.13176-0.125-0.1875l-2.6875-3.8125 2.6875-3.8125c0.039807-0.057709 0.071467-0.12103 0.09375-0.1875z"/>
|
||||
<path id="path3657" style="opacity:.6;block-progression:tb;text-indent:0;color:#bebebe;enable-background:new;text-transform:none;fill:#fff" d="m7.0036 7.0006h1c0.01037-0.00012 0.02079-0.00046 0.03125 0 0.25495 0.0112 0.50987 0.12858 0.6875 0.3125l1.2812 1.2812 1.3125-1.2812c0.26562-0.2305 0.44667-0.3055 0.6875-0.3125h1v1c0 0.28647-0.03434 0.55065-0.25 0.75l-1.2812 1.2813 1.25 1.25c0.18819 0.18817 0.28124 0.45345 0.28125 0.71875v1h-1c-0.2653-0.00001-0.53059-0.0931-0.71875-0.28125l-1.2812-1.2812-1.2812 1.2812c-0.18816 0.18819-0.45346 0.28125-0.71875 0.28125h-1v-1c-0.000003-0.26529 0.09306-0.53058 0.28125-0.71875l1.2812-1.25-1.2812-1.2813c-0.21074-0.19463-0.30316-0.46925-0.28125-0.75v-1z"/>
|
||||
<path id="path2836" style="opacity:.7;block-progression:tb;text-indent:0;color:#000000;text-transform:none;fill:url(#linearGradient3645)" d="m4.2192 4-0.03125 0.03125c-0.1393 0.0565-0.2608 0.1559-0.3438 0.2813l-2.7002 4.25c-0.18164 0.25295-0.18164 0.62205 0 0.875l2.7002 4.25c0.082937 0.12535 0.20446 0.22478 0.34375 0.28125l0.0312 0.031h0.125 0.15625c0.020821 0.000868 0.041679 0.000868 0.0625 0h9.9375 0.5v-0.5-9-0.5h-0.5-9.875-0.0625c-0.020821-0.0008682-0.041679-0.0008682-0.0625 0h-0.1875-0.09375zm0.9375 1h8.8438v8h-8.8125c-0.031927-0.06831-0.074226-0.13176-0.125-0.1875l-2.687-3.812 2.6875-3.8125c0.0398-0.0577 0.0714-0.121 0.0937-0.1875z"/>
|
||||
<path id="path10839" style="opacity:.7;block-progression:tb;text-indent:0;color:#bebebe;enable-background:new;text-transform:none;fill:url(#linearGradient3653)" d="m7.0036 6.0002h1c0.01037-0.00012 0.02079-0.00046 0.03125 0 0.25495 0.0112 0.50987 0.12858 0.6875 0.3125l1.2812 1.2812 1.3125-1.2812c0.26562-0.2305 0.44667-0.3055 0.6875-0.3125h1v1c0 0.28647-0.03434 0.55065-0.25 0.75l-1.2812 1.2812 1.25 1.25c0.18819 0.18817 0.28124 0.45345 0.28125 0.71875v1h-1c-0.2653-0.00001-0.53059-0.0931-0.71875-0.28125l-1.2812-1.2812-1.2813 1.2812c-0.18816 0.18819-0.45346 0.28125-0.71875 0.28125h-1v-1c-0.000003-0.26529 0.09306-0.53058 0.28125-0.71875l1.2811-1.2495-1.2812-1.2813c-0.21074-0.19463-0.30316-0.46925-0.28125-0.75v-1z"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 3.5 KiB |
@@ -1,28 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg id="svg3691" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs id="defs3693">
|
||||
<linearGradient id="linearGradient4884" y2="224.68" gradientUnits="userSpaceOnUse" x2="31.341" y1="235.03" x1="31.341">
|
||||
<stop id="stop4024-2-8" style="stop-color:#555753" offset="0"/>
|
||||
<stop id="stop4026-8-3" style="stop-color:#babdb6" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient3655" y2="225" gradientUnits="userSpaceOnUse" x2="23.5" y1="225" x1="34.5">
|
||||
<stop id="stop2605-6" style="stop-color:#bb2b12" offset="0"/>
|
||||
<stop id="stop2607-3" style="stop-color:#cd7233" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient3663" y2="229" gradientUnits="userSpaceOnUse" x2="35.5" y1="229" x1="24.5">
|
||||
<stop id="stop2612-7" style="stop-color:#f0c178" offset="0"/>
|
||||
<stop id="stop2614-5" style="stop-color:#e18941" offset=".5"/>
|
||||
<stop id="stop2616-9" style="stop-color:#ec4f18" offset="1"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="layer1">
|
||||
<g id="g4946" style="enable-background:new" transform="matrix(0,1,1,0,-219,-21.5)">
|
||||
<g id="g4873" style="stroke:url(#linearGradient4884)">
|
||||
<path id="path2932-4" style="stroke-linejoin:round;stroke-width:4;stroke:url(#linearGradient3655);stroke-linecap:round;enable-background:new;fill:none" d="m32 221-5.5 5.5 5.5 5.5"/>
|
||||
</g>
|
||||
<path id="path2932" style="stroke-linejoin:round;stroke:url(#linearGradient3663);stroke-linecap:round;stroke-width:2;fill:none" d="m32 221-5.5 5.5 5.5 5.5"/>
|
||||
<path id="path2932-0-9-9" style="opacity:.4;stroke:#fff;stroke-linecap:round;enable-background:new;fill:none" d="m31.4 232-5.5-5.5 5.5-5.5"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.8 KiB |
@@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg id="svg2461" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.0" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs id="defs2463">
|
||||
<linearGradient id="linearGradient2457" y2="3.0816" gradientUnits="userSpaceOnUse" x2="18.379" gradientTransform="matrix(.36857 0 0 .36857 -.84577 -.84577)" y1="44.98" x1="18.379">
|
||||
<stop id="stop2788" style="stop-color:#1f4b6a" offset="0"/>
|
||||
<stop id="stop2790" style="stop-color:#4083c2" offset="1"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="radialGradient2455" gradientUnits="userSpaceOnUse" cy="3.99" cx="23.896" gradientTransform="matrix(0 .87966 -1.1611 0 12.633 -21.084)" r="20.397">
|
||||
<stop id="stop2778" style="stop-color:#8badea" offset="0"/>
|
||||
<stop id="stop2780" style="stop-color:#6396cd" offset=".26238"/>
|
||||
<stop id="stop2782" style="stop-color:#3b7caf" offset=".66094"/>
|
||||
<stop id="stop2784" style="stop-color:#194c70" offset="1"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="linearGradient2452" y2="5.4676" gradientUnits="userSpaceOnUse" x2="63.397" gradientTransform="matrix(.74324 0 0 .74322 -38.23 10.609)" y1="-12.489" x1="63.397">
|
||||
<stop id="stop4875" style="stop-color:#fff" offset="0"/>
|
||||
<stop id="stop4877" style="stop-color:#fff;stop-opacity:0" offset="1"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="layer1">
|
||||
<path id="path2449" style="stroke-linejoin:round;stroke:url(#linearGradient2457);stroke-linecap:round;stroke-width:1.0037;fill:url(#radialGradient2455)" d="m8 0.50183c-4.1372 0-7.4982 3.361-7.4982 7.4982 0.00003 4.137 3.361 7.498 7.4982 7.498 4.137 0 7.498-3.361 7.498-7.498 0-4.1372-3.361-7.4982-7.498-7.4982z"/>
|
||||
<path id="path2451" style="opacity:.4;stroke:url(#linearGradient2452);fill:none" d="m14.5 7.9998c0 3.5902-2.91 6.5002-6.4999 6.5002s-6.5001-2.91-6.5001-6.5002c0-3.5898 2.9102-6.4998 6.5001-6.4998s6.4999 2.91 6.4999 6.4998z"/>
|
||||
<path id="path3536" style="fill:#fff" d="m5.8809 7.6039c0.1112 0.2727 0.2329 0.4926 0.4614 0.176 0.291-0.1922 1.259-1.0222 1.1895-0.2449-0.2635 1.4439-0.5972 2.876-0.8384 4.323-0.2804 0.798 0.4546 1.481 1.1726 0.94 0.7716-0.361 1.4257-0.923 2.0961-1.441-0.1034-0.231-0.1794-0.565-0.4273-0.248-0.3352 0.171-1.0517 0.943-1.2144 0.337 0.2258-1.561 0.6984-3.0746 0.9775-4.6254 0.2848-0.7194-0.2609-1.5917-1.002-0.976-0.8996 0.4419-1.6391 1.1342-2.415 1.7593zm3.1923-5.3491c-0.936-0.0124-1.3641 1.536-0.46 1.9183 0.7319 0.2706 1.4868-0.5111 1.281-1.2531-0.07-0.3879-0.4276-0.6943-0.821-0.6652z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.5 KiB |
@@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg id="svg3247" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.0" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs id="defs3249">
|
||||
<linearGradient id="linearGradient2401" y2="34.225" gradientUnits="userSpaceOnUse" x2="24.104" gradientTransform="matrix(.70965 0 0 .70537 -8.945 -8.2363)" y1="15.181" x1="24.104">
|
||||
<stop id="stop2266" style="stop-color:#d7e866" offset="0"/>
|
||||
<stop id="stop2268" style="stop-color:#8cab2a" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient3190" y2="16.004" gradientUnits="userSpaceOnUse" x2="8" x1="8">
|
||||
<stop id="stop3182" style="stop-color:#fff" offset="0"/>
|
||||
<stop id="stop3184" style="stop-color:#fff;stop-opacity:0" offset="1"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="layer1">
|
||||
<path id="path2262" style="stroke-linejoin:round;fill-rule:evenodd;stroke:#699536;fill:url(#linearGradient2401)" d="m5.5 5.5v-5h5v5h5v5h-5v5h-5v-5h-5v-5h5z"/>
|
||||
<path id="path3188" style="opacity:.4;stroke:url(#linearGradient3190);fill:none" d="m6.5 1.5v4c-0.00481 0.55028-0.44972 0.99519-1 1h-4v3h4c0.55028 0.00481 0.99519 0.44972 1 1v4h3v-4c0.00481-0.55028 0.44972-0.99519 1-1h4v-3h-4c-0.5503-0.0048-0.9952-0.4497-1-1v-4h-3z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.3 KiB |
@@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg id="svg3247" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.0" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs id="defs3249">
|
||||
<linearGradient id="linearGradient2401" y2="29.707" gradientUnits="userSpaceOnUse" x2="23.878" gradientTransform="matrix(.70965 0 0 .70537 -8.945 -8.2363)" y1="18.765" x1="23.878">
|
||||
<stop id="stop3945" style="stop-color:#e35d4f" offset="0"/>
|
||||
<stop id="stop3947" style="stop-color:#c6262e" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient3190" y2="16.004" gradientUnits="userSpaceOnUse" x2="8" x1="8">
|
||||
<stop id="stop3182" style="stop-color:#fff" offset="0"/>
|
||||
<stop id="stop3184" style="stop-color:#fff;stop-opacity:0" offset="1"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="layer1">
|
||||
<path id="path2262" style="stroke-linejoin:round;fill-rule:evenodd;stroke:#a53738;fill:url(#linearGradient2401)" d="m15.5 5.5v5h-15v-5h15z"/>
|
||||
<path id="path3188" style="opacity:.4;stroke:url(#linearGradient3190);fill:none" d="m1.5 6.5v3h13v-3h-13z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
@@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg id="svg2829" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.0" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs id="defs2831">
|
||||
<linearGradient id="linearGradient3615">
|
||||
<stop id="stop3617" style="stop-color:#eeeeec" offset="0"/>
|
||||
<stop id="stop3619" style="stop-color:#babdb6" offset=".69580"/>
|
||||
<stop id="stop3621" style="stop-color:#a1a59b" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient2782">
|
||||
<stop id="stop2784" style="stop-color:#fff" offset="0"/>
|
||||
<stop id="stop2786" style="stop-color:#fff;stop-opacity:0" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient3627" y2="45.849" xlink:href="#linearGradient3615" gradientUnits="userSpaceOnUse" x2="-11.448" gradientTransform="matrix(.36755 0 0 .36638 8.2056 -1.7938)" y1="10.344" x1="-11.448"/>
|
||||
<linearGradient id="linearGradient3629" y2="52.94" xlink:href="#linearGradient2782" gradientUnits="userSpaceOnUse" x2="10.44" gradientTransform="matrix(.29583 0 0 .33661 8.2499 -1.1702)" y1="9.9657" x1="10.44"/>
|
||||
<linearGradient id="linearGradient3635" y2="45.849" xlink:href="#linearGradient3615" gradientUnits="userSpaceOnUse" x2="-11.448" gradientTransform="matrix(.36755 0 0 .36638 16.206 -1.7938)" y1="10.344" x1="-11.448"/>
|
||||
<linearGradient id="linearGradient3637" y2="52.94" xlink:href="#linearGradient2782" gradientUnits="userSpaceOnUse" x2="10.44" gradientTransform="matrix(.29583 0 0 .33661 16.25 -1.1702)" y1="9.9657" x1="10.44"/>
|
||||
</defs>
|
||||
<g id="layer1">
|
||||
<path id="path3623" style="stroke-linejoin:round;fill-rule:evenodd;stroke:#888a86;stroke-linecap:round;stroke-width:1.0007;fill:url(#linearGradient3627)" d="m1.5004 1.5004v12.999h4.9993v-12.999h-4.9993z"/>
|
||||
<path id="path3625" style="opacity:0.41;stroke-opacity:.97255;stroke:url(#linearGradient3629);stroke-linecap:round;stroke-width:1.0013;fill:none" d="m2.5007 2.5007v10.999l2.9983-0.0154v-10.983h-2.9983z"/>
|
||||
<path id="path3631" style="stroke-linejoin:round;fill-rule:evenodd;stroke:#888a86;stroke-linecap:round;stroke-width:1.0007;fill:url(#linearGradient3635)" d="m9.5004 1.5004v12.999h4.9993v-12.999h-4.9993z"/>
|
||||
<path id="path3633" style="opacity:0.41;stroke-opacity:.97255;stroke:url(#linearGradient3637);stroke-linecap:round;stroke-width:1.0013;fill:none" d="m10.501 2.5007v10.999l2.9983-0.0154v-10.983h-2.9983z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.4 KiB |
@@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg id="svg2397" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs id="defs2399">
|
||||
<linearGradient id="linearGradient2395" y2="43.878" gradientUnits="userSpaceOnUse" x2="18.037" gradientTransform="matrix(.42222 0 0 .38297 -3.1322 -1.1011)" y1="14.511" x1="18.037">
|
||||
<stop id="stop2266" style="stop-color:#d7e866" offset="0"/>
|
||||
<stop id="stop2268" style="stop-color:#8cab2a" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient2392" y2="46.874" gradientUnits="userSpaceOnUse" x2="13.759" gradientTransform="matrix(.35126 0 0 .34884 -.99223 -.37226)" y1="14.66" x1="34.404">
|
||||
<stop id="stop4224" style="stop-color:#fff" offset="0"/>
|
||||
<stop id="stop4226" style="stop-color:#fff;stop-opacity:0" offset="1"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="layer1">
|
||||
<path id="path3375" style="stroke-linejoin:round;fill-rule:evenodd;stroke:#548820;stroke-linecap:round;fill:url(#linearGradient2395)" d="m1.5 14.5v-13l13 6.5-13 6.5z"/>
|
||||
<path id="path2294" style="opacity:0.41;stroke:url(#linearGradient2392);stroke-linecap:round;fill:none" d="m2.5 12.878v-9.778l9.841 4.9-9.841 4.878z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
@@ -1,28 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg id="svg2528" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.0" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs id="defs2530">
|
||||
<linearGradient id="linearGradient2406" y2="5.4676" gradientUnits="userSpaceOnUse" x2="63.397" gradientTransform="matrix(.74324 0 0 .74322 -38.23 10.609)" y1="-12.489" x1="63.397">
|
||||
<stop id="stop4875" style="stop-color:#fff" offset="0"/>
|
||||
<stop id="stop4877" style="stop-color:#fff;stop-opacity:0" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient2411" y2="3.0816" gradientUnits="userSpaceOnUse" x2="18.379" gradientTransform="matrix(.36857 0 0 .36857 -.84577 -.84577)" y1="44.98" x1="18.379">
|
||||
<stop id="stop2492" style="stop-color:#791235" offset="0"/>
|
||||
<stop id="stop2494" style="stop-color:#dd3b27" offset="1"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="radialGradient2409" gradientUnits="userSpaceOnUse" cy="3.99" cx="23.896" gradientTransform="matrix(0 .87966 -1.1611 0 12.633 -21.084)" r="20.397">
|
||||
<stop id="stop3244" style="stop-color:#f8b17e" offset="0"/>
|
||||
<stop id="stop3246" style="stop-color:#e35d4f" offset=".26238"/>
|
||||
<stop id="stop3248" style="stop-color:#c6262e" offset=".66094"/>
|
||||
<stop id="stop3250" style="stop-color:#690b54" offset="1"/>
|
||||
</radialGradient>
|
||||
</defs>
|
||||
<g id="layer1">
|
||||
<g id="g2552">
|
||||
<path id="path2555" style="stroke-linejoin:round;stroke:url(#linearGradient2411);stroke-linecap:round;stroke-width:1.0037;fill:url(#radialGradient2409)" d="m8 0.50183c-4.1372 0-7.4982 3.361-7.4982 7.4982 0.00003 4.137 3.361 7.498 7.4982 7.498 4.137 0 7.498-3.361 7.498-7.498 0-4.1372-3.361-7.4982-7.498-7.4982z"/>
|
||||
<path id="path2463" style="opacity:.4;stroke:url(#linearGradient2406);fill:none" d="m14.5 7.9998c0 3.5902-2.91 6.5002-6.4999 6.5002s-6.5001-2.91-6.5001-6.5002c0-3.5898 2.9102-6.4998 6.5001-6.4998s6.4999 2.91 6.4999 6.4998z"/>
|
||||
</g>
|
||||
<path id="path3243" style="opacity:.2;fill-rule:evenodd" d="m5.2625 3l-1.2625 1.2625 2.6047 2.5913c0.08 0.081 0.08 0.2114 0 0.2924l-2.6047 2.5913 1.2625 1.2625 2.5913-2.5914c0.081-0.08 0.2114-0.08 0.2924 0l2.5918 2.5914 1.262-1.2625-2.5914-2.5913c-0.08-0.081-0.08-0.2114 0-0.2924l2.5914-2.5913-1.262-1.2625-2.5918 2.5914c-0.081 0.08-0.2114 0.08-0.2924 0l-2.5913-2.5914z"/>
|
||||
<path id="path3256" style="fill:#fff;fill-rule:evenodd" d="m5.2625 4l-1.2625 1.2625 2.6047 2.5913c0.08 0.081 0.08 0.2114 0 0.2924l-2.6047 2.5918 1.2625 1.262 2.5913-2.5914c0.081-0.08 0.2114-0.08 0.2924 0l2.5918 2.5914 1.262-1.262-2.5914-2.5918c-0.08-0.081-0.08-0.2114 0-0.2924l2.5914-2.5913-1.262-1.2625-2.5918 2.5914c-0.081 0.08-0.2114 0.08-0.2924 0l-2.5913-2.5914z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 290 B |
|
Before Width: | Height: | Size: 308 B |
@@ -1,65 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg id="svg2987" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="16px" width="16px" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs id="defs2989">
|
||||
<linearGradient id="linearGradient2880" y2="44" gradientUnits="userSpaceOnUse" x2="16.143" gradientTransform="matrix(.23078 0 0 .15386 2.4612 4.8074)" y1="4" x1="16.143">
|
||||
<stop id="stop2225-6-4-7-2" style="stop-color:#fff" offset="0"/>
|
||||
<stop id="stop2229-2-5-5-8" style="stop-color:#fff;stop-opacity:0" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient2883" y2="24.628" gradientUnits="userSpaceOnUse" x2="20.055" gradientTransform="matrix(.30476 0 0 .32156 .68572 1.0807)" y1="15.298" x1="16.626">
|
||||
<stop id="stop2687-1-9-0-2" style="stop-color:#fff" offset="0"/>
|
||||
<stop id="stop2689-5-4-3-1" style="stop-color:#fff;stop-opacity:0" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient2886" y2="16" xlink:href="#linearGradient3680-6" gradientUnits="userSpaceOnUse" x2="16" gradientTransform="matrix(.34286 0 0 .36364 -.42808 -.81818)" y1="27.045" x1="16"/>
|
||||
<linearGradient id="linearGradient3680-6">
|
||||
<stop id="stop3682-4" style="stop-color:#dcdcdc" offset="0"/>
|
||||
<stop id="stop3684-8" style="stop-color:#fff" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient2890" y2="26" xlink:href="#linearGradient3680-6" gradientUnits="userSpaceOnUse" x2="20" gradientTransform="matrix(.375 0 0 0.375 -.74978 -0.5)" y1="28" x1="20"/>
|
||||
<linearGradient id="linearGradient2894" y2="47.279" gradientUnits="userSpaceOnUse" x2="12.213" gradientTransform="matrix(.28855 0 0 .25608 1.0743 2.6116)" y1="2.9165" x1="12.579">
|
||||
<stop id="stop2240-1-6-7-0" style="stop-color:#fff" offset="0"/>
|
||||
<stop id="stop2242-7-3-7-2" style="stop-color:#fff;stop-opacity:0" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient2897" y2="33.296" gradientUnits="userSpaceOnUse" x2="23.071" gradientTransform="matrix(.33032 0 0 .32624 .074248 1.9649)" y1="36.047" x1="23.071">
|
||||
<stop id="stop2225-6-4-7" style="stop-color:#fff" offset="0"/>
|
||||
<stop id="stop2229-2-5-5" style="stop-color:#fff;stop-opacity:0" offset="1"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="radialGradient2900" gradientUnits="userSpaceOnUse" cy="8.4498" cx="7.4957" gradientTransform="matrix(0 .47178 -.86826 -1.9907e-8 15.337 1.0829)" r="20">
|
||||
<stop id="stop3790-0-0" style="stop-color:#505050" offset="0"/>
|
||||
<stop id="stop3792-0-2" style="stop-color:#141414" offset="1"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="linearGradient2902" y2="44" gradientUnits="userSpaceOnUse" x2="16.143" gradientTransform="matrix(.28207 0 0 .20514 1.2304 3.5766)" y1="4" x1="16.143">
|
||||
<stop id="stop3796-3-0" style="stop-color:#323232" offset="0"/>
|
||||
<stop id="stop3798-8-6" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient2983" y2="43.865" gradientUnits="userSpaceOnUse" y1="7.96" gradientTransform="matrix(.33330 0 0 .32429 .00075427 .06858)" x2="24" x1="24">
|
||||
<stop id="stop4324-9-7" style="stop-color:#f0f0f0" offset="0"/>
|
||||
<stop id="stop2860-4-4" style="stop-color:#d7d7d8" offset=".085525"/>
|
||||
<stop id="stop2862-5-9" style="stop-color:#b2b2b3" offset=".92166"/>
|
||||
<stop id="stop4326-1-1" style="stop-color:#979798" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient2985" y2="2.8765" gradientUnits="userSpaceOnUse" y1="44.96" gradientTransform="matrix(.31912 0 0 .29298 .34112 1.4648)" x2="10.014" x1="10.014">
|
||||
<stop id="stop4334-7-6" style="stop-color:#595959" offset="0"/>
|
||||
<stop id="stop4336-8-0" style="stop-color:#b3b3b3" offset="1"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<metadata id="metadata2992">
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g id="layer1">
|
||||
<rect id="rect2551-5-8" style="stroke-linejoin:round;fill-rule:evenodd;stroke:url(#linearGradient2985);stroke-linecap:round;stroke-width:1.0021;fill:url(#linearGradient2983)" rx="1" ry="1" height="11.998" width="14.998" y="2.5011" x=".50107"/>
|
||||
<rect id="rect1314-3-3" style="stroke-linejoin:round;color:#000000;stroke:url(#linearGradient2902);stroke-linecap:round;fill:url(#radialGradient2900)" rx="0" ry="0" height="8" width="11" y="4.5" x="2.5"/>
|
||||
<rect id="rect2221-3-8" style="opacity:.4;stroke-linejoin:round;stroke:url(#linearGradient2897);stroke-linecap:round;stroke-width:1.0021;fill:none" rx="0" ry="0" height="9.9979" width="12.998" y="3.5011" x="1.501"/>
|
||||
<rect id="rect2556-8-5" style="opacity:.8;stroke-linejoin:round;stroke:url(#linearGradient2894);stroke-linecap:round;stroke-width:1.0037;fill:none" height="9.9963" width="12.996" y="3.5019" x="1.5019"/>
|
||||
<path id="path3651-2" style="fill:url(#linearGradient2890)" d="m9.0002 10v-0.75h-3v0.75h3z"/>
|
||||
<path id="path3653-7" style="fill:url(#linearGradient2886)" d="m3.6862 9-0.6857-0.7273 1.5428-1.2727-1.5428-1.2727 0.6857-0.7273 2.3143 2-2.3143 2z"/>
|
||||
<path id="path3333-3-0" style="opacity:.2;fill:url(#linearGradient2883);fill-rule:evenodd" d="m1.6667 3c-0.3683 0-0.6667 0.3149-0.6667 0.7034v5.145c0.0009545 0.043283 0.018837 0.084214 0.049602 0.11286 0.030769 0.028643 0.071495 0.04238 0.1123 0.037874l13.714-2.2911c0.071-0.0117 0.123-0.0754 0.124-0.1507v-2.8539c0-0.3885-0.298-0.7034-0.667-0.7034h-12.667z"/>
|
||||
<rect id="rect1314-3-3-9" style="opacity:.1;stroke-linejoin:round;color:#000000;stroke:url(#linearGradient2880);stroke-linecap:round;fill:none" rx="0" ry="0" height="6" width="9" y="5.5" x="3.5"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 5.7 KiB |
@@ -1,155 +0,0 @@
|
||||
# Paparazzi center utilities
|
||||
#
|
||||
# Copyright (C) 2016 ENAC, Florian BITARD (intern student)
|
||||
#
|
||||
# This file is part of paparazzi.
|
||||
#
|
||||
# paparazzi 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 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
# Boston, MA 02111-1307, USA.
|
||||
|
||||
###############################################################################
|
||||
# [Imports]
|
||||
|
||||
import lib.gui as gui
|
||||
|
||||
import PyQt5.QtCore as Core
|
||||
import re
|
||||
|
||||
|
||||
###############################################################################
|
||||
# [Constants]
|
||||
|
||||
DEFAULT_FONT_QCOLOR = gui.generate_qcolor("black")
|
||||
DEFAULT_BACKGROUND_QCOLOR = gui.generate_qcolor("white")
|
||||
DEFAULT_LOGGER_FONT_QCOLOR = gui.generate_qcolor("blue")
|
||||
|
||||
ALL_MESSAGES_LEVEL = "all"
|
||||
CUSTOM_MESSAGES_LEVEL = "custom"
|
||||
MINIMAL_MESSAGES_LEVEL = "minimal"
|
||||
|
||||
PROCESS_MESSAGE_TYPE = "process"
|
||||
APPLICATION_MESSAGE_TYPE = "application"
|
||||
|
||||
ERROR_FLAG = "error"
|
||||
WARNING_FLAG = "warning"
|
||||
INFO_FLAG = "info"
|
||||
DEFAULT_FLAG = "default"
|
||||
|
||||
BACKGROUNDS_COLORS = {ERROR_FLAG: "red",
|
||||
WARNING_FLAG: "yellow",
|
||||
INFO_FLAG: "green",
|
||||
DEFAULT_FLAG: "white"}
|
||||
|
||||
FONTS_COLORS = {ERROR_FLAG: "red",
|
||||
WARNING_FLAG: "orange",
|
||||
INFO_FLAG: "blue",
|
||||
DEFAULT_FLAG: "black"}
|
||||
|
||||
ERROR_REGEX = re.compile(r"[Ee][Rr]{2}[Oo][Rr][ :]")
|
||||
WARNING_REGEX = re.compile(r"[Ww][Aa][Rr][Nn][Ii][Nn][Gg][ :]")
|
||||
INFO_REGEX = re.compile(r"[Ii][Nn][Ff][Oo][ :]")
|
||||
|
||||
|
||||
def analyse_log_line(line):
|
||||
if ERROR_REGEX.search(line) is not None:
|
||||
flag = ERROR_FLAG
|
||||
elif WARNING_REGEX.search(line) is not None:
|
||||
flag = WARNING_FLAG
|
||||
elif INFO_REGEX.search(line) is not None:
|
||||
flag = INFO_FLAG
|
||||
else:
|
||||
flag = DEFAULT_FLAG
|
||||
return line, flag
|
||||
|
||||
|
||||
###############################################################################
|
||||
# [Console class]
|
||||
|
||||
class Console(Core.QObject):
|
||||
""" Class to define a Console object."""
|
||||
def __init__(self, q_text_edit_widget):
|
||||
super(Console, self).__init__()
|
||||
|
||||
self.edit = q_text_edit_widget
|
||||
|
||||
def write(self, line, font_color=DEFAULT_FONT_QCOLOR,
|
||||
backgroud_color=DEFAULT_BACKGROUND_QCOLOR):
|
||||
|
||||
self.edit.setTextColor(font_color)
|
||||
self.edit.setTextBackgroundColor(backgroud_color)
|
||||
self.edit.append(line)
|
||||
|
||||
|
||||
###############################################################################
|
||||
# [LogFilter class]
|
||||
|
||||
class LogFilter(object):
|
||||
"""Class to define a LogFilter object to manage the messages written in the
|
||||
integrated console."""
|
||||
def __init__(self, init_level_str, init_default_bool, init_info_bool,
|
||||
init_warning_bool, init_error_bool):
|
||||
"""
|
||||
-> 'level' sets what sort of messages to display in the console and is
|
||||
linked to the HMI radio-button choice.
|
||||
-> 'info', 'warning' and 'error' are booleans to set what logs to
|
||||
display in the console and is linked to the HMI check-boxes.
|
||||
"""
|
||||
self.level = init_level_str
|
||||
|
||||
self.default = init_default_bool
|
||||
self.info = init_info_bool
|
||||
self.warning = init_warning_bool
|
||||
self.error = init_error_bool
|
||||
|
||||
def __repr__(self):
|
||||
string = "\t| level = {!s:<10} | default = {!s:<5} | info = {!s:<5} |"\
|
||||
" warning = {!s:<5} | error = {!s:<5} |"
|
||||
format_string = string.format(self.level, self.default, self.info,
|
||||
self.warning, self.error)
|
||||
return format_string
|
||||
|
||||
def set_level(self, level):
|
||||
"""
|
||||
:param level:
|
||||
-> level = 'minimum' (only important messages)
|
||||
'basic' (customized messages)
|
||||
'all' (all messages emitted by Makefiles and compilers).
|
||||
"""
|
||||
self.level = level
|
||||
|
||||
def set_sensitivity_filter(self, default, info, warning, error):
|
||||
"""
|
||||
:param default:
|
||||
:param info:
|
||||
:param warning:
|
||||
:param error:
|
||||
-> info, warnings and error are booleans.
|
||||
"""
|
||||
self.default = default
|
||||
self.info = info
|
||||
self.warning = warning
|
||||
self.error = error
|
||||
|
||||
def write_line_decision(self, flag):
|
||||
if flag == ERROR_FLAG and self.error:
|
||||
return True
|
||||
elif flag == WARNING_FLAG and self.warning:
|
||||
return True
|
||||
elif flag == INFO_FLAG and self.info:
|
||||
return True
|
||||
elif flag == DEFAULT_FLAG and self.default:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
@@ -1,163 +0,0 @@
|
||||
# Paparazzi center utilities
|
||||
#
|
||||
# Copyright (C) 2016 ENAC, Florian BITARD (intern student)
|
||||
#
|
||||
# This file is part of paparazzi.
|
||||
#
|
||||
# paparazzi 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 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
# Boston, MA 02111-1307, USA.
|
||||
|
||||
###############################################################################
|
||||
# [Imports]
|
||||
|
||||
|
||||
###############################################################################
|
||||
# [Configuration class]
|
||||
|
||||
class Configuration(object):
|
||||
"""Class to define a Configuration (old aircraft) object."""
|
||||
def __init__(self, name, config_id, airframes, targets):
|
||||
# Necessary parameters :
|
||||
self.name = name
|
||||
self.id = config_id
|
||||
self.airframes = airframes
|
||||
|
||||
# Not necessary parameters :
|
||||
self.settings = []
|
||||
self.modules = []
|
||||
self.flight_plan = []
|
||||
self.radio = []
|
||||
self.telemetry = []
|
||||
|
||||
self.color = []
|
||||
|
||||
self.targets = targets
|
||||
|
||||
def __repr__(self):
|
||||
string = "| name = {!s:<25} | id = {!s:<3} | airframe = {!s:<65} |" + \
|
||||
"targets = {!s:<250} | color = {!s:<15} | " + \
|
||||
"radio = {!s:<40} | telemetry = {!s:<45} | " + \
|
||||
"flight_plan = {!s:<75} | settings = {!s:<265} | " + \
|
||||
"modules = {!s:<265} |"
|
||||
format_string = string.format(self.name, self.id, self.airframes,
|
||||
[_ for _ in self.targets.values()],
|
||||
self.color, self.radio,
|
||||
self.telemetry, self.flight_plan,
|
||||
self.settings, self.modules)
|
||||
return format_string
|
||||
|
||||
|
||||
###############################################################################
|
||||
# [Set class]
|
||||
|
||||
class Set(object):
|
||||
"""Class to define a Set (old configuration) object."""
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.configs_names = []
|
||||
|
||||
def __repr__(self):
|
||||
string = "| name = {!s:<75} | configs_names = {!s:<680} |"
|
||||
format_string = string.format(self.name, self.configs_names)
|
||||
return format_string
|
||||
|
||||
def is_config_in_set(self, config):
|
||||
return config.id in self.configs_names
|
||||
|
||||
|
||||
###############################################################################
|
||||
# [Target class]
|
||||
|
||||
class Target(object):
|
||||
"""Class to define a Target object."""
|
||||
def __init__(self, name, board, ):
|
||||
self.name = name
|
||||
self.board = board
|
||||
|
||||
self.defines = None
|
||||
|
||||
def __repr__(self):
|
||||
string = "| name = {!s:<15} | board = {!s:<20} |"
|
||||
format_string = string.format(self.name, self.board)
|
||||
return format_string
|
||||
|
||||
|
||||
###############################################################################
|
||||
# [Device class]
|
||||
|
||||
class Device(object):
|
||||
"""Class to define a Device (old flash mode) object."""
|
||||
def __init__(self, name, variable_name="", variable_value=""):
|
||||
self.name = name
|
||||
self.variable = (variable_name, variable_value)
|
||||
self.boards_regex = []
|
||||
|
||||
def __repr__(self):
|
||||
string = "| name = {!s:<25} | variable = {!s:<35} | " + \
|
||||
"boards_regex = {!s:<125} |"
|
||||
format_string = string.format(self.name, self.variable,
|
||||
self.boards_regex)
|
||||
return format_string
|
||||
|
||||
|
||||
###############################################################################
|
||||
# [Session class]
|
||||
|
||||
class Session(object):
|
||||
"""Class to define a Session object."""
|
||||
def __init__(self, name, programs):
|
||||
self.name = name
|
||||
self.programs = programs
|
||||
|
||||
def __repr__(self):
|
||||
string = "| name = {!s:<30} | programs = {!s:<1300} |"
|
||||
format_string = string.format(self.name,
|
||||
[_ for _ in self.programs.values()])
|
||||
return format_string
|
||||
|
||||
|
||||
###############################################################################
|
||||
# [Program class]
|
||||
|
||||
class Program(object):
|
||||
"""Class to define a Program (old tool) object."""
|
||||
def __init__(self, name, command, options, icon=None, favorite=None, blacklisted=None):
|
||||
self.name = name
|
||||
self.command = command
|
||||
self.options = options
|
||||
self.icon = icon
|
||||
self.favorite = favorite
|
||||
self.blacklisted = blacklisted
|
||||
|
||||
def __repr__(self):
|
||||
string = "\t| name = {!s:<30} | command = {!s:<60} | options = {!s:<70} | icon={!s} |"
|
||||
format_string = string.format(self.name, self.command, self.options, self.icon)
|
||||
return format_string
|
||||
|
||||
|
||||
###############################################################################
|
||||
# [Cache class]
|
||||
|
||||
class Cache(object):
|
||||
"""Class to define a Cache (old %gconf) object."""
|
||||
def __init__(self, last_update_time):
|
||||
self.last_update = last_update_time
|
||||
|
||||
self.main_window_shape = (0, 0)
|
||||
self.last_set = None
|
||||
self.last_configuration = None
|
||||
self.last_target = None
|
||||
self.last_session = None
|
||||
self.last_device = None
|
||||
@@ -1,15 +0,0 @@
|
||||
<cache>
|
||||
- <system>
|
||||
- <window>
|
||||
- <geometry value="100 100 1026 448" />
|
||||
- </window>
|
||||
- <filters value="all 2 2 2 2" />
|
||||
- </system>
|
||||
- <data>
|
||||
- <set value="conf_example.xml" />
|
||||
- <config value="Microjet" />
|
||||
- <target value="sim" />
|
||||
- <device value=" __Default__ " />
|
||||
- <session value="Simulation" />
|
||||
- </data>
|
||||
-</cache>
|
||||
@@ -1,91 +0,0 @@
|
||||
# Paparazzi center utilities
|
||||
#
|
||||
# Copyright (C) 2016 ENAC, Florian BITARD (intern student)
|
||||
#
|
||||
# This file is part of paparazzi.
|
||||
#
|
||||
# paparazzi 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 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
# Boston, MA 02111-1307, USA.
|
||||
|
||||
###############################################################################
|
||||
# [Imports]
|
||||
|
||||
import os
|
||||
from sys import platform as os_name
|
||||
import logging
|
||||
|
||||
|
||||
###############################################################################
|
||||
# [Constants]
|
||||
|
||||
LOGGER = logging.getLogger("[ENV]")
|
||||
OS = os_name
|
||||
|
||||
SRC_NAME = "PAPARAZZI_SRC"
|
||||
HERE_TO_SRC = "../../../.."
|
||||
CONF_NAME = "PAPARAZZI_CONF"
|
||||
HOME_TO_CONF = "conf"
|
||||
HOME_NAME = "PAPARAZZI_HOME"
|
||||
HOME_TO_VAR = "var"
|
||||
IVY_BUS_NAME = "IVY_BUS"
|
||||
|
||||
|
||||
def get_src_dir(src_name):
|
||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
src_dir = os.path.normpath(os.path.join(current_dir, HERE_TO_SRC))
|
||||
return os.getenv(src_name, src_dir)
|
||||
|
||||
PAPARAZZI_SRC = get_src_dir(SRC_NAME)
|
||||
LOGGER.debug("%s=%s", SRC_NAME, PAPARAZZI_SRC)
|
||||
|
||||
|
||||
def get_home_dir(home_name):
|
||||
return os.getenv(home_name, get_src_dir(SRC_NAME))
|
||||
|
||||
PAPARAZZI_HOME = get_home_dir(HOME_NAME)
|
||||
LOGGER.info("%s=%s", HOME_NAME, PAPARAZZI_HOME)
|
||||
|
||||
|
||||
def get_conf_dir(conf_name):
|
||||
conf_dir = os.path.join(PAPARAZZI_HOME, HOME_TO_CONF)
|
||||
if os.path.exists(conf_dir):
|
||||
return os.getenv(conf_name, conf_dir)
|
||||
else:
|
||||
LOGGER.error("'%s' directory doesn't exist !", conf_dir)
|
||||
|
||||
PAPARAZZI_CONF = get_conf_dir(CONF_NAME)
|
||||
|
||||
|
||||
def get_ivy_bus(ivy_bus_name):
|
||||
supposed_ivy_bus = os.getenv(ivy_bus_name)
|
||||
if supposed_ivy_bus is not None:
|
||||
return supposed_ivy_bus
|
||||
elif OS == 'linux':
|
||||
return "127.255.255.255:2010"
|
||||
elif OS == 'linux2':
|
||||
return "127.255.255.255:2010"
|
||||
elif OS == 'darwin':
|
||||
return "224.5.6.7:8910"
|
||||
LOGGER.error("Unknown Ivy bus for the current OS !")
|
||||
|
||||
IVY_BUS = get_ivy_bus(IVY_BUS_NAME)
|
||||
LOGGER.debug("%s=%s", HOME_NAME, PAPARAZZI_HOME)
|
||||
|
||||
RUN_VERSION_EXE_NAME = "paparazzi_version"
|
||||
RUN_VERSION_EXE = os.path.join(PAPARAZZI_HOME, RUN_VERSION_EXE_NAME)
|
||||
|
||||
BUILD_VERSION_FILE_NAME = "build_version.txt"
|
||||
BUILD_VERSION_FILE = os.path.join(PAPARAZZI_HOME, HOME_TO_VAR,
|
||||
BUILD_VERSION_FILE_NAME)
|
||||
@@ -1,69 +0,0 @@
|
||||
# Paparazzi center utilities
|
||||
#
|
||||
# Copyright (C) 2016 ENAC, Florian BITARD (intern student)
|
||||
#
|
||||
# This file is part of paparazzi.
|
||||
#
|
||||
# paparazzi 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 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
# Boston, MA 02111-1307, USA.
|
||||
|
||||
###############################################################################
|
||||
# [Imports]
|
||||
|
||||
import PyQt5.QtGui as Gui
|
||||
|
||||
|
||||
###############################################################################
|
||||
# [Constants]
|
||||
|
||||
NORMAL_CURSOR_SHAPE = "normal"
|
||||
WAIT_CURSOR_SHAPE = "wait"
|
||||
|
||||
|
||||
###############################################################################
|
||||
# [Functions]
|
||||
|
||||
def generate_qcolor(color):
|
||||
qcolor = Gui.QColor()
|
||||
qcolor.setNamedColor(color)
|
||||
return qcolor
|
||||
|
||||
|
||||
def generate_widget_palette(widget, qcolor):
|
||||
qpalette = Gui.QPalette(widget.palette())
|
||||
qpalette.setColor(Gui.QPalette.Background, qcolor)
|
||||
return qpalette
|
||||
|
||||
|
||||
def generate_qcursor(shape):
|
||||
qcursor = Gui.QCursor()
|
||||
if shape == WAIT_CURSOR_SHAPE:
|
||||
qcursor.setShape(16)
|
||||
elif shape == NORMAL_CURSOR_SHAPE:
|
||||
qcursor.setShape(0)
|
||||
else:
|
||||
qcursor.setShape(0)
|
||||
return qcursor
|
||||
|
||||
|
||||
def generate_qpixmap(picture_path=""):
|
||||
return Gui.QPixmap(picture_path)
|
||||
|
||||
|
||||
def generate_qicon(icon_path=None):
|
||||
if icon_path is not None:
|
||||
return Gui.QIcon(icon_path)
|
||||
else:
|
||||
return Gui.QIcon()
|
||||
@@ -1,59 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Paparazzi center utilities
|
||||
#
|
||||
# Copyright (C) 2016 ENAC, Florian BITARD (intern student)
|
||||
#
|
||||
# This file is part of paparazzi.
|
||||
#
|
||||
# paparazzi 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 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# paparazzi 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 paparazzi; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
# Boston, MA 02111-1307, USA.
|
||||
|
||||
###############################################################################
|
||||
# [Imports]
|
||||
|
||||
import lib.environment as env
|
||||
import hmi
|
||||
|
||||
import PyQt5.QtWidgets as Widgets
|
||||
import sys
|
||||
import os
|
||||
|
||||
|
||||
###############################################################################
|
||||
# [Main function]
|
||||
def main():
|
||||
"""Main program : creates the main window and starts the main loop."""
|
||||
|
||||
# Set this file's location as working directory
|
||||
os.chdir(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
# Set the environment variables (useful for some processes) :
|
||||
os.putenv(env.HOME_NAME, env.PAPARAZZI_HOME)
|
||||
os.putenv(env.SRC_NAME, env.PAPARAZZI_SRC)
|
||||
|
||||
app = Widgets.QApplication(sys.argv)
|
||||
|
||||
# TODO : SET APPLICATION ICON IN THE LAUNCHER (UBUNTU : UNITY)
|
||||
|
||||
main_window = hmi.Hmi()
|
||||
main_window.init_all_hmi()
|
||||
main_window.show()
|
||||
|
||||
sys.exit(app.exec_())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,13 @@
|
||||
# Copyright (C) 2008-2022 The Paparazzi Team
|
||||
# released under GNU GPLv2 or later. See COPYING file.
|
||||
|
||||
from generated.ui_operation_panel import Ui_OperationPanel
|
||||
from PyQt5.QtWidgets import *
|
||||
|
||||
|
||||
class OperationPanel(QWidget, Ui_OperationPanel):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
QWidget.__init__(self, parent=parent)
|
||||
self.setupUi(self)
|
||||
self.session.set_console(self.console)
|
||||