1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-24 00:35:18 +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] [Main developers]
Bertrand Songis (bsongis) Bertrand Songis (bsongis)
André Bernet (kilrah) André Bernet (kilrah)
JC D. (3djc)
Michael Blandford Michael Blandford
Damjan Adamic (projectkk2glider) Damjan Adamic (projectkk2glider)
Franck Aguerre (jivarofad) Franck Aguerre (jivarofad)
@ -9,6 +10,7 @@ Martin Hotař (mhotar)
Maxim (Max) Paperno (mpaperno) Maxim (Max) Paperno (mpaperno)
Arne Schwabe (schwabe) Arne Schwabe (schwabe)
Daniel Gorbea (dgatf) Daniel Gorbea (dgatf)
Neil Horne (elecpower)
[Translators] [Translators]
[fr] Sebastien Charpentier (LapinFou) [fr] Sebastien Charpentier (LapinFou)
@ -2028,3 +2030,8 @@ Justin Digby
John Magnuson (monthly) John Magnuson (monthly)
Holger Lippert Holger Lippert
Hubert Huber 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(); Firmware * fw = getCurrentFirmware();
addItems(SOURCE_TYPE_NONE, RawSource::NoneGroup, 1); 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_LUA_OUTPUT, RawSource::ScriptsGroup, fw->getCapability(LuaOutputsPerScript), i * 16);
addItems(SOURCE_TYPE_VIRTUAL_INPUT, RawSource::InputsGroup, fw->getCapability(VirtualInputs)); addItems(SOURCE_TYPE_VIRTUAL_INPUT, RawSource::InputsGroup, fw->getCapability(VirtualInputs));
addItems(SOURCE_TYPE_STICK, RawSource::SourcesGroup, board.getCapability(Board::MaxAnalogs)); 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_PPM, RawSource::SourcesGroup, fw->getCapability(TrainerInputs));
addItems(SOURCE_TYPE_CH, RawSource::SourcesGroup, fw->getCapability(Outputs)); addItems(SOURCE_TYPE_CH, RawSource::SourcesGroup, fw->getCapability(Outputs));
addItems(SOURCE_TYPE_SPECIAL, RawSource::TelemGroup, 5); 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)); 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())); 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 // Descending switch direction: NOT (!) switches
addItems(SWITCH_TYPE_ACT, -1); 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_TELEMETRY, -1);
addItems(SWITCH_TYPE_FLIGHT_MODE, -fw->getCapability(FlightModes)); addItems(SWITCH_TYPE_FLIGHT_MODE, -fw->getCapability(FlightModes));
addItems(SWITCH_TYPE_VIRTUAL, -fw->getCapability(LogicalSwitches)); 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_VIRTUAL, fw->getCapability(LogicalSwitches));
addItems(SWITCH_TYPE_FLIGHT_MODE, fw->getCapability(FlightModes)); addItems(SWITCH_TYPE_FLIGHT_MODE, fw->getCapability(FlightModes));
addItems(SWITCH_TYPE_TELEMETRY, 1); 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_ON, 1);
addItems(SWITCH_TYPE_ONE, 1); addItems(SWITCH_TYPE_ONE, 1);
addItems(SWITCH_TYPE_ACT, 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())); 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 }; enum DataRoles { ItemIdRole = Qt::UserRole, ItemTypeRole, ItemFlagsRole, IsAvailableRole };
Q_ENUM(DataRoles) 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) : explicit AbstractRawItemDataModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr) :
QStandardItemModel(parent), QStandardItemModel(parent),
generalSettings(generalSettings), generalSettings(generalSettings),
@ -43,7 +50,11 @@ class AbstractRawItemDataModel: public QStandardItemModel
{} {}
public slots: public slots:
virtual void update() const = 0; virtual void update() = 0;
signals:
void dataAboutToBeUpdated();
void dataUpdateComplete();
protected: protected:
const GeneralSettings * generalSettings; const GeneralSettings * generalSettings;
@ -58,7 +69,7 @@ class RawSourceItemModel: public AbstractRawItemDataModel
explicit RawSourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr); explicit RawSourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr);
public slots: public slots:
void update() const override; void update() override;
protected: protected:
void setDynamicItemData(QStandardItem * item, const RawSource & src) const; 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); explicit RawSwitchItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr);
public slots: public slots:
void update() const override; void update() override;
protected: protected:
void setDynamicItemData(QStandardItem * item, const RawSwitch & rsw) const; 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 #endif // RAWITEMDATAMODELS_H

View file

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

View file

