mirror of
https://github.com/Lurkki14/tuxclocker.git
synced 2025-02-25 18:55:24 -06:00
qt: display unit and current value in Assignables
This commit is contained in:
parent
3aedbf474b
commit
7268ef989e
@ -8,7 +8,8 @@ namespace TC = TuxClocker;
|
||||
class AssignableItemData {
|
||||
public:
|
||||
AssignableItemData() {m_enabled = false;}
|
||||
AssignableItemData(TC::Device::AssignableInfo info) : m_info(info) {
|
||||
AssignableItemData(TC::Device::AssignableInfo info, std::optional<QString> unit) : m_info(info) {
|
||||
m_unit = unit;
|
||||
m_enabled = false;
|
||||
}
|
||||
TC::Device::AssignableInfo assignableInfo() {return m_info;}
|
||||
@ -17,8 +18,10 @@ public:
|
||||
void setCommittal(bool on) {m_enabled = on;}
|
||||
void setValue(QVariant v) {m_targetValue = v;}
|
||||
QVariant value() {return m_targetValue;}
|
||||
std::optional<QString> unit() {return m_unit;}
|
||||
private:
|
||||
bool m_enabled;
|
||||
TC::Device::AssignableInfo m_info;
|
||||
std::optional<QString> m_unit;
|
||||
QVariant m_targetValue;
|
||||
};
|
||||
|
@ -10,10 +10,14 @@ namespace TCD = TuxClocker::DBus;
|
||||
using namespace TuxClocker::Device;
|
||||
|
||||
Q_DECLARE_METATYPE(TCD::Result<int>)
|
||||
Q_DECLARE_METATYPE(TCD::Result<QString>)
|
||||
Q_DECLARE_METATYPE(TCD::Result<QDBusVariant>)
|
||||
|
||||
AssignableProxy::AssignableProxy(QString path, QDBusConnection conn,
|
||||
QObject *parent) : QObject(parent) {
|
||||
qDBusRegisterMetaType<TCD::Result<int>>();
|
||||
qDBusRegisterMetaType<TCD::Result<QString>>();
|
||||
qDBusRegisterMetaType<TCD::Result<QDBusVariant>>();
|
||||
m_iface = new QDBusInterface("org.tuxclocker",
|
||||
path, "org.tuxclocker.Assignable", conn, this);
|
||||
}
|
||||
@ -58,3 +62,31 @@ void AssignableProxy::startConnection(std::shared_ptr<AssignableConnection> conn
|
||||
emit connectionStarted();
|
||||
m_assignableConnection->start();
|
||||
}
|
||||
|
||||
// DBus type to the more precise C++ type
|
||||
std::optional<AssignmentArgument> toAssignmentArgument(TCD::Result<QDBusVariant> res) {
|
||||
if (res.error)
|
||||
return std::nullopt;
|
||||
|
||||
auto type = static_cast<QMetaType::Type>(res.value.variant().type());
|
||||
auto v = res.value.variant();
|
||||
|
||||
switch (type) {
|
||||
case QMetaType::Int:
|
||||
return v.value<int>();
|
||||
case QMetaType::UInt:
|
||||
return v.value<uint>();
|
||||
case QMetaType::Double:
|
||||
return v.value<double>();
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::optional<AssignmentArgument> AssignableProxy::currentValue() {
|
||||
QDBusReply<TCD::Result<QDBusVariant>> reply = m_iface->call("currentValue");
|
||||
if (!reply.isValid())
|
||||
return std::nullopt;
|
||||
return toAssignmentArgument(reply.value());
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ public:
|
||||
// Stop connection and clear current connection
|
||||
void stopConnection();
|
||||
void setValue(QVariant v) {m_value = v;}
|
||||
std::optional<TC::Device::AssignmentArgument> currentValue();
|
||||
signals:
|
||||
void applied(std::optional<TC::Device::AssignmentError>);
|
||||
void connectionValueChanged(std::variant<QVariant, TC::Device::AssignmentError>,
|
||||
|
@ -2,8 +2,6 @@
|
||||
|
||||
#include "AssignableProxy.hpp"
|
||||
#include "DynamicReadableProxy.hpp"
|
||||
#include "qnamespace.h"
|
||||
#include "qstandarditemmodel.h"
|
||||
#include <fplus/fplus.hpp>
|
||||
#include <QApplication>
|
||||
#include <QDBusReply>
|
||||
@ -23,12 +21,15 @@ Q_DECLARE_METATYPE(DynamicReadableProxy*)
|
||||
Q_DECLARE_METATYPE(TCDBus::Enumeration)
|
||||
Q_DECLARE_METATYPE(TCDBus::Range)
|
||||
Q_DECLARE_METATYPE(EnumerationVec)
|
||||
Q_DECLARE_METATYPE(TCDBus::Result<QString>)
|
||||
|
||||
DeviceModel::DeviceModel(TC::TreeNode<TCDBus::DeviceNode> root, QObject *parent) :
|
||||
QStandardItemModel(parent) {
|
||||
qDBusRegisterMetaType<TCDBus::Enumeration>();
|
||||
qDBusRegisterMetaType<QVector<TCDBus::Enumeration>>();
|
||||
qDBusRegisterMetaType<TCDBus::Range>();
|
||||
qDBusRegisterMetaType<TCDBus::Result<QString>>();
|
||||
|
||||
/* Data storage:
|
||||
- Interface column should store assignable info for editors
|
||||
- Name colums should store the interface type for filtering
|
||||
@ -107,6 +108,15 @@ std::optional<const AssignableProxy*>
|
||||
std::nullopt;
|
||||
}
|
||||
|
||||
QString fromAssignmentArgument(AssignmentArgument a_arg) {
|
||||
return p::match(a_arg) (
|
||||
pattern(as<int>(arg)) = [](auto i) {return QString::number(i);},
|
||||
pattern(as<uint>(arg)) = [](auto u) {return QString::number(u);},
|
||||
pattern(as<double>(arg)) = [](auto d) {return QString::number(d);},
|
||||
pattern(_) = [] {return QString("");}
|
||||
);
|
||||
}
|
||||
|
||||
QStandardItem *DeviceModel::createAssignable(TC::TreeNode<TCDBus::DeviceNode> node,
|
||||
QDBusConnection conn, AssignableItemData itemData) {
|
||||
auto ifaceItem = new AssignableItem(this);
|
||||
@ -132,8 +142,41 @@ QStandardItem *DeviceModel::createAssignable(TC::TreeNode<TCDBus::DeviceNode> no
|
||||
QVariant v;
|
||||
v.setValue(itemData);
|
||||
ifaceItem->setData(v, AssignableRole);
|
||||
ifaceItem->setText("No value set");
|
||||
|
||||
|
||||
// Set initial text to current value (one-time at startup)
|
||||
QString text("No value set");
|
||||
auto unit = itemData.unit();
|
||||
auto currentValue = proxy->currentValue();
|
||||
|
||||
if (currentValue.has_value()) {
|
||||
p::match(itemData.assignableInfo()) (
|
||||
pattern(as<EnumerationVec>(arg)) = [&](auto e_vec) {
|
||||
/* Find index from EnumVec (O(n) doesn't matter since we only search once here)
|
||||
This should never be anything other than an uint but in theory it could be
|
||||
whatever at this point */
|
||||
try {
|
||||
auto index = std::get<uint>(currentValue.value());
|
||||
for (auto &e : e_vec) {
|
||||
if (index == e.key) {
|
||||
text = QString::fromStdString(e.name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (std::bad_variant_access &e) {}
|
||||
|
||||
//text = QString::fromStdString(e_vec[std::get<uint>(currentValue.value())].name);
|
||||
},
|
||||
pattern(as<RangeInfo>(_)) = [&]() {
|
||||
auto base = fromAssignmentArgument(currentValue.value());
|
||||
if (unit.has_value())
|
||||
text = QString("%1 %2").arg(base, unit.value());
|
||||
else
|
||||
text = base;
|
||||
}
|
||||
);
|
||||
}
|
||||
ifaceItem->setText(text);
|
||||
|
||||
connect(ifaceItem, &AssignableItem::assignableDataChanged,
|
||||
[=](QVariant v) {
|
||||
// Only show checkbox when value has been changed
|
||||
@ -199,6 +242,12 @@ QVariant DeviceModel::data(const QModelIndex &index, int role) const {
|
||||
return QStandardItemModel::data(index, role);
|
||||
}
|
||||
|
||||
std::optional<QString> fromDBusResult(TCDBus::Result<QString> res) {
|
||||
if (res.error)
|
||||
return std::nullopt;
|
||||
return res.value;
|
||||
}
|
||||
|
||||
std::optional<QStandardItem*> DeviceModel::setupAssignable(
|
||||
TC::TreeNode<TCDBus::DeviceNode> node, QDBusConnection conn) {
|
||||
QDBusInterface ifaceNode("org.tuxclocker", node.value().path,
|
||||
@ -207,6 +256,13 @@ std::optional<QStandardItem*> DeviceModel::setupAssignable(
|
||||
auto a_info =
|
||||
qvariant_cast<QDBusVariant>(ifaceNode.property("assignableInfo"))
|
||||
.variant();
|
||||
// Get unit of Assignable
|
||||
auto dbusUnit = qvariant_cast<TCDBus::Result<QString>>(ifaceNode.property("unit"));
|
||||
auto unit = fromDBusResult(dbusUnit);
|
||||
|
||||
// Get initial value
|
||||
|
||||
|
||||
/* TODO: bad hack: this code can only differentiate between
|
||||
arrays and structs: make it based on signature instead */
|
||||
auto d_arg = qvariant_cast<QDBusArgument>(a_info);
|
||||
@ -214,13 +270,13 @@ std::optional<QStandardItem*> DeviceModel::setupAssignable(
|
||||
case QDBusArgument::StructureType: {
|
||||
TCDBus::Range r;
|
||||
d_arg >> r;
|
||||
AssignableItemData data(r.toAssignableInfo());
|
||||
AssignableItemData data(r.toAssignableInfo(), unit);
|
||||
return createAssignable(node, conn, data);
|
||||
}
|
||||
case QDBusArgument::ArrayType: {
|
||||
QVector<TCDBus::Enumeration> e;
|
||||
d_arg >> e;
|
||||
AssignableItemData data(toEnumVec(e));
|
||||
AssignableItemData data(toEnumVec(e), unit);
|
||||
return createAssignable(node, conn, data);
|
||||
}
|
||||
default:
|
||||
|
@ -60,7 +60,13 @@ void DeviceModelDelegate::setModelData(QWidget *editor,
|
||||
data.setValue(a_editor->assignableData());
|
||||
QVariant v;
|
||||
v.setValue(data);
|
||||
model->setData(index, a_editor->displayData(), Qt::DisplayRole);
|
||||
// TODO: add unit
|
||||
|
||||
auto text = (data.unit().has_value()) ?
|
||||
QString("%1 %2").arg(a_editor->displayData(), data.unit().value()) :
|
||||
a_editor->displayData();
|
||||
|
||||
model->setData(index, text, Qt::DisplayRole);
|
||||
model->setData(index, v, DeviceModel::AssignableRole);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user