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