From 92e1ed7b3fd5360278d41db087518b6c5af80b3e Mon Sep 17 00:00:00 2001 From: saturneric Date: Sun, 26 Jan 2025 19:17:20 +0100 Subject: feat: allow file batch operations --- src/ui/widgets/FileTreeView.cpp | 61 +++++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 20 deletions(-) (limited to 'src/ui/widgets/FileTreeView.cpp') diff --git a/src/ui/widgets/FileTreeView.cpp b/src/ui/widgets/FileTreeView.cpp index 500d9787..aa29d040 100644 --- a/src/ui/widgets/FileTreeView.cpp +++ b/src/ui/widgets/FileTreeView.cpp @@ -37,7 +37,7 @@ namespace GpgFrontend::UI { FileTreeView::FileTreeView(QWidget* parent, const QString& target_path) : QTreeView(parent) { - dir_model_ = new QFileSystemModel(); + dir_model_ = new QFileSystemModel(this); dir_model_->setRootPath(target_path.isEmpty() ? QDir::currentPath() : target_path); dir_model_->setFilter(QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot); @@ -49,6 +49,7 @@ FileTreeView::FileTreeView(QWidget* parent, const QString& target_path) slot_create_popup_menu(); this->setContextMenuPolicy(Qt::CustomContextMenu); + this->setSelectionMode(QAbstractItemView::MultiSelection); connect(this, &QWidget::customContextMenuRequested, this, &FileTreeView::slot_show_custom_context_menu); @@ -64,16 +65,19 @@ void FileTreeView::selectionChanged(const QItemSelection& selected, const QItemSelection& deselected) { QTreeView::selectionChanged(selected, deselected); - if (!selected.indexes().empty()) { - selected_path_ = dir_model_->filePath(selected.indexes().first()); - emit SignalSelectedChanged(selected_path_); - } else { - selected_path_ = QString(); - if (!this->selectedIndexes().isEmpty()) { - selected_path_ = dir_model_->filePath(this->selectedIndexes().front()); - emit SignalSelectedChanged(selected_path_); + selected_paths_.clear(); + if (!this->selectedIndexes().isEmpty()) { + QSet paths; + for (const auto& index : this->selectedIndexes()) { + const auto path = dir_model_->filePath(index); + if (path == current_path_) continue; + + paths.insert(path); } + selected_paths_.append(paths.values()); } + + emit SignalSelectedChanged(selected_paths_); } void FileTreeView::SlotGoPath(const QString& target_path) { @@ -143,7 +147,9 @@ auto FileTreeView::GetPathByClickPoint(const QPoint& point) -> QString { return dir_model_->fileInfo(index).absoluteFilePath(); } -auto FileTreeView::GetSelectedPath() -> QString { return selected_path_; } +auto FileTreeView::GetSelectedPaths() -> QContainer { + return selected_paths_; +} auto FileTreeView::SlotDeleteSelectedItem() -> void { QModelIndex const index = this->currentIndex(); @@ -209,7 +215,9 @@ void FileTreeView::SlotTouch() { } void FileTreeView::SlotTouchBelowAtSelectedItem() { - auto root_path(selected_path_); + if (selected_paths_.size() != 1) return; + + auto root_path(selected_paths_.front()); if (root_path.isEmpty()) root_path = dir_model_->rootPath(); QString new_file_name; @@ -243,23 +251,29 @@ void FileTreeView::keyPressEvent(QKeyEvent* event) { } void FileTreeView::SlotOpenSelectedItemBySystemApplication() { - QFileInfo const info(selected_path_); + if (selected_paths_.size() != 1) return; + + auto selected_path = selected_paths_.front(); + QFileInfo const info(selected_path); if (info.isDir()) { const auto file_path = info.filePath().toUtf8(); - QDesktopServices::openUrl(QUrl::fromLocalFile(selected_path_)); + QDesktopServices::openUrl(QUrl::fromLocalFile(selected_path)); } else { - QDesktopServices::openUrl(QUrl::fromLocalFile(selected_path_)); + QDesktopServices::openUrl(QUrl::fromLocalFile(selected_path)); } } void FileTreeView::SlotRenameSelectedItem() { + if (selected_paths_.size() != 1) return; + bool ok; + auto selected_path = selected_paths_.front(); auto text = QInputDialog::getText(this, tr("Rename"), tr("New Filename"), QLineEdit::Normal, - QFileInfo(selected_path_).fileName(), &ok); + QFileInfo(selected_path).fileName(), &ok); if (ok && !text.isEmpty()) { - auto file_info = QFileInfo(selected_path_); + auto file_info = QFileInfo(selected_path); auto new_name_path = file_info.absolutePath() + "/" + text; if (!QDir().rename(file_info.absoluteFilePath(), new_name_path)) { @@ -282,8 +296,9 @@ void FileTreeView::slot_create_popup_menu() { action_open_file_ = new QAction(this); action_open_file_->setText(tr("Open")); - connect(action_open_file_, &QAction::triggered, this, - [this](bool) { emit SignalOpenFile(GetSelectedPath()); }); + connect(action_open_file_, &QAction::triggered, this, [this](bool) { + for (const auto& path : GetSelectedPaths()) emit SignalOpenFile(path); + }); action_rename_file_ = new QAction(this); action_rename_file_->setText(tr("Rename")); @@ -342,8 +357,11 @@ void FileTreeView::slot_create_popup_menu() { void FileTreeView::slot_show_custom_context_menu(const QPoint& point) { auto target_path = this->GetPathByClickPoint(point); - auto select_path = GetSelectedPath(); + auto select_paths = GetSelectedPaths(); + if (select_paths.size() != 1) return; + + auto select_path = select_paths.front(); if (target_path.isEmpty() && !select_path.isEmpty()) { target_path = select_path; } @@ -378,11 +396,14 @@ void FileTreeView::slot_show_custom_context_menu(const QPoint& point) { } void FileTreeView::slot_calculate_hash() { + if (GetSelectedPaths().empty()) return; + auto selected_path = GetSelectedPaths().front(); + CommonUtils::WaitForOpera( this->parentWidget(), tr("Calculating"), [=](const OperaWaitingHd& hd) { RunOperaAsync( [=](const DataObjectPtr& data_object) { - data_object->Swap({CalculateHash(this->GetSelectedPath())}); + data_object->Swap({CalculateHash(selected_path)}); return 0; }, [hd](int rtn, const DataObjectPtr& data_object) { -- cgit v1.2.3 From 731ec7339dc6f251a814d4aef59c05b1900ecf3f Mon Sep 17 00:00:00 2001 From: saturneric Date: Sun, 26 Jan 2025 19:40:43 +0100 Subject: fix: improve code compatibility --- src/ui/widgets/FileTreeView.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/ui/widgets/FileTreeView.cpp') diff --git a/src/ui/widgets/FileTreeView.cpp b/src/ui/widgets/FileTreeView.cpp index aa29d040..d50f8726 100644 --- a/src/ui/widgets/FileTreeView.cpp +++ b/src/ui/widgets/FileTreeView.cpp @@ -147,9 +147,7 @@ auto FileTreeView::GetPathByClickPoint(const QPoint& point) -> QString { return dir_model_->fileInfo(index).absoluteFilePath(); } -auto FileTreeView::GetSelectedPaths() -> QContainer { - return selected_paths_; -} +auto FileTreeView::GetSelectedPaths() -> QStringList { return selected_paths_; } auto FileTreeView::SlotDeleteSelectedItem() -> void { QModelIndex const index = this->currentIndex(); -- cgit v1.2.3 From 3aa7e3221436599a6e1461bb71f2fce9cef7c2ac Mon Sep 17 00:00:00 2001 From: saturneric Date: Sun, 26 Jan 2025 19:52:33 +0100 Subject: feat: add ui ability to switch batch mode --- src/ui/widgets/FileTreeView.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/ui/widgets/FileTreeView.cpp') diff --git a/src/ui/widgets/FileTreeView.cpp b/src/ui/widgets/FileTreeView.cpp index d50f8726..616cffb4 100644 --- a/src/ui/widgets/FileTreeView.cpp +++ b/src/ui/widgets/FileTreeView.cpp @@ -49,7 +49,7 @@ FileTreeView::FileTreeView(QWidget* parent, const QString& target_path) slot_create_popup_menu(); this->setContextMenuPolicy(Qt::CustomContextMenu); - this->setSelectionMode(QAbstractItemView::MultiSelection); + this->setSelectionMode(QAbstractItemView::SingleSelection); connect(this, &QWidget::customContextMenuRequested, this, &FileTreeView::slot_show_custom_context_menu); @@ -439,4 +439,10 @@ void FileTreeView::slot_adjust_column_widths() { } } +void FileTreeView::SlotSwitchBatchMode(bool batch) { + this->setSelectionMode(batch ? QAbstractItemView::MultiSelection + : QAbstractItemView::SingleSelection); + selectionModel()->clearSelection(); +} + } // namespace GpgFrontend::UI -- cgit v1.2.3 From bd0bfe63e715439f9de6562d7abc862b9ae6a9fc Mon Sep 17 00:00:00 2001 From: saturneric Date: Sun, 26 Jan 2025 20:51:16 +0100 Subject: feat: allow changing sort options by ui at file page --- src/ui/widgets/FileTreeView.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/ui/widgets/FileTreeView.cpp') diff --git a/src/ui/widgets/FileTreeView.cpp b/src/ui/widgets/FileTreeView.cpp index 616cffb4..20078e7c 100644 --- a/src/ui/widgets/FileTreeView.cpp +++ b/src/ui/widgets/FileTreeView.cpp @@ -45,6 +45,7 @@ FileTreeView::FileTreeView(QWidget* parent, const QString& target_path) this->setModel(dir_model_); this->setColumnWidth(0, 320); this->sortByColumn(0, Qt::AscendingOrder); + this->setSortingEnabled(true); current_path_ = dir_model_->rootPath(); slot_create_popup_menu(); -- cgit v1.2.3 From 0a8a116d2dabedae09995906bef7a4a25af2fd61 Mon Sep 17 00:00:00 2001 From: saturneric Date: Tue, 28 Jan 2025 00:07:49 +0100 Subject: refactor: code clean up --- src/ui/widgets/FileTreeView.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/ui/widgets/FileTreeView.cpp') diff --git a/src/ui/widgets/FileTreeView.cpp b/src/ui/widgets/FileTreeView.cpp index 20078e7c..86411d79 100644 --- a/src/ui/widgets/FileTreeView.cpp +++ b/src/ui/widgets/FileTreeView.cpp @@ -31,7 +31,7 @@ #include "core/utils/AsyncUtils.h" #include "core/utils/IOUtils.h" #include "ui/UISignalStation.h" -#include "ui/UserInterfaceUtils.h" +#include "ui/function/GpgOperaHelper.h" namespace GpgFrontend::UI { @@ -398,7 +398,7 @@ void FileTreeView::slot_calculate_hash() { if (GetSelectedPaths().empty()) return; auto selected_path = GetSelectedPaths().front(); - CommonUtils::WaitForOpera( + GpgOperaHelper::WaitForOpera( this->parentWidget(), tr("Calculating"), [=](const OperaWaitingHd& hd) { RunOperaAsync( [=](const DataObjectPtr& data_object) { -- cgit v1.2.3