From 36e3489d867c5aacd51eadbb010c02805c0cb08f Mon Sep 17 00:00:00 2001 From: Warchamp7 Date: Sun, 23 Feb 2025 12:15:26 -0500 Subject: [PATCH] frontend: Adjust missing files dialog --- frontend/dialogs/OBSMissingFiles.cpp | 21 +--- frontend/forms/OBSMissingFiles.ui | 10 +- frontend/utility/MissingFilesModel.cpp | 116 +++++++++++------- frontend/utility/MissingFilesModel.hpp | 12 +- .../utility/MissingFilesPathItemDelegate.cpp | 6 + .../utility/MissingFilesPathItemDelegate.hpp | 3 + 6 files changed, 108 insertions(+), 60 deletions(-) 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;