1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-16 04:45:17 +03:00

Merge branch '2.3' into 3djc/T-Lite

# Conflicts:
#	companion/src/firmwares/boards.h
#	companion/src/firmwares/opentx/opentxeeprom.h
#	radio/src/gui/common/stdlcd/radio_hardware.cpp
#	radio/src/targets/common/arm/stm32/adc_driver.cpp
#	radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt
#	radio/src/targets/taranis/board.h
#	radio/src/targets/taranis/hal.h
#	radio/src/targets/taranis/keys_driver.cpp
#	radio/src/targets/taranis/lcd_driver_spi.cpp
This commit is contained in:
Kilrah 2021-01-15 20:17:02 +01:00
commit c34ed67343
160 changed files with 3911 additions and 1408 deletions

View file

@ -2,7 +2,7 @@ project(OpenTX)
set(VERSION_MAJOR "2")
set(VERSION_MINOR "3")
set(VERSION_REVISION "11")
set(VERSION_REVISION "12")
set(VERSION_SUFFIX $ENV{OPENTX_VERSION_SUFFIX})
set(VERSION_FAMILY ${VERSION_MAJOR}.${VERSION_MINOR})
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}${VERSION_SUFFIX})

View file

@ -2069,3 +2069,32 @@ Raoul Piccioli
Uwe Probst
Glendon Satchell
Trevor Collins
Horst Grashauser
Miguel José Cárdenas Herrera
Mike Jennings
José Bernardo
Carlos Dangle
Gordon Evans
Pablo Peinado Abad
Carl Payne
Adam Sosnowski
Гасак Сергей
SaltCtyRacingFPV
Georg Bernhardt
James Mildenhall
Dave Plummer
Ivan Mokris
Patrick Daniels
Stuart Olson
Cory Znebel
Andrey Yarovoy
Christian Pons
Burt Pickard-Richardson
Michal Mesaros
Conrad Young
Martin Mathes
Jens Rainer Hansen
Mark Trible
Marc Dubois
Alan Wilkins
Daniel Hryciuk

View file

@ -347,6 +347,8 @@ elseif(PCB STREQUAL X7 AND PCBREV STREQUAL TLITE)
set(FLAVOUR tlite)
elseif(PCB STREQUAL X7 AND PCBREV STREQUAL TX12)
set(FLAVOUR tx12)
elseif(PCB STREQUAL X7 AND PCBREV STREQUAL T8)
set(FLAVOUR t8)
elseif(PCB STREQUAL X9D+ AND PCBREV STREQUAL 2019)
set(FLAVOUR x9d+2019)
elseif(PCB STREQUAL X10 AND PCBREV STREQUAL EXPRESS)

View file

@ -200,6 +200,18 @@
<file>images/simulator/TX12/right-mdl.png</file>
<file>images/simulator/TX12/bottom.png</file>
<file>images/simulator/TX12/top.png</file>
<file>images/simulator/T8/left.png</file>
<file>images/simulator/T8/left-pageup.png</file>
<file>images/simulator/T8/left-pagedn.png</file>
<file>images/simulator/T8/left-rtn.png</file>
<file>images/simulator/T8/left-sys.png</file>
<file>images/simulator/T8/right.png</file>
<file>images/simulator/T8/right-ent.png</file>
<file>images/simulator/T8/right-mdl.png</file>
<file>images/simulator/T8/right-up.png</file>
<file>images/simulator/T8/right-dn.png</file>
<file>images/simulator/T8/bottom.png</file>
<file>images/simulator/T8/top.png</file>
<file>images/simulator/JumperT16/left.png</file>
<file>images/simulator/JumperT16/right.png</file>
<file>images/simulator/JumperT16/top.png</file>

View file

@ -1,12 +1,12 @@
set(datamodels_SRCS
rawitemdatamodels.cpp
rawitemfilteredmodel.cpp
compounditemmodels.cpp
filtereditemmodels.cpp
)
set(datamodels_HDRS
rawitemdatamodels.h
rawitemfilteredmodel.h
compounditemmodels.h
filtereditemmodels.h
)
qt5_wrap_cpp(datamodels_SRCS ${datamodels_HDRS})

View file

@ -0,0 +1,705 @@
/*
* 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 "compounditemmodels.h"
#include "generalsettings.h"
#include "eeprominterface.h"
#include "modeldata.h"
#include "adjustmentreference.h"
// static
QString AbstractItemModel::idToString(const int value)
{
switch (value) {
case IMID_Unknown:
return "Unknown";
case IMID_RawSource:
return "RawSource";
case IMID_RawSwitch:
return "RawSwitch";
case IMID_Curve:
return "Curve";
case IMID_GVarRef:
return "GVarRef";
case IMID_ThrSource:
return "ThrSource";
case IMID_CustomFuncAction:
return "CustomFuncAction";
case IMID_CustomFuncResetParam:
return "CustomFuncResetParam";
case IMID_TeleSource:
return "TeleSource";
case IMID_CurveRefType:
return "CurveRefType";
case IMID_CurveRefFunc:
return "CurveRefFunc";
default:
return "Custom";
}
}
// static
void AbstractItemModel::dumpItemModelContents(AbstractItemModel * itemModel)
{
if (itemModel) {
qDebug() << "id:" << itemModel->getId() << "name:" << itemModel->getName();
for (int i = 0; i < itemModel->rowCount(); ++i) {
qDebug() << "row:" << i
<< "text:" << itemModel->data(itemModel->index(i, 0), Qt::DisplayRole).toString()
<< "id:" << itemModel->data(itemModel->index(i, 0), AbstractItemModel::IMDR_Id).toInt()
<< "avail:" << itemModel->data(itemModel->index(i, 0), AbstractItemModel::IMDR_Available).toBool()
<< "flags:" << itemModel->data(itemModel->index(i, 0), AbstractItemModel::IMDR_Flags).toInt()
<< "type:" << itemModel->data(itemModel->index(i, 0), AbstractItemModel::IMDR_Type).toInt();
}
}
else
qDebug() << "Error: model not of class AbstractItemModel";
}
//
// AbstractStaticItemModel
//
void AbstractStaticItemModel::loadItemList()
{
foreach (const ListItem *item, itemList) {
QStandardItem * modelItem = new QStandardItem();
modelItem->setText(item->text);
modelItem->setData(item->id, IMDR_Id);
modelItem->setData(item->type, IMDR_Type);
modelItem->setData(item->flags, IMDR_Flags);
modelItem->setData(item->isAvailable, IMDR_Available);
appendRow(modelItem);
}
itemList.clear();
};
//
// RawSourceItemModel
//
RawSourceItemModel::RawSourceItemModel(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_RawSource);
setUpdateMask(IMUE_All &~ (IMUE_Curves | IMUE_Scripts));
addItems(SOURCE_TYPE_NONE, RawSource::NoneGroup, 1);
for (int i = 0; i < firmware->getCapability(LuaScripts); i++)
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));
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));
addItems(SOURCE_TYPE_CH, RawSource::SourcesGroup, firmware->getCapability(Outputs));
addItems(SOURCE_TYPE_SPECIAL, RawSource::TelemGroup, 5);
addItems(SOURCE_TYPE_TELEMETRY, RawSource::TelemGroup, firmware->getCapability(Sensors) * 3);
addItems(SOURCE_TYPE_GVAR, RawSource::GVarsGroup, firmware->getCapability(Gvars));
}
void RawSourceItemModel::setDynamicItemData(QStandardItem * item, const RawSource & src) const
{
item->setText(src.toString(modelData, generalSettings, boardType));
item->setData(src.isAvailable(modelData, generalSettings, boardType), IMDR_Available);
}
void RawSourceItemModel::addItems(const RawSourceType & type, const int group, const int count, const int start)
{
for (int i = start; i < start + count; i++) {
const RawSource src = RawSource(type, i);
QStandardItem * modelItem = new QStandardItem();
modelItem->setData(src.toValue(), IMDR_Id);
modelItem->setData(type, IMDR_Type);
modelItem->setData(group, IMDR_Flags);
setDynamicItemData(modelItem, src);
appendRow(modelItem);
}
}
void RawSourceItemModel::update(const int event)
{
if (doUpdate(event)) {
emit aboutToBeUpdated();
for (int i = 0; i < rowCount(); ++i)
setDynamicItemData(item(i), RawSource(item(i)->data(IMDR_Id).toInt()));
emit updateComplete();
}
}
//
// RawSwitchItemModel
//
RawSwitchItemModel::RawSwitchItemModel(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_RawSwitch);
setUpdateMask(IMUE_FlightModes | IMUE_LogicalSwitches | IMUE_TeleSensors);
// Descending switch direction: NOT (!) switches
addItems(SWITCH_TYPE_ACT, -1);
addItems(SWITCH_TYPE_SENSOR, -firmware->getCapability(Sensors));
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));
// Ascending switch direction (including zero)
addItems(SWITCH_TYPE_TIMER_MODE, 5);
addItems(SWITCH_TYPE_NONE, 1);
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);
addItems(SWITCH_TYPE_SENSOR, firmware->getCapability(Sensors));
addItems(SWITCH_TYPE_ON, 1);
addItems(SWITCH_TYPE_ONE, 1);
addItems(SWITCH_TYPE_ACT, 1);
}
void RawSwitchItemModel::setDynamicItemData(QStandardItem * item, const RawSwitch & rsw) const
{
item->setText(rsw.toString(boardType, generalSettings, modelData));
item->setData(rsw.isAvailable(modelData, generalSettings, boardType), IMDR_Available);
}
void RawSwitchItemModel::addItems(const RawSwitchType & type, int count)
{
// Most RawSwitch() indices are one-based (vs. typical zero); these are exceptions to the rule:
const static QVector<int> rawSwitchIndexBaseZeroTypes = QVector<int>() << SWITCH_TYPE_NONE << SWITCH_TYPE_ON << SWITCH_TYPE_OFF << SWITCH_TYPE_TIMER_MODE;
// handle exceptions in RawSwitch() index values
const short rawIdxAdj = rawSwitchIndexBaseZeroTypes.contains(type) ? -1 : 0;
// determine cotext flags
int context = RawSwitch::AllSwitchContexts;
switch (type) {
case SWITCH_TYPE_FLIGHT_MODE:
context &= ~RawSwitch::MixesContext;
// fallthrough
case SWITCH_TYPE_VIRTUAL:
case SWITCH_TYPE_SENSOR:
context &= ~RawSwitch::GlobalFunctionsContext;
break;
case SWITCH_TYPE_TIMER_MODE:
context = RawSwitch::TimersContext;
break;
case SWITCH_TYPE_NONE:
context &= ~RawSwitch::TimersContext;
break;
case SWITCH_TYPE_ON:
case SWITCH_TYPE_ONE:
context = RawSwitch::SpecialFunctionsContext | RawSwitch::GlobalFunctionsContext;
break;
default:
break;
}
int i = (count < 0 ? count : 1);
count = (i < 0 ? 0 : count + i);
for ( ; i < count; ++i) {
RawSwitch rs(type, i + rawIdxAdj);
QStandardItem * modelItem = new QStandardItem();
modelItem->setData(rs.toValue(), IMDR_Id);
modelItem->setData(type, IMDR_Type);
modelItem->setData(context, IMDR_Flags);
setDynamicItemData(modelItem, rs);
appendRow(modelItem);
}
}
void RawSwitchItemModel::update(const int event)
{
if (doUpdate(event)) {
emit aboutToBeUpdated();
for (int i = 0; i < rowCount(); ++i)
setDynamicItemData(item(i), RawSwitch(item(i)->data(IMDR_Id).toInt()));
emit updateComplete();
}
}
//
// CurveItemModel
//
CurveItemModel::CurveItemModel(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_Curve);
if (!modelData)
return;
setUpdateMask(IMUE_Curves);
const int count = firmware->getCapability(NumCurves);
for (int i = -count ; i <= count; ++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 CurveItemModel::setDynamicItemData(QStandardItem * item, const int value) const
{
CurveReference cr = CurveReference(CurveReference::CURVE_REF_CUSTOM, value);
item->setText(cr.toString(modelData, false));
item->setData(cr.isAvailable(), IMDR_Available);
}
void CurveItemModel::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();
}
}
//
// GVarReferenceItemModel
//
GVarReferenceItemModel::GVarReferenceItemModel(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_GVarRef);
if (!modelData)
return;
setUpdateMask(IMUE_GVars | IMUE_FlightModes | IMUE_LogicalSwitches);
const int count = firmware->getCapability(Gvars);
if (count > 0) {
addItems(-count);
addItems(count);
}
}
void GVarReferenceItemModel::addItems(int count)
{
int i = (count < 0 ? count : 1);
count = (i < 0 ? 0 : count + i);
for ( ; i < count; ++i) {
QStandardItem * modelItem = new QStandardItem();
AdjustmentReference ar(AdjustmentReference::ADJUST_REF_GVAR, i);
modelItem->setData(ar.toValue(), IMDR_Id);
modelItem->setData(i < 0 ? IMDG_Negative : i > 0 ? IMDG_Positive : IMDG_None, IMDR_Flags);
setDynamicItemData(modelItem, ar);
appendRow(modelItem);
}
}
void GVarReferenceItemModel::setDynamicItemData(QStandardItem * item, const AdjustmentReference & ar) const
{
item->setText(ar.toString(modelData, false));
item->setData(ar.isAvailable(), IMDR_Available);
}
void GVarReferenceItemModel::update(const int event)
{
if (doUpdate(event)) {
emit aboutToBeUpdated();
for (int i = 0; i < rowCount(); ++i)
setDynamicItemData(item(i), AdjustmentReference(item(i)->data(IMDR_Id).toInt()));
emit updateComplete();
}
}
//
// ThrottleSourceItemModel
//
ThrottleSourceItemModel::ThrottleSourceItemModel(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_ThrSource);
if (!modelData)
return;
setUpdateMask(IMUE_Timers | IMUE_Inputs | IMUE_TeleSensors);
for (int i = 0; i < modelData->thrTraceSrcCount(); i++) {
QStandardItem * modelItem = new QStandardItem();
modelItem->setData(i, IMDR_Id);
setDynamicItemData(modelItem, i);
appendRow(modelItem);
}
}
void ThrottleSourceItemModel::setDynamicItemData(QStandardItem * item, const int value) const
{
item->setText(modelData->thrTraceSrcToString(value));
item->setData(modelData->isThrTraceSrcAvailable(generalSettings, value), IMDR_Available);
}
void ThrottleSourceItemModel::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();
}
}
//
// CustomFuncActionItemModel
//
CustomFuncActionItemModel::CustomFuncActionItemModel(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_CustomFuncAction);
setUpdateMask(IMUE_All &~ (IMUE_Curves | IMUE_Scripts));
for (int i = 0; i < AssignFunc::FuncCount; i++) {
QStandardItem * modelItem = new QStandardItem();
modelItem->setData(i, IMDR_Id);
modelItem->setData(CustomFunctionData::funcContext(i), IMDR_Flags);
setDynamicItemData(modelItem, i);
appendRow(modelItem);
}
}
void CustomFuncActionItemModel::setDynamicItemData(QStandardItem * item, const int value) const
{
item->setText(CustomFunctionData(AssignFunc(value)).funcToString(modelData));
item->setData(CustomFunctionData::isFuncAvailable(value), IMDR_Available);
}
void CustomFuncActionItemModel::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();
}
}
//
// CustomFuncResetParamItemModel
//
CustomFuncResetParamItemModel::CustomFuncResetParamItemModel(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_CustomFuncResetParam);
setUpdateMask(IMUE_TeleSensors);
for (int i = 0; i < CustomFunctionData::resetParamCount(modelData); i++) {
QStandardItem * modelItem = new QStandardItem();
modelItem->setData(i, IMDR_Id);
setDynamicItemData(modelItem, i);
appendRow(modelItem);
}
}
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);
}
void CustomFuncResetParamItemModel::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();
}
}
//
// TelemetrySourceItemModel
//
TelemetrySourceItemModel::TelemetrySourceItemModel(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_TeleSource);
if (!modelData)
return;
setUpdateMask(IMUE_TeleSensors);
const int count = firmware->getCapability(Sensors);
for (int i = -count; i <= count; ++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 TelemetrySourceItemModel::setDynamicItemData(QStandardItem * item, const int value) const
{
item->setText(SensorData::sourceToString(modelData, value));
item->setData(SensorData::isSourceAvailable(modelData, value), IMDR_Available);
}
void TelemetrySourceItemModel::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
//
CurveRefTypeItemModel::CurveRefTypeItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
Firmware * firmware, const Boards * const board, const Board::Type boardType) :
AbstractStaticItemModel(generalSettings, modelData, firmware, board, boardType)
{
setId(IMID_CurveRefType);
for (int i = 0; i <= CurveReference::MAX_CURVE_REF_TYPE; i++) {
QStandardItem * modelItem = new QStandardItem();
modelItem->setText(CurveReference::typeToString((CurveReference::CurveRefType)i));
modelItem->setData(i, IMDR_Id);
modelItem->setData(CurveReference::isTypeAvailable((CurveReference::CurveRefType)i), IMDR_Available);
appendRow(modelItem);
}
}
//
// CurveRefFuncItemModel
//
CurveRefFuncItemModel::CurveRefFuncItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
Firmware * firmware, const Boards * const board, const Board::Type boardType) :
AbstractStaticItemModel(generalSettings, modelData, firmware, board, boardType)
{
setId(IMID_CurveRefFunc);
for (int i = 1; i <= CurveReference::functionCount(); i++) {
QStandardItem * modelItem = new QStandardItem();
modelItem->setText(CurveReference::functionToString(i));
modelItem->setData(i, IMDR_Id);
modelItem->setData(CurveReference::isFunctionAvailable(i), IMDR_Available);
appendRow(modelItem);
}
}
//
// PrecisionItemModel
//
PrecisionItemModel::PrecisionItemModel(const int minDecimals, const int maxDecimals, const QString suffix, const bool placeholders) :
AbstractStaticItemModel()
{
for (int i = minDecimals, j = maxDecimals; j >= 0; i++, j--) {
QString str = QString("0.%1").arg(QString(i, '0'));
if (placeholders)
str.append(QString(j, '_'));
if (!suffix.isEmpty())
str.append(QString(" %1").arg(suffix));
QStandardItem * modelItem = new QStandardItem();
modelItem->setText(str);
modelItem->setData(i, IMDR_Id);
modelItem->setData(true, IMDR_Available);
appendRow(modelItem);
}
}
//
// CompoundItemModelFactory
//
CompoundItemModelFactory::CompoundItemModelFactory(const GeneralSettings * const generalSettings, const ModelData * const modelData) :
generalSettings(generalSettings),
modelData(modelData)
{
firmware = getCurrentFirmware();
board = new Boards(getCurrentBoard());
boardType = getCurrentBoard();
}
CompoundItemModelFactory::~CompoundItemModelFactory()
{
unregisterItemModels();
delete board;
}
void CompoundItemModelFactory::addItemModel(const int id)
{
switch (id) {
case AbstractItemModel::IMID_RawSource:
registerItemModel(new RawSourceItemModel(generalSettings, modelData, firmware, board, boardType));
break;
case AbstractItemModel::IMID_RawSwitch:
registerItemModel(new RawSwitchItemModel(generalSettings, modelData, firmware, board, boardType));
break;
case AbstractItemModel::IMID_Curve:
registerItemModel(new CurveItemModel(generalSettings, modelData, firmware, board, boardType));
break;
case AbstractItemModel::IMID_GVarRef:
registerItemModel(new GVarReferenceItemModel(generalSettings, modelData, firmware, board, boardType));
break;
case AbstractItemModel::IMID_ThrSource:
registerItemModel(new ThrottleSourceItemModel(generalSettings, modelData, firmware, board, boardType));
break;
case AbstractItemModel::IMID_CustomFuncAction:
registerItemModel(new CustomFuncActionItemModel(generalSettings, modelData, firmware, board, boardType));
break;
case AbstractItemModel::IMID_CustomFuncResetParam:
registerItemModel(new CustomFuncResetParamItemModel(generalSettings, modelData, firmware, board, boardType));
break;
case AbstractItemModel::IMID_TeleSource:
registerItemModel(new TelemetrySourceItemModel(generalSettings, modelData, firmware, board, boardType));
break;
case AbstractItemModel::IMID_CurveRefType:
registerItemModel(new CurveRefTypeItemModel(generalSettings, modelData, firmware, board, boardType));
break;
case AbstractItemModel::IMID_CurveRefFunc:
registerItemModel(new CurveRefFuncItemModel(generalSettings, modelData, firmware, board, boardType));
break;
default:
qDebug() << "Error: unknown item model: id";
break;
}
}
int CompoundItemModelFactory::registerItemModel(AbstractItemModel * itemModel)
{
if (itemModel) {
if (!isItemModelRegistered(itemModel->getId())) {
setSourceId(itemModel);
registeredItemModels.append(itemModel);
return itemModel->getId();
}
else
return itemModel->getId();
}
return -1;
}
void CompoundItemModelFactory::unregisterItemModels()
{
foreach (AbstractItemModel *itemModel, registeredItemModels) {
delete itemModel;
}
}
void CompoundItemModelFactory::unregisterItemModel(const int id)
{
AbstractItemModel * itemModel = getItemModel(id);
if (itemModel)
delete itemModel;
}
AbstractItemModel * CompoundItemModelFactory::getItemModel(const int id) const
{
foreach (AbstractItemModel * itemModel, registeredItemModels) {
if (itemModel->getId() == id)
return itemModel;
}
return nullptr;
}
bool CompoundItemModelFactory::isItemModelRegistered(const int id) const
{
foreach (AbstractItemModel * itemModel, registeredItemModels) {
if (itemModel->getId() == id)
return true;
}
return false;
}
void CompoundItemModelFactory::update(const int event)
{
foreach (AbstractItemModel * itemModel, registeredItemModels) {
itemModel->update(event);
}
}
void CompoundItemModelFactory::dumpAllItemModelContents() const
{
foreach (AbstractItemModel * itemModel, registeredItemModels) {
AbstractItemModel::dumpItemModelContents(itemModel);
}
}
void CompoundItemModelFactory::setSourceId(AbstractItemModel * itemModel)
{
if (itemModel && itemModel->getId() == AbstractItemModel::IMID_Unknown)
itemModel->setId(AbstractItemModel::IMID_ReservedCount + registeredItemModels.count());
}

View file

@ -0,0 +1,365 @@
/*
* 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 COMPOUNDITEMMODELS_H
#define COMPOUNDITEMMODELS_H
#include "rawsource.h"
#include "rawswitch.h"
#include <QStandardItemModel>
class GeneralSettings;
class ModelData;
class AdjustmentReference;
class AbstractItemModel: public QStandardItemModel
{
Q_OBJECT
public:
enum ItemModelId {
IMID_Unknown,
IMID_RawSource,
IMID_RawSwitch,
IMID_Curve,
IMID_GVarRef,
IMID_ThrSource,
IMID_CustomFuncAction,
IMID_CustomFuncResetParam,
IMID_TeleSource,
IMID_CurveRefType,
IMID_CurveRefFunc,
IMID_ReservedCount,
IMID_Custom
};
Q_ENUM(ItemModelId)
enum ItemModelDataRoles {
IMDR_Id = Qt::UserRole,
IMDR_Type,
IMDR_Flags,
IMDR_Available
};
Q_ENUM(ItemModelDataRoles)
enum ItemModelDataGroups {
IMDG_None = 0x01,
IMDG_Negative = 0x02,
IMDG_Positive = 0x04
};
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_All = IMUE_SystemRefresh | IMUE_Channels | IMUE_Curves | IMUE_FlightModes | IMUE_GVars | IMUE_Inputs |
IMUE_LogicalSwitches | IMUE_Scripts | IMUE_TeleSensors | IMUE_Timers
};
Q_ENUM(ItemModelUpdateEvent)
explicit AbstractItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
Firmware * firmware, const Boards * const board, const Board::Type boardType) :
QStandardItemModel(nullptr),
generalSettings(generalSettings),
modelData(modelData),
firmware(firmware),
board(board),
boardType(boardType),
m_id(IMID_Unknown),
m_name(""),
m_updateMask(IMUE_None)
{}
virtual ~AbstractItemModel() {}
void setId(int id) { m_id = id; }
int getId () const { return m_id; }
bool isReservedModelId() const { return m_id > IMID_Unknown && m_id < IMID_ReservedCount; }
void setName(QString name) { m_name = name; }
QString getName() const { return isReservedModelId() ? idToString(m_id) : m_name; }
void setUpdateMask(const int mask) { m_updateMask = mask; }
int getUpdateMask() const { return m_updateMask; }
inline bool doUpdate(const int event) const { return m_updateMask & event; }
AbstractItemModel * getItemModel(const int id) const;
static void dumpItemModelContents(AbstractItemModel * itemModel);
public slots:
virtual void update(const int event = IMUE_SystemRefresh) = 0;
protected:
const GeneralSettings * generalSettings;
const ModelData * modelData;
Firmware * firmware;
const Boards * board;
const Board::Type boardType;
private:
int m_id = IMID_Unknown;
QString m_name = "";
int m_updateMask = IMUE_None;
static QString idToString(const int value);
};
class AbstractStaticItemModel: public AbstractItemModel
{
Q_OBJECT
public:
explicit AbstractStaticItemModel(const GeneralSettings * const generalSettings = nullptr, const ModelData * const modelData = nullptr,
Firmware * firmware = nullptr, const Boards * const board = nullptr,
const Board::Type boardType = Board::BOARD_UNKNOWN) :
AbstractItemModel(generalSettings, modelData, firmware, board, boardType) {}
virtual ~AbstractStaticItemModel() {};
inline void appendToItemList(QString text, int id, bool isAvailable = true, int type = 0, int flags = 0)
{ itemList.append(new ListItem(text, id, isAvailable, type, flags)); }
void loadItemList();
public slots:
virtual void update(const int event) override final {}
protected:
struct ListItem
{
QString text;
int id;
bool isAvailable;
int type;
int flags;
ListItem() {}
ListItem(QString p_text, int p_id, bool p_isAvailable, int p_type, int p_flags) :
text(p_text), id(p_id), isAvailable(p_isAvailable), type(p_type), flags(p_flags) {}
};
QVector<ListItem *> itemList;
};
class AbstractDynamicItemModel: public AbstractItemModel
{
Q_OBJECT
public:
explicit AbstractDynamicItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
Firmware * firmware, const Boards * const board, const Board::Type boardType) :
AbstractItemModel(generalSettings, modelData, firmware, board, boardType) {}
virtual ~AbstractDynamicItemModel() {};
public slots:
virtual void update(const int event = IMUE_SystemRefresh) {}
signals:
void aboutToBeUpdated();
void updateComplete();
};
class RawSourceItemModel: public AbstractDynamicItemModel
{
Q_OBJECT
public:
explicit RawSourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
Firmware * firmware, const Boards * const board, const Board::Type boardType);
virtual ~RawSourceItemModel() {};
public slots:
virtual void update(const int event = IMUE_SystemRefresh) override;
protected:
virtual void setDynamicItemData(QStandardItem * item, const RawSource & src) const;
void addItems(const RawSourceType & type, const int group, const int count, const int start = 0);
};
class RawSwitchItemModel: public AbstractDynamicItemModel
{
Q_OBJECT
public:
explicit RawSwitchItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
Firmware * firmware, const Boards * const board, const Board::Type boardType);
virtual ~RawSwitchItemModel() {};
public slots:
virtual void update(const int event = IMUE_SystemRefresh) override;
protected:
virtual void setDynamicItemData(QStandardItem * item, const RawSwitch & rsw) const;
void addItems(const RawSwitchType & type, int count);
};
class CurveItemModel: public AbstractDynamicItemModel
{
Q_OBJECT
public:
explicit CurveItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
Firmware * firmware, const Boards * const board, const Board::Type boardType);
virtual ~CurveItemModel() {};
public slots:
virtual void update(const int event = IMUE_SystemRefresh) override;
protected:
virtual void setDynamicItemData(QStandardItem * item, const int value) const;
};
class GVarReferenceItemModel: public AbstractDynamicItemModel
{
Q_OBJECT
public:
explicit GVarReferenceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
Firmware * firmware, const Boards * const board, const Board::Type boardType);
virtual ~GVarReferenceItemModel() {};
public slots:
virtual void update(const int event = IMUE_SystemRefresh) override;
protected:
virtual void setDynamicItemData(QStandardItem * item, const AdjustmentReference & ar) const;
void addItems(int count);
};
class ThrottleSourceItemModel: public AbstractDynamicItemModel
{
Q_OBJECT
public:
explicit ThrottleSourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
Firmware * firmware, const Boards * const board, const Board::Type boardType);
virtual ~ThrottleSourceItemModel() {};
public slots:
virtual void update(const int event = IMUE_SystemRefresh) override;
protected:
virtual void setDynamicItemData(QStandardItem * item, const int value) const;
};
class CustomFuncActionItemModel: public AbstractDynamicItemModel
{
Q_OBJECT
public:
explicit CustomFuncActionItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
Firmware * firmware, const Boards * const board, const Board::Type boardType);
virtual ~CustomFuncActionItemModel() {};
public slots:
virtual void update(const int event = IMUE_SystemRefresh) override;
protected:
virtual void setDynamicItemData(QStandardItem * item, const int value) const;
};
class CustomFuncResetParamItemModel: public AbstractDynamicItemModel
{
Q_OBJECT
public:
explicit CustomFuncResetParamItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
Firmware * firmware, const Boards * const board, const Board::Type boardType);
virtual ~CustomFuncResetParamItemModel() {};
public slots:
virtual void update(const int event = IMUE_SystemRefresh) override;
protected:
virtual void setDynamicItemData(QStandardItem * item, const int value) const;
};
class TelemetrySourceItemModel: public AbstractDynamicItemModel
{
Q_OBJECT
public:
explicit TelemetrySourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
Firmware * firmware, const Boards * const board, const Board::Type boardType);
virtual ~TelemetrySourceItemModel() {};
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
public:
explicit CurveRefTypeItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
Firmware * firmware, const Boards * const board, const Board::Type boardType);
virtual ~CurveRefTypeItemModel() {};
};
class CurveRefFuncItemModel : public AbstractStaticItemModel
{
Q_OBJECT
public:
explicit CurveRefFuncItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
Firmware * firmware, const Boards * const board, const Board::Type boardType);
virtual ~CurveRefFuncItemModel() {};
};
class PrecisionItemModel : public AbstractStaticItemModel
{
Q_OBJECT
public:
explicit PrecisionItemModel(const int minDecimals, const int maxDecimals, const QString suffix = "", const bool placeholders = false);
virtual ~PrecisionItemModel() {};
};
//
// CompoundItemModelFactory
//
class CompoundItemModelFactory
{
public:
CompoundItemModelFactory(const GeneralSettings * const generalSettings, const ModelData * const modelData);
virtual ~CompoundItemModelFactory();
void addItemModel(const int id);
int registerItemModel(AbstractItemModel * itemModel);
void unregisterItemModels();
void unregisterItemModel(const int id);
bool isItemModelRegistered(const int id) const;
AbstractItemModel * getItemModel(const int id) const;
void update(const int event = AbstractItemModel::IMUE_SystemRefresh);
void dumpAllItemModelContents() const;
protected:
const GeneralSettings * generalSettings;
const ModelData * modelData;
Firmware * firmware;
Boards * board;
Board::Type boardType;
QVector<AbstractItemModel *> registeredItemModels;
private:
void setSourceId(AbstractItemModel * itemModel);
};
#endif // COMPOUNDITEMMODELS_H

View file

@ -0,0 +1,252 @@
/*
* 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 "filtereditemmodels.h"
FilteredItemModel::FilteredItemModel(AbstractItemModel * sourceModel, int flags) :
QSortFilterProxyModel(nullptr),
filterFlags(0),
m_id(0),
m_name("")
{
setFilterRole(AbstractItemModel::IMDR_Available);
setFilterKeyColumn(0);
setFilterFlags(flags);
setDynamicSortFilter(true);
setSourceModel(sourceModel);
AbstractDynamicItemModel * itemModel = qobject_cast<AbstractDynamicItemModel *>(sourceModel);
if (itemModel) {
connect(itemModel, &AbstractDynamicItemModel::aboutToBeUpdated, this, &FilteredItemModel::onAboutToBeUpdated);
connect(itemModel, &AbstractDynamicItemModel::updateComplete, this, &FilteredItemModel::onUpdateComplete);
}
}
void FilteredItemModel::setFilterFlags(int flags)
{
if (filterFlags != flags) {
filterFlags = flags;
invalidateFilter();
}
}
bool FilteredItemModel::filterAcceptsRow(int sourceRow, const QModelIndex & sourceParent) const
{
const QModelIndex & srcIdx = sourceModel()->index(sourceRow, 0, sourceParent);
if (!srcIdx.isValid() || !sourceModel()->data(srcIdx, filterRole()).toBool())
return false;
if (!filterFlags)
return true;
bool ok;
const int flags = sourceModel()->data(srcIdx, AbstractItemModel::IMDR_Flags).toInt(&ok);
return (ok && (!flags || (filterFlags & flags)));
}
void FilteredItemModel::update() const
{
AbstractDynamicItemModel * itemModel = qobject_cast<AbstractDynamicItemModel *>(sourceModel());
if (itemModel)
itemModel->update();
}
void FilteredItemModel::onAboutToBeUpdated()
{
emit aboutToBeUpdated();
}
void FilteredItemModel::onUpdateComplete()
{
emit updateComplete();
}
// static
void FilteredItemModel::dumpItemModelContents(FilteredItemModel * itemModel)
{
if (itemModel) {
qDebug() << "id:" << itemModel->getId() << "name:" << itemModel->getName();
for (int i = 0; i < itemModel->rowCount(); ++i) {
qDebug() << "row:" << i
<< "text:" << itemModel->data(itemModel->index(i, 0), Qt::DisplayRole).toString()
<< "id:" << itemModel->data(itemModel->index(i, 0), AbstractItemModel::IMDR_Id).toInt()
<< "avail:" << itemModel->data(itemModel->index(i, 0), AbstractItemModel::IMDR_Available).toBool()
<< "flags:" << itemModel->data(itemModel->index(i, 0), AbstractItemModel::IMDR_Flags).toInt()
<< "type:" << itemModel->data(itemModel->index(i, 0), AbstractItemModel::IMDR_Type).toInt();
}
}
else
qDebug() << "Error: model not of class FilteredItemModel";
}
//
// FilteredItemModelFactory
//
FilteredItemModelFactory::FilteredItemModelFactory()
{
}
FilteredItemModelFactory::~FilteredItemModelFactory()
{
unregisterItemModels();
}
int FilteredItemModelFactory::registerItemModel(FilteredItemModel * itemModel, const QString name, const int id)
{
if (itemModel) {
if (isItemModelRegistered(name)) {
qDebug() << "Error: item model already registered with name:" << name;
return 0;
}
else if (id > -1 && isItemModelRegistered(id)) {
qDebug() << "Error: item model already registered with id:" << id;
return 0;
}
else {
int fid = id;
if (fid < 0) {
fid = registeredItemModels.count() + 1;
AbstractItemModel * mdl = qobject_cast<AbstractItemModel *>(itemModel->sourceModel());
if (mdl) {
fid += mdl->getId() * 128;
}
}
itemModel->setId(fid);
itemModel->setName(name);
registeredItemModels.append(itemModel);
return fid;
}
}
qDebug() << "Error: invalid filtered item model pointer";
return 0;
}
void FilteredItemModelFactory::unregisterItemModels()
{
foreach (FilteredItemModel * itemModel, registeredItemModels) {
delete itemModel;
}
}
void FilteredItemModelFactory::unregisterItemModel(const int id)
{
FilteredItemModel * itemModel = getItemModel(id);
if (itemModel)
delete itemModel;
}
bool FilteredItemModelFactory::isItemModelRegistered(const int id) const
{
return getItemModel(id);
}
bool FilteredItemModelFactory::isItemModelRegistered(const QString name) const
{
return getItemModel(name);
}
FilteredItemModel * FilteredItemModelFactory::getItemModel(const int id) const
{
foreach (FilteredItemModel * itemModel, registeredItemModels) {
if (itemModel->getId() == id)
return itemModel;
}
return nullptr;
}
FilteredItemModel * FilteredItemModelFactory::getItemModel(const QString name) const
{
foreach (FilteredItemModel * itemModel, registeredItemModels) {
if (itemModel->getName() == name)
return itemModel;
}
return nullptr;
}
void FilteredItemModelFactory::update()
{
foreach (FilteredItemModel * itemModel, registeredItemModels) {
itemModel->update();
}
}
void FilteredItemModelFactory::dumpItemModelContents(const int id) const
{
FilteredItemModel::dumpItemModelContents(getItemModel(id));
}
void FilteredItemModelFactory::dumpItemModelContents(const QString name) const
{
FilteredItemModel::dumpItemModelContents(getItemModel(name));
}
void FilteredItemModelFactory::dumpAllItemModelContents() const
{
foreach (FilteredItemModel * itemModel, registeredItemModels) {
FilteredItemModel::dumpItemModelContents(itemModel);
}
}
//
// CurveRefFilteredFactory
//
CurveRefFilteredFactory::CurveRefFilteredFactory(CompoundItemModelFactory * sharedItemModels, const int curveFlags, const int gvarRefFlags)
{
if (!sharedItemModels) {
qDebug() << "Error: invalid compound item model factory pointer";
return;
}
registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_Curve), curveFlags),
fidToString(CRFIM_CURVE), CRFIM_CURVE);
registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_GVarRef), gvarRefFlags),
fidToString(CRFIM_GVARREF), CRFIM_GVARREF);
registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_CurveRefType)),
fidToString(CRFIM_TYPE), CRFIM_TYPE);
registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_CurveRefFunc)),
fidToString(CRFIM_FUNC), CRFIM_FUNC);
}
CurveRefFilteredFactory::~CurveRefFilteredFactory()
{
}
// static
QString CurveRefFilteredFactory::fidToString(const int value)
{
switch(value) {
case CRFIM_CURVE:
return "Curves";
case CRFIM_GVARREF:
return "Global Variables";
case CRFIM_TYPE:
return "Types";
case CRFIM_FUNC:
return "Functions";
default:
return CPN_STR_UNKNOWN_ITEM;
}
}

View file

@ -0,0 +1,115 @@
/*
* 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 FILTEREDITEMMODELS_H
#define FILTEREDITEMMODELS_H
#include "compounditemmodels.h"
#include <QObject>
#include <QSortFilterProxyModel>
#include <QString>
class FilteredItemModel: public QSortFilterProxyModel
{
Q_OBJECT
public:
enum DataFilters {
AllFilter = AbstractItemModel::IMDG_Negative | AbstractItemModel::IMDG_None | AbstractItemModel::IMDG_Positive,
AllExcludeNoneFilter = AllFilter &~ AbstractItemModel::IMDG_None,
NegativeFilter = AbstractItemModel::IMDG_Negative | AbstractItemModel::IMDG_None,
NegativeExcludeNoneFilter = AbstractItemModel::IMDG_Negative,
PositiveFilter = AbstractItemModel::IMDG_Positive | AbstractItemModel::IMDG_None,
PositiveExcludeNoneFilter = AbstractItemModel::IMDG_Positive
};
Q_ENUM(DataFilters)
explicit FilteredItemModel(AbstractItemModel * sourceModel, int flags);
explicit FilteredItemModel(AbstractItemModel * sourceModel) :
FilteredItemModel(sourceModel, 0) {}
virtual ~FilteredItemModel() {};
void setId(int id) { m_id = id; }
int getId() const { return m_id; };
void setName(QString name) { m_name = name; }
QString getName() const { return m_name; }
static void dumpItemModelContents(FilteredItemModel * itemModel);
public slots:
void setFilterFlags(int flags);
void update() const;
void onAboutToBeUpdated();
void onUpdateComplete();
signals:
void aboutToBeUpdated();
void updateComplete();
protected:
bool filterAcceptsRow(int sourceRow, const QModelIndex & sourceParent) const override;
int filterFlags;
private:
int m_id = 0;
QString m_name = "";
};
class FilteredItemModelFactory
{
public:
explicit FilteredItemModelFactory();
virtual ~FilteredItemModelFactory();
int registerItemModel(FilteredItemModel * itemModel, const QString name, const int id = -1);
void unregisterItemModels();
void unregisterItemModel(const int id);
bool isItemModelRegistered(const int id) const;
bool isItemModelRegistered(const QString name) const;
FilteredItemModel * getItemModel(const int id) const;
FilteredItemModel * getItemModel(const QString name) const;
void update();
void dumpItemModelContents(const int id) const;
void dumpItemModelContents(const QString name) const;
void dumpAllItemModelContents() const;
protected:
QVector<FilteredItemModel *> registeredItemModels;
};
class CurveRefFilteredFactory : public FilteredItemModelFactory
{
public:
enum FilteredItemModelId {
CRFIM_CURVE,
CRFIM_GVARREF,
CRFIM_TYPE,
CRFIM_FUNC
};
explicit CurveRefFilteredFactory(CompoundItemModelFactory * sharedItemModels, const int curveFlags = 0, const int gvarRefFlags = 0);
virtual ~CurveRefFilteredFactory();
static QString fidToString(const int value);
};
#endif // FILTEREDITEMMODELS_H

View file

@ -1,264 +0,0 @@
/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "rawitemdatamodels.h"
#include "generalsettings.h"
#include "eeprominterface.h"
#include "modeldata.h"
RawSourceItemModel::RawSourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent) :
AbstractRawItemDataModel(generalSettings, modelData, parent)
{
const Boards board = Boards(getCurrentBoard());
Firmware * fw = getCurrentFirmware();
addItems(SOURCE_TYPE_NONE, RawSource::NoneGroup, 1);
for (int i = 0; i < fw->getCapability(LuaScripts); i++)
addItems(SOURCE_TYPE_LUA_OUTPUT, RawSource::ScriptsGroup, fw->getCapability(LuaOutputsPerScript), i * 16);
addItems(SOURCE_TYPE_VIRTUAL_INPUT, RawSource::InputsGroup, fw->getCapability(VirtualInputs));
addItems(SOURCE_TYPE_STICK, RawSource::SourcesGroup, board.getCapability(Board::MaxAnalogs));
addItems(SOURCE_TYPE_ROTARY_ENCODER, RawSource::SourcesGroup, fw->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));
addItems(SOURCE_TYPE_CUSTOM_SWITCH, RawSource::SwitchesGroup, fw->getCapability(LogicalSwitches));
addItems(SOURCE_TYPE_CYC, RawSource::SourcesGroup, CPN_MAX_CYC);
addItems(SOURCE_TYPE_PPM, RawSource::SourcesGroup, fw->getCapability(TrainerInputs));
addItems(SOURCE_TYPE_CH, RawSource::SourcesGroup, fw->getCapability(Outputs));
addItems(SOURCE_TYPE_SPECIAL, RawSource::TelemGroup, 5);
addItems(SOURCE_TYPE_TELEMETRY, RawSource::TelemGroup, fw->getCapability(Sensors) * 3);
addItems(SOURCE_TYPE_GVAR, RawSource::GVarsGroup, fw->getCapability(Gvars));
}
void RawSourceItemModel::setDynamicItemData(QStandardItem * item, const RawSource & src) const
{
Board::Type board = getCurrentBoard();
item->setText(src.toString(modelData, generalSettings, board));
item->setData(src.isAvailable(modelData, generalSettings, board), IsAvailableRole);
}
void RawSourceItemModel::addItems(const RawSourceType & type, const int group, const int count, const int start)
{
for (int i = start; i < start + count; i++) {
const RawSource src = RawSource(type, i);
QStandardItem * modelItem = new QStandardItem();
modelItem->setData(src.toValue(), ItemIdRole);
modelItem->setData(type, ItemTypeRole);
modelItem->setData(group, ItemFlagsRole);
setDynamicItemData(modelItem, src);
appendRow(modelItem);
}
}
void RawSourceItemModel::update()
{
emit dataAboutToBeUpdated();
for (int i = 0; i < rowCount(); ++i)
setDynamicItemData(item(i), RawSource(item(i)->data(ItemIdRole).toInt()));
emit dataUpdateComplete();
}
//
// RawSwitchItemModel
//
RawSwitchItemModel::RawSwitchItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent) :
AbstractRawItemDataModel(generalSettings, modelData, parent)
{
Boards board = Boards(getCurrentBoard());
Firmware * fw = getCurrentFirmware();
// Descending switch direction: NOT (!) switches
addItems(SWITCH_TYPE_ACT, -1);
addItems(SWITCH_TYPE_SENSOR, -fw->getCapability(Sensors));
addItems(SWITCH_TYPE_TELEMETRY, -1);
addItems(SWITCH_TYPE_FLIGHT_MODE, -fw->getCapability(FlightModes));
addItems(SWITCH_TYPE_VIRTUAL, -fw->getCapability(LogicalSwitches));
addItems(SWITCH_TYPE_ROTARY_ENCODER, -fw->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));
// Ascending switch direction (including zero)
addItems(SWITCH_TYPE_TIMER_MODE, 5);
addItems(SWITCH_TYPE_NONE, 1);
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, fw->getCapability(RotaryEncoders));
addItems(SWITCH_TYPE_VIRTUAL, fw->getCapability(LogicalSwitches));
addItems(SWITCH_TYPE_FLIGHT_MODE, fw->getCapability(FlightModes));
addItems(SWITCH_TYPE_TELEMETRY, 1);
addItems(SWITCH_TYPE_SENSOR, fw->getCapability(Sensors));
addItems(SWITCH_TYPE_ON, 1);
addItems(SWITCH_TYPE_ONE, 1);
addItems(SWITCH_TYPE_ACT, 1);
}
void RawSwitchItemModel::setDynamicItemData(QStandardItem * item, const RawSwitch & rsw) const
{
const Board::Type board = getCurrentBoard();
item->setText(rsw.toString(board, generalSettings, modelData));
item->setData(rsw.isAvailable(modelData, generalSettings, board), IsAvailableRole);
}
void RawSwitchItemModel::addItems(const RawSwitchType & type, int count)
{
// Most RawSwitch() indices are one-based (vs. typical zero); these are exceptions to the rule:
const static QVector<int> rawSwitchIndexBaseZeroTypes = QVector<int>() << SWITCH_TYPE_NONE << SWITCH_TYPE_ON << SWITCH_TYPE_OFF << SWITCH_TYPE_TIMER_MODE;
// handle exceptions in RawSwitch() index values
const short rawIdxAdj = rawSwitchIndexBaseZeroTypes.contains(type) ? -1 : 0;
// determine cotext flags
int context = RawSwitch::AllSwitchContexts;
switch (type) {
case SWITCH_TYPE_FLIGHT_MODE:
context &= ~RawSwitch::MixesContext;
// fallthrough
case SWITCH_TYPE_VIRTUAL:
case SWITCH_TYPE_SENSOR:
context &= ~RawSwitch::GlobalFunctionsContext;
break;
case SWITCH_TYPE_TIMER_MODE:
context = RawSwitch::TimersContext;
break;
case SWITCH_TYPE_NONE:
context &= ~RawSwitch::TimersContext;
break;
case SWITCH_TYPE_ON:
case SWITCH_TYPE_ONE:
context = RawSwitch::SpecialFunctionsContext | RawSwitch::GlobalFunctionsContext;
break;
default:
break;
}
int i = (count < 0 ? count : 1);
count = (i < 0 ? 0 : count + i);
for ( ; i < count; ++i) {
RawSwitch rs(type, i + rawIdxAdj);
QStandardItem * modelItem = new QStandardItem();
modelItem->setData(rs.toValue(), ItemIdRole);
modelItem->setData(type, ItemTypeRole);
modelItem->setData(context, ItemFlagsRole);
setDynamicItemData(modelItem, rs);
appendRow(modelItem);
}
}
void RawSwitchItemModel::update()
{
emit dataAboutToBeUpdated();
for (int i = 0; i < rowCount(); ++i)
setDynamicItemData(item(i), RawSwitch(item(i)->data(ItemIdRole).toInt()));
emit dataUpdateComplete();
}
//
// CurveItemModel
//
CurveItemModel::CurveItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent) :
AbstractRawItemDataModel(generalSettings, modelData, parent)
{
const int count = getCurrentFirmware()->getCapability(NumCurves);
for (int i = -count ; i <= count; ++i) {
QStandardItem * modelItem = new QStandardItem();
modelItem->setData(i, ItemIdRole);
int flags;
if (i < 0)
flags = DataGroups::NegativeGroup;
else if (i > 0)
flags = DataGroups::PositiveGroup;
else
flags = DataGroups::NoneGroup;
modelItem->setData(flags, ItemFlagsRole);
setDynamicItemData(modelItem, i);
appendRow(modelItem);
}
}
void CurveItemModel::setDynamicItemData(QStandardItem * item, int index) const
{
item->setText(CurveReference(CurveReference::CURVE_REF_CUSTOM, index).toString(modelData, false));
item->setData(true, IsAvailableRole);
}
void CurveItemModel::update()
{
emit dataAboutToBeUpdated();
for (int i = 0; i < rowCount(); ++i)
setDynamicItemData(item(i), item(i)->data(ItemIdRole).toInt());
emit dataUpdateComplete();
}
//
// CommonItemModels
//
CommonItemModels::CommonItemModels(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent) :
QObject(parent)
{
m_rawSourceItemModel = new RawSourceItemModel(generalSettings, modelData, parent);
m_rawSwitchItemModel = new RawSwitchItemModel(generalSettings, modelData, parent);
m_curveItemModel = new CurveItemModel(generalSettings, modelData, parent);
}
CommonItemModels::~CommonItemModels()
{
}
void CommonItemModels::update(const RadioModelObjects radioModelObjects)
{
switch (radioModelObjects) {
case RMO_CHANNELS:
case RMO_INPUTS:
case RMO_TELEMETRY_SENSORS:
case RMO_TIMERS:
m_rawSourceItemModel->update();
break;
case RMO_FLIGHT_MODES:
case RMO_GLOBAL_VARIABLES:
case RMO_LOGICAL_SWITCHES:
m_rawSourceItemModel->update();
m_rawSwitchItemModel->update();
break;
case RMO_CURVES:
m_curveItemModel->update();
break;
case RMO_SCRIPTS:
// no need to refresh
break;
default:
qDebug() << "Unknown RadioModelObject:" << radioModelObjects;
}
}

View file

@ -1,140 +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 RAWITEMDATAMODELS_H
#define RAWITEMDATAMODELS_H
#include "rawsource.h"
#include "rawswitch.h"
#include <QStandardItemModel>
class GeneralSettings;
class ModelData;
class AbstractRawItemDataModel: public QStandardItemModel
{
Q_OBJECT
public:
enum DataRoles { ItemIdRole = Qt::UserRole, ItemTypeRole, ItemFlagsRole, IsAvailableRole };
Q_ENUM(DataRoles)
enum DataGroups {
NoneGroup = 0x01,
NegativeGroup = 0x02,
PositiveGroup = 0x04
};
Q_ENUM(DataGroups)
explicit AbstractRawItemDataModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr) :
QStandardItemModel(parent),
generalSettings(generalSettings),
modelData(modelData)
{}
public slots:
virtual void update() = 0;
signals:
void dataAboutToBeUpdated();
void dataUpdateComplete();
protected:
const GeneralSettings * generalSettings;
const ModelData * modelData;
};
class RawSourceItemModel: public AbstractRawItemDataModel
{
Q_OBJECT
public:
explicit RawSourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr);
public slots:
void update() override;
protected:
void setDynamicItemData(QStandardItem * item, const RawSource & src) const;
void addItems(const RawSourceType & type, const int group, const int count, const int start = 0);
};
class RawSwitchItemModel: public AbstractRawItemDataModel
{
Q_OBJECT
public:
explicit RawSwitchItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr);
public slots:
void update() override;
protected:
void setDynamicItemData(QStandardItem * item, const RawSwitch & rsw) const;
void addItems(const RawSwitchType & type, int count);
};
class CurveItemModel: public AbstractRawItemDataModel
{
Q_OBJECT
public:
explicit CurveItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr);
public slots:
void update() override;
protected:
void setDynamicItemData(QStandardItem * item, int index) const;
};
class CommonItemModels: public QObject
{
Q_OBJECT
public:
enum RadioModelObjects {
RMO_CHANNELS,
RMO_CURVES,
RMO_FLIGHT_MODES,
RMO_GLOBAL_VARIABLES,
RMO_INPUTS,
RMO_LOGICAL_SWITCHES,
RMO_SCRIPTS,
RMO_TELEMETRY_SENSORS,
RMO_TIMERS
};
Q_ENUM(RadioModelObjects)
explicit CommonItemModels(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr);
~CommonItemModels();
void update(const RadioModelObjects radioModelObjects);
RawSourceItemModel * rawSourceItemModel() const { return m_rawSourceItemModel; }
RawSwitchItemModel * rawSwitchItemModel() const { return m_rawSwitchItemModel; }
CurveItemModel * curveItemModel() const { return m_curveItemModel; }
private:
RawSourceItemModel *m_rawSourceItemModel;
RawSwitchItemModel *m_rawSwitchItemModel;
CurveItemModel *m_curveItemModel;
};
#endif // RAWITEMDATAMODELS_H

View file

@ -1,77 +0,0 @@
/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "rawitemfilteredmodel.h"
RawItemFilteredModel::RawItemFilteredModel(QAbstractItemModel * sourceModel, int flags, QObject * parent) :
QSortFilterProxyModel(parent),
filterFlags(0)
{
setFilterRole(AbstractRawItemDataModel::IsAvailableRole);
setFilterKeyColumn(0);
setFilterFlags(flags);
setDynamicSortFilter(true);
setSourceModel(sourceModel);
AbstractRawItemDataModel * itemModel = qobject_cast<AbstractRawItemDataModel *>(sourceModel);
if (itemModel) {
connect(itemModel, &AbstractRawItemDataModel::dataAboutToBeUpdated, this, &RawItemFilteredModel::onDataAboutToBeUpdated);
connect(itemModel, &AbstractRawItemDataModel::dataUpdateComplete, this, &RawItemFilteredModel::onDataUpdateComplete);
}
}
void RawItemFilteredModel::setFilterFlags(int flags)
{
if (filterFlags != flags) {
filterFlags = flags;
invalidateFilter();
}
}
bool RawItemFilteredModel::filterAcceptsRow(int sourceRow, const QModelIndex & sourceParent) const
{
const QModelIndex & srcIdx = sourceModel()->index(sourceRow, 0, sourceParent);
if (!srcIdx.isValid() || !sourceModel()->data(srcIdx, filterRole()).toBool())
return false;
if (!filterFlags)
return true;
bool ok;
const int flags = sourceModel()->data(srcIdx, AbstractRawItemDataModel::ItemFlagsRole).toInt(&ok);
return (ok && (!flags || (filterFlags & flags)));
}
void RawItemFilteredModel::update() const
{
AbstractRawItemDataModel * itemModel = qobject_cast<AbstractRawItemDataModel *>(sourceModel());
if (itemModel)
itemModel->update();
}
void RawItemFilteredModel::onDataAboutToBeUpdated()
{
emit dataAboutToBeUpdated();
}
void RawItemFilteredModel::onDataUpdateComplete()
{
emit dataUpdateComplete();
}

View file

@ -1,63 +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 RAWITEMFILTEREDMODEL_H
#define RAWITEMFILTEREDMODEL_H
#include "rawitemdatamodels.h"
#include <QSortFilterProxyModel>
class GeneralSettings;
class ModelData;
class RawItemFilteredModel: public QSortFilterProxyModel
{
Q_OBJECT
public:
enum DataFilters {
AllFilter = AbstractRawItemDataModel::NegativeGroup | AbstractRawItemDataModel::NoneGroup | AbstractRawItemDataModel::PositiveGroup,
AllExcludeNoneFilter = AllFilter &~ AbstractRawItemDataModel::NoneGroup,
NegativeFilter = AbstractRawItemDataModel::NegativeGroup | AbstractRawItemDataModel::NoneGroup,
NegativeExcludeNoneFilter = AbstractRawItemDataModel::NegativeGroup,
PositiveFilter = AbstractRawItemDataModel::PositiveGroup | AbstractRawItemDataModel::NoneGroup,
PositiveExcludeNoneFilter = AbstractRawItemDataModel::PositiveGroup
};
Q_ENUM(DataFilters)
explicit RawItemFilteredModel(QAbstractItemModel * sourceModel, int flags, QObject * parent = nullptr);
explicit RawItemFilteredModel(QAbstractItemModel * sourceModel, QObject * parent = nullptr) : RawItemFilteredModel(sourceModel, 0, parent) {}
public slots:
void setFilterFlags(int flags);
void update() const;
void onDataAboutToBeUpdated();
void onDataUpdateComplete();
signals:
void dataAboutToBeUpdated();
void dataUpdateComplete();
protected:
bool filterAcceptsRow(int sourceRow, const QModelIndex & sourceParent) const override;
int filterFlags;
};
#endif // RAWITEMFILTEREDMODEL_H

View file

@ -19,7 +19,7 @@
*/
#include "adjustmentreference.h"
#include "radiodata.h" // for ModelData
#include "modeldata.h"
AdjustmentReference::AdjustmentReference(int value)
{
@ -76,3 +76,8 @@ QString AdjustmentReference::toString(const ModelData * model, const bool sign)
}
return ret;
}
const bool AdjustmentReference::isAvailable() const
{
return true;
}

