summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAl <26797547+Al12rs@users.noreply.github.com>2020-01-22 23:09:45 +0100
committerGitHub <noreply@github.com>2020-01-22 23:09:45 +0100
commiteacbe101f180b48bb48bf36d84125ed8cfd4901a (patch)
tree217440ae03e9a9e9cf53b15cd9309f972a7d34a2 /src
parent84678a3a2866ebb9d32337948b3f634efa08b7e6 (diff)
parent7c55ae3a2233c1031504cefeab059b7a83fc5bf9 (diff)
Merge pull request #979 from Al12rs/hidden-files-flag
Add Restore hidden files option and clean up hidden files code
Diffstat (limited to 'src')
-rw-r--r--src/mainwindow.cpp103
-rw-r--r--src/mainwindow.h1
-rw-r--r--src/modinfodialog.cpp44
-rw-r--r--src/modinfodialogfwd.h4
-rw-r--r--src/modinfowithconflictinfo.cpp5
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;
}