1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-23 08:15:17 +03:00

Merge branch '2.3' into 3djc/review-about

This commit is contained in:
3djc 2020-12-04 16:06:56 +01:00 committed by GitHub
commit e17ca05c2a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
49 changed files with 1510 additions and 836 deletions

View file

@ -1,6 +1,7 @@
[Main developers]
Bertrand Songis (bsongis)
André Bernet (kilrah)
JC D. (3djc)
Michael Blandford
Damjan Adamic (projectkk2glider)
Franck Aguerre (jivarofad)
@ -9,6 +10,7 @@ Martin Hotař (mhotar)
Maxim (Max) Paperno (mpaperno)
Arne Schwabe (schwabe)
Daniel Gorbea (dgatf)
Neil Horne (elecpower)
[Translators]
[fr] Sebastien Charpentier (LapinFou)
@ -2028,3 +2030,8 @@ Justin Digby
John Magnuson (monthly)
Holger Lippert
Hubert Huber
David Blum
Noam Kfir
Mats gårdstad friberg
Jesper Frickmann
Alan Bunker

View file

@ -30,7 +30,7 @@ RawSourceItemModel::RawSourceItemModel(const GeneralSettings * const generalSett
Firmware * fw = getCurrentFirmware();
addItems(SOURCE_TYPE_NONE, RawSource::NoneGroup, 1);
for (int i=0; i < fw->getCapability(LuaScripts); i++)
for (int i = 0; i < fw->getCapability(LuaScripts); i++)
addItems(SOURCE_TYPE_LUA_OUTPUT, RawSource::ScriptsGroup, fw->getCapability(LuaOutputsPerScript), i * 16);
addItems(SOURCE_TYPE_VIRTUAL_INPUT, RawSource::InputsGroup, fw->getCapability(VirtualInputs));
addItems(SOURCE_TYPE_STICK, RawSource::SourcesGroup, board.getCapability(Board::MaxAnalogs));
@ -43,7 +43,7 @@ RawSourceItemModel::RawSourceItemModel(const GeneralSettings * const generalSett
addItems(SOURCE_TYPE_PPM, RawSource::SourcesGroup, fw->getCapability(TrainerInputs));
addItems(SOURCE_TYPE_CH, RawSource::SourcesGroup, fw->getCapability(Outputs));
addItems(SOURCE_TYPE_SPECIAL, RawSource::TelemGroup, 5);
addItems(SOURCE_TYPE_TELEMETRY, RawSource::TelemGroup, CPN_MAX_SENSORS * 3);
addItems(SOURCE_TYPE_TELEMETRY, RawSource::TelemGroup, fw->getCapability(Sensors) * 3);
addItems(SOURCE_TYPE_GVAR, RawSource::GVarsGroup, fw->getCapability(Gvars));
}
@ -67,10 +67,14 @@ void RawSourceItemModel::addItems(const RawSourceType & type, const int group, c
}
}
void RawSourceItemModel::update() const
void RawSourceItemModel::update()
{
for (int i=0; i < rowCount(); ++i)
emit dataAboutToBeUpdated();
for (int i = 0; i < rowCount(); ++i)
setDynamicItemData(item(i), RawSource(item(i)->data(ItemIdRole).toInt()));
emit dataUpdateComplete();
}
@ -86,7 +90,7 @@ RawSwitchItemModel::RawSwitchItemModel(const GeneralSettings * const generalSett
// Descending switch direction: NOT (!) switches
addItems(SWITCH_TYPE_ACT, -1);
addItems(SWITCH_TYPE_SENSOR, -CPN_MAX_SENSORS);
addItems(SWITCH_TYPE_SENSOR, -fw->getCapability(Sensors));
addItems(SWITCH_TYPE_TELEMETRY, -1);
addItems(SWITCH_TYPE_FLIGHT_MODE, -fw->getCapability(FlightModes));
addItems(SWITCH_TYPE_VIRTUAL, -fw->getCapability(LogicalSwitches));
@ -105,7 +109,7 @@ RawSwitchItemModel::RawSwitchItemModel(const GeneralSettings * const generalSett
addItems(SWITCH_TYPE_VIRTUAL, fw->getCapability(LogicalSwitches));
addItems(SWITCH_TYPE_FLIGHT_MODE, fw->getCapability(FlightModes));
addItems(SWITCH_TYPE_TELEMETRY, 1);
addItems(SWITCH_TYPE_SENSOR, CPN_MAX_SENSORS);
addItems(SWITCH_TYPE_SENSOR, fw->getCapability(Sensors));
addItems(SWITCH_TYPE_ON, 1);
addItems(SWITCH_TYPE_ONE, 1);
addItems(SWITCH_TYPE_ACT, 1);
@ -166,8 +170,95 @@ void RawSwitchItemModel::addItems(const RawSwitchType & type, int count)
}
}
void RawSwitchItemModel::update() const
void RawSwitchItemModel::update()
{
for (int i=0; i < rowCount(); ++i)
emit dataAboutToBeUpdated();
for (int i = 0; i < rowCount(); ++i)
setDynamicItemData(item(i), RawSwitch(item(i)->data(ItemIdRole).toInt()));
emit dataUpdateComplete();
}
//
// CurveItemModel
//
CurveItemModel::CurveItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent) :
AbstractRawItemDataModel(generalSettings, modelData, parent)
{
const int count = getCurrentFirmware()->getCapability(NumCurves);
for (int i = -count ; i <= count; ++i) {
QStandardItem * modelItem = new QStandardItem();
modelItem->setData(i, ItemIdRole);
int flags;
if (i < 0)
flags = DataGroups::NegativeGroup;
else if (i > 0)
flags = DataGroups::PositiveGroup;
else
flags = DataGroups::NoneGroup;
modelItem->setData(flags, ItemFlagsRole);
setDynamicItemData(modelItem, i);
appendRow(modelItem);
}
}
void CurveItemModel::setDynamicItemData(QStandardItem * item, int index) const
{
item->setText(CurveReference(CurveReference::CURVE_REF_CUSTOM, index).toString(modelData, false));
item->setData(true, IsAvailableRole);
}
void CurveItemModel::update()
{
emit dataAboutToBeUpdated();
for (int i = 0; i < rowCount(); ++i)
setDynamicItemData(item(i), item(i)->data(ItemIdRole).toInt());
emit dataUpdateComplete();
}
//
// CommonItemModels
//
CommonItemModels::CommonItemModels(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent) :
QObject(parent)
{
m_rawSourceItemModel = new RawSourceItemModel(generalSettings, modelData, parent);
m_rawSwitchItemModel = new RawSwitchItemModel(generalSettings, modelData, parent);
m_curveItemModel = new CurveItemModel(generalSettings, modelData, parent);
}
CommonItemModels::~CommonItemModels()
{
}
void CommonItemModels::update(const RadioModelObjects radioModelObjects)
{
switch (radioModelObjects) {
case RMO_CHANNELS:
case RMO_INPUTS:
case RMO_TELEMETRY_SENSORS:
case RMO_TIMERS:
m_rawSourceItemModel->update();
break;
case RMO_FLIGHT_MODES:
case RMO_GLOBAL_VARIABLES:
case RMO_LOGICAL_SWITCHES:
m_rawSourceItemModel->update();
m_rawSwitchItemModel->update();
break;
case RMO_CURVES:
m_curveItemModel->update();
break;
case RMO_SCRIPTS:
// no need to refresh
break;
default:
qDebug() << "Unknown RadioModelObject:" << radioModelObjects;
}
}

View file

@ -36,6 +36,13 @@ class AbstractRawItemDataModel: public QStandardItemModel
enum DataRoles { ItemIdRole = Qt::UserRole, ItemTypeRole, ItemFlagsRole, IsAvailableRole };
Q_ENUM(DataRoles)
enum DataGroups {
NoneGroup = 0x01,
NegativeGroup = 0x02,
PositiveGroup = 0x04
};
Q_ENUM(DataGroups)
explicit AbstractRawItemDataModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr) :
QStandardItemModel(parent),
generalSettings(generalSettings),
@ -43,7 +50,11 @@ class AbstractRawItemDataModel: public QStandardItemModel
{}
public slots:
virtual void update() const = 0;
virtual void update() = 0;
signals:
void dataAboutToBeUpdated();
void dataUpdateComplete();
protected:
const GeneralSettings * generalSettings;
@ -58,7 +69,7 @@ class RawSourceItemModel: public AbstractRawItemDataModel
explicit RawSourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr);
public slots:
void update() const override;
void update() override;
protected:
void setDynamicItemData(QStandardItem * item, const RawSource & src) const;
@ -73,7 +84,7 @@ class RawSwitchItemModel: public AbstractRawItemDataModel
explicit RawSwitchItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr);
public slots:
void update() const override;
void update() override;
protected:
void setDynamicItemData(QStandardItem * item, const RawSwitch & rsw) const;
@ -81,4 +92,49 @@ class RawSwitchItemModel: public AbstractRawItemDataModel
};
class CurveItemModel: public AbstractRawItemDataModel
{
Q_OBJECT
public:
explicit CurveItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr);
public slots:
void update() override;
protected:
void setDynamicItemData(QStandardItem * item, int index) const;
};
class CommonItemModels: public QObject
{
Q_OBJECT
public:
enum RadioModelObjects {
RMO_CHANNELS,
RMO_CURVES,
RMO_FLIGHT_MODES,
RMO_GLOBAL_VARIABLES,
RMO_INPUTS,
RMO_LOGICAL_SWITCHES,
RMO_SCRIPTS,
RMO_TELEMETRY_SENSORS,
RMO_TIMERS
};
Q_ENUM(RadioModelObjects)
explicit CommonItemModels(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr);
~CommonItemModels();
void update(const RadioModelObjects radioModelObjects);
RawSourceItemModel * rawSourceItemModel() const { return m_rawSourceItemModel; }
RawSwitchItemModel * rawSwitchItemModel() const { return m_rawSwitchItemModel; }
CurveItemModel * curveItemModel() const { return m_curveItemModel; }
private:
RawSourceItemModel *m_rawSourceItemModel;
RawSwitchItemModel *m_rawSwitchItemModel;
CurveItemModel *m_curveItemModel;
};
#endif // RAWITEMDATAMODELS_H

View file

@ -19,7 +19,6 @@
*/
#include "rawitemfilteredmodel.h"
#include "rawitemdatamodels.h"
RawItemFilteredModel::RawItemFilteredModel(QAbstractItemModel * sourceModel, int flags, QObject * parent) :
QSortFilterProxyModel(parent),
@ -30,6 +29,12 @@ RawItemFilteredModel::RawItemFilteredModel(QAbstractItemModel * sourceModel, int
setFilterFlags(flags);
setDynamicSortFilter(true);
setSourceModel(sourceModel);
AbstractRawItemDataModel * itemModel = qobject_cast<AbstractRawItemDataModel *>(sourceModel);
if (itemModel) {
connect(itemModel, &AbstractRawItemDataModel::dataAboutToBeUpdated, this, &RawItemFilteredModel::onDataAboutToBeUpdated);
connect(itemModel, &AbstractRawItemDataModel::dataUpdateComplete, this, &RawItemFilteredModel::onDataUpdateComplete);
}
}
void RawItemFilteredModel::setFilterFlags(int flags)
@ -56,19 +61,17 @@ bool RawItemFilteredModel::filterAcceptsRow(int sourceRow, const QModelIndex & s
void RawItemFilteredModel::update() const
{
AbstractRawItemDataModel * model = qobject_cast<AbstractRawItemDataModel *>(sourceModel());
if (model)
model->update();
AbstractRawItemDataModel * itemModel = qobject_cast<AbstractRawItemDataModel *>(sourceModel());
if (itemModel)
itemModel->update();
}
RawSourceFilterItemModel::RawSourceFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, int flags, QObject * parent) :
RawItemFilteredModel(new RawSourceItemModel(generalSettings, modelData, parent), flags, parent)
void RawItemFilteredModel::onDataAboutToBeUpdated()
{
emit dataAboutToBeUpdated();
}
RawSwitchFilterItemModel::RawSwitchFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, int context, QObject * parent) :
RawItemFilteredModel(new RawSwitchItemModel(generalSettings, modelData, parent), context, parent)
void RawItemFilteredModel::onDataUpdateComplete()
{
emit dataUpdateComplete();
}

View file

@ -21,54 +21,43 @@
#ifndef RAWITEMFILTEREDMODEL_H
#define RAWITEMFILTEREDMODEL_H
#include "rawitemdatamodels.h"
#include <QSortFilterProxyModel>
class GeneralSettings;
class ModelData;
class RawSourceItemModel;
class RawSwitchItemModel;
class RawItemFilteredModel: public QSortFilterProxyModel
{
Q_OBJECT
public:
enum DataFilters {
AllFilter = AbstractRawItemDataModel::NegativeGroup | AbstractRawItemDataModel::NoneGroup | AbstractRawItemDataModel::PositiveGroup,
AllExcludeNoneFilter = AllFilter &~ AbstractRawItemDataModel::NoneGroup,
NegativeFilter = AbstractRawItemDataModel::NegativeGroup | AbstractRawItemDataModel::NoneGroup,
NegativeExcludeNoneFilter = AbstractRawItemDataModel::NegativeGroup,
PositiveFilter = AbstractRawItemDataModel::PositiveGroup | AbstractRawItemDataModel::NoneGroup,
PositiveExcludeNoneFilter = AbstractRawItemDataModel::PositiveGroup
};
Q_ENUM(DataFilters)
explicit RawItemFilteredModel(QAbstractItemModel * sourceModel, int flags, QObject * parent = nullptr);
explicit RawItemFilteredModel(QAbstractItemModel * sourceModel, QObject * parent = nullptr) : RawItemFilteredModel(sourceModel, 0, parent) {}
public slots:
void setFilterFlags(int flags);
void update() const;
void onDataAboutToBeUpdated();
void onDataUpdateComplete();
signals:
void dataAboutToBeUpdated();
void dataUpdateComplete();
protected:
bool filterAcceptsRow(int sourceRow, const QModelIndex & sourceParent) const override;
int filterFlags;
};
// The specialized "convenience" types below can go away once centralalized RawSource/RawSwitch item models are established.
// These proxy classes will automatically create a source model of the corresponding type.
class RawSwitchFilterItemModel: public RawItemFilteredModel
{
Q_OBJECT
public:
using RawItemFilteredModel::RawItemFilteredModel;
explicit RawSwitchFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, int context, QObject * parent = nullptr);
};
class RawSourceFilterItemModel: public RawItemFilteredModel
{
Q_OBJECT
public:
using RawItemFilteredModel::RawItemFilteredModel;
explicit RawSourceFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, int flags, QObject * parent = nullptr);
explicit RawSourceFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr) :
RawSourceFilterItemModel(generalSettings, modelData, 0, parent) {}
};
#endif // RAWITEMFILTEREDMODEL_H

View file

@ -36,6 +36,15 @@ class CurveReference {
CURVE_REF_CUSTOM
};
enum CurveRefGroups {
NoneGroup = 0x001,
NegativeGroup = 0x002,
PositiveGroup = 0x004,
AllCurveRefGroups = NoneGroup | NegativeGroup | PositiveGroup,
PositiveCurveRefGroups = AllCurveRefGroups &~ NegativeGroup
};
CurveReference() { clear(); }
CurveReference(CurveRefType type, int value):
@ -51,6 +60,14 @@ class CurveReference {
QString toString(const ModelData * model = NULL, bool verbose = true) const;
bool isSet() const { return type != CURVE_REF_DIFF || value != 0; }
bool operator == ( const CurveReference & other) const {
return (this->type == other.type) && (this->value == other.value);
}
bool operator != ( const CurveReference & other) const {
return (this->type != other.type) || (this->value != other.value);
}
};
#endif // CURVEREFERENCE_H

View file

@ -126,20 +126,15 @@ void CustomFunctionData::populateResetParams(const ModelData * model, QComboBox
b->addItem(tr("REa"), val++);
b->addItem(tr("REb"), val++);
}
if ((int)value < b->count()) {
b->setCurrentIndex(value);
}
if (model) {
for (unsigned i=0; i<CPN_MAX_SENSORS; ++i) {
for (int i = 0; i < firmware->getCapability(Sensors); ++i) {
if (model->sensorData[i].isAvailable()) {
RawSource item = RawSource(SOURCE_TYPE_TELEMETRY, 3*i);
b->addItem(item.toString(model), val+i);
if (value == val+i) {
b->setCurrentIndex(b->count()-1);
}
RawSource item = RawSource(SOURCE_TYPE_TELEMETRY, 3 * i);
b->addItem(item.toString(model), val + i);
}
}
}
b->setCurrentIndex(b->findData(value));
}
void CustomFunctionData::populatePlaySoundParams(QStringList & qs)

View file

@ -723,11 +723,15 @@ int ModelData::updateReference()
updateAssignFunc(cfd);
if (!cfd->isEmpty()) {
updateSwitchRef(cfd->swtch);
if (cfd->func == FuncVolume || cfd->func == FuncBacklight || cfd->func == FuncPlayValue || (cfd->func >= FuncAdjustGV1 && cfd->func <= FuncAdjustGVLast && (cfd->adjustMode == FUNC_ADJUST_GVAR_GVAR || cfd->adjustMode == FUNC_ADJUST_GVAR_SOURCE))) {
if (cfd->func == FuncVolume || cfd->func == FuncBacklight || cfd->func == FuncPlayValue ||
(cfd->func >= FuncAdjustGV1 && cfd->func <= FuncAdjustGVLast && (cfd->adjustMode == FUNC_ADJUST_GVAR_GVAR || cfd->adjustMode == FUNC_ADJUST_GVAR_SOURCE))) {
updateSourceIntRef(cfd->param);
if (cfd->param == 0)
cfd->clear();
}
else if (cfd->func == FuncReset) {
updateResetParam(cfd);
}
}
}
}
@ -847,7 +851,7 @@ void ModelData::updateTypeIndexRef(R & curRef, const T type, const int idxAdj, c
newRef.clear();
else {
newRef.type = (T)defType;
newRef.index = defIndex + idxAdj;
newRef.index = defIndex;
}
break;
case REF_UPD_ACT_SHIFT:
@ -904,7 +908,7 @@ void ModelData::updateTypeValueRef(R & curRef, const T type, const int idxAdj, c
newRef.clear();
else {
newRef.type = (T)defType;
newRef.value = defValue + idxAdj;
newRef.value = defValue;
}
break;
case REF_UPD_ACT_SHIFT:
@ -972,7 +976,7 @@ void ModelData::updateAssignFunc(CustomFunctionData * cfd)
{
const int invalidateRef = -1;
int newRef = (int)cfd->func;
int idxAdj;
int idxAdj = 0;
switch (updRefInfo.type)
{
@ -989,7 +993,7 @@ void ModelData::updateAssignFunc(CustomFunctionData * cfd)
case REF_UPD_TYPE_TIMER:
if (cfd->func < FuncSetTimer1 || cfd->func > FuncSetTimer3) // TODO refactor to FuncSetTimerLast
return;
idxAdj = FuncSetTimer1 - 2; // reverse earlier offset requiured for rawsource
idxAdj = FuncSetTimer1 - 2; // reverse earlier offset required for rawsource
break;
default:
return;
@ -1374,3 +1378,64 @@ void ModelData::sortMixes()
memcpy(&mixData[0], &sortedMixData[0], CPN_MAX_MIXERS * sizeof(MixData));
}
void ModelData::updateResetParam(CustomFunctionData * cfd)
{
if (cfd->func != FuncReset)
return;
const int invalidateRef = -1;
int newRef = cfd->param;
int idxAdj = 0;
Firmware *firmware = getCurrentFirmware();
switch (updRefInfo.type)
{
case REF_UPD_TYPE_SENSOR:
idxAdj = 5/*3 Timers + Flight + Telemetery*/ + firmware->getCapability(RotaryEncoders);
if (cfd->param < idxAdj || cfd->param > (idxAdj + firmware->getCapability(Sensors)))
return;
break;
default:
return;
}
switch (updRefInfo.action)
{
case REF_UPD_ACT_CLEAR:
if (newRef != (updRefInfo.index1 + idxAdj))
return;
newRef = invalidateRef;
break;
case REF_UPD_ACT_SHIFT:
if (newRef < (updRefInfo.index1 + idxAdj))
return;
newRef += updRefInfo.shift;
if (newRef < (updRefInfo.index1 + idxAdj) || newRef > (updRefInfo.maxindex + idxAdj))
newRef = invalidateRef;
break;
case REF_UPD_ACT_SWAP:
if (newRef == updRefInfo.index1 + idxAdj)
newRef = updRefInfo.index2 + idxAdj;
else if (newRef == updRefInfo.index2 + idxAdj)
newRef = updRefInfo.index1 + idxAdj;
break;
default:
qDebug() << "Error - unhandled action:" << updRefInfo.action;
return;
}
if (newRef == invalidateRef) {
cfd->clear();
//qDebug() << "Function cleared";
updRefInfo.updcnt++;
}
else if (cfd->param != newRef) {
//qDebug() << "Updated reference:" << cfd->param << " -> " << newRef;
cfd->param = newRef;
updRefInfo.updcnt++;
}
}

View file

@ -338,6 +338,7 @@ class ModelData {
value = swtch.toValue();
}
void sortMixes();
void updateResetParam(CustomFunctionData * cfd);
};
#endif // MODELDATA_H

View file

@ -1202,19 +1202,19 @@ void registerOpenTxFirmwares()
firmware->addOption("horussticks", Firmware::tr("Horus gimbals installed (Hall sensors)"));
addOpenTxTaranisOptions(firmware);
registerOpenTxFirmware(firmware);
addOpenTxRfOptions(firmware, EU + FLEX + AFHDS3);
addOpenTxRfOptions(firmware, EU + FLEX);
/* FrSky X9-Lite board */
firmware = new OpenTxFirmware("opentx-x9lite", Firmware::tr("FrSky Taranis X9-Lite"), BOARD_TARANIS_X9LITE);
addOpenTxTaranisOptions(firmware);
registerOpenTxFirmware(firmware);
addOpenTxRfOptions(firmware, FLEX + AFHDS3);
addOpenTxRfOptions(firmware, FLEX);
/* FrSky X9-LiteS board */
firmware = new OpenTxFirmware("opentx-x9lites", Firmware::tr("FrSky Taranis X9-Lite S"), BOARD_TARANIS_X9LITES);
addOpenTxTaranisOptions(firmware);
registerOpenTxFirmware(firmware);
addOpenTxRfOptions(firmware, FLEX + AFHDS3);
addOpenTxRfOptions(firmware, FLEX);
/* FrSky X7 board */
firmware = new OpenTxFirmware("opentx-x7", Firmware::tr("FrSky Taranis X7 / X7S"), BOARD_TARANIS_X7);
@ -1232,7 +1232,7 @@ void registerOpenTxFirmwares()
firmware = new OpenTxFirmware("opentx-xlites", Firmware::tr("FrSky Taranis X-Lite S/PRO"), BOARD_TARANIS_XLITES);
addOpenTxTaranisOptions(firmware);
registerOpenTxFirmware(firmware);
addOpenTxRfOptions(firmware, FLEX + AFHDS3);
addOpenTxRfOptions(firmware, FLEX);
/* FrSky X-Lite board */
firmware = new OpenTxFirmware("opentx-xlite", Firmware::tr("FrSky Taranis X-Lite"), BOARD_TARANIS_XLITE);
@ -1273,7 +1273,7 @@ void registerOpenTxFirmwares()
firmware->addOption("internalmulti", Firmware::tr("Support for MULTI internal module"));
addOpenTxFontOptions(firmware);
registerOpenTxFirmware(firmware);
addOpenTxRfOptions(firmware, FLEX + AFHDS3);
addOpenTxRfOptions(firmware, FLEX);
/* Jumper T16 board */
firmware = new OpenTxFirmware("opentx-t16", Firmware::tr("Jumper T16 / T16+ / T16 Pro"), BOARD_JUMPER_T16);
@ -1292,7 +1292,7 @@ void registerOpenTxFirmwares()
firmware->addOption("lua", Firmware::tr("Enable Lua custom scripts screen"));
addOpenTxFontOptions(firmware);
registerOpenTxFirmware(firmware);
addOpenTxRfOptions(firmware, FLEX + AFHDS3);
addOpenTxRfOptions(firmware, FLEX);
/* Radiomaster TX16S board */
firmware = new OpenTxFirmware("opentx-tx16s", Firmware::tr("Radiomaster TX16S / SE / Hall / Masterfire"), BOARD_RADIOMASTER_TX16S);

View file

@ -59,7 +59,7 @@ QString RawSwitch::toString(Board::Type board, const GeneralSettings * const gen
tr("THs"), tr("TH%"), tr("THt")
};
const QStringList directionIndicators = QStringList()
static const QStringList directionIndicators = QStringList()
<< CPN_STR_SW_INDICATOR_UP
<< CPN_STR_SW_INDICATOR_NEUT
<< CPN_STR_SW_INDICATOR_DN;

View file

@ -28,4 +28,4 @@ qt5_wrap_ui(generaledit_SRCS ${generaledit_UIS})
qt5_wrap_cpp(generaledit_SRCS ${generaledit_HDRS})
add_library(generaledit ${generaledit_SRCS})
target_link_libraries(generaledit PRIVATE ${CPN_COMMON_LIB} Qt5::Multimedia)
target_link_libraries(generaledit PRIVATE datamodels ${CPN_COMMON_LIB} Qt5::Multimedia)

View file

@ -28,6 +28,7 @@
#include "hardware.h"
#include "../modeledit/customfunctions.h"
#include "verticalscrollarea.h"
#include "rawitemdatamodels.h"
GeneralEdit::GeneralEdit(QWidget * parent, RadioData & radioData, Firmware * firmware) :
QDialog(parent),
@ -55,8 +56,10 @@ GeneralEdit::GeneralEdit(QWidget * parent, RadioData & radioData, Firmware * fir
}
}
commonItemModels = new CommonItemModels(&generalSettings, nullptr, this);
addTab(new GeneralSetupPanel(this, generalSettings, firmware), tr("Setup"));
addTab(new CustomFunctionsPanel(this, NULL, generalSettings, firmware), tr("Global Functions"));
addTab(new CustomFunctionsPanel(this, nullptr, generalSettings, firmware, commonItemModels), tr("Global Functions"));
addTab(new TrainerPanel(this, generalSettings, firmware), tr("Trainer"));
addTab(new HardwarePanel(this, generalSettings, firmware), tr("Hardware"));
addTab(new CalibrationPanel(this, generalSettings, firmware), tr("Calibration"));

View file

@ -25,6 +25,8 @@
#include "eeprominterface.h"
#include "genericpanel.h"
class CommonItemModels;
namespace Ui {
class GeneralEdit;
}
@ -56,7 +58,7 @@ class GeneralEdit : public QDialog
void getGeneralSwitchDefPos(int i, bool val);
void setSwitchDefPos();
void updateVarioPitchRange();
signals:
void modified();
@ -71,7 +73,7 @@ class GeneralEdit : public QDialog
QVector<GenericPanel *> panels;
void addTab(GenericPanel *panel, QString text);
void closeEvent(QCloseEvent *event);
CommonItemModels *commonItemModels;
};
#endif // _GENERALEDIT_H_

