File indexing completed on 2024-04-28 05:46:50

0001 /*****************************************************************************
0002  *   Copyright 2013 - 2015 Yichao Yu <yyc1992@gmail.com>                     *
0003  *                                                                           *
0004  *   This program is free software; you can redistribute it and/or modify    *
0005  *   it under the terms of the GNU Lesser General Public License as          *
0006  *   published by the Free Software Foundation; either version 2.1 of the    *
0007  *   License, or (at your option) version 3, or any later version accepted   *
0008  *   by the membership of KDE e.V. (or its successor approved by the         *
0009  *   membership of KDE e.V.), which shall act as a proxy defined in          *
0010  *   Section 6 of version 3 of the license.                                  *
0011  *                                                                           *
0012  *   This program is distributed in the hope that it will be useful,         *
0013  *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
0014  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU       *
0015  *   Lesser General Public License for more details.                         *
0016  *                                                                           *
0017  *   You should have received a copy of the GNU Lesser General Public        *
0018  *   License along with this library. If not,                                *
0019  *   see <http://www.gnu.org/licenses/>.                                     *
0020  *****************************************************************************/
0021 
0022 #ifndef __QTC_UTILS_QT_UTILS_H__
0023 #define __QTC_UTILS_QT_UTILS_H__
0024 
0025 #include "utils.h"
0026 #include <QtGlobal>
0027 #include <QWidget>
0028 #include <config.h>
0029 #include <QStyleOption>
0030 #include <QObject>
0031 #include <QRect>
0032 
0033 namespace QtCurve {
0034 
0035 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0) && defined QTC_QT4_ENABLE_KDE) || \
0036     (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) && defined QTC_QT5_ENABLE_KDE)
0037 #define _QTC_QT_ENABLE_KDE 1
0038 #else
0039 #define _QTC_QT_ENABLE_KDE 0
0040 #endif
0041 
0042 #define qtcCheckKDEType(obj, type) (qtcCheckKDETypeFull(obj, type, #type))
0043 
0044 template<typename T, typename T2>
0045 QTC_ALWAYS_INLINE static inline const T*
0046 qtcObjCast(const T2 *obj)
0047 {
0048     return obj ? qobject_cast<const T*>(obj) : nullptr;
0049 }
0050 template<typename T, typename T2>
0051 QTC_ALWAYS_INLINE static inline T*
0052 qtcObjCast(T2 *obj)
0053 {
0054     return obj ? qobject_cast<T*>(obj) : nullptr;
0055 }
0056 
0057 template <class T, class T2> static inline bool
0058 qtcCheckType(T2 *obj)
0059 {
0060     return qtcObjCast<T>(obj);
0061 }
0062 template <class T2> static inline bool
0063 qtcCheckType(T2 *obj, const char *name)
0064 {
0065     return obj && obj->inherits(name);
0066 }
0067 
0068 #if _QTC_QT_ENABLE_KDE
0069 #define qtcCheckKDETypeFull(obj, type, name) (qtcCheckType<type>(obj))
0070 #else
0071 #define qtcCheckKDETypeFull(obj, type, name) (qtcCheckType(obj, name))
0072 #endif
0073 
0074 QTC_ALWAYS_INLINE static inline WId
0075 qtcGetWid(const QWidget *w)
0076 {
0077     if (!(w && w->testAttribute(Qt::WA_WState_Created))) {
0078         return (WId)0;
0079     }
0080     return w->internalWinId();
0081 }
0082 
0083 QTC_ALWAYS_INLINE static inline Qt::WindowType
0084 qtcGetWindowType(const QWidget *w)
0085 {
0086     return w ? w->windowType() : (Qt::WindowType)0;
0087 }
0088 
0089 QTC_ALWAYS_INLINE static inline bool
0090 qtcIsDialog(const QWidget *w)
0091 {
0092     return oneOf(qtcGetWindowType(w), Qt::Dialog, Qt::Sheet);
0093 }
0094 
0095 QTC_ALWAYS_INLINE static inline bool
0096 qtcIsWindow(const QWidget *w)
0097 {
0098     return oneOf(qtcGetWindowType(w), Qt::Window);
0099 }
0100 
0101 QTC_ALWAYS_INLINE static inline bool
0102 qtcIsToolTip(const QWidget *w)
0103 {
0104     return oneOf(qtcGetWindowType(w), Qt::Tool, Qt::SplashScreen,
0105                  Qt::ToolTip, Qt::Drawer);
0106 }
0107 
0108 QTC_ALWAYS_INLINE static inline bool
0109 qtcIsPopup(const QWidget *w)
0110 {
0111     return oneOf(qtcGetWindowType(w), Qt::Popup);
0112 }
0113 
0114 QTC_ALWAYS_INLINE static inline QWidget*
0115 qtcToWidget(QObject *obj)
0116 {
0117     if (obj->isWidgetType()) {
0118         return static_cast<QWidget*>(obj);
0119     }
0120     return nullptr;
0121 }
0122 
0123 QTC_ALWAYS_INLINE static inline const QWidget*
0124 qtcToWidget(const QObject *obj)
0125 {
0126     if (obj->isWidgetType()) {
0127         return static_cast<const QWidget*>(obj);
0128     }
0129     return nullptr;
0130 }
0131 
0132 class Style;
0133 template<class StyleType=Style, class C>
0134 static inline StyleType*
0135 getStyle(const C *obj)
0136 {
0137     QStyle *style = obj->style();
0138     return style ? qobject_cast<StyleType*>(style) : 0;
0139 }
0140 
0141 // Get the width and direction of the arrow in a QBalloonTip
0142 QTC_ALWAYS_INLINE static inline int
0143 qtcGetBalloonMargin(QWidget *widget, bool *atTop)
0144 {
0145     auto margins = widget->contentsMargins();
0146     int topMargin = margins.top();
0147     int bottomMargin = margins.bottom();
0148     if (topMargin > bottomMargin) {
0149         *atTop = true;
0150         return topMargin - bottomMargin;
0151     } else {
0152         *atTop = false;
0153         return bottomMargin - topMargin;
0154     }
0155 }
0156 
0157 template<typename T, typename T2>
0158 QTC_ALWAYS_INLINE static inline const T*
0159 styleOptCast(const T2 *opt)
0160 {
0161     return qstyleoption_cast<const T*>(opt);
0162 }
0163 
0164 template<typename T, typename T2>
0165 QTC_ALWAYS_INLINE static inline T*
0166 styleOptCast(T2 *opt)
0167 {
0168     return qstyleoption_cast<T*>(opt);
0169 }
0170 
0171 template<unsigned level=1>
0172 QTC_ALWAYS_INLINE static inline QWidget*
0173 getParent(const QWidget *w)
0174 {
0175     if (const QWidget *parent = getParent<level - 1>(w)) {
0176         return parent->parentWidget();
0177     }
0178     return nullptr;
0179 }
0180 
0181 template<>
0182 inline QWidget*
0183 getParent<0>(const QWidget *w)
0184 {
0185     return const_cast<QWidget*>(w);
0186 }
0187 
0188 template<unsigned level=1>
0189 QTC_ALWAYS_INLINE static inline QObject*
0190 getParent(const QObject *o)
0191 {
0192     if (const QObject *parent = getParent<level - 1>(o)) {
0193         return parent->parent();
0194     }
0195     return nullptr;
0196 }
0197 
0198 template<>
0199 inline QObject*
0200 getParent<0>(const QObject *o)
0201 {
0202     return const_cast<QObject*>(o);
0203 }
0204 
0205 #define _qtcSlotWithTypes(self, name, types)                    \
0206     self, static_cast<void(qtcPtrType<decltype(self)>::*)types> \
0207         (qtcMemPtr(self, name))
0208 
0209 #define _qtcSlotWithoutTypes(self, name)        \
0210     self, qtcMemPtr(self, name)
0211 
0212 #define qtcSlot(self, name, types...)                           \
0213     QTC_SWITCH(types, _qtcSlotWithTypes, _qtcSlotWithoutTypes)  \
0214     (self, name, ##types)
0215 
0216 static inline QRect centerRect(const QRect &rect, int width, int height)
0217 {
0218     return QRect(rect.left() + (rect.width() - width) / 2,
0219                  rect.top() + (rect.height() - height) / 2, width, height);
0220 }
0221 
0222 static inline QRect centerRect(const QRect &rect, const QSize &size)
0223 {
0224     return centerRect(rect, size.width(), size.height());
0225 }
0226 
0227 }
0228 
0229 #endif