Visually validate input path in torrent creator dialog

PR #19245.
This commit is contained in:
Chocobo1 2023-07-02 12:56:41 +08:00 committed by GitHub
parent f4deb1050f
commit c3fc96dfe6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 48 additions and 17 deletions

View File

@ -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));
}

View File

@ -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)

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -66,7 +66,7 @@
</widget>
</item>
<item>
<widget class="QLineEdit" name="textInputPath">
<widget class="FileSystemPathLineEdit" name="textInputPath">
<property name="acceptDrops">
<bool>false</bool>
</property>
@ -470,6 +470,14 @@
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>FileSystemPathLineEdit</class>
<extends>QWidget</extends>
<header>gui/fspathedit.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>textInputPath</tabstop>
<tabstop>addFileButton</tabstop>