@ -21,54 +21,43 @@
#ifndef RAWITEMFILTEREDMODEL_H #ifndef RAWITEMFILTEREDMODEL_H
#define RAWITEMFILTEREDMODEL_H #define RAWITEMFILTEREDMODEL_H
#include "rawitemdatamodels.h"
#include <QSortFilterProxyModel> #include <QSortFilterProxyModel>
class GeneralSettings; class GeneralSettings;
class ModelData; class ModelData;
class RawSourceItemModel;
class RawSwitchItemModel;
class RawItemFilteredModel: public QSortFilterProxyModel class RawItemFilteredModel: public QSortFilterProxyModel
{ {
Q_OBJECT Q_OBJECT
public: 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, int flags, QObject * parent = nullptr);
explicit RawItemFilteredModel(QAbstractItemModel * sourceModel, QObject * parent = nullptr) : RawItemFilteredModel(sourceModel, 0, parent) {} explicit RawItemFilteredModel(QAbstractItemModel * sourceModel, QObject * parent = nullptr) : RawItemFilteredModel(sourceModel, 0, parent) {}
public slots: public slots:
void setFilterFlags(int flags); void setFilterFlags(int flags);
void update() const; void update() const;
void onDataAboutToBeUpdated();
void onDataUpdateComplete();
signals:
void dataAboutToBeUpdated();
void dataUpdateComplete();
protected: protected:
bool filterAcceptsRow(int sourceRow, const QModelIndex & sourceParent) const override; bool filterAcceptsRow(int sourceRow, const QModelIndex & sourceParent) const override;
int filterFlags; 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 #endif // RAWITEMFILTEREDMODEL_H

View file

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

View file

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

View file

@ -723,11 +723,15 @@ int ModelData::updateReference()
updateAssignFunc(cfd); updateAssignFunc(cfd);
if (!cfd->isEmpty()) { if (!cfd->isEmpty()) {
updateSwitchRef(cfd->swtch); 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); updateSourceIntRef(cfd->param);
if (cfd->param == 0) if (cfd->param == 0)
cfd->clear(); 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(); newRef.clear();
else { else {
newRef.type = (T)defType; newRef.type = (T)defType;
newRef.index = defIndex + idxAdj; newRef.index = defIndex;
} }
break; break;
case REF_UPD_ACT_SHIFT: case REF_UPD_ACT_SHIFT:
@ -904,7 +908,7 @@ void ModelData::updateTypeValueRef(R & curRef, const T type, const int idxAdj, c
newRef.clear(); newRef.clear();
else { else {
newRef.type = (T)defType; newRef.type = (T)defType;
newRef.value = defValue + idxAdj; newRef.value = defValue;
} }
break; break;
case REF_UPD_ACT_SHIFT: case REF_UPD_ACT_SHIFT:
@ -972,7 +976,7 @@ void ModelData::updateAssignFunc(CustomFunctionData * cfd)
{ {
const int invalidateRef = -1; const int invalidateRef = -1;
int newRef = (int)cfd->func; int newRef = (int)cfd->func;
int idxAdj; int idxAdj = 0;
switch (updRefInfo.type) switch (updRefInfo.type)
{ {
@ -989,7 +993,7 @@ void ModelData::updateAssignFunc(CustomFunctionData * cfd)
case REF_UPD_TYPE_TIMER: case REF_UPD_TYPE_TIMER:
if (cfd->func < FuncSetTimer1 || cfd->func > FuncSetTimer3) // TODO refactor to FuncSetTimerLast if (cfd->func < FuncSetTimer1 || cfd->func > FuncSetTimer3) // TODO refactor to FuncSetTimerLast
return; return;
idxAdj = FuncSetTimer1 - 2; // reverse earlier offset requiured for rawsource idxAdj = FuncSetTimer1 - 2; // reverse earlier offset required for rawsource
break; break;
default: default:
return; return;
@ -1374,3 +1378,64 @@ void ModelData::sortMixes()
memcpy(&mixData[0], &sortedMixData[0], CPN_MAX_MIXERS * sizeof(MixData)); 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(); value = swtch.toValue();
} }
void sortMixes(); void sortMixes();
void updateResetParam(CustomFunctionData * cfd);
}; };
#endif // MODELDATA_H #endif // MODELDATA_H

View file

@ -1202,19 +1202,19 @@ void registerOpenTxFirmwares()
firmware->addOption("horussticks", Firmware::tr("Horus gimbals installed (Hall sensors)")); firmware->addOption("horussticks", Firmware::tr("Horus gimbals installed (Hall sensors)"));
addOpenTxTaranisOptions(firmware); addOpenTxTaranisOptions(firmware);
registerOpenTxFirmware(firmware); registerOpenTxFirmware(firmware);
addOpenTxRfOptions(firmware, EU + FLEX + AFHDS3); addOpenTxRfOptions(firmware, EU + FLEX);
/* FrSky X9-Lite board */ /* FrSky X9-Lite board */
firmware = new OpenTxFirmware("opentx-x9lite", Firmware::tr("FrSky Taranis X9-Lite"), BOARD_TARANIS_X9LITE); firmware = new OpenTxFirmware("opentx-x9lite", Firmware::tr("FrSky Taranis X9-Lite"), BOARD_TARANIS_X9LITE);
addOpenTxTaranisOptions(firmware); addOpenTxTaranisOptions(firmware);
registerOpenTxFirmware(firmware); registerOpenTxFirmware(firmware);
addOpenTxRfOptions(firmware, FLEX + AFHDS3); addOpenTxRfOptions(firmware, FLEX);
/* FrSky X9-LiteS board */ /* FrSky X9-LiteS board */
firmware = new OpenTxFirmware("opentx-x9lites", Firmware::tr("FrSky Taranis X9-Lite S"), BOARD_TARANIS_X9LITES); firmware = new OpenTxFirmware("opentx-x9lites", Firmware::tr("FrSky Taranis X9-Lite S"), BOARD_TARANIS_X9LITES);
addOpenTxTaranisOptions(firmware); addOpenTxTaranisOptions(firmware);
registerOpenTxFirmware(firmware); registerOpenTxFirmware(firmware);
addOpenTxRfOptions(firmware, FLEX + AFHDS3); addOpenTxRfOptions(firmware, FLEX);
/* FrSky X7 board */ /* FrSky X7 board */
firmware = new OpenTxFirmware("opentx-x7", Firmware::tr("FrSky Taranis X7 / X7S"), BOARD_TARANIS_X7); 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); firmware = new OpenTxFirmware("opentx-xlites", Firmware::tr("FrSky Taranis X-Lite S/PRO"), BOARD_TARANIS_XLITES);
addOpenTxTaranisOptions(firmware); addOpenTxTaranisOptions(firmware);
registerOpenTxFirmware(firmware); registerOpenTxFirmware(firmware);
addOpenTxRfOptions(firmware, FLEX + AFHDS3); addOpenTxRfOptions(firmware, FLEX);
/* FrSky X-Lite board */ /* FrSky X-Lite board */
firmware = new OpenTxFirmware("opentx-xlite", Firmware::tr("FrSky Taranis X-Lite"), BOARD_TARANIS_XLITE); 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")); firmware->addOption("internalmulti", Firmware::tr("Support for MULTI internal module"));
addOpenTxFontOptions(firmware); addOpenTxFontOptions(firmware);
registerOpenTxFirmware(firmware); registerOpenTxFirmware(firmware);
addOpenTxRfOptions(firmware, FLEX + AFHDS3); addOpenTxRfOptions(firmware, FLEX);
/* Jumper T16 board */ /* Jumper T16 board */
firmware = new OpenTxFirmware("opentx-t16", Firmware::tr("Jumper T16 / T16+ / T16 Pro"), BOARD_JUMPER_T16); 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")); firmware->addOption("lua", Firmware::tr("Enable Lua custom scripts screen"));
addOpenTxFontOptions(firmware); addOpenTxFontOptions(firmware);
registerOpenTxFirmware(firmware); registerOpenTxFirmware(firmware);
addOpenTxRfOptions(firmware, FLEX + AFHDS3); addOpenTxRfOptions(firmware, FLEX);
/* Radiomaster TX16S board */ /* Radiomaster TX16S board */
firmware = new OpenTxFirmware("opentx-tx16s", Firmware::tr("Radiomaster TX16S / SE / Hall / Masterfire"), BOARD_RADIOMASTER_TX16S); 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") tr("THs"), tr("TH%"), tr("THt")
}; };
const QStringList directionIndicators = QStringList() static const QStringList directionIndicators = QStringList()
<< CPN_STR_SW_INDICATOR_UP << CPN_STR_SW_INDICATOR_UP
<< CPN_STR_SW_INDICATOR_NEUT << CPN_STR_SW_INDICATOR_NEUT
<< CPN_STR_SW_INDICATOR_DN; << 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}) qt5_wrap_cpp(generaledit_SRCS ${generaledit_HDRS})
add_library(generaledit ${generaledit_SRCS}) 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 "hardware.h"
#include "../modeledit/customfunctions.h" #include "../modeledit/customfunctions.h"
#include "verticalscrollarea.h" #include "verticalscrollarea.h"
#include "rawitemdatamodels.h"
GeneralEdit::GeneralEdit(QWidget * parent, RadioData & radioData, Firmware * firmware) : GeneralEdit::GeneralEdit(QWidget * parent, RadioData & radioData, Firmware * firmware) :
QDialog(parent), 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 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 TrainerPanel(this, generalSettings, firmware), tr("Trainer"));
addTab(new HardwarePanel(this, generalSettings, firmware), tr("Hardware")); addTab(new HardwarePanel(this, generalSettings, firmware), tr("Hardware"));
addTab(new CalibrationPanel(this, generalSettings, firmware), tr("Calibration")); addTab(new CalibrationPanel(this, generalSettings, firmware), tr("Calibration"));

View file

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

View file

@ -742,7 +742,8 @@ GpsCoord extractGpsCoordinates(const QString & position)
return result; 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) #if defined(TABLE_LAYOUT)
tableWidget = new QTableWidget(parent); tableWidget = new QTableWidget(parent);

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -24,7 +24,8 @@
#include "helpers.h" #include "helpers.h"
ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, GeneralSettings & generalSettings, ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, GeneralSettings & generalSettings,
Firmware * firmware, QString & inputName) : Firmware * firmware, QString & inputName, RawItemFilteredModel * rawSourceModel,
RawItemFilteredModel * rawSwitchModel) :
QDialog(parent), QDialog(parent),
ui(new Ui::ExpoDialog), ui(new Ui::ExpoDialog),
model(model), model(model),
@ -36,9 +37,10 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G
lock(false) lock(false)
{ {
ui->setupUi(this); 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 }; 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 };
for (int i=0; i<CPN_MAX_FLIGHT_MODES; i++) { 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]; 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, curveGroup = new CurveGroup(ui->curveTypeCB, ui->curveGVarCB, ui->curveValueCB, ui->curveValueSB, ed->curve, model,
firmware->getCapability(HasInputDiff) ? 0 : (HIDE_DIFF | HIDE_NEGATIVE_CURVES)); 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->switchesCB->setCurrentIndex(ui->switchesCB->findData(ed->swtch.toValue()));
ui->sideCB->setCurrentIndex(ed->mode-1); ui->sideCB->setCurrentIndex(ed->mode - 1);
if (!firmware->getCapability(FlightModes)) { if (!firmware->getCapability(FlightModes)) {
ui->label_phases->hide(); 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(); lb_fp[i]->hide();
cb_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); ui->label_phases->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->label_phases, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(label_phases_customContextMenuRequested(const QPoint &))); connect(ui->label_phases, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(label_phases_customContextMenuRequested(const QPoint &)));
int mask = 1; 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) { if ((ed->flightModes & mask) == 0) {
cb_fp[i]->setChecked(true); cb_fp[i]->setChecked(true);
} }
mask <<= 1; 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(); lb_fp[i]->hide();
cb_fp[i]->hide(); cb_fp[i]->hide();
} }
@ -83,9 +85,8 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G
if (firmware->getCapability(VirtualInputs)) { if (firmware->getCapability(VirtualInputs)) {
ui->inputName->setMaxLength(firmware->getCapability(InputsLength)); 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->setCurrentIndex(ui->sourceCB->findData(ed->srcRaw.toValue()));
ui->sourceCB->removeItem(0);
ui->inputName->setValidator(new QRegExpValidator(rx, this)); ui->inputName->setValidator(new QRegExpValidator(rx, this));
ui->inputName->setText(inputName); ui->inputName->setText(inputName);
} }
@ -98,8 +99,8 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G
ui->trimCB->hide(); ui->trimCB->hide();
} }
for(int i=0; i < getBoardCapability(getCurrentBoard(), Board::NumTrims); i++) { for(int i = 0; i < getBoardCapability(getCurrentBoard(), Board::NumTrims); i++) {
ui->trimCB->addItem(RawSource(SOURCE_TYPE_TRIM, i).toString(), i+1); ui->trimCB->addItem(RawSource(SOURCE_TYPE_TRIM, i).toString(), i + 1);
} }
ui->trimCB->setCurrentIndex(1 - ed->carryTrim); 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->trimCB, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesChanged()));
connect(ui->switchesCB, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesChanged())); connect(ui->switchesCB, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesChanged()));
connect(ui->sideCB, 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())); connect(cb_fp[i], SIGNAL(toggled(bool)), this, SLOT(valuesChanged()));
} }
if (firmware->getCapability(VirtualInputs)) { if (firmware->getCapability(VirtualInputs)) {
@ -181,7 +182,7 @@ void ExpoDialog::valuesChanged()
} }
ed->flightModes = 0; 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()) { if (!cb_fp[i]->checkState()) {
ed->flightModes++; ed->flightModes++;
} }
@ -212,7 +213,7 @@ void ExpoDialog::label_phases_customContextMenuRequested(const QPoint & pos)
void ExpoDialog::fmClearAll() void ExpoDialog::fmClearAll()
{ {
lock = true; 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); cb_fp[i]->setChecked(false);
} }
lock = false; lock = false;
@ -222,7 +223,7 @@ void ExpoDialog::fmClearAll()
void ExpoDialog::fmSetAll() void ExpoDialog::fmSetAll()
{ {
lock = true; 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); cb_fp[i]->setChecked(true);
} }
lock = false; lock = false;
@ -232,7 +233,7 @@ void ExpoDialog::fmSetAll()
void ExpoDialog::fmInvertAll() void ExpoDialog::fmInvertAll()
{ {
lock = true; 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()); cb_fp[i]->setChecked(!cb_fp[i]->isChecked());
} }
lock = false; lock = false;

