From 35e8b61b7d34b960e47990cd541e6009d12e7ee5 Mon Sep 17 00:00:00 2001
From: Neil Horne <15316949+elecpower@users.noreply.github.com>
Date: Fri, 24 Jan 2025 12:49:34 +1100
Subject: [PATCH] feat(cpn): read and write to/from radio profile SD path,
menu reorganisation (#5753)
---
companion/releasenotes.txt | 484 -----------------
companion/src/companion.qrc | 41 +-
.../originals/folder-tree-read-classic.svg | 162 ++++++
.../originals/folder-tree-read-monochrome.svg | 66 +++
.../originals/folder-tree-read-outline.svg | 110 ++++
.../originals/folder-tree-read-yerico.svg | 111 ++++
.../originals/folder-tree-write-classic.svg | 162 ++++++
.../folder-tree-write-monochrome.svg | 66 +++
.../originals/folder-tree-write-outline.svg | 108 ++++
.../originals/folder-tree-write-yerico.svg | 111 ++++
companion/src/mainwindow.cpp | 514 ++++++++++++------
companion/src/mainwindow.h | 67 ++-
companion/src/mdichild.cpp | 72 ++-
companion/src/mdichild.h | 19 +-
companion/src/radiointerface.cpp | 28 +-
companion/src/radiointerface.h | 7 +-
companion/src/storage/appdata.h | 7 +
.../themes/classic/16/folder-tree-read.png | Bin 0 -> 569 bytes
.../themes/classic/16/folder-tree-write.png | Bin 0 -> 586 bytes
.../themes/classic/24/folder-tree-read.png | Bin 0 -> 803 bytes
.../themes/classic/24/folder-tree-write.png | Bin 0 -> 789 bytes
.../themes/classic/32/folder-tree-read.png | Bin 0 -> 1055 bytes
.../themes/classic/32/folder-tree-write.png | Bin 0 -> 1078 bytes
.../themes/classic/48/folder-tree-read.png | Bin 0 -> 1560 bytes
.../themes/classic/48/folder-tree-write.png | Bin 0 -> 1586 bytes
.../themes/monoblue/16/folder-tree-read.png | Bin 0 -> 424 bytes
.../themes/monoblue/16/folder-tree-write.png | Bin 0 -> 418 bytes
.../themes/monoblue/24/folder-tree-read.png | Bin 0 -> 435 bytes
.../themes/monoblue/24/folder-tree-write.png | Bin 0 -> 432 bytes
.../themes/monoblue/32/folder-tree-read.png | Bin 0 -> 452 bytes
.../themes/monoblue/32/folder-tree-write.png | Bin 0 -> 450 bytes
.../themes/monoblue/48/folder-tree-read.png | Bin 0 -> 480 bytes
.../themes/monoblue/48/folder-tree-write.png | Bin 0 -> 479 bytes
.../themes/monochrome/16/folder-tree-read.png | Bin 0 -> 436 bytes
.../monochrome/16/folder-tree-write.png | Bin 0 -> 434 bytes
.../themes/monochrome/24/folder-tree-read.png | Bin 0 -> 573 bytes
.../monochrome/24/folder-tree-write.png | Bin 0 -> 568 bytes
.../themes/monochrome/32/folder-tree-read.png | Bin 0 -> 711 bytes
.../monochrome/32/folder-tree-write.png | Bin 0 -> 715 bytes
.../themes/monochrome/48/folder-tree-read.png | Bin 0 -> 983 bytes
.../monochrome/48/folder-tree-write.png | Bin 0 -> 1013 bytes
.../themes/monowhite/16/folder-tree-read.png | Bin 0 -> 440 bytes
.../themes/monowhite/16/folder-tree-write.png | Bin 0 -> 434 bytes
.../themes/monowhite/24/folder-tree-read.png | Bin 0 -> 625 bytes
.../themes/monowhite/24/folder-tree-write.png | Bin 0 -> 612 bytes
.../themes/monowhite/32/folder-tree-read.png | Bin 0 -> 798 bytes
.../themes/monowhite/32/folder-tree-write.png | Bin 0 -> 794 bytes
.../themes/monowhite/48/folder-tree-read.png | Bin 0 -> 1238 bytes
.../themes/monowhite/48/folder-tree-write.png | Bin 0 -> 1241 bytes
.../src/themes/yerico/16/folder-tree-read.png | Bin 0 -> 812 bytes
.../themes/yerico/16/folder-tree-write.png | Bin 0 -> 812 bytes
.../src/themes/yerico/24/folder-tree-read.png | Bin 0 -> 1241 bytes
.../themes/yerico/24/folder-tree-write.png | Bin 0 -> 1240 bytes
.../src/themes/yerico/32/folder-tree-read.png | Bin 0 -> 1721 bytes
.../themes/yerico/32/folder-tree-write.png | Bin 0 -> 1725 bytes
.../src/themes/yerico/48/folder-tree-read.png | Bin 0 -> 2652 bytes
.../themes/yerico/48/folder-tree-write.png | Bin 0 -> 2659 bytes
57 files changed, 1403 insertions(+), 732 deletions(-)
delete mode 100644 companion/releasenotes.txt
create mode 100644 companion/src/images/originals/folder-tree-read-classic.svg
create mode 100644 companion/src/images/originals/folder-tree-read-monochrome.svg
create mode 100644 companion/src/images/originals/folder-tree-read-outline.svg
create mode 100644 companion/src/images/originals/folder-tree-read-yerico.svg
create mode 100644 companion/src/images/originals/folder-tree-write-classic.svg
create mode 100644 companion/src/images/originals/folder-tree-write-monochrome.svg
create mode 100644 companion/src/images/originals/folder-tree-write-outline.svg
create mode 100644 companion/src/images/originals/folder-tree-write-yerico.svg
create mode 100644 companion/src/themes/classic/16/folder-tree-read.png
create mode 100644 companion/src/themes/classic/16/folder-tree-write.png
create mode 100644 companion/src/themes/classic/24/folder-tree-read.png
create mode 100644 companion/src/themes/classic/24/folder-tree-write.png
create mode 100644 companion/src/themes/classic/32/folder-tree-read.png
create mode 100644 companion/src/themes/classic/32/folder-tree-write.png
create mode 100644 companion/src/themes/classic/48/folder-tree-read.png
create mode 100644 companion/src/themes/classic/48/folder-tree-write.png
create mode 100644 companion/src/themes/monoblue/16/folder-tree-read.png
create mode 100644 companion/src/themes/monoblue/16/folder-tree-write.png
create mode 100644 companion/src/themes/monoblue/24/folder-tree-read.png
create mode 100644 companion/src/themes/monoblue/24/folder-tree-write.png
create mode 100644 companion/src/themes/monoblue/32/folder-tree-read.png
create mode 100644 companion/src/themes/monoblue/32/folder-tree-write.png
create mode 100644 companion/src/themes/monoblue/48/folder-tree-read.png
create mode 100644 companion/src/themes/monoblue/48/folder-tree-write.png
create mode 100644 companion/src/themes/monochrome/16/folder-tree-read.png
create mode 100644 companion/src/themes/monochrome/16/folder-tree-write.png
create mode 100644 companion/src/themes/monochrome/24/folder-tree-read.png
create mode 100644 companion/src/themes/monochrome/24/folder-tree-write.png
create mode 100644 companion/src/themes/monochrome/32/folder-tree-read.png
create mode 100644 companion/src/themes/monochrome/32/folder-tree-write.png
create mode 100644 companion/src/themes/monochrome/48/folder-tree-read.png
create mode 100644 companion/src/themes/monochrome/48/folder-tree-write.png
create mode 100644 companion/src/themes/monowhite/16/folder-tree-read.png
create mode 100644 companion/src/themes/monowhite/16/folder-tree-write.png
create mode 100644 companion/src/themes/monowhite/24/folder-tree-read.png
create mode 100644 companion/src/themes/monowhite/24/folder-tree-write.png
create mode 100644 companion/src/themes/monowhite/32/folder-tree-read.png
create mode 100644 companion/src/themes/monowhite/32/folder-tree-write.png
create mode 100644 companion/src/themes/monowhite/48/folder-tree-read.png
create mode 100644 companion/src/themes/monowhite/48/folder-tree-write.png
create mode 100644 companion/src/themes/yerico/16/folder-tree-read.png
create mode 100644 companion/src/themes/yerico/16/folder-tree-write.png
create mode 100644 companion/src/themes/yerico/24/folder-tree-read.png
create mode 100644 companion/src/themes/yerico/24/folder-tree-write.png
create mode 100644 companion/src/themes/yerico/32/folder-tree-read.png
create mode 100644 companion/src/themes/yerico/32/folder-tree-write.png
create mode 100644 companion/src/themes/yerico/48/folder-tree-read.png
create mode 100644 companion/src/themes/yerico/48/folder-tree-write.png
diff --git a/companion/releasenotes.txt b/companion/releasenotes.txt
deleted file mode 100644
index 58ef7c750..000000000
--- a/companion/releasenotes.txt
+++ /dev/null
@@ -1,484 +0,0 @@
-
Version 2.2.1 / 2017-12-17
-
-Please see this page for details.
-
-Version 2.2.0 / 2017-05-30
-
-Major release! Please see this page for details.
-
-Version 2.1.9 / 2016-09-14
-
-
-SD sync fixes (#3351 )
-Fixed: Telemetry mode "FrSky D (cable)" choice was missing for Taranis (#3372 )
-Show persistent option only for calculated sensors (#3454 )
-Fixed Flight mode clear command (#3214 )
-Fixed a problem with Rotary encoders linked to flight mode (could freeze Companion) (#3459 , #3470 )
-Telemetry simulator improvements: added fuel quantity sensor, increased RPM range (#3505 , #3506 )
-Implemented minimal support for the DYI Multimodule (#3526 )
-Fixed: GVar combo-box not being refreshed when GV check-box (re-)selected (#3518 )
-Fixed: Heli inversion not correctly shown/saved from Companion on Radios without virtual inputs (#3510 )
-Implemented print functions for the Heli setup screen (#3554 )
-Fixed: Flight modes linked trims display value (#3547 , #3568 )
-Fixed: New model global variables and rotary encoders initialisation (#3473 )
-Fixed: Prevent circular linked global variables and rotary encoders (#3472 )
-Fixed wrong log replay speed issue in Telemetry simulator (#3708 )
-Various texts and translations corrections
-
-
-
-Version 2.1.8 / 2016-04-14
-
-
-Telemetry Simulator sensor instance number fixed (#3207 )
-Fixed: Throttle Source combo-box was populated multiple times (#3222 )
-RTC option tool-tip corrected (#3225 )
-Fixed: Companion was looking for custom scripts at the wrong place (#3237 )
-Offset displayed in inputs screen (#3248 )
-Import/export handling was broken for Average formula telemetry sensors (#3262 )
-Fixed: Hardware Setup control types and names were not stored in profile (#3260 )
-Fixed voice language list (#3338 )
-Fixed data overflow in Special Functions Override Channel (#3347 )
-Fixed: Sync dialog new line problem (only present for some UI languages) (#3350 )
-Removed a few legacy timer limitations, fix non-working limit (#3301 )
-Default AVR fuse settings changed to disable JTAG interface (#3379 )
-Channel range fix (Start, Channels) in Model Settings, Setup page, int/ext module settings
-Use friendly GVAR names in dialogs (if available) (#3353 )
-Various texts and translations corrections
-
-
-
-Version 2.1.7 / 2016-01-04
-
-
-Lua 'execute' failed in non-root directory (in Simulator) (#3024 )
-
-LR12 changes: removed option for remote failsafe configuration, added in EU firmware variant
-Added Clear option to the flight mode context menu (right click on the Name label) (#3026 )
-New features for Telemetry Simulator: log replay, user friendly sensor values (#3124 )
-Added F7 key to reload LUA permanent scripts in radio simulator (#3141 )
-AR9X firmware flashing fall-back was wrong
-Command line options support added to standalone simulator (try "./simulator21 --help" on Linux and "simulator.exe /help" on Windows for usage) (#3160 )
-Various rounding problem fixed: Telemetry sensor Ratio parameter (#3117 ),
- Outputs Sub-trim, Min and Max values (#3156 )
-Fixed: telemetry sensors Ratio and Offset value increment/decrement step (#3121 )
-Hardware/Calibration tab split int two tabs (#2974 )
-Fixed Fahrenheit temperature conversion error (if PREC was not 0) (#3146 )
-Application Setting 'Enable automatic backup before writing firmware' was not saved (#3040 )
-Fixed RPM package problem on Fedora (#3130 )
-Fixed conversion errors when loading 2.0.x EEPE (#3177 )
-Various texts and translations corrections
-
-
-
-Version 2.1.6 / 2015-11-11
-
-
-Telemetry custom screen changes didn't emit modified signal (#3029 )
-Hide D8/LR12 when eu firmware option is selected
-
-
-
-Version 2.1.5 / 2015-11-05
-
-Notice: version 2.1.4 was skipped by the OpenTX team to avoid confusion with FrSky's release of OpenTX 2.1.4
-
-
-Fixed: changing any setting on the telemetry panel does not set the file as being modified (#2875 )
-Print model fix for "Play value.... not on startup" (#2736 )
-Top LCD Timer could not be selected for X9E (#2850 )
-More informative error/info messages when openin eepe files (#2778 )
-Print model fix for curves (#2896 )
-Added missing special functions (bind, range check, set failsafe) (#2753 )
-Some defaults missing when changing telemetry formula, update propagation issues (#2928 )
-Fixed wrong import of Logical switches from OpenTX 2.0.x version (#2942 )
-Fixed a problem with updates path on Windows (#2876 )
-Edge representation unified (changed from "no release" to "instant") (#2837 )
-Added channel names on failsafe sliders (#3021 )
-Corrected failsafe mapping when using Custom failsafe mode, D16 protocol and channel range different from from 1-8.
- Users with such setups are advised to re-check their failsafe settings (#2975 )
-Various texts and translations corrections
-Various small bug-fixes: #2994 ,
- #3016 ,
- #3012
-
-
-
-
-Version 2.1.3 / 2015-09-09
-
-
-Fix missing translations in inputs/mixes tabs, print and compare dialogs (#2847 )
-
-
-
-Version 2.1.2 / 2015-09-07
-
-
-Fixed: Lua model scripts outputs not working in a simulator (#2684 )
-Fixed a problem of Companion 2.1 trying to install into 2.0 path.
- The effect will only be visible for the users that did not install any of the previous 2.1.x versions.
- (#2645 )
-Added missing SDL libraries to MAC package (#2678 )
-Added used channels check/warning in Wizard (#2091 )
-Model Print and Model Compare improvements and fixes (#2734 , #2737 , #2576 )
-Negative telemetry offset value was reset when writing back to radio (#2738 )
-Telemetry sensor names were not displayed (#2807 )
-Mixes multiplex representation now the same as on the radio (#2808 )
-Fixed language-related startup crash on Mac (#2815 )
-Fixed issues with conversion from 2.0 (#2809 , #2800 )
-Fixed Throttle source export issue on X9E (#2844 )
-Added support for the AR9X replacement board (prototype) for the Turnigy 9X radio, info here
-
-
-
-Version 2.1.1 / 2015-08-06
-
-Vario source and center silent options were not saved(#2476 )
-DSM receiver numbers for external module were not converted from previous version EEPROM (#2474 )
-Precision incorrectly set for Calculated->Cells sensor (#2479 )
-Unit incorrectly set for Calculated->Cells sensor (#2485 )
-Fixed import/export of trim values (#2484 )
-Removed constant access to floppy disk (#2160 )
-Telemetry view script combo box list was empty (#2465 )
-Telemetry view bars ranges not transfered to radio (#2491 )
-Fixed Standalone simulator radio selection display problem (#2503 )
-Added missing simulation libraries and enabled side by side installation of Companion 2.0 and 2.1 on Linux (#2500 )
-Standalone simulator now remembers which radio was simulated in previous session (#2503 )
-Radio calibration value were not displayed (#2502 )
-Fixed Vario / Voltage / Current sources export problem
-Writing model settings to 9XR-PRO did not work (#2402 , #2517 )
-Model Print and Model Compare improvements
-Fixed Companion OSX version (#2549 )
-Firmware nightly builds are now downloadable from nightly builds of Companion (#2526 , #2634 )
-Fixed telemetry item lists (#2541 )
-Fixed missing pots P1..P3 for 9X (#2543 )
-Fixed "Invalid model and settings" error message when writing models and settings to the radio (#2544 )
-Global Functions fixes (#2558 )
-Export to Google Earth now working (only) with the new telemetry fields (GPS, GAlt and GSpd) (#2546 )
-Fixed unsuccessful writing of setting to the radio for 9XR PRO (#2605 )
-Fixed missing LUA script outputs in special function "Play Value" (#2649 )
-Various texts and translations corrections
-Various small bug-fixes
-
-
-
-Version 2.1.0 / 2015-07-16
-
-SD card synchronizaton tool
-Added session duraton information in Log Viewer
-Enabled Mixers monitor in Taranis simulator
-Better support for multi-axes in Log Viewer (#2267 )
-File path issue in Taranis simulator function findTrueFileName() on Windows (#2301 )
-Added simulator volume gain setting (#2260 )
-Added GPS glitch filtering and Latitude/Longitude position synchronization to Google Earth export (#2326 )
-Fixed a rare program crash when editing Input for 9X radio (#2420 )
-Fixed missing RSSI audio warnings if simulator was started multiple times (#2446 )
-
-
-
-Version 2.0.17 / 2015-05-04
-
-Simulator crash (#2253 )
-
-
-
-Version 2.0.16 / 2015-05-03
-
-nooverridech firmware option was not working
-Fixed setting Expo from gvars for 9XR-Pro (#2040 )
-Added Mixers Monitor screen option mixersmon (#1945 )
-Added audio playing in simulator (#457 )
-Fixed sorting of audio tracks (#2002 )
-Model wizard fixes (#2091 )
-GVAR names removed for 9x, radio doesn't support them (#2150 )
-Some LS sources didn't follow the Imperial units setting (#2180 )
-Added more fields to the telemetry simulator (#2171 )
-Log viewer improvements and massive speed increase (#1863 , #2163 )
-Added Battery meter range setting (#2195 )
-Improvements in Print and Compare dialogs (#2219 )
-Reset pots to the middle by right double clicking them in Simulator (#1939 )
-Minor fixes: #2153 ,
- #2138 ,
- #2090 ,
- #2122
-
-
-
-
-Version 2.0.15 / 2015-01-13
-
-Firmware was not written correctly on radio when compatibility warning check enabled
-Time format for Special Functions Set Timers
-
-
-Version 2.0.14 / 2015-01-12
-
-OpenTX Companion and Companion9x can now be installed side by side on Linux
-Improved TAB order in dialogs
-Special Function Start Logs renamed to more appropriate SD Logs
-Improvements for MAC build
-Fixes to Google Earth logs export
-Firmware compatibility warning check added when flashing new firmware to radio
-Fixed issue with Telemetry Type setting on 9XR-PRO
-Added Telemetry simulator
-Added Trainer simulator
-Added Debug Output window
-Various texts and translations corrections
-Various small bug-fixes
-More reliable method of writing EEPROM.BIN and FIRMWARE.BIN to radio
-Fixed issue with Edge function INSTANT for V1>2s
-Fixed buffer overflow in Joystick code
-
-
-Version 2.0.13 / 2014-11-20
-
-Too many curves shown on non ARM boards
-Fixed vario limits
-Fixes in compare dialog
-Fixed receiver number range
-Virtual inputs not selectable in SF Volume and heli Collective Source
-Joystick calibration crash after channel assignment
-Gvar import error for limits
-Companion shows too many curve types in input/mixer for 9x
-NOT curves removed from inputs (for non ARM platforms)
-Companion again builds on OS X (Mac)
-Companion simulator Lua crash on OS X 64bit (Mac)
-Companion didn't take care of PlayScript functions
-
-
-Version 2.0.12 / 2014-09-15
-
-Typos & Translations updated
-
-
-Version 2.0.11 / 2014-09-10
-
-Limits EEPROM export was broken (all boards except Taranis)
-Fix issue when a GVAR was used as Offset
-
-
-Version 2.0.10 / 2014-09-08
-
-Taranis is now the default board in General Settings
-GVARS allowed in Limits min/max/offset
-Limits displayed in us when ppmus option selected
-
-
-Version 2.0.8 / 2014-07-23
-
-Compare dialog bugfixes
-Curve index correctly resetted when type changed
-
-
-Version 2.0.7
-
-SafetyCH function was missing in simulator
-EEPROM export warning when exporting logical switches > L12 on 9X128
-FAS offset was not exported on 9X/9XR boards
-Trims modes bugfix on non Taranis boards
-It was impossible to open a backuped model from the Tx
-
-
-Version 2.0.6
-
-Fix Mix curves bug on Sky9x boards
-Channels 17-32 are displayed in the simulator
-Backlight simulation bugfix
-
-
-Version 2.0.5
-
-Fix crash on startup
-Fix version number in simu
-9XR-Pro now supported on Mac
-Fix loss of settings in telemetry custom screens
-Fix 10000% bug when using GVs in mixer weithg or offset
-Fix Cnsp range in logical switches (up to 30000mAh)
-
-
-Version 2.0.4
-
-Sound should be ok on all platforms
-Min/Max reviewed in Logical switches (for the whole telemetry)
-Various bug fixes
-
-
-Version 2.0.3
-
-EEPROM import bug on AdjustGVAR function
-Timers correctly displayed in logical switches tab
-
-
-Version 2.0.2
-
-Mouse scroll wheel behaves differently
-Play Sounds should now work on all platforms
-A lot of small bug fixes
-
-
-Version 2.0.1
-
-Fix on recursive GVars
-Sky9x EEPROM read/write fix
-Translations updated
- Wizard fixes
- Fix on invalid splashes bitmaps
-
-
-Version 2.0.0
-
-Companion now merged into OpenTX
-Too many changes to list them all!
-
-
-Version 1.52
-
-Fix crash when writing certain EEPROMS
-Google Earth export of logs containing GPS positions
-DSM2 added for Taranis
-
-
-Version 1.51
-
-Wrong DFU-Util default path (MAC)
-new voices download server (ip address changed to new fiber connection)
-Fixed contributor list
-
-
-Version 1.50
-
-solved issue with taranis radio with some linux distributions
-blank eeprom created using a radio profile that holds calibration data, will contain calibration data from the profile
-new opentx compilation server (ip address changed to new fiber connection)
-
-
-Version 1.49
-
-Stack usage optimizations
-Playsound order is misaligned between companion9x and the TX
-Model image could not be reset.
-
-
-Version 1.48
-
-Interface fixes
-Hide include dr/expo when not applicable
-Fix extraction of grayscale images from taranis firmwares
-No TX and RX in Taranis telemetry fields
-Issue 255 fixed - "No GVAR selection possible for PLAY VALUE"
-Issue 254 fixed - "SE Language for building opentx"
-Issue 253 fixed - "OpenTX doesn't accept this protocol (DSM2 on Sky9x)"
-Prevent segfault while parsing wrong log files or files with broken lines
-Small bug in model printout
-Fixed wrong display of values in custom functions
-Image in preferences was saved only black & white
-Issue 247 fixed - "Labelled items on radio should not be translated."
-Added support of tstick (taranis like stick) compile option for sky9x opentx firmware
-
-
-Version 1.47
-
-Interface fixes (issues 232,233,238,241)
-Fix for print/compare models
-Function switch parameter on screen different than printout.
-Translations fixes
-Command line print mode
-Better mavlink support
-SE tts language added for taranis
-Alternate font option for opentx added
-
-
-
-Version 1.46
-
-Interface fixes (issues 224,225)
-Show persistent timers value in modeledit
-Consistent naming of Custom Switches in c9x
-
-
-Version 1.45
-
-
-Version 1.44
-
-Fix regression on AND parameter in custom functions
-Add mavlink support for stock and m128 boards
-
-
-Version 1.43
-
-Copy Malfunctions in Custom Functions (Issue 205)
-Enable repeat parameter in functions for all boards
-Remove sink tones from vario for stock/m128 board
-Fix for wrongly named channels in mixerlist (Issue 210)
-Fix badly exported gvars in mixers
-Fix while editing custom switches
-Add access to the release notes of currently selected firmware
-
-
-Version 1.42
-
-Add Companion9X changelog
-Add Fw release notes browser
-Simplify burn menu for sky9x and Taranis.
-Fix in telemetry conversion (rssi alarm) for stock board
-Drop support of sky9x boards on MacOS due to missing SAM-BA tool.
-
-
-Version 1.41
-
-Fix unneeded rescaling of splash images
-Fix for telemetry screens for Taranis
-
-
-Version 1.40
-
-Log dialog - Split of logging sessions.
-Telemetry screen 1 as default (issue 206)
-Rename all channels in mixer tab accordingly to limits names
-Fix a segfault in phases tabs (Issue 203 regression introduced in release 2140)
-
-
-Version 1.39
-
-Custom functions cut&paste
-Custom switches cut&paste
-Color button text in curve editor for MACOSX
-Adjust name lengths for Taranis
-
-
-Version 1.38
-
-Core when model names were > 10 chars
-
-
-Version 1.37
-
-Fix OpenTX segfault in Taranis simulator
-Implement brightness control for Taranis
-Reduce modeledit windows size
-Taranis splash screen in grayscale
-
-
-Version 1.36
-
-Burning windows (with progress bar) now in foreground (Issue 197)
-Allow a selection of tracks for Background Music (Issue 199)
-
-
-Version 1.35
-
-Country names mismatch between Taranis and Companion 9X (Issue 198)
-TIM function in custom switches
-Fix timer switches.
-Taranis LCD adjustment in general settings.
-New tool in curve editor
-Minor fixes
-Expo move bug + invalid chars in channels, expo and mixer names
-Try to reduce modeledit window form MAC
-Wrong init of RF-Module data
-Read flash from TX didn't worked for Taranis
-
diff --git a/companion/src/companion.qrc b/companion/src/companion.qrc
index b78cf3506..bd395a443 100644
--- a/companion/src/companion.qrc
+++ b/companion/src/companion.qrc
@@ -2,7 +2,6 @@
images/customize.png
images/icon.png
- ../releasenotes.txt
images/screenshot.png
images/splash.png
images/companion-title.png
@@ -191,6 +190,8 @@
themes/monochrome/16/stop.png
themes/monochrome/16/write_eeprom.png
themes/monochrome/16/sdsync.png
+ themes/monochrome/16/folder-tree-read.png
+ themes/monochrome/16/folder-tree-write.png
themes/monochrome/24/paintbrush.png
themes/monochrome/24/open.png
themes/monochrome/24/edit.png
@@ -235,6 +236,8 @@
themes/monochrome/24/stop.png
themes/monochrome/24/write_eeprom.png
themes/monochrome/24/sdsync.png
+ themes/monochrome/24/folder-tree-read.png
+ themes/monochrome/24/folder-tree-write.png
themes/monochrome/32/paintbrush.png
themes/monochrome/32/open.png
themes/monochrome/32/edit.png
@@ -279,6 +282,8 @@
themes/monochrome/32/stop.png
themes/monochrome/32/write_eeprom.png
themes/monochrome/32/sdsync.png
+ themes/monochrome/32/folder-tree-read.png
+ themes/monochrome/32/folder-tree-write.png
themes/monochrome/48/paintbrush.png
themes/monochrome/48/open.png
themes/monochrome/48/edit.png
@@ -323,6 +328,8 @@
themes/monochrome/48/stop.png
themes/monochrome/48/write_eeprom.png
themes/monochrome/48/sdsync.png
+ themes/monochrome/48/folder-tree-read.png
+ themes/monochrome/48/folder-tree-write.png
themes/classic/16/paintbrush.png
themes/classic/16/open.png
themes/classic/16/edit.png
@@ -367,6 +374,8 @@
themes/classic/16/stop.png
themes/classic/16/write_eeprom.png
themes/classic/16/sdsync.png
+ themes/classic/16/folder-tree-read.png
+ themes/classic/16/folder-tree-write.png
themes/classic/24/paintbrush.png
themes/classic/24/open.png
themes/classic/24/edit.png
@@ -411,6 +420,8 @@
themes/classic/24/stop.png
themes/classic/24/write_eeprom.png
themes/classic/24/sdsync.png
+ themes/classic/24/folder-tree-read.png
+ themes/classic/24/folder-tree-write.png
themes/classic/32/paintbrush.png
themes/classic/32/open.png
themes/classic/32/edit.png
@@ -455,6 +466,8 @@
themes/classic/32/stop.png
themes/classic/32/write_eeprom.png
themes/classic/32/sdsync.png
+ themes/classic/32/folder-tree-read.png
+ themes/classic/32/folder-tree-write.png
themes/classic/48/paintbrush.png
themes/classic/48/open.png
themes/classic/48/edit.png
@@ -499,6 +512,8 @@
themes/classic/48/stop.png
themes/classic/48/write_eeprom.png
themes/classic/48/sdsync.png
+ themes/classic/48/folder-tree-read.png
+ themes/classic/48/folder-tree-write.png
themes/monoblue/16/paintbrush.png
themes/monoblue/16/open.png
themes/monoblue/16/edit.png
@@ -543,6 +558,8 @@
themes/monoblue/16/stop.png
themes/monoblue/16/write_eeprom.png
themes/monoblue/16/sdsync.png
+ themes/monoblue/16/folder-tree-read.png
+ themes/monoblue/16/folder-tree-write.png
themes/monoblue/24/paintbrush.png
themes/monoblue/24/open.png
themes/monoblue/24/edit.png
@@ -587,6 +604,8 @@
themes/monoblue/24/stop.png
themes/monoblue/24/write_eeprom.png
themes/monoblue/24/sdsync.png
+ themes/monoblue/24/folder-tree-read.png
+ themes/monoblue/24/folder-tree-write.png
themes/monoblue/32/paintbrush.png
themes/monoblue/32/open.png
themes/monoblue/32/edit.png
@@ -631,6 +650,8 @@
themes/monoblue/32/stop.png
themes/monoblue/32/write_eeprom.png
themes/monoblue/32/sdsync.png
+ themes/monoblue/32/folder-tree-read.png
+ themes/monoblue/32/folder-tree-write.png
themes/monoblue/48/paintbrush.png
themes/monoblue/48/open.png
themes/monoblue/48/edit.png
@@ -675,6 +696,8 @@
themes/monoblue/48/stop.png
themes/monoblue/48/write_eeprom.png
themes/monoblue/48/sdsync.png
+ themes/monoblue/48/folder-tree-read.png
+ themes/monoblue/48/folder-tree-write.png
themes/monowhite/16/paintbrush.png
themes/monowhite/16/open.png
themes/monowhite/16/edit.png
@@ -719,6 +742,8 @@
themes/monowhite/16/stop.png
themes/monowhite/16/write_eeprom.png
themes/monowhite/16/sdsync.png
+ themes/monowhite/16/folder-tree-read.png
+ themes/monowhite/16/folder-tree-write.png
themes/monowhite/24/paintbrush.png
themes/monowhite/24/open.png
themes/monowhite/24/edit.png
@@ -763,6 +788,8 @@
themes/monowhite/24/stop.png
themes/monowhite/24/write_eeprom.png
themes/monowhite/24/sdsync.png
+ themes/monowhite/24/folder-tree-read.png
+ themes/monowhite/24/folder-tree-write.png
themes/monowhite/32/paintbrush.png
themes/monowhite/32/open.png
themes/monowhite/32/edit.png
@@ -807,6 +834,8 @@
themes/monowhite/32/stop.png
themes/monowhite/32/write_eeprom.png
themes/monowhite/32/sdsync.png
+ themes/monowhite/32/folder-tree-read.png
+ themes/monowhite/32/folder-tree-write.png
themes/monowhite/48/paintbrush.png
themes/monowhite/48/open.png
themes/monowhite/48/edit.png
@@ -851,6 +880,8 @@
themes/monowhite/48/stop.png
themes/monowhite/48/write_eeprom.png
themes/monowhite/48/sdsync.png
+ themes/monowhite/48/folder-tree-read.png
+ themes/monowhite/48/folder-tree-write.png
themes/yerico/16/paintbrush.png
themes/yerico/16/open.png
themes/yerico/16/edit.png
@@ -895,6 +926,8 @@
themes/yerico/16/stop.png
themes/yerico/16/write_eeprom.png
themes/yerico/16/sdsync.png
+ themes/yerico/16/folder-tree-read.png
+ themes/yerico/16/folder-tree-write.png
themes/yerico/24/paintbrush.png
themes/yerico/24/open.png
themes/yerico/24/edit.png
@@ -939,6 +972,8 @@
themes/yerico/24/stop.png
themes/yerico/24/write_eeprom.png
themes/yerico/24/sdsync.png
+ themes/yerico/24/folder-tree-read.png
+ themes/yerico/24/folder-tree-write.png
themes/yerico/32/paintbrush.png
themes/yerico/32/open.png
themes/yerico/32/edit.png
@@ -983,6 +1018,8 @@
themes/yerico/32/stop.png
themes/yerico/32/write_eeprom.png
themes/yerico/32/sdsync.png
+ themes/yerico/32/folder-tree-read.png
+ themes/yerico/32/folder-tree-write.png
themes/yerico/48/paintbrush.png
themes/yerico/48/open.png
themes/yerico/48/edit.png
@@ -1027,6 +1064,8 @@
themes/yerico/48/stop.png
themes/yerico/48/write_eeprom.png
themes/yerico/48/sdsync.png
+ themes/yerico/48/folder-tree-read.png
+ themes/yerico/48/folder-tree-write.png
sounds/0.wav
sounds/1.wav
sounds/2.wav
diff --git a/companion/src/images/originals/folder-tree-read-classic.svg b/companion/src/images/originals/folder-tree-read-classic.svg
new file mode 100644
index 000000000..99bdf8f32
--- /dev/null
+++ b/companion/src/images/originals/folder-tree-read-classic.svg
@@ -0,0 +1,162 @@
+
+
+
+
diff --git a/companion/src/images/originals/folder-tree-read-monochrome.svg b/companion/src/images/originals/folder-tree-read-monochrome.svg
new file mode 100644
index 000000000..61bbd4967
--- /dev/null
+++ b/companion/src/images/originals/folder-tree-read-monochrome.svg
@@ -0,0 +1,66 @@
+
+
+
+
diff --git a/companion/src/images/originals/folder-tree-read-outline.svg b/companion/src/images/originals/folder-tree-read-outline.svg
new file mode 100644
index 000000000..4411f60e4
--- /dev/null
+++ b/companion/src/images/originals/folder-tree-read-outline.svg
@@ -0,0 +1,110 @@
+
+
+
+
diff --git a/companion/src/images/originals/folder-tree-read-yerico.svg b/companion/src/images/originals/folder-tree-read-yerico.svg
new file mode 100644
index 000000000..9128da187
--- /dev/null
+++ b/companion/src/images/originals/folder-tree-read-yerico.svg
@@ -0,0 +1,111 @@
+
+
+
+
diff --git a/companion/src/images/originals/folder-tree-write-classic.svg b/companion/src/images/originals/folder-tree-write-classic.svg
new file mode 100644
index 000000000..c1fcb7a5a
--- /dev/null
+++ b/companion/src/images/originals/folder-tree-write-classic.svg
@@ -0,0 +1,162 @@
+
+
+
+
diff --git a/companion/src/images/originals/folder-tree-write-monochrome.svg b/companion/src/images/originals/folder-tree-write-monochrome.svg
new file mode 100644
index 000000000..1ef1dac65
--- /dev/null
+++ b/companion/src/images/originals/folder-tree-write-monochrome.svg
@@ -0,0 +1,66 @@
+
+
+
+
diff --git a/companion/src/images/originals/folder-tree-write-outline.svg b/companion/src/images/originals/folder-tree-write-outline.svg
new file mode 100644
index 000000000..e9a703d9d
--- /dev/null
+++ b/companion/src/images/originals/folder-tree-write-outline.svg
@@ -0,0 +1,108 @@
+
+
+
+
diff --git a/companion/src/images/originals/folder-tree-write-yerico.svg b/companion/src/images/originals/folder-tree-write-yerico.svg
new file mode 100644
index 000000000..4318c5ea2
--- /dev/null
+++ b/companion/src/images/originals/folder-tree-write-yerico.svg
@@ -0,0 +1,111 @@
+
+
+
+
diff --git a/companion/src/mainwindow.cpp b/companion/src/mainwindow.cpp
index 542b15d73..362bed837 100644
--- a/companion/src/mainwindow.cpp
+++ b/companion/src/mainwindow.cpp
@@ -90,7 +90,7 @@ MainWindow::MainWindow():
if (g.isFirstUse()) {
g.warningId(g.warningId() | AppMessages::MSG_WELCOME);
- QTimer::singleShot(updateDelay-500, this, SLOT(appPrefs())); // must be shown before warnings dialog but after splash
+ QTimer::singleShot(updateDelay-500, this, SLOT(editAppSettings())); // must be shown before warnings dialog but after splash
}
else {
if (!g.previousVersion().isEmpty())
@@ -205,7 +205,7 @@ void MainWindow::closeEvent(QCloseEvent *event)
#endif
g.mainWinGeo(saveGeometry());
g.mainWinState(saveState());
- g.tabbedMdi(actTabbedWindows->isChecked());
+ g.tabbedMdi(tabbedWindowsAct->isChecked());
QApplication::closeAllWindows();
mdiArea->closeAllSubWindows();
if (mdiArea->currentSubWindow()) {
@@ -255,7 +255,7 @@ void MainWindow::manualCheckForUpdates()
statusBar()->clearMessage();
}
-void MainWindow::downloads()
+void MainWindow::updates()
{
doUpdates(false);
}
@@ -325,13 +325,13 @@ void MainWindow::onIconSizeChanged(QAction * act)
void MainWindow::setTabbedWindows(bool on)
{
mdiArea->setViewMode(on ? QMdiArea::TabbedView : QMdiArea::SubWindowView);
- if (actTileWindows)
- actTileWindows->setDisabled(on);
- if (actCascadeWindows)
- actCascadeWindows->setDisabled(on);
+ if (tileWindowsAct)
+ tileWindowsAct->setDisabled(on);
+ if (cascadeWindowsAct)
+ cascadeWindowsAct->setDisabled(on);
- if (actTabbedWindows->isChecked() != on)
- actTabbedWindows->setChecked(on);
+ if (tabbedWindowsAct->isChecked() != on)
+ tabbedWindowsAct->setChecked(on);
}
void MainWindow::newFile()
@@ -452,7 +452,7 @@ void MainWindow::loadProfile()
}
}
-void MainWindow::appPrefs()
+void MainWindow::editAppSettings()
{
AppPreferencesDialog * dialog = new AppPreferencesDialog(this, updateFactories);
dialog->setMainWinHasDirtyChild(anyChildrenDirty());
@@ -460,6 +460,7 @@ void MainWindow::appPrefs()
connect(dialog, &AppPreferencesDialog::firmwareProfileChanged, this, &MainWindow::onCurrentProfileChanged);
dialog->exec();
dialog->deleteLater();
+ updateMenus();
}
void MainWindow::sdsync(bool postUpdate)
@@ -677,9 +678,11 @@ void MainWindow::updateMenus()
compareAct->setEnabled(activeChild);
writeSettingsAct->setEnabled(activeChild);
readSettingsAct->setEnabled(true);
+ writeSettingsSDPathAct->setEnabled(activeChild && isSDPathValid());
+ readSettingsSDPathAct->setEnabled(isSDPathValid());
writeBUToRadioAct->setEnabled(false);
readBUToFileAct->setEnabled(false);
- editSplashAct->setDisabled(IS_FAMILY_HORUS_OR_T16(getCurrentBoard()));
+ editSplashAct->setDisabled(Boards::getBoardCapability(getCurrentBoard(), Board::HasColorLcd));
foreach (QAction * act, fileWindowActions) {
if (!act)
@@ -692,34 +695,39 @@ void MainWindow::updateMenus()
if (act->isSeparator() && act->parent() == this)
delete act;
}
- fileWindowActions.clear();
- if (activeChild) {
- editMenu->clear();
- editMenu->addActions(activeMdiChild()->getEditActions());
- editMenu->addSeparator();
- editMenu->addActions(activeMdiChild()->getModelActions()); // maybe separate menu/toolbar?
- editMenu->setEnabled(true);
- editToolBar->clear();
- editToolBar->addActions(activeMdiChild()->getEditActions());
- editToolBar->setEnabled(true);
+ fileWindowActions.clear();
+
+ if (activeChild) {
+ modelsMenu->clear();
+ modelsMenu->addActions(activeMdiChild()->getEditActions());
+ modelsMenu->addSeparator();
+ modelsMenu->addActions(activeMdiChild()->getModelActions()); // maybe separate menu/toolbar?
+ modelsMenu->addAction(compareAct);
+ modelsMenu->setEnabled(true);
+
+ modelsToolBar->clear();
+ modelsToolBar->addActions(activeMdiChild()->getEditActions());
+ modelsToolBar->addAction(compareAct);
+ modelsToolBar->setEnabled(true);
+
if (activeMdiChild()->getAction(MdiChild::ACT_MDL_MOV)) {
// workaround for default split button appearance of action with menu :-/
QToolButton * btn;
- if ((btn = qobject_cast(editToolBar->widgetForAction(activeMdiChild()->getAction(MdiChild::ACT_MDL_MOV)))))
+ if ((btn = qobject_cast(modelsToolBar->widgetForAction(activeMdiChild()->getAction(MdiChild::ACT_MDL_MOV)))))
btn->setPopupMode(QToolButton::InstantPopup);
}
fileWindowActions = activeMdiChild()->getGeneralActions();
QAction *sep = new QAction(this);
sep->setSeparator(true);
- fileWindowActions.append(sep);
- fileMenu->insertActions(logsAct, fileWindowActions);
- fileToolBar->insertActions(logsAct, fileWindowActions);
+ fileWindowActions.insert(0, sep);
+ radioMenu->addActions(fileWindowActions);
+ modelsToolBar->addActions(fileWindowActions); // do not put these in radio toolbar
}
else {
- editToolBar->setDisabled(true);
- editMenu->setDisabled(true);
+ modelsToolBar->setDisabled(true);
+ modelsMenu->setDisabled(true);
}
foreach (QAction * act, windowsListActions->actions()) {
@@ -732,7 +740,7 @@ void MainWindow::updateMenus()
updateRecentFileActions();
updateProfilesActions();
- setWindowTitle(tr("EdgeTX Companion %1 - Radio: %2 - Profile: %3").arg(VERSION).arg(getCurrentFirmware()->getName()).arg(g.profile[g.id()].name()));
+ setWindowTitle(tr("%1 %2 - Radio: %3 - Profile: %4").arg(CPN_STR_APP_NAME).arg(VERSION).arg(getCurrentFirmware()->getName()).arg(g.profile[g.id()].name()));
}
MdiChild * MainWindow::createMdiChild()
@@ -801,59 +809,70 @@ void MainWindow::trAct(QAction * act, const QString & text, const QString & desc
void MainWindow::retranslateUi(bool showMsg)
{
- trAct(newAct, tr("New"), tr("Create a new Models and Settings file"));
- trAct(openAct, tr("Open..."), tr("Open Models and Settings file"));
- trAct(saveAct, tr("Save"), tr("Save Models and Settings file"));
- trAct(saveAsAct, tr("Save As..."), tr("Save Models and Settings file"));
- trAct(closeAct, tr("Close"), tr("Close Models and Settings file"));
- trAct(exitAct, tr("Exit"), tr("Exit the application"));
- trAct(aboutAct, tr("About Companion..."), tr("Show the application's About box"));
+ trAct(newAct, tr("New"), tr("Create a new Models and Settings file"));
+ trAct(openAct, tr("Open..."), tr("Open an existing Models and Settings file"));
+ trAct(saveAct, tr("Save"), tr("Save to Models and Settings file"));
+ trAct(saveAsAct, tr("Save As..."), tr("Save Models and Settings to another file name"));
+ trAct(closeAct, tr("Close"), tr("Close Models and Settings file"));
+ trAct(recentFilesAct, tr("Recent Files"), tr("List of recently used files"));
+ trAct(writeSettingsSDPathAct, tr("Write Models and Settings to SD Path"), tr("Write Models and Settings to SD Path"));
+ trAct(readSettingsSDPathAct, tr("Read Models and Settings from SD Path"), tr("Read Models and Settings from SD Path"));
+ trAct(exitAct, tr("Exit"), tr("Exit the application"));
- trAct(recentFilesAct, tr("Recent Files"), tr("List of recently used files"));
- trAct(profilesMenuAct, tr("Radio Profiles"), tr("Create or Select Radio Profiles"));
- trAct(logsAct, tr("View Log File..."), tr("Open and view log file"));
- trAct(appPrefsAct, tr("Settings..."), tr("Edit Settings"));
- trAct(downloadsAct, tr("Download components..."), tr("Download EdgeTX components and supporting resources"));
- trAct(manualChkForUpdAct, tr("Check for updates..."), tr("Check for updates to EdgeTX and supporting resources"));
- trAct(changelogAct, tr("Release notes..."), tr("Show release notes"));
- trAct(compareAct, tr("Compare Models..."), tr("Compare models"));
- trAct(editSplashAct, tr("Edit Radio Splash Image..."), tr("Edit the splash image of your Radio"));
- trAct(readFlashAct, tr("Read Firmware from Radio"), tr("Read firmware from Radio"));
- trAct(writeFlashAct, tr("Write Firmware to Radio"), tr("Write firmware to Radio"));
- trAct(sdsyncAct, tr("Synchronize SD"), tr("SD card synchronization"));
+ trAct(editAppSettingsAct, tr("Edit Settings..."), tr("Edit %1 and Simulator settings (including radio profiles) settings").arg(CPN_STR_APP_NAME));
+ trAct(exportAppSettingsAct, tr("Export Settings..."), tr("Save all the current %1 and Simulator settings (including radio profiles) to a file.").arg(CPN_STR_APP_NAME));
+ trAct(importAppSettingsAct, tr("Import Settings..."), tr("Load %1 and Simulator settings from a prevously exported settings file.").arg(CPN_STR_APP_NAME));
- //trAct(openDocURLAct, tr("Manuals and other Documents"), tr("Open the EdgeTX document page in a web browser"));
- trAct(writeSettingsAct, tr("Write Models and Settings To Radio"), tr("Write Models and Settings to Radio"));
- trAct(readSettingsAct, tr("Read Models and Settings From Radio"), tr("Read Models and Settings from Radio"));
- trAct(burnConfigAct, tr("Configure Communications..."), tr("Configure software for communicating with the Radio"));
+ trAct(burnConfigAct, tr("Configure Radio Communications..."), tr("Configure Companion for communicating with the Radio"));
+ trAct(editSplashAct, tr("Edit Radio Splash Image..."), tr("Edit the splash image of your Radio"));
+ trAct(readFlashAct, tr("Read Firmware from Radio"), tr("Read firmware from Radio"));
+ trAct(writeFlashAct, tr("Write Firmware to Radio"), tr("Write firmware to Radio"));
+ trAct(writeSettingsAct, tr("Write Models and Settings to Radio"), tr("Write Models and Settings to Radio"));
+ trAct(readSettingsAct, tr("Read Models and Settings from Radio"), tr("Read Models and Settings from Radio"));
trAct(writeBUToRadioAct, tr("Write Backup to Radio"), tr("Write Backup from file to Radio"));
trAct(readBUToFileAct, tr("Backup Radio to File"), tr("Save a complete backup file of all settings and model data in the Radio"));
+ trAct(compareAct, tr("Compare Models"), tr("Compare models"));
+ trAct(updatesAct, tr("Update components..."), tr("Download and update EdgeTX components and supporting resources"));
+ trAct(sdsyncAct, tr("Synchronize SD card..."), tr("SD card synchronization"));
+ trAct(logsAct, tr("View Log File..."), tr("Open and view log file"));
+
+ trAct(profilesMenuAct, tr("Radio Profiles"), tr("Create or Select Radio Profiles"));
trAct(createProfileAct, tr("Add Radio Profile"), tr("Create a new Radio Settings Profile"));
trAct(copyProfileAct, tr("Copy Current Radio Profile"), tr("Duplicate current Radio Settings Profile"));
trAct(deleteProfileAct, tr("Delete Current Radio Profile..."), tr("Delete the current Radio Settings Profile"));
- trAct(exportSettingsAct, tr("Export Application Settings.."), tr("Save all the current %1 and Simulator settings (including radio profiles) to a file.").arg(CPN_STR_APP_NAME));
- trAct(importSettingsAct, tr("Import Application Settings.."), tr("Load %1 and Simulator settings from a prevously exported settings file.").arg(CPN_STR_APP_NAME));
+ trAct(viewFileToolbarAct, tr("File Toolbar"), tr("Configure File toolbar visibility"));
+ trAct(viewModelsToolbarAct, tr("Models Toolbar"), tr("Configure Models toolbar visibility"));
+ trAct(viewRadioToolbarAct, tr("Radio Toolbar"), tr("Configure Radio toolbar visibility"));
+ trAct(viewSettingsToolbarAct, tr("Settings Toolbar"), tr("Configure Settings toolbar visibility"));
+ trAct(viewToolsToolbarAct, tr("Tools Toolbar"), tr("Configure Tools toolbar visibility"));
- trAct(actTabbedWindows, tr("Tabbed Windows"), tr("Use tabs to arrange open windows."));
- trAct(actTileWindows, tr("Tile Windows"), tr("Arrange open windows across all the available space."));
- trAct(actCascadeWindows, tr("Cascade Windows"), tr("Arrange all open windows in a stack."));
- trAct(actCloseAllWindows, tr("Close All Windows"), tr("Closes all open files (prompts to save if necessary."));
+ trAct(tabbedWindowsAct, tr("Tabbed Windows"), tr("Use tabs to arrange open windows."));
+ trAct(tileWindowsAct, tr("Tile Windows"), tr("Arrange open windows across all the available space."));
+ trAct(cascadeWindowsAct, tr("Cascade Windows"), tr("Arrange all open windows in a stack."));
+ trAct(closeAllWindowsAct, tr("Close All Windows"), tr("Closes all open files (prompts to save if necessary."));
+
+ trAct(manualChkForUpdAct, tr("Check for updates..."), tr("Check for updates to EdgeTX and supporting resources"));
+ trAct(changelogAct, tr("Release notes..."), tr("Show release notes"));
+ trAct(aboutAct, tr("About"), tr("Show the application's About box"));
- editMenu->setTitle(tr("Edit"));
fileMenu->setTitle(tr("File"));
+ viewMenu->setTitle(tr("View"));
+ modelsMenu->setTitle(tr("Models"));
settingsMenu->setTitle(tr("Settings"));
themeMenu->setTitle(tr("Set Icon Theme"));
iconThemeSizeMenu->setTitle(tr("Set Icon Size"));
- burnMenu->setTitle(tr("Read/Write"));
+ radioMenu->setTitle(tr("Radio"));
+ toolsMenu->setTitle(tr("Tools"));
windowMenu->setTitle(tr("Window"));
helpMenu->setTitle(tr("Help"));
fileToolBar->setWindowTitle(tr("File"));
- editToolBar->setWindowTitle(tr("Edit"));
- burnToolBar->setWindowTitle(tr("Write"));
- helpToolBar->setWindowTitle(tr("Help"));
+ modelsToolBar->setWindowTitle(tr("Models"));
+ radioToolBar->setWindowTitle(tr("Radio"));
+ settingsToolBar->setWindowTitle(tr("Settings"));
+ toolsToolBar->setWindowTitle(tr("Tools"));
showReadyStatus();
@@ -863,60 +882,71 @@ void MainWindow::retranslateUi(bool showMsg)
void MainWindow::createActions()
{
- newAct = addAct("new.png", SLOT(newFile()), QKeySequence::New);
- openAct = addAct("open.png", SLOT(openFile()), QKeySequence::Open);
- saveAct = addAct("save.png", SLOT(save()), QKeySequence::Save);
- saveAsAct = addAct("saveas.png", SLOT(saveAs()), tr("Ctrl+Shift+S")); // Windows doesn't have "native" save-as key, Lin/OSX both use this one anyway
- closeAct = addAct("clear.png", SLOT(closeFile()) /*, QKeySequence::Close*/); // setting/showing this shortcut interferes with the system one (Ctrl+W/Ctrl-F4)
- exitAct = addAct("exit.png", SLOT(closeAllWindows()), QKeySequence::Quit, qApp);
+ newAct = addAct("new.png", SLOT(newFile()), QKeySequence::New);
+ openAct = addAct("open.png", SLOT(openFile()), QKeySequence::Open);
+ saveAct = addAct("save.png", SLOT(save()), QKeySequence::Save);
+ saveAsAct = addAct("saveas.png", SLOT(saveAs()), tr("Ctrl+Shift+S")); // Windows doesn't have "native" save-as key, Lin/OSX both use this one anyway
+ // assigned menus in createMenus()
+ recentFilesAct = addAct("recentdocument.png");
+ closeAct = addAct("clear.png", SLOT(closeFile()) /*, QKeySequence::Close*/); // setting/showing this shortcut interferes with the system one (Ctrl+W/Ctrl-F4)
+ // TODO change to more appropriate icon sets and uncomment toolbar actions
+ writeSettingsSDPathAct = addAct("folder-tree-write.png", SLOT(writeSettingsSDPath()));
+ readSettingsSDPathAct = addAct("folder-tree-read.png", SLOT(readSettingsSDPath()));
+ // end TODO
+ exitAct = addAct("exit.png", SLOT(closeAllWindows()), QKeySequence::Quit, qApp);
- logsAct = addAct("logs.png", SLOT(logFile()), tr("Ctrl+Alt+L"));
- appPrefsAct = addAct("apppreferences.png", SLOT(appPrefs()), QKeySequence::Preferences);
- downloadsAct = addAct("download.png", SLOT(downloads()), tr("Ctrl+Alt+D"));
- compareAct = addAct("compare.png", SLOT(compare()), tr("Ctrl+Alt+R"));
- sdsyncAct = addAct("sdsync.png", SLOT(sdsync()));
+ editAppSettingsAct = addAct("apppreferences.png", SLOT(editAppSettings()), QKeySequence::Preferences);
+ exportAppSettingsAct = addAct("saveas.png", SLOT(exportAppSettings()));
+ importAppSettingsAct = addAct("open.png", SLOT(importAppSettings()));
+ burnConfigAct = addAct("configure.png", SLOT(burnConfig()));
- editSplashAct = addAct("paintbrush.png", SLOT(customizeSplash()));
- burnListAct = addAct("list.png", SLOT(burnList()));
- readFlashAct = addAct("read_flash.png", SLOT(readFlash()));
- writeFlashAct = addAct("write_flash.png", SLOT(writeFlash()));
- writeSettingsAct = addAct("write_eeprom.png", SLOT(writeSettings()));
- readSettingsAct = addAct("read_eeprom.png", SLOT(readSettings()));
- burnConfigAct = addAct("configure.png", SLOT(burnConfig()));
+ compareAct = addAct("compare.png", SLOT(compare()), tr("Ctrl+Alt+R"));
+ updatesAct = addAct("download.png", SLOT(updates()), tr("Ctrl+Alt+D"));
+ editSplashAct = addAct("paintbrush.png", SLOT(customizeSplash()));
+ // assigned menus in createMenus()
+ profilesMenuAct = addAct("profiles.png");
+ createProfileAct = addAct("new.png", SLOT(createProfile()));
+ copyProfileAct = addAct("copy.png", SLOT(copyProfile()));
+ deleteProfileAct = addAct("clear.png", SLOT(deleteCurrentProfile()));
+ sdsyncAct = addAct("sdsync.png", SLOT(sdsync()));
+ logsAct = addAct("logs.png", SLOT(logFile()), tr("Ctrl+Alt+L"));
- writeBUToRadioAct = addAct("write_eeprom_file.png", SLOT(writeBackup()));
- readBUToFileAct = addAct("read_eeprom_file.png", SLOT(readBackup()));
+ burnListAct = addAct("list.png", SLOT(burnList()));
+ readFlashAct = addAct("read_flash.png", SLOT(readFlash()));
+ writeFlashAct = addAct("write_flash.png", SLOT(writeFlash()));
+ writeSettingsAct = addAct("write_eeprom.png", SLOT(writeSettings()));
+ readSettingsAct = addAct("read_eeprom.png", SLOT(readSettings()));
+ writeBUToRadioAct = addAct("write_eeprom_file.png", SLOT(writeBackup()));
+ readBUToFileAct = addAct("read_eeprom_file.png", SLOT(readBackup()));
- createProfileAct = addAct("new.png", SLOT(createProfile()));
- copyProfileAct = addAct("copy.png", SLOT(copyProfile()));
- deleteProfileAct = addAct("clear.png", SLOT(deleteCurrentProfile()));
+ viewFileToolbarAct = addAct("", SLOT(viewFileToolbar()));
+ viewModelsToolbarAct = addAct("", SLOT(viewModelsToolbar()));
+ viewRadioToolbarAct = addAct("", SLOT(viewRadioToolbar()));
+ viewSettingsToolbarAct = addAct("", SLOT(viewSettingsToolbar()));
+ viewToolsToolbarAct = addAct("", SLOT(viewToolsToolbar()));
- exportSettingsAct = addAct("saveas.png", SLOT(exportSettings()));
- importSettingsAct = addAct("open.png", SLOT(importSettings()));
+ tabbedWindowsAct = addAct("", SLOT(setTabbedWindows(bool)), 0, this, SIGNAL(triggered(bool)));
+ tileWindowsAct = addAct("", SLOT(tileSubWindows()), 0, mdiArea);
+ cascadeWindowsAct = addAct("", SLOT(cascadeSubWindows()), 0, mdiArea);
+ closeAllWindowsAct = addAct("", SLOT(closeAllSubWindows()), 0, mdiArea);
- actTabbedWindows = addAct("", SLOT(setTabbedWindows(bool)), 0, this, SIGNAL(triggered(bool)));
- actTileWindows = addAct("", SLOT(tileSubWindows()), 0, mdiArea);
- actCascadeWindows = addAct("", SLOT(cascadeSubWindows()), 0, mdiArea);
- actCloseAllWindows = addAct("", SLOT(closeAllSubWindows()), 0, mdiArea);
-
- manualChkForUpdAct = addAct("update.png", SLOT(manualCheckForUpdates()));
- aboutAct = addAct("information.png", SLOT(about()));
- //openDocURLAct = addAct("changelog.png", SLOT(openDocURL()));
- changelogAct = addAct("changelog.png", SLOT(changelog()));
-
- // these two get assigned menus in createMenus()
- recentFilesAct = addAct("recentdocument.png");
- profilesMenuAct = addAct("profiles.png");
+ manualChkForUpdAct = addAct("update.png", SLOT(manualCheckForUpdates()));
+ changelogAct = addAct("changelog.png", SLOT(changelog()));
+ aboutAct = addAct("information.png", SLOT(about()));
exitAct->setMenuRole(QAction::QuitRole);
aboutAct->setMenuRole(QAction::AboutRole);
- appPrefsAct->setMenuRole(QAction::PreferencesRole);
- //openDocURLAct->setMenuRole(QAction::ApplicationSpecificRole);
- //manualChkForUpdAct->setMenuRole(QAction::ApplicationSpecificRole);
+ editAppSettingsAct->setMenuRole(QAction::PreferencesRole);
changelogAct->setMenuRole(QAction::ApplicationSpecificRole);
- actTabbedWindows->setCheckable(true);
compareAct->setEnabled(false);
+
+ setActCheckability(tabbedWindowsAct, false);
+ setActCheckability(viewFileToolbarAct, g.fileToolbarVisible());
+ setActCheckability(viewModelsToolbarAct, g.modelsToolbarVisible());
+ setActCheckability(viewRadioToolbarAct, g.radioToolbarVisible());
+ setActCheckability(viewSettingsToolbarAct, g.settingsToolbarVisible());
+ setActCheckability(viewToolsToolbarAct, g.toolsToolbarVisible());
}
void MainWindow::createMenus()
@@ -929,19 +959,23 @@ void MainWindow::createMenus()
fileMenu->addAction(closeAct);
fileMenu->addAction(recentFilesAct);
fileMenu->addSeparator();
- fileMenu->addAction(logsAct);
- fileMenu->addAction(downloadsAct);
- fileMenu->addAction(compareAct);
- fileMenu->addAction(sdsyncAct);
+ fileMenu->addAction(readSettingsSDPathAct);
+ fileMenu->addAction(writeSettingsSDPathAct);
fileMenu->addSeparator();
fileMenu->addAction(exitAct);
- editMenu = menuBar()->addMenu("");
+ viewMenu = menuBar()->addMenu("");
+ viewMenu->addAction(viewFileToolbarAct);
+ viewMenu->addAction(viewModelsToolbarAct);
+ viewMenu->addAction(viewRadioToolbarAct);
+ viewMenu->addAction(viewSettingsToolbarAct);
+ viewMenu->addAction(viewToolsToolbarAct);
+ viewMenu->addSeparator();
+ viewMenu->addMenu(createLanguageMenu(viewMenu));
- settingsMenu = menuBar()->addMenu("");
- settingsMenu->addMenu(createLanguageMenu(settingsMenu));
+ modelsMenu = menuBar()->addMenu("");
- themeMenu = settingsMenu->addMenu("");
+ themeMenu = viewMenu->addMenu("");
QActionGroup * themeGroup = new QActionGroup(themeMenu);
addActToGroup(themeGroup, tr("Classical"), tr("The classic companion9x icon theme"), "themeId", 0, g.theme());
addActToGroup(themeGroup, tr("Yerico"), tr("Yellow round honey sweet icon theme"), "themeId", 1, g.theme());
@@ -951,7 +985,7 @@ void MainWindow::createMenus()
connect(themeGroup, &QActionGroup::triggered, this, &MainWindow::onThemeChanged);
themeMenu->addActions(themeGroup->actions());
- iconThemeSizeMenu = settingsMenu->addMenu("");
+ iconThemeSizeMenu = viewMenu->addMenu("");
QActionGroup * szGroup = new QActionGroup(iconThemeSizeMenu);
addActToGroup(szGroup, tr("Small"), tr("Use small toolbar icons"), "sizeId", 0, g.iconSize());
addActToGroup(szGroup, tr("Normal"), tr("Use normal size toolbar icons"), "sizeId", 1, g.iconSize());
@@ -960,41 +994,42 @@ void MainWindow::createMenus()
connect(szGroup, &QActionGroup::triggered, this, &MainWindow::onIconSizeChanged);
iconThemeSizeMenu->addActions(szGroup->actions());
- settingsMenu->addSeparator();
- settingsMenu->addAction(appPrefsAct);
- settingsMenu->addAction(profilesMenuAct);
- settingsMenu->addAction(editSplashAct);
- settingsMenu->addAction(burnConfigAct);
- settingsMenu->addSeparator();
- settingsMenu->addAction(exportSettingsAct);
- settingsMenu->addAction(importSettingsAct);
+ radioMenu = menuBar()->addMenu("");
+ radioMenu->addAction(writeSettingsAct);
+ radioMenu->addAction(readSettingsAct);
+ radioMenu->addSeparator();
+ radioMenu->addAction(writeBUToRadioAct);
+ radioMenu->addAction(readBUToFileAct);
+ radioMenu->addSeparator();
+ radioMenu->addAction(writeFlashAct);
+ radioMenu->addAction(readFlashAct);
+ radioMenu->addSeparator();
+ radioMenu->addAction(burnConfigAct);
+ radioMenu->addAction(editSplashAct);
- burnMenu = menuBar()->addMenu("");
- burnMenu->addAction(writeSettingsAct);
- burnMenu->addAction(readSettingsAct);
- burnMenu->addSeparator();
- burnMenu->addAction(writeBUToRadioAct);
- burnMenu->addAction(readBUToFileAct);
- burnMenu->addSeparator();
- burnMenu->addAction(writeFlashAct);
- burnMenu->addAction(readFlashAct);
- burnMenu->addSeparator();
- burnMenu->addSeparator();
+ settingsMenu = menuBar()->addMenu("");
+ settingsMenu->addAction(editAppSettingsAct);
+ settingsMenu->addAction(exportAppSettingsAct);
+ settingsMenu->addAction(importAppSettingsAct);
+ settingsMenu->addSeparator();
+ settingsMenu->addAction(profilesMenuAct);
+
+ toolsMenu = menuBar()->addMenu("");
+ toolsMenu->addAction(updatesAct);
+ toolsMenu->addAction(sdsyncAct);
+ toolsMenu->addAction(logsAct);
+ toolsMenu->addSeparator();
windowMenu = menuBar()->addMenu("");
- windowMenu->addAction(actTabbedWindows);
- windowMenu->addAction(actTileWindows);
- windowMenu->addAction(actCascadeWindows);
- windowMenu->addAction(actCloseAllWindows);
+ windowMenu->addAction(tabbedWindowsAct);
+ windowMenu->addAction(tileWindowsAct);
+ windowMenu->addAction(cascadeWindowsAct);
+ windowMenu->addAction(closeAllWindowsAct);
windowMenu->addSeparator();
helpMenu = menuBar()->addMenu("");
helpMenu->addAction(manualChkForUpdAct);
- //helpMenu->addSeparator();
- //helpMenu->addAction(openDocURLAct);
- //helpMenu->addSeparator();
helpMenu->addAction(changelogAct);
- //helpMenu->addSeparator();
helpMenu->addAction(aboutAct);
recentFilesMenu = new QMenu(this);
@@ -1008,7 +1043,7 @@ void MainWindow::createMenus()
profilesMenu = new QMenu(this);
QActionGroup *profilesGroup = new QActionGroup(this);
- for (int i=0; i < MAX_PROFILES; i++) {
+ for (int i = 0; i < MAX_PROFILES; i++) {
profileActs.append(profilesMenu->addAction(""));
profileActs[i]->setVisible(false);
profileActs[i]->setCheckable(true);
@@ -1032,46 +1067,81 @@ void MainWindow::createToolBars()
fileToolBar->addAction(saveAct);
fileToolBar->addAction(closeAct);
fileToolBar->addSeparator();
- fileToolBar->addAction(logsAct);
- fileToolBar->addAction(downloadsAct);
- fileToolBar->addSeparator();
- fileToolBar->addAction(appPrefsAct);
- fileToolBar->addAction(profilesMenuAct);
- fileToolBar->addAction(editSplashAct);
- fileToolBar->addAction(editSplashAct);
- fileToolBar->addSeparator();
- fileToolBar->addAction(compareAct);
- fileToolBar->addAction(sdsyncAct);
+ fileToolBar->addAction(readSettingsSDPathAct);
+ fileToolBar->addAction(writeSettingsSDPathAct);
// workaround for default split button appearance of action with menu :-/
QToolButton * btn;
if ((btn = qobject_cast(fileToolBar->widgetForAction(recentFilesAct))))
btn->setPopupMode(QToolButton::InstantPopup);
- if ((btn = qobject_cast(fileToolBar->widgetForAction(profilesMenuAct))))
- btn->setPopupMode(QToolButton::InstantPopup);
// gets populated later
- editToolBar = addToolBar("");
- editToolBar->setObjectName("Edit");
+ modelsToolBar = addToolBar("");
+ modelsToolBar->setObjectName("Models");
- burnToolBar = new QToolBar(this);
- addToolBar( Qt::LeftToolBarArea, burnToolBar );
- burnToolBar->setObjectName("Write");
- burnToolBar->addAction(writeSettingsAct);
- burnToolBar->addAction(readSettingsAct);
- burnToolBar->addSeparator();
- burnToolBar->addAction(writeBUToRadioAct);
- burnToolBar->addAction(readBUToFileAct);
- burnToolBar->addSeparator();
- burnToolBar->addAction(writeFlashAct);
- burnToolBar->addAction(readFlashAct);
- burnToolBar->addSeparator();
- burnToolBar->addAction(burnConfigAct);
+ radioToolBar = new QToolBar(this);
+ addToolBar(Qt::LeftToolBarArea, radioToolBar);
+ radioToolBar->setObjectName("Radio");
+ radioToolBar->addAction(writeSettingsAct);
+ radioToolBar->addAction(readSettingsAct);
+ radioToolBar->addSeparator();
+ radioToolBar->addAction(writeBUToRadioAct);
+ radioToolBar->addAction(readBUToFileAct);
+ radioToolBar->addSeparator();
+ radioToolBar->addAction(writeFlashAct);
+ radioToolBar->addAction(readFlashAct);
+ radioToolBar->addSeparator();
+ radioToolBar->addAction(burnConfigAct);
+
+ settingsToolBar = addToolBar("");
+ settingsToolBar->setObjectName("Settings");
+ settingsToolBar->addAction(editAppSettingsAct);
+ settingsToolBar->addAction(profilesMenuAct);
+
+ if ((btn = qobject_cast(settingsToolBar->widgetForAction(profilesMenuAct))))
+ btn->setPopupMode(QToolButton::InstantPopup);
+
+ toolsToolBar = addToolBar("");
+ toolsToolBar->setObjectName("Tools");
+ toolsToolBar->addAction(updatesAct);
+ toolsToolBar->addAction(sdsyncAct);
+ toolsToolBar->addAction(logsAct);
+
+ connect(fileToolBar, &QToolBar::visibilityChanged, [=](bool visible)
+ {
+ g.fileToolbarVisible(visible);
+ const QSignalBlocker blocker(viewFileToolbarAct);
+ viewFileToolbarAct->setChecked(g.fileToolbarVisible());
+ });
+
+ connect(modelsToolBar, &QToolBar::visibilityChanged, [=](bool visible)
+ {
+ g.modelsToolbarVisible(visible);
+ const QSignalBlocker blocker(viewModelsToolbarAct);
+ viewModelsToolbarAct->setChecked(g.modelsToolbarVisible());
+ });
+
+ connect(radioToolBar, &QToolBar::visibilityChanged, [=](bool visible)
+ {
+ g.radioToolbarVisible(visible);
+ const QSignalBlocker blocker(viewRadioToolbarAct);
+ viewRadioToolbarAct->setChecked(g.radioToolbarVisible());
+ });
+
+ connect(settingsToolBar, &QToolBar::visibilityChanged, [=](bool visible)
+ {
+ g.settingsToolbarVisible(visible);
+ const QSignalBlocker blocker(viewSettingsToolbarAct);
+ viewSettingsToolbarAct->setChecked(g.settingsToolbarVisible());
+ });
+
+ connect(toolsToolBar, &QToolBar::visibilityChanged, [=](bool visible)
+ {
+ g.toolsToolbarVisible(visible);
+ const QSignalBlocker blocker(viewToolsToolbarAct);
+ viewToolsToolbarAct->setChecked(g.toolsToolbarVisible());
+ });
- helpToolBar = addToolBar("");
- helpToolBar->setObjectName("Help");
- helpToolBar->addAction(manualChkForUpdAct);
- helpToolBar->addAction(aboutAct);
}
QMenu * MainWindow::createLanguageMenu(QWidget * parent)
@@ -1262,7 +1332,7 @@ int MainWindow::newProfile(bool loadProfile)
if (loadProfile) {
if (loadProfileId(i))
- appPrefs();
+ editAppSettings();
}
return i;
@@ -1281,7 +1351,7 @@ void MainWindow::copyProfile()
g.profile[newId] = g.profile[g.id()];
g.profile[newId].name(g.profile[newId].name() + tr(" - Copy"));
if (loadProfileId(newId))
- appPrefs();
+ editAppSettings();
}
}
@@ -1316,12 +1386,12 @@ void MainWindow::deleteCurrentProfile()
deleteProfile(g.id());
}
-void MainWindow::exportSettings()
+void MainWindow::exportAppSettings()
{
Helpers::exportAppSettings();
}
-void MainWindow::importSettings()
+void MainWindow::importAppSettings()
{
if (anyChildrenDirty()) {
QMessageBox::warning(this, CPN_STR_APP_NAME, tr("Please save or close all modified files before importing settings"));
@@ -1416,3 +1486,95 @@ void MainWindow::chooseProfile()
g.warningId(g.warningId() | AppMessages::MSG_NO_RADIO_TYPE);
}
}
+
+void MainWindow::readSettingsSDPath()
+{
+ QString tempFile;
+ tempFile = generateProcessUniqueTempFileName("temp.etx");
+ qDebug() << "Reading models and settings from SD path into temp file: " << tempFile;
+
+ if (readSettingsFromSDPath(tempFile)) {
+ MdiChild * child = createMdiChild();
+ child->newFile(false);
+ child->loadFile(tempFile, false);
+ child->show();
+ qunlink(tempFile);
+ }
+}
+
+bool MainWindow::readSettingsFromSDPath(const QString & filename)
+{
+ ProgressDialog progressDialog(this, tr("Read Models and Settings from SD path"), CompanionIcon("read_eeprom.png"));
+ bool result = ::readSettingsSDCard(filename, progressDialog.progress(), false);
+ if (!result) {
+ if (!progressDialog.isEmpty()) {
+ progressDialog.exec();
+ }
+ }
+ else {
+ statusBar()->showMessage(tr("Models and Settings read"), 2000);
+ }
+ return result;
+}
+
+void MainWindow::writeSettingsSDPath()
+{
+ StatusDialog *status = new StatusDialog(this, tr("Writing models and settings to SD path"), tr("In progress..."), 400);
+
+ if (activeMdiChild())
+ activeMdiChild()->writeSettings(status, false);
+
+ delete status;
+}
+
+bool MainWindow::isSDPathValid()
+{
+ bool ret = false;
+ const QString sdPath = g.currentProfile().sdPath();
+ if (!sdPath.isEmpty()) {
+ if (QFile::exists(sdPath))
+ ret = true;
+ }
+ return ret;
+}
+
+void MainWindow::setActCheckability(QAction * act, bool checked)
+{
+ act->setCheckable(true);
+ act->setChecked(checked);
+}
+
+void MainWindow::viewFileToolbar()
+{
+ g.fileToolbarVisible(viewFileToolbarAct->isChecked());
+ const QSignalBlocker blocker(fileToolBar);
+ fileToolBar->setVisible(viewFileToolbarAct->isChecked());
+}
+
+void MainWindow::viewModelsToolbar()
+{
+ g.modelsToolbarVisible(viewModelsToolbarAct->isChecked());
+ const QSignalBlocker blocker(modelsToolBar);
+ modelsToolBar->setVisible(viewModelsToolbarAct->isChecked());
+}
+
+void MainWindow::viewRadioToolbar()
+{
+ g.radioToolbarVisible(viewRadioToolbarAct->isChecked());
+ const QSignalBlocker blocker(radioToolBar);
+ radioToolBar->setVisible(viewRadioToolbarAct->isChecked());
+}
+
+void MainWindow::viewSettingsToolbar()
+{
+ g.settingsToolbarVisible(viewSettingsToolbarAct->isChecked());
+ const QSignalBlocker blocker(settingsToolBar);
+ settingsToolBar->setVisible(viewSettingsToolbarAct->isChecked());
+}
+
+void MainWindow::viewToolsToolbar()
+{
+ g.toolsToolbarVisible(viewToolsToolbarAct->isChecked());
+ const QSignalBlocker blocker(toolsToolBar);
+ toolsToolBar->setVisible(viewToolsToolbarAct->isChecked());
+}
diff --git a/companion/src/mainwindow.h b/companion/src/mainwindow.h
index 6014fe759..f90b9ad03 100644
--- a/companion/src/mainwindow.h
+++ b/companion/src/mainwindow.h
@@ -101,23 +101,32 @@ class MainWindow : public QMainWindow
void customizeSplash();
void about();
void compare();
- void appPrefs();
void updateMenus();
void createProfile();
void copyProfile();
void deleteProfile(const int pid);
void deleteCurrentProfile();
- void exportSettings();
- void importSettings();
+ void editAppSettings();
+ void exportAppSettings();
+ void importAppSettings();
void autoClose();
void chooseProfile();
void autoCheckForUpdates();
void manualCheckForUpdates();
- void downloads();
+ void updates();
void doUpdates(bool check, bool interactive = true);
void openFile(const QString & fileName);
+ void readSettingsSDPath();
+ void writeSettingsSDPath();
+
+ void viewFileToolbar();
+ void viewModelsToolbar();
+ void viewRadioToolbar();
+ void viewSettingsToolbar();
+ void viewToolsToolbar();
+
private:
QAction * addAct(const QString & icon, const char * slot = NULL, const QKeySequence & shortcut = 0, QObject * slotObj = NULL, const char * signal = NULL);
QAction * addActToGroup(QActionGroup * aGroup, const QString & sName, const QString & lName, const char * propName = 0,
@@ -126,6 +135,8 @@ class MainWindow : public QMainWindow
QMenu * createLanguageMenu(QWidget * parent = Q_NULLPTR);
+ void setActCheckability(QAction * act, bool checked);
+
void createActions();
void createMenus();
void createToolBars();
@@ -143,9 +154,12 @@ class MainWindow : public QMainWindow
bool readSettingsFromRadio(const QString & filename);
bool readFirmwareFromRadio(const QString & filename);
+ bool readSettingsFromSDPath(const QString & filename);
bool checkProfileRadioExists(int profId);
+ bool isSDPathValid();
+
QMdiArea *mdiArea;
QString installer_fileName;
@@ -155,21 +169,30 @@ class MainWindow : public QMainWindow
QVector profileActs;
QList fileWindowActions;
+ // top level menus
QMenu *fileMenu;
- QMenu *editMenu;
+ QMenu *modelsMenu;
+ QMenu *viewMenu;
QMenu *settingsMenu;
- QMenu *burnMenu;
- QMenu *helpMenu;
+ QMenu *radioMenu;
+ QMenu *toolsMenu;
QMenu *windowMenu;
+ QMenu *helpMenu;
+
+ // sub menus
QMenu *iconThemeSizeMenu;
QMenu *themeMenu;
QMenu *recentFilesMenu;
QMenu *profilesMenu;
+
QActionGroup * windowsListActions;
+
QToolBar *fileToolBar;
- QToolBar *editToolBar;
- QToolBar *burnToolBar;
- QToolBar *helpToolBar;
+ QToolBar *modelsToolBar;
+ QToolBar *radioToolBar;
+ QToolBar *settingsToolBar;
+ QToolBar *toolsToolBar;
+
QAction *newAct;
QAction *openAct;
QAction *saveAct;
@@ -177,8 +200,8 @@ class MainWindow : public QMainWindow
QAction *closeAct;
QAction *recentFilesAct;
QAction *exitAct;
- QAction *appPrefsAct;
- QAction *downloadsAct;
+ QAction *editAppSettingsAct;
+ QAction *updatesAct;
QAction *manualChkForUpdAct;
QAction *sdsyncAct;
QAction *changelogAct;
@@ -198,11 +221,17 @@ class MainWindow : public QMainWindow
QAction *createProfileAct;
QAction *copyProfileAct;
QAction *deleteProfileAct;
- QAction *exportSettingsAct;
- QAction *importSettingsAct;
- //QAction *openDocURLAct;
- QAction *actTabbedWindows;
- QAction *actTileWindows;
- QAction *actCascadeWindows;
- QAction *actCloseAllWindows;
+ QAction *exportAppSettingsAct;
+ QAction *importAppSettingsAct;
+ QAction *tabbedWindowsAct;
+ QAction *tileWindowsAct;
+ QAction *cascadeWindowsAct;
+ QAction *closeAllWindowsAct;
+ QAction *writeSettingsSDPathAct;
+ QAction *readSettingsSDPathAct;
+ QAction *viewFileToolbarAct;
+ QAction *viewModelsToolbarAct;
+ QAction *viewRadioToolbarAct;
+ QAction *viewSettingsToolbarAct;
+ QAction *viewToolsToolbarAct;
};
diff --git a/companion/src/mdichild.cpp b/companion/src/mdichild.cpp
index 2fe03a3d1..ab13be5d3 100644
--- a/companion/src/mdichild.cpp
+++ b/companion/src/mdichild.cpp
@@ -216,19 +216,12 @@ void MdiChild::setupNavigation()
addAct(ACT_GEN_PST, "paste.png", SLOT(pasteGeneralSettings()), tr("Ctrl+Alt+V"));
addAct(ACT_GEN_SIM, "simulate.png", SLOT(radioSimulate()), tr("Alt+Shift+S"));
- addAct(ACT_ITM_EDT, "edit.png", SLOT(edit()), Qt::Key_Enter);
- addAct(ACT_ITM_DEL, "clear.png", SLOT(confirmDelete()), QKeySequence::Delete);
-
+ addAct(ACT_MDL_EDT, "edit.png", SLOT(edit()), Qt::Key_Enter);
+ addAct(ACT_MDL_DEL, "clear.png", SLOT(confirmDelete()), QKeySequence::Delete);
addAct(ACT_MDL_ADD, "add.png", SLOT(modelAdd()), tr("Alt+A"));
addAct(ACT_MDL_RTR, "open.png", SLOT(loadBackup()), tr("Alt+R"));
addAct(ACT_MDL_WIZ, "wizard.png", SLOT(wizardEdit()), tr("Alt+W"));
- addAct(ACT_LBL_ADD, "add.png", SLOT(labelAdd()), tr("Alt-L"));
- addAct(ACT_LBL_DEL, "clear.png", SLOT(labelDelete()), tr("Alt-L"));
- addAct(ACT_LBL_REN, "edit.png", SLOT(labelRename()), tr("Alt-R"));
- addAct(ACT_LBL_MVU, "moveup.png", SLOT(labelMoveUp()), tr("Alt-+"));
- addAct(ACT_LBL_MVD, "movedown.png", SLOT(labelMoveDown()), tr("Alt--"));
-
addAct(ACT_MDL_DFT, "currentmodel.png", SLOT(setDefault()), tr("Alt+U"));
addAct(ACT_MDL_PRT, "print.png", SLOT(print()), QKeySequence::Print);
addAct(ACT_MDL_SIM, "simulate.png", SLOT(modelSimulate()), tr("Alt+S"));
@@ -244,6 +237,12 @@ void MdiChild::setupNavigation()
QMenu * catsMenu = new QMenu(this);
action[ACT_MDL_MOV]->setMenu(catsMenu);
+ addAct(ACT_LBL_ADD, "add.png", SLOT(labelAdd()), tr("Alt-L"));
+ addAct(ACT_LBL_DEL, "clear.png", SLOT(labelDelete()), tr("Alt-L"));
+ addAct(ACT_LBL_REN, "edit.png", SLOT(labelRename()), tr("Alt-R"));
+ addAct(ACT_LBL_MVU, "moveup.png", SLOT(labelMoveUp()), tr("Alt-+"));
+ addAct(ACT_LBL_MVD, "movedown.png", SLOT(labelMoveDown()), tr("Alt--"));
+
// set up the toolbars
QToolButton * btn;
@@ -352,6 +351,8 @@ void MdiChild::updateNavigation()
}
action[ACT_GEN_SRT]->setVisible(hasLabels);
+ action[ACT_MDL_DEL]->setEnabled(modelsSelected);
+ action[ACT_MDL_DEL]->setText(tr("Delete") % (modelsSelected ? sp % modelsRemvTxt : ns));
action[ACT_MDL_CUT]->setEnabled(modelsSelected);
action[ACT_MDL_CUT]->setText(tr("Cut") % (modelsSelected ? sp % modelsRemvTxt : ns));
action[ACT_MDL_CPY]->setEnabled(modelsSelected);
@@ -379,8 +380,8 @@ void MdiChild::retranslateUi()
action[ACT_GEN_SIM]->setText(tr("Simulate Radio"));
cboModelSortOrder->setToolTip(tr("Radio Models Order"));
- action[ACT_ITM_EDT]->setText(tr("Edit Model"));
- action[ACT_ITM_DEL]->setText(tr("Delete"));
+ action[ACT_MDL_EDT]->setText(tr("Edit Model"));
+ action[ACT_MDL_DEL]->setText(tr("Delete Model"));
action[ACT_LBL_ADD]->setText(tr("Add"));
action[ACT_LBL_DEL]->setText(tr("Delete"));
@@ -408,6 +409,7 @@ QList MdiChild::getGeneralActions()
{
QList actGrp;
actGrp.append(getAction(ACT_GEN_SIM));
+ actGrp.append(actionsSeparator());
actGrp.append(getAction(ACT_GEN_EDT));
actGrp.append(getAction(ACT_GEN_CPY));
actGrp.append(getAction(ACT_GEN_PST));
@@ -418,27 +420,28 @@ QList MdiChild::getEditActions()
{
QList actGrp;
actGrp.append(action[ACT_MDL_ADD]);
- QAction * sep2 = new QAction(this);
- sep2->setSeparator(true);
- actGrp.append(sep2);
- actGrp.append(getAction(ACT_ITM_EDT));
- actGrp.append(getAction(ACT_ITM_DEL));
+ actGrp.append(actionsSeparator());
+ actGrp.append(getAction(ACT_MDL_EDT));
+ actGrp.append(getAction(ACT_MDL_DEL));
actGrp.append(getAction(ACT_MDL_CUT));
actGrp.append(getAction(ACT_MDL_CPY));
actGrp.append(getAction(ACT_MDL_PST));
actGrp.append(getAction(ACT_MDL_INS));
actGrp.append(getAction(ACT_MDL_DUP));
- actGrp.append(getAction(ACT_MDL_MOV));
actGrp.append(getAction(ACT_MDL_EXP));
+ actGrp.append(getAction(ACT_MDL_MOV));
return actGrp;
}
QList MdiChild::getModelActions()
{
QList actGrp;
- actGrp.append(getAction(ACT_MDL_RTR));
actGrp.append(getAction(ACT_MDL_WIZ));
actGrp.append(getAction(ACT_MDL_DFT));
+ // TODO remove
+ // the function has been hobbled as expects eeprom binary backup so do not list
+ // can just open another etx so use case doubtful
+ //actGrp.append(getAction(ACT_MDL_RTR));
actGrp.append(getAction(ACT_MDL_PRT));
actGrp.append(getAction(ACT_MDL_SIM));
return actGrp;
@@ -1481,12 +1484,12 @@ int MdiChild::askQuestion(const QString & msg, QMessageBox::StandardButtons butt
return QMessageBox::question(this, CPN_STR_APP_NAME, msg, buttons, defaultButton);
}
-void MdiChild::writeSettings(StatusDialog * status) // write to Tx
+void MdiChild::writeSettings(StatusDialog * status, bool toRadio) // write to Tx
{
if (g.confirmWriteModelsAndSettings()) {
QMessageBox msgbox;
- msgbox.setText(tr("You are about to overwrite ALL models on the Radio."));
- msgbox.setInformativeText(tr("Do you want to continue?"));
+ msgbox.setText(tr("You are about to overwrite ALL models."));
+ msgbox.setInformativeText(tr("Continue?"));
msgbox.setIcon(QMessageBox::Icon::Question);
msgbox.setStandardButtons(QMessageBox::Yes | QMessageBox::Abort);
msgbox.setDefaultButton(QMessageBox::Abort);
@@ -1499,21 +1502,31 @@ void MdiChild::writeSettings(StatusDialog * status) // write to Tx
return;
}
- QString radioPath = findMassstoragePath("RADIO", true);
- qDebug() << "Searching for SD card, found" << radioPath;
+ QString radioPath;
+
+ if (toRadio) {
+ radioPath = findMassstoragePath("RADIO", true);
+ qDebug() << "Searching for SD card, found" << radioPath;
+ }
+ else {
+ radioPath = g.currentProfile().sdPath();
+ if (!QFile(radioPath % "/RADIO").exists())
+ radioPath.clear();
+ }
+
if (radioPath.isEmpty()) {
qDebug() << "Radio SD card not found";
- QMessageBox::critical(this, CPN_STR_TTL_ERROR, tr("Unable to find radio SD card!"));
+ QMessageBox::critical(this, CPN_STR_TTL_ERROR, tr("Unable to find SD card!"));
return;
}
if (saveFile(radioPath, false)) {
status->hide();
- QMessageBox::information(this, CPN_STR_TTL_INFO, tr("Models and settings written to radio"));
+ QMessageBox::information(this, CPN_STR_TTL_INFO, tr("Models and settings written"));
}
else {
status->hide();
- QMessageBox::critical(this, CPN_STR_TTL_ERROR, tr("Error writing models and settings to radio!"));
+ QMessageBox::critical(this, CPN_STR_TTL_ERROR, tr("Error writing models and settings!"));
}
}
@@ -1834,3 +1847,10 @@ void MdiChild::setModelModified(const int modelIndex, bool cascade)
setModified();
}
}
+
+QAction * MdiChild::actionsSeparator()
+{
+ QAction * act = new QAction(this);
+ act->setSeparator(true);
+ return act;
+}
diff --git a/companion/src/mdichild.h b/companion/src/mdichild.h
index fa3fbcd69..49f4cbc34 100644
--- a/companion/src/mdichild.h
+++ b/companion/src/mdichild.h
@@ -55,14 +55,9 @@ class MdiChild : public QWidget
ACT_GEN_PST,
ACT_GEN_SIM,
ACT_GEN_SRT, // model sort order
- ACT_ITM_EDT,
- ACT_ITM_DEL,
- ACT_LBL_ADD,
- ACT_LBL_DEL,
- ACT_LBL_MVU, // Move up
- ACT_LBL_MVD, // Move down
- ACT_LBL_REN, // Move down
- ACT_MDL_ADD, // model actions...
+ ACT_MDL_EDT, // model actions...
+ ACT_MDL_DEL,
+ ACT_MDL_ADD,
ACT_MDL_CPY,
ACT_MDL_CUT,
ACT_MDL_PST,
@@ -75,6 +70,11 @@ class MdiChild : public QWidget
ACT_MDL_DFT, // set as DeFaulT
ACT_MDL_PRT, // print
ACT_MDL_SIM,
+ ACT_LBL_ADD, // label actions..
+ ACT_LBL_DEL,
+ ACT_LBL_MVU, // Move up
+ ACT_LBL_MVD, // Move down
+ ACT_LBL_REN, // Move down
ACT_ENUM_END
};
@@ -97,7 +97,7 @@ class MdiChild : public QWidget
bool saveAs(bool isNew=false);
bool saveFile(const QString & fileName, bool setCurrent=true);
void closeFile(bool force = false);
- void writeSettings(StatusDialog * status);
+ void writeSettings(StatusDialog * status, bool toRadio = true);
void print(int model=-1, const QString & filename="");
void onFirmwareChanged();
@@ -231,6 +231,7 @@ class MdiChild : public QWidget
AbstractStaticItemModel* modelSortOrderItemModel;
QComboBox* cboModelSortOrder;
void setModelModified(const int modelIndex, bool cascade = true);
+ QAction * actionsSeparator();
};
// This will draw the drop indicator across all columns of a model View (vs. in just one column), and lets us make the indicator more obvious.
diff --git a/companion/src/radiointerface.cpp b/companion/src/radiointerface.cpp
index 37265cf62..afe08f836 100644
--- a/companion/src/radiointerface.cpp
+++ b/companion/src/radiointerface.cpp
@@ -189,21 +189,25 @@ bool readSettings(const QString & filename, ProgressWidget * progress)
return readSettingsEeprom(filename, progress);
}
-bool readSettingsSDCard(const QString & filename, ProgressWidget * progress)
+bool readSettingsSDCard(const QString & filename, ProgressWidget * progress, bool fromRadio)
{
- QString radioPath = findMassstoragePath("RADIO", true, progress);
- qDebug() << "Searching for SD card, found" << radioPath;
- if (radioPath.isEmpty()) {
- QMessageBox::critical(progress, CPN_STR_TTL_ERROR,
- QCoreApplication::translate("RadioInterface", "Unable to find radio SD card!"));
- return false;
+ QString radioPath;
+
+ if (fromRadio) {
+ radioPath = findMassstoragePath("RADIO", true, progress);
+ qDebug() << "Searching for SD card, found" << radioPath;
+ }
+ else {
+ radioPath = g.currentProfile().sdPath();
+ if (!QFile::exists(radioPath % "/RADIO"))
+ radioPath.clear();
}
- // if radio.yml it is a converted radio
- // if radio.bin unconverted pre 2.6
- // if neither then unconverted eeprom or empty
- if (!QFile::exists(radioPath % "/RADIO/radio.yml") && !QFile::exists(radioPath % "/RADIO/radio.bin"))
- return readSettingsEeprom(filename, progress);
+ if (radioPath.isEmpty()) {
+ QMessageBox::critical(progress, CPN_STR_TTL_ERROR,
+ QCoreApplication::translate("RadioInterface", "Unable to find SD card!"));
+ return false;
+ }
RadioData radioData;
Storage inputStorage(radioPath);
diff --git a/companion/src/radiointerface.h b/companion/src/radiointerface.h
index d97bcd983..4b930df9c 100644
--- a/companion/src/radiointerface.h
+++ b/companion/src/radiointerface.h
@@ -19,8 +19,7 @@
* GNU General Public License for more details.
*/
-#ifndef _RADIOINTERFACE_H_
-#define _RADIOINTERFACE_H_
+#pragma once
#include
#include
@@ -42,8 +41,6 @@ QStringList getWriteFirmwareArgs(const QString &filename);
bool readFirmware(const QString &filename, ProgressWidget *progress);
bool writeFirmware(const QString &filename, ProgressWidget *progress);
bool readSettings(const QString &filename, ProgressWidget *progress);
-bool readSettingsSDCard(const QString &filename, ProgressWidget *progress);
+bool readSettingsSDCard(const QString &filename, ProgressWidget *progress, bool fromRadio = true);
bool readSettingsEeprom(const QString &filename, ProgressWidget *progress);
bool writeSettings(const QString &filename, ProgressWidget *progress);
-
-#endif // _RADIOINTERFACE_H_
diff --git a/companion/src/storage/appdata.h b/companion/src/storage/appdata.h
index 1b57c77f0..119dd8169 100644
--- a/companion/src/storage/appdata.h
+++ b/companion/src/storage/appdata.h
@@ -835,6 +835,13 @@ class AppData: public CompStoreObj
// Message box confirmations
PROPERTY(bool, confirmWriteModelsAndSettings, true)
+ // Toolbars visibility
+ PROPERTY(bool, fileToolbarVisible, true)
+ PROPERTY(bool, modelsToolbarVisible, true)
+ PROPERTY(bool, radioToolbarVisible, true)
+ PROPERTY(bool, settingsToolbarVisible, true)
+ PROPERTY(bool, toolsToolbarVisible, true)
+
bool firstUse;
QString upgradeFromVersion;
diff --git a/companion/src/themes/classic/16/folder-tree-read.png b/companion/src/themes/classic/16/folder-tree-read.png
new file mode 100644
index 0000000000000000000000000000000000000000..c6c4cecdcdbb106289e4df30ecc095d03d57e592
GIT binary patch
literal 569
zcmV-90>=G`P)A4FCWD8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H10mey0
zK~y-6rISBsQ&AYjfA^)vMrgE(T~rLw$;l9*E?xXnEwqjuDxyONBMA-;b?GDy(y@@C
zvr`2@l1a4XHP{fUpw=R-ytdXPBu#k~QZ+5U_c=64)4XRCJn(V3hwmP~bI-j>MED=H
z0Vt&|i^%IL*9DwwapoORuJ5W742cNUx>>1I#4rpgl}h4*3k|)y6Eq{4OcDqLNT<_y
zz1}(>4u=T_gH8+0$ZeQ>`EFrb9@wz}@OU)JGpT2evbb5P{{nr
z0=W&71$_?7-h1ZjdX`@EG!tXf_ZVZY)g3Tj*o3ASub%JYK#Lf)h8QpAx7EHFYv^?O
zcWnS7^0bi~8hI4UuPi&7kJwHHR|`*~chGg+!QU9U@8Es|A4FCWD8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H10oO@H
zK~y-6rISBMTTv9ozx(oxMlc$wI%sJKSj31B5@@%Aii@q37Hm<34pj_9%%WMGq81!F
z1-A|ky10lWt4ItsNN^Bi>A$pTqfaIJ42eQg%sURg#Ha5?gnn@0-j8#CoWpl7BO?5d
zcmQCGbrR94?9~Hkz2nXnfK2fuchFBnkk>#qo26JRM#*H7G~`g!UUhI=fj|Ievl-!V
z7<#?F=-cgfSS%Lx2)DI=EaJy`9#UQh{L2FXbUF^1_0atQJBKN-=Y1-FZ^ftb3V=Gs
zSRVj5oz5phjzd-ULRDNV2gVqyd~CHge~U)93xFgMEy??`w-escqxdfsphlAL-ZlKn
z{lW9;=a=sh07F_MRL_hIVr}E|4KuO#2VzAUEd$TSADA2XZC7+tIf7E$!=^^O=EM5#zy%4|Cq>ud|qb
z$r!6q0yssCPlX)QjM1d{cSMvb0*GiqQOEatrbdO|S~04BuI31{u6GCqgDSt*Gp6z`
Y0aCZm)bV1i1^@s607*qoM6N<$f*F_nEC2ui
literal 0
HcmV?d00001
diff --git a/companion/src/themes/classic/24/folder-tree-read.png b/companion/src/themes/classic/24/folder-tree-read.png
new file mode 100644
index 0000000000000000000000000000000000000000..307a0c3c08315306091b828064374c88f6741ba4
GIT binary patch
literal 803
zcmV+;1Kj+HP)0cec_P#P})fX>cN91aHn>FMc|mzT%E
z+ycOEw^LhN3qV_28&<1zgYWfvsjI8QU@&YCpePDYUw7b_6)^55B|US4Z}hmCoSY;h
zBV&7jPxc|4r%KT!s;3ThedcVTSF=7QAds{NV_K%BpPY4!#l^)f0kR}XdJqZ{6B84v
ztE*XXPp~QnBP)eq_Gce*Ao@cM2Mh@z>ciqB;BHsN4OZnqL}5@~W2~i~CrQ#HAw>A7*b6K~gO}XCDCOTP*>E=U
zb-?$b?zv<7$L}(q&o>zD27W-AnVG?6vjJc>n@LMcTTfWQFkL4vF{cn0^eX{?H
z-|ruXEqtP;rY4GuivehCY^0!|VBMQuo+Ck?LIee#mjm8kE#LZI1l&Et002ovPDHLkV1n1AY-Rue
literal 0
HcmV?d00001
diff --git a/companion/src/themes/classic/24/folder-tree-write.png b/companion/src/themes/classic/24/folder-tree-write.png
new file mode 100644
index 0000000000000000000000000000000000000000..0b61387dce0b3194558b847b1730509f055bf01c
GIT binary patch
literal 789
zcmV+w1M2*VP)QN-F!7cR>n3QVXdSn5zOiZJs+
zM1<}XqHYSk@FGDZih?dAMzkAg+-V_A3R0RMG3=A+fHU>aWP7Zdv
zJq2eH0=L^ub8|BQeSLkjx3|afP$)!8OABVRd2<3y(|G!#pKwG2WgEM5^5VEMt>X9l
z$<58(oZyw)!{-tkhV=D6^$fk?^r?{U{tX4uj4TvOo-W^>Uqmn%OiGY1gt)iZq^GBw
z91aJ+)G6j7G2H=?=-P`agfK}dwbcTTl(Kb2p8+%t)mT5=|gjmJ1;=i;53*<{q#f
z0ZLa3)~)bth#B7(T^{sLl9hFwx|{W9j#Zv$yVL0`=(_u8bdhf;Xsf%((C~9zp0>-t
z{mwQHo;`f^R(rJ)1;S!MBqK-zWMxG;l@;Y{psK1kAGV5x{b?L+Jcq$#RJ__Z0A}U<
zQpP0`gaHu<1aP@r02CG$VzF2N7@zRs4NQ`4D`rA|hsg5AIhouE0O;xIp{lA1fR2t1
z%F4=?*tM!!-VVQK^w}Vp^#x??-2uQ~=93pFib82=Deymwd_G?s_jo+?Uhc-;bYO?$Ml?-}dnd#4<9Y(a%BV1#&Blg?27aoOiK8N>
z&*B79%Enbp0h}){)FnK@f|jH}ul5+DsE?hxT>CvkaYL>C04b&3qsY|Cw%(k7>=Z+A
TXVl2w00000NkvXXu0mjf+?!+W
literal 0
HcmV?d00001
diff --git a/companion/src/themes/classic/32/folder-tree-read.png b/companion/src/themes/classic/32/folder-tree-read.png
new file mode 100644
index 0000000000000000000000000000000000000000..b97aaaf8316c931f94629e2d2948aa5e22e7aeb1
GIT binary patch
literal 1055
zcmV+)1mOFLP)8>RKGq
zQVK$gGAkR*{Sig$$2O$058Rv`#kx(gmOii8l){NDoW7hM+tHNdy4aP>fGj(eO0e$gY4
zDP93;a}@C9LjZv3>1mu!XKG$iQ9(gLL5^OxBC8^7ZEYnO3=#|mnVg)YySw|gHis+7Sjv2j(tu&|Kc-roEPM59qmCKFRrQ>dy6fWzUy;c%>A&1N%g
zZEd>p>J~^QlYDvlEI$SoSbvW(BRe^}a+ihF+N4UV-O_5JDc4TQac{Zh&Z=&u1?Z%PP(DmDCSV8y^@;-#Eo;t18!i8%jIHZWF)m%Q&WS*Vp#&JX!x`M%TEE{useDAz`#uWuh=0a
z9PPuA-HL~i4U!6I}#fSk6>(X+w
z<1-ZZ-_HiiChA|_wPs%30)D?A^X77F4J{ctTm3!&&cA-Ax}kPwyWvJ5#M8^6{{H?V
zkH>=&o!8xtbLoaYzzICG9GaMzFonZm77`1(1@!*$r39puA)qr2=NK9q+IsfGVI7e@$Q(K!GB002ovPDHLkV1o2p{JsDH
literal 0
HcmV?d00001
diff --git a/companion/src/themes/classic/32/folder-tree-write.png b/companion/src/themes/classic/32/folder-tree-write.png
new file mode 100644
index 0000000000000000000000000000000000000000..85810d684a0d56740e75a28fc9e601d73ae57864
GIT binary patch
literal 1078
zcmV-61j+k}P)hp@4+5wF*a*XzaQa?#%2epAIEfey^g
z%~4cTL~U(tY_Ge!oBI0tb@{BUEIKD@bUJZ5ooiUL*-UeD
zvr=AV0mCpj`CUIhEk;O9Gi}ITyE;eE_50=uxZQ3tx9#Sh7n+p#frckGS3uWwq?STR
zH`HDbA}N7ALWt9=A&0}UOV@S$<^p8_Lvh5c7Pug#e0v@4+~DBgz9T(n2rCM#H{^s6
z_gQnS$2<$3=cJT@^#nGIs38gIYF{m$5<+C<7v^`BKDKB7lK;BE-@7+>-_q%T#YsoJ=P@dNGWWyXk|8oH<3zU?U@Jh|2T)Fg>
z5?}Z7K^!#|Y$>xn-8I}}N=;8=KDtOGB?^#|sKA{7M_X?E6P%fu;jN=hoWAf42R?og
zb8eQ&!xCJ-yNGB}An^_;aVI`MLDy#=@_6U7lstGB0Sp3B?+PZY=^{R#s=y?$ePUvQ
zk&%(uW@Tk1+1c5#b@?OZoILY2znr>AxG%k?fHB@
zIyySmuu@9)?kvM*-9~$LhcB;rmpR+9H3c9jbU_k_kmcoNOePbfqoV|aK>+M_J9fK$
z4QsVpX=`ia_4?PSaa6y*qkQK>sawrecN{Ox3u<9OG954sgHz|ub8$%nEoDPC;#=U_
zZ!Q3AHd`P(8#p9{*fI6Y`5vOic9QA9{QNxT`*%}RcSMOFcy;A8lv0iY4~sNW1;l1`
z;?ppCbJI{pWPkj6wLqZ|qH6U^y}i9Tv$L~=0)PFd)6fl!0r#$k#>dAq{C+=?a70-^
z^&ekMKuYNY-uoBMIW#o%K>w$GgcYZuff}cL1_}xa@J^0ly8MHhKq$1i0ydkCcj}(v
w$4h5#$O-`;d~{qbv6NEfIV+QohK+Ln4I%H_G*{t41ONa407*qoM6N<$f(9}A*8l(j
literal 0
HcmV?d00001
diff --git a/companion/src/themes/classic/48/folder-tree-read.png b/companion/src/themes/classic/48/folder-tree-read.png
new file mode 100644
index 0000000000000000000000000000000000000000..3e7cbcddde3ed5d1f28b8aaf3b7bbaa1c8199d64
GIT binary patch
literal 1560
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
literal 0
HcmV?d00001
diff --git a/companion/src/themes/monoblue/16/folder-tree-read.png b/companion/src/themes/monoblue/16/folder-tree-read.png
new file mode 100644
index 0000000000000000000000000000000000000000..fd4a1b479cf4fbbe734e576b19267f63302b47d1
GIT binary patch
literal 424
zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFvNcITwWnidMV_;}#VPNEq&<7~;px-&&!2zXwT$U4P>M0h
z+uensgH_f8$l)yTh%5%uH6Y9=%K!EWkilN!>Fdh=l2KSlO|3`C;SEs8!qdeugyVX0
z0t1tqBcmFdfq+Phfy6-`M*&@imBol%>cmxuX4B8lk85GvC
z2CaK|)f{MsYKdz^NlIc#s#S7PDv)9@GB7gLH89jQv9Zfmi~x#{!~9
z##-PXP>&=?PjG%(NqJ&XDnogBxn5>oc5!lIL8@MUQTpt6Hc~)E44$rjF6*2UngAfK
Bbv6J1
literal 0
HcmV?d00001
diff --git a/companion/src/themes/monoblue/16/folder-tree-write.png b/companion/src/themes/monoblue/16/folder-tree-write.png
new file mode 100644
index 0000000000000000000000000000000000000000..0fa6d2f48c9354bf93648426b7556323428abaab
GIT binary patch
literal 418
zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFvNcITwWnidMV_;}#VPNEq&<7~;px-&&!2zXwT$U4P>M0h
z+uensgH_f8$l)yTh%5%uH6Y9=%K!EWkilN!>Fdh=l2KSlO|3`C;SEs8$kW9!gyVX0
z0t2I?qng24j${WH7DuKPJdTcx7R`+9QYuHAR&+@w1bOfXBqSNMF$gm#DzOHiZscYM
z>Q*grjVMV;EJ?LWE=mPb3`Pbfc98G^vGBX`~&Kd
v1nCLRPb(=;EJ|f4FE7{2%*!rLPAo{(%P&fw{mw=TsEEPS)z4*}Q$iB}3Z8Pz
literal 0
HcmV?d00001
diff --git a/companion/src/themes/monoblue/24/folder-tree-read.png b/companion/src/themes/monoblue/24/folder-tree-read.png
new file mode 100644
index 0000000000000000000000000000000000000000..5852ebb38d49699e0ed0001af14231369d22652e
GIT binary patch
literal 435
zcmeAS@N?(olHy`uVBq!ia0vp^5+KaP3?%1DUd;wl3dtTpz6=aiY77hwEes65fI9x9$j#HmF@)oKasm*D
zCMGciE==e$6gkM9P%6q8ypTzNOGQHJ71u(U2tkn$zPVh92LyO{OI6#
z$Ac^N0zcRpR^J!%FH5r20-C5=;u=wsl30>zm0Xkxq!^40j7)V640R1HLkumfjLof#
z&9n^+tPBihyRQWL8A(HKeoAIqB|?Kmh>@X{iG`J+2}Hvtp6{GM4H|G8N-}d(i%Sx7
z3lMrBmH_RsfasC27WfC$BMH(IoS#-wo>-L1P+nfHmzkGcoSayYs+V7sKKq@G6i^X^
Mr>mdKI;Vst0D=T~;{X5v
literal 0
HcmV?d00001
diff --git a/companion/src/themes/monoblue/24/folder-tree-write.png b/companion/src/themes/monoblue/24/folder-tree-write.png
new file mode 100644
index 0000000000000000000000000000000000000000..711cdb5897dbead7ccd6e91cd266e86853f92a10
GIT binary patch
literal 432
zcmeAS@N?(olHy`uVBq!ia0vp^5+KaP3?%1DUd;wl3dtTpz6=aiY77hwEes65fI9x9$l24yF@)oKasoq>
zgPOoe39e-k&VqXw!q_=PwKx_!?70vS&hhj>*MbE_FG4t&+Y&NXC{HS53)5ho)*R@-
zu>4>10egnGo?-{yguJW<8mC&~8c~vxSdwa$T$Bo=7>o>zOmz(mbqy^;3@xmT&8>{h
zv<(cb3=C$wuLOD+NkeXaN@iLmLW4z!k)f4|nU#?RM8nfpt8{@HG~hOrWag$8mn7yE
zAoM^i0onuABV#S_52!~Hq$fB(t)x7$D3zhSyj(9cFS|H7u^?41zbJk7I~ysWA_h-a
KKbLh*2~7Zm6MT38
literal 0
HcmV?d00001
diff --git a/companion/src/themes/monoblue/32/folder-tree-read.png b/companion/src/themes/monoblue/32/folder-tree-read.png
new file mode 100644
index 0000000000000000000000000000000000000000..3cc3b30c9f0c43ef388857aea498ffcdaac86dc0
GIT binary patch
literal 452
zcmeAS@N?(olHy`uVBq!ia0vp^3LwnH3?%tPCZ&To$sR$z3=CCj3=9n|3=F@3LJcn%
z7)lKo7+xhXFj&oCU=S~uvn$XBD8U)v6XN>+|9=LCv}eygRJ`JT1{7pW@^*J&=wOxg
z0I4YOh%5%uKR}rA{K03bKn8n>r>`sfOGaTKHMJfkhc`f>C{Gv15Q)pBXHWAs81OI$
zG+*IOnE&L0wa3{>KA!f4Dj}~f2T#7@aCX^^i-o5d-W18S>bF|wmMG2aa(?i_TGT2*
zjj^Utq+>Ow?&_{H^GgF6!y3ZtKXh^SKW9w~l+|9=LCv}eygRJ`JT1{7pW@^*J&=wOxg
z0I4YOh%5%uKR}rA{K03bKn8n>r>`sfOGaTKHMJfkhc`f>2u~Ns5Q)pBXC3((6nIz;
zTs^`6!M@-@U+3Q?>s5~CHak`&GUbS0uzYmS|Hy2Cq}{9TUio;wQ^9trheC`0&sLA3
z2iz>}%hg`2(dx=Q*Uc5ds`HgS%%{SFcN3r7rT?sJihy>gmbgZgq$HN4S|t~y0x1R~
z10z#i14CUy%Me2gD`RsjV>4|711kfA+3qWWL4c$oH$NpatrDTZBE-nh%EZjd&>W&+
zuI^oRpau=N4JDbmsl_FUxdjM45KDmeSU~j1SPT3E>X8KL3C>R|DNig)WhgH%*UQYy
dE>2D?NY%?PN}v7CMhd8i!PC{xWt~$(698KliIe~U
literal 0
HcmV?d00001
diff --git a/companion/src/themes/monoblue/48/folder-tree-read.png b/companion/src/themes/monoblue/48/folder-tree-read.png
new file mode 100644
index 0000000000000000000000000000000000000000..ffa75386d240764dc0eac47869c30b9a057f003b
GIT binary patch
literal 480
zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDD3?#L31Vw<9Lb6AYF9SoB8UsT^3j@P1pisjL
z28L3g!dD3l3|2E37{m+a>&pI;QCLV#tw+h>4N$1e)5S4FcUglCQy+t>Sv4EAPXHGaZh)AHBA8
z_R`fmt<;@g@f%%YGNoH&pI;QCLV#tw+h>4N$1m)5S4Frj_;KV_~*9knzu4%
z9pF@~b?$ZDDYX;m0M!!Lh?11Vl2ohYqEsNoU}Ruqs%v1VYiJo_Xkle+Ze?tyZD3$!
zU@+T#B`|!DH00)|WTsUjG+2Zf8Csc`Ss7SDG%)U1_5`Rw18ze}W^QV6Nn&mRLJ!0e
zpgk54Ju=n;|A2ZVL3)Do(@M${i&7cN%ggmL^RkPR6AM!H@{7`Ezq647Dq`?-^>bP0
Hl+XkK1Co?h
literal 0
HcmV?d00001
diff --git a/companion/src/themes/monochrome/16/folder-tree-read.png b/companion/src/themes/monochrome/16/folder-tree-read.png
new file mode 100644
index 0000000000000000000000000000000000000000..db62ca731b811c0c81d8d1bcd26863a57cff0d9a
GIT binary patch
literal 436
zcmV;l0ZaagP)0}_-((pV@7c8V5OMr`~MlEzhB8d?{P$4iD>%!%AblRUtgzfP8C3BVR^H2>E)fU4TZev-YmpcM#yRn^C4
z2L~7?X>WZTPY-j@#d)(Y^?my2JL5ZSn~ZV|^WB85gZU&Yo%jVT;XclqEbu0tbp?K7
z5ic9=6uwl|5Z58e!OEH5V3KWIO!BRvm;N_G7q756ga33SfvQ^XX<%+N8g29?
e9frYRaODrIMOpmM1BEaE000046(41kR}fyX?y}3s}#n@LP_Z}q(~DIkdVeU
zcIgt>R1qTVf+z~v!ob27!jWcg^mp?maVe=FCiFrg0Dv3wVq+dYRekbUJ&DF^i}0
z8o#iCAA{If0-4#xH_T%avxC?~(WQy4%-k-xcbKj^9#r|em>K3^8f&%Y&+r~ywD1{6
zSia)`iPebsT5yl>DKjr3;t-42ulPFxDytjC{{+2i4_CN~h|98|6bRg8=Fh)GL=UGC
zQQrCiKHTS^jupc%)g3%Wo$)))^hbHFf5LxIcQ6?d%eD9u%;61|^cT2^k9C1Rc!=YI
zo5yu#p5g^W#M_|`GP8wd8H|WCJdKFo1wHq_5$gDYogw`BSOS^(azq0Y?RNXssHFSQ
cXf)Pu0R#_J@#-}XI{*Lx07*qoM6N<$g4B<>$^ZZW
literal 0
HcmV?d00001
diff --git a/companion/src/themes/monochrome/24/folder-tree-read.png b/companion/src/themes/monochrome/24/folder-tree-read.png
new file mode 100644
index 0000000000000000000000000000000000000000..04d42a07dfd34f8a50030cd342cf39ea9a0ec946
GIT binary patch
literal 573
zcmV-D0>b@?P)g%ii;Be0Uo#&kIz0bYpxiV8b4TmsPj*p3FY{L>jRf=BLrJ|~BZ*nd!<7cZW
zdWNeF-eKHq65mu+fWTa4zFlHQ43xt&5%H~J-GNpCE9urUbHCOCn6y|DR;ASd25|}t
zn8kEvzF2R-75qRaHbul8Okf7zAv3?$FKVY24O=WH7jYi1@dj=k85<2ca@;0=Z>7Pflzl>MK7Mp?3-LqzOq36Pl=Dxe}_1mjh6%c-4n
z@H8UkEByYo0zP7Ng_wm#Bg#UxA*$7CYx?Q8q^_bUo@~_S5wYhlf*mYNF}N5Q00000
LNkvXXu0mjfcS`rL
literal 0
HcmV?d00001
diff --git a/companion/src/themes/monochrome/24/folder-tree-write.png b/companion/src/themes/monochrome/24/folder-tree-write.png
new file mode 100644
index 0000000000000000000000000000000000000000..b19006030b4b5dcd2f9abadcd92c92e0a9d294ab
GIT binary patch
literal 568
zcmV-80>}M{P)SbQahu(euvFAmpzb3Q>SORXBokO*^Sy+H>4#&<~+h?MLO?Q03-T{i6CMce;ag(BW#e>yvn$WCUYL
zCMxi;spd|Afh5~%+WM-$SxR}AWXSK5?7$ifVtF0VRHA48l%lDv=z3;2ThSdiozhB1oIP)hkYb<$kkqMcZRGdP78c#Cng>*h`;*qLOwrme2}52cjv
zxRK;8wqPj^;9xg^m)L~Y@5C(QdbU`{{QReXUmO{{LD$$>v|ItNzZmg>0000n)d^a0yf#%&f-=m;ep|4}e#|
zM_|_3&A8yK43s1tOz>@S?PmZp`yy!sI15yOJ-}w7ZMZLSgpA`jkCihnDOJZCD{>sq
z5#8(3Pyu$hm$!^q0cJJ@Or-@%syP8|!N)E*DQO|a-?z~MuC)`~j(~f>lLGvAaS!EI
tY9|ncVYue|zhPl?TtEcitP!j4}+E
z2=&(k2U<84&+}{@B|y>zVAAy~z+K>A6t_~s;OBt};Hab?U>aBjrXm9hPWxV<2@JaH
zYru1$CxTz`Jg=0wp9J0ky}(Z31EKX$x&SBQ98h!pexL!2MhS>q1CsUtW56pjdlthv
z3G4v=0N;VHK;6uKo7r_qKim|5l5`9h$-D-D(|`e&6W+4!IANOyj%3VKdYcspw8eBvfUNo~e0FuTC%I>hUFzx`k1&m7C8si&q?ZVm(
zGkYYd4;TjefX%=Va5ip$I01iMJM1h8tKkbXTOyc}8i1r~I|A0`{vL2UhI11bOc9rg
zGy!vF_9T)Z{pxh^BmsFaBWXFozoi`kS;}t>yK`_e3&?`wIpbFf6<}ry>8y0LeISuk
zmt@YCBsC=6khCGsbBb7mE5IVbhv^J(NYYi{3&E$j>3EA~_N_Izh$Gp!nQeChW`O+!
zN3a*bdxEXF0bGd+PRl^Aq>jEmi@Bi$kfPYvuSnhh|?U4Wg002ovPDHLkV1j4hHKPCk
literal 0
HcmV?d00001
diff --git a/companion/src/themes/monochrome/48/folder-tree-read.png b/companion/src/themes/monochrome/48/folder-tree-read.png
new file mode 100644
index 0000000000000000000000000000000000000000..6f1a5e6b0c947dff05b488213a1c46db70753ee3
GIT binary patch
literal 983
zcmV;|11S87P)fB$vMFG4U=2tmn62tv#Y1ydnWi=wY3sGAHyyV0u<5v3cE)Js3`
zq7)IlRU@$SB5#5)f>OFDq%VY76%qVcMc3WG7jxET-+i4qv-{4B!T#aEne(3KKhOVt
zo-^k>2iw%$fH#4zma%7n$*~+slI%>9#9cIl4}n9HvhRNZ_)5~`GDJ-YI0bwJe322+
z3oHXpN}3c))QAAv$AI;~$H148x@`XeybUZTjYO1)rXqmt!=xhC5+Y&yG$lneCLrJh
z@GtN#Fb5!r*a@r#wiOX{SLt0IBuxXp1*QY5ZT}s{UjeoNKLERncp8a7aQ-wfpVaxE
z!uV3)8{i!9y6sy1kkEc)Vo$c7)9=U~0?oJ>ZJ%
zd!fH($oYU-z3tOK>aDy
z4J-nVO4^g%iEUpl>--R5)#wAx0s>wFW`yz0K#!yo!0*8IHn#n?Pv()=Az-WReE^as
z03QH*Nk5;@0iWjB-r&FW*A{i8(D|W`?SXKNSOWak3G%WL=#lhd#Ju^L{+-qzZC{YI
z09XMm1ZK8O*#u09aVSQBGySzOq%FALmed{u&V)7$lGYI^ASQ(dV~BF#;whs?*%UfJ
zCZ}`o3Gi}xcgiD1fHM8>Y=2#7Ag!V%0Wm40;wjCcj(y;uq_R6~?zcaSvMDqgEFPnM
zE}E{$#*C^`Xd`J=HC7aU!YdJA`*Ib$?NEsTNmGF*Geb9Rx80G)imKMY5#U;;^-Hp(
zi;|9q!o4G?dlAnjy+S!7X=5h{>(~bdNz284U|x73I&7$rm%>~Lee~H5-@%mjlgzES4-MF6+5vG0q<2wKAu94z!qRv2Y6b~Mk7#F
zLGxD?yzTJ6PoZ%EO{2TFw|7I+PK*)@0hA<3rH8Gm@ce~)ctN<^+&f;VOq2olysL6T@hbz!V+AKn#0db3gxA$`!DDBT2#
z2t^S=kOsOCT^Qwd7e%CmL?l=c%-=+eQnOrlpDt#s<1{;SX7@ic1^d8(^MB{O&pFSY
z_k6sEm2J9)q$R)-+h6DG%WVHp11Xz}{KMcHH<=?3QNjC$Z
z0fWGiz`h*MAYdi1
zFtfh^3`;r)d#SODAtJYVAb8~?1oLbMS=-(0TP
zp0NEMa1U^-ALMmsU|7)lFrujDc$=+)D5BO;O-gvm!k7miJ79Q5E=ot^?|2y3vWb#?Vp?A
zEkYv#B+Un|2~1~g7oNy7MN@0w9pFq*#wA(OPm&HuTHUXX+Fry-9EwJ&0*y
j6@Zc?>Hhz1W`Mr{$%bFkEjBl)00000NkvXXu0mjfTOzmj
literal 0
HcmV?d00001
diff --git a/companion/src/themes/monowhite/16/folder-tree-read.png b/companion/src/themes/monowhite/16/folder-tree-read.png
new file mode 100644
index 0000000000000000000000000000000000000000..bb46e259fc360c95089cdb6824161261bfe81aae
GIT binary patch
literal 440
zcmV;p0Z0CcP)b9k0y7v}T%-O<|D9iHMQK4Pb;
z&O(y${|X#KVS?cO@?z51yn@q79`xriw(%C1@C1i&FUhyR1aKIinsebD&R`Eed;V%w
zN%C+g0DFC4OT5PSB+skrA~t##za0!SINyAaaRCcR@-oSz_VK?Q>?e8LXE4ESYz|z_
zu(e8{#iF-7(XH=C&u`$>su5a@bwPf`5o}^QEE+nPR@LQ3V2-1@xu<>iFS=|#37O9$p83C6wKE+hQqH$ng$VZ7fh=?Z<@uI4`5%DS_p5r0*F@x8o9&ymaVeK5Bu!>uSe1theq#B12
zu~F4uaGIGPB4Qm&Sk`7S;sEYf^DZ7>J|b?T!2t%791Jq^4Mao_TgCdLs;9xqIDr~h
zIKw4=;I!I%KaD^ai};Cq_>E(nYcu%uFM-)A#4f&Jp%7+@U|*Zf_hEt5K2wb&EN14x
z^+H5EE7$w`3Yqz~W|j~)u~NSBjY|`ru|{GIUx(HQ^}%C9%*-q7O*o(xXqsl{e@)}i
c>2x0d0iecCbbbgvPyhe`07*qoM6N<$f*ByR*#H0l
literal 0
HcmV?d00001
diff --git a/companion/src/themes/monowhite/24/folder-tree-read.png b/companion/src/themes/monowhite/24/folder-tree-read.png
new file mode 100644
index 0000000000000000000000000000000000000000..3e7a66cf8d636e8c8d7c02e112891437f6bce6c2
GIT binary patch
literal 625
zcmV-%0*?KOP)6j2n#e@C-MiAoX#K~Y2$B!mPkQtP50K~PXw5NvD|{SJbK_z@zAg?5RR
zU}Cp6DQvU|X2s}$_%En2>MnaM=0zss%k0jG7lwJ
zv$%msU>#Vq-OTxq0Ea@t_dp$}0XKmgK-2cUe7=~1qN;(7V3uLV#0)SyjmvX)_Nu$6^+cT1m0;hoQz;@sx
z@HDIo6=3^z%r9v#X%Dcy2rOpy8bs8`2rTJJsBD7*(q@*j7=eHl+tVAIX@zZILekDi
z+)%#+n^_GQ1|Ae(CV?+i3Fd*rJuqK^*HsCQk)GJC;r$c1Z@W_zREA)W?P*Elf#eNv
zS<(vd30MobrtQ`Bpi;9)(jagm6m}kXWcv=#Bt7N3Nas^e1gwO^!)yXy|ya~XAwSfzgv*uEYEZkC{zm1#1h|M-E(=L2{f
z3n<_>pz?t-$u(62<(nf4TJgvVkN?X8%`mNn^hO1>DgytR#_{00000
LNkvXXu0mjf7*7h4
literal 0
HcmV?d00001
diff --git a/companion/src/themes/monowhite/24/folder-tree-write.png b/companion/src/themes/monowhite/24/folder-tree-write.png
new file mode 100644
index 0000000000000000000000000000000000000000..a14749b3914ef7af47cbd7e857571610230e3153
GIT binary patch
literal 612
zcmV-q0-ODbP)I$)wSBqU5o{Q(9WNhb?~!T;c2z(itb(y^lfF_=Uo
zL?S6g+(be&s)#l{hUdL+i2XQ+pZI~Vc#e%LMIbY8)riL
znK{|&X+(@FDO!X&f{ci3l~=7eh#PedbwV9MU^+AJED{zE=Wrw6vnifr
z=4?}`r&$yco0N%38FcqE^DZ9YX(b=*CV~&u&1}U2w&6`?KEtz!I2{qk(XXWMVY{I^
zf+5T*VYlM95^**KnfcdX)y7M(gdj7o*BxBWz)I+)$dn%6Ta!NcSf|iSk>{1?aXIW!
yhTozWt?LM?dEYbE^yqhkzDA=l@xP2m#KAu!JG+(@gr|o90000Vibxu5tgICR+SrJqrJ{|XqQtCVNJKCR5i}q+
zijAF(AQqzAs$gjd2nq_i;~z*Qt4Y?~}sEbEyPFL4v^#-?8X#M;N6wQtLpr^0g^n2
zJMm9dy*c3h6wc!B)^t^q_WSWYj$scTz>{5zcLHFhs*WZ((eZv9zf{#*eNba~qlKBq
zBA%+Mb6txM16a3`9MPowx+dj&@bZc+$-}Md{;GOqqyS0wVyUW5C)thH@HI|X)zT{8
zf!XW=Nc(vy$)KN4@QtS67NDvYFq`B-O*6Wwo&Qi(J=(R2p&6*Ew}-t?a!`}{{+Kz;
z_4#zw(NKVDgU{l(j<|pE>9EPyqqS<_VpW}5ZEVx~VmsWKWZ#fEc5DS;EnU=fyJv^^
z{Iy*G`*15hS<5lWU7CU&8Nh$|PSg3;tGPkO%>tAr{VTeF-_fh~HnLuA_Bfu#6Mf^`
z@d(~Ya^FTK+DZ-lR8?OkxfgfiOMHkIl02q41^?7sNZ@i+eLhM6Nha|$KEPqj;AB-@
zNwNd`G1Ss1jyS^zKg?O?U8
zv;fO1hN_y!EF_u6PR;$WQ(XX49Xnr9@GXAsa;U0BEGD_SVSuWd9TwEriaP<;tF5-;
zWgJd&&k&zO+XhfozvA(&%&}R3>o~ARovhZbLB?#bbB}`0R-n3i3(5Ew*UYD07*qoM6N<$g5A=AIsgCw
literal 0
HcmV?d00001
diff --git a/companion/src/themes/monowhite/32/folder-tree-write.png b/companion/src/themes/monowhite/32/folder-tree-write.png
new file mode 100644
index 0000000000000000000000000000000000000000..76cea1acb87c267c5566d0ca7a03092e7aa62d4f
GIT binary patch
literal 794
zcmV+#1LgdQP)OlF7tVR-M|d(J)od(OG%+)-7g
z@xvpyxqaV)rv_wZdc9sLyN5~!-rG_L*)uWP(;7522D`5!t%kmPAx
z+b(*nV}4eXSU)3}!wSBxs!x*y`*9Oq#+$eWpLenDIzmU*KRf2PljX)gh^h&m8}Qf!*@8)dSy@REx4{reoRMo!&vPZ@t
zkoMV2^5T&BZ*c|ALRI~VSCZU^=i36bjJvDq$zhw=&;wQV?nd)TZpG?=&H@(J$#m{~
z6oG1$Kfo_T^iJcGjTXNUjLLx@tLpIJV3O^4w*8!Ib72^^O+sK4PGd=PR5j*ez-cEAY
zI15dZ1HGy`p5#tVtzW>0IGE%yO_+YQRwvF@)yJDj;CxrykN0tZ`~F5%{gq@ZZm@O?
z4`6HpyM~nFt(uF+4xFs26F8CNMol?h(ln=KoU5w0lKjzSU=)GpT4P=K8#`M=psMXh^nx!n7tc;q)e@GH{4+Lzs_Jt4n)S6(Je0tNV$xE)f(MiA
z-azJ#sS&8EpYX&aYg{aWRop%zPX;m9HJJ9&cquT`@AsFd^51YATyg?4{eJ(k
literal 0
HcmV?d00001
diff --git a/companion/src/themes/monowhite/48/folder-tree-read.png b/companion/src/themes/monowhite/48/folder-tree-read.png
new file mode 100644
index 0000000000000000000000000000000000000000..f87930d4f5a81177872c7e44abf560fca213ceaa
GIT binary patch
literal 1238
zcmV;{1S$K8P)$W1Iq@ffPSO`H&R0KgE8nqNfEtXhBVOaeURzzP|mRneV
z#6pqeM@G3(tEL%kM5&ekNkJ+RrbvY{L$YSE+q$i~Pk)@dwqG-I#+^HZ&;ys5d(L~G
z^FDLVdFOr4#Wt0^fDEt-m@usURiG)BCzs1D%Vx8G*HC$6fIES9NfQRO&j40Px;ci#
zb}dj}4FUZ?7Wjl9qBd#o23mn9V?_W|T!8J9z$-vAuo>8t%*4~cJ-}+<2}!ra@Qq8$
z(L%7jL6Qg#Zvr*~^MN~nEx=k}i6m@y6ymCi007(Vl4b$d0^b5FZ7-6v5ZDXM1GY(O
zwEcTNo@(p?03^-ezh%@6tduk!cpG>DXaQa<{;wgSt6=YdCT@0Rp3unV{j_`>$O7^0#ABs~TU#OwXGw-m9j1s)%zs~T^#lB83%we;TRp0ZC23?SvF!
z573_c59|b-|K;%Atd$*;Nc|KX_a(t($$xIjwfv9_hX!j5il+p_$Y8;4Cx?b2+?H(k{oA5
zo+Ig2U{34+F{wmWCF*9HQNmGIEfP+QsGr$qs3&!YM6ru$H0)DXFT*z3`
zB;dobIu?sc59{51gdP$SZF<4rgIA?ofzD`MVfeuNFZT~cufhtkZTnRK0W_vI2x$W(e
z4goEaW&*zvju!u7WbV{v`^S9zX%{pC-XI*EoCK~0zLwOIWTST{HZuuJtacd10^nkx
zIs$<6fdjU8B=4{=`x_zb`K%ekBIk@t|>M^sRFK&w4nsf2Ex)f4cpz4<^zj>
z&yuLsLs&ioXtVukj62yVK
z)<>cL1ymd3a=F~%YCCa;XarC;n;q@7&RK(h0eTDIzi0gU761SM07*qoM6N<$f{0`m
A8UO$Q
literal 0
HcmV?d00001
diff --git a/companion/src/themes/monowhite/48/folder-tree-write.png b/companion/src/themes/monowhite/48/folder-tree-write.png
new file mode 100644
index 0000000000000000000000000000000000000000..86c96905f0ac76de65d3001a26e3c34a7f6de0bd
GIT binary patch
literal 1241
zcmV;~1Sb25P)|yqDr$@f4c~@{vW&0~iW)Q%%!CptlAa=p41!2PsfQwZ
zkV#Wsz8fEHj?h4$Nk^DB)h6bkDKg@UKiU`T2Px`BJj+HVE61FcEp8%iJ=
z|0eJWppy2Rfv17prR|l_Fapu|t-wdXHNe}keIf7+@Cq;;IGm)XAp|5f0iD3d!1cf$
z+ntgY0BeDlfX9HPwnvh5O*w&R{1)I-;5wk+_6A8e0qY3HKMpLi{cA0KjaY#u!qymx
z@8hxk3gBnp!uUR#Mp<(X1}4Jxn55;vTfk0Wu_WRa5^x952XsqXVS6G;-;@&ousts6
zKA@N2Dwjx_u)R4R?uEdIz*b53Cy}U0K+>~>r3M(Z-Bm;W48lPy$1v~#sBsUZ*+R!{4@jDoLbiw_wg;;8y&-8H&?9L*f!s1e*zgykXBq~6
zN}4G5Ga%`1!pcnpz682#eMa!A=r;tfkc1}S2iqN!F)S_85OB%&
z2ey|c2}?Q~=$VvN888*G(7BSboSloZD9@X~FfapnKI6E=c&ik-60m)M5GLe?ya>#S
zetxo;0~|~e$b-Nr@D6Zw9dvyU3?>QGoq+8z;DvhYt%kZ2kkkUKs?aq8{0Mw*J26Dg
zf;@t`>4YfqaLMyqY`+%RB&kQzdG(kquR}Z(BhQM6C6xChJ!1Qd$xJjA3C(=qPC{xp
z2)t{1x1;=h2EF6-u4bcqJyMMfSJHK
zWh#~fb4l<-d9OelA)(n5fA>pz4d|5A4!mglsO>_f!Lihsh^zz_q)cdvNz7T4RoHAF
zi-oO~z;;Qc)wv=z+U`wbP!mTsAs0Rcwoej@yPW`%S_xYS;CA5hv__>S
z;P978VyU|VQYAF;@*4w?l&U6LL>dAYOWK=3r+|I7AIf6L>7ph9+jFugoa%(8;s23M
z7J0kT-+_54JXbk3rWMRPq1jJa&9mOfi@=PGd2lscKm!t*aYFfJO`Y_8m(-a@LNh`L
zr>6w}c`x)ofkvZwXlUr+MjLUOXa`WCP;f2De>46BcFXj?ga~Wl00000NkvXXu0mjf
DIBYc6
literal 0
HcmV?d00001
diff --git a/companion/src/themes/yerico/16/folder-tree-read.png b/companion/src/themes/yerico/16/folder-tree-read.png
new file mode 100644
index 0000000000000000000000000000000000000000..5d5e602ea1e484c99e8924b992f84e2adff49bd1
GIT binary patch
literal 812
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
DLbp>Z
literal 0
HcmV?d00001
diff --git a/companion/src/themes/yerico/24/folder-tree-write.png b/companion/src/themes/yerico/24/folder-tree-write.png
new file mode 100644
index 0000000000000000000000000000000000000000..dffadcb9913d393ec2026c18af4feacdb4f5f49c
GIT binary patch
literal 1240
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
TZV=@B00000NkvXXu0mjfv|UQ;
literal 0
HcmV?d00001
diff --git a/companion/src/themes/yerico/48/folder-tree-read.png b/companion/src/themes/yerico/48/folder-tree-read.png
new file mode 100644
index 0000000000000000000000000000000000000000..92e850066e2ae9e15bcdac6e7c6945a2a4ea5816
GIT binary patch
literal 2652
zcmV-i3ZwOjP)bpQYW8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H13F%2h
zK~!jgy_$P)RMj2FKj+@Nk0hIH-cJY!Aq0w|A|j3*E7nIXVl7q>OKa_j79?UtYsYG<
z(E6f^1RX`~)S^<;nsYL`8NXUa=NV0itmh5J;o4xm*{*h#pkPX>vg5Q~)
z+4K0F-}k$F?(d%8?_MFLWVAT^TxPanD)WR?=73ow5R)XN0gj$2J^`%~Sq(~=#4I&c
zbJz6cO|H@U7O@H_dv;u!F!h^3ECnuz(f|LXl$%kt*Nax1XpLoo5euj+88^<5=4ynz
z4Tz7$X#{kDd{O9@b%l4=){Vq4Y5`wt5*9~S)^em+OW)QQYxt$)NliE&Em&C*jK&};
z0p-u+O+}GgLCzdC#b_Yp0V%XaMJrAm9d4>J+=Q}?xeHOuecu^*04dHDrm^qnhTQ9i
zn|fLSWhFVc2r2)`ncFg_L!uP&&GL=8cbsn0kXxv%B=>d!Tr10HicAL;fiI3VLmN
zVH!cC5sHp>1V|~1i;7((5xqqcP_{95p^$Q`YEM=Rmb?l;prw-I+gAa?XbT;FF0(*L`8PlviHBh!6s$>kq)eO7
zglnI|o;Guij0k>kuKY3sdhLY#a2`<*n~+I!tN4{>3ISXVx+q-j4$WXlX6Kl~P2GHbTTe
zUvlhUccA;-0N7F|k$(QoIP&KpR13~2Kg3yhB?ub`DH#Zz0g06ZhAH0{sCrZH5h5MVW`0Mup5NIjG
zefVwiuHC}7Z(W1b1HS;C)sC#s$Wc^nR%AMT3PK&tH16FvtN_*S93Vi8&%`MkOnG!YSr^?!d*%DIe*GFqNuc>KerG=EbMB*g&m*(H
zc_u4M5t@400Hy=@#}YaRBJk4Sx%5SdpU|__&lhi>@Zbp
z9zcddBu|}>J*^M`X&U%yOG%k|D^hZi0_LFG^H>Sc9QkxM9S*k>a%N$5=41H0kv|We4&OUc`P}bAwTsWJ_bO>_a8&=Xbz9rQVWRX
z$8vx8K59Y&wzDUPx1%2PpeAIcDvWWmB8?E(3Y)UyQm=dA%oyw&VRh}LZ<8LoUv01`xp{U4^Pbz?KG#pQbYIQJS!Fnbv
zSdTR+3)SWfkLevPF|C=scq!>WT7d5FvsWz+bid210c}9)D0%lmQL(2N^ms9`CQm@`
z>^_nD8^0pytgFbnVM#>OU|lVq&psK@mvZUlV6Oc@3D`QX$hHF
zlk@S{egaZ_rs$^pkeH(L@X!M%@m9TuJtZGoO7||6ra|N0b$DxbM|7)LtxS6GFWB|M41v?nW7JrhN<8b0!j;4Hq6xkq?DV55Q7Aa8a*{9BhW_u2P??E@;O?+d4r(mSdYL;nm*qMLZI55
z2*rXCJjuyjT?3X8s)f`Ui_kq4v>kl8SI=hX&52d*bxh+?PR)s>L8yI%&ma^9iz9PT
zcUM~lwc8hw_v614Xsx2XdS_qGEG0(36LGn?tQj~bUxDY~i?kmN*R?uKp>BnKmAUeg
z?59BtUwRt`{qyKxYc)07iU-X}oN^th=dU2(t|ZW0M$mISe31%8LrcgYF6$iPv(F*q
zE~n{}hXx1~@YlkX4XdGFRYK^NbyCxB<203tv4Xc^8{Ud-*wUxtoVEz(
zv13infsh;Dw>xRr@z5Z1T{XgWp|F6$yKC#pOLEo#kBt>kVYL&Vd+urH_^RH*71R8{rGM4-y{k|7>kQWzJ`FJ(Up5UL@eWQ8Di&lbFl+tJjXjQoY#UVRLQh
z-!b4cI%}B>nW}Lk&_0%4#|S=5Wl8_KC=5|vKe{3JdMV_a#89DDEOBJa{&nm$`=P6?
zhPET`0T>AR)2Vm5wx2p@=m#7da+e7qUltsc;c~k!M95WuchvNThF?k^Hr#1*qahD5ylQY{eMXK@)O&>x
z%NV=6c87!)Ox1XDq%VMs>SYg1<0b?@7m^DZc^OX%_%D)Ibwk@S{q9=#@Fs&1vw;4n
zdOkbT(78-XE&@>moCRdi?{yoX88`;AObALbpQYW8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H13Ghio
zK~!jgy_$P)RMj2FKj+@Nk8Cyxd6EYYfg}X1JVa2m&iHDpBeqgIV)0R`m0Dg^iyfU>
z87xzrN>O<@YAZ7eRq=s9(T$p6e&7fBH=$eBls@9B8_dLn9r*GUVR42>E<%b`^em0xMnFoQ)r50(@zUy0
zA`=pFpz?*Hi70X_$f-l7mty??5pReP`qWq?jg5<51PQ
z!nyH8FX%wU`ho>Q%D1?9OXfmIlR~~zxuNi(3keOlgeuk-{#w9Gsx=h=DNW2sAOX9A
z?m68sjS$j^Bu2X*NGX?vu4xFN{H%0I-S+bb`YfU2FXj~sDK`P?U@XLiP_U*K
zkvVA&V{coFJ$u4nW~)+~o2xbym7PDJ#Ws$w{GL_K(%uD`K2*NlFe3r`nm`^mj@G#n%1ZNSt!`pyjn2z%?hn@&@jZ+!WRxN^oq8C{RP9MH1QJu0Q>
zf431L3Hp*#?>&SbXaT^MHJ+Ty@5VXiN`z`5qvR$sN`C~x2Ex*5L+W6LL5A_UKBw;E
zr+X;C^wePfZ-F)4ebFUU_1x$pDaDgXupAH(UsIGkK&a&;b-Pz_?&~)}%SPHu=h8Tsd;5sa6MZI(i!HV+da|^oL(O*ES#$!P5?IQ-N)k)eV
z-;YaLvGzn4rXK7w?i_a`sm1qju6!?k*M7{1zkfwSV9zRHIfbe%
z2Yv@#yHICfW_-(evCV)xN`eTroTPU9vTjD?Ui}BO5hZwzzn9>a+zCg)bTTIVfVvOv
zL-#cR_@$zbEn9r1Sp(>bD*Fazrjayx0AhCN{F~Nd7?S2ATY3#xGsfb`pNifb#4)}E
zBiKr?xtc)Z5v1N34h7DBMa0)g(XFphx9dK1e`Bg*7caKX)Axbhj{vEvZvmIJ$Ev#`}WeZb1S)PI%%XA-;5dd;i=d`
zd(B56B@u5u%}3v&aL#ME-u*Gs2;T>6)XJaFEl^Z#M*nnrJc#(4X#8wLTnAKpMlT06
zM;^}7xwsGZ%ykr8PTtH#2+c;Ix`NuZt4XLh#0-K6A{;r?PH(ufdlci}s|
zkDRL>r)l5QGrxIZh-;t_Trz+*4Z0**ZrCHn%&5*%m;<9WCo(41rFXey7kQ;TL{
zNh?G~BAi_HB*8PT9%0kO@Oh&j&Wq79C-p?ufySexj=cd86E%b=X6SkS03Kw~(ReJz
zftesBr`P=j-?5{;MEzCe9J%YZe$^DrUqHe91!$?c=>8_89zySEN73x18j=yi$=Qqq
zsQ=^{0CKNgjo#4{b=oq=Q@{CDTK0ULly2LIap?Xg0E|!@sxv=JW0;c_X+-eWehNU=
z>=0(S=cH}>^fMaX-jcL#)t(W3HX;GklssqLlyXRr5}{e6&0zhvLsA!edMm0G8SzOC
z@Bvvv(i{WT>SWZ-s{pX3<)PU!i0EzrvgiB|!yDw>N4t{Jt^3{4XT|13_n-A@fQMmp
z07b=~Q{4Hin%J_6iF6t6XgtE`#gC%w6Cq|Lww)vL$TSJ@YHG?6G|?q!wmay
z?_V3uEiCCpSkns$xc&=L>{oPCegYTgDAR*&_-a1DnwpCve|lH1r0LMhc*?h-q}V8a
z`dRFwM$_M^AM%`{e$NWR?VaUPp<2nl^iCQ+Sq>m0(%dVglvJ)S_#Bvdz5>-gg6^_P
zG6=PtqIUaIRC^|)?|7ecU%f`SttWiYQgcZke-jql7`%s%G4l3#m|-8m=1P371NiF>
z_JkBdA$QsW0`QMve!h+fzAN5-RQ!Ea0ru~AD`!Jp(o4Um}Lw8QBYHwf~t2sX>mIjgbLEb?q
z3KnNxpYE{d1g`hzQgrL`PtFZdJi%y1DERy&Tu
zX&037)ojC8vn|@Trsp&A>Lr~GQ|}`$VP)*yTCd8S&(^RuHIzS3!1O*dlYlj?kkMUn
z(JQ?{9Fxgr;m+
z{VNiF3H1FZeRnV<;x_}4hXigZt2PwfE~WW8kT%@x;-DQN@9l5d#3G?<*79|EB|@lM
zhii9A0EZ3Lm^XQm`$Rm!gmU6Z%iPrsEe*2}@?pR`WO@T5ASEk}mh9PykcT8*H7I{R
zw?HWBV?v094Bx5km+-Qw8qW^)1&|@V?15?g9Kk(8GK;~N@uYx*NVe#P_U7bATrKgZ
z^hMGR#G>Y<{5(VFdMUXIL>Vv+$R*}=8=wg|1+qd24yYP?COp*O9!O`R_&+u#ByWmR
RknaEh002ovPDHLkV1g!l8?yia
literal 0
HcmV?d00001