From f6ef5477e718b14af99bd22436f66dee0b9d22cd Mon Sep 17 00:00:00 2001 From: Tannin Date: Thu, 17 Jul 2014 22:02:15 +0200 Subject: normalized eol style (all files should now have windows line endings) --- src/messagedialog.cpp | 184 +++++++++++++++++++++++++------------------------- 1 file changed, 92 insertions(+), 92 deletions(-) (limited to 'src/messagedialog.cpp') diff --git a/src/messagedialog.cpp b/src/messagedialog.cpp index 2aa07ccf..863d7628 100644 --- a/src/messagedialog.cpp +++ b/src/messagedialog.cpp @@ -1,92 +1,92 @@ -/* -Copyright (C) 2012 Sebastian Herbord. All rights reserved. - -This file is part of Mod Organizer. - -Mod Organizer is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -Mod Organizer is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Mod Organizer. If not, see . -*/ - -#include "messagedialog.h" -#include "ui_messagedialog.h" -#include -#include -#include - -MessageDialog::MessageDialog(const QString &text, QWidget *reference) : - QDialog(reference), - ui(new Ui::MessageDialog) -{ - ui->setupUi(this); - - // very crude way to ensure no single word in the test is wider than the message window. ellide in the center if necessary - QFontMetrics metrics(ui->message->font()); - QString restrictedText; - QStringList lines = text.split("\n"); - foreach (const QString &line, lines) { - QString newLine; - QStringList words = line.split(" "); - foreach (const QString &word, words) { - if (word.length() > 10) { - newLine += "" + metrics.elidedText(word, Qt::ElideMiddle, ui->message->maximumWidth()) + ""; - } else { - newLine += word; - } - newLine += " "; - } - restrictedText += newLine + "\n"; - } - - ui->message->setText(restrictedText); - this->setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); - this->setFocusPolicy(Qt::NoFocus); - this->setAttribute(Qt::WA_ShowWithoutActivating); - QTimer::singleShot(1000 + (text.length() * 40), this, SLOT(hide())); - if (reference != NULL) { - QPoint position = reference->mapToGlobal(QPoint(reference->width() / 2, reference->height())); - position.rx() -= this->width() / 2; - position.ry() -= this->height() + 5; - move(position); - } -} - - -MessageDialog::~MessageDialog() -{ - delete ui; -} - - -void MessageDialog::resizeEvent(QResizeEvent *event) -{ - QWidget *par = parentWidget(); - if (par != NULL) { - QPoint position = par->mapToGlobal(QPoint(par->width() / 2, par->height())); - position.rx() -= event->size().width() / 2; - position.ry() -= event->size().height() + 5; - move(position); - } -} - - -void MessageDialog::showMessage(const QString &text, QWidget *reference, bool bringToFront) -{ - qDebug("%s", qPrintable(text)); - if (reference != NULL) { - if (bringToFront || (qApp->activeWindow() != NULL)) { - MessageDialog *dialog = new MessageDialog(text, reference); - dialog->show(); - reference->activateWindow(); - } - } -} +/* +Copyright (C) 2012 Sebastian Herbord. All rights reserved. + +This file is part of Mod Organizer. + +Mod Organizer is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Mod Organizer is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Mod Organizer. If not, see . +*/ + +#include "messagedialog.h" +#include "ui_messagedialog.h" +#include +#include +#include + +MessageDialog::MessageDialog(const QString &text, QWidget *reference) : + QDialog(reference), + ui(new Ui::MessageDialog) +{ + ui->setupUi(this); + + // very crude way to ensure no single word in the test is wider than the message window. ellide in the center if necessary + QFontMetrics metrics(ui->message->font()); + QString restrictedText; + QStringList lines = text.split("\n"); + foreach (const QString &line, lines) { + QString newLine; + QStringList words = line.split(" "); + foreach (const QString &word, words) { + if (word.length() > 10) { + newLine += "" + metrics.elidedText(word, Qt::ElideMiddle, ui->message->maximumWidth()) + ""; + } else { + newLine += word; + } + newLine += " "; + } + restrictedText += newLine + "\n"; + } + + ui->message->setText(restrictedText); + this->setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); + this->setFocusPolicy(Qt::NoFocus); + this->setAttribute(Qt::WA_ShowWithoutActivating); + QTimer::singleShot(1000 + (text.length() * 40), this, SLOT(hide())); + if (reference != NULL) { + QPoint position = reference->mapToGlobal(QPoint(reference->width() / 2, reference->height())); + position.rx() -= this->width() / 2; + position.ry() -= this->height() + 5; + move(position); + } +} + + +MessageDialog::~MessageDialog() +{ + delete ui; +} + + +void MessageDialog::resizeEvent(QResizeEvent *event) +{ + QWidget *par = parentWidget(); + if (par != NULL) { + QPoint position = par->mapToGlobal(QPoint(par->width() / 2, par->height())); + position.rx() -= event->size().width() / 2; + position.ry() -= event->size().height() + 5; + move(position); + } +} + + +void MessageDialog::showMessage(const QString &text, QWidget *reference, bool bringToFront) +{ + qDebug("%s", qPrintable(text)); + if (reference != NULL) { + if (bringToFront || (qApp->activeWindow() != NULL)) { + MessageDialog *dialog = new MessageDialog(text, reference); + dialog->show(); + reference->activateWindow(); + } + } +} -- cgit v1.3.1 From f2f9e11fdd876821107cff0c1c5b9d8ecf66691f Mon Sep 17 00:00:00 2001 From: Tannin Date: Fri, 21 Nov 2014 14:45:30 +0100 Subject: - started on a refactoring moving functionality out of the MainWindow class - started on support for game-plugins --- src/browserdialog.cpp | 1 - src/editexecutablesdialog.cpp | 18 +- src/editexecutablesdialog.ui | 3 + src/executableslist.cpp | 32 +- src/executableslist.h | 13 +- src/installationmanager.cpp | 13 +- src/installationmanager.h | 4 +- src/iuserinterface.h | 39 + src/main.cpp | 36 +- src/mainwindow.cpp | 1851 +++++++++-------------------------------- src/mainwindow.h | 152 +--- src/messagedialog.cpp | 2 +- src/organizer.pro | 11 +- src/organizercore.cpp | 1249 +++++++++++++++++++++++++++ src/organizercore.h | 239 ++++++ src/organizerproxy.cpp | 108 +-- src/organizerproxy.h | 12 +- src/plugincontainer.cpp | 329 ++++++++ src/plugincontainer.h | 102 +++ src/selfupdater.cpp | 11 +- src/selfupdater.h | 4 +- src/shared/fallout3info.cpp | 4 +- src/shared/fallout3info.h | 2 +- src/shared/falloutnvinfo.cpp | 4 +- src/shared/falloutnvinfo.h | 2 +- src/shared/gameinfo.h | 10 +- src/shared/oblivioninfo.cpp | 4 +- src/shared/oblivioninfo.h | 2 +- src/shared/skyriminfo.cpp | 4 +- src/shared/skyriminfo.h | 2 +- 30 files changed, 2509 insertions(+), 1754 deletions(-) create mode 100644 src/iuserinterface.h create mode 100644 src/organizercore.cpp create mode 100644 src/organizercore.h create mode 100644 src/plugincontainer.cpp create mode 100644 src/plugincontainer.h (limited to 'src/messagedialog.cpp') diff --git a/src/browserdialog.cpp b/src/browserdialog.cpp index f93ffcae..933b4bc0 100644 --- a/src/browserdialog.cpp +++ b/src/browserdialog.cpp @@ -202,7 +202,6 @@ void BrowserDialog::unsupportedContent(QNetworkReply *reply) return; } - qDebug("unsupported: %s - %s", view->url().toString().toUtf8().constData(), reply->url().toString().toUtf8().constData()); emit requestDownload(view->url(), reply); } catch (const std::exception &e) { if (isVisible()) { diff --git a/src/editexecutablesdialog.cpp b/src/editexecutablesdialog.cpp index fe548a9a..3cc749d6 100644 --- a/src/editexecutablesdialog.cpp +++ b/src/editexecutablesdialog.cpp @@ -53,9 +53,7 @@ ExecutablesList EditExecutablesDialog::getExecutablesList() const void EditExecutablesDialog::refreshExecutablesWidget() { - QListWidget *executablesWidget = findChild("executablesListBox"); - - executablesWidget->clear(); + ui->executablesListBox->clear(); std::vector::const_iterator current, end; m_ExecutablesList.getExecutables(current, end); @@ -65,7 +63,7 @@ void EditExecutablesDialog::refreshExecutablesWidget() temp.setValue(*current); newItem->setData(Qt::UserRole, temp); newItem->setTextColor(current->m_Custom ? QColor(Qt::black) : QColor(Qt::darkGray)); - executablesWidget->addItem(newItem); + ui->executablesListBox->addItem(newItem); } ui->addButton->setEnabled(false); @@ -96,7 +94,8 @@ void EditExecutablesDialog::saveExecutable() { m_ExecutablesList.addExecutable(ui->titleEdit->text(), QDir::fromNativeSeparators(ui->binaryEdit->text()), ui->argumentsEdit->text(), QDir::fromNativeSeparators(ui->workingDirEdit->text()), - (ui->closeCheckBox->checkState() == Qt::Checked) ? DEFAULT_CLOSE : DEFAULT_STAY, + (ui->closeCheckBox->checkState() == Qt::Checked) ? ExecutableInfo::CloseMOStyle::DEFAULT_CLOSE + : ExecutableInfo::CloseMOStyle::DEFAULT_STAY, ui->overwriteAppIDBox->isChecked() ? ui->appIDOverwriteEdit->text() : "", true, false); } @@ -212,14 +211,14 @@ bool EditExecutablesDialog::executableChanged() || selectedExecutable.m_SteamAppID != ui->appIDOverwriteEdit->text() || selectedExecutable.m_WorkingDirectory != QDir::fromNativeSeparators(ui->workingDirEdit->text()) || selectedExecutable.m_BinaryInfo.absoluteFilePath() != QDir::fromNativeSeparators(ui->binaryEdit->text()) - || (selectedExecutable.m_CloseMO == DEFAULT_CLOSE) != ui->closeCheckBox->isChecked(); + || (selectedExecutable.m_CloseMO == ExecutableInfo::CloseMOStyle::DEFAULT_CLOSE) != ui->closeCheckBox->isChecked(); } else { return false; } } -void EditExecutablesDialog::on_executablesListBox_currentItemChanged(QListWidgetItem *current, QListWidgetItem*) +void EditExecutablesDialog::on_executablesListBox_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous) { if (current == NULL) { resetInput(); @@ -249,8 +248,8 @@ void EditExecutablesDialog::on_executablesListBox_currentItemChanged(QListWidget ui->binaryEdit->setText(QDir::toNativeSeparators(selectedExecutable.m_BinaryInfo.absoluteFilePath())); ui->argumentsEdit->setText(selectedExecutable.m_Arguments); ui->workingDirEdit->setText(QDir::toNativeSeparators(selectedExecutable.m_WorkingDirectory)); - ui->closeCheckBox->setChecked(selectedExecutable.m_CloseMO == DEFAULT_CLOSE); - if (selectedExecutable.m_CloseMO == NEVER_CLOSE) { + ui->closeCheckBox->setChecked(selectedExecutable.m_CloseMO == ExecutableInfo::CloseMOStyle::DEFAULT_CLOSE); + if (selectedExecutable.m_CloseMO == ExecutableInfo::CloseMOStyle::NEVER_CLOSE) { ui->closeCheckBox->setEnabled(false); ui->closeCheckBox->setToolTip(tr("MO must be kept running or this application will not work correctly.")); } else { @@ -286,4 +285,3 @@ void EditExecutablesDialog::on_closeButton_clicked() } this->accept(); } - diff --git a/src/editexecutablesdialog.ui b/src/editexecutablesdialog.ui index 4f0462db..8e70c1c0 100644 --- a/src/editexecutablesdialog.ui +++ b/src/editexecutablesdialog.ui @@ -28,6 +28,9 @@ Qt::MoveAction + + QAbstractItemView::SingleSelection + diff --git a/src/executableslist.cpp b/src/executableslist.cpp index 2c6754d7..11158c5b 100644 --- a/src/executableslist.cpp +++ b/src/executableslist.cpp @@ -31,8 +31,14 @@ using namespace MOShared; QDataStream &operator<<(QDataStream &out, const Executable &obj) { - out << obj.m_Title << obj.m_BinaryInfo.absoluteFilePath() << obj.m_Arguments << obj.m_CloseMO - << obj.m_SteamAppID << obj.m_WorkingDirectory << obj.m_Custom << obj.m_Toolbar; + out << obj.m_Title + << obj.m_BinaryInfo.absoluteFilePath() + << obj.m_Arguments + << static_cast::type>(obj.m_CloseMO) + << obj.m_SteamAppID + << obj.m_WorkingDirectory + << obj.m_Custom + << obj.m_Toolbar; return out; } @@ -43,7 +49,7 @@ QDataStream &operator>>(QDataStream &in, Executable &obj) in >> obj.m_Title >> binaryTemp >> obj.m_Arguments >> closeStyleTemp >> obj.m_SteamAppID >> obj.m_WorkingDirectory >> obj.m_Custom >> obj.m_Toolbar; - obj.m_CloseMO = (CloseMOStyle)closeStyleTemp; + obj.m_CloseMO = static_cast(closeStyleTemp); obj.m_BinaryInfo.setFile(binaryTemp); return in; } @@ -64,14 +70,16 @@ ExecutablesList::~ExecutablesList() { } -void ExecutablesList::init() +void ExecutablesList::init(IPluginGame *game) { - std::vector executables = GameInfo::instance().getExecutables(); - for (std::vector::const_iterator iter = executables.begin(); iter != executables.end(); ++iter) { - addExecutableInternal(ToQString(iter->title), - QDir::fromNativeSeparators(ToQString(GameInfo::instance().getGameDirectory())).append("/").append(ToQString(iter->binary)), - ToQString(iter->arguments), ToQString(iter->workingDirectory), - iter->closeMO, ToQString(iter->steamAppID)); + m_Executables.clear(); + for (const ExecutableInfo &info : game->executables()) { + addExecutableInternal(info.title(), + info.binary().absoluteFilePath(), + info.arguments().join(" "), + info.workingDirectory().absolutePath(), + info.closeMO(), + info.steamAppID()); } } @@ -143,7 +151,7 @@ void ExecutablesList::addExecutable(const Executable &executable) void ExecutablesList::addExecutable(const QString &title, const QString &executableName, const QString &arguments, - const QString &workingDirectory, CloseMOStyle closeMO, const QString &steamAppID, + const QString &workingDirectory, ExecutableInfo::CloseMOStyle closeMO, const QString &steamAppID, bool custom, bool toolbar) { QFileInfo file(executableName); @@ -185,7 +193,7 @@ void ExecutablesList::remove(const QString &title) void ExecutablesList::addExecutableInternal(const QString &title, const QString &executableName, const QString &arguments, const QString &workingDirectory, - CloseMOStyle closeMO, const QString &steamAppID) + ExecutableInfo::CloseMOStyle closeMO, const QString &steamAppID) { QFileInfo file(executableName); if (file.exists()) { diff --git a/src/executableslist.h b/src/executableslist.h index 6f7771e5..207190c4 100644 --- a/src/executableslist.h +++ b/src/executableslist.h @@ -25,6 +25,7 @@ along with Mod Organizer. If not, see . #include #include #include +#include /*! @@ -34,7 +35,7 @@ struct Executable { QString m_Title; QFileInfo m_BinaryInfo; QString m_Arguments; - MOShared::CloseMOStyle m_CloseMO; + MOBase::ExecutableInfo::CloseMOStyle m_CloseMO; QString m_SteamAppID; QString m_WorkingDirectory; @@ -64,7 +65,7 @@ public: /** * @brief initialise the list with the executables preconfigured for this game **/ - void init(); + void init(MOBase::IPluginGame *game); /** * @brief retrieve an executable by index @@ -114,7 +115,9 @@ public: * @param arguments arguments to pass to the executable * @param closeMO if true, MO will be closed when the binary is started **/ - void addExecutable(const QString &title, const QString &executableName, const QString &arguments, const QString &workingDirectory, MOShared::CloseMOStyle closeMO, const QString &steamAppID, bool custom, bool toolbar); + void addExecutable(const QString &title, const QString &executableName, const QString &arguments, + const QString &workingDirectory, MOBase::ExecutableInfo::CloseMOStyle closeMO, + const QString &steamAppID, bool custom, bool toolbar); /** * @brief remove the executable with the specified file name. This needs to be an absolute file path @@ -144,7 +147,9 @@ private: Executable *findExe(const QString &title); - void addExecutableInternal(const QString &title, const QString &executableName, const QString &arguments, const QString &workingDirectory, MOShared::CloseMOStyle closeMO, const QString &steamAppID); + void addExecutableInternal(const QString &title, const QString &executableName, const QString &arguments, + const QString &workingDirectory, MOBase::ExecutableInfo::CloseMOStyle closeMO, + const QString &steamAppID); private: diff --git a/src/installationmanager.cpp b/src/installationmanager.cpp index d6435e57..0fb1b78d 100644 --- a/src/installationmanager.cpp +++ b/src/installationmanager.cpp @@ -67,9 +67,8 @@ template T resolveFunction(QLibrary &lib, const char *name) } -InstallationManager::InstallationManager(QWidget *parent) - : QObject(parent), m_ParentWidget(parent), - m_InstallationProgress(parent), m_SupportedExtensions(boost::assign::list_of("zip")("rar")("7z")("fomod")("001")) +InstallationManager::InstallationManager() + : m_InstallationProgress(nullptr), m_SupportedExtensions(boost::assign::list_of("zip")("rar")("7z")("fomod")("001")) { QLibrary archiveLib("dlls\\archive.dll"); if (!archiveLib.load()) { @@ -92,6 +91,14 @@ InstallationManager::~InstallationManager() delete m_CurrentArchive; } +void InstallationManager::setParentWidget(QWidget *widget) +{ + m_InstallationProgress.setParent(widget); + for (IPluginInstaller *installer : m_Installers) { + installer->setParentWidget(widget); + } +} + void InstallationManager::queryPassword(LPSTR password) { diff --git a/src/installationmanager.h b/src/installationmanager.h index 336c1ce3..cd20f0dd 100644 --- a/src/installationmanager.h +++ b/src/installationmanager.h @@ -53,10 +53,12 @@ public: * * @param parent parent object. **/ - explicit InstallationManager(QWidget *parent); + explicit InstallationManager(); virtual ~InstallationManager(); + void setParentWidget(QWidget *widget); + /** * @brief update the directory where mods are to be installed * @param modsDirectory the mod directory diff --git a/src/iuserinterface.h b/src/iuserinterface.h new file mode 100644 index 00000000..76d4c75a --- /dev/null +++ b/src/iuserinterface.h @@ -0,0 +1,39 @@ +#ifndef IUSERINTERFACE_H +#define IUSERINTERFACE_H + + +#include "modinfo.h" +#include +#include + + +class IUserInterface +{ +public: + + void storeSettings(QSettings &settings); + + virtual HANDLE startApplication(const QString &executable, const QStringList &args = QStringList(), const QString &cwd = "", const QString &profile = "") = 0; + + virtual bool waitForProcessOrJob(HANDLE processHandle, LPDWORD exitCode = NULL) = 0; + + virtual void registerPluginTool(MOBase::IPluginTool *tool) = 0; + virtual void registerModPage(MOBase::IPluginModPage *modPage) = 0; + + virtual void installTranslator(const QString &name) = 0; + + virtual void disconnectPlugins() = 0; + + virtual bool close() = 0; + + virtual void setEnabled(bool enabled) = 0; + + virtual void displayModInformation(ModInfo::Ptr modInfo, unsigned int index, int tab) = 0; + + virtual void updateBSAList(const QStringList &defaultArchives, const QStringList &activeArchives) = 0; + + virtual bool saveArchiveList() = 0; + +}; + +#endif // IUSERINTERFACE_H diff --git a/src/main.cpp b/src/main.cpp index b4139f09..f292eac7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -42,6 +42,7 @@ along with Mod Organizer. If not, see . #include #include #include +#include #include #include "mainwindow.h" #include "report.h" @@ -398,6 +399,11 @@ int main(int argc, char *argv[]) QSettings settings(dataPath + "/ModOrganizer.ini", QSettings::IniFormat); + OrganizerCore organizer(settings); + + PluginContainer pluginContainer(&organizer); + pluginContainer.loadPlugins(); + QString gamePath = QString::fromUtf8(settings.value("gamePath", "").toByteArray()); bool done = false; @@ -473,9 +479,7 @@ int main(int argc, char *argv[]) #pragma message("edition isn't used?") qDebug("managing game at %s", qPrintable(QDir::toNativeSeparators(gamePath))); - ExecutablesList executablesList; - - executablesList.init(); + organizer.updateExecutablesList(settings); if (!bootstrap()) { // requires gameinfo to be initialised! return -1; @@ -483,24 +487,6 @@ int main(int argc, char *argv[]) cleanupDir(); - qDebug("setting up configured executables"); - - int numCustomExecutables = settings.beginReadArray("customExecutables"); - for (int i = 0; i < numCustomExecutables; ++i) { - settings.setArrayIndex(i); - CloseMOStyle closeMO = settings.value("closeOnStart").toBool() ? DEFAULT_CLOSE : DEFAULT_STAY; - executablesList.addExecutable(settings.value("title").toString(), - settings.value("binary").toString(), - settings.value("arguments").toString(), - settings.value("workingDirectory", "").toString(), - closeMO, - settings.value("steamAppID", "").toString(), - settings.value("custom", true).toBool(), - settings.value("toolbar", false).toBool()); - } - - settings.endArray(); - qDebug("initializing tutorials"); TutorialManager::init(QDir::fromNativeSeparators(ToQString(GameInfo::instance().getTutorialDir())).append("/")); @@ -512,11 +498,11 @@ int main(int argc, char *argv[]) int res = 1; { // scope to control lifetime of mainwindow // set up main window and its data structures - MainWindow mainWindow(argv[0], settings); + MainWindow mainWindow(argv[0], settings, organizer, pluginContainer); + QObject::connect(&mainWindow, SIGNAL(styleChanged(QString)), &application, SLOT(setStyleFile(QString))); - QObject::connect(&instance, SIGNAL(messageSent(QString)), &mainWindow, SLOT(externalMessage(QString))); + QObject::connect(&instance, SIGNAL(messageSent(QString)), &organizer, SLOT(externalMessage(QString))); - mainWindow.setExecutablesList(executablesList); mainWindow.readSettings(); QString selectedProfileName = QString::fromUtf8(settings.value("selected_profile", "").toByteArray()); @@ -571,7 +557,7 @@ int main(int argc, char *argv[]) if ((arguments.size() > 1) && (isNxmLink(arguments.at(1)))) { qDebug("starting download from command line: %s", qPrintable(arguments.at(1))); - mainWindow.externalMessage(arguments.at(1)); + organizer.externalMessage(arguments.at(1)); } splash.finish(&mainWindow); res = application.exec(); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 024e2510..4762358e 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -16,10 +16,10 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Mod Organizer. If not, see . */ +#ifndef Q_MOC_RUN #include "mainwindow.h" #include "ui_mainwindow.h" -#include #include "spawn.h" #include "report.h" #include "modlist.h" @@ -61,14 +61,16 @@ along with Mod Organizer. If not, see . #include "aboutdialog.h" #include "safewritefile.h" #include "organizerproxy.h" +#include #include #include #include #include #include +#include +#endif // Q_MOC_RUN #include #include -#include #include #include #include @@ -123,6 +125,7 @@ along with Mod Organizer. If not, see . #include #endif #include +#include #ifdef TEST_MODELS #include "modeltest.h" @@ -136,46 +139,28 @@ using namespace MOShared; -static bool isOnline() -{ - QList interfaces = QNetworkInterface::allInterfaces(); - - bool connected = false; - for (auto iter = interfaces.begin(); iter != interfaces.end() && !connected; ++iter) { - if ( (iter->flags() & QNetworkInterface::IsUp) && - (iter->flags() & QNetworkInterface::IsRunning) && - !(iter->flags() & QNetworkInterface::IsLoopBack)) { - auto addresses = iter->addressEntries(); - if (addresses.count() == 0) { - continue; - } - qDebug("interface %s seems to be up (address: %s)", - qPrintable(iter->humanReadableName()), - qPrintable(addresses[0].ip().toString())); - connected = true; - } - } - - return connected; -} - - -MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget *parent) - : QMainWindow(parent), ui(new Ui::MainWindow), m_Tutorial(this, "MainWindow"), - m_ExeName(exeName), m_OldProfileIndex(-1), - m_DirectoryStructure(new DirectoryEntry(L"data", NULL, 0)), - m_ModList(this), m_ModListGroupingProxy(NULL), m_ModListSortProxy(NULL), - m_PluginList(this), m_OldExecutableIndex(-1), m_GamePath(ToQString(GameInfo::instance().getGameDirectory())), - m_DownloadManager(NexusInterface::instance(), this), m_InstallationManager(this), - m_Updater(NexusInterface::instance(), this), m_CategoryFactory(CategoryFactory::instance()), - m_CurrentProfile(NULL), m_AskForNexusPW(false), - m_ArchivesInit(false), m_DirectoryUpdate(false), m_ContextItem(NULL), m_ContextAction(NULL), m_CurrentSaveView(NULL), - m_GameInfo(new GameInfoImpl()), m_AboutToRun(), m_ModInstalled(), m_DidUpdateMasterList(false) +MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, OrganizerCore &organizerCore, PluginContainer &pluginContainer, QWidget *parent) + : QMainWindow(parent) + , ui(new Ui::MainWindow) + , m_Tutorial(this, "MainWindow") + , m_ExeName(exeName) + , m_OldProfileIndex(-1) + , m_ModListGroupingProxy(nullptr) + , m_ModListSortProxy(nullptr) + , m_OldExecutableIndex(-1) + , m_GamePath(ToQString(GameInfo::instance().getGameDirectory())) + , m_CategoryFactory(CategoryFactory::instance()) + , m_ContextItem(nullptr) + , m_ContextAction(nullptr) + , m_CurrentSaveView(nullptr) + , m_OrganizerCore(organizerCore) + , m_PluginContainer(pluginContainer) + , m_DidUpdateMasterList(false) { ui->setupUi(this); - this->setWindowTitle(ToQString(GameInfo::instance().getGameName()) + " Mod Organizer v" + m_Updater.getVersion().displayString()); + this->setWindowTitle(ToQString(GameInfo::instance().getGameName()) + " Mod Organizer v" + m_OrganizerCore.getVersion().displayString()); - languageChange(m_Settings.language()); + languageChange(m_OrganizerCore.settings().language()); ui->logList->setModel(LogBuffer::instance()); ui->logList->setColumnWidth(0, 100); @@ -202,16 +187,8 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget updateToolBar(); - ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure, m_Settings.displayForeign()); - // set up mod list - m_ModListSortProxy = new ModListSortProxy(m_CurrentProfile, this); - m_ModListSortProxy->setSourceModel(&m_ModList); - -#ifdef TEST_MODELS - new ModelTest(&m_ModList, this); - new ModelTest(m_ModListSortProxy, this); -#endif //TEST_MODELS + m_ModListSortProxy = m_OrganizerCore.createModListProxyModel(); ui->modList->setModel(m_ModListSortProxy); @@ -221,7 +198,7 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget ui->modList->setItemDelegateForColumn(ModList::COL_FLAGS, new ModFlagIconDelegate(ui->modList)); ui->modList->setItemDelegateForColumn(ModList::COL_CONTENT, contentDelegate); //ui->modList->setAcceptDrops(true); - ui->modList->header()->installEventFilter(&m_ModList); + ui->modList->header()->installEventFilter(m_OrganizerCore.modList()); if (initSettings.contains("mod_list_state")) { ui->modList->header()->restoreState(initSettings.value("mod_list_state").toByteArray()); @@ -236,11 +213,10 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget } ui->modList->header()->setSectionHidden(ModList::COL_NAME, false); // prevent the name-column from being hidden - ui->modList->installEventFilter(&m_ModList); + ui->modList->installEventFilter(m_OrganizerCore.modList()); // set up plugin list - m_PluginListSortProxy = new PluginListSortProxy(this); - m_PluginListSortProxy->setSourceModel(&m_PluginList); + m_PluginListSortProxy = m_OrganizerCore.createPluginListProxyModel(); ui->espList->setModel(m_PluginListSortProxy); ui->espList->sortByColumn(PluginList::COL_PRIORITY, Qt::AscendingOrder); @@ -248,7 +224,7 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget if (initSettings.contains("plugin_list_state")) { ui->espList->header()->restoreState(initSettings.value("plugin_list_state").toByteArray()); } - ui->espList->installEventFilter(&m_PluginList); + ui->espList->installEventFilter(m_OrganizerCore.pluginList()); ui->bsaList->setLocalMoveOnly(true); @@ -265,70 +241,50 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget ui->listOptionsBtn->setMenu(modListContextMenu()); - m_DownloadManager.setOutputDirectory(m_Settings.getDownloadDirectory()); - m_DownloadManager.setPreferredServers(m_Settings.getPreferredServers()); - - NexusInterface::instance()->setCacheDirectory(m_Settings.getCacheDirectory()); - NexusInterface::instance()->setNMMVersion(m_Settings.getNMMVersion()); - - m_InstallationManager.setModsDirectory(m_Settings.getModDirectory()); - m_InstallationManager.setDownloadDirectory(m_Settings.getDownloadDirectory()); - updateDownloadListDelegate(); ui->savegameList->installEventFilter(this); ui->savegameList->setMouseTracking(true); - connect(&m_DownloadManager, SIGNAL(showMessage(QString)), this, SLOT(showMessage(QString))); - connect(&m_DownloadManager, SIGNAL(downloadSpeed(QString,int)), this, SLOT(downloadSpeed(QString,int))); - connect(&m_DownloadManager, SIGNAL(downloadAdded()), ui->downloadView, SLOT(scrollToBottom())); connect(ui->savegameList, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(saveSelectionChanged(QListWidgetItem*))); - connect(&m_ModList, SIGNAL(modorder_changed()), this, SLOT(modorder_changed())); - connect(&m_ModList, SIGNAL(removeOrigin(QString)), this, SLOT(removeOrigin(QString))); - connect(&m_ModList, SIGNAL(showMessage(QString)), this, SLOT(showMessage(QString))); - connect(&m_ModList, SIGNAL(modRenamed(QString,QString)), this, SLOT(modRenamed(QString,QString))); - connect(&m_ModList, SIGNAL(modUninstalled(QString)), this, SLOT(modRemoved(QString))); - connect(&m_ModList, SIGNAL(modlist_changed(QModelIndex, int)), this, SLOT(modlistChanged(QModelIndex, int))); - connect(&m_ModList, SIGNAL(removeSelectedMods()), this, SLOT(removeMod_clicked())); - connect(&m_ModList, SIGNAL(requestColumnSelect(QPoint)), this, SLOT(displayColumnSelection(QPoint))); - connect(&m_ModList, SIGNAL(fileMoved(QString, QString, QString)), this, SLOT(fileMoved(QString, QString, QString))); - connect(ui->modList, SIGNAL(dropModeUpdate(bool)), &m_ModList, SLOT(dropModeUpdate(bool))); + connect(ui->modList, SIGNAL(dropModeUpdate(bool)), m_OrganizerCore.modList(), SLOT(dropModeUpdate(bool))); connect(ui->modList->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(modlistSelectionChanged(QModelIndex,QModelIndex))); connect(m_ModListSortProxy, SIGNAL(filterActive(bool)), this, SLOT(modFilterActive(bool))); connect(ui->modFilterEdit, SIGNAL(textChanged(QString)), m_ModListSortProxy, SLOT(updateFilter(QString))); connect(ui->espFilterEdit, SIGNAL(textChanged(QString)), m_PluginListSortProxy, SLOT(updateFilter(QString))); connect(ui->espFilterEdit, SIGNAL(textChanged(QString)), this, SLOT(espFilterChanged(QString))); - connect(&m_PluginList, SIGNAL(saveTimer()), this, SLOT(savePluginList())); + connect(m_OrganizerCore.pluginList(), SIGNAL(saveTimer()), this, SLOT(savePluginList())); connect(ui->bsaList, SIGNAL(itemsMoved()), this, SLOT(bsaList_itemMoved())); connect(ui->dataTree, SIGNAL(itemExpanded(QTreeWidgetItem*)), this, SLOT(expandDataTreeItem(QTreeWidgetItem*))); - connect(&m_DirectoryRefresher, SIGNAL(refreshed()), this, SLOT(directory_refreshed())); - connect(&m_DirectoryRefresher, SIGNAL(progress(int)), this, SLOT(refresher_progress(int))); - connect(&m_DirectoryRefresher, SIGNAL(error(QString)), this, SLOT(showError(QString))); + connect(m_OrganizerCore.directoryRefresher(), SIGNAL(refreshed()), this, SLOT(directory_refreshed())); + connect(m_OrganizerCore.directoryRefresher(), SIGNAL(progress(int)), this, SLOT(refresher_progress(int))); + connect(m_OrganizerCore.directoryRefresher(), SIGNAL(error(QString)), this, SLOT(showError(QString))); connect(&m_SavesWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(refreshSavesIfOpen())); - connect(&m_Settings, SIGNAL(languageChanged(QString)), this, SLOT(languageChange(QString))); - connect(&m_Settings, SIGNAL(styleChanged(QString)), this, SIGNAL(styleChanged(QString))); + connect(&m_OrganizerCore.settings(), SIGNAL(languageChanged(QString)), this, SLOT(languageChange(QString))); + connect(&m_OrganizerCore.settings(), SIGNAL(styleChanged(QString)), this, SIGNAL(styleChanged(QString))); - connect(&m_Updater, SIGNAL(restart()), this, SLOT(close())); - connect(&m_Updater, SIGNAL(updateAvailable()), this, SLOT(updateAvailable())); - connect(&m_Updater, SIGNAL(motdAvailable(QString)), this, SLOT(motdReceived(QString))); + connect(m_OrganizerCore.updater(), SIGNAL(restart()), this, SLOT(close())); + connect(m_OrganizerCore.updater(), SIGNAL(updateAvailable()), this, SLOT(updateAvailable())); + connect(m_OrganizerCore.updater(), SIGNAL(motdAvailable(QString)), this, SLOT(motdReceived(QString))); - connect(NexusInterface::instance()->getAccessManager(), SIGNAL(loginSuccessful(bool)), this, SLOT(loginSuccessful(bool))); - connect(NexusInterface::instance()->getAccessManager(), SIGNAL(loginFailed(QString)), this, SLOT(loginFailed(QString))); connect(NexusInterface::instance(), SIGNAL(requestNXMDownload(QString)), this, SLOT(downloadRequestedNXM(QString))); connect(NexusInterface::instance(), SIGNAL(nxmDownloadURLsAvailable(int,int,QVariant,QVariant,int)), this, SLOT(nxmDownloadURLs(int,int,QVariant,QVariant,int))); connect(NexusInterface::instance(), SIGNAL(needLogin()), this, SLOT(nexusLogin())); + connect(NexusInterface::instance()->getAccessManager(), SIGNAL(loginFailed(QString)), this, SLOT(loginFailed(QString))); connect(&TutorialManager::instance(), SIGNAL(windowTutorialFinished(QString)), this, SLOT(windowTutorialFinished(QString))); connect(ui->modList->header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), this, SLOT(modListSortIndicatorChanged(int,Qt::SortOrder))); connect(ui->toolBar, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(toolBar_customContextMenuRequested(QPoint))); + connect(&m_OrganizerCore, &OrganizerCore::modInstalled, this, &MainWindow::modInstalled); + connect(&m_IntegratedBrowser, SIGNAL(requestDownload(QUrl,QNetworkReply*)), this, SLOT(requestDownload(QUrl,QNetworkReply*))); connect(this, SIGNAL(styleChanged(QString)), this, SLOT(updateStyle(QString))); @@ -343,42 +299,44 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget connect(&m_SaveMetaTimer, SIGNAL(timeout()), this, SLOT(saveModMetas())); m_SaveMetaTimer.start(5000); - m_DirectoryRefresher.moveToThread(&m_RefresherThread); - m_RefresherThread.start(); - - m_AskForNexusPW = initSettings.value("ask_for_nexuspw", true).toBool(); setCategoryListVisible(initSettings.value("categorylist_visible", true).toBool()); FileDialogMemory::restore(initSettings); fixCategories(); - if (isOnline() && !m_Settings.offlineMode()) { - m_Updater.testForUpdate(); - } else { - qDebug("user doesn't seem to be connected to the internet"); - } - m_StartTime = QTime::currentTime(); - m_Tutorial.expose("modList", &m_ModList); - m_Tutorial.expose("espList", &m_PluginList); + m_Tutorial.expose("modList", m_OrganizerCore.modList()); + m_Tutorial.expose("espList", m_OrganizerCore.pluginList()); // before we start loading plugins we, add the dll path to the dll search order ::SetDllDirectoryW(ToWString(QDir::toNativeSeparators(qApp->applicationDirPath() + "/dlls")).c_str()); - loadPlugins(); + + m_OrganizerCore.setUserInterface(this, this); + + for (const QString &fileName : m_PluginContainer.pluginFileNames()) { + installTranslator(QFileInfo(fileName).baseName()); + } + + refreshExecutablesList(); + updateToolBar(); } MainWindow::~MainWindow() { - m_AboutToRun.disconnect_all_slots(); - m_ModInstalled.disconnect_all_slots(); - m_RefresherThread.exit(); - m_RefresherThread.wait(); + m_PluginContainer.setUserInterface(nullptr, nullptr); + m_OrganizerCore.setUserInterface(nullptr, nullptr); m_IntegratedBrowser.close(); delete ui; - delete m_GameInfo; - delete m_DirectoryStructure; +} + + +void MainWindow::disconnectPlugins() +{ + if (ui->actionTool->menu() != NULL) { + ui->actionTool->menu()->clear(); + } } @@ -537,7 +495,7 @@ void MainWindow::updateToolBar() ui->toolBar->insertWidget(action, spacer); std::vector::iterator begin, end; - m_ExecutablesList.getExecutables(begin, end); + m_OrganizerCore.executablesList()->getExecutables(begin, end); for (auto iter = begin; iter != end; ++iter) { if (iter->m_Toolbar) { QAction *exeAction = new QAction(iconForExecutable(iter->m_BinaryInfo.filePath()), @@ -623,7 +581,7 @@ bool MainWindow::errorReported(QString &logFile) int MainWindow::checkForProblems() { int numProblems = 0; - foreach (IPluginDiagnose *diagnose, m_DiagnosisPlugins) { + for (IPluginDiagnose *diagnose : m_PluginContainer.plugins()) { numProblems += diagnose->activeProblems().size(); } return numProblems; @@ -631,7 +589,7 @@ int MainWindow::checkForProblems() void MainWindow::about() { - AboutDialog dialog(m_Updater.getVersion().displayString(), this); + AboutDialog dialog(m_OrganizerCore.getVersion().displayString(), this); dialog.exec(); } @@ -701,47 +659,10 @@ void MainWindow::createHelpWidget() } -bool MainWindow::saveArchiveList() -{ - if (m_ArchivesInit) { - SafeWriteFile archiveFile(m_CurrentProfile->getArchivesFileName()); - for (int i = 0; i < ui->bsaList->topLevelItemCount(); ++i) { - QTreeWidgetItem *tlItem = ui->bsaList->topLevelItem(i); - for (int j = 0; j < tlItem->childCount(); ++j) { - QTreeWidgetItem *item = tlItem->child(j); - if (item->checkState(0) == Qt::Checked) { - // in managed mode, "register" all enabled archives, otherwise register only the files registered in the ini - if (ui->manageArchivesBox->isChecked() - || item->data(0, Qt::UserRole).toBool()) { - archiveFile->write(item->text(0).toUtf8().append("\r\n")); - } - } - } - } - if (archiveFile.commitIfDifferent(m_ArchiveListHash)) { - qDebug("%s saved", qPrintable(QDir::toNativeSeparators(m_CurrentProfile->getArchivesFileName()))); - return true; - } - } else { - qWarning("archive list not initialised"); - } - return false; -} - -void MainWindow::savePluginList() -{ - m_PluginList.saveTo(m_CurrentProfile->getPluginsFileName(), - m_CurrentProfile->getLoadOrderFileName(), - m_CurrentProfile->getLockedOrderFileName(), - m_CurrentProfile->getDeleterFileName(), - m_Settings.hideUncheckedPlugins()); - m_PluginList.saveLoadOrder(*m_DirectoryStructure); -} - void MainWindow::modFilterActive(bool filterActive) { if (filterActive) { - m_ModList.setOverwriteMarkers(std::set(), std::set()); + m_OrganizerCore.modList()->setOverwriteMarkers(std::set(), std::set()); ui->modList->setStyleSheet("QTreeView { border: 2px ridge #f00; }"); } else if (ui->groupCombo->currentIndex() != 0) { ui->modList->setStyleSheet("QTreeView { border: 2px ridge #337733; }"); @@ -781,22 +702,6 @@ void MainWindow::expandModList(const QModelIndex &index) } } -bool MainWindow::saveCurrentLists() -{ - if (m_DirectoryUpdate) { - qWarning("not saving lists during directory update"); - return false; - } - - try { - savePluginList(); - saveArchiveList(); - } catch (const std::exception &e) { - reportError(tr("failed to save load order: %1").arg(e.what())); - } - - return true; -} bool MainWindow::addProfile() { @@ -834,7 +739,7 @@ void MainWindow::hookUpWindowTutorials() QString firstLine = QString::fromUtf8(file.readLine()); if (firstLine.startsWith("//WIN")) { QString windowName = firstLine.mid(6).trimmed(); - if (!m_Settings.directInterface().value("CompletedWindowTutorials/" + windowName, false).toBool()) { + if (!m_OrganizerCore.settings().directInterface().value("CompletedWindowTutorials/" + windowName, false).toBool()) { TutorialManager::instance().activateTutorial(windowName, fileName); } } @@ -850,7 +755,7 @@ void MainWindow::showEvent(QShowEvent *event) hookUpWindowTutorials(); - if (m_Settings.directInterface().value("first_start", true).toBool()) { + if (m_OrganizerCore.settings().directInterface().value("first_start", true).toBool()) { QString firstStepsTutorial = ToQString(AppConfig::firstStepsTutorial()); if (TutorialManager::instance().hasTutorial(firstStepsTutorial)) { if (QMessageBox::question(this, tr("Show tutorial?"), @@ -869,48 +774,35 @@ void MainWindow::showEvent(QShowEvent *event) QObject::tr("Please use \"Help\" from the toolbar to get usage instructions to all elements")); } - m_Settings.directInterface().setValue("first_start", false); + m_OrganizerCore.settings().directInterface().setValue("first_start", false); } // this has no visible impact when called before the ui is visible - int grouping = m_Settings.directInterface().value("group_state").toInt(); + int grouping = m_OrganizerCore.settings().directInterface().value("group_state").toInt(); ui->groupCombo->setCurrentIndex(grouping); allowListResize(); - m_Settings.registerAsNXMHandler(false); + m_OrganizerCore.settings().registerAsNXMHandler(false); } void MainWindow::closeEvent(QCloseEvent* event) { - if (m_DownloadManager.downloadsInProgress()) { + if (m_OrganizerCore.downloadManager()->downloadsInProgress()) { if (QMessageBox::question(this, tr("Downloads in progress"), tr("There are still downloads in progress, do you really want to quit?"), QMessageBox::Yes | QMessageBox::Cancel) == QMessageBox::Cancel) { event->ignore(); return; } else { - m_DownloadManager.pauseAll(); + m_OrganizerCore.downloadManager()->pauseAll(); } } setCursor(Qt::WaitCursor); m_IntegratedBrowser.close(); - - storeSettings(); - -// unloadPlugins(); - - // profile has to be cleaned up before the modinfo-buffer is cleared - delete m_CurrentProfile; - m_CurrentProfile = NULL; - - ModInfo::clear(); - LogBuffer::cleanQuit(); - m_ModList.setProfile(NULL); - NexusInterface::instance()->cleanup(); } @@ -952,7 +844,7 @@ SaveGameGamebryo *MainWindow::getSaveGame(QListWidgetItem *item) void MainWindow::displaySaveGameInfo(const SaveGameGamebryo *save, QPoint pos) { if (m_CurrentSaveView == NULL) { - m_CurrentSaveView = new SaveGameInfoWidgetGamebryo(save, &m_PluginList, this); + m_CurrentSaveView = new SaveGameInfoWidgetGamebryo(save, m_OrganizerCore.pluginList(), this); } else { m_CurrentSaveView->setSave(save); } @@ -1012,53 +904,6 @@ bool MainWindow::eventFilter(QObject *object, QEvent *event) } -bool MainWindow::testForSteam() -{ - DWORD processIDs[1024]; - DWORD bytesReturned; - if (!::EnumProcesses(processIDs, sizeof(processIDs), &bytesReturned)) { - qWarning("failed to determine if steam is running"); - return true; - } - - TCHAR processName[MAX_PATH]; - for (unsigned int i = 0; i < bytesReturned / sizeof(DWORD); ++i) { - memset(processName, '\0', sizeof(TCHAR) * MAX_PATH); - if (processIDs[i] != 0) { - HANDLE process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processIDs[i]); - - if (process != NULL) { - HMODULE module; - DWORD ignore; - - // first module in a process is always the binary - if (EnumProcessModules(process, &module, sizeof(HMODULE) * 1, &ignore)) { - GetModuleBaseName(process, module, processName, MAX_PATH); - if ((_tcsicmp(processName, TEXT("steam.exe")) == 0) || - (_tcsicmp(processName, TEXT("steamservice.exe")) == 0)) { - return true; - } - } - } - } - } - - return false; -} - - -bool MainWindow::verifyPlugin(IPlugin *plugin) -{ - if (plugin == NULL) { - return false; - } else if (!plugin->init(new OrganizerProxy(this, plugin->name()))) { - qWarning("plugin failed to initialize"); - return false; - } - return true; -} - - void MainWindow::toolPluginInvoke() { QAction *triggeredAction = qobject_cast(sender()); @@ -1073,55 +918,6 @@ void MainWindow::toolPluginInvoke() } -void MainWindow::requestDownload(const QUrl &url, QNetworkReply *reply) -{ - QToolButton *browserBtn = qobject_cast(ui->toolBar->widgetForAction(ui->actionNexus)); - if (browserBtn->menu() != NULL) { - // go through modpage plugins, find one to handle the download. - QList browserActions = browserBtn->menu()->actions(); - foreach (QAction *action, browserActions) { - // the nexus action doesn't have a plugin connected currently - if (action->data().isValid()) { - IPluginModPage *plugin = qobject_cast(qvariant_cast(action->data())); - if (plugin == NULL) { - qCritical("invalid mod page. This is a bug"); - continue; - } - ModRepositoryFileInfo *fileInfo = new ModRepositoryFileInfo(); - if (plugin->handlesDownload(url, reply->url(), *fileInfo)) { - fileInfo->repository = plugin->name(); - m_DownloadManager.addDownload(reply, fileInfo); - return; - } - } - } - } - - // no mod found that could handle the download. Is it a nexus mod? - if (url.host() == "www.nexusmods.com") { - int modID = 0; - int fileID = 0; - QRegExp modExp("mods/(\\d+)"); - if (modExp.indexIn(url.toString()) != -1) { - modID = modExp.cap(1).toInt(); - } - QRegExp fileExp("fid=(\\d+)"); - if (fileExp.indexIn(reply->url().toString()) != -1) { - fileID = fileExp.cap(1).toInt(); - } - m_DownloadManager.addDownload(reply, new ModRepositoryFileInfo(modID, fileID)); - } else { - if (QMessageBox::question(this, tr("Download?"), - tr("A download has been started but no installed page plugin recognizes it.\n" - "If you download anyway no information (i.e. version) will be associated with the download.\n" - "Continue?"), - QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { - m_DownloadManager.addDownload(reply, new ModRepositoryFileInfo()); - } - } -} - - void MainWindow::modPagePluginInvoke() { QAction *triggeredAction = qobject_cast(sender()); @@ -1134,6 +930,7 @@ void MainWindow::modPagePluginInvoke() } } + void MainWindow::registerPluginTool(IPluginTool *tool) { QAction *action = new QAction(tool->icon(), tool->displayName(), ui->toolBar); @@ -1171,366 +968,24 @@ void MainWindow::registerModPage(IPluginModPage *modPage) } -bool MainWindow::registerPlugin(QObject *plugin, const QString &fileName) -{ - { // generic treatment for all plugins - IPlugin *pluginObj = qobject_cast(plugin); - if (pluginObj == NULL) { - qDebug("not an IPlugin"); - return false; - } - plugin->setProperty("filename", fileName); - m_Settings.registerPlugin(pluginObj); - installTranslator(QFileInfo(fileName).baseName()); - } - - { // diagnosis plugins - IPluginDiagnose *diagnose = qobject_cast(plugin); - if (diagnose != NULL) { - m_DiagnosisPlugins.push_back(diagnose); - m_DiagnosisConnections.push_back( - diagnose->onInvalidated([&] () { this->scheduleUpdateButton(); }) - ); - } - } - { // mod page plugin - IPluginModPage *modPage = qobject_cast(plugin); - if (verifyPlugin(modPage)) { - registerModPage(modPage); - return true; - } - } - { // tool plugins - IPluginTool *tool = qobject_cast(plugin); - if (verifyPlugin(tool)) { - registerPluginTool(tool); - return true; - } - } - { // installer plugins - IPluginInstaller *installer = qobject_cast(plugin); - if (verifyPlugin(installer)) { - installer->setParentWidget(this); - m_InstallationManager.registerInstaller(installer); - return true; - } - } - { // preview plugins - IPluginPreview *preview = qobject_cast(plugin); - if (verifyPlugin(preview)) { - m_PreviewGenerator.registerPlugin(preview); - return true; - } - } - { // proxy plugins - IPluginProxy *proxy = qobject_cast(plugin); - if (verifyPlugin(proxy)) { - proxy->setParentWidget(this); - QStringList pluginNames = proxy->pluginList(QCoreApplication::applicationDirPath() + "/" + ToQString(AppConfig::pluginPath())); - foreach (const QString &pluginName, pluginNames) { - try { - QObject *proxiedPlugin = proxy->instantiate(pluginName); - if (proxiedPlugin != NULL) { - if (registerPlugin(proxiedPlugin, pluginName)) { - qDebug("loaded plugin \"%s\"", qPrintable(pluginName)); - } else { - qWarning("plugin \"%s\" failed to load", qPrintable(pluginName)); - } - } - } catch (const std::exception &e) { - reportError(tr("failed to init plugin %1: %2").arg(pluginName).arg(e.what())); - } - } - return true; - } - } - - { // dummy plugins - // only initialize these, no processing otherwise - IPlugin *dummy = qobject_cast(plugin); - if (verifyPlugin(dummy)) { - return true; - } - } - - qDebug("no matching plugin interface"); - - return false; -} - -void MainWindow::unloadPlugins() -{ - // disconnect all slots before unloading plugins so plugins don't have to take care of that - m_AboutToRun.disconnect_all_slots(); - m_ModInstalled.disconnect_all_slots(); - m_ModList.disconnectSlots(); - m_PluginList.disconnectSlots(); - - m_DiagnosisPlugins.clear(); - - foreach (const boost::signals2::connection &connection, m_DiagnosisConnections) { - connection.disconnect(); - } - m_DiagnosisConnections.clear(); - - m_Settings.clearPlugins(); - - if (ui->actionTool->menu() != NULL) { - ui->actionTool->menu()->clear(); - } - - while (!m_PluginLoaders.empty()) { - QPluginLoader *loader = m_PluginLoaders.back(); - m_PluginLoaders.pop_back(); - if (!loader->unload()) { - qDebug("failed to unload %s: %s", qPrintable(loader->fileName()), qPrintable(loader->errorString())); - } - delete loader; - } -} - -void MainWindow::loadPlugins() -{ - unloadPlugins(); - - foreach (QObject *plugin, QPluginLoader::staticInstances()) { - registerPlugin(plugin, ""); - } - - QFile loadCheck(qApp->property("dataPath").toString() + "/plugin_loadcheck.tmp"); - if (loadCheck.exists() && loadCheck.open(QIODevice::ReadOnly)) { - // oh, there was a failed plugin load last time. Find out which plugin was loaded last - QString fileName; - while (!loadCheck.atEnd()) { - fileName = QString::fromUtf8(loadCheck.readLine().constData()).trimmed(); - } - if (QMessageBox::question(this, tr("Plugin error"), - tr("It appears the plugin \"%1\" failed to load last startup and caused MO to crash. Do you want to disable it?\n" - "(Please note: If this is the first time you see this message for this plugin you may want to give it another try. " - "The plugin may be able to recover from the problem)").arg(fileName), - QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) == QMessageBox::Yes) { - m_Settings.addBlacklistPlugin(fileName); - } - loadCheck.close(); - } - - loadCheck.open(QIODevice::WriteOnly); - - QString pluginPath = QDir::fromNativeSeparators(ToQString(GameInfo::instance().getOrganizerDirectory())) + "/" + ToQString(AppConfig::pluginPath()); - qDebug("looking for plugins in %s", QDir::toNativeSeparators(pluginPath).toUtf8().constData()); - QDirIterator iter(pluginPath, QDir::Files | QDir::NoDotAndDotDot); - - while (iter.hasNext()) { - iter.next(); - if (m_Settings.pluginBlacklisted(iter.fileName())) { - qDebug("plugin \"%s\" blacklisted", qPrintable(iter.fileName())); - continue; - } - loadCheck.write(iter.fileName().toUtf8()); - loadCheck.write("\n"); - loadCheck.flush(); - QString pluginName = iter.filePath(); - if (QLibrary::isLibrary(pluginName)) { - QPluginLoader *pluginLoader = new QPluginLoader(pluginName, this); - if (pluginLoader->instance() == NULL) { - m_FailedPlugins.push_back(pluginName); - qCritical("failed to load plugin %s: %s", - qPrintable(pluginName), qPrintable(pluginLoader->errorString())); - } else { - if (registerPlugin(pluginLoader->instance(), pluginName)) { - qDebug("loaded plugin \"%s\"", qPrintable(pluginName)); - m_PluginLoaders.push_back(pluginLoader); - } else { - m_FailedPlugins.push_back(pluginName); - qWarning("plugin \"%s\" failed to load", qPrintable(pluginName)); - } - } - } - } - - // remove the load check file on success - loadCheck.remove(); - - m_DownloadManager.setSupportedExtensions(m_InstallationManager.getSupportedExtensions()); - - m_DiagnosisPlugins.push_back(this); -} - - -void MainWindow::startSteam() -{ - QSettings steamSettings("HKEY_CURRENT_USER\\Software\\Valve\\Steam", - QSettings::NativeFormat); - QString exe = steamSettings.value("SteamExe", "").toString(); - if (!exe.isEmpty()) { - QString temp = QString("\"%1\"").arg(exe); - if (!QProcess::startDetached(temp)) { - reportError(tr("Failed to start \"%1\"").arg(temp)); - } else { - QMessageBox::information(this, tr("Waiting"), tr("Please press OK once you're logged into steam.")); - } - } -} - - -HANDLE MainWindow::spawnBinaryDirect(const QFileInfo &binary, const QString &arguments, const QString &profileName, - const QDir ¤tDirectory, const QString &steamAppID) -{ - storeSettings(); - - if (!binary.exists()) { - reportError(tr("Executable \"%1\" not found").arg(binary.fileName())); - return INVALID_HANDLE_VALUE; - } - - if (!steamAppID.isEmpty()) { - ::SetEnvironmentVariableW(L"SteamAPPId", ToWString(steamAppID).c_str()); - } else { - ::SetEnvironmentVariableW(L"SteamAPPId", ToWString(m_Settings.getSteamAppID()).c_str()); - } - - if ((GameInfo::instance().requiresSteam()) && - (m_Settings.getLoadMechanism() == LoadMechanism::LOAD_MODORGANIZER)) { - if (!testForSteam()) { - if (QuestionBoxMemory::query(this->isVisible() ? this : NULL, - "steamQuery", tr("Start Steam?"), - tr("Steam is required to be running already to correctly start the game. " - "Should MO try to start steam now?"), - QDialogButtonBox::Yes | QDialogButtonBox::No) == QDialogButtonBox::Yes) { - startSteam(); - } - } - } - - while (m_DirectoryUpdate) { - ::Sleep(100); - QCoreApplication::processEvents(); - } - - // need to make sure all data is saved before we start the application - if (m_CurrentProfile != nullptr) { - m_CurrentProfile->writeModlistNow(true); - } - - // TODO: should also pass arguments - if (m_AboutToRun(binary.absoluteFilePath())) { - return startBinary(binary, arguments, profileName, m_Settings.logLevel(), currentDirectory, true); - } else { - qDebug("start of \"%s\" canceled by plugin", qPrintable(binary.absoluteFilePath())); - return INVALID_HANDLE_VALUE; - } -} - -std::wstring getProcessName(DWORD processId) -{ - HANDLE process = ::OpenProcess(PROCESS_QUERY_INFORMATION, false, processId); - - wchar_t buffer[MAX_PATH]; - if (::GetProcessImageFileNameW(process, buffer, MAX_PATH) != 0) { - wchar_t *fileName = wcsrchr(buffer, L'\\'); - if (fileName == nullptr) { - fileName = buffer; - } else { - fileName += 1; - } - return fileName; - } else { - return std::wstring(L"unknown"); - } -} - -void MainWindow::spawnBinary(const QFileInfo &binary, const QString &arguments, const QDir ¤tDirectory, bool closeAfterStart, const QString &steamAppID) -{ - LockedDialog *dialog = new LockedDialog(this); - dialog->show(); - ON_BLOCK_EXIT([&] () { dialog->hide(); dialog->deleteLater(); }); - - HANDLE processHandle = spawnBinaryDirect(binary, arguments, m_CurrentProfile->getName(), currentDirectory, steamAppID); - if (processHandle != INVALID_HANDLE_VALUE) { - if (closeAfterStart) { - close(); - } else { - this->setEnabled(false); - // re-enable the locked dialog because what'd be the point otherwise? - dialog->setEnabled(true); - - QCoreApplication::processEvents(); - - DWORD retLen; - JOBOBJECT_BASIC_PROCESS_ID_LIST info; - - { - DWORD currentProcess = 0UL; - bool isJobHandle = true; - - DWORD res = ::MsgWaitForMultipleObjects(1, &processHandle, false, 1000, QS_KEY | QS_MOUSE); - while ((res != WAIT_FAILED) && (res != WAIT_OBJECT_0) && !dialog->unlockClicked()) { - if (isJobHandle) { - if (::QueryInformationJobObject(processHandle, JobObjectBasicProcessIdList, &info, sizeof(info), &retLen) > 0) { - if (info.NumberOfProcessIdsInList == 0) { - break; - } else { - if (info.ProcessIdList[0] != currentProcess) { - currentProcess = info.ProcessIdList[0]; - dialog->setProcessName(ToQString(getProcessName(currentProcess))); - } - } - } else { - // the info-object I passed only provides space for 1 process id. but since this code only cares about whether there - // is more than one that's good enough. ERROR_MORE_DATA simply signals there are at least two processes running. - // any other error probably means the handle is a regular process handle, probably caused by running MO in a job without - // the right to break out. - if (::GetLastError() != ERROR_MORE_DATA) { - isJobHandle = false; - } - } - } - - // keep processing events so the app doesn't appear dead - QCoreApplication::processEvents(); - - res = ::MsgWaitForMultipleObjects(1, &processHandle, false, 1000, QS_KEY | QS_MOUSE); - } - } - ::CloseHandle(processHandle); - - this->setEnabled(true); - refreshDirectoryStructure(); - // need to remove our stored load order because it may be outdated if a foreign tool changed the - // file time. After removing that file, refreshESPList will use the file time as the order - if (GameInfo::instance().getLoadOrderMechanism() == GameInfo::TYPE_FILETIME) { - QFile::remove(m_CurrentProfile->getLoadOrderFileName()); - refreshESPList(); - } - } - } -} - - void MainWindow::startExeAction() { QAction *action = qobject_cast(sender()); if (action != NULL) { Executable selectedExecutable = action->data().value(); - spawnBinary(selectedExecutable.m_BinaryInfo, - selectedExecutable.m_Arguments, - selectedExecutable.m_WorkingDirectory.length() != 0 ? selectedExecutable.m_WorkingDirectory - : selectedExecutable.m_BinaryInfo.absolutePath(), - selectedExecutable.m_CloseMO == DEFAULT_CLOSE, - selectedExecutable.m_SteamAppID); + m_OrganizerCore.spawnBinary( + selectedExecutable.m_BinaryInfo, + selectedExecutable.m_Arguments, + selectedExecutable.m_WorkingDirectory.length() != 0 ? selectedExecutable.m_WorkingDirectory + : selectedExecutable.m_BinaryInfo.absolutePath(), + selectedExecutable.m_CloseMO == ExecutableInfo::CloseMOStyle::DEFAULT_CLOSE, + selectedExecutable.m_SteamAppID); } else { qCritical("not an action?"); } } -void MainWindow::setExecutablesList(const ExecutablesList &executablesList) -{ - m_ExecutablesList = executablesList; - refreshExecutablesList(); - updateToolBar(); -} - void MainWindow::setExecutableIndex(int index) { QComboBox *executableBox = findChild("executablesListBox"); @@ -1548,13 +1003,11 @@ void MainWindow::activateSelectedProfile() qDebug("activate profile \"%s\"", qPrintable(profileName)); QString profileDir = QDir::fromNativeSeparators(ToQString(GameInfo::instance().getProfilesDir())) .append("/").append(profileName); - delete m_CurrentProfile; - m_CurrentProfile = new Profile(QDir(profileDir)); - m_ModList.setProfile(m_CurrentProfile); + m_OrganizerCore.setCurrentProfile(new Profile(QDir(profileDir))); - m_ModListSortProxy->setProfile(m_CurrentProfile); + m_ModListSortProxy->setProfile(m_OrganizerCore.currentProfile()); - connect(m_CurrentProfile, SIGNAL(modStatusChanged(uint)), this, SLOT(modStatusChanged(uint))); + connect(m_OrganizerCore.currentProfile(), SIGNAL(modStatusChanged(uint)), this, SLOT(modStatusChanged(uint))); refreshSaveList(); refreshModList(); @@ -1567,9 +1020,9 @@ void MainWindow::on_profileBox_currentIndexChanged(int index) m_OldProfileIndex = index; if ((previousIndex != -1) && - (m_CurrentProfile != NULL) && - m_CurrentProfile->exists()) { - saveCurrentLists(); + (m_OrganizerCore.currentProfile() != NULL) && + m_OrganizerCore.currentProfile()->exists()) { + m_OrganizerCore.saveCurrentLists(); } // ensure the new index is valid @@ -1590,7 +1043,6 @@ void MainWindow::on_profileBox_currentIndexChanged(int index) } } - void MainWindow::updateTo(QTreeWidgetItem *subTree, const std::wstring &directorySoFar, const DirectoryEntry &directoryEntry, bool conflictsOnly) { { @@ -1605,7 +1057,7 @@ void MainWindow::updateTo(QTreeWidgetItem *subTree, const std::wstring &director QStringList columns(fileName); bool isArchive = false; int originID = current->getOrigin(isArchive); - FilesOrigin origin = m_DirectoryStructure->getOriginByID(originID); + FilesOrigin origin = m_OrganizerCore.directoryStructure()->getOriginByID(originID); QString source("data"); unsigned int modIndex = ModInfo::getIndex(ToQString(origin.getName())); if (modIndex != UINT_MAX) { @@ -1645,7 +1097,7 @@ void MainWindow::updateTo(QTreeWidgetItem *subTree, const std::wstring &director if (altIter != alternatives.begin()) { altString << " , "; } - altString << "" << m_DirectoryStructure->getOriginByID(*altIter).getName() << ""; + altString << "" << m_OrganizerCore.directoryStructure()->getOriginByID(*altIter).getName() << ""; } fileChild->setToolTip(1, QString("%1").arg(ToQString(altString.str()))); fileChild->setForeground(1, QBrush(Qt::red)); @@ -1706,7 +1158,7 @@ void MainWindow::expandDataTreeItem(QTreeWidgetItem *item) bool conflictsOnly = onDemandDataItem->data(0, Qt::UserRole + 2).toBool(); std::wstring virtualPath = (path + L"\\").substr(6) + ToWString(item->text(0)); - DirectoryEntry *dir = m_DirectoryStructure->findSubDirectoryRecursive(virtualPath); + DirectoryEntry *dir = m_OrganizerCore.directoryStructure()->findSubDirectoryRecursive(virtualPath); if (dir != NULL) { updateTo(item, path, *dir, conflictsOnly); } else { @@ -1769,31 +1221,6 @@ bool MainWindow::refreshProfiles(bool selectProfile) } } -std::set MainWindow::enabledArchives() -{ - std::set result; - QFile archiveFile(m_CurrentProfile->getArchivesFileName()); - if (archiveFile.open(QIODevice::ReadOnly)) { - while (!archiveFile.atEnd()) { - result.insert(QString::fromUtf8(archiveFile.readLine()).trimmed()); - } - archiveFile.close(); - } - return result; -} - -void MainWindow::refreshDirectoryStructure() -{ - m_DirectoryUpdate = true; - std::vector > activeModList = m_CurrentProfile->getActiveMods(); - - m_DirectoryRefresher.setMods(activeModList, enabledArchives()); - - statusBar()->show(); - m_RefreshProgress->setRange(0, 100); - - QTimer::singleShot(0, &m_DirectoryRefresher, SLOT(refresh())); -} #if QT_VERSION >= 0x050000 extern QPixmap qt_pixmapFromWinHICON(HICON icon); @@ -1824,7 +1251,7 @@ void MainWindow::refreshExecutablesList() QAbstractItemModel *model = executablesList->model(); std::vector::const_iterator current, end; - m_ExecutablesList.getExecutables(current, end); + m_OrganizerCore.executablesList()->getExecutables(current, end); for(int i = 0; current != end; ++current, ++i) { QVariant temp; temp.setValue(*current); @@ -1846,7 +1273,7 @@ void MainWindow::refreshDataTree() QStringList columns("data"); columns.append(""); QTreeWidgetItem *subTree = new QTreeWidgetItem(columns); - updateTo(subTree, L"", *m_DirectoryStructure, conflictsBox->isChecked()); + updateTo(subTree, L"", *m_OrganizerCore.directoryStructure(), conflictsBox->isChecked()); tree->insertTopLevelItem(0, subTree); subTree->setExpanded(true); tree->header()->resizeSection(0, 200); @@ -1866,13 +1293,13 @@ void MainWindow::refreshSaveList() ui->savegameList->clear(); QDir savesDir; - if (m_CurrentProfile->localSavesEnabled()) { - savesDir.setPath(m_CurrentProfile->getPath() + "/saves"); + if (m_OrganizerCore.currentProfile()->localSavesEnabled()) { + savesDir.setPath(m_OrganizerCore.currentProfile()->getPath() + "/saves"); } else { wchar_t path[MAX_PATH]; ::GetPrivateProfileStringW(L"General", L"SLocalSavePath", L"Saves", path, MAX_PATH, - (ToWString(m_CurrentProfile->getPath()) + L"\\" + GameInfo::instance().getIniFileNames().at(0)).c_str()); + (ToWString(m_OrganizerCore.currentProfile()->getPath()) + L"\\" + GameInfo::instance().getIniFileNames().at(0)).c_str()); savesDir.setPath(QDir::fromNativeSeparators(ToQString(GameInfo::instance().getDocumentsDir() + L"\\" + path))); } @@ -1895,67 +1322,15 @@ void MainWindow::refreshSaveList() } -void MainWindow::refreshLists() -{ - if ((m_CurrentProfile != NULL) && m_DirectoryStructure->isPopulated()) { - refreshESPList(); - refreshBSAList(); - } // no point in refreshing lists if no files have been added to the directory tree -} - - -void MainWindow::refreshESPList() -{ - m_CurrentProfile->writeModlist(); - - // clear list - try { - m_PluginList.refresh(m_CurrentProfile->getName(), - *m_DirectoryStructure, - m_CurrentProfile->getPluginsFileName(), - m_CurrentProfile->getLoadOrderFileName(), - m_CurrentProfile->getLockedOrderFileName()); - } catch (const std::exception &e) { - reportError(tr("Failed to refresh list of esps: %1").arg(e.what())); - } -} - -void MainWindow::refreshModList(bool saveChanges) -{ - // don't lose changes! - if (saveChanges) { - m_CurrentProfile->writeModlistNow(true); - } - ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure, m_Settings.displayForeign()); - - m_CurrentProfile->refreshModStatus(); - - m_ModList.notifyChange(-1); - - refreshDirectoryStructure(); -} - - static bool BySortValue(const std::pair &LHS, const std::pair &RHS) { return LHS.first < RHS.first; } -template -QStringList toStringList(InputIterator current, InputIterator end) +void MainWindow::updateBSAList(const QStringList &defaultArchives, const QStringList &activeArchives) { - QStringList result; - for (; current != end; ++current) { - result.append(*current); - } - return result; -} - -void MainWindow::refreshBSAList() -{ - m_ArchivesInit = false; ui->bsaList->clear(); #if QT_VERSION >= QT_VERSION_CHECK(5,0,0) ui->bsaList->header()->setSectionResizeMode(QHeaderView::ResizeToContents); @@ -1963,40 +1338,9 @@ void MainWindow::refreshBSAList() ui->bsaList->header()->setResizeMode(QHeaderView::ResizeToContents); #endif - m_DefaultArchives.clear(); - - wchar_t buffer[256]; - std::wstring iniFileName = ToWString(QDir::toNativeSeparators(m_CurrentProfile->getIniFileName())); - if (::GetPrivateProfileStringW(L"Archive", GameInfo::instance().archiveListKey().c_str(), - L"", buffer, 256, iniFileName.c_str()) != 0) { - m_DefaultArchives = ToQString(buffer).split(','); - } else { - std::vector vanillaBSAs = GameInfo::instance().getVanillaBSAs(); - for (auto iter = vanillaBSAs.begin(); iter != vanillaBSAs.end(); ++iter) { - m_DefaultArchives.append(ToQString(*iter)); - } - } - - if (::GetPrivateProfileStringW(L"Archive", GameInfo::instance().archiveListKey().append(L"2").c_str(), - L"", buffer, 256, iniFileName.c_str()) != 0) { - m_DefaultArchives.append(ToQString(buffer).split(',')); - } - - for (int i = 0; i < m_DefaultArchives.count(); ++i) { - m_DefaultArchives[i] = m_DefaultArchives[i].trimmed(); - } - - m_ActiveArchives.clear(); - - auto iter = enabledArchives(); - m_ActiveArchives = toStringList(iter.begin(), iter.end()); - if (m_ActiveArchives.isEmpty()) { - m_ActiveArchives = m_DefaultArchives; - } - std::vector > items; - std::vector files = m_DirectoryStructure->getFiles(); + std::vector files = m_OrganizerCore.directoryStructure()->getFiles(); for (auto iter = files.begin(); iter != files.end(); ++iter) { FileEntry::Ptr current = *iter; @@ -2004,7 +1348,7 @@ void MainWindow::refreshBSAList() QString extension = filename.right(3).toLower(); if (extension == "bsa") { - int index = m_ActiveArchives.indexOf(filename); + int index = activeArchives.indexOf(filename); if (index == -1) { index = 0xFFFF; } @@ -2012,20 +1356,20 @@ void MainWindow::refreshBSAList() QStringList strings(filename); bool isArchive = false; int origin = current->getOrigin(isArchive); - strings.append(ToQString(m_DirectoryStructure->getOriginByID(origin).getName())); + strings.append(ToQString(m_OrganizerCore.directoryStructure()->getOriginByID(origin).getName())); QTreeWidgetItem *newItem = new QTreeWidgetItem(strings); newItem->setData(0, Qt::UserRole, index); newItem->setData(1, Qt::UserRole, origin); newItem->setFlags(newItem->flags() & ~Qt::ItemIsDropEnabled | Qt::ItemIsUserCheckable); newItem->setCheckState(0, (index != -1) ? Qt::Checked : Qt::Unchecked); newItem->setData(0, Qt::UserRole, false); - if (m_Settings.forceEnableCoreFiles() - && m_DefaultArchives.contains(filename)) { + if (m_OrganizerCore.settings().forceEnableCoreFiles() + && defaultArchives.contains(filename)) { newItem->setCheckState(0, Qt::Checked); newItem->setDisabled(true); newItem->setData(0, Qt::UserRole, true); - } else if ((m_PluginList.state(basename + ".esp") == IPluginList::STATE_ACTIVE) - || (m_PluginList.state(basename + ".esm") == IPluginList::STATE_ACTIVE)) { + } else if ((m_OrganizerCore.pluginList()->state(basename + ".esp") == IPluginList::STATE_ACTIVE) + || (m_OrganizerCore.pluginList()->state(basename + ".esm") == IPluginList::STATE_ACTIVE)) { newItem->setCheckState(0, Qt::Checked); newItem->setDisabled(true); } else { @@ -2039,7 +1383,7 @@ void MainWindow::refreshBSAList() if (index < 0) index = 0; - UINT32 sortValue = ((m_DirectoryStructure->getOriginByID(origin).getPriority() & 0xFFFF) << 16) | (index & 0xFFFF); + UINT32 sortValue = ((m_OrganizerCore.directoryStructure()->getOriginByID(origin).getPriority() & 0xFFFF) << 16) | (index & 0xFFFF); items.push_back(std::make_pair(sortValue, newItem)); } } @@ -2049,7 +1393,7 @@ void MainWindow::refreshBSAList() for (std::vector >::iterator iter = items.begin(); iter != items.end(); ++iter) { int originID = iter->second->data(1, Qt::UserRole).toInt(); - FilesOrigin origin = m_DirectoryStructure->getOriginByID(originID); + FilesOrigin origin = m_OrganizerCore.directoryStructure()->getOriginByID(originID); QString modName("data"); unsigned int modIndex = ModInfo::getIndex(ToQString(origin.getName())); if (modIndex != UINT_MAX) { @@ -2069,12 +1413,11 @@ void MainWindow::refreshBSAList() subItem->setExpanded(true); } - checkBSAList(); - m_ArchivesInit = true; + m_OrganizerCore.checkBSAList(); } -void MainWindow::checkBSAList() +void MainWindow::checkBSAList(const QStringList &defaultArchives) { ui->bsaList->blockSignals(true); @@ -2090,7 +1433,7 @@ void MainWindow::checkBSAList() item->setToolTip(0, QString()); if (item->checkState(0) == Qt::Unchecked) { - if (m_DefaultArchives.contains(filename)) { + if (defaultArchives.contains(filename)) { item->setIcon(0, QIcon(":/MO/gui/warning")); item->setToolTip(0, tr("This bsa is enabled in the ini file so it may be required!")); modWarning = true; @@ -2183,130 +1526,51 @@ void MainWindow::readSettings() } bool filtersVisible = settings.value("filters_visible", false).toBool(); - setCategoryListVisible(filtersVisible); - ui->displayCategoriesBtn->setChecked(filtersVisible); - - int selectedExecutable = settings.value("selected_executable").toInt(); - setExecutableIndex(selectedExecutable); - - if (settings.value("Settings/use_proxy", false).toBool()) { - activateProxy(true); - } - - ui->manageArchivesBox->blockSignals(true); - ui->manageArchivesBox->setChecked(settings.value("manage_bsas", true).toBool()); - ui->manageArchivesBox->blockSignals(false); -} - - -bool renameFile(const QString &oldName, const QString &newName, bool overwrite = true) -{ - if (overwrite && QFile::exists(newName)) { - QFile::remove(newName); - } - return QFile::rename(oldName, newName); -} - - -void MainWindow::storeSettings() -{ - if (m_CurrentProfile == NULL) { - return; - } - m_CurrentProfile->writeModlist(); - m_CurrentProfile->createTweakedIniFile(); - saveCurrentLists(); - m_Settings.setupLoadMechanism(); - - QString iniFile = ToQString(GameInfo::instance().getIniFilename()); - shellCopy(iniFile, iniFile + ".new", true, this); - - QSettings::Status result = QSettings::NoError; - { - QSettings settings(iniFile + ".new", QSettings::IniFormat); - settings.setValue("selected_profile", m_CurrentProfile->getName().toUtf8().constData()); - - settings.setValue("mod_list_state", ui->modList->header()->saveState()); - settings.setValue("plugin_list_state", ui->espList->header()->saveState()); + setCategoryListVisible(filtersVisible); + ui->displayCategoriesBtn->setChecked(filtersVisible); - settings.setValue("group_state", ui->groupCombo->currentIndex()); + int selectedExecutable = settings.value("selected_executable").toInt(); + setExecutableIndex(selectedExecutable); - settings.setValue("ask_for_nexuspw", m_AskForNexusPW); + if (settings.value("Settings/use_proxy", false).toBool()) { + activateProxy(true); + } - settings.setValue("window_geometry", saveGeometry()); - settings.setValue("window_split", ui->splitter->saveState()); - settings.setValue("log_split", ui->topLevelSplitter->saveState()); + ui->manageArchivesBox->blockSignals(true); + ui->manageArchivesBox->setChecked(settings.value("manage_bsas", true).toBool()); + ui->manageArchivesBox->blockSignals(false); +} - settings.setValue("browser_geometry", m_IntegratedBrowser.saveGeometry()); - settings.setValue("filters_visible", ui->displayCategoriesBtn->isChecked()); - settings.setValue("manage_bsas", ui->manageArchivesBox->isChecked()); +void MainWindow::storeSettings(QSettings &settings) +{ + settings.setValue("mod_list_state", ui->modList->header()->saveState()); + settings.setValue("plugin_list_state", ui->espList->header()->saveState()); - settings.remove("customExecutables"); - settings.beginWriteArray("customExecutables"); - std::vector::const_iterator current, end; - m_ExecutablesList.getExecutables(current, end); - int count = 0; - for (; current != end; ++current) { - const Executable &item = *current; - if (item.m_Custom || item.m_Toolbar) { - settings.setArrayIndex(count++); - settings.setValue("binary", item.m_BinaryInfo.absoluteFilePath()); - settings.setValue("title", item.m_Title); - settings.setValue("arguments", item.m_Arguments); - settings.setValue("workingDirectory", item.m_WorkingDirectory); - settings.setValue("closeOnStart", item.m_CloseMO == DEFAULT_CLOSE); - settings.setValue("steamAppID", item.m_SteamAppID); - settings.setValue("custom", item.m_Custom); - settings.setValue("toolbar", item.m_Toolbar); - } - } - settings.endArray(); + settings.setValue("group_state", ui->groupCombo->currentIndex()); - QComboBox *executableBox = findChild("executablesListBox"); - settings.setValue("selected_executable", executableBox->currentIndex()); + settings.setValue("window_geometry", saveGeometry()); + settings.setValue("window_split", ui->splitter->saveState()); + settings.setValue("log_split", ui->topLevelSplitter->saveState()); - FileDialogMemory::save(settings); + settings.setValue("browser_geometry", m_IntegratedBrowser.saveGeometry()); - settings.sync(); - result = settings.status(); - } - if (result == QSettings::NoError) { - if (!shellRename(iniFile + ".new", iniFile, true, this)) { - DWORD err = ::GetLastError(); - // make a second attempt using qt functions but if that fails print the error from the first attempt - if (!renameFile(iniFile + ".new", iniFile)) { - QMessageBox::critical(this, tr("Failed to write settings"), - tr("An error occured trying to write back MO settings: %1").arg(windowsErrorString(err))); - } - } - } else { - QString reason = result == QSettings::AccessError ? tr("File is write protected") - : result == QSettings::FormatError ? tr("Invalid file format (probably a bug)") - : tr("Unknown error %1").arg(result); - QMessageBox::critical(this, tr("Failed to write settings"), - tr("An error occured trying to write back MO settings: %1").arg(reason)); - } + settings.setValue("filters_visible", ui->displayCategoriesBtn->isChecked()); + settings.setValue("manage_bsas", ui->manageArchivesBox->isChecked()); } void MainWindow::on_btnRefreshData_clicked() { - if (!m_DirectoryUpdate) { - // save the mod list so changes don't get lost - m_CurrentProfile->writeModlistNow(true); - refreshDirectoryStructure(); - } else { - qDebug("directory update"); - } + m_OrganizerCore.refreshDirectoryStructure(); } void MainWindow::on_tabWidget_currentChanged(int index) { if (index == 0) { - refreshESPList(); + m_OrganizerCore.refreshESPList(); } else if (index == 1) { - refreshBSAList(); + m_OrganizerCore.refreshBSAList(); } else if (index == 2) { refreshDataTree(); } else if (index == 3) { @@ -2316,67 +1580,11 @@ void MainWindow::on_tabWidget_currentChanged(int index) } } -std::vector MainWindow::activeProblems() const -{ - std::vector problems; - if (m_FailedPlugins.size() != 0) { - problems.push_back(PROBLEM_PLUGINSNOTLOADED); - } - if (m_PluginList.enabledCount() > 255) { - problems.push_back(PROBLEM_TOOMANYPLUGINS); - } - return problems; -} - -QString MainWindow::shortDescription(unsigned int key) const -{ - switch (key) { - case PROBLEM_PLUGINSNOTLOADED: { - return tr("Some plugins could not be loaded"); - } break; - case PROBLEM_TOOMANYPLUGINS: { - return tr("Too many esps and esms enabled"); - } break; - default: { - return tr("Description missing"); - } break; - } -} - -QString MainWindow::fullDescription(unsigned int key) const -{ - switch (key) { - case PROBLEM_PLUGINSNOTLOADED: { - QString result = tr("The following plugins could not be loaded. The reason may be missing dependencies (i.e. python) or an outdated version:") + "
    "; - foreach (const QString &plugin, m_FailedPlugins) { - result += "
  • " + plugin + "
  • "; - } - result += "
      "; - return result; - } break; - case PROBLEM_TOOMANYPLUGINS: { - return tr("The game doesn't allow more than 255 active plugins (including the official ones) to be loaded. You have to disable some unused plugins or " - "merge some plugins into one. You can find a guide here: http://wiki.step-project.com/Guide:Merging_Plugins"); - } break; - default: { - return tr("Description missing"); - } break; - } -} - -bool MainWindow::hasGuidedFix(unsigned int) const -{ - return false; -} - -void MainWindow::startGuidedFix(unsigned int) const -{ -} void MainWindow::installMod() { try { - QStringList extensions = m_InstallationManager.getSupportedExtensions(); + QStringList extensions = m_OrganizerCore.installationManager()->getSupportedExtensions(); for (auto iter = extensions.begin(); iter != extensions.end(); ++iter) { *iter = "*." + *iter; } @@ -2387,114 +1595,13 @@ void MainWindow::installMod() if (fileName.length() == 0) { return; } else { - installMod(fileName); + m_OrganizerCore.installMod(fileName); } } catch (const std::exception &e) { reportError(e.what()); } } -IModInterface *MainWindow::installMod(const QString &fileName) -{ - if (m_CurrentProfile == NULL) { - return NULL; - } - - bool hasIniTweaks = false; - GuessedValue modName; - m_CurrentProfile->writeModlistNow(); - m_InstallationManager.setModsDirectory(m_Settings.getModDirectory()); - if (m_InstallationManager.install(fileName, modName, hasIniTweaks)) { - MessageDialog::showMessage(tr("Installation successful"), this); - refreshModList(); - - QModelIndexList posList = m_ModList.match(m_ModList.index(0, 0), Qt::DisplayRole, static_cast(modName)); - if (posList.count() == 1) { - ui->modList->scrollTo(posList.at(0)); - } - int modIndex = ModInfo::getIndex(modName); - if (modIndex != UINT_MAX) { - ModInfo::Ptr modInfo = ModInfo::getByIndex(modIndex); - if (hasIniTweaks && - (QMessageBox::question(this, tr("Configure Mod"), - tr("This mod contains ini tweaks. Do you want to configure them now?"), - QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)) { - displayModInformation(modInfo, modIndex, ModInfoDialog::TAB_INIFILES); - } - m_ModInstalled(modName); - return modInfo.data(); - } else { - reportError(tr("mod \"%1\" not found").arg(modName)); - } - } else if (m_InstallationManager.wasCancelled()) { - QMessageBox::information(this, tr("Installation cancelled"), tr("The mod was not installed completely."), QMessageBox::Ok); - } - return NULL; -} - -IModInterface *MainWindow::getMod(const QString &name) -{ - unsigned int index = ModInfo::getIndex(name); - if (index == UINT_MAX) { - return NULL; - } else { - return ModInfo::getByIndex(index).data(); - } -} - -IModInterface *MainWindow::createMod(GuessedValue &name) -{ - if (!m_InstallationManager.testOverwrite(name)) { - return NULL; - } - - m_InstallationManager.setModsDirectory(m_Settings.getModDirectory()); - - QString targetDirectory = QDir::fromNativeSeparators(m_Settings.getModDirectory()).append("/").append(name); - - QSettings settingsFile(targetDirectory.mid(0).append("/meta.ini"), QSettings::IniFormat); - - settingsFile.setValue("modid", 0); - settingsFile.setValue("version", ""); - settingsFile.setValue("newestVersion", ""); - settingsFile.setValue("category", 0); - settingsFile.setValue("installationFile", ""); - return ModInfo::createFrom(QDir(targetDirectory), &m_DirectoryStructure).data(); -} - -bool MainWindow::removeMod(IModInterface *mod) -{ - unsigned int index = ModInfo::getIndex(mod->name()); - if (index == UINT_MAX) { - return mod->remove(); - } else { - return ModInfo::removeMod(index); - } -} - -QList MainWindow::findFileInfos(const QString &path, const std::function &filter) const -{ - QList result; - DirectoryEntry *dir = m_DirectoryStructure->findSubDirectoryRecursive(ToWString(path)); - if (dir != NULL) { - std::vector files = dir->getFiles(); - foreach (FileEntry::Ptr file, files) { - IOrganizer::FileInfo info; - info.filePath = ToQString(file->getFullPath()); - bool fromArchive = false; - info.origins.append(ToQString(m_DirectoryStructure->getOriginByID(file->getOrigin(fromArchive)).getName())); - info.archive = fromArchive ? ToQString(file->getArchive()) : ""; - foreach (int idx, file->getAlternatives()) { - info.origins.append(ToQString(m_DirectoryStructure->getOriginByID(idx).getName())); - } - - if (filter(info)) { - result.append(info); - } - } - } - return result; -} void MainWindow::on_startButton_clicked() { @@ -2502,12 +1609,13 @@ void MainWindow::on_startButton_clicked() Executable selectedExecutable = executablesList->itemData(executablesList->currentIndex()).value(); - spawnBinary(selectedExecutable.m_BinaryInfo, - selectedExecutable.m_Arguments, - selectedExecutable.m_WorkingDirectory.length() != 0 ? selectedExecutable.m_WorkingDirectory - : selectedExecutable.m_BinaryInfo.absolutePath(), - selectedExecutable.m_CloseMO == DEFAULT_CLOSE, - selectedExecutable.m_SteamAppID); + m_OrganizerCore.spawnBinary( + selectedExecutable.m_BinaryInfo, + selectedExecutable.m_Arguments, + selectedExecutable.m_WorkingDirectory.length() != 0 ? selectedExecutable.m_WorkingDirectory + : selectedExecutable.m_BinaryInfo.absolutePath(), + selectedExecutable.m_CloseMO == ExecutableInfo::CloseMOStyle::DEFAULT_CLOSE, + selectedExecutable.m_SteamAppID); } @@ -2584,9 +1692,9 @@ bool MainWindow::modifyExecutablesDialog() { bool result = false; try { - EditExecutablesDialog dialog(m_ExecutablesList); + EditExecutablesDialog dialog(m_OrganizerCore.executablesList()); if (dialog.exec() == QDialog::Accepted) { - m_ExecutablesList = dialog.getExecutablesList(); + m_OrganizerCore.setExecutablesDialog(dialog.getExecutablesList()); result = true; } refreshExecutablesList(); @@ -2698,26 +1806,6 @@ void MainWindow::setESPListSorting(int index) } -bool MainWindow::queryLogin(QString &username, QString &password) -{ - CredentialsDialog dialog(this); - int res = dialog.exec(); - if (dialog.neverAsk()) { - m_AskForNexusPW = false; - } - if (res == QDialog::Accepted) { - username = dialog.username(); - password = dialog.password(); - if (dialog.store()) { - m_Settings.setNexusLogin(username, password); - } - return true; - } else { - return false; - } -} - - bool MainWindow::setCurrentProfile(int index) { QComboBox *profilesBox = findChild("profileBox"); @@ -2746,136 +1834,45 @@ bool MainWindow::setCurrentProfile(const QString &name) void MainWindow::refresher_progress(int percent) { - m_RefreshProgress->setValue(percent); + if (percent == 100) { + m_RefreshProgress->setVisible(false); + } else if (!m_RefreshProgress->isVisible()) { + m_RefreshProgress->setVisible(true); + m_RefreshProgress->setRange(0, 100); + m_RefreshProgress->setValue(percent); + } } - void MainWindow::directory_refreshed() { - DirectoryEntry *newStructure = m_DirectoryRefresher.getDirectoryStructure(); - Q_ASSERT(newStructure != m_DirectoryStructure); - if (newStructure != NULL) { - std::swap(m_DirectoryStructure, newStructure); - delete newStructure; - refreshDataTree(); - } else { - // TODO: don't know why this happens, this slot seems to get called twice with only one emit - return; - } - m_DirectoryUpdate = false; - if (m_CurrentProfile != NULL) { - refreshLists(); - } - // some problem-reports may rely on the virtual directory tree so they need to be updated // now + refreshDataTree(); updateProblemsButton(); - - for (int i = 0; i < m_ModList.rowCount(); ++i) { - ModInfo::Ptr modInfo = ModInfo::getByIndex(i); - modInfo->clearCaches(); - } statusBar()->hide(); } -void MainWindow::externalMessage(const QString &message) -{ - if (message.left(6).toLower() == "nxm://") { - MessageDialog::showMessage(tr("Download started"), this); - downloadRequestedNXM(message); - } -} - -void MainWindow::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() - ); - DirectoryRefresher::cleanStructure(m_DirectoryStructure); - // need to refresh plugin list now so we can activate esps - refreshESPList(); - // activate all esps of the specified mod so the bsas get activated along with it - updateModActiveState(index, true); - // now we need to refresh the bsa list and save it so there is no confusion about what archives are avaiable and active - refreshBSAList(); - saveArchiveList(); - m_DirectoryRefresher.setMods(m_CurrentProfile->getActiveMods(), enabledArchives()); - - // 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() - ); -} - -void MainWindow::modStatusChanged(unsigned int index) -{ - try { - ModInfo::Ptr modInfo = ModInfo::getByIndex(index); - if (m_CurrentProfile->modEnabled(index)) { - updateModInDirectoryStructure(index, modInfo); - } else { - updateModActiveState(index, false); - refreshESPList(); - if (m_DirectoryStructure->originExists(ToWString(modInfo->name()))) { - FilesOrigin &origin = m_DirectoryStructure->getOriginByName(ToWString(modInfo->name())); - origin.enable(false); - } - } - modInfo->clearCaches(); - - 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 MainWindow::removeOrigin(const QString &name) -{ - FilesOrigin &origin = m_DirectoryStructure->getOriginByName(ToWString(name)); - origin.enable(false); - refreshLists(); -} - - void MainWindow::modorder_changed() { - for (unsigned int i = 0; i < m_CurrentProfile->numMods(); ++i) { - int priority = m_CurrentProfile->getModPriority(i); - if (m_CurrentProfile->modEnabled(i)) { + for (unsigned int i = 0; i < m_OrganizerCore.currentProfile()->numMods(); ++i) { + int priority = m_OrganizerCore.currentProfile()->getModPriority(i); + if (m_OrganizerCore.currentProfile()->modEnabled(i)) { ModInfo::Ptr modInfo = ModInfo::getByIndex(i); // priorities in the directory structure are one higher because data is 0 - m_DirectoryStructure->getOriginByName(ToWString(modInfo->internalName())).setPriority(priority + 1); + m_OrganizerCore.directoryStructure()->getOriginByName(ToWString(modInfo->internalName())).setPriority(priority + 1); } } - refreshBSAList(); - m_CurrentProfile->writeModlist(); - saveArchiveList(); - m_DirectoryStructure->getFileRegister()->sortOrigins(); + m_OrganizerCore.refreshBSAList(); + m_OrganizerCore.currentProfile()->writeModlist(); + m_OrganizerCore.saveArchiveList(); + m_OrganizerCore.directoryStructure()->getFileRegister()->sortOrigins(); { // refresh selection QModelIndex current = ui->modList->currentIndex(); if (current.isValid()) { ModInfo::Ptr modInfo = ModInfo::getByIndex(current.data(Qt::UserRole + 1).toInt()); modInfo->doConflictCheck(); - m_ModList.setOverwriteMarkers(modInfo->getModOverwrite(), modInfo->getModOverwritten()); + m_OrganizerCore.modList()->setOverwriteMarkers(modInfo->getModOverwrite(), modInfo->getModOverwritten()); if (m_ModListSortProxy != NULL) { m_ModListSortProxy->invalidate(); } @@ -2884,6 +1881,16 @@ void MainWindow::modorder_changed() } } +void MainWindow::modInstalled() +{ + QModelIndexList posList = + m_OrganizerCore.modList().match(m_OrganizerCore.modList().index(0, 0), + Qt::DisplayRole, static_cast(modName)); + if (posList.count() == 1) { + ui->modList->scrollTo(posList.at(0)); + } +} + void MainWindow::procError(QProcess::ProcessError error) { reportError(tr("failed to spawn notepad.exe: %1").arg(error)); @@ -2895,15 +1902,6 @@ void MainWindow::procFinished(int, QProcess::ExitStatus) this->sender()->deleteLater(); } -void MainWindow::profileRefresh() -{ - // have to refresh mods twice (again in refreshModList), otherwise the refresh isn't complete. Not sure why - ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure, m_Settings.displayForeign()); - m_CurrentProfile->refreshModStatus(); - - refreshModList(); -} - void MainWindow::showMessage(const QString &message) { MessageDialog::showMessage(message, this); @@ -2987,12 +1985,12 @@ void MainWindow::modRenamed(const QString &oldName, const QString &newName) } // immediately refresh the active profile because the data in memory is invalid - m_CurrentProfile->refreshModStatus(); + m_OrganizerCore.currentProfile()->refreshModStatus(); // also fix the directory structure try { - if (m_DirectoryStructure->originExists(ToWString(oldName))) { - FilesOrigin &origin = m_DirectoryStructure->getOriginByName(ToWString(oldName)); + if (m_OrganizerCore.directoryStructure()->originExists(ToWString(oldName))) { + FilesOrigin &origin = m_OrganizerCore.directoryStructure()->getOriginByName(ToWString(oldName)); origin.setName(ToWString(newName)); } else { @@ -3011,11 +2009,11 @@ void MainWindow::modlistChanged(int) void MainWindow::fileMoved(const QString &filePath, const QString &oldOriginName, const QString &newOriginName) { - const FileEntry::Ptr filePtr = m_DirectoryStructure->findFile(ToWString(filePath)); + const FileEntry::Ptr filePtr = m_OrganizerCore.directoryStructure()->findFile(ToWString(filePath)); if (filePtr.get() != NULL) { try { - if (m_DirectoryStructure->originExists(ToWString(newOriginName))) { - FilesOrigin &newOrigin = m_DirectoryStructure->getOriginByName(ToWString(newOriginName)); + if (m_OrganizerCore.directoryStructure()->originExists(ToWString(newOriginName))) { + FilesOrigin &newOrigin = m_OrganizerCore.directoryStructure()->getOriginByName(ToWString(newOriginName)); QString fullNewPath = ToQString(newOrigin.getPath()) + "\\" + filePath; WIN32_FIND_DATAW findData; @@ -3023,8 +2021,8 @@ void MainWindow::fileMoved(const QString &filePath, const QString &oldOriginName filePtr->addOrigin(newOrigin.getID(), findData.ftCreationTime, L""); } - if (m_DirectoryStructure->originExists(ToWString(oldOriginName))) { - FilesOrigin &oldOrigin = m_DirectoryStructure->getOriginByName(ToWString(oldOriginName)); + if (m_OrganizerCore.directoryStructure()->originExists(ToWString(oldOriginName))) { + FilesOrigin &oldOrigin = m_OrganizerCore.directoryStructure()->getOriginByName(ToWString(oldOriginName)); filePtr->removeOrigin(oldOrigin.getID()); } } catch (const std::exception &e) { @@ -3140,7 +2138,7 @@ void MainWindow::restoreBackup_clicked() ModInfo::Ptr modInfo = ModInfo::getByIndex(m_ContextRow); if (backupRegEx.indexIn(modInfo->name()) != -1) { QString regName = backupRegEx.cap(1); - QDir modDir(QDir::fromNativeSeparators(m_Settings.getModDirectory())); + QDir modDir(QDir::fromNativeSeparators(m_OrganizerCore.settings().getModDirectory())); if (!modDir.exists(regName) || (QMessageBox::question(this, tr("Overwrite?"), tr("This will replace the existing mod \"%1\". Continue?").arg(regName), @@ -3148,7 +2146,7 @@ void MainWindow::restoreBackup_clicked() if (modDir.exists(regName) && !shellDelete(QStringList(modDir.absoluteFilePath(regName)))) { reportError(tr("failed to remove mod \"%1\"").arg(regName)); } else { - QString destinationPath = QDir::fromNativeSeparators(m_Settings.getModDirectory()) + "/" + regName; + QString destinationPath = QDir::fromNativeSeparators(m_OrganizerCore.settings().getModDirectory()) + "/" + regName; if (!modDir.rename(modInfo->absolutePath(), destinationPath)) { reportError(tr("failed to rename \"%1\" to \"%2\"").arg(modInfo->absolutePath()).arg(destinationPath)); } @@ -3158,43 +2156,18 @@ void MainWindow::restoreBackup_clicked() } } -void MainWindow::updateModActiveState(int index, bool active) -{ - ModInfo::Ptr modInfo = ModInfo::getByIndex(index); - - QDir dir(modInfo->absolutePath()); - foreach (const QString &esm, dir.entryList(QStringList("*.esm"), QDir::Files)) { - m_PluginList.enableESP(esm, active); - } - int enabled = 0; - QStringList esps = dir.entryList(QStringList("*.esp"), QDir::Files); - foreach (const QString &esp, esps) { - if (active != m_PluginList.isEnabled(esp)) { - m_PluginList.enableESP(esp, active); - ++enabled; - } - } - if (active && (enabled > 1)) { - MessageDialog::showMessage(tr("Multiple esps activated, please check that they don't conflict."), this); - } - m_PluginList.refreshLoadOrder(); - // immediately save affected lists - savePluginList(); -// refreshBSAList(); -} - void MainWindow::modlistChanged(const QModelIndex&, int) { - m_CurrentProfile->writeModlist(); + m_OrganizerCore.currentProfile()->writeModlist(); } void MainWindow::modlistSelectionChanged(const QModelIndex ¤t, const QModelIndex&) { if (current.isValid()) { ModInfo::Ptr selectedMod = ModInfo::getByIndex(current.data(Qt::UserRole + 1).toInt()); - m_ModList.setOverwriteMarkers(selectedMod->getModOverwrite(), selectedMod->getModOverwritten()); + m_OrganizerCore.modList()->setOverwriteMarkers(selectedMod->getModOverwrite(), selectedMod->getModOverwritten()); } else { - m_ModList.setOverwriteMarkers(std::set(), std::set()); + m_OrganizerCore.modList()->setOverwriteMarkers(std::set(), std::set()); } if ((m_ModListSortProxy != NULL) && !m_ModListSortProxy->beingInvalidated()) { @@ -3229,11 +2202,11 @@ void MainWindow::removeMod_clicked() QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { // use mod names instead of indexes because those become invalid during the removal foreach (QString name, modNames) { - m_ModList.removeRowForce(ModInfo::getIndex(name)); + m_OrganizerCore.modList()->removeRowForce(ModInfo::getIndex(name)); } } } else { - m_ModList.removeRow(m_ContextRow, QModelIndex()); + m_OrganizerCore.modList()->removeRow(m_ContextRow, QModelIndex()); } } catch (const std::exception &e) { reportError(tr("failed to remove mod: %1").arg(e.what())); @@ -3244,9 +2217,9 @@ void MainWindow::removeMod_clicked() void MainWindow::modRemoved(const QString &fileName) { if (!fileName.isEmpty() && !QFileInfo(fileName).isAbsolute()) { - int index = m_DownloadManager.indexByName(fileName); + int index = m_OrganizerCore.downloadManager()->indexByName(fileName); if (index >= 0) { - m_DownloadManager.markUninstalled(index); + m_OrganizerCore.downloadManager()->markUninstalled(index); } } } @@ -3263,10 +2236,10 @@ void MainWindow::reinstallMod_clicked() if (fileInfo.exists()) { fullInstallationFile = installationFile; } else { - fullInstallationFile = m_DownloadManager.getOutputDirectory().append("/").append(fileInfo.fileName()); + fullInstallationFile = m_OrganizerCore.downloadManager()->getOutputDirectory().append("/").append(fileInfo.fileName()); } } else { - fullInstallationFile = m_DownloadManager.getOutputDirectory().append("/").append(installationFile); + fullInstallationFile = m_OrganizerCore.downloadManager()->getOutputDirectory().append("/").append(installationFile); } if (QFile::exists(fullInstallationFile)) { installMod(fullInstallationFile); @@ -3283,11 +2256,12 @@ void MainWindow::reinstallMod_clicked() void MainWindow::resumeDownload(int downloadIndex) { if (NexusInterface::instance()->getAccessManager()->loggedIn()) { - m_DownloadManager.resumeDownload(downloadIndex); + m_OrganizerCore.downloadManager()->resumeDownload(downloadIndex); } else { QString username, password; - if (m_Settings.getNexusLogin(username, password)) { - m_PostLoginTasks.push_back(boost::bind(&MainWindow::resumeDownload, _1, downloadIndex)); + if (m_OrganizerCore.settings().getNexusLogin(username, password)) { + //m_PostLoginTasks.push_back(boost::bind(&MainWindow::resumeDownload, _1, downloadIndex)); + m_OrganizerCore.doAfterLogin(std::bind(&MainWindow::resumeDownload, this, downloadIndex)); NexusInterface::instance()->getAccessManager()->login(username, password); } else { MessageDialog::showMessage(tr("You need to be logged in with Nexus to resume a download"), this); @@ -3302,7 +2276,7 @@ void MainWindow::endorseMod(ModInfo::Ptr mod) mod->endorse(true); } else { QString username, password; - if (m_Settings.getNexusLogin(username, password)) { + if (m_OrganizerCore.settings().getNexusLogin(username, password)) { m_PostLoginTasks.push_back(boost::bind(&MainWindow::endorseMod, _1, mod)); NexusInterface::instance()->getAccessManager()->login(username, password); } else { @@ -3329,7 +2303,7 @@ void MainWindow::unendorse_clicked() if (NexusInterface::instance()->getAccessManager()->loggedIn()) { ModInfo::getByIndex(m_ContextRow)->endorse(false); } else { - if (m_Settings.getNexusLogin(username, password)) { + if (m_OrganizerCore.settings().getNexusLogin(username, password)) { m_PostLoginTasks.push_back(boost::mem_fn(&MainWindow::unendorse_clicked)); NexusInterface::instance()->getAccessManager()->login(username, password); } else { @@ -3338,12 +2312,21 @@ void MainWindow::unendorse_clicked() } } +void MainWindow::loginFailed(const QString &message) +{ + statusBar()->hide(); +} + +void MainWindow::windowTutorialFinished(const QString &windowName) +{ + m_OrganizerCore.settings().directInterface().setValue(QString("CompletedWindowTutorials/") + windowName, this); +} void MainWindow::overwriteClosed(int) { OverwriteInfoDialog *dialog = this->findChild("__overwriteDialog"); if (dialog != NULL) { - m_ModList.modInfoChanged(dialog->modInfo()); + m_OrganizerCore.modList()->modInfoChanged(dialog->modInfo()); dialog->deleteLater(); } } @@ -3351,7 +2334,7 @@ void MainWindow::overwriteClosed(int) void MainWindow::displayModInformation(ModInfo::Ptr modInfo, unsigned int index, int tab) { - m_ModList.modInfoAboutToChange(modInfo); + m_OrganizerCore.modList()->modInfoAboutToChange(modInfo); std::vector flags = modInfo->getFlags(); if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end()) { QDialog *dialog = this->findChild("__overwriteDialog"); @@ -3371,7 +2354,7 @@ void MainWindow::displayModInformation(ModInfo::Ptr modInfo, unsigned int index, } } else { modInfo->saveMeta(); - ModInfoDialog dialog(modInfo, m_DirectoryStructure, modInfo->hasFlag(ModInfo::FLAG_FOREIGN), this); + ModInfoDialog dialog(modInfo, m_OrganizerCore.directoryStructure(), modInfo->hasFlag(ModInfo::FLAG_FOREIGN), this); connect(&dialog, SIGNAL(nexusLinkActivated(QString)), this, SLOT(nexusLinkActivated(QString))); connect(&dialog, SIGNAL(downloadRequest(QString)), this, SLOT(downloadRequestedNXM(QString))); connect(&dialog, SIGNAL(modOpen(QString, int)), this, SLOT(displayModInformation(QString, int)), Qt::QueuedConnection); @@ -3381,31 +2364,31 @@ void MainWindow::displayModInformation(ModInfo::Ptr modInfo, unsigned int index, connect(&dialog, SIGNAL(endorseMod(ModInfo::Ptr)), this, SLOT(endorseMod(ModInfo::Ptr))); dialog.openTab(tab); - dialog.restoreTabState(m_Settings.directInterface().value("mod_info_tabs").toByteArray()); + dialog.restoreTabState(m_OrganizerCore.settings().directInterface().value("mod_info_tabs").toByteArray()); dialog.exec(); - m_Settings.directInterface().setValue("mod_info_tabs", dialog.saveTabState()); + m_OrganizerCore.settings().directInterface().setValue("mod_info_tabs", dialog.saveTabState()); modInfo->saveMeta(); emit modInfoDisplayed(); - m_ModList.modInfoChanged(modInfo); + m_OrganizerCore.modList()->modInfoChanged(modInfo); } - if (m_CurrentProfile->modEnabled(index)) { - FilesOrigin& origin = m_DirectoryStructure->getOriginByName(ToWString(modInfo->name())); + if (m_OrganizerCore.currentProfile()->modEnabled(index)) { + FilesOrigin& origin = m_OrganizerCore.directoryStructure()->getOriginByName(ToWString(modInfo->name())); origin.enable(false); - if (m_DirectoryStructure->originExists(ToWString(modInfo->name()))) { - FilesOrigin& origin = m_DirectoryStructure->getOriginByName(ToWString(modInfo->name())); + if (m_OrganizerCore.directoryStructure()->originExists(ToWString(modInfo->name()))) { + FilesOrigin& origin = m_OrganizerCore.directoryStructure()->getOriginByName(ToWString(modInfo->name())); origin.enable(false); - m_DirectoryRefresher.addModToStructure(m_DirectoryStructure + m_OrganizerCore.directoryRefresher()->addModToStructure(m_OrganizerCore.directoryStructure() , modInfo->name() - , m_CurrentProfile->getModPriority(index) + , m_OrganizerCore.currentProfile()->getModPriority(index) , modInfo->absolutePath() , modInfo->stealFiles() , modInfo->archives()); - DirectoryRefresher::cleanStructure(m_DirectoryStructure); - refreshLists(); + DirectoryRefresher::cleanStructure(m_OrganizerCore.directoryStructure()); + m_OrganizerCore.refreshLists(); } } } @@ -3413,7 +2396,7 @@ void MainWindow::displayModInformation(ModInfo::Ptr modInfo, unsigned int index, void MainWindow::modOpenNext() { - QModelIndex index = m_ModListSortProxy->mapFromSource(m_ModList.index(m_ContextRow, 0)); + QModelIndex index = m_ModListSortProxy->mapFromSource(m_OrganizerCore.modList()->index(m_ContextRow, 0)); index = m_ModListSortProxy->index((index.row() + 1) % m_ModListSortProxy->rowCount(), 0); m_ContextRow = m_ModListSortProxy->mapToSource(index).row(); @@ -3430,7 +2413,7 @@ void MainWindow::modOpenNext() void MainWindow::modOpenPrev() { - QModelIndex index = m_ModListSortProxy->mapFromSource(m_ModList.index(m_ContextRow, 0)); + QModelIndex index = m_ModListSortProxy->mapFromSource(m_OrganizerCore.modList()->index(m_ContextRow, 0)); int row = index.row() - 1; if (row == -1) { row = m_ModListSortProxy->rowCount() - 1; @@ -3473,15 +2456,15 @@ void MainWindow::ignoreMissingData_clicked() ModInfo::Ptr info = ModInfo::getByIndex(m_ContextRow); QDir(info->absolutePath()).mkdir("textures"); info->testValid(); - connect(this, SIGNAL(modListDataChanged(QModelIndex,QModelIndex)), &m_ModList, SIGNAL(dataChanged(QModelIndex,QModelIndex))); + connect(this, SIGNAL(modListDataChanged(QModelIndex,QModelIndex)), m_OrganizerCore.modList(), SIGNAL(dataChanged(QModelIndex,QModelIndex))); - emit modListDataChanged(m_ModList.index(m_ContextRow, 0), m_ModList.index(m_ContextRow, m_ModList.columnCount() - 1)); + emit modListDataChanged(m_OrganizerCore.modList()->index(m_ContextRow, 0), m_OrganizerCore.modList()->index(m_ContextRow, m_OrganizerCore.modList()->columnCount() - 1)); } void MainWindow::visitOnNexus_clicked() { - int modID = m_ModList.data(m_ModList.index(m_ContextRow, 0), Qt::UserRole).toInt(); + int modID = m_OrganizerCore.modList()->data(m_OrganizerCore.modList()->index(m_ContextRow, 0), Qt::UserRole).toInt(); if (modID > 0) { nexusLinkActivated(QString("%1/mods/%2").arg(ToQString(GameInfo::instance().getNexusPage(false))).arg(modID)); } else { @@ -3508,9 +2491,9 @@ void MainWindow::information_clicked() void MainWindow::syncOverwrite() { ModInfo::Ptr modInfo = ModInfo::getByIndex(m_ContextRow); - SyncOverwriteDialog syncDialog(modInfo->absolutePath(), m_DirectoryStructure, this); + SyncOverwriteDialog syncDialog(modInfo->absolutePath(), m_OrganizerCore.directoryStructure(), this); if (syncDialog.exec() == QDialog::Accepted) { - syncDialog.apply(QDir::fromNativeSeparators(m_Settings.getModDirectory())); + syncDialog.apply(QDir::fromNativeSeparators(m_OrganizerCore.settings().getModDirectory())); modInfo->testValid(); refreshDirectoryStructure(); } @@ -3533,12 +2516,12 @@ void MainWindow::createModFromOverwrite() } } - if (getMod(name) != NULL) { + if (m_OrganizerCore.getMod(name) != NULL) { reportError(tr("A mod with this name already exists")); return; } - IModInterface *newMod = createMod(name); + IModInterface *newMod = m_OrganizerCore.createMod(name); if (newMod == NULL) { return; } @@ -3561,7 +2544,7 @@ void MainWindow::on_modList_doubleClicked(const QModelIndex &index) if (!index.isValid()) { return; } - QModelIndex sourceIdx = mapToModel(&m_ModList, index); + QModelIndex sourceIdx = mapToModel(m_OrganizerCore.modList(), index); if (!sourceIdx.isValid()) { return; } @@ -3675,14 +2658,14 @@ void MainWindow::addRemoveCategories_MenuHandler() { if (selected.size() > 0) { foreach (const QPersistentModelIndex &idx, selected) { qDebug("change categories on: %s (ref: %s)", qPrintable(idx.data().toString()), qPrintable(m_ContextIdx.data().toString())); - QModelIndex modIdx = mapToModel(&m_ModList, idx); + QModelIndex modIdx = mapToModel(m_OrganizerCore.modList(), idx); if (modIdx.row() != m_ContextIdx.row()) { addRemoveCategoriesFromMenu(menu, modIdx.row(), m_ContextIdx.row()); } } replaceCategoriesFromMenu(menu, m_ContextIdx.row()); - m_ModList.notifyChange(-1); + m_OrganizerCore.modList()->notifyChange(-1); foreach (const QPersistentModelIndex &idx, selected) { ui->modList->selectionModel()->select(idx, QItemSelectionModel::Select | QItemSelectionModel::Rows); @@ -3690,7 +2673,7 @@ void MainWindow::addRemoveCategories_MenuHandler() { } else { //For single mod selections, just do a replace replaceCategoriesFromMenu(menu, m_ContextRow); - m_ModList.notifyChange(m_ContextRow); + m_OrganizerCore.modList()->notifyChange(m_ContextRow); } refreshFilters(); @@ -3708,12 +2691,12 @@ void MainWindow::replaceCategories_MenuHandler() { if (selected.size() > 0) { QStringList selectedMods; for (int i = 0; i < selected.size(); ++i) { - QModelIndex temp = mapToModel(&m_ModList, selected.at(i)); + QModelIndex temp = mapToModel(m_OrganizerCore.modList(), selected.at(i)); selectedMods.append(temp.data().toString()); - replaceCategoriesFromMenu(menu, mapToModel(&m_ModList, selected.at(i)).row()); + replaceCategoriesFromMenu(menu, mapToModel(m_OrganizerCore.modList(), selected.at(i)).row()); } - m_ModList.notifyChange(-1); + m_OrganizerCore.modList()->notifyChange(-1); // find mods by their name because indices are invalidated QAbstractItemModel *model = ui->modList->model(); @@ -3727,7 +2710,7 @@ void MainWindow::replaceCategories_MenuHandler() { } else { //For single mod selections, just do a replace replaceCategoriesFromMenu(menu, m_ContextRow); - m_ModList.notifyChange(m_ContextRow); + m_OrganizerCore.modList()->notifyChange(m_ContextRow); } refreshFilters(); @@ -3757,6 +2740,33 @@ void MainWindow::savePrimaryCategory() } } +bool MainWindow::saveArchiveList() +{ + if (m_ArchivesInit) { + SafeWriteFile archiveFile(m_OrganizerCore.currentProfile()->getArchivesFileName()); + for (int i = 0; i < ui->bsaList->topLevelItemCount(); ++i) { + QTreeWidgetItem *tlItem = ui->bsaList->topLevelItem(i); + for (int j = 0; j < tlItem->childCount(); ++j) { + QTreeWidgetItem *item = tlItem->child(j); + if (item->checkState(0) == Qt::Checked) { + // in managed mode, "register" all enabled archives, otherwise register only the files registered in the ini + if (ui->manageArchivesBox->isChecked() + || item->data(0, Qt::UserRole).toBool()) { + archiveFile->write(item->text(0).toUtf8().append("\r\n")); + } + } + } + } + if (archiveFile.commitIfDifferent(m_ArchiveListHash)) { + qDebug("%s saved", qPrintable(QDir::toNativeSeparators(m_OrganizerCore.currentProfile()->getArchivesFileName()))); + return true; + } + } else { + qWarning("archive list not initialised"); + } + return false; +} + void MainWindow::checkModsForUpdates() { statusBar()->show(); @@ -3765,8 +2775,8 @@ void MainWindow::checkModsForUpdates() m_RefreshProgress->setRange(0, m_ModsToUpdate); } else { QString username, password; - if (m_Settings.getNexusLogin(username, password)) { - m_PostLoginTasks.push_back(boost::mem_fn(&MainWindow::checkModsForUpdates)); + if (m_OrganizerCore.settings().getNexusLogin(username, password)) { + m_OrganizerCore.doAfterLogin(boost::mem_fn(&MainWindow::checkModsForUpdates)); NexusInterface::instance()->getAccessManager()->login(username, password); } else { // otherwise there will be no endorsement info m_ModsToUpdate = ModInfo::checkAllForUpdate(this); @@ -3891,7 +2901,7 @@ void MainWindow::exportModListCSV() for (unsigned int i = 0; i < numMods; ++i) { ModInfo::Ptr info = ModInfo::getByIndex(i); - bool enabled = m_CurrentProfile->modEnabled(i); + bool enabled = m_OrganizerCore.currentProfile()->modEnabled(i); if ((selection.getChoiceData().toInt() == 1) && !enabled) { continue; } else if ((selection.getChoiceData().toInt() == 2) && !m_ModListSortProxy->filterMatchesMod(info, enabled)) { @@ -3936,7 +2946,7 @@ QMenu *MainWindow::modListContextMenu() menu->addAction(tr("Check all for update"), this, SLOT(checkModsForUpdates())); - menu->addAction(tr("Refresh"), this, SLOT(profileRefresh())); + menu->addAction(tr("Refresh"), &m_OrganizerCore, SLOT(profileRefresh())); menu->addAction(tr("Export to csv..."), this, SLOT(exportModListCSV())); return menu; @@ -3947,7 +2957,7 @@ void MainWindow::on_modList_customContextMenuRequested(const QPoint &pos) try { QTreeView *modList = findChild("modList"); - m_ContextIdx = mapToModel(&m_ModList, modList->indexAt(pos)); + m_ContextIdx = mapToModel(m_OrganizerCore.modList(), modList->indexAt(pos)); m_ContextRow = m_ContextIdx.row(); QMenu *menu = NULL; @@ -4123,7 +3133,7 @@ void MainWindow::fixMods_clicked() for (int i = 0; i < save->numPlugins(); ++i) { const QString &pluginName = save->plugin(i); - if (!m_PluginList.isEnabled(pluginName)) { + if (!m_OrganizerCore.pluginList()->isEnabled(pluginName)) { missingPlugins[pluginName] = std::vector(); } } @@ -4145,8 +3155,8 @@ void MainWindow::fixMods_clicked() } // search in mods - for (unsigned int i = 0; i < m_CurrentProfile->numRegularMods(); ++i) { - int modIndex = m_CurrentProfile->modIndexByPriority(i); + for (unsigned int i = 0; i < m_OrganizerCore.currentProfile()->numRegularMods(); ++i) { + int modIndex = m_OrganizerCore.currentProfile()->modIndexByPriority(i); ModInfo::Ptr modInfo = ModInfo::getByIndex(modIndex); QStringList esps = QDir(modInfo->absolutePath()).entryList(espFilter); @@ -4178,18 +3188,18 @@ void MainWindow::fixMods_clicked() for (std::set::iterator iter = modsToActivate.begin(); iter != modsToActivate.end(); ++iter) { if ((*iter != "") && (*iter != "")) { unsigned int modIndex = ModInfo::getIndex(*iter); - m_CurrentProfile->setModEnabled(modIndex, true); + m_OrganizerCore.currentProfile()->setModEnabled(modIndex, true); } } - m_CurrentProfile->writeModlist(); - refreshLists(); + m_OrganizerCore.currentProfile()->writeModlist(); + m_OrganizerCore.refreshLists(); std::set espsToActivate = dialog.getESPsToActivate(); for (std::set::iterator iter = espsToActivate.begin(); iter != espsToActivate.end(); ++iter) { - m_PluginList.enableESP(*iter); + m_OrganizerCore.pluginList()->enableESP(*iter); } - saveCurrentLists(); + m_OrganizerCore.saveCurrentLists(); } } @@ -4216,7 +3226,7 @@ void MainWindow::on_savegameList_customContextMenuRequested(const QPoint &pos) void MainWindow::linkToolbar() { const Executable &selectedExecutable = ui->executablesListBox->itemData(ui->executablesListBox->currentIndex()).value(); - Executable &exe = m_ExecutablesList.find(selectedExecutable.m_Title); + Executable &exe = m_OrganizerCore.executablesList()->find(selectedExecutable.m_Title); exe.m_Toolbar = !exe.m_Toolbar; ui->linkButton->menu()->actions().at(2)->setIcon(exe.m_Toolbar ? QIcon(":/MO/gui/remove") : QIcon(":/MO/gui/link")); updateToolBar(); @@ -4289,44 +3299,44 @@ void MainWindow::linkMenu() void MainWindow::downloadSpeed(const QString &serverName, int bytesPerSecond) { - m_Settings.setDownloadSpeed(serverName, bytesPerSecond); + m_OrganizerCore.settings().setDownloadSpeed(serverName, bytesPerSecond); } void MainWindow::on_actionSettings_triggered() { - QString oldModDirectory(m_Settings.getModDirectory()); - QString oldCacheDirectory(m_Settings.getCacheDirectory()); - bool oldDisplayForeign(m_Settings.displayForeign()); - bool proxy = m_Settings.useProxy(); - m_Settings.query(this); - m_InstallationManager.setModsDirectory(m_Settings.getModDirectory()); - m_InstallationManager.setDownloadDirectory(m_Settings.getDownloadDirectory()); + QString oldModDirectory(m_OrganizerCore.settings().getModDirectory()); + QString oldCacheDirectory(m_OrganizerCore.settings().getCacheDirectory()); + bool oldDisplayForeign(m_OrganizerCore.settings().displayForeign()); + bool proxy = m_OrganizerCore.settings().useProxy(); + m_OrganizerCore.settings().query(this); + m_OrganizerCore.installationManager()->setModsDirectory(m_OrganizerCore.settings().getModDirectory()); + m_OrganizerCore.installationManager()->setDownloadDirectory(m_OrganizerCore.settings().getDownloadDirectory()); fixCategories(); refreshFilters(); - if (QDir::fromNativeSeparators(m_DownloadManager.getOutputDirectory()) != QDir::fromNativeSeparators(m_Settings.getDownloadDirectory())) { - if (m_DownloadManager.downloadsInProgress()) { + if (QDir::fromNativeSeparators(m_OrganizerCore.downloadManager()->getOutputDirectory()) != QDir::fromNativeSeparators(m_OrganizerCore.settings().getDownloadDirectory())) { + if (m_OrganizerCore.downloadManager()->downloadsInProgress()) { MessageDialog::showMessage(tr("Can't change download directory while downloads are in progress!"), this); } else { - m_DownloadManager.setOutputDirectory(m_Settings.getDownloadDirectory()); + m_OrganizerCore.downloadManager()->setOutputDirectory(m_OrganizerCore.settings().getDownloadDirectory()); } } - m_DownloadManager.setPreferredServers(m_Settings.getPreferredServers()); + m_OrganizerCore.downloadManager()->setPreferredServers(m_OrganizerCore.settings().getPreferredServers()); - if ((m_Settings.getModDirectory() != oldModDirectory) - || (m_Settings.displayForeign() != oldDisplayForeign)) { - profileRefresh(); + if ((m_OrganizerCore.settings().getModDirectory() != oldModDirectory) + || (m_OrganizerCore.settings().displayForeign() != oldDisplayForeign)) { + m_OrganizerCore.profileRefresh(); } - if (m_Settings.getCacheDirectory() != oldCacheDirectory) { - NexusInterface::instance()->setCacheDirectory(m_Settings.getCacheDirectory()); + if (m_OrganizerCore.settings().getCacheDirectory() != oldCacheDirectory) { + NexusInterface::instance()->setCacheDirectory(m_OrganizerCore.settings().getCacheDirectory()); } - if (proxy != m_Settings.useProxy()) { - activateProxy(m_Settings.useProxy()); + if (proxy != m_OrganizerCore.settings().useProxy()) { + activateProxy(m_OrganizerCore.settings().useProxy()); } - NexusInterface::instance()->setNMMVersion(m_Settings.getNMMVersion()); + NexusInterface::instance()->setNMMVersion(m_OrganizerCore.settings().getNMMVersion()); updateDownloadListDelegate(); } @@ -4351,49 +3361,6 @@ void MainWindow::linkClicked(const QString &url) } -bool MainWindow::nexusLogin() -{ - QString username, password; - - NXMAccessManager *accessManager = NexusInterface::instance()->getAccessManager(); - - if (!accessManager->loginAttempted() - && !accessManager->loggedIn() - && (m_Settings.getNexusLogin(username, password) - || (m_AskForNexusPW - && queryLogin(username, password)))) { - accessManager->login(username, password); - return true; - } else { - return false; - } -} - - -void MainWindow::downloadRequestedNXM(const QString &url) -{ - qDebug("download requested: %s", qPrintable(url)); - if (nexusLogin()) { - m_PendingDownloads.append(url); - } else { - m_DownloadManager.addNXMDownload(url); - } -} - - -void MainWindow::downloadRequested(QNetworkReply *reply, int modID, const QString &fileName) -{ - try { - if (m_DownloadManager.addDownload(reply, QStringList(), fileName, modID, 0, new ModRepositoryFileInfo(modID))) { - MessageDialog::showMessage(tr("Download started"), this); - } - } catch (const std::exception &e) { - MessageDialog::showMessage(tr("Download failed"), this); - qCritical("exception starting download: %s", e.what()); - } -} - - void MainWindow::installTranslator(const QString &name) { QTranslator *translator = new QTranslator(this); @@ -4436,8 +3403,8 @@ void MainWindow::languageChange(const QString &newLanguage) void MainWindow::installDownload(int index) { try { - QString fileName = m_DownloadManager.getFilePath(index); - int modID = m_DownloadManager.getModID(index); + QString fileName = m_OrganizerCore.downloadManager()->getFilePath(index); + int modID = m_OrganizerCore.downloadManager()->getModID(index); GuessedValue modName; // see if there already are mods with the specified mod id @@ -4452,15 +3419,15 @@ void MainWindow::installDownload(int index) } } - m_CurrentProfile->writeModlistNow(); + m_OrganizerCore.currentProfile()->writeModlistNow(); bool hasIniTweaks = false; - m_InstallationManager.setModsDirectory(m_Settings.getModDirectory()); - if (m_InstallationManager.install(fileName, modName, hasIniTweaks)) { + m_OrganizerCore.installationManager()->setModsDirectory(m_OrganizerCore.settings().getModDirectory()); + if (m_OrganizerCore.installationManager()->install(fileName, modName, hasIniTweaks)) { MessageDialog::showMessage(tr("Installation successful"), this); refreshModList(); - QModelIndexList posList = m_ModList.match(m_ModList.index(0, 0), Qt::DisplayRole, static_cast(modName)); + QModelIndexList posList = m_OrganizerCore.modList()->match(m_OrganizerCore.modList()->index(0, 0), Qt::DisplayRole, static_cast(modName)); if (posList.count() == 1) { ui->modList->scrollTo(posList.at(0)); } @@ -4479,10 +3446,10 @@ void MainWindow::installDownload(int index) } else { reportError(tr("mod \"%1\" not found").arg(modName)); } - m_DownloadManager.markInstalled(index); + m_OrganizerCore.downloadManager()->markInstalled(index); emit modInstalled(); - } else if (m_InstallationManager.wasCancelled()) { + } else if (m_OrganizerCore.installationManager()->wasCancelled()) { QMessageBox::information(this, tr("Installation cancelled"), tr("The mod was not installed completely."), QMessageBox::Ok); } } catch (const std::exception &e) { @@ -4512,7 +3479,7 @@ void MainWindow::writeDataToFile(QFile &file, const QString &directory, const Di file.write(fullName.toUtf8()); file.write("\t("); - file.write(ToQString(m_DirectoryStructure->getOriginByID(origin).getName()).toUtf8()); + file.write(ToQString(m_OrganizerCore.directoryStructure()->getOriginByID(origin).getName()).toUtf8()); file.write(")\r\n"); } } @@ -4535,7 +3502,7 @@ void MainWindow::writeDataToFile() reportError(tr("failed to write to file %1").arg(fileName)); } - writeDataToFile(file, "data", *m_DirectoryStructure); + writeDataToFile(file, "data", *m_OrganizerCore.directoryStructure()); file.close(); MessageDialog::showMessage(tr("%1 written").arg(QDir::toNativeSeparators(fileName)), this); @@ -4607,9 +3574,9 @@ void MainWindow::addAsExecutable() tr("Please enter a name for the executable"), QLineEdit::Normal, targetInfo.baseName()); if (!name.isEmpty()) { - m_ExecutablesList.addExecutable(name, binaryInfo.absoluteFilePath(), + m_OrganizerCore.executablesList()->addExecutable(name, binaryInfo.absoluteFilePath(), arguments, targetInfo.absolutePath(), - DEFAULT_STAY, QString(), + ExecutableInfo::CloseMOStyle::DEFAULT_STAY, QString(), true, false); refreshExecutablesList(); } @@ -4627,10 +3594,10 @@ void MainWindow::addAsExecutable() void MainWindow::originModified(int originID) { - FilesOrigin &origin = m_DirectoryStructure->getOriginByID(originID); + FilesOrigin &origin = m_OrganizerCore.directoryStructure()->getOriginByID(originID); origin.enable(false); - m_DirectoryStructure->addFromOrigin(origin.getName(), origin.getPath(), origin.getPriority()); - DirectoryRefresher::cleanStructure(m_DirectoryStructure); + m_OrganizerCore.directoryStructure()->addFromOrigin(origin.getName(), origin.getPath(), origin.getPriority()); + DirectoryRefresher::cleanStructure(m_OrganizerCore.directoryStructure()); } @@ -4691,11 +3658,11 @@ void MainWindow::previewDataFile() // what we want is the path relative to the virtual data directory // crude: we search for the next slash after the base mod directory to skip everything up to the data-relative directory - int offset = m_Settings.getModDirectory().size() + 1; + int offset = m_OrganizerCore.settings().getModDirectory().size() + 1; offset = fileName.indexOf("/", offset); fileName = fileName.mid(offset + 1); - const FileEntry::Ptr file = m_DirectoryStructure->searchFile(ToWString(fileName), NULL); + const FileEntry::Ptr file = m_OrganizerCore.directoryStructure()->searchFile(ToWString(fileName), NULL); if (file.get() == NULL) { reportError(tr("file not found: %1").arg(fileName)); @@ -4705,12 +3672,12 @@ void MainWindow::previewDataFile() // set up preview dialog PreviewDialog preview(fileName); auto addFunc = [&] (int originId) { - FilesOrigin &origin = m_DirectoryStructure->getOriginByID(originId); + FilesOrigin &origin = m_OrganizerCore.directoryStructure()->getOriginByID(originId); QString filePath = QDir::fromNativeSeparators(ToQString(origin.getPath())) + "/" + fileName; if (QFile::exists(filePath)) { // it's very possible the file doesn't exist, because it's inside an archive. we don't support that - QWidget *wid = m_PreviewGenerator.genPreview(filePath); - if (wid == NULL) { + QWidget *wid = m_PluginContainer.previewGenerator().genPreview(filePath); + if (wid == nullptr) { reportError(tr("failed to generate preview for %1").arg(filePath)); } else { preview.addVariant(ToQString(origin.getName()), wid); @@ -4737,7 +3704,7 @@ void MainWindow::openDataFile() QString arguments; switch (getBinaryExecuteInfo(targetInfo, binaryInfo, arguments)) { case 1: { - spawnBinaryDirect(binaryInfo, arguments, m_CurrentProfile->getName(), targetInfo.absolutePath(), ""); + spawnBinaryDirect(binaryInfo, arguments, m_OrganizerCore.currentProfile()->getName(), targetInfo.absolutePath(), ""); } break; case 2: { ::ShellExecuteW(NULL, L"open", ToWString(targetInfo.absoluteFilePath()).c_str(), NULL, NULL, SW_SHOWNORMAL); @@ -4769,10 +3736,10 @@ void MainWindow::motdReceived(const QString &motd) // internet connection is faster next time if (m_StartTime.secsTo(QTime::currentTime()) < 5) { uint hash = qHash(motd); - if (hash != m_Settings.getMotDHash()) { + if (hash != m_OrganizerCore.settings().getMotDHash()) { MotDDialog dialog(motd); dialog.exec(); - m_Settings.setMotDHash(hash); + m_OrganizerCore.settings().setMotDHash(hash); } } @@ -4797,7 +3764,7 @@ void MainWindow::on_dataTree_customContextMenuRequested(const QPoint &pos) menu.addAction(tr("Add as Executable"), this, SLOT(addAsExecutable())); QString fileName = m_ContextItem->text(0); - if (m_PreviewGenerator.previewSupported(QFileInfo(fileName).completeSuffix())) { + if (m_PluginContainer.previewGenerator().previewSupported(QFileInfo(fileName).completeSuffix())) { menu.addAction(tr("Preview"), this, SLOT(previewDataFile())); } @@ -4826,11 +3793,7 @@ void MainWindow::on_conflictsCheckBox_toggled(bool) void MainWindow::on_actionUpdate_triggered() { - if (nexusLogin()) { - m_PostLoginTasks.push_back([&](MainWindow*) { m_Updater.startUpdate(); }); - } else { - m_Updater.startUpdate(); - } + m_OrganizerCore.startMOUpdate(); } @@ -4846,16 +3809,22 @@ void MainWindow::on_actionEndorseMO_triggered() void MainWindow::updateDownloadListDelegate() { - if (m_Settings.compactDownloads()) { - ui->downloadView->setItemDelegate(new DownloadListWidgetCompactDelegate(&m_DownloadManager, m_Settings.metaDownloads(), - ui->downloadView, ui->downloadView)); + if (m_OrganizerCore.settings().compactDownloads()) { + ui->downloadView->setItemDelegate( + new DownloadListWidgetCompactDelegate(m_OrganizerCore.downloadManager(), + m_OrganizerCore.settings().metaDownloads(), + ui->downloadView, + ui->downloadView)); } else { - ui->downloadView->setItemDelegate(new DownloadListWidgetDelegate(&m_DownloadManager, m_Settings.metaDownloads(), - ui->downloadView, ui->downloadView)); + ui->downloadView->setItemDelegate( + new DownloadListWidgetDelegate(m_OrganizerCore.downloadManager(), + m_OrganizerCore.settings().metaDownloads(), + ui->downloadView, + ui->downloadView)); } - DownloadListSortProxy *sortProxy = new DownloadListSortProxy(&m_DownloadManager, ui->downloadView); - sortProxy->setSourceModel(new DownloadList(&m_DownloadManager, ui->downloadView)); + DownloadListSortProxy *sortProxy = new DownloadListSortProxy(m_OrganizerCore.downloadManager(), ui->downloadView); + sortProxy->setSourceModel(new DownloadList(m_OrganizerCore.downloadManager(), ui->downloadView)); connect(ui->downloadFilterEdit, SIGNAL(textChanged(QString)), sortProxy, SLOT(updateFilter(QString))); connect(ui->downloadFilterEdit, SIGNAL(textChanged(QString)), this, SLOT(downloadFilterChanged(QString))); @@ -4864,11 +3833,11 @@ void MainWindow::updateDownloadListDelegate() ui->downloadView->header()->resizeSections(QHeaderView::Fixed); connect(ui->downloadView->itemDelegate(), SIGNAL(installDownload(int)), this, SLOT(installDownload(int))); - connect(ui->downloadView->itemDelegate(), SIGNAL(queryInfo(int)), &m_DownloadManager, SLOT(queryInfo(int))); - connect(ui->downloadView->itemDelegate(), SIGNAL(removeDownload(int, bool)), &m_DownloadManager, SLOT(removeDownload(int, bool))); - connect(ui->downloadView->itemDelegate(), SIGNAL(restoreDownload(int)), &m_DownloadManager, SLOT(restoreDownload(int))); - connect(ui->downloadView->itemDelegate(), SIGNAL(cancelDownload(int)), &m_DownloadManager, SLOT(cancelDownload(int))); - connect(ui->downloadView->itemDelegate(), SIGNAL(pauseDownload(int)), &m_DownloadManager, SLOT(pauseDownload(int))); + connect(ui->downloadView->itemDelegate(), SIGNAL(queryInfo(int)), m_OrganizerCore.downloadManager(), SLOT(queryInfo(int))); + connect(ui->downloadView->itemDelegate(), SIGNAL(removeDownload(int, bool)), m_OrganizerCore.downloadManager(), SLOT(removeDownload(int, bool))); + connect(ui->downloadView->itemDelegate(), SIGNAL(restoreDownload(int)), m_OrganizerCore.downloadManager(), SLOT(restoreDownload(int))); + connect(ui->downloadView->itemDelegate(), SIGNAL(cancelDownload(int)), m_OrganizerCore.downloadManager(), SLOT(cancelDownload(int))); + connect(ui->downloadView->itemDelegate(), SIGNAL(pauseDownload(int)), m_OrganizerCore.downloadManager(), SLOT(pauseDownload(int))); connect(ui->downloadView->itemDelegate(), SIGNAL(resumeDownload(int)), this, SLOT(resumeDownload(int))); } @@ -4957,7 +3926,7 @@ void MainWindow::nxmDownloadURLs(int, int, QVariant, QVariant resultData, int) // other keys: ConnectedUsers, Country, URI servers.append(info); } - m_Settings.updateServers(servers); + m_OrganizerCore.settings().updateServers(servers); } @@ -4972,62 +3941,6 @@ void MainWindow::nxmRequestFailed(int modID, int, QVariant, int, const QString & } -void MainWindow::loginSuccessful(bool necessary) -{ - if (necessary) { - MessageDialog::showMessage(tr("login successful"), this); - } - foreach (QString url, m_PendingDownloads) { - downloadRequestedNXM(url); - } - m_PendingDownloads.clear(); - foreach (auto task, m_PostLoginTasks) { - task(this); - } - - m_PostLoginTasks.clear(); - NexusInterface::instance()->loginCompleted(); -} - - -void MainWindow::loginSuccessfulUpdate(bool necessary) -{ - if (necessary) { - MessageDialog::showMessage(tr("login successful"), this); - } - m_Updater.startUpdate(); -} - - -void MainWindow::loginFailed(const QString &message) -{ - if (!m_PendingDownloads.isEmpty()) { - MessageDialog::showMessage(tr("login failed: %1. Trying to download anyway").arg(message), this); - foreach (QString url, m_PendingDownloads) { - downloadRequestedNXM(url); - } - m_PendingDownloads.clear(); - } else { - MessageDialog::showMessage(tr("login failed: %1").arg(message), this); - m_PostLoginTasks.clear(); - statusBar()->hide(); - } - NexusInterface::instance()->loginCompleted(); -} - - -void MainWindow::loginFailedUpdate(const QString &message) -{ - MessageDialog::showMessage(tr("login failed: %1. You need to log-in with Nexus to update MO.").arg(message), this); -} - - -void MainWindow::windowTutorialFinished(const QString &windowName) -{ - m_Settings.directInterface().setValue(QString("CompletedWindowTutorials/") + windowName, true); -} - - BSA::EErrorCode MainWindow::extractBSA(BSA::Archive &archive, BSA::Folder::Ptr folder, const QString &destination, QProgressDialog &progress) { @@ -5085,7 +3998,7 @@ void MainWindow::extractBSATriggered() QString targetFolder = FileDialogMemory::getExistingDirectory("extractBSA", this, tr("Extract BSA")); if (!targetFolder.isEmpty()) { BSA::Archive archive; - QString originPath = QDir::fromNativeSeparators(ToQString(m_DirectoryStructure->getOriginByName(ToWString(item->text(1))).getPath())); + QString originPath = QDir::fromNativeSeparators(ToQString(m_OrganizerCore.directoryStructure()->getOriginByName(ToWString(item->text(1))).getPath())); QString archivePath = QString("%1\\%2").arg(originPath).arg(item->text(0)); BSA::EErrorCode result = archive.read(archivePath.toLocal8Bit().constData(), true); @@ -5166,7 +4079,7 @@ void MainWindow::on_bsaList_itemChanged(QTreeWidgetItem*, int) void MainWindow::on_actionProblems_triggered() { - ProblemsDialog problems(m_DiagnosisPlugins, this); + ProblemsDialog problems(m_PluginContainer.plugins(), this); if (problems.hasProblems()) { problems.exec(); updateProblemsButton(); @@ -5217,10 +4130,10 @@ void MainWindow::updateESPLock(bool locked) QItemSelection currentSelection = ui->espList->selectionModel()->selection(); if (currentSelection.count() == 0) { // this path is probably useless - m_PluginList.lockESPIndex(m_ContextRow, locked); + m_OrganizerCore.pluginList()->lockESPIndex(m_ContextRow, locked); } else { Q_FOREACH (const QModelIndex &idx, currentSelection.indexes()) { - m_PluginList.lockESPIndex(mapToModel(&m_PluginList, idx).row(), locked); + m_OrganizerCore.pluginList()->lockESPIndex(mapToModel(m_OrganizerCore.pluginList(), idx).row(), locked); } } } @@ -5240,7 +4153,7 @@ void MainWindow::unlockESPIndex() void MainWindow::removeFromToolbar() { try { - Executable &exe = m_ExecutablesList.find(m_ContextAction->text()); + Executable &exe = m_OrganizerCore.executablesList()->find(m_ContextAction->text()); exe.m_Toolbar = false; } catch (const std::runtime_error&) { qDebug("executable doesn't exist any more"); @@ -5268,16 +4181,16 @@ void MainWindow::on_espList_customContextMenuRequested(const QPoint &pos) m_ContextRow = m_PluginListSortProxy->mapToSource(ui->espList->indexAt(pos)).row(); QMenu menu; - menu.addAction(tr("Enable all"), &m_PluginList, SLOT(enableAll())); - menu.addAction(tr("Disable all"), &m_PluginList, SLOT(disableAll())); + menu.addAction(tr("Enable all"), m_OrganizerCore.pluginList(), SLOT(enableAll())); + menu.addAction(tr("Disable all"), m_OrganizerCore.pluginList(), SLOT(disableAll())); QItemSelection currentSelection = ui->espList->selectionModel()->selection(); bool hasLocked = false; bool hasUnlocked = false; Q_FOREACH (const QModelIndex &idx, currentSelection.indexes()) { int row = m_PluginListSortProxy->mapToSource(idx).row(); - if (m_PluginList.isEnabled(row)) { - if (m_PluginList.isESPLocked(row)) { + if (m_OrganizerCore.pluginList()->isEnabled(row)) { + if (m_OrganizerCore.pluginList()->isESPLocked(row)) { hasLocked = true; } else { hasUnlocked = true; @@ -5311,11 +4224,11 @@ void MainWindow::on_groupCombo_currentIndexChanged(int index) QAbstractProxyModel *newModel = NULL; switch (index) { case 1: { - newModel = new QtGroupingProxy(&m_ModList, QModelIndex(), ModList::COL_CATEGORY, Qt::UserRole, + newModel = new QtGroupingProxy(m_OrganizerCore.modList(), QModelIndex(), ModList::COL_CATEGORY, Qt::UserRole, 0, Qt::UserRole + 2); } break; case 2: { - newModel = new QtGroupingProxy(&m_ModList, QModelIndex(), ModList::COL_MODID, Qt::DisplayRole, + newModel = new QtGroupingProxy(m_OrganizerCore.modList(), QModelIndex(), ModList::COL_MODID, Qt::DisplayRole, QtGroupingProxy::FLAG_NOGROUPNAME | QtGroupingProxy::FLAG_NOSINGLE, Qt::UserRole + 2); } break; @@ -5333,7 +4246,7 @@ void MainWindow::on_groupCombo_currentIndexChanged(int index) connect(ui->modList, SIGNAL(collapsed(QModelIndex)), newModel, SLOT(collapsed(QModelIndex))); connect(newModel, SIGNAL(expandItem(QModelIndex)), this, SLOT(expandModList(QModelIndex))); } else { - m_ModListSortProxy->setSourceModel(&m_ModList); + m_ModListSortProxy->setSourceModel(m_OrganizerCore.modList()); } modFilterActive(m_ModListSortProxy->isFilterActive()); } @@ -5355,7 +4268,7 @@ void MainWindow::on_linkButton_pressed() void MainWindow::on_showHiddenBox_toggled(bool checked) { - m_DownloadManager.setShowHidden(checked); + m_OrganizerCore.downloadManager()->setShowHidden(checked); } @@ -5421,11 +4334,11 @@ void MainWindow::processLOOTOut(const std::string &lootOut, std::string &reportU if (std::tr1::regex_match(line, match, exRequires)) { std::string modName(match[1].first, match[1].second); std::string dependency(match[2].first, match[2].second); - m_PluginList.addInformation(modName.c_str(), tr("depends on missing \"%1\"").arg(dependency.c_str())); + m_OrganizerCore.pluginList()->addInformation(modName.c_str(), tr("depends on missing \"%1\"").arg(dependency.c_str())); } else if (std::tr1::regex_match(line, match, exIncompatible)) { std::string modName(match[1].first, match[1].second); std::string dependency(match[2].first, match[2].second); - m_PluginList.addInformation(modName.c_str(), tr("incompatible with \"%1\"").arg(dependency.c_str())); + m_OrganizerCore.pluginList()->addInformation(modName.c_str(), tr("incompatible with \"%1\"").arg(dependency.c_str())); } else { qDebug("[loot] %s", line.c_str()); } @@ -5442,8 +4355,8 @@ HANDLE MainWindow::startApplication(const QString &executable, const QStringList QString currentDirectory = cwd; QString profileName = profile; if (profile.length() == 0) { - if (m_CurrentProfile != NULL) { - profileName = m_CurrentProfile->getName(); + if (m_OrganizerCore.currentProfile() != NULL) { + profileName = m_OrganizerCore.currentProfile()->getName(); } else { throw MyException(tr("No profile set")); } @@ -5459,7 +4372,7 @@ HANDLE MainWindow::startApplication(const QString &executable, const QStringList } std::vector::iterator current, end; - m_ExecutablesList.getExecutables(current, end); + m_OrganizerCore.executablesList()->getExecutables(current, end); for (; current != end; ++current) { if (current->m_BinaryInfo == binary) { steamAppID = current->m_SteamAppID; @@ -5473,7 +4386,7 @@ HANDLE MainWindow::startApplication(const QString &executable, const QStringList } else { // only a file name, search executables list try { - const Executable &exe = m_ExecutablesList.find(executable); + const Executable &exe = m_OrganizerCore.executablesList()->find(executable); steamAppID = exe.m_SteamAppID; if (arguments == "") { arguments = exe.m_Arguments; @@ -5555,7 +4468,7 @@ void MainWindow::on_bossButton_clicked() std::string reportURL; std::string errorMessages; - m_CurrentProfile->writeModlistNow(); + m_OrganizerCore.currentProfile()->writeModlistNow(); bool success = false; @@ -5587,8 +4500,8 @@ void MainWindow::on_bossButton_clicked() createStdoutPipe(&stdOutRead, &stdOutWrite); HANDLE loot = startBinary(QFileInfo(qApp->applicationDirPath() + "/loot/lootcli.exe"), parameters.join(" "), - m_CurrentProfile->getName(), - m_Settings.logLevel(), + m_OrganizerCore.currentProfile()->getName(), + m_OrganizerCore.settings().logLevel(), qApp->applicationDirPath() + "/loot", true, stdOutWrite); @@ -5596,7 +4509,7 @@ void MainWindow::on_bossButton_clicked() // we don't use the write end ::CloseHandle(stdOutWrite); - m_PluginList.clearAdditionalInformation(); + m_OrganizerCore.pluginList()->clearAdditionalInformation(); DWORD retLen; JOBOBJECT_BASIC_PROCESS_ID_LIST info; @@ -5669,11 +4582,11 @@ void MainWindow::on_bossButton_clicked() QJsonArray pluginMessages = pluginObj["messages"].toArray(); for (auto msgIter = pluginMessages.begin(); msgIter != pluginMessages.end(); ++msgIter) { QJsonObject msg = (*msgIter).toObject(); - m_PluginList.addInformation(pluginObj["name"].toString(), + m_OrganizerCore.pluginList()->addInformation(pluginObj["name"].toString(), QString("%1: %2").arg(msg["type"].toString(), msg["message"].toString())); } if (pluginObj["dirty"].toString() == "yes") - m_PluginList.addInformation(pluginObj["name"].toString(), "dirty"); + m_OrganizerCore.pluginList()->addInformation(pluginObj["name"].toString(), "dirty"); } } @@ -5708,9 +4621,9 @@ void MainWindow::on_bossButton_clicked() // if the game specifies load order by file time, our own load order file needs to be removed because it's outdated. // refreshESPList will then use the file time as the load order. if (GameInfo::instance().getLoadOrderMechanism() == GameInfo::TYPE_FILETIME) { - QFile::remove(m_CurrentProfile->getLoadOrderFileName()); + QFile::remove(m_OrganizerCore.currentProfile()->getLoadOrderFileName()); } - refreshESPList(); + m_OrganizerCore.refreshESPList(); } } @@ -5734,11 +4647,11 @@ bool MainWindow::createBackup(const QString &filePath, const QDateTime &time) void MainWindow::on_saveButton_clicked() { - savePluginList(); + m_OrganizerCore.savePluginList(); QDateTime now = QDateTime::currentDateTime(); - if (createBackup(m_CurrentProfile->getPluginsFileName(), now) - && createBackup(m_CurrentProfile->getLoadOrderFileName(), now) - && createBackup(m_CurrentProfile->getLockedOrderFileName(), now)) { + if (createBackup(m_OrganizerCore.currentProfile()->getPluginsFileName(), now) + && createBackup(m_OrganizerCore.currentProfile()->getLoadOrderFileName(), now) + && createBackup(m_OrganizerCore.currentProfile()->getLockedOrderFileName(), now)) { MessageDialog::showMessage(tr("Backup of load order created"), this); } } @@ -5775,32 +4688,32 @@ QString MainWindow::queryRestore(const QString &filePath) void MainWindow::on_restoreButton_clicked() { - QString pluginName = m_CurrentProfile->getPluginsFileName(); + QString pluginName = m_OrganizerCore.currentProfile()->getPluginsFileName(); QString choice = queryRestore(pluginName); if (!choice.isEmpty()) { - QString loadOrderName = m_CurrentProfile->getLoadOrderFileName(); - QString lockedName = m_CurrentProfile->getLockedOrderFileName(); + QString loadOrderName = m_OrganizerCore.currentProfile()->getLoadOrderFileName(); + QString lockedName = m_OrganizerCore.currentProfile()->getLockedOrderFileName(); if (!shellCopy(pluginName + "." + choice, pluginName, true, this) || !shellCopy(loadOrderName + "." + choice, loadOrderName, true, this) || !shellCopy(lockedName + "." + choice, lockedName, true, this)) { QMessageBox::critical(this, tr("Restore failed"), tr("Failed to restore the backup. Errorcode: %1").arg(windowsErrorString(::GetLastError()))); } - refreshESPList(); + m_OrganizerCore.refreshESPList(); } } void MainWindow::on_saveModsButton_clicked() { - m_CurrentProfile->writeModlistNow(true); + m_OrganizerCore.currentProfile()->writeModlistNow(true); QDateTime now = QDateTime::currentDateTime(); - if (createBackup(m_CurrentProfile->getModlistFileName(), now)) { + if (createBackup(m_OrganizerCore.currentProfile()->getModlistFileName(), now)) { MessageDialog::showMessage(tr("Backup of modlist created"), this); } } void MainWindow::on_restoreModsButton_clicked() { - QString modlistName = m_CurrentProfile->getModlistFileName(); + QString modlistName = m_OrganizerCore.currentProfile()->getModlistFileName(); QString choice = queryRestore(modlistName); if (!choice.isEmpty()) { if (!shellCopy(modlistName + "." + choice, modlistName, true, this)) { @@ -5845,5 +4758,5 @@ void MainWindow::on_managedArchiveLabel_linkHovered(const QString&) void MainWindow::on_manageArchivesBox_toggled(bool) { - refreshBSAList(); + m_OrganizerCore.refreshBSAList(); } diff --git a/src/mainwindow.h b/src/mainwindow.h index ea79fc37..c8cb8152 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -29,18 +29,16 @@ along with Mod Organizer. If not, see . #include #include #include -#include #include "executableslist.h" #include "modlist.h" #include "pluginlist.h" +#include "plugincontainer.h" #define WIN32_LEAN_AND_MEAN #include #include #include "directoryrefresher.h" #include -#include -#include -#include +#include #include "settings.h" #include "downloadmanager.h" #include "installationmanager.h" @@ -52,6 +50,7 @@ along with Mod Organizer. If not, see . #include "savegameinfowidgetgamebryo.h" #include "previewgenerator.h" #include "browserdialog.h" +#include "iuserinterface.h" #include #include #ifndef Q_MOC_RUN @@ -67,42 +66,24 @@ class ModListSortProxy; class ModListGroupCategoriesProxy; -class MainWindow : public QMainWindow, public MOBase::IPluginDiagnose +class MainWindow : public QMainWindow, public IUserInterface { Q_OBJECT - Q_INTERFACES(MOBase::IPluginDiagnose) friend class OrganizerProxy; -private: - - struct SignalCombinerAnd - { - typedef bool result_type; - template - bool operator()(InputIterator first, InputIterator last) const - { - while (first != last) { - if (!(*first)) { - return false; - } - ++first; - } - return true; - } - }; - - typedef boost::signals2::signal SignalAboutToRunApplication; - typedef boost::signals2::signal SignalModInstalled; public: - explicit MainWindow(const QString &exeName, QSettings &initSettings, QWidget *parent = 0); + explicit MainWindow(const QString &exeName, QSettings &initSettings, + OrganizerCore &organizerCore, PluginContainer &pluginContainer, + QWidget *parent = 0); ~MainWindow(); + void storeSettings(QSettings &settings); void readSettings(); bool addProfile(); - void refreshBSAList(); + void updateBSAList(const QStringList &defaultArchives, const QStringList &activeArchives); void refreshDataTree(); void refreshSaveList(); @@ -116,21 +97,13 @@ public: void createFirstProfile(); -/* void spawnProgram(const QString &fileName, const QString &argumentsArg, - const QString &profileName, const QDir ¤tDirectory);*/ - - void loadPlugins(); + bool saveArchiveList(); - virtual std::vector activeProblems() const; - virtual QString shortDescription(unsigned int key) const; - virtual QString fullDescription(unsigned int key) const; - virtual bool hasGuidedFix(unsigned int key) const; - virtual void startGuidedFix(unsigned int key) const; + void registerPluginTool(MOBase::IPluginTool *tool); + void registerModPage(MOBase::IPluginModPage *modPage); void addPrimaryCategoryCandidates(QMenu *primaryCategoryMenu, ModInfo::Ptr info); - bool saveArchiveList(); - void createStdoutPipe(HANDLE *stdOutRead, HANDLE *stdOutWrite); std::string readFromPipe(HANDLE stdOutRead); void processLOOTOut(const std::string &lootOut, std::string &reportURL, std::string &errorMessages, QProgressDialog &dialog); @@ -141,16 +114,21 @@ public: void updateModInDirectoryStructure(unsigned int index, ModInfo::Ptr modInfo); - QString getOriginDisplayName(int originID); - void unloadPlugins(); -public slots: - void refreshLists(); + void installTranslator(const QString &name); + + virtual void disconnectPlugins(); + + virtual bool close(); + virtual void setEnabled(bool enabled); + + void displayModInformation(ModInfo::Ptr modInfo, unsigned int index, int tab); + +public slots: void displayColumnSelection(const QPoint &pos); - void externalMessage(const QString &message); void modorder_changed(); void refresher_progress(int percent); void directory_refreshed(); @@ -160,11 +138,6 @@ public slots: signals: - /** - * @brief emitted after a mod has been installed - * @node this is currently only used for tutorials - */ - void modInstalled(); /** * @brief emitted after the information dialog has been closed @@ -188,41 +161,28 @@ protected: private: - void refreshESPList(); void refreshModList(bool saveChanges = true); void actionToToolButton(QAction *&sourceAction); - bool verifyPlugin(MOBase::IPlugin *plugin); - void registerPluginTool(MOBase::IPluginTool *tool); - void registerModPage(MOBase::IPluginModPage *modPage); - bool registerPlugin(QObject *pluginObj, const QString &fileName); - bool unregisterPlugin(QObject *pluginObj, const QString &fileName); void updateToolBar(); void activateSelectedProfile(); void setExecutableIndex(int index); - bool testForSteam(); void startSteam(); HANDLE spawnBinaryDirect(const QFileInfo &binary, const QString &arguments, const QString &profileName, const QDir ¤tDirectory, const QString &steamAppID); - void spawnBinary(const QFileInfo &binary, const QString &arguments = "", const QDir ¤tDirectory = QDir(), bool closeAfterStart = true, const QString &steamAppID = ""); void updateTo(QTreeWidgetItem *subTree, const std::wstring &directorySoFar, const MOShared::DirectoryEntry &directoryEntry, bool conflictsOnly); void refreshDirectoryStructure(); bool refreshProfiles(bool selectProfile = true); void refreshExecutablesList(); void installMod(); - MOBase::IModInterface *installMod(const QString &fileName); - MOBase::IModInterface *getMod(const QString &name); - MOBase::IModInterface *createMod(MOBase::GuessedValue &name); - bool removeMod(MOBase::IModInterface *mod); QList findFileInfos(const QString &path, const std::function &filter) const; bool modifyExecutablesDialog(); - void displayModInformation(ModInfo::Ptr modInfo, unsigned int index, int tab); void displayModInformation(int row, int tab = 0); void testExtractBSA(int modIndex); @@ -256,10 +216,6 @@ private: // remove invalid category-references from mods void fixCategories(); - void storeSettings(); - - bool queryLogin(QString &username, QString &password); - void createHelpWidget(); bool extractProgress(QProgressDialog &extractProgress, int percentage, std::string fileName); @@ -288,7 +244,6 @@ private: static void setupNetworkProxy(bool activate); void activateProxy(bool activate); - void installTranslator(const QString &name); void setBrowserGeometry(const QByteArray &geometry); bool createBackup(const QString &filePath, const QDateTime &time); @@ -300,13 +255,8 @@ private: void scheduleUpdateButton(); - void updateModActiveState(int index, bool active); - private: - static const unsigned int PROBLEM_PLUGINSNOTLOADED = 1; - static const unsigned int PROBLEM_TOOMANYPLUGINS = 2; - static const char *PATTERN_BACKUP_GLOB; static const char *PATTERN_BACKUP_REGEX; static const char *PATTERN_BACKUP_DATE; @@ -321,21 +271,15 @@ private: int m_OldProfileIndex; - QThread m_RefresherThread; - DirectoryRefresher m_DirectoryRefresher; - MOShared::DirectoryEntry *m_DirectoryStructure; std::vector m_ModNameList; // the mod-list to go with the directory structure QProgressBar *m_RefreshProgress; bool m_Refreshing; - ModList m_ModList; QAbstractItemModel *m_ModListGroupingProxy; ModListSortProxy *m_ModListSortProxy; - PluginList m_PluginList; PluginListSortProxy *m_PluginListSortProxy; - ExecutablesList m_ExecutablesList; int m_OldExecutableIndex; QString m_GamePath; @@ -347,28 +291,12 @@ private: //int m_SelectedSaveGame; - Settings m_Settings; - - DownloadManager m_DownloadManager; - InstallationManager m_InstallationManager; - - SelfUpdater m_Updater; - CategoryFactory &m_CategoryFactory; - Profile *m_CurrentProfile; - int m_ModsToUpdate; - QStringList m_PendingDownloads; - QList > m_PostLoginTasks; - bool m_AskForNexusPW; bool m_LoginAttempted; - QStringList m_DefaultArchives; - QStringList m_ActiveArchives; - bool m_DirectoryUpdate; - bool m_ArchivesInit; QTimer m_CheckBSATimer; QTimer m_SaveMetaTimer; QTimer m_UpdateProblemsTimer; @@ -376,23 +304,14 @@ private: QTime m_StartTime; SaveGameInfoWidget *m_CurrentSaveView; - MOBase::IGameInfo *m_GameInfo; - - std::vector m_DiagnosisPlugins; - std::vector m_DiagnosisConnections; - std::vector m_ModPages; - std::vector m_FailedPlugins; - std::vector m_PluginLoaders; + OrganizerCore &m_OrganizerCore; + PluginContainer &m_PluginContainer; - QFile m_PluginsCheck; - - SignalAboutToRunApplication m_AboutToRun; - SignalModInstalled m_ModInstalled; + MOBase::IPluginGame *m_ActiveGame; QString m_CurrentLanguage; std::vector m_Translators; - PreviewGenerator m_PreviewGenerator; BrowserDialog m_IntegratedBrowser; QFileSystemWatcher m_SavesWatcher; @@ -447,8 +366,6 @@ private slots: void modStatusChanged(unsigned int index); void saveSelectionChanged(QListWidgetItem *newItem); - bool saveCurrentLists(); - void windowTutorialFinished(const QString &windowName); BSA::EErrorCode extractBSA(BSA::Archive &archive, BSA::Folder::Ptr folder, const QString &destination, QProgressDialog &extractProgress); @@ -457,8 +374,6 @@ private slots: void createModFromOverwrite(); - void removeOrigin(const QString &name); - void procError(QProcess::ProcessError error); void procFinished(int exitCode, QProcess::ExitStatus exitStatus); @@ -466,17 +381,9 @@ private slots: void checkModsForUpdates(); void nexusLinkActivated(const QString &link); - void linkClicked(const QString &url); - - bool nexusLogin(); - - void loginSuccessful(bool necessary); - void loginSuccessfulUpdate(bool necessary); void loginFailed(const QString &message); - void loginFailedUpdate(const QString &message); - void downloadRequestedNXM(const QString &url); - void downloadRequested(QNetworkReply *reply, int modID, const QString &fileName); + void linkClicked(const QString &url); void installDownload(int index); void updateAvailable(); @@ -495,6 +402,8 @@ private slots: void modDetailsUpdated(bool success); void modlistChanged(int row); + void modInstalled(); + void nxmUpdatesAvailable(const std::vector &modIDs, QVariant userData, QVariant resultData, int requestID); void nxmEndorsementToggled(int, QVariant, QVariant resultData, int); void nxmDownloadURLs(int modID, int fileID, QVariant userData, QVariant resultData, int requestID); @@ -527,7 +436,7 @@ private slots: void startExeAction(); - void checkBSAList(); + void checkBSAList(const QStringList &defaultArchives); void updateProblemsButton(); @@ -538,7 +447,6 @@ private slots: void modlistChanged(const QModelIndex &index, int role); void fileMoved(const QString &filePath, const QString &oldOriginName, const QString &newOriginName); - void savePluginList(); void modFilterActive(bool active); void espFilterChanged(const QString &filter); @@ -576,7 +484,6 @@ private slots: void modListSortIndicatorChanged(int column, Qt::SortOrder order); private slots: // ui slots - void profileRefresh(); // actions void on_actionAdd_Profile_triggered(); void on_actionInstallMod_triggered(); @@ -619,6 +526,7 @@ private slots: // ui slots void on_categoriesOrBtn_toggled(bool checked); void on_managedArchiveLabel_linkHovered(const QString &link); void on_manageArchivesBox_toggled(bool checked); + }; diff --git a/src/messagedialog.cpp b/src/messagedialog.cpp index 863d7628..36902bbf 100644 --- a/src/messagedialog.cpp +++ b/src/messagedialog.cpp @@ -82,7 +82,7 @@ void MessageDialog::resizeEvent(QResizeEvent *event) void MessageDialog::showMessage(const QString &text, QWidget *reference, bool bringToFront) { qDebug("%s", qPrintable(text)); - if (reference != NULL) { + if (reference != nullptr) { if (bringToFront || (qApp->activeWindow() != NULL)) { MessageDialog *dialog = new MessageDialog(text, reference); dialog->show(); diff --git a/src/organizer.pro b/src/organizer.pro index fd1e6aad..98dbcd4a 100644 --- a/src/organizer.pro +++ b/src/organizer.pro @@ -94,7 +94,9 @@ SOURCES += \ modflagicondelegate.cpp \ genericicondelegate.cpp \ organizerproxy.cpp \ - viewmarkingscrollbar.cpp + viewmarkingscrollbar.cpp \ + plugincontainer.cpp \ + organizercore.cpp HEADERS += \ @@ -174,7 +176,10 @@ HEADERS += \ modflagicondelegate.h \ genericicondelegate.h \ organizerproxy.h \ - viewmarkingscrollbar.h + viewmarkingscrollbar.h \ + plugincontainer.h \ + organizercore.h \ + iuserinterface.h FORMS += \ transfersavesdialog.ui \ @@ -279,7 +284,7 @@ CONFIG(debug, debug|release) { #QMAKE_CXXFLAGS_WARN_ON -= -W3 #QMAKE_CXXFLAGS_WARN_ON += -W4 -QMAKE_CXXFLAGS += -wd4100 -wd4127 -wd4512 -wd4189 +QMAKE_CXXFLAGS += /wd4100 -wd4127 -wd4512 -wd4189 CONFIG += embed_manifest_exe diff --git a/src/organizercore.cpp b/src/organizercore.cpp new file mode 100644 index 00000000..68989c8c --- /dev/null +++ b/src/organizercore.cpp @@ -0,0 +1,1249 @@ +#include "organizercore.h" +#include "mainwindow.h" +#include "gameinfoimpl.h" +#include "messagedialog.h" +#include "logbuffer.h" +#include "credentialsdialog.h" +#include "filedialogmemory.h" +#include "lockeddialog.h" +#include "modinfodialog.h" +#include "report.h" +#include "spawn.h" +#include "safewritefile.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +using namespace MOShared; +using namespace MOBase; + + +static bool isOnline() +{ + QList interfaces = QNetworkInterface::allInterfaces(); + + bool connected = false; + for (auto iter = interfaces.begin(); iter != interfaces.end() && !connected; ++iter) { + if ( (iter->flags() & QNetworkInterface::IsUp) && + (iter->flags() & QNetworkInterface::IsRunning) && + !(iter->flags() & QNetworkInterface::IsLoopBack)) { + auto addresses = iter->addressEntries(); + if (addresses.count() == 0) { + continue; + } + qDebug("interface %s seems to be up (address: %s)", + qPrintable(iter->humanReadableName()), + qPrintable(addresses[0].ip().toString())); + connected = true; + } + } + + return connected; +} + +static bool renameFile(const QString &oldName, const QString &newName, bool overwrite = true) +{ + if (overwrite && QFile::exists(newName)) { + QFile::remove(newName); + } + return QFile::rename(oldName, newName); +} + +static std::wstring getProcessName(DWORD processId) +{ + HANDLE process = ::OpenProcess(PROCESS_QUERY_INFORMATION, false, processId); + + wchar_t buffer[MAX_PATH]; + if (::GetProcessImageFileNameW(process, buffer, MAX_PATH) != 0) { + wchar_t *fileName = wcsrchr(buffer, L'\\'); + if (fileName == nullptr) { + fileName = buffer; + } else { + fileName += 1; + } + return fileName; + } else { + return std::wstring(L"unknown"); + } +} + +static bool testForSteam() +{ + DWORD processIDs[1024]; + DWORD bytesReturned; + if (!::EnumProcesses(processIDs, sizeof(processIDs), &bytesReturned)) { + qWarning("failed to determine if steam is running"); + return true; + } + + TCHAR processName[MAX_PATH]; + for (unsigned int i = 0; i < bytesReturned / sizeof(DWORD); ++i) { + memset(processName, '\0', sizeof(TCHAR) * MAX_PATH); + if (processIDs[i] != 0) { + HANDLE process = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processIDs[i]); + + if (process != NULL) { + HMODULE module; + DWORD ignore; + + // first module in a process is always the binary + if (::EnumProcessModules(process, &module, sizeof(HMODULE) * 1, &ignore)) { + ::GetModuleBaseName(process, module, processName, MAX_PATH); + if ((_tcsicmp(processName, TEXT("steam.exe")) == 0) || + (_tcsicmp(processName, TEXT("steamservice.exe")) == 0)) { + return true; + } + } + } + } + } + + return false; +} + +static void startSteam(QWidget *widget) +{ + QSettings steamSettings("HKEY_CURRENT_USER\\Software\\Valve\\Steam", QSettings::NativeFormat); + QString exe = steamSettings.value("SteamExe", "").toString(); + if (!exe.isEmpty()) { + QString temp = QString("\"%1\"").arg(exe); + if (!QProcess::startDetached(temp)) { + reportError(QObject::tr("Failed to start \"%1\"").arg(temp)); + } else { + QMessageBox::information(widget, QObject::tr("Waiting"), + QObject::tr("Please press OK once you're logged into steam.")); + } + } +} + +template +QStringList toStringList(InputIterator current, InputIterator end) +{ + QStringList result; + for (; current != end; ++current) { + result.append(*current); + } + return result; +} + + +OrganizerCore::OrganizerCore(const QSettings &initSettings) + : m_GameInfo(new GameInfoImpl()) + , m_UserInterface(nullptr) + , m_PluginContainer(nullptr) + , m_CurrentProfile(nullptr) + , m_Settings() + , m_Updater(NexusInterface::instance()) + , m_AboutToRun() + , m_FinishedRun() + , m_ModInstalled() + , m_ModList(this) + , m_PluginList(this) + , m_DirectoryRefresher() + , m_DirectoryStructure(new DirectoryEntry(L"data", nullptr, 0)) + , m_DownloadManager(NexusInterface::instance(), this) + , m_InstallationManager() + , m_RefresherThread() + , m_AskForNexusPW(false) + , m_DirectoryUpdate(false) + , m_ArchivesInit(false) +{ + m_DownloadManager.setOutputDirectory(m_Settings.getDownloadDirectory()); + m_DownloadManager.setPreferredServers(m_Settings.getPreferredServers()); + + NexusInterface::instance()->setCacheDirectory(m_Settings.getCacheDirectory()); + NexusInterface::instance()->setNMMVersion(m_Settings.getNMMVersion()); + + m_InstallationManager.setModsDirectory(m_Settings.getModDirectory()); + m_InstallationManager.setDownloadDirectory(m_Settings.getDownloadDirectory()); + + connect(&m_DownloadManager, SIGNAL(downloadSpeed(QString,int)), this, SLOT(downloadSpeed(QString,int))); + connect(&m_DirectoryRefresher, SIGNAL(refreshed()), this, SLOT(directory_refreshed())); + + connect(&m_ModList, SIGNAL(removeOrigin(QString)), this, SLOT(removeOrigin(QString))); + + connect(NexusInterface::instance()->getAccessManager(), SIGNAL(loginSuccessful(bool)), this, SLOT(loginSuccessful(bool))); + connect(NexusInterface::instance()->getAccessManager(), SIGNAL(loginFailed(QString)), this, SLOT(loginFailed(QString))); + + ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure, m_Settings.displayForeign()); + + // make directory refresher run in a separate thread + m_RefresherThread.start(); + m_DirectoryRefresher.moveToThread(&m_RefresherThread); + + m_AskForNexusPW = initSettings.value("ask_for_nexuspw", true).toBool(); +} + +OrganizerCore::~OrganizerCore() +{ + m_RefresherThread.exit(); + m_RefresherThread.wait(); + + prepareStart(); + + // profile has to be cleaned up before the modinfo-buffer is cleared + delete m_CurrentProfile; + m_CurrentProfile = nullptr; + + ModInfo::clear(); + LogBuffer::cleanQuit(); + m_ModList.setProfile(nullptr); + NexusInterface::instance()->cleanup(); + + delete m_GameInfo; + delete m_DirectoryStructure; +} + +void OrganizerCore::storeSettings() +{ + QString iniFile = ToQString(GameInfo::instance().getIniFilename()); + shellCopy(iniFile, iniFile + ".new", true, qApp->activeWindow()); + + QSettings::Status result = QSettings::NoError; + { + QSettings settings(iniFile + ".new", QSettings::IniFormat); + if (m_UserInterface != nullptr) { + m_UserInterface->storeSettings(settings); + } + settings.setValue("selected_profile", m_CurrentProfile->getName().toUtf8().constData()); + settings.setValue("ask_for_nexuspw", m_AskForNexusPW); + + settings.remove("customExecutables"); + settings.beginWriteArray("customExecutables"); + std::vector::const_iterator current, end; + m_ExecutablesList.getExecutables(current, end); + int count = 0; + for (; current != end; ++current) { + const Executable &item = *current; + if (item.m_Custom || item.m_Toolbar) { + settings.setArrayIndex(count++); + settings.setValue("binary", item.m_BinaryInfo.absoluteFilePath()); + settings.setValue("title", item.m_Title); + settings.setValue("arguments", item.m_Arguments); + settings.setValue("workingDirectory", item.m_WorkingDirectory); + settings.setValue("closeOnStart", item.m_CloseMO == ExecutableInfo::CloseMOStyle::DEFAULT_CLOSE); + settings.setValue("steamAppID", item.m_SteamAppID); + settings.setValue("custom", item.m_Custom); + settings.setValue("toolbar", item.m_Toolbar); + } + } + settings.endArray(); + + QComboBox *executableBox = findChild("executablesListBox"); + settings.setValue("selected_executable", executableBox->currentIndex()); + + FileDialogMemory::save(settings); + + settings.sync(); + result = settings.status(); + } + if (result == QSettings::NoError) { + if (!shellRename(iniFile + ".new", iniFile, true, qApp->activeWindow())) { + DWORD err = ::GetLastError(); + // make a second attempt using qt functions but if that fails print the error from the first attempt + if (!renameFile(iniFile + ".new", iniFile)) { + QMessageBox::critical(qApp->activeWindow(), tr("Failed to write settings"), + tr("An error occured trying to write back MO settings: %1").arg(windowsErrorString(err))); + } + } + } else { + QString reason = result == QSettings::AccessError ? tr("File is write protected") + : result == QSettings::FormatError ? tr("Invalid file format (probably a bug)") + : tr("Unknown error %1").arg(result); + QMessageBox::critical(qApp->activeWindow(), tr("Failed to write settings"), + tr("An error occured trying to write back MO settings: %1").arg(reason)); + } +} + +void OrganizerCore::updateExecutablesList(QSettings &settings) +{ + m_ExecutablesList.init(m_PluginContainer->managedGame(ToQString(GameInfo::instance().getGameName()))); + + qDebug("setting up configured executables"); + + int numCustomExecutables = settings.beginReadArray("customExecutables"); + for (int i = 0; i < numCustomExecutables; ++i) { + settings.setArrayIndex(i); + ExecutableInfo::CloseMOStyle closeMO = + settings.value("closeOnStart").toBool() ? ExecutableInfo::CloseMOStyle::DEFAULT_CLOSE + : ExecutableInfo::CloseMOStyle::DEFAULT_STAY; + m_ExecutablesList.addExecutable(settings.value("title").toString(), + settings.value("binary").toString(), + settings.value("arguments").toString(), + settings.value("workingDirectory", "").toString(), + closeMO, + settings.value("steamAppID", "").toString(), + settings.value("custom", true).toBool(), + settings.value("toolbar", false).toBool()); + } + + settings.endArray(); +} + +void OrganizerCore::setUserInterface(IUserInterface *userInterface, QWidget *widget) +{ + storeSettings(); + + m_UserInterface = userInterface; + + connect(&m_ModList, SIGNAL(modlist_changed(QModelIndex,int)), widget, SLOT(modorder_changed())); + connect(&m_ModList, SIGNAL(showMessage(QString)), widget, SLOT(showMessage(QString))); + connect(&m_ModList, SIGNAL(modRenamed(QString,QString)), widget, SLOT(modRenamed(QString,QString))); + connect(&m_ModList, SIGNAL(modUninstalled(QString)), widget, SLOT(modRemoved(QString))); + connect(&m_ModList, SIGNAL(modlist_changed(QModelIndex, int)), widget, SLOT(modlistChanged(QModelIndex, int))); + connect(&m_ModList, SIGNAL(removeSelectedMods()), widget, SLOT(removeMod_clicked())); + connect(&m_ModList, SIGNAL(requestColumnSelect(QPoint)), widget, SLOT(displayColumnSelection(QPoint))); + connect(&m_ModList, SIGNAL(fileMoved(QString, QString, QString)), widget, SLOT(fileMoved(QString, QString, QString))); + connect(&m_DownloadManager, SIGNAL(downloadAdded()), widget, SLOT(scrollToBottom())); + connect(&m_DownloadManager, SIGNAL(showMessage(QString)), widget, SLOT(showMessage(QString))); + + m_InstallationManager.setParentWidget(widget); + m_Updater.setUserInterface(widget); + + // this currently wouldn't work reliably if the ui isn't initialized yet to display the result + if (isOnline() && !m_Settings.offlineMode()) { + m_Updater.testForUpdate(); + } else { + qDebug("user doesn't seem to be connected to the internet"); + } +} + +void OrganizerCore::connectPlugins(PluginContainer *container) +{ + m_DownloadManager.setSupportedExtensions(m_InstallationManager.getSupportedExtensions()); + m_PluginContainer = container; +} + +void OrganizerCore::disconnectPlugins() +{ + m_AboutToRun.disconnect_all_slots(); + m_FinishedRun.disconnect_all_slots(); + m_ModInstalled.disconnect_all_slots(); + m_ModList.disconnectSlots(); + m_PluginList.disconnectSlots(); + + m_Settings.clearPlugins(); + m_PluginContainer = nullptr; +} + +Settings &OrganizerCore::settings() +{ + return m_Settings; +} + +bool OrganizerCore::nexusLogin() +{ + QString username, password; + + NXMAccessManager *accessManager = NexusInterface::instance()->getAccessManager(); + + if (!accessManager->loginAttempted() + && !accessManager->loggedIn() + && (m_Settings.getNexusLogin(username, password) + || (m_AskForNexusPW + && queryLogin(username, password)))) { + accessManager->login(username, password); + return true; + } else { + return false; + } +} + +bool OrganizerCore::queryLogin(QString &username, QString &password) +{ + CredentialsDialog dialog(qApp->activeWindow()); + int res = dialog.exec(); + if (dialog.neverAsk()) { + m_AskForNexusPW = false; + } + if (res == QDialog::Accepted) { + username = dialog.username(); + password = dialog.password(); + if (dialog.store()) { + m_Settings.setNexusLogin(username, password); + } + return true; + } else { + return false; + } +} + +void OrganizerCore::startMOUpdate() +{ + if (nexusLogin()) { + m_PostLoginTasks.append([&]() { m_Updater.startUpdate(); }); + } else { + m_Updater.startUpdate(); + } +} + +void OrganizerCore::downloadRequestedNXM(const QString &url) +{ + qDebug("download requested: %s", qPrintable(url)); + if (nexusLogin()) { + m_PendingDownloads.append(url); + } else { + m_DownloadManager.addNXMDownload(url); + } +} + +void OrganizerCore::externalMessage(const QString &message) +{ + if (message.left(6).toLower() == "nxm://") { + MessageDialog::showMessage(tr("Download started"), qApp->activeWindow()); + downloadRequestedNXM(message); + } +} + +void OrganizerCore::downloadRequested(QNetworkReply *reply, int modID, const QString &fileName) +{ + try { + if (m_DownloadManager.addDownload(reply, QStringList(), fileName, modID, 0, new ModRepositoryFileInfo(modID))) { + MessageDialog::showMessage(tr("Download started"), qApp->activeWindow()); + } + } catch (const std::exception &e) { + MessageDialog::showMessage(tr("Download failed"), qApp->activeWindow()); + qCritical("exception starting download: %s", e.what()); + } +} + +void OrganizerCore::removeOrigin(const QString &name) +{ + FilesOrigin &origin = m_DirectoryStructure->getOriginByName(ToWString(name)); + origin.enable(false); + refreshLists(); +} + +InstallationManager *OrganizerCore::installationManager() +{ + return &m_InstallationManager; +} + +void OrganizerCore::setCurrentProfile(Profile *profile) { + delete m_CurrentProfile; + m_CurrentProfile = profile; + m_ModList.setProfile(profile); +} + +MOBase::IGameInfo &OrganizerCore::gameInfo() const +{ + return *m_GameInfo; +} + +MOBase::IModRepositoryBridge *OrganizerCore::createNexusBridge() const +{ + return new NexusBridge(); +} + +QString OrganizerCore::profileName() const +{ + if (m_CurrentProfile != NULL) { + return m_CurrentProfile->getName(); + } else { + return ""; + } +} + +QString OrganizerCore::profilePath() const +{ + if (m_CurrentProfile != NULL) { + return m_CurrentProfile->getPath(); + } else { + return ""; + } +} + +QString OrganizerCore::downloadsPath() const +{ + return QDir::fromNativeSeparators(m_Settings.getDownloadDirectory()); +} + +MOBase::VersionInfo OrganizerCore::appVersion() const +{ + return m_Updater.getVersion(); +} + +MOBase::IModInterface *OrganizerCore::getMod(const QString &name) +{ + unsigned int index = ModInfo::getIndex(name); + if (index == UINT_MAX) { + return NULL; + } else { + return ModInfo::getByIndex(index).data(); + } +} + +MOBase::IModInterface *OrganizerCore::createMod(GuessedValue &name) +{ + if (!m_InstallationManager.testOverwrite(name)) { + return NULL; + } + + m_InstallationManager.setModsDirectory(m_Settings.getModDirectory()); + + QString targetDirectory = QDir::fromNativeSeparators(m_Settings.getModDirectory()).append("/").append(name); + + QSettings settingsFile(targetDirectory.mid(0).append("/meta.ini"), QSettings::IniFormat); + + settingsFile.setValue("modid", 0); + settingsFile.setValue("version", ""); + settingsFile.setValue("newestVersion", ""); + settingsFile.setValue("category", 0); + settingsFile.setValue("installationFile", ""); + return ModInfo::createFrom(QDir(targetDirectory), &m_DirectoryStructure).data(); +} + +bool OrganizerCore::removeMod(MOBase::IModInterface *mod) +{ + unsigned int index = ModInfo::getIndex(mod->name()); + if (index == UINT_MAX) { + return mod->remove(); + } else { + return ModInfo::removeMod(index); + } +} + +void OrganizerCore::modDataChanged(MOBase::IModInterface *mod) +{ + refreshModList(false); +} + +QVariant OrganizerCore::pluginSetting(const QString &pluginName, const QString &key) const +{ + return m_Settings.pluginSetting(pluginName, key); +} + +void OrganizerCore::setPluginSetting(const QString &pluginName, const QString &key, const QVariant &value) +{ + m_Settings.setPluginSetting(pluginName, key, value); +} + +QVariant OrganizerCore::persistent(const QString &pluginName, const QString &key, const QVariant &def) const +{ + return m_Settings.pluginPersistent(pluginName, key, def); +} + +void OrganizerCore::setPersistent(const QString &pluginName, const QString &key, const QVariant &value, bool sync) +{ + m_Settings.setPluginPersistent(pluginName, key, value, sync); +} + +QString OrganizerCore::pluginDataPath() const +{ + QString pluginPath = QDir::fromNativeSeparators(ToQString(GameInfo::instance().getOrganizerDirectory())) + "/" + ToQString(AppConfig::pluginPath()); + return pluginPath + "/data"; +} + +MOBase::IModInterface *OrganizerCore::installMod(const QString &fileName) +{ + if (m_CurrentProfile == nullptr) { + return nullptr; + } + + bool hasIniTweaks = false; + GuessedValue modName; + m_CurrentProfile->writeModlistNow(); + m_InstallationManager.setModsDirectory(m_Settings.getModDirectory()); + if (m_InstallationManager.install(fileName, modName, hasIniTweaks)) { + MessageDialog::showMessage(tr("Installation successful"), qApp->activeWindow()); + refreshModList(); + + int modIndex = ModInfo::getIndex(modName); + if (modIndex != UINT_MAX) { + ModInfo::Ptr modInfo = ModInfo::getByIndex(modIndex); + if (hasIniTweaks + && (m_UserInterface != nullptr) + && (QMessageBox::question(qApp->activeWindow(), tr("Configure Mod"), + tr("This mod contains ini tweaks. Do you want to configure them now?"), + QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)) { + m_UserInterface->displayModInformation(modInfo, modIndex, ModInfoDialog::TAB_INIFILES); + } + m_ModInstalled(modName); + return modInfo.data(); + } else { + reportError(tr("mod \"%1\" not found").arg(modName)); + } + } else if (m_InstallationManager.wasCancelled()) { + QMessageBox::information(qApp->activeWindow(), tr("Installation cancelled"), + tr("The mod was not installed completely."), QMessageBox::Ok); + } + return nullptr; +} + +QString OrganizerCore::resolvePath(const QString &fileName) const +{ + if (m_DirectoryStructure == nullptr) { + return QString(); + } + const FileEntry::Ptr file = m_DirectoryStructure->searchFile(ToWString(fileName), nullptr); + if (file.get() != nullptr) { + return ToQString(file->getFullPath()); + } else { + return QString(); + } +} + +QStringList OrganizerCore::listDirectories(const QString &directoryName) const +{ + QStringList result; + DirectoryEntry *dir = m_DirectoryStructure->findSubDirectoryRecursive(ToWString(directoryName)); + if (dir != NULL) { + std::vector::iterator current, end; + dir->getSubDirectories(current, end); + for (; current != end; ++current) { + result.append(ToQString((*current)->getName())); + } + } + return result; +} + +QStringList OrganizerCore::findFiles(const QString &path, const std::function &filter) const +{ + QStringList result; + DirectoryEntry *dir = m_DirectoryStructure->findSubDirectoryRecursive(ToWString(path)); + if (dir != NULL) { + std::vector files = dir->getFiles(); + foreach (FileEntry::Ptr file, files) { + if (filter(ToQString(file->getFullPath()))) { + result.append(ToQString(file->getFullPath())); + } + } + } else { + qWarning("directory %s not found", qPrintable(path)); + } + return result; +} + +QStringList OrganizerCore::getFileOrigins(const QString &fileName) const +{ + QStringList result; + const FileEntry::Ptr file = m_DirectoryStructure->searchFile(ToWString(QFileInfo(fileName).fileName()), NULL); + + if (file.get() != NULL) { + result.append(ToQString(m_DirectoryStructure->getOriginByID(file->getOrigin()).getName())); + foreach (int i, file->getAlternatives()) { + result.append(ToQString(m_DirectoryStructure->getOriginByID(i).getName())); + } + } else { + qDebug("%s not found", qPrintable(fileName)); + } + return result; +} + +QList OrganizerCore::findFileInfos(const QString &path, const std::function &filter) const +{ + QList result; + DirectoryEntry *dir = m_DirectoryStructure->findSubDirectoryRecursive(ToWString(path)); + if (dir != NULL) { + std::vector files = dir->getFiles(); + foreach (FileEntry::Ptr file, files) { + IOrganizer::FileInfo info; + info.filePath = ToQString(file->getFullPath()); + bool fromArchive = false; + info.origins.append(ToQString(m_DirectoryStructure->getOriginByID(file->getOrigin(fromArchive)).getName())); + info.archive = fromArchive ? ToQString(file->getArchive()) : ""; + foreach (int idx, file->getAlternatives()) { + info.origins.append(ToQString(m_DirectoryStructure->getOriginByID(idx).getName())); + } + + if (filter(info)) { + result.append(info); + } + } + } + return result; +} + +DownloadManager *OrganizerCore::downloadManager() +{ + return &m_DownloadManager; +} + +PluginList *OrganizerCore::pluginList() +{ + return &m_PluginList; +} + +ModList *OrganizerCore::modList() +{ + return &m_ModList; +} + +void OrganizerCore::spawnBinary(const QFileInfo &binary, const QString &arguments, const QDir ¤tDirectory, bool closeAfterStart, const QString &steamAppID) +{ + LockedDialog *dialog = new LockedDialog(qApp->activeWindow()); + dialog->show(); + ON_BLOCK_EXIT([&] () { dialog->hide(); dialog->deleteLater(); }); + + HANDLE processHandle = spawnBinaryDirect(binary, arguments, m_CurrentProfile->getName(), currentDirectory, steamAppID); + if (processHandle != INVALID_HANDLE_VALUE) { + if (closeAfterStart && (m_UserInterface != nullptr)) { + m_UserInterface->close(); + } else { + if (m_UserInterface != nullptr) { + m_UserInterface->setEnabled(false); + } + // re-enable the locked dialog because what'd be the point otherwise? + dialog->setEnabled(true); + + QCoreApplication::processEvents(); + + DWORD processExitCode; + DWORD retLen; + JOBOBJECT_BASIC_PROCESS_ID_LIST info; + + { + DWORD currentProcess = 0UL; + bool isJobHandle = true; + + DWORD res = ::MsgWaitForMultipleObjects(1, &processHandle, false, 1000, QS_KEY | QS_MOUSE); + while ((res != WAIT_FAILED) && (res != WAIT_OBJECT_0) && !dialog->unlockClicked()) { + if (isJobHandle) { + if (::QueryInformationJobObject(processHandle, JobObjectBasicProcessIdList, &info, sizeof(info), &retLen) > 0) { + if (info.NumberOfProcessIdsInList == 0) { + break; + } else { + if (info.ProcessIdList[0] != currentProcess) { + currentProcess = info.ProcessIdList[0]; + dialog->setProcessName(ToQString(getProcessName(currentProcess))); + } + } + } else { + // the info-object I passed only provides space for 1 process id. but since this code only cares about whether there + // is more than one that's good enough. ERROR_MORE_DATA simply signals there are at least two processes running. + // any other error probably means the handle is a regular process handle, probably caused by running MO in a job without + // the right to break out. + if (::GetLastError() != ERROR_MORE_DATA) { + isJobHandle = false; + } + } + } + + // keep processing events so the app doesn't appear dead + QCoreApplication::processEvents(); + + res = ::MsgWaitForMultipleObjects(1, &processHandle, false, 1000, QS_KEY | QS_MOUSE); + } + ::GetExitCodeProcess(processHandle, &processExitCode); + } + ::CloseHandle(processHandle); + + if (m_UserInterface != nullptr) { + m_UserInterface->setEnabled(true); + } + refreshDirectoryStructure(); + // need to remove our stored load order because it may be outdated if a foreign tool changed the + // file time. After removing that file, refreshESPList will use the file time as the order + if (GameInfo::instance().getLoadOrderMechanism() == GameInfo::TYPE_FILETIME) { + QFile::remove(m_CurrentProfile->getLoadOrderFileName()); + refreshESPList(); + } + + m_FinishedRun(binary.absoluteFilePath(), processExitCode); + } + } +} + +HANDLE OrganizerCore::spawnBinaryDirect(const QFileInfo &binary, const QString &arguments, const QString &profileName, + const QDir ¤tDirectory, const QString &steamAppID) +{ + prepareStart(); + + if (!binary.exists()) { + reportError(tr("Executable \"%1\" not found").arg(binary.fileName())); + return INVALID_HANDLE_VALUE; + } + + if (!steamAppID.isEmpty()) { + ::SetEnvironmentVariableW(L"SteamAPPId", ToWString(steamAppID).c_str()); + } else { + ::SetEnvironmentVariableW(L"SteamAPPId", ToWString(m_Settings.getSteamAppID()).c_str()); + } + + if ((GameInfo::instance().requiresSteam()) + && (m_Settings.getLoadMechanism() == LoadMechanism::LOAD_MODORGANIZER)) { + if (!testForSteam()) { + QWidget *window = qApp->activeWindow(); + if ((window != nullptr) && (!window->isVisible())) { + window = nullptr; + } + if (QuestionBoxMemory::query(window, "steamQuery", + tr("Start Steam?"), + tr("Steam is required to be running already to correctly start the game. " + "Should MO try to start steam now?"), + QDialogButtonBox::Yes | QDialogButtonBox::No) == QDialogButtonBox::Yes) { + startSteam(qApp->activeWindow()); + } + } + } + + while (m_DirectoryUpdate) { + ::Sleep(100); + QCoreApplication::processEvents(); + } + + // need to make sure all data is saved before we start the application + if (m_CurrentProfile != nullptr) { + m_CurrentProfile->writeModlistNow(true); + } + + // TODO: should also pass arguments + if (m_AboutToRun(binary.absoluteFilePath())) { + return startBinary(binary, arguments, profileName, m_Settings.logLevel(), currentDirectory, true); + } else { + qDebug("start of \"%s\" canceled by plugin", qPrintable(binary.absoluteFilePath())); + return INVALID_HANDLE_VALUE; + } +} + +HANDLE OrganizerCore::startApplication(const QString &executable, const QStringList &args, const QString &cwd, const QString &profile) +{ + if (m_UserInterface != nullptr) { + return m_UserInterface->startApplication(executable, args, cwd, profile); + } +} + +bool OrganizerCore::waitForApplication(HANDLE handle, LPDWORD exitCode) const +{ + if (m_UserInterface != nullptr) { + return m_UserInterface->waitForProcessOrJob(handle, exitCode); + } +} + +bool OrganizerCore::onAboutToRun(const std::function &func) +{ + auto conn = m_AboutToRun.connect(func); + return conn.connected(); +} + +bool OrganizerCore::onFinishedRun(const std::function &func) +{ + auto conn = m_FinishedRun.connect(func); + return conn.connected(); +} + +bool OrganizerCore::onModInstalled(const std::function &func) +{ + auto conn = m_ModInstalled.connect(func); + return conn.connected(); +} + +void OrganizerCore::refreshModList(bool saveChanges) +{ + // don't lose changes! + if (saveChanges) { + m_CurrentProfile->writeModlistNow(true); + } + ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure, m_Settings.displayForeign()); + + m_CurrentProfile->refreshModStatus(); + + m_ModList.notifyChange(-1); + + refreshDirectoryStructure(); +} + +void OrganizerCore::refreshESPList() +{ + m_CurrentProfile->writeModlist(); + + // clear list + try { + m_PluginList.refresh(m_CurrentProfile->getName(), + *m_DirectoryStructure, + m_CurrentProfile->getPluginsFileName(), + m_CurrentProfile->getLoadOrderFileName(), + m_CurrentProfile->getLockedOrderFileName()); + } catch (const std::exception &e) { + reportError(tr("Failed to refresh list of esps: %1").arg(e.what())); + } +} + + +void OrganizerCore::refreshBSAList() +{ + m_ArchivesInit = false; + + m_DefaultArchives.clear(); + + wchar_t buffer[256]; + std::wstring iniFileName = ToWString(QDir::toNativeSeparators(m_CurrentProfile->getIniFileName())); + if (::GetPrivateProfileStringW(L"Archive", GameInfo::instance().archiveListKey().c_str(), + L"", buffer, 256, iniFileName.c_str()) != 0) { + m_DefaultArchives = ToQString(buffer).split(','); + } else { + std::vector vanillaBSAs = GameInfo::instance().getVanillaBSAs(); + for (auto iter = vanillaBSAs.begin(); iter != vanillaBSAs.end(); ++iter) { + m_DefaultArchives.append(ToQString(*iter)); + } + } + + if (::GetPrivateProfileStringW(L"Archive", GameInfo::instance().archiveListKey().append(L"2").c_str(), + L"", buffer, 256, iniFileName.c_str()) != 0) { + m_DefaultArchives.append(ToQString(buffer).split(',')); + } + + for (int i = 0; i < m_DefaultArchives.count(); ++i) { + m_DefaultArchives[i] = m_DefaultArchives[i].trimmed(); + } + + m_ActiveArchives.clear(); + + auto iter = enabledArchives(); + m_ActiveArchives = toStringList(iter.begin(), iter.end()); + if (m_ActiveArchives.isEmpty()) { + m_ActiveArchives = m_DefaultArchives; + } + + if (m_UserInterface != nullptr) { + m_UserInterface->updateBSAList(); + } + + m_ArchivesInit = true; +} + +void OrganizerCore::refreshLists() +{ + if ((m_CurrentProfile != nullptr) && m_DirectoryStructure->isPopulated()) { + refreshESPList(); + refreshBSAList(); + } // no point in refreshing lists if no files have been added to the directory tree +} + +void OrganizerCore::updateModActiveState(int index, bool active) +{ + ModInfo::Ptr modInfo = ModInfo::getByIndex(index); + + QDir dir(modInfo->absolutePath()); + foreach (const QString &esm, dir.entryList(QStringList("*.esm"), QDir::Files)) { + m_PluginList.enableESP(esm, active); + } + int enabled = 0; + QStringList esps = dir.entryList(QStringList("*.esp"), QDir::Files); + foreach (const QString &esp, esps) { + if (active != m_PluginList.isEnabled(esp)) { + m_PluginList.enableESP(esp, active); + ++enabled; + } + } + if (active && (enabled > 1)) { + MessageDialog::showMessage(tr("Multiple esps activated, please check that they don't conflict."), qApp->activeWindow()); + } + m_PluginList.refreshLoadOrder(); + // immediately save affected lists + savePluginList(); +// refreshBSAList(); +} + +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() + ); + DirectoryRefresher::cleanStructure(m_DirectoryStructure); + // need to refresh plugin list now so we can activate esps + refreshESPList(); + // activate all esps of the specified mod so the bsas get activated along with it + updateModActiveState(index, true); + // now we need to refresh the bsa list and save it so there is no confusion about what archives are avaiable and active + refreshBSAList(); + if (m_UserInterface != nullptr) { + m_UserInterface->saveArchiveList(); + } + m_DirectoryRefresher.setMods(m_CurrentProfile->getActiveMods(), enabledArchives()); + + // 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() + ); +} + +void OrganizerCore::requestDownload(const QUrl &url, QNetworkReply *reply) +{ + if (m_PluginContainer != nullptr) { + for (IPluginModPage *modPage : m_PluginContainer->plugins()) { + ModRepositoryFileInfo *fileInfo = new ModRepositoryFileInfo(); + if (modPage->handlesDownload(url, reply->url(), *fileInfo)) { + fileInfo->repository = modPage->name(); + m_DownloadManager.addDownload(reply, fileInfo); + return; + } + } + } + + // no mod found that could handle the download. Is it a nexus mod? + if (url.host() == "www.nexusmods.com") { + int modID = 0; + int fileID = 0; + QRegExp modExp("mods/(\\d+)"); + if (modExp.indexIn(url.toString()) != -1) { + modID = modExp.cap(1).toInt(); + } + QRegExp fileExp("fid=(\\d+)"); + if (fileExp.indexIn(reply->url().toString()) != -1) { + fileID = fileExp.cap(1).toInt(); + } + m_DownloadManager.addDownload(reply, new ModRepositoryFileInfo(modID, fileID)); + } else { + if (QMessageBox::question(qApp->activeWindow(), tr("Download?"), + tr("A download has been started but no installed page plugin recognizes it.\n" + "If you download anyway no information (i.e. version) will be associated with the download.\n" + "Continue?"), + QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { + m_DownloadManager.addDownload(reply, new ModRepositoryFileInfo()); + } + } +} + +ModListSortProxy *OrganizerCore::createModListProxyModel() +{ + ModListSortProxy *result = new ModListSortProxy(m_CurrentProfile, this); + result->setSourceModel(&m_ModList); + return result; +} + +PluginListSortProxy *OrganizerCore::createPluginListProxyModel() +{ + PluginListSortProxy *result = new PluginListSortProxy(this); + result->setSourceModel(&m_PluginList); + return result; +} + +std::set OrganizerCore::enabledArchives() +{ + std::set result; + QFile archiveFile(m_CurrentProfile->getArchivesFileName()); + if (archiveFile.open(QIODevice::ReadOnly)) { + while (!archiveFile.atEnd()) { + result.insert(QString::fromUtf8(archiveFile.readLine()).trimmed()); + } + archiveFile.close(); + } + return result; +} + +void OrganizerCore::refreshDirectoryStructure() +{ + if (!m_DirectoryUpdate) { + m_CurrentProfile->writeModlistNow(true); + + m_DirectoryUpdate = true; + std::vector > activeModList = m_CurrentProfile->getActiveMods(); + + m_DirectoryRefresher.setMods(activeModList, enabledArchives()); + + QTimer::singleShot(0, &m_DirectoryRefresher, SLOT(refresh())); + } else { + qDebug("directory update"); + } +} + +void OrganizerCore::directory_refreshed() +{ + DirectoryEntry *newStructure = m_DirectoryRefresher.getDirectoryStructure(); + Q_ASSERT(newStructure != m_DirectoryStructure); + if (newStructure != nullptr) { + std::swap(m_DirectoryStructure, newStructure); + delete newStructure; + } else { + // TODO: don't know why this happens, this slot seems to get called twice with only one emit + return; + } + m_DirectoryUpdate = false; + if (m_CurrentProfile != nullptr) { + refreshLists(); + } + + for (int i = 0; i < m_ModList.rowCount(); ++i) { + ModInfo::Ptr modInfo = ModInfo::getByIndex(i); + modInfo->clearCaches(); + } +} + +void OrganizerCore::profileRefresh() +{ + // have to refresh mods twice (again in refreshModList), otherwise the refresh isn't complete. Not sure why + ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure, m_Settings.displayForeign()); + m_CurrentProfile->refreshModStatus(); + + refreshModList(); +} + +void OrganizerCore::modStatusChanged(unsigned int index) +{ + try { + ModInfo::Ptr modInfo = ModInfo::getByIndex(index); + if (m_CurrentProfile->modEnabled(index)) { + updateModInDirectoryStructure(index, modInfo); + } else { + updateModActiveState(index, false); + refreshESPList(); + if (m_DirectoryStructure->originExists(ToWString(modInfo->name()))) { + FilesOrigin &origin = m_DirectoryStructure->getOriginByName(ToWString(modInfo->name())); + origin.enable(false); + } + } + modInfo->clearCaches(); + + 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) { + MessageDialog::showMessage(tr("login successful"), qApp->activeWindow()); + } + foreach (QString url, m_PendingDownloads) { + downloadRequestedNXM(url); + } + m_PendingDownloads.clear(); + for (auto task : m_PostLoginTasks) { + task(); + } + + m_PostLoginTasks.clear(); + NexusInterface::instance()->loginCompleted(); +} + +void OrganizerCore::loginSuccessfulUpdate(bool necessary) +{ + if (necessary) { + MessageDialog::showMessage(tr("login successful"), qApp->activeWindow()); + } + m_Updater.startUpdate(); +} + +void OrganizerCore::loginFailed(const QString &message) +{ + if (!m_PendingDownloads.isEmpty()) { + MessageDialog::showMessage(tr("login failed: %1. Trying to download anyway").arg(message), qApp->activeWindow()); + foreach (QString url, m_PendingDownloads) { + downloadRequestedNXM(url); + } + m_PendingDownloads.clear(); + } else { + MessageDialog::showMessage(tr("login failed: %1").arg(message), qApp->activeWindow()); + m_PostLoginTasks.clear(); + } + NexusInterface::instance()->loginCompleted(); +} + + +void OrganizerCore::loginFailedUpdate(const QString &message) +{ + MessageDialog::showMessage(tr("login failed: %1. You need to log-in with Nexus to update MO.").arg(message), qApp->activeWindow()); +} + + +std::vector OrganizerCore::activeProblems() const +{ + std::vector problems; + if (enabledCount() > 255) { + problems.push_back(PROBLEM_TOOMANYPLUGINS); + } + return problems; +} + +QString OrganizerCore::shortDescription(unsigned int key) const +{ + switch (key) { + case PROBLEM_TOOMANYPLUGINS: { + return tr("Too many esps and esms enabled"); + } break; + default: { + return tr("Description missing"); + } break; + } +} + +QString OrganizerCore::fullDescription(unsigned int key) const +{ + switch (key) { + case PROBLEM_TOOMANYPLUGINS: { + return tr("The game doesn't allow more than 255 active plugins (including the official ones) to be loaded. You have to disable some unused plugins or " + "merge some plugins into one. You can find a guide here: http://wiki.step-project.com/Guide:Merging_Plugins"); + } break; + default: { + return tr("Description missing"); + } break; + } +} + +bool OrganizerCore::hasGuidedFix(unsigned int) const +{ + return false; +} + +void OrganizerCore::startGuidedFix(unsigned int) const +{ +} + +bool OrganizerCore::saveCurrentLists() +{ + if (m_DirectoryUpdate) { + qWarning("not saving lists during directory update"); + return false; + } + + try { + savePluginList(); + if (m_UserInterface != nullptr) { + m_UserInterface->saveArchiveList(); + } + } catch (const std::exception &e) { + reportError(tr("failed to save load order: %1").arg(e.what())); + } + + return true; +} + +void OrganizerCore::savePluginList() +{ + m_PluginList.saveTo(m_CurrentProfile->getPluginsFileName(), + m_CurrentProfile->getLoadOrderFileName(), + m_CurrentProfile->getLockedOrderFileName(), + m_CurrentProfile->getDeleterFileName(), + m_Settings.hideUncheckedPlugins()); + m_PluginList.saveLoadOrder(*m_DirectoryStructure); +} + +void OrganizerCore::prepareStart() { + if (m_CurrentProfile == nullptr) { + return; + } + m_CurrentProfile->writeModlist(); + m_CurrentProfile->createTweakedIniFile(); + saveCurrentLists(); + m_Settings.setupLoadMechanism(); + storeSettings(); +} + diff --git a/src/organizercore.h b/src/organizercore.h new file mode 100644 index 00000000..b362a002 --- /dev/null +++ b/src/organizercore.h @@ -0,0 +1,239 @@ +#ifndef ORGANIZERCORE_H +#define ORGANIZERCORE_H + + +#include "profile.h" +#include "selfupdater.h" +#include "iuserinterface.h" +#include "settings.h" +#include "modlist.h" +#include "pluginlist.h" +#include "directoryrefresher.h" +#include "installationmanager.h" +#include "downloadmanager.h" +#include "modlistsortproxy.h" +#include "pluginlistsortproxy.h" +#include "executableslist.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +class PluginContainer; + + +class OrganizerCore : public QObject, public MOBase::IPluginDiagnose +{ + + Q_OBJECT + Q_INTERFACES(MOBase::IPluginDiagnose) + +private: + + struct SignalCombinerAnd + { + typedef bool result_type; + template + bool operator()(InputIterator first, InputIterator last) const + { + while (first != last) { + if (!(*first)) { + return false; + } + ++first; + } + return true; + } + }; + +private: + + typedef boost::signals2::signal SignalAboutToRunApplication; + typedef boost::signals2::signal SignalFinishedRunApplication; + typedef boost::signals2::signal SignalModInstalled; + +public: + + OrganizerCore(const QSettings &initSettings); + + ~OrganizerCore(); + + void setUserInterface(IUserInterface *userInterface, QWidget *widget); + void connectPlugins(PluginContainer *container); + void disconnectPlugins(); + + void updateExecutablesList(QSettings &settings); + + void startMOUpdate(); + + Settings &settings(); + SelfUpdater *updater() { return &m_Updater; } + InstallationManager *installationManager(); + MOShared::DirectoryEntry *directoryStructure() { return m_DirectoryStructure; } + DirectoryRefresher *directoryRefresher() { return &m_DirectoryRefresher; } + ExecutablesList *executablesList() { return &m_ExecutablesList; } + void setExecutablesDialog(const ExecutablesList &executablesList) { m_ExecutablesList = executablesList; } + + Profile *currentProfile() { return m_CurrentProfile; } + void setCurrentProfile(Profile *profile); + + void setExecutablesList(const ExecutablesList &executablesList); + + std::set enabledArchives(); + + MOBase::VersionInfo getVersion() const { return m_Updater.getVersion(); } + + ModListSortProxy *createModListProxyModel(); + PluginListSortProxy *createPluginListProxyModel(); + + bool isArchivesInit() const { return m_ArchivesInit; } + + bool saveCurrentLists(); + void savePluginList(); + + void prepareStart(); + + void refreshESPList(); + void refreshBSAList(); + + void refreshDirectoryStructure(); + void updateModInDirectoryStructure(unsigned int index, ModInfo::Ptr modInfo); + + void requestDownload(const QUrl &url, QNetworkReply *reply); + + void doAfterLogin(std::function &function) { m_PostLoginTasks.append(function); } + + void spawnBinary(const QFileInfo &binary, const QString &arguments = "", const QDir ¤tDirectory = QDir(), bool closeAfterStart = true, const QString &steamAppID = ""); + + void modStatusChanged(unsigned int index); + + void loginSuccessful(bool necessary); + void loginSuccessfulUpdate(bool necessary); + void loginFailed(const QString &message); + void loginFailedUpdate(const QString &message); + +public: + virtual MOBase::IGameInfo &gameInfo() const; + virtual MOBase::IModRepositoryBridge *createNexusBridge() const; + virtual QString profileName() const; + virtual QString profilePath() const; + virtual QString downloadsPath() const; + virtual MOBase::VersionInfo appVersion() const; + virtual MOBase::IModInterface *getMod(const QString &name); + virtual MOBase::IModInterface *createMod(MOBase::GuessedValue &name); + virtual bool removeMod(MOBase::IModInterface *mod); + virtual void modDataChanged(MOBase::IModInterface *mod); + virtual QVariant pluginSetting(const QString &pluginName, const QString &key) const; + virtual void setPluginSetting(const QString &pluginName, const QString &key, const QVariant &value); + virtual QVariant persistent(const QString &pluginName, const QString &key, const QVariant &def) const; + virtual void setPersistent(const QString &pluginName, const QString &key, const QVariant &value, bool sync); + virtual QString pluginDataPath() const; + virtual MOBase::IModInterface *installMod(const QString &fileName); + virtual QString resolvePath(const QString &fileName) const; + virtual QStringList listDirectories(const QString &directoryName) const; + virtual QStringList findFiles(const QString &path, const std::function &filter) const; + virtual QStringList getFileOrigins(const QString &fileName) const; + virtual QList findFileInfos(const QString &path, const std::function &filter) const; + virtual DownloadManager *downloadManager(); + virtual PluginList *pluginList(); + virtual ModList *modList(); + virtual HANDLE startApplication(const QString &executable, const QStringList &args, const QString &cwd, const QString &profile); + virtual bool waitForApplication(HANDLE handle, LPDWORD exitCode) const; + virtual bool onModInstalled(const std::function &func); + virtual bool onAboutToRun(const std::function &func); + virtual bool onFinishedRun(const std::function &func); + virtual void refreshModList(bool saveChanges = true); + +public: // IPluginDiagnose interface + + virtual std::vector activeProblems() const; + virtual QString shortDescription(unsigned int key) const; + virtual QString fullDescription(unsigned int key) const; + virtual bool hasGuidedFix(unsigned int key) const; + virtual void startGuidedFix(unsigned int key) const; + +public slots: + + void profileRefresh(); + void externalMessage(const QString &message); + + void refreshLists(); + +signals: + + /** + * @brief emitted after a mod has been installed + * @node this is currently only used for tutorials + */ + void modInstalled(); + +private: + + void storeSettings(); + + bool queryLogin(QString &username, QString &password); + + bool nexusLogin(); + + HANDLE spawnBinaryDirect(const QFileInfo &binary, const QString &arguments, const QString &profileName, const QDir ¤tDirectory, const QString &steamAppID); + void updateModActiveState(int index, bool active); + +private slots: + + void directory_refreshed(); + void downloadRequestedNXM(const QString &url); + void downloadRequested(QNetworkReply *reply, int modID, const QString &fileName); + void removeOrigin(const QString &name); + +private: + + static const unsigned int PROBLEM_TOOMANYPLUGINS = 1; + +private: + + MOBase::IGameInfo *m_GameInfo; + + IUserInterface *m_UserInterface; + PluginContainer *m_PluginContainer; + + Profile *m_CurrentProfile; + + Settings m_Settings; + + SelfUpdater m_Updater; + + SignalAboutToRunApplication m_AboutToRun; + SignalFinishedRunApplication m_FinishedRun; + SignalModInstalled m_ModInstalled; + + ModList m_ModList; + PluginList m_PluginList; + + QList> m_PostLoginTasks; + + ExecutablesList m_ExecutablesList; + QStringList m_PendingDownloads; + QStringList m_DefaultArchives; + QStringList m_ActiveArchives; + + DirectoryRefresher m_DirectoryRefresher; + MOShared::DirectoryEntry *m_DirectoryStructure; + + DownloadManager m_DownloadManager; + InstallationManager m_InstallationManager; + + QThread m_RefresherThread; + + bool m_AskForNexusPW; + bool m_DirectoryUpdate; + bool m_ArchivesInit; + +}; + +#endif // ORGANIZERCORE_H diff --git a/src/organizerproxy.cpp b/src/organizerproxy.cpp index 903c979e..07a006f5 100644 --- a/src/organizerproxy.cpp +++ b/src/organizerproxy.cpp @@ -7,50 +7,40 @@ using namespace MOBase; using namespace MOShared; -OrganizerProxy::OrganizerProxy(MainWindow *window, const QString &pluginName) - : m_Proxied(window) +OrganizerProxy::OrganizerProxy(OrganizerCore *organizer, const QString &pluginName) + : m_Proxied(organizer) , m_PluginName(pluginName) { } IGameInfo &OrganizerProxy::gameInfo() const { - return *m_Proxied->m_GameInfo; + return m_Proxied->gameInfo(); } - IModRepositoryBridge *OrganizerProxy::createNexusBridge() const { return new NexusBridge(m_PluginName); } - QString OrganizerProxy::profileName() const { - if (m_Proxied->m_CurrentProfile != NULL) { - return m_Proxied->m_CurrentProfile->getName(); - } else { - return ""; - } + return m_Proxied->profileName(); } QString OrganizerProxy::profilePath() const { - if (m_Proxied->m_CurrentProfile != NULL) { - return m_Proxied->m_CurrentProfile->getPath(); - } else { - return ""; - } + return m_Proxied->profilePath(); } QString OrganizerProxy::downloadsPath() const { - return QDir::fromNativeSeparators(m_Proxied->m_Settings.getDownloadDirectory()); + return m_Proxied->downloadsPath(); } VersionInfo OrganizerProxy::appVersion() const { - return m_Proxied->m_Updater.getVersion(); + return m_Proxied->appVersion(); } IModInterface *OrganizerProxy::getMod(const QString &name) @@ -68,35 +58,34 @@ bool OrganizerProxy::removeMod(IModInterface *mod) return m_Proxied->removeMod(mod); } -void OrganizerProxy::modDataChanged(IModInterface*) +void OrganizerProxy::modDataChanged(IModInterface *mod) { - m_Proxied->refreshModList(); + m_Proxied->modDataChanged(mod); } QVariant OrganizerProxy::pluginSetting(const QString &pluginName, const QString &key) const { - return m_Proxied->m_Settings.pluginSetting(pluginName, key); + return m_Proxied->pluginSetting(pluginName, key); } void OrganizerProxy::setPluginSetting(const QString &pluginName, const QString &key, const QVariant &value) { - m_Proxied->m_Settings.setPluginSetting(pluginName, key, value); + m_Proxied->setPluginSetting(pluginName, key, value); } QVariant OrganizerProxy::persistent(const QString &pluginName, const QString &key, const QVariant &def) const { - return m_Proxied->m_Settings.pluginPersistent(pluginName, key, def); + return m_Proxied->persistent(pluginName, key, def); } void OrganizerProxy::setPersistent(const QString &pluginName, const QString &key, const QVariant &value, bool sync) { - m_Proxied->m_Settings.setPluginPersistent(pluginName, key, value, sync); + m_Proxied->setPersistent(pluginName, key, value, sync); } QString OrganizerProxy::pluginDataPath() const { - QString pluginPath = QDir::fromNativeSeparators(ToQString(GameInfo::instance().getOrganizerDirectory())) + "/" + ToQString(AppConfig::pluginPath()); - return pluginPath + "/data"; + return m_Proxied->pluginDataPath(); } HANDLE OrganizerProxy::startApplication(const QString &executable, const QStringList &args, const QString &cwd, const QString &profile) @@ -106,26 +95,31 @@ HANDLE OrganizerProxy::startApplication(const QString &executable, const QString bool OrganizerProxy::waitForApplication(HANDLE handle, LPDWORD exitCode) const { - return m_Proxied->waitForProcessOrJob(handle, exitCode); + return m_Proxied->waitForApplication(handle, exitCode); } bool OrganizerProxy::onAboutToRun(const std::function &func) { - auto conn = m_Proxied->m_AboutToRun.connect(func); - return conn.connected(); + return m_Proxied->onAboutToRun(func); +} + +bool OrganizerProxy::onFinishedRun(const std::function &func) +{ + return m_Proxied->onFinishedRun(func); } bool OrganizerProxy::onModInstalled(const std::function &func) { - auto conn = m_Proxied->m_ModInstalled.connect(func); - return conn.connected(); + return m_Proxied->onModInstalled(func); } + void OrganizerProxy::refreshModList(bool saveChanges) { m_Proxied->refreshModList(saveChanges); } + IModInterface *OrganizerProxy::installMod(const QString &fileName) { return m_Proxied->installMod(fileName); @@ -133,62 +127,22 @@ IModInterface *OrganizerProxy::installMod(const QString &fileName) QString OrganizerProxy::resolvePath(const QString &fileName) const { - if (m_Proxied->m_DirectoryStructure == NULL) { - return QString(); - } - const FileEntry::Ptr file = m_Proxied->m_DirectoryStructure->searchFile(ToWString(fileName), NULL); - if (file.get() != NULL) { - return ToQString(file->getFullPath()); - } else { - return QString(); - } + return m_Proxied->resolvePath(fileName); } QStringList OrganizerProxy::listDirectories(const QString &directoryName) const { - QStringList result; - DirectoryEntry *dir = m_Proxied->m_DirectoryStructure->findSubDirectoryRecursive(ToWString(directoryName)); - if (dir != NULL) { - std::vector::iterator current, end; - dir->getSubDirectories(current, end); - for (; current != end; ++current) { - result.append(ToQString((*current)->getName())); - } - } - return result; + return m_Proxied->listDirectories(directoryName); } QStringList OrganizerProxy::findFiles(const QString &path, const std::function &filter) const { - QStringList result; - DirectoryEntry *dir = m_Proxied->m_DirectoryStructure->findSubDirectoryRecursive(ToWString(path)); - if (dir != NULL) { - std::vector files = dir->getFiles(); - foreach (FileEntry::Ptr file, files) { - if (filter(ToQString(file->getFullPath()))) { - result.append(ToQString(file->getFullPath())); - } - } - } else { - qWarning("directory %s not found", qPrintable(path)); - } - return result; + return m_Proxied->findFiles(path, filter); } QStringList OrganizerProxy::getFileOrigins(const QString &fileName) const { - QStringList result; - const FileEntry::Ptr file = m_Proxied->m_DirectoryStructure->searchFile(ToWString(QFileInfo(fileName).fileName()), NULL); - - if (file.get() != NULL) { - result.append(ToQString(m_Proxied->m_DirectoryStructure->getOriginByID(file->getOrigin()).getName())); - foreach (int i, file->getAlternatives()) { - result.append(ToQString(m_Proxied->m_DirectoryStructure->getOriginByID(i).getName())); - } - } else { - qDebug("%s not found", qPrintable(fileName)); - } - return result; + return m_Proxied->getFileOrigins(fileName); } QList OrganizerProxy::findFileInfos(const QString &path, const std::function &filter) const @@ -198,15 +152,15 @@ QList OrganizerProxy::findFileInfos(const QString MOBase::IDownloadManager *OrganizerProxy::downloadManager() { - return &m_Proxied->m_DownloadManager; + return m_Proxied->downloadManager(); } MOBase::IPluginList *OrganizerProxy::pluginList() { - return &m_Proxied->m_PluginList; + return m_Proxied->pluginList(); } MOBase::IModList *OrganizerProxy::modList() { - return &m_Proxied->m_ModList; + return m_Proxied->modList(); } diff --git a/src/organizerproxy.h b/src/organizerproxy.h index affa2d55..625e86aa 100644 --- a/src/organizerproxy.h +++ b/src/organizerproxy.h @@ -7,8 +7,10 @@ class OrganizerProxy : public MOBase::IOrganizer { + public: - OrganizerProxy(MainWindow *window, const QString &pluginName); + + OrganizerProxy(OrganizerCore *organizer, const QString &pluginName); virtual MOBase::IGameInfo &gameInfo() const; virtual MOBase::IModRepositoryBridge *createNexusBridge() const; @@ -40,10 +42,14 @@ public: virtual void refreshModList(bool saveChanges); virtual bool onAboutToRun(const std::function &func); - virtual bool onModInstalled(const std::function &func); + virtual bool onFinishedRun(const std::function &func); + virtual bool onModInstalled(const std::function &func); + private: - MainWindow *m_Proxied; + + OrganizerCore *m_Proxied; + const QString &m_PluginName; }; diff --git a/src/plugincontainer.cpp b/src/plugincontainer.cpp new file mode 100644 index 00000000..bd96828e --- /dev/null +++ b/src/plugincontainer.cpp @@ -0,0 +1,329 @@ +#include "plugincontainer.h" +#include "organizerproxy.h" +#include "report.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace MOBase; +using namespace MOShared; + +namespace bf = boost::fusion; + + +PluginContainer::PluginContainer(OrganizerCore *organizer) + : m_Organizer(organizer) +{ +} + + +void PluginContainer::setUserInterface(IUserInterface *userInterface, QWidget *widget) +{ + for (IPluginProxy *proxy : bf::at_key(m_Plugins)) { + proxy->setParentWidget(widget); + } + m_UserInterface = userInterface; +} + + +QStringList PluginContainer::pluginFileNames() const +{ + QStringList result; + for (QPluginLoader *loader : m_PluginLoaders) { + result.append(loader->fileName()); + } + return result; +} + + +bool PluginContainer::verifyPlugin(IPlugin *plugin) +{ + if (plugin == NULL) { + return false; + } else if (!plugin->init(new OrganizerProxy(m_Organizer, plugin->name()))) { + qWarning("plugin failed to initialize"); + return false; + } + return true; +} + + +void PluginContainer::registerGame(IPluginGame *game) +{ + m_SupportedGames.insert({ game->gameName(), game }); +} + + +bool PluginContainer::registerPlugin(QObject *plugin, const QString &fileName) +{ + { // generic treatment for all plugins + IPlugin *pluginObj = qobject_cast(plugin); + if (pluginObj == NULL) { + qDebug("not an IPlugin"); + return false; + } + plugin->setProperty("filename", fileName); + m_Organizer->settings().registerPlugin(pluginObj); + } + + { // diagnosis plugins + IPluginDiagnose *diagnose = qobject_cast(plugin); + if (diagnose != NULL) { + bf::at_key(m_Plugins).push_back(diagnose); + m_DiagnosisConnections.push_back( + diagnose->onInvalidated([&] () { emit diagnosisUpdate(); }) + ); + } + } + { // mod page plugin + IPluginModPage *modPage = qobject_cast(plugin); + if (verifyPlugin(modPage)) { + bf::at_key(m_Plugins).push_back(modPage); + registerModPage(modPage); + return true; + } + } + { // game plugin + IPluginGame *game = qobject_cast(plugin); + if (verifyPlugin(game)) { + bf::at_key(m_Plugins).push_back(game); + registerGame(game); + return true; + } + } + { // tool plugins + IPluginTool *tool = qobject_cast(plugin); + if (verifyPlugin(tool)) { + bf::at_key(m_Plugins).push_back(tool); + registerPluginTool(tool); + return true; + } + } + { // installer plugins + IPluginInstaller *installer = qobject_cast(plugin); + if (verifyPlugin(installer)) { + bf::at_key(m_Plugins).push_back(installer); + m_Organizer->installationManager()->registerInstaller(installer); + return true; + } + } + { // preview plugins + IPluginPreview *preview = qobject_cast(plugin); + if (verifyPlugin(preview)) { + bf::at_key(m_Plugins).push_back(preview); + m_PreviewGenerator.registerPlugin(preview); + return true; + } + } + { // proxy plugins + IPluginProxy *proxy = qobject_cast(plugin); + if (verifyPlugin(proxy)) { + bf::at_key(m_Plugins).push_back(proxy); + QStringList pluginNames = proxy->pluginList(QCoreApplication::applicationDirPath() + "/" + ToQString(AppConfig::pluginPath())); + foreach (const QString &pluginName, pluginNames) { + try { + QObject *proxiedPlugin = proxy->instantiate(pluginName); + if (proxiedPlugin != NULL) { + if (registerPlugin(proxiedPlugin, pluginName)) { + qDebug("loaded plugin \"%s\"", qPrintable(pluginName)); + } else { + qWarning("plugin \"%s\" failed to load", qPrintable(pluginName)); + } + } + } catch (const std::exception &e) { + reportError(QObject::tr("failed to init plugin %1: %2").arg(pluginName).arg(e.what())); + } + } + return true; + } + } + + { // dummy plugins + // only initialize these, no processing otherwise + IPlugin *dummy = qobject_cast(plugin); + if (verifyPlugin(dummy)) { + bf::at_key(m_Plugins).push_back(dummy); + return true; + } + } + + qDebug("no matching plugin interface"); + + return false; +} + +struct clearPlugins +{ + template + void operator()(T& t) const + { + t.second.clear(); + } +}; + +void PluginContainer::unloadPlugins() +{ + if (m_UserInterface != nullptr) { + m_UserInterface->disconnectPlugins(); + } + + // disconnect all slots before unloading plugins so plugins don't have to take care of that + m_Organizer->disconnectPlugins(); + + bf::for_each(m_Plugins, clearPlugins()); + + foreach (const boost::signals2::connection &connection, m_DiagnosisConnections) { + connection.disconnect(); + } + m_DiagnosisConnections.clear(); + + while (!m_PluginLoaders.empty()) { + QPluginLoader *loader = m_PluginLoaders.back(); + m_PluginLoaders.pop_back(); + if (!loader->unload()) { + qDebug("failed to unload %s: %s", qPrintable(loader->fileName()), qPrintable(loader->errorString())); + } + delete loader; + } +} + +IPluginGame *PluginContainer::managedGame(const QString &name) const +{ + auto iter = m_SupportedGames.find(name); + if (iter != m_SupportedGames.end()) { + return iter->second; + } else { + return nullptr; + } +} + +const PreviewGenerator &PluginContainer::previewGenerator() const +{ + return m_PreviewGenerator; +} + +void PluginContainer::loadPlugins() +{ + unloadPlugins(); + + foreach (QObject *plugin, QPluginLoader::staticInstances()) { + registerPlugin(plugin, ""); + } + + QFile loadCheck(qApp->property("dataPath").toString() + "/plugin_loadcheck.tmp"); + if (loadCheck.exists() && loadCheck.open(QIODevice::ReadOnly)) { + // oh, there was a failed plugin load last time. Find out which plugin was loaded last + QString fileName; + while (!loadCheck.atEnd()) { + fileName = QString::fromUtf8(loadCheck.readLine().constData()).trimmed(); + } + if (QMessageBox::question(nullptr, QObject::tr("Plugin error"), + QObject::tr("It appears the plugin \"%1\" failed to load last startup and caused MO to crash. Do you want to disable it?\n" + "(Please note: If this is the first time you see this message for this plugin you may want to give it another try. " + "The plugin may be able to recover from the problem)").arg(fileName), + QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) == QMessageBox::Yes) { + m_Organizer->settings().addBlacklistPlugin(fileName); + } + loadCheck.close(); + } + + loadCheck.open(QIODevice::WriteOnly); + + QString pluginPath = QDir::fromNativeSeparators(ToQString(GameInfo::instance().getOrganizerDirectory())) + "/" + ToQString(AppConfig::pluginPath()); + qDebug("looking for plugins in %s", QDir::toNativeSeparators(pluginPath).toUtf8().constData()); + QDirIterator iter(pluginPath, QDir::Files | QDir::NoDotAndDotDot); + + while (iter.hasNext()) { + iter.next(); + if (m_Organizer->settings().pluginBlacklisted(iter.fileName())) { + qDebug("plugin \"%s\" blacklisted", qPrintable(iter.fileName())); + continue; + } + loadCheck.write(iter.fileName().toUtf8()); + loadCheck.write("\n"); + loadCheck.flush(); + QString pluginName = iter.filePath(); + if (QLibrary::isLibrary(pluginName)) { + QPluginLoader *pluginLoader = new QPluginLoader(pluginName, this); + if (pluginLoader->instance() == NULL) { + m_FailedPlugins.push_back(pluginName); + qCritical("failed to load plugin %s: %s", + qPrintable(pluginName), qPrintable(pluginLoader->errorString())); + } else { + if (registerPlugin(pluginLoader->instance(), pluginName)) { + qDebug("loaded plugin \"%s\"", qPrintable(pluginName)); + m_PluginLoaders.push_back(pluginLoader); + } else { + m_FailedPlugins.push_back(pluginName); + qWarning("plugin \"%s\" failed to load", qPrintable(pluginName)); + } + } + } + } + + // remove the load check file on success + loadCheck.remove(); + + bf::at_key(m_Plugins).push_back(this); + + m_Organizer->connectPlugins(this); +} + + +std::vector PluginContainer::activeProblems() const +{ + std::vector problems; + if (m_FailedPlugins.size()) { + problems.push_back(PROBLEM_PLUGINSNOTLOADED); + } + return problems; +} + +QString PluginContainer::shortDescription(unsigned int key) const +{ + switch (key) { + case PROBLEM_PLUGINSNOTLOADED: { + return tr("Some plugins could not be loaded"); + } break; + default: { + return tr("Description missing"); + } break; + } +} + +QString PluginContainer::fullDescription(unsigned int key) const +{ + switch (key) { + case PROBLEM_PLUGINSNOTLOADED: { + QString result = tr("The following plugins could not be loaded. The reason may be missing dependencies (i.e. python) or an outdated version:") + "
        "; + for (const QString &plugin : m_FailedPlugins) { + result += "
      • " + plugin + "
      • "; + } + result += "
          "; + return result; + } break; + default: { + return tr("Description missing"); + } break; + } +} + +bool PluginContainer::hasGuidedFix(unsigned int) const +{ + return false; +} + +void PluginContainer::startGuidedFix(unsigned int) const +{ +} diff --git a/src/plugincontainer.h b/src/plugincontainer.h new file mode 100644 index 00000000..213b4154 --- /dev/null +++ b/src/plugincontainer.h @@ -0,0 +1,102 @@ +#ifndef PLUGINCONTAINER_H +#define PLUGINCONTAINER_H + + +#include "organizercore.h" +#include "previewgenerator.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef Q_MOC_RUN +#include +#endif // Q_MOC_RUN +#include + + +class PluginContainer : public QObject, public MOBase::IPluginDiagnose +{ + + Q_OBJECT + Q_INTERFACES(MOBase::IPluginDiagnose) + +public: + + PluginContainer(OrganizerCore *organizer); + + void setUserInterface(IUserInterface *userInterface, QWidget *widget); + + void loadPlugins(); + void unloadPlugins(); + + MOBase::IPluginGame *managedGame(const QString &name) const; + + template + std::vector plugins() const { + return boost::fusion::at_key(m_Plugins); + } + + const PreviewGenerator &previewGenerator() const; + + QStringList pluginFileNames() const; + +public: // IPluginDiagnose interface + + virtual std::vector activeProblems() const; + virtual QString shortDescription(unsigned int key) const; + virtual QString fullDescription(unsigned int key) const; + virtual bool hasGuidedFix(unsigned int key) const; + virtual void startGuidedFix(unsigned int key) const; + +signals: + + void diagnosisUpdate(); + +private: + + bool verifyPlugin(MOBase::IPlugin *plugin); + void registerPluginTool(MOBase::IPluginTool *tool); + void registerModPage(MOBase::IPluginModPage *modPage); + void registerGame(MOBase::IPluginGame *game); + bool registerPlugin(QObject *pluginObj, const QString &fileName); + bool unregisterPlugin(QObject *pluginObj, const QString &fileName); + +private: + + typedef boost::fusion::map< + boost::fusion::pair>, + boost::fusion::pair>, + boost::fusion::pair>, + boost::fusion::pair>, + boost::fusion::pair>, + boost::fusion::pair>, + boost::fusion::pair>, + boost::fusion::pair> + > PluginMap; + + static const unsigned int PROBLEM_PLUGINSNOTLOADED = 1; + +private: + + OrganizerCore *m_Organizer; + + IUserInterface *m_UserInterface; + + PluginMap m_Plugins; + + std::map m_SupportedGames; + std::vector m_DiagnosisConnections; + QStringList m_FailedPlugins; + std::vector m_PluginLoaders; + + PreviewGenerator m_PreviewGenerator; + + QFile m_PluginsCheck; +}; + +#endif // PLUGINCONTAINER_H diff --git a/src/selfupdater.cpp b/src/selfupdater.cpp index 6037422c..803b2cfa 100644 --- a/src/selfupdater.cpp +++ b/src/selfupdater.cpp @@ -55,9 +55,9 @@ template T resolveFunction(QLibrary &lib, const char *name) } -SelfUpdater::SelfUpdater(NexusInterface *nexusInterface, QWidget *parent) - : QObject(parent), m_Parent(parent), m_Interface(nexusInterface), m_UpdateRequestID(-1), - m_Reply(NULL), m_Progress(parent), m_Attempts(3) +SelfUpdater::SelfUpdater(NexusInterface *nexusInterface) + : m_Parent(nullptr), m_Interface(nexusInterface), m_UpdateRequestID(-1), + m_Reply(NULL), m_Progress(nullptr), m_Attempts(3) { m_Progress.setMaximum(100); @@ -88,6 +88,11 @@ SelfUpdater::~SelfUpdater() delete m_CurrentArchive; } +void SelfUpdater::setUserInterface(QWidget *widget) +{ + m_Progress.setParent(widget); + m_Parent = widget; +} void SelfUpdater::testForUpdate() { diff --git a/src/selfupdater.h b/src/selfupdater.h index 75b0ff45..3490b58a 100644 --- a/src/selfupdater.h +++ b/src/selfupdater.h @@ -64,10 +64,12 @@ public: * @param parent parent widget * @todo passing the nexus interface is unneccessary **/ - SelfUpdater(NexusInterface *nexusInterface, QWidget *parent); + SelfUpdater(NexusInterface *nexusInterface); virtual ~SelfUpdater(); + void setUserInterface(QWidget *widget); + /** * @brief start the update process * @note this should not be called if there is no update available diff --git a/src/shared/fallout3info.cpp b/src/shared/fallout3info.cpp index 22db91ac..82b285b7 100644 --- a/src/shared/fallout3info.cpp +++ b/src/shared/fallout3info.cpp @@ -267,7 +267,7 @@ bool Fallout3Info::rerouteToProfile(const wchar_t *fileName, const wchar_t*) } -std::vector Fallout3Info::getExecutables() +/*std::vector Fallout3Info::getExecutables() { std::vector result; result.push_back(ExecutableInfo(L"FOSE", L"fose_loader.exe", L"", L"", DEFAULT_CLOSE)); @@ -278,5 +278,5 @@ std::vector Fallout3Info::getExecutables() result.push_back(ExecutableInfo(L"BOSS", L"BOSS/BOSS.exe", L"", L"", NEVER_CLOSE)); return result; -} +}*/ } // namespace MOShared diff --git a/src/shared/fallout3info.h b/src/shared/fallout3info.h index d1356de1..7e39cce4 100644 --- a/src/shared/fallout3info.h +++ b/src/shared/fallout3info.h @@ -87,7 +87,7 @@ public: // get a list of executables (game binary and known-to-work 3rd party tools). All of these are relative to // the game directory - virtual std::vector getExecutables(); + //virtual std::vector getExecutables(); virtual std::wstring archiveListKey() { return L"SArchiveList"; } diff --git a/src/shared/falloutnvinfo.cpp b/src/shared/falloutnvinfo.cpp index 0dde4db1..178ce8b4 100644 --- a/src/shared/falloutnvinfo.cpp +++ b/src/shared/falloutnvinfo.cpp @@ -257,7 +257,7 @@ bool FalloutNVInfo::rerouteToProfile(const wchar_t *fileName, const wchar_t*) return false; } - +/* std::vector FalloutNVInfo::getExecutables() { std::vector result; @@ -269,5 +269,5 @@ std::vector FalloutNVInfo::getExecutables() result.push_back(ExecutableInfo(L"BOSS", L"BOSS/BOSS.exe", L"", L"", NEVER_CLOSE)); return result; -} +}*/ } // namespace MOShared diff --git a/src/shared/falloutnvinfo.h b/src/shared/falloutnvinfo.h index 50a0d00d..231311de 100644 --- a/src/shared/falloutnvinfo.h +++ b/src/shared/falloutnvinfo.h @@ -88,7 +88,7 @@ public: // get a list of executables (game binary and known-to-work 3rd party tools). All of these are relative to // the game directory - virtual std::vector getExecutables(); + //virtual std::vector getExecutables(); virtual std::wstring archiveListKey() { return L"SArchiveList"; } diff --git a/src/shared/gameinfo.h b/src/shared/gameinfo.h index d719a073..c11679f3 100644 --- a/src/shared/gameinfo.h +++ b/src/shared/gameinfo.h @@ -28,7 +28,7 @@ along with Mod Organizer. If not, see . #include namespace MOShared { - +/* enum CloseMOStyle { DEFAULT_CLOSE, DEFAULT_STAY, @@ -53,7 +53,7 @@ struct ExecutableInfo { CloseMOStyle closeMO; std::wstring steamAppID; }; - +*/ /** Class to manage information that depends on the used game type. The intention is to keep @@ -160,13 +160,9 @@ public: virtual bool rerouteToProfile(const wchar_t *fileName, const wchar_t *fullPath) = 0; - // get a list of executables (game binary and known-to-work 3rd party tools). All of these are relative to - // the game directory. the boolean says whether omo should be closed when the executable is started - virtual std::vector getExecutables() = 0; - public: - // initialise with the path to the omo directory (needs to be where hook.dll is stored). This + // initialise with the path to the mo directory (needs to be where hook.dll is stored). This // needs to be called before the instance can be retrieved static bool init(const std::wstring &moDirectory, const std::wstring &moDataDirectory, const std::wstring &gamePath = L""); diff --git a/src/shared/oblivioninfo.cpp b/src/shared/oblivioninfo.cpp index 790fcdb0..89a795a5 100644 --- a/src/shared/oblivioninfo.cpp +++ b/src/shared/oblivioninfo.cpp @@ -273,7 +273,7 @@ std::wstring OblivionInfo::getSteamAPPId(int) const return L"22330"; } - +/* std::vector OblivionInfo::getExecutables() { std::vector result; @@ -286,5 +286,5 @@ std::vector OblivionInfo::getExecutables() result.push_back(ExecutableInfo(L"BOSS (old)", L"Data/BOSS.exe", L"", L"", NEVER_CLOSE)); return result; -} +}*/ } // namespace MOShared diff --git a/src/shared/oblivioninfo.h b/src/shared/oblivioninfo.h index e64ae37b..cb506c01 100644 --- a/src/shared/oblivioninfo.h +++ b/src/shared/oblivioninfo.h @@ -84,7 +84,7 @@ public: // get a list of executables (game binary and known-to-work 3rd party tools). All of these are relative to // the game directory - virtual std::vector getExecutables(); + //virtual std::vector getExecutables(); virtual std::wstring archiveListKey() { return L"SArchiveList"; } diff --git a/src/shared/skyriminfo.cpp b/src/shared/skyriminfo.cpp index 319e58d5..1203e3ed 100644 --- a/src/shared/skyriminfo.cpp +++ b/src/shared/skyriminfo.cpp @@ -306,7 +306,7 @@ bool SkyrimInfo::rerouteToProfile(const wchar_t *fileName, const wchar_t *fullPa } -std::vector SkyrimInfo::getExecutables() +/*std::vector SkyrimInfo::getExecutables() { std::vector result; result.push_back(ExecutableInfo(L"SKSE", L"skse_loader.exe", L"", L"", DEFAULT_CLOSE)); @@ -317,6 +317,6 @@ std::vector SkyrimInfo::getExecutables() result.push_back(ExecutableInfo(L"Creation Kit", L"CreationKit.exe", L"", L"", DEFAULT_STAY, L"202480")); return result; -} +}*/ } // namespace MOShared diff --git a/src/shared/skyriminfo.h b/src/shared/skyriminfo.h index a7aff8dc..ad6ab95d 100644 --- a/src/shared/skyriminfo.h +++ b/src/shared/skyriminfo.h @@ -94,7 +94,7 @@ public: // get a list of executables (game binary and known-to-work 3rd party tools). All of these are relative to // the game directory - virtual std::vector getExecutables(); + //virtual std::vector getExecutables(); virtual std::wstring archiveListKey() { return L"SResourceArchiveList"; } -- cgit v1.3.1 From 99de80e7224f2491fb7518e32f195ad6a912b624 Mon Sep 17 00:00:00 2001 From: Tannin Date: Fri, 28 Nov 2014 11:19:20 +0100 Subject: replaced all uses of NULL with nullptr fixed a few placed where NULL was used as a number or boolean --- src/ModOrganizer.pro | 1 - src/activatemodsdialog.cpp | 4 +- src/bbcode.h | 2 +- src/browserdialog.cpp | 16 ++-- src/categories.cpp | 6 +- src/directoryrefresher.cpp | 8 +- src/downloadlistwidget.cpp | 8 +- src/downloadlistwidgetcompact.cpp | 12 +-- src/downloadmanager.cpp | 32 ++++---- src/downloadmanager.h | 2 +- src/dummybsa.cpp | 4 +- src/editexecutablesdialog.cpp | 10 +-- src/executableslist.cpp | 6 +- src/genericicondelegate.h | 2 +- src/helper.cpp | 2 +- src/installationmanager.cpp | 28 +++---- src/installationmanager.h | 4 +- src/json.cpp | 2 +- src/loadmechanism.cpp | 8 +- src/lockeddialog.cpp | 4 +- src/logbuffer.cpp | 2 +- src/main.cpp | 28 +++---- src/mainwindow.cpp | 160 +++++++++++++++++++------------------- src/messagedialog.cpp | 6 +- src/modinfo.cpp | 2 +- src/modinfodialog.cpp | 18 ++--- src/modlist.cpp | 38 ++++----- src/modlist.h | 2 +- src/modlistsortproxy.cpp | 6 +- src/motddialog.cpp | 2 +- src/nexusinterface.cpp | 22 +++--- src/noeditdelegate.cpp | 2 +- src/noeditdelegate.h | 2 +- src/nxmaccessmanager.cpp | 18 ++--- src/organizercore.cpp | 22 +++--- src/organizerproxy.h | 2 +- src/overwriteinfodialog.cpp | 6 +- src/pdll.h | 110 +++++++++++++------------- src/plugincontainer.cpp | 8 +- src/pluginlist.cpp | 22 +++--- src/pluginlist.h | 2 +- src/pluginlistsortproxy.cpp | 4 +- src/problemsdialog.cpp | 2 +- src/profile.cpp | 14 ++-- src/profilesdialog.cpp | 8 +- src/report.cpp | 2 +- src/savegameinfowidget.cpp | 6 +- src/selectiondialog.cpp | 4 +- src/selfupdater.cpp | 11 ++- src/settingsdialog.cpp | 2 +- src/shared/directoryentry.cpp | 56 ++++++------- src/shared/directoryentry.h | 10 +-- src/shared/error_report.cpp | 12 +-- src/shared/fallout3info.cpp | 12 +-- src/shared/falloutnvinfo.cpp | 12 +-- src/shared/gameinfo.cpp | 14 ++-- src/shared/inject.cpp | 16 ++-- src/shared/leaktrace.cpp | 2 +- src/shared/oblivioninfo.cpp | 14 ++-- src/shared/skyriminfo.cpp | 20 ++--- src/shared/util.cpp | 16 ++-- src/shared/windows_error.cpp | 4 +- src/spawn.cpp | 18 ++--- src/syncoverwritedialog.cpp | 10 +-- src/viewmarkingscrollbar.cpp | 2 +- 65 files changed, 455 insertions(+), 457 deletions(-) (limited to 'src/messagedialog.cpp') diff --git a/src/ModOrganizer.pro b/src/ModOrganizer.pro index a8f7f53e..98f6f730 100644 --- a/src/ModOrganizer.pro +++ b/src/ModOrganizer.pro @@ -12,7 +12,6 @@ SUBDIRS = bsatk \ nxmhandler \ BossDummy \ pythonRunner \ - loot_cli \ esptk pythonRunner.depends = uibase diff --git a/src/activatemodsdialog.cpp b/src/activatemodsdialog.cpp index be6eef54..fd56ae3e 100644 --- a/src/activatemodsdialog.cpp +++ b/src/activatemodsdialog.cpp @@ -72,7 +72,7 @@ std::set ActivateModsDialog::getModsToActivate() for (int row = 0; row < modsTable->rowCount(); ++row) { QComboBox *comboBox = dynamic_cast(modsTable->cellWidget(row, 1)); - if (comboBox != NULL) { + if (comboBox != nullptr) { result.insert(comboBox->currentText()); } } @@ -87,7 +87,7 @@ std::set ActivateModsDialog::getESPsToActivate() for (int row = 0; row < modsTable->rowCount(); ++row) { QComboBox *comboBox = dynamic_cast(modsTable->cellWidget(row, 1)); - if (comboBox != NULL) { + if (comboBox != nullptr) { QLabel *espName = dynamic_cast(modsTable->cellWidget(row, 0)); result.insert(espName->text()); diff --git a/src/bbcode.h b/src/bbcode.h index f88e9a6c..708dfe71 100644 --- a/src/bbcode.h +++ b/src/bbcode.h @@ -29,7 +29,7 @@ namespace BBCode { /** * @brief convert a string with BB Code-Tags to HTML * @param input the input string with BB tags - * @param replaceOccured if not NULL, this parameter will be set to true if any bb tags were replaced + * @param replaceOccured if not nullptr, this parameter will be set to true if any bb tags were replaced * @return the same string in html representation **/ QString convertToHTML(const QString &input); diff --git a/src/browserdialog.cpp b/src/browserdialog.cpp index 82cd8d49..1401b941 100644 --- a/src/browserdialog.cpp +++ b/src/browserdialog.cpp @@ -115,7 +115,7 @@ BrowserView *BrowserDialog::getCurrentView() void BrowserDialog::urlChanged(const QUrl &url) { BrowserView *currentView = getCurrentView(); - if (currentView != NULL) { + if (currentView != nullptr) { ui->backBtn->setEnabled(currentView->history()->canGoBack()); ui->fwdBtn->setEnabled(currentView->history()->canGoForward()); } @@ -192,12 +192,12 @@ void BrowserDialog::unsupportedContent(QNetworkReply *reply) { try { QWebPage *page = qobject_cast(sender()); - if (page == NULL) { + if (page == nullptr) { qCritical("sender not a page"); return; } BrowserView *view = qobject_cast(page->view()); - if (view == NULL) { + if (view == nullptr) { qCritical("no view?"); return; } @@ -231,7 +231,7 @@ void BrowserDialog::tabCloseRequested(int index) void BrowserDialog::on_backBtn_clicked() { BrowserView *currentView = getCurrentView(); - if (currentView != NULL) { + if (currentView != nullptr) { currentView->back(); } } @@ -239,7 +239,7 @@ void BrowserDialog::on_backBtn_clicked() void BrowserDialog::on_fwdBtn_clicked() { BrowserView *currentView = getCurrentView(); - if (currentView != NULL) { + if (currentView != nullptr) { currentView->forward(); } } @@ -254,7 +254,7 @@ void BrowserDialog::startSearch() void BrowserDialog::on_searchEdit_returnPressed() { BrowserView *currentView = getCurrentView(); - if (currentView != NULL) { + if (currentView != nullptr) { currentView->findText(ui->searchEdit->text(), QWebPage::FindWrapsAroundDocument); } } @@ -267,7 +267,7 @@ void BrowserDialog::on_refreshBtn_clicked() void BrowserDialog::on_browserTabWidget_currentChanged(int index) { BrowserView *currentView = qobject_cast(ui->browserTabWidget->widget(index)); - if (currentView != NULL) { + if (currentView != nullptr) { ui->backBtn->setEnabled(currentView->history()->canGoBack()); ui->fwdBtn->setEnabled(currentView->history()->canGoForward()); } @@ -276,7 +276,7 @@ void BrowserDialog::on_browserTabWidget_currentChanged(int index) void BrowserDialog::on_urlEdit_returnPressed() { QWebView *currentView = getCurrentView(); - if (currentView != NULL) { + if (currentView != nullptr) { currentView->setUrl(QUrl(ui->urlEdit->text())); } } diff --git a/src/categories.cpp b/src/categories.cpp index 57e18a28..1d5fdefe 100644 --- a/src/categories.cpp +++ b/src/categories.cpp @@ -32,7 +32,7 @@ using namespace MOBase; using namespace MOShared; -CategoryFactory* CategoryFactory::s_Instance = NULL; +CategoryFactory* CategoryFactory::s_Instance = nullptr; QString CategoryFactory::categoriesFilePath() @@ -93,7 +93,7 @@ CategoryFactory::CategoryFactory() CategoryFactory &CategoryFactory::instance() { - if (s_Instance == NULL) { + if (s_Instance == nullptr) { s_Instance = new CategoryFactory; } return *s_Instance; @@ -133,7 +133,7 @@ void CategoryFactory::setParents() void CategoryFactory::cleanup() { delete s_Instance; - s_Instance = NULL; + s_Instance = nullptr; } diff --git a/src/directoryrefresher.cpp b/src/directoryrefresher.cpp index 24fda501..45692fdf 100644 --- a/src/directoryrefresher.cpp +++ b/src/directoryrefresher.cpp @@ -31,7 +31,7 @@ using namespace MOShared; DirectoryRefresher::DirectoryRefresher() - : m_DirectoryStructure(NULL) + : m_DirectoryStructure(nullptr) { } @@ -44,7 +44,7 @@ DirectoryEntry *DirectoryRefresher::getDirectoryStructure() { QMutexLocker locker(&m_RefreshLock); DirectoryEntry *result = m_DirectoryStructure; - m_DirectoryStructure = NULL; + m_DirectoryStructure = nullptr; return result; } @@ -104,7 +104,7 @@ void DirectoryRefresher::addModFilesToStructure(DirectoryEntry *directoryStructu foreach (const QString &filename, stealFiles) { QFileInfo fileInfo(filename); FileEntry::Ptr file = directoryStructure->findFile(ToWString(fileInfo.fileName())); - if (file.get() != NULL) { + if (file.get() != nullptr) { if (file->getOrigin() == 0) { // replace data as the origin on this bsa file->removeOrigin(0); @@ -134,7 +134,7 @@ void DirectoryRefresher::refresh() delete m_DirectoryStructure; - m_DirectoryStructure = new DirectoryEntry(L"data", NULL, 0); + m_DirectoryStructure = new DirectoryEntry(L"data", nullptr, 0); std::wstring dataDirectory = GameInfo::instance().getGameDirectory() + L"\\data"; m_DirectoryStructure->addFromOrigin(L"data", dataDirectory, 0); diff --git a/src/downloadlistwidget.cpp b/src/downloadlistwidget.cpp index 9d276de9..2a398bc0 100644 --- a/src/downloadlistwidget.cpp +++ b/src/downloadlistwidget.cpp @@ -255,7 +255,7 @@ void DownloadListWidgetDelegate::issueResume() void DownloadListWidgetDelegate::issueDeleteAll() { - if (QMessageBox::question(NULL, tr("Are you sure?"), + if (QMessageBox::question(nullptr, tr("Are you sure?"), tr("This will remove all finished downloads from this list and from disk."), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { emit removeDownload(-1, true); @@ -264,7 +264,7 @@ void DownloadListWidgetDelegate::issueDeleteAll() void DownloadListWidgetDelegate::issueDeleteCompleted() { - if (QMessageBox::question(NULL, tr("Are you sure?"), + if (QMessageBox::question(nullptr, tr("Are you sure?"), tr("This will remove all installed downloads from this list and from disk."), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { emit removeDownload(-2, true); @@ -273,7 +273,7 @@ void DownloadListWidgetDelegate::issueDeleteCompleted() void DownloadListWidgetDelegate::issueRemoveFromViewAll() { - if (QMessageBox::question(NULL, tr("Are you sure?"), + if (QMessageBox::question(nullptr, tr("Are you sure?"), tr("This will remove all finished downloads from this list (but NOT from disk)."), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { emit removeDownload(-1, false); @@ -282,7 +282,7 @@ void DownloadListWidgetDelegate::issueRemoveFromViewAll() void DownloadListWidgetDelegate::issueRemoveFromViewCompleted() { - if (QMessageBox::question(NULL, tr("Are you sure?"), + if (QMessageBox::question(nullptr, tr("Are you sure?"), tr("This will remove all installed downloads from this list (but NOT from disk)."), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { emit removeDownload(-2, false); diff --git a/src/downloadlistwidgetcompact.cpp b/src/downloadlistwidgetcompact.cpp index 21a690ab..a298494a 100644 --- a/src/downloadlistwidgetcompact.cpp +++ b/src/downloadlistwidgetcompact.cpp @@ -90,7 +90,7 @@ void DownloadListWidgetCompactDelegate::paintPendingDownload(int downloadIndex) { std::pair nexusids = m_Manager->getPendingDownload(downloadIndex); m_NameLabel->setText(tr("< mod %1 file %2 >").arg(nexusids.first).arg(nexusids.second)); - if (m_SizeLabel != NULL) { + if (m_SizeLabel != nullptr) { m_SizeLabel->setText("???"); } m_DoneLabel->setVisible(true); @@ -110,7 +110,7 @@ void DownloadListWidgetCompactDelegate::paintRegularDownload(int downloadIndex) DownloadManager::DownloadState state = m_Manager->getState(downloadIndex); - if ((m_SizeLabel != NULL) && (state >= DownloadManager::STATE_READY)) { + if ((m_SizeLabel != nullptr) && (state >= DownloadManager::STATE_READY)) { m_SizeLabel->setText(QString::number(m_Manager->getFileSize(downloadIndex) / 1048576)); } @@ -242,7 +242,7 @@ void DownloadListWidgetCompactDelegate::issueResume() void DownloadListWidgetCompactDelegate::issueDeleteAll() { - if (QMessageBox::question(NULL, tr("Are you sure?"), + if (QMessageBox::question(nullptr, tr("Are you sure?"), tr("This will remove all finished downloads from this list and from disk."), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { emit removeDownload(-1, true); @@ -251,7 +251,7 @@ void DownloadListWidgetCompactDelegate::issueDeleteAll() void DownloadListWidgetCompactDelegate::issueDeleteCompleted() { - if (QMessageBox::question(NULL, tr("Are you sure?"), + if (QMessageBox::question(nullptr, tr("Are you sure?"), tr("This will remove all installed downloads from this list and from disk."), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { emit removeDownload(-2, true); @@ -260,7 +260,7 @@ void DownloadListWidgetCompactDelegate::issueDeleteCompleted() void DownloadListWidgetCompactDelegate::issueRemoveFromViewAll() { - if (QMessageBox::question(NULL, tr("Are you sure?"), + if (QMessageBox::question(nullptr, tr("Are you sure?"), tr("This will permanently remove all finished downloads from this list (but NOT from disk)."), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { emit removeDownload(-1, false); @@ -269,7 +269,7 @@ void DownloadListWidgetCompactDelegate::issueRemoveFromViewAll() void DownloadListWidgetCompactDelegate::issueRemoveFromViewCompleted() { - if (QMessageBox::question(NULL, tr("Are you sure?"), + if (QMessageBox::question(nullptr, tr("Are you sure?"), tr("This will permanently remove all installed downloads from this list (but NOT from disk)."), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { emit removeDownload(-2, false); diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp index d785a939..1d141656 100644 --- a/src/downloadmanager.cpp +++ b/src/downloadmanager.cpp @@ -75,7 +75,7 @@ DownloadManager::DownloadInfo *DownloadManager::DownloadInfo::createFromMeta(con QString metaFileName = filePath + ".meta"; QSettings metaFile(metaFileName, QSettings::IniFormat); if (!showHidden && metaFile.value("removed", false).toBool()) { - return NULL; + return nullptr; } else { info->m_Hidden = metaFile.value("removed", false).toBool(); } @@ -308,7 +308,7 @@ void DownloadManager::refreshList() QString fileName = QDir::fromNativeSeparators(m_OutputDirectory) + "/" + file; DownloadInfo *info = DownloadInfo::createFromMeta(fileName, m_ShowHidden); - if (info != NULL) { + if (info != nullptr) { m_ActiveDownloads.push_front(info); } } @@ -368,7 +368,7 @@ bool DownloadManager::addDownload(QNetworkReply *reply, const QStringList &URLs, } if (QFile::exists(m_OutputDirectory + "/" + baseName) && - (QMessageBox::question(NULL, tr("Download again?"), tr("A file with the same name has already been downloaded. " + (QMessageBox::question(nullptr, tr("Download again?"), tr("A file with the same name has already been downloaded. " "Do you want to download it again? The new file will receive a different name."), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)) { removePending(modID, fileID); @@ -453,7 +453,7 @@ void DownloadManager::addNXMDownload(const QString &url) qDebug("add nxm download: %s", qPrintable(url)); if (nxmInfo.game().compare(managedGame, Qt::CaseInsensitive) != 0) { qDebug("download requested for wrong game (game: %s, url: %s)", qPrintable(managedGame), qPrintable(nxmInfo.game())); - QMessageBox::information(NULL, tr("Wrong Game"), tr("The download link is for a mod for \"%1\" but this instance of MO " + 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(managedGame), QMessageBox::Ok); return; } @@ -608,7 +608,7 @@ void DownloadManager::pauseDownload(int index) DownloadInfo *info = m_ActiveDownloads.at(index); if (info->m_State == STATE_DOWNLOADING) { - if ((info->m_Reply != NULL) && (info->m_Reply->isRunning())) { + if ((info->m_Reply != nullptr) && (info->m_Reply->isRunning())) { setState(info, STATE_PAUSING); } else { setState(info, STATE_PAUSED); @@ -664,7 +664,7 @@ DownloadManager::DownloadInfo *DownloadManager::downloadInfoByID(unsigned int id if (iter != m_ActiveDownloads.end()) { return *iter; } else { - return NULL; + return nullptr; } } @@ -694,8 +694,8 @@ void DownloadManager::queryInfo(int index) if (info->m_FileInfo->modID < 0) { QString modIDString; while (modIDString.isEmpty()) { - modIDString = QInputDialog::getText(NULL, tr("Please enter the nexus mod id"), tr("Mod ID:"), QLineEdit::Normal, - QString(), NULL, 0, Qt::ImhFormattedNumbersOnly); + modIDString = QInputDialog::getText(nullptr, tr("Please enter the nexus mod id"), tr("Mod ID:"), QLineEdit::Normal, + QString(), nullptr, 0, Qt::ImhFormattedNumbersOnly); if (modIDString.isNull()) { // canceled return; @@ -704,7 +704,7 @@ void DownloadManager::queryInfo(int index) modIDString.clear(); } } - info->m_FileInfo->modID = modIDString.toInt(NULL, 10); + info->m_FileInfo->modID = modIDString.toInt(nullptr, 10); } } info->m_ReQueried = true; @@ -962,13 +962,13 @@ DownloadManager::DownloadInfo *DownloadManager::findDownload(QObject *reply, int // reverse search as newer, thus more relevant, downloads are at the end for (int i = m_ActiveDownloads.size() - 1; i >= 0; --i) { if (m_ActiveDownloads[i]->m_Reply == reply) { - if (index != NULL) { + if (index != nullptr) { *index = i; } return m_ActiveDownloads[i]; } } - return NULL; + return nullptr; } @@ -1007,7 +1007,7 @@ void DownloadManager::downloadReadyRead() { try { DownloadInfo *info = findDownload(this->sender()); - if (info != NULL) { + if (info != nullptr) { info->m_Output.write(info->m_Reply->readAll()); } } catch (const std::bad_alloc&) { @@ -1059,7 +1059,7 @@ void DownloadManager::nxmDescriptionAvailable(int, QVariant userData, QVariant r QVariantMap result = resultData.toMap(); DownloadInfo *info = downloadInfoByID(userData.toInt()); - if (info == NULL) return; + if (info == nullptr) return; info->m_FileInfo->categoryID = result["category_id"].toInt(); info->m_FileInfo->modName = result["name"].toString().trimmed(); info->m_FileInfo->newestVersion.parse(result["version"].toString()); @@ -1104,7 +1104,7 @@ void DownloadManager::nxmFilesAvailable(int, QVariant userData, QVariant resultD } DownloadInfo *info = downloadInfoByID(userData.toInt()); - if (info == NULL) return; + if (info == nullptr) return; QVariantList result = resultData.toList(); @@ -1323,7 +1323,7 @@ void DownloadManager::downloadFinished() int index = 0; DownloadInfo *info = findDownload(this->sender(), &index); - if (info != NULL) { + if (info != nullptr) { QNetworkReply *reply = info->m_Reply; QByteArray data; if (reply->isOpen()) { @@ -1437,7 +1437,7 @@ void DownloadManager::metaDataChanged() int index = 0; DownloadInfo *info = findDownload(this->sender(), &index); - if (info != NULL) { + if (info != nullptr) { QString newName = getFileNameFromNetworkReply(info->m_Reply); if (!newName.isEmpty() && (newName != info->m_FileName)) { info->setName(getDownloadFileName(newName), true); diff --git a/src/downloadmanager.h b/src/downloadmanager.h index 95288884..52da27b8 100644 --- a/src/downloadmanager.h +++ b/src/downloadmanager.h @@ -439,7 +439,7 @@ private: bool addDownload(const QStringList &URLs, int modID, int fileID, const MOBase::ModRepositoryFileInfo *fileInfo); // important: the caller has to lock the list-mutex, otherwise the DownloadInfo-pointer might get invalidated at any time - DownloadInfo *findDownload(QObject *reply, int *index = NULL) const; + DownloadInfo *findDownload(QObject *reply, int *index = nullptr) const; void removeFile(int index, bool deleteFile); diff --git a/src/dummybsa.cpp b/src/dummybsa.cpp index df757139..49c6ee53 100644 --- a/src/dummybsa.cpp +++ b/src/dummybsa.cpp @@ -65,7 +65,7 @@ static unsigned long long genHash(const char* fileName) fileNameLower[i] = '\0'; char* ext = strrchr(fileNameLower, '.'); - if (ext == NULL) { + if (ext == nullptr) { ext = fileNameLower + strlen(fileNameLower); } @@ -117,7 +117,7 @@ static unsigned long long genHash(const char* fileName) unsigned char *fileNameLowerU = reinterpret_cast(fileNameLower); char* ext = strrchr(fileNameLower, '.'); - if (ext == NULL) { + if (ext == nullptr) { ext = fileNameLower + strlen(fileNameLower); } unsigned char *extU = reinterpret_cast(ext); diff --git a/src/editexecutablesdialog.cpp b/src/editexecutablesdialog.cpp index 3cc749d6..162c6a83 100644 --- a/src/editexecutablesdialog.cpp +++ b/src/editexecutablesdialog.cpp @@ -30,7 +30,7 @@ using namespace MOShared; EditExecutablesDialog::EditExecutablesDialog(const ExecutablesList &executablesList, QWidget *parent) : TutorableDialog("EditExecutables", parent), - ui(new Ui::EditExecutablesDialog), m_CurrentItem(NULL), m_ExecutablesList(executablesList) + ui(new Ui::EditExecutablesDialog), m_CurrentItem(nullptr), m_ExecutablesList(executablesList) { ui->setupUi(this); @@ -86,7 +86,7 @@ void EditExecutablesDialog::resetInput() ui->appIDOverwriteEdit->clear(); ui->overwriteAppIDBox->setChecked(false); ui->closeCheckBox->setChecked(false); - m_CurrentItem = NULL; + m_CurrentItem = nullptr; } @@ -128,7 +128,7 @@ void EditExecutablesDialog::on_browseButton_clicked() { // try to find java automatically std::wstring binaryNameW = ToWString(binaryName); WCHAR buffer[MAX_PATH]; - if (::FindExecutableW(binaryNameW.c_str(), NULL, buffer) > (HINSTANCE)32) { + if (::FindExecutableW(binaryNameW.c_str(), nullptr, buffer) > (HINSTANCE)32) { DWORD binaryType = 0UL; if (!::GetBinaryTypeW(binaryNameW.c_str(), &binaryType)) { qDebug("failed to determine binary type of \"%ls\": %lu", binaryNameW.c_str(), ::GetLastError()); @@ -204,7 +204,7 @@ void EditExecutablesDialog::on_titleEdit_textChanged(const QString &arg1) bool EditExecutablesDialog::executableChanged() { - if (m_CurrentItem != NULL) { + if (m_CurrentItem != nullptr) { const Executable &selectedExecutable = m_CurrentItem->data(Qt::UserRole).value(); return selectedExecutable.m_Arguments != ui->argumentsEdit->text() @@ -220,7 +220,7 @@ bool EditExecutablesDialog::executableChanged() void EditExecutablesDialog::on_executablesListBox_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous) { - if (current == NULL) { + if (current == nullptr) { resetInput(); return; } diff --git a/src/executableslist.cpp b/src/executableslist.cpp index c46cea10..03f2b7c9 100644 --- a/src/executableslist.cpp +++ b/src/executableslist.cpp @@ -130,7 +130,7 @@ Executable *ExecutablesList::findExe(const QString &title) return &*iter; } } - return NULL; + return nullptr; } @@ -144,7 +144,7 @@ bool ExecutablesList::titleExists(const QString &title) const void ExecutablesList::addExecutable(const Executable &executable) { Executable *existingExe = findExe(executable.m_Title); - if (existingExe != NULL) { + if (existingExe != nullptr) { *existingExe = executable; } else { m_Executables.push_back(executable); @@ -158,7 +158,7 @@ void ExecutablesList::addExecutable(const QString &title, const QString &executa { QFileInfo file(executableName); Executable *existingExe = findExe(title); - if (existingExe != NULL) { + if (existingExe != nullptr) { existingExe->m_Title = title; existingExe->m_CloseMO = closeMO; existingExe->m_BinaryInfo = file; diff --git a/src/genericicondelegate.h b/src/genericicondelegate.h index 8bc75e27..9842d09a 100644 --- a/src/genericicondelegate.h +++ b/src/genericicondelegate.h @@ -20,7 +20,7 @@ public: * of the view, the delegate will turn off this behaviour if the column is smaller than "compactSize" * @param compactSize see explanation of logicalIndex */ - GenericIconDelegate(QObject *parent = NULL, int role = Qt::UserRole + 1, int logicalIndex = -1, int compactSize = 150); + GenericIconDelegate(QObject *parent = nullptr, int role = Qt::UserRole + 1, int logicalIndex = -1, int compactSize = 150); public slots: void columnResized(int logicalIndex, int oldSize, int newSize); private: diff --git a/src/helper.cpp b/src/helper.cpp index d0825d10..f47a468a 100644 --- a/src/helper.cpp +++ b/src/helper.cpp @@ -40,7 +40,7 @@ bool helperExec(LPCWSTR moDirectory, LPCWSTR commandLine) execInfo.cbSize = sizeof(SHELLEXECUTEINFOW); execInfo.fMask = SEE_MASK_NOCLOSEPROCESS; - execInfo.hwnd = NULL; + execInfo.hwnd = nullptr; execInfo.lpVerb = L"runas"; execInfo.lpFile = fileName; execInfo.lpParameters = commandLine; diff --git a/src/installationmanager.cpp b/src/installationmanager.cpp index 25fe06a4..6ab051b2 100644 --- a/src/installationmanager.cpp +++ b/src/installationmanager.cpp @@ -60,7 +60,7 @@ typedef Archive* (*CreateArchiveType)(); template T resolveFunction(QLibrary &lib, const char *name) { T temp = reinterpret_cast(lib.resolve(name)); - if (temp == NULL) { + if (temp == nullptr) { throw std::runtime_error(QObject::tr("invalid 7-zip32.dll: %1").arg(lib.errorString()).toLatin1().constData()); } return temp; @@ -94,7 +94,7 @@ InstallationManager::~InstallationManager() void InstallationManager::setParentWidget(QWidget *widget) { - m_InstallationProgress.setParent(widget); + m_InstallationProgress.setParent(widget, Qt::Dialog); for (IPluginInstaller *installer : m_Installers) { installer->setParentWidget(widget); } @@ -103,7 +103,7 @@ void InstallationManager::setParentWidget(QWidget *widget) void InstallationManager::queryPassword(LPSTR password) { - QString result = QInputDialog::getText(NULL, tr("Password required"), tr("Password"), QLineEdit::Password); + QString result = QInputDialog::getText(nullptr, tr("Password required"), tr("Password"), QLineEdit::Password); strncpy(password, result.toLocal8Bit().constData(), MAX_PASSWORD_LENGTH); } @@ -231,10 +231,10 @@ QStringList InstallationManager::extractFiles(const QStringList &filesOrig, bool const wchar_t *targetFile = data[i]->getFileName(); if (flatten) { targetFile = wcsrchr(data[i]->getFileName(), '\\'); - if (targetFile == NULL) { + if (targetFile == nullptr) { targetFile = wcsrchr(data[i]->getFileName(), '/'); } - if (targetFile == NULL) { + if (targetFile == nullptr) { qCritical("failed to find backslash in %ls", data[i]->getFileName()); continue; } else { @@ -383,7 +383,7 @@ DirectoryTree::Node *InstallationManager::getSimpleArchiveBase(DirectoryTree *da currentNode = *currentNode->nodesBegin(); } else { qDebug("not a simple archive"); - return NULL; + return nullptr; } } } @@ -675,7 +675,7 @@ bool InstallationManager::install(const QString &fileName, GuessedValue } ON_BLOCK_EXIT(std::bind(&InstallationManager::postInstallCleanup, this)); - QScopedPointer filesTree(archiveOpen ? createFilesTree() : NULL); + QScopedPointer filesTree(archiveOpen ? createFilesTree() : nullptr); IPluginInstaller::EInstallResult installResult = IPluginInstaller::RESULT_NOTATTEMPTED; std::sort(m_Installers.begin(), m_Installers.end(), [] (IPluginInstaller *LHS, IPluginInstaller *RHS) { @@ -700,8 +700,8 @@ bool InstallationManager::install(const QString &fileName, GuessedValue try { { // simple case IPluginInstallerSimple *installerSimple = dynamic_cast(installer); - if ((installerSimple != NULL) && - (filesTree != NULL) && (installer->isArchiveSupported(*filesTree))) { + if ((installerSimple != nullptr) && + (filesTree != nullptr) && (installer->isArchiveSupported(*filesTree))) { installResult = installerSimple->install(modName, *filesTree, version, modID); if (installResult == IPluginInstaller::RESULT_SUCCESS) { mapToArchive(filesTree.data()); @@ -715,9 +715,9 @@ bool InstallationManager::install(const QString &fileName, GuessedValue { // custom case IPluginInstallerCustom *installerCustom = dynamic_cast(installer); - if ((installerCustom != NULL) && - (((filesTree != NULL) && installer->isArchiveSupported(*filesTree)) || - ((filesTree == NULL) && installerCustom->isArchiveSupported(fileName)))) { + if ((installerCustom != nullptr) && + (((filesTree != nullptr) && installer->isArchiveSupported(*filesTree)) || + ((filesTree == nullptr) && installerCustom->isArchiveSupported(fileName)))) { std::set installerExtensions = installerCustom->supportedExtensions(); if (installerExtensions.find(fileInfo.suffix()) != installerExtensions.end()) { installResult = installerCustom->install(modName, fileName, version, modID); @@ -738,7 +738,7 @@ bool InstallationManager::install(const QString &fileName, GuessedValue } break; case IPluginInstaller::RESULT_SUCCESS: case IPluginInstaller::RESULT_SUCCESSCANCEL: { - if (filesTree != NULL) { + if (filesTree != nullptr) { DirectoryTree::node_iterator iniTweakNode = filesTree->nodeFind(DirectoryTreeInformation("INI Tweaks")); hasIniTweaks = (iniTweakNode != filesTree->nodesEnd()) && ((*iniTweakNode)->numLeafs() != 0); @@ -796,7 +796,7 @@ void InstallationManager::registerInstaller(IPluginInstaller *installer) m_Installers.push_back(installer); installer->setInstallationManager(this); IPluginInstallerCustom *installerCustom = dynamic_cast(installer); - if (installerCustom != NULL) { + if (installerCustom != nullptr) { std::set extensions = installerCustom->supportedExtensions(); m_SupportedExtensions.insert(extensions.begin(), extensions.end()); } diff --git a/src/installationmanager.h b/src/installationmanager.h index cd20f0dd..4750a148 100644 --- a/src/installationmanager.h +++ b/src/installationmanager.h @@ -143,7 +143,7 @@ public: * @param merge if this value is not null, the value will be set to whether the use chose to merge or replace * @return true if we can proceed with the installation, false if the user canceled or in case of an unrecoverable error */ - virtual bool testOverwrite(MOBase::GuessedValue &modName, bool *merge = NULL) const; + virtual bool testOverwrite(MOBase::GuessedValue &modName, bool *merge = nullptr) const; private: @@ -168,7 +168,7 @@ private: bool isSimpleArchiveTopLayer(const MOBase::DirectoryTree::Node *node, bool bainStyle); MOBase::DirectoryTree::Node *getSimpleArchiveBase(MOBase::DirectoryTree *dataTree); - //bool testOverwrite(const QString &modsDirectory, MOBase::GuessedValue &modName, bool *merge = NULL); + //bool testOverwrite(const QString &modsDirectory, MOBase::GuessedValue &modName, bool *merge = nullptr); bool doInstall(MOBase::GuessedValue &modName, int modID, const QString &version, const QString &newestVersion, int categoryID); diff --git a/src/json.cpp b/src/json.cpp index a280ba34..05a2665a 100644 --- a/src/json.cpp +++ b/src/json.cpp @@ -409,7 +409,7 @@ namespace QtJson { bool ok; if (numberStr.contains('.')) { - return QVariant(numberStr.toDouble(NULL)); + return QVariant(numberStr.toDouble(nullptr)); } else if (numberStr.startsWith('-')) { int i = numberStr.toInt(&ok); if (!ok) { diff --git a/src/loadmechanism.cpp b/src/loadmechanism.cpp index 9d7e4e28..711a7f1a 100644 --- a/src/loadmechanism.cpp +++ b/src/loadmechanism.cpp @@ -141,7 +141,7 @@ void LoadMechanism::deactivateScriptExtender() removeHintFile(pluginsDir); } catch (const std::exception &e) { - QMessageBox::critical(NULL, QObject::tr("Failed to deactivate script extender loading"), e.what()); + QMessageBox::critical(nullptr, QObject::tr("Failed to deactivate script extender loading"), e.what()); } } @@ -172,7 +172,7 @@ void LoadMechanism::deactivateProxyDLL() QDir dir(gameDirectory); removeHintFile(dir); } catch (const std::exception &e) { - QMessageBox::critical(NULL, QObject::tr("Failed to deactivate proxy-dll loading"), e.what()); + QMessageBox::critical(nullptr, QObject::tr("Failed to deactivate proxy-dll loading"), e.what()); } } @@ -211,7 +211,7 @@ void LoadMechanism::activateScriptExtender() } writeHintFile(pluginsDir); } catch (const std::exception &e) { - QMessageBox::critical(NULL, QObject::tr("Failed to set up script extender loading"), e.what()); + QMessageBox::critical(nullptr, QObject::tr("Failed to set up script extender loading"), e.what()); } } @@ -265,7 +265,7 @@ void LoadMechanism::activateProxyDLL() } writeHintFile(QDir(gameDirectory)); } catch (const std::exception &e) { - QMessageBox::critical(NULL, QObject::tr("Failed to set up proxy-dll loading"), e.what()); + QMessageBox::critical(nullptr, QObject::tr("Failed to set up proxy-dll loading"), e.what()); } } diff --git a/src/lockeddialog.cpp b/src/lockeddialog.cpp index c688fff6..907e3c0a 100644 --- a/src/lockeddialog.cpp +++ b/src/lockeddialog.cpp @@ -31,7 +31,7 @@ LockedDialog::LockedDialog(QWidget *parent, const QString &text, bool unlockButt this->setWindowFlags(this->windowFlags() | Qt::ToolTip | Qt::FramelessWindowHint); - if (parent != NULL) { + if (parent != nullptr) { QPoint position = parent->mapToGlobal(QPoint(parent->width() / 2, parent->height() / 2)); position.rx() -= this->width() / 2; position.ry() -= this->height() / 2; @@ -61,7 +61,7 @@ void LockedDialog::setProcessName(const QString &name) void LockedDialog::resizeEvent(QResizeEvent *event) { QWidget *par = parentWidget(); - if (par != NULL) { + if (par != nullptr) { QPoint position = par->mapToGlobal(QPoint(par->width() / 2, par->height() / 2)); position.rx() -= event->size().width() / 2; position.ry() -= event->size().height() / 2; diff --git a/src/logbuffer.cpp b/src/logbuffer.cpp index 17417bf9..635ce13e 100644 --- a/src/logbuffer.cpp +++ b/src/logbuffer.cpp @@ -30,7 +30,7 @@ QMutex LogBuffer::s_Mutex; LogBuffer::LogBuffer(int messageCount, QtMsgType minMsgType, const QString &outputFileName) - : QAbstractItemModel(NULL), m_OutFileName(outputFileName), m_ShutDown(false), + : QAbstractItemModel(nullptr), m_OutFileName(outputFileName), m_ShutDown(false), m_MinMsgType(minMsgType), m_NumMessages(0) { m_Messages.resize(messageCount); diff --git a/src/main.cpp b/src/main.cpp index 3f0360c2..a3ddac20 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -99,12 +99,12 @@ bool bootstrap() // verify the hook-dll exists QString dllName = qApp->applicationDirPath() + "/" + ToQString(AppConfig::hookDLLName()); - if (::GetModuleHandleW(ToWString(dllName).c_str()) != NULL) { + if (::GetModuleHandleW(ToWString(dllName).c_str()) != nullptr) { throw std::runtime_error("hook.dll already loaded! You can't start Mod Organizer from within itself (not even indirectly)"); } HMODULE dllMod = ::LoadLibraryW(ToWString(dllName).c_str()); - if (dllMod == NULL) { + if (dllMod == nullptr) { throw windows_error("hook.dll is missing or invalid"); } ::FreeLibrary(dllMod); @@ -135,7 +135,7 @@ LONG WINAPI MyUnhandledExceptionFilter(struct _EXCEPTION_POINTERS *exceptionPtrs FuncMiniDumpWriteDump funcDump = (FuncMiniDumpWriteDump)::GetProcAddress(dbgDLL, "MiniDumpWriteDump"); if (funcDump) { - if (QMessageBox::question(NULL, QObject::tr("Woops"), + if (QMessageBox::question(nullptr, QObject::tr("Woops"), QObject::tr("ModOrganizer has crashed! Should a diagnostic file be created? If you send me this file " "(%1) to sherb@gmx.net, the bug is a lot more likely to be fixed. " "Please include a short description of what you were doing when the crash happened").arg(qApp->applicationFilePath().append(".dmp")), @@ -144,14 +144,14 @@ LONG WINAPI MyUnhandledExceptionFilter(struct _EXCEPTION_POINTERS *exceptionPtrs std::wstring dumpName = ToWString(qApp->applicationFilePath().append(".dmp")); HANDLE dumpFile = ::CreateFile(dumpName.c_str(), - GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + GENERIC_WRITE, FILE_SHARE_WRITE, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); if (dumpFile != INVALID_HANDLE_VALUE) { _MINIDUMP_EXCEPTION_INFORMATION exceptionInfo; exceptionInfo.ThreadId = ::GetCurrentThreadId(); exceptionInfo.ExceptionPointers = exceptionPtrs; - exceptionInfo.ClientPointers = NULL; + exceptionInfo.ClientPointers = false; - BOOL success = funcDump(::GetCurrentProcess(), ::GetCurrentProcessId(), dumpFile, MiniDumpNormal, &exceptionInfo, NULL, NULL); + BOOL success = funcDump(::GetCurrentProcess(), ::GetCurrentProcessId(), dumpFile, MiniDumpNormal, &exceptionInfo, nullptr, nullptr); ::FlushFileBuffers(dumpFile); ::CloseHandle(dumpFile); @@ -174,7 +174,7 @@ LONG WINAPI MyUnhandledExceptionFilter(struct _EXCEPTION_POINTERS *exceptionPtrs _snprintf(errorBuffer, errorLen, "dbghelp.dll not found"); } - QMessageBox::critical(NULL, QObject::tr("Woops"), + QMessageBox::critical(nullptr, QObject::tr("Woops"), QObject::tr("ModOrganizer has crashed! Unfortunately I was not able to write a diagnostic file: %1").arg(errorBuffer)); return result; } @@ -191,14 +191,14 @@ bool HaveWriteAccess(const std::wstring &path) const static SECURITY_INFORMATION requestedFileInformation = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION; DWORD length = 0; - if (!::GetFileSecurityW(path.c_str(), requestedFileInformation, NULL, NULL, &length) + if (!::GetFileSecurityW(path.c_str(), requestedFileInformation, nullptr, 0UL, &length) && (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { std::string tempBuffer; tempBuffer.reserve(length); PSECURITY_DESCRIPTOR security = (PSECURITY_DESCRIPTOR)tempBuffer.data(); if (security && ::GetFileSecurity(path.c_str(), requestedFileInformation, security, length, &length)) { - HANDLE token = NULL; + HANDLE token = nullptr; const static DWORD tokenDesiredAccess = TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_DUPLICATE | STANDARD_RIGHTS_READ; if (!::OpenThreadToken(::GetCurrentThread(), tokenDesiredAccess, TRUE, &token)) { if (!::OpenProcessToken(::GetCurrentProcess(), tokenDesiredAccess, &token)) { @@ -206,7 +206,7 @@ bool HaveWriteAccess(const std::wstring &path) } } - HANDLE impersonatedToken = NULL; + HANDLE impersonatedToken = nullptr; if (::DuplicateToken(token, SecurityImpersonation, &impersonatedToken)) { GENERIC_MAPPING mapping = { 0xFFFFFFFF }; mapping.GenericRead = FILE_GENERIC_READ; @@ -297,7 +297,7 @@ int main(int argc, char *argv[]) if (!HaveWriteAccess(ToWString(application.applicationDirPath()))) { QStringList arguments = application.arguments(); arguments.pop_front(); - ::ShellExecuteW( NULL + ::ShellExecuteW( nullptr , L"runas" , ToWString(QString("\"%1\"").arg(QCoreApplication::applicationFilePath())).c_str() , ToWString(arguments.join(" ")).c_str() @@ -348,7 +348,7 @@ int main(int argc, char *argv[]) instance.sendMessage(arguments.at(1)); return 0; } else if (arguments.size() == 1) { - QMessageBox::information(NULL, QObject::tr("Mod Organizer"), QObject::tr("An instance of Mod Organizer is already running")); + QMessageBox::information(nullptr, QObject::tr("Mod Organizer"), QObject::tr("An instance of Mod Organizer is already running")); return 0; } } // we continue for the primary instance OR if MO has been called with parameters @@ -399,7 +399,7 @@ int main(int argc, char *argv[]) } else { gamePath = QDir::cleanPath(selection.getChoiceData().toString()); if (gamePath.isEmpty()) { - gamePath = QFileDialog::getExistingDirectory(NULL, QObject::tr("Please select the game to manage"), QString(), + gamePath = QFileDialog::getExistingDirectory(nullptr, QObject::tr("Please select the game to manage"), QString(), QFileDialog::ShowDirsOnly); } } @@ -426,7 +426,7 @@ int main(int argc, char *argv[]) if (!settings.contains("game_edition")) { std::vector editions = GameInfo::instance().getSteamVariants(); if (editions.size() > 1) { - SelectionDialog selection(QObject::tr("Please select the game edition you have (MO can't start the game correctly if this is set incorrectly!)"), NULL); + SelectionDialog selection(QObject::tr("Please select the game edition you have (MO can't start the game correctly if this is set incorrectly!)"), nullptr); int index = 0; for (auto iter = editions.begin(); iter != editions.end(); ++iter) { selection.addChoice(ToQString(*iter), "", index++); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index d4a7f4fc..0fdbdfad 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -336,7 +336,7 @@ MainWindow::~MainWindow() void MainWindow::disconnectPlugins() { - if (ui->actionTool->menu() != NULL) { + if (ui->actionTool->menu() != nullptr) { ui->actionTool->menu()->clear(); } } @@ -432,11 +432,11 @@ static QModelIndex mapToModel(const QAbstractItemModel *targetModel, QModelIndex QModelIndex result = idx; const QAbstractItemModel *model = idx.model(); while (model != targetModel) { - if (model == NULL) { + if (model == nullptr) { return QModelIndex(); } const QAbstractProxyModel *proxyModel = qobject_cast(model); - if (proxyModel == NULL) { + if (proxyModel == nullptr) { return QModelIndex(); } result = proxyModel->mapToSource(result); @@ -484,7 +484,7 @@ void MainWindow::updateToolBar() QWidget *widget = ui->toolBar->widgetForAction(ui->actionTool); QToolButton *toolBtn = qobject_cast(widget); - if (toolBtn->menu() == NULL) { + if (toolBtn->menu() == nullptr) { actionToToolButton(ui->actionTool); } @@ -600,7 +600,7 @@ void MainWindow::createHelpWidget() { QToolButton *toolBtn = qobject_cast(ui->toolBar->widgetForAction(ui->actionHelp)); QMenu *buttonMenu = toolBtn->menu(); - if (buttonMenu == NULL) { + if (buttonMenu == nullptr) { return; } buttonMenu->clear(); @@ -838,14 +838,14 @@ SaveGameGamebryo *MainWindow::getSaveGame(QListWidgetItem *item) return saveGame; } catch (const std::exception &e) { reportError(tr("failed to read savegame: %1").arg(e.what())); - return NULL; + return nullptr; } } void MainWindow::displaySaveGameInfo(const SaveGameGamebryo *save, QPoint pos) { - if (m_CurrentSaveView == NULL) { + if (m_CurrentSaveView == nullptr) { m_CurrentSaveView = new SaveGameInfoWidgetGamebryo(save, m_OrganizerCore.pluginList(), this); } else { m_CurrentSaveView->setSave(save); @@ -874,11 +874,11 @@ void MainWindow::displaySaveGameInfo(const SaveGameGamebryo *save, QPoint pos) void MainWindow::saveSelectionChanged(QListWidgetItem *newItem) { - if (newItem == NULL) { + if (newItem == nullptr) { hideSaveGameInfo(); - } else if ((m_CurrentSaveView == NULL) || (newItem != m_CurrentSaveView->property("displayItem").value())) { + } else if ((m_CurrentSaveView == nullptr) || (newItem != m_CurrentSaveView->property("displayItem").value())) { const SaveGameGamebryo *save = getSaveGame(newItem); - if (save != NULL) { + if (save != nullptr) { displaySaveGameInfo(save, QCursor::pos()); m_CurrentSaveView->setProperty("displayItem", qVariantFromValue((void*)newItem)); } @@ -889,10 +889,10 @@ void MainWindow::saveSelectionChanged(QListWidgetItem *newItem) void MainWindow::hideSaveGameInfo() { - if (m_CurrentSaveView != NULL) { + if (m_CurrentSaveView != nullptr) { disconnect(m_CurrentSaveView, SIGNAL(closeSaveInfo()), this, SLOT(hideSaveGameInfo())); m_CurrentSaveView->deleteLater(); - m_CurrentSaveView = NULL; + m_CurrentSaveView = nullptr; } } @@ -928,7 +928,7 @@ void MainWindow::modPagePluginInvoke() m_IntegratedBrowser.setWindowTitle(plugin->displayName()); m_IntegratedBrowser.openUrl(plugin->pageURL()); } else { - ::ShellExecuteW(NULL, L"open", ToWString(plugin->pageURL().toString()).c_str(), NULL, NULL, SW_SHOWNORMAL); + ::ShellExecuteW(nullptr, L"open", ToWString(plugin->pageURL().toString()).c_str(), nullptr, nullptr, SW_SHOWNORMAL); } } @@ -948,7 +948,7 @@ void MainWindow::registerPluginTool(IPluginTool *tool) void MainWindow::registerModPage(IPluginModPage *modPage) { // turn the browser action into a drop-down menu if necessary - if (ui->actionNexus->menu() == NULL) { + if (ui->actionNexus->menu() == nullptr) { QAction *nexusAction = ui->actionNexus; // TODO: use a different icon for nexus! ui->actionNexus = new QAction(nexusAction->icon(), tr("Browse Mod Page"), ui->toolBar); @@ -973,7 +973,7 @@ void MainWindow::registerModPage(IPluginModPage *modPage) void MainWindow::startExeAction() { QAction *action = qobject_cast(sender()); - if (action != NULL) { + if (action != nullptr) { Executable selectedExecutable = action->data().value(); m_OrganizerCore.spawnBinary( selectedExecutable.m_BinaryInfo, @@ -1016,7 +1016,7 @@ void MainWindow::on_profileBox_currentIndexChanged(int index) m_OldProfileIndex = index; if ((previousIndex != -1) && - (m_OrganizerCore.currentProfile() != NULL) && + (m_OrganizerCore.currentProfile() != nullptr) && m_OrganizerCore.currentProfile()->exists()) { m_OrganizerCore.saveCurrentLists(); } @@ -1155,7 +1155,7 @@ void MainWindow::expandDataTreeItem(QTreeWidgetItem *item) std::wstring virtualPath = (path + L"\\").substr(6) + ToWString(item->text(0)); DirectoryEntry *dir = m_OrganizerCore.directoryStructure()->findSubDirectoryRecursive(virtualPath); - if (dir != NULL) { + if (dir != nullptr) { updateTo(item, path, *dir, conflictsOnly); } else { qWarning("failed to update view of %ls", path.c_str()); @@ -1227,7 +1227,7 @@ extern QPixmap qt_pixmapFromWinHICON(HICON icon); QIcon MainWindow::iconForExecutable(const QString &filePath) { HICON winIcon; - UINT res = ::ExtractIconExW(ToWString(filePath).c_str(), 0, &winIcon, NULL, 1); + UINT res = ::ExtractIconExW(ToWString(filePath).c_str(), 0, &winIcon, nullptr, 1); if (res == 1) { QIcon result = QIcon(qt_pixmapFromWinHICON(winIcon)); ::DestroyIcon(winIcon); @@ -1397,7 +1397,7 @@ void MainWindow::updateBSAList(const QStringList &defaultArchives, const QString modName = modInfo->name(); } QList items = ui->bsaList->findItems(modName, Qt::MatchFixedString); - QTreeWidgetItem *subItem = NULL; + QTreeWidgetItem *subItem = nullptr; if (items.length() > 0) { subItem = items.at(0); } else { @@ -1648,14 +1648,14 @@ static HRESULT CreateShortcut(LPCWSTR targetFileName, LPCWSTR arguments, LPCWSTR currentDirectory) { HRESULT result = E_INVALIDARG; - if ((targetFileName != NULL) && (wcslen(targetFileName) > 0) && - (arguments != NULL) && - (linkFileName != NULL) && (strlen(linkFileName) > 0) && - (description != NULL) && - (currentDirectory != NULL)) { + if ((targetFileName != nullptr) && (wcslen(targetFileName) > 0) && + (arguments != nullptr) && + (linkFileName != nullptr) && (strlen(linkFileName) > 0) && + (description != nullptr) && + (currentDirectory != nullptr)) { IShellLink* shellLink; - result = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, + result = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&shellLink); if (!SUCCEEDED(result)) { @@ -1755,19 +1755,19 @@ void MainWindow::helpTriggered() void MainWindow::wikiTriggered() { -// ::ShellExecuteW(NULL, L"open", L"http://issue.tannin.eu/tbg/wiki/Modorganizer%3AMainPage", NULL, NULL, SW_SHOWNORMAL); - ::ShellExecuteW(NULL, L"open", L"http://wiki.step-project.com/Guide:Mod_Organizer", NULL, NULL, SW_SHOWNORMAL); +// ::ShellExecuteW(nullptr, L"open", L"http://issue.tannin.eu/tbg/wiki/Modorganizer%3AMainPage", nullptr, nullptr, SW_SHOWNORMAL); + ::ShellExecuteW(nullptr, L"open", L"http://wiki.step-project.com/Guide:Mod_Organizer", nullptr, nullptr, SW_SHOWNORMAL); } void MainWindow::issueTriggered() { - ::ShellExecuteW(NULL, L"open", L"http://issue.tannin.eu/tbg", NULL, NULL, SW_SHOWNORMAL); + ::ShellExecuteW(nullptr, L"open", L"http://issue.tannin.eu/tbg", nullptr, nullptr, SW_SHOWNORMAL); } void MainWindow::tutorialTriggered() { QAction *tutorialAction = qobject_cast(sender()); - if (tutorialAction != NULL) { + if (tutorialAction != nullptr) { if (QMessageBox::question(this, tr("Start Tutorial?"), tr("You're about to start a tutorial. For technical reasons it's not possible to end " "the tutorial early. Continue?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { @@ -1870,7 +1870,7 @@ void MainWindow::modorder_changed() ModInfo::Ptr modInfo = ModInfo::getByIndex(current.data(Qt::UserRole + 1).toInt()); modInfo->doConflictCheck(); m_OrganizerCore.modList()->setOverwriteMarkers(modInfo->getModOverwrite(), modInfo->getModOverwritten()); - if (m_ModListSortProxy != NULL) { + if (m_ModListSortProxy != nullptr) { m_ModListSortProxy->invalidate(); } ui->modList->verticalScrollBar()->repaint(); @@ -2007,7 +2007,7 @@ void MainWindow::modlistChanged(int) void MainWindow::fileMoved(const QString &filePath, const QString &oldOriginName, const QString &newOriginName) { const FileEntry::Ptr filePtr = m_OrganizerCore.directoryStructure()->findFile(ToWString(filePath)); - if (filePtr.get() != NULL) { + if (filePtr.get() != nullptr) { try { if (m_OrganizerCore.directoryStructure()->originExists(ToWString(newOriginName))) { FilesOrigin &newOrigin = m_OrganizerCore.directoryStructure()->getOriginByName(ToWString(newOriginName)); @@ -2035,7 +2035,7 @@ QTreeWidgetItem *MainWindow::addFilterItem(QTreeWidgetItem *root, const QString QTreeWidgetItem *item = new QTreeWidgetItem(QStringList(name)); item->setData(0, Qt::UserRole, categoryID); item->setData(0, Qt::UserRole + 1, type); - if (root != NULL) { + if (root != nullptr) { root->addChild(item); } else { ui->categoriesList->addTopLevelItem(item); @@ -2046,7 +2046,7 @@ QTreeWidgetItem *MainWindow::addFilterItem(QTreeWidgetItem *root, const QString void MainWindow::addContentFilters() { for (unsigned i = 0; i < ModInfo::NUM_CONTENT_TYPES; ++i) { - addFilterItem(NULL, tr("").arg(ModInfo::getContentTypeName(i)), i, ModListSortProxy::TYPE_CONTENT); + addFilterItem(nullptr, tr("").arg(ModInfo::getContentTypeName(i)), i, ModListSortProxy::TYPE_CONTENT); } } @@ -2079,14 +2079,14 @@ void MainWindow::refreshFilters() } ui->categoriesList->clear(); - addFilterItem(NULL, tr(""), CategoryFactory::CATEGORY_SPECIAL_CHECKED, ModListSortProxy::TYPE_SPECIAL); - addFilterItem(NULL, tr(""), CategoryFactory::CATEGORY_SPECIAL_UNCHECKED, ModListSortProxy::TYPE_SPECIAL); - addFilterItem(NULL, tr(""), CategoryFactory::CATEGORY_SPECIAL_UPDATEAVAILABLE, ModListSortProxy::TYPE_SPECIAL); - addFilterItem(NULL, tr(""), CategoryFactory::CATEGORY_SPECIAL_MANAGED, ModListSortProxy::TYPE_SPECIAL); - addFilterItem(NULL, tr(""), CategoryFactory::CATEGORY_SPECIAL_UNMANAGED, ModListSortProxy::TYPE_SPECIAL); - addFilterItem(NULL, tr(""), CategoryFactory::CATEGORY_SPECIAL_NOCATEGORY, ModListSortProxy::TYPE_SPECIAL); - addFilterItem(NULL, tr(""), CategoryFactory::CATEGORY_SPECIAL_CONFLICT, ModListSortProxy::TYPE_SPECIAL); - addFilterItem(NULL, tr(""), CategoryFactory::CATEGORY_SPECIAL_NOTENDORSED, ModListSortProxy::TYPE_SPECIAL); + addFilterItem(nullptr, tr(""), CategoryFactory::CATEGORY_SPECIAL_CHECKED, ModListSortProxy::TYPE_SPECIAL); + addFilterItem(nullptr, tr(""), CategoryFactory::CATEGORY_SPECIAL_UNCHECKED, ModListSortProxy::TYPE_SPECIAL); + addFilterItem(nullptr, tr(""), CategoryFactory::CATEGORY_SPECIAL_UPDATEAVAILABLE, ModListSortProxy::TYPE_SPECIAL); + addFilterItem(nullptr, tr(""), CategoryFactory::CATEGORY_SPECIAL_MANAGED, ModListSortProxy::TYPE_SPECIAL); + addFilterItem(nullptr, tr(""), CategoryFactory::CATEGORY_SPECIAL_UNMANAGED, ModListSortProxy::TYPE_SPECIAL); + addFilterItem(nullptr, tr(""), CategoryFactory::CATEGORY_SPECIAL_NOCATEGORY, ModListSortProxy::TYPE_SPECIAL); + addFilterItem(nullptr, tr(""), CategoryFactory::CATEGORY_SPECIAL_CONFLICT, ModListSortProxy::TYPE_SPECIAL); + addFilterItem(nullptr, tr(""), CategoryFactory::CATEGORY_SPECIAL_NOTENDORSED, ModListSortProxy::TYPE_SPECIAL); addContentFilters(); @@ -2103,7 +2103,7 @@ void MainWindow::refreshFilters() } } - addCategoryFilters(NULL, categoriesUsed, 0); + addCategoryFilters(nullptr, categoriesUsed, 0); foreach (const QString &item, selectedItems) { QList matches = ui->categoriesList->findItems(item, Qt::MatchFixedString | Qt::MatchRecursive); @@ -2166,7 +2166,7 @@ void MainWindow::modlistSelectionChanged(const QModelIndex ¤t, const QMode } else { m_OrganizerCore.modList()->setOverwriteMarkers(std::set(), std::set()); } - if ((m_ModListSortProxy != NULL) + if ((m_ModListSortProxy != nullptr) && !m_ModListSortProxy->beingInvalidated()) { m_ModListSortProxy->invalidate(); } @@ -2322,7 +2322,7 @@ void MainWindow::windowTutorialFinished(const QString &windowName) void MainWindow::overwriteClosed(int) { OverwriteInfoDialog *dialog = this->findChild("__overwriteDialog"); - if (dialog != NULL) { + if (dialog != nullptr) { m_OrganizerCore.modList()->modInfoChanged(dialog->modInfo()); dialog->deleteLater(); } @@ -2336,7 +2336,7 @@ void MainWindow::displayModInformation(ModInfo::Ptr modInfo, unsigned int index, if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end()) { QDialog *dialog = this->findChild("__overwriteDialog"); try { - if (dialog == NULL) { + if (dialog == nullptr) { dialog = new OverwriteInfoDialog(modInfo, this); dialog->setObjectName("__overwriteDialog"); } else { @@ -2483,7 +2483,7 @@ void MainWindow::openExplorer_clicked() { ModInfo::Ptr modInfo = ModInfo::getByIndex(m_ContextRow); - ::ShellExecuteW(NULL, L"explore", ToWString(modInfo->absolutePath()).c_str(), NULL, NULL, SW_SHOWNORMAL); + ::ShellExecuteW(nullptr, L"explore", ToWString(modInfo->absolutePath()).c_str(), nullptr, nullptr, SW_SHOWNORMAL); } void MainWindow::information_clicked() @@ -2523,13 +2523,13 @@ void MainWindow::createModFromOverwrite() } } - if (m_OrganizerCore.getMod(name) != NULL) { + if (m_OrganizerCore.getMod(name) != nullptr) { reportError(tr("A mod with this name already exists")); return; } IModInterface *newMod = m_OrganizerCore.createMod(name); - if (newMod == NULL) { + if (newMod == nullptr) { return; } @@ -2610,11 +2610,11 @@ void MainWindow::replaceCategoriesFromMenu(QMenu *menu, int modRow) { ModInfo::Ptr modInfo = ModInfo::getByIndex(modRow); foreach (QAction* action, menu->actions()) { - if (action->menu() != NULL) { + if (action->menu() != nullptr) { replaceCategoriesFromMenu(action->menu(), modRow); } else { QWidgetAction *widgetAction = qobject_cast(action); - if (widgetAction != NULL) { + if (widgetAction != nullptr) { QCheckBox *checkbox = qobject_cast(widgetAction->defaultWidget()); modInfo->setCategory(widgetAction->data().toInt(), checkbox->isChecked()); } @@ -2627,11 +2627,11 @@ void MainWindow::addRemoveCategoriesFromMenu(QMenu *menu, int modRow, int refere if (referenceRow != -1 && referenceRow != modRow) { ModInfo::Ptr editedModInfo = ModInfo::getByIndex(referenceRow); foreach (QAction* action, menu->actions()) { - if (action->menu() != NULL) { + if (action->menu() != nullptr) { addRemoveCategoriesFromMenu(action->menu(), modRow, referenceRow); } else { QWidgetAction *widgetAction = qobject_cast(action); - if (widgetAction != NULL) { + if (widgetAction != nullptr) { QCheckBox *checkbox = qobject_cast(widgetAction->defaultWidget()); int categoryId = widgetAction->data().toInt(); bool checkedBefore = editedModInfo->categorySet(categoryId); @@ -2651,7 +2651,7 @@ void MainWindow::addRemoveCategoriesFromMenu(QMenu *menu, int modRow, int refere void MainWindow::addRemoveCategories_MenuHandler() { QMenu *menu = qobject_cast(sender()); - if (menu == NULL) { + if (menu == nullptr) { qCritical("not a menu?"); return; } @@ -2688,7 +2688,7 @@ void MainWindow::addRemoveCategories_MenuHandler() { void MainWindow::replaceCategories_MenuHandler() { QMenu *menu = qobject_cast(sender()); - if (menu == NULL) { + if (menu == nullptr) { qCritical("not a menu?"); return; } @@ -2726,14 +2726,14 @@ void MainWindow::replaceCategories_MenuHandler() { void MainWindow::savePrimaryCategory() { QMenu *menu = qobject_cast(sender()); - if (menu == NULL) { + if (menu == nullptr) { qCritical("not a menu?"); return; } foreach (QAction* action, menu->actions()) { QWidgetAction *widgetAction = qobject_cast(action); - if (widgetAction != NULL) { + if (widgetAction != nullptr) { QRadioButton *btn = qobject_cast(widgetAction->defaultWidget()); if (btn->isChecked()) { QModelIndexList selected = ui->modList->selectionModel()->selectedRows(); @@ -2854,7 +2854,7 @@ void MainWindow::addPrimaryCategoryCandidates(QMenu *primaryCategoryMenu, ModInf void MainWindow::addPrimaryCategoryCandidates() { QMenu *menu = qobject_cast(sender()); - if (menu == NULL) { + if (menu == nullptr) { qCritical("not a menu?"); return; } @@ -2866,7 +2866,7 @@ void MainWindow::addPrimaryCategoryCandidates() void MainWindow::enableVisibleMods() { - if (QMessageBox::question(NULL, tr("Confirm"), tr("Really enable all visible mods?"), + if (QMessageBox::question(nullptr, tr("Confirm"), tr("Really enable all visible mods?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { m_ModListSortProxy->enableAllVisible(); } @@ -2874,7 +2874,7 @@ void MainWindow::enableVisibleMods() void MainWindow::disableVisibleMods() { - if (QMessageBox::question(NULL, tr("Confirm"), tr("Really disable all visible mods?"), + if (QMessageBox::question(nullptr, tr("Confirm"), tr("Really disable all visible mods?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { m_ModListSortProxy->disableAllVisible(); } @@ -2967,7 +2967,7 @@ void MainWindow::on_modList_customContextMenuRequested(const QPoint &pos) m_ContextIdx = mapToModel(m_OrganizerCore.modList(), modList->indexAt(pos)); m_ContextRow = m_ContextIdx.row(); - QMenu *menu = NULL; + QMenu *menu = nullptr; QMenu *allMods = modListContextMenu(); if (m_ContextRow == -1) { // no selection @@ -3121,7 +3121,7 @@ void MainWindow::fixMods_clicked() { QListWidgetItem *selectedItem = ui->savegameList->currentItem(); - if (selectedItem == NULL) + if (selectedItem == nullptr) return; // if required, parse the save game @@ -3345,20 +3345,20 @@ void MainWindow::on_actionSettings_triggered() void MainWindow::on_actionNexus_triggered() { - ::ShellExecuteW(NULL, L"open", GameInfo::instance().getNexusPage(false).c_str(), NULL, NULL, SW_SHOWNORMAL); + ::ShellExecuteW(nullptr, L"open", GameInfo::instance().getNexusPage(false).c_str(), nullptr, nullptr, SW_SHOWNORMAL); } void MainWindow::nexusLinkActivated(const QString &link) { - ::ShellExecuteW(NULL, L"open", ToWString(link).c_str(), NULL, NULL, SW_SHOWNORMAL); + ::ShellExecuteW(nullptr, L"open", ToWString(link).c_str(), nullptr, nullptr, SW_SHOWNORMAL); ui->tabWidget->setCurrentIndex(4); } void MainWindow::linkClicked(const QString &url) { - ::ShellExecuteW(NULL, L"open", ToWString(url).c_str(), NULL, NULL, SW_SHOWNORMAL); + ::ShellExecuteW(nullptr, L"open", ToWString(url).c_str(), nullptr, nullptr, SW_SHOWNORMAL); } @@ -3470,7 +3470,7 @@ int MainWindow::getBinaryExecuteInfo(const QFileInfo &targetInfo, { // try to find java automatically WCHAR buffer[MAX_PATH]; - if (::FindExecutableW(targetPathW.c_str(), NULL, buffer) > (HINSTANCE)32) { + if (::FindExecutableW(targetPathW.c_str(), nullptr, buffer) > (HINSTANCE)32) { DWORD binaryType = 0UL; if (!::GetBinaryTypeW(targetPathW.c_str(), &binaryType)) { qDebug("failed to determine binary type of \"%ls\": %lu", targetPathW.c_str(), ::GetLastError()); @@ -3507,7 +3507,7 @@ int MainWindow::getBinaryExecuteInfo(const QFileInfo &targetInfo, void MainWindow::addAsExecutable() { - if (m_ContextItem != NULL) { + if (m_ContextItem != nullptr) { QFileInfo targetInfo(m_ContextItem->data(0, Qt::UserRole).toString()); QFileInfo binaryInfo; QString arguments; @@ -3605,9 +3605,9 @@ void MainWindow::previewDataFile() offset = fileName.indexOf("/", offset); fileName = fileName.mid(offset + 1); - const FileEntry::Ptr file = m_OrganizerCore.directoryStructure()->searchFile(ToWString(fileName), NULL); + const FileEntry::Ptr file = m_OrganizerCore.directoryStructure()->searchFile(ToWString(fileName), nullptr); - if (file.get() == NULL) { + if (file.get() == nullptr) { reportError(tr("file not found: %1").arg(fileName)); return; } @@ -3641,7 +3641,7 @@ void MainWindow::previewDataFile() void MainWindow::openDataFile() { - if (m_ContextItem != NULL) { + if (m_ContextItem != nullptr) { QFileInfo targetInfo(m_ContextItem->data(0, Qt::UserRole).toString()); QFileInfo binaryInfo; QString arguments; @@ -3650,7 +3650,7 @@ void MainWindow::openDataFile() m_OrganizerCore.spawnBinaryDirect(binaryInfo, arguments, m_OrganizerCore.currentProfile()->getName(), targetInfo.absolutePath(), ""); } break; case 2: { - ::ShellExecuteW(NULL, L"open", ToWString(targetInfo.absoluteFilePath()).c_str(), NULL, NULL, SW_SHOWNORMAL); + ::ShellExecuteW(nullptr, L"open", ToWString(targetInfo.absoluteFilePath()).c_str(), nullptr, nullptr, SW_SHOWNORMAL); } break; default: { // nop @@ -3702,7 +3702,7 @@ void MainWindow::on_dataTree_customContextMenuRequested(const QPoint &pos) m_ContextItem = dataTree->itemAt(pos.x(), pos.y()); QMenu menu; - if ((m_ContextItem != NULL) && (m_ContextItem->childCount() == 0)) { + if ((m_ContextItem != nullptr) && (m_ContextItem->childCount() == 0)) { menu.addAction(tr("Open/Execute"), this, SLOT(openDataFile())); menu.addAction(tr("Add as Executable"), this, SLOT(addAsExecutable())); @@ -3984,9 +3984,9 @@ void MainWindow::displayColumnSelection(const QPoint &pos) int i = 1; foreach (const QAction *action, menu.actions()) { const QWidgetAction *widgetAction = qobject_cast(action); - if (widgetAction != NULL) { + if (widgetAction != nullptr) { const QCheckBox *checkBox = qobject_cast(widgetAction->defaultWidget()); - if (checkBox != NULL) { + if (checkBox != nullptr) { ui->modList->header()->setSectionHidden(i, !checkBox->isChecked()); } } @@ -4109,7 +4109,7 @@ void MainWindow::removeFromToolbar() void MainWindow::toolBar_customContextMenuRequested(const QPoint &point) { QAction *action = ui->toolBar->actionAt(point); - if (action != NULL) { + if (action != nullptr) { if (action->objectName().startsWith("custom_")) { m_ContextAction = action; QMenu menu; @@ -4161,10 +4161,10 @@ void MainWindow::on_espList_customContextMenuRequested(const QPoint &pos) void MainWindow::on_groupCombo_currentIndexChanged(int index) { - if (m_ModListSortProxy == NULL) { + if (m_ModListSortProxy == nullptr) { return; } - QAbstractProxyModel *newModel = NULL; + QAbstractProxyModel *newModel = nullptr; switch (index) { case 1: { newModel = new QtGroupingProxy(m_OrganizerCore.modList(), QModelIndex(), ModList::COL_CATEGORY, Qt::UserRole, @@ -4176,11 +4176,11 @@ void MainWindow::on_groupCombo_currentIndexChanged(int index) Qt::UserRole + 2); } break; default: { - newModel = NULL; + newModel = nullptr; } break; } - if (newModel != NULL) { + if (newModel != nullptr) { #ifdef TEST_MODELS new ModelTest(newModel, this); #endif // TEST_MODELS @@ -4220,7 +4220,7 @@ void MainWindow::createStdoutPipe(HANDLE *stdOutRead, HANDLE *stdOutWrite) SECURITY_ATTRIBUTES secAttributes; secAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); secAttributes.bInheritHandle = TRUE; - secAttributes.lpSecurityDescriptor = NULL; + secAttributes.lpSecurityDescriptor = nullptr; if (!::CreatePipe(stdOutRead, stdOutWrite, &secAttributes, 0)) { qCritical("failed to create stdout reroute"); @@ -4242,7 +4242,7 @@ std::string MainWindow::readFromPipe(HANDLE stdOutRead) DWORD read = 1; while (read > 0) { - if (!::ReadFile(stdOutRead, buffer, chunkSize, &read, NULL)) { + if (!::ReadFile(stdOutRead, buffer, chunkSize, &read, nullptr)) { break; } if (read > 0) { diff --git a/src/messagedialog.cpp b/src/messagedialog.cpp index 36902bbf..90b0a9d3 100644 --- a/src/messagedialog.cpp +++ b/src/messagedialog.cpp @@ -52,7 +52,7 @@ MessageDialog::MessageDialog(const QString &text, QWidget *reference) : this->setFocusPolicy(Qt::NoFocus); this->setAttribute(Qt::WA_ShowWithoutActivating); QTimer::singleShot(1000 + (text.length() * 40), this, SLOT(hide())); - if (reference != NULL) { + if (reference != nullptr) { QPoint position = reference->mapToGlobal(QPoint(reference->width() / 2, reference->height())); position.rx() -= this->width() / 2; position.ry() -= this->height() + 5; @@ -70,7 +70,7 @@ MessageDialog::~MessageDialog() void MessageDialog::resizeEvent(QResizeEvent *event) { QWidget *par = parentWidget(); - if (par != NULL) { + if (par != nullptr) { QPoint position = par->mapToGlobal(QPoint(par->width() / 2, par->height())); position.rx() -= event->size().width() / 2; position.ry() -= event->size().height() + 5; @@ -83,7 +83,7 @@ void MessageDialog::showMessage(const QString &text, QWidget *reference, bool br { qDebug("%s", qPrintable(text)); if (reference != nullptr) { - if (bringToFront || (qApp->activeWindow() != NULL)) { + if (bringToFront || (qApp->activeWindow() != nullptr)) { MessageDialog *dialog = new MessageDialog(text, reference); dialog->show(); reference->activateWindow(); diff --git a/src/modinfo.cpp b/src/modinfo.cpp index d773823a..aa831e04 100644 --- a/src/modinfo.cpp +++ b/src/modinfo.cpp @@ -639,7 +639,7 @@ void ModInfoRegular::nxmRequestFailed(int, int, QVariant userData, const QString if (userData.canConvert() && (userData.toInt() == 1)) { fullMessage += "\nNexus will reject endorsements within 15 Minutes of a failed attempt, the error message may be misleading."; } - if (QApplication::activeWindow() != NULL) { + if (QApplication::activeWindow() != nullptr) { MessageDialog::showMessage(fullMessage, QApplication::activeWindow()); } emit modDetailsUpdated(false); diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp index 9133b166..0dfdd1f4 100644 --- a/src/modinfodialog.cpp +++ b/src/modinfodialog.cpp @@ -63,8 +63,8 @@ bool operator<(const ModFileListWidget &LHS, const ModFileListWidget &RHS) ModInfoDialog::ModInfoDialog(ModInfo::Ptr modInfo, const DirectoryEntry *directory, bool unmanaged, QWidget *parent) : TutorableDialog("ModInfoDialog", parent), ui(new Ui::ModInfoDialog), m_ModInfo(modInfo), m_ThumbnailMapper(this), m_RequestStarted(false), - m_DeleteAction(NULL), m_RenameAction(NULL), m_OpenAction(NULL), - m_Directory(directory), m_Origin(NULL) + m_DeleteAction(nullptr), m_RenameAction(nullptr), m_OpenAction(nullptr), + m_Directory(directory), m_Origin(nullptr) { ui->setupUi(this); this->setWindowTitle(modInfo->name()); @@ -90,7 +90,7 @@ ModInfoDialog::ModInfoDialog(ModInfo::Ptr modInfo, const DirectoryEntry *directo if (directory->originExists(ToWString(modInfo->name()))) { m_Origin = &directory->getOriginByName(ToWString(modInfo->name())); if (m_Origin->isDisabled()) { - m_Origin = NULL; + m_Origin = nullptr; } } @@ -115,7 +115,7 @@ ModInfoDialog::ModInfoDialog(ModInfo::Ptr modInfo, const DirectoryEntry *directo } initINITweaks(); - ui->tabWidget->setTabEnabled(TAB_CONFLICTS, m_Origin != NULL); + ui->tabWidget->setTabEnabled(TAB_CONFLICTS, m_Origin != nullptr); if (ui->tabWidget->currentIndex() == TAB_NEXUS) { activateNexusTab(); @@ -248,7 +248,7 @@ void ModInfoDialog::refreshLists() ui->overwriteTree->clear(); ui->overwrittenTree->clear(); - if (m_Origin != NULL) { + if (m_Origin != nullptr) { std::vector files = m_Origin->getFiles(); for (auto iter = files.begin(); iter != files.end(); ++iter) { QString relativeName = QDir::fromNativeSeparators(ToQString((*iter)->getRelativePath())); @@ -692,7 +692,7 @@ void ModInfoDialog::linkClicked(const QUrl &url) this->close(); emit nexusLinkActivated(url.toString()); } else { - ::ShellExecuteW(NULL, L"open", ToWString(url.toString()).c_str(), NULL, NULL, SW_SHOWNORMAL); + ::ShellExecuteW(nullptr, L"open", ToWString(url.toString()).c_str(), nullptr, nullptr, SW_SHOWNORMAL); } } @@ -981,7 +981,7 @@ void ModInfoDialog::openFile(const QModelIndex &index) { QString fileName = m_FileSystemModel->filePath(index); - HINSTANCE res = ::ShellExecuteW(NULL, L"open", ToWString(fileName).c_str(), NULL, NULL, SW_SHOW); + HINSTANCE res = ::ShellExecuteW(nullptr, L"open", ToWString(fileName).c_str(), nullptr, nullptr, SW_SHOW); if ((int)res <= 32) { qCritical("failed to invoke %s: %d", fileName.toUtf8().constData(), res); } @@ -1065,7 +1065,7 @@ void ModInfoDialog::on_fileTree_customContextMenuRequested(const QPoint &pos) void ModInfoDialog::on_categoriesTree_itemChanged(QTreeWidgetItem *item, int) { QTreeWidgetItem *parent = item->parent(); - while ((parent != NULL) && ((parent->flags() & Qt::ItemIsUserCheckable) != 0) && (parent->checkState(0) == Qt::Unchecked)) { + while ((parent != nullptr) && ((parent->flags() & Qt::ItemIsUserCheckable) != 0) && (parent->checkState(0) == Qt::Unchecked)) { parent->setCheckState(0, Qt::Checked); parent = parent->parent(); } @@ -1184,7 +1184,7 @@ void ModInfoDialog::on_overwriteTree_customContextMenuRequested(const QPoint &po { m_ConflictsContextItem = ui->overwriteTree->itemAt(pos.x(), pos.y()); - if (m_ConflictsContextItem != NULL) { + if (m_ConflictsContextItem != nullptr) { // offer to hide/unhide file, but not for files from archives if (!m_ConflictsContextItem->data(1, Qt::UserRole + 2).toBool()) { QMenu menu; diff --git a/src/modlist.cpp b/src/modlist.cpp index fb8df15e..1bd7b0f0 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -50,8 +50,8 @@ using namespace MOBase; ModList::ModList(QObject *parent) : QAbstractItemModel(parent) - , m_Profile(NULL) - , m_NexusInterface(NULL) + , m_Profile(nullptr) + , m_NexusInterface(nullptr) , m_Modified(false) , m_FontMetrics(QFont()) , m_DropOnItems(false) @@ -177,7 +177,7 @@ QString ModList::contentsToToolTip(const std::vector &content QVariant ModList::data(const QModelIndex &modelIndex, int role) const { - if (m_Profile == NULL) return QVariant(); + if (m_Profile == nullptr) return QVariant(); if (!modelIndex.isValid()) return QVariant(); unsigned int modIndex = modelIndex.row(); int column = modelIndex.column(); @@ -410,7 +410,7 @@ bool ModList::renameMod(int index, const QString &newName) { QString nameFixed = newName; if (!fixDirectoryName(nameFixed) || nameFixed.isEmpty()) { - MessageDialog::showMessage(tr("Invalid name"), NULL); + MessageDialog::showMessage(tr("Invalid name"), nullptr); return false; } @@ -433,7 +433,7 @@ bool ModList::renameMod(int index, const QString &newName) bool ModList::setData(const QModelIndex &index, const QVariant &value, int role) { - if (m_Profile == NULL) return false; + if (m_Profile == nullptr) return false; if (static_cast(index.row()) >= ModInfo::getNumMods()) { return false; @@ -591,7 +591,7 @@ QStringList ModList::mimeTypes() const void ModList::changeModPriority(std::vector sourceIndices, int newPriority) { - if (m_Profile == NULL) return; + if (m_Profile == nullptr) return; emit layoutAboutToBeChanged(); Profile *profile = m_Profile; @@ -625,7 +625,7 @@ void ModList::changeModPriority(std::vector sourceIndices, int newPriority) void ModList::changeModPriority(int sourceIndex, int newPriority) { - if (m_Profile == NULL) return; + if (m_Profile == nullptr) return; emit layoutAboutToBeChanged(); m_Profile->setModPriority(sourceIndex, newPriority); @@ -839,7 +839,7 @@ bool ModList::dropMimeData(const QMimeData *mimeData, Qt::DropAction action, int return true; } - if (m_Profile == NULL) return false; + if (m_Profile == nullptr) return false; if (mimeData->hasUrls()) { return dropURLs(mimeData, row, parent); } else { @@ -854,7 +854,7 @@ void ModList::removeRowForce(int row) if (static_cast(row) >= ModInfo::getNumMods()) { return; } - if (m_Profile == NULL) return; + if (m_Profile == nullptr) return; m_Profile->setModEnabled(row, false); @@ -882,7 +882,7 @@ void ModList::removeRow(int row, const QModelIndex&) if (static_cast(row) >= ModInfo::getNumMods()) { return; } - if (m_Profile == NULL) return; + if (m_Profile == nullptr) return; m_Profile->setModEnabled(row, false); @@ -992,28 +992,28 @@ bool ModList::eventFilter(QObject *obj, QEvent *event) if (event->type() == QEvent::ContextMenu) { QContextMenuEvent *contextEvent = static_cast(event); QWidget *object = qobject_cast(obj); - if ((object != NULL) && (contextEvent->reason() == QContextMenuEvent::Mouse)) { + if ((object != nullptr) && (contextEvent->reason() == QContextMenuEvent::Mouse)) { emit requestColumnSelect(object->mapToGlobal(contextEvent->pos())); return true; } - } else if ((event->type() == QEvent::KeyPress) && (m_Profile != NULL)) { + } else if ((event->type() == QEvent::KeyPress) && (m_Profile != nullptr)) { QAbstractItemView *itemView = qobject_cast(obj); QKeyEvent *keyEvent = static_cast(event); - if ((itemView != NULL) + if ((itemView != nullptr) && (keyEvent->modifiers() == Qt::ControlModifier) && ((keyEvent->key() == Qt::Key_Up) || (keyEvent->key() == Qt::Key_Down))) { QItemSelectionModel *selectionModel = itemView->selectionModel(); const QAbstractProxyModel *proxyModel = qobject_cast(selectionModel->model()); - const QSortFilterProxyModel *filterModel = NULL; - while ((filterModel == NULL) && (proxyModel != NULL)) { + const QSortFilterProxyModel *filterModel = nullptr; + while ((filterModel == nullptr) && (proxyModel != nullptr)) { filterModel = qobject_cast(proxyModel); - if (filterModel == NULL) { + if (filterModel == nullptr) { proxyModel = qobject_cast(proxyModel->sourceModel()); } } - if (filterModel == NULL) { + if (filterModel == nullptr) { return true; } int diff = -1; @@ -1028,7 +1028,7 @@ bool ModList::eventFilter(QObject *obj, QEvent *event) } } foreach (QModelIndex idx, rows) { - if (filterModel != NULL) { + if (filterModel != nullptr) { idx = filterModel->mapToSource(idx); } int newPriority = m_Profile->getModPriority(idx.row()) + diff; @@ -1054,7 +1054,7 @@ bool ModList::eventFilter(QObject *obj, QEvent *event) QModelIndex minRow, maxRow; foreach (QModelIndex idx, selectionModel->selectedRows()) { - if (proxyModel != NULL) { + if (proxyModel != nullptr) { idx = proxyModel->mapToSource(idx); } if (!minRow.isValid() || (idx.row() < minRow.row())) { diff --git a/src/modlist.h b/src/modlist.h index cf52b2ec..8dcab2fa 100644 --- a/src/modlist.h +++ b/src/modlist.h @@ -73,7 +73,7 @@ public: * @brief constructor * @todo ensure this view works without a profile set, otherwise there are intransparent dependencies on the initialisation order **/ - ModList(QObject *parent = NULL); + ModList(QObject *parent = nullptr); ~ModList(); diff --git a/src/modlistsortproxy.cpp b/src/modlistsortproxy.cpp index e132b71e..d16f8353 100644 --- a/src/modlistsortproxy.cpp +++ b/src/modlistsortproxy.cpp @@ -81,7 +81,7 @@ Qt::ItemFlags ModListSortProxy::flags(const QModelIndex &modelIndex) const void ModListSortProxy::enableAllVisible() { - if (m_Profile == NULL) return; + if (m_Profile == nullptr) return; for (int i = 0; i < this->rowCount(); ++i) { int modID = mapToSource(index(i, 0)).data(Qt::UserRole + 1).toInt(); @@ -92,7 +92,7 @@ void ModListSortProxy::enableAllVisible() void ModListSortProxy::disableAllVisible() { - if (m_Profile == NULL) return; + if (m_Profile == nullptr) return; for (int i = 0; i < this->rowCount(); ++i) { int modID = mapToSource(index(i, 0)).data(Qt::UserRole + 1).toInt(); @@ -313,7 +313,7 @@ void ModListSortProxy::setFilterMode(ModListSortProxy::FilterMode mode) bool ModListSortProxy::filterAcceptsRow(int row, const QModelIndex &parent) const { - if (m_Profile == NULL) { + if (m_Profile == nullptr) { return false; } diff --git a/src/motddialog.cpp b/src/motddialog.cpp index 9fa2f005..59ace4d1 100644 --- a/src/motddialog.cpp +++ b/src/motddialog.cpp @@ -45,5 +45,5 @@ void MotDDialog::on_okButton_clicked() void MotDDialog::linkClicked(const QUrl &url) { - ::ShellExecuteW(NULL, L"open", MOBase::ToWString(url.toString()).c_str(), NULL, NULL, SW_SHOWNORMAL); + ::ShellExecuteW(nullptr, L"open", MOBase::ToWString(url.toString()).c_str(), nullptr, nullptr, SW_SHOWNORMAL); } diff --git a/src/nexusinterface.cpp b/src/nexusinterface.cpp index d68fe8fe..bd40921f 100644 --- a/src/nexusinterface.cpp +++ b/src/nexusinterface.cpp @@ -218,8 +218,8 @@ void NexusInterface::interpretNexusFileName(const QString &fileName, QString &mo QString r3Highlight(fileName); r3Highlight.insert(result.position(3) + result.length(3), "* ").insert(result.position(3), " *"); - selection.addChoice(candidate.c_str(), r3Highlight, strtol(candidate.c_str(), NULL, 10)); - selection.addChoice(candidate2.c_str() + offset, r2Highlight, abs(strtol(candidate2.c_str() + offset, NULL, 10))); + selection.addChoice(candidate.c_str(), r3Highlight, strtol(candidate.c_str(), nullptr, 10)); + selection.addChoice(candidate2.c_str() + offset, r2Highlight, abs(strtol(candidate2.c_str() + offset, nullptr, 10))); if (selection.exec() == QDialog::Accepted) { modID = selection.getChoiceData().toInt(); } else { @@ -229,7 +229,7 @@ void NexusInterface::interpretNexusFileName(const QString &fileName, QString &mo modID = -1; } } else { - modID = strtol(candidate.c_str(), NULL, 10); + modID = strtol(candidate.c_str(), nullptr, 10); } qDebug("mod id guessed: %s -> %d", qPrintable(fileName), modID); } else if (std::tr1::regex_search(fileNameUTF8.constData(), result, simpleexp)) { @@ -542,7 +542,7 @@ void NexusInterface::requestFinished() void NexusInterface::requestError(QNetworkReply::NetworkError) { QNetworkReply *reply = qobject_cast(sender()); - if (reply == NULL) { + if (reply == nullptr) { qWarning("invalid sender type"); return; } @@ -555,7 +555,7 @@ void NexusInterface::requestError(QNetworkReply::NetworkError) void NexusInterface::requestTimeout() { QTimer *timer = qobject_cast(sender()); - if (timer == NULL) { + if (timer == nullptr) { qWarning("invalid sender type"); return; } @@ -577,10 +577,10 @@ NexusInterface::NXMRequestInfo::NXMRequestInfo(int modID , int nexusGameId) : m_ModID(modID) , m_FileID(0) - , m_Reply(NULL) + , m_Reply(nullptr) , m_Type(type) , m_UserData(userData) - , m_Timeout(NULL) + , m_Timeout(nullptr) , m_Reroute(false) , m_ID(s_NextID.fetchAndAddAcquire(1)) , m_URL(url) @@ -598,10 +598,10 @@ NexusInterface::NXMRequestInfo::NXMRequestInfo(std::vector modIDList : m_ModID(-1) , m_ModIDList(modIDList) , m_FileID(0) - , m_Reply(NULL) + , m_Reply(nullptr) , m_Type(type) , m_UserData(userData) - , m_Timeout(NULL) + , m_Timeout(nullptr) , m_Reroute(false) , m_ID(s_NextID.fetchAndAddAcquire(1)) , m_URL(url) @@ -619,10 +619,10 @@ NexusInterface::NXMRequestInfo::NXMRequestInfo(int modID , int nexusGameId) : m_ModID(modID) , m_FileID(fileID) - , m_Reply(NULL) + , m_Reply(nullptr) , m_Type(type) , m_UserData(userData) - , m_Timeout(NULL) + , m_Timeout(nullptr) , m_Reroute(false) , m_ID(s_NextID.fetchAndAddAcquire(1)) , m_URL(url) diff --git a/src/noeditdelegate.cpp b/src/noeditdelegate.cpp index ab8a4880..d5147b9f 100644 --- a/src/noeditdelegate.cpp +++ b/src/noeditdelegate.cpp @@ -6,5 +6,5 @@ NoEditDelegate::NoEditDelegate(QObject *parent) } QWidget *NoEditDelegate::createEditor(QWidget*, const QStyleOptionViewItem&, const QModelIndex&) const { - return NULL; + return nullptr; } diff --git a/src/noeditdelegate.h b/src/noeditdelegate.h index d0ba2f68..6fd5ba76 100644 --- a/src/noeditdelegate.h +++ b/src/noeditdelegate.h @@ -5,7 +5,7 @@ class NoEditDelegate: public QStyledItemDelegate { public: - NoEditDelegate(QObject *parent = NULL); + NoEditDelegate(QObject *parent = nullptr); virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; }; diff --git a/src/nxmaccessmanager.cpp b/src/nxmaccessmanager.cpp index 18568dad..db314be6 100644 --- a/src/nxmaccessmanager.cpp +++ b/src/nxmaccessmanager.cpp @@ -44,7 +44,7 @@ using namespace MOShared; NXMAccessManager::NXMAccessManager(QObject *parent, const QString &moVersion) : QNetworkAccessManager(parent) - , m_LoginReply(NULL) + , m_LoginReply(nullptr) , m_ProgressDialog() , m_MOVersion(moVersion) , m_LoginAttempted(false) @@ -56,9 +56,9 @@ NXMAccessManager::NXMAccessManager(QObject *parent, const QString &moVersion) NXMAccessManager::~NXMAccessManager() { - if (m_LoginReply != NULL) { + if (m_LoginReply != nullptr) { m_LoginReply->deleteLater(); - m_LoginReply = NULL; + m_LoginReply = nullptr; } } @@ -104,13 +104,13 @@ bool NXMAccessManager::loggedIn() const bool NXMAccessManager::loginWaiting() const { - return m_LoginReply != NULL; + return m_LoginReply != nullptr; } void NXMAccessManager::login(const QString &username, const QString &password) { - if (m_LoginReply != NULL) { + if (m_LoginReply != nullptr) { return; } @@ -168,7 +168,7 @@ void NXMAccessManager::loginTimeout() { emit loginFailed(tr("timeout")); m_LoginReply->deleteLater(); - m_LoginReply = NULL; + m_LoginReply = nullptr; m_LoginAttempted = false; // this usually means we might have usccess later m_LoginTimeout.stop(); m_Username.clear(); @@ -180,10 +180,10 @@ void NXMAccessManager::loginError(QNetworkReply::NetworkError) { m_ProgressDialog.hide(); m_LoginTimeout.stop(); - if (m_LoginReply != NULL) { + if (m_LoginReply != nullptr) { emit loginFailed(m_LoginReply->errorString()); m_LoginReply->deleteLater(); - m_LoginReply = NULL; + m_LoginReply = nullptr; } else { emit loginFailed(tr("Unknown error")); } @@ -216,7 +216,7 @@ void NXMAccessManager::loginFinished() m_LoginTimeout.stop(); m_LoginReply->deleteLater(); - m_LoginReply = NULL; + m_LoginReply = nullptr; m_Username.clear(); m_Password.clear(); } diff --git a/src/organizercore.cpp b/src/organizercore.cpp index 751cc010..fe032eba 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -91,7 +91,7 @@ static bool testForSteam() if (processIDs[i] != 0) { HANDLE process = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processIDs[i]); - if (process != NULL) { + if (process != nullptr) { HMODULE module; DWORD ignore; @@ -463,7 +463,7 @@ MOBase::IModRepositoryBridge *OrganizerCore::createNexusBridge() const QString OrganizerCore::profileName() const { - if (m_CurrentProfile != NULL) { + if (m_CurrentProfile != nullptr) { return m_CurrentProfile->getName(); } else { return ""; @@ -472,7 +472,7 @@ QString OrganizerCore::profileName() const QString OrganizerCore::profilePath() const { - if (m_CurrentProfile != NULL) { + if (m_CurrentProfile != nullptr) { return m_CurrentProfile->getPath(); } else { return ""; @@ -493,7 +493,7 @@ MOBase::IModInterface *OrganizerCore::getMod(const QString &name) { unsigned int index = ModInfo::getIndex(name); if (index == UINT_MAX) { - return NULL; + return nullptr; } else { return ModInfo::getByIndex(index).data(); } @@ -502,7 +502,7 @@ MOBase::IModInterface *OrganizerCore::getMod(const QString &name) MOBase::IModInterface *OrganizerCore::createMod(GuessedValue &name) { if (!m_InstallationManager.testOverwrite(name)) { - return NULL; + return nullptr; } m_InstallationManager.setModsDirectory(m_Settings.getModDirectory()); @@ -670,7 +670,7 @@ QStringList OrganizerCore::listDirectories(const QString &directoryName) const { QStringList result; DirectoryEntry *dir = m_DirectoryStructure->findSubDirectoryRecursive(ToWString(directoryName)); - if (dir != NULL) { + if (dir != nullptr) { std::vector::iterator current, end; dir->getSubDirectories(current, end); for (; current != end; ++current) { @@ -684,7 +684,7 @@ QStringList OrganizerCore::findFiles(const QString &path, const std::functionfindSubDirectoryRecursive(ToWString(path)); - if (dir != NULL) { + if (dir != nullptr) { std::vector files = dir->getFiles(); foreach (FileEntry::Ptr file, files) { if (filter(ToQString(file->getFullPath()))) { @@ -700,9 +700,9 @@ QStringList OrganizerCore::findFiles(const QString &path, const std::functionsearchFile(ToWString(QFileInfo(fileName).fileName()), NULL); + const FileEntry::Ptr file = m_DirectoryStructure->searchFile(ToWString(QFileInfo(fileName).fileName()), nullptr); - if (file.get() != NULL) { + if (file.get() != nullptr) { result.append(ToQString(m_DirectoryStructure->getOriginByID(file->getOrigin()).getName())); foreach (int i, file->getAlternatives()) { result.append(ToQString(m_DirectoryStructure->getOriginByID(i).getName())); @@ -717,7 +717,7 @@ QList OrganizerCore::findFileInfos(const QString & { QList result; DirectoryEntry *dir = m_DirectoryStructure->findSubDirectoryRecursive(ToWString(path)); - if (dir != NULL) { + if (dir != nullptr) { std::vector files = dir->getFiles(); foreach (FileEntry::Ptr file, files) { IOrganizer::FileInfo info; @@ -987,7 +987,7 @@ bool OrganizerCore::waitForProcessOrJob(HANDLE handle, LPDWORD exitCode) res = ::MsgWaitForMultipleObjects(1, &handle, false, 500, QS_KEY | QS_MOUSE); } - if (exitCode != NULL) { + if (exitCode != nullptr) { ::GetExitCodeProcess(processHandle, exitCode); } ::CloseHandle(processHandle); diff --git a/src/organizerproxy.h b/src/organizerproxy.h index 625e86aa..aa2a7fab 100644 --- a/src/organizerproxy.h +++ b/src/organizerproxy.h @@ -38,7 +38,7 @@ public: virtual MOBase::IPluginList *pluginList(); virtual MOBase::IModList *modList(); virtual HANDLE startApplication(const QString &executable, const QStringList &args = QStringList(), const QString &cwd = "", const QString &profile = ""); - virtual bool waitForApplication(HANDLE handle, LPDWORD exitCode = NULL) const; + virtual bool waitForApplication(HANDLE handle, LPDWORD exitCode = nullptr) const; virtual void refreshModList(bool saveChanges); virtual bool onAboutToRun(const std::function &func); diff --git a/src/overwriteinfodialog.cpp b/src/overwriteinfodialog.cpp index d06922bc..e956b025 100644 --- a/src/overwriteinfodialog.cpp +++ b/src/overwriteinfodialog.cpp @@ -71,8 +71,8 @@ private: OverwriteInfoDialog::OverwriteInfoDialog(ModInfo::Ptr modInfo, QWidget *parent) - : QDialog(parent), ui(new Ui::OverwriteInfoDialog), m_FileSystemModel(NULL), - m_DeleteAction(NULL), m_RenameAction(NULL), m_OpenAction(NULL) + : QDialog(parent), ui(new Ui::OverwriteInfoDialog), m_FileSystemModel(nullptr), + m_DeleteAction(nullptr), m_RenameAction(nullptr), m_OpenAction(nullptr) { ui->setupUi(this); @@ -185,7 +185,7 @@ void OverwriteInfoDialog::openFile(const QModelIndex &index) { QString fileName = m_FileSystemModel->filePath(index); - HINSTANCE res = ::ShellExecuteW(NULL, L"open", ToWString(fileName).c_str(), NULL, NULL, SW_SHOW); + HINSTANCE res = ::ShellExecuteW(nullptr, L"open", ToWString(fileName).c_str(), nullptr, nullptr, SW_SHOW); if ((int)res <= 32) { qCritical("failed to invoke %s: %d", fileName.toUtf8().constData(), res); } diff --git a/src/pdll.h b/src/pdll.h index 6e1d06f3..22d74557 100644 --- a/src/pdll.h +++ b/src/pdll.h @@ -26,7 +26,7 @@ //check for dll handle //if this is the first call to the function then try to load it //if not then if the function was loaded successfully make a call to it -//otherwise return a NULL cast to the return parameter. +//otherwise return a nullptr cast to the return parameter. #define DECLARE_FUNCTION0(CallType, retVal, FuncName) \ typedef retVal (CallType* TYPE_##FuncName)(); \ @@ -38,17 +38,17 @@ { \ if (FUNC_LOADED != m_is##FuncName) \ {\ - m_##FuncName = NULL; \ + m_##FuncName = nullptr; \ m_##FuncName = (TYPE_##FuncName)GetProcAddress(m_dllHandle, #FuncName); \ m_is##FuncName = FUNC_LOADED;\ }\ - if (NULL != m_##FuncName) \ + if (nullptr != m_##FuncName) \ return m_##FuncName(); \ else \ - return (retVal)NULL; \ + return (retVal)nullptr; \ } \ else \ - return (retVal)NULL; \ + return (retVal)nullptr; \ } #define DECLARE_FUNCTION1(CallType,retVal, FuncName, Param1) \ @@ -61,17 +61,17 @@ { \ if (FUNC_LOADED != m_is##FuncName) \ {\ - m_##FuncName = NULL; \ + m_##FuncName = nullptr; \ m_##FuncName = (TYPE_##FuncName)GetProcAddress(m_dllHandle, #FuncName); \ m_is##FuncName = FUNC_LOADED;\ }\ - if (NULL != m_##FuncName) \ + if (nullptr != m_##FuncName) \ return m_##FuncName(p1); \ else \ - return (retVal)NULL; \ + return (retVal)nullptr; \ } \ else \ - return (retVal)NULL; \ + return (retVal)nullptr; \ } #define DECLARE_FUNCTION2(CallType,retVal, FuncName, Param1, Param2) \ @@ -84,17 +84,17 @@ {\ if (FUNC_LOADED != m_is##FuncName) \ {\ - m_##FuncName = NULL; \ + m_##FuncName = nullptr; \ m_##FuncName = (TYPE_##FuncName)GetProcAddress(m_dllHandle, #FuncName); \ m_is##FuncName = FUNC_LOADED;\ }\ - if (NULL != m_##FuncName) \ + if (nullptr != m_##FuncName) \ return m_##FuncName(p1, p2); \ else \ - return (retVal)NULL; \ + return (retVal)nullptr; \ } \ else\ - return (retVal)NULL; \ + return (retVal)nullptr; \ } #define DECLARE_FUNCTION3(CallType,retVal, FuncName, Param1, Param2, Param3) \ @@ -107,17 +107,17 @@ {\ if (FUNC_LOADED != m_is##FuncName) \ {\ - m_##FuncName = NULL; \ + m_##FuncName = nullptr; \ m_##FuncName = (TYPE_##FuncName)GetProcAddress(m_dllHandle, #FuncName); \ m_is##FuncName = FUNC_LOADED; \ }\ - if (NULL != m_##FuncName) \ + if (nullptr != m_##FuncName) \ return m_##FuncName(p1, p2, p3);\ else \ - return (retVal)NULL; \ + return (retVal)nullptr; \ } \ else\ - return (retVal)NULL; \ + return (retVal)nullptr; \ } #define DECLARE_FUNCTION4(CallType,retVal, FuncName, Param1, Param2, Param3, Param4) \ @@ -130,17 +130,17 @@ {\ if (FUNC_LOADED != m_is##FuncName) \ {\ - m_##FuncName = NULL; \ + m_##FuncName = nullptr; \ m_##FuncName = (TYPE_##FuncName)GetProcAddress(m_dllHandle, #FuncName); \ m_is##FuncName = FUNC_LOADED;\ }\ - if (NULL != m_##FuncName) \ + if (nullptr != m_##FuncName) \ return m_##FuncName(p1, p2, p3, p4);\ else \ - return (retVal)NULL; \ + return (retVal)nullptr; \ } \ else\ - return (retVal)NULL; \ + return (retVal)nullptr; \ } #define DECLARE_FUNCTION5(CallType,retVal, FuncName, Param1, Param2, Param3, Param4, Param5) \ @@ -153,17 +153,17 @@ {\ if (FUNC_LOADED != m_is##FuncName) \ {\ - m_##FuncName = NULL; \ + m_##FuncName = nullptr; \ m_##FuncName = (TYPE_##FuncName)GetProcAddress(m_dllHandle, #FuncName); \ m_is##FuncName = FUNC_LOADED;\ }\ - if (NULL != m_##FuncName) \ + if (nullptr != m_##FuncName) \ return m_##FuncName(p1, p2, p3, p4, p5);\ else \ - return (retVal)NULL; \ + return (retVal)nullptr; \ } \ else\ - return (retVal)NULL; \ + return (retVal)nullptr; \ } #define DECLARE_FUNCTION6(CallType,retVal, FuncName, Param1, Param2, Param3, Param4, Param5, Param6) \ @@ -176,17 +176,17 @@ {\ if (FUNC_LOADED != m_is##FuncName) \ {\ - m_##FuncName = NULL; \ + m_##FuncName = nullptr; \ m_##FuncName = (TYPE_##FuncName)GetProcAddress(m_dllHandle, #FuncName); \ m_is##FuncName = FUNC_LOADED;\ }\ - if (NULL != m_##FuncName) \ + if (nullptr != m_##FuncName) \ return m_##FuncName(p1, p2, p3, p4, p5, p6);\ else \ - return (retVal)NULL; \ + return (retVal)nullptr; \ } \ else\ - return (retVal)NULL; \ + return (retVal)nullptr; \ } #define DECLARE_FUNCTION7(CallType,retVal, FuncName, Param1, Param2, Param3, Param4, Param5, Param6, Param7) \ @@ -199,17 +199,17 @@ {\ if (FUNC_LOADED != m_is##FuncName) \ {\ - m_##FuncName = NULL; \ + m_##FuncName = nullptr; \ m_##FuncName = (TYPE_##FuncName)GetProcAddress(m_dllHandle, #FuncName); \ m_is##FuncName = FUNC_LOADED;\ }\ - if (NULL != m_##FuncName) \ + if (nullptr != m_##FuncName) \ return m_##FuncName(p1, p2, p3, p4, p5, p6, p7);\ else \ - return (retVal)NULL; \ + return (retVal)nullptr; \ } \ else\ - return (retVal)NULL; \ + return (retVal)nullptr; \ } #define DECLARE_FUNCTION8(CallType,retVal, FuncName, Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8) \ @@ -222,17 +222,17 @@ {\ if (FUNC_LOADED != m_is##FuncName) \ {\ - m_##FuncName = NULL; \ + m_##FuncName = nullptr; \ m_##FuncName = (TYPE_##FuncName)GetProcAddress(m_dllHandle, #FuncName); \ m_is##FuncName = FUNC_LOADED;\ }\ - if (NULL != m_##FuncName) \ + if (nullptr != m_##FuncName) \ return m_##FuncName(p1, p2, p3, p4, p5, p6, p7, p8);\ else \ - return (retVal)NULL; \ + return (retVal)nullptr; \ }\ else\ - return (retVal)NULL; \ + return (retVal)nullptr; \ } #define DECLARE_FUNCTION9(CallType,retVal, FuncName, Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9) \ @@ -245,17 +245,17 @@ {\ if (FUNC_NAME != m_is##FuncName) \ {\ - m_##FuncName = NULL; \ + m_##FuncName = nullptr; \ m_##FuncName = (TYPE_##FuncName)GetProcAddress(m_dllHandle, #FuncName); \ m_is##FuncName = FUNC_LOADED;\ }\ - if (NULL != m_##FuncName) \ + if (nullptr != m_##FuncName) \ return m_##FuncName(p1, p2, p3, p4, p5, p6, p7, p8, p9);\ else \ - return (retVal)NULL; \ + return (retVal)nullptr; \ }\ else\ - return (retVal)NULL; \ + return (retVal)nullptr; \ } #define DECLARE_FUNCTION10(CallType,retVal, FuncName, Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10) \ @@ -268,17 +268,17 @@ {\ if (FUNC_LOADED != m_is##FuncName) \ {\ - m_##FuncName = NULL; \ + m_##FuncName = nullptr; \ m_##FuncName = (TYPE_##FuncName)GetProcAddress(m_dllHandle, #FuncName); \ m_is##FuncName = FUNC_LOADED;\ }\ - if (NULL != m_##FuncName) \ + if (nullptr != m_##FuncName) \ return m_##FuncName(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);\ else \ - return (retVal)NULL; \ + return (retVal)nullptr; \ }\ else \ - return (retVal)NULL;\ + return (retVal)nullptr;\ } //declare constructors and LoadFunctions @@ -299,12 +299,12 @@ public: PDLL() { - m_dllHandle = NULL; - m_dllName = NULL; + m_dllHandle = nullptr; + m_dllName = nullptr; m_refCount = 0; } - //A NULL here means the name has already been set + //A nullptr here means the name has already been set void LoadDll(LPCTSTR name, bool showMsg = true) { if (name) @@ -313,7 +313,7 @@ public: //try to load m_dllHandle = LoadLibrary(m_dllName); - if (m_dllHandle == NULL && showMsg) + if (m_dllHandle == nullptr && showMsg) { std::ostringstream message; message << "failed to load dll: " << ::GetLastError(); @@ -332,7 +332,7 @@ public: if (m_dllName) { delete []m_dllName; - m_dllName = NULL; + m_dllName = nullptr; } //They may be setting this null (e.g., uninitialize) @@ -357,8 +357,8 @@ public: if (m_refCount == 1 && m_dllName) //if this is first time, load the DLL { //we are assuming the name is already set - LoadDll(NULL, showMsg); - retVal = (m_dllHandle != NULL); + LoadDll(nullptr, showMsg); + retVal = (m_dllHandle != nullptr); } return retVal; } @@ -377,10 +377,10 @@ public: if (m_dllHandle) { FreeLibrary(m_dllHandle); - m_dllHandle = NULL; + m_dllHandle = nullptr; } - SetDllName(NULL); //clear out the name & free memory + SetDllName(nullptr); //clear out the name & free memory } } @@ -394,7 +394,7 @@ public: if (m_dllName) { delete [] m_dllName; - m_dllName = NULL; + m_dllName = nullptr; } } diff --git a/src/plugincontainer.cpp b/src/plugincontainer.cpp index 92073c12..bbcd3b6a 100644 --- a/src/plugincontainer.cpp +++ b/src/plugincontainer.cpp @@ -59,7 +59,7 @@ QStringList PluginContainer::pluginFileNames() const bool PluginContainer::verifyPlugin(IPlugin *plugin) { - if (plugin == NULL) { + if (plugin == nullptr) { return false; } else if (!plugin->init(new OrganizerProxy(m_Organizer, plugin->name()))) { qWarning("plugin failed to initialize"); @@ -89,7 +89,7 @@ bool PluginContainer::registerPlugin(QObject *plugin, const QString &fileName) { // diagnosis plugins IPluginDiagnose *diagnose = qobject_cast(plugin); - if (diagnose != NULL) { + if (diagnose != nullptr) { bf::at_key(m_Plugins).push_back(diagnose); m_DiagnosisConnections.push_back( diagnose->onInvalidated([&] () { emit diagnosisUpdate(); }) @@ -142,7 +142,7 @@ bool PluginContainer::registerPlugin(QObject *plugin, const QString &fileName) foreach (const QString &pluginName, pluginNames) { try { QObject *proxiedPlugin = proxy->instantiate(pluginName); - if (proxiedPlugin != NULL) { + if (proxiedPlugin != nullptr) { if (registerPlugin(proxiedPlugin, pluginName)) { qDebug("loaded plugin \"%s\"", qPrintable(pluginName)); } else { @@ -264,7 +264,7 @@ void PluginContainer::loadPlugins() QString pluginName = iter.filePath(); if (QLibrary::isLibrary(pluginName)) { QPluginLoader *pluginLoader = new QPluginLoader(pluginName, this); - if (pluginLoader->instance() == NULL) { + if (pluginLoader->instance() == nullptr) { m_FailedPlugins.push_back(pluginName); qCritical("failed to load plugin %s: %s", qPrintable(pluginName), qPrintable(pluginLoader->errorString())); diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp index 2b1fcca1..f0352e8a 100644 --- a/src/pluginlist.cpp +++ b/src/pluginlist.cpp @@ -88,7 +88,7 @@ PluginList::PluginList(QObject *parent) m_Utf8Codec = QTextCodec::codecForName("utf-8"); m_LocalCodec = QTextCodec::codecForName("Windows-1252"); - if (m_LocalCodec == NULL) { + if (m_LocalCodec == nullptr) { qCritical("required 8-bit string-encoding not supported."); m_LocalCodec = m_Utf8Codec; } @@ -142,7 +142,7 @@ void PluginList::refresh(const QString &profileName, const DirectoryEntry &baseD std::vector files = baseDirectory.getFiles(); for (auto iter = files.begin(); iter != files.end(); ++iter) { FileEntry::Ptr current = *iter; - if (current.get() == NULL) { + if (current.get() == nullptr) { continue; } QString filename = ToQString(current->getName()); @@ -157,7 +157,7 @@ void PluginList::refresh(const QString &profileName, const DirectoryEntry &baseD FilesOrigin &origin = baseDirectory.getOriginByID(current->getOrigin(archive)); QString iniPath = QFileInfo(filename).baseName() + ".ini"; - bool hasIni = baseDirectory.findFile(ToWString(iniPath)).get() != NULL; + bool hasIni = baseDirectory.findFile(ToWString(iniPath)).get() != nullptr; QString originName = ToQString(origin.getName()); unsigned int modIndex = ModInfo::getIndex(originName); @@ -243,7 +243,7 @@ void PluginList::enableESP(const QString &name, bool enable) void PluginList::enableAll() { - if (QMessageBox::question(NULL, tr("Confirm"), tr("Really enable all plugins?"), + if (QMessageBox::question(nullptr, tr("Confirm"), tr("Really enable all plugins?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { for (std::vector::iterator iter = m_ESPs.begin(); iter != m_ESPs.end(); ++iter) { iter->m_Enabled = true; @@ -255,7 +255,7 @@ void PluginList::enableAll() void PluginList::disableAll() { - if (QMessageBox::question(NULL, tr("Confirm"), tr("Really disable all plugins?"), + if (QMessageBox::question(nullptr, tr("Confirm"), tr("Really disable all plugins?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { for (std::vector::iterator iter = m_ESPs.begin(); iter != m_ESPs.end(); ++iter) { if (!iter->m_ForceEnabled) { @@ -515,14 +515,14 @@ bool PluginList::saveLoadOrder(DirectoryEntry &directoryStructure) for (std::vector::iterator iter = m_ESPs.begin(); iter != m_ESPs.end(); ++iter) { std::wstring espName = ToWString(iter->m_Name); const FileEntry::Ptr fileEntry = directoryStructure.findFile(espName); - if (fileEntry.get() != NULL) { + if (fileEntry.get() != nullptr) { QString fileName; bool archive = false; int originid = fileEntry->getOrigin(archive); fileName = QString("%1\\%2").arg(QDir::toNativeSeparators(ToQString(directoryStructure.getOriginByID(originid).getPath()))).arg(iter->m_Name); HANDLE file = ::CreateFile(ToWString(fileName).c_str(), GENERIC_READ | GENERIC_WRITE, - 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); if (file == INVALID_HANDLE_VALUE) { if (::GetLastError() == ERROR_SHARING_VIOLATION) { // file is locked, probably the game is running @@ -541,7 +541,7 @@ bool PluginList::saveLoadOrder(DirectoryEntry &directoryStructure) newWriteTime.dwHighDateTime = (DWORD)(temp >> 32); iter->m_Time = newWriteTime; fileEntry->setFileTime(newWriteTime); - if (!::SetFileTime(file, NULL, NULL, &newWriteTime)) { + if (!::SetFileTime(file, nullptr, nullptr, &newWriteTime)) { throw windows_error(QObject::tr("failed to set file time %1").arg(fileName).toUtf8().constData()); } @@ -1102,7 +1102,7 @@ bool PluginList::eventFilter(QObject *obj, QEvent *event) if (event->type() == QEvent::KeyPress) { QAbstractItemView *itemView = qobject_cast(obj); - if (itemView == NULL) { + if (itemView == nullptr) { return QObject::eventFilter(obj, event); } @@ -1112,7 +1112,7 @@ bool PluginList::eventFilter(QObject *obj, QEvent *event) ((keyEvent->key() == Qt::Key_Up) || (keyEvent->key() == Qt::Key_Down))) { QItemSelectionModel *selectionModel = itemView->selectionModel(); const QSortFilterProxyModel *proxyModel = qobject_cast(selectionModel->model()); - if (proxyModel != NULL) { + if (proxyModel != nullptr) { int diff = -1; if (((keyEvent->key() == Qt::Key_Up) && (proxyModel->sortOrder() == Qt::DescendingOrder)) || ((keyEvent->key() == Qt::Key_Down) && (proxyModel->sortOrder() == Qt::AscendingOrder))) { @@ -1147,7 +1147,7 @@ bool PluginList::eventFilter(QObject *obj, QEvent *event) QModelIndex minRow, maxRow; foreach (QModelIndex idx, selectionModel->selectedRows()) { - if (proxyModel != NULL) { + if (proxyModel != nullptr) { idx = proxyModel->mapToSource(idx); } if (!minRow.isValid() || (idx.row() < minRow.row())) { diff --git a/src/pluginlist.h b/src/pluginlist.h index 933a38ee..da644ad3 100644 --- a/src/pluginlist.h +++ b/src/pluginlist.h @@ -96,7 +96,7 @@ public: * * @param parent parent object **/ - PluginList(QObject *parent = NULL); + PluginList(QObject *parent = nullptr); ~PluginList(); diff --git a/src/pluginlistsortproxy.cpp b/src/pluginlistsortproxy.cpp index 02d99b36..dd236f4c 100644 --- a/src/pluginlistsortproxy.cpp +++ b/src/pluginlistsortproxy.cpp @@ -86,9 +86,9 @@ void PluginListSortProxy::displayColumnSelection(const QPoint &pos) m_EnabledColumns.reset(); foreach (const QAction *action, menu.actions()) { const QWidgetAction *widgetAction = qobject_cast(action); - if (widgetAction != NULL) { + if (widgetAction != nullptr) { const QCheckBox *checkBox = qobject_cast(widgetAction->defaultWidget()); - if (checkBox != NULL) { + if (checkBox != nullptr) { m_EnabledColumns.set(i, checkBox->checkState() == Qt::Checked); } } diff --git a/src/problemsdialog.cpp b/src/problemsdialog.cpp index edb34f39..d8af6a62 100644 --- a/src/problemsdialog.cpp +++ b/src/problemsdialog.cpp @@ -73,5 +73,5 @@ void ProblemsDialog::startFix() void ProblemsDialog::urlClicked(const QUrl &url) { - ::ShellExecuteW(NULL, L"open", ToWString(url.toString()).c_str(), NULL, NULL, SW_SHOWNORMAL); + ::ShellExecuteW(nullptr, L"open", ToWString(url.toString()).c_str(), nullptr, nullptr, SW_SHOWNORMAL); } diff --git a/src/profile.cpp b/src/profile.cpp index 37ed94cc..a6b8bf00 100644 --- a/src/profile.cpp +++ b/src/profile.cpp @@ -42,7 +42,7 @@ using namespace MOBase; using namespace MOShared; Profile::Profile() - : m_SaveTimer(NULL) + : m_SaveTimer(nullptr) { initTimer(); } @@ -56,7 +56,7 @@ void Profile::touchFile(QString fileName) } Profile::Profile(const QString &name, bool useDefaultSettings) - : m_SaveTimer(NULL) + : m_SaveTimer(nullptr) { initTimer(); QString profilesDir = qApp->property("datapath").toString() + "/" + ToQString(AppConfig::profilesPath()); @@ -108,7 +108,7 @@ Profile::Profile(const QDir &directory) Profile::Profile(const Profile& reference) - : m_Directory(reference.m_Directory), m_SaveTimer(NULL) + : m_Directory(reference.m_Directory), m_SaveTimer(nullptr) { initTimer(); refreshModStatus(); @@ -553,7 +553,7 @@ void Profile::mergeTweak(const QString &tweakName, const QString &tweakedIni) co for (std::vector::iterator iter = sections.begin(); iter != sections.end(); ++iter) { // retrieve the names of all keys - size = ::GetPrivateProfileStringW(iter->c_str(), NULL, NULL, buffer.data(), + size = ::GetPrivateProfileStringW(iter->c_str(), nullptr, nullptr, buffer.data(), bufferSize, tweakNameW.c_str()); if (size == bufferSize - 2) { throw MyException(QString("Buffer too small. Please report this as a bug. " @@ -566,7 +566,7 @@ void Profile::mergeTweak(const QString &tweakName, const QString &tweakedIni) co keyIter != keys.end(); ++keyIter) { //TODO this treats everything as strings but how could I differentiate the type? ::GetPrivateProfileStringW(iter->c_str(), keyIter->c_str(), - NULL, buffer.data(), bufferSize, ToWString(tweakName).c_str()); + nullptr, buffer.data(), bufferSize, ToWString(tweakName).c_str()); ::WritePrivateProfileStringW(iter->c_str(), keyIter->c_str(), buffer.data(), tweakedIniW.c_str()); } @@ -586,7 +586,7 @@ void Profile::mergeTweaks(ModInfo::Ptr modInfo, const QString &tweakedIni) const bool Profile::invalidationActive(bool *supported) const { if (GameInfo::instance().requiresBSAInvalidation()) { - if (supported != NULL) { + if (supported != nullptr) { *supported = true; } wchar_t buffer[1024]; @@ -597,7 +597,7 @@ bool Profile::invalidationActive(bool *supported) const if (::GetPrivateProfileStringW(L"Archive", GameInfo::instance().archiveListKey().c_str(), L"", buffer, 1024, iniFileName.c_str()) == 0) { if (errno != 0x02) { - if (supported != NULL) { + if (supported != nullptr) { *supported = false; } return false; diff --git a/src/profilesdialog.cpp b/src/profilesdialog.cpp index 3fdad880..26891b3c 100644 --- a/src/profilesdialog.cpp +++ b/src/profilesdialog.cpp @@ -177,7 +177,7 @@ void ProfilesDialog::on_removeProfileButton_clicked() Profile::Ptr currentProfile = profilesList->currentItem()->data(Qt::UserRole).value(); QString profilePath; - if (currentProfile.get() == NULL) { + if (currentProfile.get() == nullptr) { profilePath = QDir::fromNativeSeparators(ToQString(GameInfo::instance().getProfilesDir())) + "/" + profilesList->currentItem()->text(); if (QMessageBox::question(this, tr("Profile broken"), tr("This profile you're about to delete seems to be broken or the path is invalid. " @@ -190,7 +190,7 @@ void ProfilesDialog::on_removeProfileButton_clicked() profilePath = currentProfile->getPath(); } QListWidgetItem* item = profilesList->takeItem(profilesList->currentRow()); - if (item != NULL) { + if (item != nullptr) { delete item; } if (!shellDelete(QStringList(profilePath))) { @@ -231,7 +231,7 @@ void ProfilesDialog::on_invalidationBox_stateChanged(int state) QListWidget *profilesList = findChild("profilesList"); QListWidgetItem *currentItem = profilesList->currentItem(); - if (currentItem == NULL) { + if (currentItem == nullptr) { return; } if (!ui->invalidationBox->isEnabled()) { @@ -263,7 +263,7 @@ void ProfilesDialog::on_profilesList_currentItemChanged(QListWidgetItem *current QPushButton *transferButton = findChild("transferButton"); QPushButton *renameButton = findChild("renameButton"); - if (current != NULL) { + if (current != nullptr) { if (!current->data(Qt::UserRole).isValid()) return; const Profile::Ptr currentProfile = current->data(Qt::UserRole).value(); diff --git a/src/report.cpp b/src/report.cpp index 5cf36078..cca511a9 100644 --- a/src/report.cpp +++ b/src/report.cpp @@ -33,7 +33,7 @@ void reportError(QString message) QMessageBox messageBox(QMessageBox::Warning, QObject::tr("Error"), message, QMessageBox::Ok); messageBox.exec(); } else { - ::MessageBoxW(NULL, ToWString(message).c_str(), ToWString(QObject::tr("Error")).c_str(), MB_ICONERROR | MB_OK); + ::MessageBoxW(nullptr, ToWString(message).c_str(), ToWString(QObject::tr("Error")).c_str(), MB_ICONERROR | MB_OK); } } diff --git a/src/savegameinfowidget.cpp b/src/savegameinfowidget.cpp index 093b794c..7da89747 100644 --- a/src/savegameinfowidget.cpp +++ b/src/savegameinfowidget.cpp @@ -46,9 +46,9 @@ void SaveGameInfoWidget::setSave(const SaveGame *saveGame) ui->levelLabel->setText(QString("%1").arg(saveGame->pcLevel())); ui->dateLabel->setText(MOBase::ToString(saveGame->creationTime())); ui->screenshotLabel->setPixmap(QPixmap::fromImage(saveGame->screenshot())); - if (ui->gameFrame->layout() != NULL) { - QLayoutItem *item = NULL; - while ((item = ui->gameFrame->layout()->takeAt(0)) != NULL) { + if (ui->gameFrame->layout() != nullptr) { + QLayoutItem *item = nullptr; + while ((item = ui->gameFrame->layout()->takeAt(0)) != nullptr) { delete item->widget(); delete item; } diff --git a/src/selectiondialog.cpp b/src/selectiondialog.cpp index b4df8a1f..1b284928 100644 --- a/src/selectiondialog.cpp +++ b/src/selectiondialog.cpp @@ -23,7 +23,7 @@ along with Mod Organizer. If not, see . #include SelectionDialog::SelectionDialog(const QString &description, QWidget *parent) - : QDialog(parent), ui(new Ui::SelectionDialog), m_Choice(NULL), m_ValidateByData(false) + : QDialog(parent), ui(new Ui::SelectionDialog), m_Choice(nullptr), m_ValidateByData(false) { ui->setupUi(this); @@ -58,7 +58,7 @@ QVariant SelectionDialog::getChoiceData() QString SelectionDialog::getChoiceString() { - if ((m_Choice == NULL) || + if ((m_Choice == nullptr) || (m_ValidateByData && !m_Choice->property("data").isValid())) { return QString(); } else { diff --git a/src/selfupdater.cpp b/src/selfupdater.cpp index 0f75e392..0c222ebb 100644 --- a/src/selfupdater.cpp +++ b/src/selfupdater.cpp @@ -48,7 +48,7 @@ typedef Archive* (*CreateArchiveType)(); template T resolveFunction(QLibrary &lib, const char *name) { T temp = reinterpret_cast(lib.resolve(name)); - if (temp == NULL) { + if (temp == nullptr) { throw std::runtime_error(QObject::tr("invalid 7-zip32.dll: %1").arg(lib.errorString()).toLatin1().constData()); } return temp; @@ -94,7 +94,6 @@ SelfUpdater::~SelfUpdater() void SelfUpdater::setUserInterface(QWidget *widget) { - m_Progress.setVisible(false); m_Parent = widget; } @@ -163,7 +162,7 @@ void SelfUpdater::download(const QString &downloadLink, const QString &fileName) void SelfUpdater::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) { - if (m_Reply != NULL) { + if (m_Reply != nullptr) { if (m_Canceled) { m_Reply->abort(); } else { @@ -177,7 +176,7 @@ void SelfUpdater::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) void SelfUpdater::downloadReadyRead() { - if (m_Reply != NULL) { + if (m_Reply != nullptr) { m_UpdateFile.write(m_Reply->readAll()); } } @@ -187,7 +186,7 @@ void SelfUpdater::downloadFinished() { int error = QNetworkReply::NoError; - if (m_Reply != NULL) { + if (m_Reply != nullptr) { m_UpdateFile.write(m_Reply->readAll()); error = m_Reply->error(); @@ -199,7 +198,7 @@ void SelfUpdater::downloadFinished() m_Progress.hide(); m_Reply->close(); m_Reply->deleteLater(); - m_Reply = NULL; + m_Reply = nullptr; } m_UpdateFile.close(); diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index d1947b5a..765858f5 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -125,7 +125,7 @@ void SettingsDialog::on_resetDialogsButton_clicked() void SettingsDialog::storeSettings(QListWidgetItem *pluginItem) { - if (pluginItem != NULL) { + if (pluginItem != nullptr) { QMap settings = pluginItem->data(Qt::UserRole + 1).toMap(); for (int i = 0; i < ui->pluginSettingsList->topLevelItemCount(); ++i) { diff --git a/src/shared/directoryentry.cpp b/src/shared/directoryentry.cpp index 0adf0812..58bf5ae6 100644 --- a/src/shared/directoryentry.cpp +++ b/src/shared/directoryentry.cpp @@ -232,8 +232,8 @@ std::vector FilesOrigin::getFiles() const void FileEntry::addOrigin(int origin, FILETIME fileTime, const std::wstring &archive) { - m_LastAccessed = time(NULL); - if (m_Parent != NULL) { + m_LastAccessed = time(nullptr); + if (m_Parent != nullptr) { m_Parent->propagateOrigin(origin); } if (m_Origin == -1) { @@ -290,8 +290,8 @@ bool FileEntry::removeOrigin(int origin) // now we need to update the file time... std::wstring filePath = getFullPath(); HANDLE file = ::CreateFile(filePath.c_str(), GENERIC_READ | GENERIC_WRITE, - 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (!::GetFileTime(file, NULL, NULL, &m_FileTime)) { + 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); + if (!::GetFileTime(file, nullptr, nullptr, &m_FileTime)) { // maybe this file is in a bsa, but there is no easy way to find out which. User should refresh // the view to find out m_Archive = L"bsa?"; @@ -324,13 +324,13 @@ static bool ByOriginPriority(DirectoryEntry *entry, int LHS, int RHS) FileEntry::FileEntry() - : m_Index(UINT_MAX), m_Name(), m_Origin(-1), m_Parent(NULL), m_LastAccessed(time(NULL)) + : m_Index(UINT_MAX), m_Name(), m_Origin(-1), m_Parent(nullptr), m_LastAccessed(time(nullptr)) { LEAK_TRACE; } FileEntry::FileEntry(Index index, const std::wstring &name, DirectoryEntry *parent) - : m_Index(index), m_Name(name), m_Origin(-1), m_Parent(parent), m_Archive(L""), m_LastAccessed(time(NULL)) + : m_Index(index), m_Name(name), m_Origin(-1), m_Parent(parent), m_Archive(L""), m_LastAccessed(time(nullptr)) { LEAK_TRACE; } @@ -351,7 +351,7 @@ void FileEntry::sortOrigins() bool FileEntry::recurseParents(std::wstring &path, const DirectoryEntry *parent) const { - if (parent == NULL) { + if (parent == nullptr) { return false; } else { // don't append the topmost parent because it is the virtual data-root @@ -480,7 +480,7 @@ void DirectoryEntry::addFromBSA(const std::wstring &originName, std::wstring &di void DirectoryEntry::propagateOrigin(int origin) { m_Origins.insert(origin); - if (m_Parent != NULL) { + if (m_Parent != nullptr) { m_Parent->propagateOrigin(origin); } } @@ -515,13 +515,13 @@ void DirectoryEntry::addFiles(FilesOrigin &origin, wchar_t *buffer, int bufferOf _snwprintf(buffer + bufferOffset, MAXPATH_UNICODE - bufferOffset, L"\\*"); - HANDLE searchHandle = NULL; + HANDLE searchHandle = nullptr; if (SupportOptimizedFind()) { - searchHandle = ::FindFirstFileExW(buffer, FindExInfoBasic, &findData, FindExSearchNameMatch, NULL, + searchHandle = ::FindFirstFileExW(buffer, FindExInfoBasic, &findData, FindExSearchNameMatch, nullptr, FIND_FIRST_EX_LARGE_FETCH); } else { - searchHandle = ::FindFirstFileExW(buffer, FindExInfoStandard, &findData, FindExSearchNameMatch, NULL, 0); + searchHandle = ::FindFirstFileExW(buffer, FindExInfoStandard, &findData, FindExSearchNameMatch, nullptr, 0); } if (searchHandle != INVALID_HANDLE_VALUE) { @@ -572,7 +572,7 @@ void DirectoryEntry::removeFile(const std::wstring &filePath, int *origin) std::wstring dirName = filePath.substr(0, pos); std::wstring rest = filePath.substr(pos + 1); DirectoryEntry *entry = getSubDirectoryRecursive(dirName, false); - if (entry != NULL) { + if (entry != nullptr) { entry->removeFile(rest, origin); } } @@ -608,7 +608,7 @@ void DirectoryEntry::removeDir(const std::wstring &path) std::wstring dirName = path.substr(0, pos); std::wstring rest = path.substr(pos + 1); DirectoryEntry *entry = getSubDirectoryRecursive(dirName, false); - if (entry != NULL) { + if (entry != nullptr) { entry->removeDir(rest); } } @@ -707,12 +707,12 @@ FilesOrigin &DirectoryEntry::getOriginByName(const std::wstring &name) const int DirectoryEntry::getOrigin(const std::wstring &path, bool &archive) { - const DirectoryEntry *directory = NULL; + const DirectoryEntry *directory = nullptr; const FileEntry::Ptr file = searchFile(path, &directory); - if (file.get() != NULL) { + if (file.get() != nullptr) { return file->getOrigin(archive); } else { - if (directory != NULL) { + if (directory != nullptr) { return directory->anyOrigin(); } else { return -1; @@ -732,13 +732,13 @@ std::vector DirectoryEntry::getFiles() const const FileEntry::Ptr DirectoryEntry::searchFile(const std::wstring &path, const DirectoryEntry **directory) const { - if (directory != NULL) { - *directory = NULL; + if (directory != nullptr) { + *directory = nullptr; } if ((path.length() == 0) || (path == L"*")) { // no file name -> the path ended on a (back-)slash - if (directory != NULL) { + if (directory != nullptr) { *directory = this; } return FileEntry::Ptr(); @@ -751,9 +751,9 @@ const FileEntry::Ptr DirectoryEntry::searchFile(const std::wstring &path, const auto iter = m_Files.find(ToLower(path)); if (iter != m_Files.end()) { return m_FileRegister->getFile(iter->second); - } else if (directory != NULL) { + } else if (directory != nullptr) { DirectoryEntry *temp = findSubDirectory(path); - if (temp != NULL) { + if (temp != nullptr) { *directory = temp; } } @@ -761,7 +761,7 @@ const FileEntry::Ptr DirectoryEntry::searchFile(const std::wstring &path, const // file is in in a subdirectory, recurse into the matching subdirectory std::wstring pathComponent = path.substr(0, len); DirectoryEntry *temp = findSubDirectory(pathComponent); - if (temp != NULL) { + if (temp != nullptr) { return temp->searchFile(path.substr(len + 1), directory); } } @@ -776,7 +776,7 @@ DirectoryEntry *DirectoryEntry::findSubDirectory(const std::wstring &name) const return *iter; } } - return NULL; + return nullptr; } @@ -808,7 +808,7 @@ DirectoryEntry *DirectoryEntry::getSubDirectory(const std::wstring &name, bool c new DirectoryEntry(name, this, originID, m_FileRegister, m_OriginConnection)); return *iter; } else { - return NULL; + return nullptr; } } @@ -825,8 +825,8 @@ DirectoryEntry *DirectoryEntry::getSubDirectoryRecursive(const std::wstring &pat return getSubDirectory(path, create); } else { DirectoryEntry *nextChild = getSubDirectory(path.substr(0, pos), create, originID); - if (nextChild == NULL) { - return NULL; + if (nextChild == nullptr) { + return nullptr; } else { return nextChild->getSubDirectoryRecursive(path.substr(pos + 1), create, originID); } @@ -888,7 +888,7 @@ void FileRegister::unregisterFile(FileEntry::Ptr file) } // unregister from directory - if (file->getParent() != NULL) { + if (file->getParent() != nullptr) { file->getParent()->removeFile(file->getIndex()); } } @@ -944,7 +944,7 @@ void FileRegister::removeOriginMulti(std::set indices, int ori // only when disabling an origin that is probably frequently the case std::set parents; BOOST_FOREACH (const FileEntry::Ptr &file, removedFiles) { - if (file->getParent() != NULL) { + if (file->getParent() != nullptr) { parents.insert(file->getParent()); } } diff --git a/src/shared/directoryentry.h b/src/shared/directoryentry.h index d588ab02..197062ef 100644 --- a/src/shared/directoryentry.h +++ b/src/shared/directoryentry.h @@ -250,12 +250,12 @@ public: /** retrieve a file in this directory by name. * @param name name of the file - * @return fileentry object for the file or NULL if no file matches + * @return fileentry object for the file or nullptr if no file matches */ const FileEntry::Ptr findFile(const std::wstring &name) const; /** search through this directory and all subdirectories for a file by the specified name (relative path). - if directory is not NULL, the referenced variable will be set to the path containing the file */ + if directory is not nullptr, the referenced variable will be set to the path containing the file */ const FileEntry::Ptr searchFile(const std::wstring &path, const DirectoryEntry **directory) const; void insertFile(const std::wstring &filePath, FilesOrigin &origin, FILETIME fileTime); @@ -263,7 +263,7 @@ public: void removeFile(FileEntry::Index index); // remove the specified file from the tree. This can be a path leading to a file in a subdirectory - void removeFile(const std::wstring &filePath, int *origin = NULL); + void removeFile(const std::wstring &filePath, int *origin = nullptr); /** * @brief remove the specified directory @@ -274,9 +274,9 @@ public: void remove(const std::wstring &fileName, int *origin) { auto iter = m_Files.find(ToLower(fileName)); if (iter != m_Files.end()) { - if (origin != NULL) { + if (origin != nullptr) { FileEntry::Ptr entry = m_FileRegister->getFile(iter->second); - if (entry.get() != NULL) { + if (entry.get() != nullptr) { bool ignore; *origin = entry->getOrigin(ignore); } diff --git a/src/shared/error_report.cpp b/src/shared/error_report.cpp index 02ff2d56..c9277c1b 100644 --- a/src/shared/error_report.cpp +++ b/src/shared/error_report.cpp @@ -35,7 +35,7 @@ void reportError(LPCSTR format, ...) vsnprintf(buffer, 1024, format, argList); va_end(argList); - MessageBoxA(NULL, buffer, "Error", MB_OK | MB_ICONERROR); + MessageBoxA(nullptr, buffer, "Error", MB_OK | MB_ICONERROR); } void reportError(LPCWSTR format, ...) @@ -50,18 +50,18 @@ void reportError(LPCWSTR format, ...) _vsnwprintf(buffer, 1024, format, argList); va_end(argList); - MessageBoxW(NULL, buffer, L"Error", MB_OK | MB_ICONERROR); + MessageBoxW(nullptr, buffer, L"Error", MB_OK | MB_ICONERROR); } std::string getCurrentErrorStringA() { - LPSTR buffer = NULL; + LPSTR buffer = nullptr; DWORD errorCode = ::GetLastError(); if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buffer, 0, NULL) == 0) { + nullptr, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buffer, 0, nullptr) == 0) { ::SetLastError(errorCode); return std::string(); } else { @@ -78,12 +78,12 @@ std::string getCurrentErrorStringA() std::wstring getCurrentErrorStringW() { - LPWSTR buffer = NULL; + LPWSTR buffer = nullptr; DWORD errorCode = ::GetLastError(); if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&buffer, 0, NULL) == 0) { + nullptr, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&buffer, 0, nullptr) == 0) { ::SetLastError(errorCode); return std::wstring(); } else { diff --git a/src/shared/fallout3info.cpp b/src/shared/fallout3info.cpp index 82b285b7..6c420044 100644 --- a/src/shared/fallout3info.cpp +++ b/src/shared/fallout3info.cpp @@ -60,7 +60,7 @@ std::wstring Fallout3Info::getRegPathStatic() WCHAR temp[MAX_PATH]; DWORD bufferSize = MAX_PATH; - if (::RegQueryValueExW(key, L"Installed Path", NULL, NULL, (LPBYTE)temp, &bufferSize) == ERROR_SUCCESS) { + if (::RegQueryValueExW(key, L"Installed Path", nullptr, nullptr, (LPBYTE)temp, &bufferSize) == ERROR_SUCCESS) { return std::wstring(temp); } else { return std::wstring(); @@ -74,9 +74,9 @@ std::wstring Fallout3Info::getInvalidationBSA() bool Fallout3Info::isInvalidationBSA(const std::wstring &bsaName) { - static LPCWSTR invalidation[] = { L"Fallout - AI!.bsa", L"Fallout - Invalidation.bsa", NULL }; + static LPCWSTR invalidation[] = { L"Fallout - AI!.bsa", L"Fallout - Invalidation.bsa", nullptr }; - for (int i = 0; invalidation[i] != NULL; ++i) { + for (int i = 0; invalidation[i] != nullptr; ++i) { if (wcscmp(bsaName.c_str(), invalidation[i]) == 0) { return true; } @@ -203,7 +203,7 @@ void Fallout3Info::createProfile(const std::wstring &directory, bool useDefaults std::wostringstream source; source << getLocalAppFolder() << "\\Fallout3\\plugins.txt"; if (!::CopyFileW(source.str().c_str(), target.str().c_str(), true)) { - HANDLE file = ::CreateFileW(target.str().c_str(), GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); + HANDLE file = ::CreateFileW(target.str().c_str(), GENERIC_WRITE, 0, nullptr, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, nullptr); ::CloseHandle(file); } } @@ -256,9 +256,9 @@ void Fallout3Info::repairProfile(const std::wstring &directory) bool Fallout3Info::rerouteToProfile(const wchar_t *fileName, const wchar_t*) { - static LPCWSTR profileFiles[] = { L"fallout.ini", L"falloutprefs.ini", L"plugins.txt", NULL }; + static LPCWSTR profileFiles[] = { L"fallout.ini", L"falloutprefs.ini", L"plugins.txt", nullptr }; - for (int i = 0; profileFiles[i] != NULL; ++i) { + for (int i = 0; profileFiles[i] != nullptr; ++i) { if (_wcsicmp(fileName, profileFiles[i]) == 0) { return true; } diff --git a/src/shared/falloutnvinfo.cpp b/src/shared/falloutnvinfo.cpp index 178ce8b4..f589124a 100644 --- a/src/shared/falloutnvinfo.cpp +++ b/src/shared/falloutnvinfo.cpp @@ -61,7 +61,7 @@ std::wstring FalloutNVInfo::getRegPathStatic() WCHAR temp[MAX_PATH]; DWORD bufferSize = MAX_PATH; - if (::RegQueryValueExW(key, L"Installed Path", NULL, NULL, (LPBYTE)temp, &bufferSize) == ERROR_SUCCESS) { + if (::RegQueryValueExW(key, L"Installed Path", nullptr, nullptr, (LPBYTE)temp, &bufferSize) == ERROR_SUCCESS) { return std::wstring(temp); } else { return std::wstring(); @@ -75,9 +75,9 @@ std::wstring FalloutNVInfo::getInvalidationBSA() bool FalloutNVInfo::isInvalidationBSA(const std::wstring &bsaName) { - static LPCWSTR invalidation[] = { L"Fallout - AI!.bsa", L"Fallout - Invalidation.bsa", NULL }; + static LPCWSTR invalidation[] = { L"Fallout - AI!.bsa", L"Fallout - Invalidation.bsa", nullptr }; - for (int i = 0; invalidation[i] != NULL; ++i) { + for (int i = 0; invalidation[i] != nullptr; ++i) { if (wcscmp(bsaName.c_str(), invalidation[i]) == 0) { return true; } @@ -170,7 +170,7 @@ void FalloutNVInfo::createProfile(const std::wstring &directory, bool useDefault if (!FileExists(target)) { std::wstring source = getLocalAppFolder() + L"\\FalloutNV\\plugins.txt"; if (!::CopyFileW(source.c_str(), target.c_str(), true)) { - HANDLE file = ::CreateFileW(target.c_str(), GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); + HANDLE file = ::CreateFileW(target.c_str(), GENERIC_WRITE, 0, nullptr, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, nullptr); ::CloseHandle(file); } } @@ -247,9 +247,9 @@ void FalloutNVInfo::repairProfile(const std::wstring &directory) bool FalloutNVInfo::rerouteToProfile(const wchar_t *fileName, const wchar_t*) { - static LPCWSTR profileFiles[] = { L"fallout.ini", L"falloutprefs.ini", L"plugins.txt", NULL }; + static LPCWSTR profileFiles[] = { L"fallout.ini", L"falloutprefs.ini", L"plugins.txt", nullptr }; - for (int i = 0; profileFiles[i] != NULL; ++i) { + for (int i = 0; profileFiles[i] != nullptr; ++i) { if (_wcsicmp(fileName, profileFiles[i]) == 0) { return true; } diff --git a/src/shared/gameinfo.cpp b/src/shared/gameinfo.cpp index 1a815701..3727ea49 100644 --- a/src/shared/gameinfo.cpp +++ b/src/shared/gameinfo.cpp @@ -37,7 +37,7 @@ along with Mod Organizer. If not, see . namespace MOShared { -GameInfo* GameInfo::s_Instance = NULL; +GameInfo* GameInfo::s_Instance = nullptr; GameInfo::GameInfo(const std::wstring &moDirectory, const std::wstring &moDataDirectory, const std::wstring &gameDirectory) @@ -62,14 +62,14 @@ void GameInfo::identifyMyGamesDirectory(const std::wstring &file) m_MyGamesDirectory.clear(); // a) this is the way it should work. get the configured My Documents\My Games directory - if (::SHGetFolderPathW(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, myDocuments) == S_OK) { + if (::SHGetFolderPathW(nullptr, CSIDL_PERSONAL, nullptr, SHGFP_TYPE_CURRENT, myDocuments) == S_OK) { m_MyGamesDirectory = std::wstring(myDocuments) + L"\\My Games"; } // b) if there is no directory there, look in the default directory if (m_MyGamesDirectory.empty() || !FileExists(m_MyGamesDirectory + L"\\" + file)) { - if (::SHGetFolderPathW(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_DEFAULT, myDocuments) == S_OK) { + if (::SHGetFolderPathW(nullptr, CSIDL_PERSONAL, nullptr, SHGFP_TYPE_DEFAULT, myDocuments) == S_OK) { std::wstring fromDefault = std::wstring(myDocuments) + L"\\My Games"; if (FileExists(fromDefault + L"\\" + file)) { m_MyGamesDirectory = fromDefault; @@ -99,13 +99,13 @@ bool GameInfo::identifyGame(const std::wstring &moDirectory, const std::wstring s_Instance = new SkyrimInfo(moDirectory, moDataDirectory, searchPath); } - return s_Instance != NULL; + return s_Instance != nullptr; } bool GameInfo::init(const std::wstring &moDirectory, const std::wstring &moDataDirectory, const std::wstring &gamePath) { - if (s_Instance == NULL) { + if (s_Instance == nullptr) { if (gamePath.length() == 0) { // search upward in the directory until a recognized game-binary is found std::wstring searchPath(moDirectory); @@ -191,7 +191,7 @@ std::wstring GameInfo::getLocalAppFolder() const wchar_t localAppFolder[MAX_PATH]; memset(localAppFolder, '\0', MAX_PATH * sizeof(wchar_t)); - if (::SHGetFolderPathW(NULL, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, localAppFolder) == S_OK) { + if (::SHGetFolderPathW(nullptr, CSIDL_LOCAL_APPDATA, nullptr, SHGFP_TYPE_CURRENT, localAppFolder) == S_OK) { return localAppFolder; } else { // fallback: try the registry @@ -212,7 +212,7 @@ std::wstring GameInfo::getSpecialPath(LPCWSTR name) const WCHAR temp[MAX_PATH]; DWORD bufferSize = MAX_PATH; - errorcode = ::RegQueryValueExW(key, name, NULL, NULL, (LPBYTE)temp, &bufferSize); + errorcode = ::RegQueryValueExW(key, name, nullptr, nullptr, (LPBYTE)temp, &bufferSize); if (errorcode != ERROR_SUCCESS) { throw windows_error((boost::format("failed to look up special folder (%1%)") % ToString(name, true)).str(), errorcode); } diff --git a/src/shared/inject.cpp b/src/shared/inject.cpp index 5a111c4a..143652c2 100644 --- a/src/shared/inject.cpp +++ b/src/shared/inject.cpp @@ -57,13 +57,13 @@ void injectDLL(HANDLE processHandle, HANDLE threadHandle, const std::string &dll _snprintf(parameters.initstr, 5, "Init"); //this is the name of thie initialisation function we want to call in the target process HMODULE k32mod = ::LoadLibrary(__TEXT("kernel32.dll")); - TLoadLibraryType loadLibraryFunc = NULL; - TGetProcAddressType getProcAddressFunc = NULL; + TLoadLibraryType loadLibraryFunc = nullptr; + TGetProcAddressType getProcAddressFunc = nullptr; // ansi binaries - if (k32mod != NULL) { + if (k32mod != nullptr) { loadLibraryFunc = reinterpret_cast(::GetProcAddress(k32mod, "LoadLibraryA")); getProcAddressFunc = reinterpret_cast(::GetProcAddress(k32mod, "GetProcAddress")); - if ((loadLibraryFunc == NULL) || (getProcAddressFunc == NULL)) { + if ((loadLibraryFunc == nullptr) || (getProcAddressFunc == nullptr)) { throw windows_error("failed to determine address for required functions"); } } else { @@ -71,8 +71,8 @@ void injectDLL(HANDLE processHandle, HANDLE threadHandle, const std::string &dll } // allocate memory in the target process and write the parameter-block there - LPVOID remoteMem = ::VirtualAllocEx(processHandle, NULL, sizeof(TParameters), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); - if (remoteMem == NULL) { + LPVOID remoteMem = ::VirtualAllocEx(processHandle, nullptr, sizeof(TParameters), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + if (remoteMem == nullptr) { throw windows_error("failed to allocate memory in target process"); } SIZE_T written; @@ -104,8 +104,8 @@ void injectDLL(HANDLE processHandle, HANDLE threadHandle, const std::string &dll }; // reserve memory for the stub - PBYTE stubRemote = reinterpret_cast(::VirtualAllocEx(processHandle, NULL, sizeof(stubLocal), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)); - if (stubRemote == NULL) { + PBYTE stubRemote = reinterpret_cast(::VirtualAllocEx(processHandle, nullptr, sizeof(stubLocal), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)); + if (stubRemote == nullptr) { throw windows_error("failed to allocate memory for stub"); } TParameters *remoteParams = reinterpret_cast(remoteMem); diff --git a/src/shared/leaktrace.cpp b/src/shared/leaktrace.cpp index 729eb42e..46ff7924 100644 --- a/src/shared/leaktrace.cpp +++ b/src/shared/leaktrace.cpp @@ -22,7 +22,7 @@ void initDbgIfNecessary() ::SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS); firstCall = false; } - if (!::SymInitialize(process, NULL, TRUE)) { + if (!::SymInitialize(process, nullptr, TRUE)) { printf("failed to initialize symbols: %d", ::GetLastError()); } initialized.insert(::GetCurrentProcessId()); diff --git a/src/shared/oblivioninfo.cpp b/src/shared/oblivioninfo.cpp index 89a795a5..586bcaef 100644 --- a/src/shared/oblivioninfo.cpp +++ b/src/shared/oblivioninfo.cpp @@ -61,7 +61,7 @@ std::wstring OblivionInfo::getRegPathStatic() WCHAR temp[MAX_PATH]; DWORD bufferSize = MAX_PATH; - if (::RegQueryValueExW(key, L"Installed Path", NULL, NULL, (LPBYTE)temp, &bufferSize) == ERROR_SUCCESS) { + if (::RegQueryValueExW(key, L"Installed Path", nullptr, nullptr, (LPBYTE)temp, &bufferSize) == ERROR_SUCCESS) { return std::wstring(temp); } else { return std::wstring(); @@ -76,9 +76,9 @@ std::wstring OblivionInfo::getInvalidationBSA() bool OblivionInfo::isInvalidationBSA(const std::wstring &bsaName) { static LPCWSTR invalidation[] = { L"Oblivion - Invalidation.bsa", L"ArchiveInvalidationInvalidated!.bsa", - L"BSARedirection.bsa", NULL }; + L"BSARedirection.bsa", nullptr }; - for (int i = 0; invalidation[i] != NULL; ++i) { + for (int i = 0; invalidation[i] != nullptr; ++i) { if (wcscmp(bsaName.c_str(), invalidation[i]) == 0) { return true; } @@ -158,7 +158,7 @@ void OblivionInfo::createProfile(const std::wstring &directory, bool useDefaults std::wostringstream source; source << getLocalAppFolder() << "\\Oblivion\\plugins.txt"; if (!::CopyFileW(source.str().c_str(), target.str().c_str(), true)) { - HANDLE file = ::CreateFileW(target.str().c_str(), GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); + HANDLE file = ::CreateFileW(target.str().c_str(), GENERIC_WRITE, 0, nullptr, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, nullptr); ::CloseHandle(file); } } @@ -194,7 +194,7 @@ void OblivionInfo::createProfile(const std::wstring &directory, bool useDefaults if (!FileExists(target)) { std::wstring source = getMyGamesDirectory() + L"\\Oblivion\\oblivionprefs.ini"; if (!::CopyFileW(source.c_str(), target.c_str(), true)) { - if ((::CreateFileW(target.c_str(), GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL) == INVALID_HANDLE_VALUE) && + if ((::CreateFileW(target.c_str(), GENERIC_WRITE, 0, nullptr, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, nullptr) == INVALID_HANDLE_VALUE) && (::GetLastError() != ERROR_FILE_EXISTS)) { throw windows_error(std::string("failed to create ini file: ") + ToString(target, false)); } @@ -240,9 +240,9 @@ void OblivionInfo::repairProfile(const std::wstring &directory) bool OblivionInfo::rerouteToProfile(const wchar_t *fileName, const wchar_t*) { - static LPCWSTR profileFiles[] = { L"oblivion.ini", L"oblivionprefs.ini", L"plugins.txt", NULL }; + static LPCWSTR profileFiles[] = { L"oblivion.ini", L"oblivionprefs.ini", L"plugins.txt", nullptr }; - for (int i = 0; profileFiles[i] != NULL; ++i) { + for (int i = 0; profileFiles[i] != nullptr; ++i) { if (_wcsicmp(fileName, profileFiles[i]) == 0) { return true; } diff --git a/src/shared/skyriminfo.cpp b/src/shared/skyriminfo.cpp index 7f70c097..1d00c4f3 100644 --- a/src/shared/skyriminfo.cpp +++ b/src/shared/skyriminfo.cpp @@ -39,7 +39,7 @@ SkyrimInfo::SkyrimInfo(const std::wstring &moDirectory, const std::wstring &moDa identifyMyGamesDirectory(L"skyrim"); wchar_t appDataPath[MAX_PATH]; - if (SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, appDataPath))) { + if (SUCCEEDED(SHGetFolderPathW(nullptr, CSIDL_LOCAL_APPDATA, nullptr, SHGFP_TYPE_CURRENT, appDataPath))) { m_AppData = appDataPath; } } @@ -69,7 +69,7 @@ std::wstring SkyrimInfo::getRegPathStatic() WCHAR temp[MAX_PATH]; DWORD bufferSize = MAX_PATH; - if (::RegQueryValueExW(key, L"Installed Path", NULL, NULL, (LPBYTE)temp, &bufferSize) == ERROR_SUCCESS) { + if (::RegQueryValueExW(key, L"Installed Path", nullptr, nullptr, (LPBYTE)temp, &bufferSize) == ERROR_SUCCESS) { return std::wstring(temp); } else { return std::wstring(); @@ -84,9 +84,9 @@ std::wstring SkyrimInfo::getInvalidationBSA() bool SkyrimInfo::isInvalidationBSA(const std::wstring &bsaName) { - static LPCWSTR invalidation[] = { L"Skyrim - Invalidation.bsa", NULL }; + static LPCWSTR invalidation[] = { L"Skyrim - Invalidation.bsa", nullptr }; - for (int i = 0; invalidation[i] != NULL; ++i) { + for (int i = 0; invalidation[i] != nullptr; ++i) { if (wcscmp(bsaName.c_str(), invalidation[i]) == 0) { return true; } @@ -229,7 +229,7 @@ void SkyrimInfo::createProfile(const std::wstring &directory, bool useDefaults) std::wostringstream source; source << getLocalAppFolder() << "\\Skyrim\\plugins.txt"; if (!::CopyFileW(source.str().c_str(), target.c_str(), true)) { - HANDLE file = ::CreateFileW(target.c_str(), GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); + HANDLE file = ::CreateFileW(target.c_str(), GENERIC_WRITE, 0, nullptr, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, nullptr); ::CloseHandle(file); } } @@ -237,7 +237,7 @@ void SkyrimInfo::createProfile(const std::wstring &directory, bool useDefaults) if (!FileExists(target)) { std::wstring source = getLocalAppFolder() + L"\\Skyrim\\loadorder.txt"; if (!::CopyFileW(source.c_str(), target.c_str(), true)) { - HANDLE file = ::CreateFileW(target.c_str(), GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); + HANDLE file = ::CreateFileW(target.c_str(), GENERIC_WRITE, 0, nullptr, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, nullptr); ::CloseHandle(file); } } @@ -272,7 +272,7 @@ void SkyrimInfo::createProfile(const std::wstring &directory, bool useDefaults) if (!::CopyFileW(source.c_str(), target.c_str(), true)) { log("failed to copy ini file %ls", source.c_str()); // create empty - if (::CreateFileW(target.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL) == INVALID_HANDLE_VALUE) { + if (::CreateFileW(target.c_str(), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr) == INVALID_HANDLE_VALUE) { throw windows_error(std::string("failed to copy ini file: ") + ToString(source, false)); } } @@ -289,16 +289,16 @@ void SkyrimInfo::repairProfile(const std::wstring &directory) bool SkyrimInfo::rerouteToProfile(const wchar_t *fileName, const wchar_t *fullPath) { - static LPCWSTR profileFiles[] = { L"skyrim.ini", L"skyrimprefs.ini", L"loadorder.txt", NULL }; + static LPCWSTR profileFiles[] = { L"skyrim.ini", L"skyrimprefs.ini", L"loadorder.txt", nullptr }; - for (int i = 0; profileFiles[i] != NULL; ++i) { + for (int i = 0; profileFiles[i] != nullptr; ++i) { if (_wcsicmp(fileName, profileFiles[i]) == 0) { return true; } } if ((_wcsicmp(fileName, L"plugins.txt") == 0) && - (m_AppData.empty() || (StrStrIW(fullPath, m_AppData.c_str()) != NULL))) { + (m_AppData.empty() || (StrStrIW(fullPath, m_AppData.c_str()) != nullptr))) { return true; } diff --git a/src/shared/util.cpp b/src/shared/util.cpp index d4a77929..df3a8bad 100644 --- a/src/shared/util.cpp +++ b/src/shared/util.cpp @@ -34,7 +34,7 @@ bool FileExists(const std::string &filename) { WIN32_FIND_DATAA findData; ZeroMemory(&findData, sizeof(WIN32_FIND_DATAA)); - HANDLE search = ::FindFirstFileExA(filename.c_str(), FindExInfoStandard, &findData, FindExSearchNameMatch, NULL, 0); + HANDLE search = ::FindFirstFileExA(filename.c_str(), FindExInfoStandard, &findData, FindExSearchNameMatch, nullptr, 0); if (search == INVALID_HANDLE_VALUE) { return false; } else { @@ -47,7 +47,7 @@ bool FileExists(const std::wstring &filename) { WIN32_FIND_DATAW findData; ZeroMemory(&findData, sizeof(WIN32_FIND_DATAW)); - HANDLE search = ::FindFirstFileExW(filename.c_str(), FindExInfoStandard, &findData, FindExSearchNameMatch, NULL, 0); + HANDLE search = ::FindFirstFileExW(filename.c_str(), FindExInfoStandard, &findData, FindExSearchNameMatch, nullptr, 0); if (search == INVALID_HANDLE_VALUE) { return false; } else { @@ -67,14 +67,14 @@ std::string ToString(const std::wstring &source, bool utf8) { std::string result; UINT codepage = utf8 ? CP_UTF8 : GetACP(); - int sizeRequired = ::WideCharToMultiByte(codepage, 0, &source[0], -1, NULL, 0, NULL, NULL); + int sizeRequired = ::WideCharToMultiByte(codepage, 0, &source[0], -1, nullptr, 0, nullptr, nullptr); if (sizeRequired == 0) { throw windows_error("failed to convert string to multibyte"); } // the size returned by WideCharToMultiByte contains zero termination IF -1 is specified for the length. // we don't want that \0 in the string because then the length field would be wrong. Because madness result.resize(sizeRequired - 1, '\0'); - ::WideCharToMultiByte(codepage, 0, &source[0], (int)source.size(), &result[0], sizeRequired, NULL, NULL); + ::WideCharToMultiByte(codepage, 0, &source[0], (int)source.size(), &result[0], sizeRequired, nullptr, nullptr); return result; } @@ -82,7 +82,7 @@ std::wstring ToWString(const std::string &source, bool utf8) { std::wstring result; UINT codepage = utf8 ? CP_UTF8 : GetACP(); - int sizeRequired = ::MultiByteToWideChar(codepage, 0, &source[0], (int)source.size(), NULL, 0); + int sizeRequired = ::MultiByteToWideChar(codepage, 0, &source[0], (int)source.size(), nullptr, 0); if (sizeRequired == 0) { throw windows_error("failed to convert string to wide character"); } @@ -131,7 +131,7 @@ VS_FIXEDFILEINFO GetFileVersion(const std::wstring &fileName) throw windows_error("failed to determine file version info"); } - void *versionInfoPtr = NULL; + void *versionInfoPtr = nullptr; UINT versionInfoLength = 0; if (!::VerQueryValue(buffer, L"\\", &versionInfoPtr, &versionInfoLength)) { throw windows_error("failed to determine file version"); @@ -160,14 +160,14 @@ std::string GetStack() ::SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS); firstCall = false; } - if (!::SymInitialize(process, NULL, TRUE)) { + if (!::SymInitialize(process, nullptr, TRUE)) { log("failed to initialize symbols: %d", ::GetLastError()); } initialized.insert(::GetCurrentProcessId()); } LPVOID stack[32]; - WORD frames = ::CaptureStackBackTrace(0, 100, stack, NULL); + WORD frames = ::CaptureStackBackTrace(0, 100, stack, nullptr); char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)]; PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer; diff --git a/src/shared/windows_error.cpp b/src/shared/windows_error.cpp index 647a5bfb..97a58a20 100644 --- a/src/shared/windows_error.cpp +++ b/src/shared/windows_error.cpp @@ -27,13 +27,13 @@ std::string windows_error::constructMessage(const std::string& input, int inErro std::ostringstream finalMessage; finalMessage << input; - LPSTR buffer = NULL; + LPSTR buffer = nullptr; DWORD errorCode = inErrorCode != -1 ? inErrorCode : ::GetLastError(); // TODO: the message is not english? if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buffer, 0, NULL) == 0) { + nullptr, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buffer, 0, nullptr) == 0) { finalMessage << " (errorcode " << errorCode << ")"; } else { LPSTR lastChar = buffer + strlen(buffer) - 2; diff --git a/src/spawn.cpp b/src/spawn.cpp index cd7e202e..96c219fc 100644 --- a/src/spawn.cpp +++ b/src/spawn.cpp @@ -55,7 +55,7 @@ bool spawn(LPCWSTR binary, LPCWSTR arguments, LPCWSTR currentDirectory, bool sus } si.cb = sizeof(si); int length = wcslen(binary) + wcslen(arguments) + 4; - wchar_t *commandLine = NULL; + wchar_t *commandLine = nullptr; if (arguments[0] != L'\0') { commandLine = new wchar_t[length]; _snwprintf(commandLine, length, L"\"%ls\" %ls", binary, arguments); @@ -84,12 +84,12 @@ bool spawn(LPCWSTR binary, LPCWSTR arguments, LPCWSTR currentDirectory, bool sus } PROCESS_INFORMATION pi; - BOOL success = ::CreateProcess(NULL, + BOOL success = ::CreateProcess(nullptr, commandLine, - NULL, NULL, // no special process or thread attributes + nullptr, nullptr, // no special process or thread attributes inheritHandles, // inherit handles if we plan to use stdout or stderr reroute CREATE_BREAKAWAY_FROM_JOB | (suspended ? CREATE_SUSPENDED : 0), // create suspended so I have time to inject the DLL - NULL, // same environment as parent + nullptr, // same environment as parent currentDirectory, // current directory &si, &pi // startup and process information ); @@ -119,12 +119,12 @@ HANDLE startBinary(const QFileInfo &binary, { JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobInfo; - ::QueryInformationJobObject(NULL, JobObjectExtendedLimitInformation, &jobInfo, sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION), NULL); + ::QueryInformationJobObject(nullptr, JobObjectExtendedLimitInformation, &jobInfo, sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION), nullptr); jobInfo.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_BREAKAWAY_OK; - HANDLE jobObject = ::CreateJobObject(NULL, NULL); + HANDLE jobObject = ::CreateJobObject(nullptr, nullptr); - if (jobObject == NULL) { + if (jobObject == nullptr) { qWarning("failed to create job object: %lu", ::GetLastError()); } else { ::SetInformationJobObject(jobObject, JobObjectExtendedLimitInformation, &jobInfo, sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION)); @@ -144,7 +144,7 @@ HANDLE startBinary(const QFileInfo &binary, if (e.getErrorCode() == ERROR_ELEVATION_REQUIRED) { // TODO: check if this is really correct. Are all settings updated that the secondary instance may use? - if (QMessageBox::question(NULL, QObject::tr("Elevation required"), + if (QMessageBox::question(nullptr, QObject::tr("Elevation required"), QObject::tr("This process requires elevation to run.\n" "This is a potential security risk so I highly advice you to investigate if\n" "\"%1\"\n" @@ -153,7 +153,7 @@ HANDLE startBinary(const QFileInfo &binary, "(you will be asked if you want to allow ModOrganizer.exe to make changes to the system)").arg( QDir::toNativeSeparators(binary.absoluteFilePath())), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { - ::ShellExecuteW(NULL, L"runas", ToWString(QCoreApplication::applicationFilePath()).c_str(), + ::ShellExecuteW(nullptr, L"runas", ToWString(QCoreApplication::applicationFilePath()).c_str(), (std::wstring(L"\"") + binaryName + L"\" " + ToWString(arguments)).c_str(), currentDirectoryName.c_str(), SW_SHOWNORMAL); return INVALID_HANDLE_VALUE; } else { diff --git a/src/syncoverwritedialog.cpp b/src/syncoverwritedialog.cpp index 380719d8..adeac9b8 100644 --- a/src/syncoverwritedialog.cpp +++ b/src/syncoverwritedialog.cpp @@ -82,18 +82,18 @@ void SyncOverwriteDialog::readTree(const QString &path, DirectoryEntry *director if (fileInfo.isDir()) { DirectoryEntry *subDir = directoryStructure->findSubDirectory(ToWString(file)); - if (subDir != NULL) { + if (subDir != nullptr) { readTree(fileInfo.absoluteFilePath(), subDir, newItem); } else { qCritical("no directory structure for %s?", file.toUtf8().constData()); delete newItem; - newItem = NULL; + newItem = nullptr; } } else { const FileEntry::Ptr entry = directoryStructure->findFile(ToWString(file)); QComboBox* combo = new QComboBox(ui->syncTree); combo->addItem(tr(""), -1); - if (entry.get() != NULL) { + if (entry.get() != nullptr) { bool ignore; int origin = entry->getOrigin(ignore); addToComboBox(combo, ToQString(m_DirectoryStructure->getOriginByID(origin).getName()), origin); @@ -107,7 +107,7 @@ void SyncOverwriteDialog::readTree(const QString &path, DirectoryEntry *director } ui->syncTree->setItemWidget(newItem, 1, combo); } - if (newItem != NULL) { + if (newItem != nullptr) { subTree->addChild(newItem); } } @@ -137,7 +137,7 @@ void SyncOverwriteDialog::applyTo(QTreeWidgetItem *item, const QString &path, co applyTo(child, filePath, modDirectory); } else { QComboBox *comboBox = qobject_cast(ui->syncTree->itemWidget(child, 1)); - if (comboBox != NULL) { + if (comboBox != nullptr) { int originID = comboBox->itemData(comboBox->currentIndex(), Qt::UserRole).toInt(); if (originID != -1) { FilesOrigin &origin = m_DirectoryStructure->getOriginByID(originID); diff --git a/src/viewmarkingscrollbar.cpp b/src/viewmarkingscrollbar.cpp index f1b1ba34..2452d0e3 100644 --- a/src/viewmarkingscrollbar.cpp +++ b/src/viewmarkingscrollbar.cpp @@ -14,7 +14,7 @@ ViewMarkingScrollBar::ViewMarkingScrollBar(QAbstractItemModel *model, QWidget *p void ViewMarkingScrollBar::paintEvent(QPaintEvent *event) { - if (m_Model == NULL) { + if (m_Model == nullptr) { return; } QScrollBar::paintEvent(event); -- cgit v1.3.1