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
40 QT_BEGIN_NAMESPACE
41
42 namespace {
43 const bool debugMetaDatabase = false;
44 }
45
46 namespace qdesigner_internal {
47
MetaDataBaseItem(QObject * object)48 MetaDataBaseItem::MetaDataBaseItem(QObject *object)
49 : m_object(object),
50 m_enabled(true)
51 {
52 }
53
54 MetaDataBaseItem::~MetaDataBaseItem() = default;
55
name() const56 QString MetaDataBaseItem::name() const
57 {
58 Q_ASSERT(m_object);
59 return m_object->objectName();
60 }
61
setName(const QString & name)62 void MetaDataBaseItem::setName(const QString &name)
63 {
64 Q_ASSERT(m_object);
65 m_object->setObjectName(name);
66 }
67
customClassName() const68 QString MetaDataBaseItem::customClassName() const
69 {
70 return m_customClassName;
71 }
setCustomClassName(const QString & customClassName)72 void MetaDataBaseItem::setCustomClassName(const QString &customClassName)
73 {
74 m_customClassName = customClassName;
75 }
76
77
tabOrder() const78 QWidgetList MetaDataBaseItem::tabOrder() const
79 {
80 return m_tabOrder;
81 }
82
setTabOrder(const QWidgetList & tabOrder)83 void MetaDataBaseItem::setTabOrder(const QWidgetList &tabOrder)
84 {
85 m_tabOrder = tabOrder;
86 }
87
enabled() const88 bool MetaDataBaseItem::enabled() const
89 {
90 return m_enabled;
91 }
92
setEnabled(bool b)93 void MetaDataBaseItem::setEnabled(bool b)
94 {
95 m_enabled = b;
96 }
97
fakeSlots() const98 QStringList MetaDataBaseItem::fakeSlots() const
99 {
100 return m_fakeSlots;
101 }
102
setFakeSlots(const QStringList & fs)103 void MetaDataBaseItem::setFakeSlots(const QStringList &fs)
104 {
105 m_fakeSlots = fs;
106 }
107
fakeSignals() const108 QStringList MetaDataBaseItem::fakeSignals() const
109 {
110 return m_fakeSignals;
111 }
112
setFakeSignals(const QStringList & fs)113 void MetaDataBaseItem::setFakeSignals(const QStringList &fs)
114 {
115 m_fakeSignals = fs;
116 }
117
118 // -----------------------------------------------------
MetaDataBase(QDesignerFormEditorInterface * core,QObject * parent)119 MetaDataBase::MetaDataBase(QDesignerFormEditorInterface *core, QObject *parent)
120 : QDesignerMetaDataBaseInterface(parent),
121 m_core(core)
122 {
123 }
124
~MetaDataBase()125 MetaDataBase::~MetaDataBase()
126 {
127 qDeleteAll(m_items);
128 }
129
metaDataBaseItem(QObject * object) const130 MetaDataBaseItem *MetaDataBase::metaDataBaseItem(QObject *object) const
131 {
132 MetaDataBaseItem *i = m_items.value(object);
133 if (i == nullptr || !i->enabled())
134 return nullptr;
135 return i;
136 }
137
add(QObject * object)138 void MetaDataBase::add(QObject *object)
139 {
140 MetaDataBaseItem *item = m_items.value(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(object, item);
151 if (debugMetaDatabase) {
152 qDebug() << "MetaDataBase::add: New item " << object->metaObject()->className() << item->name();
153 }
154 connect(object, &QObject::destroyed, this, &MetaDataBase::slotDestroyed);
155
156 emit changed();
157 }
158
remove(QObject * object)159 void MetaDataBase::remove(QObject *object)
160 {
161 Q_ASSERT(object);
162
163 if (MetaDataBaseItem *item = m_items.value(object)) {
164 item->setEnabled(false);
165 emit changed();
166 }
167 }
168
objects() const169 QObjectList 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(it.key());
177 }
178
179 return result;
180 }
181
core() const182 QDesignerFormEditorInterface *MetaDataBase::core() const
183 {
184 return m_core;
185 }
186
slotDestroyed(QObject * object)187 void MetaDataBase::slotDestroyed(QObject *object)
188 {
189 if (m_items.contains(object)) {
190 MetaDataBaseItem *item = m_items.value(object);
191 delete item;
192 m_items.remove(object);
193 }
194 }
195
196 // promotion convenience
promoteWidget(QDesignerFormEditorInterface * core,QWidget * widget,const QString & customClassName)197 QDESIGNER_SHARED_EXPORT bool promoteWidget(QDesignerFormEditorInterface *core,QWidget *widget,const QString &customClassName)
198 {
199
200 MetaDataBase *db = qobject_cast<MetaDataBase *>(core->metaDataBase());
201 if (!db)
202 return false;
203 MetaDataBaseItem *item = db->metaDataBaseItem(widget);
204 if (!item) {
205 db ->add(widget);
206 item = db->metaDataBaseItem(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
demoteWidget(QDesignerFormEditorInterface * core,QWidget * widget)221 QDESIGNER_SHARED_EXPORT void demoteWidget(QDesignerFormEditorInterface *core,QWidget *widget)
222 {
223 MetaDataBase *db = qobject_cast<MetaDataBase *>(core->metaDataBase());
224 if (!db)
225 return;
226 MetaDataBaseItem *item = db->metaDataBaseItem(widget);
227 item->setCustomClassName(QString());
228 if (debugMetaDatabase) {
229 qDebug() << "Demoting " << widget;
230 }
231 }
232
isPromoted(QDesignerFormEditorInterface * core,QWidget * widget)233 QDESIGNER_SHARED_EXPORT bool isPromoted(QDesignerFormEditorInterface *core, QWidget* widget)
234 {
235 const MetaDataBase *db = qobject_cast<const MetaDataBase *>(core->metaDataBase());
236 if (!db)
237 return false;
238 const MetaDataBaseItem *item = db->metaDataBaseItem(widget);
239 if (!item)
240 return false;
241 return !item->customClassName().isEmpty();
242 }
243
promotedCustomClassName(QDesignerFormEditorInterface * core,QWidget * widget)244 QDESIGNER_SHARED_EXPORT QString promotedCustomClassName(QDesignerFormEditorInterface *core, QWidget* widget)
245 {
246 const MetaDataBase *db = qobject_cast<const MetaDataBase *>(core->metaDataBase());
247 if (!db)
248 return QString();
249 const MetaDataBaseItem *item = db->metaDataBaseItem(widget);
250 if (!item)
251 return QString();
252 return item->customClassName();
253 }
254
promotedExtends(QDesignerFormEditorInterface * core,QWidget * widget)255 QDESIGNER_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(customClassName);
261 if (i == -1)
262 return QString();
263 return core->widgetDataBase()->item(i)->extends();
264 }
265
266
267 } // namespace qdesigner_internal
268
269 QT_END_NAMESPACE
270