- 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
This commit is contained in:
Tannin
2013-11-18 20:17:14 +01:00
parent 14fc674d72
commit 0566a968e8
6 changed files with 89 additions and 31 deletions
+41 -19
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,15 +37,15 @@ 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)
{
PythonRunner *result = new PythonRunner(moInfo);
@@ -581,6 +582,7 @@ BOOST_PYTHON_MODULE(mobase)
.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")
@@ -636,6 +638,7 @@ PythonRunner::PythonRunner(const MOBase::IOrganizer *moInfo)
static char* argv0 = "ModOrganizer.exe";
bool PythonRunner::initPython(const QString &pythonPath)
{
try {
@@ -649,21 +652,25 @@ bool PythonRunner::initPython(const QString &pythonPath)
Py_SetProgramName(argv0);
PyImport_AppendInittab("mobase", &initmobase);
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");
@@ -693,26 +700,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);