// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only

/*!
    \example tools/customtype
    \title Custom Type Example

    \brief The Custom Type example shows how to integrate a custom type into Qt's
    meta-object system.

    Contents:

    \tableofcontents

    \section1 Overview

    Qt provides a range of standard value types that are used to provide
    rich and meaningful APIs. These types are integrated with the meta-object
    system, enabling them to be stored in QVariant objects, written out in
    debugging information and sent between components in signal-slot
    communication.

    Custom types can also be integrated with the meta-object system as long as
    they are written to conform to some simple guidelines. In this example, we
    introduce a simple \c Message class, we describe how we make it work with
    QVariant, and we show how it can be extended to generate a printable
    representation of itself for use in debugging output.

    \section1 The Message Class Definition

    The \c Message class is a simple value class that contains two pieces
    of information (a QString and a QStringList), each of which can be read
    using trivial getter functions:

    \snippet tools/customtype/message.h custom type definition

    The default constructor, copy constructor and destructor are
    all required, and must be public, if the type is to be integrated into the
    meta-object system. Other than this, we are free to implement whatever we
    need to make the type do what we want, so we also include a constructor
    that lets us set the type's data members.

    To enable the type to be used with QVariant, we declare it using the
    Q_DECLARE_METATYPE() macro:

    \snippet tools/customtype/message.h custom type meta-type declaration

    We do not need to write any additional code to accompany this macro.

    To allow us to see a readable description of each \c Message object when it
    is sent to the debug output stream, we define a streaming operator:

    \snippet tools/customtype/message.h custom type streaming operator

    This facility is useful if you need to insert tracing statements in your
    code for debugging purposes.

    \section1 The Message Class Implementation

    The streaming operator is implemented in the following way:

    \snippet tools/customtype/message.cpp custom type streaming operator

    Here, we want to represent each value depending on how many lines are stored
    in the message body. We stream text to the QDebug object passed to the
    operator and return the QDebug object obtained from its maybeSpace() member
    function; this is described in more detail in the
    \l{Creating Custom Qt Types#Making the Type Printable}{Creating Custom Qt Types}
    document.

    We include the code for the getter functions for completeness:

    \snippet tools/customtype/message.cpp getter functions

    With the type fully defined, implemented, and integrated with the
    meta-object system, we can now use it.

    \section1 Using the Message

    In the example's \c{main()} function, we show how a \c Message object can
    be printed to the console by sending it to the debug stream:

    \snippet tools/customtype/main.cpp printing a custom type

    You can use the type with QVariant in exactly the same way as you would
    use standard Qt value types. Here's how to store a value using the
    QVariant::setValue() function:

    \snippet tools/customtype/main.cpp storing a custom value

    Alternatively, the QVariant::fromValue() function can be used if
    you are using a compiler without support for member template
    functions.

    The value can be retrieved using the QVariant::value() member template
    function:

    \snippet tools/customtype/main.cpp retrieving a custom value

    \section1 Further Reading

    The custom \c Message type can also be used with direct signal-slot
    connections.

    To register a custom type for use with queued signals and slots, such as
    those used in cross-thread communication, see the
    \l{Queued Custom Type Example}.

    More information on using custom types with Qt can be found in the
    \l{Creating Custom Qt Types} document.
*/
