1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Designer of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29#include "default_extensionfactory.h"
30#include "qextensionmanager.h"
31#include <qpointer.h>
32#include <QtCore/qdebug.h>
33
34QT_BEGIN_NAMESPACE
35
36/*!
37 \class QExtensionFactory
38
39 \brief The QExtensionFactory class allows you to create a factory
40 that is able to make instances of custom extensions in Qt
41 Designer.
42
43 \inmodule QtDesigner
44
45 In \QD the extensions are not created until they are required. For
46 that reason, when implementing a custom extension, you must also
47 create a QExtensionFactory, i.e. a class that is able to make an
48 instance of your extension, and register it using \QD's \l
49 {QExtensionManager}{extension manager}.
50
51 The QExtensionManager class provides extension management
52 facilities for Qt Designer. When an extension is required, Qt
53 Designer's \l {QExtensionManager}{extension manager} will run
54 through all its registered factories calling
55 QExtensionFactory::createExtension() for each until the first one
56 that is able to create a requested extension for the selected
57 object, is found. This factory will then make an instance of the
58 extension.
59
60 There are four available types of extensions in Qt Designer:
61 QDesignerContainerExtension , QDesignerMemberSheetExtension,
62 QDesignerPropertySheetExtension and QDesignerTaskMenuExtension. Qt
63 Designer's behavior is the same whether the requested extension is
64 associated with a multi page container, a member sheet, a property
65 sheet or a task menu.
66
67 You can either create a new QExtensionFactory and reimplement the
68 QExtensionFactory::createExtension() function. For example:
69
70 \snippet lib/tools_designer_src_lib_extension_default_extensionfactory.cpp 0
71
72 Or you can use an existing factory, expanding the
73 QExtensionFactory::createExtension() function to make the factory
74 able to create your extension as well. For example:
75
76 \snippet lib/tools_designer_src_lib_extension_default_extensionfactory.cpp 1
77
78 For a complete example using the QExtensionFactory class, see the
79 \l {taskmenuextension}{Task Menu Extension example}. The
80 example shows how to create a custom widget plugin for Qt
81 Designer, and how to to use the QDesignerTaskMenuExtension class
82 to add custom items to Qt Designer's task menu.
83
84 \sa QExtensionManager, QAbstractExtensionFactory
85*/
86
87/*!
88 Constructs an extension factory with the given \a parent.
89*/
90QExtensionFactory::QExtensionFactory(QExtensionManager *parent)
91 : QObject(parent)
92{
93}
94
95/*!
96 Returns the extension specified by \a iid for the given \a object.
97
98 \sa createExtension()
99*/
100
101QObject *QExtensionFactory::extension(QObject *object, const QString &iid) const
102{
103 if (!object)
104 return nullptr;
105 const IdObjectKey key = qMakePair(x: iid, y: object);
106
107 ExtensionMap::iterator it = m_extensions.find(akey: key);
108 if (it == m_extensions.end()) {
109 if (QObject *ext = createExtension(object, iid, parent: const_cast<QExtensionFactory*>(this))) {
110 connect(sender: ext, signal: &QObject::destroyed, receiver: this, slot: &QExtensionFactory::objectDestroyed);
111 it = m_extensions.insert(akey: key, avalue: ext);
112 }
113 }
114
115 if (!m_extended.contains(akey: object)) {
116 connect(sender: object, signal: &QObject::destroyed, receiver: this, slot: &QExtensionFactory::objectDestroyed);
117 m_extended.insert(akey: object, avalue: true);
118 }
119
120 if (it == m_extensions.end())
121 return nullptr;
122
123 return it.value();
124}
125
126void QExtensionFactory::objectDestroyed(QObject *object)
127{
128 for (auto it = m_extensions.begin(); it != m_extensions.end(); ) {
129 if (it.key().second == object || object == it.value())
130 it = m_extensions.erase(it);
131 else
132 ++it;
133 }
134
135 m_extended.remove(akey: object);
136}
137
138/*!
139 Creates an extension specified by \a iid for the given \a object.
140 The extension object is created as a child of the specified \a
141 parent.
142
143 \sa extension()
144*/
145QObject *QExtensionFactory::createExtension(QObject *object, const QString &iid, QObject *parent) const
146{
147 Q_UNUSED(object);
148 Q_UNUSED(iid);
149 Q_UNUSED(parent);
150
151 return nullptr;
152}
153
154/*!
155 Returns the extension manager for the extension factory.
156*/
157QExtensionManager *QExtensionFactory::extensionManager() const
158{
159 return static_cast<QExtensionManager *>(parent());
160}
161
162QT_END_NAMESPACE
163

source code of qttools/src/designer/src/lib/extension/default_extensionfactory.cpp