// Copyright (C) 2017 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\page qtqml-modules-qmldir.html
\title Module Definition qmldir Files
\brief Defines a QML module

There are two distinct types of \c qmldir files:
\list
\li QML document directory listing files
\li QML module definition files
\endlist

This documentation covers only the second form of \c qmldir file, which
lists the QML types, JavaScript files, and plugins that are available under a
module. For more information about the first form of \c qmldir file, see
\l{qtqml-syntax-directoryimports.html#directory-listing-qmldir-files}
{directory listing qmldir files}.

\section1 Contents of a Module Definition qmldir File

A \c qmldir file is a plain-text file that contains the following commands:

\list
    \li \l {Module Identifier Declaration}
    \li \l {Object Type Declaration}
    \li \l {Internal Object Type Declaration}
    \li \l {JavaScript Resource Declaration}
    \li \l {Plugin Declaration}
    \li \l {Plugin Classname Declaration}
    \li \l {Type Description File Declaration}
    \li \l {Module Dependencies Declaration}
    \li \l {Module Import Declaration}
    \li \l {Designer Support Declaration}
    \li \l {Preferred Path Declaration}
\endlist

\note Each command in a \c qmldir file must be on a separate line.

In addition to commands, you can also add comments, which are lines starting
with \c {#}.

\section2 Module Identifier Declaration

\code
    module <ModuleIdentifier>
\endcode

Declares the module identifier of the module. The <ModuleIdentifier> is the
(dotted URI notation) identifier for the module, which must match the module's
install path.

The \l{Identified Modules#Semantics of Identified Modules}
{module identifier directive} must be the first line of the file. Exactly one
module identifier directive may exist in the \c qmldir file.

Example:
\code
    module ExampleModule
\endcode

\section2 Object Type Declaration
\code
    [singleton] <TypeName> <InitialVersion> <File>
\endcode

Declares a \l{qtqml-typesystem-objecttypes.html}{QML object type}
to be made available by the module.
\list
    \li \c [singleton] Optional. Used to declare a singleton type.
    \li \c <TypeName> is the type being made available
    \li \c <InitialVersion> is the module version for which the type is to be
    made available
    \li \c <File> is the (relative) file name of the QML file that defines
    the type
\endlist

Zero or more object type declarations may exist in the \c qmldir
file. However, each object type must have a unique type name within
any particular version of the module.
\note To declare a \c singleton type, the QML file defining the
type must include the \c {pragma Singleton} statement.

Example:
\code
    //Style.qml with custom singleton type definition
    pragma Singleton
    import QtQuick 2.0

    QtObject {
        property int textSize: 20
        property color textColor: "green"
    }

    // qmldir declaring the singleton type
    module CustomStyles
    singleton Style 1.0 Style.qml

    // singleton type in use
    import QtQuick 2.0
    import CustomStyles 1.0

    Text {
        font.pixelSize: Style.textSize
        color: Style.textColor
        text: "Hello World"
    }
\endcode

\section2 Internal Object Type Declaration

\code
    internal <TypeName> <File>
\endcode

Declares an object type that is in the module but should not be
made available to users of the module.

Zero or more internal object type declarations may exist in the
\c qmldir file.

Example:
\code
    internal MyPrivateType MyPrivateType.qml
\endcode

This is necessary if the module is imported remotely
(see \l{Identified Modules#Remotely Installed Identified Modules}
{Remotely Installed Identified Modules}) because if an exported type depends
on a non-exported type within the module, the engine must also
load the non-exported type.

\section2 JavaScript Resource Declaration

\code
    <ResourceIdentifier> <InitialVersion> <File>
\endcode

Declares a JavaScript file to be made available by the module.
The resource will be made available via the specified identifier
with the specified version number.

Zero or more JavaScript resource declarations may exist in the
\c qmldir file. However, each JavaScript resource must have a unique
identifier within any particular version of the module.

Example:
\code
    MyScript 1.0 MyScript.js
\endcode

See the documentation about \l{qtqml-javascript-resources.html}
{defining JavaScript resources} and
\l{qtqml-javascript-imports.html}
{Importing JavaScript Resources In QML} for more information.

\section2 Plugin Declaration

\code
    [optional] plugin <Name> [<Path>]
\endcode

Declares a plugin to be made available by the module.

\list
    \li \c optional denotes that the plugin itself does not contain
        any relevant code and only serves to load a library it links
        to. If given, and if any types for the module are already
        available, indicating that the library has been loaded by some
        other means, QML will not load the plugin.
    \li \c <Name> is the plugin library name. This is usually not the
        same as the file name of the plugin binary, which is platform
        dependent. For example, the library \c MyAppTypes would produce
        \c libMyAppTypes.so on Linux and \c MyAppTypes.dll on Windows.
    \li \c <Path> (optional) specifies either:
        \list
            \li an absolute path to the directory containing the plugin
            file, or
            \li a relative path from the directory containing the \c qmldir
            file to the directory containing the plugin file.
        \endlist
\endlist

By default, the engine searches for the plugin library in the
directory that contains the \c qmldir file. (The plugin search
path can be queried with QQmlEngine::pluginPathList() and
modified using QQmlEngine::addPluginPath().)

Zero or more C++ plugin declarations may exist in the \c qmldir
file. However, since plugin loading is a relatively expensive
operation, clients are advised to specify at most a single plugin.

Example:
\code
    plugin MyPluginLibrary
\endcode

\section2 Plugin Classname Declaration

\code
    classname <C++ plugin class>
\endcode

Provides the class name of the C++ plugin used by the module.

This information is required for all the QML modules that depend
on a C++ plugin for additional functionality. Qt Quick applications
built with static linking cannot resolve the module imports without
this information.

\section2 Type Description File Declaration

\code
    typeinfo <File>
\endcode

Declares a \l{Type Description Files}{type description file} for
the module that can be read by QML tools such as Qt Creator to
access information about the types defined by the module's plugins.
\c <File> is the (relative) file name of a \c .qmltypes file.

Example:
\code
    typeinfo mymodule.qmltypes
\endcode

Without such a file, QML tools may be unable to offer features such
as code completion for the types defined in your plugins.

\section2 Module Dependencies Declaration

\code
    depends <ModuleIdentifier> <InitialVersion>
\endcode

Declares that this module depends on another.

Example:
\code
    depends MyOtherModule 1.0
\endcode

This declaration is necessary only in cases when the dependency is
hidden: for example, when the C++ code for one module is used to
load QML (perhaps conditionally), which then depends on other
modules. In such cases, the \c depends declaration is necessary
to include the other modules in application packages.

\section2 Module Import Declaration

\code
    import <ModuleIdentifier> [<Version>]
\endcode

Declares that this module imports another.

Example:
\code
    import MyOtherModule 1.0
\endcode

The types from the other module are made available in the same type
namespace as this module is imported into. Omitting the version
imports the latest version available of the other module. Specifying
\c auto as version imports the same version as the version of this
module specified in the QML \c import statement.

\section2 Designer Support Declaration

\code
    designersupported
\endcode

Set this property if the plugin is supported by Qt Quick Designer.
By default, the plugin will not be supported.

A plugin that is supported by Qt Quick Designer has to be properly
tested. This means that the plugin does not crash when running inside
the qml2puppet that is used by Qt Quick Designer to execute QML.
Generally, the plugin should work well in the Qt Quick Designer
and not cause any show stoppers, like taking excessive amounts of memory,
slowing down the qml2puppet heavily, or anything else that renders
the plugin effectively unusable in the Qt Quick Designer.

The items of an unsupported plugin are not painted in the Qt Quick Designer,
but they are still available as empty boxes and the properties can be edited.

\section2 Preferred Path Declaration

\code
    prefer <Path>
\endcode

This property directs the QML engine to load any further files for this
module from <path>, rather than the current directory. This can be used
to load files compiled with qmlcachegen.

For example, you can add a module's QML files as resources to a resource
path \c{:/my/path/MyModule/}. Then, add \c{prefer :/my/path/MyModule} to
the qmldir file in order to use the files in the resource system, rather
than the ones in the file system. If you then use qmlcachegen for those,
the pre-compiled files will be available to any clients of the module.

\section1 Versioning Semantics

All QML types that are exported for a particular major version are available
with the latest version of the same major version. For example, if a module
provides a \c MyButton type in version 1.0 and \c MyWindow type in version 1.1,
clients importing version \c 1.1 of the module get to use the \c MyButton and
\c MyWindow types. However, the reverse is not true: a type exported for a
particular minor version cannot be used by importing an older or earlier minor
version. In the example mentioned earlier, if the client had imported version
\c 1.0 of the module, they can use the \c MyButton type only but not the
\c MyWindow type.

A module can offer multiple major versions but the clients have access
to one major version only at a time. For example, importing
\c{MyExampleModule 2.0} provides access to that major version only and not
the previous major version. Although you can organize the artifacts that belong
to different major versions under a sigle directory and a \c qmldir file, it is
recommended to use different directories for each major version. If you
choose to go with the earlier approach (one directory and a \c qmldir file),
try to use the version suffix for the file names. For example, artifacts
that belong to \c{MyExampleModule 2.0} can use \c .2 suffix in their file name.

A version cannot be imported if no types have been explicitly exported for that
version. If a module provides a \c MyButton type in version 1.0 and a
\c MyWindow type in version 1.1, you cannot import version 1.2 or version 2.0 of
that module.

A type can be defined by different files in different minor versions. In this case,
the most closely matching version is used when imported by clients.
For example, if a module had specified the following types via its \c qmldir
file:

\code
module ExampleModule
MyButton 1.0 MyButton.qml
MyButton 1.1 MyButton11.qml
MyButton 1.3 MyButton13.qml
MyRectangle 1.2 MyRectangle12.qml
\endcode

a client who imports version \c 1.2 of \c ExampleModule can use the \c MyButton
type definition provided by \c MyButton11.qml as it is the latest version of that
type, and the \c MyRectangle type definition provided by \c MyRectangle12.qml.

The version system ensures that a given QML file works regardless of the
version of installed software, as a versioned import only imports types
for that version, leaving other identifiers available, even if the actual
installed version might otherwise provide those identifiers.

\section1 Example of a qmldir File

One example of a \c qmldir file follows:

\code
module ExampleModule
CustomButton 2.0 CustomButton20.qml
CustomButton 2.1 CustomButton21.qml
plugin examplemodule
MathFunctions 2.0 mathfuncs.js
\endcode

The above \c qmldir file defines a module called "ExampleModule".  It defines
the \c CustomButton QML object type in versions 2.0 and 2.1 of the
module, with different implementations for each version. It specifies a plugin
that must be loaded by the engine when the module is imported by clients, and
that plugin may register various C++-defined types with the QML type system.
On Unix-like systems the QML engine attempts to load \c libexamplemodule.so
as a QQmlExtensionPlugin, and on Windows it loads \c examplemodule.dll as a
QQmlExtensionPlugin.  Finally, the \c qmldir file specifies a
\l{qtqml-javascript-resources.html}{JavaScript resource}, which is
only available if version 2.0 or a later version (under the same major version)
of the module is imported.

If the module is \l{qtqml-modules-identifiedmodules.html}{installed} into the
QML import path, clients could import and use the module in the following
manner:

\qml
import QtQuick 2.0
import ExampleModule 2.1

Rectangle {
    width: 400
    height: 400
    color: "lightsteelblue"

    CustomButton {
        color: "gray"
        text: "Click Me!"
        onClicked: MathFunctions.generateRandom() > 10 ? color = "red" : color = "gray";
    }
}
\endqml

The \c CustomButton type used above would come from the definition specified in
the \c CustomButton21.qml file, and the JavaScript resource identified by the
\c MathFunctions identifier would be defined in the \c mathfuncs.js file.

\section1 Type Description Files

QML modules may refer to one or more type information files in their
\c qmldir file. These usually have the \c .qmltypes
extension and are read by external tools to gain information about
types defined in C++ and typically imported via plugins.

As such qmltypes files have no effect on the functionality of a QML module.
Their only use is to allow tools such as Qt Creator to provide code completion,
error checking and other functionality to users of your module.

Any module that defines QML types in C++ should also ship a type description
file.

The best way to create a qmltypes file for your module is to generate it
using the build system and the \l QML_ELEMENT macros. If you follow the
documentation on this, no further action is needed. qmltyperegistrar will
automatically generate the \c .qmltypes files.

Example:
If your module is in \c /tmp/imports/My/Module, a file called \c plugins.qmltypes
should be generated alongside the actual plugin binary.

Add the line
\code
typeinfo plugins.qmltypes
\endcode
to \c /tmp/imports/My/Module/qmldir to register it.

*/

