From 3b8d177861296cc59da5bd3ae54a0d3c4afa6b4a Mon Sep 17 00:00:00 2001 From: Max Paperno Date: Wed, 11 Jul 2018 02:49:12 -0400 Subject: [PATCH] [Companion] Start RawSource / RawSwitch data models refactor; Create RawSourceItemModel and RawSourceFilterItemModel. --- companion/src/CMakeLists.txt | 5 +- .../src/datamodels/rawsourceitemmodel.cpp | 126 ++++++++++++++++++ companion/src/datamodels/rawsourceitemmodel.h | 77 +++++++++++ companion/src/firmwares/rawsource.cpp | 2 +- companion/src/firmwares/rawsource.h | 16 ++- 5 files changed, 223 insertions(+), 3 deletions(-) create mode 100644 companion/src/datamodels/rawsourceitemmodel.cpp create mode 100644 companion/src/datamodels/rawsourceitemmodel.h diff --git a/companion/src/CMakeLists.txt b/companion/src/CMakeLists.txt index ea24fe339..288767939 100644 --- a/companion/src/CMakeLists.txt +++ b/companion/src/CMakeLists.txt @@ -106,6 +106,7 @@ include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR} ${COMPANION_SRC_DIRECTORY} + ${COMPANION_SRC_DIRECTORY}/datamodels ${COMPANION_SRC_DIRECTORY}/shared ${SIMU_SRC_DIRECTORY} ${COMPANION_SRC_DIRECTORY}/thirdparty/qcustomplot @@ -248,7 +249,8 @@ set(companion_SRCS wizarddata.cpp wizarddialog.cpp styleeditdialog.cpp - dialogs/filesyncdialog.cpp + datamodels/rawsourceitemmodel.cpp # TODO move to own lib with other item models + dialogs/filesyncdialog.cpp # also move all dialogs into subfolder ) set(companion_MOC_HDRS @@ -282,6 +284,7 @@ set(companion_MOC_HDRS modelslist.h styleeditdialog.h helpers_html.h + datamodels/rawsourceitemmodel.h dialogs/filesyncdialog.h ) diff --git a/companion/src/datamodels/rawsourceitemmodel.cpp b/companion/src/datamodels/rawsourceitemmodel.cpp new file mode 100644 index 000000000..cc54b3bec --- /dev/null +++ b/companion/src/datamodels/rawsourceitemmodel.cpp @@ -0,0 +1,126 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "rawsourceitemmodel.h" +#include "generalsettings.h" +#include "eeprominterface.h" +#include "modeldata.h" + +RawSourceItemModel::RawSourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent) : + QStandardItemModel(parent), + generalSettings(generalSettings), + modelData(modelData) +{ + const Boards board = Boards(getCurrentBoard()); + Firmware * fw = getCurrentFirmware(); + const int anasCount = CPN_MAX_STICKS + board.getCapability(Board::Pots) + board.getCapability(Board::Sliders) + board.getCapability(Board::MouseAnalogs); + + addItems(SOURCE_TYPE_NONE, RawSource::NoneGroup, 1); + for (int i=0; i < fw->getCapability(LuaScripts); i++) + addItems(SOURCE_TYPE_LUA_OUTPUT, RawSource::ScriptsGroup, fw->getCapability(LuaOutputsPerScript), i * 16); + addItems(SOURCE_TYPE_VIRTUAL_INPUT, RawSource::InputsGroup, fw->getCapability(VirtualInputs)); + addItems(SOURCE_TYPE_STICK, RawSource::SourcesGroup, anasCount); + addItems(SOURCE_TYPE_ROTARY_ENCODER, RawSource::SourcesGroup, fw->getCapability(RotaryEncoders)); + addItems(SOURCE_TYPE_TRIM, RawSource::TrimsGroup, board.getCapability(Board::NumTrims)); + addItems(SOURCE_TYPE_MAX, RawSource::SourcesGroup, 1); + addItems(SOURCE_TYPE_SWITCH, RawSource::SwitchesGroup, board.getCapability(Board::Switches)); + addItems(SOURCE_TYPE_CUSTOM_SWITCH, RawSource::SwitchesGroup, fw->getCapability(LogicalSwitches)); + addItems(SOURCE_TYPE_CYC, RawSource::SourcesGroup, CPN_MAX_CYC); + addItems(SOURCE_TYPE_PPM, RawSource::SourcesGroup, fw->getCapability(TrainerInputs)); + addItems(SOURCE_TYPE_CH, RawSource::SourcesGroup, fw->getCapability(Outputs)); + addItems(SOURCE_TYPE_SPECIAL, RawSource::TelemGroup, 5); + addItems(SOURCE_TYPE_TELEMETRY, RawSource::TelemGroup, CPN_MAX_SENSORS * 3); + addItems(SOURCE_TYPE_GVAR, RawSource::GVarsGroup, fw->getCapability(Gvars)); +} + +void RawSourceItemModel::setDynamicItemData(QStandardItem * item, const RawSource & src) +{ + Board::Type board = getCurrentBoard(); + item->setText(src.toString(modelData, generalSettings, board)); + item->setData(src.isAvailable(modelData, generalSettings, board), IsAvailableRole); +} + +void RawSourceItemModel::addItems(const RawSourceType & type, const unsigned group, const int count, const int start) +{ + for (int i = start; i < start + count; i++) { + const RawSource src = RawSource(type, i); + QStandardItem * modelItem = new QStandardItem(); + modelItem->setData(src.toValue(), ItemIdRole); + modelItem->setData(type, ItemTypeRole); + modelItem->setData(group, ItemGroupRole); + setDynamicItemData(modelItem, src); + appendRow(modelItem); + } +} + +void RawSourceItemModel::update() +{ + for (int i=0; i < rowCount(); ++i) + setDynamicItemData(item(i), RawSource(item(i)->data(ItemIdRole).toInt())); +} + + +// +// RawSourceFilterItemModel +// + +RawSourceFilterItemModel::RawSourceFilterItemModel(QAbstractItemModel * sourceModel, unsigned groups, QObject * parent) : + QSortFilterProxyModel(parent), + filterGroups(0) +{ + setFilterRole(RawSourceItemModel::IsAvailableRole); + setFilterKeyColumn(0); + setFilterGroups(groups); + setDynamicSortFilter(true); + setSourceModel(sourceModel); +} + +RawSourceFilterItemModel::RawSourceFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, unsigned groups, QObject * parent) : + RawSourceFilterItemModel(new RawSourceItemModel(generalSettings, modelData, parent), groups, parent) +{ +} + +void RawSourceFilterItemModel::setFilterGroups(unsigned groups) +{ + if (filterGroups != groups) { + filterGroups = groups; + invalidateFilter(); + } +} + +bool RawSourceFilterItemModel::filterAcceptsRow(int sourceRow, const QModelIndex & sourceParent) const +{ + bool ok = true; + const QModelIndex & srcIdx = sourceModel()->index(sourceRow, 0, sourceParent); + if (!sourceModel()->data(srcIdx, filterRole()).toBool()) + return false; + if (filterGroups && filterGroups != RawSource::AllSourceGroups) { + const unsigned group = sourceModel()->data(srcIdx, RawSourceItemModel::ItemGroupRole).toUInt(&ok); + return (ok && (filterGroups & group)); + } + return true; +} + +void RawSourceFilterItemModel::update() +{ + RawSourceItemModel * model = qobject_cast(sourceModel()); + if (model) + model->update(); +} diff --git a/companion/src/datamodels/rawsourceitemmodel.h b/companion/src/datamodels/rawsourceitemmodel.h new file mode 100644 index 000000000..0f5b827b8 --- /dev/null +++ b/companion/src/datamodels/rawsourceitemmodel.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef RAWSOURCEITEMMODEL_H +#define RAWSOURCEITEMMODEL_H + +#include "rawsource.h" + +#include +#include + +class GeneralSettings; +class ModelData; + +class RawSourceItemModel: public QStandardItemModel +{ + Q_OBJECT + public: + enum DataRoles { ItemIdRole = Qt::UserRole, ItemTypeRole, ItemGroupRole, IsAvailableRole }; + Q_ENUM(DataRoles) + + RawSourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr); + + public slots: + void update(); + + protected: + void setDynamicItemData(QStandardItem * item, const RawSource & src); + void addItems(const RawSourceType & type, const unsigned group, const int count, const int start = 0); + + const GeneralSettings * generalSettings; + const ModelData * modelData; +}; + + +class RawSourceFilterItemModel: public QSortFilterProxyModel +{ + Q_OBJECT + public: + explicit RawSourceFilterItemModel(QAbstractItemModel * sourceModel, unsigned groups, QObject * parent = nullptr); + explicit RawSourceFilterItemModel(QAbstractItemModel * sourceModel, QObject * parent = nullptr) : + RawSourceFilterItemModel(sourceModel, RawSource::AllSourceGroups, parent) + {} + + explicit RawSourceFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, unsigned groups, QObject * parent = nullptr); + explicit RawSourceFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr) : + RawSourceFilterItemModel(generalSettings, modelData, RawSource::AllSourceGroups, parent) + {} + + public slots: + void setFilterGroups(unsigned groups); + void update(); + + protected: + bool filterAcceptsRow(int sourceRow, const QModelIndex & sourceParent) const override; + + unsigned int filterGroups; +}; + +#endif // RAWSOURCEITEMMODEL_H diff --git a/companion/src/firmwares/rawsource.cpp b/companion/src/firmwares/rawsource.cpp index 57ce40d63..bb7d4d710 100644 --- a/companion/src/firmwares/rawsource.cpp +++ b/companion/src/firmwares/rawsource.cpp @@ -495,7 +495,7 @@ bool RawSource::isTimeBased(Board::Type board) const return (type==SOURCE_TYPE_TELEMETRY && (index==TELEMETRY_SOURCE_TX_TIME || index==TELEMETRY_SOURCE_TIMER1 || index==TELEMETRY_SOURCE_TIMER2 || index==TELEMETRY_SOURCE_TIMER3)); } -bool RawSource::isAvailable(const ModelData * const model, const GeneralSettings * const gs, Board::Type board) +bool RawSource::isAvailable(const ModelData * const model, const GeneralSettings * const gs, Board::Type board) const { if (board == Board::BOARD_UNKNOWN) board = getCurrentBoard(); diff --git a/companion/src/firmwares/rawsource.h b/companion/src/firmwares/rawsource.h index 5fd84128c..267d6af43 100644 --- a/companion/src/firmwares/rawsource.h +++ b/companion/src/firmwares/rawsource.h @@ -213,6 +213,20 @@ class RawSource { Q_DECLARE_TR_FUNCTIONS(RawSource) public: + enum SourceGroups { + NoneGroup = 0x001, + SourcesGroup = 0x002, + TrimsGroup = 0x004, + SwitchesGroup = 0x008, + GVarsGroup = 0x010, + TelemGroup = 0x020, + InputsGroup = 0x040, + ScriptsGroup = 0x080, + + InputSourceGroups = NoneGroup | SourcesGroup | TrimsGroup | SwitchesGroup | InputsGroup, + AllSourceGroups = InputSourceGroups | GVarsGroup | TelemGroup | ScriptsGroup + }; + RawSource(): type(SOURCE_TYPE_NONE), index(0) @@ -243,7 +257,7 @@ class RawSource { bool isPot(int * potsIndex = NULL, Board::Type board = Board::BOARD_UNKNOWN) const; bool isSlider(int * sliderIndex = NULL, Board::Type board = Board::BOARD_UNKNOWN) const; bool isTimeBased(Board::Type board = Board::BOARD_UNKNOWN) 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 RawSource & other) { return (this->type == other.type) && (this->index == other.index);