230 lines
7.1 KiB
C++
230 lines
7.1 KiB
C++
#include "checkqueuetablemodel.h"
|
|
|
|
#include <QMimeData>
|
|
#include <QIODevice>
|
|
#include <QDateTime>
|
|
#include <QVector>
|
|
CheckQueueTableModel::CheckQueueTableModel(std::vector<Check> *checks, QObject *parent)
|
|
: checks(checks), QAbstractTableModel{parent}
|
|
{}
|
|
|
|
int CheckQueueTableModel::rowCount(const QModelIndex &parent) const { return checks->size(); }
|
|
int CheckQueueTableModel::columnCount(const QModelIndex &parent) const { return 2; }
|
|
|
|
QVariant CheckQueueTableModel::data(const QModelIndex &index, int role) const {
|
|
if (!index.isValid() || index.row() >= checks->size())
|
|
return QVariant();
|
|
if (role != Qt::DisplayRole) return QVariant();
|
|
Check& c = checks->at(index.row());
|
|
switch (index.column()) {
|
|
case 0:
|
|
return QVariant::fromValue(QString::fromStdString(c.get_date()));
|
|
break;
|
|
case 1:
|
|
return QVariant::fromValue(c.get_total());
|
|
break;
|
|
}
|
|
|
|
return QVariant();
|
|
}
|
|
|
|
bool CheckQueueTableModel::setData(const QModelIndex &index, const QVariant &value, int role) {
|
|
if (role == Qt::EditRole) {
|
|
if (!index.isValid() || index.row() >= checks->size())
|
|
return false;
|
|
unsigned int row = index.row();
|
|
Check &c = checks->at(row);
|
|
switch (index.column()) {
|
|
case 0:
|
|
c.set_date(value.value<std::string>());
|
|
break;
|
|
case 1:
|
|
c.set_total(value.value<double>());
|
|
break;
|
|
emit dataChanged(index, index, {role});
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
QVariant CheckQueueTableModel::headerData(int section, Qt::Orientation orientation, int role) const {
|
|
if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
|
|
switch (section) {
|
|
case 0:
|
|
return tr("Date&Time");
|
|
case 1:
|
|
return tr("Total");
|
|
}
|
|
} else if (role == Qt::DisplayRole && orientation == Qt::Vertical) {
|
|
return section + 1;
|
|
}
|
|
return QVariant();
|
|
}
|
|
|
|
Qt::ItemFlags CheckQueueTableModel::flags(const QModelIndex &index) const {
|
|
auto flags = QAbstractItemModel::flags(index);
|
|
|
|
if (index.isValid())
|
|
flags |= Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled;
|
|
else
|
|
flags |= Qt::ItemIsDropEnabled;
|
|
|
|
return flags;
|
|
}
|
|
|
|
Qt::DropActions CheckQueueTableModel::supportedDropActions() const {
|
|
return Qt::DropActions() | Qt::MoveAction;
|
|
}
|
|
|
|
bool CheckQueueTableModel::insertRows(int position, int rows, const QModelIndex &index) {
|
|
beginInsertRows(QModelIndex(), position, position+rows-1);
|
|
for (int i = 0; i < rows; ++i)
|
|
checks->emplace(checks->begin() + position, Check());
|
|
|
|
endInsertRows();
|
|
return true;
|
|
}
|
|
|
|
bool CheckQueueTableModel::removeRows(int position, int rows, const QModelIndex &index) {
|
|
beginRemoveRows(QModelIndex(), position, position+rows-1);
|
|
|
|
for (int row = 0; row < rows; ++row)
|
|
checks->erase(std::next(checks->begin(), position));
|
|
|
|
endRemoveRows();
|
|
return true;
|
|
}
|
|
|
|
QStringList CheckQueueTableModel::mimeTypes() const {
|
|
QStringList types;
|
|
types << CheckQueueTableModel::MimeType;
|
|
return types;
|
|
}
|
|
|
|
bool CheckQueueTableModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int, const QModelIndex &) {
|
|
if (action != Qt::MoveAction || !data->hasFormat(CheckQueueTableModel::MimeType))
|
|
return false;
|
|
if (row > checks->size()) return false;
|
|
return true;
|
|
}
|
|
|
|
QMimeData* CheckQueueTableModel::mimeData(const QModelIndexList &indexes) const {
|
|
QMimeData* mimeData = new QMimeData;
|
|
QByteArray encodedData;
|
|
|
|
QDataStream stream(&encodedData, QIODevice::WriteOnly);
|
|
|
|
for (const QModelIndex &i : indexes) {
|
|
if (i.isValid() && i.column() == 0) {
|
|
Check &c = checks->at(i.row());
|
|
QString date = QString::fromStdString(c.get_date()),
|
|
fn = QString::fromStdString(c.get_fn()),
|
|
fd = QString::fromStdString(c.get_fd()),
|
|
fi = QString::fromStdString(c.get_fi());
|
|
double total = c.get_total();
|
|
OperationType type = c.get_operationType();
|
|
std::vector<Goods> goods = c.get_goods();
|
|
|
|
stream << date << total << type << fn << fd << fi << goods;
|
|
}
|
|
}
|
|
mimeData->setData(CheckQueueTableModel::MimeType, encodedData);
|
|
return mimeData;
|
|
}
|
|
|
|
bool CheckQueueTableModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) {
|
|
if (!canDropMimeData(data, action, row, column, parent)) return false;
|
|
if (action == Qt::IgnoreAction) return true;
|
|
else if (action != Qt::MoveAction) return false;
|
|
if (row > checks->size()) return false;
|
|
|
|
QByteArray encodedData = data->data(CheckQueueTableModel::MimeType);
|
|
QDataStream stream(&encodedData, QIODevice::ReadOnly);
|
|
std::vector<Check> newItems;
|
|
int rows = 0;
|
|
|
|
while (!stream.atEnd()) {
|
|
QString date, fn, fd, fi;
|
|
double total;
|
|
OperationType type;
|
|
std::vector<Goods> goods;
|
|
|
|
stream >> date >> total >> type >> fn >> fd >> fi >> goods;
|
|
Check c = Check(
|
|
date.toStdString(),
|
|
total,
|
|
type,
|
|
fn.toStdString(),
|
|
fd.toStdString(),
|
|
fi.toStdString(),
|
|
goods
|
|
);
|
|
newItems.push_back(c);
|
|
++rows;
|
|
}
|
|
|
|
insertRows(row, rows, QModelIndex());
|
|
|
|
for (Check item : newItems) {
|
|
// (*checks)[row] = std::move(item);
|
|
Check &c = checks->at(row);
|
|
c.set_date(item.get_date());
|
|
c.set_total(item.get_total());
|
|
c.set_fn(item.get_fn());
|
|
c.set_fd(item.get_fd());
|
|
c.set_fi(item.get_fi());
|
|
c.set_operation_type(item.get_operationType());
|
|
for (Goods &g : item.get_goods()) {
|
|
c.add_goods(g);
|
|
}
|
|
emit dataChanged(index(row, 0), index(row, 1));
|
|
row++;
|
|
}
|
|
|
|
|
|
return true;
|
|
}
|
|
|
|
void CheckQueueTableModel::sort(int column, Qt::SortOrder order) {
|
|
beginResetModel();
|
|
switch (column) {
|
|
case 0:
|
|
std::sort(checks->begin(), checks->end(),
|
|
[&](const Check& a, const Check& b) {
|
|
if (order == Qt::AscendingOrder) {
|
|
return compare(a, b, column);
|
|
} else {
|
|
return !compare(a, b, column);
|
|
}
|
|
});
|
|
break;
|
|
case 1:
|
|
std::sort(checks->begin(), checks->end(),
|
|
[&](const Check& a, const Check& b) {
|
|
if (order == Qt::AscendingOrder) {
|
|
return compare(a, b, column);
|
|
} else {
|
|
return !compare(a, b, column);
|
|
}
|
|
});
|
|
}
|
|
|
|
endResetModel();
|
|
}
|
|
|
|
bool CheckQueueTableModel::compare(const Check &check_a, const Check &check_b, int column) {
|
|
switch (column) {
|
|
case 0:
|
|
return
|
|
QDateTime::fromString(QString::fromStdString(((Check &)check_a).get_date()), "yyyyMMddThhmm")
|
|
>
|
|
QDateTime::fromString(QString::fromStdString(((Check &)check_b).get_date()), "yyyyMMddThhmm");
|
|
break;
|
|
case 1:
|
|
return ((Check &)check_a).get_total() > ((Check &)check_b).get_total();
|
|
break;
|
|
default: return false;
|
|
}
|
|
}
|