View file

@ -45,6 +45,7 @@ class AdjustmentReference {
bool isSet() const { return type != ADJUST_REF_VALUE || value != 0; }
bool isValid(const int value) const;
QString toString(const ModelData * model = nullptr, const bool sign = false) const;
const bool isAvailable() const;
inline const int toValue() const
{

View file

@ -89,6 +89,8 @@ uint32_t Boards::getFourCC(Type board)
return 0x3878746F;
case BOARD_RADIOMASTER_TX12:
return 0x4178746F;
case BOARD_RADIOMASTER_T8:
return 0x4378746F;
case BOARD_UNKNOWN:
break;
}
@ -117,6 +119,7 @@ int Boards::getEEpromSize(Board::Type board)
case BOARD_JUMPER_T12:
case BOARD_JUMPER_TLITE:
case BOARD_RADIOMASTER_TX12:
case BOARD_RADIOMASTER_T8:
return EESIZE_TARANIS;
case BOARD_UNKNOWN:
return EESIZE_MAX;
@ -153,6 +156,7 @@ int Boards::getFlashSize(Type board)
case BOARD_JUMPER_T12:
case BOARD_JUMPER_TLITE:
case BOARD_RADIOMASTER_TX12:
case BOARD_RADIOMASTER_T8:
return FSIZE_TARANIS;
case BOARD_HORUS_X12S:
case BOARD_X10:
@ -195,7 +199,20 @@ SwitchInfo Boards::getSwitchInfo(Board::Type board, int index)
if (index < DIM(switches))
return switches[index];
}
else if (IS_TARANIS_X7(board)) {
else if (board == BOARD_TARANIS_X7_ACCESS) {
const Board::SwitchInfo switches[] = {
{SWITCH_3POS, "SA"},
{SWITCH_3POS, "SB"},
{SWITCH_3POS, "SC"},
{SWITCH_3POS, "SD"},
{SWITCH_2POS, "SF"},
{SWITCH_TOGGLE, "SH"},
{SWITCH_2POS, "SI"}
};
if (index < DIM(switches))
return switches[index];
}
else if (board == BOARD_TARANIS_X7) {
const Board::SwitchInfo switches[] = {
{SWITCH_3POS, "SA"},
{SWITCH_3POS, "SB"},
@ -223,6 +240,16 @@ SwitchInfo Boards::getSwitchInfo(Board::Type board, int index)
if (index < DIM(switches))
return switches[index];
}
else if (IS_RADIOMASTER_T8(board)) {
const Board::SwitchInfo switches[] = {
{SWITCH_TOGGLE, "SA"},
{SWITCH_3POS, "SB"},
{SWITCH_3POS, "SC"},
{SWITCH_TOGGLE, "SD"}
};
if (index < DIM(switches))
return switches[index];
}
else if (IS_JUMPER_T12(board)) {
const Board::SwitchInfo switches[] = {
{SWITCH_3POS, "SA"},
@ -360,7 +387,9 @@ int Boards::getCapability(Board::Type board, Board::Capability capability)
return 5;
else if (board == Board::BOARD_TARANIS_X9LITES)
return 7;
else if (IS_TARANIS_X7(board))
else if (board == BOARD_TARANIS_X7_ACCESS)
return 7;
else if (board == BOARD_TARANIS_X7)
return 8;
else if (IS_FAMILY_T12(board))
return 8;
@ -573,6 +602,8 @@ QString Boards::getBoardName(Board::Type board)
return "Radiomaster TX16S";
case BOARD_RADIOMASTER_TX12:
return "Radiomaster TX12";
case BOARD_RADIOMASTER_T8:
return "Radiomaster T8";
default:
return tr("Unknown");
}

View file

@ -53,9 +53,11 @@ namespace Board {
BOARD_RADIOMASTER_TX16S,
BOARD_JUMPER_T18,
BOARD_RADIOMASTER_TX12,
BOARD_RADIOMASTER_T8,
BOARD_JUMPER_TLITE
};
constexpr int BOARD_TYPE_MAX = BOARD_JUMPER_TLITE;
enum PotType
@ -232,6 +234,11 @@ inline bool IS_RADIOMASTER_TX12(Board::Type board)
return board == Board::BOARD_RADIOMASTER_TX12;
}
inline bool IS_RADIOMASTER_T8(Board::Type board)
{
return board == Board::BOARD_RADIOMASTER_T8;
}
inline bool IS_FAMILY_T16(Board::Type board)
{
return board == Board::BOARD_JUMPER_T16 || board == Board::BOARD_RADIOMASTER_TX16S || board == Board::BOARD_JUMPER_T18;
@ -239,7 +246,7 @@ inline bool IS_FAMILY_T16(Board::Type board)
inline bool IS_FAMILY_T12(Board::Type board)
{
return board == Board::BOARD_JUMPER_T12 || board == Board::BOARD_RADIOMASTER_TX12 || board == Board::BOARD_JUMPER_TLITE;;
return board == Board::BOARD_JUMPER_T12 || board == Board::BOARD_RADIOMASTER_TX12 || board == Board::BOARD_RADIOMASTER_T8 || board == Board::BOARD_JUMPER_TLITE;
}
inline bool IS_TARANIS_XLITE(Board::Type board)

View file

@ -22,7 +22,7 @@
#include "adjustmentreference.h"
#include "helpers.h"
#include "modeldata.h"
#include "rawitemfilteredmodel.h"
#include "filtereditemmodels.h"
const QString CurveReference::toString(const ModelData * model, bool verbose) const
{
@ -63,6 +63,11 @@ const bool CurveReference::isValueNumber() const
return (type == CURVE_REF_DIFF || type == CURVE_REF_EXPO) && AdjustmentReference(value).type == AdjustmentReference::ADJUST_REF_VALUE;
}
const bool CurveReference::isAvailable() const
{
return true;
}
// static
int CurveReference::getDefaultValue(const CurveRefType type, const bool isGVar)
{
@ -77,7 +82,7 @@ int CurveReference::getDefaultValue(const CurveRefType type, const bool isGVar)
// static
QString CurveReference::typeToString(const CurveRefType type)
{
const QStringList strl = { "Diff", "Expo" , "Func", "Curve" };
const QStringList strl = { tr("Diff"), tr("Expo") , tr("Func"), tr("Curve") };
int idx = (int)type;
if (idx < 0 || idx >= strl.count())
@ -86,8 +91,6 @@ QString CurveReference::typeToString(const CurveRefType type)
return strl.at(idx);
}
constexpr int MAX_CURVE_REF_FUNC { 6 };
// static
QString CurveReference::functionToString(const int value)
{
@ -100,76 +103,65 @@ QString CurveReference::functionToString(const int value)
return strl.at(idx);
}
// static
bool CurveReference::isTypeAvailable(const CurveRefType type)
{
bool ret = false;
Firmware * fw = getCurrentFirmware();
switch(type) {
case CURVE_REF_DIFF:
if (fw->getCapability(HasInputDiff))
ret = true;
break;
case CURVE_REF_EXPO:
if (fw->getCapability(HasMixerExpo))
ret = true;
break;
case CURVE_REF_FUNC:
case CURVE_REF_CUSTOM:
ret = true;
break;
}
return ret;
}
// static
bool CurveReference::isFunctionAvailable(const int value)
{
return true;
}
// static
int CurveReference::functionCount()
{
return 6;
}
/*
* CurveReferenceUIManager
*/
constexpr int CURVE_REF_UI_HIDE_DIFF { 0x01 };
constexpr int CURVE_REF_UI_HIDE_EXPO { 0x02 };
constexpr int CURVE_REF_UI_HIDE_NEGATIVE_CURVES { 0x04 };
// static
bool CurveReferenceUIManager::firsttime { true };
int CurveReferenceUIManager::flags { 0 };
bool CurveReferenceUIManager::hasCapabilityGvars { false };
int CurveReferenceUIManager::numCurves { 0 };
RawItemFilteredModel * CurveReferenceUIManager::curveItemModel { nullptr };
QStandardItemModel * CurveReferenceUIManager::tempModel { nullptr };
CurveReferenceUIManager::CurveReferenceUIManager(QComboBox * curveValueCB, CurveReference & curve, const ModelData & model,
RawItemFilteredModel * curveItemModel, QObject * parent) :
QObject(parent),
curveTypeCB(nullptr),
curveGVarCB(nullptr),
curveValueSB(nullptr),
curveValueCB(curveValueCB),
curve(curve),
model(model),
lock(false)
{
init(curveItemModel);
}
CurveReferenceUIManager::CurveReferenceUIManager(QComboBox * curveTypeCB, QCheckBox * curveGVarCB, QSpinBox * curveValueSB,
QComboBox * curveValueCB, CurveReference & curve, const ModelData & model,
RawItemFilteredModel * curveItemModel, QObject * parent) :
QComboBox * curveValueCB, CurveReference & curveRef, const ModelData & model,
CurveRefFilteredFactory * curveRefFilteredFactory, QObject * parent) :
QObject(parent),
curveTypeCB(curveTypeCB),
curveGVarCB(curveGVarCB),
curveValueSB(curveValueSB),
curveValueCB(curveValueCB),
curve(curve),
curveRef(curveRef),
model(model),
lock(false)
lock(false),
filteredModelFactory(curveRefFilteredFactory)
{
init(curveItemModel);
}
CurveReferenceUIManager::~CurveReferenceUIManager()
{
delete tempModel;
}
void CurveReferenceUIManager::init(RawItemFilteredModel * curveModel)
{
tempModel = new QStandardItemModel();
if (firsttime) {
firsttime = false;
Firmware * fw = getCurrentFirmware();
hasCapabilityGvars = fw->getCapability(Gvars);
numCurves = fw->getCapability(NumCurves);
curveItemModel = curveModel;
if (!fw->getCapability(HasInputDiff))
flags |= (CURVE_REF_UI_HIDE_DIFF | CURVE_REF_UI_HIDE_NEGATIVE_CURVES);
if (!fw->getCapability(HasMixerExpo))
flags |= CURVE_REF_UI_HIDE_EXPO;
}
hasCapabilityGvars = getCurrentFirmware()->getCapability(Gvars);
if (curveTypeCB) {
populateTypeCB(curveTypeCB, curve);
curveTypeCB->setModel(filteredModelFactory->getItemModel(CurveRefFilteredFactory::CRFIM_TYPE));
curveTypeCB->setCurrentIndex(curveTypeCB->findData((int)curveRef.type));
connect(curveTypeCB, SIGNAL(currentIndexChanged(int)), this, SLOT(typeChanged(int)));
}
@ -182,13 +174,20 @@ void CurveReferenceUIManager::init(RawItemFilteredModel * curveModel)
connect(curveValueSB, SIGNAL(editingFinished()), this, SLOT(valueSBChanged()));
}
if (curveValueCB) {
curveValueCB->setSizeAdjustPolicy(QComboBox::AdjustToContents);
curveValueCB->setMaxVisibleItems(10);
connect(curveValueCB, SIGNAL(currentIndexChanged(int)), this, SLOT(valueCBChanged()));
}
update();
}
CurveReferenceUIManager::~CurveReferenceUIManager()
{
delete filteredModelFactory;
}
#define CURVE_REF_UI_GVAR_SHOW (1<<0)
#define CURVE_REF_UI_VALUE_SHOW (1<<1)
#define CURVE_REF_UI_REF_SHOW (1<<2)
@ -198,12 +197,12 @@ void CurveReferenceUIManager::update()
lock = true;
int widgetsMask = 0;
if (curve.type == CurveReference::CURVE_REF_DIFF || curve.type == CurveReference::CURVE_REF_EXPO) {
if (curveRef.type == CurveReference::CURVE_REF_DIFF || curveRef.type == CurveReference::CURVE_REF_EXPO) {
if (hasCapabilityGvars)
widgetsMask |= CURVE_REF_UI_GVAR_SHOW;
if (curve.isValueNumber()) {
if (curveRef.isValueNumber()) {
curveGVarCB->setChecked(false);
curveValueSB->setValue(curve.value);
curveValueSB->setValue(curveRef.value);
widgetsMask |= CURVE_REF_UI_VALUE_SHOW;
}
else {
@ -216,7 +215,7 @@ void CurveReferenceUIManager::update()
}
if(curveTypeCB) {
curveTypeCB->setCurrentIndex(curveTypeCB->findData(curve.type));
curveTypeCB->setCurrentIndex(curveTypeCB->findData(curveRef.type));
curveTypeCB->show();
}
if(curveGVarCB)
@ -224,8 +223,8 @@ void CurveReferenceUIManager::update()
if(curveValueSB)
curveValueSB->setVisible(widgetsMask & CURVE_REF_UI_VALUE_SHOW);
if(curveValueCB) {
if (curve.isValueReference())
populateValueCB(curveValueCB, curve, &model);
if (curveRef.isValueReference())
populateValueCB(curveValueCB);
curveValueCB->setVisible(widgetsMask & CURVE_REF_UI_REF_SHOW);
}
@ -235,7 +234,7 @@ void CurveReferenceUIManager::update()
void CurveReferenceUIManager::gvarCBChanged(int state)
{
if (!lock) {
curve.value = CurveReference::getDefaultValue(curve.type, state);
curveRef.value = CurveReference::getDefaultValue(curveRef.type, state);
update();
}
}
@ -244,7 +243,7 @@ void CurveReferenceUIManager::typeChanged(int value)
{
if (!lock) {
CurveReference::CurveRefType type = (CurveReference::CurveRefType)curveTypeCB->itemData(curveTypeCB->currentIndex()).toInt();
curve = CurveReference(type, CurveReference::getDefaultValue(type));
curveRef = CurveReference(type, CurveReference::getDefaultValue(type));
update();
}
}
@ -252,7 +251,7 @@ void CurveReferenceUIManager::typeChanged(int value)
void CurveReferenceUIManager::valueSBChanged()
{
if (!lock) {
curve.value = curveValueSB->value();
curveRef.value = curveValueSB->value();
update();
}
}
@ -260,47 +259,24 @@ void CurveReferenceUIManager::valueSBChanged()
void CurveReferenceUIManager::valueCBChanged()
{
if (!lock) {
curve.value = curveValueCB->itemData(curveValueCB->currentIndex()).toInt();
curveRef.value = curveValueCB->itemData(curveValueCB->currentIndex()).toInt();
update();
}
}
// static
void CurveReferenceUIManager::populateTypeCB(QComboBox * cb, const CurveReference & curveRef)
void CurveReferenceUIManager::populateValueCB(QComboBox * cb)
{
if (cb) {
cb->clear();
for (int i = 0; i <= CurveReference::MAX_CURVE_REF_TYPE; i++) {
if ((curveRef.type == CurveReference::CURVE_REF_DIFF && !(flags & CURVE_REF_UI_HIDE_DIFF)) ||
(curveRef.type == CurveReference::CURVE_REF_EXPO && !(flags & CURVE_REF_UI_HIDE_EXPO)) ||
(curveRef.type != CurveReference::CURVE_REF_DIFF && curveRef.type != CurveReference::CURVE_REF_EXPO))
cb->addItem(CurveReference::typeToString((CurveReference::CurveRefType)i), i);
}
cb->setCurrentIndex(cb->findData((int)curveRef.type));
}
}
// static
void CurveReferenceUIManager::populateValueCB(QComboBox * cb, const CurveReference & curveRef, const ModelData * model)
{
if (cb) {
cb->setModel(tempModel); // do not want to clear/alter the shared curves model and set to nullptr is invalid
switch (curveRef.type) {
case CurveReference::CURVE_REF_DIFF:
case CurveReference::CURVE_REF_EXPO:
cb->clear();
Helpers::populateGVCB(*cb, curveRef.value, *model);
cb->setModel(filteredModelFactory->getItemModel(CurveRefFilteredFactory::CRFIM_GVARREF));
break;
case CurveReference::CURVE_REF_FUNC:
cb->clear();
for (int i = 1; i <= MAX_CURVE_REF_FUNC; i++) {
cb->addItem(CurveReference::functionToString(i), i);
}
cb->setModel(filteredModelFactory->getItemModel(CurveRefFilteredFactory::CRFIM_FUNC));
break;
case CurveReference::CURVE_REF_CUSTOM:
cb->setModel(curveItemModel);
cb->setModel(filteredModelFactory->getItemModel(CurveRefFilteredFactory::CRFIM_CURVE));
break;
default:
break;

View file

@ -29,7 +29,7 @@
class ModelData;
class RawItemFilteredModel;
class CurveRefFilteredFactory;
class CurveReference {
@ -63,6 +63,7 @@ class CurveReference {
const bool isValueNumber() const;
const bool isValueReference() const { return !isValueNumber(); }
const QString toString(const ModelData * model = nullptr, bool verbose = true) const;
const bool isAvailable() const;
CurveRefType type;
int value;
@ -78,6 +79,9 @@ class CurveReference {
static int getDefaultValue(const CurveRefType type, const bool isGVar = false);
static QString typeToString(const CurveRefType type);
static QString functionToString(const int value);
static bool isTypeAvailable(const CurveRefType type);
static bool isFunctionAvailable(const int value);
static int functionCount();
};
class CurveReferenceUIManager : public QObject {
@ -85,38 +89,34 @@ class CurveReferenceUIManager : public QObject {
Q_OBJECT
public:
CurveReferenceUIManager(QComboBox *curveValueCB, CurveReference & curve, const ModelData & model,
RawItemFilteredModel * curveItemModel, QObject * parent = nullptr);
CurveReferenceUIManager(QComboBox *curveTypeCB, QCheckBox *curveGVarCB, QSpinBox *curveValueSB, QComboBox *curveValueCB,
CurveReference & curve, const ModelData & model, RawItemFilteredModel * curveItemModel, QObject * parent = nullptr);
explicit CurveReferenceUIManager(QComboBox *curveTypeCB, QCheckBox *curveGVarCB, QSpinBox *curveValueSB, QComboBox *curveValueCB,
CurveReference & curve, const ModelData & model, CurveRefFilteredFactory * curveRefFilteredFactory,
QObject * parent = nullptr);
explicit CurveReferenceUIManager(QComboBox *curveValueCB, CurveReference & curve, const ModelData & model,
CurveRefFilteredFactory * curveRefFilteredFactory, QObject * parent = nullptr) :
CurveReferenceUIManager(nullptr, nullptr, nullptr, curveValueCB, curve, model, curveRefFilteredFactory, parent) {}
virtual ~CurveReferenceUIManager();
void init(RawItemFilteredModel * curveModel);
void update();
protected slots:
void gvarCBChanged(int);
void typeChanged(int);
void valueSBChanged();
void valueCBChanged();
void update();
protected:
private:
QComboBox *curveTypeCB;
QCheckBox *curveGVarCB;
QSpinBox *curveValueSB;
QComboBox *curveValueCB;
CurveReference & curve;
CurveReference & curveRef;
const ModelData & model;
bool lock;
static bool firsttime;
static int flags;
static bool hasCapabilityGvars;
static int numCurves;
static RawItemFilteredModel * curveItemModel;
static QStandardItemModel * tempModel;
static void populateTypeCB(QComboBox * cb, const CurveReference & curveRef);
static void populateValueCB(QComboBox * cb, const CurveReference & curveRef, const ModelData * model = nullptr);
bool hasCapabilityGvars;
CurveRefFilteredFactory *filteredModelFactory;
void populateValueCB(QComboBox * cb);
};
#endif // CURVEREFERENCE_H

View file

@ -38,12 +38,12 @@ bool CustomFunctionData::isEmpty() const
QString CustomFunctionData::nameToString(int index, bool globalContext) const
{
return RadioData::getElementName((globalContext ? tr("GF") : tr("SF")), index+1, 0, true);
return RadioData::getElementName((globalContext ? tr("GF") : tr("SF")), index + 1, 0, true);
}
QString CustomFunctionData::funcToString(const ModelData * model) const
{
if (func >= FuncOverrideCH1 && func <= FuncOverrideCH32)
if (func >= FuncOverrideCH1 && func <= FuncOverrideCHLast)
return tr("Override %1").arg(RawSource(SOURCE_TYPE_CH, func).toString(model));
else if (func == FuncTrainer)
return tr("Trainer Sticks");
@ -65,8 +65,8 @@ QString CustomFunctionData::funcToString(const ModelData * model) const
return tr("Haptic");
else if (func == FuncReset)
return tr("Reset");
else if (func >= FuncSetTimer1 && func <= FuncSetTimer3)
return tr("Set Timer %1").arg(func-FuncSetTimer1+1);
else if (func >= FuncSetTimer1 && func <= FuncSetTimerLast)
return tr("Set %1").arg(RawSource(SOURCE_TYPE_SPECIAL, SOURCE_TYPE_SPECIAL_TIMER1_IDX + func - FuncSetTimer1).toString(model));
else if (func == FuncVario)
return tr("Vario");
else if (func == FuncPlayPrompt)
@ -90,7 +90,7 @@ QString CustomFunctionData::funcToString(const ModelData * model) const
else if (func == FuncBackgroundMusicPause)
return tr("Background Music Pause");
else if (func >= FuncAdjustGV1 && func <= FuncAdjustGVLast)
return tr("Adjust %1").arg(RawSource(SOURCE_TYPE_GVAR, func-FuncAdjustGV1).toString(model));
return tr("Adjust %1").arg(RawSource(SOURCE_TYPE_GVAR, func - FuncAdjustGV1).toString(model));
else if (func == FuncSetFailsafe)
return tr("Set Failsafe");
else if (func == FuncRangeCheckInternalModule)
@ -102,7 +102,7 @@ QString CustomFunctionData::funcToString(const ModelData * model) const
else if (func == FuncBindExternalModule)
return tr("Bind Ext. Module");
else {
return QString("???"); // Highlight unknown functions with output of question marks.(BTW should not happen that we do not know what a function is)
return QString(CPN_STR_UNKNOWN_ITEM);
}
}
@ -111,11 +111,16 @@ void CustomFunctionData::populateResetParams(const ModelData * model, QComboBox
int val = 0;
Firmware * firmware = Firmware::getCurrentVariant();
b->addItem(tr("Timer1"), val++);
b->addItem(tr("Timer2"), val++);
b->addItem( tr("Timer3"), val++);
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++);
@ -124,6 +129,7 @@ void CustomFunctionData::populateResetParams(const ModelData * model, QComboBox
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()) {
@ -132,6 +138,7 @@ void CustomFunctionData::populateResetParams(const ModelData * model, QComboBox
}
}
}
b->setCurrentIndex(b->findData(value));
}
@ -153,18 +160,18 @@ QString CustomFunctionData::paramToString(const ModelData * model) const
return QString("%1").arg(param);
}
else if (func == FuncLogs) {
return QString("%1").arg(param/10.0) + tr("s");
return QString("%1").arg(param / 10.0) + tr("s");
}
else if (func == FuncPlaySound) {
CustomFunctionData::populatePlaySoundParams(qs);
if (param>=0 && param<(int)qs.count())
if (param >= 0 && param < (int)qs.count())
return qs.at(param);
else
return tr("<font color=red><b>Inconsistent parameter</b></font>");
}
else if (func == FuncPlayHaptic) {
CustomFunctionData::populateHapticParams(qs);
if (param>=0 && param<(int)qs.count())
if (param >= 0 && param < (int)qs.count())
return qs.at(param);
else
return tr("<font color=red><b>Inconsistent parameter</b></font>");
@ -193,7 +200,7 @@ 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 tr("Value ") + QString("%1").arg(param);
case FUNC_ADJUST_GVAR_SOURCE:
case FUNC_ADJUST_GVAR_GVAR:
return RawSource(param).toString();
@ -218,16 +225,16 @@ QString CustomFunctionData::repeatToString() const
}
else {
unsigned int step = 1;
return tr("repeat(%1s)").arg(step*repeatParam);
return tr("repeat(%1s)").arg(step * repeatParam);
}
}
QString CustomFunctionData::enabledToString() const
{
if ((func >= FuncOverrideCH1 && func <= FuncOverrideCH32) ||
if ((func >= FuncOverrideCH1 && func <= FuncOverrideCHLast) ||
(func >= FuncAdjustGV1 && func <= FuncAdjustGVLast) ||
(func == FuncReset) ||
(func >= FuncSetTimer1 && func <= FuncSetTimer2) ||
(func >= FuncSetTimer1 && func <= FuncSetTimerLast) ||
(func == FuncVolume) ||
(func == FuncBacklight) ||
(func <= FuncInstantTrim)) {
@ -238,6 +245,64 @@ QString CustomFunctionData::enabledToString() const
return "";
}
// static
bool CustomFunctionData::isFuncAvailable(int index)
{
Firmware * fw = getCurrentFirmware();
bool ret = (((index >= FuncOverrideCH1 && index <= FuncOverrideCHLast) && !fw->getCapability(SafetyChannelCustomFunction)) ||
((index == FuncVolume || index == FuncBackgroundMusic || index == FuncBackgroundMusicPause) && !fw->getCapability(HasVolume)) ||
((index == FuncPlayScript && !IS_HORUS_OR_TARANIS(fw->getBoard()))) ||
((index == FuncPlayHaptic) && !fw->getCapability(Haptic)) ||
((index == FuncPlayBoth) && !fw->getCapability(HasBeeper)) ||
((index == FuncLogs) && !fw->getCapability(HasSDLogs)) ||
((index >= FuncSetTimer1 && index <= FuncSetTimerLast) && index > FuncSetTimer1 + fw->getCapability(Timers)) ||
((index == FuncScreenshot) && !IS_HORUS_OR_TARANIS(fw->getBoard())) ||
((index >= FuncRangeCheckInternalModule && index <= FuncBindExternalModule) && !fw->getCapability(DangerousFunctions)) ||
((index >= FuncAdjustGV1 && index <= FuncAdjustGVLast) && !fw->getCapability(Gvars))
);
return !ret;
}
// static
int CustomFunctionData::funcContext(int index)
{
int ret = AllFunctionContexts;
if ((index >= FuncOverrideCH1 && index <= FuncOverrideCHLast) ||
(index >= FuncRangeCheckInternalModule && index <= FuncBindExternalModule) ||
(index >= FuncAdjustGV1 && index <= FuncAdjustGVLast))
ret &= ~GlobalFunctionsContext;
return ret;
}
// static
int CustomFunctionData::resetParamCount(const ModelData * model)
{
QComboBox cb;
CustomFunctionData::populateResetParams(model, &cb);
return cb.count();
}
// static
bool CustomFunctionData::isResetParamAvailable(const ModelData * model, int index)
{
Firmware * firmware = getCurrentFirmware();
if (index < CPN_MAX_TIMERS) {
if (index < firmware->getCapability(Timers))
return true;
else
return false;
}
else if (index < CPN_MAX_TIMERS + firmware->getCapability(RotaryEncoders))
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();
return false;
}
void CustomFunctionData::convert(RadioDataConversionState & cstate)
{
cstate.setComponent(tr("CFN"), 8);

View file

@ -35,7 +35,8 @@ class RadioDataConversionState;
enum AssignFunc {
FuncOverrideCH1 = 0,
FuncOverrideCH32 = FuncOverrideCH1+CPN_MAX_CHNOUT-1,
FuncOverrideCHLast = FuncOverrideCH1 + CPN_MAX_CHNOUT - 1,
FuncOverrideCH32 = FuncOverrideCHLast, // TODO remove
FuncTrainer,
FuncTrainerRUD,
FuncTrainerELE,
@ -47,8 +48,9 @@ enum AssignFunc {
FuncPlayHaptic,
FuncReset,
FuncSetTimer1,
FuncSetTimer2,
FuncSetTimer3,
FuncSetTimer2, // TODO remove
FuncSetTimer3, // TODO remove
FuncSetTimerLast = FuncSetTimer1 + CPN_MAX_TIMERS - 1,
FuncVario,
FuncPlayPrompt,
FuncPlayBoth,
@ -61,7 +63,7 @@ enum AssignFunc {
FuncBackgroundMusic,
FuncBackgroundMusicPause,
FuncAdjustGV1,
FuncAdjustGVLast = FuncAdjustGV1+CPN_MAX_GVARS-1,
FuncAdjustGVLast = FuncAdjustGV1 + CPN_MAX_GVARS - 1,
FuncSetFailsafe,
FuncRangeCheckInternalModule,
FuncRangeCheckExternalModule,
@ -83,7 +85,15 @@ class CustomFunctionData {
Q_DECLARE_TR_FUNCTIONS(CustomFunctionData)
public:
CustomFunctionData(AssignFunc func=FuncOverrideCH1) { clear(); this->func = func; }
enum CustomFunctionContext
{
GlobalFunctionsContext = 0x01,
SpecialFunctionsContext = 0x02,
AllFunctionContexts = GlobalFunctionsContext | SpecialFunctionsContext
};
CustomFunctionData(AssignFunc func = FuncOverrideCH1) { clear(); this->func = func; }
RawSwitch swtch;
AssignFunc func;
int param;
@ -95,7 +105,7 @@ class CustomFunctionData {
void clear();
bool isEmpty() const;
QString nameToString(int index, bool globalContext = false) const;
QString funcToString(const ModelData * model = NULL) const;
QString funcToString(const ModelData * model = nullptr) const;
QString paramToString(const ModelData * model) const;
QString repeatToString() const;
QString enabledToString() const;
@ -103,6 +113,10 @@ class CustomFunctionData {
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);

View file

@ -1439,3 +1439,42 @@ void ModelData::updateResetParam(CustomFunctionData * cfd)
updRefInfo.updcnt++;
}
}
QString ModelData::thrTraceSrcToString() const
{
return thrTraceSrcToString((int)thrTraceSrc);
}
QString ModelData::thrTraceSrcToString(const int index) const
{
Firmware * firmware = getCurrentFirmware();
const Boards board = Boards(getCurrentBoard());
const int pscnt = board.getCapability(Board::Pots) + board.getCapability(Board::Sliders);
if (index == 0)
return tr("THR");
else if (index <= pscnt)
return board.getAnalogInputName(index + board.getCapability(Board::Sticks) - 1);
else if (index <= pscnt + firmware->getCapability(Outputs))
return RawSource(SOURCE_TYPE_CH, index - pscnt - 1).toString(this);
return QString(CPN_STR_UNKNOWN_ITEM);
}
int ModelData::thrTraceSrcCount() const
{
const Boards board = Boards(getCurrentBoard());
Firmware * firmware = getCurrentFirmware();
return 1 + board.getCapability(Board::Pots) + board.getCapability(Board::Sliders) + firmware->getCapability(Outputs);
}
bool ModelData::isThrTraceSrcAvailable(const GeneralSettings * generalSettings, const int index) const
{
const Boards board = Boards(getCurrentBoard());
if (index > 0 && index <= board.getCapability(Board::Pots) + board.getCapability(Board::Sliders))
return RawSource(SOURCE_TYPE_STICK, index + board.getCapability(Board::Sticks) - 1).isAvailable(this, generalSettings, board.getBoardType());
else
return true;
}

View file

@ -283,6 +283,10 @@ class ModelData {
bool hasExpoChildren(const int index);
bool hasExpoSiblings(const int index);
void removeMix(const int idx);
QString thrTraceSrcToString() const;
QString thrTraceSrcToString(const int index) const;
int thrTraceSrcCount() const;
bool isThrTraceSrcAvailable(const GeneralSettings * generalSettings, const int index) const;
protected:
void removeGlobalVar(int & var);

View file

@ -141,8 +141,9 @@ enum MultiModuleRFProtocols {
MODULE_SUBTYPE_MULTI_REALACC,
MODULE_SUBTYPE_MULTI_OMP,
MODULE_SUBTYPE_MULTI_MLINK,
MODULE_SUBTYPE_MULTI_WFLYRF,
MODULE_SUBTYPE_MULTI_LAST = MODULE_SUBTYPE_MULTI_WFLYRF
MODULE_SUBTYPE_MULTI_WFLY2,
MODULE_SUBTYPE_MULTI_E016HV2,
MODULE_SUBTYPE_MULTI_LAST = MODULE_SUBTYPE_MULTI_E016HV2
};
enum TrainerProtocol {

View file

@ -90,10 +90,10 @@ static const QStringList STR_SUBTYPE_FRSKYL {"LR12", "LR12 6-Channel"};
static const QStringList STR_SUBTYPE_ESKY150V2 {"150 V2"};
static const QStringList STR_SUBTYPE_JJRC345 {"Standard", "SkyTumbler"};
static const QStringList STR_SUBTYPE_KYOSHO {"FHSS", "Hype"};
static const QStringList STR_SUBTYPE_RLINK {"Surface", "Air"};
static const QStringList STR_SUBTYPE_RLINK {"Surface", "Air", "DumboRC"};
static const QStringList STR_SUBTYPE_ELRS {"Not Available WIP"};
static const QStringList STR_SUBTYPE_REALACC {"R11"};
static const QStringList STR_SUBTYPE_WFLYRF {"RF20x"};
static const QStringList STR_SUBTYPE_WFLY2 {"RF20x"};
static const QStringList NO_SUBTYPE {STR_MULTI_DEFAULT};
@ -159,11 +159,12 @@ const Multiprotocols multiProtocols {
{MODULE_SUBTYPE_MULTI_JJRC345, 1, false, STR_SUBTYPE_JJRC345, nullptr},
{MODULE_SUBTYPE_MULTI_Q90C, 0, false, NO_SUBTYPE, STR_MULTI_RFTUNE},
{MODULE_SUBTYPE_MULTI_KYOSHO, 1, false, STR_SUBTYPE_KYOSHO, nullptr},
{MODULE_SUBTYPE_MULTI_RLINK, 1, false, STR_SUBTYPE_RLINK, STR_MULTI_RFTUNE},
{MODULE_SUBTYPE_MULTI_RLINK, 2, false, STR_SUBTYPE_RLINK, STR_MULTI_RFTUNE},
{MODULE_SUBTYPE_MULTI_ELRS, 0, false, STR_SUBTYPE_ELRS, nullptr},
{MODULE_SUBTYPE_MULTI_REALACC, 0, false, STR_SUBTYPE_REALACC, nullptr},
{MODULE_SUBTYPE_MULTI_OMP, 0, false, NO_SUBTYPE, STR_MULTI_RFTUNE},
{MODULE_SUBTYPE_MULTI_WFLYRF, 0, false, STR_SUBTYPE_WFLYRF, nullptr},
{MODULE_SUBTYPE_MULTI_WFLY2, 0, false, STR_SUBTYPE_WFLY2, STR_MULTI_OPTION},
{MODULE_SUBTYPE_MULTI_E016HV2, 0, false, NO_SUBTYPE, STR_MULTI_RFTUNE},
{MM_RF_CUSTOM_SELECTED, 7, true, STR_SUBTYPE_CUSTOM, STR_MULTI_OPTION},
// Sentinel and default for protocols not listed above (MM_RF_CUSTOM is 0xff)
@ -208,7 +209,8 @@ QString Multiprotocols::protocolToString(int protocol, bool custom)
"Hitec", "Wfly", "Bugs", "Bugs Mini", "Traxxas", "NCC-1701-A", "E01X", "WL Heli V911S", "GD00X", "Volantex V761",
"KFPlan KF606", "Redpine", "Potensic", "ZSX", "Height", "Scanner", "FrSky RX", "FlySky AFHDS2A RX", "HoTT", "Fx816",
"Bayang RX", "Pelikan", "Tiger", "XK", "XN297 Dump", "FrSky X 2.1", "FrSky R9", "Propel", "FrSky L", "Skyartec",
"ESky 150v2", "DSM RX", "JJRC345", "Q90C", "Kyosho", "RadioLink", "ExpressLRS", "Realacc", "OMP", "M-Link", "Wfly RF"
"ESky 150v2", "DSM RX", "JJRC345", "Q90C", "Kyosho", "RadioLink", "ExpressLRS", "Realacc", "OMP", "M-Link", "Wfly 2",
"E016H v2"
});
return strings.value(protocol, CPN_STR_UNKNOWN_ITEM);

View file

@ -48,6 +48,9 @@ inline int MAX_SWITCHES(Board::Type board, int version)
if (IS_FAMILY_T12(board))
return 8;
if (IS_TARANIS_X7(board))
return 8;
return Boards::getCapability(board, Board::Switches);
}

View file

@ -38,6 +38,7 @@
#define JUMPER_T12_VARIANT 0x4001
#define RADIOMASTER_TX12_VARIANT 0x4002
#define JUMPER_TLITE_VARIANT 0x4003
#define RADIOMASTER_T8_VARIANT 0x4004
class OpenTxGeneralData: public TransformedField {
public:

View file

@ -70,6 +70,8 @@ const char * OpenTxEepromInterface::getName()
return "OpenTX for Radiomaster TX16S";
case BOARD_RADIOMASTER_TX12:
return "OpenTX for Radiomaster TX12";
case BOARD_RADIOMASTER_T8:
return "OpenTX for Radiomaster T8";
case BOARD_TARANIS_X9D:
return "OpenTX for FrSky Taranis X9D";
case BOARD_TARANIS_X9DP:
@ -344,6 +346,9 @@ int OpenTxEepromInterface::save(uint8_t * eeprom, const RadioData & radioData, u
else if (IS_RADIOMASTER_TX12(board)) {
variant |= RADIOMASTER_TX12_VARIANT;
}
else if (IS_RADIOMASTER_T8(board)) {
variant |= RADIOMASTER_T8_VARIANT;
}
OpenTxGeneralData generator((GeneralSettings &)radioData.generalSettings, board, version, variant);
// generator.dump();
QByteArray data;
@ -692,6 +697,8 @@ int OpenTxFirmware::getCapability(::Capability capability)
return JUMPER_TLITE_VARIANT;
else if (IS_RADIOMASTER_TX12(board))
return RADIOMASTER_TX12_VARIANT;
else if (IS_RADIOMASTER_T8(board))
return RADIOMASTER_T8_VARIANT;
else
return 0;
case MavlinkTelemetry:
@ -966,6 +973,11 @@ bool OpenTxEepromInterface::checkVariant(unsigned int version, unsigned int vari
variantError = true;
}
}
else if (IS_RADIOMASTER_T8(board)) {
if (variant != RADIOMASTER_T8_VARIANT) {
variantError = true;
}
}
else if (IS_TARANIS(board)) {
if (variant != 0) {
variantError = true;
@ -1316,6 +1328,17 @@ void registerOpenTxFirmwares()
registerOpenTxFirmware(firmware);
addOpenTxRfOptions(firmware, FLEX);
/* Radiomaster T8 board */
firmware = new OpenTxFirmware("opentx-t8", QCoreApplication::translate("Firmware", "Radiomaster T8"), BOARD_RADIOMASTER_T8);
addOpenTxCommonOptions(firmware);
firmware->addOption("noheli", Firmware::tr("Disable HELI menu and cyclic mix support"));
firmware->addOption("nogvars", Firmware::tr("Disable Global variables"));
firmware->addOption("lua", Firmware::tr("Enable Lua custom scripts screen"));
addOpenTxFontOptions(firmware);
registerOpenTxFirmware(firmware);
addOpenTxRfOptions(firmware, NONE);
firmware->addOption("bindkey", Firmware::tr("Allow bind using bind key"));
/* Radiomaster TX16S board */
firmware = new OpenTxFirmware("opentx-tx16s", Firmware::tr("Radiomaster TX16S / SE / Hall / Masterfire"), BOARD_RADIOMASTER_TX16S);
addOpenTxFrskyOptions(firmware);

View file

@ -143,14 +143,14 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
static const QString rotary[] = { tr("REa"), tr("REb") };
if (index<0) {
return tr("???");
return QString(CPN_STR_UNKNOWN_ITEM);
}
QString result;
int genAryIdx = 0;
switch (type) {
case SOURCE_TYPE_NONE:
return tr("----");
return QString(CPN_STR_NONE_ITEM);
case SOURCE_TYPE_VIRTUAL_INPUT:
{
@ -161,7 +161,7 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
}
case SOURCE_TYPE_LUA_OUTPUT:
return tr("LUA%1%2").arg(index/16+1).arg(QChar('a'+index%16));
return tr("LUA%1%2").arg(index / 16 + 1).arg(QChar('a' + index % 16));
case SOURCE_TYPE_STICK:
if (generalSettings) {
@ -193,10 +193,10 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
return result;
case SOURCE_TYPE_CUSTOM_SWITCH:
return RawSwitch(SWITCH_TYPE_VIRTUAL, index+1).toString();
return RawSwitch(SWITCH_TYPE_VIRTUAL, index + 1).toString();
case SOURCE_TYPE_CYC:
return tr("CYC%1").arg(index+1);
return tr("CYC%1").arg(index + 1);
case SOURCE_TYPE_PPM:
return RadioData::getElementName(tr("TR", "as in Trainer"), index + 1);
@ -208,18 +208,15 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
return LimitData().nameToString(index);
case SOURCE_TYPE_SPECIAL:
result = CHECK_IN_ARRAY(special, index);
// TODO refactor timers into own source type
if (result.startsWith("Timer")) {
bool ok;
int n = result.right(1).toInt(&ok);
if (ok) {
if (index >= SOURCE_TYPE_SPECIAL_TIMER1_IDX && index <= SOURCE_TYPE_SPECIAL_TIMER1_IDX + CPN_MAX_TIMERS - 1) {
if (model)
result = model->timers[n - 1].nameToString(n - 1);
result = model->timers[index - SOURCE_TYPE_SPECIAL_TIMER1_IDX].nameToString(index - SOURCE_TYPE_SPECIAL_TIMER1_IDX);
else
result = TimerData().nameToString(n - 1);
}
result = TimerData().nameToString(index - SOURCE_TYPE_SPECIAL_TIMER1_IDX);
}
else
result = CHECK_IN_ARRAY(special, index);
return result;
case SOURCE_TYPE_TELEMETRY:
@ -241,7 +238,7 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
return GVarData().nameToString(index);
default:
return tr("???");
return QString(CPN_STR_UNKNOWN_ITEM);
}
}
@ -409,4 +406,3 @@ QStringList RawSource::getSwitchList(Boards board) const
}
return ret;
}

View file

@ -178,6 +178,9 @@ enum RawSourceType {
MAX_SOURCE_TYPE
};
constexpr int SOURCE_TYPE_STICK_THR_IDX { 3 }; // TODO is there a function to determine index?
constexpr int SOURCE_TYPE_SPECIAL_TIMER1_IDX { 2 }; // TODO temp const until Timers own source type
class RawSourceRange
{
Q_DECLARE_TR_FUNCTIONS(RawSourceRange)

View file

@ -22,6 +22,8 @@
#include "radiodata.h"
#include "modeldata.h"
#include "eeprominterface.h"
#include "compounditemmodels.h"
void SensorData::updateUnit()
{
@ -31,9 +33,18 @@ void SensorData::updateUnit()
}
}
// TODO depreciated
QString SensorData::unitString() const
{
switch (unit) {
return unitToString(unit);
}
// static
QString SensorData::unitToString(const int value)
{
switch (value) {
case UNIT_RAW:
return tr("Raw (-)");
case UNIT_VOLTS:
return tr("V");
case UNIT_AMPS:
@ -91,7 +102,7 @@ QString SensorData::unitString() const
case UNIT_US:
return tr("uS");
default:
return "";
return CPN_STR_UNKNOWN_ITEM;
}
}
@ -118,3 +129,166 @@ bool SensorData::isEmpty() const
{
return (!isAvailable() && type == 0 && id == 0 && subid == 0 && instance == 0 && rxIdx == 0 && moduleIdx == 0 && unit == 0 && ratio == 0 && prec == 0 && offset == 0 && autoOffset == 0 && filter == 0 && onlyPositive == 0 && logs == 0);
}
// static
QString SensorData::typeToString(const int value)
{
switch(value) {
case TELEM_TYPE_CUSTOM:
return tr("Custom");
case TELEM_TYPE_CALCULATED:
return tr("Calculated");
default:
return CPN_STR_UNKNOWN_ITEM;
}
}
// static
QString SensorData::formulaToString(const int value)
{
switch(value) {
case TELEM_FORMULA_ADD:
return tr("Add");
case TELEM_FORMULA_AVERAGE:
return tr("Average");
case TELEM_FORMULA_MIN:
return tr("Minimum");
case TELEM_FORMULA_MAX:
return tr("Maximum");
case TELEM_FORMULA_MULTIPLY:
return tr("Multiply");
case TELEM_FORMULA_TOTALIZE:
return tr("Totalize");
case TELEM_FORMULA_CELL:
return tr("Cell");
case TELEM_FORMULA_CONSUMPTION:
return tr("Consumption");
case TELEM_FORMULA_DIST:
return tr("Distance");
default:
return CPN_STR_UNKNOWN_ITEM;
}
}
// static
QString SensorData::cellIndexToString(const int value)
{
if (value == TELEM_CELL_INDEX_LOWEST)
return tr("Lowest");
if (value > TELEM_CELL_INDEX_LOWEST && value < TELEM_CELL_INDEX_HIGHEST)
return tr("Cell %1").arg(value - TELEM_CELL_INDEX_LOWEST);
if (value== TELEM_CELL_INDEX_HIGHEST)
return tr("Highest");
if (value == TELEM_CELL_INDEX_DELTA)
return tr("Delta");
return CPN_STR_UNKNOWN_ITEM;
}
// static
QString SensorData::precisionToString(const int value)
{
return QString("0.%1").arg(QString(value, '0'));
}
// static
QString SensorData::sourceToString(const ModelData * model, const int index, const bool sign)
{
if (model) {
const QString prfx = sign ? index < 0 ? "-" : "+" : "";
if (abs(index) > 0) {
const SensorData &sd = model->sensorData[abs(index) - 1];
if (sd.type == SensorData::TELEM_TYPE_CUSTOM)
return QString("%1%2 (%3)").arg(prfx).arg(sd.label).arg(sd.getOrigin(model));
else
return QString("%1%2").arg(prfx).arg(sd.label);
}
else
return CPN_STR_NONE_ITEM;
}
return "";
}
// static
bool SensorData::isSourceAvailable(const ModelData * model, const int index)
{
Firmware * firmware = getCurrentFirmware();
const int sensorcnt = firmware->getCapability(Sensors);
const int i = abs(index);
if (model && sensorcnt > 0 && i <= sensorcnt) {
if (i > 0)
return model->sensorData[i - 1].isAvailable();
else
return true;
}
return false;
}
// static
AbstractStaticItemModel * SensorData::typeItemModel()
{
AbstractStaticItemModel * mdl = new AbstractStaticItemModel();
mdl->setName("sensordata.type");
for (int i = 0; i <= TELEM_TYPE_LAST; i++) {
mdl->appendToItemList(typeToString(i), i);
}
mdl->loadItemList();
return mdl;
}
// static
AbstractStaticItemModel * SensorData::formulaItemModel()
{
AbstractStaticItemModel * mdl = new AbstractStaticItemModel();
mdl->setName("sensordata.formula");
for (int i = 0; i <= TELEM_FORMULA_LAST; i++) {
mdl->appendToItemList(formulaToString(i), i);
}
mdl->loadItemList();
return mdl;
}
// static
AbstractStaticItemModel * SensorData::cellIndexItemModel()
{
AbstractStaticItemModel * mdl = new AbstractStaticItemModel();
mdl->setName("sensordata.cellindex");
for (int i = 0; i <= TELEM_CELL_INDEX_LAST; i++) {
mdl->appendToItemList(cellIndexToString(i), i);
}
mdl->loadItemList();
return mdl;
}
// static
AbstractStaticItemModel * SensorData::unitItemModel()
{
AbstractStaticItemModel * mdl = new AbstractStaticItemModel();
mdl->setName("sensordata.unit");
for (int i = 0; i <= UNIT_MAX; i++) {
QString str = unitToString(i);
if (str != CPN_STR_UNKNOWN_ITEM)
mdl->appendToItemList(str, i);
}
mdl->loadItemList();
return mdl;
}
// static
PrecisionItemModel * SensorData::precisionItemModel()
{
PrecisionItemModel * mdl = new PrecisionItemModel(0, 2);
mdl->setName("sensordata.precision");
return mdl;
}

View file

@ -27,6 +27,8 @@ constexpr int CPN_MAX_SENSORS = 60;
constexpr int SENSOR_LABEL_LEN = 4;
class ModelData;
class AbstractStaticItemModel;
class PrecisionItemModel;
class SensorData {
Q_DECLARE_TR_FUNCTIONS(SensorData)
@ -36,7 +38,8 @@ class SensorData {
enum
{
TELEM_TYPE_CUSTOM,
TELEM_TYPE_CALCULATED
TELEM_TYPE_CALCULATED,
TELEM_TYPE_LAST = TELEM_TYPE_CALCULATED
};
enum
@ -63,6 +66,7 @@ class SensorData {
TELEM_CELL_INDEX_6,
TELEM_CELL_INDEX_HIGHEST,
TELEM_CELL_INDEX_DELTA,
TELEM_CELL_INDEX_LAST = TELEM_CELL_INDEX_DELTA
};
enum
@ -168,6 +172,20 @@ class SensorData {
QString getOrigin(const ModelData* model) const;
void clear() { memset(this, 0, sizeof(SensorData)); }
bool isEmpty() const;
static QString sourceToString(const ModelData * model, const int index, const bool sign = false);
static bool isSourceAvailable(const ModelData * model, const int index);
static QString typeToString(const int value);
static QString formulaToString(const int value);
static QString cellIndexToString(const int value);
static QString unitToString(const int value);
static QString precisionToString(const int value);
static AbstractStaticItemModel * typeItemModel();
static AbstractStaticItemModel * formulaItemModel();
static AbstractStaticItemModel * cellIndexItemModel();
static AbstractStaticItemModel * unitItemModel();
static PrecisionItemModel * precisionItemModel();
};
#endif // SENSORDATA_H

View file

@ -28,7 +28,7 @@
#include "hardware.h"
#include "../modeledit/customfunctions.h"
#include "verticalscrollarea.h"
#include "rawitemdatamodels.h"
#include "compounditemmodels.h"
GeneralEdit::GeneralEdit(QWidget * parent, RadioData & radioData, Firmware * firmware) :
QDialog(parent),
@ -56,10 +56,14 @@ GeneralEdit::GeneralEdit(QWidget * parent, RadioData & radioData, Firmware * fir
}
}
commonItemModels = new CommonItemModels(&generalSettings, nullptr, this);
sharedItemModels = new CompoundItemModelFactory(&generalSettings, nullptr);
sharedItemModels->addItemModel(AbstractItemModel::IMID_RawSource);
sharedItemModels->addItemModel(AbstractItemModel::IMID_RawSwitch);
sharedItemModels->addItemModel(AbstractItemModel::IMID_CustomFuncAction);
sharedItemModels->addItemModel(AbstractItemModel::IMID_CustomFuncResetParam);
addTab(new GeneralSetupPanel(this, generalSettings, firmware), tr("Setup"));
addTab(new CustomFunctionsPanel(this, nullptr, generalSettings, firmware, commonItemModels), tr("Global Functions"));
addTab(new CustomFunctionsPanel(this, nullptr, generalSettings, firmware, sharedItemModels), tr("Global Functions"));
addTab(new TrainerPanel(this, generalSettings, firmware), tr("Trainer"));
addTab(new HardwarePanel(this, generalSettings, firmware), tr("Hardware"));
addTab(new CalibrationPanel(this, generalSettings, firmware), tr("Calibration"));
@ -70,6 +74,7 @@ GeneralEdit::GeneralEdit(QWidget * parent, RadioData & radioData, Firmware * fir
GeneralEdit::~GeneralEdit()
{
delete ui;
delete sharedItemModels;
}
void GeneralEdit::closeEvent(QCloseEvent *event)

View file

@ -25,7 +25,7 @@
#include "eeprominterface.h"
#include "genericpanel.h"
class CommonItemModels;
class CompoundItemModelFactory;
namespace Ui {
class GeneralEdit;
@ -73,7 +73,7 @@ class GeneralEdit : public QDialog
QVector<GenericPanel *> panels;
void addTab(GenericPanel *panel, QString text);
void closeEvent(QCloseEvent *event);
CommonItemModels *commonItemModels;
CompoundItemModelFactory *sharedItemModels;
};
#endif // _GENERALEDIT_H_

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View file

@ -1585,7 +1585,7 @@ void MainWindow::updateWindowActions()
QString scut;
if (++count < 10)
scut = tr("Alt+%1").arg(count);
QAction * act = addActToGroup(windowsListActions, "", "", "window_ptr", qVariantFromValue(win), QVariant(), scut);
QAction * act = addActToGroup(windowsListActions, "", "", "window_ptr", QVariant::fromValue(win), QVariant(), scut);
act->setChecked(win == mdiArea->activeSubWindow());
updateWindowActionTitle(win, act);
}

View file

@ -20,7 +20,7 @@
#include "channels.h"
#include "helpers.h"
#include "rawitemfilteredmodel.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):
firmware(firmware),
@ -96,16 +96,15 @@ void LimitsGroup::updateMinMax(int max)
}
}
}
ChannelsPanel::ChannelsPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels):
ChannelsPanel::ChannelsPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels):
ModelPanel(parent, model, generalSettings, firmware),
commonItemModels(commonItemModels)
sharedItemModels(sharedItemModels)
{
chnCapability = firmware->getCapability(Outputs);
int channelNameMaxLen = firmware->getCapability(ChannelsName);
curveFilteredModel = new RawItemFilteredModel(commonItemModels->curveItemModel(), RawItemFilteredModel::AllFilter, this);
connect(curveFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &ChannelsPanel::onModelDataAboutToBeUpdated);
connect(curveFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &ChannelsPanel::onModelDataUpdateComplete);
curveFilteredModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_Curve));
connectItemModelEvents(curveFilteredModel);
QStringList headerLabels;
headerLabels << "#";
@ -214,6 +213,7 @@ ChannelsPanel::~ChannelsPanel()
delete centerSB[i];
delete symlimitsChk[i];
}
delete curveFilteredModel;
}
void ChannelsPanel::symlimitsEdited()
@ -474,12 +474,18 @@ void ChannelsPanel::swapData(int idx1, int idx2)
}
}
void ChannelsPanel::onModelDataAboutToBeUpdated()
void ChannelsPanel::connectItemModelEvents(const FilteredItemModel * itemModel)
{
connect(itemModel, &FilteredItemModel::aboutToBeUpdated, this, &ChannelsPanel::onItemModelAboutToBeUpdated);
connect(itemModel, &FilteredItemModel::updateComplete, this, &ChannelsPanel::onItemModelUpdateComplete);
}
void ChannelsPanel::onItemModelAboutToBeUpdated()
{
lock = true;
}
void ChannelsPanel::onModelDataUpdateComplete()
void ChannelsPanel::onItemModelUpdateComplete()
{
update();
lock = false;
@ -487,5 +493,5 @@ void ChannelsPanel::onModelDataUpdateComplete()
void ChannelsPanel::updateItemModels()
{
commonItemModels->update(CommonItemModels::RMO_CHANNELS);
sharedItemModels->update(AbstractItemModel::IMUE_Channels);
}

View file

@ -26,8 +26,8 @@
#include <QtCore>
class CommonItemModels;
class RawItemFilteredModel;
class CompoundItemModelFactory;
class FilteredItemModel;
constexpr char MIMETYPE_CHANNEL[] = "application/x-companion-channel";
@ -57,8 +57,8 @@ class ChannelsPanel : public ModelPanel
Q_OBJECT
public:
ChannelsPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels);
~ChannelsPanel();
ChannelsPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels);
virtual ~ChannelsPanel();
public slots:
void refreshExtendedLimits();
@ -81,8 +81,8 @@ class ChannelsPanel : public ModelPanel
void cmClear(bool prompt = true);
void cmClearAll();
void onCustomContextMenuRequested(QPoint pos);
void onModelDataAboutToBeUpdated();
void onModelDataUpdateComplete();
void onItemModelAboutToBeUpdated();
void onItemModelUpdateComplete();
private:
bool hasClipboardData(QByteArray * data = nullptr) const;
@ -100,9 +100,10 @@ class ChannelsPanel : public ModelPanel
QCheckBox *symlimitsChk[CPN_MAX_CHNOUT];
int selectedIndex;
int chnCapability;
CommonItemModels * commonItemModels;
RawItemFilteredModel *curveFilteredModel;
CompoundItemModelFactory *sharedItemModels;
FilteredItemModel *curveFilteredModel;
void updateItemModels();
void connectItemModelEvents(const FilteredItemModel * itemModel);
};
#endif // _CHANNELS_H_

View file

@ -23,7 +23,7 @@
#include "node.h"
#include "edge.h"
#include "helpers.h"
#include "rawitemfilteredmodel.h"
#include "filtereditemmodels.h"
#define GFX_MARGIN 16
@ -109,11 +109,12 @@ float curveSymmetricalX(float x, float coeff, float yMin, float yMid, float yMax
return y;
}
CurvesPanel::CurvesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels):
CurvesPanel::CurvesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware,
CompoundItemModelFactory * sharedItemModels):
ModelPanel(parent, model, generalSettings, firmware),
ui(new Ui::Curves),
currentCurve(0),
commonItemModels(commonItemModels)
sharedItemModels(sharedItemModels)
{
ui->setupUi(this);
@ -812,7 +813,7 @@ void CurvesPanel::swapData(int idx1, int idx2)
void CurvesPanel::updateItemModels()
{
commonItemModels->update(CommonItemModels::RMO_CURVES);
sharedItemModels->update(AbstractItemModel::IMUE_Curves);
}
CustomScene::CustomScene(QGraphicsView * view) :

View file

@ -26,7 +26,7 @@
#include <QGraphicsScene>
#include <QGraphicsView>
class CommonItemModels;
class CompoundItemModelFactory;
constexpr char MIMETYPE_CURVE[] = "application/x-companion-curve";
@ -61,7 +61,7 @@ class CurvesPanel : public ModelPanel
Q_OBJECT
public:
CurvesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels);
CurvesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels);
virtual ~CurvesPanel();
virtual void update();
@ -121,7 +121,7 @@ class CurvesPanel : public ModelPanel
bool moveDownAllowed() const;
bool moveUpAllowed() const;
void swapData(int idx1, int idx2);
CommonItemModels * commonItemModels;
CompoundItemModelFactory * sharedItemModels;
void updateItemModels();
};

View file

@ -19,7 +19,7 @@
*/
#include "customfunctions.h"
#include "rawitemfilteredmodel.h"
#include "filtereditemmodels.h"
#include "helpers.h"
#include "appdata.h"
@ -66,10 +66,10 @@ void RepeatComboBox::update()
setCurrentIndex(value);
}
CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels):
CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, GeneralSettings & generalSettings, Firmware * firmware,
CompoundItemModelFactory * sharedItemModels):
GenericPanel(parent, model, generalSettings, firmware),
functions(model ? model->customFn : generalSettings.customFn),
commonItemModels(commonItemModels),
mediaPlayerCurrent(-1),
mediaPlayer(nullptr),
modelsUpdateCnt(0)
@ -77,21 +77,18 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model,
lock = true;
fswCapability = model ? firmware->getCapability(CustomFunctions) : firmware->getCapability(GlobalFunctions);
rawSwitchFilteredModel = new RawItemFilteredModel(commonItemModels->rawSwitchItemModel(), model ? RawSwitch::SpecialFunctionsContext : RawSwitch::GlobalFunctionsContext, this);
connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &CustomFunctionsPanel::onModelDataAboutToBeUpdated);
connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &CustomFunctionsPanel::onModelDataUpdateComplete);
rawSwitchFilteredModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSwitch),
model ? RawSwitch::SpecialFunctionsContext : RawSwitch::GlobalFunctionsContext);
connectItemModelEvents(rawSwitchFilteredModel);
rawSourceAllModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), this);
connect(rawSourceAllModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &CustomFunctionsPanel::onModelDataAboutToBeUpdated);
connect(rawSourceAllModel, &RawItemFilteredModel::dataUpdateComplete, this, &CustomFunctionsPanel::onModelDataUpdateComplete);
rawSourceAllModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource));
connectItemModelEvents(rawSourceAllModel);
rawSourceInputsModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), RawSource::InputSourceGroups, this);
connect(rawSourceInputsModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &CustomFunctionsPanel::onModelDataAboutToBeUpdated);
connect(rawSourceInputsModel, &RawItemFilteredModel::dataUpdateComplete, this, &CustomFunctionsPanel::onModelDataUpdateComplete);
rawSourceInputsModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource), RawSource::InputSourceGroups);
connectItemModelEvents(rawSourceInputsModel);
rawSourceGVarsModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), RawSource::GVarsGroup, this);
connect(rawSourceGVarsModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &CustomFunctionsPanel::onModelDataAboutToBeUpdated);
connect(rawSourceGVarsModel, &RawItemFilteredModel::dataUpdateComplete, this, &CustomFunctionsPanel::onModelDataUpdateComplete);
rawSourceGVarsModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource), RawSource::GVarsGroup);
connectItemModelEvents(rawSourceGVarsModel);
if (!firmware->getCapability(VoicesAsNumbers)) {
tracksSet = getFilesSet(getSoundsPath(generalSettings), QStringList() << "*.wav" << "*.WAV", firmware->getCapability(VoicesMaxLength));
@ -253,6 +250,10 @@ CustomFunctionsPanel::~CustomFunctionsPanel()
{
if (mediaPlayer)
stopSound(mediaPlayerCurrent);
delete rawSwitchFilteredModel;
delete rawSourceAllModel;
delete rawSourceInputsModel;
delete rawSourceGVarsModel;
}
void CustomFunctionsPanel::onMediaPlayerStateChanged(QMediaPlayer::State state)
@ -827,13 +828,19 @@ bool CustomFunctionsPanel::moveUpAllowed() const
return selectedIndex > 0;
}
void CustomFunctionsPanel::onModelDataAboutToBeUpdated()
void CustomFunctionsPanel::connectItemModelEvents(const FilteredItemModel * itemModel)
{
connect(itemModel, &FilteredItemModel::aboutToBeUpdated, this, &CustomFunctionsPanel::onItemModelAboutToBeUpdated);
connect(itemModel, &FilteredItemModel::updateComplete, this, &CustomFunctionsPanel::onItemModelUpdateComplete);
}
void CustomFunctionsPanel::onItemModelAboutToBeUpdated()
{
lock = true;
modelsUpdateCnt++;
}
void CustomFunctionsPanel::onModelDataUpdateComplete()
void CustomFunctionsPanel::onItemModelUpdateComplete()
{
modelsUpdateCnt--;
if (modelsUpdateCnt < 1) {

View file

@ -26,8 +26,8 @@
#include <QMediaPlayer>
class CommonItemModels;
class RawItemFilteredModel;
class CompoundItemModelFactory;
class FilteredItemModel;
class TimerEdit;
constexpr char MIMETYPE_CUSTOM_FUNCTION[] = "application/x-companion-custom-function";
@ -55,8 +55,8 @@ class CustomFunctionsPanel : public GenericPanel
Q_OBJECT
public:
CustomFunctionsPanel(QWidget *parent, ModelData * model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels);
~CustomFunctionsPanel();
CustomFunctionsPanel(QWidget *parent, ModelData * model, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels);
virtual ~CustomFunctionsPanel();
virtual void update();
@ -83,8 +83,8 @@ class CustomFunctionsPanel : public GenericPanel
void cmInsert();
void cmClear(bool prompt = true);
void cmClearAll();
void onModelDataAboutToBeUpdated();
void onModelDataUpdateComplete();
void onItemModelAboutToBeUpdated();
void onItemModelUpdateComplete();
private:
void populateFuncCB(QComboBox *b, unsigned int value);
@ -96,11 +96,12 @@ class CustomFunctionsPanel : public GenericPanel
bool moveUpAllowed() const;
void swapData(int idx1, int idx2);
void resetCBsAndRefresh(int idx);
CommonItemModels * commonItemModels;
RawItemFilteredModel * rawSwitchFilteredModel;
RawItemFilteredModel * rawSourceAllModel;
RawItemFilteredModel * rawSourceInputsModel;
RawItemFilteredModel * rawSourceGVarsModel;
void connectItemModelEvents(const FilteredItemModel * itemModel);
FilteredItemModel * rawSwitchFilteredModel;
FilteredItemModel * rawSourceAllModel;
FilteredItemModel * rawSourceInputsModel;
FilteredItemModel * rawSourceGVarsModel;
QSet<QString> tracksSet;
QSet<QString> scriptsSet;

View file

@ -20,12 +20,11 @@
#include "expodialog.h"
#include "ui_expodialog.h"
#include "rawitemfilteredmodel.h"
#include "filtereditemmodels.h"
#include "helpers.h"
ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, GeneralSettings & generalSettings,
Firmware * firmware, QString & inputName, RawItemFilteredModel * rawSourceModel,
RawItemFilteredModel * rawSwitchModel, RawItemFilteredModel * curveItemModel) :
Firmware * firmware, QString & inputName, CompoundItemModelFactory * sharedItemModels) :
QDialog(parent),
ui(new Ui::ExpoDialog),
model(model),
@ -38,6 +37,9 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G
{
ui->setupUi(this);
dialogFilteredItemModels = new FilteredItemModelFactory();
int id;
QLabel * lb_fp[CPN_MAX_FLIGHT_MODES] = {ui->lb_FP0, ui->lb_FP1, ui->lb_FP2, ui->lb_FP3, ui->lb_FP4, ui->lb_FP5, ui->lb_FP6, ui->lb_FP7, ui->lb_FP8 };
QCheckBox * tmp[CPN_MAX_FLIGHT_MODES] = {ui->cb_FP0, ui->cb_FP1, ui->cb_FP2, ui->cb_FP3, ui->cb_FP4, ui->cb_FP5, ui->cb_FP6, ui->cb_FP7, ui->cb_FP8 };
for (int i = 0; i < CPN_MAX_FLIGHT_MODES; i++) {
@ -50,9 +52,15 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G
gvWeightGroup = new GVarGroup(ui->weightGV, ui->weightSB, ui->weightCB, ed->weight, model, 100, -100, 100);
gvOffsetGroup = new GVarGroup(ui->offsetGV, ui->offsetSB, ui->offsetCB, ed->offset, model, 0, -100, 100);
curveGroup = new CurveReferenceUIManager(ui->curveTypeCB, ui->curveGVarCB, ui->curveValueSB, ui->curveValueCB, ed->curve, model, curveItemModel, this);
ui->switchesCB->setModel(rawSwitchModel);
curveRefFilteredItemModels = new CurveRefFilteredFactory(sharedItemModels,
firmware->getCapability(HasInputDiff) ? 0 : FilteredItemModel::PositiveFilter);
curveGroup = new CurveReferenceUIManager(ui->curveTypeCB, ui->curveGVarCB, ui->curveValueSB, ui->curveValueCB, ed->curve, model,
curveRefFilteredItemModels, this);
id = dialogFilteredItemModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSwitch),
RawSwitch::MixesContext), "RawSwitch");
ui->switchesCB->setModel(dialogFilteredItemModels->getItemModel(id));
ui->switchesCB->setCurrentIndex(ui->switchesCB->findData(ed->swtch.toValue()));
ui->sideCB->setCurrentIndex(ed->mode - 1);
@ -83,7 +91,10 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G
if (firmware->getCapability(VirtualInputs)) {
ui->inputName->setMaxLength(firmware->getCapability(InputsLength));
ui->sourceCB->setModel(rawSourceModel);
id = dialogFilteredItemModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource),
(RawSource::InputSourceGroups & ~ RawSource::NoneGroup & ~RawSource::InputsGroup)),
"RawSource");
ui->sourceCB->setModel(dialogFilteredItemModels->getItemModel(id));
ui->sourceCB->setCurrentIndex(ui->sourceCB->findData(ed->srcRaw.toValue()));
ui->inputName->setValidator(new QRegExpValidator(rx, this));
ui->inputName->setText(inputName);
@ -135,9 +146,10 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G
ExpoDialog::~ExpoDialog()
{
delete ui;
delete gvWeightGroup;
delete gvOffsetGroup;
delete ui;
delete dialogFilteredItemModels;
}
void ExpoDialog::updateScale()