View file

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

View file

@ -24,14 +24,15 @@
#include "helpers.h" #include "helpers.h"
#include "customdebug.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), ModelPanel(parent, model, generalSettings, firmware),
ui(new Ui::FlightMode), ui(new Ui::FlightMode),
phaseIdx(phaseIdx), phaseIdx(phaseIdx),
phase(model.flightModeData[phaseIdx]), phase(model.flightModeData[phaseIdx])
rawSwitchItemModel(NULL)
{ {
ui->setupUi(this); ui->setupUi(this);
connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataAboutToBeUpdated, this, &FlightModePanel::onModelDataAboutToBeUpdated);
connect(rawSwitchFilteredModel, &RawItemFilteredModel::dataUpdateComplete, this, &FlightModePanel::onModelDataUpdateComplete);
ui->labelName->setContextMenuPolicy(Qt::CustomContextMenu); ui->labelName->setContextMenuPolicy(Qt::CustomContextMenu);
ui->labelName->setToolTip(tr("Popup menu available")); ui->labelName->setToolTip(tr("Popup menu available"));
@ -56,8 +57,8 @@ FlightModePanel::FlightModePanel(QWidget * parent, ModelData & model, int phaseI
// Flight mode switch // Flight mode switch
if (phaseIdx > 0) { if (phaseIdx > 0) {
ui->swtch->setModel(switchModel); ui->swtch->setModel(rawSwitchFilteredModel);
connect(ui->swtch, SIGNAL(activated(int)), this, SLOT(phaseSwitchChanged(int))); connect(ui->swtch, SIGNAL(currentIndexChanged(int)), this, SLOT(phaseSwitch_currentIndexChanged(int)));
} }
else { else {
ui->swtch->hide(); ui->swtch->hide();
@ -316,8 +317,6 @@ void FlightModePanel::update()
for (int i = 0; i < reCount; i++) { for (int i = 0; i < reCount; i++) {
updateRotaryEncoder(i); updateRotaryEncoder(i);
} }
emit nameModified();
} }
void FlightModePanel::updateGVar(int index) void FlightModePanel::updateGVar(int index)
@ -390,17 +389,18 @@ void FlightModePanel::phaseName_editingFinished()
{ {
QLineEdit *lineEdit = qobject_cast<QLineEdit*>(sender()); QLineEdit *lineEdit = qobject_cast<QLineEdit*>(sender());
strcpy(phase.name, lineEdit->text().toLatin1()); strcpy(phase.name, lineEdit->text().toLatin1());
emit phaseNameChanged();
emit modified(); emit modified();
emit nameModified();
} }
void FlightModePanel::phaseSwitchChanged(int index) void FlightModePanel::phaseSwitch_currentIndexChanged(int index)
{ {
if (!lock) { if (!lock) {
bool ok; bool ok;
const RawSwitch rs(ui->swtch->itemData(index).toInt(&ok)); const RawSwitch rs(ui->swtch->itemData(index).toInt(&ok));
if (ok && phase.swtch.toValue() != rs.toValue()) { if (ok && phase.swtch.toValue() != rs.toValue()) {
phase.swtch = rs; phase.swtch = rs;
emit phaseSwitchChanged();
emit modified(); emit modified();
} }
} }
@ -457,7 +457,7 @@ void FlightModePanel::phaseGVValue_editingFinished()
QDoubleSpinBox *spinBox = qobject_cast<QDoubleSpinBox*>(sender()); QDoubleSpinBox *spinBox = qobject_cast<QDoubleSpinBox*>(sender());
int gvar = spinBox->property("index").toInt(); int gvar = spinBox->property("index").toInt();
phase.gvars[gvar] = spinBox->value() * model->gvarData[gvar].multiplierSet(); phase.gvars[gvar] = spinBox->value() * model->gvarData[gvar].multiplierSet();
emit datachanged(); updateGVar(gvar);
emit modified(); emit modified();
} }
} }
@ -469,7 +469,7 @@ void FlightModePanel::GVName_editingFinished()
int gvar = lineedit->property("index").toInt(); int gvar = lineedit->property("index").toInt();
memset(&model->gvarData[gvar].name, 0, sizeof(model->gvarData[gvar].name)); memset(&model->gvarData[gvar].name, 0, sizeof(model->gvarData[gvar].name));
strcpy(model->gvarData[gvar].name, lineedit->text().toLatin1()); strcpy(model->gvarData[gvar].name, lineedit->text().toLatin1());
emit datachanged(); emit gvNameChanged();
emit modified(); emit modified();
} }
} }
@ -488,7 +488,7 @@ void FlightModePanel::phaseGVUse_currentIndexChanged(int index)
} }
if (model->isGVarLinkedCircular(phaseIdx, gvar)) if (model->isGVarLinkedCircular(phaseIdx, gvar))
QMessageBox::warning(this, "Companion", tr("Warning: Global variable links back to itself. Flight Mode 0 value used.")); QMessageBox::warning(this, "Companion", tr("Warning: Global variable links back to itself. Flight Mode 0 value used."));
emit datachanged(); updateGVar(gvar);
emit modified(); emit modified();
lock = false; lock = false;
} }
@ -500,7 +500,7 @@ void FlightModePanel::phaseGVUnit_currentIndexChanged(int index)
QComboBox *comboBox = qobject_cast<QComboBox*>(sender()); QComboBox *comboBox = qobject_cast<QComboBox*>(sender());
int gvar = comboBox->property("index").toInt(); int gvar = comboBox->property("index").toInt();
model->gvarData[gvar].unit = index; model->gvarData[gvar].unit = index;
emit datachanged(); updateGVar(gvar);
emit modified(); emit modified();
} }
} }
@ -511,7 +511,7 @@ void FlightModePanel::phaseGVPrec_currentIndexChanged(int index)
QComboBox *comboBox = qobject_cast<QComboBox*>(sender()); QComboBox *comboBox = qobject_cast<QComboBox*>(sender());
int gvar = comboBox->property("index").toInt(); int gvar = comboBox->property("index").toInt();
model->gvarData[gvar].prec = index; model->gvarData[gvar].prec = index;
emit datachanged(); updateGVar(gvar);
emit modified(); emit modified();
} }
} }
@ -534,7 +534,7 @@ void FlightModePanel::phaseGVMin_editingFinished()
} }
} }
} }
emit datachanged(); updateGVar(gvar);
emit modified(); emit modified();
} }
} }
@ -557,7 +557,7 @@ void FlightModePanel::phaseGVMax_editingFinished()
} }
} }
} }
emit datachanged(); updateGVar(gvar);
emit modified(); 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); model->updateAllReferences(ModelData::REF_UPD_TYPE_FLIGHT_MODE, ModelData::REF_UPD_ACT_CLEAR, phaseIdx);
emit datachanged(); update();
emit phaseDataChanged();
emit modified(); emit modified();
} }
@ -767,7 +768,7 @@ void FlightModePanel::cmClearAll()
model->updateAllReferences(ModelData::REF_UPD_TYPE_GLOBAL_VARIABLE, ModelData::REF_UPD_ACT_CLEAR, i); model->updateAllReferences(ModelData::REF_UPD_TYPE_GLOBAL_VARIABLE, ModelData::REF_UPD_ACT_CLEAR, i);
} }
emit datachanged(); emit phaseDataChanged();
emit modified(); 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); model->updateAllReferences(ModelData::REF_UPD_TYPE_FLIGHT_MODE, ModelData::REF_UPD_ACT_SHIFT, phaseIdx, 0, -1);
emit datachanged(); emit phaseDataChanged();
emit modified(); 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); model->updateAllReferences(ModelData::REF_UPD_TYPE_FLIGHT_MODE, ModelData::REF_UPD_ACT_SHIFT, phaseIdx, 0, 1);
emit datachanged(); emit phaseDataChanged();
emit modified(); emit modified();
} }
@ -946,7 +947,7 @@ void FlightModePanel::cmPaste()
} }
} }
emit datachanged(); emit phaseDataChanged();
emit modified(); 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); model->updateAllReferences(ModelData::REF_UPD_TYPE_FLIGHT_MODE, ModelData::REF_UPD_ACT_SWAP, idx1, idx2);
emit datachanged(); emit phaseDataChanged();
emit modified(); emit modified();
} }
@ -1162,7 +1163,8 @@ void FlightModePanel::gvCmClear(bool prompt)
} }
phase.gvars[gvIdx] = phase.linkedGVarFlightModeZero(phaseIdx); phase.gvars[gvIdx] = phase.linkedGVarFlightModeZero(phaseIdx);
} }
emit datachanged(); updateGVar(gvIdx);
emit gvNameChanged();
emit modified(); emit modified();
} }
@ -1186,7 +1188,10 @@ void FlightModePanel::gvCmClearAll()
phase.gvars[i] = phase.linkedGVarFlightModeZero(phaseIdx); phase.gvars[i] = phase.linkedGVarFlightModeZero(phaseIdx);
} }
} }
emit datachanged(); for (int i = 0; i < gvCount; i++) {
updateGVar(i);
}
emit gvNameChanged();
emit modified(); emit modified();
} }
@ -1261,8 +1266,13 @@ void FlightModePanel::gvCmDelete()
for (int j = 0; j < fmCount; j++) { for (int j = 0; j < fmCount; j++) {
model->flightModeData[j].gvars[maxidx] = model->flightModeData[j].linkedGVarFlightModeZero(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); 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(); emit modified();
} }
@ -1279,7 +1289,10 @@ void FlightModePanel::gvCmInsert()
model->flightModeData[j].gvars[gvIdx] = model->flightModeData[j].linkedGVarFlightModeZero(j); 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); 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(); emit modified();
} }
@ -1322,7 +1335,8 @@ void FlightModePanel::gvCmPaste()
else else
phase.gvars[gvIdx] = val; phase.gvars[gvIdx] = val;
} }
emit datachanged(); updateGVar(gvIdx);
emit gvNameChanged();
emit modified(); emit modified();
} }
@ -1340,33 +1354,51 @@ void FlightModePanel::gvSwapData(int idx1, int idx2)
model->flightModeData[j].gvars[idx1] = valtmp; model->flightModeData[j].gvars[idx1] = valtmp;
} }
model->updateAllReferences(ModelData::REF_UPD_TYPE_GLOBAL_VARIABLE, ModelData::REF_UPD_ACT_SWAP, idx1, idx2); 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(); 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), ModelPanel(parent, model, generalSettings, firmware),
modesCount(firmware->getCapability(FlightModes)) commonItemModels(commonItemModels)
{ {
rawSwitchFilteredModel = new RawItemFilteredModel(commonItemModels->rawSwitchItemModel(), RawSwitch::MixesContext, this);
RawSwitchFilterItemModel * swModel = new RawSwitchFilterItemModel(&generalSettings, &model, RawSwitch::MixesContext, this); modesCount = firmware->getCapability(FlightModes);
connect(this, &FlightModesPanel::updated, swModel, &RawSwitchFilterItemModel::update);
QGridLayout * gridLayout = new QGridLayout(this); QGridLayout * gridLayout = new QGridLayout(this);
tabWidget = new QTabWidget(this); tabWidget = new QTabWidget(this);
for (int i = 0; i < modesCount; i++) { 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); tab->setProperty("index", i);
connect(tab, &FlightModePanel::datachanged, this, &FlightModesPanel::update); connect(tab, &FlightModePanel::modified, this, &FlightModesPanel::modified);
connect(tab, &FlightModePanel::modified, this, &FlightModesPanel::modified); connect(tab, &FlightModePanel::phaseDataChanged, this, &FlightModesPanel::onPhaseNameChanged);
connect(tab, &FlightModePanel::nameModified, this, &FlightModesPanel::onPhaseNameChanged); connect(tab, &FlightModePanel::phaseNameChanged, this, &FlightModesPanel::onPhaseNameChanged);
connect(this, &FlightModesPanel::updated, tab, &FlightModePanel::update); 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)); tabWidget->addTab(tab, getTabName(i));
panels << tab;
} }
connect(tabWidget, &QTabWidget::currentChanged, this, &FlightModesPanel::onTabIndexChanged);
gridLayout->addWidget(tabWidget, 0, 0, 1, 1); gridLayout->addWidget(tabWidget, 0, 0, 1, 1);
onTabIndexChanged(0);
} }
FlightModesPanel::~FlightModesPanel() FlightModesPanel::~FlightModesPanel()
@ -1391,9 +1423,22 @@ void FlightModesPanel::onPhaseNameChanged()
{ {
int index = sender()->property("index").toInt(); int index = sender()->property("index").toInt();
tabWidget->setTabText(index, getTabName(index)); tabWidget->setTabText(index, getTabName(index));
updateItemModels();
} }
void FlightModesPanel::update() void FlightModesPanel::update()
{ {
emit updated(); 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 "modeledit.h"
#include "eeprominterface.h" #include "eeprominterface.h"
class RawSwitchFilterItemModel; class CommonItemModels;
class RawItemFilteredModel;
constexpr char MIMETYPE_FLIGHTMODE[] = "application/x-companion-flightmode"; constexpr char MIMETYPE_FLIGHTMODE[] = "application/x-companion-flightmode";
constexpr char MIMETYPE_GVAR_PARAMS[] = "application/x-companion-gvar-params"; constexpr char MIMETYPE_GVAR_PARAMS[] = "application/x-companion-gvar-params";
@ -40,18 +41,20 @@ class FlightModePanel : public ModelPanel
Q_OBJECT Q_OBJECT
public: 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 ~FlightModePanel();
virtual void update(); virtual void update();
signals: signals:
void nameModified(); void gvNameChanged();
void datachanged(); void phaseDataChanged();
void phaseNameChanged();
void phaseSwitchChanged();
private slots: private slots:
void phaseName_editingFinished(); void phaseName_editingFinished();
void phaseSwitchChanged(int index); void phaseSwitch_currentIndexChanged(int index);
void phaseFadeIn_editingFinished(); void phaseFadeIn_editingFinished();
void phaseFadeOut_editingFinished(); void phaseFadeOut_editingFinished();
void phaseTrimUse_currentIndexChanged(int index); void phaseTrimUse_currentIndexChanged(int index);
@ -87,6 +90,8 @@ class FlightModePanel : public ModelPanel
void gvCmPaste(); void gvCmPaste();
void gvCmMoveDown(); void gvCmMoveDown();
void gvCmMoveUp(); void gvCmMoveUp();
void onModelDataAboutToBeUpdated();
void onModelDataUpdateComplete();
private: private:
Ui::FlightMode *ui; Ui::FlightMode *ui;
@ -111,7 +116,6 @@ class FlightModePanel : public ModelPanel
QVector<QComboBox *> trimsUse; QVector<QComboBox *> trimsUse;
QVector<QSpinBox *> trimsValue; QVector<QSpinBox *> trimsValue;
QVector<QSlider *> trimsSlider; QVector<QSlider *> trimsSlider;
RawSwitchFilterItemModel * rawSwitchItemModel;
Board::Type board; Board::Type board;
void trimUpdate(unsigned int trim); void trimUpdate(unsigned int trim);
@ -141,7 +145,7 @@ class FlightModesPanel : public ModelPanel
Q_OBJECT Q_OBJECT
public: public:
FlightModesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware); FlightModesPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels);
virtual ~FlightModesPanel(); virtual ~FlightModesPanel();
public slots: public slots:
@ -152,13 +156,17 @@ class FlightModesPanel : public ModelPanel
private slots: private slots:
void onPhaseNameChanged(); void onPhaseNameChanged();
void onTabIndexChanged(int index);
private: private:
QString getTabName(int index); QString getTabName(int index);
int modesCount; int modesCount;
QTabWidget *tabWidget; QTabWidget *tabWidget;
CommonItemModels *commonItemModels;
RawItemFilteredModel *rawSwitchFilteredModel;
QVector<GenericPanel *> panels;
void updateItemModels();
}; };
#endif // _FLIGHTMODES_H_ #endif // _FLIGHTMODES_H_

