diff --git a/.gitignore b/.gitignore
index 343691fe08..b39dca8b94 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,6 +23,8 @@
*.gdb_history
+.cache.xml
+
# Eclipse IDE project files
*.cproject
*.project
diff --git a/paparazzi-python.sh b/paparazzi-python.sh
new file mode 100755
index 0000000000..1a99867207
--- /dev/null
+++ b/paparazzi-python.sh
@@ -0,0 +1,3 @@
+#!/usr/bin/env /bin/sh
+cd $PAPARAZZI_SRC/sw/supervision/python
+./main.py
diff --git a/src/paparazzi b/src/paparazzi
index 8895cccacb..9cda33fba4 100755
--- a/src/paparazzi
+++ b/src/paparazzi
@@ -9,7 +9,16 @@ let env =
let value = if value = "." then Sys.getcwd () else value in
Printf.sprintf "%s=%s" var value)
[|"PAPARAZZI_SRC"; "PAPARAZZI_HOME"|]
-let com = dirname // "sw/supervision/paparazzicenter";;
+let com =
+ if Array.length (Sys.argv) > 1 then begin
+ Printf.printf "%d\n" (Array.length (Sys.argv));
+ if Sys.argv.(1) = "-python" then
+ dirname // "paparazzi-python.sh"
+ else
+ dirname // "sw/supervision/paparazzicenter"
+ end
+ else
+ dirname // "sw/supervision/paparazzicenter";;
Sys.argv.(0) <- com;;
let env = Array.append env (Unix.environment ());;
Unix.execve com Sys.argv env
diff --git a/sw/supervision/python/.cache.dtd b/sw/supervision/python/.cache.dtd
new file mode 100644
index 0000000000..3a3f843f05
--- /dev/null
+++ b/sw/supervision/python/.cache.dtd
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sw/supervision/python/README.md b/sw/supervision/python/README.md
new file mode 100644
index 0000000000..759f72a36b
--- /dev/null
+++ b/sw/supervision/python/README.md
@@ -0,0 +1,69 @@
+###############################################################################
+# 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/dialogs.py b/sw/supervision/python/dialogs.py
new file mode 100644
index 0000000000..1f3c1c2097
--- /dev/null
+++ b/sw/supervision/python/dialogs.py
@@ -0,0 +1,103 @@
+# 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/hmi.py b/sw/supervision/python/hmi.py
new file mode 100644
index 0000000000..406a606e62
--- /dev/null
+++ b/sw/supervision/python/hmi.py
@@ -0,0 +1,1768 @@
+# 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]
+
+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"
+
+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):
+ """
+ -> 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()
+
+ # Data object creation implies XML parsing in the parser module :
+ try:
+ 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)
+ 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()
+
+ # 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_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.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.
+ """
+ self.ui.menuTools.clear()
+ sorted_names = parser.sorted_tools_names(self.data.tools)
+ for name in sorted_names:
+ action = Widgets.QAction(name, self)
+ self.ui.menuTools.addAction(action)
+ for action in self.ui.menuTools.actions():
+ action.triggered.connect(functools.partial(
+ self.add_program_to_session, self.data.tools[action.text()]))
+
+ def fullscreen_view(self):
+ if self.isMaximized():
+ self.resize(800, 600)
+ else:
+ self.showMaximized()
+
+ 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
new file mode 100644
index 0000000000..03db109a64
--- /dev/null
+++ b/sw/supervision/python/icons/accessories-text-editor.svg
@@ -0,0 +1,107 @@
+
+
+
diff --git a/sw/supervision/python/icons/dialog-apply.svg b/sw/supervision/python/icons/dialog-apply.svg
new file mode 100644
index 0000000000..f009b90ee3
--- /dev/null
+++ b/sw/supervision/python/icons/dialog-apply.svg
@@ -0,0 +1,18 @@
+
+
+
diff --git a/sw/supervision/python/icons/dialog-error.svg b/sw/supervision/python/icons/dialog-error.svg
new file mode 100644
index 0000000000..a3d6de4d72
--- /dev/null
+++ b/sw/supervision/python/icons/dialog-error.svg
@@ -0,0 +1,28 @@
+
+
+
diff --git a/sw/supervision/python/icons/dialog-warning-symbolic.svg b/sw/supervision/python/icons/dialog-warning-symbolic.svg
new file mode 100644
index 0000000000..e9474a9d14
--- /dev/null
+++ b/sw/supervision/python/icons/dialog-warning-symbolic.svg
@@ -0,0 +1,17 @@
+
+
+
diff --git a/sw/supervision/python/icons/dialog-warning.png b/sw/supervision/python/icons/dialog-warning.png
new file mode 100644
index 0000000000..d1020c6d9e
Binary files /dev/null and b/sw/supervision/python/icons/dialog-warning.png differ
diff --git a/sw/supervision/python/icons/edit-clear.svg b/sw/supervision/python/icons/edit-clear.svg
new file mode 100644
index 0000000000..568fe9de66
--- /dev/null
+++ b/sw/supervision/python/icons/edit-clear.svg
@@ -0,0 +1,16 @@
+
+
+
diff --git a/sw/supervision/python/icons/go-up.svg b/sw/supervision/python/icons/go-up.svg
new file mode 100644
index 0000000000..e5e58672cd
--- /dev/null
+++ b/sw/supervision/python/icons/go-up.svg
@@ -0,0 +1,28 @@
+
+
+
diff --git a/sw/supervision/python/icons/gtk-info.svg b/sw/supervision/python/icons/gtk-info.svg
new file mode 100644
index 0000000000..f1ec53786a
--- /dev/null
+++ b/sw/supervision/python/icons/gtk-info.svg
@@ -0,0 +1,25 @@
+
+
+
diff --git a/sw/supervision/python/icons/list-add.svg b/sw/supervision/python/icons/list-add.svg
new file mode 100644
index 0000000000..f40a948324
--- /dev/null
+++ b/sw/supervision/python/icons/list-add.svg
@@ -0,0 +1,18 @@
+
+
+
diff --git a/sw/supervision/python/icons/list-remove.svg b/sw/supervision/python/icons/list-remove.svg
new file mode 100644
index 0000000000..ebc6bdbe8f
--- /dev/null
+++ b/sw/supervision/python/icons/list-remove.svg
@@ -0,0 +1,18 @@
+
+
+
diff --git a/sw/supervision/python/icons/media-playback-pause.svg b/sw/supervision/python/icons/media-playback-pause.svg
new file mode 100644
index 0000000000..fde2760829
--- /dev/null
+++ b/sw/supervision/python/icons/media-playback-pause.svg
@@ -0,0 +1,25 @@
+
+
+
diff --git a/sw/supervision/python/icons/media-playback-start.svg b/sw/supervision/python/icons/media-playback-start.svg
new file mode 100644
index 0000000000..87c34d3025
--- /dev/null
+++ b/sw/supervision/python/icons/media-playback-start.svg
@@ -0,0 +1,18 @@
+
+
+
diff --git a/sw/supervision/python/icons/penguin_icon.png b/sw/supervision/python/icons/penguin_icon.png
new file mode 100644
index 0000000000..f61d8024e9
Binary files /dev/null and b/sw/supervision/python/icons/penguin_icon.png differ
diff --git a/sw/supervision/python/icons/process-stop.svg b/sw/supervision/python/icons/process-stop.svg
new file mode 100644
index 0000000000..1c9162caab
--- /dev/null
+++ b/sw/supervision/python/icons/process-stop.svg
@@ -0,0 +1,28 @@
+
+
+
diff --git a/sw/supervision/python/icons/search_field.png b/sw/supervision/python/icons/search_field.png
new file mode 100644
index 0000000000..c3264f66d9
Binary files /dev/null and b/sw/supervision/python/icons/search_field.png differ
diff --git a/sw/supervision/python/icons/system-run.png b/sw/supervision/python/icons/system-run.png
new file mode 100644
index 0000000000..ad6d80b0de
Binary files /dev/null and b/sw/supervision/python/icons/system-run.png differ
diff --git a/sw/supervision/python/icons/utilities-terminal.svg b/sw/supervision/python/icons/utilities-terminal.svg
new file mode 100644
index 0000000000..add2893910
--- /dev/null
+++ b/sw/supervision/python/icons/utilities-terminal.svg
@@ -0,0 +1,65 @@
+
+
+
diff --git a/sw/supervision/python/lib/console.py b/sw/supervision/python/lib/console.py
new file mode 100644
index 0000000000..945712cc7a
--- /dev/null
+++ b/sw/supervision/python/lib/console.py
@@ -0,0 +1,155 @@
+# 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
new file mode 100644
index 0000000000..1a67a0b5f7
--- /dev/null
+++ b/sw/supervision/python/lib/database.py
@@ -0,0 +1,161 @@
+# 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.subsystems = None
+ 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):
+ self.name = name
+ self.command = command
+ self.options = options
+
+ def __repr__(self):
+ string = "\t| name = {!s:<30} | command = {!s:<60} | options = {!s:<70} |"
+ format_string = string.format(self.name, self.command, self.options)
+ 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
new file mode 100644
index 0000000000..0201937d78
--- /dev/null
+++ b/sw/supervision/python/lib/default_cache.xml
@@ -0,0 +1,15 @@
+
(Python/Qt version)
+Copyright (C) 2007-2008 ENAC, Pascal Brisset
+License GPLv2
+ + + diff --git a/sw/supervision/python/ui/data_changed.html b/sw/supervision/python/ui/data_changed.html new file mode 100644 index 0000000000..ba8ef77ead --- /dev/null +++ b/sw/supervision/python/ui/data_changed.html @@ -0,0 +1,13 @@ + + + + + + +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 new file mode 100644 index 0000000000..03db109a64 --- /dev/null +++ b/sw/supervision/python/ui/icons/accessories-text-editor.svg @@ -0,0 +1,107 @@ + + + diff --git a/sw/supervision/python/ui/icons/dialog-apply.svg b/sw/supervision/python/ui/icons/dialog-apply.svg new file mode 100644 index 0000000000..f009b90ee3 --- /dev/null +++ b/sw/supervision/python/ui/icons/dialog-apply.svg @@ -0,0 +1,18 @@ + + + diff --git a/sw/supervision/python/ui/icons/dialog-error.svg b/sw/supervision/python/ui/icons/dialog-error.svg new file mode 100644 index 0000000000..a3d6de4d72 --- /dev/null +++ b/sw/supervision/python/ui/icons/dialog-error.svg @@ -0,0 +1,28 @@ + + + diff --git a/sw/supervision/python/ui/icons/dialog-warning-symbolic.svg b/sw/supervision/python/ui/icons/dialog-warning-symbolic.svg new file mode 100644 index 0000000000..e9474a9d14 --- /dev/null +++ b/sw/supervision/python/ui/icons/dialog-warning-symbolic.svg @@ -0,0 +1,17 @@ + + + diff --git a/sw/supervision/python/ui/icons/dialog-warning.png b/sw/supervision/python/ui/icons/dialog-warning.png new file mode 100644 index 0000000000..d1020c6d9e Binary files /dev/null and b/sw/supervision/python/ui/icons/dialog-warning.png differ diff --git a/sw/supervision/python/ui/icons/edit-clear.svg b/sw/supervision/python/ui/icons/edit-clear.svg new file mode 100644 index 0000000000..568fe9de66 --- /dev/null +++ b/sw/supervision/python/ui/icons/edit-clear.svg @@ -0,0 +1,16 @@ + + + diff --git a/sw/supervision/python/ui/icons/go-up.svg b/sw/supervision/python/ui/icons/go-up.svg new file mode 100644 index 0000000000..e5e58672cd --- /dev/null +++ b/sw/supervision/python/ui/icons/go-up.svg @@ -0,0 +1,28 @@ + + + diff --git a/sw/supervision/python/ui/icons/gtk-info.svg b/sw/supervision/python/ui/icons/gtk-info.svg new file mode 100644 index 0000000000..f1ec53786a --- /dev/null +++ b/sw/supervision/python/ui/icons/gtk-info.svg @@ -0,0 +1,25 @@ + + + diff --git a/sw/supervision/python/ui/icons/list-add.svg b/sw/supervision/python/ui/icons/list-add.svg new file mode 100644 index 0000000000..f40a948324 --- /dev/null +++ b/sw/supervision/python/ui/icons/list-add.svg @@ -0,0 +1,18 @@ + + + diff --git a/sw/supervision/python/ui/icons/list-remove.svg b/sw/supervision/python/ui/icons/list-remove.svg new file mode 100644 index 0000000000..ebc6bdbe8f --- /dev/null +++ b/sw/supervision/python/ui/icons/list-remove.svg @@ -0,0 +1,18 @@ + + + diff --git a/sw/supervision/python/ui/icons/media-playback-pause.svg b/sw/supervision/python/ui/icons/media-playback-pause.svg new file mode 100644 index 0000000000..fde2760829 --- /dev/null +++ b/sw/supervision/python/ui/icons/media-playback-pause.svg @@ -0,0 +1,25 @@ + + + diff --git a/sw/supervision/python/ui/icons/media-playback-start.svg b/sw/supervision/python/ui/icons/media-playback-start.svg new file mode 100644 index 0000000000..87c34d3025 --- /dev/null +++ b/sw/supervision/python/ui/icons/media-playback-start.svg @@ -0,0 +1,18 @@ + + + diff --git a/sw/supervision/python/ui/icons/penguin_icon.png b/sw/supervision/python/ui/icons/penguin_icon.png new file mode 100644 index 0000000000..f61d8024e9 Binary files /dev/null and b/sw/supervision/python/ui/icons/penguin_icon.png differ diff --git a/sw/supervision/python/ui/icons/process-stop.svg b/sw/supervision/python/ui/icons/process-stop.svg new file mode 100644 index 0000000000..1c9162caab --- /dev/null +++ b/sw/supervision/python/ui/icons/process-stop.svg @@ -0,0 +1,28 @@ + + + diff --git a/sw/supervision/python/ui/icons/search_field.png b/sw/supervision/python/ui/icons/search_field.png new file mode 100644 index 0000000000..c3264f66d9 Binary files /dev/null and b/sw/supervision/python/ui/icons/search_field.png differ diff --git a/sw/supervision/python/ui/icons/system-run.png b/sw/supervision/python/ui/icons/system-run.png new file mode 100644 index 0000000000..ad6d80b0de Binary files /dev/null and b/sw/supervision/python/ui/icons/system-run.png differ diff --git a/sw/supervision/python/ui/icons/utilities-terminal.svg b/sw/supervision/python/ui/icons/utilities-terminal.svg new file mode 100644 index 0000000000..add2893910 --- /dev/null +++ b/sw/supervision/python/ui/icons/utilities-terminal.svg @@ -0,0 +1,65 @@ + + + diff --git a/sw/supervision/python/ui/main_window.py b/sw/supervision/python/ui/main_window.py new file mode 100644 index 0000000000..6363b7abff --- /dev/null +++ b/sw/supervision/python/ui/main_window.py @@ -0,0 +1,1700 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'ui/main_window.ui' +# +# Created: Tue Jun 28 14:49:52 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_MainWindow(object): + def setupUi(self, MainWindow): + MainWindow.setObjectName("MainWindow") + MainWindow.resize(744, 481) + 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, 298, 622)) + 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.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.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.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.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.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.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_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.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.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.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.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.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.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.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) + 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) + spacerItem3 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_3.addItem(spacerItem3, 12, 11, 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.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, 8) + 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.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.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, 1, 2, 3, 1) + self.label_8 = QtWidgets.QLabel(self.sessions_tab) + self.label_8.setObjectName("label_8") + self.gridLayout_2.addWidget(self.label_8, 1, 0, 1, 2) + spacerItem4 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_2.addItem(spacerItem4, 2, 3, 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)) + icon7 = QtGui.QIcon() + icon7.addPixmap(QtGui.QPixmap("icons/media-playback-start.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + 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, 1, 3, 1, 1) + self.label_7 = QtWidgets.QLabel(self.sessions_tab) + self.label_7.setObjectName("label_7") + self.gridLayout_2.addWidget(self.label_7, 4, 0, 1, 2) + 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) + self.start_all_button.setIcon(icon7) + self.start_all_button.setObjectName("start_all_button") + self.gridLayout_2.addWidget(self.start_all_button, 4, 3, 1, 1) + spacerItem5 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.gridLayout_2.addItem(spacerItem5, 6, 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, 3, 3, 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, 0, 2, 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, 4, 2, 2, 1) + self.label_4 = QtWidgets.QLabel(self.sessions_tab) + self.label_4.setObjectName("label_4") + self.gridLayout_2.addWidget(self.label_4, 0, 0, 1, 2) + 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, 3, 0, 1, 1) + 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, 3, 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, 5, 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, 5, 1, 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) + self.stackedWidget = QtWidgets.QStackedWidget(self.centralwidget) + 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, 148, 598)) + 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, 148, 598)) + 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.gridLayout_10.addWidget(self.stackedWidget, 0, 1, 2, 1) + MainWindow.setCentralWidget(self.centralwidget) + self.menubar = QtWidgets.QMenuBar(MainWindow) + self.menubar.setGeometry(QtCore.QRect(0, 0, 744, 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.menuTools = QtWidgets.QMenu(self.menubar) + self.menuTools.setObjectName("menuTools") + 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.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.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.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.menuTools.menuAction()) + self.menubar.addAction(self.menuView.menuAction()) + self.menubar.addAction(self.menuHelp.menuAction()) + + self.retranslateUi(MainWindow) + self.main_tab.setCurrentIndex(0) + 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.flash_result.setToolTip(_translate("MainWindow", "Flash result")) + self.info_nb.setToolTip(_translate("MainWindow", "Info found during build")) + 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.label_23.setText(_translate("MainWindow", "Build")) + self.warnings_nb.setToolTip(_translate("MainWindow", "Warnings found during build")) + self.label_9.setText(_translate("MainWindow", "Result :")) + self.label_12.setText(_translate("MainWindow", "Device :")) + self.label_14.setText(_translate("MainWindow", "Info :")) + self.clean.setToolTip(_translate("MainWindow", "Clean the current configuration")) + self.clean.setText(_translate("MainWindow", "Clean")) + self.target.setToolTip(_translate("MainWindow", "Current target")) + self.errors_nb.setToolTip(_translate("MainWindow", "Errors found during build")) + self.device.setToolTip(_translate("MainWindow", "Current device")) + self.show_console.setToolTip(_translate("MainWindow", "Switch to the console tab")) + self.show_console.setText(_translate("MainWindow", "Show console")) + self.build.setToolTip(_translate("MainWindow", "Build the current configuration")) + self.build.setText(_translate("MainWindow", "Build")) + self.upload.setToolTip(_translate("MainWindow", "Flash the current device")) + self.upload.setText(_translate("MainWindow", "Upload")) + self.build_result.setToolTip(_translate("MainWindow", "Clean & build 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.programs.setToolTip(_translate("MainWindow", "Programs running (green) and stopped (red)")) + self.label_8.setText(_translate("MainWindow", "Programs :")) + self.play_stop_program.setToolTip(_translate("MainWindow", "Start / stop the selected program")) + self.play_stop_program.setText(_translate("MainWindow", "Start")) + self.label_7.setText(_translate("MainWindow", "Options :")) + self.start_all_button.setToolTip(_translate("MainWindow", "Kill & restart all programs")) + self.start_all_button.setText(_translate("MainWindow", "Start all")) + self.kill_all_button.setToolTip(_translate("MainWindow", "Kill all running programs")) + self.kill_all_button.setText(_translate("MainWindow", "Kill all")) + self.session.setToolTip(_translate("MainWindow", "Current session")) + self.options.setToolTip(_translate("MainWindow", "Options of the selected program")) + self.label_4.setText(_translate("MainWindow", "Session :")) + self.remove_program.setToolTip(_translate("MainWindow", "Remove a programs from the 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" +"Primary documentation, Paparazzi wiki:
+ +Community-based support, mailing list:
++ Contact +
+The Paparazzi auto-generated developer documentation:
+ +Paparazzi sourcecode and issue tracker:
+ +