View file

@ -26,7 +26,9 @@
#include "modelprinter.h"
class GVarGroup;
class RawItemFilteredModel;
class CompoundItemModelFactory;
class FilteredItemModelFactory;
class CurveRefFilteredFactory;
class CurveReferenceUIManager;
namespace Ui {
@ -37,9 +39,8 @@ class ExpoDialog : public QDialog {
Q_OBJECT
public:
ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expodata, GeneralSettings & generalSettings,
Firmware * firmware, QString & inputName, RawItemFilteredModel * rawSourceItemModel,
RawItemFilteredModel * rawSwitchItemModel, RawItemFilteredModel * curveItemModel);
~ExpoDialog();
Firmware * firmware, QString & inputName, CompoundItemModelFactory * sharedItemModels);
virtual ~ExpoDialog();
protected:
void updateScale();
@ -65,6 +66,8 @@ class ExpoDialog : public QDialog {
ModelPrinter modelPrinter;
bool lock;
QCheckBox * cb_fp[CPN_MAX_FLIGHT_MODES];
FilteredItemModelFactory *dialogFilteredItemModels;
CurveRefFilteredFactory *curveRefFilteredItemModels;
};
#endif // _EXPODIALOG_H_

View file

@ -20,19 +20,19 @@
#include "flightmodes.h"
#include "ui_flightmode.h"
#include "rawitemfilteredmodel.h"
#include "filtereditemmodels.h"
#include "helpers.h"
#include "customdebug.h"
FlightModePanel::FlightModePanel(QWidget * parent, ModelData & model, int phaseIdx, GeneralSettings & generalSettings, Firmware * firmware, RawItemFilteredModel * rawSwitchFilteredModel):
FlightModePanel::FlightModePanel(QWidget * parent, ModelData & model, int phaseIdx, GeneralSettings & generalSettings, Firmware * firmware,
FilteredItemModel * rawSwitchFilteredModel):
ModelPanel(parent, model, generalSettings, firmware),
ui(new Ui::FlightMode),
phaseIdx(phaseIdx),
phase(model.flightModeData[phaseIdx])
{
ui->setupUi(this);
connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &FlightModePanel::onModelDataAboutToBeUpdated);
connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &FlightModePanel::onModelDataUpdateComplete);
connectItemModelEvents(rawSwitchFilteredModel);
ui->labelName->setContextMenuPolicy(Qt::CustomContextMenu);
ui->labelName->setToolTip(tr("Popup menu available"));
@ -1361,12 +1361,18 @@ void FlightModePanel::gvSwapData(int idx1, int idx2)
}
}
void FlightModePanel::onModelDataAboutToBeUpdated()
void FlightModePanel::connectItemModelEvents(const FilteredItemModel * itemModel)
{
connect(itemModel, &FilteredItemModel::aboutToBeUpdated, this, &FlightModePanel::onItemModelAboutToBeUpdated);
connect(itemModel, &FilteredItemModel::updateComplete, this, &FlightModePanel::onItemModelUpdateComplete);
}
void FlightModePanel::onItemModelAboutToBeUpdated()
{
lock = true;
}
void FlightModePanel::onModelDataUpdateComplete()
void FlightModePanel::onItemModelUpdateComplete()
{
update();
lock = false;
@ -1374,11 +1380,14 @@ void FlightModePanel::onModelDataUpdateComplete()
/**********************************************************/
FlightModesPanel::FlightModesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels):
FlightModesPanel::FlightModesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware,
CompoundItemModelFactory * sharedItemModels):
ModelPanel(parent, model, generalSettings, firmware),
commonItemModels(commonItemModels)
sharedItemModels(sharedItemModels)
{
rawSwitchFilteredModel = new RawItemFilteredModel(commonItemModels->rawSwitchItemModel(), RawSwitch::MixesContext, this);
rawSwitchFilteredModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSwitch), RawSwitch::MixesContext);
connectItemModelEvents(rawSwitchFilteredModel);
modesCount = firmware->getCapability(FlightModes);
QGridLayout * gridLayout = new QGridLayout(this);
@ -1403,6 +1412,7 @@ FlightModesPanel::FlightModesPanel(QWidget * parent, ModelData & model, GeneralS
FlightModesPanel::~FlightModesPanel()
{
delete rawSwitchFilteredModel;
}
QString FlightModesPanel::getTabName(int index)
@ -1431,10 +1441,24 @@ void FlightModesPanel::update()
emit updated();
}
void FlightModesPanel::connectItemModelEvents(const FilteredItemModel * itemModel)
{
connect(itemModel, &FilteredItemModel::aboutToBeUpdated, this, &FlightModesPanel::onItemModelAboutToBeUpdated);
connect(itemModel, &FilteredItemModel::updateComplete, this, &FlightModesPanel::onItemModelUpdateComplete);
}
void FlightModesPanel::onItemModelAboutToBeUpdated()
{
}
void FlightModesPanel::onItemModelUpdateComplete()
{
}
void FlightModesPanel::updateItemModels()
{
commonItemModels->update(CommonItemModels::RMO_FLIGHT_MODES);
commonItemModels->update(CommonItemModels::RMO_GLOBAL_VARIABLES);
sharedItemModels->update(AbstractItemModel::IMUE_FlightModes);
sharedItemModels->update(AbstractItemModel::IMUE_GVars);
}
void FlightModesPanel::onTabIndexChanged(int index)

