Original dotherside repository up to 4d0d6a353c33ff2227b83562a127b3514a7e2169

This commit is contained in:
Michał Cieślak 2023-01-31 13:31:12 +01:00 committed by Michał
parent 121c62bd9a
commit 561c60a0d0
58 changed files with 11322 additions and 0 deletions

7
vendor/DOtherSide/.docker/Dockerfile vendored Normal file
View File

@ -0,0 +1,7 @@
FROM ubuntu:18.04
RUN apt-get update && \
apt-get install --no-install-recommends -y apt-transport-https ca-certificates gnupg software-properties-common wget && \
wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | apt-key add - && \
apt-add-repository 'deb https://apt.kitware.com/ubuntu/ bionic main' && \
apt-get update && \
apt-get install --no-install-recommends -y cmake g++ make qt5-default git lcov curl qtdeclarative5-dev qtbase5-dev qtquickcontrols2-5-dev xvfb ninja-build qml-module-qtquick-controls

12
vendor/DOtherSide/.gitignore vendored Normal file
View File

@ -0,0 +1,12 @@
*.*~
build*
*.pro.*
*.o
.directory
#*#
nimcache
*.kdev4
*.user
.idea
*.orig
doc

25
vendor/DOtherSide/.travis.sh vendored Executable file
View File

@ -0,0 +1,25 @@
#!/bin/bash
# Early exit on first error
set -e
# Build DOtherSide
mkdir build
cd build
cmake -GNinja -DENABLE_COVERAGE=ON -DCMAKE_BUILD_TYPE=Debug ..
cmake --build .
# Start framebuffer
Xvfb :99 -screen 0 1024x768x24 > /dev/null &
export DISPLAY=:99.0
# Execute Tests
./test/TestDynamicQObject
# Collect coverage info
lcov --directory . --capture --output-file coverage.info
# Clean it up
lcov --remove coverage.info "/usr/*" -o coverage.info
lcov --remove coverage.info "*/build/*" -o coverage.info
lcov --remove coverage.info "*/test/*" -o coverage.info

15
vendor/DOtherSide/.travis.yml vendored Normal file
View File

@ -0,0 +1,15 @@
language: cpp
sudo: required
services:
- docker
before_install:
- docker pull filcuc/dotherside
script:
- docker run -ti --rm -v`pwd`:/repo -w /repo filcuc/dotherside /bin/bash -c "./.travis.sh"
after_success:
- bash <(curl -s https://codecov.io/bash)

78
vendor/DOtherSide/CHANGELOG.md vendored Normal file
View File

@ -0,0 +1,78 @@
# Version 0.6.4
* Added support for QCoreApplication::processEvents
* Added support for QObject::deleteLater
* Added support for QObject::readProperty and QObject::writeProperty
* Added support for QPixmap::isNull and QPixmap:: assign functions
* Added optional support for QtQuickControls2 and setting style
# Version 0.6.3
* Added soversion and version to CMake
* Fixed #57: Added support for QModelIndex internal pointer
* Added support for QAbstractItemModel::hasIndex
# Version 0.6.2
* Updated appveyor packages by adding 5.8 and removing 5.5 and 5.7
# Version 0.6.1
* Fixed compilation on windows with Visual studio 2013 and 2015
# Version 0.6.0
* Fixed #48: Added support QAbstractItemModel and QAbstractTableModels
* Added missing canFetchMore, fetchMore, hasChildren callbacks
* Fixed #46: Added support for index, createIndex
* Fixed #45: Added support for setting the qml signal names (old behaviour was arg0, arg1..)
* Added support
# Version 0.5.2
* Added support qmlRegisterType
* Added support qmlRegisterSingletonType
* Added support for creating QObject in the binded language
* Added support for using signal arguments from qml with names arg0, arg1 etc
* Introduced the concept of QMetaObject in the binded language
* Greatly reduced memory consumption of QObject by using QMetaObjects
* Greatly improved creation speed of QObjects
* Removed undefined behaviour when casting to void*
* Lots of refactoring and code cleanups
* New architecture for slots and signal invokation
* Added support for building the project with meson build system
* Added appveyor for creating pre built binaries for windows
* Improved the test suite
# Version 0.4.5
* Removed the D bindings
* Removed the Nim bindings
# Version 0.4.2
* [DOtherSide] Code cleanup and little refactoring
* [NimQml] Made nim compiles with the "cpp" option by default. This should fix C/C++ interop problems
# Version 0.4.1
* [DQml] Added support for code generation of slots, signals and properties by using custom UDAs
* [DQml] Updated the examples with the new attributes for code generation
* [NimQml] Little fix for adding fixing compilation with Nim 0.11.0
# Version 0.4.0
* [DQml] Inheritance of slots and signals is now supported
* [DQml] Added support for QAbstractListModel subclasses
* [DQml] Put on par the examples for matching those in NimQml
* [NimQml] Fixed AbstractItemModel example
* [NimQml] Initial support for windows builds with Visual Studio community edition
* [DOtherSide] Initial support for windows build
* [DOtherSide] Removed most warnings and code cleanup
# Version 0.3.0
* [NimQml] Added support for QAbstractListModel subclasses
* [NimQml] Fixed QtObject macro wrong reorder of the methods and proc declaration (thanks to Will)
* [NimQml] Added new ContactApp example
* [NimQml] Added optional support for finalizers
* [DOtherSide] Added support for injecting the DynamicQObject as behaviour to QObject subclasses
* [DotherSide] Added support for QAbstractListModel subclasses
# Version 0.2.0
* [DQml] Initial support for properties creation
* [NimQml] Added new macro syntax for creating QObject derived object (thanks to Will)
# Version 0.1.0
* [DOtherSide] Initial version with support for QObject Slot, Signal and Properties creation
* [DQml] Initial support for Slot and Signal creation
* [NimQml] Initial support for Slot, Signal and Properties creation

25
vendor/DOtherSide/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,25 @@
cmake_minimum_required(VERSION 3.2)
project(DOtherSide)
# Add additional source path for cmake
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/)
# Add strict warning checking for C++
if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
# Add Coverage option
option(ENABLE_COVERAGE "Enable coverage" OFF)
add_compile_options(-Wall -Wno-long-long -pedantic)
if (ENABLE_COVERAGE)
message(STATUS "Enabling coverage")
set(CMAKE_BUILD_TYPE Debug)
add_compile_options(-g -O0 --coverage)
add_link_options(--coverage)
endif()
endif()
add_subdirectory(doc)
add_subdirectory(lib)
add_subdirectory(test)

185
vendor/DOtherSide/LICENSE vendored Normal file
View File

@ -0,0 +1,185 @@
This software is licensed under the LGPLv3, included below.
As a special exception to the GNU Lesser General Public License version 3
("LGPL3"), the copyright holders of this Library give you permission to
convey to a third party a Combined Work that links statically or dynamically
to this Library without providing any Minimal Corresponding Source or
Minimal Application Code as set out in 4d or providing the installation
information set out in section 4e, provided that you comply with the other
provisions of LGPL3 and provided that you meet, for the Application the
terms and conditions of the license(s) which apply to the Application.
Except as stated in this special exception, the provisions of LGPL3 will
continue to comply in full to this Library. If you modify this Library, you
may apply this exception to your version of this Library, but you are not
obliged to do so. If you do not wish to do so, delete this exception
statement from your version. This exception does not (and cannot) modify any
license terms which apply to the Application, with which you must still
comply.
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

65
vendor/DOtherSide/README.md vendored Normal file
View File

