218 lines
4.6 KiB
C++
Executable File
218 lines
4.6 KiB
C++
Executable File
#include "DataModel.h"
|
|
|
|
#include <QDebug>
|
|
#include <QColor>
|
|
#include <QDateTime>
|
|
#include <QMetaEnum>
|
|
#include <QMetaObject>
|
|
#include <QMetaType>
|
|
|
|
//#define WAIT_FOR_IDLE while (!m_idle) { QThread::msleep(50); } (void)m_idle
|
|
|
|
|
|
DataModel::DataModel(QObject *parent) // [M]VC
|
|
: QAbstractTableModel(parent)
|
|
, m_idle(true)
|
|
{
|
|
resetFlags();
|
|
}
|
|
|
|
|
|
//void DataModel::fillModel(const HeaderList &headerList, const DataList &dataList)
|
|
//{
|
|
// beginResetModel();
|
|
|
|
// m_headerList = headerList;
|
|
// m_dataList = dataList;
|
|
|
|
// endResetModel();
|
|
//}
|
|
|
|
|
|
void DataModel::dataListReserve(const int size)
|
|
{
|
|
m_newDataList.reserve(size);
|
|
}
|
|
|
|
|
|
void DataModel::addLine(const Data& data)
|
|
{
|
|
m_newDataList.append(data);
|
|
}
|
|
|
|
|
|
void DataModel::addColumn(const QString& columnName, QVariant::Type type)
|
|
{
|
|
// QPair<QString,QVariant::Type> pair;
|
|
// pair.first = columnName;
|
|
// pair.second = type;
|
|
m_newHeaderList.append(QPair<QString,QVariant::Type>(columnName, type));
|
|
}
|
|
|
|
|
|
void DataModel::slotSwapLists() // for threading..
|
|
{
|
|
m_dataList = m_newDataList;
|
|
m_headerList = m_newHeaderList;
|
|
|
|
m_newDataList.clear();
|
|
m_newHeaderList.clear();
|
|
|
|
beginResetModel();
|
|
endResetModel();
|
|
}
|
|
|
|
|
|
void DataModel::setTableName(const QString &tableName)
|
|
{
|
|
m_tableName = tableName;
|
|
setEditable(!m_tableName.isEmpty()); // editable items depend on wether it's a custom query, or a table list query
|
|
}
|
|
|
|
|
|
QString DataModel::getTableName() const
|
|
{
|
|
return m_tableName;
|
|
}
|
|
|
|
|
|
int DataModel::rowCount(const QModelIndex &parent) const
|
|
{
|
|
return parent.isValid() ? 0 : m_dataList.count();
|
|
}
|
|
|
|
|
|
int DataModel::columnCount(const QModelIndex &parent) const
|
|
{
|
|
return parent.isValid() ? 0 : m_headerList.count();
|
|
}
|
|
|
|
|
|
QVariant DataModel::data(const QModelIndex &index, int role) const
|
|
{
|
|
if (index.row() >= m_dataList.count())
|
|
{
|
|
//qWarning() << "threading problems.. #1";
|
|
return QVariant();
|
|
}
|
|
|
|
const Data& row = m_dataList.at(index.row());
|
|
if (index.column() >= row.count())
|
|
{
|
|
//qWarning() << "threading problems.. #2";
|
|
return QVariant();
|
|
}
|
|
|
|
const QVariant& element = row.at(index.column());
|
|
|
|
switch (role)
|
|
{
|
|
case Qt::EditRole:
|
|
case Qt::DisplayRole:
|
|
return element;
|
|
|
|
case Qt::BackgroundRole:
|
|
if (element.isNull())
|
|
return QColor::fromRgb(255, 255, 215);
|
|
return QVariant();
|
|
|
|
case Qt::ToolTipRole:
|
|
if ((element.type() == QVariant::ULongLong || element.type() == QVariant::LongLong)
|
|
&& element.toLongLong() > 1000000000)
|
|
return QDateTime::fromMSecsSinceEpoch(element.toLongLong()).toString(QStringLiteral("dd.MM.yyyy hh:mm:ss.zzz"));
|
|
|
|
break;
|
|
}
|
|
|
|
return QVariant();
|
|
}
|
|
|
|
|
|
QVariant DataModel::headerData(int section, Qt::Orientation orientation, int role) const
|
|
{
|
|
if (orientation == Qt::Horizontal && section >= 0 && section < m_headerList.size())
|
|
{
|
|
switch (role)
|
|
{
|
|
case Qt::DisplayRole:
|
|
return m_headerList.at(section).first;
|
|
case Qt::ToolTipRole:
|
|
int type = m_headerList.at(section).second;
|
|
return QString::fromUtf8(QMetaType::typeName(type));
|
|
}
|
|
}
|
|
|
|
return QAbstractTableModel::headerData(section, orientation, role);
|
|
}
|
|
|
|
|
|
void DataModel::setEditable(bool editable)
|
|
{
|
|
resetFlags();
|
|
|
|
if (editable)
|
|
m_flags |= Qt::ItemIsEditable;
|
|
}
|
|
|
|
|
|
const HeaderList& DataModel::getHeaderList() const
|
|
{
|
|
return m_headerList;
|
|
}
|
|
|
|
|
|
void DataModel::resetFlags()
|
|
{
|
|
m_flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
|
|
}
|
|
|
|
|
|
Qt::ItemFlags DataModel::flags(const QModelIndex &index) const
|
|
{
|
|
Q_UNUSED(index);
|
|
|
|
return m_flags;
|
|
}
|
|
|
|
|
|
void DataModel::slotSetData(const QModelIndex &index, const QVariant &value)
|
|
{
|
|
Data row = m_dataList.at(index.row()); // get row from data list
|
|
row.replace(index.column(), value); // replace column in row
|
|
m_dataList.replace(index.row(), row); // replace row in data list
|
|
|
|
emit dataChanged(index, index); // tell the view that data has changed and redraw/reget data
|
|
}
|
|
|
|
bool DataModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
|
{
|
|
if (role != Qt::EditRole)
|
|
return true;
|
|
|
|
// DataModel* => model to write value to on success
|
|
// QModelIndex => row&col of value to write
|
|
// QVariant => value to write
|
|
emit signalSetData(this, index, value);
|
|
|
|
return false; // ALWAYS! as we need to wait for a result (which is async)
|
|
}
|
|
|
|
|
|
void DataModel::deleteLines(const QList<QModelIndex> &affectedRowsList)
|
|
{
|
|
if (affectedRowsList.isEmpty())
|
|
{
|
|
//qWarning() << "DataModel::deleteLines: !affectedRowsList->count()";
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < affectedRowsList.count(); i++)
|
|
{
|
|
const QModelIndex &idx = affectedRowsList.at(i);
|
|
|
|
beginRemoveRows(QModelIndex() /* FIXME: ??? */, idx.row(), idx.row());
|
|
m_dataList.removeAt(idx.row() /* TODO: checks ?? */);
|
|
endRemoveRows();
|
|
}
|
|
}
|