#include "buttonsmodel.h" #include "configmanager.h" #include #include #include #include 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 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 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 {}; }