From f494968f459dd9288aa8a40dcc1d360daaf98151 Mon Sep 17 00:00:00 2001 From: Tannin Date: Sat, 13 Jul 2013 10:10:46 +0200 Subject: [PATCH] - some fixes to the refreshing behaviour - "fix" buttons in problems dialog are now actually functional - python proxy now has diagnosis functionality to warn user if correct proxy version is not available - python proxy now has a configurable python path --- src/proxy/proxyPython.pro | 2 +- src/proxy/proxypython.cpp | 103 +++++++++++++++++++++++++++++++++++--- src/proxy/proxypython.h | 25 ++++++++- 3 files changed, 121 insertions(+), 9 deletions(-) diff --git a/src/proxy/proxyPython.pro b/src/proxy/proxyPython.pro index 1cfff7e..6015a64 100644 --- a/src/proxy/proxyPython.pro +++ b/src/proxy/proxyPython.pro @@ -23,7 +23,7 @@ CONFIG(release, debug|release) { DEFINES += PROXYPYTHON_LIBRARY -INCLUDEPATH += "$(BOOSTPATH)" "$$(PYTHONPATH)/include" +INCLUDEPATH += "$(BOOSTPATH)" "$$(PYTHONPATH)/include" "$$(PYTHONPATH)/Lib/site-packages/PyQt4/include" # INCLUDEPATH += "$$(SIPPATH)/siplib" SOURCES += proxypython.cpp \ diff --git a/src/proxy/proxypython.cpp b/src/proxy/proxypython.cpp index a400bac..5a3567d 100644 --- a/src/proxy/proxypython.cpp +++ b/src/proxy/proxypython.cpp @@ -23,6 +23,9 @@ using namespace MOBase; namespace bpy = boost::python; +const char *ProxyPython::s_DownloadPythonURL = "http://www.python.org/download/releases/"; + + MOBase::IOrganizer *s_Organizer = NULL; @@ -590,12 +593,25 @@ static char* argv0 = "ModOrganizer.exe"; ProxyPython::ProxyPython() : m_MOInfo(NULL) +{ + m_PythonHome = new char[MAX_PATH + 1]; +} + +bool ProxyPython::initPython() { try { + QString pythonPath = m_MOInfo->pluginSetting(name(), "python_dir").toString(); + strncpy(m_PythonHome, pythonPath.toUtf8().constData(), MAX_PATH); + if (!pythonPath.isEmpty()) { + Py_SetPythonHome(m_PythonHome); + } + + Py_SetProgramName(argv0); PyImport_AppendInittab("mobase", &initmobase); Py_Initialize(); - qDebug("Python: %s", Py_GetVersion()); - + if (!Py_IsInitialized()) { + return false; + } PySys_SetArgv(0, &argv0); bpy::object main_module = bpy::import("__main__"); @@ -605,6 +621,7 @@ ProxyPython::ProxyPython() bpy::exec("s_ErrIO = cStringIO.StringIO()\n" "sys.stderr = s_ErrIO", main_namespace); + return true; } catch (const bpy::error_already_set&) { qDebug("failed to init python"); PyErr_Print(); @@ -613,6 +630,7 @@ ProxyPython::ProxyPython() } else { qCritical("An unexpected C++ exception was thrown in python code"); } + return false; } } @@ -620,7 +638,7 @@ bool ProxyPython::init(IOrganizer *moInfo) { m_MOInfo = moInfo; s_Organizer = moInfo; - return true; + return initPython(); } QString ProxyPython::name() const @@ -640,17 +658,19 @@ QString ProxyPython::description() const VersionInfo ProxyPython::version() const { - return VersionInfo(1, 0, 0, VersionInfo::RELEASE_FINAL); + return VersionInfo(1, 0, 1, VersionInfo::RELEASE_FINAL); } bool ProxyPython::isActive() const { - return true; + return isPythonInstalled(); } QList ProxyPython::settings() const { - return QList(); + QList result; + result.push_back(PluginSetting("python_dir", "Path to your python installation. Leave empty for auto-detection", Py_GetExecPrefix())); + return result; } QStringList ProxyPython::pluginList(const QString &pluginPath) const @@ -714,6 +734,77 @@ QObject *ProxyPython::instantiate(const QString &pluginName) } +bool ProxyPython::isPythonInstalled() const +{ + return Py_IsInitialized(); +} + + +bool ProxyPython::isPythonVersionSupported() const +{ + const char *version = Py_GetVersion(); + return strstr(version, "2.7") == version; +} + + +std::vector ProxyPython::activeProblems() const +{ + std::vector result; + + if (!isPythonInstalled()) { + result.push_back(PROBLEM_PYTHONMISSING); + } else if (!isPythonVersionSupported()) { + result.push_back(PROBLEM_PYTHONWRONGVERSION); + } + + return result; +} + +QString ProxyPython::shortDescription(unsigned int key) const +{ + switch (key) { + case PROBLEM_PYTHONMISSING: { + return tr("Python not installed or not found"); + } break; + case PROBLEM_PYTHONWRONGVERSION: { + return tr("Python version is incompatible"); + } break; + default: + throw MyException(tr("invalid problem key %1").arg(key)); + } +} + + +QString ProxyPython::fullDescription(unsigned int key) const +{ + switch (key) { + case PROBLEM_PYTHONMISSING: { + return tr("Some plugins require the python interpreter to be installed. " + "These plugins will not even show up in settings->plugins.\n" + "If you want to use those plugins, please install Python 2.7.x from %1.").arg(s_DownloadPythonURL); + } break; + case PROBLEM_PYTHONWRONGVERSION: { + return tr("Your installed python version has a different version than 2.7. " + "Some plugins may not work.
" + "If you have multiple versions of python installed you may have to configure the path to 2.7 " + "in the settings dialog."); + } break; + default: + throw MyException(tr("invalid problem key %1").arg(key)); + } +} + +bool ProxyPython::hasGuidedFix(unsigned int) const +{ + return true; +} + +void ProxyPython::startGuidedFix(unsigned int) const +{ + ::ShellExecuteA(NULL, "open", s_DownloadPythonURL, NULL, NULL, SW_SHOWNORMAL); +} + + #if QT_VERSION < QT_VERSION_CHECK(5,0,0) Q_EXPORT_PLUGIN2(proxyPython, ProxyPython) #endif diff --git a/src/proxy/proxypython.h b/src/proxy/proxypython.h index 286a43a..a5e3a07 100644 --- a/src/proxy/proxypython.h +++ b/src/proxy/proxypython.h @@ -3,17 +3,19 @@ #include +#include #include +#include #ifndef Q_MOC_RUN #include #endif -class ProxyPython : public QObject, MOBase::IPluginProxy +class ProxyPython : public QObject, MOBase::IPluginProxy, MOBase::IPluginDiagnose { Q_OBJECT - Q_INTERFACES(MOBase::IPlugin MOBase::IPluginProxy) + Q_INTERFACES(MOBase::IPlugin MOBase::IPluginProxy MOBase::IPluginDiagnose) #if QT_VERSION >= QT_VERSION_CHECK(5,0,0) Q_PLUGIN_METADATA(IID "org.tannin.ProxyPython" FILE "proxypython.json") #endif @@ -38,12 +40,31 @@ public: */ virtual QWidget *getParentWidget() { return parentWidget(); } +public: // IPluginDiagnose + + virtual std::vector activeProblems() const; + virtual QString shortDescription(unsigned int key) const; + virtual QString fullDescription(unsigned int key) const; + virtual bool hasGuidedFix(unsigned int key) const; + virtual void startGuidedFix(unsigned int key) const; + +private: + + bool initPython(); + bool isPythonInstalled() const; + bool isPythonVersionSupported() const; + private: const MOBase::IOrganizer *m_MOInfo; std::map m_PythonObjects; + static const unsigned int PROBLEM_PYTHONMISSING = 1; + static const unsigned int PROBLEM_PYTHONWRONGVERSION = 2; + static const char *s_DownloadPythonURL; + char *m_PythonHome; + }; #endif // PROXYPYTHON_H