View file

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

View file

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

View file

@ -21,12 +21,22 @@
#include "inputs.h" #include "inputs.h"
#include "expodialog.h" #include "expodialog.h"
#include "helpers.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), ModelPanel(parent, model, generalSettings, firmware),
expoInserted(false), 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); inputsCount = firmware->getCapability(VirtualInputs);
if (inputsCount == 0) if (inputsCount == 0)
inputsCount = CPN_MAX_STICKS; inputsCount = CPN_MAX_STICKS;
@ -180,13 +190,14 @@ void InputsPanel::gm_openExpo(int index)
if (firmware->getCapability(VirtualInputs)) if (firmware->getCapability(VirtualInputs))
inputName = model->inputNames[ed.chn]; inputName = model->inputNames[ed.chn];
ExpoDialog *g = new ExpoDialog(this, *model, &ed, generalSettings, firmware, inputName); ExpoDialog *dlg = new ExpoDialog(this, *model, &ed, generalSettings, firmware, inputName, rawSourceFilteredModel, rawSwitchFilteredModel);
if (g->exec()) { if (dlg->exec()) {
model->expoData[index] = ed; model->expoData[index] = ed;
if (firmware->getCapability(VirtualInputs)) if (firmware->getCapability(VirtualInputs))
strncpy(model->inputNames[ed.chn], inputName.toLatin1().data(), INPUT_NAME_LEN); strncpy(model->inputNames[ed.chn], inputName.toLatin1().data(), INPUT_NAME_LEN);
emit modified();
update(); update();
updateItemModels();
emit modified();
} }
else { else {
if (expoInserted) { if (expoInserted) {
@ -195,6 +206,7 @@ void InputsPanel::gm_openExpo(int index)
expoInserted=false; expoInserted=false;
update(); update();
} }
delete dlg;
} }
int InputsPanel::getExpoIndex(unsigned int dch) int InputsPanel::getExpoIndex(unsigned int dch)
@ -239,8 +251,9 @@ void InputsPanel::exposDelete(bool prompt)
} }
exposDeleteList(list, prompt); exposDeleteList(list, prompt);
emit modified();
update(); update();
updateItemModels();
emit modified();
} }
void InputsPanel::exposCut() void InputsPanel::exposCut()
@ -313,8 +326,9 @@ void InputsPanel::pasteExpoMimeData(const QMimeData * mimeData, int destIdx)
i += sizeof(ExpoData); i += sizeof(ExpoData);
} }
emit modified();
update(); update();
updateItemModels();
emit modified();
} }
} }
@ -481,8 +495,9 @@ void InputsPanel::moveExpoList(bool down)
} }
} }
if (mod) { if (mod) {
emit modified();
update(); update();
updateItemModels();
emit modified();
} }
setSelectedByExpoList(highlightList); setSelectedByExpoList(highlightList);
} }
@ -520,8 +535,9 @@ void InputsPanel::clearExpos()
for (int i = 0; i < inputsCount; i++) { for (int i = 0; i < inputsCount; i++) {
model->updateAllReferences(ModelData::REF_UPD_TYPE_INPUT, ModelData::REF_UPD_ACT_CLEAR, i); model->updateAllReferences(ModelData::REF_UPD_TYPE_INPUT, ModelData::REF_UPD_ACT_CLEAR, i);
} }
emit modified();
update(); update();
updateItemModels();
emit modified();
} }
} }
@ -569,6 +585,7 @@ void InputsPanel::cmInputClear()
} }
model->updateAllReferences(ModelData::REF_UPD_TYPE_INPUT, ModelData::REF_UPD_ACT_CLEAR, inputIdx); model->updateAllReferences(ModelData::REF_UPD_TYPE_INPUT, ModelData::REF_UPD_ACT_CLEAR, inputIdx);
update(); update();
updateItemModels();
emit modified(); emit modified();
} }
@ -592,6 +609,7 @@ void InputsPanel::cmInputDelete()
model->updateAllReferences(ModelData::REF_UPD_TYPE_INPUT, ModelData::REF_UPD_ACT_SHIFT, inputIdx, 0, -1); model->updateAllReferences(ModelData::REF_UPD_TYPE_INPUT, ModelData::REF_UPD_ACT_SHIFT, inputIdx, 0, -1);
update(); update();
updateItemModels();
emit modified(); emit modified();
} }
@ -610,6 +628,7 @@ void InputsPanel::cmInputInsert()
model->updateAllReferences(ModelData::REF_UPD_TYPE_INPUT, ModelData::REF_UPD_ACT_SHIFT, inputIdx, 0, 1); model->updateAllReferences(ModelData::REF_UPD_TYPE_INPUT, ModelData::REF_UPD_ACT_SHIFT, inputIdx, 0, 1);
update(); update();
updateItemModels();
emit modified(); 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); model->updateAllReferences(ModelData::REF_UPD_TYPE_INPUT, ModelData::REF_UPD_ACT_SWAP, idx1, idx2);
update(); update();
updateItemModels();
emit modified(); emit modified();
} }
@ -705,3 +725,19 @@ int InputsPanel::getInputIndexFromSelected()
} }
return idx; 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 "mixerslistwidget.h"
#include "modelprinter.h" #include "modelprinter.h"
class CommonItemModels;
class RawItemFilteredModel;
constexpr char MIMETYPE_EXPO[] = "application/x-companion-expo"; constexpr char MIMETYPE_EXPO[] = "application/x-companion-expo";
class InputsPanel : public ModelPanel class InputsPanel : public ModelPanel
@ -32,7 +35,7 @@ class InputsPanel : public ModelPanel
Q_OBJECT Q_OBJECT
public: public:
InputsPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware); InputsPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels);
virtual ~InputsPanel(); virtual ~InputsPanel();
virtual void update(); virtual void update();
@ -59,6 +62,8 @@ class InputsPanel : public ModelPanel
void cmInputInsert(); void cmInputInsert();
void cmInputMoveDown(); void cmInputMoveDown();
void cmInputMoveUp(); void cmInputMoveUp();
void onModelDataAboutToBeUpdated();
void onModelDataUpdateComplete();
private: private:
bool expoInserted; bool expoInserted;
@ -67,6 +72,9 @@ class InputsPanel : public ModelPanel
ModelPrinter modelPrinter; ModelPrinter modelPrinter;
int selectedIdx; int selectedIdx;
int inputIdx; int inputIdx;
CommonItemModels * commonItemModels;
RawItemFilteredModel *rawSourceFilteredModel;
RawItemFilteredModel *rawSwitchFilteredModel;
int getExpoIndex(unsigned int dch); int getExpoIndex(unsigned int dch);
bool gm_insertExpo(int idx); bool gm_insertExpo(int idx);
@ -87,6 +95,7 @@ class InputsPanel : public ModelPanel
bool isExpoIndex(const int index); bool isExpoIndex(const int index);
int getIndexFromSelected(); int getIndexFromSelected();
int getInputIndexFromSelected(); int getInputIndexFromSelected();
void updateItemModels();
}; };
#endif // _INPUTS_H_ #endif // _INPUTS_H_

