From ff31ce636b68a19949d6e4049d20f7cf88e29f99 Mon Sep 17 00:00:00 2001 From: Eran Mizrahi Date: Sun, 17 Dec 2017 21:05:18 +0200 Subject: Fix mod rename with custom profiles path --- src/mainwindow.cpp | 64 +-------------------------------------------- src/mainwindow.h | 2 -- src/modlist.cpp | 10 +++---- src/profile.cpp | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/profile.h | 5 ++++ 5 files changed, 87 insertions(+), 70 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 3782b034..6f156269 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -2019,71 +2019,9 @@ void MainWindow::installMod_clicked() installMod(); } -void MainWindow::renameModInList(QFile &modList, const QString &oldName, const QString &newName) -{ - //TODO this code needs to be merged with ModList::readFrom - if (!modList.open(QIODevice::ReadWrite)) { - reportError(tr("failed to open %1").arg(modList.fileName())); - return; - } - - QBuffer outBuffer; - outBuffer.open(QIODevice::WriteOnly); - - while (!modList.atEnd()) { - QByteArray line = modList.readLine(); - - if (line.length() == 0) { - // ignore empty lines - qWarning("mod list contained invalid data: empty line"); - continue; - } - - char spec = line.at(0); - if (spec == '#') { - // don't touch comments - outBuffer.write(line); - continue; - } - - QString modName = QString::fromUtf8(line).mid(1).trimmed(); - - if (modName.isEmpty()) { - // file broken? - qWarning("mod list contained invalid data: missing mod name"); - continue; - } - - outBuffer.write(QByteArray(1, spec)); - if (modName == oldName) { - modName = newName; - } - outBuffer.write(modName.toUtf8().constData()); - outBuffer.write("\r\n"); - } - - modList.resize(0); - modList.write(outBuffer.buffer()); - modList.close(); -} - - void MainWindow::modRenamed(const QString &oldName, const QString &newName) { - // fix the profiles directly on disc - for (int i = 0; i < ui->profileBox->count(); ++i) { - QString profileName = ui->profileBox->itemText(i); - - //TODO this functionality should be in the Profile class - QString modlistName = QString("%1/%2/modlist.txt") - .arg(qApp->property("dataPath").toString() + "/" + QString::fromStdWString(AppConfig::profilesPath())) - .arg(profileName); - - QFile modList(modlistName); - if (modList.exists()) { - renameModInList(modList, oldName, newName); - } - } + Profile::renameModInAllProfiles(oldName, newName); // immediately refresh the active profile because the data in memory is invalid m_OrganizerCore.currentProfile()->refreshModStatus(); diff --git a/src/mainwindow.h b/src/mainwindow.h index 45a41137..a4ded688 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -220,8 +220,6 @@ private: void writeDataToFile(QFile &file, const QString &directory, const MOShared::DirectoryEntry &directoryEntry); - void renameModInList(QFile &modList, const QString &oldName, const QString &newName); - void refreshFilters(); /** diff --git a/src/modlist.cpp b/src/modlist.cpp index c028432c..046e2280 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -424,13 +424,13 @@ bool ModList::renameMod(int index, const QString &newName) return false; } - // before we rename, write back the current profile so we don't lose changes and to ensure - // there is no scheduled asynchronous rewrite anytime soon - m_Profile->writeModlistNow(); - ModInfo::Ptr modInfo = ModInfo::getByIndex(index); QString oldName = modInfo->name(); - if (modInfo->setName(nameFixed)) { + if (newName != oldName && modInfo->setName(nameFixed)) { + // before we rename, write back the current profile so we don't lose changes and to ensure + // there is no scheduled asynchronous rewrite anytime soon + m_Profile->writeModlistNow(); + // this just disabled the mod in all profiles. The recipient of modRenamed must fix that emit modRenamed(oldName, nameFixed); } diff --git a/src/profile.cpp b/src/profile.cpp index 3383ffee..00509ef7 100644 --- a/src/profile.cpp +++ b/src/profile.cpp @@ -39,6 +39,8 @@ along with Mod Organizer. If not, see . #include // for QStringList #include // for qDebug, qWarning, etc #include // for qPrintable +#include +#include #include @@ -242,9 +244,83 @@ void Profile::createTweakedIniFile() qDebug("%s saved", qPrintable(QDir::toNativeSeparators(tweakedIni))); } +// static +void Profile::renameModInAllProfiles(const QString& oldName, const QString& newName) +{ + QDir profilesDir(Settings::instance().getProfileDirectory()); + profilesDir.setFilter(QDir::AllDirs | QDir::NoDotAndDotDot); + QDirIterator profileIter(profilesDir); + while (profileIter.hasNext()) { + profileIter.next(); + QFile modList(profileIter.filePath() + "/modlist.txt"); + if (modList.exists()) + renameModInList(modList, oldName, newName); + else + qWarning("Profile has no modlist.txt : %s", qPrintable(profileIter.filePath())); + } +} + +// static +void Profile::renameModInList(QFile &modList, const QString &oldName, const QString &newName) +{ + if (!modList.open(QIODevice::ReadOnly)) { + reportError(tr("failed to open %1").arg(modList.fileName())); + return; + } + + QBuffer outBuffer; + outBuffer.open(QIODevice::WriteOnly); + + int renamed = 0; + while (!modList.atEnd()) { + QByteArray line = modList.readLine(); + + if (line.length() == 0) { + // ignore empty lines + qWarning("mod list contained invalid data: empty line"); + continue; + } + + char spec = line.at(0); + if (spec == '#') { + // don't touch comments + outBuffer.write(line); + continue; + } + + QString modName = QString::fromUtf8(line).mid(1).trimmed(); + + if (modName.isEmpty()) { + // file broken? + qWarning("mod list contained invalid data: missing mod name"); + continue; + } + + outBuffer.write(QByteArray(1, spec)); + if (modName == oldName) { + modName = newName; + ++renamed; + } + outBuffer.write(modName.toUtf8().constData()); + outBuffer.write("\r\n"); + } + modList.close(); + + if (renamed) { + modList.open(QIODevice::WriteOnly); + modList.write(outBuffer.buffer()); + modList.close(); + } + + if (renamed) + qDebug("Renamed %d \"%s\" mod to \"%s\" in %s", + renamed, qPrintable(oldName), qPrintable(newName), qPrintable(modList.fileName())); +} void Profile::refreshModStatus() { + writeModlistNow(true); // if there are pending changes write them first + QFile file(getModlistFileName()); if (!file.open(QIODevice::ReadOnly)) { throw MyException(tr("\"%1\" is missing or inaccessible").arg(getModlistFileName())); diff --git a/src/profile.h b/src/profile.h index edbbffe7..3e620b3c 100644 --- a/src/profile.h +++ b/src/profile.h @@ -89,6 +89,9 @@ public: **/ static Profile *createPtrFrom(const QString &name, const Profile &reference, MOBase::IPluginGame const *gamePlugin); + + static void renameModInAllProfiles(const QString& oldName, const QString& newName); + void writeModlist(); void writeModlistNow(bool onlyIfPending=false); @@ -331,6 +334,8 @@ private: void touchFile(QString fileName); void finishChangeStatus() const; + static void renameModInList(QFile &modList, const QString &oldName, const QString &newName); + private: QDir m_Directory; -- cgit v1.3.1