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 | |
4 | #include "customwidgetsinfo.h" |
5 | #include "driver.h" |
6 | #include "ui4.h" |
7 | #include "utils.h" |
8 | |
9 | #include <utility> |
10 | |
11 | QT_BEGIN_NAMESPACE |
12 | |
13 | using namespace Qt::StringLiterals; |
14 | |
15 | CustomWidgetsInfo::CustomWidgetsInfo() = default; |
16 | |
17 | void CustomWidgetsInfo::acceptUI(DomUI *node) |
18 | { |
19 | m_customWidgets.clear(); |
20 | |
21 | if (node->elementCustomWidgets()) |
22 | acceptCustomWidgets(node: node->elementCustomWidgets()); |
23 | } |
24 | |
25 | void CustomWidgetsInfo::acceptCustomWidgets(DomCustomWidgets *node) |
26 | { |
27 | TreeWalker::acceptCustomWidgets(customWidgets: node); |
28 | } |
29 | |
30 | void CustomWidgetsInfo::acceptCustomWidget(DomCustomWidget *node) |
31 | { |
32 | if (node->elementClass().isEmpty()) |
33 | return; |
34 | |
35 | m_customWidgets.insert(key: node->elementClass(), value: node); |
36 | } |
37 | |
38 | bool CustomWidgetsInfo::extends(const QString &classNameIn, QAnyStringView baseClassName) const |
39 | { |
40 | if (classNameIn == baseClassName) |
41 | return true; |
42 | |
43 | QString className = classNameIn; |
44 | while (const DomCustomWidget *c = customWidget(name: className)) { |
45 | const QString extends = c->elementExtends(); |
46 | if (className == extends) // Faulty legacy custom widget entries exist. |
47 | return false; |
48 | if (extends == baseClassName) |
49 | return true; |
50 | className = extends; |
51 | } |
52 | return false; |
53 | } |
54 | |
55 | bool CustomWidgetsInfo::extendsOneOf(const QString &classNameIn, |
56 | const QStringList &baseClassNames) const |
57 | { |
58 | if (baseClassNames.contains(str: classNameIn)) |
59 | return true; |
60 | |
61 | QString className = classNameIn; |
62 | while (const DomCustomWidget *c = customWidget(name: className)) { |
63 | const QString extends = c->elementExtends(); |
64 | if (className == extends) // Faulty legacy custom widget entries exist. |
65 | return false; |
66 | if (baseClassNames.contains(str: extends)) |
67 | return true; |
68 | className = extends; |
69 | } |
70 | return false; |
71 | } |
72 | |
73 | bool CustomWidgetsInfo::isCustomWidgetContainer(const QString &className) const |
74 | { |
75 | if (const DomCustomWidget *dcw = m_customWidgets.value(key: className, defaultValue: nullptr)) |
76 | if (dcw->hasElementContainer()) |
77 | return dcw->elementContainer() != 0; |
78 | return false; |
79 | } |
80 | |
81 | // Is it ambiguous, resulting in different signals for Python |
82 | // "QAbstractButton::clicked(checked=false)" |
83 | bool CustomWidgetsInfo::isAmbiguousSignal(const QString &className, |
84 | const QString &signalSignature) const |
85 | { |
86 | if (signalSignature.startsWith(s: u"triggered" ) && extends(classNameIn: className, baseClassName: "QAction" )) |
87 | return true; |
88 | if (signalSignature.startsWith(s: u"clicked(" ) |
89 | && extendsOneOf(classNameIn: className, baseClassNames: {u"QCommandLinkButton"_s , u"QCheckBox"_s , |
90 | u"QPushButton"_s , u"QRadioButton"_s , u"QToolButton"_s })) { |
91 | return true; |
92 | } |
93 | return false; |
94 | } |
95 | |
96 | QString CustomWidgetsInfo::realClassName(const QString &className) const |
97 | { |
98 | if (className == "Line"_L1 ) |
99 | return u"QFrame"_s ; |
100 | |
101 | return className; |
102 | } |
103 | |
104 | QString CustomWidgetsInfo::customWidgetAddPageMethod(const QString &name) const |
105 | { |
106 | if (DomCustomWidget *dcw = m_customWidgets.value(key: name, defaultValue: nullptr)) |
107 | return dcw->elementAddPageMethod(); |
108 | return QString(); |
109 | } |
110 | |
111 | // add page methods for simple containers taking only the widget parameter |
112 | QString CustomWidgetsInfo::simpleContainerAddPageMethod(const QString &name) const |
113 | { |
114 | using AddPageMethod = std::pair<QString, QString>; |
115 | |
116 | static const AddPageMethod addPageMethods[] = { |
117 | {u"QStackedWidget"_s , u"addWidget"_s }, |
118 | {u"QToolBar"_s , u"addWidget"_s }, |
119 | {u"QDockWidget"_s , u"setWidget"_s }, |
120 | {u"QScrollArea"_s , u"setWidget"_s }, |
121 | {u"QSplitter"_s , u"addWidget"_s }, |
122 | {u"QMdiArea"_s , u"addSubWindow"_s } |
123 | }; |
124 | for (const auto &m : addPageMethods) { |
125 | if (extends(classNameIn: name, baseClassName: m.first)) |
126 | return m.second; |
127 | } |
128 | return QString(); |
129 | } |
130 | |
131 | QT_END_NAMESPACE |
132 | |