1 | // Copyright (C) 2016 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #ifndef QSTYLESHEETSTYLE_P_H |
5 | #define QSTYLESHEETSTYLE_P_H |
6 | |
7 | #include <QtWidgets/private/qtwidgetsglobal_p.h> |
8 | #include "private/qwindowsstyle_p.h" |
9 | |
10 | #ifndef QT_NO_STYLE_STYLESHEET |
11 | |
12 | #include "QtWidgets/qapplication.h" |
13 | #include "QtWidgets/qstyleoption.h" |
14 | #include "QtCore/qhash.h" |
15 | #include "QtCore/qlist.h" |
16 | #include "QtCore/qset.h" |
17 | #include "QtGui/qbrush.h" |
18 | #include "QtGui/qevent.h" |
19 | #include "private/qcssparser_p.h" |
20 | |
21 | QT_BEGIN_NAMESPACE |
22 | |
23 | // |
24 | // W A R N I N G |
25 | // ------------- |
26 | // |
27 | // This file is not part of the Qt API. It exists purely as an |
28 | // implementation detail. This header file may change from version to |
29 | // version without notice, or even be removed. |
30 | // |
31 | // We mean it. |
32 | // |
33 | |
34 | class QRenderRule; |
35 | class QAbstractScrollArea; |
36 | class QStyleSheetStylePrivate; |
37 | class QStyleOptionTitleBar; |
38 | |
39 | class Q_AUTOTEST_EXPORT QStyleSheetStyle : public QWindowsStyle |
40 | { |
41 | typedef QWindowsStyle ParentStyle; |
42 | |
43 | Q_OBJECT |
44 | public: |
45 | QStyleSheetStyle(QStyle *baseStyle); |
46 | ~QStyleSheetStyle(); |
47 | |
48 | void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p, |
49 | const QWidget *w = nullptr) const override; |
50 | void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p, |
51 | const QWidget *w = nullptr) const override; |
52 | void drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, const QPixmap &pixmap) const override; |
53 | void drawItemText(QPainter *painter, const QRect& rect, int alignment, const QPalette &pal, |
54 | bool enabled, const QString& text, QPalette::ColorRole textRole = QPalette::NoRole) const override; |
55 | void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p, |
56 | const QWidget *w = nullptr) const override; |
57 | QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, |
58 | const QStyleOption *option) const override; |
59 | SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, |
60 | const QPoint &pt, const QWidget *w = nullptr) const override; |
61 | QRect itemPixmapRect(const QRect &rect, int alignment, const QPixmap &pixmap) const override; |
62 | QRect itemTextRect(const QFontMetrics &metrics, const QRect &rect, int alignment, bool enabled, |
63 | const QString &text) const override; |
64 | int pixelMetric(PixelMetric metric, const QStyleOption *option = nullptr, const QWidget *widget = nullptr) const override; |
65 | void polish(QWidget *widget) override; |
66 | void polish(QApplication *app) override; |
67 | void polish(QPalette &pal) override; |
68 | QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, |
69 | const QSize &contentsSize, const QWidget *widget = nullptr) const override; |
70 | QPalette standardPalette() const override; |
71 | QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *opt = nullptr, |
72 | const QWidget *widget = nullptr) const override; |
73 | QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *option = nullptr, |
74 | const QWidget *w = nullptr ) const override; |
75 | int layoutSpacing(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2, |
76 | Qt::Orientation orientation, const QStyleOption *option = nullptr, |
77 | const QWidget *widget = nullptr) const override; |
78 | int styleHint(StyleHint sh, const QStyleOption *opt = nullptr, const QWidget *w = nullptr, |
79 | QStyleHintReturn *shret = nullptr) const override; |
80 | QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget = nullptr) const override; |
81 | QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, |
82 | const QWidget *w = nullptr) const override; |
83 | |
84 | // These functions are called from QApplication/QWidget. Be careful. |
85 | QStyle *baseStyle() const; |
86 | void repolish(QWidget *widget); |
87 | void repolish(QApplication *app); |
88 | |
89 | void unpolish(QWidget *widget) override; |
90 | void unpolish(QApplication *app) override; |
91 | |
92 | QStyle *base; |
93 | void ref() { ++refcount; } |
94 | void deref() { Q_ASSERT(refcount > 0); if (!--refcount) delete this; } |
95 | |
96 | void updateStyleSheetFont(QWidget* w) const; |
97 | void saveWidgetFont(QWidget* w, const QFont& font) const; |
98 | void clearWidgetFont(QWidget* w) const; |
99 | |
100 | bool styleSheetPalette(const QWidget* w, const QStyleOption* opt, QPalette* pal); |
101 | |
102 | protected: |
103 | bool event(QEvent *e) override; |
104 | |
105 | private: |
106 | int refcount; |
107 | |
108 | friend class QRenderRule; |
109 | int nativeFrameWidth(const QWidget *); |
110 | QRenderRule renderRule(const QObject *, int, quint64 = 0) const; |
111 | QRenderRule renderRule(const QObject *, const QStyleOption *, int = 0) const; |
112 | QSize defaultSize(const QWidget *, QSize, const QRect&, int) const; |
113 | QRect positionRect(const QWidget *, const QRenderRule&, const QRenderRule&, int, |
114 | const QRect&, Qt::LayoutDirection) const; |
115 | QRect positionRect(const QWidget *w, const QRenderRule &rule2, int pe, |
116 | const QRect &originRect, Qt::LayoutDirection dir) const; |
117 | |
118 | mutable QCss::Parser parser; |
119 | |
120 | void setPalette(QWidget *); |
121 | void unsetPalette(QWidget *); |
122 | void setProperties(QWidget *); |
123 | void setGeometry(QWidget *); |
124 | void unsetStyleSheetFont(QWidget *) const; |
125 | QList<QCss::StyleRule> styleRules(const QObject *obj) const; |
126 | bool hasStyleRule(const QObject *obj, int part) const; |
127 | |
128 | QHash<QStyle::SubControl, QRect> titleBarLayout(const QWidget *w, const QStyleOptionTitleBar *tb) const; |
129 | |
130 | QCss::StyleSheet getDefaultStyleSheet() const; |
131 | |
132 | static Qt::Alignment resolveAlignment(Qt::LayoutDirection, Qt::Alignment); |
133 | static bool isNaturalChild(const QObject *obj); |
134 | static QPixmap loadPixmap(const QString &fileName, const QObject *context); |
135 | bool initObject(const QObject *obj) const; |
136 | void (const QStyleOptionMenuItem *mi, QPainter *p, const QWidget *w, |
137 | const QRect &rect, QRenderRule &subRule) const; |
138 | public: |
139 | static int numinstances; |
140 | |
141 | private: |
142 | Q_DISABLE_COPY_MOVE(QStyleSheetStyle) |
143 | Q_DECLARE_PRIVATE(QStyleSheetStyle) |
144 | }; |
145 | |
146 | class QStyleSheetStyleCaches : public QObject |
147 | { |
148 | Q_OBJECT |
149 | public Q_SLOTS: |
150 | void objectDestroyed(QObject *); |
151 | void styleDestroyed(QObject *); |
152 | public: |
153 | QHash<const QObject *, QList<QCss::StyleRule>> styleRulesCache; |
154 | QHash<const QObject *, QHash<int, bool> > hasStyleRuleCache; |
155 | typedef QHash<int, QHash<quint64, QRenderRule> > QRenderRules; |
156 | QHash<const QObject *, QRenderRules> renderRulesCache; |
157 | QHash<const void *, QCss::StyleSheet> styleSheetCache; // parsed style sheets |
158 | QSet<const QWidget *> autoFillDisabledWidgets; |
159 | // widgets with whose palettes and fonts we have tampered: |
160 | template <typename T> |
161 | struct Tampered { |
162 | T oldWidgetValue; |
163 | decltype(std::declval<T>().resolveMask()) resolveMask; |
164 | |
165 | // only call this function on an rvalue *this (it mangles oldWidgetValue) |
166 | T reverted(T current) |
167 | #ifdef Q_COMPILER_REF_QUALIFIERS |
168 | && |
169 | #endif |
170 | { |
171 | oldWidgetValue.setResolveMask(oldWidgetValue.resolveMask() & resolveMask); |
172 | current.setResolveMask(current.resolveMask() & ~resolveMask); |
173 | current.resolve(oldWidgetValue); |
174 | current.setResolveMask(current.resolveMask() | oldWidgetValue.resolveMask()); |
175 | return current; |
176 | } |
177 | }; |
178 | QHash<const QWidget *, Tampered<QPalette>> customPaletteWidgets; |
179 | QHash<const QWidget *, Tampered<QFont>> customFontWidgets; |
180 | }; |
181 | template <typename T> |
182 | class QTypeInfo<QStyleSheetStyleCaches::Tampered<T>> |
183 | : public QTypeInfoMerger<QStyleSheetStyleCaches::Tampered<T>, T> {}; |
184 | |
185 | |
186 | // Returns a QStyleSheet from the given style. |
187 | inline QStyleSheetStyle* qt_styleSheet(QStyle *style) |
188 | { |
189 | return qobject_cast<QStyleSheetStyle *>(object: style); |
190 | } |
191 | |
192 | QT_END_NAMESPACE |
193 | #endif // QT_NO_STYLE_STYLESHEET |
194 | #endif // QSTYLESHEETSTYLE_P_H |
195 | |