View file

@ -24,8 +24,8 @@
#include "modeledit.h"
#include "eeprominterface.h"
class CommonItemModels;
class RawItemFilteredModel;
class CompoundItemModelFactory;
class FilteredItemModel;
constexpr char MIMETYPE_FLIGHTMODE[] = "application/x-companion-flightmode";
constexpr char MIMETYPE_GVAR_PARAMS[] = "application/x-companion-gvar-params";
@ -41,7 +41,8 @@ class FlightModePanel : public ModelPanel
Q_OBJECT
public:
FlightModePanel(QWidget *parent, ModelData &model, int modeIdx, GeneralSettings & generalSettings, Firmware * firmware, RawItemFilteredModel * rawSwitchFilteredModel);
FlightModePanel(QWidget *parent, ModelData &model, int modeIdx, GeneralSettings & generalSettings, Firmware * firmware,
FilteredItemModel * rawSwitchFilteredModel);
virtual ~FlightModePanel();
virtual void update();
@ -90,8 +91,8 @@ class FlightModePanel : public ModelPanel
void gvCmPaste();
void gvCmMoveDown();
void gvCmMoveUp();
void onModelDataAboutToBeUpdated();
void onModelDataUpdateComplete();
void onItemModelAboutToBeUpdated();
void onItemModelUpdateComplete();
private:
Ui::FlightMode *ui;
@ -138,6 +139,7 @@ class FlightModePanel : public ModelPanel
bool gvMoveDownAllowed() const;
bool gvMoveUpAllowed() const;
void gvSwapData(int idx1, int idx2);
void connectItemModelEvents(const FilteredItemModel * itemModel);
};
class FlightModesPanel : public ModelPanel
@ -145,7 +147,7 @@ class FlightModesPanel : public ModelPanel
Q_OBJECT
public:
FlightModesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels);
FlightModesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels);
virtual ~FlightModesPanel();
public slots:
@ -157,16 +159,19 @@ class FlightModesPanel : public ModelPanel
private slots:
void onPhaseNameChanged();
void onTabIndexChanged(int index);
void onItemModelAboutToBeUpdated();
void onItemModelUpdateComplete();
private:
QString getTabName(int index);
int modesCount;
QTabWidget *tabWidget;
CommonItemModels *commonItemModels;
RawItemFilteredModel *rawSwitchFilteredModel;
CompoundItemModelFactory *sharedItemModels;
FilteredItemModel *rawSwitchFilteredModel;
QVector<GenericPanel *> panels;
void updateItemModels();
void connectItemModelEvents(const FilteredItemModel * itemModel);
};
#endif // _FLIGHTMODES_H_

