chore: Companion - port of OpenTX function switches management (#1694)
* TPro - Port of OpenTX function switches management (https://github.com/opentx/opentx/pull/8847) * cleanup * Corrections * Fix YAML generation and adjusted switches to match TPRO firmware Co-authored-by: Batam <batam@macbook-pro.home>
This commit is contained in:
@@ -114,6 +114,7 @@ RawSourceItemModel::RawSourceItemModel(const GeneralSettings * const generalSett
|
||||
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));
|
||||
addItems(SOURCE_TYPE_FUNCTIONSWITCH, RawSource::SwitchesGroup, board->getCapability(Board::FunctionSwitches));
|
||||
addItems(SOURCE_TYPE_CUSTOM_SWITCH, RawSource::SwitchesGroup, firmware->getCapability(LogicalSwitches));
|
||||
addItems(SOURCE_TYPE_CYC, RawSource::SourcesGroup, CPN_MAX_CYC);
|
||||
addItems(SOURCE_TYPE_PPM, RawSource::SourcesGroup, firmware->getCapability(TrainerInputs));
|
||||
@@ -163,7 +164,7 @@ RawSwitchItemModel::RawSwitchItemModel(const GeneralSettings * const generalSett
|
||||
AbstractDynamicItemModel(generalSettings, modelData, firmware, board, boardType)
|
||||
{
|
||||
setId(IMID_RawSwitch);
|
||||
setUpdateMask(IMUE_FlightModes | IMUE_LogicalSwitches | IMUE_TeleSensors);
|
||||
setUpdateMask(IMUE_FlightModes | IMUE_LogicalSwitches | IMUE_TeleSensors | IMUE_FunctionSwitches);
|
||||
|
||||
// Descending switch direction: NOT (!) switches
|
||||
addItems(SWITCH_TYPE_ACT, -1);
|
||||
@@ -173,11 +174,13 @@ RawSwitchItemModel::RawSwitchItemModel(const GeneralSettings * const generalSett
|
||||
addItems(SWITCH_TYPE_VIRTUAL, -firmware->getCapability(LogicalSwitches));
|
||||
addItems(SWITCH_TYPE_TRIM, -board->getCapability(Board::NumTrimSwitches));
|
||||
addItems(SWITCH_TYPE_MULTIPOS_POT, -(board->getCapability(Board::MultiposPots) * board->getCapability(Board::MultiposPotsPositions)));
|
||||
addItems(SWITCH_TYPE_FUNCTIONSWITCH, -board->getCapability(Board::NumFunctionSwitchesPositions));
|
||||
addItems(SWITCH_TYPE_SWITCH, -board->getCapability(Board::SwitchPositions));
|
||||
|
||||
// Ascending switch direction (including zero)
|
||||
addItems(SWITCH_TYPE_NONE, 1);
|
||||
addItems(SWITCH_TYPE_SWITCH, board->getCapability(Board::SwitchPositions));
|
||||
addItems(SWITCH_TYPE_FUNCTIONSWITCH, board->getCapability(Board::NumFunctionSwitchesPositions));
|
||||
addItems(SWITCH_TYPE_MULTIPOS_POT, board->getCapability(Board::MultiposPots) * board->getCapability(Board::MultiposPotsPositions));
|
||||
addItems(SWITCH_TYPE_TRIM, board->getCapability(Board::NumTrimSwitches));
|
||||
addItems(SWITCH_TYPE_VIRTUAL, firmware->getCapability(LogicalSwitches));
|
||||
@@ -202,7 +205,7 @@ void RawSwitchItemModel::addItems(const RawSwitchType & type, int count)
|
||||
// handle exceptions in RawSwitch() index values
|
||||
const short rawIdxAdj = rawSwitchIndexBaseZeroTypes.contains(type) ? -1 : 0;
|
||||
|
||||
// determine cotext flags
|
||||
// determine context flags
|
||||
int context = RawSwitch::AllSwitchContexts;
|
||||
switch (type) {
|
||||
case SWITCH_TYPE_FLIGHT_MODE:
|
||||
|
||||
@@ -67,20 +67,21 @@ class AbstractItemModel: public QStandardItemModel
|
||||
Q_ENUM(ItemModelDataGroups)
|
||||
|
||||
enum ItemModelUpdateEvent {
|
||||
IMUE_None = 0,
|
||||
IMUE_SystemRefresh = 1 << 0,
|
||||
IMUE_Channels = 1 << 1,
|
||||
IMUE_Curves = 1 << 2,
|
||||
IMUE_FlightModes = 1 << 3,
|
||||
IMUE_GVars = 1 << 4,
|
||||
IMUE_Inputs = 1 << 5,
|
||||
IMUE_LogicalSwitches = 1 << 6,
|
||||
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_Modules
|
||||
IMUE_None = 0,
|
||||
IMUE_SystemRefresh = 1 << 0,
|
||||
IMUE_Channels = 1 << 1,
|
||||
IMUE_Curves = 1 << 2,
|
||||
IMUE_FlightModes = 1 << 3,
|
||||
IMUE_GVars = 1 << 4,
|
||||
IMUE_Inputs = 1 << 5,
|
||||
IMUE_LogicalSwitches = 1 << 6,
|
||||
IMUE_Scripts = 1 << 7,
|
||||
IMUE_TeleSensors = 1 << 8,
|
||||
IMUE_Timers = 1 << 9,
|
||||
IMUE_Modules = 1 << 10,
|
||||
IMUE_FunctionSwitches = 1 << 11,
|
||||
IMUE_All = IMUE_SystemRefresh | IMUE_Channels | IMUE_Curves | IMUE_FlightModes | IMUE_GVars | IMUE_Inputs |
|
||||
IMUE_LogicalSwitches | IMUE_Scripts | IMUE_TeleSensors | IMUE_Timers | IMUE_Modules | IMUE_FunctionSwitches
|
||||
};
|
||||
Q_ENUM(ItemModelUpdateEvent)
|
||||
|
||||
|
||||
@@ -449,6 +449,9 @@ int Boards::getCapability(Board::Type board, Board::Capability capability)
|
||||
else
|
||||
return 7;
|
||||
|
||||
case FunctionSwitches:
|
||||
return (IS_JUMPER_TPRO(board) ? 6 : 0);
|
||||
|
||||
case FactoryInstalledSwitches:
|
||||
if (IS_TARANIS_X9E(board))
|
||||
return 8;
|
||||
@@ -469,6 +472,10 @@ int Boards::getCapability(Board::Type board, Board::Capability capability)
|
||||
else
|
||||
return 9;
|
||||
|
||||
case NumFunctionSwitchesPositions:
|
||||
return getCapability(board, Board::FunctionSwitches) * 3;
|
||||
|
||||
|
||||
case NumTrims:
|
||||
if (IS_FAMILY_HORUS_OR_T16(board) && !IS_FLYSKY_NV14(board))
|
||||
return 6;
|
||||
@@ -484,9 +491,6 @@ int Boards::getCapability(Board::Type board, Board::Capability capability)
|
||||
case HasColorLcd:
|
||||
return IS_FAMILY_HORUS_OR_T16(board);
|
||||
|
||||
case NumFunctionSwitches:
|
||||
return IS_JUMPER_TPRO(board) ? 6 : 0;
|
||||
|
||||
case HasSDCard:
|
||||
return IS_STM32(board);
|
||||
|
||||
@@ -867,10 +871,12 @@ int Boards::getDefaultInternalModules(Board::Type board)
|
||||
case BOARD_RADIOMASTER_TX12:
|
||||
case BOARD_RADIOMASTER_T8:
|
||||
case BOARD_JUMPER_TLITE:
|
||||
case BOARD_RADIOMASTER_ZORRO:
|
||||
case BOARD_JUMPER_TPRO:
|
||||
return (int)MODULE_TYPE_MULTIMODULE;
|
||||
|
||||
|
||||
case BOARD_RADIOMASTER_ZORRO:
|
||||
return (int)MODULE_TYPE_CROSSFIRE;
|
||||
|
||||
case BOARD_FLYSKY_NV14:
|
||||
return (int)MODULE_TYPE_FLYSKY;
|
||||
|
||||
|
||||
@@ -140,13 +140,14 @@ namespace Board {
|
||||
MultiposPots,
|
||||
MultiposPotsPositions,
|
||||
Switches,
|
||||
FunctionSwitches,
|
||||
SwitchPositions,
|
||||
NumFunctionSwitchesPositions,
|
||||
FactoryInstalledSwitches,
|
||||
NumTrims,
|
||||
NumTrimSwitches,
|
||||
HasRTC,
|
||||
HasColorLcd,
|
||||
NumFunctionSwitches,
|
||||
HasSDCard,
|
||||
HasInternalModuleSupport,
|
||||
SportMaxBaudRate
|
||||
|
||||
@@ -957,7 +957,7 @@ Node convert<ModelData>::encode(const ModelData& rhs)
|
||||
|
||||
node["modelRegistrationID"] = rhs.registrationId;
|
||||
|
||||
if (getCurrentFirmware()->getCapability(FunctionSwitches)) {
|
||||
if (Boards::getCapability(getCurrentBoard(), Board::FunctionSwitches)) {
|
||||
node["functionSwitchConfig"] = rhs.functionSwitchConfig;
|
||||
node["functionSwitchGroup"] = rhs.functionSwitchGroup;
|
||||
node["functionSwitchStartConfig"] = rhs.functionSwitchStartConfig;
|
||||
@@ -965,8 +965,7 @@ Node convert<ModelData>::encode(const ModelData& rhs)
|
||||
|
||||
for (int i = 0; i < CPN_MAX_FUNCTION_SWITCHES; i++) {
|
||||
if (strlen(rhs.functionSwitchNames[i]) > 0) {
|
||||
node["functionSwitchNames"][std::to_string(i)] =
|
||||
rhs.functionSwitchNames[i];
|
||||
node["switchNames"][std::to_string(i)]["val"] = rhs.functionSwitchNames[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1137,8 +1136,7 @@ bool convert<ModelData>::decode(const Node& node, ModelData& rhs)
|
||||
node["functionSwitchGroup"] >> rhs.functionSwitchGroup;
|
||||
node["functionSwitchStartConfig"] >> rhs.functionSwitchStartConfig;
|
||||
node["functionSwitchLogicalState"] >> rhs.functionSwitchLogicalState;
|
||||
node["functionSwitchNames"] >> rhs.functionSwitchNames;
|
||||
|
||||
node["switchNames"] >> rhs.functionSwitchNames;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
std::string YamlRawSourceEncode(const RawSource& rhs)
|
||||
{
|
||||
std::string src_str;
|
||||
char c = 'A';
|
||||
switch (rhs.type) {
|
||||
case SOURCE_TYPE_VIRTUAL_INPUT:
|
||||
src_str += "I" + std::to_string(rhs.index);
|
||||
@@ -52,6 +53,14 @@ std::string YamlRawSourceEncode(const RawSource& rhs)
|
||||
src_str += std::to_string(rhs.index + 1);
|
||||
src_str += ")";
|
||||
break;
|
||||
case SOURCE_TYPE_FUNCTIONSWITCH:
|
||||
if (IS_JUMPER_TPRO(getCurrentBoard())) {
|
||||
c += Boards::getCapability(getCurrentBoard(), Board::Switches);
|
||||
c += rhs.index;
|
||||
src_str += "S";
|
||||
src_str += c;
|
||||
}
|
||||
break;
|
||||
case SOURCE_TYPE_CYC:
|
||||
src_str = getCurrentFirmware()->getRawSourceCyclicTag(rhs.index);
|
||||
break;
|
||||
@@ -114,9 +123,19 @@ RawSource YamlRawSourceDecode(const std::string& src_str)
|
||||
&& val[1] <= 'Z') {
|
||||
|
||||
int idx = getCurrentFirmware()->getSwitchesIndex(src_str.c_str());
|
||||
if (idx >= 0 && idx < CPN_MAX_SWITCHES)
|
||||
if (idx >= 0 && idx < CPN_MAX_SWITCHES) {
|
||||
rhs = RawSource(SOURCE_TYPE_SWITCH, idx);
|
||||
|
||||
} else if (IS_JUMPER_TPRO(getCurrentBoard())) {
|
||||
int numSw = Boards::getCapability(getCurrentBoard(), Board::Switches);
|
||||
idx = val[1] - 'A';
|
||||
idx -= numSw;
|
||||
|
||||
if(idx >= 0 and idx < Boards::getCapability(getCurrentBoard(), Board::FunctionSwitches)) {
|
||||
rhs = RawSource(SOURCE_TYPE_FUNCTIONSWITCH, idx);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (val_len > 4 &&
|
||||
val[0] == 'l' &&
|
||||
val[1] == 'u' &&
|
||||
@@ -142,6 +161,17 @@ RawSource YamlRawSourceDecode(const std::string& src_str)
|
||||
if (ls > 0 && ls <= CPN_MAX_LOGICAL_SWITCHES)
|
||||
rhs = RawSource(SOURCE_TYPE_CUSTOM_SWITCH, ls - 1);
|
||||
|
||||
} else if (val_len > 3 &&
|
||||
val[0] == 'f' &&
|
||||
val[1] == 's' &&
|
||||
val[2] == '(') {
|
||||
|
||||
std::stringstream src(src_str.substr(3));
|
||||
int fs = 0;
|
||||
src >> fs;
|
||||
if (fs > 0 && fs <= CPN_MAX_FUNCTION_SWITCHES)
|
||||
rhs = RawSource(SOURCE_TYPE_FUNCTIONSWITCH, fs - 1);
|
||||
|
||||
} else if (val_len > 3 &&
|
||||
val[0] == 't' &&
|
||||
val[1] == 'r' &&
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
std::string YamlRawSwitchEncode(const RawSwitch& rhs)
|
||||
{
|
||||
std::string sw_str;
|
||||
char c = 'A';
|
||||
int32_t sval = rhs.index;
|
||||
if (rhs.index < 0) {
|
||||
sval = -sval;
|
||||
@@ -42,6 +43,16 @@ std::string YamlRawSwitchEncode(const RawSwitch& rhs)
|
||||
sw_str += "L";
|
||||
sw_str += std::to_string(sval);
|
||||
break;
|
||||
|
||||
case SWITCH_TYPE_FUNCTIONSWITCH:
|
||||
if (IS_JUMPER_TPRO(getCurrentBoard())) {
|
||||
c += Boards::getCapability(getCurrentBoard(), Board::Switches);
|
||||
c += (sval - 1) / 3;
|
||||
sw_str += "S";
|
||||
sw_str += c;
|
||||
sw_str += std::to_string((sval - 1) % 3);
|
||||
}
|
||||
break;
|
||||
|
||||
case SWITCH_TYPE_MULTIPOS_POT:
|
||||
sw_str += "6P";
|
||||
@@ -143,6 +154,16 @@ RawSwitch YamlRawSwitchDecode(const std::string& sw_str)
|
||||
if (sw_idx >= 0) {
|
||||
rhs.type = SWITCH_TYPE_SWITCH;
|
||||
rhs.index = sw_idx * 3 + (val[2] - '0' + 1);
|
||||
|
||||
} else if (IS_JUMPER_TPRO(getCurrentBoard())) {
|
||||
int numSw = Boards::getCapability(getCurrentBoard(), Board::Switches);
|
||||
int idx = val[1] - 'A';
|
||||
idx = idx - numSw;
|
||||
|
||||
if(idx >= 0 and idx < Boards::getCapability(getCurrentBoard(), Board::FunctionSwitches)) {
|
||||
idx = idx * 3 + (val[2] - '0' + 1);
|
||||
rhs = RawSwitch(SWITCH_TYPE_FUNCTIONSWITCH, idx);
|
||||
}
|
||||
}
|
||||
|
||||
// these types use index = 1
|
||||
@@ -158,7 +179,6 @@ RawSwitch YamlRawSwitchDecode(const std::string& sw_str)
|
||||
|
||||
// TODO: SWITCH_TYPE_TIMER_MODE
|
||||
// check as it appears to be depreciated as not in RawSwitch data model and not in radio yaml export
|
||||
|
||||
} else {
|
||||
// types which do not use index
|
||||
int sw_type = getCurrentFirmware()->getRawSwitchTypesIndex(sw_str_tmp.c_str());
|
||||
|
||||
@@ -165,7 +165,6 @@ enum Capability {
|
||||
HasADCJitterFilter,
|
||||
HasTelemetryBaudrate,
|
||||
TopBarZones,
|
||||
FunctionSwitches,
|
||||
HasModelsList,
|
||||
HasFlySkyGimbals
|
||||
};
|
||||
|
||||
@@ -218,8 +218,8 @@ void ModelData::setDefaultFunctionSwitches(int functionSwitchCount)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < functionSwitchCount; i++) {
|
||||
functionSwitchConfig |= (Board::SWITCH_2POS << 2 * i);
|
||||
functionSwitchGroup |= (1 << 2 * i);
|
||||
setFuncSwitchConfig(i, Board::SWITCH_2POS);
|
||||
setFuncSwitchGroup(i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,7 +232,7 @@ void ModelData::setDefaultValues(unsigned int id, const GeneralSettings & settin
|
||||
moduleData[i].modelId = id + 1;
|
||||
}
|
||||
setDefaultMixes(settings);
|
||||
setDefaultFunctionSwitches(getCurrentFirmware()->getCapability(FunctionSwitches));
|
||||
setDefaultFunctionSwitches(Boards::getCapability(getCurrentFirmware()->getBoard(), Board::FunctionSwitches));
|
||||
}
|
||||
|
||||
int ModelData::getTrimValue(int phaseIdx, int trimIdx)
|
||||
@@ -384,6 +384,28 @@ int ModelData::getChannelsMax(bool forceExtendedLimits) const
|
||||
return 100;
|
||||
}
|
||||
|
||||
bool ModelData::isFunctionSwitchPositionAvailable(int index) const
|
||||
{
|
||||
if (index == 0)
|
||||
return true;
|
||||
|
||||
div_t qr = div(abs(index) - 1, 3);
|
||||
int fs = getFuncSwitchConfig(qr.quot);
|
||||
|
||||
if (qr.rem == 1) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return fs != Board::SWITCH_NOT_AVAILABLE;
|
||||
}
|
||||
}
|
||||
|
||||
bool ModelData::isFunctionSwitchSourceAllowed(int index) const
|
||||
{
|
||||
return (int)getFuncSwitchConfig(index) != Board::SWITCH_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
|
||||
bool ModelData::isAvailable(const RawSwitch & swtch) const
|
||||
{
|
||||
unsigned index = abs(swtch.index) - 1;
|
||||
@@ -397,6 +419,9 @@ bool ModelData::isAvailable(const RawSwitch & swtch) const
|
||||
else if (swtch.type == SWITCH_TYPE_SENSOR) {
|
||||
return strlen(sensorData[index].label) > 0;
|
||||
}
|
||||
else if (swtch.type == SWITCH_TYPE_FUNCTIONSWITCH) {
|
||||
return isFunctionSwitchPositionAvailable(index + 1);
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
@@ -1654,76 +1679,123 @@ AbstractStaticItemModel * ModelData::trainerModeItemModel(const GeneralSettings
|
||||
return mdl;
|
||||
}
|
||||
|
||||
QString ModelData::funcSwitchConfigToString(const int index) const
|
||||
{
|
||||
if (index < CPN_MAX_FUNCTION_SWITCHES)
|
||||
return funcSwitchConfigToString(index, (int)(functionSwitchConfig >> (2 * index)) & 0x03);
|
||||
else
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
}
|
||||
|
||||
// static
|
||||
QString ModelData::funcSwitchConfigToString(const int index, const int value)
|
||||
{
|
||||
switch (value) {
|
||||
case FUNC_SWITCH_CONFIG_NONE:
|
||||
return tr("NONE");
|
||||
case FUNC_SWITCH_CONFIG_TOGGLE:
|
||||
return tr("TOGGLE");
|
||||
case FUNC_SWITCH_CONFIG_2POS:
|
||||
return tr("2POS");
|
||||
default:
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
}
|
||||
}
|
||||
unsigned int ModelData::getFuncSwitchConfig(unsigned int index) const
|
||||
{
|
||||
if (index < CPN_MAX_FUNCTION_SWITCHES)
|
||||
return Helpers::getBitmappedValue(functionSwitchConfig, index, 2);
|
||||
else
|
||||
return FUNC_SWITCH_CONFIG_NONE;
|
||||
}
|
||||
|
||||
// static
|
||||
AbstractStaticItemModel * ModelData::funcSwitchConfigItemModel()
|
||||
{
|
||||
AbstractStaticItemModel * mdl = new AbstractStaticItemModel();
|
||||
mdl->setName(AIM_MODELDATA_FUNCSWITCHCONFIG);
|
||||
void ModelData::setFuncSwitchConfig(unsigned int index, unsigned int value)
|
||||
{
|
||||
if (index < CPN_MAX_FUNCTION_SWITCHES)
|
||||
Helpers::setBitmappedValue(functionSwitchConfig, value, index, 2);
|
||||
}
|
||||
|
||||
for (int i = FUNC_SWITCH_CONFIG_FIRST; i <= FUNC_SWITCH_CONFIG_LAST; i++) {
|
||||
mdl->appendToItemList(funcSwitchConfigToString(0, i), i);
|
||||
}
|
||||
// static
|
||||
QString ModelData::funcSwitchConfigToString(unsigned int value)
|
||||
{
|
||||
switch (value) {
|
||||
case FUNC_SWITCH_CONFIG_NONE:
|
||||
return tr("NONE");
|
||||
case FUNC_SWITCH_CONFIG_TOGGLE:
|
||||
return tr("TOGGLE");
|
||||
case FUNC_SWITCH_CONFIG_2POS:
|
||||
return tr("2POS");
|
||||
default:
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
}
|
||||
}
|
||||
|
||||
mdl->loadItemList();
|
||||
return mdl;
|
||||
}
|
||||
// static
|
||||
AbstractStaticItemModel * ModelData::funcSwitchConfigItemModel()
|
||||
{
|
||||
AbstractStaticItemModel * mdl = new AbstractStaticItemModel();
|
||||
mdl->setName(AIM_MODELDATA_FUNCSWITCHCONFIG);
|
||||
|
||||
QString ModelData::funcSwitchStartToString(const int index) const
|
||||
{
|
||||
if (index < CPN_MAX_FUNCTION_SWITCHES)
|
||||
return funcSwitchStartToString(index, (int)(functionSwitchStartConfig >> (2 * index)) & 0x03);
|
||||
else
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
}
|
||||
for (unsigned int i = FUNC_SWITCH_CONFIG_FIRST; i <= FUNC_SWITCH_CONFIG_LAST; i++) {
|
||||
mdl->appendToItemList(funcSwitchConfigToString(i), i);
|
||||
}
|
||||
|
||||
// static
|
||||
QString ModelData::funcSwitchStartToString(const int index, const int value)
|
||||
{
|
||||
switch (value) {
|
||||
case FUNC_SWITCH_START_INACTIVE:
|
||||
return tr("Inactive");
|
||||
case FUNC_SWITCH_START_ACTIVE:
|
||||
return tr("Active");
|
||||
case FUNC_SWITCH_START_PREVIOUS:
|
||||
return tr("Restore");
|
||||
default:
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
}
|
||||
}
|
||||
mdl->loadItemList();
|
||||
return mdl;
|
||||
}
|
||||
|
||||
// static
|
||||
AbstractStaticItemModel * ModelData::funcSwitchStartItemModel()
|
||||
{
|
||||
AbstractStaticItemModel * mdl = new AbstractStaticItemModel();
|
||||
mdl->setName(AIM_MODELDATA_FUNCSWITCHSTART);
|
||||
unsigned int ModelData::getFuncSwitchGroup(unsigned int index) const
|
||||
{
|
||||
if (index < CPN_MAX_FUNCTION_SWITCHES)
|
||||
return Helpers::getBitmappedValue(functionSwitchGroup, index, 2);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int i = FUNC_SWITCH_START_FIRST; i <= FUNC_SWITCH_START_LAST; i++) {
|
||||
mdl->appendToItemList(funcSwitchStartToString(0, i), i);
|
||||
}
|
||||
void ModelData::setFuncSwitchGroup(unsigned int index, unsigned int value)
|
||||
{
|
||||
if (index < CPN_MAX_FUNCTION_SWITCHES)
|
||||
Helpers::setBitmappedValue(functionSwitchGroup, value, index, 2);
|
||||
}
|
||||
|
||||
mdl->loadItemList();
|
||||
return mdl;
|
||||
}
|
||||
unsigned int ModelData::getFuncSwitchAlwaysOnGroup(unsigned int index) const
|
||||
{
|
||||
if (index < CPN_MAX_FUNCTION_SWITCHES) {
|
||||
unsigned int grp = getFuncSwitchGroup(index);
|
||||
unsigned int switchcnt = Boards::getCapability(getCurrentFirmware()->getBoard(), Board::FunctionSwitches);
|
||||
return Helpers::getBitmappedValue(functionSwitchGroup, grp, 1, 2 * switchcnt);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ModelData::setFuncSwitchAlwaysOnGroup(unsigned int index, unsigned int value)
|
||||
{
|
||||
if (index < CPN_MAX_FUNCTION_SWITCHES) {
|
||||
unsigned int grp = getFuncSwitchGroup(index);
|
||||
unsigned int switchcnt = Boards::getCapability(getCurrentFirmware()->getBoard(), Board::FunctionSwitches);
|
||||
Helpers::setBitmappedValue(functionSwitchGroup, value, grp, 1, 2 * switchcnt);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int ModelData::getFuncSwitchStart(unsigned int index) const
|
||||
{
|
||||
if (index < CPN_MAX_FUNCTION_SWITCHES)
|
||||
return Helpers::getBitmappedValue(functionSwitchStartConfig, index, 2);
|
||||
else
|
||||
return FUNC_SWITCH_START_INACTIVE;
|
||||
}
|
||||
|
||||
void ModelData::setFuncSwitchStart(unsigned int index, unsigned int value)
|
||||
{
|
||||
if (index < CPN_MAX_FUNCTION_SWITCHES)
|
||||
Helpers::setBitmappedValue(functionSwitchStartConfig, value, index, 2);
|
||||
}
|
||||
|
||||
// static
|
||||
QString ModelData::funcSwitchStartToString(unsigned int value)
|
||||
{
|
||||
switch (value) {
|
||||
case FUNC_SWITCH_START_INACTIVE:
|
||||
return tr("Inactive");
|
||||
case FUNC_SWITCH_START_ACTIVE:
|
||||
return tr("Active");
|
||||
case FUNC_SWITCH_START_PREVIOUS:
|
||||
return tr("Restore");
|
||||
default:
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
AbstractStaticItemModel * ModelData::funcSwitchStartItemModel()
|
||||
{
|
||||
AbstractStaticItemModel * mdl = new AbstractStaticItemModel();
|
||||
mdl->setName(AIM_MODELDATA_FUNCSWITCHSTART);
|
||||
|
||||
for (unsigned int i = FUNC_SWITCH_START_FIRST; i <= FUNC_SWITCH_START_LAST; i++) {
|
||||
mdl->appendToItemList(funcSwitchStartToString(i), i);
|
||||
}
|
||||
|
||||
mdl->loadItemList();
|
||||
return mdl;
|
||||
}
|
||||
|
||||
@@ -184,9 +184,10 @@ class ModelData {
|
||||
};
|
||||
|
||||
enum FunctionSwitchStart {
|
||||
FUNC_SWITCH_START_INACTIVE,
|
||||
FUNC_SWITCH_START_FIRST = FUNC_SWITCH_START_INACTIVE,
|
||||
FUNC_SWITCH_START_ACTIVE,
|
||||
FUNC_SWITCH_START_FIRST = FUNC_SWITCH_START_ACTIVE,
|
||||
FUNC_SWITCH_START_INACTIVE,
|
||||
//FUNC_SWITCH_START_FIRST = FUNC_SWITCH_START_INACTIVE,
|
||||
FUNC_SWITCH_START_PREVIOUS,
|
||||
FUNC_SWITCH_START_LAST = FUNC_SWITCH_START_PREVIOUS
|
||||
};
|
||||
@@ -232,6 +233,8 @@ class ModelData {
|
||||
int getChannelsMax(bool forceExtendedLimits=false) const;
|
||||
|
||||
bool isAvailable(const RawSwitch & swtch) const;
|
||||
bool isFunctionSwitchPositionAvailable(int index) const;
|
||||
bool isFunctionSwitchSourceAllowed(int index) const;
|
||||
|
||||
enum ReferenceUpdateAction {
|
||||
REF_UPD_ACT_CLEAR,
|
||||
@@ -287,13 +290,23 @@ class ModelData {
|
||||
static QString trainerModeToString(const int value);
|
||||
static bool isTrainerModeAvailable(const GeneralSettings & generalSettings, const Firmware * firmware, const int value);
|
||||
static AbstractStaticItemModel * trainerModeItemModel(const GeneralSettings & generalSettings, const Firmware * firmware);
|
||||
QString funcSwitchConfigToString(const int index) const;
|
||||
static QString funcSwitchConfigToString(const int index, const int value);
|
||||
unsigned int getFuncSwitchConfig(unsigned int index) const;
|
||||
void setFuncSwitchConfig(unsigned int index, unsigned int value);
|
||||
static QString funcSwitchConfigToString(unsigned int value);
|
||||
static AbstractStaticItemModel * funcSwitchConfigItemModel();
|
||||
QString funcSwitchStartToString(const int index) const;
|
||||
static QString funcSwitchStartToString(const int index, const int value);
|
||||
|
||||
unsigned int getFuncSwitchGroup(unsigned int index) const;
|
||||
void setFuncSwitchGroup(unsigned int index, unsigned int value);
|
||||
|
||||
unsigned int getFuncSwitchAlwaysOnGroup(unsigned int index) const;
|
||||
void setFuncSwitchAlwaysOnGroup(unsigned int index, unsigned int value);
|
||||
|
||||
unsigned int getFuncSwitchStart(unsigned int index) const;
|
||||
void setFuncSwitchStart(unsigned int index, unsigned int value);
|
||||
static QString funcSwitchStartToString(unsigned int value);
|
||||
static AbstractStaticItemModel * funcSwitchStartItemModel();
|
||||
|
||||
|
||||
protected:
|
||||
void removeGlobalVar(int & var);
|
||||
|
||||
|
||||
@@ -45,26 +45,44 @@ inline int MAX_SWITCHES(Board::Type board, int version)
|
||||
if (IS_TARANIS_X9D(board))
|
||||
return 9;
|
||||
|
||||
if (IS_JUMPER_TPRO(board))
|
||||
return 10;
|
||||
|
||||
if (IS_FAMILY_T12(board))
|
||||
return 8;
|
||||
|
||||
if (IS_TARANIS_X7(board))
|
||||
return 8;
|
||||
|
||||
if (IS_JUMPER_TPRO(board))
|
||||
return 10;
|
||||
|
||||
return Boards::getCapability(board, Board::Switches);
|
||||
}
|
||||
|
||||
inline int MAX_SWITCHES_SOURCE(Board::Type board, int version)
|
||||
{
|
||||
if (IS_JUMPER_TPRO(board)) // 10 switches are allocated in EEprom but 6 are reserved for FS
|
||||
return Boards::getCapability(board, Board::Switches);
|
||||
else
|
||||
return MAX_SWITCHES(board, version);
|
||||
}
|
||||
|
||||
inline int MAX_SWITCHES_POSITION(Board::Type board, int version)
|
||||
{
|
||||
if (IS_HORUS_OR_TARANIS(board)) {
|
||||
if (IS_JUMPER_TPRO(board))
|
||||
return Boards::getCapability(board, Board::SwitchPositions);
|
||||
else if (IS_HORUS_OR_TARANIS(board))
|
||||
return MAX_SWITCHES(board, version) * 3;
|
||||
}
|
||||
else {
|
||||
else
|
||||
return Boards::getCapability(board, Board::SwitchPositions);
|
||||
}
|
||||
|
||||
inline int MAX_FUNCTIONSWITCHES(Board::Type board, int version)
|
||||
{
|
||||
return Boards::getCapability(board, Board::FunctionSwitches);
|
||||
}
|
||||
|
||||
inline int MAX_FUNCTIONSWITCHES_POSITION(Board::Type board, int version)
|
||||
{
|
||||
return Boards::getCapability(board, Board::NumFunctionSwitchesPositions);
|
||||
}
|
||||
|
||||
inline int POTS_CONFIG_SIZE(Board::Type board, int version)
|
||||
@@ -156,7 +174,7 @@ inline int SWITCHES_CONFIG_SIZE(Board::Type board, int version)
|
||||
if (IS_FAMILY_HORUS_OR_T16(board))
|
||||
return 32;
|
||||
|
||||
if (version >= 219 && IS_TARANIS_X9D(board))
|
||||
if (version >= 219 && (IS_TARANIS_X9D(board) || IS_JUMPER_TPRO(board)))
|
||||
return 32;
|
||||
|
||||
return 16;
|
||||
@@ -220,6 +238,13 @@ class SwitchesConversionTable: public ConversionTable {
|
||||
val++;
|
||||
}
|
||||
|
||||
for (int i=1; i<=MAX_FUNCTIONSWITCHES_POSITION(board, version); i++) {
|
||||
int s = switchIndex(i, board, version);
|
||||
addConversion(RawSwitch(SWITCH_TYPE_FUNCTIONSWITCH, s), val);
|
||||
addConversion(RawSwitch(SWITCH_TYPE_FUNCTIONSWITCH, -s), -val+offset);
|
||||
val++;
|
||||
}
|
||||
|
||||
if (IS_HORUS_OR_TARANIS(board)) {
|
||||
for (int i=1; i<=MAX_XPOTS(board, version)*6; i++) {
|
||||
addConversion(RawSwitch(SWITCH_TYPE_MULTIPOS_POT, -i), -val+offset);
|
||||
@@ -368,8 +393,10 @@ class SourcesConversionTable: public ConversionTable {
|
||||
addConversion(RawSource(SOURCE_TYPE_SWITCH, 0), val++);
|
||||
|
||||
if (!(flags & FLAG_NOSWITCHES)) {
|
||||
for (int i=1; i<MAX_SWITCHES(board, version); i++)
|
||||
for (int i=1; i<MAX_SWITCHES_SOURCE(board, version); i++)
|
||||
addConversion(RawSource(SOURCE_TYPE_SWITCH, i), val++);
|
||||
for (int i=0; i<MAX_FUNCTIONSWITCHES(board, version); i++)
|
||||
addConversion(RawSource(SOURCE_TYPE_FUNCTIONSWITCH, i), val++);
|
||||
for (int i=0; i<MAX_LOGICAL_SWITCHES(board, version); i++)
|
||||
addConversion(RawSource(SOURCE_TYPE_CUSTOM_SWITCH, i), val++);
|
||||
}
|
||||
@@ -2877,7 +2904,7 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, Board::Type board, unsig
|
||||
internalField.Append(new UnsignedField<16>(this, modelData.functionSwitchGroup));
|
||||
internalField.Append(new UnsignedField<16>(this, modelData.functionSwitchStartConfig));
|
||||
internalField.Append(new UnsignedField<8>(this, modelData.functionSwitchLogicalState));
|
||||
for (int i=0; i < MAX_FUNCTION_SWITCHES(board, version); ++i) {
|
||||
for (int i=0; i < Boards::getCapability(board, Board::FunctionSwitches); ++i) {
|
||||
internalField.Append(new ZCharField<3>(this, modelData.functionSwitchNames[i], "Function switch name"));
|
||||
}
|
||||
}
|
||||
@@ -3209,7 +3236,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
|
||||
|
||||
if (IS_TARANIS_X9E(board))
|
||||
internalField.Append(new SpareBitsField<64>(this)); // switchUnlockStates
|
||||
else if (version >= 219 && IS_TARANIS_X9D(board))
|
||||
else if (version >= 219 && (IS_TARANIS_X9D(board) || IS_JUMPER_TPRO(board)))
|
||||
internalField.Append(new SpareBitsField<32>(this)); // switchUnlockStates
|
||||
else if (IS_TARANIS(board))
|
||||
internalField.Append(new SpareBitsField<16>(this)); // switchUnlockStates
|
||||
|
||||
@@ -757,8 +757,6 @@ int OpenTxFirmware::getCapability(::Capability capability)
|
||||
return IS_HORUS_OR_TARANIS(board);
|
||||
case TopBarZones:
|
||||
return getCapability(LcdWidth) > getCapability(LcdHeight) ? 4 : 2;
|
||||
case FunctionSwitches:
|
||||
return IS_JUMPER_TPRO(board) ? 6 : 0;
|
||||
case HasModelsList:
|
||||
return IS_FAMILY_HORUS_OR_T16(board);
|
||||
case HasFlySkyGimbals:
|
||||
|
||||
@@ -196,6 +196,13 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
|
||||
result = Boards::getSwitchInfo(board, index).name;
|
||||
return result;
|
||||
|
||||
case SOURCE_TYPE_FUNCTIONSWITCH:
|
||||
if (model)
|
||||
result = QString(model->functionSwitchNames[index]).trimmed();
|
||||
if (result.isEmpty())
|
||||
result = tr("SW%1").arg(index + 1);
|
||||
return result;
|
||||
|
||||
case SOURCE_TYPE_CUSTOM_SWITCH:
|
||||
return RawSwitch(SWITCH_TYPE_VIRTUAL, index + 1).toString();
|
||||
|
||||
@@ -309,10 +316,17 @@ bool RawSource::isAvailable(const ModelData * const model, const GeneralSettings
|
||||
if (type == SOURCE_TYPE_SWITCH && index >= b.getCapability(Board::Switches))
|
||||
return false;
|
||||
|
||||
if (type == SOURCE_TYPE_FUNCTIONSWITCH)
|
||||
if (!model || index >= b.getCapability(Board::FunctionSwitches))
|
||||
return false;
|
||||
|
||||
if (type == SOURCE_TYPE_SPECIAL && index >= SOURCE_TYPE_SPECIAL_FIRST_RESERVED && index <= SOURCE_TYPE_SPECIAL_LAST_RESERVED)
|
||||
return false;
|
||||
|
||||
if (model) {
|
||||
if (type == SOURCE_TYPE_FUNCTIONSWITCH && !model->isFunctionSwitchSourceAllowed(index))
|
||||
return false;
|
||||
|
||||
if (type == SOURCE_TYPE_VIRTUAL_INPUT && !model->isInputValid(index))
|
||||
return false;
|
||||
|
||||
|
||||
@@ -169,6 +169,7 @@ enum RawSourceType {
|
||||
SOURCE_TYPE_TRIM,
|
||||
SOURCE_TYPE_MAX,
|
||||
SOURCE_TYPE_SWITCH,
|
||||
SOURCE_TYPE_FUNCTIONSWITCH,
|
||||
SOURCE_TYPE_CUSTOM_SWITCH,
|
||||
SOURCE_TYPE_CYC,
|
||||
SOURCE_TYPE_PPM,
|
||||
|
||||
@@ -73,7 +73,7 @@ QString RawSwitch::toString(Board::Type board, const GeneralSettings * const gen
|
||||
switch(type) {
|
||||
case SWITCH_TYPE_SWITCH:
|
||||
if (IS_HORUS_OR_TARANIS(board)) {
|
||||
qr = div(index-1, 3);
|
||||
qr = div(index - 1, 3);
|
||||
if (generalSettings)
|
||||
swName = QString(generalSettings->switchName[qr.quot]).trimmed();
|
||||
if (swName.isEmpty())
|
||||
@@ -90,9 +90,19 @@ QString RawSwitch::toString(Board::Type board, const GeneralSettings * const gen
|
||||
else
|
||||
return LogicalSwitchData().nameToString(index-1);
|
||||
|
||||
case SWITCH_TYPE_FUNCTIONSWITCH:
|
||||
if (!Boards::getCapability(board, Board::FunctionSwitches))
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
qr = div(index - 1, 3);
|
||||
if (modelData)
|
||||
swName = QString(modelData->functionSwitchNames[qr.quot]).trimmed();
|
||||
if (swName.isEmpty())
|
||||
swName = tr("SW%1").arg(qr.quot + 1);
|
||||
return swName + directionIndicators.at(qr.rem > -1 && qr.rem < directionIndicators.size() ? qr.rem : 1);
|
||||
|
||||
case SWITCH_TYPE_MULTIPOS_POT:
|
||||
if (!Boards::getCapability(board, Board::MultiposPotsPositions))
|
||||
return tr("???");
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
qr = div(index - 1, Boards::getCapability(board, Board::MultiposPotsPositions));
|
||||
if (generalSettings && qr.quot < (int)DIM(generalSettings->potConfig))
|
||||
swName = QString(generalSettings->potName[qr.quot]);
|
||||
@@ -140,8 +150,8 @@ QString RawSwitch::toString(Board::Type board, const GeneralSettings * const gen
|
||||
return tr("Telemetry");
|
||||
|
||||
default:
|
||||
return tr("???");
|
||||
}
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,6 +165,13 @@ bool RawSwitch::isAvailable(const ModelData * const model, const GeneralSettings
|
||||
if (type == SWITCH_TYPE_SWITCH && abs(index) > b.getCapability(Board::SwitchPositions))
|
||||
return false;
|
||||
|
||||
if (type == SWITCH_TYPE_FUNCTIONSWITCH) {
|
||||
if (!model || abs(index) > b.getCapability(Board::NumFunctionSwitchesPositions))
|
||||
return false;
|
||||
else if (!model->isFunctionSwitchPositionAvailable(abs(index)))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (type == SWITCH_TYPE_TRIM && abs(index) > b.getCapability(Board::NumTrimSwitches))
|
||||
return false;
|
||||
|
||||
@@ -257,6 +274,7 @@ StringTagMappingTable RawSwitch::getRawSwitchTypesLookupTable()
|
||||
{std::to_string(SWITCH_TYPE_ON), "ON"},
|
||||
{std::to_string(SWITCH_TYPE_OFF), "OFF"},
|
||||
{std::to_string(SWITCH_TYPE_ONE), "ONE"},
|
||||
{std::to_string(SWITCH_TYPE_FUNCTIONSWITCH), "Sxn"},
|
||||
{std::to_string(SWITCH_TYPE_FLIGHT_MODE), "FMn"},
|
||||
{std::to_string(SWITCH_TYPE_TIMER_MODE), "Timer"},
|
||||
{std::to_string(SWITCH_TYPE_TELEMETRY), "TELEMETRY_STREAMING"},
|
||||
|
||||
@@ -34,6 +34,7 @@ class RadioDataConversionState;
|
||||
enum RawSwitchType {
|
||||
SWITCH_TYPE_NONE,
|
||||
SWITCH_TYPE_SWITCH,
|
||||
SWITCH_TYPE_FUNCTIONSWITCH,
|
||||
SWITCH_TYPE_VIRTUAL,
|
||||
SWITCH_TYPE_MULTIPOS_POT,
|
||||
SWITCH_TYPE_TRIM,
|
||||
|
||||
@@ -305,6 +305,24 @@ void Helpers::exportAppSettings(QWidget * dlgParent)
|
||||
exportAppSettings(dlgParent);
|
||||
}
|
||||
|
||||
unsigned int Helpers::getBitmappedValue(const unsigned int & field, const unsigned int index, const unsigned int numbits, const unsigned int offset)
|
||||
{
|
||||
int mask = -1;
|
||||
mask = mask << numbits;
|
||||
mask = ~mask;
|
||||
return (field >> (numbits * index + offset)) & (unsigned int)mask;
|
||||
}
|
||||
|
||||
void Helpers::setBitmappedValue(unsigned int & field, unsigned int value, unsigned int index, unsigned int numbits, unsigned int offset)
|
||||
{
|
||||
int mask = -1;
|
||||
mask = mask << numbits;
|
||||
mask = ~mask;
|
||||
|
||||
unsigned int fieldmask = ((unsigned int)mask << (numbits * index + offset));
|
||||
field = (field & ~fieldmask) | (value << (numbits * index + offset));
|
||||
}
|
||||
|
||||
void startSimulation(QWidget * parent, RadioData & radioData, int modelIdx)
|
||||
{
|
||||
QString fwId = SimulatorLoader::findSimulatorByFirmwareName(getCurrentFirmware()->getId());
|
||||
|
||||
@@ -113,6 +113,8 @@ namespace Helpers
|
||||
QString getChecklistFilename(const ModelData * model);
|
||||
QString getChecklistFilePath(const ModelData * model);
|
||||
QString removeAccents(const QString & str);
|
||||
unsigned int getBitmappedValue(const unsigned int & field, const unsigned int index, const unsigned int numbits = 1, const unsigned int offset = 0);
|
||||
void setBitmappedValue(unsigned int & field, unsigned int value, unsigned int index, unsigned int numbits = 1, unsigned int offset = 0);
|
||||
|
||||
} // namespace Helpers
|
||||
|
||||
|
||||
@@ -1026,7 +1026,7 @@ FunctionSwitchesPanel::FunctionSwitchesPanel(QWidget * parent, ModelData & model
|
||||
|
||||
QRegExp rx(CHAR_FOR_NAMES_REGEX);
|
||||
|
||||
switchcnt = Boards::getCapability(firmware->getBoard(), Board::NumFunctionSwitches);
|
||||
switchcnt = Boards::getCapability(firmware->getBoard(), Board::FunctionSwitches);
|
||||
|
||||
for (int i = 0; i < switchcnt; i++) {
|
||||
QLabel * lblSwitchId = new QLabel(this);
|
||||
@@ -1062,6 +1062,7 @@ FunctionSwitchesPanel::FunctionSwitchesPanel(QWidget * parent, ModelData & model
|
||||
ui->gridSwitches->addWidget(sbGroup, row++, i + coloffset);
|
||||
ui->gridSwitches->addWidget(cbAlwaysOnGroup, row++, i + coloffset);
|
||||
|
||||
connect(aleName, &AutoLineEdit::currentDataChanged, this, &FunctionSwitchesPanel::on_nameEditingFinished);
|
||||
connect(cboConfig, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &FunctionSwitchesPanel::on_configCurrentIndexChanged);
|
||||
connect(cboStartPosn, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &FunctionSwitchesPanel::on_startPosnCurrentIndexChanged);
|
||||
connect(sbGroup, QOverload<int>::of(&QSpinBox::valueChanged), this, &FunctionSwitchesPanel::on_groupChanged);
|
||||
@@ -1097,11 +1098,11 @@ void FunctionSwitchesPanel::update(int index)
|
||||
|
||||
for (int i = 0; i < switchcnt; i++) {
|
||||
aleNames[i]->update();
|
||||
cboConfigs[i]->setCurrentIndex((model->functionSwitchConfig >> (2 * i)) & 0x03);
|
||||
cboStartupPosns[i]->setCurrentIndex((model->functionSwitchStartConfig >> (2 * i)) & 0x03);
|
||||
const int grp = (model->functionSwitchGroup >> (2 * i)) & 0x03;
|
||||
cboConfigs[i]->setCurrentIndex(model->getFuncSwitchConfig(i));
|
||||
cboStartupPosns[i]->setCurrentIndex(model->getFuncSwitchStart(i));
|
||||
unsigned int grp = model->getFuncSwitchGroup(i);
|
||||
sbGroups[i]->setValue(grp);
|
||||
cbAlwaysOnGroups[i]->setChecked((model->functionSwitchGroup >> (2 * switchcnt + grp)) & 0x01);
|
||||
cbAlwaysOnGroups[i]->setChecked(model->getFuncSwitchAlwaysOnGroup(i));
|
||||
|
||||
if (cboConfigs[i]->currentIndex() < 2)
|
||||
cboStartupPosns[i]->setEnabled(false);
|
||||
@@ -1122,6 +1123,12 @@ void FunctionSwitchesPanel::update(int index)
|
||||
lock = false;
|
||||
}
|
||||
|
||||
void FunctionSwitchesPanel::on_nameEditingFinished()
|
||||
{
|
||||
emit updateDataModels();
|
||||
}
|
||||
|
||||
|
||||
void FunctionSwitchesPanel::on_configCurrentIndexChanged(int index)
|
||||
{
|
||||
if (!sender())
|
||||
@@ -1132,17 +1139,17 @@ void FunctionSwitchesPanel::on_configCurrentIndexChanged(int index)
|
||||
if (cb && !lock) {
|
||||
lock = true;
|
||||
bool ok = false;
|
||||
int i = sender()->property("index").toInt(&ok);
|
||||
if (ok && ((model->functionSwitchConfig >> (2 * i)) & 0x03) != (unsigned int)index) {
|
||||
unsigned int mask = ((unsigned int) 0x03 << (2 * i));
|
||||
model->functionSwitchConfig = (model->functionSwitchConfig & ~ mask) | ((unsigned int) index << (2 * i));
|
||||
unsigned int i = sender()->property("index").toInt(&ok);
|
||||
if (ok && model->getFuncSwitchConfig(i) != (unsigned int)index) {
|
||||
model->setFuncSwitchConfig(i, index);
|
||||
if (index < 2)
|
||||
model->functionSwitchStartConfig = (model->functionSwitchStartConfig & ~ mask) | ((unsigned int) 0 << (2 * i));
|
||||
model->setFuncSwitchStart(i, ModelData::FUNC_SWITCH_START_INACTIVE);
|
||||
if (index < 1)
|
||||
model->functionSwitchGroup = (model->functionSwitchGroup & ~ mask) | ((unsigned int) 0 << (2 * i));
|
||||
model->setFuncSwitchGroup(i, 0);
|
||||
update(i);
|
||||
emit modified();
|
||||
}
|
||||
emit updateDataModels();
|
||||
}
|
||||
lock = false;
|
||||
}
|
||||
}
|
||||
@@ -1157,10 +1164,9 @@ void FunctionSwitchesPanel::on_startPosnCurrentIndexChanged(int index)
|
||||
if (cb && !lock) {
|
||||
lock = true;
|
||||
bool ok = false;
|
||||
int i = sender()->property("index").toInt(&ok);
|
||||
if (ok && ((model->functionSwitchStartConfig >> (2 * i)) & 0x03) != (unsigned int)index) {
|
||||
unsigned int mask = ((unsigned int) 0x03 << (2 * i));
|
||||
model->functionSwitchStartConfig = (model->functionSwitchStartConfig & ~ mask) | ((unsigned int) index << (2 * i));
|
||||
unsigned int i = sender()->property("index").toInt(&ok);
|
||||
if (ok && model->getFuncSwitchStart(i) != (unsigned int)index) {
|
||||
model->setFuncSwitchStart(i, index);
|
||||
emit modified();
|
||||
}
|
||||
lock = false;
|
||||
@@ -1178,9 +1184,8 @@ void FunctionSwitchesPanel::on_groupChanged(int value)
|
||||
lock = true;
|
||||
bool ok = false;
|
||||
int i = sender()->property("index").toInt(&ok);
|
||||
if (ok && ((model->functionSwitchGroup >> (2 * i)) & 0x03) != (unsigned int)value) {
|
||||
unsigned int mask = ((unsigned int) 0x03 << (2 * i));
|
||||
model->functionSwitchGroup = (model->functionSwitchGroup & ~ mask) | ((unsigned int) value << (2 * i));
|
||||
if (ok && model->getFuncSwitchGroup(i) != (unsigned int)value) {
|
||||
model->setFuncSwitchGroup(i, (unsigned int)value);
|
||||
update(i);
|
||||
emit modified();
|
||||
}
|
||||
@@ -1201,9 +1206,7 @@ void FunctionSwitchesPanel::on_alwaysOnGroupChanged(int value)
|
||||
int i = sender()->property("index").toInt(&ok);
|
||||
|
||||
if (ok) {
|
||||
const int grp = (model->functionSwitchGroup >> (2 * i)) & 0x03;
|
||||
unsigned int mask = ((unsigned int) 0x01 << (2 * switchcnt + grp));
|
||||
model->functionSwitchGroup = (model->functionSwitchGroup & ~ mask) | ((unsigned int) value << (2 * switchcnt + grp));
|
||||
model->setFuncSwitchAlwaysOnGroup(i, (unsigned int)value);
|
||||
update();
|
||||
emit modified();
|
||||
}
|
||||
@@ -1458,10 +1461,12 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
|
||||
|
||||
ui->trimsDisplay->setField(model.trimsDisplay, this);
|
||||
|
||||
if (Boards::getCapability(firmware->getBoard(), Board::NumFunctionSwitches) > 0)
|
||||
ui->functionSwitchesLayout->addWidget(new FunctionSwitchesPanel(this, model, generalSettings, firmware));
|
||||
//else
|
||||
// ui->functionSwitchesLayout->hide();
|
||||
if (Boards::getCapability(firmware->getBoard(), Board::FunctionSwitches) > 0) {
|
||||
funcswitches = new FunctionSwitchesPanel(this, model, generalSettings, firmware);
|
||||
ui->functionSwitchesLayout->addWidget(funcswitches);
|
||||
connect(funcswitches, &FunctionSwitchesPanel::modified, this, &SetupPanel::modified);
|
||||
connect(funcswitches, &FunctionSwitchesPanel::updateDataModels, this, &SetupPanel::onFunctionSwitchesUpdateItemModels);
|
||||
}
|
||||
|
||||
for (int i = firmware->getCapability(NumFirstUsableModule); i < firmware->getCapability(NumModules); i++) {
|
||||
modules[i] = new ModulePanel(this, model, model.moduleData[i], generalSettings, firmware, i, panelFilteredModels);
|
||||
@@ -2001,3 +2006,8 @@ void SetupPanel::onModuleUpdateItemModels()
|
||||
{
|
||||
sharedItemModels->update(AbstractItemModel::IMUE_Modules);
|
||||
}
|
||||
|
||||
void SetupPanel::onFunctionSwitchesUpdateItemModels()
|
||||
{
|
||||
sharedItemModels->update(AbstractItemModel::IMUE_FunctionSwitches);
|
||||
}
|
||||
|
||||
@@ -143,7 +143,11 @@ class FunctionSwitchesPanel : public ModelPanel
|
||||
virtual void update();
|
||||
void update(int index);
|
||||
|
||||
signals:
|
||||
void updateDataModels();
|
||||
|
||||
private slots:
|
||||
void on_nameEditingFinished();
|
||||
void on_configCurrentIndexChanged(int index);
|
||||
void on_startPosnCurrentIndexChanged(int index);
|
||||
void on_groupChanged(int value);
|
||||
@@ -207,6 +211,7 @@ class SetupPanel : public ModelPanel
|
||||
void onItemModelAboutToBeUpdated();
|
||||
void onItemModelUpdateComplete();
|
||||
void onModuleUpdateItemModels();
|
||||
void onFunctionSwitchesUpdateItemModels();
|
||||
void on_jitterFilter_currentIndexChanged(int index);
|
||||
|
||||
private:
|
||||
@@ -217,6 +222,8 @@ class SetupPanel : public ModelPanel
|
||||
QVector<QCheckBox *> centerBeepCheckboxes;
|
||||
ModulePanel * modules[CPN_MAX_MODULES + 1];
|
||||
TimerPanel * timers[CPN_MAX_TIMERS];
|
||||
FunctionSwitchesPanel * funcswitches;
|
||||
|
||||
void updateStartupSwitches();
|
||||
void updatePotWarnings();
|
||||
void updateBeepCenter();
|
||||
|
||||
@@ -369,7 +369,7 @@ QString ModelPrinter::printInputLine(const ExpoData & input)
|
||||
str += " " + flightModesStr.toHtmlEscaped();
|
||||
|
||||
if (input.swtch.type != SWITCH_TYPE_NONE)
|
||||
str += " " + tr("Switch(%1)").arg(input.swtch.toString(getCurrentBoard(), &generalSettings)).toHtmlEscaped();
|
||||
str += " " + tr("Switch(%1)").arg(input.swtch.toString(getCurrentBoard(), &generalSettings, &model)).toHtmlEscaped();
|
||||
|
||||
|
||||
if (firmware->getCapability(VirtualInputs)) {
|
||||
@@ -418,7 +418,7 @@ QString ModelPrinter::printMixerLine(const MixData & mix, bool showMultiplex, in
|
||||
str += " " + flightModesStr.toHtmlEscaped();
|
||||
|
||||
if (mix.swtch.type != SWITCH_TYPE_NONE)
|
||||
str += " " + tr("Switch(%1)").arg(mix.swtch.toString(getCurrentBoard(), &generalSettings)).toHtmlEscaped();
|
||||
str += " " + tr("Switch(%1)").arg(mix.swtch.toString(getCurrentBoard(), &generalSettings, &model)).toHtmlEscaped();
|
||||
|
||||
if (mix.carryTrim > 0)
|
||||
str += " " + tr("NoTrim");
|
||||
@@ -650,7 +650,7 @@ QString ModelPrinter::printCurveName(int idx)
|
||||
|
||||
QString ModelPrinter::printCurve(int idx)
|
||||
{
|
||||
const CurveData & curve = model.curves[idx];
|
||||
const CurveData & curve = model.curves[idx];
|
||||
return QString("%1 %2").arg(curve.typeToString()).arg(curve.pointsToString());
|
||||
}
|
||||
|
||||
@@ -759,7 +759,7 @@ QString ModelPrinter::printSwitchWarnings()
|
||||
uint64_t switchStates = model.switchWarningStates;
|
||||
uint64_t value;
|
||||
|
||||
for (int idx=0; idx<board.getCapability(Board::Switches); idx++) {
|
||||
for (int idx=0; idx<board.getCapability(Board::Switches) + board.getCapability(Board::FunctionSwitches); idx++) {
|
||||
Board::SwitchInfo switchInfo = Boards::getSwitchInfo(board.getBoardType(), idx);
|
||||
switchInfo.config = Board::SwitchType(generalSettings.switchConfig[idx]);
|
||||
if (switchInfo.config == Board::SWITCH_NOT_AVAILABLE || switchInfo.config == Board::SWITCH_TOGGLE) {
|
||||
|
||||
@@ -277,9 +277,10 @@ QString MultiModelPrinter::print(QTextDocument * document)
|
||||
if (firmware->getCapability(Timers)) {
|
||||
str.append(printTimers());
|
||||
}
|
||||
if (Boards::getCapability(firmware->getBoard(), Board::NumFunctionSwitches)) {
|
||||
if (Boards::getCapability(firmware->getBoard(), Board::FunctionSwitches)) {
|
||||
str.append(printFunctionSwitches());
|
||||
}
|
||||
|
||||
str.append(printModules());
|
||||
if (firmware->getCapability(Heli))
|
||||
str.append(printHeliSetup());
|
||||
@@ -942,51 +943,59 @@ QString MultiModelPrinter::printChecklist()
|
||||
return str;
|
||||
}
|
||||
|
||||
QString MultiModelPrinter::printFunctionSwitches()
|
||||
{
|
||||
QString str;
|
||||
MultiColumns columns(modelPrinterMap.size());
|
||||
columns.appendSectionTableStart();
|
||||
|
||||
int numFS = Boards::getCapability(firmware->getBoard(), Board::NumFunctionSwitches);
|
||||
int colwidth = 80 / numFS;
|
||||
QString MultiModelPrinter::printFunctionSwitches()
|
||||
{
|
||||
QString str;
|
||||
MultiColumns columns(modelPrinterMap.size());
|
||||
columns.appendSectionTableStart();
|
||||
|
||||
QStringList headings = { tr("Function Switches") };
|
||||
for (int i = 0; i < numFS; i++) {
|
||||
headings << tr("Switch %1").arg(i + 1);
|
||||
}
|
||||
columns.appendRowHeader(headings);
|
||||
int numFS = Boards::getCapability(firmware->getBoard(), Board::FunctionSwitches);
|
||||
int colwidth = 80 / numFS;
|
||||
|
||||
columns.appendRowStart(tr("Name"), 20);
|
||||
QStringList headings = { tr("Function Switches") };
|
||||
for (int i = 0; i < numFS; i++) {
|
||||
headings << tr("Switch %1").arg(i + 1);
|
||||
}
|
||||
columns.appendRowHeader(headings);
|
||||
|
||||
for (int i = 0; i < numFS; i++) {
|
||||
COMPARECELLWIDTH(model->functionSwitchNames[i], colwidth);
|
||||
}
|
||||
columns.appendRowStart(tr("Name"), 20);
|
||||
|
||||
columns.appendRowEnd();
|
||||
columns.appendRowStart(tr("Type"), 20);
|
||||
for (int i = 0; i < numFS; i++) {
|
||||
COMPARECELLWIDTH(model->functionSwitchNames[i], colwidth);
|
||||
}
|
||||
|
||||
for (int i = 0; i < numFS; i++) {
|
||||
COMPARECELLWIDTH(model->funcSwitchConfigToString((unsigned int)i), colwidth);
|
||||
}
|
||||
columns.appendRowEnd();
|
||||
columns.appendRowStart(tr("Type"), 20);
|
||||
|
||||
columns.appendRowEnd();
|
||||
columns.appendRowStart(tr("Start"), 20);
|
||||
for (int i = 0; i < numFS; i++) {
|
||||
COMPARECELLWIDTH(model->funcSwitchConfigToString(model->getFuncSwitchConfig((unsigned int)i)), colwidth);
|
||||
}
|
||||
|
||||
for (int i = 0; i < numFS; i++) {
|
||||
COMPARECELLWIDTH(model->funcSwitchStartToString((unsigned int)i), colwidth);
|
||||
}
|
||||
columns.appendRowEnd();
|
||||
columns.appendRowStart(tr("Start"), 20);
|
||||
|
||||
columns.appendRowEnd();
|
||||
columns.appendRowStart(tr("Group"), 20);
|
||||
for (int i = 0; i < numFS; i++) {
|
||||
COMPARECELLWIDTH(model->funcSwitchStartToString(model->getFuncSwitchStart((unsigned int)i)), colwidth);
|
||||
}
|
||||
|
||||
for (int i = 0; i < numFS; i++) {
|
||||
COMPARECELLWIDTH((model->functionSwitchGroup >> (2 * i)) & 0x03, colwidth);
|
||||
}
|
||||
columns.appendRowEnd();
|
||||
columns.appendRowStart(tr("Group"), 20);
|
||||
|
||||
columns.appendRowEnd();
|
||||
for (int i = 0; i < numFS; i++) {
|
||||
COMPARECELLWIDTH(model->getFuncSwitchGroup((unsigned int)i), colwidth);
|
||||
}
|
||||
|
||||
columns.appendTableEnd();
|
||||
str.append(columns.print());
|
||||
return str;
|
||||
}
|
||||
columns.appendRowEnd();
|
||||
columns.appendRowStart(tr("Always On"), 20);
|
||||
|
||||
for (int i = 0; i < numFS; i++) {
|
||||
COMPARECELLWIDTH((model->getFuncSwitchAlwaysOnGroup((unsigned int)i) == 0 ? "No" : "Yes"), colwidth);
|
||||
}
|
||||
|
||||
columns.appendRowEnd();
|
||||
|
||||
columns.appendTableEnd();
|
||||
str.append(columns.print());
|
||||
return str;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user