From a49f63f40138ce897ffe3a2488895686b1bbbd63 Mon Sep 17 00:00:00 2001 From: taynpg Date: Sat, 28 Jun 2025 23:48:15 +0800 Subject: [PATCH] add: filter file ext. --- Gui/Control/FileControl.cpp | 108 +++++++++++++++++++++++++++++++++--- Gui/Control/FileControl.h | 11 +++- Note/version.md | 2 +- 3 files changed, 109 insertions(+), 12 deletions(-) diff --git a/Gui/Control/FileControl.cpp b/Gui/Control/FileControl.cpp index 6f437c8..0cf4b6b 100644 --- a/Gui/Control/FileControl.cpp +++ b/Gui/Control/FileControl.cpp @@ -2,9 +2,11 @@ #include #include +#include #include #include #include +#include #include #include @@ -14,6 +16,7 @@ FileManager::FileManager(QWidget* parent) : QWidget(parent), ui(new Ui::FileMana { ui->setupUi(this); InitControl(); + InitMenu(); } FileManager::~FileManager() @@ -75,6 +78,8 @@ void FileManager::InitControl() ui->tableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection); ui->tableWidget->setDragDropMode(QAbstractItemView::DragDrop); + ui->tableWidget->setContextMenuPolicy(Qt::CustomContextMenu); + connect(ui->btnHome, &QPushButton::clicked, this, &FileManager::evtHome); connect(ui->btnVisit, &QPushButton::clicked, this, &FileManager::evtFile); connect(ui->tableWidget, &QTableWidget::cellDoubleClicked, this, &FileManager::doubleClick); @@ -82,16 +87,17 @@ void FileManager::InitControl() connect(ui->tableWidget, &CustomTableWidget::sigTasks, this, [this](const QVector& tasks) { emit sigSendTasks(tasks); }); + connect(ui->tableWidget, &QTableWidget::customContextMenuRequested, this, + [this](const QPoint& pos) { menu_->exec(QCursor::pos()); }); + connect(ui->tableWidget->horizontalHeader(), &QHeaderView::sectionClicked, this, &FileManager::HeaderClicked); } -void FileManager::InitMenu(bool remote) +void FileManager::InitMenu() { - if (remote) { - // auto acDown = new QAction(tr("Download")); - } else { - // auto acUp = new QAction(tr("Upload")); - } + menu_ = new QMenu(ui->tableWidget); + menu_->addAction(tr("Filter"), this, &FileManager::ShowFilterForm); + menu_->addSeparator(); } void FileManager::ShowPath(const QString& path) @@ -112,6 +118,9 @@ void FileManager::ShowFile(const DirFileInfoVec& info) QMutexLocker locker(&tbMut_); currentInfo_ = info; SortFileInfo(SortMethod::SMD_BY_TYPE_DESC); + GenFilter(); + curSelectTypes_.clear(); + currentShowInfo_ = currentInfo_; RefreshTab(); ui->tableWidget->resizeColumnToContents(0); SetRoot(currentInfo_.root); @@ -202,9 +211,9 @@ void FileManager::RefreshTab() { ui->tableWidget->setUpdatesEnabled(false); ui->tableWidget->setRowCount(0); - ui->tableWidget->setRowCount(currentInfo_.vec.size()); - for (int i = 0; i < currentInfo_.vec.size(); ++i) { - const DirFileInfo& fileInfo = currentInfo_.vec[i]; + ui->tableWidget->setRowCount(currentShowInfo_.vec.size()); + for (int i = 0; i < currentShowInfo_.vec.size(); ++i) { + const DirFileInfo& fileInfo = currentShowInfo_.vec[i]; // *********************************************************************************** auto* iconItem = new QTableWidgetItem(""); @@ -315,6 +324,87 @@ void FileManager::HeaderClicked(int column) QMetaObject::invokeMethod(this, "RefreshTab", Qt::QueuedConnection); } +void FileManager::FilterFile(const QStringList& selectedTypes) +{ + if (selectedTypes.contains("*")) { + currentShowInfo_.vec = currentInfo_.vec; + QMetaObject::invokeMethod(this, "RefreshTab", Qt::QueuedConnection); + return; + } + currentShowInfo_.vec.clear(); + for (const auto& d : currentInfo_.vec) { + if (d.type == File) { + auto ext = d.fullPath.lastIndexOf('.'); + if (ext != -1) { + QString extStr = d.fullPath.mid(ext + 1).toLower(); + if (selectedTypes.contains(extStr)) { + currentShowInfo_.vec.push_back(d); + } + } + } + } + QMetaObject::invokeMethod(this, "RefreshTab", Qt::QueuedConnection); +} + +void FileManager::GenFilter() +{ + fileTypes_.clear(); + for (const auto& fileInfo : currentInfo_.vec) { + if (fileInfo.type == File) { + auto ext = fileInfo.fullPath.lastIndexOf('.'); + if (ext != -1) { + QString extStr = fileInfo.fullPath.mid(ext + 1).toLower(); + fileTypes_.insert(extStr); + } + } + } +} + +void FileManager::ShowFilterForm() +{ + QDialog dialog(this); + dialog.setWindowTitle("Select file type"); + dialog.resize(400, 300); + QListWidget listWidget(&dialog); + + listWidget.setSelectionMode(QAbstractItemView::NoSelection); + QListWidgetItem* allItem = new QListWidgetItem("*(ALL)"); + allItem->setData(Qt::UserRole, "*"); + allItem->setCheckState(curSelectTypes_.contains("*") ? Qt::Checked : Qt::Unchecked); + listWidget.addItem(allItem); + + for (const QString& ext : fileTypes_) { + QListWidgetItem* item = new QListWidgetItem(ext); + item->setData(Qt::UserRole, ext); + item->setCheckState(curSelectTypes_.contains(ext) ? Qt::Checked : Qt::Unchecked); + listWidget.addItem(item); + } + + QDialogButtonBox buttons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, &dialog); + connect(&buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept); + connect(&buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject); + + QVBoxLayout layout(&dialog); + layout.addWidget(&listWidget); + layout.addWidget(&buttons); + dialog.setLayout(&layout); + + if (dialog.exec() == QDialog::Accepted) { + QStringList selectedTypes; + for (int i = 0; i < listWidget.count(); ++i) { + QListWidgetItem* item = listWidget.item(i); + if (item->checkState() == Qt::Checked) { + selectedTypes << item->data(Qt::UserRole).toString(); + } + } + FilterFile(selectedTypes); + curSelectTypes_.clear(); + for (int i = 0; i < selectedTypes.count(); ++i) { + curSelectTypes_.insert(selectedTypes[i]); + } + } +} + QString FileManager::GetRoot() { if (isRemote_) { diff --git a/Gui/Control/FileControl.h b/Gui/Control/FileControl.h index 1dce9cd..bd23485 100644 --- a/Gui/Control/FileControl.h +++ b/Gui/Control/FileControl.h @@ -4,12 +4,13 @@ #include #include #include +#include #include #include #include #include -#include #include +#include namespace Ui { class FileManager; @@ -43,13 +44,16 @@ signals: private: void InitControl(); - void InitMenu(bool remote = false); + void InitMenu(); void ShowPath(const QString& path); void ShowFile(const DirFileInfoVec& info); void doubleClick(int row, int column); void SetRoot(const QString& path); void SortFileInfo(SortMethod method); void HeaderClicked(int column); + void FilterFile(const QStringList& selectedTypes); + void GenFilter(); + void ShowFilterForm(); public slots: void evtHome(); @@ -64,7 +68,10 @@ private: ClientCore* cliCore_; QMutex cbMut_; QMutex tbMut_; + QSet fileTypes_; + QSet curSelectTypes_; DirFileInfoVec currentInfo_; + DirFileInfoVec currentShowInfo_; std::map sortMedRecord_; std::shared_ptr fileHelper_; }; diff --git a/Note/version.md b/Note/version.md index f4d60f5..4589999 100644 --- a/Note/version.md +++ b/Note/version.md @@ -21,7 +21,7 @@ | 11 | 问题 | 断连后当前远端ID要清除。 | | 0.1 | 0.2 | | 10 | 功能 | 对照传输可以支持反向下载。 | | 0.1 | | | 9 | 优化 | 输入路径后可以直接回车访问。 | | 0.1 | | -| 8 | 功能 | 文件浏览页面要支持按照类型排序,时间排序,和文件后缀筛选。 | | 0.1 | | +| 8 | 功能 | 文件浏览页面要支持按照类型排序,时间排序,和文件后缀筛选。 | | 0.1 | 0.2 | | 7 | 优化 | IP和Port宽度要合理一些,IP过小,Port宽度过大。 | | 0.1 | 0.2 | | 6 | 功能 | 比对控件添加可尝试目录浏览控件跳转到指定目录。 | | 0.1 | | | 5 | 问题 | 未设置心跳包,导致超时被Server端踢出。 | 必改 | 0.1 | 0.2 |