View file

@ -742,7 +742,8 @@ GpsCoord extractGpsCoordinates(const QString & position)
return result;
}
TableLayout::TableLayout(QWidget * parent, int rowCount, const QStringList & headerLabels)
TableLayout::TableLayout(QWidget * parent, int rowCount, const QStringList & headerLabels) :
QObject(parent)
{
#if defined(TABLE_LAYOUT)
tableWidget = new QTableWidget(parent);

View file

@ -208,8 +208,9 @@ private:
GpsCoord extractGpsCoordinates(const QString & position);
class TableLayout
class TableLayout: public QObject
{
Q_OBJECT
public:
TableLayout(QWidget * parent, int rowCount, const QStringList & headerLabels);
// ~TableLayout() ;

View file

@ -20,6 +20,7 @@
#include "channels.h"
#include "helpers.h"
#include "rawitemfilteredmodel.h"
LimitsGroup::LimitsGroup(Firmware * firmware, TableLayout * tableLayout, int row, int col, int & value, const ModelData & model, int min, int max, int deflt, ModelPanel * panel):
firmware(firmware),
@ -95,15 +96,17 @@ void LimitsGroup::updateMinMax(int max)
}
}
}
Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware):
ModelPanel(parent, model, generalSettings, firmware)
ChannelsPanel::ChannelsPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels):
ModelPanel(parent, model, generalSettings, firmware),
commonItemModels(commonItemModels)
{
Stopwatch s1("Channels");
chnCapability = firmware->getCapability(Outputs);
int channelNameMaxLen = firmware->getCapability(ChannelsName);
curveFilteredModel = new RawItemFilteredModel(commonItemModels->curveItemModel(), RawItemFilteredModel::AllFilter, this);
connect(curveFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &ChannelsPanel::onModelDataAboutToBeUpdated);
connect(curveFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &ChannelsPanel::onModelDataUpdateComplete);
QStringList headerLabels;
headerLabels << "#";
if (channelNameMaxLen > 0) {
@ -118,8 +121,6 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera
headerLabels << tr("Linear Subtrim");
TableLayout *tableLayout = new TableLayout(this, chnCapability, headerLabels);
s1.report("header");
for (int i = 0; i < chnCapability; i++) {
int col = 0;
@ -165,6 +166,7 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera
if (IS_HORUS_OR_TARANIS(firmware->getBoard())) {
curveCB[i] = new QComboBox(this);
curveCB[i]->setProperty("index", i);
curveCB[i]->setModel(curveFilteredModel);
connect(curveCB[i], SIGNAL(currentIndexChanged(int)), this, SLOT(curveEdited()));
tableLayout->addWidget(i, col++, curveCB[i]);
}
@ -193,15 +195,13 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera
}
}
update();
s1.report("add elements");
disableMouseScrolling();
tableLayout->resizeColumnsToContents();
tableLayout->pushRowsUp(chnCapability+1);
s1.report("end");
}
Channels::~Channels()
ChannelsPanel::~ChannelsPanel()
{
// compiler warning if delete[]
for (int i = 0; i < CPN_MAX_CHNOUT; i++) {
@ -216,7 +216,7 @@ Channels::~Channels()
}
}
void Channels::symlimitsEdited()
void ChannelsPanel::symlimitsEdited()
{
if (!lock) {
QCheckBox *ckb = qobject_cast<QCheckBox*>(sender());
@ -226,17 +226,20 @@ void Channels::symlimitsEdited()
}
}
void Channels::nameEdited()
void ChannelsPanel::nameEdited()
{
if (!lock) {
QLineEdit *le = qobject_cast<QLineEdit*>(sender());
int index = le->property("index").toInt();
strcpy(model->limitData[index].name, le->text().toLatin1());
emit modified();
if (model->limitData[index].name != le->text()) {
strcpy(model->limitData[index].name, le->text().toLatin1());
updateItemModels();
emit modified();
}
}
}
void Channels::refreshExtendedLimits()
void ChannelsPanel::refreshExtendedLimits()
{
int channelMax = model->getChannelsMax();
@ -248,7 +251,7 @@ void Channels::refreshExtendedLimits()
emit modified();
}
void Channels::invEdited()
void ChannelsPanel::invEdited()
{
if (!lock) {
QComboBox *cb = qobject_cast<QComboBox*>(sender());
@ -258,17 +261,20 @@ void Channels::invEdited()
}
}
void Channels::curveEdited()
void ChannelsPanel::curveEdited()
{
if (!lock) {
QComboBox *cb = qobject_cast<QComboBox*>(sender());
int index = cb->property("index").toInt();
model->limitData[index].curve = CurveReference(CurveReference::CURVE_REF_CUSTOM, cb->itemData(cb->currentIndex()).toInt());
emit modified();
// ignore unnecessary updates that could be triggered by updates to the data model
if (model->limitData[index].curve != CurveReference(CurveReference::CURVE_REF_CUSTOM, cb->itemData(cb->currentIndex()).toInt())) {
model->limitData[index].curve = CurveReference(CurveReference::CURVE_REF_CUSTOM, cb->itemData(cb->currentIndex()).toInt());
emit modified();
}
}
}
void Channels::ppmcenterEdited()
void ChannelsPanel::ppmcenterEdited()
{
if (!lock) {
QSpinBox *sb = qobject_cast<QSpinBox*>(sender());
@ -278,51 +284,49 @@ void Channels::ppmcenterEdited()
}
}
void Channels::update()
void ChannelsPanel::update()
{
for (int i = 0; i < chnCapability; i++) {
updateLine(i);
}
}
void Channels::updateLine(int i)
void ChannelsPanel::updateLine(int i)
{
lock = true;
LimitData &chn = model->limitData[i];
if (firmware->getCapability(ChannelsName) > 0) {
name[i]->setText(model->limitData[i].name);
name[i]->setText(chn.name);
}
chnOffset[i]->setValue(model->limitData[i].offset);
chnMin[i]->setValue(model->limitData[i].min);
chnMax[i]->setValue(model->limitData[i].max);
invCB[i]->setCurrentIndex((model->limitData[i].revert) ? 1 : 0);
chnOffset[i]->setValue(chn.offset);
chnMin[i]->setValue(chn.min);
chnMax[i]->setValue(chn.max);
invCB[i]->setCurrentIndex((chn.revert) ? 1 : 0);
if (IS_HORUS_OR_TARANIS(firmware->getBoard())) {
int numcurves = firmware->getCapability(NumCurves);
curveCB[i]->clear();
for (int j = -numcurves; j <= numcurves; j++) {
curveCB[i]->addItem(CurveReference(CurveReference::CURVE_REF_CUSTOM, j).toString(model, false), j);
}
curveCB[i]->setCurrentIndex(model->limitData[i].curve.value + numcurves);
curveCB[i]->setCurrentIndex(curveCB[i]->findData(chn.curve.value));
}
if (firmware->getCapability(PPMCenter)) {
centerSB[i]->setValue(model->limitData[i].ppmCenter + 1500);
centerSB[i]->setValue(chn.ppmCenter + 1500);
}
if (firmware->getCapability(SYMLimits)) {
symlimitsChk[i]->setChecked(model->limitData[i].symetrical);
symlimitsChk[i]->setChecked(chn.symetrical);
}
lock = false;
}
void Channels::cmPaste()
void ChannelsPanel::cmPaste()
{
QByteArray data;
if (hasClipboardData(&data)) {
memcpy(&model->limitData[selectedIndex], data.constData(), sizeof(LimitData));
updateLine(selectedIndex);
updateItemModels();
emit modified();
}
}
void Channels::cmDelete()
void ChannelsPanel::cmDelete()
{
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Delete Channel. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
return;
@ -335,10 +339,11 @@ void Channels::cmDelete()
updateLine(i);
}
updateItemModels();
emit modified();
}
void Channels::cmCopy()
void ChannelsPanel::cmCopy()
{
QByteArray data;
data.append((char*)&model->limitData[selectedIndex], sizeof(LimitData));
@ -347,7 +352,7 @@ void Channels::cmCopy()
QApplication::clipboard()->setMimeData(mimeData,QClipboard::Clipboard);
}
void Channels::cmCut()
void ChannelsPanel::cmCut()
{
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Cut Channel. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
return;
@ -356,7 +361,7 @@ void Channels::cmCut()
cmClear(false);
}
void Channels::onCustomContextMenuRequested(QPoint pos)
void ChannelsPanel::onCustomContextMenuRequested(QPoint pos)
{
QLabel *label = (QLabel *)sender();
selectedIndex = label->property("index").toInt();
@ -378,7 +383,7 @@ void Channels::onCustomContextMenuRequested(QPoint pos)
contextMenu.exec(globalPos);
}
bool Channels::hasClipboardData(QByteArray * data) const
bool ChannelsPanel::hasClipboardData(QByteArray * data) const
{
const QClipboard * clipboard = QApplication::clipboard();
const QMimeData * mimeData = clipboard->mimeData();
@ -390,32 +395,32 @@ bool Channels::hasClipboardData(QByteArray * data) const
return false;
}
bool Channels::insertAllowed() const
bool ChannelsPanel::insertAllowed() const
{
return ((selectedIndex < chnCapability - 1) && (model->limitData[chnCapability - 1].isEmpty()));
}
bool Channels::moveDownAllowed() const
bool ChannelsPanel::moveDownAllowed() const
{
return selectedIndex < chnCapability - 1;
}
bool Channels::moveUpAllowed() const
bool ChannelsPanel::moveUpAllowed() const
{
return selectedIndex > 0;
}
void Channels::cmMoveUp()
void ChannelsPanel::cmMoveUp()
{
swapData(selectedIndex, selectedIndex - 1);
}
void Channels::cmMoveDown()
void ChannelsPanel::cmMoveDown()
{
swapData(selectedIndex, selectedIndex + 1);
}
void Channels::cmClear(bool prompt)
void ChannelsPanel::cmClear(bool prompt)
{
if (prompt) {
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear Channel. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
@ -425,10 +430,11 @@ void Channels::cmClear(bool prompt)
model->limitData[selectedIndex].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_CHANNEL, ModelData::REF_UPD_ACT_CLEAR, selectedIndex);
updateLine(selectedIndex);
updateItemModels();
emit modified();
}
void Channels::cmClearAll()
void ChannelsPanel::cmClearAll()
{
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear all Channels. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
return;
@ -438,19 +444,21 @@ void Channels::cmClearAll()
model->updateAllReferences(ModelData::REF_UPD_TYPE_CHANNEL, ModelData::REF_UPD_ACT_CLEAR, i);
updateLine(i);
}
updateItemModels();
emit modified();
}
void Channels::cmInsert()
void ChannelsPanel::cmInsert()
{
memmove(&model->limitData[selectedIndex + 1], &model->limitData[selectedIndex], (CPN_MAX_CHNOUT - (selectedIndex + 1)) * sizeof(LimitData));
model->limitData[selectedIndex].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_CHANNEL, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, 1);
update();
updateItemModels();
emit modified();
}
void Channels::swapData(int idx1, int idx2)
void ChannelsPanel::swapData(int idx1, int idx2)
{
if ((idx1 != idx2) && (!model->limitData[idx1].isEmpty() || !model->limitData[idx2].isEmpty())) {
LimitData chntmp = model->limitData[idx2];
@ -461,6 +469,23 @@ void Channels::swapData(int idx1, int idx2)
model->updateAllReferences(ModelData::REF_UPD_TYPE_CHANNEL, ModelData::REF_UPD_ACT_SWAP, idx1, idx2);
updateLine(idx1);
updateLine(idx2);
updateItemModels();
emit modified();
}
}
void ChannelsPanel::onModelDataAboutToBeUpdated()
{
lock = true;
}
void ChannelsPanel::onModelDataUpdateComplete()
{
update();
lock = false;
}
void ChannelsPanel::updateItemModels()
{
commonItemModels->update(CommonItemModels::RMO_CHANNELS);
}

View file

@ -26,6 +26,9 @@
#include <QtCore>
class CommonItemModels;
class RawItemFilteredModel;
constexpr char MIMETYPE_CHANNEL[] = "application/x-companion-channel";
class GVarGroup;
@ -49,13 +52,13 @@ class LimitsGroup
double displayStep;
};
class Channels : public ModelPanel
class ChannelsPanel : public ModelPanel
{
Q_OBJECT
public:
Channels(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware);
~Channels();
ChannelsPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels);
~ChannelsPanel();
public slots:
void refreshExtendedLimits();
@ -78,6 +81,8 @@ class Channels : public ModelPanel
void cmClear(bool prompt = true);
void cmClearAll();
void onCustomContextMenuRequested(QPoint pos);
void onModelDataAboutToBeUpdated();
void onModelDataUpdateComplete();
private:
bool hasClipboardData(QByteArray * data = nullptr) const;
@ -95,6 +100,9 @@ class Channels : public ModelPanel
QCheckBox *symlimitsChk[CPN_MAX_CHNOUT];
int selectedIndex;
int chnCapability;
CommonItemModels * commonItemModels;
RawItemFilteredModel *curveFilteredModel;
void updateItemModels();
};
#endif // _CHANNELS_H_

View file

@ -23,6 +23,7 @@
#include "node.h"
#include "edge.h"
#include "helpers.h"
#include "rawitemfilteredmodel.h"
#define GFX_MARGIN 16
@ -108,10 +109,11 @@ float curveSymmetricalX(float x, float coeff, float yMin, float yMid, float yMax
return y;
}
Curves::Curves(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware):
CurvesPanel::CurvesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels):
ModelPanel(parent, model, generalSettings, firmware),
ui(new Ui::Curves),
currentCurve(0)
currentCurve(0),
commonItemModels(commonItemModels)
{
ui->setupUi(this);
@ -230,12 +232,12 @@ Curves::Curves(QWidget * parent, ModelData & model, GeneralSettings & generalSet
lock = false;
}
Curves::~Curves()
CurvesPanel::~CurvesPanel()
{
delete ui;
}
void Curves::editCurve()
void CurvesPanel::editCurve()
{
QPushButton *button = (QPushButton *)sender();
int index = button->property("index").toInt();
@ -243,7 +245,7 @@ void Curves::editCurve()
update();
}
void Curves::plotCurve(bool checked)
void CurvesPanel::plotCurve(bool checked)
{
QCheckBox *chk = (QCheckBox *)sender();
int index = chk->property("index").toInt();
@ -251,7 +253,7 @@ void Curves::plotCurve(bool checked)
updateCurve();
}
void Curves::update()
void CurvesPanel::update()
{
lock = true;
@ -266,12 +268,12 @@ void Curves::update()
lock = false;
}
void Curves::setCurrentCurve(int index)
void CurvesPanel::setCurrentCurve(int index)
{
currentCurve = index;
}
void Curves::updateCurveType()
void CurvesPanel::updateCurveType()
{
lock = true;
@ -297,7 +299,7 @@ void Curves::updateCurveType()
lock = false;
}
void Curves::updateCurve()
void CurvesPanel::updateCurve()
{
lock = true;
@ -371,7 +373,7 @@ void Curves::updateCurve()
lock = false;
}
void Curves::updateCurvePoints()
void CurvesPanel::updateCurvePoints()
{
lock = true;
@ -405,7 +407,7 @@ void Curves::updateCurvePoints()
lock = false;
}
void Curves::onPointEdited()
void CurvesPanel::onPointEdited()
{
if (!lock) {
int index = sender()->property("index").toInt();
@ -417,7 +419,7 @@ void Curves::onPointEdited()
}
}
void Curves::onNodeMoved(int x, int y)
void CurvesPanel::onNodeMoved(int x, int y)
{
if (!lock) {
lock = true;
@ -435,20 +437,20 @@ void Curves::onNodeMoved(int x, int y)
}
}
void Curves::onNodeFocus()
void CurvesPanel::onNodeFocus()
{
int index = sender()->property("index").toInt();
spny[index]->setFocus();
}
void Curves::onNodeUnfocus()
void CurvesPanel::onNodeUnfocus()
{
int index = sender()->property("index").toInt();
spny[index]->clearFocus();
updateCurve();
}
bool Curves::allowCurveType(int points, CurveData::CurveType type)
bool CurvesPanel::allowCurveType(int points, CurveData::CurveType type)
{
int totalpoints = 0;
for (int i = 0; i < maxCurves; i++) {
@ -466,7 +468,7 @@ bool Curves::allowCurveType(int points, CurveData::CurveType type)
}
}
void Curves::on_curvePoints_currentIndexChanged(int index)
void CurvesPanel::on_curvePoints_currentIndexChanged(int index)
{
if (!lock) {
int numpoints = ((QComboBox *)sender())->itemData(index).toInt();
@ -489,7 +491,7 @@ void Curves::on_curvePoints_currentIndexChanged(int index)
}
}
void Curves::on_curveCustom_currentIndexChanged(int index)
void CurvesPanel::on_curveCustom_currentIndexChanged(int index)
{
if (!lock) {
CurveData::CurveType type = (CurveData::CurveType)index;
@ -513,20 +515,23 @@ void Curves::on_curveCustom_currentIndexChanged(int index)
}
}
void Curves::on_curveSmooth_currentIndexChanged(int index)
void CurvesPanel::on_curveSmooth_currentIndexChanged(int index)
{
model->curves[currentCurve].smooth = index;
update();
}
void Curves::on_curveName_editingFinished()
void CurvesPanel::on_curveName_editingFinished()
{
memset(model->curves[currentCurve].name, 0, sizeof(model->curves[currentCurve].name));
strcpy(model->curves[currentCurve].name, ui->curveName->text().toLatin1());
emit modified();
if (ui->curveName->text() != model->curves[currentCurve].name) {
memset(model->curves[currentCurve].name, 0, sizeof(model->curves[currentCurve].name));
strcpy(model->curves[currentCurve].name, ui->curveName->text().toLatin1());
updateItemModels();
emit modified();
}
}
void Curves::resizeEvent(QResizeEvent *event)
void CurvesPanel::resizeEvent(QResizeEvent *event)
{
QRect qr = ui->curvePreview->contentsRect();
ui->curvePreview->scene()->setSceneRect(GFX_MARGIN, GFX_MARGIN, qr.width() - GFX_MARGIN * 2, qr.height() - GFX_MARGIN * 2);
@ -534,7 +539,7 @@ void Curves::resizeEvent(QResizeEvent *event)
ModelPanel::resizeEvent(event);
}
void Curves::on_curveType_currentIndexChanged(int index)
void CurvesPanel::on_curveType_currentIndexChanged(int index)
{
unsigned int flags = templates[index].flags;
ui->curveCoeffLabel->setVisible(flags & CURVE_COEFF_ENABLE);
@ -548,7 +553,7 @@ void Curves::on_curveType_currentIndexChanged(int index)
ui->yMin->setValue(-100);
}
void Curves::addTemplate(QString name, unsigned int flags, curveFunction function)
void CurvesPanel::addTemplate(QString name, unsigned int flags, curveFunction function)
{
CurveCreatorTemplate tmpl;
tmpl.name = name;
@ -558,7 +563,7 @@ void Curves::addTemplate(QString name, unsigned int flags, curveFunction functio
ui->curveType->addItem(name);
}
void Curves::on_curveApply_clicked()
void CurvesPanel::on_curveApply_clicked()
{
int index = ui->curveType->currentIndex();
int numpoints = model->curves[currentCurve].count;
@ -595,14 +600,14 @@ void Curves::on_curveApply_clicked()
emit modified();
}
void Curves::onPointSizeEdited()
void CurvesPanel::onPointSizeEdited()
{
if (!lock) {
update();
}
}
void Curves::onNodeDelete()
void CurvesPanel::onNodeDelete()
{
int index = sender()->property("index").toInt();
int numpoints = model->curves[currentCurve].count;
@ -620,7 +625,7 @@ void Curves::onNodeDelete()
}
}
void Curves::onSceneNewPoint(int x, int y)
void CurvesPanel::onSceneNewPoint(int x, int y)
{
if ((model->curves[currentCurve].type == CurveData::CURVE_TYPE_CUSTOM) && (model->curves[currentCurve].count < CPN_MAX_POINTS)) {
int newidx = 0;
@ -651,7 +656,7 @@ void Curves::onSceneNewPoint(int x, int y)
}
}
void Curves::onCustomContextMenuRequested(QPoint pos)
void CurvesPanel::onCustomContextMenuRequested(QPoint pos)
{
QPushButton *button = (QPushButton *)sender();
selectedIndex = button->property("index").toInt();
@ -673,7 +678,7 @@ void Curves::onCustomContextMenuRequested(QPoint pos)
contextMenu.exec(globalPos);
}
bool Curves::hasClipboardData(QByteArray * data) const
bool CurvesPanel::hasClipboardData(QByteArray * data) const
{
const QClipboard * clipboard = QApplication::clipboard();
const QMimeData * mimeData = clipboard->mimeData();
@ -685,22 +690,22 @@ bool Curves::hasClipboardData(QByteArray * data) const
return false;
}
bool Curves::insertAllowed() const
bool CurvesPanel::insertAllowed() const
{
return ((selectedIndex < maxCurves - 1) && (model->curves[maxCurves - 1].isEmpty()));
}
bool Curves::moveDownAllowed() const
bool CurvesPanel::moveDownAllowed() const
{
return selectedIndex < maxCurves - 1;
}
bool Curves::moveUpAllowed() const
bool CurvesPanel::moveUpAllowed() const
{
return selectedIndex > 0;
}
void Curves::cmClear(bool prompt)
void CurvesPanel::cmClear(bool prompt)
{
if (prompt) {
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear Curve. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
@ -710,10 +715,11 @@ void Curves::cmClear(bool prompt)
model->curves[selectedIndex].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_CURVE, ModelData::REF_UPD_ACT_CLEAR, selectedIndex);
update();
updateItemModels();
emit modified();
}
void Curves::cmClearAll()
void CurvesPanel::cmClearAll()
{
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear all Curves. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
return;
@ -723,10 +729,11 @@ void Curves::cmClearAll()
model->updateAllReferences(ModelData::REF_UPD_TYPE_CURVE, ModelData::REF_UPD_ACT_CLEAR, i);
}
update();
updateItemModels();
emit modified();
}
void Curves::cmCopy()
void CurvesPanel::cmCopy()
{
QByteArray data;
data.append((char*)&model->curves[selectedIndex], sizeof(CurveData));
@ -735,7 +742,7 @@ void Curves::cmCopy()
QApplication::clipboard()->setMimeData(mimeData,QClipboard::Clipboard);
}
void Curves::cmCut()
void CurvesPanel::cmCut()
{
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Cut Curve. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
return;
@ -743,7 +750,7 @@ void Curves::cmCut()
cmClear(false);
}
void Curves::cmDelete()
void CurvesPanel::cmDelete()
{
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Delete Curve. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
return;
@ -752,40 +759,43 @@ void Curves::cmDelete()
model->curves[maxCurves - 1].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_CURVE, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, -1);
update();
updateItemModels();
emit modified();
}
void Curves::cmInsert()
void CurvesPanel::cmInsert()
{
memmove(&model->curves[selectedIndex + 1], &model->curves[selectedIndex], (CPN_MAX_CURVES - (selectedIndex + 1)) * sizeof(CurveData));
model->curves[selectedIndex].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_CURVE, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, 1);
update();
updateItemModels();
emit modified();
}
void Curves::cmMoveDown()
void CurvesPanel::cmMoveDown()
{
swapData(selectedIndex, selectedIndex + 1);
}
void Curves::cmMoveUp()
void CurvesPanel::cmMoveUp()
{
swapData(selectedIndex, selectedIndex - 1);
}
void Curves::cmPaste()
void CurvesPanel::cmPaste()
{
QByteArray data;
if (hasClipboardData(&data)) {
CurveData *cd = &model->curves[selectedIndex];
memcpy(cd, data.constData(), sizeof(CurveData));
update();
updateItemModels();
emit modified();
}
}
void Curves::swapData(int idx1, int idx2)
void CurvesPanel::swapData(int idx1, int idx2)
{
if ((idx1 != idx2) && (!model->curves[idx1].isEmpty() || !model->curves[idx2].isEmpty())) {
CurveData cdtmp = model->curves[idx2];
@ -795,10 +805,16 @@ void Curves::swapData(int idx1, int idx2)
memcpy(cd1, &cdtmp, sizeof(CurveData));
model->updateAllReferences(ModelData::REF_UPD_TYPE_CURVE, ModelData::REF_UPD_ACT_SWAP, idx1, idx2);
update();
updateItemModels();
emit modified();
}
}
void CurvesPanel::updateItemModels()
{
commonItemModels->update(CommonItemModels::RMO_CURVES);
}
CustomScene::CustomScene(QGraphicsView * view) :
QGraphicsScene(view)
{

View file

@ -26,6 +26,8 @@
#include <QGraphicsScene>
#include <QGraphicsView>
class CommonItemModels;
constexpr char MIMETYPE_CURVE[] = "application/x-companion-curve";
namespace Ui {
@ -54,13 +56,13 @@ class CustomScene : public QGraphicsScene
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent * event) override;
};
class Curves : public ModelPanel
class CurvesPanel : public ModelPanel
{
Q_OBJECT
public:
Curves(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware);
virtual ~Curves();
CurvesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels);
virtual ~CurvesPanel();
virtual void update();
@ -119,6 +121,8 @@ class Curves : public ModelPanel
bool moveDownAllowed() const;
bool moveUpAllowed() const;
void swapData(int idx1, int idx2);
CommonItemModels * commonItemModels;
void updateItemModels();
};
#endif // _CURVES_H_

