diff --git a/paparazzi b/paparazzi
index 2557c7debe..18e723de9c 100755
--- a/paparazzi
+++ b/paparazzi
@@ -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'))
diff --git a/sw/supervision/python/.cache.dtd b/sw/supervision/python/.cache.dtd
deleted file mode 100644
index 3a3f843f05..0000000000
--- a/sw/supervision/python/.cache.dtd
+++ /dev/null
@@ -1,44 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/sw/supervision/python/Makefile b/sw/supervision/python/Makefile
new file mode 100644
index 0000000000..6db5e54e04
--- /dev/null
+++ b/sw/supervision/python/Makefile
@@ -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
diff --git a/sw/supervision/python/README.md b/sw/supervision/python/README.md
deleted file mode 100644
index 759f72a36b..0000000000
--- a/sw/supervision/python/README.md
+++ /dev/null
@@ -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.
diff --git a/sw/supervision/python/Readme.md b/sw/supervision/python/Readme.md
new file mode 100644
index 0000000000..6ec617f025
--- /dev/null
+++ b/sw/supervision/python/Readme.md
@@ -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`
diff --git a/sw/supervision/python/app_settings.py b/sw/supervision/python/app_settings.py
new file mode 100644
index 0000000000..d74fa78ed8
--- /dev/null
+++ b/sw/supervision/python/app_settings.py
@@ -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)
diff --git a/sw/supervision/python/build_widget.py b/sw/supervision/python/build_widget.py
new file mode 100644
index 0000000000..64a2e9594f
--- /dev/null
+++ b/sw/supervision/python/build_widget.py
@@ -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)
+
diff --git a/sw/supervision/python/conf.py b/sw/supervision/python/conf.py
new file mode 100644
index 0000000000..e7540aab37
--- /dev/null
+++ b/sw/supervision/python/conf.py
@@ -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 = " "
+ 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 = "\n"
+ xml += "\n".join([ac.to_string() for ac in self.aircrafts])
+ xml += "\n \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)
+
+
+
+
+
diff --git a/sw/supervision/python/conf_file_widget.py b/sw/supervision/python/conf_file_widget.py
new file mode 100644
index 0000000000..39b1db1952
--- /dev/null
+++ b/sw/supervision/python/conf_file_widget.py
@@ -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()
diff --git a/sw/supervision/python/conf_widget.py b/sw/supervision/python/conf_widget.py
new file mode 100644
index 0000000000..88c50fe35e
--- /dev/null
+++ b/sw/supervision/python/conf_widget.py
@@ -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()
+
diff --git a/sw/supervision/python/configuration_panel.py b/sw/supervision/python/configuration_panel.py
new file mode 100644
index 0000000000..8465d447f1
--- /dev/null
+++ b/sw/supervision/python/configuration_panel.py
@@ -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 {} ?".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()
diff --git a/sw/supervision/python/console_widget.py b/sw/supervision/python/console_widget.py
new file mode 100644
index 0000000000..6ffc1b1435
--- /dev/null
+++ b/sw/supervision/python/console_widget.py
@@ -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 = "{} ".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()
diff --git a/sw/supervision/python/dialogs.py b/sw/supervision/python/dialogs.py
deleted file mode 100644
index 1f3c1c2097..0000000000
--- a/sw/supervision/python/dialogs.py
+++ /dev/null
@@ -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)
diff --git a/sw/supervision/python/generated/ui_app_settings.py b/sw/supervision/python/generated/ui_app_settings.py
new file mode 100644
index 0000000000..3f8f2aa4c1
--- /dev/null
+++ b/sw/supervision/python/generated/ui_app_settings.py
@@ -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"))
diff --git a/sw/supervision/python/generated/ui_build.py b/sw/supervision/python/generated/ui_build.py
new file mode 100644
index 0000000000..b2d0095f24
--- /dev/null
+++ b/sw/supervision/python/generated/ui_build.py
@@ -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"))
diff --git a/sw/supervision/python/generated/ui_conf_header.py b/sw/supervision/python/generated/ui_conf_header.py
new file mode 100644
index 0000000000..b5331f61a4
--- /dev/null
+++ b/sw/supervision/python/generated/ui_conf_header.py
@@ -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"))
diff --git a/sw/supervision/python/generated/ui_conf_item.py b/sw/supervision/python/generated/ui_conf_item.py
new file mode 100644
index 0000000000..0e8b83985e
--- /dev/null
+++ b/sw/supervision/python/generated/ui_conf_item.py
@@ -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"))
diff --git a/sw/supervision/python/generated/ui_configuration_panel.py b/sw/supervision/python/generated/ui_configuration_panel.py
new file mode 100644
index 0000000000..494017000e
--- /dev/null
+++ b/sw/supervision/python/generated/ui_configuration_panel.py
@@ -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
diff --git a/sw/supervision/python/generated/ui_console.py b/sw/supervision/python/generated/ui_console.py
new file mode 100644
index 0000000000..2ba3261794
--- /dev/null
+++ b/sw/supervision/python/generated/ui_console.py
@@ -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"))
diff --git a/sw/supervision/python/generated/ui_new_ac_dialog.py b/sw/supervision/python/generated/ui_new_ac_dialog.py
new file mode 100644
index 0000000000..d120aef70f
--- /dev/null
+++ b/sw/supervision/python/generated/ui_new_ac_dialog.py
@@ -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"))
diff --git a/sw/supervision/python/generated/ui_operation_panel.py b/sw/supervision/python/generated/ui_operation_panel.py
new file mode 100644
index 0000000000..f83f320a00
--- /dev/null
+++ b/sw/supervision/python/generated/ui_operation_panel.py
@@ -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
diff --git a/sw/supervision/python/generated/ui_program.py b/sw/supervision/python/generated/ui_program.py
new file mode 100644
index 0000000000..c685c856ca
--- /dev/null
+++ b/sw/supervision/python/generated/ui_program.py
@@ -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", "..."))
diff --git a/sw/supervision/python/generated/ui_session.py b/sw/supervision/python/generated/ui_session.py
new file mode 100644
index 0000000000..09ab39345b
--- /dev/null
+++ b/sw/supervision/python/generated/ui_session.py
@@ -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"))
diff --git a/sw/supervision/python/generated/ui_tools_list.py b/sw/supervision/python/generated/ui_tools_list.py
new file mode 100644
index 0000000000..1ac6019775
--- /dev/null
+++ b/sw/supervision/python/generated/ui_tools_list.py
@@ -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"))
diff --git a/sw/supervision/python/header_widget.py b/sw/supervision/python/header_widget.py
new file mode 100644
index 0000000000..93b99c80a6
--- /dev/null
+++ b/sw/supervision/python/header_widget.py
@@ -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))
diff --git a/sw/supervision/python/hmi.py b/sw/supervision/python/hmi.py
deleted file mode 100644
index dbf41fdf54..0000000000
--- a/sw/supervision/python/hmi.py
+++ /dev/null
@@ -1,1781 +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.main_window as ui
-import dialogs as dial
-import lib.console as cs
-import lib.database as db
-import lib.environment as env
-import lib.gui as gui
-import parser
-import processes as proc
-
-import PyQt5.QtCore as Core
-import PyQt5.QtWidgets as Widgets
-import functools
-import logging
-import os
-import sys
-import re
-import shutil
-
-###############################################################################
-# [Constants]
-
-DEFAULT_TOOL_ICON = "default_tool_icon.svg"
-
-LOGGER = logging.getLogger("[HMI]")
-
-CONF_PATH = env.PAPARAZZI_CONF
-SET_SYMBOLIC_LINK = CONF_PATH + "/conf.xml"
-CONF_XML_COPY = CONF_PATH + "/conf_copy.xml"
-
-OK_QPIXMAP = "icons/dialog-apply.svg"
-ERROR_QPIXMAP = "icons/dialog-error.svg"
-START_ICON = "icons/media-playback-start.svg"
-STOP_ICON = "icons/process-stop.svg"
-CHANGED_ICON = "icons/dialog-warning-symbolic.svg"
-ICONS_TOOLS_PATH = "data/pictures/tools_icons/"
-
-UNKNOWN_VALUE = "---"
-
-PROGRESS_BAR_LINE = " "
-PROGRESS_BAR_CURSOR = "***"
-PROGRESS_BAR_SPEED = 10
-
-
-###############################################################################
-# [Functions] System functions
-
-def control_cwd():
- """
- -> Get the current directory path and log it.
- """
- cwd = os.getcwd()
- LOGGER.info("Current directory : '%s'.", cwd)
- return cwd
-
-
-def point_symbol_link_to(set_file):
- """
- :param set_file:
- -> Make the 'conf.xml' symbolic file point to the given 'set_file'.
- """
- if os.path.exists(SET_SYMBOLIC_LINK):
- os.remove(SET_SYMBOLIC_LINK)
- os.symlink(set_file, SET_SYMBOLIC_LINK)
- LOGGER.debug("'%s' -> '%s'.", SET_SYMBOLIC_LINK, set_file)
-
-
-def init_conf_xml_path():
- """
- -> Create a copy of the conf.xml file if it's an existing and real file.
- -> Make the conf.xml file point to the copy created.
- """
- if os.path.exists(SET_SYMBOLIC_LINK) \
- and not os.path.islink(SET_SYMBOLIC_LINK):
- shutil.copy(SET_SYMBOLIC_LINK, CONF_XML_COPY)
- point_symbol_link_to(CONF_XML_COPY)
-
-
-###############################################################################
-# [Functions] Widgets management functions
-
-def set_widgets_visibility(widgets, set_visible_bool):
- """
- :param widgets:
- :param set_visible_bool:
- -> Set a list of widgets visible or not together.
- """
- for widget in widgets:
- widget.setVisible(set_visible_bool)
-
-
-def set_widgets_availability(widgets, set_available_bool):
- """
- :param widgets:
- :param set_available_bool:
- -> Set a list of widgets available or not together.
- """
- for widget in widgets:
- widget.setEnabled(set_available_bool)
-
-
-def set_items_icons(list_widget_items, qicon):
- """
- :param list_widget_items:
- :param qicon:
- -> Put the same QIcon to items of a QListWidget.
- """
- for item in list_widget_items:
- item.setIcon(qicon)
-
-
-def clear_widgets(widgets):
- """
- :param widgets:
- -> Clear each widget in a list of widgets.
- """
- for widget in widgets:
- widget.clear()
-
-
-def clear_list_widgets_selection(widgets):
- """
- :param widgets:
- -> Clear the selection of each widget in a list of QListWidget widgets.
- """
- for widget in widgets:
- widget.clearSelection()
- widget.clearFocus()
-
-
-###############################################################################
-# [Hmi class]
-
-class Hmi(Widgets.QMainWindow):
- """Class to manage the main HMI behavior."""
- def __init__(self):
- """
- -> Creation of a MainWindow object generated by the command :
- 'pyuic5 *.ui -o *.py' from the PyQt5 HMI designed under QtDesigner.
- -> Creation of Dialog objects used from the main HMI.
- -> Declaration of widgets groups for code factorization.
- -> Declaration of HMI private attributes for its own methods.
- """
- super(Hmi, self).__init__()
-
- self.ui = ui.Ui_MainWindow()
- self.ui.setupUi(self)
-
- # Existing popups :
- self.settings = None
- self.data_changed_popup = None
- self.credits_popup = None
- self.tutorial_popup = None
-
- # Shortcuts for lists of widgets :
- self.change_config_widgets = [self.ui.current_airframes,
- self.ui.current_settings,
- self.ui.current_flight_plan,
- self.ui.current_radio,
- self.ui.current_telemetry]
- self.display_config_widgets = [self.ui.airframes_overview,
- self.ui.settings_overview,
- self.ui.flight_plan_overview,
- self.ui.radio_overview,
- self.ui.telemetry_overview,
- self.ui.airframes_overview_2,
- self.ui.settings_overview_2,
- self.ui.flight_plan_overview_2,
- self.ui.radio_overview_2,
- self.ui.telemetry_overview_2]
- self.flight_plan_buttons = [self.ui.open_gui,
- self.ui.select_kml]
- self.session_widgets = [self.ui.session,
- self.ui.session_overview_1,
- self.ui.session_overview_2]
- self.display_programs_widgets = [self.ui.programs_overview_1,
- self.ui.programs_overview_2]
- self.target_widgets = [self.ui.quick_target, self.ui.target]
- self.messages_level_widgets = [self.ui.important,
- self.ui.custom, self.ui.all]
- self.log_filters_widgets = [self.ui.display_default,
- self.ui.display_info,
- self.ui.display_warnings,
- self.ui.display_errors]
- self.messages_nb_widgets = [self.ui.info_nb, self.ui.warnings_nb,
- self.ui.errors_nb]
- self.start_all_buttons = [self.ui.start_all_button,
- self.ui.quick_restart,
- self.ui.quick_restart_3]
- self.kill_all_buttons = [self.ui.kill_all_button, self.ui.quick_kill,
- self.ui.quick_kill_2]
-
- # Icons used in widgets (can't be constants because qpixmap objects
- # must be declared into a QApplication) :
- self.ok_qpixmap = gui.generate_qpixmap(OK_QPIXMAP)
- self.error_qpixmap = gui.generate_qpixmap(ERROR_QPIXMAP)
- self.start_qicon = gui.generate_qicon(START_ICON)
- self.stop_qicon = gui.generate_qicon(STOP_ICON)
- self.changed_qicon = gui.generate_qicon(CHANGED_ICON)
-
- # Progress bar initialization :
- self.max_result_field_size = self.ui.build_result.width() // 10
- self.progress_bar_to_left = False
-
- # HMI parameters initialization (could be set in settings menu) :
- self.dev_mode = False
-
- self.current_log_filter = None
-
- self.data = None
- self.current_set = None
- self.current_config = None
- self.current_item = None
-
- self.current_target = None
- self.simulation_targets_names = ['nps', 'sim']
- self.change_target_bool = True
-
- self.current_device = None
- self.current_session = None
- self.current_program = None
- self.current_option = None
-
- self.run_version = None
- self.build_version = None
-
- self.configurations_changed = {}
- self.sessions_changed = {}
-
- self.build = None
- self.build_running = False
- self.clean = None
- self.clean_running = False
- self.upload = None
- self.upload_running = False
-
- self.running_programs = {}
-
- self.console = cs.Console(self.ui.console)
-
- # Logger output redirected to a special stream to allow an integrated
- # console display (and logger level could be set in settings menu) :
- self.logger_stream = proc.LoggerStream()
- self.logger_stream.logger_log_sent.connect(self.write_log_in_console)
- logging.basicConfig(level=logging.INFO, stream=self.logger_stream)
-
-###############################################################################
-# [Hmi methods] Init HMI methods
-
- def init_hmi_data(self):
- try:
- self.init_hmi_data_core()
- except:
- " if something goes wrong, delete cache and load again (to be improved)"
- LOGGER.error("ERROR while load HMI cache"
- "Original message : '%s'.", sys.exc_info()[0])
- print("HMI error in cache, load default instead")
- parser.delete_cache()
- self.init_hmi_data_core()
-
- # Run and build Paparazzi versions found by existing program
- # './paparazzi_version' and file './var/build_version.txt' :
- run_version_cmd = env.RUN_VERSION_EXE
- self.run_version = os.popen(run_version_cmd).readline().strip()
- build_version_cmd = " ".join(["cat", env.BUILD_VERSION_FILE])
- self.build_version = os.popen(build_version_cmd).readline().strip()
-
- def init_hmi_data_core(self):
- """
- -> Initialization of a 'Data' object with all necessary data from XML
- files found in the 'CONF_PATH' Paparazzi UAV directory.
- -> Loading of cache data (last settings used) to restore them.
- -> Initialization of main HMI widgets with necessary data found.
- """
- init_conf_xml_path()
- self.data = parser.Data(CONF_PATH)
-
- # Cache parameters extracted from the cache dictionary :
- last_geometry = self.data.cache[parser.LAST_GEOMETRY].split(" ")
- last_x, last_y, last_width, last_height = map(int, last_geometry)
- self.setGeometry(last_x, last_y, last_width, last_height)
-
- last_set_name = self.data.cache[parser.LAST_SET]
- self.current_set = self.data.sets[last_set_name]
-
- point_symbol_link_to(self.current_set.name)
-
- last_config_name = self.data.cache[parser.LAST_CONFIG]
- self.current_config = self.data.configurations[last_config_name]
-
- last_target_name = self.data.cache[parser.LAST_TARGET]
- self.current_target = self.current_config.targets[last_target_name]
-
- self.ui.upload.setEnabled(self.current_target.name
- not in self.simulation_targets_names)
-
- last_device_name = self.data.cache[parser.LAST_DEVICE]
- self.current_device = self.data.devices[last_device_name]
-
- last_session_name = self.data.cache[parser.LAST_SESSION]
- self.current_session = self.data.sessions[last_session_name]
-
- last_log_filters = self.data.cache[parser.LAST_LOG_FILTERS].split(" ")
- last_level = last_log_filters[0]
- last_default, last_info, last_warning, last_error =\
- map(int, last_log_filters[1:])
- self.current_log_filter = cs.LogFilter(last_level,
- last_default, last_info,
- last_warning, last_error)
-
-
- def init_hmi_widgets(self):
- """
- -> Initialization of all the HMI widgets content.
- -> Initialization of existing popups.
- """
- # Update functions used for initialization :
- self.update_home_button()
- self.update_mode_button()
- self.update_versions()
- self.update_set_combo()
- self.update_config_combo()
- self.update_config_items_lists()
- self.update_target_combos(self.target_widgets)
- self.update_log_filters()
- self.change_messages_level()
- self.update_device_combo()
- self.update_session_combos()
- self.update_programs_list()
- self.update_program_options_list()
- self.init_tools_menu()
-
- # Popup initialization :
- self.settings = dial.SettingsManager()
- self.data_changed_popup = dial.Popup(dial.DATA_CHANGED_POPUP_TYPE)
- self.credits_popup = dial.Popup(dial.CREDITS_POPUP_TYPE)
- self.tutorial_popup = dial.Popup(dial.TUTORIAL_POPUP_TYPE)
-
- def init_all_hmi(self):
- """
- -> Centralize all initializations before the mainwindow is shown.
- """
- control_cwd()
- LOGGER.info("HMI init in progress...\n")
- print("\nHMI init in progress...")
- self.init_hmi_data()
- self.init_hmi_widgets()
- self.connect_signals()
- LOGGER.info("HMI init finished.\n")
- print("HMI init finished.\n")
-
-###############################################################################
-# [Hmi methods] Connect signals methods
-
- def connect_signals(self):
- """
- -> Connection of 'triggered' signals from 'QMenu' or 'QAction'.
- -> Connection of 'currentIndexChanged' signals from 'QComboBox'.
- -> Connection of 'clicked' signals from 'QPushButton'.
- """
- #######################################################################
- # Actions in menus
-
- self.ui.actionQuit_Paparazzi_UAV.triggered.connect(self.close)
-
- self.ui.actionSetManager.triggered.connect(self.settings.show)
- self.ui.actionSave_2.triggered.connect(self.save_current_config)
-
- self.ui.actionSave_3.triggered.connect(self.save_current_session)
-
- self.ui.actionFull_screen.triggered.connect(self.fullscreen_view)
- self.ui.actionHide_overviews.triggered.connect(self.toggle_overview)
-
- self.ui.actionAbout_Paparazzi_UAV.triggered.connect(
- self.credits_popup.show)
- self.ui.actionTutorial.triggered.connect(self.tutorial_popup.show)
-
- #######################################################################
- # Equipment tab
-
- for list_widget in self.change_config_widgets:
- list_widget.itemSelectionChanged.connect(functools.partial(
- self.change_current_item, list_widget))
- self.ui.current_settings.itemClicked.connect(
- self.change_setting_check_state)
-
- self.ui.current_set.currentIndexChanged.connect(self.change_current_set)
- self.ui.current_configuration.currentIndexChanged.connect(
- self.change_current_config)
-
- self.ui.remove_item.clicked.connect(self.remove_item_from_config)
- self.ui.add_item.clicked.connect(self.open_item_file_chooser)
- self.ui.edit.clicked.connect(self.open_gedit)
-
- self.ui.quick_build.clicked.connect(self.quick_build)
-
- #######################################################################
- # Build / flash tab
-
- for combo_widget in self.target_widgets:
- combo_widget.currentIndexChanged.connect(functools.partial(
- self.change_current_target, combo_widget))
-
- for widget in self.log_filters_widgets:
- widget.clicked.connect(self.change_sensitivity_filters)
-
- for widget in self.messages_level_widgets:
- widget.clicked.connect(self.change_messages_level)
-
- self.ui.clean.clicked.connect(self.clean_config)
- self.ui.build.clicked.connect(self.build_config)
- self.ui.upload.clicked.connect(self.flash_device)
- self.ui.show_console.clicked.connect(functools.partial(
- self.switch_to_tab, 3))
-
- self.ui.device.currentIndexChanged.connect(self.change_current_device)
-
- #######################################################################
- # Session tab
-
- for combo_widget in self.session_widgets:
- combo_widget.currentIndexChanged.connect(functools.partial(
- self.change_current_session, combo_widget))
-
- self.ui.programs.itemSelectionChanged.connect(
- self.change_current_program)
- self.ui.options.itemSelectionChanged.connect(
- self.change_current_option)
-
- self.ui.play_stop_program.clicked.connect(functools.partial(
- self.run_program, None))
- for button in self.start_all_buttons:
- button.clicked.connect(self.start_all_programs)
- for button in self.kill_all_buttons:
- button.clicked.connect(self.kill_all_programs)
-
- self.ui.remove_program.clicked.connect(
- self.remove_program_from_session)
- self.ui.remove_option.clicked.connect(self.remove_option_from_program)
- self.ui.add_option.clicked.connect(self.add_option_to_program)
- self.ui.options.itemChanged.connect(self.edit_current_option)
-
- #######################################################################
- # Console tab
-
- self.ui.clean_console.clicked.connect(self.clean_console)
-
- #######################################################################
- # Other widgets connected
-
- self.ui.open_home_terminal.clicked.connect(self.open_terminal)
- self.ui.switch_mode.clicked.connect(self.switch_current_mode)
-
-###############################################################################
-# [Hmi methods] Reimplemented methods
-
- def closeEvent(self, event):
- """
- :param event: QEvent object automatically filled when 'closed' signal
- caught.
- -> Called automatically when when 'closed' signal caught.
- -> Kill all processes still running.
- -> Update the cache file.
- -> Call the real mainWindow closeEvent to finish the 'app.exec_'
- events loop.
- """
- for process in [self.clean, self.build, self.upload]:
- # + list(self.running_programs.values()):
- # /!\ REQUIREMENT : DON'T KILL SESSION PROCESSES WHEN THE
- # APPLICATION EXITS...
- if process is not None:
- try:
- process.subprocess.kill()
- except ProcessLookupError:
- print("Process : '%s' already stopped. "
- "Can't be killed again !\n" % process.name)
- else:
- print("Process : '%s' killed !\n" % process.name)
-
- # Ask for a confirmation if some data are unsaved and quit saving
- # these data :
- if self.configurations_changed != {} or self.sessions_changed != {}:
- if self.sessions_changed != {parser.SIMULATION_NAME:
- parser.SIMULATION_SESSION} \
- and self.sessions_changed != {parser.REPLAY_NAME:
- parser.REPLAY_SESSION}:
- self.data_changed_popup.show()
- self.data_changed_popup.accepted.connect(
- self.save_all_changed_data)
- self.data_changed_popup.rejected.connect(
- self.save_cache_data)
- else:
- print("A special in-code defined session (Session or Replay) "
- "has been changed and could not have been saved...\n")
- self.save_cache_data()
- else:
- self.save_cache_data()
-
-###############################################################################
-# [Hmi methods] Update widgets methods
-
- def update_home_button(self):
- self.ui.open_home_terminal.setText(env.PAPARAZZI_HOME)
-
- def update_mode_button(self):
- if self.dev_mode:
- self.ui.switch_mode.setText("Developer")
- else:
- self.ui.switch_mode.setText("Standard")
-
- def update_versions(self):
- for field, value in zip([self.ui.run_version, self.ui.build_version],
- [self.run_version, self.build_version]):
- if value is not None:
- field.setText(value)
- else:
- field.setText(UNKNOWN_VALUE)
-
- def switch_to_tab(self, tab_index):
- self.ui.main_tab.setCurrentIndex(tab_index)
-
- def init_tools_menu(self):
- """
- -> Clear the 'Tools' menu actions (menubar).
- -> Fill the 'Tools' menu with the names found in 'control_panel.xml'
- -> Connect each action to the corresponding tool process.
- """
- # The tools are sorted first by whether they are favorite or not, then by their names
- for tool in sorted(self.data.tools.values(), key=lambda tool: (not tool.favorite, tool.name)):
- if not tool.blacklisted:
- command = functools.partial(self.add_program_to_session, tool)
- icon_name = tool.icon if tool.icon is not None else DEFAULT_TOOL_ICON
- icon_path = "/".join([env.PAPARAZZI_HOME, ICONS_TOOLS_PATH, icon_name])
- self.ui.tools_menu.add_item(tool.name, icon_path, command)
-
- def fullscreen_view(self):
- if self.isMaximized():
- self.resize(800, 600)
- else:
- self.showMaximized()
-
- def toggle_overview(self):
- if self.ui.dockWidget.isVisible():
- self.ui.dockWidget.hide()
- self.ui.actionHide_overviews.setText("Show overviews")
- else:
- self.ui.dockWidget.show()
- self.ui.actionHide_overviews.setText("Hide overviews")
-
- def update_set_combo(self):
- """
- -> Clear the 'Set' combobox.
- -> Fill the combobox with the names found in 'conf.xml'.
- """
- self.ui.current_set.clear()
- sorted_names = parser.sorted_sets_names(self.data.sets)
- self.ui.current_set.addItems(sorted_names)
- self.ui.current_set.setCurrentText(self.current_set.name)
-
- def update_config_combo(self):
- """
- -> Clear the 'Configuration' combobox.
- -> Fill the combobox with the configurations names corresponding to the
- current selected set.
- -> Save the current settings check state when configuration changed.
- (allows to the configuration to be recovered when selected again)
- """
- self.ui.current_configuration.clear()
- sorted_names = parser.sorted_current_configs_names(
- self.data.configurations,
- self.current_set)
- self.ui.current_configuration.addItems(sorted_names)
- self.ui.current_configuration.setCurrentText(self.current_config.name)
-
- def update_config_items_lists(self):
- """
- -> Disable or hide widgets and buttons to init config.
- -> Set config ID and color.
- -> Set config items by category.
- -> Make 'settings' items checkable and set check-boxes.
- """
- set_widgets_visibility(self.display_config_widgets +
- self.change_config_widgets, False)
- set_widgets_availability([self.ui.remove_item,
- self.ui.edit], False)
- set_widgets_visibility(self.flight_plan_buttons, False)
-
- self.ui.current_id.setText(self.current_config.id)
- color = gui.generate_qcolor(self.current_config.color[0])
- palette = gui.generate_widget_palette(self.ui.current_color, color)
- self.ui.current_color.setPalette(palette)
-
- clear_widgets(self.change_config_widgets)
- for widget, values in zip(self.change_config_widgets,
- [self.current_config.airframes,
- self.current_config.settings +
- self.current_config.modules,
- self.current_config.flight_plan,
- self.current_config.radio,
- self.current_config.telemetry]):
- for value in values:
- value = value.strip()
- if value:
- widget.addItem(value)
- if values:
- set_widgets_visibility([widget], True)
-
- for i in range(self.ui.current_settings.count()):
- item = self.ui.current_settings.item(i)
- item.setFlags(Core.Qt.ItemIsUserCheckable | Core.Qt.ItemIsEnabled |
- Core.Qt.ItemIsSelectable)
- if item.text().startswith("["):
- item.setText(item.text().strip("[]"))
- item.setCheckState(Core.Qt.Unchecked)
- else:
- item.setCheckState(Core.Qt.Checked)
-
- self.update_config_overview_lists()
-
- def update_config_overview_lists(self):
- """
- -> Hide all the configuration overview widgets.
- -> Clear these widgets.
- -> Copy the content of the real configuration QListWidget widgets.
- -> Keep only the basename of long items (put full name in tooltip).
- -> Display the widgets only if not empty (save some vertical space).
- """
- set_widgets_visibility(self.display_config_widgets, False)
- clear_widgets(self.display_config_widgets)
- for input_widget, display_widget in zip(self.change_config_widgets*2,
- self.display_config_widgets):
- items_full_names = []
- for i in range(input_widget.count()):
- item_full_name = input_widget.item(i).text()
- item_name = os.path.splitext(
- os.path.basename(item_full_name))[0]
- display_widget.addItem(item_name)
- items_full_names.append(item_full_name)
- display_widget.setToolTip("\n".join(items_full_names))
- if display_widget.count() != 0:
- display_widget.setVisible(True)
-
- def update_target_combos(self, combo_widgets):
- """
- :param combo_widgets:
- -> Clear the 2 'Target' combo widgets.
- -> Fill them with the targets available for the current configuration.
- """
- clear_widgets(combo_widgets)
- sorted_names = parser.sorted_current_targets_names(
- self.current_config.targets)
- for widget in combo_widgets:
- widget.addItems(sorted_names)
- widget.setCurrentText(self.current_target.name)
-
- def update_log_filters(self):
- """
- -> Load the last filters from the cache.
- -> Disable the filters if the level is minimum or maximum.
- -> Set the filters check state by the current LogFilter object
- properties.
- """
- if self.current_log_filter.level == cs.MINIMAL_MESSAGES_LEVEL:
- self.ui.important.setChecked(True)
- set_widgets_availability(self.log_filters_widgets, False)
- elif self.current_log_filter.level == cs.ALL_MESSAGES_LEVEL:
- self.ui.all.setChecked(True)
- set_widgets_availability(self.log_filters_widgets, False)
- else:
- self.ui.custom.setChecked(True)
- set_widgets_availability(self.log_filters_widgets, True)
- self.ui.display_default.setChecked(self.current_log_filter.default)
- self.ui.display_info.setChecked(self.current_log_filter.info)
- self.ui.display_warnings.setChecked(self.current_log_filter.warning)
- self.ui.display_errors.setChecked(self.current_log_filter.error)
-
- def update_device_combo(self):
- """
- -> Clear the 'Device' combobox.
- -> Search compatible boards for current target.
- -> Update the combo-box with devices corresponding to each board.
- -> Deal with empty devices list because of default Wi-Fi flash.
- """
- self.ui.device.clear()
- current_devices = []
- for device in self.data.devices.values():
- if device.name != parser.DEFAULT_DEVICE_NAME:
- for board_regex in device.boards_regex:
- found_match = re.search(board_regex, self.current_target.board)
- if found_match:
- current_devices.append(device)
- break
- else:
- current_devices.append(device)
- sorted_names = parser.sorted_current_devices_names(current_devices)
- self.ui.device.addItems(sorted_names)
- self.ui.device.setCurrentText(self.current_device.name)
- self.ui.device.setEnabled(True)
-
- def update_session_combos(self):
- """
- -> Clear the 'Session' combobox.
- -> Fill it with the sessions found in 'control_panel.xml'
- """
- clear_widgets(self.session_widgets)
- sorted_names = parser.sorted_sessions_names(self.data.sessions)
- for widget in self.session_widgets:
- widget.addItems(sorted_names)
- sep_index = sorted_names.index(parser.SESSIONS_COMBO_SEP)
- variant = Core.QVariant(not Core.Qt.ItemIsEnabled)
- widget.setItemData(sep_index, variant, Core.Qt.UserRole - 1)
- widget.setCurrentText(self.current_session.name)
-
- def update_programs_list(self):
- """
- -> Clear the programs QListWidget.
- -> Fill it with the programs available for the current session.
- -> Update the programs overview widgets with the same programs.
- -> Init the play/stop program button HMI.
- """
- self.ui.programs.clear()
- self.current_program = None
- sorted_names = parser.sorted_current_programs_names(
- self.current_session)
- self.ui.programs.addItems(sorted_names)
- for i in range(self.ui.programs.count()):
- self.ui.programs.item(i).setIcon(self.stop_qicon)
- self.update_programs_overviews()
- self.update_program_button()
- self.update_program_options_list()
-
- set_widgets_availability([self.ui.play_stop_program,
- self.ui.remove_program,
- self.ui.add_option] +
- self.kill_all_buttons, False)
-
- def update_programs_overviews(self):
- """
- -> Clear the programs overview QListWidget widgets.
- -> Fill them with the current programs widget items.
- -> Set their icon to stopped state.
- """
- clear_widgets(self.display_programs_widgets)
- for input_widget, display_widget in zip([self.ui.programs]*2,
- self.display_programs_widgets):
- for i in range(input_widget.count()):
- display_widget.addItem(input_widget.item(i).text())
- item = display_widget.item(i)
- item.setIcon(self.stop_qicon)
- item.setFlags(Core.Qt.ItemIsEnabled)
-
- def update_program_options_list(self):
- """
- -> Clear the options QListWidget.
- -> Fill them with the current options of the selected program if
- possible (and detect the option shape : tuple or str).
- """
- self.ui.options.clear()
- self.current_option = None
- if self.current_program is not None:
- options = self.current_program[1].options
- for option in options:
- option_str = option
- if type(option) is tuple:
- option_str = " ".join(option)
- self.ui.options.addItem(option_str)
- for i in range(self.ui.options.count()):
- item = self.ui.options.item(i)
- item.setFlags(Core.Qt.ItemIsEditable | Core.Qt.ItemIsEnabled |
- Core.Qt.ItemIsSelectable)
- self.ui.remove_option.setEnabled(False)
-
- def init_build_flash_hmi(self):
- """
- -> Kill the build processes if already running.
- -> Clear the build widgets.
- """
- clear_widgets([self.ui.build_result_icon,
- self.ui.build_result,
- self.ui.flash_resut_icon,
- self.ui.flash_result] + self.messages_nb_widgets)
-
- def update_flags_nb_hmi(self, compilation_object):
- """
- :param compilation_object:
- -> Update the flags number QLabel widgets at each log sent to the
- console.
- """
- self.ui.errors_nb.setText(str(
- compilation_object.flags[cs.ERROR_FLAG]))
- self.ui.warnings_nb.setText(str(
- compilation_object.flags[cs.WARNING_FLAG]))
- self.ui.info_nb.setText(str(
- compilation_object.flags[cs.INFO_FLAG]))
-
-###############################################################################
-# [Hmi methods] Clean methods
-
- def set_clean_started_hmi(self):
- """
- -> Turn HMI to clean running state.
- """
- self.init_build_flash_hmi()
- self.clean_running = True
- set_widgets_availability([self.ui.build, self.ui.upload,
- self.ui.quick_build] +
- self.target_widgets, False)
- self.ui.clean.setText("Stop !")
- self.setCursor(gui.generate_qcursor(gui.WAIT_CURSOR_SHAPE))
-
- def set_clean_stopped_hmi(self):
- """
- -> Turn HMI to clean stopped state.
- -> Display the result of the clean process.
- -> Switch to the build / flash tab.
- """
- self.clean_running = False
- set_widgets_availability([self.ui.build, self.ui.quick_build,
- self.ui.clean] +
- self.target_widgets, True)
- if self.current_target.name not in self.simulation_targets_names:
- self.ui.upload.setEnabled(True)
- self.ui.clean.setText("Clean")
- self.setCursor(gui.generate_qcursor(gui.NORMAL_CURSOR_SHAPE))
- self.update_flags_nb_hmi(self.clean)
- errors = self.clean.flags[cs.ERROR_FLAG]
- if self.clean.exit_code == proc.INTERRUPTED_EXIT_CODE:
- self.ui.build_result.setText("Clean aborted by user !")
- self.ui.build_result_icon.setPixmap(self.error_qpixmap)
- elif errors != 0 or self.clean.exit_code == proc.DEFAULT_EXIT_CODE:
- self.ui.build_result.setText("Error(s) found " +
- "during clean. " +
- "Please try again !")
- self.ui.build_result_icon.setPixmap(self.error_qpixmap)
- elif self.clean.exit_code == proc.SUCCESS_EXIT_CODE:
- self.ui.build_result.setText("Clean done with success !")
- self.ui.build_result_icon.setPixmap(self.ok_qpixmap)
- else:
- self.ui.build_result.setText("Unknown error !")
- self.ui.build_result_icon.setPixmap(self.error_qpixmap)
- self.clean = None
- self.switch_to_tab(1)
-
-###############################################################################
-# [Hmi methods] Build methods
-
- def set_build_started_hmi(self):
- """
- -> Turn HMI to build running state.
- """
- self.init_build_flash_hmi()
- self.build_running = True
- set_widgets_availability([self.ui.clean, self.ui.upload,
- self.ui.quick_build] +
- self.target_widgets, False)
- self.ui.build.setText("Stop !")
- self.setCursor(gui.generate_qcursor(gui.WAIT_CURSOR_SHAPE))
-
- def set_build_stopped_hmi(self):
- """
- -> Turn HMI to build stopped state.
- -> Display the result of the build process.
- -> Switch to the build / flash tab.
- """
- self.build_running = False
- set_widgets_availability([self.ui.clean, self.ui.quick_build,
- self.ui.build] +
- self.target_widgets, True)
- if self.current_target.name not in self.simulation_targets_names:
- self.ui.upload.setEnabled(True)
- self.ui.build.setText("Build")
- self.setCursor(gui.generate_qcursor(gui.NORMAL_CURSOR_SHAPE))
- self.update_flags_nb_hmi(self.build)
- errors = self.build.flags[cs.ERROR_FLAG]
- if self.build.exit_code == proc.INTERRUPTED_EXIT_CODE:
- self.ui.build_result.setText("Build aborted by user !")
- self.ui.build_result_icon.setPixmap(self.error_qpixmap)
- elif errors != 0 or self.build.exit_code == proc.DEFAULT_EXIT_CODE:
- self.ui.build_result.setText("Error(s) found " +
- "during build. " +
- "Please try again !")
- self.ui.build_result_icon.setPixmap(self.error_qpixmap)
- elif self.build.exit_code == proc.SUCCESS_EXIT_CODE:
- self.ui.build_result.setText("Build done with success !")
- self.ui.build_result_icon.setPixmap(self.ok_qpixmap)
- else:
- self.ui.build_result.setText("Unknown error !")
- self.ui.build_result_icon.setPixmap(self.error_qpixmap)
- self.build = None
- self.switch_to_tab(1)
-
-###############################################################################
-# [Hmi methods] Flash methods
-
- def set_flash_started_hmi(self):
- """
- -> Turn HMI to flash running state.
- """
- self.init_build_flash_hmi()
- self.upload_running = True
- set_widgets_availability([self.ui.clean, self.ui.build,
- self.ui.quick_build, self.ui.device] +
- self.target_widgets, False)
- self.ui.upload.setText("Stop !")
- self.setCursor(gui.generate_qcursor(gui.WAIT_CURSOR_SHAPE))
- clear_widgets([self.ui.flash_resut_icon,
- self.ui.flash_result])
-
- def set_flash_stopped_hmi(self):
- """
- -> Turn HMI to flash stopped state.
- -> Display the result of the upload process.
- -> Switch to the build / flash tab.
- """
- self.upload_running = False
- set_widgets_availability([self.ui.clean, self.ui.build,
- self.ui.upload,
- self.ui.quick_build, self.ui.device] +
- self.target_widgets, True)
- self.ui.upload.setText("Upload")
- self.setCursor(gui.generate_qcursor(gui.NORMAL_CURSOR_SHAPE))
- self.update_flags_nb_hmi(self.upload)
- errors = self.upload.flags[cs.ERROR_FLAG]
- if self.upload.exit_code == proc.INTERRUPTED_EXIT_CODE:
- self.ui.flash_result.setText("Upload aborted by user !")
- self.ui.flash_resut_icon.setPixmap(self.error_qpixmap)
- elif errors != 0 or self.upload.exit_code == proc.DEFAULT_EXIT_CODE:
- self.ui.flash_result.setText("Error(s) found " +
- "during upload. " +
- "Please try again !")
- self.ui.flash_resut_icon.setPixmap(self.error_qpixmap)
- elif self.upload.exit_code == proc.SUCCESS_EXIT_CODE:
- self.ui.flash_result.setText("Upload done with success !")
- self.ui.flash_resut_icon.setPixmap(self.ok_qpixmap)
- else:
- self.ui.flash_result.setText("Unknown error !")
- self.ui.flash_resut_icon.setPixmap(self.error_qpixmap)
- self.upload = None
- self.switch_to_tab(1)
-
-###############################################################################
-# [Hmi methods] Program methods
-
- def update_program_button(self):
- """
- -> Update the play/stop program button HMI to correct state.
- """
- if self.current_program is not None:
- self.ui.play_stop_program.setEnabled(True)
- if self.current_program[1].name in self.running_programs.keys():
- self.ui.play_stop_program.setIcon(self.stop_qicon)
- self.ui.play_stop_program.setText("Stop")
- else:
- self.ui.play_stop_program.setIcon(self.start_qicon)
- self.ui.play_stop_program.setText("Start")
- else:
- self.ui.play_stop_program.setEnabled(False)
- self.ui.play_stop_program.setIcon(self.start_qicon)
-
- def set_program_started_hmi(self, program_process):
- """
- :param program_process:
- -> Turn HMI to program running state.
- """
- self.running_programs[program_process.program.name] = program_process
-
- items = [widget.findItems(program_process.program.name,
- Core.Qt.MatchExactly)[0]
- for widget in [self.ui.programs,
- self.ui.programs_overview_1,
- self.ui.programs_overview_2]]
- set_items_icons(items, self.start_qicon)
- self.update_program_button()
-
- if self.running_programs != {}:
- set_widgets_availability([self.ui.session,
- self.ui.session_overview_1,
- self.ui.session_overview_2,
- self.ui.current_set],
- False)
- set_widgets_availability(self.kill_all_buttons, True)
- set_widgets_availability(self.start_all_buttons, False)
-
- def set_program_stopped_hmi(self, program_process):
- """
- :param program_process:
- -> Turn HMI to program stopped state.
- -> Display the result of the program process.
- -> Switch to the sessions management tab.
- """
- self.running_programs.pop(program_process.program.name)
-
- items = [widget.findItems(program_process.program.name,
- Core.Qt.MatchExactly)[0]
- for widget in [self.ui.programs,
- self.ui.programs_overview_1,
- self.ui.programs_overview_2]]
- set_items_icons(items, self.stop_qicon)
- self.update_program_button()
-
- if self.running_programs == {}:
- set_widgets_availability([self.ui.session,
- self.ui.session_overview_1,
- self.ui.session_overview_2,
- self.ui.current_set],
- True)
- set_widgets_availability(self.kill_all_buttons, False)
- set_widgets_availability(self.start_all_buttons, True)
- self.switch_to_tab(2)
-
-###############################################################################
-# [Hmi methods] Write log methods
-
- def write_log_in_console(self, log, flag, log_type):
- """
- :param log:
- :param flag:
- :param log_type:
- -> Get the logs sent by the processes when a 'log_sent' signal is
- caught.
- -> Treat the log depending if it's an application or a process one.
- -> Put color to the log line and write it into the console.
- """
- if log_type == cs.PROCESS_MESSAGE_TYPE:
- if self.current_log_filter.write_line_decision(flag):
- str_color = cs.BACKGROUNDS_COLORS[flag]
- background_qcolor = gui.generate_qcolor(str_color)
- self.console.write(log,
- backgroud_color=background_qcolor)
- elif log_type == cs.APPLICATION_MESSAGE_TYPE:
- if log != "\n":
- str_color = cs.FONTS_COLORS[flag]
- font_qcolor = gui.generate_qcolor(str_color)
- self.console.write(log, font_color=font_qcolor)
-
- def animate_progress_bar(self):
- """
- -> For all running build / flash processes, animate the progress bar.
- -> Change the text displayed in the result field according to its size
- and the current direction.
- """
- for program, label in zip([self.clean, self.build, self.upload],
- [self.ui.build_result, self.ui.build_result,
- self.ui.flash_result]):
- if program is not None:
- last_result_text = label.text()
- last_result_text_size = label.fontMetrics().\
- boundingRect(last_result_text).width()
- field_width = label.width()
-
- if len(last_result_text) < PROGRESS_BAR_SPEED+1:
- new_result_text = PROGRESS_BAR_LINE * PROGRESS_BAR_SPEED \
- + PROGRESS_BAR_CURSOR
- self.progress_bar_to_left = False
- elif last_result_text_size > field_width - 100\
- or self.progress_bar_to_left:
- new_result_text = last_result_text[PROGRESS_BAR_SPEED:]
- self.progress_bar_to_left = True
- else:
- new_result_text = PROGRESS_BAR_LINE * PROGRESS_BAR_SPEED \
- + last_result_text
- self.progress_bar_to_left = False
- label.setText(new_result_text)
-
-###############################################################################
-# [Hmi methods] Widgets connected with signals methods
-
- def switch_current_mode(self):
- """
- -> Real switch but no real effect (no dev mode yet...)
- -> RELOAD MAIN WINDOW WITH NEW WIDGETS ?
- """
- self.dev_mode = not self.dev_mode
- self.update_mode_button()
-
- def change_current_set(self):
- """
- -> Get current set when combobox value changed.
- -> Symbolic link to 'config.xml' changed to the new set.
- -> Update configuration and its items.
- """
- self.save_all_changed_configurations()
- current_set_name = self.ui.current_set.currentText()
- if current_set_name:
- self.current_set = self.data.sets[current_set_name]
- point_symbol_link_to(self.current_set.name)
- self.update_config_combo()
- self.update_config_items_lists()
-
- def change_current_config(self):
- """
- -> Get current configuration when combobox value changed.
- -> Update target and device values.
- -> Stop the build processes if some running.
- -> Init the build / flash HMI to be ready to a new process.
- """
- current_config_name = self.ui.current_configuration.currentText()
- if current_config_name:
- self.current_config = self.data.configurations[current_config_name]
- self.update_config_items_lists()
- self.update_target_combos([self.ui.target])
- self.update_device_combo()
- self.init_build_flash_hmi()
-
- def change_current_item(self, list_widget):
- """
- :param list_widget:
- -> Update the current selected item : (widget, item, object).
- -> Clear the others selected items in other categories.
- -> Update the configuration management HMI (buttons).
- -> Make the flight plan buttons appear or disappear.
- -> Update all the check states of the settings list if the current
- selected item is a setting.
- """
- current_selected_item = list_widget.currentItem()
- if current_selected_item is not None:
- current_item_text = current_selected_item.text()
- self.current_item = (list_widget,
- current_selected_item,
- current_item_text)
- widgets_to_clear = [_ for _ in self.change_config_widgets]
- widgets_to_clear.remove(list_widget)
- clear_list_widgets_selection(widgets_to_clear)
- set_widgets_availability([self.ui.remove_item,
- self.ui.edit], True)
- set_widgets_visibility(self.flight_plan_buttons,
- list_widget.objectName() ==
- "current_flight_plan")
-
- def change_current_target(self, combo_widget):
- """
- :param combo_widget:
- -> Update the current target and the devices combobox (related).
- -> Possible to change the target from 2 widgets. That's why the
- solution found is strange...
- """
- current_target_name = combo_widget.currentText()
- if current_target_name and self.change_target_bool:
- self.current_target = self.current_config.targets[
- current_target_name]
- self.ui.upload.setEnabled(self.current_target.name
- not in self.simulation_targets_names)
- other_widgets = [_ for _ in self.target_widgets]
- other_widgets.remove(combo_widget)
- # TODO BETTER : AVOID THE SIGNALS PING-PONG BETWEEN TARGETS WIDGETS
- self.change_target_bool = False
- self.update_target_combos(other_widgets)
- self.change_target_bool = True
- self.update_device_combo()
-
- def change_sensitivity_filters(self):
- """
- -> Get checkbox values to set the current filters.
- -> Update the filters values for the console.
- """
- self.current_log_filter.set_sensitivity_filter(
- self.ui.display_default.checkState(),
- self.ui.display_info.checkState(),
- self.ui.display_warnings.checkState(),
- self.ui.display_errors.checkState())
- self.update_log_filters()
-
- def change_messages_level(self):
- """
- -> Get radiobutton value to set the current message level.
- -> Update the level value for the console.
- """
- if self.ui.all.isChecked():
- self.current_log_filter.set_level(cs.ALL_MESSAGES_LEVEL)
- self.current_log_filter.set_sensitivity_filter(2, 2, 2, 2)
- elif self.ui.custom.isChecked():
- self.current_log_filter.set_level(cs.CUSTOM_MESSAGES_LEVEL)
- elif self.ui.important.isChecked():
- self.current_log_filter.set_level(cs.MINIMAL_MESSAGES_LEVEL)
- self.current_log_filter.set_sensitivity_filter(0, 0, 2, 2)
- self.update_log_filters()
-
- def change_current_device(self):
- """
- -> Get current device when combobox value changed.
- -> If no device available, the default flash mode is WiFi.
- """
- current_device_name = self.ui.device.currentText()
- if current_device_name:
- self.current_device = self.data.devices[current_device_name]
-
- def change_current_session(self, combo_widget):
- """
- :param combo_widget:
- -> Get current session when combobox value changed.
- -> Update programs HMI for the new selected session.
- -> Deselect the last selected program and clear the options.
- """
- current_session_name = combo_widget.currentText()
- if current_session_name:
- clear_list_widgets_selection([self.ui.programs] +
- self.display_programs_widgets)
- self.current_session = self.data.sessions[current_session_name]
- widgets = [_ for _ in self.session_widgets]
- widgets.remove(combo_widget)
- for widget in widgets:
- widget.setCurrentText(self.current_session.name)
- self.update_programs_list()
- self.update_program_options_list()
- self.ui.options.clear()
-
- def change_current_program(self):
- """
- -> Get current selected program when QListWidget selection changed.
- -> Update options HMI for the new selected program.
- """
- current_selected_item = self.ui.programs.currentItem()
- if current_selected_item is not None:
- item_name = current_selected_item.text()
- if item_name in self.current_session.programs.keys():
- self.current_program = (current_selected_item,
- self.current_session.programs[
- item_name])
- self.ui.remove_program.setEnabled(item_name not in
- self.running_programs.keys())
- self.ui.add_option.setEnabled(True)
- self.update_program_options_list()
- self.update_program_button()
-
- def change_current_option(self):
- """
- -> Get the current selected option when QListWidget selection changed.
- -> Enable options management HMI.
- """
- current_selected_item = self.ui.options.currentItem()
- if current_selected_item is not None:
- item_name = current_selected_item.text()
- self.current_option = (current_selected_item, item_name)
- self.ui.remove_option.setEnabled(True)
-
- def open_item_file_chooser(self):
- """
- -> While left part of equipment tab is not finished, a simple file
- chooser is used to select new equipment items.
- -> Add the selected new item to the correct category if possible.
- """
- file_chooser = Widgets.QFileDialog()
- fc_title = "Select a file to add to '" +\
- self.current_config.name + "'..."
- fc_dir = env.PAPARAZZI_CONF
- fc_filter = "XML file(*.xml)"
- path, other = file_chooser.getOpenFileName(file_chooser,
- fc_title,
- fc_dir,
- fc_filter)
- if path:
- filename = parser.full_to_conf_path(path)
- self.add_item_to_config(filename)
-
- def open_gedit(self):
- """
- -> Open a text editor depending on the OS found.
- """
- if self.current_item is not None:
-
- if env.OS in ["linux", "linux2"]:
- file_path = os.path.join(CONF_PATH, self.current_item[2])
- command = " ".join(["gedit", file_path])
- try:
- os.popen(command)
- except ChildProcessError:
- LOGGER.error("Gedit text editor is not available !\n")
- self.switch_to_tab(3)
- elif env.OS in []:
- pass
- else:
- LOGGER.error("No text file editor found for your OS !\n")
- self.switch_to_tab(3)
-
- def clean_console(self):
- """
- -> Just clear the console QTextEdit widget.
- """
- self.ui.console.clear()
-
- def open_terminal(self):
- """
- -> Open a terminal in the Paparazzi home directory depending on the OS
- found.
- """
- if env.OS in ["linux", "linux2"]:
- command_terms = ["gnome-terminal", "--working-directory ",
- env.PAPARAZZI_HOME]
- command = " ".join(command_terms)
- os.popen(command)
- else:
- LOGGER.error("No terminal shortcut available for your OS !\n")
- self.switch_to_tab(3)
-
-###############################################################################
-# [Hmi methods] Processes management (connected with signals) methods
-
- def quick_build(self):
- """
- -> Clean the current configuration when the quick build button is
- clicked.
- -> Give the information to the clean function that a build process
- is planned after the clean process.
- """
- self.switch_to_tab(1)
- self.clean_config(is_quick_build=True)
-
- def clean_config(self, is_quick_build=False):
- """
- :param is_quick_build:
- -> Clean the current configuration if not already started.
- -> Else, abort the current clean process and set the HMI to the
- initial state.
- """
- if not self.clean_running:
- self.clean = proc.Process(proc.CLEAN,
- configuration=self.current_config)
- if self.clean.check_before_start():
- self.clean.start()
- self.clean.subprocess.finished.connect(self.set_clean_stopped_hmi)
- self.clean.process_log_sent.connect(functools.partial(
- self.update_flags_nb_hmi, self.clean))
- self.clean.process_log_sent.connect(self.write_log_in_console)
- self.clean.process_log_sent.connect(self.animate_progress_bar)
- self.set_clean_started_hmi()
-
- if is_quick_build:
- self.clean.subprocess.finished.connect(functools.partial(
- self.build_config))
- else:
- LOGGER.error("Incorrect config, can't clean !\n")
- self.switch_to_tab(3)
- else:
- self.clean.process_killed.emit()
- self.ui.clean.setEnabled(False)
-
- def build_config(self):
- """
- -> Build the current configuration if not already started.
- -> Else, abort the current build process and set the HMI to the
- initial state.
- """
- if not self.build_running:
- self.build = proc.Process(proc.BUILD,
- configuration=self.current_config,
- target=self.current_target)
- self.save_current_config()
-
- if self.build.check_before_start():
- self.build.start()
- self.build.subprocess.finished.connect(self.set_build_stopped_hmi)
- self.build.process_log_sent.connect(functools.partial(
- self.update_flags_nb_hmi, self.build))
- self.build.process_log_sent.connect(self.write_log_in_console)
- self.build.process_log_sent.connect(self.animate_progress_bar)
- self.set_build_started_hmi()
- else:
- LOGGER.error("Incorrect config, can't build !\n")
- self.switch_to_tab(3)
- else:
- self.build.process_killed.emit()
- self.ui.build.setEnabled(False)
-
- def flash_device(self):
- """
- -> Flash the current configuration if not already started.
- -> Else, abort the current upload process and set the HMI to the
- initial state.
- """
- if not self.upload_running:
- self.upload = proc.Process(proc.UPLOAD,
- configuration=self.current_config,
- target=self.current_target,
- device=self.current_device)
- if self.upload.check_before_start():
- self.upload.start()
- self.upload.subprocess.finished.connect(self.set_flash_stopped_hmi)
- self.upload.process_log_sent.connect(functools.partial(
- self.update_flags_nb_hmi, self.upload))
- self.upload.process_log_sent.connect(self.write_log_in_console)
- self.upload.process_log_sent.connect(self.animate_progress_bar)
- self.set_flash_started_hmi()
- else:
- LOGGER.error("Incorrect device, can't upload !\n")
- self.switch_to_tab(3)
- else:
- self.upload.process_killed.emit()
- self.ui.upload.setEnabled(False)
-
- def run_program(self, program):
- """
- :param program:
- -> Run the current selected program if not already started.
- Else, abort it and set the HMI to the initial state.
- """
- if program is None and self.current_program is not None:
- program_item, program = self.current_program
- if program.name not in self.running_programs.keys():
- new_program_proc = proc.Process(proc.PROGRAM,
- program=program,
- configuration=self.current_config,
- target=self.current_target)
- if new_program_proc.check_before_start():
- new_program_proc.start()
- new_program_proc.subprocess.finished.connect(functools.partial(
- self.set_program_stopped_hmi, new_program_proc))
- new_program_proc.process_log_sent.connect(
- self.write_log_in_console)
- self.set_program_started_hmi(new_program_proc)
- else:
- self.running_programs[program.name].process_killed.emit()
- self.ui.play_stop_program.setEnabled(False)
-
- def start_all_programs(self):
- """
- -> Kill all running programs of the current session.
- -> Start all programs not running (so it's a restart).
- -> Keep the current selected program if there's one.
- """
- for program in self.current_session.programs.values():
- if program.name not in self.running_programs.keys():
- self.run_program(program)
-
- def kill_all_programs(self):
- """
- -> Kill all running programs of the current session.
- -> Keep the current selected program if there's one.
- """
- for program in self.current_session.programs.values():
- if program.name in self.running_programs.keys():
- self.run_program(program)
-
-###############################################################################
-# [Hmi methods] Data management (connected with signals) methods
-
- def change_setting_check_state(self, clicked_item):
- """
- :param clicked_item:
- -> Save the new check state of settings items.
- -> Add the current config to changed configs => ask to save
- before quitting the application.
- """
- if self.current_config is not None\
- and self.current_item is not None:
- list_widget, list_item, item_name = self.current_item
- setting_name = item_name
- setting_state = list_item.checkState()
- # TODO BETTER : NO SOLUTION (OR SIGNAL) FOUND TO DETECT A CLICK ON
- # : TODO : 'QListWidgetItem' SO ONLY CURRENT ITEM CHECKSTATE
- # : TODO : SHOULD BE CHANGED... (NOT WORKING WELL)
- if clicked_item == list_item:
- if parser.SETTINGS_REF in setting_name:
- settings_modules = self.current_config.settings
- else:
- settings_modules = self.current_config.modules
- settings_modules_names = [item.strip("[]") for item in settings_modules]
- setting_index = settings_modules_names.index(setting_name)
- settings_modules.pop(setting_index)
- if not setting_state:
- setting_name = "[" + setting_name + "]"
- settings_modules.insert(setting_index, setting_name)
-
- self.configurations_changed[self.current_config.name] = \
- self.current_config
- index = self.ui.current_configuration.currentIndex()
- self.ui.current_configuration.setItemIcon(index, self.changed_qicon)
- else:
- clicked_item.setCheckState(setting_state)
-
- def remove_item_from_config(self):
- """
- -> Remove an item from the current selected configuration.
- -> Impossible to remove all airframes because it doesn't make sense.
- """
- if self.current_config is not None \
- and self.current_item is not None:
- list_widget, list_item, item_name = self.current_item
- if not (list_widget is self.ui.current_airframes and
- len(list_widget) == 1):
- if list_widget == self.ui.current_settings and \
- not list_item.checkState():
- item_name = "[" + item_name + "]"
-
- config_attributes_lists = [self.current_config.airframes,
- self.current_config.settings,
- self.current_config.modules,
- self.current_config.flight_plan,
- self.current_config.radio,
- self.current_config.telemetry]
- for attributes_list in config_attributes_lists:
- if item_name in attributes_list:
- attributes_list.remove(item_name)
- break
-
- list_widget.takeItem(list_widget.row(list_item))
- list_widget.clearSelection()
- self.current_item = None
- self.ui.remove_item.setEnabled(False)
- if not list_widget:
- list_widget.setVisible(False)
- if list_widget is self.ui.current_flight_plan:
- set_widgets_visibility(self.flight_plan_buttons, False)
- self.update_config_overview_lists()
-
- self.configurations_changed[self.current_config.name] = \
- self.current_config
- index = self.ui.current_configuration.currentIndex()
- self.ui.current_configuration.setItemIcon(index,
- self.changed_qicon)
- else:
- LOGGER.error("You can't remove all airframes from a "
- "configuration !\n")
- self.switch_to_tab(3)
-
- def add_item_to_config(self, filename):
- """
- :param filename:
- -> Add the selected filename to the correct category if it's possible.
- -> Else, an error is raised in the console.
- -> If a setting is added, it's checked by default.
- """
- if self.current_config is not None:
- keywords = [parser.AIRFRAME_REF, parser.SETTINGS_REF,
- parser.MODULES_REF, parser.FP_REF,
- parser.RADIO_REF, parser.TELEMETRY_REF]
- fields = [self.current_config.airframes,
- self.current_config.settings,
- self.current_config.modules,
- self.current_config.flight_plan,
- self.current_config.radio,
- self.current_config.telemetry]
- widgets = self.change_config_widgets.copy()
- widgets.insert(2, self.ui.current_settings)
-
- match_found = False
- for keyword, field, widget in zip(keywords, fields, widgets):
- if keyword in filename:
- field.append(filename)
- widget.addItem(filename)
- last_item = widget.item(widget.count()-1)
- if widget == self.ui.current_settings:
- last_item.setFlags(Core.Qt.ItemIsUserCheckable |
- Core.Qt.ItemIsEnabled |
- Core.Qt.ItemIsSelectable)
- last_item.setCheckState(Core.Qt.Checked)
- widget.setCurrentItem(last_item)
- match_found = True
- break
-
- if match_found:
- self.configurations_changed[self.current_config.name] = \
- self.current_config
- index = self.ui.current_configuration.currentIndex()
- self.ui.current_configuration.setItemIcon(index,
- self.changed_qicon)
- else:
- LOGGER.error("The selected file '%s' is not an acceptable file in"
- " a configuration !\n", filename)
- self.switch_to_tab(3)
-
- def remove_program_from_session(self):
- """
- -> Remove the selected program from the current selected session.
- -> Add the current session to changed sessions => ask to save
- before quitting the application.
- """
- if self.current_session is not None \
- and self.current_program is not None:
- program_item, program = self.current_program
-
- self.current_session.programs.pop(program.name)
- self.update_programs_list()
-
- self.sessions_changed[self.current_session.name] = \
- self.current_session
- index = self.ui.session.currentIndex()
- self.ui.session.setItemIcon(index, self.changed_qicon)
- self.switch_to_tab(2)
-
- def add_program_to_session(self, program):
- """
- :param program:
- -> Add a program object (only a copy of a tool from the Tools menu
- for now) to the current selected session.
- """
- if self.current_session is not None:
-
- new_program_name = parser.find_unused_item_name(
- self.current_session.programs, program.name)
- new_program = db.Program(new_program_name, program.command,
- program.options)
- self.current_session.programs[new_program.name] = new_program
- self.update_programs_list()
- new_item = self.ui.programs.findItems(new_program.name,
- Core.Qt.MatchExactly)[0]
- self.ui.programs.setCurrentItem(new_item)
-
- self.sessions_changed[self.current_session.name] = \
- self.current_session
- index = self.ui.session.currentIndex()
- self.ui.session.setItemIcon(index, self.changed_qicon)
- self.switch_to_tab(2)
-
- def remove_option_from_program(self):
- """
- -> Remove the selected option from the current selected program.
- """
- if self.current_program is not None \
- and self.current_option is not None:
- program_item, program = self.current_program
- option_item, option = self.current_option
-
- if type(option) is str:
- program.options.remove(option)
- else:
- program.options.remove(tuple(option.split()))
- self.update_program_options_list()
-
- self.sessions_changed[self.current_session.name] = \
- self.current_session
- index = self.ui.session.currentIndex()
- self.ui.session.setItemIcon(index, self.changed_qicon)
-
- def add_option_to_program(self):
- """
- -> Add an option to the current selected program.
- """
- if self.current_session is not None \
- and self.current_program is not None:
- program_item, program = self.current_program
- new_option = ""
- program.options.append(new_option)
- self.update_program_options_list()
- last_item = self.ui.options.item(self.ui.options.count()-1)
- self.ui.options.setCurrentItem(last_item)
-
- self.sessions_changed[self.current_session.name] = \
- self.current_session
- index = self.ui.session.currentIndex()
- self.ui.session.setItemIcon(index, self.changed_qicon)
-
- def edit_current_option(self):
- """
- -> Edit the selected option when enter pressed after changes.
- """
- if self.current_program is not None \
- and self.current_option is not None:
- program_item, program = self.current_program
-
- old_option_item, old_option = self.current_option
- old_option_index = program.options.index(old_option)
- program.options.remove(old_option)
- self.change_current_option()
- new_option_item, new_option = self.current_option
- program.options.insert(old_option_index, new_option)
-
- self.sessions_changed[self.current_session.name] = \
- self.current_session
- index = self.ui.session.currentIndex()
- self.ui.session.setItemIcon(index, self.changed_qicon)
-
-###############################################################################
-# [Hmi methods] Data management : XML writing methods
-
- def save_current_config(self):
- """
- -> Update the new values of the current configuration in the
- corresponding XML file.
- """
- if self.current_config.name in self.configurations_changed.keys():
- self.configurations_changed.pop(self.current_config.name)
- index = self.ui.current_configuration.currentIndex()
- self.ui.current_configuration.setItemIcon(index,
- gui.generate_qicon())
-
- LOGGER.info("Saving '%s' configuration...",
- self.current_config.name)
- parser.save_configuration(self.current_set.name,
- self.current_config)
- LOGGER.info("'%s' configuration saved.\n",
- self.current_config.name)
- else:
- LOGGER.info("Nothing to save, configuration already up-to-date.\n")
-
- def save_current_session(self):
- """
- -> Update the new values of the current session in the
- corresponding 'control_panel.xml' file.
- -> Deal with the in-code defined sessions (Simulation, Replay).
- """
- if self.current_session.name in self.sessions_changed.keys():
- self.sessions_changed.pop(self.current_session.name)
- index = self.ui.session.currentIndex()
- self.ui.session.setItemIcon(index, gui.generate_qicon())
- if self.current_session.name not in [parser.SIMULATION_NAME,
- parser.REPLAY_NAME]:
- LOGGER.info("Saving '%s' session...", self.current_session.name)
- parser.save_session(parser.CONTROL_PANEL_FILE,
- self.current_session)
- LOGGER.info("'%s' session saved.\n", self.current_session.name)
- else:
- LOGGER.error("'%s' is an in-code defined session. "
- "Impossible to save it !\n",
- self.current_session.name)
- print("'%s' is an in-code defined session. "
- "Impossible to save it !\n"
- % self.current_session.name)
- self.switch_to_tab(3)
- else:
- LOGGER.info("Nothing to save, session already up-to-date.\n")
-
- def save_all_changed_configurations(self):
- changed_configs = [_ for _ in self.configurations_changed.values()]
- for config in changed_configs:
- self.current_config = config
- self.save_current_config()
-
- def save_all_changed_sessions(self):
- changed_sessions = [_ for _ in self.sessions_changed.values()]
- for session in changed_sessions:
- self.current_session = session
- self.save_current_session()
-
- def save_all_changed_data(self):
- self.save_all_changed_configurations()
- self.save_all_changed_sessions()
- print("All changes in data saved.\n")
- self.save_cache_data()
-
- def save_cache_data(self):
- """
- -> Change values in cache with the 'write' mode of the common parsing
- function.
- """
- LOGGER.info("Cache updating...")
- print("Cache updating...")
- current_geometry_str = " ".join(map(str,
- [self.geometry().x(),
- self.geometry().y(),
- self.geometry().width(),
- self.geometry().height()]))
- current_log_filters_str = " ".join(map(str,
- [self.current_log_filter.level,
- self.current_log_filter.default,
- self.current_log_filter.info,
- self.current_log_filter.warning,
- self.current_log_filter.error]))
-
- parser.parse_cache_file("w", self.data.cache_file,
- geometry_str=current_geometry_str,
- set_str=self.current_set.name,
- config_str=self.current_config.name,
- target_str=self.current_target.name,
- log_filters_str=current_log_filters_str,
- device_str=self.current_device.name,
- session_str=self.current_session.name)
- LOGGER.info("Cache now up-to-date.\n")
- print("Cache now up-to-date.\n")
diff --git a/sw/supervision/python/icons/accessories-text-editor.svg b/sw/supervision/python/icons/accessories-text-editor.svg
deleted file mode 100644
index 03db109a64..0000000000
--- a/sw/supervision/python/icons/accessories-text-editor.svg
+++ /dev/null
@@ -1,107 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/sw/supervision/python/icons/dialog-apply.svg b/sw/supervision/python/icons/dialog-apply.svg
deleted file mode 100644
index f009b90ee3..0000000000
--- a/sw/supervision/python/icons/dialog-apply.svg
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/sw/supervision/python/icons/dialog-error.svg b/sw/supervision/python/icons/dialog-error.svg
deleted file mode 100644
index a3d6de4d72..0000000000
--- a/sw/supervision/python/icons/dialog-error.svg
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/sw/supervision/python/icons/dialog-warning-symbolic.svg b/sw/supervision/python/icons/dialog-warning-symbolic.svg
deleted file mode 100644
index e9474a9d14..0000000000
--- a/sw/supervision/python/icons/dialog-warning-symbolic.svg
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
- image/svg+xml
-
- Gnome Symbolic Icon Theme
-
-
-
- Gnome Symbolic Icon Theme
-
-
-
-
diff --git a/sw/supervision/python/icons/dialog-warning.png b/sw/supervision/python/icons/dialog-warning.png
deleted file mode 100644
index d1020c6d9e..0000000000
Binary files a/sw/supervision/python/icons/dialog-warning.png and /dev/null differ
diff --git a/sw/supervision/python/icons/edit-clear.svg b/sw/supervision/python/icons/edit-clear.svg
deleted file mode 100644
index 568fe9de66..0000000000
--- a/sw/supervision/python/icons/edit-clear.svg
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/sw/supervision/python/icons/go-up.svg b/sw/supervision/python/icons/go-up.svg
deleted file mode 100644
index e5e58672cd..0000000000
--- a/sw/supervision/python/icons/go-up.svg
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/sw/supervision/python/icons/gtk-info.svg b/sw/supervision/python/icons/gtk-info.svg
deleted file mode 100644
index f1ec53786a..0000000000
--- a/sw/supervision/python/icons/gtk-info.svg
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/sw/supervision/python/icons/list-add.svg b/sw/supervision/python/icons/list-add.svg
deleted file mode 100644
index f40a948324..0000000000
--- a/sw/supervision/python/icons/list-add.svg
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/sw/supervision/python/icons/list-remove.svg b/sw/supervision/python/icons/list-remove.svg
deleted file mode 100644
index ebc6bdbe8f..0000000000
--- a/sw/supervision/python/icons/list-remove.svg
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/sw/supervision/python/icons/media-playback-pause.svg b/sw/supervision/python/icons/media-playback-pause.svg
deleted file mode 100644
index fde2760829..0000000000
--- a/sw/supervision/python/icons/media-playback-pause.svg
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/sw/supervision/python/icons/media-playback-start.svg b/sw/supervision/python/icons/media-playback-start.svg
deleted file mode 100644
index 87c34d3025..0000000000
--- a/sw/supervision/python/icons/media-playback-start.svg
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/sw/supervision/python/icons/penguin_icon.png b/sw/supervision/python/icons/penguin_icon.png
deleted file mode 100644
index f61d8024e9..0000000000
Binary files a/sw/supervision/python/icons/penguin_icon.png and /dev/null differ
diff --git a/sw/supervision/python/icons/process-stop.svg b/sw/supervision/python/icons/process-stop.svg
deleted file mode 100644
index 1c9162caab..0000000000
--- a/sw/supervision/python/icons/process-stop.svg
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/sw/supervision/python/icons/search_field.png b/sw/supervision/python/icons/search_field.png
deleted file mode 100644
index c3264f66d9..0000000000
Binary files a/sw/supervision/python/icons/search_field.png and /dev/null differ
diff --git a/sw/supervision/python/icons/system-run.png b/sw/supervision/python/icons/system-run.png
deleted file mode 100644
index ad6d80b0de..0000000000
Binary files a/sw/supervision/python/icons/system-run.png and /dev/null differ
diff --git a/sw/supervision/python/icons/utilities-terminal.svg b/sw/supervision/python/icons/utilities-terminal.svg
deleted file mode 100644
index add2893910..0000000000
--- a/sw/supervision/python/icons/utilities-terminal.svg
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- image/svg+xml
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/sw/supervision/python/lib/console.py b/sw/supervision/python/lib/console.py
deleted file mode 100644
index 945712cc7a..0000000000
--- a/sw/supervision/python/lib/console.py
+++ /dev/null
@@ -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
diff --git a/sw/supervision/python/lib/database.py b/sw/supervision/python/lib/database.py
deleted file mode 100644
index f773ba314b..0000000000
--- a/sw/supervision/python/lib/database.py
+++ /dev/null
@@ -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
diff --git a/sw/supervision/python/lib/default_cache.xml b/sw/supervision/python/lib/default_cache.xml
deleted file mode 100644
index 0201937d78..0000000000
--- a/sw/supervision/python/lib/default_cache.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
--
--
--
--
--
--
--
--
--
--
--
--
--
--
diff --git a/sw/supervision/python/lib/environment.py b/sw/supervision/python/lib/environment.py
deleted file mode 100644
index 6315673439..0000000000
--- a/sw/supervision/python/lib/environment.py
+++ /dev/null
@@ -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)
diff --git a/sw/supervision/python/lib/gui.py b/sw/supervision/python/lib/gui.py
deleted file mode 100644
index cd9c2f19ee..0000000000
--- a/sw/supervision/python/lib/gui.py
+++ /dev/null
@@ -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()
diff --git a/sw/supervision/python/main.py b/sw/supervision/python/main.py
deleted file mode 100755
index f5a87f3f29..0000000000
--- a/sw/supervision/python/main.py
+++ /dev/null
@@ -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()
diff --git a/sw/supervision/python/operation_panel.py b/sw/supervision/python/operation_panel.py
new file mode 100644
index 0000000000..db0601844d
--- /dev/null
+++ b/sw/supervision/python/operation_panel.py
@@ -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)
diff --git a/sw/supervision/python/paparazzicenter.py b/sw/supervision/python/paparazzicenter.py
new file mode 100755
index 0000000000..22bd241f5e
--- /dev/null
+++ b/sw/supervision/python/paparazzicenter.py
@@ -0,0 +1,128 @@
+#!/usr/bin/python3
+# Copyright (C) 2008-2022 The Paparazzi Team
+# released under GNU GPLv2 or later. See COPYING file.
+import os
+import conf
+from PyQt5.QtWidgets import *
+from PyQt5 import QtCore, QtGui
+from configuration_panel import ConfigurationPanel
+from operation_panel import OperationPanel
+import utils
+from typing import Dict
+from lxml import etree as ET
+from app_settings import AppSettings
+
+
+class PprzCenter(QMainWindow):
+ def __init__(self, parent=None):
+ QMainWindow.__init__(self, parent=parent)
+ self.setWindowTitle("Paparazzi Center")
+ icon = QtGui.QIcon(os.path.join(utils.PAPARAZZI_HOME, "data", "pictures", "penguin_logo.svg"))
+ self.setWindowIcon(icon)
+ self.addMenu()
+ self.tabwidget = QTabWidget(parent=self)
+ self.setCentralWidget(self.tabwidget)
+ self.configuration_panel = ConfigurationPanel(self.tabwidget)
+ self.operation_panel = OperationPanel(self.tabwidget)
+ self.tabwidget.addTab(self.configuration_panel, "Configuration")
+ self.tabwidget.addTab(self.operation_panel, "Operation")
+ self.status_msg = QLabel()
+ self.statusBar().addWidget(self.status_msg)
+ self.fill_status_bar()
+ self.statusBar().show()
+ self.configuration_panel.msg_error.connect(self.handle_error)
+ self.configuration_panel.clear_error.connect(self.clear_error)
+ self.operation_panel.session.program_spawned.connect(self.configuration_panel.disable_sets)
+ self.operation_panel.session.programs_all_stopped.connect(self.configuration_panel.enable_sets)
+ self.configuration_panel.ac_changed.connect(self.operation_panel.session.set_aircraft)
+ self.configuration_panel.splitter.splitterMoved.connect(self.update_left_pane_width)
+ settings = utils.get_settings()
+ window_size = settings.value("ui/window_size", QtCore.QSize(1000, 600), QtCore.QSize)
+ self.resize(window_size)
+ self.configuration_panel.init()
+ self.operation_panel.session.init()
+
+ def addMenu(self):
+ menubar = QMenuBar()
+ file_menu = QMenu("&File", menubar)
+ help_menu = QMenu("&Help", menubar)
+ menubar.addMenu(file_menu)
+ menubar.addMenu(help_menu)
+ settings_action = QAction("&Edit Settings", file_menu)
+ file_menu.addAction(settings_action)
+ about_action = QAction("&About", help_menu)
+ help_menu.addAction(about_action)
+
+ def edit_settings():
+ settings_dialog = AppSettings(self)
+ settings_dialog.show()
+ settings_action.triggered.connect(edit_settings)
+ about_action.triggered.connect(lambda: QMessageBox.about(self, "About Paparazzi", utils.ABOUT_TEXT))
+
+ self.setMenuBar(menubar)
+
+ def closeEvent(self, e: QtGui.QCloseEvent) -> None:
+ if self.operation_panel.session.any_program_running():
+ self.operation_panel.session.programs_all_stopped.connect(self.close)
+ self.operation_panel.session.stop_all()
+ e.ignore()
+ self.operation_panel.session.programs_all_stopped.connect(self.close)
+ else:
+ if utils.get_settings().value("always_keep_changes", False, bool):
+ self.configuration_panel.conf.save()
+ else:
+ conf_tree_orig = self.configuration_panel.conf.tree_orig
+ conf_tree = self.configuration_panel.conf.to_xml_tree()
+ if ET.tostring(conf_tree) != ET.tostring(conf_tree_orig):
+ buttons = QMessageBox.question(self, "Save configuration?",
+ "The configuration has changed, do you want to save it?")
+ if buttons == QMessageBox.Yes:
+ self.configuration_panel.conf.save()
+ else:
+ self.configuration_panel.conf.restore_conf()
+ self.configuration_panel.conf.save()
+ self.save_gconf()
+ e.accept()
+
+ def save_gconf(self):
+ settings = utils.get_settings()
+ settings.setValue("ui/window_size", self.size())
+ settings.setValue("ui/last_AC", self.configuration_panel.get_current_ac())
+ settings.setValue("ui/last_session", self.operation_panel.session.get_current_session())
+
+ def update_left_pane_width(self, pos, index):
+ utils.get_settings().setValue("ui/left_pane_width", pos)
+
+ def fill_status_bar(self):
+ home_widget = QWidget()
+ home_lay = QHBoxLayout(home_widget)
+ home_lay.addWidget(QLabel("HOME: ", home_widget))
+ home_button = QPushButton(utils.PAPARAZZI_HOME, home_widget)
+ home_lay.addWidget(home_button)
+ home_button.clicked.connect(lambda: utils.open_terminal(utils.PAPARAZZI_HOME))
+ self.statusBar().addPermanentWidget(home_widget)
+ self.statusBar().addPermanentWidget(utils.make_line(None, True))
+ label_version = QLabel("Version={}".format(utils.get_version()))
+ self.statusBar().addPermanentWidget(label_version)
+ self.statusBar().addPermanentWidget(utils.make_line(None, True))
+ label_build = QLabel("Build={}".format(utils.get_build_version()))
+ self.statusBar().addPermanentWidget(label_build)
+
+ def handle_error(self, msg):
+ self.status_msg.setText(msg)
+ self.statusBar().setStyleSheet("background-color: red;")
+ # self.statusBar().showMessage(msg)
+
+ def clear_error(self):
+ self.status_msg.setText("")
+ self.statusBar().setStyleSheet("")
+
+
+if __name__ == "__main__":
+ import sys
+ app = QApplication(sys.argv)
+ main_window = PprzCenter()
+ main_window.show()
+ # qApp.aboutToQuit.connect(main_window.quit)
+ sys.exit(app.exec_())
+
diff --git a/sw/supervision/python/parser.py b/sw/supervision/python/parser.py
deleted file mode 100644
index edcec8f21d..0000000000
--- a/sw/supervision/python/parser.py
+++ /dev/null
@@ -1,855 +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.database as db
-import lib.environment as env
-
-import xml.etree.ElementTree as Et
-import os
-import re
-import logging
-
-from typing import List, Dict
-import shutil
-
-
-###############################################################################
-# [Constants]
-
-STRINGS_FALSE = ["False", "false", None, "0"]
-
-LOGGER = logging.getLogger("[PARSER]")
-
-XML_EXT = ".xml"
-TEST_XML = "test.xml"
-
-# GLOBAL XML TREE REFERENCES :
-NAME_REF = "name"
-VALUE_REF = "value"
-CONSTANT_REF = "constant"
-VARIABLE_REF = "variable"
-MODE_REF = "mode"
-FAVORITE_REF = "favorite"
-
-# REFERENCES AND STRUCTURES OF CONF XML FILES :
-# CONF_STRUCTURE = [(node_name, [node_attributes],
-# [(child_name, [child_attributes],
-# [children_of_child...]),
-# (...)
-# ])
-# ]
-
-# CACHE :
-CACHE = "cache"
-CACHE_FILE = "." + CACHE + XML_EXT
-DEFAULT_CACHE_FILE = "default_cache" + XML_EXT
-DEFAULT_CACHE_PATH = os.path.join("lib", DEFAULT_CACHE_FILE)
-
-LAST_GEOMETRY = "last_geometry"
-LAST_GEOMETRY_REF = "system/window/geometry"
-LAST_SET = "last_set"
-LAST_SET_REF = "data/set"
-LAST_CONFIG = "last_config"
-LAST_CONFIG_REF = "data/config"
-LAST_TARGET = "last target"
-LAST_TARGET_REF = "data/target"
-LAST_LOG_FILTERS = "last log filters"
-LAST_LOG_FILTERS_REF = "system/filters"
-LAST_DEVICE = "last device"
-LAST_DEVICE_REF = "data/device"
-LAST_SESSION = "last session"
-LAST_SESSION_REF = "data/session"
-
-# SET :
-SET = "conf"
-SET_REGEX = re.compile(r"" + SET + "([_-][\w]*)?\.xml$")
-
-CONF_REF = "aircraft"
-ID_REF = "ac_id"
-AIRFRAME_REF = "airframe"
-SETTINGS_REF = "settings"
-MODULES_REF = "module"
-FP_REF = "flight_plan"
-RADIO_REF = "radio"
-TELEMETRY_REF = "telemetry"
-SETTINGS_MODULES_REF = "settings_modules"
-COLOR_REF = "gui_color"
-
-CONFIG_TAG_REF = CONF_REF
-
-SET_STRUCTURE = [(SET, [],
- [(CONF_REF, [NAME_REF, ID_REF, AIRFRAME_REF, RADIO_REF,
- TELEMETRY_REF, FP_REF, SETTINGS_REF,
- SETTINGS_MODULES_REF, COLOR_REF],
- [])
- ])
- ]
-
-
-# DEVICE :
-DEVICE = "flash_modes"
-DEVICES_FILE = DEVICE + XML_EXT
-
-BOARD_REF = "board"
-BOARDS_REF = "boards"
-
-DEVICE_TAG_REF = MODE_REF
-
-DEVICE_STRUCTURE = [(DEVICE, [],
- [(MODE_REF, [NAME_REF],
- [(VARIABLE_REF, [NAME_REF, VALUE_REF],
- [(BOARDS_REF, [],
- [(BOARD_REF, [NAME_REF],
- [])
- ])
- ])
- ])
- ])
- ]
-
-# DEFAULT DEVICE :
-DEFAULT_DEVICE_NAME = " __Default__ "
-DEFAULT_DEVICE = db.Device(DEFAULT_DEVICE_NAME)
-
-# TOOLS
-TOOLS = "tools"
-
-# CONTROL_PANEL :
-CONTROL_PANEL = "control_panel"
-CONTROL_PANEL_FILE = CONTROL_PANEL + XML_EXT
-
-SECTION_REF = "section"
-PROGRAM_REF = "program"
-SESSION_REF = "session"
-COMMAND_REF = "command"
-ICON_REF = "icon"
-FLAG_REF = "flag"
-OPTION_REF = "arg"
-
-SESSION_TAG_REF = "/".join((SECTION_REF, SESSION_REF))
-
-CONTROL_PANEL_STRUCTURE = [(CONTROL_PANEL, [NAME_REF],
- [(SECTION_REF, [NAME_REF],
- [(PROGRAM_REF, [NAME_REF, COMMAND_REF],
- [(OPTION_REF, [FLAG_REF, CONSTANT_REF],
- [])
- ])
- ]),
- (SECTION_REF, [NAME_REF],
- [(SESSION_REF, [NAME_REF],
- [(PROGRAM_REF, [NAME_REF],
- [(OPTION_REF, [FLAG_REF, CONSTANT_REF],
- [])
- ])
- ])
- ])
- ])
- ]
-
-# DEFAULT SESSIONS :
-SIMULATOR_OBJECT = db.Program("Simulator", "sw/simulator/pprzsim-launch",
- [("-a", "@AIRCRAFT"), ("-t", "@TARGET"),
- "--boot", "--norc"])
-GCS_OBJECT = db.Program("GCS", "sw/ground_segment/cockpit/gcs", [])
-SERVER_OBJECT = db.Program("Server", "sw/ground_segment/tmtc/server", ["-n"])
-PLAYER_OBJECT = db.Program("Log File Player", "sw/logalizer/play", [])
-
-SIMULATION_NAME = "Simulation"
-SIMULATION_SESSION = db.Session(SIMULATION_NAME,
- {SIMULATOR_OBJECT.name: SIMULATOR_OBJECT,
- GCS_OBJECT.name: GCS_OBJECT,
- SERVER_OBJECT.name: SERVER_OBJECT})
-SESSIONS_COMBO_SEP = " - - - - - - - - - - "
-REPLAY_NAME = "Replay"
-REPLAY_SESSION = db.Session(REPLAY_NAME,
- {PLAYER_OBJECT.name: PLAYER_OBJECT,
- SERVER_OBJECT.name: SERVER_OBJECT,
- GCS_OBJECT.name: GCS_OBJECT})
-
-# AIRFRAME :
-FIRMWARE_REF = "firmware"
-TARGET_REF = "target"
-BOARD_REF = "board"
-
-TARGET_TAG_REF = "/".join((FIRMWARE_REF, TARGET_REF))
-
-AIRFRAME_STRUCTURE = [] # TODO
-
-
-###############################################################################
-# [Functions]
-
-def full_path_to_filename(path):
- return os.path.basename(path)
-
-
-def full_to_conf_path(full_path):
- return os.path.relpath(full_path, start=env.PAPARAZZI_CONF)
-
-
-def filename_to_conf_path(filename):
- return os.path.join(env.PAPARAZZI_CONF, filename)
-
-
-def find_unused_item_name(dictionary, name):
- new_name = name
- nb = 0
- while new_name in dictionary.keys():
- nb += 1
- new_name = new_name.split("[")[0] + "[" + str(nb) + "]"
- return new_name
-
-
-###############################################################################
-# [Functions] Data management functions
-
-def sorted_sets_names(sets):
- sets_names = [set_object.name for set_object in sets.values()]
- return sorted(sets_names)
-
-
-def sorted_current_configs_names(configurations, current_set):
- configs_names = [configurations[config_name].name
- for config_name in current_set.configs_names]
- return sorted(configs_names)
-
-
-def sorted_current_targets_names(targets):
- target_names = [target.name for target in targets.values()]
- return sorted(target_names)
-
-
-def sorted_sessions_names(sessions):
- sessions_names = [session.name for session in sessions.values()]
- sorted_names = sorted(sessions_names)
- old_simulation_index = sorted_names.index(SIMULATION_NAME)
- sorted_names.insert(0, sorted_names.pop(old_simulation_index))
- old_replay_index = sorted_names.index(REPLAY_NAME)
- sorted_names.insert(1, sorted_names.pop(old_replay_index))
- sorted_names.insert(2, SESSIONS_COMBO_SEP)
- return sorted_names
-
-
-def sorted_current_programs_names(current_session):
- programs_names = [program.name for program
- in current_session.programs.values()]
- return sorted(programs_names)
-
-
-def sorted_current_devices_names(devices):
- devices_names = [device.name for device in devices]
- return sorted(devices_names)
-
-
-def sorted_tools_names(tools):
- tools_names = [tool.name for tool in tools.values()]
- return sorted(tools_names)
-
-
-###############################################################################
-# [Functions] Load cache from '.cache' file
-
-def parse_cache_file(mode, cache_file,
- geometry_str=None, set_str=None, config_str=None,
- target_str=None, log_filters_str=None,
- device_str=None, session_str=None):
- """
- :param mode:
- :param cache_file:
- :param geometry_str:
- :param set_str:
- :param config_str:
- :param target_str:
- :param log_filters_str:
- :param device_str:
- :param session_str:
- -> Scan 'cache_file' to get tags by name reference.
- -> Read values of tags in 'r' mode.
- -> Write new values of tags in 'w' mode.
- -> Except an incorrect XML format and raise ERROR.
- """
- cache_dict = {}
- try:
- try:
- cache_tree = Et.parse(cache_file)
- except FileNotFoundError:
- cache_tree = Et.parse(DEFAULT_CACHE_PATH)
-
- last_geometry_tag = cache_tree.find(LAST_GEOMETRY_REF)
- last_set_tag = cache_tree.find(LAST_SET_REF)
- last_config_tag = cache_tree.find(LAST_CONFIG_REF)
- last_target_tag = cache_tree.find(LAST_TARGET_REF)
- last_log_filters_tag = cache_tree.find(LAST_LOG_FILTERS_REF)
- last_device_tag = cache_tree.find(LAST_DEVICE_REF)
- last_session_tag = cache_tree.find(LAST_SESSION_REF)
-
- last_tags_list = [last_geometry_tag, last_set_tag,
- last_config_tag, last_target_tag,
- last_log_filters_tag, last_device_tag,
- last_session_tag]
- if mode == "r":
- for key, tag in zip([LAST_GEOMETRY, LAST_SET,
- LAST_CONFIG, LAST_TARGET,
- LAST_LOG_FILTERS, LAST_DEVICE,
- LAST_SESSION],
- last_tags_list):
- cache_dict[key] = tag.get(VALUE_REF)
- return cache_dict
-
- elif mode == "w":
- for tag, string in zip(last_tags_list,
- [geometry_str, set_str,
- config_str, target_str,
- log_filters_str, device_str,
- session_str]):
- tag.set(VALUE_REF, string)
- cache_tree.write(cache_file)
-
- except Et.ParseError as msg:
- LOGGER.error("ERROR in syntax of XML file : '%s'. "
- "Original message : '%s'.", cache_file, msg)
-
-
-def load_cache():
- """
- -> Scan the 'python' current directory to find the '.cache.xml' file.
- -> Parse the cache file withe the 'w' mode to load the last values.
- -> Except multiple cache files and raise an ERROR if so.
- """
- cache_file = None
- for root, dirs, files in os.walk("./"):
- for file in files:
- ext = os.path.splitext(file)[1]
- if ext == XML_EXT and file == CACHE_FILE:
- cache_file = os.path.join(root, file)
- break
- if cache_file is not None:
- cache = parse_cache_file("r", cache_file)
- else:
- cache = parse_cache_file("r", DEFAULT_CACHE_PATH)
- cache_file = CACHE_FILE
-
- LOGGER.error("No cache file found ! Default cache '%s' loaded.",
- DEFAULT_CACHE_PATH)
- print("No cache file found ! Default cache '%s' loaded." %
- DEFAULT_CACHE_PATH)
-
- if logging.DEBUG:
- LOGGER.debug("Cache dictionary :\n%s", cache)
- return cache, cache_file
-
-def delete_cache():
- """
- -> Scan the 'python' current directory to find the '.cache.xml' file.
- -> Remove if found
- """
- cache_file = None
- for root, dirs, files in os.walk("./"):
- for file in files:
- ext = os.path.splitext(file)[1]
- if ext == XML_EXT and file == CACHE_FILE:
- cache_file = os.path.join(root, file)
- break
- if cache_file is not None:
- cache = os.remove(cache_file)
- LOGGER.debug("Deleting cache file '%s'\n", cache_file)
- else:
- LOGGER.debug("No cache to delete\n")
-
-
-###############################################################################
-# [Functions] Load files to init HMI
-
-def load_init_files(conf_path):
- """
- :param conf_path:
- -> Scan the conf directory to find the configuration files : all files
- matching with '*conf*.xml', 'control_panel.xml' and 'flash_modes.xml'.
- -> Show the result of scan if DEBUG mode is on (main.py)
- """
- conf_files, devices_files = [], []
- cp_file = None
-
- cp_path = conf_path + "/" + CONTROL_PANEL + XML_EXT
- if os.path.exists(cp_path):
- cp_file = cp_path
- else:
- raise Exception("%s not found!"% conf_path)
-
- tools_path = conf_path + "/" + TOOLS
- if not os.path.exists(tools_path):
- raise Exception("%s not found!" % tools_path)
-
- for root, dirs, files in os.walk(conf_path):
- for file in files:
- ext = os.path.splitext(file)[1]
- if ext == XML_EXT:
- xml_file = os.path.join(root, file)
- if SET_REGEX.search(file) is not None \
- and file != "%gconf.xml"\
- and xml_file != env.PAPARAZZI_CONF+"/conf.xml":
- conf_files.append(xml_file)
- elif file == CONTROL_PANEL_FILE and "airframes" not in root:
- pass
- elif file == DEVICES_FILE:
- devices_files.append(xml_file)
-
- result = "{} startup files found." # exclude control_panel.xml
- files_nb = sum((len(conf_files), len(devices_files)))
- info = result.format(files_nb)
-
- if logging.DEBUG:
- LOGGER.debug("'conf' files :")
- for file in conf_files:
- LOGGER.debug(file)
- LOGGER.debug("'devices' file(s) :")
- for file in devices_files:
- LOGGER.debug(file)
- LOGGER.debug("'control_panel' file(s) :")
- LOGGER.debug(cp_file)
- return conf_files, cp_file, tools_path, devices_files, info
-
-
-###############################################################################
-# [Functions] Load sets and configurations from 'conf' files
-
-def set_config_details(config_object, tag):
- """
- :param config_object:
- :param tag:
- -> Parse values of a configuration in the given XML tag element.
- -> Fills attributes of the given configuration object.
- """
- variables = [[] for _ in range(6)]
- keys = [SETTINGS_REF, SETTINGS_MODULES_REF, FP_REF, RADIO_REF,
- TELEMETRY_REF, COLOR_REF]
- for i, key in zip(range(6), keys):
- items = tag.get(key)
- if items:
- for item in items.split(" "):
- variables[i].append(item)
-
- config_object.settings = variables[0]
- config_object.modules = variables[1]
- config_object.flight_plan = variables[2]
- config_object.radio = variables[3]
- config_object.telemetry = variables[4]
- config_object.color = variables[5]
-
-
-def parse_targets(airframe_file):
- """
- :param airframe_file:
- -> Parse values of a target in the airframe file given.
- -> Except an incorrect XML format and raise ERROR.
- """
- available_targets = {}
- try:
- airframe_tree = Et.parse(filename_to_conf_path(airframe_file))
- targets_tags = airframe_tree.findall(TARGET_TAG_REF)
- for target_tag in targets_tags:
- name = target_tag.get(NAME_REF)
- board = target_tag.get(BOARD_REF)
- target_object = db.Target(name, board)
- available_targets[target_object.name] = target_object
-
- except Et.ParseError as msg:
- LOGGER.error("ERROR in syntax of XML file : '%s'. "
- "Original message : '%s'.", airframe_file, msg)
- except (FileNotFoundError, IOError) as msg:
- LOGGER.error("ERROR file '%s' not found or IO error"
- "Original message : '%s'.", airframe_file, msg)
- return available_targets
-
-
-def parse_conf_files(set_files):
- """
- :param set_files:
- -> Parse values of a target in the airframe file given.
- -> Except an incorrect XML format and raise ERROR.
- """
- configs, sets = {}, {}
- for set_file in set_files:
- try:
- set_name = full_to_conf_path(set_file)
- set_object = db.Set(set_name)
- set_tree = Et.parse(set_file)
- config_tags = set_tree.findall(CONFIG_TAG_REF)
- for tag in config_tags:
- config_name = tag.get(NAME_REF)
- config_id = tag.get(ID_REF)
- config_airframes = tag.get(AIRFRAME_REF).split(" ")
- config_targets = parse_targets(config_airframes[0])
- config_object = db.Configuration(config_name, config_id,
- config_airframes,
- config_targets)
- if config_object.id not in set_object.configs_names:
- set_config_details(config_object, tag)
- configs[config_object.name] = config_object
- set_object.configs_names.append(config_object.name)
- else:
- LOGGER.error("'%s' configuration can't be loaded in "
- "'%s' set because ID already exists !",
- config_object.name, set_object.name)
- sets[set_name] = set_object
-
- except Et.ParseError as msg:
- LOGGER.error("ERROR in syntax of XML file : '%s'. "
- "Original message : '%s'.", set_file, msg)
- return configs, sets
-
-
-def load_sets_and_configurations(set_files):
- """
- :param set_files:
- -> Parse the sets and the configurations from the '*conf*.xml' files.
- -> Show the result of scan if DEBUG mode is on (main.py)
- """
- configurations, sets = parse_conf_files(set_files)
- result = "{} sets and {} configurations found."
- sets_nb, configs_nb = len(sets), len(configurations)
- info = result.format(sets_nb, configs_nb)
-
- if logging.DEBUG:
- sets_str = "Sets :\n"
- for set_object in sets.values():
- sets_str += str(set_object) + "\n"
- LOGGER.debug(sets_str)
- configs_str = "Configurations :\n"
- for config_object in configurations.values():
- configs_str += str(config_object) + "\n"
- LOGGER.debug(configs_str)
- return sets, configurations, info
-
-
-def save_configuration(conf_file, config_object):
- """
- :param conf_file:
- :param config_object:
- -> Set the new values of the configuration object given into the
- corresponding XML file.
- """
- conf_file_path = filename_to_conf_path(conf_file)
-
- conf_tree = Et.parse(conf_file_path)
- config_tags = conf_tree.findall(CONFIG_TAG_REF)
- for tag in config_tags:
- if tag.get(NAME_REF) == config_object.name:
- attributes = [AIRFRAME_REF, SETTINGS_REF,
- SETTINGS_MODULES_REF, FP_REF,
- RADIO_REF, TELEMETRY_REF]
- new_values = [config_object.airframes, config_object.settings,
- config_object.modules, config_object.flight_plan,
- config_object.radio, config_object.telemetry]
- for attribute, values in zip(attributes, new_values):
- string = " ".join(values)
- tag.set(attribute, string)
- conf_tree.write(conf_file_path)
-
-
-###############################################################################
-# [Functions] Load sets devices from 'flash_modes' file
-
-def parse_devices_file(devices_file):
- """
- :param devices_file:
- -> Parse values of a device in the 'flash_modes' file given.
- -> Except an incorrect XML format and raise ERROR.
- """
- devices = {}
- try:
- devices_tree = Et.parse(devices_file)
- devices_tags = devices_tree.findall(DEVICE_TAG_REF)
- for device_tag in devices_tags:
- device_name = device_tag.get(NAME_REF)
- variable_tag = device_tag.find(VARIABLE_REF)
- variable_name = variable_tag.get(NAME_REF)
- variable_value = variable_tag.get(VALUE_REF)
- device_object = db.Device(device_name,
- variable_name, variable_value)
- for board_tag in device_tag.find(BOARDS_REF):
- board_name = board_tag.get(NAME_REF)
- device_object.boards_regex.append(board_name)
- devices[device_name] = device_object
- except Et.ParseError as msg:
- LOGGER.error("ERROR in syntax of XML file : '%s'. "
- "Original message : '%s'.", devices_file, msg)
- return devices
-
-
-def load_devices(devices_file):
- """
- :param devices_file:
- -> Parse the devices from the 'flash_modes.xml' files.
- -> Show the result of scan if DEBUG mode is on (main.py)
- """
- devices = parse_devices_file(devices_file)
- default_object = db.Device("Default")
- devices[default_object.name] = default_object
-
- devices[DEFAULT_DEVICE.name] = DEFAULT_DEVICE
-
- result = "{} devices found."
- devices_nb = len(devices)
- info = result.format(devices_nb)
-
- if logging.DEBUG:
- devices_str = "Devices :\n"
- for device_object in devices.values():
- devices_str += str(device_object) + "\n"
- LOGGER.debug(devices_str)
-
- return devices, info
-
-
-###############################################################################
-# [Functions] Load tools and sessions from 'control_panel' file
-
-def parse_arg_option(option_tag):
- """
- :param option_tag:
- -> Fill an option triplet (flag, argument type : 'constant' or 'variable',
- value of the argument) from an option tag in the XML tree.
- """
- option_flag = option_tag.get(FLAG_REF)
- constant = option_tag.get(CONSTANT_REF)
- variable = option_tag.get(VARIABLE_REF)
- if constant is not None:
- option = (option_flag, constant)
- elif variable is not None:
- option = (option_flag, variable)
- else:
- option = option_flag
- return option
-
-
-def parse_tools(tools_path):
- """
- :param tools_path:
- -> Parse all tools files in the 'tools_path' directory.
- -> Except an incorrect XML format and raise ERROR.
- """
- tools = {}
- blacklisted_tools = []
- blacklist = tools_path + "/" + "blacklisted"
- if os.path.exists(blacklist):
- with open(blacklist, 'r') as blacklist_fic:
- for line in blacklist_fic:
- line = line.strip()
- if line != "" and line[0] != "#":
- blacklisted_tools.append(line)
-
- for file in os.listdir(tools_path):
- if file.endswith(".xml"):
- file_path = tools_path + "/" + file
- try:
- tree = Et.parse(file_path)
- tool_tag = tree.getroot()
- if tool_tag.tag == PROGRAM_REF:
- tool_name = tool_tag.get(NAME_REF)
- tool_command = tool_tag.get(COMMAND_REF)
- icon = tool_tag.get(ICON_REF)
- fav = tool_tag.get(FAVORITE_REF)
- favorite = fav if fav is None else (fav not in STRINGS_FALSE)
-
- options = []
- for option_tag in tool_tag:
- option = parse_arg_option(option_tag)
- options.append(option)
- blacklisted = True if tool_name in blacklisted_tools else False
- tool_object = db.Program(tool_name, tool_command, options, icon, favorite=favorite, blacklisted=blacklisted)
- tools[tool_name] = tool_object
-
- except Et.ParseError as msg:
- LOGGER.error("ERROR in syntax of XML file : '%s'. "
- "Original message : '%s'.", file, msg)
- return tools
-
-
-def parse_sessions(cp_file, tools):
- """
- :param cp_file:
- :param tools:
- -> Parse all sessions in the 'control_panel.xml' file given.
- -> Except an incorrect XML format and raise ERROR.
- """
- sessions = {}
- try:
- cp_tree = Et.parse(cp_file)
- sessions_tags = cp_tree.findall(SESSION_TAG_REF)
- for session_tag in sessions_tags:
- session_name = session_tag.get(NAME_REF)
- session_programs = {}
- for program_tag in session_tag:
- program_name = program_tag.get(NAME_REF)
- command = tools[program_name].command
- options = []
- for option_tag in program_tag:
- option = parse_arg_option(option_tag)
- options.append(option)
- program_object = db.Program(program_name, command, options)
- session_programs[program_name] = program_object
- session_object = db.Session(session_name, session_programs)
- sessions[session_name] = session_object
-
- except Et.ParseError as msg:
- LOGGER.error("ERROR in syntax of XML file : '%s'. "
- "Original message : '%s'.", cp_file, msg)
- return sessions
-
-
-def load_sessions_and_programs(cp_file, tools_path):
- """
- :param cp_file:
- :param tools_path:
- -> Parse the tools and sessions from the 'tools:*xml' files.
- -> Add the default sessions 'simulation' & replay.
- -> Show the result of scan if DEBUG mode is on (main.py)
- """
- tools = parse_tools(tools_path)
- sessions = parse_sessions(cp_file, tools)
-
- sessions[SIMULATION_SESSION.name] = SIMULATION_SESSION
- sessions[REPLAY_SESSION.name] = REPLAY_SESSION
-
- result = "{} tools and {} sessions found."
- tools_nb, sessions_nb = len(tools), len(sessions)
- info = result.format(tools_nb, sessions_nb)
-
- if logging.DEBUG:
- tools_str = "Tools :\n"
- for tool_object in tools.values():
- tools_str += str(tool_object) + "\n"
- LOGGER.debug(tools_str)
- sessions_str = "Sessions :\n"
- for session_object in sessions.values():
- sessions_str += str(session_object) + "\n"
- LOGGER.debug(sessions_str)
-
- return tools, sessions, info
-
-
-def save_session(cp_file, session_object):
- """
- :param cp_file:
- :param session_object:
- -> Set the new values of the session object given into the
- corresponding XML file.
- """
- cp_file_path = filename_to_conf_path(cp_file)
-
- cp_tree = Et.parse(cp_file_path)
- cp_tags = cp_tree.findall(SESSION_TAG_REF)
- for session_tag in cp_tags:
- if session_tag.get(NAME_REF) == session_object.name:
- session_tag.clear()
- session_tag.set(NAME_REF, session_object.name)
- for program in session_object.programs.values():
- program_tag = Et.SubElement(session_tag, PROGRAM_REF,
- {NAME_REF: program.name})
- for option in program.options:
- attributes = {}
- if type(option) is tuple:
- attributes[FLAG_REF] = option[0]
- attributes[CONSTANT_REF] = option[1]
- else:
- attributes[FLAG_REF] = option
- _option_tag = Et.SubElement(program_tag, OPTION_REF,
- attributes)
- cp_tree.write(cp_file_path)
-
-
-###############################################################################
-# [Data class]
-
-class Data(object):
- """Class to manage a Data meta-object that gathers all the useful data
- parsed in the various XML files of the /conf directory."""
- def __init__(self, conf_path):
- self.conf_path = conf_path
-
- self.cache_file = None
- self.conf_files = []
- self.devices_file = None
- self.cp_file = None
- self.tools_path = None
-
- self.cache = {}
- self.configurations = {}
- self.sets = {}
- self.devices = {}
- self.tools = {}
- self.sessions = {}
-
- self.init_data()
-
-###############################################################################
-# [Data methods] Init data methods
-
- def init_data(self):
- self.load_cache()
- self.load_conf_files()
- self.load_sets_and_configs()
- self.load_devices()
- self.load_sessions_and_programs()
-
- LOGGER.info("All data loaded.\n")
-
- def load_cache(self):
- LOGGER.info("Loading cache...")
- self.cache, self.cache_file = load_cache()
- LOGGER.info("Cache loaded.\n")
-
- def load_conf_files(self):
- LOGGER.info("Scanning current directory...")
- self.conf_files, self.cp_file, self.tools_path, self.devices_file, load_info = \
- load_init_files(self.conf_path)
- LOGGER.debug(load_info)
- LOGGER.info("End of scan.\n")
-
- def load_sets_and_configs(self):
- LOGGER.info("Loading sets and configurations...")
- self.sets, self.configurations, \
- load_info = load_sets_and_configurations(self.conf_files)
- LOGGER.debug(load_info)
- LOGGER.info("Sets and configurations loaded.\n")
-
- def load_devices(self):
- LOGGER.info("Loading devices...")
- if len(self.devices_file) == 1:
- self.devices, load_info = load_devices(self.devices_file[0])
- LOGGER.debug(load_info)
- LOGGER.info("Devices loaded.\n")
- else:
- LOGGER.error("Multiple '%s' XML files !", DEVICE)
-
- def load_sessions_and_programs(self):
- LOGGER.info("Loading programs and sessions...")
- if self.cp_file is not None and self.tools_path is not None:
- self.tools, self.sessions, \
- load_info = load_sessions_and_programs(self.cp_file, self.tools_path)
- LOGGER.debug(load_info)
- LOGGER.info("Programs and sessions loaded.\n")
- else:
- LOGGER.error("ERROR : control_panel.xml or tools.xml not found!")
diff --git a/sw/supervision/python/processes.py b/sw/supervision/python/processes.py
deleted file mode 100644
index 0a8b2c0096..0000000000
--- a/sw/supervision/python/processes.py
+++ /dev/null
@@ -1,238 +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.environment as env
-import lib.console as cs
-
-import PyQt5.QtCore as Core
-import logging
-import os
-import signal
-
-
-###############################################################################
-# [Constants]
-
-LOGGER = logging.getLogger("[PROCESSES]")
-
-AC_MAKEFILE_NAME = "Makefile.ac"
-CONF_FLAG_NAME = "AIRCRAFT"
-DEVICE_FLAG_NAME = "FLASH_MODE"
-
-DEFAULT_EXIT_CODE = 2
-INTERRUPTED_EXIT_CODE = -1
-SUCCESS_EXIT_CODE = 0
-
-CLEAN = "clean"
-BUILD = "build"
-UPLOAD = "upload"
-PROGRAM = "program"
-TOOL = "tool"
-
-CLEAN_TARGET_KEY = "clean_ac"
-BUILD_TARGET_KEY = ".compile"
-UPLOAD_TARGET_KEY = ".upload"
-
-CONF_FLAG = "@" + CONF_FLAG_NAME
-TARGET_FLAG = "@TARGET"
-CONF_ID_FLAG = "@AC_ID"
-
-
-###############################################################################
-# [Stream class]
-
-class LoggerStream(Core.QObject):
- """ Class to define a Stream object."""
- logger_log_sent = Core.pyqtSignal(str, str, str)
-
- def __init__(self):
- super(LoggerStream, self).__init__()
-
- # Reimplemented method in order to write the logs in the console :
- def write(self, line):
- log, flag = cs.analyse_log_line(line)
- log_type = cs.APPLICATION_MESSAGE_TYPE
- self.logger_log_sent.emit(log, flag, log_type)
-
-
-###############################################################################
-# [Process class]
-
-class Process(Core.QObject):
- """Class to upload the built code to a device."""
- process_killed = Core.pyqtSignal()
- process_log_sent = Core.pyqtSignal(str, str, str)
-
- def __init__(self, process_type,
- configuration=None, target=None, device=None, program=None):
- """
- :param process_type:
- :param configuration:
- :param target:
- :param device:
- :param program:
- -> Declare a Process object as a QObject derivative.
- -> Give it a name and the necessary parameters for its type.
- -> Generate a command for the system call by the Popen object that
- manages the subprocess and allows to redirect the output.
- -> The process runs into an independent thread.
- -> A queue is used to collect the logs from the Popen output and
- an other one is used to send it to the QTextEdit integrated console.
- -> Logs flags are collected for information.
- -> Exit code is initialized to default value. Must change in case of
- normal exit, error or user interruption.
- """
- super(Process, self).__init__()
-
- self.type = process_type
- self.name = None
-
- self.config = configuration
- self.target = target
- self.device = device
- self.program = program
-
- if self.type == CLEAN:
- self.command = self.generate_make_command(CLEAN_TARGET_KEY)
- self.name = " - ".join([self.type.upper(),
- self.config.name])
- elif self.type == BUILD:
- self.command = self.generate_make_command(BUILD_TARGET_KEY)
- self.name = " - ".join([self.type.upper(), self.config.name,
- self.target.name])
- elif self.type == UPLOAD:
- self.command = self.generate_make_command(UPLOAD_TARGET_KEY)
- self.name = " - ".join([self.type.upper(), self.config.name,
- self.target.name, self.device.name])
- else:
- self.command = self.generate_program_command()
- self.name = " - ".join([self.type.upper(),
- self.program.name])
-
- self.subprocess = Core.QProcess()
- self.subprocess.setProcessChannelMode(Core.QProcess.MergedChannels)
- self.subprocess.setReadChannel(Core.QProcess.StandardOutput)
-
- self.process_killed.connect(self.emergency_stop)
- self.exit_code = DEFAULT_EXIT_CODE
-
- self.flags = {cs.ERROR_FLAG: 0,
- cs.WARNING_FLAG: 0,
- cs.INFO_FLAG: 0}
-
- def generate_make_command(self, target_key):
- """
- :param target_key:
- -> Generate a system command to compile files by a Makefile and
- putting the right arguments if given.
- """
- if self.config is not None:
- aircraft_term = CONF_FLAG_NAME + "=" + self.config.name
-
- if self.target is not None:
- target_key = self.target.name + target_key
-
- command_terms = ["make", "-C", env.PAPARAZZI_HOME, "-f",
- AC_MAKEFILE_NAME,
- aircraft_term, target_key]
-
- if self.device is not None and self.device.variable[1]:
- device_term = DEVICE_FLAG_NAME + "=" + self.device.variable[1]
- command_terms.insert(-1, device_term)
-
- return " ".join(command_terms)
-
- def generate_program_command(self):
- """
- -> Generate a system command to run a program and add its options
- if it has some.
- """
- if self.program is not None:
- full_command = os.path.join(env.PAPARAZZI_HOME,
- self.program.command)
-
- for option in self.program.options:
- if type(option) is tuple:
- flag, value = option
- if value == CONF_FLAG:
- full_command += " " + flag + " " + self.config.name
- elif value == TARGET_FLAG:
- full_command += " " + flag + " " + self.target.name
- elif value == CONF_ID_FLAG:
- full_command += " " + flag + " " + self.config.id
- else:
- full_command += " " + flag + " " + value
- else:
- full_command += " " + option
-
- return full_command
-
- def check_before_start(self):
- # TODO IF NECESSARY !!!
- return self == self
-
- def start(self):
- """
- -> Start the thread => start the worker => call the run method.
- """
- LOGGER.info("'%s' process running ... (command='%s')",
- self.name, self.command)
- self.subprocess.start(self.command)
- self.subprocess.readyReadStandardOutput.connect(self.send_text)
- self.subprocess.finished.connect(self.finish_process)
-
- def send_text(self):
- """
- -> Analyse an process output line to find a flag in it.
- -> Send the item by the sending queue object.
- -> Collect the flag found.
- """
- q_byte_array = self.subprocess.readAllStandardOutput()
- string = str(q_byte_array, encoding="utf-8").strip()
- for line in string.split("\n"):
- log, flag = cs.analyse_log_line(line)
- log_type = cs.PROCESS_MESSAGE_TYPE
- self.process_log_sent.emit(log, flag, log_type)
- if flag != cs.DEFAULT_FLAG:
- self.flags[flag] += 1
-
- def finish_process(self):
- """
- -> If the process finished, get the exit code.
- -> Else, the process crashed...
- """
- if self.subprocess.exitStatus() == Core.QProcess.NormalExit:
- self.exit_code = self.subprocess.exitCode()
- LOGGER.info("'%s' process finished with exit code %s.\n",
- self.name, self.exit_code)
- else:
- self.exit_code = INTERRUPTED_EXIT_CODE
- LOGGER.error("'%s' process crashed, probably stopped by user !\n",
- self.name)
-
- def emergency_stop(self):
- """
- -> Kill the subprocess by getting its ProcessID.
- """
- os.kill(self.subprocess.pid(), signal.SIGKILL)
diff --git a/sw/supervision/python/program_widget.py b/sw/supervision/python/program_widget.py
new file mode 100644
index 0000000000..986031087d
--- /dev/null
+++ b/sw/supervision/python/program_widget.py
@@ -0,0 +1,89 @@
+# Copyright (C) 2008-2022 The Paparazzi Team
+# released under GNU GPLv2 or later. See COPYING file.
+import os.path
+
+from generated.ui_program import Ui_Program
+from PyQt5.QtWidgets import *
+from PyQt5 import QtCore
+from PyQt5.QtCore import QProcess
+from PyQt5.QtGui import QIcon
+import utils
+from typing import List
+
+
+class ProgramWidget(QWidget, Ui_Program):
+
+ ready_read_stdout = QtCore.pyqtSignal()
+ ready_read_stderr = QtCore.pyqtSignal()
+ finished = QtCore.pyqtSignal(int, QProcess.ExitStatus)
+ remove = QtCore.pyqtSignal()
+
+ def __init__(self, shortname: str, cmd: List[str], icon=None, parent=None):
+ QWidget.__init__(self, parent=parent)
+ self.setupUi(self)
+ self.cmd = cmd
+ self.shortname = shortname
+ self.process = QProcess(self)
+ self.program_lineedit.setText(" ".join(cmd))
+ self.program_lineedit.returnPressed.connect(self.handle_cmd_return)
+ self.run_button.clicked.connect(self.handle_run)
+ self.remove_button.clicked.connect(self.handle_remove)
+ self.process.readyReadStandardOutput.connect(self.ready_read_stdout)
+ self.process.readyReadStandardError.connect(self.ready_read_stderr)
+ self.process.finished.connect(self.handle_finished)
+ self.process.started.connect(self.handle_started)
+ self.process.errorOccurred.connect(self.handle_error)
+ i = QIcon(os.path.join(utils.PAPARAZZI_HOME, "data", "pictures", "tools_icons", icon))
+ self.icon_label.setPixmap(i.pixmap(20, 20))
+ self.icon_label.setToolTip(shortname)
+
+ def start_program(self):
+ if self.process.state() == QProcess.NotRunning:
+ self.process.start(self.cmd[0], self.cmd[1:])
+
+ def handle_cmd_return(self):
+ if self.process.state() == QProcess.NotRunning:
+ self.cmd = self.program_lineedit.text().split(" ")
+ self.start_program()
+
+ def handle_run(self):
+ if self.process.state() == QProcess.NotRunning:
+ self.cmd = self.program_lineedit.text().split(" ")
+ self.start_program()
+ elif self.process.state() == QProcess.Running:
+ self.process.terminate()
+
+ def handle_remove(self):
+ if self.process.state() == QProcess.NotRunning:
+ self.remove.emit()
+ elif self.process.state() == QProcess.Running:
+ self.process.finished.connect(self.remove)
+ self.process.terminate()
+
+ def handle_started(self):
+ icon = QIcon.fromTheme("media-playback-stop")
+ self.run_button.setIcon(icon)
+ self.program_lineedit.setReadOnly(True)
+
+ def handle_finished(self, exit_code: int, exit_status: QProcess.ExitStatus):
+ icon = QIcon.fromTheme("media-playback-start")
+ self.run_button.setIcon(icon)
+ self.program_lineedit.setReadOnly(False)
+ self.finished.emit(exit_code, exit_status)
+
+ def handle_error(self, error: QProcess.ProcessError):
+ if error == QProcess.FailedToStart:
+ self.handle_finished(-1, QProcess.CrashExit)
+ # FailedToStart
+ # Crashed
+ # Timedout
+ # ReadError
+ # WriteError
+ # UnknownError
+
+ def terminate(self):
+ if self.process.state() != QProcess.NotRunning:
+ self.process.terminate()
+
+ def state(self):
+ return self.process.state()
diff --git a/sw/supervision/python/programs_conf.py b/sw/supervision/python/programs_conf.py
new file mode 100644
index 0000000000..390441d9b8
--- /dev/null
+++ b/sw/supervision/python/programs_conf.py
@@ -0,0 +1,132 @@
+# Copyright (C) 2008-2022 The Paparazzi Team
+# released under GNU GPLv2 or later. See COPYING file.
+from __future__ import annotations
+from dataclasses import dataclass, field
+from typing import List, Optional, Tuple, Dict
+from lxml import etree as ET
+from conf import *
+from copy import deepcopy
+
+
+@dataclass
+class Arg:
+ flag: str
+ constant: Optional[str]
+
+ @staticmethod
+ def parse(xml_arg):
+ flag = xml_arg.get("flag")
+ constant = xml_arg.get("constant")
+ return Arg(flag, constant)
+
+ def args(self, ac: Aircraft = None) -> List[str]:
+ if self.constant is not None:
+ constant = self.constant
+ if "@AIRCRAFT" in self.constant:
+ constant = self.constant.replace("@AIRCRAFT", ac.name)
+ if "@AC_ID" in self.constant:
+ constant = constant.replace("@AC_ID", str(ac.ac_id))
+ return [self.flag, constant]
+ else:
+ return [self.flag]
+
+ def to_xml(self) -> ET.Element:
+ xml = ET.Element("arg")
+ xml.set("flag", self.flag)
+ if self.constant is not None:
+ xml.set("constant", self.constant)
+ return xml
+
+
+@dataclass
+class Program:
+ name: str
+ args: List[Arg] = field(default_factory=list)
+
+ @staticmethod
+ def parse(xml_program):
+ name = xml_program.get("name")
+ args = [Arg.parse(xml_arg) for xml_arg in xml_program.findall("arg")]
+ return Program(name, args)
+
+ @staticmethod
+ def from_tool(t: Tool):
+ return Program(t.name, deepcopy(t.args))
+
+ def to_xml(self) -> ET.Element:
+ xml: ET._Element = ET.Element("program")
+ xml.set("name", self.name)
+ for arg in self.args:
+ xml.append(arg.to_xml())
+ return xml
+
+
+@dataclass
+class Session:
+ name: str
+ programs: List[Program] = field(default_factory=list)
+
+ @staticmethod
+ def parse(xml_session):
+ name = xml_session.get("name")
+ programs = [Program.parse(xml_program) for xml_program in xml_session.findall("program")]
+ return Session(name, programs)
+
+ def to_xml(self) -> ET.Element:
+ xml = ET.Element("session")
+ xml.set("name", self.name)
+ for p in self.programs:
+ xml.append(p.to_xml())
+ return xml
+
+
+@dataclass
+class Tool:
+ name: str
+ command: str
+ icon: Optional[str]
+ args: List[Arg]
+ favorite: bool
+
+ @staticmethod
+ def parse(xml_program) -> Tuple[str, Tool]:
+ name = xml_program.get("name")
+ command = xml_program.get("command")
+ icon = xml_program.get("icon")
+ if icon is None:
+ icon = "default_tool_icon.svg"
+ favorite = True if xml_program.get("favorite") is not None else False
+ args = [Arg.parse(xml_arg) for xml_arg in xml_program.findall("arg")]
+ return name, Tool(name, command, icon, args, favorite)
+
+
+def parse_tools() -> Dict[str, Tool]:
+ tools = {}
+ tools_dir = os.path.join(utils.CONF_DIR, "tools")
+ for file in os.listdir(tools_dir):
+ if file.endswith(".xml"):
+ path = os.path.join(utils.CONF_DIR, "tools", file)
+ xml = ET.parse(path).getroot()
+ if xml.tag == "program":
+ name, tool = Tool.parse(xml)
+ tools[name] = tool
+ else:
+ print("unexpected tag ", xml.tag)
+
+ # programs from control_panel.xml
+ # override programs from conf/tools/*.xml
+ control_panel = ET.parse(os.path.join(utils.CONF_DIR, "control_panel.xml"))
+ for xml_section in control_panel.getroot().findall("section"):
+ if xml_section.get("name") == "programs":
+ for xml_program in xml_section.findall("program"):
+ name, tool = Tool.parse(xml_program)
+ tools[name] = tool
+
+ return tools
+
+
+def parse_sessions() -> List[Session]:
+ control_panel = ET.parse(os.path.join(utils.CONF_DIR, "control_panel.xml"))
+ for xml_section in control_panel.getroot().findall("section"):
+ if xml_section.get("name") == "sessions":
+ return [Session.parse(xml_session) for xml_session in xml_section.findall("session")]
diff --git a/sw/supervision/python/requirements.txt b/sw/supervision/python/requirements.txt
new file mode 100644
index 0000000000..92adab28d1
--- /dev/null
+++ b/sw/supervision/python/requirements.txt
@@ -0,0 +1,3 @@
+PyQt5
+lxml
+
diff --git a/sw/supervision/python/session_widget.py b/sw/supervision/python/session_widget.py
new file mode 100644
index 0000000000..49fd17914e
--- /dev/null
+++ b/sw/supervision/python/session_widget.py
@@ -0,0 +1,291 @@
+# Copyright (C) 2008-2022 The Paparazzi Team
+# released under GNU GPLv2 or later. See COPYING file.
+import os.path
+
+import console_widget
+from generated.ui_session import Ui_Session
+from PyQt5.QtWidgets import *
+from PyQt5 import QtCore
+import utils
+import lxml.etree as ET
+
+from typing import List, Optional, Tuple, Dict
+from program_widget import ProgramWidget
+from tools_menu import ToolMenu
+from programs_conf import *
+from conf import *
+from console_widget import ConsoleWidget
+
+
+class SessionWidget(QWidget, Ui_Session):
+
+ programs_all_stopped = QtCore.pyqtSignal()
+ program_spawned = QtCore.pyqtSignal()
+
+ def __init__(self, parent=None):
+ QWidget.__init__(self, parent=parent)
+ self.setupUi(self)
+ self.program_widgets: List[ProgramWidget] = []
+ self.console: ConsoleWidget = None
+ self.ac: Aircraft = None
+ self.sessions = []
+ self.tools = []
+ self.tools_menu = ToolMenu()
+ self.sessions_combo.addItems(["Simulation", "Replay"])
+ self.sessions_combo.insertSeparator(2)
+ self.menu_button.addAction(self.save_session_action)
+ self.menu_button.addAction(self.save_as_action)
+ self.menu_button.addAction(self.rename_session_action)
+ self.menu_button.addAction(self.remove_session_action)
+ self.tools_menu.tool_clicked.connect(self.handle_new_tool)
+ self.start_session_button.clicked.connect(self.start_session)
+ self.startall_button.clicked.connect(self.start_all)
+ self.removeall_button.clicked.connect(self.remove_all)
+ self.stopall_button.clicked.connect(self.stop_all)
+ self.add_tool_button.clicked.connect(self.open_tools)
+ self.save_session_action.triggered.connect(self.handle_save)
+ self.save_as_action.triggered.connect(self.handle_save_as)
+ self.rename_session_action.triggered.connect(self.handle_rename)
+ self.remove_session_action.triggered.connect(self.remove_session)
+
+ def set_console(self, console: console_widget.ConsoleWidget):
+ self.console = console
+
+ def set_aircraft(self, ac: Aircraft):
+ self.ac = ac
+
+ def init(self):
+ self.sessions = parse_sessions()
+ self.tools = parse_tools()
+ self.init_tools_menu()
+ sessions_names = [session.name for session in self.sessions]
+ self.sessions_combo.addItems(sessions_names)
+ last_session = utils.get_settings().value("ui/last_session", None, str)
+ if last_session is not None:
+ self.sessions_combo.setCurrentText(last_session)
+
+ def get_current_session(self) -> str:
+ """
+ :return: current session name in comboBox.
+ """
+ return self.sessions_combo.currentText()
+
+ def start_session(self):
+ combo_text = self.sessions_combo.currentText()
+ if combo_text == "Simulation":
+ self.start_simulation()
+ elif combo_text == "Replay":
+ self.start_replay()
+ else:
+ for session in self.sessions:
+ if session.name == combo_text:
+ for program in session.programs:
+ self.launch_program(program)
+
+ def start_replay(self):
+ lfp = Program.from_tool(self.tools["Log File Player"])
+ server = Program.from_tool(self.tools["Server"])
+ server.args.append(Arg("-n", None))
+ gcs = Program.from_tool(self.tools["GCS"])
+ self.launch_program(lfp)
+ self.launch_program(server)
+ self.launch_program(gcs)
+
+ def start_simulation(self):
+ if "nps" not in self.ac.boards and "sim" not in self.ac.boards:
+ self.console.post_message(None, "No simulation target for {}.".format(self.ac.name))
+ return
+
+ elif "nps" in self.ac.boards and "sim" in self.ac.boards:
+ simulator, ok = QInputDialog.getItem(self, "Simulator", "Please choose the simulator:",
+ ["nps", "sim"], editable=False)
+ if not ok:
+ return
+ elif "nps" in self.ac.boards:
+ simulator = "nps"
+ else:
+ # simulator is "sim"
+ simulator = "sim"
+
+ if simulator == "nps":
+ t = self.tools["Simulator"]
+ simu = Program.from_tool(t)
+ simu.args.append(Arg("-t", "nps"))
+ self.launch_program(simu)
+ datalink = Program.from_tool(self.tools["Data Link"])
+ datalink.args = [Arg("-udp", None), Arg("-udp_broadcast", None)]
+ self.launch_program(datalink)
+ else:
+ # simulator is "sim"
+ sim = Program.from_tool(self.tools["Simulator"])
+ sim.args.extend([Arg("-t", "sim"), Arg("--boot", None), Arg("--norc", None)])
+ self.launch_program(sim)
+
+ server = Program.from_tool(self.tools["Server"])
+ server.args.append(Arg("-n", None))
+ gcs = Program.from_tool(self.tools["GCS"])
+ self.launch_program(server)
+ self.launch_program(gcs)
+
+ def launch_program(self, program: Program):
+ if self.console is None:
+ raise Exception("Console not set!")
+ tool = self.tools[program.name]
+ args = [arg.args(self.ac) for arg in program.args]
+ flat_args = [item for sublist in args for item in sublist]
+ if tool.command.startswith("$"):
+ cmd = [tool.command[1:]] + flat_args
+ else:
+ cmd = [os.path.join(utils.PAPARAZZI_SRC, tool.command)] + flat_args
+
+ pw = ProgramWidget(tool.name, cmd, tool.icon, self.programs_widget)
+ self.program_widgets.append(pw)
+ lay: QVBoxLayout = self.programs_widget.layout()
+ lay.insertWidget(lay.count()-1, pw)
+ pw.ready_read_stderr.connect(lambda: self.console.handle_stderr(pw))
+ pw.ready_read_stdout.connect(lambda: self.console.handle_stdout(pw))
+ pw.finished.connect(lambda c, s: self.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()
+ self.console.new_program(pw)
+ self.program_spawned.emit()
+
+ def remove_program(self, pw: ProgramWidget):
+ self.console.remove_program(pw)
+ pw.setParent(None)
+ # self.programs_widget.layout().removeWidget(pw)
+ self.program_widgets.remove(pw)
+ if len(self.program_widgets) == 0:
+ self.programs_all_stopped.emit()
+ # pw.deleteLater()
+
+ def any_program_running(self):
+ return any([pw.state() == QtCore.QProcess.Running for pw in self.program_widgets])
+
+ def handle_program_finished(self, pw, c, s):
+ self.console.handle_program_finished(pw, c, s)
+ if not self.any_program_running():
+ self.programs_all_stopped.emit()
+
+ def stop_all(self):
+ for pw in self.program_widgets:
+ pw.terminate()
+
+ def start_all(self):
+ for pw in self.program_widgets:
+ pw.start_program()
+
+ def remove_all(self):
+ for pw in list(self.program_widgets):
+ pw.handle_remove()
+
+ def init_tools_menu(self):
+ for t in self.tools.values():
+ self.tools_menu.add_tool(t)
+
+ def handle_new_tool(self, name):
+ p = Program.from_tool(self.tools[name])
+ self.launch_program(p)
+
+ def open_tools(self):
+ if self.tools_menu.isVisible():
+ self.tools_menu.close()
+ else:
+ bottomLeft = self.mapToGlobal(self.add_tool_button.geometry().bottomLeft())
+ self.tools_menu.move(bottomLeft)
+ self.tools_menu.show()
+ self.tools_menu.setFocus(QtCore.Qt.PopupFocusReason)
+
+ def handle_save(self):
+ session_name = self.sessions_combo.currentText()
+ programs = self.get_programs()
+ session = Session(session_name, programs)
+ self.replace_session(session)
+ self.save_sessions()
+
+ def handle_save_as(self):
+ session_name, ok = QInputDialog.getText(self, "Session name", "enter the session name:")
+ if not ok:
+ return
+ for session in self.sessions:
+ if session.name == session_name:
+ QMessageBox.warning(self, "Error", "A session with this name already exits.\nTry again with a new name.")
+ return
+ programs = self.get_programs()
+ session = Session(session_name, programs)
+ self.sessions.append(session)
+ self.save_sessions()
+
+ def handle_rename(self):
+ for session_orig in self.sessions:
+ if session_orig.name == self.sessions_combo.currentText():
+ break
+ else:
+ print("session not found")
+ return
+ session_name, ok = QInputDialog.getText(self, "Session name", "enter the session name:")
+ if not ok:
+ return
+ for session in self.sessions:
+ if session.name == session_name:
+ QMessageBox.warning(self, "Error", "A session with this name already exits.\nTry again with a new name.")
+ return
+ session_orig.name = session_name
+ self.save_sessions()
+
+ def remove_session(self):
+ for session in self.sessions:
+ if session.name == self.sessions_combo.currentText():
+ self.sessions.remove(session)
+ i = self.sessions_combo.currentIndex()
+ self.sessions_combo.removeItem(i)
+ self.save_sessions()
+ return
+ print("session {} not found".format(self.sessions_combo.currentText()))
+
+ def replace_session(self, session):
+ for i, s in enumerate(self.sessions):
+ if s.name == session.name:
+ self.sessions[i] = session
+ break
+
+ def save_sessions(self):
+ ctrl_panel_path = os.path.join(utils.CONF_DIR, "control_panel.xml")
+ parser = ET.XMLParser(remove_blank_text=True)
+ control_panel = ET.parse(ctrl_panel_path, parser)
+ xml_sessions = ET.Element("section")
+ xml_sessions.set("name", "sessions")
+ for session in self.sessions:
+ xml_sessions.append(session.to_xml())
+ for xml_section in control_panel.getroot().findall("section"):
+ if xml_section.get("name") == "sessions":
+ control_panel.getroot().replace(xml_section, xml_sessions)
+ break
+ control_panel.write(ctrl_panel_path, pretty_print=True)
+ print("sessions saved to {}".format(ctrl_panel_path))
+
+ def get_programs(self):
+ programs = []
+ for p in self.program_widgets:
+ name = p.shortname
+ args = []
+ if len(p.cmd) > 0:
+ arg = None
+ for param in p.cmd[1:]:
+ if param.startswith("-"):
+ # if it start with "-", make a new arg
+ arg = Arg(param, None)
+ args.append(arg)
+ else:
+ if arg is not None and arg.flag.startswith("-"):
+ # if it don't starts with -, but the previous did, fill the constant
+ arg.constant = param
+ else:
+ # if it don't starts with -, nor the previous, its probably a mandatory argument
+ arg = Arg(param, None)
+ args.append(arg)
+ program = Program(name, args)
+ programs.append(program)
+ return programs
diff --git a/sw/supervision/python/tools_menu.py b/sw/supervision/python/tools_menu.py
index 4ce7e2832a..5afb50a963 100644
--- a/sw/supervision/python/tools_menu.py
+++ b/sw/supervision/python/tools_menu.py
@@ -1,89 +1,54 @@
-from PyQt5 import QtCore, QtGui, QtWidgets
+# Copyright (C) 2008-2022 The Paparazzi Team
+# released under GNU GPLv2 or later. See COPYING file.
+from PyQt5 import QtCore, QtGui
+from programs_conf import *
+import os
+import utils
+from PyQt5.QtWidgets import *
+from PyQt5.QtCore import Qt
+from generated.ui_tools_list import Ui_ToolsList
-ICON_SIZE = (60, 60)
-POPUP_SIZE = (1000, 400)
-POPUP_GRID_WIDTH = 4
-SC_MINIMUM_SIZE = (200, 130)
-ICON_NUMBER = 6
+ICON_SIZE = (40, 40)
-class ToolList(QtWidgets.QScrollArea):
+
+class ToolMenu(QWidget, Ui_ToolsList):
+
+ tool_clicked = QtCore.pyqtSignal(str)
def __init__(self):
- super(ToolList, self).__init__()
- self.frame = QtWidgets.QFrame()
- self.gridLayout = QtWidgets.QGridLayout()
- self.frame.setLayout(self.gridLayout)
- self.setWidget(self.frame)
- self.setWidgetResizable(True)
+ super(ToolMenu, self).__init__()
+ self.setupUi(self)
+ self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.Popup)
+ self.tools_buttons: Dict[str, QToolButton] = {}
+ self.filter_lineedit.textChanged.connect(self.filter)
+ self.setFocusProxy(self.filter_lineedit)
+ # self.gridLayout.setContentsMargins(10, 10, 24, 10)
+ # self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
+ # self.setWidgetResizable(True)
- def add(self, button):
- count = self.gridLayout.count()
- row = count // POPUP_GRID_WIDTH
- col = count % POPUP_GRID_WIDTH
- self.gridLayout.addWidget(button, row, col)
-
- def focusOutEvent(self, QFocusEvent):
- self.close()
-
-
-class ToolsMenu(QtWidgets.QFrame):
- def __init__(self, parent):
- super(ToolsMenu, self).__init__(parent)
- self.hlayout = QtWidgets.QHBoxLayout(self)
- self.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
-
- self.toolsFrame = QtWidgets.QFrame()
- self.toolsLayout = QtWidgets.QHBoxLayout(self.toolsFrame)
- self.scrollArea = QtWidgets.QScrollArea()
- self.scrollArea.setWidget(self.toolsFrame)
- self.hlayout.addWidget(self.scrollArea)
- self.scrollArea.setMinimumSize(*SC_MINIMUM_SIZE)
- self.setMinimumSize(SC_MINIMUM_SIZE[0] + 10, SC_MINIMUM_SIZE[1] + 100)
-
- self.toolsLayout.setSizeConstraint(QtWidgets.QLayout.SetMinimumSize)
-
- self.scrollArea.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
- self.scrollArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
- self.scrollArea.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
-
- self.button_more = None
- self.popup = ToolList()
- self.popup.setWindowFlags(QtCore.Qt.FramelessWindowHint)
- self.popup.setMinimumSize(*POPUP_SIZE)
- self.buttons = []
- self.toolsLayout.addStretch(0)
-
- self._add_more_button()
-
- def _add_more_button(self):
- if self.button_more is None:
- self.button_more = QtWidgets.QToolButton()
- more_icon = QtGui.QIcon("ui/icons/tools_more.svg")
- self.button_more.setIcon(more_icon)
- self.button_more.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Expanding)
- self.hlayout.addWidget(self.button_more, QtCore.Qt.AlignRight)
- self.button_more.clicked.connect(self.open_popup)
-
- def add_item(self, name, image_path, callback):
- button = QtWidgets.QToolButton()
- button.setText(name)
- button.setIcon(QtGui.QIcon(image_path))
+ def add_tool(self, t: Tool):
+ button = QToolButton()
+ button.setText(t.name)
+ icon = QtGui.QIcon(os.path.join(utils.PAPARAZZI_HOME, "data", "pictures", "tools_icons", t.icon))
+ button.setIcon(icon)
button.setIconSize(QtCore.QSize(*ICON_SIZE))
- button.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)
- button.clicked.connect(callback)
+ # button.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)
+ button.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
+ button.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
+ button.clicked.connect(lambda: self.tool_clicked.emit(button.text()))
+ self.tools_buttons[t.name] = button
+ self.content_widget.layout().addWidget(button)
- self.buttons.append(button)
+ def filter(self, txt: str):
+ for name, button in self.tools_buttons.items():
+ show = txt.lower() in name.lower()
+ button.setVisible(show)
- if self.toolsLayout.count() <= ICON_NUMBER:
- self.toolsLayout.insertWidget(self.toolsLayout.count() - 1, button, QtCore.Qt.AlignLeft)
- else:
- self.popup.add(button)
- button.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- button.show()
- self.popup.adjustSize()
+ def keyPressEvent(self, e: QtGui.QKeyEvent) -> None:
+ if e.key() == Qt.Key_Escape:
+ self.releaseMouse()
+ self.close()
- def open_popup(self):
- bottomLeft = self.mapToGlobal(self.hlayout.geometry().bottomLeft())
- self.popup.move(bottomLeft)
- self.popup.show()
- self.popup.setFocus(QtCore.Qt.PopupFocusReason)
+ def show(self) -> None:
+ super(ToolMenu, self).show()
+ self.filter_lineedit.clear()
diff --git a/sw/supervision/python/ui/app_settings.ui b/sw/supervision/python/ui/app_settings.ui
new file mode 100644
index 0000000000..95036026ab
--- /dev/null
+++ b/sw/supervision/python/ui/app_settings.ui
@@ -0,0 +1,98 @@
+
+
+ AppSettingsDialog
+
+
+
+ 0
+ 0
+ 381
+ 131
+
+
+
+ Settings
+
+
+ -
+
+
+ Text editor
+
+
+
+ -
+
+
+ -
+
+
+ Terminal Emulator
+
+
+
+ -
+
+
+ -
+
+
+ Keep changes on exit
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QDialogButtonBox::Cancel|QDialogButtonBox::Ok
+
+
+
+
+
+
+
+
+ buttonBox
+ accepted()
+ AppSettingsDialog
+ accept()
+
+
+ 248
+ 254
+
+
+ 157
+ 274
+
+
+
+
+ buttonBox
+ rejected()
+ AppSettingsDialog
+ reject()
+
+
+ 316
+ 260
+
+
+ 286
+ 274
+
+
+
+
+
diff --git a/sw/supervision/python/ui/build.ui b/sw/supervision/python/ui/build.ui
new file mode 100644
index 0000000000..1b22973b16
--- /dev/null
+++ b/sw/supervision/python/ui/build.ui
@@ -0,0 +1,139 @@
+
+
+ Build
+
+
+
+ 0
+ 0
+ 437
+ 87
+
+
+
+ Form
+
+
+ -
+
+
+ Build
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Target
+
+
+
+ -
+
+
+
+
+
+ false
+
+
+
+ -
+
+
+ Clean
+
+
+ ...
+
+
+
+ . .
+
+
+
+ -
+
+
+ Build
+
+
+ ...
+
+
+
+ . .
+
+
+ Qt::ToolButtonIconOnly
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ print config at build time
+
+
+
+
+
+
+
+
+
+ -
+
+
+ Flash
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Device
+
+
+
+ -
+
+
+ -
+
+
+ Upload
+
+
+ Flash
+
+
+
+ . .
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sw/supervision/python/ui/conf_header.ui b/sw/supervision/python/ui/conf_header.ui
new file mode 100644
index 0000000000..6d8ad9b53f
--- /dev/null
+++ b/sw/supervision/python/ui/conf_header.ui
@@ -0,0 +1,169 @@
+
+
+ ConfHeader
+
+
+
+ 0
+ 0
+ 664
+ 192
+
+
+
+ Form
+
+
+ -
+
+
+ 255
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ false
+
+
+
+ -
+
+
+ Qt::ActionsContextMenu
+
+
+
+
+
+
+ . .
+
+
+
+ -
+
+
+ refresh Aircraft
+
+
+ ...
+
+
+
+ . .
+
+
+
+ -
+
+
+ save conf
+
+
+ ...
+
+
+
+ . .
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Set
+
+
+
+ -
+
+
+
+
+
+
+ . .
+
+
+ New AC
+
+
+
+
+
+ . .
+
+
+ Remove
+
+
+
+
+
+ . .
+
+
+ Duplicate
+
+
+
+
+
+ . .
+
+
+ Rename
+
+
+
+
+
+
+ menu_button
+ clicked()
+ menu_button
+ showMenu()
+
+
+ 302
+ 95
+
+
+ 302
+ 95
+
+
+
+
+
diff --git a/sw/supervision/python/ui/conf_item.ui b/sw/supervision/python/ui/conf_item.ui
new file mode 100644
index 0000000000..b5628897f8
--- /dev/null
+++ b/sw/supervision/python/ui/conf_item.ui
@@ -0,0 +1,72 @@
+
+
+ FileConf
+
+
+
+ 0
+ 0
+ 306
+ 129
+
+
+
+ Form
+
+
+ -
+
+ -
+
+
+ font-weight: bold;
+
+
+ Flight Plan
+
+
+
+ -
+
+
+ Edit alt
+
+
+
+ -
+
+
+ Edit
+
+
+
+ -
+
+
+ Select
+
+
+
+
+
+ -
+
+
+ /path/to/file.xml
+
+
+ true
+
+
+ false
+
+
+ Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse
+
+
+
+
+
+
+
+
diff --git a/sw/supervision/python/ui/configuration_panel.ui b/sw/supervision/python/ui/configuration_panel.ui
new file mode 100644
index 0000000000..cb057069b7
--- /dev/null
+++ b/sw/supervision/python/ui/configuration_panel.ui
@@ -0,0 +1,114 @@
+
+
+ ConfigurationPanel
+
+
+
+ 0
+ 0
+ 562
+ 480
+
+
+
+ Form
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 0
+
+
+
+
+ -
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+ Save configuration
+
+
+ Ctrl+S
+
+
+
+
+
+ ConfWidget
+ QWidget
+
+ 1
+
+
+ BuildWidget
+ QWidget
+
+ 1
+
+
+ HeaderWidget
+ QWidget
+
+ 1
+
+
+ ConsoleWidget
+ QWidget
+
+ 1
+
+
+
+
+
diff --git a/sw/supervision/python/ui/console.ui b/sw/supervision/python/ui/console.ui
new file mode 100644
index 0000000000..f2a0fdda38
--- /dev/null
+++ b/sw/supervision/python/ui/console.ui
@@ -0,0 +1,168 @@
+
+
+ Console
+
+
+
+ 0
+ 0
+ 709
+ 647
+
+
+
+ Form
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ true
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Filters
+
+
+
+ -
+
+
+ Programs
+
+
+ false
+
+
+
+ -
+
+
+ true
+
+
+
+
+ 0
+ 0
+ 382
+ 524
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 1
+ 167
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Log level:
+
+
+
+ -
+
+
+
+ 100
+ 16777215
+
+
+
+ 3
+
+
+ 1
+
+
+ 3
+
+
+ Qt::Horizontal
+
+
+ QSlider::TicksBelow
+
+
+ 1
+
+
+
+ -
+
+
+ All
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Clear console
+
+
+
+ . .
+
+
+
+
+
+
+
+
+
+
diff --git a/sw/supervision/python/ui/credits.html b/sw/supervision/python/ui/credits.html
deleted file mode 100644
index e97422d6fd..0000000000
--- a/sw/supervision/python/ui/credits.html
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
-
-
- Paparazzi Center
- (Python/Qt version)
-
- Copyright (C) 2007-2008 ENAC, Pascal Brisset
- License GPLv2
- http://paparazziuav.org
-
-
diff --git a/sw/supervision/python/ui/data_changed.html b/sw/supervision/python/ui/data_changed.html
deleted file mode 100644
index ba8ef77ead..0000000000
--- a/sw/supervision/python/ui/data_changed.html
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
- Values have been modified locally but not into the original XML files...
- Do you want to save or ignore them ?
-
-
diff --git a/sw/supervision/python/ui/icons/accessories-text-editor.svg b/sw/supervision/python/ui/icons/accessories-text-editor.svg
deleted file mode 100644
index 03db109a64..0000000000
--- a/sw/supervision/python/ui/icons/accessories-text-editor.svg
+++ /dev/null
@@ -1,107 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/sw/supervision/python/ui/icons/dialog-apply.svg b/sw/supervision/python/ui/icons/dialog-apply.svg
deleted file mode 100644
index f009b90ee3..0000000000
--- a/sw/supervision/python/ui/icons/dialog-apply.svg
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/sw/supervision/python/ui/icons/dialog-error.svg b/sw/supervision/python/ui/icons/dialog-error.svg
deleted file mode 100644
index a3d6de4d72..0000000000
--- a/sw/supervision/python/ui/icons/dialog-error.svg
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/sw/supervision/python/ui/icons/dialog-warning-symbolic.svg b/sw/supervision/python/ui/icons/dialog-warning-symbolic.svg
deleted file mode 100644
index e9474a9d14..0000000000
--- a/sw/supervision/python/ui/icons/dialog-warning-symbolic.svg
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
- image/svg+xml
-
- Gnome Symbolic Icon Theme
-
-
-
- Gnome Symbolic Icon Theme
-
-
-
-
diff --git a/sw/supervision/python/ui/icons/dialog-warning.png b/sw/supervision/python/ui/icons/dialog-warning.png
deleted file mode 100644
index d1020c6d9e..0000000000
Binary files a/sw/supervision/python/ui/icons/dialog-warning.png and /dev/null differ
diff --git a/sw/supervision/python/ui/icons/edit-clear.svg b/sw/supervision/python/ui/icons/edit-clear.svg
deleted file mode 100644
index 568fe9de66..0000000000
--- a/sw/supervision/python/ui/icons/edit-clear.svg
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/sw/supervision/python/ui/icons/go-up.svg b/sw/supervision/python/ui/icons/go-up.svg
deleted file mode 100644
index e5e58672cd..0000000000
--- a/sw/supervision/python/ui/icons/go-up.svg
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/sw/supervision/python/ui/icons/gtk-info.svg b/sw/supervision/python/ui/icons/gtk-info.svg
deleted file mode 100644
index f1ec53786a..0000000000
--- a/sw/supervision/python/ui/icons/gtk-info.svg
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/sw/supervision/python/ui/icons/list-add.svg b/sw/supervision/python/ui/icons/list-add.svg
deleted file mode 100644
index f40a948324..0000000000
--- a/sw/supervision/python/ui/icons/list-add.svg
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/sw/supervision/python/ui/icons/list-remove.svg b/sw/supervision/python/ui/icons/list-remove.svg
deleted file mode 100644
index ebc6bdbe8f..0000000000
--- a/sw/supervision/python/ui/icons/list-remove.svg
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/sw/supervision/python/ui/icons/media-playback-pause.svg b/sw/supervision/python/ui/icons/media-playback-pause.svg
deleted file mode 100644
index fde2760829..0000000000
--- a/sw/supervision/python/ui/icons/media-playback-pause.svg
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/sw/supervision/python/ui/icons/media-playback-start.svg b/sw/supervision/python/ui/icons/media-playback-start.svg
deleted file mode 100644
index 87c34d3025..0000000000
--- a/sw/supervision/python/ui/icons/media-playback-start.svg
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/sw/supervision/python/ui/icons/penguin_icon.png b/sw/supervision/python/ui/icons/penguin_icon.png
deleted file mode 100644
index f61d8024e9..0000000000
Binary files a/sw/supervision/python/ui/icons/penguin_icon.png and /dev/null differ
diff --git a/sw/supervision/python/ui/icons/process-stop.svg b/sw/supervision/python/ui/icons/process-stop.svg
deleted file mode 100644
index 1c9162caab..0000000000
--- a/sw/supervision/python/ui/icons/process-stop.svg
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/sw/supervision/python/ui/icons/search_field.png b/sw/supervision/python/ui/icons/search_field.png
deleted file mode 100644
index c3264f66d9..0000000000
Binary files a/sw/supervision/python/ui/icons/search_field.png and /dev/null differ
diff --git a/sw/supervision/python/ui/icons/system-run.png b/sw/supervision/python/ui/icons/system-run.png
deleted file mode 100644
index ad6d80b0de..0000000000
Binary files a/sw/supervision/python/ui/icons/system-run.png and /dev/null differ
diff --git a/sw/supervision/python/ui/icons/tools_more.svg b/sw/supervision/python/ui/icons/tools_more.svg
deleted file mode 100644
index 77f5bdd499..0000000000
--- a/sw/supervision/python/ui/icons/tools_more.svg
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
- image/svg+xml
-
-
-
-
-
-
-
-
-
diff --git a/sw/supervision/python/ui/icons/utilities-terminal.svg b/sw/supervision/python/ui/icons/utilities-terminal.svg
deleted file mode 100644
index add2893910..0000000000
--- a/sw/supervision/python/ui/icons/utilities-terminal.svg
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- image/svg+xml
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/sw/supervision/python/ui/main_window.py b/sw/supervision/python/ui/main_window.py
deleted file mode 100644
index 4c0f35c378..0000000000
--- a/sw/supervision/python/ui/main_window.py
+++ /dev/null
@@ -1,1715 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file 'main_window.ui'
-#
-# Created by: PyQt5 UI code generator 5.5.1
-#
-# WARNING! All changes made in this file will be lost!
-
-from PyQt5 import QtCore, QtGui, QtWidgets
-
-class Ui_MainWindow(object):
- def setupUi(self, MainWindow):
- MainWindow.setObjectName("MainWindow")
- MainWindow.resize(833, 568)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth())
- MainWindow.setSizePolicy(sizePolicy)
- MainWindow.setMaximumSize(QtCore.QSize(16777215, 16777215))
- self.centralwidget = QtWidgets.QWidget(MainWindow)
- self.centralwidget.setObjectName("centralwidget")
- self.gridLayout_10 = QtWidgets.QGridLayout(self.centralwidget)
- self.gridLayout_10.setObjectName("gridLayout_10")
- self.current_set_and_configuration = QtWidgets.QFrame(self.centralwidget)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.current_set_and_configuration.sizePolicy().hasHeightForWidth())
- self.current_set_and_configuration.setSizePolicy(sizePolicy)
- self.current_set_and_configuration.setMinimumSize(QtCore.QSize(0, 40))
- self.current_set_and_configuration.setMaximumSize(QtCore.QSize(16777215, 40))
- self.current_set_and_configuration.setAutoFillBackground(False)
- self.current_set_and_configuration.setStyleSheet("")
- self.current_set_and_configuration.setFrameShape(QtWidgets.QFrame.StyledPanel)
- self.current_set_and_configuration.setFrameShadow(QtWidgets.QFrame.Plain)
- self.current_set_and_configuration.setObjectName("current_set_and_configuration")
- self.gridLayout = QtWidgets.QGridLayout(self.current_set_and_configuration)
- self.gridLayout.setObjectName("gridLayout")
- self.label = QtWidgets.QLabel(self.current_set_and_configuration)
- self.label.setToolTip("")
- self.label.setObjectName("label")
- self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
- self.current_configuration = QtWidgets.QComboBox(self.current_set_and_configuration)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.current_configuration.sizePolicy().hasHeightForWidth())
- self.current_configuration.setSizePolicy(sizePolicy)
- self.current_configuration.setMinimumSize(QtCore.QSize(0, 20))
- self.current_configuration.setObjectName("current_configuration")
- self.gridLayout.addWidget(self.current_configuration, 0, 3, 1, 1)
- self.current_color = QtWidgets.QLabel(self.current_set_and_configuration)
- self.current_color.setEnabled(True)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.current_color.sizePolicy().hasHeightForWidth())
- self.current_color.setSizePolicy(sizePolicy)
- self.current_color.setMinimumSize(QtCore.QSize(30, 0))
- self.current_color.setMaximumSize(QtCore.QSize(40, 16777215))
- self.current_color.setMouseTracking(False)
- self.current_color.setFocusPolicy(QtCore.Qt.NoFocus)
- self.current_color.setAutoFillBackground(True)
- self.current_color.setStyleSheet("")
- self.current_color.setFrameShape(QtWidgets.QFrame.Box)
- self.current_color.setMidLineWidth(1)
- self.current_color.setText("")
- self.current_color.setAlignment(QtCore.Qt.AlignCenter)
- self.current_color.setObjectName("current_color")
- self.gridLayout.addWidget(self.current_color, 0, 7, 1, 1)
- self.label_2 = QtWidgets.QLabel(self.current_set_and_configuration)
- self.label_2.setToolTip("")
- self.label_2.setObjectName("label_2")
- self.gridLayout.addWidget(self.label_2, 0, 2, 1, 1)
- self.label_3 = QtWidgets.QLabel(self.current_set_and_configuration)
- self.label_3.setToolTip("")
- self.label_3.setObjectName("label_3")
- self.gridLayout.addWidget(self.label_3, 0, 4, 1, 1)
- self.current_id = QtWidgets.QLabel(self.current_set_and_configuration)
- self.current_id.setEnabled(True)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.current_id.sizePolicy().hasHeightForWidth())
- self.current_id.setSizePolicy(sizePolicy)
- self.current_id.setMinimumSize(QtCore.QSize(30, 0))
- self.current_id.setMaximumSize(QtCore.QSize(40, 16777215))
- font = QtGui.QFont()
- font.setBold(True)
- font.setWeight(75)
- self.current_id.setFont(font)
- self.current_id.setMouseTracking(False)
- self.current_id.setFocusPolicy(QtCore.Qt.NoFocus)
- self.current_id.setAutoFillBackground(True)
- self.current_id.setStyleSheet("")
- self.current_id.setFrameShape(QtWidgets.QFrame.Box)
- self.current_id.setMidLineWidth(1)
- self.current_id.setText("")
- self.current_id.setAlignment(QtCore.Qt.AlignCenter)
- self.current_id.setObjectName("current_id")
- self.gridLayout.addWidget(self.current_id, 0, 5, 1, 1)
- self.label_27 = QtWidgets.QLabel(self.current_set_and_configuration)
- self.label_27.setToolTip("")
- self.label_27.setObjectName("label_27")
- self.gridLayout.addWidget(self.label_27, 0, 6, 1, 1)
- self.current_set = QtWidgets.QComboBox(self.current_set_and_configuration)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.current_set.sizePolicy().hasHeightForWidth())
- self.current_set.setSizePolicy(sizePolicy)
- self.current_set.setMinimumSize(QtCore.QSize(0, 20))
- self.current_set.setObjectName("current_set")
- self.gridLayout.addWidget(self.current_set, 0, 1, 1, 1)
- self.gridLayout_10.addWidget(self.current_set_and_configuration, 0, 0, 1, 1)
- self.main_tab = QtWidgets.QTabWidget(self.centralwidget)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.main_tab.sizePolicy().hasHeightForWidth())
- self.main_tab.setSizePolicy(sizePolicy)
- self.main_tab.setMaximumSize(QtCore.QSize(16777215, 16777215))
- self.main_tab.setToolTip("")
- self.main_tab.setLayoutDirection(QtCore.Qt.LeftToRight)
- self.main_tab.setTabPosition(QtWidgets.QTabWidget.North)
- self.main_tab.setTabShape(QtWidgets.QTabWidget.Triangular)
- self.main_tab.setElideMode(QtCore.Qt.ElideNone)
- self.main_tab.setUsesScrollButtons(True)
- self.main_tab.setDocumentMode(False)
- self.main_tab.setTabsClosable(False)
- self.main_tab.setObjectName("main_tab")
- self.equipment_tab = QtWidgets.QWidget()
- self.equipment_tab.setObjectName("equipment_tab")
- self.gridLayout_11 = QtWidgets.QGridLayout(self.equipment_tab)
- self.gridLayout_11.setObjectName("gridLayout_11")
- spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
- self.gridLayout_11.addItem(spacerItem, 6, 2, 1, 1)
- self.search_item = QtWidgets.QLineEdit(self.equipment_tab)
- self.search_item.setEnabled(False)
- self.search_item.setMinimumSize(QtCore.QSize(0, 0))
- self.search_item.setMaximumSize(QtCore.QSize(16777215, 16777215))
- self.search_item.setObjectName("search_item")
- self.gridLayout_11.addWidget(self.search_item, 0, 1, 1, 1)
- self.all_items_tree = QtWidgets.QTreeWidget(self.equipment_tab)
- self.all_items_tree.setEnabled(False)
- self.all_items_tree.setObjectName("all_items_tree")
- self.gridLayout_11.addWidget(self.all_items_tree, 1, 0, 7, 2)
- self.frame_4 = QtWidgets.QFrame(self.equipment_tab)
- self.frame_4.setMinimumSize(QtCore.QSize(0, 40))
- self.frame_4.setMaximumSize(QtCore.QSize(16777215, 40))
- self.frame_4.setFrameShape(QtWidgets.QFrame.NoFrame)
- self.frame_4.setFrameShadow(QtWidgets.QFrame.Raised)
- self.frame_4.setObjectName("frame_4")
- self.gridLayout_9 = QtWidgets.QGridLayout(self.frame_4)
- self.gridLayout_9.setObjectName("gridLayout_9")
- self.quick_target = QtWidgets.QComboBox(self.frame_4)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.quick_target.sizePolicy().hasHeightForWidth())
- self.quick_target.setSizePolicy(sizePolicy)
- self.quick_target.setMinimumSize(QtCore.QSize(0, 20))
- self.quick_target.setMaximumSize(QtCore.QSize(16777215, 20))
- self.quick_target.setObjectName("quick_target")
- self.gridLayout_9.addWidget(self.quick_target, 0, 2, 1, 1)
- self.label_19 = QtWidgets.QLabel(self.frame_4)
- self.label_19.setMaximumSize(QtCore.QSize(16777215, 20))
- self.label_19.setObjectName("label_19")
- self.gridLayout_9.addWidget(self.label_19, 0, 0, 1, 1)
- self.quick_build = QtWidgets.QPushButton(self.frame_4)
- self.quick_build.setMinimumSize(QtCore.QSize(0, 20))
- self.quick_build.setMaximumSize(QtCore.QSize(16777215, 20))
- self.quick_build.setLayoutDirection(QtCore.Qt.LeftToRight)
- icon = QtGui.QIcon()
- icon.addPixmap(QtGui.QPixmap("icons/system-run.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
- self.quick_build.setIcon(icon)
- self.quick_build.setObjectName("quick_build")
- self.gridLayout_9.addWidget(self.quick_build, 0, 3, 1, 1)
- self.gridLayout_11.addWidget(self.frame_4, 7, 3, 1, 1)
- self.remove_item = QtWidgets.QPushButton(self.equipment_tab)
- self.remove_item.setEnabled(True)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.remove_item.sizePolicy().hasHeightForWidth())
- self.remove_item.setSizePolicy(sizePolicy)
- self.remove_item.setMinimumSize(QtCore.QSize(50, 50))
- self.remove_item.setMaximumSize(QtCore.QSize(50, 50))
- self.remove_item.setText("")
- icon1 = QtGui.QIcon()
- icon1.addPixmap(QtGui.QPixmap("icons/list-remove.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
- self.remove_item.setIcon(icon1)
- self.remove_item.setAutoDefault(False)
- self.remove_item.setObjectName("remove_item")
- self.gridLayout_11.addWidget(self.remove_item, 4, 2, 1, 1)
- spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
- self.gridLayout_11.addItem(spacerItem1, 1, 2, 1, 1)
- self.edit = QtWidgets.QPushButton(self.equipment_tab)
- self.edit.setMinimumSize(QtCore.QSize(50, 50))
- self.edit.setMaximumSize(QtCore.QSize(50, 50))
- self.edit.setText("")
- icon2 = QtGui.QIcon()
- icon2.addPixmap(QtGui.QPixmap("icons/accessories-text-editor.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
- self.edit.setIcon(icon2)
- self.edit.setIconSize(QtCore.QSize(24, 24))
- self.edit.setObjectName("edit")
- self.gridLayout_11.addWidget(self.edit, 5, 2, 1, 1)
- self.add_item = QtWidgets.QPushButton(self.equipment_tab)
- self.add_item.setEnabled(True)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.add_item.sizePolicy().hasHeightForWidth())
- self.add_item.setSizePolicy(sizePolicy)
- self.add_item.setMinimumSize(QtCore.QSize(50, 50))
- self.add_item.setMaximumSize(QtCore.QSize(50, 50))
- self.add_item.setText("")
- icon3 = QtGui.QIcon()
- icon3.addPixmap(QtGui.QPixmap("icons/list-add.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
- self.add_item.setIcon(icon3)
- self.add_item.setAutoDefault(False)
- self.add_item.setObjectName("add_item")
- self.gridLayout_11.addWidget(self.add_item, 2, 2, 1, 1)
- self.scrollArea_3 = QtWidgets.QScrollArea(self.equipment_tab)
- self.scrollArea_3.setWidgetResizable(True)
- self.scrollArea_3.setObjectName("scrollArea_3")
- self.scrollAreaWidgetContents_3 = QtWidgets.QWidget()
- self.scrollAreaWidgetContents_3.setGeometry(QtCore.QRect(0, 0, 162, 607))
- self.scrollAreaWidgetContents_3.setObjectName("scrollAreaWidgetContents_3")
- self.gridLayout_4 = QtWidgets.QGridLayout(self.scrollAreaWidgetContents_3)
- self.gridLayout_4.setObjectName("gridLayout_4")
- self.current_flight_plan = QtWidgets.QListWidget(self.scrollAreaWidgetContents_3)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.current_flight_plan.sizePolicy().hasHeightForWidth())
- self.current_flight_plan.setSizePolicy(sizePolicy)
- self.current_flight_plan.setMinimumSize(QtCore.QSize(0, 0))
- self.current_flight_plan.setMaximumSize(QtCore.QSize(16777215, 16777215))
- self.current_flight_plan.setObjectName("current_flight_plan")
- self.gridLayout_4.addWidget(self.current_flight_plan, 5, 1, 1, 1)
- self.current_airframes = QtWidgets.QListWidget(self.scrollAreaWidgetContents_3)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.current_airframes.sizePolicy().hasHeightForWidth())
- self.current_airframes.setSizePolicy(sizePolicy)
- self.current_airframes.setMinimumSize(QtCore.QSize(0, 0))
- self.current_airframes.setMaximumSize(QtCore.QSize(16777215, 16777215))
- self.current_airframes.setObjectName("current_airframes")
- self.gridLayout_4.addWidget(self.current_airframes, 1, 1, 1, 1)
- self.current_telemetry = QtWidgets.QListWidget(self.scrollAreaWidgetContents_3)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.current_telemetry.sizePolicy().hasHeightForWidth())
- self.current_telemetry.setSizePolicy(sizePolicy)
- self.current_telemetry.setMinimumSize(QtCore.QSize(0, 0))
- self.current_telemetry.setMaximumSize(QtCore.QSize(16777215, 16777215))
- self.current_telemetry.setObjectName("current_telemetry")
- self.gridLayout_4.addWidget(self.current_telemetry, 11, 1, 1, 1)
- self.current_flight_plan_label = QtWidgets.QLabel(self.scrollAreaWidgetContents_3)
- self.current_flight_plan_label.setMinimumSize(QtCore.QSize(0, 20))
- self.current_flight_plan_label.setMaximumSize(QtCore.QSize(16777215, 20))
- self.current_flight_plan_label.setObjectName("current_flight_plan_label")
- self.gridLayout_4.addWidget(self.current_flight_plan_label, 4, 1, 1, 1)
- self.current_airframes_label = QtWidgets.QLabel(self.scrollAreaWidgetContents_3)
- self.current_airframes_label.setMinimumSize(QtCore.QSize(0, 20))
- self.current_airframes_label.setMaximumSize(QtCore.QSize(16777215, 20))
- self.current_airframes_label.setObjectName("current_airframes_label")
- self.gridLayout_4.addWidget(self.current_airframes_label, 0, 1, 1, 1)
- self.current_settings = QtWidgets.QListWidget(self.scrollAreaWidgetContents_3)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.current_settings.sizePolicy().hasHeightForWidth())
- self.current_settings.setSizePolicy(sizePolicy)
- self.current_settings.setMinimumSize(QtCore.QSize(0, 0))
- self.current_settings.setMaximumSize(QtCore.QSize(16777215, 16777215))
- self.current_settings.setObjectName("current_settings")
- self.gridLayout_4.addWidget(self.current_settings, 3, 1, 1, 1)
- self.current_radio_label = QtWidgets.QLabel(self.scrollAreaWidgetContents_3)
- self.current_radio_label.setMinimumSize(QtCore.QSize(0, 20))
- self.current_radio_label.setMaximumSize(QtCore.QSize(16777215, 20))
- self.current_radio_label.setObjectName("current_radio_label")
- self.gridLayout_4.addWidget(self.current_radio_label, 8, 1, 1, 1)
- self.select_kml = QtWidgets.QPushButton(self.scrollAreaWidgetContents_3)
- self.select_kml.setEnabled(False)
- self.select_kml.setMinimumSize(QtCore.QSize(0, 24))
- self.select_kml.setObjectName("select_kml")
- self.gridLayout_4.addWidget(self.select_kml, 7, 1, 1, 1)
- self.current_radio = QtWidgets.QListWidget(self.scrollAreaWidgetContents_3)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.current_radio.sizePolicy().hasHeightForWidth())
- self.current_radio.setSizePolicy(sizePolicy)
- self.current_radio.setMinimumSize(QtCore.QSize(0, 0))
- self.current_radio.setMaximumSize(QtCore.QSize(16777215, 16777215))
- self.current_radio.setObjectName("current_radio")
- self.gridLayout_4.addWidget(self.current_radio, 9, 1, 1, 1)
- self.open_gui = QtWidgets.QPushButton(self.scrollAreaWidgetContents_3)
- self.open_gui.setEnabled(False)
- self.open_gui.setMinimumSize(QtCore.QSize(0, 24))
- self.open_gui.setObjectName("open_gui")
- self.gridLayout_4.addWidget(self.open_gui, 6, 1, 1, 1)
- self.current_settings_label = QtWidgets.QLabel(self.scrollAreaWidgetContents_3)
- self.current_settings_label.setMinimumSize(QtCore.QSize(0, 20))
- self.current_settings_label.setMaximumSize(QtCore.QSize(16777215, 20))
- self.current_settings_label.setObjectName("current_settings_label")
- self.gridLayout_4.addWidget(self.current_settings_label, 2, 1, 1, 1)
- self.current_telemetry_label = QtWidgets.QLabel(self.scrollAreaWidgetContents_3)
- self.current_telemetry_label.setMinimumSize(QtCore.QSize(0, 20))
- self.current_telemetry_label.setMaximumSize(QtCore.QSize(16777215, 20))
- self.current_telemetry_label.setObjectName("current_telemetry_label")
- self.gridLayout_4.addWidget(self.current_telemetry_label, 10, 1, 1, 1)
- self.scrollArea_3.setWidget(self.scrollAreaWidgetContents_3)
- self.gridLayout_11.addWidget(self.scrollArea_3, 0, 3, 7, 1)
- self.search_item_icon = QtWidgets.QLabel(self.equipment_tab)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.search_item_icon.sizePolicy().hasHeightForWidth())
- self.search_item_icon.setSizePolicy(sizePolicy)
- self.search_item_icon.setMinimumSize(QtCore.QSize(0, 0))
- self.search_item_icon.setMaximumSize(QtCore.QSize(16777215, 16777215))
- self.search_item_icon.setToolTip("")
- self.search_item_icon.setFrameShape(QtWidgets.QFrame.NoFrame)
- self.search_item_icon.setText("")
- self.search_item_icon.setPixmap(QtGui.QPixmap("icons/search_field.png"))
- self.search_item_icon.setObjectName("search_item_icon")
- self.gridLayout_11.addWidget(self.search_item_icon, 0, 0, 1, 1)
- self.main_tab.addTab(self.equipment_tab, "")
- self.build_flash_tab = QtWidgets.QWidget()
- self.build_flash_tab.setObjectName("build_flash_tab")
- self.gridLayout_3 = QtWidgets.QGridLayout(self.build_flash_tab)
- self.gridLayout_3.setObjectName("gridLayout_3")
- self.label_28 = QtWidgets.QLabel(self.build_flash_tab)
- self.label_28.setMinimumSize(QtCore.QSize(20, 20))
- self.label_28.setMaximumSize(QtCore.QSize(20, 20))
- self.label_28.setText("")
- self.label_28.setPixmap(QtGui.QPixmap("icons/gtk-info.svg"))
- self.label_28.setObjectName("label_28")
- self.gridLayout_3.addWidget(self.label_28, 11, 0, 1, 1)
- self.build_result = QtWidgets.QLabel(self.build_flash_tab)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.build_result.sizePolicy().hasHeightForWidth())
- self.build_result.setSizePolicy(sizePolicy)
- self.build_result.setMinimumSize(QtCore.QSize(0, 20))
- self.build_result.setMaximumSize(QtCore.QSize(16777215, 20))
- self.build_result.setFrameShape(QtWidgets.QFrame.StyledPanel)
- self.build_result.setText("")
- self.build_result.setObjectName("build_result")
- self.gridLayout_3.addWidget(self.build_result, 3, 3, 1, 9)
- self.info_nb = QtWidgets.QLabel(self.build_flash_tab)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.info_nb.sizePolicy().hasHeightForWidth())
- self.info_nb.setSizePolicy(sizePolicy)
- self.info_nb.setMinimumSize(QtCore.QSize(30, 20))
- self.info_nb.setMaximumSize(QtCore.QSize(30, 20))
- font = QtGui.QFont()
- font.setBold(True)
- font.setWeight(75)
- self.info_nb.setFont(font)
- self.info_nb.setStyleSheet("border:2px solid #00ff00;")
- self.info_nb.setFrameShape(QtWidgets.QFrame.StyledPanel)
- self.info_nb.setText("")
- self.info_nb.setObjectName("info_nb")
- self.gridLayout_3.addWidget(self.info_nb, 11, 2, 1, 1)
- self.flash_resut_icon = QtWidgets.QLabel(self.build_flash_tab)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.flash_resut_icon.sizePolicy().hasHeightForWidth())
- self.flash_resut_icon.setSizePolicy(sizePolicy)
- self.flash_resut_icon.setMinimumSize(QtCore.QSize(30, 0))
- self.flash_resut_icon.setMaximumSize(QtCore.QSize(16777215, 16777215))
- self.flash_resut_icon.setToolTip("")
- self.flash_resut_icon.setFrameShape(QtWidgets.QFrame.NoFrame)
- self.flash_resut_icon.setText("")
- self.flash_resut_icon.setObjectName("flash_resut_icon")
- self.gridLayout_3.addWidget(self.flash_resut_icon, 7, 2, 1, 1)
- self.flash_result = QtWidgets.QLabel(self.build_flash_tab)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.flash_result.sizePolicy().hasHeightForWidth())
- self.flash_result.setSizePolicy(sizePolicy)
- self.flash_result.setMinimumSize(QtCore.QSize(0, 20))
- self.flash_result.setMaximumSize(QtCore.QSize(16777215, 20))
- self.flash_result.setFrameShape(QtWidgets.QFrame.StyledPanel)
- self.flash_result.setText("")
- self.flash_result.setObjectName("flash_result")
- self.gridLayout_3.addWidget(self.flash_result, 7, 3, 1, 8)
- self.label_25 = QtWidgets.QLabel(self.build_flash_tab)
- font = QtGui.QFont()
- font.setPointSize(14)
- font.setBold(True)
- font.setWeight(75)
- self.label_25.setFont(font)
- self.label_25.setObjectName("label_25")
- self.gridLayout_3.addWidget(self.label_25, 5, 0, 1, 2)
- self.label_10 = QtWidgets.QLabel(self.build_flash_tab)
- self.label_10.setObjectName("label_10")
- self.gridLayout_3.addWidget(self.label_10, 11, 8, 1, 1)
- self.line_3 = QtWidgets.QFrame(self.build_flash_tab)
- self.line_3.setFrameShape(QtWidgets.QFrame.HLine)
- self.line_3.setFrameShadow(QtWidgets.QFrame.Sunken)
- self.line_3.setObjectName("line_3")
- self.gridLayout_3.addWidget(self.line_3, 4, 0, 1, 12)
- self.label_26 = QtWidgets.QLabel(self.build_flash_tab)
- self.label_26.setMinimumSize(QtCore.QSize(0, 0))
- self.label_26.setMaximumSize(QtCore.QSize(60, 16777215))
- self.label_26.setObjectName("label_26")
- self.gridLayout_3.addWidget(self.label_26, 1, 0, 1, 2)
- self.label_11 = QtWidgets.QLabel(self.build_flash_tab)
- self.label_11.setObjectName("label_11")
- self.gridLayout_3.addWidget(self.label_11, 11, 5, 1, 1)
- self.label_13 = QtWidgets.QLabel(self.build_flash_tab)
- self.label_13.setMinimumSize(QtCore.QSize(0, 0))
- self.label_13.setMaximumSize(QtCore.QSize(60, 16777215))
- self.label_13.setObjectName("label_13")
- self.gridLayout_3.addWidget(self.label_13, 7, 0, 1, 2)
- self.warnings_nb = QtWidgets.QLabel(self.build_flash_tab)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.warnings_nb.sizePolicy().hasHeightForWidth())
- self.warnings_nb.setSizePolicy(sizePolicy)
- self.warnings_nb.setMinimumSize(QtCore.QSize(30, 20))
- self.warnings_nb.setMaximumSize(QtCore.QSize(30, 20))
- font = QtGui.QFont()
- font.setBold(True)
- font.setWeight(75)
- self.warnings_nb.setFont(font)
- self.warnings_nb.setStyleSheet("border:2px solid #ffaa00;")
- self.warnings_nb.setFrameShape(QtWidgets.QFrame.StyledPanel)
- self.warnings_nb.setText("")
- self.warnings_nb.setObjectName("warnings_nb")
- self.gridLayout_3.addWidget(self.warnings_nb, 11, 6, 1, 1)
- self.label_23 = QtWidgets.QLabel(self.build_flash_tab)
- font = QtGui.QFont()
- font.setPointSize(14)
- font.setBold(True)
- font.setWeight(75)
- self.label_23.setFont(font)
- self.label_23.setObjectName("label_23")
- self.gridLayout_3.addWidget(self.label_23, 0, 0, 1, 2)
- self.label_12 = QtWidgets.QLabel(self.build_flash_tab)
- self.label_12.setMinimumSize(QtCore.QSize(0, 0))
- self.label_12.setMaximumSize(QtCore.QSize(60, 16777215))
- self.label_12.setObjectName("label_12")
- self.gridLayout_3.addWidget(self.label_12, 6, 0, 1, 2)
- spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
- self.gridLayout_3.addItem(spacerItem2, 11, 10, 1, 1)
- self.label_14 = QtWidgets.QLabel(self.build_flash_tab)
- self.label_14.setObjectName("label_14")
- self.gridLayout_3.addWidget(self.label_14, 11, 1, 1, 1)
- self.label_15 = QtWidgets.QLabel(self.build_flash_tab)
- self.label_15.setMinimumSize(QtCore.QSize(20, 20))
- self.label_15.setMaximumSize(QtCore.QSize(20, 20))
- self.label_15.setText("")
- self.label_15.setPixmap(QtGui.QPixmap("icons/dialog-error.svg"))
- self.label_15.setObjectName("label_15")
- self.gridLayout_3.addWidget(self.label_15, 11, 7, 1, 1)
- self.target = QtWidgets.QComboBox(self.build_flash_tab)
- self.target.setMinimumSize(QtCore.QSize(0, 30))
- self.target.setMaximumSize(QtCore.QSize(16777215, 30))
- self.target.setObjectName("target")
- self.gridLayout_3.addWidget(self.target, 1, 2, 1, 8)
- self.label_16 = QtWidgets.QLabel(self.build_flash_tab)
- self.label_16.setMinimumSize(QtCore.QSize(20, 20))
- self.label_16.setMaximumSize(QtCore.QSize(20, 20))
- self.label_16.setText("")
- self.label_16.setPixmap(QtGui.QPixmap("icons/dialog-warning.png"))
- self.label_16.setObjectName("label_16")
- self.gridLayout_3.addWidget(self.label_16, 11, 4, 1, 1)
- self.clean = QtWidgets.QPushButton(self.build_flash_tab)
- self.clean.setMinimumSize(QtCore.QSize(130, 30))
- self.clean.setMaximumSize(QtCore.QSize(130, 30))
- self.clean.setLayoutDirection(QtCore.Qt.LeftToRight)
- icon4 = QtGui.QIcon()
- icon4.addPixmap(QtGui.QPixmap("icons/edit-clear.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
- self.clean.setIcon(icon4)
- self.clean.setObjectName("clean")
- self.gridLayout_3.addWidget(self.clean, 1, 11, 1, 1)
- self.line_4 = QtWidgets.QFrame(self.build_flash_tab)
- self.line_4.setFrameShape(QtWidgets.QFrame.HLine)
- self.line_4.setFrameShadow(QtWidgets.QFrame.Sunken)
- self.line_4.setObjectName("line_4")
- self.gridLayout_3.addWidget(self.line_4, 9, 0, 1, 12)
- self.errors_nb = QtWidgets.QLabel(self.build_flash_tab)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.errors_nb.sizePolicy().hasHeightForWidth())
- self.errors_nb.setSizePolicy(sizePolicy)
- self.errors_nb.setMinimumSize(QtCore.QSize(30, 20))
- self.errors_nb.setMaximumSize(QtCore.QSize(30, 20))
- font = QtGui.QFont()
- font.setBold(True)
- font.setWeight(75)
- self.errors_nb.setFont(font)
- self.errors_nb.setAutoFillBackground(False)
- self.errors_nb.setStyleSheet("border:2px solid #ff0000;")
- self.errors_nb.setFrameShape(QtWidgets.QFrame.StyledPanel)
- self.errors_nb.setText("")
- self.errors_nb.setObjectName("errors_nb")
- self.gridLayout_3.addWidget(self.errors_nb, 11, 9, 1, 1)
- self.device = QtWidgets.QComboBox(self.build_flash_tab)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.device.sizePolicy().hasHeightForWidth())
- self.device.setSizePolicy(sizePolicy)
- self.device.setMinimumSize(QtCore.QSize(0, 30))
- self.device.setMaximumSize(QtCore.QSize(16777215, 30))
- self.device.setObjectName("device")
- self.gridLayout_3.addWidget(self.device, 6, 2, 1, 8)
- self.build = QtWidgets.QPushButton(self.build_flash_tab)
- self.build.setMinimumSize(QtCore.QSize(130, 30))
- self.build.setMaximumSize(QtCore.QSize(130, 30))
- self.build.setLayoutDirection(QtCore.Qt.LeftToRight)
- self.build.setIcon(icon)
- self.build.setObjectName("build")
- self.gridLayout_3.addWidget(self.build, 2, 11, 1, 1)
- self.show_console = QtWidgets.QPushButton(self.build_flash_tab)
- self.show_console.setMinimumSize(QtCore.QSize(0, 30))
- self.show_console.setMaximumSize(QtCore.QSize(16777215, 20))
- self.show_console.setLayoutDirection(QtCore.Qt.LeftToRight)
- icon5 = QtGui.QIcon()
- icon5.addPixmap(QtGui.QPixmap("icons/utilities-terminal.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
- self.show_console.setIcon(icon5)
- self.show_console.setObjectName("show_console")
- self.gridLayout_3.addWidget(self.show_console, 11, 11, 1, 1, QtCore.Qt.AlignVCenter)
- spacerItem3 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
- self.gridLayout_3.addItem(spacerItem3, 12, 11, 1, 1)
- self.build_result_icon = QtWidgets.QLabel(self.build_flash_tab)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.build_result_icon.sizePolicy().hasHeightForWidth())
- self.build_result_icon.setSizePolicy(sizePolicy)
- self.build_result_icon.setMinimumSize(QtCore.QSize(0, 0))
- self.build_result_icon.setMaximumSize(QtCore.QSize(30, 16777215))
- self.build_result_icon.setToolTip("")
- self.build_result_icon.setFrameShape(QtWidgets.QFrame.NoFrame)
- self.build_result_icon.setText("")
- self.build_result_icon.setObjectName("build_result_icon")
- self.gridLayout_3.addWidget(self.build_result_icon, 3, 2, 1, 1)
- self.upload = QtWidgets.QPushButton(self.build_flash_tab)
- self.upload.setEnabled(True)
- self.upload.setMinimumSize(QtCore.QSize(130, 30))
- self.upload.setMaximumSize(QtCore.QSize(130, 30))
- icon6 = QtGui.QIcon()
- icon6.addPixmap(QtGui.QPixmap("icons/go-up.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
- self.upload.setIcon(icon6)
- self.upload.setObjectName("upload")
- self.gridLayout_3.addWidget(self.upload, 6, 11, 1, 1)
- self.label_9 = QtWidgets.QLabel(self.build_flash_tab)
- self.label_9.setMinimumSize(QtCore.QSize(0, 30))
- self.label_9.setMaximumSize(QtCore.QSize(60, 16777215))
- self.label_9.setObjectName("label_9")
- self.gridLayout_3.addWidget(self.label_9, 3, 0, 1, 2)
- self.main_tab.addTab(self.build_flash_tab, "")
- self.sessions_tab = QtWidgets.QWidget()
- self.sessions_tab.setObjectName("sessions_tab")
- self.gridLayout_2 = QtWidgets.QGridLayout(self.sessions_tab)
- self.gridLayout_2.setObjectName("gridLayout_2")
- self.label_7 = QtWidgets.QLabel(self.sessions_tab)
- self.label_7.setObjectName("label_7")
- self.gridLayout_2.addWidget(self.label_7, 5, 0, 1, 2)
- self.programs = QtWidgets.QListWidget(self.sessions_tab)
- self.programs.setMinimumSize(QtCore.QSize(0, 0))
- self.programs.setMaximumSize(QtCore.QSize(16777215, 16777215))
- self.programs.setLayoutDirection(QtCore.Qt.LeftToRight)
- self.programs.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
- self.programs.setIconSize(QtCore.QSize(10, 10))
- self.programs.setObjectName("programs")
- self.gridLayout_2.addWidget(self.programs, 2, 2, 3, 1)
- self.label_8 = QtWidgets.QLabel(self.sessions_tab)
- self.label_8.setObjectName("label_8")
- self.gridLayout_2.addWidget(self.label_8, 2, 0, 1, 2)
- spacerItem4 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
- self.gridLayout_2.addItem(spacerItem4, 3, 3, 1, 1)
- self.start_all_button = QtWidgets.QPushButton(self.sessions_tab)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.start_all_button.sizePolicy().hasHeightForWidth())
- self.start_all_button.setSizePolicy(sizePolicy)
- self.start_all_button.setMinimumSize(QtCore.QSize(0, 50))
- self.start_all_button.setMaximumSize(QtCore.QSize(16777215, 50))
- font = QtGui.QFont()
- font.setBold(True)
- font.setItalic(False)
- font.setUnderline(False)
- font.setWeight(75)
- font.setStrikeOut(False)
- font.setKerning(True)
- self.start_all_button.setFont(font)
- icon7 = QtGui.QIcon()
- icon7.addPixmap(QtGui.QPixmap("icons/media-playback-start.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
- self.start_all_button.setIcon(icon7)
- self.start_all_button.setObjectName("start_all_button")
- self.gridLayout_2.addWidget(self.start_all_button, 5, 3, 1, 1)
- spacerItem5 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
- self.gridLayout_2.addItem(spacerItem5, 7, 2, 1, 1)
- self.play_stop_program = QtWidgets.QPushButton(self.sessions_tab)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.play_stop_program.sizePolicy().hasHeightForWidth())
- self.play_stop_program.setSizePolicy(sizePolicy)
- self.play_stop_program.setMinimumSize(QtCore.QSize(0, 50))
- self.play_stop_program.setMaximumSize(QtCore.QSize(16777215, 50))
- self.play_stop_program.setIcon(icon7)
- self.play_stop_program.setAutoDefault(False)
- self.play_stop_program.setObjectName("play_stop_program")
- self.gridLayout_2.addWidget(self.play_stop_program, 2, 3, 1, 1)
- self.options = QtWidgets.QListWidget(self.sessions_tab)
- self.options.setMaximumSize(QtCore.QSize(16777215, 16777215))
- self.options.setObjectName("options")
- self.gridLayout_2.addWidget(self.options, 5, 2, 2, 1)
- self.remove_program = QtWidgets.QPushButton(self.sessions_tab)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.remove_program.sizePolicy().hasHeightForWidth())
- self.remove_program.setSizePolicy(sizePolicy)
- self.remove_program.setMinimumSize(QtCore.QSize(30, 30))
- self.remove_program.setMaximumSize(QtCore.QSize(30, 30))
- self.remove_program.setText("")
- self.remove_program.setIcon(icon1)
- self.remove_program.setAutoDefault(False)
- self.remove_program.setObjectName("remove_program")
- self.gridLayout_2.addWidget(self.remove_program, 4, 0, 1, 1)
- self.session = QtWidgets.QComboBox(self.sessions_tab)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.session.sizePolicy().hasHeightForWidth())
- self.session.setSizePolicy(sizePolicy)
- self.session.setObjectName("session")
- self.gridLayout_2.addWidget(self.session, 1, 2, 1, 1)
- self.kill_all_button = QtWidgets.QPushButton(self.sessions_tab)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.kill_all_button.sizePolicy().hasHeightForWidth())
- self.kill_all_button.setSizePolicy(sizePolicy)
- self.kill_all_button.setMinimumSize(QtCore.QSize(0, 50))
- self.kill_all_button.setMaximumSize(QtCore.QSize(16777215, 50))
- font = QtGui.QFont()
- font.setBold(True)
- font.setItalic(False)
- font.setUnderline(False)
- font.setWeight(75)
- font.setStrikeOut(False)
- font.setKerning(True)
- self.kill_all_button.setFont(font)
- self.kill_all_button.setLayoutDirection(QtCore.Qt.LeftToRight)
- icon8 = QtGui.QIcon()
- icon8.addPixmap(QtGui.QPixmap("icons/process-stop.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
- self.kill_all_button.setIcon(icon8)
- self.kill_all_button.setObjectName("kill_all_button")
- self.gridLayout_2.addWidget(self.kill_all_button, 4, 3, 1, 1)
- self.label_4 = QtWidgets.QLabel(self.sessions_tab)
- self.label_4.setObjectName("label_4")
- self.gridLayout_2.addWidget(self.label_4, 1, 0, 1, 2)
- self.add_program = QtWidgets.QPushButton(self.sessions_tab)
- self.add_program.setEnabled(False)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.add_program.sizePolicy().hasHeightForWidth())
- self.add_program.setSizePolicy(sizePolicy)
- self.add_program.setMinimumSize(QtCore.QSize(30, 30))
- self.add_program.setMaximumSize(QtCore.QSize(30, 30))
- self.add_program.setText("")
- self.add_program.setIcon(icon3)
- self.add_program.setAutoDefault(False)
- self.add_program.setObjectName("add_program")
- self.gridLayout_2.addWidget(self.add_program, 4, 1, 1, 1)
- self.remove_option = QtWidgets.QPushButton(self.sessions_tab)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.remove_option.sizePolicy().hasHeightForWidth())
- self.remove_option.setSizePolicy(sizePolicy)
- self.remove_option.setMinimumSize(QtCore.QSize(30, 30))
- self.remove_option.setMaximumSize(QtCore.QSize(30, 30))
- self.remove_option.setText("")
- self.remove_option.setIcon(icon1)
- self.remove_option.setAutoDefault(False)
- self.remove_option.setObjectName("remove_option")
- self.gridLayout_2.addWidget(self.remove_option, 6, 0, 1, 1)
- self.add_option = QtWidgets.QPushButton(self.sessions_tab)
- self.add_option.setEnabled(True)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.add_option.sizePolicy().hasHeightForWidth())
- self.add_option.setSizePolicy(sizePolicy)
- self.add_option.setMinimumSize(QtCore.QSize(30, 30))
- self.add_option.setMaximumSize(QtCore.QSize(30, 30))
- self.add_option.setText("")
- self.add_option.setIcon(icon3)
- self.add_option.setAutoDefault(False)
- self.add_option.setObjectName("add_option")
- self.gridLayout_2.addWidget(self.add_option, 6, 1, 1, 1)
- self.tools_menu = ToolsMenu(self.sessions_tab)
- self.tools_menu.setMinimumSize(QtCore.QSize(0, 0))
- self.tools_menu.setBaseSize(QtCore.QSize(200, 140))
- self.tools_menu.setFrameShape(QtWidgets.QFrame.StyledPanel)
- self.tools_menu.setFrameShadow(QtWidgets.QFrame.Raised)
- self.tools_menu.setObjectName("tools_menu")
- self.gridLayout_2.addWidget(self.tools_menu, 0, 2, 1, 1)
- self.main_tab.addTab(self.sessions_tab, "")
- self.console_tab = QtWidgets.QWidget()
- self.console_tab.setObjectName("console_tab")
- self.gridLayout_5 = QtWidgets.QGridLayout(self.console_tab)
- self.gridLayout_5.setObjectName("gridLayout_5")
- self.line_7 = QtWidgets.QFrame(self.console_tab)
- self.line_7.setFrameShape(QtWidgets.QFrame.HLine)
- self.line_7.setFrameShadow(QtWidgets.QFrame.Sunken)
- self.line_7.setObjectName("line_7")
- self.gridLayout_5.addWidget(self.line_7, 10, 1, 1, 1)
- self.console = QtWidgets.QTextEdit(self.console_tab)
- self.console.setEnabled(True)
- font = QtGui.QFont()
- font.setFamily("Ubuntu")
- self.console.setFont(font)
- self.console.setLayoutDirection(QtCore.Qt.LeftToRight)
- self.console.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
- self.console.setTextInteractionFlags(QtCore.Qt.TextSelectableByKeyboard|QtCore.Qt.TextSelectableByMouse)
- self.console.setObjectName("console")
- self.gridLayout_5.addWidget(self.console, 0, 0, 13, 1)
- self.label_24 = QtWidgets.QLabel(self.console_tab)
- font = QtGui.QFont()
- font.setPointSize(14)
- font.setBold(True)
- font.setWeight(75)
- self.label_24.setFont(font)
- self.label_24.setObjectName("label_24")
- self.gridLayout_5.addWidget(self.label_24, 0, 1, 1, 1)
- self.important = QtWidgets.QRadioButton(self.console_tab)
- self.important.setToolTip("")
- self.important.setChecked(False)
- self.important.setObjectName("important")
- self.gridLayout_5.addWidget(self.important, 2, 1, 1, 1)
- self.custom = QtWidgets.QRadioButton(self.console_tab)
- self.custom.setToolTip("")
- self.custom.setChecked(True)
- self.custom.setObjectName("custom")
- self.gridLayout_5.addWidget(self.custom, 3, 1, 1, 1)
- self.all = QtWidgets.QRadioButton(self.console_tab)
- self.all.setToolTip("")
- self.all.setChecked(False)
- self.all.setObjectName("all")
- self.gridLayout_5.addWidget(self.all, 4, 1, 1, 1)
- self.clean_console = QtWidgets.QPushButton(self.console_tab)
- self.clean_console.setIcon(icon4)
- self.clean_console.setObjectName("clean_console")
- self.gridLayout_5.addWidget(self.clean_console, 12, 1, 1, 1)
- self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
- self.horizontalLayout_2.setObjectName("horizontalLayout_2")
- self.display_info = QtWidgets.QCheckBox(self.console_tab)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.display_info.sizePolicy().hasHeightForWidth())
- self.display_info.setSizePolicy(sizePolicy)
- icon9 = QtGui.QIcon()
- icon9.addPixmap(QtGui.QPixmap("icons/gtk-info.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
- self.display_info.setIcon(icon9)
- self.display_info.setObjectName("display_info")
- self.horizontalLayout_2.addWidget(self.display_info)
- self.gridLayout_5.addLayout(self.horizontalLayout_2, 7, 1, 1, 1)
- self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
- self.horizontalLayout_4.setObjectName("horizontalLayout_4")
- self.display_warnings = QtWidgets.QCheckBox(self.console_tab)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.display_warnings.sizePolicy().hasHeightForWidth())
- self.display_warnings.setSizePolicy(sizePolicy)
- icon10 = QtGui.QIcon()
- icon10.addPixmap(QtGui.QPixmap("icons/dialog-warning.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
- self.display_warnings.setIcon(icon10)
- self.display_warnings.setChecked(False)
- self.display_warnings.setObjectName("display_warnings")
- self.horizontalLayout_4.addWidget(self.display_warnings)
- self.gridLayout_5.addLayout(self.horizontalLayout_4, 8, 1, 1, 1)
- spacerItem6 = QtWidgets.QSpacerItem(20, 261, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
- self.gridLayout_5.addItem(spacerItem6, 11, 1, 1, 1)
- self.line_5 = QtWidgets.QFrame(self.console_tab)
- self.line_5.setFrameShape(QtWidgets.QFrame.HLine)
- self.line_5.setFrameShadow(QtWidgets.QFrame.Sunken)
- self.line_5.setObjectName("line_5")
- self.gridLayout_5.addWidget(self.line_5, 5, 1, 1, 1)
- self.horizontalLayout_5 = QtWidgets.QHBoxLayout()
- self.horizontalLayout_5.setObjectName("horizontalLayout_5")
- self.display_errors = QtWidgets.QCheckBox(self.console_tab)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.display_errors.sizePolicy().hasHeightForWidth())
- self.display_errors.setSizePolicy(sizePolicy)
- icon11 = QtGui.QIcon()
- icon11.addPixmap(QtGui.QPixmap("icons/dialog-error.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
- self.display_errors.setIcon(icon11)
- self.display_errors.setChecked(False)
- self.display_errors.setObjectName("display_errors")
- self.horizontalLayout_5.addWidget(self.display_errors)
- self.gridLayout_5.addLayout(self.horizontalLayout_5, 9, 1, 1, 1)
- self.line_6 = QtWidgets.QFrame(self.console_tab)
- self.line_6.setFrameShape(QtWidgets.QFrame.HLine)
- self.line_6.setFrameShadow(QtWidgets.QFrame.Sunken)
- self.line_6.setObjectName("line_6")
- self.gridLayout_5.addWidget(self.line_6, 1, 1, 1, 1)
- self.horizontalLayout_6 = QtWidgets.QHBoxLayout()
- self.horizontalLayout_6.setObjectName("horizontalLayout_6")
- self.display_default = QtWidgets.QCheckBox(self.console_tab)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.display_default.sizePolicy().hasHeightForWidth())
- self.display_default.setSizePolicy(sizePolicy)
- self.display_default.setObjectName("display_default")
- self.horizontalLayout_6.addWidget(self.display_default)
- self.gridLayout_5.addLayout(self.horizontalLayout_6, 6, 1, 1, 1)
- self.main_tab.addTab(self.console_tab, "")
- self.gridLayout_10.addWidget(self.main_tab, 1, 0, 1, 1)
- self.frame = QtWidgets.QFrame(self.centralwidget)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth())
- self.frame.setSizePolicy(sizePolicy)
- self.frame.setMaximumSize(QtCore.QSize(16777215, 20))
- self.frame.setFrameShape(QtWidgets.QFrame.NoFrame)
- self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
- self.frame.setLineWidth(0)
- self.frame.setObjectName("frame")
- self.gridLayout_6 = QtWidgets.QGridLayout(self.frame)
- self.gridLayout_6.setContentsMargins(-1, 0, -1, 0)
- self.gridLayout_6.setVerticalSpacing(0)
- self.gridLayout_6.setObjectName("gridLayout_6")
- self.line_2 = QtWidgets.QFrame(self.frame)
- self.line_2.setFrameShape(QtWidgets.QFrame.VLine)
- self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken)
- self.line_2.setObjectName("line_2")
- self.gridLayout_6.addWidget(self.line_2, 0, 5, 1, 1)
- self.label_20 = QtWidgets.QLabel(self.frame)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.label_20.sizePolicy().hasHeightForWidth())
- self.label_20.setSizePolicy(sizePolicy)
- self.label_20.setMinimumSize(QtCore.QSize(0, 20))
- self.label_20.setMaximumSize(QtCore.QSize(16777215, 20))
- self.label_20.setObjectName("label_20")
- self.gridLayout_6.addWidget(self.label_20, 0, 0, 1, 1)
- self.open_home_terminal = QtWidgets.QPushButton(self.frame)
- self.open_home_terminal.setMinimumSize(QtCore.QSize(0, 20))
- self.open_home_terminal.setMaximumSize(QtCore.QSize(16777215, 20))
- self.open_home_terminal.setText("")
- self.open_home_terminal.setDefault(False)
- self.open_home_terminal.setFlat(False)
- self.open_home_terminal.setObjectName("open_home_terminal")
- self.gridLayout_6.addWidget(self.open_home_terminal, 0, 1, 1, 1)
- self.run_version = QtWidgets.QLabel(self.frame)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.run_version.sizePolicy().hasHeightForWidth())
- self.run_version.setSizePolicy(sizePolicy)
- self.run_version.setMinimumSize(QtCore.QSize(0, 20))
- self.run_version.setMaximumSize(QtCore.QSize(16777215, 20))
- self.run_version.setFrameShape(QtWidgets.QFrame.NoFrame)
- self.run_version.setText("")
- self.run_version.setObjectName("run_version")
- self.gridLayout_6.addWidget(self.run_version, 0, 7, 1, 1)
- self.label_29 = QtWidgets.QLabel(self.frame)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.label_29.sizePolicy().hasHeightForWidth())
- self.label_29.setSizePolicy(sizePolicy)
- self.label_29.setMinimumSize(QtCore.QSize(0, 20))
- self.label_29.setMaximumSize(QtCore.QSize(16777215, 20))
- self.label_29.setObjectName("label_29")
- self.gridLayout_6.addWidget(self.label_29, 0, 9, 1, 1)
- self.build_version = QtWidgets.QLabel(self.frame)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.build_version.sizePolicy().hasHeightForWidth())
- self.build_version.setSizePolicy(sizePolicy)
- self.build_version.setMinimumSize(QtCore.QSize(0, 20))
- self.build_version.setMaximumSize(QtCore.QSize(16777215, 20))
- self.build_version.setFrameShape(QtWidgets.QFrame.NoFrame)
- self.build_version.setText("")
- self.build_version.setObjectName("build_version")
- self.gridLayout_6.addWidget(self.build_version, 0, 10, 1, 1)
- self.label_22 = QtWidgets.QLabel(self.frame)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.label_22.sizePolicy().hasHeightForWidth())
- self.label_22.setSizePolicy(sizePolicy)
- self.label_22.setMinimumSize(QtCore.QSize(0, 20))
- self.label_22.setMaximumSize(QtCore.QSize(16777215, 20))
- self.label_22.setObjectName("label_22")
- self.gridLayout_6.addWidget(self.label_22, 0, 6, 1, 1)
- self.switch_mode = QtWidgets.QPushButton(self.frame)
- self.switch_mode.setEnabled(False)
- self.switch_mode.setMinimumSize(QtCore.QSize(0, 20))
- self.switch_mode.setMaximumSize(QtCore.QSize(16777215, 20))
- self.switch_mode.setText("")
- self.switch_mode.setFlat(False)
- self.switch_mode.setObjectName("switch_mode")
- self.gridLayout_6.addWidget(self.switch_mode, 0, 4, 1, 1)
- self.line_8 = QtWidgets.QFrame(self.frame)
- self.line_8.setFrameShape(QtWidgets.QFrame.VLine)
- self.line_8.setFrameShadow(QtWidgets.QFrame.Sunken)
- self.line_8.setObjectName("line_8")
- self.gridLayout_6.addWidget(self.line_8, 0, 8, 1, 1)
- self.line = QtWidgets.QFrame(self.frame)
- self.line.setFrameShape(QtWidgets.QFrame.VLine)
- self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
- self.line.setObjectName("line")
- self.gridLayout_6.addWidget(self.line, 0, 2, 1, 1)
- self.label_21 = QtWidgets.QLabel(self.frame)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.label_21.sizePolicy().hasHeightForWidth())
- self.label_21.setSizePolicy(sizePolicy)
- self.label_21.setMinimumSize(QtCore.QSize(0, 20))
- self.label_21.setMaximumSize(QtCore.QSize(16777215, 20))
- self.label_21.setObjectName("label_21")
- self.gridLayout_6.addWidget(self.label_21, 0, 3, 1, 1)
- spacerItem7 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
- self.gridLayout_6.addItem(spacerItem7, 0, 11, 1, 1)
- self.gridLayout_10.addWidget(self.frame, 2, 0, 1, 2)
- MainWindow.setCentralWidget(self.centralwidget)
- self.menubar = QtWidgets.QMenuBar(MainWindow)
- self.menubar.setGeometry(QtCore.QRect(0, 0, 833, 25))
- self.menubar.setObjectName("menubar")
- self.menuSet = QtWidgets.QMenu(self.menubar)
- self.menuSet.setObjectName("menuSet")
- self.menuConfiguration = QtWidgets.QMenu(self.menubar)
- self.menuConfiguration.setObjectName("menuConfiguration")
- self.menuMenu = QtWidgets.QMenu(self.menubar)
- self.menuMenu.setObjectName("menuMenu")
- self.menuView = QtWidgets.QMenu(self.menubar)
- self.menuView.setObjectName("menuView")
- self.menuHelp = QtWidgets.QMenu(self.menubar)
- self.menuHelp.setObjectName("menuHelp")
- self.menuSession = QtWidgets.QMenu(self.menubar)
- self.menuSession.setObjectName("menuSession")
- MainWindow.setMenuBar(self.menubar)
- self.statusbar = QtWidgets.QStatusBar(MainWindow)
- self.statusbar.setObjectName("statusbar")
- MainWindow.setStatusBar(self.statusbar)
- self.dockWidget = QtWidgets.QDockWidget(MainWindow)
- self.dockWidget.setObjectName("dockWidget")
- self.dockWidgetContents = QtWidgets.QWidget()
- self.dockWidgetContents.setObjectName("dockWidgetContents")
- self.horizontalLayout = QtWidgets.QHBoxLayout(self.dockWidgetContents)
- self.horizontalLayout.setObjectName("horizontalLayout")
- self.stackedWidget = QtWidgets.QStackedWidget(self.dockWidgetContents)
- self.stackedWidget.setEnabled(True)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.stackedWidget.sizePolicy().hasHeightForWidth())
- self.stackedWidget.setSizePolicy(sizePolicy)
- self.stackedWidget.setMinimumSize(QtCore.QSize(200, 0))
- self.stackedWidget.setMaximumSize(QtCore.QSize(200, 16777215))
- self.stackedWidget.setToolTip("")
- self.stackedWidget.setFrameShape(QtWidgets.QFrame.StyledPanel)
- self.stackedWidget.setFrameShadow(QtWidgets.QFrame.Plain)
- self.stackedWidget.setObjectName("stackedWidget")
- self.widget_2 = QtWidgets.QWidget()
- self.widget_2.setObjectName("widget_2")
- self.gridLayout_7 = QtWidgets.QGridLayout(self.widget_2)
- self.gridLayout_7.setObjectName("gridLayout_7")
- self.quick_restart = QtWidgets.QPushButton(self.widget_2)
- self.quick_restart.setEnabled(True)
- font = QtGui.QFont()
- font.setBold(True)
- font.setItalic(False)
- font.setUnderline(False)
- font.setWeight(75)
- font.setStrikeOut(False)
- font.setKerning(True)
- self.quick_restart.setFont(font)
- self.quick_restart.setIcon(icon7)
- self.quick_restart.setObjectName("quick_restart")
- self.gridLayout_7.addWidget(self.quick_restart, 6, 0, 1, 1)
- self.label_33 = QtWidgets.QLabel(self.widget_2)
- self.label_33.setObjectName("label_33")
- self.gridLayout_7.addWidget(self.label_33, 3, 0, 1, 1)
- self.programs_overview_1 = QtWidgets.QListWidget(self.widget_2)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.programs_overview_1.sizePolicy().hasHeightForWidth())
- self.programs_overview_1.setSizePolicy(sizePolicy)
- self.programs_overview_1.setMinimumSize(QtCore.QSize(0, 0))
- self.programs_overview_1.setMaximumSize(QtCore.QSize(16777215, 16777215))
- self.programs_overview_1.setObjectName("programs_overview_1")
- self.gridLayout_7.addWidget(self.programs_overview_1, 4, 0, 1, 1)
- self.label_32 = QtWidgets.QLabel(self.widget_2)
- self.label_32.setObjectName("label_32")
- self.gridLayout_7.addWidget(self.label_32, 1, 0, 1, 1)
- self.session_overview_1 = QtWidgets.QComboBox(self.widget_2)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.session_overview_1.sizePolicy().hasHeightForWidth())
- self.session_overview_1.setSizePolicy(sizePolicy)
- self.session_overview_1.setObjectName("session_overview_1")
- self.gridLayout_7.addWidget(self.session_overview_1, 2, 0, 1, 1)
- self.label_6 = QtWidgets.QLabel(self.widget_2)
- self.label_6.setFrameShape(QtWidgets.QFrame.StyledPanel)
- self.label_6.setTextFormat(QtCore.Qt.AutoText)
- self.label_6.setScaledContents(False)
- self.label_6.setWordWrap(False)
- self.label_6.setObjectName("label_6")
- self.gridLayout_7.addWidget(self.label_6, 0, 0, 1, 1)
- spacerItem8 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
- self.gridLayout_7.addItem(spacerItem8, 10, 0, 1, 1)
- self.quick_kill = QtWidgets.QPushButton(self.widget_2)
- self.quick_kill.setEnabled(True)
- font = QtGui.QFont()
- font.setBold(True)
- font.setItalic(False)
- font.setUnderline(False)
- font.setWeight(75)
- font.setStrikeOut(False)
- font.setKerning(True)
- self.quick_kill.setFont(font)
- self.quick_kill.setIcon(icon8)
- self.quick_kill.setObjectName("quick_kill")
- self.gridLayout_7.addWidget(self.quick_kill, 5, 0, 1, 1)
- self.stackedWidget.addWidget(self.widget_2)
- self.area = QtWidgets.QWidget()
- self.area.setObjectName("area")
- self.gridLayout_8 = QtWidgets.QGridLayout(self.area)
- self.gridLayout_8.setObjectName("gridLayout_8")
- self.scrollArea = QtWidgets.QScrollArea(self.area)
- self.scrollArea.setWidgetResizable(True)
- self.scrollArea.setObjectName("scrollArea")
- self.scrollAreaWidgetContents = QtWidgets.QWidget()
- self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 151, 583))
- self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
- self.gridLayout_13 = QtWidgets.QGridLayout(self.scrollAreaWidgetContents)
- self.gridLayout_13.setObjectName("gridLayout_13")
- self.label_5 = QtWidgets.QLabel(self.scrollAreaWidgetContents)
- self.label_5.setMinimumSize(QtCore.QSize(0, 30))
- self.label_5.setMaximumSize(QtCore.QSize(16777215, 30))
- self.label_5.setFrameShape(QtWidgets.QFrame.StyledPanel)
- self.label_5.setTextFormat(QtCore.Qt.AutoText)
- self.label_5.setScaledContents(False)
- self.label_5.setObjectName("label_5")
- self.gridLayout_13.addWidget(self.label_5, 0, 0, 1, 1)
- self.label_35 = QtWidgets.QLabel(self.scrollAreaWidgetContents)
- self.label_35.setMinimumSize(QtCore.QSize(0, 20))
- self.label_35.setMaximumSize(QtCore.QSize(16777215, 20))
- font = QtGui.QFont()
- font.setBold(True)
- font.setWeight(75)
- self.label_35.setFont(font)
- self.label_35.setObjectName("label_35")
- self.gridLayout_13.addWidget(self.label_35, 1, 0, 1, 1)
- self.airframes_overview = QtWidgets.QListWidget(self.scrollAreaWidgetContents)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.airframes_overview.sizePolicy().hasHeightForWidth())
- self.airframes_overview.setSizePolicy(sizePolicy)
- self.airframes_overview.setMinimumSize(QtCore.QSize(0, 0))
- self.airframes_overview.setMaximumSize(QtCore.QSize(16777215, 16777215))
- self.airframes_overview.setToolTip("")
- self.airframes_overview.setFrameShape(QtWidgets.QFrame.StyledPanel)
- self.airframes_overview.setAutoScroll(True)
- self.airframes_overview.setTextElideMode(QtCore.Qt.ElideLeft)
- self.airframes_overview.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerItem)
- self.airframes_overview.setResizeMode(QtWidgets.QListView.Adjust)
- self.airframes_overview.setLayoutMode(QtWidgets.QListView.SinglePass)
- self.airframes_overview.setObjectName("airframes_overview")
- self.gridLayout_13.addWidget(self.airframes_overview, 2, 0, 1, 1)
- self.label_34 = QtWidgets.QLabel(self.scrollAreaWidgetContents)
- self.label_34.setMinimumSize(QtCore.QSize(0, 20))
- self.label_34.setMaximumSize(QtCore.QSize(16777215, 20))
- font = QtGui.QFont()
- font.setBold(True)
- font.setWeight(75)
- self.label_34.setFont(font)
- self.label_34.setObjectName("label_34")
- self.gridLayout_13.addWidget(self.label_34, 3, 0, 1, 1)
- self.settings_overview = QtWidgets.QListWidget(self.scrollAreaWidgetContents)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.settings_overview.sizePolicy().hasHeightForWidth())
- self.settings_overview.setSizePolicy(sizePolicy)
- self.settings_overview.setMinimumSize(QtCore.QSize(0, 0))
- self.settings_overview.setMaximumSize(QtCore.QSize(16777215, 16777215))
- self.settings_overview.setToolTip("")
- self.settings_overview.setFrameShape(QtWidgets.QFrame.StyledPanel)
- self.settings_overview.setAutoScroll(True)
- self.settings_overview.setTextElideMode(QtCore.Qt.ElideLeft)
- self.settings_overview.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerItem)
- self.settings_overview.setResizeMode(QtWidgets.QListView.Adjust)
- self.settings_overview.setLayoutMode(QtWidgets.QListView.SinglePass)
- self.settings_overview.setObjectName("settings_overview")
- self.gridLayout_13.addWidget(self.settings_overview, 4, 0, 1, 1)
- self.label_36 = QtWidgets.QLabel(self.scrollAreaWidgetContents)
- self.label_36.setMinimumSize(QtCore.QSize(0, 20))
- self.label_36.setMaximumSize(QtCore.QSize(16777215, 20))
- font = QtGui.QFont()
- font.setBold(True)
- font.setWeight(75)
- self.label_36.setFont(font)
- self.label_36.setObjectName("label_36")
- self.gridLayout_13.addWidget(self.label_36, 5, 0, 1, 1)
- self.flight_plan_overview = QtWidgets.QListWidget(self.scrollAreaWidgetContents)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.flight_plan_overview.sizePolicy().hasHeightForWidth())
- self.flight_plan_overview.setSizePolicy(sizePolicy)
- self.flight_plan_overview.setMinimumSize(QtCore.QSize(0, 0))
- self.flight_plan_overview.setMaximumSize(QtCore.QSize(16777215, 16777215))
- self.flight_plan_overview.setToolTip("")
- self.flight_plan_overview.setFrameShape(QtWidgets.QFrame.StyledPanel)
- self.flight_plan_overview.setAutoScroll(True)
- self.flight_plan_overview.setTextElideMode(QtCore.Qt.ElideLeft)
- self.flight_plan_overview.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerItem)
- self.flight_plan_overview.setResizeMode(QtWidgets.QListView.Adjust)
- self.flight_plan_overview.setLayoutMode(QtWidgets.QListView.SinglePass)
- self.flight_plan_overview.setObjectName("flight_plan_overview")
- self.gridLayout_13.addWidget(self.flight_plan_overview, 6, 0, 1, 1)
- self.label_37 = QtWidgets.QLabel(self.scrollAreaWidgetContents)
- self.label_37.setMinimumSize(QtCore.QSize(0, 20))
- self.label_37.setMaximumSize(QtCore.QSize(16777215, 20))
- font = QtGui.QFont()
- font.setBold(True)
- font.setWeight(75)
- self.label_37.setFont(font)
- self.label_37.setObjectName("label_37")
- self.gridLayout_13.addWidget(self.label_37, 7, 0, 1, 1)
- self.radio_overview = QtWidgets.QListWidget(self.scrollAreaWidgetContents)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.radio_overview.sizePolicy().hasHeightForWidth())
- self.radio_overview.setSizePolicy(sizePolicy)
- self.radio_overview.setMinimumSize(QtCore.QSize(0, 0))
- self.radio_overview.setMaximumSize(QtCore.QSize(16777215, 16777215))
- self.radio_overview.setToolTip("")
- self.radio_overview.setFrameShape(QtWidgets.QFrame.StyledPanel)
- self.radio_overview.setAutoScroll(True)
- self.radio_overview.setTextElideMode(QtCore.Qt.ElideLeft)
- self.radio_overview.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerItem)
- self.radio_overview.setResizeMode(QtWidgets.QListView.Adjust)
- self.radio_overview.setLayoutMode(QtWidgets.QListView.SinglePass)
- self.radio_overview.setObjectName("radio_overview")
- self.gridLayout_13.addWidget(self.radio_overview, 8, 0, 1, 1)
- self.label_38 = QtWidgets.QLabel(self.scrollAreaWidgetContents)
- self.label_38.setMinimumSize(QtCore.QSize(0, 20))
- self.label_38.setMaximumSize(QtCore.QSize(16777215, 20))
- font = QtGui.QFont()
- font.setBold(True)
- font.setWeight(75)
- self.label_38.setFont(font)
- self.label_38.setObjectName("label_38")
- self.gridLayout_13.addWidget(self.label_38, 9, 0, 1, 1)
- self.telemetry_overview = QtWidgets.QListWidget(self.scrollAreaWidgetContents)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.telemetry_overview.sizePolicy().hasHeightForWidth())
- self.telemetry_overview.setSizePolicy(sizePolicy)
- self.telemetry_overview.setMinimumSize(QtCore.QSize(0, 0))
- self.telemetry_overview.setMaximumSize(QtCore.QSize(16777215, 16777215))
- self.telemetry_overview.setToolTip("")
- self.telemetry_overview.setFrameShape(QtWidgets.QFrame.StyledPanel)
- self.telemetry_overview.setAutoScroll(True)
- self.telemetry_overview.setTextElideMode(QtCore.Qt.ElideLeft)
- self.telemetry_overview.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerItem)
- self.telemetry_overview.setResizeMode(QtWidgets.QListView.Adjust)
- self.telemetry_overview.setLayoutMode(QtWidgets.QListView.SinglePass)
- self.telemetry_overview.setObjectName("telemetry_overview")
- self.gridLayout_13.addWidget(self.telemetry_overview, 10, 0, 1, 1)
- self.scrollArea.setWidget(self.scrollAreaWidgetContents)
- self.gridLayout_8.addWidget(self.scrollArea, 0, 0, 1, 1)
- self.stackedWidget.addWidget(self.area)
- self.area_2 = QtWidgets.QWidget()
- self.area_2.setObjectName("area_2")
- self.gridLayout_12 = QtWidgets.QGridLayout(self.area_2)
- self.gridLayout_12.setObjectName("gridLayout_12")
- self.scrollArea_2 = QtWidgets.QScrollArea(self.area_2)
- self.scrollArea_2.setWidgetResizable(True)
- self.scrollArea_2.setObjectName("scrollArea_2")
- self.scrollAreaWidgetContents_2 = QtWidgets.QWidget()
- self.scrollAreaWidgetContents_2.setGeometry(QtCore.QRect(0, 0, 151, 583))
- self.scrollAreaWidgetContents_2.setObjectName("scrollAreaWidgetContents_2")
- self.gridLayout_15 = QtWidgets.QGridLayout(self.scrollAreaWidgetContents_2)
- self.gridLayout_15.setObjectName("gridLayout_15")
- self.label_18 = QtWidgets.QLabel(self.scrollAreaWidgetContents_2)
- self.label_18.setMinimumSize(QtCore.QSize(0, 30))
- self.label_18.setMaximumSize(QtCore.QSize(16777215, 30))
- self.label_18.setFrameShape(QtWidgets.QFrame.StyledPanel)
- self.label_18.setTextFormat(QtCore.Qt.AutoText)
- self.label_18.setScaledContents(False)
- self.label_18.setObjectName("label_18")
- self.gridLayout_15.addWidget(self.label_18, 0, 0, 1, 1)
- self.label_39 = QtWidgets.QLabel(self.scrollAreaWidgetContents_2)
- self.label_39.setMinimumSize(QtCore.QSize(0, 20))
- self.label_39.setMaximumSize(QtCore.QSize(16777215, 20))
- font = QtGui.QFont()
- font.setBold(True)
- font.setWeight(75)
- self.label_39.setFont(font)
- self.label_39.setObjectName("label_39")
- self.gridLayout_15.addWidget(self.label_39, 1, 0, 1, 1)
- self.airframes_overview_2 = QtWidgets.QListWidget(self.scrollAreaWidgetContents_2)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.airframes_overview_2.sizePolicy().hasHeightForWidth())
- self.airframes_overview_2.setSizePolicy(sizePolicy)
- self.airframes_overview_2.setMinimumSize(QtCore.QSize(0, 0))
- self.airframes_overview_2.setMaximumSize(QtCore.QSize(16777215, 16777215))
- self.airframes_overview_2.setToolTip("")
- self.airframes_overview_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
- self.airframes_overview_2.setTextElideMode(QtCore.Qt.ElideLeft)
- self.airframes_overview_2.setObjectName("airframes_overview_2")
- self.gridLayout_15.addWidget(self.airframes_overview_2, 2, 0, 1, 1)
- self.label_40 = QtWidgets.QLabel(self.scrollAreaWidgetContents_2)
- self.label_40.setMinimumSize(QtCore.QSize(0, 20))
- self.label_40.setMaximumSize(QtCore.QSize(16777215, 20))
- font = QtGui.QFont()
- font.setBold(True)
- font.setWeight(75)
- self.label_40.setFont(font)
- self.label_40.setObjectName("label_40")
- self.gridLayout_15.addWidget(self.label_40, 3, 0, 1, 1)
- self.settings_overview_2 = QtWidgets.QListWidget(self.scrollAreaWidgetContents_2)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.settings_overview_2.sizePolicy().hasHeightForWidth())
- self.settings_overview_2.setSizePolicy(sizePolicy)
- self.settings_overview_2.setMinimumSize(QtCore.QSize(0, 0))
- self.settings_overview_2.setMaximumSize(QtCore.QSize(16777215, 16777215))
- self.settings_overview_2.setToolTip("")
- self.settings_overview_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
- self.settings_overview_2.setTextElideMode(QtCore.Qt.ElideLeft)
- self.settings_overview_2.setObjectName("settings_overview_2")
- self.gridLayout_15.addWidget(self.settings_overview_2, 4, 0, 1, 1)
- self.label_41 = QtWidgets.QLabel(self.scrollAreaWidgetContents_2)
- self.label_41.setMinimumSize(QtCore.QSize(0, 20))
- self.label_41.setMaximumSize(QtCore.QSize(16777215, 20))
- font = QtGui.QFont()
- font.setBold(True)
- font.setWeight(75)
- self.label_41.setFont(font)
- self.label_41.setObjectName("label_41")
- self.gridLayout_15.addWidget(self.label_41, 5, 0, 1, 1)
- self.flight_plan_overview_2 = QtWidgets.QListWidget(self.scrollAreaWidgetContents_2)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.flight_plan_overview_2.sizePolicy().hasHeightForWidth())
- self.flight_plan_overview_2.setSizePolicy(sizePolicy)
- self.flight_plan_overview_2.setMinimumSize(QtCore.QSize(0, 0))
- self.flight_plan_overview_2.setMaximumSize(QtCore.QSize(16777215, 16777215))
- self.flight_plan_overview_2.setToolTip("")
- self.flight_plan_overview_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
- self.flight_plan_overview_2.setTextElideMode(QtCore.Qt.ElideLeft)
- self.flight_plan_overview_2.setObjectName("flight_plan_overview_2")
- self.gridLayout_15.addWidget(self.flight_plan_overview_2, 6, 0, 1, 1)
- self.label_42 = QtWidgets.QLabel(self.scrollAreaWidgetContents_2)
- self.label_42.setMinimumSize(QtCore.QSize(0, 20))
- self.label_42.setMaximumSize(QtCore.QSize(16777215, 20))
- font = QtGui.QFont()
- font.setBold(True)
- font.setWeight(75)
- self.label_42.setFont(font)
- self.label_42.setObjectName("label_42")
- self.gridLayout_15.addWidget(self.label_42, 7, 0, 1, 1)
- self.radio_overview_2 = QtWidgets.QListWidget(self.scrollAreaWidgetContents_2)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.radio_overview_2.sizePolicy().hasHeightForWidth())
- self.radio_overview_2.setSizePolicy(sizePolicy)
- self.radio_overview_2.setMinimumSize(QtCore.QSize(0, 0))
- self.radio_overview_2.setMaximumSize(QtCore.QSize(16777215, 16777215))
- self.radio_overview_2.setToolTip("")
- self.radio_overview_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
- self.radio_overview_2.setTextElideMode(QtCore.Qt.ElideLeft)
- self.radio_overview_2.setObjectName("radio_overview_2")
- self.gridLayout_15.addWidget(self.radio_overview_2, 8, 0, 1, 1)
- self.label_43 = QtWidgets.QLabel(self.scrollAreaWidgetContents_2)
- self.label_43.setMinimumSize(QtCore.QSize(0, 20))
- self.label_43.setMaximumSize(QtCore.QSize(16777215, 20))
- font = QtGui.QFont()
- font.setBold(True)
- font.setWeight(75)
- self.label_43.setFont(font)
- self.label_43.setObjectName("label_43")
- self.gridLayout_15.addWidget(self.label_43, 9, 0, 1, 1)
- self.telemetry_overview_2 = QtWidgets.QListWidget(self.scrollAreaWidgetContents_2)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.telemetry_overview_2.sizePolicy().hasHeightForWidth())
- self.telemetry_overview_2.setSizePolicy(sizePolicy)
- self.telemetry_overview_2.setMinimumSize(QtCore.QSize(0, 0))
- self.telemetry_overview_2.setMaximumSize(QtCore.QSize(16777215, 16777215))
- self.telemetry_overview_2.setToolTip("")
- self.telemetry_overview_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
- self.telemetry_overview_2.setTextElideMode(QtCore.Qt.ElideLeft)
- self.telemetry_overview_2.setObjectName("telemetry_overview_2")
- self.gridLayout_15.addWidget(self.telemetry_overview_2, 10, 0, 1, 1)
- self.scrollArea_2.setWidget(self.scrollAreaWidgetContents_2)
- self.gridLayout_12.addWidget(self.scrollArea_2, 0, 0, 1, 1)
- self.stackedWidget.addWidget(self.area_2)
- self.widget = QtWidgets.QWidget()
- self.widget.setObjectName("widget")
- self.gridLayout_14 = QtWidgets.QGridLayout(self.widget)
- self.gridLayout_14.setObjectName("gridLayout_14")
- self.label_17 = QtWidgets.QLabel(self.widget)
- self.label_17.setFrameShape(QtWidgets.QFrame.StyledPanel)
- self.label_17.setTextFormat(QtCore.Qt.AutoText)
- self.label_17.setScaledContents(False)
- self.label_17.setWordWrap(False)
- self.label_17.setObjectName("label_17")
- self.gridLayout_14.addWidget(self.label_17, 0, 0, 1, 1)
- self.label_45 = QtWidgets.QLabel(self.widget)
- self.label_45.setObjectName("label_45")
- self.gridLayout_14.addWidget(self.label_45, 1, 0, 1, 1)
- self.session_overview_2 = QtWidgets.QComboBox(self.widget)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.session_overview_2.sizePolicy().hasHeightForWidth())
- self.session_overview_2.setSizePolicy(sizePolicy)
- self.session_overview_2.setObjectName("session_overview_2")
- self.gridLayout_14.addWidget(self.session_overview_2, 2, 0, 1, 1)
- self.label_46 = QtWidgets.QLabel(self.widget)
- self.label_46.setObjectName("label_46")
- self.gridLayout_14.addWidget(self.label_46, 3, 0, 1, 1)
- self.programs_overview_2 = QtWidgets.QListWidget(self.widget)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.programs_overview_2.sizePolicy().hasHeightForWidth())
- self.programs_overview_2.setSizePolicy(sizePolicy)
- self.programs_overview_2.setMinimumSize(QtCore.QSize(0, 0))
- self.programs_overview_2.setMaximumSize(QtCore.QSize(16777215, 16777215))
- self.programs_overview_2.setObjectName("programs_overview_2")
- self.gridLayout_14.addWidget(self.programs_overview_2, 4, 0, 1, 1)
- self.quick_kill_2 = QtWidgets.QPushButton(self.widget)
- font = QtGui.QFont()
- font.setBold(True)
- font.setWeight(75)
- self.quick_kill_2.setFont(font)
- self.quick_kill_2.setIcon(icon8)
- self.quick_kill_2.setObjectName("quick_kill_2")
- self.gridLayout_14.addWidget(self.quick_kill_2, 5, 0, 1, 1)
- self.quick_restart_3 = QtWidgets.QPushButton(self.widget)
- font = QtGui.QFont()
- font.setBold(True)
- font.setWeight(75)
- self.quick_restart_3.setFont(font)
- self.quick_restart_3.setIcon(icon7)
- self.quick_restart_3.setObjectName("quick_restart_3")
- self.gridLayout_14.addWidget(self.quick_restart_3, 6, 0, 1, 1)
- spacerItem9 = QtWidgets.QSpacerItem(20, 94, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
- self.gridLayout_14.addItem(spacerItem9, 7, 0, 1, 1)
- self.stackedWidget.addWidget(self.widget)
- self.horizontalLayout.addWidget(self.stackedWidget)
- self.dockWidget.setWidget(self.dockWidgetContents)
- MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea(2), self.dockWidget)
- self.actionNew = QtWidgets.QAction(MainWindow)
- self.actionNew.setEnabled(False)
- self.actionNew.setObjectName("actionNew")
- self.actionOpen = QtWidgets.QAction(MainWindow)
- self.actionOpen.setEnabled(False)
- self.actionOpen.setObjectName("actionOpen")
- self.actionSave = QtWidgets.QAction(MainWindow)
- self.actionSave.setEnabled(False)
- self.actionSave.setObjectName("actionSave")
- self.actionRemove = QtWidgets.QAction(MainWindow)
- self.actionRemove.setEnabled(False)
- self.actionRemove.setObjectName("actionRemove")
- self.actionSetManager = QtWidgets.QAction(MainWindow)
- self.actionSetManager.setObjectName("actionSetManager")
- self.actionNew_2 = QtWidgets.QAction(MainWindow)
- self.actionNew_2.setEnabled(False)
- self.actionNew_2.setObjectName("actionNew_2")
- self.actionOpen_2 = QtWidgets.QAction(MainWindow)
- self.actionOpen_2.setEnabled(False)
- self.actionOpen_2.setObjectName("actionOpen_2")
- self.actionSave_2 = QtWidgets.QAction(MainWindow)
- self.actionSave_2.setObjectName("actionSave_2")
- self.actionRemove_2 = QtWidgets.QAction(MainWindow)
- self.actionRemove_2.setEnabled(False)
- self.actionRemove_2.setObjectName("actionRemove_2")
- self.actionMode = QtWidgets.QAction(MainWindow)
- self.actionMode.setEnabled(False)
- self.actionMode.setObjectName("actionMode")
- self.actionStandard = QtWidgets.QAction(MainWindow)
- self.actionStandard.setCheckable(False)
- self.actionStandard.setChecked(False)
- self.actionStandard.setEnabled(False)
- self.actionStandard.setIconVisibleInMenu(False)
- self.actionStandard.setObjectName("actionStandard")
- self.actionDeveloper = QtWidgets.QAction(MainWindow)
- self.actionDeveloper.setEnabled(False)
- self.actionDeveloper.setObjectName("actionDeveloper")
- self.actionSettings = QtWidgets.QAction(MainWindow)
- self.actionSettings.setEnabled(False)
- self.actionSettings.setObjectName("actionSettings")
- self.actionQuit_Paparazzi_UAV = QtWidgets.QAction(MainWindow)
- self.actionQuit_Paparazzi_UAV.setObjectName("actionQuit_Paparazzi_UAV")
- self.actionFull_screen = QtWidgets.QAction(MainWindow)
- self.actionFull_screen.setObjectName("actionFull_screen")
- self.actionTutorial = QtWidgets.QAction(MainWindow)
- self.actionTutorial.setEnabled(True)
- self.actionTutorial.setObjectName("actionTutorial")
- self.actionAbout_Paparazzi_UAV = QtWidgets.QAction(MainWindow)
- self.actionAbout_Paparazzi_UAV.setEnabled(True)
- self.actionAbout_Paparazzi_UAV.setObjectName("actionAbout_Paparazzi_UAV")
- self.actionNew_empty_session = QtWidgets.QAction(MainWindow)
- self.actionNew_empty_session.setEnabled(False)
- self.actionNew_empty_session.setObjectName("actionNew_empty_session")
- self.actionOpen_3 = QtWidgets.QAction(MainWindow)
- self.actionOpen_3.setEnabled(False)
- self.actionOpen_3.setObjectName("actionOpen_3")
- self.actionSave_3 = QtWidgets.QAction(MainWindow)
- self.actionSave_3.setObjectName("actionSave_3")
- self.actionRemove_3 = QtWidgets.QAction(MainWindow)
- self.actionRemove_3.setEnabled(False)
- self.actionRemove_3.setObjectName("actionRemove_3")
- self.actionUndo = QtWidgets.QAction(MainWindow)
- self.actionUndo.setEnabled(False)
- self.actionUndo.setObjectName("actionUndo")
- self.actionRedo = QtWidgets.QAction(MainWindow)
- self.actionRedo.setEnabled(False)
- self.actionRedo.setObjectName("actionRedo")
- self.actionSimulator = QtWidgets.QAction(MainWindow)
- self.actionSimulator.setObjectName("actionSimulator")
- self.actionGCS = QtWidgets.QAction(MainWindow)
- self.actionGCS.setObjectName("actionGCS")
- self.actionMeteo = QtWidgets.QAction(MainWindow)
- self.actionMeteo.setObjectName("actionMeteo")
- self.actionServer = QtWidgets.QAction(MainWindow)
- self.actionServer.setObjectName("actionServer")
- self.actionMessages = QtWidgets.QAction(MainWindow)
- self.actionMessages.setObjectName("actionMessages")
- self.action = QtWidgets.QAction(MainWindow)
- self.action.setObjectName("action")
- self.actionWILL_BE_AVAILABLE_LATER = QtWidgets.QAction(MainWindow)
- self.actionWILL_BE_AVAILABLE_LATER.setEnabled(False)
- self.actionWILL_BE_AVAILABLE_LATER.setObjectName("actionWILL_BE_AVAILABLE_LATER")
- self.actionSet_default_cache_at_current_state = QtWidgets.QAction(MainWindow)
- self.actionSet_default_cache_at_current_state.setObjectName("actionSet_default_cache_at_current_state")
- self.actionRestore_default_state = QtWidgets.QAction(MainWindow)
- self.actionRestore_default_state.setObjectName("actionRestore_default_state")
- self.actionHide_overviews = QtWidgets.QAction(MainWindow)
- self.actionHide_overviews.setObjectName("actionHide_overviews")
- self.menuSet.addAction(self.actionSetManager)
- self.menuConfiguration.addAction(self.actionNew_2)
- self.menuConfiguration.addAction(self.actionOpen_2)
- self.menuConfiguration.addAction(self.actionSave_2)
- self.menuConfiguration.addAction(self.actionRemove_2)
- self.menuMenu.addAction(self.actionMode)
- self.menuMenu.addAction(self.actionStandard)
- self.menuMenu.addAction(self.actionDeveloper)
- self.menuMenu.addSeparator()
- self.menuMenu.addAction(self.actionSettings)
- self.menuMenu.addSeparator()
- self.menuMenu.addAction(self.actionQuit_Paparazzi_UAV)
- self.menuView.addAction(self.actionFull_screen)
- self.menuView.addAction(self.actionHide_overviews)
- self.menuHelp.addAction(self.actionTutorial)
- self.menuHelp.addAction(self.actionAbout_Paparazzi_UAV)
- self.menuSession.addAction(self.actionNew_empty_session)
- self.menuSession.addAction(self.actionOpen_3)
- self.menuSession.addAction(self.actionSave_3)
- self.menuSession.addAction(self.actionRemove_3)
- self.menubar.addAction(self.menuMenu.menuAction())
- self.menubar.addAction(self.menuSet.menuAction())
- self.menubar.addAction(self.menuConfiguration.menuAction())
- self.menubar.addAction(self.menuSession.menuAction())
- self.menubar.addAction(self.menuView.menuAction())
- self.menubar.addAction(self.menuHelp.menuAction())
-
- self.retranslateUi(MainWindow)
- self.main_tab.setCurrentIndex(2)
- self.stackedWidget.setCurrentIndex(0)
- self.main_tab.currentChanged['int'].connect(self.stackedWidget.setCurrentIndex)
- QtCore.QMetaObject.connectSlotsByName(MainWindow)
-
- def retranslateUi(self, MainWindow):
- _translate = QtCore.QCoreApplication.translate
- MainWindow.setWindowTitle(_translate("MainWindow", "Paparazzi Center"))
- self.label.setText(_translate("MainWindow", "Set :"))
- self.current_configuration.setToolTip(_translate("MainWindow", "Current configuration"))
- self.current_color.setToolTip(_translate("MainWindow", "Current configuration color"))
- self.label_2.setText(_translate("MainWindow", "Configuration :"))
- self.label_3.setText(_translate("MainWindow", "ID :"))
- self.current_id.setToolTip(_translate("MainWindow", "Current configuration ID"))
- self.label_27.setText(_translate("MainWindow", "Color :"))
- self.current_set.setToolTip(_translate("MainWindow", "Current set of configurations"))
- self.search_item.setToolTip(_translate("MainWindow", "Search an XML"))
- self.search_item.setText(_translate("MainWindow", "COMING SOON"))
- self.all_items_tree.setToolTip(_translate("MainWindow", "Select an XML file"))
- self.all_items_tree.headerItem().setText(0, _translate("MainWindow", "COMING SOON"))
- self.quick_target.setToolTip(_translate("MainWindow", "Select a target to build quickly"))
- self.label_19.setText(_translate("MainWindow", "Quick build :"))
- self.quick_build.setToolTip(_translate("MainWindow", "Clean & build quickly the current configuration"))
- self.quick_build.setText(_translate("MainWindow", "Clean && build"))
- self.remove_item.setToolTip(_translate("MainWindow", "Remove the XML file selected from the current configuration"))
- self.edit.setToolTip(_translate("MainWindow", "Edit the selected XML file"))
- self.add_item.setToolTip(_translate("MainWindow", "Add the selected XML file to the current configuration"))
- self.scrollArea_3.setToolTip(_translate("MainWindow", "Current configuration"))
- self.current_flight_plan.setToolTip(_translate("MainWindow", "Current flight plan (click to edit by GUI)"))
- self.current_airframes.setToolTip(_translate("MainWindow", "Current airframes"))
- self.current_telemetry.setToolTip(_translate("MainWindow", "Current telemetry"))
- self.current_flight_plan_label.setText(_translate("MainWindow", "Flight plan :"))
- self.current_airframes_label.setText(_translate("MainWindow", "Airframes :"))
- self.current_settings.setToolTip(_translate("MainWindow", "Current settings"))
- self.current_radio_label.setText(_translate("MainWindow", "Radio :"))
- self.select_kml.setToolTip(_translate("MainWindow", "Change the flight plan by KML to XML tool"))
- self.select_kml.setText(_translate("MainWindow", "Select KML (Maps)"))
- self.current_radio.setToolTip(_translate("MainWindow", "Current radio"))
- self.open_gui.setToolTip(_translate("MainWindow", "Change the flight plan by GCS"))
- self.open_gui.setText(_translate("MainWindow", "Open a GUI (GCS)"))
- self.current_settings_label.setText(_translate("MainWindow", "Settings :"))
- self.current_telemetry_label.setText(_translate("MainWindow", "Telemetry :"))
- self.main_tab.setTabText(self.main_tab.indexOf(self.equipment_tab), _translate("MainWindow", "Equipment"))
- self.main_tab.setTabToolTip(self.main_tab.indexOf(self.equipment_tab), _translate("MainWindow", "Tab to manage the equipments of the current configuration"))
- self.build_result.setToolTip(_translate("MainWindow", "Clean & build result"))
- self.info_nb.setToolTip(_translate("MainWindow", "Info found during build"))
- self.flash_result.setToolTip(_translate("MainWindow", "Flash result"))
- self.label_25.setText(_translate("MainWindow", "Flash"))
- self.label_10.setText(_translate("MainWindow", "Errors :"))
- self.label_26.setText(_translate("MainWindow", "Target :"))
- self.label_11.setText(_translate("MainWindow", "Warnings :"))
- self.label_13.setText(_translate("MainWindow", "Result :"))
- self.warnings_nb.setToolTip(_translate("MainWindow", "Warnings found during build"))
- self.label_23.setText(_translate("MainWindow", "Build"))
- self.label_12.setText(_translate("MainWindow", "Device :"))
- self.label_14.setText(_translate("MainWindow", "Info :"))
- self.target.setToolTip(_translate("MainWindow", "Current target"))
- self.clean.setToolTip(_translate("MainWindow", "Clean the current configuration"))
- self.clean.setText(_translate("MainWindow", "Clean"))
- self.errors_nb.setToolTip(_translate("MainWindow", "Errors found during build"))
- self.device.setToolTip(_translate("MainWindow", "Current device"))
- self.build.setToolTip(_translate("MainWindow", "Build the current configuration"))
- self.build.setText(_translate("MainWindow", "Build"))
- self.show_console.setToolTip(_translate("MainWindow", "Switch to the console tab"))
- self.show_console.setText(_translate("MainWindow", "Show console"))
- self.upload.setToolTip(_translate("MainWindow", "Flash the current device"))
- self.upload.setText(_translate("MainWindow", "Upload"))
- self.label_9.setText(_translate("MainWindow", "Result :"))
- self.main_tab.setTabText(self.main_tab.indexOf(self.build_flash_tab), _translate("MainWindow", "Build / Flash"))
- self.main_tab.setTabToolTip(self.main_tab.indexOf(self.build_flash_tab), _translate("MainWindow", "Tab to build and flash the current configuration"))
- self.label_7.setText(_translate("MainWindow", "Options :"))
- self.programs.setToolTip(_translate("MainWindow", "Programs running (green) and stopped (red)"))
- self.label_8.setText(_translate("MainWindow", "Programs :"))
- self.start_all_button.setToolTip(_translate("MainWindow", "Kill & restart all programs"))
- self.start_all_button.setText(_translate("MainWindow", "Start all"))
- self.play_stop_program.setToolTip(_translate("MainWindow", "Start / stop the selected program"))
- self.play_stop_program.setText(_translate("MainWindow", "Start"))
- self.options.setToolTip(_translate("MainWindow", "Options of the selected program"))
- self.remove_program.setToolTip(_translate("MainWindow", "Remove a programs from the session"))
- self.session.setToolTip(_translate("MainWindow", "Current session"))
- self.kill_all_button.setToolTip(_translate("MainWindow", "Kill all running programs"))
- self.kill_all_button.setText(_translate("MainWindow", "Kill all"))
- self.label_4.setText(_translate("MainWindow", "Session :"))
- self.add_program.setToolTip(_translate("MainWindow", "Add a programs to the session"))
- self.remove_option.setToolTip(_translate("MainWindow", "Remove the selected option"))
- self.add_option.setToolTip(_translate("MainWindow", "Add an option to the selected program"))
- self.main_tab.setTabText(self.main_tab.indexOf(self.sessions_tab), _translate("MainWindow", "Run session"))
- self.main_tab.setTabToolTip(self.main_tab.indexOf(self.sessions_tab), _translate("MainWindow", "Tab to launch and customize the current session"))
- self.console.setToolTip(_translate("MainWindow", "Console to display the logs"))
- self.console.setHtml(_translate("MainWindow", "\n"
-" \n"
-"
"))
- self.label_24.setText(_translate("MainWindow", "Logs"))
- self.important.setText(_translate("MainWindow", "Important only"))
- self.custom.setText(_translate("MainWindow", "Customized"))
- self.all.setText(_translate("MainWindow", "All"))
- self.clean_console.setToolTip(_translate("MainWindow", "Clean the console (all logs will be deleted !)"))
- self.clean_console.setText(_translate("MainWindow", "Clean console"))
- self.display_info.setText(_translate("MainWindow", "Info"))
- self.display_warnings.setText(_translate("MainWindow", "Warnings"))
- self.display_errors.setText(_translate("MainWindow", "Errors"))
- self.display_default.setText(_translate("MainWindow", "Default (no flag)"))
- self.main_tab.setTabText(self.main_tab.indexOf(self.console_tab), _translate("MainWindow", "Console"))
- self.main_tab.setTabToolTip(self.main_tab.indexOf(self.console_tab), _translate("MainWindow", "Tab where informations are displayed in a real customizable console"))
- self.label_20.setText(_translate("MainWindow", "HOME = "))
- self.open_home_terminal.setToolTip(_translate("MainWindow", "Home directory of Paparazzi UAV (click to open a terminal here)"))
- self.run_version.setToolTip(_translate("MainWindow", "Current version of Paparazzi UAV"))
- self.label_29.setText(_translate("MainWindow", "BUILD_VERSION = "))
- self.build_version.setToolTip(_translate("MainWindow", "Current version of Paparazzi UAV"))
- self.label_22.setText(_translate("MainWindow", "RUN_VERSION = "))
- self.switch_mode.setToolTip(_translate("MainWindow", "Current mode (click to switch the mode)"))
- self.label_21.setText(_translate("MainWindow", "MODE = "))
- self.menuSet.setTitle(_translate("MainWindow", "Set"))
- self.menuConfiguration.setTitle(_translate("MainWindow", "Configuration"))
- self.menuMenu.setTitle(_translate("MainWindow", "Menu"))
- self.menuView.setTitle(_translate("MainWindow", "View"))
- self.menuHelp.setTitle(_translate("MainWindow", "Help"))
- self.menuSession.setTitle(_translate("MainWindow", "Session"))
- self.quick_restart.setToolTip(_translate("MainWindow", "Kill & restart all programs"))
- self.quick_restart.setText(_translate("MainWindow", "Start all"))
- self.label_33.setText(_translate("MainWindow", "Processus :"))
- self.programs_overview_1.setToolTip(_translate("MainWindow", "Programs running (green) and stopped (red)"))
- self.label_32.setText(_translate("MainWindow", "Session :"))
- self.session_overview_1.setToolTip(_translate("MainWindow", "Current session"))
- self.label_6.setText(_translate("MainWindow", "Session overview"))
- self.quick_kill.setToolTip(_translate("MainWindow", "Kill all running programs"))
- self.quick_kill.setText(_translate("MainWindow", "Kill all"))
- self.label_5.setText(_translate("MainWindow", "Settings overview"))
- self.label_35.setText(_translate("MainWindow", "Airframes"))
- self.label_34.setText(_translate("MainWindow", "Settings"))
- self.label_36.setText(_translate("MainWindow", "Flight plan"))
- self.label_37.setText(_translate("MainWindow", "Radio"))
- self.label_38.setText(_translate("MainWindow", "Telemetry"))
- self.label_18.setText(_translate("MainWindow", "Settings overview"))
- self.label_39.setText(_translate("MainWindow", "Airframes"))
- self.label_40.setText(_translate("MainWindow", "Settings"))
- self.label_41.setText(_translate("MainWindow", "Flight plan"))
- self.label_42.setText(_translate("MainWindow", "Radio"))
- self.label_43.setText(_translate("MainWindow", "Telemetry"))
- self.label_17.setText(_translate("MainWindow", "Session overview"))
- self.label_45.setText(_translate("MainWindow", "Session :"))
- self.session_overview_2.setToolTip(_translate("MainWindow", "Current session"))
- self.label_46.setText(_translate("MainWindow", "Processus :"))
- self.programs_overview_2.setToolTip(_translate("MainWindow", "Programs running (green) and stopped (red)"))
- self.quick_kill_2.setToolTip(_translate("MainWindow", "Kill all running programs"))
- self.quick_kill_2.setText(_translate("MainWindow", "Kill all"))
- self.quick_restart_3.setToolTip(_translate("MainWindow", "Kill & restart all programs"))
- self.quick_restart_3.setText(_translate("MainWindow", "Start all"))
- self.actionNew.setText(_translate("MainWindow", "New empty set"))
- self.actionNew.setShortcut(_translate("MainWindow", "Ctrl+Shift+N"))
- self.actionOpen.setText(_translate("MainWindow", "Save set as..."))
- self.actionSave.setText(_translate("MainWindow", "Save"))
- self.actionRemove.setText(_translate("MainWindow", "Remove"))
- self.actionSetManager.setText(_translate("MainWindow", "Set manager... (COMING SOON)"))
- self.actionSetManager.setShortcut(_translate("MainWindow", "Ctrl+Shift+M"))
- self.actionNew_2.setText(_translate("MainWindow", "New empty configuration"))
- self.actionNew_2.setShortcut(_translate("MainWindow", "Ctrl+N"))
- self.actionOpen_2.setText(_translate("MainWindow", "Save configuration as..."))
- self.actionOpen_2.setShortcut(_translate("MainWindow", "Ctrl+S"))
- self.actionSave_2.setText(_translate("MainWindow", "Save"))
- self.actionRemove_2.setText(_translate("MainWindow", "Remove"))
- self.actionMode.setText(_translate("MainWindow", "Active mode :"))
- self.actionStandard.setText(_translate("MainWindow", "Standard"))
- self.actionStandard.setToolTip(_translate("MainWindow", "Switch to standard user mode"))
- self.actionDeveloper.setText(_translate("MainWindow", "Developer"))
- self.actionDeveloper.setToolTip(_translate("MainWindow", "Switch to developer mode"))
- self.actionSettings.setText(_translate("MainWindow", "Settings..."))
- self.actionSettings.setToolTip(_translate("MainWindow", "Change global settings of the Paparazzi Center"))
- self.actionQuit_Paparazzi_UAV.setText(_translate("MainWindow", "Quit Paparazzi UAV"))
- self.actionQuit_Paparazzi_UAV.setShortcut(_translate("MainWindow", "Ctrl+Q"))
- self.actionFull_screen.setText(_translate("MainWindow", "Full screen"))
- self.actionFull_screen.setShortcut(_translate("MainWindow", "F11"))
- self.actionTutorial.setText(_translate("MainWindow", "Tutorials..."))
- self.actionTutorial.setShortcut(_translate("MainWindow", "Ctrl+H"))
- self.actionAbout_Paparazzi_UAV.setText(_translate("MainWindow", "Credits..."))
- self.actionNew_empty_session.setText(_translate("MainWindow", "New empty session"))
- self.actionNew_empty_session.setShortcut(_translate("MainWindow", "Ctrl+Shift+N, Ctrl+Shift+N"))
- self.actionOpen_3.setText(_translate("MainWindow", "Save session as..."))
- self.actionOpen_3.setShortcut(_translate("MainWindow", "Ctrl+Shift+S"))
- self.actionSave_3.setText(_translate("MainWindow", "Save"))
- self.actionRemove_3.setText(_translate("MainWindow", "Remove"))
- self.actionUndo.setText(_translate("MainWindow", "Undo"))
- self.actionUndo.setToolTip(_translate("MainWindow", "Undo the last action"))
- self.actionUndo.setShortcut(_translate("MainWindow", "Ctrl+Z"))
- self.actionRedo.setText(_translate("MainWindow", "Redo"))
- self.actionRedo.setToolTip(_translate("MainWindow", "Redo the last action"))
- self.actionRedo.setShortcut(_translate("MainWindow", "Ctrl+Y"))
- self.actionSimulator.setText(_translate("MainWindow", "Simulator"))
- self.actionGCS.setText(_translate("MainWindow", "GCS"))
- self.actionMeteo.setText(_translate("MainWindow", "Meteo"))
- self.actionServer.setText(_translate("MainWindow", "Server"))
- self.actionMessages.setText(_translate("MainWindow", "Messages"))
- self.action.setText(_translate("MainWindow", "..."))
- self.actionWILL_BE_AVAILABLE_LATER.setText(_translate("MainWindow", "WILL BE AVAILABLE LATER :"))
- self.actionSet_default_cache_at_current_state.setText(_translate("MainWindow", "Set default app state to current"))
- self.actionRestore_default_state.setText(_translate("MainWindow", "Restore default app state"))
- self.actionHide_overviews.setText(_translate("MainWindow", "Hide overviews"))
-
-from tools_menu import ToolsMenu
diff --git a/sw/supervision/python/ui/main_window.ui b/sw/supervision/python/ui/main_window.ui
deleted file mode 100644
index 066dfdc126..0000000000
--- a/sw/supervision/python/ui/main_window.ui
+++ /dev/null
@@ -1,3868 +0,0 @@
-
-
- MainWindow
-
-
-
- 0
- 0
- 833
- 568
-
-
-
-
- 0
- 0
-
-
-
-
- 16777215
- 16777215
-
-
-
- Paparazzi Center
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 40
-
-
-
-
- 16777215
- 40
-
-
-
- false
-
-
-
-
-
- QFrame::StyledPanel
-
-
- QFrame::Plain
-
-
- -
-
-
-
-
-
- Set :
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 20
-
-
-
- Current configuration
-
-
-
- -
-
-
- true
-
-
-
- 0
- 0
-
-
-
-
- 30
- 0
-
-
-
-
- 40
- 16777215
-
-
-
- false
-
-
- Qt::NoFocus
-
-
- Current configuration color
-
-
- true
-
-
-
-
-
- QFrame::Box
-
-
- 1
-
-
-
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
-
-
-
- Configuration :
-
-
-
- -
-
-
-
-
-
- ID :
-
-
-
- -
-
-
- true
-
-
-
- 0
- 0
-
-
-
-
- 30
- 0
-
-
-
-
- 40
- 16777215
-
-
-
-
- 75
- true
-
-
-
- false
-
-
- Qt::NoFocus
-
-
- Current configuration ID
-
-
- true
-
-
-
-
-
- QFrame::Box
-
-
- 1
-
-
-
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
-
-
-
- Color :
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 20
-
-
-
- Current set of configurations
-
-
-
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 16777215
- 16777215
-
-
-
-
-
-
- Qt::LeftToRight
-
-
- QTabWidget::North
-
-
- QTabWidget::Triangular
-
-
- 2
-
-
- Qt::ElideNone
-
-
- true
-
-
- false
-
-
- false
-
-
-
- Equipment
-
-
- Tab to manage the equipments of the current configuration
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
- -
-
-
- false
-
-
-
- 0
- 0
-
-
-
-
- 16777215
- 16777215
-
-
-
- Search an XML
-
-
- COMING SOON
-
-
-
- -
-
-
- false
-
-
- Select an XML file
-
-
-
- COMING SOON
-
-
-
-
- -
-
-
-
- 0
- 40
-
-
-
-
- 16777215
- 40
-
-
-
- QFrame::NoFrame
-
-
- QFrame::Raised
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 20
-
-
-
-
- 16777215
- 20
-
-
-
- Select a target to build quickly
-
-
-
- -
-
-
-
- 16777215
- 20
-
-
-
- Quick build :
-
-
-
- -
-
-
-
- 0
- 20
-
-
-
-
- 16777215
- 20
-
-
-
- Clean & build quickly the current configuration
-
-
- Qt::LeftToRight
-
-
- Clean && build
-
-
-
- icons/system-run.png icons/system-run.png
-
-
-
-
-
-
- -
-
-
- true
-
-
-
- 0
- 0
-
-
-
-
- 50
- 50
-
-
-
-
- 50
- 50
-
-
-
- Remove the XML file selected from the current configuration
-
-
-
-
-
-
- icons/list-remove.svg icons/list-remove.svg
-
-
- false
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
- -
-
-
-
- 50
- 50
-
-
-
-
- 50
- 50
-
-
-
- Edit the selected XML file
-
-
-
-
-
-
- icons/accessories-text-editor.svg icons/accessories-text-editor.svg
-
-
-
- 24
- 24
-
-
-
-
- -
-
-
- true
-
-
-
- 0
- 0
-
-
-
-
- 50
- 50
-
-
-
-
- 50
- 50
-
-
-
- Add the selected XML file to the current configuration
-
-
-
-
-
-
- icons/list-add.svg icons/list-add.svg
-
-
- false
-
-
-
- -
-
-
- Current configuration
-
-
- true
-
-
-
-
- 0
- 0
- 162
- 607
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 0
-
-
-
-
- 16777215
- 16777215
-
-
-
- Current flight plan (click to edit by GUI)
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 0
-
-
-
-
- 16777215
- 16777215
-
-
-
- Current airframes
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 0
-
-
-
-
- 16777215
- 16777215
-
-
-
- Current telemetry
-
-
-
- -
-
-
-
- 0
- 20
-
-
-
-
- 16777215
- 20
-
-
-
- Flight plan :
-
-
-
- -
-
-
-
- 0
- 20
-
-
-
-
- 16777215
- 20
-
-
-
- Airframes :
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 0
-
-
-
-
- 16777215
- 16777215
-
-
-
- Current settings
-
-
-
- -
-
-
-
- 0
- 20
-
-
-
-
- 16777215
- 20
-
-
-
- Radio :
-
-
-
- -
-
-
- false
-
-
-
- 0
- 24
-
-
-
- Change the flight plan by KML to XML tool
-
-
- Select KML (Maps)
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 0
-
-
-
-
- 16777215
- 16777215
-
-
-
- Current radio
-
-
-
- -
-
-
- false
-
-
-
- 0
- 24
-
-
-
- Change the flight plan by GCS
-
-
- Open a GUI (GCS)
-
-
-
- -
-
-
-
- 0
- 20
-
-
-
-
- 16777215
- 20
-
-
-
- Settings :
-
-
-
- -
-
-
-
- 0
- 20
-
-
-
-
- 16777215
- 20
-
-
-
- Telemetry :
-
-
-
-
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 0
-
-
-
-
- 16777215
- 16777215
-
-
-
-
-
-
- QFrame::NoFrame
-
-
-
-
-
- icons/search_field.png
-
-
-
-
-
-
-
- Build / Flash
-
-
- Tab to build and flash the current configuration
-
-
- -
-
-
-
- 20
- 20
-
-
-
-
- 20
- 20
-
-
-
-
-
-
- icons/gtk-info.svg
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 20
-
-
-
-
- 16777215
- 20
-
-
-
- Clean & build result
-
-
- QFrame::StyledPanel
-
-
-
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 30
- 20
-
-
-
-
- 30
- 20
-
-
-
-
- 75
- true
-
-
-
- Info found during build
-
-
- border:2px solid #00ff00;
-
-
- QFrame::StyledPanel
-
-
-
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 30
- 0
-
-
-
-
- 16777215
- 16777215
-
-
-
-
-
-
- QFrame::NoFrame
-
-
-
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 20
-
-
-
-
- 16777215
- 20
-
-
-
- Flash result
-
-
- QFrame::StyledPanel
-
-
-
-
-
-
- -
-
-
-
- 14
- 75
- true
-
-
-
- Flash
-
-
-
- -
-
-
- Errors :
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 60
- 16777215
-
-
-
- Target :
-
-
-
- -
-
-
- Warnings :
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 60
- 16777215
-
-
-
- Result :
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 30
- 20
-
-
-
-
- 30
- 20
-
-
-
-
- 75
- true
-
-
-
- Warnings found during build
-
-
- border:2px solid #ffaa00;
-
-
- QFrame::StyledPanel
-
-
-
-
-
-
- -
-
-
-
- 14
- 75
- true
-
-
-
- Build
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 60
- 16777215
-
-
-
- Device :
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
- Info :
-
-
-
- -
-
-
-
- 20
- 20
-
-
-
-
- 20
- 20
-
-
-
-
-
-
- icons/dialog-error.svg
-
-
-
- -
-
-
-
- 0
- 30
-
-
-
-
- 16777215
- 30
-
-
-
- Current target
-
-
-
- -
-
-
-
- 20
- 20
-
-
-
-
- 20
- 20
-
-
-
-
-
-
- icons/dialog-warning.png
-
-
-
- -
-
-
-
- 130
- 30
-
-
-
-
- 130
- 30
-
-
-
- Clean the current configuration
-
-
- Qt::LeftToRight
-
-
- Clean
-
-
-
- icons/edit-clear.svg icons/edit-clear.svg
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 30
- 20
-
-
-
-
- 30
- 20
-
-
-
-
- 75
- true
-
-
-
- Errors found during build
-
-
- false
-
-
- border:2px solid #ff0000;
-
-
- QFrame::StyledPanel
-
-
-
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 30
-
-
-
-
- 16777215
- 30
-
-
-
- Current device
-
-
-
- -
-
-
-
- 130
- 30
-
-
-
-
- 130
- 30
-
-
-
- Build the current configuration
-
-
- Qt::LeftToRight
-
-
- Build
-
-
-
- icons/system-run.png icons/system-run.png
-
-
-
- -
-
-
-
- 0
- 30
-
-
-
-
- 16777215
- 20
-
-
-
- Switch to the console tab
-
-
- Qt::LeftToRight
-
-
- Show console
-
-
-
- icons/utilities-terminal.svg icons/utilities-terminal.svg
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 0
-
-
-
-
- 30
- 16777215
-
-
-
-
-
-
- QFrame::NoFrame
-
-
-
-
-
-
- -
-
-
- true
-
-
-
- 130
- 30
-
-
-
-
- 130
- 30
-
-
-
- Flash the current device
-
-
- Upload
-
-
-
- icons/go-up.svg icons/go-up.svg
-
-
-
- -
-
-
-
- 0
- 30
-
-
-
-
- 60
- 16777215
-
-
-
- Result :
-
-
-
-
-
-
-
- Run session
-
-
- Tab to launch and customize the current session
-
-
- -
-
-
- Options :
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 16777215
- 16777215
-
-
-
- Programs running (green) and stopped (red)
-
-
- Qt::LeftToRight
-
-
- QAbstractItemView::SelectRows
-
-
-
- 10
- 10
-
-
-
-
- -
-
-
- Programs :
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 50
-
-
-
-
- 16777215
- 50
-
-
-
-
- 75
- false
- true
- false
- false
- true
-
-
-
- Kill & restart all programs
-
-
- Start all
-
-
-
- icons/media-playback-start.svg icons/media-playback-start.svg
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 50
-
-
-
-
- 16777215
- 50
-
-
-
- Start / stop the selected program
-
-
- Start
-
-
-
- icons/media-playback-start.svg icons/media-playback-start.svg
-
-
- false
-
-
-
- -
-
-
-
- 16777215
- 16777215
-
-
-
- Options of the selected program
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 30
- 30
-
-
-
-
- 30
- 30
-
-
-
- Remove a programs from the session
-
-
-
-
-
-
- icons/list-remove.svg icons/list-remove.svg
-
-
- false
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Current session
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 50
-
-
-
-
- 16777215
- 50
-
-
-
-
- 75
- false
- true
- false
- false
- true
-
-
-
- Kill all running programs
-
-
- Qt::LeftToRight
-
-
- Kill all
-
-
-
- icons/process-stop.svg icons/process-stop.svg
-
-
-
- -
-
-
- Session :
-
-
-
- -
-
-
- false
-
-
-
- 0
- 0
-
-
-
-
- 30
- 30
-
-
-
-
- 30
- 30
-
-
-
- Add a programs to the session
-
-
-
-
-
-
- icons/list-add.svg icons/list-add.svg
-
-
- false
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 30
- 30
-
-
-
-
- 30
- 30
-
-
-
- Remove the selected option
-
-
-
-
-
-
- icons/list-remove.svg icons/list-remove.svg
-
-
- false
-
-
-
- -
-
-
- true
-
-
-
- 0
- 0
-
-
-
-
- 30
- 30
-
-
-
-
- 30
- 30
-
-
-
- Add an option to the selected program
-
-
-
-
-
-
- icons/list-add.svg icons/list-add.svg
-
-
- false
-
-
-
- -
-
-
-
-
-
-
- Console
-
-
- Tab where informations are displayed in a real customizable console
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- -
-
-
- true
-
-
-
- Ubuntu
-
-
-
- Console to display the logs
-
-
- Qt::LeftToRight
-
-
- Qt::ScrollBarAsNeeded
-
-
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
-<html><head><meta name="qrichtext" content="1" /><style type="text/css">
-p, li { white-space: pre-wrap; }
-</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;">
-<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html>
-
-
- Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse
-
-
-
- -
-
-
-
- 14
- 75
- true
-
-
-
- Logs
-
-
-
- -
-
-
-
-
-
- Important only
-
-
- false
-
-
-
- -
-
-
-
-
-
- Customized
-
-
- true
-
-
-
- -
-
-
-
-
-
- All
-
-
- false
-
-
-
- -
-
-
- Clean the console (all logs will be deleted !)
-
-
- Clean console
-
-
-
- icons/edit-clear.svg icons/edit-clear.svg
-
-
-
- -
-
- -
-
-
-
- 0
- 0
-
-
-
- Info
-
-
-
- icons/gtk-info.svg icons/gtk-info.svg
-
-
-
-
-
- -
-
- -
-
-
-
- 0
- 0
-
-
-
- Warnings
-
-
-
- icons/dialog-warning.png icons/dialog-warning.png
-
-
- false
-
-
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 261
-
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- -
-
- -
-
-
-
- 0
- 0
-
-
-
- Errors
-
-
-
- icons/dialog-error.svg icons/dialog-error.svg
-
-
- false
-
-
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- -
-
- -
-
-
-
- 0
- 0
-
-
-
- Default (no flag)
-
-
-
-
-
-
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 16777215
- 20
-
-
-
- QFrame::NoFrame
-
-
- QFrame::Raised
-
-
- 0
-
-
-
- 0
-
-
- 0
-
-
- 0
-
- -
-
-
- Qt::Vertical
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 20
-
-
-
-
- 16777215
- 20
-
-
-
- HOME =
-
-
-
- -
-
-
-
- 0
- 20
-
-
-
-
- 16777215
- 20
-
-
-
- Home directory of Paparazzi UAV (click to open a terminal here)
-
-
-
-
-
- false
-
-
- false
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 20
-
-
-
-
- 16777215
- 20
-
-
-
- Current version of Paparazzi UAV
-
-
- QFrame::NoFrame
-
-
-
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 20
-
-
-
-
- 16777215
- 20
-
-
-
- BUILD_VERSION =
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 20
-
-
-
-
- 16777215
- 20
-
-
-
- Current version of Paparazzi UAV
-
-
- QFrame::NoFrame
-
-
-
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 20
-
-
-
-
- 16777215
- 20
-
-
-
- RUN_VERSION =
-
-
-
- -
-
-
- false
-
-
-
- 0
- 20
-
-
-
-
- 16777215
- 20
-
-
-
- Current mode (click to switch the mode)
-
-
-
-
-
- false
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 20
-
-
-
-
- 16777215
- 20
-
-
-
- MODE =
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
-
-
-
-
-
-
-
-
- 2
-
-
-
- -
-
-
- true
-
-
-
- 0
- 0
-
-
-
-
- 200
- 0
-
-
-
-
- 200
- 16777215
-
-
-
-
-
-
- QFrame::StyledPanel
-
-
- QFrame::Plain
-
-
- 0
-
-
-
- -
-
-
- true
-
-
-
- 75
- false
- true
- false
- false
- true
-
-
-
- Kill & restart all programs
-
-
- Start all
-
-
-
- icons/media-playback-start.svg icons/media-playback-start.svg
-
-
-
- -
-
-
- Processus :
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 0
-
-
-
-
- 16777215
- 16777215
-
-
-
- Programs running (green) and stopped (red)
-
-
-
- -
-
-
- Session :
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Current session
-
-
-
- -
-
-
- QFrame::StyledPanel
-
-
- Session overview
-
-
- Qt::AutoText
-
-
- false
-
-
- false
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
- -
-
-
- true
-
-
-
- 75
- false
- true
- false
- false
- true
-
-
-
- Kill all running programs
-
-
- Kill all
-
-
-
- icons/process-stop.svg icons/process-stop.svg
-
-
-
-
-
-
-
- -
-
-
- true
-
-
-
-
- 0
- 0
- 151
- 583
-
-
-
- -
-
-
-
- 0
- 30
-
-
-
-
- 16777215
- 30
-
-
-
- QFrame::StyledPanel
-
-
- Settings overview
-
-
- Qt::AutoText
-
-
- false
-
-
-
- -
-
-
-
- 0
- 20
-
-
-
-
- 16777215
- 20
-
-
-
-
- 75
- true
-
-
-
- Airframes
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 0
-
-
-
-
- 16777215
- 16777215
-
-
-
-
-
-
- QFrame::StyledPanel
-
-
- true
-
-
- Qt::ElideLeft
-
-
- QAbstractItemView::ScrollPerItem
-
-
- QListView::Adjust
-
-
- QListView::SinglePass
-
-
-
- -
-
-
-
- 0
- 20
-
-
-
-
- 16777215
- 20
-
-
-
-
- 75
- true
-
-
-
- Settings
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 0
-
-
-
-
- 16777215
- 16777215
-
-
-
-
-
-
- QFrame::StyledPanel
-
-
- true
-
-
- Qt::ElideLeft
-
-
- QAbstractItemView::ScrollPerItem
-
-
- QListView::Adjust
-
-
- QListView::SinglePass
-
-
-
- -
-
-
-
- 0
- 20
-
-
-
-
- 16777215
- 20
-
-
-
-
- 75
- true
-
-
-
- Flight plan
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 0
-
-
-
-
- 16777215
- 16777215
-
-
-
-
-
-
- QFrame::StyledPanel
-
-
- true
-
-
- Qt::ElideLeft
-
-
- QAbstractItemView::ScrollPerItem
-
-
- QListView::Adjust
-
-
- QListView::SinglePass
-
-
-
- -
-
-
-
- 0
- 20
-
-
-
-
- 16777215
- 20
-
-
-
-
- 75
- true
-
-
-
- Radio
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 0
-
-
-
-
- 16777215
- 16777215
-
-
-
-
-
-
- QFrame::StyledPanel
-
-
- true
-
-
- Qt::ElideLeft
-
-
- QAbstractItemView::ScrollPerItem
-
-
- QListView::Adjust
-
-
- QListView::SinglePass
-
-
-
- -
-
-
-
- 0
- 20
-
-
-
-
- 16777215
- 20
-
-
-
-
- 75
- true
-
-
-
- Telemetry
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 0
-
-
-
-
- 16777215
- 16777215
-
-
-
-
-
-
- QFrame::StyledPanel
-
-
- true
-
-
- Qt::ElideLeft
-
-
- QAbstractItemView::ScrollPerItem
-
-
- QListView::Adjust
-
-
- QListView::SinglePass
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
- true
-
-
-
-
- 0
- 0
- 151
- 583
-
-
-
- -
-
-
-
- 0
- 30
-
-
-
-
- 16777215
- 30
-
-
-
- QFrame::StyledPanel
-
-
- Settings overview
-
-
- Qt::AutoText
-
-
- false
-
-
-
- -
-
-
-
- 0
- 20
-
-
-
-
- 16777215
- 20
-
-
-
-
- 75
- true
-
-
-
- Airframes
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 0
-
-
-
-
- 16777215
- 16777215
-
-
-
-
-
-
- QFrame::StyledPanel
-
-
- Qt::ElideLeft
-
-
-
- -
-
-
-
- 0
- 20
-
-
-
-
- 16777215
- 20
-
-
-
-
- 75
- true
-
-
-
- Settings
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 0
-
-
-
-
- 16777215
- 16777215
-
-
-
-
-
-
- QFrame::StyledPanel
-
-
- Qt::ElideLeft
-
-
-
- -
-
-
-
- 0
- 20
-
-
-
-
- 16777215
- 20
-
-
-
-
- 75
- true
-
-
-
- Flight plan
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 0
-
-
-
-
- 16777215
- 16777215
-
-
-
-
-
-
- QFrame::StyledPanel
-
-
- Qt::ElideLeft
-
-
-
- -
-
-
-
- 0
- 20
-
-
-
-
- 16777215
- 20
-
-
-
-
- 75
- true
-
-
-
- Radio
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 0
-
-
-
-
- 16777215
- 16777215
-
-
-
-
-
-
- QFrame::StyledPanel
-
-
- Qt::ElideLeft
-
-
-
- -
-
-
-
- 0
- 20
-
-
-
-
- 16777215
- 20
-
-
-
-
- 75
- true
-
-
-
- Telemetry
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 0
-
-
-
-
- 16777215
- 16777215
-
-
-
-
-
-
- QFrame::StyledPanel
-
-
- Qt::ElideLeft
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
- QFrame::StyledPanel
-
-
- Session overview
-
-
- Qt::AutoText
-
-
- false
-
-
- false
-
-
-
- -
-
-
- Session :
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Current session
-
-
-
- -
-
-
- Processus :
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 0
-
-
-
-
- 16777215
- 16777215
-
-
-
- Programs running (green) and stopped (red)
-
-
-
- -
-
-
-
- 75
- true
-
-
-
- Kill all running programs
-
-
- Kill all
-
-
-
- icons/process-stop.svg icons/process-stop.svg
-
-
-
- -
-
-
-
- 75
- true
-
-
-
- Kill & restart all programs
-
-
- Start all
-
-
-
- icons/media-playback-start.svg icons/media-playback-start.svg
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 94
-
-
-
-
-
-
-
-
-
-
-
-
-
- false
-
-
- New empty set
-
-
- Ctrl+Shift+N
-
-
-
-
- false
-
-
- Save set as...
-
-
-
-
- false
-
-
- Save
-
-
-
-
- false
-
-
- Remove
-
-
-
-
- Set manager... (COMING SOON)
-
-
- Ctrl+Shift+M
-
-
-
-
- false
-
-
- New empty configuration
-
-
- Ctrl+N
-
-
-
-
- false
-
-
- Save configuration as...
-
-
- Ctrl+S
-
-
-
-
- Save
-
-
-
-
- false
-
-
- Remove
-
-
-
-
- false
-
-
- Active mode :
-
-
-
-
- false
-
-
- false
-
-
- false
-
-
- Standard
-
-
- Switch to standard user mode
-
-
- false
-
-
-
-
- false
-
-
- Developer
-
-
- Switch to developer mode
-
-
-
-
- false
-
-
- Settings...
-
-
- Change global settings of the Paparazzi Center
-
-
-
-
- Quit Paparazzi UAV
-
-
- Ctrl+Q
-
-
-
-
- Full screen
-
-
- F11
-
-
-
-
- true
-
-
- Tutorials...
-
-
- Ctrl+H
-
-
-
-
- true
-
-
- Credits...
-
-
-
-
- false
-
-
- New empty session
-
-
- Ctrl+Shift+N, Ctrl+Shift+N
-
-
-
-
- false
-
-
- Save session as...
-
-
- Ctrl+Shift+S
-
-
-
-
- Save
-
-
-
-
- false
-
-
- Remove
-
-
-
-
- false
-
-
- Undo
-
-
- Undo the last action
-
-
- Ctrl+Z
-
-
-
-
- false
-
-
- Redo
-
-
- Redo the last action
-
-
- Ctrl+Y
-
-
-
-
- Simulator
-
-
-
-
- GCS
-
-
-
-
- Meteo
-
-
-
-
- Server
-
-
-
-
- Messages
-
-
-
-
- ...
-
-
-
-
- false
-
-
- WILL BE AVAILABLE LATER :
-
-
-
-
- Set default app state to current
-
-
-
-
- Restore default app state
-
-
-
-
- Hide overviews
-
-
-
-
-
- ToolsMenu
- QFrame
-
- 1
-
-
-
-
-
- main_tab
- currentChanged(int)
- stackedWidget
- setCurrentIndex(int)
-
-
- 130
- 88
-
-
- 690
- 126
-
-
-
-
-
diff --git a/sw/supervision/python/ui/new_ac_dialog.ui b/sw/supervision/python/ui/new_ac_dialog.ui
new file mode 100644
index 0000000000..013d924f74
--- /dev/null
+++ b/sw/supervision/python/ui/new_ac_dialog.ui
@@ -0,0 +1,62 @@
+
+
+ Dialog
+
+
+
+ 0
+ 0
+ 187
+ 106
+
+
+
+ Dialog
+
+
+ -
+
+
+ Name
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ ID
+
+
+
+ -
+
+
+ 1
+
+
+ 255
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QDialogButtonBox::Cancel|QDialogButtonBox::Ok
+
+
+
+
+
+
+
+
diff --git a/sw/supervision/python/ui/operation_panel.ui b/sw/supervision/python/ui/operation_panel.ui
new file mode 100644
index 0000000000..1d2cac67d1
--- /dev/null
+++ b/sw/supervision/python/ui/operation_panel.ui
@@ -0,0 +1,44 @@
+
+
+ OperationPanel
+
+
+
+ 0
+ 0
+ 400
+ 300
+
+
+
+ Form
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+
+
+
+
+
+
+ ConsoleWidget
+ QWidget
+
+ 1
+
+
+ SessionWidget
+ QWidget
+
+ 1
+
+
+
+
+
diff --git a/sw/supervision/python/ui/popup.py b/sw/supervision/python/ui/popup.py
deleted file mode 100644
index 66e119393a..0000000000
--- a/sw/supervision/python/ui/popup.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file 'ui/popup.ui'
-#
-# Created: Mon Jun 20 16:13:37 2016
-# by: PyQt5 UI code generator 5.2.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(500, 350)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(Dialog.sizePolicy().hasHeightForWidth())
- Dialog.setSizePolicy(sizePolicy)
- self.gridLayout = QtWidgets.QGridLayout(Dialog)
- self.gridLayout.setObjectName("gridLayout")
- self.textBrowser = QtWidgets.QTextBrowser(Dialog)
- self.textBrowser.setFrameShape(QtWidgets.QFrame.NoFrame)
- self.textBrowser.setObjectName("textBrowser")
- self.gridLayout.addWidget(self.textBrowser, 0, 0, 1, 1)
- self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.buttonBox.sizePolicy().hasHeightForWidth())
- self.buttonBox.setSizePolicy(sizePolicy)
- self.buttonBox.setMaximumSize(QtCore.QSize(16777215, 30))
- self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.NoButton)
- self.buttonBox.setObjectName("buttonBox")
- self.gridLayout.addWidget(self.buttonBox, 3, 0, 1, 1)
-
- self.retranslateUi(Dialog)
- self.buttonBox.rejected.connect(Dialog.reject)
- self.buttonBox.accepted.connect(Dialog.accept)
- QtCore.QMetaObject.connectSlotsByName(Dialog)
-
- def retranslateUi(self, Dialog):
- _translate = QtCore.QCoreApplication.translate
- Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
-
diff --git a/sw/supervision/python/ui/popup.ui b/sw/supervision/python/ui/popup.ui
deleted file mode 100644
index 7b515cc852..0000000000
--- a/sw/supervision/python/ui/popup.ui
+++ /dev/null
@@ -1,86 +0,0 @@
-
-
- Dialog
-
-
-
- 0
- 0
- 500
- 350
-
-
-
-
- 0
- 0
-
-
-
- Dialog
-
-
- -
-
-
- QFrame::NoFrame
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 16777215
- 30
-
-
-
- QDialogButtonBox::NoButton
-
-
-
-
-
-
-
-
- buttonBox
- rejected()
- Dialog
- reject()
-
-
- 217
- 181
-
-
- 217
- 211
-
-
-
-
- buttonBox
- accepted()
- Dialog
- accept()
-
-
- 97
- 174
-
-
- 99
- 203
-
-
-
-
-
diff --git a/sw/supervision/python/ui/program.ui b/sw/supervision/python/ui/program.ui
new file mode 100644
index 0000000000..c3d56ac92a
--- /dev/null
+++ b/sw/supervision/python/ui/program.ui
@@ -0,0 +1,66 @@
+
+
+ Program
+
+
+
+ 0
+ 0
+ 374
+ 25
+
+
+
+ Form
+
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+ ...
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ -
+
+
+ ...
+
+
+
+ . .
+
+
+
+ -
+
+
+ ...
+
+
+
+ . .
+
+
+
+
+
+
+
+
diff --git a/sw/supervision/python/ui/session.ui b/sw/supervision/python/ui/session.ui
new file mode 100644
index 0000000000..1622ff14b9
--- /dev/null
+++ b/sw/supervision/python/ui/session.ui
@@ -0,0 +1,263 @@
+
+
+ Session
+
+
+
+ 0
+ 0
+ 400
+ 300
+
+
+
+ Form
+
+
+ -
+
+
+ Session
+
+
+
+ -
+
+ -
+
+
+ -
+
+
+ Start Session
+
+
+ ...
+
+
+
+ . .
+
+
+
+ -
+
+
+ Qt::ActionsContextMenu
+
+
+ ...
+
+
+
+ . .
+
+
+
+
+
+ -
+
+
+ -
+
+ -
+
+
+ Programs
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Add Tool
+
+
+ Add tool
+
+
+
+ . .
+
+
+ Qt::ToolButtonTextBesideIcon
+
+
+ false
+
+
+ Qt::NoArrow
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ -
+
+
+ Start All
+
+
+ ...
+
+
+
+ . .
+
+
+
+ -
+
+
+ Stop All
+
+
+ ...
+
+
+
+ . .
+
+
+
+ -
+
+
+ Remove All
+
+
+ ...
+
+
+
+ . .
+
+
+
+
+
+ -
+
+
+ true
+
+
+
+
+ 0
+ 0
+ 380
+ 176
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+
+
+
+
+ . .
+
+
+ Save session
+
+
+
+
+
+ . .
+
+
+ Save as...
+
+
+ Save session as...
+
+
+
+
+
+ . .
+
+
+ Rename session
+
+
+
+
+
+ . .
+
+
+ Remove session
+
+
+
+
+
+
+ menu_button
+ clicked()
+ menu_button
+ showMenu()
+
+
+ 377
+ 45
+
+
+ 377
+ 45
+
+
+
+
+
diff --git a/sw/supervision/python/ui/set_manager.py b/sw/supervision/python/ui/set_manager.py
deleted file mode 100644
index ddbe24e1b7..0000000000
--- a/sw/supervision/python/ui/set_manager.py
+++ /dev/null
@@ -1,136 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file 'set_manager.ui'
-#
-# Created: Wed Mar 9 08:54:50 2016
-# by: PyQt5 UI code generator 5.2.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(400, 300)
- self.gridLayout_2 = QtWidgets.QGridLayout(Dialog)
- self.gridLayout_2.setObjectName("gridLayout_2")
- self.verticalLayout_3 = QtWidgets.QVBoxLayout()
- self.verticalLayout_3.setObjectName("verticalLayout_3")
- self.horizontalLayout = QtWidgets.QHBoxLayout()
- self.horizontalLayout.setObjectName("horizontalLayout")
- self.label_2 = QtWidgets.QLabel(Dialog)
- self.label_2.setObjectName("label_2")
- self.horizontalLayout.addWidget(self.label_2)
- self.sets_combo = QtWidgets.QComboBox(Dialog)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.sets_combo.sizePolicy().hasHeightForWidth())
- self.sets_combo.setSizePolicy(sizePolicy)
- self.sets_combo.setMinimumSize(QtCore.QSize(0, 40))
- self.sets_combo.setMaximumSize(QtCore.QSize(16777215, 40))
- self.sets_combo.setObjectName("sets_combo")
- self.sets_combo.addItem("")
- self.sets_combo.addItem("")
- self.sets_combo.addItem("")
- self.horizontalLayout.addWidget(self.sets_combo)
- self.verticalLayout_3.addLayout(self.horizontalLayout)
- self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
- self.horizontalLayout_2.setObjectName("horizontalLayout_2")
- self.verticalLayout_2 = QtWidgets.QVBoxLayout()
- self.verticalLayout_2.setObjectName("verticalLayout_2")
- self.label = QtWidgets.QLabel(Dialog)
- self.label.setMaximumSize(QtCore.QSize(16777215, 40))
- self.label.setObjectName("label")
- self.verticalLayout_2.addWidget(self.label)
- self.configs_combo = QtWidgets.QComboBox(Dialog)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.configs_combo.sizePolicy().hasHeightForWidth())
- self.configs_combo.setSizePolicy(sizePolicy)
- self.configs_combo.setMinimumSize(QtCore.QSize(0, 40))
- self.configs_combo.setMaximumSize(QtCore.QSize(16777215, 40))
- self.configs_combo.setObjectName("configs_combo")
- self.configs_combo.addItem("")
- self.configs_combo.addItem("")
- self.configs_combo.addItem("")
- self.configs_combo.addItem("")
- self.configs_combo.addItem("")
- self.configs_combo.addItem("")
- self.verticalLayout_2.addWidget(self.configs_combo)
- self.verticalLayout = QtWidgets.QVBoxLayout()
- self.verticalLayout.setObjectName("verticalLayout")
- self.gridLayout = QtWidgets.QGridLayout()
- self.gridLayout.setObjectName("gridLayout")
- self.remove_button = QtWidgets.QPushButton(Dialog)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.remove_button.sizePolicy().hasHeightForWidth())
- self.remove_button.setSizePolicy(sizePolicy)
- self.remove_button.setMinimumSize(QtCore.QSize(50, 50))
- self.remove_button.setMaximumSize(QtCore.QSize(50, 50))
- self.remove_button.setText("")
- icon = QtGui.QIcon()
- icon.addPixmap(QtGui.QPixmap("list-remove.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
- self.remove_button.setIcon(icon)
- self.remove_button.setAutoDefault(False)
- self.remove_button.setObjectName("remove_button")
- self.gridLayout.addWidget(self.remove_button, 0, 0, 1, 1)
- self.add_button = QtWidgets.QPushButton(Dialog)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.add_button.sizePolicy().hasHeightForWidth())
- self.add_button.setSizePolicy(sizePolicy)
- self.add_button.setMinimumSize(QtCore.QSize(50, 50))
- self.add_button.setMaximumSize(QtCore.QSize(50, 50))
- self.add_button.setText("")
- icon1 = QtGui.QIcon()
- icon1.addPixmap(QtGui.QPixmap("list-add.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
- self.add_button.setIcon(icon1)
- self.add_button.setAutoDefault(False)
- self.add_button.setObjectName("add_button")
- self.gridLayout.addWidget(self.add_button, 0, 1, 1, 1)
- self.verticalLayout.addLayout(self.gridLayout)
- self.remove_all = QtWidgets.QPushButton(Dialog)
- self.remove_all.setMinimumSize(QtCore.QSize(0, 40))
- self.remove_all.setAutoDefault(False)
- self.remove_all.setObjectName("remove_all")
- self.verticalLayout.addWidget(self.remove_all)
- self.verticalLayout_2.addLayout(self.verticalLayout)
- self.horizontalLayout_2.addLayout(self.verticalLayout_2)
- self.configs_list = QtWidgets.QListView(Dialog)
- self.configs_list.setObjectName("configs_list")
- self.horizontalLayout_2.addWidget(self.configs_list)
- self.verticalLayout_3.addLayout(self.horizontalLayout_2)
- 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.verticalLayout_3.addWidget(self.buttonBox)
- self.gridLayout_2.addLayout(self.verticalLayout_3, 0, 0, 1, 1)
-
- self.retranslateUi(Dialog)
- self.buttonBox.accepted.connect(Dialog.accept)
- self.buttonBox.rejected.connect(Dialog.reject)
- QtCore.QMetaObject.connectSlotsByName(Dialog)
-
- def retranslateUi(self, Dialog):
- _translate = QtCore.QCoreApplication.translate
- Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
- self.label_2.setText(_translate("Dialog", "Set :"))
- self.sets_combo.setItemText(0, _translate("Dialog", "Set1"))
- self.sets_combo.setItemText(1, _translate("Dialog", "Set2"))
- self.sets_combo.setItemText(2, _translate("Dialog", "Set3"))
- self.label.setText(_translate("Dialog", "Configurations of the set :"))
- self.configs_combo.setItemText(0, _translate("Dialog", "Config1"))
- self.configs_combo.setItemText(1, _translate("Dialog", "Config2"))
- self.configs_combo.setItemText(2, _translate("Dialog", "Config3"))
- self.configs_combo.setItemText(3, _translate("Dialog", "Config4"))
- self.configs_combo.setItemText(4, _translate("Dialog", "Config5"))
- self.configs_combo.setItemText(5, _translate("Dialog", "Config6"))
- self.remove_all.setText(_translate("Dialog", "Remove all"))
-
diff --git a/sw/supervision/python/ui/set_manager.ui b/sw/supervision/python/ui/set_manager.ui
deleted file mode 100644
index 06c54a3043..0000000000
--- a/sw/supervision/python/ui/set_manager.ui
+++ /dev/null
@@ -1,280 +0,0 @@
-
-
- Dialog
-
-
-
- 0
- 0
- 400
- 300
-
-
-
- Dialog
-
-
- -
-
- -
-
- -
-
-
- Set :
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 40
-
-
-
-
- 16777215
- 40
-
-
- -
-
- Set1
-
-
- -
-
- Set2
-
-
- -
-
- Set3
-
-
-
-
-
-
- -
-
- -
-
- -
-
-
-
- 16777215
- 40
-
-
-
- Configurations of the set :
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 0
- 40
-
-
-
-
- 16777215
- 40
-
-
- -
-
- Config1
-
-
- -
-
- Config2
-
-
- -
-
- Config3
-
-
- -
-
- Config4
-
-
- -
-
- Config5
-
-
- -
-
- Config6
-
-
-
-
- -
-
- -
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 50
- 50
-
-
-
-
- 50
- 50
-
-
-
-
-
-
-
- list-remove.svg list-remove.svg
-
-
- false
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 50
- 50
-
-
-
-
- 50
- 50
-
-
-
-
-
-
-
- list-add.svg list-add.svg
-
-
- false
-
-
-
-
-
- -
-
-
-
- 0
- 40
-
-
-
- Remove all
-
-
- false
-
-
-
-
-
-
-
- -
-
-
-
-
- -
-
-
- Qt::Horizontal
-
-
- QDialogButtonBox::Cancel|QDialogButtonBox::Ok
-
-
-
-
-
-
-
-
-
-
- buttonBox
- accepted()
- Dialog
- accept()
-
-
- 258
- 289
-
-
- 157
- 274
-
-
-
-
- buttonBox
- rejected()
- Dialog
- reject()
-
-
- 326
- 289
-
-
- 286
- 274
-
-
-
-
-
diff --git a/sw/supervision/python/ui/tools_list.ui b/sw/supervision/python/ui/tools_list.ui
new file mode 100644
index 0000000000..df3ae116f9
--- /dev/null
+++ b/sw/supervision/python/ui/tools_list.ui
@@ -0,0 +1,46 @@
+
+
+ ToolsList
+
+
+
+ 0
+ 0
+ 328
+ 357
+
+
+
+ Form
+
+
+ -
+
+
+ true
+
+
+
+ -
+
+
+ true
+
+
+
+
+ 0
+ 0
+ 308
+ 306
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sw/supervision/python/ui/tutorial.html b/sw/supervision/python/ui/tutorial.html
deleted file mode 100644
index 47a79b9a45..0000000000
--- a/sw/supervision/python/ui/tutorial.html
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-
-
-
-
-
- About Paparazzi UAV :
-
-
-
-
diff --git a/sw/supervision/python/utils.py b/sw/supervision/python/utils.py
new file mode 100644
index 0000000000..3c062fbc96
--- /dev/null
+++ b/sw/supervision/python/utils.py
@@ -0,0 +1,109 @@
+# Copyright (C) 2008-2022 The Paparazzi Team
+# released under GNU GPLv2 or later. See COPYING file.
+import os
+import subprocess
+from PyQt5.QtWidgets import *
+from typing import NamedTuple
+from PyQt5.QtCore import QSettings
+
+
+class GConfEntry(NamedTuple):
+ name: str
+ value: str
+ application: str
+
+
+PAPARAZZI_SRC = os.getenv("PAPARAZZI_HOME")
+PAPARAZZI_HOME = os.getenv("PAPARAZZI_HOME", PAPARAZZI_SRC)
+CONF_DIR = os.path.join(PAPARAZZI_HOME, "conf/")
+
+
+# TODO: make it work with shell program such as vim.
+def edit_file(file_path, prefix=CONF_DIR):
+ path = prefix + file_path
+ editor = get_settings().value("text_editor", "", str)
+ if editor == "":
+ editor = "gedit"
+ try:
+ subprocess.Popen([editor, path])
+ except Exception as e:
+ print(e)
+
+
+def make_line(parent: QWidget = None, vertical=False) -> QWidget:
+ line = QFrame(parent)
+ if vertical:
+ line.setFrameShape(QFrame.VLine)
+ else:
+ line.setFrameShape(QFrame.HLine)
+ line.setFrameShadow(QFrame.Sunken)
+ return line
+
+
+def get_version() -> str:
+ run_version_exe = os.path.join(PAPARAZZI_HOME, "paparazzi_version")
+ proc = subprocess.run(run_version_exe, cwd=PAPARAZZI_HOME, capture_output=True)
+ return proc.stdout.decode().strip()
+
+
+def get_build_version() -> str:
+ bv_path = os.path.join(PAPARAZZI_HOME, "var", "build_version.txt")
+ with open(bv_path, 'r') as f:
+ version = f.readline().strip()
+ return version
+
+
+def open_terminal(wd, command=None):
+ cmd = ""
+ if command is not None:
+ cmd = " -- {}".format(command)
+ terminal_emulator = get_settings().value("terminal_emulator", "", str)
+ if terminal_emulator == "":
+ terminal_emulator = "gnome-terminal"
+ os.system("{} --working-directory {}{}".format(terminal_emulator, wd, cmd))
+
+
+def get_settings() -> QSettings:
+ return QSettings(os.path.join(CONF_DIR, "pprz_center_settings.ini"), QSettings.IniFormat)
+
+
+ABOUT_TEXT = \
+ """
+ Paparazzi Center
+ The Paparazzi Center is the home application for Paparazzi UAV.
+ Learn more about Paparazzi:
+
+
+
+ Licence information:
+
+ Copyright (C) 2008-2022 The Paparazzi Team
+ Paparazzi Center is part of the Paparazzi, released under GPLv2 or any later version.
+ See the file COPYING ,
+ or the licence information at http://www.gnu.org/licenses/ .
+
+
+ This software uses:
+
+ Qt released under GNU LGPL
+ PyQt5 released under GNU GPLv3
+
+
+
+ """.format(PAPARAZZI_HOME)