Changeset View
Changeset View
Standalone View
Standalone View
kcms/style/kcmstyle.cpp
1 | /* | 1 | /* | ||
---|---|---|---|---|---|
2 | * KCMStyle | 2 | * KCMStyle | ||
3 | * Copyright (C) 2002 Karol Szwed <gallium@kde.org> | 3 | * Copyright (C) 2002 Karol Szwed <gallium@kde.org> | ||
4 | * Copyright (C) 2002 Daniel Molkentin <molkentin@kde.org> | 4 | * Copyright (C) 2002 Daniel Molkentin <molkentin@kde.org> | ||
5 | * Copyright (C) 2007 Urs Wolfer <uwolfer @ kde.org> | 5 | * Copyright (C) 2007 Urs Wolfer <uwolfer @ kde.org> | ||
6 | * Copyright (C) 2009 by Davide Bettio <davide.bettio@kdemail.net> | 6 | * Copyright (C) 2009 by Davide Bettio <davide.bettio@kdemail.net> | ||
7 | 7 | * Copyright (C) 2019 Kai Uwe Broulik <kde@broulik.de> | |||
8 | * | ||||
8 | * Portions Copyright (C) 2007 Paolo Capriotti <p.capriotti@gmail.com> | 9 | * Portions Copyright (C) 2007 Paolo Capriotti <p.capriotti@gmail.com> | ||
9 | * Portions Copyright (C) 2007 Ivan Cukic <ivan.cukic+kde@gmail.com> | 10 | * Portions Copyright (C) 2007 Ivan Cukic <ivan.cukic+kde@gmail.com> | ||
10 | * Portions Copyright (C) 2008 by Petri Damsten <damu@iki.fi> | 11 | * Portions Copyright (C) 2008 by Petri Damsten <damu@iki.fi> | ||
11 | * Portions Copyright (C) 2000 TrollTech AS. | 12 | * Portions Copyright (C) 2000 TrollTech AS. | ||
12 | * | 13 | * | ||
13 | * This program is free software; you can redistribute it and/or | 14 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public | 15 | * modify it under the terms of the GNU General Public | ||
15 | * License version 2 as published by the Free Software Foundation. | 16 | * License version 2 as published by the Free Software Foundation. | ||
16 | * | 17 | * | ||
17 | * This program is distributed in the hope that it will be useful, | 18 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
20 | * General Public License for more details. | 21 | * General Public License for more details. | ||
21 | * | 22 | * | ||
22 | * You should have received a copy of the GNU General Public License | 23 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; see the file COPYING. If not, write to | 24 | * along with this program; see the file COPYING. If not, write to | ||
24 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 25 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
25 | * Boston, MA 02110-1301, USA. | 26 | * Boston, MA 02110-1301, USA. | ||
26 | */ | 27 | */ | ||
27 | 28 | | |||
28 | #include "kcmstyle.h" | 29 | #include "kcmstyle.h" | ||
29 | 30 | | |||
30 | #if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) | | |||
31 | #include <config-X11.h> | | |||
32 | #endif | | |||
33 | | ||||
34 | #include "styleconfdialog.h" | 31 | #include "styleconfdialog.h" | ||
35 | #include "ui_stylepreview.h" | | |||
36 | #include "ui_styleconfig.h" | | |||
37 | 32 | | |||
38 | #include <kaboutdata.h> | 33 | #include <KAboutData> | ||
39 | //#include <kapplication.h> | | |||
40 | #include <kcombobox.h> | | |||
41 | #include <kmessagebox.h> | | |||
42 | #include <kautostart.h> | | |||
43 | #include <KLocalizedString> | | |||
44 | #include <KLibrary> | | |||
45 | #include <KColorScheme> | | |||
46 | #include <KStandardDirs> | | |||
47 | #include <KNewStuff3/KNS3/DownloadDialog> | | |||
48 | #include <KConfigGroup> | 34 | #include <KConfigGroup> | ||
35 | #include <KLocalizedString> | ||||
36 | #include <KPluginFactory> | ||||
37 | #include <KPluginLoader> | ||||
49 | 38 | | |||
50 | #include <QFile> | 39 | #include <QLibrary> | ||
51 | #include <QSettings> | 40 | #include <QMetaEnum> | ||
52 | #include <QAbstractItemView> | 41 | #include <QQuickItem> | ||
53 | #include <QLabel> | 42 | #include <QQuickWindow> | ||
54 | #include <QGroupBox> | 43 | #include <QScopedPointer> | ||
55 | #include <QPainter> | | |||
56 | #include <QPixmapCache> | | |||
57 | #include <QStyleFactory> | 44 | #include <QStyleFactory> | ||
58 | #include <QFormLayout> | 45 | #include <QWidget> | ||
59 | #include <QStandardItemModel> | 46 | #include <QWindow> | ||
60 | #include <QDBusConnection> | | |||
61 | #include <QDBusMessage> | | |||
62 | #include <QStyle> | | |||
63 | 47 | | |||
64 | #include <KGlobal> | 48 | #include <KGlobal> | ||
65 | #include <KGlobalSettings> | 49 | #include <KGlobalSettings> | ||
66 | 50 | | |||
67 | #if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) | | |||
68 | #include <QX11Info> | | |||
69 | #endif | | |||
70 | | ||||
71 | #include "../krdb/krdb.h" | 51 | #include "../krdb/krdb.h" | ||
72 | 52 | | |||
73 | #if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) | 53 | #include "stylesmodel.h" | ||
74 | #include <X11/Xlib.h> | 54 | #include "previewitem.h" | ||
75 | #endif | | |||
76 | | ||||
77 | // X11 namespace cleanup | | |||
78 | #undef Bool | | |||
79 | #undef Below | | |||
80 | #undef KeyPress | | |||
81 | #undef KeyRelease | | |||
82 | | ||||
83 | | ||||
84 | /**** DLL Interface for kcontrol ****/ | | |||
85 | | ||||
86 | #include <kpluginfactory.h> | | |||
87 | #include <kpluginloader.h> | | |||
88 | | ||||
89 | K_PLUGIN_FACTORY(KCMStyleFactory, registerPlugin<KCMStyle>();) | | |||
90 | K_EXPORT_PLUGIN(KCMStyleFactory("kcmstyle")) | | |||
91 | 55 | | |||
56 | K_PLUGIN_FACTORY_WITH_JSON(KCMStyleFactory, "kcm_style.json", registerPlugin<KCMStyle>();) | ||||
92 | 57 | | |||
93 | extern "C" | 58 | extern "C" | ||
94 | { | 59 | { | ||
95 | Q_DECL_EXPORT void kcminit_style() | 60 | Q_DECL_EXPORT void kcminit_style() | ||
96 | { | 61 | { | ||
97 | uint flags = KRdbExportQtSettings | KRdbExportGtkColors | KRdbExportQtColors | KRdbExportXftSettings | KRdbExportGtkTheme; | 62 | uint flags = KRdbExportQtSettings | KRdbExportGtkColors | KRdbExportQtColors | KRdbExportXftSettings | KRdbExportGtkTheme; | ||
98 | KConfig _config( QStringLiteral("kcmdisplayrc"), KConfig::NoGlobals ); | 63 | KConfig _config( QStringLiteral("kcmdisplayrc"), KConfig::NoGlobals ); | ||
99 | KConfigGroup config(&_config, "X11"); | 64 | KConfigGroup config(&_config, "X11"); | ||
100 | 65 | | |||
101 | // This key is written by the "colors" module. | 66 | // This key is written by the "colors" module. | ||
102 | bool exportKDEColors = config.readEntry("exportKDEColors", true); | 67 | bool exportKDEColors = config.readEntry("exportKDEColors", true); | ||
103 | if (exportKDEColors) | 68 | if (exportKDEColors) | ||
104 | flags |= KRdbExportColors; | 69 | flags |= KRdbExportColors; | ||
105 | runRdb( flags ); | 70 | runRdb( flags ); | ||
106 | } | 71 | } | ||
107 | } | 72 | } | ||
108 | 73 | | |||
109 | class StylePreview : public QWidget, public Ui::StylePreview | | |||
110 | { | | |||
111 | public: | | |||
112 | StylePreview(QWidget *parent = nullptr) | | |||
113 | : QWidget(parent) | | |||
114 | { | | |||
115 | setupUi(this); | | |||
116 | | ||||
117 | // Ensure that the user can't toy with the child widgets. | | |||
118 | // Method borrowed from Qt's qtconfig. | | |||
119 | QList<QWidget*> widgets = findChildren<QWidget*>(); | | |||
120 | foreach (QWidget* widget, widgets) | | |||
121 | { | | |||
122 | widget->installEventFilter(this); | | |||
123 | widget->setFocusPolicy(Qt::NoFocus); | | |||
124 | } | | |||
125 | } | | |||
126 | | ||||
127 | bool eventFilter( QObject* /* obj */, QEvent* ev ) override | | |||
128 | { | | |||
129 | switch( ev->type() ) | | |||
130 | { | | |||
131 | case QEvent::MouseButtonPress: | | |||
132 | case QEvent::MouseButtonRelease: | | |||
133 | case QEvent::MouseButtonDblClick: | | |||
134 | case QEvent::MouseMove: | | |||
135 | case QEvent::KeyPress: | | |||
136 | case QEvent::KeyRelease: | | |||
137 | case QEvent::Enter: | | |||
138 | case QEvent::Leave: | | |||
139 | case QEvent::Wheel: | | |||
140 | case QEvent::ContextMenu: | | |||
141 | return true; // ignore | | |||
142 | default: | | |||
143 | break; | | |||
144 | } | | |||
145 | return false; | | |||
146 | } | | |||
147 | }; | | |||
148 | | ||||
149 | class StyleConfig : public QWidget, public Ui::StyleConfig | | |||
150 | { | | |||
151 | public: | | |||
152 | StyleConfig(QWidget *parent = nullptr) | | |||
153 | : QWidget(parent) | | |||
154 | { | | |||
155 | setupUi(this); | | |||
156 | } | | |||
157 | }; | | |||
158 | | ||||
159 | QString KCMStyle::defaultStyle() | 74 | QString KCMStyle::defaultStyle() | ||
160 | { | 75 | { | ||
161 | #if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) | 76 | return QStringLiteral("Breeze"); | ||
162 | return QStringLiteral("breeze"); | | |||
163 | #else | | |||
164 | return QString(); // native style | | |||
165 | #endif | | |||
166 | } | 77 | } | ||
167 | 78 | | |||
168 | KCMStyle::KCMStyle( QWidget* parent, const QVariantList& ) | 79 | KCMStyle::KCMStyle(QObject *parent, const QVariantList &args) | ||
169 | : KCModule( parent ), appliedStyle(nullptr) | 80 | : KQuickAddons::ConfigModule(parent, args) | ||
81 | , m_model(new StylesModel(this)) | ||||
170 | { | 82 | { | ||
171 | setQuickHelp( i18n("This module allows you to modify the visual appearance " | 83 | qmlRegisterUncreatableType<KCMStyle>("org.kde.private.kcms.style", 1, 0, "KCM", QStringLiteral("Cannot create instances of KCM")); | ||
172 | "of applications' user interface elements.")); | 84 | qmlRegisterType<StylesModel>(); | ||
173 | 85 | qmlRegisterType<PreviewItem>("org.kde.private.kcms.style", 1, 0, "PreviewItem"); | |||
174 | m_bStyleDirty= false; | | |||
175 | m_bEffectsDirty = false; | | |||
176 | | ||||
177 | | ||||
178 | KGlobal::dirs()->addResourceType("themes", "data", "kstyle/themes"); | | |||
179 | 86 | | |||
180 | KAboutData *about = | 87 | KAboutData *about = | ||
181 | new KAboutData( QStringLiteral("kcmstyle"), i18n("Application Style"), QStringLiteral("1.0"), | 88 | new KAboutData( QStringLiteral("kcm_style"), i18n("Application Style"), QStringLiteral("2.0"), | ||
182 | QString(), KAboutLicense::GPL, | 89 | QString(), KAboutLicense::GPL, | ||
183 | i18n("(c) 2002 Karol Szwed, Daniel Molkentin")); | 90 | i18n("(c) 2002 Karol Szwed, Daniel Molkentin, (c) 2019 Kai Uwe Broulik")); | ||
184 | 91 | | |||
185 | about->addAuthor(i18n("Karol Szwed"), QString(), QStringLiteral("gallium@kde.org")); | 92 | about->addAuthor(i18n("Karol Szwed"), QString(), QStringLiteral("gallium@kde.org")); | ||
186 | about->addAuthor(i18n("Daniel Molkentin"), QString(), QStringLiteral("molkentin@kde.org")); | 93 | about->addAuthor(i18n("Daniel Molkentin"), QString(), QStringLiteral("molkentin@kde.org")); | ||
94 | about->addAuthor(i18n("Kai Uwe Broulik"), QString(), QStringLiteral("kde@broulik.de")); | ||||
187 | setAboutData( about ); | 95 | setAboutData(about); | ||
188 | 96 | | |||
189 | // Setup mainLayout | 97 | connect(m_model, &StylesModel::selectedStyleChanged, this, [this] { | ||
190 | mainLayout = new QVBoxLayout( this ); | 98 | m_selectedStyleDirty = true; | ||
191 | mainLayout->setContentsMargins(0, 0, 0, 0); | 99 | setNeedsSave(true); | ||
192 | 100 | }); | |||
193 | styleConfig = new StyleConfig(); | | |||
194 | | ||||
195 | QHBoxLayout *previewLayout = new QHBoxLayout(); | | |||
196 | QGroupBox *gbPreview = new QGroupBox( i18n( "Preview" ) ); | | |||
197 | QHBoxLayout *previewLayoutInner = new QHBoxLayout(gbPreview); | | |||
198 | previewLayout->setContentsMargins(0, 0, 0, 0); | | |||
199 | previewLayoutInner->setContentsMargins(0, 0, 0, 0); | | |||
200 | previewLayout->addStretch(); | | |||
201 | previewLayout->addWidget( gbPreview ); | | |||
202 | previewLayout->addStretch(); | | |||
203 | | ||||
204 | stylePreview = new StylePreview( gbPreview ); | | |||
205 | previewLayoutInner->addWidget( stylePreview ); | | |||
206 | | ||||
207 | mainLayout->addWidget( styleConfig ); | | |||
208 | mainLayout->addLayout( previewLayout ); | | |||
209 | mainLayout->addStretch(); | | |||
210 | | ||||
211 | connect( styleConfig->comboStyle, SIGNAL(activated(int)), this, SLOT(styleChanged()) ); | | |||
212 | connect( styleConfig->comboStyle, SIGNAL(activated(int)), this, SLOT(updateConfigButton()) ); | | |||
213 | connect( styleConfig->pbConfigStyle, &QAbstractButton::clicked, this, &KCMStyle::styleSpecificConfig ); | | |||
214 | connect( styleConfig->comboStyle, SIGNAL(activated(int)), this, SLOT(setStyleDirty()) ); | | |||
215 | connect( styleConfig->cbIconsOnButtons, &QAbstractButton::toggled, this, &KCMStyle::setEffectsDirty ); | | |||
216 | connect( styleConfig->cbIconsInMenus, &QAbstractButton::toggled, this, &KCMStyle::setEffectsDirty ); | | |||
217 | connect( styleConfig->comboToolbarIcons, SIGNAL(activated(int)), this, SLOT(setEffectsDirty()) ); | | |||
218 | connect( styleConfig->comboSecondaryToolbarIcons, SIGNAL(activated(int)), this, SLOT(setEffectsDirty()) ); | | |||
219 | | ||||
220 | addWhatsThis(); | | |||
221 | } | 101 | } | ||
222 | 102 | | |||
103 | KCMStyle::~KCMStyle() = default; | ||||
223 | 104 | | |||
224 | KCMStyle::~KCMStyle() | 105 | StylesModel *KCMStyle::model() const | ||
225 | { | 106 | { | ||
226 | qDeleteAll(styleEntries); | 107 | return m_model; | ||
227 | delete appliedStyle; | | |||
228 | } | 108 | } | ||
229 | 109 | | |||
230 | void KCMStyle::updateConfigButton() | 110 | bool KCMStyle::iconsOnButtons() const | ||
231 | { | 111 | { | ||
232 | if (!styleEntries[currentStyle()] || styleEntries[currentStyle()]->configPage.isEmpty()) { | 112 | return m_iconsOnButtons; | ||
233 | styleConfig->pbConfigStyle->setEnabled(false); | | |||
234 | return; | | |||
235 | } | | |||
236 | | ||||
237 | // We don't check whether it's loadable here - | | |||
238 | // lets us report an error and not waste time | | |||
239 | // loading things if the user doesn't click the button | | |||
240 | styleConfig->pbConfigStyle->setEnabled( true ); | | |||
241 | } | 113 | } | ||
242 | 114 | | |||
243 | void KCMStyle::styleSpecificConfig() | 115 | void KCMStyle::setIconsOnButtons(bool enable) | ||
244 | { | 116 | { | ||
245 | QString libname = styleEntries[currentStyle()]->configPage; | 117 | if (m_iconsOnButtons != enable) { | ||
118 | m_iconsOnButtons = enable; | ||||
119 | emit iconsOnButtonsChanged(); | ||||
246 | 120 | | |||
247 | KLibrary library(libname); | 121 | m_effectsDirty = true; | ||
248 | if (!library.load()) { | 122 | setNeedsSave(true); | ||
249 | KMessageBox::detailedError(this, | 123 | } | ||
250 | i18n("There was an error loading the configuration dialog for this style."), | | |||
251 | library.errorString(), | | |||
252 | i18n("Unable to Load Dialog")); | | |||
253 | return; | | |||
254 | } | 124 | } | ||
255 | 125 | | |||
256 | KLibrary::void_function_ptr allocPtr = library.resolveFunction("allocate_kstyle_config"); | 126 | bool KCMStyle::iconsInMenus() const | ||
257 | | ||||
258 | if (!allocPtr) | | |||
259 | { | 127 | { | ||
260 | KMessageBox::detailedError(this, | 128 | return m_iconsInMenus; | ||
261 | i18n("There was an error loading the configuration dialog for this style."), | | |||
262 | library.errorString(), | | |||
263 | i18n("Unable to Load Dialog")); | | |||
264 | return; | | |||
265 | } | 129 | } | ||
266 | 130 | | |||
267 | //Create the container dialog | 131 | void KCMStyle::setIconsInMenus(bool enable) | ||
268 | StyleConfigDialog* dial = new StyleConfigDialog(this, styleEntries[currentStyle()]->name); | 132 | { | ||
269 | 133 | if (m_iconsInMenus != enable) { | |||
270 | typedef QWidget*(* factoryRoutine)( QWidget* parent ); | 134 | m_iconsInMenus = enable; | ||
271 | 135 | emit iconsInMenusChanged(); | |||
272 | //Get the factory, and make the widget. | | |||
273 | factoryRoutine factory = (factoryRoutine)(allocPtr); //Grmbl. So here I am on my | | |||
274 | //"never use C casts" moralizing streak, and I find that one can't go void* -> function ptr | | |||
275 | //even with a reinterpret_cast. | | |||
276 | | ||||
277 | QWidget* pluginConfig = factory( dial ); | | |||
278 | | ||||
279 | //Insert it in... | | |||
280 | dial->setMainWidget( pluginConfig ); | | |||
281 | | ||||
282 | //..and connect it to the wrapper | | |||
283 | connect(pluginConfig, SIGNAL(changed(bool)), dial, SLOT(setDirty(bool))); | | |||
284 | connect(dial, SIGNAL(defaults()), pluginConfig, SLOT(defaults())); | | |||
285 | connect(dial, SIGNAL(save()), pluginConfig, SLOT(save())); | | |||
286 | | ||||
287 | if (dial->exec() == QDialog::Accepted && dial->isDirty() ) { | | |||
288 | // Force re-rendering of the preview, to apply settings | | |||
289 | switchStyle(currentStyle(), true); | | |||
290 | | ||||
291 | //For now, ask all KDE apps to recreate their styles to apply the setitngs | | |||
292 | KGlobalSettings::self()->emitChange(KGlobalSettings::StyleChanged); | | |||
293 | 136 | | |||
294 | // We call setStyleDirty here to make sure we force style re-creation | 137 | m_effectsDirty = true; | ||
295 | setStyleDirty(); | 138 | setNeedsSave(true); | ||
296 | } | 139 | } | ||
297 | | ||||
298 | delete dial; | | |||
299 | } | 140 | } | ||
300 | 141 | | |||
301 | void KCMStyle::changeEvent( QEvent *event ) | 142 | KCMStyle::ToolBarStyle KCMStyle::mainToolBarStyle() const | ||
302 | { | 143 | { | ||
303 | KCModule::changeEvent( event ); | 144 | return m_mainToolBarStyle; | ||
304 | if ( event->type() == QEvent::PaletteChange ) { | | |||
305 | // Force re-rendering of the preview, to apply new palette | | |||
306 | switchStyle(currentStyle(), true); | | |||
307 | } | | |||
308 | } | 145 | } | ||
309 | 146 | | |||
310 | void KCMStyle::load() | 147 | void KCMStyle::setMainToolBarStyle(ToolBarStyle style) | ||
311 | { | 148 | { | ||
312 | KConfig config( QStringLiteral("kdeglobals"), KConfig::FullConfig ); | 149 | if (m_mainToolBarStyle != style) { | ||
313 | 150 | m_mainToolBarStyle = style; | |||
314 | loadStyle( config ); | 151 | emit mainToolBarStyleChanged(); | ||
315 | loadEffects( config ); | | |||
316 | | ||||
317 | m_bStyleDirty= false; | | |||
318 | m_bEffectsDirty = false; | | |||
319 | //Enable/disable the button for the initial style | | |||
320 | updateConfigButton(); | | |||
321 | 152 | | |||
322 | emit changed( false ); | 153 | m_effectsDirty = true; | ||
154 | setNeedsSave(true); | ||||
155 | } | ||||
323 | } | 156 | } | ||
324 | 157 | | |||
325 | 158 | KCMStyle::ToolBarStyle KCMStyle::otherToolBarStyle() const | |||
326 | void KCMStyle::save() | | |||
327 | { | | |||
328 | // Don't do anything if we don't need to. | | |||
329 | if ( !(m_bStyleDirty | m_bEffectsDirty ) ) | | |||
330 | return; | | |||
331 | | ||||
332 | // Save effects. | | |||
333 | KConfig _config(QStringLiteral("kdeglobals"), KConfig::NoGlobals); | | |||
334 | KConfigGroup config(&_config, "KDE"); | | |||
335 | // Effects page | | |||
336 | config.writeEntry( "ShowIconsOnPushButtons", styleConfig->cbIconsOnButtons->isChecked()); | | |||
337 | config.writeEntry( "ShowIconsInMenuItems", styleConfig->cbIconsInMenus->isChecked()); | | |||
338 | | ||||
339 | config.writeEntry("widgetStyle", currentStyle()); | | |||
340 | | ||||
341 | KConfigGroup toolbarStyleGroup(&_config, "Toolbar style"); | | |||
342 | toolbarStyleGroup.writeEntry("ToolButtonStyle", | | |||
343 | toolbarButtonText(styleConfig->comboToolbarIcons->currentIndex())); | | |||
344 | toolbarStyleGroup.writeEntry("ToolButtonStyleOtherToolbars", | | |||
345 | toolbarButtonText(styleConfig->comboSecondaryToolbarIcons->currentIndex())); | | |||
346 | | ||||
347 | _config.sync(); | | |||
348 | | ||||
349 | // Export the changes we made to qtrc, and update all qt-only | | |||
350 | // applications on the fly, ensuring that we still follow the user's | | |||
351 | // export fonts/colors settings. | | |||
352 | if (m_bStyleDirty || m_bEffectsDirty) // Export only if necessary | | |||
353 | { | 159 | { | ||
354 | uint flags = KRdbExportQtSettings | KRdbExportGtkTheme; | 160 | return m_otherToolBarStyle; | ||
355 | KConfig _kconfig( QStringLiteral("kcmdisplayrc"), KConfig::NoGlobals ); | | |||
356 | KConfigGroup kconfig(&_kconfig, "X11"); | | |||
357 | bool exportKDEColors = kconfig.readEntry("exportKDEColors", true); | | |||
358 | if (exportKDEColors) | | |||
359 | flags |= KRdbExportColors; | | |||
360 | runRdb( flags ); | | |||
361 | } | 161 | } | ||
362 | 162 | | |||
363 | // Now allow KDE apps to reconfigure themselves. | 163 | void KCMStyle::setOtherToolBarStyle(ToolBarStyle style) | ||
364 | if ( m_bStyleDirty ) | 164 | { | ||
365 | KGlobalSettings::self()->emitChange(KGlobalSettings::StyleChanged); | 165 | if (m_otherToolBarStyle != style) { | ||
366 | 166 | m_otherToolBarStyle = style; | |||
367 | if ( m_bEffectsDirty ) { | 167 | emit otherToolBarStyleChanged(); | ||
368 | KGlobalSettings::self()->emitChange(KGlobalSettings::SettingsChanged, KGlobalSettings::SETTINGS_STYLE); | | |||
369 | // ##### FIXME - Doesn't apply all settings correctly due to bugs in | | |||
370 | // KApplication/KToolbar | | |||
371 | KGlobalSettings::self()->emitChange(KGlobalSettings::ToolbarStyleChanged); | | |||
372 | 168 | | |||
373 | #if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) | 169 | m_effectsDirty = true; | ||
374 | // Send signal to all kwin instances | 170 | setNeedsSave(true); | ||
375 | QDBusMessage message = | | |||
376 | QDBusMessage::createSignal(QStringLiteral("/KWin"), QStringLiteral("org.kde.KWin"), QStringLiteral("reloadConfig")); | | |||
377 | QDBusConnection::sessionBus().send(message); | | |||
378 | #endif | | |||
379 | } | 171 | } | ||
380 | | ||||
381 | // Clean up | | |||
382 | m_bStyleDirty = false; | | |||
383 | m_bEffectsDirty = false; | | |||
384 | emit changed( false ); | | |||
385 | } | 172 | } | ||
386 | 173 | | |||
387 | 174 | void KCMStyle::configure(const QString &styleName, QQuickItem *ctx) | |||
388 | bool KCMStyle::findStyle( const QString& str, int& combobox_item ) | | |||
389 | { | 175 | { | ||
390 | StyleEntry* se = styleEntries[str.toLower()]; | 176 | if (m_styleConfigDialog) { | ||
391 | 177 | return; | |||
392 | QString name = se ? se->name : str; | 178 | } | ||
393 | | ||||
394 | combobox_item = 0; | | |||
395 | 179 | | |||
396 | //look up name | 180 | const QString configPage = m_model->styleConfigPage(styleName); | ||
397 | for( int i = 0; i < styleConfig->comboStyle->count(); i++ ) | 181 | if (configPage.isEmpty()) { | ||
398 | { | 182 | return; | ||
399 | if ( styleConfig->comboStyle->itemText(i) == name ) | | |||
400 | { | | |||
401 | combobox_item = i; | | |||
402 | return true; | | |||
403 | } | 183 | } | ||
184 | | ||||
185 | QLibrary library(KPluginLoader::findPlugin(configPage)); | ||||
186 | if (!library.load()) { | ||||
187 | qWarning() << "Failed to load style config page" << configPage << library.errorString(); | ||||
188 | emit showErrorMessage(i18n("There was an error loading the configuration dialog for this style.")); | ||||
189 | return; | ||||
404 | } | 190 | } | ||
405 | 191 | | |||
406 | return false; | 192 | auto allocPtr = library.resolve("allocate_kstyle_config"); | ||
193 | if (!allocPtr) { | ||||
194 | qWarning() << "Failed to resolve allocate_kstyle_config in" << configPage; | ||||
195 | emit showErrorMessage(i18n("There was an error loading the configuration dialog for this style.")); | ||||
196 | return; | ||||
407 | } | 197 | } | ||
408 | 198 | | |||
199 | m_styleConfigDialog = new StyleConfigDialog(nullptr/*this*/, configPage); | ||||
200 | m_styleConfigDialog->setAttribute(Qt::WA_DeleteOnClose); | ||||
201 | m_styleConfigDialog->setWindowModality(Qt::WindowModal); | ||||
202 | m_styleConfigDialog->winId(); // so it creates windowHandle | ||||
409 | 203 | | |||
410 | void KCMStyle::defaults() | 204 | if (ctx && ctx->window()) { | ||
411 | { | 205 | m_styleConfigDialog->windowHandle()->setTransientParent(ctx->window()); | ||
412 | // Select default style | 206 | } | ||
413 | int item = 0; | | |||
414 | bool found; | | |||
415 | 207 | | |||
416 | found = findStyle( defaultStyle(), item ); | 208 | typedef QWidget*(* factoryRoutine)( QWidget* parent ); | ||
417 | if (!found) | | |||
418 | found = findStyle( QStringLiteral("oxygen"), item ); | | |||
419 | if (!found) | | |||
420 | found = findStyle( QStringLiteral("plastique"), item ); | | |||
421 | if (!found) | | |||
422 | found = findStyle( QStringLiteral("windows"), item ); | | |||
423 | if (!found) | | |||
424 | found = findStyle( QStringLiteral("platinum"), item ); | | |||
425 | if (!found) | | |||
426 | found = findStyle( QStringLiteral("motif"), item ); | | |||
427 | 209 | | |||
428 | styleConfig->comboStyle->setCurrentIndex( item ); | 210 | //Get the factory, and make the widget. | ||
211 | factoryRoutine factory = (factoryRoutine)(allocPtr); //Grmbl. So here I am on my | ||||
212 | //"never use C casts" moralizing streak, and I find that one can't go void* -> function ptr | ||||
213 | //even with a reinterpret_cast. | ||||
429 | 214 | | |||
430 | m_bStyleDirty = true; | 215 | QWidget* pluginConfig = factory( m_styleConfigDialog.data() ); | ||
431 | switchStyle( currentStyle() ); // make resets visible | | |||
432 | 216 | | |||
433 | // Effects | 217 | //Insert it in... | ||
434 | styleConfig->comboToolbarIcons->setCurrentIndex(toolbarButtonIndex(QStringLiteral("TextBesideIcon"))); | 218 | m_styleConfigDialog->setMainWidget( pluginConfig ); | ||
435 | styleConfig->comboSecondaryToolbarIcons->setCurrentIndex(toolbarButtonIndex(QStringLiteral("TextBesideIcon"))); | | |||
436 | styleConfig->cbIconsOnButtons->setChecked(true); | | |||
437 | styleConfig->cbIconsInMenus->setChecked(true); | | |||
438 | emit changed(true); | | |||
439 | emit updateConfigButton(); | | |||
440 | } | | |||
441 | 219 | | |||
442 | void KCMStyle::setEffectsDirty() | 220 | //..and connect it to the wrapper | ||
443 | { | 221 | connect(pluginConfig, SIGNAL(changed(bool)), m_styleConfigDialog.data(), SLOT(setDirty(bool))); | ||
444 | m_bEffectsDirty = true; | 222 | connect(m_styleConfigDialog.data(), SIGNAL(defaults()), pluginConfig, SLOT(defaults())); | ||
445 | emit changed(true); | 223 | connect(m_styleConfigDialog.data(), SIGNAL(save()), pluginConfig, SLOT(save())); | ||
446 | } | | |||
447 | 224 | | |||
448 | void KCMStyle::setStyleDirty() | 225 | connect(m_styleConfigDialog.data(), &QDialog::accepted, this, [this, styleName] { | ||
449 | { | 226 | if (!m_styleConfigDialog->isDirty()) { | ||
450 | m_bStyleDirty = true; | 227 | return; | ||
451 | emit changed(true); | | |||
452 | } | 228 | } | ||
453 | 229 | | |||
454 | // ---------------------------------------------------------------- | 230 | // Force re-rendering of the preview, to apply settings | ||
455 | // All the Style Switching / Preview stuff | 231 | emit styleReconfigured(styleName); | ||
456 | // ---------------------------------------------------------------- | | |||
457 | | ||||
458 | void KCMStyle::loadStyle( KConfig& config ) | | |||
459 | { | | |||
460 | styleConfig->comboStyle->clear(); | | |||
461 | // Create a dictionary of WidgetStyle to Name and Desc. mappings, | | |||
462 | // as well as the config page info | | |||
463 | qDeleteAll(styleEntries); | | |||
464 | styleEntries.clear(); | | |||
465 | | ||||
466 | QString strWidgetStyle; | | |||
467 | QStringList list = KGlobal::dirs()->findAllResources("themes", QStringLiteral("*.themerc"), | | |||
468 | KStandardDirs::Recursive | | | |||
469 | KStandardDirs::NoDuplicates); | | |||
470 | for (QStringList::iterator it = list.begin(); it != list.end(); ++it) | | |||
471 | { | | |||
472 | KConfig config( *it, KConfig::SimpleConfig); | | |||
473 | if ( !(config.hasGroup("KDE") && config.hasGroup("Misc")) ) | | |||
474 | continue; | | |||
475 | | ||||
476 | KConfigGroup configGroup = config.group("KDE"); | | |||
477 | 232 | | |||
478 | strWidgetStyle = configGroup.readEntry("WidgetStyle"); | 233 | //For now, ask all KDE apps to recreate their styles to apply the setitngs | ||
479 | if (strWidgetStyle.isNull()) | 234 | KGlobalSettings::self()->emitChange(KGlobalSettings::StyleChanged); | ||
480 | continue; | | |||
481 | 235 | | |||
482 | // We have a widgetstyle, so lets read the i18n entries for it... | 236 | // When user edited a style, assume they want to use it, too | ||
483 | StyleEntry* entry = new StyleEntry; | 237 | m_model->setSelectedStyle(styleName); | ||
484 | configGroup = config.group("Misc"); | | |||
485 | entry->name = configGroup.readEntry("Name"); | | |||
486 | entry->desc = configGroup.readEntry("Comment", i18n("No description available.")); | | |||
487 | entry->configPage = configGroup.readEntry("ConfigPage", QString()); | | |||
488 | 238 | | |||
489 | // Check if this style should be shown | 239 | // We call setStyleDirty here to make sure we force style re-creation | ||
490 | configGroup = config.group("Desktop Entry"); | 240 | m_selectedStyleDirty = true; | ||
491 | entry->hidden = configGroup.readEntry("Hidden", false); | 241 | setNeedsSave(true); | ||
242 | }); | ||||
492 | 243 | | |||
493 | // Insert the entry into our dictionary. | 244 | m_styleConfigDialog->show(); | ||
494 | styleEntries.insert(strWidgetStyle.toLower(), entry); | | |||
495 | } | 245 | } | ||
496 | 246 | | |||
497 | // Obtain all style names | 247 | void KCMStyle::load() | ||
498 | QStringList allStyles = QStyleFactory::keys(); | | |||
499 | | ||||
500 | // Get translated names, remove all hidden style entries. | | |||
501 | QStringList styles; | | |||
502 | StyleEntry* entry; | | |||
503 | for (QStringList::iterator it = allStyles.begin(); it != allStyles.end(); ++it) | | |||
504 | { | | |||
505 | QString id = (*it).toLower(); | | |||
506 | // Find the entry. | | |||
507 | if ( (entry = styleEntries[id]) != nullptr ) | | |||
508 | { | 248 | { | ||
509 | // Do not add hidden entries | 249 | m_model->load(); | ||
510 | if (entry->hidden) | | |||
511 | continue; | | |||
512 | 250 | | |||
513 | styles += entry->name; | 251 | KConfig config(QStringLiteral("kdeglobals")); | ||
514 | 252 | | |||
515 | nameToStyleKey[entry->name] = id; | 253 | // Current style | ||
516 | } | 254 | KConfigGroup kdeGroup = config.group("KDE"); | ||
517 | else | 255 | const QString widgetStyle = kdeGroup.readEntry("widgetStyle", KCMStyle::defaultStyle()); | ||
518 | { | | |||
519 | styles += (*it); //Fall back to the key (but in original case) | | |||
520 | nameToStyleKey[*it] = id; | | |||
521 | } | | |||
522 | } | | |||
523 | 256 | | |||
524 | // Sort the style list, and add it to the combobox | 257 | m_model->setSelectedStyle(widgetStyle); | ||
525 | styles.sort(); | | |||
526 | styleConfig->comboStyle->addItems( styles ); | | |||
527 | 258 | | |||
528 | // Find out which style is currently being used | 259 | // Effects settings | ||
529 | KConfigGroup configGroup = config.group( "KDE" ); | 260 | setIconsOnButtons(kdeGroup.readEntry("ShowIconsOnPushButtons", true)); | ||
530 | QString defaultStyle = KCMStyle::defaultStyle(); | 261 | setIconsInMenus(kdeGroup.readEntry("ShowIconsInMenuItems", true)); | ||
531 | QString cfgStyle = configGroup.readEntry( "widgetStyle", defaultStyle ); | | |||
532 | 262 | | |||
533 | // Select the current style | 263 | KConfigGroup toolBarGroup = config.group("Toolbar style"); | ||
534 | // Do not use comboStyle->listBox() as this may be NULL for some styles when | 264 | const QString mainToolBarStyle = toolBarGroup.readEntry("ToolButtonStyle", "TextBesideIcon"); | ||
535 | // they use QPopupMenus for the drop-down list! | 265 | const QString otherToolBarStyle = toolBarGroup.readEntry("ToolButtonStyleOtherToolbars", "TextBesideIcon"); | ||
536 | 266 | | |||
537 | // ##### Since Trolltech likes to seemingly copy & paste code, | 267 | const QMetaEnum toolBarStyleEnum = QMetaEnum::fromType<ToolBarStyle>(); | ||
538 | // QStringList::findItem() doesn't have a Qt::StringComparisonMode field. | 268 | setMainToolBarStyle(static_cast<ToolBarStyle>(toolBarStyleEnum.keyToValue(qUtf8Printable(mainToolBarStyle)))); | ||
539 | // We roll our own (yuck) | 269 | setOtherToolBarStyle(static_cast<ToolBarStyle>(toolBarStyleEnum.keyToValue(qUtf8Printable(otherToolBarStyle)))); | ||
540 | cfgStyle = cfgStyle.toLower(); | | |||
541 | int item = 0; | | |||
542 | for( int i = 0; i < styleConfig->comboStyle->count(); i++ ) | | |||
543 | { | | |||
544 | QString id = nameToStyleKey[styleConfig->comboStyle->itemText(i)]; | | |||
545 | item = i; | | |||
546 | if ( id == cfgStyle ) // ExactMatch | | |||
547 | break; | | |||
548 | else if ( id.contains( cfgStyle ) ) | | |||
549 | break; | | |||
550 | else if ( id.contains( QApplication::style()->metaObject()->className() ) ) | | |||
551 | break; | | |||
552 | item = 0; | | |||
553 | } | | |||
554 | styleConfig->comboStyle->setCurrentIndex( item ); | | |||
555 | m_bStyleDirty = false; | | |||
556 | 270 | | |||
557 | switchStyle( currentStyle() ); // make resets visible | 271 | m_selectedStyleDirty = false; | ||
272 | m_effectsDirty = false; | ||||
273 | setNeedsSave(false); | ||||
558 | } | 274 | } | ||
559 | 275 | | |||
560 | QString KCMStyle::currentStyle() | 276 | void KCMStyle::save() | ||
561 | { | 277 | { | ||
562 | return nameToStyleKey[styleConfig->comboStyle->currentText()]; | 278 | if (!m_selectedStyleDirty && !m_effectsDirty) { | ||
279 | return; | ||||
563 | } | 280 | } | ||
564 | 281 | | |||
565 | 282 | // Check whether the new style can actually be loaded before saving it. | |||
566 | void KCMStyle::styleChanged() | 283 | // Otherwise apps will use the default style despite something else having been written to the config | ||
567 | { | 284 | bool newStyleLoaded = false; | ||
568 | switchStyle( currentStyle() ); | 285 | if (m_selectedStyleDirty) { | ||
286 | QScopedPointer<QStyle> newStyle(QStyleFactory::create(m_model->selectedStyle())); | ||||
287 | if (newStyle) { | ||||
288 | newStyleLoaded = true; | ||||
289 | } else { | ||||
290 | const QString styleDisplay = m_model->data(m_model->index(m_model->selectedStyleIndex(), 0), Qt::DisplayRole).toString(); | ||||
291 | emit showErrorMessage(i18n("Failed to apply selected style '%1'.", styleDisplay)); | ||||
569 | } | 292 | } | ||
570 | | ||||
571 | | ||||
572 | void KCMStyle::switchStyle(const QString& styleName, bool force) | | |||
573 | { | | |||
574 | // Don't flicker the preview if the same style is chosen in the cb | | |||
575 | if (!force && appliedStyle && appliedStyle->objectName() == styleName) | | |||
576 | return; | | |||
577 | | ||||
578 | // Create an instance of the new style... | | |||
579 | QStyle* style = QStyleFactory::create(styleName); | | |||
580 | if (!style) | | |||
581 | return; | | |||
582 | | ||||
583 | // Prevent Qt from wrongly caching radio button images | | |||
584 | QPixmapCache::clear(); | | |||
585 | | ||||
586 | setStyleRecursive( stylePreview, style ); | | |||
587 | | ||||
588 | // this flickers, but reliably draws the widgets correctly. | | |||
589 | stylePreview->resize( stylePreview->sizeHint() ); | | |||
590 | | ||||
591 | delete appliedStyle; | | |||
592 | appliedStyle = style; | | |||
593 | } | 293 | } | ||
594 | 294 | | |||
595 | void KCMStyle::setStyleRecursive(QWidget* w, QStyle* s) | 295 | KConfig config(QStringLiteral("kdeglobals")); | ||
596 | { | | |||
597 | // Don't let broken styles kill the palette | | |||
598 | // for other styles being previewed. (e.g SGI style) | | |||
599 | w->setPalette(QPalette()); | | |||
600 | 296 | | |||
601 | QPalette newPalette(KGlobalSettings::createApplicationPalette()); | 297 | KConfigGroup kdeGroup = config.group("KDE"); | ||
602 | s->polish( newPalette ); | | |||
603 | w->setPalette(newPalette); | | |||
604 | 298 | | |||
605 | // Apply the new style. | 299 | if (newStyleLoaded) { | ||
606 | w->setStyle(s); | 300 | kdeGroup.writeEntry("widgetStyle", m_model->selectedStyle()); | ||
301 | } | ||||
607 | 302 | | |||
608 | // Recursively update all children. | 303 | kdeGroup.writeEntry("ShowIconsOnPushButtons", m_iconsOnButtons); | ||
609 | const QObjectList children = w->children(); | 304 | kdeGroup.writeEntry("ShowIconsInMenuItems", m_iconsInMenus); | ||
610 | 305 | | |||
611 | // Apply the style to each child widget. | 306 | KConfigGroup toolBarGroup = config.group("Toolbar style"); | ||
612 | foreach (QObject* child, children) | 307 | const QMetaEnum toolBarStyleEnum = QMetaEnum::fromType<ToolBarStyle>(); | ||
613 | { | | |||
614 | if (child->isWidgetType()) | | |||
615 | setStyleRecursive((QWidget *) child, s); | | |||
616 | } | | |||
617 | } | | |||
618 | 308 | | |||
619 | // ---------------------------------------------------------------- | 309 | toolBarGroup.writeEntry("ToolButtonStyle", toolBarStyleEnum.valueToKey(m_mainToolBarStyle)); | ||
620 | // All the Effects stuff | 310 | toolBarGroup.writeEntry("ToolButtonStyleOtherToolbars", toolBarStyleEnum.valueToKey(m_otherToolBarStyle)); | ||
621 | // ---------------------------------------------------------------- | | |||
622 | QString KCMStyle::toolbarButtonText(int index) | | |||
623 | { | | |||
624 | switch (index) { | | |||
625 | case 1: | | |||
626 | return QStringLiteral("TextOnly"); | | |||
627 | case 2: | | |||
628 | return QStringLiteral("TextBesideIcon"); | | |||
629 | case 3: | | |||
630 | return QStringLiteral("TextUnderIcon"); | | |||
631 | default: | | |||
632 | break; | | |||
633 | } | | |||
634 | 311 | | |||
635 | return QStringLiteral("NoText"); | 312 | config.sync(); | ||
636 | } | | |||
637 | 313 | | |||
638 | int KCMStyle::toolbarButtonIndex(const QString &text) | 314 | // Export the changes we made to qtrc, and update all qt-only | ||
639 | { | 315 | // applications on the fly, ensuring that we still follow the user's | ||
640 | if (text == QLatin1String("TextOnly")) { | 316 | // export fonts/colors settings. | ||
641 | return 1; | 317 | if (m_selectedStyleDirty || m_effectsDirty) { | ||
642 | } else if (text == QLatin1String("TextBesideIcon")) { | 318 | uint flags = KRdbExportQtSettings | KRdbExportGtkTheme; | ||
643 | return 2; | 319 | KConfig _kconfig( QStringLiteral("kcmdisplayrc"), KConfig::NoGlobals ); | ||
644 | } else if (text == QLatin1String("TextUnderIcon")) { | 320 | KConfigGroup kconfig(&_kconfig, "X11"); | ||
645 | return 3; | 321 | bool exportKDEColors = kconfig.readEntry("exportKDEColors", true); | ||
322 | if (exportKDEColors) { | ||||
323 | flags |= KRdbExportColors; | ||||
646 | } | 324 | } | ||
647 | 325 | runRdb( flags ); | |||
648 | return 0; | | |||
649 | } | 326 | } | ||
650 | 327 | | |||
651 | QString KCMStyle::menuBarStyleText(int index) | 328 | // Now allow KDE apps to reconfigure themselves. | ||
652 | { | 329 | if (newStyleLoaded) { | ||
653 | switch (index) { | 330 | KGlobalSettings::self()->emitChange(KGlobalSettings::StyleChanged); | ||
654 | case 1: | | |||
655 | return QStringLiteral("Decoration"); | | |||
656 | case 2: | | |||
657 | return QStringLiteral("Widget"); | | |||
658 | } | 331 | } | ||
659 | 332 | | |||
660 | return QStringLiteral("InApplication"); | 333 | if (m_effectsDirty) { | ||
334 | KGlobalSettings::self()->emitChange(KGlobalSettings::SettingsChanged, KGlobalSettings::SETTINGS_STYLE); | ||||
335 | // ##### FIXME - Doesn't apply all settings correctly due to bugs in | ||||
336 | // KApplication/KToolbar | ||||
337 | KGlobalSettings::self()->emitChange(KGlobalSettings::ToolbarStyleChanged); | ||||
661 | } | 338 | } | ||
662 | 339 | | |||
663 | int KCMStyle::menuBarStyleIndex(const QString &text) | 340 | // Reset selected style back to current in case of failure | ||
664 | { | 341 | if (!newStyleLoaded) { | ||
665 | if (text == QLatin1String("Decoration")) { | 342 | const QString widgetStyle = kdeGroup.readEntry("widgetStyle", KCMStyle::defaultStyle()); | ||
666 | return 1; | 343 | m_model->setSelectedStyle(widgetStyle); | ||
667 | } else if (text == QLatin1String("Widget")) { | | |||
668 | return 2; | | |||
669 | } | 344 | } | ||
670 | 345 | | |||
671 | return 0; | 346 | m_effectsDirty = false; | ||
347 | setNeedsSave(false); | ||||
672 | } | 348 | } | ||
673 | 349 | | |||
674 | void KCMStyle::loadEffects( KConfig& config ) | 350 | void KCMStyle::defaults() | ||
675 | { | 351 | { | ||
676 | // KDE's Part via KConfig | 352 | // TODO the old code had a fallback chain but do we actually support not having Breeze for Plasma? | ||
677 | KConfigGroup configGroup = config.group("Toolbar style"); | 353 | // defaultStyle() -> oxygen -> plastique -> windows -> platinum -> motif | ||
678 | | ||||
679 | QString tbIcon = configGroup.readEntry("ToolButtonStyle", "TextBesideIcon"); | | |||
680 | styleConfig->comboToolbarIcons->setCurrentIndex(toolbarButtonIndex(tbIcon)); | | |||
681 | tbIcon = configGroup.readEntry("ToolButtonStyleOtherToolbars", "TextBesideIcon"); | | |||
682 | styleConfig->comboSecondaryToolbarIcons->setCurrentIndex(toolbarButtonIndex(tbIcon)); | | |||
683 | 354 | | |||
684 | configGroup = config.group("KDE"); | 355 | m_model->setSelectedStyle(defaultStyle()); | ||
685 | styleConfig->cbIconsOnButtons->setChecked(configGroup.readEntry("ShowIconsOnPushButtons", true)); | | |||
686 | styleConfig->cbIconsInMenus->setChecked(configGroup.readEntry("ShowIconsInMenuItems", true)); | | |||
687 | 356 | | |||
688 | m_bEffectsDirty = false; | 357 | setIconsOnButtons(true); | ||
689 | } | 358 | setIconsInMenus(true); | ||
690 | 359 | setMainToolBarStyle(TextBesideIcon); | |||
691 | void KCMStyle::addWhatsThis() | 360 | setOtherToolBarStyle(TextBesideIcon); | ||
692 | { | | |||
693 | stylePreview->setWhatsThis( i18n("This area shows a preview of the currently selected style " | | |||
694 | "without having to apply it to the whole desktop.") ); | | |||
695 | styleConfig->comboStyle->setWhatsThis( i18n("Here you can choose from a list of" | | |||
696 | " predefined widget styles (e.g. the way buttons are drawn) which" | | |||
697 | " may or may not be combined with a theme (additional information" | | |||
698 | " like a marble texture or a gradient).") ); | | |||
699 | styleConfig->cbIconsOnButtons->setWhatsThis( i18n( "If you enable this option, applications will " | | |||
700 | "show small icons alongside some important buttons.") ); | | |||
701 | styleConfig->cbIconsInMenus->setWhatsThis( i18n( "If you enable this option, applications will " | | |||
702 | "show small icons alongside most menu items.") ); | | |||
703 | styleConfig->comboToolbarIcons->setWhatsThis( i18n( "<p><b>No text:</b> Shows only icons on toolbar buttons. " | | |||
704 | "Best option for low resolutions.</p>" | | |||
705 | "<p><b>Text only: </b>Shows only text on toolbar buttons.</p>" | | |||
706 | "<p><b>Text beside icons: </b> Shows icons and text on toolbar buttons. " | | |||
707 | "Text is aligned beside the icon.</p>" | | |||
708 | "<b>Text below icons: </b> Shows icons and text on toolbar buttons. " | | |||
709 | "Text is aligned below the icon.") ); | | |||
710 | } | 361 | } | ||
711 | 362 | | |||
712 | #include "kcmstyle.moc" | 363 | #include "kcmstyle.moc" | ||
713 | 364 | | |||
714 | // vim: set noet ts=4: | 365 | // vim: set noet ts=4: |