View file

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

View file

@ -24,7 +24,8 @@
#include "rawitemfilteredmodel.h" #include "rawitemfilteredmodel.h"
#include "helpers.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), QDialog(parent),
ui(new Ui::MixerDialog), ui(new Ui::MixerDialog),
model(model), model(model),
@ -34,18 +35,18 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata,
lock(false) lock(false)
{ {
ui->setupUi(this); ui->setupUi(this);
QRegExp rx(CHAR_FOR_NAMES_REGEX); 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 }; 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 }; 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++) { for (int i = 0; i < CPN_MAX_FLIGHT_MODES; i++) {
cb_fp[i] = tmp[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->setCurrentIndex(ui->sourceCB->findData(md->srcRaw.toValue()));
ui->sourceCB->removeItem(0);
int limit = firmware->getCapability(OffsetWeight); int limit = firmware->getCapability(OffsetWeight);
@ -62,7 +63,7 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata,
} }
if (!firmware->getCapability(VirtualInputs)) { 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)); ui->trimCB->addItem(firmware->getAnalogInputName(i));
} }
} }
@ -82,7 +83,7 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata,
if (!firmware->getCapability(FlightModes)) { if (!firmware->getCapability(FlightModes)) {
ui->label_phases->hide(); 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(); lb_fp[i]->hide();
cb_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); ui->label_phases->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->label_phases, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(label_phases_customContextMenuRequested(const QPoint &))); connect(ui->label_phases, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(label_phases_customContextMenuRequested(const QPoint &)));
int mask = 1; 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) { if ((md->flightModes & mask) == 0) {
cb_fp[i]->setChecked(true); cb_fp[i]->setChecked(true);
} }
mask <<= 1; 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(); lb_fp[i]->hide();
cb_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->switchesCB->setCurrentIndex(ui->switchesCB->findData(md->swtch.toValue()));
ui->warningCB->setCurrentIndex(md->mixWarn); ui->warningCB->setCurrentIndex(md->mixWarn);
ui->mltpxCB->setCurrentIndex(md->mltpx); ui->mltpxCB->setCurrentIndex(md->mltpx);
int scale=firmware->getCapability(SlowScale); int scale=firmware->getCapability(SlowScale);
float range=firmware->getCapability(SlowRange); float range=firmware->getCapability(SlowRange);
ui->slowDownSB->setMaximum(range/scale); ui->slowDownSB->setMaximum(range / scale);
ui->slowDownSB->setSingleStep(1.0/scale); ui->slowDownSB->setSingleStep(1.0 / scale);
ui->slowDownSB->setDecimals((scale==1 ? 0 :1)); ui->slowDownSB->setDecimals((scale == 1 ? 0 : 1));
ui->slowDownSB->setValue((float)md->speedDown/scale); ui->slowDownSB->setValue((float)md->speedDown/scale);
ui->slowUpSB->setMaximum(range/scale); ui->slowUpSB->setMaximum(range / scale);
ui->slowUpSB->setSingleStep(1.0/scale); ui->slowUpSB->setSingleStep(1.0 / scale);
ui->slowUpSB->setDecimals((scale==1 ? 0 :1)); ui->slowUpSB->setDecimals((scale == 1 ? 0 : 1));
ui->slowUpSB->setValue((float)md->speedUp/scale); ui->slowUpSB->setValue((float)md->speedUp/scale);
ui->delayDownSB->setMaximum(range/scale); ui->delayDownSB->setMaximum(range / scale);
ui->delayDownSB->setSingleStep(1.0/scale); ui->delayDownSB->setSingleStep(1.0 / scale);
ui->delayDownSB->setDecimals((scale==1 ? 0 :1)); ui->delayDownSB->setDecimals((scale == 1 ? 0 : 1));
ui->delayDownSB->setValue((float)md->delayDown/scale); ui->delayDownSB->setValue((float)md->delayDown / scale);
ui->delayUpSB->setMaximum(range/scale); ui->delayUpSB->setMaximum(range / scale);
ui->delayUpSB->setSingleStep(1.0/scale); ui->delayUpSB->setSingleStep(1.0 / scale);
ui->delayUpSB->setDecimals((scale==1 ? 0 :1)); ui->delayUpSB->setDecimals((scale == 1 ? 0 : 1));
ui->delayUpSB->setValue((float)md->delayUp/scale); ui->delayUpSB->setValue((float)md->delayUp / scale);
QTimer::singleShot(0, this, SLOT(shrink())); QTimer::singleShot(0, this, SLOT(shrink()));
valuesChanged(); valuesChanged();
@ -147,10 +148,10 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata,
MixerDialog::~MixerDialog() MixerDialog::~MixerDialog()
{ {
delete ui;
delete gvWeightGroup; delete gvWeightGroup;
delete gvOffsetGroup; delete gvOffsetGroup;
delete curveGroup; delete curveGroup;
delete ui;
} }
void MixerDialog::changeEvent(QEvent *e) void MixerDialog::changeEvent(QEvent *e)
@ -176,20 +177,20 @@ void MixerDialog::valuesChanged()
ui->MixDR_CB->setEnabled(drVisible); ui->MixDR_CB->setEnabled(drVisible);
ui->label_MixDR->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->noExpo = ui->MixDR_CB->checkState() ? 0 : 1;
md->swtch = RawSwitch(ui->switchesCB->itemData(ui->switchesCB->currentIndex()).toInt()); md->swtch = RawSwitch(ui->switchesCB->itemData(ui->switchesCB->currentIndex()).toInt());
md->mixWarn = ui->warningCB->currentIndex(); md->mixWarn = ui->warningCB->currentIndex();
md->mltpx = (MltpxValue)ui->mltpxCB->currentIndex(); md->mltpx = (MltpxValue)ui->mltpxCB->currentIndex();
int scale = firmware->getCapability(SlowScale); int scale = firmware->getCapability(SlowScale);
md->delayDown = round(ui->delayDownSB->value()*scale); md->delayDown = round(ui->delayDownSB->value() * scale);
md->delayUp = round(ui->delayUpSB->value()*scale); md->delayUp = round(ui->delayUpSB->value() * scale);
md->speedDown = round(ui->slowDownSB->value()*scale); md->speedDown = round(ui->slowDownSB->value() * scale);
md->speedUp = round(ui->slowUpSB->value()*scale); md->speedUp = round(ui->slowUpSB->value() * scale);
strcpy(md->name, ui->mixerName->text().toLatin1()); strcpy(md->name, ui->mixerName->text().toLatin1());
md->flightModes = 0; 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()) { if (!cb_fp[i]->checkState()) {
md->flightModes++; md->flightModes++;
} }
@ -220,7 +221,7 @@ void MixerDialog::label_phases_customContextMenuRequested(const QPoint & pos)
void MixerDialog::fmClearAll() void MixerDialog::fmClearAll()
{ {
lock = true; 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); cb_fp[i]->setChecked(false);
} }
lock = false; lock = false;
@ -230,7 +231,7 @@ void MixerDialog::fmClearAll()
void MixerDialog::fmSetAll() void MixerDialog::fmSetAll()
{ {
lock = true; 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); cb_fp[i]->setChecked(true);
} }
lock = false; lock = false;
@ -240,7 +241,7 @@ void MixerDialog::fmSetAll()
void MixerDialog::fmInvertAll() void MixerDialog::fmInvertAll()
{ {
lock = true; 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()); cb_fp[i]->setChecked(!cb_fp[i]->isChecked());
} }
lock = false; lock = false;

