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 "qdesigner_membersheet_p.h"
30
31#include <QtDesigner/abstractformeditor.h>
32#include <abstractintrospection_p.h>
33
34#include <QtWidgets/qwidget.h>
35QT_BEGIN_NAMESPACE
36
37static QList<QByteArray> stringListToByteArray(const QStringList &l)
38{
39 if (l.isEmpty())
40 return QList<QByteArray>();
41 QList<QByteArray> rc;
42 const QStringList::const_iterator cend = l.constEnd();
43 for (QStringList::const_iterator it = l.constBegin(); it != cend; ++it)
44 rc += it->toUtf8();
45 return rc;
46}
47
48// Find the form editor in the hierarchy.
49// We know that the parent of the sheet is the extension manager
50// whose parent is the core.
51
52static QDesignerFormEditorInterface *formEditorForObject(QObject *o) {
53 do {
54 if (QDesignerFormEditorInterface* core = qobject_cast<QDesignerFormEditorInterface*>(object: o))
55 return core;
56 o = o->parent();
57 } while(o);
58 Q_ASSERT(o);
59 return nullptr;
60}
61
62// ------------ QDesignerMemberSheetPrivate
63class QDesignerMemberSheetPrivate {
64public:
65 explicit QDesignerMemberSheetPrivate(QObject *object, QObject *sheetParent);
66
67 QDesignerFormEditorInterface *m_core;
68 const QDesignerMetaObjectInterface *m_meta;
69
70 class Info {
71 public:
72 QString group;
73 bool visible{true};
74 };
75
76 using InfoHash = QHash<int, Info>;
77
78 Info &ensureInfo(int index);
79
80 InfoHash m_info;
81};
82
83QDesignerMemberSheetPrivate::QDesignerMemberSheetPrivate(QObject *object, QObject *sheetParent) :
84 m_core(formEditorForObject(o: sheetParent)),
85 m_meta(m_core->introspection()->metaObject(object))
86{
87}
88
89QDesignerMemberSheetPrivate::Info &QDesignerMemberSheetPrivate::ensureInfo(int index)
90{
91 InfoHash::iterator it = m_info.find(akey: index);
92 if (it == m_info.end()) {
93 it = m_info.insert(akey: index, avalue: Info());
94 }
95 return it.value();
96}
97
98// --------- QDesignerMemberSheet
99
100QDesignerMemberSheet::QDesignerMemberSheet(QObject *object, QObject *parent) :
101 QObject(parent),
102 d(new QDesignerMemberSheetPrivate(object, parent))
103{
104}
105
106QDesignerMemberSheet::~QDesignerMemberSheet()
107{
108 delete d;
109}
110
111int QDesignerMemberSheet::count() const
112{
113 return d->m_meta->methodCount();
114}
115
116int QDesignerMemberSheet::indexOf(const QString &name) const
117{
118 return d->m_meta->indexOfMethod(method: name);
119}
120
121QString QDesignerMemberSheet::memberName(int index) const
122{
123 return d->m_meta->method(index)->tag();
124}
125
126QString QDesignerMemberSheet::declaredInClass(int index) const
127{
128 const QString member = d->m_meta->method(index)->signature();
129
130 // Find class whose superclass does not contain the method.
131 const QDesignerMetaObjectInterface *meta_obj = d->m_meta;
132
133 for (;;) {
134 const QDesignerMetaObjectInterface *tmp = meta_obj->superClass();
135 if (tmp == nullptr)
136 break;
137 if (tmp->indexOfMethod(method: member) == -1)
138 break;
139 meta_obj = tmp;
140 }
141 return meta_obj->className();
142}
143
144QString QDesignerMemberSheet::memberGroup(int index) const
145{
146 return d->m_info.value(akey: index).group;
147}
148
149void QDesignerMemberSheet::setMemberGroup(int index, const QString &group)
150{
151 d->ensureInfo(index).group = group;
152}
153
154QString QDesignerMemberSheet::signature(int index) const
155{
156 return d->m_meta->method(index)->normalizedSignature();
157}
158
159bool QDesignerMemberSheet::isVisible(int index) const
160{
161 const auto it = d->m_info.constFind(akey: index);
162 if (it != d->m_info.constEnd())
163 return it.value().visible;
164
165 return d->m_meta->method(index)->methodType() == QDesignerMetaMethodInterface::Signal
166 || d->m_meta->method(index)->access() == QDesignerMetaMethodInterface::Public;
167}
168
169void QDesignerMemberSheet::setVisible(int index, bool visible)
170{
171 d->ensureInfo(index).visible = visible;
172}
173
174bool QDesignerMemberSheet::isSignal(int index) const
175{
176 return d->m_meta->method(index)->methodType() == QDesignerMetaMethodInterface::Signal;
177}
178
179bool QDesignerMemberSheet::isSlot(int index) const
180{
181 return d->m_meta->method(index)->methodType() == QDesignerMetaMethodInterface::Slot;
182}
183
184bool QDesignerMemberSheet::inheritedFromWidget(int index) const
185{
186 return declaredInClass(index) == QStringLiteral("QWidget") || declaredInClass(index) == QStringLiteral("QObject");
187}
188
189
190QList<QByteArray> QDesignerMemberSheet::parameterTypes(int index) const
191{
192 return stringListToByteArray(l: d->m_meta->method(index)->parameterTypes());
193}
194
195QList<QByteArray> QDesignerMemberSheet::parameterNames(int index) const
196{
197 return stringListToByteArray(l: d->m_meta->method(index)->parameterNames());
198}
199
200bool QDesignerMemberSheet::signalMatchesSlot(const QString &signal, const QString &slot)
201{
202 bool result = true;
203
204 do {
205 int signal_idx = signal.indexOf(c: QLatin1Char('('));
206 int slot_idx = slot.indexOf(c: QLatin1Char('('));
207 if (signal_idx == -1 || slot_idx == -1)
208 break;
209
210 ++signal_idx; ++slot_idx;
211
212 if (slot.at(i: slot_idx) == QLatin1Char(')'))
213 break;
214
215 while (signal_idx < signal.size() && slot_idx < slot.size()) {
216 const QChar signal_c = signal.at(i: signal_idx);
217 const QChar slot_c = slot.at(i: slot_idx);
218
219 if (signal_c == QLatin1Char(',') && slot_c == QLatin1Char(')'))
220 break;
221
222 if (signal_c == QLatin1Char(')') && slot_c == QLatin1Char(')'))
223 break;
224
225 if (signal_c != slot_c) {
226 result = false;
227 break;
228 }
229
230 ++signal_idx; ++slot_idx;
231 }
232 } while (false);
233
234 return result;
235}
236
237// ------------ QDesignerMemberSheetFactory
238
239QDesignerMemberSheetFactory::QDesignerMemberSheetFactory(QExtensionManager *parent)
240 : QExtensionFactory(parent)
241{
242}
243
244QObject *QDesignerMemberSheetFactory::createExtension(QObject *object, const QString &iid, QObject *parent) const
245{
246 if (iid == Q_TYPEID(QDesignerMemberSheetExtension)) {
247 return new QDesignerMemberSheet(object, parent);
248 }
249
250 return nullptr;
251}
252
253QT_END_NAMESPACE
254

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