diff --git a/CMakeLists.txt b/CMakeLists.txt index a76f6cd17..791a42731 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 "0034") +set(SDCARD_REVISION "0035") set(SDCARD_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}V${SDCARD_REVISION}) cmake_minimum_required(VERSION 2.8) diff --git a/CREDITS.txt b/CREDITS.txt index 95dc3e6a3..3136f7b6e 100644 --- a/CREDITS.txt +++ b/CREDITS.txt @@ -1,6 +1,7 @@ [Main developers] Bertrand Songis (bsongis) André Bernet (kilrah) +JC D. (3djc) Michael Blandford Damjan Adamic (projectkk2glider) Franck Aguerre (jivarofad) @@ -9,6 +10,7 @@ Martin Hotař (mhotar) Maxim (Max) Paperno (mpaperno) Arne Schwabe (schwabe) Daniel Gorbea (dgatf) +Neil Horne (elecpower) [Translators] [fr] Sebastien Charpentier (LapinFou) @@ -1942,3 +1944,152 @@ Miklos Turcsin Edward Skerness Stefano Perinetti Toni Marchante +Stuart Olson +Peter Campbell +Keith Wood +Leo Duflou +Michael Florey +Gerhard Weixelbaumer +Peter K Lehotsky +Elisha Jones +Joerg Sattler +paul42 +Pascal Heg +Bjorn Sorenssen +Chris Payne +Pascal Afflard +Robert Boboryko +Chris Whitehead +David Bradley +Ian Lever +Phillip Barber +Jan Bronee +N Haasnoot +Rick Smith +Randall Grant +Patrick Degouy +Piotr Zdanowski +David Gardner +TMac FPV +Bernard Thompson +Mark Sutton +Darren J Crane +Michael Keyes +Magnus Borg +David Lorentzen +Antony Smith +Aleksandr Sarkisov +Johannes Kuhne +Kathleen Cilluffo +David Hoffmann +Alan Porter +Arlé Mooldijk +Tenbones +Kim Bitsch Lauridsen +Arthur Costerus +Peter Harvey +John Simpson +Landy de los Santos +Graham Ridley +Schenk Peter +Joseph Rex +Richard Honeywell +Roy Nixon +Andrew Shewan +David Bradley +Alan Micklethwaite +Susan Siegel +Stephen Evans +William Hallman +Franck Michel +László Gajcsi (monthly) +Danny Koch +Robert Martin +Gavin Meerwald +Frédéric Maix +Frank Steinberg +Kevin Berkefeld +Marccos Colon +Kerry Reynolds +Kim Jeppesen +Arthur Peters +Andrew Lowes +Anthony Hallo +Bill Hill +Gerard Falaise +Kevin Raynor +Lorenzo gh +Jan Landeweer +David Bland +Manuel Spoerri +Jeff Jacobs +David Thorne +Maddox Philip +James Jewitt +Justin Digby +John Magnuson (monthly) +Holger Lippert +Hubert Huber +David Blum +Noam Kfir +Mats gårdstad friberg +Jesper Frickmann +Alan Bunker +Emanuel Kircher +Barry Andersen +Gabriel Formanek +Timothy Justiniano +Kelvin Garcia Urbina +Jan Lau +Choon Wei Jonathan Tan +Daniel Navas +Ray Moss +Markus Frielingsdorf +Michael Hirschauer +Jesse Frey +Philipp Koch +Robert Rubio +Dennis G Miller +Leonardo Garcia Osuna +Antonio Carrasco Pastor +Musa Pinar +Jens Moder +Josef de Beer +Chad Mofford +Pim Pouw +Kenth Jonsson +Gordon Westfall +Jean-Michel Saves +Roberto Orsello +Luboš Konvalinka +Lawrence Dorn +Michael Dittmann +Bernd Schmiedel +Raoul Piccioli +Uwe Probst +Glendon Satchell +Trevor Collins +Horst Grashauser +Miguel José Cárdenas Herrera +Mike Jennings +José Bernardo +Carlos Dangle +Gordon Evans +Pablo Peinado Abad +Carl Payne +Adam Sosnowski +Гасак Сергей +SaltCtyRacingFPV +Georg Bernhardt +James Mildenhall +Dave Plummer +Ivan Mokris +Patrick Daniels +Stuart Olson +Cory Znebel +Andrey Yarovoy +Christian Pons +Burt Pickard-Richardson +Michal Mesaros +Conrad Young +Martin Mathes diff --git a/companion/src/constants.h b/companion/src/constants.h index d2d32a745..b635f2d23 100644 --- a/companion/src/constants.h +++ b/companion/src/constants.h @@ -71,6 +71,7 @@ #define CPN_STR_APP_SETTINGS_FILTER CPN_STR_APP_SETTINGS_FILES % " (*.ini)" #define CPN_STR_UNKNOWN_ITEM "???" +#define CPN_STR_NONE_ITEM "----" #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. diff --git a/companion/src/datamodels/rawitemdatamodels.cpp b/companion/src/datamodels/rawitemdatamodels.cpp index 1cba1c180..d7c1b6682 100644 --- a/companion/src/datamodels/rawitemdatamodels.cpp +++ b/companion/src/datamodels/rawitemdatamodels.cpp @@ -30,7 +30,7 @@ RawSourceItemModel::RawSourceItemModel(const GeneralSettings * const generalSett Firmware * fw = getCurrentFirmware(); addItems(SOURCE_TYPE_NONE, RawSource::NoneGroup, 1); - for (int i=0; i < fw->getCapability(LuaScripts); i++) + for (int i = 0; i < fw->getCapability(LuaScripts); i++) addItems(SOURCE_TYPE_LUA_OUTPUT, RawSource::ScriptsGroup, fw->getCapability(LuaOutputsPerScript), i * 16); addItems(SOURCE_TYPE_VIRTUAL_INPUT, RawSource::InputsGroup, fw->getCapability(VirtualInputs)); addItems(SOURCE_TYPE_STICK, RawSource::SourcesGroup, board.getCapability(Board::MaxAnalogs)); @@ -43,7 +43,7 @@ RawSourceItemModel::RawSourceItemModel(const GeneralSettings * const generalSett addItems(SOURCE_TYPE_PPM, RawSource::SourcesGroup, fw->getCapability(TrainerInputs)); addItems(SOURCE_TYPE_CH, RawSource::SourcesGroup, fw->getCapability(Outputs)); addItems(SOURCE_TYPE_SPECIAL, RawSource::TelemGroup, 5); - addItems(SOURCE_TYPE_TELEMETRY, RawSource::TelemGroup, CPN_MAX_SENSORS * 3); + addItems(SOURCE_TYPE_TELEMETRY, RawSource::TelemGroup, fw->getCapability(Sensors) * 3); addItems(SOURCE_TYPE_GVAR, RawSource::GVarsGroup, fw->getCapability(Gvars)); } @@ -67,10 +67,14 @@ void RawSourceItemModel::addItems(const RawSourceType & type, const int group, c } } -void RawSourceItemModel::update() const +void RawSourceItemModel::update() { - for (int i=0; i < rowCount(); ++i) + emit dataAboutToBeUpdated(); + + for (int i = 0; i < rowCount(); ++i) setDynamicItemData(item(i), RawSource(item(i)->data(ItemIdRole).toInt())); + + emit dataUpdateComplete(); } @@ -86,7 +90,7 @@ RawSwitchItemModel::RawSwitchItemModel(const GeneralSettings * const generalSett // Descending switch direction: NOT (!) switches addItems(SWITCH_TYPE_ACT, -1); - addItems(SWITCH_TYPE_SENSOR, -CPN_MAX_SENSORS); + addItems(SWITCH_TYPE_SENSOR, -fw->getCapability(Sensors)); addItems(SWITCH_TYPE_TELEMETRY, -1); addItems(SWITCH_TYPE_FLIGHT_MODE, -fw->getCapability(FlightModes)); addItems(SWITCH_TYPE_VIRTUAL, -fw->getCapability(LogicalSwitches)); @@ -105,7 +109,7 @@ RawSwitchItemModel::RawSwitchItemModel(const GeneralSettings * const generalSett addItems(SWITCH_TYPE_VIRTUAL, fw->getCapability(LogicalSwitches)); addItems(SWITCH_TYPE_FLIGHT_MODE, fw->getCapability(FlightModes)); addItems(SWITCH_TYPE_TELEMETRY, 1); - addItems(SWITCH_TYPE_SENSOR, CPN_MAX_SENSORS); + addItems(SWITCH_TYPE_SENSOR, fw->getCapability(Sensors)); addItems(SWITCH_TYPE_ON, 1); addItems(SWITCH_TYPE_ONE, 1); addItems(SWITCH_TYPE_ACT, 1); @@ -166,8 +170,95 @@ void RawSwitchItemModel::addItems(const RawSwitchType & type, int count) } } -void RawSwitchItemModel::update() const +void RawSwitchItemModel::update() { - for (int i=0; i < rowCount(); ++i) + emit dataAboutToBeUpdated(); + + for (int i = 0; i < rowCount(); ++i) setDynamicItemData(item(i), RawSwitch(item(i)->data(ItemIdRole).toInt())); + + emit dataUpdateComplete(); +} + +// +// CurveItemModel +// + +CurveItemModel::CurveItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent) : + AbstractRawItemDataModel(generalSettings, modelData, parent) +{ + const int count = getCurrentFirmware()->getCapability(NumCurves); + + for (int i = -count ; i <= count; ++i) { + QStandardItem * modelItem = new QStandardItem(); + modelItem->setData(i, ItemIdRole); + int flags; + if (i < 0) + flags = DataGroups::NegativeGroup; + else if (i > 0) + flags = DataGroups::PositiveGroup; + else + flags = DataGroups::NoneGroup; + modelItem->setData(flags, ItemFlagsRole); + setDynamicItemData(modelItem, i); + appendRow(modelItem); + } +} + +void CurveItemModel::setDynamicItemData(QStandardItem * item, int index) const +{ + item->setText(CurveReference(CurveReference::CURVE_REF_CUSTOM, index).toString(modelData, false)); + item->setData(true, IsAvailableRole); +} + +void CurveItemModel::update() +{ + emit dataAboutToBeUpdated(); + + for (int i = 0; i < rowCount(); ++i) + setDynamicItemData(item(i), item(i)->data(ItemIdRole).toInt()); + + emit dataUpdateComplete(); +} + +// +// CommonItemModels +// + +CommonItemModels::CommonItemModels(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent) : + QObject(parent) +{ + m_rawSourceItemModel = new RawSourceItemModel(generalSettings, modelData, parent); + m_rawSwitchItemModel = new RawSwitchItemModel(generalSettings, modelData, parent); + m_curveItemModel = new CurveItemModel(generalSettings, modelData, parent); +} + +CommonItemModels::~CommonItemModels() +{ +} + +void CommonItemModels::update(const RadioModelObjects radioModelObjects) +{ + switch (radioModelObjects) { + case RMO_CHANNELS: + case RMO_INPUTS: + case RMO_TELEMETRY_SENSORS: + case RMO_TIMERS: + m_rawSourceItemModel->update(); + break; + case RMO_FLIGHT_MODES: + case RMO_GLOBAL_VARIABLES: + case RMO_LOGICAL_SWITCHES: + m_rawSourceItemModel->update(); + m_rawSwitchItemModel->update(); + break; + case RMO_CURVES: + m_curveItemModel->update(); + break; + case RMO_SCRIPTS: + // no need to refresh + break; + default: + qDebug() << "Unknown RadioModelObject:" << radioModelObjects; + } } diff --git a/companion/src/datamodels/rawitemdatamodels.h b/companion/src/datamodels/rawitemdatamodels.h index 59eb6025e..48cb55fd2 100644 --- a/companion/src/datamodels/rawitemdatamodels.h +++ b/companion/src/datamodels/rawitemdatamodels.h @@ -36,6 +36,13 @@ class AbstractRawItemDataModel: public QStandardItemModel enum DataRoles { ItemIdRole = Qt::UserRole, ItemTypeRole, ItemFlagsRole, IsAvailableRole }; Q_ENUM(DataRoles) + enum DataGroups { + NoneGroup = 0x01, + NegativeGroup = 0x02, + PositiveGroup = 0x04 + }; + Q_ENUM(DataGroups) + explicit AbstractRawItemDataModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr) : QStandardItemModel(parent), generalSettings(generalSettings), @@ -43,7 +50,11 @@ class AbstractRawItemDataModel: public QStandardItemModel {} public slots: - virtual void update() const = 0; + virtual void update() = 0; + + signals: + void dataAboutToBeUpdated(); + void dataUpdateComplete(); protected: const GeneralSettings * generalSettings; @@ -58,7 +69,7 @@ class RawSourceItemModel: public AbstractRawItemDataModel explicit RawSourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr); public slots: - void update() const override; + void update() override; protected: void setDynamicItemData(QStandardItem * item, const RawSource & src) const; @@ -73,7 +84,7 @@ class RawSwitchItemModel: public AbstractRawItemDataModel explicit RawSwitchItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr); public slots: - void update() const override; + void update() override; protected: void setDynamicItemData(QStandardItem * item, const RawSwitch & rsw) const; @@ -81,4 +92,49 @@ class RawSwitchItemModel: public AbstractRawItemDataModel }; +class CurveItemModel: public AbstractRawItemDataModel +{ + Q_OBJECT + public: + explicit CurveItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr); + + public slots: + void update() override; + + protected: + void setDynamicItemData(QStandardItem * item, int index) const; +}; + + +class CommonItemModels: public QObject +{ + Q_OBJECT + public: + enum RadioModelObjects { + RMO_CHANNELS, + RMO_CURVES, + RMO_FLIGHT_MODES, + RMO_GLOBAL_VARIABLES, + RMO_INPUTS, + RMO_LOGICAL_SWITCHES, + RMO_SCRIPTS, + RMO_TELEMETRY_SENSORS, + RMO_TIMERS + }; + Q_ENUM(RadioModelObjects) + + explicit CommonItemModels(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr); + ~CommonItemModels(); + + void update(const RadioModelObjects radioModelObjects); + RawSourceItemModel * rawSourceItemModel() const { return m_rawSourceItemModel; } + RawSwitchItemModel * rawSwitchItemModel() const { return m_rawSwitchItemModel; } + CurveItemModel * curveItemModel() const { return m_curveItemModel; } + + private: + RawSourceItemModel *m_rawSourceItemModel; + RawSwitchItemModel *m_rawSwitchItemModel; + CurveItemModel *m_curveItemModel; +}; + #endif // RAWITEMDATAMODELS_H diff --git a/companion/src/datamodels/rawitemfilteredmodel.cpp b/companion/src/datamodels/rawitemfilteredmodel.cpp index 1de9e26b2..abe9ca08e 100644 --- a/companion/src/datamodels/rawitemfilteredmodel.cpp +++ b/companion/src/datamodels/rawitemfilteredmodel.cpp @@ -19,7 +19,6 @@ */ #include "rawitemfilteredmodel.h" -#include "rawitemdatamodels.h" RawItemFilteredModel::RawItemFilteredModel(QAbstractItemModel * sourceModel, int flags, QObject * parent) : QSortFilterProxyModel(parent), @@ -30,6 +29,12 @@ RawItemFilteredModel::RawItemFilteredModel(QAbstractItemModel * sourceModel, int setFilterFlags(flags); setDynamicSortFilter(true); setSourceModel(sourceModel); + + AbstractRawItemDataModel * itemModel = qobject_cast(sourceModel); + if (itemModel) { + connect(itemModel, &AbstractRawItemDataModel::dataAboutToBeUpdated, this, &RawItemFilteredModel::onDataAboutToBeUpdated); + connect(itemModel, &AbstractRawItemDataModel::dataUpdateComplete, this, &RawItemFilteredModel::onDataUpdateComplete); + } } void RawItemFilteredModel::setFilterFlags(int flags) @@ -56,19 +61,17 @@ bool RawItemFilteredModel::filterAcceptsRow(int sourceRow, const QModelIndex & s void RawItemFilteredModel::update() const { - AbstractRawItemDataModel * model = qobject_cast(sourceModel()); - if (model) - model->update(); + AbstractRawItemDataModel * itemModel = qobject_cast(sourceModel()); + if (itemModel) + itemModel->update(); } - -RawSourceFilterItemModel::RawSourceFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, int flags, QObject * parent) : - RawItemFilteredModel(new RawSourceItemModel(generalSettings, modelData, parent), flags, parent) +void RawItemFilteredModel::onDataAboutToBeUpdated() { + emit dataAboutToBeUpdated(); } - -RawSwitchFilterItemModel::RawSwitchFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, int context, QObject * parent) : - RawItemFilteredModel(new RawSwitchItemModel(generalSettings, modelData, parent), context, parent) +void RawItemFilteredModel::onDataUpdateComplete() { + emit dataUpdateComplete(); } diff --git a/companion/src/datamodels/rawitemfilteredmodel.h b/companion/src/datamodels/rawitemfilteredmodel.h index 2d95dff71..3274460f7 100644 --- a/companion/src/datamodels/rawitemfilteredmodel.h +++ b/companion/src/datamodels/rawitemfilteredmodel.h @@ -21,54 +21,43 @@ #ifndef RAWITEMFILTEREDMODEL_H #define RAWITEMFILTEREDMODEL_H +#include "rawitemdatamodels.h" + #include class GeneralSettings; class ModelData; -class RawSourceItemModel; -class RawSwitchItemModel; class RawItemFilteredModel: public QSortFilterProxyModel { Q_OBJECT public: + enum DataFilters { + AllFilter = AbstractRawItemDataModel::NegativeGroup | AbstractRawItemDataModel::NoneGroup | AbstractRawItemDataModel::PositiveGroup, + AllExcludeNoneFilter = AllFilter &~ AbstractRawItemDataModel::NoneGroup, + NegativeFilter = AbstractRawItemDataModel::NegativeGroup | AbstractRawItemDataModel::NoneGroup, + NegativeExcludeNoneFilter = AbstractRawItemDataModel::NegativeGroup, + PositiveFilter = AbstractRawItemDataModel::PositiveGroup | AbstractRawItemDataModel::NoneGroup, + PositiveExcludeNoneFilter = AbstractRawItemDataModel::PositiveGroup + }; + Q_ENUM(DataFilters) + explicit RawItemFilteredModel(QAbstractItemModel * sourceModel, int flags, QObject * parent = nullptr); explicit RawItemFilteredModel(QAbstractItemModel * sourceModel, QObject * parent = nullptr) : RawItemFilteredModel(sourceModel, 0, parent) {} public slots: void setFilterFlags(int flags); void update() const; + void onDataAboutToBeUpdated(); + void onDataUpdateComplete(); + + signals: + void dataAboutToBeUpdated(); + void dataUpdateComplete(); protected: bool filterAcceptsRow(int sourceRow, const QModelIndex & sourceParent) const override; int filterFlags; }; - - -// The specialized "convenience" types below can go away once centralalized RawSource/RawSwitch item models are established. -// These proxy classes will automatically create a source model of the corresponding type. - -class RawSwitchFilterItemModel: public RawItemFilteredModel -{ - Q_OBJECT - public: - using RawItemFilteredModel::RawItemFilteredModel; - - explicit RawSwitchFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, int context, QObject * parent = nullptr); -}; - - -class RawSourceFilterItemModel: public RawItemFilteredModel -{ - Q_OBJECT - public: - using RawItemFilteredModel::RawItemFilteredModel; - - explicit RawSourceFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, int flags, QObject * parent = nullptr); - - explicit RawSourceFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr) : - RawSourceFilterItemModel(generalSettings, modelData, 0, parent) {} -}; - #endif // RAWITEMFILTEREDMODEL_H diff --git a/companion/src/firmwares/CMakeLists.txt b/companion/src/firmwares/CMakeLists.txt index 1b99964fa..e50d9241b 100644 --- a/companion/src/firmwares/CMakeLists.txt +++ b/companion/src/firmwares/CMakeLists.txt @@ -32,8 +32,14 @@ list(APPEND firmwares_HDRS moduledata.h ) +set(firmwares_QT + curvereference.h + ) + +qt5_wrap_cpp(firmwares_SRCS ${firmwares_QT}) + add_library(firmwares ${firmwares_SRCS} ${firmwares_HDRS}) -target_link_libraries(firmwares ${CPN_COMMON_LIB} Qt5::Core Qt5::Xml Qt5::Widgets) +target_link_libraries(firmwares ${CPN_COMMON_LIB} datamodels Qt5::Core Qt5::Xml Qt5::Widgets) target_include_directories(firmwares PRIVATE ${CMAKE_SOURCE_DIR} diff --git a/companion/src/firmwares/boards.cpp b/companion/src/firmwares/boards.cpp index 35f7a0bab..82e645d05 100644 --- a/companion/src/firmwares/boards.cpp +++ b/companion/src/firmwares/boards.cpp @@ -191,7 +191,20 @@ SwitchInfo Boards::getSwitchInfo(Board::Type board, int index) if (index < DIM(switches)) return switches[index]; } - else if (IS_TARANIS_X7(board)) { + else if (board == BOARD_TARANIS_X7_ACCESS) { + const Board::SwitchInfo switches[] = { + {SWITCH_3POS, "SA"}, + {SWITCH_3POS, "SB"}, + {SWITCH_3POS, "SC"}, + {SWITCH_3POS, "SD"}, + {SWITCH_2POS, "SF"}, + {SWITCH_TOGGLE, "SH"}, + {SWITCH_2POS, "SI"} + }; + if (index < DIM(switches)) + return switches[index]; + } + else if (board == BOARD_TARANIS_X7) { const Board::SwitchInfo switches[] = { {SWITCH_3POS, "SA"}, {SWITCH_3POS, "SB"}, @@ -350,7 +363,9 @@ int Boards::getCapability(Board::Type board, Board::Capability capability) return 5; else if (board == Board::BOARD_TARANIS_X9LITES) return 7; - else if (IS_TARANIS_X7(board)) + else if (board == BOARD_TARANIS_X7_ACCESS) + return 7; + else if (board == BOARD_TARANIS_X7) return 8; else if (IS_FAMILY_T12(board)) return 8; diff --git a/companion/src/firmwares/curvereference.cpp b/companion/src/firmwares/curvereference.cpp index 578d7e72b..449dc0266 100644 --- a/companion/src/firmwares/curvereference.cpp +++ b/companion/src/firmwares/curvereference.cpp @@ -19,45 +19,293 @@ */ #include "curvereference.h" +#include "adjustmentreference.h" +#include "helpers.h" +#include "modeldata.h" +#include "rawitemfilteredmodel.h" -#include "helpers.h" // for Helpers::getAdjustmentString() -#include "radiodata.h" // for ModelData - -QString CurveReference::toString(const ModelData * model, bool verbose) const +const QString CurveReference::toString(const ModelData * model, bool verbose) const { - if (value == 0) { - return "----"; - } + if (value == 0) + return CPN_STR_NONE_ITEM; QString ret; unsigned idx = abs(value) - 1; switch(type) { case CURVE_REF_DIFF: - ret = tr("Diff(%1)").arg(Helpers::getAdjustmentString(value, model)); - break; - case CURVE_REF_EXPO: - ret = tr("Expo(%1)").arg(Helpers::getAdjustmentString(value, model)); + ret = AdjustmentReference(value).toString(model); break; - case CURVE_REF_FUNC: - ret = QString("x>0" "x<0" "|x|" "f>0" "f<0" "|f|").mid(3*(value-1), 3); - if (verbose) - ret = tr("Function(%1)").arg(ret); + ret = functionToString(value); break; - - default: + case CURVE_REF_CUSTOM: if (model) ret = model->curves[idx].nameToString(idx); else ret = CurveData().nameToString(idx); - if (verbose) - ret = tr("Curve(%1)").arg(ret); if (value < 0) ret.prepend(CPN_STR_SW_INDICATOR_REV); break; + default: + return CPN_STR_UNKNOWN_ITEM; } + if (verbose) + ret = tr(qPrintable(QString(typeToString(type) + "(%1)").arg(ret))); + return ret; } + +const bool CurveReference::isValueNumber() const +{ + return (type == CURVE_REF_DIFF || type == CURVE_REF_EXPO) && AdjustmentReference(value).type == AdjustmentReference::ADJUST_REF_VALUE; +} + +// static +int CurveReference::getDefaultValue(const CurveRefType type, const bool isGVar) +{ + if (isGVar && (type == CURVE_REF_DIFF || type == CURVE_REF_EXPO)) + return AdjustmentReference(AdjustmentReference::ADJUST_REF_GVAR, 1).toValue(); + else if (type == CURVE_REF_FUNC) + return 1; + else + return 0; +} + +// static +QString CurveReference::typeToString(const CurveRefType type) +{ + const QStringList strl = { "Diff", "Expo" , "Func", "Curve" }; + int idx = (int)type; + + if (idx < 0 || idx >= strl.count()) + return CPN_STR_UNKNOWN_ITEM; + + return strl.at(idx); +} + +constexpr int MAX_CURVE_REF_FUNC { 6 }; + +// static +QString CurveReference::functionToString(const int value) +{ + const QStringList strl = { "x>0", "x<0", "|x|", "f>0", "f<0", "|f|" }; + int idx = value - 1; + + if (idx < 0 || idx >= strl.count()) + return CPN_STR_UNKNOWN_ITEM; + + return strl.at(idx); +} + +/* + * CurveReferenceUIManager +*/ + +constexpr int CURVE_REF_UI_HIDE_DIFF { 0x01 }; +constexpr int CURVE_REF_UI_HIDE_EXPO { 0x02 }; +constexpr int CURVE_REF_UI_HIDE_NEGATIVE_CURVES { 0x04 }; + +// static +bool CurveReferenceUIManager::firsttime { true }; +int CurveReferenceUIManager::flags { 0 }; +bool CurveReferenceUIManager::hasCapabilityGvars { false }; +int CurveReferenceUIManager::numCurves { 0 }; +RawItemFilteredModel * CurveReferenceUIManager::curveItemModel { nullptr }; +QStandardItemModel * CurveReferenceUIManager::tempModel { nullptr }; + +CurveReferenceUIManager::CurveReferenceUIManager(QComboBox * curveValueCB, CurveReference & curve, const ModelData & model, + RawItemFilteredModel * curveItemModel, QObject * parent) : + QObject(parent), + curveTypeCB(nullptr), + curveGVarCB(nullptr), + curveValueSB(nullptr), + curveValueCB(curveValueCB), + curve(curve), + model(model), + lock(false) +{ + init(curveItemModel); +} + +CurveReferenceUIManager::CurveReferenceUIManager(QComboBox * curveTypeCB, QCheckBox * curveGVarCB, QSpinBox * curveValueSB, + QComboBox * curveValueCB, CurveReference & curve, const ModelData & model, + RawItemFilteredModel * curveItemModel, QObject * parent) : + QObject(parent), + curveTypeCB(curveTypeCB), + curveGVarCB(curveGVarCB), + curveValueSB(curveValueSB), + curveValueCB(curveValueCB), + curve(curve), + model(model), + lock(false) +{ + init(curveItemModel); +} + +CurveReferenceUIManager::~CurveReferenceUIManager() +{ + delete tempModel; +} + +void CurveReferenceUIManager::init(RawItemFilteredModel * curveModel) +{ + tempModel = new QStandardItemModel(); + + if (firsttime) { + firsttime = false; + Firmware * fw = getCurrentFirmware(); + hasCapabilityGvars = fw->getCapability(Gvars); + numCurves = fw->getCapability(NumCurves); + curveItemModel = curveModel; + + if (!fw->getCapability(HasInputDiff)) + flags |= (CURVE_REF_UI_HIDE_DIFF | CURVE_REF_UI_HIDE_NEGATIVE_CURVES); + + if (!fw->getCapability(HasMixerExpo)) + flags |= CURVE_REF_UI_HIDE_EXPO; + } + + if (curveTypeCB) { + populateTypeCB(curveTypeCB, curve); + connect(curveTypeCB, SIGNAL(currentIndexChanged(int)), this, SLOT(typeChanged(int))); + } + + if (curveGVarCB) + connect(curveGVarCB, SIGNAL(stateChanged(int)), this, SLOT(gvarCBChanged(int))); + + if (curveValueSB) { + curveValueSB->setMinimum(-100); + curveValueSB->setMaximum(100); + connect(curveValueSB, SIGNAL(editingFinished()), this, SLOT(valueSBChanged())); + } + + curveValueCB->setSizeAdjustPolicy(QComboBox::AdjustToContents); + curveValueCB->setMaxVisibleItems(10); + connect(curveValueCB, SIGNAL(currentIndexChanged(int)), this, SLOT(valueCBChanged())); + + update(); +} + +#define CURVE_REF_UI_GVAR_SHOW (1<<0) +#define CURVE_REF_UI_VALUE_SHOW (1<<1) +#define CURVE_REF_UI_REF_SHOW (1<<2) + +void CurveReferenceUIManager::update() +{ + lock = true; + int widgetsMask = 0; + + if (curve.type == CurveReference::CURVE_REF_DIFF || curve.type == CurveReference::CURVE_REF_EXPO) { + if (hasCapabilityGvars) + widgetsMask |= CURVE_REF_UI_GVAR_SHOW; + if (curve.isValueNumber()) { + curveGVarCB->setChecked(false); + curveValueSB->setValue(curve.value); + widgetsMask |= CURVE_REF_UI_VALUE_SHOW; + } + else { + curveGVarCB->setChecked(true); + widgetsMask |= CURVE_REF_UI_REF_SHOW; + } + } + else { + widgetsMask |= CURVE_REF_UI_REF_SHOW; + } + + if(curveTypeCB) { + curveTypeCB->setCurrentIndex(curveTypeCB->findData(curve.type)); + curveTypeCB->show(); + } + if(curveGVarCB) + curveGVarCB->setVisible(widgetsMask & CURVE_REF_UI_GVAR_SHOW); + if(curveValueSB) + curveValueSB->setVisible(widgetsMask & CURVE_REF_UI_VALUE_SHOW); + if(curveValueCB) { + if (curve.isValueReference()) + populateValueCB(curveValueCB, curve, &model); + curveValueCB->setVisible(widgetsMask & CURVE_REF_UI_REF_SHOW); + } + + lock = false; +} + +void CurveReferenceUIManager::gvarCBChanged(int state) +{ + if (!lock) { + curve.value = CurveReference::getDefaultValue(curve.type, state); + update(); + } +} + +void CurveReferenceUIManager::typeChanged(int value) +{ + if (!lock) { + CurveReference::CurveRefType type = (CurveReference::CurveRefType)curveTypeCB->itemData(curveTypeCB->currentIndex()).toInt(); + curve = CurveReference(type, CurveReference::getDefaultValue(type)); + update(); + } +} + +void CurveReferenceUIManager::valueSBChanged() +{ + if (!lock) { + curve.value = curveValueSB->value(); + update(); + } +} + +void CurveReferenceUIManager::valueCBChanged() +{ + if (!lock) { + curve.value = curveValueCB->itemData(curveValueCB->currentIndex()).toInt(); + update(); + } +} + +// static +void CurveReferenceUIManager::populateTypeCB(QComboBox * cb, const CurveReference & curveRef) +{ + if (cb) { + cb->clear(); + for (int i = 0; i <= CurveReference::MAX_CURVE_REF_TYPE; i++) { + if ((curveRef.type == CurveReference::CURVE_REF_DIFF && !(flags & CURVE_REF_UI_HIDE_DIFF)) || + (curveRef.type == CurveReference::CURVE_REF_EXPO && !(flags & CURVE_REF_UI_HIDE_EXPO)) || + (curveRef.type != CurveReference::CURVE_REF_DIFF && curveRef.type != CurveReference::CURVE_REF_EXPO)) + cb->addItem(CurveReference::typeToString((CurveReference::CurveRefType)i), i); + } + + cb->setCurrentIndex(cb->findData((int)curveRef.type)); + } +} + +// static +void CurveReferenceUIManager::populateValueCB(QComboBox * cb, const CurveReference & curveRef, const ModelData * model) +{ + if (cb) { + cb->setModel(tempModel); // do not want to clear/alter the shared curves model and set to nullptr is invalid + + switch (curveRef.type) { + case CurveReference::CURVE_REF_DIFF: + case CurveReference::CURVE_REF_EXPO: + cb->clear(); + Helpers::populateGVCB(*cb, curveRef.value, *model); + break; + case CurveReference::CURVE_REF_FUNC: + cb->clear(); + for (int i = 1; i <= MAX_CURVE_REF_FUNC; i++) { + cb->addItem(CurveReference::functionToString(i), i); + } + break; + case CurveReference::CURVE_REF_CUSTOM: + cb->setModel(curveItemModel); + break; + default: + break; + } + + cb->setCurrentIndex(cb->findData(curveRef.value)); + } +} diff --git a/companion/src/firmwares/curvereference.h b/companion/src/firmwares/curvereference.h index cb5be4e73..0a1c7a180 100644 --- a/companion/src/firmwares/curvereference.h +++ b/companion/src/firmwares/curvereference.h @@ -22,35 +22,101 @@ #define CURVEREFERENCE_H #include +#include +#include +#include +#include + class ModelData; +class RawItemFilteredModel; class CurveReference { + Q_DECLARE_TR_FUNCTIONS(CurveReference) public: + enum CurveRefType { CURVE_REF_DIFF, CURVE_REF_EXPO, CURVE_REF_FUNC, - CURVE_REF_CUSTOM + CURVE_REF_CUSTOM, + MAX_CURVE_REF_TYPE = CURVE_REF_CUSTOM + }; + + enum CurveRefGroups { + NoneGroup = 0x001, + NegativeGroup = 0x002, + PositiveGroup = 0x004, + + AllCurveRefGroups = NoneGroup | NegativeGroup | PositiveGroup, + PositiveCurveRefGroups = AllCurveRefGroups &~ NegativeGroup }; CurveReference() { clear(); } - - CurveReference(CurveRefType type, int value): - type(type), - value(value) - { - } + CurveReference(CurveRefType type, int value) : type(type), value(value) { ; } void clear() { memset(this, 0, sizeof(CurveReference)); } + const bool isEmpty() const { return type == CURVE_REF_DIFF && value == 0; } + const bool isSet() const { return !isEmpty(); } + const bool isValueNumber() const; + const bool isValueReference() const { return !isValueNumber(); } + const QString toString(const ModelData * model = nullptr, bool verbose = true) const; CurveRefType type; int value; - QString toString(const ModelData * model = NULL, bool verbose = true) const; - bool isSet() const { return type != CURVE_REF_DIFF || value != 0; } + bool operator == ( const CurveReference & other) const { + return (this->type == other.type) && (this->value == other.value); + } + + bool operator != ( const CurveReference & other) const { + return (this->type != other.type) || (this->value != other.value); + } + + static int getDefaultValue(const CurveRefType type, const bool isGVar = false); + static QString typeToString(const CurveRefType type); + static QString functionToString(const int value); +}; + +class CurveReferenceUIManager : public QObject { + + Q_OBJECT + + public: + CurveReferenceUIManager(QComboBox *curveValueCB, CurveReference & curve, const ModelData & model, + RawItemFilteredModel * curveItemModel, QObject * parent = nullptr); + CurveReferenceUIManager(QComboBox *curveTypeCB, QCheckBox *curveGVarCB, QSpinBox *curveValueSB, QComboBox *curveValueCB, + CurveReference & curve, const ModelData & model, RawItemFilteredModel * curveItemModel, QObject * parent = nullptr); + virtual ~CurveReferenceUIManager(); + void init(RawItemFilteredModel * curveModel); + void update(); + + protected slots: + void gvarCBChanged(int); + void typeChanged(int); + void valueSBChanged(); + void valueCBChanged(); + + protected: + QComboBox *curveTypeCB; + QCheckBox *curveGVarCB; + QSpinBox *curveValueSB; + QComboBox *curveValueCB; + CurveReference & curve; + const ModelData & model; + bool lock; + + static bool firsttime; + static int flags; + static bool hasCapabilityGvars; + static int numCurves; + static RawItemFilteredModel * curveItemModel; + static QStandardItemModel * tempModel; + + static void populateTypeCB(QComboBox * cb, const CurveReference & curveRef); + static void populateValueCB(QComboBox * cb, const CurveReference & curveRef, const ModelData * model = nullptr); }; #endif // CURVEREFERENCE_H diff --git a/companion/src/firmwares/customfunctiondata.cpp b/companion/src/firmwares/customfunctiondata.cpp index 42d84d570..d6918e27c 100644 --- a/companion/src/firmwares/customfunctiondata.cpp +++ b/companion/src/firmwares/customfunctiondata.cpp @@ -91,10 +91,8 @@ QString CustomFunctionData::funcToString(const ModelData * model) const return tr("Background Music Pause"); else if (func >= FuncAdjustGV1 && func <= FuncAdjustGVLast) return tr("Adjust %1").arg(RawSource(SOURCE_TYPE_GVAR, func-FuncAdjustGV1).toString(model)); - else if (func == FuncSetFailsafeInternalModule) - return tr("SetFailsafe Int. Module"); - else if (func == FuncSetFailsafeExternalModule) - return tr("SetFailsafe Ext. Module"); + else if (func == FuncSetFailsafe) + return tr("Set Failsafe"); else if (func == FuncRangeCheckInternalModule) return tr("RangeCheck Int. Module"); else if (func == FuncRangeCheckExternalModule) @@ -126,20 +124,15 @@ void CustomFunctionData::populateResetParams(const ModelData * model, QComboBox b->addItem(tr("REa"), val++); b->addItem(tr("REb"), val++); } - if ((int)value < b->count()) { - b->setCurrentIndex(value); - } if (model) { - for (unsigned i=0; igetCapability(Sensors); ++i) { if (model->sensorData[i].isAvailable()) { - RawSource item = RawSource(SOURCE_TYPE_TELEMETRY, 3*i); - b->addItem(item.toString(model), val+i); - if (value == val+i) { - b->setCurrentIndex(b->count()-1); - } + RawSource item = RawSource(SOURCE_TYPE_TELEMETRY, 3 * i); + b->addItem(item.toString(model), val + i); } } } + b->setCurrentIndex(b->findData(value)); } void CustomFunctionData::populatePlaySoundParams(QStringList & qs) diff --git a/companion/src/firmwares/customfunctiondata.h b/companion/src/firmwares/customfunctiondata.h index 9150035c5..93f9969e8 100644 --- a/companion/src/firmwares/customfunctiondata.h +++ b/companion/src/firmwares/customfunctiondata.h @@ -62,8 +62,7 @@ enum AssignFunc { FuncBackgroundMusicPause, FuncAdjustGV1, FuncAdjustGVLast = FuncAdjustGV1+CPN_MAX_GVARS-1, - FuncSetFailsafeInternalModule, - FuncSetFailsafeExternalModule, + FuncSetFailsafe, FuncRangeCheckInternalModule, FuncRangeCheckExternalModule, FuncBindInternalModule, diff --git a/companion/src/firmwares/modeldata.cpp b/companion/src/firmwares/modeldata.cpp index e38958249..930df092c 100644 --- a/companion/src/firmwares/modeldata.cpp +++ b/companion/src/firmwares/modeldata.cpp @@ -723,11 +723,15 @@ int ModelData::updateReference() updateAssignFunc(cfd); if (!cfd->isEmpty()) { updateSwitchRef(cfd->swtch); - if (cfd->func == FuncVolume || cfd->func == FuncBacklight || cfd->func == FuncPlayValue || (cfd->func >= FuncAdjustGV1 && cfd->func <= FuncAdjustGVLast && (cfd->adjustMode == FUNC_ADJUST_GVAR_GVAR || cfd->adjustMode == FUNC_ADJUST_GVAR_SOURCE))) { + if (cfd->func == FuncVolume || cfd->func == FuncBacklight || cfd->func == FuncPlayValue || + (cfd->func >= FuncAdjustGV1 && cfd->func <= FuncAdjustGVLast && (cfd->adjustMode == FUNC_ADJUST_GVAR_GVAR || cfd->adjustMode == FUNC_ADJUST_GVAR_SOURCE))) { updateSourceIntRef(cfd->param); if (cfd->param == 0) cfd->clear(); } + else if (cfd->func == FuncReset) { + updateResetParam(cfd); + } } } } @@ -847,7 +851,7 @@ void ModelData::updateTypeIndexRef(R & curRef, const T type, const int idxAdj, c newRef.clear(); else { newRef.type = (T)defType; - newRef.index = defIndex + idxAdj; + newRef.index = defIndex; } break; case REF_UPD_ACT_SHIFT: @@ -904,7 +908,7 @@ void ModelData::updateTypeValueRef(R & curRef, const T type, const int idxAdj, c newRef.clear(); else { newRef.type = (T)defType; - newRef.value = defValue + idxAdj; + newRef.value = defValue; } break; case REF_UPD_ACT_SHIFT: @@ -972,7 +976,7 @@ void ModelData::updateAssignFunc(CustomFunctionData * cfd) { const int invalidateRef = -1; int newRef = (int)cfd->func; - int idxAdj; + int idxAdj = 0; switch (updRefInfo.type) { @@ -989,7 +993,7 @@ void ModelData::updateAssignFunc(CustomFunctionData * cfd) case REF_UPD_TYPE_TIMER: if (cfd->func < FuncSetTimer1 || cfd->func > FuncSetTimer3) // TODO refactor to FuncSetTimerLast return; - idxAdj = FuncSetTimer1 - 2; // reverse earlier offset requiured for rawsource + idxAdj = FuncSetTimer1 - 2; // reverse earlier offset required for rawsource break; default: return; @@ -1374,3 +1378,64 @@ void ModelData::sortMixes() memcpy(&mixData[0], &sortedMixData[0], CPN_MAX_MIXERS * sizeof(MixData)); } + +void ModelData::updateResetParam(CustomFunctionData * cfd) +{ + + if (cfd->func != FuncReset) + return; + + const int invalidateRef = -1; + int newRef = cfd->param; + int idxAdj = 0; + Firmware *firmware = getCurrentFirmware(); + + switch (updRefInfo.type) + { + case REF_UPD_TYPE_SENSOR: + idxAdj = 5/*3 Timers + Flight + Telemetery*/ + firmware->getCapability(RotaryEncoders); + if (cfd->param < idxAdj || cfd->param > (idxAdj + firmware->getCapability(Sensors))) + return; + break; + default: + return; + } + + switch (updRefInfo.action) + { + case REF_UPD_ACT_CLEAR: + if (newRef != (updRefInfo.index1 + idxAdj)) + return; + newRef = invalidateRef; + break; + case REF_UPD_ACT_SHIFT: + if (newRef < (updRefInfo.index1 + idxAdj)) + return; + + newRef += updRefInfo.shift; + + if (newRef < (updRefInfo.index1 + idxAdj) || newRef > (updRefInfo.maxindex + idxAdj)) + newRef = invalidateRef; + break; + case REF_UPD_ACT_SWAP: + if (newRef == updRefInfo.index1 + idxAdj) + newRef = updRefInfo.index2 + idxAdj; + else if (newRef == updRefInfo.index2 + idxAdj) + newRef = updRefInfo.index1 + idxAdj; + break; + default: + qDebug() << "Error - unhandled action:" << updRefInfo.action; + return; + } + + if (newRef == invalidateRef) { + cfd->clear(); + //qDebug() << "Function cleared"; + updRefInfo.updcnt++; + } + else if (cfd->param != newRef) { + //qDebug() << "Updated reference:" << cfd->param << " -> " << newRef; + cfd->param = newRef; + updRefInfo.updcnt++; + } +} diff --git a/companion/src/firmwares/modeldata.h b/companion/src/firmwares/modeldata.h index 0afc66b72..7eacdc26d 100644 --- a/companion/src/firmwares/modeldata.h +++ b/companion/src/firmwares/modeldata.h @@ -338,6 +338,7 @@ class ModelData { value = swtch.toValue(); } void sortMixes(); + void updateResetParam(CustomFunctionData * cfd); }; #endif // MODELDATA_H diff --git a/companion/src/firmwares/moduledata.h b/companion/src/firmwares/moduledata.h index e22c167e3..119f44eb8 100644 --- a/companion/src/firmwares/moduledata.h +++ b/companion/src/firmwares/moduledata.h @@ -84,7 +84,7 @@ enum MultiModuleRFProtocols { MODULE_SUBTYPE_MULTI_MJXQ, MODULE_SUBTYPE_MULTI_SHENQI, MODULE_SUBTYPE_MULTI_FY326, - MODULE_SUBTYPE_MULTI_SFHSS, + MODULE_SUBTYPE_MULTI_FUTABA, MODULE_SUBTYPE_MULTI_J6PRO, MODULE_SUBTYPE_MULTI_FQ777, MODULE_SUBTYPE_MULTI_ASSAN, @@ -115,7 +115,7 @@ enum MultiModuleRFProtocols { MODULE_SUBTYPE_MULTI_REDPINE, MODULE_SUBTYPE_MULTI_POTENSIC, MODULE_SUBTYPE_MULTI_ZSX, - MODULE_SUBTYPE_MULTI_FLYZONE, + MODULE_SUBTYPE_MULTI_HEIGHT, MODULE_SUBTYPE_MULTI_SCANNER, MODULE_SUBTYPE_MULTI_FRSKYX_RX, MODULE_SUBTYPE_MULTI_AFHDS2A_RX, @@ -135,7 +135,15 @@ enum MultiModuleRFProtocols { MODULE_SUBTYPE_MULTI_DSM_RX, MODULE_SUBTYPE_MULTI_JJRC345, MODULE_SUBTYPE_MULTI_Q90C, - MODULE_SUBTYPE_MULTI_LAST = MODULE_SUBTYPE_MULTI_Q90C + MODULE_SUBTYPE_MULTI_KYOSHO, + MODULE_SUBTYPE_MULTI_RLINK, + MODULE_SUBTYPE_MULTI_ELRS, + MODULE_SUBTYPE_MULTI_REALACC, + MODULE_SUBTYPE_MULTI_OMP, + MODULE_SUBTYPE_MULTI_MLINK, + MODULE_SUBTYPE_MULTI_WFLY2, + MODULE_SUBTYPE_MULTI_E016HV2, + MODULE_SUBTYPE_MULTI_LAST = MODULE_SUBTYPE_MULTI_E016HV2 }; enum TrainerProtocol { diff --git a/companion/src/firmwares/multiprotocols.cpp b/companion/src/firmwares/multiprotocols.cpp index c8c18e6e5..1aedbc7d5 100644 --- a/companion/src/firmwares/multiprotocols.cpp +++ b/companion/src/firmwares/multiprotocols.cpp @@ -55,8 +55,9 @@ static const QStringList STR_SUBTYPE_ESky {"Standard", "ET4"}; static const QStringList STR_SUBTYPE_MT99 {"MT99", "H7", "YZ", "LS", "FY805"}; static const QStringList STR_SUBTYPE_MJXQ {"WLH08", "X600", "X800", "H26D", "E010", "H26WH", "Phoenix"}; static const QStringList STR_SUBTYPE_FY326 {"Standard", "FY319"}; +static const QStringList STR_SUBTYPE_FUTABA {"SFHSS"}; static const QStringList STR_SUBTYPE_HONTAI {"Standard", "JJRC X1", "X5C1 Clone", "FQ777_951"}; -static const QStringList STR_SUBTYPE_AFHDS2A {"PWM and IBUS", "PPM and IBUS", "PWM and SBUS", "PPM and SBUS"}; +static const QStringList STR_SUBTYPE_AFHDS2A {"PWM and IBUS", "PPM and IBUS", "PWM and SBUS", "PPM and SBUS", "PWM and IBUS16", "PPM and IBUS16"}; static const QStringList STR_SUBTYPE_Q2X2 {"Q222", "Q242", "Q282"}; static const QStringList STR_SUBTYPE_WK2x01 {"WK2801", "WK2401", "W6_5_1", "W6_6_1", "W6_HEL", "W6_HEL_I"}; static const QStringList STR_SUBTYPE_Q303 {"Standard", "CX35", "CX10D", "CX10WD"}; @@ -65,7 +66,7 @@ static const QStringList STR_SUBTYPE_ESKY150 {"4 Channel", "7 Channel"}; static const QStringList STR_SUBTYPE_H83D {"H8 Mini 3D", "H20H", "H20 Mini", "H30 Mini"}; static const QStringList STR_SUBTYPE_CORONA {"Corona V1", "Corona V2", "Flydream V3"}; static const QStringList STR_SUBTYPE_HITEC {"Optima", "Optima Hub Telem", "Minima"}; -static const QStringList STR_SUBTYPE_WFLY {"WFR0xS"}; +static const QStringList STR_SUBTYPE_WFLY {"WFR0x"}; static const QStringList STR_SUBTYPE_BUGS_MINI {"Standard", "Bugs 3H"}; static const QStringList STR_SUBTYPE_TRAXXAS {"6519 RX"}; static const QStringList STR_SUBTYPE_E01X {"E012", "E015", "E016H"}; @@ -75,18 +76,24 @@ static const QStringList STR_SUBTYPE_V761 {"3 Channel", "4 Channel"}; static const QStringList STR_SUBTYPE_REDPINE {"Fast", "Slow"}; static const QStringList STR_SUBTYPE_POTENSIC {"A20 Firefly"}; static const QStringList STR_SUBTYPE_ZSX {"JJRC ZSX-280"}; -static const QStringList STR_SUBTYPE_FLYZONE {"FZ-410 TX"}; +static const QStringList STR_SUBTYPE_HEIGHT {"5 Channel", "8 Channel"}; static const QStringList STR_SUBTYPE_FRSKYX_RX {"RX", "Clone TX"}; static const QStringList STR_SUBTYPE_HOTT {"Sync", "No_Sync"}; static const QStringList STR_SUBTYPE_FX816 {"P38"}; static const QStringList STR_SUBTYPE_PELIKAN {"Pro", "Lite"}; static const QStringList STR_SUBTYPE_XK {"X450", "X420"}; static const QStringList STR_SUBTYPE_XN297DUMP {"250K", "1M", "2M", "AUTO", "NRF"}; -static const QStringList STR_SUBTYPE_FRSKYX2 {"D16", "D16 8ch", "D16 EU-LBT", "D16 EU-LBT 8ch", "D16 Cloned"}; -static const QStringList STR_SUBTYPE_FRSKYR9 {"915 MHz", "868 MHz", "915 MHz 8-Channel", "868 MHz 8-Channel"}; +static const QStringList STR_SUBTYPE_FRSKYX2 {"D16", "D16 8ch", "D16 EU-LBT", "D16 EU-LBT 8ch", "Cloned", "Cloned 8ch"}; +static const QStringList STR_SUBTYPE_FRSKYR9 {"915 MHz", "868 MHz", "915 MHz 8-Channel", "868 MHz 8-Channel", "FCC", "---", "FCC 8-Channel"}; static const QStringList STR_SUBTYPE_PROPEL {"74-Z"}; static const QStringList STR_SUBTYPE_FRSKYL {"LR12", "LR12 6-Channel"}; static const QStringList STR_SUBTYPE_ESKY150V2 {"150 V2"}; +static const QStringList STR_SUBTYPE_JJRC345 {"Standard", "SkyTumbler"}; +static const QStringList STR_SUBTYPE_KYOSHO {"FHSS", "Hype"}; +static const QStringList STR_SUBTYPE_RLINK {"Surface", "Air", "DumboRC"}; +static const QStringList STR_SUBTYPE_ELRS {"Not Available WIP"}; +static const QStringList STR_SUBTYPE_REALACC {"R11"}; +static const QStringList STR_SUBTYPE_WFLY2 {"RF20x"}; static const QStringList NO_SUBTYPE {STR_MULTI_DEFAULT}; @@ -112,11 +119,11 @@ const Multiprotocols multiProtocols { {MODULE_SUBTYPE_MULTI_MT99XX, 4, false, STR_SUBTYPE_MT99, nullptr}, {MODULE_SUBTYPE_MULTI_MJXQ, 6, false, STR_SUBTYPE_MJXQ, STR_MULTI_RFTUNE}, {MODULE_SUBTYPE_MULTI_FY326, 1, false, STR_SUBTYPE_FY326, nullptr}, - {MODULE_SUBTYPE_MULTI_SFHSS, 0, true, NO_SUBTYPE, STR_MULTI_RFTUNE}, + {MODULE_SUBTYPE_MULTI_FUTABA, 0, true, STR_SUBTYPE_FUTABA, STR_MULTI_RFTUNE}, {MODULE_SUBTYPE_MULTI_J6PRO, 0, false, NO_SUBTYPE, nullptr}, {MODULE_SUBTYPE_MULTI_HONTAI, 3, false, STR_SUBTYPE_HONTAI, nullptr}, {MODULE_SUBTYPE_MULTI_OLRS, 0, false, NO_SUBTYPE, STR_MULTI_RFPOWER}, - {MODULE_SUBTYPE_MULTI_FS_AFHDS2A, 3, true, STR_SUBTYPE_AFHDS2A, STR_MULTI_SERVOFREQ}, + {MODULE_SUBTYPE_MULTI_FS_AFHDS2A, 5, true, STR_SUBTYPE_AFHDS2A, STR_MULTI_SERVOFREQ}, {MODULE_SUBTYPE_MULTI_Q2X2, 2, false, STR_SUBTYPE_Q2X2, nullptr}, {MODULE_SUBTYPE_MULTI_WK_2X01, 5, false, STR_SUBTYPE_WK2x01, nullptr}, {MODULE_SUBTYPE_MULTI_Q303, 3, false, STR_SUBTYPE_Q303, nullptr}, @@ -136,20 +143,28 @@ const Multiprotocols multiProtocols { {MODULE_SUBTYPE_MULTI_REDPINE, 1, false, STR_SUBTYPE_REDPINE, STR_MULTI_RFTUNE}, {MODULE_SUBTYPE_MULTI_POTENSIC, 0, false, STR_SUBTYPE_POTENSIC, nullptr}, {MODULE_SUBTYPE_MULTI_ZSX, 0, false, STR_SUBTYPE_ZSX, nullptr}, - {MODULE_SUBTYPE_MULTI_FLYZONE, 0, false, STR_SUBTYPE_FLYZONE, nullptr}, + {MODULE_SUBTYPE_MULTI_HEIGHT, 1, false, STR_SUBTYPE_HEIGHT, nullptr}, {MODULE_SUBTYPE_MULTI_FRSKYX_RX, 1, false, STR_SUBTYPE_FRSKYX_RX, STR_MULTI_RFTUNE}, {MODULE_SUBTYPE_MULTI_HOTT, 1, true, STR_SUBTYPE_HOTT, STR_MULTI_RFTUNE}, {MODULE_SUBTYPE_MULTI_FX816, 0, false, STR_SUBTYPE_FX816, nullptr}, {MODULE_SUBTYPE_MULTI_PELIKAN, 1, false, STR_SUBTYPE_PELIKAN, nullptr}, {MODULE_SUBTYPE_MULTI_XK, 1, false, STR_SUBTYPE_XK, STR_MULTI_RFTUNE}, {MODULE_SUBTYPE_MULTI_XN297DUMP, 4, false, STR_SUBTYPE_XN297DUMP, nullptr}, - {MODULE_SUBTYPE_MULTI_FRSKYX2, 4, true, STR_SUBTYPE_FRSKYX2, STR_MULTI_RFTUNE}, - {MODULE_SUBTYPE_MULTI_FRSKY_R9, 3, true, STR_SUBTYPE_FRSKYR9, nullptr}, + {MODULE_SUBTYPE_MULTI_FRSKYX2, 5, true, STR_SUBTYPE_FRSKYX2, STR_MULTI_RFTUNE}, + {MODULE_SUBTYPE_MULTI_FRSKY_R9, 6, true, STR_SUBTYPE_FRSKYR9, nullptr}, {MODULE_SUBTYPE_MULTI_PROPEL, 0, false, STR_SUBTYPE_PROPEL, nullptr}, {MODULE_SUBTYPE_MULTI_FRSKYL, 1, false, STR_SUBTYPE_FRSKYL, STR_MULTI_RFTUNE}, {MODULE_SUBTYPE_MULTI_SKYARTEC, 0, false, NO_SUBTYPE, STR_MULTI_RFTUNE}, {MODULE_SUBTYPE_MULTI_ESKY150V2, 0, false, STR_SUBTYPE_ESKY150V2, STR_MULTI_RFTUNE}, + {MODULE_SUBTYPE_MULTI_JJRC345, 1, false, STR_SUBTYPE_JJRC345, nullptr}, {MODULE_SUBTYPE_MULTI_Q90C, 0, false, NO_SUBTYPE, STR_MULTI_RFTUNE}, + {MODULE_SUBTYPE_MULTI_KYOSHO, 1, false, STR_SUBTYPE_KYOSHO, nullptr}, + {MODULE_SUBTYPE_MULTI_RLINK, 2, false, STR_SUBTYPE_RLINK, STR_MULTI_RFTUNE}, + {MODULE_SUBTYPE_MULTI_ELRS, 0, false, STR_SUBTYPE_ELRS, nullptr}, + {MODULE_SUBTYPE_MULTI_REALACC, 0, false, STR_SUBTYPE_REALACC, nullptr}, + {MODULE_SUBTYPE_MULTI_OMP, 0, false, NO_SUBTYPE, STR_MULTI_RFTUNE}, + {MODULE_SUBTYPE_MULTI_WFLY2, 0, false, STR_SUBTYPE_WFLY2, STR_MULTI_OPTION}, + {MODULE_SUBTYPE_MULTI_E016HV2, 0, false, NO_SUBTYPE, STR_MULTI_RFTUNE}, {MM_RF_CUSTOM_SELECTED, 7, true, STR_SUBTYPE_CUSTOM, STR_MULTI_OPTION}, // Sentinel and default for protocols not listed above (MM_RF_CUSTOM is 0xff) @@ -189,12 +204,13 @@ QString Multiprotocols::protocolToString(int protocol, bool custom) { static const QStringList strings({ "FlySky", "Hubsan", "FrSky", "Hisky", "V2x2", "DSM", "Devo", "YD717", "KN", "SymaX", "SLT", "CX10", "CG023", - "Bayang", "ESky", "MT99XX", "MJXQ", "Shenqi", "FY326", "SFHSS", "J6 PRO","FQ777","Assan","Hontai","Open LRS", + "Bayang", "ESky", "MT99XX", "MJXQ", "Shenqi", "FY326", "Futaba", "J6 PRO","FQ777","Assan","Hontai","Open LRS", "FlySky AFHDS2A", "Q2x2", "WK2x01", "Q303", "GW008", "DM002", "Cabell", "ESky 150", "H8 3D", "Corona", "CFlie", "Hitec", "Wfly", "Bugs", "Bugs Mini", "Traxxas", "NCC-1701-A", "E01X", "WL Heli V911S", "GD00X", "Volantex V761", - "KFPlan KF606", "Redpine", "Potensic", "ZSX", "FlyZone", "Scanner", "FrSky RX", "FlySky AFHDS2A RX", "HoTT", "Fx816", + "KFPlan KF606", "Redpine", "Potensic", "ZSX", "Height", "Scanner", "FrSky RX", "FlySky AFHDS2A RX", "HoTT", "Fx816", "Bayang RX", "Pelikan", "Tiger", "XK", "XN297 Dump", "FrSky X 2.1", "FrSky R9", "Propel", "FrSky L", "Skyartec", - "ESky 150v2", "DSM RX", "JJRC345", "Q90C" + "ESky 150v2", "DSM RX", "JJRC345", "Q90C", "Kyosho", "RadioLink", "ExpressLRS", "Realacc", "OMP", "M-Link", "Wfly 2", + "E016H v2" }); return strings.value(protocol, CPN_STR_UNKNOWN_ITEM); diff --git a/companion/src/firmwares/opentx/opentxeeprom.cpp b/companion/src/firmwares/opentx/opentxeeprom.cpp index 30666ca79..264a3ad6a 100644 --- a/companion/src/firmwares/opentx/opentxeeprom.cpp +++ b/companion/src/firmwares/opentx/opentxeeprom.cpp @@ -48,6 +48,9 @@ inline int MAX_SWITCHES(Board::Type board, int version) if (IS_FAMILY_T12(board)) return 8; + if (IS_TARANIS_X7(board)) + return 8; + return Boards::getCapability(board, Board::Switches); } @@ -1406,8 +1409,7 @@ class CustomFunctionsConversionTable: public ConversionTable { addConversion(FuncAdjustGV1+i, val); val++; addConversion(FuncVolume, val++); - addConversion(FuncSetFailsafeInternalModule, val); - addConversion(FuncSetFailsafeExternalModule, val++); + addConversion(FuncSetFailsafe, val++); addConversion(FuncRangeCheckInternalModule, val); addConversion(FuncRangeCheckExternalModule, val++); addConversion(FuncBindInternalModule, val); @@ -1520,9 +1522,6 @@ class ArmCustomFunctionField: public TransformedField { *((uint16_t *)_param) = fn.param; *((uint8_t *)(_param+3)) = fn.func - FuncSetTimer1; } - else if (fn.func >= FuncSetFailsafeInternalModule && fn.func <= FuncSetFailsafeExternalModule) { - *((uint16_t *)_param) = fn.func - FuncSetFailsafeInternalModule; - } else if (fn.func >= FuncRangeCheckInternalModule && fn.func <= FuncRangeCheckExternalModule) { *((uint16_t *)_param) = fn.func - FuncRangeCheckInternalModule; } diff --git a/companion/src/firmwares/rawswitch.cpp b/companion/src/firmwares/rawswitch.cpp index 10d3f7fa3..7aef46922 100644 --- a/companion/src/firmwares/rawswitch.cpp +++ b/companion/src/firmwares/rawswitch.cpp @@ -59,7 +59,7 @@ QString RawSwitch::toString(Board::Type board, const GeneralSettings * const gen tr("THs"), tr("TH%"), tr("THt") }; - const QStringList directionIndicators = QStringList() + static const QStringList directionIndicators = QStringList() << CPN_STR_SW_INDICATOR_UP << CPN_STR_SW_INDICATOR_NEUT << CPN_STR_SW_INDICATOR_DN; diff --git a/companion/src/generaledit/CMakeLists.txt b/companion/src/generaledit/CMakeLists.txt index 827c37ddf..2c458c719 100644 --- a/companion/src/generaledit/CMakeLists.txt +++ b/companion/src/generaledit/CMakeLists.txt @@ -28,4 +28,4 @@ qt5_wrap_ui(generaledit_SRCS ${generaledit_UIS}) qt5_wrap_cpp(generaledit_SRCS ${generaledit_HDRS}) add_library(generaledit ${generaledit_SRCS}) -target_link_libraries(generaledit PRIVATE ${CPN_COMMON_LIB} Qt5::Multimedia) +target_link_libraries(generaledit PRIVATE datamodels ${CPN_COMMON_LIB} Qt5::Multimedia) diff --git a/companion/src/generaledit/generaledit.cpp b/companion/src/generaledit/generaledit.cpp index 34d090e65..bff9d3f83 100644 --- a/companion/src/generaledit/generaledit.cpp +++ b/companion/src/generaledit/generaledit.cpp @@ -28,6 +28,7 @@ #include "hardware.h" #include "../modeledit/customfunctions.h" #include "verticalscrollarea.h" +#include "rawitemdatamodels.h" GeneralEdit::GeneralEdit(QWidget * parent, RadioData & radioData, Firmware * firmware) : QDialog(parent), @@ -55,8 +56,10 @@ GeneralEdit::GeneralEdit(QWidget * parent, RadioData & radioData, Firmware * fir } } + commonItemModels = new CommonItemModels(&generalSettings, nullptr, this); + addTab(new GeneralSetupPanel(this, generalSettings, firmware), tr("Setup")); - addTab(new CustomFunctionsPanel(this, NULL, generalSettings, firmware), tr("Global Functions")); + addTab(new CustomFunctionsPanel(this, nullptr, generalSettings, firmware, commonItemModels), tr("Global Functions")); addTab(new TrainerPanel(this, generalSettings, firmware), tr("Trainer")); addTab(new HardwarePanel(this, generalSettings, firmware), tr("Hardware")); addTab(new CalibrationPanel(this, generalSettings, firmware), tr("Calibration")); diff --git a/companion/src/generaledit/generaledit.h b/companion/src/generaledit/generaledit.h index 1c1d096a5..3f73a9e01 100644 --- a/companion/src/generaledit/generaledit.h +++ b/companion/src/generaledit/generaledit.h @@ -25,6 +25,8 @@ #include "eeprominterface.h" #include "genericpanel.h" +class CommonItemModels; + namespace Ui { class GeneralEdit; } @@ -56,7 +58,7 @@ class GeneralEdit : public QDialog void getGeneralSwitchDefPos(int i, bool val); void setSwitchDefPos(); void updateVarioPitchRange(); - + signals: void modified(); @@ -71,7 +73,7 @@ class GeneralEdit : public QDialog QVector panels; void addTab(GenericPanel *panel, QString text); void closeEvent(QCloseEvent *event); - + CommonItemModels *commonItemModels; }; #endif // _GENERALEDIT_H_ diff --git a/companion/src/helpers.cpp b/companion/src/helpers.cpp index 2b0f62503..020f1b45b 100644 --- a/companion/src/helpers.cpp +++ b/companion/src/helpers.cpp @@ -210,170 +210,6 @@ void GVarGroup::setWeight(int val) lock = false; } - -/* - * CurveGroup -*/ - -CurveGroup::CurveGroup(QComboBox * curveTypeCB, QCheckBox * curveGVarCB, QComboBox * curveValueCB, QSpinBox * curveValueSB, CurveReference & curve, const ModelData & model, unsigned int flags): - QObject(), - curveTypeCB(curveTypeCB), - curveGVarCB(curveGVarCB), - curveValueCB(curveValueCB), - curveValueSB(curveValueSB), - curve(curve), - model(model), - flags(flags), - lock(false), - lastType(-1) -{ - if (!(flags & HIDE_DIFF)) curveTypeCB->addItem(tr("Diff"), 0); - if (!(flags & HIDE_EXPO)) curveTypeCB->addItem(tr("Expo"), 1); - curveTypeCB->addItem(tr("Func"), 2); - curveTypeCB->addItem(tr("Curve"), 3); - - curveValueCB->setMaxVisibleItems(10); - - connect(curveTypeCB, SIGNAL(currentIndexChanged(int)), this, SLOT(typeChanged(int))); - connect(curveGVarCB, SIGNAL(stateChanged(int)), this, SLOT(gvarCBChanged(int))); - connect(curveValueCB, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesChanged())); - connect(curveValueSB, SIGNAL(editingFinished()), this, SLOT(valuesChanged())); - - update(); -} - -void CurveGroup::update() -{ - lock = true; - - int found = curveTypeCB->findData(curve.type); - if (found < 0) found = 0; - curveTypeCB->setCurrentIndex(found); - - if (curve.type == CurveReference::CURVE_REF_DIFF || curve.type == CurveReference::CURVE_REF_EXPO) { - curveGVarCB->setVisible(getCurrentFirmware()->getCapability(Gvars)); - if (curve.value > 100 || curve.value < -100) { - curveGVarCB->setChecked(true); - if (lastType != CurveReference::CURVE_REF_DIFF && lastType != CurveReference::CURVE_REF_EXPO) { - lastType = curve.type; - Helpers::populateGVCB(*curveValueCB, curve.value, model); - } - curveValueCB->show(); - curveValueSB->hide(); - } - else { - curveGVarCB->setChecked(false); - curveValueSB->setMinimum(-100); - curveValueSB->setMaximum(100); - curveValueSB->setValue(curve.value); - curveValueSB->show(); - curveValueCB->hide(); - } - } - else { - curveGVarCB->hide(); - curveValueSB->hide(); - curveValueCB->show(); - switch (curve.type) { - case CurveReference::CURVE_REF_FUNC: - if (lastType != curve.type) { - lastType = curve.type; - curveValueCB->clear(); - for (int i=0; i<=6/*TODO constant*/; i++) { - curveValueCB->addItem(CurveReference(CurveReference::CURVE_REF_FUNC, i).toString(&model, false)); - } - } - curveValueCB->setCurrentIndex(curve.value); - break; - case CurveReference::CURVE_REF_CUSTOM: - { - int numcurves = getCurrentFirmware()->getCapability(NumCurves); - if (lastType != curve.type) { - lastType = curve.type; - curveValueCB->clear(); - for (int i= ((flags & HIDE_NEGATIVE_CURVES) ? 0 : -numcurves); i<=numcurves; i++) { - curveValueCB->addItem(CurveReference(CurveReference::CURVE_REF_CUSTOM, i).toString(&model, false), i); - if (i == curve.value) { - curveValueCB->setCurrentIndex(curveValueCB->count() - 1); - } - } - } - break; - } - default: - break; - } - } - - lock = false; -} - -void CurveGroup::gvarCBChanged(int state) -{ - if (!lock) { - if (state) { - curve.value = 10000+1; // TODO constant in EEpromInterface ... - lastType = -1; // quickfix for issue #3518: force refresh of curveValueCB at next update() to set current index to GV1 - } - else { - curve.value = 0; // TODO could be better - } - - update(); - } -} - -void CurveGroup::typeChanged(int value) -{ - if (!lock) { - int type = curveTypeCB->itemData(curveTypeCB->currentIndex()).toInt(); - switch (type) { - case 0: - curve = CurveReference(CurveReference::CURVE_REF_DIFF, 0); - break; - case 1: - curve = CurveReference(CurveReference::CURVE_REF_EXPO, 0); - break; - case 2: - curve = CurveReference(CurveReference::CURVE_REF_FUNC, 0); - break; - case 3: - curve = CurveReference(CurveReference::CURVE_REF_CUSTOM, 0); - break; - } - - update(); - } -} - -void CurveGroup::valuesChanged() -{ - if (!lock) { - switch (curveTypeCB->itemData(curveTypeCB->currentIndex()).toInt()) { - case 0: - case 1: - { - int value; - if (curveGVarCB->isChecked()) - value = curveValueCB->itemData(curveValueCB->currentIndex()).toInt(); - else - value = curveValueSB->value(); - curve = CurveReference(curveTypeCB->itemData(curveTypeCB->currentIndex()).toInt() == 0 ? CurveReference::CURVE_REF_DIFF : CurveReference::CURVE_REF_EXPO, value); - break; - } - case 2: - curve = CurveReference(CurveReference::CURVE_REF_FUNC, curveValueCB->currentIndex()); - break; - case 3: - curve = CurveReference(CurveReference::CURVE_REF_CUSTOM, curveValueCB->itemData(curveValueCB->currentIndex()).toInt()); - break; - } - - update(); - } -} - - /* * Helpers namespace functions */ @@ -399,26 +235,6 @@ void Helpers::populateGVCB(QComboBox & b, int value, const ModelData & model) b.setCurrentIndex(count); } -// Returns Diff/Expo/Weight/Offset adjustment value as either a percentage or a global variable name. -QString Helpers::getAdjustmentString(int16_t val, const ModelData * model, bool sign) -{ - QString ret; - if (val >= -10000 && val <= 10000) { - ret = "%1%"; - if (sign && val > 0) - ret.prepend("+"); - ret = ret.arg(val); - } - else { - ret = RawSource(SOURCE_TYPE_GVAR, abs(val) - 10001).toString(model); - if (val < 0) - ret.prepend("-"); - else if (sign) - ret.prepend("+"); - } - return ret; -} - // TODO: Move lookup to GVarData class (w/out combobox) void Helpers::populateGvarUseCB(QComboBox * b, unsigned int phase) { @@ -742,7 +558,8 @@ GpsCoord extractGpsCoordinates(const QString & position) return result; } -TableLayout::TableLayout(QWidget * parent, int rowCount, const QStringList & headerLabels) +TableLayout::TableLayout(QWidget * parent, int rowCount, const QStringList & headerLabels) : + QObject(parent) { #if defined(TABLE_LAYOUT) tableWidget = new QTableWidget(parent); diff --git a/companion/src/helpers.h b/companion/src/helpers.h index 8a7399c56..107ca2aa0 100644 --- a/companion/src/helpers.h +++ b/companion/src/helpers.h @@ -98,40 +98,10 @@ class GVarGroup: public QObject { bool lock; }; -#define HIDE_DIFF 0x01 -#define HIDE_EXPO 0x02 -#define HIDE_NEGATIVE_CURVES 0x04 - -class CurveGroup : public QObject { - - Q_OBJECT - - public: - CurveGroup(QComboBox *curveTypeCB, QCheckBox *curveGVarCB, QComboBox *curveValueCB, QSpinBox *curveValueSB, CurveReference & curve, const ModelData & model, unsigned int flags=0); - void update(); - - protected slots: - void gvarCBChanged(int); - void typeChanged(int); - void valuesChanged(); - - protected: - QComboBox *curveTypeCB; - QCheckBox *curveGVarCB; - QComboBox *curveValueCB; - QSpinBox *curveValueSB; - CurveReference & curve; - const ModelData & model; - unsigned int flags; - bool lock; - int lastType; -}; - namespace Helpers { void populateGvarUseCB(QComboBox *b, unsigned int phase); void populateGVCB(QComboBox & b, int value, const ModelData & model); - QString getAdjustmentString(int16_t val, const ModelData * model = NULL, bool sign = false); void populateFileComboBox(QComboBox * b, const QSet & set, const QString & current); void getFileComboBoxValue(QComboBox * b, char * dest, int length); @@ -208,8 +178,9 @@ private: GpsCoord extractGpsCoordinates(const QString & position); -class TableLayout +class TableLayout: public QObject { + Q_OBJECT public: TableLayout(QWidget * parent, int rowCount, const QStringList & headerLabels); // ~TableLayout() ; diff --git a/companion/src/modeledit/channels.cpp b/companion/src/modeledit/channels.cpp index 6442cc2fb..d2818368e 100644 --- a/companion/src/modeledit/channels.cpp +++ b/companion/src/modeledit/channels.cpp @@ -20,6 +20,7 @@ #include "channels.h" #include "helpers.h" +#include "rawitemfilteredmodel.h" LimitsGroup::LimitsGroup(Firmware * firmware, TableLayout * tableLayout, int row, int col, int & value, const ModelData & model, int min, int max, int deflt, ModelPanel * panel): firmware(firmware), @@ -95,15 +96,17 @@ void LimitsGroup::updateMinMax(int max) } } } - -Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware): - ModelPanel(parent, model, generalSettings, firmware) +ChannelsPanel::ChannelsPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels): + ModelPanel(parent, model, generalSettings, firmware), + commonItemModels(commonItemModels) { - Stopwatch s1("Channels"); - chnCapability = firmware->getCapability(Outputs); int channelNameMaxLen = firmware->getCapability(ChannelsName); + curveFilteredModel = new RawItemFilteredModel(commonItemModels->curveItemModel(), RawItemFilteredModel::AllFilter, this); + connect(curveFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &ChannelsPanel::onModelDataAboutToBeUpdated); + connect(curveFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &ChannelsPanel::onModelDataUpdateComplete); + QStringList headerLabels; headerLabels << "#"; if (channelNameMaxLen > 0) { @@ -118,8 +121,6 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera headerLabels << tr("Linear Subtrim"); TableLayout *tableLayout = new TableLayout(this, chnCapability, headerLabels); - s1.report("header"); - for (int i = 0; i < chnCapability; i++) { int col = 0; @@ -165,6 +166,7 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera if (IS_HORUS_OR_TARANIS(firmware->getBoard())) { curveCB[i] = new QComboBox(this); curveCB[i]->setProperty("index", i); + curveCB[i]->setModel(curveFilteredModel); connect(curveCB[i], SIGNAL(currentIndexChanged(int)), this, SLOT(curveEdited())); tableLayout->addWidget(i, col++, curveCB[i]); } @@ -193,15 +195,13 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera } } update(); - s1.report("add elements"); disableMouseScrolling(); tableLayout->resizeColumnsToContents(); tableLayout->pushRowsUp(chnCapability+1); - s1.report("end"); } -Channels::~Channels() +ChannelsPanel::~ChannelsPanel() { // compiler warning if delete[] for (int i = 0; i < CPN_MAX_CHNOUT; i++) { @@ -216,7 +216,7 @@ Channels::~Channels() } } -void Channels::symlimitsEdited() +void ChannelsPanel::symlimitsEdited() { if (!lock) { QCheckBox *ckb = qobject_cast(sender()); @@ -226,17 +226,20 @@ void Channels::symlimitsEdited() } } -void Channels::nameEdited() +void ChannelsPanel::nameEdited() { if (!lock) { QLineEdit *le = qobject_cast(sender()); int index = le->property("index").toInt(); - strcpy(model->limitData[index].name, le->text().toLatin1()); - emit modified(); + if (model->limitData[index].name != le->text()) { + strcpy(model->limitData[index].name, le->text().toLatin1()); + updateItemModels(); + emit modified(); + } } } -void Channels::refreshExtendedLimits() +void ChannelsPanel::refreshExtendedLimits() { int channelMax = model->getChannelsMax(); @@ -248,7 +251,7 @@ void Channels::refreshExtendedLimits() emit modified(); } -void Channels::invEdited() +void ChannelsPanel::invEdited() { if (!lock) { QComboBox *cb = qobject_cast(sender()); @@ -258,17 +261,20 @@ void Channels::invEdited() } } -void Channels::curveEdited() +void ChannelsPanel::curveEdited() { if (!lock) { QComboBox *cb = qobject_cast(sender()); int index = cb->property("index").toInt(); - model->limitData[index].curve = CurveReference(CurveReference::CURVE_REF_CUSTOM, cb->itemData(cb->currentIndex()).toInt()); - emit modified(); + // ignore unnecessary updates that could be triggered by updates to the data model + if (model->limitData[index].curve != CurveReference(CurveReference::CURVE_REF_CUSTOM, cb->itemData(cb->currentIndex()).toInt())) { + model->limitData[index].curve = CurveReference(CurveReference::CURVE_REF_CUSTOM, cb->itemData(cb->currentIndex()).toInt()); + emit modified(); + } } } -void Channels::ppmcenterEdited() +void ChannelsPanel::ppmcenterEdited() { if (!lock) { QSpinBox *sb = qobject_cast(sender()); @@ -278,51 +284,49 @@ void Channels::ppmcenterEdited() } } -void Channels::update() +void ChannelsPanel::update() { for (int i = 0; i < chnCapability; i++) { updateLine(i); } } -void Channels::updateLine(int i) +void ChannelsPanel::updateLine(int i) { lock = true; + LimitData &chn = model->limitData[i]; + if (firmware->getCapability(ChannelsName) > 0) { - name[i]->setText(model->limitData[i].name); + name[i]->setText(chn.name); } - chnOffset[i]->setValue(model->limitData[i].offset); - chnMin[i]->setValue(model->limitData[i].min); - chnMax[i]->setValue(model->limitData[i].max); - invCB[i]->setCurrentIndex((model->limitData[i].revert) ? 1 : 0); + chnOffset[i]->setValue(chn.offset); + chnMin[i]->setValue(chn.min); + chnMax[i]->setValue(chn.max); + invCB[i]->setCurrentIndex((chn.revert) ? 1 : 0); if (IS_HORUS_OR_TARANIS(firmware->getBoard())) { - int numcurves = firmware->getCapability(NumCurves); - curveCB[i]->clear(); - for (int j = -numcurves; j <= numcurves; j++) { - curveCB[i]->addItem(CurveReference(CurveReference::CURVE_REF_CUSTOM, j).toString(model, false), j); - } - curveCB[i]->setCurrentIndex(model->limitData[i].curve.value + numcurves); + curveCB[i]->setCurrentIndex(curveCB[i]->findData(chn.curve.value)); } if (firmware->getCapability(PPMCenter)) { - centerSB[i]->setValue(model->limitData[i].ppmCenter + 1500); + centerSB[i]->setValue(chn.ppmCenter + 1500); } if (firmware->getCapability(SYMLimits)) { - symlimitsChk[i]->setChecked(model->limitData[i].symetrical); + symlimitsChk[i]->setChecked(chn.symetrical); } lock = false; } -void Channels::cmPaste() +void ChannelsPanel::cmPaste() { QByteArray data; if (hasClipboardData(&data)) { memcpy(&model->limitData[selectedIndex], data.constData(), sizeof(LimitData)); updateLine(selectedIndex); + updateItemModels(); emit modified(); } } -void Channels::cmDelete() +void ChannelsPanel::cmDelete() { if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Delete Channel. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) return; @@ -335,10 +339,11 @@ void Channels::cmDelete() updateLine(i); } + updateItemModels(); emit modified(); } -void Channels::cmCopy() +void ChannelsPanel::cmCopy() { QByteArray data; data.append((char*)&model->limitData[selectedIndex], sizeof(LimitData)); @@ -347,7 +352,7 @@ void Channels::cmCopy() QApplication::clipboard()->setMimeData(mimeData,QClipboard::Clipboard); } -void Channels::cmCut() +void ChannelsPanel::cmCut() { if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Cut Channel. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) return; @@ -356,7 +361,7 @@ void Channels::cmCut() cmClear(false); } -void Channels::onCustomContextMenuRequested(QPoint pos) +void ChannelsPanel::onCustomContextMenuRequested(QPoint pos) { QLabel *label = (QLabel *)sender(); selectedIndex = label->property("index").toInt(); @@ -378,7 +383,7 @@ void Channels::onCustomContextMenuRequested(QPoint pos) contextMenu.exec(globalPos); } -bool Channels::hasClipboardData(QByteArray * data) const +bool ChannelsPanel::hasClipboardData(QByteArray * data) const { const QClipboard * clipboard = QApplication::clipboard(); const QMimeData * mimeData = clipboard->mimeData(); @@ -390,32 +395,32 @@ bool Channels::hasClipboardData(QByteArray * data) const return false; } -bool Channels::insertAllowed() const +bool ChannelsPanel::insertAllowed() const { return ((selectedIndex < chnCapability - 1) && (model->limitData[chnCapability - 1].isEmpty())); } -bool Channels::moveDownAllowed() const +bool ChannelsPanel::moveDownAllowed() const { return selectedIndex < chnCapability - 1; } -bool Channels::moveUpAllowed() const +bool ChannelsPanel::moveUpAllowed() const { return selectedIndex > 0; } -void Channels::cmMoveUp() +void ChannelsPanel::cmMoveUp() { swapData(selectedIndex, selectedIndex - 1); } -void Channels::cmMoveDown() +void ChannelsPanel::cmMoveDown() { swapData(selectedIndex, selectedIndex + 1); } -void Channels::cmClear(bool prompt) +void ChannelsPanel::cmClear(bool prompt) { if (prompt) { if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear Channel. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) @@ -425,10 +430,11 @@ void Channels::cmClear(bool prompt) model->limitData[selectedIndex].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_CHANNEL, ModelData::REF_UPD_ACT_CLEAR, selectedIndex); updateLine(selectedIndex); + updateItemModels(); emit modified(); } -void Channels::cmClearAll() +void ChannelsPanel::cmClearAll() { if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear all Channels. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) return; @@ -438,19 +444,21 @@ void Channels::cmClearAll() model->updateAllReferences(ModelData::REF_UPD_TYPE_CHANNEL, ModelData::REF_UPD_ACT_CLEAR, i); updateLine(i); } + updateItemModels(); emit modified(); } -void Channels::cmInsert() +void ChannelsPanel::cmInsert() { memmove(&model->limitData[selectedIndex + 1], &model->limitData[selectedIndex], (CPN_MAX_CHNOUT - (selectedIndex + 1)) * sizeof(LimitData)); model->limitData[selectedIndex].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_CHANNEL, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, 1); update(); + updateItemModels(); emit modified(); } -void Channels::swapData(int idx1, int idx2) +void ChannelsPanel::swapData(int idx1, int idx2) { if ((idx1 != idx2) && (!model->limitData[idx1].isEmpty() || !model->limitData[idx2].isEmpty())) { LimitData chntmp = model->limitData[idx2]; @@ -461,6 +469,23 @@ void Channels::swapData(int idx1, int idx2) model->updateAllReferences(ModelData::REF_UPD_TYPE_CHANNEL, ModelData::REF_UPD_ACT_SWAP, idx1, idx2); updateLine(idx1); updateLine(idx2); + updateItemModels(); emit modified(); } } + +void ChannelsPanel::onModelDataAboutToBeUpdated() +{ + lock = true; +} + +void ChannelsPanel::onModelDataUpdateComplete() +{ + update(); + lock = false; +} + +void ChannelsPanel::updateItemModels() +{ + commonItemModels->update(CommonItemModels::RMO_CHANNELS); +} diff --git a/companion/src/modeledit/channels.h b/companion/src/modeledit/channels.h index d20923a35..a481feec2 100644 --- a/companion/src/modeledit/channels.h +++ b/companion/src/modeledit/channels.h @@ -26,6 +26,9 @@ #include +class CommonItemModels; +class RawItemFilteredModel; + constexpr char MIMETYPE_CHANNEL[] = "application/x-companion-channel"; class GVarGroup; @@ -49,13 +52,13 @@ class LimitsGroup double displayStep; }; -class Channels : public ModelPanel +class ChannelsPanel : public ModelPanel { Q_OBJECT public: - Channels(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware); - ~Channels(); + ChannelsPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels); + ~ChannelsPanel(); public slots: void refreshExtendedLimits(); @@ -78,6 +81,8 @@ class Channels : public ModelPanel void cmClear(bool prompt = true); void cmClearAll(); void onCustomContextMenuRequested(QPoint pos); + void onModelDataAboutToBeUpdated(); + void onModelDataUpdateComplete(); private: bool hasClipboardData(QByteArray * data = nullptr) const; @@ -95,6 +100,9 @@ class Channels : public ModelPanel QCheckBox *symlimitsChk[CPN_MAX_CHNOUT]; int selectedIndex; int chnCapability; + CommonItemModels * commonItemModels; + RawItemFilteredModel *curveFilteredModel; + void updateItemModels(); }; #endif // _CHANNELS_H_ diff --git a/companion/src/modeledit/curves.cpp b/companion/src/modeledit/curves.cpp index da056964e..9e60f30c3 100644 --- a/companion/src/modeledit/curves.cpp +++ b/companion/src/modeledit/curves.cpp @@ -23,6 +23,7 @@ #include "node.h" #include "edge.h" #include "helpers.h" +#include "rawitemfilteredmodel.h" #define GFX_MARGIN 16 @@ -108,10 +109,11 @@ float curveSymmetricalX(float x, float coeff, float yMin, float yMid, float yMax return y; } -Curves::Curves(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware): +CurvesPanel::CurvesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels): ModelPanel(parent, model, generalSettings, firmware), ui(new Ui::Curves), - currentCurve(0) + currentCurve(0), + commonItemModels(commonItemModels) { ui->setupUi(this); @@ -230,12 +232,12 @@ Curves::Curves(QWidget * parent, ModelData & model, GeneralSettings & generalSet lock = false; } -Curves::~Curves() +CurvesPanel::~CurvesPanel() { delete ui; } -void Curves::editCurve() +void CurvesPanel::editCurve() { QPushButton *button = (QPushButton *)sender(); int index = button->property("index").toInt(); @@ -243,7 +245,7 @@ void Curves::editCurve() update(); } -void Curves::plotCurve(bool checked) +void CurvesPanel::plotCurve(bool checked) { QCheckBox *chk = (QCheckBox *)sender(); int index = chk->property("index").toInt(); @@ -251,7 +253,7 @@ void Curves::plotCurve(bool checked) updateCurve(); } -void Curves::update() +void CurvesPanel::update() { lock = true; @@ -266,12 +268,12 @@ void Curves::update() lock = false; } -void Curves::setCurrentCurve(int index) +void CurvesPanel::setCurrentCurve(int index) { currentCurve = index; } -void Curves::updateCurveType() +void CurvesPanel::updateCurveType() { lock = true; @@ -297,7 +299,7 @@ void Curves::updateCurveType() lock = false; } -void Curves::updateCurve() +void CurvesPanel::updateCurve() { lock = true; @@ -371,7 +373,7 @@ void Curves::updateCurve() lock = false; } -void Curves::updateCurvePoints() +void CurvesPanel::updateCurvePoints() { lock = true; @@ -405,7 +407,7 @@ void Curves::updateCurvePoints() lock = false; } -void Curves::onPointEdited() +void CurvesPanel::onPointEdited() { if (!lock) { int index = sender()->property("index").toInt(); @@ -417,7 +419,7 @@ void Curves::onPointEdited() } } -void Curves::onNodeMoved(int x, int y) +void CurvesPanel::onNodeMoved(int x, int y) { if (!lock) { lock = true; @@ -435,20 +437,20 @@ void Curves::onNodeMoved(int x, int y) } } -void Curves::onNodeFocus() +void CurvesPanel::onNodeFocus() { int index = sender()->property("index").toInt(); spny[index]->setFocus(); } -void Curves::onNodeUnfocus() +void CurvesPanel::onNodeUnfocus() { int index = sender()->property("index").toInt(); spny[index]->clearFocus(); updateCurve(); } -bool Curves::allowCurveType(int points, CurveData::CurveType type) +bool CurvesPanel::allowCurveType(int points, CurveData::CurveType type) { int totalpoints = 0; for (int i = 0; i < maxCurves; i++) { @@ -466,7 +468,7 @@ bool Curves::allowCurveType(int points, CurveData::CurveType type) } } -void Curves::on_curvePoints_currentIndexChanged(int index) +void CurvesPanel::on_curvePoints_currentIndexChanged(int index) { if (!lock) { int numpoints = ((QComboBox *)sender())->itemData(index).toInt(); @@ -489,7 +491,7 @@ void Curves::on_curvePoints_currentIndexChanged(int index) } } -void Curves::on_curveCustom_currentIndexChanged(int index) +void CurvesPanel::on_curveCustom_currentIndexChanged(int index) { if (!lock) { CurveData::CurveType type = (CurveData::CurveType)index; @@ -513,20 +515,23 @@ void Curves::on_curveCustom_currentIndexChanged(int index) } } -void Curves::on_curveSmooth_currentIndexChanged(int index) +void CurvesPanel::on_curveSmooth_currentIndexChanged(int index) { model->curves[currentCurve].smooth = index; update(); } -void Curves::on_curveName_editingFinished() +void CurvesPanel::on_curveName_editingFinished() { - memset(model->curves[currentCurve].name, 0, sizeof(model->curves[currentCurve].name)); - strcpy(model->curves[currentCurve].name, ui->curveName->text().toLatin1()); - emit modified(); + if (ui->curveName->text() != model->curves[currentCurve].name) { + memset(model->curves[currentCurve].name, 0, sizeof(model->curves[currentCurve].name)); + strcpy(model->curves[currentCurve].name, ui->curveName->text().toLatin1()); + updateItemModels(); + emit modified(); + } } -void Curves::resizeEvent(QResizeEvent *event) +void CurvesPanel::resizeEvent(QResizeEvent *event) { QRect qr = ui->curvePreview->contentsRect(); ui->curvePreview->scene()->setSceneRect(GFX_MARGIN, GFX_MARGIN, qr.width() - GFX_MARGIN * 2, qr.height() - GFX_MARGIN * 2); @@ -534,7 +539,7 @@ void Curves::resizeEvent(QResizeEvent *event) ModelPanel::resizeEvent(event); } -void Curves::on_curveType_currentIndexChanged(int index) +void CurvesPanel::on_curveType_currentIndexChanged(int index) { unsigned int flags = templates[index].flags; ui->curveCoeffLabel->setVisible(flags & CURVE_COEFF_ENABLE); @@ -548,7 +553,7 @@ void Curves::on_curveType_currentIndexChanged(int index) ui->yMin->setValue(-100); } -void Curves::addTemplate(QString name, unsigned int flags, curveFunction function) +void CurvesPanel::addTemplate(QString name, unsigned int flags, curveFunction function) { CurveCreatorTemplate tmpl; tmpl.name = name; @@ -558,7 +563,7 @@ void Curves::addTemplate(QString name, unsigned int flags, curveFunction functio ui->curveType->addItem(name); } -void Curves::on_curveApply_clicked() +void CurvesPanel::on_curveApply_clicked() { int index = ui->curveType->currentIndex(); int numpoints = model->curves[currentCurve].count; @@ -595,14 +600,14 @@ void Curves::on_curveApply_clicked() emit modified(); } -void Curves::onPointSizeEdited() +void CurvesPanel::onPointSizeEdited() { if (!lock) { update(); } } -void Curves::onNodeDelete() +void CurvesPanel::onNodeDelete() { int index = sender()->property("index").toInt(); int numpoints = model->curves[currentCurve].count; @@ -620,7 +625,7 @@ void Curves::onNodeDelete() } } -void Curves::onSceneNewPoint(int x, int y) +void CurvesPanel::onSceneNewPoint(int x, int y) { if ((model->curves[currentCurve].type == CurveData::CURVE_TYPE_CUSTOM) && (model->curves[currentCurve].count < CPN_MAX_POINTS)) { int newidx = 0; @@ -651,7 +656,7 @@ void Curves::onSceneNewPoint(int x, int y) } } -void Curves::onCustomContextMenuRequested(QPoint pos) +void CurvesPanel::onCustomContextMenuRequested(QPoint pos) { QPushButton *button = (QPushButton *)sender(); selectedIndex = button->property("index").toInt(); @@ -673,7 +678,7 @@ void Curves::onCustomContextMenuRequested(QPoint pos) contextMenu.exec(globalPos); } -bool Curves::hasClipboardData(QByteArray * data) const +bool CurvesPanel::hasClipboardData(QByteArray * data) const { const QClipboard * clipboard = QApplication::clipboard(); const QMimeData * mimeData = clipboard->mimeData(); @@ -685,22 +690,22 @@ bool Curves::hasClipboardData(QByteArray * data) const return false; } -bool Curves::insertAllowed() const +bool CurvesPanel::insertAllowed() const { return ((selectedIndex < maxCurves - 1) && (model->curves[maxCurves - 1].isEmpty())); } -bool Curves::moveDownAllowed() const +bool CurvesPanel::moveDownAllowed() const { return selectedIndex < maxCurves - 1; } -bool Curves::moveUpAllowed() const +bool CurvesPanel::moveUpAllowed() const { return selectedIndex > 0; } -void Curves::cmClear(bool prompt) +void CurvesPanel::cmClear(bool prompt) { if (prompt) { if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear Curve. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) @@ -710,10 +715,11 @@ void Curves::cmClear(bool prompt) model->curves[selectedIndex].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_CURVE, ModelData::REF_UPD_ACT_CLEAR, selectedIndex); update(); + updateItemModels(); emit modified(); } -void Curves::cmClearAll() +void CurvesPanel::cmClearAll() { if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear all Curves. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) return; @@ -723,10 +729,11 @@ void Curves::cmClearAll() model->updateAllReferences(ModelData::REF_UPD_TYPE_CURVE, ModelData::REF_UPD_ACT_CLEAR, i); } update(); + updateItemModels(); emit modified(); } -void Curves::cmCopy() +void CurvesPanel::cmCopy() { QByteArray data; data.append((char*)&model->curves[selectedIndex], sizeof(CurveData)); @@ -735,7 +742,7 @@ void Curves::cmCopy() QApplication::clipboard()->setMimeData(mimeData,QClipboard::Clipboard); } -void Curves::cmCut() +void CurvesPanel::cmCut() { if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Cut Curve. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) return; @@ -743,7 +750,7 @@ void Curves::cmCut() cmClear(false); } -void Curves::cmDelete() +void CurvesPanel::cmDelete() { if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Delete Curve. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) return; @@ -752,40 +759,43 @@ void Curves::cmDelete() model->curves[maxCurves - 1].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_CURVE, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, -1); update(); + updateItemModels(); emit modified(); } -void Curves::cmInsert() +void CurvesPanel::cmInsert() { memmove(&model->curves[selectedIndex + 1], &model->curves[selectedIndex], (CPN_MAX_CURVES - (selectedIndex + 1)) * sizeof(CurveData)); model->curves[selectedIndex].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_CURVE, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, 1); update(); + updateItemModels(); emit modified(); } -void Curves::cmMoveDown() +void CurvesPanel::cmMoveDown() { swapData(selectedIndex, selectedIndex + 1); } -void Curves::cmMoveUp() +void CurvesPanel::cmMoveUp() { swapData(selectedIndex, selectedIndex - 1); } -void Curves::cmPaste() +void CurvesPanel::cmPaste() { QByteArray data; if (hasClipboardData(&data)) { CurveData *cd = &model->curves[selectedIndex]; memcpy(cd, data.constData(), sizeof(CurveData)); update(); + updateItemModels(); emit modified(); } } -void Curves::swapData(int idx1, int idx2) +void CurvesPanel::swapData(int idx1, int idx2) { if ((idx1 != idx2) && (!model->curves[idx1].isEmpty() || !model->curves[idx2].isEmpty())) { CurveData cdtmp = model->curves[idx2]; @@ -795,10 +805,16 @@ void Curves::swapData(int idx1, int idx2) memcpy(cd1, &cdtmp, sizeof(CurveData)); model->updateAllReferences(ModelData::REF_UPD_TYPE_CURVE, ModelData::REF_UPD_ACT_SWAP, idx1, idx2); update(); + updateItemModels(); emit modified(); } } +void CurvesPanel::updateItemModels() +{ + commonItemModels->update(CommonItemModels::RMO_CURVES); +} + CustomScene::CustomScene(QGraphicsView * view) : QGraphicsScene(view) { diff --git a/companion/src/modeledit/curves.h b/companion/src/modeledit/curves.h index 34d1a675e..8df3a8528 100644 --- a/companion/src/modeledit/curves.h +++ b/companion/src/modeledit/curves.h @@ -26,6 +26,8 @@ #include #include +class CommonItemModels; + constexpr char MIMETYPE_CURVE[] = "application/x-companion-curve"; namespace Ui { @@ -54,13 +56,13 @@ class CustomScene : public QGraphicsScene virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent * event) override; }; -class Curves : public ModelPanel +class CurvesPanel : public ModelPanel { Q_OBJECT public: - Curves(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware); - virtual ~Curves(); + CurvesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels); + virtual ~CurvesPanel(); virtual void update(); @@ -119,6 +121,8 @@ class Curves : public ModelPanel bool moveDownAllowed() const; bool moveUpAllowed() const; void swapData(int idx1, int idx2); + CommonItemModels * commonItemModels; + void updateItemModels(); }; #endif // _CURVES_H_ diff --git a/companion/src/modeledit/customfunctions.cpp b/companion/src/modeledit/customfunctions.cpp index 36dba9c97..c3ee895b7 100644 --- a/companion/src/modeledit/customfunctions.cpp +++ b/companion/src/modeledit/customfunctions.cpp @@ -41,7 +41,7 @@ RepeatComboBox::RepeatComboBox(QWidget *parent, int & repeatParam): addItem(tr("No repeat"), 0); - for (unsigned int i=step; i<=60; i+=step) { + for (unsigned int i = step; i <= 60; i += step) { addItem(tr("%1s").arg(i), i); } @@ -66,24 +66,36 @@ void RepeatComboBox::update() setCurrentIndex(value); } -CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, GeneralSettings & generalSettings, Firmware * firmware): +CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels): GenericPanel(parent, model, generalSettings, firmware), functions(model ? model->customFn : generalSettings.customFn), + commonItemModels(commonItemModels), mediaPlayerCurrent(-1), - mediaPlayer(nullptr) + mediaPlayer(nullptr), + modelsUpdateCnt(0) { - Stopwatch s1("CustomFunctionsPanel - populate"); lock = true; fswCapability = model ? firmware->getCapability(CustomFunctions) : firmware->getCapability(GlobalFunctions); - rawSwitchItemModel = new RawSwitchFilterItemModel(&generalSettings, model, model ? RawSwitch::SpecialFunctionsContext : RawSwitch::GlobalFunctionsContext, this); - rawSrcAllItemModel = new RawSourceFilterItemModel(&generalSettings, model, this); - rawSrcInputsItemModel = new RawSourceFilterItemModel(rawSrcAllItemModel->sourceModel(), RawSource::InputSourceGroups, this); - rawSrcGVarsItemModel = new RawSourceFilterItemModel(rawSrcAllItemModel->sourceModel(), RawSource::GVarsGroup, this); + rawSwitchFilteredModel = new RawItemFilteredModel(commonItemModels->rawSwitchItemModel(), model ? RawSwitch::SpecialFunctionsContext : RawSwitch::GlobalFunctionsContext, this); + connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &CustomFunctionsPanel::onModelDataAboutToBeUpdated); + connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &CustomFunctionsPanel::onModelDataUpdateComplete); + + rawSourceAllModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), this); + connect(rawSourceAllModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &CustomFunctionsPanel::onModelDataAboutToBeUpdated); + connect(rawSourceAllModel, &RawItemFilteredModel::dataUpdateComplete, this, &CustomFunctionsPanel::onModelDataUpdateComplete); + + rawSourceInputsModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), RawSource::InputSourceGroups, this); + connect(rawSourceInputsModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &CustomFunctionsPanel::onModelDataAboutToBeUpdated); + connect(rawSourceInputsModel, &RawItemFilteredModel::dataUpdateComplete, this, &CustomFunctionsPanel::onModelDataUpdateComplete); + + rawSourceGVarsModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), RawSource::GVarsGroup, this); + connect(rawSourceGVarsModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &CustomFunctionsPanel::onModelDataAboutToBeUpdated); + connect(rawSourceGVarsModel, &RawItemFilteredModel::dataUpdateComplete, this, &CustomFunctionsPanel::onModelDataUpdateComplete); if (!firmware->getCapability(VoicesAsNumbers)) { tracksSet = getFilesSet(getSoundsPath(generalSettings), QStringList() << "*.wav" << "*.WAV", firmware->getCapability(VoicesMaxLength)); - for (int i=0; igetBoard())) { scriptsSet = getFilesSet(g.profile[g.id()].sdPath() + "/SCRIPTS/FUNCTIONS", QStringList() << "*.lua", firmware->getCapability(VoicesMaxLength)); - for (int i=0; isetContextMenuPolicy(Qt::CustomContextMenu); @@ -123,9 +132,9 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, label->setMouseTracking(true); label->setProperty("index", i); if (model) - label->setText(tr("SF%1").arg(i+1)); + label->setText(tr("SF%1").arg(i + 1)); else - label->setText(tr("GF%1").arg(i+1)); + label->setText(tr("GF%1").arg(i + 1)); label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum); connect(label, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onCustomContextMenuRequested(QPoint))); tableLayout->addWidget(i, 0, label); @@ -133,7 +142,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, // The switch fswtchSwtch[i] = new QComboBox(this); - fswtchSwtch[i]->setModel(rawSwitchItemModel); + fswtchSwtch[i]->setModel(rawSwitchFilteredModel); fswtchSwtch[i]->setCurrentIndex(fswtchSwtch[i]->findData(functions[i].swtch.toValue())); fswtchSwtch[i]->setProperty("index", i); fswtchSwtch[i]->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Minimum); @@ -198,7 +207,6 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, fswtchParamArmT[i]->setEditable(true); fswtchParamArmT[i]->setSizeAdjustPolicy(QComboBox::AdjustToContents); paramLayout->addWidget(fswtchParamArmT[i]); - connect(fswtchParamArmT[i], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited())); connect(fswtchParamArmT[i], SIGNAL(editTextChanged ( const QString)), this, SLOT(customFunctionEdited())); @@ -221,31 +229,24 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, QHBoxLayout * repeatLayout = new QHBoxLayout(); tableLayout->addLayout(i, 4, repeatLayout); fswtchRepeat[i] = new RepeatComboBox(this, functions[i].repeatParam); - repeatLayout->addWidget(fswtchRepeat[i], i+1); - connect(fswtchRepeat[i], SIGNAL(modified()), this, SLOT(onChildModified())); + repeatLayout->addWidget(fswtchRepeat[i], i + 1); + connect(fswtchRepeat[i], SIGNAL(modified()), this, SLOT(onRepeatModified())); fswtchEnable[i] = new QCheckBox(this); fswtchEnable[i]->setProperty("index", i); fswtchEnable[i]->setText(tr("ON")); fswtchEnable[i]->setFixedWidth(200); - repeatLayout->addWidget(fswtchEnable[i], i+1); + repeatLayout->addWidget(fswtchEnable[i], i + 1); connect(fswtchEnable[i], SIGNAL(stateChanged(int)), this, SLOT(customFunctionEdited())); } - s1.report("add items"); - disableMouseScrolling(); - s1.report("disableMouseScrolling"); - - lock = false; + tableLayout->resizeColumnsToContents(); + tableLayout->setColumnWidth(3, 300); + tableLayout->pushRowsUp(fswCapability + 1); update(); - s1.report("update"); - tableLayout->resizeColumnsToContents(); - s1.report("resizeColumnsToContents"); - tableLayout->setColumnWidth(3, 300); - tableLayout->pushRowsUp(fswCapability+1); - s1.report("end"); + lock = false; } CustomFunctionsPanel::~CustomFunctionsPanel() @@ -254,15 +255,6 @@ CustomFunctionsPanel::~CustomFunctionsPanel() stopSound(mediaPlayerCurrent); } -void CustomFunctionsPanel::updateDataModels() -{ - const bool oldLock = lock; - lock = true; - rawSwitchItemModel->update(); - rawSrcAllItemModel->update(); - lock = oldLock; -} - void CustomFunctionsPanel::onMediaPlayerStateChanged(QMediaPlayer::State state) { if (state != QMediaPlayer::PlayingState) @@ -343,6 +335,7 @@ void CustomFunctionsPanel::toggleSound(bool play) #define CUSTOM_FUNCTION_BL_COLOR (1<<9) #define CUSTOM_FUNCTION_SHOW_FUNC (1<<10) + void CustomFunctionsPanel::customFunctionEdited() { if (!lock) { @@ -369,162 +362,155 @@ void CustomFunctionsPanel::functionEdited() } } -void CustomFunctionsPanel::onChildModified() +void CustomFunctionsPanel::onRepeatModified() { emit modified(); } void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) { - CustomFunctionData & cfn = functions[i]; - AssignFunc func = (AssignFunc)fswtchFunc[i]->currentData().toInt(); + CustomFunctionData & cfn = functions[i]; + AssignFunc func = (AssignFunc)fswtchFunc[i]->currentData().toInt(); - unsigned int widgetsMask = 0; - if (modified) { - cfn.swtch = RawSwitch(fswtchSwtch[i]->currentData().toInt()); - cfn.func = func; - cfn.enabled = fswtchEnable[i]->isChecked(); - } + unsigned int widgetsMask = 0; + if (modified) { + cfn.swtch = RawSwitch(fswtchSwtch[i]->currentData().toInt()); + cfn.func = func; + cfn.enabled = fswtchEnable[i]->isChecked(); + } + else { + fswtchSwtch[i]->setCurrentIndex(fswtchSwtch[i]->findData(cfn.swtch.toValue())); + fswtchFunc[i]->setCurrentIndex(fswtchFunc[i]->findData(cfn.func)); + } - if (!cfn.isEmpty()) { - widgetsMask |= CUSTOM_FUNCTION_SHOW_FUNC; + if (!cfn.isEmpty()) { + widgetsMask |= CUSTOM_FUNCTION_SHOW_FUNC; - if (func >= FuncOverrideCH1 && func <= FuncOverrideCH32) { - if (model) { - int channelsMax = model->getChannelsMax(true); - fswtchParam[i]->setDecimals(0); - fswtchParam[i]->setSingleStep(1); - fswtchParam[i]->setMinimum(-channelsMax); - fswtchParam[i]->setMaximum(channelsMax); - if (modified) { - cfn.param = fswtchParam[i]->value(); - } - fswtchParam[i]->setValue(cfn.param); - widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM | CUSTOM_FUNCTION_ENABLE; + if (func >= FuncOverrideCH1 && func <= FuncOverrideCH32) { + if (model) { + int channelsMax = model->getChannelsMax(true); + fswtchParam[i]->setDecimals(0); + fswtchParam[i]->setSingleStep(1); + fswtchParam[i]->setMinimum(-channelsMax); + fswtchParam[i]->setMaximum(channelsMax); + if (modified) { + cfn.param = fswtchParam[i]->value(); } + fswtchParam[i]->setValue(cfn.param); + widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM | CUSTOM_FUNCTION_ENABLE; } - else if (func == FuncLogs) { - fswtchParam[i]->setDecimals(1); - fswtchParam[i]->setMinimum(0); - fswtchParam[i]->setMaximum(25.5); - fswtchParam[i]->setSingleStep(0.1); + } + else if (func == FuncLogs) { + fswtchParam[i]->setDecimals(1); + fswtchParam[i]->setMinimum(0); + fswtchParam[i]->setMaximum(25.5); + fswtchParam[i]->setSingleStep(0.1); + if (modified) + cfn.param = fswtchParam[i]->value() * 10.0; + fswtchParam[i]->setValue(cfn.param / 10.0); + widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM; + } + else if (func >= FuncAdjustGV1 && func <= FuncAdjustGVLast) { + int gvidx = func - FuncAdjustGV1; + if (modified) + cfn.adjustMode = fswtchGVmode[i]->currentIndex(); + fswtchGVmode[i]->setCurrentIndex(cfn.adjustMode); + widgetsMask |= CUSTOM_FUNCTION_GV_MODE | CUSTOM_FUNCTION_ENABLE; + if (cfn.adjustMode == FUNC_ADJUST_GVAR_CONSTANT || cfn.adjustMode == FUNC_ADJUST_GVAR_INCDEC) { if (modified) - cfn.param = fswtchParam[i]->value()*10.0; - fswtchParam[i]->setValue(cfn.param/10.0); - widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM; - } - else if (func >= FuncAdjustGV1 && func <= FuncAdjustGVLast) { - int gvidx = func - FuncAdjustGV1; - if (modified) - cfn.adjustMode = fswtchGVmode[i]->currentIndex(); - fswtchGVmode[i]->setCurrentIndex(cfn.adjustMode); - widgetsMask |= CUSTOM_FUNCTION_GV_MODE | CUSTOM_FUNCTION_ENABLE; - if (cfn.adjustMode == FUNC_ADJUST_GVAR_CONSTANT || cfn.adjustMode == FUNC_ADJUST_GVAR_INCDEC) { - if (modified) - cfn.param = fswtchParam[i]->value() * model->gvarData[gvidx].multiplierSet(); - fswtchParam[i]->setDecimals(model->gvarData[gvidx].prec); - fswtchParam[i]->setSingleStep(model->gvarData[gvidx].multiplierGet()); - fswtchParam[i]->setSuffix(model->gvarData[gvidx].unitToString()); - if (cfn.adjustMode==FUNC_ADJUST_GVAR_INCDEC) { - double rng = abs(model->gvarData[gvidx].getMax() - model->gvarData[gvidx].getMin()); - rng *= model->gvarData[gvidx].multiplierGet(); - fswtchParam[i]->setMinimum(-rng); - fswtchParam[i]->setMaximum(rng); - } - else { - fswtchParam[i]->setMinimum(model->gvarData[gvidx].getMinPrec()); - fswtchParam[i]->setMaximum(model->gvarData[gvidx].getMaxPrec()); - } - fswtchParam[i]->setValue(cfn.param * model->gvarData[gvidx].multiplierGet()); - widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM; + cfn.param = fswtchParam[i]->value() * model->gvarData[gvidx].multiplierSet(); + fswtchParam[i]->setDecimals(model->gvarData[gvidx].prec); + fswtchParam[i]->setSingleStep(model->gvarData[gvidx].multiplierGet()); + fswtchParam[i]->setSuffix(model->gvarData[gvidx].unitToString()); + if (cfn.adjustMode == FUNC_ADJUST_GVAR_INCDEC) { + double rng = abs(model->gvarData[gvidx].getMax() - model->gvarData[gvidx].getMin()); + rng *= model->gvarData[gvidx].multiplierGet(); + fswtchParam[i]->setMinimum(-rng); + fswtchParam[i]->setMaximum(rng); } else { - if (modified) - cfn.param = fswtchParamT[i]->currentData().toInt(); - populateFuncParamCB(fswtchParamT[i], func, cfn.param, cfn.adjustMode); - widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM; + fswtchParam[i]->setMinimum(model->gvarData[gvidx].getMinPrec()); + fswtchParam[i]->setMaximum(model->gvarData[gvidx].getMaxPrec()); } + fswtchParam[i]->setValue(cfn.param * model->gvarData[gvidx].multiplierGet()); + widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM; } - else if (func == FuncReset) { + else { + if (modified) + cfn.param = fswtchParamT[i]->currentData().toInt(); + populateFuncParamCB(fswtchParamT[i], func, cfn.param, cfn.adjustMode); + widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM; + } + } + else if (func == FuncReset) { + if (modified) + cfn.param = fswtchParamT[i]->currentData().toInt(); + populateFuncParamCB(fswtchParamT[i], func, cfn.param); + widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM | CUSTOM_FUNCTION_ENABLE; + } + else if (func >= FuncSetTimer1 && func <= FuncSetTimer3) { + if (modified) + cfn.param = fswtchParamTime[i]->timeInSeconds(); + RawSourceRange range = RawSource(SOURCE_TYPE_SPECIAL, func - FuncSetTimer1 + 2).getRange(model, generalSettings); + fswtchParamTime[i]->setTimeRange((int)range.min, (int)range.max); + fswtchParamTime[i]->setTime(cfn.param); + widgetsMask |= CUSTOM_FUNCTION_TIME_PARAM | CUSTOM_FUNCTION_ENABLE; + } + else if (func >= FuncSetFailsafe && func <= FuncBindExternalModule) { + widgetsMask |= CUSTOM_FUNCTION_ENABLE; + } + else if (func == FuncVolume || func == FuncBacklight) { + if (modified) + cfn.param = fswtchParamT[i]->currentData().toInt(); + populateFuncParamCB(fswtchParamT[i], func, cfn.param); + widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM | CUSTOM_FUNCTION_ENABLE; + } + else if (func == FuncPlaySound || func == FuncPlayHaptic || func == FuncPlayValue || func == FuncPlayPrompt || func == FuncPlayBoth || func == FuncBackgroundMusic) { + if (func != FuncBackgroundMusic) { + widgetsMask |= CUSTOM_FUNCTION_REPEAT; + fswtchRepeat[i]->update(); + } + if (func == FuncPlayValue) { if (modified) cfn.param = fswtchParamT[i]->currentData().toInt(); populateFuncParamCB(fswtchParamT[i], func, cfn.param); - widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM | CUSTOM_FUNCTION_ENABLE; + widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM | CUSTOM_FUNCTION_REPEAT; } - else if (func >= FuncSetTimer1 && func <= FuncSetTimer3) { - if (modified) - cfn.param = fswtchParamTime[i]->timeInSeconds(); - RawSourceRange range = RawSource(SOURCE_TYPE_SPECIAL, func - FuncSetTimer1 + 2).getRange(model, generalSettings); - fswtchParamTime[i]->setTimeRange((int)range.min, (int)range.max); - fswtchParamTime[i]->setTime(cfn.param); - widgetsMask |= CUSTOM_FUNCTION_TIME_PARAM | CUSTOM_FUNCTION_ENABLE; - } - else if (func >= FuncSetFailsafeInternalModule && func <= FuncBindExternalModule) { - widgetsMask |= CUSTOM_FUNCTION_ENABLE; - } - else if (func == FuncVolume || func == FuncBacklight) { - if (modified) - cfn.param = fswtchParamT[i]->currentData().toInt(); - populateFuncParamCB(fswtchParamT[i], func, cfn.param); - widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM | CUSTOM_FUNCTION_ENABLE; - } - else if (func == FuncPlaySound || func == FuncPlayHaptic || func == FuncPlayValue || func == FuncPlayPrompt || func == FuncPlayBoth || func == FuncBackgroundMusic) { - if (func != FuncBackgroundMusic) { - widgetsMask |= CUSTOM_FUNCTION_REPEAT; - fswtchRepeat[i]->update(); - } - if (func == FuncPlayValue) { - if (modified) - cfn.param = fswtchParamT[i]->currentData().toInt(); - populateFuncParamCB(fswtchParamT[i], func, cfn.param); - widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM | CUSTOM_FUNCTION_REPEAT; - } - else if (func == FuncPlayPrompt || func == FuncPlayBoth) { - if (firmware->getCapability(VoicesAsNumbers)) { - fswtchParam[i]->setDecimals(0); - fswtchParam[i]->setSingleStep(1); - fswtchParam[i]->setMinimum(0); - if (func == FuncPlayPrompt) { - widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM | CUSTOM_FUNCTION_REPEAT | CUSTOM_FUNCTION_GV_TOOGLE; - } - else { - widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM | CUSTOM_FUNCTION_REPEAT; - fswtchParamGV[i]->setChecked(false); - } - fswtchParam[i]->setMaximum(func == FuncPlayBoth ? 254 : 255); - if (modified) { - if (fswtchParamGV[i]->isChecked()) { - fswtchParam[i]->setMinimum(1); - cfn.param = std::min(fswtchParam[i]->value(),5.0)+(fswtchParamGV[i]->isChecked() ? 250 : 0); - } - else { - cfn.param = fswtchParam[i]->value(); - } - } - if (cfn.param>250 && (func!=FuncPlayBoth)) { - fswtchParamGV[i]->setChecked(true); - fswtchParam[i]->setValue(cfn.param-250); - fswtchParam[i]->setMaximum(5); - } - else { - fswtchParamGV[i]->setChecked(false); - fswtchParam[i]->setValue(cfn.param); - } - if (cfn.param < 251) - widgetsMask |= CUSTOM_FUNCTION_PLAY; + else if (func == FuncPlayPrompt || func == FuncPlayBoth) { + if (firmware->getCapability(VoicesAsNumbers)) { + fswtchParam[i]->setDecimals(0); + fswtchParam[i]->setSingleStep(1); + fswtchParam[i]->setMinimum(0); + if (func == FuncPlayPrompt) { + widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM | CUSTOM_FUNCTION_REPEAT | CUSTOM_FUNCTION_GV_TOOGLE; } else { - widgetsMask |= CUSTOM_FUNCTION_FILE_PARAM; - if (modified) { - Helpers::getFileComboBoxValue(fswtchParamArmT[i], cfn.paramarm, firmware->getCapability(VoicesMaxLength)); + widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM | CUSTOM_FUNCTION_REPEAT; + fswtchParamGV[i]->setChecked(false); + } + fswtchParam[i]->setMaximum(func == FuncPlayBoth ? 254 : 255); + if (modified) { + if (fswtchParamGV[i]->isChecked()) { + fswtchParam[i]->setMinimum(1); + cfn.param = std::min(fswtchParam[i]->value(),5.0)+(fswtchParamGV[i]->isChecked() ? 250 : 0); } - Helpers::populateFileComboBox(fswtchParamArmT[i], tracksSet, cfn.paramarm); - if (fswtchParamArmT[i]->currentText() != "----") { - widgetsMask |= CUSTOM_FUNCTION_PLAY; + else { + cfn.param = fswtchParam[i]->value(); } } + if (cfn.param > 250 && (func != FuncPlayBoth)) { + fswtchParamGV[i]->setChecked(true); + fswtchParam[i]->setValue(cfn.param - 250); + fswtchParam[i]->setMaximum(5); + } + else { + fswtchParamGV[i]->setChecked(false); + fswtchParam[i]->setValue(cfn.param); + } + if (cfn.param < 251) + widgetsMask |= CUSTOM_FUNCTION_PLAY; } - else if (func == FuncBackgroundMusic) { + else { widgetsMask |= CUSTOM_FUNCTION_FILE_PARAM; if (modified) { Helpers::getFileComboBoxValue(fswtchParamArmT[i], cfn.paramarm, firmware->getCapability(VoicesMaxLength)); @@ -534,58 +520,68 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) widgetsMask |= CUSTOM_FUNCTION_PLAY; } } - else if (func == FuncPlaySound) { - if (modified) - cfn.param = (uint8_t)fswtchParamT[i]->currentIndex(); - populateFuncParamCB(fswtchParamT[i], func, cfn.param); - widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM; - } - else if (func == FuncPlayHaptic) { - if (modified) - cfn.param = (uint8_t)fswtchParamT[i]->currentIndex(); - populateFuncParamCB(fswtchParamT[i], func, cfn.param); - widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM; - } } - else if (func == FuncPlayScript) { + else if (func == FuncBackgroundMusic) { widgetsMask |= CUSTOM_FUNCTION_FILE_PARAM; if (modified) { - Helpers::getFileComboBoxValue(fswtchParamArmT[i], cfn.paramarm, 8); + Helpers::getFileComboBoxValue(fswtchParamArmT[i], cfn.paramarm, firmware->getCapability(VoicesMaxLength)); + } + Helpers::populateFileComboBox(fswtchParamArmT[i], tracksSet, cfn.paramarm); + if (fswtchParamArmT[i]->currentText() != "----") { + widgetsMask |= CUSTOM_FUNCTION_PLAY; } - Helpers::populateFileComboBox(fswtchParamArmT[i], scriptsSet, cfn.paramarm); } - else { + else if (func == FuncPlaySound) { if (modified) - cfn.param = fswtchParam[i]->value(); - fswtchParam[i]->setDecimals(0); - fswtchParam[i]->setSingleStep(1); - fswtchParam[i]->setValue(cfn.param); - if (func <= FuncInstantTrim) { - widgetsMask |= CUSTOM_FUNCTION_ENABLE; - } + cfn.param = (uint8_t)fswtchParamT[i]->currentIndex(); + populateFuncParamCB(fswtchParamT[i], func, cfn.param); + widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM; + } + else if (func == FuncPlayHaptic) { + if (modified) + cfn.param = (uint8_t)fswtchParamT[i]->currentIndex(); + populateFuncParamCB(fswtchParamT[i], func, cfn.param); + widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM; } } + else if (func == FuncPlayScript) { + widgetsMask |= CUSTOM_FUNCTION_FILE_PARAM; + if (modified) { + Helpers::getFileComboBoxValue(fswtchParamArmT[i], cfn.paramarm, 8); + } + Helpers::populateFileComboBox(fswtchParamArmT[i], scriptsSet, cfn.paramarm); + } + else { + if (modified) + cfn.param = fswtchParam[i]->value(); + fswtchParam[i]->setDecimals(0); + fswtchParam[i]->setSingleStep(1); + fswtchParam[i]->setValue(cfn.param); + if (func <= FuncInstantTrim) { + widgetsMask |= CUSTOM_FUNCTION_ENABLE; + } + } + } - fswtchFunc[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_SHOW_FUNC); - fswtchParam[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_NUMERIC_PARAM); - fswtchParamTime[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_TIME_PARAM); - fswtchParamGV[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_GV_TOOGLE); - fswtchParamT[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_SOURCE_PARAM); - fswtchParamArmT[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_FILE_PARAM); - fswtchEnable[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_ENABLE); - if (widgetsMask & CUSTOM_FUNCTION_ENABLE) - fswtchEnable[i]->setChecked(cfn.enabled); - else - fswtchEnable[i]->setChecked(false); - fswtchRepeat[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_REPEAT); - fswtchGVmode[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_GV_MODE); - fswtchBLcolor[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_BL_COLOR); - playBT[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_PLAY); + fswtchFunc[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_SHOW_FUNC); + fswtchParam[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_NUMERIC_PARAM); + fswtchParamTime[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_TIME_PARAM); + fswtchParamGV[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_GV_TOOGLE); + fswtchParamT[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_SOURCE_PARAM); + fswtchParamArmT[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_FILE_PARAM); + fswtchEnable[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_ENABLE); + if (widgetsMask & CUSTOM_FUNCTION_ENABLE) + fswtchEnable[i]->setChecked(cfn.enabled); + else + fswtchEnable[i]->setChecked(false); + fswtchRepeat[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_REPEAT); + fswtchGVmode[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_GV_MODE); + fswtchBLcolor[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_BL_COLOR); + playBT[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_PLAY); } void CustomFunctionsPanel::update() { - updateDataModels(); lock = true; for (int i = 0; i < fswCapability; i++) { refreshCustomFunction(i); @@ -660,16 +656,16 @@ void CustomFunctionsPanel::populateFuncCB(QComboBox *b, unsigned int value) { b->clear(); for (unsigned int i = 0; i < FuncCount; i++) { - if (((i>=FuncOverrideCH1 && i<=FuncOverrideCH32) && (!model || !firmware->getCapability(SafetyChannelCustomFunction))) || - ((i==FuncVolume || i==FuncBackgroundMusic || i==FuncBackgroundMusicPause) && !firmware->getCapability(HasVolume)) || - ((i==FuncPlayScript && !IS_HORUS_OR_TARANIS(firmware->getBoard()))) || - ((i==FuncPlayHaptic) && !firmware->getCapability(Haptic)) || - ((i==FuncPlayBoth) && !firmware->getCapability(HasBeeper)) || - ((i==FuncLogs) && !firmware->getCapability(HasSDLogs)) || - ((i==FuncSetTimer3) && firmware->getCapability(Timers) < 3) || - ((i==FuncScreenshot) && !IS_HORUS_OR_TARANIS(firmware->getBoard())) || - ((i>=FuncRangeCheckInternalModule && i<=FuncBindExternalModule) && (!model || !firmware->getCapability(DangerousFunctions))) || - ((i>=FuncAdjustGV1 && i<=FuncAdjustGVLast) && (!model || !firmware->getCapability(Gvars))) + if (((i >= FuncOverrideCH1 && i <= FuncOverrideCH32) && (!model || !firmware->getCapability(SafetyChannelCustomFunction))) || + ((i == FuncVolume || i == FuncBackgroundMusic || i == FuncBackgroundMusicPause) && !firmware->getCapability(HasVolume)) || + ((i == FuncPlayScript && !IS_HORUS_OR_TARANIS(firmware->getBoard()))) || + ((i == FuncPlayHaptic) && !firmware->getCapability(Haptic)) || + ((i == FuncPlayBoth) && !firmware->getCapability(HasBeeper)) || + ((i == FuncLogs) && !firmware->getCapability(HasSDLogs)) || + ((i == FuncSetTimer3) && firmware->getCapability(Timers) < 3) || + ((i == FuncScreenshot) && !IS_HORUS_OR_TARANIS(firmware->getBoard())) || + ((i >= FuncRangeCheckInternalModule && i <= FuncBindExternalModule) && (!model || !firmware->getCapability(DangerousFunctions))) || + ((i >= FuncAdjustGV1 && i <= FuncAdjustGVLast) && (!model || !firmware->getCapability(Gvars))) ) { // skipped continue; @@ -711,21 +707,21 @@ void CustomFunctionsPanel::populateFuncParamCB(QComboBox *b, uint function, unsi CustomFunctionData::populateResetParams(model, b, value); } else if (function == FuncVolume || function == FuncBacklight) { - b->setModel(rawSrcInputsItemModel); + b->setModel(rawSourceInputsModel); b->setCurrentIndex(b->findData(value)); } else if (function == FuncPlayValue) { - b->setModel(rawSrcAllItemModel); + b->setModel(rawSourceAllModel); b->setCurrentIndex(b->findData(value)); } else if (function >= FuncAdjustGV1 && function <= FuncAdjustGVLast) { switch (adjustmode) { case 1: - b->setModel(rawSrcInputsItemModel); + b->setModel(rawSourceInputsModel); b->setCurrentIndex(b->findData(value)); break; case 2: - b->setModel(rawSrcGVarsItemModel); + b->setModel(rawSourceGVarsModel); b->setCurrentIndex(b->findData(value)); break; } @@ -830,3 +826,23 @@ bool CustomFunctionsPanel::moveUpAllowed() const { return selectedIndex > 0; } + +void CustomFunctionsPanel::onModelDataAboutToBeUpdated() +{ + lock = true; + modelsUpdateCnt++; +} + +void CustomFunctionsPanel::onModelDataUpdateComplete() +{ + modelsUpdateCnt--; + if (modelsUpdateCnt < 1) { + lock = true; + for (int i = 0; i < fswCapability; i++) { + fswtchSwtch[i]->setCurrentIndex(fswtchSwtch[i]->findData(functions[i].swtch.toValue())); + fswtchFunc[i]->setCurrentIndex(fswtchFunc[i]->findData(functions[i].func)); + } + update(); + lock = false; + } +} diff --git a/companion/src/modeledit/customfunctions.h b/companion/src/modeledit/customfunctions.h index 54a83ddcf..9b3e3d238 100644 --- a/companion/src/modeledit/customfunctions.h +++ b/companion/src/modeledit/customfunctions.h @@ -26,8 +26,8 @@ #include -class RawSourceFilterItemModel; -class RawSwitchFilterItemModel; +class CommonItemModels; +class RawItemFilteredModel; class TimerEdit; constexpr char MIMETYPE_CUSTOM_FUNCTION[] = "application/x-companion-custom-function"; @@ -55,7 +55,7 @@ class CustomFunctionsPanel : public GenericPanel Q_OBJECT public: - CustomFunctionsPanel(QWidget *parent, ModelData * model, GeneralSettings & generalSettings, Firmware * firmware); + CustomFunctionsPanel(QWidget *parent, ModelData * model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels); ~CustomFunctionsPanel(); virtual void update(); @@ -64,12 +64,11 @@ class CustomFunctionsPanel : public GenericPanel CustomFunctionData * functions; private slots: - void updateDataModels(); void customFunctionEdited(); void functionEdited(); void onCustomContextMenuRequested(QPoint pos); void refreshCustomFunction(int index, bool modified=false); - void onChildModified(); + void onRepeatModified(); bool playSound(int index); void stopSound(int index); void toggleSound(bool play); @@ -84,6 +83,8 @@ class CustomFunctionsPanel : public GenericPanel void cmInsert(); void cmClear(bool prompt = true); void cmClearAll(); + void onModelDataAboutToBeUpdated(); + void onModelDataUpdateComplete(); private: void populateFuncCB(QComboBox *b, unsigned int value); @@ -95,10 +96,11 @@ class CustomFunctionsPanel : public GenericPanel bool moveUpAllowed() const; void swapData(int idx1, int idx2); void resetCBsAndRefresh(int idx); - RawSwitchFilterItemModel * rawSwitchItemModel; - RawSourceFilterItemModel * rawSrcAllItemModel; - RawSourceFilterItemModel * rawSrcInputsItemModel; - RawSourceFilterItemModel * rawSrcGVarsItemModel; + CommonItemModels * commonItemModels; + RawItemFilteredModel * rawSwitchFilteredModel; + RawItemFilteredModel * rawSourceAllModel; + RawItemFilteredModel * rawSourceInputsModel; + RawItemFilteredModel * rawSourceGVarsModel; QSet tracksSet; QSet scriptsSet; @@ -119,7 +121,7 @@ class CustomFunctionsPanel : public GenericPanel int selectedIndex; int fswCapability; - + int modelsUpdateCnt; }; #endif // _CUSTOMFUNCTIONS_H_ diff --git a/companion/src/modeledit/expodialog.cpp b/companion/src/modeledit/expodialog.cpp index 95aaeca66..afebbeb27 100644 --- a/companion/src/modeledit/expodialog.cpp +++ b/companion/src/modeledit/expodialog.cpp @@ -24,7 +24,8 @@ #include "helpers.h" ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, GeneralSettings & generalSettings, - Firmware * firmware, QString & inputName) : + Firmware * firmware, QString & inputName, RawItemFilteredModel * rawSourceModel, + RawItemFilteredModel * rawSwitchModel, RawItemFilteredModel * curveItemModel) : QDialog(parent), ui(new Ui::ExpoDialog), model(model), @@ -36,9 +37,10 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G lock(false) { ui->setupUi(this); - QLabel * lb_fp[CPN_MAX_FLIGHT_MODES] = {ui->lb_FP0,ui->lb_FP1,ui->lb_FP2,ui->lb_FP3,ui->lb_FP4,ui->lb_FP5,ui->lb_FP6,ui->lb_FP7,ui->lb_FP8 }; - QCheckBox * tmp[CPN_MAX_FLIGHT_MODES] = {ui->cb_FP0,ui->cb_FP1,ui->cb_FP2,ui->cb_FP3,ui->cb_FP4,ui->cb_FP5,ui->cb_FP6,ui->cb_FP7,ui->cb_FP8 }; - for (int i=0; ilb_FP0, ui->lb_FP1, ui->lb_FP2, ui->lb_FP3, ui->lb_FP4, ui->lb_FP5, ui->lb_FP6, ui->lb_FP7, ui->lb_FP8 }; + QCheckBox * tmp[CPN_MAX_FLIGHT_MODES] = {ui->cb_FP0, ui->cb_FP1, ui->cb_FP2, ui->cb_FP3, ui->cb_FP4, ui->cb_FP5, ui->cb_FP6, ui->cb_FP7, ui->cb_FP8 }; + for (int i = 0; i < CPN_MAX_FLIGHT_MODES; i++) { cb_fp[i] = tmp[i]; } @@ -48,18 +50,16 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G gvWeightGroup = new GVarGroup(ui->weightGV, ui->weightSB, ui->weightCB, ed->weight, model, 100, -100, 100); gvOffsetGroup = new GVarGroup(ui->offsetGV, ui->offsetSB, ui->offsetCB, ed->offset, model, 0, -100, 100); + curveGroup = new CurveReferenceUIManager(ui->curveTypeCB, ui->curveGVarCB, ui->curveValueSB, ui->curveValueCB, ed->curve, model, curveItemModel, this); - curveGroup = new CurveGroup(ui->curveTypeCB, ui->curveGVarCB, ui->curveValueCB, ui->curveValueSB, ed->curve, model, - firmware->getCapability(HasInputDiff) ? 0 : (HIDE_DIFF | HIDE_NEGATIVE_CURVES)); - - ui->switchesCB->setModel(new RawSwitchFilterItemModel(&generalSettings, &model, RawSwitch::MixesContext, this)); + ui->switchesCB->setModel(rawSwitchModel); ui->switchesCB->setCurrentIndex(ui->switchesCB->findData(ed->swtch.toValue())); - ui->sideCB->setCurrentIndex(ed->mode-1); + ui->sideCB->setCurrentIndex(ed->mode - 1); if (!firmware->getCapability(FlightModes)) { ui->label_phases->hide(); - for (int i=0; ihide(); cb_fp[i]->hide(); } @@ -69,13 +69,13 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G ui->label_phases->setContextMenuPolicy(Qt::CustomContextMenu); connect(ui->label_phases, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(label_phases_customContextMenuRequested(const QPoint &))); int mask = 1; - for (int i=0; iflightModes & mask) == 0) { cb_fp[i]->setChecked(true); } mask <<= 1; } - for (int i=firmware->getCapability(FlightModes); igetCapability(FlightModes); i < CPN_MAX_FLIGHT_MODES; i++) { lb_fp[i]->hide(); cb_fp[i]->hide(); } @@ -83,9 +83,8 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G if (firmware->getCapability(VirtualInputs)) { ui->inputName->setMaxLength(firmware->getCapability(InputsLength)); - ui->sourceCB->setModel(new RawSourceFilterItemModel(&generalSettings, &model, (RawSource::InputSourceGroups & ~RawSource::InputsGroup) | RawSource::TelemGroup, this)); + ui->sourceCB->setModel(rawSourceModel); ui->sourceCB->setCurrentIndex(ui->sourceCB->findData(ed->srcRaw.toValue())); - ui->sourceCB->removeItem(0); ui->inputName->setValidator(new QRegExpValidator(rx, this)); ui->inputName->setText(inputName); } @@ -98,8 +97,8 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G ui->trimCB->hide(); } - for(int i=0; i < getBoardCapability(getCurrentBoard(), Board::NumTrims); i++) { - ui->trimCB->addItem(RawSource(SOURCE_TYPE_TRIM, i).toString(), i+1); + for(int i = 0; i < getBoardCapability(getCurrentBoard(), Board::NumTrims); i++) { + ui->trimCB->addItem(RawSource(SOURCE_TYPE_TRIM, i).toString(), i + 1); } ui->trimCB->setCurrentIndex(1 - ed->carryTrim); @@ -124,7 +123,7 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G connect(ui->trimCB, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesChanged())); connect(ui->switchesCB, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesChanged())); connect(ui->sideCB, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesChanged())); - for (int i=0; igetCapability(VirtualInputs)) { @@ -138,7 +137,6 @@ ExpoDialog::~ExpoDialog() { delete gvWeightGroup; delete gvOffsetGroup; - delete curveGroup; delete ui; } @@ -181,7 +179,7 @@ void ExpoDialog::valuesChanged() } ed->flightModes = 0; - for (int i=CPN_MAX_FLIGHT_MODES-1; i>=0 ; i--) { + for (int i = CPN_MAX_FLIGHT_MODES - 1; i >= 0 ; i--) { if (!cb_fp[i]->checkState()) { ed->flightModes++; } @@ -212,7 +210,7 @@ void ExpoDialog::label_phases_customContextMenuRequested(const QPoint & pos) void ExpoDialog::fmClearAll() { lock = true; - for (int i=0; isetChecked(false); } lock = false; @@ -222,7 +220,7 @@ void ExpoDialog::fmClearAll() void ExpoDialog::fmSetAll() { lock = true; - for (int i=0; isetChecked(true); } lock = false; @@ -232,7 +230,7 @@ void ExpoDialog::fmSetAll() void ExpoDialog::fmInvertAll() { lock = true; - for (int i=0; isetChecked(!cb_fp[i]->isChecked()); } lock = false; diff --git a/companion/src/modeledit/expodialog.h b/companion/src/modeledit/expodialog.h index e1355e147..b77d55852 100644 --- a/companion/src/modeledit/expodialog.h +++ b/companion/src/modeledit/expodialog.h @@ -26,7 +26,8 @@ #include "modelprinter.h" class GVarGroup; -class CurveGroup; +class RawItemFilteredModel; +class CurveReferenceUIManager; namespace Ui { class ExpoDialog; @@ -36,7 +37,8 @@ class ExpoDialog : public QDialog { Q_OBJECT public: ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expodata, GeneralSettings & generalSettings, - Firmware * firmware, QString & inputName); + Firmware * firmware, QString & inputName, RawItemFilteredModel * rawSourceItemModel, + RawItemFilteredModel * rawSwitchItemModel, RawItemFilteredModel * curveItemModel); ~ExpoDialog(); protected: @@ -59,7 +61,7 @@ class ExpoDialog : public QDialog { QString & inputName; GVarGroup * gvWeightGroup; GVarGroup * gvOffsetGroup; - CurveGroup * curveGroup; + CurveReferenceUIManager * curveGroup; ModelPrinter modelPrinter; bool lock; QCheckBox * cb_fp[CPN_MAX_FLIGHT_MODES]; diff --git a/companion/src/modeledit/flightmodes.cpp b/companion/src/modeledit/flightmodes.cpp index 12082091d..32188feea 100644 --- a/companion/src/modeledit/flightmodes.cpp +++ b/companion/src/modeledit/flightmodes.cpp @@ -24,14 +24,15 @@ #include "helpers.h" #include "customdebug.h" -FlightModePanel::FlightModePanel(QWidget * parent, ModelData & model, int phaseIdx, GeneralSettings & generalSettings, Firmware * firmware, RawSwitchFilterItemModel * switchModel): +FlightModePanel::FlightModePanel(QWidget * parent, ModelData & model, int phaseIdx, GeneralSettings & generalSettings, Firmware * firmware, RawItemFilteredModel * rawSwitchFilteredModel): ModelPanel(parent, model, generalSettings, firmware), ui(new Ui::FlightMode), phaseIdx(phaseIdx), - phase(model.flightModeData[phaseIdx]), - rawSwitchItemModel(NULL) + phase(model.flightModeData[phaseIdx]) { ui->setupUi(this); + connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &FlightModePanel::onModelDataAboutToBeUpdated); + connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &FlightModePanel::onModelDataUpdateComplete); ui->labelName->setContextMenuPolicy(Qt::CustomContextMenu); ui->labelName->setToolTip(tr("Popup menu available")); @@ -56,8 +57,8 @@ FlightModePanel::FlightModePanel(QWidget * parent, ModelData & model, int phaseI // Flight mode switch if (phaseIdx > 0) { - ui->swtch->setModel(switchModel); - connect(ui->swtch, SIGNAL(activated(int)), this, SLOT(phaseSwitchChanged(int))); + ui->swtch->setModel(rawSwitchFilteredModel); + connect(ui->swtch, SIGNAL(currentIndexChanged(int)), this, SLOT(phaseSwitch_currentIndexChanged(int))); } else { ui->swtch->hide(); @@ -316,8 +317,6 @@ void FlightModePanel::update() for (int i = 0; i < reCount; i++) { updateRotaryEncoder(i); } - - emit nameModified(); } void FlightModePanel::updateGVar(int index) @@ -390,17 +389,18 @@ void FlightModePanel::phaseName_editingFinished() { QLineEdit *lineEdit = qobject_cast(sender()); strcpy(phase.name, lineEdit->text().toLatin1()); + emit phaseNameChanged(); emit modified(); - emit nameModified(); } -void FlightModePanel::phaseSwitchChanged(int index) +void FlightModePanel::phaseSwitch_currentIndexChanged(int index) { if (!lock) { bool ok; const RawSwitch rs(ui->swtch->itemData(index).toInt(&ok)); if (ok && phase.swtch.toValue() != rs.toValue()) { phase.swtch = rs; + emit phaseSwitchChanged(); emit modified(); } } @@ -457,7 +457,7 @@ void FlightModePanel::phaseGVValue_editingFinished() QDoubleSpinBox *spinBox = qobject_cast(sender()); int gvar = spinBox->property("index").toInt(); phase.gvars[gvar] = spinBox->value() * model->gvarData[gvar].multiplierSet(); - emit datachanged(); + updateGVar(gvar); emit modified(); } } @@ -469,7 +469,7 @@ void FlightModePanel::GVName_editingFinished() int gvar = lineedit->property("index").toInt(); memset(&model->gvarData[gvar].name, 0, sizeof(model->gvarData[gvar].name)); strcpy(model->gvarData[gvar].name, lineedit->text().toLatin1()); - emit datachanged(); + emit gvNameChanged(); emit modified(); } } @@ -488,7 +488,7 @@ void FlightModePanel::phaseGVUse_currentIndexChanged(int index) } if (model->isGVarLinkedCircular(phaseIdx, gvar)) QMessageBox::warning(this, "Companion", tr("Warning: Global variable links back to itself. Flight Mode 0 value used.")); - emit datachanged(); + updateGVar(gvar); emit modified(); lock = false; } @@ -500,7 +500,7 @@ void FlightModePanel::phaseGVUnit_currentIndexChanged(int index) QComboBox *comboBox = qobject_cast(sender()); int gvar = comboBox->property("index").toInt(); model->gvarData[gvar].unit = index; - emit datachanged(); + updateGVar(gvar); emit modified(); } } @@ -511,7 +511,7 @@ void FlightModePanel::phaseGVPrec_currentIndexChanged(int index) QComboBox *comboBox = qobject_cast(sender()); int gvar = comboBox->property("index").toInt(); model->gvarData[gvar].prec = index; - emit datachanged(); + updateGVar(gvar); emit modified(); } } @@ -534,7 +534,7 @@ void FlightModePanel::phaseGVMin_editingFinished() } } } - emit datachanged(); + updateGVar(gvar); emit modified(); } } @@ -557,7 +557,7 @@ void FlightModePanel::phaseGVMax_editingFinished() } } } - emit datachanged(); + updateGVar(gvar); emit modified(); } } @@ -741,7 +741,8 @@ void FlightModePanel::cmClear(bool prompt) model->updateAllReferences(ModelData::REF_UPD_TYPE_FLIGHT_MODE, ModelData::REF_UPD_ACT_CLEAR, phaseIdx); - emit datachanged(); + update(); + emit phaseDataChanged(); emit modified(); } @@ -767,7 +768,7 @@ void FlightModePanel::cmClearAll() model->updateAllReferences(ModelData::REF_UPD_TYPE_GLOBAL_VARIABLE, ModelData::REF_UPD_ACT_CLEAR, i); } - emit datachanged(); + emit phaseDataChanged(); emit modified(); } @@ -846,7 +847,7 @@ void FlightModePanel::cmDelete() model->updateAllReferences(ModelData::REF_UPD_TYPE_FLIGHT_MODE, ModelData::REF_UPD_ACT_SHIFT, phaseIdx, 0, -1); - emit datachanged(); + emit phaseDataChanged(); emit modified(); } @@ -897,7 +898,7 @@ void FlightModePanel::cmInsert() model->updateAllReferences(ModelData::REF_UPD_TYPE_FLIGHT_MODE, ModelData::REF_UPD_ACT_SHIFT, phaseIdx, 0, 1); - emit datachanged(); + emit phaseDataChanged(); emit modified(); } @@ -946,7 +947,7 @@ void FlightModePanel::cmPaste() } } - emit datachanged(); + emit phaseDataChanged(); emit modified(); } } @@ -1035,7 +1036,7 @@ void FlightModePanel::swapData(int idx1, int idx2) } model->updateAllReferences(ModelData::REF_UPD_TYPE_FLIGHT_MODE, ModelData::REF_UPD_ACT_SWAP, idx1, idx2); - emit datachanged(); + emit phaseDataChanged(); emit modified(); } @@ -1162,7 +1163,8 @@ void FlightModePanel::gvCmClear(bool prompt) } phase.gvars[gvIdx] = phase.linkedGVarFlightModeZero(phaseIdx); } - emit datachanged(); + updateGVar(gvIdx); + emit gvNameChanged(); emit modified(); } @@ -1186,7 +1188,10 @@ void FlightModePanel::gvCmClearAll() phase.gvars[i] = phase.linkedGVarFlightModeZero(phaseIdx); } } - emit datachanged(); + for (int i = 0; i < gvCount; i++) { + updateGVar(i); + } + emit gvNameChanged(); emit modified(); } @@ -1261,8 +1266,13 @@ void FlightModePanel::gvCmDelete() for (int j = 0; j < fmCount; j++) { model->flightModeData[j].gvars[maxidx] = model->flightModeData[j].linkedGVarFlightModeZero(j); } + model->updateAllReferences(ModelData::REF_UPD_TYPE_GLOBAL_VARIABLE, ModelData::REF_UPD_ACT_SHIFT, gvIdx, 0, -1); - emit datachanged(); + + for (int i = 0; i < gvCount; i++) { + updateGVar(i); + } + emit gvNameChanged(); emit modified(); } @@ -1279,7 +1289,10 @@ void FlightModePanel::gvCmInsert() model->flightModeData[j].gvars[gvIdx] = model->flightModeData[j].linkedGVarFlightModeZero(j); } model->updateAllReferences(ModelData::REF_UPD_TYPE_GLOBAL_VARIABLE, ModelData::REF_UPD_ACT_SHIFT, gvIdx, 0, 1); - emit datachanged(); + for (int i = 0; i < gvCount; i++) { + updateGVar(i); + } + emit gvNameChanged(); emit modified(); } @@ -1322,7 +1335,8 @@ void FlightModePanel::gvCmPaste() else phase.gvars[gvIdx] = val; } - emit datachanged(); + updateGVar(gvIdx); + emit gvNameChanged(); emit modified(); } @@ -1340,33 +1354,51 @@ void FlightModePanel::gvSwapData(int idx1, int idx2) model->flightModeData[j].gvars[idx1] = valtmp; } model->updateAllReferences(ModelData::REF_UPD_TYPE_GLOBAL_VARIABLE, ModelData::REF_UPD_ACT_SWAP, idx1, idx2); - emit datachanged(); + updateGVar(idx1); + updateGVar(idx2); + emit gvNameChanged(); emit modified(); } } +void FlightModePanel::onModelDataAboutToBeUpdated() +{ + lock = true; +} + +void FlightModePanel::onModelDataUpdateComplete() +{ + update(); + lock = false; +} + /**********************************************************/ -FlightModesPanel::FlightModesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware): +FlightModesPanel::FlightModesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels): ModelPanel(parent, model, generalSettings, firmware), - modesCount(firmware->getCapability(FlightModes)) + commonItemModels(commonItemModels) { - - RawSwitchFilterItemModel * swModel = new RawSwitchFilterItemModel(&generalSettings, &model, RawSwitch::MixesContext, this); - connect(this, &FlightModesPanel::updated, swModel, &RawSwitchFilterItemModel::update); + rawSwitchFilteredModel = new RawItemFilteredModel(commonItemModels->rawSwitchItemModel(), RawSwitch::MixesContext, this); + modesCount = firmware->getCapability(FlightModes); QGridLayout * gridLayout = new QGridLayout(this); tabWidget = new QTabWidget(this); for (int i = 0; i < modesCount; i++) { - FlightModePanel * tab = new FlightModePanel(tabWidget, model, i, generalSettings, firmware, swModel); + FlightModePanel * tab = new FlightModePanel(tabWidget, model, i, generalSettings, firmware, rawSwitchFilteredModel); tab->setProperty("index", i); - connect(tab, &FlightModePanel::datachanged, this, &FlightModesPanel::update); - connect(tab, &FlightModePanel::modified, this, &FlightModesPanel::modified); - connect(tab, &FlightModePanel::nameModified, this, &FlightModesPanel::onPhaseNameChanged); - connect(this, &FlightModesPanel::updated, tab, &FlightModePanel::update); + connect(tab, &FlightModePanel::modified, this, &FlightModesPanel::modified); + connect(tab, &FlightModePanel::phaseDataChanged, this, &FlightModesPanel::onPhaseNameChanged); + connect(tab, &FlightModePanel::phaseNameChanged, this, &FlightModesPanel::onPhaseNameChanged); + connect(tab, &FlightModePanel::phaseSwitchChanged, this, &FlightModesPanel::updateItemModels); + connect(tab, &FlightModePanel::gvNameChanged, this, &FlightModesPanel::updateItemModels); + + connect(this, &FlightModesPanel::updated, tab, &FlightModePanel::update); tabWidget->addTab(tab, getTabName(i)); + panels << tab; } + connect(tabWidget, &QTabWidget::currentChanged, this, &FlightModesPanel::onTabIndexChanged); gridLayout->addWidget(tabWidget, 0, 0, 1, 1); + onTabIndexChanged(0); } FlightModesPanel::~FlightModesPanel() @@ -1391,9 +1423,22 @@ void FlightModesPanel::onPhaseNameChanged() { int index = sender()->property("index").toInt(); tabWidget->setTabText(index, getTabName(index)); + updateItemModels(); } void FlightModesPanel::update() { emit updated(); } + +void FlightModesPanel::updateItemModels() +{ + commonItemModels->update(CommonItemModels::RMO_FLIGHT_MODES); + commonItemModels->update(CommonItemModels::RMO_GLOBAL_VARIABLES); +} + +void FlightModesPanel::onTabIndexChanged(int index) +{ + if (index < panels.size()) + panels.at(index)->update(); +} diff --git a/companion/src/modeledit/flightmodes.h b/companion/src/modeledit/flightmodes.h index 61e25c59a..ca3619c6c 100644 --- a/companion/src/modeledit/flightmodes.h +++ b/companion/src/modeledit/flightmodes.h @@ -24,7 +24,8 @@ #include "modeledit.h" #include "eeprominterface.h" -class RawSwitchFilterItemModel; +class CommonItemModels; +class RawItemFilteredModel; constexpr char MIMETYPE_FLIGHTMODE[] = "application/x-companion-flightmode"; constexpr char MIMETYPE_GVAR_PARAMS[] = "application/x-companion-gvar-params"; @@ -40,18 +41,20 @@ class FlightModePanel : public ModelPanel Q_OBJECT public: - FlightModePanel(QWidget *parent, ModelData &model, int modeIdx, GeneralSettings & generalSettings, Firmware * firmware, RawSwitchFilterItemModel * switchModel); + FlightModePanel(QWidget *parent, ModelData &model, int modeIdx, GeneralSettings & generalSettings, Firmware * firmware, RawItemFilteredModel * rawSwitchFilteredModel); virtual ~FlightModePanel(); virtual void update(); signals: - void nameModified(); - void datachanged(); + void gvNameChanged(); + void phaseDataChanged(); + void phaseNameChanged(); + void phaseSwitchChanged(); private slots: void phaseName_editingFinished(); - void phaseSwitchChanged(int index); + void phaseSwitch_currentIndexChanged(int index); void phaseFadeIn_editingFinished(); void phaseFadeOut_editingFinished(); void phaseTrimUse_currentIndexChanged(int index); @@ -87,6 +90,8 @@ class FlightModePanel : public ModelPanel void gvCmPaste(); void gvCmMoveDown(); void gvCmMoveUp(); + void onModelDataAboutToBeUpdated(); + void onModelDataUpdateComplete(); private: Ui::FlightMode *ui; @@ -111,7 +116,6 @@ class FlightModePanel : public ModelPanel QVector trimsUse; QVector trimsValue; QVector trimsSlider; - RawSwitchFilterItemModel * rawSwitchItemModel; Board::Type board; void trimUpdate(unsigned int trim); @@ -141,7 +145,7 @@ class FlightModesPanel : public ModelPanel Q_OBJECT public: - FlightModesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware); + FlightModesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels); virtual ~FlightModesPanel(); public slots: @@ -152,13 +156,17 @@ class FlightModesPanel : public ModelPanel private slots: void onPhaseNameChanged(); + void onTabIndexChanged(int index); private: QString getTabName(int index); int modesCount; QTabWidget *tabWidget; - + CommonItemModels *commonItemModels; + RawItemFilteredModel *rawSwitchFilteredModel; + QVector panels; + void updateItemModels(); }; #endif // _FLIGHTMODES_H_ diff --git a/companion/src/modeledit/heli.cpp b/companion/src/modeledit/heli.cpp index c0a4e39d8..1b8607799 100644 --- a/companion/src/modeledit/heli.cpp +++ b/companion/src/modeledit/heli.cpp @@ -23,19 +23,26 @@ #include "helpers.h" #include "rawitemfilteredmodel.h" -HeliPanel::HeliPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware): +HeliPanel::HeliPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels): ModelPanel(parent, model, generalSettings, firmware), - ui(new Ui::Heli) + ui(new Ui::Heli), + commonItemModels(commonItemModels) { ui->setupUi(this); - rawSourceItemModel = new RawSourceFilterItemModel(&generalSettings, &model, RawSource::InputSourceGroups, this); + rawSourceFilteredModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), RawSource::InputSourceGroups, this); + connect(rawSourceFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &HeliPanel::onModelDataAboutToBeUpdated); + connect(rawSourceFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &HeliPanel::onModelDataUpdateComplete); connect(ui->swashType, SIGNAL(currentIndexChanged(int)), this, SLOT(edited())); connect(ui->swashRingVal, SIGNAL(editingFinished()), this, SLOT(edited())); + ui->swashCollectiveSource->setModel(rawSourceFilteredModel); connect(ui->swashCollectiveSource, SIGNAL(currentIndexChanged(int)), this, SLOT(edited())); + if (firmware->getCapability(VirtualInputs)) { + ui->swashAileronSource->setModel(rawSourceFilteredModel); connect(ui->swashAileronSource, SIGNAL(currentIndexChanged(int)), this, SLOT(edited())); + ui->swashElevatorSource->setModel(rawSourceFilteredModel); connect(ui->swashElevatorSource, SIGNAL(currentIndexChanged(int)), this, SLOT(edited())); connect(ui->swashAileronWeight, SIGNAL(editingFinished()), this, SLOT(edited())); connect(ui->swashElevatorWeight, SIGNAL(editingFinished()), this, SLOT(edited())); @@ -66,27 +73,15 @@ HeliPanel::~HeliPanel() delete ui; } -void HeliPanel::updateDataModels() -{ - const bool oldLock = lock; - lock = true; - rawSourceItemModel->update(); - lock = oldLock; -} - void HeliPanel::update() { lock = true; - updateDataModels(); ui->swashType->setCurrentIndex(model->swashRingData.type); - ui->swashCollectiveSource->setModel(rawSourceItemModel); ui->swashCollectiveSource->setCurrentIndex(ui->swashCollectiveSource->findData(model->swashRingData.collectiveSource.toValue())); ui->swashRingVal->setValue(model->swashRingData.value); if (firmware->getCapability(VirtualInputs)) { - ui->swashElevatorSource->setModel(rawSourceItemModel); ui->swashElevatorSource->setCurrentIndex(ui->swashElevatorSource->findData(model->swashRingData.elevatorSource.toValue())); - ui->swashAileronSource->setModel(rawSourceItemModel); ui->swashAileronSource->setCurrentIndex(ui->swashAileronSource->findData(model->swashRingData.aileronSource.toValue())); ui->swashElevatorWeight->setValue(model->swashRingData.elevatorWeight); ui->swashAileronWeight->setValue(model->swashRingData.aileronWeight); @@ -122,3 +117,14 @@ void HeliPanel::edited() emit modified(); } } + +void HeliPanel::onModelDataAboutToBeUpdated() +{ + lock = true; +} + +void HeliPanel::onModelDataUpdateComplete() +{ + update(); + lock = false; +} diff --git a/companion/src/modeledit/heli.h b/companion/src/modeledit/heli.h index 5a27c7c26..ee9a3ac36 100644 --- a/companion/src/modeledit/heli.h +++ b/companion/src/modeledit/heli.h @@ -23,7 +23,8 @@ #include "modeledit.h" -class RawSourceFilterItemModel; +class CommonItemModels; +class RawItemFilteredModel; namespace Ui { class Heli; @@ -34,17 +35,19 @@ class HeliPanel : public ModelPanel Q_OBJECT public: - HeliPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware); + HeliPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels); ~HeliPanel(); void update(); private slots: - void updateDataModels(); void edited(); + void onModelDataAboutToBeUpdated(); + void onModelDataUpdateComplete(); private: Ui::Heli *ui; - RawSourceFilterItemModel * rawSourceItemModel; + CommonItemModels * commonItemModels; + RawItemFilteredModel * rawSourceFilteredModel; }; #endif // _HELI_H_ diff --git a/companion/src/modeledit/inputs.cpp b/companion/src/modeledit/inputs.cpp index 2e65c788c..ee2347aee 100644 --- a/companion/src/modeledit/inputs.cpp +++ b/companion/src/modeledit/inputs.cpp @@ -21,12 +21,26 @@ #include "inputs.h" #include "expodialog.h" #include "helpers.h" +#include "rawitemfilteredmodel.h" -InputsPanel::InputsPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware): +InputsPanel::InputsPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels): ModelPanel(parent, model, generalSettings, firmware), expoInserted(false), - modelPrinter(firmware, generalSettings, model) + modelPrinter(firmware, generalSettings, model), + commonItemModels(commonItemModels) { + rawSourceFilteredModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), (RawSource::InputSourceGroups & ~ RawSource::NoneGroup & ~RawSource::InputsGroup), this); + connect(rawSourceFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &InputsPanel::onModelDataAboutToBeUpdated); + connect(rawSourceFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &InputsPanel::onModelDataUpdateComplete); + + rawSwitchFilteredModel = new RawItemFilteredModel(commonItemModels->rawSwitchItemModel(), RawSwitch::MixesContext, this); + connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &InputsPanel::onModelDataAboutToBeUpdated); + connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &InputsPanel::onModelDataUpdateComplete); + + curveFilteredModel = new RawItemFilteredModel(commonItemModels->curveItemModel(), RawItemFilteredModel::AllFilter, this); + connect(curveFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &InputsPanel::onModelDataAboutToBeUpdated); + connect(curveFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &InputsPanel::onModelDataUpdateComplete); + inputsCount = firmware->getCapability(VirtualInputs); if (inputsCount == 0) inputsCount = CPN_MAX_STICKS; @@ -180,13 +194,14 @@ void InputsPanel::gm_openExpo(int index) if (firmware->getCapability(VirtualInputs)) inputName = model->inputNames[ed.chn]; - ExpoDialog *g = new ExpoDialog(this, *model, &ed, generalSettings, firmware, inputName); - if (g->exec()) { + ExpoDialog *dlg = new ExpoDialog(this, *model, &ed, generalSettings, firmware, inputName, rawSourceFilteredModel, rawSwitchFilteredModel, curveFilteredModel); + if (dlg->exec()) { model->expoData[index] = ed; if (firmware->getCapability(VirtualInputs)) strncpy(model->inputNames[ed.chn], inputName.toLatin1().data(), INPUT_NAME_LEN); - emit modified(); update(); + updateItemModels(); + emit modified(); } else { if (expoInserted) { @@ -195,6 +210,7 @@ void InputsPanel::gm_openExpo(int index) expoInserted=false; update(); } + delete dlg; } int InputsPanel::getExpoIndex(unsigned int dch) @@ -239,8 +255,9 @@ void InputsPanel::exposDelete(bool prompt) } exposDeleteList(list, prompt); - emit modified(); update(); + updateItemModels(); + emit modified(); } void InputsPanel::exposCut() @@ -313,8 +330,9 @@ void InputsPanel::pasteExpoMimeData(const QMimeData * mimeData, int destIdx) i += sizeof(ExpoData); } - emit modified(); update(); + updateItemModels(); + emit modified(); } } @@ -481,8 +499,9 @@ void InputsPanel::moveExpoList(bool down) } } if (mod) { - emit modified(); update(); + updateItemModels(); + emit modified(); } setSelectedByExpoList(highlightList); } @@ -520,8 +539,9 @@ void InputsPanel::clearExpos() for (int i = 0; i < inputsCount; i++) { model->updateAllReferences(ModelData::REF_UPD_TYPE_INPUT, ModelData::REF_UPD_ACT_CLEAR, i); } - emit modified(); update(); + updateItemModels(); + emit modified(); } } @@ -569,6 +589,7 @@ void InputsPanel::cmInputClear() } model->updateAllReferences(ModelData::REF_UPD_TYPE_INPUT, ModelData::REF_UPD_ACT_CLEAR, inputIdx); update(); + updateItemModels(); emit modified(); } @@ -592,6 +613,7 @@ void InputsPanel::cmInputDelete() model->updateAllReferences(ModelData::REF_UPD_TYPE_INPUT, ModelData::REF_UPD_ACT_SHIFT, inputIdx, 0, -1); update(); + updateItemModels(); emit modified(); } @@ -610,6 +632,7 @@ void InputsPanel::cmInputInsert() model->updateAllReferences(ModelData::REF_UPD_TYPE_INPUT, ModelData::REF_UPD_ACT_SHIFT, inputIdx, 0, 1); update(); + updateItemModels(); emit modified(); } @@ -671,6 +694,7 @@ void InputsPanel::cmInputSwapData(int idx1, int idx2) model->updateAllReferences(ModelData::REF_UPD_TYPE_INPUT, ModelData::REF_UPD_ACT_SWAP, idx1, idx2); update(); + updateItemModels(); emit modified(); } @@ -705,3 +729,19 @@ int InputsPanel::getInputIndexFromSelected() } return idx; } + +void InputsPanel::onModelDataAboutToBeUpdated() +{ + lock = true; +} + +void InputsPanel::onModelDataUpdateComplete() +{ + update(); + lock = false; +} + +void InputsPanel::updateItemModels() +{ + commonItemModels->update(CommonItemModels::RMO_INPUTS); +} diff --git a/companion/src/modeledit/inputs.h b/companion/src/modeledit/inputs.h index 9922f2873..ea1243213 100644 --- a/companion/src/modeledit/inputs.h +++ b/companion/src/modeledit/inputs.h @@ -25,6 +25,9 @@ #include "mixerslistwidget.h" #include "modelprinter.h" +class CommonItemModels; +class RawItemFilteredModel; + constexpr char MIMETYPE_EXPO[] = "application/x-companion-expo"; class InputsPanel : public ModelPanel @@ -32,7 +35,7 @@ class InputsPanel : public ModelPanel Q_OBJECT public: - InputsPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware); + InputsPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels); virtual ~InputsPanel(); virtual void update(); @@ -59,6 +62,8 @@ class InputsPanel : public ModelPanel void cmInputInsert(); void cmInputMoveDown(); void cmInputMoveUp(); + void onModelDataAboutToBeUpdated(); + void onModelDataUpdateComplete(); private: bool expoInserted; @@ -67,6 +72,10 @@ class InputsPanel : public ModelPanel ModelPrinter modelPrinter; int selectedIdx; int inputIdx; + CommonItemModels * commonItemModels; + RawItemFilteredModel *rawSourceFilteredModel; + RawItemFilteredModel *rawSwitchFilteredModel; + RawItemFilteredModel *curveFilteredModel; int getExpoIndex(unsigned int dch); bool gm_insertExpo(int idx); @@ -87,6 +96,7 @@ class InputsPanel : public ModelPanel bool isExpoIndex(const int index); int getIndexFromSelected(); int getInputIndexFromSelected(); + void updateItemModels(); }; #endif // _INPUTS_H_ diff --git a/companion/src/modeledit/logicalswitches.cpp b/companion/src/modeledit/logicalswitches.cpp index e70d63568..cacd5c6fd 100644 --- a/companion/src/modeledit/logicalswitches.cpp +++ b/companion/src/modeledit/logicalswitches.cpp @@ -24,16 +24,20 @@ #include -LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware): +LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels): ModelPanel(parent, model, generalSettings, firmware), - selectedIndex(0) + commonItemModels(commonItemModels), + selectedIndex(0), + modelsUpdateCnt(0) { - Stopwatch s1("LogicalSwitchesPanel"); - - rawSwitchItemModel = new RawSwitchFilterItemModel(&generalSettings, &model, RawSwitch::LogicalSwitchesContext, this); + rawSwitchFilteredModel = new RawItemFilteredModel(commonItemModels->rawSwitchItemModel(), RawSwitch::LogicalSwitchesContext, this); + connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &LogicalSwitchesPanel::onModelDataAboutToBeUpdated); + connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &LogicalSwitchesPanel::onModelDataUpdateComplete); const int srcGroups = firmware->getCapability(GvarsInCS) ? 0 : (RawSource::AllSourceGroups & ~RawSource::GVarsGroup); - rawSourceItemModel = new RawSourceFilterItemModel(&generalSettings, &model, srcGroups, this); + rawSourceFilteredModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), srcGroups, this); + connect(rawSourceFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &LogicalSwitchesPanel::onModelDataAboutToBeUpdated); + connect(rawSourceFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &LogicalSwitchesPanel::onModelDataUpdateComplete); lsCapability = firmware->getCapability(LogicalSwitches); lsCapabilityExt = firmware->getCapability(LogicalSwitchesExt); @@ -45,16 +49,13 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, } TableLayout * tableLayout = new TableLayout(this, lsCapability, headerLabels); - s1.report("header"); - const int channelsMax = model.getChannelsMax(true); - lock = true; - for (int i=0; isetProperty("index", i); - label->setText(RawSwitch(SWITCH_TYPE_VIRTUAL, i+1).toString()); + label->setText(RawSwitch(SWITCH_TYPE_VIRTUAL, i + 1).toString()); label->setContextMenuPolicy(Qt::CustomContextMenu); label->setToolTip(tr("Popup menu available")); label->setMouseTracking(true); @@ -123,7 +124,8 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, // AND cbAndSwitch[i] = new QComboBox(this); cbAndSwitch[i]->setProperty("index", i); - populateAndSwitchCB(cbAndSwitch[i]); + cbAndSwitch[i]->setModel(rawSwitchFilteredModel); + cbAndSwitch[i]->setVisible(true); connect(cbAndSwitch[i], SIGNAL(currentIndexChanged(int)), this, SLOT(onAndSwitchChanged(int))); tableLayout->addWidget(i, 4, cbAndSwitch[i]); @@ -152,72 +154,63 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, } } - s1.report("added elements"); - disableMouseScrolling(); - lock = false; - update(); tableLayout->resizeColumnsToContents(); tableLayout->pushRowsUp(lsCapability+1); - s1.report("end"); } LogicalSwitchesPanel::~LogicalSwitchesPanel() { } -void LogicalSwitchesPanel::updateDataModels() -{ - const bool oldLock = lock; - lock = true; - rawSwitchItemModel->update(); - rawSourceItemModel->update(); - lock = oldLock; -} - void LogicalSwitchesPanel::onFunctionChanged() { - int i = sender()->property("index").toInt(); - unsigned newFunc = cbFunction[i]->currentData().toUInt(); + if (!lock) { + int i = sender()->property("index").toInt(); + unsigned newFunc = cbFunction[i]->currentData().toUInt(); - if (model->logicalSw[i].func == newFunc) - return; + if (model->logicalSw[i].func == newFunc) + return; - const unsigned oldFunc = model->logicalSw[i].func; - CSFunctionFamily oldFuncFamily = model->logicalSw[i].getFunctionFamily(); - model->logicalSw[i].func = newFunc; - CSFunctionFamily newFuncFamily = model->logicalSw[i].getFunctionFamily(); - - if (oldFuncFamily != newFuncFamily) { - model->logicalSw[i].clear(); + unsigned oldFunc = model->logicalSw[i].func; + CSFunctionFamily oldFuncFamily = model->logicalSw[i].getFunctionFamily(); model->logicalSw[i].func = newFunc; - if (newFuncFamily == LS_FAMILY_TIMER) { - model->logicalSw[i].val1 = -119; - model->logicalSw[i].val2 = -119; + CSFunctionFamily newFuncFamily = model->logicalSw[i].getFunctionFamily(); + + if (oldFuncFamily != newFuncFamily || newFunc == LS_FN_OFF) { + model->logicalSw[i].clear(); + model->logicalSw[i].func = newFunc; + if (newFuncFamily == LS_FAMILY_TIMER) { + model->logicalSw[i].val1 = -119; + model->logicalSw[i].val2 = -119; + } + else if (newFuncFamily == LS_FAMILY_EDGE) { + model->logicalSw[i].val2 = -129; + } } - else if (newFuncFamily == LS_FAMILY_EDGE) { - model->logicalSw[i].val2 = -129; - } - } - if (bool(oldFunc) != bool(newFunc)) - update(); - else + updateLine(i); - emit modified(); + if (oldFunc == LS_FN_OFF || newFunc == LS_FN_OFF) + updateItemModels(); + + emit modified(); + } } void LogicalSwitchesPanel::onV1Changed(int value) { if (!lock) { int i = sender()->property("index").toInt(); - model->logicalSw[i].val1 = cbSource1[i]->itemData(value).toInt(); - if (model->logicalSw[i].getFunctionFamily() == LS_FAMILY_VOFS) { - if (!offsetChangedAt(i)) - updateLine(i); - } - else { - emit modified(); + if (model->logicalSw[i].val1 != cbSource1[i]->itemData(value).toInt()) { + model->logicalSw[i].val1 = cbSource1[i]->itemData(value).toInt(); + if (model->logicalSw[i].getFunctionFamily() == LS_FAMILY_VOFS) { + if (!offsetChangedAt(i)) + updateLine(i); + } + else { + emit modified(); + } } } } @@ -226,8 +219,10 @@ void LogicalSwitchesPanel::onV2Changed(int value) { if (!lock) { int i = sender()->property("index").toInt(); - model->logicalSw[i].val2 = cbSource2[i]->itemData(value).toInt(); - emit modified(); + if (model->logicalSw[i].val2 != cbSource2[i]->itemData(value).toInt()) { + model->logicalSw[i].val2 = cbSource2[i]->itemData(value).toInt(); + emit modified(); + } } } @@ -235,8 +230,10 @@ void LogicalSwitchesPanel::onAndSwitchChanged(int value) { if (!lock) { int index = sender()->property("index").toInt(); - model->logicalSw[index].andsw = cbAndSwitch[index]->itemData(value).toInt(); - emit modified(); + if (model->logicalSw[index].andsw != cbAndSwitch[index]->itemData(value).toInt()) { + model->logicalSw[index].andsw = cbAndSwitch[index]->itemData(value).toInt(); + emit modified(); + } } } @@ -244,7 +241,7 @@ void LogicalSwitchesPanel::onDurationChanged(double duration) { if (!lock) { int index = sender()->property("index").toInt(); - model->logicalSw[index].duration = (uint8_t)round(duration*10); + model->logicalSw[index].duration = (uint8_t)round(duration * 10); emit modified(); } } @@ -253,7 +250,7 @@ void LogicalSwitchesPanel::onDelayChanged(double delay) { if (!lock) { int index = sender()->property("index").toInt(); - model->logicalSw[index].delay = (uint8_t)round(delay*10); + model->logicalSw[index].delay = (uint8_t)round(delay * 10); emit modified(); } } @@ -326,9 +323,9 @@ void LogicalSwitchesPanel::updateTimerParam(QDoubleSpinBox *sb, int timer, doubl sb->setMinimum(minimum); sb->setMaximum(175); float value = ValToTim(timer); - if (value>=60) + if (value >= 60) sb->setSingleStep(1); - else if (value>=2) + else if (value >= 2) sb->setSingleStep(0.5); else sb->setSingleStep(0.1); @@ -347,16 +344,14 @@ void LogicalSwitchesPanel::updateTimerParam(QDoubleSpinBox *sb, int timer, doubl void LogicalSwitchesPanel::updateLine(int i) { + const bool savelock = lock; lock = true; - unsigned int mask; + unsigned int mask = 0; cbFunction[i]->setCurrentIndex(cbFunction[i]->findData(model->logicalSw[i].func)); cbAndSwitch[i]->setCurrentIndex(cbAndSwitch[i]->findData(RawSwitch(model->logicalSw[i].andsw).toValue())); - if (!model->logicalSw[i].func) { - mask = 0; - } - else { + if (!model->logicalSw[i].isEmpty()) { mask = LINE_ENABLED | DELAY_ENABLED | DURATION_ENABLED; switch (model->logicalSw[i].getFunctionFamily()) @@ -367,7 +362,7 @@ void LogicalSwitchesPanel::updateLine(int i) RawSource source = RawSource(model->logicalSw[i].val1); RawSourceRange range = source.getRange(model, generalSettings, model->logicalSw[i].getRangeFlags()); double value = range.step * model->logicalSw[i].val2 + range.offset; /* TODO+source.getRawOffset(model)*/ - cbSource1[i]->setModel(rawSourceItemModel); + cbSource1[i]->setModel(rawSourceFilteredModel); cbSource1[i]->setCurrentIndex(cbSource1[i]->findData(source.toValue())); if (source.isTimeBased()) { mask |= VALUE_TO_VISIBLE; @@ -396,27 +391,27 @@ void LogicalSwitchesPanel::updateLine(int i) case LS_FAMILY_STICKY: // no break case LS_FAMILY_VBOOL: mask |= SOURCE1_VISIBLE | SOURCE2_VISIBLE; - cbSource1[i]->setModel(rawSwitchItemModel); + cbSource1[i]->setModel(rawSwitchFilteredModel); cbSource1[i]->setCurrentIndex(cbSource1[i]->findData(model->logicalSw[i].val1)); - cbSource2[i]->setModel(rawSwitchItemModel); + cbSource2[i]->setModel(rawSwitchFilteredModel); cbSource2[i]->setCurrentIndex(cbSource2[i]->findData(model->logicalSw[i].val2)); break; case LS_FAMILY_EDGE: mask |= SOURCE1_VISIBLE | VALUE2_VISIBLE | VALUE3_VISIBLE; mask &= ~DELAY_ENABLED; - cbSource1[i]->setModel(rawSwitchItemModel); + cbSource1[i]->setModel(rawSwitchFilteredModel); cbSource1[i]->setCurrentIndex(cbSource1[i]->findData(model->logicalSw[i].val1)); updateTimerParam(dsbOffset[i], model->logicalSw[i].val2, 0.0); - updateTimerParam(dsbOffset2[i], model->logicalSw[i].val2+model->logicalSw[i].val3, ValToTim(TimToVal(dsbOffset[i]->value())-1)); + updateTimerParam(dsbOffset2[i], model->logicalSw[i].val2 + model->logicalSw[i].val3, ValToTim(TimToVal(dsbOffset[i]->value()) - 1)); dsbOffset2[i]->setSuffix((model->logicalSw[i].val3) ? "" : tr(" (infinite)")); break; case LS_FAMILY_VCOMP: mask |= SOURCE1_VISIBLE | SOURCE2_VISIBLE; - cbSource1[i]->setModel(rawSourceItemModel); + cbSource1[i]->setModel(rawSourceFilteredModel); cbSource1[i]->setCurrentIndex(cbSource1[i]->findData(model->logicalSw[i].val1)); - cbSource2[i]->setModel(rawSourceItemModel); + cbSource2[i]->setModel(rawSourceFilteredModel); cbSource2[i]->setCurrentIndex(cbSource2[i]->findData(model->logicalSw[i].val2)); break; @@ -439,12 +434,12 @@ void LogicalSwitchesPanel::updateLine(int i) dsbDuration[i]->setVisible(mask & DURATION_ENABLED); dsbDelay[i]->setVisible(mask & DELAY_ENABLED); if (mask & DURATION_ENABLED) - dsbDuration[i]->setValue(model->logicalSw[i].duration/10.0); + dsbDuration[i]->setValue(model->logicalSw[i].duration / 10.0); if (mask & DELAY_ENABLED) - dsbDelay[i]->setValue(model->logicalSw[i].delay/10.0); + dsbDelay[i]->setValue(model->logicalSw[i].delay / 10.0); } - lock = false; + lock = savelock; } void LogicalSwitchesPanel::populateFunctionCB(QComboBox *b) @@ -475,7 +470,7 @@ void LogicalSwitchesPanel::populateFunctionCB(QComboBox *b) }; b->clear(); - for (int i=0; isetMaxVisibleItems(10); } -void LogicalSwitchesPanel::populateAndSwitchCB(QComboBox *b) -{ - b->setModel(rawSwitchItemModel); - b->setVisible(true); -} - void LogicalSwitchesPanel::update() { - updateDataModels(); - for (int i=0; ilogicalSw[selectedIndex], data.constData(), sizeof(LogicalSwitchData)); - updateDataModels(); updateLine(selectedIndex); + updateItemModels(); emit modified(); } } @@ -519,6 +507,7 @@ void LogicalSwitchesPanel::cmDelete() model->updateAllReferences(ModelData::REF_UPD_TYPE_LOGICAL_SWITCH, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, -1); update(); + updateItemModels(); emit modified(); } @@ -528,7 +517,7 @@ void LogicalSwitchesPanel::cmCopy() data.append((char*)&model->logicalSw[selectedIndex], sizeof(LogicalSwitchData)); QMimeData *mimeData = new QMimeData; mimeData->setData(MIMETYPE_LOGICAL_SWITCH, data); - QApplication::clipboard()->setMimeData(mimeData,QClipboard::Clipboard); + QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard); } void LogicalSwitchesPanel::cmCut() @@ -539,7 +528,6 @@ void LogicalSwitchesPanel::cmCut() cmClear(false); } -// TODO make something generic here! void LogicalSwitchesPanel::onCustomContextMenuRequested(QPoint pos) { QLabel *label = (QLabel *)sender(); @@ -608,7 +596,8 @@ void LogicalSwitchesPanel::cmClear(bool prompt) model->logicalSw[selectedIndex].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_LOGICAL_SWITCH, ModelData::REF_UPD_ACT_CLEAR, selectedIndex); - update(); + updateLine(selectedIndex); + updateItemModels(); emit modified(); } @@ -617,11 +606,12 @@ void LogicalSwitchesPanel::cmClearAll() if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear all Logical Switches. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) return; - for (int i=0; ilogicalSw[i].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_LOGICAL_SWITCH, ModelData::REF_UPD_ACT_CLEAR, i); } update(); + updateItemModels(); emit modified(); } @@ -631,6 +621,7 @@ void LogicalSwitchesPanel::cmInsert() model->logicalSw[selectedIndex].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_LOGICAL_SWITCH, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, 1); update(); + updateItemModels(); emit modified(); } @@ -643,7 +634,30 @@ void LogicalSwitchesPanel::swapData(int idx1, int idx2) memcpy(lsw2, lsw1, sizeof(LogicalSwitchData)); memcpy(lsw1, &lstmp, sizeof(LogicalSwitchData)); model->updateAllReferences(ModelData::REF_UPD_TYPE_LOGICAL_SWITCH, ModelData::REF_UPD_ACT_SWAP, idx1, idx2); - update(); + updateLine(idx1); + updateLine(idx2); + updateItemModels(); emit modified(); } } + +void LogicalSwitchesPanel::updateItemModels() +{ + lock = true; + commonItemModels->update(CommonItemModels::RMO_LOGICAL_SWITCHES); +} + +void LogicalSwitchesPanel::onModelDataAboutToBeUpdated() +{ + lock = true; + modelsUpdateCnt++; +} + +void LogicalSwitchesPanel::onModelDataUpdateComplete() +{ + modelsUpdateCnt--; + if (modelsUpdateCnt < 1) { + update(); + lock = false; + } +} diff --git a/companion/src/modeledit/logicalswitches.h b/companion/src/modeledit/logicalswitches.h index 62aa69f30..87a360408 100644 --- a/companion/src/modeledit/logicalswitches.h +++ b/companion/src/modeledit/logicalswitches.h @@ -24,8 +24,8 @@ #include "modeledit.h" #include "radiodata.h" -class RawSwitchFilterItemModel; -class RawSourceFilterItemModel; +class CommonItemModels; +class RawItemFilteredModel; class TimerEdit; constexpr char MIMETYPE_LOGICAL_SWITCH[] = "application/x-companion-logical-switch"; @@ -35,13 +35,12 @@ class LogicalSwitchesPanel : public ModelPanel Q_OBJECT public: - LogicalSwitchesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware); + LogicalSwitchesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels); virtual ~LogicalSwitchesPanel(); virtual void update(); private slots: - void updateDataModels(); void onFunctionChanged(); void onV1Changed(int value); void onV2Changed(int value); @@ -61,6 +60,8 @@ class LogicalSwitchesPanel : public ModelPanel void cmInsert(); void cmClear(bool prompt = true); void cmClearAll(); + void onModelDataAboutToBeUpdated(); + void onModelDataUpdateComplete(); private: QComboBox * cbFunction[CPN_MAX_LOGICAL_SWITCHES]; @@ -73,11 +74,11 @@ class LogicalSwitchesPanel : public ModelPanel QDoubleSpinBox * dsbDelay[CPN_MAX_LOGICAL_SWITCHES]; QComboBox * cbSource1[CPN_MAX_LOGICAL_SWITCHES]; QComboBox * cbSource2[CPN_MAX_LOGICAL_SWITCHES]; - RawSwitchFilterItemModel * rawSwitchItemModel; - RawSourceFilterItemModel * rawSourceItemModel; + CommonItemModels * commonItemModels; + RawItemFilteredModel * rawSwitchFilteredModel; + RawItemFilteredModel * rawSourceFilteredModel; int selectedIndex; void populateFunctionCB(QComboBox *b); - void populateAndSwitchCB(QComboBox *b); void updateTimerParam(QDoubleSpinBox *sb, int timer, double minimum=0); int lsCapability; int lsCapabilityExt; @@ -86,6 +87,8 @@ class LogicalSwitchesPanel : public ModelPanel bool insertAllowed() const; bool moveDownAllowed() const; bool moveUpAllowed() const; + int modelsUpdateCnt; + void updateItemModels(); }; #endif // _LOGICALSWITCHES_H_ diff --git a/companion/src/modeledit/mixerdialog.cpp b/companion/src/modeledit/mixerdialog.cpp index 1b17e9471..00d2badc8 100644 --- a/companion/src/modeledit/mixerdialog.cpp +++ b/companion/src/modeledit/mixerdialog.cpp @@ -24,7 +24,8 @@ #include "rawitemfilteredmodel.h" #include "helpers.h" -MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata, GeneralSettings & generalSettings, Firmware * firmware) : +MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata, GeneralSettings & generalSettings, Firmware * firmware, + RawItemFilteredModel * rawSourceModel, RawItemFilteredModel * rawSwitchModel, RawItemFilteredModel * curveItemModel) : QDialog(parent), ui(new Ui::MixerDialog), model(model), @@ -34,25 +35,24 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata, lock(false) { ui->setupUi(this); + QRegExp rx(CHAR_FOR_NAMES_REGEX); - QLabel * lb_fp[CPN_MAX_FLIGHT_MODES] = {ui->lb_FP0,ui->lb_FP1,ui->lb_FP2,ui->lb_FP3,ui->lb_FP4,ui->lb_FP5,ui->lb_FP6,ui->lb_FP7,ui->lb_FP8 }; - QCheckBox * tmp[CPN_MAX_FLIGHT_MODES] = {ui->cb_FP0,ui->cb_FP1,ui->cb_FP2,ui->cb_FP3,ui->cb_FP4,ui->cb_FP5,ui->cb_FP6,ui->cb_FP7,ui->cb_FP8 }; - for (int i=0; ilb_FP0, ui->lb_FP1, ui->lb_FP2, ui->lb_FP3, ui->lb_FP4, ui->lb_FP5, ui->lb_FP6, ui->lb_FP7, ui->lb_FP8 }; + QCheckBox * tmp[CPN_MAX_FLIGHT_MODES] = {ui->cb_FP0, ui->cb_FP1, ui->cb_FP2, ui->cb_FP3, ui->cb_FP4, ui->cb_FP5, ui->cb_FP6, ui->cb_FP7, ui->cb_FP8 }; + for (int i = 0; i < CPN_MAX_FLIGHT_MODES; i++) { cb_fp[i] = tmp[i]; } - this->setWindowTitle(tr("DEST -> %1").arg(RawSource(SOURCE_TYPE_CH, md->destCh-1).toString(&model, &generalSettings))); + this->setWindowTitle(tr("DEST -> %1").arg(RawSource(SOURCE_TYPE_CH, md->destCh - 1).toString(&model, &generalSettings))); - ui->sourceCB->setModel(new RawSourceFilterItemModel(&generalSettings, &model, RawSource::InputSourceGroups | RawSource::ScriptsGroup, this)); + ui->sourceCB->setModel(rawSourceModel); ui->sourceCB->setCurrentIndex(ui->sourceCB->findData(md->srcRaw.toValue())); - ui->sourceCB->removeItem(0); int limit = firmware->getCapability(OffsetWeight); gvWeightGroup = new GVarGroup(ui->weightGV, ui->weightSB, ui->weightCB, md->weight, model, 100, -limit, limit); gvOffsetGroup = new GVarGroup(ui->offsetGV, ui->offsetSB, ui->offsetCB, md->sOffset, model, 0, -limit, limit); - curveGroup = new CurveGroup(ui->curveTypeCB, ui->curveGVarCB, ui->curveValueCB, ui->curveValueSB, - md->curve, model, firmware->getCapability(HasMixerExpo) ? 0 : HIDE_EXPO); + curveGroup = new CurveReferenceUIManager(ui->curveTypeCB, ui->curveGVarCB, ui->curveValueSB, ui->curveValueCB, md->curve, model, curveItemModel, this); ui->MixDR_CB->setChecked(md->noExpo == 0); @@ -62,7 +62,7 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata, } if (!firmware->getCapability(VirtualInputs)) { - for(int i=0; i < CPN_MAX_STICKS; i++) { + for(int i = 0; i < CPN_MAX_STICKS; i++) { ui->trimCB->addItem(firmware->getAnalogInputName(i)); } } @@ -82,7 +82,7 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata, if (!firmware->getCapability(FlightModes)) { ui->label_phases->hide(); - for (int i=0; ihide(); cb_fp[i]->hide(); } @@ -92,40 +92,40 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata, ui->label_phases->setContextMenuPolicy(Qt::CustomContextMenu); connect(ui->label_phases, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(label_phases_customContextMenuRequested(const QPoint &))); int mask = 1; - for (int i=0; iflightModes & mask) == 0) { cb_fp[i]->setChecked(true); } mask <<= 1; } - for (int i=firmware->getCapability(FlightModes); igetCapability(FlightModes); i < CPN_MAX_FLIGHT_MODES; i++) { lb_fp[i]->hide(); cb_fp[i]->hide(); } } - ui->switchesCB->setModel(new RawSwitchFilterItemModel(&generalSettings, &model, RawSwitch::MixesContext, this)); + ui->switchesCB->setModel(rawSwitchModel); ui->switchesCB->setCurrentIndex(ui->switchesCB->findData(md->swtch.toValue())); ui->warningCB->setCurrentIndex(md->mixWarn); ui->mltpxCB->setCurrentIndex(md->mltpx); int scale=firmware->getCapability(SlowScale); float range=firmware->getCapability(SlowRange); - ui->slowDownSB->setMaximum(range/scale); - ui->slowDownSB->setSingleStep(1.0/scale); - ui->slowDownSB->setDecimals((scale==1 ? 0 :1)); + ui->slowDownSB->setMaximum(range / scale); + ui->slowDownSB->setSingleStep(1.0 / scale); + ui->slowDownSB->setDecimals((scale == 1 ? 0 : 1)); ui->slowDownSB->setValue((float)md->speedDown/scale); - ui->slowUpSB->setMaximum(range/scale); - ui->slowUpSB->setSingleStep(1.0/scale); - ui->slowUpSB->setDecimals((scale==1 ? 0 :1)); + ui->slowUpSB->setMaximum(range / scale); + ui->slowUpSB->setSingleStep(1.0 / scale); + ui->slowUpSB->setDecimals((scale == 1 ? 0 : 1)); ui->slowUpSB->setValue((float)md->speedUp/scale); - ui->delayDownSB->setMaximum(range/scale); - ui->delayDownSB->setSingleStep(1.0/scale); - ui->delayDownSB->setDecimals((scale==1 ? 0 :1)); - ui->delayDownSB->setValue((float)md->delayDown/scale); - ui->delayUpSB->setMaximum(range/scale); - ui->delayUpSB->setSingleStep(1.0/scale); - ui->delayUpSB->setDecimals((scale==1 ? 0 :1)); - ui->delayUpSB->setValue((float)md->delayUp/scale); + ui->delayDownSB->setMaximum(range / scale); + ui->delayDownSB->setSingleStep(1.0 / scale); + ui->delayDownSB->setDecimals((scale == 1 ? 0 : 1)); + ui->delayDownSB->setValue((float)md->delayDown / scale); + ui->delayUpSB->setMaximum(range / scale); + ui->delayUpSB->setSingleStep(1.0 / scale); + ui->delayUpSB->setDecimals((scale == 1 ? 0 : 1)); + ui->delayUpSB->setValue((float)md->delayUp / scale); QTimer::singleShot(0, this, SLOT(shrink())); valuesChanged(); @@ -147,10 +147,9 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata, MixerDialog::~MixerDialog() { + delete ui; delete gvWeightGroup; delete gvOffsetGroup; - delete curveGroup; - delete ui; } void MixerDialog::changeEvent(QEvent *e) @@ -176,20 +175,20 @@ void MixerDialog::valuesChanged() ui->MixDR_CB->setEnabled(drVisible); ui->label_MixDR->setEnabled(drVisible); } - md->carryTrim = -(ui->trimCB->currentIndex()-1); + md->carryTrim = -(ui->trimCB->currentIndex() - 1); md->noExpo = ui->MixDR_CB->checkState() ? 0 : 1; md->swtch = RawSwitch(ui->switchesCB->itemData(ui->switchesCB->currentIndex()).toInt()); md->mixWarn = ui->warningCB->currentIndex(); md->mltpx = (MltpxValue)ui->mltpxCB->currentIndex(); int scale = firmware->getCapability(SlowScale); - md->delayDown = round(ui->delayDownSB->value()*scale); - md->delayUp = round(ui->delayUpSB->value()*scale); - md->speedDown = round(ui->slowDownSB->value()*scale); - md->speedUp = round(ui->slowUpSB->value()*scale); + md->delayDown = round(ui->delayDownSB->value() * scale); + md->delayUp = round(ui->delayUpSB->value() * scale); + md->speedDown = round(ui->slowDownSB->value() * scale); + md->speedUp = round(ui->slowUpSB->value() * scale); strcpy(md->name, ui->mixerName->text().toLatin1()); md->flightModes = 0; - for (int i=CPN_MAX_FLIGHT_MODES-1; i>=0 ; i--) { + for (int i = CPN_MAX_FLIGHT_MODES - 1; i >= 0 ; i--) { if (!cb_fp[i]->checkState()) { md->flightModes++; } @@ -220,7 +219,7 @@ void MixerDialog::label_phases_customContextMenuRequested(const QPoint & pos) void MixerDialog::fmClearAll() { lock = true; - for (int i=0; isetChecked(false); } lock = false; @@ -230,7 +229,7 @@ void MixerDialog::fmClearAll() void MixerDialog::fmSetAll() { lock = true; - for (int i=0; isetChecked(true); } lock = false; @@ -240,7 +239,7 @@ void MixerDialog::fmSetAll() void MixerDialog::fmInvertAll() { lock = true; - for (int i=0; isetChecked(!cb_fp[i]->isChecked()); } lock = false; diff --git a/companion/src/modeledit/mixerdialog.h b/companion/src/modeledit/mixerdialog.h index 93f061d0d..6d2131de2 100644 --- a/companion/src/modeledit/mixerdialog.h +++ b/companion/src/modeledit/mixerdialog.h @@ -25,7 +25,8 @@ #include "eeprominterface.h" class GVarGroup; -class CurveGroup; +class RawItemFilteredModel; +class CurveReferenceUIManager; namespace Ui { class MixerDialog; @@ -34,7 +35,8 @@ namespace Ui { class MixerDialog : public QDialog { Q_OBJECT public: - MixerDialog(QWidget *parent, ModelData & model, MixData *mixdata, GeneralSettings & generalSettings, Firmware * firmware); + MixerDialog(QWidget *parent, ModelData & model, MixData *mixdata, GeneralSettings & generalSettings, Firmware * firmware, + RawItemFilteredModel * rawSourceModel, RawItemFilteredModel * rawSwitchModel, RawItemFilteredModel * curveItemModel); ~MixerDialog(); protected: @@ -57,7 +59,7 @@ class MixerDialog : public QDialog { bool lock; GVarGroup * gvWeightGroup; GVarGroup * gvOffsetGroup; - CurveGroup * curveGroup; + CurveReferenceUIManager * curveGroup; QCheckBox * cb_fp[CPN_MAX_FLIGHT_MODES]; }; diff --git a/companion/src/modeledit/mixes.cpp b/companion/src/modeledit/mixes.cpp index 4d0f5f4cd..f02a57417 100644 --- a/companion/src/modeledit/mixes.cpp +++ b/companion/src/modeledit/mixes.cpp @@ -20,13 +20,27 @@ #include "mixes.h" #include "helpers.h" +#include "rawitemfilteredmodel.h" -MixesPanel::MixesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware): +MixesPanel::MixesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware,CommonItemModels * commonItemModels): ModelPanel(parent, model, generalSettings, firmware), mixInserted(false), highlightedSource(0), - modelPrinter(firmware, generalSettings, model) + modelPrinter(firmware, generalSettings, model), + commonItemModels(commonItemModels) { + rawSourceFilteredModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), ((RawSource::InputSourceGroups | RawSource::ScriptsGroup) & ~ RawSource::NoneGroup), this); + connect(rawSourceFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &MixesPanel::onModelDataAboutToBeUpdated); + connect(rawSourceFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &MixesPanel::onModelDataUpdateComplete); + + rawSwitchFilteredModel = new RawItemFilteredModel(commonItemModels->rawSwitchItemModel(), RawSwitch::MixesContext, this); + connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &MixesPanel::onModelDataAboutToBeUpdated); + connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &MixesPanel::onModelDataUpdateComplete); + + curveFilteredModel = new RawItemFilteredModel(commonItemModels->curveItemModel(), RawItemFilteredModel::AllFilter, this); + connect(curveFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &MixesPanel::onModelDataAboutToBeUpdated); + connect(curveFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &MixesPanel::onModelDataUpdateComplete); + QGridLayout * mixesLayout = new QGridLayout(this); mixersListWidget = new MixersListWidget(this, false); // TODO enum @@ -175,8 +189,8 @@ void MixesPanel::gm_openMix(int index) MixData mixd(model->mixData[index]); - MixerDialog *g = new MixerDialog(this, *model, &mixd, generalSettings, firmware); - if(g->exec()) { + MixerDialog *dlg = new MixerDialog(this, *model, &mixd, generalSettings, firmware, rawSourceFilteredModel, rawSwitchFilteredModel, curveFilteredModel); + if(dlg->exec()) { model->mixData[index] = mixd; emit modified(); update(); @@ -188,6 +202,7 @@ void MixesPanel::gm_openMix(int index) mixInserted = false; update(); } + delete dlg; } int MixesPanel::getMixerIndex(unsigned int dch) @@ -529,3 +544,14 @@ void MixesPanel::clearMixes() update(); } } + +void MixesPanel::onModelDataAboutToBeUpdated() +{ + lock = true; +} + +void MixesPanel::onModelDataUpdateComplete() +{ + update(); + lock = false; +} diff --git a/companion/src/modeledit/mixes.h b/companion/src/modeledit/mixes.h index 95765465e..014786b74 100644 --- a/companion/src/modeledit/mixes.h +++ b/companion/src/modeledit/mixes.h @@ -26,12 +26,15 @@ #include "mixerdialog.h" #include "modelprinter.h" +class CommonItemModels; +class RawItemFilteredModel; + class MixesPanel : public ModelPanel { Q_OBJECT public: - MixesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware); + MixesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels); virtual ~MixesPanel(); virtual void update(); @@ -50,7 +53,6 @@ class MixesPanel : public ModelPanel void moveMixDown(); void mixerHighlight(); - void mixerlistWidget_customContextMenuRequested(QPoint pos); void mixerlistWidget_doubleClicked(QModelIndex index); void mixerlistWidget_KeyPress(QKeyEvent *event); @@ -58,11 +60,18 @@ class MixesPanel : public ModelPanel void mimeMixerDropped(int index, const QMimeData *data, Qt::DropAction action); void pasteMixerMimeData(const QMimeData * mimeData, int destIdx); + void onModelDataAboutToBeUpdated(); + void onModelDataUpdateComplete(); + private: MixersListWidget * mixersListWidget; bool mixInserted; unsigned int highlightedSource; ModelPrinter modelPrinter; + CommonItemModels * commonItemModels; + RawItemFilteredModel *rawSourceFilteredModel; + RawItemFilteredModel *rawSwitchFilteredModel; + RawItemFilteredModel *curveFilteredModel; int getMixerIndex(unsigned int dch); bool gm_insertMix(int idx); diff --git a/companion/src/modeledit/modeledit.cpp b/companion/src/modeledit/modeledit.cpp index af3166c7f..41989ba53 100644 --- a/companion/src/modeledit/modeledit.cpp +++ b/companion/src/modeledit/modeledit.cpp @@ -33,6 +33,7 @@ #include "customfunctions.h" #include "telemetry.h" #include "appdata.h" +#include "rawitemdatamodels.h" ModelEdit::ModelEdit(QWidget * parent, RadioData & radioData, int modelId, Firmware * firmware) : QDialog(parent), @@ -48,33 +49,55 @@ ModelEdit::ModelEdit(QWidget * parent, RadioData & radioData, int modelId, Firmw setWindowIcon(CompanionIcon("edit.png")); restoreGeometry(g.modelEditGeo()); ui->pushButton->setIcon(CompanionIcon("simulate.png")); - SetupPanel * setupPanel = new SetupPanel(this, radioData.models[modelId], radioData.generalSettings, firmware); + + GeneralSettings &generalSettings = radioData.generalSettings; + ModelData &model = radioData.models[modelId]; + + commonItemModels = new CommonItemModels(&generalSettings, &model, this); + s1.report("Init"); + + SetupPanel * setupPanel = new SetupPanel(this, model, generalSettings, firmware, commonItemModels); addTab(setupPanel, tr("Setup")); - if (firmware->getCapability(Heli)) - addTab(new HeliPanel(this, radioData.models[modelId], radioData.generalSettings, firmware), tr("Heli")); - addTab(new FlightModesPanel(this, radioData.models[modelId], radioData.generalSettings, firmware), tr("Flight Modes")); - addTab(new InputsPanel(this, radioData.models[modelId], radioData.generalSettings, firmware), tr("Inputs")); - s1.report("inputs"); - addTab(new MixesPanel(this, radioData.models[modelId], radioData.generalSettings, firmware), tr("Mixes")); + s1.report("Setup"); + + if (firmware->getCapability(Heli)) { + addTab(new HeliPanel(this, model, generalSettings, firmware, commonItemModels), tr("Heli")); + s1.report("Heli"); + } + + addTab(new FlightModesPanel(this, model, generalSettings, firmware, commonItemModels), tr("Flight Modes")); + s1.report("Flight Modes"); + + addTab(new InputsPanel(this, model, generalSettings, firmware, commonItemModels), tr("Inputs")); + s1.report("Inputs"); + + addTab(new MixesPanel(this, model, generalSettings, firmware, commonItemModels), tr("Mixes")); s1.report("Mixes"); - Channels * chnPanel = new Channels(this, radioData.models[modelId], radioData.generalSettings, firmware); - addTab(chnPanel, tr("Outputs")); + + ChannelsPanel * channelsPanel = new ChannelsPanel(this, model, generalSettings, firmware, commonItemModels); + addTab(channelsPanel, tr("Outputs")); s1.report("Outputs"); - addTab(new Curves(this, radioData.models[modelId], radioData.generalSettings, firmware), tr("Curves")); - addTab(new LogicalSwitchesPanel(this, radioData.models[modelId], radioData.generalSettings, firmware), tr("Logical Switches")); - s1.report("LS"); - addTab(new CustomFunctionsPanel(this, &radioData.models[modelId], radioData.generalSettings, firmware), tr("Special Functions")); - s1.report("CF"); - if (firmware->getCapability(Telemetry)) - addTab(new TelemetryPanel(this, radioData.models[modelId], radioData.generalSettings, firmware), tr("Telemetry")); - onTabIndexChanged(ui->tabWidget->currentIndex()); // make sure to trigger update on default tab panel + addTab(new CurvesPanel(this, model, generalSettings, firmware, commonItemModels), tr("Curves")); + s1.report("Curves"); - connect(setupPanel, &SetupPanel::extendedLimitsToggled, chnPanel, &Channels::refreshExtendedLimits); + addTab(new LogicalSwitchesPanel(this, model, generalSettings, firmware, commonItemModels), tr("Logical Switches")); + s1.report("Logical Switches"); + + addTab(new CustomFunctionsPanel(this, &model, generalSettings, firmware, commonItemModels), tr("Special Functions")); + s1.report("Special Functions"); + + if (firmware->getCapability(Telemetry)) { + addTab(new TelemetryPanel(this, model, generalSettings, firmware, commonItemModels), tr("Telemetry")); + s1.report("Telemetry"); + } + + connect(setupPanel, &SetupPanel::extendedLimitsToggled, channelsPanel, &ChannelsPanel::refreshExtendedLimits); connect(ui->tabWidget, &QTabWidget::currentChanged, this, &ModelEdit::onTabIndexChanged); connect(ui->pushButton, &QPushButton::clicked, this, &ModelEdit::launchSimulation); - s1.report("end"); + onTabIndexChanged(ui->tabWidget->currentIndex()); // make sure to trigger update on default tab panel + gStopwatch.report("ModelEdit end constructor"); } diff --git a/companion/src/modeledit/modeledit.h b/companion/src/modeledit/modeledit.h index 969ae85d7..9095101bf 100644 --- a/companion/src/modeledit/modeledit.h +++ b/companion/src/modeledit/modeledit.h @@ -25,6 +25,7 @@ #include "genericpanel.h" class RadioData; +class CommonItemModels; namespace Ui { class ModelEdit; @@ -62,6 +63,7 @@ class ModelEdit : public QDialog RadioData & radioData; Firmware * firmware; QVector panels; + CommonItemModels * commonItemModels; void addTab(GenericPanel *panel, QString text); void launchSimulation(); diff --git a/companion/src/modeledit/setup.cpp b/companion/src/modeledit/setup.cpp index 5d4dfec79..e4f67178d 100644 --- a/companion/src/modeledit/setup.cpp +++ b/companion/src/modeledit/setup.cpp @@ -31,13 +31,14 @@ #include -TimerPanel::TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, Firmware * firmware, QWidget * prevFocus, RawSwitchFilterItemModel * switchModel): +TimerPanel::TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, Firmware * firmware, QWidget * prevFocus, RawItemFilteredModel * rawSwitchFilteredModel): ModelPanel(parent, model, generalSettings, firmware), timer(timer), ui(new Ui::Timer) { - ui->setupUi(this); + connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &TimerPanel::onModelDataAboutToBeUpdated); + connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &TimerPanel::onModelDataUpdateComplete); lock = true; @@ -48,11 +49,10 @@ TimerPanel::TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, Ge } else { ui->name->setMaxLength(length); - //ui->name->setText(timer.name); } // Mode - ui->mode->setModel(switchModel); + ui->mode->setModel(rawSwitchFilteredModel); ui->mode->setCurrentIndex(ui->mode->findData(timer.mode.toValue())); connect(ui->mode, SIGNAL(activated(int)), this, SLOT(onModeChanged(int))); @@ -94,6 +94,7 @@ TimerPanel::~TimerPanel() void TimerPanel::update() { lock = true; + ui->name->setText(timer.name); int hour = timer.val / 3600; @@ -114,7 +115,7 @@ void TimerPanel::update() pvalue -= hours * 3600; int minutes = pvalue / 60; int seconds = pvalue % 60; - ui->persistentValue->setText(QString(" %1(%2:%3:%4)").arg(sign<0 ? "-" :" ").arg(hours, 2, 10, QLatin1Char('0')).arg(minutes, 2, 10, QLatin1Char('0')).arg(seconds, 2, 10, QLatin1Char('0'))); + ui->persistentValue->setText(QString(" %1(%2:%3:%4)").arg(sign < 0 ? "-" :" ").arg(hours, 2, 10, QLatin1Char('0')).arg(minutes, 2, 10, QLatin1Char('0')).arg(seconds, 2, 10, QLatin1Char('0'))); } ui->countdownBeep->updateValue(); @@ -131,7 +132,7 @@ QWidget * TimerPanel::getLastFocus() void TimerPanel::on_value_editingFinished() { if (!lock) { - unsigned val = ui->value->time().hour()*3600 + ui->value->time().minute()*60 + ui->value->time().second(); + 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(); @@ -165,11 +166,23 @@ void TimerPanel::on_name_editingFinished() if (QString(timer.name) != ui->name->text()) { int length = ui->name->maxLength(); strncpy(timer.name, ui->name->text().toLatin1(), length); + emit nameChanged(); emit modified(); } } } +void TimerPanel::onModelDataAboutToBeUpdated() +{ + lock = true; +} + +void TimerPanel::onModelDataUpdateComplete() +{ + update(); + lock = false; +} + /******************************************************************************/ #define FAILSAFE_CHANNEL_HOLD 2000 @@ -237,19 +250,19 @@ ModulePanel::ModulePanel(QWidget * parent, ModelData & model, ModuleData & modul } // The protocols available on this board - for (unsigned int i=0; iisAvailable((PulsesProtocol) i, moduleIdx)) { ui->protocol->addItem(ModuleData::protocolToString(i), i); if (i == module.protocol) - ui->protocol->setCurrentIndex(ui->protocol->count()-1); + ui->protocol->setCurrentIndex(ui->protocol->count() - 1); } } - for (int i=0; i<=MODULE_SUBTYPE_MULTI_LAST; i++) { + for (int i = 0; i <= MODULE_SUBTYPE_MULTI_LAST; i++) { if (i == MODULE_SUBTYPE_MULTI_SCANNER) continue; ui->multiProtocol->addItem(Multiprotocols::protocolToString(i), i); } - for (int i=MODULE_SUBTYPE_MULTI_LAST + 1; i <= 124; i++) { + for (int i = MODULE_SUBTYPE_MULTI_LAST + 1; i <= 124; i++) { ui->multiProtocol->addItem(QString::number(i + 3), i); } @@ -327,7 +340,7 @@ void ModulePanel::setupFailsafes() else { QLabel * label = new QLabel(this); label->setProperty("index", i); - label->setText(QString::number(i+1)); + label->setText(QString::number(i + 1)); QComboBox * combo = new QComboBox(this); combo->setProperty("index", i); @@ -506,7 +519,7 @@ void ModulePanel::update() ui->ppmFrameLength->setVisible(mask & MASK_SBUSPPM_FIELDS); ui->ppmFrameLength->setMinimum(module.channelsCount * (model->extendedLimits ? 2.250 : 2)+3.5); ui->ppmFrameLength->setMaximum(firmware->getCapability(PPMFrameLength)); - ui->ppmFrameLength->setValue(22.5+((double)module.ppm.frameLength)*0.5); + ui->ppmFrameLength->setValue(22.5 + ((double)module.ppm.frameLength) * 0.5); // Antenna mode on Horus and XLite if (mask & MASK_ANTENNA) { @@ -600,17 +613,17 @@ void ModulePanel::update() ui->registrationIdLabel->setVisible(mask & MASK_ACCESS); ui->registrationId->setVisible(mask & MASK_ACCESS); - ui->rx1Label->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<0))); - ui->clearRx1->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<0))); - ui->rx1->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<0))); + ui->rx1Label->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1 << 0))); + ui->clearRx1->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1 << 0))); + ui->rx1->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1 << 0))); - ui->rx2Label->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<1))); - ui->clearRx2->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<1))); - ui->rx2->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<1))); + ui->rx2Label->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1 << 1))); + ui->clearRx2->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1 << 1))); + ui->rx2->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1 << 1))); - ui->rx3Label->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<2))); - ui->clearRx3->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<2))); - ui->rx3->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<2))); + ui->rx3Label->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1 << 2))); + ui->clearRx3->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1 << 2))); + ui->rx3->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1 << 2))); // Failsafes ui->label_failsafeMode->setVisible(mask & MASK_FAILSAFES); @@ -703,8 +716,8 @@ void ModulePanel::on_channelsCount_editingFinished() { if (!lock && module.channelsCount != ui->channelsCount->value()) { module.channelsCount = ui->channelsCount->value(); - update(); emit channelsRangeChanged(); + update(); emit modified(); } } @@ -713,8 +726,8 @@ void ModulePanel::on_channelsStart_editingFinished() { if (!lock && module.channelsStart != (unsigned)ui->channelsStart->value() - 1) { module.channelsStart = (unsigned)ui->channelsStart->value() - 1; - update(); emit channelsRangeChanged(); + update(); emit modified(); } } @@ -738,7 +751,7 @@ void ModulePanel::on_rxNumber_editingFinished() void ModulePanel::on_ppmFrameLength_editingFinished() { - int val = (ui->ppmFrameLength->value()-22.5) / 0.5; + int val = (ui->ppmFrameLength->value() - 22.5) / 0.5; if (module.ppm.frameLength != val) { module.ppm.frameLength = val; emit modified(); @@ -762,8 +775,8 @@ void ModulePanel::onMultiProtocolChanged(int index) module.multi.rfProtocol = (unsigned int)rfProtocol; unsigned int maxSubTypes = multiProtocols.getProtocol(index).numSubTypes(); if (rfProtocol > MODULE_SUBTYPE_MULTI_LAST) - maxSubTypes=8; - module.subType = std::min(module.subType, maxSubTypes -1); + maxSubTypes = 8; + module.subType = std::min(module.subType, maxSubTypes - 1); module.channelsCount = module.getMaxChannelCount(); update(); emit modified(); @@ -957,19 +970,19 @@ void ModulePanel::onClearAccessRxClicked() QPushButton *button = qobject_cast(sender()); if (button == ui->clearRx1) { - module.access.receivers &= ~(1<<0); + module.access.receivers &= ~(1 << 0); ui->rx1->clear(); update(); emit modified(); } else if (button == ui->clearRx2) { - module.access.receivers &= ~(1<<1); + module.access.receivers &= ~(1 << 1); ui->rx2->clear(); update(); emit modified(); } else if (button == ui->clearRx3) { - module.access.receivers &= ~(1<<2); + module.access.receivers &= ~(1 << 2); ui->rx3->clear(); update(); emit modified(); @@ -978,18 +991,20 @@ void ModulePanel::onClearAccessRxClicked() /******************************************************************************/ -SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware): +SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels): ModelPanel(parent, model, generalSettings, firmware), - ui(new Ui::Setup) + ui(new Ui::Setup), + commonItemModels(commonItemModels) { + ui->setupUi(this); + rawSwitchFilteredModel = new RawItemFilteredModel(commonItemModels->rawSwitchItemModel(), RawSwitch::TimersContext, this); + Board::Type board = firmware->getBoard(); lock = true; memset(modules, 0, sizeof(modules)); - ui->setupUi(this); - QRegExp rx(CHAR_FOR_NAMES_REGEX); ui->name->setValidator(new QRegExpValidator(rx, this)); ui->name->setMaxLength(firmware->getCapability(ModelName)); @@ -1007,7 +1022,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge foreach ( QString file, qd.entryList(filters, QDir::Files) ) { QFileInfo fi(file); QString temp = fi.fileName(); - if (!items.contains(temp) && temp.length() <= 6+4) { + if (!items.contains(temp) && temp.length() <= 6 + 4) { items.append(temp); } } @@ -1017,7 +1032,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge foreach (QString file, qd.entryList(filters, QDir::Files)) { QFileInfo fi(file); QString temp = fi.completeBaseName(); - if (!items.contains(temp) && temp.length() <= 10+4) { + if (!items.contains(temp) && temp.length() <= 10 + 4) { items.append(temp); } } @@ -1030,7 +1045,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge foreach (QString file, items) { ui->image->addItem(file); if (file == model.bitmap) { - ui->image->setCurrentIndex(ui->image->count()-1); + ui->image->setCurrentIndex(ui->image->count() - 1); QString fileName = path; fileName.append(model.bitmap); if (!IS_FAMILY_HORUS_OR_T16(board)) @@ -1062,18 +1077,16 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge } QWidget * prevFocus = ui->image; - RawSwitchFilterItemModel * swModel = new RawSwitchFilterItemModel(&generalSettings, &model, RawSwitch::TimersContext, this); - connect(this, &SetupPanel::updated, swModel, &RawSwitchFilterItemModel::update); timersCount = firmware->getCapability(Timers); for (int i = 0; i < CPN_MAX_TIMERS; i++) { if (i < timersCount) { - timers[i] = new TimerPanel(this, model, model.timers[i], generalSettings, firmware, prevFocus, swModel); + timers[i] = new TimerPanel(this, model, model.timers[i], generalSettings, firmware, prevFocus, rawSwitchFilteredModel); ui->gridLayout->addWidget(timers[i], 1+i, 1); connect(timers[i], &TimerPanel::modified, this, &SetupPanel::modified); + connect(timers[i], &TimerPanel::nameChanged, this, &SetupPanel::onTimerNameChanged); connect(this, &SetupPanel::updated, timers[i], &TimerPanel::update); - connect(this, &SetupPanel::timerUpdated, timers[i], &TimerPanel::update); prevFocus = timers[i]->getLastFocus(); // TODO more reliable method required QLabel *label = findChild(QString("label_timer%1").arg(i + 1)); @@ -1095,7 +1108,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge if (firmware->getCapability(HasTopLcd)) { ui->toplcdTimer->setField(model.toplcdTimer, this); for (int i = 0; i < CPN_MAX_TIMERS; i++) { - if (itoplcdTimer->addItem(tr("Timer %1").arg(i + 1), i); } } @@ -1118,12 +1131,12 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge prevFocus = ui->trimsDisplay; int analogs = CPN_MAX_STICKS + getBoardCapability(board, Board::Pots) + getBoardCapability(board, Board::Sliders); int genAryIdx = 0; - for (int i=0; i < analogs + firmware->getCapability(RotaryEncoders); i++) { + for (int i = 0; i < analogs + firmware->getCapability(RotaryEncoders); i++) { RawSource src((i < analogs) ? SOURCE_TYPE_STICK : SOURCE_TYPE_ROTARY_ENCODER, (i < analogs) ? i : analogs - i); QCheckBox * checkbox = new QCheckBox(this); checkbox->setProperty("index", i); checkbox->setText(src.toString(&model, &generalSettings)); - ui->centerBeepLayout->addWidget(checkbox, 0, i+1); + ui->centerBeepLayout->addWidget(checkbox, 0, i + 1); connect(checkbox, SIGNAL(toggled(bool)), this, SLOT(onBeepCenterToggled(bool))); centerBeepCheckboxes << checkbox; if (IS_HORUS_OR_TARANIS(board)) { @@ -1139,7 +1152,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge } // Startup switches warnings - for (int i=0; isetText(src.toString(&model, &generalSettings)); slider->setMaximum(switchInfo.config == Board::SWITCH_3POS ? 2 : 1); cb->setProperty("index", i); - ui->switchesStartupLayout->addWidget(label, 0, i+1); + ui->switchesStartupLayout->addWidget(label, 0, i + 1); ui->switchesStartupLayout->setAlignment(label, Qt::AlignCenter); - ui->switchesStartupLayout->addWidget(slider, 1, i+1); + ui->switchesStartupLayout->addWidget(slider, 1, i + 1); ui->switchesStartupLayout->setAlignment(slider, Qt::AlignCenter); - ui->switchesStartupLayout->addWidget(cb, 2, i+1); + ui->switchesStartupLayout->addWidget(cb, 2, i + 1); ui->switchesStartupLayout->setAlignment(cb, Qt::AlignCenter); connect(slider, SIGNAL(valueChanged(int)), this, SLOT(startupSwitchEdited(int))); connect(cb, SIGNAL(toggled(bool)), this, SLOT(startupSwitchToggled(bool))); @@ -1181,12 +1194,12 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge // Pot warnings prevFocus = ui->potWarningMode; if (IS_HORUS_OR_TARANIS(board)) { - for (int i=0; isetProperty("index", i); cb->setText(src.toString(&model, &generalSettings)); - ui->potWarningLayout->addWidget(cb, 0, i+1); + ui->potWarningLayout->addWidget(cb, 0, i + 1); connect(cb, SIGNAL(toggled(bool)), this, SLOT(potWarningToggled(bool))); potWarningCheckboxes << cb; if (src.isPot(&genAryIdx) && !generalSettings.isPotAvailable(genAryIdx)) { @@ -1264,7 +1277,7 @@ void SetupPanel::on_extendedTrims_toggled(bool checked) void SetupPanel::on_trimIncrement_currentIndexChanged(int index) { - model->trimInc = index-2; + model->trimInc = index - 2; emit modified(); } @@ -1341,13 +1354,13 @@ void SetupPanel::populateThrottleSourceCB() ui->throttleSource->clear(); ui->throttleSource->addItem(tr("THR"), 0); - int idx=1; - for (int i=0; ithrottleSource->addItem(firmware->getAnalogInputName(4+i), idx); + int idx = 1; + for (int i = 0; i < getBoardCapability(board, Board::Pots) + getBoardCapability(board, Board::Sliders); i++, idx++) { + if (RawSource(SOURCE_TYPE_STICK, 4 + i).isAvailable(model, &generalSettings, board)) { + ui->throttleSource->addItem(firmware->getAnalogInputName(4 + i), idx); } } - for (int i=0; igetCapability(Outputs); i++, idx++) { + for (int i = 0; i < firmware->getCapability(Outputs); i++, idx++) { ui->throttleSource->addItem(RawSource(SOURCE_TYPE_CH, i).toString(model, &generalSettings), idx); } @@ -1362,9 +1375,15 @@ void SetupPanel::populateThrottleTrimSwitchCB() lock = true; ui->throttleTrimSwitch->clear(); int idx=0; + QString trim; for (int i=0; ithrottleTrimSwitch->addItem(trim, idx); } @@ -1394,7 +1413,7 @@ void SetupPanel::update() updatePotWarnings(); } - for (int i=0; iupdate(); } @@ -1405,7 +1424,7 @@ void SetupPanel::update() void SetupPanel::updateBeepCenter() { - for (int i=0; isetChecked(model->beepANACenter & (0x01 << i)); } } @@ -1417,20 +1436,20 @@ void SetupPanel::updateStartupSwitches() uint64_t switchStates = model->switchWarningStates; uint64_t value; - for (int i=0; iproperty("index").toInt(); bool enabled = !(model->switchWarningEnable & (1 << index)); if (IS_HORUS_OR_TARANIS(firmware->getBoard())) { - value = (switchStates >> (2*index)) & 0x03; + value = (switchStates >> (2 * index)) & 0x03; if (generalSettings.switchConfig[index] != Board::SWITCH_3POS && value == 2) { value = 1; } } else { - value = (i==0 ? switchStates & 0x3 : switchStates & 0x1); - switchStates >>= (i==0 ? 2 : 1); + value = (i == 0 ? switchStates & 0x3 : switchStates & 0x1); + switchStates >>= (i == 0 ? 2 : 1); } slider->setValue(value); slider->setEnabled(enabled); @@ -1456,7 +1475,7 @@ void SetupPanel::startupSwitchEdited(int value) mask = 0x03; } else { - shift = index+1; + shift = index + 1; mask = 0x01ull << shift; } } @@ -1497,7 +1516,7 @@ void SetupPanel::updatePotWarnings() { lock = true; ui->potWarningMode->setCurrentIndex(model->potsWarningMode); - for (int i=0; iproperty("index").toInt(); checkbox->setChecked(!model->potsWarnEnabled[index]); @@ -1627,7 +1646,7 @@ void SetupPanel::cmTimerClear(bool prompt) model->timers[selectedTimerIndex].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_TIMER, ModelData::REF_UPD_ACT_CLEAR, selectedTimerIndex); - emit timerUpdated(); + updateItemModels(); emit modified(); } @@ -1640,7 +1659,7 @@ void SetupPanel::cmTimerClearAll() model->timers[i].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_TIMER, ModelData::REF_UPD_ACT_CLEAR, i); } - emit timerUpdated(); + updateItemModels(); emit modified(); } @@ -1674,7 +1693,7 @@ void SetupPanel::cmTimerDelete() } model->timers[maxidx].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_TIMER, ModelData::REF_UPD_ACT_SHIFT, selectedTimerIndex, 0, -1); - emit timerUpdated(); + updateItemModels(); emit modified(); } @@ -1687,7 +1706,7 @@ void SetupPanel::cmTimerInsert() } model->timers[selectedTimerIndex].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_TIMER, ModelData::REF_UPD_ACT_SHIFT, selectedTimerIndex, 0, 1); - emit timerUpdated(); + updateItemModels(); emit modified(); } @@ -1707,7 +1726,7 @@ void SetupPanel::cmTimerPaste() if (hasTimerClipboardData(&data)) { TimerData *td = &model->timers[selectedTimerIndex]; memcpy(td, data.constData(), sizeof(TimerData)); - emit timerUpdated(); + updateItemModels(); emit modified(); } } @@ -1721,7 +1740,17 @@ void SetupPanel::swapTimerData(int idx1, int idx2) memcpy(td2, td1, sizeof(TimerData)); memcpy(td1, &tdtmp, sizeof(TimerData)); model->updateAllReferences(ModelData::REF_UPD_TYPE_TIMER, ModelData::REF_UPD_ACT_SWAP, idx1, idx2); - emit timerUpdated(); + updateItemModels(); emit modified(); } } + +void SetupPanel::onTimerNameChanged() +{ + updateItemModels(); +} + +void SetupPanel::updateItemModels() +{ + commonItemModels->update(CommonItemModels::RMO_TIMERS); +} diff --git a/companion/src/modeledit/setup.h b/companion/src/modeledit/setup.h index e0c3df507..c56e63ea1 100644 --- a/companion/src/modeledit/setup.h +++ b/companion/src/modeledit/setup.h @@ -26,7 +26,8 @@ constexpr char MIMETYPE_TIMER[] = "application/x-companion-timer"; -class RawSwitchFilterItemModel; +class CommonItemModels; +class RawItemFilteredModel; namespace Ui { class Setup; @@ -39,7 +40,7 @@ class TimerPanel : public ModelPanel Q_OBJECT public: - TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, Firmware * firmware, QWidget *prevFocus, RawSwitchFilterItemModel * switchModel); + TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, Firmware * firmware, QWidget *prevFocus, RawItemFilteredModel * switchModel); virtual ~TimerPanel(); virtual void update(); @@ -50,6 +51,11 @@ class TimerPanel : public ModelPanel void on_value_editingFinished(); void on_minuteBeep_toggled(bool checked); void on_name_editingFinished(); + void onModelDataAboutToBeUpdated(); + void onModelDataUpdateComplete(); + + signals: + void nameChanged(); private: TimerData & timer; @@ -125,7 +131,7 @@ class SetupPanel : public ModelPanel Q_OBJECT public: - SetupPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware); + SetupPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels); virtual ~SetupPanel(); virtual void update(); @@ -133,7 +139,6 @@ class SetupPanel : public ModelPanel signals: void extendedLimitsToggled(); void updated(); - void timerUpdated(); private slots: void on_name_editingFinished(); @@ -164,6 +169,7 @@ class SetupPanel : public ModelPanel void cmTimerPaste(); void cmTimerMoveDown(); void cmTimerMoveUp(); + void onTimerNameChanged(); private: Ui::Setup *ui; @@ -185,6 +191,9 @@ class SetupPanel : public ModelPanel bool moveTimerDownAllowed() const; bool moveTimerUpAllowed() const; void swapTimerData(int idx1, int idx2); -}; + CommonItemModels * commonItemModels; + RawItemFilteredModel * rawSwitchFilteredModel; + void updateItemModels(); + }; #endif // _SETUP_H_ diff --git a/companion/src/modeledit/telemetry.cpp b/companion/src/modeledit/telemetry.cpp index b34caa89e..e980c3943 100644 --- a/companion/src/modeledit/telemetry.cpp +++ b/companion/src/modeledit/telemetry.cpp @@ -28,18 +28,20 @@ #include -TelemetryCustomScreen::TelemetryCustomScreen(QWidget *parent, ModelData & model, FrSkyScreenData & screen, GeneralSettings & generalSettings, Firmware * firmware, RawSourceFilterItemModel * srcModel): +TelemetryCustomScreen::TelemetryCustomScreen(QWidget *parent, ModelData & model, FrSkyScreenData & screen, GeneralSettings & generalSettings, Firmware * firmware, RawItemFilteredModel * rawSourceModel): ModelPanel(parent, model, generalSettings, firmware), ui(new Ui::TelemetryCustomScreen), screen(screen) { ui->setupUi(this); + connect(rawSourceModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &TelemetryCustomScreen::onModelDataAboutToBeUpdated); + connect(rawSourceModel, &RawItemFilteredModel::dataUpdateComplete, this, &TelemetryCustomScreen::onModelDataUpdateComplete); for (int l = 0; l < firmware->getCapability(TelemetryCustomScreensLines); l++) { for (int c = 0; c < firmware->getCapability(TelemetryCustomScreensFieldsPerLine); c++) { fieldsCB[l][c] = new QComboBox(this); fieldsCB[l][c]->setProperty("index", c + (l << 8)); - fieldsCB[l][c]->setModel(srcModel); + fieldsCB[l][c]->setModel(rawSourceModel); ui->screenNumsLayout->addWidget(fieldsCB[l][c], l, c, 1, 1); connect(fieldsCB[l][c], SIGNAL(activated(int)), this, SLOT(customFieldChanged(int))); } @@ -48,7 +50,7 @@ TelemetryCustomScreen::TelemetryCustomScreen(QWidget *parent, ModelData & model, for (int l = 0; l < firmware->getCapability(TelemetryCustomScreensBars); l++) { barsCB[l] = new QComboBox(this); barsCB[l]->setProperty("index", l); - barsCB[l]->setModel(srcModel); + barsCB[l]->setModel(rawSourceModel); connect(barsCB[l], SIGNAL(activated(int)), this, SLOT(barSourceChanged(int))); ui->screenBarsLayout->addWidget(barsCB[l], l, 0, 1, 1); @@ -287,6 +289,17 @@ void TelemetryCustomScreen::barTimeChanged() } } +void TelemetryCustomScreen::onModelDataAboutToBeUpdated() +{ + lock = true; +} + +void TelemetryCustomScreen::onModelDataUpdateComplete() +{ + update(); + lock = false; +} + /******************************************************/ TelemetrySensorPanel::TelemetrySensorPanel(QWidget *parent, SensorData & sensor, int sensorIndex, int sensorCapability, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware): @@ -305,6 +318,7 @@ TelemetrySensorPanel::TelemetrySensorPanel(QWidget *parent, SensorData & sensor, QFontMetrics *f = new QFontMetrics(QFont()); QSize sz; sz = f->size(Qt::TextSingleLine, "TELE00"); + delete f; ui->numLabel->setMinimumWidth(sz.width()); ui->numLabel->setContextMenuPolicy(Qt::CustomContextMenu); ui->numLabel->setToolTip(tr("Popup menu available")); @@ -505,7 +519,6 @@ void TelemetrySensorPanel::on_name_editingFinished() if (!lock) { strcpy(sensor.label, ui->name->text().toLatin1()); emit dataModified(); - emit modified(); } } @@ -535,7 +548,6 @@ void TelemetrySensorPanel::on_formula_currentIndexChanged(int index) sensor.unit = SensorData::UNIT_METERS; } emit dataModified(); - emit modified(); } } @@ -631,7 +643,6 @@ void TelemetrySensorPanel::cmPaste() if (hasClipboardData(&data)) { memcpy(&sensor, data.constData(), sizeof(SensorData)); emit dataModified(); - emit modified(); } } @@ -645,7 +656,6 @@ void TelemetrySensorPanel::cmClear(bool prompt) sensor.clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_CLEAR, selectedIndex); emit dataModified(); - emit modified(); } void TelemetrySensorPanel::cmClearAll() @@ -678,11 +688,13 @@ void TelemetrySensorPanel::cmMoveDown() /******************************************************/ -TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware): +TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels): ModelPanel(parent, model, generalSettings, firmware), - ui(new Ui::Telemetry) + ui(new Ui::Telemetry), + commonItemModels(commonItemModels) { ui->setupUi(this); + rawSourceFilteredModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), this); sensorCapability = firmware->getCapability(Sensors); if (sensorCapability > CPN_MAX_SENSORS) // TODO should be role of getCapability @@ -696,11 +708,12 @@ TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettin ui->varioCenterSilent->setField(model.frsky.varioCenterSilent, this); ui->A1GB->hide(); ui->A2GB->hide(); + for (int i = 0; i < sensorCapability; ++i) { TelemetrySensorPanel * panel = new TelemetrySensorPanel(this, model.sensorData[i], i, sensorCapability, model, generalSettings, firmware); ui->sensorsLayout->addWidget(panel); sensorPanels[i] = panel; - connect(panel, SIGNAL(dataModified()), this, SLOT(update())); + connect(panel, SIGNAL(dataModified()), this, SLOT(on_dataModifiedSensor())); connect(panel, SIGNAL(modified()), this, SLOT(onModified())); connect(panel, SIGNAL(clearAllSensors()), this, SLOT(on_clearAllSensors())); connect(panel, SIGNAL(insertSensor(int)), this, SLOT(on_insertSensor(int))); @@ -717,15 +730,11 @@ TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettin ui->topbarGB->hide(); } - RawSourceFilterItemModel * srcModel = (new RawSourceFilterItemModel(&generalSettings, &model, this)); - connect(this, &TelemetryPanel::updated, srcModel, &RawSourceFilterItemModel::update); - for (int i = 0; i < firmware->getCapability(TelemetryCustomScreens); i++) { - TelemetryCustomScreen * tab = new TelemetryCustomScreen(this, model, model.frsky.screens[i], generalSettings, firmware, srcModel); + TelemetryCustomScreen * tab = new TelemetryCustomScreen(this, model, model.frsky.screens[i], generalSettings, firmware, rawSourceFilteredModel); ui->customScreens->addTab(tab, tr("Telemetry screen %1").arg(i + 1)); telemetryCustomScreens[i] = tab; connect(tab, &TelemetryCustomScreen::modified, this, &TelemetryPanel::onModified); - connect(this, &TelemetryPanel::updated, tab, &TelemetryCustomScreen::update); } disableMouseScrolling(); @@ -759,79 +768,78 @@ void TelemetryPanel::update() sensorPanels[i]->update(); } - emit updated(); + for (int i = 0; i < firmware->getCapability(TelemetryCustomScreens); i++) { + telemetryCustomScreens[i]->update(); + } } void TelemetryPanel::setup() { - QString firmware_id = g.profile[g.id()].fwType(); + lock = true; - lock = true; + ui->telemetryProtocol->addItem(tr("FrSky S.PORT"), 0); + ui->telemetryProtocol->addItem(tr("FrSky D"), 1); + if (IS_9XRPRO(firmware->getBoard()) || + (IS_TARANIS(firmware->getBoard()) && generalSettings.auxSerialMode == 2)) { + ui->telemetryProtocol->addItem(tr("FrSky D (cable)"), 2); + } + ui->telemetryProtocol->setCurrentIndex(model->telemetryProtocol); + ui->ignoreSensorIds->setField(model->frsky.ignoreSensorIds, this); + ui->disableTelemetryAlarms->setField(model->rssiAlarms.disabled); - ui->telemetryProtocol->addItem(tr("FrSky S.PORT"), 0); - ui->telemetryProtocol->addItem(tr("FrSky D"), 1); - if (IS_9XRPRO(firmware->getBoard()) || - (IS_TARANIS(firmware->getBoard()) && generalSettings.auxSerialMode == 2)) { - ui->telemetryProtocol->addItem(tr("FrSky D (cable)"), 2); - } - ui->telemetryProtocol->setCurrentIndex(model->telemetryProtocol); - ui->ignoreSensorIds->setField(model->frsky.ignoreSensorIds, this); - ui->disableTelemetryAlarms->setField(model->rssiAlarms.disabled); + ui->rssiAlarmWarningSB->setValue(model->rssiAlarms.warning); + ui->rssiAlarmCriticalSB->setValue(model->rssiAlarms.critical); - ui->rssiAlarmWarningSB->setValue(model->rssiAlarms.warning); - ui->rssiAlarmCriticalSB->setValue(model->rssiAlarms.critical); + ui->rssiSourceLabel->show(); + ui->rssiSourceLabel->setText(tr("Source")); + ui->rssiSourceCB->setField(model->rssiSource, this); + ui->rssiSourceCB->show(); + populateTelemetrySourcesComboBox(ui->rssiSourceCB, model, false); - ui->rssiSourceLabel->show(); - ui->rssiSourceLabel->setText(tr("Source")); - ui->rssiSourceCB->setField(model->rssiSource, this); - ui->rssiSourceCB->show(); - populateTelemetrySourcesComboBox(ui->rssiSourceCB, model, false); + ui->rssiAlarmWarningCB->hide(); + ui->rssiAlarmCriticalCB->hide(); + ui->rssiAlarmWarningLabel->setText(tr("Low Alarm")); + ui->rssiAlarmCriticalLabel->setText(tr("Critical Alarm")); - ui->rssiAlarmWarningCB->hide(); - ui->rssiAlarmCriticalCB->hide(); - ui->rssiAlarmWarningLabel->setText(tr("Low Alarm")); - ui->rssiAlarmCriticalLabel->setText(tr("Critical Alarm")); - - int varioCap = firmware->getCapability(HasVario); - if (!varioCap) { - ui->varioLimitMax_DSB->hide(); + if (!firmware->getCapability(HasVario)) { + ui->varioLimitMax_DSB->hide(); + ui->varioLimitMin_DSB->hide(); + ui->varioLimitCenterMin_DSB->hide(); + ui->varioLimitCenterMax_DSB->hide(); + ui->varioLimit_label->hide(); + ui->VarioLabel_1->hide(); + ui->VarioLabel_2->hide(); + ui->VarioLabel_3->hide(); + ui->VarioLabel_4->hide(); + ui->varioSource->hide(); + ui->varioSource_label->hide(); + } + else { + if (!firmware->getCapability(HasVarioSink)) { ui->varioLimitMin_DSB->hide(); ui->varioLimitCenterMin_DSB->hide(); - ui->varioLimitCenterMax_DSB->hide(); - ui->varioLimit_label->hide(); ui->VarioLabel_1->hide(); ui->VarioLabel_2->hide(); - ui->VarioLabel_3->hide(); - ui->VarioLabel_4->hide(); - ui->varioSource->hide(); - ui->varioSource_label->hide(); - } - else { - if (!firmware->getCapability(HasVarioSink)) { - ui->varioLimitMin_DSB->hide(); - ui->varioLimitCenterMin_DSB->hide(); - ui->VarioLabel_1->hide(); - ui->VarioLabel_2->hide(); - } - ui->varioLimitMin_DSB->setValue(model->frsky.varioMin - 10); - ui->varioLimitMax_DSB->setValue(model->frsky.varioMax + 10); - ui->varioLimitCenterMax_DSB->setValue((model->frsky.varioCenterMax / 10.0) + 0.5); - ui->varioLimitCenterMin_DSB->setValue((model->frsky.varioCenterMin / 10.0) - 0.5); } + ui->varioLimitMin_DSB->setValue(model->frsky.varioMin - 10); + ui->varioLimitMax_DSB->setValue(model->frsky.varioMax + 10); + ui->varioLimitCenterMax_DSB->setValue((model->frsky.varioCenterMax / 10.0) + 0.5); + ui->varioLimitCenterMin_DSB->setValue((model->frsky.varioCenterMin / 10.0) - 0.5); + } - ui->altimetryGB->setVisible(firmware->getCapability(HasVario)), - ui->frskyProtoCB->setDisabled(firmware->getCapability(NoTelemetryProtocol)); + ui->altimetryGB->setVisible(firmware->getCapability(HasVario)), + ui->frskyProtoCB->setDisabled(firmware->getCapability(NoTelemetryProtocol)); - if (firmware->getCapability(Telemetry)) { - ui->frskyProtoCB->addItem(tr("Winged Shadow How High")); - } - else { - ui->frskyProtoCB->addItem(tr("Winged Shadow How High (not supported)")); - } + if (firmware->getCapability(Telemetry)) { + ui->frskyProtoCB->addItem(tr("Winged Shadow How High")); + } + else { + ui->frskyProtoCB->addItem(tr("Winged Shadow How High (not supported)")); + } - ui->variousGB->hide(); + ui->variousGB->hide(); - lock = false; + lock = false; } void TelemetryPanel::populateVarioSource() @@ -972,6 +980,7 @@ void TelemetryPanel::on_clearAllSensors() model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_CLEAR, i); } + updateItemModels(); update(); emit modified(); } @@ -982,6 +991,7 @@ void TelemetryPanel::on_insertSensor(int selectedIndex) model->sensorData[selectedIndex].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, 1); + updateItemModels(); update(); emit modified(); } @@ -995,6 +1005,7 @@ void TelemetryPanel::on_deleteSensor(int selectedIndex) model->sensorData[CPN_MAX_SENSORS - 1].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, -1); + updateItemModels(); update(); emit modified(); } @@ -1018,7 +1029,20 @@ void TelemetryPanel::swapData(int idx1, int idx2) memcpy(sd2, sd1, sizeof(SensorData)); memcpy(sd1, &sdtmp, sizeof(SensorData)); model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_SWAP, idx1, idx2); + updateItemModels(); update(); emit modified(); } } + +void TelemetryPanel::on_dataModifiedSensor() +{ + updateItemModels(); + update(); + emit modified(); +} + +void TelemetryPanel::updateItemModels() +{ + commonItemModels->update(CommonItemModels::RMO_TELEMETRY_SENSORS); +} diff --git a/companion/src/modeledit/telemetry.h b/companion/src/modeledit/telemetry.h index cddade217..9719c7df6 100644 --- a/companion/src/modeledit/telemetry.h +++ b/companion/src/modeledit/telemetry.h @@ -27,7 +27,8 @@ constexpr char MIMETYPE_TELE_SENSOR[] = "application/x-companion-tele-sensor"; class AutoComboBox; -class RawSourceFilterItemModel; +class CommonItemModels; +class RawItemFilteredModel; class TimerEdit; namespace Ui { @@ -41,7 +42,7 @@ class TelemetryCustomScreen: public ModelPanel Q_OBJECT public: - TelemetryCustomScreen(QWidget *parent, ModelData & model, FrSkyScreenData & screen, GeneralSettings & generalSettings, Firmware * firmware, RawSourceFilterItemModel * srcModel); + TelemetryCustomScreen(QWidget *parent, ModelData & model, FrSkyScreenData & screen, GeneralSettings & generalSettings, Firmware * firmware, RawItemFilteredModel * rawSourceModel); ~TelemetryCustomScreen(); void update(); @@ -53,6 +54,8 @@ class TelemetryCustomScreen: public ModelPanel void barMinChanged(double value); void barMaxChanged(double value); void barTimeChanged(); + void onModelDataAboutToBeUpdated(); + void onModelDataUpdateComplete(); private: void updateBar(int line); @@ -122,7 +125,7 @@ class TelemetryPanel : public ModelPanel Q_OBJECT public: - TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware); + TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels); virtual ~TelemetryPanel(); virtual void update(); @@ -148,12 +151,15 @@ class TelemetryPanel : public ModelPanel void on_deleteSensor(int index); void on_moveUpSensor(int index); void on_moveDownSensor(int index); + void on_dataModifiedSensor(); private: Ui::Telemetry *ui; TelemetryCustomScreen * telemetryCustomScreens[4]; TelemetrySensorPanel * sensorPanels[CPN_MAX_SENSORS]; int sensorCapability; + CommonItemModels * commonItemModels; + RawItemFilteredModel * rawSourceFilteredModel; void setup(); void telBarUpdate(); @@ -161,6 +167,7 @@ class TelemetryPanel : public ModelPanel void populateCurrentSource(); void populateVarioSource(); void swapData(int idx1, int idx2); + void updateItemModels(); }; #endif // _TELEMETRY_H_ diff --git a/companion/src/modelprinter.cpp b/companion/src/modelprinter.cpp index 5e5d7a349..61bfedda9 100644 --- a/companion/src/modelprinter.cpp +++ b/companion/src/modelprinter.cpp @@ -24,6 +24,7 @@ #include "boards.h" #include "helpers_html.h" #include "appdata.h" +#include "adjustmentreference.h" #include #include @@ -396,7 +397,7 @@ QString ModelPrinter::printInputLine(const ExpoData & input) str += input.srcRaw.toString(&model, &generalSettings).toHtmlEscaped(); } - str += " " + tr("Weight").toHtmlEscaped() + QString("(%1)").arg(Helpers::getAdjustmentString(input.weight, &model, true).toHtmlEscaped()); + str += " " + tr("Weight(%1)").arg(AdjustmentReference(input.weight).toString(&model, true)).toHtmlEscaped(); if (input.curve.value) str += " " + input.curve.toString(&model).toHtmlEscaped(); @@ -405,19 +406,18 @@ QString ModelPrinter::printInputLine(const ExpoData & input) str += " " + flightModesStr.toHtmlEscaped(); if (input.swtch.type != SWITCH_TYPE_NONE) - str += " " + tr("Switch").toHtmlEscaped() + QString("(%1)").arg(input.swtch.toString(getCurrentBoard(), &generalSettings)).toHtmlEscaped(); + str += " " + tr("Switch(%1)").arg(input.swtch.toString(getCurrentBoard(), &generalSettings)).toHtmlEscaped(); if (firmware->getCapability(VirtualInputs)) { - if (input.carryTrim>0) - str += " " + tr("NoTrim").toHtmlEscaped(); - else if (input.carryTrim<0) - str += " " + RawSource(SOURCE_TYPE_TRIM, (-(input.carryTrim)-1)).toString(&model, &generalSettings).toHtmlEscaped(); + if (input.carryTrim > 0) + str += " " + tr("NoTrim"); + else if (input.carryTrim < 0) + str += " " + RawSource(SOURCE_TYPE_TRIM, (-(input.carryTrim) - 1)).toString(&model, &generalSettings).toHtmlEscaped(); } if (input.offset) - str += " " + tr("Offset(%1)").arg(Helpers::getAdjustmentString(input.offset, &model)).toHtmlEscaped(); - + str += " " + tr("Offset(%1)").arg(AdjustmentReference(input.offset).toString(&model)).toHtmlEscaped(); if (firmware->getCapability(HasExpoNames) && input.name[0]) str += QString(" [%1]").arg(input.name).toHtmlEscaped(); @@ -440,7 +440,7 @@ QString ModelPrinter::printMixerLine(const MixData & mix, bool showMultiplex, in } // highlight source if needed QString source = mix.srcRaw.toString(&model, &generalSettings).toHtmlEscaped(); - if ( (mix.srcRaw.type == SOURCE_TYPE_CH) && (mix.srcRaw.index+1 == (int)highlightedSource) ) { + if ( (mix.srcRaw.type == SOURCE_TYPE_CH) && (mix.srcRaw.index + 1 == (int)highlightedSource) ) { source = "" + source + ""; } str += " " + source; @@ -448,35 +448,35 @@ QString ModelPrinter::printMixerLine(const MixData & mix, bool showMultiplex, in if (mix.mltpx == MLTPX_MUL && !showMultiplex) str += " " + tr("MULT!").toHtmlEscaped(); else - str += " " + tr("Weight") + QString("(%1)").arg(Helpers::getAdjustmentString(mix.weight, &model, true)).toHtmlEscaped(); + str += " " + tr("Weight(%1)").arg(AdjustmentReference(mix.weight).toString(&model, true)).toHtmlEscaped(); QString flightModesStr = printFlightModes(mix.flightModes); if (!flightModesStr.isEmpty()) str += " " + flightModesStr.toHtmlEscaped(); if (mix.swtch.type != SWITCH_TYPE_NONE) - str += " " + tr("Switch") + QString("(%1)").arg(mix.swtch.toString(getCurrentBoard(), &generalSettings)).toHtmlEscaped(); + str += " " + tr("Switch(%1)").arg(mix.swtch.toString(getCurrentBoard(), &generalSettings)).toHtmlEscaped(); if (mix.carryTrim > 0) - str += " " + tr("NoTrim").toHtmlEscaped(); + str += " " + tr("NoTrim"); else if (mix.carryTrim < 0) str += " " + RawSource(SOURCE_TYPE_TRIM, (-(mix.carryTrim)-1)).toString(&model, &generalSettings); if (firmware->getCapability(HasNoExpo) && mix.noExpo) str += " " + tr("No DR/Expo").toHtmlEscaped(); if (mix.sOffset) - str += " " + tr("Offset") + QString("(%1)").arg(Helpers::getAdjustmentString(mix.sOffset, &model)).toHtmlEscaped(); + str += " " + tr("Offset(%1)").arg(AdjustmentReference(mix.sOffset).toString(&model)).toHtmlEscaped(); if (mix.curve.value) str += " " + mix.curve.toString(&model).toHtmlEscaped(); int scale = firmware->getCapability(SlowScale); if (scale == 0) scale = 1; if (mix.delayDown || mix.delayUp) - str += " " + tr("Delay") + QString("(u%1:d%2)").arg((double)mix.delayUp/scale).arg((double)mix.delayDown/scale).toHtmlEscaped(); + str += " " + tr("Delay(u%1:d%2)").arg((double)mix.delayUp / scale).arg((double)mix.delayDown / scale).toHtmlEscaped(); if (mix.speedDown || mix.speedUp) - str += " " + tr("Slow") + QString("(u%1:d%2)").arg((double)mix.speedUp/scale).arg((double)mix.speedDown/scale).toHtmlEscaped(); + str += " " + tr("Slow(u%1:d%2)").arg((double)mix.speedUp / scale).arg((double)mix.speedDown / scale).toHtmlEscaped(); if (mix.mixWarn) - str += " " + tr("Warn") + QString("(%1)").arg(mix.mixWarn).toHtmlEscaped(); + str += " " + tr("Warn(%1)").arg(mix.mixWarn).toHtmlEscaped(); if (firmware->getCapability(HasMixerNames) && mix.name[0]) str += QString(" [%1]").arg(mix.name).toHtmlEscaped(); return str; @@ -496,13 +496,13 @@ QString ModelPrinter::printFlightModes(unsigned int flightModes) { int numFlightModes = firmware->getCapability(FlightModes); if (numFlightModes && flightModes) { - if (flightModes == (unsigned int)(1<getCapability(FlightModes); if (numFlightModes && flightModes) { - if (flightModes == (unsigned int)(1<AppPreferencesDialog - - + + Edit Settings Editar ajustes - - + + Radio Profile Perfil de radio - - + + Default Channel Order Orden prederterminado canales - - + + Build Options Opciones del firmware - - + + Menu Language Lenguaje de los menús - - + + Default Stick Mode Modo prederterminado sticks - - + + Select Image Seleccionar imagen - - + + Mode selection: Mode 1: @@ -186,729 +186,736 @@ Modo 4: - - + + Mode 1 (RUD ELE THR AIL) Modo 1 (RUD ELE THR AIL) - - + + Mode 2 (RUD THR ELE AIL) Modo 2 (RUD THR ELE AIL) - - + + Mode 3 (AIL ELE THR RUD) Modo 3 (AIL ELE THR RUD) - - + + Mode 4 (AIL THR ELE RUD) Modo 4 (AIL THR ELE RUD) - - + + Splash Screen Pantalla de inicio - - - - + + + + The profile specific folder, if set, will override general Backup folder La carpeta específica del perfil, si está fijada, anulará la carpeta de copia de seguridad general - - + + Backup folder Carpeta de copia de seguridad - - + + If set it will override the application general setting Si está fijado anulará los ajustes generales de la aplicación> - - + + if set, will override general backup enable si está fijado anulará la copia de seguridad general> - - + + <html><head/><body><p>Channel order</p><p><br/></p><p>Defines the order of the default mixes created on a new model.</p></body></html> <html><head/><body><p>Orden de los canales</p><p><br/></p><p>Define el orden por defecto de las mezclas en un nuevo modelo</p></body></html> - - + + R E T A - - + + R E A T - - + + R T E A - - + + R T A E - - + + R A E T - - + + R A T E - - + + E R T A - - + + E R A T - - + + E T R A - - + + E T A R - - + + E A R T - - + + E A T R - - + + T R E A - - + + T R A E - - + + T E R A - - + + T E A R - - + + T A R E - - + + T A E R - - + + A R E T - - + + A R T E - - + + A E R T - - + + A E T R - - + + A T R E - - + + A T E R - - - - - - - - + + + + + + - - - - - + + + + + - + + + Select Folder Selecciona carpeta - - - + + + + Show splash screen + Mostrar pantalla de inicio + + + + + Select Executable Selecciona ejecutable - - - + + + Release channel Canal de distribución - - - + + + Releases (stable) Releases (estable) - - - + + + Release candidates (testing) Release candidates (testing) - - - + + + Nightly builds (unstable) Nightly builds (inestable) - - - + + + Simulator Volume Gain Ganancia de volumen del simulador - - - + + + Simulator controls Controles de simulador - - - + + + Save switch/pot positions on simulator exit Guardar las posiciones de interruptores/pots al salir del simulador - - - + + + Clear saved positions Limpiar las posiciones guardadas - - + + Profile Name Nombre de perfil - - + + Clear Image Limpiar imagen - - + + Append version number to FW file name Agregar el número de versión al nombre de archivo de firmware - - + + Offer to write FW to Tx after download Ofrecer grabar el firmware al Tx después de la descarga - - + + Radio Type Tipo de radio - - + + Other Settings Otros ajustes - - + + General Settings Ajustes generales - - + + SD Structure path Estructura de archivos SD - - + + Application Settings Ajustes de la aplicación - - - - Show splash screen when Companion starts - Mostrar pantalla de inicio cuando Companion comience - - - - - + + + Automatic check for Companion updates Comprobar automáticamente actualizaciones de Companion - - - - - + + + + + Enable automatic backup before writing firmware Activar copia de seguridad automática antes de escribir el firmware - - - + + + Automatic check for OpenTX firmware updates Comprobar automáticamente actualizaciones del firmware OpenTX - - - + + + Splash Screen Library Librería de pantallas de inicio - - - + + + Google Earth Executable Ejecutable Google Earth - - - + + + Only show user splash images Mostrar sólo pantallas de inicio de usuario - - - + + + Show user and companion splash images Mostrar pantallas de inicio de usuario y companion - - - + + + User Splash Screens Pantallas de inicio de usuario - - - + + + Automatic Backup Folder Carpeta copia de seguridad automática - - - + + + Simulator Settings Ajustes del simulador - - - + + + Simulator BackLight Luz de fondo del simulador - - - + + + Enable Activado - - - + + + most recently used files ficheros usados recientemente - - - + + + Startup Settings Ajustes de inicio - - - + + + Remember Recordar - - - + + + Output Logs Folder Carpeta de reportes - - - + + + <html><head/><body><p>This option maintains the behaviour from older OpenTx versions where empty model slots are preserved when a model is deleted or moved. </p><p>When this option is de-selected, the other models may be re-arranged to fill the gap left by the removed model.</p></body></html> <html><head/><body><p>Esta opción mantiene el comportamiento de las versiones anteriores de OpenTx donde se conservan los slots de modelos vacíos cuando se elimina o mueve un modelo. </p><p>Cuando esta opción no está seleccionada, los otros modelos pueden reordenarse para llenar el hueco dejado por el modelo borrado.</p></body></html> - - - + + + Remove empty model slots when deleting models (only applies for radios w/out categories) Eliminar los slots vacíos cuando se borran modelos (sólo aplica a radios sin categorías) - + Use model wizard Usar el asistente de modelos - + Open model editor Abrir el editor de modelos - + Just create the model Sólo crear el modelo - - - + + + Debug Output Logging Reporte de depuración - - - + + + <html><head/><body><p>Keep a log of all debugging messages generated by the desktop Companion/Simulator applications. An OpenTX developer may request this to help diagnose an issue.</p></body></html> <html><head/><body><p>Mantiene un reporte para todos los mensajes de depuración generados por las aplicaciones Companion/Simulador. Un desarrollador de OpenTX los puede requerir para ayudar a diagnosticar el problema.</p></body></html> - - - + + + Application (Companion/Simulator) Aplicación (Companion/simulador) - - - + + + <html><head/><body><p>Keep a log of all messages generated by the radio firmware when running in Simulator. This is the same information one would also see in the Simulator <span style=" font-style:italic;">Debug Output</span> window.</p></body></html> <html><head/><body><p>Mantiene un log para todos los mensajes generados por el firmware de la radio mientras se ejecuta en el simulador. Esta es la misma información que se vería en el simulador <span style=" font-style:italic;">Salida de depuración</span> ventana.</p></body></html> - - - + + + Radio Firmware (in Simulator) Radio firmware (en simulador) - - - + + + Action on New Model Accioń en nuevo modelo - - - + + + + Prompt for radio profile + Preguntar por perfil de radio + + + + + Blue Azul - - - + + + Green Verde - - - + + + Red Rojo - - - + + + Orange Naranja - - - + + + Yellow Amarillo - - - + + + Screenshot capture folder Carpeta de capturas de pantalla - - - + + + Joystick Joystick - - - + + + Calibrate Calibrar - - - + + + Only capture to clipboard Sólo capturar al portapapeles - + My Radio Mi radio - + <p><b>You cannot switch Radio Type or change Build Options while there are unsaved file changes. What do you wish to do?</b></p> <ul><li><i>Save All</i> - Save any open file(s) before saving Settings.<li><li><i>Reset</i> - Revert to the previous Radio Type and Build Options before saving Settings.</li><li><i>Cancel</i> - Return to the Settings editor dialog.</li></ul> <p><b>No puedes cambiar el tipo de radio o las opciones del firmware mientras hay cambios sin guardar ¿Qué quieres hacer?</b></p> <ul><li><i>Guardar todo</i> - Guardar los archivos abiertos andtes de guardar los ajustes.<li><li><i>Resetear</i> - Volver al tipo de radio y opciones de firmware anteriores antes de salvar los los ajustes.</li><li><i>Cancelar</i> - Volver a la ventana de edición de ajustes.</li></ul> - + Select your snapshot folder Selecciona la carpeta de capturas - + Note: Nightly builds are not available in this version, Release/RC update channel will be used. Nota: No hay nightly builds para esta versión, se usará el canal Release/RC. - - + + No joysticks found No se han encontrado joysticks - + EMPTY: No radio settings stored in profile VACÍO: No se han guardado ajustes en el perfil de tu radio - + AVAILABLE: Radio settings of unknown age DISPONIBLE:Ajustes de radio de antigüedad desconocida - + AVAILABLE: Radio settings stored %1 DISPONIBLE: Ajustes de radio guardados %1 - + Select your library folder Selecciona tu carpeta de librerías - - + + Select your Models and Settings backup folder Selecciona la carpeta de seguridad de tus modelos y ajustes - + Select a folder for application logs Selecciona una carpeta para los reportes de la aplicación - + Select Google Earth executable Selecciona el ejecutable de Google Earth - + Select the folder replicating your SD structure Selecciona la carpeta que replica la estructura de tu tarjeta SD - + Open Image to load Abre imagen para cargar - + Images (%1) Imágenes (%1) @@ -948,58 +955,58 @@ Modo 4: Boards - + Left Horizontal Izquierda horizontal - + Left Vertical Izquierda vertical - + Right Vertical Derecha vertical - + Right Horizontal Derecha horizontal - + Aux. 1 - + Aux. 2 - - + + Unknown Desconocido - + Rud - + Ele - + Thr - + Ail @@ -1046,112 +1053,132 @@ Modo 4: - Channels + ChannelsPanel - + Name Nombre - - Min - Mín - - - - Max - Máx - - - + Subtrim - + + Min + + + + + Max + + + + Direction Dirección - + Curve Curva - + PPM Center Centro PPM - + Linear Subtrim Subtrim lineal - + CH%1 - + Popup menu available Menú emergente disponible - + --- - + INV - + + Delete Channel. Are you sure? + Borrar canal ¿Estás seguro? + + + + Cut Channel. Are you sure? + Cortar canal ¿Estás seguro? + + + Copy Copiar - + Cut Cortar - + Paste Pegar - + Clear Limpiar - + Insert Insertar - + Delete Borrar - + Move Up Mover arriba - + Move Down Mover abajo - + Clear All Limpiar todo + + + Clear Channel. Are you sure? + Limpiar canal ¿Estás seguro? + + + + Clear all Channels. Are you sure? + Limpiar todos los canales ¿Estás seguro? + ChecklistDialog @@ -1592,7 +1619,7 @@ Si tienes un archivo de backup, puedes importar en su lugar. CurveData - + CV @@ -1767,81 +1794,119 @@ Si tienes un archivo de backup, puedes importar en su lugar. Curve name Nombre de la curva + + + CurvesPanel - + Curve %1 Curva %1 - + Popup menu available - Menú desplegable disponible + Menú emergente disponible - + %1 points %1 puntos - + Linear Lineal - + Single Expo Expo único - + Symmetrical f(x)=-f(-x) Simétricas f(x)=-f(-x) - + Symmetrical f(x)=f(-x) Simétricas f(x)=f(-x) - - Copy - Copiar - - - - Paste - Pegar - - - - Clear - Limpiar - - - - Clear all curves - Limpiar todas las curvas - - - - Are you sure you want to reset curve %1? - ¿Seguro que quieres resetear todas la curva %1? - - - - Are you sure you want to reset all curves? - ¿Seguro que quiere resetear todas las curvas? - - - + Editing curve %1 Edición de curva %1 - + Not enough free points in EEPROM to store the curve. No hay suficientes puntos libres en la EEPROM para guardar la curva. + + + Copy + Copiar + + + + Cut + Cortar + + + + Paste + Pegar + + + + Clear + Limpiar + + + + Insert + Insertar + + + + Delete + Borrar + + + + Move Up + Mover arriba + + + + Move Down + Mover abajo + + + + Clear All + Limpiar todo + + + + Clear Curve. Are you sure? + Limpiar curva ¿Estás seguro? + + + + Clear all Curves. Are you sure? + Limpiar todas las curvas ¿Estás seguro? + + + + Cut Curve. Are you sure? + Cortar curva ¿Estás seguro? + + + + Delete Curve. Are you sure? + Borrar curva ¿Estás seguro? + CustomFunctionData @@ -1862,8 +1927,8 @@ Si tienes un archivo de backup, puedes importar en su lugar. - Trainer - Entrenador + Trainer Sticks + Sticks entrenador @@ -2006,79 +2071,79 @@ Si tienes un archivo de backup, puedes importar en su lugar. Bind módulo externo - + Timer1 Temporizador 1 - + Timer2 Temporizador 2 - + Timer3 Temporizador 3 - + Flight Vuelo - + Telemetry Telemetría - + Rotary Encoder Codificador rotativo - + REa - + REb - + s - - - + + + <font color=red><b>Inconsistent parameter</b></font> <font color=red><b>Parámetro Inconsistente</b></font> - + Value Valor - + played once, not during startup reproducido una vez, no durante el inicio - + repeat(%1s) repetir(%1s) - + DISABLED DESABILITADO - + CFN @@ -2086,122 +2151,144 @@ Si tienes un archivo de backup, puedes importar en su lugar. CustomFunctionsPanel - + Switch Interruptor - + Action Acción - + Parameters Parámetros - + Enable Activar - + Popup menu available Menú deplegable disponible - + SF%1 - + GF%1 - + ON - + Error occurred while trying to play sound, possibly the file is already opened. (Err: %1 [%2]) Ha ocurrido un error al reproducir el sonido, posiblemente el archivo ya está abierto. (Err: %1 [%2]) - + Unable to find or open sound file: %1 No se puede encontrar o abrir el archivo de sonido: %1 - + + Delete Function. Are you sure? + Borrar función ¿Estás seguro? + + + + + Cut Special Function. Are you sure? + Cortar función especial ¿Estás seguro? + + + + Copy Copiar - + Cut Cortar - + Paste Pegar - + Clear Limpiar - + Insert Insertar - + Delete Borrar - + Move Up Mover arriba - + Move Down Mover abajo - + Clear All Limpiar todo - + Value Valor - + Source Fuente - + GVAR - + Increment Incremento + + + Clear Function. Are you sure? + Limpiar función ¿Estás seguro? + + + + Clear all Functions. Are you sure? + Limpiar todas funciones ¿Estás seguro? + CustomizeSplashDialog @@ -2400,48 +2487,48 @@ Si tienes un archivo de backup, puedes importar en su lugar. Error de conversión en el campo %1 - + Switch Interruptor - + Switch Interruptor - + cannot be exported on this board! no puede ser exportada en esta placa! - + Source Fuente - + Source %1 cannot be exported on this board! ¡La fuente %1 no puede ser exportada a esta placa! - + OpenTX only accepts %1 points in all curves OpenTX sólo acepta %1 puntos en todas las curvas - + OpenTx only accepts %1 points in all curves OpenTX sólo acepta %1 puntos en todas las curvas - - + + OpenTX on this board doesn't accept this function OpenTX en esta placa no acepta esa función - + OpenTX doesn't accept this radio protocol OpenTX no acepta este protocolo de radio @@ -2452,6 +2539,7 @@ Si tienes un archivo de backup, puedes importar en su lugar. + Debug Output Salida de depuración @@ -2459,6 +2547,7 @@ Si tienes un archivo de backup, puedes importar en su lugar. + <html><head/><body><p>Enable or disable the filter. If the button won't stay enabled, it is likely there is a syntax error in the Regular Expression entered.</p></body></html> <html><head/><body><p>Activa/desactiva el filtro. Si el botón no permanece activo, probablemente hay un error de sintaxis en la expresión introducida.</p></body></html> @@ -2466,6 +2555,7 @@ Si tienes un archivo de backup, puedes importar en su lugar. + Filter: Filtro: @@ -2473,6 +2563,7 @@ Si tienes un archivo de backup, puedes importar en su lugar. + <html><head/><body><p>Enter filter text here. Click the help/info button for details about using the filter. </p><p> To <b>remove a remembered entry</b> from the filter list, first choose it, and then press <code>Shift-Delete</code> (or <code>Shift-Backspace</code>) key combination.</p></body></html> <html><head/><body><p>Introduce fitro de texto aquí. Presiona el botón de ayuda/info para detalles acerca del uso del filtro. </p><p> @@ -2482,6 +2573,7 @@ Para <b>eliminar una entrada recordada</b> desde la lista de filtros + Buffer: Buffer: @@ -2489,6 +2581,7 @@ Para <b>eliminar una entrada recordada</b> desde la lista de filtros + Number of lines to keep in display. Número de líneas a mantener en display. @@ -2496,6 +2589,7 @@ Para <b>eliminar una entrada recordada</b> desde la lista de filtros + Filter &Help &Ayuda filtros @@ -2503,6 +2597,7 @@ Para <b>eliminar una entrada recordada</b> desde la lista de filtros + Show information about using the filter. Muestra información acerca del uso de filtros. @@ -2510,6 +2605,7 @@ Para <b>eliminar una entrada recordada</b> desde la lista de filtros + Word &Wrap Ajuste de &línea @@ -2517,6 +2613,7 @@ Para <b>eliminar una entrada recordada</b> desde la lista de filtros + Toggle word wrapping on/off. Habilita/desabilita ajuste de línea. @@ -2524,6 +2621,7 @@ Para <b>eliminar una entrada recordada</b> desde la lista de filtros + &Clear &Limpiar @@ -2531,6 +2629,7 @@ Para <b>eliminar una entrada recordada</b> desde la lista de filtros + Clear the output window of all text. Limpia de texto la ventana de salida. @@ -2538,6 +2637,7 @@ Para <b>eliminar una entrada recordada</b> desde la lista de filtros + Enable &Filter Habilitar &filtro @@ -2545,6 +2645,7 @@ Para <b>eliminar una entrada recordada</b> desde la lista de filtros + Turn the filter on/off. Apaga/enciende el filtro. @@ -2598,69 +2699,54 @@ Para <b>eliminar una entrada recordada</b> desde la lista de filtros - - Eeprom is not from Th9X - - Eeprom no es de Th9X - - - - - Eeprom is not from Gruvin9X - - Eeprom no es de Gruvin9X - - - - Eeprom is not from ErSky9X - Eeprom no es de ErSky9X - - - Eeprom is not from Er9X - - Eeprom no es de Er9X - - - + - Eeprom size is invalid - Tamaño de eeprom no es válido - + - Eeprom file system is invalid - Sistema de archivos de eeprom no es válido - + - Eeprom is from a unknown board - Eeprom es de una placa desconocida - + - Eeprom is from the wrong board - Eeprom es de una placa errónea - + - Eeprom backup not supported - Backup de Eeprom no soportado - + - Something that couldn't be guessed, sorry - Algo que no pudo ser adivinado, lo siento - + Warning: Advertencia: - - + + - Your radio probably uses a wrong firmware, eeprom size is 4096 but only the first 2048 are used Tu radio probablemente usa un firmware erróneo, el tamaño de la eeprom es de 4096 pero sólo los primeros 2048 son usados - + - Your eeprom is from an old version of OpenTX, upgrading! To keep your original file as a backup, please choose File -> Save As specifying a different name. Tu eeprom es de una vesión anterior de OpenTX, actualizando! @@ -2864,27 +2950,27 @@ Si está en blanco entonces las entradas son consideradas ON todo el tiempo.TODO - + Edit %1 Editar %1 - + Popup menu available Disponible menú desplegable - + Clear All Limpiar todo - + Set All Fijar todo - + Invert All Invertir todo @@ -3253,277 +3339,275 @@ Vacío significa incluir todos. Comodines ?, *, y [...] aceptados. Firmware - + Channel values displayed in us Visualiza los valores de canal en us - + No OverrideCH functions available Sin funciones OverrideCH - + Possibility to enable FAI MODE (no telemetry) at field Posibilidad de habilitar el MODO FAI (sin telemetría) - + FAI MODE (no telemetry) always enabled MODO FAI (sin telemetría) siempre activado - + Removes D8 FrSky protocol support which is not legal for use in the EU on radios sold after Jan 1st, 2015 Elimina el soporte para el protocolo D8 FrSky el cual no es de uso legal en EU en radios vendidas después del 1 de enero de 2015 - - + + + Disable HELI menu and cyclic mix support Desactiva el menú de HELI y el soporte de mezcla de cíclico - - + + + Disable Global variables Desactiva las variables globales - - + + + Enable Lua custom scripts screen Habilita la pantalla de Lua custom scripts - + Use alternative SQT5 font Usa la fuente alternativa SQT5 - + Pots use in menus navigation Usa potenciómetros en los menús de navegación - + FrSky Taranis X9D+ - - Support for PPM internal module hack - Soporte para el hack de PPM del módulo interno - - - + Enable non certified firmwares Habilita firmware no certificado - - + + Enable AFHDS3 support + Habilitar soporte AFHDS3 + + + + Disable RAS (SWR) Desactiva RAS (SWR) - + FrSky Taranis X9D+ 2019 - + FrSky Taranis X9D - + Haptic module installed Módulo haptic instalado - + FrSky Taranis X9E - + Confirmation before radio shutdown Confirmar antes de apagar la radio - + Horus gimbals installed (Hall sensors) Gimbals Horus instalados (sensores Hall) - + FrSky Taranis X9-Lite - + FrSky Taranis X7 / X7S - + FrSky Taranis X-Lite S/PRO - + FrSky Taranis X-Lite - + FrSky Horus X10 / X10S - + + + + + + Support hardware mod: R9M ACCESS + Soporte mod hardware: R9M ACCESS + + + FrSky Horus X10 Express / X10S Express - + FrSky Horus X12S - + Use ONLY with first DEV pcb version Usar SÓLO con la primera versión DEV pcb - + Jumper T12 / T12 Pro - - + + Support for MULTI internal module Soporte para módulo interno MULTI - + Jumper T16 / T16+ / T16 Pro - - + + + Support for bluetooth module Soporte para módulo bluetooth - - Radiomaster TX16s / TX16s Hall / TX16s Masterfire + + Radiomaster TX12 - + + Radiomaster TX16S / SE / Hall / Masterfire + + + + + Support internal GPS + Soporte GPS interno + + + + Jumper T18 + + + + Turnigy 9XR-PRO - + Enable HELI menu and cyclic mix support Activar menú HELI y el soporte de mezcla de cíclico - + Global variables Variables globales - + In model setup menus automatically set source by moving the control En el menú de ajuste de modelo se selecciona automáticamente el origen del control moviéndolo - + In model setup menus automatically set switch by moving the control En el menú de ajuste de modelo se selecciona automáticamente el interruptor de control moviéndolo - + No graphical check boxes and sliders Sin casillas de verificación ni sliders gráficos - + Battery graph Gráfico batería - + Don't use bold font for highlighting active items No usar la fuente negrita para destacar elementos activos - + FrSky Taranis X9-Lite S - + FrSky Taranis X7 / X7S Access FrSky Taranis X7 / X7S Access - - + + Support for ACCESS internal module replacement Soporte para módulo interno ACCESS de reemplazo - - Turnigy 9XR with m128 chip - Turnigy 9XR con chip m128 - - - - Turnigy 9XR - - - - - 9X with stock board - 9X con placa de stock - - - + Enable resetting values by pressing up and down at the same time Activar el reseteo de valores presionando arriva y abajo al mismo tiempo - - 9X with stock board and m128 chip - 9X con placa de stock y chip m128 - - - + 9X with AR9X board 9X con placa AR9X - + 9X with Sky9x board 9X con placa Sky9x - - - 9X with Gruvin9x board - 9X con placa Gruvin9x - - - - DIY MEGA2560 radio - - FirmwarePreferencesDialog @@ -3848,62 +3932,62 @@ Vacío significa incluir todos. Comodines ?, *, y [...] aceptados. Escribir al TX - + Open Firmware File Abrir archivo de firmware - + %1 may not be a valid firmware file %1 puede no ser un archivo de firmware válido - + The firmware file is not valid. El archivo de firmware no es válido. - + There is no start screen image in the firmware file. No hay imagen de pantalla de inicio en el archivo de firmware. - + Profile image %1 is invalid. El perfil de imagen %1 no es válido. - + Open image file to use as radio start screen Abrir archivo de imagen para usar de pantalla de inicio de la radio - + Images (%1) Imágenes (%1) - + Image could not be loaded from %1 La imagen no puede ser cargada desde %1 - + The library image could not be loaded La librería de imágen no puede ser cargada - + Splash image not found Imagen de inicio no encontrada - + Cannot save customized firmware No se puede guardar el firmware personalizado - + Write Firmware to Radio Escribir firmware a la radio @@ -3924,27 +4008,27 @@ Vacío significa incluir todos. Comodines ?, *, y [...] aceptados. ¡El nuevo firmware no es compatible con el instalado actualmente! - + Conversion failed Coversión fallida - + Cannot convert Models and Settings for use with this firmware, original data will be used No se puede convertir los modelos y ajustes para usar con este firmware, se usarán los datos originales - + Restore failed Restauración fallida - + Could not restore Models and Settings to Radio. The models and settings data file can be found at: %1 No se ha podido restaurar los modelos y ajustes a la radio. Los datos de los modelos y ajustes se pueden encontrar en: %1 - + Flashing done Flashing hecho @@ -3957,42 +4041,42 @@ Vacío significa incluir todos. Comodines ?, *, y [...] aceptados. Ejecutable %1 no encontrado - + Writing... Escribiendo... - + Reading... Leyendo... - + Verifying... Verificando... - + unknown desconocido - + ie: OpenTX for 9X board or OpenTX for 9XR board Esto es: OpenTX para placas 9x o OpenTX para placas 9XR - + ie: OpenTX for M128 / 9X board or OpenTX for 9XR board with M128 chip Esto es: OpenTX para placas M128 / 9x o OpenTX para placas 9XR con el chip M128 - + ie: OpenTX for Gruvin9X board Esto es: OpenTX para placas Gruvin9x - + Your radio uses a %1 CPU!!! Please check advanced burn options to set the correct cpu type. @@ -4001,7 +4085,7 @@ Please check advanced burn options to set the correct cpu type. Por favor comprueba en las opciones avanzadas de grabado el tipo correcto de cpu. - + Your radio uses a %1 CPU!!! Please select an appropriate firmware type to program it. @@ -4010,7 +4094,7 @@ Please select an appropriate firmware type to program it. Por favor elige el tipo de firmware apropiado para programarlo. - + You are currently using: %1 @@ -4019,22 +4103,22 @@ Actualmente estás usando: %1 - + Your radio does not seem connected to USB or the driver is not initialized!!!. ¡¡¡La radio no parece estar conectada al USB o el controlador no está inicializado!!! - + Flashing done (exit code = %1) Flashing hecho (código salida = %1) - + Flashing done with errors Flashing hecho con errores - + FUSES: Low=%1 High=%2 Ext=%3 FUSIBLES: Low=%1 High=%2 Ext=%3 @@ -4087,7 +4171,7 @@ Actualmente estás usando: FlightModeData - + FM @@ -4095,37 +4179,38 @@ Actualmente estás usando: FlightModePanel - + Rotary Encoder %1 Codificador rotativo %1 - + Name Nombre - + Value source Valor fuente - + Value Valor - + GVAR%1 - + Popup enabled Menú desplegable activado - + + Popup menu available Menú desplegable disponible @@ -4150,67 +4235,174 @@ Actualmente estás usando: Usar trim para modo de vuelo %1 + trim propio con compensador - + Unit Unidad - + Prec - + Min Mín - + Max Máx - + 0._ - + 0.0 - - - &Clear - &Limpiar + + Warning: Global variable links back to itself. Flight Mode 0 value used. + Atención: Variable global linkada a si misma. Usado valor del modo de vuelo 0 - - + + Warning: Rotary encoder links back to itself. Flight Mode 0 value used. + Atención: Rotary encoder linkado a si mismo. Usado valor del modo de vuelo 0 + + + + + Copy + Copiar + + + + + Cut + Cortar + + + + + Paste + Pegar + + + + + Insert + Insertar + + + + + Delete + Borrar + + + + + Move Up + Mover arriba + + + + + Move Down + Mover abajo + + + + + Clear All + Limpiar todo + + + + Clear Flight Mode. Are you sure? + Limpiar modo de vuelo ¿Estás seguro? + + + + Clear all Flight Modes. Are you sure? + Limpiar todos los modos de vuelo ¿Estás seguro? + + + + Cut Flight Mode. Are you sure? + Cortar modo de vuelo ¿Estás seguro? + + + + Delete Flight Mode. Are you sure? + Borrar modo de vuelo ¿Estás seguro? + + + + Clear Global Variable across all Flight Modes. Are you sure? + Limpiar variable global para todos los modos de vuelo ¿Estás seguro? + + + + Clear Global Variable. Are you sure? + Limpiar variable global ¿Estás seguro? + + + + Clear all Global Variables for all Flight Modes. Are you sure? + Limpiar todas las variables globales para todos los modos de vuelo ¿Estás seguro? + + + + Clear all Global Variables for this Flight Mode. Are you sure? + Limpiar todas las variables globales para este modo de vuelo ¿Estás seguro? + + + + Cut Global Variable across all Flight Modes. Are you sure? + Cortar variable global para todos los modos de vuelo ¿Estás seguro? + + + + Cut Global Variable. Are you sure? + Cortar variable global ¿Estás seguro? + + + + Delete Global Variable. Are you sure? + Borrar variable global ¿Estás seguro? + + + + Paste to selected Global Variable across all Flight Modes. Are you sure? + Pegar a la variable global en todos los modos de vuelo ¿Estás seguro? + + + + Clear Limpiar - - - Clear all current Flight Mode properties? - ¿Limpiar todas las propiedades del modo de vuelo actual? - FlightModesPanel - + Flight Mode %1 Modo de vuelo %1 - + (%1) - + (default) (predeterminado) @@ -4269,15 +4461,11 @@ Actualmente estás usando: FusesDialog - - Fuses Fusibles - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } @@ -4307,15 +4495,11 @@ p, li { white-space: pre-wrap; } - - Read Fuses Leer fusibles - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } @@ -4349,8 +4533,6 @@ p, li { white-space: pre-wrap; } - - Reset Fuses EEPROM - PROTECT Resetear fusibles @@ -4358,8 +4540,6 @@ EEPROM - PROTEGIDA - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } @@ -4393,8 +4573,6 @@ p, li { white-space: pre-wrap; } - - Reset Fuses EEPROM - DELETE Resetear fusibles @@ -4402,8 +4580,6 @@ EEPROM - BORRAR - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } @@ -4494,12 +4670,12 @@ These will be relevant for all models in the same EEPROM. Estos puede ser relevantes para todos los modelos en el mismo EEPROM. - + Setup Configuración - + Trainer Entrenador @@ -4518,42 +4694,42 @@ Estos puede ser relevantes para todos los modelos en el mismo EEPROM.Recuperar calib. y ajustes hw de un perfil - + Global Functions Funciones globales - + Hardware Hardware - + Calibration Calibración - + Wrong data in profile, radio calibration was not retrieved Datos incorrectos en el perfil, la cablibración de la radio no se ha recuperado - + Wrong data in profile, Switch/pot config not retrieved Datos erróneos en el perfil, configuración de interruptor/pot no se ha recuperado - + Wrong data in profile, hw related parameters were not retrieved Datos incorrectos en el perfil, los parámetros de hw no se han recuperado - + Do you want to store calibration in %1 profile<br>overwriting existing calibration? ¿Quieres guardar la calibración en el perfil %1<br>¿Sobreescribir la calibración existente? - + Calibration and HW parameters saved. Calibración y parámetros de HW guardados. @@ -4561,7 +4737,7 @@ Estos puede ser relevantes para todos los modelos en el mismo EEPROM. GeneralSettings - + Radio Settings Ajustes de radio @@ -4570,300 +4746,300 @@ Estos puede ser relevantes para todos los modelos en el mismo EEPROM.GeneralSetup - - + + Form Form - - + + Readonly Unlock Desactivar sólo lectura - - + + SC - - + + SE - - + + SA - - + + SF - - + + SH - - + + SD - - + + SB - - + + SG - - - + + + Timeshift from UTC Zona horaria UTC - - - + + + Voice Language Lenguaje de las voces - - - + + + Country Code Código país - - - + + + Stick reverse Invertir stick - - - + + + FAI Mode Modo FAI - - - + + + Adjust RTC Ajustar RTC - - - + + + Vario pitch at max Tono de vario al máx - - - - - - + + + + + + Hz - - - + + + Speaker Volume Volumen altavoz - - - + + + Backlight Switch Interruptor de luz de fondo - - - + + + Sound Mode Modo sonido - - - + + + Color 1 - - - + + + Color 2 - - - + + + Speaker Pitch (spkr only) Tono altavoz(sólo alt) - - - + + + If this value is not 0, any keypress will turn on the backlight and turn it off after the specified number of seconds. Si este valor no es 0, cualquier pulsación encenderá la pantalla y se apagará despues de un número determinado de segundos. - - - - - - - - - + + + + + + + + + sec seg - - - + + + Backlight color Color de pantalla - - - + + + Beeper Beeper - - - + + + Speaker Altavoz - - - + + + BeeperVoice VozBeeper - - - + + + SpeakerVoice VozAltavoz - - - + + + Beep volume Volumen beep - - - + + + Wav volume Volumen wav - - - + + + Vario volume Volumen vario - - - + + + Background volume Volumen de fondo - - - - - - + + + + + + ms - - - + + + Backlight Auto OFF after Auto apagado de pantalla después de - - - + + + Backlight flash on alarm Pantalla parpadea con alarma - - - + + + Vario pitch at zero Tono de vario en cero - - - + + + Vario repeat at zero Vario repite en cero - - - + + + This is the switch selectrion for turning on the backlight (if installed). @@ -4872,12 +5048,12 @@ Estos puede ser relevantes para todos los modelos en el mismo EEPROM. - - - - - - + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } @@ -4892,58 +5068,58 @@ p, li { white-space: pre-wrap; } <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Los valores pueden ser 20-45</span></p></body></html> - - - + + + Backlight Brightness Brillo pantalla - - - + + + RotEnc Navigation Navegación RotEnc - - - + + + Automatically adjust the radio's clock if a GPS is connected to telemetry. Ajusta automáticamente el reloj de la radio si se conecta un GPS a la telemetría. - - - + + + America América - - - + + + Japan Japón - - - + + + Europe Europa - - - + + + Backlight OFF Brightness Brillo luz de fondo OFF - - - + + + Mode selection: Mode 1: @@ -4984,486 +5160,493 @@ Modo 4: - - - + + + Mode 1 (RUD ELE THR AIL) Modo 1 (RUD ELE THR AIL) - - - + + + Mode 2 (RUD THR ELE AIL) Modo 2 (RUD THR ELE AIL) - - - + + + Mode 3 (AIL ELE THR RUD) Modo 3 (AIL ELE THR RUD) - - - + + + Mode 4 (AIL THR ELE RUD) Modo 4 (AIL THR ELE RUD) - - - + + + <html><head/><body><p>Channel order</p><p><br/></p><p>Defines the order of the default mixes created on a new model.</p></body></html> <html><head/><body><p>Orden de los canales</p><p><br/></p><p>Define el orden por defecto de las mezclas en un nuevo modelo</p></body></html> - - - + + + If you enable FAI, only RSSI and RxBt sensors will keep working. This function cannot be disabled by the radio. Si activas FAI, sólo los sensores RSSI y RxBt seguirán funcionando. Esta función no puede ser deshabilitada en la radio. - - - + + + RSSI Poweroff Warning Aviso RSSI al apagado - - - + + + Low EEPROM Warning Advertencia de poca EEPROM - - - + + + Owner Registration ID ID de propietario - - - + + + + Keys Backlight + Teclas luz de fondo + + + + + R E T A - - - + + + R E A T - - - + + + R T E A - - - + + + R T A E - - - + + + R A E T - - - + + + R A T E - - - + + + E R T A - - - + + + E R A T - - - + + + E T R A - - - + + + E T A R - - - + + + E A R T - - - + + + E A T R - - - + + + T R E A - - - + + + T R A E - - - + + + T E R A - - - + + + T E A R - - - + + + T A R E - - - + + + T A E R - - - + + + A R E T - - - + + + A R T E - - - + + + A E R T - - - + + + A E T R - - - + + + A T R E - - - + + + A T E R - - - + + + Power On Delay Retraso de encendido - - - + + + Jack Mode Modo jack - - - + + + Audio - - - + + + Trainer Entrenador - - - + + + DMS - - - + + + USB Mode Modo USB - - - + + + Power Off Delay Retraso de apagado - - - - - - + + + + + + Ask on Connect Preguntar al conectar - - - + + + Joystick (HID) Joystick (HID) - - - + + + USB Mass Storage Almacenamiento USB - - - + + + USB Serial (CDC) USB Serial (CDC) - - - + + + Stick Mode Modo sticks - - - + + + Metric Métrico - - - + + + Imperial Imperial - - - + + + Default Channel Order Orden prederterminado canales - - - + + + GPS Coordinates Coordenadas GPS - - - + + + Min Mín - - - - - - + + + + + + v - - - + + + Max Máx - - - + + + Inactivity Timer Tiempo de inactividad - - - + + + Show Splash Screen on Startup Mostrar pantalla de inicio al encender - - - + + + Contrast Contraste - - - + + + Battery Meter Range Medidor de rango de batería - - - + + + Haptic Strength Fuerza de haptic - - - + + + LCD Display Type Tipo de pantalla LCD - - - + + + "No Sound" Warning Aviso "sin sonido" - - - + + + Battery Warning Aviso de batería - - - + + + Haptic Length Duración haptic - - - + + + MAVLink Baud Rate Velocidad de transmisión MAVLink - - - - - - + + + + + + Quiet Silencio - - - + + + Only Alarms Sólo alarmas - - - - - - + + + + + + No Keys No teclas - - - - - - + + + + + + All Todo - - - + + + Battery warning voltage. This is the threashhold where the battery warning sounds. @@ -5474,172 +5657,172 @@ Este es el umbral cuando la batería emite sonidos de aviso. Los valores aceptables son 5v..10v - - - + + + Standard Estándar - - - + + + Optrex - - - + + + If not zero will sound beeps if the transmitter has been left without inputs for the specified number of minutes. Si no es cero emitirá sonidos si el transmisor se deja sin pulsaciones durante el número específico de minutos. - - - + + + nnnnnnNN - - - + + + min - - - - - - + + + + + + Show splash screen on startup Mostrar pantalla de inicio al encender - - - + + + --- - - - + + + 2s - - - + + + 3s - - - + + + 4s - - - + + + 6s - - - + + + 8s - - - + + + 10s - - - + + + 15s - - - + + + 4800 Baud - - - + + + 9600 Baud - - - + + + 14400 Baud - - - + + + 19200 Baud - - - + + + 38400 Baud - - - + + + 57600 Baud - - - + + + 76800 Baud - - - + + + 115200 Baud - - - - - - - - - + + + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } @@ -5664,101 +5847,101 @@ p, li { white-space: pre-wrap; } <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Aviso de silencio - te alertará si el beeper está en modo silencio (0)</p></body></html> - - - - - - + + + + + + X-Short X-Corto - - - - - - + + + + + + Short Corto - - - - - - + + + + + + Normal - - - - - - + + + + + + Long Largo - - - - - - + + + + + + X-Long X-Largo - - - + + + NMEA - - - + + + Play Delay (switch mid position) Retardo de reproducción (interruptor en posición media) - - - + + + Measurement Units Unidades de medida - - - + + + Haptic Mode Modo haptic - - - + + + Beeper Length Duración del beeper - - - + + + Beeper Mode Modo beeper - - - + + + Beeper volume 0 - Quiet. No beeps at all. @@ -5769,15 +5952,15 @@ p, li { white-space: pre-wrap; } Volumen beeper 0 - Silencio. Ningun tipo de beep. -1 - No teclas. Los beeps suenan normal pero las teclas de menu no sonarán. +1 - No teclas. Los beeps suenan normal pero las teclas de menú no sonarán. 2 - Normal. 3 - Alto. 4 - Extra Alto. - - - + + + Alarms Only Sólo alarmas @@ -5785,127 +5968,127 @@ p, li { white-space: pre-wrap; } GeneralSetupPanel - + OFF - + Keys Teclas - + Sticks Sticks - + Keys + Sticks Teclas + Sticks - + ON - + English Inglés - + Dutch Holandés - + French Francés - + Italian Italiano - + German Alemán - + Czech Checo - + Slovak Eslovaco - + Spanish Español - + Polish Polaco - + Portuguese Portugués - + Russian Ruso - + Swedish Sueco - + Hungarian Húngaro - + No - + RotEnc A - + Rot Enc B - + Rot Enc C - + Rot Enc D - + Rot Enc E - + If you enable FAI, only RSSI and RxBt sensors will keep working. This function cannot be disabled by the radio. Are you sure ? @@ -5936,357 +6119,363 @@ Esta función no puede ser deshabilitada en la radio. Hardware - + Form Form - - + + SQ - - + + SR - - + + LS2 - - + + SP - - + + SO - - + + S4 - - + + RS - - + + SB - - + + PPM 2 - - + + OFF - - + + S-Port Mirror - S-Port + - - + + Telemetry Telemetría - - + + SBUS Trainer Entrenador SBUS - - + + Debug Depuración - - + + RTC Batt Check Check Batería RTC - - + + + S.Port Power + + + + + Rud - - + + PPM 3 - - + + S1 - - + + S2 - - + + S3 - - + + PPM 1 - - + + Serial Port Puerto Serie - - + + v - - + + PPM Multiplier Multiplicador PPM - - + + Current Offset Offset actual - - + + PPM 4 - - + + SA - - + + Ele - - + + Antenna Antena - - + + S5 - - + + Ail - - + + Thr - - + + SC - - + + LS - - + + SD - - + + Battery Offset Offset batería - - + + SE - - + + SF - - + + SG - - + + SH - - + + SI - - + + SJ - - + + SK - - + + SL - - + + SM - - + + SN - - + + RS2 - - + + Bluetooth Bluetooth - - + + ADC Filter Filtro ADC - - + + Device Name: Nombre dispositivo: @@ -6296,8 +6485,8 @@ Esta función no puede ser deshabilitada en la radio. HardwarePanel - - + + None Ninguno @@ -6317,67 +6506,67 @@ Esta función no puede ser deshabilitada en la radio. 3 posiciones - + Pot with detent Pos con fijador - + Multipos switch Interruptor multipos - + Pot without detent Pot sin fijador - + Slider with detent Slider con fijador - + OFF - + Enabled Activado - + Telemetry Telemetría - + Trainer Entrenador - + Internal Interno - + Ask Preguntar - + Per model Por modelo - + Internal + External Interno + Externo - + External Externo @@ -6531,139 +6720,177 @@ Esta función no puede ser deshabilitada en la radio. InputsPanel - - + + + Move Up Mover arriba - - + + Ctrl+Up Ctrl+Arriba - - + + + Move Down Mover abajo - - + + Ctrl+Down Ctrl+Abajo - + Clear All Inputs Limpiar todas las entradas - - Not enough available inputs! - ¡No hay disponibles suficientes entradas! + + Not enough available Inputs! + ¡No hay suficientes entradas! - - Delete Selected Inputs? - ¿Borrar las entradas seleccionadas? + + Delete selected Input lines. Are you sure? + Borrar las líneas de entrada seleccionadas ¿Estás seguro? - + + Cut selected Input lines. Are you sure? + Cortar las líneas de entrada seleccionadas ¿Estás seguro? + + + + Lines + Líneas + + + &Add &Añadir - + Ctrl+A - + &Edit &Editar - + Enter Intro - + &Delete &Borrar - + + Delete Borrar - + &Copy &Copiar - + Ctrl+C - + &Cut C&ortar - + Ctrl+X - + &Paste &Pegar - + Ctrl+V - + Du&plicate &Duplicar - + Ctrl+U - - Clear Inputs? - ¿Limpiar entradas? + + Input + Entrada - - Really clear all the inputs? - ¿Seguro que quieres limpiar todas las entradas? + + Insert + Insertar + + + + Clear + Limpiar + + + + Clear All + Limpiar todo + + + + Clear all Input lines. Are you sure? + Limpiar todas las líneas de entrada ¿Estás seguro? + + + + Clear all lines for the selected Inputs. Are you sure? + Limpiar todas las líneas para las entradas seleccionadas¿Estás seguro? + + + + Delete all lines for the selected Inputs. Are you sure? + Borrar todas las líneas para las entradas seleccionadas ¿Estás seguro? LimitData - + INV - + NOR - + CH @@ -6671,7 +6898,7 @@ Esta función no puede ser deshabilitada en la radio. LimitsGroup - + GV @@ -6802,69 +7029,114 @@ Esta función no puede ser deshabilitada en la radio. LogicalSwitchesPanel - + V1 - + V2 - + Duration Duración - + Delay Retardo - + Function Función - + AND Switch Interruptor AND - + Popup menu available Menú emergente disponible - + (instant) (instante) - + (infinite) (infinito) - - &Delete - &Borrar + + Delete Logical Switch. Are you sure? + Borrar interruptor lógico ¿Estás seguro? - - &Copy - &Copiar + + Cut Logical Switch. Are you sure? + Cortar interruptor lógico ¿Estás seguro? - - &Cut - C&ortar + + Copy + Copiar - - &Paste - &Pegar + + Cut + Cortar + + + + Paste + Pegar + + + + Clear + Limpiar + + + + Insert + Insertar + + + + Delete + Borrar + + + + Move Up + Mover arriba + + + + Move Down + Mover abajo + + + + Clear All + Limpiar todo + + + + Clear Logical Switch. Are you sure? + Limpiar interruptor lógico ¿Estás seguro? + + + + Clear all Logical Switches. Are you sure? + Limpiar todos los interruptores lógicos ¿Estás seguro? @@ -7063,24 +7335,24 @@ Las columnas para altitud "GAlt" y para velocidad "GSpd" son MainWindow - + File loaded Archivo cargado - - + + Save As Guardar como - - + + No updates available at this time. No hay actualizaciones disponibles ahora. - + Checking for updates Comprobando actualizaciones @@ -7096,184 +7368,174 @@ Las columnas para altitud "GAlt" y para velocidad "GSpd" son ¿Quieres ejecutar el instalador? - - + + File saved Archivo guardado - + Read Models and Settings From Radio Leer los modelos y ajustes de la radio - + Save Radio Backup to File Guardar copia de seguridad de la radio a un archivo - + Read Radio Firmware to File Leer el firmware de la radio a un archivo - + OpenTX Home Page: <a href='%1'>%1</a> OpenTX Home Page: <a href='%1'>%1</a> - + If you've found this program useful, please support by <a href='%1'>donating</a> Si has encontrado este programa útl, por favor ayuda con una <a href='%1'>donación</a> - + New release available Nueva versión disponible - + Error opening file %1: %2. Error abriendo el archivo %1: %2. - + Compilation server too busy, try later Servidor de compilación demasiado ocupado, inténtalo más tarde - + Unknown server failure, try later Fallo desconocido de servidor, inténtalo más tarde - - + + Yes - - + + No - - + + Release Notes Notas de la versión - - + + Open Models and Settings file Abre archivo de modelos y ajustes - + New Nuevo - + Open... Abrir... - + Save Guardar - + Save As... Guardar como... - + Compare models Comparar modelos - + Exit the application Sale de la aplicación - - List available programmers - Lista de programadores disponibles - - - - Show fuses dialog - Muestra ventane de fusibles - - - + Show the application's About box Muestra la ventana de aplicación Acerca de - + Set Menu Language Lenguaje - + Write Escribir - + %2 - + Alt+%1 - + New Radio Nueva radio - + A new version of Companion is available (version %1)<br>Would you like to download it? Una nueva versión de Companion está disponible (versión %1),<br>¿Te gustaría descargarla? - + Do you want to write the firmware to the radio now ? ¿Te gustaría escribir el firmware en la radio ahora? - + The new theme will be loaded the next time you start Companion. El nuevo tema será cargado la próxima vez que inicies Companion. - + About Companion Acerca de Companion - + A monochrome black icon theme Tema de icono monocromo negro - + A monochrome white icon theme Tema de icono monocromo blanco - + A monochrome blue icon theme Tema de icono monocromo azul @@ -7288,12 +7550,12 @@ Las columnas para altitud "GAlt" y para velocidad "GSpd" son ¿Quieres abrir la imagen del disco para instalar la nueva versioń? - + A new release of Companion is available, please check the <a href='%1'>OpenTX website!</a> Una nueva versión de Companion está disponible, por favor visita <a href='%1'>OpenTX website!</a> - + There are unsaved file changes which you may lose when switching radio types. Do you wish to continue? @@ -7302,387 +7564,387 @@ Do you wish to continue? ¿Quieres continuar? - + No local SD structure path configured! ¡No configurada la ruta a la estructura SD local! - + No Radio or SD card detected! ¡No radio o tarjeta SD detectada! - + Close Cerrar - + Close Models and Settings file Cierra el archivo de modelos y ajustes - + List of recently used files Lista de los archivos recientes - + Radio Profiles Perfiles de radio - + Create or Select Radio Profiles Crea o selecciona perfiles de radio - + Release notes... Notas de la versión... - + Show release notes Muestra notas de la versión - + Create a new Radio Settings Profile Crea un nuevo perfil de ajustes de radio - + Copy Current Radio Profile Copiar el perfil de radio actual - + Duplicate current Radio Settings Profile Duplica el perfil de radio actual - + Delete Current Radio Profile... Borrar el perfil de radio actual... - + Delete the current Radio Settings Profile Borra los ajustes actuales del perfil de radio actual - + Export Application Settings.. Exportar ajustes aplicación... - + Save all the current %1 and Simulator settings (including radio profiles) to a file. Guarda los ajustes actuales de %1 y del simulador (incluyendo perfiles de radio) a un archivo - + Import Application Settings.. Importar ajustes de la aplicación... - + Load %1 and Simulator settings from a prevously exported settings file. Carga los ajustes de %1 y del simulador desde un fichero de ajustes exportado previamente - + Use tabs to arrange open windows. Usa las pestañas para organizar las ventanas abiertas - + Tabbed Windows Ventanas con pestañas - + Tile Windows Ventanas en cascada - + Arrange open windows across all the available space. Organiza las ventanas en todo el espacio disponible - + Cascade Windows Ventanas en cascada - + Arrange all open windows in a stack. Organiza todas las ventanas abiertas en una cascada - + Close All Windows Cierra todas las ventanas - + Closes all open files (prompts to save if necessary. Cierra todos los archivos abiertos (pregunta guardar si es necesario) - + Window Ventana - + Ctrl+Shift+S - + Ctrl+Alt+L - + Ctrl+Alt+D - + Ctrl+Alt+R - + Small Pequeño - + Use small toolbar icons Usa iconos pequeños en la barra de herramientas - + Use normal size toolbar icons Usa iconos normales en la barra de herramientas - + Normal Normal - + Use big toolbar icons Usa iconos grandes en la barra de herramientas - + Big Grande - + Use huge toolbar icons Usa iconos extra grandes en la barra de herramientas - + Huge Extra Grande - + - Copy - Copiar - + Companion :: Open files warning Companion :: advertencia de archivos abiertos - + Please save or close modified file(s) before deleting the active profile. Por favor guarda o cierra los archivos modificados antes de borrar el perfil activo. - + Not possible to remove profile No se puede eliminar el perfil - + The default profile can not be removed. El perfil prederterminado no se puede eliminar. - + Confirm Delete Profile Confirma borrar perfil - + Are you sure you wish to delete the "%1" radio profile? There is no way to undo this action! ¿Seguro que quieres borrar el perfil de radio "%1"? ¡Esta acción no se puede deshacer! - + Please save or close all modified files before importing settings Por favor guarda o cierra todos los archivos modificados antes de importar ajustes - + <html><p>%1 and Simulator settings can be imported (restored) from a previosly saved export (backup) file. This will replace current settings with any settings found in the file.</p><p>An automatic backup of the current settings will be attempted. But if the current settings are useful then it is recommended that you make a manual backup first.</p><p>For best results when importing settings, <b>close any other %1 windows you may have open, and make sure the standalone Simulator application is not running.</p><p>Do you wish to continue?</p></html> <html><p>Los ajustes de %1 y del simulador pueden ser importados (restaurar) desde archvo exportado previamente (copia de seguridad). Esto reemplazará los ajustes actuales con los ajustes del archivo.</p><p>Se realizará automáticamente una copia de seguridad de los ajustes actuales. Pero si los ajustes actuales son útiles se recomienda que hagas una copia de seguridad manual primero.</p><p>Para los mejores resultados al importar ajustes, <b>cierra otras ventanas de %1 que tengas abiertas, y asegúrate que la aplicación del simulador no se está ejecutando.</p><p>¿Quieres continuar?</p></html> - + Confirm Settings Import Confirma importar ajustes - + Select %1: Selecciona %1 - + backup copia de seguridad - + Press the 'Ignore' button to continue anyway. Presiona el botón de 'Ignorar' para continuar de todos modos. - + The settings could not be imported. Los ajustes no han podido ser importados. - + <html><p>New settings have been imported from:<br> %1.</p><p>%2 will now re-initialize.</p><p>Note that you may need to close and restart %2 before some settings like language and icon theme take effect.</p> <html><p>Nuevos ajustes han sido importados desde:<br> %1.</p><p>%2 ahora se reiniciará.</p><p>Ten en cuenta que puedes necesitar cerrar y reiniciar %2 antes de que algunos ajustes como el lenguaje y el tema de iconos se hagan efectivos.</p> - + <p>The previous settings were backed up to:<br> %1</p> <p>Los ajustes anteriores fueron guardados en:<br> %1</p> - + Not enough flash available on this board for all the selected options No hay suficiente flash en esta placa para todas las opciones seleccionadas - + Compilation server temporary failure, try later Fallo temporal del servidor de compilación, intentalo más tarde - + Compilation error Error de compilación - + Invalid firmware Firmware no válido - + Invalid board Placa no válida - + Invalid language Lenguaje no válido - + Some text will not be translated until the next time you start Companion. Please note that some translations may not be complete. Algunos textos no serán traducidos hasta que reinicie Companion. Por favor ten en cuenta que algunas traducciones no están completas. - + Models and Settings read Lee modelos y ajustes - + No Companion release candidates are currently being served for this version, please switch release channel Actualmente no hay release candidates de Companion disponibles para esta versión, por favor cambia el canal de distribución - + No nightly Companion builds are currently being served for this version, please switch release channel Actualmente no hay nightly builds de Companion disponibles para esta versión, por favor cambia el canal de distribución - + No Companion release builds are currently being served for this version, please switch release channel Actualmente no hay distribuciones de Companion disponibles para esta versión, por favor cambia el canal de distribución - + Companion update check failed, new version information not found. El chequeo de la actualización de Companion ha fallado, la información de la nueva versión no se ha encontrado. - + No firmware release candidates are currently being served for this version, please switch release channel Actualmente no hay releases candidates de firmware disponibles para esta versión, por favor cambia el canal de distribución - + No firmware nightly builds are currently being served for this version, please switch release channel Actualmente no hay nightly builds de firmware disponibles para esta versión, por favor cambia el canal de distribución - + No firmware release builds are currently being served for this version, please switch release channel Actualmente no hay distribuciones de firmware disponibles para esta versión, por favor cambia el canal de distribución - + Release candidate builds are now available for this version, would you like to switch to using them? Ya hay disponibles release candidates para esta versión, ¿quieres cambiar para usarlas? - + Channel changed to RC, please restart the download process Canal cambiado a RC, por favor reinicia el proceso de descarga - + Official release builds are now available for this version, would you like to switch to using them? Ya hay disponibles distribuciones oficiales para esta versión, ¿quieres cambiar para usarlas? - + Channel changed to Release, please restart the download process Canal cambiado a Release, por favor reinicia el proceso de descarga - + This radio (%1) is not currently available in this firmware release channel Actualmente la radio (%1) no está disponible en este canal de distribución - + Firmware update check failed, new version information not found or invalid. El chequeo de la actualización del firmware ha fallado, la información de la versión no se ha encontrado o no es válida. - + Firmware %1 does not seem to have ever been downloaded. Version %2 is available. Do you want to download it now? @@ -7695,110 +7957,110 @@ La versión %2 está disponible. Te recomendamos que revises las notas de la versión usando el botón de abajo para los ver cambios que puedan ser importantes para tí. - - + + Do you want to download version %1 now ? ¿Quieres descargar ahora la versión %1? - + Ignore this version %1? ¿Ignorar esta versión %1? - + Local Folder Carpeta local - + Radio Folder Carpeta de radio - - + + This function is not yet implemented Esta función aún no está implementada - + The OpenTX Companion project was originally forked from <a href='%1'>eePe</a> El proyecto OpenTX Companion se ha bifurcado originalmente desde <a href='%1'>eePe</a> - + Copyright OpenTX Team Derechos de autor del equipo OpenTX - + Create a new Models and Settings file Crea un nuevo archivo de modelos y ajustes - - + + Save Models and Settings file Guarda el archivo de modelos y ajustes - + Exit Salir - + Use default system language. Usa el lenguaje predeterminado del sistema. - + Use %1 language (some translations may not be complete). Usa lenguaje %1 (algunas traducciones pueden no estar completas) - + Classical Clásico - + The classic companion9x icon theme Tema de iconos clásicos de companion9x - + Yerico Yerico - + Yellow round honey sweet icon theme Tema de iconos amarillo miel redondo - + Monochrome Monocromo - + MonoWhite MonoBlanco - + MonoBlue MonoAzul - + System language Lenguaje del sistema - + A new version of %1 firmware is available: - current is %2 - newer is %3 @@ -7815,228 +8077,218 @@ We recommend you view the release notes using the button below to learn about an Te recomendamos que revises las notas de la versión usando el botón de abajo para los ver cambios que puedan ser importantes para tí. - - + + Synchronize SD Sincronizar SD - + OpenTX Companion %1 - Radio: %2 - Profile: %3 OpenTX Companion %1 - Radio: %2 - Perfil: %3 - + About... Acerca de... - + View Log File... Ver archivo de registro... - + Open and view log file Abre el archivo de registro - + Settings... Ajustes... - + Edit Settings Edita ajustes - + Download... Descargar... - + Download firmware and voice files Descarga los archivos de firmware y voces - + Check for Updates... Comprobar actualizaciones... - + Check OpenTX and Companion updates Comprueba las actualizaciones de OpenTX y Companion - + Compare Models... Comparar modelos... - + Edit Radio Splash Image... Editar imagen de inicio de la radio... - + Edit the splash image of your Radio Editar la imagen de inicio de tu radio - - List programmers... - Lista de programadores... - - - - Fuses... - Fusibles... - - - - + + Read Firmware from Radio Leer firmware de la radio - + Read firmware from Radio Leer firmware de la radio - + Write Firmware to Radio Escribir firmware a la radio - + Write firmware to Radio Escribir firmware a la radio - + Add Radio Profile Añadir perfil de radio - + Manuals and other Documents Manuales y otros documentos - + Open the OpenTX document page in a web browser Abre la página de documentación de OpenTX en un navegador - + Write Models and Settings To Radio Escribir modelos y ajustes a la radio - + Write Models and Settings to Radio Escribir modelos y ajustes a la radio - - + + Read Models and Settings from Radio Leer los modelos y ajustes de la radio - + Configure Communications... Configurar comunicaciones... - + Configure software for communicating with the Radio Configura software para la comunicación con la radio - + Write Backup to Radio Escribir copia de seguridad a la radio - + Write Backup from file to Radio Escribir copia de seguridad desde un archivo a la radio - + Backup Radio to File Copia de seguridad de la radio a un archivo - + Save a complete backup file of all settings and model data in the Radio Guardar una copia de seguridad completa de todos los datos de ajustes y modelos en la radio - + Contributors... Contribuidores... - + A tribute to those who have contributed to OpenTX and Companion Un tributo a aquellos que han contribuido en OpenTX y Companion - + SD card synchronization Sincronización de la tarjeta SD - + Recent Files Archivos recientes - + Set Icon Theme Tema de iconos - + Set Icon Size Tamaño de iconos - - + + File Archivo - - + + Edit Editar - + Settings Ajustes - + Read/Write Leer/Escribir - - + + Help Ayuda - + Ready Listo @@ -8423,12 +8675,12 @@ Do you want to save your changes? MixData - + MIX - + (@%1) @@ -8712,27 +8964,27 @@ Esto determina cómo los valores de mezcla son añadidos. Abajo - + DEST -> %1 - + Click to access popup menu Pulsa para acceder el menú emergente - + Clear All Limpiar todo - + Set All Fijar todo - + Invert All Ivertir todo @@ -8763,131 +9015,136 @@ Esto determina cómo los valores de mezcla son añadidos. MixesPanel - - + + Move Up Mover arriba - - + + Ctrl+Up Ctrl+Arriba - - + + Move Down Mover abajo - - + + Ctrl+Down Ctrl+Abajo - + Clear Mixes Limpiar mezclas - + Not enough available mixers! ¡No hay suficientes mezclas disponibles! - - Delete Selected Mixes? - ¿Borrar las mezclas seleccionadas? + + Delete selected Mix lines. Are you sure? + Borrar líneas de mixes seleccionadas ¿Estás seguro? - + + Cut selected Mix lines. Are you sure? + Cortar líneas de mixes seleccionadas ¿Estás seguro? + + + &Add &Añadir - + Ctrl+A - + &Edit &Editar - + Enter Intro - + &Toggle highlight &Seleccionar palanca - + Ctrl+T - + &Delete &Borrar - + Delete Borrar - + &Copy &Copiar - + Ctrl+C - + Ctrl+X - + C&ut C&ortar - + &Paste &Pegar - + Ctrl+V - + Du&plicate &Duplicar - + Ctrl+U - + Clear Mixes? ¿Limpiar mezclas? - + Really clear all the mixes? ¿Seguro que quieres limpiar todas las mezclas? @@ -8895,12 +9152,12 @@ Esto determina cómo los valores de mezcla son añadidos. ModelData - + Model: Modelo: - + Throttle Source Fuente del acelerador @@ -8915,52 +9172,52 @@ Esto determina cómo los valores de mezcla son añadidos. Mensaje - + Setup Ajustes - + Heli Heli - + Inputs Entradas - + Logical Switches Interruptor lógicos - + Mixes Mezclas - + Outputs Salidas - + Curves Curvas - + Special Functions Funciones especiales - + Telemetry Telemetría - + Flight Modes Fases de vuelo @@ -8975,784 +9232,784 @@ Esto determina cómo los valores de mezcla son añadidos. ModelPrinter - + Exponential Exponencial - + Extra Fine Extra Fino - + Fine Fino - + Medium Medio - + Coarse Duro - + Unknown Desconocido - + Slave/Jack Slave/Jack - + Master/SBUS Module Módulo Master/SBUS - + Master/CPPM Module Módulo Master/CPPM - + Master/SBUS in battery compartment Master/SBUS en compartimento de la batería - + Master/Jack - + Enable Activar - + Disable Desactivar - + True Verdadero - + False Falso - + Yes - + No - + Y - + N - + ON - - - - + + + + OFF - + bytes - - + + Mode Modo - - + + Channels Canales - - + + Frame length Longitud frame - + PPM delay Retardo PPM - - + + Polarity Polaridad - + Protocol Protocolo - - - + + + Delay Retardo - - + + Receiver Receptor - + Radio protocol Protocolo radio - + Subtype Subtipo - + Option value Valor opción - + Sub Type Sub tipo - + + RF Output Power Potencia de salida RF - + + Output Type + Tipo de salida + + + + RX Output Frequency + Frecuencia de salida del RX + + + 90 - + 120 - + 120X - + 140 - + MULT! - - + + Offset - + Slow Lento - + Warn Aviso - + Flight modes Modos de vuelo - + Flight mode Modo de vuelo - + All Todo - + Edge Borde - + Sticky Pegajoso - + Timer Temporizador - + missing falta - + Duration Duración - + Extended Limits Límites extendidos - + Display Checklist Mostrar lista de verificación - + Global Functions Funciones globales - + Manual Manual - + Auto Auto - + Failsafe Mode Modo failsafe - - + + Hold Mantener - + No Pulse Sin pulsos - + Not set No fijado - + No pulses Sin pulsos - + Silent Silencio - + Beeps Beeps - + Voice Voz - + Haptic Haptic - + Flight Vuelo - + Manual reset Reset manual - + Step Paso - + Display Mostrar - + Extended Extendido - + Never Nunca - + On Change Al cambiar - + Always Siempre - - - + + + Source Fuente - + Trim idle only Trim sólo al ralentí - + Warning Aviso - + Reversed Invertido - + Tmr Temporiz. - + FrSky S.PORT - + FrSky D - + FrSky D (cable) - + Alti - + Alti+ - + VSpeed Veloc. vert. - - - - - A1 - - - A2 + A1 + - A3 + A2 - A4 + A3 - FAS + A4 + + FAS + + + + Cells Celdas - + Calculated Calculado - + Add Sumar - + Average Media - - + + Min Mínimo - - + + Max Máximo - + Multiply Multiplicar - + Totalise Total - + Cell Celda - + Consumption Consumo - + Distance Distancia - + Lowest Menor - + Cell %1 Celda %1 - + Highest Mayor - + Delta - - Formula - Fórmula + + Auto Offset + - - + + 0. + + + + + 0.0 + + + + + 0.00 + + + + Id - - Instance - Instancia - - - - - - + + Sensor - - + Sources Fuentes - - + GPS GPS - - Alt. - - - - - + Blades Palas - - Multi. - - - - + F - + Inst - + Alt - + Unit Unidad - + Prec - + Ratio - + Multi - - A/Offset - - - - + Filter Filtro - + Persist Persist. - + Positive Positivo - + Log Reporte - + Numbers Números - + Bars Barras - + Script Script - + Filename Nombre archivo - + Error: Unable to open or read file! Error: ¡No se puede abrir o leer el archivo! - + Persistent Persistente - + Off - - - - - - + + + + + + None Ninguno - + Name Nombre - + Countdown Cuenta atrás - + Minute call Cada minuto - - - + + + FM%1 - + FM%1%2 - + FM%1+%2 - - + + Weight Peso - - + + Switch Interruptor - - + + NoTrim - + No DR/Expo - + Offset(%1) - + Disabled in all flight modes Desactivado en todos los modos de vuelo - + instant instante - - - + + + Custom Personalizado - + Standard Estándar @@ -9788,353 +10045,367 @@ Esto determina cómo los valores de mezcla son añadidos. Module - - - + + + Failsafe Mode Modo failsafe - - + + Start Comenzar - - - + + + PPM delay Retardo PPM - - - + + + Negative Negativo - - - + + + Positive Positivo - - - + + + Polarity Polaridad - - - + + + Trainer Mode Modo entrenador - - - + + + PPM Frame Length Longitud trama PPM - - - + + + CH - - - + + + Antenna Antena - - - + + + Option value Valor opción - - - + + + RF Output Power Potencia de salida de RF - - - + + + Low Power Baja potencia - - - + + + us - - - + + + Multi Radio Protocol Multi Radio protocol - - - + + + Sub Type Sub tipo - - - + + + Master/Jack Master/Jack - - - + + + Slave/Jack Slave/Jack - - - + + + Master/SBUS Module Módulo Master/SBUS - - - + + + Master/CPPM Module Módulo Master/CPPM - - - + + + Master/SBUS in battery compartment Master/SBUS en compartimento de la batería - - - + + + Show values in: Muestra valores en: - - - + + + % abbreviation for percent - - - + + + μs abbreviation for microseconds - - - + + + ms - - - + + + Receiver 1 Receptor 1 - - - - - - - - - + + + + + + + + + X - - - + + + Receiver 2 Receptor 2 - - - + + + Receiver 3 Receptor 3 - - - + + + WARNING: changing RF Output Power needs RE-BIND AVISO: cambiar potencia salida de RF requiere RE-BIND - - - + + + Channels Canales - - - + + + + RX Frequency + Frecuencia RX + + + + + + Hz + + + + + + Registration ID Registro ID - - - + + + WARNING: Requires non-certified firmware! AVISO: ¡Requiere firmware no certificado! - - - + + + Not set No fijado - - - + + + Hold Mantener - - - + + + Custom Personalizado - - - + + + No Pulses Sin Pulsos - - - + + + Receiver Receptor - - - + + + Master/Bluetooth Master/Bluetooth - - - + + + Slave/Bluetooth Slave/Bluetooth - - - + + + Master/Multi Master/Multi - - - + + + Disable Telemetry Desactivar telemetría - - - + + + Disable Ch. Map Desactivar mapa canales - - - + + + Failsafe Positions Posiciones failsafe - - - + + + Protocol Protocolo - - - + + + Receiver No. Receptor Nº. - - - + + + Output type Tipo de salida - - - + + + Open Drain - - - + + + Push Pull @@ -10142,133 +10413,153 @@ Esto determina cómo los valores de mezcla son añadidos. ModuleData - + Positive Positivo - + Negative Negativo - + Trainer Port Puerto entrenador - + Internal Radio System Sistema de radio interno - + External Radio Module Módulo externo de radio - + Extra Radio System Sistema de radio extra - + Radio System Sistema de radio - + 10mW - 16CH - - + + 100mW - 16CH - + 500mW - 16CH - + Auto <= 1W - 16CH - - + + 25mW - 8CH - - + + 25mW - 16CH - + 200mW - 16CH (no telemetry) 200mW - 16CH (sin telemetría) - + 500mW - 16CH (no telemetry) 500mW - 16CH (sin telemetría) - + 100mW - 16CH (no telemetry) 100mW - 16CH (sin telemetría) + + + 25 mW + + + + + 100 mW + + + + + 500 mW + + + + + 1 W + + + + + 2 W + + ModulePanel - + Value Valor - + Hold Mantener - + No Pulse Sin pulsos - + Ask Preguntar - + Internal Interno - + Internal + External Interno + Externo - + External Externo - - Autodetect Format - Autodetectar formato - - - + Bind on channel Bind con canal @@ -10276,44 +10567,44 @@ Esto determina cómo los valores de mezcla son añadidos. MultiModelPrinter - + Input Entrada - + Weight Peso - + Long. cyc Cíc. long. - + Lateral cyc Cíc. lateral - + Collective Colectivo - + Flight modes Modos de vuelo - - + + Flight mode Modo de vuelo - - + + Switch Interruptores @@ -10323,401 +10614,349 @@ Esto determina cómo los valores de mezcla son añadidos. - + EEprom Size Tamaño EEprom - + Model Image Imagen del modelo - + Throttle Acelerador - + Trims - + Center Beep Beep en centro - + Switch Warnings Avisos interruptores - + Pot Warnings Avisos potenciómetros - + Other Otro - + Timers Temporizadores - + Time Hora - + Countdown Cuenta atrás - + Modules Módulos - + Trainer port Puerto entrenador - + Helicopter Helicóptero - + Swash - - + + Type Tipo - + Ring - + Protocol Protocolo - + Low Bajo - + Critical Crítico - + Telemetry audio Audio telemetría - + Altimetry Altímetro - - + + Vario source Fuente variómetro - + Vario limits > Límites variómetro - + Sink max Descenso máx - + Sink min Descenso mín - + Climb min Ascenso mín - + Climb max Ascenso máx - + Center silent Centro silencio - + Top Bar Barra superior - - + Volts source Fuente de voltage - + Altitude source Fuente de altitud - - Various - Varios - - - - Serial protocol - Protocolo serie - - - - FAS offset - - - - - mAh count - Valor mAh - - - - Persistent mAh - mAh persistente - - - - Current source - Fuente actual - - - - Blades - Palas - - - + Parameters Parámetros - + Telemetry Sensors Sensores de telemetría - + Telemetry Screens Pantallas de telemetría - + GF%1 - + Global Functions Funciones globales - + Checklist Lista de verificación - - + + GV%1 - + RE%1 - + Channel Canal - - + + Name Nombre - + Prec - + Popup Emergente - + Outputs Salidas - + Subtrim - + Direct Directo - + Curve Curva - + PPM - + Linear Lineal - + Telemetry Telemetría - - Offset - - - - - + + Min Mín - + Min.call Cada min - + Persist Persistente - + F.In Atn. entr. - + F.Out Atn.sal. - + Global vars Vars globales - - + + Max Máx - + Global Variables Variables globales - + Inputs Entradas - + Mixers Mezclas - + Curves Curvas - + L%1 - + Logical Switches Interruptores lógicos - + SF%1 - + Special Functions Funciones especiales - - Analogs - Analógicos - - - - + Unit Unidad - - Scale - Escala - - - + RSSI Alarms Alarmas RSSI @@ -10741,13 +10980,13 @@ Esto determina cómo los valores de mezcla son añadidos. - Telemetry - Telemetría + RF power + - Radio output power - Potencia de salida radio + Telemetry + Telemetría @@ -10796,22 +11035,22 @@ Esto determina cómo los valores de mezcla son añadidos. OpenTxEepromInterface - + Unknown error Error desconocido - + ... plus %1 errors ... más %1 errores - + Cannot write radio settings No se pueden escribir los ajustes de la radio - + Cannot write model %1 No se puede escribir el modelo %1 @@ -10924,6 +11163,23 @@ Esto determina cómo los valores de mezcla son añadidos. Archivos ODF (*.odt);;Archivos PDF (*.pdf);;Archivos HTML(*.htm *.html);;Todos los Archivos (*) + + ProfileChooserDialog + + + + + Select Profile + Seleccionar perfil + + + + + + Profile + Perfil + + ProgressDialog @@ -11079,25 +11335,20 @@ Esto determina cómo los valores de mezcla son añadidos. RadioInterface - + Cannot write file %1: %2. No se puede escribir el archivo %1: %2. - - <b><u>WARNING!</u></b><br>This will reset the fuses of %1 to the factory settings.<br>Writing fuses can mess up your radio.<br>Do this only if you are sure they are wrong!<br>Are you sure you want to continue? - <b><u>¡AVISO!</u></b><br>Esto reseteará los fusibles de %1 a los ajustes de fábrica.<br>Escribir los fusibles puede estropear tu radio.<br>¡Haz esto sólo si estás seguro que están mal!<br>¿Estás seguro de continuar? - - - - + + Could not delete temporary file: %1 No se puede borrar el archivo temporal: %1 - + Unable to find radio SD card! ¡No se puede encontrar la tarjeta SD de la radio! @@ -11145,6 +11396,7 @@ Esto determina cómo los valores de mezcla son añadidos. + Form @@ -11152,6 +11404,7 @@ Esto determina cómo los valores de mezcla son añadidos. + View: Vista: @@ -11159,6 +11412,7 @@ Esto determina cómo los valores de mezcla son añadidos. + Logical Switches Interruptores lógicos @@ -11166,6 +11420,7 @@ Esto determina cómo los valores de mezcla son añadidos. + Global Variables Variables globales @@ -11173,6 +11428,7 @@ Esto determina cómo los valores de mezcla son añadidos. + Channel Outputs Salidas canales @@ -11180,6 +11436,7 @@ Esto determina cómo los valores de mezcla son añadidos. + Mix Outputs Salidas mixes @@ -11187,6 +11444,7 @@ Esto determina cómo los valores de mezcla son añadidos. + L o g @@ -11203,6 +11461,7 @@ o + G l o @@ -11215,6 +11474,7 @@ l + C h a @@ -11235,6 +11495,7 @@ s + M i x @@ -11264,439 +11525,131 @@ s RawSource - - - - + V - - - - + + s - - ft - - - - - - m - - - - - °C - - - - - ° - - - - - % - - - - - - mph - - - - - - km/h - - - - - m/s - - - - - A - - - - - mAh - - - - - W - - - - - g - - - - + TrmR - + TrmE - + TrmT - + TrmA - + Trm5 - + Trm6 - + TrmH - + TrmV - - + Batt Batería - - + Time Hora - - + Timer1 Temporizador1 - - + Timer2 Temporizador 2 - - + Timer3 Temporizador 3 - - RAS - - - - - RSSI Tx - - - - - RSSI Rx - - - - - A1 - - - - - A2 - - - - - A3 - - - - - A4 - - - - - Alt - - - - - Rpm - - - - - Fuel - Combustible - - - - T1 - - - - - T2 - - - - - Speed - Velocidad - - - - Dist - Distancia - - - - GPS Alt - - - - - Cell - Celda - - - - Cells - Celdas - - - - Vfas - - - - - Curr - - - - - Cnsp - Cons - - - - Powr - - - - - AccX - - - - - AccY - - - - - AccZ - - - - - Hdg - - - - - VSpd - VelocVert - - - - AirSpeed - VelocAire - - - - dTE - - - - - A1- - - - - - A2- - - - - - A3- - - - - - A4- - - - - - Alt- - - - - - Alt+ - - - - - Rpm+ - - - - - T1+ - - - - - T2+ - - - - - Speed+ - Velocidad+ - - - - Dist+ - - - - - AirSpeed+ - VelocAire+ - - - - Cell- - Celda- - - - - Cells- - Celdas- - - - - Vfas- - - - - - Curr+ - - - - - Powr+ - - - - - ACC - - - - - GPS Time - Hora GPS - - - + REa - + REb - - + + ??? - + ---- - + I as in Input - + LUA%1%2 - + MAX - + CYC%1 - + TR as in Trainer - + SRC @@ -12065,7 +12018,22 @@ s ml/minuto - + + Hertz + + + + + mS + + + + + uS + + + + TELE @@ -12073,226 +12041,233 @@ s Setup - - - + + + Center beep Centro beep - - - + + + OFF - - - + + + Model Image Imagen del modelo - - - + + + Exponential Exponencial - - - + + + Throttle Trim Idle Only Trim acel. ralentí - - - + + + Extra Fine Extra Fino - - - + + + Fine Fino - - - + + + Medium Medio - - - + + + Coarse Grueso - - - + + + Display Checklist Lista de verific. - - - + + + Timer 2 Temporizador 2 - - + + Timer 1 Temporizador 1 - - - + + + Timer 3 Temporizador 3 - - - + + + Never Nunca - - - + + + Top LCD Timer Temp. LCD superior - - - + + + On change Al cambiar - - - + + + Always Siempre - - - + + + Global Functions Funcs. globales - - - + + + Edit Checklist... Lista de verific... - - - + + + Throttle Source Fuente acelerador - - - + + + Trim Step Paso de trim - - - + + + Trims Display Mostrar trims - - - + + + Warnings Avisos - - - + + + Switch Warnings Avisos interruptores - - - + + + Pot Warnings Avisos Potenciómetros - - - + + + Manual Manual - - - + + + Auto - - - + + + Model Modelo - - - + + + + Throttle trim switch + + + + + + Extended Limits Límites extendidos - - - + + + Extended Trims Trims extendidos - - - + + + Throttle Warning Aviso acelerador - - - + + + Reverse throttle operation. If this is checked the throttle will be reversed. Idle will be forward, trim will also be reversed and the throttle warning will be reversed as well. @@ -12303,9 +12278,9 @@ Si está marcado el acelerador será invertido. El ralentí será delante, el t - - - + + + Reverse Throttle Invertir acelerador @@ -12313,25 +12288,95 @@ Si está marcado el acelerador será invertido. El ralentí será delante, el t SetupPanel - + + Popup menu available + Menú emergente disponible + + + Timer %1 Temporizador %1 - + THR - + Profile Settings Ajustes de perfil - + SD structure path not specified or invalid Ruta de la SD no especificada o no válida + + + Copy + Copiar + + + + Cut + Cortar + + + + Paste + Pegar + + + + Clear + Limpiar + + + + Insert + Insertar + + + + Delete + Borrar + + + + Move Up + Mover arriba + + + + Move Down + Mover abajo + + + + Clear All + Limpiar todo + + + + Clear Timer. Are you sure? + Limpiar timer ¿Estás seguro? + + + + Clear all Timers. Are you sure? + Limpiar todos los timers ¿Estás seguro? + + + + Cut Timer. Are you sure? + Cortar timer ¿Estás seguro? + + + + Delete Timer. Are you sure? + Borrar timer ¿Estás seguro? + SimpleTailPage @@ -12680,6 +12725,7 @@ Perfil ID: [%1]; Radio ID: [%2] + OpenTx Simulator Simulador de OpenTX @@ -12687,6 +12733,7 @@ Perfil ID: [%1]; Radio ID: [%2] + View Vista @@ -12694,6 +12741,7 @@ Perfil ID: [%1]; Radio ID: [%2] + Radio Window Ventana de radio @@ -12701,6 +12749,7 @@ Perfil ID: [%1]; Radio ID: [%2] + Reload... Recargar... @@ -12708,6 +12757,7 @@ Perfil ID: [%1]; Radio ID: [%2] + Tools Herramientas @@ -12715,6 +12765,7 @@ Perfil ID: [%1]; Radio ID: [%2] + Toolbar Barra de herramientas @@ -12722,6 +12773,7 @@ Perfil ID: [%1]; Radio ID: [%2] + Reload Lua Scripts Recarga scripts Lua @@ -12729,6 +12781,7 @@ Perfil ID: [%1]; Radio ID: [%2] + Reload the Lua environment on the simulated radio. Recarga el entorno Lua en la simulación de la radio. @@ -12736,6 +12789,7 @@ Perfil ID: [%1]; Radio ID: [%2] + F7 @@ -12743,6 +12797,7 @@ Perfil ID: [%1]; Radio ID: [%2] + Reload Radio Data Recarga datos de radio @@ -12750,6 +12805,7 @@ Perfil ID: [%1]; Radio ID: [%2] + Reload all radio data without restarting the simulator. Recarga todos los datos de la radio sin reiniciar el simulador. @@ -12757,6 +12813,7 @@ Perfil ID: [%1]; Radio ID: [%2] + F9 @@ -12764,6 +12821,7 @@ Perfil ID: [%1]; Radio ID: [%2] + Key Mapping Mapa de teclas @@ -12771,6 +12829,7 @@ Perfil ID: [%1]; Radio ID: [%2] + Show keyboard maping reference. Muestra el mapa de teclas. @@ -12778,6 +12837,7 @@ Perfil ID: [%1]; Radio ID: [%2] + F1 @@ -12785,6 +12845,7 @@ Perfil ID: [%1]; Radio ID: [%2] + Joystick Settings Ajustes joystick @@ -12792,6 +12853,7 @@ Perfil ID: [%1]; Radio ID: [%2] + Open joystick configuration settings dialog. Abre la configuracíon de ajustes del joystick. @@ -12799,6 +12861,7 @@ Perfil ID: [%1]; Radio ID: [%2] + F3 @@ -12806,6 +12869,7 @@ Perfil ID: [%1]; Radio ID: [%2] + LCD Screenshot Captura LCD @@ -12813,6 +12877,7 @@ Perfil ID: [%1]; Radio ID: [%2] + Save a screenshot of the current simulated LCD screen. Guarda una captura de la simulación de la pantalla LCD. @@ -12820,6 +12885,7 @@ Perfil ID: [%1]; Radio ID: [%2] + F8 @@ -12827,6 +12893,7 @@ Perfil ID: [%1]; Radio ID: [%2] + Dock In Main Window Anclar en la ventana principal @@ -12834,6 +12901,7 @@ Perfil ID: [%1]; Radio ID: [%2] + Show the radio in the main window or as a separate "floating" window. Muestra la radio en la ventana principal o en una ventana "flotante" separada. @@ -12841,6 +12909,7 @@ Perfil ID: [%1]; Radio ID: [%2] + Menu Bar Barra superior @@ -12848,6 +12917,7 @@ Perfil ID: [%1]; Radio ID: [%2] + Show or hide the top menu bar. Muestra u oculta la barra superior. @@ -12855,6 +12925,7 @@ Perfil ID: [%1]; Radio ID: [%2] + Alt+M Alt+M @@ -12862,6 +12933,7 @@ Perfil ID: [%1]; Radio ID: [%2] + Constrain Width Restringir ancho @@ -12869,6 +12941,7 @@ Perfil ID: [%1]; Radio ID: [%2] + Set radio widget width to be a fixed size. Fija el ancho de widget de la radio a un tamaño fijo. @@ -12876,6 +12949,7 @@ Perfil ID: [%1]; Radio ID: [%2] + Constrain Height Restringir alto @@ -12883,6 +12957,7 @@ Perfil ID: [%1]; Radio ID: [%2] + Set radio widget height to be a fixed size. Fija el alto de widget de la radio a un tamaño fijo. @@ -12965,6 +13040,7 @@ Perfil ID: [%1]; Radio ID: [%2] + OpenTX Simulator - Startup Options Simulador de OpenTX - Opciones de arranque @@ -12972,6 +13048,7 @@ Perfil ID: [%1]; Radio ID: [%2] + Simulator Startup Options: Opciones de arranque del simulador: @@ -12979,6 +13056,7 @@ Perfil ID: [%1]; Radio ID: [%2] + Radio Profile: Perfil de radio: @@ -12986,6 +13064,7 @@ Perfil ID: [%1]; Radio ID: [%2] + Existing radio profiles are shown here.<br /> Create or edit profiles using the Companion application. Los perfiles de radio existentes se muestran aquí.<br /> @@ -12995,6 +13074,7 @@ Crea o edita perfiles usando la aplicación de Companion. + Radio Type: Tipo de radio: @@ -13002,6 +13082,7 @@ Crea o edita perfiles usando la aplicación de Companion. + Existing radio simulators are shown here.<br /> The radio type specified in the selected profile is used by default. Los simuladores de radio existentes se muestran aquí.<br /> @@ -13011,6 +13092,7 @@ Por defecto se us el tipo de radio especificado en en perfil seleccionado. + Data Source: Origen de datos: @@ -13018,6 +13100,7 @@ Por defecto se us el tipo de radio especificado en en perfil seleccionado. + Data File: Archivo de datos: @@ -13025,6 +13108,7 @@ Por defecto se us el tipo de radio especificado en en perfil seleccionado. + Data Folder: Carpeta de datos: @@ -13032,6 +13116,7 @@ Por defecto se us el tipo de radio especificado en en perfil seleccionado. + SD Image Path: Ruta de la imagen SD: @@ -13039,6 +13124,7 @@ Por defecto se us el tipo de radio especificado en en perfil seleccionado. + Radio data (.bin/.eeprom/.otx) image file to use. A new file with a default image will be created if necessary.<br /> <b>NOTE</b>: any existing EEPROM data incompatible with the selected radio type may be overwritten! Archivo de datos de la radio (.bin/.eeprom/.otx) a usar. Un nuevo archivo con imange predeterminada se creará si es necesario.<br /> @@ -13048,6 +13134,7 @@ Por defecto se us el tipo de radio especificado en en perfil seleccionado. + Select data file... Selecciona archivo de datos... @@ -13061,6 +13148,9 @@ Por defecto se us el tipo de radio especificado en en perfil seleccionado. + + + ... @@ -13068,6 +13158,7 @@ Por defecto se us el tipo de radio especificado en en perfil seleccionado. + Directory containing RADIO and MODELS folders to use.<br /> New folder(s) with default radio/model will be created here if necessary. Directorio conteniendo RADIO y MODELOS a usar.<br /> @@ -13077,6 +13168,7 @@ Nuevas carpeta(s) con radio/modelo predeterminado se crearán aquí si es necesa + Select data folder... Selecciona carpeta de datos... @@ -13084,6 +13176,7 @@ Nuevas carpeta(s) con radio/modelo predeterminado se crearán aquí si es necesa + Directory containing the SD card image to use.<br/> The default is configured in the chosen Radio Profile. Directorio que contiene la imagen de la tarjeta SD a usar.<br/> @@ -13093,6 +13186,7 @@ El predeterminado es configurado en el Perfil de radio seleccionado. + Select SD card image folder... Selecciona la carpeta de la imagen de la tarjeta SD... @@ -13100,6 +13194,7 @@ El predeterminado es configurado en el Perfil de radio seleccionado. + Select which of the data sources (File/Folder/SD Card) you would like to start the simulator with. Selecciona el origen de datos (Archivo/carpeta/tarjata SD) con el que quieres iniciar el simulador. @@ -13107,6 +13202,7 @@ El predeterminado es configurado en el Perfil de radio seleccionado. + File Archivo @@ -13114,6 +13210,7 @@ El predeterminado es configurado en el Perfil de radio seleccionado. + Folder Carpeta @@ -13121,6 +13218,7 @@ El predeterminado es configurado en el Perfil de radio seleccionado. + SD Path Ruta SD @@ -13151,6 +13249,7 @@ El predeterminado es configurado en el Perfil de radio seleccionado. + Companion Simulator Simulador Companion @@ -13160,62 +13259,62 @@ El predeterminado es configurado en el Perfil de radio seleccionado.Simulador radio (%1) - + Could not determine startup data source. No se pueden determinar los datos de arranque. - + Could not load data, possibly wrong format. No se puede cargar datos, posiblemente formato erróneo. - + Data Load Error Error de carga de de datos - + Invalid startup data provided. Plese specify a proper file/path. Datos de inicio inválidos. Por favor specifica un archivo/ruta válido. - + Simulator Startup Error Error de arranque del simulador - + Error saving data: could open file for writing: '%1' Error salvando datos: no se puede abrir el archivo como escritura: '%1' - + Error saving data: could not get data from simulator interface. Error salvando datos: no se puede obtener datos de la interfaz del simulador. - + An unexpected error occurred while attempting to save radio data to file '%1'. Ha ocurrido un error inesperado al intentar guardar los datos de la radio al archivo '%1'. - + Data Save Error Error de guardado de datos - + Radio firmware error: %1 Error del firmware de la radio: %1 - + - Flight Mode %1 (#%2) - Modo de vuelo %1 (#%2) - + Cannot open joystick, joystick disabled No se puede abrir el joystick, joystick desactivado @@ -13852,167 +13951,110 @@ Demasiados errores, abortando. TelemetryAnalog - - Unit Unidad - - Max Value Valor máx - - Alarm 1 Alarma 1 - - - - ---- - - - - Yellow Amarillo - - - - Orange Naranja - - - - Red Rojo - - - - < - - - - > - - Alarm 2 Alarma 2 - - Offset - - Volts (V) Voltios (V) - - Amps (A) Amperios (A) - - Speed (m/s or ft/s) Velocidad (m/s o pies/s) - - Raw (-) - - Speed (km/h or miles/h) Velocidad (km/h o millas/h) - - Meters (m or ft) Metros (m o pies) - - Temp (°) - - Fuel (%) Combustible (%) - - mAmps (mA) miliAmperios (mA) - - - Range - Rango - TelemetryCustomScreen @@ -14024,22 +14066,22 @@ Demasiados errores, abortando. Personalizar tipo pantalla - + None Ninguno - + Numbers Números - + Bars Barras - + Script Script @@ -14075,107 +14117,112 @@ Demasiados errores, abortando. TelemetryPanel - + FrSky S.PORT - + FrSky D - + FrSky D (cable) - + Telemetry screen %1 Pantalla telemetría %1 - + Source Fuente - + Low Alarm Alarma baja - + Critical Alarm Alarma crítica - + Winged Shadow How High - + Winged Shadow How High (not supported) Winged Shadow How High (no soportado) - + Alti - + Alti+ - + VSpeed VelocVert - - - + + + A1 - - - + + + A2 - - + + A3 - - + + A4 - - + + FAS - + Cells Celdas - + --- + + + Delete Sensor. Are you sure? + Borrar sensor ¿Estás seguro? + TelemetrySensor @@ -14596,67 +14643,92 @@ Demasiados errores, abortando. TelemetrySensorPanel - + TELE%1 - + Popup menu available Menú desplegable disponible - + Lowest Menor - + Cell %1 Celda %1 - + Highest Mayor - + Delta - + Copy Copiar - + Cut Cortar - + Paste Pegar - + Clear Limpiar - + + Insert + Insertar + + + + Delete + Borrar + + + + Move Up + Mover arriba + + + + Move Down + Mover abajo + + + Clear All Limpiar todo - + + Cut Telemetry Sensor. Are you sure? + Cortar sensor de telemetría ¿Estás seguro? + + + Clear Telemetry Sensor. Are you sure? Limpiar el sensor de telemetría ¿Estás seguro? - + Clear all Telemetry Sensors. Are you sure? Limpiar todos los sensores de telemetría ¿Estás seguro? @@ -14667,6 +14739,7 @@ Demasiados errores, abortando. + Telemetry Simulator Simulador de telemetría @@ -14674,6 +14747,7 @@ Demasiados errores, abortando. + VFAS @@ -14681,6 +14755,7 @@ Demasiados errores, abortando. + RSSI @@ -14688,6 +14763,7 @@ Demasiados errores, abortando. + A1 @@ -14695,6 +14771,7 @@ Demasiados errores, abortando. + A2 @@ -14702,6 +14779,7 @@ Demasiados errores, abortando. + Simulate Simular @@ -14709,6 +14787,7 @@ Demasiados errores, abortando. + Replay SD Log File Reproducir archivo SD de reporte @@ -14716,6 +14795,7 @@ Demasiados errores, abortando. + Replay rate Velocidad de reproducción @@ -14723,6 +14803,7 @@ Demasiados errores, abortando. + Load Cargar @@ -14730,6 +14811,7 @@ Demasiados errores, abortando. + |> @@ -14737,6 +14819,7 @@ Demasiados errores, abortando. + <| @@ -14744,6 +14827,7 @@ Demasiados errores, abortando. + > @@ -14751,6 +14835,7 @@ Demasiados errores, abortando. + <- @@ -14758,6 +14843,7 @@ Demasiados errores, abortando. + X @@ -14765,6 +14851,7 @@ Demasiados errores, abortando. + Row # Timestamp Col # @@ -14774,6 +14861,7 @@ Tiempo + 1/5x @@ -14781,6 +14869,7 @@ Tiempo + 5x @@ -14788,6 +14877,7 @@ Tiempo + No Log File Currently Loaded Actualmente no hay cargado archivo de reporte @@ -14795,6 +14885,7 @@ Tiempo + RAS @@ -14808,6 +14899,9 @@ Tiempo + + + V / ratio @@ -14815,6 +14909,7 @@ Tiempo + Db @@ -14822,6 +14917,7 @@ Tiempo + RxBt @@ -14865,6 +14961,19 @@ Tiempo + + + + + + + + + + + + + <html><head/><body><p><br/></p></body></html> @@ -14872,6 +14981,7 @@ Tiempo + Tmp1 Temporizador 1 @@ -14879,6 +14989,7 @@ Tiempo + A3 @@ -14886,6 +14997,7 @@ Tiempo + A4 @@ -14893,6 +15005,7 @@ Tiempo + Tmp2 Temporizador 2 @@ -14900,6 +15013,7 @@ Tiempo + Fuel Combustible @@ -14910,6 +15024,8 @@ Tiempo + + °C @@ -14917,6 +15033,7 @@ Tiempo + ml @@ -14924,6 +15041,7 @@ Tiempo + % @@ -14934,6 +15052,8 @@ Tiempo + + Meters Metros @@ -14941,6 +15061,7 @@ Tiempo + Alt @@ -14948,6 +15069,7 @@ Tiempo + VSpd VelocVertical @@ -14955,6 +15077,7 @@ Tiempo + m/s @@ -14962,6 +15085,7 @@ Tiempo + Fuel Qty Cant. combust. @@ -14972,6 +15096,8 @@ Tiempo + + km/h @@ -14979,6 +15105,7 @@ Tiempo + Hdg @@ -14986,6 +15113,7 @@ Tiempo + ASpd VelocAire @@ -14999,6 +15127,9 @@ Tiempo + + + G @@ -15006,6 +15137,7 @@ Tiempo + GPS @@ -15013,6 +15145,7 @@ Tiempo + Lat,Lon (dec.deg.) @@ -15021,6 +15154,7 @@ Tiempo + AccX @@ -15028,6 +15162,7 @@ Tiempo + dd-MM-yyyy hh:mm:ss @@ -15036,6 +15171,7 @@ hh:mm:ss + Date Fecha @@ -15043,6 +15179,7 @@ hh:mm:ss + Amps @@ -15050,6 +15187,7 @@ hh:mm:ss + AccZ @@ -15057,6 +15195,7 @@ hh:mm:ss + GAlt @@ -15067,6 +15206,8 @@ hh:mm:ss + + Volts Voltios @@ -15074,6 +15215,7 @@ hh:mm:ss + Cels Celdas @@ -15081,6 +15223,7 @@ hh:mm:ss + Curr @@ -15088,6 +15231,7 @@ hh:mm:ss + AccY @@ -15095,6 +15239,7 @@ hh:mm:ss + GSpd VelocTierra @@ -15102,6 +15247,7 @@ hh:mm:ss + Degrees Grados @@ -15109,6 +15255,7 @@ hh:mm:ss + Setting RSSI to zero simulates telemetry and radio link loss. Fijando RSSI a cero simula pérdida de telemetría y conexión con la radio. @@ -15116,6 +15263,7 @@ hh:mm:ss + Set RSSI to zero when paused. Fijar RSSI a cero en pausa. @@ -15123,6 +15271,7 @@ hh:mm:ss + Stop sending telemetry data when the Telemetry Simulator window is hidden. Para de enviar datos de telemetría cuado el simulador esté oculto. @@ -15130,6 +15279,7 @@ hh:mm:ss + Pause simulation when hidden. Pausar simulación cuando se oculte. @@ -15140,6 +15290,8 @@ hh:mm:ss + + RPM @@ -15147,6 +15299,7 @@ hh:mm:ss + When enabled, sends any non-blank values as simulated telemetry data. Cuando está activado, envía valores no vacíos como datos de telemetría simulados. @@ -15204,15 +15357,21 @@ hh:mm:ss TimerData - + TMR - + Timer %1 Temporizador %1 + + + TMR + as in Timer + + TimerEdit @@ -15242,37 +15401,37 @@ CTRL + scroll o AV/RE PÁG para cambiar el tiempo en pasos grandes. TimerPanel - + Silent Silencio - + Beeps - + Voice Voz - + Haptic - + Not persistent No persistente - + Persistent (flight) Persistente (vuelo) - + Persistent (manual reset) Persistente (reset manual) @@ -15494,6 +15653,7 @@ CTRL + scroll o AV/RE PÁG para cambiar el tiempo en pasos grandes. + Trainer simulator Simulador de entrenador @@ -15916,126 +16076,66 @@ CTRL + scroll o AV/RE PÁG para cambiar el tiempo en pasos grandes. burnConfigDialog - - - - - AVRDUDE Location - Ubicación AVRDUDE - - - - - - Location of AVRDUDE executable - Locatioon of AVRDUDE executable - Ubicación del ejecutable AVRDUDE - - - + + Programmer Configuration Configuration AVRDUDE / SAM-BA Configuración del programador - - - - - - - - - - - - + + + + + + + + + The location of the AVRDUDE executable. The location of the AVRDUDE.EXE executable. La ubicación del ejecutable AVRDUDE. - - - + + + DFU-Util Location Ubicación de la utilidad DFU - - - - - - - - - + + + + + + Use this button to browse and look for the AVRDUDE executable file. Usa este botón para explorar y ver el archivo ejecutable de AVRDUDE. - - - - - - - - - + + + + + + Browse... Explorar... - - - - Programmer - Programador - - - - - - Programmer used for communicating with the controller. -Please consult the programmer's documentation and the AVRDUDE documentation to select the appropriate programmer. - Programador usado para la comunicación con el controlador. -Por favor consulta la documentacion del programador y la documentación de AVRDUDE para elegir el programador adecuado. - - - - - - List all available programmers. - Lista todos los programadores disponibles. - - - - - - List Available - Listado disponibles - - - - - - - - + + + Extra arguments that will be passed to AVRDUDE on every call Argumentos extra que deben pasar a AVRDUDE en cada llamada - - - - - - + + + Extra arguments used in AVRDUDE. This can be used for providing extra information to AVRDUDE. @@ -16046,157 +16146,91 @@ Esto se puede utilizar para proporcionar información adicional para AVRDUDE. Por favor solamente usa esto si sabes lo que estás haciendo. No hay control de errores y podría paralizar tu controlador. - - - - Extra Arguments - Argumentos extra - - - - - - Show AVRDUDE help - Mostrar la ayuda de AVRDUDE - - - - - - Show Help - Mostrar ayuda - - - - - - Communication port to the programmer. - - Puerto de comunicaciones al programador. - - - - - - MCU - - - - - - + + + at91sam3s8-9xr - - - + + + Alternate device Dispositivo alternativo - - - + + + Use advanced controls Usar controles avanzados - - - - - - + + + Port Puerto - - - + + + SAM-BA Location Ubicación SAM-BA - - - - - - + + + + + + Location of sam-ba executable Ubicación del ejecutable sam-ba - - - + + + ARM MCU - - - + + + sam-ba serial port Puerto serie sam-ba - + DFU-UTIL Configuration Configuración DFU-UTIL - + SAM-BA Configuration Configuración SAM-BA - - AVRDUDE Configuration - Configuración AVRDUDE - - - - - + + Select Location Seleccionar ubicación - - List available programmers - Lista de programadores disponibles - - - - Avrdude help - Ayuda Avrdude - - - - <b><u>WARNING!</u></b><br>Normally CPU type is automatically selected according to the chosen firmware.<br>If you change the CPU type the resulting eeprom could be inconsistent. - <b><u>¡AVISO!</u></b><br>Normalmente el tipo de CPU es automáticamente elegida para el tipo de firmware.<br>Si cambias el tipo de CPU el eeprom resultante podría ser inconsistente. - - - - - - - - + + + CPU of your TX CPU de tu TX - - - - - - + + + CPU present on your 9x radio Should be m64 for stock radios m2560 for v4.1 boards @@ -16211,6 +16245,7 @@ m2560 para las placas v4.1 + Configure Joystick Configurar joystick @@ -16218,6 +16253,7 @@ m2560 para las placas v4.1 + Ch2 @@ -16225,6 +16261,7 @@ m2560 para las placas v4.1 + Ch1 @@ -16232,6 +16269,7 @@ m2560 para las placas v4.1 + Ch4 @@ -16239,6 +16277,7 @@ m2560 para las placas v4.1 + Ch6 @@ -16246,6 +16285,7 @@ m2560 para las placas v4.1 + Ch3 @@ -16253,6 +16293,7 @@ m2560 para las placas v4.1 + Ch5 @@ -16260,6 +16301,7 @@ m2560 para las placas v4.1 + Ch7 @@ -16267,6 +16309,7 @@ m2560 para las placas v4.1 + Ch8 @@ -16274,6 +16317,7 @@ m2560 para las placas v4.1 + Instructions Instrucciones @@ -16281,6 +16325,7 @@ m2560 para las placas v4.1 + Enable Activar @@ -16288,6 +16333,7 @@ m2560 para las placas v4.1 + Cancel Cancelar @@ -16295,6 +16341,7 @@ m2560 para las placas v4.1 + Back Atrás @@ -16302,6 +16349,7 @@ m2560 para las placas v4.1 + Start Inicio @@ -16314,6 +16362,7 @@ m2560 para las placas v4.1 + Ok diff --git a/companion/src/translations/companion_fr.ts b/companion/src/translations/companion_fr.ts index 9b18ec30e..593231b91 100644 --- a/companion/src/translations/companion_fr.ts +++ b/companion/src/translations/companion_fr.ts @@ -743,58 +743,58 @@ Manche Droit: Profondeur, Direction Boards - + Left Horizontal Gauche Horizontal - + Left Vertical Gauche Vertical - + Right Vertical Droit Vertical - + Right Horizontal Droit Horizontal - + Aux. 1 - + Aux. 2 - - + + Unknown Inconnu - + Rud Dir - + Ele Prf - + Thr Gaz - + Ail @@ -841,129 +841,129 @@ Manche Droit: Profondeur, Direction - Channels + ChannelsPanel - + Name Nom - + + Subtrim + Subtrim + + + Min - + Max - - Subtrim - - - - + Direction - + Curve Courbe - + PPM Center Neutre PPM - + Linear Subtrim Subtrim linéaire - + CH%1 VOIE%1 - + Popup menu available Menu contextuel disponible - + --- - + INV - + Delete Channel. Are you sure? Supprimer la Voie. Êtes-vous sûr? - + Cut Channel. Are you sure? Couper la Voie. Êtes-vous sûr? - + Copy Copier - + Cut Couper - + Paste Coller - + Clear Effacer - + Insert Insérer - + Delete Supprimer - + Move Up Monter - + Move Down Descendre - + Clear All Effacer Tout - + Clear Channel. Are you sure? Effacer la Voie. Êtes-vous sûr? - + Clear all Channels. Are you sure? Effacer toutes les Voies. Êtes-vous sûr? @@ -1118,37 +1118,37 @@ Manche Droit: Profondeur, Direction <p> Le type de radio sélectionnée dans le profil n'existe pas. Utilisez plutôt le type par défaut. </p> <p><b>Veuillez mettre à jour les paramètres de votre profil!</b></p> - + Select or create a file for exported Settings: Sélectionnez ou créez un fichier pour les paramètres exportés: - + Press the 'Retry' button to choose another file. Appuyez sur le bouton 'Réessayer' pour choisir un autre fichier. - + Simulator for this firmware is not yet available Le simulateur n'est pas encore disponible pour ce firmware - + Uknown error during Simulator startup. Erreur inconnue pendant le démarrage du simulateur. - + Simulator Error Erreur Simulateur - + Data Load Error Erreur de chargement des données - + Error occurred while starting simulator. Une erreur s'est produite lors du démarrage du simulateur. @@ -1386,52 +1386,6 @@ Si vous avez un fichier de sauvegarde des paramètres, vous pouvez l'import CB - - CurveGroup - - - Diff - - - - - Expo - - - - - Func - Fonc - - - - Curve - Courbe - - - - CurveReference - - - Diff(%1) - - - - - Expo(%1) - - - - - Function(%1) - Fonction(%1) - - - - Curve(%1) - Courbe(%1) - - Curves @@ -1520,116 +1474,119 @@ Si vous avez un fichier de sauvegarde des paramètres, vous pouvez l'import Curve name Nom de la courbe + + + CurvesPanel - + Curve %1 Courbe %1 - + Popup menu available Menu contextuel disponible - + %1 points - + Linear Linéaire - + Single Expo Expo simple - + Symmetrical f(x)=-f(-x) Symétrique f(x)=-f(-x) - + Symmetrical f(x)=f(-x) Symétrique f(x)=f(-x) - - Copy - Copier - - - - Cut - Couper - - - - Paste - Coller - - - - Clear - Effacer - - - - Insert - Insérer - - - - Delete - Supprimer - - - - Move Up - Monter - - - - Move Down - Descendre - - - - Clear All - Effacer Tout - - - - Clear Curve. Are you sure? - Effacer la Courbe. Êtes-vous sûr? - - - - Clear all Curves. Are you sure? - Effacer toutes les Courbes. Êtes-vous sûr? - - - - Cut Curve. Are you sure? - Couper la Courbe. Êtes-vous sûr? - - - - Delete Curve. Are you sure? - Supprimer la Courbe. Êtes-vous sûr? - - - + Editing curve %1 Édition de la courbe %1 - + Not enough free points in EEPROM to store the curve. Pas assez de points disponibles en mémoire pour enregistrer la courbe. + + + Copy + Copier + + + + Cut + Couper + + + + Paste + Coller + + + + Clear + Effacer + + + + Insert + Insérer + + + + Delete + Supprimer + + + + Move Up + Monter + + + + Move Down + Descendre + + + + Clear All + Effacer Tout + + + + Clear Curve. Are you sure? + Effacer la Courbe. Êtes-vous sûr? + + + + Clear all Curves. Are you sure? + Effacer toutes les Courbes. Êtes-vous sûr? + + + + Cut Curve. Are you sure? + Couper la Courbe. Êtes-vous sûr? + + + + Delete Curve. Are you sure? + Supprimer la Courbe. Êtes-vous sûr? + CustomFunctionData @@ -1765,108 +1722,103 @@ Si vous avez un fichier de sauvegarde des paramètres, vous pouvez l'import - SetFailsafe Int. Module - Définir failsafe module interne + Set Failsafe + Définir Failsafe - SetFailsafe Ext. Module - Définir failsafe module externe - - - RangeCheck Int. Module Test portée module interne - + RangeCheck Ext. Module Test portée module externe - + Bind Int. Module Bind module interne - + Bind Ext. Module Bind module externe - + Timer1 Chrono 1 - + Timer2 Chrono 2 - + Timer3 Chrono 3 - + Flight Vol - + Telemetry Télémétrie - + Rotary Encoder Sélecteur Rotatif - + REa - + REb - + s + - - + <font color=red><b>Inconsistent parameter</b></font> <font color=red><b>Paramètre inconsistant</b></font> - + Value Valeur - + played once, not during startup !1x Lu une fois, mais pas à la mise en route - + repeat(%1s) Répéter chaque %1s - + DISABLED DESACTIVE - + CFN FPN @@ -1874,139 +1826,139 @@ Si vous avez un fichier de sauvegarde des paramètres, vous pouvez l'import CustomFunctionsPanel - + Switch Interrupteur - + Action - + Parameters Paramètres - + Enable Actif - + Popup menu available Menu contextuel disponible - + SF%1 FS%1 - + GF%1 FG%1 - + ON - + Error occurred while trying to play sound, possibly the file is already opened. (Err: %1 [%2]) Une erreur s'est produite lors de la lecture du son, le fichier est peut-être déjà ouvert. (Err: %1 [%2]) - + Unable to find or open sound file: %1 Impossible de trouver ou d'ouvrir le fichier son: %1 - + Delete Function. Are you sure? Supprimer la Fonction. Êtes-vous sûr? - + Cut Special Function. Are you sure? Couper la Fonction. Êtes-vous sûr? - + Copy Copier - + Cut Couper - + Paste Coller - + Clear Effacer - + Insert Insérer - + Delete Supprimer - + Move Up Monter - + Move Down Descendre - + Clear All Effacer Tout - + Value Valeur - + Source Source - + GVAR VG - + Increment Incrément - + Clear Function. Are you sure? Effacer la Fonction. Êtes-vous sûr? - + Clear all Functions. Are you sure? Effacer toutes les Fonctions. Êtes-vous sûr? @@ -2209,13 +2161,13 @@ Si vous avez un fichier de sauvegarde des paramètres, vous pouvez l'import OpenTX n'accepte que %1 points au maximum entre toutes les courbes - - + + OpenTX on this board doesn't accept this function OpenTX ne supporte pas cette fonction sur cette carte - + OpenTX doesn't accept this radio protocol OpenTX ne supporte pas ce protocole radio @@ -2548,7 +2500,7 @@ Si vide, la ligne est toujours active. Les 2 - + Edit %1 Éditer %1 @@ -2558,17 +2510,17 @@ Si vide, la ligne est toujours active. Menu contextuel disponible - + Clear All Effacer Tout - + Set All Définir Tout - + Invert All Inverser Tout @@ -2937,255 +2889,272 @@ Blanc signifie "inclure tous".Les métacaractères ?, * et [...] sont Firmware - + Channel values displayed in us Positions de voies affichées en µs - + No OverrideCH functions available Désactive la fonction spéciale "Remplacer VOIExx" - + Possibility to enable FAI MODE (no telemetry) at field Possibilité d'activer le mode FAI (télémétrie désactivée) sur le terrain - + FAI MODE (no telemetry) always enabled Mode FAI (télémétrie toujours désactivée) - + Removes D8 FrSky protocol support which is not legal for use in the EU on radios sold after Jan 1st, 2015 Masque le protocole D8. Légalement obligatoire sur les radios Européennes importées après le 1er janvier 2015 - - + + + Disable HELI menu and cyclic mix support Supprimer le menu HELICO et les mixages cycliques - - + + + Disable Global variables Supprimer le support des variables globales - - + + + Enable Lua custom scripts screen Activer l'écran des scripts Lua personnalisés - + Use alternative SQT5 font Utiliser la police alternative SQT5 - + Disable RAS (SWR) Désactiver le RAS (SWR). Utile uniquement pour les X9D+ avec un RAS/SWR non fonctionnel - + Pots use in menus navigation Support de la navigation dans les menus avec les POTS - + Enable AFHDS3 support Activer le support du AFHDS3 - + FrSky Taranis X9D+ - + FrSky Taranis X9D+ 2019 - + FrSky Taranis X9D - + Haptic module installed Module vibreur installé - + FrSky Taranis X9E - + Confirmation before radio shutdown Confirmation avant l'arrêt de la radio - + Horus gimbals installed (Hall sensors) Manches Horus à effet HALL installés - + FrSky Taranis X9-Lite - + FrSky Taranis X9-Lite S - + FrSky Taranis X7 / X7S - + FrSky Taranis X7 / X7S Access - + FrSky Taranis X-Lite S/PRO - + FrSky Taranis X-Lite - + FrSky Horus X10 / X10S - + Support for ACCESS internal module replacement Prise en charge du module de remplacement interne ACCESS - + + + + + + Support hardware mod: R9M ACCESS + Prise en charge du mod hardware: R9M ACCESS + + + FrSky Horus X10 Express / X10S Express - + FrSky Horus X12S - + Use ONLY with first DEV pcb version Exclusivement pour les Horus DEV - - + + Support for MULTI internal module Prise en charge du module MULTI interne - - - + + + Support for bluetooth module Prise en charge du module Bluetooth - - Radiomaster TX16s / TX16s Hall / TX16s Masterfire - - - - + Support internal GPS Prise en charge du GPS interne - + Jumper T18 - + Turnigy 9XR-PRO - + Enable HELI menu and cyclic mix support Activer le menu hélico et les mixages CCPM - + Global variables Variables globales - + Enable non certified firmwares Activer les firmwares non certifiés - + In model setup menus automatically set source by moving the control Sélectionner les sources des mixeurs en bougeant le contrôle désiré - + In model setup menus automatically set switch by moving the control Sélectionner les interrupteurs en bougeant le contrôle désiré - + No graphical check boxes and sliders Pas de cases à cocher et de curseurs graphiques - + Battery graph Graphique de la batterie - + Don't use bold font for highlighting active items Ne pas mettre les lignes actives en gras - + Enable resetting values by pressing up and down at the same time Permet la remise à zéro des valeurs en pressant haut-bas en même temps, valeur min avec gauche/bas, valeur max avec haut/droite, inversion avec gauche/droite - + + Radiomaster TX12 + + + + + Radiomaster TX16S / SE / Hall / Masterfire + + + + 9X with AR9X board 9X avec carte AR9X - + Jumper T12 / T12 Pro - + Jumper T16 / T16+ / T16 Pro - + 9X with Sky9x board 9X avec carte Sky9x @@ -3682,47 +3651,47 @@ Vous utilisez actuellement: FlightModePanel - + Rotary Encoder %1 Sélecteur Rotatif %1 - + Name Nom - + Value source Source valeur - + Value Valeur - + Unit - + Prec - + Min Min - + Max Max - + GVAR%1 VG%1 @@ -3738,49 +3707,49 @@ Vous utilisez actuellement: - + Copy Copier - + Cut Couper - + Paste Coller - + Insert Insérer - + Delete Supprimer - + Move Up Monter - + Move Down Descendre - + Clear All Effacer Tout @@ -3790,104 +3759,104 @@ Vous utilisez actuellement: Effacer la Phase de Vol. Êtes-vous sûr? - + Clear all Flight Modes. Are you sure? Effacer toutes les Phases de Vol. Êtes-vous sûr? - + Cut Flight Mode. Are you sure? Couper la Phase de Vol. Êtes-vous sûr? - + Delete Flight Mode. Are you sure? Supprimer la Phase de Vol. Êtes-vous sûr? - + Clear Global Variable across all Flight Modes. Are you sure? Effacer la Variable Globale pour toutes les Phases de Vol. Êtes-vous sûr? - + Clear Global Variable. Are you sure? Effacer la Variable Globale. Êtes-vous sûr? - + Cut Global Variable across all Flight Modes. Are you sure? Couper la Variable Globale pour toutes les Phases de Vol. Êtes-vous sûr? - + Cut Global Variable. Are you sure? Couper la Variable Globale. Êtes-vous sûr? - + Delete Global Variable. Are you sure? Supprimer la Variable Globale. Êtes-vous sûr? - + Paste to selected Global Variable across all Flight Modes. Are you sure? Coller la Variable Globale pour toutes les Phases de Vol. Êtes-vous sûr? - + Clear all Global Variables for all Flight Modes. Are you sure? Effacer toutes les Variables Globales pour toutes les Phases de Vol. Êtes-vous sûr? - + Clear all Global Variables for this Flight Mode. Are you sure? Effacer toutes les Variables Globales pour cette Phase de Vol. Êtes-vous sûr? - + Popup enabled Indication activée - - + + Popup menu available Menu contextuel disponible - + Trim disabled Trim désactivé - + Own Trim Valeur indépendante - + Use Trim from Flight mode %1 Utiliser le trim de la phase de vol %1 - + Use Trim from Flight mode %1 + Own Trim as an offset Utiliser le trim de la phase de vol %1 + une valeur indépendante additionnée - + 0._ - + 0.0 - + Clear Effacer @@ -3895,17 +3864,17 @@ Vous utilisez actuellement: FlightModesPanel - + Flight Mode %1 Phase de vol %1 - + (%1) - + (default) (par défaut) @@ -4145,12 +4114,12 @@ p, li { white-space: pre-wrap; } VG - + Own value Valeur indépendante - + Flight mode %1 value Valeur de la phase de vol %1 @@ -4158,7 +4127,7 @@ p, li { white-space: pre-wrap; } GeneralEdit - + Setup Configuration @@ -4175,7 +4144,7 @@ These will be relevant for all models in the same EEPROM. Communs à tous les modèles d'une même EEPROM. - + Trainer Écolage @@ -4190,42 +4159,42 @@ Communs à tous les modèles d'une même EEPROM. Lire étalonnage et paramètres hw du profil - + Global Functions Fonctions globales - + Hardware Matériel - + Calibration - + Wrong data in profile, radio calibration was not retrieved Données du profil erronnées, l'étalonnage n'a pas été lu - + Wrong data in profile, Switch/pot config not retrieved Données incorecte, Interrupteurs/Pot non trouvés - + Wrong data in profile, hw related parameters were not retrieved Données du profil erronnées, les paramètres hw n'ont pas été lus - + Do you want to store calibration in %1 profile<br>overwriting existing calibration? Voulez-vous stocker l'étalonnage dans le profil %1<br> et écraser l'étalonnage existant ? - + Calibration and HW parameters saved. Etalonnage et paramètres hw enregistrés avec succès. @@ -5274,252 +5243,257 @@ Cette fonction ne peut pas être désactivée sur la radio. Formulaire - + SQ - + SR - + LS2 - + SP - + SO - + S4 - + RS - + SB - + PPM 2 - + Antenna Antenne - + OFF Eteint - + S-Port Mirror Recopie S. Port - + Telemetry Télémetrie - + SBUS Trainer Écolage SBUS - + Debug Débogage - + RTC Batt Check Vérif Batterie RTC - + + S.Port Power + Alimentation S.Port + + + S5 - + Rud Dir - + PPM 3 - + S1 - + S2 - + S3 - + PPM 1 - + Serial Port Port série - + v - + PPM Multiplier Coeff. multiplicateur PPM - + Current Offset Correction courant - + PPM 4 - + SA - + Ele Prf - + Ail Ail - + Thr Gaz - + SC - + LS - + SD - + Battery Offset Correction tension - + SE - + SF - + SG - + SH - + SI - + SJ - + SK - + SL - + SM - + SN - + RS2 - + Bluetooth - + ADC Filter Filtre ADC - + Device Name: Nom de l'appareil: @@ -5528,8 +5502,8 @@ Cette fonction ne peut pas être désactivée sur la radio. HardwarePanel - - + + None Aucun @@ -5549,67 +5523,67 @@ Cette fonction ne peut pas être désactivée sur la radio. 3 Positions - + Pot with detent Potentiomètre avec centre - + Multipos switch Inter multiposition - + Pot without detent Potentiomètre sans centre - + Slider with detent Curseur avec centre - + OFF - + Enabled Activé - + Telemetry Télémétrie - + Trainer Écolage - + Internal Interne - + Ask Demander - + Per model Par modèle - + Internal + External Interne + Externe - + External Externe @@ -5735,159 +5709,159 @@ Cette fonction ne peut pas être désactivée sur la radio. InputsPanel - - - + + + Move Up Monter - - + + Ctrl+Up Ctrl+Haut - - - + + + Move Down Descendre - - + + Ctrl+Down Ctrl+Bas - + Clear All Inputs Effacer toutes les entrées - + Not enough available Inputs! Pas assez d'Entrées disponibles! - + Delete selected Input lines. Are you sure? Supprimer les lignes Entrée sélectionnées. Êtes-vous sûr? - + Cut selected Input lines. Are you sure? Couper les lignes Entrée sélectionnées. Êtes-vous sûr? - + Lines Linéaire - + &Add &Ajouter - + Ctrl+A Ctrl+A - + &Edit &Édition - + Enter Entrée - + &Delete &Supprimer - - + + Delete Supprimer - + &Copy &Copier - + Ctrl+C - + &Cut &Couper - + Ctrl+X - + &Paste &Coller - + Ctrl+V - + Du&plicate Du&pliquer - + Ctrl+U - + Input Entrée - + Insert Insérer - + Clear Effacer - + Clear All Effacer Tout - + Clear all Input lines. Are you sure? Effacer toutes les lignes Entrée. Êtes-vous sûr? - + Clear all lines for the selected Inputs. Are you sure? Effacer toutes les lignes Entrée sélectionnées. Êtes-vous sûr? - + Delete all lines for the selected Inputs. Are you sure? Supprimer toutes les lignes Entrée sélectionnées. Êtes-vous sûr? @@ -5913,7 +5887,7 @@ Cette fonction ne peut pas être désactivée sur la radio. LimitsGroup - + GV VG @@ -6044,112 +6018,112 @@ Cette fonction ne peut pas être désactivée sur la radio. LogicalSwitchesPanel - + V1 - + V2 - + Duration Durée - + Delay Délai - + Function Fonction - + AND Switch ET supplémentaire - + Popup menu available Menu contextuel disponible - + (instant) - + (infinite) (infini) - + Delete Logical Switch. Are you sure? Supprimer l'Interrupteur Logique. Êtes-vous sûr? - + Cut Logical Switch. Are you sure? Couper l'Interrupteur Logique. Êtes-vous sûr? - + Copy Copier - + Cut Couper - + Paste Coller - + Clear Effacer - + Insert Insérer - + Delete Supprimer - + Move Up Monter - + Move Down Descendre - + Clear All Effacer Tout - + Clear Logical Switch. Are you sure? Effacer l'Interrupteur Logique. Êtes-vous sûr? - + Clear all Logical Switches. Are you sure? Effacer tous les Interrupteurs Logiques. Êtes-vous sûr? @@ -7876,7 +7850,7 @@ Mixage actif par défaut si non-renseigné. Nom - + DEST -> %1 @@ -7886,17 +7860,17 @@ Mixage actif par défaut si non-renseigné. Cliquez pour accéder au menu contextuel - + Clear All Effacer Tout - + Set All Définir Tout - + Invert All Inverser Tout @@ -7942,136 +7916,136 @@ Mixage actif par défaut si non-renseigné. MixesPanel - - + + Move Up Monter - - + + Ctrl+Up Ctrl+Haut - - + + Move Down Descendre - - + + Ctrl+Down Ctrl+Bas - + Clear Mixes Effacer tous les mixages - + Not enough available mixers! Plus de mixages disponibles ! - + Delete selected Mix lines. Are you sure? Supprimer les lignes Mixeur sélectionnées. Êtes-vous sûr? - + Cut selected Mix lines. Are you sure? Couper les lignes Mixeur sélectionnées. Êtes-vous sûr? - + &Add &Ajouter - + Ctrl+A - + &Edit &Édition - + Enter Entrée - + Ctrl+T - + &Toggle highlight &(Dé)sélectionner - + &Delete &Supprimer - + Delete Supprimer - + &Copy &Copier - + Ctrl+C - + Ctrl+X - + C&ut &Couper - + &Paste &Coller - + Ctrl+V - + Du&plicate &Dupliquer - + Ctrl+U - + Clear Mixes? Effacer tous les mixages ? - + Really clear all the mixes? Êtes-vous sûr de vraiment vouloir effacer tous les mixages ? @@ -8097,32 +8071,32 @@ Mixage actif par défaut si non-renseigné. Simulation - + Heli Paramètres hélico - + Inputs Entrées - + Mixes Mixages - + Logical Switches Inters logiques - + Setup Configuration - + Curves Courbes @@ -8132,22 +8106,22 @@ Mixage actif par défaut si non-renseigné. Dialogue - + Flight Modes Phases de vol - + Outputs Sorties - + Special Functions Fonctions spéciales - + Telemetry Télémesure @@ -8247,8 +8221,8 @@ Mixage actif par défaut si non-renseigné. - - + + OFF @@ -8259,7 +8233,7 @@ Mixage actif par défaut si non-renseigné. - + Mode @@ -8293,14 +8267,13 @@ Mixage actif par défaut si non-renseigné. - - + Delay Délai - + Receiver Récepteur @@ -8361,477 +8334,482 @@ Mixage actif par défaut si non-renseigné. - + + + Weight(%1) + Ratio(%1) + + + + + Switch(%1) + Inter(%1) + + + MULT! - - + + Delay(u%1:d%2) + Délai(h%1:b%2) + + + + Slow(u%1:d%2) + Ralenti(h%1:b%2) + + + + Warn(%1) + Alerte(%1) + + + Offset Décalage - - Slow - Ralenti - - - - Warn - Attn - - - + Flight modes Phases de vol - + Flight mode Phase de vol - + All Tous - + Edge Flanc - + Sticky Bistable - + Timer Chrono - + missing absent - + Duration Durée - + Extended Limits Limites étendues - + Display Checklist Afficher la checklist - + Global Functions Fonctions globales - + Manual Manuel - + Auto - + Failsafe Mode Mode Failsafe - - + + Hold Maintien - + No Pulse Pas d'impulsion - + Not set Non défini - + No pulses Pas d'impulsions - + Silent Aucun - + Beeps Bips - + Voice Voix - + Haptic Vibreur - + Flight Vol - + Manual reset RAZ manuelle - + Step Pas - + Display Affichage - + Extended Étendu - + Never Jamais - + On Change Sur changement - + Always Toujours - - - + + + Source - + Trim idle only Trim ralenti uniquement - + Warning Avertissement - + Reversed Inversé - + Tmr Chrono - + FrSky S.PORT - + FrSky D - + FrSky D (cable) FrSky D (câble) - + Alti Alt - + Alti+ Alt+ - + VSpeed Vitesse verticale - - - + + + A1 - - - + + + A2 - - + + A3 - - + + A4 - - + + FAS - + Cells Velm - + Calculated Calculé - + Add Addition - + Average Moyenne - - + + Min - - + + Max - + Multiply Multiplication - + Totalise - + Cell Element LiPo - + Consumption Consommation - + Distance - + Lowest Min - + Cell %1 Elém. %1 - + Highest Max - + Delta - - Formula - Formule + + Auto Offset + Offset Auto - - - Id + + 0. - - Instance - - - - - - - - Sensor - Capteur - - - - - Sources - - - - - - GPS - - - - - Alt. - - - - - - Blades - Pales - - - - Multi. - - - - - F - - - - - Inst - - - - - Alt - Altitude - - - - Unit - Unité - - - - Prec - - - - - Ratio + + 0.0 + 0.00 + + + + + Id + + + + + + Sensor + Capteur + + + + Sources + + + + + GPS + + + + + Blades + Pales + + + + F + + + + + Inst + + + + + Alt + Altitude + + + + Unit + Unité + + + + Prec + + + + + Ratio + + + + Multi - - A/Offset - - - - + Filter Filtre - + Persist - + Positive - + Log - + Numbers Chiffres - + Bars Barres - + Script - + Filename Nom de fichier - + Error: Unable to open or read file! Erreur: Impossible d'ouvrir ou de lire le fichier! @@ -8847,11 +8825,11 @@ Mixage actif par défaut si non-renseigné. - - - - - + + + + + None Aucun @@ -8887,31 +8865,20 @@ Mixage actif par défaut si non-renseigné. FM%1+%2 PV%1+%2 - - - - Weight - Ratio - - - - - Switch - Inter - - + NoTrim Pas de trim - + No DR/Expo Pas d'expo/DR + Offset(%1) Décalage(%1) @@ -8926,24 +8893,24 @@ Mixage actif par défaut si non-renseigné. - + Disabled in all flight modes Désactivé pour toutes les phases de vol - + instant immédiat - - - + + + Custom Prédéfini - + Standard @@ -9241,12 +9208,12 @@ Mixage actif par défaut si non-renseigné. ModuleData - + Positive - + Negative Négative @@ -9352,42 +9319,42 @@ Mixage actif par défaut si non-renseigné. ModulePanel - + Value Valeur - + Hold Maintien - + No Pulse Pas d'impulsion - + Ask Demander - + Internal Interne - + Internal + External Interne + Externe - + External Externe - + Bind on channel Bind avec VOIE @@ -9395,127 +9362,127 @@ Mixage actif par défaut si non-renseigné. MultiModelPrinter - + Input Entrée - + Weight Ratio - + Long. cyc Cyc. longitudinal - + Lateral cyc Cyc. latéral - + Collective Source du pas collectif - + Flight modes Phases de vol - - + + Flight mode Phase de vol - - + + Switch Inter - - + + GV%1 VG%1 - + RE%1 - + Channel Voie - + Direct - + Curve Courbe - + PPM - + Linear Linéaire - + Telemetry Télémétrie - - + + Min - + Timers Chronos - + Time Temps - + Countdown Compte à rebours - + Modules - + Outputs Sorties - + Subtrim Subtrim - - + + Max @@ -9526,265 +9493,265 @@ Mixage actif par défaut si non-renseigné. - - + + Name Nom - + EEprom Size Taille EEPROM - + Model Image Image du modèle - + Throttle Gaz - + Trims - + Center Beep Bip Centrer - + Switch Warnings Positions des interrupteurs - + Pot Warnings Positions des potentiomètres - + Other Autre - + Min.call Annonces minutes - + Persist Persistant - + Trainer port Port écolage - + Helicopter Hélicoptère - + Swash Cyclique - - + + Type - + Ring Plateau - + F.In Fondu en entrée - + F.Out Fondu en sortie - + Global vars Variables globales - + Prec - + Popup - + Global Variables Variables globales - + Inputs Entrées - + Mixers Mixages - + Curves Courbes - + L%1 - + Logical Switches Inters logiques - + SF%1 FS%1 - + Special Functions Fonctions spéciales - + Protocol Protocole - + Low Faible - + Critical Critique - + Telemetry audio Audio télémétrie - + Altimetry Altimétrie - - + + Vario source Source vario - + Vario limits > Limites vario > - + Sink max Chute max - + Sink min Chute min - + Climb min Pompe min - + Climb max Pompe max - + Center silent Silence centrer - + Top Bar Barre de titre de l'écran d'accueil - + Volts source Source de la tension - + Altitude source Source de l'altitude - + Parameters Paramètres - + Telemetry Sensors Capteurs Télémétrie - + Telemetry Screens Écrans Télémétrie - + GF%1 FG%1 - + Global Functions Fonctions globales - + Checklist - + Unit Unité - + RSSI Alarms Alarmes RSSI @@ -9863,22 +9830,22 @@ Mixage actif par défaut si non-renseigné. OpenTxEepromInterface - + Unknown error Erreur inconnue - + ... plus %1 errors ... plus %1 erreurs - + Cannot write radio settings Impossible d'écrire les paramètres de la radio - + Cannot write model %1 Impossible d'écrire le modèle %1 @@ -10026,12 +9993,12 @@ Mixage actif par défaut si non-renseigné. QObject - + WARNING ATTENTION - + <p>Importing JumperTX data into OpenTX 2.3 is <b>not supported and dangerous.</b></p> <p>It is unfortunately not possible for us to differentiate JumperTX data from legitimate FrSky X10 data, but <b>You should only continue here if the file you opened comes from a real FrSky X10.</b></p> <p>Do you really want to continue?</p> <p>L'importation de données JumperTX dans OpenTX 2.3 est <b> non prise en charge et dangereuse.</b></p> <p>Il n'est malheureusement pas possible pour nous de différencier les données JumperTX des données légitimes FrSky X10, donc <b>Vous devez continuer uniquement si le fichier que vous avez ouvert provient d’une véritable radio FrSky X10.</b></p> <p>Voulez-vous vraiment continuer?</p> @@ -10430,22 +10397,22 @@ E RawSwitch - + - + - + - - + ! @@ -10814,62 +10781,62 @@ E Setup - + Center beep Bip de centrage - + OFF - + Model Image Image du modèle - + Exponential Exponentiel - + Throttle Trim Idle Only Trim ralenti uniquement - + Timer 3 Chrono 3 - + Extra Fine Extra fin - + Fine Fin - + Medium Moyen - + Coarse Grossier - + Display Checklist Afficher la checklist - + Timer 2 Chrono 2 @@ -10879,97 +10846,102 @@ E Chrono 1 - + Never Jamais - + On change Au changement - + Always Toujours - + Global Functions Fonctions globales - + Edit Checklist... Éditer Checklist... - + Throttle Source Source des gaz - + Trim Step Pas des trims - + Trims Display Affichage des trims - + Warnings Avertissements - + Top LCD Timer Chrono LCD supérieur - + Switch Warnings Positions des interrupteurs - + Pot Warnings Positions des potentiomètres - + Manual Manuel - + Auto - + Model Modèle - + + Throttle trim switch + Inter trim gaz + + + Extended Limits Limites étendues - + Extended Trims Trims étendus - + Throttle Warning Alerte gaz - + Reverse throttle operation. If this is checked the throttle will be reversed. Idle will be forward, trim will also be reversed and the throttle warning will be reversed as well. @@ -10980,7 +10952,7 @@ Si cette option est cochée, la voie des gaz est inversée: le ralenti est &apo - + Reverse Throttle Gaz inversés @@ -10988,92 +10960,92 @@ Si cette option est cochée, la voie des gaz est inversée: le ralenti est &apo SetupPanel - + Popup menu available Menu contextuel disponible - + Timer %1 Chrono %1 - + THR GAZ - + Profile Settings Paramètres du profil - + SD structure path not specified or invalid Chemin de la structure SD non spécifié ou invalide - + Copy Copier - + Cut Couper - + Paste Coller - + Clear Effacer - + Insert Insérer - + Delete Supprimer - + Move Up Monter - + Move Down Descendre - + Clear All Effacer Tout - + Clear Timer. Are you sure? Effacer le Chrono. Êtes-vous sûr? - + Clear all Timers. Are you sure? Effacer tous les Chronos. Êtes-vous sûr? - + Cut Timer. Are you sure? Couper le Chrono. Êtes-vous sûr? - + Delete Timer. Are you sure? Supprimer le Chrono. Êtes-vous sûr? @@ -11797,62 +11769,62 @@ La valeur par défaut est configurée dans le profil radio sélectionné.Simulateur Radio (%1) - + Could not determine startup data source. Impossible de déterminer les données source. - + Could not load data, possibly wrong format. Impossible de charger les données, mauvais format. - + Data Load Error Erreur de lecture des données - + Invalid startup data provided. Plese specify a proper file/path. Données de démarrage fournies non valides. Veuillez spécifier un fichier/chemin approprié. - + Simulator Startup Error Erreur de démarrage du simulateur - + Error saving data: could open file for writing: '%1' Erreur de sauvegarde des données: impossible d'écrire le fichier '%1' - + Error saving data: could not get data from simulator interface. Erreur de sauvegarde des données: impossible de récupérer les données depuis l'interface de simulation. - + An unexpected error occurred while attempting to save radio data to file '%1'. Une erreur inattendue s'est produite lors de l'enregistrement des données radio dans le fichier '%1'. - + Data Save Error Erreur de sauvegarde des données - + Cannot open joystick, joystick disabled Impossible d'accéder au Joystick, Joystick désactivé - + Radio firmware error: %1 Erreur firmware radio: %1 - + - Flight Mode %1 (#%2) - Phase de Vol %1 (#%2) @@ -12507,22 +12479,22 @@ Trop d'erreurs, abandon. Type d'écran personnalisé - + None Aucun - + Numbers Chiffres - + Bars Barres - + Script @@ -12550,109 +12522,109 @@ Trop d'erreurs, abandon. TelemetryPanel - + FrSky S.PORT - + FrSky D - + FrSky D (cable) FrSky D (câble) - + Telemetry screen %1 Ecran de télémesure %1 - + Source - + Low Alarm Alarme basse - + Critical Alarm Alarme critique - + Winged Shadow How High - + Winged Shadow How High (not supported) Winged Shadow How High (non supporté) - + Alti Alt - + Alti+ Alt+ - + VSpeed Vitesse verticale - - + + A1 - - + + A2 - - + + A3 - - + + A4 - - + + FAS - + Cells Velm - + --- - + Delete Sensor. Are you sure? Supprimer le Capteur. Êtes-vous sûr? @@ -12950,92 +12922,92 @@ Trop d'erreurs, abandon. TelemetrySensorPanel - + TELE%1 - + Popup menu available Menu contextuel disponible - + Lowest Min - + Cell %1 Elém. %1 - + Highest Max - + Delta - + Copy Copier - + Cut Couper - + Paste Coller - + Clear Effacer - + Insert Insérer - + Delete Supprimer - + Move Up Monter - + Move Down Descendre - + Clear All Effacer Tout - + Cut Telemetry Sensor. Are you sure? Couper le capteur de télémétrie. Êtes-vous sûr? - + Clear Telemetry Sensor. Are you sure? Effacer le capteur de télémétrie. Êtes-vous sûr? - + Clear all Telemetry Sensors. Are you sure? Effacez tous les capteurs de télémétrie. Êtes-vous sûr? diff --git a/companion/src/translations/companion_ja.ts b/companion/src/translations/companion_ja.ts index da32c47fc..2d7d02b4d 100644 --- a/companion/src/translations/companion_ja.ts +++ b/companion/src/translations/companion_ja.ts @@ -730,58 +730,58 @@ Mode 4: Boards - + Left Horizontal 左・横 - + Left Vertical 左・縦 - + Right Vertical 右・縦 - + Right Horizontal 右・横 - + Aux. 1 AUX. 1 - + Aux. 2 AUX. 2 - - + + Unknown 不明 - + Rud ラダー - + Ele エレベーター - + Thr スロットル - + Ail エルロン @@ -895,57 +895,62 @@ Mode 4: チャンネルを削除します。よろしいですか? - + + Cut Channel. Are you sure? + チャンネルを切り取ります。よろしいですか? + + + Copy コピー - + Cut 切り取り - + Paste 貼り付け - + Clear 消去 - + Insert 挿入 - + Delete 削除 - + Move Up 上へ移動 - + Move Down 下へ移動 - + Clear All すべて消去 - + Clear Channel. Are you sure? チャンネルを消去します。よろしいですか? - + Clear all Channels. Are you sure? チャンネルをすべて消去します。よろしいですか? @@ -1595,17 +1600,22 @@ If you have a settings backup file, you may import that instead. すべて消去 - + Clear Curve. Are you sure? カーブを消去します。よろしいですか? - + Clear all Curves. Are you sure? カーブをすべて消去します。よろしいですか? - + + Cut Curve. Are you sure? + カーブを切り取ります。よろしいですか? + + + Delete Curve. Are you sure? カーブを削除します。よろしいですか? @@ -1629,8 +1639,8 @@ If you have a settings backup file, you may import that instead. - Trainer - トレーナー + Trainer Sticks + トレーナー Sticks @@ -1773,79 +1783,79 @@ If you have a settings backup file, you may import that instead. バインド 外部モジュール - + Timer1 タイマー1 - + Timer2 タイマー2 - + Timer3 タイマー3 - + Flight フライト - + Telemetry テレメトリー - + Rotary Encoder エンコーダ再生 - + REa エンコーダ再生a - + REb エンコーダ再生b - + s s - - - + + + <font color=red><b>Inconsistent parameter</b></font> <font color=red><b>矛盾しているパラメータ</b></font> - + Value - + played once, not during startup 起動時以外 1回実行 - + repeat(%1s) リピート(%1s) - + DISABLED 無効 - + CFN CFN @@ -1905,82 +1915,87 @@ If you have a settings backup file, you may import that instead. %1 - - Delete Special Function. Are you sure? - スペシャルファンクションを削除します。よろしいですか? + + Delete Function. Are you sure? + ファンクションを削除します。よろしいですか? - + + Cut Special Function. Are you sure? + ファンクションを切り取ります。よろしいですか? + + + + Clear Function. Are you sure? + ファンクションを消去します。よろしいですか? + + + + Clear all Functions. Are you sure? + ファンクションをすべて消去します。よろしいですか? + + + Copy コピー - + Cut 切り取り - + Paste 貼り付け - + Clear 消去 - + Insert 挿入 - + Delete 削除 - + Move Up 上へ移動 - + Move Down 下へ移動 - + Clear All すべて消去 - - Clear Special Function. Are you sure? - スペシャルファンクションを消去します。よろしいですか? - - - - Clear all Special Functions. Are you sure? - スペシャルファンクションをすべて消去します。よろしいですか? - - - + Value - + Source 選択元 - + GVAR GVAR - + Increment 増加 @@ -2148,48 +2163,48 @@ If you have a settings backup file, you may import that instead. フィールド %1 変換エラー - + Switch スイッチ - + Switch スイッチ - + cannot be exported on this board! このボードにエクスポートできません! - + Source 選択元 - + Source %1 cannot be exported on this board! このボードでは選択元 %1 をエクスポートできません! - + OpenTX only accepts %1 points in all curves OpenTXはすべてのカーブで %1 点のみを許容します - + OpenTx only accepts %1 points in all curves OpenTxはすべてのカーブで %1 点のみを許容します - - + + OpenTX on this board doesn't accept this function このボード上のOpenTXはこの機能を受け付けません - + OpenTX doesn't accept this radio protocol OpenTXはこの送信機プロトコルを受け付けません @@ -2316,69 +2331,54 @@ To <b>remove a remembered entry</b> from the filter list, first cho - - Eeprom is not from Th9X - - EEPROMはTh9Xからのものではありません - - - - - Eeprom is not from Gruvin9X - - EEPROMはGruvin9Xからのものではありません - - - - Eeprom is not from ErSky9X - EEPROMはErSky9Xからのものではありません - - - Eeprom is not from Er9X - - EEPROMはEr9Xからのものではありません - - - + - Eeprom size is invalid - EEPROMサイズが無効です - + - Eeprom file system is invalid - EEPROMファイルシステムが無効です - + - Eeprom is from a unknown board - EEPROMは不明なボードからのものです - + - Eeprom is from the wrong board - EEPROMは間違ったボードからのものです - + - Eeprom backup not supported - EEPROMバックアップはサポートされていません - + - Something that couldn't be guessed, sorry - 推測できない問題が起きています。申し訳ありません - + Warning: 警告: - - + + - Your radio probably uses a wrong firmware, eeprom size is 4096 but only the first 2048 are used - この送信機は、おそらく間違ったファームウェアを適用しています。 EEPROMサイズは4096ですが、最初の2048しか使用されません - + - Your eeprom is from an old version of OpenTX, upgrading! To keep your original file as a backup, please choose File -> Save As specifying a different name. - このEEPROMは古いバージョンのOpenTXでアップグレードしています。 @@ -2541,22 +2541,22 @@ If blank then the input is considered to be "ON" all the time.編集 %1 - + Popup menu available 利用可能なポップアップメニュー - + Clear All すべて消去 - + Set All すべて設定 - + Invert All すべてリバース @@ -2925,282 +2925,258 @@ Blank means include all. ?, *, and [...] wildcards accepted. Firmware - + Channel values displayed in us 表示されるチャンネル値 - + No OverrideCH functions available 使用可能な上書きチャンネル機能はありません - + Possibility to enable FAI MODE (no telemetry) at field フィールドでFAIモード (テレメトリーなし) を有効にする可能性 - + FAI MODE (no telemetry) always enabled FAIモード (テレメトリーなし) を常に有効 - + Removes D8 FrSky protocol support which is not legal for use in the EU on radios sold after Jan 1st, 2015 2015/01/01以降に販売された送信機に対し、EUでの使用に適さないD8 FrSkyプロトコルサポートを削除 - + Enable non certified firmwares 認定されていないファームウェアを有効にする - - + + Disable HELI menu and cyclic mix support HELIメニューとサイクリックミックスサポートを無効にする - - + + Disable Global variables グローバル変数を無効にする - - + + Enable Lua custom scripts screen Luaカスタムスクリプト画面を有効にする - + Use alternative SQT5 font SQT5 代替フォントを使用する - + Pots use in menus navigation メニューナビゲーションでダイヤルを使用 - + FrSky Taranis X9D+ FrSky Taranis X9D+ - - Support for PPM internal module hack - PPM内部モジュールハックのサポート - - - - + + Disable RAS (SWR) RAS (SWR)を無効にする - + FrSky Taranis X9D+ 2019 - + FrSky Taranis X9D FrSky Taranis X9D - + Haptic module installed タッチパネル対応モジュールをインストール - + FrSky Taranis X9E FrSky Taranis X9E - + Confirmation before radio shutdown 送信機シャットダウン前の確認 - + Horus gimbals installed (Hall sensors) Horusジンバル (ホールセンサー) をインストール - + FrSky Taranis X9-Lite FrSky Taranis X9-Lite - + FrSky Taranis X9-Lite S - + FrSky Taranis X7 / X7S FrSky Taranis X7 / X7S - + FrSky Taranis X-Lite S/PRO FrSky Taranis X-Lite S/PRO - + FrSky Taranis X-Lite FrSky Taranis X-Lite - + FrSky Horus X10 / X10S FrSky Horus X10 / X10S - + FrSky Horus X12S FrSky Horus X12S - + Use ONLY with first DEV pcb version 初期DEV pcbバージョンでのみ使用 - - + + Support for MULTI internal module MULTI内部モジュールのサポート - - + + + Support for bluetooth module Bluetoothモジュールのサポート - + + Radiomaster TX16S / SE / Hall / Masterfire + Radiomaster TX16S / SE / Hall / Masterfire + + + + Jumper T18 + Jumper T18 + + + Turnigy 9XR-PRO Turnigy 9XR-PRO - + Enable HELI menu and cyclic mix support HELIメニューとサイクリックミックスのサポートを有効にする - + + Enable AFHDS3 support + AFHDS3サポート 有効 + + + Global variables グローバル変数 - + In model setup menus automatically set source by moving the control モデル設定メニューでは、コントローラーを動かし自動的に選択元を設定します - + In model setup menus automatically set switch by moving the control モデル設定メニューでは、コントローラーを動かし自動的にスイッチを設定します - + No graphical check boxes and sliders グラフィカルなチェックボックスとスライダーはありません - + Battery graph バッテリーグラフ - + Don't use bold font for highlighting active items 有効なアイテムを強調表示するために太字フォントを使用しない - + FrSky Taranis X7 / X7S Access FrSky Taranis X7 / X7S ACCESS - - + + Support for ACCESS internal module replacement ACCESS内部モジュール変更のサポート - - Turnigy 9XR with m128 chip - Turnigy 9XR m128チップ搭載 - - - - Turnigy 9XR - Turnigy 9XR - - - - 9X with stock board - 9X ストックボード - - - + Enable resetting values by pressing up and down at the same time 上下に同時に押し、値のリセットを有効にする - - 9X with stock board and m128 chip - 9X ストックボード+m128 chip - - - + 9X with AR9X board 9X AR9Xボード - + FrSky Horus X10 Express / X10S Express FrSky Horus X10 Express / X10S Express - + Jumper T12 / T12 Pro Jumper T12 / T12 Pro - + Jumper T16 / T16+ / T16 Pro Jumper T16 / T16+ / T16 Pro - - Radiomaster TX16s / TX16s Hall / TX16s Masterfire - Radiomaster TX16s / TX16s Hall / TX16s Masterfire - - - + Support internal GPS 内蔵GPSサポート - + 9X with Sky9x board 9X Sky9Xボード - - - 9X with Gruvin9x board - 9X Gruvin9X - - - - DIY MEGA2560 radio - DIY MEGA2560 送信機 - FirmwarePreferencesDialog @@ -3459,62 +3435,62 @@ Blank means include all. ?, *, and [...] wildcards accepted. 書き込み - + Open Firmware File FWファイルを開く - + %1 may not be a valid firmware file %1 は有効なファームウェアファイルでない可能性があります - + The firmware file is not valid. ファームウェアファイルが無効です。 - + There is no start screen image in the firmware file. ファームウェアファイルに起動画面のイメージがありません。 - + Profile image %1 is invalid. プロファイルイメージ %1 が無効です。 - + Open image file to use as radio start screen 送信機の起動画面として使用するイメージファイルを開く - + Images (%1) イメージ (%1) - + Image could not be loaded from %1 イメージを %1からロードできませんでした - + The library image could not be loaded ライブラリイメージを読み込めませんでした - + Splash image not found 起動イメージが見つかりません - + Cannot save customized firmware カスタマイズされたファームウェアを保存できません - + Write Firmware to Radio 送信機にファームウェアを書き込みます @@ -3535,27 +3511,27 @@ Blank means include all. ?, *, and [...] wildcards accepted. 新しいファームウェアは現在インストールされているものと互換性がありません! - + Conversion failed 変換に失敗しました - + Cannot convert Models and Settings for use with this firmware, original data will be used このファームウェアで使用するためにモデルと設定を変換することはできません。元のデータが使用されます - + Restore failed 復元に失敗しました - + Could not restore Models and Settings to Radio. The models and settings data file can be found at: %1 モデルと設定を送信機に復元できませんでした。モデルと設定データファイルは %1 にあります - + Flashing done 書き込み完了 @@ -3568,42 +3544,42 @@ Blank means include all. ?, *, and [...] wildcards accepted. 実行可能ファイル %1 が見つかりません - + Writing... 書き込み中... - + Reading... 読み込み中... - + Verifying... 確認中... - + unknown 不明 - + ie: OpenTX for 9X board or OpenTX for 9XR board 例: 9Xボード用のOpenTXまたは9XRボード用のOpenTX - + ie: OpenTX for M128 / 9X board or OpenTX for 9XR board with M128 chip 例: M128 / 9Xボード用のOpenTXまたはM128チップ搭載 9XRボード用のOpenTX - + ie: OpenTX for Gruvin9X board 例: Gruvin9Xボード用OpenTX - + Your radio uses a %1 CPU!!! Please check advanced burn options to set the correct cpu type. @@ -3612,7 +3588,7 @@ Please check advanced burn options to set the correct cpu type. 正しいCPUタイプを設定するには、詳細書き込みオプションを確認してください。 - + Your radio uses a %1 CPU!!! Please select an appropriate firmware type to program it. @@ -3621,7 +3597,7 @@ Please select an appropriate firmware type to program it. 適切なファームウェアタイプを選択してください。 - + You are currently using: %1 @@ -3630,22 +3606,22 @@ You are currently using: %1 - + Your radio does not seem connected to USB or the driver is not initialized!!!. お使いの送信機がUSBに接続されていないか、ドライバが初期化されていません。 - + Flashing done (exit code = %1) 書き込み完了 (終了コード= %1 ) - + Flashing done with errors エラーを含んだ書き込み完了 - + FUSES: Low=%1 High=%2 Ext=%3 FUSES: Low=%1 High=%2 Ext=%3 @@ -3791,85 +3767,115 @@ You are currently using: - + Copy コピー - + Cut 切り取り - + Paste 貼り付け - + Insert 挿入 - + Delete 削除 - + Move Up 上へ移動 - + Move Down 下へ移動 - + Clear All すべて消去 - + Clear Flight Mode. Are you sure? フライトモードを消去します。よろしいですか? - + Clear all Flight Modes. Are you sure? フライトモードをすべて消去します。よろしいですか? - + + Cut Flight Mode. Are you sure? + フライトモードを切り取ります。よろしいですか? + + + Delete Flight Mode. Are you sure? フライトモードを削除します。よろしいですか? - - Clear selected Global Variable across all Flight Modes. Are you sure? - すべてのフライトモードの選択したグローバル変数を消去します。よろしいですか? + + Clear Global Variable across all Flight Modes. Are you sure? + すべてのフライトモードのグローバル変数を消去します。よろしいですか? - + + Clear Global Variable. Are you sure? + グローバル変数を消去します。よろしいですか? + + + + Cut Global Variable across all Flight Modes. Are you sure? + すべてのフライトモードのグローバル変数を切り取ります。よろしいですか? + + + + Cut Global Variable. Are you sure? + グローバル変数を切り取ります。よろしいですか? + + + + Delete Global Variable. Are you sure? + グローバル変数を削除します。よろしいですか? + + + + Paste to selected Global Variable across all Flight Modes. Are you sure? + すべてのフライトモードで選択したグローバル変数を貼り付けます。よろしいですか? + + + Clear all Global Variables for all Flight Modes. Are you sure? すべてのフライトモードのすべてのグローバル変数を消去します。よろしいですか? - + Clear all Global Variables for this Flight Mode. Are you sure? このフライトモードのすべてのグローバル変数を消去します。よろしいですか? - + Clear 消去 @@ -3877,17 +3883,17 @@ You are currently using: FlightModesPanel - + Flight Mode %1 フライトモード %1 - + (%1) (%1) - + (default) (初期値) @@ -4167,47 +4173,47 @@ These will be relevant for all models in the same EEPROM. セットアップ - + Global Functions グローバルファンクション - + Trainer トレーナー - + Hardware ハードウェア - + Calibration 校正 - + Wrong data in profile, radio calibration was not retrieved プロファイルデータが正しくなく、送信機校正情報が取得できませんでした - + Wrong data in profile, Switch/pot config not retrieved プロファイルデータが正しくなく、スイッチ/ダイヤル構成が取得できませんでした - + Wrong data in profile, hw related parameters were not retrieved プロファイルデータが正しくなく、HW関連パラメーターが取得できませんでした - + Do you want to store calibration in %1 profile<br>overwriting existing calibration? 既存の校正情報を上書きして %1 プロファイルに校正情報を保存しますか? - + Calibration and HW parameters saved. 校正情報とHWパラメータが保存されました。 @@ -4215,7 +4221,7 @@ These will be relevant for all models in the same EEPROM. GeneralSettings - + Radio Settings 送信機設定 @@ -4273,161 +4279,161 @@ These will be relevant for all models in the same EEPROM. SG - + Stick reverse スティック リバース - + Country Code 地域 - + If you enable FAI, only RSSI and RxBt sensors will keep working. This function cannot be disabled by the radio. FAIを有効にすると、RSSIとRxBtセンサーのみが機能し続けます。この機能を送信機側で無効にすることはできません。 - + FAI Mode FAIモード - + Automatically adjust the radio's clock if a GPS is connected to telemetry. GPSがテレメトリーに接続されている場合、自動的に送信機側の内蔵時計を調整します。 - + Adjust RTC 時計調整 - + Speaker Volume スピーカー音量 - - + + Hz Hz - + Vario pitch at max バリオピッチ 最大 - + Backlight Switch バックライトスイッチ - + Color 1 カラー 1 - + Color 2 カラー 2 - + Sound Mode サウンドモード - + If this value is not 0, any keypress will turn on the backlight and turn it off after the specified number of seconds. この値が0以外の場合、キーを押すとバックライトが点灯し、指定秒数を経過すると消灯します。 - - - + + + sec - + Backlight color バックライトカラー - + Speaker Pitch (spkr only) 再生ピッチ (対応機のみ) - + Beeper ビープ - + Speaker スピーカー - + BeeperVoice ビープ音声 - + SpeakerVoice スピーカー音声 - + Beep volume ビープ音量 - + Wav volume WAV音量 - + Vario volume バリオVOL - + Background volume バックグランドVOL - - + + ms ms - + Backlight flash on alarm アラーム時ライト点滅 - + Vario pitch at zero バリオピッチ ゼロ - + Vario repeat at zero バリオリピート ゼロ - + Backlight Auto OFF after バックライト 自動消灯 - + This is the switch selectrion for turning on the backlight (if installed). @@ -4436,8 +4442,8 @@ These will be relevant for all models in the same EEPROM. - - + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } @@ -4452,49 +4458,49 @@ p, li { white-space: pre-wrap; } <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">値は20~45です</span></p></body></html> - + RotEnc Navigation Rot Enc ナビゲーション - + Backlight Brightness バックライト 明るさ - + America アメリカ - + Japan 日本 - + Europe ヨーロッパ - + Voice Language 音声言語 - + Timeshift from UTC UTC 時差 - + Backlight OFF Brightness バックライトOFF 明るさ - - - + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } @@ -4519,12 +4525,12 @@ p, li { white-space: pre-wrap; } <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">サイレントモード警告 - ビープ音が消音(0)に設定されていると警告します</p></body></html> - + RSSI Poweroff Warning RSSI 信号切断 警告 - + Beeper volume 0 - Quiet. No beeps at all. @@ -4541,221 +4547,221 @@ p, li { white-space: pre-wrap; } 4 - より大きい音量。 - - + + Quiet 消音 - + Alarms Only アラームのみ - - + + No Keys キーなし - - + + All すべて - + Beeper Mode ビープ モード - + Jack Mode Jackモード - + Audio 音声 - + Trainer トレーナー - - + + X-Short より短い - - + + Short 短い - - + + Normal 通常 - - + + Long 長い - - + + X-Long より長い - + Beeper Length ビープ音の長さ - + Haptic Mode タッチパネルモード - + Measurement Units 計量単位 - + Play Delay (switch mid position) 遅延動作 (スイッチ中央) - + NMEA - + 4800 Baud - + 9600 Baud - + 14400 Baud - + 19200 Baud - + 38400 Baud - + 57600 Baud - + 76800 Baud - + 115200 Baud - - + + Show splash screen on startup 起動時、起動イメージ表示 - + nnnnnnNN nnnnnnNN - + Power On Delay 起動時間 - + --- --- - + 2s 2秒 - + 3s 3秒 - + 4s 4秒 - + 6s 6秒 - + 8s 8秒 - + 10s 10秒 - + 15s 15秒 - + If not zero will sound beeps if the transmitter has been left without inputs for the specified number of minutes. 指定された時間(分)入力がないまま送信機が放置されると、ゼロでない場合はビープ音が鳴ります。 - + min - + Standard 標準 - + Optrex オプトレックス(京セラ) - + Battery warning voltage. This is the threashhold where the battery warning sounds. @@ -4765,243 +4771,248 @@ Acceptable values are 5v..10v 許容値は5~10vです - + Only Alarms アラームのみ - + MAVLink Baud Rate MAVLink ボーレート - + Haptic Length タッチパネル長押し - + Battery Warning バッテリー警告 - + "No Sound" Warning 【無音】警告 - + LCD Display Type 液晶ディスプレイタイプ - + Haptic Strength タッチパネル感度 - + Battery Meter Range バッテリーメーター範囲 - + Contrast コントラスト - + Show Splash Screen on Startup 起動時、起動イメージ表示 - + Low EEPROM Warning EEPROM残量警告 - + Inactivity Timer 非アクティブタイマー - + Min 最小 - - + + v v - + Max 最大 - + GPS Coordinates GPS座標 - + Default Channel Order 初期チャンネルマップ - + Metric メートル法 - + Imperial ヤード・ポンド法 - + Stick Mode スティックモード - + <html><head/><body><p>Channel order</p><p><br/></p><p>Defines the order of the default mixes created on a new model.</p></body></html> <html><head/><body><p>チャンネルマップ</p><p><br/></p><p>モデル作成された際の初期チャンネルマッピングを定義します</p></body></html> - + Owner Registration ID オーナー登録ID - + + Keys Backlight + キー バックライト + + + R E T A ↔RUD ↕ELE ↕THR ↔AIL [R E T A] - + R E A T ↔RUD ↕ELE ↔AIL ↕THR [R E A T] - + R T E A ↔RUD ↕THR ↕ELE ↔AIL [R T E A] - + R T A E ↔RUD ↕THR ↔AIL ↕ELE [R T A E] - + R A E T ↔RUD ↔AIL ↕ELE ↕THR [R A E T] - + R A T E ↔RUD ↔AIL ↕THR ↕ELE [R A T E] - + E R T A ↕ELE ↔RUD ↕THR ↔AIL [E R T A] - + E R A T ↕ELE ↔RUD ↔AIL ↕THR [E R A T] - + E T R A ↕ELE ↕THR ↔RUD ↔AIL [E T R A] - + E T A R ↕ELE ↕THR ↔AIL ↔RUD [E T A R] - + E A R T ↕ELE ↔AIL ↔RUD ↕THR [E A R T] - + E A T R ↕ELE ↔AIL ↕THR ↔RUD [E A T R] - + T R E A ↕THR ↔RUD ↕ELE ↔AIL [T R E A] - + T R A E ↕THR ↔RUD ↔AIL ↕ELE [T R A E] - + T E R A ↕THR ↕ELE ↔RUD ↔AIL [T E R A] - + T E A R ↕THR ↕ELE ↔AIL ↔RUD [T E A R] - + T A R E ↕THR ↔AIL ↔RUD ↕ELE [T A R E] - + T A E R ↕THR ↔AIL ↕ELE ↔RUD [T A E R] - + A R E T ↔AIL ↔RUD ↕ELE ↕THR [A R E T] - + A R T E ↔AIL ↔RUD ↕THR ↕ELE [A R T E] - + A E R T ↔AIL ↕ELE ↔RUD ↕THR [A E R T] - + A E T R ↔AIL ↕ELE ↕THR ↔RUD [A E T R] - + A T R E ↔AIL ↕THR ↔RUD ↕ELE [A T R E] - + A T E R ↔AIL ↕THR ↕ELE ↔RUD [A T E R] - + Power Off Delay 終了時間 - + Mode selection: Mode 1: @@ -5042,53 +5053,53 @@ Mode 4: - + Mode 1 (RUD ELE THR AIL) モード1 (左:エレベーター・ラダー 右:スロットル・エルロン) - + Mode 2 (RUD THR ELE AIL) モード2 (左:スロットル・ラダー 右:エレベーター・エルロン) - + Mode 3 (AIL ELE THR RUD) モード3 (左:エレベーター・エルロン 右:スロットル・ラダー) - + Mode 4 (AIL THR ELE RUD) モード4 (左:スロットル・エルロン 右:エレベーター・ラダー) - + DMS - + USB Mode USBモード - - + + Ask on Connect 接続毎に確認 - + Joystick (HID) ジョイスティック (HID) - + USB Mass Storage USBストレージ - + USB Serial (CDC) USBシリアル (CDC) @@ -5096,127 +5107,127 @@ Mode 4: GeneralSetupPanel - + OFF OFF - + Keys キー - + Sticks スティック - + Keys + Sticks キー+スティック - + ON ON - + English - + Dutch - + French - + Italian - + German - + Czech - + Slovak - + Spanish - + Polish - + Portuguese - + Russian - + Swedish - + Hungarian - + No いいえ - + RotEnc A Rot Enc A - + Rot Enc B - + Rot Enc C - + Rot Enc D - + Rot Enc E - + If you enable FAI, only RSSI and RxBt sensors will keep working. This function cannot be disabled by the radio. Are you sure ? @@ -5748,9 +5759,14 @@ Are you sure ? 入力項目が不足しています! - - Delete selected Inputs. Are you sure? - 選択した入力項目を削除します。よろしいですか? + + Delete selected Input lines. Are you sure? + 選択したInput行を削除します。よろしいですか? + + + + Cut selected Input lines. Are you sure? + 選択したInput行を切り取ります。よろしいですか? @@ -5850,18 +5866,18 @@ Are you sure ? - Clear all Inputs. Are you sure? - すべての入力項目を消去します。よろしいですか? + Clear all Input lines. Are you sure? + すべてのInput行を消去します。よろしいですか? - Clear Input. Are you sure? - 入力項目を消去します。よろしいですか? + Clear all lines for the selected Inputs. Are you sure? + 選択したすべてのInput行を消去します。よろしいですか? - Delete Input. Are you sure? - 入力項目を削除します。よろしいですか? + Delete all lines for the selected Inputs. Are you sure? + 選択したすべてのInput行を削除します。よろしいですか? @@ -6061,57 +6077,67 @@ Are you sure ? (無制限) - + Delete Logical Switch. Are you sure? 論理スイッチを削除します。よろしいですか? - + + Cut Logical Switch. Are you sure? + 論理スイッチを切り取ります。よろしいですか? + + + Copy コピー - + Cut 切り取り - + Paste 貼り付け - + Clear 消去 - + Insert 挿入 - + Delete 削除 - + Move Up 上へ移動 - + Move Down 下へ移動 - + Clear All すべて消去 - + + Clear Logical Switch. Are you sure? + 論理スイッチを消去します。よろしいですか? + + + Clear all Logical Switches. Are you sure? 論理スイッチをすべて消去します。よろしいですか? @@ -6293,123 +6319,123 @@ The columns for altitude "GAlt" and for speed "GSpd" are opt MainWindow - + Diskimage (*.dmg) ディスクイメージ (*.dmg) - + Would you like to open the disk image to install the new version? 新しいバージョンをインストールするためにディスクイメージを開きますか? - + Executable (*.exe) 実行ファイル (*.exe) - - + + Would you like to launch the installer? インストーラを起動しますか? - - + + File loaded ファイルがロードされました - + Checking for updates アップデートの確認 - + A new version of Companion is available (version %1)<br>Would you like to download it? Companionの新しいバージョンがあります。 (version %1)<br>ダウンロードしますか? - - + + Save As 名前を付けて保存 - + New release available 新リリースが利用可能 - + A new release of Companion is available, please check the <a href='%1'>OpenTX website!</a> Companionの新リリースが利用可能です。<a href='%1'>OpenTX Webサイト</a>をチェックしてください - - + + No updates available at this time. 現時点で利用可能なアップデートはありません。 - + Error opening file %1: %2. ファイル %1 を開くときにエラーが発生しました: %2. - + Not enough flash available on this board for all the selected options 選択されたすべてのオプションに対してこのボードでは十分な書き込みが行えません - + Compilation server temporary failure, try later コンパイルサーバが一時的に失敗しました。後程お試しください - + Compilation server too busy, try later コンパイルサーバがビジー状態です。後程お試しください - + Compilation error コンパイルエラー - + Invalid firmware 無効なファームウェア - + Invalid board 無効なボード - + Invalid language 無効な言語 - + Unknown server failure, try later 不明なサーバの障害です。後程お試しください - + Do you want to write the firmware to the radio now ? 今すぐファームウェアを送信機に書き込みますか? - + Firmware update check failed, new version information not found or invalid. ファームウェアアップデートの確認に失敗しました。新しいバージョン情報が見つからないか、または無効です。 - + Firmware %1 does not seem to have ever been downloaded. Version %2 is available. Do you want to download it now? @@ -6422,31 +6448,31 @@ We recommend you view the release notes using the button below to learn about an 重要な変更については、下のボタンをクリックしてリリースノートを参照することをお勧めします。 - - + + Yes はい - - + + No いいえ - - + + Release Notes リリースノート - - + + Do you want to download version %1 now ? 今すぐバージョン %1 をダウンロードしますか? - + A new version of %1 firmware is available: - current is %2 - newer is %3 @@ -6463,29 +6489,29 @@ We recommend you view the release notes using the button below to learn about an 重要な変更については、下のボタンをクリックしてリリースノートを参照することをお勧めします。 - + Ignore this version %1? このバージョン %1 を無視しますか? - + The new theme will be loaded the next time you start Companion. 次回Companionを起動したときに、新しいテーマがロードされます。 - - + + Open Models and Settings file 機体モデルと設定ファイルを開く - - + + File saved ファイル 保存 - + There are unsaved file changes which you may lose when switching radio types. Do you wish to continue? @@ -6494,780 +6520,760 @@ Do you wish to continue? そのまま続けますか? - - + + Synchronize SD SDカードを同期する - + No local SD structure path configured! SDカード保存先パスが設定されていません! - + No Companion release candidates are currently being served for this version, please switch release channel 現在このバージョンのCompanion RC版は提供されていません。リリース状態を切り替えてください - + No nightly Companion builds are currently being served for this version, please switch release channel 現在、このバージョンのCompanion ナイトリービルド版は提供されていません。リリース状態を切り替えてください - + No Companion release builds are currently being served for this version, please switch release channel このバージョンのCompanion リリース版は現在提供されていません。リリース状態を切り替えてください - + Companion update check failed, new version information not found. Companionアップデートの確認に失敗しました。新しいバージョン情報が見つかりません。 - + No firmware release candidates are currently being served for this version, please switch release channel 現在、このバージョンのファームウェア RC版は提供されていません。リリース状態を切り替えてください - + No firmware nightly builds are currently being served for this version, please switch release channel 現在、このバージョンのファームウェア ナイトリービルド版は提供されていません。リリース状態を切り替えてください - + No firmware release builds are currently being served for this version, please switch release channel 現在、このバージョンのファームウェア リリース版は提供されていません。リリース状態を切り替えてください - + Release candidate builds are now available for this version, would you like to switch to using them? RC版はこのバージョンで利用可能になりました。それらに切り替えますか? - + Channel changed to RC, please restart the download process リリース状態をRC版に変更しました。ダウンロードプロセスを再起動してください - + Official release builds are now available for this version, would you like to switch to using them? このバージョンの公式リリース版が利用可能になりました。それらに切り替えますか? - + Channel changed to Release, please restart the download process リリース状態をリリース版に変更しました。ダウンロードプロセスを再起動してください - + This radio (%1) is not currently available in this firmware release channel この送信機 (%1) は、現在このファームウェアリリース状態では利用できません - + No Radio or SD card detected! 送信機またはSDカードが検出されませんでした! - + Local Folder ローカルフォルダ - + Radio Folder 送信機フォルダ - - + + Read Firmware from Radio 送信機からファームウェアを読み込み - - + + Read Models and Settings from Radio 送信機から機体モデルや設定を読み込み - + Models and Settings read 機体モデルと設定の読み込み - - + + This function is not yet implemented この機能はまだ実装されていません - + Save Radio Backup to File 送信機のバックアップをファイルに保存 - + Read Radio Firmware to File 送信機ファームウェアからファイルへの読み込み - + OpenTX Home Page: <a href='%1'>%1</a> OpenTX ホームページ: <a href='%1'>%1</a> - + The OpenTX Companion project was originally forked from <a href='%1'>eePe</a> OpenTX Companionプロジェクトは元々<a href='%1'>eePe</a>から派生しました - + If you've found this program useful, please support by <a href='%1'>donating</a> このプログラムが役に立つと感じた場合は、<a href='%1'>寄付</a>でのサポートをお願いします - + Copyright OpenTX Team Copyright OpenTX Team - + About Companion Companionについて - + OpenTX Companion %1 - Radio: %2 - Profile: %3 OpenTX Companion %1 - 送信機: %2 - プロファイル: %3 - + New 新規 - + Create a new Models and Settings file 新規モデルと設定ファイルを作成します - + Open... 開く... - + Save 保存 - - + + Save Models and Settings file 機体モデルと設定ファイルを保存します - + Save As... 名前を付けて保存... - + Close 閉じる - + Close Models and Settings file 機体モデルと設定ファイルを閉じます - + Exit 終了 - + Exit the application アプリケーションを終了します - + About... バージョン情報... - + Show the application's About box アプリケーションのバージョン情報を表示します - + Recent Files 最近使用したファイル - + List of recently used files 最近使用したファイルを一覧表示 - + Radio Profiles 送信機プロファイル - + Create or Select Radio Profiles 送信機プロファイルを作成または選択します - + View Log File... ログファイルを表示... - + Open and view log file ログファイルを開いて表示します - + Settings... 設定... - + Edit Settings 設定を編集します - + Download... ダウンロード... - + Download firmware and voice files ファームウェアと音声ファイルをダウンロードします - + Check for Updates... アップデートのチェック... - + Check OpenTX and Companion updates OpenTXとCompanionのアップデートを確認します - + Release notes... リリースノート... - + Show release notes リリースノートを表示します - + Compare Models... 機体モデルを比較... - + Compare models 機体モデルを比較します - + Edit Radio Splash Image... 送信機の起動イメージを編集... - + Edit the splash image of your Radio 送信機の起動イメージを編集します - - List programmers... - プログラムを一覧表示... - - - - List available programmers - 利用可能なプログラムを一覧表示します - - - - Fuses... - ヒューズ... - - - - Show fuses dialog - ヒューズダイアログを表示します - - - + Read firmware from Radio 送信機からファームウェアを読み込み - + Write Firmware to Radio 送信機にファームウェアを書き込み - + Write firmware to Radio 送信機にファームウェアを書き込み - + SD card synchronization SDカードの同期 - + Manuals and other Documents マニュアルと他の文書 - + Open the OpenTX document page in a web browser WebブラウザでOpenTXドキュメントページを開く - + Write Models and Settings To Radio 機体モデルと設定を送信機に書き込み - + Write Models and Settings to Radio 機体モデルと設定を送信機に書き込み - + Read Models and Settings From Radio 送信機から機体モデルや設定を読み込み - + Configure Communications... 送信機疎通を設定... - + Configure software for communicating with the Radio 送信機と疎通するためのソフトウェアを設定します - + Write Backup to Radio 送信機からバックアップを書き出す - + Write Backup from file to Radio 送信機ファイルからバックアップを書き出します - + Backup Radio to File ファイルを送信機にバックアップ - + Save a complete backup file of all settings and model data in the Radio すべての設定とモデルデータの完全なバックアップファイルを送信機に保存します - + Contributors... 貢献者... - + A tribute to those who have contributed to OpenTX and Companion OpenTXとCompanionに貢献した人々への賛辞 - + Add Radio Profile 送信機プロファイルの追加 - + Create a new Radio Settings Profile 新しい送信機設定プロファイルを作成します - + Copy Current Radio Profile 現在の送信機プロファイルをコピー - + Duplicate current Radio Settings Profile 現在の送信機設定プロファイルを複製します - + Delete Current Radio Profile... 現在の送信機プロファイルを削除... - + Delete the current Radio Settings Profile 現在の送信機設定プロファイルを削除します - + Export Application Settings.. アプリケーション設定のエクスポート.. - + Save all the current %1 and Simulator settings (including radio profiles) to a file. 現在のすべての%1およびシミュレータ設定(送信機プロファイル含)をファイルに保存します。 - + Import Application Settings.. アプリケーション設定をインポート.. - + Load %1 and Simulator settings from a prevously exported settings file. 以前にエクスポートした設定ファイルから%1とシミュレーション設定を読み込みます。 - + Tabbed Windows タブ付きウィンドウ - + Use tabs to arrange open windows. 開いているウィンドウを並べ替えるのにタブを使用します。 - + Tile Windows ウィンドウのタイトル - + Arrange open windows across all the available space. 利用可能なすべてのスペースに開いているウィンドウを配置します。 - + Cascade Windows ウィンドウを重ねる - + Arrange all open windows in a stack. 開いているウィンドウをすべて重ねて配置します。 - + Close All Windows すべてのウィンドウを閉じる - + Closes all open files (prompts to save if necessary. 開いているファイルをすべて閉じます (必要に応じ保存を求められます)。 - - + + Edit 編集 - - + + File ファイル - + Settings 設定 - + Set Icon Theme アイコンテーマ設定 - + Set Icon Size アイコンサイズ設定 - + Read/Write 読み込み/書き込み - + Window ウィンドウ - - + + Help ヘルプ - + Write 書き込み - + Some text will not be translated until the next time you start Companion. Please note that some translations may not be complete. 次にCompanionを起動するまで一部のテキストは翻訳されません。いくつかの翻訳は完全ではないかもしれませんのでご注意ください。 - + Ctrl+Shift+S - + Ctrl+Alt+L - + Ctrl+Alt+D - + Ctrl+Alt+R - + Classical クラシック - + The classic companion9x icon theme クラシック Companion9x アイコンテーマ - + Yerico イェリコ - + Yellow round honey sweet icon theme Yellow round honey sweet アイコンテーマ - + Monochrome モノクローム - + A monochrome black icon theme A monochrome black アイコンテーマ - + MonoBlue モノブルー - + A monochrome blue icon theme A monochrome blue アイコンテーマ - + MonoWhite モノホワイト - + A monochrome white icon theme A monochrome white アイコンテーマ - + Small 小サイズ - + Use small toolbar icons 小サイズのツールバーアイコンを使用 - + Normal 標準サイズ - + Use normal size toolbar icons 標準サイズのツールバーアイコンを使用 - + Big 大サイズ - + Use big toolbar icons 大サイズのツールバーアイコンを使用 - + Huge 特大サイズ - + Use huge toolbar icons 特大サイズのツールバーアイコンを使用 - + Set Menu Language メニュー言語を設定 - + System language システム言語 - + Use default system language. デフォルトのシステム言語を使用します。 - + Use %1 language (some translations may not be complete). %1言語を使用します (一部の翻訳が不完全な場合あり)。 - + Ready 準備完了 - + %2 %2 - + Alt+%1 - + New Radio 新規 送信機 - + - Copy - コピー - + Companion :: Open files warning Companion :: ファイルを開くときの警告 - + Please save or close modified file(s) before deleting the active profile. 有効なプロファイルを削除する前に、変更したファイルを保存するか閉じてください。 - + Not possible to remove profile プロファイルを削除できません - + The default profile can not be removed. デフォルトプロファイルは削除できません。 - + Confirm Delete Profile プロファイル削除の確認 - + Are you sure you wish to delete the "%1" radio profile? There is no way to undo this action! 『%1』送信機プロファイルを削除してもよろしいですか?この操作を元に戻すことはできません! - + Please save or close all modified files before importing settings 設定をインポートする前に、変更したファイルをすべて保存するか閉じてください - + <html><p>%1 and Simulator settings can be imported (restored) from a previosly saved export (backup) file. This will replace current settings with any settings found in the file.</p><p>An automatic backup of the current settings will be attempted. But if the current settings are useful then it is recommended that you make a manual backup first.</p><p>For best results when importing settings, <b>close any other %1 windows you may have open, and make sure the standalone Simulator application is not running.</p><p>Do you wish to continue?</p></html> <html><p>%1とシミュレータの設定は、以前に保存したエクスポート(バックアップ)ファイルからインポート(復元)できます。これにより、現在の設定がファイル内の設定に置き換えられます。</p><p>現在の設定の自動バックアップが実行されます。ただし、現在の設定が便利な場合は、まず手動バックアップを作成することをお勧めします。</p><p>設定をインポートし最良の結果を得るには、<b>開いている%1ウィンドウをすべて閉じます。スタンドアロンのシミュレーターアプリケーションが実行されていません。</p><p>続行しますか?</p></html> - + Confirm Settings Import 設定のインポートの確認 - + Select %1: %1を選択: - + backup バックアップ - + Press the 'Ignore' button to continue anyway. とにかく続行するには『無視』ボタンを押してください。 - + The settings could not be imported. 設定をインポートできませんでした。 - + <html><p>New settings have been imported from:<br> %1.</p><p>%2 will now re-initialize.</p><p>Note that you may need to close and restart %2 before some settings like language and icon theme take effect.</p> <html><p>新しい設定は次の場所からインポートされました。<br>%1.</p><p>%2は再初期化されます。</p><p>場合によっては閉じて再起動する必要があります。言語やアイコンテーマなどの設定が有効になる前に%2が発生しました。</p> - + <p>The previous settings were backed up to:<br> %1</p> <p>以前の設定は次の場所にバックアップされました:<br> %1</p> @@ -7918,25 +7924,25 @@ If blank then the mix is considered to be "ON" all the time. MixesPanel - + Move Up 上へ移動 - + Ctrl+Up - + Move Down 下へ移動 - + Ctrl+Down @@ -7951,97 +7957,102 @@ If blank then the mix is considered to be "ON" all the time. ミキサー項目が足りません! - - Delete Selected Mixes? - 選択したミキサーを削除しますか? + + Delete selected Mix lines. Are you sure? + 選択したMix行を削除します。よろしいですか? - + + Cut selected Mix lines. Are you sure? + 選択したMix行を切り取ります。よろしいですか? + + + &Add &追加 - + Ctrl+A - + &Edit &編集 - + Enter Enter - + &Toggle highlight &ハイライト切替 - + Ctrl+T - + &Delete &削除 - + Delete 削除 - + &Copy &コピー - + Ctrl+C - + C&ut &切り取り - + Ctrl+X - + &Paste &貼り付け - + Ctrl+V - + Du&plicate &複製 - + Ctrl+U - + Clear Mixes? ミキサーを消去しますか? - + Really clear all the mixes? すべてのミキサーを本当に消去しますか? @@ -8049,12 +8060,12 @@ If blank then the mix is considered to be "ON" all the time. ModelData - + Model: 機体モデル: - + Throttle Source スロットル値 @@ -8171,9 +8182,9 @@ If blank then the mix is considered to be "ON" all the time. - - - + + + OFF OFF @@ -8214,7 +8225,7 @@ If blank then the mix is considered to be "ON" all the time. - + Mode モード @@ -8248,14 +8259,14 @@ If blank then the mix is considered to be "ON" all the time. - - + + Delay 遅延 - + Receiver 受信機 @@ -8281,628 +8292,639 @@ If blank then the mix is considered to be "ON" all the time. + RF Output Power 送信出力 - + + Output Type + 出力タイプ + + + + RX Output Frequency + 受信出力周波数 + + + Master/Jack マスター/Jack - + Slave/Jack スレーブ/Jack - + Master/SBUS Module マスター/SBUSモジュール - + Master/CPPM Module マスター/CPPMモジュール - + Master/SBUS in battery compartment マスター/バッテリーカバー内SBUB - + 90 90 - + 120 120 - + 120X 120X - + 140 140 - + Off OFF - - - - - - + + + + + + None なし - + Name 名称 - + Countdown カウントダウン - + Minute call 音声時報 - + Persistent 持続 - - - + + + FM%1 - + FM%1%2 - + FM%1+%2 - - + + Weight ウェイト - - + + Switch スイッチ - - + + NoTrim トリムなし - + Offset(%1) オフセット(%1) - + MULT! 複数! - + No DR/Expo DR/Expoなし - - + + Offset オフセット - + Slow ゆっくり - + Warn 警告 - + Disabled in all flight modes すべてのフライトモードを無効 - + Flight modes フライトモード - + Flight mode フライトモード - + All すべて - + Edge Edge:端 - + instant 簡易 - + Sticky Sticky:追尾 - + Timer タイマー - + missing 間違い - + Duration 期間 - - - + + + Custom カスタム - + Standard 標準 - + Extended Limits 拡張制限 - + Display Checklist ディスプレイ チェックリスト - + Global Functions グローバルファンクション - + Manual 手動 - + Auto 自動 - + Failsafe Mode フェイルセーフモード - - + + Hold ホールド - + No Pulse パルスなし - + Not set セットなし - + No pulses パルスなし - + Silent 消音 - + Beeps ビープ - + Voice 音声 - + Haptic タッチパネル - + Flight フライト - + Manual reset 手動リセット - + Step ステップ - + Display ディスプレイ - + Extended 拡張 - + Never なし - + On Change 変更 - + Always 常に - - - + + + Source 選択元 - + Trim idle only トリムアイドルのみ - + Warning 警告 - + Reversed リバース - + Tmr Tmr - + FrSky S.PORT - + FrSky D - + FrSky D (cable) - + Alti - + Alti+ - + VSpeed - - - + + + A1 - - - + + + A2 - - + + A3 - - + + A4 - - + + FAS - + Cells セル - + Calculated 計算値 - + Add 追加 - + Average 平均 - - + + Min 最小 - - + + Max 最大 - + Multiply 乗算 - + Totalise 合計 - + Cell セル - + Consumption 消費 - + Distance 距離 - + Lowest より低く - + Cell %1 セル %1 - + Highest より高く - + Delta 差分 - + Formula 定式 - - + + Id - + Instance インスタンス - - - - + + + + Sensor センサー - - + + Sources 選択元 - - + + GPS GPS - + Alt. Alt. - - + + Blades ブレード - + Multi. マルチ. - + F - + Inst - + Alt - + Unit - + Prec 精度 - + Ratio レシオ - + Multi マルチ - + A/Offset A/オフセット - + Filter フィルタ - + Persist 持続 - + Positive ノーマル - + Log ログ - + Numbers ナンバー - + Bars バー - + Script スクリプト - + Filename ファイル名 - + Error: Unable to open or read file! エラー: ファイルを開けないか、読み取れません! @@ -8943,245 +8965,255 @@ If blank then the mix is considered to be "ON" all the time. スタート - + CH - + Receiver No. 受信機 No. - + Polarity 極性 - + Negative リバース - + Positive ノーマル - + RF Output Power 送信出力 - + Receiver 1 受信機 1 - - - + + + X X - + Receiver 2 受信機 2 - + Receiver 3 受信機 3 - + Low Power 低パワー - + WARNING: changing RF Output Power needs RE-BIND 警告: 送信出力を変更するには再バインドが必要です - + Channels チャンネル - + PPM delay PPM 遅延 - + us - + PPM Frame Length PPM フレーム長 - + ms ms - + Antenna アンテナ - + Output type 出力タイプ - + Open Drain オープン ドレン - + Push Pull プッシュ プル - + Option value オプション値 - + + RX Frequency + 受信周波数 + + + + Hz + Hz + + + Protocol プロトコル - + Registration ID 登録ID - + Multi Radio Protocol マルチプロトコル - + Sub Type サブタイプ - + Failsafe Mode フェイルセーフモード - + Not set 設定なし - + Hold ホールド - + Custom カスタム - + No Pulses パルスなし - + Receiver 受信機 - + Trainer Mode トレーナーモード - + Master/Jack マスター/Jack - + Slave/Jack スレーブ/Jack - + Master/SBUS Module マスター/SBUSモジュール - + Master/CPPM Module マスター/CPPMモジュール - + Master/SBUS in battery compartment マスター/バッテリーカバー内SBUB - + WARNING: Requires non-certified firmware! 警告: 未認定のR9Mファームウェアが必要です! - + Master/Bluetooth マスター/Bluetooth - + Slave/Bluetooth スレーブ/Bluetooth - + Master/Multi マスター/Multi - + Disable Telemetry テレメトリー無効 - + Disable Ch. Map チャンネルマップ無効 - + Failsafe Positions フェイルセーフポジション - + Show values in: 値の表示: - + % abbreviation for percent - + μs abbreviation for microseconds @@ -9190,85 +9222,110 @@ If blank then the mix is considered to be "ON" all the time. ModuleData - + Trainer Port トレーナーポート - + Internal Radio System 内部送信システム - + External Radio Module 外部送信モジュール - + Extra Radio System 追加送信システム - + Radio System 送信システム - + 10mW - 16CH - - + + 100mW - 16CH - + 500mW - 16CH - + Auto <= 1W - 16CH - - + + 25mW - 8CH - - + + 25mW - 16CH - + 200mW - 16CH (no telemetry) 200mW - 16CH (テレメトリーなし) - + 500mW - 16CH (no telemetry) 500mW - 16CH (テレメトリーなし) - + 100mW - 16CH (no telemetry) 100mW - 16CH (テレメトリーなし) - + + 25 mW + 25 mW + + + + 100 mW + 100 mW + + + + 500 mW + 500 mW + + + + 1 W + 1 W + + + + 2 W + 2 W + + + Positive ノーマル - + Negative リバース @@ -9276,47 +9333,42 @@ If blank then the mix is considered to be "ON" all the time. ModulePanel - + Value - + Hold ホールド - + No Pulse パルスなし - + Ask 確認 - + Internal 内部 - + Internal + External 内部 + 外部 - + External 外部 - - Autodetect Format - フォーマット自動検出 - - - + Bind on channel チャンネルへバインド @@ -9330,442 +9382,390 @@ If blank then the mix is considered to be "ON" all the time. - - + + Name 名称 - + EEprom Size EEPROMサイズ - + Model Image モデルイメージ - + Throttle スロットル - + Trims トリム - + Center Beep センター ビープ - + Switch Warnings スイッチ警告 - + Pot Warnings ダイヤル警告 - + Other その他 - + Timers タイマー - + Time 時間 - - + + Switch スイッチ - + Countdown カウントダウン - + Min.call 音声時報 - + Persist 持続 - + Modules モジュール - + Trainer port トレーナーポート - + Helicopter ヘリコプター - + Swash Swash - - + + Type タイプ - + Ring リング - + Input 入力 - + Weight ウェイト - + Long. cyc 長周期 - + Lateral cyc 側面周期 - + Collective コレクティブ - + Flight modes フライトモード - - + + Flight mode フライトモード - + F.In F.In - + F.Out F.Out - + Global vars グローバル変数 - - + + GV%1 GV%1 - + RE%1 RE%1 - - + Unit ユニット - + Prec 精度 - - + + Min 最小 - - + + Max 最大 - + Popup ポップアップ - + Outputs 出力 - + Channel チャンネル - + Subtrim サブトリム - + Direct ダイレクト - + Curve カーブ - + PPM PPM - + Linear 線形 - + Global Variables グローバル変数 - + Inputs 入力 - + Mixers ミキサー - + Curves カーブ - + L%1 L%1 - + Logical Switches 論理スイッチ - + SF%1 SF%1 - + Special Functions スペシャルファンクション - + Telemetry テレメトリー - - Analogs - アナログ - - - - Scale - スケール - - - - Offset - オフセット - - - + Protocol プロトコル - + RSSI Alarms RSSIアラーム - + Low - + Critical クリティカル - + Telemetry audio テレメトリー音源 - + Altimetry 高度計 - - + + Vario source バリオ 元値 - + Vario limits > バリオ リミット値 > - + Sink max Sink 最大 - + Sink min Sink 最小 - + Climb min クライム 最小 - + Climb max クライム 最大 - + Center silent センター サイレント - + Top Bar トップバー - - + Volts source ボルト 元値 - + Altitude source 高度 元値 - - Various - その他の設定 - - - - Serial protocol - シリアル プロトコル - - - - FAS offset - FAS オフセット - - - - mAh count - mAh カウント - - - - Persistent mAh - 持続 mAh - - - - Current source - 現在の元値 - - - - Blades - ブレード - - - + Parameters パラメータ - + Telemetry Sensors テレメトリーセンサー - + Telemetry Screens テレメトリースクリーン - + GF%1 GF%1 - + Global Functions グローバルファンクション - + Checklist チェックリスト @@ -9789,13 +9789,13 @@ If blank then the mix is considered to be "ON" all the time. - Telemetry - テレメトリー + RF power + 送信出力 - Radio output power - 送信機 送信出力 + Telemetry + テレメトリー @@ -9844,22 +9844,22 @@ If blank then the mix is considered to be "ON" all the time. OpenTxEepromInterface - + Unknown error 不明のエラー - + ... plus %1 errors ...追加 %1 エラー - + Cannot write radio settings 送信機設定を書き込めません - + Cannot write model %1 機体モデル %1 を書き込めません @@ -10126,25 +10126,20 @@ If blank then the mix is considered to be "ON" all the time. RadioInterface - + Cannot write file %1: %2. ファイルを書き込めません %1: %2. - - <b><u>WARNING!</u></b><br>This will reset the fuses of %1 to the factory settings.<br>Writing fuses can mess up your radio.<br>Do this only if you are sure they are wrong!<br>Are you sure you want to continue? - <b><u>WARNING!</u></b><br>これにより %1 のヒューズが工場出荷時の設定にリセットされます。<br>ヒューズを作成すると送信機が故障する可能性があります。<br>操作が間違っているかと思います!<br>本当に続行しても宜しいですか? - - - - + + Could not delete temporary file: %1 一時ファイルを削除できませんでした: %1 - + Unable to find radio SD card! 送信機のSDカードが見つかりません! @@ -10287,439 +10282,131 @@ X RawSource - - - - + V V - - - - + + s s - - ft - - - - - - m - - - - - °C - - - - - ° - - - - - % - - - - - - mph - - - - - - km/h - - - - - m/s - - - - - A - - - - - mAh - - - - - W - - - - - g - - - - + TrmR トリムR - + TrmE トリムE - + TrmT トリムT - + TrmA トリムA - + Trm5 トリム5 - + Trm6 トリム6 - + TrmH トリム横 - + TrmV トリム縦 - - + Batt - - + Time 時間 - - + Timer1 タイマー1 - - + Timer2 タイマー2 - - + Timer3 タイマー3 - - RAS - - - - - RSSI Tx - RSSI送信 - - - - RSSI Rx - RSSI受信 - - - - A1 - - - - - A2 - - - - - A3 - - - - - A4 - - - - - Alt - - - - - Rpm - RPM - - - - Fuel - 燃料 - - - - T1 - - - - - T2 - - - - - Speed - 速度 - - - - Dist - - - - - GPS Alt - - - - - Cell - セル - - - - Cells - セル - - - - Vfas - - - - - Curr - - - - - Cnsp - - - - - Powr - - - - - AccX - - - - - AccY - - - - - AccZ - - - - - Hdg - - - - - VSpd - - - - - AirSpeed - エアスピード - - - - dTE - - - - - A1- - - - - - A2- - - - - - A3- - - - - - A4- - - - - - Alt- - - - - - Alt+ - - - - - Rpm+ - RPM+ - - - - T1+ - - - - - T2+ - - - - - Speed+ - 速度+ - - - - Dist+ - - - - - AirSpeed+ - エアスピード+ - - - - Cell- - セル- - - - - Cells- - セル- - - - - Vfas- - - - - - Curr+ - - - - - Powr+ - - - - - ACC - - - - - GPS Time - - - - + REa エンコーダ再生a - + REb エンコーダ再生b - - + + ??? - + ---- - + I as in Input - + LUA%1%2 - + MAX 最大 - + CYC%1 - + TR as in Trainer - + SRC @@ -11088,7 +10775,22 @@ X - + + Hertz + + + + + mS + + + + + uS + + + + TELE @@ -11101,117 +10803,117 @@ X タイマー 1 - + Top LCD Timer 液晶タイマー - + Model Image モデルイメージ - + Warnings 警告 - + Switch Warnings スイッチ警告 - + Pot Warnings ダイヤル警告 - + OFF OFF - + Manual 手動 - + Auto 自動 - + Model 機体モデル - + Center beep センター ビープ - + Display Checklist チェックリスト表示 - + Never なし - + On change 変更 - + Always 常に - + Throttle Trim Idle Only THRトリムアイドル - + Global Functions グローバルファンクション - + Throttle Warning スロットル警告 - + Exponential エクスポ - + Extra Fine 極細 - + Fine 細かめ - + Medium 中間 - + Coarse 粗め - + Reverse throttle operation. If this is checked the throttle will be reversed. Idle will be forward, trim will also be reversed and the throttle warning will be reversed as well. @@ -11220,47 +10922,52 @@ If this is checked the throttle will be reversed. Idle will be forward, trim wi これがチェックされている場合、スロットル操作が逆になります。アイドルは前方になり、トリムもまた逆になり、スロットル警告も逆になります。 - + Reverse Throttle スロットル リバース - + Edit Checklist... チェックリストの編集... - + + Throttle trim switch + スロットル トリムスイッチ + + + Extended Trims 拡張トリム - + Extended Limits 拡張制限 - + Throttle Source スロットル値 - + Trim Step トリム間隔 - + Trims Display トリム表示 - + Timer 2 タイマー 2 - + Timer 3 タイマー 3 @@ -11268,87 +10975,92 @@ If this is checked the throttle will be reversed. Idle will be forward, trim wi SetupPanel - + Popup menu available 利用可能なポップアップメニュー - + Timer %1 タイマー %1 - + THR - + Profile Settings プロファイル設定 - + SD structure path not specified or invalid SDカード保存先パスが指定されていないか無効です - + Copy コピー - + Cut 切り取り - + Paste 貼り付け - + Clear 消去 - + Insert 挿入 - + Delete 削除 - + Move Up 上へ移動 - + Move Down 下へ移動 - + Clear All すべて消去 - + Clear Timer. Are you sure? タイマーを消去します。よろしいですか? - + Clear all Timers. Are you sure? タイマーをすべて消去します。よろしいですか? - + + Cut Timer. Are you sure? + タイマーを切り取ります。よろしいですか? + + + Delete Timer. Are you sure? タイマーを削除します。よろしいですか? @@ -12074,62 +11786,62 @@ The default is configured in the chosen Radio Profile. 送信機シミュレータ (%1) - + Could not determine startup data source. 起動データ元を特定できませんでした。 - + Could not load data, possibly wrong format. データをロードできません、フォーマットが間違っている可能性があります。 - + Data Load Error データロード エラー - + Invalid startup data provided. Plese specify a proper file/path. 無効なスタートアップデータが提供されました。正しいファイル/パスを指定してください。 - + Simulator Startup Error シミュレータ スタートアップ エラー - + Error saving data: could open file for writing: '%1' データ保存エラー: 書き込み用にファイルを開くことができました: 「%1」 - + Error saving data: could not get data from simulator interface. データ保存エラー: シミュレータのインターフェイスからデータを取得できませんでした。 - + An unexpected error occurred while attempting to save radio data to file '%1'. 送信機データをファイル「%1」に保存しようとしたときに予期せぬエラーが発生しました。 - + Data Save Error データ保存 エラー - + Cannot open joystick, joystick disabled スティックが接続不可、もしくはスティックが無効です - + Radio firmware error: %1 送信機 ファームウェア エラー: %1 - + - Flight Mode %1 (#%2) - フライトモード %1 (#%2) @@ -12773,11 +12485,6 @@ Too many errors, giving up. mAmps (mA) ミリアンペア (mA) - - - Range - レンジ - TelemetryCustomScreen @@ -12807,22 +12514,22 @@ Too many errors, giving up. 最大 - + None なし - + Numbers ナンバー - + Bars バー - + Script スクリプト @@ -12830,107 +12537,112 @@ Too many errors, giving up. TelemetryPanel - + Telemetry screen %1 テレメトリースクリーン %1 - + FrSky S.PORT - + FrSky D - + FrSky D (cable) - + Source 信号元 - + Low Alarm 低アラーム - + Critical Alarm クリティカルアラーム - + Winged Shadow How High Winged Shadow How High - + Winged Shadow How High (not supported) Winged Shadow How High (サポートなし) - + Alti - + Alti+ - + VSpeed - - - + + + A1 - - - + + + A2 - - + + A3 - - + + A4 - - + + FAS - + Cells セル - + --- --- + + + Delete Sensor. Are you sure? + テレメトリーセンサーを削除します。よろしいですか? + TelemetrySensor @@ -13225,67 +12937,92 @@ Too many errors, giving up. TelemetrySensorPanel - + TELE%1 - + Popup menu available 利用可能なポップアップメニュー - + Lowest より低く - + Cell %1 セル %1 - + Highest より高く - + Delta 差分 - + Copy コピー - + Cut 切り取り - + Paste 貼り付け - + Clear 消去 - + + Insert + 挿入 + + + + Delete + 削除 + + + + Move Up + 上へ移動 + + + + Move Down + 下へ移動 + + + Clear All すべて消去 - + + Cut Telemetry Sensor. Are you sure? + テレメトリーセンサーを切り取ります。よろしいですか? + + + Clear Telemetry Sensor. Are you sure? テレメトリーセンサーを消去します。よろしいですか? - + Clear all Telemetry Sensors. Are you sure? テレメトリーセンサーのすべてを消去します。よろしいですか? @@ -13669,13 +13406,19 @@ hh:mm:ss TMR - + TMR Timer %1 タイマー %1 + + + TMR + as in Timer + TMR + TimerEdit @@ -13705,37 +13448,37 @@ CTRL+スクロールまたはPAGE UP/DOWNキーを押すと、大きなステ TimerPanel - + Silent 消音 - + Beeps ビープ - + Voice 音声 - + Haptic タッチパネル - + Not persistent 持続なし - + Persistent (flight) 持続 (フライト) - + Persistent (manual reset) 持続 (手動リセット) @@ -14297,74 +14040,42 @@ CTRL+スクロールまたはPAGE UP/DOWNキーを押すと、大きなステ プログラムの設定 - - + + Location of sam-ba executable sam-ba実行ファイル場所 - - - - + + + The location of the AVRDUDE executable. AVRDUDE実行ファイル場所. - + DFU-Util Location DFU-Utiltyの場所 - - Location of AVRDUDE executable - AVRDUDE実行ファイル場所 - - - - - + + Use this button to browse and look for the AVRDUDE executable file. AVRDUDE実行ファイルを参照・検索するには、このボタンを押してください。 - - - + + Browse... 参照... - - Programmer - プログラム - - - - Programmer used for communicating with the controller. -Please consult the programmer's documentation and the AVRDUDE documentation to select the appropriate programmer. - コントローラとの通信に使用されるプログラムです。 -適切なプログラムを選択するには、プログラム側の資料とAVRDUDEの資料を参照してください。 - - - - List all available programmers. - 利用可能なプログラムを一覧表示します。 - - - - List Available - 一覧表示 - - - - + Extra arguments that will be passed to AVRDUDE on every call すべての呼び出しでAVRDUDEに渡される追加引数 - - + Extra arguments used in AVRDUDE. This can be used for providing extra information to AVRDUDE. @@ -14375,51 +14086,17 @@ Please only use this if you know what you are doing. There are no error checks こちらは自己責任においてご利用ください。エラーチェックは行われません。不具合がある場合コントローラが制御不能となる可能性があります。 - - Extra Arguments - 追加引数 - - - - Show AVRDUDE help - AVRDUDEのヘルプを表示します - - - - Show Help - ヘルプを表示 - - - - Communication port to the programmer. - - プログラムへの通信ポートです。 - - - - + Port ポート - - AVRDUDE Location - AVRDUDEの場所 - - - - MCU - MCU - - - - + CPU of your TX 送信機のCPU - - + CPU present on your 9x radio Should be m64 for stock radios m2560 for v4.1 boards @@ -14428,72 +14105,51 @@ m2560 for v4.1 boards v4.1ボード用m2560 - + at91sam3s8-9xr at91sam3s8-9xr - + SAM-BA Location SAM-BAの場所 - + ARM MCU ARM MCU - + sam-ba serial port sam-ba シリアルポート - + Alternate device 代替デバイス - + Use advanced controls 詳細設定を使用 - + DFU-UTIL Configuration DFU-Utility 設定 - + SAM-BA Configuration SAM-BA 設定 - - AVRDUDE Configuration - AVRDUDE 設定 - - - - - + + Select Location 場所の選択 - - - List available programmers - 利用可能なプログラムを一覧表示します - - - - Avrdude help - Avrdude ヘルプ - - - - <b><u>WARNING!</u></b><br>Normally CPU type is automatically selected according to the chosen firmware.<br>If you change the CPU type the resulting eeprom could be inconsistent. - <b><u>警告!</u></b><br>通常CPUタイプは、選択されたファームウェアによって自動的に選択されます。<br>CPUタイプを変更すると、その結果EEPROMに矛盾が生じる可能性があります。 - joystickDialog diff --git a/radio/sdcard/horus/SCRIPTS/TOOLS/crossfire.lua b/radio/sdcard/horus/SCRIPTS/TOOLS/crossfire.lua index 0f9b1a20f..b19bb5ee2 100644 --- a/radio/sdcard/horus/SCRIPTS/TOOLS/crossfire.lua +++ b/radio/sdcard/horus/SCRIPTS/TOOLS/crossfire.lua @@ -30,6 +30,11 @@ local function run(event) return 2 end + if crossfireTelemetryPush() == nil then + error("Crossfire not available!") + return 2 + end + chdir("/SCRIPTS/TOOLS/CROSSFIRE") return "crossfire.lua" end diff --git a/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/crossfire.lua b/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/crossfire.lua index debf9056d..3e8a6930a 100644 --- a/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/crossfire.lua +++ b/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/crossfire.lua @@ -30,6 +30,11 @@ local function run(event) return 2 end + if crossfireTelemetryPush() == nil then + error("Crossfire not available!") + return 2 + end + chdir("/SCRIPTS/TOOLS/CROSSFIRE") return "crossfire.lua" end diff --git a/radio/sdcard/taranis-x7/SCRIPTS/WIZARD/multi.lua b/radio/sdcard/taranis-x7/SCRIPTS/WIZARD/multi.lua index 923acc43b..fc65db204 100755 --- a/radio/sdcard/taranis-x7/SCRIPTS/WIZARD/multi.lua +++ b/radio/sdcard/taranis-x7/SCRIPTS/WIZARD/multi.lua @@ -171,6 +171,8 @@ local function init() local ver, radio, maj, minor, rev = getVersion() if string.match(radio, "x7") then switches = {"SA", "SB", "SC", "SD", "SF", "SH"} + elseif string.match(radio, "tx12") then + switches = {"SA", "SB", "SC", "SD", "SE", "SF"} else switches = {"SA", "SB", "SC", "SD"} end diff --git a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/crossfire.lua b/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/crossfire.lua index 0f9b1a20f..b19bb5ee2 100644 --- a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/crossfire.lua +++ b/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/crossfire.lua @@ -30,6 +30,11 @@ local function run(event) return 2 end + if crossfireTelemetryPush() == nil then + error("Crossfire not available!") + return 2 + end + chdir("/SCRIPTS/TOOLS/CROSSFIRE") return "crossfire.lua" end diff --git a/radio/src/gui/128x64/gui.h b/radio/src/gui/128x64/gui.h index 40773737e..caac6e958 100644 --- a/radio/src/gui/128x64/gui.h +++ b/radio/src/gui/128x64/gui.h @@ -36,7 +36,6 @@ #define HEADER_LINE_COLUMNS 0, #endif -#define COLUMN_X 0 #define drawFieldLabel(x, y, str) lcdDrawTextAlignedLeft(y, str) #define NUM_BODY_LINES (LCD_LINES-1) diff --git a/radio/src/gui/128x64/model_select.cpp b/radio/src/gui/128x64/model_select.cpp index c7e1a1313..0087fef7c 100644 --- a/radio/src/gui/128x64/model_select.cpp +++ b/radio/src/gui/128x64/model_select.cpp @@ -83,7 +83,7 @@ void onModelSelectMenu(const char * result) void menuModelSelect(event_t event) { event_t _event_ = event; - if ((s_copyMode && EVT_KEY_MASK(event) == KEY_EXIT) || event == EVT_KEY_BREAK(KEY_EXIT) || IS_ROTARY_BREAK(event) || IS_ROTARY_LONG(event)) { + if ((s_copyMode && IS_KEY_EVT(event, KEY_EXIT)) || event == EVT_KEY_BREAK(KEY_EXIT) || IS_ROTARY_BREAK(event) || IS_ROTARY_LONG(event)) { _event_ = 0; } diff --git a/radio/src/gui/128x64/model_special_functions.cpp b/radio/src/gui/128x64/model_special_functions.cpp index c85cdf2f2..e74c8b21b 100644 --- a/radio/src/gui/128x64/model_special_functions.cpp +++ b/radio/src/gui/128x64/model_special_functions.cpp @@ -276,10 +276,12 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF lcdDrawNumber(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr|LEFT); } #endif // OVERRIDE_CHANNEL_FUNCTION - else if (func >= FUNC_SET_FAILSAFE && func <= FUNC_BIND) { +#if defined(DANGEROUS_MODULE_FUNCTIONS) + else if (func >= FUNC_RANGECHECK && func <= FUNC_BIND) { val_max = NUM_MODULES-1; lcdDrawTextAtIndex(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, "\004Int.Ext.", CFN_PARAM(cfn), attr); } +#endif else if (func == FUNC_SET_TIMER) { getMixSrcRange(MIXSRC_FIRST_TIMER, val_min, val_max); drawTimer(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr|LEFT, attr); diff --git a/radio/src/gui/128x64/view_main.cpp b/radio/src/gui/128x64/view_main.cpp index 111c6bee7..48e6cfbe1 100644 --- a/radio/src/gui/128x64/view_main.cpp +++ b/radio/src/gui/128x64/view_main.cpp @@ -44,7 +44,6 @@ struct { #define PHASE_FLAGS 0 #define VBATT_X (6*FW-1) #define VBATT_Y (2*FH) -#define VBATTUNIT_X (VBATT_X-1) #define VBATTUNIT_Y (3*FH) #define REBOOT_X (20*FW-3) #define BAR_HEIGHT (BOX_WIDTH-1l) // don't remove the l here to force 16bits maths on 9X @@ -260,8 +259,13 @@ void displayBattVoltage() count = (get_tmr10ms() & 127u) * count / 128; } #endif - for (uint8_t i = 0; i < count; i += 2) + for (uint8_t i = 0; i < count; i += 2) { +#if defined(USB_CHARGER) + if ((i >= count - 2) && usbChargerLed() && BLINK_ON_PHASE) // Blink last segment on charge + continue; +#endif lcdDrawSolidVerticalLine(VBATT_X - 24 + i, VBATT_Y + 10, 3); + } if (!IS_TXBATT_WARNING() || BLINK_ON_PHASE) lcdDrawSolidFilledRect(VBATT_X - 26, VBATT_Y, 24, 15); #else diff --git a/radio/src/gui/212x64/model_special_functions.cpp b/radio/src/gui/212x64/model_special_functions.cpp index c8b74a124..703821cda 100644 --- a/radio/src/gui/212x64/model_special_functions.cpp +++ b/radio/src/gui/212x64/model_special_functions.cpp @@ -268,10 +268,12 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF lcdDrawNumber(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr|LEFT); } #endif - else if (func >= FUNC_SET_FAILSAFE && func <= FUNC_BIND) { +#if defined(DANGEROUS_MODULE_FUNCTIONS) + else if (func >= FUNC_RANGECHECK && func <= FUNC_BIND) { val_max = NUM_MODULES-1; lcdDrawTextAtIndex(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, "\004Int.Ext.", CFN_PARAM(cfn), attr); } +#endif else if (func == FUNC_SET_TIMER) { getMixSrcRange(MIXSRC_FIRST_TIMER, val_min, val_max); drawTimer(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, val_displayed, attr|LEFT|TIMEHOUR, attr); diff --git a/radio/src/gui/212x64/view_main.cpp b/radio/src/gui/212x64/view_main.cpp index bf8d6abb7..2d6d1d06b 100644 --- a/radio/src/gui/212x64/view_main.cpp +++ b/radio/src/gui/212x64/view_main.cpp @@ -27,7 +27,6 @@ #define MODELNAME_Y (11) #define VBATT_X (MODELNAME_X+26) #define VBATT_Y (FH+3) -#define VBATTUNIT_X (VBATT_X-2) #define VBATTUNIT_Y VBATT_Y #define BITMAP_X ((LCD_W-64)/2) #define BITMAP_Y (LCD_H/2) diff --git a/radio/src/gui/colorlcd/layouts/layout4+2.cpp b/radio/src/gui/colorlcd/layouts/layout4+2.cpp deleted file mode 100644 index 31e868c07..000000000 --- a/radio/src/gui/colorlcd/layouts/layout4+2.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) OpenTX - * - * Based on code named - * th9x - http://code.google.com/p/th9x - * er9x - http://code.google.com/p/er9x - * gruvin9x - http://code.google.com/p/gruvin9x - * - * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include "opentx.h" -#include "sliders.h" -#include "trims.h" - -#define HAS_TOPBAR() (persistentData->options[0].value.boolValue == true) -#define HAS_FM() (persistentData->options[1].value.boolValue == true) -#define HAS_SLIDERS() (persistentData->options[2].value.boolValue == true) -#define HAS_TRIMS() (persistentData->options[3].value.boolValue == true) -#define IS_MIRRORED() (persistentData->options[4].value.boolValue == true) - -const uint8_t LBM_LAYOUT_4P2[] = { -#include "mask_layout4+2.lbm" -}; - -const ZoneOption OPTIONS_LAYOUT_4P2[] = { - { STR_TOP_BAR, ZoneOption::Bool }, - { STR_FLIGHT_MODE, ZoneOption::Bool }, - { STR_SLIDERS, ZoneOption::Bool }, - { STR_TRIMS, ZoneOption::Bool }, - { STR_MIRROR, ZoneOption::Bool }, - { nullptr, ZoneOption::Bool } -}; - -class Layout4P2: public Layout -{ - public: - Layout4P2(const LayoutFactory * factory, Layout::PersistentData * persistentData): - Layout(factory, persistentData) - { - decorate(); - } - - void create() override - { - Layout::create(); - persistentData->options[0].value.boolValue = true; - persistentData->options[1].value.boolValue = true; - persistentData->options[2].value.boolValue = true; - persistentData->options[3].value.boolValue = true; - persistentData->options[4].value.boolValue = false; - persistentData->options[5].value.boolValue = false; - decorate(); - } - - void decorate() - { - Layout::decorate(HAS_TOPBAR(), HAS_SLIDERS(), HAS_TRIMS(), HAS_FM()); - } - - unsigned int getZonesCount() const override - { - return 6; - } - - rect_t getZone(unsigned int index) const override - { - coord_t areaw = LCD_W - (HAS_SLIDERS() ? 2 * TRIM_SQUARE_SIZE : 0) - (HAS_TRIMS() ? 2 * TRIM_SQUARE_SIZE : 0) - 10; - coord_t areah = LCD_H - (HAS_TOPBAR() ? TOPBAR_HEIGHT : 0) - (HAS_SLIDERS() ? TRIM_SQUARE_SIZE : 0) - (HAS_TRIMS() ? TRIM_SQUARE_SIZE : 0) - 10; - areah = 4 * (areah % 4); - - return { - IS_MIRRORED() ? ((index >= 4) ? (LCD_W - areaw) / 2 : 240) : ((index >= 4) ? 240 : (LCD_W - areaw) / 2), - static_cast((index >= 4) ? (HAS_TOPBAR() ? TOPBAR_HEIGHT + 1 : 1) + (index == 5 ? areah / 4 : 0) : (HAS_TOPBAR() ? TOPBAR_HEIGHT + 1 : 1) + (index % 4) * (areah / 4)), - areaw / 2, - (index >= 4) ? (areah / 2) : (areah / 4) - }; - } - - void checkEvents() override - { - Layout::checkEvents(); - uint8_t newValue = persistentData->options[4].value.boolValue << 4 | persistentData->options[3].value.boolValue << 3 | persistentData->options[2].value.boolValue << 2 - | persistentData->options[1].value.boolValue << 1 | persistentData->options[0].value.boolValue; - if (value != newValue) { - value = newValue; - // TODO call this from the Layout config window - this->clear(); - decorate(); - } - } - protected: - uint8_t value = 0; -}; - -BaseLayoutFactory layout4P2("Layout4P2", "4 + 2", LBM_LAYOUT_4P2, OPTIONS_LAYOUT_4P2); \ No newline at end of file diff --git a/radio/src/gui/colorlcd/layouts/mask_layout4+2.png b/radio/src/gui/colorlcd/layouts/mask_layout4+2.png deleted file mode 100644 index 9e6e34f57..000000000 Binary files a/radio/src/gui/colorlcd/layouts/mask_layout4+2.png and /dev/null differ diff --git a/radio/src/gui/colorlcd/screens_setup_old.cpp b/radio/src/gui/colorlcd/screens_setup_old.cpp index 7015325cc..cc12cc312 100644 --- a/radio/src/gui/colorlcd/screens_setup_old.cpp +++ b/radio/src/gui/colorlcd/screens_setup_old.cpp @@ -614,6 +614,7 @@ bool menuScreenSetup(int index, event_t event) ZoneOptionValue * value = currentScreen->getOptionValue(o); if (editZoneOption(y, option, value, attr, EE_MODEL, event)) { currentScreen->update(); + loadCustomScreens(); } } else if (menuPageCount > 3 && o == optionsCount) { diff --git a/radio/src/gui/colorlcd/topbar.cpp b/radio/src/gui/colorlcd/topbar.cpp index d3c3d0c2c..cbe773a1e 100644 --- a/radio/src/gui/colorlcd/topbar.cpp +++ b/radio/src/gui/colorlcd/topbar.cpp @@ -64,6 +64,11 @@ void TopBar::paint(BitmapBuffer * dc) dc->drawBitmapPattern(LCD_W - 98, 8, LBM_TOPMENU_USB, MENU_COLOR); } + // Logs + if (isFunctionActive(FUNCTION_LOGS) && !usbPlugged() && BLINK_ON_PHASE) { + dc->drawBitmapPattern(LCD_W - 98, 6, LBM_DOT, MENU_COLOR); + } + // RSSI const uint8_t rssiBarsValue[] = {30, 40, 50, 60, 80}; const uint8_t rssiBarsHeight[] = {5, 10, 15, 21, 31}; diff --git a/radio/src/gui/colorlcd/view_about.cpp b/radio/src/gui/colorlcd/view_about.cpp index 3f5e14660..ea3561188 100644 --- a/radio/src/gui/colorlcd/view_about.cpp +++ b/radio/src/gui/colorlcd/view_about.cpp @@ -128,7 +128,7 @@ bool menuAboutView(event_t event) break; case ABOUT_HARDWARE: - lcdDrawText(ABOUT_X, MENU_CONTENT_TOP, "FrSky", INVERS); + lcdDrawText(ABOUT_X, MENU_CONTENT_TOP, STR_ABOUT_HARDWARE_1, INVERS); lcdDrawText(ABOUT_X+ABOUT_INDENT, MENU_CONTENT_TOP + FH, STR_ABOUT_HARDWARE_2); lcdDrawText(ABOUT_X+ABOUT_INDENT, MENU_CONTENT_TOP + 2*FH, STR_ABOUT_HARDWARE_3); break; diff --git a/radio/src/gui/common/stdlcd/radio_ghost_menu.cpp b/radio/src/gui/common/stdlcd/radio_ghost_menu.cpp index 490e9f021..d0e0dd159 100644 --- a/radio/src/gui/common/stdlcd/radio_ghost_menu.cpp +++ b/radio/src/gui/common/stdlcd/radio_ghost_menu.cpp @@ -25,6 +25,8 @@ void menuGhostModuleConfig(event_t event) switch (event) { case EVT_ENTRY: memclear(&reusableBuffer.ghostMenu, sizeof(reusableBuffer.ghostMenu)); + strAppend((char *) &reusableBuffer.ghostMenu.line[1].menuText, STR_WAITING_FOR_MODULE, 0); + reusableBuffer.ghostMenu.line[1].lineFlags = GHST_LINE_FLAGS_VALUE_EDIT; reusableBuffer.ghostMenu.buttonAction = GHST_BTN_NONE; reusableBuffer.ghostMenu.menuAction = GHST_MENU_CTRL_OPEN; moduleState[EXTERNAL_MODULE].counter = GHST_MENU_CONTROL; @@ -40,6 +42,7 @@ void menuGhostModuleConfig(event_t event) reusableBuffer.ghostMenu.buttonAction = GHST_BTN_JOYUP; reusableBuffer.ghostMenu.menuAction = GHST_MENU_CTRL_NONE; moduleState[EXTERNAL_MODULE].counter = GHST_MENU_CONTROL; + audioKeyPress(); break; #if defined(ROTARY_ENCODER_NAVIGATION) @@ -52,6 +55,7 @@ void menuGhostModuleConfig(event_t event) reusableBuffer.ghostMenu.buttonAction = GHST_BTN_JOYDOWN; reusableBuffer.ghostMenu.menuAction = GHST_MENU_CTRL_NONE; moduleState[EXTERNAL_MODULE].counter = GHST_MENU_CONTROL; + audioKeyPress(); break; @@ -59,12 +63,14 @@ void menuGhostModuleConfig(event_t event) reusableBuffer.ghostMenu.buttonAction = GHST_BTN_JOYPRESS; reusableBuffer.ghostMenu.menuAction = GHST_MENU_CTRL_NONE; moduleState[EXTERNAL_MODULE].counter = GHST_MENU_CONTROL; + audioKeyPress(); break; case EVT_KEY_BREAK(KEY_EXIT): reusableBuffer.ghostMenu.buttonAction = GHST_BTN_JOYLEFT; reusableBuffer.ghostMenu.menuAction = GHST_MENU_CTRL_NONE; moduleState[EXTERNAL_MODULE].counter = GHST_MENU_CONTROL; + audioKeyPress(); break; case EVT_KEY_LONG(KEY_EXIT): @@ -78,7 +84,12 @@ void menuGhostModuleConfig(event_t event) break; } - if (reusableBuffer.ghostMenu.menuAction == GHST_MENU_CTRL_CLOSE) { + if (reusableBuffer.ghostMenu.menuStatus == GHST_MENU_STATUS_UNOPENED) { // Handles situation where module is plugged after tools start + reusableBuffer.ghostMenu.buttonAction = GHST_BTN_NONE; + reusableBuffer.ghostMenu.menuAction = GHST_MENU_CTRL_OPEN; + moduleState[EXTERNAL_MODULE].counter = GHST_MENU_CONTROL; + } + else if (reusableBuffer.ghostMenu.menuStatus == GHST_MENU_STATUS_CLOSING) { popMenu(); } @@ -104,6 +115,8 @@ void menuGhostModuleConfig(event_t event) else { if (reusableBuffer.ghostMenu.line[line].lineFlags & GHST_LINE_FLAGS_LABEL_SELECT) flags = INVERS; + if (reusableBuffer.ghostMenu.line[line].lineFlags & GHST_LINE_FLAGS_VALUE_EDIT) + flags |= BLINK; lcdDrawText(xOffset, yOffset + line * FH, reusableBuffer.ghostMenu.line[line].menuText, flags); } } diff --git a/radio/src/gui/common/stdlcd/radio_sdmanager.cpp b/radio/src/gui/common/stdlcd/radio_sdmanager.cpp index b07eee74d..a34dee913 100644 --- a/radio/src/gui/common/stdlcd/radio_sdmanager.cpp +++ b/radio/src/gui/common/stdlcd/radio_sdmanager.cpp @@ -227,14 +227,19 @@ void onSdManagerMenu(const char * result) #if defined(INTERNAL_MODULE_MULTI) else if (result == STR_FLASH_INTERNAL_MULTI) { getSelectionFullPath(lfn); - MultiDeviceFirmwareUpdate device(INTERNAL_MODULE); + MultiDeviceFirmwareUpdate device(INTERNAL_MODULE, MULTI_TYPE_MULTIMODULE); device.flashFirmware(lfn, drawProgressScreen); } #endif else if (result == STR_FLASH_EXTERNAL_MULTI) { getSelectionFullPath(lfn); MultiDeviceFirmwareUpdate device(EXTERNAL_MODULE); - device.flashFirmware(lfn, drawProgressScreen); + device.flashFirmware(lfn, MULTI_TYPE_MULTIMODULE, drawProgressScreen); + } + else if (result == STR_FLASH_EXTERNAL_ELRS) { + getSelectionFullPath(lfn); + MultiDeviceFirmwareUpdate device(EXTERNAL_MODULE); + device.flashFirmware(lfn, MULTI_TYPE_ELRS, drawProgressScreen); } #endif #if defined(BLUETOOTH) @@ -404,6 +409,12 @@ void menuRadioSdManager(event_t _event) POPUP_MENU_ADD_ITEM(STR_FLASH_EXTERNAL_MULTI); } } + + if (!READ_ONLY() && !strcasecmp(ext, ELRS_FIRMWARE_EXT)) { + TCHAR lfn[FF_MAX_LFN + 1]; + getSelectionFullPath(lfn); + POPUP_MENU_ADD_ITEM(STR_FLASH_EXTERNAL_ELRS); + } #endif #if defined(PCBTARANIS) if (!READ_ONLY() && !strcasecmp(ext, FIRMWARE_EXT)) { diff --git a/radio/src/gui/common/stdlcd/radio_tools.cpp b/radio/src/gui/common/stdlcd/radio_tools.cpp index ab881a1d6..082b4a79c 100644 --- a/radio/src/gui/common/stdlcd/radio_tools.cpp +++ b/radio/src/gui/common/stdlcd/radio_tools.cpp @@ -133,6 +133,7 @@ void menuRadioTools(event_t event) if (isModuleGhost(EXTERNAL_MODULE)) addRadioModuleTool(index++, "Ghost Menu", menuGhostModuleConfig, EXTERNAL_MODULE); #endif + if (index == 0) { lcdDrawCenteredText(LCD_H/2, STR_NO_TOOLS); } diff --git a/radio/src/gui/gui_common.cpp b/radio/src/gui/gui_common.cpp index a60581df6..8dcb46645 100644 --- a/radio/src/gui/gui_common.cpp +++ b/radio/src/gui/gui_common.cpp @@ -555,7 +555,7 @@ bool isPxx2IsrmChannelsCountAllowed(int channels) bool isTrainerUsingModuleBay() { #if defined(PCBTARANIS) - if (TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE <= g_model.trainerData.mode && g_model.trainerData.mode <= TRAINER_MODE_MASTER_BATTERY_COMPARTMENT) + if (TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE <= g_model.trainerData.mode && g_model.trainerData.mode <= TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE) return true; #endif return false; @@ -951,8 +951,9 @@ const char STR_SUBTYPE_ESky[] = "\003""Std""ET4"; const char STR_SUBTYPE_MT99[] = "\006""MT99\0 ""H7\0 ""YZ\0 ""LS\0 ""FY805"; const char STR_SUBTYPE_MJXQ[] = "\007""WLH08\0 ""X600\0 ""X800\0 ""H26D\0 ""E010\0 ""H26WH\0 ""Phoenix"; const char STR_SUBTYPE_FY326[] = "\005""Std\0 ""FY319"; +const char STR_SUBTYPE_FUTABA[] = "\005""SFHSS"; const char STR_SUBTYPE_HONTAI[] = "\007""Std\0 ""JJRC X1""X5C1\0 ""FQ_951"; -const char STR_SUBTYPE_AFHDS2A[] = "\010""PWM,IBUS""PPM,IBUS""PWM,SBUS""PPM,SBUS"; +const char STR_SUBTYPE_AFHDS2A[] = "\010""PWM,IBUS""PPM,IBUS""PWM,SBUS""PPM,SBUS""PWM,IB16""PPM,IB16"; const char STR_SUBTYPE_Q2X2[] = "\004""Q222""Q242""Q282"; const char STR_SUBTYPE_WK2x01[] = "\006""WK2801""WK2401""W6_5_1""W6_6_1""W6_HeL""W6_HeI"; const char STR_SUBTYPE_Q303[] = "\006""Std\0 ""CX35\0 ""CX10D\0""CX10WD"; @@ -961,7 +962,7 @@ const char STR_SUBTYPE_ESKY150[] = "\003""4ch""7ch"; const char STR_SUBTYPE_H83D[] = "\007""Std\0 ""H20H\0 ""H20Mini""H30Mini"; const char STR_SUBTYPE_CORONA[] = "\005""V1\0 ""V2\0 ""FD V3"; const char STR_SUBTYPE_HITEC[] = "\007""Optima\0""Opt Hub""Minima\0"; -const char STR_SUBTYPE_WFLY[] = "\006""WFR0xS"; +const char STR_SUBTYPE_WFLY[] = "\005""WFR0x"; const char STR_SUBTYPE_BUGS_MINI[] = "\006""Std\0 ""Bugs3H"; const char STR_SUBTYPE_TRAXXAS[] = "\004""6519"; const char STR_SUBTYPE_E01X[] = "\005""E012\0""E015\0""E016H"; @@ -971,18 +972,24 @@ const char STR_SUBTYPE_V761[] = "\003""3ch""4ch"; const char STR_SUBTYPE_REDPINE[] = "\004""Fast""Slow"; const char STR_SUBTYPE_POTENSIC[] = "\003""A20"; const char STR_SUBTYPE_ZSX[] = "\007""280JJRC"; -const char STR_SUBTYPE_FLYZONE[] = "\005""FZ410"; +const char STR_SUBTYPE_HEIGHT[] = "\003""5ch""8ch"; const char STR_SUBTYPE_FRSKYX_RX[] = "\007""RX\0 ""CloneTX"; const char STR_SUBTYPE_HOTT[] = "\007""Sync\0 ""No_Sync"; const char STR_SUBTYPE_FX816[] = "\003""P38"; const char STR_SUBTYPE_PELIKAN[] = "\004""Pro\0""Lite"; const char STR_SUBTYPE_XK[] = "\004""X450""X420"; const char STR_SUBTYPE_XN297DUMP[] = "\004""250K""1M\0 ""2M\0 ""AUTO""NRF\0"; -const char STR_SUBTYPE_FRSKYX2[] = "\011""D16\0 ""D16 8ch\0 ""LBT(EU)\0 ""LBT 8ch\0 ""D16Cloned"; -const char STR_SUBTYPE_FRSKYR9[] = "\007""915MHz\0""868MHz\0""915 8ch""868 8ch"; +const char STR_SUBTYPE_FRSKYX2[] = "\010""D16\0 ""D16 8ch\0""LBT(EU)\0""LBT 8ch\0""Cloned\0 ""Clone8ch"; +const char STR_SUBTYPE_FRSKYR9[] = "\007""915MHz\0""868MHz\0""915 8ch""868 8ch""FCC\0 ""---\0 ""FCC 8ch"; const char STR_SUBTYPE_PROPEL[] = "\004""74-Z"; const char STR_SUBTYPE_FRSKYL[] = "\010""LR12\0 ""LR12 6ch"; const char STR_SUBTYPE_ESKY150V2[] = "\006""150 V2"; +const char STR_SUBTYPE_JJRC345[] = "\007""Std\0 ""SkyTmbr"; +const char STR_SUBTYPE_KYOSHO[] = "\004""FHSS""Hype"; +const char STR_SUBTYPE_RLINK[] = "\007""Surface""Air\0 ""DumboRC"; +const char STR_SUBTYPE_ELRS[] = "\007""N/A WIP"; +const char STR_SUBTYPE_REALACC[] = "\003""R11"; +const char STR_SUBTYPE_WFLY2[] = "\005""RF20x"; const char* mm_options_strings::options[] = { nullptr, @@ -1017,11 +1024,11 @@ const mm_protocol_definition multi_protocols[] = { {MODULE_SUBTYPE_MULTI_MT99XX, 4, false, false, STR_SUBTYPE_MT99, nullptr}, {MODULE_SUBTYPE_MULTI_MJXQ, 6, false, false, STR_SUBTYPE_MJXQ, STR_MULTI_RFTUNE}, {MODULE_SUBTYPE_MULTI_FY326, 1, false, false, STR_SUBTYPE_FY326, nullptr}, - {MODULE_SUBTYPE_MULTI_SFHSS, 0, true, true, NO_SUBTYPE, STR_MULTI_RFTUNE}, + {MODULE_SUBTYPE_MULTI_FUTABA, 0, true, true, STR_SUBTYPE_FUTABA, STR_MULTI_RFTUNE}, {MODULE_SUBTYPE_MULTI_J6PRO, 0, false, true, NO_SUBTYPE, nullptr}, {MODULE_SUBTYPE_MULTI_HONTAI, 3, false, false, STR_SUBTYPE_HONTAI, nullptr}, {MODULE_SUBTYPE_MULTI_OLRS, 0, false, false, NO_SUBTYPE, STR_RF_POWER}, - {MODULE_SUBTYPE_MULTI_FS_AFHDS2A, 3, true, true, STR_SUBTYPE_AFHDS2A, STR_MULTI_SERVOFREQ}, + {MODULE_SUBTYPE_MULTI_FS_AFHDS2A, 5, true, true, STR_SUBTYPE_AFHDS2A, STR_MULTI_SERVOFREQ}, {MODULE_SUBTYPE_MULTI_Q2X2, 2, false, false, STR_SUBTYPE_Q2X2, nullptr}, {MODULE_SUBTYPE_MULTI_WK_2X01, 5, false, true, STR_SUBTYPE_WK2x01, nullptr}, {MODULE_SUBTYPE_MULTI_Q303, 3, false, false, STR_SUBTYPE_Q303, nullptr}, @@ -1041,20 +1048,28 @@ const mm_protocol_definition multi_protocols[] = { {MODULE_SUBTYPE_MULTI_REDPINE, 1, false, false, STR_SUBTYPE_REDPINE, STR_MULTI_RFTUNE}, {MODULE_SUBTYPE_MULTI_POTENSIC, 0, false, false, STR_SUBTYPE_POTENSIC, nullptr}, {MODULE_SUBTYPE_MULTI_ZSX, 0, false, false, STR_SUBTYPE_ZSX, nullptr}, - {MODULE_SUBTYPE_MULTI_FLYZONE, 0, false, false, STR_SUBTYPE_FLYZONE, nullptr}, + {MODULE_SUBTYPE_MULTI_HEIGHT, 1, false, false, STR_SUBTYPE_HEIGHT, nullptr}, {MODULE_SUBTYPE_MULTI_FRSKYX_RX, 1, false, false, STR_SUBTYPE_FRSKYX_RX, STR_MULTI_RFTUNE}, {MODULE_SUBTYPE_MULTI_HOTT, 1, true, false, STR_SUBTYPE_HOTT, STR_MULTI_RFTUNE}, {MODULE_SUBTYPE_MULTI_FX816, 0, false, false, STR_SUBTYPE_FX816, nullptr}, - {MODULE_SUBTYPE_MULTI_PELIKAN, 1, false, false, STR_SUBTYPE_PELIKAN, nullptr}, + {MODULE_SUBTYPE_MULTI_PELIKAN, 1, false, true, STR_SUBTYPE_PELIKAN, nullptr}, {MODULE_SUBTYPE_MULTI_XK, 1, false, false, STR_SUBTYPE_XK, STR_MULTI_RFTUNE}, {MODULE_SUBTYPE_MULTI_XN297DUMP, 4, false, false, STR_SUBTYPE_XN297DUMP, STR_MULTI_RFCHAN}, - {MODULE_SUBTYPE_MULTI_FRSKYX2, 4, true, false, STR_SUBTYPE_FRSKYX2, STR_MULTI_RFTUNE}, - {MODULE_SUBTYPE_MULTI_FRSKY_R9, 3, true, false, STR_SUBTYPE_FRSKYR9, nullptr}, + {MODULE_SUBTYPE_MULTI_FRSKYX2, 5, true, false, STR_SUBTYPE_FRSKYX2, STR_MULTI_RFTUNE}, + {MODULE_SUBTYPE_MULTI_FRSKY_R9, 6, true, false, STR_SUBTYPE_FRSKYR9, nullptr}, {MODULE_SUBTYPE_MULTI_PROPEL, 0, false, false, STR_SUBTYPE_PROPEL, nullptr}, {MODULE_SUBTYPE_MULTI_FRSKYL, 1, false, false, STR_SUBTYPE_FRSKYL, STR_MULTI_RFTUNE}, {MODULE_SUBTYPE_MULTI_SKYARTEC, 0, false, false, NO_SUBTYPE, STR_MULTI_RFTUNE}, {MODULE_SUBTYPE_MULTI_ESKY150V2, 0, false, true, STR_SUBTYPE_ESKY150V2, STR_MULTI_RFTUNE}, + {MODULE_SUBTYPE_MULTI_JJRC345, 1, false, false, STR_SUBTYPE_JJRC345, nullptr}, {MODULE_SUBTYPE_MULTI_Q90C, 0, false, false, NO_SUBTYPE, STR_MULTI_RFTUNE}, + {MODULE_SUBTYPE_MULTI_KYOSHO, 1, false, true, STR_SUBTYPE_KYOSHO, nullptr}, + {MODULE_SUBTYPE_MULTI_RLINK, 2, false, false, STR_SUBTYPE_RLINK, STR_MULTI_RFTUNE}, + {MODULE_SUBTYPE_MULTI_ELRS, 0, false, false, STR_SUBTYPE_ELRS, nullptr}, + {MODULE_SUBTYPE_MULTI_REALACC, 0, false, false, STR_SUBTYPE_REALACC, nullptr}, + {MODULE_SUBTYPE_MULTI_OMP, 0, false, false, NO_SUBTYPE, STR_MULTI_RFTUNE}, + {MODULE_SUBTYPE_MULTI_WFLY2, 0, false, false, STR_SUBTYPE_WFLY2, STR_MULTI_OPTION}, + {MODULE_SUBTYPE_MULTI_E016HV2, 0, false, false, NO_SUBTYPE, STR_MULTI_RFTUNE}, {MM_RF_CUSTOM_SELECTED, 7, true, true, NO_SUBTYPE, STR_MULTI_OPTION}, // Sentinel and default for protocols not listed above (MM_RF_CUSTOM is 0xff) diff --git a/radio/src/gui/gui_common.h b/radio/src/gui/gui_common.h index 335c5a83c..b8ef67f17 100644 --- a/radio/src/gui/gui_common.h +++ b/radio/src/gui/gui_common.h @@ -248,10 +248,12 @@ inline bool MULTIMODULE_HAS_SUBTYPE(uint8_t moduleIdx) } else { - if (g_model.moduleData[moduleIdx].getMultiProtocol() > MODULE_SUBTYPE_MULTI_LAST) + if (g_model.moduleData[moduleIdx].getMultiProtocol() > MODULE_SUBTYPE_MULTI_LAST) { return true; - else - return getMultiProtocolDefinition(g_model.moduleData[moduleIdx].getMultiProtocol())->maxSubtype > 0; + } + else { + return getMultiProtocolDefinition(g_model.moduleData[moduleIdx].getMultiProtocol())->subTypeString != nullptr; + } } } @@ -303,9 +305,9 @@ inline uint8_t MULTIMODULE_HASOPTIONS(uint8_t moduleIdx) #endif #if defined(AFHDS3) -#define AFHDS3_PROTOCOL_ROW(moduleIdx) isModuleAFHDS3(moduleIdx) ? 0 : HIDDEN_ROW, +#define AFHDS3_PROTOCOL_ROW(moduleIdx) isModuleAFHDS3(moduleIdx) ? uint8_t(0) : HIDDEN_ROW, #define AFHDS3_MODE_ROWS(moduleIdx) isModuleAFHDS3(moduleIdx) ? TITLE_ROW : HIDDEN_ROW, isModuleAFHDS3(moduleIdx) ? TITLE_ROW : HIDDEN_ROW, isModuleAFHDS3(moduleIdx) ? TITLE_ROW : HIDDEN_ROW, -#define AFHDS3_MODULE_ROWS(moduleIdx) isModuleAFHDS3(moduleIdx) ? (uint8_t) 0 : HIDDEN_ROW, isModuleAFHDS3(moduleIdx) ? (uint8_t) TITLE_ROW : HIDDEN_ROW, +#define AFHDS3_MODULE_ROWS(moduleIdx) isModuleAFHDS3(moduleIdx) ? uint8_t(0) : HIDDEN_ROW, isModuleAFHDS3(moduleIdx) ? TITLE_ROW : HIDDEN_ROW, #else #define AFHDS3_PROTOCOL_ROW(moduleIdx) #define AFHDS3_MODE_ROWS(moduleIdx) diff --git a/radio/src/io/multi_firmware_update.cpp b/radio/src/io/multi_firmware_update.cpp index 21dc934e1..940b7dc74 100644 --- a/radio/src/io/multi_firmware_update.cpp +++ b/radio/src/io/multi_firmware_update.cpp @@ -19,6 +19,7 @@ */ #if !defined(DISABLE_MULTI_UPDATE) + #include "opentx.h" #include "multi_firmware_update.h" #include "stk500.h" @@ -35,23 +36,22 @@ class MultiFirmwareUpdateDriver protected: virtual void moduleOn() const = 0; virtual void init(bool inverted) const = 0; - virtual bool getByte(uint8_t& byte) const = 0; + virtual bool getByte(uint8_t & byte) const = 0; virtual void sendByte(uint8_t byte) const = 0; virtual void clear() const = 0; virtual void deinit(bool inverted) const {} private: - bool getRxByte(uint8_t& byte) const; + bool getRxByte(uint8_t & byte) const; bool checkRxByte(uint8_t byte) const; const char * waitForInitialSync(bool& inverted) const; - const char * getDeviceSignature(uint8_t* signature) const; + const char * getDeviceSignature(uint8_t * signature) const; const char * loadAddress(uint32_t offset) const; - const char * progPage(uint8_t* buffer, uint16_t size) const; + const char * progPage(uint8_t * buffer, uint16_t size) const; void leaveProgMode(bool inverted) const; }; #if defined(INTERNAL_MODULE_MULTI) - class MultiInternalUpdateDriver: public MultiFirmwareUpdateDriver { public: @@ -68,7 +68,7 @@ class MultiInternalUpdateDriver: public MultiFirmwareUpdateDriver intmoduleSerialStart(57600, true, USART_Parity_No, USART_StopBits_1, USART_WordLength_8b); } - bool getByte(uint8_t& byte) const override + bool getByte(uint8_t & byte) const override { return intmoduleFifo.pop(byte); } @@ -90,7 +90,6 @@ class MultiInternalUpdateDriver: public MultiFirmwareUpdateDriver }; static const MultiInternalUpdateDriver multiInternalUpdateDriver; - #endif class MultiExternalUpdateDriver: public MultiFirmwareUpdateDriver @@ -122,7 +121,7 @@ class MultiExternalUpdateDriver: public MultiFirmwareUpdateDriver telemetryPortInit(57600, TELEMETRY_SERIAL_DEFAULT); } - bool getByte(uint8_t& byte) const override + bool getByte(uint8_t & byte) const override { return telemetryGetByte(&byte); } @@ -150,12 +149,53 @@ class MultiExternalUpdateDriver: public MultiFirmwareUpdateDriver static const MultiExternalUpdateDriver multiExternalUpdateDriver; -bool MultiFirmwareUpdateDriver::getRxByte(uint8_t& byte) const +class MultiExtSportUpdateDriver: public MultiFirmwareUpdateDriver +{ + public: + MultiExtSportUpdateDriver(): MultiFirmwareUpdateDriver() {} + + protected: + void moduleOn() const override + { + EXTERNAL_MODULE_ON(); + } + + void init(bool inverted) const override + { + telemetryPortInit(57600, TELEMETRY_SERIAL_DEFAULT); + } + + bool getByte(uint8_t & byte) const override + { + return telemetryGetByte(&byte); + } + + void sendByte(uint8_t byte) const override + { + sportSendByte(byte); + telemetryPortSetDirectionInput(); + } + + void clear() const override + { + telemetryClearFifo(); + } + + void deinit(bool inverted) const override + { + telemetryPortInit(0, 0); + clear(); + } +}; + +static const MultiExtSportUpdateDriver multiExtSportUpdateDriver; + +bool MultiFirmwareUpdateDriver::getRxByte(uint8_t & byte) const { uint16_t time; - time = getTmr2MHz() ; - while ( (uint16_t) (getTmr2MHz() - time) < 25000 ) { // 12.5mS + time = getTmr2MHz(); + while ((uint16_t) (getTmr2MHz() - time) < 25000) { // 12.5mS if (getByte(byte)) { #if defined(DEBUG_EXT_MODULE_FLASH) @@ -175,11 +215,15 @@ bool MultiFirmwareUpdateDriver::checkRxByte(uint8_t byte) const return getRxByte(rxchar) ? rxchar == byte : false; } -const char * MultiFirmwareUpdateDriver::waitForInitialSync(bool& inverted) const +const char * MultiFirmwareUpdateDriver::waitForInitialSync(bool & inverted) const { uint8_t byte; int retries = 200; +#if defined(DEBUG_EXT_MODULE_FLASH) + TRACE("[Wait for Sync]"); +#endif + clear(); do { @@ -189,7 +233,7 @@ const char * MultiFirmwareUpdateDriver::waitForInitialSync(bool& inverted) const inverted = !inverted; init(inverted); } - + // Send sync request sendByte(STK_GET_SYNC); sendByte(CRC_EOP); @@ -197,24 +241,35 @@ const char * MultiFirmwareUpdateDriver::waitForInitialSync(bool& inverted) const getRxByte(byte); WDG_RESET(); - } while((byte != STK_INSYNC) && --retries); + } while ((byte != STK_INSYNC) && --retries); if (!retries) { return "NoSync"; } if (byte != STK_INSYNC) { +#if defined(DEBUG_EXT_MODULE_FLASH) + TRACE("[byte != STK_INSYNC]"); +#endif return "NoSync"; } if (!checkRxByte(STK_OK)) { +#if defined(DEBUG_EXT_MODULE_FLASH) + TRACE("[!checkRxByte(STK_OK)]"); +#endif return "NoSync"; } + // avoids sending STK_READ_SIGN with STK_OK + // in case the receiver is too slow changing + // to RX mode (half-duplex). + RTOS_WAIT_TICKS(1); + return nullptr; } -const char * MultiFirmwareUpdateDriver::getDeviceSignature(uint8_t* signature) const +const char * MultiFirmwareUpdateDriver::getDeviceSignature(uint8_t * signature) const { // Read signature sendByte(STK_READ_SIGN); @@ -224,7 +279,7 @@ const char * MultiFirmwareUpdateDriver::getDeviceSignature(uint8_t* signature) c if (!checkRxByte(STK_INSYNC)) return "NoSync"; - for (uint8_t i=0; i<4; i++) { + for (uint8_t i = 0; i < 4; i++) { if (!getRxByte(signature[i])) { return "NoSignature"; } @@ -244,10 +299,14 @@ const char * MultiFirmwareUpdateDriver::loadAddress(uint32_t offset) const return "NoSync"; } + // avoids sending next page back-to-back with STK_OK + // in case the receiver is to slow changing to RX mode (half-duplex). + RTOS_WAIT_TICKS(1); + return nullptr; } -const char * MultiFirmwareUpdateDriver::progPage(uint8_t* buffer, uint16_t size) const +const char * MultiFirmwareUpdateDriver::progPage(uint8_t * buffer, uint16_t size) const { sendByte(STK_PROG_PAGE); @@ -258,9 +317,10 @@ const char * MultiFirmwareUpdateDriver::progPage(uint8_t* buffer, uint16_t size) // flash/eeprom flag sendByte(0); - for (uint16_t i=0; i < size; i++) { + for (uint16_t i = 0; i < size; i++) { sendByte(buffer[i]); } + sendByte(CRC_EOP); if (!checkRxByte(STK_INSYNC)) @@ -271,7 +331,7 @@ const char * MultiFirmwareUpdateDriver::progPage(uint8_t* buffer, uint16_t size) do { getRxByte(byte); WDG_RESET(); - } while(!byte && --retries); + } while (!byte && --retries); if (!retries || (byte != STK_OK)) return "NoPageSync"; @@ -323,7 +383,7 @@ const char * MultiFirmwareUpdateDriver::flashFirmware(FIL * file, const char * l return result; } - uint8_t buffer[256]; + uint8_t buffer[256]; uint16_t pageSize = 128; uint32_t writeOffset = 0; @@ -340,7 +400,7 @@ const char * MultiFirmwareUpdateDriver::flashFirmware(FIL * file, const char * l while (!f_eof(file)) { progressHandler(label, STR_WRITING, file->fptr, file->obj.objsize); - UINT count=0; + UINT count = 0; memclear(buffer, pageSize); if (f_read(file, buffer, pageSize, &count) != FR_OK) { result = "Error reading file"; @@ -460,7 +520,7 @@ const char * MultiFirmwareInformation::readMultiFirmwareInformation(const char * if (f_open(&file, filename, FA_READ) != FR_OK) return "Error opening file"; - const char * err = readMultiFirmwareInformation(&file); + const char * err = readMultiFirmwareInformation(&file); f_close(&file); return err; @@ -473,7 +533,7 @@ const char * MultiFirmwareInformation::readMultiFirmwareInformation(FIL * file) if (f_size(file) < MULTI_SIGN_SIZE) return "File too small"; - + f_lseek(file, f_size(file) - MULTI_SIGN_SIZE); if (f_read(file, buffer, MULTI_SIGN_SIZE, &count) != FR_OK || count != MULTI_SIGN_SIZE) { return "Error reading file"; @@ -482,11 +542,11 @@ const char * MultiFirmwareInformation::readMultiFirmwareInformation(FIL * file) if (!memcmp(buffer, "multi-x", 7)) { return readV2Signature(buffer); } - + return readV1Signature(buffer); } -bool MultiDeviceFirmwareUpdate::flashFirmware(const char * filename, ProgressHandler progressHandler) +bool MultiDeviceFirmwareUpdate::flashFirmware(const char * filename, MultiModuleType type, ProgressHandler progressHandler) { FIL file; @@ -495,34 +555,38 @@ bool MultiDeviceFirmwareUpdate::flashFirmware(const char * filename, ProgressHan return false; } - MultiFirmwareInformation firmwareFile; - if (firmwareFile.readMultiFirmwareInformation(&file)) { - f_close(&file); - POPUP_WARNING("Not a valid file"); - return false; - } - f_lseek(&file, 0); - - if (module == EXTERNAL_MODULE) { - if (!firmwareFile.isMultiExternalFirmware()) { + if (type == MULTI_TYPE_MULTIMODULE) { + MultiFirmwareInformation firmwareFile; + if (firmwareFile.readMultiFirmwareInformation(&file)) { f_close(&file); - POPUP_WARNING(STR_NEEDS_FILE, STR_EXT_MULTI_SPEC); + POPUP_WARNING("Not a valid file"); return false; } - } - else { - if (!firmwareFile.isMultiInternalFirmware()) { - f_close(&file); - POPUP_WARNING(STR_NEEDS_FILE, STR_INT_MULTI_SPEC); - return false; + f_lseek(&file, 0); + + if (module == EXTERNAL_MODULE) { + if (!firmwareFile.isMultiExternalFirmware()) { + f_close(&file); + POPUP_WARNING(STR_NEEDS_FILE, STR_EXT_MULTI_SPEC); + return false; + } + } + else { + if (!firmwareFile.isMultiInternalFirmware()) { + f_close(&file); + POPUP_WARNING(STR_NEEDS_FILE, STR_INT_MULTI_SPEC); + return false; + } } } - const MultiFirmwareUpdateDriver* driver = &multiExternalUpdateDriver; + const MultiFirmwareUpdateDriver * driver = &multiExternalUpdateDriver; #if defined(INTERNAL_MODULE_MULTI) if (module == INTERNAL_MODULE) driver = &multiInternalUpdateDriver; #endif + if (type == MULTI_TYPE_ELRS) + driver = &multiExtSportUpdateDriver; pausePulses(); @@ -548,7 +612,7 @@ bool MultiDeviceFirmwareUpdate::flashFirmware(const char * filename, ProgressHan const char * result = driver->flashFirmware(&file, getBasename(filename), progressHandler); f_close(&file); - AUDIO_PLAY(AU_SPECIAL_SOUND_BEEP1 ); + AUDIO_PLAY(AU_SPECIAL_SOUND_BEEP1); BACKLIGHT_ENABLE(); #if defined(HARDWARE_INTERNAL_MODULE) @@ -570,7 +634,7 @@ bool MultiDeviceFirmwareUpdate::flashFirmware(const char * filename, ProgressHan // reset telemetry protocol telemetryInit(255); - + #if defined(HARDWARE_INTERNAL_MODULE) if (intPwr) { INTERNAL_MODULE_ON(); diff --git a/radio/src/io/multi_firmware_update.h b/radio/src/io/multi_firmware_update.h index 00dd5588f..837dcd7bf 100644 --- a/radio/src/io/multi_firmware_update.h +++ b/radio/src/io/multi_firmware_update.h @@ -18,8 +18,7 @@ * GNU General Public License for more details. */ -#ifndef OPENTX_MULTI_FIRMWARE_H -#define OPENTX_MULTI_FIRMWARE_H +#pragma once #include "ff.h" @@ -101,6 +100,11 @@ class MultiFirmwareInformation { const char * readV2Signature(const char * buffer); }; +enum MultiModuleType { + MULTI_TYPE_MULTIMODULE = 0, + MULTI_TYPE_ELRS, +}; + class MultiDeviceFirmwareUpdate { public: explicit MultiDeviceFirmwareUpdate(ModuleIndex module): @@ -108,10 +112,8 @@ class MultiDeviceFirmwareUpdate { { } - bool flashFirmware(const char * filename, ProgressHandler progressHandler); + bool flashFirmware(const char * filename, MultiModuleType type, ProgressHandler progressHandler); protected: ModuleIndex module; }; - -#endif //OPENTX_MULTI_FIRMWARE_H diff --git a/radio/src/keys.h b/radio/src/keys.h index ba9deff7a..487ecadb3 100644 --- a/radio/src/keys.h +++ b/radio/src/keys.h @@ -76,9 +76,22 @@ constexpr bool IS_VIRTUAL_KEY_EVENT(event_t event) // normal order of events is: FIRST, LONG, REPEAT, REPEAT, ..., BREAK #define EVT_KEY_MASK(e) ((e) & 0x1F) -#define EVT_KEY_FIRST(key) ((key)|_MSK_KEY_FIRST) // fired when key is pressed -#define EVT_KEY_LONG(key) ((key)|_MSK_KEY_LONG) // fired when key is held pressed for a while -#define EVT_KEY_REPT(key) ((key)|_MSK_KEY_REPT) // fired when key is held pressed long enough, fires multiple times with increasing speed + +constexpr event_t EVT_KEY_FIRST(uint8_t key) +{ + return (key | _MSK_KEY_FIRST); // fired when key is pressed +} + +constexpr event_t EVT_KEY_REPT(uint8_t key) +{ + return (key | _MSK_KEY_REPT); // fired when key is held pressed long enough, fires multiple times with increasing speed +} + +constexpr event_t EVT_KEY_LONG(uint8_t key) +{ + return (key | _MSK_KEY_LONG); // fired when key is held pressed for a while +} + constexpr event_t EVT_KEY_BREAK(uint8_t key) { return (key | _MSK_KEY_BREAK); // fired when key is released (short or long), but only if the event was not killed @@ -94,10 +107,30 @@ constexpr bool IS_TRIM_EVENT(event_t event) return (IS_KEY_EVENT(event) && EVT_KEY_MASK(event) >= TRM_BASE); } -#define IS_KEY_FIRST(evt) (((evt) & _MSK_KEY_FLAGS) == _MSK_KEY_FIRST) -#define IS_KEY_LONG(evt) (((evt) & _MSK_KEY_FLAGS) == _MSK_KEY_LONG) -#define IS_KEY_REPT(evt) (((evt) & _MSK_KEY_FLAGS) == _MSK_KEY_REPT) -#define IS_KEY_BREAK(evt) (((evt) & _MSK_KEY_FLAGS) == _MSK_KEY_BREAK) +inline bool IS_KEY_FIRST(event_t evt) +{ + return (evt & _MSK_KEY_FLAGS) == _MSK_KEY_FIRST; +} + +inline bool IS_KEY_REPT(event_t evt) +{ + return (evt & _MSK_KEY_FLAGS) == _MSK_KEY_REPT; +} + +inline bool IS_KEY_LONG(event_t evt) +{ + return (evt & _MSK_KEY_FLAGS) == _MSK_KEY_LONG; +} + +inline bool IS_KEY_BREAK(event_t evt) +{ + return (evt & _MSK_KEY_FLAGS) == _MSK_KEY_BREAK; +} + +inline bool IS_KEY_EVT(event_t evt, uint8_t key) +{ + return (evt & _MSK_KEY_FLAGS) && (EVT_KEY_MASK(evt) == key); +} #if defined(PCBXLITE) #define EVT_ROTARY_BREAK EVT_KEY_BREAK(KEY_ENTER) diff --git a/radio/src/lua/api_lcd.cpp b/radio/src/lua/api_lcd.cpp index d9c1078ac..eb53dad93 100644 --- a/radio/src/lua/api_lcd.cpp +++ b/radio/src/lua/api_lcd.cpp @@ -71,7 +71,8 @@ Reset the backlight timeout */ static int luaLcdResetBacklightTimeout(lua_State * L) { - if (!luaLcdAllowed) return 0; + if (!luaLcdAllowed) + return 0; resetBacklightTimeout(); return 0; } @@ -95,7 +96,8 @@ bottom line is 63. Drawing on an existing black pixel produces white pixel (TODO */ static int luaLcdDrawPoint(lua_State *L) { - if (!luaLcdAllowed) return 0; + if (!luaLcdAllowed) + return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); LcdFlags att = luaL_optunsigned(L, 3, 0); @@ -123,7 +125,8 @@ whole line will not be drawn (starting from OpenTX 2.1.5) */ static int luaLcdDrawLine(lua_State *L) { - if (!luaLcdAllowed) return 0; + if (!luaLcdAllowed) + return 0; coord_t x1 = luaL_checkunsigned(L, 1); coord_t y1 = luaL_checkunsigned(L, 2); coord_t x2 = luaL_checkunsigned(L, 3); @@ -228,7 +231,8 @@ See the [Appendix](../appendix/fonts.md) for available characters in each font s */ static int luaLcdDrawText(lua_State *L) { - if (!luaLcdAllowed) return 0; + if (!luaLcdAllowed) + return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); const char * s = luaL_checkstring(L, 3); @@ -259,7 +263,8 @@ Display a value formatted as time at (x,y) */ static int luaLcdDrawTimer(lua_State *L) { - if (!luaLcdAllowed) return 0; + if (!luaLcdAllowed) + return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); int seconds = luaL_checkinteger(L, 3); @@ -293,7 +298,8 @@ Display a number at (x,y) */ static int luaLcdDrawNumber(lua_State *L) { - if (!luaLcdAllowed) return 0; + if (!luaLcdAllowed) + return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); int val = luaL_checkinteger(L, 3); @@ -321,7 +327,8 @@ See getValue() */ static int luaLcdDrawChannel(lua_State *L) { - if (!luaLcdAllowed) return 0; + if (!luaLcdAllowed) + return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); int channel = -1; @@ -358,7 +365,8 @@ displays negated switch */ static int luaLcdDrawSwitch(lua_State *L) { - if (!luaLcdAllowed) return 0; + if (!luaLcdAllowed) + return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); int s = luaL_checkinteger(L, 3); @@ -382,7 +390,8 @@ Displays the name of the corresponding input as defined by the source at (x,y) */ static int luaLcdDrawSource(lua_State *L) { - if (!luaLcdAllowed) return 0; + if (!luaLcdAllowed) + return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); int s = luaL_checkinteger(L, 3); @@ -532,7 +541,8 @@ Omitting scale draws image in 1:1 scale and is faster than specifying 100 for sc */ static int luaLcdDrawBitmap(lua_State *L) { - if (!luaLcdAllowed) return 0; + if (!luaLcdAllowed) + return 0; const BitmapBuffer * b = checkBitmap(L, 1); if (b) { @@ -564,7 +574,8 @@ Draw a bitmap at (x,y) */ static int luaLcdDrawPixmap(lua_State *L) { - if (!luaLcdAllowed) return 0; + if (!luaLcdAllowed) + return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); const char * filename = luaL_checkstring(L, 3); @@ -597,7 +608,8 @@ Draw a rectangle from top left corner (x,y) of specified width and height */ static int luaLcdDrawRectangle(lua_State *L) { - if (!luaLcdAllowed) return 0; + if (!luaLcdAllowed) + return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); int w = luaL_checkinteger(L, 3); @@ -629,7 +641,8 @@ Draw a solid rectangle from top left corner (x,y) of specified width and height */ static int luaLcdDrawFilledRectangle(lua_State *L) { - if (!luaLcdAllowed) return 0; + if (!luaLcdAllowed) + return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); int w = luaL_checkinteger(L, 3); @@ -661,7 +674,8 @@ Draw a simple gauge that is filled based upon fill value */ static int luaLcdDrawGauge(lua_State *L) { - if (!luaLcdAllowed) return 0; + if (!luaLcdAllowed) + return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); int w = luaL_checkinteger(L, 3); @@ -699,7 +713,8 @@ the right side of title bar. (i.e. idx=2, cnt=5, display `2/5`) */ static int luaLcdDrawScreenTitle(lua_State *L) { - if (!luaLcdAllowed) return 0; + if (!luaLcdAllowed) + return 0; const char * str = luaL_checkstring(L, 1); int idx = luaL_checkinteger(L, 2); int cnt = luaL_checkinteger(L, 3); @@ -739,7 +754,8 @@ Draw a combo box */ static int luaLcdDrawCombobox(lua_State *L) { - if (!luaLcdAllowed) return 0; + if (!luaLcdAllowed) + return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); int w = luaL_checkinteger(L, 3); @@ -818,7 +834,13 @@ Set a color for specific area * `MENU_BGCOLOR` * `HEADER_ICON_BGCOLOR` * `HEADER_CURRENT_BGCOLOR` + * `MAINVIEW_PANES_COLOR` + * `MAINVIEW_GRAPHICS_COLOR` * `OVERLAY_COLOR` + * `BARGRAPH1_COLOR` + * `BARGRAPH2_COLOR` + * `BARGRAPH_BGCOLOR` + * `CUSTOM_COLOR` @param color (number) color in 5/6/5 rgb format. The following prefined colors are available * `WHITE` @@ -831,19 +853,40 @@ Set a color for specific area * `RED` * `DARKRED` -@notice Only available on Horus +@notice Only available on Colorlcd radios @status current Introduced in 2.2.0 */ static int luaLcdSetColor(lua_State *L) { - if (!luaLcdAllowed) return 0; + if (!luaLcdAllowed) + return 0; unsigned int index = luaL_checkunsigned(L, 1) >> 16; unsigned int color = luaL_checkunsigned(L, 2); lcdColorTable[index] = color; return 0; } +/*luadoc +@function lcd.getColor(area) + +Get the color for specific area : see lcd.setColor for area list + +@notice Only available on Colorlcd radios + +@status current Introduced in 2.3.11 +*/ + +static int luaLcdGetColor(lua_State *L) +{ + if (!luaLcdAllowed) + return 0; + + unsigned int index = luaL_checkunsigned(L, 1) >> 16; + lua_pushunsigned(L, lcdColorTable[index]); + return 1; +} + /*luadoc @function lcd.RGB(r, g, b) @@ -857,13 +900,14 @@ Returns a 5/6/5 rgb color code, that can be used with lcd.setColor @retval number (integer) rgb color expressed in 5/6/5 format -@notice Only available on Horus +@notice Only available on Colorlcd radios @status current Introduced in 2.2.0 */ static int luaRGB(lua_State *L) { - if (!luaLcdAllowed) return 0; + if (!luaLcdAllowed) + return 0; int r = luaL_checkinteger(L, 1); int g = luaL_checkinteger(L, 2); int b = luaL_checkinteger(L, 3); @@ -890,6 +934,7 @@ const luaL_Reg lcdLib[] = { #if defined(COLORLCD) { "drawBitmap", luaLcdDrawBitmap }, { "setColor", luaLcdSetColor }, + { "getColor", luaLcdGetColor }, { "RGB", luaRGB }, #else { "getLastPos", luaLcdGetLastPos }, diff --git a/radio/src/lua/api_model.cpp b/radio/src/lua/api_model.cpp index 334e1d4ca..90c19f4d9 100644 --- a/radio/src/lua/api_model.cpp +++ b/radio/src/lua/api_model.cpp @@ -1518,16 +1518,16 @@ Get Telemetry Sensor parameters @param sensor (unsigned number) sensor number (use 0 for sensor 1) -@retval nil requested logical switch does not exist +@retval nil requested sensor does not exist -@retval table logical switch data: - * `func` (number) function index - * `v1` (number) V1 value (index) - * `v2` (number) V2 value (index or value) - * `v3` (number) V3 value (index or value) - * `and` (number) AND switch index - * `delay` (number) delay (time in 1/10 s) - * `duration` (number) duration (time in 1/10 s) +@retval table with sensor data: + * `type` (number) 0 = custom, 1 = calculated + * `name` (string) Name + * `unit` (number) See list of units in the appendix of the OpenTX Lua Reference Guide + * `prec` (number) Number of decimals + * `id` (number) Only custom sensors + * `instance` (number) Only custom sensors + * `formula` (number) Only calculated sensors. 0 = Add etc. see list of formula choices in Companion popup @status current Introduced in 2.3.0 */ @@ -1564,7 +1564,7 @@ Reset Telemetry Sensor parameters @retval nil -@status current Introduced in 2.3.0 +@status current Introduced in 2.3.11 */ static int luaModelResetSensor(lua_State *L) { @@ -1572,7 +1572,7 @@ static int luaModelResetSensor(lua_State *L) if (idx < MAX_TELEMETRY_SENSORS) { telemetryItems[idx].clear(); } - + lua_pushnil(L); return 1; } diff --git a/radio/src/opentx.h b/radio/src/opentx.h index b2dfb6753..156bd9d3d 100644 --- a/radio/src/opentx.h +++ b/radio/src/opentx.h @@ -18,8 +18,7 @@ * GNU General Public License for more details. */ -#ifndef _OPENTX_H_ -#define _OPENTX_H_ +#pragma once #include #include "definitions.h" @@ -1115,6 +1114,7 @@ union ReusableBuffer #if defined(GHOST) struct { GhostMenuData line[GHST_MENU_LINES + 1]; + uint8_t menuStatus; uint8_t menuAction; uint8_t buttonAction; } ghostMenu; @@ -1313,4 +1313,3 @@ inline bool isAsteriskDisplayed() #include "thirdparty/libACCESS/libAccess.h" #endif -#endif // _OPENTX_H_ diff --git a/radio/src/pulses/ghost.cpp b/radio/src/pulses/ghost.cpp index 40cf551db..4074bce47 100755 --- a/radio/src/pulses/ghost.cpp +++ b/radio/src/pulses/ghost.cpp @@ -22,8 +22,6 @@ uint8_t createGhostMenuControlFrame(uint8_t * frame, int16_t * pulses) { - moduleState[EXTERNAL_MODULE].counter = GHST_FRAME_CHANNEL; - uint8_t * buf = frame; #if SPORT_MAX_BAUDRATE < 400000 *buf++ = g_eeGeneral.telemetryBaudrate == GHST_TELEMETRY_RATE_400K ? GHST_ADDR_MODULE_SYM : GHST_ADDR_MODULE_ASYM; @@ -118,5 +116,7 @@ void setupPulsesGhost() extmodulePulsesData.ghost.length = createGhostMenuControlFrame(pulses, &channelOutputs[g_model.moduleData[EXTERNAL_MODULE].channelsStart]); else extmodulePulsesData.ghost.length = createGhostChannelsFrame(pulses, &channelOutputs[g_model.moduleData[EXTERNAL_MODULE].channelsStart]); + + moduleState[EXTERNAL_MODULE].counter = GHST_FRAME_CHANNEL; } } \ No newline at end of file diff --git a/radio/src/pulses/modules_constants.h b/radio/src/pulses/modules_constants.h index 0ddf2477a..15a2c2283 100644 --- a/radio/src/pulses/modules_constants.h +++ b/radio/src/pulses/modules_constants.h @@ -121,7 +121,7 @@ enum ModuleSubtypeMulti { MODULE_SUBTYPE_MULTI_MJXQ, MODULE_SUBTYPE_MULTI_SHENQI, MODULE_SUBTYPE_MULTI_FY326, - MODULE_SUBTYPE_MULTI_SFHSS, + MODULE_SUBTYPE_MULTI_FUTABA, MODULE_SUBTYPE_MULTI_J6PRO, //20 MODULE_SUBTYPE_MULTI_FQ777, MODULE_SUBTYPE_MULTI_ASSAN, @@ -152,7 +152,7 @@ enum ModuleSubtypeMulti { MODULE_SUBTYPE_MULTI_REDPINE, MODULE_SUBTYPE_MULTI_POTENSIC, MODULE_SUBTYPE_MULTI_ZSX, - MODULE_SUBTYPE_MULTI_FLYZONE, //50 + MODULE_SUBTYPE_MULTI_HEIGHT, //50 MODULE_SUBTYPE_MULTI_SCANNER, MODULE_SUBTYPE_MULTI_FRSKYX_RX, MODULE_SUBTYPE_MULTI_AFHDS2A_RX, @@ -172,7 +172,15 @@ enum ModuleSubtypeMulti { MODULE_SUBTYPE_MULTI_DSM_RX, MODULE_SUBTYPE_MULTI_JJRC345, MODULE_SUBTYPE_MULTI_Q90C, - MODULE_SUBTYPE_MULTI_LAST = MODULE_SUBTYPE_MULTI_Q90C + MODULE_SUBTYPE_MULTI_KYOSHO, //70 + MODULE_SUBTYPE_MULTI_RLINK, + MODULE_SUBTYPE_MULTI_ELRS, + MODULE_SUBTYPE_MULTI_REALACC, + MODULE_SUBTYPE_MULTI_OMP, + MODULE_SUBTYPE_MULTI_MLINK, //75 + MODULE_SUBTYPE_MULTI_WFLY2, + MODULE_SUBTYPE_MULTI_E016HV2, + MODULE_SUBTYPE_MULTI_LAST = MODULE_SUBTYPE_MULTI_E016HV2 }; #define MODULE_SUBTYPE_MULTI_XN297DP 63-3 diff --git a/radio/src/pulses/modules_helpers.h b/radio/src/pulses/modules_helpers.h index da72601e9..2c92e65ff 100644 --- a/radio/src/pulses/modules_helpers.h +++ b/radio/src/pulses/modules_helpers.h @@ -284,9 +284,14 @@ inline bool isModulePXX1(uint8_t idx) return isModuleTypePXX1(g_model.moduleData[idx].type); } +inline bool isModuleXJTLite(uint8_t idx) +{ + return g_model.moduleData[idx].type == MODULE_TYPE_XJT_LITE_PXX2; +} + inline bool isModulePXX2(uint8_t idx) { - return isModuleISRM(idx) || isModuleR9MAccess(idx); + return isModuleISRM(idx) || isModuleR9MAccess(idx) || isModuleXJTLite(idx); } inline bool isModuleRFAccess(uint8_t idx) diff --git a/radio/src/sdcard.h b/radio/src/sdcard.h index d13ef205f..906679285 100644 --- a/radio/src/sdcard.h +++ b/radio/src/sdcard.h @@ -76,6 +76,7 @@ const char RADIO_SETTINGS_YAML_PATH[] = RADIO_PATH "/radio.yml"; #define SPORT_FIRMWARE_EXT ".frk" #define FRSKY_FIRMWARE_EXT ".frsk" #define MULTI_FIRMWARE_EXT ".bin" +#define ELRS_FIRMWARE_EXT ".elrs" #define YAML_EXT ".yml" #if defined(COLORLCD) diff --git a/radio/src/targets/common/arm/CMakeLists.txt b/radio/src/targets/common/arm/CMakeLists.txt index 689d0ac51..b57b2d8c1 100644 --- a/radio/src/targets/common/arm/CMakeLists.txt +++ b/radio/src/targets/common/arm/CMakeLists.txt @@ -236,12 +236,8 @@ set(FIRMWARE_TARGET_SRC ${FIRMWARE_TARGET_SRC} keys_driver.cpp diskio.cpp -) - -set(TARGET_SRC - ${TARGET_SRC} telemetry_driver.cpp - ) +) set(FIRMWARE_SRC ${FIRMWARE_SRC} diff --git a/radio/src/targets/common/arm/stm32/aux_serial_driver.cpp b/radio/src/targets/common/arm/stm32/aux_serial_driver.cpp index 555b1b22a..a4d4f4fcc 100644 --- a/radio/src/targets/common/arm/stm32/aux_serial_driver.cpp +++ b/radio/src/targets/common/arm/stm32/aux_serial_driver.cpp @@ -150,7 +150,7 @@ void auxSerialInit(unsigned int mode, unsigned int protocol) break; case UART_MODE_SBUS_TRAINER: - auxSerialSetup(SBUS_BAUDRATE, false, USART_WordLength_9b, USART_Parity_Even, USART_StopBits_2); // 2 stop bits requires USART_WordLength_9b + auxSerialSetup(SBUS_BAUDRATE, true, USART_WordLength_9b, USART_Parity_Even, USART_StopBits_2); // 2 stop bits requires USART_WordLength_9b AUX_SERIAL_POWER_ON(); break; @@ -238,10 +238,6 @@ extern "C" void AUX_SERIAL_USART_IRQHandler(void) #if defined(LUA) & !defined(CLI) if (luaRxFifo && auxSerialMode == UART_MODE_LUA) luaRxFifo->push(data); -#endif -#if !defined(BOOT) - if (auxSerialMode == UART_MODE_SBUS_TRAINER) - trainerSbusFifo.push(data); #endif } status = AUX_SERIAL_USART->SR; @@ -352,7 +348,7 @@ void aux2SerialInit(unsigned int mode, unsigned int protocol) break; case UART_MODE_SBUS_TRAINER: - aux2SerialSetup(SBUS_BAUDRATE, false, USART_WordLength_9b, USART_Parity_Even, USART_StopBits_2); // 2 stop bits requires USART_WordLength_9b + aux2SerialSetup(SBUS_BAUDRATE, true, USART_WordLength_9b, USART_Parity_Even, USART_StopBits_2); // 2 stop bits requires USART_WordLength_9b AUX2_SERIAL_POWER_ON(); break; @@ -438,11 +434,6 @@ extern "C" void AUX2_SERIAL_USART_IRQHandler(void) if (luaRxFifo && aux2SerialMode == UART_MODE_LUA) { luaRxFifo->push(data); } -#endif -#if !defined(BOOT) - if (aux2SerialMode == UART_MODE_SBUS_TRAINER) { - trainerSbusFifo.push(data); - } #endif } status = AUX2_SERIAL_USART->SR; diff --git a/radio/src/targets/common/arm/stm32/usbd_desc.c b/radio/src/targets/common/arm/stm32/usbd_desc.c index cec340e69..8b13a8b0c 100644 --- a/radio/src/targets/common/arm/stm32/usbd_desc.c +++ b/radio/src/targets/common/arm/stm32/usbd_desc.c @@ -54,28 +54,32 @@ * @{ */ -#define USBD_VID 0x0483 +#define USBD_VID_STM 0x0483 // STM Vendor ID +#define USBD_VID_PID_CODES 0x1209 // https://pid.codes #define USBD_LANGID_STRING 0x409 +#define USBD_MANUFACTURER_STRING "OpenTX" #define USBD_SERIALNUMBER_FS_STRING "00000000001B" - #if defined(BOOT) #define USBD_MSC_PRODUCT_FS_STRING USB_NAME " Bootloader" #else #define USBD_MSC_PRODUCT_FS_STRING USB_NAME " Mass Storage" #endif +#define USBD_MSC_VID USBD_VID_STM #define USBD_MSC_PID 0x5720 #define USBD_MSC_CONFIGURATION_FS_STRING "MSC Config" #define USBD_MSC_INTERFACE_FS_STRING "MSC Interface" -#define USBD_HID_PID 0x5710 +#define USBD_HID_VID USBD_VID_PID_CODES +#define USBD_HID_PID 0x4F54 // OpenTX assigned PID #define USBD_HID_PRODUCT_FS_STRING USB_NAME " Joystick" #define USBD_HID_CONFIGURATION_FS_STRING "HID Config" #define USBD_HID_INTERFACE_FS_STRING "HID Interface" -#define USBD_CDC_PID 0x5740 // do not change, this ID is used by the ST USB driver for Windows +#define USBD_CDC_VID USBD_VID_STM +#define USBD_CDC_PID 0x5740 // do not change, this ID is used by the ST USB driver for Windows #define USBD_CDC_PRODUCT_FS_STRING USB_NAME " Serial Port" #define USBD_CDC_CONFIGURATION_FS_STRING "VSP Config" #define USBD_CDC_INTERFACE_FS_STRING "VSP Interface" @@ -125,20 +129,29 @@ __ALIGN_BEGIN uint8_t USBD_StrDesc[USB_MAX_STR_DESC_SIZ] __ALIGN_END ; // modifi * @param length : pointer to data length variable * @retval pointer to descriptor buffer */ -uint8_t * USBD_USR_DeviceDescriptor( uint8_t speed , uint16_t *length) +uint8_t * USBD_USR_DeviceDescriptor( uint8_t speed , uint16_t *length) { - int pid=0; + int vid, pid; switch (getSelectedUsbMode()) { case USB_JOYSTICK_MODE: + vid = USBD_HID_VID; pid = USBD_HID_PID; break; + case USB_SERIAL_MODE: + vid = USBD_CDC_VID; pid = USBD_CDC_PID; break; + case USB_MASS_STORAGE_MODE: + vid = USBD_MSC_VID; pid = USBD_MSC_PID; break; + + default: + vid = 0; + pid = 0; } /* USB Standard Device Descriptor */ @@ -152,10 +165,10 @@ uint8_t * USBD_USR_DeviceDescriptor( uint8_t speed , uint16_t *length) 0x00, /*bDeviceSubClass*/ 0x00, /*bDeviceProtocol*/ USB_OTG_MAX_EP0_SIZE, /*bMaxPacketSize*/ - LOBYTE(USBD_VID), /*idVendor*/ - HIBYTE(USBD_VID), /*idVendor*/ - LOBYTE(pid), /*idVendor*/ - HIBYTE(pid), /*idVendor*/ + LOBYTE(vid), /*idVendor*/ + HIBYTE(vid), /*idVendor*/ + LOBYTE(pid), /*idVendor*/ + HIBYTE(pid), /*idVendor*/ 0x00, /*bcdDevice rel. 2.00*/ 0x02, USBD_IDX_MFC_STR, /*Index of manufacturer string*/ diff --git a/radio/src/targets/horus/board.h b/radio/src/targets/horus/board.h index 6d240c126..05e4d4450 100644 --- a/radio/src/targets/horus/board.h +++ b/radio/src/targets/horus/board.h @@ -637,7 +637,11 @@ void sportUpdatePowerInit(); #endif // Aux serial port driver -#define DEBUG_BAUDRATE 115200 +#if defined(RADIO_TX16S) + #define DEBUG_BAUDRATE 400000 +#else + #define DEBUG_BAUDRATE 115200 +#endif #if defined(AUX_SERIAL_GPIO) extern uint8_t auxSerialMode; void auxSerialInit(unsigned int mode, unsigned int protocol); @@ -711,6 +715,7 @@ void bluetoothDisable(); extern DMAFifo<512> telemetryFifo; typedef DMAFifo<32> AuxSerialRxFifo; extern AuxSerialRxFifo auxSerialRxFifo; +extern AuxSerialRxFifo aux2SerialRxFifo; extern volatile uint32_t externalModulePort; #endif diff --git a/radio/src/targets/horus/trainer_driver.cpp b/radio/src/targets/horus/trainer_driver.cpp index a4f0c7b6b..ce649c688 100644 --- a/radio/src/targets/horus/trainer_driver.cpp +++ b/radio/src/targets/horus/trainer_driver.cpp @@ -160,9 +160,16 @@ extern "C" void TRAINER_TIMER_IRQHandler() int sbusGetByte(uint8_t * byte) { switch (currentTrainerMode) { -#if defined(AUX_SERIAL) +#if defined(AUX_SERIAL) || defined(AUX2_SERIAL) case TRAINER_MODE_MASTER_BATTERY_COMPARTMENT: - return trainerSbusFifo.pop(*byte); +#if defined(AUX_SERIAL) + if (auxSerialMode == UART_MODE_SBUS_TRAINER) + return auxSerialRxFifo.pop(*byte); +#endif +#if defined(AUX2_SERIAL) + if (aux2SerialMode == UART_MODE_SBUS_TRAINER) + return aux2SerialRxFifo.pop(*byte); +#endif #endif default: return false; diff --git a/radio/src/targets/simu/simpgmspace.cpp b/radio/src/targets/simu/simpgmspace.cpp index a6db988f4..eacf06bd7 100644 --- a/radio/src/targets/simu/simpgmspace.cpp +++ b/radio/src/targets/simu/simpgmspace.cpp @@ -42,6 +42,8 @@ char * main_thread_error = nullptr; bool simu_shutdown = false; bool simu_running = false; +uint32_t telemetryErrors = 0; + #if defined(STM32) GPIO_TypeDef gpioa, gpiob, gpioc, gpiod, gpioe, gpiof, gpiog, gpioh, gpioi, gpioj; TIM_TypeDef tim1, tim2, tim3, tim4, tim5, tim6, tim7, tim8, tim9, tim10; @@ -470,6 +472,47 @@ void sportUpdatePowerInit() { } +void telemetryPortSetDirectionInput() +{ +} + +void telemetryPortSetDirectionOutput() +{ +} + +void rxPdcUsart( void (*pChProcess)(uint8_t x) ) +{ +} + +void telemetryPortInit(uint32_t baudrate, uint8_t mode) +{ +} + +bool telemetryGetByte(uint8_t * byte) +{ + return false; +} + +void telemetryClearFifo() +{ +} + +void telemetryPortInvertedInit(uint32_t baudrate) +{ +} + +void sportSendByte(uint8_t byte) +{ +} + +void sportSendBuffer(const uint8_t * buffer, uint32_t count) +{ +} + +void check_telemetry_exti() +{ +} + void boardInit() { } diff --git a/radio/src/targets/sky9x/CMakeLists.txt b/radio/src/targets/sky9x/CMakeLists.txt index 64a41f0e0..cad5226a5 100644 --- a/radio/src/targets/sky9x/CMakeLists.txt +++ b/radio/src/targets/sky9x/CMakeLists.txt @@ -125,9 +125,13 @@ set(FIRMWARE_TARGET_SRC MEDSdcard.c ) +set(FIRMWARE_TARGET_SRC + ${FIRMWARE_TARGET_SRC} + telemetry_driver.cpp + ) + set(TARGET_SRC ${TARGET_SRC} - telemetry_driver.cpp adc_driver.cpp pulses_driver.cpp audio_driver.cpp diff --git a/radio/src/targets/sky9x/board.h b/radio/src/targets/sky9x/board.h index d0ea38747..f96a57298 100644 --- a/radio/src/targets/sky9x/board.h +++ b/radio/src/targets/sky9x/board.h @@ -399,10 +399,8 @@ void debugPutc(const char c); // Telemetry driver void telemetryPortInit(uint32_t baudrate, uint8_t mode); -inline void telemetryPortSetDirectionOutput() -{ -} -uint32_t telemetryTransmitPending(); +void telemetryPortSetDirectionOutput(); +void telemetryPortSetDirectionInput(); void telemetryTransmitBuffer(const uint8_t * buffer, uint32_t size); void rxPdcUsart( void (*pChProcess)(uint8_t x) ); void sportSendBuffer(const uint8_t * buffer, uint32_t size); diff --git a/radio/src/targets/sky9x/telemetry_driver.cpp b/radio/src/targets/sky9x/telemetry_driver.cpp index 4875c5d35..8efa83951 100644 --- a/radio/src/targets/sky9x/telemetry_driver.cpp +++ b/radio/src/targets/sky9x/telemetry_driver.cpp @@ -93,10 +93,8 @@ void startPdcUsartReceive() { Usart *pUsart = SECOND_USART; TelemetryInBuffer.outPtr = TelemetryInBuffer.fifo ; -#ifndef SIMU pUsart->US_RPR = (uint32_t)TelemetryInBuffer.fifo ; pUsart->US_RNPR = (uint32_t)TelemetryInBuffer.fifo ; -#endif pUsart->US_RCR = RX_UART_BUFFER_SIZE ; pUsart->US_RNCR = RX_UART_BUFFER_SIZE ; pUsart->US_PTCR = US_PTCR_RXTEN ; @@ -104,7 +102,6 @@ void startPdcUsartReceive() void rxPdcUsart( void (*pChProcess)(uint8_t x) ) { -#if !defined(SIMU) Usart *pUsart = SECOND_USART; uint8_t *ptr ; uint8_t *endPtr ; @@ -132,7 +129,6 @@ void rxPdcUsart( void (*pChProcess)(uint8_t x) ) pUsart->US_RNPR = (uint32_t)TelemetryInBuffer.fifo ; pUsart->US_RNCR = RX_UART_BUFFER_SIZE ; } -#endif } uint32_t txPdcUsart(const uint8_t * buffer, uint32_t size) @@ -140,9 +136,7 @@ uint32_t txPdcUsart(const uint8_t * buffer, uint32_t size) Usart * pUsart = SECOND_USART; if (pUsart->US_TNCR == 0) { -#ifndef SIMU pUsart->US_TNPR = (uint32_t)buffer ; -#endif pUsart->US_TNCR = size ; pUsart->US_PTCR = US_PTCR_TXTEN ; return 1 ; @@ -150,6 +144,7 @@ uint32_t txPdcUsart(const uint8_t * buffer, uint32_t size) return 0 ; } +/* uint32_t telemetryTransmitPending() { Usart *pUsart = SECOND_USART; @@ -164,13 +159,20 @@ uint32_t telemetryTransmitPending() return x ; } +*/ + +void telemetryPortSetDirectionOutput() +{ +} + +void telemetryPortSetDirectionInput() +{ +} void telemetryPortInit(uint32_t baudrate, uint8_t mode) { -#if !defined(SIMU) UART2_Configure(baudrate, Master_frequency, mode); startPdcUsartReceive(); -#endif } void sportSendBuffer(const uint8_t * buffer, uint32_t size) diff --git a/radio/src/targets/taranis/CMakeLists.txt b/radio/src/targets/taranis/CMakeLists.txt index c3c96548a..f63f9ef11 100644 --- a/radio/src/targets/taranis/CMakeLists.txt +++ b/radio/src/targets/taranis/CMakeLists.txt @@ -135,7 +135,6 @@ elseif(PCB STREQUAL X7) set(LUA_EXPORT lua_export_t12) add_definitions(-DRADIO_T12) add_definitions(-DEEPROM_VARIANT=0x4001) - add_definitions(-DMANUFACTURER_JUMPER) elseif(PCBREV STREQUAL TX12) option(INTERNAL_MODULE_MULTI "Support for MULTI internal module" ON) set(FLAVOUR tx12) @@ -146,6 +145,7 @@ elseif(PCB STREQUAL X7) set(ROTARY_ENCODER YES) set(LUA_EXPORT lua_export_tx12) set(BLUETOOTH NO) + set(USB_CHARGER YES) add_definitions(-DRADIO_TX12) add_definitions(-DEEPROM_VARIANT=0x4002) add_definitions(-DMANUFACTURER_RADIOMASTER) @@ -347,6 +347,11 @@ if(ROTARY_ENCODER) ) endif() +if(USB_CHARGER) + set(TARGET_SRC ${TARGET_SRC} usb_charger_driver.cpp) + add_definitions(-DUSB_CHARGER) +endif() + if(BLUETOOTH) add_definitions(-DBLUETOOTH) set(TARGET_SRC diff --git a/radio/src/targets/taranis/board.cpp b/radio/src/targets/taranis/board.cpp index b038fc0f7..d86a82f2d 100644 --- a/radio/src/targets/taranis/board.cpp +++ b/radio/src/targets/taranis/board.cpp @@ -92,7 +92,8 @@ void boardInit() TRAINER_RCC_AHB1Periph | TRAINER_MODULE_RCC_AHB1Periph | BT_RCC_AHB1Periph | - GYRO_RCC_AHB1Periph, + GYRO_RCC_AHB1Periph | + USB_CHARGER_RCC_AHB1Periph, ENABLE); RCC_APB1PeriphClockCmd(ROTARY_ENCODER_RCC_APB1Periph | @@ -193,6 +194,10 @@ void boardInit() toplcdInit(); #endif +#if defined(USB_CHARGER) + usbChargerInit(); +#endif + if (HAS_SPORT_UPDATE_CONNECTOR()) { sportUpdateInit(); } diff --git a/radio/src/targets/taranis/board.h b/radio/src/targets/taranis/board.h index d9092fcdc..6ffff9df9 100644 --- a/radio/src/targets/taranis/board.h +++ b/radio/src/targets/taranis/board.h @@ -863,6 +863,10 @@ void bluetoothDisable(); #define IS_BLUETOOTH_CHIP_PRESENT() (true) #endif +// USB Charger +void usbChargerInit(); +bool usbChargerLed(); + // LED driver void ledInit(); void ledOff(); diff --git a/radio/src/targets/taranis/hal.h b/radio/src/targets/taranis/hal.h index d6cd67241..778febeab 100644 --- a/radio/src/targets/taranis/hal.h +++ b/radio/src/targets/taranis/hal.h @@ -1431,6 +1431,16 @@ #define PCBREV_RCC_AHB1Periph 0 #endif + +// USB Charger +#if defined(USB_CHARGER) + #define USB_CHARGER_RCC_AHB1Periph RCC_AHB1Periph_GPIOB + #define USB_CHARGER_GPIO GPIOB + #define USB_CHARGER_GPIO_PIN GPIO_Pin_5 // PB.05 +#else + #define USB_CHARGER_RCC_AHB1Periph 0 +#endif + // S.Port update connector #if defined(PCBXLITE) #define SPORT_MAX_BAUDRATE 250000 // not tested @@ -1446,7 +1456,7 @@ #define SPORT_UPDATE_PWR_GPIO_PIN GPIO_Pin_3 // PB.03 #define GPIO_SPORT_UPDATE_PWR_GPIO_ON GPIO_SetBits #define GPIO_SPORT_UPDATE_PWR_GPIO_OFF GPIO_ResetBits -#elif defined(PCBX7) +#elif defined(RADIO_X7) #define SPORT_MAX_BAUDRATE 250000 // < 400000 #define SPORT_UPDATE_RCC_AHB1Periph RCC_AHB1Periph_GPIOB #define SPORT_UPDATE_PWR_GPIO GPIOB diff --git a/radio/src/targets/taranis/usb_charger_driver.cpp b/radio/src/targets/taranis/usb_charger_driver.cpp new file mode 100644 index 000000000..7e92c6dbc --- /dev/null +++ b/radio/src/targets/taranis/usb_charger_driver.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "opentx.h" + +void usbChargerInit() +{ + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Pin = USB_CHARGER_GPIO_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_Init(USB_CHARGER_GPIO, &GPIO_InitStructure); +} + +bool usbChargerLed() +{ + return (GPIO_ReadInputDataBit(USB_CHARGER_GPIO, USB_CHARGER_GPIO_PIN) == Bit_RESET && usbPlugged()); +} diff --git a/radio/src/telemetry/ghost.cpp b/radio/src/telemetry/ghost.cpp index 5a8dd681e..098e9c990 100755 --- a/radio/src/telemetry/ghost.cpp +++ b/radio/src/telemetry/ghost.cpp @@ -192,11 +192,10 @@ void processGhostTelemetryFrame() { GhostMenuFrame * packet; GhostMenuData * lineData; - packet = (GhostMenuFrame * ) telemetryRxBuffer; lineData = (GhostMenuData *) &reusableBuffer.ghostMenu.line[packet->lineIndex]; lineData->splitLine = 0; - reusableBuffer.ghostMenu.menuAction = packet->menuFlags; + reusableBuffer.ghostMenu.menuStatus = packet->menuStatus; lineData->lineFlags = packet->lineFlags; for (uint8_t i = 0; i < GHST_MENU_CHARS; i++) { if (packet->menuText[i] == 0x7C) { @@ -208,8 +207,6 @@ void processGhostTelemetryFrame() } } lineData->menuText[GHST_MENU_CHARS] = '\0'; - if (packet->lineIndex == GHST_MENU_LINES - 1) - lineData->menuUpdateNeeded = true; break; } diff --git a/radio/src/telemetry/ghost.h b/radio/src/telemetry/ghost.h index 84884bc5a..0a3195835 100755 --- a/radio/src/telemetry/ghost.h +++ b/radio/src/telemetry/ghost.h @@ -142,6 +142,13 @@ enum GhostMenuControl GHST_MENU_CTRL_REDRAW = 0X04, }; +enum GhostMenuStatus +{ + GHST_MENU_STATUS_UNOPENED = 0x00, + GHST_MENU_STATUS_OPENED = 0x01, + GHST_MENU_STATUS_CLOSING = 0x02, +}; + enum GhostFrames { GHST_FRAME_CHANNEL, @@ -157,8 +164,8 @@ struct GhostMenuFrame uint8_t address; uint8_t length ; uint8_t packetId; - uint8_t menuFlags; // GHST_MENU_CTRL - uint8_t lineFlags; // Carat states, Inverse, Bold for each of Menu Label, and Value + uint8_t menuStatus; // GhostMenuStatus + uint8_t lineFlags; // GhostLineFlags uint8_t lineIndex; // 0 = first line unsigned char menuText[GHST_MENU_CHARS]; uint8_t crc; @@ -166,9 +173,9 @@ struct GhostMenuFrame struct GhostMenuData { - uint8_t menuFlags; // Update Line, Clear Menu, etc. + uint8_t menuStatus; // Update Line, Clear Menu, etc. uint8_t lineFlags; // Carat states, Inverse, Bold for each of Menu Label, and Value uint8_t splitLine; // Store beginning of Value substring char menuText[GHST_MENU_CHARS + 1]; - uint8_t menuUpdateNeeded; }; + diff --git a/radio/src/telemetry/telemetry.cpp b/radio/src/telemetry/telemetry.cpp index 52799763e..3979ecb0e 100644 --- a/radio/src/telemetry/telemetry.cpp +++ b/radio/src/telemetry/telemetry.cpp @@ -288,6 +288,7 @@ void telemetryInit(uint8_t protocol) #if defined(LUA) outputTelemetryBuffer.reset(); #endif + telemetryPortSetDirectionInput(); } else if (protocol == PROTOCOL_TELEMETRY_SPEKTRUM) { // Spektrum's own small race RX (SPM4648) uses 125000 8N1, use the same since there is no real standard @@ -322,7 +323,7 @@ void telemetryInit(uint8_t protocol) } #endif -#if defined(AFHDS3) && !defined(SIMU) +#if defined(AFHDS3) else if (protocol == PROTOCOL_TELEMETRY_AFHDS3) { telemetryPortInvertedInit(AFHDS3_BAUDRATE); telemetryPortSetDirectionInput(); diff --git a/radio/src/tests/switches.cpp b/radio/src/tests/switches.cpp index d2ecf9764..56be91390 100644 --- a/radio/src/tests/switches.cpp +++ b/radio/src/tests/switches.cpp @@ -106,7 +106,7 @@ TEST(evalLogicalSwitches, playFile) char filename[AUDIO_FILENAME_MAXLEN+1]; //#if defined(EEPROM) -#define MODELNAME "MODEL01" +#define MODELNAME TR_MODEL "01" /*#else #define MODELNAME "Model00" #endif*/ diff --git a/radio/src/trainer.cpp b/radio/src/trainer.cpp index 78b0ef60a..7f3da8324 100644 --- a/radio/src/trainer.cpp +++ b/radio/src/trainer.cpp @@ -26,8 +26,8 @@ uint8_t currentTrainerMode = 0xff; void checkTrainerSignalWarning() { - enum PpmInValidState_t { - PPM_IN_IS_NOT_USED=0, + enum { + PPM_IN_IS_NOT_USED = 0, PPM_IN_IS_VALID, PPM_IN_INVALID }; @@ -137,17 +137,20 @@ void checkTrainerSettings() #if defined(TRAINER_BATTERY_COMPARTMENT) case TRAINER_MODE_MASTER_BATTERY_COMPARTMENT: #if defined(AUX_SERIAL) - if (g_eeGeneral.auxSerialMode == UART_MODE_SBUS_TRAINER) + if (g_eeGeneral.auxSerialMode == UART_MODE_SBUS_TRAINER) { auxSerialSbusInit(); - else + break; + } #endif + #if defined(AUX2_SERIAL) - if (g_eeGeneral.aux2SerialMode == UART_MODE_SBUS_TRAINER) + if (g_eeGeneral.aux2SerialMode == UART_MODE_SBUS_TRAINER) { aux2SerialSbusInit(); - else + break; + } #endif - init_trainer_capture(); - break; + + // no break #endif case TRAINER_MODE_MASTER_TRAINER_JACK: diff --git a/radio/src/translations.cpp b/radio/src/translations.cpp index 6ad2651d1..12fa79bfd 100644 --- a/radio/src/translations.cpp +++ b/radio/src/translations.cpp @@ -136,6 +136,7 @@ const char STR_REFRESHRATE[] = TR_REFRESHRATE; const char STR_MS[] = TR_MS; const char STR_SWITCH[] = TR_SWITCH; const char STR_TRIMS[] = TR_TRIMS; +const char STR_MIRROR[] = TR_MIRROR; const char STR_FADEIN[] = TR_FADEIN; const char STR_FADEOUT[] = TR_FADEOUT; const char STR_DEFAULT[] = TR_DEFAULT; @@ -190,6 +191,8 @@ const char STR_MINUTEBEEP[] = TR_MINUTEBEEP; const char STR_BEEPCOUNTDOWN[] = TR_BEEPCOUNTDOWN; const char STR_PERSISTENT[] = TR_PERSISTENT; const char STR_BACKLIGHT_LABEL[] = TR_BACKLIGHT_LABEL; +const char STR_GHOST_MENU_LABEL[] = TR_GHOST_MENU_LABEL; +const char STR_BLDELAY[] = TR_BLDELAY; const char STR_RXCHANNELORD[] = TR_RXCHANNELORD; const char STR_STICKS[] = TR_STICKS; const char STR_POTS[] = TR_POTS; @@ -377,6 +380,7 @@ const char STR_SPECTRUM_ANALYSER_EXT[] = TR_SPECTRUM_ANALYSER_EXT; const char STR_SPECTRUM_ANALYSER_INT[] = TR_SPECTRUM_ANALYSER_INT; const char STR_WAITING_FOR_RX[] = TR_WAITING_FOR_RX; const char STR_WAITING_FOR_TX[] = TR_WAITING_FOR_TX; +const char STR_WAITING_FOR_MODULE[] = TR_WAITING_FOR_MODULE; const char STR_WARN_5VOLTS[] = TR_WARN_5VOLTS; const char STR_CAT_NOT_EMPTY[] = TR_CAT_NOT_EMPTY; const char STR_WARNING[] = TR_WARNING; @@ -456,6 +460,7 @@ const char STR_FLASH_INTERNAL_MODULE[] = TR_FLASH_INTERNAL_MODULE; const char STR_FLASH_INTERNAL_MULTI[] = TR_FLASH_INTERNAL_MULTI; const char STR_FLASH_EXTERNAL_MODULE[] = TR_FLASH_EXTERNAL_MODULE; const char STR_FLASH_EXTERNAL_MULTI[] = TR_FLASH_EXTERNAL_MULTI; +const char STR_FLASH_EXTERNAL_ELRS[] = TR_FLASH_EXTERNAL_ELRS; const char STR_FIRMWARE_UPDATE_ERROR[] = TR_FIRMWARE_UPDATE_ERROR; const char STR_FIRMWARE_UPDATE_SUCCESS[] = TR_FIRMWARE_UPDATE_SUCCESS; const char STR_WRITING[] = TR_WRITING; @@ -673,7 +678,6 @@ const char STR_MAX[] = TR_MAX; const char STR_INVERTED[] = TR_INVERTED; const char STR_CURVE_PRESET[] = TR_CURVE_PRESET; const char STR_PRESET[] = TR_PRESET; -const char STR_MIRROR[] = TR_MIRROR; const char STR_CLEAR[] = TR_CLEAR; const char STR_RESET[] = TR_RESET; const char STR_COUNT[] = TR_COUNT; diff --git a/radio/src/translations.h b/radio/src/translations.h index ed68c407b..6a801634b 100644 --- a/radio/src/translations.h +++ b/radio/src/translations.h @@ -233,6 +233,7 @@ extern const char STR_REFRESHRATE[]; extern const char STR_MS[]; extern const char STR_SWITCH[]; extern const char STR_TRIMS[]; +extern const char STR_MIRROR[]; extern const char STR_FADEIN[]; extern const char STR_FADEOUT[]; extern const char STR_DEFAULT[]; @@ -307,6 +308,8 @@ extern const char STR_MINUTEBEEP[]; extern const char STR_BEEPCOUNTDOWN[]; extern const char STR_PERSISTENT[]; extern const char STR_BACKLIGHT_LABEL[]; +extern const char STR_GHOST_MENU_LABEL[]; +extern const char STR_BLDELAY[]; #if defined(PWM_BACKLIGHT) || defined(COLORLCD) extern const char STR_BLONBRIGHTNESS[]; @@ -563,6 +566,7 @@ extern const char STR_SPECTRUM_ANALYSER_EXT[]; extern const char STR_SPECTRUM_ANALYSER_INT[]; extern const char STR_WAITING_FOR_RX[]; extern const char STR_WAITING_FOR_TX[]; +extern const char STR_WAITING_FOR_MODULE[]; extern const char STR_WARN_5VOLTS[]; extern const char STR_BACKUP_MODEL[]; @@ -693,6 +697,7 @@ extern const char STR_FLASH_INTERNAL_MODULE[]; extern const char STR_FLASH_INTERNAL_MULTI[]; extern const char STR_FLASH_EXTERNAL_MODULE[]; extern const char STR_FLASH_EXTERNAL_MULTI[]; +extern const char STR_FLASH_EXTERNAL_ELRS[]; extern const char STR_FIRMWARE_UPDATE_ERROR[]; extern const char STR_FIRMWARE_UPDATE_SUCCESS[]; extern const char STR_WRITING[]; @@ -981,7 +986,6 @@ extern const char STR_MAX[]; extern const char STR_INVERTED[]; extern const char STR_CURVE_PRESET[]; extern const char STR_PRESET[]; -extern const char STR_MIRROR[]; extern const char STR_CLEAR[]; extern const char STR_RESET[]; extern const char STR_COUNT[]; diff --git a/radio/src/translations/cz.h.txt b/radio/src/translations/cz.h.txt index 17bd6e9fd..d4a0a8012 100644 --- a/radio/src/translations/cz.h.txt +++ b/radio/src/translations/cz.h.txt @@ -538,8 +538,10 @@ #define TR_BEEPCOUNTDOWN INDENT"Odpočet" #define TR_PERSISTENT INDENT"Trvalé" #define TR_BACKLIGHT_LABEL "Podsvětlení" -#define TR_BLONBRIGHTNESS TR3("Jas Zap.", "Jas Zap.", "Jas zapnutého LCD") -#define TR_BLOFFBRIGHTNESS TR3("Jas Vyp.", "Jas Vyp.", "Jas vypnutého LCD") +#define TR_GHOST_MENU_LABEL "GHOST MENU" +#define TR_BLDELAY INDENT"Zhasnout po" +#define TR_BLONBRIGHTNESS TR3(INDENT"Jas Zap.", INDENT"Jas Zap.", INDENT"Jas zapnutého LCD") +#define TR_BLOFFBRIGHTNESS TR3(INDENT"Jas Vyp.", INDENT"Jas Vyp.", INDENT"Jas vypnutého LCD") #define TR_KEYS_BACKLIGHT "Keys backlight" #define TR_BLCOLOR "Barva" #define TR_SPLASHSCREEN TR("úvodní logo", "Zobrazit úvodní logo") @@ -727,6 +729,7 @@ #define TR_NO_SDCARD "Není SD karta" #define TR_WAITING_FOR_RX "Čekám na RX..." #define TR_WAITING_FOR_TX "Čekám na TX..." +#define TR_WAITING_FOR_MODULE TR("Waiting module", "Waiting for module...") #define TR_NO_TOOLS TR("Nejsou k dispozici", "Žádné nástroje k dispozici") #define TR_NORMAL "Normální" #define TR_NOT_INVERTED "Neinvert" @@ -869,6 +872,7 @@ #define TR_FLASH_INTERNAL_MULTI TR("Flash Int. Multi", "Flash Internal Multi") #define TR_FLASH_EXTERNAL_MODULE TR("Flash ext. modulu", "Flash externího zařízení") #define TR_FLASH_EXTERNAL_MULTI TR("Flash Ext. Multi", "Flash External Multi") +#define TR_FLASH_EXTERNAL_ELRS TR("Flash Ext. ELRS", "Flash External ELRS") #define TR_FIRMWARE_UPDATE_ERROR TR("Chyba zápisu FW", "Chyba zápisu firmware") #define TR_FIRMWARE_UPDATE_SUCCESS "Úspěšný zápis FW" #define TR_WRITING "Zapisuji.." diff --git a/radio/src/translations/de.h.txt b/radio/src/translations/de.h.txt index bee7b9942..6dac4c4ef 100644 --- a/radio/src/translations/de.h.txt +++ b/radio/src/translations/de.h.txt @@ -544,8 +544,10 @@ #define TR_BEEPCOUNTDOWN INDENT "Countdown" #define TR_PERSISTENT TR(INDENT "Permanent", INDENT "Permanent") #define TR_BACKLIGHT_LABEL "LCD-Beleuchtung" -#define TR_BLONBRIGHTNESS "An-Helligkeit" -#define TR_BLOFFBRIGHTNESS "Aus-Helligkeit" +#define TR_GHOST_MENU_LABEL "GHOST MENU" +#define TR_BLDELAY INDENT "Dauer" +#define TR_BLONBRIGHTNESS INDENT "An-Helligkeit" +#define TR_BLOFFBRIGHTNESS INDENT "Aus-Helligkeit" #define TR_KEYS_BACKLIGHT "Keys backlight" #define TR_BLCOLOR "Farbe" #define TR_SPLASHSCREEN TR("Startbild Ein", "Startbild Anzeigedauer") @@ -734,6 +736,7 @@ #define TR_NO_SDCARD "Keine SD-Karte" #define TR_WAITING_FOR_RX "Waiting for RX..." #define TR_WAITING_FOR_TX "Waiting for TX..." +#define TR_WAITING_FOR_MODULE TR("Waiting module", "Waiting for module...") #define TR_NO_TOOLS "No tools available" #define TR_NORMAL "Normal" #define TR_NOT_INVERTED "Not inv" @@ -876,6 +879,7 @@ #define TR_FLASH_INTERNAL_MULTI TR("Flash Int. Multi", "Flash int. Multimodul") #define TR_FLASH_EXTERNAL_MODULE TR("Flash ext. mod","Flash ext. Modul") #define TR_FLASH_EXTERNAL_MULTI TR("Flash Ext. Multi", "Flash ext. Multimodul") +#define TR_FLASH_EXTERNAL_ELRS TR("Flash Ext. ELRS", "Flash External ELRS") #define TR_FIRMWARE_UPDATE_ERROR TR("FW update Error","Firmware Updatefehler") #define TR_FIRMWARE_UPDATE_SUCCESS TR3("Flash successful","Flash successful","Update erfolgreich") #define TR_WRITING "Schreibe..." diff --git a/radio/src/translations/en.h.txt b/radio/src/translations/en.h.txt index 6b2cd2a48..ffc803f9f 100644 --- a/radio/src/translations/en.h.txt +++ b/radio/src/translations/en.h.txt @@ -542,8 +542,10 @@ #define TR_BEEPCOUNTDOWN INDENT "Countdown" #define TR_PERSISTENT TR(INDENT "Persist.", INDENT "Persistent") #define TR_BACKLIGHT_LABEL "Backlight" -#define TR_BLONBRIGHTNESS "ON brightness" -#define TR_BLOFFBRIGHTNESS "OFF brightness" +#define TR_GHOST_MENU_LABEL "GHOST MENU" +#define TR_BLDELAY INDENT "Duration" +#define TR_BLONBRIGHTNESS INDENT "ON brightness" +#define TR_BLOFFBRIGHTNESS INDENT "OFF brightness" #define TR_KEYS_BACKLIGHT "Keys backlight" #define TR_BLCOLOR "Color" #define TR_SPLASHSCREEN "Splash screen" @@ -737,6 +739,7 @@ #define TR_NO_SDCARD "No SD card" #define TR_WAITING_FOR_RX "Waiting for RX..." #define TR_WAITING_FOR_TX "Waiting for TX..." +#define TR_WAITING_FOR_MODULE TR("Waiting module", "Waiting for module...") #define TR_NO_TOOLS "No tools available" #define TR_NORMAL "Normal" #define TR_NOT_INVERTED "Not inv" @@ -879,6 +882,7 @@ #define TR_FLASH_INTERNAL_MULTI TR("Flash Int. Multi", "Flash Internal Multi") #define TR_FLASH_EXTERNAL_MODULE TR("Flash ext. module", "Flash external module") #define TR_FLASH_EXTERNAL_MULTI TR("Flash Ext. Multi", "Flash External Multi") +#define TR_FLASH_EXTERNAL_ELRS TR("Flash Ext. ELRS", "Flash External ELRS") #define TR_FIRMWARE_UPDATE_ERROR TR("FW update error", "Firmware update error") #define TR_FIRMWARE_UPDATE_SUCCESS "Flash successful" #define TR_WRITING "Writing..." @@ -1157,6 +1161,14 @@ #define TR_ABOUT_HARDWARE_1 "JumperRC" #define TR_ABOUT_HARDWARE_2 TR("Hardware design/producer", "Hardware designer/producer") #define TR_ABOUT_HARDWARE_3 "Firmware contributor" +#elif defined(MANUFACTURER_RADIOMASTER) + #define TR_ABOUT_HARDWARE_1 "Radiomaster" + #define TR_ABOUT_HARDWARE_2 TR("Hardware design/producer", "Hardware designer/producer") + #define TR_ABOUT_HARDWARE_3 "Firmware contributor" +#elif defined(MANUFACTURER_JUMPER) + #define TR_ABOUT_HARDWARE_1 "JumperRC" + #define TR_ABOUT_HARDWARE_2 TR("Hardware design/producer", "Hardware designer/producer") + #define TR_ABOUT_HARDWARE_3 "Firmware contributor" #else #define TR_ABOUT_HARDWARE_1 "Brent Nelson" #define TR_ABOUT_HARDWARE_2 "Sky9x designer/producer" diff --git a/radio/src/translations/es.h.txt b/radio/src/translations/es.h.txt index f1280f553..cd9c65107 100644 --- a/radio/src/translations/es.h.txt +++ b/radio/src/translations/es.h.txt @@ -452,10 +452,10 @@ #define TR_OUTPUT_TYPE INDENT "Output" #endif #define TR_PROTO TR(INDENT"Proto",INDENT"Protocolo") -#define TR_PPMFRAME "Trama PPM" +#define TR_PPMFRAME INDENT "Trama PPM" #define TR_REFRESHRATE TR(INDENT "Refresco", INDENT "Velocidad refresco") #define STR_WARN_BATTVOLTAGE TR(INDENT "Salida es VBAT: ", INDENT "Aviso: señal salida es VBAT: ") -#define TR_WARN_5VOLTS "Warning: output level is 5 volts" +#define TR_WARN_5VOLTS "Aviso: nivel de salida 5 voltios" #define TR_MS "ms" #define TR_FREQUENCY INDENT "Frequencia" #define TR_SWITCH TR("Interr.", "Interruptor") @@ -541,6 +541,7 @@ #define TR_BEEPCOUNTDOWN TR(INDENT"Cta. atrás", INDENT"Cuenta atrás") #define TR_PERSISTENT TR(INDENT"Persisten.", INDENT"Persistente") #define TR_BACKLIGHT_LABEL "Luz fondo" +#define TR_GHOST_MENU_LABEL "GHOST MENU" #define TR_BLDELAY INDENT"Duración" #define TR_BLONBRIGHTNESS INDENT"MAS brillo" #define TR_BLOFFBRIGHTNESS INDENT"MENOS brillo" @@ -735,6 +736,7 @@ #define TR_NO_SDCARD "No SDCARD" #define TR_WAITING_FOR_RX "Esperando a RX..." #define TR_WAITING_FOR_TX "Esperando a TX..." +#define TR_WAITING_FOR_MODULE TR("Waiting module", "Waiting for module...") #define TR_NO_TOOLS "No hay utils" #define TR_NORMAL "Normal" #define TR_NOT_INVERTED "No inv" @@ -877,6 +879,7 @@ #define TR_FLASH_INTERNAL_MULTI TR("Flash Multi int", "Flash Multi interno") #define TR_FLASH_EXTERNAL_MODULE TR("Flash módulo ext", "Flash módulo externo") #define TR_FLASH_EXTERNAL_MULTI TR("Flash Multi ext", "Flash Multi externo") +#define TR_FLASH_EXTERNAL_ELRS TR("Flash Ext. ELRS", "Flash External ELRS") #define TR_FIRMWARE_UPDATE_ERROR TR("Error act FW", "Error actualiz. firmware") #define TR_FIRMWARE_UPDATE_SUCCESS "Flash ok" #define TR_WRITING "Escribiendo..." @@ -962,8 +965,8 @@ #define TR_DEBUG "Debug" #define TR_KEYS_BTN BUTTON(TR("SW","Switches")) #define TR_ANALOGS_BTN BUTTON(TR("Analog","Analogs")) -#define TR_TOUCH_NOTFOUND "Touch hardware not found" -#define TR_TOUCH_EXIT "Touch screen to exit" +#define TR_TOUCH_NOTFOUND "Hardware táctil no encontrado" +#define TR_TOUCH_EXIT "Tocar pantalla para salir" #define TR_CALIBRATION "Calibración" #define TR_SET "[Ajuste]" #define TR_TRAINER "Entrenador" @@ -981,8 +984,8 @@ #define TR_UNIT "Unidad" #define TR_TELEMETRY_NEWSENSOR INDENT "Añadir sensor..." #define TR_CHANNELRANGE INDENT "Canales" -#define TR_AFHDS3_RX_FREQ TR("RX freq.", "RX frequency") -#define TR_AFHDS3_ONE_TO_ONE_TELEMETRY TR("Unicast/Tel.", "Unicast/Telemetry") +#define TR_AFHDS3_RX_FREQ TR("RX freq.", "RX frequencia") +#define TR_AFHDS3_ONE_TO_ONE_TELEMETRY TR("Unicast/Tel.", "Unicast/Telemetría") #define TR_AFHDS3_ONE_TO_MANY "Multicast" #define TR_AFHDS3_ACTUAL_POWER TR("Act. pow", "Actual power") #define TR_AFHDS3_POWER_SOURCE TR("Power src.", "Power source") @@ -1047,7 +1050,7 @@ #define LEN_SPORT_UPDATE_POWER_MODES "\004" #define TR_SPORT_UPDATE_POWER_MODES "AUTO""ON\0 " #define TR_NO_TELEMETRY_SCREENS TR("No hay pant. telemetría", "No hay pantallas de telemetría") -#define TR_TOUCH_PANEL "Touch panel:" +#define TR_TOUCH_PANEL "Pantalla táctil:" // Horus and Taranis column headers #define TR_PHASES_HEADERS_NAME "Nombre" @@ -1233,9 +1236,9 @@ #define TR_ADD_MAIN_VIEW "Añadir vista pral." #define TR_BACKGROUND_COLOR "Color de fondo" #define TR_MAIN_COLOR "Color principal" -#define TR_BAR2_COLOR "Secondary bar color" -#define TR_BAR1_COLOR "Main bar color" -#define TR_TEXT_COLOR "Text color" +#define TR_BAR2_COLOR "Color barra secundaria" +#define TR_BAR1_COLOR "Color barra principal" +#define TR_TEXT_COLOR "Color texto" #define TR_TEXT_VIEWER "Visor de texto" #define TR_MENU_INPUTS "\314Entradas" diff --git a/radio/src/translations/fi.h.txt b/radio/src/translations/fi.h.txt index 9e4bf8201..ef22212f6 100644 --- a/radio/src/translations/fi.h.txt +++ b/radio/src/translations/fi.h.txt @@ -555,8 +555,10 @@ #define TR_BEEPCOUNTDOWN INDENT"Countdown" #define TR_PERSISTENT TR(INDENT"Persist.", INDENT"Persistent") #define TR_BACKLIGHT_LABEL "Backlight" -#define TR_BLONBRIGHTNESS "ON Brightness" -#define TR_BLOFFBRIGHTNESS "OFF Brightness" +#define TR_GHOST_MENU_LABEL "GHOST MENU" +#define TR_BLDELAY INDENT"Duration" +#define TR_BLONBRIGHTNESS INDENT"ON Brightness" +#define TR_BLOFFBRIGHTNESS INDENT"OFF Brightness" #define TR_KEYS_BACKLIGHT "Keys backlight" #define TR_BLCOLOR "Color" #define TR_SPLASHSCREEN "Splash screen" @@ -749,6 +751,7 @@ #define TR_NO_SDCARD "No SDCARD" #define TR_WAITING_FOR_RX "Waiting for RX..." #define TR_WAITING_FOR_TX "Waiting for TX..." +#define TR_WAITING_FOR_MODULE TR("Waiting module", "Waiting for module...") #define TR_NO_TOOLS "No tools available" #define TR_NORMAL "Normal" #define TR_NOT_INVERTED "Not inv" @@ -891,6 +894,7 @@ #define TR_FLASH_INTERNAL_MULTI TR("Flash Int. Multi", "Flash Internal Multi") #define TR_FLASH_EXTERNAL_MODULE "Flash external module" #define TR_FLASH_EXTERNAL_MULTI TR("Flash Ext. Multi", "Flash External Multi") +#define TR_FLASH_EXTERNAL_ELRS TR("Flash Ext. ELRS", "Flash External ELRS") #define TR_FIRMWARE_UPDATE_ERROR TR("FW update Error","Firmware update error") #define TR_FIRMWARE_UPDATE_SUCCESS "Flash successful" #define TR_WRITING "Writing..." diff --git a/radio/src/translations/fr.h.txt b/radio/src/translations/fr.h.txt index 57461e3a7..96da546bb 100644 --- a/radio/src/translations/fr.h.txt +++ b/radio/src/translations/fr.h.txt @@ -562,8 +562,10 @@ #define TR_BEEPCOUNTDOWN TR(INDENT "Bip fin", INDENT "Compte à rebours") #define TR_PERSISTENT TR(INDENT "Persist.", INDENT "Persistant") #define TR_BACKLIGHT_LABEL "Rétroéclairage" -#define TR_BLONBRIGHTNESS "Luminosité ON" -#define TR_BLOFFBRIGHTNESS "Luminosité OFF" +#define TR_GHOST_MENU_LABEL "GHOST MENU" +#define TR_BLDELAY INDENT "Durée" +#define TR_BLONBRIGHTNESS INDENT "Luminosité ON" +#define TR_BLOFFBRIGHTNESS INDENT "Luminosité OFF" #define TR_KEYS_BACKLIGHT "Keys backlight" #define TR_BLCOLOR "Couleur" #define TR_SPLASHSCREEN "Logo d'accueil" @@ -754,6 +756,7 @@ #define TR_NO_SDCARD "Carte SD indisponible" #define TR_WAITING_FOR_RX "Attente du RX..." #define TR_WAITING_FOR_TX "Attente du TX..." +#define TR_WAITING_FOR_MODULE TR("Waiting module", "Waiting for module...") #define TR_NO_TOOLS "Pas d'outils dispo" #define TR_NORMAL "Normal" #define TR_NOT_INVERTED "Non inv" @@ -895,6 +898,7 @@ #define TR_FLASH_INTERNAL_MULTI TR("Flash Int. Multi", "Flash Internal Multi") #define TR_FLASH_EXTERNAL_MODULE TR("Flasher module ext.", "Flasher module externe") #define TR_FLASH_EXTERNAL_MULTI TR("Flash Ext. Multi", "Flash External Multi") +#define TR_FLASH_EXTERNAL_ELRS TR("Flash Ext. ELRS", "Flash External ELRS") #define TR_FIRMWARE_UPDATE_ERROR TR("Erreur màj FW","Erreur de mise à jour") #define TR_FIRMWARE_UPDATE_SUCCESS "Flash ok" #define TR_WRITING "Ecriture..." @@ -1182,6 +1186,14 @@ #define TR_ABOUT_HARDWARE_1 "JumperRC" #define TR_ABOUT_HARDWARE_2 "Développeur/fabricant" #define TR_ABOUT_HARDWARE_3 "du matériel" +#elif defined(MANUFACTURER_RADIOMASTER) + #define TR_ABOUT_HARDWARE_1 "Radiomaster" + #define TR_ABOUT_HARDWARE_2 "Développeur/fabricant" + #define TR_ABOUT_HARDWARE_3 "du matériel" +#elif defined(MANUFACTURER_JUMPER) + #define TR_ABOUT_HARDWARE_1 "JumperRC" + #define TR_ABOUT_HARDWARE_2 "Développeur/fabricant" + #define TR_ABOUT_HARDWARE_3 "du matériel" #else #define TR_ABOUT_HARDWARE_1 "Brent Nelson" #define TR_ABOUT_HARDWARE_2 "Développeur/fabricant" diff --git a/radio/src/translations/it.h.txt b/radio/src/translations/it.h.txt index 6857255a8..39e950b29 100644 --- a/radio/src/translations/it.h.txt +++ b/radio/src/translations/it.h.txt @@ -566,8 +566,10 @@ #define TR_BEEPCOUNTDOWN TR(INDENT "Conto rov", INDENT "Conto rovescia") #define TR_PERSISTENT TR(INDENT "Persist.", INDENT "Persistente") #define TR_BACKLIGHT_LABEL TR("Retroillu.", "Retroilluminazione") -#define TR_BLONBRIGHTNESS TR("Lumin. ON", "Luminosità ON") -#define TR_BLOFFBRIGHTNESS TR("Lumin. OFF", "Luminosità OFF") +#define TR_GHOST_MENU_LABEL "GHOST MENU" +#define TR_BLDELAY INDENT "Durata" +#define TR_BLONBRIGHTNESS TR(INDENT "Lumin. ON", INDENT "Luminosità ON") +#define TR_BLOFFBRIGHTNESS TR(INDENT "Lumin. OFF", INDENT "Luminosità OFF") #define TR_KEYS_BACKLIGHT "Keys backlight" #define TR_BLCOLOR "Colore" #define TR_SPLASHSCREEN TR("Sch. avvio", "Schermata d'avvio") @@ -756,6 +758,7 @@ #define TR_NO_SDCARD "No SDCard" #define TR_WAITING_FOR_RX "Attendo la RX..." #define TR_WAITING_FOR_TX "Attendo la TX..." +#define TR_WAITING_FOR_MODULE TR("Waiting module", "Waiting for module...") #define TR_NO_TOOLS "Tools non disp." #define TR_NORMAL "Normale" #define TR_NOT_INVERTED "No inv." @@ -894,6 +897,7 @@ #define TR_FLASH_BLUETOOTH_MODULE TR("Prog. mod. BT", INDENT "Prog. modulo Bluetooth") #define TR_FLASH_POWER_MANAGEMENT_UNIT TR("Prog. PMU", "Programma PMU") #define TR_CURRENT_VERSION TR("Vers. currente ", "Versione corrente: ") +#define TR_FLASH_EXTERNAL_ELRS TR("Flash Ext. ELRS", "Flash External ELRS") #define TR_FLASH_INTERNAL_MODULE TR("Prog. modulo int.", "Programma modulo interno") #define TR_FLASH_EXTERNAL_MODULE TR("Prog. modulo est.", "Programma modulo esterno") #define TR_FLASH_INTERNAL_MULTI TR("Prog. MULTI int.", "Programma MULTI interno") diff --git a/radio/src/translations/nl.h.txt b/radio/src/translations/nl.h.txt index 8c0893943..36e6afce6 100644 --- a/radio/src/translations/nl.h.txt +++ b/radio/src/translations/nl.h.txt @@ -543,8 +543,10 @@ #define TR_BEEPCOUNTDOWN INDENT "Countdown" #define TR_PERSISTENT TR(INDENT "Vasth.", INDENT "Vasthouden") #define TR_BACKLIGHT_LABEL "LCD-Verlichting" -#define TR_BLONBRIGHTNESS "Aan-Helderheid" -#define TR_BLOFFBRIGHTNESS "Uit-Helderheid" +#define TR_GHOST_MENU_LABEL "GHOST MENU" +#define TR_BLDELAY INDENT "Duur" +#define TR_BLONBRIGHTNESS INDENT "Aan-Helderheid" +#define TR_BLOFFBRIGHTNESS INDENT "Uit-Helderheid" #define TR_KEYS_BACKLIGHT "Keys backlight" #define TR_BLCOLOR "Kleur" #define TR_SPLASHSCREEN "Startscherm Aan" @@ -738,6 +740,7 @@ #define TR_NO_SDCARD "Geen SD-Kaart" #define TR_WAITING_FOR_RX "Waiting for RX..." #define TR_WAITING_FOR_TX "Waiting for TX..." +#define TR_WAITING_FOR_MODULE TR("Waiting module", "Waiting for module...") #define TR_NO_TOOLS "No tools available" #define TR_NORMAL "Normal" #define TR_NOT_INVERTED "Not inv" @@ -880,6 +883,7 @@ #define TR_FLASH_INTERNAL_MULTI TR("Flash Int. Multi", "Flash Internal Multi") #define TR_FLASH_EXTERNAL_MODULE "Flash external module" #define TR_FLASH_EXTERNAL_MULTI TR("Flash Ext. Multi", "Flash External Multi") +#define TR_FLASH_EXTERNAL_ELRS TR("Flash Ext. ELRS", "Flash External ELRS") #define TR_FIRMWARE_UPDATE_ERROR TR("FW update Error","Firmware update error") #define TR_FIRMWARE_UPDATE_SUCCESS "Flash successful" #define TR_WRITING "Schrijven..." diff --git a/radio/src/translations/pl.h.txt b/radio/src/translations/pl.h.txt index 04d38d010..dc47f8076 100644 --- a/radio/src/translations/pl.h.txt +++ b/radio/src/translations/pl.h.txt @@ -562,8 +562,10 @@ #define TR_BEEPCOUNTDOWN INDENT "Odliczanie" #define TR_PERSISTENT TR(INDENT "Dokł.", INDENT "Dokładny") #define TR_BACKLIGHT_LABEL "Podświetl" -#define TR_BLONBRIGHTNESS "Jasnośc wł." -#define TR_BLOFFBRIGHTNESS "Jasność wył." +#define TR_GHOST_MENU_LABEL "GHOST MENU" +#define TR_BLDELAY INDENT"Czas trwania" +#define TR_BLONBRIGHTNESS INDENT"Jasnośc wł." +#define TR_BLOFFBRIGHTNESS INDENT"Jasność wył." #define TR_KEYS_BACKLIGHT "Keys backlight" #define TR_BLCOLOR "Color" #define TR_SPLASHSCREEN "Logo ekranu" @@ -752,6 +754,7 @@ #define TR_NO_SDCARD "Brak karty SD" #define TR_WAITING_FOR_RX "Waiting for RX..." #define TR_WAITING_FOR_TX "Waiting for TX..." +#define TR_WAITING_FOR_MODULE TR("Waiting module", "Waiting for module...") #define TR_NO_TOOLS "No tools available" #define TR_NORMAL "Normal" #define TR_NOT_INVERTED "Not inv" @@ -894,6 +897,7 @@ #define TR_FLASH_INTERNAL_MULTI TR("Flash Int. Multi", "Flash Internal Multi") #define TR_FLASH_EXTERNAL_MODULE "Flash external module" #define TR_FLASH_EXTERNAL_MULTI TR("Flash Ext. Multi", "Flash External Multi") +#define TR_FLASH_EXTERNAL_ELRS TR("Flash Ext. ELRS", "Flash External ELRS") #define TR_FIRMWARE_UPDATE_ERROR TR("FW update Error","Firmware update error") #define TR_FIRMWARE_UPDATE_SUCCESS "Flash successful" #define TR_WRITING "Zapis... " @@ -1175,6 +1179,10 @@ #define TR_ABOUT_HARDWARE_2 "Proucent/projektant Hardware" #define TR_ABOUT_HARDWARE_3 "Współautor firmware" #else + #define TR_ABOUT_HARDWARE_1 "Brent Nelson" + #define TR_ABOUT_HARDWARE_2 "Sky9x designer/výrobce" + #define TR_ABOUT_HARDWARE_3 "" +#endif #define TR_ABOUT_PARENTS_1 "Projekty macierzyste" #define TR_ABOUT_PARENTS_2 TR("Ersky9x (Mike Blandford)", "Ersky9x (Mike Blandford)") diff --git a/radio/src/translations/pt.h.txt b/radio/src/translations/pt.h.txt index a8154ed8c..d23f7dc89 100644 --- a/radio/src/translations/pt.h.txt +++ b/radio/src/translations/pt.h.txt @@ -559,8 +559,10 @@ #define TR_BEEPCOUNTDOWN INDENT "Beep Regressivo" #define TR_PERSISTENT INDENT "Persist." #define TR_BACKLIGHT_LABEL "Backlight" -#define TR_BLONBRIGHTNESS "ON Brightness" -#define TR_BLOFFBRIGHTNESS "OFF Brightness" +#define TR_GHOST_MENU_LABEL "GHOST MENU" +#define TR_BLDELAY INDENT "Tempo Backlight" +#define TR_BLONBRIGHTNESS INDENT "ON Brightness" +#define TR_BLOFFBRIGHTNESS INDENT "OFF Brightness" #define TR_KEYS_BACKLIGHT "Keys backlight" #define TR_BLCOLOR "Color" #define TR_SPLASHSCREEN "Splash screen" @@ -753,6 +755,7 @@ #define TR_NO_SDCARD "Sem SDCARD" #define TR_WAITING_FOR_RX "Waiting for RX..." #define TR_WAITING_FOR_TX "Waiting for TX..." +#define TR_WAITING_FOR_MODULE TR("Waiting module", "Waiting for module...") #define TR_NO_TOOLS "No tools available" #define TR_NORMAL "Normal" #define TR_NOT_INVERTED "Not inv" @@ -895,6 +898,7 @@ #define TR_FLASH_INTERNAL_MULTI TR("Flash Int. Multi", "Flash Internal Multi") #define TR_FLASH_EXTERNAL_MODULE "Flash external module" #define TR_FLASH_EXTERNAL_MULTI TR("Flash Ext. Multi", "Flash External Multi") +#define TR_FLASH_EXTERNAL_ELRS TR("Flash Ext. ELRS", "Flash External ELRS") #define TR_FIRMWARE_UPDATE_ERROR TR("FW update Error","Firmware update error") #define TR_FIRMWARE_UPDATE_SUCCESS "Flash successful" #define TR_WRITING "Writing..." diff --git a/radio/src/translations/se.h.txt b/radio/src/translations/se.h.txt index fed86106d..573961173 100644 --- a/radio/src/translations/se.h.txt +++ b/radio/src/translations/se.h.txt @@ -564,8 +564,10 @@ #define TR_BEEPCOUNTDOWN INDENT "Nedräkning" #define TR_PERSISTENT TR("Jämt på ", INDENT"Alltid På") #define TR_BACKLIGHT_LABEL "Belysning" -#define TR_BLONBRIGHTNESS "På Ljusstyrka" -#define TR_BLOFFBRIGHTNESS "Av Ljusstyrka" +#define TR_GHOST_MENU_LABEL "GHOST MENU" +#define TR_BLDELAY INDENT "Av efter" +#define TR_BLONBRIGHTNESS INDENT "På Ljusstyrka" +#define TR_BLOFFBRIGHTNESS INDENT "Av Ljusstyrka" #define TR_KEYS_BACKLIGHT "Keys backlight" #define TR_SPLASHSCREEN "Startbild" #define TR_PWR_ON_DELAY "Pwr On delay" @@ -754,6 +756,7 @@ #define TR_NO_SDCARD "SDCARD saknas" #define TR_WAITING_FOR_RX "Waiting for RX..." #define TR_WAITING_FOR_TX "Waiting for TX..." +#define TR_WAITING_FOR_MODULE TR("Waiting module", "Waiting for module...") #define TR_NO_TOOLS "No tools available" #define TR_NORMAL "Normal" #define TR_NOT_INVERTED "Not inv" @@ -897,6 +900,7 @@ #define TR_FLASH_INTERNAL_MULTI TR("Flash Int. Multi", "Flash Internal Multi") #define TR_FLASH_EXTERNAL_MODULE "Flash external module" #define TR_FLASH_EXTERNAL_MULTI TR("Flash Ext. Multi", "Flash External Multi") +#define TR_FLASH_EXTERNAL_ELRS TR("Flash Ext. ELRS", "Flash External ELRS") #define TR_FIRMWARE_UPDATE_ERROR TR("FW update Error","Firmware update error") #define TR_FIRMWARE_UPDATE_SUCCESS "Flash successful" #define TR_WRITING "Skriver..." diff --git a/radio/src/translations/untranslated.h b/radio/src/translations/untranslated.h index 3f66d013b..328e33fe6 100644 --- a/radio/src/translations/untranslated.h +++ b/radio/src/translations/untranslated.h @@ -47,6 +47,9 @@ #elif defined(RADIO_TX12) #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0""\312SE\0""\312SF\0""\312SI\0""\312SJ\0" +#elif defined(RADIO_TX12) + #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0" + #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0""\312SE\0""\312SF\0""\312SI\0""\312SJ\0" #elif defined(PCBX7) #define TR_POTS_VSRCRAW STR_CHAR_POT"S1\0" STR_CHAR_POT"S2\0" #define TR_SW_VSRCRAW STR_CHAR_SWITCH"SA\0" STR_CHAR_SWITCH"SB\0" STR_CHAR_SWITCH"SC\0" STR_CHAR_SWITCH"SD\0" STR_CHAR_SWITCH"SF\0" STR_CHAR_SWITCH"SH\0" STR_CHAR_SWITCH"SI\0" STR_CHAR_SWITCH"SJ\0" @@ -139,7 +142,7 @@ #define TR_DSM_PROTOCOLS "LP45""DSM2""DSMX" #define LEN_MULTI_PROTOCOLS "\007" -#define TR_MULTI_PROTOCOLS "FlySky\0""Hubsan\0""FrSky\0 ""Hisky\0 ""V2x2\0 ""DSM\0 ""Devo\0 ""YD717\0 ""KN\0 ""SymaX\0 ""SLT\0 ""CX10\0 ""CG023\0 ""Bayang\0""ESky\0 ""MT99XX\0""MJXq\0 ""Shenqi\0""FY326\0 ""SFHSS\0 ""J6 Pro\0""FQ777\0 ""Assan\0 ""Hontai\0""OpenLrs""FlSky2A""Q2x2\0 ""Walkera""Q303\0 ""GW008\0 ""DM002\0 ""Cabell\0""Esky150""H8 3D\0 ""Corona\0""CFlie\0 ""Hitec\0 ""WFly\0 ""Bugs\0 ""BugMini""Traxxas""NCC1701""E01X\0 ""V911S\0 ""GD00X\0 ""V761\0 ""KF606\0 ""Redpine""Potensi""ZSX\0 ""FlyZone""Scanner""FrSkyRX""FS2A_RX""HoTT\0 ""FX816\0 ""BayanRX""Pelikan""Tiger\0 ""XK\0 ""XN297DU""FrSkyX2""FrSkyR9""Propel\0""FrSkyL\0""Skyarte""ESky-v2""DSM RX\0""JJRC345""Q90C\0 " +#define TR_MULTI_PROTOCOLS "FlySky\0""Hubsan\0""FrSky\0 ""Hisky\0 ""V2x2\0 ""DSM\0 ""Devo\0 ""YD717\0 ""KN\0 ""SymaX\0 ""SLT\0 ""CX10\0 ""CG023\0 ""Bayang\0""ESky\0 ""MT99XX\0""MJXq\0 ""Shenqi\0""FY326\0 ""Futaba\0""J6 Pro\0""FQ777\0 ""Assan\0 ""Hontai\0""OpenLrs""FlSky2A""Q2x2\0 ""Walkera""Q303\0 ""GW008\0 ""DM002\0 ""Cabell\0""Esky150""H8 3D\0 ""Corona\0""CFlie\0 ""Hitec\0 ""WFly\0 ""Bugs\0 ""BugMini""Traxxas""NCC1701""E01X\0 ""V911S\0 ""GD00X\0 ""V761\0 ""KF606\0 ""Redpine""Potensi""ZSX\0 ""Height\0""Scanner""FrSkyRX""FS2A_RX""HoTT\0 ""FX816\0 ""BayanRX""Pelikan""Tiger\0 ""XK\0 ""XN297DU""FrSkyX2""FrSkyR9""Propel\0""FrSkyL\0""Skyartc""ESky-v2""DSM RX\0""JJRC345""Q90C\0 ""Kyosho\0""RadLink""ExpLRS\0""Realacc""OMP\0 ""M-Link\0""Wfly 2\0""E016Hv2" #define LEN_MULTI_POWER "\005" #define TR_MULTI_POWER "10mW\0""25mW\0""50mW\0""100mW""200mW""300mW""500mW""1W\0 ""2W\0 " diff --git a/tools/commit-tests.sh b/tools/commit-tests.sh index b9a336b01..700f7ae07 100755 --- a/tools/commit-tests.sh +++ b/tools/commit-tests.sh @@ -88,7 +88,7 @@ fi if [[ " X9LITE ALL " =~ \ ${FLAVOR}\ ]] ; then # OpenTX on X9LITE rm -rf ./* || true - cmake "${COMMON_OPTIONS}" -DPCB=X9LITE -DHELI=YES -DGVARS=YES "${SRCDIR}" + cmake "${COMMON_OPTIONS}" -DPCB=X9LITE -DHELI=YES -DGVARS=YES -DTRANSLATIONS=CZ "${SRCDIR}" make -j"${CORES}" ${FIRMARE_TARGET} make -j"${CORES}" libsimulator make -j"${CORES}" tests-radio @@ -97,7 +97,7 @@ fi if [[ " X9LITES X9LITE ALL " =~ \ ${FLAVOR}\ ]] ; then # OpenTX on X9LITES rm -rf ./* || true - cmake "${COMMON_OPTIONS}" -DPCB=X9LITES -DHELI=YES -DGVARS=YES -DMULTIMODULE=NO "${SRCDIR}" + cmake "${COMMON_OPTIONS}" -DPCB=X9LITES -DHELI=YES -DGVARS=YES -DMULTIMODULE=NO -DTRANSLATIONS=DE "${SRCDIR}" make -j"${CORES}" ${FIRMARE_TARGET} make -j"${CORES}" libsimulator make -j"${CORES}" tests-radio @@ -115,7 +115,16 @@ fi if [[ " X7ACCESS X7 ALL " =~ \ ${FLAVOR}\ ]] ; then # OpenTX on X7 ACCESS rm -rf ./* - cmake "${COMMON_OPTIONS}" -DPCB=X7 -DPCBREV=ACCESS -DHELI=YES -DGVARS=YES "${SRCDIR}" + cmake "${COMMON_OPTIONS}" -DPCB=X7 -DPCBREV=ACCESS -DHELI=YES -DGVARS=YES -DTRANSLATIONS=ES "${SRCDIR}" + make -j"${CORES}" ${FIRMARE_TARGET} + make -j"${CORES}" libsimulator + make -j"${CORES}" tests-radio +fi + +if [[ " X7ACCESS X7 ALL " =~ \ ${FLAVOR}\ ]] ; then + # OpenTX on X7 ACCESS + rm -rf ./* + cmake "${COMMON_OPTIONS}" -DPCB=X7 -DPCBREV=ACCESS -DHELI=YES -DGVARS=YES -DTRANSLATIONS=FR "${SRCDIR}" make -j"${CORES}" ${FIRMARE_TARGET} make -j"${CORES}" libsimulator make -j"${CORES}" tests-radio @@ -124,7 +133,16 @@ fi if [[ " T12 X7 ALL " =~ \ ${FLAVOR}\ ]] ; then # OpenTX on T12 rm -rf ./* || true - cmake "${COMMON_OPTIONS}" -DPCB=X7 -DPCBREV=T12 -DHELI=YES -DGVARS=YES "${SRCDIR}" + cmake "${COMMON_OPTIONS}" -DPCB=X7 -DPCBREV=T12 -DHELI=YES -DGVARS=YES -DTRANSLATIONS=IT "${SRCDIR}" + make -j"${CORES}" ${FIRMARE_TARGET} + make -j"${CORES}" libsimulator + make -j"${CORES}" tests-radio +fi + +if [[ " TX12 X7 ALL " =~ \ ${FLAVOR}\ ]] ; then + # OpenTX on TX12 + rm -rf ./* + cmake "${COMMON_OPTIONS}" -DPCB=X7 -DPCBREV=TX12 -DHELI=YES -DGVARS=YES -DTRANSLATIONS=PT "${SRCDIR}" make -j"${CORES}" ${FIRMARE_TARGET} make -j"${CORES}" libsimulator make -j"${CORES}" tests-radio @@ -142,7 +160,7 @@ fi if [[ " XLITE ALL " =~ \ ${FLAVOR}\ ]] ; then # OpenTX on X-Lite rm -rf ./* || true - cmake "${COMMON_OPTIONS}" -DPCB=XLITE -DHELI=YES -DGVARS=YES "${SRCDIR}" + cmake "${COMMON_OPTIONS}" -DPCB=XLITE -DHELI=YES -DGVARS=YES -DTRANSLATIONS=SK "${SRCDIR}" make -j"${CORES}" ${FIRMARE_TARGET} make -j"${CORES}" libsimulator make -j"${CORES}" tests-radio @@ -151,7 +169,7 @@ fi if [[ " XLITES XLITE ALL " =~ \ ${FLAVOR}\ ]] ; then # OpenTX on X-Lites rm -rf ./* || true - cmake "${COMMON_OPTIONS}" -DPCB=XLITES -DHELI=YES -DGVARS=YES "${SRCDIR}" + cmake "${COMMON_OPTIONS}" -DPCB=XLITES -DHELI=YES -DGVARS=YES -DTRANSLATIONS=SE "${SRCDIR}" make -j"${CORES}" ${FIRMARE_TARGET} make -j"${CORES}" libsimulator make -j"${CORES}" tests-radio @@ -160,7 +178,7 @@ fi if [[ " X9D X9 ALL " =~ \ ${FLAVOR}\ ]] ; then # OpenTX on X9D rm -rf ./* || true - cmake "${COMMON_OPTIONS}" -DPCB=X9D -DHELI=YES -DLUA=YES -DGVARS=YES "${SRCDIR}" + cmake "${COMMON_OPTIONS}" -DPCB=X9D -DHELI=YES -DLUA=YES -DGVARS=YES -DTRANSLATIONS=PL "${SRCDIR}" make -j"${CORES}" ${FIRMARE_TARGET} make -j"${CORES}" libsimulator make -j"${CORES}" tests-radio @@ -169,7 +187,7 @@ fi if [[ " X9D+ X9 ALL " =~ \ ${FLAVOR}\ ]] ; then # OpenTX on X9D+ rm -rf ./* || true - cmake "${COMMON_OPTIONS}" -DPCB=X9D+ -DHELI=YES -DLUA=YES -DGVARS=YES "${SRCDIR}" + cmake "${COMMON_OPTIONS}" -DPCB=X9D+ -DHELI=YES -DLUA=YES -DGVARS=YES -DTRANSLATIONS=HU "${SRCDIR}" make -j"${CORES}" ${FIRMARE_TARGET} make -j"${CORES}" libsimulator make -j"${CORES}" tests-radio @@ -178,7 +196,7 @@ fi if [[ " X9D+2019 X9 ALL " =~ \ ${FLAVOR}\ ]] ; then # OpenTX on X9D+ 2019 rm -rf ./* || true - cmake "${COMMON_OPTIONS}" -DPCB=X9D+ -DPCBREV=2019 -DHELI=YES -DLUA=YES -DGVARS=YES "${SRCDIR}" + cmake "${COMMON_OPTIONS}" -DPCB=X9D+ -DPCBREV=2019 -DHELI=YES -DLUA=YES -DGVARS=YES -DTRANSLATIONS=NL "${SRCDIR}" make -j"${CORES}" ${FIRMARE_TARGET} make -j"${CORES}" libsimulator make -j"${CORES}" tests-radio