diff --git a/CMakeLists.txt b/CMakeLists.txt
index d502a78..a8572f2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -166,6 +166,7 @@ else()
${PROJECT_SOURCES}
${SOURCES}
widgets/checkqueuetablemodel.h widgets/checkqueuetablemodel.cpp
+ # widgets/checkqueuetableview.h widgets/checkqueuetableview.cpp
)
endif()
diff --git a/mainwindow.cpp b/mainwindow.cpp
index d8aacf0..3cc8176 100644
--- a/mainwindow.cpp
+++ b/mainwindow.cpp
@@ -39,6 +39,8 @@ MainWindow::MainWindow(QWidget *parent)
model = new CheckQueueTableModel(&checks, this);
ui->checkQueueTable->setModel(model);
+ ui->checkQueueTable->viewport()->setAcceptDrops(true);
+ ui->checkQueueTable->setDragDropMode(QAbstractItemView::DragDrop);
// ui->
// connect(this, &MainWindow::deleteCheckFromList, this, &MainWindow::deleteCheckFromListHandler);
@@ -236,15 +238,17 @@ void MainWindow::on_parse_button_clicked() {
// }
void MainWindow::on_add_new_check_button_clicked() {
- Check *new_check = parse_new_check();
+ Check *new_check = new Check();/* parse_new_check();
if (new_check == nullptr) {
return;
- }
+ }*/
+ new_check->set_date("123");
+ new_check->set_total(rand() * 1800);
- checks.push_back(*new_check);
+ // checks.push_back(*new_check);
unsigned int newRowIndex = checks.size();
- model->insertRow(newRowIndex, 1);
+ model->insertRows(newRowIndex, 1);
model->setData(model->index(newRowIndex, 0), QVariant::fromValue(new_check->get_date()));
model->setData(model->index(newRowIndex, 1), QVariant::fromValue(new_check->get_total()));
diff --git a/scenes/mainwindow.ui b/scenes/mainwindow.ui
index 1ff732c..e8a5c61 100644
--- a/scenes/mainwindow.ui
+++ b/scenes/mainwindow.ui
@@ -209,13 +209,13 @@
QAbstractItemView::DragDropMode::InternalMove
- Qt::DropAction::TargetMoveAction
+ Qt::DropAction::MoveAction
true
- QAbstractItemView::SelectionMode::SingleSelection
+ QAbstractItemView::SelectionMode::MultiSelection
QAbstractItemView::SelectionBehavior::SelectRows
diff --git a/translations/en_US.ts b/translations/en_US.ts
index 22025e1..a49bcbd 100644
--- a/translations/en_US.ts
+++ b/translations/en_US.ts
@@ -228,77 +228,77 @@
checks parser
-
+
QR code for binaryeye to connect
QR code for binaryeye to connect
-
+
I've scanned
I've scanned
-
+
Could not start http server. 10 times in a row random port was occupied. Either you should run for a lottery ticket, or the problem is in the program. If the lottery ticket wasn't lucky, please, contact the developer.
Could not start http server. 10 times in a row random port was occupied. Either you should run for a lottery ticket, or the problem is in the program. If the lottery ticket wasn't lucky, please, contact the developer.
-
+
Could not start http server.
Could not start http server.
-
+
Selected image:
Selected image:
-
+
This feature is under development. Wait it to appear in next updates.
This feature is under development. Wait for it to appear in next updates.
-
+
Under development
Under development
-
+
Please, add check(s) to parse
Please, add check(s) to parse
-
+
No checks to parse
No checks to parse
-
+
Captcha was not solved correctly!
Captcha was not solved correctly!
-
+
Captcha is incorrect
Captcha is incorrect
-
+
Internal server error. Please, try again later.
Internal server error. Please, try again later.
-
+
Internal server error
Internal server error
-
+
Check not found. Please, ensure correctness of entered data.
Check not found. Please, ensure correctness of entered data.
-
+
Check was not found
Check was not found
@@ -311,12 +311,12 @@
Error in parsing
-
+
Please, select a picture where QR code that contains info about check is present
Please, select a picture where QR code that contains info about check is present
-
+
Picture was not selected
Picture was not selected
diff --git a/translations/ru_RU.ts b/translations/ru_RU.ts
index d13457b..201f5ea 100644
--- a/translations/ru_RU.ts
+++ b/translations/ru_RU.ts
@@ -224,77 +224,77 @@
Парсер чеков
-
+
QR code for binaryeye to connect
QR код для подключения BinaryEye
-
+
I've scanned
Просканировал
-
+
Could not start http server. 10 times in a row random port was occupied. Either you should run for a lottery ticket, or the problem is in the program. If the lottery ticket wasn't lucky, please, contact the developer.
Не смог поднять HTTP сервер. 10 раз подряд случайно выбранный порт был занят. Либо Вам следует бежать за лоттерейным билетом, или в программе баг. Если лотерейный билет не был выигрышным, пожалуйста, сообщите разработчику.
-
+
Could not start http server.
Не получилось запустить HTTP сервер.
-
+
Selected image:
Выбранное изображение:
-
+
This feature is under development. Wait it to appear in next updates.
-
+
Under development
-
+
Please, add check(s) to parse
-
+
No checks to parse
-
+
Captcha was not solved correctly!
Капча была решена неверно!
-
+
Captcha is incorrect
Капча введена неверно
-
+
Internal server error. Please, try again later.
Внутренняя ошибка сервера. Пожалуйста, попробуйте снова позже.
-
+
Internal server error
Внутренняя ошибка сервера
-
+
Check not found. Please, ensure correctness of entered data.
Чек не найден. Пожалуйста, убедитесь в правильности введённых данных.
-
+
Check was not found
Чек не найден
@@ -307,12 +307,12 @@
Ошибка в парсинге
-
+
Please, select a picture where QR code that contains info about check is present
Пожалуйста, выберете изображение, содержащее QR код с информацией о чеке
-
+
Picture was not selected
Изображение не было выбрано
diff --git a/utils/utils.cpp b/utils/utils.cpp
index b460367..4e342e2 100644
--- a/utils/utils.cpp
+++ b/utils/utils.cpp
@@ -181,9 +181,9 @@ std::vector find_in_html(std::string& html, std::string regex, std
it != end; it++) {
std::wstring found_entry = from_utf8(it->str());
- std::cout << "Found: " << to_utf8(found_entry) << std::endl;
+ // std::cout << "Found: " << to_utf8(found_entry) << std::endl;
std::wstring extracted = substring_from_to(found_entry, from_utf8(html_start), from_utf8(html_end));
- std::cout << "Extracted: " << to_utf8(extracted) << std::endl;
+ // std::cout << "Extracted: " << to_utf8(extracted) << std::endl;
parsed.push_back(extracted);
}
return parsed;
@@ -293,8 +293,8 @@ Check parseOfdRuAnswer(std::string html) {
Check c;
for (int i = 0; i < products.size(); i ++) {
- std::cout << "Adding to check: ";
- std::cout << to_utf8(products[i]) << " " << to_utf8(prices[i]) << " " << to_utf8(net_weights[i]) << " " << to_utf8(amounts[i]) << std::endl;
+ // std::cout << "Adding to check: ";
+ // std::cout << to_utf8(products[i]) << " " << to_utf8(prices[i]) << " " << to_utf8(net_weights[i]) << " " << to_utf8(amounts[i]) << std::endl;
Goods goods(to_utf8(products[i]), std::stod(prices[i]), to_utf8(net_weights[i]), std::stod(amounts[i]));
c.add_goods(goods);
}
diff --git a/widgets/checkqueuetablemodel.cpp b/widgets/checkqueuetablemodel.cpp
index 51a7d91..bac1766 100644
--- a/widgets/checkqueuetablemodel.cpp
+++ b/widgets/checkqueuetablemodel.cpp
@@ -1,6 +1,7 @@
#include "checkqueuetablemodel.h"
-#include
+#include
+#include
CheckQueueTableModel::CheckQueueTableModel(std::vector *checks, QObject *parent)
: checks(checks), QAbstractTableModel{parent}
@@ -10,8 +11,10 @@ int CheckQueueTableModel::rowCount(const QModelIndex &parent) const { return che
int CheckQueueTableModel::columnCount(const QModelIndex &parent) const { return 3; }
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());
+ Check& c = checks->at(index.row());
switch (index.column()) {
case 0:
return QVariant::fromValue(QString::fromStdString(c.get_date()));
@@ -33,24 +36,16 @@ bool CheckQueueTableModel::setData(const QModelIndex &index, const QVariant &val
return false;
unsigned int row = index.row();
switch (index.column()) {
- case 0:
+ case 0: {
checks->at(row).set_date(value.value());
break;
- case 1:
+ } case 1:
checks->at(row).set_total(value.value());
break;
case 2:
// delete Button
break;
}
-
- //for presentation purposes only: build and emit a joined string
- // QString result = "dick";
- // for (int row = 0; row < checks->size(); row++) {
- // for (int col= 0; col < 3; col++)
- // result += m_gridData[row][col] + ' ';
- // }
- // emit editCompleted(result);
return true;
}
return false;
@@ -74,21 +69,100 @@ QVariant CheckQueueTableModel::headerData(int section, Qt::Orientation orientati
}
Qt::ItemFlags CheckQueueTableModel::flags(const QModelIndex &index) const {
- Qt::ItemFlags defaultFlags = QAbstractTableModel::flags(index);
+ auto flags = QAbstractItemModel::flags(index);
if (index.isValid())
- return Qt::ItemIsDragEnabled | defaultFlags;
+ flags |= Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled;
else
- return Qt::ItemIsDropEnabled | defaultFlags;
- // return Qt::ItemIsSelectable | QAbstractTableModel::flags(index);
+ flags |= Qt::ItemIsDropEnabled;
+
+ return flags;
}
-bool CheckQueueTableModel::insertRow(int row, int count, const QModelIndex &parent) {
- beginInsertRows(QModelIndex(), row, row+count-1);
+Qt::DropActions CheckQueueTableModel::supportedDropActions() const {
+ return Qt::DropActions() | Qt::MoveAction;
+}
- for (int i = 0; i < count; ++i)
- checks->emplace(checks->begin() + row, Check());
+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, int, const QModelIndex &) {
+ if (action != Qt::MoveAction || !data->hasFormat(CheckQueueTableModel::MimeType))
+ 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) {
+ QString date = data(i, Qt::DisplayRole).toString();
+ double total = data(index(i.row(), i.column() + 1), Qt::DisplayRole).toDouble();
+ stream << date << total;
+ }
+ }
+ 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;
+ QByteArray encodedData = data->data(CheckQueueTableModel::MimeType);
+ QDataStream stream(&encodedData, QIODevice::ReadOnly);
+ std::vector newItems;
+ int rows = 0;
+
+ while (!stream.atEnd()) {
+ QString date;
+ double total;
+ stream >> date >> total;
+ Check c;
+ c.set_date(date.toStdString());
+ c.set_total(total);
+ newItems.push_back(c);
+ ++rows;
+ }
+
+ insertRows(row, rows, QModelIndex());
+ for (Check &c : newItems) {
+ QModelIndex date_index = index(row, 0, QModelIndex());
+ QModelIndex total_index = index(row, 1, QModelIndex());
+ setData(date_index, QVariant::fromValue(c.get_date()), Qt::EditRole);
+ setData(total_index, QVariant::fromValue(c.get_total()), Qt::EditRole);
+ row++;
+ }
+
+ return true;
+}
diff --git a/widgets/checkqueuetablemodel.h b/widgets/checkqueuetablemodel.h
index 3d759bc..0c00617 100644
--- a/widgets/checkqueuetablemodel.h
+++ b/widgets/checkqueuetablemodel.h
@@ -8,6 +8,7 @@
class CheckQueueTableModel : public QAbstractTableModel
{
Q_OBJECT
+ static constexpr const char* MimeType = "application/check.queue.model";
public:
explicit CheckQueueTableModel(std::vector *checks, QObject *parent = nullptr);
@@ -19,8 +20,16 @@ public:
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
Qt::ItemFlags flags(const QModelIndex &index) const override;
+ Qt::DropActions supportedDropActions() const override;
- bool insertRow(int row, int count, const QModelIndex &parent = QModelIndex());
+ // bool insertRow(int row, int count, const QModelIndex &parent = QModelIndex());
+ bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex()) override;
+ bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex()) override;
+
+ QStringList mimeTypes() const override;
+ bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int, int, const QModelIndex &);
+ QMimeData* mimeData(const QModelIndexList &indexes) const override;
+ bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
private:
std::vector *checks;
signals:
diff --git a/widgets/checkqueuetableview.cpp b/widgets/checkqueuetableview.cpp
new file mode 100644
index 0000000..a06fab8
--- /dev/null
+++ b/widgets/checkqueuetableview.cpp
@@ -0,0 +1,47 @@
+#include "checkqueuetableview.h"
+
+CheckQueueTableView::CheckQueueTableView(QWidget *parent)
+ : QTableView(parent), m_dropRow(0) {
+ setSelectionMode(QAbstractItemView::SingleSelection);
+ setSelectionBehavior(QAbstractItemView::SelectRows);
+ setDragEnabled(true);
+ setAcceptDrops(true);
+ setDragDropMode(QAbstractItemView::DragDrop);
+ setDefaultDropAction(Qt::MoveAction);
+ setDragDropOverwriteMode(false);
+ setDropIndicatorShown(true);
+}
+
+int CheckQueueTableView::selectedRow() const {
+ QItemSelectionModel *selection = selectionModel();
+ return selection->hasSelection() ? selection->selectedRows().front().row() : -1;
+}
+
+void CheckQueueTableView::reset() {
+ QTableView::reset();
+
+ QObject::connect(model(), &QAbstractTableModel::rowsInserted, this, [this](const QModelIndex &parent, int first, int last) {
+ Q_UNUSED(parent)
+ Q_UNUSED(last)
+ m_dropRow = first;
+ });
+}
+
+void CheckQueueTableView::dropEvent(QDropEvent *e) {
+ if (e->source() != this || e->dropAction() != Qt::MoveAction)
+ return;
+
+ int dragRow = selectedRow();
+
+ QTableView::dropEvent(e); // m_dropRow is set by inserted row
+
+ if (m_dropRow > dragRow)
+ --m_dropRow;
+
+ QMetaObject::invokeMethod(this,
+ std::bind(&CheckQueueTableView::selectRow, this, m_dropRow),
+ Qt::QueuedConnection); // Postpones selection
+}
+
+
+
diff --git a/widgets/checkqueuetableview.h b/widgets/checkqueuetableview.h
new file mode 100644
index 0000000..2482bca
--- /dev/null
+++ b/widgets/checkqueuetableview.h
@@ -0,0 +1,19 @@
+#ifndef CHECKQUEUETABLEVIEW_H
+#define CHECKQUEUETABLEVIEW_H
+
+#include
+#include
+
+class CheckQueueTableView : public QTableView
+{
+ Q_OBJECT
+ int m_dropRow;
+public:
+ CheckQueueTableView(QWidget *parent = nullptr);
+ Q_INVOKABLE int selectedRow() const;
+ void reset();
+ void dropEvent(QDropEvent *e);
+
+};
+
+#endif // CHECKQUEUETABLEVIEW_H
diff --git a/widgets/outputcolumnmodel.cpp b/widgets/outputcolumnmodel.cpp
index bbf84d6..bdd8d32 100644
--- a/widgets/outputcolumnmodel.cpp
+++ b/widgets/outputcolumnmodel.cpp
@@ -77,12 +77,6 @@ bool OutputColumnModel::removeRows(int position, int rows, const QModelIndex &pa
return true;
}
-QStringList OutputColumnModel::mimeTypes() const {
- QStringList types;
- types << OutputColumnModel::MimeType;
- return types;
-}
-
bool OutputColumnModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, int, int, const QModelIndex &) {
if ( action != Qt::MoveAction || !data->hasFormat(OutputColumnModel::MimeType))
return false;
diff --git a/widgets/outputcolumnmodel.h b/widgets/outputcolumnmodel.h
index 23ad8be..ee1ed7e 100644
--- a/widgets/outputcolumnmodel.h
+++ b/widgets/outputcolumnmodel.h
@@ -28,7 +28,7 @@ public:
bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex()) override;
bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex()) override;
- QStringList mimeTypes() const override;
+ // QStringList mimeTypes() const override;
bool canDropMimeData(const QMimeData *, Qt::DropAction, int, int, const QModelIndex&);
QMimeData* mimeData(const QModelIndexList &indexes) const;
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent);