mirror of
https://github.com/MatsuriDayo/nekoray.git
synced 2025-12-17 20:44:38 +03:00
feat: refactor proxy table ui
This commit is contained in:
@@ -152,6 +152,11 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
|
|||||||
group->order = ui->proxyListTable->order;
|
group->order = ui->proxyListTable->order;
|
||||||
group->Save();
|
group->Save();
|
||||||
};
|
};
|
||||||
|
ui->proxyListTable->refresh_data = [=](int id) { refresh_proxy_list_impl_refresh_data(id); };
|
||||||
|
if (auto button = ui->proxyListTable->findChild<QAbstractButton *>(QString(), Qt::FindDirectChildrenOnly)) {
|
||||||
|
// Corner Button
|
||||||
|
connect(button, &QAbstractButton::clicked, this, [=] { refresh_proxy_list_impl(-1, {NekoRay::GroupSortMethod::ById}); });
|
||||||
|
}
|
||||||
connect(ui->proxyListTable->horizontalHeader(), &QHeaderView::sectionClicked, this, [=](int logicalIndex) {
|
connect(ui->proxyListTable->horizontalHeader(), &QHeaderView::sectionClicked, this, [=](int logicalIndex) {
|
||||||
NekoRay::GroupSortAction action;
|
NekoRay::GroupSortAction action;
|
||||||
// 不正确的descending实现
|
// 不正确的descending实现
|
||||||
@@ -163,27 +168,24 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
|
|||||||
}
|
}
|
||||||
action.save_sort = true;
|
action.save_sort = true;
|
||||||
// 表头
|
// 表头
|
||||||
if (logicalIndex == 1) {
|
if (logicalIndex == 0) {
|
||||||
action.method = NekoRay::GroupSortMethod::ByType;
|
action.method = NekoRay::GroupSortMethod::ByType;
|
||||||
} else if (logicalIndex == 2) {
|
} else if (logicalIndex == 1) {
|
||||||
action.method = NekoRay::GroupSortMethod::ByAddress;
|
action.method = NekoRay::GroupSortMethod::ByAddress;
|
||||||
} else if (logicalIndex == 3) {
|
} else if (logicalIndex == 2) {
|
||||||
action.method = NekoRay::GroupSortMethod::ByName;
|
action.method = NekoRay::GroupSortMethod::ByName;
|
||||||
} else if (logicalIndex == 4) {
|
} else if (logicalIndex == 3) {
|
||||||
action.method = NekoRay::GroupSortMethod::ByLatency;
|
action.method = NekoRay::GroupSortMethod::ByLatency;
|
||||||
} else if (logicalIndex == 0) {
|
|
||||||
action.method = NekoRay::GroupSortMethod::ById;
|
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
refresh_proxy_list_impl(-1, action);
|
refresh_proxy_list_impl(-1, action);
|
||||||
});
|
});
|
||||||
ui->proxyListTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
|
ui->proxyListTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
|
||||||
ui->proxyListTable->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
|
ui->proxyListTable->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
|
||||||
ui->proxyListTable->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Stretch);
|
ui->proxyListTable->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Stretch);
|
||||||
ui->proxyListTable->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Stretch);
|
ui->proxyListTable->horizontalHeader()->setSectionResizeMode(3, QHeaderView::ResizeToContents);
|
||||||
ui->proxyListTable->horizontalHeader()->setSectionResizeMode(4, QHeaderView::ResizeToContents);
|
ui->proxyListTable->horizontalHeader()->setSectionResizeMode(4, QHeaderView::ResizeToContents);
|
||||||
ui->proxyListTable->horizontalHeader()->setSectionResizeMode(5, QHeaderView::ResizeToContents);
|
|
||||||
ui->tableWidget_conn->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
|
ui->tableWidget_conn->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
|
||||||
ui->tableWidget_conn->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
|
ui->tableWidget_conn->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
|
||||||
ui->tableWidget_conn->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Stretch);
|
ui->tableWidget_conn->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Stretch);
|
||||||
@@ -226,10 +228,10 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
|
|||||||
this->refresh_groups();
|
this->refresh_groups();
|
||||||
|
|
||||||
// Setup Tray
|
// Setup Tray
|
||||||
tray = new QSystemTrayIcon(this); //初始化托盘对象tray
|
tray = new QSystemTrayIcon(this); // 初始化托盘对象tray
|
||||||
tray->setIcon(TrayIcon::GetIcon(TrayIcon::NONE));
|
tray->setIcon(TrayIcon::GetIcon(TrayIcon::NONE));
|
||||||
tray->setContextMenu(ui->menu_program); //创建托盘菜单
|
tray->setContextMenu(ui->menu_program); // 创建托盘菜单
|
||||||
tray->show(); //让托盘图标显示在系统托盘上
|
tray->show(); // 让托盘图标显示在系统托盘上
|
||||||
connect(tray, &QSystemTrayIcon::activated, this, [=](QSystemTrayIcon::ActivationReason reason) {
|
connect(tray, &QSystemTrayIcon::activated, this, [=](QSystemTrayIcon::ActivationReason reason) {
|
||||||
switch (reason) {
|
switch (reason) {
|
||||||
case QSystemTrayIcon::Trigger:
|
case QSystemTrayIcon::Trigger:
|
||||||
@@ -391,8 +393,8 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
|
|||||||
|
|
||||||
void MainWindow::closeEvent(QCloseEvent *event) {
|
void MainWindow::closeEvent(QCloseEvent *event) {
|
||||||
if (tray->isVisible()) {
|
if (tray->isVisible()) {
|
||||||
hide(); //隐藏窗口
|
hide(); // 隐藏窗口
|
||||||
event->ignore(); //忽略事件
|
event->ignore(); // 忽略事件
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -734,75 +736,19 @@ void MainWindow::refresh_proxy_list(const int &id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::refresh_proxy_list_impl(const int &id, NekoRay::GroupSortAction groupSortAction) {
|
void MainWindow::refresh_proxy_list_impl(const int &id, NekoRay::GroupSortAction groupSortAction) {
|
||||||
|
// id < 0 重绘
|
||||||
if (id < 0) {
|
if (id < 0) {
|
||||||
//这样才能清空数据
|
// 清空数据
|
||||||
|
ui->proxyListTable->row2Id.clear();
|
||||||
ui->proxyListTable->setRowCount(0);
|
ui->proxyListTable->setRowCount(0);
|
||||||
}
|
// 添加行
|
||||||
|
|
||||||
QTableWidgetItem *started_item = nullptr;
|
|
||||||
|
|
||||||
// 绘制或更新item(s)
|
|
||||||
int row = -1;
|
int row = -1;
|
||||||
for (const auto &profile: NekoRay::profileManager->profiles) {
|
for (const auto &profile: NekoRay::profileManager->profiles) {
|
||||||
if (NekoRay::dataStore->current_group != profile->gid) continue;
|
if (NekoRay::dataStore->current_group != profile->gid) continue;
|
||||||
|
|
||||||
row++;
|
row++;
|
||||||
if (id >= 0 && profile->id != id) continue; // update only one item
|
|
||||||
if (id < 0) {
|
|
||||||
ui->proxyListTable->insertRow(row);
|
ui->proxyListTable->insertRow(row);
|
||||||
} else {
|
ui->proxyListTable->row2Id += profile->id;
|
||||||
// 排序过的,要找
|
|
||||||
row = ui->proxyListTable->id2Row[id];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto f0 = std::make_unique<QTableWidgetItem>();
|
|
||||||
f0->setData(114514, profile->id);
|
|
||||||
|
|
||||||
// C0: is Running
|
|
||||||
auto f = f0->clone();
|
|
||||||
if (profile->id == NekoRay::dataStore->started_id) {
|
|
||||||
f->setText("✓");
|
|
||||||
if (groupSortAction.scroll_to_started) started_item = f;
|
|
||||||
} else {
|
|
||||||
f->setText(" ");
|
|
||||||
}
|
|
||||||
ui->proxyListTable->setItem(row, 0, f);
|
|
||||||
|
|
||||||
// C1: Type
|
|
||||||
f = f0->clone();
|
|
||||||
f->setText(profile->bean->DisplayType());
|
|
||||||
auto insecure_hint = profile->bean->DisplayInsecureHint();
|
|
||||||
if (!insecure_hint.isEmpty()) {
|
|
||||||
f->setBackground(Qt::red);
|
|
||||||
f->setToolTip(insecure_hint);
|
|
||||||
}
|
|
||||||
ui->proxyListTable->setItem(row, 1, f);
|
|
||||||
|
|
||||||
// C2: Address+Port
|
|
||||||
f = f0->clone();
|
|
||||||
f->setText(profile->bean->DisplayAddress());
|
|
||||||
ui->proxyListTable->setItem(row, 2, f);
|
|
||||||
|
|
||||||
// C3: Name
|
|
||||||
f = f0->clone();
|
|
||||||
f->setText(profile->bean->name);
|
|
||||||
ui->proxyListTable->setItem(row, 3, f);
|
|
||||||
|
|
||||||
// C4: Test Result
|
|
||||||
f = f0->clone();
|
|
||||||
if (profile->full_test_report.isEmpty()) {
|
|
||||||
auto color = profile->DisplayLatencyColor();
|
|
||||||
if (color.isValid()) f->setForeground(color);
|
|
||||||
f->setText(profile->DisplayLatency());
|
|
||||||
} else {
|
|
||||||
f->setText(profile->full_test_report);
|
|
||||||
}
|
|
||||||
ui->proxyListTable->setItem(row, 4, f);
|
|
||||||
|
|
||||||
// C5: Traffic
|
|
||||||
f = f0->clone();
|
|
||||||
f->setText(profile->traffic_data->DisplayTraffic());
|
|
||||||
ui->proxyListTable->setItem(row, 5, f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 显示排序
|
// 显示排序
|
||||||
@@ -815,14 +761,8 @@ void MainWindow::refresh_proxy_list_impl(const int &id, NekoRay::GroupSortAction
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NekoRay::GroupSortMethod::ById: {
|
case NekoRay::GroupSortMethod::ById: {
|
||||||
std::sort(ui->proxyListTable->order.begin(), ui->proxyListTable->order.end(),
|
// Clear Order
|
||||||
[=](int a, int b) {
|
ui->proxyListTable->order.clear();
|
||||||
if (groupSortAction.descending) {
|
|
||||||
return a > b;
|
|
||||||
} else {
|
|
||||||
return a < b;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NekoRay::GroupSortMethod::ByAddress:
|
case NekoRay::GroupSortMethod::ByAddress:
|
||||||
@@ -869,10 +809,60 @@ void MainWindow::refresh_proxy_list_impl(const int &id, NekoRay::GroupSortAction
|
|||||||
ui->proxyListTable->update_order(groupSortAction.save_sort);
|
ui->proxyListTable->update_order(groupSortAction.save_sort);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (started_item != nullptr) {
|
// refresh data
|
||||||
runOnUiThread([=] {
|
refresh_proxy_list_impl_refresh_data(id);
|
||||||
ui->proxyListTable->verticalScrollBar()->setSliderPosition(started_item->row());
|
}
|
||||||
});
|
|
||||||
|
void MainWindow::refresh_proxy_list_impl_refresh_data(const int &id) {
|
||||||
|
// 绘制或更新item(s)
|
||||||
|
for (int row = 0; row < ui->proxyListTable->rowCount(); row++) {
|
||||||
|
auto profile = NekoRay::profileManager->GetProfile(ui->proxyListTable->row2Id[row]);
|
||||||
|
if (profile == nullptr) continue;
|
||||||
|
if (id >= 0 && profile->id != id) continue; // refresh ONE item
|
||||||
|
|
||||||
|
auto f0 = std::make_unique<QTableWidgetItem>();
|
||||||
|
f0->setData(114514, profile->id);
|
||||||
|
|
||||||
|
// Check state
|
||||||
|
auto check = f0->clone();
|
||||||
|
check->setText(profile->id == NekoRay::dataStore->started_id ? "✓" : Int2String(row + 1));
|
||||||
|
ui->proxyListTable->setVerticalHeaderItem(row, check);
|
||||||
|
|
||||||
|
// C0: Type
|
||||||
|
auto f = f0->clone();
|
||||||
|
f->setText(profile->bean->DisplayType());
|
||||||
|
auto insecure_hint = profile->bean->DisplayInsecureHint();
|
||||||
|
if (!insecure_hint.isEmpty()) {
|
||||||
|
f->setBackground(Qt::red);
|
||||||
|
f->setToolTip(insecure_hint);
|
||||||
|
}
|
||||||
|
ui->proxyListTable->setItem(row, 0, f);
|
||||||
|
|
||||||
|
// C1: Address+Port
|
||||||
|
f = f0->clone();
|
||||||
|
f->setText(profile->bean->DisplayAddress());
|
||||||
|
ui->proxyListTable->setItem(row, 1, f);
|
||||||
|
|
||||||
|
// C2: Name
|
||||||
|
f = f0->clone();
|
||||||
|
f->setText(profile->bean->name);
|
||||||
|
ui->proxyListTable->setItem(row, 2, f);
|
||||||
|
|
||||||
|
// C3: Test Result
|
||||||
|
f = f0->clone();
|
||||||
|
if (profile->full_test_report.isEmpty()) {
|
||||||
|
auto color = profile->DisplayLatencyColor();
|
||||||
|
if (color.isValid()) f->setForeground(color);
|
||||||
|
f->setText(profile->DisplayLatency());
|
||||||
|
} else {
|
||||||
|
f->setText(profile->full_test_report);
|
||||||
|
}
|
||||||
|
ui->proxyListTable->setItem(row, 3, f);
|
||||||
|
|
||||||
|
// C4: Traffic
|
||||||
|
f = f0->clone();
|
||||||
|
f->setText(profile->traffic_data->DisplayTraffic());
|
||||||
|
ui->proxyListTable->setItem(row, 4, f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1237,7 +1227,7 @@ void MainWindow::on_menu_resolve_domain_triggered() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_proxyListTable_customContextMenuRequested(const QPoint &pos) {
|
void MainWindow::on_proxyListTable_customContextMenuRequested(const QPoint &pos) {
|
||||||
ui->menu_server->popup(ui->proxyListTable->viewport()->mapToGlobal(pos)); //弹出菜单
|
ui->menu_server->popup(ui->proxyListTable->viewport()->mapToGlobal(pos)); // 弹出菜单
|
||||||
}
|
}
|
||||||
|
|
||||||
QMap<int, QSharedPointer<NekoRay::ProxyEntity>> MainWindow::get_now_selected() {
|
QMap<int, QSharedPointer<NekoRay::ProxyEntity>> MainWindow::get_now_selected() {
|
||||||
@@ -1312,8 +1302,7 @@ void MainWindow::on_masterLogBrowser_customContextMenuRequested(const QPoint &po
|
|||||||
ui->masterLogBrowser->clear();
|
ui->masterLogBrowser->clear();
|
||||||
});
|
});
|
||||||
menu->addAction(action_clear);
|
menu->addAction(action_clear);
|
||||||
|
menu->exec(ui->masterLogBrowser->viewport()->mapToGlobal(pos)); // 弹出菜单
|
||||||
menu->exec(ui->masterLogBrowser->viewport()->mapToGlobal(pos)); //弹出菜单
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// eventFilter
|
// eventFilter
|
||||||
|
|||||||
@@ -156,6 +156,8 @@ private:
|
|||||||
|
|
||||||
void refresh_proxy_list_impl(const int &id = -1, NekoRay::GroupSortAction groupSortAction = {});
|
void refresh_proxy_list_impl(const int &id = -1, NekoRay::GroupSortAction groupSortAction = {});
|
||||||
|
|
||||||
|
void refresh_proxy_list_impl_refresh_data(const int &id = -1);
|
||||||
|
|
||||||
void keyPressEvent(QKeyEvent *event) override;
|
void keyPressEvent(QKeyEvent *event) override;
|
||||||
|
|
||||||
void closeEvent(QCloseEvent *event) override;
|
void closeEvent(QCloseEvent *event) override;
|
||||||
|
|||||||
@@ -266,13 +266,8 @@
|
|||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</attribute>
|
</attribute>
|
||||||
<attribute name="verticalHeaderDefaultSectionSize">
|
<attribute name="verticalHeaderDefaultSectionSize">
|
||||||
<number>26</number>
|
<number>24</number>
|
||||||
</attribute>
|
</attribute>
|
||||||
<column>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</column>
|
|
||||||
<column>
|
<column>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Type</string>
|
<string>Type</string>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <QTableWidget>
|
#include <QTableWidget>
|
||||||
#include <QDropEvent>
|
#include <QDropEvent>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <functional>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
class MyTableWidget : public QTableWidget {
|
class MyTableWidget : public QTableWidget {
|
||||||
@@ -15,31 +16,18 @@ public:
|
|||||||
this->setSelectionBehavior(QAbstractItemView::SelectRows);
|
this->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||||
};
|
};
|
||||||
|
|
||||||
// takes and returns the whole row
|
QList<int> order; // id sorted (save)
|
||||||
QList<QTableWidgetItem *> takeRow(int row) {
|
std::map<int, int> id2Row; // id2Row
|
||||||
QList<QTableWidgetItem *> rowItems;
|
QList<int> row2Id; // row2Id: use this to refresh data
|
||||||
for (int col = 0; col < columnCount(); ++col) {
|
|
||||||
rowItems << takeItem(row, col);
|
|
||||||
}
|
|
||||||
return rowItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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::function<void()> callback_save_order;
|
||||||
std::map<int, int> id2Row;
|
std::function<void(int id)> refresh_data;
|
||||||
|
|
||||||
void _save_order(bool saveToFile) {
|
void _save_order(bool saveToFile) {
|
||||||
order.clear();
|
order.clear();
|
||||||
id2Row.clear();
|
id2Row.clear();
|
||||||
for (int i = 0; i < this->rowCount(); i++) {
|
for (int i = 0; i < this->rowCount(); i++) {
|
||||||
auto id = this->item(i, 0)->data(114514).toInt();
|
auto id = row2Id[i];
|
||||||
order += id;
|
order += id;
|
||||||
id2Row[id] = i;
|
id2Row[id] = i;
|
||||||
}
|
}
|
||||||
@@ -57,7 +45,7 @@ public:
|
|||||||
bool needSave = false;
|
bool needSave = false;
|
||||||
auto deleted_profiles = order;
|
auto deleted_profiles = order;
|
||||||
for (int i = 0; i < this->rowCount(); i++) {
|
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);
|
deleted_profiles.removeAll(id);
|
||||||
}
|
}
|
||||||
for (auto deleted_profile: deleted_profiles) {
|
for (auto deleted_profile: deleted_profiles) {
|
||||||
@@ -65,9 +53,10 @@ public:
|
|||||||
order.removeAll(deleted_profile);
|
order.removeAll(deleted_profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
QMap<int, QList<QTableWidgetItem *>> newRows;
|
// map(dstRow -> srcId)
|
||||||
|
QMap<int, int> newRows;
|
||||||
for (int i = 0; i < this->rowCount(); i++) {
|
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);
|
auto dst = order.indexOf(id);
|
||||||
if (dst == i) continue;
|
if (dst == i) continue;
|
||||||
if (dst == -1) {
|
if (dst == -1) {
|
||||||
@@ -75,12 +64,12 @@ public:
|
|||||||
needSave = true;
|
needSave = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
newRows[dst] = takeRow(i);
|
newRows[dst] = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < this->rowCount(); i++) {
|
for (int i = 0; i < this->rowCount(); i++) {
|
||||||
if (!newRows.contains(i)) continue;
|
if (!newRows.contains(i)) continue;
|
||||||
setRow(i, newRows[i]);
|
row2Id[i] = newRows[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then save the order
|
// Then save the order
|
||||||
@@ -95,30 +84,27 @@ protected:
|
|||||||
* 注意:DragDropMode相关参数的设置
|
* 注意:DragDropMode相关参数的设置
|
||||||
*/
|
*/
|
||||||
void dropEvent(QDropEvent *event) override {
|
void dropEvent(QDropEvent *event) override {
|
||||||
|
if (order.isEmpty()) order = row2Id;
|
||||||
|
|
||||||
// 原行号与目标行号的确定
|
// 原行号与目标行号的确定
|
||||||
int row_src, row_dst;
|
int row_src, row_dst;
|
||||||
row_src = this->currentRow(); // 原行号 可加if
|
row_src = this->currentRow(); // 原行号 可加if
|
||||||
|
auto id_src = row2Id[row_src]; // id_src
|
||||||
QTableWidgetItem *item = this->itemAt(event->pos()); // 获取落点的item
|
QTableWidgetItem *item = this->itemAt(event->pos()); // 获取落点的item
|
||||||
if (item != nullptr) {
|
if (item != nullptr) {
|
||||||
// 判断是否为空
|
// 判断是否为空
|
||||||
row_dst = item->row(); // 不为空 获取其行号
|
row_dst = item->row(); // 不为空 获取其行号
|
||||||
// 保证鼠标落下的位置 就是拖拽的一行最后所移动到的位置(考虑插入新行 移除原行的上下变化)
|
// Modify order
|
||||||
row_src = (row_src > row_dst ? row_src + 1 : row_src); // 如果src在dst的下方(行号大),后续插入dst会影响src的行号
|
order.removeAt(row_src);
|
||||||
row_dst = (row_src < row_dst ? row_dst + 1 : row_dst); // 如果src在dst的上方(行号小),后续移除src会影响dst的行号
|
order.insert(row_dst, id_src);
|
||||||
this->insertRow(row_dst); // 插入一行
|
|
||||||
} else {
|
} else {
|
||||||
// 落点没有item 说明拖动到了最下面
|
// 落点没有item 说明拖动到了最下面
|
||||||
row_dst = this->rowCount(); // 获取行总数
|
return;
|
||||||
this->insertRow(row_dst); // 在最后新增一行
|
|
||||||
}
|
}
|
||||||
// 执行移动 并移除原行
|
|
||||||
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
|
// Do update order & refresh
|
||||||
_save_order(true);
|
clearSelection();
|
||||||
|
update_order(true);
|
||||||
|
refresh_data(-1);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user