This commit is contained in:
2026-06-17 04:55:15 +03:00
commit da3d9ef7b5
74 changed files with 5307 additions and 0 deletions
+125
View File
@@ -0,0 +1,125 @@
#include "buttonsmodel.h"
#include "configmanager.h"
#include <QJsonDocument>
#include <QFileInfo>
#include <QDir>
ButtonsModel::ButtonsModel(ConfigManager *config, QObject *parent)
: QAbstractListModel(parent)
, m_config(config)
{
connect(m_config, &ConfigManager::buttonsChanged, this, &ButtonsModel::reload);
reload();
}
void ButtonsModel::reload()
{
beginResetModel();
m_buttons = m_config->buttons();
// prune runtime state for removed ids
QSet<QString> ids;
for (const auto &v : m_buttons) ids.insert(v.toObject().value("id").toString());
for (auto it = m_runtime.begin(); it != m_runtime.end(); ) {
if (!ids.contains(it.key())) it = m_runtime.erase(it);
else ++it;
}
endResetModel();
emit countChanged();
}
int ButtonsModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid()) return 0;
return m_buttons.size();
}
QVariant ButtonsModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || index.row() < 0 || index.row() >= m_buttons.size())
return {};
QJsonObject b = m_buttons.at(index.row()).toObject();
QString id = b.value("id").toString();
QJsonObject action = b.value("action").toObject();
QJsonObject feedback = b.value("feedback").toObject();
RuntimeState rt = m_runtime.value(id);
switch (role) {
case IdRole: return id;
case LabelRole: return b.value("label").toString();
case IconPathRole: {
QString p = b.value("iconPath").toString();
if (p.isEmpty()) return QString();
if (p.startsWith("qrc:/") || p.startsWith(":/") || p.startsWith("file://") || p.startsWith("http"))
return p;
if (QFileInfo(p).isAbsolute())
return QString("file:///") + p;
return QString("file:///") + QDir(m_config->iconsDir()).filePath(p);
}
case ActionTypeRole: return action.value("type").toString("http_get");
case ActionUrlRole: return action.value("url").toString();
case ActionHeadersRole: return QJsonDocument(action.value("headers").toObject()).toJson(QJsonDocument::Compact);
case ActionBodyRole: return action.value("body").toString();
case SuccessTextRole: return feedback.value("successText").toString();
case ErrorTextRole: return feedback.value("errorText").toString();
case FadeMsRole: return feedback.value("fadeMs").toInt(5000);
case StatusRole: return rt.status;
case StatusTextRole: return rt.text;
case BtnColorRole: return b.value("color").toString("#7b007b");
}
return {};
}
QHash<int, QByteArray> ButtonsModel::roleNames() const
{
return {
{IdRole, "btnId"},
{LabelRole, "label"},
{IconPathRole, "iconPath"},
{ActionTypeRole, "actionType"},
{ActionUrlRole, "actionUrl"},
{ActionHeadersRole, "actionHeaders"},
{ActionBodyRole, "actionBody"},
{SuccessTextRole, "successText"},
{ErrorTextRole, "errorText"},
{FadeMsRole, "fadeMs"},
{StatusRole, "status"},
{StatusTextRole, "statusText"},
{BtnColorRole, "btnColor"}
};
}
QVariantMap ButtonsModel::get(int row) const
{
QVariantMap m;
if (row < 0 || row >= m_buttons.size()) return m;
auto rn = roleNames();
for (auto it = rn.begin(); it != rn.end(); ++it)
m.insert(QString::fromUtf8(it.value()), data(index(row, 0), it.key()));
return m;
}
int ButtonsModel::indexOfId(const QString &id) const
{
for (int i = 0; i < m_buttons.size(); ++i)
if (m_buttons.at(i).toObject().value("id").toString() == id)
return i;
return -1;
}
void ButtonsModel::setStatus(const QString &id, int status, const QString &statusText)
{
int row = indexOfId(id);
if (row < 0) return;
RuntimeState &rt = m_runtime[id];
rt.status = status;
rt.text = statusText;
QModelIndex idx = index(row, 0);
emit dataChanged(idx, idx, {StatusRole, StatusTextRole});
}
QVariantMap ButtonsModel::buttonToVariant(const QJsonObject &b, int row) const
{
Q_UNUSED(b); Q_UNUSED(row);
return {};
}