View file

@ -26,6 +26,7 @@
class GVarGroup; class GVarGroup;
class CurveGroup; class CurveGroup;
class RawItemFilteredModel;
namespace Ui { namespace Ui {
class MixerDialog; class MixerDialog;
@ -34,7 +35,8 @@ namespace Ui {
class MixerDialog : public QDialog { class MixerDialog : public QDialog {
Q_OBJECT Q_OBJECT
public: 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(); ~MixerDialog();
protected: protected:

View file

@ -20,13 +20,23 @@
#include "mixes.h" #include "mixes.h"
#include "helpers.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), ModelPanel(parent, model, generalSettings, firmware),
mixInserted(false), mixInserted(false),
highlightedSource(0), 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); QGridLayout * mixesLayout = new QGridLayout(this);
mixersListWidget = new MixersListWidget(this, false); // TODO enum mixersListWidget = new MixersListWidget(this, false); // TODO enum
@ -175,8 +185,8 @@ void MixesPanel::gm_openMix(int index)
MixData mixd(model->mixData[index]); MixData mixd(model->mixData[index]);
MixerDialog *g = new MixerDialog(this, *model, &mixd, generalSettings, firmware); MixerDialog *dlg = new MixerDialog(this, *model, &mixd, generalSettings, firmware, rawSourceFilteredModel, rawSwitchFilteredModel);
if(g->exec()) { if(dlg->exec()) {
model->mixData[index] = mixd; model->mixData[index] = mixd;
emit modified(); emit modified();
update(); update();
@ -188,6 +198,7 @@ void MixesPanel::gm_openMix(int index)
mixInserted = false; mixInserted = false;
update(); update();
} }
delete dlg;
} }
int MixesPanel::getMixerIndex(unsigned int dch) int MixesPanel::getMixerIndex(unsigned int dch)
@ -529,3 +540,14 @@ void MixesPanel::clearMixes()
update(); update();
} }
} }
void MixesPanel::onModelDataAboutToBeUpdated()
{
lock = true;
}
void MixesPanel::onModelDataUpdateComplete()
{
update();
lock = false;
}

View file

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

View file

@ -33,6 +33,7 @@
#include "customfunctions.h" #include "customfunctions.h"
#include "telemetry.h" #include "telemetry.h"
#include "appdata.h" #include "appdata.h"
#include "rawitemdatamodels.h"
ModelEdit::ModelEdit(QWidget * parent, RadioData & radioData, int modelId, Firmware * firmware) : ModelEdit::ModelEdit(QWidget * parent, RadioData & radioData, int modelId, Firmware * firmware) :
QDialog(parent), QDialog(parent),
@ -48,33 +49,55 @@ ModelEdit::ModelEdit(QWidget * parent, RadioData & radioData, int modelId, Firmw
setWindowIcon(CompanionIcon("edit.png")); setWindowIcon(CompanionIcon("edit.png"));
restoreGeometry(g.modelEditGeo()); restoreGeometry(g.modelEditGeo());
ui->pushButton->setIcon(CompanionIcon("simulate.png")); 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")); addTab(setupPanel, tr("Setup"));
if (firmware->getCapability(Heli)) s1.report("Setup");
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")); if (firmware->getCapability(Heli)) {
addTab(new InputsPanel(this, radioData.models[modelId], radioData.generalSettings, firmware), tr("Inputs")); addTab(new HeliPanel(this, model, generalSettings, firmware, commonItemModels), tr("Heli"));
s1.report("inputs"); s1.report("Heli");
addTab(new MixesPanel(this, radioData.models[modelId], radioData.generalSettings, firmware), tr("Mixes")); }
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"); 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"); 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->tabWidget, &QTabWidget::currentChanged, this, &ModelEdit::onTabIndexChanged);
connect(ui->pushButton, &QPushButton::clicked, this, &ModelEdit::launchSimulation); 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"); gStopwatch.report("ModelEdit end constructor");
} }

View file

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

View file

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

View file

