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