Files
Button/src/buttonsmodel.cpp
T
2026-08-24 16:40:48 +03:00

156 lines
5.6 KiB
C++

#include "buttonsmodel.h"
#include "configmanager.h"
#include <QJsonDocument>
#include <QFileInfo>
#include <QDir>
#include <QUrl>
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();
QJsonObject trigger = b.value("trigger").toObject();
QJsonObject latchReset = b.value("latchReset").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 QUrl::fromLocalFile(p).toString();
return QUrl::fromLocalFile(QDir(m_config->iconsDir()).filePath(p)).toString();
}
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 PendingTextRole: return feedback.value("pendingText").toString(QStringLiteral("..."));
case ResponseCheckEnabledRole:
return action.value(QStringLiteral("responseCheck")).toObject()
.value(QStringLiteral("enabled")).toBool(false);
case LatchResetEnabledRole:
return latchReset.value(QStringLiteral("enabled")).toBool(false);
case LatchResetUrlRole:
return latchReset.value(QStringLiteral("resetUrl")).toString();
case LatchSuccessMatchRole:
return latchReset.value(QStringLiteral("successMatch")).toString(QStringLiteral("OK"));
case LatchFireAndForgetRole:
return latchReset.value(QStringLiteral("fireAndForget")).toBool(false);
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");
case TriggerModeRole: return trigger.value("mode").toString("hold");
case HoldMsRole: return trigger.value("holdMs").toInt(800);
}
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"},
{PendingTextRole, "pendingText"},
{ResponseCheckEnabledRole, "responseCheckEnabled"},
{LatchResetEnabledRole, "latchResetEnabled"},
{LatchResetUrlRole, "latchResetUrl"},
{LatchSuccessMatchRole, "latchSuccessMatch"},
{LatchFireAndForgetRole, "latchFireAndForget"},
{FadeMsRole, "fadeMs"},
{StatusRole, "status"},
{StatusTextRole, "statusText"},
{BtnColorRole, "btnColor"},
{TriggerModeRole, "triggerMode"},
{HoldMsRole, "holdMs"}
};
}
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});
}
int ButtonsModel::buttonStatus(const QString &id) const
{
return m_runtime.value(id).status;
}
QVariantMap ButtonsModel::buttonToVariant(const QJsonObject &b, int row) const
{
Q_UNUSED(b); Q_UNUSED(row);
return {};
}