#include "checkqueuetablemodel.h" #include #include #include #include CheckQueueTableModel::CheckQueueTableModel(std::vector *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()); break; case 1: c.set_total(value.value()); 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 = 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 newItems; int rows = 0; while (!stream.atEnd()) { QString date, fn, fd, fi; double total; OperationType type; std::vector 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; } }