View file

@ -21,18 +21,16 @@
#include "heli.h"
#include "ui_heli.h"
#include "helpers.h"
#include "rawitemfilteredmodel.h"
#include "filtereditemmodels.h"
HeliPanel::HeliPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels):
HeliPanel::HeliPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels):
ModelPanel(parent, model, generalSettings, firmware),
ui(new Ui::Heli),
commonItemModels(commonItemModels)
ui(new Ui::Heli)
{
ui->setupUi(this);
rawSourceFilteredModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), RawSource::InputSourceGroups, this);
connect(rawSourceFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &HeliPanel::onModelDataAboutToBeUpdated);
connect(rawSourceFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &HeliPanel::onModelDataUpdateComplete);
rawSourceFilteredModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource), RawSource::InputSourceGroups);
connectItemModelEvents(rawSourceFilteredModel);
connect(ui->swashType, SIGNAL(currentIndexChanged(int)), this, SLOT(edited()));
connect(ui->swashRingVal, SIGNAL(editingFinished()), this, SLOT(edited()));
@ -71,6 +69,7 @@ HeliPanel::HeliPanel(QWidget *parent, ModelData & model, GeneralSettings & gener
HeliPanel::~HeliPanel()
{
delete ui;
delete rawSourceFilteredModel;
}
void HeliPanel::update()
@ -118,12 +117,18 @@ void HeliPanel::edited()
}
}
void HeliPanel::onModelDataAboutToBeUpdated()
void HeliPanel::connectItemModelEvents(const FilteredItemModel * itemModel)
{
connect(itemModel, &FilteredItemModel::aboutToBeUpdated, this, &HeliPanel::onItemModelAboutToBeUpdated);
connect(itemModel, &FilteredItemModel::updateComplete, this, &HeliPanel::onItemModelUpdateComplete);
}
void HeliPanel::onItemModelAboutToBeUpdated()
{
lock = true;
}
void HeliPanel::onModelDataUpdateComplete()
void HeliPanel::onItemModelUpdateComplete()
{
update();
lock = false;

View file

@ -23,8 +23,8 @@
#include "modeledit.h"
class CommonItemModels;
class RawItemFilteredModel;
class CompoundItemModelFactory;
class FilteredItemModel;
namespace Ui {
class Heli;
@ -35,19 +35,19 @@ class HeliPanel : public ModelPanel
Q_OBJECT
public:
HeliPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels);
~HeliPanel();
HeliPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels);
virtual ~HeliPanel();
void update();
private slots:
void edited();
void onModelDataAboutToBeUpdated();
void onModelDataUpdateComplete();
void onItemModelAboutToBeUpdated();
void onItemModelUpdateComplete();
private:
Ui::Heli *ui;
CommonItemModels * commonItemModels;
RawItemFilteredModel * rawSourceFilteredModel;
FilteredItemModel * rawSourceFilteredModel;
void connectItemModelEvents(const FilteredItemModel * itemModel);
};
#endif // _HELI_H_

View file

@ -21,25 +21,19 @@
#include "inputs.h"
#include "expodialog.h"
#include "helpers.h"
#include "rawitemfilteredmodel.h"
#include "filtereditemmodels.h"
InputsPanel::InputsPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels):
InputsPanel::InputsPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels):
ModelPanel(parent, model, generalSettings, firmware),
expoInserted(false),
modelPrinter(firmware, generalSettings, model),
commonItemModels(commonItemModels)
sharedItemModels(sharedItemModels),
modelsUpdateCnt(0)
{
rawSourceFilteredModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), (RawSource::InputSourceGroups & ~ RawSource::NoneGroup & ~RawSource::InputsGroup), this);
connect(rawSourceFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &InputsPanel::onModelDataAboutToBeUpdated);
connect(rawSourceFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &InputsPanel::onModelDataUpdateComplete);
rawSwitchFilteredModel = new RawItemFilteredModel(commonItemModels->rawSwitchItemModel(), RawSwitch::MixesContext, this);
connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &InputsPanel::onModelDataAboutToBeUpdated);
connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &InputsPanel::onModelDataUpdateComplete);
curveFilteredModel = new RawItemFilteredModel(commonItemModels->curveItemModel(), RawItemFilteredModel::AllFilter, this);
connect(curveFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &InputsPanel::onModelDataAboutToBeUpdated);
connect(curveFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &InputsPanel::onModelDataUpdateComplete);
connectItemModelEvents(AbstractItemModel::IMID_RawSource);
connectItemModelEvents(AbstractItemModel::IMID_RawSwitch);
connectItemModelEvents(AbstractItemModel::IMID_Curve);
connectItemModelEvents(AbstractItemModel::IMID_GVarRef);
inputsCount = firmware->getCapability(VirtualInputs);
if (inputsCount == 0)
@ -194,7 +188,7 @@ void InputsPanel::gm_openExpo(int index)
if (firmware->getCapability(VirtualInputs))
inputName = model->inputNames[ed.chn];
ExpoDialog *dlg = new ExpoDialog(this, *model, &ed, generalSettings, firmware, inputName, rawSourceFilteredModel, rawSwitchFilteredModel, curveFilteredModel);
ExpoDialog *dlg = new ExpoDialog(this, *model, &ed, generalSettings, firmware, inputName, sharedItemModels);
if (dlg->exec()) {
model->expoData[index] = ed;
if (firmware->getCapability(VirtualInputs))
@ -730,18 +724,31 @@ int InputsPanel::getInputIndexFromSelected()
return idx;
}
void InputsPanel::onModelDataAboutToBeUpdated()
void InputsPanel::connectItemModelEvents(const int id)
{
lock = true;
AbstractDynamicItemModel * itemModel = qobject_cast<AbstractDynamicItemModel *>(sharedItemModels->getItemModel(id));
if (itemModel) {
connect(itemModel, &AbstractDynamicItemModel::aboutToBeUpdated, this, &InputsPanel::onItemModelAboutToBeUpdated);
connect(itemModel, &AbstractDynamicItemModel::updateComplete, this, &InputsPanel::onItemModelUpdateComplete);
}
}
void InputsPanel::onModelDataUpdateComplete()
void InputsPanel::onItemModelAboutToBeUpdated()
{
lock = true;
modelsUpdateCnt++;
}
void InputsPanel::onItemModelUpdateComplete()
{
modelsUpdateCnt--;
if (modelsUpdateCnt < 1) {
update();
lock = false;
}
}
void InputsPanel::updateItemModels()
{
commonItemModels->update(CommonItemModels::RMO_INPUTS);
sharedItemModels->update(AbstractItemModel::IMUE_Inputs);
}

View file

@ -25,8 +25,8 @@
#include "mixerslistwidget.h"
#include "modelprinter.h"
class CommonItemModels;
class RawItemFilteredModel;
class CompoundItemModelFactory;
class FilteredItemModel;
constexpr char MIMETYPE_EXPO[] = "application/x-companion-expo";
@ -35,7 +35,7 @@ class InputsPanel : public ModelPanel
Q_OBJECT
public:
InputsPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels);
InputsPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels);
virtual ~InputsPanel();
virtual void update();
@ -62,8 +62,8 @@ class InputsPanel : public ModelPanel
void cmInputInsert();
void cmInputMoveDown();
void cmInputMoveUp();
void onModelDataAboutToBeUpdated();
void onModelDataUpdateComplete();
void onItemModelAboutToBeUpdated();
void onItemModelUpdateComplete();
private:
bool expoInserted;
@ -72,10 +72,8 @@ class InputsPanel : public ModelPanel
ModelPrinter modelPrinter;
int selectedIdx;
int inputIdx;
CommonItemModels * commonItemModels;
RawItemFilteredModel *rawSourceFilteredModel;
RawItemFilteredModel *rawSwitchFilteredModel;
RawItemFilteredModel *curveFilteredModel;
CompoundItemModelFactory *sharedItemModels;
int modelsUpdateCnt;
int getExpoIndex(unsigned int dch);
bool gm_insertExpo(int idx);
@ -97,6 +95,7 @@ class InputsPanel : public ModelPanel
int getIndexFromSelected();
int getInputIndexFromSelected();
void updateItemModels();
void connectItemModelEvents(const int id);
};
#endif // _INPUTS_H_

View file

@ -19,25 +19,25 @@
*/
#include "logicalswitches.h"
#include "rawitemfilteredmodel.h"
#include "filtereditemmodels.h"
#include "helpers.h"
#include <TimerEdit>
LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels):
LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware,
CompoundItemModelFactory * sharedItemModels):
ModelPanel(parent, model, generalSettings, firmware),
commonItemModels(commonItemModels),
sharedItemModels(sharedItemModels),
selectedIndex(0),
modelsUpdateCnt(0)
{
rawSwitchFilteredModel = new RawItemFilteredModel(commonItemModels->rawSwitchItemModel(), RawSwitch::LogicalSwitchesContext, this);
connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &LogicalSwitchesPanel::onModelDataAboutToBeUpdated);
connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &LogicalSwitchesPanel::onModelDataUpdateComplete);
rawSwitchFilteredModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSwitch),
RawSwitch::LogicalSwitchesContext);
connectItemModelEvents(rawSwitchFilteredModel);
const int srcGroups = firmware->getCapability(GvarsInCS) ? 0 : (RawSource::AllSourceGroups & ~RawSource::GVarsGroup);
rawSourceFilteredModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), srcGroups, this);
connect(rawSourceFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &LogicalSwitchesPanel::onModelDataAboutToBeUpdated);
connect(rawSourceFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &LogicalSwitchesPanel::onModelDataUpdateComplete);
rawSourceFilteredModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource), srcGroups);
connectItemModelEvents(rawSourceFilteredModel);
lsCapability = firmware->getCapability(LogicalSwitches);
lsCapabilityExt = firmware->getCapability(LogicalSwitchesExt);
@ -161,6 +161,8 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model,
LogicalSwitchesPanel::~LogicalSwitchesPanel()
{
delete rawSourceFilteredModel;
delete rawSwitchFilteredModel;
}
void LogicalSwitchesPanel::onFunctionChanged()
@ -644,16 +646,22 @@ void LogicalSwitchesPanel::swapData(int idx1, int idx2)
void LogicalSwitchesPanel::updateItemModels()
{
lock = true;
commonItemModels->update(CommonItemModels::RMO_LOGICAL_SWITCHES);
sharedItemModels->update(AbstractItemModel::IMUE_LogicalSwitches);
}
void LogicalSwitchesPanel::onModelDataAboutToBeUpdated()
void LogicalSwitchesPanel::connectItemModelEvents(const FilteredItemModel * itemModel)
{
connect(itemModel, &FilteredItemModel::aboutToBeUpdated, this, &LogicalSwitchesPanel::onItemModelAboutToBeUpdated);
connect(itemModel, &FilteredItemModel::updateComplete, this, &LogicalSwitchesPanel::onItemModelUpdateComplete);
}
void LogicalSwitchesPanel::onItemModelAboutToBeUpdated()
{
lock = true;
modelsUpdateCnt++;
}
void LogicalSwitchesPanel::onModelDataUpdateComplete()
void LogicalSwitchesPanel::onItemModelUpdateComplete()
{
modelsUpdateCnt--;
if (modelsUpdateCnt < 1) {

View file

@ -24,8 +24,8 @@
#include "modeledit.h"
#include "radiodata.h"
class CommonItemModels;
class RawItemFilteredModel;
class CompoundItemModelFactory;
class FilteredItemModel;
class TimerEdit;
constexpr char MIMETYPE_LOGICAL_SWITCH[] = "application/x-companion-logical-switch";
@ -35,7 +35,7 @@ class LogicalSwitchesPanel : public ModelPanel
Q_OBJECT
public:
LogicalSwitchesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels);
LogicalSwitchesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels);
virtual ~LogicalSwitchesPanel();
virtual void update();
@ -60,8 +60,8 @@ class LogicalSwitchesPanel : public ModelPanel
void cmInsert();
void cmClear(bool prompt = true);
void cmClearAll();
void onModelDataAboutToBeUpdated();
void onModelDataUpdateComplete();
void onItemModelAboutToBeUpdated();
void onItemModelUpdateComplete();
private:
QComboBox * cbFunction[CPN_MAX_LOGICAL_SWITCHES];
@ -74,9 +74,9 @@ class LogicalSwitchesPanel : public ModelPanel
QDoubleSpinBox * dsbDelay[CPN_MAX_LOGICAL_SWITCHES];
QComboBox * cbSource1[CPN_MAX_LOGICAL_SWITCHES];
QComboBox * cbSource2[CPN_MAX_LOGICAL_SWITCHES];
CommonItemModels * commonItemModels;
RawItemFilteredModel * rawSwitchFilteredModel;
RawItemFilteredModel * rawSourceFilteredModel;
CompoundItemModelFactory * sharedItemModels;
FilteredItemModel * rawSwitchFilteredModel;
FilteredItemModel * rawSourceFilteredModel;
int selectedIndex;
void populateFunctionCB(QComboBox *b);
void updateTimerParam(QDoubleSpinBox *sb, int timer, double minimum=0);
@ -89,6 +89,7 @@ class LogicalSwitchesPanel : public ModelPanel
bool moveUpAllowed() const;
int modelsUpdateCnt;
void updateItemModels();
void connectItemModelEvents(const FilteredItemModel * itemModel);
};
#endif // _LOGICALSWITCHES_H_

View file

@ -21,11 +21,11 @@
#include "mixerdialog.h"
#include "ui_mixerdialog.h"
#include "radiodata.h"
#include "rawitemfilteredmodel.h"
#include "filtereditemmodels.h"
#include "helpers.h"
MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata, GeneralSettings & generalSettings, Firmware * firmware,
RawItemFilteredModel * rawSourceModel, RawItemFilteredModel * rawSwitchModel, RawItemFilteredModel * curveItemModel) :
CompoundItemModelFactory * sharedItemModels) :
QDialog(parent),
ui(new Ui::MixerDialog),
model(model),
@ -36,6 +36,9 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata,
{
ui->setupUi(this);
dialogFilteredItemModels = new FilteredItemModelFactory();
int id;
QRegExp rx(CHAR_FOR_NAMES_REGEX);
QLabel * lb_fp[CPN_MAX_FLIGHT_MODES] = {ui->lb_FP0, ui->lb_FP1, ui->lb_FP2, ui->lb_FP3, ui->lb_FP4, ui->lb_FP5, ui->lb_FP6, ui->lb_FP7, ui->lb_FP8 };
QCheckBox * tmp[CPN_MAX_FLIGHT_MODES] = {ui->cb_FP0, ui->cb_FP1, ui->cb_FP2, ui->cb_FP3, ui->cb_FP4, ui->cb_FP5, ui->cb_FP6, ui->cb_FP7, ui->cb_FP8 };
@ -45,14 +48,20 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata,
this->setWindowTitle(tr("DEST -> %1").arg(RawSource(SOURCE_TYPE_CH, md->destCh - 1).toString(&model, &generalSettings)));
ui->sourceCB->setModel(rawSourceModel);
id = dialogFilteredItemModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource),
((RawSource::InputSourceGroups | RawSource::ScriptsGroup) & ~ RawSource::NoneGroup)),
"RawSource");
ui->sourceCB->setModel(dialogFilteredItemModels->getItemModel(id));
ui->sourceCB->setCurrentIndex(ui->sourceCB->findData(md->srcRaw.toValue()));
int limit = firmware->getCapability(OffsetWeight);
gvWeightGroup = new GVarGroup(ui->weightGV, ui->weightSB, ui->weightCB, md->weight, model, 100, -limit, limit);
gvOffsetGroup = new GVarGroup(ui->offsetGV, ui->offsetSB, ui->offsetCB, md->sOffset, model, 0, -limit, limit);
curveGroup = new CurveReferenceUIManager(ui->curveTypeCB, ui->curveGVarCB, ui->curveValueSB, ui->curveValueCB, md->curve, model, curveItemModel, this);
curveRefFilteredItemModels = new CurveRefFilteredFactory(sharedItemModels,
firmware->getCapability(HasMixerExpo) ? 0 : FilteredItemModel::PositiveFilter);
curveGroup = new CurveReferenceUIManager(ui->curveTypeCB, ui->curveGVarCB, ui->curveValueSB, ui->curveValueCB, md->curve, model,
curveRefFilteredItemModels, this);
ui->MixDR_CB->setChecked(md->noExpo == 0);
@ -104,7 +113,9 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata,
}
}
ui->switchesCB->setModel(rawSwitchModel);
id = dialogFilteredItemModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSwitch),
RawSwitch::MixesContext), "RawSwitch");
ui->switchesCB->setModel(dialogFilteredItemModels->getItemModel(id));
ui->switchesCB->setCurrentIndex(ui->switchesCB->findData(md->swtch.toValue()));
ui->warningCB->setCurrentIndex(md->mixWarn);
ui->mltpxCB->setCurrentIndex(md->mltpx);
@ -150,6 +161,7 @@ MixerDialog::~MixerDialog()
delete ui;
delete gvWeightGroup;
delete gvOffsetGroup;
delete dialogFilteredItemModels;
}
void MixerDialog::changeEvent(QEvent *e)

View file

@ -25,7 +25,9 @@
#include "eeprominterface.h"
class GVarGroup;
class RawItemFilteredModel;
class CompoundItemModelFactory;
class FilteredItemModelFactory;
class CurveRefFilteredFactory;
class CurveReferenceUIManager;
namespace Ui {
@ -36,7 +38,7 @@ class MixerDialog : public QDialog {
Q_OBJECT
public:
MixerDialog(QWidget *parent, ModelData & model, MixData *mixdata, GeneralSettings & generalSettings, Firmware * firmware,
RawItemFilteredModel * rawSourceModel, RawItemFilteredModel * rawSwitchModel, RawItemFilteredModel * curveItemModel);
CompoundItemModelFactory * sharedItemModels);
~MixerDialog();
protected:
@ -61,6 +63,8 @@ class MixerDialog : public QDialog {
GVarGroup * gvOffsetGroup;
CurveReferenceUIManager * curveGroup;
QCheckBox * cb_fp[CPN_MAX_FLIGHT_MODES];
FilteredItemModelFactory *dialogFilteredItemModels;
CurveRefFilteredFactory *curveRefFilteredItemModels;
};
#endif // _MIXERDIALOG_H_

View file

@ -20,26 +20,20 @@
#include "mixes.h"
#include "helpers.h"
#include "rawitemfilteredmodel.h"
#include "filtereditemmodels.h"
MixesPanel::MixesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware,CommonItemModels * commonItemModels):
MixesPanel::MixesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels):
ModelPanel(parent, model, generalSettings, firmware),
mixInserted(false),
highlightedSource(0),
modelPrinter(firmware, generalSettings, model),
commonItemModels(commonItemModels)
sharedItemModels(sharedItemModels),
modelsUpdateCnt(0)
{
rawSourceFilteredModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), ((RawSource::InputSourceGroups | RawSource::ScriptsGroup) & ~ RawSource::NoneGroup), this);
connect(rawSourceFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &MixesPanel::onModelDataAboutToBeUpdated);
connect(rawSourceFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &MixesPanel::onModelDataUpdateComplete);
rawSwitchFilteredModel = new RawItemFilteredModel(commonItemModels->rawSwitchItemModel(), RawSwitch::MixesContext, this);
connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &MixesPanel::onModelDataAboutToBeUpdated);
connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &MixesPanel::onModelDataUpdateComplete);
curveFilteredModel = new RawItemFilteredModel(commonItemModels->curveItemModel(), RawItemFilteredModel::AllFilter, this);
connect(curveFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &MixesPanel::onModelDataAboutToBeUpdated);
connect(curveFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &MixesPanel::onModelDataUpdateComplete);
connectItemModelEvents(AbstractItemModel::IMID_RawSource);
connectItemModelEvents(AbstractItemModel::IMID_RawSwitch);
connectItemModelEvents(AbstractItemModel::IMID_Curve);
connectItemModelEvents(AbstractItemModel::IMID_GVarRef);
QGridLayout * mixesLayout = new QGridLayout(this);
@ -189,7 +183,7 @@ void MixesPanel::gm_openMix(int index)
MixData mixd(model->mixData[index]);
MixerDialog *dlg = new MixerDialog(this, *model, &mixd, generalSettings, firmware, rawSourceFilteredModel, rawSwitchFilteredModel, curveFilteredModel);
MixerDialog *dlg = new MixerDialog(this, *model, &mixd, generalSettings, firmware, sharedItemModels);
if(dlg->exec()) {
model->mixData[index] = mixd;
emit modified();
@ -545,13 +539,26 @@ void MixesPanel::clearMixes()
}
}
void MixesPanel::onModelDataAboutToBeUpdated()
void MixesPanel::connectItemModelEvents(const int id)
{
lock = true;
AbstractDynamicItemModel * itemModel = qobject_cast<AbstractDynamicItemModel *>(sharedItemModels->getItemModel(id));
if (itemModel) {
connect(itemModel, &AbstractDynamicItemModel::aboutToBeUpdated, this, &MixesPanel::onItemModelAboutToBeUpdated);
connect(itemModel, &AbstractDynamicItemModel::updateComplete, this, &MixesPanel::onItemModelUpdateComplete);
}
}
void MixesPanel::onModelDataUpdateComplete()
void MixesPanel::onItemModelAboutToBeUpdated()
{
lock = true;
modelsUpdateCnt++;
}
void MixesPanel::onItemModelUpdateComplete()
{
modelsUpdateCnt--;
if (modelsUpdateCnt < 1) {
update();
lock = false;
}
}

View file

@ -26,15 +26,15 @@
#include "mixerdialog.h"
#include "modelprinter.h"
class CommonItemModels;
class RawItemFilteredModel;
class CompoundItemModelFactory;
class FilteredItemModel;
class MixesPanel : public ModelPanel
{
Q_OBJECT
public:
MixesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels);
MixesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels);
virtual ~MixesPanel();
virtual void update();
@ -60,18 +60,16 @@ class MixesPanel : public ModelPanel
void mimeMixerDropped(int index, const QMimeData *data, Qt::DropAction action);
void pasteMixerMimeData(const QMimeData * mimeData, int destIdx);
void onModelDataAboutToBeUpdated();
void onModelDataUpdateComplete();
void onItemModelAboutToBeUpdated();
void onItemModelUpdateComplete();
private:
MixersListWidget * mixersListWidget;
bool mixInserted;
unsigned int highlightedSource;
ModelPrinter modelPrinter;
CommonItemModels * commonItemModels;
RawItemFilteredModel *rawSourceFilteredModel;
RawItemFilteredModel *rawSwitchFilteredModel;
RawItemFilteredModel *curveFilteredModel;
CompoundItemModelFactory *sharedItemModels;
int modelsUpdateCnt;
int getMixerIndex(unsigned int dch);
bool gm_insertMix(int idx);
@ -83,6 +81,7 @@ class MixesPanel : public ModelPanel
void setSelectedByMixList(QList<int> list);
void AddMixerLine(int dest);
QString getMixerText(int dest, bool newChannel);
void connectItemModelEvents(const int id);
};
#endif // _MIXES_H_

View file

