Compare commits

...

74 Commits

Author SHA1 Message Date
Max Paperno 85863358fb [Horus] Outputs widget: Fix bar graph overflow with extended limits (#4969)
* [Horus][Widgets] Outputs widget: Fix bar graph overflow with extended limits (closes #4968); Show standard/translatable source names (CHxx) when no custom name is defined; More const-ness, less math.

* [OutputsWidget] Yet more const-ness and less calculation repetition.
2017-05-30 18:37:38 +02:00
3djc b397af1bac Fix overflow when firmware filename is too long (#4971) 2017-05-30 18:36:36 +02:00
Max Paperno 0906bdc6d7 Adjust logical switch abbreviations. (#4965)
* [Companion] Change logical switch abbreviations to "LS##" in Source/Switch selection lists.

* [LogicalSwitchesPanel] Normalize LS name label.

* We had decided on "Lxx"

* Match firmware side

* ARM wasn't using the translations

* Update strhelpers.cpp
2017-05-30 18:36:04 +02:00
Arne Schwabe 77925f6abc Fix issue #4961 (#4963) 2017-05-29 18:16:01 +02:00
Martin Hotar 0a0893e6cc cz translations of companion (#4964) 2017-05-29 18:15:21 +02:00
3djc 3d17023bc9 Fixes numbering discrepancy for Horus inputs (#4967)
Fixes #4966
2017-05-29 13:24:29 +02:00
3djc fd16151850 Update CREDITS.txt 2017-05-28 10:21:12 +02:00
Arne Schwabe 2ae0472f76 Minor fixes to lua dua 2017-05-28 09:48:34 +02:00
Arne Schwabe cd23fedb56 Schwabe/lua set curve (#4955)
* Implement setCurve for lua

* Bug fixes after actual testing of API

* Fix documentation

* Even more error checking

* Add example code how to use this function

* Silence gcc warnings

* Drop points and start array index at 1 and note about wrong index in getCurve

* Add standard example

* Fixes

* Don’t use an invalid number in example

* fix missing 0
2017-05-28 07:30:43 +02:00
Bertrand Songis 1cb0156cd0 Update CREDITS.txt 2017-05-25 11:25:30 +02:00
Arne Schwabe 4880c029b7 Schwabe/fix curve overflow (#4951)
* Fix curve editing function not checking if there is space for the curve

* Fix compile error
2017-05-24 18:42:56 +02:00
Arne Schwabe c79994d812 Exit if the FindSDL script finds 2.x instead of 1.x (#4948) 2017-05-23 16:46:36 +02:00
Sebastien Charpentier f462af1b0e Updated French translation (#4946)
* Updated French .ts file.

* Updated French Translation.

* Missing space.
2017-05-23 16:12:04 +02:00
David Zumbrunnen 8729bbc41b Fixed syntax error in UDEV rules (#4945)
Extraneous semicolon results in an error saying: `invalid key/value pair in
file /lib/udev/rules.d/45-companion22-taranis.rules on line 1, starting
at character 83 (';')`
2017-05-23 13:46:10 +02:00
Max Paperno 0fc1681d5c [Companion] Improve first use of Companion & upgrade notice (#4940)
* [Companion] On first use of Companion show preferences dialog and new welcome message (closes #4731); Improve detection of new version upgrade & reformat message; Add download link URL to Linux update notice (closes #4774); Fix issue with leftover top-level settings categories when checking for older versions which don't exist; Introduce basic structure for warnings/messages to be suppressed by user preferences (eg. "don't show this message again" option).

* Welcome msg typo fix.
2017-05-23 09:44:47 +02:00
Max Paperno 69576cb17d [Companion] Speed up/fix findMassstoragePath(): Use Qt methods when available (v5.4+) and only check for path on FAT[32] file systems; For older Qt, skip root (/), /net, /proc, & /run devices on Linux/macOS; Fixes long delay on eg. macOS due to network access. Remove unused #include "mountlist.h" in process_flash.cpp. (#4937) 2017-05-20 21:34:26 +02:00
3djc 1a85956dcb Tentative fix (#4939) 2017-05-20 21:33:43 +02:00
Arne Schwabe 01150497bb Schwabe/log sensors by default (#4932)
* Log telemetry sensors by default

* Renome now redundant logs = True code from Frsky
2017-05-19 17:19:43 +02:00
Sebastien Charpentier 0ed7f5a5ad French translation (#4936)
* Created French .ts file.

* Fixed some French translation.
2017-05-19 17:18:59 +02:00
Bertrand Songis ce83cf00e0 Update CREDITS.txt 2017-05-19 17:16:38 +02:00
Andre Bernet 8eea072cd1 Don’t spam simulator with dummy values on telemetry reset anymore (#4933)
* Don’t spam simulator with dummy values on telemetry reset anymore, simulator can be used if needed

* Ditch more dummies
2017-05-18 07:11:48 +02:00
Andre Bernet 4d23292ad3 Empty error message box is no fun 2017-05-16 14:39:27 +04:00
Damjan Adamic 618832974e Re #4718: added missing dependency libqt5multimedia5-plugins for Debian/Ubuntu packages (missing sound when using Qt Multimedia) 2017-05-14 19:20:51 +02:00
3djc c80fbf2de7 Get lua fields info from inside docker 2017-05-14 12:35:13 +02:00
3djc 5b69ceff0d Further follow up 2017-05-14 08:40:47 +02:00
3djc 3cc3687dcb Follow up on next rename 2017-05-14 08:11:04 +02:00
Andre Bernet eb7c73668f Leftover stuff on Windows uninstall 2017-05-13 16:18:56 +02:00
Damjan Adamic d35d3b5e22 Prepare Launchpad scripts for non-nightly release 2017-05-13 14:02:59 +02:00
3djc 935518f6dd Let's build a few more 2017-05-13 13:37:02 +02:00
3djc 20dcee3a5c Release prep 2017-05-13 13:17:14 +02:00
Arne Schwabe 5825a2ec2c remove dubious GNUC and rename 9x refrences 2017-05-13 13:05:47 +02:00
Arne Schwabe 355f4b5f92 Also download and open new updates on OS X (#4926)
* Also download and open new updates on OS X

* Cosmetics
2017-05-13 13:03:39 +02:00
Andre Bernet 9437d98df9 Merge branch 'kilrah/companion_sdcard_download' into next 2017-05-13 11:55:59 +02:00
3djc 7a8ca1c675 Match release dir struct 2017-05-13 11:49:58 +02:00
3djc 79d9359e56 More release prep 2017-05-13 11:46:13 +02:00
3djc 006166a25c Release helping change 2017-05-13 11:17:48 +02:00
3djc 33cc0861a6 Release prep 2017-05-13 11:00:07 +02:00
Bertrand Songis d48ab63497 Update CREDITS.txt 2017-05-12 22:09:07 +02:00
3djc bd62281144 X12 : split S6R settings and calibration scripts (#4920)
* Quick and dirty split

* Some cleanups
2017-05-12 19:53:46 +02:00
Bertrand Songis 50397d0052 3djc added
Thanks for your help!
2017-05-12 07:56:00 +02:00
Andre Bernet 460e6aab96 Update all custom screen references after deleting one (fix #4909) (#4914) 2017-05-11 18:39:26 +02:00
3djc 95b0a21cfc Introduce S6R calibration tool to x7 (#4916)
Introduce real time position feedback
Autosense between S6R and S8R (not same sensor orientation)
2017-05-11 18:39:10 +02:00
Max Paperno f7b6d95910 [Companion] Input names formatting (#4888)
* [Companion] Re-format Inputs list to format input name consistently with rest of UI; Add leading zeros to RawSource numbers in names; Show custom channel name in MixerDialog.

* [Companion] Remove colon separator between input number and custom name.

* Fix segfault when no model pointer is passed to RawSource::toString() (problem was only on this branch).
2017-05-11 07:37:13 +02:00
Sebastien Charpentier 6e0bec9db4 Update French translation (#4908)
* Generated new French .ts file.

* Update French translation concerning the new SD sync mechanism.

* Skip must be translated as "Ignorer", not "Sauter".

* French mistake.
2017-05-11 07:36:54 +02:00
Bertrand Songis 83132ef041 Update README.md 2017-05-09 09:30:06 +02:00
Max Paperno c1586b72bb [Companion] SD Sync reworked: (#4906)
* Complete re-write of SyncProcess, now more robust, UI-independent, runs in own thread, large speed boost;
    * Use file hash comparisons instead of byte-level compare with string methods (probable fixes for #4837 and #4848);
    * New pre-sync options dialog with selectable folders and other settings (settings are remembered until app exit);
    * Option to choose sync direction(s) (up/down/bi) and the order in which bi-directional sync runs;
    * Option to choose file comparison mode (timestamp/hash/both) or force overwrite (for one-way sync);
    * Option to set a maximum file size to copy;
    * Option to do a test run w/out actually copying any files;
    * Better reporting of progress, total counts (copied/updated/skipped), and errors, with color coding;
    * Much more reliable to cancel long-running/hung copy process;
    * ProgressWidget can now display rich-text in the text browser, added some new functions for usage;
    * Misc. small layout tweaks to ProgressDialog and ProgressWidget to make them behave/look better;
2017-05-08 20:51:26 +02:00
Max Paperno ca25696d1a [Companion] Radio module setup: Fix custom failsafe no-pulse and hold options not being saved properly (closes #4904). 2017-05-08 08:29:11 -04:00
Bertrand Songis 11579d9118 Update CREDITS.txt 2017-05-08 13:48:13 +02:00
Andre Bernet 32714fb841 No more subdomain 2017-05-08 12:33:15 +02:00
Andre Bernet 2bc2030f86 Merge branch 'next' into kilrah/companion_sdcard_download
# Conflicts:
#	companion/src/fwpreferencesdialog.cpp
2017-05-08 09:48:53 +02:00
Bertrand Songis 93dbdf8680 Just some comments, the very minimum 2017-05-07 22:27:10 +02:00
3djc 301e33a271 gTTS (#4899)
* Release prep work

* Add CZ support

* Prep for release

* No more need to prefix unicode strings (we use python3)
Some fixes
Italian fixes
2017-05-07 17:39:31 +02:00
Sebastien Charpentier 53bb8bc6c3 Updated French translation. (#4902)
* Generate nex French .ts file.

* Updated French translation.
2017-05-07 17:39:06 +02:00
Max Paperno e2502772cb [Companion] Model Setup: Prevent bogus modification signals. (#4896)
* [Companion] Model editor Setup panel: Prevent bogus modification signals, eg. when populating protocols box or when removing focus from some fields w/out the value actually changing; Remove unnecessary function.

* [SetupPanel] Fix comparison warning and also a translation issue with Multiprotocols subtype and option names.

* [ModelPrinter] Add a missing include.
2017-05-06 18:09:20 +02:00
Max Paperno 24de312a30 [Companion] Some radio settings Hardware tab fixes. (#4895)
* [Companion] Radio -> General Settings -> Hardware: Hide external serial port option for Horus; Fix battery voltage and current calibration changes not registering (wrong signal handler name); Prevent modified() event if edited value wasn't actually changed (this is a problem in all panels with onEditingFinished() signals); Fix some cosmetic layout issues when no hardware names are editable.

* [HardwarePanel] Minor layout fix for BT option.

* [HardwarePanel] Fix comparison issue.
2017-05-06 18:08:55 +02:00
3djc efe53eb034 Fix translation for audio files (#4889)
Switch the time mechanic to english one (may not be perfect, but current italian is not working at all)
2017-05-06 18:08:28 +02:00
Max Paperno 96ccb4cb3f [Companion] Fix a few translations. (#4890)
* [Simulator] Fix keymap translations.

* [Companion] Fix translations in file type selector dialogs.

* [Simulator] Fix inadvertent help text delimiter change.
2017-05-06 18:04:51 +02:00
Bertrand Songis 3f06037e1b [Companion] Credits dialog refactoring 2017-05-06 17:55:03 +02:00
Bertrand Songis 38d8f6a326 Update DONATIONS.txt 2017-05-06 00:13:12 +02:00
Bertrand Songis 2bec60517a Update DONATIONS.txt 2017-05-05 07:28:32 +02:00
Bertrand Songis d3b8133ee2 Add LapinFou to CREDITS.txt 2017-05-02 07:33:10 +02:00
Sebastien Charpentier 4b2b5a9d37 Logical switch L% or LSw% are now translated in IL% (Interrupteur Logique). (#4886) 2017-05-01 17:44:08 +02:00
Bertrand Songis 6edc3b61ff Update DONATIONS.txt 2017-05-01 08:29:22 +02:00
Arne Schwabe f525b1762b Fix #4881 (#4884)
Thanks Mike for noticing: In pxx_arm.cpp, the pulse duration is set to either 48 or 32. This value gets put into the ARR register of the timer (via DMA). Counters count from 0 to the ARR value, then go back to 0. This will result in either 49 or 33 counts for the pulse width, thus making the pulses 0.5uS too long.

Tested only with external PXX
2017-05-01 00:33:45 +02:00
3djc 4f5f241669 Fix opentx-9x-autoswitch-autosource-dblkeys-battgraph-telemetrez-sp22-stickrev-pgbar-en.hex (#4883) 2017-04-30 23:19:43 +02:00
Bertrand Songis 0b25332171 Add @schwabe to CREDITS.txt 2017-04-30 12:58:49 +02:00
3djc 054c87c91e Fix adjust GVAR and Volume (#4880) 2017-04-30 12:53:25 +02:00
Bertrand Songis e053abfc3e Max added to the CREDITS.txt 2017-04-30 08:57:36 +02:00
Max Paperno 6abd36d628 [Simulator] Revert logic switch names in Radio Outputs view to numbers-only (since @72b1ad0, closes #4877). 2017-04-29 20:49:04 -04:00
Damjan Adamic 582546f8ed Fixes #4839: path buffer overflow if LUA widget or theme directory name was too long (max length of directory name is 13 characters) (#4876) 2017-04-29 22:18:11 +02:00
Damjan Adamic c1e7235375 Launchpad changelogs for 2.2.0 RC18 2017-04-29 19:26:49 +02:00
Bertrand Songis 975023bdc7 Update DONATIONS.txt 2017-04-29 16:02:37 +02:00
Andre Bernet b8e0f26a22 Cosmetics 2017-03-20 10:31:39 +01:00
Andre Bernet 22217e8e22 [companion] Replace voice download by SD download, new URL for 2.2 (sd-22.open-tx.org, needs to be created) 2017-03-20 10:24:43 +01:00
111 changed files with 7731 additions and 5670 deletions
+4 -1
View File
@@ -6,7 +6,7 @@ set(VERSION_REVISION "0")
set(VERSION_SUFFIX $ENV{OPENTX_VERSION_SUFFIX})
set(VERSION_FAMILY ${VERSION_MAJOR}.${VERSION_MINOR})
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}${VERSION_SUFFIX})
set(SDCARD_REVISION "0009")
set(SDCARD_REVISION "0010")
set(SDCARD_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}V${SDCARD_REVISION})
cmake_minimum_required(VERSION 2.8)
@@ -133,6 +133,9 @@ if(Qt5Core_FOUND OR FOX_FOUND)
find_package("SDL")
if(SDL_FOUND)
message(STATUS "SDL Lib: ${SDL_LIBRARY}; Headers: ${SDL_INCLUDE_DIR}; Version: ${SDL_VERSION_STRING}")
if (NOT ${SDL_VERSION_STRING} VERSION_LESS "2.0")
message(FATAL_ERROR "OpenTX requires SDL 1.x, not 2.x")
endif()
else()
message(STATUS "SDL not found! Simulator audio, and joystick inputs, will not work.")
endif()
+1203
View File
File diff suppressed because it is too large Load Diff
-1183
View File
File diff suppressed because it is too large Load Diff
-1
View File
@@ -10,7 +10,6 @@ The ongoing development on 2.2.x is done in this branch.
Refer to the [OpenTX wiki](https://github.com/opentx/opentx/wiki) for information about setting up the tool chains for building OpenTX and OpenTX Companion as well as other development related issues.
Useful links:
* OpenTX Blog http://blog.open-tx.org/
* OpenTX Main Site http://www.open-tx.org/
* OpenTx University http://open-txu.org/
* OpenTX User Manual https://www.gitbook.com/book/opentx/opentx-taranis-manual/details
+2 -2
View File
@@ -218,7 +218,7 @@ set(companion_SRCS
burnconfigdialog.cpp
multimodelprinter.cpp
comparedialog.cpp
contributorsdialog.cpp
creditsdialog.cpp
releasenotesdialog.cpp
releasenotesfirmwaredialog.cpp
customizesplashdialog.cpp
@@ -252,7 +252,7 @@ set(companion_MOC_HDRS
printdialog.h
fusesdialog.h
logsdialog.h
contributorsdialog.h
creditsdialog.h
releasenotesdialog.h
releasenotesfirmwaredialog.h
customizesplashdialog.h
-1
View File
@@ -3,7 +3,6 @@
<file>images/customize.png</file>
<file>icon.png</file>
<file>../../CREDITS.txt</file>
<file>../../DONATIONS.txt</file>
<file>../releasenotes.txt</file>
<file>images/screenshot.png</file>
<file>images/splash.png</file>
+16 -14
View File
@@ -21,6 +21,8 @@
#ifndef _CONSTANTS_H_
#define _CONSTANTS_H_
#include <QCoreApplication>
#define CPN_MAX_MODELS 60
#define CPN_MAX_TIMERS 3
#define CPN_MAX_FLIGHT_MODES 9
@@ -47,23 +49,23 @@
#define CPN_MAX_MOUSE_ANALOGS 2
#define CPN_MAX_ANALOGS (CPN_MAX_STICKS + CPN_MAX_POTS + CPN_MAX_MOUSE_ANALOGS)
#define CPN_STR_FILES QT_TRANSLATE_NOOP("CompanionMacros", "files")
#define CPN_STR_RAD_MOD_SETTINGS QT_TRANSLATE_NOOP("CompanionMacros", "Radio and Models settings")
#define HEX_FILES_FILTER "HEX " CPN_STR_FILES " (*.hex);;"
#define BIN_FILES_FILTER "BIN " CPN_STR_FILES " (*.bin);;"
#define DFU_FILES_FILTER "DFU " CPN_STR_FILES " (*.dfu);;"
#define EEPE_FILES_FILTER "EEPE " CPN_STR_FILES " (*.eepe);;"
#define OTX_FILES_FILTER "OpenTX " CPN_STR_FILES " (*.otx);;"
#define EEPROM_FILES_FILTER CPN_STR_RAD_MOD_SETTINGS " " CPN_STR_FILES " (*.otx *.eepe *.bin *.hex);;" OTX_FILES_FILTER EEPE_FILES_FILTER BIN_FILES_FILTER HEX_FILES_FILTER
#define FLASH_FILES_FILTER "FLASH " CPN_STR_FILES " (*.bin *.hex *.dfu);;" BIN_FILES_FILTER HEX_FILES_FILTER DFU_FILES_FILTER
#define EXTERNAL_EEPROM_FILES_FILTER "EEPROM " CPN_STR_FILES " (*.bin *.hex);;" BIN_FILES_FILTER HEX_FILES_FILTER
#define CPN_STR_FILES QCoreApplication::translate("Companion", "files")
#define CPN_STR_RAD_MOD_SETTINGS QCoreApplication::translate("Companion", "Radio and Models settings")
#define HEX_FILES_FILTER "HEX " % CPN_STR_FILES % " (*.hex);;"
#define BIN_FILES_FILTER "BIN " % CPN_STR_FILES % " (*.bin);;"
#define DFU_FILES_FILTER "DFU " % CPN_STR_FILES % " (*.dfu);;"
#define EEPE_FILES_FILTER "EEPE " % CPN_STR_FILES % " (*.eepe);;"
#define OTX_FILES_FILTER "OpenTX " % CPN_STR_FILES % " (*.otx);;"
#define EEPROM_FILES_FILTER CPN_STR_RAD_MOD_SETTINGS % " " % CPN_STR_FILES % " (*.otx *.eepe *.bin *.hex);;" % OTX_FILES_FILTER % EEPE_FILES_FILTER % BIN_FILES_FILTER % HEX_FILES_FILTER
#define FLASH_FILES_FILTER "FLASH " % CPN_STR_FILES % " (*.bin *.hex *.dfu);;" % BIN_FILES_FILTER % HEX_FILES_FILTER % DFU_FILES_FILTER
#define EXTERNAL_EEPROM_FILES_FILTER "EEPROM " % CPN_STR_FILES % " (*.bin *.hex);;" % BIN_FILES_FILTER % HEX_FILES_FILTER
#define ER9X_EEPROM_FILE_TYPE "ER9X_EEPROM_FILE"
#define EEPE_EEPROM_FILE_HEADER "EEPE EEPROM FILE"
#define EEPE_MODEL_FILE_HEADER "EEPE MODEL FILE"
#define CPN_STR_SW_INDICATOR_UP QT_TRANSLATE_NOOP("RawSwitch", "\xE2\x86\x91") // Switch up position indicator: Up arrow, or similar.
#define CPN_STR_SW_INDICATOR_DN QT_TRANSLATE_NOOP("RawSwitch", "\xE2\x86\x93") // Switch down position indicator: Down arrow, or similar.
#define CPN_STR_SW_INDICATOR_NEUT QT_TRANSLATE_NOOP("RawSwitch", "-") // Switch neutral (middle) position indicator.
#define CPN_STR_SW_INDICATOR_REV QT_TRANSLATE_NOOP("RawSwitch", "!") // Switch reversed logic (NOT) indicator.
#define CPN_STR_SW_INDICATOR_UP QCoreApplication::translate("RawSwitch", "\xE2\x86\x91") // Switch up position indicator: Up arrow, or similar.
#define CPN_STR_SW_INDICATOR_DN QCoreApplication::translate("RawSwitch", "\xE2\x86\x93") // Switch down position indicator: Down arrow, or similar.
#define CPN_STR_SW_INDICATOR_NEUT QCoreApplication::translate("RawSwitch", "-") // Switch neutral (middle) position indicator.
#define CPN_STR_SW_INDICATOR_REV QCoreApplication::translate("RawSwitch", "!") // Switch reversed logic (NOT) indicator.
#endif // _CONSTANTS_H_
@@ -18,12 +18,12 @@
* GNU General Public License for more details.
*/
#include "contributorsdialog.h"
#include "creditsdialog.h"
#include "ui_htmldialog.h"
#include "helpers.h"
#include <QFile>
ContributorsDialog::ContributorsDialog(QWidget * parent):
CreditsDialog::CreditsDialog(QWidget * parent):
QDialog(parent),
ui(new Ui::HtmlDialog)
{
@@ -42,42 +42,8 @@ ContributorsDialog::ContributorsDialog(QWidget * parent):
"</head>"
"<body class=\"normal\">";
QFile credits(":/CREDITS.txt");
if (credits.open(QIODevice::ReadOnly | QIODevice::Text)) {
QStringList names;
while (!credits.atEnd()) {
QByteArray line = credits.readLine();
if (line.trimmed() == "")
break;
names.append(line.trimmed());
}
str.append(formatTable(tr("Main Developers"), names, 3));
names.clear();
while (!credits.atEnd()) {
QByteArray line = credits.readLine();
names.append(line.trimmed());
}
str.append(formatTable(tr("Other contributors"), names, 3));
}
QFile donations(":/DONATIONS.txt");
if (donations.open(QIODevice::ReadOnly | QIODevice::Text)) {
QStringList names;
while (!donations.atEnd()) {
QByteArray line = donations.readLine();
if (line.trimmed() == "")
break;
names.append(line.trimmed());
}
str.append(formatTable(tr("Companies and projects who have donated to OpenTX"), names, 3));
names.clear();
while (!donations.atEnd()) {
QByteArray line = donations.readLine();
names.append(line);
}
str.append(formatTable(tr("People who have donated to OpenTX"), names, 6));
foreach(CreditsSection section, readCredits()) {
str.append(formatTable(sectionTitle(section.title), section.names, 3));
}
str.append("<table><tr><td class=\"normal\">&nbsp;</td></tr>" \
@@ -87,9 +53,9 @@ ContributorsDialog::ContributorsDialog(QWidget * parent):
#if 0
QFile blacklist(":/BLACKLIST.txt");
if (blacklist.open(QIODevice::ReadOnly | QIODevice::Text)) {
QStringList names;
names << blacklist.readAll();
str.append(formatTable(tr("OpenTX Blacklist"), names, 1));
QStringList names;
names << blacklist.readAll();
str.append(formatTable(tr("OpenTX Blacklist"), names, 1));
}
#endif
@@ -99,12 +65,45 @@ ContributorsDialog::ContributorsDialog(QWidget * parent):
ui->textEditor->setOpenExternalLinks(true);
}
ContributorsDialog::~ContributorsDialog()
CreditsDialog::~CreditsDialog()
{
delete ui;
}
QString ContributorsDialog::formatTable(const QString & title, const QStringList & names, int columns)
QList<CreditsDialog::CreditsSection> CreditsDialog::readCredits()
{
QFile credits(":/CREDITS.txt");
QList<CreditsSection> result;
if (credits.open(QIODevice::ReadOnly | QIODevice::Text)) {
while (!credits.atEnd()) {
QByteArray line = credits.readLine().trimmed();
if (line.size() >= 2) {
if (line.startsWith("[") && line.endsWith("]")) {
result.push_back(CreditsSection(line.mid(1, line.size() - 2)));
} else {
result.back().addName(line);
}
}
}
}
return result;
}
QString CreditsDialog::sectionTitle(const QString & title)
{
if (title == "Main developers")
return tr("Main developers");
else if (title == "Translators")
return tr("Translators");
else if (title == "Companies and projects who have donated to OpenTX")
return tr("Companies and projects who have donated to OpenTX");
else if (title == "People who have donated to OpenTX")
return tr("People who have donated to OpenTX");
else
return tr("Other contributors");
}
QString CreditsDialog::formatTable(const QString & title, const QStringList & names, int columns)
{
const float cwidth = 100.0 / columns;
QString str = "<table width=\"100%\" border=0 cellspacing=0 cellpadding=2>" \
@@ -18,8 +18,8 @@
* GNU General Public License for more details.
*/
#ifndef _CONTRIBUTORSDIALOG_H_
#define _CONTRIBUTORSDIALOG_H_
#ifndef _CREDITSDIALOG_H_
#define _CREDITSDIALOG_H_
#include <QDialog>
@@ -27,17 +27,36 @@ namespace Ui {
class HtmlDialog;
}
class ContributorsDialog : public QDialog
class CreditsDialog : public QDialog
{
Q_OBJECT
class CreditsSection
{
public:
CreditsSection(const QString & title):
title(title)
{
}
void addName(const QString & name)
{
names.push_back(name);
}
QString title;
QStringList names;
};
public:
explicit ContributorsDialog(QWidget * parent = 0);
~ContributorsDialog();
explicit CreditsDialog(QWidget * parent = 0);
~CreditsDialog();
private:
Ui::HtmlDialog * ui;
QList<CreditsSection> readCredits();
QString sectionTitle(const QString & title);
QString formatTable(const QString & title, const QStringList & names, int colums);
};
#endif // _CONTRIBUTORSDIALOG_H_
#endif // _CREDITSDIALOG_H_
+7 -7
View File
@@ -508,9 +508,9 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
int genAryIdx = 0;
switch (type) {
case SOURCE_TYPE_VIRTUAL_INPUT:
result = QObject::tr("[I%1]").arg(index+1);
result = QObject::tr("[I%1]").arg(index+1, 2, 10, QChar('0'));
if (model && model->inputNames[index][0])
result.append(":" + QString(model->inputNames[index]).trimmed());
result.append(/*":" + */QString(model->inputNames[index]).trimmed());
return result;
case SOURCE_TYPE_LUA_OUTPUT:
@@ -544,13 +544,13 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
return result;
case SOURCE_TYPE_CUSTOM_SWITCH:
return QObject::tr("LSw%1").arg(index+1, 2, 10, QChar('0'));
return RawSwitch(SWITCH_TYPE_VIRTUAL, index+1).toString();
case SOURCE_TYPE_CYC:
return QObject::tr("CYC%1").arg(index+1);
case SOURCE_TYPE_PPM:
return QObject::tr("TR%1").arg(index+1);
return QObject::tr("TR%1").arg(index+1, 2, 10, QChar('0'));
case SOURCE_TYPE_CH:
result = QObject::tr("CH%1").arg(index+1, 2, 10, QChar('0'));
@@ -564,7 +564,7 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
case SOURCE_TYPE_TELEMETRY:
if (IS_ARM(getCurrentBoard())) {
div_t qr = div(index, 3);
result = model ? QString(model->sensorData[qr.quot].label) : QString("[T%1]").arg(qr.quot+1);
result = model ? QString(model->sensorData[qr.quot].label) : QString("[T%1]").arg(qr.quot+1, 2, 10, QChar('0'));
if (qr.rem)
result += (qr.rem == 1 ? "-" : "+");
return result;
@@ -574,7 +574,7 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
}
case SOURCE_TYPE_GVAR:
result = QObject::tr("GV%1").arg(index+1);
result = QObject::tr("GV%1").arg(index+1, 2, 10, QChar('0'));
if (getCurrentFirmware()->getCapability(GvarsName) && model && model->gvars_names[index][0])
result.append(":" + QString(model->gvars_names[index]).trimmed());
return result;
@@ -682,7 +682,7 @@ QString RawSwitch::toString(Board::Type board, const GeneralSettings * const gen
}
case SWITCH_TYPE_VIRTUAL:
return QObject::tr("LSw%1").arg(index, 2, 10, QChar('0'));
return QObject::tr("L%1").arg(index, 2, 10, QChar('0'));
case SWITCH_TYPE_MULTIPOS_POT:
if (!getCurrentFirmware()->getCapability(MultiposPotsPositions))
@@ -884,7 +884,7 @@ class FlightModeField: public TransformedField {
virtual void beforeExport()
{
for (int i=0; i<CPN_MAX_STICKS+MAX_AUX_TRIMS(board); i++) {
if (IS_HORUS_OR_TARANIS(board) && version >= 216) {
if ((IS_HORUS_OR_TARANIS(board) && version >= 216) || (IS_ARM(board) && version >= 218)) {
if (phase.trimMode[i] < 0)
trimMode[i] = TRIM_MODE_NONE;
else
@@ -912,7 +912,7 @@ class FlightModeField: public TransformedField {
virtual void afterImport()
{
for (int i=0; i<CPN_MAX_STICKS+MAX_AUX_TRIMS(board); i++) {
if (IS_HORUS_OR_TARANIS(board) && version >= 216) {
if ((IS_HORUS_OR_TARANIS(board) && version >= 216) || (IS_ARM(board) && version >= 218)) {
if (trimMode[i] == TRIM_MODE_NONE) {
phase.trimMode[i] = -1;
}
@@ -1207,7 +1207,7 @@ class MixField: public TransformedField {
if (mix.srcRaw.type != SOURCE_TYPE_NONE) {
mix.destCh = _destCh + 1;
if (!IS_STM32(board) || version < 216) {
if (!IS_ARM(board) || (!IS_STM32(board) && version < 218) || version < 216) {
if (!_curveMode)
mix.curve = CurveReference(CurveReference::CURVE_REF_DIFF, smallGvarToC9x(_curveParam));
else if (_curveParam > 6)
@@ -1410,7 +1410,7 @@ class InputField: public TransformedField {
expo.offset = smallGvarToC9x(_offset);
}
if (!IS_STM32(board) || version < 216) {
if (!IS_ARM(board) || (!IS_STM32(board) && version < 218) || version < 216) {
if (!_curveMode)
expo.curve = CurveReference(CurveReference::CURVE_REF_EXPO, smallGvarToC9x(_curveParam));
else if (_curveParam > 6)
+1 -1
View File
@@ -102,7 +102,7 @@ void FlashEEpromDialog::updateUI()
void FlashEEpromDialog::on_eepromLoad_clicked()
{
QString filename = QFileDialog::getOpenFileName(this, tr("Choose Radio Backup file"), g.eepromDir(), tr(EXTERNAL_EEPROM_FILES_FILTER));
QString filename = QFileDialog::getOpenFileName(this, tr("Choose Radio Backup file"), g.eepromDir(), EXTERNAL_EEPROM_FILES_FILTER);
if (!filename.isEmpty()) {
eepromFilename = filename;
updateUI();
+3 -9
View File
@@ -34,12 +34,6 @@ FirmwarePreferencesDialog::FirmwarePreferencesDialog(QWidget *parent) :
ui->setupUi(this);
setWindowIcon(CompanionIcon("fwpreferences.png"));
initSettings();
foreach(const char *lang, getCurrentFirmware()->getFirmwareBase()->ttslanguages) {
ui->voiceCombo->addItem(lang);
if (Firmware::getCurrentVariant()->getId().contains(QString("-tts%1").arg(lang)))
ui->voiceCombo->setCurrentIndex(ui->voiceCombo->count() - 1);
}
}
FirmwarePreferencesDialog::~FirmwarePreferencesDialog()
@@ -70,13 +64,13 @@ void FirmwarePreferencesDialog::on_fw_dnld_clicked()
initSettings();
}
void FirmwarePreferencesDialog::on_voice_dnld_clicked()
void FirmwarePreferencesDialog::on_sd_dnld_clicked()
{
QString url = "http://voices-21.open-tx.org/";
QString url = "http://downloads.open-tx.org/2.2/sdcard/";
QString fwType = g.profile[g.id()].fwType();
QStringList list = fwType.split("-");
QString firmware = QString("%1-%2").arg(list[0]).arg(list[1]);
url.append(QString("%1/%2/").arg(firmware).arg(ui->voiceCombo->currentText().toLower()));
url.append(QString("%1/").arg(firmware));
QDesktopServices::openUrl(url);
}
+1 -1
View File
@@ -45,7 +45,7 @@ class FirmwarePreferencesDialog : public QDialog
private slots:
void on_fw_dnld_clicked();
void on_voice_dnld_clicked();
void on_sd_dnld_clicked();
void on_checkFWUpdates_clicked();
};
+59 -86
View File
@@ -26,13 +26,22 @@
<string>Downloads</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<property name="verticalSpacing">
<number>2</number>
</property>
<property name="margin">
<number>6</number>
</property>
<item row="24" column="5">
<item row="23" column="3">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@@ -42,7 +51,7 @@
</property>
</widget>
</item>
<item row="3" column="5">
<item row="3" column="3">
<widget class="QPushButton" name="checkFWUpdates">
<property name="minimumSize">
<size>
@@ -55,75 +64,6 @@
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="voiceLabel">
<property name="font">
<font>
<family>Sans Serif</family>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Voice</string>
</property>
</widget>
</item>
<item row="7" column="2">
<widget class="QComboBox" name="voiceCombo">
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Set voice language.
May be different from firmware language</string>
</property>
</widget>
</item>
<item row="7" column="5">
<widget class="QPushButton" name="voice_dnld">
<property name="text">
<string>Download Voice</string>
</property>
</widget>
</item>
<item row="5" column="5">
<widget class="QPushButton" name="fw_dnld">
<property name="text">
<string>Download FW</string>
</property>
</widget>
</item>
<item row="7" column="3">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="6" column="0" colspan="6">
<widget class="Line" name="voiceLine">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="23" column="0" colspan="6">
<widget class="Line" name="line_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_6">
<property name="sizePolicy">
@@ -147,20 +87,28 @@ May be different from firmware language</string>
</property>
</widget>
</item>
<item row="0" column="2" colspan="4">
<widget class="QLabel" name="fwTypeLbl">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item row="5" column="3">
<widget class="QPushButton" name="fw_dnld">
<property name="text">
<string notr="true">FwType</string>
<string>Download firmware</string>
</property>
</widget>
</item>
<item row="3" column="2" colspan="2">
<item row="22" column="0" colspan="4">
<widget class="Line" name="line_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="6" column="3">
<widget class="QPushButton" name="sd_dnld">
<property name="text">
<string>Download SD contents</string>
</property>
</widget>
</item>
<item row="3" column="1" colspan="2">
<widget class="QLabel" name="lastRevisionLbl">
<property name="text">
<string notr="true">-</string>
@@ -174,13 +122,38 @@ May be different from firmware language</string>
</property>
</widget>
</item>
<item row="0" column="1" colspan="3">
<widget class="QLabel" name="fwTypeLbl">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true">FwType</string>
</property>
</widget>
</item>
<item row="6" column="2">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<tabstops>
<tabstop>checkFWUpdates</tabstop>
<tabstop>fw_dnld</tabstop>
<tabstop>voiceCombo</tabstop>
<tabstop>voice_dnld</tabstop>
<tabstop>sd_dnld</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops>
<resources>
+36 -19
View File
@@ -110,6 +110,8 @@ HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings
ui->thrName->hide();
ui->ailLabel->hide();
ui->ailName->hide();
ui->potsTypeSeparator_1->hide();
ui->potsTypeSeparator_2->hide();
}
setupPotType(0, ui->pot1Label, ui->pot1Name, ui->pot1Type);
@@ -141,10 +143,11 @@ HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings
setupSwitchType(16, ui->sqLabel, ui->sqName, ui->sqType);
setupSwitchType(17, ui->srLabel, ui->srName, ui->srType);
if (IS_HORUS_OR_TARANIS(board) && !IS_TARANIS_X7(board)) {
if (IS_TARANIS(board) && !IS_TARANIS_X7(board)) {
ui->serialPortMode->setCurrentIndex(generalSettings.hw_uartMode);
}
else {
ui->serialPortMode->setCurrentIndex(0);
ui->serialPortMode->hide();
ui->serialPortLabel->hide();
}
@@ -160,8 +163,7 @@ HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings
}
else {
ui->bluetoothLabel->hide();
ui->bluetoothEnable->hide();
ui->bluetoothName->hide();
ui->bluetoothWidget->hide();
}
if (IS_HORUS_OR_TARANIS(board)) {
@@ -188,39 +190,52 @@ void HardwarePanel::on_filterEnable_stateChanged()
void HardwarePanel::on_PPM_MultiplierDSB_editingFinished()
{
generalSettings.PPM_Multiplier = (int)(ui->PPM_MultiplierDSB->value()*10)-10;
emit modified();
int val = (int)(ui->PPM_MultiplierDSB->value()*10)-10;
if (generalSettings.PPM_Multiplier != val) {
generalSettings.PPM_Multiplier = val;
emit modified();
}
}
void HardwarePanel::on_PPM1_editingFinished()
{
generalSettings.trainer.calib[0] = ui->PPM1->value();
emit modified();
if (generalSettings.trainer.calib[0] != ui->PPM1->value()) {
generalSettings.trainer.calib[0] = ui->PPM1->value();
emit modified();
}
}
void HardwarePanel::on_PPM2_editingFinished()
{
generalSettings.trainer.calib[1] = ui->PPM2->value();
emit modified();
if (generalSettings.trainer.calib[1] != ui->PPM2->value()) {
generalSettings.trainer.calib[1] = ui->PPM2->value();
emit modified();
}
}
void HardwarePanel::on_PPM3_editingFinished()
{
generalSettings.trainer.calib[2] = ui->PPM3->value();
emit modified();
if (generalSettings.trainer.calib[2] != ui->PPM3->value()) {
generalSettings.trainer.calib[2] = ui->PPM3->value();
emit modified();
}
}
void HardwarePanel::on_PPM4_editingFinished()
{
generalSettings.trainer.calib[3] = ui->PPM4->value();
emit modified();
if (generalSettings.trainer.calib[3] != ui->PPM4->value()) {
generalSettings.trainer.calib[3] = ui->PPM4->value();
emit modified();
}
}
void HardwarePanel::on_txCurrentHardware_editingFinished()
void HardwarePanel::on_txCurrentCalibration_editingFinished()
{
generalSettings.txCurrentCalibration = ui->txCurrentCalibration->value();
emit modified();
if (generalSettings.txCurrentCalibration != ui->txCurrentCalibration->value()) {
generalSettings.txCurrentCalibration = ui->txCurrentCalibration->value();
emit modified();
}
}
void HardwarePanel::on_bluetoothEnable_stateChanged(int)
@@ -241,10 +256,12 @@ void HardwarePanel::setValues()
ui->PPM_MultiplierDSB->setValue((qreal)(generalSettings.PPM_Multiplier+10)/10);
}
void HardwarePanel::on_txVoltageHardware_editingFinished()
void HardwarePanel::on_txVoltageCalibration_editingFinished()
{
generalSettings.txVoltageCalibration = ui->txVoltageCalibration->value()*10;
emit modified();
if (generalSettings.txVoltageCalibration != ui->txVoltageCalibration->value()*10) {
generalSettings.txVoltageCalibration = ui->txVoltageCalibration->value()*10;
emit modified();
}
}
void HardwarePanel::on_serialPortMode_currentIndexChanged(int index)
+2 -2
View File
@@ -40,14 +40,14 @@ class HardwarePanel : public GeneralPanel
virtual ~HardwarePanel();
private slots:
void on_txVoltageHardware_editingFinished();
void on_PPM1_editingFinished();
void on_PPM2_editingFinished();
void on_PPM3_editingFinished();
void on_PPM4_editingFinished();
void on_PPM_MultiplierDSB_editingFinished();
void on_txCurrentHardware_editingFinished();
void on_txCurrentCalibration_editingFinished();
void on_txVoltageCalibration_editingFinished();
void on_bluetoothEnable_stateChanged(int);
void on_filterEnable_stateChanged();
+120 -65
View File
@@ -6,14 +6,23 @@
<rect>
<x>0</x>
<y>0</y>
<width>359</width>
<height>1594</height>
<width>470</width>
<height>1095</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout_2" rowstretch="0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" columnstretch="0,0,0,0,0">
<layout class="QGridLayout" name="gridLayout_2">
<property name="spacing">
<number>6</number>
</property>
<item row="29" column="0">
<widget class="QLabel" name="sqLabel">
<property name="text">
@@ -125,19 +134,6 @@
</property>
</widget>
</item>
<item row="12" column="0" colspan="5">
<widget class="Line" name="potsTypeSeparator_2">
<property name="minimumSize">
<size>
<width>0</width>
<height>10</height>
</size>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="AutoLineEdit" name="pot2Name">
<property name="maxLength">
@@ -730,32 +726,6 @@
</property>
</widget>
</item>
<item row="31" column="0" colspan="4">
<widget class="Line" name="potsTypeSeparator_3">
<property name="minimumSize">
<size>
<width>0</width>
<height>10</height>
</size>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="38" column="0" colspan="4">
<widget class="Line" name="potsTypeSeparator_4">
<property name="minimumSize">
<size>
<width>0</width>
<height>10</height>
</size>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="25" column="0">
<widget class="QLabel" name="smLabel">
<property name="text">
@@ -1075,6 +1045,12 @@
</item>
<item row="32" column="0">
<widget class="QLabel" name="bluetoothLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Bluetooth</string>
</property>
@@ -1090,24 +1066,6 @@
</property>
</widget>
</item>
<item row="32" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QCheckBox" name="bluetoothEnable">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="AutoLineEdit" name="bluetoothName">
<property name="maxLength">
<number>10</number>
</property>
</widget>
</item>
</layout>
</item>
<item row="33" column="1">
<widget class="QCheckBox" name="filterEnable">
<property name="text">
@@ -1122,19 +1080,116 @@
</property>
</widget>
</item>
<item row="32" column="1">
<widget class="QWidget" name="bluetoothWidget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QCheckBox" name="bluetoothEnable">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="btNameLabel">
<property name="text">
<string>Device Name:</string>
</property>
</widget>
</item>
<item>
<widget class="AutoLineEdit" name="bluetoothName">
<property name="maxLength">
<number>10</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="31" column="0" colspan="3">
<widget class="Line" name="potsTypeSeparator_2">
<property name="minimumSize">
<size>
<width>0</width>
<height>10</height>
</size>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="38" column="0" colspan="3">
<widget class="Line" name="ppmSeparator">
<property name="minimumSize">
<size>
<width>0</width>
<height>10</height>
</size>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="12" column="0" colspan="3">
<widget class="Line" name="potsTypeSeparator_1">
<property name="minimumSize">
<size>
<width>0</width>
<height>10</height>
</size>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>AutoLineEdit</class>
<extends>QLineEdit</extends>
<header>autolineedit.h</header>
</customwidget>
<customwidget>
<class>AutoComboBox</class>
<extends>QComboBox</extends>
<header>autocombobox.h</header>
</customwidget>
<customwidget>
<class>AutoLineEdit</class>
<extends>QLineEdit</extends>
<header>autolineedit.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
+313 -52
View File
@@ -30,7 +30,7 @@
#include "downloaddialog.h"
#include "printdialog.h"
#include "version.h"
#include "contributorsdialog.h"
#include "creditsdialog.h"
#include "releasenotesdialog.h"
#include "releasenotesfirmwaredialog.h"
#include "customizesplashdialog.h"
@@ -44,6 +44,7 @@
#include "process_sync.h"
#include "radiointerface.h"
#include "progressdialog.h"
#include "progresswidget.h"
#include "storage.h"
#include "translations.h"
@@ -52,22 +53,28 @@
#include <QFileInfo>
#include <QDesktopServices>
#define OPENTX_DOWNLOADS_PAGE_URL "http://www.open-tx.org/downloads"
#define OPENTX_COMPANION_DOWNLOADS "http://downloads-22.open-tx.org/companion"
#define DONATE_STR "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=QUZ48K4SEXDP2"
#ifdef __APPLE__
#define COMPANION_STAMP "companion-macosx.stamp"
#define COMPANION_INSTALLER "companion-macosx-%1.dmg"
#else
#define COMPANION_INSTALLER "macosx/opentx-companion-%1.dmg"
#define COMPANION_FILEMASK tr("Diskimage (*.dmg)")
#define COMPANION_INSTALL_QUESTION tr("Would you like to open the disk image to install the new version?")
#elif WIN32
#define COMPANION_STAMP "companion-windows.stamp"
#define COMPANION_INSTALLER "companion-windows-%1.exe"
#define COMPANION_INSTALLER "windows/companion-windows-%1.exe"
#define COMPANION_FILEMASK tr("Executable (*.exe)")
#define COMPANION_INSTALL_QUESTION tr("Would you like to launch the installer?")
#else
#define COMPANION_STAMP "companion-linux.stamp"
#define COMPANION_INSTALLER "" // no automatated updates for linux
#define COMPANION_FILEMASK "*.*"
#define COMPANION_INSTALL_QUESTION tr("Would you like to launch the installer?")
#endif
#ifdef WIN32
#define OPENTX_NIGHT_COMPANION_DOWNLOADS "http://downloads-22.open-tx.org/nightly/companion/windows"
#else
#define OPENTX_NIGHT_COMPANION_DOWNLOADS "http://downloads-22.open-tx.org/nightly/companion/linux"
#endif
#define OPENTX_NIGHT_COMPANION_DOWNLOADS "http://downloads-22.open-tx.org/nightlies/companion"
MainWindow::MainWindow():
downloadDialog_forWait(NULL),
@@ -108,7 +115,16 @@ MainWindow::MainWindow():
if (showSplash) {
updateDelay += (SPLASH_TIME*1000);
}
QTimer::singleShot(updateDelay, this, SLOT(doAutoUpdates()));
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
}
else {
if (!g.previousVersion().isEmpty())
g.warningId(g.warningId() | AppMessages::MSG_UPGRADED);
QTimer::singleShot(updateDelay, this, SLOT(doAutoUpdates()));
}
QTimer::singleShot(updateDelay, this, SLOT(displayWarnings()));
QStringList strl = QApplication::arguments();
@@ -161,21 +177,39 @@ MainWindow::~MainWindow()
void MainWindow::displayWarnings()
{
int warnId = g.warningId();
if (warnId<WARNING_ID && warnId!=0) {
int res=0;
if (WARNING_LEVEL>0)
QMessageBox::warning(this, "Companion", WARNING);
else
QMessageBox::about(this, "Companion", WARNING);
res = QMessageBox::question(this, "Companion", tr("Display previous warning again at startup ?"), QMessageBox::Yes | QMessageBox::No);
if (res == QMessageBox::No) {
g.warningId(WARNING_ID);
}
using namespace AppMessages;
static uint shownMsgs = 0;
int showMsgs = g.warningId();
int msgId;
QString infoTxt;
if ((showMsgs & MSG_WELCOME) && !(shownMsgs & MSG_WELCOME)) {
infoTxt = CPN_STR_MSG_WELCOME.arg(VERSION);
msgId = MSG_WELCOME;
}
else if (warnId==0) {
g.warningId(WARNING_ID);
else if ((showMsgs & MSG_UPGRADED) && !(shownMsgs & MSG_UPGRADED)) {
infoTxt = CPN_STR_MSG_UPGRADED.arg(VERSION);
msgId = MSG_UPGRADED;
}
else {
return;
}
QMessageBox msgBox(this);
msgBox.setWindowTitle(tr("Companion"));
msgBox.setIcon(QMessageBox::Information);
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setInformativeText(infoTxt);
QCheckBox * cb = new QCheckBox(tr("Show this message again at next startup?"), &msgBox);
msgBox.setCheckBox(cb);
msgBox.exec();
shownMsgs |= msgId;
if (!cb->isChecked())
g.warningId(showMsgs & ~msgId);
displayWarnings(); // in case more warnings need showing
}
void MainWindow::doAutoUpdates()
@@ -288,20 +322,20 @@ void MainWindow::checkForCompanionUpdateFinished(QNetworkReply * reply)
if (version.isNull())
return onUpdatesError();
int vnum = version2index(version);
int webVersion = version2index(version);
QString c9xversion = QString(VERSION);
int c9xver = version2index(c9xversion);
int ownVersion = version2index(VERSION);
if (c9xver < vnum) {
#if defined WIN32 || !defined __GNUC__ // || defined __APPLE__ // OSX should only notify of updates since no update packages are available.
if (ownVersion < webVersion) {
#if defined WIN32 || defined __APPLE__
int ret = QMessageBox::question(this, "Companion", tr("A new version of Companion is available (version %1)<br>"
"Would you like to download it?").arg(version) ,
QMessageBox::Yes | QMessageBox::No);
if (ret == QMessageBox::Yes) {
QDir dir(g.updatesDir());
QString fileName = QFileDialog::getSaveFileName(this, tr("Save As"), dir.absoluteFilePath(QString(COMPANION_INSTALLER).arg(version)), tr("Executable (*.exe)"));
QString fileName = QFileDialog::getSaveFileName(this, tr("Save As"), dir.absoluteFilePath(QString(COMPANION_INSTALLER).arg(version)), COMPANION_FILEMASK);
if (!fileName.isEmpty()) {
g.updatesDir(QFileInfo(fileName).dir().absolutePath());
downloadDialog * dd = new downloadDialog(this, QString("%1/%2").arg(getCompanionUpdateBaseUrl()).arg(QString(COMPANION_INSTALLER).arg(version)), fileName);
@@ -311,7 +345,7 @@ void MainWindow::checkForCompanionUpdateFinished(QNetworkReply * reply)
}
}
#else
QMessageBox::warning(this, tr("New release available"), tr("A new release of Companion is available, please check the OpenTX website!"));
QMessageBox::warning(this, tr("New release available"), tr("A new release of Companion is available, please check the <a href='%1'>OpenTX website!</a>").arg(OPENTX_DOWNLOADS_PAGE_URL));
#endif
}
else {
@@ -325,8 +359,7 @@ void MainWindow::checkForCompanionUpdateFinished(QNetworkReply * reply)
void MainWindow::updateDownloaded()
{
int ret = QMessageBox::question(this, "Companion", tr("Would you like to launch the installer?") ,
QMessageBox::Yes | QMessageBox::No);
int ret = QMessageBox::question(this, "Companion", COMPANION_INSTALL_QUESTION, QMessageBox::Yes | QMessageBox::No);
if (ret == QMessageBox::Yes) {
if (QDesktopServices::openUrl(QUrl::fromLocalFile(installer_fileName)))
QApplication::exit();
@@ -657,9 +690,7 @@ void MainWindow::openFile(const QString & fileName, bool updateLastUsedDir)
void MainWindow::openFile()
{
QString fileFilter;
fileFilter = tr(EEPROM_FILES_FILTER);
QString fileName = QFileDialog::getOpenFileName(this, tr("Open Models and Settings file"), g.eepromDir(), fileFilter);
QString fileName = QFileDialog::getOpenFileName(this, tr("Open Models and Settings file"), g.eepromDir(), EEPROM_FILES_FILTER);
openFile(fileName);
}
@@ -732,29 +763,259 @@ void MainWindow::fwPrefs()
void MainWindow::contributors()
{
ContributorsDialog * dialog = new ContributorsDialog(this);
CreditsDialog * dialog = new CreditsDialog(this);
dialog->exec();
dialog->deleteLater();
}
// Create a widget with a line edit and folder select button and handles all interactions. Features autosuggest
// path hints while typing, invalid paths shown in red. The label string is only for dialog title, not a QLabel.
// This should probably be moved some place more reusable, esp. the QFileSystemModel.
QWidget * folderSelectorWidget(QString * path, const QString & label, QWidget * parent)
{
static QFileSystemModel fileModel;
static bool init = false;
if (!init) {
init = true;
fileModel.setFilter(QDir::Dirs);
fileModel.setRootPath("/");
}
QWidget * fsw = new QWidget(parent);
QLineEdit * le = new QLineEdit(parent);
QCompleter * fsc = new QCompleter(fsw);
fsc->setModel(&fileModel);
//fsc->setCompletionMode(QCompleter::InlineCompletion);
le->setCompleter(fsc);
QToolButton * btn = new QToolButton(fsw);
btn->setIcon(CompanionIcon("open.png"));
QHBoxLayout * l = new QHBoxLayout(fsw);
l->setContentsMargins(0,0,0,0);
l->setSpacing(3);
l->addWidget(le);
l->addWidget(btn);
QObject::connect(btn, &QToolButton::clicked, [=]() {
QString dir = QFileDialog::getExistingDirectory(parent, label, le->text(), 0);
if (!dir.isEmpty()) {
le->setText(QDir::toNativeSeparators(dir));
le->setFocus();
}
});
QObject::connect(le, &QLineEdit::textChanged, [=](const QString & text) {
*path = text;
if (QFile::exists(text))
le->setStyleSheet("");
else
le->setStyleSheet("QLineEdit {color: red;}");
});
le->setText(QDir::toNativeSeparators(*path));
return fsw;
}
void MainWindow::sdsync()
{
QString sdPath = g.profile[g.id()].sdPath();
if (sdPath.isEmpty()) {
QMessageBox::warning(this, QObject::tr("Synchronization error"), QObject::tr("No SD directory configured!"));
const QString dlgTtl = tr("Synchronize SD");
const QIcon dlgIcn = CompanionIcon("sdsync.png");
const QString srcArw = CPN_STR_SW_INDICATOR_UP % " ";
const QString dstArw = CPN_STR_SW_INDICATOR_DN % " ";
QStringList errorMsgs;
// remember user-selectable options for duration of session
static QString sourcePath;
static QString destPath;
static int syncDirection = SyncProcess::SYNC_A2B_B2A;
static int compareType = SyncProcess::OVERWR_NEWER_IF_DIFF;
static int maxFileSize = 2 * 1024 * 1024; // Bytes
static bool dryRun = false;
if (sourcePath.isEmpty())
sourcePath = g.profile[g.id()].sdPath();
if (destPath.isEmpty())
destPath = findMassstoragePath("SOUNDS").replace(QRegExp("[/\\\\]?SOUNDS"), "");
if (sourcePath.isEmpty())
errorMsgs << tr("No local SD structure path configured!");
if (destPath.isEmpty())
errorMsgs << tr("No Radio or SD card detected!");
QDialog dlg(this);
dlg.setWindowTitle(dlgTtl % tr(" :: Options"));
dlg.setWindowIcon(dlgIcn);
dlg.setSizeGripEnabled(true);
dlg.setWindowFlags(dlg.windowFlags() & ~Qt::WindowContextHelpButtonHint);
QLabel * lblSrc = new QLabel(tr("Local Folder:"), &dlg);
QWidget * wdgSrc = folderSelectorWidget(&sourcePath, lblSrc->text(), &dlg);
QLabel * lblDst = new QLabel(tr("Radio Folder:"), &dlg);
QWidget * wdgDst = folderSelectorWidget(&destPath, lblDst->text(), &dlg);
QLabel * lbDir = new QLabel(tr("Sync. Direction:"), &dlg);
QComboBox * syncDir = new QComboBox(&dlg);
syncDir->addItem(tr("%1%2 Both directions, to radio folder first").arg(dstArw, srcArw), SyncProcess::SYNC_A2B_B2A);
syncDir->addItem(tr("%1%2 Both directions, to local folder first").arg(srcArw, dstArw), SyncProcess::SYNC_B2A_A2B);
syncDir->addItem(tr(" %1 Only from local folder to radio folder").arg(dstArw), SyncProcess::SYNC_A2B);
syncDir->addItem(tr(" %1 Only from radio folder to local folder").arg(srcArw), SyncProcess::SYNC_B2A);
syncDir->setCurrentIndex(-1); // we set the default option later
QLabel * lbMode = new QLabel(tr("Existing Files:"), &dlg);
QComboBox * copyMode = new QComboBox(&dlg);
copyMode->setToolTip(tr("How to handle overwriting files which already exist in the destination folder."));
copyMode->addItem(tr("Copy only if newer and different (compare contents)"), SyncProcess::OVERWR_NEWER_IF_DIFF);
copyMode->addItem(tr("Copy only if newer (do not compare contents)"), SyncProcess::OVERWR_NEWER_ALWAYS);
copyMode->addItem(tr("Copy only if different (ignore file time stamps)"), SyncProcess::OVERWR_IF_DIFF);
copyMode->addItem(tr("Always copy (force overwite existing files)"), SyncProcess::OVERWR_ALWAYS);
QLabel * lbSize = new QLabel(tr("Max. File Size:"), &dlg);
QSpinBox * maxSize = new QSpinBox(&dlg);
maxSize->setRange(0, 100 * 1024);
maxSize->setAccelerated(true);
maxSize->setSpecialValueText(tr("Any size"));
maxSize->setToolTip(tr("Skip files larger than this size. Enter zero for unlimited."));
#if (QT_VERSION >= QT_VERSION_CHECK(5, 3, 0))
maxSize->setGroupSeparatorShown(true);
#endif
QCheckBox * testRun = new QCheckBox(tr("Test-run only"), &dlg);
testRun->setToolTip(tr("Run as normal but do not actually copy anything. Useful for verifying results before real sync."));
connect(testRun, &QCheckBox::toggled, [=](bool on) { dryRun = on; });
// layout to hold size spinbox and checkbox option(s)
QHBoxLayout * hlay1 = new QHBoxLayout();
hlay1->addWidget(maxSize, 1);
hlay1->addWidget(testRun);
// dialog OK/Cancel buttons
QDialogButtonBox * bb = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, &dlg);
// Create main layout and add everything
QGridLayout * dlgL = new QGridLayout(&dlg);
dlgL->setSizeConstraint(QLayout::SetFixedSize);
int row = 0;
if (errorMsgs.size()) {
QLabel * lblWarn = new QLabel(QString(errorMsgs.join('\n')), &dlg);
lblWarn->setStyleSheet("QLabel { color: red; }");
dlgL->addWidget(lblWarn, row++, 0, 1, 2);
}
dlgL->addWidget(lblSrc, row, 0);
dlgL->addWidget(wdgSrc, row++, 1);
dlgL->addWidget(lblDst, row, 0);
dlgL->addWidget(wdgDst, row++, 1);
dlgL->addWidget(lbDir, row, 0);
dlgL->addWidget(syncDir, row++, 1);
dlgL->addWidget(lbMode, row, 0);
dlgL->addWidget(copyMode, row++, 1);
dlgL->addWidget(lbSize, row, 0);
dlgL->addLayout(hlay1, row++, 1);
dlgL->addWidget(bb, row++, 0, 1, 2);
dlgL->setRowStretch(row, 1);
connect(copyMode, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), [=](int) {
compareType = copyMode->currentData().toInt();
});
// function to dis/enable the OVERWR_ALWAYS option depending on sync direction
connect(syncDir, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), [=](int) {
int dir = syncDir->currentData().toInt();
int idx = copyMode->findData(SyncProcess::OVERWR_ALWAYS);
int flg = (dir == SyncProcess::SYNC_A2B || dir == SyncProcess::SYNC_B2A) ? 33 : 0;
if (!flg && idx == copyMode->currentIndex())
copyMode->setCurrentIndex(copyMode->findData(SyncProcess::OVERWR_NEWER_IF_DIFF));
copyMode->setItemData(idx, flg, Qt::UserRole - 1);
syncDirection = dir;
});
// function to set magnitude of file size spinbox, KB or MB
connect(maxSize, static_cast<void(QSpinBox::*)(int)>(&QSpinBox::valueChanged), [=](int value) {
int multi = maxSize->property("multi").isValid() ? maxSize->property("multi").toInt() : 0;
maxSize->blockSignals(true);
if (value >= 10 * 1024 && multi != 1024 * 1024) {
// KB -> MB
multi = 1024 * 1024;
maxSize->setValue(value / 1024);
maxSize->setMaximum(100);
maxSize->setSingleStep(1);
maxSize->setSuffix(tr(" MB"));
}
else if ((value < 10 && multi != 1024) || !multi) {
// MB -> KB
if (multi)
value *= 1024;
multi = 1024;
if (value == 9 * 1024)
value += 1024 - 32; // avoid large jump when stepping from 10MB to 10,208KB
maxSize->setMaximum(100 * 1024);
maxSize->setValue(value);
maxSize->setSingleStep(32);
maxSize->setSuffix(tr(" KB"));
}
maxSize->setProperty("multi", multi);
maxSize->blockSignals(false);
maxFileSize = value * multi;
});
copyMode->setCurrentIndex(copyMode->findData(compareType));
syncDir->setCurrentIndex(syncDir->findData(syncDirection));
maxSize->setValue(maxFileSize / 1024);
testRun->setChecked(dryRun);
connect(bb, &QDialogButtonBox::accepted, &dlg, &QDialog::accept);
connect(bb, &QDialogButtonBox::rejected, &dlg, &QDialog::reject);
// to restart dialog on error/etc
openDialog:
// show the modal options dialog
if (dlg.exec() == QDialog::Rejected)
return;
// validate
errorMsgs.clear();
if (sourcePath == destPath)
errorMsgs << tr("Source and destination folders are the same!");
if (sourcePath.isEmpty() || !QFile::exists(sourcePath))
errorMsgs << tr("Source folder not found: %1").arg(sourcePath);
if (destPath.isEmpty() || !QFile::exists(destPath))
errorMsgs << tr("Destination folder not found: %1").arg(destPath);
if (!errorMsgs.isEmpty()) {
QMessageBox::warning(this, dlgTtl % tr(" :: Error"), errorMsgs.join('\n'));
goto openDialog;
}
QString massstoragePath = findMassstoragePath("SOUNDS");
if (massstoragePath.isEmpty()) {
QMessageBox::warning(this, QObject::tr("Synchronization error"), QObject::tr("No Radio connected!"));
return;
}
massstoragePath = massstoragePath.left(massstoragePath.length() - 7);
ProgressDialog progressDialog(this, tr("Synchronize SD"), CompanionIcon("sdsync.png"));
SyncProcess syncProcess(massstoragePath, g.profile[g.id()].sdPath(), progressDialog.progress());
if (!syncProcess.run()) {
progressDialog.exec();
}
// set up the progress dialog and the sync process worker
ProgressDialog * progressDlg = new ProgressDialog(this, dlgTtl % tr(" :: Progress"), dlgIcn);
progressDlg->setAttribute(Qt::WA_DeleteOnClose, true);
ProgressWidget * progWidget = progressDlg->progress();
SyncProcess * syncProcess = new SyncProcess(sourcePath, destPath, syncDirection, compareType, maxFileSize, dryRun);
// move sync process to separate thread, we only use signals/slots from here on...
QThread * syncThread = new QThread(this);
syncProcess->moveToThread(syncThread);
// ...and quite a few of them!
connect(this, &MainWindow::startSync, syncProcess, &SyncProcess::run);
connect(syncThread, &QThread::finished, syncProcess, &SyncProcess::deleteLater);
connect(syncProcess, &SyncProcess::finished, syncThread, &QThread::quit);
connect(syncProcess, &SyncProcess::destroyed, syncThread, &QThread::quit);
connect(syncProcess, &SyncProcess::destroyed, syncThread, &QThread::deleteLater);
connect(syncProcess, &SyncProcess::fileCountChanged, progWidget, &ProgressWidget::setMaximum);
connect(syncProcess, &SyncProcess::progressStep, progWidget, &ProgressWidget::setValue);
connect(syncProcess, &SyncProcess::progressMessage, progWidget, &ProgressWidget::addMessage);
connect(syncProcess, &SyncProcess::statusMessage, progWidget, &ProgressWidget::setInfo);
connect(syncProcess, &SyncProcess::started, progressDlg, &ProgressDialog::setProcessStarted);
connect(syncProcess, &SyncProcess::finished, progressDlg, &ProgressDialog::setProcessStopped);
connect(syncProcess, &SyncProcess::finished, [=]() { QApplication::alert(this); });
connect(progressDlg, &ProgressDialog::rejected, syncProcess, &SyncProcess::stop);
connect(progressDlg, &ProgressDialog::rejected, syncProcess, &SyncProcess::deleteLater);
// go (finally)
syncThread->start();
emit startSync();
}
void MainWindow::changelog()
@@ -861,7 +1122,7 @@ void MainWindow::readBackup()
return;
// TODO implementation
}
QString fileName = QFileDialog::getSaveFileName(this, tr("Save Radio Backup to File"), g.eepromDir(), tr(EXTERNAL_EEPROM_FILES_FILTER));
QString fileName = QFileDialog::getSaveFileName(this, tr("Save Radio Backup to File"), g.eepromDir(), EXTERNAL_EEPROM_FILES_FILTER);
if (!fileName.isEmpty()) {
if (!readEepromFromRadio(fileName))
return;
@@ -870,7 +1131,7 @@ void MainWindow::readBackup()
void MainWindow::readFlash()
{
QString fileName = QFileDialog::getSaveFileName(this,tr("Read Radio Firmware to File"), g.flashDir(),tr(FLASH_FILES_FILTER));
QString fileName = QFileDialog::getSaveFileName(this,tr("Read Radio Firmware to File"), g.flashDir(), FLASH_FILES_FILTER);
if (!fileName.isEmpty()) {
readFirmwareFromRadio(fileName);
}
+1
View File
@@ -54,6 +54,7 @@ class MainWindow : public QMainWindow
signals:
void firmwareChanged();
void startSync();
protected:
QString getCompanionUpdateBaseUrl();
+1 -1
View File
@@ -1480,7 +1480,7 @@ void MdiChild::writeEeprom() // write to Tx
bool MdiChild::loadBackup()
{
QString fileName = QFileDialog::getOpenFileName(this, tr("Open backup Models and Settings file"), g.eepromDir(), tr(EEPROM_FILES_FILTER));
QString fileName = QFileDialog::getOpenFileName(this, tr("Open backup Models and Settings file"), g.eepromDir(), EEPROM_FILES_FILTER);
if (fileName.isEmpty())
return false;
QFile file(fileName);
+2 -1
View File
@@ -41,7 +41,8 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G
cb_fp[i] = tmp[i];
}
setWindowTitle(tr("Edit %1").arg(modelPrinter.printInputName(ed->chn)));
RawSourceType srcType = (firmware->getCapability(VirtualInputs) ? SOURCE_TYPE_VIRTUAL_INPUT : SOURCE_TYPE_STICK);
setWindowTitle(tr("Edit %1").arg(RawSource(srcType, ed->chn).toString(&model, &generalSettings)));
QRegExp rx(CHAR_FOR_NAMES_REGEX);
if (IS_HORUS_OR_TARANIS(getCurrentBoard())) {
+11 -11
View File
@@ -153,26 +153,26 @@ bool InputsPanel::AddInputLine(int dest)
QString InputsPanel::getInputText(int dest, bool * new_ch)
{
QString str;
if (new_ch) *new_ch = 0;
if (new_ch)
*new_ch = false;
if (dest < 0) {
str = modelPrinter.printInputName(-dest-1);
if (new_ch) *new_ch = 1;
if (new_ch)
*new_ch = true;
}
else {
ExpoData & input = model->expoData[dest];
int nameChars = (firmware->getCapability(VirtualInputs) ? 10 : 4);
if ((dest == 0) || (model->expoData[dest-1].chn != input.chn)) {
if (new_ch) *new_ch = 1;
if (firmware->getCapability(VirtualInputs))
str += QString("%1").arg(modelPrinter.printInputName(input.chn), -10, ' ');
else
str = modelPrinter.printInputName(input.chn);
if (new_ch)
*new_ch = true;
str = QString("%1").arg(modelPrinter.printInputName(input.chn), -nameChars, QChar(' '));
}
else {
if (firmware->getCapability(VirtualInputs))
str = " ";
else
str = " ";
str = QString(nameChars, QChar(' '));
}
str.replace(" ", "&nbsp;");
str += modelPrinter.printInputLine(input);
+1 -1
View File
@@ -48,7 +48,7 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model,
// The label
QLabel * label = new QLabel(this);
label->setProperty("index", i);
label->setText(tr("L%1").arg(i+1));
label->setText(RawSwitch(SWITCH_TYPE_VIRTUAL, i+1).toString());
label->setContextMenuPolicy(Qt::CustomContextMenu);
label->setMouseTracking(true);
label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
+1 -1
View File
@@ -40,7 +40,7 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData *mixdata, G
cb_fp[i] = tmp[i];
}
this->setWindowTitle(tr("DEST -> CH%1").arg(md->destCh));
this->setWindowTitle(tr("DEST -> %1").arg(RawSource(SOURCE_TYPE_CH, md->destCh-1).toString(&model, &generalSettings)));
ui->sourceCB->setModel(Helpers::getRawSourceItemModel(&generalSettings, &model, POPULATE_NONE | POPULATE_SOURCES | POPULATE_SCRIPT_OUTPUTS | POPULATE_VIRTUAL_INPUTS | POPULATE_SWITCHES | POPULATE_TRIMS));
ui->sourceCB->setCurrentIndex(ui->sourceCB->findData(md->srcRaw.toValue()));
+45 -37
View File
@@ -51,7 +51,6 @@ TimerPanel::TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, Ge
// Mode
ui->mode->setModel(Helpers::getRawSwitchItemModel(&generalSettings, Helpers::TimersContext));
ui->mode->setCurrentIndex(ui->mode->findData(timer.mode.toValue()));
//Helpers::populateSwitchCB(ui->mode, timer.mode, generalSettings, Helpers::TimersContext);
if (!firmware->getCapability(PermTimers)) {
ui->persistent->hide();
@@ -121,8 +120,11 @@ QWidget * TimerPanel::getLastFocus()
void TimerPanel::on_value_editingFinished()
{
timer.val = ui->value->time().hour()*3600 + ui->value->time().minute()*60 + ui->value->time().second();
emit modified();
unsigned val = ui->value->time().hour()*3600 + ui->value->time().minute()*60 + ui->value->time().second();
if (timer.val != val) {
timer.val = val;
emit modified();
}
}
void TimerPanel::on_mode_currentIndexChanged(int index)
@@ -141,9 +143,11 @@ void TimerPanel::on_minuteBeep_toggled(bool checked)
void TimerPanel::on_name_editingFinished()
{
int length = ui->name->maxLength();
strncpy(timer.name, ui->name->text().toLatin1(), length);
emit modified();
if (QString(timer.name) != ui->name->text()) {
int length = ui->name->maxLength();
strncpy(timer.name, ui->name->text().toLatin1(), length);
emit modified();
}
}
/******************************************************************************/
@@ -234,15 +238,15 @@ ModulePanel::ModulePanel(QWidget * parent, ModelData & model, ModuleData & modul
disableMouseScrolling();
update();
connect(ui->protocol, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &ModulePanel::onProtocolChanged);
connect(ui->multiProtocol, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &ModulePanel::onMultiProtocolChanged);
connect(this, &ModulePanel::channelsRangeChanged, this, &ModulePanel::setupFailsafes);
connect(ui->btnGrpValueType, static_cast<void(QButtonGroup::*)(int)>(&QButtonGroup::buttonClicked), this, &ModulePanel::onFailsafesDisplayValueTypeChanged);
lock = false;
// a change will not register if only one item was added
if (ui->protocol->count() == 1) {
on_protocol_currentIndexChanged(ui->protocol->currentIndex());
}
}
ModulePanel::~ModulePanel()
@@ -476,7 +480,7 @@ void ModulePanel::update()
ui->optionValue->setMinimum(pdef.getOptionMin());
ui->optionValue->setMaximum(pdef.getOptionMax());
ui->optionValue->setValue(module.multi.optionValue);
ui->label_option->setText(pdef.optionsstr);
ui->label_option->setText(qApp->translate("Multiprotocols", qPrintable(pdef.optionsstr)));
}
ui->multiSubType->setCurrentIndex(module.subType);
@@ -533,7 +537,7 @@ void ModulePanel::on_trainerMode_currentIndexChanged(int index)
}
}
void ModulePanel::on_protocol_currentIndexChanged(int index)
void ModulePanel::onProtocolChanged(int index)
{
if (!lock) {
module.protocol = ui->protocol->itemData(index).toInt();
@@ -562,7 +566,7 @@ void ModulePanel::on_ppmOutputType_currentIndexChanged(int index)
void ModulePanel::on_channelsCount_editingFinished()
{
if (!lock) {
if (!lock && module.channelsCount != ui->channelsCount->value()) {
module.channelsCount = ui->channelsCount->value();
update();
emit channelsRangeChanged();
@@ -572,8 +576,8 @@ void ModulePanel::on_channelsCount_editingFinished()
void ModulePanel::on_channelsStart_editingFinished()
{
if (!lock) {
module.channelsStart = ui->channelsStart->value() - 1;
if (!lock && module.channelsStart != (unsigned)ui->channelsStart->value() - 1) {
module.channelsStart = (unsigned)ui->channelsStart->value() - 1;
update();
emit channelsRangeChanged();
emit modified();
@@ -582,7 +586,7 @@ void ModulePanel::on_channelsStart_editingFinished()
void ModulePanel::on_ppmDelay_editingFinished()
{
if (!lock) {
if (!lock && module.ppm.delay != ui->ppmDelay->value()) {
// TODO only accept valid values
module.ppm.delay = ui->ppmDelay->value();
emit modified();
@@ -591,14 +595,19 @@ void ModulePanel::on_ppmDelay_editingFinished()
void ModulePanel::on_rxNumber_editingFinished()
{
module.modelId = ui->rxNumber->value();
emit modified();
if (module.modelId != (unsigned)ui->rxNumber->value()) {
module.modelId = (unsigned)ui->rxNumber->value();
emit modified();
}
}
void ModulePanel::on_ppmFrameLength_editingFinished()
{
module.ppm.frameLength = (ui->ppmFrameLength->value()-22.5) / 0.5;
emit modified();
int val = (ui->ppmFrameLength->value()-22.5) / 0.5;
if (module.ppm.frameLength != val) {
module.ppm.frameLength = val;
emit modified();
}
}
void ModulePanel::on_failsafeMode_currentIndexChanged(int value)
@@ -610,7 +619,7 @@ void ModulePanel::on_failsafeMode_currentIndexChanged(int value)
}
}
void ModulePanel::on_multiProtocol_currentIndexChanged(int index)
void ModulePanel::onMultiProtocolChanged(int index)
{
if (!lock) {
lock=true;
@@ -627,8 +636,10 @@ void ModulePanel::on_multiProtocol_currentIndexChanged(int index)
void ModulePanel::on_optionValue_editingFinished()
{
module.multi.optionValue = ui->optionValue->value();
emit modified();
if (module.multi.optionValue != ui->optionValue->value()) {
module.multi.optionValue = ui->optionValue->value();
emit modified();
}
}
void ModulePanel::on_multiSubType_currentIndexChanged(int index)
@@ -753,16 +764,16 @@ void ModulePanel::updateFailsafe(int channel)
const int failsafeValue = module.failsafeChannels[channel];
const ChannelFailsafeWidgetsGroup & grp = failsafeGroupsMap.value(channel);
const bool valDisable = (failsafeValue == FAILSAFE_CHANNEL_HOLD || failsafeValue == FAILSAFE_CHANNEL_NOPULSE);
const int cbIdx = (failsafeValue == FAILSAFE_CHANNEL_HOLD ? 1 : failsafeValue == FAILSAFE_CHANNEL_NOPULSE ? 2 : 0);
if (grp.combo)
grp.combo->setCurrentIndex(cbIdx);
grp.combo->setCurrentIndex(grp.combo->findData(valDisable ? failsafeValue : 0));
if (grp.sbPercent)
grp.sbPercent->setDisabled(valDisable);
if (grp.sbUsec)
grp.sbUsec->setDisabled(valDisable);
setChannelFailsafeValue(channel, (valDisable ? 0 : failsafeValue), (FAILSAFE_DISPLAY_PERCENT | FAILSAFE_DISPLAY_USEC));
if (!valDisable)
setChannelFailsafeValue(channel, failsafeValue, (FAILSAFE_DISPLAY_PERCENT | FAILSAFE_DISPLAY_USEC));
}
/******************************************************************************/
@@ -855,7 +866,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
if (i<firmware->getCapability(Timers)) {
timers[i] = new TimerPanel(this, model, model.timers[i], generalSettings, firmware, prevFocus);
ui->gridLayout->addWidget(timers[i], 1+i, 1);
connect(timers[i], SIGNAL(modified()), this, SLOT(onChildModified()));
connect(timers[i], &TimerPanel::modified, this, &SetupPanel::modified);
prevFocus = timers[i]->getLastFocus();
}
else {
@@ -987,14 +998,14 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
for (int i=0; i<firmware->getCapability(NumModules); i++) {
modules[i] = new ModulePanel(this, model, model.moduleData[i], generalSettings, firmware, i);
ui->modulesLayout->addWidget(modules[i]);
connect(modules[i], SIGNAL(modified()), this, SLOT(onChildModified()));
connect(modules[i], &ModulePanel::modified, this, &SetupPanel::modified);
connect(this, &SetupPanel::extendedLimitsToggled, modules[i], &ModulePanel::onExtendedLimitsToggled);
}
if (firmware->getCapability(ModelTrainerEnable)) {
modules[CPN_MAX_MODULES] = new ModulePanel(this, model, model.moduleData[CPN_MAX_MODULES], generalSettings, firmware, -1);
ui->modulesLayout->addWidget(modules[CPN_MAX_MODULES]);
connect(modules[CPN_MAX_MODULES], SIGNAL(modified()), this, SLOT(onChildModified()));
connect(modules[CPN_MAX_MODULES], &ModulePanel::modified, this, &SetupPanel::modified);
}
disableMouseScrolling();
@@ -1048,9 +1059,11 @@ void SetupPanel::on_throttleSource_currentIndexChanged(int index)
void SetupPanel::on_name_editingFinished()
{
int length = ui->name->maxLength();
strncpy(model->name, ui->name->text().toLatin1(), length);
emit modified();
if (QString(model->name) != ui->name->text()) {
int length = ui->name->maxLength();
strncpy(model->name, ui->name->text().toLatin1(), length);
emit modified();
}
}
void SetupPanel::on_image_currentIndexChanged(int index)
@@ -1293,8 +1306,3 @@ void SetupPanel::onBeepCenterToggled(bool checked)
emit modified();
}
}
void SetupPanel::onChildModified()
{
emit modified();
}
+2 -3
View File
@@ -71,7 +71,7 @@ class ModulePanel : public ModelPanel
private slots:
void setupFailsafes();
void on_trainerMode_currentIndexChanged(int index);
void on_protocol_currentIndexChanged(int index);
void onProtocolChanged(int index);
void on_ppmDelay_editingFinished();
void on_channelsCount_editingFinished();
void on_channelsStart_editingFinished();
@@ -81,7 +81,7 @@ class ModulePanel : public ModelPanel
void on_antennaMode_currentIndexChanged(int index);
void on_rxNumber_editingFinished();
void on_failsafeMode_currentIndexChanged(int value);
void on_multiProtocol_currentIndexChanged(int index);
void onMultiProtocolChanged(int index);
void on_multiSubType_currentIndexChanged(int index);
void on_autoBind_stateChanged(int state);
void on_lowPower_stateChanged(int state);
@@ -140,7 +140,6 @@ class SetupPanel : public ModelPanel
void startupSwitchToggled(bool checked);
void potWarningToggled(bool checked);
void on_potWarningMode_currentIndexChanged(int index);
void onChildModified();
private:
Ui::Setup *ui;
+4 -15
View File
@@ -22,6 +22,7 @@
#include "modelprinter.h"
#include "multiprotocols.h"
#include <QApplication>
#include <QPainter>
#include <QFile>
#include <QUrl>
@@ -146,7 +147,7 @@ QString ModelPrinter::printMultiSubType(int rfProtocol, bool custom, unsigned in
Multiprotocols::MultiProtocolDefinition pdef = multiProtocols.getProtocol(rfProtocol);
if (subType < (unsigned int) pdef.subTypeStrings.size())
return pdef.subTypeStrings[subType];
return qApp->translate("Multiprotocols", qPrintable(pdef.subTypeStrings[subType]));
else
return "???";
}
@@ -327,20 +328,8 @@ QString ModelPrinter::printRotaryEncoder(int flightModeIndex, int reIndex)
QString ModelPrinter::printInputName(int idx)
{
QString result;
if (firmware->getCapability(VirtualInputs)) {
if (strlen(model.inputNames[idx]) > 0) {
result = tr("[I%1]").arg(idx+1);
result += QString(model.inputNames[idx]);
}
else {
result = tr("Input%1").arg(idx+1, 2, 10, QChar('0'));
}
}
else {
result = RawSource(SOURCE_TYPE_STICK, idx).toString(&model, &generalSettings);
}
return result.toHtmlEscaped();
RawSourceType srcType = (firmware->getCapability(VirtualInputs) ? SOURCE_TYPE_VIRTUAL_INPUT : SOURCE_TYPE_STICK);
return RawSource(srcType, idx).toString(&model, &generalSettings).toHtmlEscaped();
}
QString ModelPrinter::printInputLine(int idx)
+1 -2
View File
@@ -34,7 +34,6 @@
#define sleep(x) Sleep(x*1000)
#else
#include <unistd.h>
#include "mountlist.h"
#endif
FlashProcess::FlashProcess(const QString &cmd, const QStringList &args, ProgressWidget *progress):
@@ -240,7 +239,7 @@ void FlashProcess::onReadyReadStandardError()
void FlashProcess::errorWizard()
{
QString output = progress->getText();
if (output.contains("avrdude: Expected signature for")) { // wrong signature
int pos = output.indexOf("avrdude: Device signature = ");
bool fwexist = false;
+212 -89
View File
@@ -19,133 +19,256 @@
*/
#include "process_sync.h"
#include "progresswidget.h"
#include <QDirIterator>
#include <QApplication>
#include <QCryptographicHash>
#include <QDateTime>
#include <QMessageBox>
#include <QTextStream>
#include <QMutexLocker>
#include <QDirIterator>
#include <QDebug>
#include <QEventLoop>
#include <QTimer>
SyncProcess::SyncProcess(const QString & folder1, const QString & folder2, ProgressWidget * progress):
folder1(folder1),
folder2(folder2),
progress(progress),
index(0),
count(0),
closed(false)
#if (QT_VERSION < QT_VERSION_CHECK(5, 5, 0))
#define QtInfoMsg QtMsgType(4)
#endif
#define PRINT_INFO(str) emit progressMessage((str), QtInfoMsg)
#define PRINT_CREATE(str) emit progressMessage((str), QtInfoMsg)
#define PRINT_REPLACE(str) emit progressMessage((str), QtWarningMsg)
#define PRINT_DELETE(str) emit progressMessage((str), QtCriticalMsg)
#define PRINT_ERROR(str) emit progressMessage((str), QtFatalMsg)
//#define PRINT_SKIP(str) emit progressMessage((str), QtDebugMsg) // mostly useless noise (maybe make an option later)
#define PRINT_SKIP(str)
#define PRINT_SEP() PRINT_INFO(QString(80, '='))
#define SYNC_MAX_ERRORS 50 // give up after this many errors per destination
SyncProcess::SyncProcess(const QString & folderA, const QString & folderB, const int & syncDirection, const int & compareType, const qint64 & maxFileSize, const bool dryRun):
folder1(folderA),
folder2(folderB),
direction((SyncDirection)syncDirection),
ctype((SyncCompareType)compareType),
maxFileSize(qMax<qint64>(0, maxFileSize)),
dryRun(dryRun),
stopping(false)
{
connect(progress, SIGNAL(stopped()),this, SLOT(onClosed()));
if (direction == SYNC_B2A_A2B) {
folder1 = folderB;
folder2 = folderA;
direction = SYNC_A2B_B2A;
}
if (ctype == OVERWR_ALWAYS && direction == SYNC_A2B_B2A)
ctype = OVERWR_IF_DIFF;
dirFilters = QDir::Filters(QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot);
reportTemplate = tr("New: <b>%1</b>; Updated: <b>%2</b>; Skipped: <b>%3</b>; Errors: <font color=%5><b>%4</b></font>;");
if (dryRun)
testRunStr = tr("[TEST RUN] ");
}
void SyncProcess::onClosed()
void SyncProcess::stop()
{
closed = true;
QMutexLocker locker(&stopReqMutex);
stopping = true;
}
bool SyncProcess::run()
bool SyncProcess::isStopRequsted()
{
if (!QFile::exists(folder1)) {
QMessageBox::warning(NULL, QObject::tr("Synchronization error"), QObject::tr("The directory '%1' doesn't exist!").arg(folder1));
return true;
QMutexLocker locker(&stopReqMutex);
return stopping;
}
void SyncProcess::run()
{
count = index = created = updated = skipped = errored = 0;
emit started();
emit progressStep(index);
emit statusMessage(tr("Gathering file information..."));
if (direction == SYNC_A2B_B2A || direction == SYNC_A2B)
count += getFilesCount(folder1);
if (isStopRequsted()) {
finish();
return;
}
if (!QFile::exists(folder2)) {
QMessageBox::warning(NULL, QObject::tr("Synchronization error"), QObject::tr("The directory '%1' doesn't exist!").arg(folder2));
return true;
if (direction == SYNC_A2B_B2A || direction == SYNC_B2A)
count += getFilesCount(folder2);
if (isStopRequsted()) {
finish();
return;
}
count = getFilesCount(folder1) + getFilesCount(folder2);
progress->setMaximum(count);
emit fileCountChanged(count);
QStringList errors = updateDir(folder1, folder2) + updateDir(folder2, folder1);
if (errors.count() > 0) {
QMessageBox::warning(NULL, QObject::tr("Synchronization error"), errors.join("\n"));
if (!count) {
QString nf = tr("Synchronization failed, nothing found to copy.");
emit statusMessage(nf);
PRINT_ERROR(nf);
emit finished();
return;
}
// don't close the window unless the user wanted
return closed;
if (direction == SYNC_A2B_B2A || direction == SYNC_A2B)
updateDir(folder1, folder2);
if (isStopRequsted()) {
finish();
return;
}
if (direction == SYNC_A2B_B2A || direction == SYNC_B2A)
updateDir(folder2, folder1);
finish();
}
void SyncProcess::finish()
{
QString endStr = testRunStr % tr("Synchronization finished. ") % reportTemplate;
emit statusMessage(endStr.arg(created).arg(updated).arg(skipped).arg(errored).arg(errored ? "red" : "black"));
emit finished();
}
int SyncProcess::getFilesCount(const QString & directory)
{
if (!QFile::exists(directory))
return 0;
int result = 0;
QDirIterator it(directory, QDirIterator::Subdirectories);
while (it.hasNext()) {
QDirIterator it(directory, dirFilters, QDirIterator::Subdirectories | QDirIterator::FollowSymlinks);
while (it.hasNext() && !isStopRequsted()) {
it.next();
result++;
QApplication::processEvents();
}
return result;
}
QStringList SyncProcess::updateDir(const QString & source, const QString & destination)
void SyncProcess::updateDir(const QString & source, const QString & destination)
{
QDirIterator it(source, QDirIterator::Subdirectories);
while (!closed && it.hasNext()) {
QEventLoop loop;
QTimer::singleShot(10, &loop, SLOT(quit()));
loop.exec();
index++;
progress->setInfo(tr("%1/%2 files").arg(index).arg(count));
progress->setValue(index);
QString result = updateEntry(it.next(), source, destination);
if (!result.isEmpty()) {
errors << result;
int counts[4] = { created, updated, skipped, errored };
QString statusStr = testRunStr % tr("Synchronizing %1 -&gt; %2: %3").arg(source, destination, "<b>%1</b>|<b>%2</b> (%3)");
PRINT_INFO(testRunStr % tr("Starting synchronization: %1 -&gt; %2<br>").arg(source, destination));
QDirIterator it(source, dirFilters, QDirIterator::Subdirectories | QDirIterator::FollowSymlinks);
while (it.hasNext() && !isStopRequsted()) {
it.next();
++index;
emit statusMessage(statusStr.arg(index).arg(count).arg(reportTemplate.arg(created).arg(updated).arg(skipped).arg(errored).arg(errored ? "red" : "black")));
emit progressStep(index);
if (maxFileSize && it.fileInfo().isFile() && it.fileInfo().size() > maxFileSize) {
PRINT_SKIP(tr("Skipping large file: %1 (%2KB)").arg(it.fileName()).arg(int(it.fileInfo().size() / 1024)));
++skipped;
}
else {
updateEntry(it.filePath(), source, destination);
if (errored - counts[3] > SYNC_MAX_ERRORS) {
PRINT_ERROR(tr("<br><b>Too many errors, giving up.<b>"));
break;
}
}
QApplication::processEvents();
}
return errors;
QString endStr = "<br>" % testRunStr % tr("Finished synchronizing %1 -&gt; %2 :<br>&nbsp;&nbsp;&nbsp;&nbsp; %3").arg(source, destination, reportTemplate);
PRINT_INFO(endStr.arg(created-counts[0]).arg(updated-counts[1]).arg(skipped-counts[2]).arg(errored-counts[3]).arg(errored-counts[3] ? "red" : "black"));
PRINT_SEP();
}
QString SyncProcess::updateEntry(const QString & path, const QDir & source, const QDir & destination)
bool SyncProcess::updateEntry(const QString & entry, const QDir & source, const QDir & destination)
{
QFileInfo sourceInfo(path);
QString relativePath = source.relativeFilePath(path);
QString destinationPath = destination.absoluteFilePath(relativePath);
QFileInfo destinationInfo(destinationPath);
QString srcPath = source.toNativeSeparators(source.absoluteFilePath(entry));
QString relPath = source.relativeFilePath(entry);
QString destPath = destination.toNativeSeparators(destination.absoluteFilePath(relPath));
QFileInfo sourceInfo(srcPath);
QFileInfo destInfo(destPath);
if (sourceInfo.isDir()) {
if (!destinationInfo.exists()) {
progress->addText(tr("Create directory %1\n").arg(destinationPath));
if (!destination.mkdir(relativePath)) {
return QObject::tr("Create '%1' failed").arg(destinationPath);
if (!destInfo.exists()) {
PRINT_CREATE(tr("Creating directory: %1").arg(destPath));
if (!dryRun && !destination.mkpath(destPath)) {
PRINT_ERROR(tr("Could not create directory: %1").arg(destPath));
++errored;
return false;
}
++created;
}
else {
PRINT_SKIP(tr("Destination directory exists: %1").arg(destPath));
++skipped;
}
return true;
}
else {
if (!destinationInfo.exists()) {
// qDebug() << "Copy" << path << "to" << destinationPath;
progress->addText(tr("Copy %1 to %2").arg(path).arg(destinationPath) + "\n");
if (!QFile::copy(path, destinationPath)) {
return QObject::tr("Copy '%1' to '%2' failed").arg(path).arg(destinationPath);
}
}
else if (sourceInfo.lastModified() > destinationInfo.lastModified()) {
// retrieve source contents
QFile sourceFile(path);
if (!sourceFile.open(QFile::ReadOnly)) {
return QObject::tr("Open '%1' failed").arg(path);
}
QString sourceContents = sourceFile.readAll();
sourceFile.close();
// try to retrieve destination contents
QFile destinationFile(destinationPath);
if (destinationFile.open(QFile::ReadOnly)) {
QString destinationContents = destinationFile.readAll();
destinationFile.close();
if (sourceContents == destinationContents) {
// qDebug() << "Skip" << path;
return QString();
}
}
if (!destinationFile.open(QFile::WriteOnly)) {
return QObject::tr("Write '%1' failed").arg(destinationPath);
}
progress->addText(tr("Write %1").arg(destinationPath) + "\n");
// qDebug() << "Write" << destinationPath;
QTextStream destinationStream(&destinationFile);
destinationStream << sourceContents;
destinationFile.close();
QFile sourceFile(srcPath);
QFile destinationFile(destPath);
bool destExists = destInfo.exists();
bool checkDate = (ctype == OVERWR_NEWER_IF_DIFF || ctype == OVERWR_NEWER_ALWAYS);
bool checkContent = (ctype == OVERWR_NEWER_IF_DIFF || ctype == OVERWR_IF_DIFF);
bool existed = false;
if (destExists && checkDate) {
if (sourceInfo.lastModified() <= destInfo.lastModified()) {
PRINT_SKIP(tr("Skipping older file: %1").arg(srcPath));
++skipped;
return true;
}
checkDate = false;
}
return QString();
if (destExists && checkContent) {
if (!sourceFile.open(QFile::ReadOnly)) {
PRINT_ERROR(tr("Could not open source file '%1': %2").arg(srcPath, sourceFile.errorString()));
++errored;
return false;
}
if (!destinationFile.open(QFile::ReadOnly)) {
PRINT_ERROR(tr("Could not open destination file '%1': %2").arg(destPath, destinationFile.errorString()));
++errored;
return false;
}
bool skip = QCryptographicHash::hash(sourceFile.readAll(), QCryptographicHash::Md5) == QCryptographicHash::hash(destinationFile.readAll(), QCryptographicHash::Md5);
sourceFile.close();
destinationFile.close();
if (skip) {
PRINT_SKIP(tr("Skipping identical file: %1").arg(srcPath));
++skipped;
return true;
}
checkContent = false;
}
if (!destExists || (!checkDate && !checkContent)) {
if (destInfo.exists()) {
existed = true;
PRINT_REPLACE(tr("Replacing destination file: %1").arg(destPath));
if (!dryRun && !destinationFile.remove()) {
PRINT_ERROR(tr("Could not delete destination file '%1': %2").arg(destPath, destinationFile.errorString()));
++errored;
return false;
}
}
else {
PRINT_CREATE(tr("Creating destination file: %1").arg(destPath));
}
if (!dryRun && !sourceFile.copy(destPath)) {
PRINT_ERROR(tr("Copy failed: '%1' to '%2': %3").arg(srcPath, destPath, sourceFile.errorString()));
++errored;
return false;
}
if (existed)
++updated;
else
++created;
}
return true;
}
+51 -13
View File
@@ -22,34 +22,72 @@
#define _PROCESS_SYNC_H_
#include <QObject>
#include <QDir>
#include <QMutex>
#include <QString>
#include <QStringList>
class QDir;
class ProgressWidget;
class SyncProcess : public QObject
{
Q_OBJECT
public:
SyncProcess(const QString & folder1, const QString & folder2, ProgressWidget * progress);
bool run();
enum SyncDirection {
SYNC_A2B_B2A,
SYNC_B2A_A2B,
SYNC_A2B,
SYNC_B2A
};
protected slots:
void onClosed();
enum SyncCompareType {
OVERWR_NEWER_IF_DIFF,
OVERWR_NEWER_ALWAYS,
OVERWR_IF_DIFF,
OVERWR_ALWAYS
};
SyncProcess(const QString & folderA,
const QString & folderB,
const int & syncDirection = SYNC_A2B_B2A,
const int & compareType = OVERWR_NEWER_IF_DIFF,
const qint64 & maxFileSize = 5*1024*1024,
const bool dryRun = false);
public slots:
void run();
void stop();
signals:
void started();
void finished();
void fileCountChanged(int count);
void progressStep(int step);
void progressMessage(const QString & text, const int & type);
void statusMessage(const QString & text);
protected:
bool isStopRequsted();
void finish();
int getFilesCount(const QString & directory);
QStringList updateDir(const QString & source, const QString & destination);
QString updateEntry(const QString & path, const QDir & source, const QDir & destination);
void updateDir(const QString & source, const QString & destination);
bool updateEntry(const QString & entry, const QDir & source, const QDir & destination);
QString folder1;
QString folder2;
ProgressWidget * progress;
QStringList errors;
SyncDirection direction;
SyncCompareType ctype;
qint64 maxFileSize; // Bytes
QDir::Filters dirFilters;
QMutex stopReqMutex;
QString reportTemplate;
QString testRunStr;
int index;
int count;
bool closed;
int created;
int updated;
int skipped;
int errored;
bool dryRun;
bool stopping;
};
#endif // _PROCESS_SYNC_H_
+12
View File
@@ -32,6 +32,7 @@ locked(false)
ui->setupUi(this);
setWindowTitle(title);
setWindowIcon(icon);
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
if (forceOpen) {
ui->outputProgress->forceOpen();
}
@@ -53,6 +54,7 @@ void ProgressDialog::on_closeButton_clicked()
{
if (!locked) {
ui->outputProgress->stop();
emit rejected();
close();
}
}
@@ -77,3 +79,13 @@ bool ProgressDialog::isEmpty() const
{
return ui->outputProgress->isEmpty();
}
void ProgressDialog::setProcessStarted()
{
ui->closeButton->setText(tr("Cancel"));
}
void ProgressDialog::setProcessStopped()
{
ui->closeButton->setText(tr("Close"));
}
+4
View File
@@ -41,6 +41,10 @@ public:
ProgressWidget * progress();
bool isEmpty() const;
public slots:
void setProcessStarted();
void setProcessStopped();
private slots:
void on_closeButton_clicked();
void on_outputProgress_detailsToggled();
+30 -27
View File
@@ -6,22 +6,16 @@
<rect>
<x>0</x>
<y>0</y>
<width>431</width>
<height>115</height>
<width>646</width>
<height>211</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Minimum">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="windowTitle">
<string>Flash Firmware</string>
</property>
@@ -29,28 +23,37 @@
<iconset resource="companion.qrc">
<normaloff>:/icon.png</normaloff>:/icon.png</iconset>
</property>
<property name="modal">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="1,0">
<property name="spacing">
<number>5</number>
</property>
<property name="leftMargin">
<number>7</number>
</property>
<property name="topMargin">
<number>5</number>
</property>
<property name="rightMargin">
<number>7</number>
</property>
<property name="bottomMargin">
<number>4</number>
</property>
<item>
<widget class="ProgressWidget" name="outputProgress" native="true"/>
</item>
<item>
<spacer name="spacer2">
<property name="orientation">
<enum>Qt::Vertical</enum>
<widget class="ProgressWidget" name="outputProgress" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>6</number>
</property>
<item>
<spacer name="spacer1">
<property name="orientation">
@@ -59,7 +62,7 @@
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
<height>1</height>
</size>
</property>
</spacer>
+46 -11
View File
@@ -34,14 +34,15 @@ ui(new Ui::ProgressWidget)
ui->checkBox->hide();
ui->textEdit->hide();
QFont newFont(ui->textEdit->font());
newFont.setFamily("Courier");
#ifdef __APPLE__
QFont newFont("Courier", 13);
ui->textEdit->setFont(newFont);
newFont.setPointSize(13);
ui->textEdit->setAttribute(Qt::WA_MacNormalSize);
#elif defined WIN32 || !defined __GNUC__
QFont newFont("Courier", 9);
ui->textEdit->setFont(newFont);
newFont.setPointSize(9);
#endif
ui->textEdit->setFont(newFont);
}
ProgressWidget::~ProgressWidget()
@@ -81,14 +82,10 @@ void ProgressWidget::setValue(int value)
ui->progressBar->setValue(value);
}
void ProgressWidget::addText(const QString &text)
void ProgressWidget::addText(const QString &text, const bool richText)
{
ui->checkBox->setVisible(true);
if (g.outputDisplayDetails()) {
ui->checkBox->setChecked(true);
ui->textEdit->setVisible(true);
}
ui->checkBox->setChecked(g.outputDisplayDetails());
QTextCursor cursor(ui->textEdit->textCursor());
@@ -96,13 +93,51 @@ void ProgressWidget::addText(const QString &text)
bool atEnd = (ui->textEdit->verticalScrollBar()->value() == ui->textEdit->verticalScrollBar()->maximum());
cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor, 1);
cursor.insertText(text);
if (richText)
cursor.insertHtml(text);
else
cursor.insertText(text);
if (atEnd) {
ui->textEdit->verticalScrollBar()->triggerAction(QAbstractSlider::SliderToMaximum);
}
}
void ProgressWidget::addHtml(const QString & text)
{
addText(text, true);
}
void ProgressWidget::addMessage(const QString & text, const int & type)
{
QString color;
switch (type) {
case QtDebugMsg:
color = "dimgrey"; // not important messages, may be filtered out
break;
case QtWarningMsg: // use warning level as emphasis
color = "darkblue";
break;
case QtCriticalMsg: // use critical as a warning
color = "#ff7900";
break;
case QtFatalMsg: // fatal for hard errors
color = "red";
break;
case QtInfoMsg: // default plain text
default:
break;
}
if (color.isEmpty()) {
if (text.contains(QRegExp("<[^>]+>"))) // detect html (rouhgly)
addHtml(text % "<br>");
else
addText(text % "\n", false);
}
else
addHtml(QString("<font color=%1>").arg(color) % text % "</font><br>");
}
QString ProgressWidget::getText()
{
return ui->textEdit->toPlainText();
+7 -1
View File
@@ -23,6 +23,10 @@
#include <QWidget>
#if (QT_VERSION < QT_VERSION_CHECK(5, 5, 0))
#define QtInfoMsg QtMsgType(4)
#endif
namespace Ui {
class ProgressWidget;
}
@@ -35,7 +39,9 @@ class ProgressWidget : public QWidget
explicit ProgressWidget(QWidget *parent);
~ProgressWidget();
void lock(bool lock);
void addText(const QString &text);
void addText(const QString &text, const bool richText = false);
void addHtml(const QString &text);
void addMessage(const QString & text, const int & type = QtInfoMsg);
QString getText();
void setInfo(const QString &text);
void setMaximum(int value);
+86 -55
View File
@@ -9,26 +9,26 @@
<rect>
<x>0</x>
<y>0</y>
<width>700</width>
<height>244</height>
<width>753</width>
<height>474</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>700</width>
<width>650</width>
<height>0</height>
</size>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,1,0">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
@@ -43,56 +43,79 @@
</property>
<item>
<widget class="QLabel" name="info">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
<string notr="true"/>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,0">
<item>
<widget class="QProgressBar" name="progressBar">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox">
<property name="text">
<string>Show Details</string>
</property>
</widget>
</item>
</layout>
<widget class="QWidget" name="widget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,0">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QProgressBar" name="progressBar">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox">
<property name="text">
<string>Show Details</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QPlainTextEdit" name="textEdit">
<widget class="QTextEdit" name="textEdit">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>600</width>
<height>100</height>
<width>0</width>
<height>350</height>
</size>
</property>
<property name="font">
@@ -101,32 +124,40 @@
<pointsize>10</pointsize>
</font>
</property>
<property name="lineWidth">
<number>80</number>
</property>
<property name="midLineWidth">
<number>80</number>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOn</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<property name="lineWrapMode">
<enum>QPlainTextEdit::NoWrap</enum>
<property name="undoRedoEnabled">
<bool>false</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="plainText">
<string/>
<property name="html">
<string notr="true">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Courier'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textInteractionFlags">
<set>Qt::TextSelectableByMouse</set>
<set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
+48 -40
View File
@@ -25,15 +25,10 @@
#include "radionotfound.h"
#include "burnconfigdialog.h"
#include "helpers.h"
#include "mountlist.h"
#include "process_copy.h"
#include "storage.h"
#include "progresswidget.h"
#if defined WIN32 || !defined __GNUC__
#include <windows.h>
#endif
QString getRadioInterfaceCmd()
{
burnConfigDialog bcd;
@@ -401,7 +396,9 @@ bool writeEeprom(const QString & filename, ProgressWidget * progress)
return false;
}
#if (QT_VERSION < QT_VERSION_CHECK(5, 4, 0))
#if defined WIN32 || !defined __GNUC__
#include <windows.h>
bool isRemovableMedia(const QString & vol)
{
char szDosDeviceName[MAX_PATH];
@@ -415,61 +412,69 @@ bool isRemovableMedia(const QString & vol)
}
return true;
}
#endif
#else
#include "mountlist.h"
#endif // defined WIN32 || !defined __GNUC__
#endif // (QT_VERSION < QT_VERSION_CHECK(5, 4, 0))
QString findMassstoragePath(const QString & filename, bool onlyPath)
{
QString temppath;
QStringList drives;
QString eepromfile;
QString fsname;
bool found = false;
QRegularExpression fstypeRe("^(v?fat|msdos)", QRegularExpression::CaseInsensitiveOption); // Linux: "vfat"; macOS: "msdos"; Win: "FAT32"
#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0))
foreach(const QStorageInfo & si, QStorageInfo::mountedVolumes()) {
//qDebug() << si.rootPath() << si.name() << si.device() << si.displayName() << si.fileSystemType() << si.isReady();
if (!si.isReady() || !QString(si.fileSystemType()).contains(fstypeRe))
continue;
temppath = si.rootPath();
eepromfile = temppath % "/" % filename;
qDebug() << "Searching for" << eepromfile;
if (QFile::exists(eepromfile)) {
found = true;
break;
}
}
#elif defined WIN32 || !defined __GNUC__
static QStringList blacklist;
#if defined WIN32 || !defined __GNUC__
foreach(QFileInfo drive, QDir::drives()) {
foreach(const QFileInfo & drive, QDir::drives()) {
temppath = drive.absolutePath();
if (blacklist.contains(temppath))
continue;
if (!isRemovableMedia(temppath)) {
blacklist.append(temppath);
continue;
}
WCHAR szVolumeName[256] ;
WCHAR szFileSystemName[256];
DWORD dwSerialNumber = 0;
DWORD dwMaxFileNameLength=256;
DWORD dwFileSystemFlags=0;
if (!blacklist.contains(drive.absolutePath())) {
if (!isRemovableMedia( drive.absolutePath() )) {
blacklist.append(drive.absolutePath());
} else {
bool ret = GetVolumeInformationW( (WCHAR *) drive.absolutePath().utf16(),szVolumeName,256,&dwSerialNumber,&dwMaxFileNameLength,&dwFileSystemFlags,szFileSystemName,256);
if (ret) {
QString vName = QString::fromUtf16 ( (const ushort *) szVolumeName) ;
temppath = drive.absolutePath();
eepromfile = temppath;
eepromfile.append("/" + filename);
if (QFile::exists(eepromfile)) {
return onlyPath ? temppath : eepromfile;
}
}
}
if (!GetVolumeInformationW( (WCHAR *) drive.absolutePath().utf16(),szVolumeName,256,&dwSerialNumber,&dwMaxFileNameLength,&dwFileSystemFlags,szFileSystemName,256))
continue;
eepromfile = temppath % "/" % filename;
qDebug() << "Searching for" << eepromfile;
if (QFile::exists(eepromfile)) {
found = true;
break;
}
}
#else
const static QStringList blacklist = QStringList() << "/" << "/net" << "/proc" << "/run";
QStringList drives;
struct mount_entry *entry;
struct mount_entry *firstEntry;
firstEntry = entry = read_file_system_list(true);
while (entry != NULL) {
if (!drives.contains(entry->me_devname)) {
temppath = entry->me_mountdir;
if (!drives.contains(entry->me_devname) && !blacklist.contains(temppath) && QString(entry->me_type).contains(fstypeRe)) {
drives.append(entry->me_devname);
temppath = entry->me_mountdir;
eepromfile = temppath;
eepromfile.append("/" + filename);
eepromfile = temppath % "/" % filename;
qDebug() << "Searching for" << eepromfile;
#if !defined __APPLE__
QString fstype = entry->me_type;
// qDebug() << eepromfile;
if (fstype.contains("fat") && QFile::exists(eepromfile)) {
#else
if (QFile::exists(eepromfile)) {
#endif
free_file_system_list(firstEntry);
return onlyPath ? temppath : eepromfile;
found = true;
break;
}
}
entry = entry->me_next;
@@ -477,5 +482,8 @@ QString findMassstoragePath(const QString & filename, bool onlyPath)
free_file_system_list(firstEntry);
#endif
return QString();
if (found)
return onlyPath ? temppath : eepromfile;
else
return QString();
}
@@ -267,7 +267,7 @@ QWidget * RadioOutputsWidget::createLogicalSwitch(QWidget * parent, int switchNo
swtch->setMinimumWidth(swtch->fontMetrics().width("99") + 10);
font.setBold(false);
swtch->setFont(font);
swtch->setText(QString("%1").arg(RawSwitch(SWITCH_TYPE_VIRTUAL, switchNo+1).toString().remove("L"), 2, QLatin1Char('0')));
swtch->setText(QString("%1").arg(switchNo+1, 2, 10, QChar('0')));
swtch->setAlignment(Qt::AlignCenter);
m_logicSwitchMap.insert(switchNo, swtch);
return swtch;
@@ -38,40 +38,40 @@ SimulatedUIWidget9X::SimulatedUIWidget9X(SimulatorInterface * simulator, QWidget
int x = 68, y = 91, oR = 63;
polygon << QPoint(x, y) << polyArc(x, y, oR, -45, 45);
act = new RadioUiAction(3, QList<int>() << Qt::Key_Up << Qt::Key_PageUp, tr(SIMU_STR_HLP_KEYS_GO_UP) % (hasRotEnc ? "" : tr("|" SIMU_STR_HLP_MOUSE_UP)), tr(SIMU_STR_HLP_ACT_UP));
act = new RadioUiAction(3, QList<int>() << Qt::Key_Up << Qt::Key_PageUp, SIMU_STR_HLP_KEYS_GO_UP % (hasRotEnc ? QString("") : "|" % SIMU_STR_HLP_MOUSE_UP), SIMU_STR_HLP_ACT_UP);
addRadioWidget(ui->leftbuttons->addArea(polygon, "9X/9xcursup.png", act));
polygon.clear();
polygon << QPoint(x, y) << polyArc(x, y, oR, 135, 225);
act = new RadioUiAction(2, QList<int>() << Qt::Key_Down << Qt::Key_PageDown, tr(SIMU_STR_HLP_KEYS_GO_DN) % (hasRotEnc ? "" : tr("|" SIMU_STR_HLP_MOUSE_DN)), tr(SIMU_STR_HLP_ACT_DN));
act = new RadioUiAction(2, QList<int>() << Qt::Key_Down << Qt::Key_PageDown, SIMU_STR_HLP_KEYS_GO_DN % (hasRotEnc ? QString("") : "|" % SIMU_STR_HLP_MOUSE_DN), SIMU_STR_HLP_ACT_DN);
addRadioWidget(ui->leftbuttons->addArea(polygon, "9X/9xcursdown.png", act));
polygon.clear();
polygon << QPoint(x, y) << polyArc(x, y, oR, 45, 135);
act = new RadioUiAction(4, QList<int>() << Qt::Key_Right << Qt::Key_Minus, tr(SIMU_STR_HLP_KEY_RGT "|" SIMU_STR_HLP_KEY_MIN), tr(SIMU_STR_HLP_ACT_MIN));
act = new RadioUiAction(4, QList<int>() << Qt::Key_Right << Qt::Key_Minus, SIMU_STR_HLP_KEY_RGT % "|" % SIMU_STR_HLP_KEY_MIN, SIMU_STR_HLP_ACT_MIN);
addRadioWidget(ui->leftbuttons->addArea(polygon, "9X/9xcursmin.png", act));
polygon.clear();
polygon << QPoint(x, y) << polyArc(x, y, oR, 225, 315);
act = new RadioUiAction(5, QList<int>() << Qt::Key_Left << Qt::Key_Plus << Qt::Key_Equal, tr(SIMU_STR_HLP_KEY_LFT "|" SIMU_STR_HLP_KEY_PLS), tr(SIMU_STR_HLP_ACT_PLS));
act = new RadioUiAction(5, QList<int>() << Qt::Key_Left << Qt::Key_Plus << Qt::Key_Equal, SIMU_STR_HLP_KEY_LFT % "|" % SIMU_STR_HLP_KEY_PLS, SIMU_STR_HLP_ACT_PLS);
addRadioWidget(ui->leftbuttons->addArea(polygon, "9X/9xcursplus.png", act));
act = new RadioUiAction(0, QList<int>() << Qt::Key_Enter << Qt::Key_Return, tr(SIMU_STR_HLP_KEY_ENTER), tr(SIMU_STR_HLP_ACT_MENU));
act = new RadioUiAction(0, QList<int>() << Qt::Key_Enter << Qt::Key_Return, SIMU_STR_HLP_KEY_ENTER, SIMU_STR_HLP_ACT_MENU);
addRadioWidget(ui->rightbuttons->addArea(QRect(16, 54, 60, 34), "9X/9xmenumenu.png", act));
if (!hasRotEnc) {
m_mouseMidClickAction = act;
m_mouseMidClickAction->setText(act->getText() % "|" SIMU_STR_HLP_MOUSE_MID);
m_mouseMidClickAction->setText(act->getText() % "|" % SIMU_STR_HLP_MOUSE_MID);
}
act = new RadioUiAction(1, QList<int>() << Qt::Key_Delete << Qt::Key_Escape << Qt::Key_Backspace, tr(SIMU_STR_HLP_KEYS_EXIT), tr(SIMU_STR_HLP_ACT_EXIT));
act = new RadioUiAction(1, QList<int>() << Qt::Key_Delete << Qt::Key_Escape << Qt::Key_Backspace, SIMU_STR_HLP_KEYS_EXIT, SIMU_STR_HLP_ACT_EXIT);
addRadioWidget(ui->rightbuttons->addArea(QRect(16, 114, 60, 34), "9X/9xmenuexit.png", act));
addRadioWidget(ui->leftbuttons->addArea(QRect(6, 149, 30, 30), "9X/9xcursphoto.png", m_screenshotAction));
if (hasRotEnc) {
addRadioAction(new RadioUiAction(-1, 0, tr(SIMU_STR_HLP_MOUSE_SCRL), tr(SIMU_STR_HLP_ROTENC " " SIMU_STR_HLP_ROTENC_LR)));
m_mouseMidClickAction = new RadioUiAction(14, Qt::Key_Insert, tr(SIMU_STR_HLP_KEY_INS "|" SIMU_STR_HLP_MOUSE_MID), tr(SIMU_STR_HLP_ACT_ROT_DN));
addRadioAction(new RadioUiAction(-1, 0, SIMU_STR_HLP_MOUSE_SCRL, SIMU_STR_HLP_ROTENC % "|" % SIMU_STR_HLP_ROTENC_LR));
m_mouseMidClickAction = new RadioUiAction(14, Qt::Key_Insert, SIMU_STR_HLP_KEY_INS % "|" % SIMU_STR_HLP_MOUSE_MID, SIMU_STR_HLP_ACT_ROT_DN);
addRadioWidget(ui->leftbuttons->addArea(QRect(0, 0, 0, 0), "9X/9xcurs.png", m_mouseMidClickAction));
}
@@ -35,40 +35,40 @@ SimulatedUIWidgetX12::SimulatedUIWidgetX12(SimulatorInterface *simulator, QWidge
int x = 74, y = 190, oR = 63, iR = 40;
polygon << polyArc(x, y, oR, 225, 315) << polyArc(x, y, iR, 225, 315);
act = new RadioUiAction(0, QList<int>() << Qt::Key_PageUp, tr(SIMU_STR_HLP_KEY_PGUP), tr(SIMU_STR_HLP_ACT_PGUP));
act = new RadioUiAction(0, QList<int>() << Qt::Key_PageUp, SIMU_STR_HLP_KEY_PGUP, SIMU_STR_HLP_ACT_PGUP);
addRadioWidget(ui->leftbuttons->addArea(polygon, "Horus/left_btn1.png", act));
polygon.clear();
polygon << polyArc(x, y, oR, 135, 225) << polyArc(x, y, iR, 135, 225);
act = new RadioUiAction(1, QList<int>() << Qt::Key_PageDown, tr(SIMU_STR_HLP_KEY_PGDN), tr(SIMU_STR_HLP_ACT_PGDN));
act = new RadioUiAction(1, QList<int>() << Qt::Key_PageDown, SIMU_STR_HLP_KEY_PGDN, SIMU_STR_HLP_ACT_PGDN);
addRadioWidget(ui->leftbuttons->addArea(polygon, "Horus/left_btn2.png", act));
polygon.clear();
polygon << polyArc(x, y, oR, -45, 45) << polyArc(x, y, iR, -45, 45);
act = new RadioUiAction(3, QList<int>() << Qt::Key_Up, tr(SIMU_STR_HLP_KEY_UP), tr(SIMU_STR_HLP_ACT_MDL));
act = new RadioUiAction(3, QList<int>() << Qt::Key_Up, SIMU_STR_HLP_KEY_UP, SIMU_STR_HLP_ACT_MDL);
addRadioWidget(ui->rightbuttons->addArea(polygon, "Horus/right_btnU.png", act));
polygon.clear();
polygon << polyArc(x, y, oR, 225, 315) << polyArc(x, y, iR, 225, 315);
act = new RadioUiAction(6, QList<int>() << Qt::Key_Left, tr(SIMU_STR_HLP_KEY_LFT), tr(SIMU_STR_HLP_ACT_SYS));
act = new RadioUiAction(6, QList<int>() << Qt::Key_Left, SIMU_STR_HLP_KEY_LFT, SIMU_STR_HLP_ACT_SYS);
addRadioWidget(ui->rightbuttons->addArea(polygon, "Horus/right_btnL.png", act));
polygon.clear();
polygon << polyArc(x, y, oR, 45, 135) << polyArc(x, y, iR, 45, 135);
act = new RadioUiAction(5, QList<int>() << Qt::Key_Right, tr(SIMU_STR_HLP_KEY_RGT), tr(SIMU_STR_HLP_ACT_TELE));
act = new RadioUiAction(5, QList<int>() << Qt::Key_Right, SIMU_STR_HLP_KEY_RGT, SIMU_STR_HLP_ACT_TELE);
addRadioWidget(ui->rightbuttons->addArea(polygon, "Horus/right_btnR.png", act));
polygon.clear();
polygon << polyArc(x, y, oR, 135, 225) << polyArc(x, y, iR, 135, 225);
act = new RadioUiAction(4, QList<int>() << Qt::Key_Down << Qt::Key_Delete << Qt::Key_Escape << Qt::Key_Backspace,
tr(SIMU_STR_HLP_KEY_DN "<br>" SIMU_STR_HLP_KEYS_EXIT), tr(SIMU_STR_HLP_ACT_RTN));
SIMU_STR_HLP_KEY_DN % "<br>" % SIMU_STR_HLP_KEYS_EXIT, SIMU_STR_HLP_ACT_RTN);
addRadioWidget(ui->rightbuttons->addArea(polygon, "Horus/right_btnD.png", act));
m_scrollUpAction = new RadioUiAction(-1, QList<int>() << Qt::Key_Minus, tr(SIMU_STR_HLP_KEY_MIN "|" SIMU_STR_HLP_MOUSE_UP), tr(SIMU_STR_HLP_ACT_ROT_LFT));
m_scrollDnAction = new RadioUiAction(-1, QList<int>() << Qt::Key_Plus << Qt::Key_Equal, tr(SIMU_STR_HLP_KEY_PLS "|" SIMU_STR_HLP_MOUSE_DN), tr(SIMU_STR_HLP_ACT_ROT_RGT));
m_scrollUpAction = new RadioUiAction(-1, QList<int>() << Qt::Key_Minus, SIMU_STR_HLP_KEY_MIN % "|" % SIMU_STR_HLP_MOUSE_UP, SIMU_STR_HLP_ACT_ROT_LFT);
m_scrollDnAction = new RadioUiAction(-1, QList<int>() << Qt::Key_Plus << Qt::Key_Equal, SIMU_STR_HLP_KEY_PLS % "|" % SIMU_STR_HLP_MOUSE_DN, SIMU_STR_HLP_ACT_ROT_RGT);
connectScrollActions();
m_mouseMidClickAction = new RadioUiAction(2, QList<int>() << Qt::Key_Enter << Qt::Key_Return, tr(SIMU_STR_HLP_KEYS_ACTIVATE), tr(SIMU_STR_HLP_ACT_ROT_DN));
m_mouseMidClickAction = new RadioUiAction(2, QList<int>() << Qt::Key_Enter << Qt::Key_Return, SIMU_STR_HLP_KEYS_ACTIVATE, SIMU_STR_HLP_ACT_ROT_DN);
addRadioWidget(ui->rightbuttons->addArea(polyArc(x, y, iR), "Horus/right_ent.png", m_mouseMidClickAction));
addRadioWidget(ui->leftbuttons->addArea(QRect(9, 259, 30, 30), "Horus/left_scrnsht.png", m_screenshotAction));
@@ -14,22 +14,22 @@ SimulatedUIWidgetX7::SimulatedUIWidgetX7(SimulatorInterface *simulator, QWidget
QPoint ctr(70, 91);
polygon << polyArc(ctr.x(), ctr.y(), 50, -90, 90) << polyArc(ctr.x(), ctr.y(), 22, -90, 90);
act = new RadioUiAction(3, QList<int>() << Qt::Key_PageUp << Qt::Key_Up, tr(SIMU_STR_HLP_KEYS_GO_UP), tr(SIMU_STR_HLP_ACT_PAGE));
act = new RadioUiAction(3, QList<int>() << Qt::Key_PageUp << Qt::Key_Up, SIMU_STR_HLP_KEYS_GO_UP, SIMU_STR_HLP_ACT_PAGE);
addRadioWidget(ui->leftbuttons->addArea(polygon, "X7/left_page.png", act));
act = new RadioUiAction(0, QList<int>() << Qt::Key_PageDown << Qt::Key_Down, tr(SIMU_STR_HLP_KEYS_GO_DN), tr(SIMU_STR_HLP_ACT_MENU_ICN));
act = new RadioUiAction(0, QList<int>() << Qt::Key_PageDown << Qt::Key_Down, SIMU_STR_HLP_KEYS_GO_DN, SIMU_STR_HLP_ACT_MENU_ICN);
addRadioWidget(ui->leftbuttons->addArea(polyArc(ctr.x(), ctr.y(), 20), "X7/left_menu.png", act));
polygon.clear();
polygon << polyArc(ctr.x(), ctr.y(), 50, 90, 270) << polyArc(ctr.x(), ctr.y(), 22, 90, 270);
act = new RadioUiAction(1, QList<int>() << Qt::Key_Delete << Qt::Key_Escape << Qt::Key_Backspace, tr(SIMU_STR_HLP_KEYS_EXIT), tr(SIMU_STR_HLP_ACT_EXIT));
act = new RadioUiAction(1, QList<int>() << Qt::Key_Delete << Qt::Key_Escape << Qt::Key_Backspace, SIMU_STR_HLP_KEYS_EXIT, SIMU_STR_HLP_ACT_EXIT);
addRadioWidget(ui->leftbuttons->addArea(polygon, "X7/left_exit.png", act));
m_scrollUpAction = new RadioUiAction(-1, QList<int>() << Qt::Key_Minus << Qt::Key_Equal << Qt::Key_Left, tr(SIMU_STR_HLP_KEYS_GO_LFT), tr(SIMU_STR_HLP_ACT_ROT_LFT));
m_scrollDnAction = new RadioUiAction(-1, QList<int>() << Qt::Key_Plus << Qt::Key_Right, tr(SIMU_STR_HLP_KEYS_GO_RGT), tr(SIMU_STR_HLP_ACT_ROT_RGT));
m_scrollUpAction = new RadioUiAction(-1, QList<int>() << Qt::Key_Minus << Qt::Key_Equal << Qt::Key_Left, SIMU_STR_HLP_KEYS_GO_LFT, SIMU_STR_HLP_ACT_ROT_LFT);
m_scrollDnAction = new RadioUiAction(-1, QList<int>() << Qt::Key_Plus << Qt::Key_Right, SIMU_STR_HLP_KEYS_GO_RGT, SIMU_STR_HLP_ACT_ROT_RGT);
connectScrollActions();
m_mouseMidClickAction = new RadioUiAction(2, QList<int>() << Qt::Key_Enter << Qt::Key_Return, tr(SIMU_STR_HLP_KEYS_ACTIVATE), tr(SIMU_STR_HLP_ACT_ROT_DN));
m_mouseMidClickAction = new RadioUiAction(2, QList<int>() << Qt::Key_Enter << Qt::Key_Return, SIMU_STR_HLP_KEYS_ACTIVATE, SIMU_STR_HLP_ACT_ROT_DN);
addRadioWidget(ui->rightbuttons->addArea(polyArc(88, 92, 33), "X7/right_ent.png", m_mouseMidClickAction));
addRadioWidget(ui->leftbuttons->addArea(QRect(9, 154, 30, 30), "X7/left_scrnshot.png", m_screenshotAction));
@@ -37,21 +37,21 @@ SimulatedUIWidgetX9::SimulatedUIWidgetX9(SimulatorInterface *simulator, QWidget
// left side
act = new RadioUiAction(0, QList<int>() << Qt::Key_Up << Qt::Key_PageUp, tr(SIMU_STR_HLP_KEYS_GO_UP), tr(SIMU_STR_HLP_ACT_MENU));
act = new RadioUiAction(0, QList<int>() << Qt::Key_Up << Qt::Key_PageUp, SIMU_STR_HLP_KEYS_GO_UP, SIMU_STR_HLP_ACT_MENU);
addRadioWidget(ui->leftbuttons->addArea(btn, "Taranis/x9l1.png", act));
btn.moveTop(btn.top() + btn.height() + vsp);
act = new RadioUiAction(3, QList<int>() << Qt::Key_Down << Qt::Key_PageDown, tr(SIMU_STR_HLP_KEYS_GO_DN), tr(SIMU_STR_HLP_ACT_PAGE));
act = new RadioUiAction(3, QList<int>() << Qt::Key_Down << Qt::Key_PageDown, SIMU_STR_HLP_KEYS_GO_DN, SIMU_STR_HLP_ACT_PAGE);
addRadioWidget(ui->leftbuttons->addArea(btn, "Taranis/x9l2.png", act));
btn.moveTop(btn.top() + btn.height() + vsp);
act = new RadioUiAction(1, QList<int>() << Qt::Key_Delete << Qt::Key_Escape << Qt::Key_Backspace, tr(SIMU_STR_HLP_KEYS_EXIT), tr(SIMU_STR_HLP_ACT_EXIT));
act = new RadioUiAction(1, QList<int>() << Qt::Key_Delete << Qt::Key_Escape << Qt::Key_Backspace, SIMU_STR_HLP_KEYS_EXIT, SIMU_STR_HLP_ACT_EXIT);
addRadioWidget(ui->leftbuttons->addArea(btn, "Taranis/x9l3.png", act));
m_scrollUpAction = new RadioUiAction(4, QList<int>() << Qt::Key_Plus << Qt::Key_Equal << Qt::Key_Left,
tr(SIMU_STR_HLP_KEY_LFT "|" SIMU_STR_HLP_KEY_PLS "|" SIMU_STR_HLP_MOUSE_UP), tr(SIMU_STR_HLP_ACT_PLS));
SIMU_STR_HLP_KEY_LFT % "|" % SIMU_STR_HLP_KEY_PLS % "|" % SIMU_STR_HLP_MOUSE_UP, SIMU_STR_HLP_ACT_PLS);
m_scrollDnAction = new RadioUiAction(5, QList<int>() << Qt::Key_Minus << Qt::Key_Right,
tr(SIMU_STR_HLP_KEY_RGT "|" SIMU_STR_HLP_KEY_MIN "|" SIMU_STR_HLP_MOUSE_DN), tr(SIMU_STR_HLP_ACT_MIN));
SIMU_STR_HLP_KEY_RGT % "|" % SIMU_STR_HLP_KEY_MIN % "|" % SIMU_STR_HLP_MOUSE_DN, SIMU_STR_HLP_ACT_MIN);
// right side
btn.moveTopLeft(QPoint(58, btop));
@@ -62,7 +62,7 @@ SimulatedUIWidgetX9::SimulatedUIWidgetX9(SimulatorInterface *simulator, QWidget
addRadioWidget(ui->rightbuttons->addArea(btn, "Taranis/x9r2.png", m_scrollDnAction));
btn.moveTop(btn.top() + btn.height() + vsp);
m_mouseMidClickAction = new RadioUiAction(2, QList<int>() << Qt::Key_Enter << Qt::Key_Return, tr(SIMU_STR_HLP_KEYS_ACTIVATE), tr(SIMU_STR_HLP_ACT_ENT));
m_mouseMidClickAction = new RadioUiAction(2, QList<int>() << Qt::Key_Enter << Qt::Key_Return, SIMU_STR_HLP_KEYS_ACTIVATE, SIMU_STR_HLP_ACT_ENT);
addRadioWidget(ui->rightbuttons->addArea(btn, "Taranis/x9r3.png", m_mouseMidClickAction));
addRadioWidget(ui->leftbuttons->addArea(QRect(89, 177, 30, 20), "Taranis/x9l4.png", m_screenshotAction));
@@ -35,24 +35,24 @@ SimulatedUIWidgetX9E::SimulatedUIWidgetX9E(SimulatorInterface *simulator, QWidge
QPoint ctr(70, 100);
polygon << polyArc(ctr.x(), ctr.y(), 60, -90, 0) << ctr;
act = new RadioUiAction(0, QList<int>() << Qt::Key_Up << Qt::Key_PageUp, tr(SIMU_STR_HLP_KEYS_GO_UP), tr(SIMU_STR_HLP_ACT_MENU));
act = new RadioUiAction(0, QList<int>() << Qt::Key_Up << Qt::Key_PageUp, SIMU_STR_HLP_KEYS_GO_UP, SIMU_STR_HLP_ACT_MENU);
addRadioWidget(ui->leftbuttons->addArea(polygon, "X9E/left_menu.png", act));
polygon.clear();
polygon << polyArc(ctr.x(), ctr.y(), 45, 0, 180);
act = new RadioUiAction(3, QList<int>() << Qt::Key_Down << Qt::Key_PageDown, tr(SIMU_STR_HLP_KEYS_GO_DN), tr(SIMU_STR_HLP_ACT_PAGE));
act = new RadioUiAction(3, QList<int>() << Qt::Key_Down << Qt::Key_PageDown, SIMU_STR_HLP_KEYS_GO_DN, SIMU_STR_HLP_ACT_PAGE);
addRadioWidget(ui->leftbuttons->addArea(polygon, "X9E/left_page.png", act));
polygon.clear();
polygon << polyArc(ctr.x(), ctr.y(), 60, 180, 270) << ctr;
act = new RadioUiAction(1, QList<int>() << Qt::Key_Delete << Qt::Key_Escape << Qt::Key_Backspace, tr(SIMU_STR_HLP_KEYS_EXIT), tr(SIMU_STR_HLP_ACT_EXIT));
act = new RadioUiAction(1, QList<int>() << Qt::Key_Delete << Qt::Key_Escape << Qt::Key_Backspace, SIMU_STR_HLP_KEYS_EXIT, SIMU_STR_HLP_ACT_EXIT);
addRadioWidget(ui->leftbuttons->addArea(polygon, "X9E/left_exit.png", act));
m_scrollUpAction = addRadioAction(new RadioUiAction(-1, QList<int>() << Qt::Key_Minus << Qt::Key_Left, tr(SIMU_STR_HLP_KEYS_GO_LFT), tr(SIMU_STR_HLP_ACT_ROT_LFT)));
m_scrollDnAction = addRadioAction(new RadioUiAction(-1, QList<int>() << Qt::Key_Plus << Qt::Key_Equal << Qt::Key_Right, tr(SIMU_STR_HLP_KEYS_GO_RGT), tr(SIMU_STR_HLP_ACT_ROT_RGT)));
m_scrollUpAction = addRadioAction(new RadioUiAction(-1, QList<int>() << Qt::Key_Minus << Qt::Key_Left, SIMU_STR_HLP_KEYS_GO_LFT, SIMU_STR_HLP_ACT_ROT_LFT));
m_scrollDnAction = addRadioAction(new RadioUiAction(-1, QList<int>() << Qt::Key_Plus << Qt::Key_Equal << Qt::Key_Right, SIMU_STR_HLP_KEYS_GO_RGT, SIMU_STR_HLP_ACT_ROT_RGT));
connectScrollActions();
m_mouseMidClickAction = new RadioUiAction(2, QList<int>() << Qt::Key_Enter << Qt::Key_Return, tr(SIMU_STR_HLP_KEYS_ACTIVATE), tr(SIMU_STR_HLP_ACT_ROT_DN));
m_mouseMidClickAction = new RadioUiAction(2, QList<int>() << Qt::Key_Enter << Qt::Key_Return, SIMU_STR_HLP_KEYS_ACTIVATE, SIMU_STR_HLP_ACT_ROT_DN);
addRadioWidget(ui->rightbuttons->addArea(polyArc(90, 100, 50), "X9E/right_enter.png", m_mouseMidClickAction));
addRadioWidget(ui->leftbuttons->addArea(QRect(10, 170, 30, 30), "X9E/left_scrnshot.png", m_screenshotAction));
+52 -52
View File
@@ -1,66 +1,66 @@
#ifndef SIMULATOR_STRINGS_H
#define SIMULATOR_STRINGS_H
#include <QtGlobal>
#include <QCoreApplication>
#define SIMU_STR_HLP_KEY_ENTER QT_TRANSLATE_NOOP("SimulatedUIWidget", "ENTER")
#define SIMU_STR_HLP_KEY_PGUP QT_TRANSLATE_NOOP("SimulatedUIWidget", "PG-UP")
#define SIMU_STR_HLP_KEY_PGDN QT_TRANSLATE_NOOP("SimulatedUIWidget", "PG-DN")
#define SIMU_STR_HLP_KEY_DEL QT_TRANSLATE_NOOP("SimulatedUIWidget", "DEL")
#define SIMU_STR_HLP_KEY_BKSP QT_TRANSLATE_NOOP("SimulatedUIWidget", "BKSP")
#define SIMU_STR_HLP_KEY_ESC QT_TRANSLATE_NOOP("SimulatedUIWidget", "ESC")
#define SIMU_STR_HLP_KEY_INS QT_TRANSLATE_NOOP("SimulatedUIWidget", "INS")
#define SIMU_STR_HLP_KEY_PLS QT_TRANSLATE_NOOP("SimulatedUIWidget", "<font size=+3>+</font>")
#define SIMU_STR_HLP_KEY_MIN QT_TRANSLATE_NOOP("SimulatedUIWidget", "<font size=+3>-</font>")
#define SIMU_STR_HLP_KEY_ENTER QCoreApplication::translate("SimulatedUIWidget", "ENTER")
#define SIMU_STR_HLP_KEY_PGUP QCoreApplication::translate("SimulatedUIWidget", "PG-UP")
#define SIMU_STR_HLP_KEY_PGDN QCoreApplication::translate("SimulatedUIWidget", "PG-DN")
#define SIMU_STR_HLP_KEY_DEL QCoreApplication::translate("SimulatedUIWidget", "DEL")
#define SIMU_STR_HLP_KEY_BKSP QCoreApplication::translate("SimulatedUIWidget", "BKSP")
#define SIMU_STR_HLP_KEY_ESC QCoreApplication::translate("SimulatedUIWidget", "ESC")
#define SIMU_STR_HLP_KEY_INS QCoreApplication::translate("SimulatedUIWidget", "INS")
#define SIMU_STR_HLP_KEY_PLS QCoreApplication::translate("SimulatedUIWidget", "<font size=+3>+</font>")
#define SIMU_STR_HLP_KEY_MIN QCoreApplication::translate("SimulatedUIWidget", "<font size=+3>-</font>")
#define SIMU_STR_HLP_KEY_LFT QT_TRANSLATE_NOOP("SimulatedUIWidget", "<font size=+3>&larr;</font>") // ←
#define SIMU_STR_HLP_KEY_RGT QT_TRANSLATE_NOOP("SimulatedUIWidget", "<font size=+3>&rarr;</font>") // →
#define SIMU_STR_HLP_KEY_UP QT_TRANSLATE_NOOP("SimulatedUIWidget", "<font size=+3>&uarr;</font>") // ↑
#define SIMU_STR_HLP_KEY_DN QT_TRANSLATE_NOOP("SimulatedUIWidget", "<font size=+3>&darr;</font>") // ↓
#define SIMU_STR_HLP_KEY_LFT QCoreApplication::translate("SimulatedUIWidget", "<font size=+3>&larr;</font>") // ←
#define SIMU_STR_HLP_KEY_RGT QCoreApplication::translate("SimulatedUIWidget", "<font size=+3>&rarr;</font>") // →
#define SIMU_STR_HLP_KEY_UP QCoreApplication::translate("SimulatedUIWidget", "<font size=+3>&uarr;</font>") // ↑
#define SIMU_STR_HLP_KEY_DN QCoreApplication::translate("SimulatedUIWidget", "<font size=+3>&darr;</font>") // ↓
#define SIMU_STR_HLP_ROTENC QT_TRANSLATE_NOOP("SimulatedUIWidget", "<font size=+3>&#x2686;</font>") // ⚆
#define SIMU_STR_HLP_ROTENC_LFT QT_TRANSLATE_NOOP("SimulatedUIWidget", "<font size=+3>&#x21b6;</font>") // ↶
#define SIMU_STR_HLP_ROTENC_RGT QT_TRANSLATE_NOOP("SimulatedUIWidget", "<font size=+3>&#x21b7;</font>") // ↷
#define SIMU_STR_HLP_ROTENC_LR QT_TRANSLATE_NOOP("SimulatedUIWidget", "<font size=+3>&#x21c6;</font>") // ⇆
#define SIMU_STR_HLP_ROTENC_DN QT_TRANSLATE_NOOP("SimulatedUIWidget", "<font size=+3>&#x21d3;</font>") // ⇓
#define SIMU_STR_HLP_ROTENC QCoreApplication::translate("SimulatedUIWidget", "<font size=+3>&#x2686;</font>") // ⚆
#define SIMU_STR_HLP_ROTENC_LFT QCoreApplication::translate("SimulatedUIWidget", "<font size=+3>&#x21b6;</font>") // ↶
#define SIMU_STR_HLP_ROTENC_RGT QCoreApplication::translate("SimulatedUIWidget", "<font size=+3>&#x21b7;</font>") // ↷
#define SIMU_STR_HLP_ROTENC_LR QCoreApplication::translate("SimulatedUIWidget", "<font size=+3>&#x21c6;</font>") // ⇆
#define SIMU_STR_HLP_ROTENC_DN QCoreApplication::translate("SimulatedUIWidget", "<font size=+3>&#x21d3;</font>") // ⇓
#define SIMU_STR_HLP_SCRL_UP QT_TRANSLATE_NOOP("SimulatedUIWidget", "<font size=+3>&#x21d1;</font>") // ⇑
#define SIMU_STR_HLP_SCRL_DN QT_TRANSLATE_NOOP("SimulatedUIWidget", "<font size=+3>&#x21d3;</font>") // ⇓
#define SIMU_STR_HLP_SCRL_UD QT_TRANSLATE_NOOP("SimulatedUIWidget", "<font size=+3>&#x21d5;</font>") // ⇕
#define SIMU_STR_HLP_SCRL_UP QCoreApplication::translate("SimulatedUIWidget", "<font size=+3>&#x21d1;</font>") // ⇑
#define SIMU_STR_HLP_SCRL_DN QCoreApplication::translate("SimulatedUIWidget", "<font size=+3>&#x21d3;</font>") // ⇓
#define SIMU_STR_HLP_SCRL_UD QCoreApplication::translate("SimulatedUIWidget", "<font size=+3>&#x21d5;</font>") // ⇕
#define SIMU_STR_HLP_MOUSE QT_TRANSLATE_NOOP("SimulatedUIWidget", "<img src='qrc:/images/simulator/icons/svg/mouse.svg' width=20 height=18 />")
#define SIMU_STR_HLP_CLICK QT_TRANSLATE_NOOP("SimulatedUIWidget", "<img src='qrc:/images/simulator/icons/svg/arrow_click.svg' width=18 height=18 />")
#define SIMU_STR_HLP_MOUSE_MID SIMU_STR_HLP_MOUSE SIMU_STR_HLP_CLICK
#define SIMU_STR_HLP_MOUSE_UP SIMU_STR_HLP_MOUSE SIMU_STR_HLP_SCRL_UP
#define SIMU_STR_HLP_MOUSE_DN SIMU_STR_HLP_MOUSE SIMU_STR_HLP_SCRL_DN
#define SIMU_STR_HLP_MOUSE_SCRL SIMU_STR_HLP_MOUSE SIMU_STR_HLP_SCRL_UD
#define SIMU_STR_HLP_MOUSE QCoreApplication::translate("SimulatedUIWidget", "<img src='qrc:/images/simulator/icons/svg/mouse.svg' width=20 height=18 />")
#define SIMU_STR_HLP_CLICK QCoreApplication::translate("SimulatedUIWidget", "<img src='qrc:/images/simulator/icons/svg/arrow_click.svg' width=18 height=18 />")
#define SIMU_STR_HLP_MOUSE_MID SIMU_STR_HLP_MOUSE % SIMU_STR_HLP_CLICK
#define SIMU_STR_HLP_MOUSE_UP SIMU_STR_HLP_MOUSE % SIMU_STR_HLP_SCRL_UP
#define SIMU_STR_HLP_MOUSE_DN SIMU_STR_HLP_MOUSE % SIMU_STR_HLP_SCRL_DN
#define SIMU_STR_HLP_MOUSE_SCRL SIMU_STR_HLP_MOUSE % SIMU_STR_HLP_SCRL_UD
#define SIMU_STR_HLP_ACT_MENU QT_TRANSLATE_NOOP("SimulatedUIWidget", "<pre>[ MENU ]</pre>")
#define SIMU_STR_HLP_ACT_PAGE QT_TRANSLATE_NOOP("SimulatedUIWidget", "<pre>[ PAGE ]</pre>")
#define SIMU_STR_HLP_ACT_EXIT QT_TRANSLATE_NOOP("SimulatedUIWidget", "<pre>[ EXIT ]</pre>")
#define SIMU_STR_HLP_ACT_ENT QT_TRANSLATE_NOOP("SimulatedUIWidget", "<pre>[ ENT ]</pre>")
#define SIMU_STR_HLP_ACT_UP QT_TRANSLATE_NOOP("SimulatedUIWidget", "<pre>[ UP ]</pre>")
#define SIMU_STR_HLP_ACT_DN QT_TRANSLATE_NOOP("SimulatedUIWidget", "<pre>[ DN ]</pre>")
#define SIMU_STR_HLP_ACT_PLS QT_TRANSLATE_NOOP("SimulatedUIWidget", "<pre>[ <font size=+2>+</font> ]</pre>")
#define SIMU_STR_HLP_ACT_MIN QT_TRANSLATE_NOOP("SimulatedUIWidget", "<pre>[ <font size=+2>-</font> ]</pre>")
#define SIMU_STR_HLP_ACT_PGUP QT_TRANSLATE_NOOP("SimulatedUIWidget", "<pre>[ PgUp ]</pre>")
#define SIMU_STR_HLP_ACT_PGDN QT_TRANSLATE_NOOP("SimulatedUIWidget", "<pre>[ PgDn ]</pre>")
#define SIMU_STR_HLP_ACT_MDL QT_TRANSLATE_NOOP("SimulatedUIWidget", "<pre>[ MDL ]</pre>")
#define SIMU_STR_HLP_ACT_RTN QT_TRANSLATE_NOOP("SimulatedUIWidget", "<pre>[ RTN ]</pre>")
#define SIMU_STR_HLP_ACT_SYS QT_TRANSLATE_NOOP("SimulatedUIWidget", "<pre>[ SYS ]</pre>")
#define SIMU_STR_HLP_ACT_TELE QT_TRANSLATE_NOOP("SimulatedUIWidget", "<pre>[ TELE ]</pre>")
#define SIMU_STR_HLP_ACT_MENU_ICN QT_TRANSLATE_NOOP("SimulatedUIWidget", "<font size=+3>&#x2261;</font>") // ≡
#define SIMU_STR_HLP_ACT_MENU QCoreApplication::translate("SimulatedUIWidget", "<pre>[ MENU ]</pre>")
#define SIMU_STR_HLP_ACT_PAGE QCoreApplication::translate("SimulatedUIWidget", "<pre>[ PAGE ]</pre>")
#define SIMU_STR_HLP_ACT_EXIT QCoreApplication::translate("SimulatedUIWidget", "<pre>[ EXIT ]</pre>")
#define SIMU_STR_HLP_ACT_ENT QCoreApplication::translate("SimulatedUIWidget", "<pre>[ ENT ]</pre>")
#define SIMU_STR_HLP_ACT_UP QCoreApplication::translate("SimulatedUIWidget", "<pre>[ UP ]</pre>")
#define SIMU_STR_HLP_ACT_DN QCoreApplication::translate("SimulatedUIWidget", "<pre>[ DN ]</pre>")
#define SIMU_STR_HLP_ACT_PLS QCoreApplication::translate("SimulatedUIWidget", "<pre>[ <font size=+2>+</font> ]</pre>")
#define SIMU_STR_HLP_ACT_MIN QCoreApplication::translate("SimulatedUIWidget", "<pre>[ <font size=+2>-</font> ]</pre>")
#define SIMU_STR_HLP_ACT_PGUP QCoreApplication::translate("SimulatedUIWidget", "<pre>[ PgUp ]</pre>")
#define SIMU_STR_HLP_ACT_PGDN QCoreApplication::translate("SimulatedUIWidget", "<pre>[ PgDn ]</pre>")
#define SIMU_STR_HLP_ACT_MDL QCoreApplication::translate("SimulatedUIWidget", "<pre>[ MDL ]</pre>")
#define SIMU_STR_HLP_ACT_RTN QCoreApplication::translate("SimulatedUIWidget", "<pre>[ RTN ]</pre>")
#define SIMU_STR_HLP_ACT_SYS QCoreApplication::translate("SimulatedUIWidget", "<pre>[ SYS ]</pre>")
#define SIMU_STR_HLP_ACT_TELE QCoreApplication::translate("SimulatedUIWidget", "<pre>[ TELE ]</pre>")
#define SIMU_STR_HLP_ACT_MENU_ICN QCoreApplication::translate("SimulatedUIWidget", "<font size=+3>&#x2261;</font>") // ≡
#define SIMU_STR_HLP_KEYS_EXIT SIMU_STR_HLP_KEY_DEL "|" SIMU_STR_HLP_KEY_BKSP "|" SIMU_STR_HLP_KEY_ESC
#define SIMU_STR_HLP_KEYS_ACTIVATE SIMU_STR_HLP_KEY_ENTER "|" SIMU_STR_HLP_MOUSE_MID
#define SIMU_STR_HLP_KEYS_GO_UP SIMU_STR_HLP_KEY_UP "|" SIMU_STR_HLP_KEY_PGUP
#define SIMU_STR_HLP_KEYS_GO_DN SIMU_STR_HLP_KEY_DN "|" SIMU_STR_HLP_KEY_PGDN
#define SIMU_STR_HLP_KEYS_GO_LFT SIMU_STR_HLP_KEY_LFT "|" SIMU_STR_HLP_KEY_MIN "|" SIMU_STR_HLP_MOUSE_UP
#define SIMU_STR_HLP_KEYS_GO_RGT SIMU_STR_HLP_KEY_RGT "|" SIMU_STR_HLP_KEY_PLS "|" SIMU_STR_HLP_MOUSE_DN
#define SIMU_STR_HLP_KEYS_EXIT SIMU_STR_HLP_KEY_DEL % "|" % SIMU_STR_HLP_KEY_BKSP % "|" % SIMU_STR_HLP_KEY_ESC
#define SIMU_STR_HLP_KEYS_ACTIVATE SIMU_STR_HLP_KEY_ENTER % "|" % SIMU_STR_HLP_MOUSE_MID
#define SIMU_STR_HLP_KEYS_GO_UP SIMU_STR_HLP_KEY_UP % "|" % SIMU_STR_HLP_KEY_PGUP
#define SIMU_STR_HLP_KEYS_GO_DN SIMU_STR_HLP_KEY_DN % "|" % SIMU_STR_HLP_KEY_PGDN
#define SIMU_STR_HLP_KEYS_GO_LFT SIMU_STR_HLP_KEY_LFT % "|" % SIMU_STR_HLP_KEY_MIN % "|" % SIMU_STR_HLP_MOUSE_UP
#define SIMU_STR_HLP_KEYS_GO_RGT SIMU_STR_HLP_KEY_RGT % "|" % SIMU_STR_HLP_KEY_PLS % "|" % SIMU_STR_HLP_MOUSE_DN
#define SIMU_STR_HLP_ACT_ROT_LFT SIMU_STR_HLP_ROTENC " " SIMU_STR_HLP_ROTENC_LFT
#define SIMU_STR_HLP_ACT_ROT_RGT SIMU_STR_HLP_ROTENC " " SIMU_STR_HLP_ROTENC_RGT
#define SIMU_STR_HLP_ACT_ROT_DN SIMU_STR_HLP_ROTENC " " SIMU_STR_HLP_ROTENC_DN
#define SIMU_STR_HLP_ACT_ROT_LFT SIMU_STR_HLP_ROTENC % " " % SIMU_STR_HLP_ROTENC_LFT
#define SIMU_STR_HLP_ACT_ROT_RGT SIMU_STR_HLP_ROTENC % " " % SIMU_STR_HLP_ROTENC_RGT
#define SIMU_STR_HLP_ACT_ROT_DN SIMU_STR_HLP_ROTENC % " " % SIMU_STR_HLP_ROTENC_DN
#endif // SIMULATOR_STRINGS_H
@@ -227,7 +227,7 @@ void SimulatorStartupDialog::onRadioTypeChanged(int index)
void SimulatorStartupDialog::onDataFileSelect(bool)
{
QString filter = tr(EEPROM_FILES_FILTER) + tr("All files (*.*)");
QString filter = EEPROM_FILES_FILTER % tr("All files (*.*)");
QString file = QFileDialog::getSaveFileName(this, QObject::tr("Select a data file"), ui->dataFile->text(),
filter, NULL, QFileDialog::DontConfirmOverwrite);
if (!file.isEmpty()) {
+71 -29
View File
@@ -557,9 +557,15 @@ void AppData::init()
{
qRegisterMetaTypeStreamOperators<SimulatorOptions>("SimulatorOptions");
firstUse = false;
upgradeFromVersion = "";
QSettings settings(COMPANY, PRODUCT);
if (!settings.contains("settings_version"))
importSettings(settings);
if (!settings.contains("settings_version")) {
if (!importSettings(settings))
firstUse = true;
}
convertSettings(settings);
// Initialize the profiles
for (int i=0; i<MAX_PROFILES; i++)
@@ -649,23 +655,69 @@ QMap<int, QString> AppData::getActiveProfiles()
return active;
}
void AppData::convertSettings(QSettings & settings)
{
// convert old settings to new
if (settings.contains("useWizard")) {
if (!settings.contains("newModelAction")) {
newModelAction(settings.value("useWizard").toBool() ? 1 : 2);
}
settings.remove("useWizard");
}
if (settings.contains("warningId") && settings.value("warningId").toInt() == 7) {
// meaning of warningId changed during v2.2 development but value of "7" indicates old setting, removing it will restore defaults
settings.remove("warningId");
}
}
bool AppData::importSettings(QSettings & toSettings)
{
QSettings * fromSettings = NULL;
QSettings settings21("OpenTX", "Companion 2.1");
QSettings settings20("OpenTX", "Companion 2.0");
QSettings settings16("OpenTX", "OpenTX Companion");
QSettings settings9x("companion9x", "companion9x");
if (settings21.contains("settings_version"))
if (settings21.contains("settings_version")) {
fromSettings = &settings21;
else if (settings20.contains("settings_version"))
fromSettings = &settings20;
else if (settings16.contains("settings_version"))
fromSettings = &settings16;
else if (settings9x.contains("default_mode"))
fromSettings = &settings9x;
upgradeFromVersion = "2.1";
}
else {
settings21.clear();
}
if (!fromSettings) {
QSettings settings20("OpenTX", "Companion 2.0");
if (settings20.contains("settings_version")) {
fromSettings = &settings20;
upgradeFromVersion = "2.0";
}
else {
settings20.clear();
}
}
if (!fromSettings) {
QSettings settings16("OpenTX", "OpenTX Companion");
if (settings16.contains("settings_version")) {
fromSettings = &settings16;
upgradeFromVersion = "1.x";
}
else {
settings16.clear();
}
}
if (!fromSettings) {
QSettings settings9x("companion9x", "companion9x");
if (settings9x.contains("default_mode")) {
fromSettings = &settings9x;
upgradeFromVersion = "Companion9X";
}
else {
settings9x.clear();
}
}
if (!fromSettings)
return false;
// do not copy these settings
QStringList excludeKeys = QStringList() << "compilation-server";
@@ -677,16 +729,14 @@ bool AppData::importSettings(QSettings & toSettings)
#endif
// import settings
if (fromSettings) {
foreach (const QString & key, fromSettings->allKeys()) {
if (fromSettings->value(key).isValid() && !excludeKeys.contains(key)) {
toSettings.setValue(key, fromSettings->value(key));
}
foreach (const QString & key, fromSettings->allKeys()) {
if (fromSettings->value(key).isValid() && !excludeKeys.contains(key)) {
toSettings.setValue(key, fromSettings->value(key));
}
}
// Additional adjustments for companion9x settings
if (fromSettings && fromSettings->applicationName() == "companion9x") {
if (fromSettings->applicationName() == "companion9x") {
// Store old values in new locations
autoCheckApp(toSettings.value("startup_check_companion9x", true).toBool());
toSettings.setValue("useWizard", toSettings.value("wizardEnable", true));
@@ -726,20 +776,12 @@ bool AppData::importSettings(QSettings & toSettings)
toSettings.remove("sdPath");
toSettings.remove("SplashFileName");
toSettings.remove("startup_check_companion9x");
toSettings.remove("warningId");
toSettings.remove("wizardEnable");
// Select the new default profile as current profile
id( 0 );
}
// convert old settings to new
if (toSettings.contains("useWizard")) {
if (!toSettings.contains("newModelAction")) {
newModelAction(toSettings.value("useWizard").toBool() ? 1 : 2);
}
toSettings.remove("useWizard");
}
return fromSettings ? true : false;
return true;
}
+5
View File
@@ -429,10 +429,15 @@ class AppData: protected CompStoreObj
void init();
QMap<int, QString> getActiveProfiles();
inline bool isFirstUse() const { return firstUse; }
inline QString previousVersion() const { return upgradeFromVersion; }
protected:
void convertSettings(QSettings & settings);
bool importSettings(QSettings & toSettings);
bool firstUse;
QString upgradeFromVersion;
};
extern AppData g;
+1
View File
@@ -89,6 +89,7 @@ bool CategorizedStorageFormat::load(RadioData & radioData)
radioData.models.resize(modelIndex + 1);
}
if (!loadModelFromByteArray(radioData.models[modelIndex], modelBuffer)) {
setError(QObject::tr("Error loading models"));
return false;
}
strncpy(radioData.models[modelIndex].filename, qPrintable(fileName), sizeof(radioData.models[modelIndex].filename));
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+27 -3
View File
@@ -20,9 +20,33 @@
#ifndef _WARNINGS_H_
#define _WARNINGS_H_
#define WARNING_LEVEL 0
#define WARNING_ID 7
#define WARNING QObject::tr("Thank you for upgrading to OpenTX 2.0. This is a major upgrade that adds and modifies a lot of things, so please make sure that you read release notes carefully to learn about the changes, and thoroughly check each of your models for proper function.\n\nThe OpenTX Team.")
#define CPN_STR_MSG_WELCOME QCoreApplication::translate("Companion", \
"<p><b>Welcome to OpenTX v%1.</b></p>" \
"<p>As the first step, please configure the initial Radio Profile by selecting your Radio Type, Menu Language, and Build Options.</p>" \
"<p>You may also want to take this time to review the other available options in the displayed Settings dialog.</p>" \
"<p>After saving your settings, we recommend you download the latest firmware for your radio by using the <i>File -&gt; Download</i> menu option.</p>" \
"<p>Please visit <a href='http://www.open-tx.org'>open-tx.org</a> for latest news, updates and documentation. Thank you for choosing OpenTX!</p>" \
"- The OpenTX Team.")
#define CPN_STR_MSG_UPGRADED QCoreApplication::translate("Companion", \
"<p><b>Thank you for upgrading to OpenTX v%1.</b></p>" \
"<p>This is a major upgrade that adds and modifies a lot of things, so please make sure that you read release notes carefully" \
" to learn about the changes, and thoroughly check each of your models for proper function.</p>" \
"<p>Please visit <a href='http://www.open-tx.org'>open-tx.org</a> for release notes and other documentation.</p>" \
"- The OpenTX Team.")
namespace AppMessages {
// These are used for saving "[don't] show this message again" user preferences.
enum MessageCodes {
MSG_NONE = 0,
MSG_WELCOME = 0x01,
MSG_UPGRADED = 0x02,
MSG_RESERVED = 0x04, // reserved due to legacy code
};
} // namespace AppWarnings
#endif // _WARNINGS_H_
@@ -1 +1 @@
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="df11", MODE:="0666";
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="df11", MODE:="0666"
@@ -208,6 +208,7 @@ Section "Uninstall"
Delete "$INSTDIR\Qt5Network.dll"
Delete "$INSTDIR\Qt5Multimedia.dll"
Delete "$INSTDIR\Qt5Xml.dll"
Delete "$INSTDIR\Qt5Svg.dll"
Delete "$INSTDIR\avrdude.exe"
Delete "$INSTDIR\avrdude.conf"
Delete "$INSTDIR\libusb0.dll"
@@ -220,7 +221,7 @@ Section "Uninstall"
Delete "$INSTDIR\platforms\*.*"
Delete "$INSTDIR\printsupport\*.*"
Delete "$INSTDIR\mediaservice\*.*"
Delete "$INSTDIR\mediaservice\imageformats\*.*"
Delete "$INSTDIR\imageformats\*.*"
RMDir "$INSTDIR\lang"
RMDir "$INSTDIR\phonon_backend"
+1 -1
View File
@@ -16,6 +16,6 @@ Homepage: http://www.open-tx.org/
Package: opentx-companion22
Architecture: any
Depends: ${shlibs:Depends}
Depends: ${shlibs:Depends}, libqt5multimedia5-plugins
Description: OpenTX Companion
Models and settings editor for the OpenTX open source firmware
+31 -1
View File
@@ -3,9 +3,30 @@ set -e
set -x
# $1 is distribution "trusty" OR "yakkety"
#
# Option "-n" or "--nightly" can be used to configure build script to produce a Companion with DALLOW_NIGHTLY_BUILDS=YES flag
cd `dirname ${0}`
nightly_build=0
while [ $# -gt 0 ]
do
case "$1" in
--nightly*)
nightly_build=1;;
-n*)
nightly_build=1;;
-*)
echo >&2 "usage: $0 [-n|--nightly] DISTRO"
exit 1;;
*)
break;; # terminate while loop
esac
shift
done
distro=${1%/}
@@ -32,10 +53,19 @@ cp ${distro}/* ../debian/
echo "Editing rules to set version suffix to \"${suffix}\""
sed -i "s/__VERSION_SUFFIX__/${suffix}/g" ../debian/rules
if [ ${nightly_build} -gt 0 ] ; then
echo "Setting nightly build flag"
sed -i "s/DALLOW_NIGHTLY_BUILDS=YES/DALLOW_NIGHTLY_BUILDS=YES/g" ../debian/rules
else
sed -i "s/DALLOW_NIGHTLY_BUILDS=YES/DALLOW_NIGHTLY_BUILDS=NO/g" ../debian/rules
fi
# remove old package and prepare new one
cd ..
rm -f ../opentx-companion22_*${distro}*
debuild -S -sa -I -Ijenkins -Ilaunchpad -Idoc -Ibuild -I*.luac
echo "Use this command to upload to launchpad:"
echo "Use this command to upload to launchpad (nightly builds):"
echo " dput ppa:opentx-test/ppa opentx-companion22_<version>.changes"
echo "OR releases:"
echo " dput ppa:opentx-test/rel opentx-companion22_<version>.changes"
+6
View File
@@ -1,3 +1,9 @@
opentx-companion22 (2.2.0~N371~trusty) trusty; urgency=low
* New release 2.2.0~N371 RC18
-- projectkk2glider <projectkk2glider@gmail.com> Sat, 29 Apr 2017 18:57:42 +0200
opentx-companion22 (2.2.0~N370~trusty) trusty; urgency=low
* New release 2.2.0~N370 RC17
+6
View File
@@ -1,3 +1,9 @@
opentx-companion22 (2.2.0~N371~xenial) xenial; urgency=low
* New release 2.2.0~N371 RC18
-- projectkk2glider <projectkk2glider@gmail.com> Sat, 29 Apr 2017 18:57:37 +0200
opentx-companion22 (2.2.0~N370~xenial) xenial; urgency=low
* New release 2.2.0~N370 RC17
+6
View File
@@ -1,3 +1,9 @@
opentx-companion22 (2.2.0~N371~yakkety) yakkety; urgency=low
* New release 2.2.0~N371 RC18
-- projectkk2glider <projectkk2glider@gmail.com> Sat, 29 Apr 2017 18:57:47 +0200
opentx-companion22 (2.2.0~N370~yakkety) yakkety; urgency=low
* New release 2.2.0~N370 RC17
-44
View File
@@ -16,16 +16,13 @@ local fields = {}
local modifications = {}
local wingBitmaps = {}
local mountBitmaps = {}
local calibBitmaps = {}
local configFields = {
{"Wing type:", COMBO, 0x80, nil, { "Normal", "Delta", "VTail" } },
{"Mounting type:", COMBO, 0x81, nil, { "Horz", "Horz rev.", "Vert", "Vert rev." } },
}
local calibrationPositions = { "up", "down", "left", "right", "forward", "back" }
local wingBitmapsFile = {"img/plane_b.png", "img/delta_b.png", "img/planev_b.png"}
local mountBitmapsFile = {"img/up.png", "img/down.png", "img/vert.png", "img/vert-r.png"}
local calibBitmapsFile = {"img/up.png", "img/down.png", "img/left.png", "img/right.png", "img/forward.png", "img/back.png"}
local settingsFields = {
{"S6R functions:", COMBO, 0x9C, nil, { "Disable", "Enable" } },
@@ -269,53 +266,12 @@ local function runSettingsPage(event)
return runFieldsPage(event)
end
local function runCalibrationPage(event)
fields = calibrationFields
if refreshIndex == #fields then
refreshIndex = 0
end
lcd.clear()
drawScreenTitle("S6R", page, #pages)
if(calibrationStep < 6) then
local position = calibrationPositions[1 + calibrationStep]
lcd.drawText(100, 50, "Place the S6R in the following position", TEXT_COLOR)
if calibBitmaps[calibrationStep + 1] == nil then
calibBitmaps[calibrationStep + 1] = Bitmap.open(calibBitmapsFile[calibrationStep + 1])
end
lcd.drawBitmap(calibBitmaps[calibrationStep + 1], 200, 70)
for index = 1, 3, 1 do
local field = fields[index]
lcd.drawText(70, 80+20*index, field[1]..":", TEXT_COLOR)
lcd.drawNumber(90, 80+20*index, field[4]/10, LEFT+PREC2)
end
local attr = calibrationState == 0 and INVERS or 0
lcd.drawText(160, 220, "Press [Enter] when ready", attr)
else
lcd.drawText(160, 50, "Calibration completed", 0)
lcd.drawBitmap(Bitmap.open("img/done.bmp"),200, 100)
lcd.drawText(160, 220, "Press [RTN] when ready", attr)
end
if calibrationStep > 6 and (event == EVT_ENTER_BREAK or event == EVT_EXIT_BREAK) then
return 2
elseif event == EVT_ENTER_BREAK then
calibrationState = 1
elseif event == EVT_EXIT_BREAK then
if calibrationStep > 0 then
calibrationStep = 0
end
end
return 0
end
-- Init
local function init()
current, edit, refreshState, refreshIndex = 1, false, 0, 0
pages = {
runConfigPage,
runSettingsPage,
runCalibrationPage
}
end
+340
View File
@@ -0,0 +1,340 @@
local VALUE = 0
local COMBO = 1
local COLUMN_2 = 300
local edit = false
local page = 1
local current = 1
local refreshState = 0
local refreshIndex = 0
local calibrationState = 0
local pageOffset = 0
local calibrationStep = 0
local pages = {}
local fields = {}
local modifications = {}
local wingBitmaps = {}
local mountBitmaps = {}
local calibBitmaps = {}
local configFields = {
{"Wing type:", COMBO, 0x80, nil, { "Normal", "Delta", "VTail" } },
{"Mounting type:", COMBO, 0x81, nil, { "Horz", "Horz rev.", "Vert", "Vert rev." } },
}
local calibrationPositions = { "up", "down", "left", "right", "forward", "back" }
local wingBitmapsFile = {"img/plane_b.png", "img/delta_b.png", "img/planev_b.png"}
local mountBitmapsFile = {"img/up.png", "img/down.png", "img/vert.png", "img/vert-r.png"}
local calibBitmapsFile = {"img/up.png", "img/down.png", "img/left.png", "img/right.png", "img/forward.png", "img/back.png"}
local settingsFields = {
{"S6R functions:", COMBO, 0x9C, nil, { "Disable", "Enable" } },
{"CH5 mode:", COMBO, 0xA8, nil, { "AIL2", "AUX1" } },
{"CH6 mode:", COMBO, 0xA9, nil, { "ELE2", "AUX2" } },
{"AIL direction:", COMBO, 0x82, nil, { "Normal", "Invers" }, { 255, 0 } },
{"ELE direction:", COMBO, 0x83, nil, { "Normal", "Invers" }, { 255, 0 } },
{"RUD direction:", COMBO, 0x84, nil, { "Normal", "Invers" }, { 255, 0 } },
{"AIL2 direction:", COMBO, 0x9A, nil, { "Normal", "Invers" }, { 255, 0 } },
{"ELE2 direction:", COMBO, 0x9B, nil, { "Normal", "Invers" }, { 255, 0 } },
{"AIL stabilize gain:", VALUE, 0x85, nil, 0, 200, "%"},
{"ELE stabilize gain:", VALUE, 0x86, nil, 0, 200, "%"},
{"RUD stabilize gain:", VALUE, 0x87, nil, 0, 200, "%"},
{"AIL auto level gain:", VALUE, 0x88, nil, 0, 200, "%"},
{"ELE auto level gain:", VALUE, 0x89, nil, 0, 200, "%"},
{"ELE upright gain:", VALUE, 0x8C, nil, 0, 200, "%"},
{"RUD upright gain:", VALUE, 0x8D, nil, 0, 200, "%"},
{"AIL crab gain:", VALUE, 0x8E, nil, 0, 200, "%"},
{"RUD crab gain:", VALUE, 0x90, nil, 0, 200, "%"},
{"AIL auto angle offset:", VALUE, 0x91, nil, -20, 20, "%", 0x6C},
{"ELE auto angle offset:", VALUE, 0x92, nil, -20, 20, "%", 0x6C},
{"ELE upright angle offset:", VALUE, 0x95, nil, -20, 20, "%", 0x6C},
{"RUD upright angle offset:", VALUE, 0x96, nil, -20, 20, "%", 0x6C},
{"AIL crab angle offset:", VALUE, 0x97, nil, -20, 20, "%", 0x6C},
{"RUD crab angle offset:", VALUE, 0x99, nil, -20, 20, "%", 0x6C},
}
local calibrationFields = {
{"X:", VALUE, 0x9E, 0, -100, 100, "%"},
{"Y:", VALUE, 0x9F, 0, -100, 100, "%"},
{"Z:", VALUE, 0xA0, 0, -100, 100, "%"}
}
local function drawScreenTitle(title,page, pages)
lcd.drawFilledRectangle(0, 0, LCD_W, 30, TITLE_BGCOLOR)
lcd.drawText(1, 5, title, MENU_TITLE_COLOR)
lcd.drawText(LCD_W-40, 5, page.."/"..pages, MENU_TITLE_COLOR)
end
-- Change display attribute to current field
local function addField(step)
local field = fields[current]
local min, max
if field[2] == VALUE then
min = field[5]
max = field[6]
elseif field[2] == COMBO then
min = 0
max = #(field[5]) - 1
end
if (step < 0 and field[4] > min) or (step > 0 and field[4] < max) then
field[4] = field[4] + step
end
end
-- Select the next or previous page
local function selectPage(step)
page = 1 + ((page + step - 1 + #pages) % #pages)
refreshIndex = 0
calibrationStep = 0
pageOffset = 0
end
-- Select the next or previous editable field
local function selectField(step)
current = 1 + ((current + step - 1 + #fields) % #fields)
if current > 7 + pageOffset then
pageOffset = current - 7
elseif current <= pageOffset then
pageOffset = current - 1
end
end
local function drawProgressBar()
local width = (300 * refreshIndex) / #fields
lcd.drawRectangle(100, 10, 300, 6)
lcd.drawFilledRectangle(102, 13, width, 2);
end
-- Redraw the current page
local function redrawFieldsPage(event)
lcd.clear()
drawScreenTitle("S6R", page, #pages)
if refreshIndex < #fields then
drawProgressBar()
end
for index = 1, 10, 1 do
local field = fields[pageOffset+index]
if field == nil then
break
end
local attr = current == (pageOffset+index) and ((edit == true and BLINK or 0) + INVERS) or 0
attr = attr + TEXT_COLOR
lcd.drawText(1, 30+20*index, field[1], TEXT_COLOR)
if field[4] == nil then
lcd.drawText(COLUMN_2, 30+20*index, "---", attr)
else
if field[2] == VALUE then
lcd.drawNumber(COLUMN_2, 30+20*index, field[4], LEFT + attr)
elseif field[2] == COMBO then
if field[4] >= 0 and field[4] < #(field[5]) then
lcd.drawText(COLUMN_2, 30+20*index, field[5][1+field[4]], attr)
end
end
end
end
end
local function telemetryRead(field)
return sportTelemetryPush(0x17, 0x30, 0x0C30, field)
end
local function telemetryWrite(field, value)
return sportTelemetryPush(0x17, 0x31, 0x0C30, field + value*256)
end
local telemetryPopTimeout = 0
local function refreshNext()
if refreshState == 0 then
if calibrationState == 1 then
if telemetryWrite(0x9D, calibrationStep) == true then
refreshState = 1
calibrationState = 2
telemetryPopTimeout = getTime() + 80 -- normal delay is 500ms
end
elseif #modifications > 0 then
telemetryWrite(modifications[1][1], modifications[1][2])
modifications[1] = nil
elseif refreshIndex < #fields then
local field = fields[refreshIndex + 1]
if telemetryRead(field[3]) == true then
refreshState = 1
telemetryPopTimeout = getTime() + 80 -- normal delay is 500ms
end
end
elseif refreshState == 1 then
local physicalId, primId, dataId, value = sportTelemetryPop()
if physicalId == 0x1A and primId == 0x32 and dataId == 0x0C30 then
local fieldId = value % 256
if calibrationState == 2 then
if fieldId == 0x9D then
refreshState = 0
calibrationState = 0
calibrationStep = (calibrationStep + 1) % 7
end
else
local field = fields[refreshIndex + 1]
if fieldId == field[3] then
local value = math.floor(value / 256)
if field[3] >= 0x9E and field[3] <= 0xA0 then
local b1 = value % 256
local b2 = math.floor(value / 256)
value = b1*256 + b2
value = value - bit32.band(value, 0x8000) * 2
end
if field[2] == COMBO and #field == 6 then
for index = 1, #(field[6]), 1 do
if value == field[6][index] then
value = index - 1
break
end
end
elseif field[2] == VALUE and #field == 8 then
value = value - field[8] + field[5]
end
fields[refreshIndex + 1][4] = value
refreshIndex = refreshIndex + 1
refreshState = 0
end
end
elseif getTime() > telemetryPopTimeout then
refreshState = 0
calibrationState = 0
end
end
end
local function updateField(field)
local value = field[4]
if field[2] == COMBO and #field == 6 then
value = field[6][1+value]
elseif field[2] == VALUE and #field == 8 then
value = value + field[8] - field[5]
end
modifications[#modifications+1] = { field[3], value }
end
-- Main
local function runFieldsPage(event)
if event == EVT_EXIT_BREAK then -- exit script
return 2
elseif event == EVT_ENTER_BREAK or event == EVT_ROT_BREAK then -- toggle editing/selecting current field
if fields[current][4] ~= nil then
edit = not edit
if edit == false then
updateField(fields[current])
end
end
elseif edit then
if event == EVT_PLUS_FIRST or event == EVT_ROT_RIGHT or event == EVT_PLUS_REPT then
addField(1)
elseif event == EVT_MINUS_FIRST or event == EVT_ROT_LEFT or event == EVT_MINUS_REPT then
addField(-1)
end
else
if event == EVT_MINUS_FIRST or event == EVT_ROT_RIGHT then
selectField(1)
elseif event == EVT_PLUS_FIRST or event == EVT_ROT_LEFT then
selectField(-1)
end
end
redrawFieldsPage(event)
return 0
end
local function runConfigPage(event)
fields = configFields
local result = runFieldsPage(event)
if fields[1][4] ~= nil then
if wingBitmaps[1 + fields[1][4]] == nil then
wingBitmaps[1 + fields[1][4]] = Bitmap.open(wingBitmapsFile[1 + fields[1][4]])
end
lcd.drawBitmap(wingBitmaps[1 + fields[1][4]], 10, 90)
end
if fields[2][4] ~= nil then
if mountBitmaps[1 + fields[2][4]] == nil then
mountBitmaps[1 + fields[2][4]] = Bitmap.open(mountBitmapsFile[1 + fields[2][4]])
end
lcd.drawBitmap(mountBitmaps[1 + fields[2][4]], 190, 110)
end
return result
end
local function runSettingsPage(event)
fields = settingsFields
return runFieldsPage(event)
end
local function runCalibrationPage(event)
fields = calibrationFields
if refreshIndex == #fields then
refreshIndex = 0
end
lcd.clear()
drawScreenTitle("S6R", page, #pages)
if(calibrationStep < 6) then
local position = calibrationPositions[1 + calibrationStep]
lcd.drawText(100, 50, "Place the S6R in the following position", TEXT_COLOR)
if calibBitmaps[calibrationStep + 1] == nil then
calibBitmaps[calibrationStep + 1] = Bitmap.open(calibBitmapsFile[calibrationStep + 1])
end
lcd.drawBitmap(calibBitmaps[calibrationStep + 1], 200, 70)
for index = 1, 3, 1 do
local field = fields[index]
lcd.drawText(70, 80+20*index, field[1]..":", TEXT_COLOR)
lcd.drawNumber(90, 80+20*index, field[4]/10, LEFT+PREC2)
end
local attr = calibrationState == 0 and INVERS or 0
lcd.drawText(160, 220, "Press [Enter] when ready", attr)
else
lcd.drawText(160, 50, "Calibration completed", 0)
lcd.drawBitmap(Bitmap.open("img/done.bmp"),200, 100)
lcd.drawText(160, 220, "Press [RTN] when ready", attr)
end
if calibrationStep > 6 and (event == EVT_ENTER_BREAK or event == EVT_EXIT_BREAK) then
return 2
elseif event == EVT_ENTER_BREAK then
calibrationState = 1
elseif event == EVT_EXIT_BREAK then
if calibrationStep > 0 then
calibrationStep = 0
end
end
return 0
end
-- Init
local function init()
current, edit, refreshState, refreshIndex = 1, false, 0, 0
pages = {
-- runConfigPage,
-- runSettingsPage,
runCalibrationPage
}
end
-- Main
local function run(event)
if event == nil then
error("Cannot be run as a model script!")
return 2
elseif event == EVT_PAGE_BREAK or event == EVT_PAGEDN_FIRST then
selectPage(1)
elseif event == EVT_PAGE_LONG or event == EVT_PAGEUP_FIRST then
killEvents(event);
selectPage(-1)
end
local result = pages[page](event)
refreshNext()
return result
end
return { init=init, run=run }
@@ -0,0 +1,283 @@
local VALUE = 0
local COMBO = 1
local COLUMN_2 = 150
local edit = false
local page = 1
local current = 1
local refreshState = 0
local refreshIndex = 0
local calibrationState = 0
local pageOffset = 0
local calibrationStep = 0
local pages = {}
local fields = {}
local modifications = {}
local positionConfirmed = 0
local orientationAutoSense = 0
local calibrationFields = {
{"X:", VALUE, 0x9E, 0, -100, 100, "%"},
{"Y:", VALUE, 0x9F, 0, -100, 100, "%"},
{"Z:", VALUE, 0xA0, 0, -100, 100, "%"}
}
local function drawProgressBar()
local width = (140 * refreshIndex) / #fields
lcd.drawRectangle(30, 1, 144, 6)
lcd.drawFilledRectangle(32, 3, width, 2);
end
-- Select the next or previous page
local function selectPage(step)
page = 1 + ((page + step - 1 + #pages) % #pages)
refreshIndex = 0
calibrationStep = 0
pageOffset = 0
end
-- Draw initial warning page
local function runWarningPage(event)
lcd.clear()
lcd.drawScreenTitle("S6R Calibration", page, #pages)
lcd.drawText(0, 10, "You only need to calibrate", SMLSIZE)
lcd.drawText(0, 20, "once. You will need the S6R,", SMLSIZE)
lcd.drawText(0, 30, "power, and a level surface.", SMLSIZE)
lcd.drawText(0, 40, "Press [Enter] when ready", SMLSIZE)
lcd.drawText(0, 50, "Press [Exit] to cancel", SMLSIZE)
if event == EVT_ENTER_BREAK then
selectPage(1)
return 0
elseif event == EVT_EXIT_BREAK then
return 2
end
return 0
end
-- Redraw the current page
local function redrawFieldsPage()
lcd.clear()
lcd.drawScreenTitle("S6R Calibration", page, #pages)
if refreshIndex < #fields then
drawProgressBar()
end
for index = 1, 7, 1 do
local field = fields[pageOffset+index]
if field == nil then
break
end
local attr = current == (pageOffset+index) and ((edit == true and BLINK or 0) + INVERS) or 0
lcd.drawText(0, 1+8*index, field[1])
if field[4] == nil then
lcd.drawText(COLUMN_2, 1+8*index, "---", attr)
else
if field[2] == VALUE then
lcd.drawNumber(COLUMN_2, 1+8*index, field[4], LEFT + attr)
elseif field[2] == COMBO then
if field[4] >= 0 and field[4] < #(field[5]) then
lcd.drawText(COLUMN_2, 1+8*index, field[5][1+field[4]], attr)
end
end
end
end
end
local function telemetryRead(field)
return sportTelemetryPush(0x17, 0x30, 0x0C30, field)
end
local function telemetryWrite(field, value)
return sportTelemetryPush(0x17, 0x31, 0x0C30, field + value*256)
end
local telemetryPopTimeout = 0
local function refreshNext()
if refreshState == 0 then
if calibrationState == 1 then
if telemetryWrite(0x9D, calibrationStep) == true then
refreshState = 1
calibrationState = 2
telemetryPopTimeout = getTime() + 80 -- normal delay is 500ms
end
elseif #modifications > 0 then
telemetryWrite(modifications[1][1], modifications[1][2])
modifications[1] = nil
elseif refreshIndex < #fields then
local field = fields[refreshIndex + 1]
if telemetryRead(field[3]) == true then
refreshState = 1
telemetryPopTimeout = getTime() + 80 -- normal delay is 500ms
end
end
elseif refreshState == 1 then
local physicalId, primId, dataId, value = sportTelemetryPop()
if physicalId == 0x1A and primId == 0x32 and dataId == 0x0C30 then
local fieldId = value % 256
if calibrationState == 2 then
if fieldId == 0x9D then
refreshState = 0
calibrationState = 0
calibrationStep = (calibrationStep + 1) % 7
end
else
local field = fields[refreshIndex + 1]
if fieldId == field[3] then
local value = math.floor(value / 256)
if field[3] >= 0x9E and field[3] <= 0xA0 then
local b1 = value % 256
local b2 = math.floor(value / 256)
value = b1*256 + b2
value = value - bit32.band(value, 0x8000) * 2
end
if field[2] == COMBO and #field == 6 then
for index = 1, #(field[6]), 1 do
if value == field[6][index] then
value = index - 1
break
end
end
elseif field[2] == VALUE and #field == 8 then
value = value - field[8] + field[5]
end
fields[refreshIndex + 1][4] = value
refreshIndex = refreshIndex + 1
refreshState = 0
end
end
elseif getTime() > telemetryPopTimeout then
refreshState = 0
calibrationState = 0
end
end
end
local function updateField(field)
local value = field[4]
if field[2] == COMBO and #field == 6 then
value = field[6][1+value]
elseif field[2] == VALUE and #field == 8 then
value = value + field[8] - field[5]
end
modifications[#modifications+1] = { field[3], value }
end
-- Main
local function runFieldsPage(event)
if event == EVT_EXIT_BREAK then -- exit script
return 2
elseif event == EVT_ENTER_BREAK then -- toggle editing/selecting current field
if fields[current][4] ~= nil then
edit = not edit
if edit == false then
updateField(fields[current])
end
end
elseif edit then
if event == EVT_PLUS_FIRST or event == EVT_ROT_RIGHT or event == EVT_PLUS_REPT then
addField(1)
elseif event == EVT_MINUS_FIRST or event == EVT_ROT_LEFT or event == EVT_MINUS_REPT then
addField(-1)
end
else
if event == EVT_MINUS_FIRST or event == EVT_ROT_LEFT then
selectField(1)
elseif event == EVT_PLUS_FIRST or event == EVT_ROT_RIGHT then
selectField(-1)
end
end
redrawFieldsPage()
return 0
end
local function drawCalibrationOrientation(x, y, step)
local orientation = { {"Label up.", "", 0, 0, 1000, 0, 0, 1000},
{"Label down.", "", 0, 0, -1000, 0, 0, -1000},
{"Pins Up.", "", -1000, 0, 0, 1000, 0, 0},
{"Pins Down.", "", 1000, 0, 0, -1000, 0, 0},
{"Label facing you", "Pins Right", 0, 1000, 0, 0, -1000, 0},
{"Label facing you", "Pins Left", 0, -1000 , 0, 0, 1000, 0} }
lcd.drawText(0, 9, "Place the S6R as follows:", 0)
lcd.drawText(x-9, y, orientation[step][1])
lcd.drawText(x-9, y+10, orientation[step][2])
local positionStatus = 0
for index = 1, 3, 1 do
local field = fields[index]
lcd.drawText(90, 12+10*index, field[1], 0)
if math.abs(field[4] - orientation[step][2+index+orientationAutoSense]) < 200 then
lcd.drawNumber(100, 12+10*index, field[4]/10, LEFT+PREC2)
positionStatus = positionStatus + 1
else
lcd.drawNumber(100, 12+10*index, field[4]/10, LEFT+PREC2+INVERS)
end
end
if step == 3 and positionStatus == 2 then -- orientation auto sensing
orientationAutoSense = 3 - orientationAutoSense
end
if positionStatus == 3 then
lcd.drawText(0, 56, " [Enter] to validate ", INVERS)
positionConfirmed = 1
end
end
local function runCalibrationPage(event)
fields = calibrationFields
if refreshIndex == #fields then
refreshIndex = 0
end
lcd.clear()
lcd.drawScreenTitle("S6R Calibration", page, #pages)
if(calibrationStep < 6) then
drawCalibrationOrientation(10, 24, 1 + calibrationStep)
local attr = calibrationState == 0 and INVERS or 0
--lcd.drawText(0, 56, "[Enter] to validate", attr)
else
lcd.drawText(0, 19, "Calibration completed", 0)
-- lcd.drawText(10, 19, "Done",0)
lcd.drawText(0, 56, "Press [Exit] when ready", attr)
end
if calibrationStep > 6 and (event == EVT_ENTER_BREAK or event == EVT_EXIT_BREAK) then
return 2
elseif event == EVT_ENTER_BREAK and positionConfirmed then
calibrationState = 1
positionConfirmed = 0
end
return 0
end
-- Init
local function init()
current, edit, refreshState, refreshIndex = 1, false, 0, 0
pages = {
runWarningPage,
runCalibrationPage
}
end
-- Main
local function run(event)
if event == nil then
error("Cannot be run as a model script!")
return 2
elseif event == EVT_PAGE_BREAK then
selectPage(1)
elseif event == EVT_PAGE_LONG then
killEvents(event);
selectPage(-1)
end
local result = pages[page](event)
refreshNext()
return result
end
return { init=init, run=run }
+16 -1
View File
@@ -26,6 +26,7 @@ uint8_t s_curveChan;
int8_t * curveEnd[MAX_CURVES];
void loadCurves()
{
bool showWarning= false;
int8_t * tmp = g_model.points;
for (int i=0; i<MAX_CURVES; i++) {
switch (g_model.curves[i].type) {
@@ -41,7 +42,21 @@ void loadCurves()
tmp += 5+g_model.curves[i].points;
break;
}
// Older version did not check if we exceeded the array
int8_t * maxend = &g_model.points[MAX_CURVE_POINTS - 2*(MAX_CURVES-i-1)];
if (tmp > maxend) {
tmp = maxend;
g_model.curves[i].type=CURVE_TYPE_STANDARD;
g_model.curves[i].points=-3;
showWarning=true;
}
curveEnd[i] = tmp;
}
if (showWarning) {
POPUP_WARNING("Invalid curve data repaired");
const char * w = "check your curves, logic switches";
SET_WARNING_INFO(w, strlen(w), 0);
}
}
@@ -50,7 +65,7 @@ int8_t * curveAddress(uint8_t idx)
return idx==0 ? g_model.points : curveEnd[idx-1];
}
bool moveCurve(uint8_t index, int8_t shift) // TODO bool?
bool moveCurve(uint8_t index, int8_t shift)
{
if (curveEnd[MAX_CURVES-1] + shift > g_model.points + sizeof(g_model.points)) {
AUDIO_WARNING2();
+1 -1
View File
@@ -168,7 +168,7 @@ enum CurveType {
#define LEN_INPUT_NAME 3
#define LEN_CURVE_NAME 3
#define LEN_FUNCTION_NAME 6
#define MAX_CURVES 16
#define MAX_CURVES 16 // TODO next EEPROM check if can be changed to 32 to have all ARM the same
#define MAX_CURVE_POINTS 512
#elif defined(PCBTARANIS)
#define LEN_MODEL_NAME 12
+1 -1
View File
@@ -367,7 +367,7 @@ PACK(struct FlightModeData {
PACK(struct CurveData {
uint8_t type:1;
uint8_t smooth:1;
int8_t points:6; // TODO conversion
int8_t points:6; // describes number of points - 5
NOBACKUP(char name[LEN_CURVE_NAME]);
});
#else
+15 -13
View File
@@ -87,11 +87,12 @@ void menuModelCurveOne(event_t event)
for (int i = 1; i < 4 + crv.points; i++) {
points[i] = calcRESXto100(applyCustomCurve(calc100toRESX(getCurveX(5 + crv.points, i)), s_curveChan));
}
moveCurve(s_curveChan, checkIncDec_Ret > 0 ? 3 + crv.points : -3 - crv.points);
if (newType == CURVE_TYPE_CUSTOM) {
resetCustomCurveX(points, 5 + crv.points);
if (moveCurve(s_curveChan, checkIncDec_Ret > 0 ? 3 + crv.points : -3 - crv.points)) {
if (newType == CURVE_TYPE_CUSTOM) {
resetCustomCurveX(points, 5 + crv.points);
}
crv.type = newType;
}
crv.type = newType;
}
}
@@ -105,16 +106,17 @@ void menuModelCurveOne(event_t event)
if (checkIncDec_Ret) {
int8_t newPoints[MAX_POINTS_PER_CURVE];
newPoints[0] = points[0];
newPoints[4+count] = points[4+crv.points];
for (int i=1; i<4+count; i++)
newPoints[i] = calcRESXto100(applyCustomCurve(calc100toRESX(getCurveX(5+count, i)), s_curveChan));
moveCurve(s_curveChan, checkIncDec_Ret*(crv.type==CURVE_TYPE_CUSTOM?2:1));
for (int i=0; i<5+count; i++) {
points[i] = newPoints[i];
if (crv.type == CURVE_TYPE_CUSTOM && i!=0 && i!=4+count)
points[5+count+i-1] = getCurveX(5+count, i);
newPoints[4 + count] = points[4 + crv.points];
for (int i = 1; i < 4 + count; i++)
newPoints[i] = calcRESXto100(applyCustomCurve(calc100toRESX(getCurveX(5 + count, i)), s_curveChan));
if (moveCurve(s_curveChan, checkIncDec_Ret * (crv.type == CURVE_TYPE_CUSTOM ? 2 : 1))) {
for (int i = 0; i < 5 + count; i++) {
points[i] = newPoints[i];
if (crv.type == CURVE_TYPE_CUSTOM && i != 0 && i != 4 + count)
points[5 + count + i - 1] = getCurveX(5 + count, i);
}
crv.points = count;
}
crv.points = count;
}
}
@@ -366,8 +366,10 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
else if (func == FUNC_VOLUME) {
val_max = MIXSRC_LAST_CH;
drawSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr);
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable);
if (active) {
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable);
}
}
#elif defined(VOICE)
else if (func == FUNC_PLAY_TRACK) {
@@ -421,8 +423,10 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
case FUNC_ADJUST_GVAR_SOURCE:
val_max = MIXSRC_LAST_CH;
drawSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr);
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable);
if (active) {
INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE);
INCDEC_ENABLE_CHECK(isSourceAvailable);
}
break;
case FUNC_ADJUST_GVAR_GVAR:
val_max = MAX_GVARS-1;
+15 -13
View File
@@ -91,11 +91,12 @@ void menuModelCurveOne(event_t event)
for (int i = 1; i < 4 + crv.points; i++) {
points[i] = calcRESXto100(applyCustomCurve(calc100toRESX(getCurveX(5 + crv.points, i)), s_curveChan));
}
moveCurve(s_curveChan, checkIncDec_Ret > 0 ? 3 + crv.points : -3 - crv.points);
if (newType == CURVE_TYPE_CUSTOM) {
resetCustomCurveX(points, 5 + crv.points);
if (moveCurve(s_curveChan, checkIncDec_Ret > 0 ? 3 + crv.points : -3 - crv.points)) {
if (newType == CURVE_TYPE_CUSTOM) {
resetCustomCurveX(points, 5 + crv.points);
}
crv.type = newType;
}
crv.type = newType;
}
}
@@ -109,16 +110,17 @@ void menuModelCurveOne(event_t event)
if (checkIncDec_Ret) {
int8_t newPoints[MAX_POINTS_PER_CURVE];
newPoints[0] = points[0];
newPoints[4+count] = points[4+crv.points];
for (int i=1; i<4+count; i++)
newPoints[i] = calcRESXto100(applyCustomCurve(calc100toRESX(getCurveX(5+count, i)), s_curveChan));
moveCurve(s_curveChan, checkIncDec_Ret*(crv.type==CURVE_TYPE_CUSTOM?2:1));
for (int i=0; i<5+count; i++) {
points[i] = newPoints[i];
if (crv.type == CURVE_TYPE_CUSTOM && i!=0 && i!=4+count)
points[5+count+i-1] = getCurveX(5+count, i);
newPoints[4 + count] = points[4 + crv.points];
for (int i = 1; i < 4 + count; i++)
newPoints[i] = calcRESXto100(applyCustomCurve(calc100toRESX(getCurveX(5 + count, i)), s_curveChan));
if (moveCurve(s_curveChan, checkIncDec_Ret * (crv.type == CURVE_TYPE_CUSTOM ? 2 : 1))) {
for (int i = 0; i < 5 + count; i++) {
points[i] = newPoints[i];
if (crv.type == CURVE_TYPE_CUSTOM && i != 0 && i != 4 + count)
points[5 + count + i - 1] = getCurveX(5 + count, i);
}
crv.points = count;
}
crv.points = count;
}
}
+13 -11
View File
@@ -117,14 +117,15 @@ bool menuModelCurveOne(event_t event)
if (attr) {
uint8_t newType = checkIncDecModelZero(event, crv.type, CURVE_TYPE_LAST);
if (newType != crv.type) {
for (int i=1; i<4+crv.points; i++) {
for (int i = 1; i < 4 + crv.points; i++) {
points[i] = calcRESXto100(applyCustomCurve(calc100toRESX(-100 + i * 200 / (4 + crv.points)), s_curveChan));
}
moveCurve(s_curveChan, checkIncDec_Ret > 0 ? 3+crv.points : -3-crv.points);
if (newType == CURVE_TYPE_CUSTOM) {
resetCustomCurveX(points, 5+crv.points);
if (moveCurve(s_curveChan, checkIncDec_Ret > 0 ? 3 + crv.points : -3 - crv.points)) {
if (newType == CURVE_TYPE_CUSTOM) {
resetCustomCurveX(points, 5 + crv.points);
}
crv.type = newType;
}
crv.type = newType;
}
}
@@ -140,13 +141,14 @@ bool menuModelCurveOne(event_t event)
newPoints[4+count] = points[4+crv.points];
for (int i=1; i<4+count; i++)
newPoints[i] = calcRESXto100(applyCustomCurve(calc100toRESX(-100 + (i*200) / (4+count)), s_curveChan));
moveCurve(s_curveChan, checkIncDec_Ret*(crv.type==CURVE_TYPE_CUSTOM?2:1));
for (int i=0; i<5+count; i++) {
points[i] = newPoints[i];
if (crv.type == CURVE_TYPE_CUSTOM && i!=0 && i!=4+count)
points[5+count+i-1] = -100 + (i*200) / (4+count);
if (moveCurve(s_curveChan, checkIncDec_Ret*(crv.type==CURVE_TYPE_CUSTOM?2:1))) {
for (int i = 0; i < 5 + count; i++) {
points[i] = newPoints[i];
if (crv.type == CURVE_TYPE_CUSTOM && i != 0 && i != 4 + count)
points[5 + count + i - 1] = -100 + (i * 200) / (4 + count);
}
crv.points = count;
}
crv.points = count;
}
}
+1
View File
@@ -611,6 +611,7 @@ bool menuScreenSetup(int index, event_t event)
}
memset(&g_model.screenData[MAX_CUSTOM_SCREENS-1], 0, sizeof(CustomScreenData));
customScreens[MAX_CUSTOM_SCREENS-1] = NULL;
loadCustomScreens();
killEvents(KEY_ENTER);
chainMenu(menuTabScreensSetup[index > 0 ? index : 1]);
return false;
+26 -28
View File
@@ -21,9 +21,10 @@
#include "opentx.h"
#define RECT_BORDER 1
#define RECT_WIDTH (w - RECT_BORDER * 2)
#define ROW_HEIGHT 17
#define VIEW_CHANNELS_LIMIT_PCT (g_model.extendedLimits ? LIMIT_EXT_PERCENT : 100)
class OutputsWidget: public Widget
{
public:
@@ -34,40 +35,37 @@ class OutputsWidget: public Widget
virtual void refresh();
uint8_t drawChannels(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint8_t firstChan, bool bg_shown, uint16_t bg_color)
uint8_t drawChannels(const uint16_t & x, const uint16_t & y, const uint16_t & w, const uint16_t & h, const uint8_t & firstChan, const bool & bg_shown, const uint16_t & bg_color)
{
char chanString[] = "CH32";
uint8_t numChan = h / ROW_HEIGHT;
uint8_t row_height = (h - numChan * ROW_HEIGHT >= numChan ? ROW_HEIGHT + 1 : ROW_HEIGHT);
uint8_t lastChan = firstChan + numChan;
const uint8_t numChan = h / ROW_HEIGHT;
const uint8_t lastChan = firstChan + numChan;
const uint8_t rowH = (h - numChan * ROW_HEIGHT >= numChan ? ROW_HEIGHT + 1 : ROW_HEIGHT);
const uint16_t barW = w - RECT_BORDER * 2;
const uint8_t barH = rowH - RECT_BORDER;
const uint16_t barLft = x + RECT_BORDER;
const uint16_t barMid = barLft + barW / 2;
for (uint8_t curChan = firstChan; curChan < lastChan && curChan <= MAX_OUTPUT_CHANNELS; curChan++) {
const int16_t chanVal = calcRESXto100(channelOutputs[curChan-1]);
const uint16_t rowTop = y + (curChan - firstChan) * rowH;
const uint16_t barTop = rowTop + RECT_BORDER;
const uint16_t fillW = divRoundClosest(barW * limit<int16_t>(0, abs(chanVal), VIEW_CHANNELS_LIMIT_PCT), VIEW_CHANNELS_LIMIT_PCT * 2);
for (uint8_t curChan = firstChan; curChan < lastChan && curChan < 33; curChan++) {
int16_t chanVal = calcRESXto100(channelOutputs[curChan-1]);
if (bg_shown) {
lcdSetColor(bg_color);
lcdDrawSolidFilledRect(x + RECT_BORDER, y + RECT_BORDER + (curChan - firstChan) * row_height, RECT_WIDTH , row_height - RECT_BORDER, CUSTOM_COLOR);
lcdDrawSolidFilledRect(barLft, barTop, barW , barH, CUSTOM_COLOR);
}
if (chanVal > 0) {
lcdDrawSolidFilledRect(x + RECT_BORDER + RECT_WIDTH / 2, y + RECT_BORDER + (curChan -firstChan) * row_height, divRoundClosest(RECT_WIDTH * chanVal, 200), row_height - RECT_BORDER, MAINVIEW_GRAPHICS_COLOR);
if (fillW)
lcdDrawSolidFilledRect((chanVal > 0 ? barMid : barMid - fillW), barTop, fillW, barH, MAINVIEW_GRAPHICS_COLOR);
lcd->drawSolidVerticalLine(barMid, barTop, barH, MAINVIEW_GRAPHICS_COLOR);
lcdDrawRect(x, rowTop, w, rowH + 1);
lcdDrawNumber(x + barW - 10, barTop, chanVal, SMLSIZE | TEXT_COLOR | RIGHT, 0, NULL, "%");
if (g_model.limitData[curChan - 1].name[0] != 0) {
lcdDrawNumber(barLft + 1, barTop, curChan, SMLSIZE | TEXT_COLOR | LEFT | LEADING0, 2);
lcdDrawSizedText(barLft + 23, barTop, g_model.limitData[curChan - 1].name, sizeof(g_model.limitData[curChan - 1].name), SMLSIZE | TEXT_COLOR | LEFT | ZCHAR);
}
else if (chanVal < 0) {
uint16_t startpoint = x + RECT_BORDER;
uint16_t endpoint = startpoint + RECT_WIDTH / 2;
uint16_t size = divRoundClosest(- RECT_WIDTH * chanVal, 200);
lcdDrawSolidFilledRect(endpoint - size, y + RECT_BORDER + (curChan - firstChan) * row_height, size, row_height - RECT_BORDER, MAINVIEW_GRAPHICS_COLOR);
}
lcd->drawSolidVerticalLine(x + RECT_BORDER + RECT_WIDTH / 2, y + RECT_BORDER + (curChan - firstChan) * row_height, row_height - RECT_BORDER, MAINVIEW_GRAPHICS_COLOR);
lcdDrawRect(x, y + (curChan - firstChan) * row_height, w, row_height+1);
lcdDrawNumber(x + RECT_WIDTH - 10, y + (curChan - firstChan) * row_height + 1, chanVal, SMLSIZE | TEXT_COLOR | RIGHT, 0, NULL, "%");
if (g_model.limitData[curChan - 1].name[0] != 0) {
strAppendSigned(chanString, curChan, 2);
lcdDrawText(x + 2, y + (curChan - firstChan) * row_height + 1, chanString, SMLSIZE | TEXT_COLOR | LEFT);
lcdDrawSizedText(x + 25, y + (curChan - firstChan) * row_height + 1, g_model.limitData[curChan - 1].name, sizeof(g_model.limitData[curChan - 1].name), SMLSIZE | TEXT_COLOR | LEFT | ZCHAR);
}
else {
strAppend(chanString, "CH");
strAppendSigned(&chanString[2], curChan, 2);
lcdDrawText(x + 2, y + (curChan - firstChan) * row_height + 1, chanString, SMLSIZE | TEXT_COLOR | LEFT);
putsChn(barLft + 1, barTop, curChan, SMLSIZE | TEXT_COLOR | LEFT);
}
}
return lastChan - 1;
+8 -3
View File
@@ -56,11 +56,11 @@ Return OpenTX version
@retval multiple (available since 2.1.7) returns 5 values:
* (string) OpenTX version (ie "2.1.5")
* (string) radio version: `taranisx9e`, `taranisplus` or `taranis`.
* (string) radio version: `x9e`, `x9d+` or `x9d`.
If running in simulator the "-simu" is added
* (number) major version (ie 2 if version 2.1.5)
* (number) minor version (ie 1 if version 2.1.5)
* (number) revison number (ie 5 if version 2.1.5)
* (number) revision number (ie 5 if version 2.1.5)
@status current Introduced in 2.0.0, expanded in 2.1.7
@@ -108,6 +108,9 @@ Return the time since the radio was started in multiple of 10ms
@retval number Number of 10ms ticks since the radio was started Example:
run time: 12.54 seconds, return value: 1254
The timer internally uses a 32-bit counter which is enough for 30year so
overflows will not happen.
@status current Introduced in 2.0.0
*/
static int luaGetTime(lua_State * L)
@@ -304,7 +307,9 @@ bool luaFindFieldByName(const char * name, LuaField & field, unsigned int flags)
/*luadoc
@function sportTelemetryPop()
Pops a received SPORT packet from the queue. Please note that only packets using a data ID within 0x5000 to 0x52FF (frame ID == 0x10), as well as packets with a frame ID equal 0x32 (regardless of the data ID) will be passed to the LUA telemetry receive queue.
Pops a received SPORT packet from the queue. Please note that only packets using a data ID within 0x5000 to 0x52FF
(frame ID == 0x10), as well as packets with a frame ID equal 0x32 (regardless of the data ID) will be passed to
the LUA telemetry receive queue.
@retval SPORT paket as a quadruple:
* sensor ID (number)
+192
View File
@@ -805,6 +805,9 @@ Get Curve parameters
* `key` is point number (zero based)
* `value` is x value
Note that functions returns the tables starting with index 0 contrary to LUA's
usual index starting with 1
@status current Introduced in 2.0.12
*/
static int luaModelGetCurve(lua_State *L)
@@ -849,6 +852,194 @@ static int luaModelGetCurve(lua_State *L)
return 1;
}
/*luadoc
@function model.setCurve(curve, params)
Set Curve parameters
@param curve (unsigned number) curve number (use 0 for Curve1)
@param params see model.getCurve return format for table format. setCurve uses standard
lua array indexing and array start at index 1
The first and last x value must 0 and 100 and x values must be monotonically increasing
@retval 0 - Everything okay
1 - Wrong number of points
2 - Invalid Curve number
3 - Cuve does not fit anymore
4 - point of out of index
5 - x value not monotonically increasing
6 - y value not in range [-100;100]
7 - extra values for y are set
8 - extra values for x are set
@status current Introduced in 2.2.0
Example setting a 4-point custom curve:
```lua
params = {}
params["x"] = {0, 34, 77, 100}
params["y"] = {-70, 20, -89, -100}
params["smooth"] = 1
params["type"] = 1
val = model.setCurve(2, params)
```
setting a 6-point standard smoothed curve
```lua
val = model.setCurve(3, {smooth=1, y={-100, -50, 0, 50, 100, 80}})
```
*/
static int luaModelSetCurve(lua_State *L)
{
unsigned int curveIdx = luaL_checkunsigned(L, 1);
if (curveIdx >= MAX_CURVES) {
lua_pushinteger(L, 2);
return 1;
}
int8_t xPoints[MAX_POINTS_PER_CURVE];
int8_t yPoints[MAX_POINTS_PER_CURVE];
// Init to invalid values
memset(xPoints, -127, sizeof(xPoints));
memset(yPoints, -127, sizeof(yPoints));
CurveData &destCurveData = g_model.curves[curveIdx];
CurveData newCurveData;
memclear(&newCurveData, sizeof(CurveData));
luaL_checktype(L, -1, LUA_TTABLE);
for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
luaL_checktype(L, -2, LUA_TSTRING); // key is string
const char *key = luaL_checkstring(L, -2);
if (!strcmp(key, "name")) {
const char *name = luaL_checkstring(L, -1);
str2zchar(newCurveData.name, name, sizeof(newCurveData.name));
}
else if (!strcmp(key, "type")) {
newCurveData.type = luaL_checkinteger(L, -1);
}
else if (!strcmp(key, "smooth")) {
newCurveData.smooth = luaL_checkinteger(L, -1);
}
else if (!strcmp(key, "x") || !strcmp(key, "y")) {
luaL_checktype(L, -1, LUA_TTABLE);
bool isX = !strcmp(key, "x");
for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
int idx = luaL_checkinteger(L, -2)-1;
if (idx < 0 || idx > MAX_POINTS_PER_CURVE) {
lua_pushinteger(L, 4);
return 1;
}
int8_t val = luaL_checkinteger(L, -1);
if (val < -100 || val > 100) {
lua_pushinteger(L, 6);
return 1;
}
if (isX)
xPoints[idx] = val;
else
yPoints[idx] = val;
}
}
}
// Check how many points are set
uint8_t numPoints=0;
do {
numPoints++;
} while (yPoints[numPoints]!=-127 && numPoints < MAX_POINTS_PER_CURVE);
newCurveData.points = numPoints - 5;
if (numPoints < MIN_POINTS_PER_CURVE || numPoints > MAX_POINTS_PER_CURVE) {
lua_pushinteger(L, 1);
return 1;
}
if (newCurveData.type == CURVE_TYPE_CUSTOM) {
// The rest of the points are checked by the monotic condition
for (unsigned int i=numPoints; i < sizeof(xPoints);i++)
{
if (xPoints[i] != -127)
{
lua_pushinteger(L, 8);
return 1;
}
}
// Check first and last point
if (xPoints[0] != 0 || xPoints[newCurveData.points + 4] != 100) {
lua_pushinteger(L, 5);
return 1;
}
// Check that x values are increasing
for (int i = 1; i < numPoints; i++) {
if (xPoints[i - 1] > xPoints[i]) {
lua_pushinteger(L, 5);
return 1;
}
}
}
// Check that ypoints have the right number of points set
for (int i=0; i < 5 + newCurveData.points;i++)
{
if (yPoints[i] == -127)
{
lua_pushinteger(L, 7);
return 1;
}
}
// Calculate size of curve we replace
int oldCurveMemSize;
if (destCurveData.type == CURVE_TYPE_STANDARD) {
oldCurveMemSize = 5 + destCurveData.points;
}
else {
oldCurveMemSize = 8 + 2 * destCurveData.points;
}
// Calculate own size
int newCurveMemSize;
if (newCurveData.type == CURVE_TYPE_STANDARD)
newCurveMemSize = 5 + newCurveData.points;
else
newCurveMemSize = 8 + 2 * newCurveData.points;
int shift = newCurveMemSize - oldCurveMemSize;
// Also checks if new curve size would fit
if (!moveCurve(curveIdx, shift)) {
lua_pushinteger(L, 3);
TRACE("curve shift is %d", shift);
return 1;
}
// Curve fits into mem, fill new curve
destCurveData = newCurveData;
int8_t *point = curveAddress(curveIdx);
for (int i = 0; i < destCurveData.points + 5; i++) {
*point++ = yPoints[i];
}
if (destCurveData.type == CURVE_TYPE_CUSTOM) {
for (int i = 1; i < destCurveData.points + 4; i++) {
*point++ = yPoints[i];
}
}
storageDirty(EE_MODEL);
lua_pushinteger(L, 0);
return 1;
}
/*luadoc
@function model.getCustomFunction(function)
@@ -1132,6 +1323,7 @@ const luaL_Reg modelLib[] = {
{ "getCustomFunction", luaModelGetCustomFunction },
{ "setCustomFunction", luaModelSetCustomFunction },
{ "getCurve", luaModelGetCurve },
{ "setCurve", luaModelSetCurve },
{ "getOutput", luaModelGetOutput },
{ "setOutput", luaModelSetOutput },
{ "getGlobalVariable", luaModelGetGlobalVariable },
+4 -2
View File
@@ -31,6 +31,7 @@
lua_State *lsWidgets = NULL;
extern int custom_lua_atpanic(lua_State *L);
#define LUA_WIDGET_FILENAME "/main.lua"
#define LUA_FULLPATH_MAXLEN (LEN_FILE_PATH_MAX + LEN_SCRIPT_FILENAME + LEN_FILE_EXTENSION_MAX) // max length (example: /SCRIPTS/THEMES/mytheme.lua)
void exec(int function, int nresults=0)
@@ -496,9 +497,10 @@ void luaLoadFiles(const char * directory, void (*callback)())
res = f_readdir(&dir, &fno); /* Read a directory item */
if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */
uint8_t len = strlen(fno.fname);
if (len > 0 && fno.fname[0]!='.' && (fno.fattrib & AM_DIR)) {
if (len > 0 && (unsigned int)(len + pathlen + sizeof(LUA_WIDGET_FILENAME)) <= sizeof(path) &&
fno.fname[0]!='.' && (fno.fattrib & AM_DIR)) {
strcpy(&path[pathlen], fno.fname);
strcat(&path[pathlen], "/main.lua");
strcat(&path[pathlen], LUA_WIDGET_FILENAME);
if (isFileAvailable(path)) {
luaLoadFile(path, callback);
}
+4 -1
View File
@@ -128,6 +128,7 @@ uint16_t isqrt32(uint32_t n)
*/
#if defined(FRSKY_HUB) && !defined(CPUARM)
// convert latitude and longitude to 1/10^6 degrees
void extractLatitudeLongitude(uint32_t * latitude, uint32_t * longitude)
{
div_t qr = div(telemetryData.hub.gpsLatitude_bp, 100);
@@ -140,10 +141,12 @@ void extractLatitudeLongitude(uint32_t * latitude, uint32_t * longitude)
void getGpsPilotPosition()
{
extractLatitudeLongitude(&telemetryData.hub.pilotLatitude, &telemetryData.hub.pilotLongitude);
// distFromEarthAxis = cos(lat) * EARTH_RADIUS
// 1 - x2/2 + x4/24
uint32_t lat = telemetryData.hub.pilotLatitude / 10000;
uint32_t angle2 = (lat*lat) / 10000;
uint32_t angle4 = angle2 * angle2;
telemetryData.hub.distFromEarthAxis = 139*(((uint32_t)10000000-((angle2*(uint32_t)123370)/81)+(angle4/25))/12500);
telemetryData.hub.distFromEarthAxis = 139 * (((uint32_t)10000000-((angle2*(uint32_t)123370)/81)+(angle4/25)) / 12500);
// TRACE("telemetryData.hub.distFromEarthAxis=%d", telemetryData.hub.distFromEarthAxis);
}
+1 -1
View File
@@ -1557,7 +1557,7 @@ extern uint8_t s_frsky_view;
#endif
#define EARTH_RADIUSKM ((uint32_t)6371)
#define EARTH_RADIUS ((uint32_t)111194)
#define EARTH_RADIUS ((uint32_t)111194) // meters * pi / 180°
void getGpsPilotPosition();
void getGpsDistance();
+1 -1
View File
@@ -134,7 +134,7 @@ void pxxPutPcmTail(uint8_t port)
#else
void pxxPutPcmPart(uint8_t port, uint8_t value)
{
pulse_duration_t duration = value ? 48 : 32;
pulse_duration_t duration = value ? 47 : 31;
*modulePulsesData[port].pxx.ptr++ = duration;
modulePulsesData[port].pxx.rest -= duration + 1;
}
+14 -13
View File
@@ -163,14 +163,14 @@ char * getTimerString(char * dest, putstime_t tme, uint8_t hours)
{
char * s = dest;
div_t qr;
if (tme < 0) {
tme = -tme;
*s++ = '-';
}
qr = div((int)tme, 60);
if (hours) {
div_t qr2 = div(qr.quot, 60);
*s++ = '0' + (qr2.quot / 10);
@@ -178,14 +178,14 @@ char * getTimerString(char * dest, putstime_t tme, uint8_t hours)
*s++ = ':';
qr.quot = qr2.rem;
}
*s++ = '0' + (qr.quot / 10);
*s++ = '0' + (qr.quot % 10);
*s++ = ':';
*s++ = '0' + (qr.rem / 10);
*s++ = '0' + (qr.rem % 10);
*s = '\0';
return dest;
}
@@ -194,18 +194,18 @@ char * getCurveString(char * dest, int idx)
if (idx == 0) {
return getStringAtIndex(dest, STR_MMMINV, 0);
}
char * s = dest;
if (idx < 0) {
*s++ = '!';
idx = -idx;
}
if (ZEXIST(g_model.curves[idx - 1].name))
zchar2str(s, g_model.curves[idx - 1].name, LEN_CURVE_NAME);
else
strAppendStringWithIndex(s, STR_CV, idx);
return dest;
}
@@ -233,13 +233,13 @@ char * getSwitchString(char * dest, swsrc_t idx)
else if (idx == SWSRC_OFF) {
return getStringAtIndex(dest, STR_OFFON, 0);
}
char * s = dest;
if (idx < 0) {
*s++ = '!';
idx = -idx;
}
#if defined(PCBSKY9X)
#define IDX_TRIMS_IN_STR_VSWITCHES (1+SWSRC_LAST_SWITCH)
#define IDX_ON_IN_STR_VSWITCHES (IDX_TRIMS_IN_STR_VSWITCHES+SWSRC_LAST_TRIM-SWSRC_FIRST_TRIM+2)
@@ -294,7 +294,8 @@ char * getSwitchString(char * dest, swsrc_t idx)
#endif
else if (idx <= SWSRC_LAST_LOGICAL_SWITCH) {
strAppendStringWithIndex(s, "L", idx-SWSRC_FIRST_LOGICAL_SWITCH+1);
*s++ = 'L';
strAppendUnsigned(s, idx-SWSRC_FIRST_LOGICAL_SWITCH+1, 2);
}
else if (idx <= SWSRC_ONE) {
getStringAtIndex(s, STR_VSWITCHES, IDX_ON_IN_STR_VSWITCHES + idx - SWSRC_ON);
@@ -325,7 +326,7 @@ char * getSourceString(char * dest, mixsrc_t idx)
dest[LEN_INPUT_NAME] = '\0';
}
else {
strAppendUnsigned(dest, idx, 2);
strAppendUnsigned(dest, idx+1, 2);
}
}
#if defined(LUA_INPUTS)
@@ -389,7 +390,7 @@ char * getSourceString(char * dest, mixsrc_t idx)
if (qr.rem) dest[pos++] = (qr.rem==2 ? '+' : '-');
dest[pos] = '\0';
}
return dest;
}
#endif
+1 -2
View File
@@ -93,7 +93,7 @@ elseif(TELEMETRY STREQUAL MAVLINK)
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
if(NOT ${GIT_SUBMODULE_RESULT} EQUAL 0)
message(FATAL_ERROR "Error: Cannot clone submodule at ${THIRDPARTY_DIR}/GCS_MAVLink/include_v1.0
If you downloaded this project as a ZIP file, please instead run
If you downloaded this project as a ZIP file, please instead run
'git clone --recursive https://github.com/opentx/opentx.git'")
endif()
endif()
@@ -106,7 +106,6 @@ If you downloaded this project as a ZIP file, please instead run
math(EXPR EEPROM_VARIANT ${EEPROM_VARIANT}+${MAVLINK_VARIANT})
elseif(TELEMETRY STREQUAL TELEMETREZ)
add_definitions(-DTELEMETRY_TELEMETREZ)
set(SRC ${SRC} telemetry/jeti.cpp)
elseif(TELEMETRY STREQUAL FRSKY_SPORT)
add_definitions(-DTELEMETRY_FRSKY_SPORT)
set(SRC ${SRC} crc16.cpp telemetry/frsky_sport.cpp)
@@ -95,7 +95,7 @@ uint32_t firmwareWritten = 0;
uint32_t eepromAddress = 0;
uint32_t eepromWritten = 0;
TCHAR backupFilename[60];
TCHAR backupFilename[_MAX_LFN+1];
uint32_t Master_frequency;
volatile uint8_t Tenms;
@@ -229,7 +229,7 @@ const char *getBinaryPath()
FRESULT openBinaryFile(uint32_t index)
{
TCHAR filename[60];
TCHAR filename[_MAX_LFN+1];
FRESULT fr;
memset(Block_buffer, 0, sizeof(Block_buffer));
strAppend(strAppend(strAppend(filename, getBinaryPath()), "/"), Filenames[index]);
@@ -641,4 +641,3 @@ int main()
return 0;
}
+1 -4
View File
@@ -259,10 +259,7 @@ void frskySportSetDefault(int index, uint16_t id, uint8_t subId, uint8_t instanc
TelemetryUnit unit = sensor->unit;
uint8_t prec = min<uint8_t>(2, sensor->prec);
telemetrySensor.init(sensor->name, unit, prec);
if (id == RSSI_ID) {
telemetrySensor.logs = true;
}
else if (id >= ADC1_ID && id <= BATT_ID) {
if (id >= ADC1_ID && id <= BATT_ID) {
telemetrySensor.custom.ratio = 132;
telemetrySensor.filter = 1;
}
+1 -34
View File
@@ -320,19 +320,12 @@ void telemetryReset()
telemetryData.hub.gpsFix = -1;
#endif
#if defined(SIMU)
#if defined(CPUARM)
telemetryData.swr.value = 30;
telemetryData.rssi.value = 75;
#else
#if defined(SIMU) && !defined(CPUARM)
telemetryData.rssi[0].value = 75;
telemetryData.rssi[1].value = 75;
telemetryData.analog[TELEM_ANA_A1].set(120, UNIT_VOLTS);
telemetryData.analog[TELEM_ANA_A2].set(240, UNIT_VOLTS);
#endif
#if !defined(CPUARM)
telemetryData.hub.fuelLevel = 75;
telemetryData.hub.rpm = 12000;
telemetryData.hub.vfas = 100;
@@ -381,32 +374,6 @@ void telemetryReset()
telemetryData.hub.current = 55;
telemetryData.hub.maxCurrent = 65;
#endif
#endif
/*Add some default sensor values to the simulator*/
#if defined(CPUARM) && defined(SIMU)
for (int i=0; i<MAX_TELEMETRY_SENSORS; i++) {
const TelemetrySensor & sensor = g_model.telemetrySensors[i];
switch (sensor.id)
{
case RSSI_ID:
setTelemetryValue(TELEM_PROTO_FRSKY_SPORT, RSSI_ID, 0, sensor.instance , 75, UNIT_RAW, 0);
break;
case ADC1_ID:
setTelemetryValue(TELEM_PROTO_FRSKY_SPORT, ADC1_ID, 0, sensor.instance, 100, UNIT_RAW, 0);
break;
case ADC2_ID:
setTelemetryValue(TELEM_PROTO_FRSKY_SPORT, ADC2_ID, 0, sensor.instance, 245, UNIT_RAW, 0);
break;
case SWR_ID:
setTelemetryValue(TELEM_PROTO_FRSKY_SPORT, SWR_ID, 0, sensor.instance, 30, UNIT_RAW, 0);
break;
case BATT_ID:
setTelemetryValue(TELEM_PROTO_FRSKY_SPORT, BATT_ID, 0, sensor.instance, 100, UNIT_RAW, 0);
break;
}
}
#endif
}
#if defined(CPUARM)
@@ -491,6 +491,8 @@ void TelemetrySensor::init(const char * label, uint8_t unit, uint8_t prec)
prec = 1;
}
this->prec = prec;
// Log sensors by default
this->logs = true;
}
void TelemetrySensor::init(uint16_t id)
+2 -2
View File
@@ -481,9 +481,9 @@
#endif
#if defined(CPUARM)
#define TR_LOGICALSW "L1\0""L2\0""L3\0""L4\0""L5\0""L6\0""L7\0""L8\0""L9\0""L10""L11""L12""L13""L14""L15""L16""L17""L18""L19""L20""L21""L22""L23""L24""L25""L26""L27""L28""L29""L30""L31""L32"
#define TR_LOGICALSW "L01""L02""L03""L04""L05""L06""L07""L08""L09""L10""L11""L12""L13""L14""L15""L16""L17""L18""L19""L20""L21""L22""L23""L24""L25""L26""L27""L28""L29""L30""L31""L32"
#else
#define TR_LOGICALSW "L1\0""L2\0""L3\0""L4\0""L5\0""L6\0""L7\0""L8\0""L9\0""L10""L11""L12"
#define TR_LOGICALSW "L01""L02""L03""L04""L05""L06""L07""L08""L09""L10""L11""L12"
#endif
#if defined(PCBHORUS)
+2 -2
View File
@@ -504,9 +504,9 @@
#endif
#if defined(CPUARM)
#define TR_LOGICALSW "L1\0""L2\0""L3\0""L4\0""L5\0""L6\0""L7\0""L8\0""L9\0""L10""L11""L12""L13""L14""L15""L16""L17""L18""L19""L20""L21""L22""L23""L24""L25""L26""L27""L28""L29""L30""L31""L32"
#define TR_LOGICALSW "L01""L02""L03""L04""L05""L06""L07""L08""L09""L10""L11""L12""L13""L14""L15""L16""L17""L18""L19""L20""L21""L22""L23""L24""L25""L26""L27""L28""L29""L30""L31""L32"
#else
#define TR_LOGICALSW "L1\0""L2\0""L3\0""L4\0""L5\0""L6\0""L7\0""L8\0""L9\0""L10""L11""L12"
#define TR_LOGICALSW "L01""L02""L03""L04""L05""L06""L07""L08""L09""L10""L11""L12"
#endif
#if defined(PCBHORUS)
+2 -2
View File
@@ -487,9 +487,9 @@
#endif
#if defined(CPUARM)
#define TR_LOGICALSW "L1\0""L2\0""L3\0""L4\0""L5\0""L6\0""L7\0""L8\0""L9\0""L10""L11""L12""L13""L14""L15""L16""L17""L18""L19""L20""L21""L22""L23""L24""L25""L26""L27""L28""L29""L30""L31""L32"
#define TR_LOGICALSW "L01""L02""L03""L04""L05""L06""L07""L08""L09""L10""L11""L12""L13""L14""L15""L16""L17""L18""L19""L20""L21""L22""L23""L24""L25""L26""L27""L28""L29""L30""L31""L32"
#else
#define TR_LOGICALSW "L1\0""L2\0""L3\0""L4\0""L5\0""L6\0""L7\0""L8\0""L9\0""L10""L11""L12"
#define TR_LOGICALSW "L01""L02""L03""L04""L05""L06""L07""L08""L09""L10""L11""L12"
#endif
#if defined(PCBHORUS)
+2 -2
View File
@@ -477,9 +477,9 @@
#endif
#if defined(CPUARM)
#define TR_LOGICALSW "L1\0""L2\0""L3\0""L4\0""L5\0""L6\0""L7\0""L8\0""L9\0""L10""L11""L12""L13""L14""L15""L16""L17""L18""L19""L20""L21""L22""L23""L24""L25""L26""L27""L28""L29""L30""L31""L32"
#define TR_LOGICALSW "L01""L02""L03""L04""L05""L06""L07""L08""L09""L10""L11""L12""L13""L14""L15""L16""L17""L18""L19""L20""L21""L22""L23""L24""L25""L26""L27""L28""L29""L30""L31""L32"
#else
#define TR_LOGICALSW "L1\0""L2\0""L3\0""L4\0""L5\0""L6\0""L7\0""L8\0""L9\0""L10""L11""L12"
#define TR_LOGICALSW "L01""L02""L03""L04""L05""L06""L07""L08""L09""L10""L11""L12"
#endif
#if defined(PCBHORUS)
+2 -2
View File
@@ -481,9 +481,9 @@
#endif
#if defined(CPUARM)
#define TR_LOGICALSW "L1\0""L2\0""L3\0""L4\0""L5\0""L6\0""L7\0""L8\0""L9\0""L10""L11""L12""L13""L14""L15""L16""L17""L18""L19""L20""L21""L22""L23""L24""L25""L26""L27""L28""L29""L30""L31""L32"
#define TR_LOGICALSW "L01""L02""L03""L04""L05""L06""L07""L08""L09""L10""L11""L12""L13""L14""L15""L16""L17""L18""L19""L20""L21""L22""L23""L24""L25""L26""L27""L28""L29""L30""L31""L32"
#else
#define TR_LOGICALSW "L1\0""L2\0""L3\0""L4\0""L5\0""L6\0""L7\0""L8\0""L9\0""L10""L11""L12"
#define TR_LOGICALSW "L01""L02""L03""L04""L05""L06""L07""L08""L09""L10""L11""L12"
#endif
#if defined(PCBHORUS)
+2 -2
View File
@@ -494,9 +494,9 @@
#endif
#if defined(CPUARM)
#define TR_LOGICALSW "L1\0""L2\0""L3\0""L4\0""L5\0""L6\0""L7\0""L8\0""L9\0""L10""L11""L12""L13""L14""L15""L16""L17""L18""L19""L20""L21""L22""L23""L24""L25""L26""L27""L28""L29""L30""L31""L32"
#define TR_LOGICALSW "L01""L02""L03""L04""L05""L06""L07""L08""L09""L10""L11""L12""L13""L14""L15""L16""L17""L18""L19""L20""L21""L22""L23""L24""L25""L26""L27""L28""L29""L30""L31""L32"
#else
#define TR_LOGICALSW "L1\0""L2\0""L3\0""L4\0""L5\0""L6\0""L7\0""L8\0""L9\0""L10""L11""L12"
#define TR_LOGICALSW "L01""L02""L03""L04""L05""L06""L07""L08""L09""L10""L11""L12"
#endif
#if defined(PCBHORUS)
+2 -2
View File
@@ -488,9 +488,9 @@
#endif
#if defined(CPUARM)
#define TR_LOGICALSW "L1\0""L2\0""L3\0""L4\0""L5\0""L6\0""L7\0""L8\0""L9\0""L10""L11""L12""L13""L14""L15""L16""L17""L18""L19""L20""L21""L22""L23""L24""L25""L26""L27""L28""L29""L30""L31""L32"
#define TR_LOGICALSW "L01""L02""L03""L04""L05""L06""L07""L08""L09""L10""L11""L12""L13""L14""L15""L16""L17""L18""L19""L20""L21""L22""L23""L24""L25""L26""L27""L28""L29""L30""L31""L32"
#else
#define TR_LOGICALSW "L1\0""L2\0""L3\0""L4\0""L5\0""L6\0""L7\0""L8\0""L9\0""L10""L11""L12"
#define TR_LOGICALSW "L01""L02""L03""L04""L05""L06""L07""L08""L09""L10""L11""L12"
#endif
#if defined(PCBHORUS)
+2 -2
View File
@@ -478,9 +478,9 @@
#endif
#if defined(CPUARM)
#define TR_LOGICALSW "L1\0""L2\0""L3\0""L4\0""L5\0""L6\0""L7\0""L8\0""L9\0""L10""L11""L12""L13""L14""L15""L16""L17""L18""L19""L20""L21""L22""L23""L24""L25""L26""L27""L28""L29""L30""L31""L32"
#define TR_LOGICALSW "L01""L02""L03""L04""L05""L06""L07""L08""L09""L10""L11""L12""L13""L14""L15""L16""L17""L18""L19""L20""L21""L22""L23""L24""L25""L26""L27""L28""L29""L30""L31""L32"
#else
#define TR_LOGICALSW "L1\0""L2\0""L3\0""L4\0""L5\0""L6\0""L7\0""L8\0""L9\0""L10""L11""L12"
#define TR_LOGICALSW "L01""L02""L03""L04""L05""L06""L07""L08""L09""L10""L11""L12"
#endif
#if defined(PCBHORUS)
+2 -2
View File
@@ -490,9 +490,9 @@
#endif
#if defined(CPUARM)
#define TR_LOGICALSW "L1\0""L2\0""L3\0""L4\0""L5\0""L6\0""L7\0""L8\0""L9\0""L10""L11""L12""L13""L14""L15""L16""L17""L18""L19""L20""L21""L22""L23""L24""L25""L26""L27""L28""L29""L30""L31""L32"
#define TR_LOGICALSW "L01""L02""L03""L04""L05""L06""L07""L08""L09""L10""L11""L12""L13""L14""L15""L16""L17""L18""L19""L20""L21""L22""L23""L24""L25""L26""L27""L28""L29""L30""L31""L32"
#else
#define TR_LOGICALSW "L1\0""L2\0""L3\0""L4\0""L5\0""L6\0""L7\0""L8\0""L9\0""L10""L11""L12"
#define TR_LOGICALSW "L01""L02""L03""L04""L05""L06""L07""L08""L09""L10""L11""L12"
#endif
#if defined(PCBHORUS)
+2 -2
View File
@@ -478,9 +478,9 @@
#endif
#if defined(CPUARM)
#define TR_LOGICALSW "L1\0""L2\0""L3\0""L4\0""L5\0""L6\0""L7\0""L8\0""L9\0""L10""L11""L12""L13""L14""L15""L16""L17""L18""L19""L20""L21""L22""L23""L24""L25""L26""L27""L28""L29""L30""L31""L32"
#define TR_LOGICALSW "L01""L02""L03""L04""L05""L06""L07""L08""L09""L10""L11""L12""L13""L14""L15""L16""L17""L18""L19""L20""L21""L22""L23""L24""L25""L26""L27""L28""L29""L30""L31""L32"
#else
#define TR_LOGICALSW "L1\0""L2\0""L3\0""L4\0""L5\0""L6\0""L7\0""L8\0""L9\0""L10""L11""L12"
#define TR_LOGICALSW "L01""L02""L03""L04""L05""L06""L07""L08""L09""L10""L11""L12"
#endif
#if defined(PCBHORUS)
+2 -2
View File
@@ -495,9 +495,9 @@
#endif
#if defined(CPUARM)
#define TR_LOGICALSW "L1\0""L2\0""L3\0""L4\0""L5\0""L6\0""L7\0""L8\0""L9\0""L10""L11""L12""L13""L14""L15""L16""L17""L18""L19""L20""L21""L22""L23""L24""L25""L26""L27""L28""L29""L30""L31""L32"
#define TR_LOGICALSW "L01""L02""L03""L04""L05""L06""L07""L08""L09""L10""L11""L12""L13""L14""L15""L16""L17""L18""L19""L20""L21""L22""L23""L24""L25""L26""L27""L28""L29""L30""L31""L32"
#else
#define TR_LOGICALSW "L1\0""L2\0""L3\0""L4\0""L5\0""L6\0""L7\0""L8\0""L9\0""L10""L11""L12"
#define TR_LOGICALSW "L01""L02""L03""L04""L05""L06""L07""L08""L09""L10""L11""L12"
#endif
#if defined(PCBHORUS)
+16 -47
View File
@@ -179,63 +179,32 @@ I18N_PLAY_FUNCTION(it, playNumber, getvalue_t number, uint8_t unit, uint8_t att)
I18N_PLAY_FUNCTION(it, playDuration, int seconds PLAY_DURATION_ATT)
{
if (seconds == 0) {
PLAY_NUMBER(seconds, 0, 0);
return;
}
if (seconds < 0) {
PUSH_NUMBER_PROMPT(IT_PROMPT_MENO);
seconds = -seconds;
}
uint8_t ore = 0;
uint8_t tmp = seconds / 3600;
seconds %= 3600;
if (tmp > 0 || IS_PLAY_TIME()) {
PLAY_NUMBER(tmp, UNIT_HOURS, 0);
}
tmp = seconds / 60;
seconds %= 60;
if (tmp > 0) {
ore=tmp;
if (tmp > 1 || IS_PLAY_TIME()) {
#if defined(CPUARM)
PLAY_NUMBER(tmp, UNIT_HOURS, 0);
#else
PLAY_NUMBER(tmp, 0, 0);
PUSH_NUMBER_PROMPT(IT_PROMPT_ORE);
} else {
PUSH_NUMBER_PROMPT(IT_PROMPT_UN);
PUSH_NUMBER_PROMPT(IT_PROMPT_ORA);
#endif
}
}
if (seconds>0) {
tmp = seconds / 60;
seconds %= 60;
if (tmp>0 && seconds==0 && ore>0) {
PLAY_NUMBER(tmp, UNIT_MINUTES, 0);
if (seconds > 0)
PUSH_NUMBER_PROMPT(IT_PROMPT_E);
}
if (tmp > 0) {
if (tmp != 1) {
#if defined(CPUARM)
PLAY_NUMBER(tmp, UNIT_MINUTES, 0);
#else
PLAY_NUMBER(tmp, 0, 0);
PUSH_NUMBER_PROMPT(IT_PROMPT_MINUTI);
} else {
PUSH_NUMBER_PROMPT(IT_PROMPT_UN);
PUSH_NUMBER_PROMPT(IT_PROMPT_MINUTO);
#endif
}
}
if ((tmp>0 || ore>0) && seconds>0) {
PUSH_NUMBER_PROMPT(IT_PROMPT_E);
}
}
if (seconds != 0 || (ore==0 && tmp==0)) {
if (seconds != 1) {
#if defined(CPUARM)
PLAY_NUMBER(tmp, UNIT_SECONDS, 0);
#else
PLAY_NUMBER(seconds, 0, 0);
PUSH_NUMBER_PROMPT(IT_PROMPT_SECONDI);
} else {
PUSH_NUMBER_PROMPT(IT_PROMPT_UN);
PUSH_NUMBER_PROMPT(IT_PROMPT_SECONDO);
#endif
}
if (seconds > 0) {
PLAY_NUMBER(seconds, UNIT_SECONDS, 0);
}
}
+92 -92
View File
@@ -12,103 +12,103 @@ for i, s in enumerate(["nula", "jedna", "dva"]):
systemSounds.append((s, filename(PROMPT_SYSTEM_BASE + i)))
for i in range(97):
systemSounds.append((str(3 + i), filename(PROMPT_SYSTEM_BASE + 3 + i)))
for i, s in enumerate(["sto", u"dvěsta", u"třista", u"čtyřista", u"pětset", u"šestset", "sedmset", "osmset",
u"devětset", u"tisíc"]):
for i, s in enumerate(["sto", "dvěsta", "třista", "čtyřista", "pětset", "šestset", "sedmset", "osmset",
"devětset", "tisíc"]):
systemSounds.append((s, filename(PROMPT_SYSTEM_BASE + 100 + i)))
for i, s in enumerate([u"tisíce", "jeden", "jedno", u"dvě", u"celá", u"celé", u"celých", u"mínus"]):
for i, s in enumerate(["tisíce", "jeden", "jedno", "dvě", "celá", "celé", "celých", "mínus"]):
systemSounds.append((s, filename(PROMPT_SYSTEM_BASE + 110 + i)))
for i, (s, f) in enumerate([(u"volt", u"volt0"), (u"volty", u"volt1"), (u"voltů", u"volt2"),(u"voltu", u"volt3"),
(u"ampér", "amp0"), (u"ampéry", u"amp1"), (u"ampérů", u"amp2"), (u"ampéru", u"amp3"),
(u"miliampér", "mamp0"), (u"miliampéry", u"mamp1"), (u"miliampérů", u"mamp2"), (u"miliampéru", u"mamp3"),
(u"uzel", "knot0"), (u"uzly", u"knot1"), (u"uzlů", u"knot2"), (u"uzlu", u"knot3"),
(u"metr za sekundu", "mps0"), (u"metry za sekundu", u"mps1"), (u"metrů za sekundu", u"mps2"), (u"metru za sekundu", u"mps3"),
(u"stopa za sekundu", "fps0"), (u"stopy za sekundu", u"fps1"), (u"stop za sekundu", u"fps2"), (u"stopy za sekundu", u"fps3"),
(u"kilometr za hodinu", "kph0"), (u"kilometry za hodinu", u"kph1"), (u"kilometrů za hodinu", u"kph2"), (u"kilometru za hodinu", u"kph3"),
(u"míle za hodinu", "mph0"), (u"míle za hodinu", u"mph1"), (u"mil za hodinu", u"mph2"), (u"míle za hodinu", u"mph3"),
(u"metr", "meter0"), (u"metry", u"meter1"), (u"metrů", u"meter2"), (u"metru", u"meter3"),
(u"stopa", "foot0"), (u"stopy", u"foot1"), (u"stop", u"foot2"),(u"stopy", u"foot3"),
(u"stupeň celsia", "celsius0"), (u"stupně celsia", u"celsius1"), (u"stupňů celsia", u"celsius2"), (u"stupně celsia", u"celsius3"),
(u"stupeň fahrenheita", "fahr0"), (u"stupně fahrenheita", u"fahr1"), (u"stupňů fahrenheita", u"fahr2"), (u"stupně fahrenheita", u"fahr3"),
(u"procento", "percent0"), (u"procenta", u"percent1"), (u"procent", u"percent2"), (u"procenta", u"percent3"),
(u"miliampérhodina", "mamph0"), (u"miliampérhodiny", u"mamph1"), (u"miliampérhodin", u"mamph2"), (u"miliampérhodiny", u"mamph3"),
(u"vat", "watt0"), (u"vaty", u"watt1"), (u"vatů", u"watt2"), (u"vatu", u"watt3"),
(u"milivat", "mwatt0"), (u"milivaty", u"mwatt1"), (u"milivatů", u"mwatt2"), (u"milivatu", u"mwatt3"),
(u"decibel", "db0"), (u"decibely", u"db1"), (u"decibelů", u"db2"), (u"decibelu", u"db3"),
(u"otáčka za minutu", "rpm0"), (u"otáčky za minutu", u"rpm1"), (u"otáček za minutu", u"rpm2"), (u"otáčky za minutu", u"rpm3"),
(u"gé", "g0"), (u"gé", "g1"), (u"gé", "g2"), (u"gé", "g3"),
(u"stupeň", "degree0"), (u"stupně", u"degree1"), (u"stupňů", u"degree2"), (u"stupně", u"degree3"),
(u"radián", "rad0"), (u"radiány", "rad1"), (u"radiánů", "rad2"), (u"radiánu", "rad3"),
(u"mililitr", "ml0"), (u"mililitry", u"ml1"), (u"mililitrů", u"ml2"), (u"mililitru", u"ml3"),
(u"dutá unce", "founce0"), (u"duté unce", u"founce1"), (u"dutých uncí", u"founce2"), (u"duté unce", u"founce3"),
(u"hodina", "hour0"), (u"hodiny", u"hour1"), (u"hodin", u"hour2"), (u"hodiny", u"hour3"),
(u"minuta", "minute0"), (u"minuty", u"minute1"), (u"minut", u"minute2"), (u"minuty", u"minute3"),
(u"sekunda", "second0"), (u"sekundy", u"second1"), (u"sekund", u"second2"), (u"sekundy", u"second3"),
for i, (s, f) in enumerate([("volt", "volt0"), ("volty", "volt1"), ("voltů", "volt2"),("voltu", "volt3"),
("ampér", "amp0"), ("ampéry", "amp1"), ("ampérů", "amp2"), ("ampéru", "amp3"),
("miliampér", "mamp0"), ("miliampéry", "mamp1"), ("miliampérů", "mamp2"), ("miliampéru", "mamp3"),
("uzel", "knot0"), ("uzly", "knot1"), ("uzlů", "knot2"), ("uzlu", "knot3"),
("metr za sekundu", "mps0"), ("metry za sekundu", "mps1"), ("metrů za sekundu", "mps2"), ("metru za sekundu", "mps3"),
("stopa za sekundu", "fps0"), ("stopy za sekundu", "fps1"), ("stop za sekundu", "fps2"), ("stopy za sekundu", "fps3"),
("kilometr za hodinu", "kph0"), ("kilometry za hodinu", "kph1"), ("kilometrů za hodinu", "kph2"), ("kilometru za hodinu", "kph3"),
("míle za hodinu", "mph0"), ("míle za hodinu", "mph1"), ("mil za hodinu", "mph2"), ("míle za hodinu", "mph3"),
("metr", "meter0"), ("metry", "meter1"), ("metrů", "meter2"), ("metru", "meter3"),
("stopa", "foot0"), ("stopy", "foot1"), ("stop", "foot2"),("stopy", "foot3"),
("stupeň celsia", "celsius0"), ("stupně celsia", "celsius1"), ("stupňů celsia", "celsius2"), ("stupně celsia", "celsius3"),
("stupeň fahrenheita", "fahr0"), ("stupně fahrenheita", "fahr1"), ("stupňů fahrenheita", "fahr2"), ("stupně fahrenheita", "fahr3"),
("procento", "percent0"), ("procenta", "percent1"), ("procent", "percent2"), ("procenta", "percent3"),
("miliampérhodina", "mamph0"), ("miliampérhodiny", "mamph1"), ("miliampérhodin", "mamph2"), ("miliampérhodiny", "mamph3"),
("vat", "watt0"), ("vaty", "watt1"), ("vatů", "watt2"), ("vatu", "watt3"),
("milivat", "mwatt0"), ("milivaty", "mwatt1"), ("milivatů", "mwatt2"), ("milivatu", "mwatt3"),
("decibel", "db0"), ("decibely", "db1"), ("decibelů", "db2"), ("decibelu", "db3"),
("otáčka za minutu", "rpm0"), ("otáčky za minutu", "rpm1"), ("otáček za minutu", "rpm2"), ("otáčky za minutu", "rpm3"),
("gé", "g0"), ("gé", "g1"), ("gé", "g2"), ("gé", "g3"),
("stupeň", "degree0"), ("stupně", "degree1"), ("stupňů", "degree2"), ("stupně", "degree3"),
("radián", "rad0"), ("radiány", "rad1"), ("radiánů", "rad2"), ("radiánu", "rad3"),
("mililitr", "ml0"), ("mililitry", "ml1"), ("mililitrů", "ml2"), ("mililitru", "ml3"),
("dutá unce", "founce0"), ("duté unce", "founce1"), ("dutých uncí", "founce2"), ("duté unce", "founce3"),
("hodina", "hour0"), ("hodiny", "hour1"), ("hodin", "hour2"), ("hodiny", "hour3"),
("minuta", "minute0"), ("minuty", "minute1"), ("minut", "minute2"), ("minuty", "minute3"),
("sekunda", "second0"), ("sekundy", "second1"), ("sekund", "second2"), ("sekundy", "second3"),
]):
systemSounds.append((s, filename(f, PROMPT_SYSTEM_BASE + 118 + i)))
for s, f, a in [(u"střed trimu", "midtrim", 495),
(u"maximum trimu", "maxtrim", NO_ALTERNATE),
(u"minimum trimu", "mintrim", NO_ALTERNATE),
(u"stopky 1 doběhly", "timovr1", NO_ALTERNATE),
(u"stopky 2 doběhly", "timovr2", NO_ALTERNATE),
(u"stopky 3 doběhly", "timovr3", NO_ALTERNATE),
(u"baterie rádia je vybitá", "lowbatt", 485),
(u"zapoměl jsi na mě!", "inactiv", 486),
(u"plyn není na nule", "thralert", 481),
(u"přepínače nejsou ve výchozí poloze", "swalert", 482),
(u"neplatná eeprom", "eebad", 483),
(u"Oupn najn iks", "hello", 480),
(u"Tak zase příště!", "bye", 480),
(u"dvacet sekund", "timer20", 500),
(u"třicet sekund", "timer30", 501),
(u"A1,nízká", "a1_org", NO_ALTERNATE),
(u"A1,kritická", "a1_red", NO_ALTERNATE),
(u"A2,nízká", "a2_org", NO_ALTERNATE),
(u"A2,kritická", "a2_red", NO_ALTERNATE),
(u"A3,nízká", "a3_org", NO_ALTERNATE),
(u"A3,kritická", "a3_red", NO_ALTERNATE),
(u"A4,nízká", "a4_org", NO_ALTERNATE),
(u"A4,kritická", "a4_red", NO_ALTERNATE),
(u"nízký RF signál", "rssi_org", NO_ALTERNATE),
(u"kritický RF signál", "rssi_red", NO_ALTERNATE),
(u"problém s anténou rádia", "swr_red", NO_ALTERNATE),
(u"telemetrie ztracena", "telemko", NO_ALTERNATE),
(u"telemetrie je funkční", "telemok", NO_ALTERNATE),
(u"trenér port odpojen", "trainko", NO_ALTERNATE),
(u"trenér port připojen", "trainok", NO_ALTERNATE),
(u"senzor ztracen", "sensorko", NO_ALTERNATE),
(u"servo přetíženo", "servoko", NO_ALTERNATE),
(u"r f přebuzeno", "rxko", NO_ALTERNATE),
for s, f, a in [("střed trimu", "midtrim", 495),
("maximum trimu", "maxtrim", NO_ALTERNATE),
("minimum trimu", "mintrim", NO_ALTERNATE),
("stopky 1 doběhly", "timovr1", NO_ALTERNATE),
("stopky 2 doběhly", "timovr2", NO_ALTERNATE),
("stopky 3 doběhly", "timovr3", NO_ALTERNATE),
("baterie rádia je vybitá", "lowbatt", 485),
("zapoměl jsi na mě!", "inactiv", 486),
("plyn není na nule", "thralert", 481),
("přepínače nejsou ve výchozí poloze", "swalert", 482),
("neplatná eeprom", "eebad", 483),
("Oupn najn iks", "hello", 480),
("Tak zase příště!", "bye", 480),
("dvacet sekund", "timer20", 500),
("třicet sekund", "timer30", 501),
("A1,nízká", "a1_org", NO_ALTERNATE),
("A1,kritická", "a1_red", NO_ALTERNATE),
("A2,nízká", "a2_org", NO_ALTERNATE),
("A2,kritická", "a2_red", NO_ALTERNATE),
("A3,nízká", "a3_org", NO_ALTERNATE),
("A3,kritická", "a3_red", NO_ALTERNATE),
("A4,nízká", "a4_org", NO_ALTERNATE),
("A4,kritická", "a4_red", NO_ALTERNATE),
("nízký RF signál", "rssi_org", NO_ALTERNATE),
("kritický RF signál", "rssi_red", NO_ALTERNATE),
("problém s anténou rádia", "swr_red", NO_ALTERNATE),
("telemetrie ztracena", "telemko", NO_ALTERNATE),
("telemetrie je funkční", "telemok", NO_ALTERNATE),
("trenér port odpojen", "trainko", NO_ALTERNATE),
("trenér port připojen", "trainok", NO_ALTERNATE),
("senzor ztracen", "sensorko", NO_ALTERNATE),
("servo přetíženo", "servoko", NO_ALTERNATE),
("r f přebuzeno", "rxko", NO_ALTERNATE),
]:
systemSounds.append((s, filename(f, a)))
for i, (s, f) in enumerate([(u"podvozek je zasunut", "podvo0"),
(u"podvozek je vysunut", "podvo1"),
(u"klapky jsou zapnuty", "klapk1"),
(u"klapky jsou vypnuty", "klapk0"),
(u"trenér je zapnut", "trene1"),
(u"trenér je vypnutý", "trene0"),
(u"motor je vypnut", "motor0"),
(u"motor je aktivován", "motor1"),
(u"jsi příliš vysoko", "vysoko"),
(u"jsi příliš nízko", "nizko"),
(u"baterie modelu je vybitá", "bat0"),
(u"dochází palivo", "palivo"),
(u"nízký signál!", "nsigna"),
(u"kritický signál!", "ksigna"),
(u"rychlý režim aktivován", "rrychl"),
(u"termický režim aktivován", "rtermi"),
(u"normální režim aktivován", "rnorm"),
(u"režim start aktivován", "rstart"),
(u"režim přistání aktivován", "prista"),
(u"vario je zapnuto", "vario0"),
(u"vario je vypnuto", "vario1"),
(u"start povolen", "start1"),
(u"letový režim jedna", "fm-1"),
(u"letový režim dva", "fm-2"),
(u"letový režim tři", "fm-3"),
(u"letový režim čtyři", "fm-4"),
(u"letový režim pět", "fm-5"),
(u"letový režim šest", "fm-6"),
(u"letový režim sedm", "fm-7"),
(u"letový režim osm", "fm-8"),
for i, (s, f) in enumerate([("podvozek je zasunut", "podvo0"),
("podvozek je vysunut", "podvo1"),
("klapky jsou zapnuty", "klapk1"),
("klapky jsou vypnuty", "klapk0"),
("trenér je zapnut", "trene1"),
("trenér je vypnutý", "trene0"),
("motor je vypnut", "motor0"),
("motor je aktivován", "motor1"),
("jsi příliš vysoko", "vysoko"),
("jsi příliš nízko", "nizko"),
("baterie modelu je vybitá", "bat0"),
("dochází palivo", "palivo"),
("nízký signál!", "nsigna"),
("kritický signál!", "ksigna"),
("rychlý režim aktivován", "rrychl"),
("termický režim aktivován", "rtermi"),
("normální režim aktivován", "rnorm"),
("režim start aktivován", "rstart"),
("režim přistání aktivován", "prista"),
("vario je zapnuto", "vario0"),
("vario je vypnuto", "vario1"),
("start povolen", "start1"),
("letový režim jedna", "fm-1"),
("letový režim dva", "fm-2"),
("letový režim tři", "fm-3"),
("letový režim čtyři", "fm-4"),
("letový režim pět", "fm-5"),
("letový režim šest", "fm-6"),
("letový režim sedm", "fm-7"),
("letový režim osm", "fm-8"),
]):
sounds.append((s, filename(f, PROMPT_CUSTOM_BASE + i)))
+82 -82
View File
@@ -16,64 +16,64 @@ systemSounds.append(("hundert", filename(PROMPT_SYSTEM_BASE + 102)))
systemSounds.append(("tausend", filename(PROMPT_SYSTEM_BASE + 103)))
for i, s in enumerate(["komma", "und", "minus", "uhr", "minute", "minuten", "sekunde", "sekunden", "stunde", "stunden"]):
systemSounds.append((s, filename(PROMPT_SYSTEM_BASE + 104 + i)))
for i, (s, f) in enumerate([(u"Wolt","volt0"),
(u"Ampär", "amp0"),
(u"MilliAmpär", "mamp0"),
(u"Knoten", "knot0"),
(u"Meter pro sekunde", "mps0"),
(u"Fuss pro sekunde", "fps0"),
(u"Kilometer pro stunde", "kph0"),
(u"Meilen pro Stunde", "mph0"),
(u"Meter", "meter0"),
(u"Fuesse", "foot0"),
(u"Grad Celsius", "celsius0"),
(u"Grad Fahrenheit", "fahr0"),
(u"Prozent", "percent0"),
(u"Milliampär pro stunde", "mamph0"),
(u"Watt", "watt0"),
(u"Milli Watt", "mwatt0"),
(u"D B", "db0"),
(u"Drehzahl", "rpm0"),
(u"g", "g0"),
(u"Grad", "degree0"),
(u"radians", "rad0"),
(u"Milliliter", "ml0"),
(u"Unze", "founce0"),
(u"Stunde", "hour0"), (u"Stunden", "hour1"),
(u"Minute", "minute0"), (u"Minuten", "minute1"),
(u"Sekunde", "second0"), (u"Sekunden", "second1"),
for i, (s, f) in enumerate([("Wolt","volt0"),
("Ampär", "amp0"),
("MilliAmpär", "mamp0"),
("Knoten", "knot0"),
("Meter pro sekunde", "mps0"),
("Fuss pro sekunde", "fps0"),
("Kilometer pro stunde", "kph0"),
("Meilen pro Stunde", "mph0"),
("Meter", "meter0"),
("Fuesse", "foot0"),
("Grad Celsius", "celsius0"),
("Grad Fahrenheit", "fahr0"),
("Prozent", "percent0"),
("Milliampär pro stunde", "mamph0"),
("Watt", "watt0"),
("Milli Watt", "mwatt0"),
("D B", "db0"),
("Drehzahl", "rpm0"),
("g", "g0"),
("Grad", "degree0"),
("radians", "rad0"),
("Milliliter", "ml0"),
("Unze", "founce0"),
("Stunde", "hour0"), ("Stunden", "hour1"),
("Minute", "minute0"), ("Minuten", "minute1"),
("Sekunde", "second0"), ("Sekunden", "second1"),
]):
systemSounds.append((s, filename(f, PROMPT_SYSTEM_BASE + 114 + i)))
for s, f, a in [(u"Inaktivitätsalarm", "inactiv", 486),
(u"Senderspannung schwach", "lowbatt", 485),
(u"Gaskanal nicht Null, bitte prüfen", "thralert", 481),
(u"Schalter fehlpositioniert, bitte prüfen", "swalert", 482),
(u"EEPROM fehlerhaft", "eebad", NO_ALTERNATE),
(u"EEPROM formatiert", "eeformat", NO_ALTERNATE),
(u"Fehler", "error", NO_ALTERNATE),
(u"Trim zentriert", "midtrim", 495),
(u"Poti zentriert", "midpot", 496),
(u"Obere Trimmungsgrenze erreicht", "maxtrim", NO_ALTERNATE),
(u"Untere Trimmungsgrenze erreicht", "mintrim", NO_ALTERNATE),
(u"20 Sekunden", "timer20", 500),
(u"30 Sekunden", "timer30", 501),
(u"Senderstrom zu hoch!", "highmah", NO_ALTERNATE),
(u"Sendertemperatur zu hoch!", "hightemp", NO_ALTERNATE),
(u"A1 schwach!", "a1_org", NO_ALTERNATE),
(u"A1 kritisch!", "a1_red", NO_ALTERNATE),
(u"A2 schwach!", "a2_org", NO_ALTERNATE),
(u"A2 kritisch!", "a2_red", NO_ALTERNATE),
(u"A3 schwach!", "a3_org", NO_ALTERNATE),
(u"A3 kritisch!", "a3_red", NO_ALTERNATE),
(u"A4 schwach!", "a4_org", NO_ALTERNATE),
(u"A4 kritisch!", "a4_red", NO_ALTERNATE),
(u"Funksignal schwach!", "rssi_org", NO_ALTERNATE),
(u"Funksignal kritisch!", "rssi_red", NO_ALTERNATE),
(u"Problem mit der Sender Antenne", "swr_red", NO_ALTERNATE),
(u"Telemetrie verloren", "telemko", NO_ALTERNATE),
(u"Telemetrie wiederhergestellt", "telemok", NO_ALTERNATE),
(u"Schülersignal verloren", "trainko", NO_ALTERNATE),
(u"Schülersignal wiederhergestellt", "trainok", NO_ALTERNATE),
for s, f, a in [("Inaktivitätsalarm", "inactiv", 486),
("Senderspannung schwach", "lowbatt", 485),
("Gaskanal nicht Null, bitte prüfen", "thralert", 481),
("Schalter fehlpositioniert, bitte prüfen", "swalert", 482),
("EEPROM fehlerhaft", "eebad", NO_ALTERNATE),
("EEPROM formatiert", "eeformat", NO_ALTERNATE),
("Fehler", "error", NO_ALTERNATE),
("Trim zentriert", "midtrim", 495),
("Poti zentriert", "midpot", 496),
("Obere Trimmungsgrenze erreicht", "maxtrim", NO_ALTERNATE),
("Untere Trimmungsgrenze erreicht", "mintrim", NO_ALTERNATE),
("20 Sekunden", "timer20", 500),
("30 Sekunden", "timer30", 501),
("Senderstrom zu hoch!", "highmah", NO_ALTERNATE),
("Sendertemperatur zu hoch!", "hightemp", NO_ALTERNATE),
("A1 schwach!", "a1_org", NO_ALTERNATE),
("A1 kritisch!", "a1_red", NO_ALTERNATE),
("A2 schwach!", "a2_org", NO_ALTERNATE),
("A2 kritisch!", "a2_red", NO_ALTERNATE),
("A3 schwach!", "a3_org", NO_ALTERNATE),
("A3 kritisch!", "a3_red", NO_ALTERNATE),
("A4 schwach!", "a4_org", NO_ALTERNATE),
("A4 kritisch!", "a4_red", NO_ALTERNATE),
("Funksignal schwach!", "rssi_org", NO_ALTERNATE),
("Funksignal kritisch!", "rssi_red", NO_ALTERNATE),
("Problem mit der Sender Antenne", "swr_red", NO_ALTERNATE),
("Telemetrie verloren", "telemko", NO_ALTERNATE),
("Telemetrie wiederhergestellt", "telemok", NO_ALTERNATE),
("Schülersignal verloren", "trainko", NO_ALTERNATE),
("Schülersignal wiederhergestellt", "trainok", NO_ALTERNATE),
]:
systemSounds.append((s, filename(f, a)))
for i, s in enumerate(["Uhr", "Uhr", "Sender", "Empfang", "A1", "A2", "Hoehe", "Motor",
@@ -81,31 +81,31 @@ for i, s in enumerate(["Uhr", "Uhr", "Sender", "Empfang", "A1", "A2", "Hoehe", "
"Zellen gesamt", "Spannung", "Strom", "Verbrauch", "Power", "Beschleunigung X", "Beschleunigung Y", "Beschleunigung Z",
"Richtung", "Variometer", "Minimum", "Maximum"]):
systemSounds.append((s, filename(PROMPT_SYSTEM_BASE + 134 + i)))
for i, (s, f) in enumerate([(u"Fahrwerk eingezogen", "gearup"),
(u"Fahrwerk ausgefahren", "geardn"),
(u"Klappen eingefahren", "flapup"),
(u"Klappen ausgefahren", "flapdn"),
(u"Landung", "lnding"),
(u"Trainer-Modus ein", "trnon"),
(u"Trainer-Modus aus", "trnoff"),
(u"Motor aus", "engoff"),
(u"Motor an", "engon"),
(u"zu hoch", "tohigh"),
(u"zu niedrig", "tolow"),
(u"Batterie schwach", "lowbatt"),
(u"Butterfly ein", "crowon"),
(u"Butterfly aus", "crowof"),
(u"Geschwindigkeits-Modus ist aktiviert", "fm-spd"),
(u"Thermik-Modus ist aktiviert", "fm-thm"),
(u"Normal-Modus ist aktiviert", "fm-nrm"),
(u"Flugmodus 1", "fm-1"),
(u"Flugmodus 2", "fm-2"),
(u"Flugmodus 3", "fm-3"),
(u"Flugmodus 4", "fm-4"),
(u"Flugmodus 5", "fm-5"),
(u"Flugmodus 6", "fm-6"),
(u"Flugmodus 7", "fm-7"),
(u"Flugmodus 8", "fm-8"),
(u"Flugmodus 9", "fm-9"),
for i, (s, f) in enumerate([("Fahrwerk eingezogen", "gearup"),
("Fahrwerk ausgefahren", "geardn"),
("Klappen eingefahren", "flapup"),
("Klappen ausgefahren", "flapdn"),
("Landung", "lnding"),
("Trainer-Modus ein", "trnon"),
("Trainer-Modus aus", "trnoff"),
("Motor aus", "engoff"),
("Motor an", "engon"),
("zu hoch", "tohigh"),
("zu niedrig", "tolow"),
("Batterie schwach", "lowbatt"),
("Butterfly ein", "crowon"),
("Butterfly aus", "crowof"),
("Geschwindigkeits-Modus ist aktiviert", "fm-spd"),
("Thermik-Modus ist aktiviert", "fm-thm"),
("Normal-Modus ist aktiviert", "fm-nrm"),
("Flugmodus 1", "fm-1"),
("Flugmodus 2", "fm-2"),
("Flugmodus 3", "fm-3"),
("Flugmodus 4", "fm-4"),
("Flugmodus 5", "fm-5"),
("Flugmodus 6", "fm-6"),
("Flugmodus 7", "fm-7"),
("Flugmodus 8", "fm-8"),
("Flugmodus 9", "fm-9"),
]):
sounds.append((s, filename(f, PROMPT_CUSTOM_BASE + i)))
+67 -67
View File
@@ -46,74 +46,74 @@ for i, s in enumerate(["point zero", "point one", "point two", "point three",
"point four", "point five", "point six",
"point seven", "point eight", "point nine"]):
systemSounds.append((s, filename(PROMPT_SYSTEM_BASE + 167 + i)))
for s, f, a in [(u"trim center", "midtrim", 495),
(u"maximum trim reached", "maxtrim", NO_ALTERNATE),
(u"minimum trim reached", "mintrim", NO_ALTERNATE),
(u"timer 1 elapsed", "timovr1", NO_ALTERNATE),
(u"timer 2 elapsed", "timovr2", NO_ALTERNATE),
(u"timer 3 elapsed", "timovr3", NO_ALTERNATE),
(u"transmitter battery low", "lowbatt", 485),
(u"inactivity alarm", "inactiv", 486),
(u"throttle warning", "thralert", 481),
(u"switch warning", "swalert", 482),
(u"bad eeprom", "eebad", 483),
(u"Welcome to open tea ex!", "hello", 480),
(u"RF signal, low", "rssi_org", NO_ALTERNATE),
(u"RF signal, critical", "rssi_red", NO_ALTERNATE),
(u"radio antenna defective", "swr_red", NO_ALTERNATE),
(u"telemetry lost", "telemko", NO_ALTERNATE),
(u"telemetry recovered", "telemok", NO_ALTERNATE),
(u"trainer signal lost", "trainko", NO_ALTERNATE),
(u"trainer signal recovered", "trainok", NO_ALTERNATE),
(u"sensor lost", "sensorko", NO_ALTERNATE),
(u"servo overload", "servoko", NO_ALTERNATE),
(u"power overload", "rxko", NO_ALTERNATE),
for s, f, a in [("trim center", "midtrim", 495),
("maximum trim reached", "maxtrim", NO_ALTERNATE),
("minimum trim reached", "mintrim", NO_ALTERNATE),
("timer 1 elapsed", "timovr1", NO_ALTERNATE),
("timer 2 elapsed", "timovr2", NO_ALTERNATE),
("timer 3 elapsed", "timovr3", NO_ALTERNATE),
("transmitter battery low", "lowbatt", 485),
("inactivity alarm", "inactiv", 486),
("throttle warning", "thralert", 481),
("switch warning", "swalert", 482),
("bad eeprom", "eebad", 483),
("Welcome to open tea ex!", "hello", 480),
("RF signal, low", "rssi_org", NO_ALTERNATE),
("RF signal, critical", "rssi_red", NO_ALTERNATE),
("radio antenna defective", "swr_red", NO_ALTERNATE),
("telemetry lost", "telemko", NO_ALTERNATE),
("telemetry recovered", "telemok", NO_ALTERNATE),
("trainer signal lost", "trainko", NO_ALTERNATE),
("trainer signal recovered", "trainok", NO_ALTERNATE),
("sensor lost", "sensorko", NO_ALTERNATE),
("servo overload", "servoko", NO_ALTERNATE),
("power overload", "rxko", NO_ALTERNATE),
]:
systemSounds.append((s, filename(f, a)))
for i, (s, f) in enumerate([(u"gear!, up!", "gearup"),
(u"gear!, down!", "geardn"),
(u"flaps!, up!", "flapup"),
(u"flaps!, down!", "flapdn"),
(u"spoiler!, up!", "splrup"),
(u"spoiler!, down!", "splrdn"),
(u"trainer!, on!", "trnon"),
(u"trainer!, off!", "trnoff"),
(u"engine!, off!", "engoff"),
(u"too. high!", "tohigh"),
(u"too. low!", "tolow"),
(u"low. battery!", "lowbat"),
(u"crow!, on!", "crowon"),
(u"crow!, off!", "crowof"),
(u"rf. signal!, low!", "siglow"),
(u"rf. signal!, critical!", "sigcrt"),
(u"high. speed. mode!, active", "spdmod"),
(u"thermal. mode!, on", "thmmod"),
(u"normal. mode!, on", "nrmmod"),
(u"landing. mode!, on", "lnding"),
(u"acro. mode!, on", "acro"),
(u"flight. mode!, one", "fm-1"),
(u"flight. mode!, two", "fm-2"),
(u"flight. mode!, three", "fm-3"),
(u"flight. mode!, four", "fm-4"),
(u"flight. mode!, five", "fm-5"),
(u"flight. mode!, six", "fm-6"),
(u"flight. mode!, seven", "fm-7"),
(u"flight. mode!, eight", "fm-8"),
(u"vario!, on", "vrion"),
(u"vario!, off", "vrioff"),
(u"flight mode!, power", "fm-pwr"),
(u"flight mode!, land", "fm-lnd"),
(u"flight mode!, float", "fm-flt"),
(u"flight mode!, speed", "fm-spd"),
(u"flight mode!, fast", "fm-fst"),
(u"flight mode!, normal", "fm-nrm"),
(u"flight mode!, cruise", "fm-crs"),
(u"flight mode!, acro", "fm-acr"),
(u"flight mode!, race", "fm-rce"),
(u"flight mode!, launch", "fm-lch"),
(u"flight mode!, ping", "fm-png"),
(u"flight mode!, thermal", "fm-thm"),
(u"flight mode!, thermal left", "fm-thl"),
(u"flight mode!, thermal right", "fm-thr"),
for i, (s, f) in enumerate([("gear!, up!", "gearup"),
("gear!, down!", "geardn"),
("flaps!, up!", "flapup"),
("flaps!, down!", "flapdn"),
("spoiler!, up!", "splrup"),
("spoiler!, down!", "splrdn"),
("trainer!, on!", "trnon"),
("trainer!, off!", "trnoff"),
("engine!, off!", "engoff"),
("too. high!", "tohigh"),
("too. low!", "tolow"),
("low. battery!", "lowbat"),
("crow!, on!", "crowon"),
("crow!, off!", "crowof"),
("rf. signal!, low!", "siglow"),
("rf. signal!, critical!", "sigcrt"),
("high. speed. mode!, active", "spdmod"),
("thermal. mode!, on", "thmmod"),
("normal. mode!, on", "nrmmod"),
("landing. mode!, on", "lnding"),
("acro. mode!, on", "acro"),
("flight mode one", "fm-1"),
("flight mode two", "fm-2"),
("flight mode three", "fm-3"),
("flight mode four", "fm-4"),
("flight mode five", "fm-5"),
("flight mode six", "fm-6"),
("flight mode seven", "fm-7"),
("flight mode eight", "fm-8"),
("vario!, on", "vrion"),
("vario!, off", "vrioff"),
("flight mode power", "fm-pwr"),
("flight mode land", "fm-lnd"),
("flight mode float", "fm-flt"),
("flight mode speed", "fm-spd"),
("flight mode fast", "fm-fst"),
("flight mode normal", "fm-nrm"),
("flight mode cruise", "fm-crs"),
("flight mode acro", "fm-acr"),
("flight mode race", "fm-rce"),
("flight mode launch", "fm-lch"),
("flight mode ping", "fm-png"),
("flight mode thermal", "fm-thm"),
("flight mode thermal left", "fm-thl"),
("flight mode thermal right", "fm-thr"),
]):
sounds.append((s, filename(f, PROMPT_CUSTOM_BASE + i)))
+80 -80
View File
@@ -22,89 +22,89 @@ systemSounds.append(("nuevecientos", filename(PROMPT_SYSTEM_BASE + 109)))
systemSounds.append(("mil", filename(PROMPT_SYSTEM_BASE + 110)))
for i, s in enumerate(["coma", "un", "una", "y", "meno", "hora", "horas", "minuto", "minutos", "segundo", "segundos"]):
systemSounds.append((s, filename(PROMPT_SYSTEM_BASE + 111 + i)))
for i, (s, f) in enumerate([(u"Voltio","volt0"),
(u"ampério", "amp0"),
(u"miliamperios", "mamp0"),
(u"knots", "knot0"),
(u"metros por segundo", "mps0"),
(u"pie por segundo", "fps0"),
(u"kilómetro por hora", "kph0"),
(u"millas por hora", "mph0"),
(u"metros", "meter0"),
(u"pie", "foot0"),
(u"grados", "celsius0"),
(u"fahrenheit", "fahr0"),
(u"por ciento", "percent0"),
(u"miliamperios por hora", "mamph0"),
(u"vatio", "watt0"),
(u"millivatio", "mwatt0"),
(u"D B", "db0"),
(u"R P M", "rpm0"),
(u"g", "g0"),
(u"grados", "degree0"),
(u"radianes ", "rad0"),
(u"mililitro", "ml0"),
(u"onzas", "founce0"),
(u"horas", "hour0"),
(u"minutos", "minute0"),
(u"segundos", "second0"),
for i, (s, f) in enumerate([("Voltio","volt0"),
("ampério", "amp0"),
("miliamperios", "mamp0"),
("knots", "knot0"),
("metros por segundo", "mps0"),
("pie por segundo", "fps0"),
("kilómetro por hora", "kph0"),
("millas por hora", "mph0"),
("metros", "meter0"),
("pie", "foot0"),
("grados", "celsius0"),
("fahrenheit", "fahr0"),
("por ciento", "percent0"),
("miliamperios por hora", "mamph0"),
("vatio", "watt0"),
("millivatio", "mwatt0"),
("D B", "db0"),
("R P M", "rpm0"),
("g", "g0"),
("grados", "degree0"),
("radianes ", "rad0"),
("mililitro", "ml0"),
("onzas", "founce0"),
("horas", "hour0"),
("minutos", "minute0"),
("segundos", "second0"),
]):
systemSounds.append((s, filename(f, PROMPT_SYSTEM_BASE + 122 + i)))
for s, f, a in [(u"me tienes abandonada", "inactiv", 486),
(u"batería del transmisor baja", "lowbatt", 485),
(u"El acelerador está activado, por favor, corrijalo", "thralert", 481),
(u"Los interruptores no están en la posición correcta, por favor corrijalo", "swalert", 482),
(u"eeprom corrompida", "eebad", NO_ALTERNATE),
(u"Formateo de eeprom en curso", "eeformat", NO_ALTERNATE),
(u"error", "error", NO_ALTERNATE),
(u"trim centrado", "midtrim", 495),
(u"potenciómetro centrado", "midpot", 496),
(u"trim al máximo", "maxtrim", NO_ALTERNATE),
(u"trim al mínima", "mintrim", NO_ALTERNATE),
(u"20 segundos", "timer20", 500),
(u"30 segundos", "timer30", 501),
(u"assorbimiento elevado", "highmah", NO_ALTERNATE),
(u"temperatura elevada", "hightemp", NO_ALTERNATE),
(u"Alarma A1", "a1_org", NO_ALTERNATE),
(u"A1 crítica", "a1_red", NO_ALTERNATE),
(u"Alarma A2", "a2_org", NO_ALTERNATE),
(u"A2 crítica", "a2_red", NO_ALTERNATE),
(u"recepcion de señal baja", "rssi_org", NO_ALTERNATE),
(u"recepción de señal crítica", "rssi_red", NO_ALTERNATE),
(u"Problemas con la antena del transmisor", "swr_red", NO_ALTERNATE),
(u"Sin telemetría", "telemko", NO_ALTERNATE),
(u"Telemetría disponible", "telemok", NO_ALTERNATE),
systemSounds.append((s, filename(f, PROMPT_SYSTEM_BASE + 122 + i)))
for s, f, a in [("me tienes abandonada", "inactiv", 486),
("batería del transmisor baja", "lowbatt", 485),
("El acelerador está activado, por favor, corrijalo", "thralert", 481),
("Los interruptores no están en la posición correcta, por favor corrijalo", "swalert", 482),
("eeprom corrompida", "eebad", NO_ALTERNATE),
("Formateo de eeprom en curso", "eeformat", NO_ALTERNATE),
("error", "error", NO_ALTERNATE),
("trim centrado", "midtrim", 495),
("potenciómetro centrado", "midpot", 496),
("trim al máximo", "maxtrim", NO_ALTERNATE),
("trim al mínima", "mintrim", NO_ALTERNATE),
("20 segundos", "timer20", 500),
("30 segundos", "timer30", 501),
("assorbimiento elevado", "highmah", NO_ALTERNATE),
("temperatura elevada", "hightemp", NO_ALTERNATE),
("Alarma A1", "a1_org", NO_ALTERNATE),
("A1 crítica", "a1_red", NO_ALTERNATE),
("Alarma A2", "a2_org", NO_ALTERNATE),
("A2 crítica", "a2_red", NO_ALTERNATE),
("recepcion de señal baja", "rssi_org", NO_ALTERNATE),
("recepción de señal crítica", "rssi_red", NO_ALTERNATE),
("Problemas con la antena del transmisor", "swr_red", NO_ALTERNATE),
("Sin telemetría", "telemko", NO_ALTERNATE),
("Telemetría disponible", "telemok", NO_ALTERNATE),
]:
systemSounds.append((s, filename(f, a)))
for i, s in enumerate([u"cronómetro", u"cronómetro", u"transmisión", u"recepción", u"A1", u"A2", u"altitud", u"motor",
u"combustible", u"temperatura", u"temperatura", u"velocidad", u"distancia", u"altitude", u"célula lipo",
u"Total lipo", u"voltaje", u"corriente", u"consumo", u"potencia", u"aceleración X", u"aceleración Y", u"aceleración Z",
u"dirección", u"variómetro", u"minimo", u"máximo"]):
for i, s in enumerate(["cronómetro", "cronómetro", "transmisión", "recepción", "A1", "A2", "altitud", "motor",
"combustible", "temperatura", "temperatura", "velocidad", "distancia", "altitude", "célula lipo",
"Total lipo", "voltaje", "corriente", "consumo", "potencia", "aceleración X", "aceleración Y", "aceleración Z",
"dirección", "variómetro", "minimo", "máximo"]):
systemSounds.append((s, filename(PROMPT_SYSTEM_BASE + 141 + i)))
for i, (s, f) in enumerate([(u"tren arriba.", "gearup"),
(u"tren abajo.", "geardn"),
(u"flaps arriba", "flapup"),
(u"flaps abajo", "flapdn"),
(u"aterrizaje", "attero"),
(u"modo de entrenamiento activado", "trnon"),
(u"modo de entrenamiento deshabilitado", "trnoff"),
(u"motor apagado", "engoff"),
(u"muy alto", "tohigh"),
(u"muy bajo", "tolow"),
(u"bateria baja", "lowbat"),
(u"crou, activo", "crowon"),
(u"crou, desligado", "crowof"),
(u"modo de velocidad", "spdmod"),
(u"modo de térmica", "thmmod"),
(u"modo de vuelo normal", "nrmmod"),
(u"fase de vuelo 1", "fltmd1"),
(u"fase de vuelo 2", "fltmd2"),
(u"fase de vuelo 3", "fltmd3"),
(u"fase de vuelo 4", "fltmd4"),
(u"fase de vuelo 5", "fltmd5"),
(u"fase de vuelo 6", "fltmd6"),
(u"fase de vuelo 7", "fltmd7"),
(u"fase de vuelo 8", "fltmd8"),
(u"fase de vuelo 9", "fltmd9"),
for i, (s, f) in enumerate([("tren arriba.", "gearup"),
("tren abajo.", "geardn"),
("flaps arriba", "flapup"),
("flaps abajo", "flapdn"),
("aterrizaje", "attero"),
("modo de entrenamiento activado", "trnon"),
("modo de entrenamiento deshabilitado", "trnoff"),
("motor apagado", "engoff"),
("muy alto", "tohigh"),
("muy bajo", "tolow"),
("bateria baja", "lowbat"),
("crou, activo", "crowon"),
("crou, desligado", "crowof"),
("modo de velocidad", "spdmod"),
("modo de térmica", "thmmod"),
("modo de vuelo normal", "nrmmod"),
("fase de vuelo 1", "fltmd1"),
("fase de vuelo 2", "fltmd2"),
("fase de vuelo 3", "fltmd3"),
("fase de vuelo 4", "fltmd4"),
("fase de vuelo 5", "fltmd5"),
("fase de vuelo 6", "fltmd6"),
("fase de vuelo 7", "fltmd7"),
("fase de vuelo 8", "fltmd8"),
("fase de vuelo 9", "fltmd9"),
]):
sounds.append((s, filename(f, PROMPT_CUSTOM_BASE + i)))
+88 -59
View File
@@ -15,70 +15,99 @@ for i, s in enumerate(["une", "onze", "vingt et une", "trente et une", "quarante
systemSounds.append((s, filename(PROMPT_SYSTEM_BASE + 110 + i)))
for i, s in enumerate(["virgule", "et", "moins", "minuit", "midi"]):
systemSounds.append((s, filename(PROMPT_SYSTEM_BASE + 119 + i)))
for i, (s, f) in enumerate([(u"volts","volt0"),
(u"ampères", "amp0"),
(u"milli ampères", "mamp0"),
(u"noeud", "knot0"),
(u"mètres seconde", "mps0"),
(u"pieds par seconde", "fps0"),
(u"kilomètre heure", "kph0"),
(u"miles par heure", "mph0"),
(u"mètres", "meter0"),
(u"pieds", "foot0"),
(u"degrés", "celsius0"),
(u"degrés fahrenheit", "degf0"),
(u"pourcents", "percent0"),
(u"milli ampères heure", "mamph0"),
(u"watt", "watt0"),
(u"milli watt", "mwatt0"),
(u"d b", "db0"),
(u"tours minute", "rpm0"),
(u"g", "g0"),
(u"degrés", "degree0"),
(u"radians", "rad0"),
(u"millilitres", "ml0"),
(u"onces", "founce0"),
(u"heure", "hour0"),
(u"minute", "minute0"),
(u"seconde", "second0"),
for i, (s, f) in enumerate([("volts","volt0"),
("ampères", "amp0"),
("milli ampères", "mamp0"),
("noeud", "knot0"),
("mètres seconde", "mps0"),
("pieds par seconde", "fps0"),
("kilomètre heure", "kph0"),
("miles par heure", "mph0"),
("mètres", "meter0"),
("pieds", "foot0"),
("degrés", "celsius0"),
("degrés fahrenheit", "degf0"),
("pourcents", "percent0"),
("milli ampères heure", "mamph0"),
("watt", "watt0"),
("milli watt", "mwatt0"),
("d b", "db0"),
("tours minute", "rpm0"),
("g", "g0"),
("degrés", "degree0"),
("radians", "rad0"),
("millilitres", "ml0"),
("onces", "founce0"),
("heure", "hour0"),
("minute", "minute0"),
("seconde", "second0"),
]):
systemSounds.append((s, filename(f, PROMPT_SYSTEM_BASE + 125 + i)))
for i, s in enumerate(["virgule 0", "virgule 1", "virgule 2", "virgule 3", "virgule 4", "virgule 5", "virgule 6", "virgule 7", "virgule 8", "virgule 9"]):
systemSounds.append((s, filename(PROMPT_SYSTEM_BASE + 180 + i)))
for s, f, a in [(u"Trim centré", "midtrim", 495),
(u"Trim maximum atteint", "maxtrim", NO_ALTERNATE),
(u"Trim minimum atteint", "mintrim", NO_ALTERNATE),
(u"Chrono 1 à 0", "timovr1", NO_ALTERNATE),
(u"Chrono 2 à 0", "timovr2", NO_ALTERNATE),
(u"Chrono 3 à 0", "timovr3", NO_ALTERNATE),
(u"Batterie radio faible !", "lowbatt", 485),
(u"Radio inactive !", "inactiv", 486),
(u"Alerte manche des gaz", "thralert", 481),
(u"Alerte inters", "swalert", 482),
(u"éprome corrompue", "eebad", 483),
(u"Bienvenue sur Open Thé Hix!", "hello", 480),
(u"Signal RF, faible", "rssi_org", NO_ALTERNATE),
(u"Signal RF, critique", "rssi_red", NO_ALTERNATE),
(u"Antenne défectueuse", "swr_red", NO_ALTERNATE),
(u"Plus de télémétrie", "telemko", NO_ALTERNATE),
(u"Télémétrie retrouvée", "telemok", NO_ALTERNATE),
(u"Signal écolage perdu", "trainko", NO_ALTERNATE),
(u"Signal écolage retrouvé", "trainok", NO_ALTERNATE),
(u"Sonde de télémétrie perdue", "sensorko", NO_ALTERNATE),
(u"Servo en surcharge", "servoko", NO_ALTERNATE),
(u"Surcharge réception", "rxko", NO_ALTERNATE),
for s, f, a in [("Trim centré", "midtrim", 495),
("Trim maximum atteint", "maxtrim", NO_ALTERNATE),
("Trim minimum atteint", "mintrim", NO_ALTERNATE),
("Chrono 1 à 0", "timovr1", NO_ALTERNATE),
("Chrono 2 à 0", "timovr2", NO_ALTERNATE),
("Chrono 3 à 0", "timovr3", NO_ALTERNATE),
("Batterie radio faible !", "lowbatt", 485),
("Radio inactive !", "inactiv", 486),
("Alerte manche des gaz", "thralert", 481),
("Alerte inters", "swalert", 482),
("éprome corrompue", "eebad", 483),
("Bienvenue sur o pun t x", "hello", 480),
("Signal RF, faible", "rssi_org", NO_ALTERNATE),
("Signal RF, critique", "rssi_red", NO_ALTERNATE),
("Antenne défectueuse", "swr_red", NO_ALTERNATE),
("Plus de télémétrie", "telemko", NO_ALTERNATE),
("Télémétrie retrouvée", "telemok", NO_ALTERNATE),
("Signal écolage perdu", "trainko", NO_ALTERNATE),
("Signal écolage retrouvé", "trainok", NO_ALTERNATE),
("Sonde de télémétrie perdue", "sensorko", NO_ALTERNATE),
("Servo en surcharge", "servoko", NO_ALTERNATE),
("Surcharge réception", "rxko", NO_ALTERNATE),
]:
systemSounds.append((s, filename(f, a)))
for i, (s, f) in enumerate([(u"altitude", "altitude"),
(u"température moteur", "moteur"),
(u"température contrôleur", "cntrleur"),
(u"train rentré", "gearup"),
(u"train sorti", "geardn"),
(u"volets rentrés", "flapup"),
(u"volets sortis", "flapdn"),
(u"atterrissage", "attero"),
(u"écolage", "trnon"),
(u"fin écolage", "trnoff"),
(u"moteur coupé", "engoff"),
for i, (s, f) in enumerate([("altitude", "altitude"),
("température moteur", "moteur"),
("température contrôleur", "cntrleur"),
("train rentré", "gearup"),
("train sorti", "geardn"),
("volets rentrés", "flapup"),
("volets sortis", "flapdn"),
("atterrissage", "attero"),
("écolage", "trnon"),
("fin écolage", "trnoff"),
("moteur coupé", "engoff"),
("high. speed. mode!, active", "spdmod"),
("thermal. mode!, on", "thmmod"),
("normal. mode!, on", "nrmmod"),
("landing. mode!, on", "lnding"),
("mode acro", "acro"),
("mode de vol un", "fm-1"),
("mode de vol deux", "fm-2"),
("mode de vol trois", "fm-3"),
("mode de vol quatre", "fm-4"),
("mode de vol 5", "fm-5"),
("mode de vol 6", "fm-6"),
("mode de vol sept", "fm-7"),
("mode de vol 8", "fm-8"),
("vario activé", "vrion"),
("vario désactivé", "vrioff"),
("mode de vol puissance", "fm-pwr"),
("mode de vol attérissage", "fm-lnd"),
("mode de vol amérissage", "fm-flt"),
("mode de vol vitesse", "fm-spd"),
("mode de vol rapide", "fm-fst"),
("mode de vol normal", "fm-nrm"),
("mode de vol de croisière", "fm-crs"),
("mode de vol acro", "fm-acr"),
("mode de vol course", "fm-rce"),
("mode de vol lancé", "fm-lch"),
("mode de vol ping", "fm-png"),
("mode de vol thermique", "fm-thm"),
("mode de vol thermique gauche", "fm-thl"),
("mode de vol thermique droit", "fm-thr"),
]):
sounds.append((s, filename(f, PROMPT_CUSTOM_BASE + i)))

Some files were not shown because too many files have changed in this diff Show More