218 lines
6.1 KiB
C++
218 lines
6.1 KiB
C++
#include "devicemodel.h"
|
|
#include "telldusgui.h"
|
|
#include <telldus-core.h>
|
|
#include <QQueue>
|
|
#include <QIcon>
|
|
#include <math.h>
|
|
#include <QThread>
|
|
#include <QDebug>
|
|
|
|
#ifdef _WINDOWS
|
|
inline double round(double x) {
|
|
return floor(x + 0.5);
|
|
}
|
|
#endif
|
|
|
|
const int SUPPORTED_METHODS = TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_BELL | TELLSTICK_DIM | TELLSTICK_LEARN | TELLSTICK_EXECUTE | TELLSTICK_UP | TELLSTICK_DOWN | TELLSTICK_STOP;
|
|
|
|
|
|
DeviceModel::DeviceModel(QObject *parent)
|
|
:QAbstractTableModel(parent)
|
|
{
|
|
connect(this, SIGNAL(deviceChange(int,int,int)), this, SLOT(deviceChanged(int,int,int)), Qt::QueuedConnection);
|
|
int numberOfDevices = tdGetNumberOfDevices();
|
|
errorNo = 0;
|
|
if (numberOfDevices < 0) { //Error
|
|
errorNo = numberOfDevices;
|
|
}
|
|
for( int i = 0; i < numberOfDevices; ++i ) {
|
|
int id = tdGetDeviceId(i);
|
|
Device *device = new Device(id, SUPPORTED_METHODS, this);
|
|
connect(device, SIGNAL(showMessage(QString,QString,QString)), this, SIGNAL(showMessage(QString,QString,QString)));
|
|
devices.append(device);
|
|
connect(device, SIGNAL(stateChanged(int)), this, SLOT(deviceStateChanged(int)), Qt::QueuedConnection);
|
|
connect(device, SIGNAL(nameChanged(int,QString)), this, SLOT(nameChanged(int,QString)), Qt::QueuedConnection);
|
|
}
|
|
|
|
deviceChangeCallbackId = tdRegisterDeviceChangeEvent( reinterpret_cast<TDDeviceChangeEvent>(&DeviceModel::deviceChangeEvent), this);
|
|
}
|
|
|
|
|
|
DeviceModel::~DeviceModel()
|
|
{
|
|
tdUnregisterCallback(deviceChangeCallbackId);
|
|
}
|
|
|
|
int DeviceModel::rowCount(const QModelIndex &) const {
|
|
return devices.size();
|
|
}
|
|
|
|
int DeviceModel::columnCount(const QModelIndex &) const {
|
|
return 3;
|
|
}
|
|
|
|
QVariant DeviceModel::data(const QModelIndex &index, int role) const {
|
|
if (index.column() > 2) {
|
|
return QVariant();
|
|
}
|
|
|
|
if (index.row() >= devices.size()) {
|
|
return QVariant();
|
|
}
|
|
|
|
|
|
if (index.column() == 0) {
|
|
if (role == Qt::DisplayRole) {
|
|
Device *device = devices[index.row()];
|
|
switch( device->lastSentCommand() ) {
|
|
case TELLSTICK_TURNON:
|
|
return tr("on");
|
|
case TELLSTICK_TURNOFF:
|
|
return tr("off");
|
|
case TELLSTICK_UP:
|
|
return tr("up");
|
|
case TELLSTICK_DOWN:
|
|
return tr("down");
|
|
case TELLSTICK_STOP:
|
|
return tr("stopped");
|
|
case TELLSTICK_DIM:
|
|
int value = (int)round(device->lastSentValue().toFloat()/255*100);
|
|
return tr("%1%").arg(value);
|
|
}
|
|
return tr("unknown %1").arg(device->lastSentCommand());
|
|
} else if (role == Qt::DecorationRole) {
|
|
Device *device = devices[index.row()];
|
|
int lastSentCommand = device->lastSentCommand();
|
|
return QIcon( QString(":/images/state_%1.png").arg(lastSentCommand) );
|
|
} else if (role == Qt::TextAlignmentRole) {
|
|
return Qt::AlignCenter;
|
|
}
|
|
} else if (index.column() == 1) {
|
|
if (role == Qt::DisplayRole) {
|
|
return devices[index.row()]->name();
|
|
}
|
|
// } else if (index.column() == 2) {
|
|
// if (role == Qt::DisplayRole) {
|
|
// return devices[index.row()]->methods();
|
|
// }
|
|
}
|
|
|
|
return QVariant();
|
|
}
|
|
|
|
QVariant DeviceModel::headerData ( int section, Qt::Orientation orientation, int role ) const {
|
|
if (orientation != Qt::Horizontal) {
|
|
return QVariant();
|
|
}
|
|
|
|
if (role != Qt::DisplayRole) {
|
|
return QVariant();
|
|
}
|
|
|
|
switch (section) {
|
|
case 0:
|
|
return tr("State");
|
|
case 1:
|
|
return tr("Device name");
|
|
case 2:
|
|
return tr("Action");
|
|
}
|
|
|
|
return QVariant();
|
|
}
|
|
|
|
bool DeviceModel::haveError() const {
|
|
return errorNo != 0;
|
|
}
|
|
|
|
QString DeviceModel::errorString() const {
|
|
char *error = tdGetErrorString(errorNo);
|
|
QString errorStr = QString::fromUtf8( error );
|
|
tdReleaseString(error);
|
|
return errorStr;
|
|
}
|
|
|
|
|
|
Device *DeviceModel::device( const QModelIndex &index ) {
|
|
if (index.row() >= devices.size()) {
|
|
return 0;
|
|
}
|
|
return devices[index.row()];
|
|
}
|
|
|
|
int DeviceModel::deviceId( const QModelIndex &index ) {
|
|
if (index.row() >= devices.size()) {
|
|
return 0;
|
|
}
|
|
return devices[index.row()]->id();
|
|
}
|
|
|
|
void DeviceModel::deviceStateChanged( int deviceId ) {
|
|
int row = rowForId(deviceId);
|
|
if (row >= 0) {
|
|
triggerCellUpdate(row, 0);
|
|
}
|
|
}
|
|
|
|
void DeviceModel::deviceChanged( int deviceId, int eventType, int changeType ) {
|
|
if (eventType == TELLSTICK_DEVICE_ADDED) {
|
|
int deviceCount = devices.size();
|
|
beginInsertRows( QModelIndex(), deviceCount, deviceCount );
|
|
Device *device = new Device(deviceId, SUPPORTED_METHODS);
|
|
//We are not running in the DeviceModel-thread here. Move the device to the correct thread
|
|
device->moveToThread(this->thread());
|
|
device->setParent(this);
|
|
connect(device, SIGNAL(showMessage(QString,QString,QString)), this, SIGNAL(showMessage(QString,QString,QString)));
|
|
devices.append(device);
|
|
connect(device, SIGNAL(stateChanged(int)), this, SLOT(deviceStateChanged(int)));
|
|
connect(device, SIGNAL(nameChanged(int,QString)), this, SLOT(nameChanged(int,QString)));
|
|
endInsertRows();
|
|
|
|
} else if (eventType == TELLSTICK_DEVICE_REMOVED) {
|
|
int row = rowForId(deviceId);
|
|
if (row >= 0) {
|
|
beginRemoveRows( QModelIndex(), row, row );
|
|
Device *d = devices.takeAt(row);
|
|
delete d;
|
|
endRemoveRows();
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void DeviceModel::nameChanged(int deviceId, const QString &) {
|
|
int row = rowForId(deviceId);
|
|
if (row >= 0) {
|
|
triggerCellUpdate(row, 1);
|
|
}
|
|
}
|
|
|
|
void DeviceModel::triggerCellUpdate(int row, int column) {
|
|
QModelIndex index = this->index(row, column);
|
|
emit dataChanged( index, index );
|
|
}
|
|
|
|
int DeviceModel::rowForId( int deviceId ) const {
|
|
for (int i = 0; i < devices.size(); ++i) {
|
|
if (devices.at(i)->id() == deviceId) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
void WINAPI DeviceModel::deviceChangeEvent(int deviceId, int eventId, int changeType, int, void *context) {
|
|
DeviceModel *model = reinterpret_cast<DeviceModel *>(context);
|
|
if (!model) {
|
|
return;
|
|
}
|
|
emit model->deviceChange(deviceId, eventId, changeType);
|
|
}
|
|
|
|
/*void DeviceModel::connectDeviceSignals( Device *device ) const {
|
|
connect(device, SIGNAL(showMessage(const QString &, const QString &, const QString &)), this, SIGNAL(showMessage(const QString &, const QString &, const QString &)));
|
|
connect(device, SIGNAL(eventTriggered(const QString &, const QString &)), this, SIGNAL(eventTriggered(const QString &, const QString &)));
|
|
connect(device, SIGNAL(stateChanged(int, int)), this, SLOT(deviceStateChanged(int,int)));
|
|
connect(device, SIGNAL(deviceChanged(int,int,int)), this, SLOT(deviceChanged(int,int,int)));
|
|
}*/
|