@ -33,7 +33,7 @@
#include "customfunctions.h"
#include "telemetry.h"
#include "appdata.h"
#include "rawitemdatamodels.h"
#include "compounditemmodels.h"
ModelEdit::ModelEdit(QWidget * parent, RadioData & radioData, int modelId, Firmware * firmware) :
QDialog(parent),
@ -53,42 +53,53 @@ ModelEdit::ModelEdit(QWidget * parent, RadioData & radioData, int modelId, Firmw
GeneralSettings &generalSettings = radioData.generalSettings;
ModelData &model = radioData.models[modelId];
commonItemModels = new CommonItemModels(&generalSettings, &model, this);
sharedItemModels = new CompoundItemModelFactory(&generalSettings, &model);
sharedItemModels->addItemModel(AbstractItemModel::IMID_RawSource);
sharedItemModels->addItemModel(AbstractItemModel::IMID_RawSwitch);
sharedItemModels->addItemModel(AbstractItemModel::IMID_Curve);
sharedItemModels->addItemModel(AbstractItemModel::IMID_GVarRef);
sharedItemModels->addItemModel(AbstractItemModel::IMID_ThrSource);
sharedItemModels->addItemModel(AbstractItemModel::IMID_CustomFuncAction);
sharedItemModels->addItemModel(AbstractItemModel::IMID_CustomFuncResetParam);
sharedItemModels->addItemModel(AbstractItemModel::IMID_TeleSource);
sharedItemModels->addItemModel(AbstractItemModel::IMID_CurveRefType);
sharedItemModels->addItemModel(AbstractItemModel::IMID_CurveRefFunc);
s1.report("Init");
SetupPanel * setupPanel = new SetupPanel(this, model, generalSettings, firmware, commonItemModels);
SetupPanel * setupPanel = new SetupPanel(this, model, generalSettings, firmware, sharedItemModels);
addTab(setupPanel, tr("Setup"));
s1.report("Setup");
if (firmware->getCapability(Heli)) {
addTab(new HeliPanel(this, model, generalSettings, firmware, commonItemModels), tr("Heli"));
addTab(new HeliPanel(this, model, generalSettings, firmware, sharedItemModels), tr("Heli"));
s1.report("Heli");
}
addTab(new FlightModesPanel(this, model, generalSettings, firmware, commonItemModels), tr("Flight Modes"));
addTab(new FlightModesPanel(this, model, generalSettings, firmware, sharedItemModels), tr("Flight Modes"));
s1.report("Flight Modes");
addTab(new InputsPanel(this, model, generalSettings, firmware, commonItemModels), tr("Inputs"));
addTab(new InputsPanel(this, model, generalSettings, firmware, sharedItemModels), tr("Inputs"));
s1.report("Inputs");
addTab(new MixesPanel(this, model, generalSettings, firmware, commonItemModels), tr("Mixes"));
addTab(new MixesPanel(this, model, generalSettings, firmware, sharedItemModels), tr("Mixes"));
s1.report("Mixes");
ChannelsPanel * channelsPanel = new ChannelsPanel(this, model, generalSettings, firmware, commonItemModels);
ChannelsPanel * channelsPanel = new ChannelsPanel(this, model, generalSettings, firmware, sharedItemModels);
addTab(channelsPanel, tr("Outputs"));
s1.report("Outputs");
addTab(new CurvesPanel(this, model, generalSettings, firmware, commonItemModels), tr("Curves"));
addTab(new CurvesPanel(this, model, generalSettings, firmware, sharedItemModels), tr("Curves"));
s1.report("Curves");
addTab(new LogicalSwitchesPanel(this, model, generalSettings, firmware, commonItemModels), tr("Logical Switches"));
addTab(new LogicalSwitchesPanel(this, model, generalSettings, firmware, sharedItemModels), tr("Logical Switches"));
s1.report("Logical Switches");
addTab(new CustomFunctionsPanel(this, &model, generalSettings, firmware, commonItemModels), tr("Special Functions"));
addTab(new CustomFunctionsPanel(this, &model, generalSettings, firmware, sharedItemModels), tr("Special Functions"));
s1.report("Special Functions");
if (firmware->getCapability(Telemetry)) {
addTab(new TelemetryPanel(this, model, generalSettings, firmware, commonItemModels), tr("Telemetry"));
addTab(new TelemetryPanel(this, model, generalSettings, firmware, sharedItemModels), tr("Telemetry"));
s1.report("Telemetry");
}
@ -104,6 +115,7 @@ ModelEdit::ModelEdit(QWidget * parent, RadioData & radioData, int modelId, Firmw
ModelEdit::~ModelEdit()
{
delete ui;
delete sharedItemModels;
}
void ModelEdit::closeEvent(QCloseEvent *event)

View file

@ -25,7 +25,7 @@
#include "genericpanel.h"
class RadioData;
class CommonItemModels;
class CompoundItemModelFactory;
namespace Ui {
class ModelEdit;
@ -60,12 +60,12 @@ class ModelEdit : public QDialog
private:
Ui::ModelEdit *ui;
int modelId;
RadioData & radioData;
Firmware * firmware;
RadioData &radioData;
Firmware *firmware;
QVector<GenericPanel *> panels;
CommonItemModels * commonItemModels;
CompoundItemModelFactory *sharedItemModels;
void addTab(GenericPanel *panel, QString text);
void addTab(GenericPanel * panel, QString text);
void launchSimulation();
};

View file

@ -22,7 +22,7 @@
#include "ui_setup.h"
#include "ui_setup_timer.h"
#include "ui_setup_module.h"
#include "rawitemfilteredmodel.h"
#include "filtereditemmodels.h"
#include "appdata.h"
#include "modelprinter.h"
#include "multiprotocols.h"
@ -31,14 +31,14 @@
#include <QDir>
TimerPanel::TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, Firmware * firmware, QWidget * prevFocus, RawItemFilteredModel * rawSwitchFilteredModel):
TimerPanel::TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, Firmware * firmware,
QWidget * prevFocus, FilteredItemModel * rawSwitchFilteredModel):
ModelPanel(parent, model, generalSettings, firmware),
timer(timer),
ui(new Ui::Timer)
{
ui->setupUi(this);
connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &TimerPanel::onModelDataAboutToBeUpdated);
connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &TimerPanel::onModelDataUpdateComplete);
connectItemModelEvents(rawSwitchFilteredModel);
lock = true;
@ -172,12 +172,18 @@ void TimerPanel::on_name_editingFinished()
}
}
void TimerPanel::onModelDataAboutToBeUpdated()
void TimerPanel::connectItemModelEvents(const FilteredItemModel * itemModel)
{
connect(itemModel, &FilteredItemModel::aboutToBeUpdated, this, &TimerPanel::onItemModelAboutToBeUpdated);
connect(itemModel, &FilteredItemModel::updateComplete, this, &TimerPanel::onItemModelUpdateComplete);
}
void TimerPanel::onItemModelAboutToBeUpdated()
{
lock = true;
}
void TimerPanel::onModelDataUpdateComplete()
void TimerPanel::onItemModelUpdateComplete()
{
update();
lock = false;
@ -991,13 +997,19 @@ void ModulePanel::onClearAccessRxClicked()
/******************************************************************************/
SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels):
SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware,
CompoundItemModelFactory * sharedItemModels) :
ModelPanel(parent, model, generalSettings, firmware),
ui(new Ui::Setup),
commonItemModels(commonItemModels)
sharedItemModels(sharedItemModels)
{
ui->setupUi(this);
rawSwitchFilteredModel = new RawItemFilteredModel(commonItemModels->rawSwitchItemModel(), RawSwitch::TimersContext, this);
rawSwitchFilteredModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSwitch), RawSwitch::TimersContext);
connectItemModelEvents(rawSwitchFilteredModel);
thrSourceFilteredModel = new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_ThrSource));
connectItemModelEvents(thrSourceFilteredModel);
Board::Type board = firmware->getBoard();
@ -1248,6 +1260,8 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
SetupPanel::~SetupPanel()
{
delete ui;
delete rawSwitchFilteredModel;
delete thrSourceFilteredModel;
}
void SetupPanel::on_extendedLimits_toggled(bool checked)
@ -1750,7 +1764,21 @@ void SetupPanel::onTimerNameChanged()
updateItemModels();
}
void SetupPanel::connectItemModelEvents(const FilteredItemModel * itemModel)
{
connect(itemModel, &FilteredItemModel::aboutToBeUpdated, this, &SetupPanel::onItemModelAboutToBeUpdated);
connect(itemModel, &FilteredItemModel::updateComplete, this, &SetupPanel::onItemModelUpdateComplete);
}
void SetupPanel::onItemModelAboutToBeUpdated()
{
}
void SetupPanel::onItemModelUpdateComplete()
{
}
void SetupPanel::updateItemModels()
{
commonItemModels->update(CommonItemModels::RMO_TIMERS);
sharedItemModels->update(AbstractItemModel::IMUE_Timers);
}

View file

@ -26,8 +26,8 @@
constexpr char MIMETYPE_TIMER[] = "application/x-companion-timer";
class CommonItemModels;
class RawItemFilteredModel;
class CompoundItemModelFactory;
class FilteredItemModel;
namespace Ui {
class Setup;
@ -40,7 +40,8 @@ class TimerPanel : public ModelPanel
Q_OBJECT
public:
TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, Firmware * firmware, QWidget *prevFocus, RawItemFilteredModel * switchModel);
TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, Firmware * firmware,
QWidget *prevFocus, FilteredItemModel * switchModel);
virtual ~TimerPanel();
virtual void update();
@ -51,8 +52,8 @@ class TimerPanel : public ModelPanel
void on_value_editingFinished();
void on_minuteBeep_toggled(bool checked);
void on_name_editingFinished();
void onModelDataAboutToBeUpdated();
void onModelDataUpdateComplete();
void onItemModelAboutToBeUpdated();
void onItemModelUpdateComplete();
signals:
void nameChanged();
@ -60,6 +61,7 @@ class TimerPanel : public ModelPanel
private:
TimerData & timer;
Ui::Timer * ui;
void connectItemModelEvents(const FilteredItemModel * itemModel);
};
class ModulePanel : public ModelPanel
@ -131,7 +133,7 @@ class SetupPanel : public ModelPanel
Q_OBJECT
public:
SetupPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels);
SetupPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels);
virtual ~SetupPanel();
virtual void update();
@ -170,6 +172,8 @@ class SetupPanel : public ModelPanel
void cmTimerMoveDown();
void cmTimerMoveUp();
void onTimerNameChanged();
void onItemModelAboutToBeUpdated();
void onItemModelUpdateComplete();
private:
Ui::Setup *ui;
@ -191,9 +195,11 @@ class SetupPanel : public ModelPanel
bool moveTimerDownAllowed() const;
bool moveTimerUpAllowed() const;
void swapTimerData(int idx1, int idx2);
CommonItemModels * commonItemModels;
RawItemFilteredModel * rawSwitchFilteredModel;
CompoundItemModelFactory * sharedItemModels;
FilteredItemModel * rawSwitchFilteredModel;
FilteredItemModel * thrSourceFilteredModel;
void updateItemModels();
};
void connectItemModelEvents(const FilteredItemModel * itemModel);
};
#endif // _SETUP_H_

View file

