158 lines
4.0 KiB
C++
158 lines
4.0 KiB
C++
#include "widgetmodel.h"
|
|
#include "qmetaobject.h"
|
|
|
|
WidgetModel::WidgetModel(QObject *parent)
|
|
: QAbstractItemModel(parent)
|
|
{
|
|
rescanPorts();
|
|
}
|
|
|
|
|
|
WidgetModel::~WidgetModel() {
|
|
for(auto &wdgt: widgets_)
|
|
disconnect(wdgt.get(), nullptr, this, nullptr);
|
|
}
|
|
|
|
|
|
QVariant WidgetModel::headerData(int section, Qt::Orientation orientation, int role) const
|
|
{
|
|
if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
|
|
switch (static_cast<Column>(section)) {
|
|
case PortName:
|
|
return tr("Port");
|
|
case Manufacturer:
|
|
return tr("Manufacturer");
|
|
case Description:
|
|
return tr("Description");
|
|
case SerialNumber:
|
|
return tr("Serial");
|
|
case FirmwareVersion:
|
|
return tr("Firmware");
|
|
case OperatingMode:
|
|
return tr("Mode");
|
|
default:
|
|
return QVariant();
|
|
}
|
|
}
|
|
return QVariant();
|
|
}
|
|
|
|
|
|
QModelIndex WidgetModel::index(int row, int column, const QModelIndex &parent) const
|
|
{
|
|
if (parent.isValid() || row >= widgets_.size())
|
|
return QModelIndex();
|
|
|
|
return createIndex(row, column, widgets_.at(row).get());
|
|
}
|
|
|
|
|
|
QModelIndex WidgetModel::parent(const QModelIndex &index) const
|
|
{
|
|
Q_UNUSED(index)
|
|
return QModelIndex();
|
|
}
|
|
|
|
|
|
int WidgetModel::rowCount(const QModelIndex &parent) const
|
|
{
|
|
if (parent.isValid())
|
|
return 0;
|
|
|
|
return widgets_.size();
|
|
}
|
|
|
|
int WidgetModel::columnCount(const QModelIndex &parent) const
|
|
{
|
|
Q_UNUSED(parent);
|
|
return QMetaEnum::fromType<Column>().keyCount();
|
|
}
|
|
|
|
|
|
QVariant WidgetModel::data(const QModelIndex &index, int role) const
|
|
{
|
|
if (!checkIndex(index, CheckIndexOption::IndexIsValid))
|
|
return QVariant();
|
|
|
|
switch (role) {
|
|
case Qt::DisplayRole:
|
|
{
|
|
auto wdgt = widgets_.at(index.row());
|
|
auto info = wdgt->portInfo();
|
|
switch (static_cast<Column>(index.column()))
|
|
{
|
|
case PortName:
|
|
return info.portName();
|
|
case Manufacturer:
|
|
return info.manufacturer();
|
|
case Description:
|
|
return info.description();
|
|
case SerialNumber:
|
|
return wdgt->serialNumber();
|
|
case FirmwareVersion:
|
|
return QString::number(wdgt->firmwareVersion() >> 8)
|
|
+ "."
|
|
+ QString::number(wdgt->firmwareVersion() & 0xff);
|
|
case OperatingMode:
|
|
switch (wdgt->deviceClass()) {
|
|
case DMX::CONTROLLER:
|
|
return tr("Controller");
|
|
case DMX::RECEIVER:
|
|
return tr("Receiver");
|
|
case DMX::RESPONDER:
|
|
return tr("Responder");
|
|
default:
|
|
return QVariant();
|
|
}
|
|
default:
|
|
return QVariant();
|
|
}
|
|
}
|
|
case Qt::TextAlignmentRole:
|
|
switch (static_cast<Column>(index.column())) {
|
|
case SerialNumber:
|
|
case FirmwareVersion:
|
|
return Qt::AlignCenter;
|
|
default:
|
|
return QVariant();
|
|
}
|
|
case Qt::EditRole:
|
|
return QVariant::fromValue(widgets_.at(index.row()));
|
|
default:
|
|
return QVariant();
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief WidgetModel::rescanPorts
|
|
*/
|
|
void WidgetModel::rescanPorts()
|
|
{
|
|
// remove disconnected widgets
|
|
for(qsizetype i = 0; i < widgets_.size();)
|
|
if (!widgets_.at(i)->isConnected())
|
|
{
|
|
beginRemoveRows(QModelIndex(), i, i+1);
|
|
disconnect(widgets_.at(i).get(), nullptr, this, nullptr);
|
|
widgets_.remove(i);
|
|
endRemoveRows();
|
|
}
|
|
else
|
|
i++;
|
|
|
|
// look for new widgets
|
|
auto newWidgets = DmxWidget::availableWidgets();
|
|
if (!newWidgets.isEmpty())
|
|
{
|
|
beginInsertRows(QModelIndex(), widgets_.size(), widgets_.size()+newWidgets.size()-1);
|
|
widgets_.append(newWidgets);
|
|
endInsertRows();
|
|
for(auto &wdgt: newWidgets)
|
|
connect(wdgt.get(), &DmxWidget::connectedChanged, this, [this](){
|
|
// refresh the whole view. Could be optimized by looking for this widget in the rows.
|
|
emit dataChanged(createIndex(0,0), createIndex(rowCount(),columnCount()));
|
|
});
|
|
}
|
|
}
|