mirror of
https://github.com/MatsuriDayo/nekoray.git
synced 2025-12-18 04:54:38 +03:00
feat: refactor proxy table ui
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
#include <QTableWidget>
|
||||
#include <QDropEvent>
|
||||
#include <QDebug>
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
|
||||
class MyTableWidget : public QTableWidget {
|
||||
@@ -15,31 +16,18 @@ public:
|
||||
this->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
};
|
||||
|
||||
// takes and returns the whole row
|
||||
QList<QTableWidgetItem *> takeRow(int row) {
|
||||
QList<QTableWidgetItem *> rowItems;
|
||||
for (int col = 0; col < columnCount(); ++col) {
|
||||
rowItems << takeItem(row, col);
|
||||
}
|
||||
return rowItems;
|
||||
}
|
||||
QList<int> order; // id sorted (save)
|
||||
std::map<int, int> id2Row; // id2Row
|
||||
QList<int> row2Id; // row2Id: use this to refresh data
|
||||
|
||||
// sets the whole row
|
||||
void setRow(int row, const QList<QTableWidgetItem *> &rowItems) {
|
||||
for (int col = 0; col < columnCount(); ++col) {
|
||||
setItem(row, col, rowItems.at(col));
|
||||
}
|
||||
}
|
||||
|
||||
QList<int> order; // id sorted
|
||||
std::function<void()> callback_save_order;
|
||||
std::map<int, int> id2Row;
|
||||
std::function<void(int id)> refresh_data;
|
||||
|
||||
void _save_order(bool saveToFile) {
|
||||
order.clear();
|
||||
id2Row.clear();
|
||||
for (int i = 0; i < this->rowCount(); i++) {
|
||||
auto id = this->item(i, 0)->data(114514).toInt();
|
||||
auto id = row2Id[i];
|
||||
order += id;
|
||||
id2Row[id] = i;
|
||||
}
|
||||
@@ -57,7 +45,7 @@ public:
|
||||
bool needSave = false;
|
||||
auto deleted_profiles = order;
|
||||
for (int i = 0; i < this->rowCount(); i++) {
|
||||
auto id = this->item(i, 0)->data(114514).toInt();
|
||||
auto id = row2Id[i];
|
||||
deleted_profiles.removeAll(id);
|
||||
}
|
||||
for (auto deleted_profile: deleted_profiles) {
|
||||
@@ -65,9 +53,10 @@ public:
|
||||
order.removeAll(deleted_profile);
|
||||
}
|
||||
|
||||
QMap<int, QList<QTableWidgetItem *>> newRows;
|
||||
// map(dstRow -> srcId)
|
||||
QMap<int, int> newRows;
|
||||
for (int i = 0; i < this->rowCount(); i++) {
|
||||
auto id = this->item(i, 0)->data(114514).toInt();
|
||||
auto id = row2Id[i];
|
||||
auto dst = order.indexOf(id);
|
||||
if (dst == i) continue;
|
||||
if (dst == -1) {
|
||||
@@ -75,12 +64,12 @@ public:
|
||||
needSave = true;
|
||||
continue;
|
||||
}
|
||||
newRows[dst] = takeRow(i);
|
||||
newRows[dst] = id;
|
||||
}
|
||||
|
||||
for (int i = 0; i < this->rowCount(); i++) {
|
||||
if (!newRows.contains(i)) continue;
|
||||
setRow(i, newRows[i]);
|
||||
row2Id[i] = newRows[i];
|
||||
}
|
||||
|
||||
// Then save the order
|
||||
@@ -95,30 +84,27 @@ protected:
|
||||
* 注意:DragDropMode相关参数的设置
|
||||
*/
|
||||
void dropEvent(QDropEvent *event) override {
|
||||
if (order.isEmpty()) order = row2Id;
|
||||
|
||||
// 原行号与目标行号的确定
|
||||
int row_src, row_dst;
|
||||
row_src = this->currentRow(); // 原行号 可加if
|
||||
auto id_src = row2Id[row_src]; // id_src
|
||||
QTableWidgetItem *item = this->itemAt(event->pos()); // 获取落点的item
|
||||
if (item != nullptr) {
|
||||
// 判断是否为空
|
||||
row_dst = item->row(); // 不为空 获取其行号
|
||||
// 保证鼠标落下的位置 就是拖拽的一行最后所移动到的位置(考虑插入新行 移除原行的上下变化)
|
||||
row_src = (row_src > row_dst ? row_src + 1 : row_src); // 如果src在dst的下方(行号大),后续插入dst会影响src的行号
|
||||
row_dst = (row_src < row_dst ? row_dst + 1 : row_dst); // 如果src在dst的上方(行号小),后续移除src会影响dst的行号
|
||||
this->insertRow(row_dst); // 插入一行
|
||||
// Modify order
|
||||
order.removeAt(row_src);
|
||||
order.insert(row_dst, id_src);
|
||||
} else {
|
||||
// 落点没有item 说明拖动到了最下面
|
||||
row_dst = this->rowCount(); // 获取行总数
|
||||
this->insertRow(row_dst); // 在最后新增一行
|
||||
return;
|
||||
}
|
||||
// 执行移动 并移除原行
|
||||
for (int i = 0; i < this->columnCount(); i++) {
|
||||
// 遍历列
|
||||
this->setItem(row_dst, i, this->takeItem(row_src, i)); // 每一列item的移动
|
||||
}
|
||||
this->removeRow(row_src); // 删除原行
|
||||
|
||||
// Then save the order
|
||||
_save_order(true);
|
||||
// Do update order & refresh
|
||||
clearSelection();
|
||||
update_order(true);
|
||||
refresh_data(-1);
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user