diff --git a/frontend/dialogs/OBSMissingFiles.cpp b/frontend/dialogs/OBSMissingFiles.cpp
index ca5d7a101..b1d6551b9 100644
--- a/frontend/dialogs/OBSMissingFiles.cpp
+++ b/frontend/dialogs/OBSMissingFiles.cpp
@@ -25,12 +25,6 @@
#include "moc_OBSMissingFiles.cpp"
-// TODO: Fix redefinition error of due to clash with enums defined in importer code.
-enum MissingFilesRole { EntryStateRole = Qt::UserRole, NewPathsToProcessRole };
-
-// TODO: Fix redefinition error of due to clash with enums defined in importer code.
-enum MissingFilesColumn { Source, OriginalPath, NewPath, State, Count };
-
OBSMissingFiles::OBSMissingFiles(obs_missing_files_t *files, QWidget *parent)
: QDialog(parent),
filesModel(new MissingFilesModel),
@@ -41,17 +35,14 @@ OBSMissingFiles::OBSMissingFiles(obs_missing_files_t *files, QWidget *parent)
ui->setupUi(this);
ui->tableView->setModel(filesModel);
- ui->tableView->setItemDelegateForColumn(MissingFilesColumn::OriginalPath,
- new MissingFilesPathItemDelegate(false, ""));
ui->tableView->setItemDelegateForColumn(MissingFilesColumn::NewPath,
new MissingFilesPathItemDelegate(true, ""));
- ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeMode::Stretch);
- ui->tableView->horizontalHeader()->setSectionResizeMode(MissingFilesColumn::Source,
- QHeaderView::ResizeMode::ResizeToContents);
- ui->tableView->horizontalHeader()->setMaximumSectionSize(width() / 3);
- ui->tableView->horizontalHeader()->setSectionResizeMode(MissingFilesColumn::State,
- QHeaderView::ResizeMode::ResizeToContents);
+ ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeMode::ResizeToContents);
+ ui->tableView->horizontalHeader()->setMaximumSectionSize(width() / 4);
+ ui->tableView->horizontalHeader()->setSectionResizeMode(MissingFilesColumn::NewPath,
+ QHeaderView::ResizeMode::Stretch);
ui->tableView->setEditTriggers(QAbstractItemView::EditTrigger::CurrentChanged);
+ ui->tableView->setWordWrap(false);
ui->warningIcon->setPixmap(filesModel->warningIcon.pixmap(QSize(32, 32)));
@@ -126,7 +117,7 @@ void OBSMissingFiles::browseFolders()
if (dir != "") {
dir += "/";
- filesModel->fileCheckLoop(filesModel->files, dir, true);
+ filesModel->findAllFilesInPath(dir, true);
}
}
diff --git a/frontend/forms/OBSMissingFiles.ui b/frontend/forms/OBSMissingFiles.ui
index 0d2b475ca..c637585c3 100644
--- a/frontend/forms/OBSMissingFiles.ui
+++ b/frontend/forms/OBSMissingFiles.ui
@@ -6,10 +6,16 @@
0
0
- 666
- 310
+ 700
+ 320
+
+
+ 700
+ 320
+
+
MissingFiles
diff --git a/frontend/utility/MissingFilesModel.cpp b/frontend/utility/MissingFilesModel.cpp
index b41d836ac..e2080ef8a 100644
--- a/frontend/utility/MissingFilesModel.cpp
+++ b/frontend/utility/MissingFilesModel.cpp
@@ -24,12 +24,6 @@
#include "moc_MissingFilesModel.cpp"
-// TODO: Fix redefinition error of due to clash with enums defined in importer code.
-enum MissingFilesRole { EntryStateRole = Qt::UserRole, NewPathsToProcessRole };
-
-// TODO: Fix redefinition error of due to clash with enums defined in importer code.
-enum MissingFilesColumn { Source, OriginalPath, NewPath, State, Count };
-
MissingFilesModel::MissingFilesModel(QObject *parent) : QAbstractTableModel(parent)
{
QStyle *style = QApplication::style();
@@ -160,86 +154,126 @@ Qt::ItemFlags MissingFilesModel::flags(const QModelIndex &index) const
return flags;
}
-void MissingFilesModel::fileCheckLoop(QList files, QString path, bool skipPrompt)
+void MissingFilesModel::findAllFilesInPath(const QString &path, bool skipPrompt)
{
- loop = false;
- QUrl url = QUrl().fromLocalFile(path);
+ allFilesFound = false;
+ fileCheckLoop(path, skipPrompt, 0);
+}
+
+void MissingFilesModel::fileCheckLoop(const QString &path, bool skipPrompt, int depth)
+{
+ if (allFilesFound) {
+ return;
+ }
+
+ if (files.length() == found()) {
+ allFilesFound = true;
+ return;
+ }
+
+ recursionLevel += 1;
+ QUrl url = QUrl::fromLocalFile(path);
QString dir = url.toDisplayString(QUrl::RemoveScheme | QUrl::RemoveFilename | QUrl::PreferLocalFile);
bool prompted = skipPrompt;
+ int depthWithoutFileMatch = depth + 1;
- for (int i = 0; i < files.length(); i++) {
- if (files[i].state != MissingFilesState::Missing)
+ int loopIndex = -1;
+ for (const MissingFileEntry &file : files) {
+ loopIndex++;
+
+ if (file.state != MissingFilesState::Missing) {
continue;
+ }
- QUrl origFile = QUrl().fromLocalFile(files[i].originalPath);
+ QUrl origFile = QUrl::fromLocalFile(file.originalPath);
QString filename = origFile.fileName();
QString testFile = dir + filename;
if (os_file_exists(testFile.toStdString().c_str())) {
+ depthWithoutFileMatch = 0;
+
if (!prompted) {
QMessageBox::StandardButton button =
QMessageBox::question(nullptr, QTStr("MissingFiles.AutoSearch"),
QTStr("MissingFiles.AutoSearchText"));
- if (button == QMessageBox::No)
+ if (button == QMessageBox::No) {
break;
+ }
prompted = true;
}
- QModelIndex in = index(i, MissingFilesColumn::NewPath);
- setData(in, testFile, 0);
+ QModelIndex in = index(loopIndex, MissingFilesColumn::NewPath);
+ setData(in, testFile, Qt::DisplayRole);
}
}
- loop = true;
+
+ if (depthWithoutFileMatch <= 2) {
+ os_dir_t *folder = os_opendir(dir.toStdString().c_str());
+ struct os_dirent *ent;
+ while ((ent = os_readdir(folder)) != NULL) {
+ if (!ent->directory || *ent->d_name == '.')
+ continue;
+
+ QString directoryPath = dir + QString(ent->d_name) + "/";
+ fileCheckLoop(directoryPath, true, depthWithoutFileMatch);
+ }
+
+ os_closedir(folder);
+ }
+ recursionLevel -= 1;
}
bool MissingFilesModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
bool success = false;
+ int row = index.row();
+ QString valueString = value.toString();
+
if (role == MissingFilesRole::NewPathsToProcessRole) {
QStringList list = value.toStringList();
- int row = index.row() + 1;
- beginInsertRows(QModelIndex(), row, row);
+ int newRow = row + 1;
+ beginInsertRows(QModelIndex(), newRow, newRow);
MissingFileEntry entry;
entry.originalPath = list[0].replace("\\", "/");
entry.source = list[1];
- files.insert(row, entry);
- row++;
+ files.insert(newRow, entry);
endInsertRows();
success = true;
- } else {
- QString path = value.toString();
- if (index.column() == MissingFilesColumn::NewPath) {
- files[index.row()].newPath = value.toString();
- QString fileName = QUrl(path).fileName();
- QString origFileName = QUrl(files[index.row()].originalPath).fileName();
+ } else if (index.column() == MissingFilesColumn::NewPath && files[row].newPath != valueString) {
+ QString path = valueString;
+ files[row].newPath = valueString;
+ QString fileName = QUrl(path).fileName();
+ QString origFileName = QUrl(files[row].originalPath).fileName();
- if (path.isEmpty()) {
- files[index.row()].state = MissingFilesState::Missing;
- } else if (path.compare(QTStr("MissingFiles.Clear")) == 0) {
- files[index.row()].state = MissingFilesState::Cleared;
- } else if (fileName.compare(origFileName) == 0) {
- files[index.row()].state = MissingFilesState::Found;
+ if (path.isEmpty()) {
+ files[row].state = MissingFilesState::Missing;
+ } else if (path.compare(QTStr("MissingFiles.Clear")) == 0) {
+ files[row].state = MissingFilesState::Cleared;
+ } else if (fileName.compare(origFileName) == 0) {
+ files[row].state = MissingFilesState::Found;
- if (loop)
- fileCheckLoop(files, path, false);
- } else {
- files[index.row()].state = MissingFilesState::Replaced;
-
- if (loop)
- fileCheckLoop(files, path, false);
+ if (recursionLevel == 0) {
+ findAllFilesInPath(path, false);
}
+ } else {
+ files[row].state = MissingFilesState::Replaced;
- emit dataChanged(index, index);
- success = true;
+ if (recursionLevel == 0) {
+ findAllFilesInPath(path, false);
+ }
}
+
+ emit dataChanged(index, index);
+
+ success = true;
}
return success;
diff --git a/frontend/utility/MissingFilesModel.hpp b/frontend/utility/MissingFilesModel.hpp
index 4b7057e84..66ec36ea8 100644
--- a/frontend/utility/MissingFilesModel.hpp
+++ b/frontend/utility/MissingFilesModel.hpp
@@ -20,6 +20,12 @@
#include
#include
+// TODO: Fix redefinition error of due to clash with enums defined in importer code.
+enum MissingFilesRole { EntryStateRole = Qt::UserRole, NewPathsToProcessRole };
+
+// TODO: Fix redefinition error of due to clash with enums defined in importer code.
+enum MissingFilesColumn { Source, OriginalPath, NewPath, State, Count };
+
enum MissingFilesState { Missing, Found, Replaced, Cleared };
Q_DECLARE_METATYPE(MissingFilesState);
@@ -40,7 +46,8 @@ public:
Qt::ItemFlags flags(const QModelIndex &index) const;
bool setData(const QModelIndex &index, const QVariant &value, int role);
- bool loop = true;
+ bool allFilesFound = false;
+ int recursionLevel = 0;
QIcon warningIcon;
@@ -56,5 +63,6 @@ private:
QList files;
- void fileCheckLoop(QList files, QString path, bool skipPrompt);
+ void findAllFilesInPath(const QString &path, bool skipPrompt);
+ void fileCheckLoop(const QString &path, bool skipPrompt, int depth);
};
diff --git a/frontend/utility/MissingFilesPathItemDelegate.cpp b/frontend/utility/MissingFilesPathItemDelegate.cpp
index f1e722511..8bba2b0c8 100644
--- a/frontend/utility/MissingFilesPathItemDelegate.cpp
+++ b/frontend/utility/MissingFilesPathItemDelegate.cpp
@@ -124,6 +124,12 @@ void MissingFilesPathItemDelegate::paint(QPainter *painter, const QStyleOptionVi
QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &localOption, painter);
}
+void MissingFilesPathItemDelegate::initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const
+{
+ QStyledItemDelegate::initStyleOption(option, index);
+ option->textElideMode = Qt::ElideMiddle;
+}
+
void MissingFilesPathItemDelegate::handleBrowse(QWidget *container)
{
diff --git a/frontend/utility/MissingFilesPathItemDelegate.hpp b/frontend/utility/MissingFilesPathItemDelegate.hpp
index 8b9606226..c1a602944 100644
--- a/frontend/utility/MissingFilesPathItemDelegate.hpp
+++ b/frontend/utility/MissingFilesPathItemDelegate.hpp
@@ -33,6 +33,9 @@ public:
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const override;
+protected:
+ void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const override;
+
private:
bool isOutput;
QString defaultPath;