summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEran Mizrahi <erasmux@gmail.com>2017-12-19 00:44:18 +0200
committerEran Mizrahi <erasmux@gmail.com>2017-12-19 15:44:27 +0200
commitcb1c9f5e83e98039d38f548c80d4b95442163cf2 (patch)
treeeba934e34a24a9484ab076065f9e98aefca16425
parent7dad8bcb282ac385267087961b29af608f81593d (diff)
Tie moshortcuts to a specific instance
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/executableslist.cpp2
-rw-r--r--src/instancemanager.cpp17
-rw-r--r--src/instancemanager.h8
-rw-r--r--src/main.cpp16
-rw-r--r--src/mainwindow.cpp3
-rw-r--r--src/moshortcut.cpp39
-rw-r--r--src/moshortcut.h46
-rw-r--r--src/organizercore.cpp15
-rw-r--r--src/organizercore.h6
10 files changed, 134 insertions, 20 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 914bdd12..0c70fe57 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -88,6 +88,7 @@ SET(organizer_SRCS
instancemanager.cpp
usvfsconnector.cpp
eventfilter.cpp
+ moshortcut.cpp
shared/windows_error.cpp
shared/error_report.cpp
@@ -179,6 +180,7 @@ SET(organizer_HDRS
usvfsconnector.h
eventfilter.h
descriptionpage.h
+ moshortcut.h
shared/windows_error.h
shared/error_report.h
diff --git a/src/executableslist.cpp b/src/executableslist.cpp
index b1890ac9..21cb6ed4 100644
--- a/src/executableslist.cpp
+++ b/src/executableslist.cpp
@@ -86,7 +86,7 @@ Executable &ExecutablesList::find(const QString &title)
return exe;
}
}
- throw std::runtime_error(QString("invalid name %1").arg(title).toLocal8Bit().constData());
+ throw std::runtime_error(QString("invalid executable name %1").arg(title).toLocal8Bit().constData());
}
diff --git a/src/instancemanager.cpp b/src/instancemanager.cpp
index b1b85cc6..34e23d7b 100644
--- a/src/instancemanager.cpp
+++ b/src/instancemanager.cpp
@@ -47,9 +47,19 @@ InstanceManager &InstanceManager::instance()
return s_Instance;
}
+void InstanceManager::overrideInstance(const QString& instanceName)
+{
+ m_overrideInstanceName = instanceName;
+ m_overrideInstance = true;
+}
+
+
QString InstanceManager::currentInstance() const
{
- return m_AppSettings.value(INSTANCE_KEY, "").toString();
+ if (m_overrideInstance)
+ return m_overrideInstanceName;
+ else
+ return m_AppSettings.value(INSTANCE_KEY, "").toString();
}
void InstanceManager::clearCurrentInstance()
@@ -177,7 +187,8 @@ void InstanceManager::createDataPath(const QString &dataPath) const
QString InstanceManager::determineDataPath()
{
QString instanceId = currentInstance();
- if (instanceId.isEmpty() && portableInstall() && !m_Reset) {
+ if (instanceId.isEmpty() && !m_Reset && (m_overrideInstance || portableInstall()))
+ {
// startup, apparently using portable mode before
return qApp->applicationDirPath();
}
@@ -187,7 +198,7 @@ QString InstanceManager::determineDataPath()
+ "/" + instanceId);
- if (instanceId.isEmpty() || !QFileInfo::exists(dataPath)) {
+ if (!m_overrideInstance && (instanceId.isEmpty() || !QFileInfo::exists(dataPath))) {
instanceId = chooseInstance(instances());
setCurrentInstance(instanceId);
if (!instanceId.isEmpty()) {
diff --git a/src/instancemanager.h b/src/instancemanager.h
index a0a5df09..2782c71d 100644
--- a/src/instancemanager.h
+++ b/src/instancemanager.h
@@ -34,11 +34,14 @@ public:
QString determineDataPath();
void clearCurrentInstance();
+ void overrideInstance(const QString& instanceName);
+
+ QString currentInstance() const;
+
private:
InstanceManager();
- QString currentInstance() const;
QString instancePath() const;
QStringList instances() const;
@@ -55,5 +58,6 @@ private:
QSettings m_AppSettings;
bool m_Reset {false};
-
+ bool m_overrideInstance{false};
+ QString m_overrideInstanceName;
};
diff --git a/src/main.cpp b/src/main.cpp
index 4cf47a3c..3d315f1d 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -45,6 +45,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "tutorialmanager.h"
#include "nxmaccessmanager.h"
#include "instancemanager.h"
+#include "moshortcut.h"
#include <eh.h>
#include <windows_error.h>
@@ -450,9 +451,9 @@ int runApplication(MOApplication &application, SingleInstance &instance,
// if we have a command line parameter, it is either a nxm link or
// a binary to start
if (arguments.size() > 1) {
- if (OrganizerCore::isMoShortcut(arguments.at(1))) {
+ if (MOShortcut shortcut{ arguments.at(1) }) {
try {
- organizer.runShortcut(OrganizerCore::moShortcutName(arguments.at(1)));
+ organizer.runShortcut(shortcut);
return 0;
} catch (const std::exception &e) {
reportError(
@@ -552,10 +553,12 @@ int main(int argc, char *argv[])
forcePrimary = true;
}
+ MOShortcut moshortcut{ arguments.size() > 1 ? arguments.at(1) : "" };
+
SingleInstance instance(forcePrimary);
if (!instance.primaryInstance()) {
- if ((arguments.size() == 2)
- && (OrganizerCore::isMoShortcut(arguments.at(1)) || OrganizerCore::isNxmLink(arguments.at(1))))
+ if (moshortcut ||
+ arguments.size() > 1 && OrganizerCore::isNxmLink(arguments.at(1)))
{
qDebug("not primary instance, sending shortcut/download message");
instance.sendMessage(arguments.at(1));
@@ -572,7 +575,10 @@ int main(int argc, char *argv[])
QString dataPath;
try {
- dataPath = InstanceManager::instance().determineDataPath();
+ InstanceManager& instanceManager = InstanceManager::instance();
+ if (moshortcut && moshortcut.hasInstance())
+ instanceManager.overrideInstance(moshortcut.instance());
+ dataPath = instanceManager.determineDataPath();
} catch (const std::exception &e) {
if (strcmp(e.what(),"Canceled"))
QMessageBox::critical(nullptr, QObject::tr("Failed to set up instance"), e.what());
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 6f156269..1c5e321d 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -3331,7 +3331,8 @@ void MainWindow::addWindowsLink(const ShortcutType mapping)
QString executable = QDir::toNativeSeparators(selectedExecutable.m_BinaryInfo.absoluteFilePath());
std::wstring targetFile = ToWString(exeInfo.absoluteFilePath());
- std::wstring parameter = ToWString(QString("\"moshortcut://%1\"").arg(selectedExecutable.m_Title));
+ std::wstring parameter = ToWString(
+ QString("\"moshortcut://%1:%2\"").arg(InstanceManager::instance().currentInstance(),selectedExecutable.m_Title));
std::wstring description = ToWString(QString("Run %1 with ModOrganizer").arg(selectedExecutable.m_Title));
std::wstring iconFile = ToWString(executable);
std::wstring currentDirectory = ToWString(QDir::toNativeSeparators(qApp->applicationDirPath()));
diff --git a/src/moshortcut.cpp b/src/moshortcut.cpp
new file mode 100644
index 00000000..c8c2ef6f
--- /dev/null
+++ b/src/moshortcut.cpp
@@ -0,0 +1,39 @@
+/*
+Copyright (C) 2016 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 <http://www.gnu.org/licenses/>.
+*/
+
+
+#include "moshortcut.h"
+
+
+MOShortcut::MOShortcut(const QString& link)
+ : m_valid(link.startsWith("moshortcut://"))
+ , m_hasInstance(false)
+{
+ if (m_valid) {
+ int start = (int)strlen("moshortcut://");
+ int sep = link.indexOf(':', start);
+ if (sep >= 0) {
+ m_hasInstance = true;
+ m_instance = link.mid(start, sep - start);
+ m_executable = link.mid(sep + 1);
+ }
+ else
+ m_executable = link.mid(start);
+ }
+}
diff --git a/src/moshortcut.h b/src/moshortcut.h
new file mode 100644
index 00000000..7b7574b9
--- /dev/null
+++ b/src/moshortcut.h
@@ -0,0 +1,46 @@
+/*
+Copyright (C) 2016 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 <http://www.gnu.org/licenses/>.
+*/
+
+
+#pragma once
+
+
+#include <QString>
+
+
+class MOShortcut {
+
+public:
+ MOShortcut(const QString& link);
+
+ /// true iff intialized using a valid moshortcut link
+ operator bool() const { return m_valid; }
+
+ bool hasInstance() const { return m_hasInstance; }
+
+ const QString& instance() const { return m_instance; }
+
+ const QString& executable() const { return m_executable; }
+
+private:
+ QString m_instance;
+ QString m_executable;
+ bool m_valid;
+ bool m_hasInstance;
+};
diff --git a/src/organizercore.cpp b/src/organizercore.cpp
index 3be9559a..7668485c 100644
--- a/src/organizercore.cpp
+++ b/src/organizercore.cpp
@@ -32,6 +32,7 @@
#include <report.h>
#include <questionboxmemory.h>
#include "lockeddialog.h"
+#include "instancemanager.h"
#include <QApplication>
#include <QCoreApplication>
@@ -578,8 +579,8 @@ void OrganizerCore::downloadRequestedNXM(const QString &url)
void OrganizerCore::externalMessage(const QString &message)
{
- if (isMoShortcut(message)) {
- runShortcut(moShortcutName(message));
+ if (MOShortcut moshortcut{ message }) {
+ runShortcut(moshortcut);
}
else if (isNxmLink(message)) {
MessageDialog::showMessage(tr("Download started"), qApp->activeWindow());
@@ -1228,9 +1229,15 @@ HANDLE OrganizerCore::spawnBinaryProcess(const QFileInfo &binary,
}
}
-HANDLE OrganizerCore::runShortcut(const QString &title)
+HANDLE OrganizerCore::runShortcut(const MOShortcut& shortcut)
{
- Executable& exe = m_ExecutablesList.find(title);
+ if (shortcut.hasInstance() && shortcut.instance() != InstanceManager::instance().currentInstance())
+ throw std::runtime_error(
+ QString("Refusing to run executable from different instance %1:%2")
+ .arg(shortcut.instance(),shortcut.executable())
+ .toLocal8Bit().constData());
+
+ Executable& exe = m_ExecutablesList.find(shortcut.executable());
return spawnBinaryDirect(
exe.m_BinaryInfo, exe.m_Arguments,
diff --git a/src/organizercore.h b/src/organizercore.h
index decb3d01..f98e9d0a 100644
--- a/src/organizercore.h
+++ b/src/organizercore.h
@@ -13,6 +13,7 @@
#include "downloadmanager.h"
#include "executableslist.h"
#include "usvfsconnector.h"
+#include "moshortcut.h"
#include <directoryentry.h>
#include <imoinfo.h>
#include <iplugindiagnose.h>
@@ -86,9 +87,6 @@ private:
public:
static bool isNxmLink(const QString &link) { return link.startsWith("nxm://", Qt::CaseInsensitive); }
- static bool isMoShortcut(const QString &link) { return link.startsWith("moshortcut://", Qt::CaseInsensitive); }
- static QString moShortcutName(const QString &link) { return link.mid(strlen("moshortcut://")); }
-
OrganizerCore(const QSettings &initSettings);
@@ -203,7 +201,7 @@ public:
DownloadManager *downloadManager();
PluginList *pluginList();
ModList *modList();
- HANDLE runShortcut(const QString &title);
+ HANDLE runShortcut(const MOShortcut& shortcut);
HANDLE startApplication(const QString &executable, const QStringList &args, const QString &cwd, const QString &profile);
bool waitForApplication(HANDLE processHandle, LPDWORD exitCode = nullptr);
HANDLE findAndOpenAUSVFSProcess();