View file

@ -41,7 +41,7 @@ RepeatComboBox::RepeatComboBox(QWidget *parent, int & repeatParam):
addItem(tr("No repeat"), 0);
for (unsigned int i=step; i<=60; i+=step) {
for (unsigned int i = step; i <= 60; i += step) {
addItem(tr("%1s").arg(i), i);
}
@ -66,24 +66,36 @@ void RepeatComboBox::update()
setCurrentIndex(value);
}
CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, GeneralSettings & generalSettings, Firmware * firmware):
CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels):
GenericPanel(parent, model, generalSettings, firmware),
functions(model ? model->customFn : generalSettings.customFn),
commonItemModels(commonItemModels),
mediaPlayerCurrent(-1),
mediaPlayer(nullptr)
mediaPlayer(nullptr),
modelsUpdateCnt(0)
{
Stopwatch s1("CustomFunctionsPanel - populate");
lock = true;
fswCapability = model ? firmware->getCapability(CustomFunctions) : firmware->getCapability(GlobalFunctions);
rawSwitchItemModel = new RawSwitchFilterItemModel(&generalSettings, model, model ? RawSwitch::SpecialFunctionsContext : RawSwitch::GlobalFunctionsContext, this);
rawSrcAllItemModel = new RawSourceFilterItemModel(&generalSettings, model, this);
rawSrcInputsItemModel = new RawSourceFilterItemModel(rawSrcAllItemModel->sourceModel(), RawSource::InputSourceGroups, this);
rawSrcGVarsItemModel = new RawSourceFilterItemModel(rawSrcAllItemModel->sourceModel(), RawSource::GVarsGroup, this);
rawSwitchFilteredModel = new RawItemFilteredModel(commonItemModels->rawSwitchItemModel(), model ? RawSwitch::SpecialFunctionsContext : RawSwitch::GlobalFunctionsContext, this);
connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &CustomFunctionsPanel::onModelDataAboutToBeUpdated);
connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &CustomFunctionsPanel::onModelDataUpdateComplete);
rawSourceAllModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), this);
connect(rawSourceAllModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &CustomFunctionsPanel::onModelDataAboutToBeUpdated);
connect(rawSourceAllModel, &RawItemFilteredModel::dataUpdateComplete, this, &CustomFunctionsPanel::onModelDataUpdateComplete);
rawSourceInputsModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), RawSource::InputSourceGroups, this);
connect(rawSourceInputsModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &CustomFunctionsPanel::onModelDataAboutToBeUpdated);
connect(rawSourceInputsModel, &RawItemFilteredModel::dataUpdateComplete, this, &CustomFunctionsPanel::onModelDataUpdateComplete);
rawSourceGVarsModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), RawSource::GVarsGroup, this);
connect(rawSourceGVarsModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &CustomFunctionsPanel::onModelDataAboutToBeUpdated);
connect(rawSourceGVarsModel, &RawItemFilteredModel::dataUpdateComplete, this, &CustomFunctionsPanel::onModelDataUpdateComplete);
if (!firmware->getCapability(VoicesAsNumbers)) {
tracksSet = getFilesSet(getSoundsPath(generalSettings), QStringList() << "*.wav" << "*.WAV", firmware->getCapability(VoicesMaxLength));
for (int i=0; i<fswCapability; i++) {
for (int i = 0; i < fswCapability; i++) {
if (functions[i].func == FuncPlayPrompt || functions[i].func == FuncBackgroundMusic) {
QString temp = functions[i].paramarm;
if (!temp.isEmpty()) {
@ -93,11 +105,9 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model,
}
}
s1.report("get tracks");
if (IS_STM32(firmware->getBoard())) {
scriptsSet = getFilesSet(g.profile[g.id()].sdPath() + "/SCRIPTS/FUNCTIONS", QStringList() << "*.lua", firmware->getCapability(VoicesMaxLength));
for (int i=0; i<fswCapability; i++) {
for (int i = 0; i < fswCapability; i++) {
if (functions[i].func == FuncPlayScript) {
QString temp = functions[i].paramarm;
if (!temp.isEmpty()) {
@ -106,7 +116,6 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model,
}
}
}
s1.report("get scripts");
CompanionIcon playIcon("play.png");
playIcon.addImage("stop.png", QIcon::Normal, QIcon::On);
@ -115,7 +124,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model,
headerLabels << "#" << tr("Switch") << tr("Action") << tr("Parameters") << tr("Enable");
TableLayout * tableLayout = new TableLayout(this, fswCapability, headerLabels);
for (int i=0; i<fswCapability; i++) {
for (int i = 0; i < fswCapability; i++) {
// The label
QLabel * label = new QLabel(this);
label->setContextMenuPolicy(Qt::CustomContextMenu);
@ -123,9 +132,9 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model,
label->setMouseTracking(true);
label->setProperty("index", i);
if (model)
label->setText(tr("SF%1").arg(i+1));
label->setText(tr("SF%1").arg(i + 1));
else
label->setText(tr("GF%1").arg(i+1));
label->setText(tr("GF%1").arg(i + 1));
label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
connect(label, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onCustomContextMenuRequested(QPoint)));
tableLayout->addWidget(i, 0, label);
@ -133,7 +142,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model,
// The switch
fswtchSwtch[i] = new QComboBox(this);
fswtchSwtch[i]->setModel(rawSwitchItemModel);
fswtchSwtch[i]->setModel(rawSwitchFilteredModel);
fswtchSwtch[i]->setCurrentIndex(fswtchSwtch[i]->findData(functions[i].swtch.toValue()));
fswtchSwtch[i]->setProperty("index", i);
fswtchSwtch[i]->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Minimum);
@ -198,7 +207,6 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model,
fswtchParamArmT[i]->setEditable(true);
fswtchParamArmT[i]->setSizeAdjustPolicy(QComboBox::AdjustToContents);
paramLayout->addWidget(fswtchParamArmT[i]);
connect(fswtchParamArmT[i], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited()));
connect(fswtchParamArmT[i], SIGNAL(editTextChanged ( const QString)), this, SLOT(customFunctionEdited()));
@ -221,31 +229,24 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model,
QHBoxLayout * repeatLayout = new QHBoxLayout();
tableLayout->addLayout(i, 4, repeatLayout);
fswtchRepeat[i] = new RepeatComboBox(this, functions[i].repeatParam);
repeatLayout->addWidget(fswtchRepeat[i], i+1);
connect(fswtchRepeat[i], SIGNAL(modified()), this, SLOT(onChildModified()));
repeatLayout->addWidget(fswtchRepeat[i], i + 1);
connect(fswtchRepeat[i], SIGNAL(modified()), this, SLOT(onRepeatModified()));
fswtchEnable[i] = new QCheckBox(this);
fswtchEnable[i]->setProperty("index", i);
fswtchEnable[i]->setText(tr("ON"));
fswtchEnable[i]->setFixedWidth(200);
repeatLayout->addWidget(fswtchEnable[i], i+1);
repeatLayout->addWidget(fswtchEnable[i], i + 1);
connect(fswtchEnable[i], SIGNAL(stateChanged(int)), this, SLOT(customFunctionEdited()));
}
s1.report("add items");
disableMouseScrolling();
s1.report("disableMouseScrolling");
lock = false;
tableLayout->resizeColumnsToContents();
tableLayout->setColumnWidth(3, 300);
tableLayout->pushRowsUp(fswCapability + 1);
update();
s1.report("update");
tableLayout->resizeColumnsToContents();
s1.report("resizeColumnsToContents");
tableLayout->setColumnWidth(3, 300);
tableLayout->pushRowsUp(fswCapability+1);
s1.report("end");
lock = false;
}
CustomFunctionsPanel::~CustomFunctionsPanel()
@ -254,15 +255,6 @@ CustomFunctionsPanel::~CustomFunctionsPanel()
stopSound(mediaPlayerCurrent);
}
void CustomFunctionsPanel::updateDataModels()
{
const bool oldLock = lock;
lock = true;
rawSwitchItemModel->update();
rawSrcAllItemModel->update();
lock = oldLock;
}
void CustomFunctionsPanel::onMediaPlayerStateChanged(QMediaPlayer::State state)
{
if (state != QMediaPlayer::PlayingState)
@ -343,6 +335,7 @@ void CustomFunctionsPanel::toggleSound(bool play)
#define CUSTOM_FUNCTION_BL_COLOR (1<<9)
#define CUSTOM_FUNCTION_SHOW_FUNC (1<<10)
void CustomFunctionsPanel::customFunctionEdited()
{
if (!lock) {
@ -369,162 +362,155 @@ void CustomFunctionsPanel::functionEdited()
}
}
void CustomFunctionsPanel::onChildModified()
void CustomFunctionsPanel::onRepeatModified()
{
emit modified();
}
void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
{
CustomFunctionData & cfn = functions[i];
AssignFunc func = (AssignFunc)fswtchFunc[i]->currentData().toInt();
CustomFunctionData & cfn = functions[i];
AssignFunc func = (AssignFunc)fswtchFunc[i]->currentData().toInt();
unsigned int widgetsMask = 0;
if (modified) {
cfn.swtch = RawSwitch(fswtchSwtch[i]->currentData().toInt());
cfn.func = func;
cfn.enabled = fswtchEnable[i]->isChecked();
}
unsigned int widgetsMask = 0;
if (modified) {
cfn.swtch = RawSwitch(fswtchSwtch[i]->currentData().toInt());
cfn.func = func;
cfn.enabled = fswtchEnable[i]->isChecked();
}
else {
fswtchSwtch[i]->setCurrentIndex(fswtchSwtch[i]->findData(cfn.swtch.toValue()));
fswtchFunc[i]->setCurrentIndex(fswtchFunc[i]->findData(cfn.func));
}
if (!cfn.isEmpty()) {
widgetsMask |= CUSTOM_FUNCTION_SHOW_FUNC;
if (!cfn.isEmpty()) {
widgetsMask |= CUSTOM_FUNCTION_SHOW_FUNC;
if (func >= FuncOverrideCH1 && func <= FuncOverrideCH32) {
if (model) {
int channelsMax = model->getChannelsMax(true);
fswtchParam[i]->setDecimals(0);
fswtchParam[i]->setSingleStep(1);
fswtchParam[i]->setMinimum(-channelsMax);
fswtchParam[i]->setMaximum(channelsMax);
if (modified) {
cfn.param = fswtchParam[i]->value();
}
fswtchParam[i]->setValue(cfn.param);
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM | CUSTOM_FUNCTION_ENABLE;
if (func >= FuncOverrideCH1 && func <= FuncOverrideCH32) {
if (model) {
int channelsMax = model->getChannelsMax(true);
fswtchParam[i]->setDecimals(0);
fswtchParam[i]->setSingleStep(1);
fswtchParam[i]->setMinimum(-channelsMax);
fswtchParam[i]->setMaximum(channelsMax);
if (modified) {
cfn.param = fswtchParam[i]->value();
}
fswtchParam[i]->setValue(cfn.param);
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM | CUSTOM_FUNCTION_ENABLE;
}
else if (func == FuncLogs) {
fswtchParam[i]->setDecimals(1);
fswtchParam[i]->setMinimum(0);
fswtchParam[i]->setMaximum(25.5);
fswtchParam[i]->setSingleStep(0.1);
}
else if (func == FuncLogs) {
fswtchParam[i]->setDecimals(1);
fswtchParam[i]->setMinimum(0);
fswtchParam[i]->setMaximum(25.5);
fswtchParam[i]->setSingleStep(0.1);
if (modified)
cfn.param = fswtchParam[i]->value() * 10.0;
fswtchParam[i]->setValue(cfn.param / 10.0);
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM;
}
else if (func >= FuncAdjustGV1 && func <= FuncAdjustGVLast) {
int gvidx = func - FuncAdjustGV1;
if (modified)
cfn.adjustMode = fswtchGVmode[i]->currentIndex();
fswtchGVmode[i]->setCurrentIndex(cfn.adjustMode);
widgetsMask |= CUSTOM_FUNCTION_GV_MODE | CUSTOM_FUNCTION_ENABLE;
if (cfn.adjustMode == FUNC_ADJUST_GVAR_CONSTANT || cfn.adjustMode == FUNC_ADJUST_GVAR_INCDEC) {
if (modified)
cfn.param = fswtchParam[i]->value()*10.0;
fswtchParam[i]->setValue(cfn.param/10.0);
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM;
}
else if (func >= FuncAdjustGV1 && func <= FuncAdjustGVLast) {
int gvidx = func - FuncAdjustGV1;
if (modified)
cfn.adjustMode = fswtchGVmode[i]->currentIndex();
fswtchGVmode[i]->setCurrentIndex(cfn.adjustMode);
widgetsMask |= CUSTOM_FUNCTION_GV_MODE | CUSTOM_FUNCTION_ENABLE;
if (cfn.adjustMode == FUNC_ADJUST_GVAR_CONSTANT || cfn.adjustMode == FUNC_ADJUST_GVAR_INCDEC) {
if (modified)
cfn.param = fswtchParam[i]->value() * model->gvarData[gvidx].multiplierSet();
fswtchParam[i]->setDecimals(model->gvarData[gvidx].prec);
fswtchParam[i]->setSingleStep(model->gvarData[gvidx].multiplierGet());
fswtchParam[i]->setSuffix(model->gvarData[gvidx].unitToString());
if (cfn.adjustMode==FUNC_ADJUST_GVAR_INCDEC) {
double rng = abs(model->gvarData[gvidx].getMax() - model->gvarData[gvidx].getMin());
rng *= model->gvarData[gvidx].multiplierGet();
fswtchParam[i]->setMinimum(-rng);
fswtchParam[i]->setMaximum(rng);
}
else {
fswtchParam[i]->setMinimum(model->gvarData[gvidx].getMinPrec());
fswtchParam[i]->setMaximum(model->gvarData[gvidx].getMaxPrec());
}
fswtchParam[i]->setValue(cfn.param * model->gvarData[gvidx].multiplierGet());
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM;
cfn.param = fswtchParam[i]->value() * model->gvarData[gvidx].multiplierSet();
fswtchParam[i]->setDecimals(model->gvarData[gvidx].prec);
fswtchParam[i]->setSingleStep(model->gvarData[gvidx].multiplierGet());
fswtchParam[i]->setSuffix(model->gvarData[gvidx].unitToString());
if (cfn.adjustMode == FUNC_ADJUST_GVAR_INCDEC) {
double rng = abs(model->gvarData[gvidx].getMax() - model->gvarData[gvidx].getMin());
rng *= model->gvarData[gvidx].multiplierGet();
fswtchParam[i]->setMinimum(-rng);
fswtchParam[i]->setMaximum(rng);
}
else {
if (modified)
cfn.param = fswtchParamT[i]->currentData().toInt();
populateFuncParamCB(fswtchParamT[i], func, cfn.param, cfn.adjustMode);
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM;
fswtchParam[i]->setMinimum(model->gvarData[gvidx].getMinPrec());
fswtchParam[i]->setMaximum(model->gvarData[gvidx].getMaxPrec());
}
fswtchParam[i]->setValue(cfn.param * model->gvarData[gvidx].multiplierGet());
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM;
}
else if (func == FuncReset) {
else {
if (modified)
cfn.param = fswtchParamT[i]->currentData().toInt();
populateFuncParamCB(fswtchParamT[i], func, cfn.param, cfn.adjustMode);
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM;
}
}
else if (func == FuncReset) {
if (modified)
cfn.param = fswtchParamT[i]->currentData().toInt();
populateFuncParamCB(fswtchParamT[i], func, cfn.param);
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM | CUSTOM_FUNCTION_ENABLE;
}
else if (func >= FuncSetTimer1 && func <= FuncSetTimer3) {
if (modified)
cfn.param = fswtchParamTime[i]->timeInSeconds();
RawSourceRange range = RawSource(SOURCE_TYPE_SPECIAL, func - FuncSetTimer1 + 2).getRange(model, generalSettings);
fswtchParamTime[i]->setTimeRange((int)range.min, (int)range.max);
fswtchParamTime[i]->setTime(cfn.param);
widgetsMask |= CUSTOM_FUNCTION_TIME_PARAM | CUSTOM_FUNCTION_ENABLE;
}
else if (func >= FuncSetFailsafeInternalModule && func <= FuncBindExternalModule) {
widgetsMask |= CUSTOM_FUNCTION_ENABLE;
}
else if (func == FuncVolume || func == FuncBacklight) {
if (modified)
cfn.param = fswtchParamT[i]->currentData().toInt();
populateFuncParamCB(fswtchParamT[i], func, cfn.param);
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM | CUSTOM_FUNCTION_ENABLE;
}
else if (func == FuncPlaySound || func == FuncPlayHaptic || func == FuncPlayValue || func == FuncPlayPrompt || func == FuncPlayBoth || func == FuncBackgroundMusic) {
if (func != FuncBackgroundMusic) {
widgetsMask |= CUSTOM_FUNCTION_REPEAT;
fswtchRepeat[i]->update();
}
if (func == FuncPlayValue) {
if (modified)
cfn.param = fswtchParamT[i]->currentData().toInt();
populateFuncParamCB(fswtchParamT[i], func, cfn.param);
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM | CUSTOM_FUNCTION_ENABLE;
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM | CUSTOM_FUNCTION_REPEAT;
}
else if (func >= FuncSetTimer1 && func <= FuncSetTimer3) {
if (modified)
cfn.param = fswtchParamTime[i]->timeInSeconds();
RawSourceRange range = RawSource(SOURCE_TYPE_SPECIAL, func - FuncSetTimer1 + 2).getRange(model, generalSettings);
fswtchParamTime[i]->setTimeRange((int)range.min, (int)range.max);
fswtchParamTime[i]->setTime(cfn.param);
widgetsMask |= CUSTOM_FUNCTION_TIME_PARAM | CUSTOM_FUNCTION_ENABLE;
}
else if (func >= FuncSetFailsafeInternalModule && func <= FuncBindExternalModule) {
widgetsMask |= CUSTOM_FUNCTION_ENABLE;
}
else if (func == FuncVolume || func == FuncBacklight) {
if (modified)
cfn.param = fswtchParamT[i]->currentData().toInt();
populateFuncParamCB(fswtchParamT[i], func, cfn.param);
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM | CUSTOM_FUNCTION_ENABLE;
}
else if (func == FuncPlaySound || func == FuncPlayHaptic || func == FuncPlayValue || func == FuncPlayPrompt || func == FuncPlayBoth || func == FuncBackgroundMusic) {
if (func != FuncBackgroundMusic) {
widgetsMask |= CUSTOM_FUNCTION_REPEAT;
fswtchRepeat[i]->update();
}
if (func == FuncPlayValue) {
if (modified)
cfn.param = fswtchParamT[i]->currentData().toInt();
populateFuncParamCB(fswtchParamT[i], func, cfn.param);
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM | CUSTOM_FUNCTION_REPEAT;
}
else if (func == FuncPlayPrompt || func == FuncPlayBoth) {
if (firmware->getCapability(VoicesAsNumbers)) {
fswtchParam[i]->setDecimals(0);
fswtchParam[i]->setSingleStep(1);
fswtchParam[i]->setMinimum(0);
if (func == FuncPlayPrompt) {
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM | CUSTOM_FUNCTION_REPEAT | CUSTOM_FUNCTION_GV_TOOGLE;
}
else {
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM | CUSTOM_FUNCTION_REPEAT;
fswtchParamGV[i]->setChecked(false);
}
fswtchParam[i]->setMaximum(func == FuncPlayBoth ? 254 : 255);
if (modified) {
if (fswtchParamGV[i]->isChecked()) {
fswtchParam[i]->setMinimum(1);
cfn.param = std::min(fswtchParam[i]->value(),5.0)+(fswtchParamGV[i]->isChecked() ? 250 : 0);
}
else {
cfn.param = fswtchParam[i]->value();
}
}
if (cfn.param>250 && (func!=FuncPlayBoth)) {
fswtchParamGV[i]->setChecked(true);
fswtchParam[i]->setValue(cfn.param-250);
fswtchParam[i]->setMaximum(5);
}
else {
fswtchParamGV[i]->setChecked(false);
fswtchParam[i]->setValue(cfn.param);
}
if (cfn.param < 251)
widgetsMask |= CUSTOM_FUNCTION_PLAY;
else if (func == FuncPlayPrompt || func == FuncPlayBoth) {
if (firmware->getCapability(VoicesAsNumbers)) {
fswtchParam[i]->setDecimals(0);
fswtchParam[i]->setSingleStep(1);
fswtchParam[i]->setMinimum(0);
if (func == FuncPlayPrompt) {
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM | CUSTOM_FUNCTION_REPEAT | CUSTOM_FUNCTION_GV_TOOGLE;
}
else {
widgetsMask |= CUSTOM_FUNCTION_FILE_PARAM;
if (modified) {
Helpers::getFileComboBoxValue(fswtchParamArmT[i], cfn.paramarm, firmware->getCapability(VoicesMaxLength));
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM | CUSTOM_FUNCTION_REPEAT;
fswtchParamGV[i]->setChecked(false);
}
fswtchParam[i]->setMaximum(func == FuncPlayBoth ? 254 : 255);
if (modified) {
if (fswtchParamGV[i]->isChecked()) {
fswtchParam[i]->setMinimum(1);
cfn.param = std::min(fswtchParam[i]->value(),5.0)+(fswtchParamGV[i]->isChecked() ? 250 : 0);
}
Helpers::populateFileComboBox(fswtchParamArmT[i], tracksSet, cfn.paramarm);
if (fswtchParamArmT[i]->currentText() != "----") {
widgetsMask |= CUSTOM_FUNCTION_PLAY;
else {
cfn.param = fswtchParam[i]->value();
}
}
if (cfn.param > 250 && (func != FuncPlayBoth)) {
fswtchParamGV[i]->setChecked(true);
fswtchParam[i]->setValue(cfn.param - 250);
fswtchParam[i]->setMaximum(5);
}
else {
fswtchParamGV[i]->setChecked(false);
fswtchParam[i]->setValue(cfn.param);
}
if (cfn.param < 251)
widgetsMask |= CUSTOM_FUNCTION_PLAY;
}
else if (func == FuncBackgroundMusic) {
else {
widgetsMask |= CUSTOM_FUNCTION_FILE_PARAM;
if (modified) {
Helpers::getFileComboBoxValue(fswtchParamArmT[i], cfn.paramarm, firmware->getCapability(VoicesMaxLength));
@ -534,58 +520,68 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
widgetsMask |= CUSTOM_FUNCTION_PLAY;
}
}
else if (func == FuncPlaySound) {
if (modified)
cfn.param = (uint8_t)fswtchParamT[i]->currentIndex();
populateFuncParamCB(fswtchParamT[i], func, cfn.param);
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM;
}
else if (func == FuncPlayHaptic) {
if (modified)
cfn.param = (uint8_t)fswtchParamT[i]->currentIndex();
populateFuncParamCB(fswtchParamT[i], func, cfn.param);
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM;
}
}
else if (func == FuncPlayScript) {
else if (func == FuncBackgroundMusic) {
widgetsMask |= CUSTOM_FUNCTION_FILE_PARAM;
if (modified) {
Helpers::getFileComboBoxValue(fswtchParamArmT[i], cfn.paramarm, 8);
Helpers::getFileComboBoxValue(fswtchParamArmT[i], cfn.paramarm, firmware->getCapability(VoicesMaxLength));
}
Helpers::populateFileComboBox(fswtchParamArmT[i], tracksSet, cfn.paramarm);
if (fswtchParamArmT[i]->currentText() != "----") {
widgetsMask |= CUSTOM_FUNCTION_PLAY;
}
Helpers::populateFileComboBox(fswtchParamArmT[i], scriptsSet, cfn.paramarm);
}
else {
else if (func == FuncPlaySound) {
if (modified)
cfn.param = fswtchParam[i]->value();
fswtchParam[i]->setDecimals(0);
fswtchParam[i]->setSingleStep(1);
fswtchParam[i]->setValue(cfn.param);
if (func <= FuncInstantTrim) {
widgetsMask |= CUSTOM_FUNCTION_ENABLE;
}
cfn.param = (uint8_t)fswtchParamT[i]->currentIndex();
populateFuncParamCB(fswtchParamT[i], func, cfn.param);
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM;
}
else if (func == FuncPlayHaptic) {
if (modified)
cfn.param = (uint8_t)fswtchParamT[i]->currentIndex();
populateFuncParamCB(fswtchParamT[i], func, cfn.param);
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM;
}
}
else if (func == FuncPlayScript) {
widgetsMask |= CUSTOM_FUNCTION_FILE_PARAM;
if (modified) {
Helpers::getFileComboBoxValue(fswtchParamArmT[i], cfn.paramarm, 8);
}
Helpers::populateFileComboBox(fswtchParamArmT[i], scriptsSet, cfn.paramarm);
}
else {
if (modified)
cfn.param = fswtchParam[i]->value();
fswtchParam[i]->setDecimals(0);
fswtchParam[i]->setSingleStep(1);
fswtchParam[i]->setValue(cfn.param);
if (func <= FuncInstantTrim) {
widgetsMask |= CUSTOM_FUNCTION_ENABLE;
}
}
}
fswtchFunc[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_SHOW_FUNC);
fswtchParam[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_NUMERIC_PARAM);
fswtchParamTime[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_TIME_PARAM);
fswtchParamGV[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_GV_TOOGLE);
fswtchParamT[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_SOURCE_PARAM);
fswtchParamArmT[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_FILE_PARAM);
fswtchEnable[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_ENABLE);
if (widgetsMask & CUSTOM_FUNCTION_ENABLE)
fswtchEnable[i]->setChecked(cfn.enabled);
else
fswtchEnable[i]->setChecked(false);
fswtchRepeat[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_REPEAT);
fswtchGVmode[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_GV_MODE);
fswtchBLcolor[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_BL_COLOR);
playBT[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_PLAY);
fswtchFunc[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_SHOW_FUNC);
fswtchParam[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_NUMERIC_PARAM);
fswtchParamTime[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_TIME_PARAM);
fswtchParamGV[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_GV_TOOGLE);
fswtchParamT[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_SOURCE_PARAM);
fswtchParamArmT[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_FILE_PARAM);
fswtchEnable[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_ENABLE);
if (widgetsMask & CUSTOM_FUNCTION_ENABLE)
fswtchEnable[i]->setChecked(cfn.enabled);
else
fswtchEnable[i]->setChecked(false);
fswtchRepeat[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_REPEAT);
fswtchGVmode[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_GV_MODE);
fswtchBLcolor[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_BL_COLOR);
playBT[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_PLAY);
}
void CustomFunctionsPanel::update()
{
updateDataModels();
lock = true;
for (int i = 0; i < fswCapability; i++) {
refreshCustomFunction(i);
@ -660,16 +656,16 @@ void CustomFunctionsPanel::populateFuncCB(QComboBox *b, unsigned int value)
{
b->clear();
for (unsigned int i = 0; i < FuncCount; i++) {
if (((i>=FuncOverrideCH1 && i<=FuncOverrideCH32) && (!model || !firmware->getCapability(SafetyChannelCustomFunction))) ||
((i==FuncVolume || i==FuncBackgroundMusic || i==FuncBackgroundMusicPause) && !firmware->getCapability(HasVolume)) ||
((i==FuncPlayScript && !IS_HORUS_OR_TARANIS(firmware->getBoard()))) ||
((i==FuncPlayHaptic) && !firmware->getCapability(Haptic)) ||
((i==FuncPlayBoth) && !firmware->getCapability(HasBeeper)) ||
((i==FuncLogs) && !firmware->getCapability(HasSDLogs)) ||
((i==FuncSetTimer3) && firmware->getCapability(Timers) < 3) ||
((i==FuncScreenshot) && !IS_HORUS_OR_TARANIS(firmware->getBoard())) ||
((i>=FuncRangeCheckInternalModule && i<=FuncBindExternalModule) && (!model || !firmware->getCapability(DangerousFunctions))) ||
((i>=FuncAdjustGV1 && i<=FuncAdjustGVLast) && (!model || !firmware->getCapability(Gvars)))
if (((i >= FuncOverrideCH1 && i <= FuncOverrideCH32) && (!model || !firmware->getCapability(SafetyChannelCustomFunction))) ||
((i == FuncVolume || i == FuncBackgroundMusic || i == FuncBackgroundMusicPause) && !firmware->getCapability(HasVolume)) ||
((i == FuncPlayScript && !IS_HORUS_OR_TARANIS(firmware->getBoard()))) ||
((i == FuncPlayHaptic) && !firmware->getCapability(Haptic)) ||
((i == FuncPlayBoth) && !firmware->getCapability(HasBeeper)) ||
((i == FuncLogs) && !firmware->getCapability(HasSDLogs)) ||
((i == FuncSetTimer3) && firmware->getCapability(Timers) < 3) ||
((i == FuncScreenshot) && !IS_HORUS_OR_TARANIS(firmware->getBoard())) ||
((i >= FuncRangeCheckInternalModule && i <= FuncBindExternalModule) && (!model || !firmware->getCapability(DangerousFunctions))) ||
((i >= FuncAdjustGV1 && i <= FuncAdjustGVLast) && (!model || !firmware->getCapability(Gvars)))
) {
// skipped
continue;
@ -711,21 +707,21 @@ void CustomFunctionsPanel::populateFuncParamCB(QComboBox *b, uint function, unsi
CustomFunctionData::populateResetParams(model, b, value);
}
else if (function == FuncVolume || function == FuncBacklight) {
b->setModel(rawSrcInputsItemModel);
b->setModel(rawSourceInputsModel);
b->setCurrentIndex(b->findData(value));
}
else if (function == FuncPlayValue) {
b->setModel(rawSrcAllItemModel);
b->setModel(rawSourceAllModel);
b->setCurrentIndex(b->findData(value));
}
else if (function >= FuncAdjustGV1 && function <= FuncAdjustGVLast) {
switch (adjustmode) {
case 1:
b->setModel(rawSrcInputsItemModel);
b->setModel(rawSourceInputsModel);
b->setCurrentIndex(b->findData(value));
break;
case 2:
b->setModel(rawSrcGVarsItemModel);
b->setModel(rawSourceGVarsModel);
b->setCurrentIndex(b->findData(value));
break;
}
@ -830,3 +826,23 @@ bool CustomFunctionsPanel::moveUpAllowed() const
{
return selectedIndex > 0;
}
void CustomFunctionsPanel::onModelDataAboutToBeUpdated()
{
lock = true;
modelsUpdateCnt++;
}
void CustomFunctionsPanel::onModelDataUpdateComplete()
{
modelsUpdateCnt--;
if (modelsUpdateCnt < 1) {
lock = true;
for (int i = 0; i < fswCapability; i++) {
fswtchSwtch[i]->setCurrentIndex(fswtchSwtch[i]->findData(functions[i].swtch.toValue()));
fswtchFunc[i]->setCurrentIndex(fswtchFunc[i]->findData(functions[i].func));
}
update();
lock = false;
}
}

View file

@ -26,8 +26,8 @@
#include <QMediaPlayer>
class RawSourceFilterItemModel;
class RawSwitchFilterItemModel;
class CommonItemModels;
class RawItemFilteredModel;
class TimerEdit;
constexpr char MIMETYPE_CUSTOM_FUNCTION[] = "application/x-companion-custom-function";
@ -55,7 +55,7 @@ class CustomFunctionsPanel : public GenericPanel
Q_OBJECT
public:
CustomFunctionsPanel(QWidget *parent, ModelData * model, GeneralSettings & generalSettings, Firmware * firmware);
CustomFunctionsPanel(QWidget *parent, ModelData * model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels);
~CustomFunctionsPanel();
virtual void update();
@ -64,12 +64,11 @@ class CustomFunctionsPanel : public GenericPanel
CustomFunctionData * functions;
private slots:
void updateDataModels();
void customFunctionEdited();
void functionEdited();
void onCustomContextMenuRequested(QPoint pos);
void refreshCustomFunction(int index, bool modified=false);
void onChildModified();
void onRepeatModified();
bool playSound(int index);
void stopSound(int index);
void toggleSound(bool play);
@ -84,6 +83,8 @@ class CustomFunctionsPanel : public GenericPanel
void cmInsert();
void cmClear(bool prompt = true);
void cmClearAll();
void onModelDataAboutToBeUpdated();
void onModelDataUpdateComplete();
private:
void populateFuncCB(QComboBox *b, unsigned int value);
@ -95,10 +96,11 @@ class CustomFunctionsPanel : public GenericPanel
bool moveUpAllowed() const;
void swapData(int idx1, int idx2);
void resetCBsAndRefresh(int idx);
RawSwitchFilterItemModel * rawSwitchItemModel;
RawSourceFilterItemModel * rawSrcAllItemModel;
RawSourceFilterItemModel * rawSrcInputsItemModel;
RawSourceFilterItemModel * rawSrcGVarsItemModel;
CommonItemModels * commonItemModels;
RawItemFilteredModel * rawSwitchFilteredModel;
RawItemFilteredModel * rawSourceAllModel;
RawItemFilteredModel * rawSourceInputsModel;
RawItemFilteredModel * rawSourceGVarsModel;
QSet<QString> tracksSet;
QSet<QString> scriptsSet;
@ -119,7 +121,7 @@ class CustomFunctionsPanel : public GenericPanel
int selectedIndex;
int fswCapability;
int modelsUpdateCnt;
};
#endif // _CUSTOMFUNCTIONS_H_

View file

@ -24,7 +24,8 @@
#include "helpers.h"
ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, GeneralSettings & generalSettings,
Firmware * firmware, QString & inputName) :
Firmware * firmware, QString & inputName, RawItemFilteredModel * rawSourceModel,
RawItemFilteredModel * rawSwitchModel) :
QDialog(parent),
ui(new Ui::ExpoDialog),
model(model),
@ -36,9 +37,10 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G
lock(false)
{
ui->setupUi(this);
QLabel * lb_fp[CPN_MAX_FLIGHT_MODES] = {ui->lb_FP0,ui->lb_FP1,ui->lb_FP2,ui->lb_FP3,ui->lb_FP4,ui->lb_FP5,ui->lb_FP6,ui->lb_FP7,ui->lb_FP8 };
QCheckBox * tmp[CPN_MAX_FLIGHT_MODES] = {ui->cb_FP0,ui->cb_FP1,ui->cb_FP2,ui->cb_FP3,ui->cb_FP4,ui->cb_FP5,ui->cb_FP6,ui->cb_FP7,ui->cb_FP8 };
for (int i=0; i<CPN_MAX_FLIGHT_MODES; i++) {
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++) {
cb_fp[i] = tmp[i];
}
@ -52,14 +54,14 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G
curveGroup = new CurveGroup(ui->curveTypeCB, ui->curveGVarCB, ui->curveValueCB, ui->curveValueSB, ed->curve, model,
firmware->getCapability(HasInputDiff) ? 0 : (HIDE_DIFF | HIDE_NEGATIVE_CURVES));
ui->switchesCB->setModel(new RawSwitchFilterItemModel(&generalSettings, &model, RawSwitch::MixesContext, this));
ui->switchesCB->setModel(rawSwitchModel);
ui->switchesCB->setCurrentIndex(ui->switchesCB->findData(ed->swtch.toValue()));
ui->sideCB->setCurrentIndex(ed->mode-1);
ui->sideCB->setCurrentIndex(ed->mode - 1);
if (!firmware->getCapability(FlightModes)) {
ui->label_phases->hide();
for (int i=0; i<CPN_MAX_FLIGHT_MODES; i++) {
for (int i = 0; i < CPN_MAX_FLIGHT_MODES; i++) {
lb_fp[i]->hide();
cb_fp[i]->hide();
}
@ -69,13 +71,13 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G
ui->label_phases->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->label_phases, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(label_phases_customContextMenuRequested(const QPoint &)));
int mask = 1;
for (int i=0; i<CPN_MAX_FLIGHT_MODES; i++) {
for (int i = 0; i < CPN_MAX_FLIGHT_MODES; i++) {
if ((ed->flightModes & mask) == 0) {
cb_fp[i]->setChecked(true);
}
mask <<= 1;
}
for (int i=firmware->getCapability(FlightModes); i<CPN_MAX_FLIGHT_MODES; i++) {
for (int i = firmware->getCapability(FlightModes); i < CPN_MAX_FLIGHT_MODES; i++) {
lb_fp[i]->hide();
cb_fp[i]->hide();
}
@ -83,9 +85,8 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G
if (firmware->getCapability(VirtualInputs)) {
ui->inputName->setMaxLength(firmware->getCapability(InputsLength));
ui->sourceCB->setModel(new RawSourceFilterItemModel(&generalSettings, &model, (RawSource::InputSourceGroups & ~RawSource::InputsGroup) | RawSource::TelemGroup, this));
ui->sourceCB->setModel(rawSourceModel);
ui->sourceCB->setCurrentIndex(ui->sourceCB->findData(ed->srcRaw.toValue()));
ui->sourceCB->removeItem(0);
ui->inputName->setValidator(new QRegExpValidator(rx, this));
ui->inputName->setText(inputName);
}
@ -98,8 +99,8 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G
ui->trimCB->hide();
}
for(int i=0; i < getBoardCapability(getCurrentBoard(), Board::NumTrims); i++) {
ui->trimCB->addItem(RawSource(SOURCE_TYPE_TRIM, i).toString(), i+1);
for(int i = 0; i < getBoardCapability(getCurrentBoard(), Board::NumTrims); i++) {
ui->trimCB->addItem(RawSource(SOURCE_TYPE_TRIM, i).toString(), i + 1);
}
ui->trimCB->setCurrentIndex(1 - ed->carryTrim);
@ -124,7 +125,7 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G
connect(ui->trimCB, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesChanged()));
connect(ui->switchesCB, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesChanged()));
connect(ui->sideCB, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesChanged()));
for (int i=0; i<CPN_MAX_FLIGHT_MODES; i++) {
for (int i = 0; i < CPN_MAX_FLIGHT_MODES; i++) {
connect(cb_fp[i], SIGNAL(toggled(bool)), this, SLOT(valuesChanged()));
}
if (firmware->getCapability(VirtualInputs)) {
@ -181,7 +182,7 @@ void ExpoDialog::valuesChanged()
}
ed->flightModes = 0;
for (int i=CPN_MAX_FLIGHT_MODES-1; i>=0 ; i--) {
for (int i = CPN_MAX_FLIGHT_MODES - 1; i >= 0 ; i--) {
if (!cb_fp[i]->checkState()) {
ed->flightModes++;
}
@ -212,7 +213,7 @@ void ExpoDialog::label_phases_customContextMenuRequested(const QPoint & pos)
void ExpoDialog::fmClearAll()
{
lock = true;
for (int i=0; i<CPN_MAX_FLIGHT_MODES; i++) {
for (int i = 0; i < CPN_MAX_FLIGHT_MODES; i++) {
cb_fp[i]->setChecked(false);
}
lock = false;
@ -222,7 +223,7 @@ void ExpoDialog::fmClearAll()
void ExpoDialog::fmSetAll()
{
lock = true;
for (int i=0; i<CPN_MAX_FLIGHT_MODES; i++) {
for (int i = 0; i < CPN_MAX_FLIGHT_MODES; i++) {
cb_fp[i]->setChecked(true);
}
lock = false;
@ -232,7 +233,7 @@ void ExpoDialog::fmSetAll()
void ExpoDialog::fmInvertAll()
{
lock = true;
for (int i=0; i<CPN_MAX_FLIGHT_MODES; i++) {
for (int i = 0; i < CPN_MAX_FLIGHT_MODES; i++) {
cb_fp[i]->setChecked(!cb_fp[i]->isChecked());
}
lock = false;

View file

@ -27,6 +27,7 @@
class GVarGroup;
class CurveGroup;
class RawItemFilteredModel;
namespace Ui {
class ExpoDialog;
@ -36,7 +37,8 @@ class ExpoDialog : public QDialog {
Q_OBJECT
public:
ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expodata, GeneralSettings & generalSettings,
Firmware * firmware, QString & inputName);
Firmware * firmware, QString & inputName, RawItemFilteredModel * rawSourceItemModel,
RawItemFilteredModel * rawSwitchItemModel);
~ExpoDialog();
protected:

View file

@ -24,14 +24,15 @@
#include "helpers.h"
#include "customdebug.h"
FlightModePanel::FlightModePanel(QWidget * parent, ModelData & model, int phaseIdx, GeneralSettings & generalSettings, Firmware * firmware, RawSwitchFilterItemModel * switchModel):
FlightModePanel::FlightModePanel(QWidget * parent, ModelData & model, int phaseIdx, GeneralSettings & generalSettings, Firmware * firmware, RawItemFilteredModel * rawSwitchFilteredModel):
ModelPanel(parent, model, generalSettings, firmware),
ui(new Ui::FlightMode),
phaseIdx(phaseIdx),
phase(model.flightModeData[phaseIdx]),
rawSwitchItemModel(NULL)
phase(model.flightModeData[phaseIdx])
{
ui->setupUi(this);
connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &FlightModePanel::onModelDataAboutToBeUpdated);
connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &FlightModePanel::onModelDataUpdateComplete);
ui->labelName->setContextMenuPolicy(Qt::CustomContextMenu);
ui->labelName->setToolTip(tr("Popup menu available"));
@ -56,8 +57,8 @@ FlightModePanel::FlightModePanel(QWidget * parent, ModelData & model, int phaseI
// Flight mode switch
if (phaseIdx > 0) {
ui->swtch->setModel(switchModel);
connect(ui->swtch, SIGNAL(activated(int)), this, SLOT(phaseSwitchChanged(int)));
ui->swtch->setModel(rawSwitchFilteredModel);
connect(ui->swtch, SIGNAL(currentIndexChanged(int)), this, SLOT(phaseSwitch_currentIndexChanged(int)));
}
else {
ui->swtch->hide();
@ -316,8 +317,6 @@ void FlightModePanel::update()
for (int i = 0; i < reCount; i++) {
updateRotaryEncoder(i);
}
emit nameModified();
}
void FlightModePanel::updateGVar(int index)
@ -390,17 +389,18 @@ void FlightModePanel::phaseName_editingFinished()
{
QLineEdit *lineEdit = qobject_cast<QLineEdit*>(sender());
strcpy(phase.name, lineEdit->text().toLatin1());
emit phaseNameChanged();
emit modified();
emit nameModified();
}
void FlightModePanel::phaseSwitchChanged(int index)
void FlightModePanel::phaseSwitch_currentIndexChanged(int index)
{
if (!lock) {
bool ok;
const RawSwitch rs(ui->swtch->itemData(index).toInt(&ok));
if (ok && phase.swtch.toValue() != rs.toValue()) {
phase.swtch = rs;
emit phaseSwitchChanged();
emit modified();
}
}
@ -457,7 +457,7 @@ void FlightModePanel::phaseGVValue_editingFinished()
QDoubleSpinBox *spinBox = qobject_cast<QDoubleSpinBox*>(sender());
int gvar = spinBox->property("index").toInt();
phase.gvars[gvar] = spinBox->value() * model->gvarData[gvar].multiplierSet();
emit datachanged();
updateGVar(gvar);
emit modified();
}
}
@ -469,7 +469,7 @@ void FlightModePanel::GVName_editingFinished()
int gvar = lineedit->property("index").toInt();
memset(&model->gvarData[gvar].name, 0, sizeof(model->gvarData[gvar].name));
strcpy(model->gvarData[gvar].name, lineedit->text().toLatin1());
emit datachanged();
emit gvNameChanged();
emit modified();
}
}
@ -488,7 +488,7 @@ void FlightModePanel::phaseGVUse_currentIndexChanged(int index)
}
if (model->isGVarLinkedCircular(phaseIdx, gvar))
QMessageBox::warning(this, "Companion", tr("Warning: Global variable links back to itself. Flight Mode 0 value used."));
emit datachanged();
updateGVar(gvar);
emit modified();
lock = false;
}
@ -500,7 +500,7 @@ void FlightModePanel::phaseGVUnit_currentIndexChanged(int index)
QComboBox *comboBox = qobject_cast<QComboBox*>(sender());
int gvar = comboBox->property("index").toInt();
model->gvarData[gvar].unit = index;
emit datachanged();
updateGVar(gvar);
emit modified();
}
}
@ -511,7 +511,7 @@ void FlightModePanel::phaseGVPrec_currentIndexChanged(int index)
QComboBox *comboBox = qobject_cast<QComboBox*>(sender());
int gvar = comboBox->property("index").toInt();
model->gvarData[gvar].prec = index;
emit datachanged();
updateGVar(gvar);
emit modified();
}
}
@ -534,7 +534,7 @@ void FlightModePanel::phaseGVMin_editingFinished()
}
}
}
emit datachanged();
updateGVar(gvar);
emit modified();
}
}
@ -557,7 +557,7 @@ void FlightModePanel::phaseGVMax_editingFinished()
}
}
}
emit datachanged();
updateGVar(gvar);
emit modified();
}
}
@ -741,7 +741,8 @@ void FlightModePanel::cmClear(bool prompt)
model->updateAllReferences(ModelData::REF_UPD_TYPE_FLIGHT_MODE, ModelData::REF_UPD_ACT_CLEAR, phaseIdx);
emit datachanged();
update();
emit phaseDataChanged();
emit modified();
}
@ -767,7 +768,7 @@ void FlightModePanel::cmClearAll()
model->updateAllReferences(ModelData::REF_UPD_TYPE_GLOBAL_VARIABLE, ModelData::REF_UPD_ACT_CLEAR, i);
}
emit datachanged();
emit phaseDataChanged();
emit modified();
}
@ -846,7 +847,7 @@ void FlightModePanel::cmDelete()
model->updateAllReferences(ModelData::REF_UPD_TYPE_FLIGHT_MODE, ModelData::REF_UPD_ACT_SHIFT, phaseIdx, 0, -1);
emit datachanged();
emit phaseDataChanged();
emit modified();
}
@ -897,7 +898,7 @@ void FlightModePanel::cmInsert()
model->updateAllReferences(ModelData::REF_UPD_TYPE_FLIGHT_MODE, ModelData::REF_UPD_ACT_SHIFT, phaseIdx, 0, 1);
emit datachanged();
emit phaseDataChanged();
emit modified();
}
@ -946,7 +947,7 @@ void FlightModePanel::cmPaste()
}
}
emit datachanged();
emit phaseDataChanged();
emit modified();
}
}
@ -1035,7 +1036,7 @@ void FlightModePanel::swapData(int idx1, int idx2)
}
model->updateAllReferences(ModelData::REF_UPD_TYPE_FLIGHT_MODE, ModelData::REF_UPD_ACT_SWAP, idx1, idx2);
emit datachanged();
emit phaseDataChanged();
emit modified();
}
@ -1162,7 +1163,8 @@ void FlightModePanel::gvCmClear(bool prompt)
}
phase.gvars[gvIdx] = phase.linkedGVarFlightModeZero(phaseIdx);
}
emit datachanged();
updateGVar(gvIdx);
emit gvNameChanged();
emit modified();
}
@ -1186,7 +1188,10 @@ void FlightModePanel::gvCmClearAll()
phase.gvars[i] = phase.linkedGVarFlightModeZero(phaseIdx);
}
}
emit datachanged();
for (int i = 0; i < gvCount; i++) {
updateGVar(i);
}
emit gvNameChanged();
emit modified();
}
@ -1261,8 +1266,13 @@ void FlightModePanel::gvCmDelete()
for (int j = 0; j < fmCount; j++) {
model->flightModeData[j].gvars[maxidx] = model->flightModeData[j].linkedGVarFlightModeZero(j);
}
model->updateAllReferences(ModelData::REF_UPD_TYPE_GLOBAL_VARIABLE, ModelData::REF_UPD_ACT_SHIFT, gvIdx, 0, -1);
emit datachanged();
for (int i = 0; i < gvCount; i++) {
updateGVar(i);
}
emit gvNameChanged();
emit modified();
}
@ -1279,7 +1289,10 @@ void FlightModePanel::gvCmInsert()
model->flightModeData[j].gvars[gvIdx] = model->flightModeData[j].linkedGVarFlightModeZero(j);
}
model->updateAllReferences(ModelData::REF_UPD_TYPE_GLOBAL_VARIABLE, ModelData::REF_UPD_ACT_SHIFT, gvIdx, 0, 1);
emit datachanged();
for (int i = 0; i < gvCount; i++) {
updateGVar(i);
}
emit gvNameChanged();
emit modified();
}
@ -1322,7 +1335,8 @@ void FlightModePanel::gvCmPaste()
else
phase.gvars[gvIdx] = val;
}
emit datachanged();
updateGVar(gvIdx);
emit gvNameChanged();
emit modified();
}
@ -1340,33 +1354,51 @@ void FlightModePanel::gvSwapData(int idx1, int idx2)
model->flightModeData[j].gvars[idx1] = valtmp;
}
model->updateAllReferences(ModelData::REF_UPD_TYPE_GLOBAL_VARIABLE, ModelData::REF_UPD_ACT_SWAP, idx1, idx2);
emit datachanged();
updateGVar(idx1);
updateGVar(idx2);
emit gvNameChanged();
emit modified();
}
}
void FlightModePanel::onModelDataAboutToBeUpdated()
{
lock = true;
}
void FlightModePanel::onModelDataUpdateComplete()
{
update();
lock = false;
}
/**********************************************************/
FlightModesPanel::FlightModesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware):
FlightModesPanel::FlightModesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels):
ModelPanel(parent, model, generalSettings, firmware),
modesCount(firmware->getCapability(FlightModes))
commonItemModels(commonItemModels)
{
RawSwitchFilterItemModel * swModel = new RawSwitchFilterItemModel(&generalSettings, &model, RawSwitch::MixesContext, this);
connect(this, &FlightModesPanel::updated, swModel, &RawSwitchFilterItemModel::update);
rawSwitchFilteredModel = new RawItemFilteredModel(commonItemModels->rawSwitchItemModel(), RawSwitch::MixesContext, this);
modesCount = firmware->getCapability(FlightModes);
QGridLayout * gridLayout = new QGridLayout(this);
tabWidget = new QTabWidget(this);
for (int i = 0; i < modesCount; i++) {
FlightModePanel * tab = new FlightModePanel(tabWidget, model, i, generalSettings, firmware, swModel);
FlightModePanel * tab = new FlightModePanel(tabWidget, model, i, generalSettings, firmware, rawSwitchFilteredModel);
tab->setProperty("index", i);
connect(tab, &FlightModePanel::datachanged, this, &FlightModesPanel::update);
connect(tab, &FlightModePanel::modified, this, &FlightModesPanel::modified);
connect(tab, &FlightModePanel::nameModified, this, &FlightModesPanel::onPhaseNameChanged);
connect(this, &FlightModesPanel::updated, tab, &FlightModePanel::update);
connect(tab, &FlightModePanel::modified, this, &FlightModesPanel::modified);
connect(tab, &FlightModePanel::phaseDataChanged, this, &FlightModesPanel::onPhaseNameChanged);
connect(tab, &FlightModePanel::phaseNameChanged, this, &FlightModesPanel::onPhaseNameChanged);
connect(tab, &FlightModePanel::phaseSwitchChanged, this, &FlightModesPanel::updateItemModels);
connect(tab, &FlightModePanel::gvNameChanged, this, &FlightModesPanel::updateItemModels);
connect(this, &FlightModesPanel::updated, tab, &FlightModePanel::update);
tabWidget->addTab(tab, getTabName(i));
panels << tab;
}
connect(tabWidget, &QTabWidget::currentChanged, this, &FlightModesPanel::onTabIndexChanged);
gridLayout->addWidget(tabWidget, 0, 0, 1, 1);
onTabIndexChanged(0);
}
FlightModesPanel::~FlightModesPanel()
@ -1391,9 +1423,22 @@ void FlightModesPanel::onPhaseNameChanged()
{
int index = sender()->property("index").toInt();
tabWidget->setTabText(index, getTabName(index));
updateItemModels();
}
void FlightModesPanel::update()
{
emit updated();
}
void FlightModesPanel::updateItemModels()
{
commonItemModels->update(CommonItemModels::RMO_FLIGHT_MODES);
commonItemModels->update(CommonItemModels::RMO_GLOBAL_VARIABLES);
}
void FlightModesPanel::onTabIndexChanged(int index)
{
if (index < panels.size())
panels.at(index)->update();
}

