diff options
author | Tilman Roeder <tilman.roder@qt.io> | 2018-08-03 09:38:07 +0200 |
---|---|---|
committer | Tilman Roeder <tilman.roder@qt.io> | 2018-08-15 10:10:16 +0000 |
commit | 13e02b9aaea19ac21251d152a8fa69336ae76ebd (patch) | |
tree | a6320449c18251033d3a2557afaed6a8fcafbfc9 /optional | |
parent | efea0c2e4a2966d88f65cdab90f841f7905dee14 (diff) |
Initial commit
This is a quite large commit containing:
* The main extension that runs and initializes Python
* Some (example) bindings
* An initial build script for the main extension
* Optional binding and examples of how to create them
* An initial build script for the optional bindings
* A simple extension manager written in Python
* A few example Python extensions
* Some documentation (both in the code and as markdown files)
* A collection of helpful python scripts
* A small collection of unit tests
* A TODO list
For any additional details the code / docs should be consulted.
Change-Id: I3937886cfefa2f64d5a78013889a8e097eec8261
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Diffstat (limited to 'optional')
23 files changed, 758 insertions, 0 deletions
diff --git a/optional/README.md b/optional/README.md new file mode 100644 index 0000000..2c5af5d --- /dev/null +++ b/optional/README.md @@ -0,0 +1,34 @@ +# Optional Bindings + +This directory contains all optional bindings for QtCreator +Modules that are bundled with this plugin. + +Optional bindings come in the form of dynamically loaded libraries, +each binding has its own folder. The template directory contains files +that are shared for each binding. + +## Documentation + +### Building +If your environment is setup correctly (i.e. you can build the Python Extensions plugin), all that +you should need to do is run: + +``` +python setup.py --qmake=/path/to/your/qmake +``` + +and the optional bindings should build and be installed. To clean the build files after a build, +just run: + +``` +python setup.py clean +``` + +For problems and possible solutions, please refer to the main `README.md`. + +### Writing optional binding libraries +**NOTICE:** Please refer to the `pyutil.h` header file for anything that is not explained +here. + +Each library project here must include a `binding.cpp` file which must implement +a function with the signature `void bind();`. diff --git a/optional/projectexplorer/binding.cpp b/optional/projectexplorer/binding.cpp new file mode 100644 index 0000000..a544beb --- /dev/null +++ b/optional/projectexplorer/binding.cpp @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Python Extensions Plugin for QtCreator. +** +** 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 General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** 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-3.0.html. +** +****************************************************************************/ + +#include "binding.h" + +#include <QtCore/QDebug> +#include <QtCore/QString> + +#undef signals +#undef slots + +#include <sbkpython.h> +#include <sbkconverter.h> +#include <sbkmodule.h> + +#if PY_MAJOR_VERSION >= 3 +extern "C" PyObject *PyInit_QtCreatorBindingProjectExplorer(); +#else +extern "C" void initQtCreatorBindingProjectExplorer(); +#endif + +extern PyObject *SbkQtCreatorBindingProjectExplorerModuleObject; + +namespace PyUtil { + extern bool bindSubPyObject(const QString &moduleName, const QString &name, void *obj); +} + +void bind() +{ + // Init module + #if PY_MAJOR_VERSION >= 3 + const bool pythonInitialized = PyInit_QtCreatorBindingProjectExplorer() != nullptr; + #else + const bool pythonInitialized = true; + initQtCreatorBindingProjectExplorer(); + #endif + // Bind module into interpreter + bool pythonError = PyErr_Occurred() != nullptr; + if (pythonInitialized && !pythonError) { + PyUtil::bindSubPyObject("PythonExtension.QtCreator", "ProjectExplorer", (void *)SbkQtCreatorBindingProjectExplorerModuleObject); + } else { + if (pythonError) + PyErr_Print(); + qDebug() << "There was a problem initializing the ProjectExplorer bindings."; + + } +} diff --git a/optional/projectexplorer/binding_custom.pri b/optional/projectexplorer/binding_custom.pri new file mode 100644 index 0000000..b9e3faf --- /dev/null +++ b/optional/projectexplorer/binding_custom.pri @@ -0,0 +1,57 @@ +# Additional sources + +SOURCES += \ + # optional + +HEADERS += \ + # optional + + +# Declare dependencies and name + +# This has to be PythonBinding{PluginName} +QTC_PLUGIN_NAME = PythonBindingProjectExplorer +QTC_LIB_DEPENDS += \ + extensionsystem \ + utils + +QTC_PLUGIN_DEPENDS += \ + coreplugin \ + projectexplorer \ + pythonextensions + +QTC_PLUGIN_RECOMMENDS += \ + # optional plugin dependencies. nothing here at this time + + +# Shiboken binding generation setup + +WRAPPED_HEADER = wrappedclasses.h +WRAPPER_DIR = $$OUT_PWD/QtCreatorBindingProjectExplorer +TYPESYSTEM_FILE = typesystem_projectexplorer.xml + +TYPESYSTEM_NAME = qtcreatorbindingprojectexplorer + +## Include additional QtCreator paths +QT_INCLUDEPATHS += \ + -I"$$IDE_SOURCE_TREE/src/plugins/projectexplorer" + +INCLUDEPATH += \ + $$IDE_SOURCE_TREE/src/plugins/projectexplorer \ + $$IDE_SOURCE_TREE/src/libs/utils + +## These headers are needed so the generated wrappers are added to the +## build. Right now they are empty files, however there might be a more elegant +## option. +WRAPPED_CLASSES = \ + bindingheaders/projectexplorer.h \ + bindingheaders/projectexplorer_buildconfiguration.h \ + bindingheaders/projectexplorer_projectconfiguration.h \ + bindingheaders/projectexplorer_statefulprojectconfiguration.h \ + # bindingheaders/projectexplorer_ibuildconfigurationfactory.h \ + bindingheaders/projectexplorer_runconfiguration.h \ + bindingheaders/projectexplorer_project.h \ + bindingheaders/projectexplorer_projecttree.h \ + bindingheaders/utils.h \ + bindingheaders/utils_filename.h \ +# Sentinel line diff --git a/optional/projectexplorer/bindingheaders/projectexplorer.h b/optional/projectexplorer/bindingheaders/projectexplorer.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/optional/projectexplorer/bindingheaders/projectexplorer.h diff --git a/optional/projectexplorer/bindingheaders/projectexplorer_buildconfiguration.h b/optional/projectexplorer/bindingheaders/projectexplorer_buildconfiguration.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/optional/projectexplorer/bindingheaders/projectexplorer_buildconfiguration.h diff --git a/optional/projectexplorer/bindingheaders/projectexplorer_ibuildconfigurationfactory.h b/optional/projectexplorer/bindingheaders/projectexplorer_ibuildconfigurationfactory.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/optional/projectexplorer/bindingheaders/projectexplorer_ibuildconfigurationfactory.h diff --git a/optional/projectexplorer/bindingheaders/projectexplorer_project.h b/optional/projectexplorer/bindingheaders/projectexplorer_project.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/optional/projectexplorer/bindingheaders/projectexplorer_project.h diff --git a/optional/projectexplorer/bindingheaders/projectexplorer_projectconfiguration.h b/optional/projectexplorer/bindingheaders/projectexplorer_projectconfiguration.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/optional/projectexplorer/bindingheaders/projectexplorer_projectconfiguration.h diff --git a/optional/projectexplorer/bindingheaders/projectexplorer_projecttree.h b/optional/projectexplorer/bindingheaders/projectexplorer_projecttree.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/optional/projectexplorer/bindingheaders/projectexplorer_projecttree.h diff --git a/optional/projectexplorer/bindingheaders/projectexplorer_runconfiguration.h b/optional/projectexplorer/bindingheaders/projectexplorer_runconfiguration.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/optional/projectexplorer/bindingheaders/projectexplorer_runconfiguration.h diff --git a/optional/projectexplorer/bindingheaders/projectexplorer_statefulprojectconfiguration.h b/optional/projectexplorer/bindingheaders/projectexplorer_statefulprojectconfiguration.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/optional/projectexplorer/bindingheaders/projectexplorer_statefulprojectconfiguration.h diff --git a/optional/projectexplorer/bindingheaders/utils.h b/optional/projectexplorer/bindingheaders/utils.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/optional/projectexplorer/bindingheaders/utils.h diff --git a/optional/projectexplorer/bindingheaders/utils_filename.h b/optional/projectexplorer/bindingheaders/utils_filename.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/optional/projectexplorer/bindingheaders/utils_filename.h diff --git a/optional/projectexplorer/typesystem_projectexplorer.xml b/optional/projectexplorer/typesystem_projectexplorer.xml new file mode 100644 index 0000000..b663619 --- /dev/null +++ b/optional/projectexplorer/typesystem_projectexplorer.xml @@ -0,0 +1,72 @@ +<?xml version="1.0"?> +<!-- +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Python Extensions Plugin for QtCreator. +** +** $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$ +** +****************************************************************************/ +--> + +<!-- Typesystem for Qt Creator Python host plugin --> +<typesystem package="QtCreatorBindingProjectExplorer"> + + <!-- Load PySide QtWidgets typesystem (is this correct? yup) --> + <load-typesystem name="typesystem_widgets.xml" generate="no"/> + <!-- Currently there are problems with getting this to work ... --> + <!-- <load-typesystem name="../../plugins/pythonextensions/typesystem_qtcreator.xml" generate="no"/> --> + + <namespace-type name="ProjectExplorer"> + <object-type name="BuildConfiguration"> + <enum-type name="BuildType"/> + </object-type> + <object-type name="ProjectConfiguration"/> + <object-type name="RunConfiguration"> + <enum-type name="ConfigurationState"/> + </object-type> + <object-type name="StatefulProjectConfiguration"/> + <object-type name="ProjectTree"/> + <object-type name="Project"> + <enum-type name="ModelRoles"/> + <enum-type name="RestoreResult"/> + </object-type> + </namespace-type> + + <namespace-type name="Utils"> + <value-type name="FileName"/> + <modify-function signature="operator<<(QTextStream&,Utils::FileName)" remove="all"/> + </namespace-type> + +</typesystem> diff --git a/optional/projectexplorer/wrappedclasses.h b/optional/projectexplorer/wrappedclasses.h new file mode 100644 index 0000000..2d043bb --- /dev/null +++ b/optional/projectexplorer/wrappedclasses.h @@ -0,0 +1,37 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Python Extensions Plugin for QtCreator. +** +** 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 General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** 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-3.0.html. +** +****************************************************************************/ + +#ifndef WRAPPEDCLASSES_H +#define WRAPPEDCLASSES_H + +#include <QAbstractSocket> + +#include <projectexplorer/buildconfiguration.h> +#include <projectexplorer/projectconfiguration.h> +#include <projectexplorer/runconfiguration.h> +#include <projectexplorer/project.h> +#include <projectexplorer/projecttree.h> + +#endif // header end diff --git a/optional/setup.py b/optional/setup.py new file mode 100644 index 0000000..c0f6f43 --- /dev/null +++ b/optional/setup.py @@ -0,0 +1,139 @@ +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Python Extensions Plugin for QtCreator. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +# Assemble the binding projects and build them + +# You need to specify the correct qmake when running: +# $ python setup.py --qmake=/path/to/qmake +# (defaults to "qmake") + +# You can also specify a binding to build: +# $ python setup.py --only=bindingname +# (default is to build all) + +# You can clean the build directories with +# $ python setup.py clean + +import os, shutil, subprocess, sys + + +def qmake(): + for arg in sys.argv: + if arg.split("=")[0] == "--qmake": + return arg.split("=")[-1] + return "qmake" + +def only(): + for arg in sys.argv: + if arg.split("=")[0] == "--only": + return arg.split("=")[-1] + return False + +def copytree(src, dst, symlinks=False, ignore=None): + for item in os.listdir(src): + s = os.path.join(src, item) + d = os.path.join(dst, item) + if os.path.isdir(s): + shutil.copytree(s, d, symlinks, ignore) + else: + shutil.copy2(s, d) + +def generate_build_deps(): + if os.path.exists("build_deps"): + shutil.rmtree("build_deps") + # Plugin dependencies .pri file + os.makedirs("build_deps/pythonextensions") + shutil.copy2( + "../plugins/pythonextensions/pythonextensions_dependencies.pri", + "build_deps/pythonextensions/pythonextensions_dependencies.pri" + ) + +def generate_build_dir(binding_name): + build_dir = "build_{}".format(binding_name) + if os.path.exists(build_dir): + shutil.rmtree(build_dir) + os.makedirs(build_dir) + copytree("template", build_dir) + copytree(binding_name, build_dir) + +def run_build(binding_name): + build_dir = "build_{}".format(binding_name) + if os.path.exists(build_dir): + try: + subprocess.check_call(qmake(), cwd=build_dir) + subprocess.check_call("make", cwd=build_dir) + except Exception as e: + print("Got exception when building {}:".format(binding_name), e) + return False + return True + return False + +def clean_build_dirs(): + for build_dir in os.scandir(): + if build_dir.is_dir() and build_dir.name.split("_")[0] == "build": + shutil.rmtree(build_dir.name) + print("Removing {}".format(build_dir.name)) + +def main(): + generate_build_deps() + if only(): + generate_build_dir(only()) + if run_build(only()): + print("Built {}".format(only())) + else: + print("Error building {}".format(only())) + print("Skipping other builds") + return + final_message = "Summary:" + for binding in os.scandir(): + if binding.is_dir() and binding.name != "template" and binding.name.split("_")[0] != "build": + generate_build_dir(binding.name) + if run_build(binding.name): + final_message += "\nBuilt {}".format(binding.name) + else: + final_message += "\nError building {}".format(binding.name) + print(final_message) + + +if __name__ == "__main__": + if "clean" in sys.argv: + clean_build_dirs() + else: + main() diff --git a/optional/template/binding.h b/optional/template/binding.h new file mode 100644 index 0000000..9b397a1 --- /dev/null +++ b/optional/template/binding.h @@ -0,0 +1,30 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Python Extensions Plugin for QtCreator. +** +** 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 General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** 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-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include <QtGlobal> + +extern "C" Q_DECL_EXPORT void bind(); diff --git a/optional/template/binding.pro b/optional/template/binding.pro new file mode 100644 index 0000000..57be22b --- /dev/null +++ b/optional/template/binding.pro @@ -0,0 +1,87 @@ +# NOTE: This is not yet properly tested on general systems +# and will (if at all) probably only work on a linux environment + +PYTHON = python +DEFINES += PYTHONEXTENSIONS_LIBRARY + +# PythonExtensions files + +SOURCES += \ + binding.cpp + +HEADERS += \ + binding.h + + +# Qt Creator linking + +# Shared QtCreator sources and build destination +# (these are shared with the main plugin) +include(../../plugins/pythonextensions/qtcreator.pri) + +## Include Qt and QtCreator paths +QT_INCLUDEPATHS = -I"$$[QT_INSTALL_HEADERS]" -I"$$[QT_INSTALL_HEADERS]/QtCore" \ + -I"$$[QT_INSTALL_HEADERS]/QtGui" -I"$$[QT_INSTALL_HEADERS]/QtWidgets" \ + -I"$$[QT_INSTALL_HEADERS]/QtNetwork" \ + -I"$$IDE_SOURCE_TREE/src/plugins" \ + -I"$$IDE_SOURCE_TREE/src/libs" + +# Custom Buildsystem setup per binding +include(binding_custom.pri) + +# Add the build dependencies directory, which will contain dependencies +# related to the python extensions plugin +QTC_PLUGIN_DIRS += $${WRAPPER_DIR}/../../build_deps/ +include($$IDE_SOURCE_TREE/src/qtcreatorplugin.pri) + +# Shiboken stuff + +# This setup is currently only tested on Linux + +include(../../plugins/pythonextensions/pyside2.pri) + +SHIBOKEN_OPTIONS = --generator-set=shiboken --enable-parent-ctor-heuristic \ + --enable-pyside-extensions --enable-return-value-heuristic --use-isnull-as-nb_nonzero \ + $$QT_INCLUDEPATHS -I$$PWD -T$$PWD -T$$PYSIDE2/typesystems --output-directory=$$OUT_PWD + +## Prepare the shiboken tool +QT_TOOL.shiboken.binary = $$system_path($$PYSIDE2/shiboken2) +qtPrepareTool(SHIBOKEN, shiboken) + +## Shiboken run that adds the module wrapper to GENERATED_SOURCES +shiboken.output = $$WRAPPER_DIR/$${TYPESYSTEM_NAME}_module_wrapper.cpp +shiboken.commands = $$SHIBOKEN $$SHIBOKEN_OPTIONS $$PWD/$$WRAPPED_HEADER ${QMAKE_FILE_IN} +shiboken.input = TYPESYSTEM_FILE +shiboken.dependency_type = TYPE_C +shiboken.variable_out = GENERATED_SOURCES + +module_wrapper_dummy_command.output = $$WRAPPER_DIR/${QMAKE_FILE_BASE}_wrapper.cpp +module_wrapper_dummy_command.commands = echo ${QMAKE_FILE_IN} +module_wrapper_dummy_command.depends = $$WRAPPER_DIR/$${TYPESYSTEM_NAME}_module_wrapper.cpp +module_wrapper_dummy_command.input = WRAPPED_CLASSES +module_wrapper_dummy_command.dependency_type = TYPE_C +module_wrapper_dummy_command.variable_out = GENERATED_SOURCES + +## Get the path component to the active config build folder +defineReplace(getOutDir) { + out_dir = $$OUT_PWD + CONFIG(release, debug|release): out_dir = $$out_dir/release + else:out_dir = $$out_dir/debug + return($$out_dir) +} + +QMAKE_EXTRA_COMPILERS += shiboken module_wrapper_dummy_command + +# Include paths for Shiboken generated files +INCLUDEPATH += $$WRAPPER_DIR \ + $$WRAPPER_DIR/../../../plugins/pythonextensions \ + $$WRAPPER_DIR/../../../plugins/pythonextensions/PythonExtension/QtCreator \ + "$$IDE_SOURCE_TREE/src/plugins/coreplugin" \ + "$$IDE_SOURCE_TREE/src/plugins/coreplugin/actionmanager" \ + "$$IDE_SOURCE_TREE/src/plugins/coreplugin/editormanager" \ + "$$IDE_SOURCE_TREE/src/libs/extensionsystem" \ + "$$IDE_SOURCE_TREE/src/libs/utils" + +for(i, PYSIDE2_INCLUDE) { + INCLUDEPATH += $$i/QtWidgets $$i/QtGui $$i/QtCore $$i/QtNetwork +} diff --git a/optional/texteditor/binding.cpp b/optional/texteditor/binding.cpp new file mode 100644 index 0000000..d4f4bf5 --- /dev/null +++ b/optional/texteditor/binding.cpp @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Python Extensions Plugin for QtCreator. +** +** 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 General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** 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-3.0.html. +** +****************************************************************************/ + +#include "binding.h" + +#include <QtCore/QDebug> +#include <QtCore/QString> + +#undef signals +#undef slots + +#include <sbkpython.h> +#include <sbkconverter.h> +#include <sbkmodule.h> + +#if PY_MAJOR_VERSION >= 3 +extern "C" PyObject *PyInit_QtCreatorBindingTextEditor(); +#else +extern "C" void initQtCreatorBindingTextEditor(); +#endif + +extern PyObject *SbkQtCreatorBindingTextEditorModuleObject; + +namespace PyUtil { + extern bool bindSubPyObject(const QString &moduleName, const QString &name, void *obj); +} + +void bind() +{ + // Init module + #if PY_MAJOR_VERSION >= 3 + const bool pythonInitialized = PyInit_QtCreatorBindingTextEditor() != nullptr; + #else + const bool pythonInitialized = true; + initQtCreatorBindingTextEditor(); + #endif + // Bind module into interpreter + bool pythonError = PyErr_Occurred() != nullptr; + if (pythonInitialized && !pythonError) { + PyUtil::bindSubPyObject("PythonExtension.QtCreator", "TextEditor", (void *)SbkQtCreatorBindingTextEditorModuleObject); + } else { + if (pythonError) + PyErr_Print(); + qDebug() << pythonInitialized << pythonError; + qDebug() << "There was a problem initializing the TextEditor bindings."; + + } +} diff --git a/optional/texteditor/binding_custom.pri b/optional/texteditor/binding_custom.pri new file mode 100644 index 0000000..361da10 --- /dev/null +++ b/optional/texteditor/binding_custom.pri @@ -0,0 +1,51 @@ +# Additional sources + +SOURCES += \ + # optional + +HEADERS += \ + # optional + + +# Declare dependencies and name + +# This has to be PythonBinding{PluginName} +QTC_PLUGIN_NAME = PythonBindingTextEditor +QTC_LIB_DEPENDS += \ + extensionsystem \ + utils + +QTC_PLUGIN_DEPENDS += \ + coreplugin \ + texteditor \ + pythonextensions + +QTC_PLUGIN_RECOMMENDS += \ + # optional plugin dependencies. nothing here at this time + + +# Shiboken binding generation setup + +WRAPPED_HEADER = wrappedclasses.h +WRAPPER_DIR = $$OUT_PWD/QtCreatorBindingTextEditor +TYPESYSTEM_FILE = typesystem_texteditor.xml + +TYPESYSTEM_NAME = qtcreatorbindingtexteditor + +## Include additional QtCreator paths +QT_INCLUDEPATHS += \ + -I"$$IDE_SOURCE_TREE/src/plugins/texteditor" + +INCLUDEPATH += \ + $$IDE_SOURCE_TREE/src/plugins/coreplugin \ + $$IDE_SOURCE_TREE/src/plugins/coreplugin/editormanager \ + $$IDE_SOURCE_TREE/src/plugins/coreplugin/find \ + $$IDE_SOURCE_TREE/src/plugins/texteditor \ + $$IDE_SOURCE_TREE/src/libs/utils + +## These headers are needed so the generated wrappers are added to the +## build. Right now they are empty files, however there might be a more elegant +## option. +WRAPPED_CLASSES = \ + bindingheaders/texteditor.h \ +# Sentinel line diff --git a/optional/texteditor/bindingheaders/texteditor.h b/optional/texteditor/bindingheaders/texteditor.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/optional/texteditor/bindingheaders/texteditor.h diff --git a/optional/texteditor/typesystem_texteditor.xml b/optional/texteditor/typesystem_texteditor.xml new file mode 100644 index 0000000..ef10df0 --- /dev/null +++ b/optional/texteditor/typesystem_texteditor.xml @@ -0,0 +1,75 @@ +<?xml version="1.0"?> +<!-- +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Python Extensions Plugin for QtCreator. +** +** $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$ +** +****************************************************************************/ +--> + +<!-- Typesystem for Qt Creator Python host plugin --> +<typesystem package="QtCreatorBindingTextEditor"> + + <!-- Load PySide QtWidgets typesystem (is this correct? yup) --> + <load-typesystem name="typesystem_widgets.xml" generate="no"/> + <!-- Currently there are problems with getting this to work (see below) --> + <!-- <load-typesystem name="../../plugins/pythonextensions/typesystem_qtcreator.xml" generate="no"/> --> + <!-- + Here is the deal: This will compile just fine, but WON'T LOAD. + The reason for this is known: + -> The generated binding initializer will try to load the Python Module 'QtCreatorPython' + -> This module does not exists, because we expose everything as members of 'PythonExtension' + -> Now one might try to simply rename QtCreatorPython to PythonExtension.QtCreator, which would + generate an import statement like `Shiboken::Module::import("PythonExtension.QtCreator")` + -> Problem: That does not work either, because QtCreator is actually a member in PythonExtension, + which is a module and not a package. + -> So yeah, essentially it seems like this is something that would not be a problem in a module + for CPython, but there seems to be no facility to circumvent this when embedding CPython. + There is also no way in Shibken to fix this and no easy fix for that. + ==> The easiest way forward is to just include the parts that are needed within each binding in + the typesystem. Problems that might arise: + 1) Big size of bindings due to repetition of code (pretty sure) + 2) Interoperability issues between bindings (conjecture) + --> + + <namespace-type name="TextEditor"> + <enum-type name="TextPositionOperation"/> + <!-- <object-type name="BaseTextEditor"> + <modify-function signature="position(TextEditor::TextPositionOperation,int)const" remove="all"/> + </object-type> --> + </namespace-type> + +</typesystem> diff --git a/optional/texteditor/wrappedclasses.h b/optional/texteditor/wrappedclasses.h new file mode 100644 index 0000000..260f2ac --- /dev/null +++ b/optional/texteditor/wrappedclasses.h @@ -0,0 +1,37 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Python Extensions Plugin for QtCreator. +** +** 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 General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** 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-3.0.html. +** +****************************************************************************/ + +#ifndef WRAPPEDCLASSES_H +#define WRAPPEDCLASSES_H + +#include <QList> + +#include <texteditor/texteditor.h> + +#include <coreplugin/editormanager/ieditor.h> + +#include <utils/filesearch.h> + +#endif // header end |