diff options
| author | Tannin <devnull@localhost> | 2014-11-28 11:06:28 +0100 |
|---|---|---|
| committer | Tannin <devnull@localhost> | 2014-11-28 11:06:28 +0100 |
| commit | 78f628e0af2f2df562c40ac1424b432b6a969055 (patch) | |
| tree | 294c461fc858aa9d13fa65c37fd3517db4554f2a /src | |
| parent | 45a46778fb9c7195cb09fbba4a2c502dca6bca13 (diff) | |
cleanup und bugfixes after refactoring
Diffstat (limited to 'src')
| -rw-r--r-- | src/browserdialog.cpp | 4 | ||||
| -rw-r--r-- | src/browserdialog.h | 1 | ||||
| -rw-r--r-- | src/downloadmanager.cpp | 2 | ||||
| -rw-r--r-- | src/executableslist.cpp | 16 | ||||
| -rw-r--r-- | src/installationmanager.cpp | 3 | ||||
| -rw-r--r-- | src/iuserinterface.h | 14 | ||||
| -rw-r--r-- | src/main.cpp | 159 | ||||
| -rw-r--r-- | src/mainwindow.cpp | 337 | ||||
| -rw-r--r-- | src/mainwindow.h | 42 | ||||
| -rw-r--r-- | src/modinfo.cpp | 1 | ||||
| -rw-r--r-- | src/nexusinterface.cpp | 20 | ||||
| -rw-r--r-- | src/nexusinterface.h | 4 | ||||
| -rw-r--r-- | src/nxmaccessmanager.cpp | 4 | ||||
| -rw-r--r-- | src/organizer.pro | 5 | ||||
| -rw-r--r-- | src/organizercore.cpp | 239 | ||||
| -rw-r--r-- | src/organizercore.h | 91 | ||||
| -rw-r--r-- | src/organizerproxy.cpp | 2 | ||||
| -rw-r--r-- | src/plugincontainer.cpp | 20 | ||||
| -rw-r--r-- | src/plugincontainer.h | 35 | ||||
| -rw-r--r-- | src/pluginlist.cpp | 4 | ||||
| -rw-r--r-- | src/pluginlist.h | 2 | ||||
| -rw-r--r-- | src/profile.cpp | 8 | ||||
| -rw-r--r-- | src/selfupdater.cpp | 26 | ||||
| -rw-r--r-- | src/selfupdater.h | 1 | ||||
| -rw-r--r-- | src/settings.cpp | 27 | ||||
| -rw-r--r-- | src/settings.h | 2 | ||||
| -rw-r--r-- | src/shared/appconfig.inc | 1 | ||||
| -rw-r--r-- | src/shared/gameinfo.cpp | 20 | ||||
| -rw-r--r-- | src/shared/gameinfo.h | 2 | ||||
| -rw-r--r-- | src/shared/skyriminfo.cpp | 2 |
30 files changed, 526 insertions, 568 deletions
diff --git a/src/browserdialog.cpp b/src/browserdialog.cpp index 933b4bc0..82cd8d49 100644 --- a/src/browserdialog.cpp +++ b/src/browserdialog.cpp @@ -24,11 +24,11 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include "report.h"
#include "persistentcookiejar.h"
-#include <gameinfo.h>
#include "json.h"
#include <utility.h>
#include <gameinfo.h>
+#include "settings.h"
#include <QNetworkCookieJar>
#include <QNetworkCookie>
#include <QMenu>
@@ -49,7 +49,7 @@ BrowserDialog::BrowserDialog(QWidget *parent) ui->setupUi(this);
m_AccessManager->setCookieJar(new PersistentCookieJar(
- QDir::fromNativeSeparators(MOBase::ToQString(MOShared::GameInfo::instance().getCacheDir())) + "/cookies.dat", this));
+ QDir::fromNativeSeparators(Settings::instance().getCacheDirectory() + "/cookies.dat")));
Qt::WindowFlags flags = windowFlags() | Qt::WindowMaximizeButtonHint | Qt::WindowMinimizeButtonHint;
Qt::WindowFlags helpFlag = Qt::WindowContextHelpButtonHint;
diff --git a/src/browserdialog.h b/src/browserdialog.h index 10b44fac..680f5c03 100644 --- a/src/browserdialog.h +++ b/src/browserdialog.h @@ -23,7 +23,6 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include "browserview.h"
#include "tutorialcontrol.h"
#include <QDialog>
-#include <QProgressBar>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QTimer>
diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp index b803d170..d785a939 100644 --- a/src/downloadmanager.cpp +++ b/src/downloadmanager.cpp @@ -980,7 +980,7 @@ void DownloadManager::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) int index = 0;
try {
DownloadInfo *info = findDownload(this->sender(), &index);
- if (info != NULL) {
+ if (info != nullptr) {
if (info->m_State == STATE_CANCELING) {
setState(info, STATE_CANCELED);
} else if (info->m_State == STATE_PAUSING) {
diff --git a/src/executableslist.cpp b/src/executableslist.cpp index 11158c5b..c46cea10 100644 --- a/src/executableslist.cpp +++ b/src/executableslist.cpp @@ -72,18 +72,20 @@ ExecutablesList::~ExecutablesList() void ExecutablesList::init(IPluginGame *game)
{
+ Q_ASSERT(game != nullptr);
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());
+ if (info.isValid()) {
+ addExecutableInternal(info.title(),
+ info.binary().absoluteFilePath(),
+ info.arguments().join(" "),
+ info.workingDirectory().absolutePath(),
+ info.closeMO(),
+ info.steamAppID());
+ }
}
}
-
void ExecutablesList::getExecutables(std::vector<Executable>::iterator &begin, std::vector<Executable>::iterator &end)
{
begin = m_Executables.begin();
diff --git a/src/installationmanager.cpp b/src/installationmanager.cpp index 0fb1b78d..25fe06a4 100644 --- a/src/installationmanager.cpp +++ b/src/installationmanager.cpp @@ -68,7 +68,8 @@ template <typename T> T resolveFunction(QLibrary &lib, const char *name) InstallationManager::InstallationManager()
- : m_InstallationProgress(nullptr), m_SupportedExtensions(boost::assign::list_of("zip")("rar")("7z")("fomod")("001"))
+ : m_InstallationProgress(nullptr)
+ , m_SupportedExtensions({ "zip", "rar", "7z", "fomod", "001" })
{
QLibrary archiveLib("dlls\\archive.dll");
if (!archiveLib.load()) {
diff --git a/src/iuserinterface.h b/src/iuserinterface.h index 76d4c75a..5cb61a25 100644 --- a/src/iuserinterface.h +++ b/src/iuserinterface.h @@ -11,11 +11,7 @@ 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 storeSettings(QSettings &settings) = 0;
virtual void registerPluginTool(MOBase::IPluginTool *tool) = 0;
virtual void registerModPage(MOBase::IPluginModPage *modPage) = 0;
@@ -24,9 +20,9 @@ public: virtual void disconnectPlugins() = 0;
- virtual bool close() = 0;
+ virtual bool closeWindow() = 0;
- virtual void setEnabled(bool enabled) = 0;
+ virtual void setWindowEnabled(bool enabled) = 0;
virtual void displayModInformation(ModInfo::Ptr modInfo, unsigned int index, int tab) = 0;
@@ -34,6 +30,10 @@ public: virtual bool saveArchiveList() = 0;
+ virtual void lock() = 0;
+ virtual void unlock() = 0;
+ virtual bool unlockClicked() = 0;
+
};
#endif // IUSERINTERFACE_H
diff --git a/src/main.cpp b/src/main.cpp index 0e112873..3f0360c2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -82,14 +82,13 @@ using namespace MOBase; using namespace MOShared;
-// set up required folders (for a first install or after an update or to fix a broken installation)
bool bootstrap()
{
GameInfo &gameInfo = GameInfo::instance();
// remove the temporary backup directory in case we're restarting after an update
QString moDirectory = QDir::fromNativeSeparators(ToQString(gameInfo.getOrganizerDirectory()));
- QString backupDirectory = moDirectory.mid(0).append("/update_backup");
+ QString backupDirectory = moDirectory + "/update_backup";
if (QDir(backupDirectory).exists()) {
shellDelete(QStringList(backupDirectory));
}
@@ -97,47 +96,6 @@ bool bootstrap() // cycle logfile
removeOldFiles(ToQString(GameInfo::instance().getLogDir()), "ModOrganizer*.log", 5, QDir::Name);
- // create organizer directories
- QString dirNames[] = {
- QDir::fromNativeSeparators(ToQString(gameInfo.getProfilesDir())),
- QDir::fromNativeSeparators(ToQString(gameInfo.getModsDir())),
- QDir::fromNativeSeparators(ToQString(gameInfo.getDownloadDir())),
- QDir::fromNativeSeparators(ToQString(gameInfo.getOverwriteDir())),
- QDir::fromNativeSeparators(ToQString(gameInfo.getLogDir())),
- QDir::fromNativeSeparators(ToQString(gameInfo.getTutorialDir()))
- };
- static const int NUM_DIRECTORIES = sizeof(dirNames) / sizeof(QString);
-
- // optimistic run: try to simply create the directories:
- for (int i = 0; i < NUM_DIRECTORIES; ++i) {
- if (!QDir(dirNames[i]).exists()) {
- QDir().mkdir(dirNames[i]);
- }
- }
-
- // verify all directories exist and are writable,
- // otherwise invoke the helper to create them and make them writable
- for (int i = 0; i < NUM_DIRECTORIES; ++i) {
- QFileInfo fileInfo(dirNames[i]);
- if (!fileInfo.exists() || !fileInfo.isWritable()) {
- if (QMessageBox::question(NULL, QObject::tr("Permissions required"),
- QObject::tr("The current user account doesn't have the required access rights to run "
- "Mod Organizer. The neccessary changes can be made automatically (the MO directory "
- "will be made writable for the current user account). You will be asked to run "
- "\"helper.exe\" with administrative rights."),
- QMessageBox::Yes | QMessageBox::Cancel) == QMessageBox::Yes) {
- if (!Helper::init(GameInfo::instance().getOrganizerDirectory())) {
- return false;
- }
- } else {
- return false;
- }
- // no matter which directory didn't exist/wasn't writable, the helper
- // should have created them all so we can break the loop
- break;
- }
- }
-
// verify the hook-dll exists
QString dllName = qApp->applicationDirPath() + "/" + ToQString(AppConfig::hookDLLName());
@@ -154,29 +112,6 @@ bool bootstrap() return true;
}
-
-void cleanupDir()
-{
- // files from previous versions of MO that are no longer
- // required (in that location)
- QString fileNames[] = {
- "NCC/GamebryoBase.dll",
- "plugins/helloWorld.dll",
- "plugins/testnexus.py"
- };
-
- static const int NUM_FILES = sizeof(fileNames) / sizeof(QString);
-
- qDebug("cleaning up unused files");
-
- for (int i = 0; i < NUM_FILES; ++i) {
- if (QFile::remove(QApplication::applicationDirPath().append("/").append(fileNames[i]))) {
- qDebug("%s removed in cleanup",
- QApplication::applicationDirPath().append("/").append(fileNames[i]).toUtf8().constData());
- }
- }
-}
-
bool isNxmLink(const QString &link)
{
return link.left(6).toLower() == "nxm://";
@@ -299,6 +234,27 @@ bool HaveWriteAccess(const std::wstring &path) }
+QString determineProfile(QStringList arguments, const QSettings &settings)
+{
+ QString selectedProfileName = QString::fromUtf8(settings.value("selected_profile", "").toByteArray());
+ { // see if there is a profile on the command line
+ int profileIndex = arguments.indexOf("-p", 1);
+ if ((profileIndex != -1) && (profileIndex < arguments.size() - 1)) {
+ qDebug("profile overwritten on command line");
+ selectedProfileName = arguments.at(profileIndex + 1);
+ }
+ arguments.removeAt(profileIndex);
+ arguments.removeAt(profileIndex);
+ }
+ if (selectedProfileName.isEmpty()) {
+ qDebug("no configured profile");
+ } else {
+ qDebug("configured profile: %s", qPrintable(selectedProfileName));
+ }
+
+ return selectedProfileName;
+}
+
int main(int argc, char *argv[])
{
MOApplication application(argc, argv);
@@ -414,7 +370,7 @@ int main(int argc, char *argv[]) reportError(QObject::tr("No game identified in \"%1\". The directory is required to contain "
"the game binary and its launcher.").arg(gamePath));
}
- SelectionDialog selection(QObject::tr("Please select the game to manage"), NULL);
+ SelectionDialog selection(QObject::tr("Please select the game to manage"), nullptr);
{ // add options
QString skyrimPath = ToQString(SkyrimInfo::getRegPathStatic());
@@ -462,6 +418,11 @@ int main(int argc, char *argv[]) settings.setValue("gamePath", gamePath.toUtf8().constData());
}
+ if (pluginContainer.managedGame(ToQString(GameInfo::instance().getGameName())) == nullptr) {
+ reportError(QObject::tr("Plugin to handle %1 not installed").arg(ToQString(GameInfo::instance().getGameName())));
+ return 1;
+ }
+
if (!settings.contains("game_edition")) {
std::vector<std::wstring> editions = GameInfo::instance().getSteamVariants();
if (editions.size() > 1) {
@@ -486,7 +447,25 @@ int main(int argc, char *argv[]) return -1;
}
- cleanupDir();
+ QString selectedProfileName = determineProfile(arguments, settings);
+ organizer.setCurrentProfile(selectedProfileName);
+
+ // if we have a command line parameter, it is either a nxm link or
+ // a binary to start
+ if ((arguments.size() > 1) && (!isNxmLink(arguments.at(1)))) {
+ QString exeName = arguments.at(1);
+ qDebug("starting %s from command line", qPrintable(exeName));
+ arguments.removeFirst(); // remove application name (ModOrganizer.exe)
+ arguments.removeFirst(); // remove binary name
+ // pass the remaining parameters to the binary
+ try {
+ organizer.startApplication(exeName, arguments, QString(), QString());
+ return 0;
+ } catch (const std::exception &e) {
+ reportError(QObject::tr("failed to start application: %1").arg(e.what()));
+ return 1;
+ }
+ }
qDebug("initializing tutorials");
TutorialManager::init(QDir::fromNativeSeparators(ToQString(GameInfo::instance().getTutorialDir())).append("/"));
@@ -506,52 +485,8 @@ int main(int argc, char *argv[]) mainWindow.readSettings();
- QString selectedProfileName = QString::fromUtf8(settings.value("selected_profile", "").toByteArray());
-
- { // see if there is a profile on the command line
- int profileIndex = arguments.indexOf("-p", 1);
- if ((profileIndex != -1) && (profileIndex < arguments.size() - 1)) {
- qDebug("profile overwritten on command line");
- selectedProfileName = arguments.at(profileIndex + 1);
- }
- arguments.removeAt(profileIndex);
- arguments.removeAt(profileIndex);
- }
- if (selectedProfileName.isEmpty()) {
- qDebug("no configured profile");
- } else {
- qDebug("configured profile: %s", qPrintable(selectedProfileName));
- }
-
- // if we have a command line parameter, it is either a nxm link or
- // a binary to start
- if ((arguments.size() > 1) && (!isNxmLink(arguments.at(1)))) {
- QString exeName = arguments.at(1);
- qDebug("starting %s from command line", qPrintable(exeName));
- arguments.removeFirst(); // remove application name (ModOrganizer.exe)
- arguments.removeFirst(); // remove binary name
- // pass the remaining parameters to the binary
- try {
- mainWindow.startApplication(exeName, arguments, QString(), selectedProfileName);
- } catch (const std::exception &e) {
- reportError(QObject::tr("failed to start application: %1").arg(e.what()));
- }
-
- return 0;
- }
-
mainWindow.createFirstProfile();
- if (selectedProfileName.length() != 0) {
- if (!mainWindow.setCurrentProfile(selectedProfileName)) {
- mainWindow.setCurrentProfile(1);
- qWarning("failed to set profile: %s",
- selectedProfileName.toUtf8().constData());
- }
- } else {
- mainWindow.setCurrentProfile(1);
- }
-
qDebug("displaying main window");
mainWindow.show();
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 4762358e..d4a7f4fc 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -16,7 +16,6 @@ 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 <http://www.gnu.org/licenses/>.
*/
-#ifndef Q_MOC_RUN
#include "mainwindow.h"
#include "ui_mainwindow.h"
@@ -68,7 +67,6 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include <ipluginproxy.h>
#include <questionboxmemory.h>
#include <util.h>
-#endif // Q_MOC_RUN
#include <map>
#include <ctime>
#include <wchar.h>
@@ -176,6 +174,7 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, Organize m_RefreshProgress->setTextVisible(true);
m_RefreshProgress->setRange(0, 100);
m_RefreshProgress->setValue(0);
+ m_RefreshProgress->setVisible(false);
statusBar()->addWidget(m_RefreshProgress, 1000);
statusBar()->clearMessage();
@@ -255,7 +254,6 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, Organize connect(ui->espFilterEdit, SIGNAL(textChanged(QString)), m_PluginListSortProxy, SLOT(updateFilter(QString)));
connect(ui->espFilterEdit, SIGNAL(textChanged(QString)), this, SLOT(espFilterChanged(QString)));
- connect(m_OrganizerCore.pluginList(), SIGNAL(saveTimer()), this, SLOT(savePluginList()));
connect(ui->bsaList, SIGNAL(itemsMoved()), this, SLOT(bsaList_itemMoved()));
@@ -265,6 +263,8 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, Organize 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_OrganizerCore.downloadManager(), SIGNAL(downloadAdded()), ui->downloadView, SLOT(scrollToBottom()));
+
connect(&m_SavesWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(refreshSavesIfOpen()));
connect(&m_OrganizerCore.settings(), SIGNAL(languageChanged(QString)), this, SLOT(languageChange(QString)));
@@ -274,9 +274,9 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, Organize connect(m_OrganizerCore.updater(), SIGNAL(updateAvailable()), this, SLOT(updateAvailable()));
connect(m_OrganizerCore.updater(), SIGNAL(motdAvailable(QString)), this, SLOT(motdReceived(QString)));
- connect(NexusInterface::instance(), SIGNAL(requestNXMDownload(QString)), this, SLOT(downloadRequestedNXM(QString)));
+ connect(NexusInterface::instance(), SIGNAL(requestNXMDownload(QString)), &m_OrganizerCore, 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(), SIGNAL(needLogin()), &m_OrganizerCore, SLOT(nexusLogin()));
connect(NexusInterface::instance()->getAccessManager(), SIGNAL(loginFailed(QString)), this, SLOT(loginFailed(QString)));
connect(&TutorialManager::instance(), SIGNAL(windowTutorialFinished(QString)), this, SLOT(windowTutorialFinished(QString)));
@@ -285,7 +285,7 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, Organize connect(&m_OrganizerCore, &OrganizerCore::modInstalled, this, &MainWindow::modInstalled);
- connect(&m_IntegratedBrowser, SIGNAL(requestDownload(QUrl,QNetworkReply*)), this, SLOT(requestDownload(QUrl,QNetworkReply*)));
+ connect(&m_IntegratedBrowser, SIGNAL(requestDownload(QUrl,QNetworkReply*)), &m_OrganizerCore, SLOT(requestDownload(QUrl,QNetworkReply*)));
connect(this, SIGNAL(styleChanged(QString)), this, SLOT(updateStyle(QString)));
@@ -318,6 +318,8 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, Organize installTranslator(QFileInfo(fileName).baseName());
}
+ ui->profileBox->setCurrentText(m_OrganizerCore.currentProfile()->getName());
+
refreshExecutablesList();
updateToolBar();
}
@@ -999,18 +1001,12 @@ void MainWindow::setExecutableIndex(int index) void MainWindow::activateSelectedProfile()
{
- QString profileName = ui->profileBox->currentText();
- qDebug("activate profile \"%s\"", qPrintable(profileName));
- QString profileDir = QDir::fromNativeSeparators(ToQString(GameInfo::instance().getProfilesDir()))
- .append("/").append(profileName);
- m_OrganizerCore.setCurrentProfile(new Profile(QDir(profileDir)));
+ m_OrganizerCore.setCurrentProfile(ui->profileBox->currentText());
m_ModListSortProxy->setProfile(m_OrganizerCore.currentProfile());
- connect(m_OrganizerCore.currentProfile(), SIGNAL(modStatusChanged(uint)), this, SLOT(modStatusChanged(uint)));
-
refreshSaveList();
- refreshModList();
+ m_OrganizerCore.refreshModList();
}
void MainWindow::on_profileBox_currentIndexChanged(int index)
@@ -1330,7 +1326,7 @@ static bool BySortValue(const std::pair<UINT32, QTreeWidgetItem*> &LHS, const st void MainWindow::updateBSAList(const QStringList &defaultArchives, const QStringList &activeArchives)
{
-
+ m_DefaultArchives = defaultArchives;
ui->bsaList->clear();
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
ui->bsaList->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
@@ -1413,11 +1409,11 @@ void MainWindow::updateBSAList(const QStringList &defaultArchives, const QString subItem->setExpanded(true);
}
- m_OrganizerCore.checkBSAList();
+ checkBSAList();
}
-void MainWindow::checkBSAList(const QStringList &defaultArchives)
+void MainWindow::checkBSAList()
{
ui->bsaList->blockSignals(true);
@@ -1433,7 +1429,7 @@ void MainWindow::checkBSAList(const QStringList &defaultArchives) item->setToolTip(0, QString());
if (item->checkState(0) == Qt::Unchecked) {
- if (defaultArchives.contains(filename)) {
+ if (m_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;
@@ -1557,8 +1553,34 @@ void MainWindow::storeSettings(QSettings &settings) settings.setValue("filters_visible", ui->displayCategoriesBtn->isChecked());
settings.setValue("manage_bsas", ui->manageArchivesBox->isChecked());
+
+ settings.setValue("selected_executable", ui->executablesListBox->currentIndex());
+}
+
+void MainWindow::lock()
+{
+ m_LockDialog = new LockedDialog(qApp->activeWindow());
+ m_LockDialog->show();
+ setEnabled(false);
}
+void MainWindow::unlock()
+{
+ if (m_LockDialog != nullptr) {
+ m_LockDialog->hide();
+ m_LockDialog->deleteLater();
+ }
+ setEnabled(true);
+}
+
+bool MainWindow::unlockClicked()
+{
+ if (m_LockDialog != nullptr) {
+ return m_LockDialog->unlockClicked();
+ } else {
+ return false;
+ }
+}
void MainWindow::on_btnRefreshData_clicked()
{
@@ -1581,18 +1603,20 @@ void MainWindow::on_tabWidget_currentChanged(int index) }
-void MainWindow::installMod()
+void MainWindow::installMod(QString fileName)
{
try {
- QStringList extensions = m_OrganizerCore.installationManager()->getSupportedExtensions();
- for (auto iter = extensions.begin(); iter != extensions.end(); ++iter) {
- *iter = "*." + *iter;
- }
+ if (fileName.isEmpty()) {
+ QStringList extensions = m_OrganizerCore.installationManager()->getSupportedExtensions();
+ for (auto iter = extensions.begin(); iter != extensions.end(); ++iter) {
+ *iter = "*." + *iter;
+ }
- QString fileName = FileDialogMemory::getOpenFileName("installMod", this, tr("Choose Mod"), QString(),
- tr("Mod Archive").append(QString(" (%1)").arg(extensions.join(" "))));
+ fileName = FileDialogMemory::getOpenFileName("installMod", this, tr("Choose Mod"), QString(),
+ tr("Mod Archive").append(QString(" (%1)").arg(extensions.join(" "))));
+ }
- if (fileName.length() == 0) {
+ if (fileName.isEmpty()) {
return;
} else {
m_OrganizerCore.installMod(fileName);
@@ -1692,7 +1716,7 @@ bool MainWindow::modifyExecutablesDialog() {
bool result = false;
try {
- EditExecutablesDialog dialog(m_OrganizerCore.executablesList());
+ EditExecutablesDialog dialog(*m_OrganizerCore.executablesList());
if (dialog.exec() == QDialog::Accepted) {
m_OrganizerCore.setExecutablesDialog(dialog.getExecutablesList());
result = true;
@@ -1805,33 +1829,6 @@ void MainWindow::setESPListSorting(int index) }
}
-
-bool MainWindow::setCurrentProfile(int index)
-{
- QComboBox *profilesBox = findChild<QComboBox*>("profileBox");
- if (index >= profilesBox->count()) {
- return false;
- } else {
- profilesBox->setCurrentIndex(index);
- return true;
- }
-}
-
-bool MainWindow::setCurrentProfile(const QString &name)
-{
- QComboBox *profilesBox = findChild<QComboBox*>("profileBox");
- for (int i = 0; i < profilesBox->count(); ++i) {
- if (QString::compare(profilesBox->itemText(i), name, Qt::CaseInsensitive) == 0) {
- profilesBox->setCurrentIndex(i);
- return true;
- }
- }
- // profile not valid
- profilesBox->setCurrentIndex(1);
- return false;
-}
-
-
void MainWindow::refresher_progress(int percent)
{
if (percent == 100) {
@@ -1864,7 +1861,7 @@ void MainWindow::modorder_changed() }
m_OrganizerCore.refreshBSAList();
m_OrganizerCore.currentProfile()->writeModlist();
- m_OrganizerCore.saveArchiveList();
+ saveArchiveList();
m_OrganizerCore.directoryStructure()->getFileRegister()->sortOrigins();
{ // refresh selection
@@ -1881,11 +1878,11 @@ void MainWindow::modorder_changed() }
}
-void MainWindow::modInstalled()
+void MainWindow::modInstalled(const QString &modName)
{
QModelIndexList posList =
- m_OrganizerCore.modList().match(m_OrganizerCore.modList().index(0, 0),
- Qt::DisplayRole, static_cast<const QString&>(modName));
+ m_OrganizerCore.modList()->match(m_OrganizerCore.modList()->index(0, 0),
+ Qt::DisplayRole, static_cast<const QString&>(modName));
if (posList.count() == 1) {
ui->modList->scrollTo(posList.at(0));
}
@@ -2150,7 +2147,7 @@ void MainWindow::restoreBackup_clicked() if (!modDir.rename(modInfo->absolutePath(), destinationPath)) {
reportError(tr("failed to rename \"%1\" to \"%2\"").arg(modInfo->absolutePath()).arg(destinationPath));
}
- refreshModList();
+ m_OrganizerCore.refreshModList();
}
}
}
@@ -2261,7 +2258,7 @@ void MainWindow::resumeDownload(int downloadIndex) QString username, password;
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));
+ m_OrganizerCore.doAfterLogin([&] () { this->resumeDownload(downloadIndex); });
NexusInterface::instance()->getAccessManager()->login(username, password);
} else {
MessageDialog::showMessage(tr("You need to be logged in with Nexus to resume a download"), this);
@@ -2277,7 +2274,7 @@ void MainWindow::endorseMod(ModInfo::Ptr mod) } else {
QString username, password;
if (m_OrganizerCore.settings().getNexusLogin(username, password)) {
- m_PostLoginTasks.push_back(boost::bind(&MainWindow::endorseMod, _1, mod));
+ m_OrganizerCore.doAfterLogin(boost::bind(&MainWindow::endorseMod, this, mod));
NexusInterface::instance()->getAccessManager()->login(username, password);
} else {
MessageDialog::showMessage(tr("You need to be logged in with Nexus to endorse"), this);
@@ -2304,7 +2301,7 @@ void MainWindow::unendorse_clicked() ModInfo::getByIndex(m_ContextRow)->endorse(false);
} else {
if (m_OrganizerCore.settings().getNexusLogin(username, password)) {
- m_PostLoginTasks.push_back(boost::mem_fn(&MainWindow::unendorse_clicked));
+ m_OrganizerCore.doAfterLogin([&] () { this->unendorse_clicked(); });
NexusInterface::instance()->getAccessManager()->login(username, password);
} else {
MessageDialog::showMessage(tr("You need to be logged in with Nexus to endorse"), this);
@@ -2312,14 +2309,14 @@ void MainWindow::unendorse_clicked() }
}
-void MainWindow::loginFailed(const QString &message)
+void MainWindow::loginFailed(const QString&)
{
statusBar()->hide();
}
void MainWindow::windowTutorialFinished(const QString &windowName)
{
- m_OrganizerCore.settings().directInterface().setValue(QString("CompletedWindowTutorials/") + windowName, this);
+ m_OrganizerCore.settings().directInterface().setValue(QString("CompletedWindowTutorials/") + windowName, true);
}
void MainWindow::overwriteClosed(int)
@@ -2356,7 +2353,7 @@ void MainWindow::displayModInformation(ModInfo::Ptr modInfo, unsigned int index, modInfo->saveMeta();
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(downloadRequest(QString)), &m_OrganizerCore, SLOT(downloadRequestedNXM(QString)));
connect(&dialog, SIGNAL(modOpen(QString, int)), this, SLOT(displayModInformation(QString, int)), Qt::QueuedConnection);
connect(&dialog, SIGNAL(modOpenNext()), this, SLOT(modOpenNext()), Qt::QueuedConnection);
connect(&dialog, SIGNAL(modOpenPrev()), this, SLOT(modOpenPrev()), Qt::QueuedConnection);
@@ -2393,6 +2390,16 @@ void MainWindow::displayModInformation(ModInfo::Ptr modInfo, unsigned int index, }
}
+bool MainWindow::closeWindow()
+{
+ return close();
+}
+
+void MainWindow::setWindowEnabled(bool enabled)
+{
+ setEnabled(enabled);
+}
+
void MainWindow::modOpenNext()
{
@@ -2495,7 +2502,7 @@ void MainWindow::syncOverwrite() if (syncDialog.exec() == QDialog::Accepted) {
syncDialog.apply(QDir::fromNativeSeparators(m_OrganizerCore.settings().getModDirectory()));
modInfo->testValid();
- refreshDirectoryStructure();
+ m_OrganizerCore.refreshDirectoryStructure();
}
}
@@ -2530,7 +2537,7 @@ void MainWindow::createModFromOverwrite() shellMove(QStringList(QDir::toNativeSeparators(overwriteInfo->absolutePath()) + "\\*"),
QStringList(QDir::toNativeSeparators(newMod->absolutePath())), this);
- refreshModList();
+ m_OrganizerCore.refreshModList();
}
void MainWindow::cancelModListEditor()
@@ -2742,7 +2749,7 @@ void MainWindow::savePrimaryCategory() bool MainWindow::saveArchiveList()
{
- if (m_ArchivesInit) {
+ if (m_OrganizerCore.isArchivesInit()) {
SafeWriteFile archiveFile(m_OrganizerCore.currentProfile()->getArchivesFileName());
for (int i = 0; i < ui->bsaList->topLevelItemCount(); ++i) {
QTreeWidgetItem *tlItem = ui->bsaList->topLevelItem(i);
@@ -2776,7 +2783,7 @@ void MainWindow::checkModsForUpdates() } else {
QString username, password;
if (m_OrganizerCore.settings().getNexusLogin(username, password)) {
- m_OrganizerCore.doAfterLogin(boost::mem_fn(&MainWindow::checkModsForUpdates));
+ m_OrganizerCore.doAfterLogin([this] () {this->checkModsForUpdates();});
NexusInterface::instance()->getAccessManager()->login(username, password);
} else { // otherwise there will be no endorsement info
m_ModsToUpdate = ModInfo::checkAllForUpdate(this);
@@ -3297,12 +3304,6 @@ void MainWindow::linkMenu() }
}
-void MainWindow::downloadSpeed(const QString &serverName, int bytesPerSecond)
-{
- m_OrganizerCore.settings().setDownloadSpeed(serverName, bytesPerSecond);
-}
-
-
void MainWindow::on_actionSettings_triggered()
{
QString oldModDirectory(m_OrganizerCore.settings().getModDirectory());
@@ -3400,64 +3401,6 @@ void MainWindow::languageChange(const QString &newLanguage) }
-void MainWindow::installDownload(int index)
-{
- try {
- QString fileName = m_OrganizerCore.downloadManager()->getFilePath(index);
- int modID = m_OrganizerCore.downloadManager()->getModID(index);
- GuessedValue<QString> modName;
-
- // see if there already are mods with the specified mod id
- if (modID != 0) {
- std::vector<ModInfo::Ptr> modInfo = ModInfo::getByModID(modID);
- for (auto iter = modInfo.begin(); iter != modInfo.end(); ++iter) {
- std::vector<ModInfo::EFlag> flags = (*iter)->getFlags();
- if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_BACKUP) == flags.end()) {
- modName.update((*iter)->name(), GUESS_PRESET);
- (*iter)->saveMeta();
- }
- }
- }
-
- m_OrganizerCore.currentProfile()->writeModlistNow();
-
- bool hasIniTweaks = false;
- 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_OrganizerCore.modList()->match(m_OrganizerCore.modList()->index(0, 0), Qt::DisplayRole, static_cast<const QString&>(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);
- } else {
- reportError(tr("mod \"%1\" not found").arg(modName));
- }
- m_OrganizerCore.downloadManager()->markInstalled(index);
-
- emit modInstalled();
- } 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) {
- reportError(e.what());
- }
-}
-
-
void MainWindow::writeDataToFile(QFile &file, const QString &directory, const DirectoryEntry &directoryEntry)
{
{ // list files
@@ -3704,7 +3647,7 @@ void MainWindow::openDataFile() QString arguments;
switch (getBinaryExecuteInfo(targetInfo, binaryInfo, arguments)) {
case 1: {
- spawnBinaryDirect(binaryInfo, arguments, m_OrganizerCore.currentProfile()->getName(), targetInfo.absolutePath(), "");
+ 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);
@@ -3832,7 +3775,7 @@ void MainWindow::updateDownloadListDelegate() ui->downloadView->sortByColumn(1, Qt::AscendingOrder);
ui->downloadView->header()->resizeSections(QHeaderView::Fixed);
- connect(ui->downloadView->itemDelegate(), SIGNAL(installDownload(int)), this, SLOT(installDownload(int)));
+ connect(ui->downloadView->itemDelegate(), SIGNAL(installDownload(int)), &m_OrganizerCore, SLOT(installDownload(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)));
@@ -4312,7 +4255,7 @@ std::string MainWindow::readFromPipe(HANDLE stdOutRead) return result;
}
-void MainWindow::processLOOTOut(const std::string &lootOut, std::string &reportURL, std::string &errorMessages, QProgressDialog &dialog)
+void MainWindow::processLOOTOut(const std::string &lootOut, std::string &errorMessages, QProgressDialog &dialog)
{
std::vector<std::string> lines;
boost::split(lines, lootOut, boost::is_any_of("\r\n"));
@@ -4347,122 +4290,6 @@ void MainWindow::processLOOTOut(const std::string &lootOut, std::string &reportU }
}
-
-HANDLE MainWindow::startApplication(const QString &executable, const QStringList &args, const QString &cwd, const QString &profile)
-{
- QFileInfo binary;
- QString arguments = args.join(" ");
- QString currentDirectory = cwd;
- QString profileName = profile;
- if (profile.length() == 0) {
- if (m_OrganizerCore.currentProfile() != NULL) {
- profileName = m_OrganizerCore.currentProfile()->getName();
- } else {
- throw MyException(tr("No profile set"));
- }
- }
- QString steamAppID;
- if (executable.contains('\\') || executable.contains('/')) {
- // file path
-
- binary = QFileInfo(executable);
- if (binary.isRelative()) {
- // relative path, should be relative to game directory
- binary = QFileInfo(QDir::fromNativeSeparators(ToQString(GameInfo::instance().getGameDirectory())) + "/" + executable);
- }
-
- std::vector<Executable>::iterator current, end;
- m_OrganizerCore.executablesList()->getExecutables(current, end);
- for (; current != end; ++current) {
- if (current->m_BinaryInfo == binary) {
- steamAppID = current->m_SteamAppID;
- currentDirectory = current->m_WorkingDirectory;
- }
- }
-
- if (cwd.length() == 0) {
- currentDirectory = binary.absolutePath();
- }
- } else {
- // only a file name, search executables list
- try {
- const Executable &exe = m_OrganizerCore.executablesList()->find(executable);
- steamAppID = exe.m_SteamAppID;
- if (arguments == "") {
- arguments = exe.m_Arguments;
- }
- binary = exe.m_BinaryInfo;
- if (cwd.length() == 0) {
- currentDirectory = exe.m_WorkingDirectory;
- }
- } catch (const std::runtime_error&) {
- qWarning("\"%s\" not set up as executable", executable.toUtf8().constData());
- binary = QFileInfo(executable);
- }
- }
-
- return spawnBinaryDirect(binary, arguments, profileName, currentDirectory, steamAppID);
-}
-
-
-bool MainWindow::waitForProcessOrJob(HANDLE handle, LPDWORD exitCode)
-{
- LockedDialog *dialog = new LockedDialog(this);
- dialog->show();
- setEnabled(false);
- ON_BLOCK_EXIT([&] () { dialog->hide(); dialog->deleteLater(); this->setEnabled(true); });
-
- DWORD retLen;
- JOBOBJECT_BASIC_PROCESS_ID_LIST info;
-
- bool isJobHandle = true;
-
- ULONG lastProcessID = ULONG_MAX;
- HANDLE processHandle = handle;
-
- DWORD res = ::MsgWaitForMultipleObjects(1, &handle, false, 500, QS_KEY | QS_MOUSE);
- while ((res != WAIT_FAILED) && (res != WAIT_OBJECT_0) && !dialog->unlockClicked()) {
- if (isJobHandle) {
- if (::QueryInformationJobObject(handle, JobObjectBasicProcessIdList, &info, sizeof(info), &retLen) > 0) {
- if (info.NumberOfProcessIdsInList == 0) {
- // fake signaled state
- res = WAIT_OBJECT_0;
- break;
- } else {
- // this is indeed a job handle. Figure out one of the process handles as well.
- if (lastProcessID != info.ProcessIdList[0]) {
- lastProcessID = info.ProcessIdList[0];
- if (processHandle != handle) {
- ::CloseHandle(processHandle);
- }
- processHandle = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, lastProcessID);
- }
- }
- } 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, &handle, false, 500, QS_KEY | QS_MOUSE);
- }
-
- if (exitCode != NULL) {
- ::GetExitCodeProcess(processHandle, exitCode);
- }
- ::CloseHandle(processHandle);
-
- return res == WAIT_OBJECT_0;
-}
-
void MainWindow::on_bossButton_clicked()
{
std::string reportURL;
@@ -4556,14 +4383,14 @@ void MainWindow::on_bossButton_clicked() // keep processing events so the app doesn't appear dead
QCoreApplication::processEvents();
std::string lootOut = readFromPipe(stdOutRead);
- processLOOTOut(lootOut, reportURL, errorMessages, dialog);
+ processLOOTOut(lootOut, errorMessages, dialog);
res = ::MsgWaitForMultipleObjects(1, &loot, false, 1000, QS_KEY | QS_MOUSE);
}
std::string remainder = readFromPipe(stdOutRead).c_str();
if (remainder.length() > 0) {
- processLOOTOut(remainder, reportURL, errorMessages, dialog);
+ processLOOTOut(remainder, errorMessages, dialog);
}
DWORD exitCode = 0UL;
::GetExitCodeProcess(processHandle, &exitCode);
@@ -4720,7 +4547,7 @@ void MainWindow::on_restoreModsButton_clicked() QMessageBox::critical(this, tr("Restore failed"),
tr("Failed to restore the backup. Errorcode: %1").arg(windowsErrorString(::GetLastError())));
}
- refreshModList(false);
+ m_OrganizerCore.refreshModList(false);
}
}
diff --git a/src/mainwindow.h b/src/mainwindow.h index c8cb8152..27d75ba8 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -61,6 +61,7 @@ namespace Ui { class MainWindow;
}
+class LockedDialog;
class QToolButton;
class ModListSortProxy;
class ModListGroupCategoriesProxy;
@@ -79,9 +80,13 @@ public: QWidget *parent = 0);
~MainWindow();
- void storeSettings(QSettings &settings);
+ void storeSettings(QSettings &settings) override;
void readSettings();
+ virtual void lock() override;
+ virtual void unlock() override;
+ virtual bool unlockClicked() override;
+
bool addProfile();
void updateBSAList(const QStringList &defaultArchives, const QStringList &activeArchives);
void refreshDataTree();
@@ -92,9 +97,6 @@ public: void setModListSorting(int index);
void setESPListSorting(int index);
- bool setCurrentProfile(int index);
- bool setCurrentProfile(const QString &name);
-
void createFirstProfile();
bool saveArchiveList();
@@ -106,11 +108,7 @@ public: 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);
-
- HANDLE startApplication(const QString &executable, const QStringList &args = QStringList(), const QString &cwd = "", const QString &profile = "");
-
- bool waitForProcessOrJob(HANDLE processHandle, LPDWORD exitCode = NULL);
+ void processLOOTOut(const std::string &lootOut, std::string &errorMessages, QProgressDialog &dialog);
void updateModInDirectoryStructure(unsigned int index, ModInfo::Ptr modInfo);
@@ -120,11 +118,11 @@ public: virtual void disconnectPlugins();
- virtual bool close();
- virtual void setEnabled(bool enabled);
-
void displayModInformation(ModInfo::Ptr modInfo, unsigned int index, int tab);
+ virtual bool closeWindow();
+ virtual void setWindowEnabled(bool enabled);
+
public slots:
void displayColumnSelection(const QPoint &pos);
@@ -161,8 +159,6 @@ protected: private:
- void refreshModList(bool saveChanges = true);
-
void actionToToolButton(QAction *&sourceAction);
void updateToolBar();
@@ -172,13 +168,10 @@ private: void startSteam();
- HANDLE spawnBinaryDirect(const QFileInfo &binary, const QString &arguments, const QString &profileName, const QDir ¤tDirectory, 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();
+ void installMod(QString fileName = "");
QList<MOBase::IOrganizer::FileInfo> findFileInfos(const QString &path, const std::function<bool (const MOBase::IOrganizer::FileInfo &)> &filter) const;
@@ -275,6 +268,8 @@ private: QProgressBar *m_RefreshProgress;
bool m_Refreshing;
+ QStringList m_DefaultArchives;
+
QAbstractItemModel *m_ModListGroupingProxy;
ModListSortProxy *m_ModListSortProxy;
@@ -322,6 +317,8 @@ private: bool m_DidUpdateMasterList;
+ LockedDialog *m_LockDialog { nullptr };
+
private slots:
void showMessage(const QString &message);
@@ -363,7 +360,6 @@ private slots: void linkMenu();
void languageChange(const QString &newLanguage);
- void modStatusChanged(unsigned int index);
void saveSelectionChanged(QListWidgetItem *newItem);
void windowTutorialFinished(const QString &windowName);
@@ -385,7 +381,6 @@ private slots: void linkClicked(const QString &url);
- void installDownload(int index);
void updateAvailable();
void motdReceived(const QString &motd);
@@ -402,7 +397,7 @@ private slots: void modDetailsUpdated(bool success);
void modlistChanged(int row);
- void modInstalled();
+ void modInstalled(const QString &modName);
void nxmUpdatesAvailable(const std::vector<int> &modIDs, QVariant userData, QVariant resultData, int requestID);
void nxmEndorsementToggled(int, QVariant, QVariant resultData, int);
@@ -436,7 +431,7 @@ private slots: void startExeAction();
- void checkBSAList(const QStringList &defaultArchives);
+ void checkBSAList();
void updateProblemsButton();
@@ -464,8 +459,6 @@ private slots: */
void allowListResize();
- void downloadSpeed(const QString &serverName, int bytesPerSecond);
-
void toolBar_customContextMenuRequested(const QPoint &point);
void removeFromToolbar();
void overwriteClosed(int);
@@ -479,7 +472,6 @@ private slots: void about();
void delayedRemove();
- void requestDownload(const QUrl &url, QNetworkReply *reply);
void modlistSelectionChanged(const QModelIndex ¤t, const QModelIndex &previous);
void modListSortIndicatorChanged(int column, Qt::SortOrder order);
diff --git a/src/modinfo.cpp b/src/modinfo.cpp index 189e67b2..d773823a 100644 --- a/src/modinfo.cpp +++ b/src/modinfo.cpp @@ -476,6 +476,7 @@ ModInfoRegular::ModInfoRegular(const QDir &path, DirectoryEntry **directoryStruc , m_Path(path.absolutePath()) , m_MetaInfoChanged(false) , m_EndorsedState(ENDORSED_UNKNOWN) + , m_NexusBridge() { testValid(); m_CreationTime = QFileInfo(path.absolutePath()).created(); diff --git a/src/nexusinterface.cpp b/src/nexusinterface.cpp index b4006097..d68fe8fe 100644 --- a/src/nexusinterface.cpp +++ b/src/nexusinterface.cpp @@ -34,35 +34,34 @@ using namespace MOShared; NexusBridge::NexusBridge(const QString &subModule)
: m_Interface(NexusInterface::instance())
- , m_Url(MOBase::ToQString(MOShared::GameInfo::instance().getNexusInfoUrl()))
+ , m_Url() // lazy initialized
, m_SubModule(subModule)
{
}
-
void NexusBridge::requestDescription(int modID, QVariant userData)
{
- m_RequestIDs.insert(m_Interface->requestDescription(modID, this, userData, m_SubModule, m_Url));
+ m_RequestIDs.insert(m_Interface->requestDescription(modID, this, userData, m_SubModule, url()));
}
void NexusBridge::requestFiles(int modID, QVariant userData)
{
- m_RequestIDs.insert(m_Interface->requestFiles(modID, this, userData, m_SubModule, m_Url));
+ m_RequestIDs.insert(m_Interface->requestFiles(modID, this, userData, m_SubModule, url()));
}
void NexusBridge::requestFileInfo(int modID, int fileID, QVariant userData)
{
- m_RequestIDs.insert(m_Interface->requestFileInfo(modID, fileID, this, userData, m_SubModule, m_Url));
+ m_RequestIDs.insert(m_Interface->requestFileInfo(modID, fileID, this, userData, m_SubModule, url()));
}
void NexusBridge::requestDownloadURL(int modID, int fileID, QVariant userData)
{
- m_RequestIDs.insert(m_Interface->requestDownloadURL(modID, fileID, this, userData, m_SubModule, m_Url));
+ m_RequestIDs.insert(m_Interface->requestDownloadURL(modID, fileID, this, userData, m_SubModule, url()));
}
void NexusBridge::requestToggleEndorsement(int modID, bool endorse, QVariant userData)
{
- m_RequestIDs.insert(m_Interface->requestToggleEndorsement(modID, endorse, this, userData, m_SubModule, m_Url));
+ m_RequestIDs.insert(m_Interface->requestToggleEndorsement(modID, endorse, this, userData, m_SubModule, url()));
}
void NexusBridge::nxmDescriptionAvailable(int modID, QVariant userData, QVariant resultData, int requestID)
@@ -138,6 +137,13 @@ void NexusBridge::nxmRequestFailed(int modID, int fileID, QVariant userData, int }
}
+QString NexusBridge::url() {
+ if (m_Url.isEmpty()) {
+ m_Url = MOBase::ToQString(MOShared::GameInfo::instance().getNexusInfoUrl());
+ }
+ return m_Url;
+}
+
QAtomicInt NexusInterface::NXMRequestInfo::s_NextID(0);
diff --git a/src/nexusinterface.h b/src/nexusinterface.h index af2f8c75..28accd3d 100644 --- a/src/nexusinterface.h +++ b/src/nexusinterface.h @@ -109,6 +109,10 @@ public slots: private:
+ QString url();
+
+private:
+
NexusInterface *m_Interface;
QString m_Url;
QString m_SubModule;
diff --git a/src/nxmaccessmanager.cpp b/src/nxmaccessmanager.cpp index 18b47707..18568dad 100644 --- a/src/nxmaccessmanager.cpp +++ b/src/nxmaccessmanager.cpp @@ -22,6 +22,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include "report.h"
#include "utility.h"
#include "selfupdater.h"
+#include "settings.h"
#include "persistentcookiejar.h"
#include <QMessageBox>
#include <QPushButton>
@@ -48,8 +49,9 @@ NXMAccessManager::NXMAccessManager(QObject *parent, const QString &moVersion) , m_MOVersion(moVersion)
, m_LoginAttempted(false)
{
+
setCookieJar(new PersistentCookieJar(
- QDir::fromNativeSeparators(MOBase::ToQString(MOShared::GameInfo::instance().getCacheDir())) + "/nexus_cookies.dat", this));
+ QDir::fromNativeSeparators(Settings::instance().getCacheDirectory() + "/nexus_cookies.dat")));
}
NXMAccessManager::~NXMAccessManager()
diff --git a/src/organizer.pro b/src/organizer.pro index 98dbcd4a..a16e396d 100644 --- a/src/organizer.pro +++ b/src/organizer.pro @@ -284,7 +284,8 @@ CONFIG(debug, debug|release) { #QMAKE_CXXFLAGS_WARN_ON -= -W3
#QMAKE_CXXFLAGS_WARN_ON += -W4
-QMAKE_CXXFLAGS += /wd4100 -wd4127 -wd4512 -wd4189
+QMAKE_CXXFLAGS -= -w34100 -w34189
+QMAKE_CXXFLAGS += -wd4100 -wd4127 -wd4512 -wd4189
CONFIG += embed_manifest_exe
@@ -346,7 +347,7 @@ SRCDIR ~= s,/,$$QMAKE_DIR_SEP,g DSTDIR ~= s,/,$$QMAKE_DIR_SEP,g
QMAKE_POST_LINK += xcopy /y /I $$quote($$SRCDIR\\ModOrganizer*.exe) $$quote($$DSTDIR) $$escape_expand(\\n)
-QMAKE_POST_LINK += xcopy /y /I $$quote($$SRCDIR\\ModOrganizer*.exe) $$quote($$DSTDIR) $$escape_expand(\\n)
+QMAKE_POST_LINK += xcopy /y /I $$quote($$SRCDIR\\ModOrganizer*.pdb) $$quote($$DSTDIR) $$escape_expand(\\n)
QMAKE_POST_LINK += xcopy /y /s /I $$quote($$BASEDIR\\stylesheets) $$quote($$DSTDIR)\\stylesheets $$escape_expand(\\n)
QMAKE_POST_LINK += xcopy /y /s /I $$quote($$BASEDIR\\tutorials) $$quote($$DSTDIR)\\tutorials $$escape_expand(\\n)
QMAKE_POST_LINK += xcopy /y /s /I $$quote($$BASEDIR\\*.qm) $$quote($$DSTDIR)\\translations $$escape_expand(\\n)
diff --git a/src/organizercore.cpp b/src/organizercore.cpp index 68989c8c..751cc010 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -141,7 +141,7 @@ OrganizerCore::OrganizerCore(const QSettings &initSettings) , m_UserInterface(nullptr)
, m_PluginContainer(nullptr)
, m_CurrentProfile(nullptr)
- , m_Settings()
+ , m_Settings(initSettings)
, m_Updater(NexusInterface::instance())
, m_AboutToRun()
, m_FinishedRun()
@@ -170,12 +170,11 @@ OrganizerCore::OrganizerCore(const QSettings &initSettings) connect(&m_DirectoryRefresher, SIGNAL(refreshed()), this, SLOT(directory_refreshed()));
connect(&m_ModList, SIGNAL(removeOrigin(QString)), this, SLOT(removeOrigin(QString)));
+ connect(&m_PluginList, SIGNAL(saveTimer()), this, SLOT(savePluginList()));
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);
@@ -214,7 +213,9 @@ void OrganizerCore::storeSettings() if (m_UserInterface != nullptr) {
m_UserInterface->storeSettings(settings);
}
- settings.setValue("selected_profile", m_CurrentProfile->getName().toUtf8().constData());
+ if (m_CurrentProfile != nullptr) {
+ settings.setValue("selected_profile", m_CurrentProfile->getName().toUtf8().constData());
+ }
settings.setValue("ask_for_nexuspw", m_AskForNexusPW);
settings.remove("customExecutables");
@@ -238,9 +239,6 @@ void OrganizerCore::storeSettings() }
settings.endArray();
- QComboBox *executableBox = findChild<QComboBox*>("executablesListBox");
- settings.setValue("selected_executable", executableBox->currentIndex());
-
FileDialogMemory::save(settings);
settings.sync();
@@ -287,6 +285,10 @@ void OrganizerCore::updateExecutablesList(QSettings &settings) }
settings.endArray();
+
+
+ // TODO this has nothing to do with executables list move to an appropriate function!
+ ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure, m_Settings.displayForeign());
}
void OrganizerCore::setUserInterface(IUserInterface *userInterface, QWidget *widget)
@@ -295,16 +297,17 @@ void OrganizerCore::setUserInterface(IUserInterface *userInterface, QWidget *wid 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)));
+ if (widget != nullptr) {
+ 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(showMessage(QString)), widget, SLOT(showMessage(QString)));
+ }
m_InstallationManager.setParentWidget(widget);
m_Updater.setUserInterface(widget);
@@ -423,15 +426,29 @@ void OrganizerCore::removeOrigin(const QString &name) refreshLists();
}
+void OrganizerCore::downloadSpeed(const QString &serverName, int bytesPerSecond)
+{
+ m_Settings.setDownloadSpeed(serverName, bytesPerSecond);
+}
+
InstallationManager *OrganizerCore::installationManager()
{
return &m_InstallationManager;
}
-void OrganizerCore::setCurrentProfile(Profile *profile) {
+void OrganizerCore::setCurrentProfile(const QString &profileName)
+{
+ QString profileDir = qApp->property("dataPath").toString() + "/" + ToQString(AppConfig::profilesPath()) + "/" + profileName;
+
+ Profile *newProfile = new Profile(QDir(profileDir));
+
delete m_CurrentProfile;
- m_CurrentProfile = profile;
- m_ModList.setProfile(profile);
+ m_CurrentProfile = newProfile;
+ m_ModList.setProfile(newProfile);
+
+ connect(m_CurrentProfile, SIGNAL(modStatusChanged(uint)), this, SLOT(modStatusChanged(uint)));
+
+ refreshDirectoryStructure();
}
MOBase::IGameInfo &OrganizerCore::gameInfo() const
@@ -512,7 +529,7 @@ bool OrganizerCore::removeMod(MOBase::IModInterface *mod) }
}
-void OrganizerCore::modDataChanged(MOBase::IModInterface *mod)
+void OrganizerCore::modDataChanged(MOBase::IModInterface*)
{
refreshModList(false);
}
@@ -579,6 +596,63 @@ MOBase::IModInterface *OrganizerCore::installMod(const QString &fileName) return nullptr;
}
+void OrganizerCore::installDownload(int downloadIndex)
+{
+ try {
+ QString fileName = m_DownloadManager.getFilePath(downloadIndex);
+ int modID = m_DownloadManager.getModID(downloadIndex);
+ GuessedValue<QString> modName;
+
+ // see if there already are mods with the specified mod id
+ if (modID != 0) {
+ std::vector<ModInfo::Ptr> modInfo = ModInfo::getByModID(modID);
+ for (auto iter = modInfo.begin(); iter != modInfo.end(); ++iter) {
+ std::vector<ModInfo::EFlag> flags = (*iter)->getFlags();
+ if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_BACKUP) == flags.end()) {
+ modName.update((*iter)->name(), GUESS_PRESET);
+ (*iter)->saveMeta();
+ }
+ }
+ }
+
+ m_CurrentProfile->writeModlistNow();
+
+ bool hasIniTweaks = false;
+ 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);
+ } else {
+ reportError(tr("mod \"%1\" not found").arg(modName));
+ }
+ m_DownloadManager.markInstalled(downloadIndex);
+
+ emit modInstalled(modName);
+ } else if (m_InstallationManager.wasCancelled()) {
+ QMessageBox::information(qApp->activeWindow(),
+ tr("Installation cancelled"),
+ tr("The mod was not installed completely."),
+ QMessageBox::Ok);
+ }
+ } catch (const std::exception &e) {
+ reportError(e.what());
+ }
+}
+
QString OrganizerCore::resolvePath(const QString &fileName) const
{
if (m_DirectoryStructure == nullptr) {
@@ -687,10 +761,10 @@ void OrganizerCore::spawnBinary(const QFileInfo &binary, const QString &argument HANDLE processHandle = spawnBinaryDirect(binary, arguments, m_CurrentProfile->getName(), currentDirectory, steamAppID);
if (processHandle != INVALID_HANDLE_VALUE) {
if (closeAfterStart && (m_UserInterface != nullptr)) {
- m_UserInterface->close();
+ m_UserInterface->closeWindow();
} else {
if (m_UserInterface != nullptr) {
- m_UserInterface->setEnabled(false);
+ m_UserInterface->setWindowEnabled(false);
}
// re-enable the locked dialog because what'd be the point otherwise?
dialog->setEnabled(true);
@@ -738,7 +812,7 @@ void OrganizerCore::spawnBinary(const QFileInfo &binary, const QString &argument ::CloseHandle(processHandle);
if (m_UserInterface != nullptr) {
- m_UserInterface->setEnabled(true);
+ m_UserInterface->setWindowEnabled(true);
}
refreshDirectoryStructure();
// need to remove our stored load order because it may be outdated if a foreign tool changed the
@@ -807,16 +881,118 @@ HANDLE OrganizerCore::spawnBinaryDirect(const QFileInfo &binary, const QString & 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);
+ QFileInfo binary;
+ QString arguments = args.join(" ");
+ QString currentDirectory = cwd;
+ QString profileName = profile;
+ if (profile.length() == 0) {
+ if (m_CurrentProfile != nullptr) {
+ profileName = m_CurrentProfile->getName();
+ } else {
+ throw MyException(tr("No profile set"));
+ }
+ }
+ QString steamAppID;
+ if (executable.contains('\\') || executable.contains('/')) {
+ // file path
+
+ binary = QFileInfo(executable);
+ if (binary.isRelative()) {
+ // relative path, should be relative to game directory
+ binary = QFileInfo(QDir::fromNativeSeparators(ToQString(GameInfo::instance().getGameDirectory())) + "/" + executable);
+ }
+
+ std::vector<Executable>::iterator current, end;
+ m_ExecutablesList.getExecutables(current, end);
+ for (; current != end; ++current) {
+ if (current->m_BinaryInfo == binary) {
+ steamAppID = current->m_SteamAppID;
+ currentDirectory = current->m_WorkingDirectory;
+ }
+ }
+
+ if (cwd.length() == 0) {
+ currentDirectory = binary.absolutePath();
+ }
+ } else {
+ // only a file name, search executables list
+ try {
+ const Executable &exe = m_ExecutablesList.find(executable);
+ steamAppID = exe.m_SteamAppID;
+ if (arguments == "") {
+ arguments = exe.m_Arguments;
+ }
+ binary = exe.m_BinaryInfo;
+ if (cwd.length() == 0) {
+ currentDirectory = exe.m_WorkingDirectory;
+ }
+ } catch (const std::runtime_error&) {
+ qWarning("\"%s\" not set up as executable", executable.toUtf8().constData());
+ binary = QFileInfo(executable);
+ }
}
+
+ return spawnBinaryDirect(binary, arguments, profileName, currentDirectory, steamAppID);
}
-bool OrganizerCore::waitForApplication(HANDLE handle, LPDWORD exitCode) const
+bool OrganizerCore::waitForProcessOrJob(HANDLE handle, LPDWORD exitCode)
{
if (m_UserInterface != nullptr) {
- return m_UserInterface->waitForProcessOrJob(handle, exitCode);
+ m_UserInterface->lock();
+ ON_BLOCK_EXIT([&] () { m_UserInterface->unlock(); });
}
+
+ DWORD retLen;
+ JOBOBJECT_BASIC_PROCESS_ID_LIST info;
+
+ bool isJobHandle = true;
+
+ ULONG lastProcessID = ULONG_MAX;
+ HANDLE processHandle = handle;
+
+ DWORD res = ::MsgWaitForMultipleObjects(1, &handle, false, 500, QS_KEY | QS_MOUSE);
+ while ((res != WAIT_FAILED)
+ && (res != WAIT_OBJECT_0)
+ && ((m_UserInterface == nullptr) || !m_UserInterface->unlockClicked())) {
+ if (isJobHandle) {
+ if (::QueryInformationJobObject(handle, JobObjectBasicProcessIdList, &info, sizeof(info), &retLen) > 0) {
+ if (info.NumberOfProcessIdsInList == 0) {
+ // fake signaled state
+ res = WAIT_OBJECT_0;
+ break;
+ } else {
+ // this is indeed a job handle. Figure out one of the process handles as well.
+ if (lastProcessID != info.ProcessIdList[0]) {
+ lastProcessID = info.ProcessIdList[0];
+ if (processHandle != handle) {
+ ::CloseHandle(processHandle);
+ }
+ processHandle = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, lastProcessID);
+ }
+ }
+ } 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, &handle, false, 500, QS_KEY | QS_MOUSE);
+ }
+
+ if (exitCode != NULL) {
+ ::GetExitCodeProcess(processHandle, exitCode);
+ }
+ ::CloseHandle(processHandle);
+
+ return res == WAIT_OBJECT_0;
}
bool OrganizerCore::onAboutToRun(const std::function<bool (const QString &)> &func)
@@ -905,7 +1081,7 @@ void OrganizerCore::refreshBSAList() }
if (m_UserInterface != nullptr) {
- m_UserInterface->updateBSAList();
+ m_UserInterface->updateBSAList(m_DefaultArchives, m_ActiveArchives);
}
m_ArchivesInit = true;
@@ -922,7 +1098,6 @@ void OrganizerCore::refreshLists() 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);
@@ -977,7 +1152,7 @@ void OrganizerCore::updateModInDirectoryStructure(unsigned int index, ModInfo::P void OrganizerCore::requestDownload(const QUrl &url, QNetworkReply *reply)
{
if (m_PluginContainer != nullptr) {
- for (IPluginModPage *modPage : m_PluginContainer->plugins<IPluginModPage>()) {
+ for (IPluginModPage *modPage : m_PluginContainer->plugins<MOBase::IPluginModPage>()) {
ModRepositoryFileInfo *fileInfo = new ModRepositoryFileInfo();
if (modPage->handlesDownload(url, reply->url(), *fileInfo)) {
fileInfo->repository = modPage->name();
@@ -1167,7 +1342,7 @@ void OrganizerCore::loginFailedUpdate(const QString &message) std::vector<unsigned int> OrganizerCore::activeProblems() const
{
std::vector<unsigned int> problems;
- if (enabledCount() > 255) {
+ if (m_PluginList.enabledCount() > 255) {
problems.push_back(PROBLEM_TOOMANYPLUGINS);
}
return problems;
diff --git a/src/organizercore.h b/src/organizercore.h index b362a002..17b1d2dc 100644 --- a/src/organizercore.h +++ b/src/organizercore.h @@ -81,7 +81,7 @@ public: void setExecutablesDialog(const ExecutablesList &executablesList) { m_ExecutablesList = executablesList; }
Profile *currentProfile() { return m_CurrentProfile; }
- void setCurrentProfile(Profile *profile);
+ void setCurrentProfile(const QString &profileName);
void setExecutablesList(const ExecutablesList &executablesList);
@@ -95,7 +95,6 @@ public: bool isArchivesInit() const { return m_ArchivesInit; }
bool saveCurrentLists();
- void savePluginList();
void prepareStart();
@@ -105,50 +104,45 @@ public: void refreshDirectoryStructure();
void updateModInDirectoryStructure(unsigned int index, ModInfo::Ptr modInfo);
- void requestDownload(const QUrl &url, QNetworkReply *reply);
-
- void doAfterLogin(std::function<void()> &function) { m_PostLoginTasks.append(function); }
+ void doAfterLogin(std::function<void()> function) { m_PostLoginTasks.append(function); }
void spawnBinary(const QFileInfo &binary, const QString &arguments = "", const QDir ¤tDirectory = QDir(), bool closeAfterStart = true, const QString &steamAppID = "");
+ HANDLE spawnBinaryDirect(const QFileInfo &binary, const QString &arguments, const QString &profileName, const QDir ¤tDirectory, 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<QString> &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<bool (const QString &)> &filter) const;
- virtual QStringList getFileOrigins(const QString &fileName) const;
- virtual QList<MOBase::IOrganizer::FileInfo> findFileInfos(const QString &path, const std::function<bool (const MOBase::IOrganizer::FileInfo &)> &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<void (const QString &)> &func);
- virtual bool onAboutToRun(const std::function<bool (const QString &)> &func);
- virtual bool onFinishedRun(const std::function<void (const QString &, unsigned int)> &func);
- virtual void refreshModList(bool saveChanges = true);
+ MOBase::IGameInfo &gameInfo() const;
+ MOBase::IModRepositoryBridge *createNexusBridge() const;
+ QString profileName() const;
+ QString profilePath() const;
+ QString downloadsPath() const;
+ MOBase::VersionInfo appVersion() const;
+ MOBase::IModInterface *getMod(const QString &name);
+ MOBase::IModInterface *createMod(MOBase::GuessedValue<QString> &name);
+ bool removeMod(MOBase::IModInterface *mod);
+ void modDataChanged(MOBase::IModInterface *mod);
+ QVariant pluginSetting(const QString &pluginName, const QString &key) const;
+ void setPluginSetting(const QString &pluginName, const QString &key, const QVariant &value);
+ QVariant persistent(const QString &pluginName, const QString &key, const QVariant &def) const;
+ void setPersistent(const QString &pluginName, const QString &key, const QVariant &value, bool sync);
+ QString pluginDataPath() const;
+ MOBase::IModInterface *installMod(const QString &fileName);
+ QString resolvePath(const QString &fileName) const;
+ QStringList listDirectories(const QString &directoryName) const;
+ QStringList findFiles(const QString &path, const std::function<bool (const QString &)> &filter) const;
+ QStringList getFileOrigins(const QString &fileName) const;
+ QList<MOBase::IOrganizer::FileInfo> findFileInfos(const QString &path, const std::function<bool (const MOBase::IOrganizer::FileInfo &)> &filter) const;
+ DownloadManager *downloadManager();
+ PluginList *pluginList();
+ ModList *modList();
+ HANDLE startApplication(const QString &executable, const QStringList &args, const QString &cwd, const QString &profile);
+ bool waitForProcessOrJob(HANDLE processHandle, LPDWORD exitCode = nullptr);
+ bool onModInstalled(const std::function<void (const QString &)> &func);
+ bool onAboutToRun(const std::function<bool (const QString &)> &func);
+ bool onFinishedRun(const std::function<void (const QString &, unsigned int)> &func);
+ void refreshModList(bool saveChanges = true);
public: // IPluginDiagnose interface
@@ -163,15 +157,25 @@ public slots: void profileRefresh();
void externalMessage(const QString &message);
+ void savePluginList();
+
void refreshLists();
+ void installDownload(int downloadIndex);
+
+ void modStatusChanged(unsigned int index);
+ void requestDownload(const QUrl &url, QNetworkReply *reply);
+ void downloadRequestedNXM(const QString &url);
+
+ bool nexusLogin();
+
signals:
/**
* @brief emitted after a mod has been installed
* @node this is currently only used for tutorials
*/
- void modInstalled();
+ void modInstalled(const QString &modName);
private:
@@ -179,17 +183,16 @@ private: 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);
+ void downloadSpeed(const QString &serverName, int bytesPerSecond);
+ void loginSuccessful(bool necessary);
+ void loginFailed(const QString &message);
private:
diff --git a/src/organizerproxy.cpp b/src/organizerproxy.cpp index 07a006f5..61470a1a 100644 --- a/src/organizerproxy.cpp +++ b/src/organizerproxy.cpp @@ -95,7 +95,7 @@ HANDLE OrganizerProxy::startApplication(const QString &executable, const QString bool OrganizerProxy::waitForApplication(HANDLE handle, LPDWORD exitCode) const
{
- return m_Proxied->waitForApplication(handle, exitCode);
+ return m_Proxied->waitForProcessOrJob(handle, exitCode);
}
bool OrganizerProxy::onAboutToRun(const std::function<bool (const QString &)> &func)
diff --git a/src/plugincontainer.cpp b/src/plugincontainer.cpp index bd96828e..92073c12 100644 --- a/src/plugincontainer.cpp +++ b/src/plugincontainer.cpp @@ -1,11 +1,9 @@ #include "plugincontainer.h"
#include "organizerproxy.h"
#include "report.h"
-#include <gameinfo.h>
#include <ipluginproxy.h>
#include <idownloadmanager.h>
#include <appconfig.h>
-#include <gameinfo.h>
#include <QAction>
#include <QToolButton>
#include <QCoreApplication>
@@ -24,6 +22,7 @@ namespace bf = boost::fusion; PluginContainer::PluginContainer(OrganizerCore *organizer)
: m_Organizer(organizer)
+ , m_UserInterface(nullptr)
{
}
@@ -33,6 +32,17 @@ void PluginContainer::setUserInterface(IUserInterface *userInterface, QWidget *w for (IPluginProxy *proxy : bf::at_key<IPluginProxy>(m_Plugins)) {
proxy->setParentWidget(widget);
}
+
+ if (userInterface != nullptr) {
+ for (IPluginModPage *modPage : bf::at_key<IPluginModPage>(m_Plugins)) {
+ userInterface->registerModPage(modPage);
+ }
+
+ for (IPluginTool *tool : bf::at_key<IPluginTool>(m_Plugins)) {
+ userInterface->registerPluginTool(tool);
+ }
+ }
+
m_UserInterface = userInterface;
}
@@ -69,7 +79,7 @@ bool PluginContainer::registerPlugin(QObject *plugin, const QString &fileName) {
{ // generic treatment for all plugins
IPlugin *pluginObj = qobject_cast<IPlugin*>(plugin);
- if (pluginObj == NULL) {
+ if (pluginObj == nullptr) {
qDebug("not an IPlugin");
return false;
}
@@ -90,7 +100,6 @@ bool PluginContainer::registerPlugin(QObject *plugin, const QString &fileName) IPluginModPage *modPage = qobject_cast<IPluginModPage*>(plugin);
if (verifyPlugin(modPage)) {
bf::at_key<IPluginModPage>(m_Plugins).push_back(modPage);
- registerModPage(modPage);
return true;
}
}
@@ -106,7 +115,6 @@ bool PluginContainer::registerPlugin(QObject *plugin, const QString &fileName) IPluginTool *tool = qobject_cast<IPluginTool*>(plugin);
if (verifyPlugin(tool)) {
bf::at_key<IPluginTool>(m_Plugins).push_back(tool);
- registerPluginTool(tool);
return true;
}
}
@@ -240,7 +248,7 @@ void PluginContainer::loadPlugins() loadCheck.open(QIODevice::WriteOnly);
- QString pluginPath = QDir::fromNativeSeparators(ToQString(GameInfo::instance().getOrganizerDirectory())) + "/" + ToQString(AppConfig::pluginPath());
+ QString pluginPath = qApp->applicationDirPath() + "/" + ToQString(AppConfig::pluginPath());
qDebug("looking for plugins in %s", QDir::toNativeSeparators(pluginPath).toUtf8().constData());
QDirIterator iter(pluginPath, QDir::Files | QDir::NoDotAndDotDot);
diff --git a/src/plugincontainer.h b/src/plugincontainer.h index 213b4154..d0a101ad 100644 --- a/src/plugincontainer.h +++ b/src/plugincontainer.h @@ -15,6 +15,7 @@ #include <QFile>
#ifndef Q_MOC_RUN
#include <boost/fusion/container.hpp>
+#include <boost/fusion/include/at_key.hpp>
#endif // Q_MOC_RUN
#include <vector>
@@ -25,6 +26,21 @@ class PluginContainer : public QObject, public MOBase::IPluginDiagnose Q_OBJECT
Q_INTERFACES(MOBase::IPluginDiagnose)
+private:
+
+ typedef boost::fusion::map<
+ boost::fusion::pair<MOBase::IPlugin, std::vector<MOBase::IPlugin*>>,
+ boost::fusion::pair<MOBase::IPluginDiagnose, std::vector<MOBase::IPluginDiagnose*>>,
+ boost::fusion::pair<MOBase::IPluginGame, std::vector<MOBase::IPluginGame*>>,
+ boost::fusion::pair<MOBase::IPluginInstaller, std::vector<MOBase::IPluginInstaller*>>,
+ boost::fusion::pair<MOBase::IPluginModPage, std::vector<MOBase::IPluginModPage*>>,
+ boost::fusion::pair<MOBase::IPluginPreview, std::vector<MOBase::IPluginPreview*>>,
+ boost::fusion::pair<MOBase::IPluginTool, std::vector<MOBase::IPluginTool*>>,
+ boost::fusion::pair<MOBase::IPluginProxy, std::vector<MOBase::IPluginProxy*>>
+ > PluginMap;
+
+ static const unsigned int PROBLEM_PLUGINSNOTLOADED = 1;
+
public:
PluginContainer(OrganizerCore *organizer);
@@ -37,7 +53,7 @@ public: MOBase::IPluginGame *managedGame(const QString &name) const;
template <typename T>
- std::vector<T*> plugins() const {
+ std::vector<T*> plugins() {
return boost::fusion::at_key<T>(m_Plugins);
}
@@ -60,26 +76,10 @@ signals: 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<MOBase::IPlugin, std::vector<MOBase::IPlugin*>>,
- boost::fusion::pair<MOBase::IPluginDiagnose, std::vector<MOBase::IPluginDiagnose*>>,
- boost::fusion::pair<MOBase::IPluginGame, std::vector<MOBase::IPluginGame*>>,
- boost::fusion::pair<MOBase::IPluginInstaller, std::vector<MOBase::IPluginInstaller*>>,
- boost::fusion::pair<MOBase::IPluginModPage, std::vector<MOBase::IPluginModPage*>>,
- boost::fusion::pair<MOBase::IPluginPreview, std::vector<MOBase::IPluginPreview*>>,
- boost::fusion::pair<MOBase::IPluginTool, std::vector<MOBase::IPluginTool*>>,
- boost::fusion::pair<MOBase::IPluginProxy, std::vector<MOBase::IPluginProxy*>>
- > PluginMap;
-
- static const unsigned int PROBLEM_PLUGINSNOTLOADED = 1;
private:
@@ -99,4 +99,5 @@ private: QFile m_PluginsCheck;
};
+
#endif // PLUGINCONTAINER_H
diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp index b2d02cd2..2b1fcca1 100644 --- a/src/pluginlist.cpp +++ b/src/pluginlist.cpp @@ -166,7 +166,7 @@ void PluginList::refresh(const QString &profileName, const DirectoryEntry &baseD originName = modInfo->name();
}
- m_ESPs.push_back(ESPInfo(filename, forceEnabled, current->getFileTime(), originName, ToQString(current->getFullPath()), hasIni));
+ m_ESPs.push_back(ESPInfo(filename, forceEnabled, originName, ToQString(current->getFullPath()), hasIni));
} catch (const std::exception &e) {
reportError(tr("failed to update esp info for file %1 (source id: %2), error: %3").arg(filename).arg(current->getOrigin(archive)).arg(e.what()));
}
@@ -1168,7 +1168,7 @@ bool PluginList::eventFilter(QObject *obj, QEvent *event) }
-PluginList::ESPInfo::ESPInfo(const QString &name, bool enabled, FILETIME time,
+PluginList::ESPInfo::ESPInfo(const QString &name, bool enabled,
const QString &originName, const QString &fullPath,
bool hasIni)
: m_Name(name), m_FullPath(fullPath), m_Enabled(enabled), m_ForceEnabled(enabled),
diff --git a/src/pluginlist.h b/src/pluginlist.h index 729c6f8b..933a38ee 100644 --- a/src/pluginlist.h +++ b/src/pluginlist.h @@ -272,7 +272,7 @@ private: struct ESPInfo {
- ESPInfo(const QString &name, bool enabled, FILETIME time, const QString &originName, const QString &fullPath, bool hasIni);
+ ESPInfo(const QString &name, bool enabled, const QString &originName, const QString &fullPath, bool hasIni);
QString m_Name;
QString m_FullPath;
bool m_Enabled;
diff --git a/src/profile.cpp b/src/profile.cpp index 6e9d8f0f..37ed94cc 100644 --- a/src/profile.cpp +++ b/src/profile.cpp @@ -59,7 +59,8 @@ Profile::Profile(const QString &name, bool useDefaultSettings) : m_SaveTimer(NULL) { initTimer(); - QString profilesDir = QDir::fromNativeSeparators(ToQString(GameInfo::instance().getProfilesDir())); + QString profilesDir = qApp->property("datapath").toString() + "/" + ToQString(AppConfig::profilesPath()); +qDebug("pd %s", qPrintable(profilesDir)); QDir profileBase(profilesDir); QString fixedName = name; @@ -78,6 +79,7 @@ Profile::Profile(const QString &name, bool useDefaultSettings) touchFile("modlist.txt"); touchFile("archives.txt"); +qDebug("fp %s", qPrintable(fullPath)); GameInfo::instance().createProfile(ToWString(fullPath), useDefaultSettings); } catch (...) { // clean up in case of an error @@ -88,8 +90,8 @@ Profile::Profile(const QString &name, bool useDefaultSettings) } -Profile::Profile(const QDir& directory) - : m_Directory(directory), m_SaveTimer(NULL) +Profile::Profile(const QDir &directory) + : m_Directory(directory), m_SaveTimer(nullptr) { initTimer(); if (!QFile::exists(m_Directory.filePath("modlist.txt"))) { diff --git a/src/selfupdater.cpp b/src/selfupdater.cpp index 803b2cfa..0f75e392 100644 --- a/src/selfupdater.cpp +++ b/src/selfupdater.cpp @@ -56,8 +56,12 @@ template <typename T> T resolveFunction(QLibrary &lib, const char *name) SelfUpdater::SelfUpdater(NexusInterface *nexusInterface)
- : m_Parent(nullptr), m_Interface(nexusInterface), m_UpdateRequestID(-1),
- m_Reply(NULL), m_Progress(nullptr), m_Attempts(3)
+ : m_Parent(nullptr)
+ , m_Interface(nexusInterface)
+ , m_UpdateRequestID(-1)
+ , m_Reply(nullptr)
+ , m_Progress(nullptr)
+ , m_Attempts(3)
{
m_Progress.setMaximum(100);
@@ -90,7 +94,7 @@ SelfUpdater::~SelfUpdater() void SelfUpdater::setUserInterface(QWidget *widget)
{
- m_Progress.setParent(widget);
+ m_Progress.setVisible(false);
m_Parent = widget;
}
@@ -130,6 +134,16 @@ void SelfUpdater::startUpdate() }
+void SelfUpdater::showProgress()
+{
+ m_Progress.setModal(true);
+ m_Progress.setParent(m_Parent, Qt::Dialog);
+ m_Progress.show();
+ m_Progress.setValue(0);
+ m_Progress.setWindowTitle(tr("Update"));
+ m_Progress.setLabelText(tr("Download in progress"));
+}
+
void SelfUpdater::download(const QString &downloadLink, const QString &fileName)
{
QNetworkAccessManager *accessManager = m_Interface->getAccessManager();
@@ -139,11 +153,7 @@ void SelfUpdater::download(const QString &downloadLink, const QString &fileName) m_Reply = accessManager->get(request);
m_UpdateFile.setFileName(QDir::fromNativeSeparators(ToQString(GameInfo::instance().getOrganizerDirectory()).append("\\").append(fileName)));
m_UpdateFile.open(QIODevice::WriteOnly);
- m_Progress.setModal(true);
- m_Progress.show();
- m_Progress.setValue(0);
- m_Progress.setWindowTitle(tr("Update"));
- m_Progress.setLabelText(tr("Download in progress"));
+ showProgress();
connect(m_Reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(downloadProgress(qint64, qint64)));
connect(m_Reply, SIGNAL(finished()), this, SLOT(downloadFinished()));
diff --git a/src/selfupdater.h b/src/selfupdater.h index 3490b58a..c376234a 100644 --- a/src/selfupdater.h +++ b/src/selfupdater.h @@ -119,6 +119,7 @@ private: void updateProgressFile(LPCWSTR fileName);
void report7ZipError(LPCWSTR errorMessage);
QString retrieveNews(const QString &description);
+ void showProgress();
private slots:
diff --git a/src/settings.cpp b/src/settings.cpp index 274e5979..418c5661 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -57,13 +57,13 @@ private: static const unsigned char Key2[20] = { 0x99, 0xb8, 0x76, 0x42, 0x3e, 0xc1, 0x60, 0xa4, 0x5b, 0x01, 0xdb, 0xf8, 0x43, 0x3a, 0xb7, 0xb6, 0x98, 0xd4, 0x7d, 0xa2 }; -Settings *Settings::s_Instance = NULL; +Settings *Settings::s_Instance = nullptr; -Settings::Settings() - : m_Settings(ToQString(GameInfo::instance().getIniFilename()), QSettings::IniFormat) +Settings::Settings(const QSettings &config) + : m_Settings(config.fileName(), config.format()) { - if (s_Instance != NULL) { + if (s_Instance != nullptr) { throw std::runtime_error("second instance of \"Settings\" created"); } else { s_Instance = this; @@ -73,13 +73,13 @@ Settings::Settings() Settings::~Settings() { - s_Instance = NULL; + s_Instance = nullptr; } Settings &Settings::instance() { - if (s_Instance == NULL) { + if (s_Instance == nullptr) { throw std::runtime_error("no instance of \"Settings\""); } return *s_Instance; @@ -110,9 +110,9 @@ void Settings::registerAsNXMHandler(bool force) std::wstring executable = ToWString(QCoreApplication::applicationFilePath()); std::wstring mode = force ? L"forcereg" : L"reg"; std::wstring parameters = mode + L" " + GameInfo::instance().getGameShortName() + L" \"" + executable + L"\""; - HINSTANCE res = ::ShellExecuteW(NULL, L"open", nxmPath.c_str(), parameters.c_str(), NULL, SW_SHOWNORMAL); + HINSTANCE res = ::ShellExecuteW(nullptr, L"open", nxmPath.c_str(), parameters.c_str(), nullptr, SW_SHOWNORMAL); if ((int)res <= 32) { - QMessageBox::critical(NULL, tr("Failed"), + QMessageBox::critical(nullptr, tr("Failed"), tr("Sorry, failed to start the helper application")); } } @@ -181,10 +181,9 @@ QString Settings::getSteamAppID() const QString Settings::getDownloadDirectory() const { - return QDir::toNativeSeparators(m_Settings.value("Settings/download_directory", ToQString(GameInfo::instance().getDownloadDir())).toString()); + return QDir::toNativeSeparators(m_Settings.value("Settings/download_directory", qApp->applicationDirPath() + "/downloads").toString()); } - void Settings::setDownloadSpeed(const QString &serverName, int bytesPerSecond) { m_Settings.beginGroup("Servers"); @@ -221,12 +220,14 @@ std::map<QString, int> Settings::getPreferredServers() QString Settings::getCacheDirectory() const { - return QDir::toNativeSeparators(m_Settings.value("Settings/cache_directory", ToQString(GameInfo::instance().getCacheDir())).toString()); + return QDir::toNativeSeparators(m_Settings.value("Settings/cache_directory", + qApp->applicationDirPath() + "/webcache").toString()); } QString Settings::getModDirectory() const { - return QDir::toNativeSeparators(m_Settings.value("Settings/mod_directory", ToQString(GameInfo::instance().getModsDir())).toString()); + return QDir::toNativeSeparators(m_Settings.value("Settings/mod_directory", + qApp->applicationDirPath() + "/mods").toString()); } QString Settings::getNMMVersion() const @@ -647,7 +648,7 @@ void Settings::query(QWidget *parent) { // advanced settings if ((QDir::fromNativeSeparators(modDirEdit->text()) != QDir::fromNativeSeparators(getModDirectory())) && - (QMessageBox::question(NULL, tr("Confirm"), tr("Changing the mod directory affects all your profiles! " + (QMessageBox::question(nullptr, tr("Confirm"), tr("Changing the mod directory affects all your profiles! " "Mods not present (or named differently) in the new location will be disabled in all profiles. " "There is no way to undo this unless you backed up your profiles manually. Proceed?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)) { diff --git a/src/settings.h b/src/settings.h index 5d398f49..cba8392e 100644 --- a/src/settings.h +++ b/src/settings.h @@ -43,7 +43,7 @@ public: /** * @brief constructor **/ - Settings(); + Settings(const QSettings &config); virtual ~Settings(); diff --git a/src/shared/appconfig.inc b/src/shared/appconfig.inc index 080d3655..5d9d9f8e 100644 --- a/src/shared/appconfig.inc +++ b/src/shared/appconfig.inc @@ -1,5 +1,6 @@ APPPARAM(std::wstring, translationPrefix, L"organizer")
APPPARAM(std::wstring, pluginPath, L"plugins")
+APPPARAM(std::wstring, profilesPath, L"profiles")
APPPARAM(std::wstring, stylesheetsPath, L"stylesheets")
APPPARAM(std::wstring, profileTweakIni, L"profile_tweaks.ini")
APPPARAM(std::wstring, logFile, L"ModOrganizer.log")
diff --git a/src/shared/gameinfo.cpp b/src/shared/gameinfo.cpp index 5439efff..1a815701 100644 --- a/src/shared/gameinfo.cpp +++ b/src/shared/gameinfo.cpp @@ -27,12 +27,12 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include "skyriminfo.h"
#include "util.h"
+#include <boost/assign.hpp>
+#include <boost/format.hpp>
#include <shlobj.h>
#include <sstream>
#include <cassert>
-#include <boost/assign.hpp>
-#include <boost/format.hpp>
namespace MOShared {
@@ -49,7 +49,7 @@ GameInfo::GameInfo(const std::wstring &moDirectory, const std::wstring &moDataDi void GameInfo::cleanup() {
delete GameInfo::s_Instance;
- GameInfo::s_Instance = NULL;
+ GameInfo::s_Instance = nullptr;
}
@@ -126,7 +126,7 @@ bool GameInfo::init(const std::wstring &moDirectory, const std::wstring &moDataD GameInfo &GameInfo::instance()
{
- assert(s_Instance != NULL);
+ assert(s_Instance != nullptr && "gameinfo not yet initialized");
return *s_Instance;
}
@@ -151,18 +151,6 @@ std::wstring GameInfo::getIniFilename() const }
-std::wstring GameInfo::getDownloadDir() const
-{
- return m_OrganizerDirectory + L"\\downloads";
-}
-
-
-std::wstring GameInfo::getCacheDir() const
-{
- return m_OrganizerDirectory + L"\\webcache";
-}
-
-
std::wstring GameInfo::getOverwriteDir() const
{
return m_OrganizerDirectory + L"\\overwrite";
diff --git a/src/shared/gameinfo.h b/src/shared/gameinfo.h index c11679f3..a9da0b97 100644 --- a/src/shared/gameinfo.h +++ b/src/shared/gameinfo.h @@ -109,8 +109,6 @@ public: virtual std::wstring getProfilesDir() const;
virtual std::wstring getIniFilename() const;
- virtual std::wstring getDownloadDir() const;
- virtual std::wstring getCacheDir() const;
virtual std::wstring getOverwriteDir() const;
virtual std::wstring getLogDir() const;
virtual std::wstring getLootDir() const;
diff --git a/src/shared/skyriminfo.cpp b/src/shared/skyriminfo.cpp index 1203e3ed..7f70c097 100644 --- a/src/shared/skyriminfo.cpp +++ b/src/shared/skyriminfo.cpp @@ -259,7 +259,7 @@ void SkyrimInfo::createProfile(const std::wstring &directory, bool useDefaults) }
if (!::CopyFileW(source.c_str(), target.c_str(), true)) {
if (::GetLastError() != ERROR_FILE_EXISTS) {
- throw windows_error(std::string("failed to copy ini file: ") + ToString(source, false));
+ throw windows_error(std::string("failed to copy ini file: ") + ToString(source, false) + " to " + ToString(target, false));
}
}
}
|
