[Companion] Refactor RawSwitchItemModel and RawSwitchFilterItemModel for better efficiency, does not invalidate whole model on updates (structure is almost identical to the RawSource variants).
This commit is contained in:
@@ -142,7 +142,7 @@ QString RawSwitch::toString(Board::Type board, const GeneralSettings * const gen
|
||||
}
|
||||
}
|
||||
|
||||
bool RawSwitch::isAvailable(const ModelData * const model, const GeneralSettings * const gs, Board::Type board)
|
||||
bool RawSwitch::isAvailable(const ModelData * const model, const GeneralSettings * const gs, Board::Type board) const
|
||||
{
|
||||
if (board == Board::BOARD_UNKNOWN)
|
||||
board = getCurrentBoard();
|
||||
|
||||
@@ -52,6 +52,19 @@ class RawSwitch {
|
||||
Q_DECLARE_TR_FUNCTIONS(RawSwitch)
|
||||
|
||||
public:
|
||||
enum SwitchContext
|
||||
{
|
||||
NoSwitchContext = 0,
|
||||
LogicalSwitchesContext = 0x01,
|
||||
SpecialFunctionsContext = 0x02,
|
||||
GlobalFunctionsContext = 0x04,
|
||||
TimersContext = 0x08,
|
||||
MixesContext = 0x10,
|
||||
|
||||
AllModelContexts = SpecialFunctionsContext | LogicalSwitchesContext | TimersContext | MixesContext,
|
||||
AllSwitchContexts = AllModelContexts | GlobalFunctionsContext
|
||||
};
|
||||
|
||||
RawSwitch():
|
||||
type(SWITCH_TYPE_NONE),
|
||||
index(0)
|
||||
@@ -77,7 +90,7 @@ class RawSwitch {
|
||||
|
||||
RawSwitch convert(RadioDataConversionState & cstate);
|
||||
QString toString(Board::Type board = Board::BOARD_UNKNOWN, const GeneralSettings * const generalSettings = NULL, const ModelData * const modelData = NULL) const;
|
||||
bool isAvailable(const ModelData * const model = NULL, const GeneralSettings * const gs = NULL, Board::Type board = Board::BOARD_UNKNOWN);
|
||||
bool isAvailable(const ModelData * const model = NULL, const GeneralSettings * const gs = NULL, Board::Type board = Board::BOARD_UNKNOWN) const;
|
||||
|
||||
bool operator== ( const RawSwitch& other) {
|
||||
return (this->type == other.type) && (this->index == other.index);
|
||||
|
||||
@@ -29,6 +29,7 @@ set(modeledit_SRCS
|
||||
)
|
||||
|
||||
set(modeledit_HDRS
|
||||
switchitemmodel.h
|
||||
flightmodes.h
|
||||
inputs.h
|
||||
mixes.h
|
||||
|
||||
@@ -77,7 +77,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model,
|
||||
lock = true;
|
||||
int num_fsw = model ? firmware->getCapability(CustomFunctions) : firmware->getCapability(GlobalFunctions);
|
||||
|
||||
rawSwitchItemModel = new RawSwitchFilterItemModel(&generalSettings, model, model ? SpecialFunctionsContext : GlobalFunctionsContext);
|
||||
rawSwitchItemModel = new RawSwitchFilterItemModel(&generalSettings, model, model ? RawSwitch::SpecialFunctionsContext : RawSwitch::GlobalFunctionsContext, this);
|
||||
rawSrcAllItemModel = new RawSourceFilterItemModel(&generalSettings, model, this);
|
||||
rawSrcInputsItemModel = new RawSourceFilterItemModel(rawSrcAllItemModel->sourceModel(), RawSource::InputSourceGroups, this);
|
||||
rawSrcGVarsItemModel = new RawSourceFilterItemModel(rawSrcAllItemModel->sourceModel(), RawSource::GVarsGroup, this);
|
||||
|
||||
@@ -63,7 +63,7 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G
|
||||
curveGroup = new CurveGroup(ui->curveTypeCB, ui->curveGVarCB, ui->curveValueCB, ui->curveValueSB, ed->curve, model,
|
||||
firmware->getCapability(HasInputDiff) ? 0 : (HIDE_DIFF | HIDE_NEGATIVE_CURVES));
|
||||
|
||||
ui->switchesCB->setModel(new RawSwitchFilterItemModel(&generalSettings, &model, MixesContext));
|
||||
ui->switchesCB->setModel(new RawSwitchFilterItemModel(&generalSettings, &model, RawSwitch::MixesContext, this));
|
||||
ui->switchesCB->setCurrentIndex(ui->switchesCB->findData(ed->swtch.toValue()));
|
||||
|
||||
ui->sideCB->setCurrentIndex(ed->mode-1);
|
||||
|
||||
@@ -53,7 +53,7 @@ FlightModePanel::FlightModePanel(QWidget * parent, ModelData & model, int phaseI
|
||||
|
||||
// Phase switch
|
||||
if (phaseIdx > 0) {
|
||||
rawSwitchItemModel = new RawSwitchFilterItemModel(&generalSettings, &model, MixesContext);
|
||||
rawSwitchItemModel = new RawSwitchFilterItemModel(&generalSettings, &model, RawSwitch::MixesContext, this);
|
||||
ui->swtch->setModel(rawSwitchItemModel);
|
||||
ui->swtch->setCurrentIndex(ui->swtch->findData(phase.swtch.toValue()));
|
||||
connect(ui->swtch, SIGNAL(currentIndexChanged(int)), this, SLOT(phaseSwitch_currentIndexChanged(int)));
|
||||
|
||||
@@ -31,7 +31,7 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model,
|
||||
{
|
||||
Stopwatch s1("LogicalSwitchesPanel");
|
||||
|
||||
rawSwitchItemModel = new RawSwitchFilterItemModel(&generalSettings, &model, LogicalSwitchesContext);
|
||||
rawSwitchItemModel = new RawSwitchFilterItemModel(&generalSettings, &model, RawSwitch::LogicalSwitchesContext, this);
|
||||
|
||||
const unsigned srcGroups = firmware->getCapability(GvarsInCS) ? RawSource::AllSourceGroups : (RawSource::AllSourceGroups & ~RawSource::GVarsGroup);
|
||||
rawSourceItemModel = new RawSourceFilterItemModel(&generalSettings, &model, srcGroups, this);
|
||||
|
||||
@@ -105,7 +105,7 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata,
|
||||
}
|
||||
}
|
||||
|
||||
ui->switchesCB->setModel(new RawSwitchFilterItemModel(&generalSettings, &model, MixesContext));
|
||||
ui->switchesCB->setModel(new RawSwitchFilterItemModel(&generalSettings, &model, RawSwitch::MixesContext, this));
|
||||
ui->switchesCB->setCurrentIndex(ui->switchesCB->findData(md->swtch.toValue()));
|
||||
ui->warningCB->setCurrentIndex(md->mixWarn);
|
||||
ui->mltpxCB->setCurrentIndex(md->mltpx);
|
||||
|
||||
@@ -50,7 +50,7 @@ TimerPanel::TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, Ge
|
||||
}
|
||||
|
||||
// Mode
|
||||
rawSwitchItemModel = new RawSwitchFilterItemModel(&generalSettings, &model, TimersContext);
|
||||
rawSwitchItemModel = new RawSwitchFilterItemModel(&generalSettings, &model, RawSwitch::TimersContext, this);
|
||||
ui->mode->setModel(rawSwitchItemModel);
|
||||
ui->mode->setCurrentIndex(ui->mode->findData(timer.mode.toValue()));
|
||||
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
#include "switchitemmodel.h"
|
||||
#include "eeprominterface.h"
|
||||
|
||||
RawSwitchItemModel::RawSwitchItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData):
|
||||
RawSwitchItemModel::RawSwitchItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent) :
|
||||
QStandardItemModel(parent),
|
||||
generalSettings(generalSettings),
|
||||
modelData(modelData)
|
||||
{
|
||||
@@ -58,78 +59,110 @@ RawSwitchItemModel::RawSwitchItemModel(const GeneralSettings * const generalSett
|
||||
add(SWITCH_TYPE_ONE, 1);
|
||||
}
|
||||
|
||||
void RawSwitchItemModel::setDynamicItemData(QStandardItem * item, const RawSwitch & rsw) const
|
||||
{
|
||||
const Board::Type board = getCurrentBoard();
|
||||
item->setText(rsw.toString(board, generalSettings, modelData));
|
||||
item->setData(rsw.isAvailable(modelData, generalSettings, board), IsAvailableRole);
|
||||
}
|
||||
|
||||
void RawSwitchItemModel::add(const RawSwitchType & type, int count)
|
||||
{
|
||||
// Most RawSwitch() indices are one-based (vs. typical zero); these are exceptions to the rule:
|
||||
const static QVector<int> rawSwitchIndexBaseZeroTypes = QVector<int>() << SWITCH_TYPE_NONE << SWITCH_TYPE_ON << SWITCH_TYPE_OFF << SWITCH_TYPE_TIMER_MODE;
|
||||
|
||||
int rawIdxAdj = 0;
|
||||
const Board::Type board = getCurrentBoard();
|
||||
int i = (count < 0 ? count : 1);
|
||||
const int maxCount = (i < 0 ? 0 : count + i);
|
||||
|
||||
// handle exceptions in RawSwitch() index values
|
||||
if (rawSwitchIndexBaseZeroTypes.contains(type))
|
||||
rawIdxAdj = -1;
|
||||
const short rawIdxAdj = rawSwitchIndexBaseZeroTypes.contains(type) ? -1 : 0;
|
||||
|
||||
for ( ; i < maxCount; ++i) {
|
||||
// determine cotext flags
|
||||
unsigned context = RawSwitch::AllSwitchContexts;
|
||||
switch (type) {
|
||||
case SWITCH_TYPE_FLIGHT_MODE:
|
||||
context &= ~RawSwitch::MixesContext;
|
||||
// fallthrough
|
||||
case SWITCH_TYPE_VIRTUAL:
|
||||
case SWITCH_TYPE_SENSOR:
|
||||
context &= ~RawSwitch::GlobalFunctionsContext;
|
||||
break;
|
||||
|
||||
case SWITCH_TYPE_TIMER_MODE:
|
||||
context = RawSwitch::TimersContext;
|
||||
break;
|
||||
|
||||
case SWITCH_TYPE_NONE:
|
||||
context &= ~RawSwitch::TimersContext;
|
||||
break;
|
||||
|
||||
case SWITCH_TYPE_ON:
|
||||
case SWITCH_TYPE_ONE:
|
||||
context = RawSwitch::SpecialFunctionsContext | RawSwitch::GlobalFunctionsContext;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
int i = (count < 0 ? count : 1);
|
||||
count = (i < 0 ? 0 : count + i);
|
||||
for ( ; i < count; ++i) {
|
||||
RawSwitch rs(type, i + rawIdxAdj);
|
||||
QStandardItem * modelItem = new QStandardItem(rs.toString(board, generalSettings, modelData));
|
||||
modelItem->setData(rs.toValue(), Qt::UserRole);
|
||||
QStandardItem * modelItem = new QStandardItem();
|
||||
modelItem->setData(rs.toValue(), ItemIdRole);
|
||||
modelItem->setData(type, ItemTypeRole);
|
||||
modelItem->setData(context, ContextRole);
|
||||
setDynamicItemData(modelItem, rs);
|
||||
appendRow(modelItem);
|
||||
}
|
||||
}
|
||||
|
||||
void RawSwitchItemModel::update()
|
||||
void RawSwitchItemModel::update() const
|
||||
{
|
||||
for (int i=0; i<rowCount(); i++) {
|
||||
QStandardItem * modelItem = item(i, 0);
|
||||
RawSwitch swtch(modelItem->data(Qt::UserRole).toInt());
|
||||
modelItem->setText(swtch.toString(getCurrentBoard(), generalSettings, modelData));
|
||||
}
|
||||
for (int i=0; i < rowCount(); ++i)
|
||||
setDynamicItemData(item(i), RawSwitch(item(i)->data(ItemIdRole).toInt()));
|
||||
}
|
||||
|
||||
RawSwitchFilterItemModel::RawSwitchFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, SwitchContext context):
|
||||
generalSettings(generalSettings),
|
||||
modelData(modelData),
|
||||
context(context),
|
||||
parent(new RawSwitchItemModel(generalSettings, modelData))
|
||||
|
||||
//
|
||||
// RawSwitchFilterItemModel
|
||||
//
|
||||
|
||||
RawSwitchFilterItemModel::RawSwitchFilterItemModel(QAbstractItemModel * sourceModel, RawSwitch::SwitchContext context, QObject * parent) :
|
||||
QSortFilterProxyModel(parent)
|
||||
{
|
||||
setSourceModel(parent);
|
||||
setDynamicSortFilter(false);
|
||||
setFilterRole(RawSwitchItemModel::IsAvailableRole);
|
||||
setFilterKeyColumn(0);
|
||||
setSwitchContext(context);
|
||||
setDynamicSortFilter(true);
|
||||
setSourceModel(sourceModel);
|
||||
}
|
||||
|
||||
RawSwitchFilterItemModel::RawSwitchFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, RawSwitch::SwitchContext context, QObject * parent):
|
||||
RawSwitchFilterItemModel(new RawSwitchItemModel(generalSettings, modelData, parent), context, parent)
|
||||
{
|
||||
}
|
||||
|
||||
void RawSwitchFilterItemModel::setSwitchContext(RawSwitch::SwitchContext ctxt)
|
||||
{
|
||||
if (ctxt != context) {
|
||||
context = ctxt;
|
||||
invalidateFilter();
|
||||
}
|
||||
}
|
||||
|
||||
bool RawSwitchFilterItemModel::filterAcceptsRow(int sourceRow, const QModelIndex & sourceParent) const
|
||||
{
|
||||
QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
|
||||
RawSwitch swtch(sourceModel()->data(index, Qt::UserRole).toInt());
|
||||
|
||||
if (swtch.type == SWITCH_TYPE_FLIGHT_MODE && (context == MixesContext || context == GlobalFunctionsContext))
|
||||
const QModelIndex & srcIdx = sourceModel()->index(sourceRow, 0, sourceParent);
|
||||
if (!srcIdx.isValid() || !sourceModel()->data(srcIdx, filterRole()).toBool())
|
||||
return false;
|
||||
|
||||
if (swtch.type == SWITCH_TYPE_VIRTUAL && context == GlobalFunctionsContext)
|
||||
return false;
|
||||
|
||||
if (swtch.type == SWITCH_TYPE_TIMER_MODE && context != TimersContext)
|
||||
return false;
|
||||
|
||||
if (swtch.type == SWITCH_TYPE_NONE && context == TimersContext)
|
||||
return false;
|
||||
|
||||
if (swtch.type == SWITCH_TYPE_SENSOR && context == GlobalFunctionsContext)
|
||||
return false;
|
||||
|
||||
if ((swtch.type == SWITCH_TYPE_ON || swtch.type == SWITCH_TYPE_ONE) && (context != SpecialFunctionsContext && context != GlobalFunctionsContext))
|
||||
return false;
|
||||
|
||||
if (!swtch.isAvailable(modelData, generalSettings, getCurrentBoard()))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
bool ok;
|
||||
const RawSwitch::SwitchContext ctxt = RawSwitch::SwitchContext(sourceModel()->data(srcIdx, RawSwitchItemModel::ContextRole).toUInt(&ok));
|
||||
return (ok && (ctxt == RawSwitch::AllSwitchContexts || context != RawSwitch::NoSwitchContext || (context & ctxt)));
|
||||
}
|
||||
|
||||
void RawSwitchFilterItemModel::update()
|
||||
void RawSwitchFilterItemModel::update() const
|
||||
{
|
||||
parent->update();
|
||||
invalidate();
|
||||
RawSwitchItemModel * model = qobject_cast<RawSwitchItemModel *>(sourceModel());
|
||||
if (model)
|
||||
model->update();
|
||||
}
|
||||
|
||||
@@ -20,39 +20,44 @@
|
||||
|
||||
#include <QStandardItemModel>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include "radiodata.h"
|
||||
#include "rawswitch.h"
|
||||
|
||||
enum SwitchContext
|
||||
class GeneralSettings;
|
||||
class ModelData;
|
||||
|
||||
class RawSwitchItemModel: public QStandardItemModel
|
||||
{
|
||||
LogicalSwitchesContext,
|
||||
SpecialFunctionsContext,
|
||||
GlobalFunctionsContext,
|
||||
TimersContext,
|
||||
MixesContext
|
||||
};
|
||||
|
||||
class RawSwitchItemModel: public QStandardItemModel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
RawSwitchItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData);
|
||||
void update();
|
||||
enum DataRoles { ItemIdRole = Qt::UserRole, ItemTypeRole, ContextRole, IsAvailableRole };
|
||||
Q_ENUM(DataRoles)
|
||||
|
||||
RawSwitchItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void update() const;
|
||||
|
||||
protected:
|
||||
void setDynamicItemData(QStandardItem * item, const RawSwitch & rsw) const;
|
||||
void add(const RawSwitchType & type, int count);
|
||||
|
||||
const GeneralSettings * generalSettings;
|
||||
const ModelData * modelData;
|
||||
};
|
||||
|
||||
class RawSwitchFilterItemModel: public QSortFilterProxyModel {
|
||||
class RawSwitchFilterItemModel: public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
RawSwitchFilterItemModel(const GeneralSettings * const generalSettings = NULL, const ModelData * const modelData = NULL, SwitchContext context = LogicalSwitchesContext);
|
||||
void update();
|
||||
RawSwitchFilterItemModel(QAbstractItemModel * sourceModel, RawSwitch::SwitchContext context, QObject * parent = nullptr);
|
||||
RawSwitchFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, RawSwitch::SwitchContext context, QObject * parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void setSwitchContext(RawSwitch::SwitchContext ctxt);
|
||||
void update() const;
|
||||
|
||||
protected:
|
||||
const GeneralSettings * generalSettings;
|
||||
const ModelData * modelData;
|
||||
SwitchContext context;
|
||||
RawSwitchItemModel * parent;
|
||||
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex & sourceParent) const override;
|
||||
|
||||
RawSwitch::SwitchContext context = RawSwitch::NoSwitchContext;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user