From 77faaf1757c2054adf6a13ff1025621bb86a3934 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 22 May 2017 16:44:51 +0200 Subject: move everying into sources/pyside2 (dev edition) in preparation for a subtree merge. this should not be necessary to do in a separate commit, but git is a tad stupid about following history correctly without it. --- .../PySide2/QtWidgets/glue/qapplication_init.cpp | 80 ++++++++++ .../QtWidgets/glue/qlayout_help_functions.cpp | 161 +++++++++++++++++++++ .../pyside2/PySide2/QtWidgets/glue/qmenu_glue.cpp | 60 ++++++++ .../PySide2/QtWidgets/glue/qmenubar_glue.cpp | 59 ++++++++ .../PySide2/QtWidgets/glue/qtwidgets_qapp.cpp | 49 +++++++ .../PySide2/QtWidgets/glue/qwidget_glue.cpp | 104 +++++++++++++ 6 files changed, 513 insertions(+) create mode 100644 sources/pyside2/PySide2/QtWidgets/glue/qapplication_init.cpp create mode 100644 sources/pyside2/PySide2/QtWidgets/glue/qlayout_help_functions.cpp create mode 100644 sources/pyside2/PySide2/QtWidgets/glue/qmenu_glue.cpp create mode 100644 sources/pyside2/PySide2/QtWidgets/glue/qmenubar_glue.cpp create mode 100644 sources/pyside2/PySide2/QtWidgets/glue/qtwidgets_qapp.cpp create mode 100644 sources/pyside2/PySide2/QtWidgets/glue/qwidget_glue.cpp (limited to 'sources/pyside2/PySide2/QtWidgets/glue') diff --git a/sources/pyside2/PySide2/QtWidgets/glue/qapplication_init.cpp b/sources/pyside2/PySide2/QtWidgets/glue/qapplication_init.cpp new file mode 100644 index 000000000..0de34d9c5 --- /dev/null +++ b/sources/pyside2/PySide2/QtWidgets/glue/qapplication_init.cpp @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of PySide2. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// Borrowed reference to QtWidgets module +extern PyObject* moduleQtWidgets; + +static int QApplicationArgCount; +static char** QApplicationArgValues; +static const char QAPP_MACRO[] = "qApp"; + +bool QApplicationConstructorStart(PyObject* argv) +{ + if (QApplication::instance()) { + PyErr_SetString(PyExc_RuntimeError, "A QApplication instance already exists."); + return false; + } + + return Shiboken::sequenceToArgcArgv(argv, &QApplicationArgCount, &QApplicationArgValues, "PySideApp"); +} + +void QApplicationConstructorEnd(PyObject* self) +{ + // Verify if qApp is in main module + PyObject* globalsDict = PyEval_GetGlobals(); + if (globalsDict) { + PyObject* qAppObj = PyDict_GetItemString(globalsDict, QAPP_MACRO); + if (qAppObj) + PyDict_SetItemString(globalsDict, QAPP_MACRO, self); + } + + PyObject_SetAttrString(moduleQtWidgets, QAPP_MACRO, self); + PySide::registerCleanupFunction(&PySide::destroyQCoreApplication); + Py_INCREF(self); +} + +static void QApplicationConstructor(PyObject* self, PyObject* argv, QApplicationWrapper** cptr) +{ + if (QApplicationConstructorStart(argv)) { + // XXX do we need to support the ApplicationFlags parameter, instead of 0? + *cptr = new QApplicationWrapper(QApplicationArgCount, QApplicationArgValues, 0); + Shiboken::Object::releaseOwnership(reinterpret_cast(self)); + QApplicationConstructorEnd(self); + } +} diff --git a/sources/pyside2/PySide2/QtWidgets/glue/qlayout_help_functions.cpp b/sources/pyside2/PySide2/QtWidgets/glue/qlayout_help_functions.cpp new file mode 100644 index 000000000..e1d2ffc4d --- /dev/null +++ b/sources/pyside2/PySide2/QtWidgets/glue/qlayout_help_functions.cpp @@ -0,0 +1,161 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of PySide2. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +void addLayoutOwnership(QLayout* layout, QLayoutItem* item); +void removeLayoutOwnership(QLayout* layout, QWidget* widget); + +inline QByteArray retrieveObjectName(PyObject* obj) +{ + Shiboken::AutoDecRef objName(PyObject_Str(obj)); + return Shiboken::String::toCString(objName); +} + +inline void addLayoutOwnership(QLayout* layout, QWidget* widget) +{ + //transfer ownership to parent widget + QWidget *lw = layout->parentWidget(); + QWidget *pw = widget->parentWidget(); + + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QWidget*](widget)); + + //Transfer parent to layout widget + if (pw && lw && pw != lw) + Shiboken::Object::setParent(0, pyChild); + + if (!lw && !pw) { + //keep the reference while the layout is orphan + Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget*](layout)); + Shiboken::Object::keepReference(reinterpret_cast(pyParent.object()), retrieveObjectName(pyParent).data(), pyChild, true); + } else { + if (!lw) + lw = pw; + Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget*](lw)); + Shiboken::Object::setParent(pyParent, pyChild); + } +} + +inline void addLayoutOwnership(QLayout* layout, QLayout* other) +{ + //transfer all children widgets from other to layout parent widget + QWidget* parent = layout->parentWidget(); + if (!parent) { + //keep the reference while the layout is orphan + Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QLayout*](layout)); + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayout*](other)); + Shiboken::Object::keepReference(reinterpret_cast(pyParent.object()), retrieveObjectName(pyParent).data(), pyChild, true); + return; + } + + for (int i=0, i_max=other->count(); i < i_max; i++) { + QLayoutItem* item = other->itemAt(i); + if (PyErr_Occurred() || !item) + return; + addLayoutOwnership(layout, item); + } + + Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QLayout*](layout)); + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayout*](other)); + Shiboken::Object::setParent(pyParent, pyChild); +} + +inline void addLayoutOwnership(QLayout* layout, QLayoutItem* item) +{ + if (!item) + return; + + QWidget* w = item->widget(); + if (w) + addLayoutOwnership(layout, w); + else { + QLayout* l = item->layout(); + if (l) + addLayoutOwnership(layout, l); + } + + Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QLayout*](layout)); + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayoutItem*](item)); + Shiboken::Object::setParent(pyParent, pyChild); +} + +static void removeWidgetFromLayout(QLayout* layout, QWidget* widget) +{ + QWidget* parent = widget->parentWidget(); + + if (!parent) { + //remove reference on layout + Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget*](layout)); + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QWidget*](widget)); + Shiboken::Object::removeReference(reinterpret_cast(pyParent.object()), retrieveObjectName(pyParent).data(), pyChild); + } else { + //give the ownership to parent + Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget*](parent)); + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QWidget*](widget)); + Shiboken::Object::setParent(pyParent, pyChild); + } +} + +inline void removeLayoutOwnership(QLayout* layout, QLayoutItem* item) +{ + QWidget* w = item->widget(); + if (w) + removeWidgetFromLayout(layout, w); + else { + QLayout* l = item->layout(); + if (l && item != l) + removeLayoutOwnership(layout, l); + } + + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayoutItem*](item)); + Shiboken::Object::invalidate(pyChild); + Shiboken::Object::setParent(0, pyChild); +} + +inline void removeLayoutOwnership(QLayout* layout, QWidget* widget) +{ + if (!widget) + return; + + for (int i=0, i_max=layout->count(); i < i_max; i++) { + QLayoutItem* item = layout->itemAt(i); + if (PyErr_Occurred() || !item) + return; + if (item->widget() == widget) + removeLayoutOwnership(layout, item); + } +} diff --git a/sources/pyside2/PySide2/QtWidgets/glue/qmenu_glue.cpp b/sources/pyside2/PySide2/QtWidgets/glue/qmenu_glue.cpp new file mode 100644 index 000000000..68e991ce7 --- /dev/null +++ b/sources/pyside2/PySide2/QtWidgets/glue/qmenu_glue.cpp @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of PySide2. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +inline PyObject* addActionWithPyObject(QMenu* self, const QIcon& icon, const QString& text, PyObject* callback, const QKeySequence& shortcut) +{ + QAction* act = new QAction(text, self); + + if (!icon.isNull()) + act->setIcon(icon); + + if (!shortcut.isEmpty()) + act->setShortcut(shortcut); + + self->addAction(act); + + PyObject* pyAct = %CONVERTTOPYTHON[QAction*](act); + Shiboken::AutoDecRef result(PyObject_CallMethod(pyAct, "connect", "OsO", pyAct, SIGNAL(triggered()), callback)); + if (result.isNull()) { + Py_DECREF(pyAct); + return 0; + } + + return pyAct; +} diff --git a/sources/pyside2/PySide2/QtWidgets/glue/qmenubar_glue.cpp b/sources/pyside2/PySide2/QtWidgets/glue/qmenubar_glue.cpp new file mode 100644 index 000000000..15ddfb81a --- /dev/null +++ b/sources/pyside2/PySide2/QtWidgets/glue/qmenubar_glue.cpp @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of PySide2. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +inline PyObject* +addActionWithPyObject(QMenuBar* self, const QString& text, PyObject* callback) +{ + QAction* act = new QAction(text, self); + + self->addAction(act); + + PyObject* pyAct = %CONVERTTOPYTHON[QAction*](act); + PyObject* result = PyObject_CallMethod(pyAct, "connect", "OsO", pyAct, + SIGNAL(triggered(bool)), callback); + + if (result == 0 || result == Py_False) { + if (result) + Py_DECREF(result); + Py_DECREF(pyAct); + return 0; + } + + return pyAct; +} diff --git a/sources/pyside2/PySide2/QtWidgets/glue/qtwidgets_qapp.cpp b/sources/pyside2/PySide2/QtWidgets/glue/qtwidgets_qapp.cpp new file mode 100644 index 000000000..e041c7680 --- /dev/null +++ b/sources/pyside2/PySide2/QtWidgets/glue/qtwidgets_qapp.cpp @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of PySide2. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// Init qApp macro to None. +if (qApp) { + PyObject* pyApp = %CONVERTTOPYTHON[QApplication*](qApp); + Py_INCREF(pyApp); + PyModule_AddObject(module, "qApp", pyApp); +} else { + Py_INCREF(Py_None); + PyModule_AddObject(module, "qApp", Py_None); +} +moduleQtWidgets = module; diff --git a/sources/pyside2/PySide2/QtWidgets/glue/qwidget_glue.cpp b/sources/pyside2/PySide2/QtWidgets/glue/qwidget_glue.cpp new file mode 100644 index 000000000..1dd03a8fc --- /dev/null +++ b/sources/pyside2/PySide2/QtWidgets/glue/qwidget_glue.cpp @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of PySide2. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +static QString retrieveObjectName(PyObject *obj) +{ + Shiboken::AutoDecRef objName(PyObject_Str(obj)); + return QString(Shiboken::String::toCString(objName)); +} + + +/** + * Tranfer objects ownership from layout to widget + **/ +static inline void qwidgetReparentLayout(QWidget *parent, QLayout *layout) +{ + Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget*](parent)); + + for (int i=0; i < layout->count(); i++) { + QLayoutItem* item = layout->itemAt(i); + if (PyErr_Occurred() || !item) + return; + + QWidget* w = item->widget(); + if (w) { + QWidget* pw = w->parentWidget(); + if (pw != parent) { + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QWidget*](w)); + Shiboken::Object::setParent(pyParent, pyChild); + } + } else { + QLayout* l = item->layout(); + if (l) + qwidgetReparentLayout(parent, l); + } + } + + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayout*](layout)); + Shiboken::Object::setParent(pyParent, pyChild); + //remove previous references + Shiboken::Object::keepReference(reinterpret_cast(pyChild.object()), qPrintable(retrieveObjectName(pyChild)), Py_None); +} + +static inline void qwidgetSetLayout(QWidget *self, QLayout *layout) +{ + if (!layout || self->layout()) + return; + + QObject* oldParent = layout->parent(); + if (oldParent && oldParent != self) { + if (oldParent->isWidgetType()) { + // remove old parent policy + Shiboken::AutoDecRef pyLayout(%CONVERTTOPYTHON[QLayout*](layout)); + Shiboken::Object::setParent(Py_None, pyLayout); + } else { + PyErr_Format(PyExc_RuntimeError, "QWidget::setLayout: Attempting to set QLayout \"%s\" on %s \"%s\", when the QLayout already has a parent", + qPrintable(layout->objectName()), self->metaObject()->className(), qPrintable(self->objectName())); + return; + } + } + + if (oldParent != self) { + qwidgetReparentLayout(self, layout); + if (PyErr_Occurred()) + return; + + self->setLayout(layout); + } +} -- cgit v1.2.3