From ce02da497a1d18228bd3c31924212a5a432f1ab7 Mon Sep 17 00:00:00 2001 From: LostDragonist Date: Mon, 24 Dec 2018 00:59:54 -0600 Subject: Prevent missing INI dialog from popping up when creating a new instance with archive invalidation --- src/profile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/profile.cpp') diff --git a/src/profile.cpp b/src/profile.cpp index 8eb1c49a..d65ea255 100644 --- a/src/profile.cpp +++ b/src/profile.cpp @@ -85,7 +85,6 @@ Profile::Profile(const QString &name, IPluginGame const *gamePlugin, bool useDef m_Directory = QDir(fullPath); m_Settings = new QSettings(m_Directory.absoluteFilePath("settings.ini"), QSettings::IniFormat); - findProfileSettings(); try { // create files. Needs to happen after m_Directory was set! @@ -101,6 +100,7 @@ Profile::Profile(const QString &name, IPluginGame const *gamePlugin, bool useDef } gamePlugin->initializeProfile(fullPath, settings); + findProfileSettings(); } catch (...) { // clean up in case of an error shellDelete(QStringList(profileBase.absoluteFilePath(fixedName))); -- cgit v1.3.1 From a3110731ca275b857eb264d69996264be5e404f5 Mon Sep 17 00:00:00 2001 From: LostDragonist Date: Wed, 26 Dec 2018 16:18:52 -0600 Subject: Use WriteRegistryValue function to handle read-only files --- src/profile.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/profile.cpp') diff --git a/src/profile.cpp b/src/profile.cpp index d65ea255..d1741311 100644 --- a/src/profile.cpp +++ b/src/profile.cpp @@ -29,6 +29,8 @@ along with Mod Organizer. If not, see . #include #include #include +#include "util.h" +#include "registry.h" #include #include // for QFile @@ -279,7 +281,7 @@ void Profile::createTweakedIniFile() mergeTweak(getProfileTweaks(), tweakedIni); bool error = false; - if (!::WritePrivateProfileStringW(L"Archive", L"bInvalidateOlderFiles", L"1", ToWString(tweakedIni).c_str())) { + if (!MOBase::WriteRegistryValue(L"Archive", L"bInvalidateOlderFiles", L"1", ToWString(tweakedIni).c_str())) { error = true; } @@ -681,7 +683,7 @@ void Profile::mergeTweak(const QString &tweakName, const QString &tweakedIni) co //TODO this treats everything as strings but how could I differentiate the type? ::GetPrivateProfileStringW(iter->c_str(), keyIter->c_str(), nullptr, buffer.data(), bufferSize, ToWString(tweakName).c_str()); - ::WritePrivateProfileStringW(iter->c_str(), keyIter->c_str(), + MOBase::WriteRegistryValue(iter->c_str(), keyIter->c_str(), buffer.data(), tweakedIniW.c_str()); } } -- cgit v1.3.1 From 683d17784b026d857732a8d52bc26709ba0e0322 Mon Sep 17 00:00:00 2001 From: LostDragonist Date: Wed, 2 Jan 2019 14:30:17 -0600 Subject: Improve missing INI dialog when switching profiles --- src/profile.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/profile.cpp') diff --git a/src/profile.cpp b/src/profile.cpp index d1741311..e3c1e5ac 100644 --- a/src/profile.cpp +++ b/src/profile.cpp @@ -772,20 +772,21 @@ bool Profile::localSettingsEnabled() const { bool enabled = setting("LocalSettings", false).toBool(); if (enabled) { - bool reinitConfig = false; + QStringList missingFiles; for (QString file : m_GamePlugin->iniFiles()) { if (!QFile::exists(m_Directory.filePath(file))) { qWarning("missing %s in %s", qPrintable(file), qPrintable(m_Directory.path())); - reinitConfig = true; + missingFiles << file; } } - if (reinitConfig) { + if (!missingFiles.empty()) { + m_GamePlugin->initializeProfile(m_Directory, IPluginGame::CONFIGURATION); QMessageBox::StandardButton res = QMessageBox::warning( QApplication::activeModalWidget(), tr("Missing profile-specific game INI files!"), tr("Some of your profile-specific game INI files were missing. They will now be copied " - "from the vanilla game folder. You might want double-check your settings.") + "from the vanilla game folder. You might want double-check your settings.\n\n" + "Missing files:\n") + missingFiles.join("\n") ); - m_GamePlugin->initializeProfile(m_Directory, IPluginGame::CONFIGURATION); } } return enabled; -- cgit v1.3.1 From 3839de53f0057658b8fab236cec03fdb2fff1d8c Mon Sep 17 00:00:00 2001 From: LostDragonist Date: Thu, 3 Jan 2019 04:39:34 -0600 Subject: Don't call ASCII function with unicode --- src/profile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/profile.cpp') diff --git a/src/profile.cpp b/src/profile.cpp index e3c1e5ac..9da1a698 100644 --- a/src/profile.cpp +++ b/src/profile.cpp @@ -286,7 +286,7 @@ void Profile::createTweakedIniFile() } if (error) { - reportError(tr("failed to create tweaked ini: %1").arg(getCurrentErrorStringA().c_str())); + reportError(tr("failed to create tweaked ini: %1").arg(getCurrentErrorString().c_str())); } qDebug("%s saved", qPrintable(QDir::toNativeSeparators(tweakedIni))); } -- cgit v1.3.1 From f2c145b2fc9d6ffce838398e06f7aa583d05887d Mon Sep 17 00:00:00 2001 From: LostDragonist Date: Sat, 5 Jan 2019 16:34:10 -0600 Subject: Change qPrintable to qUtf8Printable to better support non-ASCII text --- src/bbcode.cpp | 2 +- src/directoryrefresher.cpp | 2 +- src/downloadmanager.cpp | 18 +++++++++--------- src/editexecutablesdialog.cpp | 2 +- src/icondelegate.cpp | 2 +- src/installationmanager.cpp | 8 ++++---- src/instancemanager.cpp | 2 +- src/logbuffer.cpp | 14 +++++++------- src/main.cpp | 24 ++++++++++++------------ src/mainwindow.cpp | 20 ++++++++++---------- src/messagedialog.cpp | 2 +- src/moapplication.cpp | 2 +- src/modinforegular.cpp | 2 +- src/modlist.cpp | 2 +- src/nexusinterface.cpp | 8 ++++---- src/nxmaccessmanager.cpp | 6 +++--- src/organizercore.cpp | 24 ++++++++++++------------ src/persistentcookiejar.cpp | 6 +++--- src/plugincontainer.cpp | 14 +++++++------- src/pluginlist.cpp | 12 ++++++------ src/profile.cpp | 18 +++++++++--------- src/profilesdialog.cpp | 2 +- src/selfupdater.cpp | 10 +++++----- src/settings.cpp | 4 ++-- src/usvfsconnector.cpp | 2 +- 25 files changed, 104 insertions(+), 104 deletions(-) (limited to 'src/profile.cpp') diff --git a/src/bbcode.cpp b/src/bbcode.cpp index 56369538..84d7a7c0 100644 --- a/src/bbcode.cpp +++ b/src/bbcode.cpp @@ -88,7 +88,7 @@ public: return temp.replace(tagIter->second.first, QString("%2").arg(color, content)); } } else { - qWarning("don't know how to deal with tag %s", qPrintable(tagName)); + qWarning("don't know how to deal with tag %s", qUtf8Printable(tagName)); } } else { if (tagName == "*") { diff --git a/src/directoryrefresher.cpp b/src/directoryrefresher.cpp index 272b0596..cc745cc8 100644 --- a/src/directoryrefresher.cpp +++ b/src/directoryrefresher.cpp @@ -117,7 +117,7 @@ void DirectoryRefresher::addModFilesToStructure(DirectoryEntry *directoryStructu origin.addFile(file->getIndex()); file->addOrigin(origin.getID(), file->getFileTime(), L""); } else { - qWarning("%s not found", qPrintable(fileInfo.fileName())); + qWarning("%s not found", qUtf8Printable(fileInfo.fileName())); } } } else { diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp index b408f1a6..15831126 100644 --- a/src/downloadmanager.cpp +++ b/src/downloadmanager.cpp @@ -400,7 +400,7 @@ bool DownloadManager::addDownload(const QStringList &URLs, QString gameName, } QUrl preferredUrl = QUrl::fromEncoded(URLs.first().toLocal8Bit()); - qDebug("selected download url: %s", qPrintable(preferredUrl.toString())); + qDebug("selected download url: %s", qUtf8Printable(preferredUrl.toString())); QNetworkRequest request(preferredUrl); request.setHeader(QNetworkRequest::UserAgentHeader, m_NexusInterface->getAccessManager()->userAgent()); return addDownload(m_NexusInterface->getAccessManager()->get(request), URLs, fileName, gameName, modID, fileID, fileInfo); @@ -540,9 +540,9 @@ void DownloadManager::addNXMDownload(const QString &url) QStringList validGames; validGames.append(m_ManagedGame->gameShortName()); validGames.append(m_ManagedGame->validShortNames()); - qDebug("add nxm download: %s", qPrintable(url)); + qDebug("add nxm download: %s", qUtf8Printable(url)); if (!validGames.contains(nxmInfo.game(), Qt::CaseInsensitive)) { - qDebug("download requested for wrong game (game: %s, url: %s)", qPrintable(m_ManagedGame->gameShortName()), qPrintable(nxmInfo.game())); + qDebug("download requested for wrong game (game: %s, url: %s)", qUtf8Printable(m_ManagedGame->gameShortName()), qUtf8Printable(nxmInfo.game())); QMessageBox::information(nullptr, tr("Wrong Game"), tr("The download link is for a mod for \"%1\" but this instance of MO " "has been set up for \"%2\".").arg(nxmInfo.game()).arg(m_ManagedGame->gameShortName()), QMessageBox::Ok); return; @@ -550,7 +550,7 @@ void DownloadManager::addNXMDownload(const QString &url) for (auto tuple : m_PendingDownloads) { if (std::get<0>(tuple).compare(nxmInfo.game(), Qt::CaseInsensitive) == 0, std::get<1>(tuple) == nxmInfo.modId() && std::get<2>(tuple) == nxmInfo.fileId()) { - qDebug("download requested is already started (mod id: %s, file id: %s)", qPrintable(QString(nxmInfo.modId())), qPrintable(QString(nxmInfo.fileId()))); + qDebug("download requested is already started (mod id: %s, file id: %s)", qUtf8Printable(QString(nxmInfo.modId())), qUtf8Printable(QString(nxmInfo.fileId()))); QMessageBox::information(nullptr, tr("Already Started"), tr("A download for this mod file has already been queued."), QMessageBox::Ok); return; } @@ -559,8 +559,8 @@ void DownloadManager::addNXMDownload(const QString &url) for (DownloadInfo *download : m_ActiveDownloads) { if (download->m_FileInfo->modID == nxmInfo.modId() && download->m_FileInfo->fileID == nxmInfo.fileId()) { if (download->m_State == STATE_DOWNLOADING || download->m_State == STATE_PAUSED || download->m_State == STATE_STARTED) { - qDebug("download requested is already started (mod: %s, file: %s)", qPrintable(QString(download->m_FileInfo->modID)), - qPrintable(download->m_FileInfo->fileName)); + qDebug("download requested is already started (mod: %s, file: %s)", qUtf8Printable(QString(download->m_FileInfo->modID)), + qUtf8Printable(download->m_FileInfo->fileName)); QMessageBox::information(nullptr, tr("Already Started"), tr("There is already a download started for this file (mod: %1, file: %2).") .arg(download->m_FileInfo->modName).arg(download->m_FileInfo->fileName), QMessageBox::Ok); @@ -814,7 +814,7 @@ void DownloadManager::resumeDownloadInt(int index) if (info->m_State == STATE_ERROR) { info->m_CurrentUrl = (info->m_CurrentUrl + 1) % info->m_Urls.count(); } - qDebug("request resume from url %s", qPrintable(info->currentURL())); + qDebug("request resume from url %s", qUtf8Printable(info->currentURL())); QNetworkRequest request(QUrl::fromEncoded(info->currentURL().toLocal8Bit())); request.setHeader(QNetworkRequest::UserAgentHeader, m_NexusInterface->getAccessManager()->userAgent()); if (info->m_State != STATE_ERROR) { @@ -1434,7 +1434,7 @@ QDateTime DownloadManager::matchDate(const QString &timeString) if (m_DateExpression.exactMatch(timeString)) { return QDateTime::fromMSecsSinceEpoch(m_DateExpression.cap(1).toLongLong()); } else { - qWarning("date not matched: %s", qPrintable(timeString)); + qWarning("date not matched: %s", qUtf8Printable(timeString)); return QDateTime::currentDateTime(); } } @@ -1783,7 +1783,7 @@ void DownloadManager::downloadError(QNetworkReply::NetworkError error) { if (error != QNetworkReply::OperationCanceledError) { QNetworkReply *reply = qobject_cast(sender()); - qWarning("%s (%d)", reply != nullptr ? qPrintable(reply->errorString()) + qWarning("%s (%d)", reply != nullptr ? qUtf8Printable(reply->errorString()) : "Download error occured", error); } diff --git a/src/editexecutablesdialog.cpp b/src/editexecutablesdialog.cpp index fde6b397..be2ee127 100644 --- a/src/editexecutablesdialog.cpp +++ b/src/editexecutablesdialog.cpp @@ -324,7 +324,7 @@ void EditExecutablesDialog::on_executablesListBox_clicked(const QModelIndex &cur QString customOverwrite = m_Profile->setting("custom_overwrites", selectedExecutable.m_Title).toString(); if (!customOverwrite.isEmpty()) { index = ui->newFilesModBox->findText(customOverwrite); - qDebug("find %s -> %d", qPrintable(customOverwrite), index); + qDebug("find %s -> %d", qUtf8Printable(customOverwrite), index); } ui->newFilesModCheckBox->setChecked(index != -1); diff --git a/src/icondelegate.cpp b/src/icondelegate.cpp index e502dc69..249dae6f 100644 --- a/src/icondelegate.cpp +++ b/src/icondelegate.cpp @@ -54,7 +54,7 @@ void IconDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, if (!QPixmapCache::find(fullIconId, &icon)) { icon = QIcon(iconId).pixmap(iconWidth, iconWidth); if (icon.isNull()) { - qWarning("failed to load icon %s", qPrintable(iconId)); + qWarning("failed to load icon %s", qUtf8Printable(iconId)); } QPixmapCache::insert(fullIconId, icon); } diff --git a/src/installationmanager.cpp b/src/installationmanager.cpp index 76b1e086..57c5e861 100644 --- a/src/installationmanager.cpp +++ b/src/installationmanager.cpp @@ -758,7 +758,7 @@ bool InstallationManager::install(const QString &fileName, if (fileInfo.dir() == QDir(m_DownloadsDirectory)) { m_CurrentFile = fileInfo.fileName(); } - qDebug("using mod name \"%s\" (id %d) -> %s", modName->toUtf8().constData(), modID, qPrintable(m_CurrentFile)); + qDebug("using mod name \"%s\" (id %d) -> %s", modName->toUtf8().constData(), modID, qUtf8Printable(m_CurrentFile)); //If there's an archive already open, close it. This happens with the bundle //installer when it uncompresses a split archive, then finds it has a real archive @@ -770,8 +770,8 @@ bool InstallationManager::install(const QString &fileName, new MethodCallback(this, &InstallationManager::queryPassword)); if (!archiveOpen) { qDebug("integrated archiver can't open %s: %s (%d)", - qPrintable(fileName), - qPrintable(getErrorString(m_ArchiveHandler->getLastError())), + qUtf8Printable(fileName), + qUtf8Printable(getErrorString(m_ArchiveHandler->getLastError())), m_ArchiveHandler->getLastError()); } ON_BLOCK_EXIT(std::bind(&InstallationManager::postInstallCleanup, this)); @@ -841,7 +841,7 @@ bool InstallationManager::install(const QString &fileName, } } catch (const IncompatibilityException &e) { qCritical("plugin \"%s\" incompatible: %s", - qPrintable(installer->name()), e.what()); + qUtf8Printable(installer->name()), e.what()); } // act upon the installation result. at this point the files have already been diff --git a/src/instancemanager.cpp b/src/instancemanager.cpp index 9066741d..a5a52d63 100644 --- a/src/instancemanager.cpp +++ b/src/instancemanager.cpp @@ -86,7 +86,7 @@ bool InstanceManager::deleteLocalInstance(const QString &instanceId) const if (!MOBase::shellDelete(QStringList(instancePath),true)) { - qWarning("Failed to shell-delete \"%s\" (errorcode %lu), trying regular delete", qPrintable(instancePath), ::GetLastError()); + qWarning("Failed to shell-delete \"%s\" (errorcode %lu), trying regular delete", qUtf8Printable(instancePath), ::GetLastError()); if (!MOBase::removeDir(instancePath)) { qWarning("regular delete failed too"); diff --git a/src/logbuffer.cpp b/src/logbuffer.cpp index 522ce3c8..485e27db 100644 --- a/src/logbuffer.cpp +++ b/src/logbuffer.cpp @@ -127,7 +127,7 @@ void LogBuffer::log(QtMsgType type, const QMessageLogContext &context, { // QMutexLocker doesn't support timeout... if (!s_Mutex.tryLock(100)) { - fprintf(stderr, "failed to log: %s", qPrintable(message)); + fprintf(stderr, "failed to log: %s", qUtf8Printable(message)); return; } ON_BLOCK_EXIT([]() { s_Mutex.unlock(); }); @@ -137,17 +137,17 @@ void LogBuffer::log(QtMsgType type, const QMessageLogContext &context, } if (type == QtDebugMsg) { - fprintf(stdout, "%s [%c] %s\n", qPrintable(QTime::currentTime().toString()), - msgTypeID(type), qPrintable(message)); + fprintf(stdout, "%s [%c] %s\n", qUtf8Printable(QTime::currentTime().toString()), + msgTypeID(type), qUtf8Printable(message)); } else { if (context.line != 0) { fprintf(stdout, "%s [%c] (%s:%u) %s\n", - qPrintable(QTime::currentTime().toString()), msgTypeID(type), - context.file, context.line, qPrintable(message)); + qUtf8Printable(QTime::currentTime().toString()), msgTypeID(type), + context.file, context.line, qUtf8Printable(message)); } else { fprintf(stdout, "%s [%c] %s\n", - qPrintable(QTime::currentTime().toString()), msgTypeID(type), - qPrintable(message)); + qUtf8Printable(QTime::currentTime().toString()), msgTypeID(type), + qUtf8Printable(message)); } } fflush(stdout); diff --git a/src/main.cpp b/src/main.cpp index 4d2bb7ed..190a8f4b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -262,7 +262,7 @@ QString determineProfile(QStringList &arguments, const QSettings &settings) qDebug("no configured profile"); selectedProfileName = "Default"; } else { - qDebug("configured profile: %s", qPrintable(selectedProfileName)); + qDebug("configured profile: %s", qUtf8Printable(selectedProfileName)); } return selectedProfileName; @@ -401,7 +401,7 @@ void setupPath() { static const int BUFSIZE = 4096; - qDebug("MO at: %s", qPrintable(QDir::toNativeSeparators( + qDebug("MO at: %s", qUtf8Printable(QDir::toNativeSeparators( QCoreApplication::applicationDirPath()))); QCoreApplication::setLibraryPaths(QStringList(QCoreApplication::applicationDirPath() + "/dlls") + QCoreApplication::libraryPaths()); @@ -429,18 +429,18 @@ static void preloadSsl() else { QString libeay32 = appPath + "\\libeay32.dll"; if (!QFile::exists(libeay32)) - qWarning("libeay32.dll not found: %s", qPrintable(libeay32)); + qWarning("libeay32.dll not found: %s", qUtf8Printable(libeay32)); else if (!LoadLibraryW(libeay32.toStdWString().c_str())) - qWarning("failed to load: %s, %d", qPrintable(libeay32), GetLastError()); + qWarning("failed to load: %s, %d", qUtf8Printable(libeay32), GetLastError()); } if (GetModuleHandleA("ssleay32.dll")) qWarning("ssleay32.dll already loaded?!"); else { QString ssleay32 = appPath + "\\ssleay32.dll"; if (!QFile::exists(ssleay32)) - qWarning("ssleay32.dll not found: %s", qPrintable(ssleay32)); + qWarning("ssleay32.dll not found: %s", qUtf8Printable(ssleay32)); else if (!LoadLibraryW(ssleay32.toStdWString().c_str())) - qWarning("failed to load: %s, %d", qPrintable(ssleay32), GetLastError()); + qWarning("failed to load: %s, %d", qUtf8Printable(ssleay32), GetLastError()); } } @@ -453,7 +453,7 @@ int runApplication(MOApplication &application, SingleInstance &instance, const QString &splashPath) { - qDebug("Starting Mod Organizer version %s revision %s", qPrintable(getVersionDisplayString()), + qDebug("Starting Mod Organizer version %s revision %s", qUtf8Printable(getVersionDisplayString()), #if defined(HGID) HGID #elif defined(GITID) @@ -471,7 +471,7 @@ int runApplication(MOApplication &application, SingleInstance &instance, #endif QString dataPath = application.property("dataPath").toString(); - qDebug("data path: %s", qPrintable(dataPath)); + qDebug("data path: %s", qUtf8Printable(dataPath)); if (!bootstrap()) { reportError("failed to set up data paths"); @@ -483,7 +483,7 @@ int runApplication(MOApplication &application, SingleInstance &instance, QStringList arguments = application.arguments(); try { - qDebug("Working directory: %s", qPrintable(QDir::toNativeSeparators(QDir::currentPath()))); + qDebug("Working directory: %s", qUtf8Printable(QDir::toNativeSeparators(QDir::currentPath()))); QSettings settings(dataPath + "/" + QString::fromStdWString(AppConfig::iniFileName()), @@ -552,7 +552,7 @@ int runApplication(MOApplication &application, SingleInstance &instance, } game->setGameVariant(settings.value("game_edition").toString()); - qDebug("managing game at %s", qPrintable(QDir::toNativeSeparators( + qDebug("managing game at %s", qUtf8Printable(QDir::toNativeSeparators( game->gameDirectory().absolutePath()))); organizer.updateExecutablesList(settings); @@ -578,12 +578,12 @@ int runApplication(MOApplication &application, SingleInstance &instance, } else if (OrganizerCore::isNxmLink(arguments.at(1))) { qDebug("starting download from command line: %s", - qPrintable(arguments.at(1))); + qUtf8Printable(arguments.at(1))); organizer.externalMessage(arguments.at(1)); } else { QString exeName = arguments.at(1); - qDebug("starting %s from command line", qPrintable(exeName)); + qDebug("starting %s from command line", qUtf8Printable(exeName)); arguments.removeFirst(); // remove application name (ModOrganizer.exe) arguments.removeFirst(); // remove binary name // pass the remaining parameters to the binary diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 83205ac4..ae37968c 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1558,7 +1558,7 @@ void MainWindow::refreshSaveList() QDir savesDir = currentSavesDir(); savesDir.setNameFilters(filters); - qDebug("reading save games from %s", qPrintable(savesDir.absolutePath())); + qDebug("reading save games from %s", qUtf8Printable(savesDir.absolutePath())); QFileInfoList files = savesDir.entryInfoList(QDir::Files, QDir::Time); for (const QFileInfo &file : files) { @@ -1763,7 +1763,7 @@ void MainWindow::setupNetworkProxy(bool activate) query.setProtocolTag("http"); QList proxies = QNetworkProxyFactory::systemProxyForQuery(query); if ((proxies.size() > 0) && (proxies.at(0).type() != QNetworkProxy::NoProxy)) { - qDebug("Using proxy: %s", qPrintable(proxies.at(0).hostName())); + qDebug("Using proxy: %s", qUtf8Printable(proxies.at(0).hostName())); QNetworkProxy::setApplicationProxy(proxies[0]); } else { qDebug("Not using proxy"); @@ -2418,7 +2418,7 @@ void MainWindow::refreshFilters() while (currentID != 0) { categoriesUsed.insert(currentID); if (!cycleTest.insert(currentID).second) { - qWarning("cycle in categories: %s", qPrintable(SetJoin(cycleTest, ", "))); + qWarning("cycle in categories: %s", qUtf8Printable(SetJoin(cycleTest, ", "))); break; } currentID = m_CategoryFactory.getParentID(m_CategoryFactory.getCategoryIndex(currentID)); @@ -2732,7 +2732,7 @@ void MainWindow::unendorse_clicked() void MainWindow::loginFailed(const QString &error) { - qDebug("login failed: %s", qPrintable(error)); + qDebug("login failed: %s", qUtf8Printable(error)); statusBar()->hide(); } @@ -3711,7 +3711,7 @@ void MainWindow::addRemoveCategories_MenuHandler() { int maxRow = -1; for (const QPersistentModelIndex &idx : selected) { - qDebug("change categories on: %s", qPrintable(idx.data().toString())); + qDebug("change categories on: %s", qUtf8Printable(idx.data().toString())); QModelIndex modIdx = mapToModel(m_OrganizerCore.modList(), idx); if (modIdx.row() != m_ContextIdx.row()) { addRemoveCategoriesFromMenu(menu, modIdx.row(), m_ContextIdx.row()); @@ -3793,7 +3793,7 @@ void MainWindow::saveArchiveList() } } if (archiveFile.commitIfDifferent(m_ArchiveListHash)) { - qDebug("%s saved", qPrintable(QDir::toNativeSeparators(m_OrganizerCore.currentProfile()->getArchivesFileName()))); + qDebug("%s saved", qUtf8Printable(QDir::toNativeSeparators(m_OrganizerCore.currentProfile()->getArchivesFileName()))); } } else { qWarning("archive list not initialised"); @@ -4693,7 +4693,7 @@ void MainWindow::installTranslator(const QString &name) QString fileName = name + "_" + m_CurrentLanguage; if (!translator->load(fileName, qApp->applicationDirPath() + "/translations")) { if (m_CurrentLanguage.compare("en", Qt::CaseInsensitive)) { - qDebug("localization file %s not found", qPrintable(fileName)); + qDebug("localization file %s not found", qUtf8Printable(fileName)); } // we don't actually expect localization files for English } @@ -4718,7 +4718,7 @@ void MainWindow::languageChange(const QString &newLanguage) installTranslator(QFileInfo(fileName).baseName()); } ui->retranslateUi(this); - qDebug("loaded language %s", qPrintable(newLanguage)); + qDebug("loaded language %s", qUtf8Printable(newLanguage)); ui->profileBox->setItemText(0, QObject::tr("")); @@ -6134,7 +6134,7 @@ void MainWindow::dropLocalFile(const QUrl &url, const QString &outputDir, bool m { QFileInfo file(url.toLocalFile()); if (!file.exists()) { - qWarning("invalid source file %s", qPrintable(file.absoluteFilePath())); + qWarning("invalid source file %s", qUtf8Printable(file.absoluteFilePath())); return; } QString target = outputDir + "/" + file.fileName(); @@ -6167,7 +6167,7 @@ void MainWindow::dropLocalFile(const QUrl &url, const QString &outputDir, bool m success = shellCopy(file.absoluteFilePath(), target, true, this); } if (!success) { - qCritical("file operation failed: %s", qPrintable(windowsErrorString(::GetLastError()))); + qCritical("file operation failed: %s", qUtf8Printable(windowsErrorString(::GetLastError()))); } } diff --git a/src/messagedialog.cpp b/src/messagedialog.cpp index 90b0a9d3..6c6de3e7 100644 --- a/src/messagedialog.cpp +++ b/src/messagedialog.cpp @@ -81,7 +81,7 @@ void MessageDialog::resizeEvent(QResizeEvent *event) void MessageDialog::showMessage(const QString &text, QWidget *reference, bool bringToFront) { - qDebug("%s", qPrintable(text)); + qDebug("%s", qUtf8Printable(text)); if (reference != nullptr) { if (bringToFront || (qApp->activeWindow() != nullptr)) { MessageDialog *dialog = new MessageDialog(text, reference); diff --git a/src/moapplication.cpp b/src/moapplication.cpp index 9ddd9e54..3a791827 100644 --- a/src/moapplication.cpp +++ b/src/moapplication.cpp @@ -137,7 +137,7 @@ void MOApplication::updateStyle(const QString &fileName) if (QFile::exists(fileName)) { setStyleSheet(QString("file:///%1").arg(fileName)); } else { - qWarning("invalid stylesheet: %s", qPrintable(fileName)); + qWarning("invalid stylesheet: %s", qUtf8Printable(fileName)); } } } diff --git a/src/modinforegular.cpp b/src/modinforegular.cpp index 548e3178..45c3985b 100644 --- a/src/modinforegular.cpp +++ b/src/modinforegular.cpp @@ -302,7 +302,7 @@ bool ModInfoRegular::setName(const QString &name) } else { if (!shellRename(modDir.absoluteFilePath(m_Name), modDir.absoluteFilePath(name))) { qCritical("failed to rename mod %s (errorcode %d)", - qPrintable(name), ::GetLastError()); + qUtf8Printable(name), ::GetLastError()); return false; } } diff --git a/src/modlist.cpp b/src/modlist.cpp index 2cb74d50..c1954b39 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -960,7 +960,7 @@ bool ModList::dropURLs(const QMimeData *mimeData, int row, const QModelIndex &pa QString overwriteName = ModInfo::getByIndex(overwriteIndex)->name(); for (const QUrl &url : mimeData->urls()) { - qDebug("URL drop requested: %s", qPrintable(url.toLocalFile())); + qDebug("URL drop requested: %s", qUtf8Printable(url.toLocalFile())); if (!url.isLocalFile()) { qDebug("URL drop ignored: Not a local file."); continue; diff --git a/src/nexusinterface.cpp b/src/nexusinterface.cpp index e97e9800..c6f05405 100644 --- a/src/nexusinterface.cpp +++ b/src/nexusinterface.cpp @@ -226,7 +226,7 @@ void NexusInterface::interpretNexusFileName(const QString &fileName, QString &mo } else { modID = strtol(candidate.c_str(), nullptr, 10); } - qDebug("mod id guessed: %s -> %d", qPrintable(fileName), modID); + qDebug("mod id guessed: %s -> %d", qUtf8Printable(fileName), modID); } else if (std::regex_search(fileNameUTF8.constData(), result, simpleexp)) { qDebug("simple expression matched, using name only"); modName = QString::fromUtf8(result[1].str().c_str()); @@ -542,7 +542,7 @@ void NexusInterface::requestFinished(std::list::iterator iter) if (nexusError.length() == 0) { nexusError = tr("empty response"); } - qDebug("nexus error: %s", qPrintable(nexusError)); + qDebug("nexus error: %s", qUtf8Printable(nexusError)); emit nxmRequestFailed(iter->m_GameName, iter->m_ModID, iter->m_FileID, iter->m_UserData, iter->m_ID, nexusError); } else { bool ok; @@ -602,8 +602,8 @@ void NexusInterface::requestError(QNetworkReply::NetworkError) } qCritical("request (%s) error: %s (%d)", - qPrintable(reply->url().toString()), - qPrintable(reply->errorString()), + qUtf8Printable(reply->url().toString()), + qUtf8Printable(reply->errorString()), reply->error()); } diff --git a/src/nxmaccessmanager.cpp b/src/nxmaccessmanager.cpp index 426c8b9c..912eab30 100644 --- a/src/nxmaccessmanager.cpp +++ b/src/nxmaccessmanager.cpp @@ -106,7 +106,7 @@ void NXMAccessManager::showCookies() const for (const QNetworkCookie &cookie : cookieJar()->cookiesForUrl(url)) { qDebug("%s - %s (expires: %s)", cookie.name().constData(), cookie.value().constData(), - qPrintable(cookie.expirationDate().toString())); + qUtf8Printable(cookie.expirationDate().toString())); } } @@ -164,7 +164,7 @@ void NXMAccessManager::retrieveCredentials() connect(reply, static_cast(&QNetworkReply::error), [=] (QNetworkReply::NetworkError) { - qDebug("failed to retrieve account credentials: %s", qPrintable(reply->errorString())); + qDebug("failed to retrieve account credentials: %s", qUtf8Printable(reply->errorString())); reply->deleteLater(); }); } @@ -235,7 +235,7 @@ QString NXMAccessManager::userAgent(const QString &subModule) const void NXMAccessManager::pageLogin() { - qDebug("logging %s in on Nexus", qPrintable(m_Username)); + qDebug("logging %s in on Nexus", qUtf8Printable(m_Username)); QString requestString = (Nexus_Management_URL + "/Sessions/?Login&uri=%1") .arg(QString(QUrl::toPercentEncoding(Nexus_Management_URL))); diff --git a/src/organizercore.cpp b/src/organizercore.cpp index 9ebe9f47..c4029a6d 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -47,7 +47,7 @@ #include #include -#include // for qPrintable, etc +#include // for qUtf8Printable, etc #include #include @@ -89,8 +89,8 @@ static bool isOnline() continue; } qDebug("interface %s seems to be up (address: %s)", - qPrintable(iter->humanReadableName()), - qPrintable(addresses[0].ip().toString())); + qUtf8Printable(iter->humanReadableName()), + qUtf8Printable(addresses[0].ip().toString())); connected = true; } } @@ -640,7 +640,7 @@ bool OrganizerCore::nexusLogin(bool retry) if ((!retry && m_Settings.getNexusLogin(username, password)) || (m_AskForNexusPW && queryLogin(username, password))) { // credentials stored or user entered them manually - qDebug("attempt login with username %s", qPrintable(username)); + qDebug("attempt login with username %s", qUtf8Printable(username)); accessManager->login(username, password); return true; } else { @@ -681,7 +681,7 @@ void OrganizerCore::startMOUpdate() void OrganizerCore::downloadRequestedNXM(const QString &url) { - qDebug("download requested: %s", qPrintable(url)); + qDebug("download requested: %s", qUtf8Printable(url)); if (nexusLogin()) { m_PendingDownloads.append(url); } else { @@ -1116,7 +1116,7 @@ QStringList OrganizerCore::findFiles( } } } else { - qWarning("directory %s not found", qPrintable(path)); + qWarning("directory %s not found", qUtf8Printable(path)); } return result; } @@ -1135,7 +1135,7 @@ QStringList OrganizerCore::getFileOrigins(const QString &fileName) const ToQString(m_DirectoryStructure->getOriginByID(i.first).getName())); } } else { - qDebug("%s not found", qPrintable(fileName)); + qDebug("%s not found", qUtf8Printable(fileName)); } return result; } @@ -1402,7 +1402,7 @@ HANDLE OrganizerCore::spawnBinaryProcess(const QFileInfo &binary, } } else { qDebug("start of \"%s\" canceled by plugin", - qPrintable(binary.absoluteFilePath())); + qUtf8Printable(binary.absoluteFilePath())); return INVALID_HANDLE_VALUE; } } @@ -1781,7 +1781,7 @@ void OrganizerCore::updateModActiveState(int index, bool active) dir.entryList(QStringList() << "*.esm", QDir::Files)) { const FileEntry::Ptr file = m_DirectoryStructure->findFile(ToWString(esm)); if (file.get() == nullptr) { - qWarning("failed to activate %s", qPrintable(esm)); + qWarning("failed to activate %s", qUtf8Printable(esm)); continue; } @@ -1797,7 +1797,7 @@ void OrganizerCore::updateModActiveState(int index, bool active) dir.entryList(QStringList() << "*.esl", QDir::Files)) { const FileEntry::Ptr file = m_DirectoryStructure->findFile(ToWString(esl)); if (file.get() == nullptr) { - qWarning("failed to activate %s", qPrintable(esl)); + qWarning("failed to activate %s", qUtf8Printable(esl)); continue; } @@ -1813,7 +1813,7 @@ void OrganizerCore::updateModActiveState(int index, bool active) for (const QString &esp : esps) { const FileEntry::Ptr file = m_DirectoryStructure->findFile(ToWString(esp)); if (file.get() == nullptr) { - qWarning("failed to activate %s", qPrintable(esp)); + qWarning("failed to activate %s", qUtf8Printable(esp)); continue; } @@ -2140,7 +2140,7 @@ std::vector OrganizerCore::activeProblems() const // of a "log spam". But since this is a sevre error which will most likely make the // game crash/freeze/etc. and is very hard to diagnose, this "log spam" will make it // easier for the user to notice the warning. - qWarning("hook.dll found in game folder: %s", qPrintable(hookdll)); + qWarning("hook.dll found in game folder: %s", qUtf8Printable(hookdll)); problems.push_back(PROBLEM_MO1SCRIPTEXTENDERWORKAROUND); } return problems; diff --git a/src/persistentcookiejar.cpp b/src/persistentcookiejar.cpp index a6eb78fa..1ed463c6 100644 --- a/src/persistentcookiejar.cpp +++ b/src/persistentcookiejar.cpp @@ -11,7 +11,7 @@ PersistentCookieJar::PersistentCookieJar(const QString &fileName, QObject *paren } PersistentCookieJar::~PersistentCookieJar() { - qDebug("save %s", qPrintable(m_FileName)); + qDebug("save %s", qUtf8Printable(m_FileName)); save(); } @@ -40,14 +40,14 @@ void PersistentCookieJar::save() { QFile oldCookies(m_FileName); if (oldCookies.exists()) { if (!oldCookies.remove()) { - qCritical("failed to save cookies: failed to remove %s", qPrintable(m_FileName)); + qCritical("failed to save cookies: failed to remove %s", qUtf8Printable(m_FileName)); return; } } // if it doesn't exists that's fine } if (!file.copy(m_FileName)) { - qCritical("failed to save cookies: failed to write %s", qPrintable(m_FileName)); + qCritical("failed to save cookies: failed to write %s", qUtf8Printable(m_FileName)); } } diff --git a/src/plugincontainer.cpp b/src/plugincontainer.cpp index 8935c472..46a95f0c 100644 --- a/src/plugincontainer.cpp +++ b/src/plugincontainer.cpp @@ -160,12 +160,12 @@ bool PluginContainer::registerPlugin(QObject *plugin, const QString &fileName) for (QObject *proxiedPlugin : matchingPlugins) { if (proxiedPlugin != nullptr) { if (registerPlugin(proxiedPlugin, pluginName)) { - qDebug("loaded plugin \"%s\"", qPrintable(QFileInfo(pluginName).fileName())); + qDebug("loaded plugin \"%s\"", qUtf8Printable(QFileInfo(pluginName).fileName())); } else { qWarning("plugin \"%s\" failed to load. If this plugin is for an older version of MO " "you have to update it or delete it if no update exists.", - qPrintable(pluginName)); + qUtf8Printable(pluginName)); } } } @@ -220,7 +220,7 @@ void PluginContainer::unloadPlugins() QPluginLoader *loader = m_PluginLoaders.back(); m_PluginLoaders.pop_back(); if ((loader != nullptr) && !loader->unload()) { - qDebug("failed to unload %s: %s", qPrintable(loader->fileName()), qPrintable(loader->errorString())); + qDebug("failed to unload %s: %s", qUtf8Printable(loader->fileName()), qUtf8Printable(loader->errorString())); } delete loader; } @@ -275,7 +275,7 @@ void PluginContainer::loadPlugins() while (iter.hasNext()) { iter.next(); if (m_Organizer->settings().pluginBlacklisted(iter.fileName())) { - qDebug("plugin \"%s\" blacklisted", qPrintable(iter.fileName())); + qDebug("plugin \"%s\" blacklisted", qUtf8Printable(iter.fileName())); continue; } loadCheck.write(iter.fileName().toUtf8()); @@ -287,14 +287,14 @@ void PluginContainer::loadPlugins() if (pluginLoader->instance() == nullptr) { m_FailedPlugins.push_back(pluginName); qCritical("failed to load plugin %s: %s", - qPrintable(pluginName), qPrintable(pluginLoader->errorString())); + qUtf8Printable(pluginName), qUtf8Printable(pluginLoader->errorString())); } else { if (registerPlugin(pluginLoader->instance(), pluginName)) { - qDebug("loaded plugin \"%s\"", qPrintable(QFileInfo(pluginName).fileName())); + qDebug("loaded plugin \"%s\"", qUtf8Printable(QFileInfo(pluginName).fileName())); m_PluginLoaders.push_back(pluginLoader.release()); } else { m_FailedPlugins.push_back(pluginName); - qWarning("plugin \"%s\" failed to load (may be outdated)", qPrintable(pluginName)); + qWarning("plugin \"%s\" failed to load (may be outdated)", qUtf8Printable(pluginName)); } } } diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp index 5171bf19..6f417331 100644 --- a/src/pluginlist.cpp +++ b/src/pluginlist.cpp @@ -182,7 +182,7 @@ void PluginList::refresh(const QString &profileName ba2Reg.setPatternSyntax(QRegExp::Wildcard); ba2Reg.setCaseSensitivity(Qt::CaseInsensitive); - //TODO: try QRegularExpression when we move to Qt5.12 + //TODO: try QRegularExpression when we move to Qt5.12 /*QRegularExpression bsaReg = QRegularExpression(); QRegularExpression ba2Reg = QRegularExpression(); bsaReg.setPatternOptions(QRegularExpression::CaseInsensitiveOption); @@ -435,7 +435,7 @@ void PluginList::addInformation(const QString &name, const QString &message) if (iter != m_ESPsByName.end()) { m_AdditionalInfo[name.toLower()].m_Messages.append(message); } else { - qWarning("failed to associate message for \"%s\"", qPrintable(name)); + qWarning("failed to associate message for \"%s\"", qUtf8Printable(name)); } } @@ -499,7 +499,7 @@ void PluginList::writeLockedOrder(const QString &fileName) const file->write(QString("%1|%2\r\n").arg(iter->first).arg(iter->second).toUtf8()); } file.commit(); - qDebug("%s saved", QDir::toNativeSeparators(fileName).toUtf8().constData()); + qDebug("%s saved", qUtf8Printable(QDir::toNativeSeparators(fileName))); } @@ -524,7 +524,7 @@ void PluginList::saveTo(const QString &lockedOrderFileName } } if (deleterFile.commitIfDifferent(m_LastSaveHash[deleterFileName])) { - qDebug("%s saved", qPrintable(QDir::toNativeSeparators(deleterFileName))); + qDebug("%s saved", qUtf8Printable(QDir::toNativeSeparators(deleterFileName))); } } else if (QFile::exists(deleterFileName)) { shellDelete(QStringList() << deleterFileName); @@ -712,7 +712,7 @@ void PluginList::setState(const QString &name, PluginStates state) { m_ESPs[iter->second].m_Enabled = (state == IPluginList::STATE_ACTIVE) || m_ESPs[iter->second].m_ForceEnabled; } else { - qWarning("plugin %s not found", qPrintable(name)); + qWarning("plugin %s not found", qUtf8Printable(name)); } } @@ -1386,7 +1386,7 @@ PluginList::ESPInfo::ESPInfo(const QString &name, bool enabled, m_Masters.insert(QString(iter->c_str())); } } catch (const std::exception &e) { - qCritical("failed to parse plugin file %s: %s", qPrintable(fullPath), e.what()); + qCritical("failed to parse plugin file %s: %s", qUtf8Printable(fullPath), e.what()); m_IsMaster = false; m_IsLight = false; m_IsLightFlagged = false; diff --git a/src/profile.cpp b/src/profile.cpp index 9da1a698..e8ead8e8 100644 --- a/src/profile.cpp +++ b/src/profile.cpp @@ -40,7 +40,7 @@ along with Mod Organizer. If not, see . #include #include // for QStringList #include // for qDebug, qWarning, etc -#include // for qPrintable +#include // for qUtf8Printable #include #include @@ -124,7 +124,7 @@ Profile::Profile(const QDir &directory, IPluginGame const *gamePlugin) findProfileSettings(); if (!QFile::exists(m_Directory.filePath("modlist.txt"))) { - qWarning("missing modlist.txt in %s", qPrintable(directory.path())); + qWarning("missing modlist.txt in %s", qUtf8Printable(directory.path())); touchFile(m_Directory.filePath("modlist.txt")); } @@ -252,7 +252,7 @@ void Profile::doWriteModlist() } if (file.commitIfDifferent(m_LastModlistHash)) { - qDebug("%s saved", QDir::toNativeSeparators(fileName).toUtf8().constData()); + qDebug("%s saved", qUtf8Printable(QDir::toNativeSeparators(fileName))); } } catch (const std::exception &e) { reportError(tr("failed to write mod list: %1").arg(e.what())); @@ -288,7 +288,7 @@ void Profile::createTweakedIniFile() if (error) { reportError(tr("failed to create tweaked ini: %1").arg(getCurrentErrorString().c_str())); } - qDebug("%s saved", qPrintable(QDir::toNativeSeparators(tweakedIni))); + qDebug("%s saved", qUtf8Printable(QDir::toNativeSeparators(tweakedIni))); } // static @@ -303,7 +303,7 @@ void Profile::renameModInAllProfiles(const QString& oldName, const QString& newN if (modList.exists()) renameModInList(modList, oldName, newName); else - qWarning("Profile has no modlist.txt : %s", qPrintable(profileIter.filePath())); + qWarning("Profile has no modlist.txt : %s", qUtf8Printable(profileIter.filePath())); } } @@ -361,7 +361,7 @@ void Profile::renameModInList(QFile &modList, const QString &oldName, const QStr if (renamed) qDebug("Renamed %d \"%s\" mod to \"%s\" in %s", - renamed, qPrintable(oldName), qPrintable(newName), qPrintable(modList.fileName())); + renamed, qUtf8Printable(oldName), qUtf8Printable(newName), qUtf8Printable(modList.fileName())); } void Profile::refreshModStatus() @@ -421,13 +421,13 @@ void Profile::refreshModStatus() } } else { qWarning("no mod state for \"%s\" (profile \"%s\")", - qPrintable(modName), m_Directory.path().toUtf8().constData()); + qUtf8Printable(modName), m_Directory.path().toUtf8().constData()); // need to rewrite the modlist to fix this modStatusModified = true; } } else { qDebug("mod \"%s\" (profile \"%s\") not found", - qPrintable(modName), m_Directory.path().toUtf8().constData()); + qUtf8Printable(modName), m_Directory.path().toUtf8().constData()); // need to rewrite the modlist to fix this modStatusModified = true; } @@ -775,7 +775,7 @@ bool Profile::localSettingsEnabled() const QStringList missingFiles; for (QString file : m_GamePlugin->iniFiles()) { if (!QFile::exists(m_Directory.filePath(file))) { - qWarning("missing %s in %s", qPrintable(file), qPrintable(m_Directory.path())); + qWarning("missing %s in %s", qUtf8Printable(file), qUtf8Printable(m_Directory.path())); missingFiles << file; } } diff --git a/src/profilesdialog.cpp b/src/profilesdialog.cpp index 17844357..f9ea655f 100644 --- a/src/profilesdialog.cpp +++ b/src/profilesdialog.cpp @@ -214,7 +214,7 @@ void ProfilesDialog::on_removeProfileButton_clicked() delete item; } if (!shellDelete(QStringList(profilePath))) { - qWarning("Failed to shell-delete \"%s\" (errorcode %lu), trying regular delete", qPrintable(profilePath), ::GetLastError()); + qWarning("Failed to shell-delete \"%s\" (errorcode %lu), trying regular delete", qUtf8Printable(profilePath), ::GetLastError()); if (!removeDir(profilePath)) { qWarning("regular delete failed too"); } diff --git a/src/selfupdater.cpp b/src/selfupdater.cpp index d26ca96c..cdcbc2f4 100644 --- a/src/selfupdater.cpp +++ b/src/selfupdater.cpp @@ -145,15 +145,15 @@ void SelfUpdater::testForUpdate() if (newestVer > this->m_MOVersion) { m_UpdateCandidate = newest; qDebug("update available: %s -> %s", - qPrintable(this->m_MOVersion.displayString()), - qPrintable(newestVer.displayString())); + qUtf8Printable(this->m_MOVersion.displayString()), + qUtf8Printable(newestVer.displayString())); emit updateAvailable(); } else if (newestVer < this->m_MOVersion) { // this could happen if the user switches from using prereleases to // stable builds. Should we downgrade? qDebug("this version is newer than the newest installed one: %s -> %s", - qPrintable(this->m_MOVersion.displayString()), - qPrintable(newestVer.displayString())); + qUtf8Printable(this->m_MOVersion.displayString()), + qUtf8Printable(newestVer.displayString())); } } }); @@ -224,7 +224,7 @@ void SelfUpdater::closeProgress() void SelfUpdater::openOutputFile(const QString &fileName) { QString outputPath = QDir::fromNativeSeparators(qApp->property("dataPath").toString()) + "/" + fileName; - qDebug("downloading to %s", qPrintable(outputPath)); + qDebug("downloading to %s", qUtf8Printable(outputPath)); m_UpdateFile.setFileName(outputPath); m_UpdateFile.open(QIODevice::WriteOnly); } diff --git a/src/settings.cpp b/src/settings.cpp index 8f768fd2..5cfe427b 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -167,7 +167,7 @@ void Settings::registerPlugin(IPlugin *plugin) QVariant temp = m_Settings.value("Plugins/" + plugin->name() + "/" + setting.key, setting.defaultValue); if (!temp.convert(setting.defaultValue.type())) { qWarning("failed to interpret \"%s\" as correct type for \"%s\" in plugin \"%s\", using default", - qPrintable(temp.toString()), qPrintable(setting.key), qPrintable(plugin->name())); + qUtf8Printable(temp.toString()), qUtf8Printable(setting.key), qUtf8Printable(plugin->name())); temp = setting.defaultValue; } m_PluginSettings[plugin->name()][setting.key] = temp; @@ -574,7 +574,7 @@ void Settings::updateServers(const QList &servers) QVariantMap val = m_Settings.value(key).toMap(); QDate lastSeen = val["lastSeen"].toDate(); if (lastSeen.daysTo(now) > 30) { - qDebug("removing server %s since it hasn't been available for downloads in over a month", qPrintable(key)); + qDebug("removing server %s since it hasn't been available for downloads in over a month", qUtf8Printable(key)); m_Settings.remove(key); } } diff --git a/src/usvfsconnector.cpp b/src/usvfsconnector.cpp index 9c81d0d9..ef7314c0 100644 --- a/src/usvfsconnector.cpp +++ b/src/usvfsconnector.cpp @@ -61,7 +61,7 @@ LogWorker::LogWorker() { m_LogFile.open(QIODevice::WriteOnly); qDebug("usvfs log messages are written to %s", - qPrintable(m_LogFile.fileName())); + qUtf8Printable(m_LogFile.fileName())); } LogWorker::~LogWorker() -- cgit v1.3.1 From f2ea231f9212006f43ec29faa6c5b47810748a99 Mon Sep 17 00:00:00 2001 From: Al Date: Sun, 6 Jan 2019 21:54:11 +0100 Subject: Made Delete INIs and Saves dialogs remember selection. --- src/profile.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'src/profile.cpp') diff --git a/src/profile.cpp b/src/profile.cpp index e8ead8e8..09c2a5f5 100644 --- a/src/profile.cpp +++ b/src/profile.cpp @@ -31,6 +31,7 @@ along with Mod Organizer. If not, see . #include #include "util.h" #include "registry.h" +#include #include #include // for QFile @@ -749,12 +750,12 @@ bool Profile::enableLocalSaves(bool enable) m_Directory.mkdir("saves"); } } else { - QMessageBox::StandardButton res = QMessageBox::question( - QApplication::activeModalWidget(), tr("Delete profile-specific save games?"), + QDialogButtonBox::StandardButton res; + res = QuestionBoxMemory::query(QApplication::activeModalWidget(), "deleteSavesQuery", + tr("Delete profile-specific save games?"), tr("Do you want to delete the profile-specific save games? (If you select \"No\", the " "save games will show up again if you re-enable profile-specific save games)"), - QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, - QMessageBox::Cancel); + QDialogButtonBox::No | QDialogButtonBox::Yes | QDialogButtonBox::Cancel, QDialogButtonBox::No); if (res == QMessageBox::Yes) { shellDelete(QStringList(m_Directory.absoluteFilePath("saves"))); } else if (res == QMessageBox::No) { @@ -797,12 +798,12 @@ bool Profile::enableLocalSettings(bool enable) if (enable) { m_GamePlugin->initializeProfile(m_Directory.absolutePath(), IPluginGame::CONFIGURATION); } else { - QMessageBox::StandardButton res = QMessageBox::question( - QApplication::activeModalWidget(), tr("Delete profile-specific game INI files?"), + QDialogButtonBox::StandardButton res; + res = QuestionBoxMemory::query(QApplication::activeModalWidget(), "deleteINIQuery", + tr("Delete profile-specific game INI files?"), tr("Do you want to delete the profile-specific game INI files? (If you select \"No\", the " "INI files will be used again if you re-enable profile-specific game INI files.)"), - QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, - QMessageBox::Cancel); + QDialogButtonBox::No | QDialogButtonBox::Yes | QDialogButtonBox::Cancel, QDialogButtonBox::No); if (res == QMessageBox::Yes) { QStringList filesToDelete; for (QString file : m_GamePlugin->iniFiles()) { -- cgit v1.3.1 From 347ac2b8b5f34a2583ae7844e0dfd79773657270 Mon Sep 17 00:00:00 2001 From: LostDragonist Date: Fri, 11 Jan 2019 01:39:05 -0600 Subject: Support for force loading libraries --- src/CMakeLists.txt | 6 + src/aboutdialog.ui | 8 +- src/editexecutablesdialog.cpp | 47 ++- src/editexecutablesdialog.h | 6 + src/editexecutablesdialog.ui | 37 ++ src/forcedloaddialog.cpp | 76 ++++ src/forcedloaddialog.h | 32 ++ src/forcedloaddialog.ui | 117 ++++++ src/forcedloaddialogwidget.cpp | 87 ++++ src/forcedloaddialogwidget.h | 38 ++ src/forcedloaddialogwidget.ui | 104 +++++ src/mainwindow.cpp | 21 +- src/organizer.pro | 12 +- src/organizer_en.ts | 893 +++++++++++++++++++++++------------------ src/organizercore.cpp | 34 +- src/organizercore.h | 8 +- src/profile.cpp | 118 +++++- src/profile.h | 13 + src/settings.cpp | 4 +- src/settings.h | 4 +- src/settingsdialog.cpp | 6 +- src/usvfsconnector.cpp | 18 +- src/usvfsconnector.h | 3 + 23 files changed, 1260 insertions(+), 432 deletions(-) create mode 100644 src/forcedloaddialog.cpp create mode 100644 src/forcedloaddialog.h create mode 100644 src/forcedloaddialog.ui create mode 100644 src/forcedloaddialogwidget.cpp create mode 100644 src/forcedloaddialogwidget.h create mode 100644 src/forcedloaddialogwidget.ui (limited to 'src/profile.cpp') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4c883cf5..5cbd5aa9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -92,6 +92,8 @@ SET(organizer_SRCS moshortcut.cpp listdialog.cpp lcdnumber.cpp + forcedloaddialog.cpp + forcedloaddialogwidget.cpp shared/windows_error.cpp shared/error_report.cpp @@ -187,6 +189,8 @@ SET(organizer_HDRS moshortcut.h listdialog.h lcdnumber.h + forcedloaddialog.h + forcedloaddialogwidget.h shared/windows_error.h shared/error_report.h @@ -226,6 +230,8 @@ SET(organizer_UIS browserdialog.ui aboutdialog.ui listdialog.ui + forcedloaddialog.ui + forcedloaddialogwidget.ui ) SET(organizer_QRCS diff --git a/src/aboutdialog.ui b/src/aboutdialog.ui index 98a76061..ac7db1fc 100644 --- a/src/aboutdialog.ui +++ b/src/aboutdialog.ui @@ -161,7 +161,7 @@ - + QAbstractItemView::NoSelection @@ -202,7 +202,7 @@ - + QAbstractItemView::NoSelection @@ -231,7 +231,7 @@ Translators - + @@ -363,7 +363,7 @@ Other Supporters && Contributors - + diff --git a/src/editexecutablesdialog.cpp b/src/editexecutablesdialog.cpp index be2ee127..212993f1 100644 --- a/src/editexecutablesdialog.cpp +++ b/src/editexecutablesdialog.cpp @@ -25,7 +25,8 @@ along with Mod Organizer. If not, see . #include #include #include - +#include "forcedloaddialog.h" +#include using namespace MOBase; using namespace MOShared; @@ -44,6 +45,8 @@ EditExecutablesDialog::EditExecutablesDialog( refreshExecutablesWidget(); ui->newFilesModBox->addItems(modList.allMods()); + + m_ForcedLibraries = m_Profile->determineForcedLibraries(ui->titleEdit->text()); } EditExecutablesDialog::~EditExecutablesDialog() @@ -93,6 +96,7 @@ void EditExecutablesDialog::resetInput() ui->overwriteAppIDBox->setChecked(false); ui->useAppIconCheckBox->setChecked(false); ui->newFilesModCheckBox->setChecked(false); + ui->forceLoadCheckBox->setChecked(false); m_CurrentItem = nullptr; } @@ -118,6 +122,9 @@ void EditExecutablesDialog::saveExecutable() else { m_Profile->removeSetting("custom_overwrites", ui->titleEdit->text()); } + + m_Profile->saveForcedLibraries(ui->titleEdit->text(), m_ForcedLibraries); + m_Profile->setForcedLibrariesEnabled(ui->titleEdit->text(), ui->forceLoadCheckBox->isChecked()); } @@ -130,6 +137,21 @@ void EditExecutablesDialog::delayedRefresh() } +void EditExecutablesDialog::on_forceLoadButton_clicked() +{ + ForcedLoadDialog dialog(this); + dialog.setValues(m_ForcedLibraries); + if (dialog.exec() == QDialog::Accepted) { + m_ForcedLibraries = dialog.values(); + } +} + +void EditExecutablesDialog::on_forceLoadCheckBox_toggled() +{ + ui->forceLoadButton->setEnabled(ui->forceLoadCheckBox->isChecked()); +} + + void EditExecutablesDialog::on_addButton_clicked() { if (executableChanged()) { @@ -231,6 +253,20 @@ bool EditExecutablesDialog::executableChanged() QString storedCustomOverwrite = m_Profile->setting("custom_overwrites", selectedExecutable.m_Title).toString(); + bool forcedLibrariesDirty = false; + auto forcedLibaries = m_Profile->determineForcedLibraries(selectedExecutable.m_Title); + forcedLibrariesDirty |= !std::equal(forcedLibaries.begin(), forcedLibaries.end(), + m_ForcedLibraries.begin(), m_ForcedLibraries.end(), + [](const ExecutableForcedLoadSetting &lhs, const ExecutableForcedLoadSetting &rhs) + { + return lhs.enabled() == rhs.enabled() && + lhs.forced() == rhs.forced() && + lhs.library() == rhs.library() && + lhs.process() == rhs.process(); + }); + forcedLibrariesDirty |= m_Profile->setting("forced_libraries", ui->titleEdit->text() + "/enabled", false).toBool() != + ui->forceLoadCheckBox->isChecked(); + return selectedExecutable.m_Title != ui->titleEdit->text() || selectedExecutable.m_Arguments != ui->argumentsEdit->text() || selectedExecutable.m_SteamAppID != ui->appIDOverwriteEdit->text() @@ -238,7 +274,9 @@ bool EditExecutablesDialog::executableChanged() || !storedCustomOverwrite.isEmpty() && (storedCustomOverwrite != ui->newFilesModBox->currentText()) || selectedExecutable.m_WorkingDirectory != QDir::fromNativeSeparators(ui->workingDirEdit->text()) || selectedExecutable.m_BinaryInfo.absoluteFilePath() != QDir::fromNativeSeparators(ui->binaryEdit->text()) - || selectedExecutable.usesOwnIcon() != ui->useAppIconCheckBox->isChecked(); + || selectedExecutable.usesOwnIcon() != ui->useAppIconCheckBox->isChecked() + || forcedLibrariesDirty + ; } else { QFileInfo fileInfo(ui->binaryEdit->text()); return !ui->binaryEdit->text().isEmpty() @@ -331,6 +369,11 @@ void EditExecutablesDialog::on_executablesListBox_clicked(const QModelIndex &cur if (index != -1) { ui->newFilesModBox->setCurrentIndex(index); } + + m_ForcedLibraries = m_Profile->determineForcedLibraries(ui->titleEdit->text()); + bool forcedLibraries = m_Profile->forcedLibrariesEnabled(ui->titleEdit->text()); + ui->forceLoadButton->setEnabled(forcedLibraries); + ui->forceLoadCheckBox->setChecked(forcedLibraries); } } diff --git a/src/editexecutablesdialog.h b/src/editexecutablesdialog.h index 0f3dbaff..82e63e15 100644 --- a/src/editexecutablesdialog.h +++ b/src/editexecutablesdialog.h @@ -92,6 +92,10 @@ private slots: void on_executablesListBox_clicked(const QModelIndex &index); + void on_forceLoadButton_clicked(); + + void on_forceLoadCheckBox_toggled(); + private: void resetInput(); @@ -108,6 +112,8 @@ private: ExecutablesList m_ExecutablesList; Profile *m_Profile; + + QList m_ForcedLibraries; }; #endif // EDITEXECUTABLESDIALOG_H diff --git a/src/editexecutablesdialog.ui b/src/editexecutablesdialog.ui index bdbb8bd1..4f9223d5 100644 --- a/src/editexecutablesdialog.ui +++ b/src/editexecutablesdialog.ui @@ -191,6 +191,43 @@ Right now the only case I know of where this needs to be overwritten is for the + + + + + + If this is enabled, the configured libraries will be automatically loaded when this executable is launched. + + + Force Load Libraries (*) + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + Configure Libraries + + + + + diff --git a/src/forcedloaddialog.cpp b/src/forcedloaddialog.cpp new file mode 100644 index 00000000..ad30a58c --- /dev/null +++ b/src/forcedloaddialog.cpp @@ -0,0 +1,76 @@ +#include "forcedloaddialog.h" +#include "ui_forcedloaddialog.h" + +#include "forcedloaddialogwidget.h" + +#include +#include + +using namespace MOBase; + +ForcedLoadDialog::ForcedLoadDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::ForcedLoadDialog) +{ + ui->setupUi(this); +} + +ForcedLoadDialog::~ForcedLoadDialog() +{ + delete ui; +} + +void ForcedLoadDialog::setValues(QList &values) +{ + ui->tableWidget->clearContents(); + + for (int i = 0; i < values.count(); i++) { + ForcedLoadDialogWidget *item = new ForcedLoadDialogWidget(this); + item->setEnabled(values[i].enabled()); + item->setProcess(values[i].process()); + item->setLibraryPath(values[i].library()); + item->setForced(values[i].forced()); + + ui->tableWidget->insertRow(i); + ui->tableWidget->setCellWidget(i, 0, item); + } + + ui->tableWidget->resizeRowsToContents(); +} + +QList ForcedLoadDialog::values() +{ + QList results; + for (int row = 0; row < ui->tableWidget->rowCount(); row++) { + auto widget = (ForcedLoadDialogWidget*)ui->tableWidget->cellWidget(row, 0); + results.append( + ExecutableForcedLoadSetting( + widget->getProcess(), + widget->getLibraryPath() + ).withEnabled(widget->getEnabled()) + .withForced(widget->getForced()) + ); + } + return results; +} + + +void ForcedLoadDialog::on_addRowButton_clicked() +{ + int row = ui->tableWidget->rowCount(); + ui->tableWidget->insertRow(row); + ForcedLoadDialogWidget *item = new ForcedLoadDialogWidget(this); + ui->tableWidget->setCellWidget(row, 0, item); + ui->tableWidget->resizeRowsToContents(); +} + +void ForcedLoadDialog::on_deleteRowButton_clicked() +{ + for (auto rowIndex: ui->tableWidget->selectionModel()->selectedRows()) { + int row = rowIndex.row(); + auto widget = (ForcedLoadDialogWidget*)ui->tableWidget->cellWidget(row, 0); + if (!widget->getForced()){ + ui->tableWidget->removeRow(row); + } + } +} diff --git a/src/forcedloaddialog.h b/src/forcedloaddialog.h new file mode 100644 index 00000000..68460d91 --- /dev/null +++ b/src/forcedloaddialog.h @@ -0,0 +1,32 @@ +#ifndef FORCEDLOADDIALOG_H +#define FORCEDLOADDIALOG_H + +#include +#include + +#include "executableinfo.h" + +namespace Ui { +class ForcedLoadDialog; +} + +class ForcedLoadDialog : public QDialog +{ + Q_OBJECT + +public: + explicit ForcedLoadDialog(QWidget *parent = nullptr); + ~ForcedLoadDialog(); + + void setValues(QList &values); + QList values(); + +private slots: + void on_addRowButton_clicked(); + void on_deleteRowButton_clicked(); + +private: + Ui::ForcedLoadDialog *ui; +}; + +#endif // FORCEDLOADDIALOG_H diff --git a/src/forcedloaddialog.ui b/src/forcedloaddialog.ui new file mode 100644 index 00000000..9c5b2d10 --- /dev/null +++ b/src/forcedloaddialog.ui @@ -0,0 +1,117 @@ + + + ForcedLoadDialog + + + + 0 + 0 + 700 + 400 + + + + Forced Load Settings + + + + + + QAbstractItemView::NoEditTriggers + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + 1 + + + false + + + true + + + + + + + + + + Adds a row to the table. + + + Adds a row to the table. + + + Add Row + + + + + + + Deletes the selected row from the table. + + + Deletes the selected row from the table. + + + Delete Row + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + + buttonBox + accepted() + ForcedLoadDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + ForcedLoadDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/forcedloaddialogwidget.cpp b/src/forcedloaddialogwidget.cpp new file mode 100644 index 00000000..61805068 --- /dev/null +++ b/src/forcedloaddialogwidget.cpp @@ -0,0 +1,87 @@ +#include "forcedloaddialogwidget.h" +#include "ui_forcedloaddialogwidget.h" + +#include + +#include "executableinfo.h" + +ForcedLoadDialogWidget::ForcedLoadDialogWidget(QWidget *parent) : + QWidget(parent), + ui(new Ui::ForcedLoadDialogWidget) +{ + ui->setupUi(this); +} + +ForcedLoadDialogWidget::~ForcedLoadDialogWidget() +{ + delete ui; +} + +bool ForcedLoadDialogWidget::getEnabled() +{ + return ui->enabledBox->isChecked(); +} + +bool ForcedLoadDialogWidget::getForced() +{ + return m_Forced; +} + +QString ForcedLoadDialogWidget::getLibraryPath() +{ + return ui->libraryPathEdit->text(); +} + +QString ForcedLoadDialogWidget::getProcess() +{ + return ui->processEdit->text(); +} + +void ForcedLoadDialogWidget::setEnabled(bool enabled) +{ + ui->enabledBox->setChecked(enabled); +} + +void ForcedLoadDialogWidget::setForced(bool forced) +{ + m_Forced = forced; + ui->libraryPathBrowseButton->setEnabled(!forced); + ui->libraryPathEdit->setEnabled(!forced); + ui->processBrowseButton->setEnabled(!forced); + ui->processEdit->setEnabled(!forced); +} + +void ForcedLoadDialogWidget::setLibraryPath(QString &path) +{ + ui->libraryPathEdit->setText(path); +} + +void ForcedLoadDialogWidget::setProcess(QString &name) +{ + ui->processEdit->setText(name); +} + +void ForcedLoadDialogWidget::on_enabledBox_toggled() +{ + // anything to do? +} + +void ForcedLoadDialogWidget::on_libraryPathBrowseButton_clicked() +{ + QDir gameDir("D:/Games/Steam Library/steamapps/common/Fallout 4"); + QString startPath = gameDir.absolutePath(); + QString result = QFileDialog::getOpenFileName(nullptr, "Select a library...", startPath, "Dynamic link library (*.dll)", nullptr, QFileDialog::ReadOnly); + if (!result.isEmpty()) { + ui->libraryPathEdit->setText(result); + } +} + +void ForcedLoadDialogWidget::on_processBrowseButton_clicked() +{ + QDir gameDir("D:/Games/Steam Library/steamapps/common/Fallout 4"); + QString startPath = gameDir.absolutePath(); + QString result = QFileDialog::getOpenFileName(nullptr, "Select a process...", startPath, "Executable (*.exe)", nullptr, QFileDialog::ReadOnly); + if (!result.isEmpty()) { + ui->processEdit->setText(QFile(result).fileName()); + } +} diff --git a/src/forcedloaddialogwidget.h b/src/forcedloaddialogwidget.h new file mode 100644 index 00000000..06ad0009 --- /dev/null +++ b/src/forcedloaddialogwidget.h @@ -0,0 +1,38 @@ +#ifndef FORCEDLOADDIALOGWIDGET_H +#define FORCEDLOADDIALOGWIDGET_H + +#include + +namespace Ui { +class ForcedLoadDialogWidget; +} + +class ForcedLoadDialogWidget : public QWidget +{ + Q_OBJECT + +public: + explicit ForcedLoadDialogWidget(QWidget *parent = nullptr); + ~ForcedLoadDialogWidget(); + + bool getEnabled(); + bool getForced(); + QString getLibraryPath(); + QString getProcess(); + + void setEnabled(bool enabled); + void setForced(bool forced); + void setLibraryPath(QString &path); + void setProcess(QString &name); + +private slots: + void on_enabledBox_toggled(); + void on_libraryPathBrowseButton_clicked(); + void on_processBrowseButton_clicked(); + +private: + Ui::ForcedLoadDialogWidget *ui; + bool m_Forced; +}; + +#endif // FORCEDLOADDIALOGWIDGET_H diff --git a/src/forcedloaddialogwidget.ui b/src/forcedloaddialogwidget.ui new file mode 100644 index 00000000..4df78beb --- /dev/null +++ b/src/forcedloaddialogwidget.ui @@ -0,0 +1,104 @@ + + + ForcedLoadDialogWidget + + + + 0 + 0 + 400 + 41 + + + + + 0 + 0 + + + + Form + + + + + + + + + + + + + The name of the process that should be forced to load a library. + + + The name of the process that should be forced to load a library. + + + Process name + + + + + + + + 0 + 0 + + + + + 32 + 0 + + + + + 32 + 16777215 + + + + Browse for a process. + + + Browse for a process. + + + ... + + + + + + + Library to load + + + + + + + + 32 + 16777215 + + + + Browse for a library. + + + Browse for a library. + + + ... + + + + + + + + diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index c6dc145d..0ebad6ae 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1162,15 +1162,20 @@ void MainWindow::startExeAction() { QAction *action = qobject_cast(sender()); if (action != nullptr) { - const Executable &selectedExecutable( - m_OrganizerCore.executablesList()->find(action->text())); - QString customOverwrite= m_OrganizerCore.currentProfile()->setting("custom_overwrites", selectedExecutable.m_Title).toString(); + const Executable &selectedExecutable(m_OrganizerCore.executablesList()->find(action->text())); + QString customOverwrite = m_OrganizerCore.currentProfile()->setting("custom_overwrites", selectedExecutable.m_Title).toString(); + auto forcedLibraries = m_OrganizerCore.currentProfile()->determineForcedLibraries(selectedExecutable.m_Title); + if (!m_OrganizerCore.currentProfile()->forcedLibrariesEnabled(selectedExecutable.m_Title)) { + forcedLibraries.clear(); + } m_OrganizerCore.spawnBinary( selectedExecutable.m_BinaryInfo, selectedExecutable.m_Arguments, selectedExecutable.m_WorkingDirectory.length() != 0 ? selectedExecutable.m_WorkingDirectory : selectedExecutable.m_BinaryInfo.absolutePath(), - selectedExecutable.m_SteamAppID, customOverwrite); + selectedExecutable.m_SteamAppID, + customOverwrite, + forcedLibraries); } else { qCritical("not an action?"); } @@ -1957,12 +1962,18 @@ void MainWindow::on_startButton_clicked() { try { const Executable &selectedExecutable(getSelectedExecutable()); QString customOverwrite = m_OrganizerCore.currentProfile()->setting("custom_overwrites", selectedExecutable.m_Title).toString(); + auto forcedLibraries = m_OrganizerCore.currentProfile()->determineForcedLibraries(selectedExecutable.m_Title); + if (!m_OrganizerCore.currentProfile()->forcedLibrariesEnabled(selectedExecutable.m_Title)) { + forcedLibraries.clear(); + } m_OrganizerCore.spawnBinary( selectedExecutable.m_BinaryInfo, selectedExecutable.m_Arguments, selectedExecutable.m_WorkingDirectory.length() != 0 ? selectedExecutable.m_WorkingDirectory : selectedExecutable.m_BinaryInfo.absolutePath(), - selectedExecutable.m_SteamAppID, customOverwrite); + selectedExecutable.m_SteamAppID, + customOverwrite, + forcedLibraries); } catch (...) { ui->startButton->setEnabled(true); throw; diff --git a/src/organizer.pro b/src/organizer.pro index b8e79e0c..ddf676f2 100644 --- a/src/organizer.pro +++ b/src/organizer.pro @@ -92,7 +92,9 @@ SOURCES += \ modinfooverwrite.cpp \ modinfoforeign.cpp \ listdialog.cpp \ - lcdnumber.cpp + lcdnumber.cpp \ + forcedloaddialog.cpp \ + forcedloaddialogwidget.cpp HEADERS += \ @@ -169,7 +171,9 @@ HEADERS += \ modinfooverwrite.h \ modinfoforeign.h \ listdialog.h \ - lcdnumber.h + lcdnumber.h \ + forcedloaddialog.h \ + forcedloaddialogwidget.h FORMS += \ transfersavesdialog.ui \ @@ -197,7 +201,9 @@ FORMS += \ previewdialog.ui \ browserdialog.ui \ aboutdialog.ui \ - listdialog.ui + listdialog.ui \ + forcedloaddialog.ui \ + forcedloaddialogwidget.ui RESOURCES += \ resources.qrc \ diff --git a/src/organizer_en.ts b/src/organizer_en.ts index 299ffe6a..4291f3ae 100644 --- a/src/organizer_en.ts +++ b/src/organizer_en.ts @@ -27,7 +27,6 @@ Lead Developers/ Maintainers - Current Maintainers @@ -116,7 +115,12 @@ - + + Tannin (Original Creator) + + + + Close @@ -980,92 +984,107 @@ Right now the only case I know of where this needs to be overwritten is for the - + + If this is enabled, the configured libraries will be automatically loaded when this executable is launched. + + + + + Force Load Libraries (*) + + + + + Configure Libraries + + + + Use Application's Icon for shortcuts - + (*) This setting is profile-specific - - + + Add an executable - - + + Add - - + + Remove the selected executable - + Remove - + Close - + Select a binary - + Executable (%1) - + Java (32-bit) required - + MO requires 32-bit java to run this application. If you already have it installed, select javaw.exe from that installation as the binary. - + Select a directory - + Confirm - + Really remove "%1" from executables? - + Modify - - + + Save Changes? - - + + You made changes to the current executable, do you want to save them? @@ -1117,6 +1136,78 @@ Right now the only case I know of where this needs to be overwritten is for the + + ForcedLoadDialog + + + Forced Load Settings + + + + + + Adds a row to the table. + + + + + Add Row + + + + + + Deletes the selected row from the table. + + + + + Delete Row + + + + + ForcedLoadDialogWidget + + + Form + + + + + + The name of the process that should be forced to load a library. + + + + + Process name + + + + + + Browse for a process. + + + + + + ... + + + + + Library to load + + + + + + Browse for a library. + + + InstallDialog @@ -1457,7 +1548,7 @@ p, li { white-space: pre-wrap; } - + Create Backup @@ -1486,7 +1577,7 @@ p, li { white-space: pre-wrap; } - + Filter @@ -1633,8 +1724,8 @@ p, li { white-space: pre-wrap; } - - + + Refresh @@ -1696,145 +1787,145 @@ p, li { white-space: pre-wrap; } - + Show Hidden - + Tool Bar - + Install Mod - + Install &Mod - + Install a new mod from an archive - + Ctrl+M - + Profiles - + &Profiles - + Configure Profiles - + Ctrl+P - + Executables - + &Executables - + Configure the executables that can be started through Mod Organizer - + Ctrl+E - + Tools - + &Tools - + Ctrl+I - + Settings - + &Settings - + Configure settings and workarounds - + Ctrl+S - + Nexus - + Search nexus network for more mods - + Ctrl+N - - + + Update - + Mod Organizer is up-to-date - + No Problems - + This button will be highlighted if MO discovered potential problems in your setup and provide tips on how to fix them. !Work in progress! @@ -1842,39 +1933,39 @@ Right now this has very limited functionality - - + + Help - + Ctrl+H - + Endorse MO - - + + Endorse Mod Organizer - + Copy Log to Clipboard - + Change Game - + Open the Instance selection dialog to manage a different Game @@ -1927,8 +2018,8 @@ Error: %1 - - + + Endorse @@ -2044,7 +2135,7 @@ Error: %1 - Notice: Your current MO version (%1) is lower than the previous version (%2).<br>The GUI may not downgrade gracefully, so you may experience oddities.<br>However, there should be no serious issues. + Notice: Your current MO version (%1) is lower than the previously used one (%2). The GUI may not downgrade gracefully, so you may experience oddities. However, there should be no serious issues. @@ -2058,676 +2149,676 @@ Error: %1 - + Start Tutorial? - + You're about to start a tutorial. For technical reasons it's not possible to end the tutorial early. Continue? - + failed to spawn notepad.exe: %1 - + failed to change origin name: %1 - + failed to move "%1" from mod "%2" to "%3": %4 - + <Contains %1> - + <Checked> - + <Unchecked> - + <Update> - + <Mod Backup> - + <Managed by MO> - + <Managed outside MO> - + <No category> - + <Conflicted> - + <Not Endorsed> - + failed to rename mod: %1 - + Overwrite? - + This will replace the existing mod "%1". Continue? - + failed to remove mod "%1" - - - + + + failed to rename "%1" to "%2" - - - - + + + + Confirm - + Remove the following mods?<br><ul>%1</ul> - + failed to remove mod: %1 - - + + Failed - + Installation file no longer exists - + Mods installed with old versions of MO can't be reinstalled in this way. - + Failed to create backup. - + You need to be logged in with Nexus to resume a download - - - - + + + + You need to be logged in with Nexus to endorse - - + + Endorsing multiple mods will take a while. Please wait... - - + + Unendorsing multiple mods will take a while. Please wait... - + Failed to display overwrite dialog: %1 - + Opening Nexus Links - + You are trying to open %1 links to Nexus Mods. Are you sure you want to do this? - + Nexus ID for this Mod is unknown - + Web page for this mod is unknown - + <table cellspacing="5"><tr><th>Type</th><th>All</th><th>Visible</th><tr><td>Enabled mods:&emsp;</td><td align=right>%1 / %2</td><td align=right>%3 / %4</td></tr><tr><td>Unmanaged/DLCs:&emsp;</td><td align=right>%5</td><td align=right>%6</td></tr><tr><td>Mod backups:&emsp;</td><td align=right>%7</td><td align=right>%8</td></tr><tr><td>Separators:&emsp;</td><td align=right>%9</td><td align=right>%10</td></tr></table> - - <table cellspacing="4"><tr><th>Type</th><th>Active</th><th>Total</th></tr><tr><td>Active plugins:</td><td align=right>%1</td><td align=right>%2</td></tr><tr><td>Active ESMs:</td><td align=right>%3</td><td align=right>%4</td></tr><tr><td>Active ESPs:</td><td align=right>%7</td><td align=right>%8</td></tr><tr><td>Active ESMs+ESPs:</td><td align=right>%9</td><td align=right>%10</td></tr><tr><td>Active ESLs:</td><td align=right>%5</td><td align=right>%6</td></tr></table> + + <table cellspacing="6"><tr><th>Type</th><th>Active </th><th>Total</th></tr><tr><td>All plugins:</td><td align=right>%1 </td><td align=right>%2</td></tr><tr><td>ESMs:</td><td align=right>%3 </td><td align=right>%4</td></tr><tr><td>ESPs:</td><td align=right>%7 </td><td align=right>%8</td></tr><tr><td>ESMs+ESPs:</td><td align=right>%9 </td><td align=right>%10</td></tr><tr><td>ESLs:</td><td align=right>%5 </td><td align=right>%6</td></tr></table> - - - + + + Create Mod... - + This will create an empty mod. Please enter a name: - - + + A mod with this name already exists - + Create Separator... - + This will create a new separator. Please enter a name: - + A separator with this name already exists - + This will move all files from overwrite into a new, regular mod. Please enter a name: - - + + Are you sure? - + About to recursively delete: - + Not logged in, endorsement information will be wrong - + Continue? - + The versioning scheme decides which version is considered newer than another. This function will guess the versioning scheme under the assumption that the installed version is outdated. - - + + Sorry - + I don't know a versioning scheme where %1 is newer than %2. - + Really enable all visible mods? - + Really disable all visible mods? - + Export to csv - + CSV (Comma Separated Values) is a format that can be imported in programs like Excel to create a spreadsheet. You can also use online editors and converters instead. - + Select what mods you want export: - + All installed mods - + Only active (checked) mods from your current profile - + All currently visible mods in the mod list - + Choose what Columns to export: - + Mod_Priority - + Mod_Name - + Notes_column - + Mod_Status - + Primary_Category - + Nexus_ID - + Mod_Nexus_URL - + Mod_Version - + Install_Date - + Download_File_Name - + export failed: %1 - + Open Game folder - + Open MyGames folder - + Open INIs folder - + Open Instance folder - + Open Mods folder - + Open Profile folder - + Open Downloads folder - + Open MO2 Install folder - + Open MO2 Plugins folder - + Open MO2 Logs folder - + Install Mod... - + Create empty mod - + Create Separator - + Enable all visible - + Disable all visible - + Check all for update - + Export to csv... - - + + Send to - - + + Top - - + + Bottom - - + + Priority... - + Separator... - + All Mods - + Sync to Mods... - + Clear Overwrite... - - + + Open in Explorer - + Restore Backup - + Remove Backup... - - + + Change Categories - - + + Primary Category - + Rename Separator... - + Remove Separator... - + Select Color... - + Reset Color - + Change versioning scheme - + Un-ignore update - + Ignore update - - + + Enable selected - - + + Disable selected - + Rename Mod... - + Reinstall Mod - + Remove Mod... - + Un-Endorse - + Won't endorse - + Endorsement state unknown - + Ignore missing data - + Mark as converted/working - + Visit on Nexus - + Visit web page - + Information... - - + + Exception: - - + + Unknown exception - + <All> - + <Multiple> - + %1 more - + Are you sure you want to remove the following %n save(s)?<br><ul>%1</ul><br>Removed saves will be sent to the Recycle Bin. @@ -2735,12 +2826,12 @@ You can also use online editors and converters instead. - + Enable Mods... - + Delete %n save(s) @@ -2748,22 +2839,22 @@ You can also use online editors and converters instead. - + failed to remove %1 - + failed to create %1 - + Restarting MO - + Changing the managed game directory requires restarting MO. Any pending downloads will be paused. @@ -2771,335 +2862,335 @@ Click OK to restart MO now. - + Can't change download directory while downloads are in progress! - + failed to write to file %1 - + %1 written - + Select binary - + Binary - + Enter Name - + Please enter a name for the executable - + Not an executable - + This is not a recognized executable. - - + + Replace file? - + There already is a hidden version of this file. Replace it? - - + + File operation failed - - + + Failed to remove "%1". Maybe you lack the required file permissions? - + There already is a visible version of this file. Replace it? - - + + Set Priority - + Set the priority of the selected plugins - + file not found: %1 - + failed to generate preview for %1 - + Sorry, can't preview anything. This function currently does not support extracting from bsas. - + Update available - + Open/Execute - + Add as Executable - + Preview - + Un-Hide - + Hide - + Write To File... - + Do you want to endorse Mod Organizer on %1 now? - + Thank you! - + Thank you for your endorsement! - + Request to Nexus failed: %1 - - + + failed to read %1: %2 - - + + Error - + failed to extract %1 (errorcode %2) - + Extract BSA - + This archive contains invalid hashes. Some files may be broken. - + Extract... - + This will restart MO, continue? - + Edit Categories... - + Deselect filter - + Remove - + Enable all - + Disable all - + Unlock load order - + Lock load order - + Open Origin in Explorer - + Open Origin Info... - + depends on missing "%1" - + incompatible with "%1" - + Please wait while LOOT is running - + loot failed. Exit code was: %1 - + failed to start loot - + failed to run loot: %1 - + Errors occured - + Backup of load order created - + Choose backup to restore - + No Backups - + There are no backups to restore - - + + Restore failed - - + + Failed to restore the backup. Errorcode: %1 - + Backup of modlist created - + A file with the same name has already been downloaded. What would you like to do? - + Overwrite - + Rename new file - + Ignore file - + Set the priority of the selected mods @@ -4007,123 +4098,123 @@ p, li { white-space: pre-wrap; } - + drag&drop failed: %1 - + Confirm - + Are you sure you want to remove "%1"? - + Flags - + Content - + Mod Name - + Version - + Priority - + Category - + Source Game - + Nexus ID - + Installation - + Notes - - + + unknown - + Name of your mods - + Version of the mod (if available) - + Installation priority of your mod. The higher, the more "important" it is and thus overwrites files from mods with lower priority. - + Category of the mod. - + The source game which was the origin of this mod. - + Id of the mod as used on Nexus. - + Emblemes to highlight things that might require attention. - + Depicts the content of the mod:<br><table cellspacing=7><tr><td><img src=":/MO/gui/content/plugin" width=32/></td><td>Game plugins (esp/esm/esl)</td></tr><tr><td><img src=":/MO/gui/content/interface" width=32/></td><td>Interface</td></tr><tr><td><img src=":/MO/gui/content/mesh" width=32/></td><td>Meshes</td></tr><tr><td><img src=":/MO/gui/content/bsa" width=32/></td><td>BSA</td></tr><tr><td><img src=":/MO/gui/content/texture" width=32/></td><td>Textures</td></tr><tr><td><img src=":/MO/gui/content/sound" width=32/></td><td>Sounds</td></tr><tr><td><img src=":/MO/gui/content/music" width=32/></td><td>Music</td></tr><tr><td><img src=":/MO/gui/content/string" width=32/></td><td>Strings</td></tr><tr><td><img src=":/MO/gui/content/script" width=32/></td><td>Scripts (Papyrus)</td></tr><tr><td><img src=":/MO/gui/content/skse" width=32/></td><td>Script Extender plugins</td></tr><tr><td><img src=":/MO/gui/content/skyproc" width=32/></td><td>SkyProc Patcher</td></tr><tr><td><img src=":/MO/gui/content/menu" width=32/></td><td>Mod Configuration Menu</td></tr><tr><td><img src=":/MO/gui/content/inifile" width=32/></td><td>INI files</td></tr><tr><td><img src=":/MO/gui/content/modgroup" width=32/></td><td>ModGroup files</td></tr></table> - + Time this mod was installed - + User notes about the mod @@ -4131,7 +4222,7 @@ p, li { white-space: pre-wrap; } ModListSortProxy - + Drag&Drop is only supported when sorting by priority @@ -4351,81 +4442,81 @@ Continue launching %1? - + Multiple esps/esls activated, please check that they don't conflict. - + Download? - + A download has been started but no installed page plugin recognizes it. If you download anyway no information (i.e. version) will be associated with the download. Continue? - + failed to update mod list: %1 - - + + login successful - + Login failed - + Login failed, try again? - + login failed: %1. Download will not be associated with an account - + login failed: %1 - + login failed: %1. You need to log-in with Nexus to update MO. - + MO1 "Script Extender" load mechanism has left hook.dll in your game folder - - + + Description missing - + <a href="%1">hook.dll</a> has been found in your game folder (right click to copy the full path). This is most likely a leftover of setting the ModOrganizer 1 load mechanism to "Script Extender", in which case you must remove this file either by changing the load mechanism in ModOrganizer 1 or manually removing the file, otherwise the game is likely to crash and burn. - + failed to save load order: %1 - + The designated write target "%1" is not enabled. @@ -4531,135 +4622,135 @@ Continue? PluginList - + Name - + Priority - + Mod Index - + Flags - - + + unknown - + Name of your mods - + Load priority of your mod. The higher, the more "important" it is and thus overwrites data from plugins with lower priority. - + The modindex determines the formids of objects originating from this mods. - + failed to update esp info for file %1 (source id: %2), error: %3 - + esp not found: %1 - - + + Confirm - + Really enable all plugins? - + Really disable all plugins? - + The file containing locked plugin indices is broken - - + + <b>Origin</b>: %1 - + <br><b><i>This plugin can't be disabled (enforced by the game).</i></b> - + Author - + Description - + Missing Masters - + Enabled Masters - + Loads Archives - + There are Archives connected to this plugin. Their assets will be added to your game, overwriting in case of conflicts following the plugin order. Loose files will always overwrite assets from Archives. (This flag only checks for Archives from the same mod as the plugin) - + Loads INI settings - + There is an ini file connected to this plugin. Its settings will be added to your game settings, overwriting in case of conflicts. - + This ESP is flagged as an ESL. It will adhere to the ESP load order but the records will be loaded in ESL space. - + failed to restore load order for %1 @@ -4721,76 +4812,76 @@ p, li { white-space: pre-wrap; } Profile - + invalid profile name %1 - + failed to create %1 - + failed to write mod list: %1 - + failed to update tweaked ini file, wrong settings may be used: %1 - + failed to create tweaked ini: %1 - + failed to open %1 - + "%1" is missing or inaccessible - - - - - + + + + + invalid index %1 - + Overwrite directory couldn't be parsed - + invalid priority %1 - + Delete profile-specific save games? - + Do you want to delete the profile-specific save games? (If you select "No", the save games will show up again if you re-enable profile-specific save games) - + Missing profile-specific game INI files! - + Some of your profile-specific game INI files were missing. They will now be copied from the vanilla game folder. You might want double-check your settings. Missing files: @@ -4798,12 +4889,12 @@ Missing files: - + Delete profile-specific game INI files? - + Do you want to delete the profile-specific game INI files? (If you select "No", the INI files will be used again if you re-enable profile-specific game INI files.) @@ -5322,7 +5413,7 @@ If the folder was still in use, restart MO and try again. - + failed to create %1 @@ -5465,7 +5556,7 @@ If the folder was still in use, restart MO and try again. - + <Manage...> @@ -5506,12 +5597,12 @@ If the folder was still in use, restart MO and try again. - + failed to access %1 - + failed to set file time %1 @@ -6714,7 +6805,7 @@ On Windows XP: UsvfsConnector - + Preparing vfs diff --git a/src/organizercore.cpp b/src/organizercore.cpp index c4029a6d..39cb4d13 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -1199,10 +1199,15 @@ QStringList OrganizerCore::modsSortedByProfilePriority() const return res; } -void OrganizerCore::spawnBinary(const QFileInfo &binary, const QString &arguments, const QDir ¤tDirectory, const QString &steamAppID, const QString &customOverwrite) +void OrganizerCore::spawnBinary(const QFileInfo &binary, + const QString &arguments, + const QDir ¤tDirectory, + const QString &steamAppID, + const QString &customOverwrite, + const QList &forcedLibraries) { DWORD processExitCode = 0; - HANDLE processHandle = spawnBinaryDirect(binary, arguments, m_CurrentProfile->name(), currentDirectory, steamAppID, customOverwrite, &processExitCode); + HANDLE processHandle = spawnBinaryDirect(binary, arguments, m_CurrentProfile->name(), currentDirectory, steamAppID, customOverwrite, forcedLibraries, &processExitCode); if (processHandle != INVALID_HANDLE_VALUE) { refreshDirectoryStructure(); // need to remove our stored load order because it may be outdated if a foreign tool changed the @@ -1227,9 +1232,10 @@ HANDLE OrganizerCore::spawnBinaryDirect(const QFileInfo &binary, const QDir ¤tDirectory, const QString &steamAppID, const QString &customOverwrite, + const QList &forcedLibraries, LPDWORD exitCode) { - HANDLE processHandle = spawnBinaryProcess(binary, arguments, profileName, currentDirectory, steamAppID, customOverwrite); + HANDLE processHandle = spawnBinaryProcess(binary, arguments, profileName, currentDirectory, steamAppID, customOverwrite, forcedLibraries); if (Settings::instance().lockGUI() && processHandle != INVALID_HANDLE_VALUE) { std::unique_ptr dlg; ILockedWaitingForProcess* uilock = nullptr; @@ -1264,7 +1270,8 @@ HANDLE OrganizerCore::spawnBinaryProcess(const QFileInfo &binary, const QString &profileName, const QDir ¤tDirectory, const QString &steamAppID, - const QString &customOverwrite) + const QString &customOverwrite, + const QList &forcedLibraries) { prepareStart(); @@ -1324,6 +1331,8 @@ HANDLE OrganizerCore::spawnBinaryProcess(const QFileInfo &binary, if (m_AboutToRun(binary.absoluteFilePath())) { try { m_USVFS.updateMapping(fileMapping(profileName, customOverwrite)); + m_USVFS.updateForcedLibraries(forcedLibraries); + } catch (const UsvfsConnectorException &e) { qDebug(e.what()); return INVALID_HANDLE_VALUE; @@ -1416,6 +1425,10 @@ HANDLE OrganizerCore::runShortcut(const MOShortcut& shortcut) .toLocal8Bit().constData()); Executable& exe = m_ExecutablesList.find(shortcut.executable()); + auto forcedLibaries = m_CurrentProfile->determineForcedLibraries(shortcut.executable()); + if (!m_CurrentProfile->forcedLibrariesEnabled(exe.m_BinaryInfo.fileName())) { + forcedLibaries.clear(); + } return spawnBinaryDirect( exe.m_BinaryInfo, exe.m_Arguments, @@ -1423,7 +1436,9 @@ HANDLE OrganizerCore::runShortcut(const MOShortcut& shortcut) exe.m_WorkingDirectory.length() != 0 ? exe.m_WorkingDirectory : exe.m_BinaryInfo.absolutePath(), - exe.m_SteamAppID, ""); + exe.m_SteamAppID, + "", + forcedLibaries); } HANDLE OrganizerCore::startApplication(const QString &executable, @@ -1444,6 +1459,7 @@ HANDLE OrganizerCore::startApplication(const QString &executable, } QString steamAppID; QString customOverwrite; + QList forcedLibraries; if (executable.contains('\\') || executable.contains('/')) { // file path @@ -1462,6 +1478,9 @@ HANDLE OrganizerCore::startApplication(const QString &executable, customOverwrite = m_CurrentProfile->setting("custom_overwrites", exe.m_Title) .toString(); + if (m_CurrentProfile->forcedLibrariesEnabled(exe.m_Title)) { + forcedLibraries = m_CurrentProfile->determineForcedLibraries(exe.m_Title); + } } catch (const std::runtime_error &) { // nop } @@ -1473,6 +1492,9 @@ HANDLE OrganizerCore::startApplication(const QString &executable, customOverwrite = m_CurrentProfile->setting("custom_overwrites", exe.m_Title) .toString(); + if (m_CurrentProfile->forcedLibrariesEnabled(exe.m_Title)) { + forcedLibraries = m_CurrentProfile->determineForcedLibraries(exe.m_Title); + } if (arguments == "") { arguments = exe.m_Arguments; } @@ -1487,7 +1509,7 @@ HANDLE OrganizerCore::startApplication(const QString &executable, } } - return spawnBinaryDirect(binary, arguments, profileName, currentDirectory, steamAppID, customOverwrite); + return spawnBinaryDirect(binary, arguments, profileName, currentDirectory, steamAppID, customOverwrite, forcedLibraries); } bool OrganizerCore::waitForApplication(HANDLE handle, LPDWORD exitCode) diff --git a/src/organizercore.h b/src/organizercore.h index 086fa11d..61020acd 100644 --- a/src/organizercore.h +++ b/src/organizercore.h @@ -20,6 +20,7 @@ #include #include #include +#include "executableinfo.h" class ModListSortProxy; class PluginListSortProxy; @@ -141,20 +142,23 @@ public: void spawnBinary(const QFileInfo &binary, const QString &arguments = "", const QDir ¤tDirectory = QDir(), const QString &steamAppID = "", - const QString &customOverwrite = ""); + const QString &customOverwrite = "", + const QList &forcedLibraries = QList()); HANDLE spawnBinaryDirect(const QFileInfo &binary, const QString &arguments, const QString &profileName, const QDir ¤tDirectory, const QString &steamAppID, const QString &customOverwrite, + const QList &forcedLibraries = QList(), LPDWORD exitCode = nullptr); HANDLE spawnBinaryProcess(const QFileInfo &binary, const QString &arguments, const QString &profileName, const QDir ¤tDirectory, const QString &steamAppID, - const QString &customOverwrite); + const QString &customOverwrite, + const QList &forcedLibraries = QList()); void loginSuccessfulUpdate(bool necessary); void loginFailedUpdate(const QString &message); diff --git a/src/profile.cpp b/src/profile.cpp index 09c2a5f5..02257de9 100644 --- a/src/profile.cpp +++ b/src/profile.cpp @@ -884,7 +884,6 @@ QVariant Profile::setting(const QString §ion, const QString &name, return m_Settings->value(section + "/" + name, fallback); } - void Profile::storeSetting(const QString §ion, const QString &name, const QVariant &value) { @@ -906,7 +905,124 @@ void Profile::removeSetting(const QString &name) removeSetting("", name); } +QVariantMap Profile::settingsByGroup(const QString §ion) const +{ + QVariantMap results; + m_Settings->beginGroup(section); + for (auto key : m_Settings->childKeys()) { + results[key] = m_Settings->value(key); + } + m_Settings->endGroup(); + return results; +} + +void Profile::storeSettingsByGroup(const QString §ion, const QVariantMap &values) +{ + m_Settings->beginGroup(section); + for (auto key : values.keys()) { + m_Settings->setValue(key, values[key]); + } + m_Settings->endGroup(); +} + +QList Profile::settingsByArray(const QString &prefix) const +{ + QList results; + int size = m_Settings->beginReadArray(prefix); + for (int i = 0; i < size; i++) { + m_Settings->setArrayIndex(i); + QVariantMap item; + for (auto key : m_Settings->childKeys()) { + item[key] = m_Settings->value(key); + } + results.append(item); + } + m_Settings->endArray(); + return results; +} + +void Profile::storeSettingsByArray(const QString &prefix, const QList &values) +{ + m_Settings->beginWriteArray(prefix); + for (int i = 0; i < values.length(); i++) { + m_Settings->setArrayIndex(i); + for (auto key : values.at(i).keys()) { + m_Settings->setValue(key, values.at(i)[key]); + } + } + m_Settings->endArray(); +} + int Profile::getPriorityMinimum() const { return m_ModIndexByPriority.begin()->first; } + +bool Profile::forcedLibrariesEnabled(const QString &executable) +{ + return setting("forced_libraries", executable + "/enabled", false).toBool(); +} + +void Profile::setForcedLibrariesEnabled(const QString &executable, bool enabled) +{ + storeSetting("forced_libraries", executable + "/enabled", enabled); +} + +QList Profile::determineForcedLibraries(const QString &executable) +{ + QList results; + + auto rawSettings = settingsByArray("forced_libraries/" + executable); + auto forcedLoads = m_GamePlugin->executableForcedLoads(); + + // look for enabled status on forced loads and add those + for (auto forcedLoad : forcedLoads) { + bool found = false; + for (auto rawSetting : rawSettings) { + if ((rawSetting.value("process").toString().compare(forcedLoad.process(), Qt::CaseInsensitive) == 0) + && (rawSetting.value("library").toString().compare(forcedLoad.library(), Qt::CaseInsensitive) == 0)) + { + results.append(forcedLoad.withEnabled(rawSetting.value("enabled", false).toBool())); + found = true; + } + } + if (!found) { + results.append(forcedLoad); + } + } + + // add everything else + for (auto rawSetting : rawSettings) { + bool add = true; + for (auto forcedLoad : forcedLoads) { + if ((rawSetting.value("process").toString().compare(forcedLoad.process(), Qt::CaseInsensitive) == 0) + && (rawSetting.value("library").toString().compare(forcedLoad.library(), Qt::CaseInsensitive) == 0)) + { + add = false; + } + } + if (add) { + results.append( + ExecutableForcedLoadSetting( + rawSetting.value("process").toString(), + rawSetting.value("library").toString() + ).withEnabled(rawSetting.value("enabled", false).toBool()) + ); + } + } + + return results; +} + +void Profile::saveForcedLibraries(const QString &executable, const QList &values) +{ + QList rawSettings; + for (auto setting : values) { + QVariantMap rawSetting; + rawSetting["enabled"] = setting.enabled(); + rawSetting["process"] = setting.process(); + rawSetting["library"] = setting.library(); + rawSettings.append(rawSetting); + } + storeSettingsByArray("forced_libraries/" + executable, rawSettings); +} diff --git a/src/profile.h b/src/profile.h index 95a5c59d..d7fb7785 100644 --- a/src/profile.h +++ b/src/profile.h @@ -24,12 +24,14 @@ along with Mod Organizer. If not, see . #include "modinfo.h" #include #include +#include "executableinfo.h" #include #include #include #include #include +#include #include @@ -310,8 +312,19 @@ public: void removeSetting(const QString §ion, const QString &name = QString()); void removeSetting(const QString &name); + QVariantMap settingsByGroup(const QString §ion) const; + void storeSettingsByGroup(const QString §ion, const QVariantMap &values); + + QList settingsByArray(const QString &prefix) const; + void storeSettingsByArray(const QString &prefix, const QList &values); + int getPriorityMinimum() const; + bool forcedLibrariesEnabled(const QString &executable); + void setForcedLibrariesEnabled(const QString &executable, bool enabled); + QList determineForcedLibraries(const QString &executable); + void saveForcedLibraries(const QString &executable, const QList &values); + signals: /** diff --git a/src/settings.cpp b/src/settings.cpp index 5cfe427b..f981f811 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -161,8 +161,8 @@ void Settings::managedGameChanged(IPluginGame const *gamePlugin) void Settings::registerPlugin(IPlugin *plugin) { m_Plugins.push_back(plugin); - m_PluginSettings.insert(plugin->name(), QMap()); - m_PluginDescriptions.insert(plugin->name(), QMap()); + m_PluginSettings.insert(plugin->name(), QVariantMap()); + m_PluginDescriptions.insert(plugin->name(), QVariantMap()); for (const PluginSetting &setting : plugin->settings()) { QVariant temp = m_Settings.value("Plugins/" + plugin->name() + "/" + setting.key, setting.defaultValue); if (!temp.convert(setting.defaultValue.type())) { diff --git a/src/settings.h b/src/settings.h index 25f22911..a47c255c 100644 --- a/src/settings.h +++ b/src/settings.h @@ -543,8 +543,8 @@ private: std::vector m_Plugins; - QMap> m_PluginSettings; - QMap> m_PluginDescriptions; + QMap m_PluginSettings; + QMap m_PluginDescriptions; QSet m_PluginBlacklist; diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index b975fa75..3032a6c6 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -307,7 +307,7 @@ void SettingsDialog::on_resetDialogsButton_clicked() void SettingsDialog::storeSettings(QListWidgetItem *pluginItem) { if (pluginItem != nullptr) { - QMap settings = pluginItem->data(Qt::UserRole + 1).toMap(); + QVariantMap settings = pluginItem->data(Qt::UserRole + 1).toMap(); for (int i = 0; i < ui->pluginSettingsList->topLevelItemCount(); ++i) { const QTreeWidgetItem *item = ui->pluginSettingsList->topLevelItem(i); @@ -328,8 +328,8 @@ void SettingsDialog::on_pluginsList_currentItemChanged(QListWidgetItem *current, ui->versionLabel->setText(plugin->version().canonicalString()); ui->descriptionLabel->setText(plugin->description()); - QMap settings = current->data(Qt::UserRole + 1).toMap(); - QMap descriptions = current->data(Qt::UserRole + 2).toMap(); + QVariantMap settings = current->data(Qt::UserRole + 1).toMap(); + QVariantMap descriptions = current->data(Qt::UserRole + 2).toMap(); ui->pluginSettingsList->setEnabled(settings.count() != 0); for (auto iter = settings.begin(); iter != settings.end(); ++iter) { QTreeWidgetItem *newItem = new QTreeWidgetItem(QStringList(iter.key())); diff --git a/src/usvfsconnector.cpp b/src/usvfsconnector.cpp index ef7314c0..5ad19fb0 100644 --- a/src/usvfsconnector.cpp +++ b/src/usvfsconnector.cpp @@ -138,6 +138,8 @@ UsvfsConnector::UsvfsConnector() BlacklistExecutable(buf.data()); } + ClearLibraryForceLoads(); + m_LogWorker.moveToThread(&m_WorkerThread); connect(&m_WorkerThread, SIGNAL(started()), &m_LogWorker, SLOT(process())); @@ -203,7 +205,8 @@ void UsvfsConnector::updateMapping(const MappingType &mapping) */ } -void UsvfsConnector::updateParams(int logLevel, int crashDumpsType, QString executableBlacklist) { +void UsvfsConnector::updateParams(int logLevel, int crashDumpsType, QString executableBlacklist) +{ USVFSUpdateParams(::logLevel(logLevel), ::crashDumpsType(crashDumpsType)); ClearExecutableBlacklist(); for (auto exec : executableBlacklist.split(";")) { @@ -211,3 +214,16 @@ void UsvfsConnector::updateParams(int logLevel, int crashDumpsType, QString exec BlacklistExecutable(buf.data()); } } + +void UsvfsConnector::updateForcedLibraries(const QList &forcedLibraries) +{ + ClearLibraryForceLoads(); + for (auto setting : forcedLibraries) { + if (setting.enabled()) { + ForceLoadLibrary( + setting.process().toStdWString().data(), + setting.library().toStdWString().data() + ); + } + } +} diff --git a/src/usvfsconnector.h b/src/usvfsconnector.h index 3aefb703..8a88bde5 100644 --- a/src/usvfsconnector.h +++ b/src/usvfsconnector.h @@ -27,7 +27,9 @@ along with Mod Organizer. If not, see . #include #include #include +#include #include +#include "executableinfo.h" class LogWorker : public QThread { @@ -83,6 +85,7 @@ public: void updateMapping(const MappingType &mapping); void updateParams(int logLevel, int crashDumpsType, QString executableBlacklist); + void updateForcedLibraries(const QList &forcedLibraries); private: -- cgit v1.3.1 From 64a242d9220868a5b564c32f75f191efb01ad18e Mon Sep 17 00:00:00 2001 From: LostDragonist Date: Fri, 11 Jan 2019 16:21:43 -0600 Subject: Remove profile-specific executable settings when removing the executable --- src/editexecutablesdialog.cpp | 4 +++- src/profile.cpp | 7 ++++++- src/profile.h | 3 ++- 3 files changed, 11 insertions(+), 3 deletions(-) (limited to 'src/profile.cpp') diff --git a/src/editexecutablesdialog.cpp b/src/editexecutablesdialog.cpp index 4b1cdb5d..bea497ef 100644 --- a/src/editexecutablesdialog.cpp +++ b/src/editexecutablesdialog.cpp @@ -124,7 +124,7 @@ void EditExecutablesDialog::saveExecutable() m_Profile->removeSetting("custom_overwrites", ui->titleEdit->text()); } - m_Profile->saveForcedLibraries(ui->titleEdit->text(), m_ForcedLibraries); + m_Profile->storeForcedLibraries(ui->titleEdit->text(), m_ForcedLibraries); m_Profile->setForcedLibrariesEnabled(ui->titleEdit->text(), ui->forceLoadCheckBox->isChecked()); } @@ -218,6 +218,8 @@ void EditExecutablesDialog::on_removeButton_clicked() { if (QMessageBox::question(this, tr("Confirm"), tr("Really remove \"%1\" from executables?").arg(ui->titleEdit->text()), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { + m_Profile->removeSetting("custom_overwrites", ui->titleEdit->text()); + m_Profile->removeForcedLibraries(ui->titleEdit->text()); m_ExecutablesList.remove(ui->titleEdit->text()); } diff --git a/src/profile.cpp b/src/profile.cpp index 02257de9..afe6fdc7 100644 --- a/src/profile.cpp +++ b/src/profile.cpp @@ -1014,7 +1014,7 @@ QList Profile::determineForcedLibraries(const QStri return results; } -void Profile::saveForcedLibraries(const QString &executable, const QList &values) +void Profile::storeForcedLibraries(const QString &executable, const QList &values) { QList rawSettings; for (auto setting : values) { @@ -1026,3 +1026,8 @@ void Profile::saveForcedLibraries(const QString &executable, const QListremove("forced_libraries/" + executable); +} diff --git a/src/profile.h b/src/profile.h index d7fb7785..dea933ad 100644 --- a/src/profile.h +++ b/src/profile.h @@ -323,7 +323,8 @@ public: bool forcedLibrariesEnabled(const QString &executable); void setForcedLibrariesEnabled(const QString &executable, bool enabled); QList determineForcedLibraries(const QString &executable); - void saveForcedLibraries(const QString &executable, const QList &values); + void storeForcedLibraries(const QString &executable, const QList &values); + void removeForcedLibraries(const QString &executable); signals: -- cgit v1.3.1 From 7fd81029ce2f67aa7a6555858dfed7d6ac58c4e3 Mon Sep 17 00:00:00 2001 From: LostDragonist Date: Tue, 22 Jan 2019 14:59:07 -0600 Subject: Reduce file I/O operations when enabling/disabling multiple mods --- src/mainwindow.cpp | 6 ++ src/mainwindow.h | 1 + src/modlist.cpp | 36 +++++---- src/modlist.h | 13 +++- src/modlistsortproxy.cpp | 8 +- src/organizercore.cpp | 190 ++++++++++++++++++++++++++++++++--------------- src/organizercore.h | 3 + src/profile.cpp | 31 ++++++++ src/profile.h | 17 +++++ 9 files changed, 229 insertions(+), 76 deletions(-) (limited to 'src/profile.cpp') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index df78df82..a9dd3e51 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -2509,6 +2509,12 @@ void MainWindow::modlistChanged(const QModelIndex&, int) updateModCount(); } +void MainWindow::modlistChanged(const QModelIndexList&, int) +{ + m_OrganizerCore.currentProfile()->writeModlist(); + updateModCount(); +} + void MainWindow::modlistSelectionChanged(const QModelIndex ¤t, const QModelIndex&) { if (current.isValid()) { diff --git a/src/mainwindow.h b/src/mainwindow.h index 23c38f19..e0311046 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -549,6 +549,7 @@ private slots: void updateStyle(const QString &style); void modlistChanged(const QModelIndex &index, int role); + void modlistChanged(const QModelIndexList &indicies, int role); void fileMoved(const QString &filePath, const QString &oldOriginName, const QString &newOriginName); diff --git a/src/modlist.cpp b/src/modlist.cpp index 58fe95d5..cc15a111 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -527,7 +527,7 @@ bool ModList::setData(const QModelIndex &index, const QVariant &value, int role) m_Profile->setModEnabled(modID, enabled); m_Modified = true; m_LastCheck.restart(); - emit modlist_changed(index, role); + emit modlistChanged(index, role); } result = true; emit dataChanged(index, index); @@ -562,7 +562,7 @@ bool ModList::setData(const QModelIndex &index, const QVariant &value, int role) int newID = value.toInt(&ok); if (ok) { info->setNexusID(newID); - emit modlist_changed(index, role); + emit modlistChanged(index, role); result = true; } else { result = false; @@ -1283,12 +1283,24 @@ bool ModList::toggleSelection(QAbstractItemView *itemView) QItemSelectionModel *selectionModel = itemView->selectionModel(); + QList modsToEnable; + QList modsToDisable; + QModelIndexList dirtyMods; for (QModelIndex idx : selectionModel->selectedRows()) { int modId = idx.data(Qt::UserRole + 1).toInt(); - m_Profile->setModEnabled(modId, !m_Profile->modEnabled(modId)); - emit modlist_changed(idx, 0); + if (m_Profile->modEnabled(modId)) { + modsToDisable.append(modId); + dirtyMods.append(idx); + } else { + modsToEnable.append(modId); + dirtyMods.append(idx); + } } + m_Profile->setModsEnabled(modsToEnable, modsToDisable); + + emit modlistChanged(dirtyMods, 0); + m_Modified = true; m_LastCheck.restart(); @@ -1331,13 +1343,12 @@ bool ModList::eventFilter(QObject *obj, QEvent *event) void ModList::enableSelected(const QItemSelectionModel *selectionModel) { if (selectionModel->hasSelection()) { - bool dirty = false; + QList modsToEnable; for (auto row : selectionModel->selectedRows(COL_PRIORITY)) { int modID = m_Profile->modIndexByPriority(row.data().toInt()); - if (!m_Profile->modEnabled(modID)) { - m_Profile->setModEnabled(modID, true); - } + modsToEnable.append(modID); } + m_Profile->setModsEnabled(modsToEnable, QList()); } } @@ -1345,14 +1356,11 @@ void ModList::enableSelected(const QItemSelectionModel *selectionModel) void ModList::disableSelected(const QItemSelectionModel *selectionModel) { if (selectionModel->hasSelection()) { - bool dirty = false; + QList modsToDisable; for (auto row : selectionModel->selectedRows(COL_PRIORITY)) { int modID = m_Profile->modIndexByPriority(row.data().toInt()); - if (m_Profile->modEnabled(modID)) { - m_Profile->setModEnabled(modID, false); - } + modsToDisable.append(modID); } - - + m_Profile->setModsEnabled(QList(), modsToDisable); } } diff --git a/src/modlist.h b/src/modlist.h index 42269386..443d583b 100644 --- a/src/modlist.h +++ b/src/modlist.h @@ -233,9 +233,18 @@ signals: * @param role role of the field that changed * @note this signal must only be emitted if the row really did change. * Slots handling this signal therefore do not have to verify that a change has happened - * @note this signal is currently only used in tutorials **/ - void modlist_changed(const QModelIndex &index, int role); + void modlistChanged(const QModelIndex &index, int role); + + /** + * @brief emitted whenever multiple row sin the list has changed + * + * @param indicies the list of indicies of the changed field + * @param role role of the field that changed + * @note this signal must only be emitted if the row really did change. + * Slots handling this signal therefore do not have to verify that a change has happened + **/ + void modlistChanged(const QModelIndexList &indicies, int role); /** * @brief emitted to have all selected mods deleted diff --git a/src/modlistsortproxy.cpp b/src/modlistsortproxy.cpp index 464f9104..5afcc26a 100644 --- a/src/modlistsortproxy.cpp +++ b/src/modlistsortproxy.cpp @@ -86,10 +86,12 @@ void ModListSortProxy::enableAllVisible() { if (m_Profile == nullptr) return; + QList modsToEnable; for (int i = 0; i < this->rowCount(); ++i) { int modID = mapToSource(index(i, 0)).data(Qt::UserRole + 1).toInt(); - m_Profile->setModEnabled(modID, true); + modsToEnable.append(modID); } + m_Profile->setModsEnabled(modsToEnable, QList()); invalidate(); } @@ -97,10 +99,12 @@ void ModListSortProxy::disableAllVisible() { if (m_Profile == nullptr) return; + QList modsToDisable; for (int i = 0; i < this->rowCount(); ++i) { int modID = mapToSource(index(i, 0)).data(Qt::UserRole + 1).toInt(); - m_Profile->setModEnabled(modID, false); + modsToDisable.append(modID); } + m_Profile->setModsEnabled(QList(), modsToDisable); invalidate(); } diff --git a/src/organizercore.cpp b/src/organizercore.cpp index 90e702ef..90e5a423 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -542,8 +542,10 @@ void OrganizerCore::setUserInterface(IUserInterface *userInterface, m_UserInterface = userInterface; if (widget != nullptr) { - connect(&m_ModList, SIGNAL(modlist_changed(QModelIndex, int)), widget, + connect(&m_ModList, SIGNAL(modlistChanged(QModelIndex, int)), widget, SLOT(modlistChanged(QModelIndex, int))); + connect(&m_ModList, SIGNAL(modlistChanged(QModelIndexList, int)), widget, + SLOT(modlistChanged(QModelIndexList, int))); connect(&m_ModList, SIGNAL(showMessage(QString)), widget, SLOT(showMessage(QString))); connect(&m_ModList, SIGNAL(modRenamed(QString, QString)), widget, @@ -821,8 +823,8 @@ void OrganizerCore::setCurrentProfile(const QString &profileName) m_CurrentProfile->deactivateInvalidation(); } - connect(m_CurrentProfile, SIGNAL(modStatusChanged(uint)), this, - SLOT(modStatusChanged(uint))); + connect(m_CurrentProfile, SIGNAL(modStatusChanged(uint)), this, SLOT(modStatusChanged(uint))); + connect(m_CurrentProfile, SIGNAL(modStatusChanged(QList)), this, SLOT(modStatusChanged(QList))); refreshDirectoryStructure(); } @@ -1798,60 +1800,70 @@ void OrganizerCore::refreshLists() void OrganizerCore::updateModActiveState(int index, bool active) { - ModInfo::Ptr modInfo = ModInfo::getByIndex(index); - QDir dir(modInfo->absolutePath()); - for (const QString &esm : - dir.entryList(QStringList() << "*.esm", QDir::Files)) { - const FileEntry::Ptr file = m_DirectoryStructure->findFile(ToWString(esm)); - if (file.get() == nullptr) { - qWarning("failed to activate %s", qUtf8Printable(esm)); - continue; - } + QList modsToUpdate; + modsToUpdate.append(index); + updateModsActiveState(modsToUpdate, active); +} - if (active != m_PluginList.isEnabled(esm) - && file->getAlternatives().empty()) { - m_PluginList.blockSignals(true); - m_PluginList.enableESP(esm, active); - m_PluginList.blockSignals(false); - } - } - int enabled = 0; - for (const QString &esl : - dir.entryList(QStringList() << "*.esl", QDir::Files)) { - const FileEntry::Ptr file = m_DirectoryStructure->findFile(ToWString(esl)); - if (file.get() == nullptr) { - qWarning("failed to activate %s", qUtf8Printable(esl)); - continue; - } +void OrganizerCore::updateModsActiveState(const QList &modIndices, bool active) +{ + int enabled = 0; + for (auto index : modIndices) { + ModInfo::Ptr modInfo = ModInfo::getByIndex(index); + QDir dir(modInfo->absolutePath()); + for (const QString &esm : + dir.entryList(QStringList() << "*.esm", QDir::Files)) { + const FileEntry::Ptr file = m_DirectoryStructure->findFile(ToWString(esm)); + if (file.get() == nullptr) { + qWarning("failed to activate %s", qUtf8Printable(esm)); + continue; + } - if (active != m_PluginList.isEnabled(esl) + if (active != m_PluginList.isEnabled(esm) && file->getAlternatives().empty()) { - m_PluginList.blockSignals(true); - m_PluginList.enableESP(esl, active); - m_PluginList.blockSignals(false); - ++enabled; + m_PluginList.blockSignals(true); + m_PluginList.enableESP(esm, active); + m_PluginList.blockSignals(false); + } } - } - QStringList esps = dir.entryList(QStringList() << "*.esp", QDir::Files); - for (const QString &esp : esps) { - const FileEntry::Ptr file = m_DirectoryStructure->findFile(ToWString(esp)); - if (file.get() == nullptr) { - qWarning("failed to activate %s", qUtf8Printable(esp)); - continue; + + for (const QString &esl : + dir.entryList(QStringList() << "*.esl", QDir::Files)) { + const FileEntry::Ptr file = m_DirectoryStructure->findFile(ToWString(esl)); + if (file.get() == nullptr) { + qWarning("failed to activate %s", qUtf8Printable(esl)); + continue; + } + + if (active != m_PluginList.isEnabled(esl) + && file->getAlternatives().empty()) { + m_PluginList.blockSignals(true); + m_PluginList.enableESP(esl, active); + m_PluginList.blockSignals(false); + ++enabled; + } } + QStringList esps = dir.entryList(QStringList() << "*.esp", QDir::Files); + for (const QString &esp : esps) { + const FileEntry::Ptr file = m_DirectoryStructure->findFile(ToWString(esp)); + if (file.get() == nullptr) { + qWarning("failed to activate %s", qUtf8Printable(esp)); + continue; + } - if (active != m_PluginList.isEnabled(esp) + if (active != m_PluginList.isEnabled(esp) && file->getAlternatives().empty()) { - m_PluginList.blockSignals(true); - m_PluginList.enableESP(esp, active); - m_PluginList.blockSignals(false); - ++enabled; + m_PluginList.blockSignals(true); + m_PluginList.enableESP(esp, active); + m_PluginList.blockSignals(false); + ++enabled; + } } } if (active && (enabled > 1)) { MessageDialog::showMessage( - tr("Multiple esps/esls activated, please check that they don't conflict."), - qApp->activeWindow()); + tr("Multiple esps/esls activated, please check that they don't conflict."), + qApp->activeWindow()); } m_PluginList.refreshLoadOrder(); // immediately save affected lists @@ -1861,18 +1873,29 @@ void OrganizerCore::updateModActiveState(int index, bool active) void OrganizerCore::updateModInDirectoryStructure(unsigned int index, ModInfo::Ptr modInfo) { - // add files of the bsa to the directory structure - m_DirectoryRefresher.addModFilesToStructure( - m_DirectoryStructure, modInfo->name(), - m_CurrentProfile->getModPriority(index), modInfo->absolutePath(), - modInfo->stealFiles()); + QMap allModInfo; + allModInfo[index] = modInfo; + updateModsInDirectoryStructure(allModInfo); +} + +void OrganizerCore::updateModsInDirectoryStructure(QMap modInfo) +{ + for (auto idx : modInfo.keys()) { + // add files of the bsa to the directory structure + m_DirectoryRefresher.addModFilesToStructure( + m_DirectoryStructure, modInfo[idx]->name(), + m_CurrentProfile->getModPriority(idx), modInfo[idx]->absolutePath(), + modInfo[idx]->stealFiles()); + } DirectoryRefresher::cleanStructure(m_DirectoryStructure); // need to refresh plugin list now so we can activate esps refreshESPList(true); // activate all esps of the specified mod so the bsas get activated along with // it m_PluginList.blockSignals(true); - updateModActiveState(index, true); + for (auto idx : modInfo.keys()) { + updateModActiveState(idx, true); + } m_PluginList.blockSignals(false); // now we need to refresh the bsa list and save it so there is no confusion // about what archives are avaiable and active @@ -1883,14 +1906,16 @@ void OrganizerCore::updateModInDirectoryStructure(unsigned int index, std::vector archives = enabledArchives(); m_DirectoryRefresher.setMods( - m_CurrentProfile->getActiveMods(), - std::set(archives.begin(), archives.end())); + m_CurrentProfile->getActiveMods(), + std::set(archives.begin(), archives.end())); // finally also add files from bsas to the directory structure - m_DirectoryRefresher.addModBSAToStructure( - m_DirectoryStructure, modInfo->name(), - m_CurrentProfile->getModPriority(index), modInfo->absolutePath(), - modInfo->archives()); + for (auto idx : modInfo.keys()) { + m_DirectoryRefresher.addModBSAToStructure( + m_DirectoryStructure, modInfo[idx]->name(), + m_CurrentProfile->getModPriority(idx), modInfo[idx]->absolutePath(), + modInfo[idx]->archives()); + } } void OrganizerCore::requestDownload(const QUrl &url, QNetworkReply *reply) @@ -2065,6 +2090,55 @@ void OrganizerCore::modStatusChanged(unsigned int index) } } +void OrganizerCore::modStatusChanged(QList index) { + try { + QMap modsToEnable; + QMap modsToDisable; + for (auto idx : index) { + if (m_CurrentProfile->modEnabled(idx)) { + modsToEnable[idx] = ModInfo::getByIndex(idx); + } else { + modsToDisable[idx] = ModInfo::getByIndex(idx); + } + } + if (!modsToEnable.isEmpty()) { + updateModsInDirectoryStructure(modsToEnable); + for (auto modInfo : modsToEnable.values()) { + modInfo->clearCaches(); + } + } + if (!modsToDisable.isEmpty()) { + updateModsActiveState(modsToDisable.keys(), false); + for (auto idx : modsToDisable.keys()) { + if (m_DirectoryStructure->originExists(ToWString(modsToDisable[idx]->name()))) { + FilesOrigin &origin + = m_DirectoryStructure->getOriginByName(ToWString(modsToDisable[idx]->name())); + origin.enable(false); + } + } + if (m_UserInterface != nullptr) { + m_UserInterface->archivesWriter().write(); + } + } + + for (unsigned int i = 0; i < m_CurrentProfile->numMods(); ++i) { + ModInfo::Ptr modInfo = ModInfo::getByIndex(i); + int priority = m_CurrentProfile->getModPriority(i); + if (m_DirectoryStructure->originExists(ToWString(modInfo->name()))) { + // priorities in the directory structure are one higher because data is + // 0 + m_DirectoryStructure->getOriginByName(ToWString(modInfo->name())) + .setPriority(priority + 1); + } + } + m_DirectoryStructure->getFileRegister()->sortOrigins(); + + refreshLists(); + } catch (const std::exception &e) { + reportError(tr("failed to update mod list: %1").arg(e.what())); + } +} + void OrganizerCore::loginSuccessful(bool necessary) { if (necessary) { diff --git a/src/organizercore.h b/src/organizercore.h index 61020acd..7a62d2c8 100644 --- a/src/organizercore.h +++ b/src/organizercore.h @@ -136,6 +136,7 @@ public: void refreshDirectoryStructure(); void updateModInDirectoryStructure(unsigned int index, ModInfo::Ptr modInfo); + void updateModsInDirectoryStructure(QMap modInfos); void doAfterLogin(const std::function &function) { m_PostLoginTasks.append(function); } @@ -238,6 +239,7 @@ public slots: void installDownload(int downloadIndex); void modStatusChanged(unsigned int index); + void modStatusChanged(QList index); void requestDownload(const QUrl &url, QNetworkReply *reply); void downloadRequestedNXM(const QString &url); @@ -266,6 +268,7 @@ private: bool queryLogin(QString &username, QString &password); void updateModActiveState(int index, bool active); + void updateModsActiveState(const QList &modIndices, bool active); bool testForSteam(); diff --git a/src/profile.cpp b/src/profile.cpp index afe6fdc7..629e043f 100644 --- a/src/profile.cpp +++ b/src/profile.cpp @@ -568,6 +568,37 @@ void Profile::setModEnabled(unsigned int index, bool enabled) } } +void Profile::setModsEnabled(const QList &modsToEnable, const QList &modsToDisable) +{ + QList dirtyMods; + for (auto idx : modsToEnable) { + if (idx >= m_ModStatus.size()) { + qCritical() << tr("invalid index %1").arg(idx); + continue; + } + if (!m_ModStatus[idx].m_Enabled) { + m_ModStatus[idx].m_Enabled = true; + dirtyMods.append(idx); + } + } + for (auto idx : modsToDisable) { + if (idx >= m_ModStatus.size()) { + qCritical() << tr("invalid index %1").arg(idx); + continue; + } + if (ModInfo::getByIndex(idx)->alwaysEnabled()) { + continue; + } + if (m_ModStatus[idx].m_Enabled) { + m_ModStatus[idx].m_Enabled = false; + dirtyMods.append(idx); + } + } + if (!dirtyMods.isEmpty()) { + emit modStatusChanged(dirtyMods); + } +} + bool Profile::modEnabled(unsigned int index) const { if (index >= m_ModStatus.size()) { diff --git a/src/profile.h b/src/profile.h index dea933ad..a7ba7e91 100644 --- a/src/profile.h +++ b/src/profile.h @@ -273,6 +273,16 @@ public: **/ void setModEnabled(unsigned int index, bool enabled); + /** + * @brief enable or disable multiple mods at once + * This is an abbreviated process and should be immediately followed by a full refresh + * to maintain data consistency. + * + * @param modsToEnable list of mod indicies to enable + * @param modsToDisable list of mod indicies to disable + **/ + void setModsEnabled(const QList &modsToEnable, const QList &modsToDisable); + /** * change the priority of a mod. Of course this also changes the priority of other mods. * The priority of the mods in the range ]old, new priority] are shifted so that no gaps @@ -335,6 +345,13 @@ signals: **/ void modStatusChanged(unsigned int index); + /** + * @brief emitted whenever the status (enabled/disabled) of multiple mods change + * + * @param index list of indices of the mods that changed + **/ + void modStatusChanged(QList index); + public slots: // should only be called by DelayedFileWriter, use writeModlist() and writeModlistNow() instead -- cgit v1.3.1 From 4b522f40e88e1350434aaa7d77fc60cb7ca36930 Mon Sep 17 00:00:00 2001 From: LostDragonist Date: Wed, 30 Jan 2019 20:32:48 -0600 Subject: Make logs more consistent in format and content --- src/categories.cpp | 12 ++++++------ src/directoryrefresher.cpp | 9 ++++++++- src/executableslist.cpp | 4 ++-- src/installationmanager.cpp | 2 +- src/loadmechanism.cpp | 4 ++-- src/mainwindow.cpp | 4 ++-- src/modinfo.cpp | 4 ++-- src/modinfodialog.cpp | 2 +- src/modlistsortproxy.cpp | 4 ++-- src/organizercore.cpp | 10 +++++----- src/overwriteinfodialog.cpp | 2 +- src/pluginlist.cpp | 6 +++--- src/profile.cpp | 22 +++++++++++----------- 13 files changed, 46 insertions(+), 39 deletions(-) (limited to 'src/profile.cpp') diff --git a/src/categories.cpp b/src/categories.cpp index 4d89eff9..9e5fa9f7 100644 --- a/src/categories.cpp +++ b/src/categories.cpp @@ -72,7 +72,7 @@ void CategoryFactory::loadCategories() bool ok = false; int temp = iter->toInt(&ok); if (!ok) { - qCritical("invalid id %s", iter->constData()); + qCritical("invalid category id %s", iter->constData()); } nexusIDs.push_back(temp); } @@ -268,7 +268,7 @@ void CategoryFactory::loadDefaultCategories() int CategoryFactory::getParentID(unsigned int index) const { if (index >= m_Categories.size()) { - throw MyException(QObject::tr("invalid index %1").arg(index)); + throw MyException(QObject::tr("invalid category index: %1").arg(index)); } return m_Categories[index].m_ParentID; @@ -303,7 +303,7 @@ bool CategoryFactory::isDecendantOf(int id, int parentID) const bool CategoryFactory::hasChildren(unsigned int index) const { if (index >= m_Categories.size()) { - throw MyException(QObject::tr("invalid index %1").arg(index)); + throw MyException(QObject::tr("invalid category index: %1").arg(index)); } return m_Categories[index].m_HasChildren; @@ -313,7 +313,7 @@ bool CategoryFactory::hasChildren(unsigned int index) const QString CategoryFactory::getCategoryName(unsigned int index) const { if (index >= m_Categories.size()) { - throw MyException(QObject::tr("invalid index %1").arg(index)); + throw MyException(QObject::tr("invalid category index: %1").arg(index)); } return m_Categories[index].m_Name; @@ -323,7 +323,7 @@ QString CategoryFactory::getCategoryName(unsigned int index) const int CategoryFactory::getCategoryID(unsigned int index) const { if (index >= m_Categories.size()) { - throw MyException(QObject::tr("invalid index %1").arg(index)); + throw MyException(QObject::tr("invalid category index: %1").arg(index)); } return m_Categories[index].m_ID; @@ -334,7 +334,7 @@ int CategoryFactory::getCategoryIndex(int ID) const { std::map::const_iterator iter = m_IDMap.find(ID); if (iter == m_IDMap.end()) { - throw MyException(QObject::tr("invalid category id %1").arg(ID)); + throw MyException(QObject::tr("invalid category id: %1").arg(ID)); } return iter->second; } diff --git a/src/directoryrefresher.cpp b/src/directoryrefresher.cpp index c48b77d9..eded70b0 100644 --- a/src/directoryrefresher.cpp +++ b/src/directoryrefresher.cpp @@ -125,6 +125,10 @@ void DirectoryRefresher::addModFilesToStructure(DirectoryEntry *directoryStructu // files to this mod FilesOrigin &origin = directoryStructure->createOrigin(ToWString(modName), directoryW, priority); for (const QString &filename : stealFiles) { + if (filename.isEmpty()) { + qWarning("Trying to find file with no name"); + continue; + } QFileInfo fileInfo(filename); FileEntry::Ptr file = directoryStructure->findFile(ToWString(fileInfo.fileName())); if (file.get() != nullptr) { @@ -135,7 +139,10 @@ void DirectoryRefresher::addModFilesToStructure(DirectoryEntry *directoryStructu origin.addFile(file->getIndex()); file->addOrigin(origin.getID(), file->getFileTime(), L"", -1); } else { - qWarning("%s not found", qUtf8Printable(fileInfo.fileName())); + QString warnStr = fileInfo.absolutePath(); + if (warnStr.isEmpty()) + warnStr = filename; + qWarning("file not found: %1", qUtf8Printable(warnStr)); } } } else { diff --git a/src/executableslist.cpp b/src/executableslist.cpp index 21cb6ed4..ae4ebdbf 100644 --- a/src/executableslist.cpp +++ b/src/executableslist.cpp @@ -75,7 +75,7 @@ const Executable &ExecutablesList::find(const QString &title) const return exe; } } - throw std::runtime_error(QString("invalid name %1").arg(title).toLocal8Bit().constData()); + throw std::runtime_error(QString("invalid executable name: %1").arg(title).toLocal8Bit().constData()); } @@ -86,7 +86,7 @@ Executable &ExecutablesList::find(const QString &title) return exe; } } - throw std::runtime_error(QString("invalid executable name %1").arg(title).toLocal8Bit().constData()); + throw std::runtime_error(QString("invalid executable name: %1").arg(title).toLocal8Bit().constData()); } diff --git a/src/installationmanager.cpp b/src/installationmanager.cpp index 6719c84a..83128e4b 100644 --- a/src/installationmanager.cpp +++ b/src/installationmanager.cpp @@ -762,7 +762,7 @@ bool InstallationManager::install(const QString &fileName, if (fileInfo.dir() == QDir(m_DownloadsDirectory)) { m_CurrentFile = fileInfo.fileName(); } - qDebug("using mod name \"%s\" (id %d) -> %s", modName->toUtf8().constData(), modID, qUtf8Printable(m_CurrentFile)); + qDebug("using mod name \"%s\" (id %d) -> %s", qUtf8Printable(modName), modID, qUtf8Printable(m_CurrentFile)); //If there's an archive already open, close it. This happens with the bundle //installer when it uncompresses a split archive, then finds it has a real archive diff --git a/src/loadmechanism.cpp b/src/loadmechanism.cpp index ebbb5de3..8f0529ce 100644 --- a/src/loadmechanism.cpp +++ b/src/loadmechanism.cpp @@ -100,7 +100,7 @@ bool LoadMechanism::hashIdentical(const QString &fileNameLHS, const QString &fil { QFile fileLHS(fileNameLHS); if (!fileLHS.open(QIODevice::ReadOnly)) { - throw MyException(QObject::tr("%1 not found").arg(fileNameLHS)); + throw MyException(QObject::tr("file not found: %1").arg(qUtf8Printable(fileNameLHS))); } QByteArray dataLHS = fileLHS.readAll(); QByteArray hashLHS = QCryptographicHash::hash(dataLHS, QCryptographicHash::Md5); @@ -109,7 +109,7 @@ bool LoadMechanism::hashIdentical(const QString &fileNameLHS, const QString &fil QFile fileRHS(fileNameRHS); if (!fileRHS.open(QIODevice::ReadOnly)) { - throw MyException(QObject::tr("%1 not found").arg(fileNameRHS)); + throw MyException(QObject::tr("file not found: %1").arg(qUtf8Printable(fileNameRHS))); } QByteArray dataRHS = fileRHS.readAll(); QByteArray hashRHS = QCryptographicHash::hash(dataRHS, QCryptographicHash::Md5); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index fccb5efe..8bcf7ba7 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -5186,7 +5186,7 @@ void MainWindow::previewDataFile() const FileEntry::Ptr file = m_OrganizerCore.directoryStructure()->searchFile(ToWString(fileName), nullptr); if (file.get() == nullptr) { - reportError(tr("file not found: %1").arg(fileName)); + reportError(tr("file not found: %1").arg(qUtf8Printable(fileName))); return; } @@ -6339,7 +6339,7 @@ void MainWindow::dropLocalFile(const QUrl &url, const QString &outputDir, bool m { QFileInfo file(url.toLocalFile()); if (!file.exists()) { - qWarning("invalid source file %s", qUtf8Printable(file.absoluteFilePath())); + qWarning("invalid source file: %s", qUtf8Printable(file.absoluteFilePath())); return; } QString target = outputDir + "/" + file.fileName(); diff --git a/src/modinfo.cpp b/src/modinfo.cpp index 1c6139f6..7ae41b02 100644 --- a/src/modinfo.cpp +++ b/src/modinfo.cpp @@ -110,7 +110,7 @@ QString ModInfo::getContentTypeName(int contentType) case CONTENT_INI: return tr("INI files"); case CONTENT_MODGROUP: return tr("ModGroup files"); - default: throw MyException(tr("invalid content type %1").arg(contentType)); + default: throw MyException(tr("invalid content type: %1").arg(contentType)); } } @@ -133,7 +133,7 @@ ModInfo::Ptr ModInfo::getByIndex(unsigned int index) QMutexLocker locker(&s_Mutex); if (index >= s_Collection.size() && index != ULONG_MAX) { - throw MyException(tr("invalid mod index %1").arg(index)); + throw MyException(tr("invalid mod index: %1").arg(index)); } if (index == ULONG_MAX) return s_Collection[ModInfo::getIndex("Overwrite")]; return s_Collection[index]; diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp index d2e5e84f..04506374 100644 --- a/src/modinfodialog.cpp +++ b/src/modinfodialog.cpp @@ -1431,7 +1431,7 @@ void ModInfoDialog::previewDataFile() const FileEntry::Ptr file = m_OrganizerCore->directoryStructure()->searchFile(ToWString(fileName), nullptr); if (file.get() == nullptr) { - reportError(tr("file not found: %1").arg(fileName)); + reportError(tr("file not found: %1").arg(qUtf8Printable(fileName))); return; } diff --git a/src/modlistsortproxy.cpp b/src/modlistsortproxy.cpp index 99f0efef..2d9ea4a5 100644 --- a/src/modlistsortproxy.cpp +++ b/src/modlistsortproxy.cpp @@ -474,13 +474,13 @@ bool ModListSortProxy::filterAcceptsRow(int row, const QModelIndex &parent) cons } if (row >= static_cast(m_Profile->numMods())) { - qWarning("invalid row idx %d", row); + qWarning("invalid row index: %d", row); return false; } QModelIndex idx = sourceModel()->index(row, 0, parent); if (!idx.isValid()) { - qDebug("invalid index"); + qDebug("invalid mod index"); return false; } if (sourceModel()->hasChildren(idx)) { diff --git a/src/organizercore.cpp b/src/organizercore.cpp index 10b6fd8b..4fa09ab6 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -1010,7 +1010,7 @@ MOBase::IModInterface *OrganizerCore::installMod(const QString &fileName, emit modInstalled(modName); return modInfo.data(); } else { - reportError(tr("mod \"%1\" not found").arg(modName)); + reportError(tr("mod not found: %1").arg(qUtf8Printable(modName))); } } else if (m_InstallationManager.wasCancelled()) { QMessageBox::information(qApp->activeWindow(), tr("Installation cancelled"), @@ -1068,7 +1068,7 @@ void OrganizerCore::installDownload(int index) m_ModInstalled(modName); } else { - reportError(tr("mod \"%1\" not found").arg(modName)); + reportError(tr("mod not found: %1").arg(qUtf8Printable(modName))); } m_DownloadManager.markInstalled(index); @@ -1129,7 +1129,7 @@ QStringList OrganizerCore::findFiles( } } } else { - qWarning("directory %s not found", qUtf8Printable(path)); + qWarning("directory not found: %1", qUtf8Printable(path)); } return result; } @@ -1148,7 +1148,7 @@ QStringList OrganizerCore::getFileOrigins(const QString &fileName) const ToQString(m_DirectoryStructure->getOriginByID(i.first).getName())); } } else { - qDebug("%s not found", qUtf8Printable(fileName)); + qWarning("file not found: %1", qUtf8Printable(fileName)); } return result; } @@ -1294,7 +1294,7 @@ HANDLE OrganizerCore::spawnBinaryProcess(const QFileInfo &binary, if (!binary.exists()) { reportError( - tr("Executable \"%1\" not found").arg(binary.absoluteFilePath())); + tr("Executable not found: %1").arg(qUtf8Printable(binary.absoluteFilePath()))); return INVALID_HANDLE_VALUE; } diff --git a/src/overwriteinfodialog.cpp b/src/overwriteinfodialog.cpp index 4d35a2c3..d1289c91 100644 --- a/src/overwriteinfodialog.cpp +++ b/src/overwriteinfodialog.cpp @@ -110,7 +110,7 @@ void OverwriteInfoDialog::setModInfo(ModInfo::Ptr modInfo) if (QDir(modInfo->absolutePath()).exists()) { m_FileSystemModel->setRootPath(modInfo->absolutePath()); } else { - throw MyException(tr("%1 not found").arg(modInfo->absolutePath())); + throw MyException(tr("mod not found: %1").arg(qUtf8Printable(modInfo->absolutePath()))); } } diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp index b2fabbe0..56a5c91f 100644 --- a/src/pluginlist.cpp +++ b/src/pluginlist.cpp @@ -298,7 +298,7 @@ void PluginList::enableESP(const QString &name, bool enable) emit writePluginsList(); } else { - reportError(tr("esp not found: %1").arg(name)); + reportError(tr("Plugin not found: %1").arg(qUtf8Printable(name))); } } @@ -694,7 +694,7 @@ void PluginList::setState(const QString &name, PluginStates state) { m_ESPs[iter->second].m_Enabled = (state == IPluginList::STATE_ACTIVE) || m_ESPs[iter->second].m_ForceEnabled; } else { - qWarning("plugin %s not found", qUtf8Printable(name)); + qWarning("Plugin not found: %1", qUtf8Printable(name)); } } @@ -824,7 +824,7 @@ void PluginList::updateIndices() continue; } if (m_ESPs[i].m_Priority >= static_cast(m_ESPs.size())) { - qCritical("invalid priority %d", m_ESPs[i].m_Priority); + qCritical("invalid plugin priority: %d", m_ESPs[i].m_Priority); continue; } m_ESPsByName[m_ESPs[i].m_Name.toLower()] = i; diff --git a/src/profile.cpp b/src/profile.cpp index 629e043f..a5e3bc54 100644 --- a/src/profile.cpp +++ b/src/profile.cpp @@ -78,7 +78,7 @@ Profile::Profile(const QString &name, IPluginGame const *gamePlugin, bool useDef QDir profileBase(profilesDir); QString fixedName = name; if (!fixDirectoryName(fixedName)) { - throw MyException(tr("invalid profile name %1").arg(name)); + throw MyException(tr("invalid profile name: %1").arg(qUtf8Printable(name))); } if (!profileBase.exists() || !profileBase.mkdir(fixedName)) { @@ -416,19 +416,19 @@ void Profile::refreshModStatus() m_ModStatus[modIndex].m_Enabled = enabled; if (m_ModStatus[modIndex].m_Priority == -1) { if (static_cast(index) >= m_ModStatus.size()) { - throw MyException(tr("invalid index %1").arg(index)); + throw MyException(tr("invalid mod index: %1").arg(index)); } m_ModStatus[modIndex].m_Priority = index++; } } else { qWarning("no mod state for \"%s\" (profile \"%s\")", - qUtf8Printable(modName), m_Directory.path().toUtf8().constData()); + qUtf8Printable(modName), qUtf8Printable(m_Directory.path())); // need to rewrite the modlist to fix this modStatusModified = true; } } else { - qDebug("mod \"%s\" (profile \"%s\") not found", - qUtf8Printable(modName), m_Directory.path().toUtf8().constData()); + qDebug("mod not found: \"%s\" (profile \"%s\")", + qUtf8Printable(modName), qUtf8Printable(m_Directory.path())); // need to rewrite the modlist to fix this modStatusModified = true; } @@ -455,7 +455,7 @@ void Profile::refreshModStatus() m_ModStatus[i].m_Priority = numKnownMods - m_ModStatus[i].m_Priority - 1; } else { if (static_cast(index) >= m_ModStatus.size()) { - throw MyException(tr("invalid index %1").arg(index)); + throw MyException(tr("invalid mod index: %1").arg(index)); } if (modInfo->hasFlag(ModInfo::FLAG_FOREIGN)) { m_ModStatus[i].m_Priority = --topInsert; @@ -552,7 +552,7 @@ unsigned int Profile::modIndexByPriority(int priority) const void Profile::setModEnabled(unsigned int index, bool enabled) { if (index >= m_ModStatus.size()) { - throw MyException(tr("invalid index %1").arg(index)); + throw MyException(tr("invalid mod index: %1").arg(index)); } ModInfo::Ptr modInfo = ModInfo::getByIndex(index); @@ -573,7 +573,7 @@ void Profile::setModsEnabled(const QList &modsToEnable, const QLis QList dirtyMods; for (auto idx : modsToEnable) { if (idx >= m_ModStatus.size()) { - qCritical() << tr("invalid index %1").arg(idx); + qCritical() << tr("invalid mod index: %1").arg(idx); continue; } if (!m_ModStatus[idx].m_Enabled) { @@ -583,7 +583,7 @@ void Profile::setModsEnabled(const QList &modsToEnable, const QLis } for (auto idx : modsToDisable) { if (idx >= m_ModStatus.size()) { - qCritical() << tr("invalid index %1").arg(idx); + qCritical() << tr("invalid mod index: %1").arg(idx); continue; } if (ModInfo::getByIndex(idx)->alwaysEnabled()) { @@ -602,7 +602,7 @@ void Profile::setModsEnabled(const QList &modsToEnable, const QLis bool Profile::modEnabled(unsigned int index) const { if (index >= m_ModStatus.size()) { - throw MyException(tr("invalid index %1").arg(index)); + throw MyException(tr("invalid mod index: %1").arg(index)); } return m_ModStatus[index].m_Enabled; @@ -612,7 +612,7 @@ bool Profile::modEnabled(unsigned int index) const int Profile::getModPriority(unsigned int index) const { if (index >= m_ModStatus.size()) { - throw MyException(tr("invalid index %1").arg(index)); + throw MyException(tr("invalid mod index: %1").arg(index)); } return m_ModStatus[index].m_Priority; -- cgit v1.3.1 From 1369c8d5712bc3b23bcc5a5e9ead4a6ec159bc17 Mon Sep 17 00:00:00 2001 From: LostDragonist Date: Wed, 30 Jan 2019 20:53:48 -0600 Subject: Make logs more consistent in format and content --- src/bbcode.cpp | 2 +- src/downloadmanager.cpp | 2 +- src/installationmanager.cpp | 4 ++-- src/mainwindow.cpp | 8 ++++---- src/modinfodialog.cpp | 4 ++-- src/modinforegular.cpp | 4 ++-- src/organizercore.cpp | 22 +++++++++++----------- src/overwriteinfodialog.cpp | 2 +- src/profile.cpp | 2 +- src/syncoverwritedialog.cpp | 2 +- src/transfersavesdialog.cpp | 2 +- 11 files changed, 27 insertions(+), 27 deletions(-) (limited to 'src/profile.cpp') diff --git a/src/bbcode.cpp b/src/bbcode.cpp index 84d7a7c0..3475f1b2 100644 --- a/src/bbcode.cpp +++ b/src/bbcode.cpp @@ -100,7 +100,7 @@ public: // expression doesn't match. either the input string is invalid // or the expression is qWarning("%s doesn't match the expression for %s", - temp.toUtf8().constData(), tagName.toUtf8().constData()); + qUtf8Printable(temp), qUtf8Printable(tagName)); length = 0; return QString(); } diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp index 15831126..1e4ec1f4 100644 --- a/src/downloadmanager.cpp +++ b/src/downloadmanager.cpp @@ -1510,7 +1510,7 @@ void DownloadManager::nxmFilesAvailable(QString, int, QVariant userData, QVarian } else { if (info->m_FileInfo->fileID == 0) { qWarning("could not determine file id for %s (state %d)", - info->m_FileName.toUtf8().constData(), info->m_State); + qUtf8Printable(info->m_FileName), info->m_State); } } diff --git a/src/installationmanager.cpp b/src/installationmanager.cpp index 83128e4b..be838867 100644 --- a/src/installationmanager.cpp +++ b/src/installationmanager.cpp @@ -526,7 +526,7 @@ bool InstallationManager::testOverwrite(GuessedValue &modName, bool *me settingsFile.write(originalSettings); settingsFile.close(); } else { - qCritical("failed to restore original settings: %s", metaFilename.toUtf8().constData()); + qCritical("failed to restore original settings: %s", qUtf8Printable(metaFilename)); } return true; } else if (overwriteDialog.action() == QueryOverwriteDialog::ACT_MERGE) { @@ -575,7 +575,7 @@ bool InstallationManager::doInstall(GuessedValue &modName, QString game QString targetDirectory = QDir(m_ModsDirectory + "/" + modName).canonicalPath(); QString targetDirectoryNative = QDir::toNativeSeparators(targetDirectory); - qDebug("installing to \"%s\"", targetDirectoryNative.toUtf8().constData()); + qDebug("installing to \"%s\"", qUtf8Printable(targetDirectoryNative)); m_InstallationProgress = new QProgressDialog(m_ParentWidget); ON_BLOCK_EXIT([this] () { diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 8bcf7ba7..9904845b 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1190,7 +1190,7 @@ void MainWindow::startExeAction() selectedExecutable.m_WorkingDirectory.length() != 0 ? selectedExecutable.m_WorkingDirectory : selectedExecutable.m_BinaryInfo.absolutePath(), - selectedExecutable.m_SteamAppID, + selectedExecutable.m_SteamAppID, customOverwrite, forcedLibraries); } else { @@ -1990,7 +1990,7 @@ void MainWindow::on_startButton_clicked() { selectedExecutable.m_WorkingDirectory.length() != 0 ? selectedExecutable.m_WorkingDirectory : selectedExecutable.m_BinaryInfo.absolutePath(), - selectedExecutable.m_SteamAppID, + selectedExecutable.m_SteamAppID, customOverwrite, forcedLibraries); } catch (...) { @@ -2961,7 +2961,7 @@ void MainWindow::displayModInformation(const QString &modName, int tab) { unsigned int index = ModInfo::getIndex(modName); if (index == UINT_MAX) { - qCritical("failed to resolve mod name %s", modName.toUtf8().constData()); + qCritical("failed to resolve mod name %s", qUtf8Printable(modName)); return; } @@ -5531,7 +5531,7 @@ BSA::EErrorCode MainWindow::extractBSA(BSA::Archive &archive, BSA::Folder::Ptr f for (unsigned int i = 0; i < folder->getNumFiles(); ++i) { BSA::File::Ptr file = folder->getFile(i); - BSA::EErrorCode res = archive.extract(file, destination.toUtf8().constData()); + BSA::EErrorCode res = archive.extract(file, qUtf8Printable(destination)); if (res != BSA::ERROR_NONE) { reportError(tr("failed to read %1: %2").arg(file->getName().c_str()).arg(res)); result = res; diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp index 04506374..c2ded812 100644 --- a/src/modinfodialog.cpp +++ b/src/modinfodialog.cpp @@ -331,7 +331,7 @@ void ModInfoDialog::refreshLists() QStringList fields(relativeName.prepend("...")); fields.append(ToQString(altString.str())); - QTreeWidgetItem *item = new QTreeWidgetItem(fields); + QTreeWidgetItem *item = new QTreeWidgetItem(fields); item->setData(0, Qt::UserRole, fileName); item->setData(1, Qt::UserRole, ToQString(m_Directory->getOriginByID(alternatives.back().first).getName())); item->setData(1, Qt::UserRole + 1, alternatives.back().first); @@ -1123,7 +1123,7 @@ void ModInfoDialog::openFile(const QModelIndex &index) HINSTANCE res = ::ShellExecuteW(nullptr, L"open", ToWString(fileName).c_str(), nullptr, nullptr, SW_SHOW); if ((unsigned long long)res <= 32) { - qCritical("failed to invoke %s: %d", fileName.toUtf8().constData(), res); + qCritical("failed to invoke %s: %d", qUtf8Printable(fileName), res); } } diff --git a/src/modinforegular.cpp b/src/modinforegular.cpp index f29d3725..15ce56ba 100644 --- a/src/modinforegular.cpp +++ b/src/modinforegular.cpp @@ -64,7 +64,7 @@ ModInfoRegular::~ModInfoRegular() saveMeta(); } catch (const std::exception &e) { qCritical("failed to save meta information for \"%s\": %s", - m_Name.toUtf8().constData(), e.what()); + qUtf8Printable(m_Name), e.what()); } } @@ -631,7 +631,7 @@ QString ModInfoRegular::getURL() const -QStringList ModInfoRegular::archives(bool checkOnDisk) +QStringList ModInfoRegular::archives(bool checkOnDisk) { if (checkOnDisk) { QStringList result; diff --git a/src/organizercore.cpp b/src/organizercore.cpp index 4fa09ab6..a3addcb4 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -1208,18 +1208,18 @@ QStringList OrganizerCore::modsSortedByProfilePriority() const ++i) { int modIndex = currentProfile()->modIndexByPriority(i); auto modInfo = ModInfo::getByIndex(modIndex); - if (!modInfo->hasFlag(ModInfo::FLAG_OVERWRITE) && + if (!modInfo->hasFlag(ModInfo::FLAG_OVERWRITE) && !modInfo->hasFlag(ModInfo::FLAG_BACKUP)) { res.push_back(ModInfo::getByIndex(modIndex)->name()); - } + } } return res; } -void OrganizerCore::spawnBinary(const QFileInfo &binary, - const QString &arguments, - const QDir ¤tDirectory, - const QString &steamAppID, +void OrganizerCore::spawnBinary(const QFileInfo &binary, + const QString &arguments, + const QDir ¤tDirectory, + const QString &steamAppID, const QString &customOverwrite, const QList &forcedLibraries) { @@ -1349,7 +1349,7 @@ HANDLE OrganizerCore::spawnBinaryProcess(const QFileInfo &binary, try { m_USVFS.updateMapping(fileMapping(profileName, customOverwrite)); m_USVFS.updateForcedLibraries(forcedLibraries); - + } catch (const UsvfsConnectorException &e) { qDebug(e.what()); return INVALID_HANDLE_VALUE; @@ -1453,7 +1453,7 @@ HANDLE OrganizerCore::runShortcut(const MOShortcut& shortcut) exe.m_WorkingDirectory.length() != 0 ? exe.m_WorkingDirectory : exe.m_BinaryInfo.absolutePath(), - exe.m_SteamAppID, + exe.m_SteamAppID, "", forcedLibaries); } @@ -1521,7 +1521,7 @@ HANDLE OrganizerCore::startApplication(const QString &executable, } } catch (const std::runtime_error &) { qWarning("\"%s\" not set up as executable", - executable.toUtf8().constData()); + qUtf8Printable(executable)); binary = QFileInfo(executable); } } @@ -1585,7 +1585,7 @@ bool OrganizerCore::waitForProcessCompletion(HANDLE handle, LPDWORD exitCode, IL uilock->setProcessName(processName); qDebug() << "Waiting for" << (originalHandle ? "spawned" : "usvfs") - << "process completion :" << processName.toUtf8().constData(); + << "process completion :" << qUtf8Printable(processName); newHandle = false; } @@ -1840,7 +1840,7 @@ void OrganizerCore::updateModsActiveState(const QList &modIndices, m_PluginList.blockSignals(false); } } - + for (const QString &esl : dir.entryList(QStringList() << "*.esl", QDir::Files)) { const FileEntry::Ptr file = m_DirectoryStructure->findFile(ToWString(esl)); diff --git a/src/overwriteinfodialog.cpp b/src/overwriteinfodialog.cpp index d1289c91..3d82cf17 100644 --- a/src/overwriteinfodialog.cpp +++ b/src/overwriteinfodialog.cpp @@ -221,7 +221,7 @@ void OverwriteInfoDialog::openFile(const QModelIndex &index) HINSTANCE res = ::ShellExecuteW(nullptr, L"open", ToWString(fileName).c_str(), nullptr, nullptr, SW_SHOW); if ((INT_PTR)res <= 32) { - qCritical("failed to invoke %s: %d", fileName.toUtf8().constData(), res); + qCritical("failed to invoke %s: %d", qUtf8Printable(fileName), res); } } diff --git a/src/profile.cpp b/src/profile.cpp index a5e3bc54..79f7d59e 100644 --- a/src/profile.cpp +++ b/src/profile.cpp @@ -349,7 +349,7 @@ void Profile::renameModInList(QFile &modList, const QString &oldName, const QStr modName = newName; ++renamed; } - outBuffer.write(modName.toUtf8().constData()); + outBuffer.write(qUtf8Printable(modName)); outBuffer.write("\r\n"); } modList.close(); diff --git a/src/syncoverwritedialog.cpp b/src/syncoverwritedialog.cpp index 7c341567..4ee4716e 100644 --- a/src/syncoverwritedialog.cpp +++ b/src/syncoverwritedialog.cpp @@ -86,7 +86,7 @@ void SyncOverwriteDialog::readTree(const QString &path, DirectoryEntry *director if (subDir != nullptr) { readTree(fileInfo.absoluteFilePath(), subDir, newItem); } else { - qCritical("no directory structure for %s?", file.toUtf8().constData()); + qCritical("no directory structure for %s?", qUtf8Printable(file)); delete newItem; newItem = nullptr; } diff --git a/src/transfersavesdialog.cpp b/src/transfersavesdialog.cpp index 61dab6e5..130df14f 100644 --- a/src/transfersavesdialog.cpp +++ b/src/transfersavesdialog.cpp @@ -342,7 +342,7 @@ bool TransferSavesDialog::transferCharacters( if (!method(sourceFile.absoluteFilePath(), destinationFile)) { qCritical(errmsg, sourceFile.absoluteFilePath().toUtf8().constData(), - destinationFile.toUtf8().constData()); + qUtf8Printable(destinationFile)); } } } -- cgit v1.3.1 From d26c4e8ea2c2450b4abedf965803a1046cb55625 Mon Sep 17 00:00:00 2001 From: LostDragonist Date: Sat, 9 Mar 2019 20:47:10 -0600 Subject: Fix conflict detection concerning overwrite --- src/directoryrefresher.cpp | 3 +-- src/modinfowithconflictinfo.cpp | 3 ++- src/profile.cpp | 15 ++++----------- 3 files changed, 7 insertions(+), 14 deletions(-) (limited to 'src/profile.cpp') diff --git a/src/directoryrefresher.cpp b/src/directoryrefresher.cpp index 8b6c55e3..3ce4691b 100644 --- a/src/directoryrefresher.cpp +++ b/src/directoryrefresher.cpp @@ -178,10 +178,9 @@ void DirectoryRefresher::refresh() std::wstring dataDirectory = QDir::toNativeSeparators(game->dataDirectory().absolutePath()).toStdWString(); m_DirectoryStructure->addFromOrigin(L"data", dataDirectory, 0); - // TODO what was the point of having the priority in this tuple? the list is already sorted by priority + std::sort(m_Mods.begin(), m_Mods.end(), [](auto lhs, auto rhs){return lhs.priority < rhs.priority;}); auto iter = m_Mods.begin(); - //TODO i is the priority here, where higher = more important. the input vector is also sorted by priority but inverted! for (int i = 1; iter != m_Mods.end(); ++iter, ++i) { try { addModToStructure(m_DirectoryStructure, iter->modName, i, iter->absolutePath, iter->stealFiles, iter->archives); diff --git a/src/modinfowithconflictinfo.cpp b/src/modinfowithconflictinfo.cpp index 12cbf416..744f323c 100644 --- a/src/modinfowithconflictinfo.cpp +++ b/src/modinfowithconflictinfo.cpp @@ -126,7 +126,8 @@ void ModInfoWithConflictInfo::doConflictCheck() const for (auto altInfo : alternatives) { if ((altInfo.first != dataID) && (altInfo.first != origin.getID())) { FilesOrigin &altOrigin = (*m_DirectoryStructure)->getOriginByID(altInfo.first); - unsigned int altIndex = ModInfo::getIndex(ToQString(altOrigin.getName())); + QString altOriginName = ToQString(altOrigin.getName()); + unsigned int altIndex = ModInfo::getIndex(altOriginName); if (altInfo.second.first.size() == 0) { if (archiveData.first.size() == 0) { if (origin.getPriority() > altOrigin.getPriority()) { diff --git a/src/profile.cpp b/src/profile.cpp index 79f7d59e..259f93c8 100644 --- a/src/profile.cpp +++ b/src/profile.cpp @@ -521,20 +521,13 @@ std::vector > Profile::getActiveMods() for (std::map::const_iterator iter = m_ModIndexByPriority.begin(); iter != m_ModIndexByPriority.end(); iter++ ) { if ((iter->second != UINT_MAX) && m_ModStatus[iter->second].m_Enabled) { ModInfo::Ptr modInfo = ModInfo::getByIndex(iter->second); - result.push_back(std::make_tuple(modInfo->internalName(), modInfo->absolutePath(), m_ModStatus[iter->second].m_Priority)); + if (modInfo->hasFlag(ModInfo::FLAG_OVERWRITE)) + result.push_back(std::make_tuple(modInfo->internalName(), modInfo->absolutePath(), INT_MAX)); + else + result.push_back(std::make_tuple(modInfo->internalName(), modInfo->absolutePath(), m_ModStatus[iter->second].m_Priority)); } } - unsigned int overwriteIndex = ModInfo::findMod([](ModInfo::Ptr mod) -> bool { - std::vector flags = mod->getFlags(); - return std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end(); }); - - if (overwriteIndex != UINT_MAX) { - ModInfo::Ptr overwriteInfo = ModInfo::getByIndex(overwriteIndex); - result.push_back(std::make_tuple(overwriteInfo->name(), overwriteInfo->absolutePath(), UINT_MAX)); - } else { - reportError(tr("Overwrite directory couldn't be parsed")); - } return result; } -- cgit v1.3.1 From 3c488a69ed7303b455da5c52f3f3dd24a705b390 Mon Sep 17 00:00:00 2001 From: LostDragonist Date: Sat, 13 Apr 2019 20:05:09 -0500 Subject: Fix typo in missing INI dialog --- src/profile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/profile.cpp') diff --git a/src/profile.cpp b/src/profile.cpp index 259f93c8..4ccaa641 100644 --- a/src/profile.cpp +++ b/src/profile.cpp @@ -809,7 +809,7 @@ bool Profile::localSettingsEnabled() const QMessageBox::StandardButton res = QMessageBox::warning( QApplication::activeModalWidget(), tr("Missing profile-specific game INI files!"), tr("Some of your profile-specific game INI files were missing. They will now be copied " - "from the vanilla game folder. You might want double-check your settings.\n\n" + "from the vanilla game folder. You might want to double-check your settings.\n\n" "Missing files:\n") + missingFiles.join("\n") ); } -- cgit v1.3.1