@ -24,24 +24,36 @@
#include "ui_telemetry_sensor.h"
#include "helpers.h"
#include "appdata.h"
#include "rawitemfilteredmodel.h"
#include <TimerEdit>
TelemetryCustomScreen::TelemetryCustomScreen(QWidget *parent, ModelData & model, FrSkyScreenData & screen, GeneralSettings & generalSettings, Firmware * firmware, RawItemFilteredModel * rawSourceModel):
constexpr char FIM_RAWSOURCE[] {"Raw Source"};
constexpr char FIM_TELEALLSRC[] {"Tele All Source"};
constexpr char FIM_TELEPOSSRC[] {"Tele Pos Source"};
constexpr char FIM_SENSORTYPE[] {"Sensor.Type"};
constexpr char FIM_SENSORFORMULA[] {"Sensor.Formula"};
constexpr char FIM_SENSORCELLINDEX[] {"Sensor.CellIndex"};
constexpr char FIM_SENSORUNIT[] {"Sensor.Unit"};
constexpr char FIM_SENSORPRECISION[] {"Sensor.Precision"};
TelemetryCustomScreen::TelemetryCustomScreen(QWidget *parent, ModelData & model, FrSkyScreenData & screen, GeneralSettings & generalSettings,
Firmware * firmware, const bool & parentLock, FilteredItemModelFactory * panelFilteredItemModels):
ModelPanel(parent, model, generalSettings, firmware),
ui(new Ui::TelemetryCustomScreen),
screen(screen)
screen(screen),
modelsUpdateCnt(0),
parentLock(parentLock)
{
ui->setupUi(this);
connect(rawSourceModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &TelemetryCustomScreen::onModelDataAboutToBeUpdated);
connect(rawSourceModel, &RawItemFilteredModel::dataUpdateComplete, this, &TelemetryCustomScreen::onModelDataUpdateComplete);
FilteredItemModel * rawSourceFilteredModel = panelFilteredItemModels->getItemModel(FIM_RAWSOURCE);
connectItemModelEvents(rawSourceFilteredModel);
for (int l = 0; l < firmware->getCapability(TelemetryCustomScreensLines); l++) {
for (int c = 0; c < firmware->getCapability(TelemetryCustomScreensFieldsPerLine); c++) {
fieldsCB[l][c] = new QComboBox(this);
fieldsCB[l][c]->setProperty("index", c + (l << 8));
fieldsCB[l][c]->setModel(rawSourceModel);
fieldsCB[l][c]->setModel(rawSourceFilteredModel);
ui->screenNumsLayout->addWidget(fieldsCB[l][c], l, c, 1, 1);
connect(fieldsCB[l][c], SIGNAL(activated(int)), this, SLOT(customFieldChanged(int)));
}
@ -50,7 +62,7 @@ TelemetryCustomScreen::TelemetryCustomScreen(QWidget *parent, ModelData & model,
for (int l = 0; l < firmware->getCapability(TelemetryCustomScreensBars); l++) {
barsCB[l] = new QComboBox(this);
barsCB[l]->setProperty("index", l);
barsCB[l]->setModel(rawSourceModel);
barsCB[l]->setModel(rawSourceFilteredModel);
connect(barsCB[l], SIGNAL(activated(int)), this, SLOT(barSourceChanged(int)));
ui->screenBarsLayout->addWidget(barsCB[l], l, 0, 1, 1);
@ -203,7 +215,7 @@ void TelemetryCustomScreen::updateBar(int line)
void TelemetryCustomScreen::on_screenType_currentIndexChanged(int index)
{
if (!lock) {
if (!isLocked()) {
memset(reinterpret_cast<void *>(&screen.body), 0, sizeof(screen.body));
update();
emit modified();
@ -212,7 +224,7 @@ void TelemetryCustomScreen::on_screenType_currentIndexChanged(int index)
void TelemetryCustomScreen::scriptNameEdited()
{
if (!lock) {
if (!isLocked()) {
lock = true;
Helpers::getFileComboBoxValue(ui->scriptName, screen.body.script.filename, 8);
emit modified();
@ -222,7 +234,7 @@ void TelemetryCustomScreen::scriptNameEdited()
void TelemetryCustomScreen::customFieldChanged(int value)
{
if (lock || !sender() || !qobject_cast<QComboBox *>(sender()))
if (isLocked() || !sender() || !qobject_cast<QComboBox *>(sender()))
return;
bool ok;
@ -238,7 +250,7 @@ void TelemetryCustomScreen::customFieldChanged(int value)
void TelemetryCustomScreen::barSourceChanged(int value)
{
if (lock || !sender() || !qobject_cast<QComboBox *>(sender()))
if (isLocked() || !sender() || !qobject_cast<QComboBox *>(sender()))
return;
bool ok;
@ -256,7 +268,7 @@ void TelemetryCustomScreen::barSourceChanged(int value)
void TelemetryCustomScreen::barMinChanged(double value)
{
if (!lock) {
if (!isLocked()) {
int line = sender()->property("index").toInt();
screen.body.bars[line].barMin = round(value / minSB[line]->singleStep());
// TODO set min (maxSB)
@ -266,7 +278,7 @@ void TelemetryCustomScreen::barMinChanged(double value)
void TelemetryCustomScreen::barMaxChanged(double value)
{
if (!lock) {
if (!isLocked()) {
int line = sender()->property("index").toInt();
screen.body.bars[line].barMax = round((value) / maxSB[line]->singleStep());
// TODO set max (minSB)
@ -276,7 +288,7 @@ void TelemetryCustomScreen::barMaxChanged(double value)
void TelemetryCustomScreen::barTimeChanged()
{
if (!lock) {
if (!isLocked()) {
int line = sender()->property("index").toInt();
int & valRef = (sender()->property("type").toString() == "min" ? screen.body.bars[line].barMin : screen.body.bars[line].barMax);
TimerEdit * te = qobject_cast<TimerEdit *>(sender());
@ -289,29 +301,51 @@ void TelemetryCustomScreen::barTimeChanged()
}
}
void TelemetryCustomScreen::onModelDataAboutToBeUpdated()
void TelemetryCustomScreen::connectItemModelEvents(const FilteredItemModel * itemModel)
{
lock = true;
connect(itemModel, &FilteredItemModel::aboutToBeUpdated, this, &TelemetryCustomScreen::onItemModelAboutToBeUpdated);
connect(itemModel, &FilteredItemModel::updateComplete, this, &TelemetryCustomScreen::onItemModelUpdateComplete);
}
void TelemetryCustomScreen::onModelDataUpdateComplete()
void TelemetryCustomScreen::onItemModelAboutToBeUpdated()
{
update();
lock = true;
modelsUpdateCnt++;
}
void TelemetryCustomScreen::onItemModelUpdateComplete()
{
modelsUpdateCnt--;
if (modelsUpdateCnt < 1) {
// leave updating to parent
lock = false;
}
}
/******************************************************/
TelemetrySensorPanel::TelemetrySensorPanel(QWidget *parent, SensorData & sensor, int sensorIndex, int sensorCapability, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware):
TelemetrySensorPanel::TelemetrySensorPanel(QWidget *parent, SensorData & sensor, int sensorIndex, int sensorCapability, ModelData & model,
GeneralSettings & generalSettings, Firmware * firmware, const bool & parentLock,
FilteredItemModelFactory * panelFilteredItemModels) :
ModelPanel(parent, model, generalSettings, firmware),
ui(new Ui::TelemetrySensor),
sensor(sensor),
lock(false),
sensorIndex(sensorIndex),
selectedIndex(0),
sensorCapability(sensorCapability)
sensorCapability(sensorCapability),
modelsUpdateCnt(0),
parentLock(parentLock)
{
// TODO ui definition housekeeping
// - remove all predefined combobox lists leaving to code
// - use Auto types for consistency
ui->setupUi(this);
FilteredItemModel * fltmdl;
connectItemModelEvents(panelFilteredItemModels->getItemModel(FIM_TELEALLSRC));
connectItemModelEvents(panelFilteredItemModels->getItemModel(FIM_TELEPOSSRC));
lock = true;
ui->numLabel->setText(tr("TELE%1").arg(sensorIndex + 1));
ui->numLabel->setProperty("index", sensorIndex);
ui->numLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
@ -326,6 +360,9 @@ TelemetrySensorPanel::TelemetrySensorPanel(QWidget *parent, SensorData & sensor,
connect(ui->numLabel, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(on_customContextMenuRequested(QPoint)));
ui->id->setField(sensor.id, this);
ui->instance->setField(sensor.instance, this);
ui->type->setModel(panelFilteredItemModels->getItemModel(FIM_SENSORTYPE));
ui->formula->setModel(panelFilteredItemModels->getItemModel(FIM_SENSORFORMULA));
ui->unit->setModel(panelFilteredItemModels->getItemModel(FIM_SENSORUNIT));
ui->ratio->setField(sensor.ratio, this);
ui->offset->setField(sensor.offset, this);
ui->autoOffset->setField(sensor.autoOffset, this);
@ -333,21 +370,29 @@ TelemetrySensorPanel::TelemetrySensorPanel(QWidget *parent, SensorData & sensor,
ui->logs->setField(sensor.logs, this);
ui->persistent->setField(sensor.persistent, this);
ui->onlyPositive->setField(sensor.onlyPositive, this);
fltmdl = panelFilteredItemModels->getItemModel(FIM_TELEPOSSRC);
ui->gpsSensor->setModel(fltmdl);
ui->gpsSensor->setField(sensor.gps, this);
ui->altSensor->setModel(fltmdl);
ui->altSensor->setField(sensor.alt, this);
ui->ampsSensor->setModel(fltmdl);
ui->ampsSensor->setField(sensor.amps, this);
ui->cellsSensor->setModel(fltmdl);
ui->cellsSensor->setField(sensor.source, this);
ui->cellsIndex->addItem(tr("Lowest"), SensorData::TELEM_CELL_INDEX_LOWEST);
for (int i = SensorData::TELEM_CELL_INDEX_LOWEST + 1; i < SensorData::TELEM_CELL_INDEX_HIGHEST; i++)
ui->cellsIndex->addItem(tr("Cell %1").arg(i), i);
ui->cellsIndex->addItem(tr("Highest"), SensorData::TELEM_CELL_INDEX_HIGHEST);
ui->cellsIndex->addItem(tr("Delta"), SensorData::TELEM_CELL_INDEX_DELTA);
ui->cellsIndex->setModel(panelFilteredItemModels->getItemModel(FIM_SENSORCELLINDEX));
ui->cellsIndex->setField(sensor.index);
fltmdl = panelFilteredItemModels->getItemModel(FIM_TELEALLSRC);
ui->source1->setModel(fltmdl);
ui->source1->setField(sensor.sources[0], this);
ui->source2->setModel(fltmdl);
ui->source2->setField(sensor.sources[1], this);
ui->source3->setModel(fltmdl);
ui->source3->setField(sensor.sources[2], this);
ui->source4->setModel(fltmdl);
ui->source4->setField(sensor.sources[3], this);
ui->prec->setField(sensor.prec, 0, 2, false, "", this);
ui->prec->setField(sensor.prec, 0, 2, false, "", this); // TODO replace autoprecisioncombobox with autocombobox and filtereditemmodel
lock = false;
update();
}
@ -358,6 +403,7 @@ TelemetrySensorPanel::~TelemetrySensorPanel()
void TelemetrySensorPanel::update()
{
// TODO use bit mask
bool isConfigurable = false;
bool gpsFieldsDisplayed = false;
bool cellsFieldsDisplayed = false;
@ -369,8 +415,8 @@ void TelemetrySensorPanel::update()
lock = true;
ui->name->setText(sensor.label);
ui->type->setCurrentIndex(sensor.type);
ui->unit->setCurrentIndex(sensor.unit);
ui->type->setCurrentIndex(ui->type->findData(sensor.type));
ui->unit->setCurrentIndex(ui->unit->findData(sensor.unit));
ui->id->updateValue();
ui->instance->updateValue();
ui->ratio->updateValue();
@ -396,7 +442,7 @@ void TelemetrySensorPanel::update()
ui->originLabel->hide();
ui->origin->hide();
ui->formula->show();
ui->formula->setCurrentIndex(sensor.formula);
ui->formula->setCurrentIndex(ui->formula->findData(sensor.formula));
isConfigurable = (sensor.formula < SensorData::TELEM_FORMULA_CELL);
gpsFieldsDisplayed = (sensor.formula == SensorData::TELEM_FORMULA_DIST);
cellsFieldsDisplayed = (sensor.formula == SensorData::TELEM_FORMULA_CELL);
@ -404,14 +450,10 @@ void TelemetrySensorPanel::update()
sources12FieldsDisplayed = (sensor.formula <= SensorData::TELEM_FORMULA_MULTIPLY);
sources34FieldsDisplayed = (sensor.formula < SensorData::TELEM_FORMULA_MULTIPLY);
totalizeFieldsDisplayed = (sensor.formula == SensorData::TELEM_FORMULA_TOTALIZE);
updateSourcesComboBox(ui->source1, true);
updateSourcesComboBox(ui->source2, true);
updateSourcesComboBox(ui->source3, true);
updateSourcesComboBox(ui->source4, true);
updateSourcesComboBox(ui->gpsSensor, false);
updateSourcesComboBox(ui->altSensor, false);
updateSourcesComboBox(ui->ampsSensor, false);
updateSourcesComboBox(ui->cellsSensor, false);
ui->source1->updateValue();
ui->source2->updateValue();
ui->source3->updateValue();
ui->source4->updateValue();
}
else {
ui->idLabel->show();
@ -483,40 +525,9 @@ void TelemetrySensorPanel::update()
lock = false;
}
void populateTelemetrySourcesComboBox(AutoComboBox * cb, const ModelData * model, bool negative)
{
cb->clear();
if (negative) {
for (int i = -CPN_MAX_SENSORS; i < 0; ++i) {
const SensorData& sensor = model->sensorData[-i - 1];
if (sensor.isAvailable()) {
if (sensor.type == SensorData::TELEM_TYPE_CUSTOM)
cb->addItem(QString("-%1 (%2)").arg(sensor.label, sensor.getOrigin(model)), i);
else
cb->addItem(QString("-%1").arg(sensor.label), i);
}
}
}
cb->addItem("---", 0);
for (unsigned i = 1; i <= CPN_MAX_SENSORS; ++i) {
const SensorData& sensor = model->sensorData[i-1];
if (sensor.isAvailable()) {
if (sensor.type == SensorData::TELEM_TYPE_CUSTOM)
cb->addItem(QString("%1 (%2)").arg(sensor.label, sensor.getOrigin(model)), i);
else
cb->addItem(QString("%1").arg(sensor.label), i);
}
}
}
void TelemetrySensorPanel::updateSourcesComboBox(AutoComboBox * cb, bool negative)
{
populateTelemetrySourcesComboBox(cb, model, negative);
}
void TelemetrySensorPanel::on_name_editingFinished()
{
if (!lock) {
if (!isLocked() && (sensor.label != ui->name->text().toLatin1())) {
strcpy(sensor.label, ui->name->text().toLatin1());
emit dataModified();
}
@ -524,8 +535,8 @@ void TelemetrySensorPanel::on_name_editingFinished()
void TelemetrySensorPanel::on_type_currentIndexChanged(int index)
{
if (!lock) {
sensor.type = index;
if (!isLocked()) {
sensor.type = ui->type->itemData(index).toInt();
update();
emit modified();
}
@ -533,8 +544,8 @@ void TelemetrySensorPanel::on_type_currentIndexChanged(int index)
void TelemetrySensorPanel::on_formula_currentIndexChanged(int index)
{
if (!lock) {
sensor.formula = index;
if (!isLocked()) {
sensor.formula = ui->formula->itemData(index).toInt();
if (sensor.formula == SensorData::TELEM_FORMULA_CELL) {
sensor.prec = 2;
sensor.unit = SensorData::UNIT_VOLTS;
@ -553,8 +564,8 @@ void TelemetrySensorPanel::on_formula_currentIndexChanged(int index)
void TelemetrySensorPanel::on_unit_currentIndexChanged(int index)
{
if (!lock) {
sensor.unit = index;
if (!isLocked()) {
sensor.unit = ui->unit->itemData(index).toInt();
if (sensor.unit == SensorData::UNIT_FAHRENHEIT) {
sensor.prec = 0;
}
@ -565,7 +576,7 @@ void TelemetrySensorPanel::on_unit_currentIndexChanged(int index)
void TelemetrySensorPanel::on_prec_valueChanged()
{
if (!lock) {
if (!isLocked()) {
update();
}
}
@ -686,15 +697,69 @@ void TelemetrySensorPanel::cmMoveDown()
emit moveDownSensor(selectedIndex);
}
void TelemetrySensorPanel::connectItemModelEvents(const FilteredItemModel * itemModel)
{
connect(itemModel, &FilteredItemModel::aboutToBeUpdated, this, &TelemetrySensorPanel::onItemModelAboutToBeUpdated);
connect(itemModel, &FilteredItemModel::updateComplete, this, &TelemetrySensorPanel::onItemModelUpdateComplete);
}
void TelemetrySensorPanel::onItemModelAboutToBeUpdated()
{
lock = true;
modelsUpdateCnt++;
}
void TelemetrySensorPanel::onItemModelUpdateComplete()
{
modelsUpdateCnt--;
if (modelsUpdateCnt < 1) {
// leave updating to parent
lock = false;
}
}
/******************************************************/
TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels):
TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware,
CompoundItemModelFactory * sharedItemModels):
ModelPanel(parent, model, generalSettings, firmware),
ui(new Ui::Telemetry),
commonItemModels(commonItemModels)
sharedItemModels(sharedItemModels),
modelsUpdateCnt(0)
{
ui->setupUi(this);
rawSourceFilteredModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), this);
panelItemModels = new CompoundItemModelFactory(&generalSettings, &model);
panelFilteredItemModels = new FilteredItemModelFactory();
int id;
id = panelFilteredItemModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource)),
FIM_RAWSOURCE);
connectItemModelEvents(id);
id = panelFilteredItemModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_TeleSource)),
FIM_TELEALLSRC);
connectItemModelEvents(id);
id = panelFilteredItemModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_TeleSource),
FilteredItemModel::PositiveFilter),
FIM_TELEPOSSRC);
connectItemModelEvents(id);
id = panelItemModels->registerItemModel(SensorData::typeItemModel());
panelFilteredItemModels->registerItemModel(new FilteredItemModel(panelItemModels->getItemModel(id)), FIM_SENSORTYPE);
id = panelItemModels->registerItemModel(SensorData::formulaItemModel());
panelFilteredItemModels->registerItemModel(new FilteredItemModel(panelItemModels->getItemModel(id)), FIM_SENSORFORMULA);
id = panelItemModels->registerItemModel(SensorData::cellIndexItemModel());
panelFilteredItemModels->registerItemModel(new FilteredItemModel(panelItemModels->getItemModel(id)), FIM_SENSORCELLINDEX);
id = panelItemModels->registerItemModel(SensorData::unitItemModel());
panelFilteredItemModels->registerItemModel(new FilteredItemModel(panelItemModels->getItemModel(id)), FIM_SENSORUNIT);
id = panelItemModels->registerItemModel(SensorData::precisionItemModel());
panelFilteredItemModels->registerItemModel(new FilteredItemModel(panelItemModels->getItemModel(id)), FIM_SENSORPRECISION);
sensorCapability = firmware->getCapability(Sensors);
if (sensorCapability > CPN_MAX_SENSORS) // TODO should be role of getCapability
@ -704,13 +769,15 @@ TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettin
model.frsky.usrProto = 1;
}
ui->varioSource->setModel(panelFilteredItemModels->getItemModel(FIM_TELEPOSSRC));
ui->varioSource->setField(model.frsky.varioSource, this);
ui->varioCenterSilent->setField(model.frsky.varioCenterSilent, this);
ui->A1GB->hide();
ui->A2GB->hide();
for (int i = 0; i < sensorCapability; ++i) {
TelemetrySensorPanel * panel = new TelemetrySensorPanel(this, model.sensorData[i], i, sensorCapability, model, generalSettings, firmware);
TelemetrySensorPanel * panel = new TelemetrySensorPanel(this, model.sensorData[i], i, sensorCapability, model, generalSettings,
firmware, lock, panelFilteredItemModels);
ui->sensorsLayout->addWidget(panel);
sensorPanels[i] = panel;
connect(panel, SIGNAL(dataModified()), this, SLOT(on_dataModifiedSensor()));
@ -723,7 +790,9 @@ TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettin
}
if (IS_TARANIS_X9(firmware->getBoard())) {
ui->voltsSource->setModel(panelFilteredItemModels->getItemModel(FIM_TELEPOSSRC));
ui->voltsSource->setField(model.frsky.voltsSource, this);
ui->altitudeSource->setModel(panelFilteredItemModels->getItemModel(FIM_TELEPOSSRC));
ui->altitudeSource->setField(model.frsky.altitudeSource, this);
}
else {
@ -731,7 +800,8 @@ TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettin
}
for (int i = 0; i < firmware->getCapability(TelemetryCustomScreens); i++) {
TelemetryCustomScreen * tab = new TelemetryCustomScreen(this, model, model.frsky.screens[i], generalSettings, firmware, rawSourceFilteredModel);
TelemetryCustomScreen * tab = new TelemetryCustomScreen(this, model, model.frsky.screens[i], generalSettings, firmware, lock,
panelFilteredItemModels);
ui->customScreens->addTab(tab, tr("Telemetry screen %1").arg(i + 1));
telemetryCustomScreens[i] = tab;
connect(tab, &TelemetryCustomScreen::modified, this, &TelemetryPanel::onModified);
@ -745,10 +815,14 @@ TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettin
TelemetryPanel::~TelemetryPanel()
{
delete ui;
delete panelFilteredItemModels;
delete panelItemModels;
}
void TelemetryPanel::update()
{
lock = true;
if (IS_HORUS_OR_TARANIS(firmware->getBoard())) {
if (model->moduleData[0].protocol == PULSES_OFF && model->moduleData[1].protocol == PULSES_PPM) {
ui->telemetryProtocol->setEnabled(true);
@ -758,10 +832,10 @@ void TelemetryPanel::update()
ui->telemetryProtocol->setCurrentIndex(0);
}
populateTelemetrySourcesComboBox(ui->rssiSourceCB, model, false);
populateTelemetrySourcesComboBox(ui->voltsSource, model, false);
populateTelemetrySourcesComboBox(ui->altitudeSource, model, false);
populateTelemetrySourcesComboBox(ui->varioSource, model, false);
ui->rssiSourceCB->updateValue();
ui->voltsSource->updateValue();
ui->altitudeSource->updateValue();
ui->varioSource->updateValue();
}
for (int i = 0; i < sensorCapability; ++i) {
@ -771,6 +845,8 @@ void TelemetryPanel::update()
for (int i = 0; i < firmware->getCapability(TelemetryCustomScreens); i++) {
telemetryCustomScreens[i]->update();
}
lock = false;
}
void TelemetryPanel::setup()
@ -792,9 +868,9 @@ void TelemetryPanel::setup()
ui->rssiSourceLabel->show();
ui->rssiSourceLabel->setText(tr("Source"));
ui->rssiSourceCB->setModel(panelFilteredItemModels->getItemModel(FIM_TELEPOSSRC));
ui->rssiSourceCB->setField(model->rssiSource, this);
ui->rssiSourceCB->show();
populateTelemetrySourcesComboBox(ui->rssiSourceCB, model, false);
ui->rssiAlarmWarningCB->hide();
ui->rssiAlarmCriticalCB->hide();
@ -842,44 +918,9 @@ void TelemetryPanel::setup()
lock = false;
}
void TelemetryPanel::populateVarioSource()
{
AutoComboBox * cb = ui->varioSource;
cb->setField(model->frsky.varioSource, this);
cb->addItem(tr("Alti"), TELEMETRY_VARIO_SOURCE_ALTI);
cb->addItem(tr("Alti+"), TELEMETRY_VARIO_SOURCE_ALTI_PLUS);
cb->addItem(tr("VSpeed"), TELEMETRY_VARIO_SOURCE_VSPEED);
cb->addItem(tr("A1"), TELEMETRY_VARIO_SOURCE_A1);
cb->addItem(tr("A2"), TELEMETRY_VARIO_SOURCE_A2);
}
void TelemetryPanel::populateVoltsSource()
{
AutoComboBox * cb = ui->frskyVoltCB;
cb->setField(model->frsky.voltsSource, this);
cb->addItem(tr("A1"), TELEMETRY_VOLTS_SOURCE_A1);
cb->addItem(tr("A2"), TELEMETRY_VOLTS_SOURCE_A2);
cb->addItem(tr("A3"), TELEMETRY_VOLTS_SOURCE_A3);
cb->addItem(tr("A4"), TELEMETRY_VOLTS_SOURCE_A4);
cb->addItem(tr("FAS"), TELEMETRY_VOLTS_SOURCE_FAS);
cb->addItem(tr("Cells"), TELEMETRY_VOLTS_SOURCE_CELLS);
}
void TelemetryPanel::populateCurrentSource()
{
AutoComboBox * cb = ui->frskyCurrentCB;
cb->setField(model->frsky.currentSource, this);
cb->addItem(tr("---"), TELEMETRY_CURRENT_SOURCE_NONE);
cb->addItem(tr("A1"), TELEMETRY_CURRENT_SOURCE_A1);
cb->addItem(tr("A2"), TELEMETRY_CURRENT_SOURCE_A2);
cb->addItem(tr("A3"), TELEMETRY_CURRENT_SOURCE_A3);
cb->addItem(tr("A4"), TELEMETRY_CURRENT_SOURCE_A4);
cb->addItem(tr("FAS"), TELEMETRY_CURRENT_SOURCE_FAS);
}
void TelemetryPanel::on_telemetryProtocol_currentIndexChanged(int index)
{
if (!lock) {
if (!isLocked()) {
model->telemetryProtocol = index;
emit modified();
}
@ -892,7 +933,7 @@ void TelemetryPanel::onModified()
void TelemetryPanel::on_bladesCount_editingFinished()
{
if (!lock) {
if (!isLocked()) {
model->frsky.blades = ui->bladesCount->value();
emit modified();
}
@ -900,7 +941,7 @@ void TelemetryPanel::on_bladesCount_editingFinished()
void TelemetryPanel::on_frskyProtoCB_currentIndexChanged(int index)
{
if (!lock) {
if (!isLocked()) {
model->frsky.usrProto = index;
for (int i = 0; i < firmware->getCapability(TelemetryCustomScreens); i++)
telemetryCustomScreens[i]->update();
@ -910,31 +951,39 @@ void TelemetryPanel::on_frskyProtoCB_currentIndexChanged(int index)
void TelemetryPanel::on_rssiAlarmWarningSB_editingFinished()
{
if (!isLocked()) {
model->rssiAlarms.warning= ui->rssiAlarmWarningSB->value();
emit modified();
}
}
void TelemetryPanel::on_rssiAlarmCriticalSB_editingFinished()
{
if (!isLocked()) {
model->rssiAlarms.critical = ui->rssiAlarmCriticalSB->value();
emit modified();
}
}
void TelemetryPanel::on_varioLimitMin_DSB_editingFinished()
{
if (!isLocked()) {
model->frsky.varioMin = round(ui->varioLimitMin_DSB->value() + 10);
emit modified();
}
}
void TelemetryPanel::on_varioLimitMax_DSB_editingFinished()
{
if (!isLocked()) {
model->frsky.varioMax = round(ui->varioLimitMax_DSB->value() - 10);
emit modified();
}
}
void TelemetryPanel::on_varioLimitCenterMin_DSB_editingFinished()
{
if (!lock) {
if (!isLocked()) {
if (ui->varioLimitCenterMin_DSB->value() > ui->varioLimitCenterMax_DSB->value()) {
ui->varioLimitCenterMax_DSB->setValue(ui->varioLimitCenterMin_DSB->value());
}
@ -945,7 +994,7 @@ void TelemetryPanel::on_varioLimitCenterMin_DSB_editingFinished()
void TelemetryPanel::on_varioLimitCenterMax_DSB_editingFinished()
{
if (!lock) {
if (!isLocked()) {
if (ui->varioLimitCenterMin_DSB->value() > ui->varioLimitCenterMax_DSB->value()) {
ui->varioLimitCenterMax_DSB->setValue(ui->varioLimitCenterMin_DSB->value());
}
@ -956,21 +1005,27 @@ void TelemetryPanel::on_varioLimitCenterMax_DSB_editingFinished()
void TelemetryPanel::on_fasOffset_DSB_editingFinished()
{
if (!isLocked()) {
model->frsky.fasOffset = ui->fasOffset_DSB->value() * 10;
emit modified();
}
}
void TelemetryPanel::on_mahCount_SB_editingFinished()
{
if (!isLocked()) {
model->frsky.storedMah = ui->mahCount_SB->value();
emit modified();
}
}
void TelemetryPanel::on_mahCount_ChkB_toggled(bool checked)
{
if (!isLocked()) {
model->frsky.mAhPersistent = checked;
ui->mahCount_SB->setDisabled(!checked);
emit modified();
}
}
void TelemetryPanel::on_clearAllSensors()
@ -980,9 +1035,7 @@ void TelemetryPanel::on_clearAllSensors()
model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_CLEAR, i);
}
updateItemModels();
update();
emit modified();
on_dataModifiedSensor();
}
void TelemetryPanel::on_insertSensor(int selectedIndex)
@ -990,10 +1043,7 @@ void TelemetryPanel::on_insertSensor(int selectedIndex)
memmove(&model->sensorData[selectedIndex + 1], &model->sensorData[selectedIndex], (CPN_MAX_SENSORS - (selectedIndex + 1)) * sizeof(SensorData));
model->sensorData[selectedIndex].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, 1);
updateItemModels();
update();
emit modified();
on_dataModifiedSensor();
}
void TelemetryPanel::on_deleteSensor(int selectedIndex)
@ -1004,10 +1054,7 @@ void TelemetryPanel::on_deleteSensor(int selectedIndex)
memmove(&model->sensorData[selectedIndex], &model->sensorData[selectedIndex + 1], (CPN_MAX_SENSORS - (selectedIndex + 1)) * sizeof(SensorData));
model->sensorData[CPN_MAX_SENSORS - 1].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, -1);
updateItemModels();
update();
emit modified();
on_dataModifiedSensor();
}
void TelemetryPanel::on_moveUpSensor(int selectedIndex)
@ -1029,20 +1076,34 @@ void TelemetryPanel::swapData(int idx1, int idx2)
memcpy(sd2, sd1, sizeof(SensorData));
memcpy(sd1, &sdtmp, sizeof(SensorData));
model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_SWAP, idx1, idx2);
updateItemModels();
update();
emit modified();
on_dataModifiedSensor();
}
}
void TelemetryPanel::on_dataModifiedSensor()
{
updateItemModels();
update();
sharedItemModels->update(AbstractItemModel::IMUE_TeleSensors);
emit modified();
}
void TelemetryPanel::updateItemModels()
void TelemetryPanel::connectItemModelEvents(const int id)
{
commonItemModels->update(CommonItemModels::RMO_TELEMETRY_SENSORS);
FilteredItemModel * itemModel = panelFilteredItemModels->getItemModel(id);
connect(itemModel, &FilteredItemModel::aboutToBeUpdated, this, &TelemetryPanel::onItemModelAboutToBeUpdated);
connect(itemModel, &FilteredItemModel::updateComplete, this, &TelemetryPanel::onItemModelUpdateComplete);
}
void TelemetryPanel::onItemModelAboutToBeUpdated()
{
lock = true;
modelsUpdateCnt++;
}
void TelemetryPanel::onItemModelUpdateComplete()
{
modelsUpdateCnt--;
if (modelsUpdateCnt < 1) {
update();
lock = false;
}
}

View file

@ -23,12 +23,11 @@
#include "modeledit.h"
#include "eeprominterface.h"
#include "filtereditemmodels.h"
constexpr char MIMETYPE_TELE_SENSOR[] = "application/x-companion-tele-sensor";
constexpr char MIMETYPE_TELE_SENSOR[] {"application/x-companion-tele-sensor"};
class AutoComboBox;
class CommonItemModels;
class RawItemFilteredModel;
class TimerEdit;
namespace Ui {
@ -42,7 +41,8 @@ class TelemetryCustomScreen: public ModelPanel
Q_OBJECT
public:
TelemetryCustomScreen(QWidget *parent, ModelData & model, FrSkyScreenData & screen, GeneralSettings & generalSettings, Firmware * firmware, RawItemFilteredModel * rawSourceModel);
TelemetryCustomScreen(QWidget *parent, ModelData & model, FrSkyScreenData & screen, GeneralSettings & generalSettings, Firmware * firmware,
const bool & parentLock, FilteredItemModelFactory * panelFilteredItemModels);
~TelemetryCustomScreen();
void update();
@ -54,8 +54,8 @@ class TelemetryCustomScreen: public ModelPanel
void barMinChanged(double value);
void barMaxChanged(double value);
void barTimeChanged();
void onModelDataAboutToBeUpdated();
void onModelDataUpdateComplete();
void onItemModelAboutToBeUpdated();
void onItemModelUpdateComplete();
private:
void updateBar(int line);
@ -67,6 +67,11 @@ class TelemetryCustomScreen: public ModelPanel
QDoubleSpinBox * maxSB[4];
TimerEdit * minTime[4];
TimerEdit * maxTime[4];
int modelsUpdateCnt;
const bool &parentLock;
inline bool isLocked() { return lock | parentLock; }
void connectItemModelEvents(const FilteredItemModel * itemModel);
};
class TelemetrySensorPanel: public ModelPanel
@ -74,7 +79,9 @@ class TelemetrySensorPanel: public ModelPanel
Q_OBJECT
public:
TelemetrySensorPanel(QWidget *parent, SensorData & sensor, int sensorIndex, int sensorCapability, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware);
TelemetrySensorPanel(QWidget *parent, SensorData & sensor, int sensorIndex, int sensorCapability, ModelData & model,
GeneralSettings & generalSettings, Firmware * firmware, const bool & parentLock,
FilteredItemModelFactory * panelFilteredItemModels);
~TelemetrySensorPanel();
void update();
@ -86,7 +93,6 @@ class TelemetrySensorPanel: public ModelPanel
void moveUpSensor(int index);
void moveDownSensor(int index);
protected slots:
void on_name_editingFinished();
void on_type_currentIndexChanged(int index);
@ -104,20 +110,23 @@ class TelemetrySensorPanel: public ModelPanel
void cmDelete();
void cmMoveUp();
void cmMoveDown();
protected:
void updateSourcesComboBox(AutoComboBox * cb, bool negative);
void onItemModelAboutToBeUpdated();
void onItemModelUpdateComplete();
private:
Ui::TelemetrySensor * ui;
SensorData & sensor;
bool lock = false;
int sensorIndex = 0;
int selectedIndex = 0;
int sensorCapability;
bool insertAllowed() const;
bool moveDownAllowed() const;
bool moveUpAllowed() const;
int modelsUpdateCnt;
const bool &parentLock;
inline bool isLocked() { return lock | parentLock; }
void connectItemModelEvents(const FilteredItemModel * itemModel);
};
class TelemetryPanel : public ModelPanel
@ -125,7 +134,8 @@ class TelemetryPanel : public ModelPanel
Q_OBJECT
public:
TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels);
TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware,
CompoundItemModelFactory * sharedItemModels);
virtual ~TelemetryPanel();
virtual void update();
@ -152,22 +162,24 @@ class TelemetryPanel : public ModelPanel
void on_moveUpSensor(int index);
void on_moveDownSensor(int index);
void on_dataModifiedSensor();
void onItemModelAboutToBeUpdated();
void onItemModelUpdateComplete();
private:
Ui::Telemetry *ui;
TelemetryCustomScreen * telemetryCustomScreens[4];
TelemetrySensorPanel * sensorPanels[CPN_MAX_SENSORS];
TelemetryCustomScreen *telemetryCustomScreens[4];
TelemetrySensorPanel *sensorPanels[CPN_MAX_SENSORS];
int sensorCapability;
CommonItemModels * commonItemModels;
RawItemFilteredModel * rawSourceFilteredModel;
CompoundItemModelFactory *sharedItemModels;
CompoundItemModelFactory *panelItemModels;
FilteredItemModelFactory *panelFilteredItemModels;
int modelsUpdateCnt;
void setup();
void telBarUpdate();
void populateVoltsSource();
void populateCurrentSource();
void populateVarioSource();
void swapData(int idx1, int idx2);
void updateItemModels();
void connectItemModelEvents(const int id);
inline bool isLocked() { return lock; }
};
#endif // _TELEMETRY_H_

View file

@ -37,31 +37,38 @@ class AutoComboBox: public QComboBox
void clear()
{
if (!hasModel) {
lock = true;
QComboBox::clear();
next = 0;
lock = false;
}
}
virtual void insertItems(int index, const QStringList & items)
{
if (!hasModel) {
foreach(QString item, items) {
addItem(item);
}
}
}
virtual void addItem(const QString & item)
{
if (!hasModel)
addItem(item, next++);
}
virtual void addItem(const QString & item, int value)
{
if (!hasModel) {
lock = true;
QComboBox::addItem(item, value);
lock = false;
updateValue();
}
}
void setField(unsigned int & field, GenericPanel * panel=nullptr)
{
@ -77,12 +84,23 @@ class AutoComboBox: public QComboBox
updateValue();
}
void setModel(QAbstractItemModel * model)
{
lock = true;
QComboBox::setModel(model);
lock = false;
hasModel = true;
updateValue();
}
void setAutoIndexes()
{
for (int i=0; i<count(); ++i)
if (!hasModel) {
for (int i = 0; i < count(); ++i)
setItemData(i, i);
updateValue();
}
}
void updateValue()
{
@ -99,6 +117,9 @@ class AutoComboBox: public QComboBox
protected slots:
void onCurrentIndexChanged(int index)
{
if (panel && panel->lock)
return;
if (index > -1) {
const int val = itemData(index).toInt();
if (field && !lock) {
*field = val;
@ -107,12 +128,14 @@ class AutoComboBox: public QComboBox
}
emit currentDataChanged(val);
}
}
protected:
int * field = nullptr;
GenericPanel * panel = nullptr;
int next = 0;
bool lock = false;
bool hasModel = false;
};
#endif // _AUTOCOMBOBOX_H_

View file

@ -17,6 +17,7 @@ set(simulation_SRCS
simulateduiwidgetJumperT16.cpp
simulateduiwidgetJumperT18.cpp
simulateduiwidgetTX12.cpp
simulateduiwidgetT8.cpp
simulateduiwidgetTX16S.cpp
simulatorinterface.cpp
simulatormainwindow.cpp
@ -45,6 +46,7 @@ set(simulation_UIS
simulateduiwidgetJumperT16.ui
simulateduiwidgetJumperT18.ui
simulateduiwidgetTX12.ui
simulateduiwidgetT8.ui
simulateduiwidgetTX16S.ui
simulatormainwindow.ui
simulatorstartupdialog.ui

View file

@ -117,6 +117,7 @@ namespace Ui {
class SimulatedUIWidgetJumperT18;
class SimulatedUIWidgetTX16S;
class SimulatedUIWidgetTX12;
class SimulatedUIWidgetT8;
}
class SimulatedUIWidget9X: public SimulatedUIWidget
@ -291,6 +292,17 @@ class SimulatedUIWidgetTX12: public SimulatedUIWidget
Ui::SimulatedUIWidgetTX12 * ui;
};
class SimulatedUIWidgetT8: public SimulatedUIWidget
{
Q_OBJECT
public:
explicit SimulatedUIWidgetT8(SimulatorInterface * simulator, QWidget * parent = nullptr);
virtual ~SimulatedUIWidgetT8();
private:
Ui::SimulatedUIWidgetT8 * ui;
};
class SimulatedUIWidgetTX16S: public SimulatedUIWidget
{

View file

@ -0,0 +1,67 @@
#include "simulateduiwidget.h"
#include "ui_simulateduiwidgetT8.h"
// NOTE: RadioUiAction(NUMBER,...): NUMBER relates to enum EnumKeys in the specific board.h
SimulatedUIWidgetT8::SimulatedUIWidgetT8(SimulatorInterface *simulator, QWidget * parent):
SimulatedUIWidget(simulator, parent),
ui(new Ui::SimulatedUIWidgetT8)
{
RadioUiAction * act;
ui->setupUi(this);
// add actions in order of appearance on the help menu
act = new RadioUiAction(5, QList<int>() << Qt::Key_Up, SIMU_STR_HLP_KEY_UP, SIMU_STR_HLP_ACT_MDL);
addRadioWidget(ui->rightbuttons->addArea(QRect(25, 40, 35, 20), "T8/right-mdl.png", act));
act = new RadioUiAction(6, QList<int>() << Qt::Key_Enter << Qt::Key_Return, SIMU_STR_HLP_KEYS_GO_UP, SIMU_STR_HLP_ACT_UP);
addRadioWidget(ui->rightbuttons->addArea(QRect(25, 90, 35, 20), "T8/right-up.png", act));
act = new RadioUiAction(7, QList<int>() << Qt::Key_Enter << Qt::Key_Return, SIMU_STR_HLP_KEYS_GO_DN, SIMU_STR_HLP_ACT_DN);
addRadioWidget(ui->rightbuttons->addArea(QRect(25, 135, 35, 20), "T8/right-dn.png", act));
act = new RadioUiAction(1, QList<int>() << Qt::Key_Enter << Qt::Key_Return, SIMU_STR_HLP_KEYS_ACTIVATE, SIMU_STR_HLP_ACT_ENT);
addRadioWidget(ui->rightbuttons->addArea(QRect(25, 180, 35, 20), "T8/right-ent.png", act));
act = new RadioUiAction(4, QList<int>() << Qt::Key_Left, SIMU_STR_HLP_KEY_LFT, SIMU_STR_HLP_ACT_SYS);
addRadioWidget(ui->leftbuttons->addArea(QRect(60, 45, 35, 20), "T8/left-sys.png", act));
act = new RadioUiAction(0, QList<int>() << Qt::Key_Down << Qt::Key_Delete << Qt::Key_Escape << Qt::Key_Backspace, SIMU_STR_HLP_KEYS_EXIT, SIMU_STR_HLP_ACT_EXIT);
addRadioWidget(ui->leftbuttons->addArea(QRect(60, 85, 35, 20), "T8/left-rtn.png", act));
act = new RadioUiAction(3, QList<int>() << Qt::Key_PageDown, SIMU_STR_HLP_KEY_PGDN, SIMU_STR_HLP_ACT_PGDN);
addRadioWidget(ui->leftbuttons->addArea(QRect(60, 135, 35, 20), "T8/left-pagedn.png", act));
act = new RadioUiAction(2, QList<int>() << Qt::Key_PageUp, SIMU_STR_HLP_KEY_PGUP, SIMU_STR_HLP_ACT_PGUP);
addRadioWidget(ui->leftbuttons->addArea(QRect(60, 180, 35, 20), "T8/left-pageup.png", act));
m_backlightColors << QColor(215, 243, 255); // X7 Blue
m_backlightColors << QColor(166,247,159);
m_backlightColors << QColor(247,159,166);
m_backlightColors << QColor(255,195,151);
m_backlightColors << QColor(247,242,159);
setLcd(ui->lcd);
QString css = "#radioUiWidget {"
"background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:1,"
"stop:0 rgba(255, 255, 255, 255),"
"stop:0.757062 rgba(241, 238, 238, 255),"
"stop:1 rgba(247, 245, 245, 255));"
"}";
QTimer * tim = new QTimer(this);
tim->setSingleShot(true);
connect(tim, &QTimer::timeout, [this, css]() {
emit customStyleRequest(css);
});
tim->start(100);
}
SimulatedUIWidgetT8::~SimulatedUIWidgetT8()
{
delete ui;
}

View file

@ -0,0 +1,258 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SimulatedUIWidgetT8</class>
<widget class="QWidget" name="SimulatedUIWidgetT8">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>480</width>
<height>300</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>480</width>
<height>300</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>480</width>
<height>300</height>
</size>
</property>
<property name="windowTitle">
<string notr="true">Radiomaster T8 Simulator</string>
</property>
<property name="styleSheet">
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(255, 255, 255, 255), stop:0.757062 rgba(241, 238, 238, 255), stop:1 rgba(247, 245, 245, 255));</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>0</number>
</property>
<item row="1" column="0" rowspan="3">
<widget class="ButtonsWidget" name="leftbuttons" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>113</width>
<height>280</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>113</width>
<height>280</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">background:url(:/images/simulator/T8/left.png);</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="LcdWidget" name="lcd" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>254</width>
<height>158</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>254</width>
<height>158</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(215, 243, 255);</string>
</property>
</widget>
</item>
<item row="1" column="2" rowspan="3">
<widget class="ButtonsWidget" name="rightbuttons" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>113</width>
<height>280</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>113</width>
<height>280</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">background:url(:/images/simulator/T8/right.png)</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QWidget" name="top" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>254</width>
<height>35</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>254</width>
<height>35</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">background:url(:/images/simulator/T8/top.png)</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QWidget" name="bottom" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>254</width>
<height>113</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>254</width>
<height>113</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">background:url(:/images/simulator/T8/bottom.png)</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="3">
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>10</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>12</height>
</size>
</property>
<property name="baseSize">
<size>
<width>0</width>
<height>12</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(255, 255, 255);</string>
</property>
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
<item row="4" column="0" colspan="3">
<widget class="QLabel" name="label_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>10</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>10</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(247, 245, 245);</string>
</property>
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>LcdWidget</class>
<extends>QWidget</extends>
<header>lcdwidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>ButtonsWidget</class>
<extends>QWidget</extends>
<header>buttonswidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View file

@ -103,6 +103,9 @@ SimulatorWidget::SimulatorWidget(QWidget * parent, SimulatorInterface * simulato
case Board::BOARD_RADIOMASTER_TX12:
radioUiWidget = new SimulatedUIWidgetTX12(simulator, this);
break;
case Board::BOARD_RADIOMASTER_T8:
radioUiWidget = new SimulatedUIWidgetT8(simulator, this);
break;
case Board::BOARD_RADIOMASTER_TX16S:
radioUiWidget = new SimulatedUIWidgetTX16S(simulator, this);
break;

View file

@ -30,6 +30,11 @@ local function run(event)
return 2
end
if crossfireTelemetryPush() == nil then
error("Crossfire not available!")
return 2
end
chdir("/SCRIPTS/TOOLS/CROSSFIRE")
return "crossfire.lua"
end

View file

@ -30,6 +30,11 @@ local function run(event)
return 2
end
if crossfireTelemetryPush() == nil then
error("Crossfire not available!")
return 2
end
chdir("/SCRIPTS/TOOLS/CROSSFIRE")
return "crossfire.lua"
end

View file

@ -30,6 +30,11 @@ local function run(event)
return 2
end
if crossfireTelemetryPush() == nil then
error("Crossfire not available!")
return 2
end
chdir("/SCRIPTS/TOOLS/CROSSFIRE")
return "crossfire.lua"
end

View file

@ -345,6 +345,10 @@ if(RADIOMASTER_RELEASE)
add_definitions(-DRADIOMASTER_RELEASE)
endif()
if(RADIOMASTER_RTF_RELEASE)
add_definitions(-DRADIOMASTER_RTF_RELEASE)
endif()
if(TBS_RELEASE)
add_definitions(-DTBS_RELEASE)
endif()

View file

@ -208,7 +208,11 @@ enum TrainerMode {
};
#endif
#if defined(RADIO_T16) && !defined(INTERNAL_MODULE_MULTI)
#define TRAINER_MODE_MIN() TRAINER_MODE_MASTER_TRAINER_JACK
#if !defined(HARDWARE_EXTERNAL_MODULE)
#define TRAINER_MODE_MAX() TRAINER_MODE_SLAVE
#elif defined(RADIO_T16) && !defined(INTERNAL_MODULE_MULTI)
#if defined(BLUETOOTH)
#define TRAINER_MODE_MAX() TRAINER_MODE_SLAVE_BLUETOOTH
#else

View file

@ -181,8 +181,9 @@ uint8_t * lcdLoadBitmap(uint8_t * dest, const char * filename, uint8_t width, ui
#if defined(BOOT)
#define BLINK_ON_PHASE (0)
#else
#define BLINK_ON_PHASE (g_blinkTmr10ms & (1<<6))
#define SLOW_BLINK_ON_PHASE (g_blinkTmr10ms & (1<<7))
#define BLINK_ON_PHASE (g_blinkTmr10ms & (1<<6))
#define FAST_BLINK_ON_PHASE (g_blinkTmr10ms & (1<<4))
#endif
inline display_t getPixel(uint8_t x, uint8_t y)

View file

@ -165,7 +165,7 @@ void menuModelCurveOne(event_t event)
}
break;
#if defined(NAVIGATION_X7_TX12)
#if defined(KEYS_GPIO_REG_MDL)
case EVT_KEY_FIRST(KEY_MODEL):
pushMenu(menuChannelsView);
killEvents(event);

View file

@ -49,7 +49,7 @@ enum ExposFields {
void menuModelExpoOne(event_t event)
{
#if defined(NAVIGATION_X7_TX12)
#if defined(KEYS_GPIO_REG_MDL)
if (event == EVT_KEY_FIRST(KEY_MODEL)) {
pushMenu(menuChannelsView);
killEvents(event);

View file

@ -85,7 +85,7 @@ void drawOffsetBar(uint8_t x, uint8_t y, MixData * md)
void menuModelMixOne(event_t event)
{
#if defined(NAVIGATION_X7_TX12)
#if defined(KEYS_GPIO_REG_MDL)
if (event == EVT_KEY_FIRST(KEY_MODEL)) {
pushMenu(menuChannelsView);
killEvents(event);

View file

@ -203,7 +203,7 @@ void menuModelSelect(event_t event)
}
break;
#if defined(NAVIGATION_X7_TX12)
#if defined(KEYS_GPIO_REG_PAGEDN)
case EVT_KEY_FIRST(KEY_PAGEUP):
chainMenu(menuTabModel[DIM(menuTabModel)-1]);
killEvents(event);
@ -212,7 +212,7 @@ void menuModelSelect(event_t event)
case EVT_KEY_FIRST(KEY_PAGEDN):
chainMenu(menuModelSetup);
break;
#elif defined(NAVIGATION_X7)
#elif defined(KEYS_GPIO_REG_PAGE)
case EVT_KEY_LONG(KEY_PAGE):
chainMenu(menuTabModel[DIM(menuTabModel)-1]);
killEvents(event);
@ -244,7 +244,7 @@ void menuModelSelect(event_t event)
#endif
#endif
#if defined(NAVIGATION_X7)
#if defined(ROTARY_ENCODER) && defined(NAVIGATION_X7)
case EVT_ROTARY_LEFT:
case EVT_ROTARY_RIGHT:
#endif

View file

@ -111,7 +111,7 @@ enum MenuModelSetupItems {
ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_RECEIVER_2,
ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_RECEIVER_3,
#endif
#if defined(HARDWARE_EXTERNAL_MODULE)
ITEM_MODEL_SETUP_EXTERNAL_MODULE_LABEL,
ITEM_MODEL_SETUP_EXTERNAL_MODULE_TYPE,
#if defined(MULTIMODULE)
@ -156,6 +156,7 @@ enum MenuModelSetupItems {
ITEM_MODEL_SETUP_EXTRA_MODULE_CHANNELS,
ITEM_MODEL_SETUP_EXTRA_MODULE_BIND,
#endif
#endif
#if defined(PCBTARANIS)
ITEM_MODEL_SETUP_TRAINER_LABEL,
@ -183,11 +184,14 @@ enum MenuModelSetupItems {
#define REGISTRATION_ID_ROWS
#endif
#if defined(HARDWARE_INTERNAL_MODULE)
#if defined(HARDWARE_INTERNAL_MODULE) && defined(HARDWARE_EXTERNAL_MODULE)
#define CURRENT_MODULE_EDITED(k) (k >= ITEM_MODEL_SETUP_EXTERNAL_MODULE_LABEL ? EXTERNAL_MODULE : INTERNAL_MODULE)
#define CURRENT_RECEIVER_EDITED(k) (k - (k >= ITEM_MODEL_SETUP_EXTERNAL_MODULE_LABEL ? ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_RECEIVER_1 : ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_RECEIVER_1))
#elif defined(PCBSKY9X)
#define CURRENT_MODULE_EDITED(k) (k >= ITEM_MODEL_SETUP_EXTRA_MODULE_LABEL ? EXTRA_MODULE : EXTERNAL_MODULE)
#elif defined(HARDWARE_INTERNAL_MODULE)
#define CURRENT_MODULE_EDITED(k) (INTERNAL_MODULE)
#define CURRENT_RECEIVER_EDITED(k) (k - ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_RECEIVER_1)
#else
#define CURRENT_MODULE_EDITED(k) (EXTERNAL_MODULE)
#define CURRENT_RECEIVER_EDITED(k) (k - ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_RECEIVER_1)
@ -335,6 +339,32 @@ void onBluetoothConnectMenu(const char * result)
#define INTERNAL_MODULE_ROWS
#endif
#if defined(HARDWARE_EXTERNAL_MODULE)
#define EXTERNAL_MODULE_ROWS \
LABEL(ExternalModule), \
MODULE_TYPE_ROWS(EXTERNAL_MODULE), \
MULTIMODULE_TYPE_ROWS(EXTERNAL_MODULE) /* PROTOCOL */ \
MULTIMODULE_SUBTYPE_ROWS(EXTERNAL_MODULE) /* SUBTYPE */ \
MULTIMODULE_STATUS_ROWS(EXTERNAL_MODULE) \
AFHDS3_PROTOCOL_ROW(EXTERNAL_MODULE) \
AFHDS3_MODE_ROWS(EXTERNAL_MODULE) \
MODULE_CHANNELS_ROWS(EXTERNAL_MODULE), \
IF_NOT_ACCESS_MODULE_RF(EXTERNAL_MODULE, MODULE_BIND_ROWS(EXTERNAL_MODULE)), /* line reused for PPM: PPM settings */ \
IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), /* RxNum */ \
AFHDS3_MODULE_ROWS(EXTERNAL_MODULE) \
MODULE_POWER_ROW(EXTERNAL_MODULE), \
IF_NOT_PXX2_MODULE(EXTERNAL_MODULE, MODULE_OPTION_ROW(EXTERNAL_MODULE)), \
MULTIMODULE_MODULE_ROWS(EXTERNAL_MODULE) \
FAILSAFE_ROWS(EXTERNAL_MODULE), /* ITEM_MODEL_SETUP_EXTERNAL_MODULE_FAILSAFE */ \
IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 1), /* Range check and Register buttons */ \
IF_PXX2_MODULE(EXTERNAL_MODULE, 0), /* Module options */ \
IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), /* Receiver 1 */ \
IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), /* Receiver 2 */ \
IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), /* Receiver 3 */
#else
#define EXTERNAL_MODULE_ROWS
#endif
void menuModelSetup(event_t event)
{
int8_t old_editMode = s_editMode;
@ -370,26 +400,7 @@ void menuModelSetup(event_t event)
INTERNAL_MODULE_ROWS
LABEL(ExternalModule),
MODULE_TYPE_ROWS(EXTERNAL_MODULE),
MULTIMODULE_TYPE_ROWS(EXTERNAL_MODULE) // PROTOCOL
MULTIMODULE_SUBTYPE_ROWS(EXTERNAL_MODULE) // SUBTYPE
MULTIMODULE_STATUS_ROWS(EXTERNAL_MODULE)
AFHDS3_PROTOCOL_ROW(EXTERNAL_MODULE)
AFHDS3_MODE_ROWS(EXTERNAL_MODULE)
MODULE_CHANNELS_ROWS(EXTERNAL_MODULE),
IF_NOT_ACCESS_MODULE_RF(EXTERNAL_MODULE, MODULE_BIND_ROWS(EXTERNAL_MODULE)), // line reused for PPM: PPM settings
IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // RxNum
AFHDS3_MODULE_ROWS(EXTERNAL_MODULE)
MODULE_POWER_ROW(EXTERNAL_MODULE),
IF_NOT_PXX2_MODULE(EXTERNAL_MODULE, MODULE_OPTION_ROW(EXTERNAL_MODULE)),
MULTIMODULE_MODULE_ROWS(EXTERNAL_MODULE)
FAILSAFE_ROWS(EXTERNAL_MODULE), //ITEM_MODEL_SETUP_EXTERNAL_MODULE_FAILSAFE
IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 1), // Range check and Register buttons
IF_PXX2_MODULE(EXTERNAL_MODULE, 0), // Module options
IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // Receiver 1
IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // Receiver 2
IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // Receiver 3
EXTERNAL_MODULE_ROWS
TRAINER_ROWS
});
@ -857,7 +868,7 @@ void menuModelSetup(event_t event)
#if !defined(INTERNAL_MODULE_MULTI)
case ITEM_MODEL_SETUP_INTERNAL_MODULE_TYPE:
{
lcdDrawTextAlignedLeft(y, INDENT TR_MODE);
lcdDrawText(INDENT_WIDTH, y, STR_MODE);
#if defined(INTERNAL_MODULE_PXX1)
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_INTERNAL_MODULE_PROTOCOLS, g_model.moduleData[INTERNAL_MODULE].type, menuHorizontalPosition==0 ? attr : 0);
if (isModuleXJT(INTERNAL_MODULE))
@ -912,14 +923,18 @@ void menuModelSetup(event_t event)
break;
#endif
#if defined(HARDWARE_EXTERNAL_MODULE)
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_LABEL:
lcdDrawTextAlignedLeft(y, STR_EXTERNALRF);
break;
#endif
#if defined(INTERNAL_MODULE_MULTI)
case ITEM_MODEL_SETUP_INTERNAL_MODULE_TYPE:
#endif
#if defined(HARDWARE_EXTERNAL_MODULE)
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_TYPE:
#endif
lcdDrawTextAlignedLeft(y, INDENT TR_MODE);
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_EXTERNAL_MODULE_PROTOCOLS, moduleIdx == EXTERNAL_MODULE ? reusableBuffer.moduleSetup.newType : g_model.moduleData[moduleIdx].type, menuHorizontalPosition==0 ? attr : 0);
if (isModuleXJT(moduleIdx))
@ -1013,7 +1028,9 @@ void menuModelSetup(event_t event)
#if defined(HARDWARE_INTERNAL_MODULE)
case ITEM_MODEL_SETUP_INTERNAL_MODULE_PROTOCOL:
#endif
#if defined(HARDWARE_EXTERNAL_MODULE)
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_PROTOCOL:
#endif
{
lcdDrawTextAlignedLeft(y, TR_TYPE);
int multi_rfProto = g_model.moduleData[moduleIdx].getMultiProtocol();
@ -1052,7 +1069,9 @@ void menuModelSetup(event_t event)
#if defined(HARDWARE_INTERNAL_MODULE)
case ITEM_MODEL_SETUP_INTERNAL_MODULE_SUBTYPE:
#endif
#if defined(HARDWARE_EXTERNAL_MODULE)
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_SUBTYPE:
#endif
{
lcdDrawTextAlignedLeft(y, STR_SUBTYPE);
lcdDrawMultiSubProtocolString(MODEL_SETUP_2ND_COLUMN, y, moduleIdx, g_model.moduleData[moduleIdx].subType, attr);
@ -1073,7 +1092,7 @@ void menuModelSetup(event_t event)
#if defined(AFHDS3)
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_AFHDS_PROTOCOL:
lcdDrawTextAlignedLeft(y, TR_PROTO);
lcdDrawText(INDENT_WIDTH, y, STR_PROTOCOL);
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_AFHDS3_PROTOCOLS, g_model.moduleData[EXTERNAL_MODULE].subType, attr);
if (attr && s_editMode > 0 && menuHorizontalPosition == 0) {
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].subType, AFHDS_SUBTYPE_FIRST, AFHDS_SUBTYPE_LAST);
@ -1095,7 +1114,7 @@ void menuModelSetup(event_t event)
lcdDrawTextAlignedLeft(y, INDENT TR_MODE);
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_VTRAINERMODES, g_model.trainerData.mode, attr);
if (attr) {
g_model.trainerData.mode = checkIncDec(event, g_model.trainerData.mode, 0, TRAINER_MODE_MAX(), EE_MODEL, isTrainerModeAvailable);
g_model.trainerData.mode = checkIncDec(event, g_model.trainerData.mode, TRAINER_MODE_MIN(), TRAINER_MODE_MAX(), EE_MODEL, isTrainerModeAvailable);
#if defined(BLUETOOTH)
if (checkIncDec_Ret) {
bluetooth.state = BLUETOOTH_STATE_OFF;
@ -1182,7 +1201,9 @@ void menuModelSetup(event_t event)
#if defined(PCBSKY9X)
case ITEM_MODEL_SETUP_EXTRA_MODULE_CHANNELS:
#endif
#if defined(HARDWARE_EXTERNAL_MODULE)
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_CHANNELS:
#endif
{
ModuleData & moduleData = g_model.moduleData[moduleIdx];
lcdDrawTextAlignedLeft(y, STR_CHANNELRANGE);
@ -1308,7 +1329,9 @@ void menuModelSetup(event_t event)
#if defined(HARDWARE_INTERNAL_MODULE)
case ITEM_MODEL_SETUP_INTERNAL_MODULE_NOT_ACCESS_RXNUM_BIND_RANGE:
#endif
#if defined(HARDWARE_EXTERNAL_MODULE)
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_NOT_ACCESS_RXNUM_BIND_RANGE:
#endif
{
ModuleData & moduleData = g_model.moduleData[moduleIdx];
if (isModulePPM(moduleIdx)) {
@ -1462,7 +1485,9 @@ void menuModelSetup(event_t event)
#if defined(HARDWARE_INTERNAL_MODULE)
case ITEM_MODEL_SETUP_INTERNAL_MODULE_FAILSAFE:
#endif
#if defined(HARDWARE_EXTERNAL_MODULE)
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_FAILSAFE:
#endif
{
ModuleData &moduleData = g_model.moduleData[moduleIdx];
lcdDrawTextAlignedLeft(y, STR_FAILSAFE);
@ -1523,7 +1548,9 @@ void menuModelSetup(event_t event)
#if defined(HARDWARE_INTERNAL_MODULE)
case ITEM_MODEL_SETUP_INTERNAL_MODULE_OPTIONS:
#endif
#if defined(HARDWARE_EXTERNAL_MODULE)
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_OPTIONS:
#endif
{
#if defined(MULTIMODULE)
if (MULTIMODULE_PROTOCOL_KNOWN(moduleIdx)) {
@ -1602,7 +1629,9 @@ void menuModelSetup(event_t event)
#if defined(INTERNAL_MODULE_MULTI)
case ITEM_MODEL_SETUP_INTERNAL_MODULE_POWER:
#endif
#if defined(HARDWARE_EXTERNAL_MODULE)
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_POWER:
#endif
{
auto & module = g_model.moduleData[moduleIdx];
// Lite FCC / Lite FLEX / Lite Pro Flex
@ -1687,7 +1716,9 @@ void menuModelSetup(event_t event)
#if defined(HARDWARE_INTERNAL_MODULE)
case ITEM_MODEL_SETUP_INTERNAL_MODULE_AUTOBIND:
#endif
#if defined(HARDWARE_EXTERNAL_MODULE)
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_AUTOBIND:
#endif
if (g_model.moduleData[moduleIdx].getMultiProtocol() == MODULE_SUBTYPE_MULTI_DSM2) {
int8_t value = (g_model.moduleData[moduleIdx].multi.optionValue & 0x02) >> 1;
lcdDrawText(INDENT_WIDTH, y, STR_MULTI_SERVOFREQ);
@ -1708,13 +1739,17 @@ void menuModelSetup(event_t event)
#if defined(HARDWARE_INTERNAL_MODULE)
case ITEM_MODEL_SETUP_INTERNAL_MODULE_DISABLE_TELEM:
#endif
#if defined(HARDWARE_EXTERNAL_MODULE)
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_DISABLE_TELEM:
#endif
g_model.moduleData[moduleIdx].multi.disableTelemetry = editCheckBox(g_model.moduleData[moduleIdx].multi.disableTelemetry, MODEL_SETUP_2ND_COLUMN, y, INDENT TR_DISABLE_TELEM, attr, event);
break;
#if defined(HARDWARE_INTERNAL_MODULE)
case ITEM_MODEL_SETUP_INTERNAL_MODULE_DISABLE_MAPPING:
#endif
#if defined(HARDWARE_EXTERNAL_MODULE)
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_DISABLE_MAPPING:
#endif
g_model.moduleData[moduleIdx].multi.disableMapping = editCheckBox(g_model.moduleData[moduleIdx].multi.disableMapping, MODEL_SETUP_2ND_COLUMN, y, INDENT TR_DISABLE_CH_MAP, attr, event);
break;
#endif
@ -1739,7 +1774,10 @@ void menuModelSetup(event_t event)
#if defined(HARDWARE_INTERNAL_MODULE)
case ITEM_MODEL_SETUP_INTERNAL_MODULE_STATUS:
#endif
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_STATUS: {
#if defined(HARDWARE_EXTERNAL_MODULE)
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_STATUS:
#endif
{
lcdDrawTextAlignedLeft(y, STR_MODULE_STATUS);
char statusText[64];
@ -1750,7 +1788,10 @@ void menuModelSetup(event_t event)
#if defined(HARDWARE_INTERNAL_MODULE)
case ITEM_MODEL_SETUP_INTERNAL_MODULE_SYNCSTATUS:
#endif
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_SYNCSTATUS: {
#if defined(HARDWARE_EXTERNAL_MODULE)
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_SYNCSTATUS:
#endif
{
lcdDrawTextAlignedLeft(y, STR_MODULE_SYNC);
char statusText[64];
getModuleSyncStatusString(moduleIdx, statusText);
@ -1848,11 +1889,13 @@ void menuModelSetup(event_t event)
checkModelIdUnique(g_eeGeneral.currModel, EXTRA_MODULE);
break;
#endif
#if defined(HARDWARE_EXTERNAL_MODULE)
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_NOT_ACCESS_RXNUM_BIND_RANGE:
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_MODEL_NUM:
if (menuHorizontalPosition == 0)
checkModelIdUnique(g_eeGeneral.currModel, EXTERNAL_MODULE);
break;
#endif
}
}
}

View file

@ -49,10 +49,15 @@ void menuRadioDiagKeys(event_t event)
displayKeyState(i&1? 20*FW : 18*FW, y, TRM_BASE+i);
}
if (i <= KEY_MAX) {
y = MENU_HEADER_HEIGHT + 1 + FH*i;
if (i == 7) {
y = MENU_HEADER_HEIGHT + 1 + FH * 6;
lcdDrawTextAtIndex(8, y, STR_VKEYS, i, 0);
displayKeyState(lcdNextPos + 10, y, i);
}
else if (i <= KEY_MAX) {
y = MENU_HEADER_HEIGHT + 1 + FH * i;
lcdDrawTextAtIndex(0, y, STR_VKEYS, i, 0);
displayKeyState(5*FW+2, y, i);
displayKeyState(5 * FW + 2, y, i);
}
#if defined(PCBSKY9X)

View file

@ -79,13 +79,13 @@ enum {
ITEM_RADIO_SETUP_MEMORY_WARNING,
ITEM_RADIO_SETUP_ALARM_WARNING,
ITEM_RADIO_SETUP_RSSI_POWEROFF_ALARM,
ITEM_RADIO_SETUP_BACKLIGHT_LABEL,
ITEM_RADIO_SETUP_BACKLIGHT_MODE,
ITEM_RADIO_SETUP_BACKLIGHT_DELAY,
ITEM_RADIO_SETUP_BRIGHTNESS,
CASE_BACKLIGHT(ITEM_RADIO_SETUP_BACKLIGHT_LABEL)
CASE_BACKLIGHT(ITEM_RADIO_SETUP_BACKLIGHT_MODE)
CASE_BACKLIGHT(ITEM_RADIO_SETUP_BACKLIGHT_DELAY)
CASE_BACKLIGHT(ITEM_RADIO_SETUP_BRIGHTNESS)
CASE_PWM_BACKLIGHT(ITEM_RADIO_SETUP_BACKLIGHT_BRIGHTNESS_OFF)
CASE_PWM_BACKLIGHT(ITEM_RADIO_SETUP_BACKLIGHT_BRIGHTNESS_ON)
ITEM_RADIO_SETUP_FLASH_BEEP,
CASE_BACKLIGHT(ITEM_RADIO_SETUP_FLASH_BEEP)
CASE_SPLASH_PARAM(ITEM_RADIO_SETUP_DISABLE_SPLASH)
CASE_PWR_BUTTON_PRESS(ITEM_RADIO_SETUP_PWR_ON_SPEED)
CASE_PWR_BUTTON_PRESS(ITEM_RADIO_SETUP_PWR_OFF_SPEED)
@ -152,10 +152,14 @@ void menuRadioSetup(event_t event)
CASE_GYRO(0)
CASE_GYRO(0)
0, LABEL(ALARMS), 0, CASE_CAPACITY(0)
0, 0, 0, 0,
LABEL(BACKLIGHT), 0, 0, 0, CASE_PWM_BACKLIGHT(0)
0, 0, 0, 0, /* ITEM_RADIO_SETUP_INACTIVITY_ALARM ITEM_RADIO_SETUP_MEMORY_WARNING ITEM_RADIO_SETUP_ALARM_WARNING ITEM_RADIO_SETUP_RSSI_POWEROFF_ALARM */
CASE_BACKLIGHT(LABEL(BACKLIGHT))
CASE_BACKLIGHT(0)
CASE_BACKLIGHT(0)
CASE_BACKLIGHT(0)
CASE_PWM_BACKLIGHT(0)
0,
CASE_PWM_BACKLIGHT(0)
CASE_BACKLIGHT(0)
CASE_SPLASH_PARAM(0)
CASE_PWR_BUTTON_PRESS(0)
CASE_PWR_BUTTON_PRESS(0)
@ -450,6 +454,7 @@ void menuRadioSetup(event_t event)
if(attr) g_eeGeneral.inactivityTimer = checkIncDec(event, g_eeGeneral.inactivityTimer, 0, 250, EE_GENERAL); //0..250minutes
break;
#if defined(BACKLIGHT_GPIO)
case ITEM_RADIO_SETUP_BACKLIGHT_LABEL:
lcdDrawTextAlignedLeft(y, STR_BACKLIGHT_LABEL);
break;
@ -478,6 +483,7 @@ void menuRadioSetup(event_t event)
g_eeGeneral.backlightBright = 100 - b;
}
break;
#endif
#if defined(PWM_BACKLIGHT)
case ITEM_RADIO_SETUP_BACKLIGHT_BRIGHTNESS_OFF:

View file

@ -42,7 +42,7 @@ enum AboutScreens {
#define ABOUT_X 2
#define ABOUT_INDENT 4
#if defined(NAVIGATION_X7_TX12)
#if defined(KEYS_GPIO_REG_PAGEDN)
#define EVT_KEY_PREVIOUS_VIEW EVT_KEY_BREAK(KEY_PAGEUP)
#define EVT_KEY_NEXT_VIEW EVT_KEY_BREAK(KEY_PAGEDN)
#elif defined(NAVIGATION_X7)

View file

@ -26,7 +26,12 @@ constexpr coord_t CHANNEL_GAUGE_OFFSET = CHANNEL_VALUE_OFFSET;
constexpr coord_t CHANNEL_BAR_WIDTH = 70;
constexpr coord_t CHANNEL_PROPERTIES_OFFSET = CHANNEL_GAUGE_OFFSET + CHANNEL_BAR_WIDTH + 2;
#if defined(NAVIGATION_X7_TX12)
#if defined(RADIO_T8)
#define EVT_KEY_PREVIOUS_VIEW EVT_KEY_BREAK(KEY_PAGEUP)
#define EVT_KEY_NEXT_VIEW EVT_KEY_BREAK(KEY_PAGEDN)
#define EVT_KEY_NEXT_PAGE EVT_KEY_BREAK(KEY_PLUS)
#define EVT_KEY_PREVIOUS_PAGE EVT_KEY_BREAK(KEY_MINUS)
#elif defined(NAVIGATION_X7_TX12)
#define EVT_KEY_PREVIOUS_VIEW EVT_KEY_BREAK(KEY_PAGEUP)
#define EVT_KEY_NEXT_VIEW EVT_KEY_BREAK(KEY_PAGEDN)
#define EVT_KEY_NEXT_PAGE EVT_ROTARY_RIGHT

View file

@ -93,8 +93,9 @@ void doMainScreenGraphics()
if (g_model.throttleReversed && CONVERT_MODE(2) == THR_STICK)
calibStickVert = -calibStickVert;
drawStick(RBOX_CENTERX, calibratedAnalogs[CONVERT_MODE(3)], calibStickVert);
#if defined(HARDWARE_POT1)
drawPotsBars();
#endif
}
void displayTrims(uint8_t phase)
@ -213,7 +214,16 @@ void displayVoltageOrAlarm()
#define displayVoltageOrAlarm() displayBattVoltage()
#endif
#if defined(NAVIGATION_X7_TX12)
#if defined(RADIO_T8)
#define EVT_KEY_CONTEXT_MENU EVT_KEY_LONG(KEY_ENTER)
#define EVT_KEY_PREVIOUS_VIEW EVT_KEY_BREAK(KEY_PAGEUP)
#define EVT_KEY_NEXT_VIEW EVT_KEY_FIRST(KEY_PAGEDN)
#define EVT_KEY_NEXT_PAGE EVT_KEY_FIRST(KEY_PLUS)
#define EVT_KEY_PREVIOUS_PAGE EVT_KEY_FIRST(KEY_MINUS)
#define EVT_KEY_MODEL_MENU EVT_KEY_LONG(KEY_MODEL)
#define EVT_KEY_GENERAL_MENU EVT_KEY_LONG(KEY_SYS)
#define EVT_KEY_TELEMETRY EVT_KEY_LONG(KEY_PAGEUP)
#elif defined(NAVIGATION_X7_TX12)
#define EVT_KEY_CONTEXT_MENU EVT_KEY_LONG(KEY_ENTER)
#define EVT_KEY_PREVIOUS_VIEW EVT_KEY_FIRST(KEY_PAGEUP)
#define EVT_KEY_NEXT_VIEW EVT_KEY_FIRST(KEY_PAGEDN)
@ -410,6 +420,7 @@ void menuMainView(event_t event)
killEvents(event);
break;
case EVT_KEY_FIRST(KEY_EXIT):
#if defined(GVARS)
if (gvarDisplayTimer > 0) {

View file

@ -31,7 +31,7 @@ void menuStatisticsView(event_t event)
switch (event) {
case EVT_KEY_FIRST(KEY_UP):
#if defined(NAVIGATION_X7_TX12)
#if defined(KEYS_GPIO_REG_PAGEDN)
case EVT_KEY_BREAK(KEY_PAGEDN):
#elif defined(NAVIGATION_X7)
case EVT_KEY_BREAK(KEY_PAGE):
@ -41,7 +41,7 @@ void menuStatisticsView(event_t event)
break;
case EVT_KEY_FIRST(KEY_DOWN):
#if defined(NAVIGATION_X7_TX12)
#if defined(KEYS_GPIO_REG_PAGEUP)
case EVT_KEY_BREAK(KEY_PAGEUP):
killEvents(event);
chainMenu(menuStatisticsDebug2);
@ -140,7 +140,7 @@ void menuStatisticsDebug(event_t event)
break;
case EVT_KEY_FIRST(KEY_UP):
#if defined(NAVIGATION_X7_TX12)
#if defined(KEYS_GPIO_REG_PAGEDN)
case EVT_KEY_BREAK(KEY_PAGEDN):
disableVBatBridge();
chainMenu(menuStatisticsDebug2);
@ -153,7 +153,7 @@ void menuStatisticsDebug(event_t event)
#endif
case EVT_KEY_FIRST(KEY_DOWN):
#if defined(NAVIGATION_X7_TX12)
#if defined(KEYS_GPIO_REG_PAGEUP)
case EVT_KEY_BREAK(KEY_PAGEUP):
#elif defined(NAVIGATION_X7)
case EVT_KEY_LONG(KEY_PAGE):
@ -278,7 +278,7 @@ void menuStatisticsDebug2(event_t event)
break;
case EVT_KEY_FIRST(KEY_UP):
#if defined(NAVIGATION_X7_TX12)
#if defined(KEYS_GPIO_REG_PAGEDN)
case EVT_KEY_BREAK(KEY_PAGEDN):
#elif defined(NAVIGATION_X7)
case EVT_KEY_BREAK(KEY_PAGE):
@ -287,7 +287,7 @@ void menuStatisticsDebug2(event_t event)
return;
case EVT_KEY_FIRST(KEY_DOWN):
#if defined(NAVIGATION_X7_TX12)
#if defined(KEYS_GPIO_REG_PAGEUP)
case EVT_KEY_BREAK(KEY_PAGEUP):
#elif defined(NAVIGATION_X7)
case EVT_KEY_LONG(KEY_PAGE):

View file

@ -47,8 +47,7 @@ enum {
ITEM_RECEIVER_SETTINGS_PWM_RATE,
ITEM_RECEIVER_SETTINGS_TELEMETRY,
ITEM_RECEIVER_SETTINGS_TELEMETRY_25MW,
ITEM_RECEIVER_SETTINGS_SPORT_FPORT,
ITEM_RECEIVER_SETTINGS_FPORT2,
ITEM_RECEIVER_SETTINGS_SPORT_MODE,
ITEM_RECEIVER_SETTINGS_CAPABILITY_NOT_SUPPORTED1,
ITEM_RECEIVER_SETTINGS_CAPABILITY_NOT_SUPPORTED2,
ITEM_RECEIVER_SETTINGS_PINMAP_FIRST
@ -60,6 +59,15 @@ enum {
#define CH_ENABLE_SPORT 4
#define CH_ENABLE_SBUS 5
bool isSPortModeAvailable(int mode)
{
uint8_t receiverId = reusableBuffer.hardwareAndSettings.receiverSettings.receiverId;
if (mode == 2 && !IS_RECEIVER_CAPABILITY_ENABLED(RECEIVER_CAPABILITY_FPORT2)) {
return false;
}
return true;
}
bool menuModelReceiverOptions(event_t event)
{
const int lim = (g_model.extendedLimits ? (512 * LIMIT_EXT_PERCENT / 100) : 512) * 2;
@ -82,8 +90,7 @@ bool menuModelReceiverOptions(event_t event)
0, // PWM rate
isModuleR9MAccess(g_moduleIdx) && receiverVariant == PXX2_VARIANT_EU && reusableBuffer.hardwareAndSettings.moduleSettings.txPower > 14 /*25mW*/ ? READONLY_ROW : (uint8_t)0, // Telemetry
IF_RECEIVER_CAPABILITY(RECEIVER_CAPABILITY_TELEMETRY_25MW, 0),
IF_RECEIVER_CAPABILITY(RECEIVER_CAPABILITY_FPORT, 0),
IF_RECEIVER_CAPABILITY(RECEIVER_CAPABILITY_FPORT2, 0),
uint8_t((IS_RECEIVER_CAPABILITY_ENABLED(RECEIVER_CAPABILITY_FPORT) || IS_RECEIVER_CAPABILITY_ENABLED(RECEIVER_CAPABILITY_FPORT2)) ? 0 : HIDDEN_ROW),
uint8_t(reusableBuffer.hardwareAndSettings.modules[g_moduleIdx].receivers[receiverId].information.capabilityNotSupported ? READONLY_ROW : HIDDEN_ROW),
uint8_t(reusableBuffer.hardwareAndSettings.modules[g_moduleIdx].receivers[receiverId].information.capabilityNotSupported ? READONLY_ROW : HIDDEN_ROW),
0 // channels ...
@ -171,21 +178,19 @@ bool menuModelReceiverOptions(event_t event)
}
break;
case ITEM_RECEIVER_SETTINGS_SPORT_FPORT:
lcdDrawText(MENUS_MARGIN_LEFT, y, "F.Port");
reusableBuffer.hardwareAndSettings.receiverSettings.fport = editCheckBox(reusableBuffer.hardwareAndSettings.receiverSettings.fport, RECEIVER_OPTIONS_2ND_COLUMN, y, attr, event);
if (attr && checkIncDec_Ret) {
case ITEM_RECEIVER_SETTINGS_SPORT_MODE:
{
lcdDrawText(0, y, STR_PROTOCOL);
uint8_t portType = reusableBuffer.hardwareAndSettings.receiverSettings.fport | (reusableBuffer.hardwareAndSettings.receiverSettings.fport2 << 1);
lcdDrawTextAtIndex(LCD_W/2, y, STR_SPORT_MODES, portType, attr);
portType = checkIncDec(event, portType, 0, 2, EE_MODEL, isSPortModeAvailable);
if (checkIncDec_Ret) {
reusableBuffer.hardwareAndSettings.receiverSettings.fport = portType & 0x01;
reusableBuffer.hardwareAndSettings.receiverSettings.fport2 = (portType & 0x02) >> 1;
reusableBuffer.hardwareAndSettings.receiverSettings.dirty = RECEIVER_SETTINGS_DIRTY;
}
break;
case ITEM_RECEIVER_SETTINGS_FPORT2:
lcdDrawText(MENUS_MARGIN_LEFT, y, "F.Port2");
reusableBuffer.hardwareAndSettings.receiverSettings.fport2 = editCheckBox(reusableBuffer.hardwareAndSettings.receiverSettings.fport2, RECEIVER_OPTIONS_2ND_COLUMN, y, attr, event);
if (attr && checkIncDec_Ret) {
reusableBuffer.hardwareAndSettings.receiverSettings.dirty = RECEIVER_SETTINGS_DIRTY;
}
break;
case ITEM_RECEIVER_SETTINGS_CAPABILITY_NOT_SUPPORTED1:
lcdDrawText(LCD_W/2, y+1, STR_MORE_OPTIONS_AVAILABLE, SMLSIZE|CENTERED);

View file

@ -246,6 +246,7 @@ void onModelSelectMenu(const char * result)
if (!confirmModelChange())
return;
}
// we store the latest changes if any
storageFlushCurrentModel();
storageCheck(true);

View file

@ -577,7 +577,7 @@ void onModelAntennaSwitchConfirm(const char * result)
MODULE_TYPE_ROWS(INTERNAL_MODULE), /* ITEM_MODEL_SETUP_INTERNAL_MODULE_TYPE*/ \
MULTIMODULE_STATUS_ROWS(INTERNAL_MODULE) /* ITEM_MODEL_SETUP_INTERNAL_MODULE_STATUS, ITEM_MODEL_SETUP_INTERNAL_MODULE_SYNCSTATUS */ \
MODULE_CHANNELS_ROWS(INTERNAL_MODULE), /* ITEM_MODEL_SETUP_INTERNAL_MODULE_CHANNELS*/ \
IF_NOT_ACCESS_MODULE_RF(INTERNAL_MODULE, IF_INTERNAL_MODULE_ON(IF_INTERNAL_MODULE_ON(isModuleRxNumAvailable(INTERNAL_MODULE) ? (uint8_t)2 : (uint8_t)1))), /* *ITEM_MODEL_SETUP_INTERNAL_MODULE_NOT_ACCESS_RXNUM_BIND_RANGE */\
IF_NOT_ACCESS_MODULE_RF(INTERNAL_MODULE, MODULE_BIND_ROWS(INTERNAL_MODULE)), /* *ITEM_MODEL_SETUP_INTERNAL_MODULE_NOT_ACCESS_RXNUM_BIND_RANGE */\
IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), /* ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_MODEL_NUM*/ \
MODULE_OPTION_ROW(INTERNAL_MODULE), /* ITEM_MODEL_SETUP_INTERNAL_MODULE_OPTIONS */ \
MULTIMODULE_MODULE_ROWS(INTERNAL_MODULE) /* ITEM_MODEL_SETUP_INTERNAL_MODULE_AUTOBIND */ \
@ -1549,6 +1549,7 @@ bool menuModelSetup(event_t event)
lcdDrawText(MENUS_MARGIN_LEFT + INDENT_WIDTH, y, STR_RECEIVER);
int l_posHorz = menuHorizontalPosition;
coord_t bindButtonPos = MODEL_SETUP_2ND_COLUMN;
// RXNUM
if (isModuleRxNumAvailable(moduleIdx)) {
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, g_model.header.modelId[moduleIdx], (l_posHorz==0 ? attr : 0) | LEADING0 | LEFT, 2);
bindButtonPos += 40;
@ -1572,12 +1573,13 @@ bool menuModelSetup(event_t event)
else if (attr) {
l_posHorz += 1;
}
// BIND - RANGE
if (isModuleBindRangeAvailable(moduleIdx)) {
drawButton(bindButtonPos, y, STR_MODULE_BIND, (moduleState[moduleIdx].mode == MODULE_MODE_BIND ? BUTTON_ON : BUTTON_OFF) | (l_posHorz==1 ? attr : 0));
if (isModuleRangeAvailable(moduleIdx)) {
drawButton(bindButtonPos + 80, y, STR_MODULE_RANGE, (moduleState[moduleIdx].mode == MODULE_MODE_RANGECHECK ? BUTTON_ON : BUTTON_OFF) | (l_posHorz==2 ? attr : 0));
}
uint8_t newFlag = 0;
uint8_t newFlag = MODULE_MODE_NORMAL;
#if defined(MULTIMODULE)
if (getMultiBindStatus(moduleIdx) == MULTI_BIND_FINISHED) {
setMultiBindStatus(moduleIdx, MULTI_NORMAL_OPERATION);

View file

@ -61,6 +61,11 @@ void drawTopBar()
lcdDrawBitmapPattern(LCD_W-98, 8, LBM_TOPMENU_USB, MENU_TITLE_COLOR);
}
// Logs
if (isFunctionActive(FUNCTION_LOGS) && !usbPlugged() && BLINK_ON_PHASE) {
lcdDrawBitmapPattern(LCD_W-98, 6, LBM_DOT, MENU_TITLE_COLOR);
}
// RSSI
const uint8_t rssiBarsValue[] = {30, 40, 50, 60, 80};
const uint8_t rssiBarsHeight[] = {5, 10, 15, 21, 31};

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