GUI: mux: optionally add one tab per dropped directory & add directory's files in it

Implements #3371.
This commit is contained in:
Moritz Bunkus 2022-08-13 15:06:04 +02:00
parent 86e3b058bc
commit 6e73088174
No known key found for this signature in database
GPG Key ID: 74AF00ADF2E32C85
16 changed files with 487 additions and 56 deletions

View File

@ -9,6 +9,10 @@
only want to relocate the preferences INI file, you can store the desired
file name for the INI file in `MKVTOOLNIX_GUI_CONFIG_FILE`. Implements
#3382.
* MKVToolNix GUI: when adding directories via drag & drop/copy & paste the GUI
will now offer the user the option to create one multiplex settings tab per
directory & adding all files from that directory to the corresponding, newly
created tab. Implements #3371.
## Bug fixes

View File

@ -727,8 +727,18 @@
<layout class="QVBoxLayout" name="verticalLayout_43">
<item>
<layout class="QGridLayout" name="gridLayout_10">
<item row="0" column="1">
<widget class="QComboBox" name="cbMAddingAppendingFilesPolicy">
<item row="1" column="0">
<widget class="QLabel" name="label_23">
<property name="text">
<string>When adding files via &amp;drag &amp;&amp; drop/copy &amp;&amp; paste:</string>
</property>
<property name="buddy">
<cstring>cbMDragAndDropFilesPolicy</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="cbMDragAndDropFilesPolicy">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
@ -747,18 +757,28 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_23">
<property name="text">
<string>When adding files via &amp;drag &amp;&amp; drop/copy &amp;&amp; paste:</string>
</property>
<property name="buddy">
<cstring>cbMDragAndDropFilesPolicy</cstring>
<item row="0" column="1">
<widget class="QComboBox" name="cbMAddingAppendingFilesPolicy">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="cbMDragAndDropFilesPolicy">
<item row="2" column="0">
<widget class="QLabel" name="label_25">
<property name="text">
<string>When adding d&amp;irectories via drag &amp;&amp; drop/copy &amp;&amp; paste:</string>
</property>
<property name="buddy">
<cstring>cbMDragAndDropDirectoriesPolicy</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="cbMDragAndDropDirectoriesPolicy">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
@ -2632,6 +2652,7 @@
<tabstop>pbMBrowseMediaInfoExe</tabstop>
<tabstop>cbMAddingAppendingFilesPolicy</tabstop>
<tabstop>cbMDragAndDropFilesPolicy</tabstop>
<tabstop>cbMDragAndDropDirectoriesPolicy</tabstop>
<tabstop>cbMAlwaysCreateSettingsForVideoFiles</tabstop>
<tabstop>cbMSortFilesTracksByTypeWhenAdding</tabstop>
<tabstop>cbMReconstructSequencesWhenAdding</tabstop>

View File