@ -28,18 +28,20 @@
#include <TimerEdit> #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), ModelPanel(parent, model, generalSettings, firmware),
ui(new Ui::TelemetryCustomScreen), ui(new Ui::TelemetryCustomScreen),
screen(screen) screen(screen)
{ {
ui->setupUi(this); 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 l = 0; l < firmware->getCapability(TelemetryCustomScreensLines); l++) {
for (int c = 0; c < firmware->getCapability(TelemetryCustomScreensFieldsPerLine); c++) { for (int c = 0; c < firmware->getCapability(TelemetryCustomScreensFieldsPerLine); c++) {
fieldsCB[l][c] = new QComboBox(this); fieldsCB[l][c] = new QComboBox(this);
fieldsCB[l][c]->setProperty("index", c + (l << 8)); 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); ui->screenNumsLayout->addWidget(fieldsCB[l][c], l, c, 1, 1);
connect(fieldsCB[l][c], SIGNAL(activated(int)), this, SLOT(customFieldChanged(int))); 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++) { for (int l = 0; l < firmware->getCapability(TelemetryCustomScreensBars); l++) {
barsCB[l] = new QComboBox(this); barsCB[l] = new QComboBox(this);
barsCB[l]->setProperty("index", l); barsCB[l]->setProperty("index", l);
barsCB[l]->setModel(srcModel); barsCB[l]->setModel(rawSourceModel);
connect(barsCB[l], SIGNAL(activated(int)), this, SLOT(barSourceChanged(int))); connect(barsCB[l], SIGNAL(activated(int)), this, SLOT(barSourceChanged(int)));
ui->screenBarsLayout->addWidget(barsCB[l], l, 0, 1, 1); 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): 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()); QFontMetrics *f = new QFontMetrics(QFont());
QSize sz; QSize sz;
sz = f->size(Qt::TextSingleLine, "TELE00"); sz = f->size(Qt::TextSingleLine, "TELE00");
delete f;
ui->numLabel->setMinimumWidth(sz.width()); ui->numLabel->setMinimumWidth(sz.width());
ui->numLabel->setContextMenuPolicy(Qt::CustomContextMenu); ui->numLabel->setContextMenuPolicy(Qt::CustomContextMenu);
ui->numLabel->setToolTip(tr("Popup menu available")); ui->numLabel->setToolTip(tr("Popup menu available"));
@ -505,7 +519,6 @@ void TelemetrySensorPanel::on_name_editingFinished()
if (!lock) { if (!lock) {
strcpy(sensor.label, ui->name->text().toLatin1()); strcpy(sensor.label, ui->name->text().toLatin1());
emit dataModified(); emit dataModified();
emit modified();
} }
} }
@ -535,7 +548,6 @@ void TelemetrySensorPanel::on_formula_currentIndexChanged(int index)
sensor.unit = SensorData::UNIT_METERS; sensor.unit = SensorData::UNIT_METERS;
} }
emit dataModified(); emit dataModified();
emit modified();
} }
} }
@ -631,7 +643,6 @@ void TelemetrySensorPanel::cmPaste()
if (hasClipboardData(&data)) { if (hasClipboardData(&data)) {
memcpy(&sensor, data.constData(), sizeof(SensorData)); memcpy(&sensor, data.constData(), sizeof(SensorData));
emit dataModified(); emit dataModified();
emit modified();
} }
} }
@ -645,7 +656,6 @@ void TelemetrySensorPanel::cmClear(bool prompt)
sensor.clear(); sensor.clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_CLEAR, selectedIndex); model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_CLEAR, selectedIndex);
emit dataModified(); emit dataModified();
emit modified();
} }
void TelemetrySensorPanel::cmClearAll() 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), ModelPanel(parent, model, generalSettings, firmware),
ui(new Ui::Telemetry) ui(new Ui::Telemetry),
commonItemModels(commonItemModels)
{ {
ui->setupUi(this); ui->setupUi(this);
rawSourceFilteredModel = new RawItemFilteredModel(commonItemModels->rawSourceItemModel(), this);
sensorCapability = firmware->getCapability(Sensors); sensorCapability = firmware->getCapability(Sensors);
if (sensorCapability > CPN_MAX_SENSORS) // TODO should be role of getCapability 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->varioCenterSilent->setField(model.frsky.varioCenterSilent, this);
ui->A1GB->hide(); ui->A1GB->hide();
ui->A2GB->hide(); ui->A2GB->hide();
for (int i = 0; i < sensorCapability; ++i) { for (int i = 0; i < sensorCapability; ++i) {
TelemetrySensorPanel * panel = new TelemetrySensorPanel(this, model.sensorData[i], i, sensorCapability, model, generalSettings, firmware); TelemetrySensorPanel * panel = new TelemetrySensorPanel(this, model.sensorData[i], i, sensorCapability, model, generalSettings, firmware);
ui->sensorsLayout->addWidget(panel); ui->sensorsLayout->addWidget(panel);
sensorPanels[i] = 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(modified()), this, SLOT(onModified()));
connect(panel, SIGNAL(clearAllSensors()), this, SLOT(on_clearAllSensors())); connect(panel, SIGNAL(clearAllSensors()), this, SLOT(on_clearAllSensors()));
connect(panel, SIGNAL(insertSensor(int)), this, SLOT(on_insertSensor(int))); connect(panel, SIGNAL(insertSensor(int)), this, SLOT(on_insertSensor(int)));
@ -717,15 +730,11 @@ TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettin
ui->topbarGB->hide(); 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++) { 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)); ui->customScreens->addTab(tab, tr("Telemetry screen %1").arg(i + 1));
telemetryCustomScreens[i] = tab; telemetryCustomScreens[i] = tab;
connect(tab, &TelemetryCustomScreen::modified, this, &TelemetryPanel::onModified); connect(tab, &TelemetryCustomScreen::modified, this, &TelemetryPanel::onModified);
connect(this, &TelemetryPanel::updated, tab, &TelemetryCustomScreen::update);
} }
disableMouseScrolling(); disableMouseScrolling();
@ -759,79 +768,78 @@ void TelemetryPanel::update()
sensorPanels[i]->update(); sensorPanels[i]->update();
} }
emit updated(); for (int i = 0; i < firmware->getCapability(TelemetryCustomScreens); i++) {
telemetryCustomScreens[i]->update();
}
} }
void TelemetryPanel::setup() 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->rssiAlarmWarningSB->setValue(model->rssiAlarms.warning);
ui->telemetryProtocol->addItem(tr("FrSky D"), 1); ui->rssiAlarmCriticalSB->setValue(model->rssiAlarms.critical);
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->rssiSourceLabel->show();
ui->rssiAlarmCriticalSB->setValue(model->rssiAlarms.critical); ui->rssiSourceLabel->setText(tr("Source"));
ui->rssiSourceCB->setField(model->rssiSource, this);
ui->rssiSourceCB->show();
populateTelemetrySourcesComboBox(ui->rssiSourceCB, model, false);
ui->rssiSourceLabel->show(); ui->rssiAlarmWarningCB->hide();
ui->rssiSourceLabel->setText(tr("Source")); ui->rssiAlarmCriticalCB->hide();
ui->rssiSourceCB->setField(model->rssiSource, this); ui->rssiAlarmWarningLabel->setText(tr("Low Alarm"));
ui->rssiSourceCB->show(); ui->rssiAlarmCriticalLabel->setText(tr("Critical Alarm"));
populateTelemetrySourcesComboBox(ui->rssiSourceCB, model, false);
ui->rssiAlarmWarningCB->hide(); if (!firmware->getCapability(HasVario)) {
ui->rssiAlarmCriticalCB->hide(); ui->varioLimitMax_DSB->hide();
ui->rssiAlarmWarningLabel->setText(tr("Low Alarm")); ui->varioLimitMin_DSB->hide();
ui->rssiAlarmCriticalLabel->setText(tr("Critical Alarm")); ui->varioLimitCenterMin_DSB->hide();
ui->varioLimitCenterMax_DSB->hide();
int varioCap = firmware->getCapability(HasVario); ui->varioLimit_label->hide();
if (!varioCap) { ui->VarioLabel_1->hide();
ui->varioLimitMax_DSB->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->varioLimitMin_DSB->hide();
ui->varioLimitCenterMin_DSB->hide(); ui->varioLimitCenterMin_DSB->hide();
ui->varioLimitCenterMax_DSB->hide();
ui->varioLimit_label->hide();
ui->VarioLabel_1->hide(); ui->VarioLabel_1->hide();
ui->VarioLabel_2->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->altimetryGB->setVisible(firmware->getCapability(HasVario)),
ui->frskyProtoCB->setDisabled(firmware->getCapability(NoTelemetryProtocol)); ui->frskyProtoCB->setDisabled(firmware->getCapability(NoTelemetryProtocol));
if (firmware->getCapability(Telemetry)) { if (firmware->getCapability(Telemetry)) {
ui->frskyProtoCB->addItem(tr("Winged Shadow How High")); ui->frskyProtoCB->addItem(tr("Winged Shadow How High"));
} }
else { else {
ui->frskyProtoCB->addItem(tr("Winged Shadow How High (not supported)")); ui->frskyProtoCB->addItem(tr("Winged Shadow How High (not supported)"));
} }
ui->variousGB->hide(); ui->variousGB->hide();
lock = false; lock = false;
} }
void TelemetryPanel::populateVarioSource() void TelemetryPanel::populateVarioSource()
@ -972,6 +980,7 @@ void TelemetryPanel::on_clearAllSensors()
model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_CLEAR, i); model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_CLEAR, i);
} }
updateItemModels();
update(); update();
emit modified(); emit modified();
} }
@ -982,6 +991,7 @@ void TelemetryPanel::on_insertSensor(int selectedIndex)
model->sensorData[selectedIndex].clear(); model->sensorData[selectedIndex].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, 1); model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, 1);
updateItemModels();
update(); update();
emit modified(); emit modified();
} }
@ -995,6 +1005,7 @@ void TelemetryPanel::on_deleteSensor(int selectedIndex)
model->sensorData[CPN_MAX_SENSORS - 1].clear(); model->sensorData[CPN_MAX_SENSORS - 1].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, -1); model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, -1);
updateItemModels();
update(); update();
emit modified(); emit modified();
} }
@ -1018,7 +1029,20 @@ void TelemetryPanel::swapData(int idx1, int idx2)
memcpy(sd2, sd1, sizeof(SensorData)); memcpy(sd2, sd1, sizeof(SensorData));
memcpy(sd1, &sdtmp, sizeof(SensorData)); memcpy(sd1, &sdtmp, sizeof(SensorData));
model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_SWAP, idx1, idx2); model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_SWAP, idx1, idx2);
updateItemModels();
update(); update();
emit modified(); 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"; constexpr char MIMETYPE_TELE_SENSOR[] = "application/x-companion-tele-sensor";
class AutoComboBox; class AutoComboBox;
class RawSourceFilterItemModel; class CommonItemModels;
class RawItemFilteredModel;
class TimerEdit; class TimerEdit;
namespace Ui { namespace Ui {
@ -41,7 +42,7 @@ class TelemetryCustomScreen: public ModelPanel
Q_OBJECT Q_OBJECT
public: 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(); ~TelemetryCustomScreen();
void update(); void update();
@ -53,6 +54,8 @@ class TelemetryCustomScreen: public ModelPanel
void barMinChanged(double value); void barMinChanged(double value);
void barMaxChanged(double value); void barMaxChanged(double value);
void barTimeChanged(); void barTimeChanged();
void onModelDataAboutToBeUpdated();
void onModelDataUpdateComplete();
private: private:
void updateBar(int line); void updateBar(int line);
@ -122,7 +125,7 @@ class TelemetryPanel : public ModelPanel
Q_OBJECT Q_OBJECT
public: public:
TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware); TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware, CommonItemModels * commonItemModels);
virtual ~TelemetryPanel(); virtual ~TelemetryPanel();
virtual void update(); virtual void update();
@ -148,12 +151,15 @@ class TelemetryPanel : public ModelPanel
void on_deleteSensor(int index); void on_deleteSensor(int index);
void on_moveUpSensor(int index); void on_moveUpSensor(int index);
void on_moveDownSensor(int index); void on_moveDownSensor(int index);
void on_dataModifiedSensor();
private: private:
Ui::Telemetry *ui; Ui::Telemetry *ui;
TelemetryCustomScreen * telemetryCustomScreens[4]; TelemetryCustomScreen * telemetryCustomScreens[4];
TelemetrySensorPanel * sensorPanels[CPN_MAX_SENSORS]; TelemetrySensorPanel * sensorPanels[CPN_MAX_SENSORS];
int sensorCapability; int sensorCapability;
CommonItemModels * commonItemModels;
RawItemFilteredModel * rawSourceFilteredModel;
void setup(); void setup();
void telBarUpdate(); void telBarUpdate();
@ -161,6 +167,7 @@ class TelemetryPanel : public ModelPanel
void populateCurrentSource(); void populateCurrentSource();
void populateVarioSource(); void populateVarioSource();
void swapData(int idx1, int idx2); void swapData(int idx1, int idx2);
void updateItemModels();
}; };
#endif // _TELEMETRY_H_ #endif // _TELEMETRY_H_

