1 /*****************************************************************************
2 * Copyright 2013 - 2015 Yichao Yu <yyc1992@gmail.com> *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU Lesser General Public License as *
6 * published by the Free Software Foundation; either version 2.1 of the *
7 * License, or (at your option) version 3, or any later version accepted *
8 * by the membership of KDE e.V. (or its successor approved by the *
9 * membership of KDE e.V.), which shall act as a proxy defined in *
10 * Section 6 of version 3 of the license. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
15 * Lesser General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU Lesser General Public *
18 * License along with this library. If not, *
19 * see <http://www.gnu.org/licenses/>. *
20 *****************************************************************************/
21
22 #ifndef __QTC_UTILS_QT_UTILS_H__
23 #define __QTC_UTILS_QT_UTILS_H__
24
25 #include "utils.h"
26 #include <QtGlobal>
27 #include <QWidget>
28 #include <config.h>
29 #include <QStyleOption>
30 #include <QObject>
31 #include <QRect>
32
33 namespace QtCurve {
34
35 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0) && defined QTC_QT4_ENABLE_KDE) || \
36 (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) && defined QTC_QT5_ENABLE_KDE)
37 #define _QTC_QT_ENABLE_KDE 1
38 #else
39 #define _QTC_QT_ENABLE_KDE 0
40 #endif
41
42 #define qtcCheckKDEType(obj, type) (qtcCheckKDETypeFull(obj, type, #type))
43
44 template<typename T, typename T2>
45 QTC_ALWAYS_INLINE static inline const T*
qtcObjCast(const T2 * obj)46 qtcObjCast(const T2 *obj)
47 {
48 return obj ? qobject_cast<const T*>(obj) : nullptr;
49 }
50 template<typename T, typename T2>
51 QTC_ALWAYS_INLINE static inline T*
qtcObjCast(T2 * obj)52 qtcObjCast(T2 *obj)
53 {
54 return obj ? qobject_cast<T*>(obj) : nullptr;
55 }
56
57 template <class T, class T2> static inline bool
qtcCheckType(T2 * obj)58 qtcCheckType(T2 *obj)
59 {
60 return qtcObjCast<T>(obj);
61 }
62 template <class T2> static inline bool
qtcCheckType(T2 * obj,const char * name)63 qtcCheckType(T2 *obj, const char *name)
64 {
65 return obj && obj->inherits(name);
66 }
67
68 #if _QTC_QT_ENABLE_KDE
69 #define qtcCheckKDETypeFull(obj, type, name) (qtcCheckType<type>(obj))
70 #else
71 #define qtcCheckKDETypeFull(obj, type, name) (qtcCheckType(obj, name))
72 #endif
73
74 QTC_ALWAYS_INLINE static inline WId
qtcGetWid(const QWidget * w)75 qtcGetWid(const QWidget *w)
76 {
77 if (!(w && w->testAttribute(Qt::WA_WState_Created))) {
78 return (WId)0;
79 }
80 return w->internalWinId();
81 }
82
83 QTC_ALWAYS_INLINE static inline Qt::WindowType
qtcGetWindowType(const QWidget * w)84 qtcGetWindowType(const QWidget *w)
85 {
86 return w ? w->windowType() : (Qt::WindowType)0;
87 }
88
89 QTC_ALWAYS_INLINE static inline bool
qtcIsDialog(const QWidget * w)90 qtcIsDialog(const QWidget *w)
91 {
92 return oneOf(qtcGetWindowType(w), Qt::Dialog, Qt::Sheet);
93 }
94
95 QTC_ALWAYS_INLINE static inline bool
qtcIsWindow(const QWidget * w)96 qtcIsWindow(const QWidget *w)
97 {
98 return oneOf(qtcGetWindowType(w), Qt::Window);
99 }
100
101 QTC_ALWAYS_INLINE static inline bool
qtcIsToolTip(const QWidget * w)102 qtcIsToolTip(const QWidget *w)
103 {
104 return oneOf(qtcGetWindowType(w), Qt::Tool, Qt::SplashScreen,
105 Qt::ToolTip, Qt::Drawer);
106 }
107
108 QTC_ALWAYS_INLINE static inline bool
qtcIsPopup(const QWidget * w)109 qtcIsPopup(const QWidget *w)
110 {
111 return oneOf(qtcGetWindowType(w), Qt::Popup);
112 }
113
114 QTC_ALWAYS_INLINE static inline QWidget*
qtcToWidget(QObject * obj)115 qtcToWidget(QObject *obj)
116 {
117 if (obj->isWidgetType()) {
118 return static_cast<QWidget*>(obj);
119 }
120 return nullptr;
121 }
122
123 QTC_ALWAYS_INLINE static inline const QWidget*
qtcToWidget(const QObject * obj)124 qtcToWidget(const QObject *obj)
125 {
126 if (obj->isWidgetType()) {
127 return static_cast<const QWidget*>(obj);
128 }
129 return nullptr;
130 }
131
132 class Style;
133 template<class StyleType=Style, class C>
134 static inline StyleType*
getStyle(const C * obj)135 getStyle(const C *obj)
136 {
137 QStyle *style = obj->style();
138 return style ? qobject_cast<StyleType*>(style) : 0;
139 }
140
141 // Get the width and direction of the arrow in a QBalloonTip
142 QTC_ALWAYS_INLINE static inline int
qtcGetBalloonMargin(QWidget * widget,bool * atTop)143 qtcGetBalloonMargin(QWidget *widget, bool *atTop)
144 {
145 int topMargin = 0;
146 int bottomMargin = 0;
147 widget->getContentsMargins(nullptr, &topMargin, nullptr, &bottomMargin);
148 if (topMargin > bottomMargin) {
149 *atTop = true;
150 return topMargin - bottomMargin;
151 } else {
152 *atTop = false;
153 return bottomMargin - topMargin;
154 }
155 }
156
157 template<typename T, typename T2>
158 QTC_ALWAYS_INLINE static inline const T*
styleOptCast(const T2 * opt)159 styleOptCast(const T2 *opt)
160 {
161 return qstyleoption_cast<const T*>(opt);
162 }
163
164 template<typename T, typename T2>
165 QTC_ALWAYS_INLINE static inline T*
styleOptCast(T2 * opt)166 styleOptCast(T2 *opt)
167 {
168 return qstyleoption_cast<T*>(opt);
169 }
170
171 template<unsigned level=1>
172 QTC_ALWAYS_INLINE static inline QWidget*
getParent(const QWidget * w)173 getParent(const QWidget *w)
174 {
175 if (const QWidget *parent = getParent<level - 1>(w)) {
176 return parent->parentWidget();
177 }
178 return nullptr;
179 }
180
181 template<>
182 inline QWidget*
183 getParent<0>(const QWidget *w)
184 {
185 return const_cast<QWidget*>(w);
186 }
187
188 template<unsigned level=1>
189 QTC_ALWAYS_INLINE static inline QObject*
getParent(const QObject * o)190 getParent(const QObject *o)
191 {
192 if (const QObject *parent = getParent<level - 1>(o)) {
193 return parent->parent();
194 }
195 return nullptr;
196 }
197
198 template<>
199 inline QObject*
200 getParent<0>(const QObject *o)
201 {
202 return const_cast<QObject*>(o);
203 }
204
205 #define _qtcSlotWithTypes(self, name, types) \
206 self, static_cast<void(qtcPtrType<decltype(self)>::*)types> \
207 (qtcMemPtr(self, name))
208
209 #define _qtcSlotWithoutTypes(self, name) \
210 self, qtcMemPtr(self, name)
211
212 #define qtcSlot(self, name, types...) \
213 QTC_SWITCH(types, _qtcSlotWithTypes, _qtcSlotWithoutTypes) \
214 (self, name, ##types)
215
centerRect(const QRect & rect,int width,int height)216 static inline QRect centerRect(const QRect &rect, int width, int height)
217 {
218 return QRect(rect.left() + (rect.width() - width) / 2,
219 rect.top() + (rect.height() - height) / 2, width, height);
220 }
221
centerRect(const QRect & rect,const QSize & size)222 static inline QRect centerRect(const QRect &rect, const QSize &size)
223 {
224 return centerRect(rect, size.width(), size.height());
225 }
226
227 }
228
229 #endif
230