aboutsummaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/pythonextensions/bindingheaders/pythonextensions_extension.h0
-rw-r--r--plugins/pythonextensions/pythonextensions.pro3
-rw-r--r--plugins/pythonextensions/pythonextensionsplugin.cpp96
-rw-r--r--plugins/pythonextensions/pythonextensionsplugin.h14
-rw-r--r--plugins/pythonextensions/pyutil.cpp11
-rw-r--r--plugins/pythonextensions/pyutil.h4
-rw-r--r--plugins/pythonextensions/typesystem_qtcreator.xml3
7 files changed, 84 insertions, 47 deletions
diff --git a/plugins/pythonextensions/bindingheaders/pythonextensions_extension.h b/plugins/pythonextensions/bindingheaders/pythonextensions_extension.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/pythonextensions/bindingheaders/pythonextensions_extension.h
diff --git a/plugins/pythonextensions/pythonextensions.pro b/plugins/pythonextensions/pythonextensions.pro
index c8fe73d..334e029 100644
--- a/plugins/pythonextensions/pythonextensions.pro
+++ b/plugins/pythonextensions/pythonextensions.pro
@@ -24,7 +24,7 @@ include($$IDE_SOURCE_TREE/src/qtcreatorplugin.pri)
# Qt Creator Core bindings
WRAPPED_HEADER = $$PWD/wrappedclasses.h
-WRAPPER_DIR = $$OUT_PWD/PythonExtension/QtCreator
+WRAPPER_DIR = $$OUT_PWD/QtCreator
TYPESYSTEM_FILE = typesystem_qtcreator.xml
TYPESYSTEM_NAME = qtcreator
SHIBOKEN_QT = core gui widgets
@@ -36,6 +36,7 @@ WRAPPED_CLASSES = \
bindingheaders/pythonextensions.h \
bindingheaders/pythonextensions_internal.h \
bindingheaders/pythonextensions_internal_pythonextensionsplugin.h \
+ bindingheaders/pythonextensions_extension.h \
bindingheaders/core.h \
bindingheaders/core_actioncontainer.h \
bindingheaders/core_actionmanager.h \
diff --git a/plugins/pythonextensions/pythonextensionsplugin.cpp b/plugins/pythonextensions/pythonextensionsplugin.cpp
index 3547a59..59b32a1 100644
--- a/plugins/pythonextensions/pythonextensionsplugin.cpp
+++ b/plugins/pythonextensions/pythonextensionsplugin.cpp
@@ -39,6 +39,8 @@
#include <extensionsystem/pluginmanager.h>
#include <extensionsystem/pluginspec.h>
+#include <utils/algorithm.h>
+
#include <QDir>
#include <QIODevice>
#include <QFile>
@@ -131,23 +133,39 @@ QDir PythonExtensionsPlugin::extensionDir()
return extension_dir;
}
-QStringList PythonExtensionsPlugin::extensionList(const bool loadedOnly)
+static QVector<Extension> getExtensionList(const QDir &directory)
{
- if (loadedOnly)
- return m_loadedExtensions;
-
- QDir extension_dir = extensionDir();
- if (!extension_dir.exists())
- return QStringList();
+ if (!directory.exists())
+ return {};
+
+ QStringList entries = directory.entryList(QDir::AllDirs | QDir::NoDotAndDotDot);
+ entries.removeAll("site-packages");
+ entries.removeAll("__pycache__");
+ const QVector<Extension> packageExtensions
+ = Utils::transform<QVector>(entries, [](const QString &entry) {
+ return Extension({entry, false});
+ });
+ const QStringList fileEntries = directory.entryList({"*.py"}, QDir::Files);
+ const QVector<Extension> fileExtensions
+ = Utils::transform<QVector>(fileEntries, [](const QString &entry) {
+ return Extension({entry.left(entry.size() - 3), false});
+ });
+ return packageExtensions + fileExtensions;
+}
- QStringList extension_list = extension_dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot);
- extension_list.removeOne("site-packages");
- return extension_list;
+QVector<Extension> PythonExtensionsPlugin::extensionList()
+{
+ return extensionListRef();
}
-void PythonExtensionsPlugin::flagAsLoaded(const QString &extension)
+QVector<Extension> &PythonExtensionsPlugin::extensionListRef()
{
- m_loadedExtensions << extension;
+ static bool initialized = false;
+ if (!initialized) {
+ m_extensions = getExtensionList(extensionDir());
+ initialized = true;
+ }
+ return m_extensions;
}
QString PythonExtensionsPlugin::pythonPackagePath()
@@ -162,18 +180,21 @@ QString PythonExtensionsPlugin::pythonPackagePath()
void PythonExtensionsPlugin::initializePythonBindings()
{
// Add our custom module directory
- if (extensionDir().exists()) {
+ if (extensionDir().exists())
PyUtil::addToSysPath(extensionDir().path().toStdString());
- PyUtil::addToSysPath(pythonPackagePath().toStdString());
- }
+ // Add directory for local python packages that are installed as requirements of extensions
+ // Need to create it first if it doesn't exist, otherwise python will ignore the path
+ if (!QFile::exists(pythonPackagePath()))
+ QDir().mkpath(pythonPackagePath());
+ PyUtil::addToSysPath(pythonPackagePath().toStdString());
// Initialize the Python context and register global Qt Creator variable
- if (!PyUtil::bindShibokenModuleObject("PythonExtension", "QtCreator")) {
+ if (!PyUtil::bindCoreModules()) {
qWarning() << "Python bindings could not be initialized";
Core::MessageManager::write(Constants::MESSAGE_MANAGER_PREFIX + tr("Python bindings could not be initialized"));
return;
}
// Bind the plugin instance
- PyUtil::bindObject("PythonExtension", "PluginInstance", PyUtil::PythonExtensionsPluginType, this);
+ PyUtil::bindObject("QtCreator", "PythonExtensions", PyUtil::PythonExtensionsPluginType, this);
}
void PythonExtensionsPlugin::initializeOptionalBindings()
@@ -208,16 +229,18 @@ void PythonExtensionsPlugin::installRequirements()
if (!extension_dir.exists())
return;
- QStringList extension_list = extensionList();
- for (const QString &extension : extension_list) {
- QString extension_requirements(extension_dir.absolutePath() + "/" + extension + "/requirements.txt");
- if (QFileInfo::exists(extension_requirements) && !QFileInfo::exists(extension_requirements + ".installed")) {
- if (!PyUtil::pipInstallRequirements(
- extension_requirements.toStdString(),
- pythonPackagePath().toStdString()
- )) {
- qWarning() << "Failed to install requirements for extension" << extension;
- Core::MessageManager::write(Constants::MESSAGE_MANAGER_PREFIX + tr("Failed to install requirements for extension ") + extension);
+ QVector<Extension> extension_list = extensionListRef();
+ for (const Extension &extension : extension_list) {
+ QString extension_requirements(extension_dir.absolutePath() + "/" + extension.name
+ + "/requirements.txt");
+ if (QFileInfo::exists(extension_requirements)
+ && !QFileInfo::exists(extension_requirements + ".installed")) {
+ if (!PyUtil::pipInstallRequirements(extension_requirements.toStdString(),
+ pythonPackagePath().toStdString())) {
+ qWarning() << "Failed to install requirements for extension" << extension.name;
+ Core::MessageManager::write(Constants::MESSAGE_MANAGER_PREFIX
+ + tr("Failed to install requirements for extension ")
+ + extension.name);
}
}
}
@@ -235,22 +258,25 @@ void PythonExtensionsPlugin::initializePythonExtensions()
qDebug() << "Found Python extension directory at location" << extension_dir.absolutePath();
- QStringList extension_list = extensionList();
+ QVector<Extension> &extension_list = extensionListRef();
qDebug() << "Number of Python extensions found:" << extension_list.size();
+ int loadedCount = 0;
// Run the extension initialization code
- for (const QString &extension : extension_list) {
- qDebug() << "Trying to initialize extension" << extension;
- if (!PyUtil::runScript("import " + extension.toStdString())) {
- qWarning() << "Failed to initialize extension" << extension;
- Core::MessageManager::write(Constants::MESSAGE_MANAGER_PREFIX + tr("Failed to initialize extension ") + extension);
+ for (Extension &extension : extension_list) {
+ qDebug() << "Trying to initialize extension" << extension.name;
+ if (PyUtil::runScript("import " + extension.name.toStdString())) {
+ extension.loaded = true;
+ ++loadedCount;
} else {
- m_loadedExtensions << extension;
+ qWarning() << "Failed to initialize extension" << extension.name;
+ Core::MessageManager::write(Constants::MESSAGE_MANAGER_PREFIX
+ + tr("Failed to initialize extension ") + extension.name);
}
}
- qDebug() << "Number of Python extensions loaded:" << m_loadedExtensions.size();
+ qDebug() << "Number of Python extensions loaded:" << loadedCount;
}
} // namespace Internal
diff --git a/plugins/pythonextensions/pythonextensionsplugin.h b/plugins/pythonextensions/pythonextensionsplugin.h
index 29010d4..1a4bce3 100644
--- a/plugins/pythonextensions/pythonextensionsplugin.h
+++ b/plugins/pythonextensions/pythonextensionsplugin.h
@@ -33,6 +33,13 @@
#include <QStringList>
namespace PythonExtensions {
+
+class Extension {
+public:
+ QString name;
+ bool loaded;
+};
+
namespace Internal {
class PythonExtensionsPlugin : public ExtensionSystem::IPlugin
@@ -50,15 +57,16 @@ public:
ShutdownFlag aboutToShutdown() final;
QDir extensionDir();
- QStringList extensionList(const bool loadedOnly = false);
- void flagAsLoaded(const QString &extension);
+ QVector<Extension> extensionList();
QString pythonPackagePath();
+
private:
- QStringList m_loadedExtensions;
void initializePythonBindings();
void initializeOptionalBindings();
void installRequirements();
void initializePythonExtensions();
+ QVector<Extension> &extensionListRef();
+ QVector<Extension> m_extensions;
};
// Util functions
diff --git a/plugins/pythonextensions/pyutil.cpp b/plugins/pythonextensions/pyutil.cpp
index b563c55..b992e36 100644
--- a/plugins/pythonextensions/pyutil.cpp
+++ b/plugins/pythonextensions/pyutil.cpp
@@ -56,10 +56,10 @@ extern "C" void initQtCreator();
// These variables store all Python types exported by QtCreators bindings,
// as well as the types exported for QtWidgets.
-extern PyTypeObject **SbkPythonExtension_QtCreatorTypes;
+extern PyTypeObject **SbkQtCreatorTypes;
// This variable stores the Python module generated by Shiboken
-extern PyObject *SbkPythonExtension_QtCreatorModuleObject;
+extern PyObject *SbkQtCreatorModuleObject;
namespace PyUtil {
@@ -157,7 +157,7 @@ bool bindObject(const QString &moduleName, const QString &name, int index, void
return false;
// Generate the type
- PyTypeObject *typeObject = SbkPythonExtension_QtCreatorTypes[index];
+ PyTypeObject *typeObject = SbkQtCreatorTypes[index];
PyObject *po = Shiboken::Conversions::pointerToPython(reinterpret_cast<SbkObjectType *>(typeObject), o);
if (!po) {
@@ -169,9 +169,10 @@ bool bindObject(const QString &moduleName, const QString &name, int index, void
return bindPyObject(moduleName, name, po);
}
-bool bindShibokenModuleObject(const QString &moduleName, const QString &name)
+bool bindCoreModules()
{
- return bindPyObject(moduleName, name, SbkPythonExtension_QtCreatorModuleObject);
+ return bindSubPyObject("QtCreator", "Utils", SbkQtCreatorModuleObject)
+ && bindSubPyObject("QtCreator", "Core", SbkQtCreatorModuleObject);
}
bool bindPyObject(const QString &moduleName, const QString &name, void *obj)
diff --git a/plugins/pythonextensions/pyutil.h b/plugins/pythonextensions/pyutil.h
index 62a1622..ca58f6e 100644
--- a/plugins/pythonextensions/pyutil.h
+++ b/plugins/pythonextensions/pyutil.h
@@ -37,7 +37,7 @@ namespace PyUtil {
// Note: If modifying the bindings, check these types still align
enum QtCreatorTypes
{
- PythonExtensionsPluginType = 33, // SBK_PYTHONEXTENSIONS_INTERNAL_PYTHONEXTENSIONSPLUGIN_IDX
+ PythonExtensionsPluginType = 34, // SBK_PYTHONEXTENSIONS_INTERNAL_PYTHONEXTENSIONSPLUGIN_IDX
};
enum State
@@ -53,7 +53,7 @@ PYTHONEXTENSIONSSHARED_EXPORT bool createModule(const std::string &moduleName);
bool bindObject(const QString &moduleName, const QString &name, int index, void *o);
-bool bindShibokenModuleObject(const QString &moduleName, const QString &name);
+bool bindCoreModules();
PYTHONEXTENSIONSSHARED_EXPORT bool bindPyObject(const QString &moduleName, const QString &name, void *obj);
diff --git a/plugins/pythonextensions/typesystem_qtcreator.xml b/plugins/pythonextensions/typesystem_qtcreator.xml
index 736fe44..69f051e 100644
--- a/plugins/pythonextensions/typesystem_qtcreator.xml
+++ b/plugins/pythonextensions/typesystem_qtcreator.xml
@@ -41,12 +41,13 @@
-->
<!-- Typesystem for Qt Creator Python host plugin -->
-<typesystem package="PythonExtension.QtCreator">
+<typesystem package="QtCreator">
<!-- Load PySide QtWidgets typesystem (is this correct? yup) -->
<load-typesystem name="typesystem_widgets.xml" generate="no"/>
<namespace-type name="PythonExtensions">
+ <value-type name="Extension"/>
<namespace-type name="Internal">
<object-type name="PythonExtensionsPlugin"/>
</namespace-type>