View file

@ -96,6 +96,14 @@ bool menuModelLimits(event_t event)
uint32_t sub = menuVerticalPosition; 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) { if (sub<MAX_OUTPUT_CHANNELS && menuHorizontalPosition>=0) {
drawColumnHeader(STR_LIMITS_HEADERS, NULL, menuHorizontalPosition); 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_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()) #define EVT_KEY_NEXT_VIEW(evt) (evt == EVT_KEY_LONG(KEY_RIGHT) && IS_SHIFT_PRESSED())
#elif defined(NAVIGATION_X7_TX12) #elif defined(NAVIGATION_X7_TX12)
#define EVT_KEY_PREVIOUS_VIEW(evt) (evt == EVT_KEY_FIRST(KEY_UP)) #define EVT_KEY_PREVIOUS_VIEW(evt) (evt == EVT_KEY_FIRST(KEY_PAGEUP))
#define EVT_KEY_NEXT_VIEW(evt) (evt == EVT_KEY_FIRST(KEY_DOWN)) #define EVT_KEY_NEXT_VIEW(evt) (evt == EVT_KEY_FIRST(KEY_PAGEDN))
#elif defined(NAVIGATION_X7) || defined(NAVIGATION_X9D) #elif defined(NAVIGATION_X7) || defined(NAVIGATION_X9D)
#define EVT_KEY_PREVIOUS_VIEW(evt) (evt == EVT_KEY_LONG(KEY_PAGE)) #define EVT_KEY_PREVIOUS_VIEW(evt) (evt == EVT_KEY_LONG(KEY_PAGE))
#define EVT_KEY_NEXT_VIEW(evt) (evt == EVT_KEY_BREAK(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; return trim;
} }
int getSourceTrimValue(int source, int stickValue=0) int getSourceTrimOrigin(int source)
{ {
if (source >= MIXSRC_Rud && source <= MIXSRC_Ail) 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) 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 else
return -1;
}
int getSourceTrimValue(int source, int stickValue=0)
{
auto origin = getSourceTrimOrigin(source);
if (origin >= 0) {
return getStickTrimValue(origin, stickValue);
}
else {
return 0; return 0;
}
} }
uint8_t mixerCurrentFlightMode; uint8_t mixerCurrentFlightMode;
@ -741,13 +752,16 @@ void evalFlightModeMixes(uint8_t mode, uint8_t tick10ms)
} }
if (applyOffsetAndCurve) { if (applyOffsetAndCurve) {
bool applyTrims = !(mode & e_perout_mode_notrims);
//========== TRIMS ================ if (!applyTrims && g_model.thrTrim) {
if (!(mode & e_perout_mode_notrims)) { auto origin = getSourceTrimOrigin(md->srcRaw);
if (md->carryTrim == 0) { if (origin == g_model.getThrottleStickTrimSource() - MIXSRC_FIRST_TRIM) {
v += getSourceTrimValue(md->srcRaw, v); 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); int32_t weight = GET_GVAR_PREC1(MD_WEIGHT(md), GV_RANGELARGE_NEG, GV_RANGELARGE, mixerCurrentFlightMode);

View file

@ -1119,7 +1119,7 @@ void checkTrims()
else { else {
phase = getTrimFlightMode(mixerCurrentFlightMode, idx); phase = getTrimFlightMode(mixerCurrentFlightMode, idx);
before = getTrimValue(phase, idx); before = getTrimValue(phase, idx);
thro = (idx==THR_STICK && g_model.thrTrim); thro = (idx == (g_model.getThrottleStickTrimSource() - MIXSRC_FIRST_TRIM) && g_model.thrTrim);
} }
#else #else
phase = getTrimFlightMode(mixerCurrentFlightMode, idx); phase = getTrimFlightMode(mixerCurrentFlightMode, idx);
@ -1824,24 +1824,27 @@ void moveTrimsToOffsets() // copy state of 3 primary to subtrim
pauseMixerCalculations(); pauseMixerCalculations();
evalFlightModeMixes(e_perout_mode_noinput, 0); // do output loop - zero input sticks and trims 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]); zeros[i] = applyLimits(i, chans[i]);
} }
evalFlightModeMixes(e_perout_mode_noinput-e_perout_mode_notrims, 0); // do output loop - only trims 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++) { for (uint8_t i = 0; i < MAX_OUTPUT_CHANNELS; i++) {
int16_t output = applyLimits(i, chans[i]) - zeros[i]; int16_t diff = applyLimits(i, chans[i]) - zeros[i];
int16_t v = g_model.limitData[i].offset; int16_t v = g_model.limitData[i].offset;
if (g_model.limitData[i].revert) if (g_model.limitData[i].revert)
output = -output; diff = -diff;
v += (output * 125) / 128; 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
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) // reset all trims, except throttle (if throttle trim)
for (uint8_t i=0; i<NUM_TRIMS; i++) { 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); int16_t original_trim = getTrimValue(mixerCurrentFlightMode, i);
for (uint8_t fm=0; fm<MAX_FLIGHT_MODES; fm++) { for (uint8_t fm=0; fm<MAX_FLIGHT_MODES; fm++) {
trim_t trim = getRawTrimValue(fm, i); 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(LCD_DUAL_BUFFER "Dual LCD Buffer" OFF)
option(PXX1 "PXX1 protocol support" ON) option(PXX1 "PXX1 protocol support" ON)
option(PXX2 "PXX2 protocol support" OFF) 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(GHOST "Ghost TX Module" ON)
option(INTERNAL_MODULE_PPM "Support for PPM internal module" OFF) option(INTERNAL_MODULE_PPM "Support for PPM internal module" OFF)
option(AUTOUPDATE "Auto update internal chips from SD" 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(LCD_DRIVER lcd_driver_spi.cpp)
set(GVAR_SCREEN model_gvars.cpp) set(GVAR_SCREEN model_gvars.cpp)
set(PCBREV 2014 CACHE STRING "PCB Revision") set(PCBREV 2014 CACHE STRING "PCB Revision")
set(AFHDS3 NO)
add_definitions(-DPCBREV=${PCBREV}) add_definitions(-DPCBREV=${PCBREV})
add_definitions(-DMANUFACTURER_FRSKY) add_definitions(-DMANUFACTURER_FRSKY)
if (${PCBREV} STREQUAL 2019) if (${PCBREV} STREQUAL 2019)
@ -106,6 +107,7 @@ elseif(PCB STREQUAL X9D)
set(GVAR_SCREEN model_gvars.cpp) set(GVAR_SCREEN model_gvars.cpp)
set(STATUS_LEDS NO) set(STATUS_LEDS NO)
add_definitions(-DMANUFACTURER_FRSKY) add_definitions(-DMANUFACTURER_FRSKY)
set(AFHDS3 NO)
elseif(PCB STREQUAL X7) elseif(PCB STREQUAL X7)
set(PWR_BUTTON "PRESS" CACHE STRING "Pwr button type (PRESS/SWITCH)") set(PWR_BUTTON "PRESS" CACHE STRING "Pwr button type (PRESS/SWITCH)")
set(HAPTIC YES) set(HAPTIC YES)

View file

@ -339,6 +339,106 @@ TEST_F(TrimsTest, CopySticksToOffset)
EXPECT_EQ(g_model.limitData[1].offset, -97); 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) TEST_F(TrimsTest, InstantTrim)
{ {
anaInValues[AIL_STICK] = 50; anaInValues[AIL_STICK] = 50;

View file

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