Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
signalslot_utils.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
5
6#include <qdesigner_membersheet_p.h>
7#include <widgetdatabase_p.h>
8#include <metadatabase_p.h>
9
10#include <QtDesigner/abstractformwindow.h>
11#include <QtDesigner/abstractformeditor.h>
12#include <QtDesigner/abstractmetadatabase.h>
13#include <QtDesigner/qextensionmanager.h>
14#include <QtDesigner/abstractlanguage.h>
15
16#include <QtCore/qpair.h>
17
19
20using ClassNameSignaturePair = std::pair<QString, QString>;
21
22// Find all member functions that match a predicate on the signature string
23// using the member sheet and the fake methods stored in the widget
24// database and the meta data base.
25// Assign a pair of <classname, signature> to OutputIterator.
26
27template <class SignaturePredicate, class OutputIterator>
28static void memberList(QDesignerFormEditorInterface *core,
29 QObject *object,
30 qdesigner_internal::MemberType member_type,
31 bool showAll,
32 SignaturePredicate predicate,
33 OutputIterator it)
34{
35 if (!object)
36 return;
37 // 1) member sheet
38 const QDesignerMemberSheetExtension *members = qt_extension<QDesignerMemberSheetExtension*>(core->extensionManager(), object);
39 Q_ASSERT(members != nullptr);
40 const int count = members->count();
41 for (int i = 0; i < count; ++i) {
42 if (!members->isVisible(i))
43 continue;
44
45 if (member_type == qdesigner_internal::SignalMember && !members->isSignal(i))
46 continue;
47
48 if (member_type == qdesigner_internal::SlotMember && !members->isSlot(i))
49 continue;
50
51 if (!showAll && members->inheritedFromWidget(i))
52 continue;
53
54 const QString signature = members->signature(i);
55 if (predicate(signature)) {
56 *it = ClassNameSignaturePair(members->declaredInClass(i), signature);
57 ++it;
58 }
59 }
60 // 2) fake slots from widget DB
61 const qdesigner_internal::WidgetDataBase *wdb = qobject_cast<qdesigner_internal::WidgetDataBase *>(core->widgetDataBase());
62 if (!wdb)
63 return;
64 const int idx = wdb->indexOfObject(object);
65 Q_ASSERT(idx != -1);
66 // get the promoted class name
67 const qdesigner_internal::WidgetDataBaseItem *wdbItem = static_cast<qdesigner_internal::WidgetDataBaseItem *>(wdb->item(idx));
68 const QString className = wdbItem->name();
69
70 const QStringList wdbFakeMethods = member_type == qdesigner_internal::SlotMember ? wdbItem->fakeSlots() : wdbItem->fakeSignals();
71 if (!wdbFakeMethods.isEmpty())
72 for (const QString &fakeMethod : wdbFakeMethods)
73 if (predicate(fakeMethod)) {
74 *it = ClassNameSignaturePair(className, fakeMethod);
75 ++it;
76 }
77 // 3) fake slots from meta DB
78 qdesigner_internal::MetaDataBase *metaDataBase = qobject_cast<qdesigner_internal::MetaDataBase *>(core->metaDataBase());
79 if (!metaDataBase)
80 return;
81
82 if (const qdesigner_internal::MetaDataBaseItem *mdbItem = metaDataBase->metaDataBaseItem(object)) {
83 const QStringList mdbFakeMethods = member_type == qdesigner_internal::SlotMember ? mdbItem->fakeSlots() : mdbItem->fakeSignals();
84 if (!mdbFakeMethods.isEmpty())
85 for (const QString &fakeMethod : mdbFakeMethods)
86 if (predicate(fakeMethod)) {
87 *it = ClassNameSignaturePair(className, fakeMethod);
88 ++it;
89 }
90 }
91}
92
93namespace {
94 // Predicate that matches the exact signature string
95 class EqualsPredicate {
96 public:
97 EqualsPredicate(const QString &pattern) : m_pattern(pattern) {}
98 bool operator()(const QString &s) const { return s == m_pattern; }
99 private:
100 const QString m_pattern;
101 };
102 // Predicate for a QString member signature that matches signals up with slots and vice versa
103 class SignalMatchesSlotPredicate {
104 public:
105 SignalMatchesSlotPredicate(QDesignerFormEditorInterface *core, const QString &peer, qdesigner_internal::MemberType memberType);
106 bool operator()(const QString &s) const;
107
108 private:
109 bool signalMatchesSlot(const QString &signal, const QString &slot) const;
110
111 const QString m_peer;
112 qdesigner_internal::MemberType m_memberType;
113 const QDesignerLanguageExtension *m_lang;
114 };
115
116 SignalMatchesSlotPredicate::SignalMatchesSlotPredicate(QDesignerFormEditorInterface *core, const QString &peer, qdesigner_internal::MemberType memberType) :
117 m_peer(peer),
118 m_memberType(memberType),
119 m_lang(qt_extension<QDesignerLanguageExtension*>(core->extensionManager(), core))
120 {
121 }
122
123 bool SignalMatchesSlotPredicate::operator()(const QString &s) const
124 {
125 return m_memberType == qdesigner_internal::SlotMember ? signalMatchesSlot(m_peer, s) : signalMatchesSlot(s, m_peer);
126 }
127
128 bool SignalMatchesSlotPredicate::signalMatchesSlot(const QString &signal, const QString &slot) const
129 {
130 if (m_lang)
131 return m_lang->signalMatchesSlot(signal, slot);
132
133 return QDesignerMemberSheet::signalMatchesSlot(signal, slot);
134 }
135
136 // Output iterator for a pair of pair of <classname, signature>
137 // that builds the reverse class list for reverseClassesMemberFunctions()
138 // (for the combos of the ToolWindow)
139 class ReverseClassesMemberIterator {
140 public:
141 ReverseClassesMemberIterator(qdesigner_internal::ClassesMemberFunctions *result);
142
143 ReverseClassesMemberIterator &operator*() { return *this; }
144 ReverseClassesMemberIterator &operator++() { return *this; }
145 ReverseClassesMemberIterator &operator=(const ClassNameSignaturePair &classNameSignature);
146
147 private:
148 qdesigner_internal::ClassesMemberFunctions *m_result;
149 QString m_lastClassName;
150 QStringList *m_memberList;
151 };
152
153 ReverseClassesMemberIterator::ReverseClassesMemberIterator(qdesigner_internal::ClassesMemberFunctions *result) :
154 m_result(result),
155 m_memberList(nullptr)
156 {
157 }
158
159 ReverseClassesMemberIterator &ReverseClassesMemberIterator::operator=(const ClassNameSignaturePair &classNameSignature)
160 {
161 // prepend a new entry if class changes
162 if (!m_memberList || classNameSignature.first != m_lastClassName) {
163 m_lastClassName = classNameSignature.first;
164 m_result->push_front(qdesigner_internal::ClassMemberFunctions(m_lastClassName));
165 m_memberList = &(m_result->front().m_memberList);
166 }
167 m_memberList->push_back(classNameSignature.second);
168 return *this;
169 }
170
171 // Output iterator for a pair of pair of <classname, signature>
172 // that adds the signatures to a string list
173 class SignatureIterator {
174 public:
175 SignatureIterator(QMap<QString, QString> *result) : m_result(result) {}
176
177 SignatureIterator &operator*() { return *this; }
178 SignatureIterator &operator++() { return *this; }
179 SignatureIterator &operator=(const ClassNameSignaturePair &classNameSignature)
180 {
181 m_result->insert(classNameSignature.second, classNameSignature.first);
182 return *this;
183 }
184
185 private:
186 QMap<QString, QString> *m_result;
187 };
188}
189
190static inline bool truePredicate(const QString &) { return true; }
191
192namespace qdesigner_internal {
193
194 ClassMemberFunctions::ClassMemberFunctions(const QString &class_name) :
196 {
197 }
198
199 bool signalMatchesSlot(QDesignerFormEditorInterface *core, const QString &signal, const QString &slot)
200 {
201 const SignalMatchesSlotPredicate predicate(core, signal, qdesigner_internal::SlotMember);
202 return predicate(slot);
203 }
204
205 // return classes and members in reverse class order to
206 // populate of the combo of the ToolWindow
208 const QString &peer, QDesignerFormWindowInterface *form)
209 {
210 QObject *object = nullptr;
211 if (obj_name == form->mainContainer()->objectName()) {
212 object = form->mainContainer();
213 } else {
214 object = form->mainContainer()->findChild<QObject*>(obj_name);
215 }
216 if (!object)
217 return ClassesMemberFunctions();
218 QDesignerFormEditorInterface *core = form->core();
219
220 ClassesMemberFunctions rc;
221 memberList(form->core(), object, member_type, true, SignalMatchesSlotPredicate(core, peer, member_type),
222 ReverseClassesMemberIterator(&rc));
223 return rc;
224 }
225
226 QMap<QString, QString> getSignals(QDesignerFormEditorInterface *core, QObject *object, bool showAll)
227 {
228 QMap<QString, QString> rc;
229 memberList(core, object, SignalMember, showAll, truePredicate, SignatureIterator(&rc));
230 return rc;
231 }
232
233 QMap<QString, QString> getMatchingSlots(QDesignerFormEditorInterface *core, QObject *object, const QString &signalSignature, bool showAll)
234 {
235 QMap<QString, QString> rc;
236 memberList(core, object, SlotMember, showAll, SignalMatchesSlotPredicate(core, signalSignature, qdesigner_internal::SlotMember), SignatureIterator(&rc));
237 return rc;
238 }
239
240 bool memberFunctionListContains(QDesignerFormEditorInterface *core, QObject *object, MemberType type, const QString &signature)
241 {
242 QMap<QString, QString> rc;
243 memberList(core, object, type, true, EqualsPredicate(signature), SignatureIterator(&rc));
244 return !rc.isEmpty();
245 }
246
247 // ### deprecated
248 QString realObjectName(QDesignerFormEditorInterface *core, QObject *object)
249 {
250 if (!object)
251 return QString();
252
253 const QDesignerMetaDataBaseInterface *mdb = core->metaDataBase();
254 if (const QDesignerMetaDataBaseItemInterface *item = mdb->item(object))
255 return item->name();
256
257 return object->objectName();
258 }
259} // namespace qdesigner_internal
260
261QT_END_NAMESPACE
Combined button and popup list for selecting options.
Auxiliary methods to store/retrieve settings.
bool signalMatchesSlot(QDesignerFormEditorInterface *core, const QString &signal, const QString &slot)
ClassesMemberFunctions reverseClassesMemberFunctions(const QString &obj_name, MemberType member_type, const QString &peer, QDesignerFormWindowInterface *form)
static void memberList(QDesignerFormEditorInterface *core, QObject *object, qdesigner_internal::MemberType member_type, bool showAll, SignaturePredicate predicate, OutputIterator it)
static bool truePredicate(const QString &)
ClassMemberFunctions(const QString &_class_name)