View file

@ -24,7 +24,8 @@
#include "modeledit.h"
#include "eeprominterface.h"
class RawSwitchFilterItemModel;
class CommonItemModels;
class RawItemFilteredModel;
constexpr char MIMETYPE_FLIGHTMODE[] = "application/x-companion-flightmode";
constexpr char MIMETYPE_GVAR_PARAMS[] = "application/x-companion-gvar-params";
@ -40,18 +41,20 @@ class FlightModePanel : public ModelPanel
Q_OBJECT
public:
FlightModePanel(QWidget *parent, ModelData &model, int modeIdx, GeneralSettings & generalSettings, Firmware * firmware, RawSwitchFilterItemModel * switchModel);
FlightModePanel(QWidget *parent, ModelData &model, int modeIdx, GeneralSettings & generalSettings, Firmware * firmware, RawItemFilteredModel * rawSwitchFilteredModel);
virtual ~FlightModePanel();
virtual void update();
signals:
void nameModified();
void datachanged();
void gvNameChanged();
void phaseDataChanged();
void phaseNameChanged();
void phaseSwitchChanged();
private slots:
void phaseName_editingFinished();
void phaseSwitchChanged(int index);
void phaseSwitch_currentIndexChanged(int index);
void phaseFadeIn_editingFinished();
void phaseFadeOut_editingFinished();
void phaseTrimUse_currentIndexChanged(int index);
@ -87,6 +90,8 @@ class FlightModePanel : public ModelPanel
void gvCmPaste();
void gvCmMoveDown();
void gvCmMoveUp();
void onModelDataAboutToBeUpdated();
void onModelDataUpdateComplete();
private:
Ui::FlightMode *ui;
@ -111,7 +116,6 @@ class FlightModePanel : public ModelPanel
QVector<QComboBox *> trimsUse;
QVector<QSpinBox *> trimsValue;
QVector<QSlider *> trimsSlider;
RawSwitchFilterItemModel * rawSwitchItemModel;
Board::Type board;
void trimUpdate(unsigned int trim);
@ -141,7 +145,7 @@ class FlightModesPanel : public ModelPanel
Q_OBJECT
public:
FlightModesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware);
FlightModesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels);
virtual ~FlightModesPanel();
public slots:
@ -152,13 +156,17 @@ class FlightModesPanel : public ModelPanel
private slots:
void onPhaseNameChanged();
void onTabIndexChanged(int index);
private:
QString getTabName(int index);
int modesCount;
QTabWidget *tabWidget;
CommonItemModels *commonItemModels;
RawItemFilteredModel *rawSwitchFilteredModel;
QVector<GenericPanel *> panels;
void updateItemModels();
};
#endif // _FLIGHTMODES_H_

