1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt for Python.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #ifndef PYSIDE_H
41 #define PYSIDE_H
42 
43 #include <sbkpython.h>
44 
45 #include <pysidemacros.h>
46 
47 #ifdef PYSIDE_QML_SUPPORT
48 #  include <QtQml/qqml.h>
49 #endif
50 
51 #include <QtCore/QMetaType>
52 #include <QtCore/QHash>
53 
54 struct SbkObjectType;
55 
56 namespace PySide
57 {
58 
59 PYSIDE_API void init(PyObject *module);
60 
61 /**
62  * Hash function used to enable hash on objects not supported on native Qt library which has toString function.
63  */
64 template<class T>
hash(const T & value)65 inline Py_ssize_t hash(const T& value)
66 {
67     return qHash(value.toString());
68 }
69 
70 /**
71  * Fill QObject properties and do signal connections using the values found in \p kwds dictonary.
72  * \param qObj PyObject fot the QObject.
73  * \param metaObj QMetaObject of \p qObj.
74  * \param blackList keys to be ignored in kwds dictionary, this string list MUST be sorted.
75  * \param blackListSize numbe rof elements in blackList.
76  * \param kwds key->value dictonary.
77  * \return True if everything goes well, false with a Python error setted otherwise.
78  */
79 PYSIDE_API bool fillQtProperties(PyObject *qObj, const QMetaObject *metaObj, PyObject *kwds, const char **blackList, unsigned int blackListSize);
80 
81 /**
82 *   If the type \p T was registered on Qt meta type system with Q_DECLARE_METATYPE macro, this class will initialize
83 *   the meta type.
84 *
85 *   Initialize a meta type means register it on Qt meta type system, Qt itself only do this on the first call of
86 *   qMetaTypeId, and this is exactly what we do to init it. If we don't do that, calls to QMetaType::type("QMatrix2x2")
87 *   could return zero, causing QVariant to not recognize some C++ types, like QMatrix2x2.
88 */
89 template<typename T, bool OK = QMetaTypeId<T>::Defined >
90 struct initQtMetaType {
initQtMetaTypeinitQtMetaType91     initQtMetaType()
92     {
93         qMetaTypeId<T>();
94     }
95 };
96 
97 // Template specialization to do nothing when the type wasn't registered on Qt meta type system.
98 template<typename T>
99 struct initQtMetaType<T, false> {
100 };
101 
102 PYSIDE_API void initDynamicMetaObject(SbkObjectType *type, const QMetaObject *base,
103                                       std::size_t cppObjSize);
104 PYSIDE_API void initQObjectSubType(SbkObjectType *type, PyObject *args, PyObject *kwds);
105 PYSIDE_API void initQApp();
106 
107 /// Return the size in bytes of a type that inherits QObject.
108 PYSIDE_API std::size_t getSizeOfQObject(SbkObjectType *type);
109 
110 typedef void (*CleanupFunction)(void);
111 
112 /**
113  * Register a function to be called before python die
114  */
115 PYSIDE_API void registerCleanupFunction(CleanupFunction func);
116 PYSIDE_API void runCleanupFunctions();
117 
118 /**
119  * Destroy a QCoreApplication taking care of destroy all instances of QObject first.
120  */
121 PYSIDE_API void destroyQCoreApplication();
122 
123 /**
124  * Check for properties and signals registered on MetaObject and return these
125  * \param cppSelf Is the QObject which contains the metaobject
126  * \param self Python object of cppSelf
127  * \param name Name of the argument which the function will try retrieve from MetaData
128  * \return The Python object which contains the Data obtained in metaObject or the Python attribute related with name
129  */
130 PYSIDE_API PyObject *getMetaDataFromQObject(QObject *cppSelf, PyObject *self, PyObject *name);
131 
132 /**
133  * Check if self inherits from class_name
134  * \param self Python object
135  * \param class_name strict with the class name
136  * \return Returns true if self object inherits from class_name, otherwise returns false
137  */
138 PYSIDE_API bool inherits(PyTypeObject *self, const char *class_name);
139 
140 PYSIDE_API void *nextQObjectMemoryAddr();
141 PYSIDE_API void setNextQObjectMemoryAddr(void *addr);
142 
143 PYSIDE_API PyObject *getWrapperForQObject(QObject *cppSelf, SbkObjectType *sbk_type);
144 
145 #ifdef PYSIDE_QML_SUPPORT
146 // Used by QtQuick module to notify QtQml that custom QtQuick items can be registered.
147 typedef bool (*QuickRegisterItemFunction)(PyObject *pyObj, const char *uri, int versionMajor,
148                                  int versionMinor, const char *qmlName,
149                                  QQmlPrivate::RegisterType *);
150 PYSIDE_API QuickRegisterItemFunction getQuickRegisterItemFunction();
151 PYSIDE_API void setQuickRegisterItemFunction(QuickRegisterItemFunction function);
152 #endif // PYSIDE_QML_SUPPORT
153 
154 /**
155  * Given A PyObject repesenting ASCII or Unicode data, returns an equivalent QString.
156  */
157 PYSIDE_API QString pyStringToQString(PyObject *str);
158 
159 /**
160  * Registers a dynamic "qt.conf" file with the Qt resource system.
161  *
162  * This is used in a standalone build, to inform QLibraryInfo of the Qt prefix (where Qt libraries
163  * are installed) so that plugins can be successfully loaded.
164  */
165 PYSIDE_API bool registerInternalQtConf();
166 
167 
168 } //namespace PySide
169 
170 
171 #endif // PYSIDE_H
172 
173