diff options
83 files changed, 1889 insertions, 1000 deletions
diff --git a/.cmake.conf b/.cmake.conf new file mode 100644 index 0000000..9305480 --- /dev/null +++ b/.cmake.conf @@ -0,0 +1 @@ +set(QT_REPO_MODULE_VERSION "6.0.0") diff --git a/.qmake.conf b/.qmake.conf index b3c7403..3066cd8 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -1,5 +1,5 @@ load(qt_build_config) -DEFINES += QT_NO_FOREACH QT_NO_JAVA_STYLE_ITERATORS QT_NO_LINKED_LIST +DEFINES += QT_NO_FOREACH QT_NO_JAVA_STYLE_ITERATORS -MODULE_VERSION = 5.15.0 +MODULE_VERSION = 6.0.0 diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..14352ff --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,20 @@ +# Generated from qtactiveqt.pro. + +cmake_minimum_required(VERSION 3.15.0) + +include(".cmake.conf") +project(QtActiveQt # special case + VERSION "${QT_REPO_MODULE_VERSION}" + DESCRIPTION "Qt Active Qt Libraries" # special case + HOMEPAGE_URL "https://qt.io/" + LANGUAGES CXX C +) + +find_package(Qt6 ${PROJECT_VERSION} CONFIG REQUIRED COMPONENTS BuildInternals Core Gui Widgets PrintSupport) # special case +find_package(Qt6 ${PROJECT_VERSION} CONFIG OPTIONAL_COMPONENTS Qml Quick) # special case + +if(NOT TARGET Qt::Widgets) + message(NOTICE "Skipping the build as the condition \"TARGET Qt::Widgets\" is not met.") + return() +endif() +qt_build_repo() diff --git a/dependencies.yaml b/dependencies.yaml new file mode 100644 index 0000000..2e75d8e --- /dev/null +++ b/dependencies.yaml @@ -0,0 +1,4 @@ +dependencies: + ../qtbase: + ref: 2eee9e6fcf9b70681c5d9202d1509d176e48fc31 + required: true diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt new file mode 100644 index 0000000..362d2da --- /dev/null +++ b/examples/CMakeLists.txt @@ -0,0 +1,7 @@ +# Generated from examples.pro. + +qt_examples_build_begin() + +add_subdirectory(activeqt) + +qt_examples_build_end() diff --git a/examples/activeqt/CMakeLists.txt b/examples/activeqt/CMakeLists.txt new file mode 100644 index 0000000..c71db69 --- /dev/null +++ b/examples/activeqt/CMakeLists.txt @@ -0,0 +1,17 @@ +# Generated from activeqt.pro. + +add_subdirectory(comapp) +add_subdirectory(hierarchy) +add_subdirectory(menus) +add_subdirectory(multiple) +add_subdirectory(simple) +add_subdirectory(wrapper) +if(MINGW OR QT_BUILD_SHARED_LIBS) + add_subdirectory(mediaplayer) +endif() +if(TARGET Qt6::OpenGLWidgets AND QT_FEATURE_opengl AND NOT QT_FEATURE_opengles2) # special case + add_subdirectory(opengl) +endif() +if(TARGET Qt::QuickControls2) + add_subdirectory(simpleqml) +endif() diff --git a/examples/activeqt/comapp/CMakeLists.txt b/examples/activeqt/comapp/CMakeLists.txt new file mode 100644 index 0000000..d2100be --- /dev/null +++ b/examples/activeqt/comapp/CMakeLists.txt @@ -0,0 +1,37 @@ +# Generated from comapp.pro. + +cmake_minimum_required(VERSION 3.14) +project(comapp LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/activeqt/comapp") + +find_package(Qt6 COMPONENTS Core) +find_package(Qt6 COMPONENTS Gui) +find_package(Qt6 COMPONENTS AxServer) +find_package(Qt6 COMPONENTS Widgets) + +add_qt_gui_executable(comapp + main.cpp +) +target_link_libraries(comapp PUBLIC + Qt::AxServer + Qt::Core + Qt::Gui + Qt::Widgets +) + +install(TARGETS comapp + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/activeqt/hierarchy/CMakeLists.txt b/examples/activeqt/hierarchy/CMakeLists.txt new file mode 100644 index 0000000..0d6d006 --- /dev/null +++ b/examples/activeqt/hierarchy/CMakeLists.txt @@ -0,0 +1,38 @@ +# Generated from hierarchy.pro. + +cmake_minimum_required(VERSION 3.14) +project(hierarchyax LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/activeqt/hierarchy") + +find_package(Qt6 COMPONENTS Core) +find_package(Qt6 COMPONENTS Gui) +find_package(Qt6 COMPONENTS Widgets) +find_package(Qt6 COMPONENTS AxServer) + +add_qt_gui_executable(hierarchyax + main.cpp + objects.cpp objects.h +) +target_link_libraries(hierarchyax PUBLIC + Qt::AxServer + Qt::Core + Qt::Gui + Qt::Widgets +) + +install(TARGETS hierarchyax + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/activeqt/mediaplayer/CMakeLists.txt b/examples/activeqt/mediaplayer/CMakeLists.txt new file mode 100644 index 0000000..317ea40 --- /dev/null +++ b/examples/activeqt/mediaplayer/CMakeLists.txt @@ -0,0 +1,39 @@ +# Generated from mediaplayer.pro. + +cmake_minimum_required(VERSION 3.14) +project(mediaplayer LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/activeqt/mediaplayer") + +find_package(Qt6 COMPONENTS Core) +find_package(Qt6 COMPONENTS Gui) +find_package(Qt6 COMPONENTS Widgets) +find_package(Qt6 COMPONENTS AxContainer) + +add_qt_gui_executable(mediaplayer + main.cpp + mainwindow.ui + mediaaxwidget.h +) +target_link_libraries(mediaplayer PUBLIC + Qt::AxContainer + Qt::Core + Qt::Gui + Qt::Widgets +) + +install(TARGETS mediaplayer + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/activeqt/mediaplayer/mediaaxwidget.h b/examples/activeqt/mediaplayer/mediaaxwidget.h index a6da749..9eedb0a 100644 --- a/examples/activeqt/mediaplayer/mediaaxwidget.h +++ b/examples/activeqt/mediaplayer/mediaaxwidget.h @@ -51,7 +51,7 @@ #ifndef MEDIAAXWIDGET_H #define MEDIAAXWIDGET_H -#include <ActiveQt/QAxWidget> +#include <QtAxContainer/QAxWidget> #include <qt_windows.h> // Overrides the translateKeyEvent() function to pass keystrokes diff --git a/examples/activeqt/menus/CMakeLists.txt b/examples/activeqt/menus/CMakeLists.txt new file mode 100644 index 0000000..1bf6a6b --- /dev/null +++ b/examples/activeqt/menus/CMakeLists.txt @@ -0,0 +1,38 @@ +# Generated from menus.pro. + +cmake_minimum_required(VERSION 3.14) +project(menusax LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/activeqt/menus") + +find_package(Qt6 COMPONENTS Core) +find_package(Qt6 COMPONENTS Gui) +find_package(Qt6 COMPONENTS Widgets) +find_package(Qt6 COMPONENTS AxServer) + +add_qt_gui_executable(menusax + main.cpp + menus.cpp menus.h +) +target_link_libraries(menusax PUBLIC + Qt::AxServer + Qt::Core + Qt::Gui + Qt::Widgets +) + +install(TARGETS menusax + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/activeqt/multiple/CMakeLists.txt b/examples/activeqt/multiple/CMakeLists.txt new file mode 100644 index 0000000..ac9f8a9 --- /dev/null +++ b/examples/activeqt/multiple/CMakeLists.txt @@ -0,0 +1,39 @@ +# Generated from multiple.pro. + +cmake_minimum_required(VERSION 3.14) +project(multipleax LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/activeqt/multiple") + +find_package(Qt6 COMPONENTS Core) +find_package(Qt6 COMPONENTS Gui) +find_package(Qt6 COMPONENTS Widgets) +find_package(Qt6 COMPONENTS AxServer) + +add_qt_gui_executable(multipleax + ax1.h + ax2.h + main.cpp +) +target_link_libraries(multipleax PUBLIC + Qt::AxServer + Qt::Core + Qt::Gui + Qt::Widgets +) + +install(TARGETS multipleax + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/activeqt/opengl/CMakeLists.txt b/examples/activeqt/opengl/CMakeLists.txt new file mode 100644 index 0000000..5c08b0c --- /dev/null +++ b/examples/activeqt/opengl/CMakeLists.txt @@ -0,0 +1,43 @@ +# Generated from opengl.pro. + +cmake_minimum_required(VERSION 3.14) +project(openglax LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/activeqt/opengl") + +find_package(Qt6 COMPONENTS Core) +find_package(Qt6 COMPONENTS Gui) +find_package(Qt6 COMPONENTS Widgets) +find_package(Qt6 COMPONENTS AxServer) +find_package(Qt6 COMPONENTS OpenGL) +find_package(Qt6 COMPONENTS OpenGLWidgets) + +add_qt_gui_executable(openglax + glbox.cpp glbox.h + globjwin.cpp globjwin.h + main.cpp +) +target_link_libraries(openglax PUBLIC + Qt::AxServer + Qt::Core + Qt::Gui + Qt::OpenGL + Qt::OpenGLWidgets + Qt::Widgets +) + +install(TARGETS openglax + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/activeqt/opengl/globjwin.cpp b/examples/activeqt/opengl/globjwin.cpp index dbb7e82..0324f06 100644 --- a/examples/activeqt/opengl/globjwin.cpp +++ b/examples/activeqt/opengl/globjwin.cpp @@ -110,7 +110,7 @@ GLObjectWindow::GLObjectWindow(QWidget *parent) // Put the GL widget inside the frame QHBoxLayout *flayout = new QHBoxLayout(f); - flayout->setMargin(0); + flayout->setContentsMargins(0, 0, 0, 0); flayout->addWidget(c, 1); hlayout->setMenuBar(m); diff --git a/examples/activeqt/opengl/opengl.pro b/examples/activeqt/opengl/opengl.pro index c62f700..1ece9b9 100644 --- a/examples/activeqt/opengl/opengl.pro +++ b/examples/activeqt/opengl/opengl.pro @@ -2,7 +2,7 @@ TEMPLATE = app TARGET = openglax CONFIG += warn_off -QT += widgets axserver +QT += widgets axserver opengl openglwidgets HEADERS = glbox.h \ globjwin.h diff --git a/examples/activeqt/qutlook/CMakeLists.txt b/examples/activeqt/qutlook/CMakeLists.txt new file mode 100644 index 0000000..3373330 --- /dev/null +++ b/examples/activeqt/qutlook/CMakeLists.txt @@ -0,0 +1,42 @@ +# Generated from qutlook.pro. + +cmake_minimum_required(VERSION 3.14) +project(qutlook LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/activeqt/qutlook") + +find_package(Qt6 COMPONENTS Core) +find_package(Qt6 COMPONENTS Gui) +find_package(Qt6 COMPONENTS Widgets) +find_package(Qt6 COMPONENTS AxContainer) + +) +target_link_libraries(qutlook PUBLIC + Qt::AxContainer + Qt::Core + Qt::Gui + Qt::Widgets +) + +if(NOT TYPELIBS_ISEMPTY) + target_sources(qutlook PUBLIC + addressview.cpp addressview.h + main.cpp + ) +endif() + +install(TARGETS qutlook + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/activeqt/simple/CMakeLists.txt b/examples/activeqt/simple/CMakeLists.txt new file mode 100644 index 0000000..600defb --- /dev/null +++ b/examples/activeqt/simple/CMakeLists.txt @@ -0,0 +1,37 @@ +# Generated from simple.pro. + +cmake_minimum_required(VERSION 3.14) +project(simpleax LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/activeqt/simple") + +find_package(Qt6 COMPONENTS Core) +find_package(Qt6 COMPONENTS Gui) +find_package(Qt6 COMPONENTS Widgets) +find_package(Qt6 COMPONENTS AxServer) + +add_qt_gui_executable(simpleax + main.cpp +) +target_link_libraries(simpleax PUBLIC + Qt::AxServer + Qt::Core + Qt::Gui + Qt::Widgets +) + +install(TARGETS simpleax + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/activeqt/simpleqml/CMakeLists.txt b/examples/activeqt/simpleqml/CMakeLists.txt new file mode 100644 index 0000000..bc293ad --- /dev/null +++ b/examples/activeqt/simpleqml/CMakeLists.txt @@ -0,0 +1,54 @@ +# Generated from simpleqml.pro. + +cmake_minimum_required(VERSION 3.14) +project(simpleqmlax LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/activeqt/simpleqml") + +find_package(Qt6 COMPONENTS Core) +find_package(Qt6 COMPONENTS Gui) +find_package(Qt6 COMPONENTS Widgets) +find_package(Qt6 COMPONENTS AxServer) +find_package(Qt6 COMPONENTS Quick) +find_package(Qt6 COMPONENTS QuickWidgets) + +add_qt_gui_executable(simpleqmlax + main.cpp +) +target_link_libraries(simpleqmlax PUBLIC + Qt::AxServer + Qt::Core + Qt::Gui + Qt::Quick + Qt::QuickWidgets + Qt::Widgets +) + + +# Resources: +set(simpleqml_resource_files + "main.qml" +) + +qt6_add_resources(simpleqmlax "simpleqml" + PREFIX + "/" + FILES + ${simpleqml_resource_files} +) + +install(TARGETS simpleqmlax + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/activeqt/wrapper/CMakeLists.txt b/examples/activeqt/wrapper/CMakeLists.txt new file mode 100644 index 0000000..4a43092 --- /dev/null +++ b/examples/activeqt/wrapper/CMakeLists.txt @@ -0,0 +1,37 @@ +# Generated from wrapper.pro. + +cmake_minimum_required(VERSION 3.14) +project(wrapperax LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/activeqt/wrapper") + +find_package(Qt6 COMPONENTS Core) +find_package(Qt6 COMPONENTS Gui) +find_package(Qt6 COMPONENTS Widgets) +find_package(Qt6 COMPONENTS AxServer) + +add_qt_gui_executable(wrapperax + main.cpp +) +target_link_libraries(wrapperax PUBLIC + Qt::AxServer + Qt::Core + Qt::Gui + Qt::Widgets +) + +install(TARGETS wrapperax + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..f7e72c9 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,6 @@ +# Generated from src.pro. + +add_subdirectory(activeqt) +if(WIN32 AND NOT WINRT) + add_subdirectory(tools) +endif() diff --git a/src/activeqt/CMakeLists.txt b/src/activeqt/CMakeLists.txt new file mode 100644 index 0000000..13c5283 --- /dev/null +++ b/src/activeqt/CMakeLists.txt @@ -0,0 +1,17 @@ +# Generated from activeqt.pro. + +# special case begin +add_subdirectory(axbase) +add_subdirectory(control) +add_subdirectory(container) +# special case end +## Scopes: +##################################################################### + +#### Keys ignored in scope 2:.:.:activeqt.pro:WIN32 AND NOT WINRT: +# SUBDIRS = "axbase" "control" "container" "activeqt" +# TEMPLATE = "subdirs" +# activeqt.file = "activeqt.prx" + +#### Keys ignored in scope 3:.:.:activeqt.pro:else: +# TEMPLATE = "aux" diff --git a/src/activeqt/activeqt.pro b/src/activeqt/activeqt.pro index 36b3d64..0df9463 100644 --- a/src/activeqt/activeqt.pro +++ b/src/activeqt/activeqt.pro @@ -1,9 +1,9 @@ -win32:!winrt:!wince { +win32:!winrt { TEMPLATE = subdirs CONFIG += ordered - axshared.file = axshared.prx - SUBDIRS = axshared container control + activeqt.file = activeqt.prx + SUBDIRS = axbase control container activeqt } else { # fake project for creating the documentation message("ActiveQt is a Windows Desktop-only module. Will just generate a docs target.") diff --git a/src/activeqt/activeqt.prx b/src/activeqt/activeqt.prx new file mode 100644 index 0000000..86d4e36 --- /dev/null +++ b/src/activeqt/activeqt.prx @@ -0,0 +1,11 @@ +# Only headers here, no library is wanted. +TEMPLATE = subdirs +VERSION = $$MODULE_VERSION +MODULE_INCNAME = ActiveQt + +QMAKE_DOCS = $$PWD/doc/activeqt.qdocconf +QMAKE_DOCS_TARGETDIR = # Make qt_docs.prf default to activeqt instead of qtaxbase + +load(qt_module_headers) +load(qt_docs) +load(qt_installs) diff --git a/src/activeqt/axbase/CMakeLists.txt b/src/activeqt/axbase/CMakeLists.txt new file mode 100644 index 0000000..787d240 --- /dev/null +++ b/src/activeqt/axbase/CMakeLists.txt @@ -0,0 +1,36 @@ +# Generated from axbase.pro. + +##################################################################### +## AxBase Module: +##################################################################### + +qt_add_module(AxBase + STATIC + INTERNAL_MODULE + SOURCES + qaxtypefunctions.cpp qaxtypefunctions_p.h + qaxutils.cpp qaxutils_p.h + LIBRARIES + advapi32 + gdi32 + ole32 + oleaut32 + user32 + PUBLIC_LIBRARIES + Qt::Core + Qt::CorePrivate + Qt::Gui + Qt::GuiPrivate + Qt::Widgets +) + +#### Keys ignored in scope 1:.:.:axbase.pro:<TRUE>: +# MODULE = "axbase" + +## Scopes: +##################################################################### + +qt_extend_target(AxBase CONDITION MINGW + LIBRARIES + uuid +) diff --git a/src/activeqt/axbase/axbase.pro b/src/activeqt/axbase/axbase.pro new file mode 100644 index 0000000..2c53614 --- /dev/null +++ b/src/activeqt/axbase/axbase.pro @@ -0,0 +1,18 @@ +TARGET = QtAxBase +MODULE = axbase + +QT += core-private gui-private widgets +CONFIG += static internal_module + +load(qt_module) + +LIBS_PRIVATE += -lole32 -loleaut32 -luser32 -lgdi32 -ladvapi32 +mingw: LIBS_PRIVATE += -luuid + +HEADERS = \ + qaxtypefunctions_p.h \ + qaxutils_p.h + +SOURCES = \ + qaxtypefunctions.cpp \ + qaxutils.cpp diff --git a/src/activeqt/shared/qaxtypefunctions.cpp b/src/activeqt/axbase/qaxtypefunctions.cpp index db54ecb..c1b76f5 100644 --- a/src/activeqt/shared/qaxtypefunctions.cpp +++ b/src/activeqt/axbase/qaxtypefunctions.cpp @@ -49,7 +49,7 @@ ****************************************************************************/ #include <qt_windows.h> -#include "qaxtypefunctions.h" +#include "qaxtypefunctions_p.h" #include <qcursor.h> #include <qpixmap.h> #include <qsize.h> diff --git a/src/activeqt/shared/qaxtypefunctions.h b/src/activeqt/axbase/qaxtypefunctions_p.h index 13a6eaa..7ce9067 100644 --- a/src/activeqt/shared/qaxtypefunctions.h +++ b/src/activeqt/axbase/qaxtypefunctions_p.h @@ -47,9 +47,21 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + #ifndef QAXTYPEFUNCTIONS_P_H #define QAXTYPEFUNCTIONS_P_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + #include <QtCore/qt_windows.h> #include <QtGui/qcolor.h> diff --git a/src/activeqt/shared/qaxutils.cpp b/src/activeqt/axbase/qaxutils.cpp index 3514558..3514558 100644 --- a/src/activeqt/shared/qaxutils.cpp +++ b/src/activeqt/axbase/qaxutils.cpp diff --git a/src/activeqt/shared/qaxutils_p.h b/src/activeqt/axbase/qaxutils_p.h index f56644b..f56644b 100644 --- a/src/activeqt/shared/qaxutils_p.h +++ b/src/activeqt/axbase/qaxutils_p.h diff --git a/src/activeqt/axshared.prx b/src/activeqt/axshared.prx deleted file mode 100644 index 6d335e9..0000000 --- a/src/activeqt/axshared.prx +++ /dev/null @@ -1,23 +0,0 @@ -# This modules provides the header files, installed under "ActiveQt/". -# It also contains shared code that is used by axcontainer and axserver. - -TARGET = QtAxBase -QMAKE_DOCS = $$PWD/doc/activeqt.qdocconf -MODULE_INCNAME = ActiveQt -CONFIG += static -QT += gui-private widgets - -LIBS_PRIVATE += -lole32 -loleaut32 -luser32 -lgdi32 -ladvapi32 -mingw: LIBS_PRIVATE += -luuid - -HEADERS = \ - shared/qaxtypefunctions.h \ - shared/qaxutils_p.h - -SOURCES = \ - shared/qaxtypefunctions.cpp \ - shared/qaxutils.cpp - -MODULE = axbase -load(qt_module) -QMAKE_DOCS_TARGETDIR = # Make qt_docs.prf default to activeqt instead of qtaxbase diff --git a/src/activeqt/container/CMakeLists.txt b/src/activeqt/container/CMakeLists.txt new file mode 100644 index 0000000..f9b72b4 --- /dev/null +++ b/src/activeqt/container/CMakeLists.txt @@ -0,0 +1,35 @@ +# Generated from container.pro. + +##################################################################### +## AxContainer Module: +##################################################################### + +qt_add_module(AxContainer + STATIC + QMAKE_MODULE_CONFIG dumpcpp + SOURCES + ../control/qaxaggregated.h + ../shared/qaxtypes.cpp ../shared/qaxtypes_p.h + qaxbase.cpp qaxbase.h qaxbase_p.h + qaxdump.cpp + qaxobject.cpp qaxobject.h + qaxscript.cpp qaxscript.h + qaxscriptwrapper.cpp + qaxselect.cpp qaxselect.h qaxselect.ui + qaxwidget.cpp qaxwidget.h + LIBRARIES + Qt::AxBasePrivate + Qt::CorePrivate + Qt::GuiPrivate + Qt::WidgetsPrivate + PUBLIC_LIBRARIES + Qt::Core + Qt::Gui + Qt::Widgets + ENABLE_AUTOGEN_TOOLS + uic +) + +#### Keys ignored in scope 1:.:.:container.pro:<TRUE>: +# MODULE = "axcontainer" +# MODULE_CONFIG = "dumpcpp" diff --git a/src/activeqt/container/container.pro b/src/activeqt/container/container.pro index 4bfeb34..3606e87 100644 --- a/src/activeqt/container/container.pro +++ b/src/activeqt/container/container.pro @@ -1,16 +1,17 @@ TARGET = QtAxContainer -QT += core-private gui gui-private widgets widgets-private axbase +QT += widgets +QT_PRIVATE += core-private gui-private widgets-private axbase-private CONFIG += static HEADERS = ../control/qaxaggregated.h \ qaxbase.h \ + qaxbase_p.h \ qaxwidget.h \ qaxobject.h \ qaxscript.h \ qaxselect.h \ - ../shared/qaxtypes.h \ - ../shared/qaxutils_p.h + ../shared/qaxtypes_p.h SOURCES = qaxbase.cpp \ qaxdump.cpp \ @@ -19,14 +20,10 @@ SOURCES = qaxbase.cpp \ qaxscript.cpp \ qaxscriptwrapper.cpp \ qaxselect.cpp \ - ../shared/qaxtypes.cpp \ - ../shared/qaxutils.cpp + ../shared/qaxtypes.cpp FORMS = qaxselect.ui MODULE = axcontainer MODULE_CONFIG = dumpcpp -MODULE_MASTER_HEADER = ActiveQt -CONFIG += no_module_headers load(qt_module) -DEFINES -= QT_NO_CAST_TO_ASCII QT_USE_QSTRINGBUILDER diff --git a/src/activeqt/container/qaxbase.cpp b/src/activeqt/container/qaxbase.cpp index 42ccffc..53fbe81 100644 --- a/src/activeqt/container/qaxbase.cpp +++ b/src/activeqt/container/qaxbase.cpp @@ -53,6 +53,9 @@ #define QT_CHECK_STATE #include "qaxobject.h" +#include "qaxbase_p.h" + +#include <QtAxBase/private/qaxtypefunctions_p.h> #include <qfile.h> #include <qwidget.h> @@ -79,8 +82,8 @@ #include <ocidl.h> #include <ctype.h> -#include "../shared/qaxtypes.h" -#include "../shared/qaxutils_p.h" +#include "../shared/qaxtypes_p.h" +#include <QtAxBase/private/qaxutils_p.h> QT_BEGIN_NAMESPACE @@ -121,45 +124,46 @@ static inline HRESULT Invoke(IDispatch *disp, \brief The QAxMetaObject class stores extended information */ -struct QAxMetaObject : public QMetaObject +class QMetaObjectExtra { - QAxMetaObject() - { - d.data = nullptr; - d.stringdata = nullptr; - } - ~QAxMetaObject() - { - delete [] d.data; - delete [] reinterpret_cast<char *>(const_cast<QByteArrayData *>(d.stringdata)); - } +public: + using DispIdNameMapping = QMap<DISPID, QByteArray>; + using UuidDispIdMapping = QMap< QUuid, QMap<DISPID, QByteArray> >; - int numParameter(const QByteArray &prototype); - QByteArray paramType(const QByteArray &signature, int index, bool *out = nullptr); - QByteArray propertyType(const QByteArray &propertyName); - void parsePrototype(const QByteArray &prototype); - DISPID dispIDofName(const QByteArray &name, IDispatch *disp); + QMetaObjectExtra() = default; + + int numParameter(const QByteArray &prototype) const; + QByteArray paramType(const QByteArray &signature, int index, bool *out = nullptr) const; + QByteArray propertyType(const QByteArray &propertyName) const; + void parsePrototype(const QByteArray &prototype) const; + DISPID dispIDofName(const QByteArray &name, IDispatch *disp) const; + + const QVector<QUuid> &connectionInterfaces() const { return m_connectionInterfaces; } + + const UuidDispIdMapping &sigs() const { return m_sigs; } + const UuidDispIdMapping &propsigs() const { return m_propsigs; } + const UuidDispIdMapping &props() const { return m_props; } private: friend class MetaObjectGenerator; // save information about QAxEventSink connections, and connect when found in cache - QVector<QUuid> connectionInterfaces; + QVector<QUuid> m_connectionInterfaces; // DISPID -> signal name - QMap< QUuid, QMap<DISPID, QByteArray> > sigs; + UuidDispIdMapping m_sigs; // DISPID -> property changed signal name - QMap< QUuid, QMap<DISPID, QByteArray> > propsigs; + UuidDispIdMapping m_propsigs; // DISPID -> property name - QMap< QUuid, QMap<DISPID, QByteArray> > props; + UuidDispIdMapping m_props; // Prototype -> member info - QHash<QByteArray, QByteArrayList> memberInfo; + mutable QHash<QByteArray, QByteArrayList> memberInfo; QMap<QByteArray, QByteArray> realPrototype; // DISPID cache - QHash<QByteArray, DISPID> dispIDs; + mutable QHash<QByteArray, DISPID> dispIDs; }; -void QAxMetaObject::parsePrototype(const QByteArray &prototype) +void QMetaObjectExtra::parsePrototype(const QByteArray &prototype) const { QByteArray realProto = realPrototype.value(prototype, prototype); QByteArray parameters = realProto.mid(realProto.indexOf('(') + 1); @@ -171,12 +175,12 @@ void QAxMetaObject::parsePrototype(const QByteArray &prototype) memberInfo.insert(prototype, parameters.split(',')); } -inline QByteArray QAxMetaObject::propertyType(const QByteArray &propertyName) +inline QByteArray QMetaObjectExtra::propertyType(const QByteArray &propertyName) const { return realPrototype.value(propertyName); } -int QAxMetaObject::numParameter(const QByteArray &prototype) +int QMetaObjectExtra::numParameter(const QByteArray &prototype) const { if (!memberInfo.contains(prototype)) parsePrototype(prototype); @@ -184,7 +188,7 @@ int QAxMetaObject::numParameter(const QByteArray &prototype) return memberInfo.value(prototype).count(); } -QByteArray QAxMetaObject::paramType(const QByteArray &prototype, int index, bool *out) +QByteArray QMetaObjectExtra::paramType(const QByteArray &prototype, int index, bool *out) const { if (!memberInfo.contains(prototype)) parsePrototype(prototype); @@ -210,7 +214,7 @@ QByteArray QAxMetaObject::paramType(const QByteArray &prototype, int index, bool return param; } -inline DISPID QAxMetaObject::dispIDofName(const QByteArray &name, IDispatch *disp) +inline DISPID QMetaObjectExtra::dispIDofName(const QByteArray &name, IDispatch *disp) const { DISPID dispid = dispIDs.value(name, DISPID_UNKNOWN); if (dispid == DISPID_UNKNOWN) { @@ -225,7 +229,8 @@ inline DISPID QAxMetaObject::dispIDofName(const QByteArray &name, IDispatch *dis } -static QHash<QString, QAxMetaObject*> mo_cache; +static QHash<QString, QMetaObject*> mo_cache; +static QHash<const QMetaObject*, QMetaObjectExtra> moextra_cache; static QHash<QUuid, QMap<QByteArray, QList<QPair<QByteArray, int> > > > enum_cache; static int mo_cache_ref = 0; static QMutex cache_mutex; @@ -382,8 +387,8 @@ public: if (qobject->signalsBlocked()) return S_OK; - QAxMetaObject *axmeta = combase->internalMetaObject(); const QMetaObject *meta = combase->metaObject(); + const QMetaObjectExtra &moExtra = moextra_cache.value(meta); int index = -1; // emit the generic signal "as is" @@ -408,7 +413,7 @@ public: Q_ASSERT(signal.methodType() == QMetaMethod::Signal); Q_ASSERT(signame == signal.methodSignature()); // verify parameter count - const int pcount = axmeta->numParameter(signame); + const int pcount = moExtra.numParameter(signame); const int argcount = int(pDispParams->cArgs); if (pcount > argcount) return DISP_E_PARAMNOTOPTIONAL; @@ -443,7 +448,7 @@ public: int p; for (p = 0; p < pcount && ok; ++p) { // map the VARIANT to the void* - QByteArray ptype = axmeta->paramType(signame, p); + QByteArray ptype = moExtra.paramType(signame, p); varp[p + 1] = VARIANTToQVariant(pDispParams->rgvarg[pcount - p - 1], ptype); argv_pointer[p + 1] = nullptr; if (varp[p + 1].isValid()) { @@ -471,7 +476,7 @@ public: // update the VARIANT for references and free memory for (p = 0; p < pcount; ++p) { bool out; - QByteArray ptype = axmeta->paramType(signame, p, &out); + QByteArray ptype = moExtra.paramType(signame, p, &out); if (out) { if (!QVariantToVARIANT(varp[p + 1], pDispParams->rgvarg[pcount - p - 1], ptype, out)) ok = false; @@ -530,8 +535,6 @@ public: // get the signal information from the metaobject if (signalHasReceivers(qobject, signame)) { - index = meta->indexOfSignal(signame); - Q_ASSERT(index != -1); // setup parameters QVariant var = qobject->property(propname); if (!var.isValid()) @@ -563,7 +566,8 @@ public: static bool signalHasReceivers(QObject *qobject, const char *signalName) { Q_ASSERT(qobject); - return static_cast<QAxObject *>(qobject)->receivers(QByteArray::number(QSIGNAL_CODE) + signalName); + const QByteArray name = QByteArray::number(QSIGNAL_CODE) + signalName; + return static_cast<QAxObject *>(qobject)->receivers(name.constData()) > 0; } IConnectionPoint *cpoint = nullptr; @@ -583,76 +587,32 @@ public: \class QAxBasePrivate */ -class QAxBasePrivate +QAxBasePrivate::QAxBasePrivate(QAxBase *b) + : q(b), useEventSink(true), useMetaObject(true), useClassInfo(true), + cachedMetaObject(false), initialized(false), tryCache(false) { - Q_DISABLE_COPY_MOVE(QAxBasePrivate) -public: - using UuidEventSinkHash = QHash<QUuid, QAxEventSink*>; - - QAxBasePrivate() - : useEventSink(true), useMetaObject(true), useClassInfo(true), - cachedMetaObject(false), initialized(false), tryCache(false) - { - // protect initialization - QMutexLocker locker(&cache_mutex); - mo_cache_ref++; - - qRegisterMetaType<IUnknown*>("IUnknown*", &ptr); - qRegisterMetaType<IDispatch*>("IDispatch*", &disp); - } - - ~QAxBasePrivate() - { - Q_ASSERT(!ptr); - Q_ASSERT(!disp); - - // protect cleanup - QMutexLocker locker(&cache_mutex); - if (!--mo_cache_ref) { - qDeleteAll(mo_cache); - mo_cache.clear(); - } - - CoFreeUnusedLibraries(); - } - - inline IDispatch *dispatch() const - { - if (disp) - return disp; - - if (ptr) - ptr->QueryInterface(IID_IDispatch, reinterpret_cast<void **>(&disp)); - return disp; - } - - QString ctrl; - UuidEventSinkHash eventSink; - uint useEventSink :1; - uint useMetaObject :1; - uint useClassInfo :1; - uint cachedMetaObject :1; - uint initialized :1; - uint tryCache :1; - unsigned long classContext = CLSCTX_SERVER; + // protect initialization + QMutexLocker locker(&cache_mutex); + mo_cache_ref++; - IUnknown *ptr = nullptr; - mutable IDispatch *disp = nullptr; + qRegisterMetaType<IUnknown*>("IUnknown*", &ptr); + qRegisterMetaType<IDispatch*>("IDispatch*", &disp); +} - QMap<QByteArray, bool> propWritable; +QAxBasePrivate::~QAxBasePrivate() +{ + Q_ASSERT(!ptr); + Q_ASSERT(!disp); - inline QAxMetaObject *metaObject() - { - if (!metaobj) - metaobj = new QAxMetaObject; - return metaobj; + // protect cleanup + QMutexLocker locker(&cache_mutex); + if (!--mo_cache_ref) { + qDeleteAll(mo_cache); + mo_cache.clear(); } - mutable QMap<QString, LONG> verbs; - - QAxMetaObject *metaobj = nullptr; -}; - + CoFreeUnusedLibraries(); +} QByteArray QAxEventSink::findProperty(DISPID dispID) { @@ -687,6 +647,11 @@ QByteArray QAxEventSink::findProperty(DISPID dispID) return propname; } +QVariant QAxBasePrivate::VARIANTToQVariant(const VARIANT &arg, const QByteArray &typeName, uint type) +{ + return ::VARIANTToQVariant(arg, typeName, type); +} + /*! \class QAxBase \brief The QAxBase class is an abstract class that provides an API @@ -879,7 +844,7 @@ QByteArray QAxEventSink::findProperty(DISPID dispID) */ QAxBase::QAxBase(IUnknown *iface) { - d = new QAxBasePrivate(); + d = new QAxBasePrivate(this); d->ptr = iface; if (d->ptr) { d->ptr->AddRef(); @@ -929,12 +894,6 @@ void QAxBase::initializeFrom(QAxBase *that) } } - -QAxMetaObject *QAxBase::internalMetaObject() const -{ - return d->metaObject(); -} - /*! \property QAxBase::control \brief the name of the COM object wrapped by this QAxBase object. @@ -1554,7 +1513,7 @@ public: void readEventInfo(); void readEventInterface(ITypeInfo *eventinfo, IConnectionPoint *cpoint); - inline void addClassInfo(const char *key, const char *value) + inline void addClassInfo(const QByteArray &key, const QByteArray &value) { classinfo_list.insert(key, value); } @@ -1641,7 +1600,7 @@ private: struct Method { QByteArray type; QByteArray parameters; - int flags = 0; + int attributes = 0; QByteArray realPrototype; }; QMap<QByteArray, Method> signal_list; @@ -1652,7 +1611,6 @@ private: Method &signal = signal_list[proto]; signal.type = "void"; signal.parameters = parameters; - signal.flags = QMetaMethod::Public | MethodSignal; if (proto != prototype) signal.realPrototype = prototype; } @@ -1665,7 +1623,8 @@ private: } QMap<QByteArray, Method> slot_list; - inline void addSlot(const QByteArray &type, const QByteArray &prototype, const QByteArray ¶meters, int flags = QMetaMethod::Public) + inline void addSlot(const QByteArray &type, const QByteArray &prototype, const QByteArray ¶meters, + int attributes = 0) { QByteArray proto = replacePrototype(prototype); @@ -1673,7 +1632,7 @@ private: slot.type = replaceType(type); slot.parameters = parameters; - slot.flags = flags | MethodSlot; + slot.attributes = attributes; if (proto != prototype) slot.realPrototype = prototype; } @@ -1734,6 +1693,19 @@ private: return enum_list.contains(enumname); } + using BuilderMethodCreationFunc = QMetaMethodBuilder (QMetaObjectBuilder::*)(const QByteArray &); + + static void addMetaMethod(QMetaObjectBuilder &builder, + BuilderMethodCreationFunc creationFunc, + const QByteArray &name, + const QByteArray ¶meters, + const QByteArray &returnType = QByteArray(), + int attributes = 0); + static void buildMethods(const QMap<QByteArray, Method> &list, + QMetaObjectExtra &moExtra, + QMetaObjectBuilder &builder, + BuilderMethodCreationFunc creationFunc); + QAxBase *that = nullptr; QAxBasePrivate *d = nullptr; @@ -1782,9 +1754,6 @@ QMetaObject *qax_readInterfaceInfo(ITypeLib *typeLib, ITypeInfo *typeInfo, const QMetaObject *qax_readClassInfo(ITypeLib *typeLib, ITypeInfo *classInfo, const QMetaObject *parentObject) { MetaObjectGenerator generator(typeLib, nullptr); - generator.addSignal("exception(int,QString,QString,QString)", "code,source,disc,help"); - generator.addSignal("propertyChanged(QString)", "name"); - QString className; BSTR bstr; if (S_OK != classInfo->GetDocumentation(-1, &bstr, nullptr, nullptr, nullptr)) @@ -1848,7 +1817,7 @@ QMetaObject *qax_readClassInfo(ITypeLib *typeLib, ITypeInfo *classInfo, const QM void qax_deleteMetaObject(QMetaObject *metaObject) { - delete static_cast<QAxMetaObject *>(metaObject); + free(metaObject); // Result of QMetaObjectBuilder::toMetaObject() needs free() } MetaObjectGenerator::MetaObjectGenerator(QAxBase *ax, QAxBasePrivate *dptr) @@ -1882,13 +1851,6 @@ void MetaObjectGenerator::init() disp = d->dispatch(); iid_propNotifySink = IID_IPropertyNotifySink; - - addSignal("signal(QString,int,void*)", "name,argc,argv"); - addSignal("exception(int,QString,QString,QString)", "code,source,disc,help"); - addSignal("propertyChanged(QString)", "name"); - if (d || dispInfo) { - addProperty("QString", "control", Readable|Writable|Designable|Scriptable|Stored|Editable|StdCppSet); - } } MetaObjectGenerator::~MetaObjectGenerator() @@ -2598,11 +2560,11 @@ void MetaObjectGenerator::readFuncsInfo(ITypeInfo *typeinfo, ushort nFuncs) pnames += ','; } defargs = pnames.contains("=0"); - int flags = QMetaMethod::Public; + int attributes = 0; if (cloned) - flags |= QMetaMethod::Cloned << 4; + attributes |= QMetaMethod::Cloned; cloned |= defargs; - addSlot(type, prototype, pnames.replace("=0", ""), flags); + addSlot(type, prototype, pnames.replace("=0", ""), attributes); if (defargs) { parameters.takeLast(); @@ -2954,20 +2916,21 @@ QMetaObject *MetaObjectGenerator::tryCache() d->metaobj = mo_cache.value(cacheKey); if (d->metaobj) { d->cachedMetaObject = true; + const QMetaObjectExtra &moExtra = moextra_cache.value(d->metaobj); IConnectionPointContainer *cpoints = nullptr; d->ptr->QueryInterface(IID_IConnectionPointContainer, reinterpret_cast<void **>(&cpoints)); if (cpoints) { - for (const QUuid &iid : qAsConst(d->metaobj->connectionInterfaces)) { + for (const QUuid &iid : moExtra.connectionInterfaces()) { IConnectionPoint *cpoint = nullptr; cpoints->FindConnectionPoint(iid, &cpoint); if (cpoint) { QAxEventSink *sink = new QAxEventSink(that); sink->advise(cpoint, iid); d->eventSink.insert(iid, sink); - sink->sigs = d->metaobj->sigs.value(iid); - sink->props = d->metaobj->props.value(iid); - sink->propsigs = d->metaobj->propsigs.value(iid); + sink->sigs = moExtra.sigs().value(iid); + sink->props = moExtra.props().value(iid); + sink->propsigs = moExtra.propsigs().value(iid); cpoint->Release(); } } @@ -2994,6 +2957,24 @@ static uint nameToTypeInfo(const QByteArray &typeName, QMetaStringTable &strings return uint(result); } +static void addMetaProperty(QMetaObjectBuilder &builder, const QByteArray &name, + const QByteArray &type, uint flags) +{ + QMetaPropertyBuilder propertyBuilder = builder.addProperty(name, type); + propertyBuilder.setReadable(flags & Readable); + propertyBuilder.setWritable(flags & Writable); + propertyBuilder.setResettable(flags & Resettable); + propertyBuilder.setEnumOrFlag(flags & EnumOrFlag); + propertyBuilder.setStdCppSet(flags & StdCppSet); + propertyBuilder.setConstant(flags & Constant); + propertyBuilder.setFinal(flags & Final); + propertyBuilder.setDesignable(flags & Designable); + propertyBuilder.setScriptable(flags & Scriptable); + propertyBuilder.setStored(flags & Stored); + propertyBuilder.setEditable(flags & Editable); + propertyBuilder.setUser(flags & User); +} + // Returns the sum of all parameters (including return type) for the given // \a map of methods. This is needed for calculating the size of the methods' // parameter type/name meta-data. @@ -3006,6 +2987,36 @@ int MetaObjectGenerator::aggregateParameterCount(const QMap<QByteArray, Method> return sum; } +void MetaObjectGenerator::addMetaMethod(QMetaObjectBuilder &builder, + BuilderMethodCreationFunc creationFunc, + const QByteArray &name, + const QByteArray ¶meters, + const QByteArray &returnType, + int attributes) +{ + QMetaMethodBuilder methodBuilder = (builder.*creationFunc)(name); + if (!parameters.isEmpty()) + methodBuilder.setParameterNames(parameters.split(',')); + if (!returnType.isEmpty() && returnType != QByteArrayLiteral("void")) + methodBuilder.setReturnType(returnType); + methodBuilder.setAttributes(attributes); +} + +void MetaObjectGenerator::buildMethods(const QMap<QByteArray, Method> &map, + QMetaObjectExtra &moExtra, + QMetaObjectBuilder &builder, + BuilderMethodCreationFunc creationFunc) +{ + for (auto it = map.constBegin(), end = map.constEnd(); it != end; ++it) { + QByteArray prototype(QMetaObject::normalizedSignature(it.key())); + const Method &method(it.value()); + if (!method.realPrototype.isEmpty()) + moExtra.realPrototype.insert(prototype, method.realPrototype); + addMetaMethod(builder, creationFunc, prototype, method.parameters, + method.type, method.attributes); + } +} + QMetaObject *MetaObjectGenerator::metaObject(const QMetaObject *parentObject, const QByteArray &className) { if (that) { @@ -3030,143 +3041,49 @@ QMetaObject *MetaObjectGenerator::metaObject(const QMetaObject *parentObject, co addClassInfo("debugInfo", debugInfo); #endif - QAxMetaObject *metaobj = new QAxMetaObject; - - int paramsDataSize = - ((aggregateParameterCount(signal_list) - + aggregateParameterCount(slot_list)) * 2) // types and parameter names - - signal_list.count() // return "parameters" don't have names - - slot_list.count(); // ditto - - int int_data_size = MetaObjectPrivateFieldCount; - int_data_size += classinfo_list.count() * 2; - int_data_size += (signal_list.count() + slot_list.count()) * 5 + paramsDataSize; - int_data_size += property_list.count() * 3; - int_data_size += enum_list.count() * 5; - for (auto it = enum_list.cbegin(), end = enum_list.cend(); it != end; ++it) - int_data_size += it.value().count() * 2; - ++int_data_size; // eod - - uint *int_data = new uint[int_data_size]; - QMetaObjectPrivate *header = reinterpret_cast<QMetaObjectPrivate *>(int_data); - Q_STATIC_ASSERT_X(QMetaObjectPrivate::OutputRevision == 8, "QtDBus meta-object generator should generate the same version as moc"); - header->revision = QMetaObjectPrivate::OutputRevision; - header->className = 0; - header->classInfoCount = classinfo_list.count(); - header->classInfoData = MetaObjectPrivateFieldCount; - header->methodCount = signal_list.count() + slot_list.count(); - header->methodData = header->classInfoData + header->classInfoCount * 2; - header->propertyCount = property_list.count(); - header->propertyData = header->methodData + header->methodCount * 5 + paramsDataSize; - header->enumeratorCount = enum_list.count(); - header->enumeratorData = header->propertyData + header->propertyCount * 3; - header->constructorCount = 0; - header->constructorData = 0; - header->flags = 0; - header->signalCount = signal_list.count(); - - QByteArray classNameForMetaObject = className; - if (that) - classNameForMetaObject = that->className(); - QMetaStringTable strings(classNameForMetaObject); - - int offset = header->classInfoData; - - // each class info in form key\0value\0 - for (auto it = classinfo_list.cbegin(), cend = classinfo_list.cend(); it != cend; ++it) { - int_data[offset++] = uint(strings.enter(it.key())); - int_data[offset++] = uint(strings.enter(it.value())); - } - Q_ASSERT(offset == header->methodData); - - int paramsOffset = offset + header->methodCount * 5; - // add each method: - for (int x = 0; x < 2; ++x) { - // Signals must be added before other methods, to match moc. - const QMap<QByteArray, Method> &map = (x == 0) ? signal_list : slot_list; - for (QMap<QByteArray, Method>::ConstIterator it = map.constBegin(); it != map.constEnd(); ++it) { - QByteArray prototype(QMetaObject::normalizedSignature(it.key())); - QByteArray name = prototype.left(prototype.indexOf('(')); - const auto paramTypeNames = paramList(prototype); - const QByteArrayList paramNames = it.value().parameters.isEmpty() - ? QByteArrayList() : it.value().parameters.split(','); - Q_ASSERT(paramTypeNames.size() == paramNames.size()); - if (!it.value().realPrototype.isEmpty()) - metaobj->realPrototype.insert(prototype, it.value().realPrototype); - int argc = paramTypeNames.size(); - QByteArray tag; - int_data[offset++] = uint(strings.enter(name)); - int_data[offset++] = uint(argc); - int_data[offset++] = uint(paramsOffset); - int_data[offset++] = uint(strings.enter(tag)); - int_data[offset++] = uint(it.value().flags); - - // Parameter types - for (int i = -1; i < argc; ++i) { - QByteArray typeName = (i < 0) ? it.value().type : paramTypeNames.at(i); - int_data[paramsOffset++] = nameToTypeInfo(typeName, strings); - } - // Parameter names - for (int i = 0; i < argc; ++i) - int_data[paramsOffset++] = uint(strings.enter(paramNames.at(i))); - } - } - Q_ASSERT(offset == header->methodData + header->methodCount * 5); - Q_ASSERT(paramsOffset = header->propertyData); - offset += paramsDataSize; - Q_ASSERT(offset == header->propertyData); - - // each property in form name\0type\0 + QMetaObjectExtra moExtra; + + if (parentObject == nullptr) + parentObject = &QObject::staticMetaObject; + QMetaObjectBuilder builder(parentObject, {} /* Don't add anything from prototype */); + builder.setSuperClass(parentObject); + builder.setClassName(that ? QByteArray(that->className()) : className); + + // each class info + for (auto it = classinfo_list.cbegin(), cend = classinfo_list.cend(); it != cend; ++it) + builder.addClassInfo(it.key(), it.value()); + + // add each method. Signals must be added before other methods, to match moc. + addMetaMethod(builder, &QMetaObjectBuilder::addSignal, + "exception(int,QString,QString,QString)", "code,source,desc,help"); + addMetaMethod(builder, &QMetaObjectBuilder::addSignal, + "propertyChanged(QString)", "name"); + addMetaMethod(builder, &QMetaObjectBuilder::addSignal, + "signal(QString,int,void*)", "name,argc,argv"); + buildMethods(signal_list, moExtra, builder, &QMetaObjectBuilder::addSignal); + buildMethods(slot_list, moExtra, builder, &QMetaObjectBuilder::addSlot); + + // each property + addMetaProperty(builder, "control", "QString", + Readable | Writable | Designable | Scriptable | Stored | Editable | StdCppSet); for (auto it = property_list.cbegin(), end = property_list.cend(); it != end; ++it) { const QByteArray &name = it.key(); const QByteArray &type = it.value().type; Q_ASSERT(!type.isEmpty()); QByteArray realType(it.value().realType); if (!realType.isEmpty() && realType != type) - metaobj->realPrototype.insert(name, realType); - int_data[offset++] = uint(strings.enter(name)); - int_data[offset++] = nameToTypeInfo(type, strings); - int_data[offset++] = uint(it.value().flags); + moExtra.realPrototype.insert(name, realType); + addMetaProperty(builder, name, type, it.value().flags); } - Q_ASSERT(offset == header->enumeratorData); - int value_offset = offset + enum_list.count() * 5; // each enum in form name\0 for (auto it = enum_list.cbegin(), end = enum_list.cend(); it != end; ++it) { - QByteArray name(it.key()); - int count = it.value().count(); - - uint nameId = uint(strings.enter(name)); - int_data[offset++] = nameId; - int_data[offset++] = nameId; - int_data[offset++] = 0x0; // 0x1 for flag? - int_data[offset++] = uint(count); - int_data[offset++] = uint(value_offset); - value_offset += count * 2; + QMetaEnumBuilder enumBuilder = builder.addEnumerator(it.key()); + for (auto v : it.value()) + enumBuilder.addKey(v.first, v.second); } - Q_ASSERT(offset == header->enumeratorData + enum_list.count() * 5); - - // each enum value in form key\0 - for (auto it = enum_list.cbegin(), end = enum_list.cend(); it != end; ++it) { - for (const auto &e : it.value()) { - int_data[offset++] = uint(strings.enter(e.first)); - int_data[offset++] = uint(e.second); - } - } - Q_ASSERT(offset == int_data_size-1); - int_data[offset] = 0; // eod - - char *string_data = new char[strings.blobSize()]; - strings.writeBlob(string_data); - - // put the metaobject together - metaobj->d.data = int_data; - metaobj->d.extradata = nullptr; - metaobj->d.stringdata = reinterpret_cast<const QByteArrayData *>(string_data); - metaobj->d.static_metacall = nullptr; - metaobj->d.relatedMetaObjects = nullptr; - metaobj->d.superdata = parentObject; + auto metaobj = builder.toMetaObject(); if (d) d->metaobj = metaobj; @@ -3177,37 +3094,36 @@ QMetaObject *MetaObjectGenerator::metaObject(const QMetaObject *parentObject, co if (QAxEventSink *sink = it.value()) { QUuid ciid = sink->connectionInterface(); - d->metaobj->connectionInterfaces.append(ciid); - d->metaobj->sigs.insert(ciid, sink->signalMap()); - d->metaobj->props.insert(ciid, sink->propertyMap()); - d->metaobj->propsigs.insert(ciid, sink->propSignalMap()); + moExtra.m_connectionInterfaces.append(ciid); + moExtra.m_sigs.insert(ciid, sink->signalMap()); + moExtra.m_props.insert(ciid, sink->propertyMap()); + moExtra.m_propsigs.insert(ciid, sink->propSignalMap()); } } + moextra_cache.insert(d->metaobj, moExtra); } return metaobj; } -#define QT_MOC_LITERAL(idx, ofs, len) { \ - Q_REFCOUNT_INITIALIZE_STATIC, len, 0, 0, \ - offsetof(qt_meta_stringdata_QAxBase_t, stringdata) + ofs \ - - idx * sizeof(QByteArrayData) \ - } +#define QT_MOC_LITERAL(ofs, len) \ + uint(offsetof(qt_meta_stringdata_QAxBase_t, stringdata) + ofs), len + const QAxBase::qt_meta_stringdata_QAxBase_t QAxBase::qt_meta_stringdata_QAxBase = { { -QT_MOC_LITERAL(0, 0, 7), -QT_MOC_LITERAL(1, 8, 6), -QT_MOC_LITERAL(2, 15, 0), -QT_MOC_LITERAL(3, 16, 4), -QT_MOC_LITERAL(4, 21, 4), -QT_MOC_LITERAL(5, 26, 4), -QT_MOC_LITERAL(6, 31, 15), -QT_MOC_LITERAL(7, 47, 9), -QT_MOC_LITERAL(8, 57, 4), -QT_MOC_LITERAL(9, 62, 6), -QT_MOC_LITERAL(10, 69, 4), -QT_MOC_LITERAL(11, 74, 4), -QT_MOC_LITERAL(12, 79, 7) +QT_MOC_LITERAL(0, 7), +QT_MOC_LITERAL(8, 6), +QT_MOC_LITERAL(15, 0), +QT_MOC_LITERAL(16, 4), +QT_MOC_LITERAL(21, 4), +QT_MOC_LITERAL(26, 4), +QT_MOC_LITERAL(31, 15), +QT_MOC_LITERAL(47, 9), +QT_MOC_LITERAL(57, 4), +QT_MOC_LITERAL(62, 6), +QT_MOC_LITERAL(69, 4), +QT_MOC_LITERAL(74, 4), +QT_MOC_LITERAL(79, 7) }, "QAxBase\0signal\0\0name\0argc\0argv\0" "propertyChanged\0exception\0code\0source\0" @@ -3404,80 +3320,87 @@ void QAxBase::connectNotify() or use it in e.g. a QTextBrowser widget. */ -static bool checkHRESULT(HRESULT hres, EXCEPINFO *exc, QAxBase *that, const QString &name, uint argerr) +void QAxBasePrivate::handleException(tagEXCEPINFO *exc, const QString &name) +{ + const QMetaObject *mo = metaObject(); + const int exceptionSignal = mo->indexOfSignal("exception(int,QString,QString,QString)"); + if (exc->pfnDeferredFillIn) + exc->pfnDeferredFillIn(exc); + int code = exc->wCode ? exc->wCode : exc->scode; + QString source = QString::fromWCharArray(exc->bstrSource); + QString desc = QString::fromWCharArray(exc->bstrDescription); + QString help = QString::fromWCharArray(exc->bstrHelpFile); + const uint helpContext = exc->dwHelpContext; + if (helpContext && !help.isEmpty()) + help += QString::fromLatin1(" [%1]").arg(helpContext); + + if (QAxEventSink::signalHasReceivers(q->qObject(), "exception(int,QString,QString,QString)")) { + void *argv[] = {nullptr, &code, &source, &desc, &help}; + QAxBase::qt_static_metacall(q, QMetaObject::InvokeMetaMethod, + exceptionSignal - mo->methodOffset(), argv); + } else { + qWarning(R"(QAxBase: Error calling IDispatch member %s: Exception thrown by server + Code : %d + Source : %s + Description: %s + Help : %s + Connect to the exception(int,QString,QString,QString) signal to catch this exception)", + qPrintable(name), code, qPrintable(source), qPrintable(desc), + qPrintable(help)); + } +} + +bool QAxBasePrivate::checkHRESULT(HRESULT hres, EXCEPINFO *exc, const QString &name, uint argerr) { switch(hres) { case S_OK: return true; case DISP_E_BADPARAMCOUNT: - qWarning("QAxBase: Error calling IDispatch member %s: Bad parameter count", name.toLatin1().data()); + qWarning("QAxBase: Error calling IDispatch member %s: Bad parameter count", + qPrintable(name)); return false; case DISP_E_BADVARTYPE: - qWarning("QAxBase: Error calling IDispatch member %s: Bad variant type", name.toLatin1().data()); + qWarning("QAxBase: Error calling IDispatch member %s: Bad variant type", + qPrintable(name)); return false; case DISP_E_EXCEPTION: - { - bool printWarning = true; - unsigned int code = uint(-1); - QString source, desc, help; - const QMetaObject *mo = that->metaObject(); - int exceptionSignal = mo->indexOfSignal("exception(int,QString,QString,QString)"); - if (exceptionSignal >= 0) { - if (exc->pfnDeferredFillIn) - exc->pfnDeferredFillIn(exc); - - code = exc->wCode ? exc->wCode : exc->scode; - source = QString::fromWCharArray(exc->bstrSource); - desc = QString::fromWCharArray(exc->bstrDescription); - help = QString::fromWCharArray(exc->bstrHelpFile); - uint helpContext = exc->dwHelpContext; - - if (helpContext && !help.isEmpty()) - help += QString::fromLatin1(" [%1]").arg(helpContext); - - if (QAxEventSink::signalHasReceivers(that->qObject(), "exception(int,QString,QString,QString)")) { - void *argv[] = {nullptr, &code, &source, &desc, &help}; - QAxBase::qt_static_metacall(that, QMetaObject::InvokeMetaMethod, - exceptionSignal - mo->methodOffset(), argv); - printWarning = false; - } - } - if (printWarning) { - qWarning("QAxBase: Error calling IDispatch member %s: Exception thrown by server", name.toLatin1().data()); - qWarning(" Code : %d", code); - qWarning(" Source : %s", source.toLatin1().data()); - qWarning(" Description: %s", desc.toLatin1().data()); - qWarning(" Help : %s", help.toLatin1().data()); - qWarning(" Connect to the exception(int,QString,QString,QString) signal to catch this exception"); - } - } + handleException(exc, name); return false; case DISP_E_MEMBERNOTFOUND: - qWarning("QAxBase: Error calling IDispatch member %s: Member not found", name.toLatin1().data()); + qWarning("QAxBase: Error calling IDispatch member %s: Member not found", + qPrintable(name)); return false; case DISP_E_NONAMEDARGS: - qWarning("QAxBase: Error calling IDispatch member %s: No named arguments", name.toLatin1().data()); + qWarning("QAxBase: Error calling IDispatch member %s: No named arguments", + qPrintable(name)); return false; case DISP_E_OVERFLOW: - qWarning("QAxBase: Error calling IDispatch member %s: Overflow", name.toLatin1().data()); + qWarning("QAxBase: Error calling IDispatch member %s: Overflow", + qPrintable(name)); return false; case DISP_E_PARAMNOTFOUND: - qWarning("QAxBase: Error calling IDispatch member %s: Parameter %d not found", name.toLatin1().data(), argerr); + qWarning("QAxBase: Error calling IDispatch member %s: Parameter %d not found", + qPrintable(name), argerr); return false; case DISP_E_TYPEMISMATCH: - qWarning("QAxBase: Error calling IDispatch member %s: Type mismatch in parameter %d", name.toLatin1().data(), argerr); + qWarning("QAxBase: Error calling IDispatch member %s: Type mismatch in parameter %d", + qPrintable(name), argerr); return false; case DISP_E_UNKNOWNINTERFACE: - qWarning("QAxBase: Error calling IDispatch member %s: Unknown interface", name.toLatin1().data()); + qWarning("QAxBase: Error calling IDispatch member %s: Unknown interface", + qPrintable(name)); return false; case DISP_E_UNKNOWNLCID: - qWarning("QAxBase: Error calling IDispatch member %s: Unknown locale ID", name.toLatin1().data()); + qWarning("QAxBase: Error calling IDispatch member %s: Unknown locale ID", + qPrintable(name)); return false; case DISP_E_PARAMNOTOPTIONAL: - qWarning("QAxBase: Error calling IDispatch member %s: Non-optional parameter missing", name.toLatin1().data()); + qWarning("QAxBase: Error calling IDispatch member %s: Non-optional parameter missing", + qPrintable(name)); return false; default: - qWarning("QAxBase: Error calling IDispatch member %s: Unknown error", name.toLatin1().data()); + qWarning("QAxBase: Error calling IDispatch member %s: Unknown error", + qPrintable(name)); return false; } } @@ -3516,11 +3439,11 @@ int QAxBase::internalProperty(QMetaObject::Call call, int index, void **v) if (!disp) return index; - DISPID dispid = d->metaObject()->dispIDofName(propname, disp); + const QMetaObjectExtra &moExtra = moextra_cache.value(d->metaObject()); + DISPID dispid = moExtra.dispIDofName(propname, disp); if (dispid == DISPID_UNKNOWN) return index; - Q_ASSERT(d->metaobj); // property found, so everthing that goes wrong now should not bother the caller index -= mo->propertyCount(); @@ -3577,7 +3500,7 @@ int QAxBase::internalProperty(QMetaObject::Call call, int index, void **v) } else { qvar = QVariant(typeId, v[0]); if (typeId < QMetaType::User) - proptype = d->metaObject()->propertyType(propname); + proptype = moExtra.propertyType(propname); } } @@ -3595,7 +3518,7 @@ int QAxBase::internalProperty(QMetaObject::Call call, int index, void **v) break; } - checkHRESULT(hres, &excepinfo, this, QLatin1String(propname), argerr); + d->checkHRESULT(hres, &excepinfo, QLatin1String(propname), argerr); return index; } @@ -3620,14 +3543,13 @@ int QAxBase::internalInvoke(QMetaObject::Call call, int index, void **v) // Get the Dispatch ID of the method to be called bool isProperty = false; - DISPID dispid = d->metaObject()->dispIDofName(slotname, disp); - - Q_ASSERT(d->metaobj); + const QMetaObjectExtra &moExtra = moextra_cache.value(d->metaObject()); + DISPID dispid = moExtra.dispIDofName(slotname, disp); if (dispid == DISPID_UNKNOWN && slotname.toLower().startsWith("set")) { // see if we are calling a property set function as a slot slotname.remove(0, 3); - dispid = d->metaobj->dispIDofName(slotname, disp); + dispid = moExtra.dispIDofName(slotname, disp); isProperty = true; } if (dispid == DISPID_UNKNOWN) @@ -3639,7 +3561,7 @@ int QAxBase::internalInvoke(QMetaObject::Call call, int index, void **v) // setup the parameters DISPPARAMS params; DISPID dispidNamed = DISPID_PROPERTYPUT; - params.cArgs = UINT(d->metaobj->numParameter(signature)); + params.cArgs = UINT(moExtra.numParameter(signature)); params.cNamedArgs = isProperty ? 1 : 0; params.rgdispidNamedArgs = isProperty ? &dispidNamed : nullptr; params.rgvarg = nullptr; @@ -3656,7 +3578,7 @@ int QAxBase::internalInvoke(QMetaObject::Call call, int index, void **v) int p; for (p = 0; p < int(params.cArgs); ++p) { bool out; - QByteArray type = d->metaobj->paramType(signature, p, &out); + QByteArray type = moExtra.paramType(signature, p, &out); QVariant::Type vt = QVariant::nameToType(type); QVariant qvar; if (vt != QVariant::UserType && vt != int(QMetaType::QVariant)) @@ -3705,7 +3627,7 @@ int QAxBase::internalInvoke(QMetaObject::Call call, int index, void **v) // update out parameters for (p = 0; p < int(params.cArgs); ++p) { bool out; - QByteArray ptype = d->metaobj->paramType(signature, p, &out); + QByteArray ptype = moExtra.paramType(signature, p, &out); if (out) { VARIANTARG &var = params.rgvarg[int(params.cArgs) - p - 1]; QVariantToVoidStar(VARIANTToQVariant(var, ptype), v[p+1], ptype); @@ -3719,7 +3641,7 @@ int QAxBase::internalInvoke(QMetaObject::Call call, int index, void **v) if (params.rgvarg != static_rgvarg) delete [] params.rgvarg; - checkHRESULT(hres, &excepinfo, this, QString::fromLatin1(slotname), params.cArgs-argerr-1); + d->checkHRESULT(hres, &excepinfo, QString::fromLatin1(slotname), params.cArgs-argerr-1); return index; } @@ -3728,19 +3650,19 @@ int QAxBase::internalInvoke(QMetaObject::Call call, int index, void **v) */ int QAxBase::qt_static_metacall(QAxBase *_t, QMetaObject::Call _c, int _id, void **_a) { + if (_c != QMetaObject::InvokeMetaMethod) + return 0; Q_ASSERT(_t != nullptr); - if (_c == QMetaObject::InvokeMetaMethod) { - const QMetaObject *mo = _t->metaObject(); - switch (mo->method(_id + mo->methodOffset()).methodType()) { - case QMetaMethod::Signal: - QMetaObject::activate(_t->qObject(), mo, _id, _a); - return _id - mo->methodCount(); - case QMetaMethod::Method: - case QMetaMethod::Slot: - return _t->internalInvoke(_c, _id, _a); - default: - break; - } + const QMetaObject *mo = _t->metaObject(); + switch (mo->method(_id + mo->methodOffset()).methodType()) { + case QMetaMethod::Signal: + QMetaObject::activate(_t->qObject(), mo, _id, _a); + return _id - mo->methodCount(); + case QMetaMethod::Method: + case QMetaMethod::Slot: + return _t->internalInvoke(_c, _id, _a); + default: + break; } return 0; } @@ -3833,6 +3755,7 @@ bool QAxBase::dynamicCallHelper(const char *name, void *inout, QList<QVariant> & const QMetaObject *mo = metaObject(); d->metaObject(); Q_ASSERT(d->metaobj); + const QMetaObjectExtra &moExtra = moextra_cache.value(d->metaobj); int varc = vars.count(); @@ -3963,7 +3886,7 @@ bool QAxBase::dynamicCallHelper(const char *name, void *inout, QList<QVariant> & } QBitArray outArgs; if (varc) { - varc = qMin(varc, d->metaobj->numParameter(normFunction)); + varc = qMin(varc, moExtra.numParameter(normFunction)); arg = varc <= QAX_NUM_PARAMS ? staticarg : new VARIANT[varc]; outArgs = QBitArray(varc); for (int i = 0; i < varc; ++i) { @@ -3976,7 +3899,7 @@ bool QAxBase::dynamicCallHelper(const char *name, void *inout, QList<QVariant> & else if (parse || disptype == DISPATCH_PROPERTYGET) paramType = nullptr; else - paramType = d->metaobj->paramType(normFunction, i, &out); + paramType = moExtra.paramType(normFunction, i, &out); if ((!parse && d->useMetaObject && var.type() == QVariant::String) || var.type() == QVariant::ByteArray) { int enumIndex =mo->indexOfEnumerator(paramType); @@ -3992,10 +3915,10 @@ bool QAxBase::dynamicCallHelper(const char *name, void *inout, QList<QVariant> & } } - DISPID dispid = d->metaobj->dispIDofName(function, disp); + DISPID dispid = moExtra.dispIDofName(function, disp); if (dispid == DISPID_UNKNOWN && function.toLower().startsWith("set")) { function = function.mid(3); - dispid = d->metaobj->dispIDofName(function, disp); + dispid = moExtra.dispIDofName(function, disp); disptype = DISPATCH_PROPERTYPUT; } @@ -4037,7 +3960,7 @@ bool QAxBase::dynamicCallHelper(const char *name, void *inout, QList<QVariant> & if (arg && arg != staticarg) delete[] arg; - return checkHRESULT(hres, &excepinfo, this, QLatin1String(function), uint(varc) - argerr - 1); + return d->checkHRESULT(hres, &excepinfo, QLatin1String(function), uint(varc) - argerr - 1); } /*! @@ -4267,7 +4190,8 @@ QAxObject *QAxBase::querySubObject(const char *name, QList<QVariant> &vars) case VT_EMPTY: #ifdef QT_CHECK_STATE { - const char *coclass = metaObject()->classInfo(metaObject()->indexOfClassInfo("CoClass")).value(); + auto mo = metaObject(); + const char *coclass = mo->classInfo(mo->indexOfClassInfo("CoClass")).value(); qWarning("QAxBase::querySubObject: %s: Error calling function or property in %s (%s)" , name, control().toLatin1().data(), coclass ? coclass: "unknown"); } @@ -4276,7 +4200,8 @@ QAxObject *QAxBase::querySubObject(const char *name, QList<QVariant> &vars) default: #ifdef QT_CHECK_STATE { - const char *coclass = metaObject()->classInfo(metaObject()->indexOfClassInfo("CoClass")).value(); + auto mo = metaObject(); + const char *coclass = mo->classInfo(mo->indexOfClassInfo("CoClass")).value(); qWarning("QAxBase::querySubObject: %s: Method or property is not of interface type in %s (%s)" , name, control().toLatin1().data(), coclass ? coclass: "unknown"); } diff --git a/src/activeqt/container/qaxbase.h b/src/activeqt/container/qaxbase.h index 38dec7e..049ee57 100644 --- a/src/activeqt/container/qaxbase.h +++ b/src/activeqt/container/qaxbase.h @@ -65,7 +65,6 @@ class QUuid; class QAxEventSink; class QAxObject; class QAxBasePrivate; -struct QAxMetaObject; class QAxBase { @@ -159,7 +158,7 @@ protected: virtual const QMetaObject *fallbackMetaObject() const = 0; struct qt_meta_stringdata_QAxBase_t { - QByteArrayData data[13]; + const uint offsetsAndSize[26]; char stringdata[88]; }; static const qt_meta_stringdata_QAxBase_t qt_meta_stringdata_QAxBase; @@ -175,7 +174,6 @@ private: friend void *qax_createObjectWrapper(int, IUnknown*); bool initializeLicensedHelper(void *factory, const QString &key, IUnknown **ptr); QAxBasePrivate *d; - QAxMetaObject *internalMetaObject() const; virtual const QMetaObject *parentMetaObject() const = 0; int internalProperty(QMetaObject::Call, int index, void **v); diff --git a/src/activeqt/container/qaxbase_p.h b/src/activeqt/container/qaxbase_p.h new file mode 100644 index 0000000..fc347b7 --- /dev/null +++ b/src/activeqt/container/qaxbase_p.h @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the ActiveQt framework of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QAXBASE_P_H +#define QAXBASE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qbytearray.h> +#include <QtCore/qhash.h> +#include <QtCore/qmap.h> +#include <QtCore/qmetaobject.h> +#include <QtCore/quuid.h> +#include <QtCore/qt_windows.h> + +struct tagEXCEPINFO; + +QT_BEGIN_NAMESPACE + +class QAxBase; +class QAxEventSink; + +class QAxBasePrivate +{ + Q_DISABLE_COPY_MOVE(QAxBasePrivate) +public: + using UuidEventSinkHash = QHash<QUuid, QAxEventSink*>; + + explicit QAxBasePrivate(QAxBase *b); + ~QAxBasePrivate(); + + IDispatch *dispatch() const + { + if (disp) + return disp; + + if (ptr) + ptr->QueryInterface(IID_IDispatch, reinterpret_cast<void **>(&disp)); + return disp; + } + + bool checkHRESULT(long hres, tagEXCEPINFO *exc, const QString &name, uint argerr); + void handleException(tagEXCEPINFO *exc, const QString &name); + + static QVariant VARIANTToQVariant(const VARIANT &arg, const QByteArray &typeName, uint type = 0); + + QAxBase *q; + QString ctrl; + UuidEventSinkHash eventSink; + uint useEventSink :1; + uint useMetaObject :1; + uint useClassInfo :1; + uint cachedMetaObject :1; + uint initialized :1; + uint tryCache :1; + unsigned long classContext = CLSCTX_SERVER; + + IUnknown *ptr = nullptr; + mutable IDispatch *disp = nullptr; + + QMap<QByteArray, bool> propWritable; + + QMetaObject *metaObject() + { + return metaobj; + } + + mutable QMap<QString, LONG> verbs; + + QMetaObject *metaobj = nullptr; +}; + +QT_END_NAMESPACE + +#endif // QAXBASE_P_H diff --git a/src/activeqt/container/qaxdump.cpp b/src/activeqt/container/qaxdump.cpp index 2313306..5adbb6a 100644 --- a/src/activeqt/container/qaxdump.cpp +++ b/src/activeqt/container/qaxdump.cpp @@ -50,6 +50,8 @@ #include "qaxbase.h" +#include <QtAxBase/private/qaxtypefunctions_p.h> + #include <qmetaobject.h> #include <quuid.h> #include <qt_windows.h> @@ -57,7 +59,7 @@ #include <ctype.h> -#include "../shared/qaxtypes.h" +#include "../shared/qaxtypes_p.h" QT_BEGIN_NAMESPACE @@ -160,20 +162,23 @@ QString qax_generateDocumentation(QAxBase *that) stream << "<h3>Interfaces</h3>" << Qt::endl; stream << "<ul>" << Qt::endl; - const char *inter = nullptr; - UINT interCount = 1; - while ((inter = mo->classInfo(mo->indexOfClassInfo("Interface " + QByteArray::number(interCount))).value())) { - stream << "<li>" << inter << Qt::endl; - interCount++; + for (int interCount = 1; ; ++interCount) { + const QByteArray name = "Interface " + QByteArray::number(interCount); + const int index = mo->indexOfClassInfo(name.constData()); + if (index < 0) + break; + stream << "<li>" << mo->classInfo(index).value() << Qt::endl; } stream << "</ul>" << Qt::endl; stream << "<h3>Event Interfaces</h3>" << Qt::endl; stream << "<ul>" << Qt::endl; - interCount = 1; - while ((inter = mo->classInfo(mo->indexOfClassInfo("Event Interface " + QByteArray::number(interCount))).value())) { - stream << "<li>" << inter << Qt::endl; - interCount++; + for (int interCount = 1; ; ++interCount) { + const QByteArray name = ("Event Interface " + QByteArray::number(interCount)); + const int index = mo->indexOfClassInfo(name.constData()); + if (index < 0) + break; + stream << "<li>" << mo->classInfo(index).value() << Qt::endl; } stream << "</ul>" << Qt::endl; @@ -272,7 +277,7 @@ QString qax_generateDocumentation(QAxBase *that) QLatin1String(name.constData()) + QLatin1Char(' ') + QLatin1String(prototype.constData()) + QLatin1String("<tt> [signal]</tt></h3>\n"); if (typeLib) { - interCount = 0; + UINT interCount = 0; do { if (typeInfo) typeInfo->Release(); diff --git a/src/activeqt/container/qaxobject.cpp b/src/activeqt/container/qaxobject.cpp index 97a995d..8f309b3 100644 --- a/src/activeqt/container/qaxobject.cpp +++ b/src/activeqt/container/qaxobject.cpp @@ -91,7 +91,7 @@ QT_BEGIN_NAMESPACE */ const QMetaObject QAxObject::staticMetaObject = { - { &QObject::staticMetaObject, qt_meta_stringdata_QAxBase.data, + { &QObject::staticMetaObject, qt_meta_stringdata_QAxBase.offsetsAndSize, qt_meta_data_QAxBase, qt_static_metacall, nullptr, nullptr } }; diff --git a/src/activeqt/container/qaxobject.h b/src/activeqt/container/qaxobject.h index 587b532..049747c 100644 --- a/src/activeqt/container/qaxobject.h +++ b/src/activeqt/container/qaxobject.h @@ -51,7 +51,7 @@ #ifndef QAXOBJECT_H #define QAXOBJECT_H -#include <ActiveQt/qaxbase.h> +#include <QtAxContainer/qaxbase.h> QT_BEGIN_NAMESPACE diff --git a/src/activeqt/container/qaxscript.cpp b/src/activeqt/container/qaxscript.cpp index 07c0669..7477e79 100644 --- a/src/activeqt/container/qaxscript.cpp +++ b/src/activeqt/container/qaxscript.cpp @@ -49,7 +49,8 @@ ****************************************************************************/ #include "qaxscript.h" -#include "../shared/qaxutils_p.h" +#include <QtAxBase/private/qaxutils_p.h> +#include <QtAxBase/private/qaxtypefunctions_p.h> #if defined(Q_CC_GNU) && (__MINGW64_VERSION_MAJOR == 3 && __MINGW64_VERSION_MINOR > 0 || __MINGW64_VERSION_MAJOR >= 4) // Workaround for mingw-w64 bug #464 @@ -71,7 +72,7 @@ #include <activscp.h> #endif -#include "../shared/qaxtypes.h" +#include "../shared/qaxtypes_p.h" QT_BEGIN_NAMESPACE diff --git a/src/activeqt/container/qaxscript.h b/src/activeqt/container/qaxscript.h index 17449d4..3997d9d 100644 --- a/src/activeqt/container/qaxscript.h +++ b/src/activeqt/container/qaxscript.h @@ -51,7 +51,7 @@ #ifndef QAXSCRIPT_H #define QAXSCRIPT_H -#include <ActiveQt/qaxobject.h> +#include <QtAxContainer/qaxobject.h> struct IActiveScript; diff --git a/src/activeqt/container/qaxscriptwrapper.cpp b/src/activeqt/container/qaxscriptwrapper.cpp index 31a082f..e548880 100644 --- a/src/activeqt/container/qaxscriptwrapper.cpp +++ b/src/activeqt/container/qaxscriptwrapper.cpp @@ -50,7 +50,7 @@ #include "qaxobject.h" -#include <ActiveQt/qaxfactory.h> +#include <QtAxServer/qaxfactory.h> #include <qt_windows.h> diff --git a/src/activeqt/container/qaxselect.ui b/src/activeqt/container/qaxselect.ui index af5f973..4fb7741 100644 --- a/src/activeqt/container/qaxselect.ui +++ b/src/activeqt/container/qaxselect.ui @@ -134,9 +134,6 @@ </layout> </widget> <layoutdefault spacing="6" margin="11"/> - <includes> - <include location="local">qaxwidget.h</include> - </includes> <resources/> <connections/> </ui> diff --git a/src/activeqt/container/qaxwidget.cpp b/src/activeqt/container/qaxwidget.cpp index 69875d2..abc9948 100644 --- a/src/activeqt/container/qaxwidget.cpp +++ b/src/activeqt/container/qaxwidget.cpp @@ -49,9 +49,10 @@ ****************************************************************************/ #include "qaxwidget.h" -#include "../shared/qaxutils_p.h" +#include <QtAxBase/private/qaxutils_p.h> +#include <QtAxBase/private/qaxtypefunctions_p.h> -#include <ActiveQt/qaxaggregated.h> +#include <QtAxServer/qaxaggregated.h> #include <qabstracteventdispatcher.h> #include <qapplication.h> @@ -104,7 +105,7 @@ }; #endif -#include "../shared/qaxtypes.h" +#include "../shared/qaxtypes_p.h" QT_BEGIN_NAMESPACE @@ -1914,7 +1915,7 @@ void QAxHostWidget::paintEvent(QPaintEvent*) */ const QMetaObject QAxWidget::staticMetaObject = { - { &QWidget::staticMetaObject, qt_meta_stringdata_QAxBase.data, + { &QWidget::staticMetaObject, qt_meta_stringdata_QAxBase.offsetsAndSize, qt_meta_data_QAxBase, qt_static_metacall, nullptr, nullptr } }; diff --git a/src/activeqt/container/qaxwidget.h b/src/activeqt/container/qaxwidget.h index 14c4290..2bcf3c7 100644 --- a/src/activeqt/container/qaxwidget.h +++ b/src/activeqt/container/qaxwidget.h @@ -51,7 +51,7 @@ #ifndef QAXWIDGET_H #define QAXWIDGET_H -#include <ActiveQt/qaxbase.h> +#include <QtAxContainer/qaxbase.h> #include <QtWidgets/qwidget.h> QT_BEGIN_NAMESPACE diff --git a/src/activeqt/control/CMakeLists.txt b/src/activeqt/control/CMakeLists.txt new file mode 100644 index 0000000..c33411d --- /dev/null +++ b/src/activeqt/control/CMakeLists.txt @@ -0,0 +1,47 @@ +# Generated from control.pro. + +##################################################################### +## AxServer Module: +##################################################################### + +qt_add_module(AxServer + STATIC + QMAKE_MODULE_CONFIG idcidl force_import_plugins + SOURCES + ../shared/qaxtypes.cpp ../shared/qaxtypes_p.h + qaxaggregated.cpp qaxaggregated.h + qaxbindable.cpp qaxbindable.h + qaxfactory.cpp qaxfactory.h + qaxmain.cpp + qaxserver.cpp + qaxserverbase.cpp + qaxserverdll.cpp + qaxservermain.cpp + qclassfactory_p.h + DEFINES + QAX_SERVER + PUBLIC_DEFINES + QAXSERVER + LIBRARIES + Qt::AxBasePrivate + Qt::CorePrivate + Qt::GuiPrivate + Qt::WidgetsPrivate + PUBLIC_LIBRARIES + Qt::Core + Qt::Gui + Qt::Widgets + shell32 +) + +#### Keys ignored in scope 1:.:.:control.pro:<TRUE>: +# MODULE = "axserver" +# MODULE_CONFIG = "idcidl" "force_import_plugins" + +## Scopes: +##################################################################### + +qt_extend_target(AxServer CONDITION MINGW + DEFINES + QT_NEEDS_QMAIN +) diff --git a/src/activeqt/control/control.pro b/src/activeqt/control/control.pro index e55bdab..e5f251e 100644 --- a/src/activeqt/control/control.pro +++ b/src/activeqt/control/control.pro @@ -1,6 +1,7 @@ TARGET = QtAxServer -QT += core-private gui-private widgets axbase +QT += widgets +QT_PRIVATE += core-private gui-private widgets-private axbase-private CONFIG += static DEFINES += QAX_SERVER @@ -11,7 +12,7 @@ HEADERS = qaxaggregated.h \ qaxbindable.h \ qaxfactory.h \ qclassfactory_p.h \ - ../shared/qaxtypes.h + ../shared/qaxtypes_p.h SOURCES = qaxaggregated.cpp \ qaxserver.cpp \ @@ -28,7 +29,4 @@ LIBS += -lshell32 MODULE = axserver MODULE_DEFINES = QAXSERVER MODULE_CONFIG = idcidl force_import_plugins -MODULE_MASTER_HEADER = ActiveQt -CONFIG += no_module_headers load(qt_module) -DEFINES -= QT_NO_CAST_TO_ASCII QT_USE_QSTRINGBUILDER diff --git a/src/activeqt/control/qaxbindable.cpp b/src/activeqt/control/qaxbindable.cpp index f74122d..96a34cd 100644 --- a/src/activeqt/control/qaxbindable.cpp +++ b/src/activeqt/control/qaxbindable.cpp @@ -53,7 +53,9 @@ #include <qmetaobject.h> #include <qt_windows.h> // for IUnknown -#include "../shared/qaxtypes.h" +#include "../shared/qaxtypes_p.h" + +#include <QtAxBase/private/qaxtypefunctions_p.h> QT_BEGIN_NAMESPACE diff --git a/src/activeqt/control/qaxserver.cpp b/src/activeqt/control/qaxserver.cpp index 92f03f9..7e85158 100644 --- a/src/activeqt/control/qaxserver.cpp +++ b/src/activeqt/control/qaxserver.cpp @@ -267,18 +267,21 @@ static void UpdateRegistryKeys(bool bRegister, const QString keyPath, QScopedPoi const QString versionLessProgId = module + dot + className; const QString progId = versionLessProgId + dot + classMajorVersion; QString key = slash + progId; - settings->setValue(key + QLatin1String("/."), className + QLatin1String(" Class")); + settings->setValue(key + QLatin1String("/."), + QString(className + QLatin1String(" Class"))); settings->setValue(key + QLatin1String("/CLSID/."), classId); if (insertable) settings->setValue(key + QLatin1String("/Insertable/."), QVariant(QLatin1String(""))); key = slash + module + dot + className; - settings->setValue(key + QLatin1String("/."), className + QLatin1String(" Class")); + settings->setValue(key + QLatin1String("/."), + QString(className + QLatin1String(" Class"))); settings->setValue(key + QLatin1String("/CLSID/."), classId); settings->setValue(key + QLatin1String("/CurVer/."), progId); key = QLatin1String("/CLSID/") + classId; - settings->setValue(key + QLatin1String("/."), className + QLatin1String(" Class")); + settings->setValue(key + QLatin1String("/."), + QString(className + QLatin1String(" Class"))); settings->setValue(key + QLatin1String("/AppID"), appId); if (control) settings->setValue(key + QLatin1String("/Control/."), QVariant(QLatin1String(""))); @@ -288,12 +291,12 @@ static void UpdateRegistryKeys(bool bRegister, const QString keyPath, QScopedPoi settings->setValue(key + QLatin1String("/InProcServer32/."), file); else settings->setValue(key + QLatin1String("/LocalServer32/."), - QLatin1Char('\"') + file + QLatin1String("\" -activex")); + QString(QLatin1Char('\"') + file + QLatin1String("\" -activex"))); settings->setValue(key + QLatin1String("/MiscStatus/."), control ? QLatin1String("1") : QLatin1String("0")); settings->setValue(key + QLatin1String("/MiscStatus/1/."), QString::number(olemisc)); settings->setValue(key + QLatin1String("/Programmable/."), QVariant(QLatin1String(""))); - settings->setValue(key + QLatin1String("/ToolboxBitmap32/."), QLatin1Char('\"') + - file + QLatin1String("\", 101")); + settings->setValue(key + QLatin1String("/ToolboxBitmap32/."), + QString(QLatin1Char('\"') + file + QLatin1String("\", 101"))); settings->setValue(key + QLatin1String("/TypeLib/."), libId); settings->setValue(key + QLatin1String("/Version/."), classVersion); settings->setValue(key + QLatin1String("/VersionIndependentProgID/."), versionLessProgId); @@ -318,7 +321,8 @@ static void UpdateRegistryKeys(bool bRegister, const QString keyPath, QScopedPoi if (!extension.isEmpty()) { key = slash + extension; - settings->setValue(key + QLatin1String("/."), module + dot + className); + settings->setValue(key + QLatin1String("/."), + QString(module + dot + className)); settings->setValue(key + QLatin1String("/Content Type"), mime); mime.replace(slash, QLatin1Char('\\')); diff --git a/src/activeqt/control/qaxserverbase.cpp b/src/activeqt/control/qaxserverbase.cpp index 57ca767..eb07d2b 100644 --- a/src/activeqt/control/qaxserverbase.cpp +++ b/src/activeqt/control/qaxserverbase.cpp @@ -48,7 +48,6 @@ ** ****************************************************************************/ -#define QT_NO_CAST_TO_ASCII #define NOMINMAX #include <qabstracteventdispatcher.h> @@ -84,8 +83,9 @@ #include "qaxbindable.h" #include "qaxaggregated.h" -#include "../shared/qaxtypes.h" -#include "../shared/qaxutils_p.h" +#include "../shared/qaxtypes_p.h" +#include <QtAxBase/private/qaxutils_p.h> +#include <QtAxBase/private/qaxtypefunctions_p.h> #include "qclassfactory_p.h" @@ -2384,8 +2384,10 @@ HRESULT WINAPI QAxServerBase::Invoke(DISPID dispidMember, REFIID riid, nameLength = name.length(); name += '('; // no parameter - shortcut - if (!pDispParams->cArgs) - index = mo->indexOfSlot((name + ')')); + if (!pDispParams->cArgs) { + const QByteArray slotName = name + ')'; + index = mo->indexOfSlot(slotName.constData()); + } // search if (index == -1) { for (int i = 0; i < mo->methodCount(); ++i) { diff --git a/src/activeqt/shared/qaxtypes.cpp b/src/activeqt/shared/qaxtypes.cpp index 3ee12c3..40f5e0a 100644 --- a/src/activeqt/shared/qaxtypes.cpp +++ b/src/activeqt/shared/qaxtypes.cpp @@ -53,8 +53,9 @@ #include <ocidl.h> #include <olectl.h> -#include "qaxtypes.h" -#include "qaxutils_p.h" +#include "qaxtypes_p.h" +#include <QtAxBase/private/qaxutils_p.h> +#include <QtAxBase/private/qaxtypefunctions_p.h> #include <qcursor.h> #include <qpixmap.h> diff --git a/src/activeqt/shared/qaxtypes.h b/src/activeqt/shared/qaxtypes_p.h index 147e261..2ce8a3f 100644 --- a/src/activeqt/shared/qaxtypes.h +++ b/src/activeqt/shared/qaxtypes_p.h @@ -51,7 +51,21 @@ #ifndef QAXTYPES_H #define QAXTYPES_H -#include <ActiveQt/qaxtypefunctions.h> +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qbytearray.h> +#include <QtCore/qvariant.h> + +#include <QtCore/qt_windows.h> QT_BEGIN_NAMESPACE diff --git a/src/src.pro b/src/src.pro index 4248dae..6cff49f 100644 --- a/src/src.pro +++ b/src/src.pro @@ -1,4 +1,4 @@ TEMPLATE = subdirs SUBDIRS = activeqt -win32:!winrt:!wince: SUBDIRS += tools +win32:!winrt: SUBDIRS += tools CONFIG += ordered diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt new file mode 100644 index 0000000..28a5f42 --- /dev/null +++ b/src/tools/CMakeLists.txt @@ -0,0 +1,3 @@ +# Generated from tools.pro. + +add_subdirectory(idc) diff --git a/src/tools/idc/CMakeLists.txt b/src/tools/idc/CMakeLists.txt new file mode 100644 index 0000000..607404f --- /dev/null +++ b/src/tools/idc/CMakeLists.txt @@ -0,0 +1,16 @@ +# Generated from idc.pro. + +##################################################################### +## idc Tool: +##################################################################### + +qt_add_tool(idc +# BOOTSTRAP # special case + TOOLS_TARGET AxContainer # special case + SOURCES + main.cpp +) + +#### Keys ignored in scope 1:.:.:idc.pro:<TRUE>: +# QMAKE_TARGET_DESCRIPTION = "Active Qt Interface Description Compiler" +# _OPTION = "host_build" diff --git a/sync.profile b/sync.profile index 15b0fdf..190bea0 100644 --- a/sync.profile +++ b/sync.profile @@ -1,4 +1,7 @@ %modules = ( # path to module name map + "QtAxBase" => "$basedir/src/activeqt/axbase", + "QtAxContainer" => "$basedir/src/activeqt/container", + "QtAxServer" => "$basedir/src/activeqt/control", "ActiveQt" => "$basedir/src/activeqt" ); %moduleheaders = ( # restrict the module headers to those found in relative path diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..2214137 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,7 @@ +# Generated from tests.pro. + +if(QT_BUILD_STANDALONE_TESTS) + # Add qt_find_package calls for extra dependencies that need to be found when building + # the standalone tests here. +endif() +qt_build_tests() diff --git a/tests/auto/CMakeLists.txt b/tests/auto/CMakeLists.txt new file mode 100644 index 0000000..8537f4f --- /dev/null +++ b/tests/auto/CMakeLists.txt @@ -0,0 +1,9 @@ +# Generated from auto.pro. + +add_subdirectory(conversion) +add_subdirectory(qaxobject) +# add_subdirectory(dumpcpp) (needs typelib target) # special case +#add_subdirectory(cmake) # special case +if(NOT GCC) + add_subdirectory(qaxscript) +endif() diff --git a/tests/auto/cmake/test_modules/container/axcontainer.cpp b/tests/auto/cmake/test_modules/container/axcontainer.cpp index 3c2758d..e16bddb 100644 --- a/tests/auto/cmake/test_modules/container/axcontainer.cpp +++ b/tests/auto/cmake/test_modules/container/axcontainer.cpp @@ -27,9 +27,7 @@ ****************************************************************************/ #include <qt_windows.h> -#include <ActiveQt> -#include <ActiveQt/ActiveQt> -#include <ActiveQt/QAxWidget> +#include <QtAxContainer/QAxWidget> #include <QAxWidget> int main(int argc, char **argv) diff --git a/tests/auto/cmake/test_modules/server/axserver.cpp b/tests/auto/cmake/test_modules/server/axserver.cpp index 98baea2..b31014c 100644 --- a/tests/auto/cmake/test_modules/server/axserver.cpp +++ b/tests/auto/cmake/test_modules/server/axserver.cpp @@ -28,10 +28,7 @@ #include <qt_windows.h> #include <QAxFactory> -#include <ActiveQt/QAxFactory> -#include <ActiveQt/ActiveQt> -#include <ActiveQt> - +#include <QtAxServer/QAxFactory> QT_BEGIN_NAMESPACE QAxFactory *qax_instantiate() diff --git a/tests/auto/conversion/CMakeLists.txt b/tests/auto/conversion/CMakeLists.txt new file mode 100644 index 0000000..4aab821 --- /dev/null +++ b/tests/auto/conversion/CMakeLists.txt @@ -0,0 +1,13 @@ +# Generated from conversion.pro. + +##################################################################### +## conversion Test: +##################################################################### + +qt_add_test(conversion + SOURCES + tst_conversion.cpp + PUBLIC_LIBRARIES + Qt::AxContainer + Qt::Gui +) diff --git a/tests/auto/dumpcpp/CMakeLists.txt b/tests/auto/dumpcpp/CMakeLists.txt new file mode 100644 index 0000000..91da6c3 --- /dev/null +++ b/tests/auto/dumpcpp/CMakeLists.txt @@ -0,0 +1,20 @@ +# Generated from dumpcpp.pro. + +##################################################################### +## tst_dumpcpp Test: +##################################################################### + +qt_add_test(tst_dumpcpp + SOURCES + tst_dumpcpp.cpp + PUBLIC_LIBRARIES + Qt::AxContainer + Qt::Gui + Qt::Widgets +) + +#### Keys ignored in scope 1:.:.:dumpcpp.pro:<TRUE>: +# TYPELIBS = "$$(SystemRoot)\\system32\\ieframe.dll" + +## Scopes: +##################################################################### diff --git a/tests/auto/qaxobject/CMakeLists.txt b/tests/auto/qaxobject/CMakeLists.txt new file mode 100644 index 0000000..7c07415 --- /dev/null +++ b/tests/auto/qaxobject/CMakeLists.txt @@ -0,0 +1,13 @@ +# Generated from qaxobject.pro. + +##################################################################### +## qaxobject Test: +##################################################################### + +qt_add_test(qaxobject + SOURCES + tst_qaxobject.cpp + PUBLIC_LIBRARIES + Qt::AxContainer + Qt::Gui +) diff --git a/tests/auto/qaxscript/CMakeLists.txt b/tests/auto/qaxscript/CMakeLists.txt new file mode 100644 index 0000000..4312217 --- /dev/null +++ b/tests/auto/qaxscript/CMakeLists.txt @@ -0,0 +1,12 @@ +# Generated from qaxscript.pro. + +##################################################################### +## qaxscript Test: +##################################################################### + +qt_add_test(qaxscript + SOURCES + tst_qaxscript.cpp + PUBLIC_LIBRARIES + Qt::AxContainer +) diff --git a/tests/manual/CMakeLists.txt b/tests/manual/CMakeLists.txt new file mode 100644 index 0000000..048232d --- /dev/null +++ b/tests/manual/CMakeLists.txt @@ -0,0 +1,5 @@ +# Generated from manual.pro. + +add_subdirectory(axviewer) +add_subdirectory(dumpcpp) +add_subdirectory(testcontrol) diff --git a/tests/manual/axviewer/CMakeLists.txt b/tests/manual/axviewer/CMakeLists.txt new file mode 100644 index 0000000..4974bcf --- /dev/null +++ b/tests/manual/axviewer/CMakeLists.txt @@ -0,0 +1,69 @@ +# Generated from axviewer.pro. + +##################################################################### +## axviewer Binary: +##################################################################### + +qt_add_manual_test(axviewer + SOURCES + ../shared/metaobjectdump.cpp ../shared/metaobjectdump.h + ../shared/textdialog.cpp ../shared/textdialog.h + main.cpp + INCLUDE_DIRECTORIES + ../shared + PUBLIC_LIBRARIES + Qt::AxContainer + Qt::Gui + Qt::Widgets +) + +#### Keys ignored in scope 1:.:.:axviewer.pro:<TRUE>: +# DIAGLIB = "../../../../qtbase/tests/manual/diaglib" +# TEMPLATE = "app" + +## Scopes: +##################################################################### + +qt_extend_target(axviewer CONDITION EXISTS _ss_DIAGLIB + SOURCES + ../../../../qtbase/tests/manual/diaglib/eventfilter.cpp ../../../../qtbase/tests/manual/diaglib/eventfilter.h + ../../../../qtbase/tests/manual/diaglib/nativewindowdump.h + ../../../../qtbase/tests/manual/diaglib/qwindowdump.cpp ../../../../qtbase/tests/manual/diaglib/qwindowdump.h + ../../../../qtbase/tests/manual/diaglib/textdump.cpp ../../../../qtbase/tests/manual/diaglib/textdump.h + DEFINES + QT_DIAG_LIB + INCLUDE_DIRECTORIES + ../../../../qtbase/tests/manual/diaglib + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::GuiPrivate +) + +qt_extend_target(axviewer CONDITION (EXISTS _ss_DIAGLIB) AND (WIN32 AND NOT WINRT) + SOURCES + ../../../../qtbase/tests/manual/diaglib/nativewindowdump_win.cpp + PUBLIC_LIBRARIES + user32 +) + +qt_extend_target(axviewer CONDITION (EXISTS _ss_DIAGLIB) AND (NOT (WIN32 AND NOT WINRT)) + SOURCES + ../../../../qtbase/tests/manual/diaglib/nativewindowdump.cpp +) + +qt_extend_target(axviewer CONDITION (EXISTS _ss_DIAGLIB) AND (QT_FEATURE_widgets) + SOURCES + ../../../../qtbase/tests/manual/diaglib/debugproxystyle.cpp ../../../../qtbase/tests/manual/diaglib/debugproxystyle.h + ../../../../qtbase/tests/manual/diaglib/logwidget.cpp ../../../../qtbase/tests/manual/diaglib/logwidget.h + ../../../../qtbase/tests/manual/diaglib/qwidgetdump.cpp ../../../../qtbase/tests/manual/diaglib/qwidgetdump.h + PUBLIC_LIBRARIES + Qt::WidgetsPrivate +) + +qt_extend_target(axviewer CONDITION (EXISTS _ss_DIAGLIB) AND (QT_FEATURE_opengl) + SOURCES + ../../../../qtbase/tests/manual/diaglib/glinfo.cpp ../../../../qtbase/tests/manual/diaglib/glinfo.h + PUBLIC_LIBRARIES + Qt::OpenGL + Qt::OpenGLWidgets +) diff --git a/tests/manual/axviewer/main.cpp b/tests/manual/axviewer/main.cpp index 2f6c4bf..29ad3dc 100644 --- a/tests/manual/axviewer/main.cpp +++ b/tests/manual/axviewer/main.cpp @@ -29,10 +29,10 @@ #include "metaobjectdump.h" #include "textdialog.h" -#include <ActiveQt/QAxSelect> -#include <ActiveQt/QAxWidget> +#include <QtAxContainer/QAxSelect> +#include <QtAxContainer/QAxWidget> -#include <QtWidgets/QAction> +#include <QtGui/QAction> #include <QtWidgets/QApplication> #include <QtWidgets/QMainWindow> #include <QtWidgets/QMenu> diff --git a/tests/manual/dumpcpp/CMakeLists.txt b/tests/manual/dumpcpp/CMakeLists.txt new file mode 100644 index 0000000..bc681d9 --- /dev/null +++ b/tests/manual/dumpcpp/CMakeLists.txt @@ -0,0 +1,26 @@ +# Generated from dumpcpp.pro. + +##################################################################### +## dumpcpp Binary: +##################################################################### + +qt_add_executable(dumpcpp + SOURCES + ../shared/metaobjectdump.cpp ../shared/metaobjectdump.h + ../shared/textdialog.cpp ../shared/textdialog.h + main.cpp + INCLUDE_DIRECTORIES + ../shared + PUBLIC_LIBRARIES + Qt::AxContainer + Qt::Gui + Qt::Test + Qt::Widgets +) + +#### Keys ignored in scope 1:.:.:dumpcpp.pro:<TRUE>: +# TEMPLATE = "app" +# TYPELIBS = "$$(SystemRoot)\\system32\\ieframe.dll" + +## Scopes: +##################################################################### diff --git a/tests/manual/testcontrol/CMakeLists.txt b/tests/manual/testcontrol/CMakeLists.txt new file mode 100644 index 0000000..3115e4d --- /dev/null +++ b/tests/manual/testcontrol/CMakeLists.txt @@ -0,0 +1,20 @@ +# Generated from testcontrol.pro. + +##################################################################### +## testcontrol Binary: +##################################################################### + +qt_add_executable(testcontrol + GUI + SOURCES + main.cpp + PUBLIC_LIBRARIES + Qt::AxServer + Qt::Gui + Qt::Widgets +) +qt_disable_warnings(testcontrol) + +#### Keys ignored in scope 1:.:.:testcontrol.pro:<TRUE>: +# RC_FILE = "testcontrol.rc" +# TEMPLATE = "app" diff --git a/tests/manual/testcontrol/main.cpp b/tests/manual/testcontrol/main.cpp index 7fca250..bedd265 100644 --- a/tests/manual/testcontrol/main.cpp +++ b/tests/manual/testcontrol/main.cpp @@ -26,8 +26,8 @@ ** ****************************************************************************/ -#include <ActiveQt/QAxFactory> -#include <QtWidgets/QAction> +#include <QtAxServer/QAxFactory> +#include <QtGui/QAction> #include <QtWidgets/QApplication> #include <QtWidgets/QMainWindow> #include <QtWidgets/QMenu> diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt new file mode 100644 index 0000000..c41b17e --- /dev/null +++ b/tools/CMakeLists.txt @@ -0,0 +1,10 @@ +# Generated from tools.pro. + + +qt_exclude_tool_directories_from_default_target( + testcon +) + +add_subdirectory(dumpdoc) +add_subdirectory(dumpcpp) +add_subdirectory(testcon) diff --git a/tools/dumpcpp/CMakeLists.txt b/tools/dumpcpp/CMakeLists.txt new file mode 100644 index 0000000..6c13386 --- /dev/null +++ b/tools/dumpcpp/CMakeLists.txt @@ -0,0 +1,23 @@ +# Generated from dumpcpp.pro. + +##################################################################### +## dumpcpp Tool: +##################################################################### + +qt_add_tool(dumpcpp + TOOLS_TARGET AxContainer # special case + SOURCES + main.cpp + moc.cpp moc.h + DEFINES + QT_ASCII_CAST_WARNINGS + QT_NO_CAST_TO_ASCII + PUBLIC_LIBRARIES + Qt::AxContainer + Qt::CorePrivate + Qt::Gui + Qt::Widgets +) + +#### Keys ignored in scope 1:.:.:dumpcpp.pro:<TRUE>: +# QMAKE_TARGET_DESCRIPTION = "Active Qt DumpCpp" diff --git a/tools/dumpcpp/dumpcpp.pro b/tools/dumpcpp/dumpcpp.pro index aaaf5f8..5b56cea 100644 --- a/tools/dumpcpp/dumpcpp.pro +++ b/tools/dumpcpp/dumpcpp.pro @@ -1,7 +1,8 @@ QT += axcontainer widgets core-private DEFINES += QT_NO_CAST_TO_ASCII QT_ASCII_CAST_WARNINGS -SOURCES = main.cpp +SOURCES = main.cpp moc.cpp +HEADERS += moc.h QMAKE_TARGET_DESCRIPTION = "Active Qt DumpCpp" load(qt_tool) diff --git a/tools/dumpcpp/main.cpp b/tools/dumpcpp/main.cpp index 780d41b..d50c65d 100644 --- a/tools/dumpcpp/main.cpp +++ b/tools/dumpcpp/main.cpp @@ -26,10 +26,13 @@ ** ****************************************************************************/ +#include "moc.h" + #include <QAxObject> #include <QFile> #include <QMetaObject> #include <QMetaEnum> +#include <QDebug> #include <QTextStream> #include <QSettings> #include <QStringList> @@ -85,17 +88,8 @@ void writeEnums(QTextStream &out, const QMetaObject *mo) { // enums for (int ienum = mo->enumeratorOffset(); ienum < mo->enumeratorCount(); ++ienum) { - QMetaEnum metaEnum = mo->enumerator(ienum); - out << " enum " << metaEnum.name() << " {" << Qt::endl; - for (int k = 0; k < metaEnum.keyCount(); ++k) { - QByteArray key(metaEnum.key(k)); - out << " " << key.leftJustified(24) << "= " << metaEnum.value(k); - if (k < metaEnum.keyCount() - 1) - out << ','; - out << Qt::endl; - } - out << " };" << Qt::endl; - out << Qt::endl; + formatCppEnum(out, mo->enumerator(ienum)); + out << '\n'; } } @@ -184,9 +178,12 @@ static void formatConstructorSignature(QTextStream &out, ObjectCategories catego out << ')'; } -static void formatConstructorBody(QTextStream &out, const QByteArray &className, +static void formatConstructorBody(QTextStream &out, const QByteArray &nameSpace, + const QByteArray &className, const QString &controlID, ObjectCategories category) { + if (!nameSpace.isEmpty()) + out << nameSpace << "::"; out << className << "::" << className; formatConstructorSignature(out, category, false); out << " :" << Qt::endl << " "; @@ -258,21 +255,8 @@ void generateClassDecl(QTextStream &out, const QMetaObject *mo, functions << className; // enums - if (nameSpace.isEmpty() && !(category & OnlyInlines)) { - for (int ienum = mo->enumeratorOffset(); ienum < mo->enumeratorCount(); ++ienum) { - QMetaEnum metaEnum = mo->enumerator(ienum); - out << " enum " << metaEnum.name() << " {" << Qt::endl; - for (int k = 0; k < metaEnum.keyCount(); ++k) { - QByteArray key(metaEnum.key(k)); - out << " " << key.leftJustified(24) << "= " << metaEnum.value(k); - if (k < metaEnum.keyCount() - 1) - out << ','; - out << Qt::endl; - } - out << " };" << Qt::endl; - out << Qt::endl; - } - } + if (nameSpace.isEmpty() && !(category & OnlyInlines)) + writeEnums(out, mo); // QAxBase public virtual functions. QByteArrayList axBase_vfuncs; axBase_vfuncs.append("metaObject"); @@ -366,13 +350,7 @@ void generateClassDecl(QTextStream &out, const QMetaObject *mo, functions << propertyName; if (property.isWritable()) { - QByteArray setter(propertyName); - if (isupper(setter.at(0))) { - setter = "Set" + setter; - } else { - setter[0] = char(toupper(setter[0])); - setter = "set" + setter; - } + const QByteArray setter = setterName(propertyName); out << indent << "inline " << "void "; if (category & OnlyInlines) @@ -558,168 +536,10 @@ void generateClassDecl(QTextStream &out, const QMetaObject *mo, } } -#define addStringIdx(string) \ - out << stridx(string) << ", "; - -// The following functions were copied from moc generator with only some minor changes -void strreg(const QByteArray &s) -{ - if (!stringIndex.contains(s)) { - stringIndex.insert(s, strings.size()); - strings.append(s); - } -} - -void strDetachAndRegister(QByteArray s) -{ - s.detach(); - strreg(s); -} - -int stridx(const QByteArray &s) -{ - int i = stringIndex.value(s); - Q_ASSERT_X(i != -1, Q_FUNC_INFO, "We forgot to register some strings"); - return i; -} - -const char *metaTypeEnumValueString(int type) -{ -#define RETURN_METATYPENAME_STRING(MetaTypeName, MetaTypeId, RealType) \ - case QMetaType::MetaTypeName: return #MetaTypeName; - - switch (type) { -QT_FOR_EACH_STATIC_TYPE(RETURN_METATYPENAME_STRING) - } -#undef RETURN_METATYPENAME_STRING - return nullptr; -} - -int nameToBuiltinType(const QByteArray &name) -{ - if (name.isEmpty()) - return 0; - - const int tp = QMetaType::type(name.constData()); - return tp < QMetaType::User ? tp : QMetaType::UnknownType; -} - -void copyFileToStream(QFile *file, QTextStream *stream) -{ - file->seek(0); - QByteArray buffer; - const int bufferSize = 4096 * 1024; - buffer.resize(bufferSize); - while (!file->atEnd()) { - const int bytesRead = static_cast<int>(file->read(buffer.data(), bufferSize)); - if (bytesRead < bufferSize) { - buffer.resize(bytesRead); - *stream << buffer; - buffer.resize(bufferSize); - } else { - *stream << buffer; - } - } -} - -void generateTypeInfo(QTextStream &out, const QByteArray &typeName) -{ - if (QtPrivate::isBuiltinType(typeName)) { - int type; - QByteArray valueString; - if (typeName == "qreal") { - type = QMetaType::UnknownType; - valueString = "QReal"; - } else { - type = nameToBuiltinType(typeName); - valueString = metaTypeEnumValueString(type); - } - if (!valueString.isEmpty()) { - out << "QMetaType::" << valueString; - } else { - Q_ASSERT(type != QMetaType::UnknownType); - out << type; - } - } else { - Q_ASSERT(!typeName.isEmpty()); - out << "0x80000000 | " << stridx(typeName); - } -} -// End functions copied from moc generator - -void generateMethods(QTextStream &out, const QMetaObject *mo, const QMetaMethod::MethodType funcType, int ¶msIndex) -{ - out << "// "; - MethodFlags funcTypeFlag; - if (funcType == QMetaMethod::Signal) { - out << "signal"; - funcTypeFlag = MethodSignal; - } else { - out << "slot"; - funcTypeFlag = MethodSlot; - } - out << ": name, argc, parameters, tag, flags" << Qt::endl; - - int methodCount = mo->methodCount(); - for (int i = mo->methodOffset(); i < methodCount; ++i) { - const QMetaMethod method(mo->method(i)); - if (method.methodType() != funcType) - continue; - out << " "; - addStringIdx(method.name()); - out << method.parameterCount() << ", "; - out << paramsIndex << ", "; - addStringIdx(method.tag()); - out << (AccessProtected | method.attributes() | funcTypeFlag) << ',' << Qt::endl; - paramsIndex += 1 + method.parameterCount() * 2; - } - out << Qt::endl; -} - -void generateMethodParameters(QTextStream &out, const QMetaObject *mo, const QMetaMethod::MethodType funcType) -{ - out << "// "; - if (funcType == QMetaMethod::Signal) - out << "signal"; - else if (funcType == QMetaMethod::Slot) - out << "slot"; - out << ": parameters" << Qt::endl; - - int methodCount = mo->methodCount(); - for (int i = mo->methodOffset(); i < methodCount; ++i) { - const QMetaMethod method(mo->method(i)); - if (method.methodType() != funcType) - continue; - - out << " "; - - int argsCount = method.parameterCount(); - - // Return type - generateTypeInfo(out, method.typeName()); - out << ','; - - // Parameter types - const auto parameterTypes = method.parameterTypes(); - for (int j = 0; j < argsCount; ++j) { - out << ' '; - generateTypeInfo(out, parameterTypes.at(j)); - out << ','; - } - - // Parameter names - const auto parameterNames = method.parameterNames(); - for (int j = 0; j < argsCount; ++j) - out << ' ' << stridx(parameterNames.at(j)) << ','; - - out << Qt::endl; - } - out << Qt::endl; -} - -void generateClassImpl(QTextStream &out, const QMetaObject *mo, const QByteArray &className, +bool generateClassImpl(QTextStream &out, const QMetaObject *mo, const QByteArray &className, const QString &controlID, - const QByteArray &nameSpace, ObjectCategories category) + const QByteArray &nameSpace, ObjectCategories category, + QString *errorString) { Q_STATIC_ASSERT_X(QMetaObjectPrivate::OutputRevision == 8, "dumpcpp should generate the same version as moc"); @@ -727,203 +547,20 @@ void generateClassImpl(QTextStream &out, const QMetaObject *mo, const QByteArray if (!nameSpace.isEmpty()) qualifiedClassName = nameSpace + "::"; qualifiedClassName += className; - QByteArray qualifiedClassNameIdentifier = qualifiedClassName; - qualifiedClassNameIdentifier.replace(':', '_'); - - int allClassInfoCount = mo->classInfoCount(); - int allMethodCount = mo->methodCount(); - int allPropertyCount = mo->propertyCount(); - int allEnumCount = mo->enumeratorCount(); - - int thisClassInfoCount = allClassInfoCount - mo->classInfoOffset(); - int thisEnumCount = allEnumCount - mo->enumeratorOffset(); - int thisMethodCount = allMethodCount - mo->methodOffset(); - int thisPropertyCount = allPropertyCount - mo->propertyOffset(); - - int signalCount = 0; - int slotCount = 0; - int combinedParameterCount = 0; - int enumStart = MetaObjectPrivateFieldCount; - - // Register strings - strreg(qualifiedClassName); - for (int i = mo->classInfoOffset(); i < allClassInfoCount; ++i) { - const QMetaClassInfo classInfo = mo->classInfo(i); - strreg(classInfo.name()); - strreg(classInfo.value()); - } - for (int i = mo->methodOffset(); i < allMethodCount; ++i) { - const QMetaMethod method(mo->method(i)); - if (method.methodType() == QMetaMethod::Signal) - signalCount++; - if (method.methodType() == QMetaMethod::Slot) - slotCount++; - int argsCount = method.parameterCount(); - combinedParameterCount += argsCount; - - strDetachAndRegister(method.name()); - QByteArray typeName = method.typeName(); - if (!QtPrivate::isBuiltinType(typeName)) - strreg(typeName); - strreg(method.tag()); - - const auto parameterNames = method.parameterNames(); - const auto parameterTypes = method.parameterTypes(); - for (int j = 0; j < argsCount; ++j) { - if (!QtPrivate::isBuiltinType(parameterTypes.at(j))) - strDetachAndRegister(parameterTypes.at(j)); - strDetachAndRegister(parameterNames.at(j)); - } - } - for (int i = mo->propertyOffset(); i < allPropertyCount; ++i) { - const QMetaProperty property = mo->property(i); - strreg(property.name()); - if (!QtPrivate::isBuiltinType(property.typeName())) - strreg(property.typeName()); - } - for (int i = mo->enumeratorOffset(); i < allEnumCount; ++i) { - const QMetaEnum enumerator = mo->enumerator(i); - strreg(enumerator.name()); - for (int j = 0; j < enumerator.keyCount(); ++j) - strreg(enumerator.key(j)); - } - - // Build data array - out << "static const uint qt_meta_data_" << qualifiedClassNameIdentifier << "[] = {" << Qt::endl; - out << Qt::endl; - out << " // content:" << Qt::endl; - out << " 7, // revision" << Qt::endl; - out << " "; - addStringIdx(qualifiedClassName); - out << " // classname" << Qt::endl; - out << " " << thisClassInfoCount << ", " << (thisClassInfoCount ? enumStart : 0) << ", // classinfo" << Qt::endl; - enumStart += thisClassInfoCount * 2; - out << " " << thisMethodCount << ", " << (thisMethodCount ? enumStart : 0) << ", // methods" << Qt::endl; - enumStart += thisMethodCount * 5; - int paramsIndex = enumStart; - enumStart += (combinedParameterCount * 2); // parameter types + names - enumStart += thisMethodCount; // return types - out << " " << thisPropertyCount << ", " << (thisPropertyCount ? enumStart : 0) << ", // properties" << Qt::endl; - enumStart += thisPropertyCount * 3; - out << " " << thisEnumCount << ", " << (thisEnumCount ? enumStart : 0) << ", // enums/sets" << Qt::endl; - out << " 0, 0, // constructors" << Qt::endl; - out << " 0, // flags" << Qt::endl; - out << " " << signalCount << ", // signal count" << Qt::endl; - out << Qt::endl; - - if (thisClassInfoCount) { - out << " // classinfo: key, value" << Qt::endl; - for (int i = mo->classInfoOffset(); i < allClassInfoCount; ++i) { - QMetaClassInfo classInfo = mo->classInfo(i); - out << " "; - addStringIdx(classInfo.name()); - addStringIdx(classInfo.value()); - out << Qt::endl; - } - out << Qt::endl; - } - - // Signal/Slot arrays - if (signalCount) - generateMethods(out, mo, QMetaMethod::Signal, paramsIndex); - if (slotCount) - generateMethods(out, mo, QMetaMethod::Slot, paramsIndex); - - // Method parameter arrays - if (signalCount) - generateMethodParameters(out, mo, QMetaMethod::Signal); - if (slotCount) - generateMethodParameters(out, mo, QMetaMethod::Slot); - - if (thisPropertyCount) { - out << " // properties: name, type, flags" << Qt::endl; - for (int i = mo->propertyOffset(); i < allPropertyCount; ++i) { - QMetaProperty property = mo->property(i); - out << " "; - addStringIdx(property.name()); - generateTypeInfo(out, property.typeName()); - out << ", "; - - uint flags = 0; - const auto vartype = property.type(); - if (vartype != QVariant::Invalid && vartype != QVariant::UserType) - flags = uint(vartype) << 24; - - if (property.isReadable()) - flags |= Readable; - if (property.isWritable()) - flags |= Writable; - if (property.isEnumType()) - flags |= EnumOrFlag; - if (property.isDesignable()) - flags |= Designable; - if (property.isScriptable()) - flags |= Scriptable; - if (property.isStored()) - flags |= Stored; - if (property.isEditable()) - flags |= Editable; - - out << "0x" << QString::number(flags, 16).rightJustified(8, QLatin1Char('0')) - << ", \t\t // " << property.typeName() << ' ' << property.name() - << Qt::endl; - } - out << Qt::endl; - } - - if (thisEnumCount) { - out << " // enums: name, flags, count, data" << Qt::endl; - enumStart += thisEnumCount * 4; - for (int i = mo->enumeratorOffset(); i < allEnumCount; ++i) { - QMetaEnum enumerator = mo->enumerator(i); - out << " "; - addStringIdx(enumerator.name()); - out << (enumerator.isFlag() ? "0x1" : "0x0") << ", " << enumerator.keyCount() << ", " << enumStart << ", " << Qt::endl; - enumStart += enumerator.keyCount() * 2; - } - out << Qt::endl; - out << " // enum data: key, value" << Qt::endl; - for (int i = mo->enumeratorOffset(); i < allEnumCount; ++i) { - QMetaEnum enumerator = mo->enumerator(i); - for (int j = 0; j < enumerator.keyCount(); ++j) { - out << " "; - addStringIdx(enumerator.key(j)); - out << "uint("; - if (nameSpace.isEmpty()) - out << className << "::"; - else - out << nameSpace << "::"; - out << enumerator.key(j) << ")," << Qt::endl; - } - } + const QString moCode = mocCode(mo, QLatin1String(qualifiedClassName), + category.testFlag(ActiveX) ? QLatin1String("QWidget") : QLatin1String("QObject"), + errorString); + if (moCode.isEmpty()) { + out << "#error moc error\n"; + return false; } - out << " 0 // eod" << Qt::endl; - out << "};" << Qt::endl; - out << Qt::endl; - formatConstructorBody(out, className, controlID, category); + out << moCode << "\n\n"; - out << "const QMetaObject " << className << "::staticMetaObject = {" << Qt::endl; - if (category & ActiveX) - out << "{ &QWidget::staticMetaObject," << Qt::endl; - else - out << "{ &QObject::staticMetaObject," << Qt::endl; - out << "qt_meta_stringdata_all.data," << Qt::endl; - out << "qt_meta_data_" << qualifiedClassNameIdentifier << ", nullptr, nullptr, nullptr }" << Qt::endl; - out << "};" << Qt::endl; - out << Qt::endl; + formatConstructorBody(out, nameSpace, className, controlID, category); - out << "void *" << className << "::qt_metacast(const char *_clname)" << Qt::endl; - out << '{' << Qt::endl; - out << " if (!_clname) return nullptr;" << Qt::endl; - out << " if (!strcmp(_clname, \"" << qualifiedClassName << "\"))" << Qt::endl; - out << " return static_cast<void*>(const_cast<" << className << "*>(this));" << Qt::endl; - if (category & ActiveX) - out << " return QAxWidget::qt_metacast(_clname);" << Qt::endl; - else - out << " return QAxObject::qt_metacast(_clname);" << Qt::endl; - out << '}' << Qt::endl; + return true; } static void formatCommentBlockFooter(const QString &typeLibFile, QTextStream &str) @@ -1020,12 +657,8 @@ bool generateTypeLibrary(QString typeLibFile, QString outname, QMetaObject *namespaceObject = qax_readEnumInfo(typelib, nullptr); - QTemporaryFile classImplFile; - if (!classImplFile.open()) { - qWarning("dumpcpp: Cannot open temporary file."); - return false; - } - QTextStream classImplOut(&classImplFile); + QString classImpl; + QTextStream classImplOut(&classImpl); QFile implFile(outname + QLatin1String(".cpp")); QTextStream implOut(&implFile); if (!(category & (NoMetaObject|NoImplementation))) { @@ -1043,8 +676,6 @@ bool generateTypeLibrary(QString typeLibFile, QString outname, implOut << "#include \"" << outname << ".h\"" << Qt::endl; implOut << "#include <OAIdl.h>" << Qt::endl; // For IDispatch implOut << Qt::endl; - implOut << "using namespace " << libName << ';' << Qt::endl; - implOut << Qt::endl; } QFile declFile(outname + QLatin1String(".h")); @@ -1129,7 +760,6 @@ bool generateTypeLibrary(QString typeLibFile, QString outname, default: break; } - qax_deleteMetaObject(metaObject); typeinfo->ReleaseTypeAttr(typeattr); typeinfo->Release(); @@ -1282,9 +912,14 @@ bool generateTypeLibrary(QString typeLibFile, QString outname, object_category | OnlyInlines); inlinesOut << Qt::endl; } - if (implFile.isOpen()) - generateClassImpl(classImplOut, metaObject, className, guid.toString(), libNameBa, - object_category); + if (implFile.isOpen()) { + QString errorString; + if (!generateClassImpl(classImplOut, metaObject, className, guid.toString(), libNameBa, + object_category, &errorString)) { + qWarning("%s", qPrintable(errorString)); + return false; + } + } } currentTypeInfo = nullptr; } @@ -1297,101 +932,9 @@ bool generateTypeLibrary(QString typeLibFile, QString outname, // String table generation logic was ported from moc generator, with some modifications // required to split large stringdata arrays. - if (!strings.isEmpty() && implFile.isOpen()) { - // - // Build stringdata struct - // - implOut << "struct qt_meta_stringdata_all_t {" << Qt::endl; - implOut << " QByteArrayData data[" << strings.size() << "];" << Qt::endl; - - QVector<QByteArrayList> listVector; - QByteArrayList currentList; - - int currentTableLen = 0; - for (const auto &s : strings) { - currentTableLen += s.length() + 1; - currentList.append(s); - // Split strings into chunks less than 64k to work around compiler limits. - if (currentTableLen > 60000) { - implOut << " char stringdata" << listVector.size() << '[' << currentTableLen + 1 << "];" << Qt::endl; - listVector.append(currentList); - currentList.clear(); - currentTableLen = 0; - } - } - implOut << " char stringdata" << listVector.size() << '[' << currentTableLen + 1 << "];" << Qt::endl; - implOut << "};" << Qt::endl; - listVector.append(currentList); - - // Macro that expands into a QByteArrayData. The offset member is - // calculated from 1) the offset of the actual characters in the - // stringdata.stringdata member, and 2) the stringdata.data index of the - // QByteArrayData being defined. This calculation relies on the - // QByteArrayData::data() implementation returning simply "this + offset". - implOut << "#define QT_MOC_LITERAL(idx, ofs, len, table) \\" << Qt::endl - << " Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \\" << Qt::endl - << " offsetof(qt_meta_stringdata_all_t, stringdata##table) + ofs \\" << Qt::endl - << " - idx * sizeof(QByteArrayData) \\" << Qt::endl - << " )" << Qt::endl; - - implOut << "static const qt_meta_stringdata_all_t qt_meta_stringdata_all = {" << Qt::endl; - implOut << " {" << Qt::endl; - - int totalStringCount = 0; - for (int i = 0; i < listVector.size(); ++i) { - int idx = 0; - for (int j = 0; j < listVector[i].size(); j++) { - if (totalStringCount) - implOut << ',' << Qt::endl; - const QByteArray &str = listVector[i].at(j); - implOut << "QT_MOC_LITERAL(" << totalStringCount++ << ", " << idx << ", " << str.length() << ", " << i << ')'; - idx += str.length() + 1; - } - } - implOut << Qt::endl << " }"; - - // - // Build stringdata arrays - // - for (const auto &l : listVector) { - int col = 0; - int len = 0; - implOut << ',' << Qt::endl; - implOut << " \""; - for (const auto &s : l) { - len = s.length(); - if (col && col + len >= 150) { - implOut << '"' << Qt::endl << " \""; - col = 0; - } else if (len && s.at(0) >= '0' && s.at(0) <= '9') { - implOut << "\"\""; - len += 2; - } - int idx = 0; - while (idx < s.length()) { - if (idx > 0) { - col = 0; - implOut << '"' << Qt::endl << " \""; - } - int spanLen = qMin(150, s.length() - idx); - implOut << s.mid(idx, spanLen); - idx += spanLen; - col += spanLen; - } - - implOut << "\\0"; - col += len + 2; - } - implOut << '"'; - } - // Terminate stringdata struct - implOut << Qt::endl << "};" << Qt::endl; - - implOut << "#undef QT_MOC_LITERAL" << Qt::endl << Qt::endl; - + if (implFile.isOpen()) { classImplOut.flush(); - copyFileToStream(&classImplFile, &implOut); - implOut << Qt::endl; + implOut << classImpl << Qt::endl; } qax_deleteMetaObject(namespaceObject); diff --git a/tools/dumpcpp/moc.cpp b/tools/dumpcpp/moc.cpp new file mode 100644 index 0000000..e405b0a --- /dev/null +++ b/tools/dumpcpp/moc.cpp @@ -0,0 +1,300 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "moc.h" + +#include <QDir> +#include <QMetaObject> +#include <QMetaProperty> +#include <QProcess> +#include <QTemporaryFile> +#include <QTextStream> + +QT_BEGIN_NAMESPACE + +QByteArray setterName(const QByteArray &propertyName) +{ + QByteArray setter(propertyName); + if (isupper(setter.at(0))) { + setter = "Set" + setter; + } else { + setter[0] = char(toupper(setter[0])); + setter = "set" + setter; + } + return setter; +} + +void formatCppEnum(QTextStream &str, const QMetaEnum &metaEnum) +{ + str << " enum " << metaEnum.name() << " {" << Qt::endl; + for (int k = 0, last = metaEnum.keyCount() - 1; k <= last; ++k) { + QByteArray key(metaEnum.key(k)); + str << " " << key.leftJustified(24) << "= " << metaEnum.value(k); + if (k < last) + str << ','; + str << Qt::endl; + } + str << " };" << Qt::endl; +} + +void formatCppEnums(QTextStream &str, const QMetaObject *mo, + const char *qEnumDecl = nullptr /* Q_ENUM, Q_ENUM_NS */) +{ + const int offset = mo->enumeratorOffset(); + const int count = mo->enumeratorCount(); + for (int e = offset; e < count; ++e) { + const auto me = mo->enumerator(e); + formatCppEnum(str, me); + if (qEnumDecl) + str << " " << qEnumDecl << '(' << me.name() << ")\n"; + str << '\n'; + } + if (offset < count) + str << '\n'; +} + +static void formatCppMethods(QTextStream &str, const QMetaObject *mo, + QMetaMethod::MethodType filter) +{ + for (int m = mo->methodOffset(), count = mo->methodCount(); m < count; ++m) { + const auto &mt = mo->method(m); + if (mt.methodType() == filter) + str << " " << mt.typeName() << ' ' << mt.methodSignature() << ";\n"; + } +} + +static void formatCppProperty(QTextStream &str, const QMetaProperty &p) +{ + str << " Q_PROPERTY(" << p.typeName() << ' ' << p.name() + << " READ " << p.name(); + if (p.isWritable()) + str << " WRITE " << setterName(p.name()); + if (p.hasNotifySignal()) + str << " NOTIFY " << p.notifySignal().name(); + if (p.isUser()) + str << " USER true"; + if (!p.isDesignable()) + str << " DESIGNABLE false"; + if (!p.isStored()) + str << " STORED false"; + if (p.isFinal()) + str << " FINAL"; + str << ")\n"; +} + +static void formatCppQuotedString(QTextStream &str, const char *s) +{ + str << '"'; + for ( ; *s ; ++s) { + const char c = *s; + if (c == '\\' || c == '\"') + str << '\\'; + str << c; + } + str << '"'; +} + +// Generate C++ code from an ActiveQt QMetaObject to be parsed by moc +static QString mocHeader(const QMetaObject *mo, const QStringList &name, + const QString &baseClass) +{ + QString result; + QTextStream str(&result); + + str << "#pragma once\n\n"; + if (!baseClass.isEmpty()) + str << "#include <" << baseClass << ">\n"; + str << "#include <qt_windows.h>\n\n"; + + for (int n = 0, count = name.size() - 1; n < count; ++n) + str << "namespace " << name.at(n) << " {\n"; + + str << "\nclass " << name.constLast(); + if (!baseClass.isEmpty()) + str << " : public " << baseClass; + str<< "\n{\n Q_OBJECT\n"; + + for (int i = mo->classInfoOffset(), count = mo->classInfoCount(); i < count; ++i) { + const auto &info = mo->classInfo(i); + str << " Q_CLASSINFO("; + formatCppQuotedString(str, info.name()); + str << ", "; + formatCppQuotedString(str, info.value()); + str << ")\n"; + } + + for (int p = mo->propertyOffset(), count = mo-> propertyCount(); p < count; ++p) + formatCppProperty(str, mo->property(p)); + + str << "public:\n"; + + formatCppEnums(str, mo, "Q_ENUM"); + + formatCppMethods(str, mo, QMetaMethod::Constructor); + str << "\nQ_SIGNALS:\n"; + formatCppMethods(str, mo, QMetaMethod::Signal); + str << "\npublic Q_SLOTS:\n"; + formatCppMethods(str, mo, QMetaMethod::Slot); + str << "};\n"; + + for (int n = name.size() - 1; n >= 0 ; --n) + str << "} // namespace " << name.at(n) << '\n'; + + return result; +} + +static QString processOutput(QByteArray output) +{ + for (int c = output.size() - 1; c >= 0; --c) { + if (output.at(c) == '\r') + output.remove(c, 1); + } + return QString::fromUtf8(output); +} + +static QString runProcess(const QString &binary, const QStringList &args, + QString *errorString) +{ + QProcess process; + process.start(binary, args); + if (!process.waitForStarted()) { + *errorString = QLatin1String("Cannot start ") + binary + QLatin1String(": ") + process.errorString(); + return QString(); + } + if (!process.waitForFinished()) { + *errorString = binary + QLatin1String(" timed out: ") + process.errorString(); + return QString(); + } + if (process.exitStatus() != QProcess::NormalExit) { + *errorString = binary + QLatin1String(" crashed: ") + process.errorString(); + return QString(); + } + if (process.exitCode() != 0) { + *errorString = binary + QLatin1String(" failed: ") + processOutput(process.readAllStandardError()); + return QString(); + } + return processOutput(process.readAllStandardOutput()); +} + +static int lineStart(int pos, const QString *s) +{ + const int lineStart = s->lastIndexOf(QLatin1Char('\n'), pos); + return lineStart >= 0 ? lineStart + 1 : 0; +} + +static int nextLineFeed(int pos, const QString *s) +{ + const int nextLineStart = s->indexOf(QLatin1Char('\n'), pos); + return nextLineStart >= 0 ? nextLineStart : s->size(); +} + +static void removeLines(const QString &start, const QString &end, + QString *s, bool keepEnd = false) +{ + int startPos = s->indexOf(start); + if (startPos < 0) + return; + int endPos = s->indexOf(end, startPos + start.size()); + if (endPos < 0) + return; + + startPos = lineStart(startPos, s); + endPos = keepEnd + ? lineStart(endPos, s) + : nextLineFeed(endPos + end.size(), s); + s->remove(startPos, endPos - startPos); +} + +static QString cleanCode(QString code, const QString &className, const QString &headerFileName) +{ + // remove include of temp file + code.remove(QLatin1String("#include \"") + headerFileName + QLatin1String("\"\n")); + + const char *removeFunctions[] = {"metaObject", "qt_metacall", "qt_static_metacall"}; + + const QString funcStart = className + QLatin1String("::"); + const QString nextFuncStart = QLatin1String("\n}"); + for (auto function : removeFunctions) + removeLines(funcStart + QLatin1String(function) + QLatin1Char('('), nextFuncStart, &code); + + // qt_static_metacall is not implemented, cannot access private function of QAxObject + code.replace(QLatin1String(" qt_static_metacall,"), QLatin1String(" nullptr,")); + + // Remove internal signals + removeLines(QLatin1String("// SIGNAL 0"), QLatin1String("QT_WARNING_POP"), &code, true); + + // Fix enum uint(Namespace::Class::Value) -> uint(Namespace::Value) (dumpcpp convention) + const QString enumPrefix = QLatin1String("uint("); + QString parentName = className; + const int lastSep = parentName.lastIndexOf(QLatin1String("::")); + if (lastSep >= 0) + parentName.truncate(lastSep); + else + parentName.clear(); + code.replace(enumPrefix + className + QLatin1String("::"), + enumPrefix + parentName + QLatin1String("::")); + return code; +} + +QString mocCode(const QMetaObject *mo, const QString &qualifiedClassName, + QString baseClass, QString *errorString) +{ + QStringList name = qualifiedClassName.split(QLatin1String("::")); + if (name.isEmpty()) + name.append(QLatin1String(mo->className())); + + if (baseClass.isEmpty()) { + if (const auto sc = mo->superClass()) + baseClass = QLatin1String(sc->className()); + } + + const QString tempPattern = QDir::tempPath() + QLatin1Char('/') + + name.constLast().toLower() + QLatin1String("_XXXXXX.h"); + QTemporaryFile header(tempPattern); + if (!header.open()) { + *errorString = QLatin1String("Cannot open temporary file: ") + header.errorString(); + return QString(); + } + const QString headerCode = mocHeader(mo, name, baseClass); + header.write(headerCode.toUtf8()); + const QString headerFileName = header.fileName(); + header.close(); + + const QString binary = QLatin1String("moc.exe"); + + QString result = runProcess(binary, {header.fileName()}, errorString); + if (result.isEmpty()) { + errorString->append(QLatin1String("\n\nOffending code:\n")); + errorString->append(headerCode); + return result; + } + + return cleanCode(result, name.join(QLatin1String("::")), headerFileName); +} + +QT_END_NAMESPACE diff --git a/tools/dumpcpp/moc.h b/tools/dumpcpp/moc.h new file mode 100644 index 0000000..30a5030 --- /dev/null +++ b/tools/dumpcpp/moc.h @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef __MOC__ +#define __MOC__ + +#include <QString> + +QT_FORWARD_DECLARE_CLASS(QMetaEnum); +QT_FORWARD_DECLARE_CLASS(QTextStream); + +QT_BEGIN_NAMESPACE + +QByteArray setterName(const QByteArray &propertyName); + +void formatCppEnum(QTextStream &str, const QMetaEnum &metaEnum); + +QString mocCode(const QMetaObject *, const QString &qualifiedClassName, + QString baseClass, QString *errorString); + +QT_END_NAMESPACE + +#endif // __MOC__ diff --git a/tools/dumpdoc/CMakeLists.txt b/tools/dumpdoc/CMakeLists.txt new file mode 100644 index 0000000..5ee059e --- /dev/null +++ b/tools/dumpdoc/CMakeLists.txt @@ -0,0 +1,18 @@ +# Generated from dumpdoc.pro. + +##################################################################### +## dumpdoc Tool: +##################################################################### + +qt_add_tool(dumpdoc + TOOLS_TARGET AxContainer # special case + SOURCES + main.cpp + PUBLIC_LIBRARIES + Qt::AxContainer + Qt::Gui + Qt::Widgets +) + +#### Keys ignored in scope 1:.:.:dumpdoc.pro:<TRUE>: +# QMAKE_TARGET_DESCRIPTION = "Active Qt DumpDoc" diff --git a/tools/testcon/CMakeLists.txt b/tools/testcon/CMakeLists.txt new file mode 100644 index 0000000..1a34519 --- /dev/null +++ b/tools/testcon/CMakeLists.txt @@ -0,0 +1,53 @@ +# Generated from testcon.pro. + +##################################################################### +## testcon Binary: +##################################################################### + +qt_add_executable(testcon + GUI +# OUTPUT_DIRECTORY "$$[QT_INSTALL_BINS]" # special case +# INSTALL_DIRECTORY "$$[QT_INSTALL_BINS]" # special case + SOURCES + ambientproperties.cpp ambientproperties.h ambientproperties.ui + changeproperties.cpp changeproperties.h changeproperties.ui + controlinfo.cpp controlinfo.h controlinfo.ui + docuwindow.cpp docuwindow.h + invokemethod.cpp invokemethod.h invokemethod.ui + main.cpp + mainwindow.cpp mainwindow.h mainwindow.ui + PUBLIC_LIBRARIES + Qt::AxContainer + Qt::AxContainerPrivate + Qt::AxServer + Qt::Gui + Qt::PrintSupport + Qt::Widgets + ENABLE_AUTOGEN_TOOLS + uic +) + +# Resources: +set(testcon_resource_files + "images/controlmethods.png" + "images/controlproperties.png" + "images/filenew.png" +) + +qt_add_resource(testcon "testcon" + PREFIX + "/" + FILES + ${testcon_resource_files} +) + + +#### Keys ignored in scope 1:.:.:testcon.pro:<TRUE>: +# RC_FILE = "testcon.rc" +# TEMPLATE = "app" + +## Scopes: +##################################################################### + +#### Keys ignored in scope 2:.:.:testcon.pro:NOT mingw: +# QMAKE_POST_LINK = "midl" "$$shell_quote($$shell_path $$PWD/testcon.idl)" "&&" "move" "testcon.tlb" "$(TARGETDIR)" diff --git a/tools/testcon/changeproperties.cpp b/tools/testcon/changeproperties.cpp index e3356ed..966b5f1 100644 --- a/tools/testcon/changeproperties.cpp +++ b/tools/testcon/changeproperties.cpp @@ -34,7 +34,7 @@ #include <QtCore/QMetaObject> #include <QtCore/QMetaProperty> #include <QtCore/QRegularExpression> -#include <ActiveQt/QAxWidget> +#include <QtAxContainer/QAxWidget> QT_BEGIN_NAMESPACE diff --git a/tools/testcon/invokemethod.cpp b/tools/testcon/invokemethod.cpp index 48dfabb..32021ea 100644 --- a/tools/testcon/invokemethod.cpp +++ b/tools/testcon/invokemethod.cpp @@ -29,8 +29,10 @@ #include "invokemethod.h" #include <qt_windows.h> -#include <ActiveQt/ActiveQt> +#include <QtAxContainer/QAxBase> #include <QtWidgets/QCompleter> +#include <QtCore/QMetaObject> +#include <QtCore/QMetaMethod> QT_BEGIN_NAMESPACE diff --git a/tools/testcon/mainwindow.cpp b/tools/testcon/mainwindow.cpp index 8e483b3..7bcc483 100644 --- a/tools/testcon/mainwindow.cpp +++ b/tools/testcon/mainwindow.cpp @@ -44,9 +44,9 @@ #include <QtCore/QDebug> #include <QtCore/QLibraryInfo> #include <QtCore/qt_windows.h> -#include <ActiveQt/QAxScriptManager> -#include <ActiveQt/QAxWidget> -#include <ActiveQt/qaxtypes.h> +#include <QtAxContainer/QAxScriptManager> +#include <QtAxContainer/QAxWidget> +#include <QtAxContainer/private/qaxbase_p.h> #include <memory> #include <sddl.h> @@ -87,7 +87,7 @@ MainWindow::MainWindow(QWidget *parent) QHBoxLayout *layout = new QHBoxLayout(Workbase); m_mdiArea = new QMdiArea(Workbase); layout->addWidget(m_mdiArea); - layout->setMargin(0); + layout->setContentsMargins(0, 0, 0, 0); connect(m_mdiArea, &QMdiArea::subWindowActivated, this, &MainWindow::updateGUI); connect(actionFileExit, &QAction::triggered, QCoreApplication::quit); @@ -584,7 +584,7 @@ void MainWindow::logSignal(const QString &signal, int argc, void *argv) auto params = static_cast<const VARIANT *>(argv); for (int a = argc-1; a >= 0; --a) { paramlist += QLatin1Char(' '); - paramlist += VARIANTToQVariant(params[a], nullptr).toString(); + paramlist += QAxBasePrivate::VARIANTToQVariant(params[a], nullptr).toString(); paramlist += a > 0 ? QLatin1Char(',') : QLatin1Char(' '); } if (argc) diff --git a/tools/testcon/mainwindow.h b/tools/testcon/mainwindow.h index 8975201..5cc605a 100644 --- a/tools/testcon/mainwindow.h +++ b/tools/testcon/mainwindow.h @@ -29,7 +29,7 @@ #ifndef MAINWINDOW_H #define MAINWINDOW_H -#include <ActiveQt/QAxSelect> +#include <QtAxContainer/QAxSelect> #include <QVector> #include "ui_mainwindow.h" diff --git a/tools/testcon/mainwindow.ui b/tools/testcon/mainwindow.ui index d18419e..ec770a9 100644 --- a/tools/testcon/mainwindow.ui +++ b/tools/testcon/mainwindow.ui @@ -626,48 +626,40 @@ <string>About Qt</string> </property> </action> - <actiongroup name="actionGroupLogging" > - <action name="actionLogSignals" > - <property name="objectName" > - <string>actionLogSignals</string> - </property> - <property name="checkable" > - <bool>true</bool> - </property> - <property name="checked" > - <bool>true</bool> - </property> - <property name="iconText" > - <string>Signals</string> - </property> - <property name="text" > - <string>&Signals</string> - </property> - </action> - <action name="actionLogProperties" > - <property name="objectName" > - <string>actionLogProperties</string> - </property> - <property name="checkable" > - <bool>true</bool> - </property> - <property name="checked" > - <bool>true</bool> - </property> - <property name="iconText" > - <string>Properties</string> - </property> - <property name="text" > - <string>&Properties</string> - </property> - </action> + <action name="actionLogSignals" > <property name="objectName" > - <string>actionGroupLogging</string> + <string>actionLogSignals</string> </property> - <property name="exclusive" > - <bool>false</bool> + <property name="checkable" > + <bool>true</bool> + </property> + <property name="checked" > + <bool>true</bool> </property> - </actiongroup> + <property name="iconText" > + <string>Signals</string> + </property> + <property name="text" > + <string>&Signals</string> + </property> + </action> + <action name="actionLogProperties" > + <property name="objectName" > + <string>actionLogProperties</string> + </property> + <property name="checkable" > + <bool>true</bool> + </property> + <property name="checked" > + <bool>true</bool> + </property> + <property name="iconText" > + <string>Properties</string> + </property> + <property name="text" > + <string>&Properties</string> + </property> + </action> </widget> <layoutdefault spacing="6" margin="11" /> </ui> diff --git a/tools/testcon/testcon.pro b/tools/testcon/testcon.pro index ead0055..f796ba9 100644 --- a/tools/testcon/testcon.pro +++ b/tools/testcon/testcon.pro @@ -1,7 +1,7 @@ TEMPLATE = app CONFIG += qaxserver_no_postlink -QT += widgets axserver axcontainer printsupport +QT += widgets axserver axcontainer axcontainer-private printsupport SOURCES = main.cpp docuwindow.cpp mainwindow.cpp invokemethod.cpp changeproperties.cpp ambientproperties.cpp controlinfo.cpp HEADERS = docuwindow.h mainwindow.h invokemethod.h changeproperties.h ambientproperties.h controlinfo.h |