@ -0,0 +1,65 @@
# DOtherSide
[![License](https://img.shields.io/badge/license-LGPL-green.svg)](https://github.com/filcuc/DOtherSide/blob/master/LICENSE)
[![Build Status](https://travis-ci.org/filcuc/DOtherSide.svg?branch=master)](https://travis-ci.org/filcuc/DOtherSide)
[![Build status](https://ci.appveyor.com/api/projects/status/ufufhtv2h507sd96/branch/master?svg=true)](https://ci.appveyor.com/project/filcuc/dotherside/branch/master)
[![codecov](https://codecov.io/gh/filcuc/dotherside/branch/master/graph/badge.svg)](https://codecov.io/gh/filcuc/dotherside)
[![Documentation Status](https://img.shields.io/badge/read-documentation-blue.svg)](https://filcuc.github.io/DOtherSide/)
C language library for creating bindings for the Qt QML language.
Documentation: https://filcuc.github.io/DOtherSide/index.html
Currently the DOtherSide library is used by the following bindings:
* [nimqml](https://github.com/filcuc/nimqml), QML bindings for the Nim programming language
* [dqml](https://github.com/filcuc/dqml), QML bindings for the D programming language
* [qml-rust](https://github.com/White-Oak/qml-rust), QML bindings for the Rust programming language
## Supported features
The following features are implementable from a binding language
* Creating custom QObject
* Creating custom QAbstractListModels
* Creating custom properties, signals and slots
* Creating from QML QObject defined in the binded language
* Creating from Singleton QML QObject defined in the binded language
## Prebuilt binaries
### Windows
Currently we provide the prebuilt binaries for windows through the
github [releases](https://github.com/filcuc/DOtherSide/releases) page
### Linux
Currently we provide the prebuilt binaries for the following
Linux distributions through the [OpenSUSE OBS service](https://build.opensuse.org/package/show/home:filcuc/DOtherSide)
* ```Archlinux``` : [here](http://software.opensuse.org/download.html?project=home%3Afilcuc&package=DOtherSide)
## Change log
The project change log can be read [here](./CHANGELOG.md).
## Supported platforms
Currently we support the following platforms/compilers:
- Linux both 32/64bit with gcc
- Windows 32/64bit with Visual Studio 2013|2015 Community Edition
## Build requirements
You need the following software:
* Qt 5.4 or higher
* Linux: gcc 4.8 or later with c++11 support or higher
* Windows: Visual Studio 2013|2015 Community Edition (Windows) or higher
## Build instructions:
1. Open a shell terminal inside the cloned repo
2. mkdir build && cd build
3. cmake ..
4. make
## Install Instructions
Once you built the package just type
```
make install
```
by default cmake will install to the default CMAKE prefix.
If you want to customize this location type the following command
during the build steps when invoking cmake
```
cmake -DCMAKE_INSTALL_PREFIX:PATH=/path/to/install/prefix path/to/CMakeLists.txt
```

64
vendor/DOtherSide/appveyor.yml vendored Normal file
View File

@ -0,0 +1,64 @@
clone_depth: 5
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
CMAKE_GENERATOR: "Visual Studio 15 2017"
QTDIR: "C:/Qt/5.12.5/msvc2017/bin"
CMAKE_PREFIX_PATH: "C:/Qt/5.12.5/msvc2017/lib/cmake"
CONFIGURATION: Release
ARTIFACT: libDOtherside-windows-msvc2017-qt-5.12.5.zip
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
CMAKE_GENERATOR: "Visual Studio 15 2017 Win64"
QTDIR: "C:/Qt/5.12.5/msvc2017_64/bin"
CMAKE_PREFIX_PATH: "C:/Qt/5.12.5/msvc2017_64/lib/cmake"
CONFIGURATION: Release
ARTIFACT: libDOtherside-windows-msvc2017_x64-qt-5.12.5.zip
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
CMAKE_GENERATOR: "Visual Studio 15 2017"
QTDIR: "C:/Qt/5.13.2/msvc2017/bin"
CMAKE_PREFIX_PATH: "C:/Qt/5.13.2/msvc2017/lib/cmake"
CONFIGURATION: Release
ARTIFACT: libDOtherside-windows-msvc2017-qt-5.13.2.zip
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
CMAKE_GENERATOR: "Visual Studio 15 2017 Win64"
QTDIR: "C:/Qt/5.13.2/msvc2017_64/bin"
CMAKE_PREFIX_PATH: "C:/Qt/5.13.2/msvc2017_64/lib/cmake"
CONFIGURATION: Release
ARTIFACT: libDOtherside-windows-msvc2017_x64-qt-5.13.2.zip
install:
- set PATH=%QTDIR%;%PATH%
build_script:
- mkdir build && cd build
- cmake .. -G"%CMAKE_GENERATOR%" -DCMAKE_PREFIX_PATH=%CMAKE_PREFIX_PATH%
- cmake --build . --config %CONFIGURATION%
- cd ..
test_script:
- set PATH=%QTDIR%;%PATH%
- build\test\%CONFIGURATION%\TestDynamicQObject.exe
after_build:
- 7z a %ARTIFACT% %APPVEYOR_BUILD_FOLDER%\build\lib\%CONFIGURATION%\DOtherSide.dll README.md CHANGELOG.md LICENSE
artifacts:
- path: $(ARTIFACT)
name: $(ARTIFACT)
type: zip
deploy:
description: 'AppVeyor Artifacts'
provider: GitHub
auth_token:
secure: mQWOVHGwctWmZ2wGL/Jy1I8DrHYjWYQwgEabF/R+LRruFlwkAUAvm2nTO5fcypNL
artifact: $(ARTIFACT)
draft: true
prerelease: true
on:
appveyor_repo_tag: true

13
vendor/DOtherSide/doc/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,13 @@
find_package(Doxygen)
if (DOXYGEN_FOUND)
set(INPUT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in)
set(INPUT_CSS_FILE ${CMAKE_CURRENT_SOURCE_DIR}/qtify.css)
set(INPUT_README_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../README.md)
set(OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR})
set(OUTPUT_FILE ${OUTPUT_DIR}/Doxyfile)
set(OUTPUT_CSS_FILE ${OUTPUT_DIR}/qtify.css)
configure_file(${INPUT_FILE} ${OUTPUT_FILE} @ONLY)
file(COPY ${INPUT_CSS_FILE} ${INPUT_README_FILE} DESTINATION ${OUTPUT_DIR})
add_custom_target(doc ${DOXYGEN_EXECUTABLE} ${OUTPUT_FILE} WORKING_DIRECTORY ${OUTPUT_DIR} COMMENT "Generating the API documentation with Doxygen" VERBATIM)
endif()

2330
vendor/DOtherSide/doc/Doxyfile.in vendored Normal file

File diff suppressed because it is too large Load Diff

1053
vendor/DOtherSide/doc/qtify.css vendored Normal file

File diff suppressed because it is too large Load Diff

71
vendor/DOtherSide/lib/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,71 @@
project(DOtherSide)
# Macro for merging common code between static and shared
macro(add_target name type)
find_package(Qt5 COMPONENTS Core Qml Gui Quick QuickControls2 Widgets)
add_library(${name} ${type}
include/DOtherSide/DOtherSideTypes.h
include/DOtherSide/DOtherSideTypesCpp.h
include/DOtherSide/DOtherSide.h
include/DOtherSide/DosQDeclarative.h
include/DOtherSide/DosQObjectWrapper.h
include/DOtherSide/DosQAbstractItemModelWrapper.h
include/DOtherSide/DosQObject.h
include/DOtherSide/DosQObjectImpl.h
include/DOtherSide/DosIQObjectImpl.h
include/DOtherSide/DosQMetaObject.h
include/DOtherSide/DosIQAbstractItemModelImpl.h
include/DOtherSide/DosQAbstractItemModel.h
include/DOtherSide/Utils.h
src/DOtherSide.cpp
src/DosQMetaObject.cpp
src/DosQDeclarative.cpp
src/DosQObject.cpp
src/DOtherSideTypesCpp.cpp
src/DosQObjectImpl.cpp
src/DosQAbstractItemModel.cpp
src/DosQQuickImageProvider.cpp
)
if (WIN32)
target_compile_definitions(${name} PRIVATE -DWIN32)
endif()
set_target_properties(${name} PROPERTIES CXX_STANDARD 11 AUTOMOC ON)
target_include_directories(${name} PUBLIC include include/Qt)
target_link_libraries(${name} PRIVATE Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Qml Qt5::Quick)
if (${Qt5QuickControls2_FOUND})
target_link_libraries(${name} PRIVATE Qt5::QuickControls2)
endif()
endmacro()
# Add shared version
add_target(${PROJECT_NAME} SHARED)
set(major 0)
set(minor 6)
set(patch 4)
set_target_properties(${PROJECT_NAME}
PROPERTIES
SOVERSION "${major}.${minor}"
VERSION "${major}.${minor}.${patch}"
)
# Add static version
add_target(${PROJECT_NAME}Static STATIC)
# Install directive for header files
install(FILES
include/DOtherSide/DOtherSide.h
include/DOtherSide/DOtherSideTypes.h
DESTINATION include/DOtherSide
)
# Install directive for binaries
install(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
)

View File

@ -0,0 +1,897 @@
/*
Copyright (C) 2019 Filippo Cucchetto.
Contact: https://github.com/filcuc/dotherside
This file is part of the DOtherSide library.
The DOtherSide library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the license, or (at your opinion) any later version.
The DOtherSide library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the DOtherSide library. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* \file DOtherSide.h
* \brief The DOtherSide API file
* \author Filippo Cucchetto
*
* This file contains all the functions from creating or manipulating the QML
* environement
*/
#ifndef DOTHERSIDE_H
#define DOTHERSIDE_H
#ifdef WIN32
#define DOS_API __declspec( dllexport )
#define DOS_CALL __cdecl
#else
#define DOS_API
#define DOS_CALL
#endif
#include <DOtherSide/DOtherSideTypes.h>
#ifdef __cplusplus
extern "C"
{
#endif
/// \defgroup QGuiApplication QGuiApplication
/// \brief Functions related to the QGuiApplication class
/// @{
/// \brief Return the QCore::applicationDirPath
/// \return The QCore::applicationDirPath as a UTF-8 string
/// \note The returned string should be deleted by the calling code by using
/// the dos_chararray_delete() function
DOS_API char *DOS_CALL dos_qcoreapplication_application_dir_path(void);
/// \brief Force the event loop to spin and process the given events
DOS_API void DOS_CALL dos_qcoreapplication_process_events(DosQEventLoopProcessEventFlag flags = DosQEventLoopProcessEventFlag::DosQEventLoopProcessEventFlagProcessAllEvents);
/// \brief Force the event loop to spin and process the given events until no more available or timed out
DOS_API void DOS_CALL dos_qcoreapplication_process_events_timed(DosQEventLoopProcessEventFlag flags, int ms);
/// \brief Create a QGuiApplication
/// \note The created QGuiApplication should be freed by calling dos_qguiapplication_delete()
DOS_API void DOS_CALL dos_qguiapplication_create(void);
/// \brief Calls the QGuiApplication::exec() function of the current QGuiApplication
/// \note A QGuiApplication should have been already created through dos_qguiapplication_create()
DOS_API void DOS_CALL dos_qguiapplication_exec(void);
/// \brief Calls the QGuiApplication::quit() function of the current QGuiApplication
/// \note A QGuiApplication should have been already created through dos_qguiapplication_create()
DOS_API void DOS_CALL dos_qguiapplication_quit(void);
/// \brief Free the memory of the current QGuiApplication
/// \note A QGuiApplication should have been already created through dos_qguiapplication_create()
DOS_API void DOS_CALL dos_qguiapplication_delete(void);
/// @}
/// \defgroup QApplication QApplication
/// \brief Functions related to the QApplication class
/// @{
/// \brief Create a QApplication
/// \note The created QApplication should be freed by calling dos_qapplication_delete()
DOS_API void DOS_CALL dos_qapplication_create(void);
/// \brief Calls the QApplication::exec() function of the current QGuiApplication
/// \note A QApplication should have been already created through dos_qapplication_create()
DOS_API void DOS_CALL dos_qapplication_exec(void);
/// \brief Calls the QApplication::quit() function of the current QGuiApplication
/// \note A QApplication should have been already created through dos_qapplication_create()
DOS_API void DOS_CALL dos_qapplication_quit(void);
/// \brief Free the memory of the current QApplication
/// \note A QApplication should have been already created through dos_qapplication_create()
DOS_API void DOS_CALL dos_qapplication_delete(void);
/// @}
/// \defgroup QQmlApplicationEngine QQmlApplicationEngine
/// \brief Functions related to the QQmlApplicationEngine class
/// @{
/// \brief Create a new QQmlApplicationEngine
/// \return A new QQmlApplicationEngine
/// \note The returned QQmlApplicationEngine should be freed by using dos_qqmlapplicationengine_delete(DosQQmlApplicationEngine*)
DOS_API DosQQmlApplicationEngine *DOS_CALL dos_qqmlapplicationengine_create(void);
/// \brief Calls the QQmlApplicationEngine::load function
/// \param vptr The QQmlApplicationEngine
/// \param filename The file to load. The file is relative to the directory that contains the application executable
DOS_API void DOS_CALL dos_qqmlapplicationengine_load(DosQQmlApplicationEngine *vptr, const char *filename);
/// \brief Calls the QQmlApplicationEngine::load function
/// \param vptr The QQmlApplicationEngine
/// \param url The QUrl of the file to load
DOS_API void DOS_CALL dos_qqmlapplicationengine_load_url(DosQQmlApplicationEngine *vptr, DosQUrl *url);
/// \brief Calls the QQmlApplicationEngine::loadData function
/// \param vptr The QQmlApplicationEngine
/// \param data The UTF-8 string of the QML to load
DOS_API void DOS_CALL dos_qqmlapplicationengine_load_data(DosQQmlApplicationEngine *vptr, const char *data);
/// \brief Calls the QQmlApplicationEngine::addImportPath function
/// \param vptr The QQmlApplicationEngine
/// \param path The path to be added to the list of import paths
DOS_API void DOS_CALL dos_qqmlapplicationengine_add_import_path(DosQQmlApplicationEngine *vptr, const char *path);
/// \brief Calls the QQmlApplicationEngine::context
/// \param vptr The QQmlApplicationEngine
/// \return A pointer to a QQmlContext. This should not be stored nor made available to the binded language if
/// you can't guarantee that this QQmlContext should not live more that its Engine. This context is owned by
/// the engine and so it should die with the engine.
DOS_API DosQQmlContext *DOS_CALL dos_qqmlapplicationengine_context(DosQQmlApplicationEngine *vptr);
/// \brief Calls the QQMLApplicationengine::addImageProvider
/// \param vptr The QQmlApplicationEngine
/// \param vptr_i A QQuickImageProvider, the QQmlApplicationEngine takes ownership of this pointer
DOS_API void DOS_CALL dos_qqmlapplicationengine_addImageProvider(DosQQmlApplicationEngine *vptr, const char* name, DosQQuickImageProvider *vptr_i);
/// \brief Free the memory allocated for the given QQmlApplicationEngine
/// \param vptr The QQmlApplicationEngine
DOS_API void DOS_CALL dos_qqmlapplicationengine_delete(DosQQmlApplicationEngine *vptr);
/// @}
/// \defgroup QQuickImageProvider QQuickImageProvider
/// \brief Functions related to the QQuickImageProvider class
/// @{
/// \brief Create a new QQuickImageProvider
/// \return A new QQuickImageProvider
/// \note The returned QQuickImageProvider should be freed by using dos_qquickimageprovider_delete(DosQQuickImageProvider*) unless the QQuickImageProvider has been bound to a QQmlApplicationEngine
DOS_API DosQQuickImageProvider *DOS_CALL dos_qquickimageprovider_create(RequestPixmapCallback callback);
/// \breif Frees a QQuickImageProvider
DOS_API void DOS_CALL dos_qquickimageprovider_delete(DosQQuickImageProvider *vptr);
/// @}
/// \defgroup QPixmap QPixmap
/// \brief Functions related to the QPixmap class
/// @{
/// \brief Creates a null QPixmap
DOS_API DosPixmap *DOS_CALL dos_qpixmap_create();
/// \brief Creates a QPixmap copied from another
DOS_API DosPixmap *DOS_CALL dos_qpixmap_create_qpixmap(const DosPixmap* other);
/// \brief Create a new QPixmap
DOS_API DosPixmap *DOS_CALL dos_qpixmap_create_width_and_height(int width, int height);
/// \brief Frees a QPixmap
DOS_API void DOS_CALL dos_qpixmap_delete(DosPixmap *vptr);
/// \brief Load image data into a QPixmap from an image file
DOS_API void DOS_CALL dos_qpixmap_load(DosPixmap *vptr, const char* filepath, const char* format);
/// \brief Load image data into a QPixmap from a buffer
DOS_API void DOS_CALL dos_qpixmap_loadFromData(DosPixmap *vptr, const unsigned char* data, unsigned int len);
/// \brief Fill a QPixmap with a single color
DOS_API void DOS_CALL dos_qpixmap_fill(DosPixmap *vptr, unsigned char r, unsigned char g, unsigned char b, unsigned char a);
/// \brief Calls the QPixmap::operator=(const QPixmap&) function
/// \param vptr The left hand side QPixmap
/// \param other The right hand side QPixmap
DOS_API void DOS_CALL dos_qpixmap_assign(DosPixmap *vptr, const DosPixmap* other);
/// \brief Calls the QPixmap::isNull
/// \return True if the QPixmap is null, false otherwise
DOS_API bool DOS_CALL dos_qpixmap_isNull(DosPixmap *vptr);
/// @}
/// \defgroup QQuickStyle QQuickStyle
/// \brief Functions related to the QQuickStyle class
/// @{
/// \brief Set the QtQuickControls2 style
DOS_API void DOS_CALL dos_qquickstyle_set_style(const char *style);
/// \brief Set the QtQuickControls2 fallback style
DOS_API void DOS_CALL dos_qquickstyle_set_fallback_style(const char *style);
/// @}
/// \defgroup QQuickView QQuickView
/// \brief Functions related to the QQuickView class
/// @{
/// \brief Create a new QQuickView
/// \return A new QQuickView
/// \note The returned QQuickView should be freed by using dos_qquickview_delete(DosQQuickview*)
DOS_API DosQQuickView *DOS_CALL dos_qquickview_create(void);
/// \brief Calls the QQuickView::show() function
/// \param vptr The QQuickView
DOS_API void DOS_CALL dos_qquickview_show(DosQQuickView *vptr);
/// \brief Calls the QQuickView::source() function
/// \param vptr The QQuickView
/// \return The QQuickView source as an UTF-8 string
/// \note The returned string should be freed by using the dos_chararray_delete() function
DOS_API char *DOS_CALL dos_qquickview_source(const DosQQuickView *vptr);
/// \brief Calls the QQuickView::setSource() function
/// \param vptr The QQuickView
/// \param url The source QUrl
DOS_API void DOS_CALL dos_qquickview_set_source_url(DosQQuickView *vptr, DosQUrl *url);
/// \brief Calls the QQuickView::setSource() function
/// \param vptr The QQuickView
/// \param filename The source path as an UTF-8 string. The path is relative to the directory
/// that contains the application executable
DOS_API void DOS_CALL dos_qquickview_set_source(DosQQuickView *vptr, const char *filename);
/// \brief Calls the QQuickView::setResizeMode() function
/// \param vptr The QQuickView
/// \param resizeMode The resize mode
DOS_API void DOS_CALL dos_qquickview_set_resize_mode(DosQQuickView *vptr, int resizeMode);
/// \brief Free the memory allocated for the given QQuickView
/// \param vptr The QQuickView
DOS_API void DOS_CALL dos_qquickview_delete(DosQQuickView *vptr);
/// \brief Return the QQuickView::rootContext() as a QQuickContext
/// \param vptr The QQuickView
DOS_API DosQQmlContext *DOS_CALL dos_qquickview_rootContext(DosQQuickView *vptr);
/// @}
/// \defgroup QQmlContext QQmlContext
/// \brief Functions related to the QQmlContext class
/// @{
/// \brief Calls the QQmlContext::baseUrl function
/// \return The QQmlContext url as an UTF-8 string
/// \note The returned string should be freed using with the dos_chararray_delete() function
DOS_API char *DOS_CALL dos_qqmlcontext_baseUrl(const DosQQmlContext *vptr);
/// \brief Sets a property inside the context
/// \param vptr The DosQQmlContext
/// \param name The property name. The string is owned by the caller thus it will not be deleted by the library
/// \param value The property value. The DosQVariant is owned by the caller thus it will not be deleted by the library
DOS_API void DOS_CALL dos_qqmlcontext_setcontextproperty(DosQQmlContext *vptr, const char *name, DosQVariant *value);
/// @}
/// \defgroup String String
/// \brief Functions related to strings
/// @{
/// \brief Free the memory allocated for the given UTF-8 string
/// \param ptr The UTF-8 string to be freed
DOS_API void DOS_CALL dos_chararray_delete(char *ptr);
/// @}
/// \defgroup QVariant QVariant
/// \brief Functions related to the QVariant class
/// @{
/// Delete a DosQVariantArray
DOS_API void DOS_CALL dos_qvariantarray_delete(DosQVariantArray *ptr);
/// \brief Create a new QVariant (null)
/// \return The a new QVariant
/// \note The returned QVariant should be freed using dos_qvariant_delete()
DOS_API DosQVariant *DOS_CALL dos_qvariant_create(void);
/// \brief Create a new QVariant holding an int value
/// \return The a new QVariant
/// \param value The int value
/// \note The returned QVariant should be freed using dos_qvariant_delete()
DOS_API DosQVariant *DOS_CALL dos_qvariant_create_int(int value);
/// \brief Create a new QVariant holding a bool value
/// \return The a new QVariant
/// \param value The bool value
/// \note The returned QVariant should be freed using dos_qvariant_delete()
DOS_API DosQVariant *DOS_CALL dos_qvariant_create_bool(bool value);
/// \brief Create a new QVariant holding a string value
/// \return The a new QVariant
/// \param value The string value
/// \note The returned QVariant should be freed using dos_qvariant_delete()
/// \note The given string is copied inside the QVariant and will not be deleted
DOS_API DosQVariant *DOS_CALL dos_qvariant_create_string(const char *value);
/// \brief Create a new QVariant holding a QObject value
/// \return The a new QVariant
/// \param value The QObject value
/// \note The returned QVariant should be freed using dos_qvariant_delete()
DOS_API DosQVariant *DOS_CALL dos_qvariant_create_qobject(DosQObject *value);
/// \brief Create a new QVariant with the same value of the one given as argument
/// \return The a new QVariant
/// \param value The QVariant to which copy its value
/// \note The returned QVariant should be freed using dos_qvariant_delete()
DOS_API DosQVariant *DOS_CALL dos_qvariant_create_qvariant(const DosQVariant *value);
/// \brief Create a new QVariant holding a float value
/// \return The a new QVariant
/// \param value The float value
/// \note The returned QVariant should be freed using dos_qvariant_delete()
DOS_API DosQVariant *DOS_CALL dos_qvariant_create_float(float value);
/// \brief Create a new QVariant holding a double value
/// \return The a new QVariant
/// \param value The double value
/// \note The returned QVariant should be freed using dos_qvariant_delete()
DOS_API DosQVariant *DOS_CALL dos_qvariant_create_double(double value);
/// \brief Create a new QVariant holding a QVariantList
/// \return A new QVariant
/// \param size The size of the QVariant array
/// \param array The array of QVariant that will be inserted in the inner QVariantList
/// \note The \p array is owned by the caller thus it will not be deleted
DOS_API DosQVariant *DOS_CALL dos_qvariant_create_array(int size, DosQVariant **array);
/// \brief Calls the QVariant::setValue<int>() function
/// \param vptr The QVariant
/// \param value The int value
DOS_API void DOS_CALL dos_qvariant_setInt(DosQVariant *vptr, int value);
/// \brief Calls the QVariant::setValue<bool>() function
/// \param vptr The QVariant
/// \param value The bool value
DOS_API void DOS_CALL dos_qvariant_setBool(DosQVariant *vptr, bool value);
/// \brief Calls the QVariant::setValue<float>() function
/// \param vptr The QVariant
/// \param value The float value
DOS_API void DOS_CALL dos_qvariant_setFloat(DosQVariant *vptr, float value);
/// \brief Calls the QVariant::setValue<double>() function
/// \param vptr The QVariant
/// \param value The double value
DOS_API void DOS_CALL dos_qvariant_setDouble(DosQVariant *vptr, double value);
/// \brief Calls the QVariant::setValue<QString>() function
/// \param vptr The QVariant
/// \param value The string value
/// \note The string argument is copied inside the QVariant and it will not be deleted
DOS_API void DOS_CALL dos_qvariant_setString(DosQVariant *vptr, const char *value);
/// \brief Calls the QVariant::setValue<QObject*>() function
/// \param vptr The QVariant
/// \param value The string value
/// \note The string argument is copied inside the QVariant and it will not be deleted
DOS_API void DOS_CALL dos_qvariant_setQObject(DosQVariant *vptr, DosQObject *value);
/// \brief Calls the QVariant::setValue<QVariantList>() function
/// \param vptr The QVariant
/// \param size The size of the \p array
/// \param array The array of QVariant use for setting the inner QVariantList
DOS_API void DOS_CALL dos_qvariant_setArray(DosQVariant *vptr, int size, DosQVariant **array);
/// \brief Calls the QVariant::isNull function
/// \return True if the QVariant is null, false otherwise
/// \param vptr The QVariant
DOS_API bool DOS_CALL dos_qvariant_isnull(const DosQVariant *vptr);
/// \brief Free the memory allocated for the given QVariant
/// \param vptr The QVariant
DOS_API void DOS_CALL dos_qvariant_delete(DosQVariant *vptr);
/// \brief Calls the QVariant::operator=(const QVariant&) function
/// \param vptr The QVariant (left side)
/// \param other The QVariant (right side)
DOS_API void DOS_CALL dos_qvariant_assign(DosQVariant *vptr, const DosQVariant *other);
/// \brief Calls the QVariant::value<int>() function
/// \param vptr The QVariant
/// \return The int value
DOS_API int DOS_CALL dos_qvariant_toInt(const DosQVariant *vptr);
/// \brief Calls the QVariant::value<bool>() function
/// \param vptr The QVariant
/// \return The bool value
DOS_API bool DOS_CALL dos_qvariant_toBool(const DosQVariant *vptr);
/// \brief Calls the QVariant::value<QString>() function
/// \param vptr The QVariant
/// \return The string value
/// \note The returned string should be freed by using dos_chararray_delete()
DOS_API char *DOS_CALL dos_qvariant_toString(const DosQVariant *vptr);
/// \brief Calls the QVariant::value<float>() function
/// \param vptr The QVariant
/// \return The float value
DOS_API float DOS_CALL dos_qvariant_toFloat (const DosQVariant *vptr);
/// \brief Calls the QVariant::value<double>() function
/// \param vptr The QVariant
/// \return The double value
DOS_API double DOS_CALL dos_qvariant_toDouble(const DosQVariant *vptr);
/// \brief Calls the QVariant::value<QVariantList>() function
/// \param vptr The QVariant
/// \return The QVariantList value as an array
DOS_API DosQVariantArray *DOS_CALL dos_qvariant_toArray(const DosQVariant *vptr);
/// \brief Calls the QVariant::value<QObject*>() function
/// \param vptr The QVariant
/// \return The QObject* value
/// \note Storing the returned QObject* is higly dengerous and depends on how you managed the memory
/// of QObjects in the binded language
DOS_API DosQObject *DOS_CALL dos_qvariant_toQObject(const DosQVariant *vptr);
/// @}
/// \defgroup QMetaObject QMetaObject
/// \brief Functions related to the QMetaObject class
/// @{
/// \brief Create a new QMetaObject
/// \param superClassMetaObject The superclass metaobject
/// \param className The class name
/// \param signalDefinitions The SignalDefinitions
/// \param slotDefinitions The SlotDefinitions struct
/// \param propertyDefinitions The PropertyDefinitions struct
/// \note The returned QMetaObject should be freed using dos_qmetaobject_delete().
/// \attention The QMetaObject should live more than the QObject it refears to.
/// Depending on the implementation usually the QMetaObject should be modeled as static variable
/// So with a lifetime equals to the entire application
DOS_API DosQMetaObject *DOS_CALL dos_qmetaobject_create(DosQMetaObject *superClassMetaObject,
const char *className,
const SignalDefinitions *signalDefinitions,
const SlotDefinitions *slotDefinitions,
const PropertyDefinitions *propertyDefinitions);
/// \brief Free the memory allocated for the given QMetaObject
/// \param vptr The QMetaObject
DOS_API void DOS_CALL dos_qmetaobject_delete(DosQMetaObject *vptr);
/// @}
/// \defgroup QAbstractListModel QAbstractItemModel
/// \brief Functions related to the QAbstractListModel class
/// @{
/// \brief Return QMetaObject associated to the QAbstractListModel class
/// \return The QMetaObject of the QAbstractListModel class
/// \note The returned QMetaObject should be freed using dos_qmetaobject_delete().
DOS_API DosQMetaObject *DOS_CALL dos_qabstractlistmodel_qmetaobject(void);
/// \brief Create a new QAbstractListModel
/// \param callbackObject The pointer of QAbstractListModel in the binded language
/// \param metaObject The QMetaObject for this QAbstractListModel
/// \param dObjectCallback The callback for handling the properties read/write and slots execution
/// \param callbacks The QAbstractItemModel callbacks
DOS_API DosQAbstractListModel *DOS_CALL dos_qabstractlistmodel_create(void *callbackObject,
DosQMetaObject *metaObject,
DObjectCallback dObjectCallback,
DosQAbstractItemModelCallbacks *callbacks);
/// \brief Calls the default QAbstractListModel::index() function
DOS_API DosQModelIndex *DOS_CALL dos_qabstractlistmodel_index(DosQAbstractListModel *vptr,
int row, int column, DosQModelIndex *parent);
/// \brief Calls the default QAbstractListModel::parent() function
DOS_API DosQModelIndex *DOS_CALL dos_qabstractlistmodel_parent(DosQAbstractListModel *vptr,
DosQModelIndex *child);
/// \brief Calls the default QAbstractListModel::columnCount() function
DOS_API int DOS_CALL dos_qabstractlistmodel_columnCount(DosQAbstractListModel *vptr,
DosQModelIndex *parent);
/// @}
/// \defgroup QAbstractTableModel QAbstractTableModel
/// \brief Functions related to the QAbstractTableModel class
/// @{
/// \brief Return QMetaObject associated to the QAbstractTableModel class
/// \return The QMetaObject of the QAbstractTableModel class
/// \note The returned QMetaObject should be freed using dos_qmetaobject_delete().
DOS_API DosQMetaObject *DOS_CALL dos_qabstracttablemodel_qmetaobject(void);
/// \brief Create a new QAbstractTableModel
/// \param callbackObject The pointer of QAbstractTableModel in the binded language
/// \param metaObject The QMetaObject for this QAbstractTableModel
/// \param dObjectCallback The callback for handling the properties read/write and slots execution
/// \param callbacks The QAbstractItemModel callbacks
DOS_API DosQAbstractTableModel *DOS_CALL dos_qabstracttablemodel_create(void *callbackObject,
DosQMetaObject *metaObject,
DObjectCallback dObjectCallback,
DosQAbstractItemModelCallbacks *callbacks);
/// \brief Calls the default QAbstractTableModel::index() function
DOS_API DosQModelIndex *DOS_CALL dos_qabstracttablemodel_index(DosQAbstractTableModel *vptr,
int row, int column, DosQModelIndex *parent);
/// \brief Calls the default QAbstractTableModel::parent() function
DOS_API DosQModelIndex *DOS_CALL dos_qabstracttablemodel_parent(DosQAbstractTableModel *vptr,
DosQModelIndex *child);
/// @}
/// \defgroup QAbstractItemModel QAbstractItemModel
/// \brief Functions related to the QAbstractItemModel class
/// @{
/// \brief Return QMetaObject associated to the QAbstractItemModel class
/// \return The QMetaObject of the QAbstractItemModel class
/// \note The returned QMetaObject should be freed using dos_qmetaobject_delete().
DOS_API DosQMetaObject *DOS_CALL dos_qabstractitemmodel_qmetaobject(void);
/// \brief Create a new QAbstractItemModel
/// \param callbackObject The pointer of QAbstractItemModel in the binded language
/// \param metaObject The QMetaObject for this QAbstractItemModel
/// \param dObjectCallback The callback for handling the properties read/write and slots execution
/// \param callbacks The QAbstractItemModel callbacks
/// \note The callbacks struct is copied so you can freely delete after calling this function
DOS_API DosQAbstractItemModel *DOS_CALL dos_qabstractitemmodel_create(void *callbackObject,
DosQMetaObject *metaObject,
DObjectCallback dObjectCallback,
DosQAbstractItemModelCallbacks *callbacks);
/// \brief Calls the QAbstractItemModel::setData function
DOS_API bool DOS_CALL dos_qabstractitemmodel_setData(DosQAbstractItemModel *vptr, DosQModelIndex *index, DosQVariant *data, int role);
/// \brief Calls the QAbstractItemModel::roleNames function
DOS_API DosQHashIntQByteArray *DOS_CALL dos_qabstractitemmodel_roleNames(DosQAbstractItemModel *vptr);
/// \brief Calls the QAbstractItemModel::flags function
DOS_API int DOS_CALL dos_qabstractitemmodel_flags(DosQAbstractItemModel *vptr, DosQModelIndex *index);
/// \brief Calls the QAbstractItemModel::headerData function
DOS_API DosQVariant *DOS_CALL dos_qabstractitemmodel_headerData(DosQAbstractItemModel *vptr, int section, int orientation, int role);
/// \brief Calls the QAbstractItemModel::hasChildren function
DOS_API bool DOS_CALL dos_qabstractitemmodel_hasChildren(DosQAbstractItemModel *vptr, DosQModelIndex *parentIndex);
/// \brief Calls the QAbstractItemModel::hasIndex function
DOS_API bool DOS_CALL dos_qabstractitemmodel_hasIndex(DosQAbstractItemModel *vptr, int row, int column, DosQModelIndex *dosParentIndex);
/// \brief Calls the QAbstractItemModel::canFetchMore function
DOS_API bool DOS_CALL dos_qabstractitemmodel_canFetchMore(DosQAbstractItemModel *vptr, DosQModelIndex *parentIndex);
/// \brief Calls the QAbstractItemModel::fetchMore function
DOS_API void DOS_CALL dos_qabstractitemmodel_fetchMore(DosQAbstractItemModel *vptr, DosQModelIndex *parentIndex);
/// \brief Calls the QAbstractItemModel::beginInsertRows() function
/// \param vptr The QAbstractItemModel
/// \param parent The parent QModelIndex
/// \param first The first row in the range
/// \param last The last row in the range
/// \note The \p parent QModelIndex is owned by the caller thus it will not be deleted
DOS_API void DOS_CALL dos_qabstractitemmodel_beginInsertRows(DosQAbstractItemModel *vptr, DosQModelIndex *parent, int first, int last);
/// \brief Calls the QAbstractItemModel::endInsertRows() function
/// \param vptr The QAbstractItemModel
DOS_API void DOS_CALL dos_qabstractitemmodel_endInsertRows(DosQAbstractItemModel *vptr);
/// \brief Calls the QAbstractItemModel::beginRemovetRows() function
/// \param vptr The QAbstractItemModel
/// \param parent The parent QModelIndex
/// \param first The first column in the range
/// \param last The last column in the range
/// \note The \p parent QModelIndex is owned by the caller thus it will not be deleted
DOS_API void DOS_CALL dos_qabstractitemmodel_beginRemoveRows(DosQAbstractItemModel *vptr, DosQModelIndex *parent, int first, int last);
/// \brief Calls the QAbstractItemModel::endRemoveRows() function
/// \param vptr The QAbstractItemModel
DOS_API void DOS_CALL dos_qabstractitemmodel_endRemoveRows(DosQAbstractItemModel *vptr);
/// \brief Calls the QAbstractItemModel::beginInsertColumns() function
/// \param vptr The QAbstractItemModel
/// \param parent The parent QModelIndex
/// \param first The first column in the range
/// \param last The last column in the range
/// \note The \p parent QModelIndex is owned by the caller thus it will not be deleted
DOS_API void DOS_CALL dos_qabstractitemmodel_beginInsertColumns(DosQAbstractItemModel *vptr, DosQModelIndex *parent, int first, int last);
/// \brief Calls the QAbstractItemModel::endInsertColumns() function
/// \param vptr The QAbstractItemModel
DOS_API void DOS_CALL dos_qabstractitemmodel_endInsertColumns(DosQAbstractItemModel *vptr);
/// \brief Calls the QAbstractItemModel::beginRemovetColumns() function
/// \param vptr The QAbstractItemModel
/// \param parent The parent QModelIndex
/// \param first The first column in the range
/// \param last The last column in the range
/// \note The \p parent QModelIndex is owned by the caller thus it will not be deleted
DOS_API void DOS_CALL dos_qabstractitemmodel_beginRemoveColumns(DosQAbstractItemModel *vptr, DosQModelIndex *parent, int first, int last);
/// \brief Calls the QAbstractItemModel::endRemoveColumns() function
/// \param vptr The QAbstractItemModel
DOS_API void DOS_CALL dos_qabstractitemmodel_endRemoveColumns(DosQAbstractItemModel *vptr);
/// \brief Calls the QAbstractItemModel::beginResetModel() function
/// \param vptr The QAbstractItemModel
DOS_API void DOS_CALL dos_qabstractitemmodel_beginResetModel(DosQAbstractItemModel *vptr);
/// \brief Calls the QAbstractItemModel::endResetModel() function
/// \param vptr The QAbstractItemModel
DOS_API void DOS_CALL dos_qabstractitemmodel_endResetModel(DosQAbstractItemModel *vptr);
/// \brief Emit the dataChanged signal
/// \param vptr The DosQAbstractItemModel pointer
/// \param topLeft The topLeft DosQModelIndex
/// \param bottomRight The bottomright DosQModelIndex
/// \param rolesPtr The roles array
/// \param rolesLength The roles array length
/// \note The \p topLeft, \p bottomRight and \p rolesPtr arguments are owned by the caller thus they will not be deleted
DOS_API void DOS_CALL dos_qabstractitemmodel_dataChanged(DosQAbstractItemModel *vptr,
const DosQModelIndex *topLeft,
const DosQModelIndex *bottomRight,
int *rolesPtr, int rolesLength);
/// \brief Calls the QAbstractItemModel::createIndex() function
DOS_API DosQModelIndex *DOS_CALL dos_qabstractitemmodel_createIndex(DosQAbstractItemModel *vptr,
int row, int column, void *data);
/// \brief Calls the default QAbstractItemModel::setData() function
DOS_API bool DOS_CALL dos_qabstractitemmodel_setData(DosQAbstractItemModel *vptr,
DosQModelIndex *index, DosQVariant *value, int role);
/// \brief Calls the default QAbstractItemModel::roleNames() function
DOS_API DosQHashIntQByteArray *DOS_CALL dos_qabstractitemmodel_roleNames(DosQAbstractItemModel *vptr);
/// \brief Calls the default QAbstractItemModel::flags() function
DOS_API int DOS_CALL dos_qabstractitemmodel_flags(DosQAbstractItemModel *vptr,
DosQModelIndex *index);
/// \brief Calls the default QAbstractItemModel::headerData() function
DOS_API DosQVariant *DOS_CALL dos_qabstractitemmodel_headerData(DosQAbstractItemModel *vptr,
int section, int orientation, int role);
/// @}
/// \defgroup QObject QObject
/// \brief Functions related to the QObject class
/// @{
/// \brief Return QMetaObject associated to the QObject class
/// \return The QMetaObject of the QObject class
/// \note The returned QObject should be freed using dos_qmetaobject_delete().
DOS_API DosQMetaObject *DOS_CALL dos_qobject_qmetaobject(void);
/// \brief Create a new QObject
/// \param dObjectPointer The pointer of the QObject in the binded language
/// \param metaObject The QMetaObject associated to the given QObject
/// \param dObjectCallback The callback called from QML whenever a slot or property
/// should be in read, write or invoked
/// \return A new QObject
/// \note The returned QObject should be freed by calling dos_qobject_delete()
/// \note The \p dObjectPointer is usefull for forwarding a property read/slot to the correct
/// object in the binded language in the callback
DOS_API DosQObject *DOS_CALL dos_qobject_create(void *dObjectPointer,
DosQMetaObject *metaObject,
DObjectCallback dObjectCallback);
/// \brief Emit a signal definited in a QObject
/// \param vptr The QObject
/// \param name The signal name
/// \param parametersCount The number of parameters in the \p parameters array
/// \param parameters An array of DosQVariant with the values of signal arguments
DOS_API void DOS_CALL dos_qobject_signal_emit(DosQObject *vptr,
const char *name,
int parametersCount,
void **parameters);
DOS_API bool DOS_CALL dos_qobject_signal_connect(DosQObject *senderVPtr,
const char *signal,
DosQObject *receiverVPtr,
const char *method,
int type);
DOS_API bool DOS_CALL dos_qobject_signal_disconnect(DosQObject *senderVPtr,
const char *signal,
DosQObject *receiverVPtr,
const char *method);
/// \brief Return the DosQObject objectName
/// \param vptr The DosQObject pointer
/// \return A string in UTF8 format
/// \note The returned string should be freed using the dos_chararray_delete() function
DOS_API char *DOS_CALL dos_qobject_objectName(const DosQObject *vptr);
/// \brief Calls the QObject::setObjectName() function
/// \param vptr The QObject
/// \param name A pointer to an UTF-8 string
/// \note The \p name string is owned by the caller thus it will not be deleted
DOS_API void DOS_CALL dos_qobject_setObjectName(DosQObject *vptr, const char *name);
/// \brief Free the memory allocated for the QObject
/// \param vptr The QObject
DOS_API void DOS_CALL dos_qobject_delete(DosQObject *vptr);
/// \brief Free the memory allocated for the QObject in the next event loop cycle
/// \param vptr The QObject
DOS_API void DOS_CALL dos_qobject_deleteLater(DosQObject *vptr);
/// \brief Read Value of a property by its name
/// \param vptr The QObject
/// \param propertyName the Name of the property to be read
/// \returns Value of the given property
/// \note returns an empty QVariant if the propertyName does not exist
DOS_API DosQVariant *DOS_CALL dos_qobject_property(DosQObject *vptr,
const char *propertyName);
/// \brief Write Value to a property by its name
/// \param vptr The QObject
/// \param propertyName The Name of the property to be written
/// \param value The value to be written
/// \return Result as bool
DOS_API bool DOS_CALL dos_qobject_setProperty(DosQObject *vptr,
const char *propertyName,
DosQVariant *value);
/// @}
/// \defgroup QModelIndex QModelIndex
/// \brief Functions related to the QModelIndex class
/// @{
/// \brief Create a new QModelIndex()
/// \note The returned QModelIndex should be freed by calling the dos_qmodelindex_delete() function
DOS_API DosQModelIndex *DOS_CALL dos_qmodelindex_create(void);
/// \brief Create a new QModelIndex() copy constructed with given index
/// \note The returned QModelIndex should be freed by calling the dos_qmodelindex_delete() function
DOS_API DosQModelIndex *DOS_CALL dos_qmodelindex_create_qmodelindex(DosQModelIndex *index);
/// \brief Free the memory allocated for the QModelIndex
/// \param vptr The QModelIndex
DOS_API void DOS_CALL dos_qmodelindex_delete (DosQModelIndex *vptr);
/// \brief Calls the QModelIndex::row() function
/// \param vptr The QModelIndex
/// \return The QModelIndex row
DOS_API int DOS_CALL dos_qmodelindex_row (const DosQModelIndex *vptr);
/// \brief Calls the QModelIndex::column() function
/// \param vptr The QModelIndex
/// \return The QModelIndex column
DOS_API int DOS_CALL dos_qmodelindex_column (const DosQModelIndex *vptr);
/// \brief Calls the QModelIndex::isvalid() function
/// \param vptr The QModelIndex
/// \return True if the QModelIndex is valid, false otherwise
DOS_API bool DOS_CALL dos_qmodelindex_isValid(const DosQModelIndex *vptr);
/// \brief Calls the QModelIndex::data() function
/// \param vptr The QModelIndex
/// \param role The model role to which we want the data
/// \return The QVariant associated at the given role
/// \note The returned QVariant should be freed by calling the dos_qvariant_delete() function
DOS_API DosQVariant *DOS_CALL dos_qmodelindex_data (const DosQModelIndex *vptr, int role);
/// \brief Calls the QModelIndex::parent() function
/// \param vptr The QModelIndex
/// \return The model parent QModelIndex
/// \note The returned QModelIndex should be freed by calling the dos_qmodelindex_delete() function
DOS_API DosQModelIndex *DOS_CALL dos_qmodelindex_parent (const DosQModelIndex *vptr);
/// \brief Calls the QModelIndex::child() function
/// \param vptr The QModelIndex
/// \param row The child row
/// \param column The child column
/// \return The model child QModelIndex at the given \p row and \p column
/// \note The returned QModelIndex should be freed by calling the dos_qmodelindex_delete() function
DOS_API DosQModelIndex *DOS_CALL dos_qmodelindex_child (const DosQModelIndex *vptr, int row, int column);
/// \brief Calls the QModelIndex::sibling() function
/// \param vptr The QModelIndex
/// \param row The sibling row
/// \param column The sibling column
/// \return The model sibling QModelIndex at the given \p row and \p column
/// \note The returned QModelIndex should be freed by calling the dos_qmodelindex_delete() function
DOS_API DosQModelIndex *DOS_CALL dos_qmodelindex_sibling(const DosQModelIndex *vptr, int row, int column);
/// \brief Calls the QModelIndex::operator=(const QModelIndex&) function
/// \param l The left side QModelIndex
/// \param r The right side QModelIndex
DOS_API void DOS_CALL dos_qmodelindex_assign(DosQModelIndex *l, const DosQModelIndex *r);
/// \brief Calls the QModelIndex::internalPointer function
/// \param vptr The QModelIndex
/// \return The internal pointer
DOS_API void* DOS_CALL dos_qmodelindex_internalPointer(DosQModelIndex *vptr);
/// @}
/// \defgroup QHash QHash
/// \brief Functions related to the QHash class
/// @{
/// \brief Create a new QHash<int, QByteArray>
/// \return A new QHash<int, QByteArray>
/// \note The retuned QHash<int, QByteArray> should be freed using
/// the dos_qhash_int_qbytearray_delete(DosQHashIntQByteArray *) function
DOS_API DosQHashIntQByteArray *DOS_CALL dos_qhash_int_qbytearray_create(void);
/// \brief Free the memory allocated for the QHash<int, QByteArray>
/// \param vptr The QHash<int, QByteArray>
DOS_API void DOS_CALL dos_qhash_int_qbytearray_delete(DosQHashIntQByteArray *vptr);
/// \brief Calls the QHash<int, QByteArray>::insert() function
/// \param vptr The QHash<int, QByteArray>
/// \param key The key
/// \param value The UTF-8 string
/// \note The \p value string is owned by the caller thus it will not be freed
DOS_API void DOS_CALL dos_qhash_int_qbytearray_insert(DosQHashIntQByteArray *vptr, int key, const char *value);
/// \brief Calls the QHash<int, QByteArray>::value() function
/// \param vptr The QHash<int, QByteArray>
/// \param key The key to which retrive the value
/// \return The UTF-8 string associated to the given value
/// \note The returned string should be freed by calling the dos_chararray_delete() function
DOS_API char *DOS_CALL dos_qhash_int_qbytearray_value(const DosQHashIntQByteArray *vptr, int key);
/// @}
/// \defgroup QResource QResource
/// \brief Functions related to the QResource class
/// @{
/// Register the given .rcc (compiled) file in the resource system
DOS_API void DOS_CALL dos_qresource_register(const char *filename);
/// @}
/// \defgroup QUrl QUrl
/// \brief Functions related to the QUrl class
/// @{
/// \brief Create a new QUrl
/// \param url The UTF-8 string that represents an url
/// \param parsingMode The parsing mode
/// \note The retuned QUrl should be freed using the dos_qurl_delete() function
DOS_API DosQUrl *DOS_CALL dos_qurl_create(const char *url, int parsingMode);
/// \brief Free the memory allocated for the QUrl
/// \param vptr The QUrl to be freed
DOS_API void DOS_CALL dos_qurl_delete(DosQUrl *vptr);
/// \brief Calls the QUrl::toString() function
/// \param vptr The QUrl
/// \return The url as an UTF-8 string
/// \note The returned string should be freed using the dos_chararray_delete() function
DOS_API char *DOS_CALL dos_qurl_to_string(const DosQUrl *vptr);
/// \brief Class the QUrl::isValid() function
/// \param vptr The QUrl
/// \return True if the QUrl is valid, false otherwise
DOS_API bool dos_qurl_isValid(const DosQUrl *vptr);
/// @}
/// \defgroup QDeclarative QDeclarative
/// \brief Functions related to the QDeclarative module
/// @{
/// \brief Register a type in order to be instantiable from QML
/// \return An integer value that represents the registration ID in the
/// qml environment
/// \note The \p qmlRegisterType is owned by the caller thus it will not be freed
DOS_API int DOS_CALL dos_qdeclarative_qmlregistertype(const QmlRegisterType *qmlRegisterType);
/// \brief Register a singleton type in order to be accessible from QML
/// \return An integer value that represents the registration ID in the
/// \note The \p qmlRegisterType is owned by the caller thus it will not be freed
DOS_API int DOS_CALL dos_qdeclarative_qmlregistersingletontype(const QmlRegisterType *qmlRegisterType);
/// @}
#ifdef __cplusplus
}
#endif
#endif // DOTHERSIDE_H

View File

@ -0,0 +1,388 @@
/*
Copyright (C) 2019 Filippo Cucchetto.
Contact: https://github.com/filcuc/dotherside
This file is part of the DOtherSide library.
The DOtherSide library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the license, or (at your opinion) any later version.
The DOtherSide library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the DOtherSide library. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* \file DOtherSideTypes.h
* \brief The DOtherSide types
*
* This file contains all the type definitions for structs and callbacks
* used by the DOtherSide library
*/
#ifndef DOTHERSIDETYPES_H
#define DOTHERSIDETYPES_H
#ifdef WIN32
#define DOS_CALL __cdecl
#else
#define DOS_CALL
#endif
#ifndef __cplusplus
#include <stdbool.h>
#endif
#ifdef __cplusplus
extern "C"
{
#endif
/// A pointer to a QVariant
typedef void DosQVariant;
/// A pointer to a QModelIndex
typedef void DosQModelIndex;
/// A pointer to a QAbstractItemModel
typedef void DosQAbstractItemModel;
/// A pointer to a QAbstractListModel
typedef void DosQAbstractListModel;
/// A pointer to a QAbstractTableModel
typedef void DosQAbstractTableModel;
/// A pointer to a QQmlApplicationEngine
typedef void DosQQmlApplicationEngine;
/// A pointer to a QQuickView
typedef void DosQQuickView;
/// A pointer to a QQmlContext
typedef void DosQQmlContext;
/// A pointer to a QHash<int,QByteArray>
typedef void DosQHashIntQByteArray;
/// A pointer to a QUrl
typedef void DosQUrl;
/// A pointer to a QMetaObject
typedef void DosQMetaObject;
/// A pointer to a QObject
typedef void DosQObject;
/// A pointer to a QQuickImageProvider
typedef void DosQQuickImageProvider;
/// A pointer to a QPixmap
typedef void DosPixmap;
/// A pixmap callback to be supplied to an image provider
/// \param id Image source id
/// \param width pointer to the width of the image
/// \param height pointer to the height of the image
/// \param requestedHeight sourceSize.height attribute
/// \param requestedWidth sourcesSize.width attribute
/// \param[out] result The result QPixmap. This should be assigned from the binded language
/// \note \p id is the trailing part of an image source url for example "image://<provider_id>/<id>
/// \note The \p result arg is an out parameter so it \b shouldn't be deleted. See the dos_qpixmap_assign
typedef void (DOS_CALL *RequestPixmapCallback)(const char *id, int *width, int *height, int requestedWidth, int requestedHeight, DosPixmap* result);
/// Called when a property is readed/written or a slot should be executed
/// \param self The pointer of QObject in the binded language
/// \param slotName The slotName as DosQVariant
/// \param argc The number of arguments
/// \param argv An array of DosQVariant pointers
/// \note The first argument of \p argv is always the return value of the called slot.
/// In other words the length of argv is always 1 + number of arguments of \p slotName.
/// The return value should be assigned and modified by calling the dos_qvariant_assign()
/// or other dos_qvariant_set... setters.
/// \note The \p slotName is owned by the library thus it \b shouldn't be deleted
/// \note The \p argv array is owned by the library thus it \b shouldn't be deleted
typedef void (DOS_CALL *DObjectCallback)(void *self, DosQVariant *slotName, int argc, DosQVariant **argv);
/// Called when the QAbstractItemModel::rowCount method must be executed
/// \param self The pointer of the QAbstractItemModel in the binded language
/// \param index The parent DosQModelIndex
/// \param[out] result The rowCount result. This must be deferenced and filled from the binded language
/// \note The \p parent QModelIndex is owned by the DOtherSide library thus it \b shouldn't be deleted
/// \note The \p result arg is an out parameter so it \b shouldn't be deleted
typedef void (DOS_CALL *RowCountCallback)(void *self, const DosQModelIndex *parent, int *result);
/// Called when the QAbstractItemModel::columnCount method must be executed
/// \param self The pointer to the QAbstractItemModel in the binded language
/// \param index The parent DosQModelIndex
/// \param[out] result The rowCount result. This must be deferenced and filled from the binded language
/// \note The \p parent QModelIndex is owned by the DOtherSide library thus it \b shouldn't be deleted
/// \note The \p result arg is an out parameter so it \b shouldn't be deleted
typedef void (DOS_CALL *ColumnCountCallback)(void *self, const DosQModelIndex *parent, int *result);
/// Called when the QAbstractItemModel::data method must be executed
/// \param self The pointer to the QAbstractItemModel in the binded language
/// \param index The DosQModelIndex to which we request the data
/// \param[out] result The DosQVariant result. This must be deferenced and filled from the binded language.
/// \note The \p index QModelIndex is owned by the DOtherSide library thus it \b shouldn't be deleted
/// \note The \p result arg is an out parameter so it \b shouldn't be deleted
typedef void (DOS_CALL *DataCallback)(void *self, const DosQModelIndex *index, int role, DosQVariant *result);
/// Called when the QAbstractItemModel::setData method must be executed
typedef void (DOS_CALL *SetDataCallback)(void *self, const DosQModelIndex *index, const DosQVariant *value, int role, bool *result);
/// Called when the QAbstractItemModel::roleNames method must be executed
typedef void (DOS_CALL *RoleNamesCallback)(void *self, DosQHashIntQByteArray *result);
/// Called when the QAbstractItemModel::flags method must be called
typedef void (DOS_CALL *FlagsCallback)(void *self, const DosQModelIndex *index, int *result);
/// Called when the QAbstractItemModel::headerData method must be called
typedef void (DOS_CALL *HeaderDataCallback)(void *self, int section, int orientation, int role, DosQVariant *result);
/// Called when the QAbstractItemModel::index method must be called
typedef void (DOS_CALL *IndexCallback)(void *self, int row, int column, const DosQModelIndex *parent, DosQModelIndex *result);
/// Called when the QAbstractItemModel::parent method must be called
typedef void (DOS_CALL *ParentCallback)(void *self, const DosQModelIndex *child, DosQModelIndex *result);
/// Called when the QAbstractItemModel::hasChildren method must be called
typedef void (DOS_CALL *HasChildrenCallback)(void *self, const DosQModelIndex *parent, bool *result);
/// Called when the QAbstractItemModel::canFetchMore method must be called
typedef void (DOS_CALL *CanFetchMoreCallback)(void *self, const DosQModelIndex *parent, bool *result);
/// Called when the QAbstractItemModel::fetchMore method must be called
typedef void (DOS_CALL *FetchMoreCallback)(void *self, const DosQModelIndex *parent);
/// Callback called from QML for creating a registered type
/**
* When a type is created through the QML engine a new QObject \p "Wrapper" is created. This becomes a proxy
* between the "default" QObject created through dos_qobject_create() and the QML engine. This imply that implementation
* for this callback should swap the DosQObject* stored in the binded language with the wrapper. At the end the wrapper
* becomes the owner of the original "default" DosQObject. Furthermore if the binding language is garbage collected you
* should disable (pin/ref) the original object and unref in the DeleteDObject() callback. Since the wrapper has been created
* from QML is QML that expect to free the memory for it thus it shouldn't be destroyed by the QObject in the binded language.
*
* An example of implementation in pseudocode is: \n
* \code{.nim}
proc createCallback(.....) =
# Call the constructor for the given type and create a QObject in Nim
let nimQObject = constructorMap[id]()
# Disable GC
GC.ref(nimQObject)
# Retrieve the DosQObject created dos_qobject_create() inside the nimQObject
*dosQObject = nimQObject.vptr
# Store the pointer to the nimQObject
*bindedQObject = cast[ptr](&nimQObject)
# Swap the vptr inside the nimQObject with the wrapper
nimQObject.vptr = wrapper
# The QObject in the Nim language should not destroy its inner DosQObject
nimQObject.owner = false
\endcode
* \param id This is the id for which we are requesting the creation.
* This is the same value that was returned during registration through the calls
* to dos_qdeclarative_qmlregistertype() or dos_qdeclarative_qmlregistersingletontype()
* \param wrapper This is the QObject wrapper that should be stored by the binded language and to which forward the
* DOtherSide calls
* \param bindedQObject This should be deferenced and assigned with the pointer of the QObject modeled in the binded language
* \param dosQObject This should be deferenced and assigned with the DosQObject pointer you gained from calling the dos_qobject_create() function
*/
typedef void (DOS_CALL *CreateDObject)(int id, void *wrapper, void **bindedQObject, void **dosQObject);
/// Callback invoked from QML for deleting a registered type
/**
* This is called when the wrapper gets deleted from QML. The implementation should unref/unpin
* the \p bindedQObject or delete it in the case of languages without GC
* \param id This is the type id for which we are requesting the deletion
* \param bindedQObject This is the pointer you given in the CreateDObject callback and you can use it
* for obtaining the QObject in your binded language. This allows you to unpin/unref it or delete it.
*/
typedef void (DOS_CALL *DeleteDObject)(int id, void *bindedQObject);
/// \brief Store an array of QVariant
/// \note This struct should be freed by calling dos_qvariantarray_delete(DosQVariantArray *ptr). This in turn
/// cleans up the internal array
struct DosQVariantArray {
/// The number of elements
int size;
/// The array
DosQVariant **data;
};
#ifndef __cplusplus
typedef struct DosQVariantArray DosQVariantArray;
#endif
/// The data needed for registering a custom type in the QML environment
/**
* This is used from dos_qdeclarative_qmlregistertype() and dos_qdeclarative_qmlregistersingletontype() calls.
* \see dos_qdeclarative_qmlregistertype()
* \see dos_qdeclarative_qmlregistersingletontype()
* \note All string and objects are considered to be owned by the caller thus they'll
* not be freed
*/
struct QmlRegisterType {
/// The Module major version
int major;
/// The Module minor version
int minor;
/// The Module uri
const char *uri;
/// The type name to be used in QML files
const char *qml;
/// The type QMetaObject
DosQMetaObject *staticMetaObject;
/// The callback invoked from QML when this type should be created
CreateDObject createDObject;
/// The callback invoked from QML when this type should be deleted
DeleteDObject deleteDObject;
};
#ifndef __cplusplus
typedef struct QmlRegisterType QmlRegisterType;
#endif
/// Represents a parameter definition
struct ParameterDefinition {
/// The parameter name
const char *name;
/// The parameter metatype
int metaType;
};
#ifndef __cplusplus
typedef struct ParameterDefinition ParameterDefinition;
#endif
/// Represents a single signal definition
struct SignalDefinition {
/// The signal name
const char *name;
/// The parameters count
int parametersCount;
/// The parameters
ParameterDefinition *parameters;
};
#ifndef __cplusplus
typedef struct SignalDefinition SignalDefinition;
#endif
/// Represents a set of signal definitions
struct SignalDefinitions {
/// The total number of signals
int count;
/// The signals
SignalDefinition *definitions;
};
#ifndef __cplusplus
typedef struct SignalDefinitions SignalDefinitions;
#endif
/// Represents a single slot definition
struct SlotDefinition {
/// The slot name
const char *name;
/// The slot return type
int returnMetaType;
/// The parameters count
int parametersCount;
/// The parameters
ParameterDefinition *parameters;
};
#ifndef __cplusplus
typedef struct SlotDefinition SlotDefinition;
#endif
/// Represents a set of slot definitions
struct SlotDefinitions {
/// The total number of slots
int count;
/// The slot definitions array
SlotDefinition *definitions;
};
#ifndef __cplusplus
typedef struct SlotDefinitions SlotDefinitions;
#endif
/// Represents a single property definition
struct PropertyDefinition {
/// The property name
const char *name;
/// The property metatype
int propertyMetaType;
/// The name of the property read slot
const char *readSlot;
/// \brief The name of the property write slot
/// \note Setting this to null means a readonly proeperty
const char *writeSlot;
/// \brief The name of the property notify signals
/// \note Setting this to null means a constant property
const char *notifySignal;
};
#ifndef __cplusplus
typedef struct PropertyDefinition PropertyDefinition;
#endif
/// Represents a set of property definitions
struct PropertyDefinitions {
/// The total number of properties
int count;
/// The property definitions array
PropertyDefinition *definitions;
};
#ifndef __cplusplus
typedef struct PropertyDefinitions PropertyDefinitions;
#endif
/// Incapsulate all the QAbstractItemModel callbacks
struct DosQAbstractItemModelCallbacks {
RowCountCallback rowCount;
ColumnCountCallback columnCount;
DataCallback data;
SetDataCallback setData;
RoleNamesCallback roleNames;
FlagsCallback flags;
HeaderDataCallback headerData;
IndexCallback index;
ParentCallback parent;
HasChildrenCallback hasChildren;
CanFetchMoreCallback canFetchMore;
FetchMoreCallback fetchMore;
};
#ifndef __cplusplus
typedef struct DosQAbstractItemModelCallbacks DosQAbstractItemModelCallbacks;
#endif
enum DosQEventLoopProcessEventFlag {
DosQEventLoopProcessEventFlagProcessAllEvents = 0x00,
DosQEventLoopProcessEventFlagExcludeUserInputEvents = 0x01,
DosQEventLoopProcessEventFlagProcessExcludeSocketNotifiers = 0x02,
DosQEventLoopProcessEventFlagProcessAllEventsWaitForMoreEvents = 0x03
};
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,176 @@
/*
Copyright (C) 2019 Filippo Cucchetto.
Contact: https://github.com/filcuc/dotherside
This file is part of the DOtherSide library.
The DOtherSide library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the license, or (at your opinion) any later version.
The DOtherSide library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the DOtherSide library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
// std
#include <memory>
// Qt
#include <QtCore/QtGlobal>
#include <QtCore/QString>
#include <QtCore/QMetaType>
// DOtherSide
#include "DOtherSide/DOtherSideTypes.h"
#include "DOtherSide/Utils.h"
namespace DOS {
struct ParameterDefinition {
ParameterDefinition(const ::ParameterDefinition &definition)
: name(QString::fromUtf8(definition.name))
, metaType(static_cast<QMetaType::Type>(definition.metaType))
{}
QString name;
QMetaType::Type metaType;
};
struct SignalDefinition {
SignalDefinition(QString n,
std::vector<ParameterDefinition> v)
: name(std::move(n))
, returnType(QMetaType::Void)
, parameters(std::move(v))
{}
SignalDefinition(::SignalDefinition cType)
: name(QString::fromUtf8(cType.name))
, returnType(QMetaType::Void)
{
parameters.reserve(static_cast<size_t>(cType.parametersCount));
for (int i = 0; i < cType.parametersCount; ++i)
parameters.emplace_back(cType.parameters[i]);
}
QString name;
QMetaType::Type returnType;
std::vector<ParameterDefinition> parameters;
};
struct SlotDefinition {
SlotDefinition(QString n,
QMetaType::Type t,
std::vector<ParameterDefinition> v)
: name(std::move(n))
, returnType(std::move(t))
, parameters(std::move(v))
{}
SlotDefinition(::SlotDefinition cType)
: name(QString::fromUtf8(cType.name))
, returnType(QMetaType::Type(cType.returnMetaType))
{
parameters.reserve(cType.parametersCount);
for (int i = 0; i < cType.parametersCount; ++i)
parameters.emplace_back(cType.parameters[i]);
}
QString name;
QMetaType::Type returnType;
std::vector<ParameterDefinition> parameters;
};
struct PropertyDefinition {
PropertyDefinition(QString n,
QMetaType::Type t,
QString r,
QString w,
QString s)
: name(std::move(n))
, type(std::move(t))
, readSlot(std::move(r))
, writeSlot(std::move(w))
, notifySignal(std::move(s))
{}
PropertyDefinition(::PropertyDefinition cType)
: name(cType.name)
, type(static_cast<QMetaType::Type>(cType.propertyMetaType))
, readSlot(QString::fromUtf8(cType.readSlot))
, writeSlot(QString::fromUtf8(cType.writeSlot))
, notifySignal(QString::fromUtf8(cType.notifySignal))
{}
QString name;
QMetaType::Type type;
QString readSlot;
QString writeSlot;
QString notifySignal;
};
using SignalDefinitions = std::vector<SignalDefinition>;
using SlotDefinitions = std::vector<SlotDefinition>;
using PropertyDefinitions = std::vector<PropertyDefinition>;
SignalDefinitions toVector(const ::SignalDefinitions &cType);
SlotDefinitions toVector(const ::SlotDefinitions &cType);
PropertyDefinitions toVector(const ::PropertyDefinitions &cType);
class DosIQMetaObjectHolder;
class DosIQMetaObject;
using DosIQMetaObjectPtr = std::shared_ptr<const DosIQMetaObject>;
class DosQMetaObject;
using OnMetaObject = std::function<DosIQMetaObjectHolder*()>;
using OnSlotExecuted = std::function<QVariant(const QString &, const std::vector<QVariant>&)>;
class SafeQMetaObjectPtr
{
public:
SafeQMetaObjectPtr(QMetaObject *ptr)
: m_d(ptr, ::free)
{}
SafeQMetaObjectPtr(SafeQMetaObjectPtr &&) = delete;
SafeQMetaObjectPtr(const SafeQMetaObjectPtr &) = delete;
SafeQMetaObjectPtr &operator=(const SafeQMetaObjectPtr &) = delete;
SafeQMetaObjectPtr &operator=(SafeQMetaObjectPtr &&) = delete;
operator bool() const noexcept {
return m_d != nullptr;
}
operator const QMetaObject *() const noexcept {
return m_d.get();
}
const QMetaObject *operator->() const noexcept {
return m_d.get();
}
void reset(QMetaObject *other) noexcept {
m_d.reset(other);
}
private:
std::unique_ptr<QMetaObject, void(*)(void *)> m_d;
};
struct QmlRegisterType {
int major;
int minor;
std::string uri;
std::string qml;
DosIQMetaObjectPtr staticMetaObject;
CreateDObject createDObject;
DeleteDObject deleteDObject;
};
} // namespace DOS

View File

@ -0,0 +1,100 @@
/*
Copyright (C) 2019 Filippo Cucchetto.
Contact: https://github.com/filcuc/dotherside
This file is part of the DOtherSide library.
The DOtherSide library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the license, or (at your opinion) any later version.
The DOtherSide library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the DOtherSide library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
// Qt
#include <QtCore/QModelIndex>
#include <QtCore/QVariant>
#include <QtCore/QHash>
#include <QtCore/QByteArray>
#include <QtCore/QVector>
// DOtherSide
#include "DOtherSide/DosIQObjectImpl.h"
namespace DOS {
class DosIQAbstractItemModelImpl : public DosIQObjectImpl
{
public:
/// Destructor
virtual ~DosIQAbstractItemModelImpl() = default;
/// @see QAbstractItemModel::setData
virtual bool defaultSetData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) = 0;
/// @see QAbstractItemModel::flags
virtual Qt::ItemFlags defaultFlags(const QModelIndex &index) const = 0;
/// @see QAbstractItemModel::headerData
virtual QVariant defaultHeaderData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const = 0;
/// @see QAbstractItemModel::roleNames
virtual QHash<int, QByteArray> defaultRoleNames() const = 0;
/// @see QAbstractItemModel::beginInsertRows
virtual void publicBeginInsertRows(const QModelIndex &index, int first, int last) = 0;
/// @see QAbstractItemModel::endInsertRows
virtual void publicEndInsertRows() = 0;
/// @see QAbstractItemModel::beginRemoveRows
virtual void publicBeginRemoveRows(const QModelIndex &index, int first, int last) = 0;
/// @see QAbstractItemModel::endRemoveRows
virtual void publicEndRemoveRows() = 0;
/// @see QAbstractItemModel::beginInsertColumns
virtual void publicBeginInsertColumns(const QModelIndex &index, int first, int last) = 0;
/// @see QAbstractItemModel::endInsertColumns
virtual void publicEndInsertColumns() = 0;
/// @see QAbstractItemModel::beginRemoveColumns
virtual void publicBeginRemoveColumns(const QModelIndex &index, int first, int last) = 0;
/// @see QAbstractItemModel::endRemoveColumns
virtual void publicEndRemoveColumns() = 0;
/// @see QAbstractItemModel::beginResetModel
virtual void publicBeginResetModel() = 0;
/// @see QAbstractItemModel::endResetModel
virtual void publicEndResetModel() = 0;
/// @see QAbstractItemModel::dataChanged
virtual void publicDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles = QVector<int>()) = 0;
/// @see QAbstractItemModel::createIndex
virtual QModelIndex publicCreateIndex(int row, int column, void *data = nullptr) const = 0;
/// @see QAbstractItemModel::hasChildren
virtual bool defaultHasChildren(const QModelIndex &parent) const = 0;
/// @see QAbstractItemModel::canFetchMore
virtual bool defaultCanFetchMore(const QModelIndex &parent) const = 0;
/// @see QAbstractItemModel::fetchMore
virtual void defaultFetchMore(const QModelIndex &parent) = 0;
/// @see QAbstractItemModel::hasIndex
virtual bool hasIndex(int row, int column, const QModelIndex &parent = QModelIndex()) const = 0;
};
} // namespace dos

View File

@ -0,0 +1,48 @@
/*
Copyright (C) 2019 Filippo Cucchetto.
Contact: https://github.com/filcuc/dotherside
This file is part of the DOtherSide library.
The DOtherSide library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the license, or (at your opinion) any later version.
The DOtherSide library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the DOtherSide library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
// std
#include <vector>
// Qt
#include <QtCore/QObject>
#include <QtCore/QString>
#include <QtCore/QVariant>
#include <QtCore/QMetaObject>
namespace DOS {
class DosIQObjectImpl
{
public:
/// Destructor
virtual ~DosIQObjectImpl() = default;
/// Emit the signal with the given name and arguments
virtual bool emitSignal(QObject *emitter, const QString &name, const std::vector<QVariant> &argumentsValues) = 0;
/// Return the metaObject
virtual const QMetaObject *metaObject() const = 0;
/// The qt_metacall implementation
virtual int qt_metacall(QMetaObject::Call, int, void **) = 0;
};
} // namespace dos

View File

@ -0,0 +1,186 @@
/*
Copyright (C) 2019 Filippo Cucchetto.
Contact: https://github.com/filcuc/dotherside
This file is part of the DOtherSide library.
The DOtherSide library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the license, or (at your opinion) any later version.
The DOtherSide library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the DOtherSide library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
// Qt
#include <QtCore/QAbstractItemModel>
#include <QtCore/QAbstractListModel>
#include <QtCore/QAbstractTableModel>
// DOtherSide
#include "DOtherSide/DOtherSideTypes.h"
#include "DOtherSide/DosQMetaObject.h"
#include "DOtherSide/DosIQAbstractItemModelImpl.h"
namespace DOS {
template<class T>
class DosQAbstractGenericModel : public T, public DosIQAbstractItemModelImpl
{
public:
/// Constructor
DosQAbstractGenericModel(void *modelObject,
DosIQMetaObjectPtr metaObject,
DObjectCallback dObjectCallback,
DosQAbstractItemModelCallbacks callbacks);
/// @see IDynamicQObject::emitSignal
bool emitSignal(QObject *emitter, const QString &name, const std::vector<QVariant> &argumentsValues) override;
/// @see QAbstractItemModel::metaObject()
const QMetaObject *metaObject() const override;
/// @see QAbstractItemModel::qt_metacall
int qt_metacall(QMetaObject::Call, int, void **) override;
/// Return the model's row count
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
/// Return the model's column count
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
/// Return the QVariant at the given index
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
/// Sets the QVariant value at the given index and role
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
/// Return the item flags for the given index
Qt::ItemFlags flags(const QModelIndex &index) const override;
/// Return the data for the given role and section in the header with the specified orientation
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
/// Return the index associated at the given row and column
QModelIndex index(int row, int column, const QModelIndex &parent) const override;
/// Return the parent for the given child index
QModelIndex parent(const QModelIndex &child) const override;
/// Return the dModelPointer
void *modelObject();
/// Return the roleNames
QHash<int, QByteArray> roleNames() const override;
/// Expose beginInsertRows
void publicBeginInsertRows(const QModelIndex &index, int first, int last) override;
/// Expose endInsertRows
void publicEndInsertRows() override;
/// Expose beginRemoveRows
void publicBeginRemoveRows(const QModelIndex &index, int first, int last) override;
/// Expose endInsertRows
void publicEndRemoveRows() override;
/// Expose beginInsertColumns
void publicBeginInsertColumns(const QModelIndex &index, int first, int last) override;
/// Expose endInsertColumns
void publicEndInsertColumns() override;
/// Expose beginRemoveColumns
void publicBeginRemoveColumns(const QModelIndex &index, int first, int last) override;
/// Expose endInsertColumns
void publicEndRemoveColumns() override;
/// Expose beginResetModel
void publicBeginResetModel() override;
/// Expose endResetModel
void publicEndResetModel() override;
/// Expose dataChanged
void publicDataChanged(const QModelIndex &topLeft,
const QModelIndex &bottomRight,
const QVector<int> &roles = QVector<int>()) override;
/// Expose createIndex
QModelIndex publicCreateIndex(int row, int column, void *data = nullptr) const override;
/// Expose the not overriden flags
Qt::ItemFlags defaultFlags(const QModelIndex &index) const override;
/// Expose the not overriden header data
QVariant defaultHeaderData(int section, Qt::Orientation orientation, int role) const override;
/// Expose the not overriden roleNames
QHash<int, QByteArray> defaultRoleNames() const override;
/// Expose the not overriden setData
bool defaultSetData(const QModelIndex &index, const QVariant &value, int role) override;
/// Expose the hasChildren
bool hasChildren(const QModelIndex &parent = QModelIndex()) const override;
/// Expose hasIndex
bool hasIndex(int row, int column, const QModelIndex &parent) const override;
/// Expose the canFetchMore
bool canFetchMore(const QModelIndex &parent) const override;
/// Expose the not override canFetchMore
bool defaultCanFetchMore(const QModelIndex &parent) const override;
/// Expose the fetchMore
void fetchMore(const QModelIndex &parent) override;
/// Expose the not overriden fetchMore
void defaultFetchMore(const QModelIndex &parent) override;
private:
std::unique_ptr<DosIQObjectImpl> m_impl;
void *m_modelObject;
DosQAbstractItemModelCallbacks m_callbacks;
};
class DosQAbstractItemModel : public DosQAbstractGenericModel<QAbstractItemModel>
{
public:
using DosQAbstractGenericModel::DosQAbstractGenericModel;
bool defaultHasChildren(const QModelIndex &parent) const override;
};
class DosQAbstractTableModel : public DosQAbstractGenericModel<QAbstractTableModel>
{
public:
using DosQAbstractGenericModel::DosQAbstractGenericModel;
QModelIndex defaultParent(const QModelIndex &child) const;
QModelIndex defaultIndex(int row, int column, const QModelIndex &parent = QModelIndex()) const;
bool defaultHasChildren(const QModelIndex &parent) const override;
};
class DosQAbstractListModel : public DosQAbstractGenericModel<QAbstractListModel>
{
public:
using DosQAbstractGenericModel::DosQAbstractGenericModel;
QModelIndex defaultParent(const QModelIndex &child) const;
QModelIndex defaultIndex(int row, int column, const QModelIndex &parent = QModelIndex()) const;
int defaultColumnCount(const QModelIndex &parent) const;
bool defaultHasChildren(const QModelIndex &parent) const override;
};
} // namespace DOS

View File

@ -0,0 +1,345 @@
/*
Copyright (C) 2019 Filippo Cucchetto.
Contact: https://github.com/filcuc/dotherside
This file is part of the DOtherSide library.
The DOtherSide library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the license, or (at your opinion) any later version.
The DOtherSide library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the DOtherSide library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "DOtherSide/DosQAbstractItemModel.h"
#include "DOtherSide/DosQMetaObject.h"
namespace DOS {
template <int, int>
class DosQAbstractItemModelWrapper : public QAbstractItemModel, public DosIQObjectImpl
{
public:
static const QMetaObject staticMetaObject;
/// Constructor
DosQAbstractItemModelWrapper(QObject *parent = nullptr);
/// Destructor
~DosQAbstractItemModelWrapper() override;
/// @see DosIQObjectImpl::metaObject
const QMetaObject *metaObject() const override;
/// @see DosIQObjectImpl::qt_metacall
int qt_metacall(QMetaObject::Call, int, void **) override;
/// @see DosIQObjectImpl::emitSignal
bool emitSignal(QObject *emitter, const QString &name, const std::vector<QVariant> &argumentsValues) override;
/// Return the qml registration type
static const QmlRegisterType &qmlRegisterType();
/// Sets the qml registration type
static void setQmlRegisterType(QmlRegisterType data);
/// Sets the static metaobject
static void setStaticMetaObject(const QMetaObject &metaObject);
/// Sets the qmlRegisterType id
static void setId(int id);
/// @see QAbstractItemModel::rowCount
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
/// @see QAbstractItemModel::columnCount
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
/// @see QAbstractItemModel::data
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
/// @see QAbstractItemModel::setData
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
/// @see QAbstractItemModel::flags
Qt::ItemFlags flags(const QModelIndex &index) const override;
/// @see QAbstractItemModel::headerData
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
/// @see QAbstractItemModel::roleNames
QHash<int, QByteArray> roleNames() const override;
/// @see QAbstractItemModel::index
QModelIndex index(int row, int column, const QModelIndex &parent) const override;
/// @see QAbstractItemModel::parent
QModelIndex parent(const QModelIndex &child) const override;
private:
void *m_dObject;
QAbstractItemModel *m_impl;
static int m_id;
static QmlRegisterType m_data;
};
template<int N, int M>
const QMetaObject DosQAbstractItemModelWrapper<N, M>::staticMetaObject = QAbstractItemModel::staticMetaObject;
template<int N, int M>
QmlRegisterType DosQAbstractItemModelWrapper<N, M>::m_data;
template<int N, int M>
int DosQAbstractItemModelWrapper<N, M>::m_id = -1;
template<int N, int M>
DosQAbstractItemModelWrapper<N, M>::DosQAbstractItemModelWrapper(QObject *parent)
: QAbstractItemModel(parent)
, m_dObject(nullptr)
, m_impl(nullptr)
{
void *impl = nullptr;
m_data.createDObject(m_id, static_cast<QObject *>(this), &m_dObject, &impl);
beginResetModel();
m_impl = dynamic_cast<QAbstractItemModel *>(static_cast<QObject *>(impl));
QObject::connect(m_impl, &QAbstractItemModel::rowsAboutToBeInserted, this, &DosQAbstractItemModelWrapper<N, M>::beginInsertRows);
QObject::connect(m_impl, &QAbstractItemModel::rowsInserted, this, &DosQAbstractItemModelWrapper<N, M>::endInsertRows);
QObject::connect(m_impl, &QAbstractItemModel::rowsAboutToBeRemoved, this, &DosQAbstractItemModelWrapper<N, M>::beginRemoveRows);
QObject::connect(m_impl, &QAbstractItemModel::rowsRemoved, this, &DosQAbstractItemModelWrapper<N, M>::endRemoveRows);
QObject::connect(m_impl, &QAbstractItemModel::rowsAboutToBeMoved, this, &DosQAbstractItemModelWrapper<N, M>::beginMoveRows);
QObject::connect(m_impl, &QAbstractItemModel::rowsMoved, this, &DosQAbstractItemModelWrapper<N, M>::endMoveRows);
QObject::connect(m_impl, &QAbstractItemModel::columnsAboutToBeInserted, this, &DosQAbstractItemModelWrapper<N, M>::beginInsertColumns);
QObject::connect(m_impl, &QAbstractItemModel::columnsInserted, this, &DosQAbstractItemModelWrapper<N, M>::endInsertColumns);
QObject::connect(m_impl, &QAbstractItemModel::columnsAboutToBeRemoved, this, &DosQAbstractItemModelWrapper<N, M>::beginRemoveColumns);
QObject::connect(m_impl, &QAbstractItemModel::columnsRemoved, this, &DosQAbstractItemModelWrapper<N, M>::endRemoveColumns);
QObject::connect(m_impl, &QAbstractItemModel::columnsAboutToBeMoved, this, &DosQAbstractItemModelWrapper<N, M>::beginMoveColumns);
QObject::connect(m_impl, &QAbstractItemModel::columnsMoved, this, &DosQAbstractItemModelWrapper<N, M>::endMoveColumns);
QObject::connect(m_impl, &QAbstractItemModel::modelAboutToBeReset, this, &DosQAbstractItemModelWrapper<N, M>::beginResetModel);
QObject::connect(m_impl, &QAbstractItemModel::modelReset, this, &DosQAbstractItemModelWrapper<N, M>::endResetModel);
QObject::connect(m_impl, &QAbstractItemModel::dataChanged, this, &DosQAbstractItemModelWrapper<N, M>::dataChanged);
QObject::connect(m_impl, &QAbstractItemModel::layoutAboutToBeChanged, this, &DosQAbstractItemModelWrapper<N, M>::layoutAboutToBeChanged);
QObject::connect(m_impl, &QAbstractItemModel::layoutChanged, this, &DosQAbstractItemModelWrapper<N, M>::layoutChanged);
endResetModel();
Q_ASSERT(m_dObject);
Q_ASSERT(m_impl);
}
template<int N, int M>
DosQAbstractItemModelWrapper<N, M>::~DosQAbstractItemModelWrapper()
{
m_data.deleteDObject(m_id, m_dObject);
m_dObject = nullptr;
delete m_impl;
m_impl = nullptr;
}
template<int N, int M>
const QMetaObject *DosQAbstractItemModelWrapper<N, M>::metaObject() const
{
Q_ASSERT(m_impl);
return m_impl->metaObject();
}
template<int N, int M>
int DosQAbstractItemModelWrapper<N, M>::qt_metacall(QMetaObject::Call call, int index, void **args)
{
Q_ASSERT(m_impl);
return m_impl->qt_metacall(call, index, args);
}
template<int N, int M>
bool DosQAbstractItemModelWrapper<N, M>::emitSignal(QObject *emitter, const QString &name, const std::vector<QVariant> &argumentsValues)
{
Q_ASSERT(m_impl);
return dynamic_cast<DosIQObjectImpl *>(this)->emitSignal(this, name, argumentsValues);
}
template<int N, int M>
void DosQAbstractItemModelWrapper<N, M>::setQmlRegisterType(QmlRegisterType data)
{
m_data = std::move(data);
}
template<int N, int M>
void DosQAbstractItemModelWrapper<N, M>::setStaticMetaObject(const QMetaObject &metaObject)
{
*(const_cast<QMetaObject *>(&staticMetaObject)) = metaObject;
}
template<int N, int M>
void DosQAbstractItemModelWrapper<N, M>::setId(int id)
{
m_id = id;
}
template<int N, int M>
int DosQAbstractItemModelWrapper<N, M>::rowCount(const QModelIndex &parent) const
{
Q_ASSERT(m_impl);
return m_impl->rowCount(parent);
}
template<int N, int M>
int DosQAbstractItemModelWrapper<N, M>::columnCount(const QModelIndex &parent) const
{
Q_ASSERT(m_impl);
return m_impl->columnCount(parent);
}
template<int N, int M>
QVariant DosQAbstractItemModelWrapper<N, M>::data(const QModelIndex &index, int role) const
{
Q_ASSERT(m_impl);
return m_impl->data(index, role);
}
template<int N, int M>
bool DosQAbstractItemModelWrapper<N, M>::setData(const QModelIndex &index, const QVariant &value, int role)
{
Q_ASSERT(m_impl);
return m_impl->setData(index, value, role);
}
template<int N, int M>
Qt::ItemFlags DosQAbstractItemModelWrapper<N, M>::flags(const QModelIndex &index) const
{
Q_ASSERT(m_impl);
return m_impl->flags(index);
}
template<int N, int M>
QVariant DosQAbstractItemModelWrapper<N, M>::headerData(int section, Qt::Orientation orientation, int role) const
{
Q_ASSERT(m_impl);
return m_impl->headerData(section, orientation, role);
}
template<int N, int M>
QHash<int, QByteArray> DosQAbstractItemModelWrapper<N, M>::roleNames() const
{
Q_ASSERT(m_impl);
return m_impl->roleNames();
}
template<int N, int M>
QModelIndex DosQAbstractItemModelWrapper<N, M>::index(int row, int column, const QModelIndex &parent) const
{
Q_ASSERT(m_impl);
return m_impl->index(row, column, parent);
}
template<int N, int M>
QModelIndex DosQAbstractItemModelWrapper<N, M>::parent(const QModelIndex &child) const
{
Q_ASSERT(m_impl);
return m_impl->parent(child);
}
template<int N, int M>
const QmlRegisterType &DosQAbstractItemModelWrapper<N, M>::qmlRegisterType()
{
return m_data;
}
namespace DQAIMW {
template<int N>
using RegisterTypeQObject = DosQAbstractItemModelWrapper<N, 0>;
template<int N>
int dosQmlRegisterType(QmlRegisterType args)
{
RegisterTypeQObject<N>::setQmlRegisterType(std::move(args));
const QmlRegisterType &type = RegisterTypeQObject<N>::qmlRegisterType();
RegisterTypeQObject<N>::setStaticMetaObject(*(type.staticMetaObject->metaObject()));
int result = qmlRegisterType<RegisterTypeQObject<N>>(type.uri.c_str(), type.major, type.minor, type.qml.c_str());
RegisterTypeQObject<N>::setId(result);
return result;
}
template<int N>
struct DosQmlRegisterHelper {
static int Register(int i, QmlRegisterType args)
{
if (i > N)
return -1;
else if (i == N)
return dosQmlRegisterType<N>(std::move(args));
else
return DosQmlRegisterHelper < N - 1 >::Register(i, std::move(args));
}
};
template<>
struct DosQmlRegisterHelper<0> {
static int Register(int i, QmlRegisterType args)
{
return i == 0 ? dosQmlRegisterType<0>(std::move(args)) : -1;
}
};
int dosQmlRegisterType(QmlRegisterType args)
{
static int i = 0;
return DosQmlRegisterHelper<35>::Register(i++, std::move(args));
}
template<int N>
using RegisterSingletonTypeQObject = DosQAbstractItemModelWrapper<N, 1>;
template<int N>
QObject *singletontype_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
{
return new RegisterSingletonTypeQObject<N>();
}
template<int N>
int dosQmlRegisterSingletonType(QmlRegisterType args)
{
using Func = QObject * (*)(QQmlEngine *, QJSEngine *);
Func f = singletontype_provider<N>;
RegisterSingletonTypeQObject<N>::setQmlRegisterType(std::move(args));
const QmlRegisterType &type = RegisterSingletonTypeQObject<N>::qmlRegisterType();
RegisterSingletonTypeQObject<N>::setStaticMetaObject(*(type.staticMetaObject->metaObject()));
int result = qmlRegisterSingletonType<RegisterSingletonTypeQObject<N>>(type.uri.c_str(), type.major, type.minor, type.qml.c_str(), f);
RegisterSingletonTypeQObject<N>::setId(result);
return result;
}
template<int N>
struct DosQmlRegisterSingletonHelper {
static int Register(int i, QmlRegisterType args)
{
if (i > N)
return -1;
else if (i == N)
return dosQmlRegisterSingletonType<N>(std::move(args));
else
return DosQmlRegisterSingletonHelper < N - 1 >::Register(i, std::move(args));
}
};
template<>
struct DosQmlRegisterSingletonHelper<0> {
static int Register(int i, QmlRegisterType args)
{
return i == 0 ? dosQmlRegisterSingletonType<0>(std::move(args)) : -1;
}
};
int dosQmlRegisterSingletonType(QmlRegisterType args)
{
static int i = 0;
return DosQmlRegisterSingletonHelper<35>::Register(i++, std::move(args));
}
}
}

View File

@ -0,0 +1,27 @@
/*
Copyright (C) 2019 Filippo Cucchetto.
Contact: https://github.com/filcuc/dotherside
This file is part of the DOtherSide library.
The DOtherSide library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the license, or (at your opinion) any later version.
The DOtherSide library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the DOtherSide library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "DOtherSide/DOtherSideTypes.h"
namespace DOS {
int dosQmlRegisterType(QmlRegisterType args);
int dosQmlRegisterSingletonType(QmlRegisterType args);
}

View File

@ -0,0 +1,130 @@
/*
Copyright (C) 2019 Filippo Cucchetto.
Contact: https://github.com/filcuc/dotherside
This file is part of the DOtherSide library.
The DOtherSide library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the license, or (at your opinion) any later version.
The DOtherSide library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the DOtherSide library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
// std
#include <memory>
#include <unordered_map>
#include <tuple>
// Qt
#include <QtCore/QObject>
#include <QtCore/QString>
#include <QtCore/QHash>
#include <QtCore/QMetaMethod>
#include <QtCore/QAbstractItemModel>
#include <QtCore/QAbstractListModel>
#include <QtCore/QAbstractTableModel>
// DOtherSide
#include "DOtherSide/DOtherSideTypesCpp.h"
namespace DOS {
/// This the QMetaObject wrapper
class DosIQMetaObject
{
public:
virtual ~DosIQMetaObject() = default;
virtual const QMetaObject *metaObject() const = 0;
virtual QMetaMethod signal(const QString &signalName) const = 0;
virtual QMetaMethod readSlot(const char *propertyName) const = 0;
virtual QMetaMethod writeSlot(const char *propertyName) const = 0;
virtual const DosIQMetaObject *superClassDosMetaObject() const = 0;
};
/// Base class for any DosIQMetaObject
class BaseDosQMetaObject : public DosIQMetaObject
{
public:
BaseDosQMetaObject(QMetaObject *metaObject);
const QMetaObject *metaObject() const override;
QMetaMethod signal(const QString &signalName) const override;
QMetaMethod readSlot(const char *propertyName) const override;
QMetaMethod writeSlot(const char *propertyName) const override;
const DosIQMetaObject *superClassDosMetaObject() const override;
protected:
SafeQMetaObjectPtr m_metaObject;
};
/// This is the DosQMetaObject for a QObject
class DosQObjectMetaObject : public BaseDosQMetaObject
{
public:
DosQObjectMetaObject();
};
/// This is the DosQMetaObject for a QAbstractItemModel
template<class T>
class DosQAbstractGenericModelMetaObject : public BaseDosQMetaObject
{
public:
DosQAbstractGenericModelMetaObject();
};
using DosQAbstractItemModelMetaObject = DosQAbstractGenericModelMetaObject<QAbstractItemModel>;
using DosQAbstractListModelMetaObject = DosQAbstractGenericModelMetaObject<QAbstractListModel>;
using DosQAbstractTableModelMetaObject = DosQAbstractGenericModelMetaObject<QAbstractTableModel>;
/// This the generic version used by subclasses of QObject or QAbstractItemModels
class DosQMetaObject : public BaseDosQMetaObject
{
public:
DosQMetaObject(DosIQMetaObjectPtr superClassDosMetaObject,
const QString &className,
const SignalDefinitions &signalDefinitions,
const SlotDefinitions &slotDefinitions,
const PropertyDefinitions &propertyDefinitions);
QMetaMethod signal(const QString &signalName) const override;
QMetaMethod readSlot(const char *propertyName) const override;
QMetaMethod writeSlot(const char *propertyName) const override;
const DosIQMetaObject *superClassDosMetaObject() const override;
private:
QMetaObject *createMetaObject(const QString &className,
const SignalDefinitions &signalDefinitions,
const SlotDefinitions &slotDefinitions,
const PropertyDefinitions &propertyDefinitions);
const DosIQMetaObjectPtr m_superClassDosMetaObject;
QHash<QString, int> m_signalIndexByName;
QHash<QString, QPair<int, int>> m_propertySlots;
};
/// This class simply holds a ptr to a IDosQMetaObject
/// It's created and passed to the binded language
class DosIQMetaObjectHolder
{
public:
DosIQMetaObjectHolder(DosIQMetaObjectPtr ptr)
: m_data(std::move(ptr))
{}
const DosIQMetaObjectPtr &data() const
{
return m_data;
}
private:
const DosIQMetaObjectPtr m_data;
};
} // namespace DOS

View File

@ -0,0 +1,51 @@
/*
Copyright (C) 2019 Filippo Cucchetto.
Contact: https://github.com/filcuc/dotherside
This file is part of the DOtherSide library.
The DOtherSide library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the license, or (at your opinion) any later version.
The DOtherSide library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the DOtherSide library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
// Qt
#include <QtCore/QObject>
#include <functional>
// DOtherSide
#include "DOtherSideTypesCpp.h"
#include "DOtherSide/DosIQObjectImpl.h"
namespace DOS {
/// This class model a QObject
class DosQObject : public QObject, public DosIQObjectImpl
{
public:
/// Constructor
DosQObject(void *dObjectPointer, DosIQMetaObjectPtr metaObject, DObjectCallback dObjectCallback);
/// Emit a signal
bool emitSignal(QObject *emitter, const QString &name, const std::vector<QVariant> &arguments) override;
/// Return the metaObject
const QMetaObject *metaObject() const override;
/// The qt_metacall
int qt_metacall(QMetaObject::Call, int, void **) override;
private:
std::unique_ptr<DosIQObjectImpl> m_impl;
};
} // namespace DOS

View File

@ -0,0 +1,71 @@
/*
Copyright (C) 2019 Filippo Cucchetto.
Contact: https://github.com/filcuc/dotherside
This file is part of the DOtherSide library.
The DOtherSide library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the license, or (at your opinion) any later version.
The DOtherSide library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the DOtherSide library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
// std
#include <vector>
// Qt
#include <QtCore/QMutex>
#include <QtCore/QString>
#include <QtCore/QVariant>
// DOtherSide
#include "DOtherSide/DosQObject.h"
#include "DOtherSide/DOtherSideTypesCpp.h"
namespace DOS {
/// This class implement the interface IDosQObject
/// and it's injected in DosQObject
class DosQObjectImpl : public DosIQObjectImpl
{
public:
using ParentMetaCall = std::function<int(QMetaObject::Call, int, void **)>;
/// Constructor
DosQObjectImpl(ParentMetaCall parentMetaCall,
std::shared_ptr<const DosIQMetaObject> metaObject,
void *dObjectPointer,
DObjectCallback dObjectCallback);
/// @see IDosQObject::emitSignal
bool emitSignal(QObject *emitter, const QString &name, const std::vector<QVariant> &arguments) override;
/// @see IDosQObject::metaObject()
const QMetaObject *metaObject() const override;
/// @see IDosQObject::qt_metacall
int qt_metacall(QMetaObject::Call, int, void **) override;
private:
bool executeSlot(const QMetaMethod &method, void **args, int argumentsOffset = 1);
bool executeSlot(int index, void **args);
QVariant executeSlot(const QString &name, const std::vector<QVariant> &args);
bool readProperty(int index, void **args);
bool writeProperty(int index, void **args);
const ParentMetaCall m_parentMetaCall;
const std::shared_ptr<const DosIQMetaObject> m_metaObject;
void* const m_dObjectPointer = nullptr;
const DObjectCallback m_dObjectCallback;
};
} // namespace DOS

View File

@ -0,0 +1,219 @@
/*
Copyright (C) 2019 Filippo Cucchetto.
Contact: https://github.com/filcuc/dotherside
This file is part of the DOtherSide library.
The DOtherSide library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the license, or (at your opinion) any later version.
The DOtherSide library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the DOtherSide library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "DOtherSide/DosQObject.h"
#include "DOtherSide/DosQMetaObject.h"
#include <QtQml/qqml.h>
namespace DOS {
template<int, int>
class DosQObjectWrapper : public QObject, public DosIQObjectImpl
{
public:
static const QMetaObject staticMetaObject;
/// Constructor
DosQObjectWrapper(QObject *parent = nullptr);
/// Destructor
~DosQObjectWrapper() override;
/// @see DosIQObjectImpl::metaObject
const QMetaObject *metaObject() const override;
/// @see DosIQObjectImpl::qt_metacall
int qt_metacall(QMetaObject::Call, int, void **) override;
/// @see DosIQObjectImpl::emitSignal
bool emitSignal(QObject *emitter, const QString &name, const std::vector<QVariant> &argumentsValues) override;
static const QmlRegisterType &qmlRegisterType();
static void setQmlRegisterType(QmlRegisterType data);
static void setStaticMetaObject(const QMetaObject &metaObject);
static void setId(int id);
private:
void *m_dObject;
DosQObject *m_impl;
static int m_id;
static QmlRegisterType m_data;
};
template<int N, int M>
const QMetaObject DosQObjectWrapper<N, M>::staticMetaObject = QObject::staticMetaObject;
template<int N, int M>
QmlRegisterType DosQObjectWrapper<N, M>::m_data;
template<int N, int M>
int DosQObjectWrapper<N, M>::m_id = -1;
template<int N, int M>
DosQObjectWrapper<N, M>::DosQObjectWrapper(QObject *parent)
: QObject(parent)
, m_dObject(nullptr)
, m_impl(nullptr)
{
void *impl = nullptr;
m_data.createDObject(m_id, static_cast<QObject *>(this), &m_dObject, &impl);
m_impl = dynamic_cast<DosQObject *>(static_cast<QObject *>(impl));
Q_ASSERT(m_dObject);
Q_ASSERT(m_impl);
}
template<int N, int M>
DosQObjectWrapper<N, M>::~DosQObjectWrapper()
{
m_data.deleteDObject(m_id, m_dObject);
m_dObject = nullptr;
delete dynamic_cast<QObject *>(m_impl);
m_impl = nullptr;
}
template<int N, int M>
const QMetaObject *DosQObjectWrapper<N, M>::metaObject() const
{
Q_ASSERT(m_impl);
return m_impl->metaObject();
}
template<int N, int M>
int DosQObjectWrapper<N, M>::qt_metacall(QMetaObject::Call call, int index, void **args)
{
Q_ASSERT(m_impl);
return m_impl->qt_metacall(call, index, args);
}
template<int N, int M>
bool DosQObjectWrapper<N, M>::emitSignal(QObject *emitter, const QString &name, const std::vector<QVariant> &argumentsValues)
{
Q_ASSERT(m_impl);
return m_impl->emitSignal(this, name, argumentsValues);
}
template<int N, int M>
void DosQObjectWrapper<N, M>::setQmlRegisterType(QmlRegisterType data)
{
m_data = std::move(data);
}
template<int N, int M>
void DosQObjectWrapper<N, M>::setStaticMetaObject(const QMetaObject &metaObject)
{
*(const_cast<QMetaObject *>(&staticMetaObject)) = metaObject;
}
template<int N, int M>
void DosQObjectWrapper<N, M>::setId(int id)
{
m_id = id;
}
template<int N, int M>
const QmlRegisterType &DosQObjectWrapper<N, M>::qmlRegisterType()
{
return m_data;
}
namespace DQOW {
template<int N>
using RegisterTypeQObject = DosQObjectWrapper<N, 0>;
template<int N>
int dosQmlRegisterType(QmlRegisterType args)
{
RegisterTypeQObject<N>::setQmlRegisterType(std::move(args));
const QmlRegisterType &type = RegisterTypeQObject<N>::qmlRegisterType();
RegisterTypeQObject<N>::setStaticMetaObject(*(type.staticMetaObject->metaObject()));
int result = qmlRegisterType<RegisterTypeQObject<N>>(type.uri.c_str(), type.major, type.minor, type.qml.c_str());
RegisterTypeQObject<N>::setId(result);
return result;
}
template<int N>
struct DosQmlRegisterHelper {
static int Register(int i, QmlRegisterType args)
{
if (i > N)
return -1;
else if (i == N)
return dosQmlRegisterType<N>(std::move(args));
else
return DosQmlRegisterHelper < N - 1 >::Register(i, std::move(args));
}
};
template<>
struct DosQmlRegisterHelper<0> {
static int Register(int i, QmlRegisterType args)
{
return i == 0 ? dosQmlRegisterType<0>(std::move(args)) : -1;
}
};
template<int N>
using RegisterSingletonTypeQObject = DosQObjectWrapper<N, 1>;
template<int N>
QObject *singletontype_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
{
return new RegisterSingletonTypeQObject<N>();
}
template<int N>
int dosQmlRegisterSingletonType(QmlRegisterType args)
{
using Func = QObject * (*)(QQmlEngine *, QJSEngine *);
Func f = singletontype_provider<N>;
RegisterSingletonTypeQObject<N>::setQmlRegisterType(std::move(args));
const QmlRegisterType &type = RegisterSingletonTypeQObject<N>::qmlRegisterType();
RegisterSingletonTypeQObject<N>::setStaticMetaObject(*(type.staticMetaObject->metaObject()));
int result = qmlRegisterSingletonType<RegisterSingletonTypeQObject<N>>(type.uri.c_str(), type.major, type.minor, type.qml.c_str(), f);
RegisterSingletonTypeQObject<N>::setId(result);
return result;
}
template<int N>
struct DosQmlRegisterSingletonHelper {
static int Register(int i, QmlRegisterType args)
{
if (i > N)
return -1;
else if (i == N)
return dosQmlRegisterSingletonType<N>(std::move(args));
else
return DosQmlRegisterSingletonHelper < N - 1 >::Register(i, std::move(args));
}
};
template<>
struct DosQmlRegisterSingletonHelper<0> {
static int Register(int i, QmlRegisterType args)
{
return i == 0 ? dosQmlRegisterSingletonType<0>(std::move(args)) : -1;
}
};
}
}

View File

@ -0,0 +1,40 @@
/*
Copyright (C) 2019 Filippo Cucchetto.
Contact: https://github.com/filcuc/dotherside
This file is part of the DOtherSide library.
The DOtherSide library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the license, or (at your opinion) any later version.
The DOtherSide library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the DOtherSide library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
// std
#include <iostream>
// Qt
#include <QtGui/QPixmap>
#include <QtQuick/QQuickImageProvider>
#include "DOtherSideTypes.h"
class DosImageProvider : public QQuickImageProvider
{
public:
DosImageProvider(RequestPixmapCallback callback);
QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize) override;
private:
RequestPixmapCallback m_pixmap_callback;
};

View File

@ -0,0 +1,96 @@
/*
Copyright (C) 2019 Filippo Cucchetto.
Contact: https://github.com/filcuc/dotherside
This file is part of the DOtherSide library.
The DOtherSide library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the license, or (at your opinion) any later version.
The DOtherSide library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the DOtherSide library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
// std
#include <algorithm>
#include <functional>
#include <type_traits>
// Qt
#include <QtCore/QtGlobal>
namespace DOS {
template<class Lambda>
struct DeferHelper {
DeferHelper(Lambda lambda)
: m_lambda(std::move(lambda))
{}
~DeferHelper()
{
try {
m_lambda();
} catch (...) {}
}
Lambda m_lambda;
};
template<typename Lambda>
DeferHelper<Lambda> defer(Lambda l)
{
return DeferHelper<Lambda>(std::move(l));
}
template <typename T>
struct wrapped_array {
wrapped_array(T *first, T *last) : begin_ {first}, end_ {last} {}
wrapped_array(T *first, std::ptrdiff_t size)
: wrapped_array {first, first + size} {}
T *begin() const Q_DECL_NOEXCEPT
{
return begin_;
}
T *end() const Q_DECL_NOEXCEPT
{
return end_;
}
T *begin_;
T *end_;
};
template <typename T>
wrapped_array<T> wrap_array(T *first, std::ptrdiff_t size) Q_DECL_NOEXCEPT
{ return {first, size}; }
template <typename T, typename G>
std::vector<T> toVector(G *first, std::ptrdiff_t size) Q_DECL_NOEXCEPT {
const wrapped_array<G> array = wrap_array(first, size);
std::vector<T> result;
for (auto it = array.begin(); it != array.end(); ++it)
result.emplace_back(T(*it));
return result;
}
template <typename T, typename K, typename R = typename std::result_of<K(T)>::type>
std::vector<R> toVector(T *first, std::ptrdiff_t size, K f) Q_DECL_NOEXCEPT {
wrapped_array<T> array = wrap_array<T>(first, size);
std::vector<R> result;
for (auto it = array.begin(); it != array.end(); ++it)
result.emplace_back(R(f(*it)));
return result;
}
}

View File

@ -0,0 +1,272 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtCore module of the Qt Toolkit.
**
** $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 Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QMETAOBJECT_P_H
#define QMETAOBJECT_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists for the convenience
// of moc. This header file may change from version to version without notice,
// or even be removed.
//
// We mean it.
//
#include <QtCore/qglobal.h>
#include <QtCore/qobjectdefs.h>
#ifndef QT_NO_QOBJECT
#include <private/qobject_p.h> // For QObjectPrivate::Connection
#endif
#include <QtCore/qvarlengtharray.h>
QT_BEGIN_NAMESPACE
enum PropertyFlags {
Invalid = 0x00000000,
Readable = 0x00000001,
Writable = 0x00000002,
Resettable = 0x00000004,
EnumOrFlag = 0x00000008,
StdCppSet = 0x00000100,
// Override = 0x00000200,
Constant = 0x00000400,
Final = 0x00000800,
Designable = 0x00001000,
ResolveDesignable = 0x00002000,
Scriptable = 0x00004000,
ResolveScriptable = 0x00008000,
Stored = 0x00010000,
ResolveStored = 0x00020000,
Editable = 0x00040000,
ResolveEditable = 0x00080000,
User = 0x00100000,
ResolveUser = 0x00200000,
Notify = 0x00400000,
Revisioned = 0x00800000
};
enum MethodFlags {
AccessPrivate = 0x00,
AccessProtected = 0x01,
AccessPublic = 0x02,
AccessMask = 0x03, //mask
MethodMethod = 0x00,
MethodSignal = 0x04,
MethodSlot = 0x08,
MethodConstructor = 0x0c,
MethodTypeMask = 0x0c,
MethodCompatibility = 0x10,
MethodCloned = 0x20,
MethodScriptable = 0x40,
MethodRevisioned = 0x80
};
enum MetaObjectFlags {
DynamicMetaObject = 0x01,
RequiresVariantMetaObject = 0x02
};
enum MetaDataFlags {
IsUnresolvedType = 0x80000000,
TypeNameIndexMask = 0x7FFFFFFF
};
extern int qMetaTypeTypeInternal(const char *);
class QArgumentType
{
public:
QArgumentType(int type)
: _type(type)
{}
QArgumentType(const QByteArray &name)
: _type(qMetaTypeTypeInternal(name.constData())), _name(name)
{}
QArgumentType()
: _type(0)
{}
int type() const
{
return _type;
}
QByteArray name() const
{
if (_type && _name.isEmpty())
const_cast<QArgumentType *>(this)->_name = QMetaType::typeName(_type);
return _name;
}
bool operator==(const QArgumentType &other) const
{
if (_type)
return _type == other._type;
else if (other._type)
return false;
else
return _name == other._name;
}
bool operator!=(const QArgumentType &other) const
{
if (_type)
return _type != other._type;
else if (other._type)
return true;
else
return _name != other._name;
}
private:
int _type;
QByteArray _name;
};
typedef QVarLengthArray<QArgumentType, 10> QArgumentTypeArray;
class QMetaMethodPrivate;
class QMutex;
struct QMetaObjectPrivate {
enum { OutputRevision = 7 }; // Used by moc, qmetaobjectbuilder and qdbus
int revision;
int className;
int classInfoCount, classInfoData;
int methodCount, methodData;
int propertyCount, propertyData;
int enumeratorCount, enumeratorData;
int constructorCount, constructorData; //since revision 2
int flags; //since revision 3
int signalCount; //since revision 4
// revision 5 introduces changes in normalized signatures, no new members
// revision 6 added qt_static_metacall as a member of each Q_OBJECT and inside QMetaObject itself
// revision 7 is Qt 5
static inline const QMetaObjectPrivate *get(const QMetaObject *metaobject)
{
return reinterpret_cast<const QMetaObjectPrivate *>(metaobject->d.data);
}
static int originalClone(const QMetaObject *obj, int local_method_index);
static QByteArray decodeMethodSignature(const char *signature,
QArgumentTypeArray &types);
static int indexOfSignalRelative(const QMetaObject **baseObject,
const QByteArray &name, int argc,
const QArgumentType *types);
static int indexOfSlotRelative(const QMetaObject **m,
const QByteArray &name, int argc,
const QArgumentType *types);
static int indexOfSignal(const QMetaObject *m, const QByteArray &name,
int argc, const QArgumentType *types);
static int indexOfSlot(const QMetaObject *m, const QByteArray &name,
int argc, const QArgumentType *types);
static int indexOfMethod(const QMetaObject *m, const QByteArray &name,
int argc, const QArgumentType *types);
static int indexOfConstructor(const QMetaObject *m, const QByteArray &name,
int argc, const QArgumentType *types);
Q_CORE_EXPORT static QMetaMethod signal(const QMetaObject *m, int signal_index);
Q_CORE_EXPORT static int signalOffset(const QMetaObject *m);
Q_CORE_EXPORT static int absoluteSignalCount(const QMetaObject *m);
Q_CORE_EXPORT static int signalIndex(const QMetaMethod &m);
static bool checkConnectArgs(int signalArgc, const QArgumentType *signalTypes,
int methodArgc, const QArgumentType *methodTypes);
static bool checkConnectArgs(const QMetaMethodPrivate *signal,
const QMetaMethodPrivate *method);
static QList<QByteArray> parameterTypeNamesFromSignature(const char *signature);
#ifndef QT_NO_QOBJECT
//defined in qobject.cpp
enum DisconnectType { DisconnectAll, DisconnectOne };
static void memberIndexes(const QObject *obj, const QMetaMethod &member,
int *signalIndex, int *methodIndex);
static QObjectPrivate::Connection *connect(const QObject *sender, int signal_index,
const QMetaObject *smeta,
const QObject *receiver, int method_index_relative,
const QMetaObject *rmeta = 0,
int type = 0, int *types = 0);
static bool disconnect(const QObject *sender, int signal_index,
const QMetaObject *smeta,
const QObject *receiver, int method_index, void **slot,
DisconnectType = DisconnectAll);
static inline bool disconnectHelper(QObjectPrivate::Connection *c,
const QObject *receiver, int method_index, void **slot,
QMutex *senderMutex, DisconnectType = DisconnectAll);
#endif
};
// For meta-object generators
enum { MetaObjectPrivateFieldCount = sizeof(QMetaObjectPrivate) / sizeof(int) };
#ifndef UTILS_H
// mirrored in moc's utils.h
static inline bool is_ident_char(char s)
{
return ((s >= 'a' && s <= 'z')
|| (s >= 'A' && s <= 'Z')
|| (s >= '0' && s <= '9')
|| s == '_'
);
}
static inline bool is_space(char s)
{
return (s == ' ' || s == '\t');
}
#endif
/*
This function is shared with moc.cpp. The implementation lives in qmetaobject_moc_p.h, which
should be included where needed. The declaration here is not used to avoid warnings from
the compiler about unused functions.
static QByteArray normalizeTypeInternal(const char *t, const char *e, bool fixScope = false, bool adjustConst = true);
*/
QT_END_NAMESPACE
#endif

View File

@ -0,0 +1,351 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtCore module of the Qt Toolkit.
**
** $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 Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QMETAOBJECTBUILDER_P_H
#define QMETAOBJECTBUILDER_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists for the convenience
// of moc. This header file may change from version to version without notice,
// or even be removed.
//
// We mean it.
//
#include <QtCore/qobject.h>
#include <QtCore/qmetaobject.h>
#include <QtCore/qdatastream.h>
#include <QtCore/qhash.h>
#include <QtCore/qmap.h>
QT_BEGIN_NAMESPACE
class QMetaObjectBuilderPrivate;
class QMetaMethodBuilder;
class QMetaMethodBuilderPrivate;
class QMetaPropertyBuilder;
class QMetaPropertyBuilderPrivate;
class QMetaEnumBuilder;
class QMetaEnumBuilderPrivate;
class Q_CORE_EXPORT QMetaObjectBuilder
{
public:
enum AddMember {
ClassName = 0x00000001,
SuperClass = 0x00000002,
Methods = 0x00000004,
Signals = 0x00000008,
Slots = 0x00000010,
Constructors = 0x00000020,
Properties = 0x00000040,
Enumerators = 0x00000080,
ClassInfos = 0x00000100,
RelatedMetaObjects = 0x00000200,
StaticMetacall = 0x00000400,
PublicMethods = 0x00000800,
ProtectedMethods = 0x00001000,
PrivateMethods = 0x00002000,
AllMembers = 0x7FFFFFFF,
AllPrimaryMembers = 0x7FFFFBFC
};
Q_DECLARE_FLAGS(AddMembers, AddMember)
enum MetaObjectFlag {
DynamicMetaObject = 0x01
};
Q_DECLARE_FLAGS(MetaObjectFlags, MetaObjectFlag)
QMetaObjectBuilder();
explicit QMetaObjectBuilder(const QMetaObject *prototype, QMetaObjectBuilder::AddMembers members = AllMembers);
virtual ~QMetaObjectBuilder();
QByteArray className() const;
void setClassName(const QByteArray &name);
const QMetaObject *superClass() const;
void setSuperClass(const QMetaObject *meta);
MetaObjectFlags flags() const;
void setFlags(MetaObjectFlags);
int methodCount() const;
int constructorCount() const;
int propertyCount() const;
int enumeratorCount() const;
int classInfoCount() const;
int relatedMetaObjectCount() const;
QMetaMethodBuilder addMethod(const QByteArray &signature);
QMetaMethodBuilder addMethod(const QByteArray &signature, const QByteArray &returnType);
QMetaMethodBuilder addMethod(const QMetaMethod &prototype);
QMetaMethodBuilder addSlot(const QByteArray &signature);
QMetaMethodBuilder addSignal(const QByteArray &signature);
QMetaMethodBuilder addConstructor(const QByteArray &signature);
QMetaMethodBuilder addConstructor(const QMetaMethod &prototype);
QMetaPropertyBuilder addProperty(const QByteArray &name, const QByteArray &type, int notifierId = -1);
QMetaPropertyBuilder addProperty(const QMetaProperty &prototype);
QMetaEnumBuilder addEnumerator(const QByteArray &name);
QMetaEnumBuilder addEnumerator(const QMetaEnum &prototype);
int addClassInfo(const QByteArray &name, const QByteArray &value);
int addRelatedMetaObject(const QMetaObject *meta);
void addMetaObject(const QMetaObject *prototype, QMetaObjectBuilder::AddMembers members = AllMembers);
QMetaMethodBuilder method(int index) const;
QMetaMethodBuilder constructor(int index) const;
QMetaPropertyBuilder property(int index) const;
QMetaEnumBuilder enumerator(int index) const;
const QMetaObject *relatedMetaObject(int index) const;
QByteArray classInfoName(int index) const;
QByteArray classInfoValue(int index) const;
void removeMethod(int index);
void removeConstructor(int index);
void removeProperty(int index);
void removeEnumerator(int index);
void removeClassInfo(int index);
void removeRelatedMetaObject(int index);
int indexOfMethod(const QByteArray &signature);
int indexOfSignal(const QByteArray &signature);
int indexOfSlot(const QByteArray &signature);
int indexOfConstructor(const QByteArray &signature);
int indexOfProperty(const QByteArray &name);
int indexOfEnumerator(const QByteArray &name);
int indexOfClassInfo(const QByteArray &name);
typedef void (*StaticMetacallFunction)(QObject *, QMetaObject::Call, int, void **);
QMetaObjectBuilder::StaticMetacallFunction staticMetacallFunction() const;
void setStaticMetacallFunction(QMetaObjectBuilder::StaticMetacallFunction value);
QMetaObject *toMetaObject() const;
QByteArray toRelocatableData(bool * = 0) const;
static void fromRelocatableData(QMetaObject *, const QMetaObject *, const QByteArray &);
#ifndef QT_NO_DATASTREAM
void serialize(QDataStream &stream) const;
void deserialize
(QDataStream &stream,
const QMap<QByteArray, const QMetaObject *> &references);
#endif
private:
Q_DISABLE_COPY(QMetaObjectBuilder)
QMetaObjectBuilderPrivate *d;
friend class QMetaMethodBuilder;
friend class QMetaPropertyBuilder;
friend class QMetaEnumBuilder;
};
class Q_CORE_EXPORT QMetaMethodBuilder
{
public:
QMetaMethodBuilder() : _mobj(0), _index(0) {}
int index() const;
QMetaMethod::MethodType methodType() const;
QByteArray signature() const;
QByteArray returnType() const;
void setReturnType(const QByteArray &value);
QList<QByteArray> parameterTypes() const;
QList<QByteArray> parameterNames() const;
void setParameterNames(const QList<QByteArray> &value);
QByteArray tag() const;
void setTag(const QByteArray &value);
QMetaMethod::Access access() const;
void setAccess(QMetaMethod::Access value);
int attributes() const;
void setAttributes(int value);
int revision() const;
void setRevision(int revision);
private:
const QMetaObjectBuilder *_mobj;
int _index;
friend class QMetaObjectBuilder;
friend class QMetaPropertyBuilder;
QMetaMethodBuilder(const QMetaObjectBuilder *mobj, int index)
: _mobj(mobj), _index(index) {}
QMetaMethodBuilderPrivate *d_func() const;
};
class Q_CORE_EXPORT QMetaPropertyBuilder
{
public:
QMetaPropertyBuilder() : _mobj(0), _index(0) {}
int index() const
{
return _index;
}
QByteArray name() const;
QByteArray type() const;
bool hasNotifySignal() const;
QMetaMethodBuilder notifySignal() const;
void setNotifySignal(const QMetaMethodBuilder &value);
void removeNotifySignal();
bool isReadable() const;
bool isWritable() const;
bool isResettable() const;
bool isDesignable() const;
bool isScriptable() const;
bool isStored() const;
bool isEditable() const;
bool isUser() const;
bool hasStdCppSet() const;
bool isEnumOrFlag() const;
bool isConstant() const;
bool isFinal() const;
void setReadable(bool value);
void setWritable(bool value);
void setResettable(bool value);
void setDesignable(bool value);
void setScriptable(bool value);
void setStored(bool value);
void setEditable(bool value);
void setUser(bool value);
void setStdCppSet(bool value);
void setEnumOrFlag(bool value);
void setConstant(bool value);
void setFinal(bool value);
int revision() const;
void setRevision(int revision);
private:
const QMetaObjectBuilder *_mobj;
int _index;
friend class QMetaObjectBuilder;
QMetaPropertyBuilder(const QMetaObjectBuilder *mobj, int index)
: _mobj(mobj), _index(index) {}
QMetaPropertyBuilderPrivate *d_func() const;
};
class Q_CORE_EXPORT QMetaEnumBuilder
{
public:
QMetaEnumBuilder() : _mobj(0), _index(0) {}
int index() const
{
return _index;
}
QByteArray name() const;
bool isFlag() const;
void setIsFlag(bool value);
int keyCount() const;
QByteArray key(int index) const;
int value(int index) const;
int addKey(const QByteArray &name, int value);
void removeKey(int index);
private:
const QMetaObjectBuilder *_mobj;
int _index;
friend class QMetaObjectBuilder;
QMetaEnumBuilder(const QMetaObjectBuilder *mobj, int index)
: _mobj(mobj), _index(index) {}
QMetaEnumBuilderPrivate *d_func() const;
};
class Q_CORE_EXPORT QMetaStringTable
{
public:
explicit QMetaStringTable(const QByteArray &className);
int enter(const QByteArray &value);
static int preferredAlignment();
int blobSize() const;
void writeBlob(char *out) const;
private:
typedef QHash<QByteArray, int> Entries; // string --> index mapping
Entries m_entries;
int m_index;
QByteArray m_className;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QMetaObjectBuilder::AddMembers)
Q_DECLARE_OPERATORS_FOR_FLAGS(QMetaObjectBuilder::MetaObjectFlags)
QT_END_NAMESPACE
#endif

View File

@ -0,0 +1,471 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Copyright (C) 2013 Olivier Goffart <ogoffart@woboq.com>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtCore module of the Qt Toolkit.
**
** $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 Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QOBJECT_P_H
#define QOBJECT_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists for the convenience
// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
// file may change from version to version without notice, or even be removed.
//
// We mean it.
//
#include "QtCore/qobject.h"
#include "QtCore/qpointer.h"
#include "QtCore/qsharedpointer.h"
#include "QtCore/qcoreevent.h"
#include "QtCore/qlist.h"
#include "QtCore/qvector.h"
#include "QtCore/qvariant.h"
#include "QtCore/qreadwritelock.h"
QT_BEGIN_NAMESPACE
class QVariant;
class QThreadData;
class QObjectConnectionListVector;
namespace QtSharedPointer {
struct ExternalRefCountData;
}
/* for Qt Test */
struct QSignalSpyCallbackSet {
typedef void (*BeginCallback)(QObject *caller, int signal_or_method_index, void **argv);
typedef void (*EndCallback)(QObject *caller, int signal_or_method_index);
BeginCallback signal_begin_callback,
slot_begin_callback;
EndCallback signal_end_callback,
slot_end_callback;
};
void Q_CORE_EXPORT qt_register_signal_spy_callbacks(const QSignalSpyCallbackSet &callback_set);
extern QSignalSpyCallbackSet Q_CORE_EXPORT qt_signal_spy_callback_set;
enum { QObjectPrivateVersion = QT_VERSION };
class Q_CORE_EXPORT QAbstractDeclarativeData
{
public:
static void (*destroyed)(QAbstractDeclarativeData *, QObject *);
static void (*destroyed_qml1)(QAbstractDeclarativeData *, QObject *);
static void (*parentChanged)(QAbstractDeclarativeData *, QObject *, QObject *);
static void (*signalEmitted)(QAbstractDeclarativeData *, QObject *, int, void **);
static int (*receivers)(QAbstractDeclarativeData *, const QObject *, int);
static bool (*isSignalConnected)(QAbstractDeclarativeData *, const QObject *, int);
};
// This is an implementation of QAbstractDeclarativeData that is identical with
// the implementation in QtDeclarative and QtQml for the first bit
struct QAbstractDeclarativeDataImpl : public QAbstractDeclarativeData {
quint32 ownedByQml1: 1;
quint32 unused: 31;
};
class Q_CORE_EXPORT QObjectPrivate : public QObjectData
{
Q_DECLARE_PUBLIC(QObject)
public:
struct ExtraData {
ExtraData() {}
#ifndef QT_NO_USERDATA
QVector<QObjectUserData *> userData;
#endif
QList<QByteArray> propertyNames;
QList<QVariant> propertyValues;
QVector<int> runningTimers;
QList<QPointer<QObject> > eventFilters;
QString objectName;
};
typedef void (*StaticMetaCallFunction)(QObject *, QMetaObject::Call, int, void **);
struct Connection {
QObject *sender;
QObject *receiver;
union {
StaticMetaCallFunction callFunction;
QtPrivate::QSlotObjectBase *slotObj;
};
// The next pointer for the singly-linked ConnectionList
Connection *nextConnectionList;
//senders linked list
Connection *next;
Connection **prev;
QAtomicPointer<const int> argumentTypes;
QAtomicInt ref_;
ushort method_offset;
ushort method_relative;
uint signal_index : 27; // In signal range (see QObjectPrivate::signalIndex())
ushort connectionType : 3; // 0 == auto, 1 == direct, 2 == queued, 4 == blocking
ushort isSlotObject : 1;
ushort ownArgumentTypes : 1;
Connection() : nextConnectionList(0), ref_(2), ownArgumentTypes(true)
{
//ref_ is 2 for the use in the internal lists, and for the use in QMetaObject::Connection
}
~Connection();
int method() const
{
return method_offset + method_relative;
}
void ref()
{
ref_.ref();
}
void deref()
{
if (!ref_.deref()) {
Q_ASSERT(!receiver);
delete this;
}
}
};
// ConnectionList is a singly-linked list
struct ConnectionList {
ConnectionList() : first(0), last(0) {}
Connection *first;
Connection *last;
};
struct Sender {
QObject *sender;
int signal;
int ref;
};
QObjectPrivate(int version = QObjectPrivateVersion);
virtual ~QObjectPrivate();
void deleteChildren();
void setParent_helper(QObject *);
void moveToThread_helper();
void setThreadData_helper(QThreadData *currentData, QThreadData *targetData);
void _q_reregisterTimers(void *pointer);
bool isSender(const QObject *receiver, const char *signal) const;
QObjectList receiverList(const char *signal) const;
QObjectList senderList() const;
void addConnection(int signal, Connection *c);
void cleanConnectionLists();
static inline Sender *setCurrentSender(QObject *receiver,
Sender *sender);
static inline void resetCurrentSender(QObject *receiver,
Sender *currentSender,
Sender *previousSender);
static QObjectPrivate *get(QObject *o)
{
return o->d_func();
}
int signalIndex(const char *signalName, const QMetaObject **meta = 0) const;
inline bool isSignalConnected(uint signalIdx) const;
// To allow abitrary objects to call connectNotify()/disconnectNotify() without making
// the API public in QObject. This is used by QQmlNotifierEndpoint.
inline void connectNotify(const QMetaMethod &signal);
inline void disconnectNotify(const QMetaMethod &signal);
template <typename Func1, typename Func2>
static inline QMetaObject::Connection connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal,
const typename QtPrivate::FunctionPointer<Func2>::Object *receiverPrivate, Func2 slot,
Qt::ConnectionType type = Qt::AutoConnection);
template <typename Func1, typename Func2>
static inline bool disconnect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal,
const typename QtPrivate::FunctionPointer<Func2>::Object *receiverPrivate, Func2 slot);
static QMetaObject::Connection connectImpl(const QObject *sender, int signal_index,
const QObject *receiver, void **slot,
QtPrivate::QSlotObjectBase *slotObj, Qt::ConnectionType type,
const int *types, const QMetaObject *senderMetaObject);
static QMetaObject::Connection connect(const QObject *sender, int signal_index, QtPrivate::QSlotObjectBase *slotObj, Qt::ConnectionType type);
static bool disconnect(const QObject *sender, int signal_index, void **slot);
public:
ExtraData *extraData; // extra data set by the user
QThreadData *threadData; // id of the thread that owns the object
QObjectConnectionListVector *connectionLists;
Connection *senders; // linked list of connections connected to this object
Sender *currentSender; // object currently activating the object
mutable quint32 connectedSignals[2];
union {
QObject *currentChildBeingDeleted;
QAbstractDeclarativeData *declarativeData; //extra data used by the declarative module
};
// these objects are all used to indicate that a QObject was deleted
// plus QPointer, which keeps a separate list
QAtomicPointer<QtSharedPointer::ExternalRefCountData> sharedRefcount;
};
/*! \internal
Returns \c true if the signal with index \a signal_index from object \a sender is connected.
Signals with indices above a certain range are always considered connected (see connectedSignals
in QObjectPrivate).
\a signal_index must be the index returned by QObjectPrivate::signalIndex;
*/
inline bool QObjectPrivate::isSignalConnected(uint signal_index) const
{
return signal_index >= sizeof(connectedSignals) * 8
|| (connectedSignals[signal_index >> 5] & (1 << (signal_index & 0x1f))
|| (declarativeData && QAbstractDeclarativeData::isSignalConnected
&& QAbstractDeclarativeData::isSignalConnected(declarativeData, q_func(), signal_index)));
}
inline QObjectPrivate::Sender *QObjectPrivate::setCurrentSender(QObject *receiver,
Sender *sender)
{
Sender *previousSender = receiver->d_func()->currentSender;
receiver->d_func()->currentSender = sender;
return previousSender;
}
inline void QObjectPrivate::resetCurrentSender(QObject *receiver,
Sender *currentSender,
Sender *previousSender)
{
// ref is set to zero when this object is deleted during the metacall
if (currentSender->ref == 1)
receiver->d_func()->currentSender = previousSender;
// if we've recursed, we need to tell the caller about the objects deletion
if (previousSender)
previousSender->ref = currentSender->ref;
}
inline void QObjectPrivate::connectNotify(const QMetaMethod &signal)
{
q_ptr->connectNotify(signal);
}
inline void QObjectPrivate::disconnectNotify(const QMetaMethod &signal)
{
q_ptr->disconnectNotify(signal);
}
namespace QtPrivate {
template<typename Func, typename Args, typename R> class QPrivateSlotObject : public QSlotObjectBase
{
typedef QtPrivate::FunctionPointer<Func> FuncType;
Func function;
static void impl(int which, QSlotObjectBase *this_, QObject *r, void **a, bool *ret)
{
switch (which) {
case Destroy:
delete static_cast<QPrivateSlotObject *>(this_);
break;
case Call:
FuncType::template call<Args, R>(static_cast<QPrivateSlotObject *>(this_)->function,
static_cast<typename FuncType::Object *>(QObjectPrivate::get(r)), a);
break;
case Compare:
*ret = *reinterpret_cast<Func *>(a) == static_cast<QPrivateSlotObject *>(this_)->function;
break;
case NumOperations:
;
}
}
public:
explicit QPrivateSlotObject(Func f) : QSlotObjectBase(&impl), function(f) {}
};
} //namespace QtPrivate
template <typename Func1, typename Func2>
inline QMetaObject::Connection QObjectPrivate::connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal,
const typename QtPrivate::FunctionPointer<Func2>::Object *receiverPrivate, Func2 slot,
Qt::ConnectionType type)
{
typedef QtPrivate::FunctionPointer<Func1> SignalType;
typedef QtPrivate::FunctionPointer<Func2> SlotType;
Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
"No Q_OBJECT in the class with the signal");
//compilation error if the arguments does not match.
Q_STATIC_ASSERT_X(int(SignalType::ArgumentCount) >= int(SlotType::ArgumentCount),
"The slot requires more arguments than the signal provides.");
Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments<typename SignalType::Arguments, typename SlotType::Arguments>::value),
"Signal and slot arguments are not compatible.");
Q_STATIC_ASSERT_X((QtPrivate::AreArgumentsCompatible<typename SlotType::ReturnType, typename SignalType::ReturnType>::value),
"Return type of the slot is not compatible with the return type of the signal.");
const int *types = 0;
if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection)
types = QtPrivate::ConnectionTypes<typename SignalType::Arguments>::types();
return QObject::connectImpl(sender, reinterpret_cast<void **>(&signal),
receiverPrivate->q_ptr, reinterpret_cast<void **>(&slot),
new QtPrivate::QPrivateSlotObject<Func2, typename QtPrivate::List_Left<typename SignalType::Arguments, SlotType::ArgumentCount>::Value,
typename SignalType::ReturnType>(slot),
type, types, &SignalType::Object::staticMetaObject);
}
template <typename Func1, typename Func2>
bool QObjectPrivate::disconnect(const typename QtPrivate::FunctionPointer< Func1 >::Object *sender, Func1 signal,
const typename QtPrivate::FunctionPointer< Func2 >::Object *receiverPrivate, Func2 slot)
{
typedef QtPrivate::FunctionPointer<Func1> SignalType;
typedef QtPrivate::FunctionPointer<Func2> SlotType;
Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
"No Q_OBJECT in the class with the signal");
//compilation error if the arguments does not match.
Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments<typename SignalType::Arguments, typename SlotType::Arguments>::value),
"Signal and slot arguments are not compatible.");
return QObject::disconnectImpl(sender, reinterpret_cast<void **>(&signal),
receiverPrivate->q_ptr, reinterpret_cast<void **>(&slot),
&SignalType::Object::staticMetaObject);
}
Q_DECLARE_TYPEINFO(QObjectPrivate::Connection, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(QObjectPrivate::Sender, Q_MOVABLE_TYPE);
class QSemaphore;
class Q_CORE_EXPORT QMetaCallEvent : public QEvent
{
public:
QMetaCallEvent(ushort method_offset, ushort method_relative, QObjectPrivate::StaticMetaCallFunction callFunction, const QObject *sender, int signalId,
int nargs = 0, int *types = 0, void **args = 0, QSemaphore *semaphore = 0);
/*! \internal
\a signalId is in the signal index range (see QObjectPrivate::signalIndex()).
*/
QMetaCallEvent(QtPrivate::QSlotObjectBase *slotObj, const QObject *sender, int signalId,
int nargs = 0, int *types = 0, void **args = 0, QSemaphore *semaphore = 0);
~QMetaCallEvent();
inline int id() const
{
return method_offset_ + method_relative_;
}
inline const QObject *sender() const
{
return sender_;
}
inline int signalId() const
{
return signalId_;
}
inline void **args() const
{
return args_;
}
virtual void placeMetaCall(QObject *object);
private:
QtPrivate::QSlotObjectBase *slotObj_;
const QObject *sender_;
int signalId_;
int nargs_;
int *types_;
void **args_;
QSemaphore *semaphore_;
QObjectPrivate::StaticMetaCallFunction callFunction_;
ushort method_offset_;
ushort method_relative_;
};
class QBoolBlocker
{
Q_DISABLE_COPY(QBoolBlocker)
public:
explicit inline QBoolBlocker(bool &b, bool value = true): block(b), reset(b)
{
block = value;
}
inline ~QBoolBlocker()
{
block = reset;
}
private:
bool &block;
bool reset;
};
void Q_CORE_EXPORT qDeleteInEventHandler(QObject *o);
struct QAbstractDynamicMetaObject;
struct Q_CORE_EXPORT QDynamicMetaObjectData {
virtual ~QDynamicMetaObjectData() {}
virtual void objectDestroyed(QObject *)
{
delete this;
}
virtual QAbstractDynamicMetaObject *toDynamicMetaObject(QObject *) = 0;
virtual int metaCall(QObject *, QMetaObject::Call, int _id, void **) = 0;
};
struct Q_CORE_EXPORT QAbstractDynamicMetaObject : public QDynamicMetaObjectData, public QMetaObject {
virtual QAbstractDynamicMetaObject *toDynamicMetaObject(QObject *)
{
return this;
}
virtual int createProperty(const char *, const char *)
{
return -1;
}
virtual int metaCall(QObject *, QMetaObject::Call c, int _id, void **a)
{
return metaCall(c, _id, a);
}
virtual int metaCall(QMetaObject::Call, int _id, void **)
{
return _id; // Compat overload
}
};
QT_END_NAMESPACE
#endif // QOBJECT_P_H

23
vendor/DOtherSide/lib/meson.build vendored Normal file
View File

@ -0,0 +1,23 @@
lib_version = '0.6.3'
lib_dependencies = dependency('qt5', modules : ['Core', 'Gui', 'Widgets', 'Quick', 'Qml'])
lib_sources = [
'src/DOtherSide.cpp',
'src/DOtherSideTypesCpp.cpp',
'src/DosQAbstractItemModel.cpp',
'src/DosQDeclarative.cpp',
'src/DosQMetaObject.cpp',
'src/DosQObject.cpp',
'src/DosQObjectImpl.cpp',
'src/DosQQuickImageProvider.cpp',
]
lib_include_directories = ['include', 'include/Qt']
lib_pch = ['../pch/lib_pch.h', '../pch/lib_pch.cpp']
lib = shared_library('DOtherSide',
sources : lib_sources,
include_directories : include_directories(lib_include_directories),
dependencies : lib_dependencies,
version: lib_version,
soversion:0,
cpp_pch: lib_pch
)

1047
vendor/DOtherSide/lib/src/DOtherSide.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,39 @@
/*
Copyright (C) 2019 Filippo Cucchetto.
Contact: https://github.com/filcuc/dotherside
This file is part of the DOtherSide library.
The DOtherSide library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the license, or (at your opinion) any later version.
The DOtherSide library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the DOtherSide library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "DOtherSide/DOtherSideTypesCpp.h"
namespace DOS {
SignalDefinitions toVector(const ::SignalDefinitions &cType)
{
return toVector<SignalDefinition>(cType.definitions, cType.count);
}
SlotDefinitions toVector(const ::SlotDefinitions &cType)
{
return toVector<SlotDefinition>(cType.definitions, cType.count);
}
PropertyDefinitions toVector(const ::PropertyDefinitions &cType)
{
return toVector<PropertyDefinition>(cType.definitions, cType.count);
}
} // namespace DOS

View File

@ -0,0 +1,328 @@
/*
Copyright (C) 2019 Filippo Cucchetto.
Contact: https://github.com/filcuc/dotherside
This file is part of the DOtherSide library.
The DOtherSide library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the license, or (at your opinion) any later version.
The DOtherSide library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the DOtherSide library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "DOtherSide/DosQAbstractItemModel.h"
#include "DOtherSide/DosQObjectImpl.h"
namespace {
template<class T>
DOS::DosQObjectImpl::ParentMetaCall createParentMetaCall(DOS::DosQAbstractGenericModel<T> *parent)
{
return [parent](QMetaObject::Call callType, int index, void **args)->int {
return parent->T::qt_metacall(callType, index, args);
};
}
}
namespace DOS {
template<class T>
DosQAbstractGenericModel<T>::DosQAbstractGenericModel(void *modelObject,
DosIQMetaObjectPtr metaObject,
DObjectCallback dObjectCallback,
DosQAbstractItemModelCallbacks callbacks)
: m_impl(new DosQObjectImpl(::createParentMetaCall(this), std::move(metaObject), modelObject, dObjectCallback))
, m_modelObject(modelObject)
, m_callbacks(callbacks)
{}
template<class T>
bool DosQAbstractGenericModel<T>::emitSignal(QObject *emitter, const QString &name, const std::vector<QVariant> &argumentsValues)
{
Q_ASSERT(m_impl);
return m_impl->emitSignal(emitter, name, argumentsValues);
}
template<class T>
const QMetaObject *DosQAbstractGenericModel<T>::metaObject() const
{
Q_ASSERT(m_impl);
return m_impl->metaObject();
}
template<class T>
int DosQAbstractGenericModel<T>::qt_metacall(QMetaObject::Call call, int index, void **args)
{
Q_ASSERT(m_impl);
return m_impl->qt_metacall(call, index, args);
}
template<class T>
int DosQAbstractGenericModel<T>::rowCount(const QModelIndex &parent) const
{
int result;
m_callbacks.rowCount(m_modelObject, &parent, &result);
return result;
}
template<class T>
int DosQAbstractGenericModel<T>::columnCount(const QModelIndex &parent) const
{
int result;
m_callbacks.columnCount(m_modelObject, &parent, &result);
return result;
}
template<class T>
QVariant DosQAbstractGenericModel<T>::data(const QModelIndex &index, int role) const
{
QVariant result;
m_callbacks.data(m_modelObject, &index, role, &result);
return result;
}
template<class T>
bool DosQAbstractGenericModel<T>::setData(const QModelIndex &index, const QVariant &value, int role)
{
bool result = false;
m_callbacks.setData(m_modelObject, &index, &value, role, &result);
return result;
}
template<class T>
Qt::ItemFlags DosQAbstractGenericModel<T>::flags(const QModelIndex &index) const
{
int result;
m_callbacks.flags(m_modelObject, &index, &result);
return Qt::ItemFlags(result);
}
template<class T>
QVariant DosQAbstractGenericModel<T>::headerData(int section, Qt::Orientation orientation, int role) const
{
QVariant result;
m_callbacks.headerData(m_modelObject, section, orientation, role, &result);
return result;
}
template<class T>
QModelIndex DosQAbstractGenericModel<T>::index(int row, int column, const QModelIndex &parent) const
{
QModelIndex result;
m_callbacks.index(m_modelObject, row, column, &parent, &result);
return result;
}
template<class T>
QModelIndex DosQAbstractGenericModel<T>::parent(const QModelIndex &child) const
{
QModelIndex result;
m_callbacks.parent(m_modelObject, &child, &result);
return result;
}
template<class T>
void *DosQAbstractGenericModel<T>::modelObject()
{
return m_modelObject;
}
template<class T>
QHash<int, QByteArray> DosQAbstractGenericModel<T>::roleNames() const
{
QHash<int, QByteArray> result;
m_callbacks.roleNames(m_modelObject, &result);
return result;
}
template<class T>
void DosQAbstractGenericModel<T>::publicBeginInsertColumns(const QModelIndex &index, int first, int last)
{
T::beginInsertColumns(index, first, last);
}
template<class T>
void DosQAbstractGenericModel<T>::publicEndInsertColumns()
{
T::endInsertColumns();
}
template<class T>
void DosQAbstractGenericModel<T>::publicBeginRemoveColumns(const QModelIndex &index, int first, int last)
{
T::beginRemoveColumns(index, first, last);
}
template<class T>
void DosQAbstractGenericModel<T>::publicEndRemoveColumns()
{
T::endRemoveColumns();
}
template<class T>
void DosQAbstractGenericModel<T>::publicBeginInsertRows(const QModelIndex &index, int first, int last)
{
T::beginInsertRows(index, first, last);
}
template<class T>
void DosQAbstractGenericModel<T>::publicEndInsertRows()
{
T::endInsertRows();
}
template<class T>
void DosQAbstractGenericModel<T>::publicBeginRemoveRows(const QModelIndex &index, int first, int last)
{
T::beginRemoveRows(index, first, last);
}
template<class T>
void DosQAbstractGenericModel<T>::publicEndRemoveRows()
{
T::endRemoveRows();
}
template<class T>
void DosQAbstractGenericModel<T>::publicBeginResetModel()
{
T::beginResetModel();
}
template<class T>
void DosQAbstractGenericModel<T>::publicEndResetModel()
{
T::endResetModel();
}
template<class T>
void DosQAbstractGenericModel<T>::publicDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
{
emit T::dataChanged(topLeft, bottomRight, roles);
}
template<class T>
QModelIndex DosQAbstractGenericModel<T>::publicCreateIndex(int row, int column, void *data) const
{
return T::createIndex(row, column, data);
}
template<class T>
Qt::ItemFlags DosQAbstractGenericModel<T>::defaultFlags(const QModelIndex &index) const
{
return T::flags(index);
}
template<class T>
QVariant DosQAbstractGenericModel<T>::defaultHeaderData(int section, Qt::Orientation orientation, int role) const
{
return T::headerData(section, orientation, role);
}
template<class T>
QHash<int, QByteArray> DosQAbstractGenericModel<T>::defaultRoleNames() const
{
return T::roleNames();
}
template<class T>
bool DosQAbstractGenericModel<T>::defaultSetData(const QModelIndex &index, const QVariant &value, int role)
{
return T::setData(index, value, role);
}
template<class T>
bool DosQAbstractGenericModel<T>::hasChildren(const QModelIndex &parent) const
{
bool result = false;
m_callbacks.hasChildren(m_modelObject, &parent, &result);
return result;
}
template<class T>
bool DosQAbstractGenericModel<T>::hasIndex(int row, int column, const QModelIndex &parent) const
{
return T::hasIndex(row, column, parent);
}
template<class T>
bool DosQAbstractGenericModel<T>::canFetchMore(const QModelIndex &parent) const
{
bool result = false;
m_callbacks.canFetchMore(m_modelObject, &parent, &result);
return result;
}
template<class T>
bool DosQAbstractGenericModel<T>::defaultCanFetchMore(const QModelIndex &parent) const
{
return this->T::canFetchMore(parent);
}
template<class T>
void DosQAbstractGenericModel<T>::fetchMore(const QModelIndex &parent)
{
m_callbacks.fetchMore(m_modelObject, &parent);
}
template<class T>
void DosQAbstractGenericModel<T>::defaultFetchMore(const QModelIndex &parent)
{
this->T::fetchMore(parent);
}
QModelIndex DosQAbstractListModel::defaultIndex(int row, int column, const QModelIndex &parent) const
{
return QAbstractListModel::index(row, column, parent);
}
int DosQAbstractListModel::defaultColumnCount(const QModelIndex &parent) const
{
return parent.isValid() ? 0 : 1;
}
bool DosQAbstractListModel::defaultHasChildren(const QModelIndex &parent) const
{
return parent.isValid() ? false : (rowCount() > 0);
}
QModelIndex DosQAbstractListModel::defaultParent(const QModelIndex & /*child*/) const
{
return QModelIndex();
}
QModelIndex DosQAbstractTableModel::defaultIndex(int row, int column, const QModelIndex &parent) const
{
return hasIndex(row, column, parent) ? createIndex(row, column) : QModelIndex();
}
bool DosQAbstractTableModel::defaultHasChildren(const QModelIndex &parent) const
{
if (parent.model() == this || !parent.isValid())
return rowCount(parent) > 0 && columnCount(parent) > 0;
return false;
}
QModelIndex DosQAbstractTableModel::defaultParent(const QModelIndex & /*child*/) const
{
return QModelIndex();
}
bool DosQAbstractItemModel::defaultHasChildren(const QModelIndex &parent) const
{
return QAbstractItemModel::hasChildren(parent);
}
} // namespace DOS
// Force instantiation
template class DOS::DosQAbstractGenericModel<QAbstractItemModel>;
template class DOS::DosQAbstractGenericModel<QAbstractListModel>;
template class DOS::DosQAbstractGenericModel<QAbstractTableModel>;

View File

@ -0,0 +1,57 @@
/*
Copyright (C) 2019 Filippo Cucchetto.
Contact: https://github.com/filcuc/dotherside
This file is part of the DOtherSide library.
The DOtherSide library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the license, or (at your opinion) any later version.
The DOtherSide library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the DOtherSide library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "DOtherSide/DosQDeclarative.h"
#include "DOtherSide/DosQObjectWrapper.h"
#include "DOtherSide/DosQAbstractItemModelWrapper.h"
namespace DOS {
bool isQAbstractItemModel(const QMetaObject *metaObject)
{
const QMetaObject *current = metaObject;
while (current) {
if (&QAbstractItemModel::staticMetaObject == current)
return true;
current = current->superClass();
}
return false;
}
int dosQmlRegisterType(QmlRegisterType args)
{
static int i = 0;
static int j = 0;
if (isQAbstractItemModel(args.staticMetaObject->metaObject()))
return DQAIMW::DosQmlRegisterHelper<35>::Register(j++, std::move(args));
else
return DQOW::DosQmlRegisterHelper<35>::Register(i++, std::move(args));
}
int dosQmlRegisterSingletonType(QmlRegisterType args)
{
static int i = 0;
static int j = 0;
if (isQAbstractItemModel(args.staticMetaObject->metaObject()))
return DQAIMW::DosQmlRegisterSingletonHelper<35>::Register(j++, std::move(args));
else
return DQOW::DosQmlRegisterSingletonHelper<35>::Register(i++, std::move(args));
}
}

View File

@ -0,0 +1,230 @@
/*
Copyright (C) 2019 Filippo Cucchetto.
Contact: https://github.com/filcuc/dotherside
This file is part of the DOtherSide library.
The DOtherSide library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the license, or (at your opinion) any later version.
The DOtherSide library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the DOtherSide library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "DOtherSide/DosQMetaObject.h"
#include "DOtherSide/DosQObject.h"
#include "private/qmetaobjectbuilder_p.h"
#include "private/qmetaobject_p.h"
#include "private/qobject_p.h"
#include <QtCore/QAbstractItemModel>
namespace {
QList<QByteArray> createParameterNames(const DOS::SignalDefinition &signal)
{
QList<QByteArray> result;
const auto &parameters = signal.parameters;
result.reserve(parameters.size());
for (size_t i = 0; i < parameters.size(); ++i)
result << parameters[i].name.toUtf8();
return result;
}
template<class T>
QByteArray createSignature(const T &functionDefinition)
{
QString signature("%1(%2)");
QString arguments;
const auto &parameters = functionDefinition.parameters;
for (size_t i = 0; i < parameters.size(); ++i) {
if (i != 0)
arguments += ",";
arguments += QMetaType::typeName(parameters[i].metaType);
}
return signature.arg(functionDefinition.name, arguments).toUtf8();
}
template<class Key, class Value>
Value valueOrDefault(std::unordered_map<Key, Value> const &map, const Key &k, Value value)
{
auto it = map.find(k);
return it != std::end(map) ? it->second : std::move(value);
}
template<class T> const char *className();
template<> const char *className<QObject>()
{
return "DosQObject";
}
template<> const char *className<QAbstractItemModel>()
{
return "DosQAbstractItemModel";
}
template<> const char *className<QAbstractListModel>()
{
return "DosQAbstractListModel";
}
template<> const char *className<QAbstractTableModel>()
{
return "DosQAbstractTableModel";
}
template <class T>
QMetaObject *createDynamicMetaObject()
{
QMetaObjectBuilder builder;
builder.setClassName(className<T>());
builder.setSuperClass(&T::staticMetaObject);
return builder.toMetaObject();
}
}
namespace DOS {
BaseDosQMetaObject::BaseDosQMetaObject(QMetaObject *metaObject)
: m_metaObject(metaObject)
{}
const QMetaObject *BaseDosQMetaObject::metaObject() const
{
return m_metaObject;
}
QMetaMethod BaseDosQMetaObject::signal(const QString &signalName) const
{
return QMetaMethod();
}
QMetaMethod BaseDosQMetaObject::readSlot(const char *propertyName) const
{
return QMetaMethod();
}
QMetaMethod BaseDosQMetaObject::writeSlot(const char *propertyName) const
{
return QMetaMethod();
}
const DosIQMetaObject *BaseDosQMetaObject::superClassDosMetaObject() const
{
return nullptr;
}
DosQObjectMetaObject::DosQObjectMetaObject()
: BaseDosQMetaObject(::createDynamicMetaObject<QObject>())
{}
template<class T>
DosQAbstractGenericModelMetaObject<T>::DosQAbstractGenericModelMetaObject()
: BaseDosQMetaObject(::createDynamicMetaObject<T>())
{}
// Force template instantations
template class DosQAbstractGenericModelMetaObject<QAbstractItemModel>;
template class DosQAbstractGenericModelMetaObject<QAbstractListModel>;
template class DosQAbstractGenericModelMetaObject<QAbstractTableModel>;
DosQMetaObject::DosQMetaObject(DosIQMetaObjectPtr superClassMetaObject,
const QString &className,
const SignalDefinitions &signalDefinitions,
const SlotDefinitions &slotDefinitions,
const PropertyDefinitions &propertyDefinitions)
: BaseDosQMetaObject(nullptr)
, m_superClassDosMetaObject(std::move(superClassMetaObject))
, m_signalIndexByName(QHash<QString, int>())
, m_propertySlots(QHash<QString, QPair<int, int>>())
{
// We do the metaobject initialization here because
// we must wait for both maps to be initialized before filling them
m_metaObject.reset(createMetaObject(className, signalDefinitions, slotDefinitions, propertyDefinitions));
}
QMetaObject *DosQMetaObject::createMetaObject(const QString &className,
const SignalDefinitions &signalDefinitions,
const SlotDefinitions &slotDefinitions,
const PropertyDefinitions &propertyDefinitions)
{
QMetaObjectBuilder builder;
builder.setClassName(className.toUtf8());
builder.setSuperClass(m_superClassDosMetaObject->metaObject());
for (const SignalDefinition &signal : signalDefinitions) {
QMetaMethodBuilder signalBuilder = builder.addSignal(::createSignature(signal));
signalBuilder.setReturnType(QMetaType::typeName(QMetaType::Void));
signalBuilder.setAccess(QMetaMethod::Public);
signalBuilder.setParameterNames(createParameterNames(signal));
m_signalIndexByName[signal.name] = signalBuilder.index();
}
QHash<QString, int> methodIndexByName;
for (const SlotDefinition &slot : slotDefinitions) {
QMetaMethodBuilder methodBuilder = builder.addSlot(::createSignature(slot));
methodBuilder.setReturnType(QMetaType::typeName(slot.returnType));
methodBuilder.setAttributes(QMetaMethod::Scriptable);
methodIndexByName[slot.name] = methodBuilder.index();
}
for (const PropertyDefinition &property : propertyDefinitions) {
const int writer = methodIndexByName.value(property.writeSlot, -1);
const int notifier = m_signalIndexByName.value(property.notifySignal, -1);
const QByteArray name = property.name.toUtf8();
const QByteArray typeName = QMetaObject::normalizedType(QMetaType::typeName(property.type));
QMetaPropertyBuilder propertyBuilder = builder.addProperty(name, typeName, notifier);
if (writer == -1)
propertyBuilder.setWritable(false);
if (notifier == -1)
propertyBuilder.setConstant(true);
m_propertySlots[property.name] = qMakePair(methodIndexByName.value(property.readSlot, -1),
methodIndexByName.value(property.writeSlot, -1));
}
return builder.toMetaObject();
}
QMetaMethod DosQMetaObject::signal(const QString &signalName) const
{
const int index = m_signalIndexByName.value(signalName, -1);
if (index != -1)
return metaObject()->method(metaObject()->methodOffset() + index);
if (auto superMetaObject = superClassDosMetaObject())
return superMetaObject->signal(signalName);
return QMetaMethod();
}
QMetaMethod DosQMetaObject::readSlot(const char *propertyName) const
{
const auto index = m_propertySlots.value(QString::fromUtf8(propertyName), qMakePair(-1, -1)).first;
if (index != -1)
return metaObject()->method(metaObject()->methodOffset() + index);
if (auto superMetaObject = superClassDosMetaObject())
return superMetaObject->readSlot(propertyName);
return QMetaMethod();
}
QMetaMethod DosQMetaObject::writeSlot(const char *propertyName) const
{
const auto index = m_propertySlots.value(QString::fromUtf8(propertyName), qMakePair(-1, -1)).second;
if (index != -1)
return metaObject()->method(metaObject()->methodOffset() + index);
if (auto superMetaObject = superClassDosMetaObject())
return superMetaObject->writeSlot(propertyName);
return QMetaMethod();
}
const DosIQMetaObject *DosQMetaObject::superClassDosMetaObject() const
{
return m_superClassDosMetaObject.get();
}
} // namespace DOS

View File

@ -0,0 +1,57 @@
/*
Copyright (C) 2019 Filippo Cucchetto.
Contact: https://github.com/filcuc/dotherside
This file is part of the DOtherSide library.
The DOtherSide library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the license, or (at your opinion) any later version.
The DOtherSide library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the DOtherSide library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "DOtherSide/DosQObject.h"
#include "DOtherSide/DosQMetaObject.h"
#include "DOtherSide/DosQObjectImpl.h"
namespace {
DOS::DosQObjectImpl::ParentMetaCall createParentMetaCall(QObject *parent)
{
return [parent](QMetaObject::Call callType, int index, void **args) -> int {
return parent->QObject::qt_metacall(callType, index, args);
};
}
}
namespace DOS {
DosQObject::DosQObject(void *dObjectPointer, DosIQMetaObjectPtr metaObject, DObjectCallback dObjectCallback)
: m_impl(new DosQObjectImpl(::createParentMetaCall(this), std::move(metaObject), dObjectPointer, dObjectCallback))
{}
bool DosQObject::emitSignal(QObject *emitter, const QString &name, const std::vector<QVariant> &args)
{
Q_ASSERT(m_impl);
return m_impl->emitSignal(emitter, name, args);
}
const QMetaObject *DosQObject::metaObject() const
{
Q_ASSERT(m_impl);
return m_impl->metaObject();
}
int DosQObject::qt_metacall(QMetaObject::Call call, int index, void **args)
{
Q_ASSERT(m_impl);
return m_impl->qt_metacall(call, index, args);
}
} // namespace DOS

View File

@ -0,0 +1,167 @@
/*
Copyright (C) 2019 Filippo Cucchetto.
Contact: https://github.com/filcuc/dotherside
This file is part of the DOtherSide library.
The DOtherSide library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the license, or (at your opinion) any later version.
The DOtherSide library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the DOtherSide library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "DOtherSide/DosQObjectImpl.h"
#include "DOtherSide/DosQMetaObject.h"
#include <QtCore/QMetaObject>
#include <QtCore/QMetaMethod>
#include <QtCore/QDebug>
namespace DOS {
DosQObjectImpl::DosQObjectImpl(ParentMetaCall parentMetaCall,
std::shared_ptr<const DosIQMetaObject> metaObject,
void *dObjectPointer,
DObjectCallback dObjectCallback)
: m_parentMetaCall(std::move(parentMetaCall))
, m_metaObject(std::move(metaObject))
, m_dObjectPointer(dObjectPointer)
, m_dObjectCallback(dObjectCallback)
{
}
bool DosQObjectImpl::emitSignal(QObject *emitter, const QString &name, const std::vector<QVariant> &args)
{
const QMetaMethod method = m_metaObject->signal(name);
if (!method.isValid())
return false;
Q_ASSERT(name.toUtf8() == method.name());
std::vector<void *> arguments(args.size() + 1, nullptr); // +1 for the result at pos 0
for (size_t i = 0; i < args.size(); ++i)
arguments[i + 1] = const_cast<void *>(args[i].constData()); // Extract inner void*
QMetaObject::activate(emitter, method.methodIndex(), arguments.data());
return true;
}
const QMetaObject *DosQObjectImpl::metaObject() const
{
return m_metaObject->metaObject();
}
int DosQObjectImpl::qt_metacall(QMetaObject::Call callType, int index, void **args)
{
if (m_parentMetaCall(callType, index, args) < 0)
return -1;
switch (callType) {
case QMetaObject::InvokeMetaMethod:
executeSlot(index, args);
break;
case QMetaObject::ReadProperty:
readProperty(index, args);
break;
case QMetaObject::WriteProperty:
writeProperty(index, args);
break;
default:
return -1;
}
return -1;
}
bool DosQObjectImpl::executeSlot(int index, void **args)
{
const QMetaObject *const mo = this->metaObject();
const QMetaMethod method = mo->method(index);
if (!method.isValid()) {
qDebug() << "C++: executeSlot: invalid method";
return false;
}
return executeSlot(method, args);
}
bool DosQObjectImpl::executeSlot(const QMetaMethod &method, void **args, int argumentsOffset)
{
Q_ASSERT(method.isValid());
const bool hasReturnType = method.returnType() != QMetaType::Void;
std::vector<QVariant> arguments;
arguments.reserve(method.parameterCount());
for (int i = 0, j = argumentsOffset; i < method.parameterCount(); ++i, ++j) {
QVariant argument(method.parameterType(i), args[j]);
arguments.emplace_back(std::move(argument));
}
const QVariant result = executeSlot(method.name(), arguments); // Execute method
if (hasReturnType && result.isValid()) {
QMetaType::construct(method.returnType(), args[0], result.constData());
}
return true;
}
QVariant DosQObjectImpl::executeSlot(const QString &name, const std::vector<QVariant> &args)
{
QVariant result;
if (!m_dObjectCallback || !m_dObjectPointer)
return result;
// prepare slot name
QVariant slotName(name);
// prepare void* for the QVariants
std::vector<void *> argumentsAsVoidPointers;
argumentsAsVoidPointers.reserve(args.size() + 1);
argumentsAsVoidPointers.emplace_back(&result);
for (size_t i = 0; i < args.size(); ++i)
argumentsAsVoidPointers.emplace_back((void *)(&args[i]));
// send them to the binding handler
m_dObjectCallback(m_dObjectPointer, &slotName, argumentsAsVoidPointers.size(), &argumentsAsVoidPointers[0]);
return result;
}
bool DosQObjectImpl::readProperty(int index, void **args)
{
const QMetaObject *const mo = metaObject();
const QMetaProperty property = mo->property(index);
if (!property.isValid() || !property.isReadable())
return false;
const QMetaMethod method = m_metaObject->readSlot(property.name());
if (!method.isValid()) {
qDebug() << "C++: readProperty: invalid read method for property " << property.name();
return false;
}
return executeSlot(method, args);
}
bool DosQObjectImpl::writeProperty(int index, void **args)
{
const QMetaObject *const mo = metaObject();
const QMetaProperty property = mo->property(index);
if (!property.isValid() || !property.isWritable())
return false;
const QMetaMethod method = m_metaObject->writeSlot(property.name());
if (!method.isValid()) {
qDebug() << "C++: writeProperty: invalid write method for property " << property.name();
return false;
}
return executeSlot(method, args, 0);
}
}

View File

@ -0,0 +1,32 @@
/*
Copyright (C) 2019 Filippo Cucchetto.
Contact: https://github.com/filcuc/dotherside
This file is part of the DOtherSide library.
The DOtherSide library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the license, or (at your opinion) any later version.
The DOtherSide library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the DOtherSide library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "DOtherSide/DosQQuickImageProvider.h"
DosImageProvider::DosImageProvider(RequestPixmapCallback callback) : QQuickImageProvider(QQuickImageProvider::Pixmap),
m_pixmap_callback(callback)
{
}
QPixmap DosImageProvider::requestPixmap(const QString &id, QSize *size, const QSize &requestedSize)
{
QPixmap result;
m_pixmap_callback(id.toLatin1().data(), &size->rwidth(), &size->rheight(), size->width(), size->height(), &result);
return result;
}

4
vendor/DOtherSide/meson.build vendored Normal file
View File

@ -0,0 +1,4 @@
project('DOtherSide', 'cpp', default_options : ['cpp_std=c++14'])
subdir('lib')
subdir('test')

1
vendor/DOtherSide/pch/lib_pch.cpp vendored Normal file
View File

@ -0,0 +1 @@
#include "lib_pch.h"

5
vendor/DOtherSide/pch/lib_pch.h vendored Normal file
View File

@ -0,0 +1,5 @@
#include <QtCore>
#include <QtWidgets>
#include <QtGui>
#include <QtQml>
#include <QtQuick>

1
vendor/DOtherSide/pch/test_pch.cpp vendored Normal file
View File

@ -0,0 +1 @@
#include "test_pch.h"

6
vendor/DOtherSide/pch/test_pch.h vendored Normal file
View File

@ -0,0 +1,6 @@
#include <QtCore>
#include <QtWidgets>
#include <QtGui>
#include <QtQml>
#include <QtQuick>
#include <QtTest>

28
vendor/DOtherSide/test/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,28 @@
project(TestDynamicQObject)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
include_directories(${CMAKE_SOURCE_DIR}/lib/include ${CMAKE_SOURCE_DIR}/lib/include/Qt)
find_package(Qt5Core REQUIRED)
find_package(Qt5Widgets REQUIRED)
find_package(Qt5Test REQUIRED)
find_package(Qt5Quick REQUIRED)
find_package(Qt5QuickTest REQUIRED)
add_executable(${PROJECT_NAME} Resources.qrc
test_dotherside.cpp
MockQObject.h
MockQObject.cpp
MockQAbstractItemModel.h
MockQAbstractItemModel.cpp
Global.h
main.qml
testQObject.qml
testQAbstractItemModel.qml
testQDeclarative.qml
)
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14)
target_link_libraries(${PROJECT_NAME} DOtherSideStatic Qt5::Quick Qt5::Widgets Qt5::Test Qt5::Core)

15
vendor/DOtherSide/test/Global.h vendored Normal file
View File

@ -0,0 +1,15 @@
#pragma once
#include <string>
#include <memory>
#include <DOtherSide/DOtherSide.h>
extern "C" {
typedef void (*VoidDeleter)(void *);
typedef void (*CharDeleter)(char *);
}
using VoidPointer = std::unique_ptr<void, VoidDeleter>;
using CharPointer = std::unique_ptr<char, CharDeleter>;

View File

@ -0,0 +1,231 @@
#include "MockQAbstractItemModel.h"
#include <QMetaType>
using namespace std;
namespace {
std::string toStringFromQVariant(const DosQVariant *variant)
{
CharPointer charArray(dos_qvariant_toString(variant), &dos_chararray_delete);
return std::string(charArray.get());
}
VoidPointer initializeMetaObject()
{
VoidPointer superClassMetaObject(dos_qabstractitemmodel_qmetaobject(),
&dos_qmetaobject_delete);
// Signals
::SignalDefinition signalDefinitionArray[1];
ParameterDefinition nameChanged[1];
nameChanged[0].metaType = QMetaType::QString;
nameChanged[0].name = "name";
signalDefinitionArray[0].name = "nameChanged";
signalDefinitionArray[0].parametersCount = 1;
signalDefinitionArray[0].parameters = nameChanged;
::SignalDefinitions signalDefinitions;
signalDefinitions.count = 1;
signalDefinitions.definitions = signalDefinitionArray;
// Slots
::SlotDefinition slotDefinitionArray[2];
slotDefinitionArray[0].name = "name";
slotDefinitionArray[0].returnMetaType = QMetaType::QString;
slotDefinitionArray[0].parametersCount = 0;
slotDefinitionArray[0].parameters = nullptr;
slotDefinitionArray[1].name = "setName";
slotDefinitionArray[1].returnMetaType = QMetaType::Void;
ParameterDefinition setNameParameters[1];
setNameParameters[0].name = "name";
setNameParameters[0].metaType = QMetaType::QString;
slotDefinitionArray[1].parametersCount = 1;
slotDefinitionArray[1].parameters = setNameParameters;
::SlotDefinitions slotDefinitions;
slotDefinitions.count = 2;
slotDefinitions.definitions = slotDefinitionArray;
// Properties
::PropertyDefinition propertyDefinitionArray[1];
propertyDefinitionArray[0].name = "name";
propertyDefinitionArray[0].notifySignal = "nameChanged";
propertyDefinitionArray[0].propertyMetaType = QMetaType::QString;
propertyDefinitionArray[0].readSlot = "name";
propertyDefinitionArray[0].writeSlot = "setName";
::PropertyDefinitions propertyDefinitions;
propertyDefinitions.count = 1;
propertyDefinitions.definitions = propertyDefinitionArray;
return VoidPointer(dos_qmetaobject_create(superClassMetaObject.get(),
"MockQAbstractListModel",
&signalDefinitions,
&slotDefinitions,
&propertyDefinitions),
&dos_qmetaobject_delete);
}
}
MockQAbstractItemModel::MockQAbstractItemModel()
: m_vptr(nullptr, &dos_qobject_delete)
, m_names(
{"John", "Mary", "Andy", "Anna"
})
{
DosQAbstractItemModelCallbacks callbacks;
callbacks.rowCount = &onRowCountCalled;
callbacks.columnCount = &onColumnCountCalled;
callbacks.data = &onDataCalled;
callbacks.setData = &onSetDataCalled;
callbacks.roleNames = &onRoleNamesCalled;
callbacks.flags = &onFlagsCalled;
callbacks.headerData = &onHeaderDataCalled;
callbacks.index = &onIndexCalled;
callbacks.parent = &onParentCalled;
m_vptr.reset(dos_qabstractitemmodel_create(this, metaObject(), &onSlotCalled, &callbacks));
}
DosQMetaObject *MockQAbstractItemModel::metaObject()
{
static VoidPointer result = initializeMetaObject();
return result.get();
}
DosQObject *MockQAbstractItemModel::data()
{
return m_vptr.get();
}
string MockQAbstractItemModel::objectName() const
{
CharPointer result (dos_qobject_objectName(m_vptr.get()), &dos_chararray_delete);
return string(result.get());
}
void MockQAbstractItemModel::setObjectName(const string &objectName)
{
dos_qobject_setObjectName(m_vptr.get(), objectName.c_str());
}
string MockQAbstractItemModel::name() const
{
return m_name;
}
void MockQAbstractItemModel::setName(const string &name)
{
if (m_name == name)
return;
m_name = name;
nameChanged(name);
}
void MockQAbstractItemModel::nameChanged(const string &name)
{
int argc = 1;
DosQVariant *argv[1];
argv[0] = dos_qvariant_create_string(name.c_str());
dos_qobject_signal_emit(m_vptr.get(), "nameChanged", argc, argv);
dos_qvariant_delete(argv[0]);
}
void MockQAbstractItemModel::onSlotCalled(void *selfVPtr, DosQVariant *dosSlotNameVariant, int dosSlotArgc, DosQVariant **dosSlotArgv)
{
auto self = static_cast<MockQAbstractItemModel *>(selfVPtr);
string slotName = toStringFromQVariant(dosSlotNameVariant);
if (slotName == "name") {
VoidPointer name(dos_qvariant_create_string(self->name().c_str()), &dos_qvariant_delete);
dos_qvariant_assign(dosSlotArgv[0], name.get());
return;
}
if (slotName == "setName") {
self->setName(toStringFromQVariant(dosSlotArgv[1]));
return;
}
}
void MockQAbstractItemModel::onRowCountCalled(void *selfVPtr, const DosQModelIndex *index, int *result)
{
auto self = static_cast<MockQAbstractItemModel *>(selfVPtr);
*result = self->m_names.size();
}
void MockQAbstractItemModel::onColumnCountCalled(void *selfVPtr, const DosQModelIndex *index, int *result)
{
auto self = static_cast<MockQAbstractItemModel *>(selfVPtr);
Q_UNUSED(self)
*result = 1;
}
void MockQAbstractItemModel::onDataCalled(void *selfVPtr, const DosQModelIndex *index, int role, DosQVariant *result)
{
auto self = static_cast<MockQAbstractItemModel *>(selfVPtr);
if (!dos_qmodelindex_isValid(index))
return;
const int row = dos_qmodelindex_row(index);
const int column = dos_qmodelindex_column(index);
if (row < 0 || static_cast<size_t>(row) >= self->m_names.size() || column != 0)
return;
dos_qvariant_setString(result, self->m_names[row].c_str());
}
void MockQAbstractItemModel::onSetDataCalled(void *selfVPtr, const DosQModelIndex *index, const DosQVariant *value, int role, bool *result)
{
auto self = static_cast<MockQAbstractItemModel *>(selfVPtr);
*result = false;
if (!dos_qmodelindex_isValid(index))
return;
const int row = dos_qmodelindex_row(index);
const int column = dos_qmodelindex_column(index);
if (row < 0 || static_cast<size_t>(row) >= self->m_names.size() || column != 0)
return;
self->m_names[row] = toStringFromQVariant(value);
dos_qabstractitemmodel_dataChanged(self->data(), index, index, 0, 0);
*result = true;
}
void MockQAbstractItemModel::onRoleNamesCalled(void *selfVPtr, DosQHashIntQByteArray *result)
{
}
void MockQAbstractItemModel::onFlagsCalled(void *selfVPtr, const DosQModelIndex *index, int *result)
{
}
void MockQAbstractItemModel::onHeaderDataCalled(void *selfVPtr, int section, int orientation, int role, DosQVariant *result)
{
}
void MockQAbstractItemModel::onIndexCalled(void *selfVPtr, int row, int column, const DosQModelIndex *parent, DosQModelIndex *result)
{
auto self = static_cast<MockQAbstractItemModel *>(selfVPtr);
auto index = dos_qabstractitemmodel_createIndex(self->data(), row, column, 0);
dos_qmodelindex_assign(result, index);
dos_qmodelindex_delete(index);
}
void MockQAbstractItemModel::onParentCalled(void *selfVPtr, const DosQModelIndex *child, DosQModelIndex *result)
{
auto index = dos_qmodelindex_create();
dos_qmodelindex_assign(result, index);
dos_qmodelindex_delete(index);
}

View File

@ -0,0 +1,37 @@
#pragma once
#include <Global.h>
#include <vector>
#include <string>
class MockQAbstractItemModel
{
public:
MockQAbstractItemModel();
DosQMetaObject *metaObject();
DosQObject *data();
std::string objectName() const;
void setObjectName(const std::string &objectName);
std::string name() const;
void setName(const std::string &name);
void nameChanged(const std::string &name);
private:
static void onSlotCalled(void *selfVPtr, DosQVariant *dosSlotNameVariant, int dosSlotArgc, DosQVariant **dosSlotArgv);
static void onRowCountCalled(void *selfVPtr, const DosQModelIndex *index, int *result);
static void onColumnCountCalled(void *selfVPtr, const DosQModelIndex *index, int *result);
static void onDataCalled(void *selfVPtr, const DosQModelIndex *index, int role, DosQVariant *result);
static void onSetDataCalled(void *selfVPtr, const DosQModelIndex *index, const DosQVariant *value, int role, bool *result);
static void onRoleNamesCalled(void *selfVPtr, DosQHashIntQByteArray *result);
static void onFlagsCalled(void *selfVPtr, const DosQModelIndex *index, int *result);
static void onHeaderDataCalled(void *selfVPtr, int section, int orientation, int role, DosQVariant *result);
static void onIndexCalled(void *selfVPtr, int row, int column, const DosQModelIndex *parent, DosQModelIndex *result);
static void onParentCalled(void *selfVPtr, const DosQModelIndex *child, DosQModelIndex *result);
VoidPointer m_vptr;
std::string m_name;
std::vector<std::string> m_names;
};

227
vendor/DOtherSide/test/MockQObject.cpp vendored Normal file
View File

@ -0,0 +1,227 @@
#include <MockQObject.h>
#include <Global.h>
#include <QMetaType>
using namespace std;
namespace {
std::string toStringFromQVariant(DosQVariant *variant)
{
CharPointer charArray(dos_qvariant_toString(variant), &dos_chararray_delete);
return std::string(charArray.get());
}
VoidPointer initializeMetaObject()
{
VoidPointer superClassMetaObject(dos_qobject_qmetaobject(), &dos_qmetaobject_delete);
// Signals
::SignalDefinition signalDefinitionArray[2];
// nameChanged
ParameterDefinition nameChanged[1];
nameChanged[0].name = "name";
nameChanged[0].metaType = QMetaType::QString;
signalDefinitionArray[0].name = "nameChanged";
signalDefinitionArray[0].parametersCount = 1;
signalDefinitionArray[0].parameters = nameChanged;
// arrayPropertyChanged
ParameterDefinition arrayPropertyChanged[1];
arrayPropertyChanged[0].metaType = QMetaType::QVariantList;
arrayPropertyChanged[0].name = "arrayProperty";
signalDefinitionArray[1].name = "arrayPropertyChanged";
signalDefinitionArray[1].parametersCount = 1;
signalDefinitionArray[1].parameters = arrayPropertyChanged;
::SignalDefinitions signalDefinitions;
signalDefinitions.count = 2;
signalDefinitions.definitions = signalDefinitionArray;
// Slots
::SlotDefinition slotDefinitionArray[4];
slotDefinitionArray[0].name = "name";
slotDefinitionArray[0].returnMetaType = QMetaType::QString;
slotDefinitionArray[0].parametersCount = 0;
slotDefinitionArray[0].parameters = nullptr;
ParameterDefinition setNameParameters[1];
setNameParameters[0].metaType = QMetaType::QString;
setNameParameters[0].name = "name";
slotDefinitionArray[1].name = "setName";
slotDefinitionArray[1].returnMetaType = QMetaType::Void;
slotDefinitionArray[1].parametersCount = 1;
slotDefinitionArray[1].parameters = setNameParameters;
slotDefinitionArray[2].name = "arrayProperty";
slotDefinitionArray[2].returnMetaType = QMetaType::QVariantList;
slotDefinitionArray[2].parametersCount = 0;
slotDefinitionArray[2].parameters = nullptr;
ParameterDefinition setArrayPropertyParameters[1];
setArrayPropertyParameters[0].metaType = QMetaType::QVariantList;
setArrayPropertyParameters[0].name = "arrayProperty";
slotDefinitionArray[3].name = "setArrayProperty";
slotDefinitionArray[3].returnMetaType = QMetaType::Void;
slotDefinitionArray[3].parametersCount = 1;
slotDefinitionArray[3].parameters = setArrayPropertyParameters;
::SlotDefinitions slotDefinitions;
slotDefinitions.count = 4;
slotDefinitions.definitions = slotDefinitionArray;
// Properties
::PropertyDefinition propertyDefinitionArray[2];
propertyDefinitionArray[0].name = "name";
propertyDefinitionArray[0].notifySignal = "nameChanged";
propertyDefinitionArray[0].propertyMetaType = QMetaType::QString;
propertyDefinitionArray[0].readSlot = "name";
propertyDefinitionArray[0].writeSlot = "setName";
propertyDefinitionArray[1].name = "arrayProperty";
propertyDefinitionArray[1].notifySignal = "arrayPropertyChanged";
propertyDefinitionArray[1].propertyMetaType = QMetaType::QVariantList;
propertyDefinitionArray[1].readSlot = "arrayProperty";
propertyDefinitionArray[1].writeSlot = "setArrayProperty";
::PropertyDefinitions propertyDefinitions;
propertyDefinitions.count = 2;
propertyDefinitions.definitions = propertyDefinitionArray;
return VoidPointer(dos_qmetaobject_create(superClassMetaObject.get(), "MockQObject", &signalDefinitions, &slotDefinitions, &propertyDefinitions),
&dos_qmetaobject_delete);
}
}
MockQObject::MockQObject()
: m_vptr(dos_qobject_create(this, metaObject(), &onSlotCalled), &dos_qobject_delete)
, m_arrayProperty(std::make_tuple(10, 5.3, false))
{}
MockQObject::~MockQObject() = default;
DosQMetaObject *MockQObject::staticMetaObject()
{
static VoidPointer result = initializeMetaObject();
return result.get();
}
::DosQMetaObject *MockQObject::metaObject()
{
return staticMetaObject();
}
std::string MockQObject::objectName() const
{
CharPointer result (dos_qobject_objectName(m_vptr.get()), &dos_chararray_delete);
return string(result.get());
}
void MockQObject::setObjectName(const string &objectName)
{
dos_qobject_setObjectName(m_vptr.get(), objectName.c_str());
}
::DosQObject *MockQObject::data()
{
return m_vptr.get();
}
void MockQObject::swapData(VoidPointer &data)
{
std::swap(m_vptr, data);
}
std::string MockQObject::name() const
{
return m_name;
}
void MockQObject::setName(const string &name)
{
if (name == m_name)
return;
m_name = name;
nameChanged(name);
}
void MockQObject::nameChanged(const string &name)
{
int argc = 1;
DosQVariant *argv[1];
argv[0] = dos_qvariant_create_string(name.c_str());
dos_qobject_signal_emit(m_vptr.get(), "nameChanged", argc, argv);
dos_qvariant_delete(argv[0]);
}
std::tuple<int, double, bool> MockQObject::arrayProperty() const
{
return m_arrayProperty;
}
void MockQObject::setArrayProperty(std::tuple<int, double, bool> value)
{
if (m_arrayProperty == value)
return;
m_arrayProperty = std::move(value);
arrayPropertyChanged(value);
}
void MockQObject::arrayPropertyChanged(const std::tuple<int, double, bool> &value)
{
std::vector<DosQVariant *> valueAsDosQVariant ({
dos_qvariant_create_int(std::get<0>(value)),
dos_qvariant_create_double(std::get<1>(value)),
dos_qvariant_create_bool(std::get<2>(value))
});
int argc = 1;
DosQVariant *argv[1];
argv[0] = dos_qvariant_create_array(valueAsDosQVariant.size(), &valueAsDosQVariant[0]);
dos_qobject_signal_emit(m_vptr.get(), "arrayPropertyChanged", argc, argv);
dos_qvariant_delete(argv[0]);
std::for_each(valueAsDosQVariant.begin(), valueAsDosQVariant.end(), &dos_qvariant_delete);
}
void MockQObject::onSlotCalled(void *selfVPtr, DosQVariant *dosSlotNameVariant, int dosSlotArgc, DosQVariant **dosSlotArgv)
{
MockQObject *self = static_cast<MockQObject *>(selfVPtr);
string slotName = toStringFromQVariant(dosSlotNameVariant);
if (slotName == "name") {
VoidPointer name(dos_qvariant_create_string(self->name().c_str()), &dos_qvariant_delete);
dos_qvariant_assign(dosSlotArgv[0], name.get());
return;
}
if (slotName == "setName") {
self->setName(toStringFromQVariant(dosSlotArgv[1]));
return;
}
if (slotName == "arrayProperty") {
auto value = self->arrayProperty();
std::vector<DosQVariant *> data {
dos_qvariant_create_int(std::get<0>(value)),
dos_qvariant_create_double(std::get<1>(value)),
dos_qvariant_create_bool(std::get<2>(value))
};
VoidPointer arrayProperty(dos_qvariant_create_array(data.size(), &data[0]), &dos_qvariant_delete);
dos_qvariant_assign(dosSlotArgv[0], arrayProperty.get());
std::for_each(data.begin(), data.end(), &dos_qvariant_delete);
return;
}
if (slotName == "setArrayProperty") {
std::tuple<int, double, bool> value;
DosQVariantArray *array = dos_qvariant_toArray(dosSlotArgv[1]);
std::get<0>(value) = dos_qvariant_toInt(array->data[0]);
std::get<1>(value) = dos_qvariant_toDouble(array->data[1]);
std::get<2>(value) = dos_qvariant_toBool(array->data[2]);
dos_qvariantarray_delete(array);
self->setArrayProperty(std::move(value));
return;
}
}

35
vendor/DOtherSide/test/MockQObject.h vendored Normal file
View File

@ -0,0 +1,35 @@
#pragma once
#include <tuple>
#include <Global.h>
class MockQObject
{
public:
MockQObject();
virtual ~MockQObject();
static ::DosQMetaObject *staticMetaObject();
virtual ::DosQMetaObject *metaObject();
::DosQObject *data();
void swapData(VoidPointer &data);
std::string objectName() const;
void setObjectName(const std::string &objectName);
std::string name() const;
void setName(const std::string &name);
void nameChanged(const std::string &name);
std::tuple<int, double, bool> arrayProperty() const;
void setArrayProperty(std::tuple<int, double, bool> value);
void arrayPropertyChanged(const std::tuple<int, double, bool> &value);
private:
static void onSlotCalled(void *selfVPtr, DosQVariant *dosSlotNameVariant, int dosSlotArgc, DosQVariant **dosSlotArgv);
VoidPointer m_vptr;
std::string m_name;
std::tuple<int, double, bool> m_arrayProperty;
};

9
vendor/DOtherSide/test/Resources.qrc vendored Normal file
View File

@ -0,0 +1,9 @@
<RCC>
<qresource prefix="/">
<file>main.qml</file>
<file>testQAbstractItemModel.qml</file>
<file>testQObject.qml</file>
<file>testQDeclarative.qml</file>
<file>testQQuickView.qml</file>
</qresource>
</RCC>

9
vendor/DOtherSide/test/main.qml vendored Normal file
View File

@ -0,0 +1,9 @@
import QtQuick 2.3
import QtQuick.Controls 1.2
ApplicationWindow {
width: 100
height: 100
objectName: "testWindow"
Component.onCompleted: visible = true
}

16
vendor/DOtherSide/test/meson.build vendored Normal file
View File

@ -0,0 +1,16 @@
test_dependencies = dependency('qt5', modules : ['Core', 'Gui', 'Widgets', 'Quick', 'Qml', 'Test'])
test_sources = ['test_dotherside.cpp', 'MockQAbstractItemModel.cpp', 'MockQObject.cpp']
test_resources = 'Resources.qrc'
test_include_directories = ['../lib/include', '../lib/include/Qt']
test_pch = ['../pch/test_pch.h', '../pch/test_pch.cpp']
qt5 = import('qt5')
test_moc_files = qt5.preprocess(moc_sources : test_sources, qresources : test_resources)
executable('TestDOtherSide',
sources : [test_sources, test_moc_files],
include_directories : include_directories(test_include_directories),
link_with : lib,
dependencies : test_dependencies,
cpp_pch: test_pch
)

View File

@ -0,0 +1,64 @@
import QtQuick 2.3
QtObject {
id: testCase
objectName: "testCase"
function testObjectName() {
return testObject && testObject.objectName === "testObject"
}
function testPropertyReadAndWrite() {
if (!testObject)
return false
if (testObject.name !== "foo")
return false
testObject.name = "bar"
if (testObject.name !== "bar")
return false
return true
}
function testSignalEmittion() {
if (!testObject)
return false
if (testObject.name !== "foo")
return false
var result = false
testObject.nameChanged.connect(function(name){ result = name === "bar" })
testObject.name = "bar"
return result
}
function testRowCount() {
return testObject && testObject.rowCount() === 4
}
function testColumnCount() {
return testObject && testObject.columnCount() === 1;
}
function testData() {
return testObject && testObject.data(testObject.index(0,0, null)) === "John"
&& testObject.data(testObject.index(1,0, null)) === "Mary"
&& testObject.data(testObject.index(2,0, null)) === "Andy"
&& testObject.data(testObject.index(3,0, null)) === "Anna"
}
function testSetData() {
if (!testObject)
return false
var index = testObject.index(0,0, null)
if (!index.valid)
return false;
if (testObject.data(index) !== "John")
return false
var dataChanged = false
testObject.dataChanged.connect(function(topLeft, bottomRight, role) {
dataChanged = topLeft === index && bottomRight === index
})
if (!testObject.setData(index, "Paul"))
return false
return testObject.data(index) === "Paul";
}
}

View File

@ -0,0 +1,41 @@
import QtQuick 2.3
import MockModule 1.0
Item {
id: testCase
objectName: "testCase"
Component {
id: mockQObjectComponent
MockQObject {}
}
function testMockQObject(testObject) {
if (!testObject)
return false
if (testObject.name !== "foo")
return false
var nameChangedEmitted = false
testObject.nameChanged.connect(function(name){nameChangedEmitted = name === "bar"});
testObject.name = "bar"
return nameChangedEmitted && testObject.name === "bar"
}
function testQmlRegisterType() {
var testObject = mockQObjectComponent.createObject(testCase, {"name":"foo"})
var result = testMockQObject(testObject)
if (testObject)
testObject.destroy()
return result
}
function testQmlRegisterSingletonType() {
var testObject = MockQObjectSingleton
MockQObjectSingleton.name = "foo"
return testMockQObject(testObject)
}
}

42
vendor/DOtherSide/test/testQObject.qml vendored Normal file
View File

@ -0,0 +1,42 @@
import QtQuick 2.3
QtObject {
id: testCase
objectName: "testCase"
function testObjectName() {
return testObject && testObject.objectName === "testObject"
}
function testPropertyReadAndWrite() {
if (!testObject)
return false
if (testObject.name !== "foo")
return false
testObject.name = "bar"
if (testObject.name !== "bar")
return false
return true
}
function testSignalEmittion() {
if (!testObject)
return false
if (testObject.name !== "foo")
return false
var result = false
testObject.nameChanged.connect(function(name){ result = name === "bar" })
testObject.name = "bar"
return result
}
function testArrayProperty() {
if (!testObject)
return false
var values = testObject.arrayProperty
if (values[0] != 10 || values[1] != 5.3 || values[2] != false)
return false
testObject.arrayProperty = [404, 6.3, true]
return values[0] != 404 || values[1] != 6.3 || values[2] != true
}
}

View File

@ -0,0 +1,7 @@
import QtQuick 2.5
Item {
objectName: "testObject"
width: 400
height: 400
}

View File

@ -0,0 +1,753 @@
// std
#include <tuple>
#include <iostream>
#include <memory>
// Qt
#include <QDebug>
#include <QTest>
#include <QSignalSpy>
#include <QTimer>
#include <QApplication>
#include <QQuickWindow>
#include <QQmlApplicationEngine>
#include <QQuickItem>
#include <QQmlContext>
#include <QtQuickTest/QtQuickTest>
// DOtherSide
#include <DOtherSide/DOtherSide.h>
#include <DOtherSide/DosQObject.h>
#include <DOtherSide/DosQMetaObject.h>
#include <DOtherSide/DosQObject.h>
#include <DOtherSide/DosQAbstractItemModel.h>
#include "MockQObject.h"
#include "MockQAbstractItemModel.h"
using namespace std;
using namespace DOS;
template<typename Test>
bool ExecuteTest(int argc, char *argv[])
{
Test test;
return QTest::qExec(&test, argc, argv) == 0;
}
template<typename Test>
bool ExecuteGuiTest(int argc, char *argv[])
{
QApplication app(argc, argv);
Test test;
return QTest::qExec(&test, argc, argv) == 0;
}
/*
* Test QGuiApplication
*/
class TestQGuiApplication : public QObject
{
Q_OBJECT
private slots:
void testExecution()
{
bool quit = false;
dos_qguiapplication_create();
QTimer::singleShot(100, [&quit]() {
quit = true;
dos_qguiapplication_quit();
});
dos_qguiapplication_exec();
QVERIFY(quit);
dos_qguiapplication_delete();
}
};
/*
* Test QApplication
*/
class TestQApplication : public QObject
{
Q_OBJECT
private slots:
void testExecution()
{
bool quit = false;
dos_qapplication_create();
QTimer::singleShot(100, [&quit]() {
quit = true;
dos_qapplication_quit();
});
dos_qapplication_exec();
QVERIFY(quit);
dos_qapplication_delete();
}
};
/*
* Test QVariant
*/
class TestQVariant : public QObject
{
Q_OBJECT
private slots:
void testCreate()
{
VoidPointer data(dos_qvariant_create(), &dos_qvariant_delete);
Q_ASSERT(data.get());
QCOMPARE(dos_qvariant_isnull(data.get()), true);
}
void testInt()
{
VoidPointer data(dos_qvariant_create_int(10), &dos_qvariant_delete);
Q_ASSERT(data.get());
QCOMPARE(dos_qvariant_isnull(data.get()), false);
int value = dos_qvariant_toInt(data.get());
QCOMPARE(value, 10);
dos_qvariant_setInt(data.get(), 20);
value = dos_qvariant_toInt(data.get());
QCOMPARE(value, 20);
}
void testBool()
{
VoidPointer data(dos_qvariant_create_bool(false), &dos_qvariant_delete);
Q_ASSERT(data.get());
QCOMPARE(dos_qvariant_isnull(data.get()), false);
bool value = dos_qvariant_toBool(data.get());
QCOMPARE(value, false);
dos_qvariant_setBool(data.get(), true);
value = dos_qvariant_toBool(data.get());
QCOMPARE(value, true);
}
void testFloat()
{
VoidPointer data(dos_qvariant_create_float(float(5.5)), &dos_qvariant_delete);
Q_ASSERT(data.get());
QCOMPARE(dos_qvariant_isnull(data.get()), false);
float value = dos_qvariant_toFloat(data.get());
QCOMPARE(value, float(5.5));
dos_qvariant_setFloat(data.get(), float(10.3));
value = dos_qvariant_toFloat(data.get());
QCOMPARE(value, float(10.3));
}
void testDouble()
{
VoidPointer data(dos_qvariant_create_double(double(5.5)), &dos_qvariant_delete);
Q_ASSERT(data.get());
QCOMPARE(dos_qvariant_isnull(data.get()), false);
double value = dos_qvariant_toDouble(data.get());
QCOMPARE(value, double(5.5));
dos_qvariant_setDouble(data.get(), double(10.3));
value = dos_qvariant_toDouble(data.get());
QCOMPARE(value, double(10.3));
}
void testString()
{
VoidPointer data(dos_qvariant_create_string("Foo"), &dos_qvariant_delete);
Q_ASSERT(data.get());
QCOMPARE(dos_qvariant_isnull(data.get()), false);
char *value = dos_qvariant_toString(data.get());
std::string copy (value);
dos_chararray_delete(value);
QCOMPARE(copy, std::string("Foo"));
dos_qvariant_setString(data.get(), "Bar");
value = dos_qvariant_toString(data.get());
copy = std::string(value);
dos_chararray_delete(value);
QCOMPARE(copy, std::string("Bar"));
}
void testQObject()
{
unique_ptr<MockQObject> testObject(new MockQObject());
testObject->setObjectName("testObject");
testObject->setName("foo");
VoidPointer data(dos_qvariant_create_qobject(testObject->data()), &dos_qvariant_delete);
auto value = dos_qvariant_toQObject(data.get());
QVERIFY(value == testObject->data());
dos_qvariant_setQObject(data.get(), nullptr);
value = dos_qvariant_toQObject(data.get());
QVERIFY(value == nullptr);
}
void testQVariant()
{
QVariant original("foo");
QVERIFY(original.type() == QVariant::String);
VoidPointer copyPointer(dos_qvariant_create_qvariant(&original), &dos_qvariant_delete);
QVariant* copy = static_cast<QVariant*>(copyPointer.get());
QCOMPARE(copy->type(), original.type());
QCOMPARE(copy->toString().toStdString(), original.toString().toStdString());
}
void testArray()
{
std::vector<DosQVariant *> data ({
dos_qvariant_create_int(10),
dos_qvariant_create_double(4.3),
dos_qvariant_create_bool(false),
dos_qvariant_create_string("FooBar")
});
VoidPointer variant (dos_qvariant_create_array(data.size(), &data[0]), &dos_qvariant_delete);
DosQVariantArray *array = dos_qvariant_toArray(variant.get());
QVERIFY(array);
QCOMPARE(int(data.size()), array->size);
QCOMPARE(dos_qvariant_toInt(array->data[0]), int(10));
QCOMPARE(dos_qvariant_toDouble(array->data[1]), double(4.3));
QCOMPARE(dos_qvariant_toBool(array->data[2]), false);
dos_qvariantarray_delete(array);
std::for_each(data.begin(), data.end(), &dos_qvariant_delete);
}
};
/*
* Test QUrl
*/
class TestQUrl : public QObject
{
Q_OBJECT
private slots:
void testCreate()
{
const string testUrl("http://www.qt.io");
VoidPointer url(dos_qurl_create(testUrl.c_str(), QUrl::StrictMode), &dos_qurl_delete);
QVERIFY(url.get());
QVERIFY(dos_qurl_isValid(url.get()));
CharPointer str (dos_qurl_to_string(url.get()), &dos_chararray_delete);
QCOMPARE(std::string(str.get()), testUrl);
}
};
/*
* Test QQmlApplicationEngine
*/
class TestQQmlApplicationEngine : public QObject
{
Q_OBJECT
private slots:
void initTestCase()
{
m_engine = nullptr;
}
void cleanupTestCase()
{
QVERIFY(m_engine == nullptr);
}
void init()
{
QVERIFY(m_engine == nullptr);
m_engine = dos_qqmlapplicationengine_create();
QVERIFY(m_engine != nullptr);
}
void cleanup()
{
dos_qqmlapplicationengine_delete(m_engine);
m_engine = nullptr;
}
void testCreateAndDelete()
{
// Implicit by invoking init and cleanup
}
void testLoadUrl()
{
void *url = dos_qurl_create("qrc:///main.qml", QUrl::TolerantMode);
QVERIFY(url != nullptr);
dos_qqmlapplicationengine_load_url(m_engine, url);
QCOMPARE(engine()->rootObjects().size(), 1);
QCOMPARE(engine()->rootObjects().front()->objectName(), QString::fromLocal8Bit("testWindow"));
QVERIFY(engine()->rootObjects().front()->isWindowType());
dos_qurl_delete(url);
}
void testLoadData()
{
dos_qqmlapplicationengine_load_data(m_engine, "import QtQuick 2.3; import QtQuick.Controls 1.2; ApplicationWindow { objectName: \"testWindow\"}");
QCOMPARE(engine()->rootObjects().size(), 1);
QCOMPARE(engine()->rootObjects().front()->objectName(), QString::fromLocal8Bit("testWindow"));
QVERIFY(engine()->rootObjects().front()->isWindowType());
}
private:
QQmlApplicationEngine *engine()
{
return static_cast<QQmlApplicationEngine *>(m_engine);
}
void *m_engine;
};
/*
* Test QQmlContext
*/
class TestQQmlContext : public QObject
{
Q_OBJECT
private slots:
void initTestCase()
{
m_engine = nullptr;
m_context = nullptr;
}
void cleanupTestCase()
{
QVERIFY(m_engine == nullptr);
QVERIFY(m_context == nullptr);
}
void init()
{
m_engine = dos_qqmlapplicationengine_create();
m_context = dos_qqmlapplicationengine_context(m_engine);
QVERIFY(m_engine != nullptr);
QVERIFY(m_context != nullptr);
}
void cleanup()
{
m_context = nullptr;
dos_qqmlapplicationengine_delete(m_engine);
m_engine = nullptr;
}
void testCreateAndDelete()
{
// Implicit by invoking init and cleanup
}
void testSetContextProperty()
{
QVariant testData("Test Message");
dos_qqmlcontext_setcontextproperty(m_context, "testData", &testData);
engine()->loadData("import QtQuick 2.3; Text { objectName: \"label\"; text: testData } ");
QObject *label = engine()->rootObjects().first();
QVERIFY(label != nullptr);
QCOMPARE(label->objectName(), QString::fromLocal8Bit("label"));
QCOMPARE(label->property("text").toString(), testData.toString());
}
private:
QQmlApplicationEngine *engine()
{
return static_cast<QQmlApplicationEngine *>(m_engine);
}
QQmlContext *context()
{
return static_cast<QQmlContext *>(m_context);
}
void *m_engine;
void *m_context;
};
/*
* Test QObject
*/
class TestQObject : public QObject
{
Q_OBJECT
private slots:
void init()
{
testObject.reset(new MockQObject());
testObject->setObjectName("testObject");
testObject->setName("foo");
engine.reset(new QQmlApplicationEngine());
engine->rootContext()->setContextProperty("testObject", QVariant::fromValue<QObject *>(static_cast<QObject *>(testObject->data())));
engine->load(QUrl("qrc:///testQObject.qml"));
}
void cleanup()
{
engine.reset();
testObject.reset();
}
void testObjectName()
{
QObject *testCase = engine->rootObjects().first();
QVERIFY(testCase);
QVariant result;
QVERIFY(QMetaObject::invokeMethod(testCase, "testObjectName", Q_RETURN_ARG(QVariant, result)));
QVERIFY(result.type() == QVariant::Bool);
QVERIFY(result.toBool());
}
void testPropertyReadAndWrite()
{
QObject *testCase = engine->rootObjects().first();
QVERIFY(testCase);
QVariant result;
QVERIFY(QMetaObject::invokeMethod(testCase, "testPropertyReadAndWrite", Q_RETURN_ARG(QVariant, result)));
QVERIFY(result.type() == QVariant::Bool);
QVERIFY(result.toBool());
}
void testPropertyGetSet() {
MockQObject testobject;
QObject *data = static_cast<QObject *>(testobject.data());
data->setProperty("name", "foo");
{
VoidPointer valuePtr(dos_qobject_property(data, "name"), &dos_qvariant_delete);
auto value = *static_cast<QVariant *>(valuePtr.get());
QVERIFY(value.type() == QVariant::String);
QVERIFY(value.toString() == "foo");
}
QVariant bar("bar");
dos_qobject_setProperty(data, "name", &bar);
{
VoidPointer valuePtr(dos_qobject_property(data, "name"), &dos_qvariant_delete);
auto value = *static_cast<QVariant *>(valuePtr.get());
QVERIFY(value.type() == QVariant::String);
QVERIFY(value.toString() == "bar");
}
}
void testSignalEmittion()
{
QObject *testCase = engine->rootObjects().first();
QVERIFY(testCase);
QVariant result;
QVERIFY(QMetaObject::invokeMethod(testCase, "testSignalEmittion", Q_RETURN_ARG(QVariant, result)));
QVERIFY(result.type() == QVariant::Bool);
QVERIFY(result.toBool());
}
void testArrayProperty()
{
QObject *testCase = engine->rootObjects().first();
QVERIFY(testCase);
QVariant result;
QVERIFY(QMetaObject::invokeMethod(testCase, "testArrayProperty", Q_RETURN_ARG(QVariant, result)));
QVERIFY(result.type() == QVariant::Bool);
QVERIFY(result.toBool());
}
private:
QString value;
unique_ptr<MockQObject> testObject;
unique_ptr<QQmlApplicationEngine> engine;
};
/*
* Test QAbstractItemModel
*/
class TestQAbstractItemModel : public QObject
{
Q_OBJECT
private slots:
void init()
{
testObject.reset(new MockQAbstractItemModel());
testObject->setObjectName("testObject");
testObject->setName("foo");
engine.reset(new QQmlApplicationEngine());
engine->rootContext()->setContextProperty("testObject", QVariant::fromValue<QObject *>(static_cast<QObject *>(testObject->data())));
engine->load(QUrl("qrc:///testQAbstractItemModel.qml"));
}
void cleanup()
{
engine.reset();
testObject.reset();
}
void testObjectName()
{
QObject *testCase = engine->rootObjects().first();
QVERIFY(testCase);
QVariant result;
QVERIFY(QMetaObject::invokeMethod(testCase, "testObjectName", Q_RETURN_ARG(QVariant, result)));
QVERIFY(result.type() == QVariant::Bool);
QVERIFY(result.toBool());
}
void testPropertyReadAndWrite()
{
QObject *testCase = engine->rootObjects().first();
QVERIFY(testCase);
QVariant result;
QVERIFY(QMetaObject::invokeMethod(testCase, "testPropertyReadAndWrite", Q_RETURN_ARG(QVariant, result)));
QVERIFY(result.type() == QVariant::Bool);
QVERIFY(result.toBool());
}
void testSignalEmittion()
{
QObject *testCase = engine->rootObjects().first();
QVERIFY(testCase);
QVariant result;
QVERIFY(QMetaObject::invokeMethod(testCase, "testSignalEmittion", Q_RETURN_ARG(QVariant, result)));
QVERIFY(result.type() == QVariant::Bool);
QVERIFY(result.toBool());
}
void testRowCount()
{
QObject *testCase = engine->rootObjects().first();
QVERIFY(testCase);
QVariant result;
QVERIFY(QMetaObject::invokeMethod(testCase, "testRowCount", Q_RETURN_ARG(QVariant, result)));
QVERIFY(result.type() == QVariant::Bool);
QVERIFY(result.toBool());
}
void testColumnCount()
{
QObject *testCase = engine->rootObjects().first();
QVERIFY(testCase);
QVariant result;
QVERIFY(QMetaObject::invokeMethod(testCase, "testColumnCount", Q_RETURN_ARG(QVariant, result)));
QVERIFY(result.type() == QVariant::Bool);
QVERIFY(result.toBool());
}
void testData()
{
QObject *testCase = engine->rootObjects().first();
QVERIFY(testCase);
QVariant result;
QVERIFY(QMetaObject::invokeMethod(testCase, "testData", Q_RETURN_ARG(QVariant, result)));
QVERIFY(result.type() == QVariant::Bool);
QVERIFY(result.toBool());
}
void testSetData()
{
QObject *testCase = engine->rootObjects().first();
QVERIFY(testCase);
QVariant result;
QVERIFY(QMetaObject::invokeMethod(testCase, "testSetData", Q_RETURN_ARG(QVariant, result)));
QVERIFY(result.type() == QVariant::Bool);
QVERIFY(result.toBool());
}
private:
QString value;
unique_ptr<MockQAbstractItemModel> testObject;
unique_ptr<QQmlApplicationEngine> engine;
};
/*
* Test QDeclarative
*/
class TestQDeclarativeIntegration : public QObject
{
Q_OBJECT
private slots:
void testQmlRegisterType()
{
::QmlRegisterType registerType;
registerType.major = 1;
registerType.minor = 0;
registerType.uri = "MockModule";
registerType.qml = "MockQObject";
registerType.staticMetaObject = MockQObject::staticMetaObject();
registerType.createDObject = &mockQObjectCreator;
registerType.deleteDObject = &mockQObjectDeleter;
dos_qdeclarative_qmlregistertype(&registerType);
auto engine = make_unique<QQmlApplicationEngine>();
engine->load(QUrl("qrc:///testQDeclarative.qml"));
QObject *testCase = engine->rootObjects().first();
QVERIFY(testCase);
QVariant result;
QVERIFY(QMetaObject::invokeMethod(testCase, "testQmlRegisterType", Q_RETURN_ARG(QVariant, result)));
QVERIFY(result.type() == QVariant::Bool);
QVERIFY(result.toBool());
}
void testQmlRegisterSingletonType()
{
::QmlRegisterType registerType;
registerType.major = 1;
registerType.minor = 0;
registerType.uri = "MockModule";
registerType.qml = "MockQObjectSingleton";
registerType.staticMetaObject = MockQObject::staticMetaObject();
registerType.createDObject = &mockQObjectCreator;
registerType.deleteDObject = &mockQObjectDeleter;
dos_qdeclarative_qmlregistersingletontype(&registerType);
auto engine = make_unique<QQmlApplicationEngine>();
engine->load(QUrl("qrc:///testQDeclarative.qml"));
QObject *testCase = engine->rootObjects().first();
QVERIFY(testCase);
QVariant result;
QVERIFY(QMetaObject::invokeMethod(testCase, "testQmlRegisterSingletonType", Q_RETURN_ARG(QVariant, result)));
QVERIFY(result.type() == QVariant::Bool);
QVERIFY(result.toBool());
}
private:
static void mockQObjectCreator(int typeId, void *wrapper, void **mockQObjectPtr, void **dosQObject)
{
VoidPointer data(wrapper, &emptyVoidDeleter);
auto mockQObject = new MockQObject();
mockQObject->swapData(data);
*dosQObject = data.release();
*mockQObjectPtr = mockQObject;
}
static void mockQObjectDeleter(int typeId, void *mockQObject)
{
auto temp = static_cast<MockQObject *>(mockQObject);
delete temp;
}
static void emptyVoidDeleter(void *) {}
};
/*
* Test QModelIndex
*/
class TestQModelIndex : public QObject
{
Q_OBJECT
private slots:
void testCreate()
{
VoidPointer index (dos_qmodelindex_create(), &dos_qmodelindex_delete);
QVERIFY(index.get());
QVERIFY(!dos_qmodelindex_isValid(index.get()));
}
void testRow()
{
VoidPointer index (dos_qmodelindex_create(), &dos_qmodelindex_delete);
QVERIFY(index.get());
QVERIFY(!dos_qmodelindex_isValid(index.get()));
QCOMPARE(dos_qmodelindex_row(index.get()), -1);
}
void testColumn()
{
VoidPointer index (dos_qmodelindex_create(), &dos_qmodelindex_delete);
QVERIFY(index.get());
QVERIFY(!dos_qmodelindex_isValid(index.get()));
QCOMPARE(dos_qmodelindex_column(index.get()), -1);
}
void testParent()
{
VoidPointer index (dos_qmodelindex_create(), &dos_qmodelindex_delete);
QVERIFY(index.get());
QVERIFY(!dos_qmodelindex_isValid(index.get()));
VoidPointer parentIndex (dos_qmodelindex_parent(index.get()), &dos_qmodelindex_delete);
QVERIFY(parentIndex.get());
QVERIFY(!dos_qmodelindex_isValid(parentIndex.get()));
}
void testChild()
{
VoidPointer index (dos_qmodelindex_create(), &dos_qmodelindex_delete);
QVERIFY(index.get());
QVERIFY(!dos_qmodelindex_isValid(index.get()));
VoidPointer childIndex (dos_qmodelindex_child(index.get(), 0, 0), &dos_qmodelindex_delete);
QVERIFY(childIndex.get());
QVERIFY(!dos_qmodelindex_isValid(childIndex.get()));
}
void testSibling()
{
VoidPointer index (dos_qmodelindex_create(), &dos_qmodelindex_delete);
QVERIFY(index.get());
QVERIFY(!dos_qmodelindex_isValid(index.get()));
VoidPointer siblingIndex (dos_qmodelindex_sibling(index.get(), 0, 0), &dos_qmodelindex_delete);
QVERIFY(siblingIndex.get());
QVERIFY(!dos_qmodelindex_isValid(siblingIndex.get()));
}
void testData()
{
VoidPointer index (dos_qmodelindex_create(), &dos_qmodelindex_delete);
QVERIFY(index.get());
QVERIFY(!dos_qmodelindex_isValid(index.get()));
VoidPointer data(dos_qmodelindex_data(index.get(), Qt::DisplayRole), &dos_qvariant_delete);
QVERIFY(data.get());
QVERIFY(dos_qvariant_isnull(data.get()));
}
};
/*
* Test QQuickView
*/
class TestQQuickView : public QObject
{
Q_OBJECT
private slots:
void testCreate()
{
VoidPointer view(dos_qquickview_create(), &dos_qquickview_delete);
QVERIFY(view.get());
}
void testSourceAndSetSource()
{
std::string testUrl = "qrc:/testQQuickView.qml";
VoidPointer view(dos_qquickview_create(), &dos_qquickview_delete);
VoidPointer url(dos_qurl_create(testUrl.c_str(), QUrl::StrictMode), &dos_qurl_delete);
dos_qquickview_set_source_url(view.get(), url.get());
CharPointer tempUrl(dos_qquickview_source(view.get()), &dos_chararray_delete);
QCOMPARE(std::string(tempUrl.get()), testUrl);
dos_qquickview_show(view.get());
}
};
int main(int argc, char *argv[])
{
using namespace DOS;
bool success = true;
success &= ExecuteTest<TestQGuiApplication>(argc, argv);
success &= ExecuteTest<TestQApplication>(argc, argv);
success &= ExecuteTest<TestQVariant>(argc, argv);
success &= ExecuteTest<TestQUrl>(argc, argv);
success &= ExecuteTest<TestQModelIndex>(argc, argv);
success &= ExecuteGuiTest<TestQQmlApplicationEngine>(argc, argv);
success &= ExecuteGuiTest<TestQQmlContext>(argc, argv);
success &= ExecuteGuiTest<TestQObject>(argc, argv);
success &= ExecuteGuiTest<TestQAbstractItemModel>(argc, argv);
success &= ExecuteGuiTest<TestQDeclarativeIntegration>(argc, argv);
success &= ExecuteGuiTest<TestQQuickView>(argc, argv);
return success ? 0 : 1;
}
#include "test_dotherside.moc"