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