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 "qextensionmanager.h" |
30 | |
31 | QT_BEGIN_NAMESPACE |
32 | |
33 | /*! |
34 | \class QExtensionManager |
35 | |
36 | \brief The QExtensionManager class provides extension management |
37 | facilities for Qt Designer. |
38 | |
39 | \inmodule QtDesigner |
40 | |
41 | In \QD the extensions are not created until they are required. For |
42 | that reason, when implementing an extension, you must also create |
43 | a QExtensionFactory, i.e a class that is able to make an instance |
44 | of your extension, and register it using \QD's extension manager. |
45 | |
46 | The registration of an extension factory is typically made in the |
47 | QDesignerCustomWidgetInterface::initialize() function: |
48 | |
49 | \snippet lib/tools_designer_src_lib_extension_qextensionmanager.cpp 0 |
50 | |
51 | The QExtensionManager is not intended to be instantiated |
52 | directly. You can retrieve an interface to \QD's extension manager |
53 | using the QDesignerFormEditorInterface::extensionManager() |
54 | function. A pointer to \QD's current QDesignerFormEditorInterface |
55 | object (\c formEditor in the example above) is provided by the |
56 | QDesignerCustomWidgetInterface::initialize() function's |
57 | parameter. When implementing a custom widget plugin, you must |
58 | subclass the QDesignerCustomWidgetInterface to expose your plugin |
59 | to \QD. |
60 | |
61 | Then, when an extension is required, \QD's extension manager will |
62 | run through all its registered factories calling |
63 | QExtensionFactory::createExtension() for each until the first one |
64 | that is able to create the requested extension for the selected |
65 | object, is found. This factory will then make an instance of the |
66 | extension. |
67 | |
68 | There are four available types of extensions in \QD: |
69 | QDesignerContainerExtension , QDesignerMemberSheetExtension, |
70 | QDesignerPropertySheetExtension and |
71 | QDesignerTaskMenuExtension. \QD's behavior is the same whether the |
72 | requested extension is associated with a container, a member |
73 | sheet, a property sheet or a task menu. |
74 | |
75 | For a complete example using the QExtensionManager class, see the |
76 | \l {taskmenuextension}{Task Menu Extension example}. The |
77 | example shows how to create a custom widget plugin for Qt |
78 | Designer, and how to to use the QDesignerTaskMenuExtension class |
79 | to add custom items to \QD's task menu. |
80 | |
81 | \sa QExtensionFactory, QAbstractExtensionManager |
82 | */ |
83 | |
84 | /*! |
85 | Constructs an extension manager with the given \a parent. |
86 | */ |
87 | QExtensionManager::QExtensionManager(QObject *parent) |
88 | : QObject(parent) |
89 | { |
90 | } |
91 | |
92 | |
93 | /*! |
94 | Destroys the extension manager |
95 | */ |
96 | QExtensionManager::~QExtensionManager() = default; |
97 | |
98 | /*! |
99 | Register the extension specified by the given \a factory and |
100 | extension identifier \a iid. |
101 | */ |
102 | void QExtensionManager::registerExtensions(QAbstractExtensionFactory *factory, const QString &iid) |
103 | { |
104 | if (iid.isEmpty()) { |
105 | m_globalExtension.prepend(t: factory); |
106 | return; |
107 | } |
108 | |
109 | FactoryMap::iterator it = m_extensions.find(akey: iid); |
110 | if (it == m_extensions.end()) |
111 | it = m_extensions.insert(akey: iid, avalue: FactoryList()); |
112 | |
113 | it.value().prepend(t: factory); |
114 | } |
115 | |
116 | /*! |
117 | Unregister the extension specified by the given \a factory and |
118 | extension identifier \a iid. |
119 | */ |
120 | void QExtensionManager::unregisterExtensions(QAbstractExtensionFactory *factory, const QString &iid) |
121 | { |
122 | if (iid.isEmpty()) { |
123 | m_globalExtension.removeAll(t: factory); |
124 | return; |
125 | } |
126 | |
127 | const FactoryMap::iterator it = m_extensions.find(akey: iid); |
128 | if (it == m_extensions.end()) |
129 | return; |
130 | |
131 | FactoryList &factories = it.value(); |
132 | factories.removeAll(t: factory); |
133 | |
134 | if (factories.isEmpty()) |
135 | m_extensions.erase(it); |
136 | } |
137 | |
138 | /*! |
139 | Returns the extension specified by \a iid, for the given \a |
140 | object. |
141 | */ |
142 | QObject *QExtensionManager::extension(QObject *object, const QString &iid) const |
143 | { |
144 | const FactoryMap::const_iterator it = m_extensions.constFind(akey: iid); |
145 | if (it != m_extensions.constEnd()) { |
146 | const FactoryList::const_iterator fcend = it.value().constEnd(); |
147 | for (FactoryList::const_iterator fit = it.value().constBegin(); fit != fcend; ++fit) |
148 | if (QObject *ext = (*fit)->extension(object, iid)) |
149 | return ext; |
150 | } |
151 | const FactoryList::const_iterator gfcend = m_globalExtension.constEnd(); |
152 | for (FactoryList::const_iterator git = m_globalExtension.constBegin(); git != gfcend; ++git) |
153 | if (QObject *ext = (*git)->extension(object, iid)) |
154 | return ext; |
155 | |
156 | return nullptr; |
157 | } |
158 | |
159 | QT_END_NAMESPACE |
160 | |