mirror of
https://github.com/ModOrganizer2/modorganizer-plugin_python.git
synced 2026-07-27 14:03:33 -07:00
Compare commits
51
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a5901d7975 | ||
|
|
a7b81418a5 | ||
|
|
560e1ce0c7 | ||
|
|
6edbec745d | ||
|
|
d6edcf4fa0 | ||
|
|
50a725a1b4 | ||
|
|
a1fdb54471 | ||
|
|
e602014dda | ||
|
|
90df417a8c | ||
|
|
cb9a7fcd2d | ||
|
|
9d2264aff8 | ||
|
|
0aeeb9365f | ||
|
|
3967d64437 | ||
|
|
a7e881869e | ||
|
|
3f66d206e8 | ||
|
|
9d48b75388 | ||
|
|
841b923751 | ||
|
|
23fd430605 | ||
|
|
1a89e42c0f | ||
|
|
42afc90c8d | ||
|
|
9b989e9f97 | ||
|
|
c7203bf9de | ||
|
|
a7d626c83c | ||
|
|
bbea63e7af | ||
|
|
9f607a5fcb | ||
|
|
b7edde6fa0 | ||
|
|
589325d91b | ||
|
|
994018a491 | ||
|
|
868ab93a1f | ||
|
|
7c8fafc196 | ||
|
|
dec620b5b7 | ||
|
|
29c66c621d | ||
|
|
5da6a9d3bd | ||
|
|
7b5f01b49d | ||
|
|
573be8c6b5 | ||
|
|
a738cef190 | ||
|
|
2c661da2da | ||
|
|
2bf3ba0984 | ||
|
|
fa09fd7635 | ||
|
|
b76c4a1869 | ||
|
|
84fe2b0307 | ||
|
|
e7e686c361 | ||
|
|
ae8b6a39b0 | ||
|
|
2dc9463951 | ||
|
|
1d4a4b485d | ||
|
|
d5838c7560 | ||
|
|
9cbf374166 | ||
|
|
f71bfff0e6 | ||
|
|
8aa2ab4eac | ||
|
|
46a0ce9e38 | ||
|
|
15e635741c |
@@ -0,0 +1,35 @@
|
||||
import os
|
||||
|
||||
Import('qt_env')
|
||||
|
||||
env = qt_env.Clone()
|
||||
|
||||
env.AppendUnique(CPPDEFINES = [
|
||||
'PROXYPYTHON_LIBRARY',
|
||||
# suppress a few warnings caused by boost vs vc++ paranoia
|
||||
'_SCL_SECURE_NO_WARNINGS'
|
||||
])
|
||||
|
||||
env.AppendUnique(CPPPATH = [
|
||||
'${BOOSTPATH}',
|
||||
'..\\..\\pythonRunner'
|
||||
])
|
||||
|
||||
env.AppendUnique(LIBS = 'shell32')
|
||||
|
||||
runner = env.File(os.path.join('..', '..', 'pythonRunner', 'pythonRunner.dll'))
|
||||
|
||||
runner_env = env.Clone()
|
||||
runner_env.AppendUnique(CPPDEFINES = 'SCONS_BUILD')
|
||||
runner_env.AppendUnique(CPPPATH = runner.dir)
|
||||
rc = runner_env.RES('embedrunner.rc')
|
||||
# Make sure we have the proper dependencies so it gets built
|
||||
runner_env.Depends(rc, runner)
|
||||
|
||||
# There's a whole load of unused C++ files in here.
|
||||
lib = env.SharedLibrary('proxyPython', [ 'proxypython.cpp' ] + rc)
|
||||
|
||||
env.InstallModule(lib)
|
||||
|
||||
res = env['QT_USED_MODULES']
|
||||
Return('res')
|
||||
@@ -1,7 +1,11 @@
|
||||
#include "resource.h"
|
||||
|
||||
#ifdef SCONS_BUILD
|
||||
IDR_LOADER_DLL BINARY MOVEABLE PURE pythonRunner.dll
|
||||
#else
|
||||
#ifdef _DEBUG
|
||||
IDR_LOADER_DLL BINARY MOVEABLE PURE "..\\..\\pythonRunner\\debug\\pythonRunner.dll"
|
||||
#else // _DEBUG
|
||||
IDR_LOADER_DLL BINARY MOVEABLE PURE "..\\..\\pythonRunner\\release\\pythonRunner.dll"
|
||||
#endif // _DEBUG
|
||||
#endif
|
||||
|
||||
@@ -8,9 +8,7 @@
|
||||
TARGET = proxyPython
|
||||
TEMPLATE = lib
|
||||
|
||||
contains(QT_VERSION, "^5.*") {
|
||||
QT += widgets
|
||||
}
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
CONFIG += plugins
|
||||
CONFIG += dll
|
||||
@@ -31,21 +29,22 @@ HEADERS += proxypython.h \
|
||||
|
||||
OTHER_FILES += \
|
||||
proxypython.json \
|
||||
embedrunner.rc
|
||||
embedrunner.rc\
|
||||
SConscript
|
||||
|
||||
RC_FILE += \
|
||||
embedrunner.rc
|
||||
|
||||
include(../plugin_template.pri)
|
||||
|
||||
INCLUDEPATH += "../../pythonRunner" "$(BOOSTPATH)"
|
||||
INCLUDEPATH += "../../pythonRunner" "$${BOOSTPATH}"
|
||||
|
||||
WINPWD = $$PWD
|
||||
WINPWD ~= s,/,$$QMAKE_DIR_SEP,g
|
||||
|
||||
//QMAKE_POST_LINK += SET VS90COMNTOOLS=%VS100COMNTOOLS% $$escape_expand(\\n)
|
||||
#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)
|
||||
|
||||
+35
-16
@@ -37,7 +37,7 @@ const char *ProxyPython::s_DownloadPythonURL = "http://www.python.org/download/r
|
||||
|
||||
HMODULE GetOwnModuleHandle()
|
||||
{
|
||||
HMODULE hMod = NULL;
|
||||
HMODULE hMod = nullptr;
|
||||
GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
|
||||
reinterpret_cast<LPCWSTR>(&GetOwnModuleHandle), &hMod);
|
||||
|
||||
@@ -50,29 +50,48 @@ QString ExtractResource(WORD resourceID, const QString &szFilename)
|
||||
HMODULE mod = GetOwnModuleHandle();
|
||||
|
||||
HRSRC hResource = FindResourceW(mod, MAKEINTRESOURCE(resourceID), L"BINARY");
|
||||
if (hResource == NULL) {
|
||||
if (hResource == nullptr) {
|
||||
throw MyException("embedded dll not available: " + windowsErrorString(::GetLastError()));
|
||||
}
|
||||
|
||||
HGLOBAL hFileResource = LoadResource(mod, hResource);
|
||||
if (hFileResource == NULL) {
|
||||
if (hFileResource == nullptr) {
|
||||
throw MyException("failed to load embedded dll resource: " + windowsErrorString(::GetLastError()));
|
||||
}
|
||||
|
||||
LPVOID lpFile = LockResource(hFileResource);
|
||||
if (lpFile == nullptr) {
|
||||
throw MyException(QString("failed to lock resource: %1").arg(windowsErrorString(::GetLastError())));
|
||||
}
|
||||
|
||||
DWORD dwSize = SizeofResource(mod, hResource);
|
||||
|
||||
QString outFile = QDir::tempPath() + "/" + szFilename;
|
||||
|
||||
HANDLE hFile = CreateFileW(ToWString(outFile).c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
HANDLE hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, dwSize, NULL);
|
||||
HANDLE hFile = CreateFileW(outFile.toStdWString().c_str(), GENERIC_READ | GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
if (::GetLastError() == ERROR_SHARING_VIOLATION) {
|
||||
// dll exists and is opened by another instance of MO, shouldn't be outdated then...
|
||||
return outFile;
|
||||
} else {
|
||||
throw MyException(QString("failed to open python runner: %1").arg(windowsErrorString(::GetLastError())));
|
||||
}
|
||||
}
|
||||
HANDLE hFileMap = CreateFileMapping(hFile, nullptr, PAGE_READWRITE, 0, dwSize, nullptr);
|
||||
if (hFileMap == NULL) {
|
||||
throw MyException(QString("failed to map python runner: %1").arg(windowsErrorString(::GetLastError())));
|
||||
}
|
||||
LPVOID lpAddress = MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0);
|
||||
if (lpAddress == nullptr) {
|
||||
throw MyException(QString("failed to map view of file: %1").arg(windowsErrorString(::GetLastError())));
|
||||
}
|
||||
|
||||
CopyMemory(lpAddress, lpFile, dwSize);
|
||||
|
||||
UnmapViewOfFile(lpAddress);
|
||||
|
||||
CloseHandle(hFileMap);
|
||||
::FlushFileBuffers(hFile);
|
||||
CloseHandle(hFile);
|
||||
|
||||
return outFile;
|
||||
@@ -80,7 +99,7 @@ QString ExtractResource(WORD resourceID, const QString &szFilename)
|
||||
|
||||
|
||||
ProxyPython::ProxyPython()
|
||||
: m_MOInfo(NULL), m_Runner(NULL), m_LoadFailure(FAIL_NOTINIT)
|
||||
: m_MOInfo(nullptr), m_Runner(nullptr), m_LoadFailure(FAIL_NOTINIT)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -118,9 +137,9 @@ bool ProxyPython::init(IOrganizer *moInfo)
|
||||
|
||||
m_TempRunnerFile = ExtractResource(IDR_LOADER_DLL, "__pythonRunner.dll");
|
||||
m_RunnerLib = ::LoadLibraryW(ToWString(m_TempRunnerFile).c_str());
|
||||
if (m_RunnerLib != NULL) {
|
||||
if (m_RunnerLib != nullptr) {
|
||||
CreatePythonRunner_func CreatePythonRunner = (CreatePythonRunner_func)::GetProcAddress(m_RunnerLib, "CreatePythonRunner");
|
||||
if (CreatePythonRunner == NULL) {
|
||||
if (CreatePythonRunner == nullptr) {
|
||||
throw MyException("embedded dll is invalid: " + windowsErrorString(::GetLastError()));
|
||||
}
|
||||
if (m_MOInfo->persistent(name(), "tryInit", false).toBool()) {
|
||||
@@ -145,7 +164,7 @@ bool ProxyPython::init(IOrganizer *moInfo)
|
||||
m_Runner = CreatePythonRunner(moInfo, pythonPath);
|
||||
m_MOInfo->setPersistent(name(), "tryInit", false);
|
||||
|
||||
if (m_Runner != NULL) {
|
||||
if (m_Runner != nullptr) {
|
||||
m_LoadFailure = FAIL_NONE;
|
||||
} else {
|
||||
m_LoadFailure = FAIL_INITFAIL;
|
||||
@@ -153,7 +172,7 @@ bool ProxyPython::init(IOrganizer *moInfo)
|
||||
return true;
|
||||
} else {
|
||||
DWORD error = ::GetLastError();
|
||||
qCritical("Failed to load python runner: %s", qPrintable(windowsErrorString(error)));
|
||||
qCritical("Failed to load python runner (%s): %s", qPrintable(m_TempRunnerFile), qPrintable(windowsErrorString(error)));
|
||||
if (error == ERROR_MOD_NOT_FOUND) {
|
||||
m_LoadFailure = FAIL_MISSINGDEPENDENCIES;
|
||||
}
|
||||
@@ -163,7 +182,7 @@ bool ProxyPython::init(IOrganizer *moInfo)
|
||||
|
||||
QString ProxyPython::name() const
|
||||
{
|
||||
return tr("Python Proxy");
|
||||
return "Python Proxy";
|
||||
}
|
||||
|
||||
QString ProxyPython::author() const
|
||||
@@ -178,7 +197,7 @@ QString ProxyPython::description() const
|
||||
|
||||
VersionInfo ProxyPython::version() const
|
||||
{
|
||||
return VersionInfo(1, 3, 0, VersionInfo::RELEASE_FINAL);
|
||||
return VersionInfo(1, 3, 1, VersionInfo::RELEASE_FINAL);
|
||||
}
|
||||
|
||||
bool ProxyPython::isActive() const
|
||||
@@ -209,11 +228,11 @@ QStringList ProxyPython::pluginList(const QString &pluginPath) const
|
||||
|
||||
QObject *ProxyPython::instantiate(const QString &pluginName)
|
||||
{
|
||||
if (m_Runner != NULL) {
|
||||
if (m_Runner != nullptr) {
|
||||
QObject *result = m_Runner->instantiate(pluginName);
|
||||
return result;
|
||||
} else {
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,7 +250,7 @@ std::vector<unsigned int> ProxyPython::activeProblems() const
|
||||
result.push_back(PROBLEM_INITFAIL);
|
||||
} else if (m_LoadFailure == FAIL_SEMICOLON) {
|
||||
result.push_back(PROBLEM_SEMICOLON);
|
||||
} else if (m_Runner != NULL) {
|
||||
} else if (m_Runner != nullptr) {
|
||||
if (!m_Runner->isPythonInstalled()) {
|
||||
// don't know how this could happen but wth
|
||||
result.push_back(PROBLEM_PYTHONMISSING);
|
||||
@@ -317,7 +336,7 @@ bool ProxyPython::hasGuidedFix(unsigned int key) const
|
||||
void ProxyPython::startGuidedFix(unsigned int key) const
|
||||
{
|
||||
if ((key == PROBLEM_PYTHONMISSING) || (key == PROBLEM_PYTHONWRONGVERSION)) {
|
||||
::ShellExecuteA(NULL, "open", s_DownloadPythonURL, NULL, NULL, SW_SHOWNORMAL);
|
||||
::ShellExecuteA(nullptr, "open", s_DownloadPythonURL, nullptr, nullptr, SW_SHOWNORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ along with python proxy plugin. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include <pythonrunner.h>
|
||||
|
||||
|
||||
class ProxyPython : public QObject, MOBase::IPluginProxy, MOBase::IPluginDiagnose
|
||||
class ProxyPython : public QObject, public MOBase::IPluginProxy, public MOBase::IPluginDiagnose
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(MOBase::IPlugin MOBase::IPluginProxy MOBase::IPluginDiagnose)
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
Import('qt_env')
|
||||
|
||||
env = qt_env.Clone()
|
||||
|
||||
env.EnableQtModules('Core', 'Gui')
|
||||
|
||||
env.AppendUnique(CPPDEFINES = 'PYTHONRUNNER_LIBRARY')
|
||||
|
||||
# suppress a few warnings caused by boost vs vc++ paranoia
|
||||
# NB HAVE_ROUND causes a warning because it's defined in pythonrunner.cpp
|
||||
env.AppendUnique(CPPDEFINES = [
|
||||
'_SCL_SECURE_NO_WARNINGS',
|
||||
'HAVE_ROUND'
|
||||
])
|
||||
|
||||
# QMAKE_CXXFLAGS += /Zi
|
||||
# QMAKE_LFLAGS += /DEBUG
|
||||
|
||||
env.RequireLibraries('uibase')
|
||||
|
||||
# AppendUnique appears not to work with QT4
|
||||
env['CPPPATH'] += [
|
||||
'${BOOSTPATH}',
|
||||
'${PYTHONPATH}\\include',
|
||||
]
|
||||
|
||||
env.AppendUnique(LIBS = [
|
||||
'python27', # Could be done better
|
||||
])
|
||||
|
||||
env.AppendUnique(LIBPATH = [
|
||||
'${PYTHONPATH}/libs', # Could be done better
|
||||
])
|
||||
|
||||
# We have to 'persuade' moc to generate certain other targets and inject them
|
||||
# into the list of cpps
|
||||
targets = env.AddExtraMoc(env.Glob('*.h'))
|
||||
|
||||
# pythontoolwrapper doesnt compile and isn't in the project file
|
||||
cpp_files = [
|
||||
x for x in Glob('*.cpp') if x.name != 'pythontoolwrapper.cpp'
|
||||
]
|
||||
|
||||
lib = env.SharedLibrary('pythonRunner', cpp_files + targets)
|
||||
|
||||
#This is referred to from inside a resource file. We don't install it.
|
||||
#env.InstallModule(lib)
|
||||
|
||||
# However...
|
||||
# we do need boost-python and pythonvv.dll and pythonvv.zip (though the last
|
||||
# isn't needed to just bring up the module)
|
||||
#env.Pseudo('install')
|
||||
#env.Depends('install',
|
||||
# (env.Install('${INSTALL_PATH}', 'pyCfg.py'),
|
||||
# env.Install(os.path.join('${INSTALL_PATH}', 'data'),
|
||||
# ( ui, rc, 'settings.json' )),
|
||||
# ))
|
||||
|
||||
res = env['QT_USED_MODULES']
|
||||
Return('res')
|
||||
@@ -1,4 +1,6 @@
|
||||
#ifndef Q_MOC_RUN
|
||||
#include <boost/python.hpp>
|
||||
#endif
|
||||
#include <QString>
|
||||
#include <utility.h>
|
||||
|
||||
|
||||
@@ -26,63 +26,63 @@ bool IPluginToolWrapper::init(MOBase::IOrganizer *moInfo)
|
||||
QString IPluginToolWrapper::name() const
|
||||
{
|
||||
try {
|
||||
return this->get_override("name")();
|
||||
return this->get_override("name")().as<QString>();
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
QString IPluginToolWrapper::author() const
|
||||
{
|
||||
try {
|
||||
return this->get_override("author")();
|
||||
return this->get_override("author")().as<QString>();
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
QString IPluginToolWrapper::description() const
|
||||
{
|
||||
try {
|
||||
return this->get_override("description")();
|
||||
return this->get_override("description")().as<QString>();
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
MOBase::VersionInfo IPluginToolWrapper::version() const
|
||||
{
|
||||
try {
|
||||
return this->get_override("version")();
|
||||
return this->get_override("version")().as<MOBase::VersionInfo>();
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
bool IPluginToolWrapper::isActive() const
|
||||
{
|
||||
try {
|
||||
return this->get_override("isActive")();
|
||||
return this->get_override("isActive")().as<bool>();
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
QList<MOBase::PluginSetting> IPluginToolWrapper::settings() const
|
||||
{
|
||||
try {
|
||||
return this->get_override("settings")();
|
||||
return this->get_override("settings")().as<QList<MOBase::PluginSetting>>();
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
QString IPluginToolWrapper::displayName() const
|
||||
{
|
||||
try {
|
||||
return this->get_override("displayName")();
|
||||
return this->get_override("displayName")().as<QString>();
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
QString IPluginToolWrapper::tooltip() const
|
||||
{
|
||||
try {
|
||||
return this->get_override("tooltip")();
|
||||
return this->get_override("tooltip")().as<QString>();
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
QIcon IPluginToolWrapper::icon() const
|
||||
{
|
||||
try {
|
||||
return this->get_override("icon")();
|
||||
return this->get_override("icon")().as<QIcon>();
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
@@ -117,21 +117,21 @@ bool IPluginInstallerCustomWrapper::init(MOBase::IOrganizer *moInfo)
|
||||
QString IPluginInstallerCustomWrapper::name() const
|
||||
{
|
||||
try {
|
||||
return this->get_override("name")();
|
||||
return this->get_override("name")().as<QString>();
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
QString IPluginInstallerCustomWrapper::author() const
|
||||
{
|
||||
try {
|
||||
return this->get_override("author")();
|
||||
return this->get_override("author")().as<QString>();
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
QString IPluginInstallerCustomWrapper::description() const
|
||||
{
|
||||
try {
|
||||
return this->get_override("description")();
|
||||
return this->get_override("description")().as<QString>();
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ bool IPluginInstallerCustomWrapper::isActive() const
|
||||
QList<MOBase::PluginSetting> IPluginInstallerCustomWrapper::settings() const
|
||||
{
|
||||
try {
|
||||
return this->get_override("settings")();
|
||||
return this->get_override("settings")().as<QList<MOBase::PluginSetting>>();
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
@@ -188,7 +188,7 @@ bool IPluginInstallerCustomWrapper::isArchiveSupported(const QString &archiveNam
|
||||
std::set<QString> IPluginInstallerCustomWrapper::supportedExtensions() const
|
||||
{
|
||||
try {
|
||||
return this->get_override("supportedExtensions")();
|
||||
return this->get_override("supportedExtensions")().as<std::set<QString>>();
|
||||
} PYCATCH;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <iplugintool.h>
|
||||
#include <iplugininstallersimple.h>
|
||||
#include <iplugininstallercustom.h>
|
||||
#include <iplugindiagnose.h>
|
||||
|
||||
#ifndef Q_MOC_RUN
|
||||
#include <boost/python.hpp>
|
||||
|
||||
+20
-13
@@ -13,7 +13,12 @@ CONFIG += warn_on
|
||||
DEFINES += PYTHONRUNNER_LIBRARY
|
||||
|
||||
# suppress a few warnings caused by boost vs vc++ paranoia
|
||||
DEFINES += _SCL_SECURE_NO_WARNINGS
|
||||
DEFINES += _SCL_SECURE_NO_WARNINGS HAVE_ROUND NOMINMAX
|
||||
|
||||
|
||||
!include(../LocalPaths.pri) {
|
||||
message("paths to required libraries need to be set up in LocalPaths.pri")
|
||||
}
|
||||
|
||||
SOURCES += pythonrunner.cpp \
|
||||
gilock.cpp \
|
||||
@@ -28,29 +33,31 @@ HEADERS += pythonrunner.h \
|
||||
pythonpluginwrapper.h \
|
||||
proxypluginwrappers.h
|
||||
|
||||
CONFIG(debug, debug|release) {
|
||||
LIBS += -L$$OUT_PWD/../uibase/debug
|
||||
} else {
|
||||
LIBS += -L$$OUT_PWD/../uibase/release
|
||||
msvc:QMAKE_CXXFLAGS += /Zi
|
||||
msvc:QMAKE_LFLAGS += /DEBUG
|
||||
}
|
||||
|
||||
INCLUDEPATH += "$${BOOSTPATH}" "$${PYTHONPATH}/include" "$${PYTHONPATH}/Lib/site-packages/PyQt5/include" ../uibase
|
||||
LIBS += -L"$${PYTHONPATH}/libs" -L"$${BOOSTPATH}/stage/lib"
|
||||
LIBS += -lpython27
|
||||
LIBS += -luibase
|
||||
|
||||
CONFIG(debug, debug|release) {
|
||||
SRCDIR = $$OUT_PWD/debug
|
||||
DSTDIR = $$PWD/../../outputd
|
||||
LIBS += -L$$OUT_PWD/../uibase/debug
|
||||
} else {
|
||||
SRCDIR = $$OUT_PWD/release
|
||||
DSTDIR = $$PWD/../../output
|
||||
LIBS += -L$$OUT_PWD/../uibase/release
|
||||
QMAKE_CXXFLAGS += /Zi
|
||||
QMAKE_LFLAGS += /DEBUG
|
||||
}
|
||||
|
||||
|
||||
SRCDIR ~= s,/,$$QMAKE_DIR_SEP,g
|
||||
DSTDIR ~= s,/,$$QMAKE_DIR_SEP,g
|
||||
|
||||
INCLUDEPATH += "$(BOOSTPATH)" "$$(PYTHONPATH)/include" "$$(PYTHONPATH)/Lib/site-packages/PyQt4/include"
|
||||
LIBS += -L"$$(PYTHONPATH)/libs" -L"$(BOOSTPATH)/stage/lib"
|
||||
LIBS += -lpython27
|
||||
|
||||
INCLUDEPATH += ../uibase
|
||||
LIBS += -luibase
|
||||
|
||||
QMAKE_POST_LINK += xcopy /y /I $$quote($$SRCDIR\\$${TARGET}*.pdb) $$quote($$DSTDIR)\\plugins $$escape_expand(\\n)
|
||||
|
||||
OTHER_FILES += \
|
||||
SConscript
|
||||
|
||||
+113
-57
@@ -3,7 +3,6 @@
|
||||
#pragma warning( disable : 4100 )
|
||||
#pragma warning( disable : 4996 )
|
||||
|
||||
#include <boost/python.hpp>
|
||||
#include <iplugininstaller.h>
|
||||
#include "uibasewrappers.h"
|
||||
#include "pythonpluginwrapper.h"
|
||||
@@ -21,7 +20,7 @@
|
||||
#endif
|
||||
|
||||
|
||||
MOBase::IOrganizer *s_Organizer = NULL;
|
||||
MOBase::IOrganizer *s_Organizer = nullptr;
|
||||
|
||||
|
||||
|
||||
@@ -54,7 +53,7 @@ IPythonRunner *CreatePythonRunner(MOBase::IOrganizer *moInfo, const QString &pyt
|
||||
return result;
|
||||
} else {
|
||||
delete result;
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,13 +101,13 @@ struct QString_from_python_str
|
||||
}
|
||||
|
||||
static void *convertible(PyObject *objPtr) {
|
||||
return PyString_Check(objPtr) ? objPtr : NULL;
|
||||
return PyString_Check(objPtr) ? objPtr : nullptr;
|
||||
}
|
||||
|
||||
static void construct(PyObject *objPtr, bpy::converter::rvalue_from_python_stage1_data *data) {
|
||||
// Extract the character data from the python string
|
||||
const char* value = PyString_AsString(objPtr);
|
||||
assert(value != NULL);
|
||||
assert(value != nullptr);
|
||||
|
||||
// allocate storage
|
||||
void *storage = ((bpy::converter::rvalue_from_python_storage<QString>*)data)->storage.bytes;
|
||||
@@ -145,7 +144,7 @@ struct GuessedValue_converters
|
||||
if PyList_Check(objPtr) {
|
||||
return objPtr;
|
||||
} else {
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,6 +176,7 @@ struct QVariant_to_python_obj
|
||||
static PyObject *convert(const QVariant &var) {
|
||||
switch (var.type()) {
|
||||
case QVariant::Int: return PyLong_FromLong(var.toInt());
|
||||
case QVariant::UInt: return PyLong_FromUnsignedLong(var.toUInt());
|
||||
case QVariant::Bool: return PyBool_FromLong(var.toBool());
|
||||
case QVariant::String: return bpy::incref(bpy::object(var.toString().toUtf8().constData()).ptr());
|
||||
case QVariant::List: {
|
||||
@@ -187,8 +187,18 @@ struct QVariant_to_python_obj
|
||||
}
|
||||
return result;
|
||||
} break;
|
||||
case QVariant::Map: {
|
||||
QVariantMap map = var.toMap();
|
||||
PyObject *result = PyDict_New();
|
||||
QMapIterator<QString, QVariant> iter(map);
|
||||
while (iter.hasNext()) {
|
||||
iter.next();
|
||||
PyDict_SetItem(result, convert(iter.key()), convert(iter.value()));
|
||||
}
|
||||
return result;
|
||||
} break;
|
||||
default: {
|
||||
PyErr_SetString(PyExc_TypeError, "type unsupported");
|
||||
PyErr_Format(PyExc_TypeError, "type unsupported: %d", var.type());
|
||||
throw bpy::error_already_set();
|
||||
} break;
|
||||
}
|
||||
@@ -205,7 +215,7 @@ struct QVariant_from_python_obj
|
||||
static void *convertible(PyObject *objPtr) {
|
||||
if (!PyString_Check(objPtr) && !PyInt_Check(objPtr) &&
|
||||
!PyBool_Check(objPtr) && !PyList_Check(objPtr)) {
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
return objPtr;
|
||||
}
|
||||
@@ -298,7 +308,7 @@ struct QList_from_python_obj
|
||||
|
||||
static void* convertible(PyObject *objPtr) {
|
||||
if (PyList_Check(objPtr)) return objPtr;
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static void construct(PyObject *objPtr, bpy::converter::rvalue_from_python_stage1_data *data) {
|
||||
@@ -327,7 +337,7 @@ struct stdset_from_python_list
|
||||
|
||||
static void* convertible(PyObject *objPtr) {
|
||||
if (PyList_Check(objPtr)) return objPtr;
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static void construct(PyObject *objPtr, bpy::converter::rvalue_from_python_stage1_data *data) {
|
||||
@@ -347,8 +357,8 @@ struct stdset_from_python_list
|
||||
|
||||
static const sipAPIDef *sipAPI()
|
||||
{
|
||||
static const sipAPIDef *sipApi = NULL;
|
||||
if (sipApi == NULL) {
|
||||
static const sipAPIDef *sipApi = nullptr;
|
||||
if (sipApi == nullptr) {
|
||||
sipApi = (const sipAPIDef *)PyCapsule_Import("sip._C_API", 0);
|
||||
}
|
||||
|
||||
@@ -356,33 +366,45 @@ static const sipAPIDef *sipAPI()
|
||||
}
|
||||
|
||||
|
||||
struct IModRepositoryBridge_to_python
|
||||
{
|
||||
static PyObject *convert(IModRepositoryBridge *bridge)
|
||||
{
|
||||
ModRepositoryBridgeWrapper wrapper(bridge);
|
||||
|
||||
return bpy::incref(bpy::object(wrapper).ptr());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <typename T> struct MetaData;
|
||||
|
||||
template <> struct MetaData<IModRepositoryBridge> { static const char *className() { return "MOBase::INexusBridge"; } };
|
||||
template <> struct MetaData<IModRepositoryBridge> { static const char *className() { return "QObject"; } };
|
||||
template <> struct MetaData<IDownloadManager> { static const char *className() { return "QObject"; } };
|
||||
template <> struct MetaData<QObject> { static const char *className() { return "QObject"; } };
|
||||
template <> struct MetaData<QWidget> { static const char *className() { return "QWidget"; } };
|
||||
template <> struct MetaData<QIcon> { static const char *className() { return "QIcon"; } };
|
||||
template <> struct MetaData<QStringList> { static const char *className() { return "QStringList"; } };
|
||||
template <> struct MetaData<QVariant> { static const char *className() { return "QVariant"; } };
|
||||
|
||||
|
||||
template <typename T>
|
||||
PyObject *toPyQt(T *objPtr)
|
||||
{
|
||||
if (objPtr == NULL) {
|
||||
if (objPtr == nullptr) {
|
||||
qDebug("no input object");
|
||||
return bpy::incref(Py_None);
|
||||
}
|
||||
|
||||
const sipTypeDef *type = sipAPI()->api_find_type(MetaData<T>::className());
|
||||
|
||||
if (type == NULL) {
|
||||
if (type == nullptr) {
|
||||
qDebug("failed to determine type: %s", MetaData<T>::className());
|
||||
return bpy::incref(Py_None);
|
||||
}
|
||||
|
||||
PyObject *sipObj = sipAPI()->api_convert_from_type(objPtr, type, 0);
|
||||
if (sipObj == NULL) {
|
||||
if (sipObj == nullptr) {
|
||||
qDebug("failed to convert");
|
||||
return bpy::incref(Py_None);
|
||||
}
|
||||
@@ -397,12 +419,12 @@ struct QClass_converters
|
||||
{
|
||||
static PyObject *convert(const T &object) {
|
||||
const sipTypeDef *type = sipAPI()->api_find_type(MetaData<T>::className());
|
||||
if (type == NULL) {
|
||||
if (type == nullptr) {
|
||||
return bpy::incref(Py_None);
|
||||
}
|
||||
|
||||
PyObject *sipObj = sipAPI()->api_convert_from_type((void*)(&object), type, 0);
|
||||
if (sipObj == NULL) {
|
||||
if (sipObj == nullptr) {
|
||||
return bpy::incref(Py_None);
|
||||
}
|
||||
|
||||
@@ -410,17 +432,17 @@ struct QClass_converters
|
||||
}
|
||||
|
||||
static PyObject *convert(T *object) {
|
||||
if (object == NULL) {
|
||||
if (object == nullptr) {
|
||||
return bpy::incref(Py_None);
|
||||
}
|
||||
|
||||
const sipTypeDef *type = sipAPI()->api_find_type(MetaData<T>::className());
|
||||
if (type == NULL) {
|
||||
if (type == nullptr) {
|
||||
return bpy::incref(Py_None);
|
||||
}
|
||||
|
||||
PyObject *sipObj = sipAPI()->api_convert_from_type(object, type, 0);
|
||||
if (sipObj == NULL) {
|
||||
if (sipObj == nullptr) {
|
||||
return bpy::incref(Py_None);
|
||||
}
|
||||
|
||||
@@ -461,12 +483,12 @@ struct QInterface_converters
|
||||
{
|
||||
static PyObject *convert(const T &object) {
|
||||
const sipTypeDef *type = sipAPI()->api_find_type(MetaData<T>::className());
|
||||
if (type == NULL) {
|
||||
if (type == nullptr) {
|
||||
return bpy::incref(Py_None);
|
||||
}
|
||||
|
||||
PyObject *sipObj = sipAPI()->api_convert_from_type((void*)(&object), type, 0);
|
||||
if (sipObj == NULL) {
|
||||
if (sipObj == nullptr) {
|
||||
return bpy::incref(Py_None);
|
||||
}
|
||||
|
||||
@@ -474,17 +496,17 @@ struct QInterface_converters
|
||||
}
|
||||
|
||||
static PyObject *convert(T *object) {
|
||||
if (object == NULL) {
|
||||
if (object == nullptr) {
|
||||
return bpy::incref(Py_None);
|
||||
}
|
||||
|
||||
const sipTypeDef *type = sipAPI()->api_find_type(MetaData<T>::className());
|
||||
if (type == NULL) {
|
||||
if (type == nullptr) {
|
||||
return bpy::incref(Py_None);
|
||||
}
|
||||
|
||||
PyObject *sipObj = sipAPI()->api_convert_from_type(object, type, 0);
|
||||
if (sipObj == NULL) {
|
||||
if (sipObj == nullptr) {
|
||||
return bpy::incref(Py_None);
|
||||
}
|
||||
|
||||
@@ -556,7 +578,7 @@ struct Functor0_converter
|
||||
{
|
||||
if (!PyCallable_Check(object)
|
||||
|| (getArgCount(object) != 0)) {
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
return object;
|
||||
}
|
||||
@@ -597,7 +619,7 @@ struct Functor2_converter
|
||||
{
|
||||
if (!PyCallable_Check(object)
|
||||
|| (getArgCount(object) != 2)) {
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
return object;
|
||||
}
|
||||
@@ -624,13 +646,13 @@ BOOST_PYTHON_MODULE(mobase)
|
||||
bpy::to_python_converter<QString, QString_to_python_str>();
|
||||
QString_from_python_str();
|
||||
|
||||
QClass_converters<QObject>();
|
||||
//QClass_converters<QObject>();
|
||||
QClass_converters<QWidget>();
|
||||
//QClass_converters<QVariant>();
|
||||
QClass_converters<QIcon>();
|
||||
QInterface_converters<IModRepositoryBridge>();
|
||||
QClass_converters<QStringList>();
|
||||
QInterface_converters<IDownloadManager>();
|
||||
|
||||
|
||||
bpy::def("toPyQt", &toPyQt<IModRepositoryBridge>);
|
||||
bpy::def("toPyQt", &toPyQt<IDownloadManager>);
|
||||
|
||||
@@ -642,6 +664,14 @@ BOOST_PYTHON_MODULE(mobase)
|
||||
.value("prealpha", MOBase::VersionInfo::RELEASE_PREALPHA)
|
||||
;
|
||||
|
||||
bpy::enum_<MOBase::VersionInfo::VersionScheme>("VersionScheme")
|
||||
.value("discover", MOBase::VersionInfo::SCHEME_DISCOVER)
|
||||
.value("regular", MOBase::VersionInfo::SCHEME_REGULAR)
|
||||
.value("decimalmark", MOBase::VersionInfo::SCHEME_DECIMALMARK)
|
||||
.value("numbersandletters", MOBase::VersionInfo::SCHEME_NUMBERSANDLETTERS)
|
||||
.value("date", MOBase::VersionInfo::SCHEME_DATE)
|
||||
;
|
||||
|
||||
bpy::enum_<MOBase::IPluginInstaller::EInstallResult>("InstallResult")
|
||||
.value("success", MOBase::IPluginInstaller::RESULT_SUCCESS)
|
||||
.value("failed", MOBase::IPluginInstaller::RESULT_FAILED)
|
||||
@@ -657,55 +687,72 @@ BOOST_PYTHON_MODULE(mobase)
|
||||
.value("skyrim", MOBase::IGameInfo::TYPE_SKYRIM)
|
||||
;
|
||||
|
||||
bpy::class_<MOBase::VersionInfo>("VersionInfo")
|
||||
.def(bpy::init<int, int, int, MOBase::VersionInfo::ReleaseType>())
|
||||
.def("parse", &MOBase::VersionInfo::parse)
|
||||
.def("canonicalString", &MOBase::VersionInfo::canonicalString)
|
||||
bpy::class_<VersionInfo>("VersionInfo")
|
||||
.def(bpy::init<QString>())
|
||||
.def(bpy::init<QString, VersionInfo::VersionScheme>())
|
||||
.def(bpy::init<int, int, int>())
|
||||
.def(bpy::init<int, int, int, VersionInfo::ReleaseType>())
|
||||
.def("parse", &VersionInfo::parse)
|
||||
.def("canonicalString", &VersionInfo::canonicalString)
|
||||
;
|
||||
|
||||
bpy::class_<MOBase::PluginSetting>("PluginSetting", bpy::init<const QString&, const QString&, const QVariant&>());
|
||||
bpy::class_<PluginSetting>("PluginSetting", bpy::init<const QString&, const QString&, const QVariant&>());
|
||||
|
||||
bpy::class_<IGameInfoWrapper, boost::noncopyable>("GameInfo")
|
||||
.def("type", bpy::pure_virtual(&MOBase::IGameInfo::type))
|
||||
.def("path", bpy::pure_virtual(&MOBase::IGameInfo::path))
|
||||
.def("binaryName", bpy::pure_virtual(&MOBase::IGameInfo::binaryName))
|
||||
.def("type", bpy::pure_virtual(&IGameInfo::type))
|
||||
.def("path", bpy::pure_virtual(&IGameInfo::path))
|
||||
.def("binaryName", bpy::pure_virtual(&IGameInfo::binaryName))
|
||||
;
|
||||
|
||||
bpy::class_<IOrganizerWrapper, boost::noncopyable>("IOrganizer")
|
||||
.def("gameInfo", bpy::pure_virtual(&MOBase::IOrganizer::gameInfo), bpy::return_value_policy<bpy::reference_existing_object>())
|
||||
//.def("createNexusBridge", bpy::pure_virtual(&MOBase::IOrganizer::createNexusBridge), bpy::return_value_policy<bpy::reference_existing_object>())
|
||||
.def("profileName", bpy::pure_virtual(&MOBase::IOrganizer::profileName))
|
||||
.def("profilePath", bpy::pure_virtual(&MOBase::IOrganizer::profilePath))
|
||||
.def("downloadsPath", bpy::pure_virtual(&MOBase::IOrganizer::downloadsPath))
|
||||
.def("appVersion", bpy::pure_virtual(&MOBase::IOrganizer::appVersion))
|
||||
.def("getMod", bpy::pure_virtual(&MOBase::IOrganizer::getMod), bpy::return_value_policy<bpy::reference_existing_object>())
|
||||
.def("createMod", bpy::pure_virtual(&MOBase::IOrganizer::createMod), bpy::return_value_policy<bpy::reference_existing_object>())
|
||||
.def("removeMod", bpy::pure_virtual(&MOBase::IOrganizer::removeMod))
|
||||
.def("modDataChanged", bpy::pure_virtual(&MOBase::IOrganizer::modDataChanged))
|
||||
.def("gameInfo", bpy::pure_virtual(&IOrganizer::gameInfo), bpy::return_value_policy<bpy::reference_existing_object>())
|
||||
.def("createNexusBridge", bpy::pure_virtual(&IOrganizer::createNexusBridge), bpy::return_value_policy<bpy::reference_existing_object>())
|
||||
.def("profileName", bpy::pure_virtual(&IOrganizer::profileName))
|
||||
.def("profilePath", bpy::pure_virtual(&IOrganizer::profilePath))
|
||||
.def("downloadsPath", bpy::pure_virtual(&IOrganizer::downloadsPath))
|
||||
.def("appVersion", bpy::pure_virtual(&IOrganizer::appVersion))
|
||||
.def("getMod", bpy::pure_virtual(&IOrganizer::getMod), bpy::return_value_policy<bpy::reference_existing_object>())
|
||||
.def("createMod", bpy::pure_virtual(&IOrganizer::createMod), bpy::return_value_policy<bpy::reference_existing_object>())
|
||||
.def("removeMod", bpy::pure_virtual(&IOrganizer::removeMod))
|
||||
.def("modDataChanged", bpy::pure_virtual(&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), bpy::return_value_policy<bpy::reference_existing_object>())
|
||||
.def("installMod", bpy::pure_virtual(&IOrganizer::installMod),(bpy::arg("nameSuggestion")=""), 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("modList", bpy::pure_virtual(&IOrganizer::modList), bpy::return_value_policy<bpy::reference_existing_object>())
|
||||
.def("startApplication", bpy::pure_virtual(&IOrganizer::startApplication), bpy::return_value_policy<bpy::return_by_value>())
|
||||
.def("waitForApplication", bpy::pure_virtual(&IOrganizer::waitForApplication), bpy::return_value_policy<bpy::return_by_value>())
|
||||
.def("onAboutToRun", bpy::pure_virtual(&IOrganizer::onAboutToRun))
|
||||
.def("onFinishedRun", bpy::pure_virtual(&IOrganizer::onFinishedRun))
|
||||
.def("onModInstalled", bpy::pure_virtual(&IOrganizer::onModInstalled))
|
||||
.def("refreshModList", bpy::pure_virtual(&IOrganizer::refreshModList))
|
||||
;
|
||||
|
||||
bpy::class_<ModRepositoryBridgeWrapper, boost::noncopyable>("ModRepositoryBridge")
|
||||
.def(bpy::init<IModRepositoryBridge*>())
|
||||
.def("requestDescription", &ModRepositoryBridgeWrapper::requestDescription)
|
||||
.def("requestFiles", &ModRepositoryBridgeWrapper::requestFiles)
|
||||
.def("requestFileInfo", &ModRepositoryBridgeWrapper::requestFileInfo)
|
||||
.def("requestDownloadURL", &ModRepositoryBridgeWrapper::requestDownloadURL)
|
||||
.def("requestToggleEndorsement", &ModRepositoryBridgeWrapper::requestToggleEndorsement)
|
||||
.def("onFilesAvailable", &ModRepositoryBridgeWrapper::onFilesAvailable)
|
||||
.def("onFileInfoAvailable", &ModRepositoryBridgeWrapper::onFileInfoAvailable)
|
||||
.def("onDescriptionAvailable", &ModRepositoryBridgeWrapper::onDescriptionAvailable)
|
||||
.def("onEndorsementToggled", &ModRepositoryBridgeWrapper::onEndorsementToggled)
|
||||
.def("onRequestFailed", &ModRepositoryBridgeWrapper::onRequestFailed)
|
||||
;
|
||||
|
||||
bpy::class_<IModRepositoryBridgeWrapper, boost::noncopyable>("IModRepositoryBridge")
|
||||
.def("requestDescription", bpy::pure_virtual(&IModRepositoryBridge::requestDescription))
|
||||
.def("requestFiles", bpy::pure_virtual(&IModRepositoryBridge::requestFiles))
|
||||
.def("requestFileInfo", bpy::pure_virtual(&IModRepositoryBridge::requestFileInfo))
|
||||
.def("requestDownloadURL", bpy::pure_virtual(&IModRepositoryBridge::requestDownloadURL))
|
||||
.def("requestToggleEndorsement", bpy::pure_virtual(&IModRepositoryBridge::requestToggleEndorsement))
|
||||
;
|
||||
|
||||
bpy::class_<IDownloadManagerWrapper, boost::noncopyable>("IDownloadManager")
|
||||
.def("startDownloadURLs", bpy::pure_virtual(&IDownloadManager::startDownloadURLs))
|
||||
.def("startDownloadNexusFile", bpy::pure_virtual(&IDownloadManager::startDownloadNexusFile))
|
||||
@@ -759,17 +806,23 @@ BOOST_PYTHON_MODULE(mobase)
|
||||
.def("priority", bpy::pure_virtual(&MOBase::IPluginList::priority))
|
||||
.def("loadOrder", bpy::pure_virtual(&MOBase::IPluginList::loadOrder))
|
||||
.def("isMaster", bpy::pure_virtual(&MOBase::IPluginList::isMaster))
|
||||
.def("masters", bpy::pure_virtual(&MOBase::IPluginList::masters))
|
||||
.def("origin", bpy::pure_virtual(&MOBase::IPluginList::origin))
|
||||
.def("onRefreshed", bpy::pure_virtual(&MOBase::IPluginList::onRefreshed))
|
||||
.def("onPluginMoved", bpy::pure_virtual(&MOBase::IPluginList::onPluginMoved))
|
||||
;
|
||||
|
||||
bpy::to_python_converter<IModList::ModStates, QFlags_to_int<IModList::ModState>>();
|
||||
Functor2_converter<const QString&, IModList::ModStates>(); // converter for the onModStateChanged-callback
|
||||
bpy::class_<IModListWrapper, boost::noncopyable>("IModList")
|
||||
.def("displayName", bpy::pure_virtual(&MOBase::IModList::displayName))
|
||||
.def("allMods", bpy::pure_virtual(&MOBase::IModList::allMods))
|
||||
.def("state", bpy::pure_virtual(&MOBase::IModList::state))
|
||||
.def("setActive", bpy::pure_virtual(&MOBase::IModList::setActive))
|
||||
.def("priority", bpy::pure_virtual(&MOBase::IModList::priority))
|
||||
.def("setPriority", bpy::pure_virtual(&MOBase::IModList::setPriority))
|
||||
.def("onModStateChanged", bpy::pure_virtual(&MOBase::IModList::onModStateChanged))
|
||||
.def("onModMoved", bpy::pure_virtual(&MOBase::IModList::onModMoved))
|
||||
;
|
||||
|
||||
GuessedValue_converters<QString>();
|
||||
@@ -790,7 +843,7 @@ PythonRunner::PythonRunner(const MOBase::IOrganizer *moInfo)
|
||||
m_PythonHome = new char[MAX_PATH + 1];
|
||||
}
|
||||
|
||||
static char* argv0 = "ModOrganizer.exe";
|
||||
static const char *argv0 = "ModOrganizer.exe";
|
||||
|
||||
|
||||
bool PythonRunner::initPython(const QString &pythonPath)
|
||||
@@ -804,7 +857,10 @@ bool PythonRunner::initPython(const QString &pythonPath)
|
||||
Py_SetPythonHome(m_PythonHome);
|
||||
}
|
||||
|
||||
Py_SetProgramName(argv0);
|
||||
char argBuffer[MAX_PATH];
|
||||
strcpy(argBuffer, argv0);
|
||||
|
||||
Py_SetProgramName(argBuffer);
|
||||
PyImport_AppendInittab("mobase", &initmobase);
|
||||
Py_OptimizeFlag = 2;
|
||||
Py_NoSiteFlag = 1;
|
||||
@@ -814,7 +870,7 @@ bool PythonRunner::initPython(const QString &pythonPath)
|
||||
return false;
|
||||
}
|
||||
|
||||
PySys_SetArgv(0, &argv0);
|
||||
PySys_SetArgv(0, (char**)&argBuffer);
|
||||
|
||||
bpy::object mainModule = bpy::import("__main__");
|
||||
bpy::object mainNamespace = mainModule.attr("__dict__");
|
||||
@@ -886,7 +942,7 @@ QObject *PythonRunner::instantiate(const QString &pluginName)
|
||||
std::string temp = ToString(pluginName);
|
||||
if (handled_exec_file(temp.c_str(), moduleNamespace)) {
|
||||
reportPythonError();
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
m_PythonObjects[pluginName] = moduleNamespace["createPlugin"]();
|
||||
|
||||
@@ -897,7 +953,7 @@ QObject *PythonRunner::instantiate(const QString &pluginName)
|
||||
qWarning("failed to run python script \"%s\"", qPrintable(pluginName));
|
||||
reportPythonError();
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool PythonRunner::isPythonInstalled() const
|
||||
|
||||
+116
-17
@@ -15,6 +15,9 @@
|
||||
#include <imodrepositorybridge.h>
|
||||
#include <imodinterface.h>
|
||||
#include <iinstallationmanager.h>
|
||||
#include <idownloadmanager.h>
|
||||
#include <ipluginlist.h>
|
||||
#include <imodlist.h>
|
||||
#include "error.h"
|
||||
#include "gilock.h"
|
||||
|
||||
@@ -55,8 +58,6 @@ public:
|
||||
{ m_Wrapped->requestFiles(modID, userData); }
|
||||
void requestFileInfo(int modID, int fileID, QVariant userData)
|
||||
{ m_Wrapped->requestFileInfo(modID, fileID, userData); }
|
||||
void requestDownloadURL(int modID, int fileID, QVariant userData)
|
||||
{ m_Wrapped->requestDownloadURL(modID, fileID, userData); }
|
||||
void requestToggleEndorsement(int modID, bool endorse, QVariant userData)
|
||||
{ m_Wrapped->requestToggleEndorsement(modID, endorse, userData); }
|
||||
|
||||
@@ -67,6 +68,27 @@ public:
|
||||
Qt::UniqueConnection);
|
||||
}
|
||||
|
||||
void onDescriptionAvailable(boost::python::object callback) {
|
||||
m_DescriptionAvailableHandler = callback;
|
||||
connect(m_Wrapped, SIGNAL(descriptionAvailable(int,QVariant,QVariant)),
|
||||
this, SLOT(descriptionAvailable(int,QVariant,QVariant)),
|
||||
Qt::UniqueConnection);
|
||||
}
|
||||
|
||||
void onFileInfoAvailable(boost::python::object callback) {
|
||||
m_FileInfoHandler = callback;
|
||||
connect(m_Wrapped, SIGNAL(fileInfoAvailable(int,int,QVariant,QVariant)),
|
||||
this, SLOT(fileInfoAvailable(int,int,QVariant,QVariant)),
|
||||
Qt::UniqueConnection);
|
||||
}
|
||||
|
||||
void onEndorsementToggled(boost::python::object callback) {
|
||||
m_EndorsementToggledHandler = callback;
|
||||
connect(m_Wrapped, SIGNAL(endorsementToggled(int,QVariant,QVariant)),
|
||||
this, SLOT(endorsementToggled(int,QVariant,QVariant)),
|
||||
Qt::UniqueConnection);
|
||||
}
|
||||
|
||||
void onRequestFailed(boost::python::object callback) {
|
||||
m_FailedHandler = callback;
|
||||
connect(m_Wrapped, SIGNAL(requestFailed(int,int,QVariant,QString)),
|
||||
@@ -90,11 +112,69 @@ private slots:
|
||||
GILock lock;
|
||||
m_FilesAvailableHandler(modID, userData, resultData);
|
||||
} catch (const boost::python::error_already_set&) {
|
||||
// qDebug("error");
|
||||
reportPythonError();
|
||||
}
|
||||
}
|
||||
|
||||
void descriptionAvailable(int modID, QVariant userData, const QVariant resultData)
|
||||
{
|
||||
try {
|
||||
if (m_DescriptionAvailableHandler.is_none()) {
|
||||
qCritical("no handler connected");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
GILock lock;
|
||||
m_DescriptionAvailableHandler(modID, userData, resultData);
|
||||
} catch (const boost::python::error_already_set&) {
|
||||
reportPythonError();
|
||||
}
|
||||
} catch (const std::exception &e) {
|
||||
qCritical("failed to report event: %s", e.what());
|
||||
} catch (...) {
|
||||
qCritical("failed to report event");
|
||||
}
|
||||
}
|
||||
|
||||
void fileInfoAvailable(int modID, int fileID, QVariant userData, const QVariant resultData) {
|
||||
try {
|
||||
if (m_FileInfoHandler.is_none()) {
|
||||
qCritical("no handler connected");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
GILock lock;
|
||||
m_FileInfoHandler(modID, fileID, userData, resultData);
|
||||
} catch (const boost::python::error_already_set&) {
|
||||
reportPythonError();
|
||||
}
|
||||
} catch (const std::exception &e) {
|
||||
qCritical("failed to report event: %s", e.what());
|
||||
} catch (...) {
|
||||
qCritical("failed to report event");
|
||||
}
|
||||
}
|
||||
|
||||
void endorsementToggled(int modID, QVariant userData, const QVariant resultData)
|
||||
{
|
||||
try {
|
||||
if (m_EndorsementToggledHandler.is_none()) {
|
||||
qCritical("no handler connected");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
GILock lock;
|
||||
m_EndorsementToggledHandler(modID, userData, resultData);
|
||||
} catch (const boost::python::error_already_set&) {
|
||||
reportPythonError();
|
||||
}
|
||||
} catch (const std::exception &e) {
|
||||
qCritical("failed to report event: %s", e.what());
|
||||
} catch (...) {
|
||||
qCritical("failed to report event");
|
||||
}
|
||||
}
|
||||
|
||||
void requestFailed(int modID, int fileID, QVariant userData, const QString &errorMessage)
|
||||
{
|
||||
try {
|
||||
@@ -109,24 +189,24 @@ private:
|
||||
|
||||
MOBase::IModRepositoryBridge *m_Wrapped;
|
||||
boost::python::object m_FilesAvailableHandler;
|
||||
boost::python::object m_DescriptionAvailableHandler;
|
||||
boost::python::object m_FileInfoHandler;
|
||||
boost::python::object m_EndorsementToggledHandler;
|
||||
boost::python::object m_FailedHandler;
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct IOrganizerWrapper: MOBase::IOrganizer, boost::python::wrapper<MOBase::IOrganizer>
|
||||
{
|
||||
virtual MOBase::IGameInfo &gameInfo() const {
|
||||
MOBase::IGameInfo *result = this->get_override("gameInfo")();
|
||||
return *result;
|
||||
}
|
||||
virtual MOBase::IModRepositoryBridge *createNexusBridge() const {
|
||||
return this->get_override("createNexusBridge")();
|
||||
}
|
||||
|
||||
virtual MOBase::IModRepositoryBridge *createNexusBridge() const { return this->get_override("createNexusBridge")(); }
|
||||
virtual QString profileName() const { return this->get_override("profileName")(); }
|
||||
virtual QString profilePath() const { return this->get_override("profilePath")(); }
|
||||
virtual QString downloadsPath() const { return this->get_override("downloadsPath")(); }
|
||||
virtual QString overwritePath() const { return this->get_override("overwritePath")(); }
|
||||
virtual MOBase::VersionInfo appVersion() const { return this->get_override("appVersion")(); }
|
||||
virtual MOBase::IModInterface *getMod(const QString &name) { return this->get_override("getMod")(name); }
|
||||
virtual MOBase::IModInterface *createMod(MOBase::GuessedValue<QString> &name) { return this->get_override("createMod")(name); }
|
||||
@@ -137,17 +217,21 @@ struct IOrganizerWrapper: MOBase::IOrganizer, boost::python::wrapper<MOBase::IOr
|
||||
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 MOBase::IModInterface *installMod(const QString &fileName) { return this->get_override("installMod")(fileName); }
|
||||
virtual MOBase::IModInterface *installMod(const QString &fileName, const QString &nameSuggestion = QString()) { return this->get_override("installMod")(fileName, nameSuggestion); }
|
||||
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 QStringList getFileOrigins(const QString &fileName) const { return this->get_override("getFileOrigins")(fileName); }
|
||||
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 bool waitForApplication(HANDLE handle, LPDWORD exitCode = nullptr) const { return this->get_override("waitForApplication")(handle, exitCode); }
|
||||
virtual void refreshModList(bool saveChanges = true) { this->get_override("refreshModList")(saveChanges); }
|
||||
virtual bool onAboutToRun(const std::function<bool(const QString&)> &func) { return this->get_override("onAboutToRun")(func); }
|
||||
virtual bool onFinishedRun(const std::function<void(const QString&, unsigned int)> &func) { return this->get_override("onFinishedRun")(func); }
|
||||
virtual bool onModInstalled(const std::function<void(const QString&)> &func) { return this->get_override("onModInstalled")(func); }
|
||||
};
|
||||
|
||||
struct IDownloadManagerWrapper: MOBase::IDownloadManager, boost::python::wrapper<MOBase::IDownloadManager>
|
||||
@@ -155,8 +239,15 @@ struct IDownloadManagerWrapper: MOBase::IDownloadManager, boost::python::wrapper
|
||||
virtual int startDownloadURLs(const QStringList &urls) { return this->get_override("downloadURLs")(urls); }
|
||||
virtual int startDownloadNexusFile(int modID, int fileID) { return this->get_override("downloadNexusFile")(modID, fileID); }
|
||||
virtual QString downloadPath(int id) { return this->get_override("downloadPath")(id); }
|
||||
private:
|
||||
boost::python::object m_DownloadCompleteHandler;
|
||||
};
|
||||
|
||||
struct IModRepositoryBridgeWrapper: MOBase::IModRepositoryBridge, boost::python::wrapper<MOBase::IModRepositoryBridge>
|
||||
{
|
||||
virtual void requestDescription(int modID, QVariant userData) { this->get_override("requestDescription")(modID, userData); }
|
||||
virtual void requestFiles(int modID, QVariant userData) { this->get_override("requestFiles")(modID, userData); }
|
||||
virtual void requestFileInfo(int modID, int fileID, QVariant userData) { this->get_override("requestFileInfo")(modID, fileID, userData); }
|
||||
virtual void requestDownloadURL(int modID, int fileID, QVariant userData) { this->get_override("requestDownloadURL")(modID, fileID, userData); }
|
||||
virtual void requestToggleEndorsement(int modID, bool endorse, QVariant userData) { this->get_override("requestToggleEndorsement")(modID, endorse, userData); }
|
||||
};
|
||||
|
||||
struct IInstallationManagerWrapper: MOBase::IInstallationManager, boost::python::wrapper<MOBase::IInstallationManager>
|
||||
@@ -181,6 +272,7 @@ struct IModInterfaceWrapper: MOBase::IModInterface, boost::python::wrapper<MOBas
|
||||
virtual void setNewestVersion(const MOBase::VersionInfo &version) { this->get_override("setNewestVersion")(version); }
|
||||
virtual void setIsEndorsed(bool endorsed) { this->get_override("setIsEndorsed")(endorsed); }
|
||||
virtual void setNexusID(int nexusID) { this->get_override("setNexusID")(nexusID); }
|
||||
virtual void setInstallationFile(const QString &fileName) { this->get_override("setInstallationFile")(fileName); }
|
||||
virtual void addNexusCategory(int categoryID) { this->get_override("addNexusCategory")(categoryID); }
|
||||
virtual bool setName(const QString &name) { return this->get_override("setName")(name); }
|
||||
virtual bool remove() { return this->get_override("remove")(); }
|
||||
@@ -188,20 +280,27 @@ struct IModInterfaceWrapper: MOBase::IModInterface, boost::python::wrapper<MOBas
|
||||
|
||||
|
||||
struct IPluginListWrapper: MOBase::IPluginList, boost::python::wrapper<MOBase::IPluginList> {
|
||||
virtual PluginState state(const QString &name) const { return this->get_override("state")(name); }
|
||||
virtual PluginStates state(const QString &name) const { return this->get_override("state")(name); }
|
||||
virtual int priority(const QString &name) const { return this->get_override("priority")(name); }
|
||||
virtual int loadOrder(const QString &name) const { return this->get_override("loadOrder")(name); }
|
||||
virtual bool isMaster(const QString &name) const { return this->get_override("isMaster")(name); }
|
||||
virtual QStringList masters(const QString &name) const { return this->get_override("masters")(name); }
|
||||
virtual QString origin(const QString &name) const { return this->get_override("origin")(name); }
|
||||
virtual bool onRefreshed(const std::function<void ()> &callback) { return this->get_override("onRefreshed")(callback); }
|
||||
virtual bool onPluginMoved(const std::function<void (const QString &, int, int)> &callback) { return this->get_override("onPluginMoved")(callback); }
|
||||
virtual bool onPluginStateChanged(const std::function<void (const QString &, PluginStates)> &callback) override { return this->get_override("onPluginStateChanged")(callback); }
|
||||
};
|
||||
|
||||
|
||||
struct IModListWrapper: MOBase::IModList, boost::python::wrapper<MOBase::IModList> {
|
||||
virtual ModStates state(const QString &name) const{ return this->get_override("state")(name); }
|
||||
virtual int priority(const QString &name) const{ return this->get_override("priority")(name); }
|
||||
virtual bool setPriority(const QString &name, int newPriority){ return this->get_override("setPriority")(name, newPriority); }
|
||||
virtual bool onModStateChanged(const std::function<void (const QString &, ModStates)> &func) { return this->get_override("onModStateChanged")(func); }
|
||||
virtual QString displayName(const QString &internalName) const override { return this->get_override("displayName")(internalName); }
|
||||
virtual QStringList allMods() const override { return this->get_override("allMods")(); }
|
||||
virtual ModStates state(const QString &name) const override { return this->get_override("state")(name); }
|
||||
virtual int priority(const QString &name) const override { return this->get_override("priority")(name); }
|
||||
virtual bool setActive(const QString &name, bool active) override { return this->get_override("setActive")(name, active); }
|
||||
virtual bool setPriority(const QString &name, int newPriority) override { return this->get_override("setPriority")(name, newPriority); }
|
||||
virtual bool onModStateChanged(const std::function<void (const QString &, ModStates)> &func) override { return this->get_override("onModStateChanged")(func); }
|
||||
virtual bool onModMoved(const std::function<void (const QString &, int, int)> &func) override { return this->get_override("onModMoved")(func); }
|
||||
};
|
||||
|
||||
#endif // UIBASEWRAPPERS_H
|
||||
|
||||
Reference in New Issue
Block a user