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 */
QExtensionManager(QObject * parent)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 */
registerExtensions(QAbstractExtensionFactory * factory,const QString & iid)102 void QExtensionManager::registerExtensions(QAbstractExtensionFactory *factory, const QString &iid)
103 {
104     if (iid.isEmpty()) {
105         m_globalExtension.prepend(factory);
106         return;
107     }
108 
109     FactoryMap::iterator it = m_extensions.find(iid);
110     if (it == m_extensions.end())
111         it = m_extensions.insert(iid, FactoryList());
112 
113     it.value().prepend(factory);
114 }
115 
116 /*!
117     Unregister the extension specified by the given \a factory and
118     extension identifier \a iid.
119 */
unregisterExtensions(QAbstractExtensionFactory * factory,const QString & iid)120 void QExtensionManager::unregisterExtensions(QAbstractExtensionFactory *factory, const QString &iid)
121 {
122     if (iid.isEmpty()) {
123         m_globalExtension.removeAll(factory);
124         return;
125     }
126 
127     const FactoryMap::iterator it = m_extensions.find(iid);
128     if (it == m_extensions.end())
129         return;
130 
131     FactoryList &factories = it.value();
132     factories.removeAll(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 */
extension(QObject * object,const QString & iid) const142 QObject *QExtensionManager::extension(QObject *object, const QString &iid) const
143 {
144     const FactoryMap::const_iterator it = m_extensions.constFind(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