cf12defd28
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
623 lines
22 KiB
CMake
623 lines
22 KiB
CMake
# SPDX-FileCopyrightText: 2019 Friedrich W. H. Kossebau <kossebau@kde.org>
|
|
#
|
|
# SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
#[=======================================================================[.rst:
|
|
ECMAddQtDesignerPlugin
|
|
----------------------
|
|
|
|
This module provides the ``ecm_add_qtdesignerplugin`` function for generating
|
|
Qt Designer plugins for custom widgets. Each of those widgets is described
|
|
using a second function ``ecm_qtdesignerplugin_widget``.
|
|
|
|
::
|
|
|
|
ecm_add_qtdesignerplugin(<target_name>
|
|
NAME <name>
|
|
WIDGETS <widgetid> [<widgetid2> [...]]
|
|
LINK_LIBRARIES <lib> [<lib2> [...]]
|
|
INSTALL_DESTINATION <install_path>
|
|
[OUTPUT_NAME <output_name>]
|
|
[DEFAULT_GROUP <group>]
|
|
[DEFAULT_HEADER_CASE <SAME_CASE|LOWER_CASE|UPPER_CASE>]
|
|
[DEFAULT_HEADER_EXTENSION <header_extension>]
|
|
[DEFAULT_ICON_DIR <icon_dir>]
|
|
[INCLUDE_FILES <include_file> [<include_file2> [...]]]
|
|
[SOURCES <src> [<src2> [...]]]
|
|
[COMPONENT <component>]
|
|
)
|
|
|
|
``NAME`` specifies the base name to use in the generated sources.
|
|
The default is <target_name>.
|
|
|
|
``WIDGETS`` specifies the widgets the plugin should support. Each widget has
|
|
to be defined before by a call of ``ecm_qtdesignerplugin_widget`` with the
|
|
respective <widgetid>, in a scope including the current call.
|
|
|
|
``LINK_LIBRARIES`` specifies the libraries to link against. This will be at
|
|
least the library providing the widget class(es).
|
|
|
|
``INSTALL_DESTINATION`` specifies where the generated plugin binary will be
|
|
installed.
|
|
|
|
``OUTPUT_NAME`` specifies the name of the plugin binary. The default is
|
|
"<target_name>".
|
|
|
|
``DEFAULT_GROUP`` specifies the default group in Qt Designer where the
|
|
widgets will be placed. The default is "Custom".
|
|
|
|
``DEFAULT_HEADER_CASE`` specifies how the name of the header is derived from
|
|
the widget class name. The default is "LOWER_CASE".
|
|
|
|
``DEFAULT_HEADER_EXTENSION`` specifies what file name extension is used for
|
|
the header file derived from the class name. The default is "h".
|
|
|
|
``DEFAULT_ICON_DIR`` specifies what file name extension is used for
|
|
the header file derived from the class name. The default is "pics".
|
|
|
|
``INCLUDE_FILES`` specifies additional include files to include with the
|
|
generated source file. This can be needed for custom code used in
|
|
initializing or creating widgets.
|
|
|
|
``SOURCES`` specifies additional source files to build the plugin from.
|
|
This can be needed to support custom code used in initializing or
|
|
creating widgets.
|
|
|
|
``COMPONENT`` specifies the installation component name with which the install
|
|
rules for the generated plugin are associated.
|
|
|
|
::
|
|
|
|
ecm_qtdesignerplugin_widget(<widgetid>
|
|
[CLASS_NAME <class_name>]
|
|
[INCLUDE_FILE <include_file>]
|
|
[CONTAINER]
|
|
[ICON <iconfile>]
|
|
[TOOLTIP <tooltip>]
|
|
[WHATSTHIS <whatsthis>]
|
|
[GROUP <group>]
|
|
[CREATE_WIDGET_CODE_FROM_VARIABLE <create_widget_code_variable>]
|
|
[INITIALIZE_CODE_FROM_VARIABLE <initialize_code_variable]
|
|
[DOM_XML_FROM_VARIABLE <dom_xml_variable>]
|
|
[IMPL_CLASS_NAME <impl_class_name>]
|
|
[CONSTRUCTOR_ARGS_CODE <constructor_args_code>]
|
|
[CONSTRUCTOR_ARGS_CODE_FROM_VARIABLE <constructor_args_code_variable>]
|
|
)
|
|
|
|
``CLASS_NAME`` specifies the name of the widget class, including namespaces.
|
|
The default is "<widgetid>".
|
|
|
|
``INCLUDE_FILE`` specifies the include file to use for the class of this
|
|
widget. The default is derived from <class_name> as configured by the
|
|
``DEFAULT_HEADER_*`` options of ``ecm_add_qtdesignerplugin``, also replacing
|
|
any namespace separators with "/".
|
|
|
|
``CONTAINER`` specifies, if set, that this widget is a container
|
|
for other widgets.
|
|
|
|
``ICON`` specifies the icon file to use as symbol for this widget.
|
|
The default is "{lowercased <class_name>}.png" in the default icons dir as
|
|
configured by the ``DEFAULT_ICON_DIR`` option of
|
|
``ecm_add_qtdesignerplugin``, if such a file exists.
|
|
|
|
``TOOLTIP`` specifies the tooltip text to use for this widget. Default is
|
|
"<class_name> Widget".
|
|
|
|
``WHATSTHIS`` specifies the What's-This text to use for this widget.
|
|
Defaults to the tooltip.
|
|
|
|
``GROUP`` specifies the group in Qt Designer where the widget will be placed.
|
|
The default is set as configured by the ``DEFAULT_GROUP`` option of
|
|
``ecm_add_qtdesignerplugin``.
|
|
|
|
``CREATE_WIDGET_CODE_FROM_VARIABLE`` specifies the variable to get from the
|
|
C++ code to use as factory code to create an instance of the widget,
|
|
for the override of
|
|
``QDesignerCustomWidgetInterface::createWidget(QWidget* parent)``.
|
|
The default is "return new <impl_class_name><constructor_args_code>;".
|
|
|
|
``INITIALIZE_CODE_FROM_VARIABLE`` specifies the variable to get from the C++
|
|
code to use with the override of
|
|
``QDesignerCustomWidgetInterface::initialize(QDesignerFormEditorInterface* core)``.
|
|
The code has to use the present class member ``m_initialized`` to track and
|
|
update the state. The default code simply sets ``m_initialized`` to
|
|
``true``, if it was not before.
|
|
|
|
``DOM_XML_FROM_VARIABLE`` specifies the variable to get from the string to
|
|
use with the optional override of
|
|
``QDesignerCustomWidgetInterface::domXml()``.
|
|
Default does not override.
|
|
|
|
``IMPL_CLASS_NAME`` specifies the name of the widget class to use for the
|
|
widget instance with Qt Designer. The default is "<class_name>".
|
|
|
|
``CONSTRUCTOR_ARGS_CODE`` specifies the C++ code to use for the constructor
|
|
arguments with the default of ``CREATE_WIDGET_CODE_FROM_VARIABLE``. Note
|
|
that the parentheses are required. The default is "(parent)".
|
|
|
|
``CONSTRUCTOR_ARGS_CODE_FROM_VARIABLE`` specifies the variable to get from
|
|
the C++ code instead of passing it directly via ``CONSTRUCTOR_ARGS_CODE``.
|
|
This can be needed if the code is more complex and e.g. includes ";" chars.
|
|
|
|
|
|
|
|
Example usage:
|
|
|
|
.. code-block:: cmake
|
|
|
|
ecm_qtdesignerplugin_widget(FooWidget
|
|
TOOLTIP "Enables to browse foo."
|
|
GROUP "Views (Foo)"
|
|
)
|
|
|
|
set(BarWidget_CREATE_WIDGET_CODE
|
|
"
|
|
auto* widget = new BarWidget(parent);
|
|
widget->setBar("Example bar");
|
|
return widget;
|
|
")
|
|
|
|
ecm_qtdesignerplugin_widget(BarWidget
|
|
TOOLTIP "Displays bars."
|
|
GROUP "Display (Foo)"
|
|
CREATE_WIDGET_CODE_FROM_VARIABLE BarWidget_CREATE_WIDGET_CODE
|
|
)
|
|
|
|
ecm_add_qtdesignerplugin(foowidgets
|
|
NAME FooWidgets
|
|
OUTPUT_NAME foo2widgets
|
|
WIDGETS
|
|
FooWidget
|
|
BarWidget
|
|
LINK_LIBRARIES
|
|
Foo::Widgets
|
|
INSTALL_DESTINATION "${KDE_INSTALL_QTPLUGINDIR}/designer"
|
|
COMPONENT Devel
|
|
)
|
|
|
|
Since 5.62.0.
|
|
#]=======================================================================]
|
|
|
|
include(FeatureSummary)
|
|
include(${CMAKE_CURRENT_LIST_DIR}/QtVersionOption.cmake)
|
|
|
|
# helper method
|
|
# escapes string for C++ code
|
|
function(_ecm_qtdesignerplugin_escape_cpp_string _varName input)
|
|
string(REPLACE "\"" "\\\"" _string ${input})
|
|
set(${_varName} "${_string}" PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
# To make the data about the widgets available to the function ecm_add_qtdesignerplugin,
|
|
# variables are created in the scope of the caller of this method, protected by
|
|
# a namespace for this macro file, and otherwise from the widget id and the property id:
|
|
# ECM_QTDESIGNERPLUGIN_${widget}_${property}
|
|
function(ecm_qtdesignerplugin_widget widget)
|
|
set(options
|
|
CONTAINER
|
|
)
|
|
set(oneValueArgs
|
|
CLASS_NAME
|
|
INCLUDE_FILE
|
|
ICON
|
|
TOOLTIP
|
|
WHATSTHIS
|
|
GROUP
|
|
CREATE_WIDGET_CODE_FROM_VARIABLE
|
|
INITIALIZE_CODE_FROM_VARIABLE
|
|
DOM_XML_FROM_VARIABLE
|
|
IMPL_CLASS_NAME
|
|
CONSTRUCTOR_ARGS_CODE
|
|
CONSTRUCTOR_ARGS_CODE_FROM_VARIABLE
|
|
)
|
|
set(multiValueArgs
|
|
)
|
|
cmake_parse_arguments(ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
|
|
|
if(NOT ARGS_CLASS_NAME)
|
|
set(ARGS_CLASS_NAME "${widget}")
|
|
endif()
|
|
if(NOT ARGS_TOOLTIP)
|
|
set(ARGS_TOOLTIP "${ARGS_CLASS_NAME} Widget")
|
|
endif()
|
|
if(NOT ARGS_WHATSTHIS)
|
|
set(ARGS_WHATSTHIS "${ARGS_TOOLTIP}")
|
|
endif()
|
|
if(ARGS_CONTAINER)
|
|
set(_is_container TRUE)
|
|
else()
|
|
set(_is_container FALSE)
|
|
endif()
|
|
if(ARGS_CONSTRUCTOR_ARGS_CODE AND ARGS_CONSTRUCTOR_ARGS_CODE_FROM_VARIABLE)
|
|
message(FATAL_ERROR "Either CONSTRUCTOR_ARGS_CODE or CONSTRUCTOR_ARGS_CODE_FROM_VARIABLE can be passed when calling ecm_qtdesignerplugin_widget().")
|
|
endif()
|
|
if(NOT ARGS_CREATE_WIDGET_CODE_FROM_VARIABLE)
|
|
if(NOT ARGS_IMPL_CLASS_NAME)
|
|
set(ARGS_IMPL_CLASS_NAME "${ARGS_CLASS_NAME}")
|
|
endif()
|
|
if(ARGS_CONSTRUCTOR_ARGS_CODE_FROM_VARIABLE)
|
|
set(_constructor_args "${${ARGS_CONSTRUCTOR_ARGS_CODE_FROM_VARIABLE}}")
|
|
elseif(ARGS_CONSTRUCTOR_ARGS_CODE)
|
|
set(_constructor_args "${ARGS_CONSTRUCTOR_ARGS_CODE}")
|
|
else()
|
|
set(_constructor_args "(parent)")
|
|
endif()
|
|
set(_create_widget_code " return new ${ARGS_IMPL_CLASS_NAME}${_constructor_args};")
|
|
else()
|
|
set(_create_widget_code "${${ARGS_CREATE_WIDGET_CODE_FROM_VARIABLE}}")
|
|
endif()
|
|
if(ARGS_ICON)
|
|
if (NOT IS_ABSOLUTE ${ARGS_ICON})
|
|
set(ARGS_ICON "${CMAKE_CURRENT_SOURCE_DIR}/${ARGS_ICON}")
|
|
endif()
|
|
if(NOT EXISTS "${ARGS_ICON}")
|
|
message(FATAL_ERROR "No such file as passed with ICON when calling ecm_qtdesignerplugin_widget(): ${ARGS_ICON}")
|
|
endif()
|
|
endif()
|
|
|
|
# store data about widget, so ecm_add_qtdesignerplugin can access it
|
|
set(ECM_QTDESIGNERPLUGIN_${widget}_CLASS_NAME "${ARGS_CLASS_NAME}" PARENT_SCOPE)
|
|
set(ECM_QTDESIGNERPLUGIN_${widget}_INCLUDE_FILE "${ARGS_INCLUDE_FILE}" PARENT_SCOPE)
|
|
set(ECM_QTDESIGNERPLUGIN_${widget}_TOOLTIP "${ARGS_TOOLTIP}" PARENT_SCOPE)
|
|
set(ECM_QTDESIGNERPLUGIN_${widget}_WHATSTHIS "${ARGS_WHATSTHIS}" PARENT_SCOPE)
|
|
set(ECM_QTDESIGNERPLUGIN_${widget}_GROUP "${ARGS_GROUP}" PARENT_SCOPE)
|
|
set(ECM_QTDESIGNERPLUGIN_${widget}_ICON "${ARGS_ICON}" PARENT_SCOPE)
|
|
set(ECM_QTDESIGNERPLUGIN_${widget}_IS_CONTAINER "${_is_container}" PARENT_SCOPE)
|
|
set(ECM_QTDESIGNERPLUGIN_${widget}_CREATE_WIDGET_CODE "${_create_widget_code}" PARENT_SCOPE)
|
|
set(ECM_QTDESIGNERPLUGIN_${widget}_INITIALIZE_CODE "${${INITIALIZE_CODE_FROM_VARIABLE}}" PARENT_SCOPE)
|
|
set(ECM_QTDESIGNERPLUGIN_${widget}_DOM_XML "${${ARGS_DOM_XML_FROM_VARIABLE}}" PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
# helper method
|
|
function(_ecm_qtdesignerplugin_write_widget designer_src_file widget default_group rc_icon_dir)
|
|
# prepare data
|
|
set(_classname "${ECM_QTDESIGNERPLUGIN_${widget}_CLASS_NAME}")
|
|
set(_factory_classname "${_classname}QtDesignerWidgetFactory")
|
|
string(REPLACE "::" "__" _factory_classname "${_factory_classname}")
|
|
set(ECM_QTDESIGNERPLUGIN_${widget}_FACTORY_CLASS_NAME "${_factory_classname}" PARENT_SCOPE)
|
|
if(ECM_QTDESIGNERPLUGIN_${widget}_IS_CONTAINER)
|
|
set(_is_container "true")
|
|
else()
|
|
set(_is_container "false")
|
|
endif()
|
|
_ecm_qtdesignerplugin_escape_cpp_string(_tooltip "${ECM_QTDESIGNERPLUGIN_${widget}_TOOLTIP}")
|
|
_ecm_qtdesignerplugin_escape_cpp_string(_whatsthis "${ECM_QTDESIGNERPLUGIN_${widget}_WHATSTHIS}")
|
|
set(_group ${ECM_QTDESIGNERPLUGIN_${widget}_GROUP})
|
|
if(NOT _group)
|
|
set(_group "${default_group}")
|
|
endif()
|
|
_ecm_qtdesignerplugin_escape_cpp_string(_group "${_group}")
|
|
set(_dom_xml "${ECM_QTDESIGNERPLUGIN_${widget}_DOM_XML}")
|
|
if(_dom_xml)
|
|
string(REPLACE "\"" "\\\"" _dom_xml "${_dom_xml}")
|
|
set(_dom_xml_method " QString domXml() const override { return QStringLiteral(\"${_dom_xml}\"); }")
|
|
else()
|
|
set(_dom_xml_method)
|
|
endif()
|
|
set(_icon "${ECM_QTDESIGNERPLUGIN_${widget}_ICON}")
|
|
if(_icon)
|
|
get_filename_component(_icon_filename ${_icon} NAME)
|
|
set(_icon_construct "QIcon(QStringLiteral(\":${rc_icon_dir}/${_icon_filename}\"))")
|
|
else()
|
|
set(_icon_construct "QIcon()")
|
|
endif()
|
|
set(_initialize_code "${ECM_QTDESIGNERPLUGIN_${widget}_INITIALIZE_CODE}")
|
|
if(NOT _initialize_code)
|
|
set(_initialize_code
|
|
" Q_UNUSED(core);
|
|
|
|
if (m_initialized) return;
|
|
|
|
m_initialized = true;"
|
|
)
|
|
endif()
|
|
|
|
# write code
|
|
file(APPEND ${designer_src_file} "
|
|
class ${_factory_classname}
|
|
: public QObject
|
|
, public QDesignerCustomWidgetInterface
|
|
{
|
|
Q_OBJECT
|
|
Q_INTERFACES(QDesignerCustomWidgetInterface)
|
|
|
|
public:
|
|
explicit ${_factory_classname}(QObject *parent = nullptr)
|
|
: QObject(parent)
|
|
, m_initialized(false)
|
|
{}
|
|
|
|
~${_factory_classname}() override {}
|
|
|
|
public: // QDesignerCustomWidgetInterface API
|
|
bool isInitialized() const override { return m_initialized; }
|
|
${_dom_xml_method}
|
|
bool isContainer() const override { return ${_is_container}; }
|
|
QIcon icon() const override { return ${_icon_construct}; }
|
|
QString group() const override { return QStringLiteral(\"${_group}\"); }
|
|
QString includeFile() const override { return QStringLiteral(\"${ECM_QTDESIGNERPLUGIN_${widget}_INCLUDE_FILE}\"); }
|
|
QString name() const override { return QStringLiteral(\"${_classname}\"); }
|
|
QString toolTip() const override { return QStringLiteral(\"${_tooltip}\"); }
|
|
QString whatsThis() const override { return QStringLiteral(\"${_whatsthis}\"); }
|
|
|
|
QWidget* createWidget(QWidget* parent) override
|
|
{
|
|
${ECM_QTDESIGNERPLUGIN_${widget}_CREATE_WIDGET_CODE}
|
|
}
|
|
|
|
void initialize(QDesignerFormEditorInterface* core) override
|
|
{
|
|
${_initialize_code}
|
|
}
|
|
|
|
private:
|
|
bool m_initialized;
|
|
};
|
|
"
|
|
)
|
|
endfunction()
|
|
|
|
# helper method
|
|
function(_ecm_qtdesignerplugin_write_icon_qrc_file rc_file rc_icon_dir)
|
|
set(_icons ${ARGN})
|
|
file(WRITE ${rc_file}
|
|
"<!DOCTYPE RCC><RCC version=\"1.0\">
|
|
<!-- DO NOT EDIT! Generated from ecm_add_qtdesignerplugin() -->
|
|
<qresource prefix=\"${rc_icon_dir}\">
|
|
"
|
|
)
|
|
foreach(_icon ${_icons})
|
|
get_filename_component(_icon_filename ${_icon} NAME)
|
|
file(APPEND ${rc_file} "<file alias=\"${_icon_filename}\">${_icon}</file>\n")
|
|
endforeach()
|
|
file(APPEND ${rc_file}
|
|
"</qresource>
|
|
</RCC>
|
|
"
|
|
)
|
|
endfunction()
|
|
|
|
# This needs to be a macro not a function because of the nested
|
|
# find_package() call, which will set some variables.
|
|
macro(ecm_add_qtdesignerplugin target)
|
|
set(options
|
|
)
|
|
set(oneValueArgs
|
|
NAME
|
|
OUTPUT_NAME
|
|
INSTALL_DESTINATION
|
|
DEFAULT_GROUP
|
|
COMPONENT
|
|
DEFAULT_HEADER_CASE
|
|
DEFAULT_HEADER_EXTENSION
|
|
DEFAULT_ICON_DIR
|
|
)
|
|
set(multiValueArgs
|
|
WIDGETS
|
|
LINK_LIBRARIES
|
|
INCLUDE_FILES
|
|
SOURCES
|
|
)
|
|
cmake_parse_arguments(ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
|
|
|
# args sanity check
|
|
if (NOT ARGS_WIDGETS)
|
|
message(FATAL_ERROR "No WIDGETS passed when calling ecm_add_qtdesignerplugin().")
|
|
endif()
|
|
foreach(_widget ${ARGS_WIDGETS})
|
|
# using _CLASS_NAME as sample property to find if defined
|
|
if (NOT ECM_QTDESIGNERPLUGIN_${_widget}_CLASS_NAME)
|
|
message(FATAL_ERROR "Undefined widget passed when calling ecm_add_qtdesignerplugin(): ${_widget}")
|
|
endif()
|
|
endforeach()
|
|
|
|
if(NOT ARGS_NAME)
|
|
set(ARGS_NAME "${target}")
|
|
endif()
|
|
if(NOT ARGS_DEFAULT_GROUP)
|
|
set(ARGS_DEFAULT_GROUP "Custom")
|
|
endif()
|
|
if(NOT ARGS_DEFAULT_HEADER_EXTENSION)
|
|
set(ARGS_DEFAULT_HEADER_EXTENSION "h")
|
|
endif()
|
|
if(NOT ARGS_DEFAULT_HEADER_CASE)
|
|
set(ARGS_DEFAULT_HEADER_CASE "LOWER_CASE")
|
|
else()
|
|
set(_allowed_values "LOWER_CASE" "UPPER_CASE" "SAME_CASE")
|
|
list(FIND _allowed_values "${ARGS_DEFAULT_HEADER_CASE}" _index)
|
|
if(_index EQUAL "-1")
|
|
message(FATAL_ERROR "Unexpected value for DEFAULT_HEADER_CASE argument to ecm_add_qtdesignerplugin(): ${ARGS_DEFAULT_HEADER_CASE}")
|
|
endif()
|
|
endif()
|
|
if(NOT ARGS_DEFAULT_ICON_DIR)
|
|
set(ARGS_DEFAULT_ICON_DIR "${CMAKE_CURRENT_SOURCE_DIR}/pics")
|
|
else()
|
|
if (NOT IS_ABSOLUTE ${ARGS_DEFAULT_ICON_DIR})
|
|
set(ARGS_DEFAULT_ICON_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${ARGS_DEFAULT_ICON_DIR}")
|
|
endif()
|
|
if(NOT EXISTS "${ARGS_DEFAULT_ICON_DIR}")
|
|
message(FATAL_ERROR "No such directory as passed with DEFAULT_ICON_DIR when calling ecm_add_qtdesignerplugin(): ${ARGS_DEFAULT_ICON_DIR}")
|
|
endif()
|
|
endif()
|
|
|
|
# Check deps
|
|
if(NOT Qt${QT_MAJOR_VERSION}UiPlugin_FOUND)
|
|
find_package(Qt${QT_MAJOR_VERSION}UiPlugin QUIET CONFIG)
|
|
set_package_properties(Qt${QT_MAJOR_VERSION}UiPlugin PROPERTIES
|
|
PURPOSE "Required to build Qt Designer plugins"
|
|
TYPE REQUIRED
|
|
)
|
|
endif()
|
|
|
|
# setup plugin only if uiplugin lib was found, as we do not abort hard the cmake run otherwise
|
|
if (Qt${QT_MAJOR_VERSION}UiPlugin_FOUND)
|
|
set(_generation_dir "${CMAKE_CURRENT_BINARY_DIR}/${target}_ECMQtDesignerPlugin")
|
|
file(MAKE_DIRECTORY "${_generation_dir}")
|
|
set(_rc_icon_dir "/${ARGS_NAME}/designer")
|
|
|
|
# process defaults for widgets
|
|
foreach(_widget ${ARGS_WIDGETS})
|
|
set(_class_name "${ECM_QTDESIGNERPLUGIN_${_widget}_CLASS_NAME}")
|
|
# include file
|
|
set(_include_file "${ECM_QTDESIGNERPLUGIN_${_widget}_INCLUDE_FILE}")
|
|
if(NOT _include_file)
|
|
set(_include_file "${_class_name}")
|
|
if (ARGS_DEFAULT_HEADER_CASE STREQUAL "LOWER_CASE")
|
|
string(TOLOWER "${_include_file}" _include_file)
|
|
elseif(ARGS_DEFAULT_HEADER_CASE STREQUAL "UPPER_CASE")
|
|
string(TOUPPER "${_include_file}" _include_file)
|
|
endif()
|
|
# turn any namespaces into dir levels
|
|
string(REPLACE "::" "/" _include_file ${_include_file})
|
|
set(ECM_QTDESIGNERPLUGIN_${_widget}_INCLUDE_FILE "${_include_file}.${ARGS_DEFAULT_HEADER_EXTENSION}")
|
|
endif()
|
|
# icon
|
|
set(_icon "${ECM_QTDESIGNERPLUGIN_${_widget}_ICON}")
|
|
if(NOT _icon)
|
|
string(TOLOWER "${_class_name}" _icon)
|
|
# handle any namespaces
|
|
string(REPLACE "::" "_" _icon "${_icon}")
|
|
set(_icon "${ARGS_DEFAULT_ICON_DIR}/${_icon}.png")
|
|
if(EXISTS "${_icon}")
|
|
set(ECM_QTDESIGNERPLUGIN_${_widget}_ICON "${_icon}")
|
|
endif()
|
|
endif()
|
|
endforeach()
|
|
|
|
set(_plugin_src_file "${_generation_dir}/designerplugin.cpp")
|
|
set(_srcs
|
|
${ARGS_SOURCES}
|
|
${_plugin_src_file}
|
|
)
|
|
|
|
set(_icons)
|
|
foreach(_widget ${ARGS_WIDGETS})
|
|
list(APPEND _icons "${ECM_QTDESIGNERPLUGIN_${_widget}_ICON}")
|
|
endforeach()
|
|
|
|
# generate qrc file with icons
|
|
if (_icons)
|
|
set(_rc_file "${_generation_dir}/designerplugin.rc")
|
|
set(_rc_work_file "${_rc_file}.work")
|
|
|
|
_ecm_qtdesignerplugin_write_icon_qrc_file("${_rc_work_file}" "${_rc_icon_dir}" ${_icons})
|
|
# avoid rebuilding if there was no change
|
|
execute_process(
|
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${_rc_work_file}" "${_rc_file}"
|
|
)
|
|
file(REMOVE "${_rc_work_file}")
|
|
|
|
if (QT_MAJOR_VERSION EQUAL "5")
|
|
qt5_add_resources(_srcs ${_rc_file})
|
|
else()
|
|
qt6_add_resources(_srcs ${_rc_file})
|
|
endif()
|
|
endif()
|
|
|
|
# generate source file
|
|
set(_collection_classname "${ARGS_NAME}QtDesignerWidgetCollection")
|
|
|
|
set(_include_files
|
|
# classes inherited
|
|
QDesignerCustomWidgetCollectionInterface
|
|
QDesignerCustomWidgetInterface
|
|
QObject
|
|
# classes used
|
|
QIcon
|
|
QString
|
|
${ARGS_INCLUDE_FILES}
|
|
)
|
|
foreach(_widget ${ARGS_WIDGETS})
|
|
list(APPEND _include_files ${ECM_QTDESIGNERPLUGIN_${_widget}_INCLUDE_FILE})
|
|
endforeach()
|
|
list(REMOVE_DUPLICATES _include_files)
|
|
|
|
set(_plugin_src_work_file "${_plugin_src_file}.work")
|
|
file(WRITE ${_plugin_src_work_file} "// DO NOT EDIT! Generated from ecm_add_qtdesignerplugin()\n\n")
|
|
foreach(_include_file ${_include_files})
|
|
if (NOT ${_include_file} MATCHES "^[\"<]")
|
|
set(_include_file "<${_include_file}>")
|
|
endif()
|
|
file(APPEND ${_plugin_src_work_file} "#include ${_include_file}\n")
|
|
endforeach()
|
|
foreach(_widget ${ARGS_WIDGETS})
|
|
_ecm_qtdesignerplugin_write_widget(${_plugin_src_work_file} ${_widget} ${ARGS_DEFAULT_GROUP} ${_rc_icon_dir})
|
|
endforeach()
|
|
file(APPEND ${_plugin_src_work_file} "
|
|
class ${_collection_classname}
|
|
: public QObject
|
|
, public QDesignerCustomWidgetCollectionInterface
|
|
{
|
|
Q_OBJECT
|
|
Q_INTERFACES(
|
|
QDesignerCustomWidgetCollectionInterface
|
|
)
|
|
|
|
Q_PLUGIN_METADATA(IID \"org.qt-project.Qt.QDesignerCustomWidgetCollectionInterface\")
|
|
|
|
public:
|
|
explicit ${_collection_classname}(QObject* parent = nullptr);
|
|
|
|
public: // QDesignerCustomWidgetCollectionInterface API
|
|
QList<QDesignerCustomWidgetInterface*> customWidgets() const override;
|
|
|
|
private:
|
|
QList<QDesignerCustomWidgetInterface*> m_widgetFactories;
|
|
};
|
|
|
|
${_collection_classname}::${_collection_classname}(QObject* parent)
|
|
: QObject(parent)
|
|
{
|
|
m_widgetFactories = QList<QDesignerCustomWidgetInterface*>{
|
|
"
|
|
)
|
|
foreach(_widget ${ARGS_WIDGETS})
|
|
file(APPEND ${_plugin_src_work_file} " new ${ECM_QTDESIGNERPLUGIN_${_widget}_FACTORY_CLASS_NAME}(this),\n")
|
|
endforeach()
|
|
file(APPEND ${_plugin_src_work_file}
|
|
" };
|
|
}
|
|
|
|
QList<QDesignerCustomWidgetInterface*> ${_collection_classname}::customWidgets() const
|
|
{
|
|
return m_widgetFactories;
|
|
}
|
|
|
|
#include \"designerplugin.moc\"
|
|
"
|
|
)
|
|
|
|
# avoid rebuilding if there was no change
|
|
execute_process(
|
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${_plugin_src_work_file}" "${_plugin_src_file}"
|
|
)
|
|
file(REMOVE "${_plugin_src_work_file}")
|
|
|
|
# setup plugin binary
|
|
add_library(${target} MODULE ${_srcs})
|
|
if(NOT WIN32)
|
|
# Since there are no libraries provided by this module,
|
|
# there is no point including the build tree in RPath,
|
|
# and then having to edit it at install time.
|
|
set_target_properties(${target} PROPERTIES
|
|
SKIP_BUILD_RPATH TRUE
|
|
BUILD_WITH_INSTALL_RPATH TRUE
|
|
)
|
|
endif()
|
|
if (ARGS_OUTPUT_NAME)
|
|
set_target_properties(${target} PROPERTIES
|
|
OUTPUT_NAME ${ARGS_OUTPUT_NAME}
|
|
)
|
|
endif()
|
|
target_link_libraries(${target} ${ARGS_LINK_LIBRARIES} Qt${QT_MAJOR_VERSION}::UiPlugin)
|
|
|
|
if (DEFINED ARGS_COMPONENT)
|
|
set(_component COMPONENT ${ARGS_COMPONENT})
|
|
else()
|
|
set(_component)
|
|
endif()
|
|
|
|
install(TARGETS ${target} DESTINATION ${ARGS_INSTALL_DESTINATION} ${_component})
|
|
endif()
|
|
endmacro()
|