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 | |
48 | MetaDataBaseItem::MetaDataBaseItem(QObject *object) |
49 | : m_object(object), |
50 | m_enabled(true) |
51 | { |
52 | } |
53 | |
54 | MetaDataBaseItem::~MetaDataBaseItem() = default; |
55 | |
56 | QString MetaDataBaseItem::name() const |
57 | { |
58 | Q_ASSERT(m_object); |
59 | return m_object->objectName(); |
60 | } |
61 | |
62 | void MetaDataBaseItem::setName(const QString &name) |
63 | { |
64 | Q_ASSERT(m_object); |
65 | m_object->setObjectName(name); |
66 | } |
67 | |
68 | QString MetaDataBaseItem::customClassName() const |
69 | { |
70 | return m_customClassName; |
71 | } |
72 | void MetaDataBaseItem::setCustomClassName(const QString &customClassName) |
73 | { |
74 | m_customClassName = customClassName; |
75 | } |
76 | |
77 | |
78 | QWidgetList MetaDataBaseItem::tabOrder() const |
79 | { |
80 | return m_tabOrder; |
81 | } |
82 | |
83 | void MetaDataBaseItem::setTabOrder(const QWidgetList &tabOrder) |
84 | { |
85 | m_tabOrder = tabOrder; |
86 | } |
87 | |
88 | bool MetaDataBaseItem::enabled() const |
89 | { |
90 | return m_enabled; |
91 | } |
92 | |
93 | void MetaDataBaseItem::setEnabled(bool b) |
94 | { |
95 | m_enabled = b; |
96 | } |
97 | |
98 | QStringList MetaDataBaseItem::fakeSlots() const |
99 | { |
100 | return m_fakeSlots; |
101 | } |
102 | |
103 | void MetaDataBaseItem::setFakeSlots(const QStringList &fs) |
104 | { |
105 | m_fakeSlots = fs; |
106 | } |
107 | |
108 | QStringList MetaDataBaseItem::fakeSignals() const |
109 | { |
110 | return m_fakeSignals; |
111 | } |
112 | |
113 | void MetaDataBaseItem::setFakeSignals(const QStringList &fs) |
114 | { |
115 | m_fakeSignals = fs; |
116 | } |
117 | |
118 | // ----------------------------------------------------- |
119 | MetaDataBase::MetaDataBase(QDesignerFormEditorInterface *core, QObject *parent) |
120 | : QDesignerMetaDataBaseInterface(parent), |
121 | m_core(core) |
122 | { |
123 | } |
124 | |
125 | MetaDataBase::~MetaDataBase() |
126 | { |
127 | qDeleteAll(c: m_items); |
128 | } |
129 | |
130 | MetaDataBaseItem *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 | |
138 | void 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 | |
159 | void 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 | |
169 | 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(t: it.key()); |
177 | } |
178 | |
179 | return result; |
180 | } |
181 | |
182 | QDesignerFormEditorInterface *MetaDataBase::core() const |
183 | { |
184 | return m_core; |
185 | } |
186 | |
187 | void 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 |
197 | QDESIGNER_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 | |
221 | QDESIGNER_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 | |
233 | QDESIGNER_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 | |
244 | QDESIGNER_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 | |
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(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 | |
269 | QT_END_NAMESPACE |
270 | |