From c3fc96dfe6233ea44d423d7af28f7b09060270f7 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Sun, 2 Jul 2023 12:56:41 +0800 Subject: [PATCH] Visually validate input path in torrent creator dialog PR #19245. --- src/gui/fspathedit.cpp | 10 ++++++++-- src/gui/fspathedit.h | 3 ++- src/gui/fspathedit_p.cpp | 21 ++++++++++++++++----- src/gui/fspathedit_p.h | 4 ++++ src/gui/torrentcreatordialog.cpp | 17 +++++++++-------- src/gui/torrentcreatordialog.ui | 10 +++++++++- 6 files changed, 48 insertions(+), 17 deletions(-) diff --git a/src/gui/fspathedit.cpp b/src/gui/fspathedit.cpp index 563bc6a1b..d620793a8 100644 --- a/src/gui/fspathedit.cpp +++ b/src/gui/fspathedit.cpp @@ -135,6 +135,8 @@ void FileSystemPathEdit::FileSystemPathEditPrivate::browseActionTriggered() newPath = QFileDialog::getExistingDirectory(q, dialogCaptionOrDefault(), initialDirectory.data(), QFileDialog::ShowDirsOnly); break; + case FileSystemPathEdit::Mode::ReadOnly: + throw std::logic_error("Not supported"); default: throw std::logic_error("Unknown FileSystemPathEdit mode"); } @@ -156,6 +158,8 @@ QString FileSystemPathEdit::FileSystemPathEditPrivate::dialogCaptionOrDefault() case FileSystemPathEdit::Mode::DirectoryOpen: case FileSystemPathEdit::Mode::DirectorySave: return defaultDialogCaptionForDirectory.tr(); + case FileSystemPathEdit::Mode::ReadOnly: + throw std::logic_error("Not supported"); default: throw std::logic_error("Unknown FileSystemPathEdit mode"); } @@ -163,11 +167,13 @@ QString FileSystemPathEdit::FileSystemPathEditPrivate::dialogCaptionOrDefault() void FileSystemPathEdit::FileSystemPathEditPrivate::modeChanged() { + m_browseBtn->setVisible(m_mode != FileSystemPathEdit::Mode::ReadOnly); m_editor->completeDirectoriesOnly((m_mode == FileSystemPathEdit::Mode::DirectoryOpen) || (m_mode == FileSystemPathEdit::Mode::DirectorySave)); - m_validator->setExistingOnly((m_mode == FileSystemPathEdit::Mode::FileOpen) || (m_mode == FileSystemPathEdit::Mode::DirectoryOpen)); + m_validator->setExistingOnly((m_mode == FileSystemPathEdit::Mode::FileOpen) || (m_mode == FileSystemPathEdit::Mode::DirectoryOpen) || (m_mode == FileSystemPathEdit::Mode::ReadOnly)); + m_validator->setFilesOnly((m_mode == FileSystemPathEdit::Mode::FileOpen) || (m_mode == FileSystemPathEdit::Mode::FileSave)); m_validator->setDirectoriesOnly((m_mode == FileSystemPathEdit::Mode::DirectoryOpen) || (m_mode == FileSystemPathEdit::Mode::DirectorySave)); - m_validator->setCheckReadPermission((m_mode == FileSystemPathEdit::Mode::FileOpen) || (m_mode == FileSystemPathEdit::Mode::DirectoryOpen)); + m_validator->setCheckReadPermission((m_mode == FileSystemPathEdit::Mode::FileOpen) || (m_mode == FileSystemPathEdit::Mode::DirectoryOpen) || (m_mode == FileSystemPathEdit::Mode::ReadOnly)); m_validator->setCheckWritePermission((m_mode == FileSystemPathEdit::Mode::FileSave) || (m_mode == FileSystemPathEdit::Mode::DirectorySave)); } diff --git a/src/gui/fspathedit.h b/src/gui/fspathedit.h index 34d2bcaa6..69ea2817d 100644 --- a/src/gui/fspathedit.h +++ b/src/gui/fspathedit.h @@ -63,7 +63,8 @@ public: FileOpen, //!< opening files, shows open file dialog FileSave, //!< saving files, shows save file dialog DirectoryOpen, //!< selecting existing directories - DirectorySave //!< selecting directories for saving + DirectorySave, //!< selecting directories for saving + ReadOnly //!< no browse button and no dialog, only validate path and check read permission }; Q_ENUM(Mode) diff --git a/src/gui/fspathedit_p.cpp b/src/gui/fspathedit_p.cpp index 7d2395c0c..d6f4031c9 100644 --- a/src/gui/fspathedit_p.cpp +++ b/src/gui/fspathedit_p.cpp @@ -66,6 +66,16 @@ void Private::FileSystemPathValidator::setExistingOnly(const bool value) m_existingOnly = value; } +bool Private::FileSystemPathValidator::filesOnly() const +{ + return m_filesOnly; +} + +void Private::FileSystemPathValidator::setFilesOnly(const bool value) +{ + m_filesOnly = value; +} + bool Private::FileSystemPathValidator::directoriesOnly() const { return m_directoriesOnly; @@ -105,16 +115,17 @@ Private::FileSystemPathValidator::testPath(const Path &path) const if (!info.exists()) return existingOnly() ? TestResult::DoesNotExist : TestResult::OK; + if (filesOnly()) + { + if (!info.isFile()) + return TestResult::NotAFile; + } + if (directoriesOnly()) { if (!info.isDir()) return TestResult::NotADir; } - else - { - if (!info.isFile()) - return TestResult::NotAFile; - } if (checkReadPermission() && !info.isReadable()) return TestResult::CantRead; diff --git a/src/gui/fspathedit_p.h b/src/gui/fspathedit_p.h index deb1fde2a..69592281b 100644 --- a/src/gui/fspathedit_p.h +++ b/src/gui/fspathedit_p.h @@ -68,6 +68,9 @@ namespace Private bool existingOnly() const; void setExistingOnly(bool value); + bool filesOnly() const; + void setFilesOnly(bool value); + bool directoriesOnly() const; void setDirectoriesOnly(bool value); @@ -87,6 +90,7 @@ namespace Private bool m_strictMode = false; bool m_existingOnly = false; + bool m_filesOnly = false; bool m_directoriesOnly = false; bool m_checkReadPermission = false; bool m_checkWritePermission = false; diff --git a/src/gui/torrentcreatordialog.cpp b/src/gui/torrentcreatordialog.cpp index 591786fc0..10ac7720b 100644 --- a/src/gui/torrentcreatordialog.cpp +++ b/src/gui/torrentcreatordialog.cpp @@ -81,6 +81,7 @@ TorrentCreatorDialog::TorrentCreatorDialog(QWidget *parent, const Path &defaultP m_ui->setupUi(this); m_ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Create Torrent")); + m_ui->textInputPath->setMode(FileSystemPathEdit::Mode::ReadOnly); connect(m_ui->addFileButton, &QPushButton::clicked, this, &TorrentCreatorDialog::onAddFileButtonClicked); connect(m_ui->addFolderButton, &QPushButton::clicked, this, &TorrentCreatorDialog::onAddFolderButtonClicked); @@ -111,13 +112,13 @@ TorrentCreatorDialog::~TorrentCreatorDialog() void TorrentCreatorDialog::updateInputPath(const Path &path) { if (path.isEmpty()) return; - m_ui->textInputPath->setText(path.toString()); + m_ui->textInputPath->setSelectedPath(path); updateProgressBar(0); } void TorrentCreatorDialog::onAddFolderButtonClicked() { - const QString oldPath = m_ui->textInputPath->text(); + const QString oldPath = m_ui->textInputPath->selectedPath().data(); const Path path {QFileDialog::getExistingDirectory(this, tr("Select folder") , oldPath, (QFileDialog::ShowDirsOnly | FILE_DIALOG_OPTIONS))}; updateInputPath(path); @@ -125,7 +126,7 @@ void TorrentCreatorDialog::onAddFolderButtonClicked() void TorrentCreatorDialog::onAddFileButtonClicked() { - const QString oldPath = m_ui->textInputPath->text(); + const QString oldPath = m_ui->textInputPath->selectedPath().data(); const Path path {QFileDialog::getOpenFileName(this, tr("Select file"), oldPath, QString(), nullptr, FILE_DIALOG_OPTIONS)}; updateInputPath(path); } @@ -185,9 +186,9 @@ void TorrentCreatorDialog::onCreateButtonClicked() { #ifdef Q_OS_WIN // Resolve the path in case it contains a shortcut (otherwise, the following usages will consider it invalid) - const auto inputPath = Utils::Fs::toCanonicalPath(Path(m_ui->textInputPath->text().trimmed())); + const Path inputPath = Utils::Fs::toCanonicalPath(m_ui->textInputPath->selectedPath()); #else - const auto inputPath = Path(m_ui->textInputPath->text().trimmed()); + const Path inputPath = m_ui->textInputPath->selectedPath(); #endif // test if readable @@ -280,7 +281,7 @@ void TorrentCreatorDialog::updateProgressBar(int progress) void TorrentCreatorDialog::updatePiecesCount() { - const Path path {m_ui->textInputPath->text().trimmed()}; + const Path path = m_ui->textInputPath->selectedPath(); #ifdef QBT_USES_LIBTORRENT2 const int count = BitTorrent::TorrentCreatorThread::calculateTotalPieces( path, getPieceSize(), getTorrentFormat()); @@ -316,7 +317,7 @@ void TorrentCreatorDialog::setInteractionEnabled(const bool enabled) const void TorrentCreatorDialog::saveSettings() { - m_storeLastAddPath = Path(m_ui->textInputPath->text().trimmed()); + m_storeLastAddPath = m_ui->textInputPath->selectedPath(); m_storePieceSize = m_ui->comboPieceSize->currentIndex(); m_storePrivateTorrent = m_ui->checkPrivate->isChecked(); @@ -339,7 +340,7 @@ void TorrentCreatorDialog::saveSettings() void TorrentCreatorDialog::loadSettings() { - m_ui->textInputPath->setText(m_storeLastAddPath.get(Utils::Fs::homePath()).toString()); + m_ui->textInputPath->setSelectedPath(m_storeLastAddPath.get(Utils::Fs::homePath())); m_ui->comboPieceSize->setCurrentIndex(m_storePieceSize); m_ui->checkPrivate->setChecked(m_storePrivateTorrent); diff --git a/src/gui/torrentcreatordialog.ui b/src/gui/torrentcreatordialog.ui index 90b931872..a0b8b5222 100644 --- a/src/gui/torrentcreatordialog.ui +++ b/src/gui/torrentcreatordialog.ui @@ -66,7 +66,7 @@ - + false @@ -470,6 +470,14 @@ + + + FileSystemPathLineEdit + QWidget +
gui/fspathedit.h
+ 1 +
+
textInputPath addFileButton