View file

@ -23,19 +23,26 @@
#include "helpers.h"
#include "rawitemfilteredmodel.h"
HeliPanel::HeliPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware):
HeliPanel::HeliPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels):
ModelPanel(parent, model, generalSettings, firmware),
ui(new Ui::Heli)
ui(new Ui::Heli),
commonItemModels(commonItemModels)
{
ui->setupUi(this);
rawSourceItemModel = new RawSourceFilterItemModel(&generalSettings, &model, RawSource::InputSourceGroups, this);
rawSourceFilteredModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), RawSource::InputSourceGroups, this);
connect(rawSourceFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &HeliPanel::onModelDataAboutToBeUpdated);
connect(rawSourceFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &HeliPanel::onModelDataUpdateComplete);
connect(ui->swashType, SIGNAL(currentIndexChanged(int)), this, SLOT(edited()));
connect(ui->swashRingVal, SIGNAL(editingFinished()), this, SLOT(edited()));
ui->swashCollectiveSource->setModel(rawSourceFilteredModel);
connect(ui->swashCollectiveSource, SIGNAL(currentIndexChanged(int)), this, SLOT(edited()));
if (firmware->getCapability(VirtualInputs)) {
ui->swashAileronSource->setModel(rawSourceFilteredModel);
connect(ui->swashAileronSource, SIGNAL(currentIndexChanged(int)), this, SLOT(edited()));
ui->swashElevatorSource->setModel(rawSourceFilteredModel);
connect(ui->swashElevatorSource, SIGNAL(currentIndexChanged(int)), this, SLOT(edited()));
connect(ui->swashAileronWeight, SIGNAL(editingFinished()), this, SLOT(edited()));
connect(ui->swashElevatorWeight, SIGNAL(editingFinished()), this, SLOT(edited()));
@ -66,27 +73,15 @@ HeliPanel::~HeliPanel()
delete ui;
}
void HeliPanel::updateDataModels()
{
const bool oldLock = lock;
lock = true;
rawSourceItemModel->update();
lock = oldLock;
}
void HeliPanel::update()
{
lock = true;
updateDataModels();
ui->swashType->setCurrentIndex(model->swashRingData.type);
ui->swashCollectiveSource->setModel(rawSourceItemModel);
ui->swashCollectiveSource->setCurrentIndex(ui->swashCollectiveSource->findData(model->swashRingData.collectiveSource.toValue()));
ui->swashRingVal->setValue(model->swashRingData.value);
if (firmware->getCapability(VirtualInputs)) {
ui->swashElevatorSource->setModel(rawSourceItemModel);
ui->swashElevatorSource->setCurrentIndex(ui->swashElevatorSource->findData(model->swashRingData.elevatorSource.toValue()));
ui->swashAileronSource->setModel(rawSourceItemModel);
ui->swashAileronSource->setCurrentIndex(ui->swashAileronSource->findData(model->swashRingData.aileronSource.toValue()));
ui->swashElevatorWeight->setValue(model->swashRingData.elevatorWeight);
ui->swashAileronWeight->setValue(model->swashRingData.aileronWeight);
@ -122,3 +117,14 @@ void HeliPanel::edited()
emit modified();
}
}
void HeliPanel::onModelDataAboutToBeUpdated()
{
lock = true;
}
void HeliPanel::onModelDataUpdateComplete()
{
update();
lock = false;
}

View file

@ -23,7 +23,8 @@
#include "modeledit.h"
class RawSourceFilterItemModel;
class CommonItemModels;
class RawItemFilteredModel;
namespace Ui {
class Heli;
@ -34,17 +35,19 @@ class HeliPanel : public ModelPanel
Q_OBJECT
public:
HeliPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware);
HeliPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels);
~HeliPanel();
void update();
private slots:
void updateDataModels();
void edited();
void onModelDataAboutToBeUpdated();
void onModelDataUpdateComplete();
private:
Ui::Heli *ui;
RawSourceFilterItemModel * rawSourceItemModel;
CommonItemModels * commonItemModels;
RawItemFilteredModel * rawSourceFilteredModel;
};
#endif // _HELI_H_

View file

@ -21,12 +21,22 @@
#include "inputs.h"
#include "expodialog.h"
#include "helpers.h"
#include "rawitemfilteredmodel.h"
InputsPanel::InputsPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware):
InputsPanel::InputsPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels):
ModelPanel(parent, model, generalSettings, firmware),
expoInserted(false),
modelPrinter(firmware, generalSettings, model)
modelPrinter(firmware, generalSettings, model),
commonItemModels(commonItemModels)
{
rawSourceFilteredModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), (RawSource::InputSourceGroups & ~ RawSource::NoneGroup & ~RawSource::InputsGroup), this);
connect(rawSourceFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &InputsPanel::onModelDataAboutToBeUpdated);
connect(rawSourceFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &InputsPanel::onModelDataUpdateComplete);
rawSwitchFilteredModel = new RawItemFilteredModel(commonItemModels->rawSwitchItemModel(), RawSwitch::MixesContext, this);
connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &InputsPanel::onModelDataAboutToBeUpdated);
connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &InputsPanel::onModelDataUpdateComplete);
inputsCount = firmware->getCapability(VirtualInputs);
if (inputsCount == 0)
inputsCount = CPN_MAX_STICKS;
@ -180,13 +190,14 @@ void InputsPanel::gm_openExpo(int index)
if (firmware->getCapability(VirtualInputs))
inputName = model->inputNames[ed.chn];
ExpoDialog *g = new ExpoDialog(this, *model, &ed, generalSettings, firmware, inputName);
if (g->exec()) {
ExpoDialog *dlg = new ExpoDialog(this, *model, &ed, generalSettings, firmware, inputName, rawSourceFilteredModel, rawSwitchFilteredModel);
if (dlg->exec()) {
model->expoData[index] = ed;
if (firmware->getCapability(VirtualInputs))
strncpy(model->inputNames[ed.chn], inputName.toLatin1().data(), INPUT_NAME_LEN);
emit modified();
update();
updateItemModels();
emit modified();
}
else {
if (expoInserted) {
@ -195,6 +206,7 @@ void InputsPanel::gm_openExpo(int index)
expoInserted=false;
update();
}
delete dlg;
}
int InputsPanel::getExpoIndex(unsigned int dch)
@ -239,8 +251,9 @@ void InputsPanel::exposDelete(bool prompt)
}
exposDeleteList(list, prompt);
emit modified();
update();
updateItemModels();
emit modified();
}
void InputsPanel::exposCut()
@ -313,8 +326,9 @@ void InputsPanel::pasteExpoMimeData(const QMimeData * mimeData, int destIdx)
i += sizeof(ExpoData);
}
emit modified();
update();
updateItemModels();
emit modified();
}
}
@ -481,8 +495,9 @@ void InputsPanel::moveExpoList(bool down)
}
}
if (mod) {
emit modified();
update();
updateItemModels();
emit modified();
}
setSelectedByExpoList(highlightList);
}
@ -520,8 +535,9 @@ void InputsPanel::clearExpos()
for (int i = 0; i < inputsCount; i++) {
model->updateAllReferences(ModelData::REF_UPD_TYPE_INPUT, ModelData::REF_UPD_ACT_CLEAR, i);
}
emit modified();
update();
updateItemModels();
emit modified();
}
}
@ -569,6 +585,7 @@ void InputsPanel::cmInputClear()
}
model->updateAllReferences(ModelData::REF_UPD_TYPE_INPUT, ModelData::REF_UPD_ACT_CLEAR, inputIdx);
update();
updateItemModels();
emit modified();
}
@ -592,6 +609,7 @@ void InputsPanel::cmInputDelete()
model->updateAllReferences(ModelData::REF_UPD_TYPE_INPUT, ModelData::REF_UPD_ACT_SHIFT, inputIdx, 0, -1);
update();
updateItemModels();
emit modified();
}
@ -610,6 +628,7 @@ void InputsPanel::cmInputInsert()
model->updateAllReferences(ModelData::REF_UPD_TYPE_INPUT, ModelData::REF_UPD_ACT_SHIFT, inputIdx, 0, 1);
update();
updateItemModels();
emit modified();
}
@ -671,6 +690,7 @@ void InputsPanel::cmInputSwapData(int idx1, int idx2)
model->updateAllReferences(ModelData::REF_UPD_TYPE_INPUT, ModelData::REF_UPD_ACT_SWAP, idx1, idx2);
update();
updateItemModels();
emit modified();
}
@ -705,3 +725,19 @@ int InputsPanel::getInputIndexFromSelected()
}
return idx;
}
void InputsPanel::onModelDataAboutToBeUpdated()
{
lock = true;
}
void InputsPanel::onModelDataUpdateComplete()
{
update();
lock = false;
}
void InputsPanel::updateItemModels()
{
commonItemModels->update(CommonItemModels::RMO_INPUTS);
}

View file

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

View file

@ -24,16 +24,20 @@
#include <TimerEdit>
LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware):
LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels):
ModelPanel(parent, model, generalSettings, firmware),
selectedIndex(0)
commonItemModels(commonItemModels),
selectedIndex(0),
modelsUpdateCnt(0)
{
Stopwatch s1("LogicalSwitchesPanel");
rawSwitchItemModel = new RawSwitchFilterItemModel(&generalSettings, &model, RawSwitch::LogicalSwitchesContext, this);
rawSwitchFilteredModel = new RawItemFilteredModel(commonItemModels->rawSwitchItemModel(), RawSwitch::LogicalSwitchesContext, this);
connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &LogicalSwitchesPanel::onModelDataAboutToBeUpdated);
connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &LogicalSwitchesPanel::onModelDataUpdateComplete);
const int srcGroups = firmware->getCapability(GvarsInCS) ? 0 : (RawSource::AllSourceGroups & ~RawSource::GVarsGroup);
rawSourceItemModel = new RawSourceFilterItemModel(&generalSettings, &model, srcGroups, this);
rawSourceFilteredModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), srcGroups, this);
connect(rawSourceFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &LogicalSwitchesPanel::onModelDataAboutToBeUpdated);
connect(rawSourceFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &LogicalSwitchesPanel::onModelDataUpdateComplete);
lsCapability = firmware->getCapability(LogicalSwitches);
lsCapabilityExt = firmware->getCapability(LogicalSwitchesExt);
@ -45,16 +49,13 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model,
}
TableLayout * tableLayout = new TableLayout(this, lsCapability, headerLabels);
s1.report("header");
const int channelsMax = model.getChannelsMax(true);
lock = true;
for (int i=0; i<lsCapability; i++) {
for (int i = 0; i < lsCapability; i++) {
// The label
QLabel * label = new QLabel(this);
label->setProperty("index", i);
label->setText(RawSwitch(SWITCH_TYPE_VIRTUAL, i+1).toString());
label->setText(RawSwitch(SWITCH_TYPE_VIRTUAL, i + 1).toString());
label->setContextMenuPolicy(Qt::CustomContextMenu);
label->setToolTip(tr("Popup menu available"));
label->setMouseTracking(true);
@ -123,7 +124,8 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model,
// AND
cbAndSwitch[i] = new QComboBox(this);
cbAndSwitch[i]->setProperty("index", i);
populateAndSwitchCB(cbAndSwitch[i]);
cbAndSwitch[i]->setModel(rawSwitchFilteredModel);
cbAndSwitch[i]->setVisible(true);
connect(cbAndSwitch[i], SIGNAL(currentIndexChanged(int)), this, SLOT(onAndSwitchChanged(int)));
tableLayout->addWidget(i, 4, cbAndSwitch[i]);
@ -152,72 +154,63 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model,
}
}
s1.report("added elements");
disableMouseScrolling();
lock = false;
update();
tableLayout->resizeColumnsToContents();
tableLayout->pushRowsUp(lsCapability+1);
s1.report("end");
}
LogicalSwitchesPanel::~LogicalSwitchesPanel()
{
}
void LogicalSwitchesPanel::updateDataModels()
{
const bool oldLock = lock;
lock = true;
rawSwitchItemModel->update();
rawSourceItemModel->update();
lock = oldLock;
}
void LogicalSwitchesPanel::onFunctionChanged()
{
int i = sender()->property("index").toInt();
unsigned newFunc = cbFunction[i]->currentData().toUInt();
if (!lock) {
int i = sender()->property("index").toInt();
unsigned newFunc = cbFunction[i]->currentData().toUInt();
if (model->logicalSw[i].func == newFunc)
return;
if (model->logicalSw[i].func == newFunc)
return;
const unsigned oldFunc = model->logicalSw[i].func;
CSFunctionFamily oldFuncFamily = model->logicalSw[i].getFunctionFamily();
model->logicalSw[i].func = newFunc;
CSFunctionFamily newFuncFamily = model->logicalSw[i].getFunctionFamily();
if (oldFuncFamily != newFuncFamily) {
model->logicalSw[i].clear();
unsigned oldFunc = model->logicalSw[i].func;
CSFunctionFamily oldFuncFamily = model->logicalSw[i].getFunctionFamily();
model->logicalSw[i].func = newFunc;
if (newFuncFamily == LS_FAMILY_TIMER) {
model->logicalSw[i].val1 = -119;
model->logicalSw[i].val2 = -119;
CSFunctionFamily newFuncFamily = model->logicalSw[i].getFunctionFamily();
if (oldFuncFamily != newFuncFamily || newFunc == LS_FN_OFF) {
model->logicalSw[i].clear();
model->logicalSw[i].func = newFunc;
if (newFuncFamily == LS_FAMILY_TIMER) {
model->logicalSw[i].val1 = -119;
model->logicalSw[i].val2 = -119;
}
else if (newFuncFamily == LS_FAMILY_EDGE) {
model->logicalSw[i].val2 = -129;
}
}
else if (newFuncFamily == LS_FAMILY_EDGE) {
model->logicalSw[i].val2 = -129;
}
}
if (bool(oldFunc) != bool(newFunc))
update();
else
updateLine(i);
emit modified();
if (oldFunc == LS_FN_OFF || newFunc == LS_FN_OFF)
updateItemModels();
emit modified();
}
}
void LogicalSwitchesPanel::onV1Changed(int value)
{
if (!lock) {
int i = sender()->property("index").toInt();
model->logicalSw[i].val1 = cbSource1[i]->itemData(value).toInt();
if (model->logicalSw[i].getFunctionFamily() == LS_FAMILY_VOFS) {
if (!offsetChangedAt(i))
updateLine(i);
}
else {
emit modified();
if (model->logicalSw[i].val1 != cbSource1[i]->itemData(value).toInt()) {
model->logicalSw[i].val1 = cbSource1[i]->itemData(value).toInt();
if (model->logicalSw[i].getFunctionFamily() == LS_FAMILY_VOFS) {
if (!offsetChangedAt(i))
updateLine(i);
}
else {
emit modified();
}
}
}
}
@ -226,8 +219,10 @@ void LogicalSwitchesPanel::onV2Changed(int value)
{
if (!lock) {
int i = sender()->property("index").toInt();
model->logicalSw[i].val2 = cbSource2[i]->itemData(value).toInt();
emit modified();
if (model->logicalSw[i].val2 != cbSource2[i]->itemData(value).toInt()) {
model->logicalSw[i].val2 = cbSource2[i]->itemData(value).toInt();
emit modified();
}
}
}
@ -235,8 +230,10 @@ void LogicalSwitchesPanel::onAndSwitchChanged(int value)
{
if (!lock) {
int index = sender()->property("index").toInt();
model->logicalSw[index].andsw = cbAndSwitch[index]->itemData(value).toInt();
emit modified();
if (model->logicalSw[index].andsw != cbAndSwitch[index]->itemData(value).toInt()) {
model->logicalSw[index].andsw = cbAndSwitch[index]->itemData(value).toInt();
emit modified();
}
}
}
@ -244,7 +241,7 @@ void LogicalSwitchesPanel::onDurationChanged(double duration)
{
if (!lock) {
int index = sender()->property("index").toInt();
model->logicalSw[index].duration = (uint8_t)round(duration*10);
model->logicalSw[index].duration = (uint8_t)round(duration * 10);
emit modified();
}
}
@ -253,7 +250,7 @@ void LogicalSwitchesPanel::onDelayChanged(double delay)
{
if (!lock) {
int index = sender()->property("index").toInt();
model->logicalSw[index].delay = (uint8_t)round(delay*10);
model->logicalSw[index].delay = (uint8_t)round(delay * 10);
emit modified();
}
}
@ -326,9 +323,9 @@ void LogicalSwitchesPanel::updateTimerParam(QDoubleSpinBox *sb, int timer, doubl
sb->setMinimum(minimum);
sb->setMaximum(175);
float value = ValToTim(timer);
if (value>=60)
if (value >= 60)
sb->setSingleStep(1);
else if (value>=2)
else if (value >= 2)
sb->setSingleStep(0.5);
else
sb->setSingleStep(0.1);
@ -347,16 +344,14 @@ void LogicalSwitchesPanel::updateTimerParam(QDoubleSpinBox *sb, int timer, doubl
void LogicalSwitchesPanel::updateLine(int i)
{
const bool savelock = lock;
lock = true;
unsigned int mask;
unsigned int mask = 0;
cbFunction[i]->setCurrentIndex(cbFunction[i]->findData(model->logicalSw[i].func));
cbAndSwitch[i]->setCurrentIndex(cbAndSwitch[i]->findData(RawSwitch(model->logicalSw[i].andsw).toValue()));
if (!model->logicalSw[i].func) {
mask = 0;
}
else {
if (!model->logicalSw[i].isEmpty()) {
mask = LINE_ENABLED | DELAY_ENABLED | DURATION_ENABLED;
switch (model->logicalSw[i].getFunctionFamily())
@ -367,7 +362,7 @@ void LogicalSwitchesPanel::updateLine(int i)
RawSource source = RawSource(model->logicalSw[i].val1);
RawSourceRange range = source.getRange(model, generalSettings, model->logicalSw[i].getRangeFlags());
double value = range.step * model->logicalSw[i].val2 + range.offset; /* TODO+source.getRawOffset(model)*/
cbSource1[i]->setModel(rawSourceItemModel);
cbSource1[i]->setModel(rawSourceFilteredModel);
cbSource1[i]->setCurrentIndex(cbSource1[i]->findData(source.toValue()));
if (source.isTimeBased()) {
mask |= VALUE_TO_VISIBLE;
@ -396,27 +391,27 @@ void LogicalSwitchesPanel::updateLine(int i)
case LS_FAMILY_STICKY: // no break
case LS_FAMILY_VBOOL:
mask |= SOURCE1_VISIBLE | SOURCE2_VISIBLE;
cbSource1[i]->setModel(rawSwitchItemModel);
cbSource1[i]->setModel(rawSwitchFilteredModel);
cbSource1[i]->setCurrentIndex(cbSource1[i]->findData(model->logicalSw[i].val1));
cbSource2[i]->setModel(rawSwitchItemModel);
cbSource2[i]->setModel(rawSwitchFilteredModel);
cbSource2[i]->setCurrentIndex(cbSource2[i]->findData(model->logicalSw[i].val2));
break;
case LS_FAMILY_EDGE:
mask |= SOURCE1_VISIBLE | VALUE2_VISIBLE | VALUE3_VISIBLE;
mask &= ~DELAY_ENABLED;
cbSource1[i]->setModel(rawSwitchItemModel);
cbSource1[i]->setModel(rawSwitchFilteredModel);
cbSource1[i]->setCurrentIndex(cbSource1[i]->findData(model->logicalSw[i].val1));
updateTimerParam(dsbOffset[i], model->logicalSw[i].val2, 0.0);
updateTimerParam(dsbOffset2[i], model->logicalSw[i].val2+model->logicalSw[i].val3, ValToTim(TimToVal(dsbOffset[i]->value())-1));
updateTimerParam(dsbOffset2[i], model->logicalSw[i].val2 + model->logicalSw[i].val3, ValToTim(TimToVal(dsbOffset[i]->value()) - 1));
dsbOffset2[i]->setSuffix((model->logicalSw[i].val3) ? "" : tr(" (infinite)"));
break;
case LS_FAMILY_VCOMP:
mask |= SOURCE1_VISIBLE | SOURCE2_VISIBLE;
cbSource1[i]->setModel(rawSourceItemModel);
cbSource1[i]->setModel(rawSourceFilteredModel);
cbSource1[i]->setCurrentIndex(cbSource1[i]->findData(model->logicalSw[i].val1));
cbSource2[i]->setModel(rawSourceItemModel);
cbSource2[i]->setModel(rawSourceFilteredModel);
cbSource2[i]->setCurrentIndex(cbSource2[i]->findData(model->logicalSw[i].val2));
break;
@ -439,12 +434,12 @@ void LogicalSwitchesPanel::updateLine(int i)
dsbDuration[i]->setVisible(mask & DURATION_ENABLED);
dsbDelay[i]->setVisible(mask & DELAY_ENABLED);
if (mask & DURATION_ENABLED)
dsbDuration[i]->setValue(model->logicalSw[i].duration/10.0);
dsbDuration[i]->setValue(model->logicalSw[i].duration / 10.0);
if (mask & DELAY_ENABLED)
dsbDelay[i]->setValue(model->logicalSw[i].delay/10.0);
dsbDelay[i]->setValue(model->logicalSw[i].delay / 10.0);
}
lock = false;
lock = savelock;
}
void LogicalSwitchesPanel::populateFunctionCB(QComboBox *b)
@ -475,7 +470,7 @@ void LogicalSwitchesPanel::populateFunctionCB(QComboBox *b)
};
b->clear();
for (int i=0; i<LS_FN_MAX; i++) {
for (int i = 0; i < LS_FN_MAX; i++) {
int func = order[i];
if (func == LS_FN_NEQUAL || func == LS_FN_EGREATER || func == LS_FN_ELESS)
continue;
@ -484,16 +479,9 @@ void LogicalSwitchesPanel::populateFunctionCB(QComboBox *b)
b->setMaxVisibleItems(10);
}
void LogicalSwitchesPanel::populateAndSwitchCB(QComboBox *b)
{
b->setModel(rawSwitchItemModel);
b->setVisible(true);
}
void LogicalSwitchesPanel::update()
{
updateDataModels();
for (int i=0; i<lsCapability; i++) {
for (int i = 0; i < lsCapability; i++) {
updateLine(i);
}
}
@ -503,8 +491,8 @@ void LogicalSwitchesPanel::cmPaste()
QByteArray data;
if (hasClipboardData(&data)) {
memcpy(&model->logicalSw[selectedIndex], data.constData(), sizeof(LogicalSwitchData));
updateDataModels();
updateLine(selectedIndex);
updateItemModels();
emit modified();
}
}
@ -519,6 +507,7 @@ void LogicalSwitchesPanel::cmDelete()
model->updateAllReferences(ModelData::REF_UPD_TYPE_LOGICAL_SWITCH, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, -1);
update();
updateItemModels();
emit modified();
}
@ -528,7 +517,7 @@ void LogicalSwitchesPanel::cmCopy()
data.append((char*)&model->logicalSw[selectedIndex], sizeof(LogicalSwitchData));
QMimeData *mimeData = new QMimeData;
mimeData->setData(MIMETYPE_LOGICAL_SWITCH, data);
QApplication::clipboard()->setMimeData(mimeData,QClipboard::Clipboard);
QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard);
}
void LogicalSwitchesPanel::cmCut()
@ -539,7 +528,6 @@ void LogicalSwitchesPanel::cmCut()
cmClear(false);
}
// TODO make something generic here!
void LogicalSwitchesPanel::onCustomContextMenuRequested(QPoint pos)
{
QLabel *label = (QLabel *)sender();
@ -608,7 +596,8 @@ void LogicalSwitchesPanel::cmClear(bool prompt)
model->logicalSw[selectedIndex].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_LOGICAL_SWITCH, ModelData::REF_UPD_ACT_CLEAR, selectedIndex);
update();
updateLine(selectedIndex);
updateItemModels();
emit modified();
}
@ -617,11 +606,12 @@ void LogicalSwitchesPanel::cmClearAll()
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear all Logical Switches. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
return;
for (int i=0; i<lsCapability; i++) {
for (int i = 0; i < lsCapability; i++) {
model->logicalSw[i].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_LOGICAL_SWITCH, ModelData::REF_UPD_ACT_CLEAR, i);
}
update();
updateItemModels();
emit modified();
}
@ -631,6 +621,7 @@ void LogicalSwitchesPanel::cmInsert()
model->logicalSw[selectedIndex].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_LOGICAL_SWITCH, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, 1);
update();
updateItemModels();
emit modified();
}
@ -643,7 +634,30 @@ void LogicalSwitchesPanel::swapData(int idx1, int idx2)
memcpy(lsw2, lsw1, sizeof(LogicalSwitchData));
memcpy(lsw1, &lstmp, sizeof(LogicalSwitchData));
model->updateAllReferences(ModelData::REF_UPD_TYPE_LOGICAL_SWITCH, ModelData::REF_UPD_ACT_SWAP, idx1, idx2);
update();
updateLine(idx1);
updateLine(idx2);
updateItemModels();
emit modified();
}
}
void LogicalSwitchesPanel::updateItemModels()
{
lock = true;
commonItemModels->update(CommonItemModels::RMO_LOGICAL_SWITCHES);
}
void LogicalSwitchesPanel::onModelDataAboutToBeUpdated()
{
lock = true;
modelsUpdateCnt++;
}
void LogicalSwitchesPanel::onModelDataUpdateComplete()
{
modelsUpdateCnt--;
if (modelsUpdateCnt < 1) {
update();
lock = false;
}
}

