aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside6/PySide6/QtDesigner
diff options
context:
space:
mode:
Diffstat (limited to 'sources/pyside6/PySide6/QtDesigner')
-rw-r--r--sources/pyside6/PySide6/QtDesigner/CMakeLists.txt70
-rw-r--r--sources/pyside6/PySide6/QtDesigner/QtDesigner_global.post.h.in1
-rw-r--r--sources/pyside6/PySide6/QtDesigner/QtDesigner_global.pre.h.in3
-rw-r--r--sources/pyside6/PySide6/QtDesigner/qpydesignercustomwidgetcollection.cpp223
-rw-r--r--sources/pyside6/PySide6/QtDesigner/typesystem_designer.xml103
5 files changed, 400 insertions, 0 deletions
diff --git a/sources/pyside6/PySide6/QtDesigner/CMakeLists.txt b/sources/pyside6/PySide6/QtDesigner/CMakeLists.txt
new file mode 100644
index 000000000..e91532b87
--- /dev/null
+++ b/sources/pyside6/PySide6/QtDesigner/CMakeLists.txt
@@ -0,0 +1,70 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtDesigner)
+
+qt_wrap_cpp(QtDesigner_static_src "${pyside6_SOURCE_DIR}/qpydesignerextensions.h")
+list(APPEND QtDesigner_static_src "${QtDesigner_SOURCE_DIR}/qpydesignercustomwidgetcollection.cpp")
+
+set(QtDesigner_SRC
+${QtDesigner_GEN_DIR}/qabstractextensionfactory_wrapper.cpp
+${QtDesigner_GEN_DIR}/qabstractextensionmanager_wrapper.cpp
+${QtDesigner_GEN_DIR}/qabstractformbuilder_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesigneractioneditorinterface_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignercontainerextension_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignercustomwidgetcollectioninterface_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignercustomwidgetinterface_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignerdnditeminterface_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignerdynamicpropertysheetextension_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignerformeditorinterface_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignerformwindowcursorinterface_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignerformwindowinterface_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignerformwindowmanagerinterface_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignerformwindowtoolinterface_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignermembersheetextension_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignerobjectinspectorinterface_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignerpropertyeditorinterface_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignerpropertysheetextension_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignertaskmenuextension_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignerwidgetboxinterface_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignerwidgetboxinterface_category_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignerwidgetboxinterface_widget_wrapper.cpp
+${QtDesigner_GEN_DIR}/qextensionmanager_wrapper.cpp
+${QtDesigner_GEN_DIR}/qextensionfactory_wrapper.cpp
+${QtDesigner_GEN_DIR}/qformbuilder_wrapper.cpp
+${QtDesigner_GEN_DIR}/qpydesignercustomwidgetcollection_wrapper.cpp
+${QtDesigner_GEN_DIR}/qpydesignercontainerextension_wrapper.cpp
+${QtDesigner_GEN_DIR}/qpydesignermembersheetextension_wrapper.cpp
+${QtDesigner_GEN_DIR}/qpydesignerpropertysheetextension_wrapper.cpp
+${QtDesigner_GEN_DIR}/qpydesignertaskmenuextension_wrapper.cpp
+
+# module is always needed
+${QtDesigner_GEN_DIR}/qtdesigner_module_wrapper.cpp
+)
+
+configure_file("${QtDesigner_SOURCE_DIR}/QtDesigner_global.pre.h.in"
+ "${QtDesigner_BINARY_DIR}/QtDesigner_global.pre.h" @ONLY)
+configure_file("${QtDesigner_SOURCE_DIR}/QtDesigner_global.post.h.in"
+ "${QtDesigner_BINARY_DIR}/QtDesigner_global.post.h" @ONLY)
+
+set(QtDesigner_include_dirs ${QtDesigner_SOURCE_DIR}
+ ${QtDesigner_BINARY_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtGui_GEN_DIR}
+ ${QtWidgets_GEN_DIR})
+
+set(QtDesigner_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}Designer_LIBRARIES})
+
+set(QtDesigner_deps QtWidgets)
+
+create_pyside_module(NAME QtDesigner
+ INCLUDE_DIRS QtDesigner_include_dirs
+ LIBRARIES QtDesigner_libraries
+ DEPS QtDesigner_deps
+ TYPESYSTEM_PATH QtDesigner_SOURCE_DIR
+ SOURCES QtDesigner_SRC
+ STATIC_SOURCES QtDesigner_static_src
+ TYPESYSTEM_NAME ${QtDesigner_BINARY_DIR}/typesystem_designer.xml)
+
+install(FILES ${pyside6_SOURCE_DIR}/qpydesignerextensions.h DESTINATION include/PySide6/QtDesigner)
diff --git a/sources/pyside6/PySide6/QtDesigner/QtDesigner_global.post.h.in b/sources/pyside6/PySide6/QtDesigner/QtDesigner_global.post.h.in
new file mode 100644
index 000000000..e5537a6cf
--- /dev/null
+++ b/sources/pyside6/PySide6/QtDesigner/QtDesigner_global.post.h.in
@@ -0,0 +1 @@
+#include <qpydesignerextensions.h>
diff --git a/sources/pyside6/PySide6/QtDesigner/QtDesigner_global.pre.h.in b/sources/pyside6/PySide6/QtDesigner/QtDesigner_global.pre.h.in
new file mode 100644
index 000000000..195acbaa7
--- /dev/null
+++ b/sources/pyside6/PySide6/QtDesigner/QtDesigner_global.pre.h.in
@@ -0,0 +1,3 @@
+// Not included by the module header
+#include <QtDesigner/QExtensionFactory>
+#include <QtDesigner/QExtensionManager>
diff --git a/sources/pyside6/PySide6/QtDesigner/qpydesignercustomwidgetcollection.cpp b/sources/pyside6/PySide6/QtDesigner/qpydesignercustomwidgetcollection.cpp
new file mode 100644
index 000000000..31f8ec152
--- /dev/null
+++ b/sources/pyside6/PySide6/QtDesigner/qpydesignercustomwidgetcollection.cpp
@@ -0,0 +1,223 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include <qpydesignerextensions.h>
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QVariant>
+
+#include <shiboken.h>
+#include <bindingmanager.h>
+
+QT_BEGIN_NAMESPACE
+
+static QString pyStringToQString(PyObject *s)
+{
+ const char *utf8 = _PepUnicode_AsString(s);
+ return utf8 ? QString::fromUtf8(utf8) : QString();
+}
+
+// Return a string from keyword argument dict
+static QString kwdString(PyObject *kwds, PyObject *key)
+{
+ QString result;
+ if (PyDict_Contains(kwds, key)) {
+ if (auto value = PyDict_GetItem(kwds, key))
+ result = pyStringToQString(value);
+ }
+ return result;
+}
+
+// Return a bool from keyword argument dict
+static bool kwdBool(PyObject *kwds, PyObject *key)
+{
+ bool result = false;
+ if (PyDict_Contains(kwds, key)) {
+ if (auto value = PyDict_GetItem(kwds, key))
+ result = PyObject_IsTrue(value);
+ }
+ return result;
+}
+
+// PyDesignerCustomWidget: A custom widget registered by type
+// (similar to what is done by QUiLoader.registerCustomWidget()).
+class PyDesignerCustomWidget : public QDesignerCustomWidgetInterface
+{
+public:
+ explicit PyDesignerCustomWidget(PyObject *pyTypeObject) :
+ m_pyTypeObject(pyTypeObject) {}
+
+ QString name() const override;
+ QString group() const override { return m_group; }
+ QString toolTip() const override { return m_toolTip; }
+ QString whatsThis() const override { return toolTip(); }
+ QString includeFile() const override { return m_includeFile; }
+ QIcon icon() const override { return m_icon; }
+ bool isContainer() const override { return m_container; }
+
+ QWidget *createWidget(QWidget *parent) override;
+
+ bool isInitialized() const override { return m_core != nullptr; }
+ void initialize(QDesignerFormEditorInterface *core) override;
+
+ QString domXml() const override { return m_domXml; }
+
+ void setGroup(const QString &group) { m_group = group; }
+ void setToolTip(const QString &toolTip) { m_toolTip = toolTip; }
+ void setIncludeFile(const QString &includeFile) { m_includeFile = includeFile; }
+ void setIcon(const QIcon &icon) { m_icon = icon; }
+ void setDomXml(const QString &domXml) { m_domXml = domXml; }
+ void setContainer(bool container) { m_container = container; }
+
+private:
+ const char *utf8Name() const;
+
+ QDesignerFormEditorInterface *m_core = nullptr;
+ QString m_group;
+ QString m_toolTip;
+ QString m_includeFile;
+ QIcon m_icon;
+ QString m_domXml;
+ PyObject *m_pyTypeObject = nullptr;
+ bool m_container = false;
+};
+
+const char *PyDesignerCustomWidget::utf8Name() const
+{
+ return reinterpret_cast<PyTypeObject *>(m_pyTypeObject)->tp_name;
+}
+
+QString PyDesignerCustomWidget::name() const
+{
+ return QString::fromUtf8(utf8Name());
+}
+
+QWidget *PyDesignerCustomWidget::createWidget(QWidget *parent)
+{
+ // This is a copy of the similar function used for QUiLoader
+ // (see sources/pyside6/plugins/uitools/customwidget.cpp)
+ // Create a python instance and return cpp object
+ PyObject *pyParent = nullptr;
+ bool unknownParent = false;
+ if (parent) {
+ pyParent = reinterpret_cast<PyObject *>(Shiboken::BindingManager::instance().retrieveWrapper(parent));
+ if (pyParent) {
+ Py_INCREF(pyParent);
+ } else {
+ static Shiboken::Conversions::SpecificConverter converter("QWidget*");
+ pyParent = converter.toPython(&parent);
+ unknownParent = true;
+ }
+ } else {
+ Py_INCREF(Py_None);
+ pyParent = Py_None;
+ }
+
+ Shiboken::AutoDecRef pyArgs(PyTuple_New(1));
+ PyTuple_SET_ITEM(pyArgs, 0, pyParent); // tuple will keep pyParent reference
+
+ // Call python constructor
+ auto result = reinterpret_cast<SbkObject *>(PyObject_CallObject(m_pyTypeObject, pyArgs));
+ if (!result) {
+ qWarning("Unable to create a Python custom widget of type \"%s\".", utf8Name());
+ PyErr_Print();
+ return nullptr;
+ }
+
+ if (unknownParent) // if parent does not exist in python, transfer the ownership to cpp
+ Shiboken::Object::releaseOwnership(result);
+ else
+ Shiboken::Object::setParent(pyParent, reinterpret_cast<PyObject *>(result));
+
+ return reinterpret_cast<QWidget *>(Shiboken::Object::cppPointer(result, Py_TYPE(result)));
+}
+
+void PyDesignerCustomWidget::initialize(QDesignerFormEditorInterface *core)
+{
+ m_core = core;
+}
+
+// QPyDesignerCustomWidgetCollection: A QDesignerCustomWidgetCollectionInterface
+// implementation that is instantiated as a singleton and stored as a dynamic
+// property of QCoreApplication. The PySide Designer plugin retrieves it from
+// there. Provides static convenience functions for registering types
+// or adding QDesignerCustomWidgetInterface instances.
+
+static QPyDesignerCustomWidgetCollection *collectionInstance = nullptr;
+
+static const char propertyName[] = "__qt_PySideCustomWidgetCollection";
+
+static void cleanup()
+{
+ delete collectionInstance;
+ collectionInstance = nullptr;
+}
+
+QPyDesignerCustomWidgetCollection::QPyDesignerCustomWidgetCollection() = default;
+
+QPyDesignerCustomWidgetCollection::~QPyDesignerCustomWidgetCollection()
+{
+ qDeleteAll(m_customWidgets);
+}
+
+QList<QDesignerCustomWidgetInterface *> QPyDesignerCustomWidgetCollection::customWidgets() const
+{
+ return m_customWidgets;
+}
+
+QPyDesignerCustomWidgetCollection *QPyDesignerCustomWidgetCollection::instance()
+{
+ if (collectionInstance == nullptr) {
+ collectionInstance = new QPyDesignerCustomWidgetCollection();
+ if (auto coreApp = QCoreApplication::instance()) {
+ QDesignerCustomWidgetCollectionInterface *c = collectionInstance;
+ coreApp->setProperty(propertyName, QVariant::fromValue<void *>(c));
+ qAddPostRoutine(cleanup);
+ } else {
+ qWarning("%s: Cannot find QCoreApplication instance.", Q_FUNC_INFO);
+ }
+ }
+ return collectionInstance;
+}
+
+// Register a custom widget by type and optional keyword arguments providing
+// the parameters of QDesignerCustomWidgetInterface.
+bool QPyDesignerCustomWidgetCollection::_registerCustomWidgetHelper(PyObject *typeArg, PyObject *kwds)
+{
+ if (!PyType_Check(typeArg)) {
+ PyErr_SetString(PyExc_TypeError, "registerCustomWidget() requires a type argument.");
+ return false;
+ }
+
+ auto pyCustomWidget = new PyDesignerCustomWidget(typeArg);
+
+ static PyObject *xmlKey = Shiboken::String::createStaticString("xml");
+ pyCustomWidget->setDomXml(kwdString(kwds, xmlKey));
+ static PyObject *toolTipKey = Shiboken::String::createStaticString("tool_tip");
+ pyCustomWidget->setToolTip(kwdString(kwds, toolTipKey));
+ static PyObject *groupKey = Shiboken::String::createStaticString("group");
+ pyCustomWidget->setGroup(kwdString(kwds, groupKey));
+ static PyObject *moduleKey = Shiboken::String::createStaticString("module");
+ pyCustomWidget->setIncludeFile(kwdString(kwds, moduleKey));
+ static PyObject *containerKey = Shiboken::String::createStaticString("container");
+ pyCustomWidget->setContainer(kwdBool(kwds, containerKey));
+ static PyObject *iconKey = Shiboken::String::createStaticString("icon");
+ const QString iconPath = kwdString(kwds, iconKey);
+ if (!iconPath.isEmpty()) {
+ QIcon icon(iconPath);
+ if (icon.availableSizes().isEmpty())
+ qWarning("%s: Cannot load icon from '%s'.", __FUNCTION__, qPrintable(iconPath));
+ else
+ pyCustomWidget->setIcon(icon);
+ }
+
+ addCustomWidget(pyCustomWidget);
+ return true;
+}
+
+void QPyDesignerCustomWidgetCollection::addCustomWidget(QDesignerCustomWidgetInterface *c)
+{
+ instance()->m_customWidgets.append(c);
+}
+
+QT_END_NAMESPACE
diff --git a/sources/pyside6/PySide6/QtDesigner/typesystem_designer.xml b/sources/pyside6/PySide6/QtDesigner/typesystem_designer.xml
new file mode 100644
index 000000000..7d37cbddf
--- /dev/null
+++ b/sources/pyside6/PySide6/QtDesigner/typesystem_designer.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtDesigner"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no"/>
+
+ <rejection class="qdesigner_internal"/>
+
+ <object-type name="QAbstractExtensionFactory"/>
+ <object-type name="QAbstractExtensionManager"/>
+ <object-type name="QAbstractFormBuilder"/>
+ <object-type name="QDesignerActionEditorInterface"/>
+ <object-type name="QDesignerContainerExtension"/>
+ <object-type name="QDesignerCustomWidgetCollectionInterface"/>
+ <object-type name="QDesignerCustomWidgetInterface">
+ <modify-function signature="createWidget(QWidget*)">
+ <modify-argument index="return">
+ <define-ownership class="native" owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <!-- QDesignerDnDItemInterface has abstract functions dealing with the
+ unexposed DomUI classes, we cannot generate a wrapper. -->
+ <object-type name="QDesignerDnDItemInterface" disable-wrapper="yes">
+ <enum-type name="DropType"/>
+ </object-type>
+ <object-type name="QDesignerDynamicPropertySheetExtension"/>
+ <object-type name="QDesignerFormEditorInterface"/>
+ <object-type name="QDesignerFormWindowCursorInterface">
+ <enum-type name="MoveMode"/>
+ <enum-type name="MoveOperation"/>
+ </object-type>
+ <!-- QDesignerFormWindowInterface has abstract functions dealing with private
+ class QtResourceSet, so, we cannot generate a wrapper. -->
+ <object-type name="QDesignerFormWindowInterface" disable-wrapper="yes">
+ <enum-type name="FeatureFlag" flags="Feature"/>
+ <enum-type name="ResourceFileSaveMode"/>
+ </object-type>
+ <object-type name="QDesignerFormWindowManagerInterface">
+ <enum-type name="Action"/>
+ <enum-type name="ActionGroup"/>
+ </object-type>
+ <object-type name="QDesignerFormWindowToolInterface"/>
+ <object-type name="QDesignerMemberSheetExtension"/>
+ <object-type name="QDesignerObjectInspectorInterface"/>
+ <object-type name="QDesignerPropertyEditorInterface"/>
+ <object-type name="QDesignerPropertySheetExtension"/>
+ <object-type name="QDesignerTaskMenuExtension"/>
+ <object-type name="QDesignerWidgetBoxInterface">
+ <value-type name="Category">
+ <enum-type name="Type"/>
+ </value-type>
+ <value-type name="Widget">
+ <enum-type name="Type"/>
+ </value-type>
+ </object-type>
+ <object-type name="QExtensionManager"/>
+ <object-type name="QExtensionFactory"/>
+ <object-type name="QFormBuilder"/>
+ <object-type name="QPyDesignerCustomWidgetCollection" disable-wrapper="yes">
+ <extra-includes>
+ <include file-name="qpydesignerextensions.h" location="global"/>
+ </extra-includes>
+ <modify-function signature="addCustomWidget(QDesignerCustomWidgetInterface*)">
+ <modify-argument index="1">
+ <define-ownership owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ <!-- Force VARARGS/keyword arguments by giving a default parameters -->
+ <add-function signature='registerCustomWidget(PyObject*@customWidgetType@,const QString&amp; @xml@ = {}, const QString&amp; @tool_tip@ = {}, const QString&amp; @group@ = {}, const QString&amp; @module@ = {}, bool @container@ = false, const QString&amp; @icon@ = {})'
+ return-type='void' static='true'>
+ <inject-code class="target" position="beginning" file="../glue/qtdesigner.cpp" snippet="qtdesigner-registercustomwidget"/>
+ </add-function>
+ </object-type>
+ <object-type name="QPyDesignerContainerExtension">
+ <extra-includes>
+ <include file-name="qpydesignerextensions.h" location="global"/>
+ </extra-includes>
+ </object-type>
+ <object-type name="QPyDesignerMemberSheetExtension">
+ <extra-includes>
+ <include file-name="qpydesignerextensions.h" location="global"/>
+ </extra-includes>
+ </object-type>
+ <object-type name="QPyDesignerPropertySheetExtension">
+ <extra-includes>
+ <include file-name="qpydesignerextensions.h" location="global"/>
+ </extra-includes>
+ </object-type>
+ <object-type name="QPyDesignerTaskMenuExtension">
+ <extra-includes>
+ <include file-name="qpydesignerextensions.h" location="global"/>
+ </extra-includes>
+ </object-type>
+
+ <!-- Suppress all QString */int * out parameters -->
+ <suppress-warning text="^There's no user provided way.*handle the primitive type.*$"/>
+ <suppress-warning text="^.*skipping abstract function.*QtResourceSet.*$"/>
+ <suppress-warning text="^.*skipping abstract function.*DomUI.*$"/>
+</typesystem>