diff --git a/.travis.yml b/.travis.yml index 6ddb599b5..909cf534d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,6 +16,8 @@ addons: - libmpc3 - libfox-1.6-dev - libgtest-dev + - lib32stdc++6 + - libclang-common-6.0-dev - clang-6.0 - python3-pip diff --git a/CREDITS.txt b/CREDITS.txt index ffa4dca00..c3cc61a76 100644 --- a/CREDITS.txt +++ b/CREDITS.txt @@ -2146,3 +2146,42 @@ Philip Garcia Helder Simoes Thomas Blanchin Jean-Luc Mesnier +Michael Bajer +David Homewood +Marc Sanders +Буров Александр +Rudy T'Jolleyn +Jay Watkins +Blaz Vodopivec +David De Salvo +Willem Verschoren +Dennis Kathrens +Alan Aucote +Richard Jerome Danstrom +David Garcia-Mendia +Mark Jones +John Zseleczky +Xiao Sun +Glenn Harvey +Albrecht Friebel +Gunter Klemke +Travis McCarthy +Franz Zier +Ian Contessa +Sean Sadler +Richard F Janczak +Mateusz Dziadosz +Thomas Merchant +M L Perkins +Stefano Boggia +Новоселов Юрий +James Rhodes +Peter Gaskill +Jacques Temey +Anthony Challis +Gerard Falaise +George McGinnis +Antoine Soulie +Tjeerd Jager +Bertold Van den Bergh +Stefanie Zerbe diff --git a/companion/src/datamodels/compounditemmodels.cpp b/companion/src/datamodels/compounditemmodels.cpp index 039e90244..ab0ba83ba 100644 --- a/companion/src/datamodels/compounditemmodels.cpp +++ b/companion/src/datamodels/compounditemmodels.cpp @@ -46,6 +46,8 @@ QString AbstractItemModel::idToString(const int value) return "CustomFuncResetParam"; case IMID_TeleSource: return "TeleSource"; + case IMID_RssiSource: + return "RssiSource"; case IMID_CurveRefType: return "CurveRefType"; case IMID_CurveRefFunc: @@ -109,7 +111,6 @@ RawSourceItemModel::RawSourceItemModel(const GeneralSettings * const generalSett addItems(SOURCE_TYPE_LUA_OUTPUT, RawSource::ScriptsGroup, firmware->getCapability(LuaOutputsPerScript), i * 16); addItems(SOURCE_TYPE_VIRTUAL_INPUT, RawSource::InputsGroup, firmware->getCapability(VirtualInputs)); addItems(SOURCE_TYPE_STICK, RawSource::SourcesGroup, board->getCapability(Board::MaxAnalogs)); - addItems(SOURCE_TYPE_ROTARY_ENCODER, RawSource::SourcesGroup, firmware->getCapability(RotaryEncoders)); addItems(SOURCE_TYPE_TRIM, RawSource::TrimsGroup, board->getCapability(Board::NumTrims)); addItems(SOURCE_TYPE_MAX, RawSource::SourcesGroup, 1); addItems(SOURCE_TYPE_SWITCH, RawSource::SwitchesGroup, board->getCapability(Board::Switches)); @@ -170,7 +171,6 @@ RawSwitchItemModel::RawSwitchItemModel(const GeneralSettings * const generalSett addItems(SWITCH_TYPE_TELEMETRY, -1); addItems(SWITCH_TYPE_FLIGHT_MODE, -firmware->getCapability(FlightModes)); addItems(SWITCH_TYPE_VIRTUAL, -firmware->getCapability(LogicalSwitches)); - addItems(SWITCH_TYPE_ROTARY_ENCODER, -firmware->getCapability(RotaryEncoders)); addItems(SWITCH_TYPE_TRIM, -board->getCapability(Board::NumTrimSwitches)); addItems(SWITCH_TYPE_MULTIPOS_POT, -(board->getCapability(Board::MultiposPots) * board->getCapability(Board::MultiposPotsPositions))); addItems(SWITCH_TYPE_SWITCH, -board->getCapability(Board::SwitchPositions)); @@ -181,7 +181,6 @@ RawSwitchItemModel::RawSwitchItemModel(const GeneralSettings * const generalSett addItems(SWITCH_TYPE_SWITCH, board->getCapability(Board::SwitchPositions)); addItems(SWITCH_TYPE_MULTIPOS_POT, board->getCapability(Board::MultiposPots) * board->getCapability(Board::MultiposPotsPositions)); addItems(SWITCH_TYPE_TRIM, board->getCapability(Board::NumTrimSwitches)); - addItems(SWITCH_TYPE_ROTARY_ENCODER, firmware->getCapability(RotaryEncoders)); addItems(SWITCH_TYPE_VIRTUAL, firmware->getCapability(LogicalSwitches)); addItems(SWITCH_TYPE_FLIGHT_MODE, firmware->getCapability(FlightModes)); addItems(SWITCH_TYPE_TELEMETRY, 1); @@ -420,7 +419,7 @@ CustomFuncActionItemModel::CustomFuncActionItemModel(const GeneralSettings * con void CustomFuncActionItemModel::setDynamicItemData(QStandardItem * item, const int value) const { - item->setText(CustomFunctionData(AssignFunc(value)).funcToString(modelData)); + item->setText(CustomFunctionData::funcToString((AssignFunc)value, modelData)); item->setData(CustomFunctionData::isFuncAvailable(value), IMDR_Available); } @@ -447,7 +446,7 @@ CustomFuncResetParamItemModel::CustomFuncResetParamItemModel(const GeneralSettin setId(IMID_CustomFuncResetParam); setUpdateMask(IMUE_TeleSensors); - for (int i = 0; i < CustomFunctionData::resetParamCount(modelData); i++) { + for (int i = 0; i < CustomFunctionData::resetParamCount(); i++) { QStandardItem * modelItem = new QStandardItem(); modelItem->setData(i, IMDR_Id); setDynamicItemData(modelItem, i); @@ -457,10 +456,8 @@ CustomFuncResetParamItemModel::CustomFuncResetParamItemModel(const GeneralSettin void CustomFuncResetParamItemModel::setDynamicItemData(QStandardItem * item, const int value) const { - CustomFunctionData cfd = CustomFunctionData(AssignFunc::FuncReset); - cfd.param = value; - item->setText(cfd.paramToString(modelData)); - item->setData(CustomFunctionData::isResetParamAvailable(modelData, value), IMDR_Available); + item->setText(CustomFunctionData::resetToString(value, modelData)); + item->setData(CustomFunctionData::isResetParamAvailable(value, modelData), IMDR_Available); } void CustomFuncResetParamItemModel::update(const int event) @@ -488,7 +485,7 @@ TelemetrySourceItemModel::TelemetrySourceItemModel(const GeneralSettings * const if (!modelData) return; - setUpdateMask(IMUE_TeleSensors); + setUpdateMask(IMUE_TeleSensors | IMUE_Modules); const int count = firmware->getCapability(Sensors); for (int i = -count; i <= count; ++i) { @@ -519,6 +516,49 @@ void TelemetrySourceItemModel::update(const int event) } } +// +// RssiSourceItemModel +// + +RssiSourceItemModel::RssiSourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, + Firmware * firmware, const Boards * const board, const Board::Type boardType) : + AbstractDynamicItemModel(generalSettings, modelData, firmware, board, boardType) +{ + setId(IMID_RssiSource); + + if (!modelData) + return; + + setUpdateMask(IMUE_TeleSensors | IMUE_Modules); + + for (int i = 0; i <= firmware->getCapability(Sensors); ++i) { + QStandardItem * modelItem = new QStandardItem(); + modelItem->setData(i, IMDR_Id); + modelItem->setData(i < 0 ? IMDG_Negative : i > 0 ? IMDG_Positive : IMDG_None, IMDR_Flags); + setDynamicItemData(modelItem, i); + appendRow(modelItem); + } +} + +void RssiSourceItemModel::setDynamicItemData(QStandardItem * item, const int value) const +{ + item->setText(SensorData::rssiSensorToString(modelData, value)); + item->setData(SensorData::isRssiSensorAvailable(modelData, value), IMDR_Available); +} + +void RssiSourceItemModel::update(const int event) +{ + if (doUpdate(event)) { + emit aboutToBeUpdated(); + + for (int i = 0; i < rowCount(); ++i) { + setDynamicItemData(item(i), item(i)->data(IMDR_Id).toInt()); + } + + emit updateComplete(); + } +} + // // CurveRefTypeItemModel // @@ -624,6 +664,9 @@ void CompoundItemModelFactory::addItemModel(const int id) case AbstractItemModel::IMID_TeleSource: registerItemModel(new TelemetrySourceItemModel(generalSettings, modelData, firmware, board, boardType)); break; + case AbstractItemModel::IMID_RssiSource: + registerItemModel(new RssiSourceItemModel(generalSettings, modelData, firmware, board, boardType)); + break; case AbstractItemModel::IMID_CurveRefType: registerItemModel(new CurveRefTypeItemModel(generalSettings, modelData, firmware, board, boardType)); break; diff --git a/companion/src/datamodels/compounditemmodels.h b/companion/src/datamodels/compounditemmodels.h index de32fc902..7acfcbdc9 100644 --- a/companion/src/datamodels/compounditemmodels.h +++ b/companion/src/datamodels/compounditemmodels.h @@ -18,8 +18,7 @@ * GNU General Public License for more details. */ -#ifndef COMPOUNDITEMMODELS_H -#define COMPOUNDITEMMODELS_H +#pragma once #include "rawsource.h" #include "rawswitch.h" @@ -44,6 +43,7 @@ class AbstractItemModel: public QStandardItemModel IMID_CustomFuncAction, IMID_CustomFuncResetParam, IMID_TeleSource, + IMID_RssiSource, IMID_CurveRefType, IMID_CurveRefFunc, IMID_ReservedCount, @@ -78,8 +78,9 @@ class AbstractItemModel: public QStandardItemModel IMUE_Scripts = 1 << 7, IMUE_TeleSensors = 1 << 8, IMUE_Timers = 1 << 9, + IMUE_Modules = 1 << 10, IMUE_All = IMUE_SystemRefresh | IMUE_Channels | IMUE_Curves | IMUE_FlightModes | IMUE_GVars | IMUE_Inputs | - IMUE_LogicalSwitches | IMUE_Scripts | IMUE_TeleSensors | IMUE_Timers + IMUE_LogicalSwitches | IMUE_Scripts | IMUE_TeleSensors | IMUE_Timers | IMUE_Modules }; Q_ENUM(ItemModelUpdateEvent) @@ -305,6 +306,21 @@ class TelemetrySourceItemModel: public AbstractDynamicItemModel virtual void setDynamicItemData(QStandardItem * item, const int value) const; }; +class RssiSourceItemModel: public AbstractDynamicItemModel +{ + Q_OBJECT + public: + explicit RssiSourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, + Firmware * firmware, const Boards * const board, const Board::Type boardType); + virtual ~RssiSourceItemModel() {}; + + public slots: + virtual void update(const int event = IMUE_SystemRefresh) override; + + protected: + virtual void setDynamicItemData(QStandardItem * item, const int value) const; +}; + class CurveRefTypeItemModel : public AbstractStaticItemModel { Q_OBJECT @@ -361,5 +377,3 @@ class CompoundItemModelFactory private: void setSourceId(AbstractItemModel * itemModel); }; - -#endif // COMPOUNDITEMMODELS_H diff --git a/companion/src/firmwares/CMakeLists.txt b/companion/src/firmwares/CMakeLists.txt index bf05bc44d..3bc2ca275 100644 --- a/companion/src/firmwares/CMakeLists.txt +++ b/companion/src/firmwares/CMakeLists.txt @@ -2,16 +2,21 @@ set(firmwares_SRCS adjustmentreference.cpp boards.cpp + curvedata.cpp curvereference.cpp customfunctiondata.cpp eeprominterface.cpp generalsettings.cpp gvardata.cpp - io_data.cpp + input_data.cpp + flightmodedata.cpp + heli_data.cpp logicalswitchdata.cpp + mixdata.cpp modeldata.cpp moduledata.cpp multiprotocols.cpp + output_data.cpp radiodata.cpp radiodataconversionstate.cpp rawsource.cpp diff --git a/companion/src/firmwares/curvedata.cpp b/companion/src/firmwares/curvedata.cpp new file mode 100644 index 000000000..c32eac4cc --- /dev/null +++ b/companion/src/firmwares/curvedata.cpp @@ -0,0 +1,48 @@ +/* + * 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 "curvedata.h" +#include "radiodata.h" + +CurveData::CurveData() +{ + clear(); +} + +void CurveData::clear(int count) +{ + memset(reinterpret_cast(this), 0, sizeof(CurveData)); + this->count = count; +} + +bool CurveData::isEmpty() const +{ + for (int i = 0; i < count; i++) { + if (points[i].y != 0) { + return false; + } + } + return true; +} + +QString CurveData::nameToString(const int idx) const +{ + return RadioData::getElementName(tr("CV"), idx + 1, name); +} diff --git a/companion/src/firmwares/curvedata.h b/companion/src/firmwares/curvedata.h new file mode 100644 index 000000000..cb083375e --- /dev/null +++ b/companion/src/firmwares/curvedata.h @@ -0,0 +1,56 @@ +/* + * 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. + */ + +#pragma once + +#include "constants.h" + +#include + +class CurvePoint { + public: + int8_t x; + int8_t y; +}; + +#define CURVEDATA_NAME_LEN 6 + +class CurveData { + Q_DECLARE_TR_FUNCTIONS(CurveData) + + public: + enum CurveType { + CURVE_TYPE_STANDARD, + CURVE_TYPE_CUSTOM, + CURVE_TYPE_LAST = CURVE_TYPE_CUSTOM + }; + + CurveData(); + + CurveType type; + bool smooth; + int count; + CurvePoint points[CPN_MAX_POINTS]; + char name[CURVEDATA_NAME_LEN + 1]; + + void clear(int count = 5); + bool isEmpty() const; + QString nameToString(const int idx) const; +}; diff --git a/companion/src/firmwares/customfunctiondata.cpp b/companion/src/firmwares/customfunctiondata.cpp index d4942c60c..98157cae2 100644 --- a/companion/src/firmwares/customfunctiondata.cpp +++ b/companion/src/firmwares/customfunctiondata.cpp @@ -22,6 +22,17 @@ #include "eeprominterface.h" #include "radiodata.h" #include "radiodataconversionstate.h" +#include "compounditemmodels.h" + +void CustomFunctionData::convert(RadioDataConversionState & cstate) +{ + cstate.setComponent(tr("CFN"), 8); + cstate.setSubComp(nameToString(cstate.subCompIdx, (cstate.toModel() ? false : true))); + swtch.convert(cstate); + if (func == FuncVolume || func == FuncBacklight || func == FuncPlayValue || (func >= FuncAdjustGV1 && func <= FuncAdjustGVLast && adjustMode == 1)) { + param = RawSource(param).convert(cstate.withComponentField("PARAM")).toValue(); + } +} void CustomFunctionData::clear() { @@ -36,12 +47,19 @@ bool CustomFunctionData::isEmpty() const return (swtch.type == SWITCH_TYPE_NONE); } -QString CustomFunctionData::nameToString(int index, bool globalContext) const +// static +QString CustomFunctionData::nameToString(const int index, const bool globalContext) { return RadioData::getElementName((globalContext ? tr("GF") : tr("SF")), index + 1, 0, true); } QString CustomFunctionData::funcToString(const ModelData * model) const +{ + return funcToString(func, model); +} + +// static +QString CustomFunctionData::funcToString(const AssignFunc func, const ModelData * model) { if (func >= FuncOverrideCH1 && func <= FuncOverrideCHLast) return tr("Override %1").arg(RawSource(SOURCE_TYPE_CH, func).toString(model)); @@ -76,7 +94,7 @@ QString CustomFunctionData::funcToString(const ModelData * model) const else if (func == FuncPlayValue) return tr("Play Value"); else if (func == FuncPlayScript) - return tr("Play Script"); + return tr("Lua Script"); else if (func == FuncLogs) return tr("SD Logs"); else if (func == FuncVolume) @@ -94,9 +112,9 @@ QString CustomFunctionData::funcToString(const ModelData * model) const else if (func == FuncSetFailsafe) return tr("Set Failsafe"); else if (func == FuncRangeCheckInternalModule) - return tr("RangeCheck Int. Module"); + return tr("Range Check Int. Module"); else if (func == FuncRangeCheckExternalModule) - return tr("RangeCheck Ext. Module"); + return tr("Range Check Ext. Module"); else if (func == FuncBindInternalModule) return tr("Bind Int. Module"); else if (func == FuncBindExternalModule) @@ -106,53 +124,6 @@ QString CustomFunctionData::funcToString(const ModelData * model) const } } -void CustomFunctionData::populateResetParams(const ModelData * model, QComboBox * b, unsigned int value = 0) -{ - int val = 0; - Firmware * firmware = Firmware::getCurrentVariant(); - - for (int i = 0; i < CPN_MAX_TIMERS; i++, val++) { - if (i < firmware->getCapability(Timers)) { - RawSource item = RawSource(SOURCE_TYPE_SPECIAL, i + SOURCE_TYPE_SPECIAL_TIMER1_IDX); - b->addItem(item.toString(model), val); - } - } - - b->addItem(tr("Flight"), val++); - b->addItem(tr("Telemetry"), val++); - - int reCount = firmware->getCapability(RotaryEncoders); - if (reCount == 1) { - b->addItem(tr("Rotary Encoder"), val++); - } - else if (reCount == 2) { - b->addItem(tr("REa"), val++); - b->addItem(tr("REb"), val++); - } - - if (model) { - for (int i = 0; i < firmware->getCapability(Sensors); ++i) { - if (model->sensorData[i].isAvailable()) { - 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) -{ - qs <<"Beep 1" << "Beep 2" << "Beep 3" << "Warn1" << "Warn2" << "Cheep" << "Ratata" << "Tick" << "Siren" << "Ring" ; - qs << "SciFi" << "Robot" << "Chirp" << "Tada" << "Crickt" << "AlmClk" ; -} - -void CustomFunctionData::populateHapticParams(QStringList & qs) -{ - qs << "0" << "1" << "2" << "3"; -} - QString CustomFunctionData::paramToString(const ModelData * model) const { QStringList qs; @@ -163,31 +134,16 @@ QString CustomFunctionData::paramToString(const ModelData * model) const return QString("%1").arg(param / 10.0) + tr("s"); } else if (func == FuncPlaySound) { - CustomFunctionData::populatePlaySoundParams(qs); - if (param >= 0 && param < (int)qs.count()) - return qs.at(param); - else - return tr("Inconsistent parameter"); + return playSoundToString(param); } else if (func == FuncPlayHaptic) { - CustomFunctionData::populateHapticParams(qs); - if (param >= 0 && param < (int)qs.count()) - return qs.at(param); - else - return tr("Inconsistent parameter"); + return harpicToString(param); } else if (func == FuncReset) { - QComboBox cb; - CustomFunctionData::populateResetParams(model, &cb); - int pos = cb.findData(param); - if (pos >= 0) - return cb.itemText(pos); - else - return tr("Inconsistent parameter"); + return resetToString(param, model); } else if (func == FuncVolume || func == FuncPlayValue || func == FuncBacklight) { - RawSource item(param); - return item.toString(model); + return RawSource(param).toString(model); } else if (func == FuncPlayPrompt || func == FuncPlayBoth) { if ( getCurrentFirmware()->getCapability(VoicesAsNumbers)) { @@ -200,16 +156,14 @@ QString CustomFunctionData::paramToString(const ModelData * model) const else if (func >= FuncAdjustGV1 && func < FuncCount) { switch (adjustMode) { case FUNC_ADJUST_GVAR_CONSTANT: - return tr("Value ") + QString("%1").arg(param); + return gvarAdjustModeToString(adjustMode) + QString(" %1").arg(param); case FUNC_ADJUST_GVAR_SOURCE: case FUNC_ADJUST_GVAR_GVAR: return RawSource(param).toString(); case FUNC_ADJUST_GVAR_INCDEC: - float val; - QString unit; - val = param * model->gvarData[func - FuncAdjustGV1].multiplierGet(); - unit = model->gvarData[func - FuncAdjustGV1].unitToString(); - return QString("Increment: %1%2").arg(val).arg(unit); + const float val = param * model->gvarData[func - FuncAdjustGV1].multiplierGet(); + const QString unit = model->gvarData[func - FuncAdjustGV1].unitToString(); + return gvarAdjustModeToString(adjustMode) + QString(": %1%2").arg(val).arg(unit); } } return ""; @@ -217,15 +171,20 @@ QString CustomFunctionData::paramToString(const ModelData * model) const QString CustomFunctionData::repeatToString() const { - if (repeatParam == -1) { - return tr("played once, not during startup"); + return repeatToString(repeatParam); +} + +// static +QString CustomFunctionData::repeatToString(const int value) +{ + if (value == -1) { + return tr("Played once, not during startup"); } - else if (repeatParam == 0) { - return ""; + else if (value == 0) { + return tr("No repeat"); } else { - unsigned int step = 1; - return tr("repeat(%1s)").arg(step * repeatParam); + return tr("Repeat %1s").arg(value); } } @@ -246,7 +205,7 @@ QString CustomFunctionData::enabledToString() const } // static -bool CustomFunctionData::isFuncAvailable(int index) +bool CustomFunctionData::isFuncAvailable(const int index) { Firmware * fw = getCurrentFirmware(); @@ -265,7 +224,7 @@ bool CustomFunctionData::isFuncAvailable(int index) } // static -int CustomFunctionData::funcContext(int index) +int CustomFunctionData::funcContext(const int index) { int ret = AllFunctionContexts; @@ -276,16 +235,42 @@ int CustomFunctionData::funcContext(int index) return ret; } + // static -int CustomFunctionData::resetParamCount(const ModelData * model) +QString CustomFunctionData::resetToString(const int value, const ModelData * model) { - QComboBox cb; - CustomFunctionData::populateResetParams(model, &cb); - return cb.count(); + Firmware * firmware = getCurrentFirmware(); + int step = CPN_MAX_TIMERS; + + if (value < step) { + if (value < firmware->getCapability(Timers)) + return RawSource(SOURCE_TYPE_SPECIAL, value + SOURCE_TYPE_SPECIAL_TIMER1_IDX).toString(model); + else + return QString(CPN_STR_UNKNOWN_ITEM); + } + + if (value < ++step) + return tr("Flight"); + + if (value < ++step) + return tr("Telemetry"); + + if (value < step + firmware->getCapability(Sensors)) + return RawSource(SOURCE_TYPE_TELEMETRY, 3 * (value - step)).toString(model); + + return QString(CPN_STR_UNKNOWN_ITEM); } // static -bool CustomFunctionData::isResetParamAvailable(const ModelData * model, int index) +int CustomFunctionData::resetParamCount() +{ + Firmware * firmware = getCurrentFirmware(); + + return CPN_MAX_TIMERS + 2 + firmware->getCapability(Sensors); +} + +// static +bool CustomFunctionData::isResetParamAvailable(const int index, const ModelData * model) { Firmware * firmware = getCurrentFirmware(); @@ -295,20 +280,121 @@ bool CustomFunctionData::isResetParamAvailable(const ModelData * model, int inde else return false; } - else if (index < CPN_MAX_TIMERS + firmware->getCapability(RotaryEncoders)) + else if (index < CPN_MAX_TIMERS + 2) return true; - else if (model && index < CPN_MAX_TIMERS + firmware->getCapability(RotaryEncoders) + firmware->getCapability(Sensors)) - return model->sensorData[index - CPN_MAX_TIMERS - firmware->getCapability(RotaryEncoders)].isAvailable(); + else if (model && index < resetParamCount()) + return model->sensorData[index - (CPN_MAX_TIMERS + 2)].isAvailable(); return false; } -void CustomFunctionData::convert(RadioDataConversionState & cstate) +QString CustomFunctionData::harpicToString() const { - cstate.setComponent(tr("CFN"), 8); - cstate.setSubComp(nameToString(cstate.subCompIdx, (cstate.toModel() ? false : true))); - swtch.convert(cstate); - if (func == FuncVolume || func == FuncBacklight || func == FuncPlayValue || (func >= FuncAdjustGV1 && func <= FuncAdjustGVLast && adjustMode == 1)) { - param = RawSource(param).convert(cstate.withComponentField("PARAM")).toValue(); + return harpicToString(param); +} + +// static +QString CustomFunctionData::harpicToString(const int value) +{ + return QString("%1").arg(value); +} + +// static +QStringList CustomFunctionData::playSoundStringList() +{ + return QStringList({ tr("Beep 1"), tr("Beep 2"), tr("Beep 3"), tr("Warn 1"), tr("Warn 2"), tr("Cheep"), tr("Ratata"), tr("Tick"), + tr("Siren"), tr("Ring"), tr("Sci Fi"), tr("Robot"), tr("Chirp"), tr("Tada"), tr("Cricket"), tr("Alarm Clock") }); +} + +QString CustomFunctionData::playSoundToString() const +{ + return playSoundToString(param); +} + +// static +QString CustomFunctionData::playSoundToString(const int value) +{ + const QStringList strl = playSoundStringList(); + if (value < strl.count()) + return strl.at(value); + else + return QString(CPN_STR_UNKNOWN_ITEM); +} + +QString CustomFunctionData::gvarAdjustModeToString() const +{ + return gvarAdjustModeToString(adjustMode); +} + +// static +QString CustomFunctionData::gvarAdjustModeToString(const int value) +{ + switch (value) { + case FUNC_ADJUST_GVAR_CONSTANT: + return tr("Value"); + case FUNC_ADJUST_GVAR_SOURCE: + return tr("Source"); + case FUNC_ADJUST_GVAR_GVAR: + return tr("Global Variable"); + case FUNC_ADJUST_GVAR_INCDEC: + return tr("Inc/Decrement"); + default: + return QString(CPN_STR_UNKNOWN_ITEM); } } + +// static +AbstractStaticItemModel * CustomFunctionData::repeatItemModel() +{ + AbstractStaticItemModel * mdl = new AbstractStaticItemModel(); + mdl->setName("customfunctiondata.repeat"); + + for (int i = -1; i <= 60; i++) { + mdl->appendToItemList(repeatToString(i), i); + } + + mdl->loadItemList(); + return mdl; +} + +// static +AbstractStaticItemModel * CustomFunctionData::playSoundItemModel() +{ + AbstractStaticItemModel * mdl = new AbstractStaticItemModel(); + mdl->setName("customfunctiondata.playsound"); + + for (int i = 0; i < playSoundStringList().count(); i++) { + mdl->appendToItemList(playSoundToString(i), i); + } + + mdl->loadItemList(); + return mdl; +} + +// static +AbstractStaticItemModel * CustomFunctionData::harpicItemModel() +{ + AbstractStaticItemModel * mdl = new AbstractStaticItemModel(); + mdl->setName("customfunctiondata.harpic"); + + for (int i = 0; i <= 3; i++) { + mdl->appendToItemList(harpicToString(i), i); + } + + mdl->loadItemList(); + return mdl; +} + +// static +AbstractStaticItemModel * CustomFunctionData::gvarAdjustModeItemModel() +{ + AbstractStaticItemModel * mdl = new AbstractStaticItemModel(); + mdl->setName("customfunctiondata.gvaradjustmode"); + + for (int i = 0; i < FUNC_ADJUST_GVAR_COUNT; i++) { + mdl->appendToItemList(gvarAdjustModeToString(i), i); + } + + mdl->loadItemList(); + return mdl; +} diff --git a/companion/src/firmwares/customfunctiondata.h b/companion/src/firmwares/customfunctiondata.h index 9e597441f..d5a08a96f 100644 --- a/companion/src/firmwares/customfunctiondata.h +++ b/companion/src/firmwares/customfunctiondata.h @@ -18,8 +18,7 @@ * GNU General Public License for more details. */ -#ifndef CUSTOMFUNCTIONDATA_H -#define CUSTOMFUNCTIONDATA_H +#pragma once #include "boards.h" #include "constants.h" @@ -32,6 +31,7 @@ class Firmware; class ModelData; class GeneralSettings; class RadioDataConversionState; +class AbstractStaticItemModel; enum AssignFunc { FuncOverrideCH1 = 0, @@ -78,7 +78,8 @@ enum GVarAdjustModes FUNC_ADJUST_GVAR_CONSTANT, FUNC_ADJUST_GVAR_SOURCE, FUNC_ADJUST_GVAR_GVAR, - FUNC_ADJUST_GVAR_INCDEC + FUNC_ADJUST_GVAR_INCDEC, + FUNC_ADJUST_GVAR_COUNT }; class CustomFunctionData { @@ -102,25 +103,33 @@ class CustomFunctionData { unsigned int adjustMode; int repeatParam; - void clear(); - bool isEmpty() const; - QString nameToString(int index, bool globalContext = false) const; - QString funcToString(const ModelData * model = nullptr) const; - QString paramToString(const ModelData * model) const; - QString repeatToString() const; - QString enabledToString() const; - - static void populateResetParams(const ModelData * model, QComboBox * b, unsigned int value); - static void populatePlaySoundParams(QStringList & qs); - static void populateHapticParams(QStringList & qs); - static bool isFuncAvailable(int index); - static int funcContext(int index); - static int resetParamCount(const ModelData * model); - static bool isResetParamAvailable(const ModelData * model, int index); - void convert(RadioDataConversionState & cstate); + void clear(); + bool isEmpty() const; + QString funcToString(const ModelData * model = nullptr) const; + QString paramToString(const ModelData * model = nullptr) const; + QString repeatToString() const; + QString enabledToString() const; + QString playSoundToString() const; + QString harpicToString() const; + QString gvarAdjustModeToString() const; + + static QString nameToString(const int index, const bool globalContext = false); + static QString funcToString(const AssignFunc func, const ModelData * model = nullptr); + static bool isFuncAvailable(const int index); + static int funcContext(const int index); + static QString resetToString(const int value, const ModelData * model = nullptr); + static int resetParamCount(); + static bool isResetParamAvailable(const int index, const ModelData * model = nullptr); + static QString repeatToString(const int value); + static QStringList playSoundStringList(); + static QString playSoundToString(const int value); + static QString harpicToString(const int value); + static QStringList gvarAdjustModeStringList(); + static QString gvarAdjustModeToString(const int value); + static AbstractStaticItemModel * repeatItemModel(); + static AbstractStaticItemModel * playSoundItemModel(); + static AbstractStaticItemModel * harpicItemModel(); + static AbstractStaticItemModel * gvarAdjustModeItemModel(); }; - - -#endif // CUSTOMFUNCTIONDATA_H diff --git a/companion/src/firmwares/io_data.cpp b/companion/src/firmwares/flightmodedata.cpp similarity index 56% rename from companion/src/firmwares/io_data.cpp rename to companion/src/firmwares/flightmodedata.cpp index a958750d8..c0a268e96 100644 --- a/companion/src/firmwares/io_data.cpp +++ b/companion/src/firmwares/flightmodedata.cpp @@ -18,121 +18,17 @@ * GNU General Public License for more details. */ -#include "io_data.h" - -#include "radiodata.h" // for RadioData::getElementName +#include "flightmodedata.h" +#include "radiodata.h" #include "radiodataconversionstate.h" -/* - * ExpoData - */ - -void ExpoData::convert(RadioDataConversionState & cstate) +void FlightModeData::convert(RadioDataConversionState & cstate) { - cstate.setComponent(tr("INP"), 3); - cstate.setSubComp(RawSource(SOURCE_TYPE_VIRTUAL_INPUT, chn).toString(cstate.fromModel(), cstate.fromGS(), cstate.fromType) % tr(" (@%1)").arg(cstate.subCompIdx)); - srcRaw.convert(cstate); + cstate.setComponent("FMD", 2); + cstate.setSubComp(nameToString(cstate.subCompIdx)); swtch.convert(cstate); } -bool ExpoData::isEmpty() const -{ - return (chn == 0 && mode == INPUT_MODE_NONE); -} - -/* - * MixData - */ - -void MixData::convert(RadioDataConversionState & cstate) -{ - cstate.setComponent(tr("MIX"), 4); - cstate.setSubComp(RawSource(SOURCE_TYPE_CH, destCh-1).toString(cstate.fromModel(), cstate.fromGS(), cstate.fromType) % tr(" (@%1)").arg(cstate.subCompIdx)); - srcRaw.convert(cstate); - swtch.convert(cstate); -} - -bool MixData::isEmpty() const -{ - return (destCh == 0); -} - -/* - * LimitData - */ - -QString LimitData::minToString() const -{ - return QString::number((qreal)min/10); -} - -QString LimitData::maxToString() const -{ - return QString::number((qreal)max/10); -} - -QString LimitData::revertToString() const -{ - return revert ? tr("INV") : tr("NOR"); -} - -QString LimitData::nameToString(int index) const -{ - return RadioData::getElementName(tr("CH"), index + 1, name); -} - -QString LimitData::offsetToString() const -{ - return QString::number((qreal)offset/10, 'f', 1); -} - -void LimitData::clear() -{ - memset(reinterpret_cast(this), 0, sizeof(LimitData)); - min = -1000; - max = +1000; -} - -bool LimitData::isEmpty() const -{ - return (min == -1000 && max == 1000 && !revert && !offset && !ppmCenter && !symetrical && name[0] == '\0' && !curve.isSet()); -} - -/* - * CurveData - */ - -CurveData::CurveData() -{ - clear(); -} - -void CurveData::clear(int count) -{ - memset(this, 0, sizeof(CurveData)); - this->count = count; -} - -bool CurveData::isEmpty() const -{ - for (int i=0; i(this), 0, sizeof(FlightModeData)); @@ -149,13 +45,6 @@ QString FlightModeData::nameToString(int phaseIdx) const return RadioData::getElementName(tr("FM"), phaseIdx, name); // names are zero-based, FM0, FM1, etc } -void FlightModeData::convert(RadioDataConversionState & cstate) -{ - cstate.setComponent("FMD", 2); - cstate.setSubComp(nameToString(cstate.subCompIdx)); - swtch.convert(cstate); -} - bool FlightModeData::isEmpty(int phaseIdx) const { if (name[0] != '\0' || swtch.isSet() || fadeIn != 0 || fadeOut != 0) diff --git a/companion/src/firmwares/flightmodedata.h b/companion/src/firmwares/flightmodedata.h new file mode 100644 index 000000000..8578d04e5 --- /dev/null +++ b/companion/src/firmwares/flightmodedata.h @@ -0,0 +1,59 @@ +/* + * 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. + */ + +#pragma once + +#include "constants.h" +#include "rawswitch.h" + +#include + +class RadioDataConversionState; + +#define FLIGHTMODE_NAME_LEN 10 +#define RENC_MAX_VALUE 1024 +#define RENC_MIN_VALUE -RENC_MAX_VALUE + +class FlightModeData { + Q_DECLARE_TR_FUNCTIONS(FlightModeData) + + public: + FlightModeData() { clear(0); } + + int trimMode[CPN_MAX_TRIMS]; + int trimRef[CPN_MAX_TRIMS]; + int trim[CPN_MAX_TRIMS]; + RawSwitch swtch; + char name[FLIGHTMODE_NAME_LEN + 1]; + unsigned int fadeIn; + unsigned int fadeOut; + int rotaryEncoders[CPN_MAX_ENCODERS]; + int gvars[CPN_MAX_GVARS]; + + void convert(RadioDataConversionState & cstate); + void clear(const int phaseIdx); + bool isEmpty(int phaseIdx) const; + QString nameToString(int phaseIdx) const; + bool isGVarEmpty(int phaseIdx, int gvIdx) const; + bool isREncEmpty(int phaseIdx, int reIdx) const; + int linkedFlightModeZero(int phaseIdx, int maxOwnValue) const; + int linkedGVarFlightModeZero(int phaseIdx) const; + int linkedREncFlightModeZero(int phaseIdx) const; +}; diff --git a/companion/src/firmwares/heli_data.cpp b/companion/src/firmwares/heli_data.cpp new file mode 100644 index 000000000..b1fb7b36e --- /dev/null +++ b/companion/src/firmwares/heli_data.cpp @@ -0,0 +1,21 @@ +/* + * 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 "heli_data.h" diff --git a/companion/src/firmwares/heli_data.h b/companion/src/firmwares/heli_data.h new file mode 100644 index 000000000..734b29928 --- /dev/null +++ b/companion/src/firmwares/heli_data.h @@ -0,0 +1,44 @@ +/* + * 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. + */ + +#pragma once + +#include "rawsource.h" + +#include + +class SwashRingData { + Q_DECLARE_TR_FUNCTIONS(SwashRingData) + + public: + SwashRingData() { clear(); } + + int elevatorWeight; + int aileronWeight; + int collectiveWeight; + unsigned int type; + RawSource collectiveSource; + RawSource aileronSource; + RawSource elevatorSource; + unsigned int value; + + void clear() { memset(reinterpret_cast(this), 0, sizeof(SwashRingData)); } +}; + diff --git a/companion/src/firmwares/input_data.cpp b/companion/src/firmwares/input_data.cpp new file mode 100644 index 000000000..9b9ecfe20 --- /dev/null +++ b/companion/src/firmwares/input_data.cpp @@ -0,0 +1,35 @@ +/* + * 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 "input_data.h" +#include "radiodataconversionstate.h" + +void ExpoData::convert(RadioDataConversionState & cstate) +{ + cstate.setComponent(tr("INP"), 3); + cstate.setSubComp(RawSource(SOURCE_TYPE_VIRTUAL_INPUT, chn).toString(cstate.fromModel(), cstate.fromGS(), cstate.fromType) % tr(" (@%1)").arg(cstate.subCompIdx)); + srcRaw.convert(cstate); + swtch.convert(cstate); +} + +bool ExpoData::isEmpty() const +{ + return (chn == 0 && mode == INPUT_MODE_NONE); +} diff --git a/companion/src/firmwares/input_data.h b/companion/src/firmwares/input_data.h new file mode 100644 index 000000000..27b6b6282 --- /dev/null +++ b/companion/src/firmwares/input_data.h @@ -0,0 +1,61 @@ +/* + * 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. + */ + +#pragma once + +#include "curvereference.h" +#include "rawsource.h" +#include "rawswitch.h" + +#include + +class RadioDataConversionState; + +enum InputMode { + INPUT_MODE_NONE, + INPUT_MODE_POS, + INPUT_MODE_NEG, + INPUT_MODE_BOTH +}; + +#define EXPODATA_NAME_LEN 10 + +class ExpoData { + Q_DECLARE_TR_FUNCTIONS(ExpoData) + + public: + ExpoData() { clear(); } + + RawSource srcRaw; + unsigned int scale; + unsigned int mode; // InputMode + unsigned int chn; + RawSwitch swtch; + unsigned int flightModes; // -5=!FP4, 0=normal, 5=FP4 + int weight; + int offset; + CurveReference curve; + int carryTrim; + char name[EXPODATA_NAME_LEN + 1]; + + void convert(RadioDataConversionState & cstate); + void clear() { memset(reinterpret_cast(this), 0, sizeof(ExpoData)); } + bool isEmpty() const; +}; diff --git a/companion/src/firmwares/io_data.h b/companion/src/firmwares/io_data.h deleted file mode 100644 index b70b174ea..000000000 --- a/companion/src/firmwares/io_data.h +++ /dev/null @@ -1,199 +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. - */ - -#ifndef IO_DATA_H -#define IO_DATA_H - -#include "constants.h" -#include "curvereference.h" -#include "rawsource.h" -#include "rawswitch.h" - -#include - -class RadioDataConversionState; - -enum InputMode { - INPUT_MODE_NONE, - INPUT_MODE_POS, - INPUT_MODE_NEG, - INPUT_MODE_BOTH -}; - -#define EXPODATA_NAME_LEN 10 - -class ExpoData { - Q_DECLARE_TR_FUNCTIONS(ExpoData) - - public: - ExpoData() { clear(); } - RawSource srcRaw; - unsigned int scale; - unsigned int mode; // InputMode - unsigned int chn; - RawSwitch swtch; - unsigned int flightModes; // -5=!FP4, 0=normal, 5=FP4 - int weight; - int offset; - CurveReference curve; - int carryTrim; - char name[EXPODATA_NAME_LEN+1]; - void clear() { memset(reinterpret_cast(this), 0, sizeof(ExpoData)); } - void convert(RadioDataConversionState & cstate); - bool isEmpty() const; -}; - -enum MltpxValue { - MLTPX_ADD=0, - MLTPX_MUL=1, - MLTPX_REP=2 -}; - -#define MIXDATA_NAME_LEN 10 - -class MixData { - Q_DECLARE_TR_FUNCTIONS(MixData) - - public: - MixData() { clear(); } - void convert(RadioDataConversionState & cstate); - - unsigned int destCh; // 1..CPN_MAX_CHNOUT - RawSource srcRaw; - int weight; - RawSwitch swtch; - CurveReference curve; //0=symmetrisch - unsigned int delayUp; - unsigned int delayDown; - unsigned int speedUp; // Servogeschwindigkeit aus Tabelle (10ms Cycle) - unsigned int speedDown; // 0 nichts - int carryTrim; - bool noExpo; - MltpxValue mltpx; // multiplex method 0=+ 1=* 2=replace - unsigned int mixWarn; // mixer warning - unsigned int flightModes; // -5=!FP4, 0=normal, 5=FP4 - int sOffset; - char name[MIXDATA_NAME_LEN+1]; - - void clear() { memset(reinterpret_cast(this), 0, sizeof(MixData)); } - bool isEmpty() const; -}; - -#define LIMITDATA_NAME_LEN 6 - -class LimitData { - Q_DECLARE_TR_FUNCTIONS(LimitData) - - public: - LimitData() { clear(); } - int min; - int max; - bool revert; - int offset; - int ppmCenter; - bool symetrical; - int failsafe; - char name[LIMITDATA_NAME_LEN + 1]; - CurveReference curve; - QString minToString() const; - QString maxToString() const; - QString offsetToString() const; - QString revertToString() const; - QString nameToString(int index) const; - void clear(); - bool isEmpty() const; -}; - -class CurvePoint { - public: - int8_t x; - int8_t y; -}; - -#define CURVEDATA_NAME_LEN 6 - -class CurveData { - Q_DECLARE_TR_FUNCTIONS(CurveData) - - public: - enum CurveType { - CURVE_TYPE_STANDARD, - CURVE_TYPE_CUSTOM, - CURVE_TYPE_LAST = CURVE_TYPE_CUSTOM - }; - - CurveData(); - void clear(int count = 5); - bool isEmpty() const; - QString nameToString(const int idx) const; - - CurveType type; - bool smooth; - int count; - CurvePoint points[CPN_MAX_POINTS]; - char name[CURVEDATA_NAME_LEN+1]; -}; - -#define FLIGHTMODE_NAME_LEN 10 -#define RENC_MAX_VALUE 1024 -#define RENC_MIN_VALUE -RENC_MAX_VALUE - -class FlightModeData { - Q_DECLARE_TR_FUNCTIONS(FlightModeData) - - public: - FlightModeData() { clear(0); } - int trimMode[CPN_MAX_TRIMS]; - int trimRef[CPN_MAX_TRIMS]; - int trim[CPN_MAX_TRIMS]; - RawSwitch swtch; - char name[FLIGHTMODE_NAME_LEN+1]; - unsigned int fadeIn; - unsigned int fadeOut; - int rotaryEncoders[CPN_MAX_ENCODERS]; - int gvars[CPN_MAX_GVARS]; - void clear(const int phaseIdx); - QString nameToString(int phaseIdx) const; - void convert(RadioDataConversionState & cstate); - bool isEmpty(int phaseIdx) const; - bool isGVarEmpty(int phaseIdx, int gvIdx) const; - bool isREncEmpty(int phaseIdx, int reIdx) const; - int linkedFlightModeZero(int phaseIdx, int maxOwnValue) const; - int linkedGVarFlightModeZero(int phaseIdx) const; - int linkedREncFlightModeZero(int phaseIdx) const; -}; - -class SwashRingData { - Q_DECLARE_TR_FUNCTIONS(SwashRingData) - - public: - SwashRingData() { clear(); } - int elevatorWeight; - int aileronWeight; - int collectiveWeight; - unsigned int type; - RawSource collectiveSource; - RawSource aileronSource; - RawSource elevatorSource; - unsigned int value; - void clear() { memset(reinterpret_cast(this), 0, sizeof(SwashRingData)); } -}; - -#endif // IO_DATA_H diff --git a/companion/src/firmwares/mixdata.cpp b/companion/src/firmwares/mixdata.cpp new file mode 100644 index 000000000..ac2893a4d --- /dev/null +++ b/companion/src/firmwares/mixdata.cpp @@ -0,0 +1,35 @@ +/* + * 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 "mixdata.h" +#include "radiodataconversionstate.h" + +void MixData::convert(RadioDataConversionState & cstate) +{ + cstate.setComponent(tr("MIX"), 4); + cstate.setSubComp(RawSource(SOURCE_TYPE_CH, destCh-1).toString(cstate.fromModel(), cstate.fromGS(), cstate.fromType) % tr(" (@%1)").arg(cstate.subCompIdx)); + srcRaw.convert(cstate); + swtch.convert(cstate); +} + +bool MixData::isEmpty() const +{ + return (destCh == 0); +} diff --git a/companion/src/firmwares/mixdata.h b/companion/src/firmwares/mixdata.h new file mode 100644 index 000000000..dc81298f0 --- /dev/null +++ b/companion/src/firmwares/mixdata.h @@ -0,0 +1,65 @@ +/* + * 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. + */ + +#pragma once + +#include "curvereference.h" +#include "rawsource.h" +#include "rawswitch.h" + +#include + +class RadioDataConversionState; + +enum MltpxValue { + MLTPX_ADD, + MLTPX_MUL, + MLTPX_REP +}; + +#define MIXDATA_NAME_LEN 10 + +class MixData { + Q_DECLARE_TR_FUNCTIONS(MixData) + + public: + MixData() { clear(); } + + unsigned int destCh; // 1..CPN_MAX_CHNOUT + RawSource srcRaw; + int weight; + RawSwitch swtch; + CurveReference curve; + unsigned int delayUp; + unsigned int delayDown; + unsigned int speedUp; + unsigned int speedDown; + int carryTrim; + bool noExpo; + MltpxValue mltpx; + unsigned int mixWarn; + unsigned int flightModes; // -5=!FP4, 0=normal, 5=FP4 + int sOffset; + char name[MIXDATA_NAME_LEN + 1]; + + void convert(RadioDataConversionState & cstate); + void clear() { memset(reinterpret_cast(this), 0, sizeof(MixData)); } + bool isEmpty() const; +}; diff --git a/companion/src/firmwares/modeldata.h b/companion/src/firmwares/modeldata.h index 847997d94..80b7d7353 100644 --- a/companion/src/firmwares/modeldata.h +++ b/companion/src/firmwares/modeldata.h @@ -18,15 +18,19 @@ * GNU General Public License for more details. */ -#ifndef MODELDATA_H -#define MODELDATA_H +#pragma once #include "constants.h" +#include "curvedata.h" #include "customfunctiondata.h" #include "gvardata.h" -#include "io_data.h" +#include "flightmodedata.h" +#include "heli_data.h" +#include "input_data.h" #include "logicalswitchdata.h" +#include "mixdata.h" #include "moduledata.h" +#include "output_data.h" #include "sensordata.h" #include "telem_data.h" @@ -346,5 +350,3 @@ class ModelData { void sortMixes(); void updateResetParam(CustomFunctionData * cfd); }; - -#endif // MODELDATA_H diff --git a/companion/src/firmwares/output_data.cpp b/companion/src/firmwares/output_data.cpp new file mode 100644 index 000000000..63127d242 --- /dev/null +++ b/companion/src/firmwares/output_data.cpp @@ -0,0 +1,60 @@ +/* + * 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 "output_data.h" +#include "radiodata.h" +#include "radiodataconversionstate.h" + +void LimitData::clear() +{ + memset(reinterpret_cast(this), 0, sizeof(LimitData)); + min = -1000; + max = +1000; +} + +bool LimitData::isEmpty() const +{ + return (min == -1000 && max == 1000 && !revert && !offset && !ppmCenter && !symetrical && name[0] == '\0' && !curve.isSet()); +} + +QString LimitData::minToString() const +{ + return QString::number((qreal)min / 10); +} + +QString LimitData::maxToString() const +{ + return QString::number((qreal)max / 10); +} + +QString LimitData::revertToString() const +{ + return revert ? tr("INV") : tr("NOR"); +} + +QString LimitData::nameToString(int index) const +{ + return RadioData::getElementName(tr("CH"), index + 1, name); +} + +QString LimitData::offsetToString() const +{ + return QString::number((qreal)offset / 10, 'f', 1); +} diff --git a/companion/src/firmwares/output_data.h b/companion/src/firmwares/output_data.h new file mode 100644 index 000000000..423f03e49 --- /dev/null +++ b/companion/src/firmwares/output_data.h @@ -0,0 +1,52 @@ +/* + * 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. + */ + +#pragma once + +#include "curvereference.h" + +#include + +#define LIMITDATA_NAME_LEN 6 + +class LimitData { + Q_DECLARE_TR_FUNCTIONS(LimitData) + + public: + LimitData() { clear(); } + + int min; + int max; + bool revert; + int offset; + int ppmCenter; + bool symetrical; + int failsafe; + char name[LIMITDATA_NAME_LEN + 1]; + CurveReference curve; + + void clear(); + bool isEmpty() const; + QString minToString() const; + QString maxToString() const; + QString offsetToString() const; + QString revertToString() const; + QString nameToString(int index) const; +}; diff --git a/companion/src/firmwares/sensordata.cpp b/companion/src/firmwares/sensordata.cpp index a87dc6d21..2c0866e66 100644 --- a/companion/src/firmwares/sensordata.cpp +++ b/companion/src/firmwares/sensordata.cpp @@ -427,6 +427,28 @@ bool SensorData::isSourceAvailable(const ModelData * model, const int index) return false; } +#define RSSI_ID 0xF101 + +// static +bool SensorData::isRssiSensorAvailable(const ModelData * model, const int value) +{ + if (value == 0) + return true; + else { + const SensorData &sensor = model->sensorData[abs(value) - 1]; + return (sensor.isAvailable() && sensor.id == RSSI_ID); + } +} + +// static +QString SensorData::rssiSensorToString(const ModelData * model, const int value) +{ + if (value == 0) + return tr("(default)"); + else + return sourceToString(model, value); +} + // static AbstractStaticItemModel * SensorData::typeItemModel() { diff --git a/companion/src/firmwares/sensordata.h b/companion/src/firmwares/sensordata.h index 5e888d749..2353a0ebf 100644 --- a/companion/src/firmwares/sensordata.h +++ b/companion/src/firmwares/sensordata.h @@ -206,6 +206,8 @@ class SensorData { static QString unitToString(const int value); static QString precToString(const int value); static QString boolToString(const bool value) { return value ? tr("Y") : tr("N"); } + static bool isRssiSensorAvailable(const ModelData * model, const int value); + static QString rssiSensorToString(const ModelData * model, const int value); static AbstractStaticItemModel * typeItemModel(); static AbstractStaticItemModel * formulaItemModel(); diff --git a/companion/src/generaledit/generalsetup.ui b/companion/src/generaledit/generalsetup.ui index 7353b9c4b..422eddc7d 100644 --- a/companion/src/generaledit/generalsetup.ui +++ b/companion/src/generaledit/generalsetup.ui @@ -1527,7 +1527,7 @@ Mode 4: Battery warning voltage. This is the threashhold where the battery warning sounds. -Acceptable values are 5v..10v +Acceptable values are 3v..12v @@ -1539,7 +1539,7 @@ Acceptable values are 5v..10v 1 - 4.000000000000000 + 3.000000000000000 12.000000000000000 @@ -1679,7 +1679,7 @@ Acceptable values are 5v..10v 1 - 4.000000000000000 + 3.000000000000000 16.000000000000000 @@ -1708,7 +1708,7 @@ Acceptable values are 5v..10v 1 - 4.000000000000000 + 3.000000000000000 16.000000000000000 diff --git a/companion/src/helpers.cpp b/companion/src/helpers.cpp index 020f1b45b..c1cd7de79 100644 --- a/companion/src/helpers.cpp +++ b/companion/src/helpers.cpp @@ -32,6 +32,7 @@ #include "simulatorinterface.h" #include "simulatormainwindow.h" #include "storage/sdcard.h" +#include "filtereditemmodels.h" #include #include @@ -117,7 +118,8 @@ void CompanionIcon::addImage(const QString & baseimage, Mode mode, State state) * GVarGroup */ -GVarGroup::GVarGroup(QCheckBox * weightGV, QAbstractSpinBox * weightSB, QComboBox * weightCB, int & weight, const ModelData & model, const int deflt, const int mini, const int maxi, const double step, bool allowGvars): +GVarGroup::GVarGroup(QCheckBox * weightGV, QAbstractSpinBox * weightSB, QComboBox * weightCB, int & weight, const ModelData & model, + const int deflt, const int mini, const int maxi, const double step, FilteredItemModel * gvarModel): QObject(), weightGV(weightGV), weightSB(weightSB), @@ -131,8 +133,8 @@ GVarGroup::GVarGroup(QCheckBox * weightGV, QAbstractSpinBox * weightSB, QComboBo step(step), lock(true) { - if (allowGvars && getCurrentFirmware()->getCapability(Gvars)) { - Helpers::populateGVCB(*weightCB, weight, model); + if (gvarModel && gvarModel->rowCount() > 0) { + weightCB->setModel(gvarModel); connect(weightGV, SIGNAL(stateChanged(int)), this, SLOT(gvarCBChanged(int))); connect(weightCB, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesChanged())); } @@ -152,12 +154,19 @@ GVarGroup::GVarGroup(QCheckBox * weightGV, QAbstractSpinBox * weightSB, QComboBo void GVarGroup::gvarCBChanged(int state) { - weightCB->setVisible(state); - if (weightSB) + if (!lock) { + weightCB->setVisible(state); + if (weightGV->isChecked()) { + // set CB to +GV1 + int cnt = getCurrentFirmware()->getCapability(Gvars); + if (weightCB->count() > cnt) + weightCB->setCurrentIndex(cnt); + else + weightCB->setCurrentIndex(0); + } weightSB->setVisible(!state); - else - weightSB->setVisible(!state); - valuesChanged(); + valuesChanged(); + } } void GVarGroup::valuesChanged() @@ -168,7 +177,7 @@ void GVarGroup::valuesChanged() else if (sb) weight = sb->value(); else - weight = round(dsb->value()/step); + weight = round(dsb->value() / step); emit valueChanged(); } @@ -180,7 +189,7 @@ void GVarGroup::setWeight(int val) int tval; - if (val>maxi || val maxi || val < mini) { tval = deflt; weightGV->setChecked(true); weightSB->hide(); @@ -214,27 +223,6 @@ void GVarGroup::setWeight(int val) * Helpers namespace functions */ -void Helpers::populateGVCB(QComboBox & b, int value, const ModelData & model) -{ - int count = getCurrentFirmware()->getCapability(Gvars); - - b.clear(); - - for (int i=-count; i<=-1; i++) { - int16_t gval = (int16_t)(-10000+i); - b.addItem("-" + RawSource(SOURCE_TYPE_GVAR, abs(i)-1).toString(&model), gval); - } - - for (int i=1; i<=count; i++) { - int16_t gval = (int16_t)(10000+i); - b.addItem(RawSource(SOURCE_TYPE_GVAR, i-1).toString(&model), gval); - } - - b.setCurrentIndex(b.findData(value)); - if (b.currentIndex() == -1) - b.setCurrentIndex(count); -} - // TODO: Move lookup to GVarData class (w/out combobox) void Helpers::populateGvarUseCB(QComboBox * b, unsigned int phase) { diff --git a/companion/src/helpers.h b/companion/src/helpers.h index 107ca2aa0..8bb1cc6b8 100644 --- a/companion/src/helpers.h +++ b/companion/src/helpers.h @@ -18,8 +18,7 @@ * GNU General Public License for more details. */ -#ifndef _HELPERS_H_ -#define _HELPERS_H_ +#pragma once #include "eeprominterface.h" #include @@ -60,12 +59,15 @@ class CompanionIcon: public QIcon { void addImage(const QString &baseimage, Mode mode = Normal, State state = Off); }; +class FilteredItemModel; + class GVarGroup: public QObject { Q_OBJECT public: - GVarGroup(QCheckBox * weightGV, QAbstractSpinBox * weightSB, QComboBox * weightCB, int & weight, const ModelData & model, const int deflt, const int mini, const int maxi, const double step=1.0, bool allowGVars=true); + GVarGroup(QCheckBox * weightGV, QAbstractSpinBox * weightSB, QComboBox * weightCB, int & weight, const ModelData & model, + const int deflt, const int mini, const int maxi, const double step = 1.0, FilteredItemModel * gvarModel = nullptr); void setWeight(int val); @@ -101,7 +103,6 @@ class GVarGroup: public QObject { namespace Helpers { void populateGvarUseCB(QComboBox *b, unsigned int phase); - void populateGVCB(QComboBox & b, int value, const ModelData & model); void populateFileComboBox(QComboBox * b, const QSet & set, const QString & current); void getFileComboBoxValue(QComboBox * b, char * dest, int length); @@ -234,5 +235,3 @@ private: }; extern Stopwatch gStopwatch; - -#endif // _HELPERS_H_ diff --git a/companion/src/modeledit/channels.cpp b/companion/src/modeledit/channels.cpp index 27374a8c4..5ec77ce55 100644 --- a/companion/src/modeledit/channels.cpp +++ b/companion/src/modeledit/channels.cpp @@ -22,42 +22,31 @@ #include "helpers.h" #include "filtereditemmodels.h" -LimitsGroup::LimitsGroup(Firmware * firmware, TableLayout * tableLayout, int row, int col, int & value, const ModelData & model, int min, int max, int deflt, ModelPanel * panel): +LimitsGroup::LimitsGroup(Firmware * firmware, TableLayout * tableLayout, int row, int col, int & value, const ModelData & model, + int min, int max, int deflt, FilteredItemModel * gvarModel, ModelPanel * panel): firmware(firmware), spinbox(new QDoubleSpinBox()), - value(value), - displayStep(0.1) + value(value) { - Board::Type board = firmware->getBoard(); - bool allowGVars = IS_HORUS_OR_TARANIS(board); - int internalStep = 1; - spinbox->setProperty("index", row); spinbox->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); spinbox->setAccelerated(true); + spinbox->setDecimals(1); if (firmware->getCapability(PPMUnitMicroseconds)) { displayStep = 0.512; - spinbox->setDecimals(1); spinbox->setSuffix("us"); } else { - spinbox->setDecimals(0); + displayStep = 0.1; spinbox->setSuffix("%"); } - if (deflt == 0 /*it's the offset*/) { - spinbox->setDecimals(1); - } - else { - internalStep *= 10; - } - - spinbox->setSingleStep(displayStep * internalStep); + spinbox->setSingleStep(displayStep); spinbox->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); QHBoxLayout *horizontalLayout = new QHBoxLayout(); - QCheckBox *gv = new QCheckBox(tr("GV")); + gv = new QCheckBox(tr("GV")); gv->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); horizontalLayout->addWidget(gv); QComboBox *cb = new QComboBox(); @@ -65,7 +54,7 @@ LimitsGroup::LimitsGroup(Firmware * firmware, TableLayout * tableLayout, int row horizontalLayout->addWidget(cb); horizontalLayout->addWidget(spinbox); tableLayout->addLayout(row, col, horizontalLayout); - gvarGroup = new GVarGroup(gv, spinbox, cb, value, model, deflt, min, max, displayStep, allowGVars); + gvarGroup = new GVarGroup(gv, spinbox, cb, value, model, deflt, min, max, displayStep, gvarModel); QObject::connect(gvarGroup, &GVarGroup::valueChanged, panel, &ModelPanel::modified); } @@ -84,18 +73,19 @@ void LimitsGroup::updateMinMax(int max) if (spinbox->maximum() == 0) { spinbox->setMinimum(-max * displayStep); gvarGroup->setMinimum(-max); - if (value < -max) { + if (!gv->isChecked() && value < -max) { value = -max; } } if (spinbox->minimum() == 0) { spinbox->setMaximum(max * displayStep); gvarGroup->setMaximum(max); - if (value > max) { + if (!gv->isChecked() && value > max) { value = max; } } } + ChannelsPanel::ChannelsPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels): ModelPanel(parent, model, generalSettings, firmware), sharedItemModels(sharedItemModels) @@ -103,8 +93,12 @@ ChannelsPanel::ChannelsPanel(QWidget * parent, ModelData & model, GeneralSetting chnCapability = firmware->getCapability(Outputs); int channelNameMaxLen = firmware->getCapability(ChannelsName); - curveFilteredModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_Curve)); - connectItemModelEvents(curveFilteredModel); + dialogFilteredItemModels = new FilteredItemModelFactory(); + + int crvid = dialogFilteredItemModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_Curve)), "Curve"); + connectItemModelEvents(dialogFilteredItemModels->getItemModel(crvid)); + + int gvid = dialogFilteredItemModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_GVarRef)), "GVarRef"); QStringList headerLabels; headerLabels << "#"; @@ -146,13 +140,13 @@ ChannelsPanel::ChannelsPanel(QWidget * parent, ModelData & model, GeneralSetting } // Channel offset - chnOffset[i] = new LimitsGroup(firmware, tableLayout, i, col++, model.limitData[i].offset, model, -1000, 1000, 0, this); + chnOffset[i] = new LimitsGroup(firmware, tableLayout, i, col++, model.limitData[i].offset, model, -1000, 1000, 0, dialogFilteredItemModels->getItemModel(gvid), this); // Channel min - chnMin[i] = new LimitsGroup(firmware, tableLayout, i, col++, model.limitData[i].min, model, -model.getChannelsMax() * 10, 0, -1000, this); + chnMin[i] = new LimitsGroup(firmware, tableLayout, i, col++, model.limitData[i].min, model, -model.getChannelsMax() * 10, 0, -1000, dialogFilteredItemModels->getItemModel(gvid), this); // Channel max - chnMax[i] = new LimitsGroup(firmware, tableLayout, i, col++, model.limitData[i].max, model, 0, model.getChannelsMax() * 10, 1000, this); + chnMax[i] = new LimitsGroup(firmware, tableLayout, i, col++, model.limitData[i].max, model, 0, model.getChannelsMax() * 10, 1000, dialogFilteredItemModels->getItemModel(gvid), this); // Channel inversion invCB[i] = new QComboBox(this); @@ -165,7 +159,7 @@ ChannelsPanel::ChannelsPanel(QWidget * parent, ModelData & model, GeneralSetting if (IS_HORUS_OR_TARANIS(firmware->getBoard())) { curveCB[i] = new QComboBox(this); curveCB[i]->setProperty("index", i); - curveCB[i]->setModel(curveFilteredModel); + curveCB[i]->setModel(dialogFilteredItemModels->getItemModel(crvid)); connect(curveCB[i], SIGNAL(currentIndexChanged(int)), this, SLOT(curveEdited())); tableLayout->addWidget(i, col++, curveCB[i]); } @@ -213,7 +207,7 @@ ChannelsPanel::~ChannelsPanel() delete centerSB[i]; delete symlimitsChk[i]; } - delete curveFilteredModel; + delete dialogFilteredItemModels; } void ChannelsPanel::symlimitsEdited() @@ -241,12 +235,11 @@ void ChannelsPanel::nameEdited() void ChannelsPanel::refreshExtendedLimits() { - int channelMax = model->getChannelsMax(); + int channelMax = model->getChannelsMax() * 10; for (int i = 0 ; i < CPN_MAX_CHNOUT; i++) { - chnOffset[i]->updateMinMax(10 * channelMax); - chnMin[i]->updateMinMax(10 * channelMax); - chnMax[i]->updateMinMax(10 * channelMax); + chnMin[i]->updateMinMax(channelMax); + chnMax[i]->updateMinMax(channelMax); } emit modified(); } diff --git a/companion/src/modeledit/channels.h b/companion/src/modeledit/channels.h index 2a65f497a..574e316d8 100644 --- a/companion/src/modeledit/channels.h +++ b/companion/src/modeledit/channels.h @@ -18,8 +18,7 @@ * GNU General Public License for more details. */ -#ifndef _CHANNELS_H_ -#define _CHANNELS_H_ +#pragma once #include "helpers.h" #include "modeledit.h" @@ -27,7 +26,7 @@ #include class CompoundItemModelFactory; -class FilteredItemModel; +class FilteredItemModelFactory; constexpr char MIMETYPE_CHANNEL[] = "application/x-companion-channel"; @@ -38,7 +37,8 @@ class LimitsGroup Q_DECLARE_TR_FUNCTIONS(LimitsGroup) public: - LimitsGroup(Firmware * firmware, TableLayout * tableLayout, int row, int col, int & value, const ModelData & model, int min, int max, int deflt, ModelPanel * panel=NULL); + LimitsGroup(Firmware * firmware, TableLayout * tableLayout, int row, int col, int & value, const ModelData & model, + int min, int max, int deflt, FilteredItemModel * gvarModel, ModelPanel * panel = nullptr); ~LimitsGroup(); void setValue(int val); @@ -50,6 +50,7 @@ class LimitsGroup GVarGroup *gvarGroup; int &value; double displayStep; + QCheckBox *gv; }; class ChannelsPanel : public ModelPanel @@ -57,7 +58,8 @@ class ChannelsPanel : public ModelPanel Q_OBJECT public: - ChannelsPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels); + ChannelsPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, + CompoundItemModelFactory * sharedItemModels); virtual ~ChannelsPanel(); public slots: @@ -101,9 +103,7 @@ class ChannelsPanel : public ModelPanel int selectedIndex; int chnCapability; CompoundItemModelFactory *sharedItemModels; - FilteredItemModel *curveFilteredModel; void updateItemModels(); void connectItemModelEvents(const FilteredItemModel * itemModel); + FilteredItemModelFactory *dialogFilteredItemModels; }; - -#endif // _CHANNELS_H_ diff --git a/companion/src/modeledit/customfunctions.cpp b/companion/src/modeledit/customfunctions.cpp index 5c15bd538..c773e90e5 100644 --- a/companion/src/modeledit/customfunctions.cpp +++ b/companion/src/modeledit/customfunctions.cpp @@ -19,53 +19,11 @@ */ #include "customfunctions.h" -#include "filtereditemmodels.h" #include "helpers.h" #include "appdata.h" #include -RepeatComboBox::RepeatComboBox(QWidget *parent, int & repeatParam): - QComboBox(parent), - repeatParam(repeatParam) -{ - unsigned int step = 1; - int value = repeatParam/step; - - setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed); - - if (step == 1) { - addItem(tr("Played once, not during startup"), -1); - value++; - } - - addItem(tr("No repeat"), 0); - - for (unsigned int i = step; i <= 60; i += step) { - addItem(tr("%1s").arg(i), i); - } - - setCurrentIndex(value); - - connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(onIndexChanged(int))); -} - -void RepeatComboBox::onIndexChanged(int index) -{ - repeatParam = itemData(index).toInt(); - emit modified(); -} - -void RepeatComboBox::update() -{ - unsigned int step = 1; - int value = repeatParam/step; - if (step == 1) { - value++; - } - setCurrentIndex(value); -} - CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels): GenericPanel(parent, model, generalSettings, firmware), @@ -77,18 +35,41 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, lock = true; fswCapability = model ? firmware->getCapability(CustomFunctions) : firmware->getCapability(GlobalFunctions); - rawSwitchFilteredModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSwitch), - model ? RawSwitch::SpecialFunctionsContext : RawSwitch::GlobalFunctionsContext); - connectItemModelEvents(rawSwitchFilteredModel); + tabModelFactory = new CompoundItemModelFactory(&generalSettings, model); + playSoundId = tabModelFactory->registerItemModel(CustomFunctionData::playSoundItemModel()); + harpicId = tabModelFactory->registerItemModel(CustomFunctionData::harpicItemModel()); + repeatId = tabModelFactory->registerItemModel(CustomFunctionData::repeatItemModel()); + gvarAdjustModeId = tabModelFactory->registerItemModel(CustomFunctionData::gvarAdjustModeItemModel()); - rawSourceAllModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource)); - connectItemModelEvents(rawSourceAllModel); + tabFilterFactory = new FilteredItemModelFactory(); - rawSourceInputsModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource), RawSource::InputSourceGroups); - connectItemModelEvents(rawSourceInputsModel); + funcActionsId = tabFilterFactory->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_CustomFuncAction), + model ? CustomFunctionData::AllFunctionContexts : CustomFunctionData::GlobalFunctionsContext), + "Function Actions"); + connectItemModelEvents(tabFilterFactory->getItemModel(funcActionsId)); - rawSourceGVarsModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource), RawSource::GVarsGroup); - connectItemModelEvents(rawSourceGVarsModel); + funcResetParamId = tabFilterFactory->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_CustomFuncResetParam)), + "Reset Params"); + connectItemModelEvents(tabFilterFactory->getItemModel(funcResetParamId)); + + rawSwitchId = tabFilterFactory->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSwitch), + model ? RawSwitch::SpecialFunctionsContext : RawSwitch::GlobalFunctionsContext), + "RawSwitch"); + connectItemModelEvents(tabFilterFactory->getItemModel(rawSwitchId)); + + rawSourceAllId = tabFilterFactory->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource)), + "RawSource All"); + connectItemModelEvents(tabFilterFactory->getItemModel(rawSourceAllId)); + + rawSourceInputsId = tabFilterFactory->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource), + RawSource::InputSourceGroups), + "RawSource Inputs"); + connectItemModelEvents(tabFilterFactory->getItemModel(rawSourceInputsId)); + + rawSourceGVarsId = tabFilterFactory->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource), + RawSource::GVarsGroup), + "RawSource GVars"); + connectItemModelEvents(tabFilterFactory->getItemModel(rawSourceGVarsId)); if (!firmware->getCapability(VoicesAsNumbers)) { tracksSet = getFilesSet(getSoundsPath(generalSettings), QStringList() << "*.wav" << "*.WAV", firmware->getCapability(VoicesMaxLength)); @@ -118,7 +99,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, playIcon.addImage("stop.png", QIcon::Normal, QIcon::On); QStringList headerLabels; - headerLabels << "#" << tr("Switch") << tr("Action") << tr("Parameters") << tr("Enable"); + headerLabels << "#" << tr("Switch") << tr("Action") << tr("Parameters") << ""; TableLayout * tableLayout = new TableLayout(this, fswCapability, headerLabels); for (int i = 0; i < fswCapability; i++) { @@ -135,32 +116,26 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum); connect(label, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onCustomContextMenuRequested(QPoint))); tableLayout->addWidget(i, 0, label); - // s1.report("label"); // The switch fswtchSwtch[i] = new QComboBox(this); - fswtchSwtch[i]->setModel(rawSwitchFilteredModel); - fswtchSwtch[i]->setCurrentIndex(fswtchSwtch[i]->findData(functions[i].swtch.toValue())); fswtchSwtch[i]->setProperty("index", i); + fswtchSwtch[i]->setModel(tabFilterFactory->getItemModel(rawSwitchId)); + fswtchSwtch[i]->setCurrentIndex(fswtchSwtch[i]->findData(functions[i].swtch.toValue())); fswtchSwtch[i]->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Minimum); + fswtchSwtch[i]->setSizeAdjustPolicy(QComboBox::AdjustToContents); fswtchSwtch[i]->setMaxVisibleItems(10); connect(fswtchSwtch[i], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited())); tableLayout->addWidget(i, 1, fswtchSwtch[i]); - // s1.report("switch"); // The function fswtchFunc[i] = new QComboBox(this); - if (!i) { - populateFuncCB(fswtchFunc[i], functions[i].func); - } - else { - fswtchFunc[i]->setModel(fswtchFunc[0]->model()); - fswtchFunc[i]->setCurrentIndex(fswtchFunc[i]->findData(functions[i].func)); - } fswtchFunc[i]->setProperty("index", i); + fswtchFunc[i]->setModel(tabFilterFactory->getItemModel(funcActionsId)); + fswtchFunc[i]->setCurrentIndex(fswtchFunc[i]->findData(functions[i].func)); + fswtchFunc[i]->setSizeAdjustPolicy(QComboBox::AdjustToContents); connect(fswtchFunc[i], SIGNAL(currentIndexChanged(int)), this, SLOT(functionEdited())); tableLayout->addWidget(i, 2, fswtchFunc[i]); - // s1.report("func"); // The parameters QHBoxLayout * paramLayout = new QHBoxLayout(); @@ -168,15 +143,15 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, fswtchGVmode[i] = new QComboBox(this); fswtchGVmode[i]->setProperty("index", i); - populateGVmodeCB(fswtchGVmode[i], functions[i].adjustMode); + fswtchGVmode[i]->setModel(tabModelFactory->getItemModel(gvarAdjustModeId)); fswtchGVmode[i]->setSizeAdjustPolicy(QComboBox::AdjustToContents); connect(fswtchGVmode[i], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited())); paramLayout->addWidget(fswtchGVmode[i]); fswtchParamGV[i] = new QCheckBox(this); fswtchParamGV[i]->setProperty("index", i); - fswtchParamGV[i]->setText("GV"); - fswtchParamGV[i]->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); + fswtchParamGV[i]->setText(tr("GV")); + fswtchParamGV[i]->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); connect(fswtchParamGV[i], SIGNAL(stateChanged(int)), this, SLOT(customFunctionEdited())); paramLayout->addWidget(fswtchParamGV[i]); @@ -207,15 +182,6 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, connect(fswtchParamArmT[i], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited())); connect(fswtchParamArmT[i], SIGNAL(editTextChanged ( const QString)), this, SLOT(customFunctionEdited())); - fswtchBLcolor[i] = new QSlider(this); - fswtchBLcolor[i]->setProperty("index", i); - fswtchBLcolor[i]->setMinimum(0); - fswtchBLcolor[i]->setMaximum(100); - fswtchBLcolor[i]->setSingleStep(1); - fswtchBLcolor[i]->setOrientation(Qt::Horizontal); - paramLayout->addWidget(fswtchBLcolor[i]); - connect(fswtchBLcolor[i], SIGNAL(sliderReleased()), this, SLOT(customFunctionEdited())); - playBT[i] = new QToolButton(this); playBT[i]->setProperty("index", i); playBT[i]->setIcon(playIcon); @@ -225,9 +191,13 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, QHBoxLayout * repeatLayout = new QHBoxLayout(); tableLayout->addLayout(i, 4, repeatLayout); - fswtchRepeat[i] = new RepeatComboBox(this, functions[i].repeatParam); + fswtchRepeat[i] = new QComboBox(this); + fswtchRepeat[i]->setProperty("index", i); + fswtchRepeat[i]->setModel(tabModelFactory->getItemModel(repeatId)); + fswtchRepeat[i]->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed); + fswtchRepeat[i]->setSizeAdjustPolicy(QComboBox::AdjustToContents); repeatLayout->addWidget(fswtchRepeat[i], i + 1); - connect(fswtchRepeat[i], SIGNAL(modified()), this, SLOT(onRepeatModified())); + connect(fswtchRepeat[i], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited())); fswtchEnable[i] = new QCheckBox(this); fswtchEnable[i]->setProperty("index", i); @@ -250,10 +220,8 @@ CustomFunctionsPanel::~CustomFunctionsPanel() { if (mediaPlayer) stopSound(mediaPlayerCurrent); - delete rawSwitchFilteredModel; - delete rawSourceAllModel; - delete rawSourceInputsModel; - delete rawSourceGVarsModel; + delete tabModelFactory; + delete tabFilterFactory; } void CustomFunctionsPanel::onMediaPlayerStateChanged(QMediaPlayer::State state) @@ -333,7 +301,6 @@ void CustomFunctionsPanel::toggleSound(bool play) #define CUSTOM_FUNCTION_ENABLE (1<<6) #define CUSTOM_FUNCTION_REPEAT (1<<7) #define CUSTOM_FUNCTION_PLAY (1<<8) -#define CUSTOM_FUNCTION_BL_COLOR (1<<9) #define CUSTOM_FUNCTION_SHOW_FUNC (1<<10) @@ -363,11 +330,6 @@ void CustomFunctionsPanel::functionEdited() } } -void CustomFunctionsPanel::onRepeatModified() -{ - emit modified(); -} - void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) { CustomFunctionData & cfn = functions[i]; @@ -414,8 +376,8 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) else if (func >= FuncAdjustGV1 && func <= FuncAdjustGVLast) { int gvidx = func - FuncAdjustGV1; if (modified) - cfn.adjustMode = fswtchGVmode[i]->currentIndex(); - fswtchGVmode[i]->setCurrentIndex(cfn.adjustMode); + cfn.adjustMode = fswtchGVmode[i]->currentData().toInt(); + fswtchGVmode[i]->setCurrentIndex(fswtchGVmode[i]->findData(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) @@ -468,8 +430,10 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) } else if (func == FuncPlaySound || func == FuncPlayHaptic || func == FuncPlayValue || func == FuncPlayPrompt || func == FuncPlayBoth || func == FuncBackgroundMusic) { if (func != FuncBackgroundMusic) { + if (modified) + cfn.repeatParam = fswtchRepeat[i]->currentData().toInt(); widgetsMask |= CUSTOM_FUNCTION_REPEAT; - fswtchRepeat[i]->update(); + fswtchRepeat[i]->setCurrentIndex(fswtchRepeat[i]->findData(cfn.repeatParam)); } if (func == FuncPlayValue) { if (modified) @@ -493,7 +457,7 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) if (modified) { if (fswtchParamGV[i]->isChecked()) { fswtchParam[i]->setMinimum(1); - cfn.param = std::min(fswtchParam[i]->value(),5.0)+(fswtchParamGV[i]->isChecked() ? 250 : 0); + cfn.param = std::min(fswtchParam[i]->value(), 5.0) + (fswtchParamGV[i]->isChecked() ? 250 : 0); } else { cfn.param = fswtchParam[i]->value(); @@ -577,7 +541,6 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) 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); } @@ -653,77 +616,43 @@ void CustomFunctionsPanel::onCustomContextMenuRequested(QPoint pos) contextMenu.exec(globalPos); } -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))) - ) { - // skipped - continue; - } - else { - b->addItem(CustomFunctionData(AssignFunc(i)).funcToString(model), i); - if (i == value) { - b->setCurrentIndex(b->count() - 1); - } - } - } -} - -void CustomFunctionsPanel::populateGVmodeCB(QComboBox *b, unsigned int value) -{ - b->clear(); - b->addItem(tr("Value")); - b->addItem(tr("Source")); - b->addItem(tr("GVAR")); - b->addItem(tr("Increment")); - b->setCurrentIndex(value); -} - void CustomFunctionsPanel::populateFuncParamCB(QComboBox *b, uint function, unsigned int value, unsigned int adjustmode) { QStringList qs; b->setModel(new QStandardItemModel(b)); // clear combo box but not any shared item model if (function == FuncPlaySound) { - CustomFunctionData::populatePlaySoundParams(qs); - b->addItems(qs); - b->setCurrentIndex(value); + b->setModel(tabModelFactory->getItemModel(playSoundId)); + b->setCurrentIndex(b->findData(value)); } else if (function == FuncPlayHaptic) { - CustomFunctionData::populateHapticParams(qs); - b->addItems(qs); - b->setCurrentIndex(value); + b->setModel(tabModelFactory->getItemModel(harpicId)); + b->setCurrentIndex(b->findData(value)); } else if (function == FuncReset) { - CustomFunctionData::populateResetParams(model, b, value); + b->setModel(tabFilterFactory->getItemModel(funcResetParamId)); + b->setCurrentIndex(b->findData(value)); } else if (function == FuncVolume || function == FuncBacklight) { - b->setModel(rawSourceInputsModel); + b->setModel(tabFilterFactory->getItemModel(rawSourceInputsId)); b->setCurrentIndex(b->findData(value)); } else if (function == FuncPlayValue) { - b->setModel(rawSourceAllModel); + b->setModel(tabFilterFactory->getItemModel(rawSourceAllId)); b->setCurrentIndex(b->findData(value)); } else if (function >= FuncAdjustGV1 && function <= FuncAdjustGVLast) { switch (adjustmode) { case 1: - b->setModel(rawSourceInputsModel); + b->setModel(tabFilterFactory->getItemModel(rawSourceInputsId)); b->setCurrentIndex(b->findData(value)); + if (b->currentIndex() < 0) + b->setCurrentIndex(0); break; case 2: - b->setModel(rawSourceGVarsModel); + b->setModel(tabFilterFactory->getItemModel(rawSourceGVarsId)); b->setCurrentIndex(b->findData(value)); + if (b->currentIndex() < 0) + b->setCurrentIndex(0); break; } } @@ -828,7 +757,7 @@ bool CustomFunctionsPanel::moveUpAllowed() const return selectedIndex > 0; } -void CustomFunctionsPanel::connectItemModelEvents(const FilteredItemModel * itemModel) +void CustomFunctionsPanel::connectItemModelEvents(FilteredItemModel * itemModel) { connect(itemModel, &FilteredItemModel::aboutToBeUpdated, this, &CustomFunctionsPanel::onItemModelAboutToBeUpdated); connect(itemModel, &FilteredItemModel::updateComplete, this, &CustomFunctionsPanel::onItemModelUpdateComplete); diff --git a/companion/src/modeledit/customfunctions.h b/companion/src/modeledit/customfunctions.h index e41baf672..87775246d 100644 --- a/companion/src/modeledit/customfunctions.h +++ b/companion/src/modeledit/customfunctions.h @@ -18,38 +18,19 @@ * GNU General Public License for more details. */ -#ifndef _CUSTOMFUNCTIONS_H_ -#define _CUSTOMFUNCTIONS_H_ +#pragma once #include "modeledit.h" #include "eeprominterface.h" +#include "compounditemmodels.h" +#include "filtereditemmodels.h" #include -class CompoundItemModelFactory; -class FilteredItemModel; class TimerEdit; constexpr char MIMETYPE_CUSTOM_FUNCTION[] = "application/x-companion-custom-function"; -class RepeatComboBox: public QComboBox -{ - Q_OBJECT - - public: - RepeatComboBox(QWidget * parent, int & repeatParam); - void update(); - - signals: - void modified(); - - private slots: - void onIndexChanged(int); - - protected: - int & repeatParam; -}; - class CustomFunctionsPanel : public GenericPanel { Q_OBJECT @@ -68,7 +49,6 @@ class CustomFunctionsPanel : public GenericPanel void functionEdited(); void onCustomContextMenuRequested(QPoint pos); void refreshCustomFunction(int index, bool modified=false); - void onRepeatModified(); bool playSound(int index); void stopSound(int index); void toggleSound(bool play); @@ -87,8 +67,6 @@ class CustomFunctionsPanel : public GenericPanel void onItemModelUpdateComplete(); private: - void populateFuncCB(QComboBox *b, unsigned int value); - void populateGVmodeCB(QComboBox *b, unsigned int value); void populateFuncParamCB(QComboBox *b, uint function, unsigned int value, unsigned int adjustmode=0); bool hasClipboardData(QByteArray * data = nullptr) const; bool insertAllowed() const; @@ -96,12 +74,20 @@ class CustomFunctionsPanel : public GenericPanel bool moveUpAllowed() const; void swapData(int idx1, int idx2); void resetCBsAndRefresh(int idx); - void connectItemModelEvents(const FilteredItemModel * itemModel); + void connectItemModelEvents(FilteredItemModel * itemModel); - FilteredItemModel * rawSwitchFilteredModel; - FilteredItemModel * rawSourceAllModel; - FilteredItemModel * rawSourceInputsModel; - FilteredItemModel * rawSourceGVarsModel; + CompoundItemModelFactory * tabModelFactory; + FilteredItemModelFactory * tabFilterFactory; + int funcActionsId; + int funcResetParamId; + int rawSwitchId; + int rawSourceAllId; + int rawSourceInputsId; + int rawSourceGVarsId; + int playSoundId; + int harpicId; + int repeatId; + int gvarAdjustModeId; QSet tracksSet; QSet scriptsSet; @@ -115,14 +101,11 @@ class CustomFunctionsPanel : public GenericPanel QComboBox * fswtchParamT[CPN_MAX_SPECIAL_FUNCTIONS]; QComboBox * fswtchParamArmT[CPN_MAX_SPECIAL_FUNCTIONS]; QCheckBox * fswtchEnable[CPN_MAX_SPECIAL_FUNCTIONS]; - RepeatComboBox * fswtchRepeat[CPN_MAX_SPECIAL_FUNCTIONS]; + QComboBox * fswtchRepeat[CPN_MAX_SPECIAL_FUNCTIONS]; QComboBox * fswtchGVmode[CPN_MAX_SPECIAL_FUNCTIONS]; - QSlider * fswtchBLcolor[CPN_MAX_SPECIAL_FUNCTIONS]; QMediaPlayer * mediaPlayer; int selectedIndex; int fswCapability; int modelsUpdateCnt; }; - -#endif // _CUSTOMFUNCTIONS_H_ diff --git a/companion/src/modeledit/expodialog.cpp b/companion/src/modeledit/expodialog.cpp index abede1d73..be549144c 100644 --- a/companion/src/modeledit/expodialog.cpp +++ b/companion/src/modeledit/expodialog.cpp @@ -50,8 +50,11 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G setWindowTitle(tr("Edit %1").arg(RawSource(srcType, ed->chn).toString(&model, &generalSettings))); QRegExp rx(CHAR_FOR_NAMES_REGEX); - 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); + id = dialogFilteredItemModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_GVarRef)), "GVarRef"); + gvWeightGroup = new GVarGroup(ui->weightGV, ui->weightSB, ui->weightCB, ed->weight, model, 100, -100, 100, 1.0, + dialogFilteredItemModels->getItemModel(id)); + gvOffsetGroup = new GVarGroup(ui->offsetGV, ui->offsetSB, ui->offsetCB, ed->offset, model, 0, -100, 100, 1.0, + dialogFilteredItemModels->getItemModel(id)); curveRefFilteredItemModels = new CurveRefFilteredFactory(sharedItemModels, firmware->getCapability(HasInputDiff) ? 0 : FilteredItemModel::PositiveFilter); diff --git a/companion/src/modeledit/inputs.cpp b/companion/src/modeledit/inputs.cpp index f48d7d916..8636d6335 100644 --- a/companion/src/modeledit/inputs.cpp +++ b/companion/src/modeledit/inputs.cpp @@ -351,6 +351,9 @@ void InputsPanel::expoOpen(QListWidgetItem *item) if (!item) item = ExposlistWidget->currentItem(); + if (item == nullptr) + return; + int idx = item->data(Qt::UserRole).toByteArray().at(0); if (idx < 0) { int ch = -idx - 1; @@ -368,7 +371,11 @@ void InputsPanel::expoOpen(QListWidgetItem *item) void InputsPanel::expoAdd() { - int index = ExposlistWidget->currentItem()->data(Qt::UserRole).toByteArray().at(0); + QListWidgetItem *item = ExposlistWidget->currentItem(); + if (item == nullptr) + return; + + int index = item->data(Qt::UserRole).toByteArray().at(0); if (index < 0) { // if empty then return relevant index expoOpen(); diff --git a/companion/src/modeledit/mixerdialog.cpp b/companion/src/modeledit/mixerdialog.cpp index 645a25274..6cc39ffd1 100644 --- a/companion/src/modeledit/mixerdialog.cpp +++ b/companion/src/modeledit/mixerdialog.cpp @@ -55,9 +55,13 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata, ui->sourceCB->setCurrentIndex(ui->sourceCB->findData(md->srcRaw.toValue())); int limit = firmware->getCapability(OffsetWeight); + id = dialogFilteredItemModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_GVarRef)), "GVarRef"); + + gvWeightGroup = new GVarGroup(ui->weightGV, ui->weightSB, ui->weightCB, md->weight, model, 100, -limit, limit, 1.0, + dialogFilteredItemModels->getItemModel(id)); + gvOffsetGroup = new GVarGroup(ui->offsetGV, ui->offsetSB, ui->offsetCB, md->sOffset, model, 0, -limit, limit, 1.0, + dialogFilteredItemModels->getItemModel(id)); - 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); curveRefFilteredItemModels = new CurveRefFilteredFactory(sharedItemModels, firmware->getCapability(HasMixerExpo) ? 0 : FilteredItemModel::PositiveFilter); curveGroup = new CurveReferenceUIManager(ui->curveTypeCB, ui->curveGVarCB, ui->curveValueSB, ui->curveValueCB, md->curve, model, diff --git a/companion/src/modeledit/mixes.cpp b/companion/src/modeledit/mixes.cpp index 3d95bd04d..023888760 100644 --- a/companion/src/modeledit/mixes.cpp +++ b/companion/src/modeledit/mixes.cpp @@ -354,7 +354,11 @@ void MixesPanel::mixersDuplicate() void MixesPanel::mixerOpen() { - int idx = mixersListWidget->currentItem()->data(Qt::UserRole).toByteArray().at(0); + QListWidgetItem *item = mixersListWidget->currentItem(); + if (item == nullptr) + return; + + int idx = item->data(Qt::UserRole).toByteArray().at(0); if(idx < 0) { int i = -idx; idx = getMixerIndex(i); //get mixer index to insert @@ -371,7 +375,11 @@ void MixesPanel::mixerOpen() void MixesPanel::mixerHighlight() { - int idx = mixersListWidget->currentItem()->data(Qt::UserRole).toByteArray().at(0); + QListWidgetItem *item = mixersListWidget->currentItem(); + if (item == nullptr) + return; + + int idx = item->data(Qt::UserRole).toByteArray().at(0); int dest; if (idx<0) { dest = -idx; diff --git a/companion/src/modeledit/modeledit.cpp b/companion/src/modeledit/modeledit.cpp index 3577be7ae..146bc01f0 100644 --- a/companion/src/modeledit/modeledit.cpp +++ b/companion/src/modeledit/modeledit.cpp @@ -62,6 +62,7 @@ ModelEdit::ModelEdit(QWidget * parent, RadioData & radioData, int modelId, Firmw sharedItemModels->addItemModel(AbstractItemModel::IMID_CustomFuncAction); sharedItemModels->addItemModel(AbstractItemModel::IMID_CustomFuncResetParam); sharedItemModels->addItemModel(AbstractItemModel::IMID_TeleSource); + sharedItemModels->addItemModel(AbstractItemModel::IMID_RssiSource); sharedItemModels->addItemModel(AbstractItemModel::IMID_CurveRefType); sharedItemModels->addItemModel(AbstractItemModel::IMID_CurveRefFunc); diff --git a/companion/src/modeledit/setup.cpp b/companion/src/modeledit/setup.cpp index d1756aa48..b695b03ff 100644 --- a/companion/src/modeledit/setup.cpp +++ b/companion/src/modeledit/setup.cpp @@ -73,7 +73,7 @@ TimerPanel::TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, Ge ui->persistent->addItem(tr("Not persistent"), 0); ui->persistent->addItem(tr("Persistent (flight)"), 1); ui->persistent->addItem(tr("Persistent (manual reset)"), 2); - + ui->countdownStart->setField(timer.countdownStart, this); ui->countdownStart->addItem("5s", 1); ui->countdownStart->addItem("10s", 0); @@ -701,6 +701,7 @@ void ModulePanel::onProtocolChanged(int index) module.protocol = ui->protocol->itemData(index).toInt(); module.channelsCount = module.getMaxChannelCount(); update(); + emit updateItemModels(); emit modified(); } } @@ -801,6 +802,7 @@ void ModulePanel::onMultiProtocolChanged(int index) module.subType = std::min(module.subType, maxSubTypes - 1); module.channelsCount = module.getMaxChannelCount(); update(); + emit updateItemModels(); emit modified(); lock = false; } @@ -1251,6 +1253,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge modules[i] = new ModulePanel(this, model, model.moduleData[i], generalSettings, firmware, i); ui->modulesLayout->addWidget(modules[i]); connect(modules[i], &ModulePanel::modified, this, &SetupPanel::modified); + connect(modules[i], &ModulePanel::updateItemModels, this, &SetupPanel::onModuleUpdateItemModels); connect(this, &SetupPanel::extendedLimitsToggled, modules[i], &ModulePanel::onExtendedLimitsToggled); } @@ -1798,3 +1801,8 @@ void SetupPanel::updateItemModels() { sharedItemModels->update(AbstractItemModel::IMUE_Timers); } + +void SetupPanel::onModuleUpdateItemModels() +{ + sharedItemModels->update(AbstractItemModel::IMUE_Modules); +} diff --git a/companion/src/modeledit/setup.h b/companion/src/modeledit/setup.h index 7a5cddba9..7409d7b25 100644 --- a/companion/src/modeledit/setup.h +++ b/companion/src/modeledit/setup.h @@ -81,6 +81,7 @@ class ModulePanel : public ModelPanel signals: void channelsRangeChanged(); void failsafeModified(unsigned index); + void updateItemModels(); private slots: void setupFailsafes(); @@ -175,6 +176,7 @@ class SetupPanel : public ModelPanel void onTimerNameChanged(); void onItemModelAboutToBeUpdated(); void onItemModelUpdateComplete(); + void onModuleUpdateItemModels(); private: Ui::Setup *ui; diff --git a/companion/src/modeledit/telemetry.cpp b/companion/src/modeledit/telemetry.cpp index 8cda220a9..bb32790b8 100644 --- a/companion/src/modeledit/telemetry.cpp +++ b/companion/src/modeledit/telemetry.cpp @@ -35,6 +35,7 @@ constexpr char FIM_SENSORFORMULA[] {"Sensor.Formula"}; constexpr char FIM_SENSORCELLINDEX[] {"Sensor.CellIndex"}; constexpr char FIM_SENSORUNIT[] {"Sensor.Unit"}; constexpr char FIM_SENSORPRECISION[] {"Sensor.Precision"}; +constexpr char FIM_RSSISOURCE[] {"Rssi Source"}; TelemetryCustomScreen::TelemetryCustomScreen(QWidget *parent, ModelData & model, FrSkyScreenData & screen, GeneralSettings & generalSettings, Firmware * firmware, const bool & parentLock, FilteredItemModelFactory * panelFilteredItemModels): @@ -111,7 +112,7 @@ TelemetryCustomScreen::TelemetryCustomScreen(QWidget *parent, ModelData & model, lock = false; if (IS_TARANIS(firmware->getBoard())) { - QSet scriptsSet = getFilesSet(g.profile[g.id()].sdPath() + "/SCRIPTS/TELEMETRY", QStringList() << "*.lua", 8); + QSet scriptsSet = getFilesSet(g.profile[g.id()].sdPath() + "/SCRIPTS/TELEMETRY", QStringList() << "*.lua", 6); Helpers::populateFileComboBox(ui->scriptName, scriptsSet, screen.body.script.filename); connect(ui->scriptName, SIGNAL(currentIndexChanged(int)), this, SLOT(scriptNameEdited())); connect(ui->scriptName, SIGNAL(editTextChanged ( const QString)), this, SLOT(scriptNameEdited())); @@ -696,6 +697,11 @@ TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettin FIM_TELEPOSSRC); connectItemModelEvents(id); + + id = panelFilteredItemModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RssiSource)), + FIM_RSSISOURCE); + connectItemModelEvents(id); + id = panelItemModels->registerItemModel(SensorData::typeItemModel()); panelFilteredItemModels->registerItemModel(new FilteredItemModel(panelItemModels->getItemModel(id)), FIM_SENSORTYPE); @@ -813,12 +819,14 @@ void TelemetryPanel::setup() ui->ignoreSensorIds->setField(model->frsky.ignoreSensorIds, this); ui->disableTelemetryAlarms->setField(model->rssiAlarms.disabled); + ui->rssiAlarmWarningSB->setRange(45 - 30, 45 + 30); ui->rssiAlarmWarningSB->setValue(model->rssiAlarms.warning); + ui->rssiAlarmCriticalSB->setRange(42 - 30, 42 + 30); ui->rssiAlarmCriticalSB->setValue(model->rssiAlarms.critical); ui->rssiSourceLabel->show(); ui->rssiSourceLabel->setText(tr("Source")); - ui->rssiSourceCB->setModel(panelFilteredItemModels->getItemModel(FIM_TELEPOSSRC)); + ui->rssiSourceCB->setModel(panelFilteredItemModels->getItemModel(FIM_RSSISOURCE)); ui->rssiSourceCB->setField(model->rssiSource, this); ui->rssiSourceCB->show(); diff --git a/companion/src/translations/companion_ja.ts b/companion/src/translations/companion_ja.ts index 2d7d02b4d..d423959d4 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 エルロン @@ -828,44 +828,44 @@ Mode 4: - Channels + ChannelsPanel - + Name 名称 - + Subtrim サブトリム - + Min 最小 - + Max 最大 - + Direction 方向 - + Curve カーブ - + PPM Center PPM センター - + Linear Subtrim 線形サブトリム @@ -890,67 +890,67 @@ Mode 4: リバース - + Delete Channel. Are you sure? チャンネルを削除します。よろしいですか? - + 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? チャンネルをすべて消去します。よろしいですか? @@ -1090,37 +1090,37 @@ Mode 4: 送信機と機体モデルの設定 - + Select or create a file for exported Settings: エクスポートした設定ファイルを選択または作成します: - + Press the 'Retry' button to choose another file. 別のファイルを選択するには『再試行』ボタンを押してください。 - + Simulator for this firmware is not yet available このファームウェアのシミュレータはまだ利用できません - + Uknown error during Simulator startup. シミュレータ起動中に不明なエラーが発生しました。 - + Simulator Error シミュレータ エラー - + Data Load Error データロード エラー - + Error occurred while starting simulator. シミュレータ起動中にエラーが発生しました。 @@ -1376,51 +1376,28 @@ If you have a settings backup file, you may import that instead. - CurveGroup + CurveReference - + Diff 差分 - + Expo エクスポ - + Func 機能 - + Curve カーブ - - CurveReference - - - Diff(%1) - 差分(%1) - - - - Expo(%1) - エクスポ(%1) - - - - Function(%1) - 機能(%1) - - - - Curve(%1) - カーブ(%1) - - Curves @@ -1509,113 +1486,116 @@ If you have a settings backup file, you may import that instead. Point size 点のサイズ + + + CurvesPanel - + Curve %1 カーブ %1 - + Popup menu available 利用可能なポップアップメニュー - + %1 points %1 点 - + Linear 線形 - + Single Expo シングルエクスポ - + Symmetrical f(x)=-f(-x) 対称 f(x)=-f(-x) - + Symmetrical f(x)=f(-x) 対称 f(x)=f(-x) - + Editing curve %1 カーブ %1 編集 - + Not enough free points in EEPROM to store the curve. EEPROMにカーブを保存する十分な空き容量がありません。 - + Copy コピー - + Cut 切り取り - + Paste 貼り付け - + Clear 消去 - + Insert 挿入 - + Delete 削除 - + Move Up 上へ移動 - + Move Down 下へ移動 - + Clear All すべて消去 - + Clear Curve. Are you sure? カーブを消去します。よろしいですか? - + Clear all Curves. Are you sure? カーブをすべて消去します。よろしいですか? - + Cut Curve. Are you sure? カーブを切り取ります。よろしいですか? - + Delete Curve. Are you sure? カーブを削除します。よろしいですか? @@ -1689,8 +1669,13 @@ If you have a settings backup file, you may import that instead. - Set Timer %1 - 設定: タイマー %1 + Set %1 + 設定 %1 + + + + Set Failsafe + フェイルセーフ設定 @@ -1750,75 +1735,50 @@ If you have a settings backup file, you may import that instead. Adjust %1 - アジャスト %1 - - - - SetFailsafe Int. Module - 設定: フェイルセーフ 内部モジュール + 調整 %1 - SetFailsafe Ext. Module - 設定: フェイルセーフ 外部モジュール - - - RangeCheck Int. Module レンジチェック 内部モジュール - + RangeCheck Ext. Module レンジチェック 外部モジュール - + Bind Int. Module バインド 内部モジュール - + Bind Ext. Module バインド 外部モジュール - - Timer1 - タイマー1 - - - - Timer2 - タイマー2 - - - - Timer3 - タイマー3 - - - + Flight フライト - + Telemetry テレメトリー - + Rotary Encoder エンコーダ再生 - + REa エンコーダ再生a - + REb エンコーダ再生b @@ -1855,7 +1815,7 @@ If you have a settings backup file, you may import that instead. 無効 - + CFN CFN @@ -1863,139 +1823,139 @@ If you have a settings backup file, you may import that instead. CustomFunctionsPanel - + Switch スイッチ - + Action 実行 - + Parameters パラメータ - + Enable 有効 - + Popup menu available 利用可能なポップアップメニュー - + SF%1 SF%1 - + GF%1 GF%1 - + ON ON - + Error occurred while trying to play sound, possibly the file is already opened. (Err: %1 [%2]) サウンド再生中にエラーが発生しました。おそらくファイルは既に開かれています (Err: %1 [%2]) - + Unable to find or open sound file: %1 音源ファイルが見つからない、または開けません。 %1 - + 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 すべて消去 - + Value 値 - + Source 選択元 - + GVAR GVAR - + Increment 増加 @@ -2163,48 +2123,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はこの送信機プロトコルを受け付けません @@ -2219,18 +2179,18 @@ If you have a settings backup file, you may import that instead. <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>フィルタを有効または無効にします。ボタンが有効にならない場合は、入力した正規表現に構文エラーがある可能性があります。</p></body></html> + <html><head/><body><p>フィルターを有効または無効にします。ボタンが有効にならない場合は、入力した正規表現に構文エラーがある可能性があります。</p></body></html> Filter: - フィルタ: + フィルター: <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>ここにフィルタテキストを入力してください。フィルタの使用方法の詳細は、help / info ボタンをクリックしてください。</p><p> + <html><head/><body><p>ここにフィルタテキストを入力してください。フィルターの使用方法の詳細は、help / info ボタンをクリックしてください。</p><p> フィルタリストから<b>保存したエントリを削除</b>するには、選択してから<code>Shift+Delete</code> (または<code>Shift+Backspace</code>) キーを押してください。</p></body></html> @@ -2246,12 +2206,12 @@ To <b>remove a remembered entry</b> from the filter list, first cho Filter &Help - フィルタ &ヘルプ + フィルター &ヘルプ Show information about using the filter. - フィルタの使用に関する情報を表示します。 + フィルターの使用に関する情報を表示します。 @@ -2276,22 +2236,22 @@ To <b>remove a remembered entry</b> from the filter list, first cho Enable &Filter - 有効 &フィルタ + 有効 &フィルター Turn the filter on/off. - フィルタをON / OFFします。 + フィルターをON / OFFします。 <html><head><style>kbd {background-color: palette(alternate-base); font-size: large; white-space: nowrap;}</style></head><body><p>The filter supports two syntax types: basic matching with common wildcards as well as full Perl-style (<code>pcre</code>) Regular Expressions.</p><p>By default a filter will only show lines which match (<b>inclusive</b>). To make an <b>exclusive</b> filter which removes matching lines, prefix the filter expression with a <kbd>!</kbd> (exclamation mark).</p><p>To use <b>Regular Expressions</b> (RegEx), prefix the filter text with a <kbd>/</kbd> (slash) or <kbd>^</kbd> (up caret). <ul><li>Put the <kbd>/</kbd> or <kbd>^</kbd> after the exclusive <kbd>!</kbd> indicator if you're using one.</li><li>By default the match is case-sensitive. To make it insensitive, add the typical <kbd>/i</kbd> (slash i) operator at the end of your RegEx.</li><li>If you use a caret (^) to denote a RegEx, it will become part of the Reg. Ex. (that is, matches from start of line).</li><li>If the RegEx is invalid, the filter edit field should show a red border and you will not be able to enable the filter.</li><li>A useful resource for testing REs (with a full reference) can be found at <a href="http://www.regexr.com/">http://www.regexr.com/</a></li></ul></p><p>To use <b>basic matching</b> just type any text.<ul><li>Wildcards: <kbd>*</kbd> (asterisk) matches zero or more of any character(s), and <kbd>?</kbd> (question mark) matches any single character.</li><li>The match is always case-insensitive.</li><li>The match always starts from the beginning of a log line. To ignore characters at the start, use a leading <kbd>*</kbd> wildcard.</li><li>A trailing <kbd>*</kbd> is always implied (that is, matches anything to the end of the log line). To avoid this, use a RegEx.</li><li>You can match literal wildcard characters by prefixing them with a <kbd>\</kbd> (backslash) character (eg. "foo\*bar" matches "foo*bar").</li></ul></p><p>After <b>editing text</b>, press ENTER or TAB key (or click anywhere outside the box) to update the filter.</p><p>To <b>remove an entry</b> from the filter selector list, first choose it, and while in the line editor press <kbd>Shift-Delete</kbd> (or <kbd>Shift-Backspace</kbd>) key combination. The default filters cannot be removed. Up to 50 filters are stored.</p></body></html> - <html><head><style>kbd {background-color: palette(alternate-base); font-size: large; white-space: nowrap;}</style></head><body><p>フィルタは2つのシンタックスタイプをサポートしています: 一般的なワイルドカードを用いた完全一致、そして完全なPerlスタイル (<code>pcre</code>) 正規表現です。初期値ではフィルタは一致する (<b>包括的</b>) な行のみを表示します。一致する行を削除する<b>排他的</b>フィルタを作成するには、フィルタ式の先頭に<kbd>!</kbd>(Exclamationマーク)を付けます。</p><p>To use <b>Regular Expressions</b> (RegEx), prefix the filter text with a <kbd>/</kbd> (slash) or <kbd>^</kbd> (up caret). <b>正規表現</b> (RegEx)を使用するには、フィルタテキストの先頭に<kbd>/</kbd> (スラッシュ) または<kbd>^</kbd>(アップキャレット)を付けます。<ul><li>既に <kbd>/</kbd> または <kbd>^</kbd> を使用している場合は、 <kbd>!</kbd> の後ろに置きます。</li><li>初期値では大文字と小文字が区別されます。それを鈍感にするには、正規表現の最後に典型的な <kbd>/i</kbd> (スラッシュ+i)演算子を追加します。</li> <li> 正規表現を表すためにキャレット『^』を使用すると、それは正規表現の一部になります。例(つまり、行頭から一致します。)</li> <li> 正規表現が無効な場合、フィルタ編集フィールドには赤い枠が表示されフィルタを有効にすることはできません。</li> <li> 正規表現のテストに役立つリソース(参考文献)は、<a href="http://www.regexr.com/"> http://www.regexr.com/にあります。</a></li> </ul></p><p><b>標準一致 basic matching</b> を使用するには、テキストを入力するだけです。<ul><li>ワイルドカード: <kbd>*</kbd> (アスタリスク)は0個以上の任意の文字に一致し、 <kbd>?</kbd> (クエスチョンマーク) は任意の1文字に一致します。</li><li>この一致では常に大文字と小文字が区別されません。</li><li>一致は常にログの先頭行から始まります。 先頭の文字を無視するには、先頭に<kbd>*</kbd>ワイルドカードを使用します。</li><li>末尾の <kbd>*</kbd> は常に暗黙的に指定されます。(つまり、ログ末尾行までが対象) これを回避するには、正規表現を使用します。</li><li>リテラルワイルドカード文字の前に <kbd>\</kbd> (バックスラッシュ) 文字を付けることで一致させることができます。(例: "foo\*bar"は"foo*bar"と一致)</li></ul></p><p><b>テキスト編集</b>後、EnterまたはTabキーを押して (またはボックスの外側をクリックし) フィルタを更新します。</p><p>フィルタセレクタリストから<b>エントリー削除</b>をするには、まずエントリーを選択しエディタで<kbd>Shift+Delete</kbd> (または<kbd>Shift+Backspace</kbd>) を押します。デフォルトのフィルタは削除できません。また最大50個のフィルタが保存されています。</p></body></html> + <html><head><style>kbd {background-color: palette(alternate-base); font-size: large; white-space: nowrap;}</style></head><body><p>フィルターは2つのシンタックスタイプをサポートしています: 一般的なワイルドカードを用いた完全一致、そして完全なPerlスタイル (<code>pcre</code>) 正規表現です。初期値ではフィルターは一致する (<b>包括的</b>) な行のみを表示します。一致する行を削除する<b>排他的</b>フィルターを作成するには、フィルター式の先頭に<kbd>!</kbd>(Exclamationマーク)を付けます。</p><p>To use <b>Regular Expressions</b> (RegEx), prefix the filter text with a <kbd>/</kbd> (slash) or <kbd>^</kbd> (up caret). <b>正規表現</b> (RegEx)を使用するには、フィルターテキストの先頭に<kbd>/</kbd> (スラッシュ) または<kbd>^</kbd>(アップキャレット)を付けます。<ul><li>既に <kbd>/</kbd> または <kbd>^</kbd> を使用している場合は、 <kbd>!</kbd> の後ろに置きます。</li><li>初期値では大文字と小文字が区別されます。それを鈍感にするには、正規表現の最後に典型的な <kbd>/i</kbd> (スラッシュ+i)演算子を追加します。</li> <li> 正規表現を表すためにキャレット『^』を使用すると、それは正規表現の一部になります。例(つまり、行頭から一致します。)</li> <li> 正規表現が無効な場合、フィルター編集フィールドには赤い枠が表示されフィルターを有効にすることはできません。</li> <li> 正規表現のテストに役立つリソース(参考文献)は、<a href="http://www.regexr.com/"> http://www.regexr.com/にあります。</a></li> </ul></p><p><b>標準一致 basic matching</b> を使用するには、テキストを入力するだけです。<ul><li>ワイルドカード: <kbd>*</kbd> (アスタリスク)は0個以上の任意の文字に一致し、 <kbd>?</kbd> (クエスチョンマーク) は任意の1文字に一致します。</li><li>この一致では常に大文字と小文字が区別されません。</li><li>一致は常にログの先頭行から始まります。 先頭の文字を無視するには、先頭に<kbd>*</kbd>ワイルドカードを使用します。</li><li>末尾の <kbd>*</kbd> は常に暗黙的に指定されます。(つまり、ログ末尾行までが対象) これを回避するには、正規表現を使用します。</li><li>リテラルワイルドカード文字の前に <kbd>\</kbd> (バックスラッシュ) 文字を付けることで一致させることができます。(例: "foo\*bar"は"foo*bar"と一致)</li></ul></p><p><b>テキスト編集</b>後、EnterまたはTabキーを押して (またはボックスの外側をクリックし) フィルターを更新します。</p><p>フィルターセレクタリストから<b>エントリー削除</b>をするには、まずエントリーを選択しエディタで<kbd>Shift+Delete</kbd> (または<kbd>Shift+Backspace</kbd>) を押します。デフォルトのフィルターは削除できません。また最大50個のフィルターが保存されています。</p></body></html> Debug Console Filter Help - デバッグコンソールフィルタ ヘルプ + デバッグコンソールフィルター ヘルプ @@ -2536,27 +2496,27 @@ If blank then the input is considered to be "ON" all the time.ミキサー選択元 - + Edit %1 編集 %1 - + Popup menu available 利用可能なポップアップメニュー - + Clear All すべて消去 - + Set All すべて設定 - + Invert All すべてリバース @@ -2925,255 +2885,293 @@ 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+ - - + + 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 - + + + + + + Support hardware mod: R9M ACCESS + ハードウェアモジュールサポート: R9M ACCESS + + + FrSky Horus X12S FrSky Horus X12S - + Use ONLY with first DEV pcb version 初期DEV pcbバージョンでのみ使用 - - + + Support for MULTI internal module MULTI内部モジュールのサポート - - - + + Jumper T-Lite + Jumper T-Lite + + + + + Support for bluetooth module Bluetoothモジュールのサポート - + + Radiomaster TX12 + Radiomaster TX12 + + + + Radiomaster T8 + Radiomaster T8 + + + + Allow bind using bind key + バインドキーを使用したバインドを許可 + + + 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内部モジュール変更のサポート - + Enable resetting values by pressing up and down at the same time 上下に同時に押し、値のリセットを有効にする - + 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 - + Support internal GPS 内蔵GPSサポート - + 9X with Sky9x board 9X Sky9Xボード @@ -3670,88 +3668,88 @@ You are currently using: FlightModePanel - - + + Popup menu available 利用可能なポップアップメニュー - + Trim disabled トリム 無効 - + Own Trim 独自トリム - + Use Trim from Flight mode %1 フライトモードからトリムを使用してください %1 - + Use Trim from Flight mode %1 + Own Trim as an offset フライトモードからトリムを使用してください %1+オフセット独自トリム - + Rotary Encoder %1 ロータリーエンコーダ %1 - + Name 名称 - + Value source 元値 - + Value 値 - + Unit ユニット - + Prec - + Min 最小 - + Max 最大 - + Popup enabled ポップアップ有効 - + GVAR%1 - + 0._ - + 0.0 0.0 @@ -3767,49 +3765,49 @@ You are currently using: - + Copy コピー - + Cut 切り取り - + Paste 貼り付け - + Insert 挿入 - + Delete 削除 - + Move Up 上へ移動 - + Move Down 下へ移動 - + Clear All すべて消去 @@ -3819,63 +3817,63 @@ You are currently using: フライトモードを消去します。よろしいですか? - + Clear all Flight Modes. Are you sure? フライトモードをすべて消去します。よろしいですか? - + Cut Flight Mode. Are you sure? フライトモードを切り取ります。よろしいですか? - + Delete Flight Mode. 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 消去 @@ -3883,17 +3881,17 @@ You are currently using: FlightModesPanel - + Flight Mode %1 フライトモード %1 - + (%1) (%1) - + (default) (初期値) @@ -4133,12 +4131,12 @@ p, li { white-space: pre-wrap; } - + Own value 独自トリム - + Flight mode %1 value フライトモード %1 値 @@ -4168,52 +4166,52 @@ These will be relevant for all models in the same EEPROM. これらは同じEEPROM内のすべてのモデルに関連します。 - + Setup セットアップ - + 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パラメータが保存されました。 @@ -4221,7 +4219,7 @@ These will be relevant for all models in the same EEPROM. GeneralSettings - + Radio Settings 送信機設定 @@ -4306,7 +4304,7 @@ These will be relevant for all models in the same EEPROM. Adjust RTC - 時計調整 + 内蔵時計調整 @@ -4823,7 +4821,7 @@ Acceptable values are 5v..10v Low EEPROM Warning - EEPROM残量警告 + EEPROM 残量警告 @@ -5262,252 +5260,257 @@ Are you sure ? フォーム - + SQ SQ - + SR SR - + LS2 LS2 - + SP SP - + SO SO - + S4 S4 - + RS RS - + SB SB - + PPM 2 PPM 2 - + Antenna アンテナ - + S5 S5 - + OFF OFF - + S-Port Mirror S-Port ミラー - + Telemetry テレメトリー - + SBUS Trainer SBUS トレーナー - + Debug デバッグ - + RTC Batt Check - RTC Battチェック + 内蔵電池チェック - + + S.Port Power + S.Port 出力 + + + Rud ラダー - + PPM 3 PPM 3 - + S1 S1 - + S2 S2 - + S3 S3 - + PPM 1 PPM 1 - + Serial Port シリアルポート - + v v - + PPM Multiplier PPM 乗算 - + Current Offset 現在のオフセット - + PPM 4 PPM 4 - + SA SA - + Ele エレベーター - + Ail エルロン - + Thr スロットル - + SC SC - + LS LS - + SD SD - + Battery Offset バッテリーオフセット - + SE SE - + SF SF - + SG SG - + SH SH - + SI SI - + SJ SJ - + SK SK - + SL SL - + SM SM - + SN SN - + RS2 RS2 - + Bluetooth Bluetooth - + ADC Filter - ADCフィルタ + ADCフィルター - + Device Name: デバイス名: @@ -5516,8 +5519,8 @@ Are you sure ? HardwarePanel - - + + None なし @@ -5537,67 +5540,67 @@ Are you sure ? 3 ポジション - + Pot with detent ダイヤル (ノッチあり) - + Multipos switch マルチPosスイッチ - + Pot without detent ダイヤル (ノッチなし) - + Slider with detent スライダー (ノッチあり) - + OFF OFF - + Enabled 有効 - + Telemetry テレメトリー - + Trainer トレーナー - + Internal 内部 - + Ask 確認 - + Per model Per モデル - + Internal + External 内部 + 外部 - + External 外部 @@ -5723,159 +5726,159 @@ Are you sure ? InputsPanel - - - + + + Move Up 上へ移動 - - + + Ctrl+Up - - - + + + Move Down 下へ移動 - - + + Ctrl+Down - + Clear All Inputs すべての入力項目を消去 - + Not enough available Inputs! 入力項目が不足しています! - + Delete selected Input lines. Are you sure? 選択したInput行を削除します。よろしいですか? - + Cut selected Input lines. Are you sure? 選択したInput行を切り取ります。よろしいですか? - + Lines 直線 - + &Add &追加 - + Ctrl+A - + &Edit &編集 - + Enter Enter - + &Delete &削除 - - + + Delete 削除 - + &Copy &コピー - + Ctrl+C - + &Cut &切り取り - + Ctrl+X - + &Paste &貼り付け - + Ctrl+V - + Du&plicate &複製 - + Ctrl+U - + Input 入力 - + Insert 挿入 - + Clear 消去 - + Clear All すべて消去 - + Clear all Input lines. Are you sure? すべてのInput行を消去します。よろしいですか? - + Clear all lines for the selected Inputs. Are you sure? 選択したすべてのInput行を消去します。よろしいですか? - + Delete all lines for the selected Inputs. Are you sure? 選択したすべてのInput行を削除します。よろしいですか? @@ -5901,7 +5904,7 @@ Are you sure ? LimitsGroup - + GV @@ -6032,112 +6035,112 @@ Are you sure ? LogicalSwitchesPanel - + Function 機能 - + V1 - + V2 - + AND Switch & スイッチ - + Duration 期間 - + Delay 遅延 - + Popup menu available 利用可能なポップアップメニュー - + (instant) (瞬間) - + (infinite) (無制限) - + 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? 論理スイッチをすべて消去します。よろしいですか? @@ -7872,27 +7875,27 @@ If blank then the mix is considered to be "ON" all the time. 空白の場合、ミックスは常に『オン』と見なします。 - + DEST -> %1 - + Click to access popup menu クリックしてポップアップメニューにアクセス - + Clear All すべて消去 - + Set All すべて設定 - + Invert All すべてリバース @@ -7923,136 +7926,136 @@ If blank then the mix is considered to be "ON" all the time. MixesPanel - - + + Move Up 上へ移動 - - + + Ctrl+Up - - + + Move Down 下へ移動 - - + + Ctrl+Down - + Clear Mixes ミキサーを消去 - + Not enough available mixers! ミキサー項目が足りません! - + 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? すべてのミキサーを本当に消去しますか? @@ -8069,6 +8072,11 @@ If blank then the mix is considered to be "ON" all the time. Throttle Source スロットル値 + + + THR + THR + ModelEdit @@ -8083,52 +8091,52 @@ If blank then the mix is considered to be "ON" all the time. シミュレート - + Setup セットアップ - + Heli ヘリ - + Flight Modes フライトモード - + Inputs 入力 - + Mixes ミキサー - + Outputs 出力 - + Curves カーブ - + Logical Switches 論理スイッチ - + Special Functions スペシャルファンクション - + Telemetry テレメトリー @@ -8183,8 +8191,8 @@ If blank then the mix is considered to be "ON" all the time. - - + + OFF OFF @@ -8225,7 +8233,7 @@ If blank then the mix is considered to be "ON" all the time. - + Mode モード @@ -8259,14 +8267,13 @@ If blank then the mix is considered to be "ON" all the time. - - + Delay 遅延 - + Receiver 受信機 @@ -8358,11 +8365,10 @@ If blank then the mix is considered to be "ON" all the time. - - - - - + + + + None なし @@ -8403,528 +8409,353 @@ If blank then the mix is considered to be "ON" all the time. FM%1+%2 - - - - Weight - ウェイト - - - - - Switch - スイッチ - - + NoTrim トリムなし + Offset(%1) オフセット(%1) - + MULT! 複数! - + No DR/Expo DR/Expoなし - - - Offset - オフセット + + + Weight(%1) + ウェイト(%1) - - Slow - ゆっくり + + + Switch(%1) + スイッチ(%1) - - Warn - 警告 + + Delay(u%1:d%2) + 遅延(u%1:d%2) - + + Slow(u%1:d%2) + 速度低下(u%1:d%2) + + + + Warn(%1) + 警告(%1) + + + 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! エラー: ファイルを開けないか、読み取れません! @@ -9019,7 +8850,7 @@ If blank then the mix is considered to be "ON" all the time. Low Power - 低パワー + 低出力 @@ -9320,12 +9151,12 @@ If blank then the mix is considered to be "ON" all the time. 2 W - + Positive ノーマル - + Negative リバース @@ -9333,42 +9164,42 @@ If blank then the mix is considered to be "ON" all the time. ModulePanel - + Value 値 - + Hold ホールド - + No Pulse パルスなし - + Ask 確認 - + Internal 内部 - + Internal + External 内部 + 外部 - + External 外部 - + Bind on channel チャンネルへバインド @@ -9844,22 +9675,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 を書き込めません @@ -10007,12 +9838,12 @@ If blank then the mix is considered to be "ON" all the time. QObject - + WARNING 警告 - + <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>JumperTXデータをOpenTX 2.3にインポートすることは<b>サポート対象外となり危険な行為です。</b></p> <p>残念ながら、JumperTXデータを正当なFrSky X10データと区別することができませんが、<b>開いたファイルが実際のFrSky X10で生成されたものである場合にのみ、続行する事ができます。</b></p> <p>本当に続行しますか?</p> @@ -10367,17 +10198,6 @@ X REb エンコーダ再生b - - - - ??? - - - - - ---- - - I @@ -10406,7 +10226,7 @@ X - + SRC @@ -10414,22 +10234,22 @@ X RawSwitch - + ↑ - + ↓ - + - - + ! @@ -10654,146 +10474,327 @@ X SensorData - - + + Formula + 定式 + + + + Id + ID + + + + Instance + インスタンス + + + + + Sensor + センサー + + + + Sources + 選択元 + + + + GPS + GPS + + + + Alt + 高度 + + + + Unit + ユニット + + + + Precision + 精度 + + + + Ratio + レシオ + + + + Offset + オフセット + + + + Auto Offset + 自動オフセット + + + + Blades + ブレード + + + + Multiplier + 乗算 + + + + Filter + フィルター + + + + Persist + 持続 + + + + Positive + ノーマル + + + + Log + ログ + + + + Custom + カスタム + + + + Calculated + 計算値 + + + + Add + 追加 + + + + Average + 平均 + + + + Minimum + 最低値 + + + + Maximum + 最大値 + + + + Multiply + 乗算 + + + + Totalize + 合計 + + + + Cell + セル + + + + Consumption + 消費 + + + + Distance + 距離 + + + + Lowest + より低く + + + + Cell %1 + セル %1 + + + + Highest + より高く + + + + Delta + 差分 + + + + Raw (-) + Raw (-) + + + + V V - + A - + mA - + kts - + m/s - + km/h - + mph - + m - + f - + °C - + °F - + % - + mAh - + W - + mW - + dB - + rpms - + g - + ° - + Rad - + hours - + minutes - + seconds - + ml/minute - + Hertz - + mS - + uS - + TELE + + + Y + Y + + + + N + N + Setup @@ -10975,92 +10976,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? タイマーを削除します。よろしいですか? @@ -11786,62 +11787,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) @@ -12514,22 +12515,22 @@ Too many errors, giving up. 最大 - + None なし - + Numbers ナンバー - + Bars バー - + Script スクリプト @@ -12537,109 +12538,52 @@ 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? テレメトリーセンサーを削除します。よろしいですか? @@ -12657,279 +12601,99 @@ Too many errors, giving up. TELE## - - Custom - カスタム - - - - Calculated - 計算値 - - - + Id ID - + Instance インスタンス - + Rx 受信 - - Add - 追加 - - - - Average - 平均 - - - - Min - 最小 - - - - Max - 最大 - - - - Multiply - 乗算 - - - - Totalize - 合計 - - - - Cell - セル - - - - Consumption - 消費 - - - - Dist - 距離 - - - + Cells Sensor : セル センサー : - - - - - - - - + + + + + + + + --- --- - + GPS Sensor : GPS センサー : - + Alt. Sensor : 高度 センサー : - + Sensor : センサー : - - Raw (-) - Raw (-) - - - - V - V - - - - A - - - - - mA - - - - - kt - - - - - m/s - - - - - ft/s - - - - - km/h - - - - - mph - - - - - m - 分 - - - - ft - - - - - °C - - - - - °F - - - - - % - - - - - mAh - - - - - W - - - - - mW - - - - - dBm - - - - - RPM - - - - - g - - - - - ° - - - - - Rad - - - - - mL - - - - - US fl.Oz. - - - - - ml/min - - - - + Precision 精度 - + Ratio レシオ - + Blades ブレード - + Offset オフセット - + Multiplier 乗算 - + Auto Offset 自動オフセット - + Filter - フィルタ + フィルター - + Persistent 持続 - + Positive ノーマル - + Logs ログ @@ -12937,92 +12701,72 @@ 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? テレメトリーセンサーのすべてを消去します。よろしいですか? @@ -13391,12 +13135,12 @@ hh:mm:ss Timer - + Countdown カウントダウン - + Minute Call 音声時報 @@ -13857,7 +13601,7 @@ CTRL+スクロールまたはPAGE UP/DOWNキーを押すと、大きなステ Has your helicopter got an adjustable gyro for the tail? - このヘリコプターはテールのアジャストジャイロを実装しましたか? + このヘリコプターはテールのジャイロ調整を実装しましたか? diff --git a/radio/src/audio.cpp b/radio/src/audio.cpp index 702ec044e..04ff8a8b2 100644 --- a/radio/src/audio.cpp +++ b/radio/src/audio.cpp @@ -161,7 +161,7 @@ const char * const unitsFilenames[] = { "hertz", "ms", "us", - "spare4", + "km", "spare5", "spare6", "spare7", diff --git a/radio/src/cli.cpp b/radio/src/cli.cpp index cb72b8076..8d64e7972 100644 --- a/radio/src/cli.cpp +++ b/radio/src/cli.cpp @@ -699,11 +699,11 @@ int cliTrace(const char ** argv) int cliStackInfo(const char ** argv) { - serialPrint("[MAIN] %d available / %d", stackAvailable(), stackSize()); - serialPrint("[MENUS] %d available / %d", menusStack.available(), menusStack.size()); - serialPrint("[MIXER] %d available / %d", mixerStack.available(), mixerStack.size()); - serialPrint("[AUDIO] %d available / %d", audioStack.available(), audioStack.size()); - serialPrint("[CLI] %d available / %d", cliStack.available(), cliStack.size()); + serialPrint("[MAIN] %d available / %d bytes", stackAvailable()*4, stackSize()*4); + serialPrint("[MENUS] %d available / %d bytes", menusStack.available()*4, menusStack.size()); + serialPrint("[MIXER] %d available / %d bytes", mixerStack.available()*4, mixerStack.size()); + serialPrint("[AUDIO] %d available / %d bytes", audioStack.available()*4, audioStack.size()); + serialPrint("[CLI] %d available / %d bytes", cliStack.available()*4, cliStack.size()); return 0; } diff --git a/radio/src/dataconstants.h b/radio/src/dataconstants.h index dae853d12..b7ab6ebea 100644 --- a/radio/src/dataconstants.h +++ b/radio/src/dataconstants.h @@ -278,6 +278,7 @@ enum TelemetryProtocol PROTOCOL_TELEMETRY_FLYSKY_IBUS, PROTOCOL_TELEMETRY_HITEC, PROTOCOL_TELEMETRY_HOTT, + PROTOCOL_TELEMETRY_MLINK, PROTOCOL_TELEMETRY_MULTIMODULE, PROTOCOL_TELEMETRY_AFHDS3, PROTOCOL_TELEMETRY_GHOST, @@ -318,8 +319,8 @@ enum TelemetryUnit { UNIT_HERTZ, UNIT_MS, UNIT_US, - UNIT_MAX = UNIT_US, - UNIT_SPARE4, + UNIT_KM, + UNIT_MAX = UNIT_KM, UNIT_SPARE5, UNIT_SPARE6, UNIT_SPARE7, diff --git a/radio/src/gui/128x64/model_setup.cpp b/radio/src/gui/128x64/model_setup.cpp index 136ab6801..77ce40c42 100644 --- a/radio/src/gui/128x64/model_setup.cpp +++ b/radio/src/gui/128x64/model_setup.cpp @@ -1538,40 +1538,35 @@ void menuModelSetup(event_t event) { #if defined(MULTIMODULE) if (MULTIMODULE_PROTOCOL_KNOWN(moduleIdx)) { + const char * title = getMultiOptionTitle(moduleIdx); + + lcdDrawText(INDENT_WIDTH, y, title); + if (title == STR_MULTI_RFTUNE) { + lcdDrawText(MODEL_SETUP_2ND_COLUMN + 23, y, "RSSI(", LEFT); + lcdDrawNumber(lcdLastRightPos, y, TELEMETRY_RSSI(), LEFT); + lcdDrawText(lcdLastRightPos, y, ")", LEFT); + } + int optionValue = g_model.moduleData[moduleIdx].multi.optionValue; - - MultiModuleStatus &status = getMultiModuleStatus(moduleIdx); const uint8_t multi_proto = g_model.moduleData[moduleIdx].getMultiProtocol(); - - if (status.isValid()) { - MultiModuleStatus &status = getMultiModuleStatus(moduleIdx); - lcdDrawText(INDENT_WIDTH, y, mm_options_strings::options[status.optionDisp]); - if (attr && status.optionDisp == 2) { - lcdDrawText(MODEL_SETUP_2ND_COLUMN + 23, y, "RSSI(", LEFT); - lcdDrawNumber(lcdLastRightPos, y, TELEMETRY_RSSI(), LEFT); - lcdDrawText(lcdLastRightPos, y, ")", LEFT); - } - } - else { - const mm_protocol_definition * pdef = getMultiProtocolDefinition(multi_proto); - if (pdef->optionsstr) { - lcdDrawText(INDENT_WIDTH, y, pdef->optionsstr); - if (attr && pdef->optionsstr == STR_MULTI_RFTUNE) { - lcdDrawText(MODEL_SETUP_2ND_COLUMN + 23, y, "RSSI(", LEFT); - lcdDrawNumber(lcdLastRightPos, y, TELEMETRY_RSSI(), LEFT); - lcdDrawText(lcdLastRightPos, y, ")", LEFT); - } - } - } - int8_t min, max; getMultiOptionValues(multi_proto, min, max); - if (multi_proto == MODULE_SUBTYPE_MULTI_FS_AFHDS2A) { + if (title == STR_MULTI_RFPOWER) { + lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_POWER, optionValue, LEFT | attr); + min = 0; + max = 15; + } + else if (title == STR_MULTI_TELEMETRY) { + lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_TELEMETRY_MODE, optionValue, LEFT | attr); + } + else if (multi_proto == MODULE_SUBTYPE_MULTI_FS_AFHDS2A) { lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, 50 + 5 * optionValue, LEFT | attr); } - else if (multi_proto == MODULE_SUBTYPE_MULTI_FRSKY_R9) { - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_POWER, optionValue, LEFT | attr); + else if (title == STR_MULTI_WBUS) { + lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_WBUS_MODE, optionValue, LEFT | attr); + min = 0; + max = 1; } else if (multi_proto == MODULE_SUBTYPE_MULTI_DSM2) { optionValue = optionValue & 0x01; diff --git a/radio/src/gui/212x64/model_setup.cpp b/radio/src/gui/212x64/model_setup.cpp index 5a2d05446..47796ac79 100644 --- a/radio/src/gui/212x64/model_setup.cpp +++ b/radio/src/gui/212x64/model_setup.cpp @@ -1294,38 +1294,34 @@ void menuModelSetup(event_t event) #if defined(MULTIMODULE) if (MULTIMODULE_PROTOCOL_KNOWN(moduleIdx)) { + const char * title = getMultiOptionTitle(moduleIdx); + + lcdDrawText(INDENT_WIDTH, y, title); + if (title == STR_MULTI_RFTUNE) { + lcdDrawText(MODEL_SETUP_2ND_COLUMN + 23, y, "RSSI(", LEFT); + lcdDrawNumber(lcdLastRightPos, y, TELEMETRY_RSSI(), LEFT); + lcdDrawText(lcdLastRightPos, y, ")", LEFT); + } + int optionValue = g_model.moduleData[moduleIdx].multi.optionValue; - - MultiModuleStatus &status = getMultiModuleStatus(moduleIdx); - const uint8_t multi_proto = g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(); - if (status.isValid()) { - lcdDrawText(INDENT_WIDTH, y, mm_options_strings::options[status.optionDisp]); - if (attr && status.optionDisp == 2) { - lcdDrawText(MODEL_SETUP_3RD_COLUMN+22, y, "RSSI(", LEFT); - lcdDrawNumber(lcdLastRightPos, y, TELEMETRY_RSSI(), LEFT); - lcdDrawText(lcdLastRightPos, y, ")", LEFT); - } - } - else { - const mm_protocol_definition * pdef = getMultiProtocolDefinition(multi_proto); - if (pdef->optionsstr) - lcdDrawText(INDENT_WIDTH, y, pdef->optionsstr); - if (pdef->optionsstr == STR_MULTI_RFTUNE) { - lcdDrawText(MODEL_SETUP_3RD_COLUMN+22, y, "RSSI(", LEFT); - lcdDrawNumber(lcdLastRightPos, y, TELEMETRY_RSSI(), LEFT); - lcdDrawText(lcdLastRightPos, y, ")", LEFT); - } - } - + const uint8_t multi_proto = g_model.moduleData[moduleIdx].getMultiProtocol(); int8_t min, max; getMultiOptionValues(multi_proto, min, max); - if (multi_proto == MODULE_SUBTYPE_MULTI_FS_AFHDS2A) { - lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, 50 + 5 * optionValue, LEFT | attr); - } - else if (multi_proto == MODULE_SUBTYPE_MULTI_FRSKY_R9) { + if (title == STR_MULTI_RFPOWER) { lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_POWER, optionValue, LEFT | attr); } + else if (title == STR_MULTI_TELEMETRY) { + lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_TELEMETRY_MODE, optionValue, LEFT | attr); + } + else if (title == STR_MULTI_WBUS) { + lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_WBUS_MODE, optionValue, LEFT | attr); + min = 0; + max = 1; + } + else if (multi_proto == MODULE_SUBTYPE_MULTI_FS_AFHDS2A) { + lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, 50 + 5 * optionValue, LEFT | attr); + } else if (multi_proto == MODULE_SUBTYPE_MULTI_DSM2) { optionValue = optionValue & 0x01; editCheckBox(optionValue, MODEL_SETUP_2ND_COLUMN, y, "", LEFT | attr, event); diff --git a/radio/src/gui/480x272/model_setup.cpp b/radio/src/gui/480x272/model_setup.cpp index cd9974ac5..895b406da 100644 --- a/radio/src/gui/480x272/model_setup.cpp +++ b/radio/src/gui/480x272/model_setup.cpp @@ -1676,34 +1676,33 @@ bool menuModelSetup(event_t event) { #if defined(MULTIMODULE) if (MULTIMODULE_PROTOCOL_KNOWN(moduleIdx)) { + const char * title = getMultiOptionTitle(moduleIdx); + + lcdDrawText(MENUS_MARGIN_LEFT + INDENT_WIDTH, y, title); + if (title == STR_MULTI_RFTUNE) { + lcdDrawNumber(LCD_W - 10, y, TELEMETRY_RSSI(), RIGHT, 0, "RSSI(", ")"); + } + int optionValue = g_model.moduleData[moduleIdx].multi.optionValue; - - MultiModuleStatus &status = getMultiModuleStatus(moduleIdx); const uint8_t multi_proto = g_model.moduleData[moduleIdx].getMultiProtocol(); - if (status.isValid()) { - lcdDrawText(MENUS_MARGIN_LEFT + INDENT_WIDTH, y, mm_options_strings::options[status.optionDisp]); - if (attr && status.optionDisp == 2) { - lcdDrawNumber(LCD_W - 10, y, TELEMETRY_RSSI(), RIGHT, 0, "RSSI(", ")"); - } - } - else { - const mm_protocol_definition * pdef = getMultiProtocolDefinition(multi_proto); - if (pdef->optionsstr) { - lcdDrawText(MENUS_MARGIN_LEFT + INDENT_WIDTH, y, pdef->optionsstr); - if (attr && pdef->optionsstr == STR_MULTI_RFTUNE) { - lcdDrawNumber(LCD_W - 10, y, TELEMETRY_RSSI(), RIGHT, 0, "RSSI(", ")"); - } - } - } - int8_t min, max; getMultiOptionValues(multi_proto, min, max); - if (multi_proto == MODULE_SUBTYPE_MULTI_FS_AFHDS2A) { - lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, 50 + 5 * optionValue, LEFT | attr); - } - else if (multi_proto == MODULE_SUBTYPE_MULTI_FRSKY_R9) { + if (title == STR_MULTI_RFPOWER) { lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_POWER, optionValue, LEFT | attr); + min = 0; + max = 15; + } + else if (title == STR_MULTI_TELEMETRY) { + lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_TELEMETRY_MODE, optionValue, LEFT | attr); + } + else if (title == STR_MULTI_WBUS) { + lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_MULTI_WBUS_MODE, optionValue, LEFT | attr); + min = 0; + max = 1; + } + else if (multi_proto == MODULE_SUBTYPE_MULTI_FS_AFHDS2A) { + lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, 50 + 5 * optionValue, LEFT | attr); } else if (multi_proto == MODULE_SUBTYPE_MULTI_DSM2) { optionValue = optionValue & 0x01; @@ -1715,6 +1714,7 @@ bool menuModelSetup(event_t event) else lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, optionValue, LEFT | attr); } + if (attr) { CHECK_INCDEC_MODELVAR(event, optionValue, min, max); if (checkIncDec_Ret) { diff --git a/radio/src/gui/gui_common.cpp b/radio/src/gui/gui_common.cpp index 368aac163..1bd84b21e 100644 --- a/radio/src/gui/gui_common.cpp +++ b/radio/src/gui/gui_common.cpp @@ -994,9 +994,15 @@ const char* mm_options_strings::options[] = { STR_MULTI_SERVOFREQ, STR_MULTI_MAX_THROW, STR_MULTI_RFCHAN, - STR_MULTI_RFPOWER + STR_MULTI_RFPOWER, + STR_MULTI_WBUS }; +const uint8_t getMaxMultiOptions() +{ + return DIM(mm_options_strings::options); +} + const mm_protocol_definition multi_protocols[] = { // Protocol as defined in pulses\modules_constants.h, number of sub_protocols - 1, Failsafe supported, Disable channel mapping supported, Subtype string, Option type {MODULE_SUBTYPE_MULTI_FLYSKY, 4, false, true, STR_SUBTYPE_FLYSKY, nullptr}, @@ -1091,3 +1097,22 @@ void editStickHardwareSettings(coord_t x, coord_t y, int idx, event_t event, Lcd else lcdDrawMMM(x, y, flags); } + +#if defined(MULTIMODULE) +const char * getMultiOptionTitle(uint8_t moduleIdx) +{ + MultiModuleStatus &status = getMultiModuleStatus(moduleIdx); + + if (status.isValid()) { + if (status.optionDisp >= getMaxMultiOptions()) { + status.optionDisp = 1; // Unknown options are defaulted to type 1 (basic option) + } + return mm_options_strings::options[status.optionDisp]; + } + else { + const uint8_t multi_proto = g_model.moduleData[moduleIdx].getMultiProtocol(); + const mm_protocol_definition * pdef = getMultiProtocolDefinition(multi_proto); + return pdef->optionsstr; + } +} +#endif diff --git a/radio/src/gui/gui_common.h b/radio/src/gui/gui_common.h index 1cda013af..b7d73d075 100644 --- a/radio/src/gui/gui_common.h +++ b/radio/src/gui/gui_common.h @@ -319,6 +319,7 @@ inline uint8_t MODULE_OPTION_ROW(uint8_t moduleIdx) { } void editStickHardwareSettings(coord_t x, coord_t y, int idx, event_t event, LcdFlags flags); +const char * getMultiOptionTitle(uint8_t moduleIdx); const char * writeScreenshot(); diff --git a/radio/src/lua/api_general.cpp b/radio/src/lua/api_general.cpp index b205b1c70..3c6f20d42 100644 --- a/radio/src/lua/api_general.cpp +++ b/radio/src/lua/api_general.cpp @@ -1411,7 +1411,10 @@ Get RSSI value as well as low and critical RSSI alarm levels (in dB) */ static int luaGetRSSI(lua_State * L) { - lua_pushunsigned(L, min((uint8_t)99, TELEMETRY_RSSI())); + if (TELEMETRY_STREAMING()) + lua_pushunsigned(L, min((uint8_t)99, TELEMETRY_RSSI())); + else + lua_pushunsigned(L, 0); lua_pushunsigned(L, g_model.rssiAlarms.getWarningRssi()); lua_pushunsigned(L, g_model.rssiAlarms.getCriticalRssi()); return 3; @@ -2038,6 +2041,7 @@ const luaR_value_entry opentxConstants[] = { {"UNIT_KMH", UNIT_KMH }, {"UNIT_MPH", UNIT_MPH }, {"UNIT_METERS", UNIT_METERS }, + {"UNIT_KM", UNIT_KM }, {"UNIT_FEET", UNIT_FEET }, {"UNIT_CELSIUS", UNIT_CELSIUS }, {"UNIT_FAHRENHEIT", UNIT_FAHRENHEIT }, diff --git a/radio/src/pulses/modules_helpers.h b/radio/src/pulses/modules_helpers.h index 0272a3825..b2bd77de4 100644 --- a/radio/src/pulses/modules_helpers.h +++ b/radio/src/pulses/modules_helpers.h @@ -42,6 +42,8 @@ struct mm_options_strings { static const char* options[]; }; +const uint8_t getMaxMultiOptions(); + struct mm_protocol_definition { uint8_t protocol; uint8_t maxSubtype; @@ -671,10 +673,6 @@ inline void getMultiOptionValues(int8_t multi_proto, int8_t & min, int8_t & max) min = -1; max = 84; break; - case MODULE_SUBTYPE_MULTI_FRSKY_R9: - min = 0; // 10mW - max = 5; // 300mW - break; default: min = -128; max = 127; diff --git a/radio/src/rtos.h b/radio/src/rtos.h index a5dbd11b9..f9f112399 100644 --- a/radio/src/rtos.h +++ b/radio/src/rtos.h @@ -168,7 +168,7 @@ template } #endif - #define RTOS_MS_PER_TICK ((CFG_CPU_FREQ / CFG_SYSTICK_FREQ) / (CFG_CPU_FREQ / 1000)) // RTOS timer tick length in ms (currently 2) + #define RTOS_MS_PER_TICK (1000 / CFG_SYSTICK_FREQ) // RTOS timer tick length in ms (currently 1 for STM32, 2 for others) typedef OS_TID RTOS_TASK_HANDLE; typedef OS_MutexID RTOS_MUTEX_HANDLE; diff --git a/radio/src/targets/common/arm/CMakeLists.txt b/radio/src/targets/common/arm/CMakeLists.txt index 16169ff24..e725bc68c 100644 --- a/radio/src/targets/common/arm/CMakeLists.txt +++ b/radio/src/targets/common/arm/CMakeLists.txt @@ -148,7 +148,7 @@ endif() if(MULTIMODULE) add_definitions(-DMULTIMODULE) - set(SRC ${SRC} pulses/multi.cpp telemetry/spektrum.cpp telemetry/hitec.cpp telemetry/hott.cpp telemetry/multi.cpp io/multi_firmware_update.cpp) + set(SRC ${SRC} pulses/multi.cpp telemetry/spektrum.cpp telemetry/hitec.cpp telemetry/hott.cpp telemetry/mlink.cpp telemetry/multi.cpp io/multi_firmware_update.cpp) endif() if(CROSSFIRE) diff --git a/radio/src/targets/horus/hal.h b/radio/src/targets/horus/hal.h index 74eeb5e2b..22a646a2d 100644 --- a/radio/src/targets/horus/hal.h +++ b/radio/src/targets/horus/hal.h @@ -420,9 +420,9 @@ #define AUX_SERIAL_USART_IRQn USART3_IRQn #define AUX_SERIAL_DMA_Stream_RX DMA1_Stream1 #define AUX_SERIAL_DMA_Channel_RX DMA_Channel_4 - #define AUX_SERIAL_PWR_GPIO GPIOA - #define AUX_SERIAL_PWR_GPIO_PIN GPIO_Pin_15 // PB.00 #if defined(RADIO_TX16S) + #define AUX_SERIAL_PWR_GPIO GPIOA + #define AUX_SERIAL_PWR_GPIO_PIN GPIO_Pin_15 // PA.15 #define TRAINER_BATTERY_COMPARTMENT // allows serial port TTL trainer #endif #else diff --git a/radio/src/targets/horus/lcd_driver.cpp b/radio/src/targets/horus/lcd_driver.cpp index 751aa88cd..97ecc5a61 100644 --- a/radio/src/targets/horus/lcd_driver.cpp +++ b/radio/src/targets/horus/lcd_driver.cpp @@ -141,29 +141,19 @@ static void LCD_NRSTConfig(void) GPIO_Init(LCD_GPIO_NRST, &GPIO_InitStructure); } -// TODO delay function -static void delay3(uint32_t nCount) -{ - uint32_t index = 0; - for(index = (1000 * 100 * nCount); index != 0; --index) - { - __asm("nop\n"); - } -} - static void lcd_reset(void) { #if defined(RADIO_T18) // T18 screen has issues if NRST is ever brought low NRST_HIGH(); #else NRST_HIGH(); - delay3(1); + delay_ms(1); NRST_LOW(); // RESET(); - delay3(20); + delay_ms(20); NRST_HIGH(); - delay3(30); + delay_ms(30); #endif } diff --git a/radio/src/telemetry/ghost.cpp b/radio/src/telemetry/ghost.cpp index 1a3cef9d4..8b949b69a 100755 --- a/radio/src/telemetry/ghost.cpp +++ b/radio/src/telemetry/ghost.cpp @@ -43,12 +43,19 @@ enum GHOST_ID_TOTAL_LATENCY = 0x0007, // Tx-side total latency GHOST_ID_VTX_FREQ = 0x0008, // Vtx Frequency (in MHz) GHOST_ID_VTX_POWER = 0x0009, // Vtx Power (in mW) - GHOST_ID_VTX_CHAN = 0x000a, // Vtx Channel - GHOST_ID_VTX_BAND = 0x000b, // Vtx Band + GHOST_ID_VTX_CHAN = 0x000A, // Vtx Channel + GHOST_ID_VTX_BAND = 0x000B, // Vtx Band - GHOST_ID_PACK_VOLTS = 0x000c, // Battery Pack Voltage - GHOST_ID_PACK_AMPS = 0x000d, // Battery Pack Current - GHOST_ID_PACK_MAH = 0x000e, // Battery Pack mAh consumed + GHOST_ID_PACK_VOLTS = 0x000C, // Battery Pack Voltage + GHOST_ID_PACK_AMPS = 0x000D, // Battery Pack Current + GHOST_ID_PACK_MAH = 0x000E, // Battery Pack mAh consumed + + GHOST_ID_GPS_LAT = 0x000F, // GPS Latitude + GHOST_ID_GPS_LONG = 0x0010, // GPS Longitude + GHOST_ID_GPS_ALT = 0x0011, // GPS Altitude + GHOST_ID_GPS_HDG = 0x0012, // GPS Heading + GHOST_ID_GPS_GSPD = 0x0013, // GPS Ground Speed + GHOST_ID_GPS_SATS = 0x0014 // GPS Satellite Count }; const GhostSensor ghostSensors[] = { @@ -70,6 +77,13 @@ const GhostSensor ghostSensors[] = { {GHOST_ID_PACK_AMPS, ZSTR_CURR, UNIT_AMPS, 2}, {GHOST_ID_PACK_MAH, ZSTR_CAPACITY, UNIT_MAH, 0}, + {GHOST_ID_GPS_LAT, ZSTR_GPS, UNIT_GPS_LATITUDE, 0}, + {GHOST_ID_GPS_LONG, ZSTR_GPS, UNIT_GPS_LONGITUDE, 0}, + {GHOST_ID_GPS_GSPD, ZSTR_GSPD, UNIT_KMH, 1}, + {GHOST_ID_GPS_HDG, ZSTR_HDG, UNIT_DEGREE, 3}, + {GHOST_ID_GPS_ALT, ZSTR_ALT, UNIT_METERS, 0}, + {GHOST_ID_GPS_SATS, ZSTR_SATELLITES, UNIT_RAW, 0}, + {0x00, NULL, UNIT_RAW, 0}, }; @@ -88,7 +102,11 @@ void processGhostTelemetryValue(uint8_t index, int32_t value) return; const GhostSensor * sensor = getGhostSensor(index); - setTelemetryValue(PROTOCOL_TELEMETRY_GHOST, sensor->id, 0, 0, value, sensor->unit, sensor->precision); + uint16_t id = sensor->id; + if (id == GHOST_ID_GPS_LONG) { + id = GHOST_ID_GPS_LAT; + } + setTelemetryValue(PROTOCOL_TELEMETRY_GHOST, id, 0, 0, value, sensor->unit, sensor->precision); } void processGhostTelemetryValueString(const GhostSensor * sensor, const char * str) @@ -105,16 +123,19 @@ bool checkGhostTelemetryFrameCRC() return (crc == telemetryRxBuffer[len + 1]); } +// hifirst uint16_t getTelemetryValue_u16(uint8_t index) { return (telemetryRxBuffer[index] << 8) | telemetryRxBuffer[index + 1]; } +// lofirst uint16_t getTelemetryValue_u16le(uint8_t index) { return (telemetryRxBuffer[index + 1] << 8) | telemetryRxBuffer[index]; } +// hifirst uint32_t getTelemetryValue_s32(uint8_t index) { uint32_t val = 0; @@ -123,6 +144,15 @@ uint32_t getTelemetryValue_s32(uint8_t index) return val; } +// lofirst +uint32_t getTelemetryValue_s32le(uint8_t index) +{ + uint32_t val = 0; + for (int i = 0; i < 4; ++i) + val <<= 8, val |= telemetryRxBuffer[index + 3 - i]; + return val; +} + void processGhostTelemetryFrame() { if (!checkGhostTelemetryFrameCRC()) { @@ -226,15 +256,40 @@ void processGhostTelemetryFrame() case GHST_DL_PACK_STAT: { #if defined(BLUETOOTH) if (g_eeGeneral.bluetoothMode == BLUETOOTH_TELEMETRY && bluetooth.state == BLUETOOTH_STATE_CONNECTED) { - bluetooth.write(telemetryRxBuffer, telemetryRxBufferCount); - } + bluetooth.write(telemetryRxBuffer, telemetryRxBufferCount); + } #endif processGhostTelemetryValue(GHOST_ID_PACK_VOLTS, getTelemetryValue_u16le(3)); processGhostTelemetryValue(GHOST_ID_PACK_AMPS, getTelemetryValue_u16le(5)); processGhostTelemetryValue(GHOST_ID_PACK_MAH, getTelemetryValue_u16le(7) * 10); - break; } + + case GHST_DL_GPS_PRIMARY: { +#if defined(BLUETOOTH) + if (g_eeGeneral.bluetoothMode == BLUETOOTH_TELEMETRY && bluetooth.state == BLUETOOTH_STATE_CONNECTED) { + bluetooth.write(telemetryRxBuffer, telemetryRxBufferCount); + } +#endif + processGhostTelemetryValue(GHOST_ID_GPS_LAT, getTelemetryValue_s32le(3) / 10); + processGhostTelemetryValue(GHOST_ID_GPS_LONG, getTelemetryValue_s32le(7) / 10); + processGhostTelemetryValue(GHOST_ID_GPS_ALT, (int16_t) getTelemetryValue_u16le(11)); + break; + } + + case GHST_DL_GPS_SECONDARY: { +#if defined(BLUETOOTH) + if (g_eeGeneral.bluetoothMode == BLUETOOTH_TELEMETRY && bluetooth.state == BLUETOOTH_STATE_CONNECTED) { + bluetooth.write(telemetryRxBuffer, telemetryRxBufferCount); + } +#endif + processGhostTelemetryValue(GHOST_ID_GPS_HDG, getTelemetryValue_u16le(5) / 10); + + // ground speed is passed via GHST as cm/s, converted to km/h for OpenTx + processGhostTelemetryValue(GHOST_ID_GPS_GSPD, (getTelemetryValue_u16le(3) * 36 + 50) / 100); + processGhostTelemetryValue(GHOST_ID_GPS_SATS, telemetryRxBuffer[7]); + break; + } } } @@ -285,6 +340,9 @@ void ghostSetDefault(int index, uint8_t id, uint8_t subId) const GhostSensor * sensor = getGhostSensor(id); if (sensor) { TelemetryUnit unit = sensor->unit; + if (unit == UNIT_GPS_LATITUDE || unit == UNIT_GPS_LONGITUDE) { + unit = UNIT_GPS; + } uint8_t prec = min(2, sensor->precision); telemetrySensor.init(sensor->name, unit, prec); } diff --git a/radio/src/telemetry/ghost.h b/radio/src/telemetry/ghost.h index 9cdd48a39..36f493b9f 100755 --- a/radio/src/telemetry/ghost.h +++ b/radio/src/telemetry/ghost.h @@ -44,6 +44,8 @@ #define GHST_DL_VTX_STAT 0x22 #define GHST_DL_PACK_STAT 0x23 #define GHST_DL_MENU_DESC 0x24 +#define GHST_DL_GPS_PRIMARY 0x25 +#define GHST_DL_GPS_SECONDARY 0x26 #define GHST_RC_CTR_VAL_12BIT 0x7C0 // 0x3e0 << 1 #define GHST_RC_CTR_VAL_8BIT 0x7C diff --git a/radio/src/telemetry/mlink.cpp b/radio/src/telemetry/mlink.cpp new file mode 100644 index 000000000..a7cdccb92 --- /dev/null +++ b/radio/src/telemetry/mlink.cpp @@ -0,0 +1,161 @@ +/* + * Copyright (C) OpenTX + * + * 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" + +struct MLinkSensor +{ + const uint16_t id; + const char * name; + const TelemetryUnit unit; + const uint8_t precision; +}; + +const MLinkSensor mlinkSensors[] = { + {MLINK_RX_VOLTAGE, ZSTR_BATT, UNIT_VOLTS, 1}, + {MLINK_VOLTAGE, ZSTR_VFAS, UNIT_VOLTS, 1}, + {MLINK_CURRENT, ZSTR_CURR, UNIT_AMPS, 1}, + {MLINK_VARIO, ZSTR_VSPD, UNIT_METERS_PER_SECOND, 1}, + {MLINK_SPEED, ZSTR_SPEED, UNIT_KMH, 1}, + {MLINK_RPM, ZSTR_RPM, UNIT_RPMS, 0}, + {MLINK_TEMP, ZSTR_TEMP1, UNIT_CELSIUS, 1}, + {MLINK_HEADING, ZSTR_HDG, UNIT_DEGREE, 1}, + {MLINK_ALT, ZSTR_ALT , UNIT_METERS, 0}, + {MLINK_FUEL, ZSTR_FUEL, UNIT_PERCENT, 0}, + {MLINK_CAPACITY, ZSTR_CAPACITY, UNIT_MAH, 0}, + {MLINK_FLOW, ZSTR_FLOW, UNIT_MILLILITERS, 0}, + {MLINK_DISTANCE, ZSTR_DIST, UNIT_KM, 1}, + {MLINK_LQI, ZSTR_RSSI, UNIT_RAW, 0}, + {MLINK_LOSS, ZSTR_LOSS, UNIT_RAW, 0}, + {MLINK_TX_RSSI, ZSTR_TX_RSSI, UNIT_RAW, 0}, + {MLINK_TX_LQI, ZSTR_TX_QUALITY, UNIT_RAW, 0}, +}; + +const MLinkSensor * getMLinkSensor(uint16_t id) +{ + for (const MLinkSensor * sensor = mlinkSensors; sensor->id; sensor++) { + if (id == sensor->id) + return sensor; + } + return nullptr; +} + +void processMLinkPacket(const uint8_t * packet) +{ + const uint8_t * data = packet + 2; + + // Multi telem + setTelemetryValue(PROTOCOL_TELEMETRY_MLINK, MLINK_TX_RSSI, 0, 0, (packet[0] * 100) / 31, UNIT_RAW, 0); + setTelemetryValue(PROTOCOL_TELEMETRY_MLINK, MLINK_TX_LQI, 0, 0, packet[1], UNIT_RAW, 0); + + // M-Link telem + if (data[0] == 0x13) { // Telemetry type RX-9 + for (uint8_t i = 1; i < 5; i += 3) { //2 sensors per packet + int32_t val = (int16_t )(data[i + 2] << 8 | data[i + 1]); + val = val >> 1; // remove alarm flag + uint8_t adress = (data[i] & 0xF0) >> 4; + switch (data[i] & 0x0F) { + case MLINK_VOLTAGE: + if ((data[i] & 0xF0) == 0x00){ + setTelemetryValue(PROTOCOL_TELEMETRY_MLINK, MLINK_RX_VOLTAGE, 0, adress, val, UNIT_VOLTS, 1); + } + else { + setTelemetryValue(PROTOCOL_TELEMETRY_MLINK, MLINK_VOLTAGE, 0, adress, val, UNIT_VOLTS, 1); + } + break; + case MLINK_CURRENT: + setTelemetryValue(PROTOCOL_TELEMETRY_MLINK, MLINK_CURRENT, 0, adress, val, UNIT_AMPS, 1); + break; + case MLINK_VARIO: + setTelemetryValue(PROTOCOL_TELEMETRY_MLINK, MLINK_VARIO, 0, adress, val, UNIT_METERS_PER_SECOND, 1); + break; + case MLINK_SPEED: + setTelemetryValue(PROTOCOL_TELEMETRY_MLINK, MLINK_SPEED, 0, adress, val, UNIT_KMH, 1); + break; + case MLINK_RPM: + if (val < 0) { + val = -val * 10; + } + else { + val = val * 100; + } + setTelemetryValue(PROTOCOL_TELEMETRY_MLINK, MLINK_RPM, 0, adress, val, UNIT_RPMS, 0); + break; + case MLINK_TEMP: + setTelemetryValue(PROTOCOL_TELEMETRY_MLINK, MLINK_TEMP, 0, adress, val, UNIT_CELSIUS, 1); + break; + case MLINK_HEADING: + setTelemetryValue(PROTOCOL_TELEMETRY_MLINK, MLINK_HEADING, 0, adress, val, UNIT_DEGREE, 1); + break; + case MLINK_ALT: + setTelemetryValue(PROTOCOL_TELEMETRY_MLINK, MLINK_ALT, 0, adress, val, UNIT_METERS, 0); + break; + case MLINK_FUEL: + setTelemetryValue(PROTOCOL_TELEMETRY_MLINK, MLINK_FUEL, 0, adress, val, UNIT_PERCENT, 0); + break; + case MLINK_CAPACITY: + setTelemetryValue(PROTOCOL_TELEMETRY_MLINK, MLINK_CAPACITY, 0, adress, val, UNIT_MAH, 0); + break; + case MLINK_FLOW: + setTelemetryValue(PROTOCOL_TELEMETRY_MLINK, MLINK_FLOW, 0, adress, val, UNIT_MILLILITERS, 0); + break; + case MLINK_DISTANCE: + setTelemetryValue(PROTOCOL_TELEMETRY_MLINK, MLINK_DISTANCE, 0, adress, val, UNIT_KM, 1); + break; + case MLINK_LQI: + uint8_t mlinkRssi = data[i + 1] >> 1; + setTelemetryValue(PROTOCOL_TELEMETRY_MLINK, MLINK_LQI, 0, 0, mlinkRssi, UNIT_RAW, 0); + telemetryData.rssi.set(mlinkRssi); + if (mlinkRssi > 0) { + telemetryStreaming = TELEMETRY_TIMEOUT10ms; + } + break; + } + } + } + else if (packet[2] == 0x03) { // Telemetry type RX-5 + uint16_t mlinkRssi = (packet[4] * 100) / 35; + setTelemetryValue(PROTOCOL_TELEMETRY_MLINK, MLINK_LQI, 0, 0, mlinkRssi, UNIT_RAW, 0); + telemetryData.rssi.set(mlinkRssi); + if (mlinkRssi > 0) { + telemetryStreaming = TELEMETRY_TIMEOUT10ms; + } + setTelemetryValue(PROTOCOL_TELEMETRY_MLINK, MLINK_LOSS, 0, 0, packet[7], UNIT_RAW, 0); + } +} + +void mlinkSetDefault(int index, uint16_t id, uint8_t subId, uint8_t instance) +{ + TelemetrySensor &telemetrySensor = g_model.telemetrySensors[index]; + telemetrySensor.id = id; + telemetrySensor.subId = subId; + telemetrySensor.instance = instance; + + const MLinkSensor * sensor = getMLinkSensor(id); + if (sensor) { + TelemetryUnit unit = sensor->unit; + uint8_t prec = min(2, sensor->precision); + telemetrySensor.init(sensor->name, unit, prec); + if (unit == UNIT_RPMS) { + telemetrySensor.custom.ratio = 1; + telemetrySensor.custom.offset = 1; + } + } + else { + telemetrySensor.init(id); + } + + storageDirty(EE_MODEL); +} diff --git a/radio/src/telemetry/mlink.h b/radio/src/telemetry/mlink.h new file mode 100644 index 000000000..eb5da955e --- /dev/null +++ b/radio/src/telemetry/mlink.h @@ -0,0 +1,47 @@ +/* + * 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. + */ + +#pragma once + +enum { + MLINK_VOLTAGE = 1, + MLINK_CURRENT = 2, + MLINK_VARIO = 3, + MLINK_SPEED = 4, + MLINK_RPM = 5, + MLINK_TEMP = 6, + MLINK_HEADING = 7, + MLINK_ALT = 8, + MLINK_FUEL = 9, + MLINK_LQI = 10, + MLINK_CAPACITY = 11, + MLINK_FLOW = 12, + MLINK_DISTANCE = 13, + MLINK_RX_VOLTAGE = 16, // out of range ID for specific RxBt treatment + MLINK_LOSS = 17, // out of range ID for handling number of loss + MLINK_TX_RSSI = 18, // out of range ID for handling Telemetry RSSi reported by multi + MLINK_TX_LQI = 19, // out of range ID for handling Telemetry LQI reported by multi +}; + +void processMLinkTelemetryData(uint8_t data, uint8_t* rxBuffer, uint8_t& rxBufferCount); +void mlinkSetDefault(int index, uint16_t id, uint8_t subId, uint8_t instance); + +// Used by multi protocol +void processMLinkPacket(const uint8_t *packet); diff --git a/radio/src/telemetry/multi.cpp b/radio/src/telemetry/multi.cpp index eb5f6fc08..1cb560b14 100644 --- a/radio/src/telemetry/multi.cpp +++ b/radio/src/telemetry/multi.cpp @@ -42,6 +42,7 @@ enum MultiPacketTypes : uint8_t FlyskyIBusTelemetryAC, MultiRxChannels, HottTelemetry, + MLinkTelemetry }; enum MultiBufferState : uint8_t @@ -360,6 +361,13 @@ static void processMultiTelemetryPaket(const uint8_t * packet, uint8_t module) TRACE("[MP] Received HoTT telemetry len %d < 14", len); break; + case MLinkTelemetry: + if (len > 6) + processMLinkPacket(data); + else + TRACE("[MP] Received M-Link telemetry len %d < 6", len); + break; + case FrSkyHubTelemetry: if (len >= 4) frskyDProcessPacket(data); diff --git a/radio/src/telemetry/telemetry.h b/radio/src/telemetry/telemetry.h index 28f66da2c..c70cc5fb9 100644 --- a/radio/src/telemetry/telemetry.h +++ b/radio/src/telemetry/telemetry.h @@ -33,6 +33,7 @@ #include "hitec.h" #include "hott.h" #include "multi.h" + #include "mlink.h" #endif #if defined(MULTIMODULE) || defined(AFHDS3) #include "flysky_ibus.h" diff --git a/radio/src/telemetry/telemetry_sensors.cpp b/radio/src/telemetry/telemetry_sensors.cpp index e88807062..b439bd678 100644 --- a/radio/src/telemetry/telemetry_sensors.cpp +++ b/radio/src/telemetry/telemetry_sensors.cpp @@ -559,6 +559,10 @@ int setTelemetryValue(TelemetryProtocol protocol, uint16_t id, uint8_t subId, ui case PROTOCOL_TELEMETRY_HOTT: hottSetDefault(index, id, subId, instance); break; + + case PROTOCOL_TELEMETRY_MLINK: + mlinkSetDefault(index, id, subId, instance); + break; #endif #if defined(LUA) diff --git a/radio/src/translations.cpp b/radio/src/translations.cpp index 455d6490d..c54248064 100644 --- a/radio/src/translations.cpp +++ b/radio/src/translations.cpp @@ -98,6 +98,8 @@ ISTR(INPUTNAMES); #if defined(MULTIMODULE) ISTR(MULTI_PROTOCOLS); ISTR(MULTI_POWER); +ISTR(MULTI_TELEMETRY_MODE); +ISTR(MULTI_WBUS_MODE); #endif #if defined(BLUETOOTH) @@ -707,6 +709,7 @@ const char STR_BIND_OK[] = TR_BIND_OK; const char STR_MULTI_CUSTOM[] = TR_MULTI_CUSTOM; const char STR_MULTI_RFTUNE[] = TR_MULTI_RFTUNE; const char STR_MULTI_RFPOWER[] = TR_MULTI_RFPOWER; +const char STR_MULTI_WBUS[] = TR_MULTI_WBUS; const char STR_MULTI_TELEMETRY[] = TR_MULTI_TELEMETRY; const char STR_MULTI_VIDFREQ[] = TR_MULTI_VIDFREQ; const char STR_MULTI_OPTION[] = TR_MULTI_OPTION; diff --git a/radio/src/translations.h b/radio/src/translations.h index a9131d8a5..90112a9f3 100644 --- a/radio/src/translations.h +++ b/radio/src/translations.h @@ -161,6 +161,8 @@ extern const char STR_R9M_PXX2_RF_PROTOCOLS[]; extern const char STR_DSM_PROTOCOLS[]; extern const char STR_MULTI_PROTOCOLS[]; extern const char STR_MULTI_POWER[]; +extern const char STR_MULTI_TELEMETRY_MODE[]; +extern const char STR_MULTI_WBUS_MODE[]; extern const char STR_SPORT_MODES[]; #if defined(AFHDS3) @@ -403,6 +405,7 @@ extern const char STR_MULTI_OPTION[]; extern const char STR_MULTI_VIDFREQ[]; extern const char STR_MULTI_RFTUNE[]; extern const char STR_MULTI_RFPOWER[]; +extern const char STR_MULTI_WBUS[]; extern const char STR_MULTI_TELEMETRY[]; extern const char STR_MULTI_AUTOBIND[]; extern const char STR_DISABLE_CH_MAP[]; diff --git a/radio/src/translations/cz.h.txt b/radio/src/translations/cz.h.txt index 59eae1a46..771093985 100644 --- a/radio/src/translations/cz.h.txt +++ b/radio/src/translations/cz.h.txt @@ -260,7 +260,7 @@ #define LEN_VUNITSSYSTEM TR("\006", "\010") #define TR_VUNITSSYSTEM TR("Metr.\0""Imper.", "Metrické""Imperial") #define LEN_VTELEMUNIT "\003" -#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm""Hz\0""mS\0""uS\0" +#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm""Hz\0""mS\0""uS\0""km\0" #define STR_V (STR_VTELEMUNIT+1) #define STR_A (STR_VTELEMUNIT+4) @@ -639,6 +639,7 @@ #define TR_RECEIVER "Přijímač" #define TR_MULTI_RFTUNE TR(INDENT "Ladění frek", INDENT "Jemné ladění frek. RF") #define TR_MULTI_RFPOWER "RF power" +#define TR_MULTI_WBUS "Output" #define TR_MULTI_TELEMETRY "Telemetrie" #define TR_MULTI_VIDFREQ TR(INDENT "Freq. videa", INDENT "Frekvence videa") #define TR_RFPOWER "Výkon RF" @@ -1380,3 +1381,6 @@ #define ZSTR_SERVO_VOLTAGE "SrvV" #define ZSTR_SERVO_TEMPERATURE "SrvT" #define ZSTR_SERVO_STATUS "SrvS" +#define ZSTR_LOSS "Loss" +#define ZSTR_SPEED "Spd " +#define ZSTR_FLOW "Flow" diff --git a/radio/src/translations/de.h.txt b/radio/src/translations/de.h.txt index fb36f0021..f0091ef99 100644 --- a/radio/src/translations/de.h.txt +++ b/radio/src/translations/de.h.txt @@ -263,7 +263,7 @@ #define LEN_VUNITSSYSTEM TR("\006", "\012") #define TR_VUNITSSYSTEM TR("Metrik""Imper.", "Metrisch\0 ""Imperial\0 ") #define LEN_VTELEMUNIT "\003" - #define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm""Hz\0""mS\0""uS\0" + #define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm""Hz\0""mS\0""uS\0""km\0" #define STR_V (STR_VTELEMUNIT+1) #define STR_A (STR_VTELEMUNIT+4) @@ -641,6 +641,7 @@ #define TR_RECEIVER "Empfänger" #define TR_MULTI_RFTUNE TR(INDENT "RF Freq.", INDENT "RF Freq. Feintuning") #define TR_MULTI_RFPOWER "RF power" +#define TR_MULTI_WBUS "Output" #define TR_MULTI_TELEMETRY "Telemetry" #define TR_MULTI_VIDFREQ TR(INDENT "Vid. Freq.", INDENT "Video Frequenz") #define TR_RFPOWER "RF Power" @@ -1387,3 +1388,6 @@ #define ZSTR_SERVO_VOLTAGE "SrvV" #define ZSTR_SERVO_TEMPERATURE "SrvT" #define ZSTR_SERVO_STATUS "SrvS" +#define ZSTR_LOSS "Loss" +#define ZSTR_SPEED "Spd " +#define ZSTR_FLOW "Flow" diff --git a/radio/src/translations/en.h.txt b/radio/src/translations/en.h.txt index f66e99a33..1fcb635cf 100644 --- a/radio/src/translations/en.h.txt +++ b/radio/src/translations/en.h.txt @@ -263,7 +263,7 @@ #define LEN_VUNITSSYSTEM TR("\006", "\010") #define TR_VUNITSSYSTEM TR("Metric""Imper.", "Metric\0 ""Imperial") #define LEN_VTELEMUNIT "\003" -#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm""Hz\0""mS\0""uS\0" +#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm""Hz\0""mS\0""uS\0""km\0" #define STR_V (STR_VTELEMUNIT+1) #define STR_A (STR_VTELEMUNIT+4) @@ -640,6 +640,7 @@ #define TR_RECEIVER "Receiver" #define TR_MULTI_RFTUNE TR("Freq tune", "RF Freq. fine tune") #define TR_MULTI_RFPOWER "RF power" +#define TR_MULTI_WBUS "Output" #define TR_MULTI_TELEMETRY "Telemetry" #define TR_MULTI_VIDFREQ TR("Vid. freq.", "Video frequency") #define TR_RFPOWER "RF Power" @@ -1384,3 +1385,6 @@ #define ZSTR_SERVO_VOLTAGE "SrvV" #define ZSTR_SERVO_TEMPERATURE "SrvT" #define ZSTR_SERVO_STATUS "SrvS" +#define ZSTR_LOSS "Loss" +#define ZSTR_SPEED "Spd " +#define ZSTR_FLOW "Flow" diff --git a/radio/src/translations/es.h.txt b/radio/src/translations/es.h.txt index 0e5fa3dc7..793be030b 100644 --- a/radio/src/translations/es.h.txt +++ b/radio/src/translations/es.h.txt @@ -260,7 +260,7 @@ #define LEN_VUNITSSYSTEM "\010" #define TR_VUNITSSYSTEM "Métrico\0""Imperial" #define LEN_VTELEMUNIT "\003" -#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm""Hz\0""mS\0""uS\0" +#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm""Hz\0""mS\0""uS\0""km\0" #define STR_V (STR_VTELEMUNIT+1) #define STR_A (STR_VTELEMUNIT+4) @@ -642,6 +642,7 @@ #define TR_RECEIVER "Receptor" #define TR_MULTI_RFTUNE TR("Sint.freq.", "RF Freq. sint.fina") #define TR_MULTI_RFPOWER "RF power" +#define TR_MULTI_WBUS "Output" #define TR_MULTI_TELEMETRY "Telemetría" #define TR_MULTI_VIDFREQ TR("Freq.vídeo", "Frecuencia vídeo") #define TR_RFPOWER "RF Power" @@ -1383,3 +1384,6 @@ #define ZSTR_SERVO_VOLTAGE "SrvV" #define ZSTR_SERVO_TEMPERATURE "SrvT" #define ZSTR_SERVO_STATUS "SrvS" +#define ZSTR_LOSS "Loss" +#define ZSTR_SPEED "Spd " +#define ZSTR_FLOW "Flow" diff --git a/radio/src/translations/fi.h.txt b/radio/src/translations/fi.h.txt index 0bd9c954f..0fa5467ea 100644 --- a/radio/src/translations/fi.h.txt +++ b/radio/src/translations/fi.h.txt @@ -281,7 +281,7 @@ #define LEN_VUNITSSYSTEM TR("\006", "\010") #define TR_VUNITSSYSTEM TR("Metric""Imper.", "Metric\0 ""Imperial") #define LEN_VTELEMUNIT "\003" -#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm""Hz\0""mS\0""uS\0" +#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm""Hz\0""mS\0""uS\0""km\0" #define STR_V (STR_VTELEMUNIT+1) #define STR_A (STR_VTELEMUNIT+4) @@ -658,6 +658,7 @@ #define TR_RECEIVER "Receiver" #define TR_MULTI_RFTUNE TR("Freq tune", "RF Freq. fine tune") #define TR_MULTI_RFPOWER "RF power" +#define TR_MULTI_WBUS "Output" #define TR_MULTI_TELEMETRY "Telemetry" #define TR_MULTI_VIDFREQ TR("Vid. freq.", "Video frequency") #define TR_RFPOWER "RF Power" @@ -1391,3 +1392,6 @@ #define ZSTR_SERVO_VOLTAGE "SrvV" #define ZSTR_SERVO_TEMPERATURE "SrvT" #define ZSTR_SERVO_STATUS "SrvS" +#define ZSTR_LOSS "Loss" +#define ZSTR_SPEED "Spd " +#define ZSTR_FLOW "Flow" diff --git a/radio/src/translations/fr.h.txt b/radio/src/translations/fr.h.txt index fb818f7e8..9190811ed 100644 --- a/radio/src/translations/fr.h.txt +++ b/radio/src/translations/fr.h.txt @@ -283,7 +283,7 @@ #define LEN_VUNITSSYSTEM TR("\006", "\012") #define TR_VUNITSSYSTEM TR("Métr.\0""Impér.", "Métriques\0""Impériales") #define LEN_VTELEMUNIT "\003" -#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm""Hz\0""mS\0""uS\0" +#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm""Hz\0""mS\0""uS\0""km\0" #define STR_V (STR_VTELEMUNIT+1) #define STR_A (STR_VTELEMUNIT+4) @@ -661,6 +661,7 @@ #define TR_RECEIVER "Récept." #define TR_MULTI_RFTUNE TR(INDENT "Ajust.fréq", INDENT "Ajustement fréq.") #define TR_MULTI_RFPOWER "RF power" +#define TR_MULTI_WBUS "Output" #define TR_MULTI_TELEMETRY "Télémétrie" #define TR_MULTI_VIDFREQ TR(INDENT "Fréq. vidéo", INDENT "Fréquence vidéo") #define TR_RFPOWER TR("Puiss. RF", "Puissance RF") @@ -1408,3 +1409,6 @@ #define ZSTR_SERVO_VOLTAGE "SrvV" #define ZSTR_SERVO_TEMPERATURE "SrvT" #define ZSTR_SERVO_STATUS "SrvS" +#define ZSTR_LOSS "Loss" +#define ZSTR_SPEED "Spd " +#define ZSTR_FLOW "Flow" diff --git a/radio/src/translations/it.h.txt b/radio/src/translations/it.h.txt index 9a0785a1e..277b21458 100644 --- a/radio/src/translations/it.h.txt +++ b/radio/src/translations/it.h.txt @@ -284,7 +284,7 @@ #define LEN_VUNITSSYSTEM TR("\006", "\011") #define TR_VUNITSSYSTEM TR("Metric""Imper.", "Metriche\0""Imperiali") #define LEN_VTELEMUNIT "\003" -#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm""Hz\0""mS\0""uS\0" +#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm""Hz\0""mS\0""uS\0""km\0" #define STR_V (STR_VTELEMUNIT+1) #define STR_A (STR_VTELEMUNIT+4) @@ -462,7 +462,7 @@ #define TR_TTRIM TR("Trim Mot.", INDENT "Trim Motore") #define TR_TTRIM_SW TR("T-Trim-Sw", INDENT "Trim switch") #define TR_BEEPCTR TR("Beep al c.", "Beep al centro") -#define TR_USE_GLOBAL_FUNCS "Usa Funz. Globali" +#define TR_USE_GLOBAL_FUNCS TR("Funz. Glob.", "Usa Funz. Globali") #if defined(PCBSKY9X) && defined(REVX) #define TR_OUTPUT_TYPE INDENT "Uscita" #endif @@ -660,6 +660,7 @@ #define TR_RECEIVER "Ricevente" #define TR_MULTI_RFTUNE TR("Tune RF", "Tune fine Freq. RF") #define TR_MULTI_RFPOWER "RF power" +#define TR_MULTI_WBUS "Output" #define TR_MULTI_TELEMETRY "Telemetria" #define TR_MULTI_VIDFREQ TR("Freq. video", "Frequenza video") #define TR_RFPOWER "Potenza RF" @@ -871,28 +872,28 @@ #define TR_FLASH_EXTERNAL_MODULE TR("Prog. modulo est.", "Programma modulo esterno") #define TR_FLASH_INTERNAL_MULTI TR("Prog. MULTI int.", "Programma MULTI interno") #define TR_FLASH_EXTERNAL_MULTI TR("Prog. MULTI est.", "Programma MULTI esterno") -#define TR_FIRMWARE_UPDATE_ERROR TR(INDENT "Errore agg. FW",INDENT "Errore aggiornamento firmware") +#define TR_FIRMWARE_UPDATE_ERROR TR(INDENT "Errore agg. FW",INDENT "Errore aggiornamento firmware") #define TR_FIRMWARE_UPDATE_SUCCESS "Aggiornamento" BREAKSPACE "riuscito" -#define TR_WRITING "Scrittura..." -#define TR_CONFIRM_FORMAT "Confermi formattazione?" -#define TR_INTERNALRF "Modulo interno" +#define TR_WRITING "Scrittura..." +#define TR_CONFIRM_FORMAT "Confermi formattazione?" +#define TR_INTERNALRF "Modulo interno" #define TR_INTERNAL_MODULE TR("Modulo int.", "Modulo interno") #define TR_EXTERNAL_MODULE TR("Modulo est.", "Modulo esterno") #define TR_OPENTX_UPGRADE_REQUIRED "OpenTX richiede aggiornamento" #define TR_TELEMETRY_DISABLED TR("Telem. off", "Telem. disabilitata") #define TR_MORE_OPTIONS_AVAILABLE "Altre opzioni assenti" #define TR_NO_MODULE_INFORMATION "Nessuna info del modulo" -#define TR_EXTERNALRF "Modulo esterno" -#define TR_FAILSAFE "Modo failsafe" -#define TR_FAILSAFESET TR(INDENT "FAILSAFE", INDENT "IMPOSTAZIONI FAILSAFE") +#define TR_EXTERNALRF "Modulo esterno" +#define TR_FAILSAFE TR(INDENT "Failsafe", INDENT "Modo failsafe") +#define TR_FAILSAFESET TR(INDENT "FAILSAFE", INDENT "IMPOSTAZIONI FAILSAFE") #define TR_REG_ID "Reg. ID" #define TR_OWNER_ID "Owner ID" #define TR_PINMAPSET "PINMAP" -#define TR_HOLD "Hold" +#define TR_HOLD "Hold" #define TR_HOLD_UPPERCASE "HOLD" -#define TR_NONE "None" +#define TR_NONE "None" #define TR_NONE_UPPERCASE "NONE" -#define TR_MENUSENSOR "SENSORE" +#define TR_MENUSENSOR "SENSORE" #define TR_POWERMETER_PEAK "Picco" #define TR_POWERMETER_POWER "Potenza" #define TR_POWERMETER_ATTN "Att." @@ -934,7 +935,7 @@ #define TR_SPEAKER INDENT "Speaker" #define TR_BUZZER INDENT "Buzzer" #define TR_BYTES "Bytes" -#define TR_MODULE_BIND "[Bind]" +#define TR_MODULE_BIND TR("[Bnd]","[Bind]") #define TR_POWERMETER_ATTN_NEEDED "Attenuatore necessario" #define TR_PXX2_SELECT_RX "Seleziona RX..." #define TR_PXX2_DEFAULT "" @@ -946,8 +947,8 @@ #define TR_RECEIVER_RESET "Resetto RX?" #define TR_SHARE "Condividere" #define TR_BIND "Bind" -#define TR_REGISTER TR("Reg", "Registrare") -#define TR_MODULE_RANGE "[Range]" +#define TR_REGISTER TR("Reg", "Registrare") +#define TR_MODULE_RANGE TR("[Rng]","[Range]") #define TR_RECEIVER_OPTIONS TR("OPZIONI RX", "OPZIONI RICEVENTE") #define TR_DEL_BUTTON BUTTON(TR("Canc.", "Cancella")) #define TR_RESET_BTN "[Reset]" @@ -970,7 +971,7 @@ #define TR_TOPLCDTIMER "Timer LCD Sup." #define TR_UNIT "Unita" #define TR_TELEMETRY_NEWSENSOR INDENT "Aggiungi nuovo sensore" -#define TR_CHANNELRANGE INDENT "Numero Canali" +#define TR_CHANNELRANGE TR(INDENT "Num Canali", INDENT "Numero Canali") #define TR_AFHDS3_RX_FREQ TR("Freq. RX", "Frequenza RX") #define TR_AFHDS3_ONE_TO_ONE_TELEMETRY TR("Unicast/Tel.", "Unicast/Telemetria") #define TR_AFHDS3_ONE_TO_MANY "Multicast" @@ -1401,3 +1402,6 @@ #define ZSTR_SERVO_VOLTAGE "SrvV" #define ZSTR_SERVO_TEMPERATURE "SrvT" #define ZSTR_SERVO_STATUS "SrvS" +#define ZSTR_LOSS "Loss" +#define ZSTR_SPEED "Spd " +#define ZSTR_FLOW "Flow" diff --git a/radio/src/translations/nl.h.txt b/radio/src/translations/nl.h.txt index 13f567589..3e9e04641 100644 --- a/radio/src/translations/nl.h.txt +++ b/radio/src/translations/nl.h.txt @@ -264,7 +264,7 @@ #define LEN_VUNITSSYSTEM TR("\006", "\010") #define TR_VUNITSSYSTEM TR("Mtrsch""Engels", "Metrisch\0 ""Engels\0 ") #define LEN_VTELEMUNIT "\003" -#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm""Hz\0""mS\0""uS\0" +#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm""Hz\0""mS\0""uS\0""km\0" #define STR_V (STR_VTELEMUNIT+1) #define STR_A (STR_VTELEMUNIT+4) @@ -646,6 +646,7 @@ #define TR_RECEIVER "Receiver" #define TR_MULTI_RFTUNE TR("Freq tune", "RF Freq. fine tune") #define TR_MULTI_RFPOWER "RF power" +#define TR_MULTI_WBUS "Output" #define TR_MULTI_TELEMETRY "Telemetry" #define TR_MULTI_VIDFREQ TR("Vid. freq.", "Video frequency") #define TR_RFPOWER "RF Power" @@ -1393,3 +1394,6 @@ #define ZSTR_SERVO_VOLTAGE "SrvV" #define ZSTR_SERVO_TEMPERATURE "SrvT" #define ZSTR_SERVO_STATUS "SrvS" +#define ZSTR_LOSS "Loss" +#define ZSTR_SPEED "Spd " +#define ZSTR_FLOW "Flow" diff --git a/radio/src/translations/pl.h.txt b/radio/src/translations/pl.h.txt index bf59714cf..a77acbcd3 100644 --- a/radio/src/translations/pl.h.txt +++ b/radio/src/translations/pl.h.txt @@ -281,7 +281,7 @@ #define LEN_VUNITSSYSTEM TR("\006", "\010") /*8 decimal*/ #define TR_VUNITSSYSTEM TR("Metr. ""Imper.", "Metryczn""Imperial") #define LEN_VTELEMUNIT "\003" -#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm""Hz\0""mS\0""uS\0" +#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm""Hz\0""mS\0""uS\0""km\0" #define STR_V (STR_VTELEMUNIT+1) #define STR_A (STR_VTELEMUNIT+4) @@ -659,6 +659,7 @@ #define TR_RECEIVER INDENT "Receiver" #define TR_MULTI_RFTUNE TR("Freq tune", "RF Freq. fine tune") #define TR_MULTI_RFPOWER "RF power" +#define TR_MULTI_WBUS "Output" #define TR_MULTI_TELEMETRY "Telemetry" #define TR_MULTI_VIDFREQ TR("Vid. freq.", "Video frequency") #define TR_RFPOWER "RF Power" @@ -1400,3 +1401,6 @@ #define ZSTR_SERVO_VOLTAGE "SrvV" #define ZSTR_SERVO_TEMPERATURE "SrvT" #define ZSTR_SERVO_STATUS "SrvS" +#define ZSTR_LOSS "Loss" +#define ZSTR_SPEED "Spd " +#define ZSTR_FLOW "Flow" diff --git a/radio/src/translations/pt.h.txt b/radio/src/translations/pt.h.txt index 8c794822e..3241e9ce4 100644 --- a/radio/src/translations/pt.h.txt +++ b/radio/src/translations/pt.h.txt @@ -277,7 +277,7 @@ #define LEN_VUNITSSYSTEM TR("\006", "\010") #define TR_VUNITSSYSTEM TR("Metric""Imper.", "Metric\0 ""Imperial") #define LEN_VTELEMUNIT "\003" - #define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm""Hz\0""mS\0""uS\0" + #define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm""Hz\0""mS\0""uS\0""km\0" #define STR_V (STR_VTELEMUNIT+1) #define STR_A (STR_VTELEMUNIT+4) @@ -661,6 +661,7 @@ #define TR_SYNCMENU "Sync [MENU]" #define TR_MULTI_RFTUNE TR("Freq tune", "RF Freq. fine tune") #define TR_MULTI_RFPOWER "RF power" +#define TR_MULTI_WBUS "Output" #define TR_MULTI_TELEMETRY "Telemetry" #define TR_MULTI_VIDFREQ TR("Vid. freq.", "Video frequency") #define TR_RFPOWER "RF Power" @@ -1400,3 +1401,6 @@ #define ZSTR_SERVO_VOLTAGE "SrvV" #define ZSTR_SERVO_TEMPERATURE "SrvT" #define ZSTR_SERVO_STATUS "SrvS" +#define ZSTR_LOSS "Loss" +#define ZSTR_SPEED "Spd " +#define ZSTR_FLOW "Flow" diff --git a/radio/src/translations/se.h.txt b/radio/src/translations/se.h.txt index 54c081eb3..4cd3b0df4 100644 --- a/radio/src/translations/se.h.txt +++ b/radio/src/translations/se.h.txt @@ -278,7 +278,7 @@ #define LEN_VUNITSSYSTEM TR("\006", "\010") #define TR_VUNITSSYSTEM TR("Metri.""Imper.", "Metriska""Imperial") #define LEN_VTELEMUNIT "\003" -#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm""Hz\0""mS\0""uS\0" +#define TR_VTELEMUNIT "-\0 ""V\0 ""A\0 ""mA\0""kts""m/s""f/s""kmh""mph""m\0 ""ft\0""@C\0""@F\0""%\0 ""mAh""W\0 ""mW\0""dB\0""rpm""g\0 ""@\0 ""rad""ml\0""fOz""mlm""Hz\0""mS\0""uS\0""km\0" #define STR_V (STR_VTELEMUNIT+1) #define STR_A (STR_VTELEMUNIT+4) @@ -659,6 +659,7 @@ #define TR_SYNCMENU "Synk [MENU]" #define TR_MULTI_RFTUNE TR("Freq tune", "RF Freq. fine tune") #define TR_MULTI_RFPOWER "RF power" +#define TR_MULTI_WBUS "Output" #define TR_MULTI_TELEMETRY "Telemetry" #define TR_MULTI_VIDFREQ TR("Vid. freq.", "Video frequency") #define TR_RFPOWER "RF Power" @@ -1400,3 +1401,6 @@ #define ZSTR_SERVO_VOLTAGE "SrvV" #define ZSTR_SERVO_TEMPERATURE "SrvT" #define ZSTR_SERVO_STATUS "SrvS" +#define ZSTR_LOSS "Loss" +#define ZSTR_SPEED "Spd " +#define ZSTR_FLOW "Flow" diff --git a/radio/src/translations/untranslated.h b/radio/src/translations/untranslated.h index 74735bc7f..a758b1a31 100644 --- a/radio/src/translations/untranslated.h +++ b/radio/src/translations/untranslated.h @@ -134,7 +134,13 @@ #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 " +#define TR_MULTI_POWER "1.6mW""2.0mW""2.5mW""3.2mW""4.0mW""5.0mW""6.3mW""7.9mW""10mW\0""13mW\0""16mW\0""20mW\0""25mW\0""32mW\0""40mW\0""50mW\0" + +#define LEN_MULTI_WBUS_MODE "\004" +#define TR_MULTI_WBUS_MODE "WBUS""PPM\0" + +#define LEN_MULTI_TELEMETRY_MODE "\007" +#define TR_MULTI_TELEMETRY_MODE "Off\0 ""On\0 ""Off+Aux""On+Aux\0" #define LEN_AFHDS3_PROTOCOLS "\x008" #define TR_AFHDS3_PROTOCOLS "PWM/IBUS""PWM/SBUS""PPM/IBUS""PPM/SBUS" diff --git a/radio/util/tts_en.py b/radio/util/tts_en.py index 616abe516..6230aafe9 100755 --- a/radio/util/tts_en.py +++ b/radio/util/tts_en.py @@ -41,6 +41,7 @@ for i, (s, f) in enumerate([("volt", "volt0"), ("volts", "volt1"), ("hertz", "hertz0"), ("hertz", "hertz1"), ("milisecond", "ms0"), ("miliseconds", "ms1"), ("microsecond", "us0"), ("microseconds", "us1"), + ("kilometer", "km0"), ("kilometers", "km1"), ("hour", "hour0"), ("hours", "hour1"), ("minute", "minute0"), ("minutes", "minute1"), ("second", "second0"), ("seconds", "second1"), diff --git a/radio/util/tts_fr.py b/radio/util/tts_fr.py index 9dc046fa5..eba461d72 100755 --- a/radio/util/tts_fr.py +++ b/radio/util/tts_fr.py @@ -39,6 +39,10 @@ for i, (s, f) in enumerate([("volts", "volt0"), ("millilitres", "ml0"), ("onces", "founce0"), ("millilitre minute", "mlpm0"), + ("microsecond", "us0"), + ("milisecond", "ms0"), + ("hertz", "hertz0"), + ("kilometre", "km0"), ("heure", "hour0"), ("minute", "minute0"), ("seconde", "second0"),