View file

@ -24,8 +24,8 @@
#include "modeledit.h"
#include "radiodata.h"
class RawSwitchFilterItemModel;
class RawSourceFilterItemModel;
class CommonItemModels;
class RawItemFilteredModel;
class TimerEdit;
constexpr char MIMETYPE_LOGICAL_SWITCH[] = "application/x-companion-logical-switch";
@ -35,13 +35,12 @@ class LogicalSwitchesPanel : public ModelPanel
Q_OBJECT
public:
LogicalSwitchesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware);
LogicalSwitchesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels);
virtual ~LogicalSwitchesPanel();
virtual void update();
private slots:
void updateDataModels();
void onFunctionChanged();
void onV1Changed(int value);
void onV2Changed(int value);
@ -61,6 +60,8 @@ class LogicalSwitchesPanel : public ModelPanel
void cmInsert();
void cmClear(bool prompt = true);
void cmClearAll();
void onModelDataAboutToBeUpdated();
void onModelDataUpdateComplete();
private:
QComboBox * cbFunction[CPN_MAX_LOGICAL_SWITCHES];
@ -73,11 +74,11 @@ class LogicalSwitchesPanel : public ModelPanel
QDoubleSpinBox * dsbDelay[CPN_MAX_LOGICAL_SWITCHES];
QComboBox * cbSource1[CPN_MAX_LOGICAL_SWITCHES];
QComboBox * cbSource2[CPN_MAX_LOGICAL_SWITCHES];
RawSwitchFilterItemModel * rawSwitchItemModel;
RawSourceFilterItemModel * rawSourceItemModel;
CommonItemModels * commonItemModels;
RawItemFilteredModel * rawSwitchFilteredModel;
RawItemFilteredModel * rawSourceFilteredModel;
int selectedIndex;
void populateFunctionCB(QComboBox *b);
void populateAndSwitchCB(QComboBox *b);
void updateTimerParam(QDoubleSpinBox *sb, int timer, double minimum=0);
int lsCapability;
int lsCapabilityExt;
@ -86,6 +87,8 @@ class LogicalSwitchesPanel : public ModelPanel
bool insertAllowed() const;
bool moveDownAllowed() const;
bool moveUpAllowed() const;
int modelsUpdateCnt;
void updateItemModels();
};
#endif // _LOGICALSWITCHES_H_

View file

