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 "metadatabase_p.h"
30#include "widgetdatabase_p.h"
31
32// sdk
33#include <QtDesigner/abstractformeditor.h>
34
35// Qt
36#include <QtWidgets/qwidget.h>
37#include <QtCore/qalgorithms.h>
38#include <QtCore/qdebug.h>
39
40QT_BEGIN_NAMESPACE
41
42namespace {
43 const bool debugMetaDatabase = false;
44}
45
46namespace qdesigner_internal {
47
48MetaDataBaseItem::MetaDataBaseItem(QObject *object)
49 : m_object(object),
50 m_enabled(true)
51{
52}
53
54MetaDataBaseItem::~MetaDataBaseItem() = default;
55
56QString MetaDataBaseItem::name() const
57{
58 Q_ASSERT(m_object);
59 return m_object->objectName();
60}
61
62void MetaDataBaseItem::setName(const QString &name)
63{
64 Q_ASSERT(m_object);
65 m_object->setObjectName(name);
66}
67
68QString MetaDataBaseItem::customClassName() const
69{
70 return m_customClassName;
71}
72void MetaDataBaseItem::setCustomClassName(const QString &customClassName)
73{
74 m_customClassName = customClassName;
75}
76
77
78QWidgetList MetaDataBaseItem::tabOrder() const
79{
80 return m_tabOrder;
81}
82
83void MetaDataBaseItem::setTabOrder(const QWidgetList &tabOrder)
84{
85 m_tabOrder = tabOrder;
86}
87
88bool MetaDataBaseItem::enabled() const
89{
90 return m_enabled;
91}
92
93void MetaDataBaseItem::setEnabled(bool b)
94{
95 m_enabled = b;
96}
97
98QStringList MetaDataBaseItem::fakeSlots() const
99{
100 return m_fakeSlots;
101}
102
103void MetaDataBaseItem::setFakeSlots(const QStringList &fs)
104{
105 m_fakeSlots = fs;
106}
107
108QStringList MetaDataBaseItem::fakeSignals() const
109{
110 return m_fakeSignals;
111}
112
113void MetaDataBaseItem::setFakeSignals(const QStringList &fs)
114{
115 m_fakeSignals = fs;
116}
117
118// -----------------------------------------------------
119MetaDataBase::MetaDataBase(QDesignerFormEditorInterface *core, QObject *parent)
120 : QDesignerMetaDataBaseInterface(parent),
121 m_core(core)
122{
123}
124
125MetaDataBase::~MetaDataBase()
126{
127 qDeleteAll(c: m_items);
128}
129
130MetaDataBaseItem *MetaDataBase::metaDataBaseItem(QObject *object) const
131{
132 MetaDataBaseItem *i = m_items.value(akey: object);
133 if (i == nullptr || !i->enabled())
134 return nullptr;
135 return i;
136}
137
138void MetaDataBase::add(QObject *object)
139{
140 MetaDataBaseItem *item = m_items.value(akey: object);
141 if (item != nullptr) {
142 item->setEnabled(true);
143 if (debugMetaDatabase) {
144 qDebug() << "MetaDataBase::add: Existing item for " << object->metaObject()->className() << item->name();
145 }
146 return;
147 }
148
149 item = new MetaDataBaseItem(object);
150 m_items.insert(akey: object, avalue: item);
151 if (debugMetaDatabase) {
152 qDebug() << "MetaDataBase::add: New item " << object->metaObject()->className() << item->name();
153 }
154 connect(sender: object, signal: &QObject::destroyed, receiver: this, slot: &MetaDataBase::slotDestroyed);
155
156 emit changed();
157}
158
159void MetaDataBase::remove(QObject *object)
160{
161 Q_ASSERT(object);
162
163 if (MetaDataBaseItem *item = m_items.value(akey: object)) {
164 item->setEnabled(false);
165 emit changed();
166 }
167}
168
169QObjectList MetaDataBase::objects() const
170{
171 QObjectList result;
172
173 ItemMap::const_iterator it = m_items.begin();
174 for (; it != m_items.end(); ++it) {
175 if (it.value()->enabled())
176 result.append(t: it.key());
177 }
178
179 return result;
180}
181
182QDesignerFormEditorInterface *MetaDataBase::core() const
183{
184 return m_core;
185}
186
187void MetaDataBase::slotDestroyed(QObject *object)
188{
189 if (m_items.contains(akey: object)) {
190 MetaDataBaseItem *item = m_items.value(akey: object);
191 delete item;
192 m_items.remove(akey: object);
193 }
194}
195
196// promotion convenience
197QDESIGNER_SHARED_EXPORT bool promoteWidget(QDesignerFormEditorInterface *core,QWidget *widget,const QString &customClassName)
198{
199
200 MetaDataBase *db = qobject_cast<MetaDataBase *>(object: core->metaDataBase());
201 if (!db)
202 return false;
203 MetaDataBaseItem *item = db->metaDataBaseItem(object: widget);
204 if (!item) {
205 db ->add(object: widget);
206 item = db->metaDataBaseItem(object: widget);
207 }
208 // Recursive promotion occurs if there is a plugin missing.
209 const QString oldCustomClassName = item->customClassName();
210 if (!oldCustomClassName.isEmpty()) {
211 qDebug() << "WARNING: Recursive promotion of " << oldCustomClassName << " to " << customClassName
212 << ". A plugin is missing.";
213 }
214 item->setCustomClassName(customClassName);
215 if (debugMetaDatabase) {
216 qDebug() << "Promoting " << widget->metaObject()->className() << " to " << customClassName;
217 }
218 return true;
219}
220
221QDESIGNER_SHARED_EXPORT void demoteWidget(QDesignerFormEditorInterface *core,QWidget *widget)
222{
223 MetaDataBase *db = qobject_cast<MetaDataBase *>(object: core->metaDataBase());
224 if (!db)
225 return;
226 MetaDataBaseItem *item = db->metaDataBaseItem(object: widget);
227 item->setCustomClassName(QString());
228 if (debugMetaDatabase) {
229 qDebug() << "Demoting " << widget;
230 }
231}
232
233QDESIGNER_SHARED_EXPORT bool isPromoted(QDesignerFormEditorInterface *core, QWidget* widget)
234{
235 const MetaDataBase *db = qobject_cast<const MetaDataBase *>(object: core->metaDataBase());
236 if (!db)
237 return false;
238 const MetaDataBaseItem *item = db->metaDataBaseItem(object: widget);
239 if (!item)
240 return false;
241 return !item->customClassName().isEmpty();
242}
243
244QDESIGNER_SHARED_EXPORT QString promotedCustomClassName(QDesignerFormEditorInterface *core, QWidget* widget)
245{
246 const MetaDataBase *db = qobject_cast<const MetaDataBase *>(object: core->metaDataBase());
247 if (!db)
248 return QString();
249 const MetaDataBaseItem *item = db->metaDataBaseItem(object: widget);
250 if (!item)
251 return QString();
252 return item->customClassName();
253}
254
255QDESIGNER_SHARED_EXPORT QString promotedExtends(QDesignerFormEditorInterface *core, QWidget* widget)
256{
257 const QString customClassName = promotedCustomClassName(core,widget);
258 if (customClassName.isEmpty())
259 return QString();
260 const int i = core->widgetDataBase()->indexOfClassName(className: customClassName);
261 if (i == -1)
262 return QString();
263 return core->widgetDataBase()->item(index: i)->extends();
264}
265
266
267} // namespace qdesigner_internal
268
269QT_END_NAMESPACE
270

source code of qttools/src/designer/src/lib/shared/metadatabase.cpp