1 /*****************************************************************************
2  *   Copyright 2007 - 2010 Craig Drummond <craig.p.drummond@gmail.com>       *
3  *   Copyright 2013 - 2015 Yichao Yu <yyc1992@gmail.com>                     *
4  *                                                                           *
5  *   This program is free software; you can redistribute it and/or modify    *
6  *   it under the terms of the GNU Lesser General Public License as          *
7  *   published by the Free Software Foundation; either version 2.1 of the    *
8  *   License, or (at your option) version 3, or any later version accepted   *
9  *   by the membership of KDE e.V. (or its successor approved by the         *
10  *   membership of KDE e.V.), which shall act as a proxy defined in          *
11  *   Section 6 of version 3 of the license.                                  *
12  *                                                                           *
13  *   This program is distributed in the hope that it will be useful,         *
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU       *
16  *   Lesser General Public License for more details.                         *
17  *                                                                           *
18  *   You should have received a copy of the GNU Lesser General Public        *
19  *   License along with this library. If not,                                *
20  *   see <http://www.gnu.org/licenses/>.                                     *
21  *****************************************************************************/
22 
23 #include "qtcurve_plugin.h"
24 #include "qtcurve.h"
25 #include "config.h"
26 
27 #include <qtcurve-utils/qtprops.h>
28 #include <qtcurve-utils/x11base.h>
29 
30 #ifdef Q_WS_X11
31 #  include <QX11Info>
32 #endif
33 
34 #include <QTypeInfo>
35 #include <QFileInfo>
36 #include <QDir>
37 
38 #include <mutex>
39 
40 namespace QtCurve {
41 
42 #ifdef QTC_QT4_STYLE_SUPPORT
43 static void
getStyles(const QString & dir,const char * sub,QSet<QString> & styles)44 getStyles(const QString &dir, const char *sub, QSet<QString> &styles)
45 {
46     QDir d(dir + sub);
47 
48     if (d.exists()) {
49         QStringList filters;
50 
51         filters << QString(THEME_PREFIX "*" THEME_SUFFIX);
52         d.setNameFilters(filters);
53 
54         foreach (const QString &str, d.entryList()) {
55             QString style(str.left(str.lastIndexOf(THEME_SUFFIX)));
56             if (!styles.contains(style)) {
57                 styles.insert(style);
58             }
59         }
60     }
61 }
62 
63 static void
getStyles(const QString & dir,QSet<QString> & styles)64 getStyles(const QString &dir, QSet<QString> &styles)
65 {
66     getStyles(dir, THEME_DIR, styles);
67     getStyles(dir, THEME_DIR4, styles);
68 }
69 #endif
70 
71 QStringList
keys() const72 StylePlugin::keys() const
73 {
74     QSet<QString> styles;
75     styles.insert("QtCurve");
76 
77 #ifdef QTC_QT4_STYLE_SUPPORT
78     getStyles(Utils::kdeHome(), styles);
79     getStyles(KDE_PREFIX(4), styles);
80 #endif
81     return styles.toList();
82 }
83 
84 QStyle*
create(const QString & key)85 StylePlugin::create(const QString &key)
86 {
87     // init needs to be called before Style is created
88     init();
89     if (key.toLower() == "qtcurve") {
90         return new Style;
91     }
92 #ifdef QTC_QT4_STYLE_SUPPORT
93     if (key.indexOf(THEME_PREFIX) == 0) {
94         return new Style(key);
95     }
96 #endif
97     return 0;
98 }
99 
100 __attribute__((hot)) static bool
qtcEventCallback(void ** cbdata)101 qtcEventCallback(void **cbdata)
102 {
103     QObject *receiver = (QObject*)cbdata[0];
104     QTC_RET_IF_FAIL(receiver, false);
105     QEvent *event = (QEvent*)cbdata[1];
106     if (qtcUnlikely(event->type() == QEvent::DynamicPropertyChange)) {
107         QDynamicPropertyChangeEvent *prop_event =
108             static_cast<QDynamicPropertyChangeEvent*>(event);
109         // eat the property change events from ourselves
110         if (prop_event->propertyName() == QTC_PROP_NAME) {
111             return true;
112         }
113     }
114     QWidget *widget = qtcToWidget(receiver);
115     if (!widget)
116         return false;
117     if (qtcUnlikely(!widget->testAttribute(Qt::WA_WState_Polished) &&
118                     !qtcGetWid(widget))) {
119         if (Style *style = getStyle(widget)) {
120             style->prePolish(widget);
121         }
122     } else if (event->type() == QEvent::UpdateRequest) {
123         QtcQWidgetProps(widget)->opacity = 100;
124     }
125     return false;
126 }
127 
128 void
init()129 StylePlugin::init()
130 {
131     static std::once_flag ref_flag;
132     std::call_once(ref_flag, [] {
133         QInternal::registerCallback(QInternal::EventNotifyCallback,
134                                     qtcEventCallback);
135 #ifdef Q_WS_X11
136         qtcX11InitXlib(QX11Info::display());
137 #endif
138         });
139 }
140 
141 Q_EXPORT_PLUGIN2(Style, StylePlugin)
142 
143 }
144