@ -24,7 +24,8 @@
#include "rawitemfilteredmodel.h"
#include "helpers.h"
MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata, GeneralSettings & generalSettings, Firmware * firmware) :
MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata, GeneralSettings & generalSettings, Firmware * firmware,
RawItemFilteredModel * rawSourceModel, RawItemFilteredModel * rawSwitchModel) :
QDialog(parent),
ui(new Ui::MixerDialog),
model(model),
@ -34,18 +35,18 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata,
lock(false)
{
ui->setupUi(this);
QRegExp rx(CHAR_FOR_NAMES_REGEX);
QLabel * lb_fp[CPN_MAX_FLIGHT_MODES] = {ui->lb_FP0,ui->lb_FP1,ui->lb_FP2,ui->lb_FP3,ui->lb_FP4,ui->lb_FP5,ui->lb_FP6,ui->lb_FP7,ui->lb_FP8 };
QCheckBox * tmp[CPN_MAX_FLIGHT_MODES] = {ui->cb_FP0,ui->cb_FP1,ui->cb_FP2,ui->cb_FP3,ui->cb_FP4,ui->cb_FP5,ui->cb_FP6,ui->cb_FP7,ui->cb_FP8 };
for (int i=0; i<CPN_MAX_FLIGHT_MODES; i++) {
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++) {
cb_fp[i] = tmp[i];
}
this->setWindowTitle(tr("DEST -> %1").arg(RawSource(SOURCE_TYPE_CH, md->destCh-1).toString(&model, &generalSettings)));
this->setWindowTitle(tr("DEST -> %1").arg(RawSource(SOURCE_TYPE_CH, md->destCh - 1).toString(&model, &generalSettings)));
ui->sourceCB->setModel(new RawSourceFilterItemModel(&generalSettings, &model, RawSource::InputSourceGroups | RawSource::ScriptsGroup, this));
ui->sourceCB->setModel(rawSourceModel);
ui->sourceCB->setCurrentIndex(ui->sourceCB->findData(md->srcRaw.toValue()));
ui->sourceCB->removeItem(0);
int limit = firmware->getCapability(OffsetWeight);
@ -62,7 +63,7 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata,
}
if (!firmware->getCapability(VirtualInputs)) {
for(int i=0; i < CPN_MAX_STICKS; i++) {
for(int i = 0; i < CPN_MAX_STICKS; i++) {
ui->trimCB->addItem(firmware->getAnalogInputName(i));
}
}
@ -82,7 +83,7 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata,
if (!firmware->getCapability(FlightModes)) {
ui->label_phases->hide();
for (int i=0; i<CPN_MAX_FLIGHT_MODES; i++) {
for (int i = 0; i < CPN_MAX_FLIGHT_MODES; i++) {
lb_fp[i]->hide();
cb_fp[i]->hide();
}
@ -92,40 +93,40 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata,
ui->label_phases->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->label_phases, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(label_phases_customContextMenuRequested(const QPoint &)));
int mask = 1;
for (int i=0; i<CPN_MAX_FLIGHT_MODES ; i++) {
for (int i = 0; i < CPN_MAX_FLIGHT_MODES ; i++) {
if ((md->flightModes & mask) == 0) {
cb_fp[i]->setChecked(true);
}
mask <<= 1;
}
for (int i=firmware->getCapability(FlightModes); i<CPN_MAX_FLIGHT_MODES; i++) {
for (int i = firmware->getCapability(FlightModes); i < CPN_MAX_FLIGHT_MODES; i++) {
lb_fp[i]->hide();
cb_fp[i]->hide();
}
}
ui->switchesCB->setModel(new RawSwitchFilterItemModel(&generalSettings, &model, RawSwitch::MixesContext, this));
ui->switchesCB->setModel(rawSwitchModel);
ui->switchesCB->setCurrentIndex(ui->switchesCB->findData(md->swtch.toValue()));
ui->warningCB->setCurrentIndex(md->mixWarn);
ui->mltpxCB->setCurrentIndex(md->mltpx);
int scale=firmware->getCapability(SlowScale);
float range=firmware->getCapability(SlowRange);
ui->slowDownSB->setMaximum(range/scale);
ui->slowDownSB->setSingleStep(1.0/scale);
ui->slowDownSB->setDecimals((scale==1 ? 0 :1));
ui->slowDownSB->setMaximum(range / scale);
ui->slowDownSB->setSingleStep(1.0 / scale);
ui->slowDownSB->setDecimals((scale == 1 ? 0 : 1));
ui->slowDownSB->setValue((float)md->speedDown/scale);
ui->slowUpSB->setMaximum(range/scale);
ui->slowUpSB->setSingleStep(1.0/scale);
ui->slowUpSB->setDecimals((scale==1 ? 0 :1));
ui->slowUpSB->setMaximum(range / scale);
ui->slowUpSB->setSingleStep(1.0 / scale);
ui->slowUpSB->setDecimals((scale == 1 ? 0 : 1));
ui->slowUpSB->setValue((float)md->speedUp/scale);
ui->delayDownSB->setMaximum(range/scale);
ui->delayDownSB->setSingleStep(1.0/scale);
ui->delayDownSB->setDecimals((scale==1 ? 0 :1));
ui->delayDownSB->setValue((float)md->delayDown/scale);
ui->delayUpSB->setMaximum(range/scale);
ui->delayUpSB->setSingleStep(1.0/scale);
ui->delayUpSB->setDecimals((scale==1 ? 0 :1));
ui->delayUpSB->setValue((float)md->delayUp/scale);
ui->delayDownSB->setMaximum(range / scale);
ui->delayDownSB->setSingleStep(1.0 / scale);
ui->delayDownSB->setDecimals((scale == 1 ? 0 : 1));
ui->delayDownSB->setValue((float)md->delayDown / scale);
ui->delayUpSB->setMaximum(range / scale);
ui->delayUpSB->setSingleStep(1.0 / scale);
ui->delayUpSB->setDecimals((scale == 1 ? 0 : 1));
ui->delayUpSB->setValue((float)md->delayUp / scale);
QTimer::singleShot(0, this, SLOT(shrink()));
valuesChanged();
@ -147,10 +148,10 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata,
MixerDialog::~MixerDialog()
{
delete ui;
delete gvWeightGroup;
delete gvOffsetGroup;
delete curveGroup;
delete ui;
}
void MixerDialog::changeEvent(QEvent *e)
@ -176,20 +177,20 @@ void MixerDialog::valuesChanged()
ui->MixDR_CB->setEnabled(drVisible);
ui->label_MixDR->setEnabled(drVisible);
}
md->carryTrim = -(ui->trimCB->currentIndex()-1);
md->carryTrim = -(ui->trimCB->currentIndex() - 1);
md->noExpo = ui->MixDR_CB->checkState() ? 0 : 1;
md->swtch = RawSwitch(ui->switchesCB->itemData(ui->switchesCB->currentIndex()).toInt());
md->mixWarn = ui->warningCB->currentIndex();
md->mltpx = (MltpxValue)ui->mltpxCB->currentIndex();
int scale = firmware->getCapability(SlowScale);
md->delayDown = round(ui->delayDownSB->value()*scale);
md->delayUp = round(ui->delayUpSB->value()*scale);
md->speedDown = round(ui->slowDownSB->value()*scale);
md->speedUp = round(ui->slowUpSB->value()*scale);
md->delayDown = round(ui->delayDownSB->value() * scale);
md->delayUp = round(ui->delayUpSB->value() * scale);
md->speedDown = round(ui->slowDownSB->value() * scale);
md->speedUp = round(ui->slowUpSB->value() * scale);
strcpy(md->name, ui->mixerName->text().toLatin1());
md->flightModes = 0;
for (int i=CPN_MAX_FLIGHT_MODES-1; i>=0 ; i--) {
for (int i = CPN_MAX_FLIGHT_MODES - 1; i >= 0 ; i--) {
if (!cb_fp[i]->checkState()) {
md->flightModes++;
}
@ -220,7 +221,7 @@ void MixerDialog::label_phases_customContextMenuRequested(const QPoint & pos)
void MixerDialog::fmClearAll()
{
lock = true;
for (int i=0; i<CPN_MAX_FLIGHT_MODES; i++) {
for (int i = 0; i < CPN_MAX_FLIGHT_MODES; i++) {
cb_fp[i]->setChecked(false);
}
lock = false;
@ -230,7 +231,7 @@ void MixerDialog::fmClearAll()
void MixerDialog::fmSetAll()
{
lock = true;
for (int i=0; i<CPN_MAX_FLIGHT_MODES; i++) {
for (int i = 0; i < CPN_MAX_FLIGHT_MODES; i++) {
cb_fp[i]->setChecked(true);
}
lock = false;
@ -240,7 +241,7 @@ void MixerDialog::fmSetAll()
void MixerDialog::fmInvertAll()
{
lock = true;
for (int i=0; i<CPN_MAX_FLIGHT_MODES; i++) {
for (int i = 0; i < CPN_MAX_FLIGHT_MODES; i++) {
cb_fp[i]->setChecked(!cb_fp[i]->isChecked());
}
lock = false;

View file

@ -26,6 +26,7 @@
class GVarGroup;
class CurveGroup;
class RawItemFilteredModel;
namespace Ui {
class MixerDialog;
@ -34,7 +35,8 @@ namespace Ui {
class MixerDialog : public QDialog {
Q_OBJECT
public:
MixerDialog(QWidget *parent, ModelData & model, MixData *mixdata, GeneralSettings & generalSettings, Firmware * firmware);
MixerDialog(QWidget *parent, ModelData & model, MixData *mixdata, GeneralSettings & generalSettings, Firmware * firmware,
RawItemFilteredModel * rawSourceModel, RawItemFilteredModel * rawSwitchModel);
~MixerDialog();
protected:

View file

@ -20,13 +20,23 @@
#include "mixes.h"
#include "helpers.h"
#include "rawitemfilteredmodel.h"
MixesPanel::MixesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware):
MixesPanel::MixesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware,CommonItemModels * commonItemModels):
ModelPanel(parent, model, generalSettings, firmware),
mixInserted(false),
highlightedSource(0),
modelPrinter(firmware, generalSettings, model)
modelPrinter(firmware, generalSettings, model),
commonItemModels(commonItemModels)
{
rawSourceFilteredModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), ((RawSource::InputSourceGroups | RawSource::ScriptsGroup) & ~ RawSource::NoneGroup), this);
connect(rawSourceFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &MixesPanel::onModelDataAboutToBeUpdated);
connect(rawSourceFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &MixesPanel::onModelDataUpdateComplete);
rawSwitchFilteredModel = new RawItemFilteredModel(commonItemModels->rawSwitchItemModel(), RawSwitch::MixesContext, this);
connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &MixesPanel::onModelDataAboutToBeUpdated);
connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &MixesPanel::onModelDataUpdateComplete);
QGridLayout * mixesLayout = new QGridLayout(this);
mixersListWidget = new MixersListWidget(this, false); // TODO enum
@ -175,8 +185,8 @@ void MixesPanel::gm_openMix(int index)
MixData mixd(model->mixData[index]);
MixerDialog *g = new MixerDialog(this, *model, &mixd, generalSettings, firmware);
if(g->exec()) {
MixerDialog *dlg = new MixerDialog(this, *model, &mixd, generalSettings, firmware, rawSourceFilteredModel, rawSwitchFilteredModel);
if(dlg->exec()) {
model->mixData[index] = mixd;
emit modified();
update();
@ -188,6 +198,7 @@ void MixesPanel::gm_openMix(int index)
mixInserted = false;
update();
}
delete dlg;
}
int MixesPanel::getMixerIndex(unsigned int dch)
@ -529,3 +540,14 @@ void MixesPanel::clearMixes()
update();
}
}
void MixesPanel::onModelDataAboutToBeUpdated()
{
lock = true;
}
void MixesPanel::onModelDataUpdateComplete()
{
update();
lock = false;
}

View file

@ -26,12 +26,15 @@
#include "mixerdialog.h"
#include "modelprinter.h"
class CommonItemModels;
class RawItemFilteredModel;
class MixesPanel : public ModelPanel
{
Q_OBJECT
public:
MixesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware);
MixesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels);
virtual ~MixesPanel();
virtual void update();
@ -50,7 +53,6 @@ class MixesPanel : public ModelPanel
void moveMixDown();
void mixerHighlight();
void mixerlistWidget_customContextMenuRequested(QPoint pos);
void mixerlistWidget_doubleClicked(QModelIndex index);
void mixerlistWidget_KeyPress(QKeyEvent *event);
@ -58,11 +60,17 @@ class MixesPanel : public ModelPanel
void mimeMixerDropped(int index, const QMimeData *data, Qt::DropAction action);
void pasteMixerMimeData(const QMimeData * mimeData, int destIdx);
void onModelDataAboutToBeUpdated();
void onModelDataUpdateComplete();
private:
MixersListWidget * mixersListWidget;
bool mixInserted;
unsigned int highlightedSource;
ModelPrinter modelPrinter;
CommonItemModels * commonItemModels;
RawItemFilteredModel *rawSourceFilteredModel;
RawItemFilteredModel *rawSwitchFilteredModel;
int getMixerIndex(unsigned int dch);
bool gm_insertMix(int idx);

View file

@ -33,6 +33,7 @@
#include "customfunctions.h"
#include "telemetry.h"
#include "appdata.h"
#include "rawitemdatamodels.h"
ModelEdit::ModelEdit(QWidget * parent, RadioData & radioData, int modelId, Firmware * firmware) :
QDialog(parent),
@ -48,33 +49,55 @@ ModelEdit::ModelEdit(QWidget * parent, RadioData & radioData, int modelId, Firmw
setWindowIcon(CompanionIcon("edit.png"));
restoreGeometry(g.modelEditGeo());
ui->pushButton->setIcon(CompanionIcon("simulate.png"));
SetupPanel * setupPanel = new SetupPanel(this, radioData.models[modelId], radioData.generalSettings, firmware);
GeneralSettings &generalSettings = radioData.generalSettings;
ModelData &model = radioData.models[modelId];
commonItemModels = new CommonItemModels(&generalSettings, &model, this);
s1.report("Init");
SetupPanel * setupPanel = new SetupPanel(this, model, generalSettings, firmware, commonItemModels);
addTab(setupPanel, tr("Setup"));
if (firmware->getCapability(Heli))
addTab(new HeliPanel(this, radioData.models[modelId], radioData.generalSettings, firmware), tr("Heli"));
addTab(new FlightModesPanel(this, radioData.models[modelId], radioData.generalSettings, firmware), tr("Flight Modes"));
addTab(new InputsPanel(this, radioData.models[modelId], radioData.generalSettings, firmware), tr("Inputs"));
s1.report("inputs");
addTab(new MixesPanel(this, radioData.models[modelId], radioData.generalSettings, firmware), tr("Mixes"));
s1.report("Setup");
if (firmware->getCapability(Heli)) {
addTab(new HeliPanel(this, model, generalSettings, firmware, commonItemModels), tr("Heli"));
s1.report("Heli");
}
addTab(new FlightModesPanel(this, model, generalSettings, firmware, commonItemModels), tr("Flight Modes"));
s1.report("Flight Modes");
addTab(new InputsPanel(this, model, generalSettings, firmware, commonItemModels), tr("Inputs"));
s1.report("Inputs");
addTab(new MixesPanel(this, model, generalSettings, firmware, commonItemModels), tr("Mixes"));
s1.report("Mixes");
Channels * chnPanel = new Channels(this, radioData.models[modelId], radioData.generalSettings, firmware);
addTab(chnPanel, tr("Outputs"));
ChannelsPanel * channelsPanel = new ChannelsPanel(this, model, generalSettings, firmware, commonItemModels);
addTab(channelsPanel, tr("Outputs"));
s1.report("Outputs");
addTab(new Curves(this, radioData.models[modelId], radioData.generalSettings, firmware), tr("Curves"));
addTab(new LogicalSwitchesPanel(this, radioData.models[modelId], radioData.generalSettings, firmware), tr("Logical Switches"));
s1.report("LS");
addTab(new CustomFunctionsPanel(this, &radioData.models[modelId], radioData.generalSettings, firmware), tr("Special Functions"));
s1.report("CF");
if (firmware->getCapability(Telemetry))
addTab(new TelemetryPanel(this, radioData.models[modelId], radioData.generalSettings, firmware), tr("Telemetry"));
onTabIndexChanged(ui->tabWidget->currentIndex()); // make sure to trigger update on default tab panel
addTab(new CurvesPanel(this, model, generalSettings, firmware, commonItemModels), tr("Curves"));
s1.report("Curves");
connect(setupPanel, &SetupPanel::extendedLimitsToggled, chnPanel, &Channels::refreshExtendedLimits);
addTab(new LogicalSwitchesPanel(this, model, generalSettings, firmware, commonItemModels), tr("Logical Switches"));
s1.report("Logical Switches");
addTab(new CustomFunctionsPanel(this, &model, generalSettings, firmware, commonItemModels), tr("Special Functions"));
s1.report("Special Functions");
if (firmware->getCapability(Telemetry)) {
addTab(new TelemetryPanel(this, model, generalSettings, firmware, commonItemModels), tr("Telemetry"));
s1.report("Telemetry");
}
connect(setupPanel, &SetupPanel::extendedLimitsToggled, channelsPanel, &ChannelsPanel::refreshExtendedLimits);
connect(ui->tabWidget, &QTabWidget::currentChanged, this, &ModelEdit::onTabIndexChanged);
connect(ui->pushButton, &QPushButton::clicked, this, &ModelEdit::launchSimulation);
s1.report("end");
onTabIndexChanged(ui->tabWidget->currentIndex()); // make sure to trigger update on default tab panel
gStopwatch.report("ModelEdit end constructor");
}

View file

@ -25,6 +25,7 @@
#include "genericpanel.h"
class RadioData;
class CommonItemModels;
namespace Ui {
class ModelEdit;
@ -62,6 +63,7 @@ class ModelEdit : public QDialog
RadioData & radioData;
Firmware * firmware;
QVector<GenericPanel *> panels;
CommonItemModels * commonItemModels;
void addTab(GenericPanel *panel, QString text);
void launchSimulation();

View file

@ -31,13 +31,14 @@
#include <QDir>
TimerPanel::TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, Firmware * firmware, QWidget * prevFocus, RawSwitchFilterItemModel * switchModel):
TimerPanel::TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, Firmware * firmware, QWidget * prevFocus, RawItemFilteredModel * rawSwitchFilteredModel):
ModelPanel(parent, model, generalSettings, firmware),
timer(timer),
ui(new Ui::Timer)
{
ui->setupUi(this);
connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &TimerPanel::onModelDataAboutToBeUpdated);
connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &TimerPanel::onModelDataUpdateComplete);
lock = true;
@ -48,11 +49,10 @@ TimerPanel::TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, Ge
}
else {
ui->name->setMaxLength(length);
//ui->name->setText(timer.name);
}
// Mode
ui->mode->setModel(switchModel);
ui->mode->setModel(rawSwitchFilteredModel);
ui->mode->setCurrentIndex(ui->mode->findData(timer.mode.toValue()));
connect(ui->mode, SIGNAL(activated(int)), this, SLOT(onModeChanged(int)));
@ -94,6 +94,7 @@ TimerPanel::~TimerPanel()
void TimerPanel::update()
{
lock = true;
ui->name->setText(timer.name);
int hour = timer.val / 3600;
@ -114,7 +115,7 @@ void TimerPanel::update()
pvalue -= hours * 3600;
int minutes = pvalue / 60;
int seconds = pvalue % 60;
ui->persistentValue->setText(QString(" %1(%2:%3:%4)").arg(sign<0 ? "-" :" ").arg(hours, 2, 10, QLatin1Char('0')).arg(minutes, 2, 10, QLatin1Char('0')).arg(seconds, 2, 10, QLatin1Char('0')));
ui->persistentValue->setText(QString(" %1(%2:%3:%4)").arg(sign < 0 ? "-" :" ").arg(hours, 2, 10, QLatin1Char('0')).arg(minutes, 2, 10, QLatin1Char('0')).arg(seconds, 2, 10, QLatin1Char('0')));
}
ui->countdownBeep->updateValue();
@ -131,7 +132,7 @@ QWidget * TimerPanel::getLastFocus()
void TimerPanel::on_value_editingFinished()
{
if (!lock) {
unsigned val = ui->value->time().hour()*3600 + ui->value->time().minute()*60 + ui->value->time().second();
unsigned val = ui->value->time().hour() * 3600 + ui->value->time().minute() * 60 + ui->value->time().second();
if (timer.val != val) {
timer.val = val;
emit modified();
@ -165,11 +166,23 @@ void TimerPanel::on_name_editingFinished()
if (QString(timer.name) != ui->name->text()) {
int length = ui->name->maxLength();
strncpy(timer.name, ui->name->text().toLatin1(), length);
emit nameChanged();
emit modified();
}
}
}
void TimerPanel::onModelDataAboutToBeUpdated()
{
lock = true;
}
void TimerPanel::onModelDataUpdateComplete()
{
update();
lock = false;
}
/******************************************************************************/
#define FAILSAFE_CHANNEL_HOLD 2000
@ -237,19 +250,19 @@ ModulePanel::ModulePanel(QWidget * parent, ModelData & model, ModuleData & modul
}
// The protocols available on this board
for (unsigned int i=0; i<PULSES_PROTOCOL_LAST; i++) {
for (unsigned int i = 0; i < PULSES_PROTOCOL_LAST; i++) {
if (firmware->isAvailable((PulsesProtocol) i, moduleIdx)) {
ui->protocol->addItem(ModuleData::protocolToString(i), i);
if (i == module.protocol)
ui->protocol->setCurrentIndex(ui->protocol->count()-1);
ui->protocol->setCurrentIndex(ui->protocol->count() - 1);
}
}
for (int i=0; i<=MODULE_SUBTYPE_MULTI_LAST; i++) {
for (int i = 0; i <= MODULE_SUBTYPE_MULTI_LAST; i++) {
if (i == MODULE_SUBTYPE_MULTI_SCANNER)
continue;
ui->multiProtocol->addItem(Multiprotocols::protocolToString(i), i);
}
for (int i=MODULE_SUBTYPE_MULTI_LAST + 1; i <= 124; i++) {
for (int i = MODULE_SUBTYPE_MULTI_LAST + 1; i <= 124; i++) {
ui->multiProtocol->addItem(QString::number(i + 3), i);
}
@ -327,7 +340,7 @@ void ModulePanel::setupFailsafes()
else {
QLabel * label = new QLabel(this);
label->setProperty("index", i);
label->setText(QString::number(i+1));
label->setText(QString::number(i + 1));
QComboBox * combo = new QComboBox(this);
combo->setProperty("index", i);
@ -506,7 +519,7 @@ void ModulePanel::update()
ui->ppmFrameLength->setVisible(mask & MASK_SBUSPPM_FIELDS);
ui->ppmFrameLength->setMinimum(module.channelsCount * (model->extendedLimits ? 2.250 : 2)+3.5);
ui->ppmFrameLength->setMaximum(firmware->getCapability(PPMFrameLength));
ui->ppmFrameLength->setValue(22.5+((double)module.ppm.frameLength)*0.5);
ui->ppmFrameLength->setValue(22.5 + ((double)module.ppm.frameLength) * 0.5);
// Antenna mode on Horus and XLite
if (mask & MASK_ANTENNA) {
@ -600,17 +613,17 @@ void ModulePanel::update()
ui->registrationIdLabel->setVisible(mask & MASK_ACCESS);
ui->registrationId->setVisible(mask & MASK_ACCESS);
ui->rx1Label->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<0)));
ui->clearRx1->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<0)));
ui->rx1->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<0)));
ui->rx1Label->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1 << 0)));
ui->clearRx1->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1 << 0)));
ui->rx1->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1 << 0)));
ui->rx2Label->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<1)));
ui->clearRx2->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<1)));
ui->rx2->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<1)));
ui->rx2Label->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1 << 1)));
ui->clearRx2->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1 << 1)));
ui->rx2->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1 << 1)));
ui->rx3Label->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<2)));
ui->clearRx3->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<2)));
ui->rx3->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1<<2)));
ui->rx3Label->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1 << 2)));
ui->clearRx3->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1 << 2)));
ui->rx3->setVisible((mask & MASK_ACCESS) && (module.access.receivers & (1 << 2)));
// Failsafes
ui->label_failsafeMode->setVisible(mask & MASK_FAILSAFES);
@ -703,8 +716,8 @@ void ModulePanel::on_channelsCount_editingFinished()
{
if (!lock && module.channelsCount != ui->channelsCount->value()) {
module.channelsCount = ui->channelsCount->value();
update();
emit channelsRangeChanged();
update();
emit modified();
}
}
@ -713,8 +726,8 @@ void ModulePanel::on_channelsStart_editingFinished()
{
if (!lock && module.channelsStart != (unsigned)ui->channelsStart->value() - 1) {
module.channelsStart = (unsigned)ui->channelsStart->value() - 1;
update();
emit channelsRangeChanged();
update();
emit modified();
}
}
@ -738,7 +751,7 @@ void ModulePanel::on_rxNumber_editingFinished()
void ModulePanel::on_ppmFrameLength_editingFinished()
{
int val = (ui->ppmFrameLength->value()-22.5) / 0.5;
int val = (ui->ppmFrameLength->value() - 22.5) / 0.5;
if (module.ppm.frameLength != val) {
module.ppm.frameLength = val;
emit modified();
@ -762,8 +775,8 @@ void ModulePanel::onMultiProtocolChanged(int index)
module.multi.rfProtocol = (unsigned int)rfProtocol;
unsigned int maxSubTypes = multiProtocols.getProtocol(index).numSubTypes();
if (rfProtocol > MODULE_SUBTYPE_MULTI_LAST)
maxSubTypes=8;
module.subType = std::min(module.subType, maxSubTypes -1);
maxSubTypes = 8;
module.subType = std::min(module.subType, maxSubTypes - 1);
module.channelsCount = module.getMaxChannelCount();
update();
emit modified();
@ -957,19 +970,19 @@ void ModulePanel::onClearAccessRxClicked()
QPushButton *button = qobject_cast<QPushButton *>(sender());
if (button == ui->clearRx1) {
module.access.receivers &= ~(1<<0);
module.access.receivers &= ~(1 << 0);
ui->rx1->clear();
update();
emit modified();
}
else if (button == ui->clearRx2) {
module.access.receivers &= ~(1<<1);
module.access.receivers &= ~(1 << 1);
ui->rx2->clear();
update();
emit modified();
}
else if (button == ui->clearRx3) {
module.access.receivers &= ~(1<<2);
module.access.receivers &= ~(1 << 2);
ui->rx3->clear();
update();
emit modified();
@ -978,18 +991,20 @@ void ModulePanel::onClearAccessRxClicked()
/******************************************************************************/
SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware):
SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels):
ModelPanel(parent, model, generalSettings, firmware),
ui(new Ui::Setup)
ui(new Ui::Setup),
commonItemModels(commonItemModels)
{
ui->setupUi(this);
rawSwitchFilteredModel = new RawItemFilteredModel(commonItemModels->rawSwitchItemModel(), RawSwitch::TimersContext, this);
Board::Type board = firmware->getBoard();
lock = true;
memset(modules, 0, sizeof(modules));
ui->setupUi(this);
QRegExp rx(CHAR_FOR_NAMES_REGEX);
ui->name->setValidator(new QRegExpValidator(rx, this));
ui->name->setMaxLength(firmware->getCapability(ModelName));
@ -1007,7 +1022,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
foreach ( QString file, qd.entryList(filters, QDir::Files) ) {
QFileInfo fi(file);
QString temp = fi.fileName();
if (!items.contains(temp) && temp.length() <= 6+4) {
if (!items.contains(temp) && temp.length() <= 6 + 4) {
items.append(temp);
}
}
@ -1017,7 +1032,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
foreach (QString file, qd.entryList(filters, QDir::Files)) {
QFileInfo fi(file);
QString temp = fi.completeBaseName();
if (!items.contains(temp) && temp.length() <= 10+4) {
if (!items.contains(temp) && temp.length() <= 10 + 4) {
items.append(temp);
}
}
@ -1030,7 +1045,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
foreach (QString file, items) {
ui->image->addItem(file);
if (file == model.bitmap) {
ui->image->setCurrentIndex(ui->image->count()-1);
ui->image->setCurrentIndex(ui->image->count() - 1);
QString fileName = path;
fileName.append(model.bitmap);
if (!IS_FAMILY_HORUS_OR_T16(board))
@ -1062,18 +1077,16 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
}
QWidget * prevFocus = ui->image;
RawSwitchFilterItemModel * swModel = new RawSwitchFilterItemModel(&generalSettings, &model, RawSwitch::TimersContext, this);
connect(this, &SetupPanel::updated, swModel, &RawSwitchFilterItemModel::update);
timersCount = firmware->getCapability(Timers);
for (int i = 0; i < CPN_MAX_TIMERS; i++) {
if (i < timersCount) {
timers[i] = new TimerPanel(this, model, model.timers[i], generalSettings, firmware, prevFocus, swModel);
timers[i] = new TimerPanel(this, model, model.timers[i], generalSettings, firmware, prevFocus, rawSwitchFilteredModel);
ui->gridLayout->addWidget(timers[i], 1+i, 1);
connect(timers[i], &TimerPanel::modified, this, &SetupPanel::modified);
connect(timers[i], &TimerPanel::nameChanged, this, &SetupPanel::onTimerNameChanged);
connect(this, &SetupPanel::updated, timers[i], &TimerPanel::update);
connect(this, &SetupPanel::timerUpdated, timers[i], &TimerPanel::update);
prevFocus = timers[i]->getLastFocus();
// TODO more reliable method required
QLabel *label = findChild<QLabel *>(QString("label_timer%1").arg(i + 1));
@ -1095,7 +1108,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
if (firmware->getCapability(HasTopLcd)) {
ui->toplcdTimer->setField(model.toplcdTimer, this);
for (int i = 0; i < CPN_MAX_TIMERS; i++) {
if (i<timersCount) {
if (i < timersCount) {
ui->toplcdTimer->addItem(tr("Timer %1").arg(i + 1), i);
}
}
@ -1118,12 +1131,12 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
prevFocus = ui->trimsDisplay;
int analogs = CPN_MAX_STICKS + getBoardCapability(board, Board::Pots) + getBoardCapability(board, Board::Sliders);
int genAryIdx = 0;
for (int i=0; i < analogs + firmware->getCapability(RotaryEncoders); i++) {
for (int i = 0; i < analogs + firmware->getCapability(RotaryEncoders); i++) {
RawSource src((i < analogs) ? SOURCE_TYPE_STICK : SOURCE_TYPE_ROTARY_ENCODER, (i < analogs) ? i : analogs - i);
QCheckBox * checkbox = new QCheckBox(this);
checkbox->setProperty("index", i);
checkbox->setText(src.toString(&model, &generalSettings));
ui->centerBeepLayout->addWidget(checkbox, 0, i+1);
ui->centerBeepLayout->addWidget(checkbox, 0, i + 1);
connect(checkbox, SIGNAL(toggled(bool)), this, SLOT(onBeepCenterToggled(bool)));
centerBeepCheckboxes << checkbox;
if (IS_HORUS_OR_TARANIS(board)) {
@ -1139,7 +1152,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
}
// Startup switches warnings
for (int i=0; i<getBoardCapability(board, Board::Switches); i++) {
for (int i = 0; i < getBoardCapability(board, Board::Switches); i++) {
Board::SwitchInfo switchInfo = Boards::getSwitchInfo(board, i);
switchInfo.config = Board::SwitchType(generalSettings.switchConfig[i]);
if (switchInfo.config == Board::SWITCH_NOT_AVAILABLE || switchInfo.config == Board::SWITCH_TOGGLE) {
@ -1163,11 +1176,11 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
label->setText(src.toString(&model, &generalSettings));
slider->setMaximum(switchInfo.config == Board::SWITCH_3POS ? 2 : 1);
cb->setProperty("index", i);
ui->switchesStartupLayout->addWidget(label, 0, i+1);
ui->switchesStartupLayout->addWidget(label, 0, i + 1);
ui->switchesStartupLayout->setAlignment(label, Qt::AlignCenter);
ui->switchesStartupLayout->addWidget(slider, 1, i+1);
ui->switchesStartupLayout->addWidget(slider, 1, i + 1);
ui->switchesStartupLayout->setAlignment(slider, Qt::AlignCenter);
ui->switchesStartupLayout->addWidget(cb, 2, i+1);
ui->switchesStartupLayout->addWidget(cb, 2, i + 1);
ui->switchesStartupLayout->setAlignment(cb, Qt::AlignCenter);
connect(slider, SIGNAL(valueChanged(int)), this, SLOT(startupSwitchEdited(int)));
connect(cb, SIGNAL(toggled(bool)), this, SLOT(startupSwitchToggled(bool)));
@ -1181,12 +1194,12 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
// Pot warnings
prevFocus = ui->potWarningMode;
if (IS_HORUS_OR_TARANIS(board)) {
for (int i=0; i<getBoardCapability(board, Board::Pots)+getBoardCapability(board, Board::Sliders); i++) {
for (int i = 0; i < getBoardCapability(board, Board::Pots) + getBoardCapability(board, Board::Sliders); i++) {
RawSource src(SOURCE_TYPE_STICK, CPN_MAX_STICKS + i);
QCheckBox * cb = new QCheckBox(this);
cb->setProperty("index", i);
cb->setText(src.toString(&model, &generalSettings));
ui->potWarningLayout->addWidget(cb, 0, i+1);
ui->potWarningLayout->addWidget(cb, 0, i + 1);
connect(cb, SIGNAL(toggled(bool)), this, SLOT(potWarningToggled(bool)));
potWarningCheckboxes << cb;
if (src.isPot(&genAryIdx) && !generalSettings.isPotAvailable(genAryIdx)) {
@ -1264,7 +1277,7 @@ void SetupPanel::on_extendedTrims_toggled(bool checked)
void SetupPanel::on_trimIncrement_currentIndexChanged(int index)
{
model->trimInc = index-2;
model->trimInc = index - 2;
emit modified();
}
@ -1341,13 +1354,13 @@ void SetupPanel::populateThrottleSourceCB()
ui->throttleSource->clear();
ui->throttleSource->addItem(tr("THR"), 0);
int idx=1;
for (int i=0; i<getBoardCapability(board, Board::Pots)+getBoardCapability(board, Board::Sliders); i++, idx++) {
if (RawSource(SOURCE_TYPE_STICK,4+i).isAvailable(model,&generalSettings,board)) {
ui->throttleSource->addItem(firmware->getAnalogInputName(4+i), idx);
int idx = 1;
for (int i = 0; i < getBoardCapability(board, Board::Pots) + getBoardCapability(board, Board::Sliders); i++, idx++) {
if (RawSource(SOURCE_TYPE_STICK, 4 + i).isAvailable(model, &generalSettings, board)) {
ui->throttleSource->addItem(firmware->getAnalogInputName(4 + i), idx);
}
}
for (int i=0; i<firmware->getCapability(Outputs); i++, idx++) {
for (int i = 0; i < firmware->getCapability(Outputs); i++, idx++) {
ui->throttleSource->addItem(RawSource(SOURCE_TYPE_CH, i).toString(model, &generalSettings), idx);
}
@ -1394,7 +1407,7 @@ void SetupPanel::update()
updatePotWarnings();
}
for (int i=0; i<CPN_MAX_MODULES+1; i++) {
for (int i = 0; i < CPN_MAX_MODULES + 1; i++) {
if (modules[i]) {
modules[i]->update();
}
@ -1405,7 +1418,7 @@ void SetupPanel::update()
void SetupPanel::updateBeepCenter()
{
for (int i=0; i<centerBeepCheckboxes.size(); i++) {
for (int i = 0; i < centerBeepCheckboxes.size(); i++) {
centerBeepCheckboxes[i]->setChecked(model->beepANACenter & (0x01 << i));
}
}
@ -1417,20 +1430,20 @@ void SetupPanel::updateStartupSwitches()
uint64_t switchStates = model->switchWarningStates;
uint64_t value;
for (int i=0; i<startupSwitchesSliders.size(); i++) {
for (int i = 0; i < startupSwitchesSliders.size(); i++) {
QSlider * slider = startupSwitchesSliders[i];
QCheckBox * cb = startupSwitchesCheckboxes[i];
int index = slider->property("index").toInt();
bool enabled = !(model->switchWarningEnable & (1 << index));
if (IS_HORUS_OR_TARANIS(firmware->getBoard())) {
value = (switchStates >> (2*index)) & 0x03;
value = (switchStates >> (2 * index)) & 0x03;
if (generalSettings.switchConfig[index] != Board::SWITCH_3POS && value == 2) {
value = 1;
}
}
else {
value = (i==0 ? switchStates & 0x3 : switchStates & 0x1);
switchStates >>= (i==0 ? 2 : 1);
value = (i == 0 ? switchStates & 0x3 : switchStates & 0x1);
switchStates >>= (i == 0 ? 2 : 1);
}
slider->setValue(value);
slider->setEnabled(enabled);
@ -1456,7 +1469,7 @@ void SetupPanel::startupSwitchEdited(int value)
mask = 0x03;
}
else {
shift = index+1;
shift = index + 1;
mask = 0x01ull << shift;
}
}
@ -1497,7 +1510,7 @@ void SetupPanel::updatePotWarnings()
{
lock = true;
ui->potWarningMode->setCurrentIndex(model->potsWarningMode);
for (int i=0; i<potWarningCheckboxes.size(); i++) {
for (int i = 0; i < potWarningCheckboxes.size(); i++) {
QCheckBox *checkbox = potWarningCheckboxes[i];
int index = checkbox->property("index").toInt();
checkbox->setChecked(!model->potsWarnEnabled[index]);
@ -1627,7 +1640,7 @@ void SetupPanel::cmTimerClear(bool prompt)
model->timers[selectedTimerIndex].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_TIMER, ModelData::REF_UPD_ACT_CLEAR, selectedTimerIndex);
emit timerUpdated();
updateItemModels();
emit modified();
}
@ -1640,7 +1653,7 @@ void SetupPanel::cmTimerClearAll()
model->timers[i].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_TIMER, ModelData::REF_UPD_ACT_CLEAR, i);
}
emit timerUpdated();
updateItemModels();
emit modified();
}
@ -1674,7 +1687,7 @@ void SetupPanel::cmTimerDelete()
}
model->timers[maxidx].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_TIMER, ModelData::REF_UPD_ACT_SHIFT, selectedTimerIndex, 0, -1);
emit timerUpdated();
updateItemModels();
emit modified();
}
@ -1687,7 +1700,7 @@ void SetupPanel::cmTimerInsert()
}
model->timers[selectedTimerIndex].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_TIMER, ModelData::REF_UPD_ACT_SHIFT, selectedTimerIndex, 0, 1);
emit timerUpdated();
updateItemModels();
emit modified();
}
@ -1707,7 +1720,7 @@ void SetupPanel::cmTimerPaste()
if (hasTimerClipboardData(&data)) {
TimerData *td = &model->timers[selectedTimerIndex];
memcpy(td, data.constData(), sizeof(TimerData));
emit timerUpdated();
updateItemModels();
emit modified();
}
}
@ -1721,7 +1734,17 @@ void SetupPanel::swapTimerData(int idx1, int idx2)
memcpy(td2, td1, sizeof(TimerData));
memcpy(td1, &tdtmp, sizeof(TimerData));
model->updateAllReferences(ModelData::REF_UPD_TYPE_TIMER, ModelData::REF_UPD_ACT_SWAP, idx1, idx2);
emit timerUpdated();
updateItemModels();
emit modified();
}
}
void SetupPanel::onTimerNameChanged()
{
updateItemModels();
}
void SetupPanel::updateItemModels()
{
commonItemModels->update(CommonItemModels::RMO_TIMERS);
}

View file

@ -26,7 +26,8 @@
constexpr char MIMETYPE_TIMER[] = "application/x-companion-timer";
class RawSwitchFilterItemModel;
class CommonItemModels;
class RawItemFilteredModel;
namespace Ui {
class Setup;
@ -39,7 +40,7 @@ class TimerPanel : public ModelPanel
Q_OBJECT
public:
TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, Firmware * firmware, QWidget *prevFocus, RawSwitchFilterItemModel * switchModel);
TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, Firmware * firmware, QWidget *prevFocus, RawItemFilteredModel * switchModel);
virtual ~TimerPanel();
virtual void update();
@ -50,6 +51,11 @@ class TimerPanel : public ModelPanel
void on_value_editingFinished();
void on_minuteBeep_toggled(bool checked);
void on_name_editingFinished();
void onModelDataAboutToBeUpdated();
void onModelDataUpdateComplete();
signals:
void nameChanged();
private:
TimerData & timer;
@ -125,7 +131,7 @@ class SetupPanel : public ModelPanel
Q_OBJECT
public:
SetupPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware);
SetupPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels);
virtual ~SetupPanel();
virtual void update();
@ -133,7 +139,6 @@ class SetupPanel : public ModelPanel
signals:
void extendedLimitsToggled();
void updated();
void timerUpdated();
private slots:
void on_name_editingFinished();
@ -164,6 +169,7 @@ class SetupPanel : public ModelPanel
void cmTimerPaste();
void cmTimerMoveDown();
void cmTimerMoveUp();
void onTimerNameChanged();
private:
Ui::Setup *ui;
@ -185,6 +191,9 @@ class SetupPanel : public ModelPanel
bool moveTimerDownAllowed() const;
bool moveTimerUpAllowed() const;
void swapTimerData(int idx1, int idx2);
};
CommonItemModels * commonItemModels;
RawItemFilteredModel * rawSwitchFilteredModel;
void updateItemModels();
};
#endif // _SETUP_H_

View file

@ -28,18 +28,20 @@
#include <TimerEdit>
TelemetryCustomScreen::TelemetryCustomScreen(QWidget *parent, ModelData & model, FrSkyScreenData & screen, GeneralSettings & generalSettings, Firmware * firmware, RawSourceFilterItemModel * srcModel):
TelemetryCustomScreen::TelemetryCustomScreen(QWidget *parent, ModelData & model, FrSkyScreenData & screen, GeneralSettings & generalSettings, Firmware * firmware, RawItemFilteredModel * rawSourceModel):
ModelPanel(parent, model, generalSettings, firmware),
ui(new Ui::TelemetryCustomScreen),
screen(screen)
{
ui->setupUi(this);
connect(rawSourceModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &TelemetryCustomScreen::onModelDataAboutToBeUpdated);
connect(rawSourceModel, &RawItemFilteredModel::dataUpdateComplete, this, &TelemetryCustomScreen::onModelDataUpdateComplete);
for (int l = 0; l < firmware->getCapability(TelemetryCustomScreensLines); l++) {
for (int c = 0; c < firmware->getCapability(TelemetryCustomScreensFieldsPerLine); c++) {
fieldsCB[l][c] = new QComboBox(this);
fieldsCB[l][c]->setProperty("index", c + (l << 8));
fieldsCB[l][c]->setModel(srcModel);
fieldsCB[l][c]->setModel(rawSourceModel);
ui->screenNumsLayout->addWidget(fieldsCB[l][c], l, c, 1, 1);
connect(fieldsCB[l][c], SIGNAL(activated(int)), this, SLOT(customFieldChanged(int)));
}
@ -48,7 +50,7 @@ TelemetryCustomScreen::TelemetryCustomScreen(QWidget *parent, ModelData & model,
for (int l = 0; l < firmware->getCapability(TelemetryCustomScreensBars); l++) {
barsCB[l] = new QComboBox(this);
barsCB[l]->setProperty("index", l);
barsCB[l]->setModel(srcModel);
barsCB[l]->setModel(rawSourceModel);
connect(barsCB[l], SIGNAL(activated(int)), this, SLOT(barSourceChanged(int)));
ui->screenBarsLayout->addWidget(barsCB[l], l, 0, 1, 1);
@ -287,6 +289,17 @@ void TelemetryCustomScreen::barTimeChanged()
}
}
void TelemetryCustomScreen::onModelDataAboutToBeUpdated()
{
lock = true;
}
void TelemetryCustomScreen::onModelDataUpdateComplete()
{
update();
lock = false;
}
/******************************************************/
TelemetrySensorPanel::TelemetrySensorPanel(QWidget *parent, SensorData & sensor, int sensorIndex, int sensorCapability, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware):
@ -305,6 +318,7 @@ TelemetrySensorPanel::TelemetrySensorPanel(QWidget *parent, SensorData & sensor,
QFontMetrics *f = new QFontMetrics(QFont());
QSize sz;
sz = f->size(Qt::TextSingleLine, "TELE00");
delete f;
ui->numLabel->setMinimumWidth(sz.width());
ui->numLabel->setContextMenuPolicy(Qt::CustomContextMenu);
ui->numLabel->setToolTip(tr("Popup menu available"));
@ -505,7 +519,6 @@ void TelemetrySensorPanel::on_name_editingFinished()
if (!lock) {
strcpy(sensor.label, ui->name->text().toLatin1());
emit dataModified();
emit modified();
}
}
@ -535,7 +548,6 @@ void TelemetrySensorPanel::on_formula_currentIndexChanged(int index)
sensor.unit = SensorData::UNIT_METERS;
}
emit dataModified();
emit modified();
}
}
@ -631,7 +643,6 @@ void TelemetrySensorPanel::cmPaste()
if (hasClipboardData(&data)) {
memcpy(&sensor, data.constData(), sizeof(SensorData));
emit dataModified();
emit modified();
}
}
@ -645,7 +656,6 @@ void TelemetrySensorPanel::cmClear(bool prompt)
sensor.clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_CLEAR, selectedIndex);
emit dataModified();
emit modified();
}
void TelemetrySensorPanel::cmClearAll()
@ -678,11 +688,13 @@ void TelemetrySensorPanel::cmMoveDown()
/******************************************************/
TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware):
TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels):
ModelPanel(parent, model, generalSettings, firmware),
ui(new Ui::Telemetry)
ui(new Ui::Telemetry),
commonItemModels(commonItemModels)
{
ui->setupUi(this);
rawSourceFilteredModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), this);
sensorCapability = firmware->getCapability(Sensors);
if (sensorCapability > CPN_MAX_SENSORS) // TODO should be role of getCapability
@ -696,11 +708,12 @@ TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettin
ui->varioCenterSilent->setField(model.frsky.varioCenterSilent, this);
ui->A1GB->hide();
ui->A2GB->hide();
for (int i = 0; i < sensorCapability; ++i) {
TelemetrySensorPanel * panel = new TelemetrySensorPanel(this, model.sensorData[i], i, sensorCapability, model, generalSettings, firmware);
ui->sensorsLayout->addWidget(panel);
sensorPanels[i] = panel;
connect(panel, SIGNAL(dataModified()), this, SLOT(update()));
connect(panel, SIGNAL(dataModified()), this, SLOT(on_dataModifiedSensor()));
connect(panel, SIGNAL(modified()), this, SLOT(onModified()));
connect(panel, SIGNAL(clearAllSensors()), this, SLOT(on_clearAllSensors()));
connect(panel, SIGNAL(insertSensor(int)), this, SLOT(on_insertSensor(int)));
@ -717,15 +730,11 @@ TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettin
ui->topbarGB->hide();
}
RawSourceFilterItemModel * srcModel = (new RawSourceFilterItemModel(&generalSettings, &model, this));
connect(this, &TelemetryPanel::updated, srcModel, &RawSourceFilterItemModel::update);
for (int i = 0; i < firmware->getCapability(TelemetryCustomScreens); i++) {
TelemetryCustomScreen * tab = new TelemetryCustomScreen(this, model, model.frsky.screens[i], generalSettings, firmware, srcModel);
TelemetryCustomScreen * tab = new TelemetryCustomScreen(this, model, model.frsky.screens[i], generalSettings, firmware, rawSourceFilteredModel);
ui->customScreens->addTab(tab, tr("Telemetry screen %1").arg(i + 1));
telemetryCustomScreens[i] = tab;
connect(tab, &TelemetryCustomScreen::modified, this, &TelemetryPanel::onModified);
connect(this, &TelemetryPanel::updated, tab, &TelemetryCustomScreen::update);
}
disableMouseScrolling();
@ -759,79 +768,78 @@ void TelemetryPanel::update()
sensorPanels[i]->update();
}
emit updated();
for (int i = 0; i < firmware->getCapability(TelemetryCustomScreens); i++) {
telemetryCustomScreens[i]->update();
}
}
void TelemetryPanel::setup()
{
QString firmware_id = g.profile[g.id()].fwType();
lock = true;
lock = true;
ui->telemetryProtocol->addItem(tr("FrSky S.PORT"), 0);
ui->telemetryProtocol->addItem(tr("FrSky D"), 1);
if (IS_9XRPRO(firmware->getBoard()) ||
(IS_TARANIS(firmware->getBoard()) && generalSettings.auxSerialMode == 2)) {
ui->telemetryProtocol->addItem(tr("FrSky D (cable)"), 2);
}
ui->telemetryProtocol->setCurrentIndex(model->telemetryProtocol);
ui->ignoreSensorIds->setField(model->frsky.ignoreSensorIds, this);
ui->disableTelemetryAlarms->setField(model->rssiAlarms.disabled);
ui->telemetryProtocol->addItem(tr("FrSky S.PORT"), 0);
ui->telemetryProtocol->addItem(tr("FrSky D"), 1);
if (IS_9XRPRO(firmware->getBoard()) ||
(IS_TARANIS(firmware->getBoard()) && generalSettings.auxSerialMode == 2)) {
ui->telemetryProtocol->addItem(tr("FrSky D (cable)"), 2);
}
ui->telemetryProtocol->setCurrentIndex(model->telemetryProtocol);
ui->ignoreSensorIds->setField(model->frsky.ignoreSensorIds, this);
ui->disableTelemetryAlarms->setField(model->rssiAlarms.disabled);
ui->rssiAlarmWarningSB->setValue(model->rssiAlarms.warning);
ui->rssiAlarmCriticalSB->setValue(model->rssiAlarms.critical);
ui->rssiAlarmWarningSB->setValue(model->rssiAlarms.warning);
ui->rssiAlarmCriticalSB->setValue(model->rssiAlarms.critical);
ui->rssiSourceLabel->show();
ui->rssiSourceLabel->setText(tr("Source"));
ui->rssiSourceCB->setField(model->rssiSource, this);
ui->rssiSourceCB->show();
populateTelemetrySourcesComboBox(ui->rssiSourceCB, model, false);
ui->rssiSourceLabel->show();
ui->rssiSourceLabel->setText(tr("Source"));
ui->rssiSourceCB->setField(model->rssiSource, this);
ui->rssiSourceCB->show();
populateTelemetrySourcesComboBox(ui->rssiSourceCB, model, false);
ui->rssiAlarmWarningCB->hide();
ui->rssiAlarmCriticalCB->hide();
ui->rssiAlarmWarningLabel->setText(tr("Low Alarm"));
ui->rssiAlarmCriticalLabel->setText(tr("Critical Alarm"));
ui->rssiAlarmWarningCB->hide();
ui->rssiAlarmCriticalCB->hide();
ui->rssiAlarmWarningLabel->setText(tr("Low Alarm"));
ui->rssiAlarmCriticalLabel->setText(tr("Critical Alarm"));
int varioCap = firmware->getCapability(HasVario);
if (!varioCap) {
ui->varioLimitMax_DSB->hide();
if (!firmware->getCapability(HasVario)) {
ui->varioLimitMax_DSB->hide();
ui->varioLimitMin_DSB->hide();
ui->varioLimitCenterMin_DSB->hide();
ui->varioLimitCenterMax_DSB->hide();
ui->varioLimit_label->hide();
ui->VarioLabel_1->hide();
ui->VarioLabel_2->hide();
ui->VarioLabel_3->hide();
ui->VarioLabel_4->hide();
ui->varioSource->hide();
ui->varioSource_label->hide();
}
else {
if (!firmware->getCapability(HasVarioSink)) {
ui->varioLimitMin_DSB->hide();
ui->varioLimitCenterMin_DSB->hide();
ui->varioLimitCenterMax_DSB->hide();
ui->varioLimit_label->hide();
ui->VarioLabel_1->hide();
ui->VarioLabel_2->hide();
ui->VarioLabel_3->hide();
ui->VarioLabel_4->hide();
ui->varioSource->hide();
ui->varioSource_label->hide();
}
else {
if (!firmware->getCapability(HasVarioSink)) {
ui->varioLimitMin_DSB->hide();
ui->varioLimitCenterMin_DSB->hide();
ui->VarioLabel_1->hide();
ui->VarioLabel_2->hide();
}
ui->varioLimitMin_DSB->setValue(model->frsky.varioMin - 10);
ui->varioLimitMax_DSB->setValue(model->frsky.varioMax + 10);
ui->varioLimitCenterMax_DSB->setValue((model->frsky.varioCenterMax / 10.0) + 0.5);
ui->varioLimitCenterMin_DSB->setValue((model->frsky.varioCenterMin / 10.0) - 0.5);
}
ui->varioLimitMin_DSB->setValue(model->frsky.varioMin - 10);
ui->varioLimitMax_DSB->setValue(model->frsky.varioMax + 10);
ui->varioLimitCenterMax_DSB->setValue((model->frsky.varioCenterMax / 10.0) + 0.5);
ui->varioLimitCenterMin_DSB->setValue((model->frsky.varioCenterMin / 10.0) - 0.5);
}
ui->altimetryGB->setVisible(firmware->getCapability(HasVario)),
ui->frskyProtoCB->setDisabled(firmware->getCapability(NoTelemetryProtocol));
ui->altimetryGB->setVisible(firmware->getCapability(HasVario)),
ui->frskyProtoCB->setDisabled(firmware->getCapability(NoTelemetryProtocol));
if (firmware->getCapability(Telemetry)) {
ui->frskyProtoCB->addItem(tr("Winged Shadow How High"));
}
else {
ui->frskyProtoCB->addItem(tr("Winged Shadow How High (not supported)"));
}
if (firmware->getCapability(Telemetry)) {
ui->frskyProtoCB->addItem(tr("Winged Shadow How High"));
}
else {
ui->frskyProtoCB->addItem(tr("Winged Shadow How High (not supported)"));
}
ui->variousGB->hide();
ui->variousGB->hide();
lock = false;
lock = false;
}
void TelemetryPanel::populateVarioSource()
@ -972,6 +980,7 @@ void TelemetryPanel::on_clearAllSensors()
model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_CLEAR, i);
}
updateItemModels();
update();
emit modified();
}
@ -982,6 +991,7 @@ void TelemetryPanel::on_insertSensor(int selectedIndex)
model->sensorData[selectedIndex].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, 1);
updateItemModels();
update();
emit modified();
}
@ -995,6 +1005,7 @@ void TelemetryPanel::on_deleteSensor(int selectedIndex)
model->sensorData[CPN_MAX_SENSORS - 1].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, -1);
updateItemModels();
update();
emit modified();
}
@ -1018,7 +1029,20 @@ void TelemetryPanel::swapData(int idx1, int idx2)
memcpy(sd2, sd1, sizeof(SensorData));
memcpy(sd1, &sdtmp, sizeof(SensorData));
model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_SWAP, idx1, idx2);
updateItemModels();
update();
emit modified();
}
}
void TelemetryPanel::on_dataModifiedSensor()
{
updateItemModels();
update();
emit modified();
}
void TelemetryPanel::updateItemModels()
{
commonItemModels->update(CommonItemModels::RMO_TELEMETRY_SENSORS);
}