@ -0,0 +1,173 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>mtx::gui::Merge::AddingDirectoriesDialog</class>
<widget class="QDialog" name="mtx::gui::Merge::AddingDirectoriesDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>691</width>
<height>232</height>
</rect>
</property>
<property name="windowTitle">
<string>Adding directories via drag &amp; drop or copy &amp; paste</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="lTitle">
<property name="minimumSize">
<size>
<width>600</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Adding directories via drag &amp; drop or copy &amp; paste</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lQuestion">
<property name="text">
<string>You've dragged &amp; dropped or copied &amp; pasted at least one directory. There are several ways to handle them:</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lOptions">
<property name="text">
<string notr="true">text</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbFlat">
<property name="text">
<string>&amp;Handle all files from all directories as a single list of files</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbAddEachDirectoryToNew">
<property name="text">
<string>&amp;Create a new multiplex settings tab for each directory</string>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cbAlwaysUseThisDecision">
<property name="text">
<string>Alwa&amp;ys use the action selected above and don't ask again</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<tabstops>
<tabstop>rbFlat</tabstop>
<tabstop>rbAddEachDirectoryToNew</tabstop>
<tabstop>cbAlwaysUseThisDecision</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>mtx::gui::Merge::AddingDirectoriesDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>521</x>
<y>310</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>mtx::gui::Merge::AddingDirectoriesDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>588</x>
<y>316</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -19,6 +19,7 @@
#include "mkvtoolnix-gui/main_window/preferences_dialog.h"
#include "mkvtoolnix-gui/main_window/prefs_language_shortcut_dialog.h"
#include "mkvtoolnix-gui/main_window/prefs_run_program_widget.h"
#include "mkvtoolnix-gui/merge/adding_directories_dialog.h"
#include "mkvtoolnix-gui/merge/additional_command_line_options_dialog.h"
#include "mkvtoolnix-gui/merge/source_file.h"
#include "mkvtoolnix-gui/util/container.h"
@ -123,6 +124,7 @@ PreferencesDialog::PreferencesDialog(QWidget *parent,
setupEnableMuxingTracksByType();
setupEnableMuxingTracksByLanguage();
setupMergeAddingAppendingFilesPolicy();
setupMergeAddingAppendingDirectoriesPolicy();
setupMergeWarnMissingAudioTrack();
setupMergePredefinedItems();
setupTrackPropertiesLayout();
@ -429,6 +431,16 @@ PreferencesDialog::setupToolTips() {
.arg(QY("The default is to always add all the files to the current multiplex settings."))
.arg(QY("The GUI can also ask the user what to do each time, e.g. appending them instead of adding them, or creating new multiplex settings and adding them to those.")));
QString fullText;
for (auto const &text : Merge::AddingDirectoriesDialog::optionDescriptions())
fullText += Q("<li>%1</li>").arg(text.toHtmlEscaped());
Util::setToolTip(ui->cbMDragAndDropDirectoriesPolicy,
Q("<p>%1</p><ol>%2</ol>")
.arg(QY("When the user drags & drops directories from an external application onto the multiplex tool the GUI can take different actions."))
.arg(fullText));
Util::setToolTip(ui->cbMWarnMissingAudioTrack, QY("The GUI can ask for confirmation when you're about to create a file without audio tracks in it."));
Util::setToolTip(ui->cbMDeriveAudioTrackLanguageFromFileName,
@ -778,6 +790,19 @@ PreferencesDialog::setupMergeAddingAppendingFilesPolicy() {
ui->cbMAlwaysCreateSettingsForVideoFiles->setChecked(m_cfg.m_mergeAlwaysCreateNewSettingsForVideoFiles);
}
void
PreferencesDialog::setupMergeAddingAppendingDirectoriesPolicy() {
ui->cbMDragAndDropDirectoriesPolicy->addItem(QY("Always ask the user"), static_cast<int>(Util::Settings::MergeAddingDirectoriesPolicy::Ask));
ui->cbMDragAndDropDirectoriesPolicy->addItem(QY("Handle all files from all directories as a single list of files"), static_cast<int>(Util::Settings::MergeAddingDirectoriesPolicy::Flat));
ui->cbMDragAndDropDirectoriesPolicy->addItem(QY("Create a new multiplex settings tab for each directory"), static_cast<int>(Util::Settings::MergeAddingDirectoriesPolicy::AddEachDirectoryToNew));
Util::setComboBoxIndexIf(ui->cbMDragAndDropDirectoriesPolicy, [this](QString const &, QVariant const &data) {
return data.isValid() && (static_cast<Util::Settings::MergeAddingDirectoriesPolicy>(data.toInt()) == m_cfg.m_mergeDragAndDropDirectoriesPolicy);
});
Util::fixComboBoxViewWidth(*ui->cbMDragAndDropDirectoriesPolicy);
}
void
PreferencesDialog::setupMergeWarnMissingAudioTrack() {
ui->cbMWarnMissingAudioTrack->addItem(QY("Never"), static_cast<int>(Util::Settings::MergeMissingAudioTrackPolicy::Never));
@ -1094,6 +1119,7 @@ PreferencesDialog::save() {
m_cfg.m_mergeEnableDialogNormGainRemoval = ui->cbMEnableDialogNormGainRemoval->isChecked();
m_cfg.m_mergeAddingAppendingFilesPolicy = static_cast<Util::Settings::MergeAddingAppendingFilesPolicy>(ui->cbMAddingAppendingFilesPolicy->currentData().toInt());
m_cfg.m_mergeDragAndDropFilesPolicy = static_cast<Util::Settings::MergeAddingAppendingFilesPolicy>(ui->cbMDragAndDropFilesPolicy->currentData().toInt());
m_cfg.m_mergeDragAndDropDirectoriesPolicy = static_cast<Util::Settings::MergeAddingDirectoriesPolicy>(ui->cbMDragAndDropDirectoriesPolicy->currentData().toInt());
m_cfg.m_mergeAlwaysCreateNewSettingsForVideoFiles = ui->cbMAlwaysCreateSettingsForVideoFiles->isChecked();
m_cfg.m_mergeSortFilesTracksByTypeWhenAdding = ui->cbMSortFilesTracksByTypeWhenAdding->isChecked();
m_cfg.m_mergeReconstructSequencesWhenAdding = ui->cbMReconstructSequencesWhenAdding->isChecked();

View File

@ -118,6 +118,7 @@ protected:
void setupEnableMuxingTracksByType();
void setupEnableMuxingTracksByLanguage();
void setupMergeAddingAppendingFilesPolicy();
void setupMergeAddingAppendingDirectoriesPolicy();
void setupMergeWarnMissingAudioTrack();
void setupMergePredefinedItems();
void setupHeaderEditorDroppedFilesPolicy();

View File

@ -0,0 +1,67 @@
#include "common/common_pch.h"
#include <QFileInfo>
#include <QPushButton>
#include "common/qt.h"
#include "mkvtoolnix-gui/forms/merge/adding_directories_dialog.h"
#include "mkvtoolnix-gui/merge/adding_directories_dialog.h"
#include "mkvtoolnix-gui/merge/tab.h"
namespace mtx::gui::Merge {
using namespace mtx::gui;
AddingDirectoriesDialog::AddingDirectoriesDialog(QWidget *parent,
Util::Settings::MergeAddingDirectoriesPolicy decision)
: QDialog{parent}
, ui{new Ui::AddingDirectoriesDialog}
{
// Setup UI controls.
ui->setupUi(this);
if (decision == Util::Settings::MergeAddingDirectoriesPolicy::AddEachDirectoryToNew)
ui->rbAddEachDirectoryToNew->setChecked(true);
else
ui->rbFlat->setChecked(true);
QString fullText;
for (auto const &text : optionDescriptions())
fullText += Q("<li>%1</li>").arg(text.toHtmlEscaped());
ui->lOptions->setText(Q("<ol>%1</ol>").arg(fullText));
adjustSize();
connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &AddingDirectoriesDialog::accept);
connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &AddingDirectoriesDialog::reject);
}
AddingDirectoriesDialog::~AddingDirectoriesDialog() {
}
QStringList
AddingDirectoriesDialog::optionDescriptions() {
QStringList texts;
texts << QY("The program can collect all files from all directories in a single list. What happens with that list is determined by how dragging & dropping/copying & pasting files is configured.");
texts << QY("For each directory a new multiplex settings tab can be created. All files from that directory will be added to this new tab. The configuration about dragging & dropping/copying & pasting files is ignored in this case.");
return texts;
}
Util::Settings::MergeAddingDirectoriesPolicy
AddingDirectoriesDialog::decision()
const {
return ui->rbFlat->isChecked() ? Util::Settings::MergeAddingDirectoriesPolicy::Flat
: Util::Settings::MergeAddingDirectoriesPolicy::AddEachDirectoryToNew;
}
bool
AddingDirectoriesDialog::alwaysUseThisDecision()
const {
return ui->cbAlwaysUseThisDecision->isEnabled() && ui->cbAlwaysUseThisDecision->isChecked();
}
}

View File

@ -0,0 +1,33 @@
#pragma once
#include "common/common_pch.h"
#include <QDialog>
#include "mkvtoolnix-gui/util/settings.h"
namespace mtx::gui::Merge {
class Tab;
namespace Ui {
class AddingDirectoriesDialog;
}
class AddingDirectoriesDialog : public QDialog {
Q_OBJECT
protected:
std::unique_ptr<Ui::AddingDirectoriesDialog> ui;
public:
explicit AddingDirectoriesDialog(QWidget *parent, Util::Settings::MergeAddingDirectoriesPolicy decision);
~AddingDirectoriesDialog();
Util::Settings::MergeAddingDirectoriesPolicy decision() const;
bool alwaysUseThisDecision() const;
public:
static QStringList optionDescriptions();
};
}

View File

@ -12,7 +12,7 @@ using SourceFilePtr = std::shared_ptr<SourceFile>;
struct IdentificationPack {
enum class FileType { Regular, Chapters, Tags, SegmentInfo };
enum class AddMode { UserChoice, Add, Append };
enum class AddMode { UserChoice, Add, Append, AddDontAsk };
struct IdentifiedFile {
FileType m_type{FileType::Regular};

View File

@ -1,6 +1,8 @@
#include "common/common_pch.h"
#include <QClipboard>
#include <QDir>
#include <QDirIterator>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QFileInfo>
@ -9,6 +11,7 @@
#include <QProgressDialog>
#include "common/bluray/util.h"
#include "common/fs_sys_helpers.h"
#include "common/path.h"
#include "common/qt.h"
#include "mkvtoolnix-gui/app.h"
@ -16,6 +19,7 @@
#include "mkvtoolnix-gui/forms/main_window/main_window.h"
#include "mkvtoolnix-gui/jobs/tool.h"
#include "mkvtoolnix-gui/merge/adding_appending_files_dialog.h"
#include "mkvtoolnix-gui/merge/adding_directories_dialog.h"
#include "mkvtoolnix-gui/merge/ask_scan_for_playlists_dialog.h"
#include "mkvtoolnix-gui/merge/file_identification_thread.h"
#include "mkvtoolnix-gui/merge/file_identification_pack.h"
@ -45,6 +49,53 @@ qHash(std::filesystem::path const &path) {
namespace mtx::gui::Merge {
namespace {
struct ResolvedDirectories {
using Dir = std::pair<QString, QStringList>;
QVector<Dir> m_directories;
QStringList m_files;
};
ResolvedDirectories
resolveDirectoriesToContainedFilesAndDirectories(QStringList const &namesToCheck) {
ResolvedDirectories resolvedDirs;
for (auto const &nameToCheck : namesToCheck) {
auto info = QFileInfo{nameToCheck};
if (!info.exists())
continue;
if (info.isFile()) {
resolvedDirs.m_files << nameToCheck;
continue;
}
if (!info.isDir())
continue;
QStringList newFileNames;
QDirIterator it{nameToCheck, QDirIterator::Subdirectories};
while (it.hasNext()) {
it.next();
info = it.fileInfo();
if (info.isFile())
newFileNames << info.absoluteFilePath();
}
newFileNames.sort(Qt::CaseInsensitive);
if (!newFileNames.isEmpty())
resolvedDirs.m_directories << std::make_pair(nameToCheck, newFileNames);
}
return resolvedDirs;
}
}
using namespace mtx::gui;
class ToolPrivate {
@ -710,10 +761,12 @@ Tool::handleIdentifiedSourceFiles(IdentificationPack &pack) {
retrieveDiscInformationForPlaylists(identifiedSourceFiles);
if ( (pack.m_addMode == IdentificationPack::AddMode::Append)
|| (pack.m_addMode == IdentificationPack::AddMode::AddDontAsk)
|| ( (identifiedSourceFiles.count() == 1)
&& ( tab->isEmpty()
|| (pack.m_addMode == IdentificationPack::AddMode::Add)))) {
tab->addOrAppendIdentifiedFiles(identifiedSourceFiles, pack.m_sourceFileIdx, pack.m_addMode);
auto addMode = pack.m_addMode == IdentificationPack::AddMode::AddDontAsk ? IdentificationPack::AddMode::Add : pack.m_addMode;
tab->addOrAppendIdentifiedFiles(identifiedSourceFiles, pack.m_sourceFileIdx, addMode);
return;
}
@ -796,11 +849,34 @@ Tool::handleIdentifiedFiles(IdentificationPack identifiedFiles) {
handleIdentifiedSourceFiles(identifiedFiles);
}
std::optional<Util::Settings::MergeAddingDirectoriesPolicy>
Tool::determineAddingDirectoriesPolicy() {
auto &settings = Util::Settings::get();
auto policy = settings.m_mergeDragAndDropDirectoriesPolicy;
if (policy != Util::Settings::MergeAddingDirectoriesPolicy::Ask)
return policy;
AddingDirectoriesDialog dlg{this, policy};
if (!dlg.exec())
return {};
policy = dlg.decision();
if (dlg.alwaysUseThisDecision()) {
settings.m_mergeDragAndDropDirectoriesPolicy = policy;
settings.save();
}
return policy;
}
void
Tool::identifyMultipleFiles(QStringList const &fileNamesToIdentify,
Qt::MouseButtons mouseButtons) {
auto &p = *p_func();
auto fileNames = Util::replaceDirectoriesByContainedFiles(fileNamesToIdentify);
Tool::addFileIdentificationPack(QStringList const &fileNames,
IdentificationPack::AddMode addMode,
Qt::MouseButtons mouseButtons) {
auto &p = *p_func();
if (fileNames.isEmpty())
return;
@ -808,11 +884,56 @@ Tool::identifyMultipleFiles(QStringList const &fileNamesToIdentify,
IdentificationPack pack;
pack.m_tabId = reinterpret_cast<uint64_t>(currentTab());
pack.m_fileNames = fileNames;
pack.m_addMode = addMode;
pack.m_mouseButtons = mouseButtons;
qDebug() << "tabId" << pack.m_tabId << pack.m_fileNames;
p.identifier->worker().addPackToIdentify(pack);
}
void
Tool::identifyMultipleFiles(QStringList const &fileNamesToIdentify,
Qt::MouseButtons mouseButtons) {
auto resolvedDirs = resolveDirectoriesToContainedFilesAndDirectories(fileNamesToIdentify);
if (resolvedDirs.m_files.isEmpty() && resolvedDirs.m_directories.isEmpty())
return;
if (resolvedDirs.m_directories.isEmpty()) {
addFileIdentificationPack(resolvedDirs.m_files, IdentificationPack::AddMode::UserChoice, mouseButtons);
return;
}
auto policyOpt = determineAddingDirectoriesPolicy();
if (!policyOpt)
return;
auto policy = *policyOpt;
if (policy == Util::Settings::MergeAddingDirectoriesPolicy::Flat) {
auto fileNames = resolvedDirs.m_files;
for (auto const &dir : resolvedDirs.m_directories)
fileNames += dir.second;
addFileIdentificationPack(fileNames, IdentificationPack::AddMode::UserChoice, mouseButtons);
return;
}
if (!currentTab())
appendNewTab();
addFileIdentificationPack(resolvedDirs.m_files, IdentificationPack::AddMode::UserChoice, mouseButtons);
// Util::Settings::MergeAddingDirectoriesPolicy::AddEachDirectoryToNew
for (auto const &dir : resolvedDirs.m_directories) {
appendNewTab();
addFileIdentificationPack(dir.second, IdentificationPack::AddMode::AddDontAsk, mouseButtons);
}
}
void
Tool::fileIdentificationStarted() {
p_func()->ui->overlordWidget->setEnabled(false);

View File

@ -5,6 +5,7 @@
#include "mkvtoolnix-gui/main_window/tool_base.h"
#include "mkvtoolnix-gui/merge/file_identification_thread.h"
#include "mkvtoolnix-gui/merge/source_file.h"
#include "mkvtoolnix-gui/util/settings.h"
class QDragEnterEvent;
class QDragMoveEvent;
@ -105,6 +106,8 @@ protected:
virtual void enableCopyMenuActions();
virtual void showMergeWidget();
virtual std::optional<Util::Settings::MergeAddingDirectoriesPolicy> determineAddingDirectoriesPolicy();
virtual void addFileIdentificationPack(QStringList const &fileNames, IdentificationPack::AddMode addMode, Qt::MouseButtons mouseButtons);
virtual QStringList fileNamesFromClipboard() const;
virtual void dragEnterEvent(QDragEnterEvent *event) override;

View File

@ -40,6 +40,7 @@ FORMS += \
forms/main_window/select_character_set_dialog.ui \
forms/main_window/status_bar_progress_widget.ui \
forms/merge/adding_appending_files_dialog.ui \
forms/merge/adding_directories_dialog.ui \
forms/merge/additional_command_line_options_dialog.ui \
forms/merge/ask_scan_for_playlists_dialog.ui \
forms/merge/command_line_dialog.ui \

View File

@ -1,8 +1,6 @@
#include "common/common_pch.h"
#include <QByteArray>
#include <QDir>
#include <QDirIterator>
#include <QFile>
#include <QFileInfo>
#include <QIODevice>
@ -90,41 +88,6 @@ replaceInvalidFileNameCharacters(QString fileName) {
return fileName;
}
QStringList
replaceDirectoriesByContainedFiles(QStringList const &namesToCheck) {
QStringList fileNames;
for (auto const &nameToCheck : namesToCheck) {
auto info = QFileInfo{nameToCheck};
if (!info.exists())
continue;
if (info.isFile()) {
fileNames << nameToCheck;
continue;
}
if (!info.isDir())
continue;
QStringList newFileNames;
QDirIterator it{nameToCheck, QDirIterator::Subdirectories};
while (it.hasNext()) {
it.next();
info = it.fileInfo();
if (info.isFile())
newFileNames << info.absoluteFilePath();
}
newFileNames.sort(Qt::CaseInsensitive);
fileNames += newFileNames;
}
return fileNames;
}
QString
detectMIMEType(QString const &fileName) {
auto mimeType = ::mtx::mime::guess_type_for_file(to_utf8(fileName));

View File

@ -20,8 +20,6 @@ QUrl pathToFileUrl(QString const &path);
QString removeInvalidPathCharacters(QString fileName);
QString replaceInvalidFileNameCharacters(QString fileName);
QStringList replaceDirectoriesByContainedFiles(QStringList const &namesToCheck);
QString detectMIMEType(QString const &fileName);
}

View File

@ -547,6 +547,7 @@ Settings::load() {
m_mergeAddingAppendingFilesPolicy = static_cast<MergeAddingAppendingFilesPolicy>(reg.value(s_valMergeAddingAppendingFilesPolicy, static_cast<int>(MergeAddingAppendingFilesPolicy::Ask)).toInt());
m_mergeLastAddingAppendingDecision = static_cast<MergeAddingAppendingFilesPolicy>(reg.value(s_valMergeLastAddingAppendingDecision, static_cast<int>(MergeAddingAppendingFilesPolicy::Add)).toInt());
m_mergeDragAndDropFilesPolicy = static_cast<MergeAddingAppendingFilesPolicy>(reg.value(s_valMergeDragAndDropFilesPolicy, static_cast<int>(MergeAddingAppendingFilesPolicy::Ask)).toInt());
m_mergeDragAndDropDirectoriesPolicy = toMergeAddingDirectoriesPolicy(reg.value(s_valMergeDragAndDropDirectoriesPolicy, static_cast<int>(MergeAddingDirectoriesPolicy::Ask)).toInt());
m_mergeLastDragAndDropFilesDecision = static_cast<MergeAddingAppendingFilesPolicy>(reg.value(s_valMergeLastDragAndDropFilesDecision, static_cast<int>(MergeAddingAppendingFilesPolicy::Add)).toInt());
m_mergeWarnMissingAudioTrack = static_cast<MergeMissingAudioTrackPolicy>(reg.value(s_valMergeWarnMissingAudioTrack, static_cast<int>(MergeMissingAudioTrackPolicy::IfAudioTrackPresent)).toInt());
m_headerEditorDroppedFilesPolicy = static_cast<HeaderEditorDroppedFilesPolicy>(reg.value(s_valHeaderEditorDroppedFilesPolicy, static_cast<int>(HeaderEditorDroppedFilesPolicy::Ask)).toInt());
@ -987,6 +988,7 @@ Settings::save()
reg.setValue(s_valMergeAddingAppendingFilesPolicy, static_cast<int>(m_mergeAddingAppendingFilesPolicy));
reg.setValue(s_valMergeLastAddingAppendingDecision, static_cast<int>(m_mergeLastAddingAppendingDecision));
reg.setValue(s_valMergeDragAndDropFilesPolicy, static_cast<int>(m_mergeDragAndDropFilesPolicy));
reg.setValue(s_valMergeDragAndDropDirectoriesPolicy, static_cast<int>(m_mergeDragAndDropDirectoriesPolicy));
reg.setValue(s_valMergeLastDragAndDropFilesDecision, static_cast<int>(m_mergeLastDragAndDropFilesDecision));
reg.setValue(s_valMergeWarnMissingAudioTrack, static_cast<int>(m_mergeWarnMissingAudioTrack));
reg.setValue(s_valHeaderEditorDroppedFilesPolicy, static_cast<int>(m_headerEditorDroppedFilesPolicy));
@ -1405,4 +1407,11 @@ Settings::nthFileColor(int idx)
return s_additionalColors.at(idx);
}
Settings::MergeAddingDirectoriesPolicy
Settings::toMergeAddingDirectoriesPolicy(int value) {
return value == static_cast<int>(MergeAddingDirectoriesPolicy::Flat) ? MergeAddingDirectoriesPolicy::Flat
: value == static_cast<int>(MergeAddingDirectoriesPolicy::AddEachDirectoryToNew) ? MergeAddingDirectoriesPolicy::AddEachDirectoryToNew
: MergeAddingDirectoriesPolicy::Ask;
}
}

View File

@ -113,6 +113,13 @@ public:
};
Q_ENUM(MergeAddingAppendingFilesPolicy);
enum class MergeAddingDirectoriesPolicy {
Ask,
Flat,
AddEachDirectoryToNew,
};
Q_ENUM(MergeAddingDirectoriesPolicy);
enum class HeaderEditorDroppedFilesPolicy {
Ask,
Open,
@ -190,6 +197,7 @@ public:
bool m_mergeEnableDialogNormGainRemoval, m_mergeAddBlurayCovers, m_mergeAttachmentsAlwaysSkipForExistingName;
ClearMergeSettingsAction m_clearMergeSettings;
MergeAddingAppendingFilesPolicy m_mergeDragAndDropFilesPolicy, m_mergeLastDragAndDropFilesDecision, m_mergeAddingAppendingFilesPolicy, m_mergeLastAddingAppendingDecision;
MergeAddingDirectoriesPolicy m_mergeDragAndDropDirectoriesPolicy;
bool m_mergeAlwaysCreateNewSettingsForVideoFiles, m_mergeSortFilesTracksByTypeWhenAdding, m_mergeReconstructSequencesWhenAdding;
HeaderEditorDroppedFilesPolicy m_headerEditorDroppedFilesPolicy;
bool m_headerEditorDateTimeInUTC;
@ -315,6 +323,8 @@ public:
static QString defaultBoundaryCharsForDerivingLanguageFromFileName();
static QVector<QColor> defaultFileColors();
static MergeAddingDirectoriesPolicy toMergeAddingDirectoriesPolicy(int value);
};
}

View File

@ -74,6 +74,7 @@ char const * const s_valMergeAlwaysAddDroppedFiles = "mergeAlways
char const * const s_valMergeAlwaysCreateNewSettingsForVideoFiles = "mergeAlwaysCreateNewSettingsForVideoFiles";
char const * const s_valMergeAlwaysShowOutputFileControls = "mergeAlwaysShowOutputFileControls";
char const * const s_valMergeAttachmentsAlwaysSkipForExistingName = "mergeAttachmentsAlwaysSkipForExistingName";
char const * const s_valMergeDragAndDropDirectoriesPolicy = "mergeDragAndDropDirectoriesPolicy";
char const * const s_valMergeDragAndDropFilesPolicy = "mergeDragAndDropFilesPolicy";
char const * const s_valMergeEnableDialogNormGainRemoval = "mergeEnableDialogNormGainRemoval";
char const * const s_valMergeFileColors = "mergeFileColors";