Compare commits

...
Author SHA1 Message Date
Tannin b33293e49a - bugfix: elevation dialog didn't offer a "yes" option
- bugfix: python plugins crashed the application when trying to create a nexus bridge
- bugfix: python plugins couldn't register for failed requests correctly
2014-01-29 21:06:55 +01:00
Tannin dc3b60e578 - bugfix: accessing profile without loading one when starting an app through the commandline
- bugfix: locked-dialog was disabled
2014-01-27 21:31:10 +01:00
Tannin d591bc017a Merge with default 2013-12-07 16:55:19 +01:00
Tannin aad5864192 minor text changes 2013-12-07 14:23:51 +01:00
Tannin 7deee938d3 - bugfix: installFile for mods was not a relative path if the downloads directory was non-default
- bugfix: crash after removing the last profile in the list (ordered alphabetically)
- improved subdirs ordering to ensure pythonrunner is compiled before pythonproxy
- translation files for plugins are now generated
- set some texts as un-translatable where it made no sense
- staging script now re-builds MO completely before packaging
- updated qt libraries for packaging to 4.8.5
- added python to the package
2013-11-22 17:45:34 +01:00
Tannin 5d51b2bcc6 added some files missing from the previous commit 2013-11-18 22:03:23 +01:00
Tannin 0566a968e8 - archive.dll now supports querying the crc value of files
- esptk now determines if a esp is a dummy (without records)
- hook.dll no longer creates a log file if noone wrote to it
- nexus id and installtime columns are now hidden by default
- modlist can now be refreshed without saving first (so plugins can replace the modlist.txt as a whole)
- plugins can now query more details about virtualised files
- added style options "plastique" and "cleanlooks"
- "overwrite" is no longer listed with a creation time
- a warning will now be displayed if the user has too many plugins active
- a warning will now be displayed if mods with scripts have an installation order that doesn't match the corresponding esp load order
- nmm importer now has select all/deselect all buttons
- nmm importer no longer tries to unpack missing files from archives (won't work anyway)
- initial support for importing from nmm 0.5 alpha
- removed some broken warning suppresions
- python runner now works with bundled python
- extended qbs build system (still fails to build the main gui application)
- implemented a nsis-based installer
2013-11-18 20:17:14 +01:00
Tannin 14fc674d72 - diagnosis plugins can now request to be re-evaluated
- main application now contains means for plugins to react on some changes (to be extended)
- plugins can now retrieve more information about a mod
- user-agent sent to nexus now automatically contains the current MO version
- included updated russian translation
- problems dialog now refreshes itself after a fix was applied
- fixed new esp/asset ordering diagnosis. May be fully functional now
- bugfix: restoring locked load order could leave MO in an endless loop (not sure if this fix is correct yet)
- bugfix: plugin list was not visually updated after some changes
- bugfix: nmm importer threw away mod ordering
2013-11-06 18:35:27 +01:00
Tannin b7cbdaad1e - added a new diagnosis to detect potential problems in regards to esp vs. asset ordering (not fully functional yet)
- new plugin interfaces to the mod list
- plugins can now query the origin (mod) of a esp/esm
- bugfix: potential access to profile before one was activated
- bugfix: regression in previous (not-yet-released) commit prevented changes to bsa list from being saved
2013-11-01 14:59:25 +01:00
Tannin 25cdcdd2fe - plugin (esp/esm) list is now exposed to plugins (read-only functionality right now)
- integrated fomod installer now supports file dependencies
- bugfix: integrated fomod installer crashed if the installer had no optiosn´´ns
2013-10-16 23:04:03 +02:00
Tannin f06a6d4e55 - added new plugin to test if fnis needs to be run
- some functionality to the plugin interface to enable them to search for files&directories in the virtual FS (rudimentary atm)
- functionality for plugins to react to application being started from MO
- broken ESPs are no longer reported as popup windows but only in the log file
- bugfix: plugins couldn't store persistent data if they had no user-editable settings
2013-10-11 23:03:49 +02:00
Tannin ceab36e5f0 - download progress is now visible in task bar
- esp-tooltip now lists all masters, highlighting the missing ones
- python plugin will now report a problem if the path contains a semicolon
- leak detection now (somewaht) works around the fact that we don't always get a stack trace
- bugfix: mod meta-file is now reliably created if it was missing
- bugfix: parser for nxm-links didn't handle numbers in the mod name
- bugfix: small memory leak
2013-09-28 21:13:57 +02:00
Tannin e158038cfc - esp reader now handles invalid files more gracefully
- files moved will now also be treated as "deleted" in the old location so a newly created file with that same name is not created in overwrite
- introduced a mechanism by which MO can recognize if it crashed before when attempting to load a plugin. That plugin can be blacklisted so it doesn't get loaded again
- plugins can now programaticaly change their settings
- plugins can now store data persistently without exposing that data as settings
- requesting an unset-setting from a plugin is no longer treated as a bug
- clarified warning message for when files are in overwrite directory
- the proxyPython plugin will now discover if python initialization crashed MO on a previous session and give the user a chance to fix it or disable the plugin
- bugfix: GetModuleFileName modified the buffer past the zero termination. While this doesn't violate the API documentation it is different from the regular windows implementation
- bugfix: proxy plugins couldn't access the parent widget
- bugfix: when moving a file from overwrite to a mod the in-memory file structure wasn't updated
- bugfix: name input dialog for profiles allowed names that weren't valid directory names
- bugfix: profile dialog wasn't able to delete profiles if the name started or ended in whitespaces
- bugfix: The name-cells for plugin settings could be changed (without effect)
- removed a few obsolete files from the repository
2013-09-21 19:25:33 +02:00
9 changed files with 188 additions and 64 deletions
+7 -5
View File
@@ -22,6 +22,9 @@ CONFIG(release, debug|release) {
DEFINES += PROXYPYTHON_LIBRARY
# suppress a few warnings caused by boost vs vc++ paranoia
DEFINES += _SCL_SECURE_NO_WARNINGS
SOURCES += proxypython.cpp
HEADERS += proxypython.h \
resource.h
@@ -35,15 +38,14 @@ RC_FILE += \
include(../plugin_template.pri)
INCLUDEPATH += "../../pythonRunner"
INCLUDEPATH += "../../pythonRunner" "$(BOOSTPATH)"
WINPWD = $$PWD
WINPWD ~= s,/,$$QMAKE_DIR_SEP,g
//QMAKE_POST_LINK += SET VS90COMNTOOLS=%VS100COMNTOOLS% $$escape_expand(\\n)
QMAKE_POST_LINK += copy $$(PYTHONPATH)\\lib\\site-packages\\sip.pyd $$quote($$DSTDIR)\\plugins\\data\\ $$escape_expand(\\n)
QMAKE_POST_LINK += copy $$(PYTHONPATH)\\lib\\site-packages\\PyQt4\\QtCore.pyd $$quote($$DSTDIR)\\plugins\\data\\PyQt4\\ $$escape_expand(\\n)
QMAKE_POST_LINK += copy $$(PYTHONPATH)\\lib\\site-packages\\PyQt4\\QtGui.pyd $$quote($$DSTDIR)\\plugins\\data\\PyQt4\\ $$escape_expand(\\n)
//QMAKE_POST_LINK += copy $$(PYTHONPATH)\\lib\\site-packages\\sip.pyd $$quote($$DSTDIR)\\plugins\\data\\ $$escape_expand(\\n)
//QMAKE_POST_LINK += copy $$(PYTHONPATH)\\lib\\site-packages\\PyQt4\\QtCore.pyd $$quote($$DSTDIR)\\plugins\\data\\PyQt4\\ $$escape_expand(\\n)
//QMAKE_POST_LINK += copy $$(PYTHONPATH)\\lib\\site-packages\\PyQt4\\QtGui.pyd $$quote($$DSTDIR)\\plugins\\data\\PyQt4\\ $$escape_expand(\\n)
+80 -15
View File
@@ -1,16 +1,31 @@
#pragma warning( push )
#pragma warning( disable : 4100 ) // a lot of unreferenced formal parameters from boost libraries
#pragma warning( disable : 4996 ) // strncpy claimed to be unsafe
/*
Copyright (C) 2013 Sebastian Herbord. All rights reserved.
This file is part of python proxy plugin for MO
python proxy plugin 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.
Python proxy plugin 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 python proxy plugin. If not, see <http://www.gnu.org/licenses/>.
*/
#include "proxypython.h"
#pragma warning( pop )
#include <utility.h>
#include <versioninfo.h>
#include <QtPlugin>
#include <QDirIterator>
#include <QWidget>
#include <QMessageBox>
#include <QCoreApplication>
#include "resource.h"
@@ -32,8 +47,6 @@ HMODULE GetOwnModuleHandle()
QString ExtractResource(WORD resourceID, const QString &szFilename)
{
bool success = false;
HMODULE mod = GetOwnModuleHandle();
HRSRC hResource = FindResourceW(mod, MAKEINTRESOURCE(resourceID), L"BINARY");
@@ -85,8 +98,16 @@ typedef IPythonRunner* (*CreatePythonRunner_func)(const MOBase::IOrganizer *moIn
bool ProxyPython::init(IOrganizer *moInfo)
{
m_MOInfo = moInfo;
if (!m_MOInfo->pluginSetting(name(), "enabled").toBool()) {
m_LoadFailure = FAIL_NONE;
return false;
}
m_LoadFailure = FAIL_OTHER;
if (QCoreApplication::applicationDirPath().contains(';')) {
m_LoadFailure = FAIL_SEMICOLON;
return true;
}
QString pythonPath = m_MOInfo->pluginSetting(name(), "python_dir").toString();
@@ -95,7 +116,6 @@ bool ProxyPython::init(IOrganizer *moInfo)
return true;
}
m_TempRunnerFile = ExtractResource(IDR_LOADER_DLL, "__pythonRunner.dll");
m_RunnerLib = ::LoadLibraryW(ToWString(m_TempRunnerFile).c_str());
if (m_RunnerLib != NULL) {
@@ -103,7 +123,28 @@ bool ProxyPython::init(IOrganizer *moInfo)
if (CreatePythonRunner == NULL) {
throw MyException("embedded dll is invalid: " + windowsErrorString(::GetLastError()));
}
if (m_MOInfo->persistent(name(), "tryInit", false).toBool()) {
if (pythonPath.isEmpty()) {
m_LoadFailure = FAIL_PYTHONDETECTION;
} else {
m_LoadFailure = FAIL_WRONGPYTHONPATH;
}
if (QMessageBox::question(parentWidget(), tr("Python Initialization failed"),
tr("On a previous start the Python Plugin failed to initialize.\n"
"Either the value in Settings->Plugins->ProxyPython->plugin_dir is set incorrectly or it is empty and auto-detection doesn't work "
"for whatever reason.\n"
"Do you want to try initializing python again (at the risk of another crash)?\n"
"Suggestion: Select \"no\", and click the warning sign for further help. Afterwards you have to re-enable the python plugin."),
QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::No) {
m_MOInfo->setPluginSetting(name(), "enabled", false);
return true;
}
}
m_MOInfo->setPersistent(name(), "tryInit", true);
m_Runner = CreatePythonRunner(moInfo, pythonPath);
m_MOInfo->setPersistent(name(), "tryInit", false);
if (m_Runner != NULL) {
m_LoadFailure = FAIL_NONE;
} else {
@@ -137,7 +178,7 @@ QString ProxyPython::description() const
VersionInfo ProxyPython::version() const
{
return VersionInfo(1, 1, 1, VersionInfo::RELEASE_FINAL);
return VersionInfo(1, 2, 1, VersionInfo::RELEASE_FINAL);
}
bool ProxyPython::isActive() const
@@ -149,6 +190,7 @@ QList<PluginSetting> ProxyPython::settings() const
{
QList<PluginSetting> result;
result.push_back(PluginSetting("python_dir", "Path to your python installation. Leave empty for auto-detection", ""));
result.push_back(PluginSetting("enabled", "Set to true to enable support for python plugins", true));
return result;
}
@@ -183,8 +225,12 @@ std::vector<unsigned int> ProxyPython::activeProblems() const
result.push_back(PROBLEM_PYTHONMISSING);
} else if (m_LoadFailure == FAIL_WRONGPYTHONPATH) {
result.push_back(PROBLEM_WRONGPYTHONPATH);
} else if (m_LoadFailure == FAIL_PYTHONDETECTION) {
result.push_back(PROBLEM_PYTHONDETECTION);
} else if (m_LoadFailure == FAIL_INITFAIL) {
result.push_back(PROBLEM_INITFAIL);
} else if (m_LoadFailure == FAIL_SEMICOLON) {
result.push_back(PROBLEM_SEMICOLON);
} else if (m_Runner != NULL) {
if (!m_Runner->isPythonInstalled()) {
// don't know how this could happen but wth
@@ -213,6 +259,12 @@ QString ProxyPython::shortDescription(unsigned int key) const
case PROBLEM_INITFAIL: {
return tr("Initializing Python failed");
} break;
case PROBLEM_PYTHONDETECTION: {
return tr("Python auto-detection failed");
} break;
case PROBLEM_SEMICOLON: {
return tr("ModOrganizer path contains a semicolon");
} break;
default:
throw MyException(tr("invalid problem key %1").arg(key));
}
@@ -231,18 +283,29 @@ QString ProxyPython::fullDescription(unsigned int key) const
case PROBLEM_PYTHONWRONGVERSION: {
return tr("Your installed python version has a different version than 2.7. "
"Some MO plugins may not work.<br>"
"If you have multiple versions of python installed you may have to configure the path to 2.7 "
"If you have multiple versions of python installed you may have to configure the path to 2.7 (32 bit) "
"in the settings dialog.<br>"
"This is only required to use some extended functionality in MO, you do not need Python to play the game.");
} break;
case PROBLEM_WRONGPYTHONPATH: {
return tr("Please set python_dir in Settings->Plugins->ProxyPython to the path of your python 2.7 installation.");
return tr("Please set python_dir in Settings->Plugins->ProxyPython to the path of your python 2.7 (32 bit) installation.");
} break;
case PROBLEM_PYTHONDETECTION: {
return tr("The auto-detection of the python path failed. I don't know why this would happen but you can try to fix it "
"by setting python_dir in Settings->Plugins->ProxyPython to the path of your python 2.7 (32 bit) installation.");
} break;
case PROBLEM_INITFAIL: {
return tr("Sorry, I don't know any details. Most likely your python installation is not supported.");
} break;
case PROBLEM_SEMICOLON: {
return tr("The path to Mod Organizer (%1) contains a semicolon. <br>"
"While this is legal on NTFS drives there is a lot of software that doesn't handle it correctly.<br>"
"Unfortunately MO depends on libraries that seem to fall into that group.<br>"
"As a result the python plugin can't be loaded.<br>"
"The only solution I can offer is to remove the semicolon / move MO to a path without a semicolon.").arg(QCoreApplication::applicationDirPath());
} break;
default:
throw MyException(tr("invalid problem key %1").arg(key));
throw MyException(QString("invalid problem key %1").arg(key));
}
}
@@ -251,9 +314,11 @@ bool ProxyPython::hasGuidedFix(unsigned int key) const
return (key == PROBLEM_PYTHONMISSING) || (key == PROBLEM_PYTHONWRONGVERSION);
}
void ProxyPython::startGuidedFix(unsigned int) const
void ProxyPython::startGuidedFix(unsigned int key) const
{
::ShellExecuteA(NULL, "open", s_DownloadPythonURL, NULL, NULL, SW_SHOWNORMAL);
if ((key == PROBLEM_PYTHONMISSING) || (key == PROBLEM_PYTHONWRONGVERSION)) {
::ShellExecuteA(NULL, "open", s_DownloadPythonURL, NULL, NULL, SW_SHOWNORMAL);
}
}
+24 -1
View File
@@ -1,3 +1,22 @@
/*
Copyright (C) 2013 Sebastian Herbord. All rights reserved.
This file is part of python proxy plugin for MO
python proxy plugin 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.
Python proxy plugin 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 python proxy plugin. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PROXYPYTHON_H
#define PROXYPYTHON_H
@@ -52,19 +71,23 @@ private:
static const unsigned int PROBLEM_PYTHONWRONGVERSION = 2;
static const unsigned int PROBLEM_WRONGPYTHONPATH = 3;
static const unsigned int PROBLEM_INITFAIL = 4;
static const unsigned int PROBLEM_PYTHONDETECTION = 5;
static const unsigned int PROBLEM_SEMICOLON = 6;
static const char *s_DownloadPythonURL;
const MOBase::IOrganizer *m_MOInfo;
MOBase::IOrganizer *m_MOInfo;
QString m_TempRunnerFile;
HMODULE m_RunnerLib;
IPythonRunner *m_Runner;
enum {
FAIL_NONE,
FAIL_SEMICOLON,
FAIL_NOTINIT,
FAIL_MISSINGDEPENDENCIES,
FAIL_INITFAIL,
FAIL_WRONGPYTHONPATH,
FAIL_PYTHONDETECTION,
FAIL_OTHER
} m_LoadFailure;
+1 -1
View File
@@ -171,7 +171,7 @@ bool IPluginInstallerCustomWrapper::isManualInstaller() const
} PYCATCH;
}
bool IPluginInstallerCustomWrapper::isArchiveSupported(const DirectoryTree &tree) const
bool IPluginInstallerCustomWrapper::isArchiveSupported(const DirectoryTree &) const
{
try {
//return this->get_override("isArchiveSupported")(tree);
+7
View File
@@ -12,6 +12,9 @@ CONFIG += warn_on
DEFINES += PYTHONRUNNER_LIBRARY
# suppress a few warnings caused by boost vs vc++ paranoia
DEFINES += _SCL_SECURE_NO_WARNINGS
SOURCES += pythonrunner.cpp \
gilock.cpp \
error.cpp \
@@ -31,6 +34,8 @@ CONFIG(debug, debug|release) {
LIBS += -L$$OUT_PWD/../uibase/debug
} else {
LIBS += -L$$OUT_PWD/../uibase/release
QMAKE_CXXFLAGS += /Zi
QMAKE_LFLAGS += /DEBUG
}
@@ -40,3 +45,5 @@ LIBS += -lpython27
INCLUDEPATH += ../uibase
LIBS += -luibase
QMAKE_POST_LINK += xcopy /y /I $$quote($$SRCDIR\\$${TARGET}*.pdb) $$quote($$DSTDIR)\\plugins $$escape_expand(\\n)
+53 -21
View File
@@ -11,6 +11,7 @@
#include <Windows.h>
#include <utility.h>
#include <QFile>
#include <QCoreApplication>
// sip and qt slots seems to conflict
#include <sip.h>
@@ -36,17 +37,18 @@ public:
private:
void initPath(boost::python::object &moduleNamespace);
private:
std::map<QString, boost::python::object> m_PythonObjects;
const MOBase::IOrganizer *m_MOInfo;
char *m_PythonHome;
};
IPythonRunner *CreatePythonRunner(const MOBase::IOrganizer *moInfo, const QString &pythonDir)
IPythonRunner *CreatePythonRunner(MOBase::IOrganizer *moInfo, const QString &pythonDir)
{
s_Organizer = moInfo;
PythonRunner *result = new PythonRunner(moInfo);
if (result->initPython(pythonDir)) {
return result;
@@ -572,9 +574,17 @@ BOOST_PYTHON_MODULE(mobase)
.def("removeMod", bpy::pure_virtual(&MOBase::IOrganizer::removeMod))
.def("modDataChanged", bpy::pure_virtual(&MOBase::IOrganizer::modDataChanged))
.def("pluginSetting", bpy::pure_virtual(&IOrganizer::pluginSetting))
.def("setPluginSetting", bpy::pure_virtual(&IOrganizer::pluginSetting))
.def("persistent", bpy::pure_virtual(&IOrganizer::persistent))
.def("setPersistent", bpy::pure_virtual(&IOrganizer::setPersistent))
.def("pluginDataPath", bpy::pure_virtual(&IOrganizer::pluginDataPath))
.def("installMod", bpy::pure_virtual(&IOrganizer::installMod))
.def("downloadManager", bpy::pure_virtual(&IOrganizer::downloadManager), bpy::return_value_policy<bpy::reference_existing_object>());
.def("downloadManager", bpy::pure_virtual(&IOrganizer::downloadManager), bpy::return_value_policy<bpy::reference_existing_object>())
.def("pluginList", bpy::pure_virtual(&IOrganizer::pluginList), bpy::return_value_policy<bpy::reference_existing_object>())
.def("startApplication", bpy::pure_virtual(&IOrganizer::startApplication), bpy::return_value_policy<bpy::return_by_value>())
.def("onAboutToRun", bpy::pure_virtual(&IOrganizer::onAboutToRun))
.def("refreshModList", bpy::pure_virtual(&IOrganizer::refreshModList))
;
bpy::class_<ModRepositoryBridgeWrapper, boost::noncopyable>("ModRepositoryBridge")
.def("requestDescription", &ModRepositoryBridgeWrapper::requestDescription)
@@ -629,6 +639,7 @@ PythonRunner::PythonRunner(const MOBase::IOrganizer *moInfo)
static char* argv0 = "ModOrganizer.exe";
bool PythonRunner::initPython(const QString &pythonPath)
{
try {
@@ -642,19 +653,25 @@ bool PythonRunner::initPython(const QString &pythonPath)
Py_SetProgramName(argv0);
PyImport_AppendInittab("mobase", &initmobase);
Py_Initialize();
Py_OptimizeFlag = 2;
Py_NoSiteFlag = 1;
Py_InitializeEx(0);
if (!Py_IsInitialized()) {
return false;
}
PySys_SetArgv(0, &argv0);
bpy::object main_module = bpy::import("__main__");
bpy::object main_namespace = main_module.attr("__dict__");
main_namespace["cStringIO"] = bpy::import("cStringIO");
main_namespace["sys"] = bpy::import("sys");
bpy::object mainModule = bpy::import("__main__");
bpy::object mainNamespace = mainModule.attr("__dict__");
mainNamespace["sys"] = bpy::import("sys");
initPath(mainNamespace);
bpy::import("site");
mainNamespace["cStringIO"] = bpy::import("cStringIO");
bpy::exec("s_ErrIO = cStringIO.StringIO()\n"
"sys.stderr = s_ErrIO",
main_namespace);
mainNamespace);
return true;
} catch (const bpy::error_already_set&) {
qDebug("failed to init python");
@@ -684,26 +701,41 @@ bool handled_exec_file(bpy::str filename, bpy::object globals = bpy::object(), b
} while (false)
void PythonRunner::initPath(bpy::object &moduleNamespace)
{
static QString paths[] = {
m_MOInfo->pluginDataPath(),
QCoreApplication::applicationDirPath(),
QCoreApplication::applicationDirPath() + "/python27.zip",
QCoreApplication::applicationDirPath() + "/python27.zip/Lib",
QCoreApplication::applicationDirPath() + "/python27.zip/DLLs",
QCoreApplication::applicationDirPath() + "/python27.zip/Lib/site-packages",
};
for (int i = 0; i < sizeof(paths) / sizeof(QString); ++i) {
QString expr = QString("sys.path.insert(%1, \"%2\")").arg(i).arg(paths[i]);
bpy::eval(expr.toUtf8().constData(), moduleNamespace);
}
}
QObject *PythonRunner::instantiate(const QString &pluginName)
{
try {
GILock lock;
bpy::object main_module = bpy::import("__main__");
bpy::object main_namespace = main_module.attr("__dict__");
bpy::object mainModule = bpy::import("__main__");
bpy::object moduleNamespace = mainModule.attr("__dict__");
bpy::object mobase_module((bpy::handle<>(PyImport_ImportModule("mobase"))));
main_namespace["sys"] = bpy::import("sys");
main_namespace["mobase"] = mobase_module;
QString appendDataPath = QString("sys.path.insert(0, \"%1\")").arg(m_MOInfo->pluginDataPath());
bpy::eval(appendDataPath.toUtf8().constData(), main_namespace);
bpy::object sys = bpy::import("sys");
moduleNamespace["sys"] = sys;
moduleNamespace["mobase"] = bpy::import("mobase");
std::string temp = ToString(pluginName);
if (handled_exec_file(temp.c_str(), main_namespace)) {
if (handled_exec_file(temp.c_str(), moduleNamespace)) {
reportPythonError();
return NULL;
}
m_PythonObjects[pluginName] = main_namespace["createPlugin"]();
m_PythonObjects[pluginName] = moduleNamespace["createPlugin"]();
bpy::object pluginObj = m_PythonObjects[pluginName];
TRY_PLUGIN_TYPE(IPluginInstallerCustom, pluginObj);
+1 -1
View File
@@ -22,7 +22,7 @@ public:
#define PYDLLEXPORT Q_DECL_IMPORT
#endif // PYTHONRUNNER_LIBRARY
extern "C" PYDLLEXPORT IPythonRunner *CreatePythonRunner(const MOBase::IOrganizer *moInfo, const QString &pythonDir);
extern "C" PYDLLEXPORT IPythonRunner *CreatePythonRunner(MOBase::IOrganizer *moInfo, const QString &pythonDir);
-12
View File
@@ -1,12 +0,0 @@
#ifndef PYTHONRUNNER_GLOBAL_H
#define PYTHONRUNNER_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(PYTHONRUNNER_LIBRARY)
# define PYTHONRUNNERSHARED_EXPORT Q_DECL_EXPORT
#else
# define PYTHONRUNNERSHARED_EXPORT Q_DECL_IMPORT
#endif
#endif // PYTHONRUNNER_GLOBAL_H
+15 -8
View File
@@ -65,8 +65,8 @@ public:
void onRequestFailed(boost::python::object callback) {
m_FailedHandler = callback;
connect(m_Wrapped, SIGNAL(requestFailed(int,QVariant,QString)),
this, SLOT(requestFailed(int,QVariant,QString)),
connect(m_Wrapped, SIGNAL(requestFailed(int,int,QVariant,QString)),
this, SLOT(requestFailed(int,int,QVariant,QString)),
Qt::UniqueConnection);
}
@@ -91,11 +91,11 @@ private slots:
// }
}
void requestFailed(int modID, QVariant userData, const QString &errorMessage)
void requestFailed(int modID, int fileID, QVariant userData, const QString &errorMessage)
{
try {
GILock lock;
m_FailedHandler(modID, userData, errorMessage);
m_FailedHandler(modID, fileID, userData, errorMessage);
} catch (const boost::python::error_already_set&) {
reportPythonError();
}
@@ -119,10 +119,6 @@ struct IOrganizerWrapper: MOBase::IOrganizer, boost::python::wrapper<MOBase::IOr
virtual MOBase::IModRepositoryBridge *createNexusBridge() const {
return this->get_override("createNexusBridge")();
}
/*
static ModRepositoryBridgeWrapper newNexusBridge(IOrganizerWrapper *self) {
return ModRepositoryBridgeWrapper(self->createNexusBridge());
}*/
virtual QString profileName() const { return this->get_override("profileName")(); }
virtual QString profilePath() const { return this->get_override("profilePath")(); }
@@ -133,10 +129,21 @@ struct IOrganizerWrapper: MOBase::IOrganizer, boost::python::wrapper<MOBase::IOr
virtual bool removeMod(MOBase::IModInterface *mod) { return this->get_override("removeMod")(mod); }
virtual void modDataChanged(MOBase::IModInterface *mod) { this->get_override("modDataChanged")(mod); }
virtual QVariant pluginSetting(const QString &pluginName, const QString &key) const { return this->get_override("pluginSetting")(pluginName, key); }
virtual void setPluginSetting(const QString &pluginName, const QString &key, const QVariant &value) { this->get_override("setPluginSetting")(pluginName, key, value); }
virtual QVariant persistent(const QString &pluginName, const QString &key, const QVariant &def = QVariant()) const { return this->get_override("persistent")(pluginName, key, def); }
virtual void setPersistent(const QString &pluginName, const QString &key, const QVariant &value, bool sync = true) { this->get_override("setPersistent")(pluginName, key, value, sync); }
virtual QString pluginDataPath() const { return this->get_override("pluginDataPath")(); }
virtual void installMod(const QString &fileName) { this->get_override("installMod")(fileName); }
virtual MOBase::IDownloadManager *downloadManager() { return this->get_override("downloadManager")(); }
virtual MOBase::IPluginList *pluginList() { return this->get_override("pluginList")(); }
virtual MOBase::IModList *modList() { return this->get_override("modList")(); }
virtual QString resolvePath(const QString &fileName) const { return this->get_override("resolvePath")(fileName); }
virtual QStringList listDirectories(const QString &directoryName) const { return this->get_override("listDirectories")(directoryName); }
virtual QStringList findFiles(const QString &path, const std::function<bool(const QString&)> &filter) const { return this->get_override("findFiles")(path, filter); }
virtual QList<FileInfo> findFileInfos(const QString &path, const std::function<bool(const FileInfo&)> &filter) const { return this->get_override("findFileInfos")(path, filter); }
virtual HANDLE startApplication(const QString &executable, const QStringList &args = QStringList(), const QString &cwd = "", const QString &profile = "") { return this->get_override("startApplication")(executable, args, cwd, profile); }
virtual bool onAboutToRun(const std::function<bool(const QString&)> &func) { return this->get_override("onAboutToRun")(func); }
virtual void refreshModList(bool saveChanges = true) { this->get_override("refreshModList")(saveChanges); }
};
struct IDownloadManagerWrapper: MOBase::IDownloadManager, boost::python::wrapper<MOBase::IDownloadManager>