Files
edgetx-gx12/companion/src/updates/repomodels.cpp
T
2022-09-06 09:29:41 +10:00

487 lines
12 KiB
C++

/*
* Copyright (C) EdgeTX
*
* Based on code named
* opentx - https://github.com/opentx/opentx
* 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 "repomodels.h"
#include "appdata.h"
#include <QStandardItem>
#include <QJsonDocument>
QString metaDataTypeToString(MetaDataType val)
{
switch ((int)val) {
case MDT_Release:
return "Release";
case MDT_Releases:
return "Releases";
case MDT_Asset:
return "Asset";
case MDT_ReleaseAssets:
return "Release Assets";
default:
return CPN_STR_UNKNOWN_ITEM;
}
}
/*
ReleasesItemModel
*/
ReleasesItemModel::ReleasesItemModel() :
UpdatesItemModel("Releases"),
m_settingsIdx(-1),
m_nightlyName(""),
m_releaseChannel(-1)
{
setSortRole(UpdatesItemModel::IMDR_Date);
}
bool ReleasesItemModel::releaseChannelChanged()
{
if (m_settingsIdx > -1 && m_releaseChannel != (int)g.component[m_settingsIdx].releaseChannel())
return true;
else
return false;
}
void ReleasesItemModel::parseMetaData(const int mdt, QJsonDocument * jsonDoc)
{
json = jsonDoc;
if (m_settingsIdx > -1)
m_releaseChannel = g.component[m_settingsIdx].releaseChannel();
switch (mdt) {
case MDT_Release:
parseRelease();
break;
case MDT_Releases:
parseReleases();
break;
}
}
void ReleasesItemModel::parseRelease()
{
clear();
if (json->isObject()) {
const QJsonObject &obj = json->object();
parseJsonObject(obj);
}
}
void ReleasesItemModel::parseReleases()
{
clear();
if (json->isArray()) {
const QJsonArray &array = json->array();
foreach (const QJsonValue &v, array)
{
if (v.isObject()) {
const QJsonObject &obj = v.toObject();
parseJsonObject(obj);
}
}
}
sort(0, Qt::DescendingOrder);
}
void ReleasesItemModel::parseJsonObject(const QJsonObject & obj)
{
QStandardItem * item = new QStandardItem();
QString tag = QString();
bool prerelease = false;
if (!obj.value("name").isUndefined()) {
item->setText(obj.value("name").toString());
}
if (!obj.value("id").isUndefined()) {
item->setData(obj.value("id").toInt(), UpdatesItemModel::IMDR_Id);
}
if (!obj.value("tag_name").isUndefined()) {
tag = obj.value("tag_name").toString();
item->setData(tag, UpdatesItemModel::IMDR_Tag);
}
if (!obj.value("prerelease").isUndefined()) {
prerelease = obj.value("prerelease").toBool();
item->setData(prerelease, UpdatesItemModel::IMDR_Prerelease);
}
if (!obj.value("created_at").isUndefined()) {
item->setData(QDateTime::fromString(obj.value("created_at").toString(), Qt::ISODate), UpdatesItemModel::IMDR_Date);
}
item->setData(isReleaseAvailable(tag, prerelease), UpdatesItemModel::IMDR_Available);
appendRow(item);
}
bool ReleasesItemModel::isReleaseAvailable(const QString tagname, const bool prerelease)
{
if (prerelease) {
if (m_releaseChannel == ComponentData::RELEASE_CHANNEL_STABLE) {
//qDebug() << "Release channel stable" << tagname << "is pre-release" ;
return false;
}
else if (m_releaseChannel == ComponentData::RELEASE_CHANNEL_PRERELEASE && tagname.toLower() == m_nightlyName) {
//qDebug() << "Release channel pre-release" << tagname << "is nightly" ;
return false;
}
}
//qDebug() << "Release available:" << tagname;
return true;
}
/*
AssetsItemModel
*/
AssetsItemModel::AssetsItemModel() :
UpdatesItemModel("Assets")
{
}
void AssetsItemModel::parseMetaData(int mdt, QJsonDocument * jsonDoc)
{
json = jsonDoc;
switch (mdt) {
case MDT_Asset:
parseAsset();
break;
case MDT_ReleaseAssets:
parseReleaseAssets();
break;
}
}
void AssetsItemModel::parseAsset()
{
clear();
if (json->isObject()) {
const QJsonObject &obj = json->object();
parseJsonObject(obj);
}
}
void AssetsItemModel::parseReleaseAssets()
{
clear();
if (json->isArray()) {
const QJsonArray &array = json->array();
foreach (const QJsonValue &v, array)
{
if (v.isObject()) {
const QJsonObject &obj = v.toObject();
parseJsonObject(obj);
}
}
}
sort(0);
}
void AssetsItemModel::parseJsonObject(const QJsonObject & obj)
{
QStandardItem * item = new QStandardItem();
if (!obj.value("name").isUndefined()) {
item->setText(obj.value("name").toString());
}
if (!obj.value("id").isUndefined()) {
item->setData(obj.value("id").toInt(), UpdatesItemModel::IMDR_Id);
}
if (!obj.value("content_type").isUndefined()) {
item->setData(obj.value("content_type").toString(), UpdatesItemModel::IMDR_Content);
}
if (!obj.value("updated_at").isUndefined()) {
item->setData(QDateTime::fromString(obj.value("updated_at").toString(), Qt::ISODate), UpdatesItemModel::IMDR_Date);
}
item->setData(true, UpdatesItemModel::IMDR_Available);
appendRow(item);
}
/*
UpdatesFilteredItemModel
*/
UpdatesFilteredItemModel::UpdatesFilteredItemModel(UpdatesItemModel * sourceModel, QString name) :
QSortFilterProxyModel(nullptr),
filterFlags(0),
m_name(name)
{
filterText.setPattern("");
filterText.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
setFilterRole(UpdatesItemModel::IMDR_Available);
setFilterKeyColumn(0);
setDynamicSortFilter(true);
setSourceModel(sourceModel);
}
void UpdatesFilteredItemModel::setFilterFlags(const int flags)
{
if (filterFlags != flags) {
filterFlags = flags;
filterText.setPattern("");
invalidateFilter();
}
}
void UpdatesFilteredItemModel::setFilterPattern(const QString & pattern)
{
if (filterText.pattern() != pattern) {
filterText.setPattern(pattern);
filterFlags = 0;
invalidateFilter();
}
}
bool UpdatesFilteredItemModel::filterAcceptsRow(int sourceRow, const QModelIndex & sourceParent) const
{
const QModelIndex & srcIdx = sourceModel()->index(sourceRow, 0, sourceParent);
if (!srcIdx.isValid() || !sourceModel()->data(srcIdx, filterRole()).toBool())
return false;
if (!filterFlags && filterText.pattern().isEmpty())
return true;
if (filterFlags) {
bool ok;
const int flags = sourceModel()->data(srcIdx, UpdatesItemModel::IMDR_Flags).toInt(&ok);
return (ok && (!flags || (filterFlags & flags)));
}
else {
return sourceModel()->data(srcIdx, Qt::DisplayRole).toString().contains(filterText);
}
}
void UpdatesFilteredItemModel::dumpContents()
{
qDebug() << "Contents of" << m_name;
for (int i = 0; i < rowCount(); ++i) {
qDebug() << "row:" << i
<< "text:" << data(index(i, 0), Qt::DisplayRole).toString()
<< "id:" << data(index(i, 0), UpdatesItemModel::IMDR_Id).toInt()
<< "date:" << data(index(i, 0), UpdatesItemModel::IMDR_Date).toDateTime()
<< "tag:" << data(index(i, 0), UpdatesItemModel::IMDR_Tag).toString()
<< "avail:" << data(index(i, 0), UpdatesItemModel::IMDR_Available).toBool()
<< "flags:" << data(index(i, 0), UpdatesItemModel::IMDR_Flags).toInt()
<< "content:" << data(index(i, 0), UpdatesItemModel::IMDR_Content).toString()
<< "prerelease:" << data(index(i, 0), UpdatesItemModel::IMDR_Prerelease).toBool();
}
}
QMap<int, QVariant> UpdatesFilteredItemModel::itemMetaData(const int id)
{
const QModelIndexList idxlst = match(index(0, 0), UpdatesItemModel::IMDR_Id, QVariant(id), 1, Qt::MatchExactly);
if (!idxlst.isEmpty())
return itemData(idxlst.at(0));
return QMap<int, QVariant>();
}
QVariant UpdatesFilteredItemModel::metaDataValue(const int id, const int role)
{
//qDebug() << "id:" << id << "role:";
const QModelIndexList idxlst = match(index(0, 0), UpdatesItemModel::IMDR_Id, QVariant(id), 1, Qt::MatchExactly);
if (!idxlst.isEmpty())
return data(idxlst.at(0), role);
return QVariant();
}
bool UpdatesFilteredItemModel::setMetaDataValue(const int id, const int role, const QVariant value)
{
//qDebug() << "id:" << id << "role:" << role << "value:" << value;
const QModelIndexList idxlst = match(index(0, 0), UpdatesItemModel::IMDR_Id, QVariant(id), 1, Qt::MatchExactly);
if (!idxlst.isEmpty())
return setData(idxlst.at(0), value, role);
return false;
}
int UpdatesFilteredItemModel::id(const int row)
{
const QModelIndex & idx = index(row, 0);
if (!idx.isValid())
return 0;
bool ok;
const int id = data(idx, UpdatesItemModel::IMDR_Id).toInt(&ok);
if (ok)
return id;
return 0;
}
int UpdatesFilteredItemModel::id(const QVariant value, const Qt::MatchFlags flags, const int role)
{
const QModelIndexList idxlst = match(index(0, 0), role, value, 1, flags);
if (!idxlst.isEmpty()) {
bool ok;
const int id = data(idxlst.at(0), UpdatesItemModel::IMDR_Id).toInt(&ok);
if (ok)
return id;
}
return 0;
}
QStringList UpdatesFilteredItemModel::list()
{
QStringList strl;
for (int i = 0; i < rowCount(); i++)
strl << data(index(i, 0)).toString();
return strl;
}
/*
ReleasesFilteredItemModel
*/
ReleasesFilteredItemModel::ReleasesFilteredItemModel(UpdatesItemModel * sourceModel) :
UpdatesFilteredItemModel(sourceModel, "Filtered Releases")
{
setSortRole(UpdatesItemModel::IMDR_Date);
}
int ReleasesFilteredItemModel::channelLatestId()
{
return rows() > 0 ? id(0) : 0; // assumes model sorted descending date
}
/*
AssetsFilteredItemModel
*/
AssetsFilteredItemModel::AssetsFilteredItemModel(UpdatesItemModel * sourceModel) :
UpdatesFilteredItemModel(sourceModel, "Filtered Assets")
{
}
bool AssetsFilteredItemModel::setFlags(const int id, const int flags)
{
return setMetaDataValue(id, UpdatesItemModel::IMDR_Flags, QVariant(flags));
}
bool AssetsFilteredItemModel::setSubDirectory(const int id, const QString path)
{
return setMetaDataValue(id, UpdatesItemModel::IMDR_SubDirectory, QVariant(path));
}
bool AssetsFilteredItemModel::setCopyFilter(const int id, const QString filter)
{
return setMetaDataValue(id, UpdatesItemModel::IMDR_CopyFilter, QVariant(filter));
}
/*
ReleasesMetaData
*/
ReleasesMetaData::ReleasesMetaData(QWidget * parent) :
QWidget(parent),
m_repo(""),
m_id(0)
{
itemModel = new ReleasesItemModel();
filteredItemModel = new ReleasesFilteredItemModel(itemModel);
}
bool ReleasesMetaData::refreshRequired()
{
if (m_id != 0)
return itemModel->releaseChannelChanged();
return true;
}
int ReleasesMetaData::getSetId()
{
m_id = filteredItemModel->channelLatestId();
return m_id;
}
int ReleasesMetaData::getSetId(int row)
{
m_id = filteredItemModel->id(row);
return m_id;
}
int ReleasesMetaData::getSetId(QVariant value, Qt::MatchFlags flags, int role)
{
m_id = filteredItemModel->id(value, flags, role);
return m_id;
}
/*
AssetsMetaData
*/
AssetsMetaData::AssetsMetaData(QWidget * parent) :
QWidget(parent)
{
itemModel = new AssetsItemModel();
filteredItemModel = new AssetsFilteredItemModel(itemModel);
}
int AssetsMetaData::getSetId(int row)
{
m_id = filteredItemModel->id(row);
return m_id;
}
int AssetsMetaData::getSetId(QVariant value, Qt::MatchFlags flags, int role)
{
m_id = filteredItemModel->id(value, flags, role);
return m_id;
}