KDEUI
kglobalsettings.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2000, 2006 David Faure <faure@kde.org> 00003 Copyright 2008 Friedrich W. H. Kossebau <kossebau@kde.org> 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Library General Public 00007 License version 2 as published by the Free Software Foundation. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to 00016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00017 Boston, MA 02110-1301, USA. 00018 */ 00019 00020 #include "kglobalsettings.h" 00021 #include <config.h> 00022 00023 #include <kconfig.h> 00024 00025 #include <kdebug.h> 00026 #include <kglobal.h> 00027 #include <kstandarddirs.h> 00028 #include <kcharsets.h> 00029 #include <klocale.h> 00030 #include <kprotocolinfo.h> 00031 #include <kcomponentdata.h> 00032 #include <kcolorscheme.h> 00033 00034 #include <kstyle.h> 00035 00036 #include <QtGui/QColor> 00037 #include <QtGui/QCursor> 00038 #include <QtGui/QDesktopWidget> 00039 #include <QtCore/QDir> 00040 #include <QtGui/QFont> 00041 #include <QtGui/QFontDatabase> 00042 #include <QtGui/QFontInfo> 00043 #include <QtGui/QKeySequence> 00044 #include <QtGui/QPixmap> 00045 #include <QtGui/QPixmapCache> 00046 #include <QApplication> 00047 #include <QtDBus/QtDBus> 00048 #include <QtGui/QStyleFactory> 00049 #include <QDesktopServices> 00050 00051 // next two needed so we can set their palettes 00052 #include <QtGui/QToolTip> 00053 #include <QtGui/QWhatsThis> 00054 00055 #ifdef Q_WS_WIN 00056 #include <windows.h> 00057 #include <kkernel_win.h> 00058 00059 static QRgb qt_colorref2qrgb(COLORREF col) 00060 { 00061 return qRgb(GetRValue(col),GetGValue(col),GetBValue(col)); 00062 } 00063 #endif 00064 #ifdef Q_WS_X11 00065 #include <X11/Xlib.h> 00066 #ifdef HAVE_XCURSOR 00067 #include <X11/Xcursor/Xcursor.h> 00068 #endif 00069 #include "fixx11h.h" 00070 #include <QX11Info> 00071 #endif 00072 00073 #include <stdlib.h> 00074 #include <kconfiggroup.h> 00075 00076 00077 //static QColor *_buttonBackground = 0; 00078 static KGlobalSettings::GraphicEffects _graphicEffects = KGlobalSettings::NoEffects; 00079 00080 // TODO: merge this with KGlobalSettings::Private 00081 // 00082 // F. Kossebau: KDE5: think to make all methods static and not expose an object, 00083 // making KGlobalSettings rather a namespace 00084 // D. Faure: how would people connect to signals, then? 00085 class KGlobalSettingsData 00086 { 00087 public: 00088 // if adding a new type here also add an entry to DefaultFontData 00089 enum FontTypes 00090 { 00091 GeneralFont = 0, 00092 FixedFont, 00093 ToolbarFont, 00094 MenuFont, 00095 WindowTitleFont, 00096 TaskbarFont , 00097 SmallestReadableFont, 00098 FontTypesCount 00099 }; 00100 00101 public: 00102 KGlobalSettingsData(); 00103 ~KGlobalSettingsData(); 00104 00105 public: 00106 static KGlobalSettingsData* self(); 00107 00108 public: // access, is not const due to caching 00109 QFont font( FontTypes fontType ); 00110 QFont largeFont( const QString& text ); 00111 KGlobalSettings::KMouseSettings& mouseSettings(); 00112 00113 public: 00114 void dropFontSettingsCache(); 00115 void dropMouseSettingsCache(); 00116 00117 protected: 00118 QFont* mFonts[FontTypesCount]; 00119 QFont* mLargeFont; 00120 KGlobalSettings::KMouseSettings* mMouseSettings; 00121 }; 00122 00123 KGlobalSettingsData::KGlobalSettingsData() 00124 : mLargeFont( 0 ), 00125 mMouseSettings( 0 ) 00126 { 00127 for( int i=0; i<FontTypesCount; ++i ) 00128 mFonts[i] = 0; 00129 } 00130 00131 KGlobalSettingsData::~KGlobalSettingsData() 00132 { 00133 for( int i=0; i<FontTypesCount; ++i ) 00134 delete mFonts[i]; 00135 delete mLargeFont; 00136 00137 delete mMouseSettings; 00138 } 00139 00140 K_GLOBAL_STATIC( KGlobalSettingsData, globalSettingsDataSingleton ) 00141 00142 inline KGlobalSettingsData* KGlobalSettingsData::self() 00143 { 00144 return globalSettingsDataSingleton; 00145 } 00146 00147 00148 class KGlobalSettings::Private 00149 { 00150 public: 00151 Private(KGlobalSettings *q) 00152 : q(q), activated(false), paletteCreated(false) 00153 { 00154 } 00155 00156 QPalette createApplicationPalette(const KSharedConfigPtr &config); 00157 void _k_slotNotifyChange(int, int); 00158 00159 void propagateQtSettings(); 00160 void kdisplaySetPalette(); 00161 void kdisplaySetStyle(); 00162 void kdisplaySetFont(); 00163 void applyGUIStyle(); 00164 00176 void applyCursorTheme(); 00177 00181 static void rereadOtherSettings(); 00182 00183 KGlobalSettings *q; 00184 bool activated; 00185 bool paletteCreated; 00186 QPalette applicationPalette; 00187 }; 00188 00189 KGlobalSettings* KGlobalSettings::self() 00190 { 00191 K_GLOBAL_STATIC(KGlobalSettings, s_self) 00192 return s_self; 00193 } 00194 00195 KGlobalSettings::KGlobalSettings() 00196 : QObject(0), d(new Private(this)) 00197 { 00198 } 00199 00200 KGlobalSettings::~KGlobalSettings() 00201 { 00202 delete d; 00203 } 00204 00205 void KGlobalSettings::activate() 00206 { 00207 activate(ApplySettings | ListenForChanges); 00208 } 00209 00210 void KGlobalSettings::activate(ActivateOptions options) 00211 { 00212 if (!d->activated) { 00213 d->activated = true; 00214 00215 if (options & ListenForChanges) { 00216 QDBusConnection::sessionBus().connect( QString(), "/KGlobalSettings", "org.kde.KGlobalSettings", 00217 "notifyChange", this, SLOT(_k_slotNotifyChange(int,int)) ); 00218 } 00219 00220 if (options & ApplySettings) { 00221 d->kdisplaySetStyle(); // implies palette setup 00222 d->kdisplaySetFont(); 00223 d->propagateQtSettings(); 00224 } 00225 } 00226 } 00227 00228 int KGlobalSettings::dndEventDelay() 00229 { 00230 KConfigGroup g( KGlobal::config(), "General" ); 00231 return g.readEntry("StartDragDist", QApplication::startDragDistance()); 00232 } 00233 00234 bool KGlobalSettings::singleClick() 00235 { 00236 KConfigGroup g( KGlobal::config(), "KDE" ); 00237 return g.readEntry("SingleClick", KDE_DEFAULT_SINGLECLICK ); 00238 } 00239 00240 bool KGlobalSettings::smoothScroll() 00241 { 00242 KConfigGroup g( KGlobal::config(), "KDE" ); 00243 return g.readEntry("SmoothScroll", KDE_DEFAULT_SMOOTHSCROLL ); 00244 } 00245 00246 KGlobalSettings::TearOffHandle KGlobalSettings::insertTearOffHandle() 00247 { 00248 int tearoff; 00249 bool effectsenabled; 00250 KConfigGroup g( KGlobal::config(), "KDE" ); 00251 effectsenabled = g.readEntry( "EffectsEnabled", false); 00252 tearoff = g.readEntry("InsertTearOffHandle", KDE_DEFAULT_INSERTTEAROFFHANDLES); 00253 return effectsenabled ? (TearOffHandle) tearoff : Disable; 00254 } 00255 00256 bool KGlobalSettings::changeCursorOverIcon() 00257 { 00258 KConfigGroup g( KGlobal::config(), "KDE" ); 00259 return g.readEntry("ChangeCursor", KDE_DEFAULT_CHANGECURSOR); 00260 } 00261 00262 int KGlobalSettings::autoSelectDelay() 00263 { 00264 KConfigGroup g( KGlobal::config(), "KDE" ); 00265 return g.readEntry("AutoSelectDelay", KDE_DEFAULT_AUTOSELECTDELAY); 00266 } 00267 00268 KGlobalSettings::Completion KGlobalSettings::completionMode() 00269 { 00270 int completion; 00271 KConfigGroup g( KGlobal::config(), "General" ); 00272 completion = g.readEntry("completionMode", -1); 00273 if ((completion < (int) CompletionNone) || 00274 (completion > (int) CompletionPopupAuto)) 00275 { 00276 completion = (int) CompletionPopup; // Default 00277 } 00278 return (Completion) completion; 00279 } 00280 00281 bool KGlobalSettings::showContextMenusOnPress () 00282 { 00283 KConfigGroup g(KGlobal::config(), "ContextMenus"); 00284 return g.readEntry("ShowOnPress", true); 00285 } 00286 00287 #ifndef KDE_NO_DEPRECATED 00288 int KGlobalSettings::contextMenuKey () 00289 { 00290 KConfigGroup g(KGlobal::config(), "Shortcuts"); 00291 QString s = g.readEntry ("PopupMenuContext", "Menu"); 00292 00293 // this is a bit of a code duplication with KShortcut, 00294 // but seeing as that is all in kdeui these days there's little choice. 00295 // this is faster for what we're really after here anyways 00296 // (less allocations, only processing the first item always, etc) 00297 if (s == QLatin1String("none")) { 00298 return QKeySequence()[0]; 00299 } 00300 00301 const QStringList shortCuts = s.split(';'); 00302 00303 if (shortCuts.count() < 1) { 00304 return QKeySequence()[0]; 00305 } 00306 00307 s = shortCuts.at(0); 00308 00309 if ( s.startsWith( QLatin1String("default(") ) ) { 00310 s = s.mid( 8, s.length() - 9 ); 00311 } 00312 00313 return QKeySequence::fromString(s)[0]; 00314 } 00315 #endif 00316 00317 // NOTE: keep this in sync with kdebase/workspace/kcontrol/colors/colorscm.cpp 00318 QColor KGlobalSettings::inactiveTitleColor() 00319 { 00320 #ifdef Q_WS_WIN 00321 return qt_colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTION)); 00322 #else 00323 KConfigGroup g( KGlobal::config(), "WM" ); 00324 return g.readEntry( "inactiveBackground", QColor(224,223,222) ); 00325 #endif 00326 } 00327 00328 // NOTE: keep this in sync with kdebase/workspace/kcontrol/colors/colorscm.cpp 00329 QColor KGlobalSettings::inactiveTextColor() 00330 { 00331 #ifdef Q_WS_WIN 00332 return qt_colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTIONTEXT)); 00333 #else 00334 KConfigGroup g( KGlobal::config(), "WM" ); 00335 return g.readEntry( "inactiveForeground", QColor(75,71,67) ); 00336 #endif 00337 } 00338 00339 // NOTE: keep this in sync with kdebase/workspace/kcontrol/colors/colorscm.cpp 00340 QColor KGlobalSettings::activeTitleColor() 00341 { 00342 #ifdef Q_WS_WIN 00343 return qt_colorref2qrgb(GetSysColor(COLOR_ACTIVECAPTION)); 00344 #else 00345 KConfigGroup g( KGlobal::config(), "WM" ); 00346 return g.readEntry( "activeBackground", QColor(48,174,232)); 00347 #endif 00348 } 00349 00350 // NOTE: keep this in sync with kdebase/workspace/kcontrol/colors/colorscm.cpp 00351 QColor KGlobalSettings::activeTextColor() 00352 { 00353 #ifdef Q_WS_WIN 00354 return qt_colorref2qrgb(GetSysColor(COLOR_CAPTIONTEXT)); 00355 #else 00356 KConfigGroup g( KGlobal::config(), "WM" ); 00357 return g.readEntry( "activeForeground", QColor(255,255,255) ); 00358 #endif 00359 } 00360 00361 int KGlobalSettings::contrast() 00362 { 00363 KConfigGroup g( KGlobal::config(), "KDE" ); 00364 return g.readEntry( "contrast", 5 ); 00365 } 00366 00367 qreal KGlobalSettings::contrastF(const KSharedConfigPtr &config) 00368 { 00369 if (config) { 00370 KConfigGroup g( config, "KDE" ); 00371 return 0.1 * g.readEntry( "contrast", 8 ); 00372 } 00373 return 0.1 * (qreal)contrast(); 00374 } 00375 00376 bool KGlobalSettings::shadeSortColumn() 00377 { 00378 KConfigGroup g( KGlobal::config(), "General" ); 00379 return g.readEntry( "shadeSortColumn", KDE_DEFAULT_SHADE_SORT_COLUMN ); 00380 } 00381 00382 bool KGlobalSettings::allowDefaultBackgroundImages() 00383 { 00384 KConfigGroup g( KGlobal::config(), "General" ); 00385 return g.readEntry( "allowDefaultBackgroundImages", KDE_DEFAULT_ALLOW_DEFAULT_BACKGROUND_IMAGES ); 00386 } 00387 00388 struct KFontData 00389 { 00390 const char* ConfigGroupKey; 00391 const char* ConfigKey; 00392 const char* FontName; 00393 int Size; 00394 int Weight; 00395 QFont::StyleHint StyleHint; 00396 }; 00397 00398 // NOTE: keep in sync with kdebase/workspace/kcontrol/fonts/fonts.cpp 00399 static const char GeneralId[] = "General"; 00400 static const char DefaultFont[] = "Sans Serif"; 00401 #ifdef Q_WS_MAC 00402 static const char DefaultMacFont[] = "Lucida Grande"; 00403 #endif 00404 00405 static const KFontData DefaultFontData[KGlobalSettingsData::FontTypesCount] = 00406 { 00407 #ifdef Q_WS_MAC 00408 { GeneralId, "font", DefaultMacFont, 13, -1, QFont::SansSerif }, 00409 { GeneralId, "fixed", "Monaco", 10, -1, QFont::TypeWriter }, 00410 { GeneralId, "toolBarFont", DefaultMacFont, 11, -1, QFont::SansSerif }, 00411 { GeneralId, "menuFont", DefaultMacFont, 13, -1, QFont::SansSerif }, 00412 #else 00413 { GeneralId, "font", DefaultFont, 9, -1, QFont::SansSerif }, 00414 { GeneralId, "fixed", "Monospace", 9, -1, QFont::TypeWriter }, 00415 { GeneralId, "toolBarFont", DefaultFont, 8, -1, QFont::SansSerif }, 00416 { GeneralId, "menuFont", DefaultFont, 9, -1, QFont::SansSerif }, 00417 #endif 00418 { "WM", "activeFont", DefaultFont, 8, -1, QFont::SansSerif }, 00419 { GeneralId, "taskbarFont", DefaultFont, 9, -1, QFont::SansSerif }, 00420 { GeneralId, "smallestReadableFont", DefaultFont, 8, -1, QFont::SansSerif } 00421 }; 00422 00423 QFont KGlobalSettingsData::font( FontTypes fontType ) 00424 { 00425 QFont* cachedFont = mFonts[fontType]; 00426 00427 if (!cachedFont) 00428 { 00429 const KFontData& fontData = DefaultFontData[fontType]; 00430 cachedFont = new QFont( fontData.FontName, fontData.Size, fontData.Weight ); 00431 cachedFont->setStyleHint( fontData.StyleHint ); 00432 00433 const KConfigGroup configGroup( KGlobal::config(), fontData.ConfigGroupKey ); 00434 *cachedFont = configGroup.readEntry( fontData.ConfigKey, *cachedFont ); 00435 00436 mFonts[fontType] = cachedFont; 00437 } 00438 00439 return *cachedFont; 00440 } 00441 00442 QFont KGlobalSettings::generalFont() 00443 { 00444 return KGlobalSettingsData::self()->font( KGlobalSettingsData::GeneralFont ); 00445 } 00446 QFont KGlobalSettings::fixedFont() 00447 { 00448 return KGlobalSettingsData::self()->font( KGlobalSettingsData::FixedFont ); 00449 } 00450 QFont KGlobalSettings::toolBarFont() 00451 { 00452 return KGlobalSettingsData::self()->font( KGlobalSettingsData::ToolbarFont ); 00453 } 00454 QFont KGlobalSettings::menuFont() 00455 { 00456 return KGlobalSettingsData::self()->font( KGlobalSettingsData::MenuFont ); 00457 } 00458 QFont KGlobalSettings::windowTitleFont() 00459 { 00460 return KGlobalSettingsData::self()->font( KGlobalSettingsData::WindowTitleFont ); 00461 } 00462 QFont KGlobalSettings::taskbarFont() 00463 { 00464 return KGlobalSettingsData::self()->font( KGlobalSettingsData::TaskbarFont ); 00465 } 00466 QFont KGlobalSettings::smallestReadableFont() 00467 { 00468 return KGlobalSettingsData::self()->font( KGlobalSettingsData::SmallestReadableFont ); 00469 } 00470 00471 00472 QFont KGlobalSettingsData::largeFont( const QString& text ) 00473 { 00474 QFontDatabase db; 00475 QStringList fam = db.families(); 00476 00477 // Move a bunch of preferred fonts to the front. 00478 // most preferred last 00479 static const char* const PreferredFontNames[] = 00480 { 00481 "Arial", 00482 "Sans Serif", 00483 "Verdana", 00484 "Tahoma", 00485 "Lucida Sans", 00486 "Lucidux Sans", 00487 "Nimbus Sans", 00488 "Gothic I" 00489 }; 00490 static const unsigned int PreferredFontNamesCount = sizeof(PreferredFontNames)/sizeof(const char*); 00491 for( unsigned int i=0; i<PreferredFontNamesCount; ++i ) 00492 { 00493 const QString fontName (PreferredFontNames[i]); 00494 if (fam.removeAll(fontName)>0) 00495 fam.prepend(fontName); 00496 } 00497 00498 if (mLargeFont) { 00499 fam.prepend(mLargeFont->family()); 00500 delete mLargeFont; 00501 } 00502 00503 for(QStringList::ConstIterator it = fam.constBegin(); 00504 it != fam.constEnd(); ++it) 00505 { 00506 if (db.isSmoothlyScalable(*it) && !db.isFixedPitch(*it)) 00507 { 00508 QFont font(*it); 00509 font.setPixelSize(75); 00510 QFontMetrics metrics(font); 00511 int h = metrics.height(); 00512 if ((h < 60) || ( h > 90)) 00513 continue; 00514 00515 bool ok = true; 00516 for(int i = 0; i < text.length(); i++) 00517 { 00518 if (!metrics.inFont(text[i])) 00519 { 00520 ok = false; 00521 break; 00522 } 00523 } 00524 if (!ok) 00525 continue; 00526 00527 font.setPointSize(48); 00528 mLargeFont = new QFont(font); 00529 return *mLargeFont; 00530 } 00531 } 00532 mLargeFont = new QFont( font(GeneralFont) ); 00533 mLargeFont->setPointSize(48); 00534 return *mLargeFont; 00535 } 00536 QFont KGlobalSettings::largeFont( const QString& text ) 00537 { 00538 return KGlobalSettingsData::self()->largeFont( text ); 00539 } 00540 00541 void KGlobalSettingsData::dropFontSettingsCache() 00542 { 00543 for( int i=0; i<FontTypesCount; ++i ) 00544 { 00545 delete mFonts[i]; 00546 mFonts[i] = 0; 00547 } 00548 delete mLargeFont; 00549 mLargeFont = 0; 00550 } 00551 00552 KGlobalSettings::KMouseSettings& KGlobalSettingsData::mouseSettings() 00553 { 00554 if (!mMouseSettings) 00555 { 00556 mMouseSettings = new KGlobalSettings::KMouseSettings; 00557 KGlobalSettings::KMouseSettings& s = *mMouseSettings; // for convenience 00558 00559 #ifndef Q_WS_WIN 00560 KConfigGroup g( KGlobal::config(), "Mouse" ); 00561 QString setting = g.readEntry("MouseButtonMapping"); 00562 if (setting == "RightHanded") 00563 s.handed = KGlobalSettings::KMouseSettings::RightHanded; 00564 else if (setting == "LeftHanded") 00565 s.handed = KGlobalSettings::KMouseSettings::LeftHanded; 00566 else 00567 { 00568 #ifdef Q_WS_X11 00569 // get settings from X server 00570 // This is a simplified version of the code in input/mouse.cpp 00571 // Keep in sync ! 00572 s.handed = KGlobalSettings::KMouseSettings::RightHanded; 00573 unsigned char map[20]; 00574 int num_buttons = XGetPointerMapping(QX11Info::display(), map, 20); 00575 if( num_buttons == 2 ) 00576 { 00577 if ( (int)map[0] == 1 && (int)map[1] == 2 ) 00578 s.handed = KGlobalSettings::KMouseSettings::RightHanded; 00579 else if ( (int)map[0] == 2 && (int)map[1] == 1 ) 00580 s.handed = KGlobalSettings::KMouseSettings::LeftHanded; 00581 } 00582 else if( num_buttons >= 3 ) 00583 { 00584 if ( (int)map[0] == 1 && (int)map[2] == 3 ) 00585 s.handed = KGlobalSettings::KMouseSettings::RightHanded; 00586 else if ( (int)map[0] == 3 && (int)map[2] == 1 ) 00587 s.handed = KGlobalSettings::KMouseSettings::LeftHanded; 00588 } 00589 #else 00590 // FIXME: Implement on other platforms 00591 #endif 00592 } 00593 #endif //Q_WS_WIN 00594 } 00595 #ifdef Q_WS_WIN 00596 //not cached 00597 #ifndef _WIN32_WCE 00598 mMouseSettings->handed = (GetSystemMetrics(SM_SWAPBUTTON) ? 00599 KGlobalSettings::KMouseSettings::LeftHanded : 00600 KGlobalSettings::KMouseSettings::RightHanded); 00601 #else 00602 // There is no mice under wince 00603 mMouseSettings->handed =KGlobalSettings::KMouseSettings::RightHanded; 00604 #endif 00605 #endif 00606 return *mMouseSettings; 00607 } 00608 // KDE5: make this a const return? 00609 KGlobalSettings::KMouseSettings & KGlobalSettings::mouseSettings() 00610 { 00611 return KGlobalSettingsData::self()->mouseSettings(); 00612 } 00613 00614 void KGlobalSettingsData::dropMouseSettingsCache() 00615 { 00616 #ifndef Q_WS_WIN 00617 delete mMouseSettings; 00618 mMouseSettings = 0; 00619 #endif 00620 } 00621 00622 QString KGlobalSettings::desktopPath() 00623 { 00624 QString path = QDesktopServices::storageLocation( QDesktopServices::DesktopLocation ); 00625 return path.isEmpty() ? QDir::homePath() : path; 00626 } 00627 00628 // Autostart is not a XDG path, so we have our own code for it. 00629 QString KGlobalSettings::autostartPath() 00630 { 00631 QString s_autostartPath; 00632 KConfigGroup g( KGlobal::config(), "Paths" ); 00633 s_autostartPath = KGlobal::dirs()->localkdedir() + "Autostart/"; 00634 s_autostartPath = g.readPathEntry( "Autostart" , s_autostartPath ); 00635 s_autostartPath = QDir::cleanPath( s_autostartPath ); 00636 if ( !s_autostartPath.endsWith( '/' ) ) { 00637 s_autostartPath.append( QLatin1Char( '/' ) ); 00638 } 00639 return s_autostartPath; 00640 } 00641 00642 QString KGlobalSettings::documentPath() 00643 { 00644 QString path = QDesktopServices::storageLocation( QDesktopServices::DocumentsLocation ); 00645 return path.isEmpty() ? QDir::homePath() : path; 00646 } 00647 00648 QString KGlobalSettings::downloadPath() 00649 { 00650 // Qt 4.4.1 does not have DOWNLOAD, so we based on old code for now 00651 QString downloadPath = QDir::homePath(); 00652 #ifndef Q_WS_WIN 00653 const QString xdgUserDirs = KGlobal::dirs()->localxdgconfdir() + QLatin1String( "user-dirs.dirs" ); 00654 if( QFile::exists( xdgUserDirs ) ) { 00655 KConfig xdgUserConf( xdgUserDirs, KConfig::SimpleConfig ); 00656 KConfigGroup g( &xdgUserConf, "" ); 00657 downloadPath = g.readPathEntry( "XDG_DOWNLOAD_DIR", downloadPath ).remove( '"' ); 00658 if ( downloadPath.isEmpty() ) { 00659 downloadPath = QDir::homePath(); 00660 } 00661 } 00662 #endif 00663 downloadPath = QDir::cleanPath( downloadPath ); 00664 if ( !downloadPath.endsWith( '/' ) ) { 00665 downloadPath.append( QLatin1Char( '/' ) ); 00666 } 00667 return downloadPath; 00668 } 00669 00670 QString KGlobalSettings::videosPath() 00671 { 00672 QString path = QDesktopServices::storageLocation( QDesktopServices::MoviesLocation ); 00673 return path.isEmpty() ? QDir::homePath() : path; 00674 } 00675 00676 QString KGlobalSettings::picturesPath() 00677 { 00678 QString path = QDesktopServices::storageLocation( QDesktopServices::PicturesLocation ); 00679 return path.isEmpty() ? QDir::homePath() :path; 00680 } 00681 00682 QString KGlobalSettings::musicPath() 00683 { 00684 QString path = QDesktopServices::storageLocation( QDesktopServices::MusicLocation ); 00685 return path.isEmpty() ? QDir::homePath() : path; 00686 } 00687 00688 bool KGlobalSettings::isMultiHead() 00689 { 00690 #ifdef Q_WS_WIN 00691 return GetSystemMetrics(SM_CMONITORS) > 1; 00692 #else 00693 QByteArray multiHead = qgetenv("KDE_MULTIHEAD"); 00694 if (!multiHead.isEmpty()) { 00695 return (multiHead.toLower() == "true"); 00696 } 00697 return false; 00698 #endif 00699 } 00700 00701 bool KGlobalSettings::wheelMouseZooms() 00702 { 00703 KConfigGroup g( KGlobal::config(), "KDE" ); 00704 return g.readEntry( "WheelMouseZooms", KDE_DEFAULT_WHEEL_ZOOM ); 00705 } 00706 00707 QRect KGlobalSettings::splashScreenDesktopGeometry() 00708 { 00709 QDesktopWidget *dw = QApplication::desktop(); 00710 00711 if (dw->isVirtualDesktop()) { 00712 KConfigGroup group(KGlobal::config(), "Windows"); 00713 int scr = group.readEntry("Unmanaged", -3); 00714 if (group.readEntry("XineramaEnabled", true) && scr != -2) { 00715 if (scr == -3) 00716 scr = dw->screenNumber(QCursor::pos()); 00717 return dw->screenGeometry(scr); 00718 } else { 00719 return dw->geometry(); 00720 } 00721 } else { 00722 return dw->geometry(); 00723 } 00724 } 00725 00726 QRect KGlobalSettings::desktopGeometry(const QPoint& point) 00727 { 00728 QDesktopWidget *dw = QApplication::desktop(); 00729 00730 if (dw->isVirtualDesktop()) { 00731 KConfigGroup group(KGlobal::config(), "Windows"); 00732 if (group.readEntry("XineramaEnabled", true) && 00733 group.readEntry("XineramaPlacementEnabled", true)) { 00734 return dw->screenGeometry(dw->screenNumber(point)); 00735 } else { 00736 return dw->geometry(); 00737 } 00738 } else { 00739 return dw->geometry(); 00740 } 00741 } 00742 00743 QRect KGlobalSettings::desktopGeometry(const QWidget* w) 00744 { 00745 QDesktopWidget *dw = QApplication::desktop(); 00746 00747 if (dw->isVirtualDesktop()) { 00748 KConfigGroup group(KGlobal::config(), "Windows"); 00749 if (group.readEntry("XineramaEnabled", true) && 00750 group.readEntry("XineramaPlacementEnabled", true)) { 00751 if (w) 00752 return dw->screenGeometry(dw->screenNumber(w)); 00753 else return dw->screenGeometry(-1); 00754 } else { 00755 return dw->geometry(); 00756 } 00757 } else { 00758 return dw->geometry(); 00759 } 00760 } 00761 00762 bool KGlobalSettings::showIconsOnPushButtons() 00763 { 00764 KConfigGroup g( KGlobal::config(), "KDE" ); 00765 return g.readEntry("ShowIconsOnPushButtons", 00766 KDE_DEFAULT_ICON_ON_PUSHBUTTON); 00767 } 00768 00769 bool KGlobalSettings::naturalSorting() 00770 { 00771 KConfigGroup g( KGlobal::config(), "KDE" ); 00772 return g.readEntry("NaturalSorting", 00773 KDE_DEFAULT_NATURAL_SORTING); 00774 } 00775 00776 KGlobalSettings::GraphicEffects KGlobalSettings::graphicEffectsLevel() 00777 { 00778 // This variable stores whether _graphicEffects has the default value because it has not been 00779 // loaded yet, or if it has been loaded from the user settings or defaults and contains a valid 00780 // value. 00781 static bool _graphicEffectsInitialized = false; 00782 00783 if (!_graphicEffectsInitialized) { 00784 _graphicEffectsInitialized = true; 00785 Private::rereadOtherSettings(); 00786 } 00787 00788 return _graphicEffects; 00789 } 00790 00791 KGlobalSettings::GraphicEffects KGlobalSettings::graphicEffectsLevelDefault() 00792 { 00793 // For now, let always enable animations by default. The plan is to make 00794 // this code a bit smarter. (ereslibre) 00795 00796 return ComplexAnimationEffects; 00797 } 00798 00799 bool KGlobalSettings::showFilePreview(const KUrl &url) 00800 { 00801 KConfigGroup g(KGlobal::config(), "PreviewSettings"); 00802 QString protocol = url.protocol(); 00803 bool defaultSetting = KProtocolInfo::showFilePreview( protocol ); 00804 return g.readEntry(protocol, defaultSetting ); 00805 } 00806 00807 bool KGlobalSettings::opaqueResize() 00808 { 00809 KConfigGroup g( KGlobal::config(), "KDE" ); 00810 return g.readEntry("OpaqueResize", KDE_DEFAULT_OPAQUE_RESIZE); 00811 } 00812 00813 int KGlobalSettings::buttonLayout() 00814 { 00815 KConfigGroup g( KGlobal::config(), "KDE" ); 00816 return g.readEntry("ButtonLayout", KDE_DEFAULT_BUTTON_LAYOUT); 00817 } 00818 00819 void KGlobalSettings::emitChange(ChangeType changeType, int arg) 00820 { 00821 QDBusMessage message = QDBusMessage::createSignal("/KGlobalSettings", "org.kde.KGlobalSettings", "notifyChange" ); 00822 QList<QVariant> args; 00823 args.append(static_cast<int>(changeType)); 00824 args.append(arg); 00825 message.setArguments(args); 00826 QDBusConnection::sessionBus().send(message); 00827 #ifdef Q_WS_X11 00828 if (qApp && qApp->type() != QApplication::Tty) { 00829 //notify non-kde qt applications of the change 00830 extern void qt_x11_apply_settings_in_all_apps(); 00831 qt_x11_apply_settings_in_all_apps(); 00832 } 00833 #endif 00834 } 00835 00836 void KGlobalSettings::Private::_k_slotNotifyChange(int changeType, int arg) 00837 { 00838 switch(changeType) { 00839 case StyleChanged: 00840 if (activated) { 00841 KGlobal::config()->reparseConfiguration(); 00842 kdisplaySetStyle(); 00843 } 00844 break; 00845 00846 case ToolbarStyleChanged: 00847 KGlobal::config()->reparseConfiguration(); 00848 emit q->toolbarAppearanceChanged(arg); 00849 break; 00850 00851 case PaletteChanged: 00852 if (activated) { 00853 KGlobal::config()->reparseConfiguration(); 00854 paletteCreated = false; 00855 kdisplaySetPalette(); 00856 } 00857 break; 00858 00859 case FontChanged: 00860 KGlobal::config()->reparseConfiguration(); 00861 KGlobalSettingsData::self()->dropFontSettingsCache(); 00862 if (activated) { 00863 kdisplaySetFont(); 00864 } 00865 break; 00866 00867 case SettingsChanged: { 00868 KGlobal::config()->reparseConfiguration(); 00869 rereadOtherSettings(); 00870 SettingsCategory category = static_cast<SettingsCategory>(arg); 00871 if (category == SETTINGS_MOUSE) { 00872 KGlobalSettingsData::self()->dropMouseSettingsCache(); 00873 } 00874 if (category == SETTINGS_QT) { 00875 if (activated) { 00876 propagateQtSettings(); 00877 } 00878 } else { 00879 emit q->settingsChanged(category); 00880 } 00881 break; 00882 } 00883 case IconChanged: 00884 QPixmapCache::clear(); 00885 KGlobal::config()->reparseConfiguration(); 00886 emit q->iconChanged(arg); 00887 break; 00888 00889 case CursorChanged: 00890 applyCursorTheme(); 00891 break; 00892 00893 case BlockShortcuts: 00894 // FIXME KAccel port 00895 //KGlobalAccel::blockShortcuts(arg); 00896 emit q->blockShortcuts(arg); // see kwin 00897 break; 00898 00899 case NaturalSortingChanged: 00900 emit q->naturalSortingChanged(); 00901 break; 00902 00903 default: 00904 kWarning(101) << "Unknown type of change in KGlobalSettings::slotNotifyChange: " << changeType; 00905 } 00906 } 00907 00908 // Set by KApplication 00909 QString kde_overrideStyle; 00910 00911 void KGlobalSettings::Private::applyGUIStyle() 00912 { 00913 //Platform plugin only loaded on X11 systems 00914 #ifdef Q_WS_X11 00915 if (!kde_overrideStyle.isEmpty()) { 00916 const QLatin1String currentStyleName(qApp->style()->metaObject()->className()); 00917 if (0 != kde_overrideStyle.compare(currentStyleName, Qt::CaseInsensitive) && 00918 0 != (QString(kde_overrideStyle + QLatin1String("Style"))).compare(currentStyleName, Qt::CaseInsensitive)) { 00919 qApp->setStyle(kde_overrideStyle); 00920 } 00921 } else { 00922 emit q->kdisplayStyleChanged(); 00923 } 00924 #else 00925 const QLatin1String currentStyleName(qApp->style()->metaObject()->className()); 00926 00927 if (kde_overrideStyle.isEmpty()) { 00928 const QString &defaultStyle = KStyle::defaultStyle(); 00929 const KConfigGroup pConfig(KGlobal::config(), "General"); 00930 const QString &styleStr = pConfig.readEntry("widgetStyle4", pConfig.readEntry("widgetStyle", defaultStyle)); 00931 00932 if (styleStr.isEmpty() || 00933 // check whether we already use the correct style to return then 00934 // (workaround for Qt misbehavior to avoid double style initialization) 00935 0 == (QString(styleStr + QLatin1String("Style"))).compare(currentStyleName, Qt::CaseInsensitive) || 00936 0 == styleStr.compare(currentStyleName, Qt::CaseInsensitive)) { 00937 return; 00938 } 00939 00940 QStyle* sp = QStyleFactory::create( styleStr ); 00941 if (sp && currentStyleName == sp->metaObject()->className()) { 00942 delete sp; 00943 return; 00944 } 00945 00946 // If there is no default style available, try falling back any available style 00947 if ( !sp && styleStr != defaultStyle) 00948 sp = QStyleFactory::create( defaultStyle ); 00949 if ( !sp ) 00950 sp = QStyleFactory::create( QStyleFactory::keys().first() ); 00951 qApp->setStyle(sp); 00952 } else if (0 != kde_overrideStyle.compare(currentStyleName, Qt::CaseInsensitive) && 00953 0 != (QString(kde_overrideStyle + QLatin1String("Style"))).compare(currentStyleName, Qt::CaseInsensitive)) { 00954 qApp->setStyle(kde_overrideStyle); 00955 } 00956 emit q->kdisplayStyleChanged(); 00957 #endif //Q_WS_X11 00958 } 00959 00960 QPalette KGlobalSettings::createApplicationPalette(const KSharedConfigPtr &config) 00961 { 00962 return self()->d->createApplicationPalette(config); 00963 } 00964 00965 QPalette KGlobalSettings::Private::createApplicationPalette(const KSharedConfigPtr &config) 00966 { 00967 // This method is typically called once by KQGuiPlatformPlugin::palette and once again 00968 // by kdisplaySetPalette(), so we cache the palette to save time. 00969 if (!paletteCreated) { 00970 paletteCreated = true; 00971 00972 QPalette palette; 00973 00974 QPalette::ColorGroup states[3] = { QPalette::Active, QPalette::Inactive, 00975 QPalette::Disabled }; 00976 00977 // TT thinks tooltips shouldn't use active, so we use our active colors for all states 00978 KColorScheme schemeTooltip(QPalette::Active, KColorScheme::Tooltip, config); 00979 00980 for ( int i = 0; i < 3 ; i++ ) { 00981 QPalette::ColorGroup state = states[i]; 00982 KColorScheme schemeView(state, KColorScheme::View, config); 00983 KColorScheme schemeWindow(state, KColorScheme::Window, config); 00984 KColorScheme schemeButton(state, KColorScheme::Button, config); 00985 KColorScheme schemeSelection(state, KColorScheme::Selection, config); 00986 00987 palette.setBrush( state, QPalette::WindowText, schemeWindow.foreground() ); 00988 palette.setBrush( state, QPalette::Window, schemeWindow.background() ); 00989 palette.setBrush( state, QPalette::Base, schemeView.background() ); 00990 palette.setBrush( state, QPalette::Text, schemeView.foreground() ); 00991 palette.setBrush( state, QPalette::Button, schemeButton.background() ); 00992 palette.setBrush( state, QPalette::ButtonText, schemeButton.foreground() ); 00993 palette.setBrush( state, QPalette::Highlight, schemeSelection.background() ); 00994 palette.setBrush( state, QPalette::HighlightedText, schemeSelection.foreground() ); 00995 palette.setBrush( state, QPalette::ToolTipBase, schemeTooltip.background() ); 00996 palette.setBrush( state, QPalette::ToolTipText, schemeTooltip.foreground() ); 00997 00998 palette.setColor( state, QPalette::Light, schemeWindow.shade( KColorScheme::LightShade ) ); 00999 palette.setColor( state, QPalette::Midlight, schemeWindow.shade( KColorScheme::MidlightShade ) ); 01000 palette.setColor( state, QPalette::Mid, schemeWindow.shade( KColorScheme::MidShade ) ); 01001 palette.setColor( state, QPalette::Dark, schemeWindow.shade( KColorScheme::DarkShade ) ); 01002 palette.setColor( state, QPalette::Shadow, schemeWindow.shade( KColorScheme::ShadowShade ) ); 01003 01004 palette.setBrush( state, QPalette::AlternateBase, schemeView.background( KColorScheme::AlternateBackground) ); 01005 palette.setBrush( state, QPalette::Link, schemeView.foreground( KColorScheme::LinkText ) ); 01006 palette.setBrush( state, QPalette::LinkVisited, schemeView.foreground( KColorScheme::VisitedText ) ); 01007 } 01008 applicationPalette = palette; 01009 } 01010 01011 return applicationPalette; 01012 } 01013 01014 void KGlobalSettings::Private::kdisplaySetPalette() 01015 { 01016 // Added by Sam/Harald (TT) for Mac OS X initially, but why? 01017 KConfigGroup cg( KGlobal::config(), "General" ); 01018 if (cg.readEntry("nopaletteChange", false)) 01019 return; 01020 01021 if (qApp->type() == QApplication::GuiClient) { 01022 QApplication::setPalette( q->createApplicationPalette() ); 01023 } 01024 emit q->kdisplayPaletteChanged(); 01025 emit q->appearanceChanged(); 01026 } 01027 01028 01029 void KGlobalSettings::Private::kdisplaySetFont() 01030 { 01031 if (qApp->type() == QApplication::GuiClient) { 01032 KGlobalSettingsData* data = KGlobalSettingsData::self(); 01033 01034 QApplication::setFont( data->font(KGlobalSettingsData::GeneralFont) ); 01035 const QFont menuFont = data->font( KGlobalSettingsData::MenuFont ); 01036 QApplication::setFont( menuFont, "QMenuBar" ); 01037 QApplication::setFont( menuFont, "QMenu" ); 01038 QApplication::setFont( menuFont, "KPopupTitle" ); 01039 QApplication::setFont( data->font(KGlobalSettingsData::ToolbarFont), "QToolBar" ); 01040 } 01041 emit q->kdisplayFontChanged(); 01042 emit q->appearanceChanged(); 01043 } 01044 01045 01046 void KGlobalSettings::Private::kdisplaySetStyle() 01047 { 01048 if (qApp->type() == QApplication::GuiClient) { 01049 applyGUIStyle(); 01050 01051 // Reread palette from config file. 01052 kdisplaySetPalette(); 01053 } 01054 } 01055 01056 01057 void KGlobalSettings::Private::rereadOtherSettings() 01058 { 01059 KConfigGroup g( KGlobal::config(), "KDE-Global GUI Settings" ); 01060 01061 // Asking for hasKey we do not ask for graphicEffectsLevelDefault() that can 01062 // contain some very slow code. If we can save that time, do it. (ereslibre) 01063 01064 if (g.hasKey("GraphicEffectsLevel")) { 01065 _graphicEffects = ((GraphicEffects) g.readEntry("GraphicEffectsLevel", QVariant((int) NoEffects)).toInt()); 01066 01067 return; 01068 } 01069 01070 _graphicEffects = KGlobalSettings::graphicEffectsLevelDefault(); 01071 } 01072 01073 01074 void KGlobalSettings::Private::applyCursorTheme() 01075 { 01076 #if defined(Q_WS_X11) && defined(HAVE_XCURSOR) 01077 KConfig config("kcminputrc"); 01078 KConfigGroup g(&config, "Mouse"); 01079 01080 QString theme = g.readEntry("cursorTheme", QString()); 01081 int size = g.readEntry("cursorSize", -1); 01082 01083 // Default cursor size is 16 points 01084 if (size == -1) 01085 { 01086 QApplication *app = static_cast<QApplication*>(QApplication::instance()); 01087 size = app->desktop()->screen(0)->logicalDpiY() * 16 / 72; 01088 } 01089 01090 // Note that in X11R7.1 and earlier, calling XcursorSetTheme() 01091 // with a NULL theme would cause Xcursor to use "default", but 01092 // in 7.2 and later it will cause it to revert to the theme that 01093 // was configured when the application was started. 01094 XcursorSetTheme(QX11Info::display(), theme.isNull() ? 01095 "default" : QFile::encodeName(theme)); 01096 XcursorSetDefaultSize(QX11Info::display(), size); 01097 01098 emit q->cursorChanged(); 01099 #endif 01100 } 01101 01102 01103 void KGlobalSettings::Private::propagateQtSettings() 01104 { 01105 KConfigGroup cg( KGlobal::config(), "KDE" ); 01106 01107 int num = cg.readEntry("CursorBlinkRate", QApplication::cursorFlashTime()); 01108 if ((num != 0) && (num < 200)) 01109 num = 200; 01110 if (num > 2000) 01111 num = 2000; 01112 QApplication::setCursorFlashTime(num); 01113 num = cg.readEntry("DoubleClickInterval", QApplication::doubleClickInterval()); 01114 QApplication::setDoubleClickInterval(num); 01115 num = cg.readEntry("StartDragTime", QApplication::startDragTime()); 01116 QApplication::setStartDragTime(num); 01117 num = cg.readEntry("StartDragDist", QApplication::startDragDistance()); 01118 QApplication::setStartDragDistance(num); 01119 num = cg.readEntry("WheelScrollLines", QApplication::wheelScrollLines()); 01120 QApplication::setWheelScrollLines(num); 01121 bool showIcons = cg.readEntry("ShowIconsInMenuItems", !QApplication::testAttribute(Qt::AA_DontShowIconsInMenus)); 01122 QApplication::setAttribute(Qt::AA_DontShowIconsInMenus, !showIcons); 01123 01124 // KDE5: this seems fairly pointless 01125 emit q->settingsChanged(SETTINGS_QT); 01126 } 01127 01128 #include "kglobalsettings.moc"
KDE 4.6 API Reference