250 lines
5.0 KiB
C++
250 lines
5.0 KiB
C++
#include "universemodel.h"
|
|
|
|
#include <QBrush>
|
|
#include <QFont>
|
|
#include <QChar>
|
|
#include <QMetaEnum>
|
|
|
|
/**
|
|
* @brief UniverseModel::UniverseModel
|
|
* @param parent
|
|
*/
|
|
UniverseModel::UniverseModel(QObject *parent)
|
|
: QAbstractTableModel(parent)
|
|
, universe_(nullptr)
|
|
, data_mode_(Decimal)
|
|
{
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief UniverseModel::headerData
|
|
* @param section
|
|
* @param orientation
|
|
* @param role
|
|
* @return
|
|
*/
|
|
QVariant UniverseModel::headerData(int section, Qt::Orientation orientation, int role) const
|
|
{
|
|
switch (role)
|
|
{
|
|
case Qt::DisplayRole:
|
|
switch (orientation)
|
|
{
|
|
case Qt::Horizontal:
|
|
return section + 1;
|
|
case Qt::Vertical:
|
|
return section * 10;
|
|
}
|
|
default:
|
|
return QVariant();
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief UniverseModel::rowCount
|
|
* @param parent
|
|
* @return
|
|
*/
|
|
int UniverseModel::rowCount(const QModelIndex &parent) const
|
|
{
|
|
if (parent.isValid())
|
|
return 0;
|
|
|
|
return 52;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief UniverseModel::columnCount
|
|
* @param parent
|
|
* @return
|
|
*/
|
|
int UniverseModel::columnCount(const QModelIndex &parent) const
|
|
{
|
|
if (parent.isValid())
|
|
return 0;
|
|
|
|
return 10;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief UniverseModel::data
|
|
* @param index
|
|
* @param role
|
|
* @return
|
|
*/
|
|
QVariant UniverseModel::data(const QModelIndex &index, int role) const
|
|
{
|
|
if (!checkIndex(index, CheckIndexOption::IndexIsValid))
|
|
return QVariant();
|
|
|
|
if (!universe_)
|
|
return QVariant();
|
|
|
|
uint16_t slot = (index.row() * 10) + (index.column() + 1);
|
|
|
|
switch (role) {
|
|
case Qt::DisplayRole:
|
|
{
|
|
if (slot == 0 || slot > 512)
|
|
return QVariant();
|
|
switch (data_mode_)
|
|
{
|
|
case Decimal:
|
|
return universe_->slot(slot);
|
|
case Hex:
|
|
return QString("%1")
|
|
.arg(universe_->slot(slot), 2, 16, QChar('0'))
|
|
.toUpper();
|
|
case Percent:
|
|
return QString("%1%").arg((universe_->slot(slot) / 255.0F) * 100,
|
|
0, 'f', 0, '0');
|
|
}
|
|
return QVariant();
|
|
}
|
|
case Qt::FontRole:
|
|
return QFont("monospace");
|
|
case Qt::TextAlignmentRole:
|
|
return int(Qt::AlignCenter | Qt::AlignVCenter);
|
|
case Qt::ForegroundRole:
|
|
{
|
|
if (slot > universe_->activeSlots() - 1)
|
|
return QBrush(Qt::gray);
|
|
return QVariant();
|
|
}
|
|
default:
|
|
return QVariant();
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief UniverseModel::setData
|
|
* @param index
|
|
* @param value
|
|
* @param role
|
|
* @return
|
|
*/
|
|
bool UniverseModel::setData(const QModelIndex &index, const QVariant &value,
|
|
int role)
|
|
{
|
|
if (!universe_->isEditable())
|
|
return false;
|
|
|
|
if (data(index, role) == value)
|
|
return false;
|
|
|
|
uint16_t slot = (index.row() * 10) + (index.column() + 1);
|
|
uint8_t data;
|
|
|
|
switch (data_mode_)
|
|
{
|
|
case Decimal:
|
|
{
|
|
if (!value.canConvert<uint>())
|
|
return false;
|
|
unsigned int d = value.toUInt();
|
|
if (d > 255)
|
|
return false;
|
|
data = d;
|
|
}
|
|
break;
|
|
case Hex:
|
|
{
|
|
if (!value.canConvert<QString>())
|
|
return false;
|
|
bool ok;
|
|
unsigned int d = value.toString().toInt(&ok, 16);
|
|
if (!ok || d > 255)
|
|
return false;
|
|
data = d;
|
|
}
|
|
break;
|
|
case Percent:
|
|
{
|
|
if (!value.canConvert<double>())
|
|
return false;
|
|
int d = 255 * (value.toDouble() / 100);
|
|
if (d < 0 || d > 255)
|
|
return false;
|
|
data = d;
|
|
}
|
|
break;
|
|
}
|
|
|
|
universe_->setValue(slot, data);
|
|
emit dataChanged(index, index, QVector<int>() << role);
|
|
return true;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief UniverseModel::flags
|
|
* @param index
|
|
* @return
|
|
*/
|
|
Qt::ItemFlags UniverseModel::flags(const QModelIndex &index) const
|
|
{
|
|
if (!checkIndex(index, CheckIndexOption::IndexIsValid))
|
|
return Qt::NoItemFlags;
|
|
|
|
if (!universe_)
|
|
return Qt::NoItemFlags;
|
|
|
|
uint16_t slot = (index.row() * 10) + (index.column() + 1);
|
|
|
|
if (slot == 0 || slot > 512)
|
|
return Qt::NoItemFlags;
|
|
|
|
auto f = QAbstractItemModel::flags(index);
|
|
return universe_->isEditable() ? f | Qt::ItemIsEditable : f;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief UniverseModel::universeRefreshed
|
|
*/
|
|
void UniverseModel::universeRefreshed() {
|
|
emit dataChanged(index(0,0), index(rowCount(), columnCount()));
|
|
emit recievedUpdate(universe_);
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief UniverseModel::setDataMode
|
|
* @param mode
|
|
*/
|
|
void UniverseModel::setDataMode(const QString mode)
|
|
{
|
|
auto metaEnum = QMetaEnum::fromType<data_modes>();
|
|
data_mode_ = static_cast<data_modes>(metaEnum.keyToValue(mode.toLocal8Bit()));
|
|
emit dataChanged(index(0,0), index(rowCount(), columnCount()));
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief UniverseModel::setUniverse
|
|
* @param universe
|
|
*/
|
|
void UniverseModel::setUniverse(QSacnUniverse *universe)
|
|
{
|
|
if (universe_)
|
|
disconnect(universe_, 0, this, 0);
|
|
universe_ = universe;
|
|
connect(universe_, &QSacnUniverse::changed,
|
|
this, &UniverseModel::universeRefreshed);
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief UniverseModel::dataMode
|
|
* @return
|
|
*/
|
|
UniverseModel::data_modes UniverseModel::dataMode()
|
|
{
|
|
return data_mode_;
|
|
}
|