Merge PR #124: Improved add device wizard
This commit is contained in:
commit
b2cfc0ec15
@ -1,6 +1,7 @@
|
|||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
* *
|
* *
|
||||||
* Copyright (C) 2017 Simon Stuerz <simon.stuerz@guh.io> *
|
* Copyright (C) 2017 Simon Stuerz <simon.stuerz@guh.io> *
|
||||||
|
* Copyright (C) 2019 Michael Zanetti <michael.zanetti@nymea.io> *
|
||||||
* *
|
* *
|
||||||
* This file is part of nymea:app *
|
* This file is part of nymea:app *
|
||||||
* *
|
* *
|
||||||
@ -57,6 +58,10 @@ QVariant DeviceClasses::data(const QModelIndex &index, int role) const
|
|||||||
return deviceClass->pluginId().toString();
|
return deviceClass->pluginId().toString();
|
||||||
case RoleVendorId:
|
case RoleVendorId:
|
||||||
return deviceClass->vendorId().toString();
|
return deviceClass->vendorId().toString();
|
||||||
|
case RoleInterfaces:
|
||||||
|
return deviceClass->interfaces();
|
||||||
|
case RoleBaseInterface:
|
||||||
|
return deviceClass->baseInterface();
|
||||||
}
|
}
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
@ -68,6 +73,9 @@ int DeviceClasses::count() const
|
|||||||
|
|
||||||
DeviceClass *DeviceClasses::get(int index) const
|
DeviceClass *DeviceClasses::get(int index) const
|
||||||
{
|
{
|
||||||
|
if (index < 0 || index >= m_deviceClasses.count()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
return m_deviceClasses.at(index);
|
return m_deviceClasses.at(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,5 +116,7 @@ QHash<int, QByteArray> DeviceClasses::roleNames() const
|
|||||||
roles[RoleDisplayName] = "displayName";
|
roles[RoleDisplayName] = "displayName";
|
||||||
roles[RolePluginId] = "pluginId";
|
roles[RolePluginId] = "pluginId";
|
||||||
roles[RoleVendorId] = "vendorId";
|
roles[RoleVendorId] = "vendorId";
|
||||||
|
roles[RoleInterfaces] = "interfaces";
|
||||||
|
roles[RoleBaseInterface] = "baseInterface";
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
* *
|
* *
|
||||||
* Copyright (C) 2017 Simon Stuerz <simon.stuerz@guh.io> *
|
* Copyright (C) 2017 Simon Stuerz <simon.stuerz@guh.io> *
|
||||||
|
* Copyright (C) 2019 Michael Zanetti <michael.zanetti@nymea.io> *
|
||||||
* *
|
* *
|
||||||
* This file is part of nymea:app *
|
* This file is part of nymea:app *
|
||||||
* *
|
* *
|
||||||
@ -37,10 +38,12 @@ public:
|
|||||||
RoleName,
|
RoleName,
|
||||||
RoleDisplayName,
|
RoleDisplayName,
|
||||||
RolePluginId,
|
RolePluginId,
|
||||||
RoleVendorId
|
RoleVendorId,
|
||||||
|
RoleInterfaces,
|
||||||
|
RoleBaseInterface
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit DeviceClasses(QObject *parent = 0);
|
explicit DeviceClasses(QObject *parent = nullptr);
|
||||||
|
|
||||||
QList<DeviceClass *> deviceClasses();
|
QList<DeviceClass *> deviceClasses();
|
||||||
|
|
||||||
|
|||||||
@ -27,8 +27,10 @@
|
|||||||
DeviceClassesProxy::DeviceClassesProxy(QObject *parent) :
|
DeviceClassesProxy::DeviceClassesProxy(QObject *parent) :
|
||||||
QSortFilterProxyModel(parent)
|
QSortFilterProxyModel(parent)
|
||||||
{
|
{
|
||||||
|
setSortRole(DeviceClasses::RoleDisplayName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QUuid DeviceClassesProxy::vendorId() const
|
QUuid DeviceClassesProxy::vendorId() const
|
||||||
{
|
{
|
||||||
return m_vendorId;
|
return m_vendorId;
|
||||||
@ -55,6 +57,35 @@ void DeviceClassesProxy::setDeviceClasses(DeviceClasses *deviceClasses)
|
|||||||
m_deviceClasses = deviceClasses;
|
m_deviceClasses = deviceClasses;
|
||||||
setSourceModel(deviceClasses);
|
setSourceModel(deviceClasses);
|
||||||
emit deviceClassesChanged();
|
emit deviceClassesChanged();
|
||||||
|
sort(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString DeviceClassesProxy::filterInterface() const
|
||||||
|
{
|
||||||
|
return m_filterInterface;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceClassesProxy::setFilterInterface(const QString &filterInterface)
|
||||||
|
{
|
||||||
|
if (m_filterInterface != filterInterface) {
|
||||||
|
m_filterInterface = filterInterface;
|
||||||
|
emit filterInterfaceChanged();
|
||||||
|
invalidateFilter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DeviceClassesProxy::groupByInterface() const
|
||||||
|
{
|
||||||
|
return m_groupByInterface;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceClassesProxy::setGroupByInterface(bool groupByInterface)
|
||||||
|
{
|
||||||
|
if (m_groupByInterface != groupByInterface) {
|
||||||
|
m_groupByInterface = groupByInterface;
|
||||||
|
emit groupByInterfaceChanged();
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceClass *DeviceClassesProxy::get(int index) const
|
DeviceClass *DeviceClassesProxy::get(int index) const
|
||||||
@ -80,16 +111,27 @@ bool DeviceClassesProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sour
|
|||||||
if (deviceClass->createMethods().count() == 1 && deviceClass->createMethods().contains("CreateMethodAuto"))
|
if (deviceClass->createMethods().count() == 1 && deviceClass->createMethods().contains("CreateMethodAuto"))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!m_vendorId.isNull() && deviceClass->vendorId() == m_vendorId)
|
if (!m_vendorId.isNull() && deviceClass->vendorId() != m_vendorId)
|
||||||
return true;
|
return false;
|
||||||
|
|
||||||
return false;
|
if (!m_filterInterface.isEmpty() && !deviceClass->interfaces().contains(m_filterInterface)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DeviceClassesProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const
|
bool DeviceClassesProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const
|
||||||
{
|
{
|
||||||
QVariant leftName = sourceModel()->data(left);
|
if (m_groupByInterface) {
|
||||||
QVariant rightName = sourceModel()->data(right);
|
QString leftBaseInterface = sourceModel()->data(left, DeviceClasses::RoleBaseInterface).toString();
|
||||||
|
QString rightBaseInterface = sourceModel()->data(right, DeviceClasses::RoleBaseInterface).toString();
|
||||||
|
if (leftBaseInterface != rightBaseInterface) {
|
||||||
|
return QString::localeAwareCompare(leftBaseInterface, rightBaseInterface) < 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QString leftName = sourceModel()->data(left, DeviceClasses::RoleDisplayName).toString();
|
||||||
|
QString rightName = sourceModel()->data(right, DeviceClasses::RoleDisplayName).toString();
|
||||||
|
|
||||||
return QString::localeAwareCompare(leftName.toString(), rightName.toString()) < 0;
|
return QString::localeAwareCompare(leftName, rightName) < 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,8 +36,12 @@ class DeviceClassesProxy : public QSortFilterProxyModel
|
|||||||
Q_PROPERTY(QUuid vendorId READ vendorId WRITE setVendorId NOTIFY vendorIdChanged)
|
Q_PROPERTY(QUuid vendorId READ vendorId WRITE setVendorId NOTIFY vendorIdChanged)
|
||||||
Q_PROPERTY(DeviceClasses *deviceClasses READ deviceClasses WRITE setDeviceClasses NOTIFY deviceClassesChanged)
|
Q_PROPERTY(DeviceClasses *deviceClasses READ deviceClasses WRITE setDeviceClasses NOTIFY deviceClassesChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(QString filterInterface READ filterInterface WRITE setFilterInterface NOTIFY filterInterfaceChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(bool groupByInterface READ groupByInterface WRITE setGroupByInterface NOTIFY groupByInterfaceChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit DeviceClassesProxy(QObject *parent = 0);
|
explicit DeviceClassesProxy(QObject *parent = nullptr);
|
||||||
|
|
||||||
QUuid vendorId() const;
|
QUuid vendorId() const;
|
||||||
void setVendorId(const QUuid &vendorId);
|
void setVendorId(const QUuid &vendorId);
|
||||||
@ -45,10 +49,22 @@ public:
|
|||||||
DeviceClasses *deviceClasses();
|
DeviceClasses *deviceClasses();
|
||||||
void setDeviceClasses(DeviceClasses *deviceClasses);
|
void setDeviceClasses(DeviceClasses *deviceClasses);
|
||||||
|
|
||||||
|
QString filterInterface() const;
|
||||||
|
void setFilterInterface(const QString &filterInterface);
|
||||||
|
|
||||||
|
bool groupByInterface() const;
|
||||||
|
void setGroupByInterface(bool groupByInterface);
|
||||||
|
|
||||||
Q_INVOKABLE DeviceClass *get(int index) const;
|
Q_INVOKABLE DeviceClass *get(int index) const;
|
||||||
|
|
||||||
Q_INVOKABLE void resetFilter();
|
Q_INVOKABLE void resetFilter();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void vendorIdChanged();
|
||||||
|
void deviceClassesChanged();
|
||||||
|
void filterInterfaceChanged();
|
||||||
|
void groupByInterfaceChanged();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const Q_DECL_OVERRIDE;
|
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const Q_DECL_OVERRIDE;
|
||||||
bool lessThan(const QModelIndex &left, const QModelIndex &right) const Q_DECL_OVERRIDE;
|
bool lessThan(const QModelIndex &left, const QModelIndex &right) const Q_DECL_OVERRIDE;
|
||||||
@ -56,11 +72,8 @@ protected:
|
|||||||
private:
|
private:
|
||||||
QUuid m_vendorId;
|
QUuid m_vendorId;
|
||||||
DeviceClasses *m_deviceClasses;
|
DeviceClasses *m_deviceClasses;
|
||||||
|
QString m_filterInterface;
|
||||||
signals:
|
bool m_groupByInterface = false;
|
||||||
void vendorIdChanged();
|
|
||||||
void deviceClassesChanged();
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DEVICECLASSFILERMODEL_H
|
#endif // DEVICECLASSFILERMODEL_H
|
||||||
|
|||||||
@ -74,68 +74,12 @@ QVariant Devices::data(const QModelIndex &index, int role) const
|
|||||||
return device->deviceClassId().toString();
|
return device->deviceClassId().toString();
|
||||||
case RoleSetupComplete:
|
case RoleSetupComplete:
|
||||||
return device->setupComplete();
|
return device->setupComplete();
|
||||||
case RoleInterfaces: {
|
case RoleInterfaces:
|
||||||
return device->deviceClass()->interfaces();
|
return device->deviceClass()->interfaces();
|
||||||
}
|
case RoleBaseInterface:
|
||||||
case RoleBaseInterface: {
|
return device->deviceClass()->baseInterface();
|
||||||
QStringList interfaces = device->deviceClass()->interfaces();
|
|
||||||
if (interfaces.contains("gateway")) {
|
|
||||||
return "gateway";
|
|
||||||
}
|
|
||||||
if (interfaces.contains("shutter")) {
|
|
||||||
return "shutter";
|
|
||||||
}
|
|
||||||
if (interfaces.contains("blind")) {
|
|
||||||
return "blind";
|
|
||||||
}
|
|
||||||
if (interfaces.contains("garagegate")) {
|
|
||||||
return "garagegate";
|
|
||||||
}
|
|
||||||
if (interfaces.contains("inputtrigger")) {
|
|
||||||
return "inputtrigger";
|
|
||||||
}
|
|
||||||
if (interfaces.contains("awning")) {
|
|
||||||
return "awning";
|
|
||||||
}
|
|
||||||
if (interfaces.contains("outputtrigger")) {
|
|
||||||
return "outputtrigger";
|
|
||||||
}
|
|
||||||
if (interfaces.contains("light")) {
|
|
||||||
return "light";
|
|
||||||
}
|
|
||||||
if (interfaces.contains("sensor")) {
|
|
||||||
return "sensor";
|
|
||||||
}
|
|
||||||
if (interfaces.contains("weather")) {
|
|
||||||
return "weather";
|
|
||||||
}
|
|
||||||
if (interfaces.contains("media")) {
|
|
||||||
return "media";
|
|
||||||
}
|
|
||||||
if (interfaces.contains("button")) {
|
|
||||||
return "button";
|
|
||||||
}
|
|
||||||
if (interfaces.contains("notifications")) {
|
|
||||||
return "notifications";
|
|
||||||
}
|
|
||||||
if (interfaces.contains("smartmeter")) {
|
|
||||||
return "smartmeter";
|
|
||||||
}
|
|
||||||
if (interfaces.contains("heating")) {
|
|
||||||
return "heating";
|
|
||||||
}
|
|
||||||
if (interfaces.contains("evcharger")) {
|
|
||||||
return "evcharger";
|
|
||||||
}
|
|
||||||
if (interfaces.contains("powersocket")) {
|
|
||||||
return "powersocket";
|
|
||||||
}
|
|
||||||
return "uncategorized";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Devices::addDevice(Device *device)
|
void Devices::addDevice(Device *device)
|
||||||
|
|||||||
@ -65,6 +65,20 @@ void InterfacesModel::setShownInterfaces(const QStringList &shownInterfaces)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool InterfacesModel::onlyConfiguredDevices() const
|
||||||
|
{
|
||||||
|
return m_onlyConfiguredDevices;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InterfacesModel::setOnlyConfiguredDevices(bool onlyConfigured)
|
||||||
|
{
|
||||||
|
if (m_onlyConfiguredDevices != onlyConfigured) {
|
||||||
|
m_onlyConfiguredDevices = onlyConfigured;
|
||||||
|
emit onlyConfiguredDevicesChanged();
|
||||||
|
syncInterfaces();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool InterfacesModel::showUncategorized() const
|
bool InterfacesModel::showUncategorized() const
|
||||||
{
|
{
|
||||||
return m_showUncategorized;
|
return m_showUncategorized;
|
||||||
@ -79,30 +93,47 @@ void InterfacesModel::setShowUncategorized(bool showUncategorized)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString InterfacesModel::get(int index) const
|
||||||
|
{
|
||||||
|
if (index < 0 || index > m_interfaces.count()) {
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
return m_interfaces.at(index);
|
||||||
|
}
|
||||||
|
|
||||||
void InterfacesModel::syncInterfaces()
|
void InterfacesModel::syncInterfaces()
|
||||||
{
|
{
|
||||||
if (!m_deviceManager) {
|
if (!m_deviceManager) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
QStringList baseList;
|
||||||
|
if (m_onlyConfiguredDevices) {
|
||||||
|
for (int i = 0; i < m_deviceManager->devices()->rowCount(); i++) {
|
||||||
|
DeviceClass *dc = m_deviceManager->deviceClasses()->getDeviceClass(m_deviceManager->devices()->get(i)->deviceClassId());
|
||||||
|
baseList << dc->interfaces();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < m_deviceManager->deviceClasses()->rowCount(); i++) {
|
||||||
|
DeviceClass *dc = m_deviceManager->deviceClasses()->get(i);
|
||||||
|
baseList << dc->interfaces();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
baseList.removeDuplicates();
|
||||||
|
|
||||||
QStringList interfacesInSource;
|
QStringList interfacesInSource;
|
||||||
for (int i = 0; i < m_deviceManager->devices()->rowCount(); i++) {
|
bool isInShownIfaces = false;
|
||||||
DeviceClass *dc = m_deviceManager->deviceClasses()->getDeviceClass(m_deviceManager->devices()->get(i)->deviceClassId());
|
foreach (const QString &interface, baseList) {
|
||||||
// qDebug() << "device" <<dc->name() << "has interfaces" << dc->interfaces();
|
if (!m_shownInterfaces.contains(interface)) {
|
||||||
|
continue;
|
||||||
bool isInShownIfaces = false;
|
|
||||||
foreach (const QString &interface, dc->interfaces()) {
|
|
||||||
if (!m_shownInterfaces.contains(interface)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!interfacesInSource.contains(interface)) {
|
|
||||||
interfacesInSource.append(interface);
|
|
||||||
}
|
|
||||||
isInShownIfaces = true;
|
|
||||||
}
|
}
|
||||||
if (!isInShownIfaces && !interfacesInSource.contains("uncategorized")) {
|
|
||||||
interfacesInSource.append("uncategorized");
|
if (!interfacesInSource.contains(interface)) {
|
||||||
|
interfacesInSource.append(interface);
|
||||||
}
|
}
|
||||||
|
isInShownIfaces = true;
|
||||||
|
}
|
||||||
|
if (!isInShownIfaces && !interfacesInSource.contains("uncategorized")) {
|
||||||
|
interfacesInSource.append("uncategorized");
|
||||||
}
|
}
|
||||||
QStringList interfacesToAdd = interfacesInSource;
|
QStringList interfacesToAdd = interfacesInSource;
|
||||||
QStringList interfacesToRemove;
|
QStringList interfacesToRemove;
|
||||||
|
|||||||
@ -14,6 +14,8 @@ class InterfacesModel : public QAbstractListModel
|
|||||||
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
|
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
|
||||||
Q_PROPERTY(DeviceManager* deviceManager READ deviceManager WRITE setDeviceManager NOTIFY deviceManagerChanged)
|
Q_PROPERTY(DeviceManager* deviceManager READ deviceManager WRITE setDeviceManager NOTIFY deviceManagerChanged)
|
||||||
Q_PROPERTY(QStringList shownInterfaces READ shownInterfaces WRITE setShownInterfaces NOTIFY shownInterfacesChanged)
|
Q_PROPERTY(QStringList shownInterfaces READ shownInterfaces WRITE setShownInterfaces NOTIFY shownInterfacesChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(bool onlyConfiguredDevices READ onlyConfiguredDevices WRITE setOnlyConfiguredDevices NOTIFY onlyConfiguredDevicesChanged)
|
||||||
Q_PROPERTY(bool showUncategorized READ showUncategorized WRITE setShowUncategorized NOTIFY showUncategorizedChanged)
|
Q_PROPERTY(bool showUncategorized READ showUncategorized WRITE setShowUncategorized NOTIFY showUncategorizedChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -34,13 +36,19 @@ public:
|
|||||||
QStringList shownInterfaces() const;
|
QStringList shownInterfaces() const;
|
||||||
void setShownInterfaces(const QStringList &shownInterfaces);
|
void setShownInterfaces(const QStringList &shownInterfaces);
|
||||||
|
|
||||||
|
bool onlyConfiguredDevices() const;
|
||||||
|
void setOnlyConfiguredDevices(bool onlyConfigured);
|
||||||
|
|
||||||
bool showUncategorized() const;
|
bool showUncategorized() const;
|
||||||
void setShowUncategorized(bool showUncategorized);
|
void setShowUncategorized(bool showUncategorized);
|
||||||
|
|
||||||
|
Q_INVOKABLE QString get(int index) const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void countChanged();
|
void countChanged();
|
||||||
void deviceManagerChanged();
|
void deviceManagerChanged();
|
||||||
void shownInterfacesChanged();
|
void shownInterfacesChanged();
|
||||||
|
bool onlyConfiguredDevicesChanged();
|
||||||
void showUncategorizedChanged();
|
void showUncategorizedChanged();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
@ -52,6 +60,7 @@ private:
|
|||||||
QStringList m_interfaces;
|
QStringList m_interfaces;
|
||||||
|
|
||||||
QStringList m_shownInterfaces;
|
QStringList m_shownInterfaces;
|
||||||
|
bool m_onlyConfiguredDevices = true;
|
||||||
bool m_showUncategorized = false;
|
bool m_showUncategorized = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -50,7 +50,7 @@ JsonTypes::JsonTypes(QObject *parent) :
|
|||||||
|
|
||||||
Vendor *JsonTypes::unpackVendor(const QVariantMap &vendorMap)
|
Vendor *JsonTypes::unpackVendor(const QVariantMap &vendorMap)
|
||||||
{
|
{
|
||||||
Vendor *v = new Vendor(vendorMap.value("id").toUuid(), vendorMap.value("name").toString());
|
Vendor *v = new Vendor(vendorMap.value("id").toString(), vendorMap.value("name").toString());
|
||||||
v->setDisplayName(vendorMap.value("displayName").toString());
|
v->setDisplayName(vendorMap.value("displayName").toString());
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,7 +34,7 @@ class VendorsProxy : public QSortFilterProxyModel
|
|||||||
Q_PROPERTY(Vendors *vendors READ vendors WRITE setVendors NOTIFY vendorsChanged)
|
Q_PROPERTY(Vendors *vendors READ vendors WRITE setVendors NOTIFY vendorsChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit VendorsProxy(QObject *parent = 0);
|
explicit VendorsProxy(QObject *parent = nullptr);
|
||||||
|
|
||||||
Vendors *vendors();
|
Vendors *vendors();
|
||||||
void setVendors(Vendors *vendors);
|
void setVendors(Vendors *vendors);
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
* *
|
* *
|
||||||
* Copyright (C) 2017 Simon Stuerz <simon.stuerz@guh.io> *
|
* Copyright (C) 2017 Simon Stuerz <simon.stuerz@guh.io> *
|
||||||
|
* Copyright (C) 2019 Michael Zanetti <michael.zanetti@nymea.io> *
|
||||||
* *
|
* *
|
||||||
* This file is part of nymea:app *
|
* This file is part of nymea:app *
|
||||||
* *
|
* *
|
||||||
@ -129,6 +130,63 @@ void DeviceClass::setInterfaces(const QStringList &interfaces)
|
|||||||
m_interfaces = interfaces;
|
m_interfaces = interfaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString DeviceClass::baseInterface() const
|
||||||
|
{
|
||||||
|
if (m_interfaces.contains("gateway")) {
|
||||||
|
return "gateway";
|
||||||
|
}
|
||||||
|
if (m_interfaces.contains("shutter")) {
|
||||||
|
return "shutter";
|
||||||
|
}
|
||||||
|
if (m_interfaces.contains("blind")) {
|
||||||
|
return "blind";
|
||||||
|
}
|
||||||
|
if (m_interfaces.contains("garagegate")) {
|
||||||
|
return "garagegate";
|
||||||
|
}
|
||||||
|
if (m_interfaces.contains("inputtrigger")) {
|
||||||
|
return "inputtrigger";
|
||||||
|
}
|
||||||
|
if (m_interfaces.contains("awning")) {
|
||||||
|
return "awning";
|
||||||
|
}
|
||||||
|
if (m_interfaces.contains("outputtrigger")) {
|
||||||
|
return "outputtrigger";
|
||||||
|
}
|
||||||
|
if (m_interfaces.contains("light")) {
|
||||||
|
return "light";
|
||||||
|
}
|
||||||
|
if (m_interfaces.contains("sensor")) {
|
||||||
|
return "sensor";
|
||||||
|
}
|
||||||
|
if (m_interfaces.contains("weather")) {
|
||||||
|
return "weather";
|
||||||
|
}
|
||||||
|
if (m_interfaces.contains("media")) {
|
||||||
|
return "media";
|
||||||
|
}
|
||||||
|
if (m_interfaces.contains("button")) {
|
||||||
|
return "button";
|
||||||
|
}
|
||||||
|
if (m_interfaces.contains("notifications")) {
|
||||||
|
return "notifications";
|
||||||
|
}
|
||||||
|
if (m_interfaces.contains("smartmeter")) {
|
||||||
|
return "smartmeter";
|
||||||
|
}
|
||||||
|
if (m_interfaces.contains("heating")) {
|
||||||
|
return "heating";
|
||||||
|
}
|
||||||
|
if (m_interfaces.contains("evcharger")) {
|
||||||
|
return "evcharger";
|
||||||
|
}
|
||||||
|
if (m_interfaces.contains("powersocket")) {
|
||||||
|
return "powersocket";
|
||||||
|
}
|
||||||
|
return "uncategorized";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
ParamTypes *DeviceClass::paramTypes() const
|
ParamTypes *DeviceClass::paramTypes() const
|
||||||
{
|
{
|
||||||
return m_paramTypes;
|
return m_paramTypes;
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
* *
|
* *
|
||||||
* Copyright (C) 2017 Simon Stuerz <simon.stuerz@guh.io> *
|
* Copyright (C) 2017 Simon Stuerz <simon.stuerz@guh.io> *
|
||||||
|
* Copyright (C) 2019 Michael Zanetti <michael.zanetti@nymea.io> *
|
||||||
* *
|
* *
|
||||||
* This file is part of nymea:app *
|
* This file is part of nymea:app *
|
||||||
* *
|
* *
|
||||||
@ -45,6 +46,7 @@ class DeviceClass : public QObject
|
|||||||
Q_PROPERTY(SetupMethod setupMethod READ setupMethod CONSTANT)
|
Q_PROPERTY(SetupMethod setupMethod READ setupMethod CONSTANT)
|
||||||
Q_PROPERTY(QStringList basicTags READ basicTagNames CONSTANT)
|
Q_PROPERTY(QStringList basicTags READ basicTagNames CONSTANT)
|
||||||
Q_PROPERTY(QStringList interfaces READ interfaces CONSTANT)
|
Q_PROPERTY(QStringList interfaces READ interfaces CONSTANT)
|
||||||
|
Q_PROPERTY(QString baseInterface READ baseInterface CONSTANT)
|
||||||
Q_PROPERTY(ParamTypes *paramTypes READ paramTypes NOTIFY paramTypesChanged)
|
Q_PROPERTY(ParamTypes *paramTypes READ paramTypes NOTIFY paramTypesChanged)
|
||||||
Q_PROPERTY(ParamTypes *discoveryParamTypes READ discoveryParamTypes NOTIFY discoveryParamTypesChanged)
|
Q_PROPERTY(ParamTypes *discoveryParamTypes READ discoveryParamTypes NOTIFY discoveryParamTypesChanged)
|
||||||
Q_PROPERTY(StateTypes *stateTypes READ stateTypes NOTIFY stateTypesChanged)
|
Q_PROPERTY(StateTypes *stateTypes READ stateTypes NOTIFY stateTypesChanged)
|
||||||
@ -116,6 +118,8 @@ public:
|
|||||||
QStringList interfaces() const;
|
QStringList interfaces() const;
|
||||||
void setInterfaces(const QStringList &interfaces);
|
void setInterfaces(const QStringList &interfaces);
|
||||||
|
|
||||||
|
QString baseInterface() const;
|
||||||
|
|
||||||
ParamTypes *paramTypes() const;
|
ParamTypes *paramTypes() const;
|
||||||
void setParamTypes(ParamTypes *paramTypes);
|
void setParamTypes(ParamTypes *paramTypes);
|
||||||
|
|
||||||
|
|||||||
@ -22,19 +22,19 @@
|
|||||||
|
|
||||||
#include "vendor.h"
|
#include "vendor.h"
|
||||||
|
|
||||||
Vendor::Vendor(const QUuid &id, const QString &name, QObject *parent) :
|
Vendor::Vendor(const QString &id, const QString &name, QObject *parent) :
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
m_id(id),
|
m_id(id),
|
||||||
m_name(name)
|
m_name(name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
QUuid Vendor::id() const
|
QString Vendor::id() const
|
||||||
{
|
{
|
||||||
return m_id;
|
return m_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vendor::setId(const QUuid &id)
|
void Vendor::setId(const QString &id)
|
||||||
{
|
{
|
||||||
m_id = id;
|
m_id = id;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,13 +32,13 @@ class Vendor : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(QString name READ name CONSTANT)
|
Q_PROPERTY(QString name READ name CONSTANT)
|
||||||
Q_PROPERTY(QString displayName READ displayName CONSTANT)
|
Q_PROPERTY(QString displayName READ displayName CONSTANT)
|
||||||
Q_PROPERTY(QUuid id READ id CONSTANT)
|
Q_PROPERTY(QString id READ id CONSTANT)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Vendor(const QUuid &id = QUuid(), const QString &name = QString(), QObject *parent = nullptr);
|
Vendor(const QString &id = QString(), const QString &name = QString(), QObject *parent = nullptr);
|
||||||
|
|
||||||
QUuid id() const;
|
QString id() const;
|
||||||
void setId(const QUuid &id);
|
void setId(const QString &id);
|
||||||
|
|
||||||
QString name() const;
|
QString name() const;
|
||||||
void setName(const QString &name);
|
void setName(const QString &name);
|
||||||
@ -47,7 +47,7 @@ public:
|
|||||||
void setDisplayName(const QString &displayName);
|
void setDisplayName(const QString &displayName);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QUuid m_id;
|
QString m_id;
|
||||||
QString m_name;
|
QString m_name;
|
||||||
QString m_displayName;
|
QString m_displayName;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -29,24 +29,14 @@ Vendors::Vendors(QObject *parent) :
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<Vendor *> Vendors::vendors()
|
Vendor *Vendors::getVendor(const QString &vendorId) const
|
||||||
{
|
|
||||||
return m_vendors;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Vendors::count() const
|
|
||||||
{
|
|
||||||
return m_vendors.count();
|
|
||||||
}
|
|
||||||
|
|
||||||
Vendor *Vendors::getVendor(const QUuid &vendorId) const
|
|
||||||
{
|
{
|
||||||
foreach (Vendor *vendor, m_vendors) {
|
foreach (Vendor *vendor, m_vendors) {
|
||||||
if (vendor->id() == vendorId) {
|
if (vendor->id() == vendorId) {
|
||||||
return vendor;
|
return vendor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Vendors::rowCount(const QModelIndex &parent) const
|
int Vendors::rowCount(const QModelIndex &parent) const
|
||||||
@ -67,7 +57,7 @@ QVariant Vendors::data(const QModelIndex &index, int role) const
|
|||||||
case RoleDisplayName:
|
case RoleDisplayName:
|
||||||
return vendor->displayName();
|
return vendor->displayName();
|
||||||
case RoleId:
|
case RoleId:
|
||||||
return vendor->id().toString();
|
return vendor->id();
|
||||||
}
|
}
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
@ -79,15 +69,24 @@ void Vendors::addVendor(Vendor *vendor)
|
|||||||
//qDebug() << "Vendors: loaded vendor" << vendor->name();
|
//qDebug() << "Vendors: loaded vendor" << vendor->name();
|
||||||
m_vendors.append(vendor);
|
m_vendors.append(vendor);
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
|
emit countChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vendors::clearModel()
|
void Vendors::clearModel()
|
||||||
{
|
{
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
qDebug() << "Vendors: delete all vendors";
|
|
||||||
qDeleteAll(m_vendors);
|
qDeleteAll(m_vendors);
|
||||||
m_vendors.clear();
|
m_vendors.clear();
|
||||||
endResetModel();
|
endResetModel();
|
||||||
|
emit countChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
Vendor *Vendors::get(int index) const
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= m_vendors.count()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return m_vendors.at(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
QHash<int, QByteArray> Vendors::roleNames() const
|
QHash<int, QByteArray> Vendors::roleNames() const
|
||||||
|
|||||||
@ -30,6 +30,8 @@
|
|||||||
class Vendors : public QAbstractListModel
|
class Vendors : public QAbstractListModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum Role {
|
enum Role {
|
||||||
RoleId,
|
RoleId,
|
||||||
@ -37,20 +39,20 @@ public:
|
|||||||
RoleDisplayName
|
RoleDisplayName
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit Vendors(QObject *parent = 0);
|
explicit Vendors(QObject *parent = nullptr);
|
||||||
|
|
||||||
QList<Vendor *> vendors();
|
|
||||||
|
|
||||||
Q_INVOKABLE int count() const;
|
|
||||||
Q_INVOKABLE Vendor *getVendor(const QUuid &vendorId) const;
|
|
||||||
|
|
||||||
int rowCount(const QModelIndex & parent = QModelIndex()) const;
|
int rowCount(const QModelIndex & parent = QModelIndex()) const;
|
||||||
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
|
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
|
||||||
|
|
||||||
void addVendor(Vendor *vendor);
|
void addVendor(Vendor *vendor);
|
||||||
|
|
||||||
void clearModel();
|
void clearModel();
|
||||||
|
|
||||||
|
Q_INVOKABLE Vendor* get(int index) const;
|
||||||
|
Q_INVOKABLE Vendor *getVendor(const QString &vendorId) const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void countChanged();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QHash<int, QByteArray> roleNames() const;
|
QHash<int, QByteArray> roleNames() const;
|
||||||
|
|
||||||
|
|||||||
@ -32,7 +32,6 @@
|
|||||||
<file>ui/components/IconMenuItem.qml</file>
|
<file>ui/components/IconMenuItem.qml</file>
|
||||||
<file>ui/components/Graph.qml</file>
|
<file>ui/components/Graph.qml</file>
|
||||||
<file>ui/components/ErrorDialog.qml</file>
|
<file>ui/components/ErrorDialog.qml</file>
|
||||||
<file>ui/components/InterfacesModels.qml</file>
|
|
||||||
<file>ui/components/ShutterControls.qml</file>
|
<file>ui/components/ShutterControls.qml</file>
|
||||||
<file>ui/components/MeaDialog.qml</file>
|
<file>ui/components/MeaDialog.qml</file>
|
||||||
<file>ui/components/MeaListItemDelegate.qml</file>
|
<file>ui/components/MeaListItemDelegate.qml</file>
|
||||||
@ -147,5 +146,6 @@
|
|||||||
<file>ui/devicepages/BoolSensorDevicePage.qml</file>
|
<file>ui/devicepages/BoolSensorDevicePage.qml</file>
|
||||||
<file>ui/devicepages/PowersocketDevicePage.qml</file>
|
<file>ui/devicepages/PowersocketDevicePage.qml</file>
|
||||||
<file>ui/devicelistpages/PowerSocketsDeviceListPage.qml</file>
|
<file>ui/devicelistpages/PowerSocketsDeviceListPage.qml</file>
|
||||||
|
<file>ui/components/GroupedListView.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|||||||
@ -60,7 +60,7 @@ Page {
|
|||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
|
|
||||||
ListView {
|
GroupedListView {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
clip: true
|
clip: true
|
||||||
@ -71,11 +71,6 @@ Page {
|
|||||||
groupByInterface: true
|
groupByInterface: true
|
||||||
nameFilter: filterInput.shown ? filterInput.text : ""
|
nameFilter: filterInput.shown ? filterInput.text : ""
|
||||||
}
|
}
|
||||||
section.property: "baseInterface"
|
|
||||||
section.criteria: ViewSection.FullString
|
|
||||||
section.delegate: ListSectionHeader {
|
|
||||||
text: app.interfaceToString(section)
|
|
||||||
}
|
|
||||||
|
|
||||||
delegate: ThingDelegate {
|
delegate: ThingDelegate {
|
||||||
device: deviceProxy.get(index)
|
device: deviceProxy.get(index)
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import QtQuick 2.5
|
import QtQuick 2.5
|
||||||
import QtQuick.Layouts 1.1
|
import QtQuick.Layouts 1.1
|
||||||
import QtQuick.Controls 2.1
|
import QtQuick.Controls 2.1
|
||||||
|
import QtQuick.Controls.Material 2.1
|
||||||
import Nymea 1.0
|
import Nymea 1.0
|
||||||
import "components"
|
import "components"
|
||||||
import "delegates"
|
import "delegates"
|
||||||
@ -27,7 +28,7 @@ Page {
|
|||||||
property DeviceClass deviceClass: null
|
property DeviceClass deviceClass: null
|
||||||
property DeviceDescriptor deviceDescriptor: null
|
property DeviceDescriptor deviceDescriptor: null
|
||||||
property var discoveryParams: []
|
property var discoveryParams: []
|
||||||
property string deviceName: null
|
property string deviceName: ""
|
||||||
property int pairRequestId: 0
|
property int pairRequestId: 0
|
||||||
property var pairingTransactionId: null
|
property var pairingTransactionId: null
|
||||||
property int addRequestId: 0
|
property int addRequestId: 0
|
||||||
@ -70,7 +71,12 @@ Page {
|
|||||||
StackView {
|
StackView {
|
||||||
id: internalPageStack
|
id: internalPageStack
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
initialItem: Page {
|
Component.onCompleted: push(deviceClassesPage)
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: vendorsPage
|
||||||
|
Page {
|
||||||
ListView {
|
ListView {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
model: VendorsProxy {
|
model: VendorsProxy {
|
||||||
@ -92,18 +98,98 @@ Page {
|
|||||||
Component {
|
Component {
|
||||||
id: deviceClassesPage
|
id: deviceClassesPage
|
||||||
Page {
|
Page {
|
||||||
ListView {
|
Pane {
|
||||||
anchors.fill: parent
|
id: filterPane
|
||||||
|
anchors { left: parent.left; top: parent.top; right: parent.right }
|
||||||
|
Behavior on height { NumberAnimation { duration: 120; easing.type: Easing.InOutQuad } }
|
||||||
|
|
||||||
|
height: implicitHeight + app.margins * 2
|
||||||
|
Material.elevation: 1
|
||||||
|
z: 1
|
||||||
|
|
||||||
|
leftPadding: 0; rightPadding: 0; topPadding: 0; bottomPadding: 0
|
||||||
|
contentItem: Rectangle {
|
||||||
|
color: app.primaryColor
|
||||||
|
clip: true
|
||||||
|
GridLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: app.margins
|
||||||
|
columnSpacing: app.margins
|
||||||
|
columns: 2
|
||||||
|
Label {
|
||||||
|
text: qsTr("Vendor")
|
||||||
|
}
|
||||||
|
|
||||||
|
ComboBox {
|
||||||
|
id: vendorFilterComboBox
|
||||||
|
Layout.fillWidth: true
|
||||||
|
textRole: "displayName"
|
||||||
|
model: ListModel {
|
||||||
|
id: vendorsFilterModel
|
||||||
|
ListElement { displayName: qsTr("All"); vendorId: "" }
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
for (var i = 0; i < engine.deviceManager.vendors.count; i++) {
|
||||||
|
var vendor = engine.deviceManager.vendors.get(i);
|
||||||
|
append({displayName: vendor.displayName, vendorId: vendor.id})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: qsTr("Type")
|
||||||
|
}
|
||||||
|
|
||||||
|
ComboBox {
|
||||||
|
id: typeFilterComboBox
|
||||||
|
Layout.fillWidth: true
|
||||||
|
textRole: "displayName"
|
||||||
|
InterfacesModel {
|
||||||
|
id: interfacesModel
|
||||||
|
deviceManager: engine.deviceManager
|
||||||
|
shownInterfaces: app.supportedInterfaces
|
||||||
|
onlyConfiguredDevices: false
|
||||||
|
showUncategorized: false
|
||||||
|
}
|
||||||
|
model: ListModel {
|
||||||
|
id: typeFilterModel
|
||||||
|
ListElement { interfaceName: ""; displayName: qsTr("All") }
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
for (var i = 0; i < interfacesModel.count; i++) {
|
||||||
|
append({interfaceName: interfacesModel.get(i), displayName: app.interfaceToString(interfacesModel.get(i))});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GroupedListView {
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
top: filterPane.bottom
|
||||||
|
right: parent.right
|
||||||
|
bottom: parent.bottom
|
||||||
|
}
|
||||||
|
|
||||||
model: DeviceClassesProxy {
|
model: DeviceClassesProxy {
|
||||||
id: deviceClassesProxy
|
id: deviceClassesProxy
|
||||||
vendorId: d.vendorId ? d.vendorId : ""
|
vendorId: vendorsFilterModel.get(vendorFilterComboBox.currentIndex).vendorId
|
||||||
deviceClasses: engine.deviceManager.deviceClasses
|
deviceClasses: engine.deviceManager.deviceClasses
|
||||||
|
filterInterface: typeFilterModel.get(typeFilterComboBox.currentIndex).interfaceName
|
||||||
|
groupByInterface: true
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate: MeaListItemDelegate {
|
delegate: MeaListItemDelegate {
|
||||||
id: deviceClassDelegate
|
id: deviceClassDelegate
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: model.displayName
|
text: model.displayName
|
||||||
|
subText: engine.deviceManager.vendors.getVendor(model.vendorId).displayName
|
||||||
iconName: app.interfacesToIcon(deviceClass.interfaces)
|
iconName: app.interfacesToIcon(deviceClass.interfaces)
|
||||||
|
prominentSubText: false
|
||||||
|
wrapTexts: false
|
||||||
|
|
||||||
property var deviceClass: deviceClassesProxy.get(index)
|
property var deviceClass: deviceClassesProxy.get(index)
|
||||||
|
|
||||||
@ -219,23 +305,46 @@ Page {
|
|||||||
|
|
||||||
property var deviceClass: null
|
property var deviceClass: null
|
||||||
|
|
||||||
ListView {
|
ColumnLayout {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
model: discovery
|
|
||||||
delegate: MeaListItemDelegate {
|
ListView {
|
||||||
width: parent.width
|
Layout.fillWidth: true
|
||||||
height: app.delegateHeight
|
Layout.fillHeight: true
|
||||||
text: model.name
|
model: discovery
|
||||||
subText: model.description
|
delegate: MeaListItemDelegate {
|
||||||
iconName: app.interfacesToIcon(discoveryView.deviceClass.interfaces)
|
width: parent.width
|
||||||
onClicked: {
|
height: app.delegateHeight
|
||||||
d.deviceDescriptor = discovery.get(index);
|
text: model.name
|
||||||
d.deviceName = model.name;
|
subText: model.description
|
||||||
internalPageStack.push(paramsPage)
|
iconName: app.interfacesToIcon(discoveryView.deviceClass.interfaces)
|
||||||
|
onClicked: {
|
||||||
|
d.deviceDescriptor = discovery.get(index);
|
||||||
|
d.deviceName = model.name;
|
||||||
|
internalPageStack.push(paramsPage)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Button {
|
||||||
|
id: retryButton
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins
|
||||||
|
text: qsTr("Search again")
|
||||||
|
onClicked: discovery.discoverDevices(d.deviceClass.id, d.discoveryParams)
|
||||||
|
visible: !discovery.busy && discovery.count > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
id: manualAddButton
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins; Layout.bottomMargin: app.margins
|
||||||
|
visible: d.deviceClass.createMethods.indexOf("CreateMethodUser") >= 0
|
||||||
|
text: qsTr("Add thing manually")
|
||||||
|
onClicked: internalPageStack.push(paramsPage)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
width: parent.width - app.margins * 2
|
width: parent.width - app.margins * 2
|
||||||
@ -249,7 +358,6 @@ Page {
|
|||||||
}
|
}
|
||||||
BusyIndicator {
|
BusyIndicator {
|
||||||
running: visible
|
running: visible
|
||||||
onRunningChanged: print("********* running changed", running)
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
15
nymea-app/ui/components/GroupedListView.qml
Normal file
15
nymea-app/ui/components/GroupedListView.qml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import QtQuick 2.9
|
||||||
|
import QtQuick.Controls 2.1
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
|
||||||
|
ScrollBar.vertical: ScrollBar {}
|
||||||
|
|
||||||
|
clip: true
|
||||||
|
section.property: "baseInterface"
|
||||||
|
section.criteria: ViewSection.FullString
|
||||||
|
section.delegate: ListSectionHeader {
|
||||||
|
text: app.interfaceToString(section)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,8 +0,0 @@
|
|||||||
import QtQuick 2.0
|
|
||||||
|
|
||||||
Item {
|
|
||||||
property ListModel eventTemplateModel: ListModel {
|
|
||||||
ListElement { interfaceName: "battery"; stateName: "batteryLevel"; stateDisplayName: qsTr("Battery level"); eventDisplayName: qsTr("Battery level changed") }
|
|
||||||
ListElement { interfaceName: "battery"; stateName: "batteryCritical"; stateDisplayName: qsTr("Battery critical"); eventDisplayName: qsTr("Battery critical changed") }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -64,16 +64,11 @@ Page {
|
|||||||
ThinDivider { visible: root.allowSelectAny }
|
ThinDivider { visible: root.allowSelectAny }
|
||||||
|
|
||||||
|
|
||||||
ListView {
|
GroupedListView {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
model: root.selectInterface ? interfacesProxy : devicesProxy
|
model: root.selectInterface ? interfacesProxy : devicesProxy
|
||||||
clip: true
|
clip: true
|
||||||
section.property: "baseInterface"
|
|
||||||
section.criteria: ViewSection.FullString
|
|
||||||
section.delegate: ListSectionHeader {
|
|
||||||
text: app.interfaceToString(section)
|
|
||||||
}
|
|
||||||
delegate: MeaListItemDelegate {
|
delegate: MeaListItemDelegate {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: root.selectInterface ? model.displayName : model.name
|
text: root.selectInterface ? model.displayName : model.name
|
||||||
|
|||||||
Reference in New Issue
Block a user