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