diff options
| author | Al <26797547+Al12rs@users.noreply.github.com> | 2020-01-22 23:09:45 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-01-22 23:09:45 +0100 |
| commit | eacbe101f180b48bb48bf36d84125ed8cfd4901a (patch) | |
| tree | 217440ae03e9a9e9cf53b15cd9309f972a7d34a2 | |
| parent | 84678a3a2866ebb9d32337948b3f634efa08b7e6 (diff) | |
| parent | 7c55ae3a2233c1031504cefeab059b7a83fc5bf9 (diff) | |
Merge pull request #979 from Al12rs/hidden-files-flag
Add Restore hidden files option and clean up hidden files code
| -rw-r--r-- | src/mainwindow.cpp | 103 | ||||
| -rw-r--r-- | src/mainwindow.h | 1 | ||||
| -rw-r--r-- | src/modinfodialog.cpp | 44 | ||||
| -rw-r--r-- | src/modinfodialogfwd.h | 4 | ||||
| -rw-r--r-- | src/modinfowithconflictinfo.cpp | 5 |
5 files changed, 150 insertions, 7 deletions
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index be8eaef8..a50e38e7 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1743,7 +1743,7 @@ void MainWindow::updateTo(QTreeWidgetItem *subTree, const std::wstring &director font.setItalic(true); fileChild->setFont(0, font); fileChild->setFont(1, font); - } else if (fileName.endsWith(ModInfo::s_HiddenExt)) { + } else if (fileName.endsWith(ModInfo::s_HiddenExt, Qt::CaseInsensitive)) { QFont font = fileChild->font(0); font.setStrikeOut(true); fileChild->setFont(0, font); @@ -3201,6 +3201,99 @@ void MainWindow::markConverted_clicked() } +void MainWindow::restoreHiddenFiles_clicked() +{ + const int max_items = 20; + QItemSelectionModel* selection = ui->modList->selectionModel(); + + QFlags<FileRenamer::RenameFlags> flags = FileRenamer::UNHIDE; + flags |= FileRenamer::MULTIPLE; + + FileRenamer renamer(this, flags); + + FileRenamer::RenameResults result = FileRenamer::RESULT_OK; + + // multi selection + if (selection->hasSelection() && selection->selectedRows().count() > 1) { + QString mods; + QStringList modNames; + int i = 0; + + for (QModelIndex idx : selection->selectedRows()) { + + QString name = idx.data().toString(); + int row_idx = idx.data(Qt::UserRole + 1).toInt(); + ModInfo::Ptr modInfo = ModInfo::getByIndex(row_idx); + const auto flags = modInfo->getFlags(); + + if (!modInfo->isRegular() || + std::find(flags.begin(), flags.end(), ModInfo::FLAG_HIDDEN_FILES) == flags.end()) { + continue; + } + + // adds an item for the mod name until `i` reaches `max_items`, which + // adds one "..." item; subsequent mods are not shown on the list but + // are still added to `modNames` below so they can be removed correctly + if (i < max_items) { + mods += "<li>" + name + "</li>"; + } + else if (i == max_items) { + mods += "<li>...</li>"; + } + + modNames.append(ModInfo::getByIndex(idx.data(Qt::UserRole + 1).toInt())->name()); + ++i; + } + if (QMessageBox::question(this, tr("Confirm"), + tr("Restore all hidden files in the following mods?<br><ul>%1</ul>").arg(mods), + QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { + + for (QModelIndex idx : selection->selectedRows()) { + + int row_idx = idx.data(Qt::UserRole + 1).toInt(); + ModInfo::Ptr modInfo = ModInfo::getByIndex(row_idx); + + const auto flags = modInfo->getFlags(); + if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_HIDDEN_FILES) != flags.end()) { + const QString modDir = modInfo->absolutePath(); + + auto partialResult = restoreHiddenFilesRecursive(renamer, modDir); + + if (partialResult == FileRenamer::RESULT_CANCEL) { + result = FileRenamer::RESULT_CANCEL; + break; + } + originModified((m_OrganizerCore.directoryStructure()->getOriginByName( + ToWString(modInfo->internalName()))).getID()); + } + } + } + } + else { + //single selection + ModInfo::Ptr modInfo = ModInfo::getByIndex(m_ContextRow); + const QString modDir = modInfo->absolutePath(); + + if (QMessageBox::question(this, tr("Are you sure?"), + tr("About to restore all hidden files in:\n") + modInfo->name(), + QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) { + + result = restoreHiddenFilesRecursive(renamer, modDir); + + originModified((m_OrganizerCore.directoryStructure()->getOriginByName( + ToWString(modInfo->internalName()))).getID()); + } + } + + if (result == FileRenamer::RESULT_CANCEL){ + log::debug("Restoring hidden files operation cancelled"); + } + else { + log::debug("Finished restoring hidden files"); + } +} + + void MainWindow::visitOnNexus_clicked() { QItemSelectionModel *selection = ui->modList->selectionModel(); @@ -4725,6 +4818,10 @@ void MainWindow::on_modList_customContextMenuRequested(const QPoint &pos) menu.addAction(tr("Remove Mod..."), this, SLOT(removeMod_clicked())); menu.addAction(tr("Create Backup"), this, SLOT(backupMod_clicked())); + if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_HIDDEN_FILES) != flags.end()) { + menu.addAction(tr("Restore hidden files"), this, SLOT(restoreHiddenFiles_clicked())); + } + menu.addSeparator(); if (info->getNexusID() > 0 && Settings::instance().nexus().endorsementIntegration()) { @@ -4774,6 +4871,8 @@ void MainWindow::on_modList_customContextMenuRequested(const QPoint &pos) menu.addAction(tr("Mark as converted/working"), this, SLOT(markConverted_clicked())); } + menu.addSeparator(); + if (info->getNexusID() > 0) { menu.addAction(tr("Visit on Nexus"), this, SLOT(visitOnNexus_clicked())); } @@ -5560,7 +5659,7 @@ void MainWindow::on_dataTree_customContextMenuRequested(const QPoint &pos) // offer to hide/unhide file, but not for files from archives if (!isArchive) { - if (m_ContextItem->text(0).endsWith(ModInfo::s_HiddenExt)) { + if (m_ContextItem->text(0).endsWith(ModInfo::s_HiddenExt, Qt::CaseInsensitive)) { menu.addAction(tr("Un-Hide"), this, SLOT(unhideFile())); } else { menu.addAction(tr("Hide"), this, SLOT(hideFile())); diff --git a/src/mainwindow.h b/src/mainwindow.h index 8f000983..2c45049a 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -421,6 +421,7 @@ private slots: void untrack_clicked(); void ignoreMissingData_clicked(); void markConverted_clicked(); + void restoreHiddenFiles_clicked(); void visitOnNexus_clicked(); void visitWebPage_clicked(); void openExplorer_clicked(); diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp index f5ca1de7..302175aa 100644 --- a/src/modinfodialog.cpp +++ b/src/modinfodialog.cpp @@ -97,7 +97,7 @@ bool canHideFile(bool isArchive, const QString& filename) return false; } - if (filename.endsWith(ModInfo::s_HiddenExt)) { + if (filename.endsWith(ModInfo::s_HiddenExt, Qt::CaseInsensitive)) { // already hidden return false; } @@ -112,7 +112,7 @@ bool canUnhideFile(bool isArchive, const QString& filename) return false; } - if (!filename.endsWith(ModInfo::s_HiddenExt)) { + if (!filename.endsWith(ModInfo::s_HiddenExt, Qt::CaseInsensitive)) { // already visible return false; } @@ -133,6 +133,46 @@ FileRenamer::RenameResults unhideFile(FileRenamer& renamer, const QString &oldNa } +FileRenamer::RenameResults restoreHiddenFilesRecursive(FileRenamer& renamer, const QString& targetDir) +{ + FileRenamer::RenameResults results = FileRenamer::RESULT_OK; + QDir currentDir = targetDir; + for (QString hiddenFile : currentDir.entryList( + (QStringList() << "*" + ModInfo::s_HiddenExt), + QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot)) { + + QString oldName = currentDir.absoluteFilePath(hiddenFile); + QString newName = oldName.left(oldName.length() - ModInfo::s_HiddenExt.length()); + + auto partialResult = renamer.rename(oldName, newName); + + if (partialResult == FileRenamer::RESULT_CANCEL) { + return FileRenamer::RESULT_CANCEL; + } + + if (partialResult == FileRenamer::RESULT_SKIP) { + results = FileRenamer::RESULT_SKIP; + } + } + + for (QString dirName : currentDir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot)) { + + const QString dirPath = currentDir.absoluteFilePath(dirName); + // recurse on childrend directories + auto partialResult = restoreHiddenFilesRecursive(renamer, dirPath); + + if (partialResult == FileRenamer::RESULT_CANCEL) { + return FileRenamer::RESULT_CANCEL; + } + + if (partialResult == FileRenamer::RESULT_SKIP) { + results = FileRenamer::RESULT_SKIP; + } + } + return results; +} + + ModInfoDialog::TabInfo::TabInfo(std::unique_ptr<ModInfoDialogTab> tab) : tab(std::move(tab)), realPos(-1), widget(nullptr) { diff --git a/src/modinfodialogfwd.h b/src/modinfodialogfwd.h index 2147fc04..5d949ce9 100644 --- a/src/modinfodialogfwd.h +++ b/src/modinfodialogfwd.h @@ -30,7 +30,9 @@ bool canHideFile(bool isArchive, const QString& filename); bool canUnhideFile(bool isArchive, const QString& filename); FileRenamer::RenameResults hideFile(FileRenamer& renamer, const QString &oldName); -FileRenamer::RenameResults unhideFile(FileRenamer& renamer, const QString &oldName); +FileRenamer::RenameResults unhideFile(FileRenamer& renamer, const QString& oldName); +FileRenamer::RenameResults restoreHiddenFilesRecursive(FileRenamer& renamer, const QString &targetDir); + int naturalCompare(const QString& a, const QString& b); diff --git a/src/modinfowithconflictinfo.cpp b/src/modinfowithconflictinfo.cpp index b068ad4a..861782d9 100644 --- a/src/modinfowithconflictinfo.cpp +++ b/src/modinfowithconflictinfo.cpp @@ -90,6 +90,7 @@ void ModInfoWithConflictInfo::doConflictCheck() const } std::wstring name = ToWString(this->name()); + const std::wstring hideExt = ToWString(ModInfo::s_HiddenExt); m_CurrentConflictState = CONFLICT_NONE; m_ArchiveConflictState = CONFLICT_NONE; @@ -107,7 +108,7 @@ void ModInfoWithConflictInfo::doConflictCheck() const if (!hasHiddenFiles) { const fs::path nameAsPath(file->getName()); - if (nameAsPath.extension().wstring().compare(L".mohidden") == 0) { + if (nameAsPath.extension().wstring().compare(hideExt) == 0) { hasHiddenFiles = true; } else { @@ -123,7 +124,7 @@ void ModInfoWithConflictInfo::doConflictCheck() const } else { const fs::path dirPath(parent->getName()); - if (dirPath.extension().wstring().compare(L".mohidden") == 0) { + if (dirPath.extension().wstring().compare(hideExt) == 0) { hasHiddenFiles = true; break; } |