View file

@ -27,7 +27,8 @@
constexpr char MIMETYPE_TELE_SENSOR[] = "application/x-companion-tele-sensor";
class AutoComboBox;
class RawSourceFilterItemModel;
class CommonItemModels;
class RawItemFilteredModel;
class TimerEdit;
namespace Ui {
@ -41,7 +42,7 @@ class TelemetryCustomScreen: public ModelPanel
Q_OBJECT
public:
TelemetryCustomScreen(QWidget *parent, ModelData & model, FrSkyScreenData & screen, GeneralSettings & generalSettings, Firmware * firmware, RawSourceFilterItemModel * srcModel);
TelemetryCustomScreen(QWidget *parent, ModelData & model, FrSkyScreenData & screen, GeneralSettings & generalSettings, Firmware * firmware, RawItemFilteredModel * rawSourceModel);
~TelemetryCustomScreen();
void update();
@ -53,6 +54,8 @@ class TelemetryCustomScreen: public ModelPanel
void barMinChanged(double value);
void barMaxChanged(double value);
void barTimeChanged();
void onModelDataAboutToBeUpdated();
void onModelDataUpdateComplete();
private:
void updateBar(int line);
@ -122,7 +125,7 @@ class TelemetryPanel : public ModelPanel
Q_OBJECT
public:
TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware);
TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels);
virtual ~TelemetryPanel();
virtual void update();
@ -148,12 +151,15 @@ class TelemetryPanel : public ModelPanel
void on_deleteSensor(int index);
void on_moveUpSensor(int index);
void on_moveDownSensor(int index);
void on_dataModifiedSensor();
private:
Ui::Telemetry *ui;
TelemetryCustomScreen * telemetryCustomScreens[4];
TelemetrySensorPanel * sensorPanels[CPN_MAX_SENSORS];
int sensorCapability;
CommonItemModels * commonItemModels;
RawItemFilteredModel * rawSourceFilteredModel;
void setup();
void telBarUpdate();
@ -161,6 +167,7 @@ class TelemetryPanel : public ModelPanel
void populateCurrentSource();
void populateVarioSource();
void swapData(int idx1, int idx2);
void updateItemModels();
};
#endif // _TELEMETRY_H_

View file

@ -96,6 +96,14 @@ bool menuModelLimits(event_t event)
uint32_t sub = menuVerticalPosition;
if (sub < MAX_OUTPUT_CHANNELS) {
#if defined(PPM_CENTER_ADJUSTABLE) || defined(PPM_UNIT_US)
lcdDrawNumber(LCD_W / 2, MENU_TITLE_TOP + 1, PPM_CH_CENTER(sub)+channelOutputs[sub]/2, MENU_TITLE_COLOR, 0, "", STR_US);
#else
lcdDrawNumber(LCD_W / 2, MENU_TITLE_TOP + 1, calcRESXto1000(channelOutputs[sub]), PREC1 | MENU_TITLE_COLOR);
#endif
}
if (sub<MAX_OUTPUT_CHANNELS && menuHorizontalPosition>=0) {
drawColumnHeader(STR_LIMITS_HEADERS, NULL, menuHorizontalPosition);
}

View file

@ -35,8 +35,8 @@ enum NavigationDirection {
#define EVT_KEY_PREVIOUS_VIEW(evt) (evt == EVT_KEY_LONG(KEY_LEFT) && IS_SHIFT_PRESSED())
#define EVT_KEY_NEXT_VIEW(evt) (evt == EVT_KEY_LONG(KEY_RIGHT) && IS_SHIFT_PRESSED())
#elif defined(NAVIGATION_X7_TX12)
#define EVT_KEY_PREVIOUS_VIEW(evt) (evt == EVT_KEY_FIRST(KEY_UP))
#define EVT_KEY_NEXT_VIEW(evt) (evt == EVT_KEY_FIRST(KEY_DOWN))
#define EVT_KEY_PREVIOUS_VIEW(evt) (evt == EVT_KEY_FIRST(KEY_PAGEUP))
#define EVT_KEY_NEXT_VIEW(evt) (evt == EVT_KEY_FIRST(KEY_PAGEDN))
#elif defined(NAVIGATION_X7) || defined(NAVIGATION_X9D)
#define EVT_KEY_PREVIOUS_VIEW(evt) (evt == EVT_KEY_LONG(KEY_PAGE))
#define EVT_KEY_NEXT_VIEW(evt) (evt == EVT_KEY_BREAK(KEY_PAGE))

View file

@ -539,14 +539,25 @@ int getStickTrimValue(int stick, int stickValue)
return trim;
}
int getSourceTrimValue(int source, int stickValue=0)
int getSourceTrimOrigin(int source)
{
if (source >= MIXSRC_Rud && source <= MIXSRC_Ail)
return getStickTrimValue(source - MIXSRC_Rud, stickValue);
return source - MIXSRC_Rud;
else if (source >= MIXSRC_FIRST_INPUT && source <= MIXSRC_LAST_INPUT)
return getStickTrimValue(virtualInputsTrims[source - MIXSRC_FIRST_INPUT], stickValue);
return virtualInputsTrims[source - MIXSRC_FIRST_INPUT];
else
return -1;
}
int getSourceTrimValue(int source, int stickValue=0)
{
auto origin = getSourceTrimOrigin(source);
if (origin >= 0) {
return getStickTrimValue(origin, stickValue);
}
else {
return 0;
}
}
uint8_t mixerCurrentFlightMode;
@ -741,13 +752,16 @@ void evalFlightModeMixes(uint8_t mode, uint8_t tick10ms)
}
if (applyOffsetAndCurve) {
//========== TRIMS ================
if (!(mode & e_perout_mode_notrims)) {
if (md->carryTrim == 0) {
v += getSourceTrimValue(md->srcRaw, v);
bool applyTrims = !(mode & e_perout_mode_notrims);
if (!applyTrims && g_model.thrTrim) {
auto origin = getSourceTrimOrigin(md->srcRaw);
if (origin == g_model.getThrottleStickTrimSource() - MIXSRC_FIRST_TRIM) {
applyTrims = true;
}
}
if (applyTrims && md->carryTrim == 0) {
v += getSourceTrimValue(md->srcRaw, v);
}
}
int32_t weight = GET_GVAR_PREC1(MD_WEIGHT(md), GV_RANGELARGE_NEG, GV_RANGELARGE, mixerCurrentFlightMode);

View file

@ -1119,7 +1119,7 @@ void checkTrims()
else {
phase = getTrimFlightMode(mixerCurrentFlightMode, idx);
before = getTrimValue(phase, idx);
thro = (idx==THR_STICK && g_model.thrTrim);
thro = (idx == (g_model.getThrottleStickTrimSource() - MIXSRC_FIRST_TRIM) && g_model.thrTrim);
}
#else
phase = getTrimFlightMode(mixerCurrentFlightMode, idx);
@ -1824,24 +1824,27 @@ void moveTrimsToOffsets() // copy state of 3 primary to subtrim
pauseMixerCalculations();
evalFlightModeMixes(e_perout_mode_noinput, 0); // do output loop - zero input sticks and trims
for (uint8_t i=0; i<MAX_OUTPUT_CHANNELS; i++) {
for (uint8_t i = 0; i < MAX_OUTPUT_CHANNELS; i++) {
zeros[i] = applyLimits(i, chans[i]);
}
evalFlightModeMixes(e_perout_mode_noinput-e_perout_mode_notrims, 0); // do output loop - only trims
for (uint8_t i=0; i<MAX_OUTPUT_CHANNELS; i++) {
int16_t output = applyLimits(i, chans[i]) - zeros[i];
for (uint8_t i = 0; i < MAX_OUTPUT_CHANNELS; i++) {
int16_t diff = applyLimits(i, chans[i]) - zeros[i];
int16_t v = g_model.limitData[i].offset;
if (g_model.limitData[i].revert)
output = -output;
v += (output * 125) / 128;
g_model.limitData[i].offset = limit((int16_t)-1000, (int16_t)v, (int16_t)1000); // make sure the offset doesn't go haywire
diff = -diff;
v += (diff * 125) / 128;
g_model.limitData[i].offset = limit((int16_t) -1000, (int16_t) v, (int16_t) 1000); // make sure the offset doesn't go haywire
}
// reset all trims, except throttle (if throttle trim)
for (uint8_t i=0; i<NUM_TRIMS; i++) {
if (i != THR_STICK || !g_model.thrTrim) {
auto thrStick = g_model.getThrottleStickTrimSource() - MIXSRC_FIRST_TRIM;
if (i != thrStick || !g_model.thrTrim) {
int16_t original_trim = getTrimValue(mixerCurrentFlightMode, i);
for (uint8_t fm=0; fm<MAX_FLIGHT_MODES; fm++) {
trim_t trim = getRawTrimValue(fm, i);

View file

@ -2,7 +2,7 @@ option(SHUTDOWN_CONFIRMATION "Shutdown confirmation" OFF)
option(LCD_DUAL_BUFFER "Dual LCD Buffer" OFF)
option(PXX1 "PXX1 protocol support" ON)
option(PXX2 "PXX2 protocol support" OFF)
option(AFHDS3 "AFHDS3 TX Module" OFF)
option(AFHDS3 "AFHDS3 TX Module" ON)
option(GHOST "Ghost TX Module" ON)
option(INTERNAL_MODULE_PPM "Support for PPM internal module" OFF)
option(AUTOUPDATE "Auto update internal chips from SD" OFF)
@ -53,6 +53,7 @@ elseif(PCB STREQUAL X9D+)
set(LCD_DRIVER lcd_driver_spi.cpp)
set(GVAR_SCREEN model_gvars.cpp)
set(PCBREV 2014 CACHE STRING "PCB Revision")
set(AFHDS3 NO)
add_definitions(-DPCBREV=${PCBREV})
add_definitions(-DMANUFACTURER_FRSKY)
if (${PCBREV} STREQUAL 2019)
@ -106,6 +107,7 @@ elseif(PCB STREQUAL X9D)
set(GVAR_SCREEN model_gvars.cpp)
set(STATUS_LEDS NO)
add_definitions(-DMANUFACTURER_FRSKY)
set(AFHDS3 NO)
elseif(PCB STREQUAL X7)
set(PWR_BUTTON "PRESS" CACHE STRING "Pwr button type (PRESS/SWITCH)")
set(HAPTIC YES)

View file

@ -339,6 +339,106 @@ TEST_F(TrimsTest, CopySticksToOffset)
EXPECT_EQ(g_model.limitData[1].offset, -97);
}
TEST_F(TrimsTest, MoveTrimsToOffsets)
{
// No trim idle only
g_model.thrTrim = 0;
anaInValues[THR_STICK] = 0;
setTrimValue(0, MIXSRC_TrimThr - MIXSRC_FIRST_TRIM, 100);
setTrimValue(0, MIXSRC_TrimEle - MIXSRC_FIRST_TRIM, -100);
evalMixes(1);
EXPECT_EQ(channelOutputs[2], 200); // THR output value is reflecting 100 trim
moveTrimsToOffsets();
EXPECT_EQ(getTrimValue(0, MIXSRC_TrimThr - MIXSRC_FIRST_TRIM), 0); // back to neutral
EXPECT_EQ(g_model.limitData[2].offset, 195); // value transferred
EXPECT_EQ(getTrimValue(0, MIXSRC_TrimEle - MIXSRC_FIRST_TRIM), 0); // back to neutral
EXPECT_EQ(g_model.limitData[1].offset, -195); // value transferred
evalMixes(1);
EXPECT_EQ(channelOutputs[2], 200); // THR output value is still reflecting 100 trim
}
TEST_F(TrimsTest, MoveTrimsToOffsetsWithTrimIdle)
{
// Trim idle only
g_model.thrTrim = 1;
anaInValues[THR_STICK] = -1024; // Min stick
g_model.limitData[2].offset = 0;
g_model.limitData[1].offset = 0;
setTrimValue(0, MIXSRC_TrimThr - MIXSRC_FIRST_TRIM, 100);
setTrimValue(0, MIXSRC_TrimEle - MIXSRC_FIRST_TRIM, -100);
evalMixes(1);
EXPECT_EQ(channelOutputs[2], -574); // THR output value is reflecting 100 trim idle
moveTrimsToOffsets();
// Trim affecting Throttle should not be affected
EXPECT_EQ(getTrimValue(0, MIXSRC_TrimThr - MIXSRC_FIRST_TRIM), 100); // unchanged
EXPECT_EQ(g_model.limitData[2].offset, 0); // unchanged
// Other trims should
EXPECT_EQ(getTrimValue(0, MIXSRC_TrimEle - MIXSRC_FIRST_TRIM), 0); // back to neutral
EXPECT_EQ(g_model.limitData[1].offset, -195); // value transferred
evalMixes(1);
EXPECT_EQ(channelOutputs[2], -574); // THR output value is still reflecting 100 trim idle
}
TEST_F(TrimsTest, MoveTrimsToOffsetsWithCrossTrims)
{
// No trim idle only
// Cross trims
g_model.thrTrim = 0;
g_model.limitData[2].offset = 0;
g_model.limitData[1].offset = 0;
g_model.thrTrimSw = MIXSRC_TrimEle - MIXSRC_FIRST_TRIM;
ExpoData *expo = expoAddress(THR_STICK);
expo->carryTrim = TRIM_ELE;
expo = expoAddress(ELE_STICK);
expo->carryTrim = TRIM_THR;
anaInValues[THR_STICK] = 0;
setTrimValue(0, MIXSRC_TrimEle - MIXSRC_FIRST_TRIM, 100);
setTrimValue(0, MIXSRC_TrimThr - MIXSRC_FIRST_TRIM, -100);
evalMixes(1);
EXPECT_EQ(channelOutputs[2], 200); // THR output value is reflecting 100 Ele trim
moveTrimsToOffsets();
evalMixes(1);
EXPECT_EQ(channelOutputs[2], 200); // THR output value remains unchanged
EXPECT_EQ(getTrimValue(0, MIXSRC_TrimThr - MIXSRC_FIRST_TRIM), 0); // back to neutral
EXPECT_EQ(g_model.limitData[2].offset, 195); // value transferred
EXPECT_EQ(getTrimValue(0, MIXSRC_TrimEle - MIXSRC_FIRST_TRIM), 0); // back to neutral
EXPECT_EQ(g_model.limitData[1].offset, -195); // value transferred
}
TEST_F(TrimsTest, MoveTrimsToOffsetsWithCrosstrimsAndTrimIdle)
{
// Trim idle only
// Cross trims
g_model.limitData[2].offset = 0;
g_model.limitData[1].offset = 0;
g_model.thrTrim = 1;
g_model.thrTrimSw = MIXSRC_TrimEle - MIXSRC_FIRST_TRIM;
ExpoData *expo = expoAddress(THR_STICK);
expo->carryTrim = TRIM_ELE;
expo = expoAddress(ELE_STICK);
expo->carryTrim = TRIM_THR;
anaInValues[THR_STICK] = -1024; // Min stick
setTrimValue(0, MIXSRC_TrimEle - MIXSRC_FIRST_TRIM, 100);
setTrimValue(0, MIXSRC_TrimThr - MIXSRC_FIRST_TRIM, -100);
evalMixes(1);
EXPECT_EQ(channelOutputs[2], -574); // THR output value is reflecting 100 ele trim idle
moveTrimsToOffsets();
// Trim affecting Throttle (now Ele because of crosstrims) should not be affected
EXPECT_EQ(getTrimValue(0, MIXSRC_TrimEle - MIXSRC_FIRST_TRIM), 100); // unchanged
EXPECT_EQ(g_model.limitData[2].offset, 0); // THR chan offset unchanged
// Other trims should
EXPECT_EQ(getTrimValue(0, MIXSRC_TrimThr - MIXSRC_FIRST_TRIM), 0); // back to neutral
EXPECT_EQ(g_model.limitData[1].offset, -195); // Ele chan offset transfered
evalMixes(1);
EXPECT_EQ(channelOutputs[2], -574); // THR output value is still reflecting 100 trim idle
}
TEST_F(TrimsTest, InstantTrim)
{
anaInValues[AIL_STICK] = 50;

View file

@ -93,13 +93,11 @@ def main():
maxsize = 65536 * 8
elif options[optcount] == "x7":
cmake_options["PCB"] = "X7"
cmake_options["AFHDS3"] = "YES"
firmware_options = options_taranis_x7
maxsize = 65536 * 8
elif options[optcount] == "x7access":
cmake_options["PCB"] = "X7"
cmake_options["PCBREV"] = "ACCESS"
cmake_options["AFHDS3"] = "YES"
firmware_options = options_taranis_x7
maxsize = 65536 * 8
elif board_name == "xlite":
@ -121,7 +119,6 @@ def main():
elif board_name == "x9d+2019":
cmake_options["PCB"] = "X9D+"
cmake_options["PCBREV"] = "2019"
cmake_options["AFHDS3"] = "YES"
firmware_options = options_taranis_x9dp
maxsize = 65536 * 8
elif board_name == "x9e":