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.x does not have QDesktopServices::DownloadLocation, so we do our own xdg reading. 00655 QString defaultDownloadPath = QDir::homePath() + "/Downloads"; 00656 QString downloadPath = defaultDownloadPath; 00657 #ifndef Q_WS_WIN 00658 const QString xdgUserDirs = KGlobal::dirs()->localxdgconfdir() + QLatin1String( "user-dirs.dirs" ); 00659 if( QFile::exists( xdgUserDirs ) ) { 00660 KConfig xdgUserConf( xdgUserDirs, KConfig::SimpleConfig ); 00661 KConfigGroup g( &xdgUserConf, "" ); 00662 downloadPath = g.readPathEntry( "XDG_DOWNLOAD_DIR", downloadPath ).remove( '"' ); 00663 if ( downloadPath.isEmpty() ) { 00664 downloadPath = defaultDownloadPath; 00665 } 00666 } 00667 #endif 00668 downloadPath = QDir::cleanPath( downloadPath ); 00669 QDir().mkpath(downloadPath); 00670 if ( !downloadPath.endsWith( '/' ) ) { 00671 downloadPath.append( QLatin1Char( '/' ) ); 00672 } 00673 return downloadPath; 00674 } 00675 00676 QString KGlobalSettings::videosPath() 00677 { 00678 QString path = QDesktopServices::storageLocation( QDesktopServices::MoviesLocation ); 00679 return path.isEmpty() ? QDir::homePath() : path; 00680 } 00681 00682 QString KGlobalSettings::picturesPath() 00683 { 00684 QString path = QDesktopServices::storageLocation( QDesktopServices::PicturesLocation ); 00685 return path.isEmpty() ? QDir::homePath() :path; 00686 } 00687 00688 QString KGlobalSettings::musicPath() 00689 { 00690 QString path = QDesktopServices::storageLocation( QDesktopServices::MusicLocation ); 00691 return path.isEmpty() ? QDir::homePath() : path; 00692 } 00693 00694 bool KGlobalSettings::isMultiHead() 00695 { 00696 #ifdef Q_WS_WIN 00697 return GetSystemMetrics(SM_CMONITORS) > 1; 00698 #else 00699 QByteArray multiHead = qgetenv("KDE_MULTIHEAD"); 00700 if (!multiHead.isEmpty()) { 00701 return (multiHead.toLower() == "true"); 00702 } 00703 return false; 00704 #endif 00705 } 00706 00707 bool KGlobalSettings::wheelMouseZooms() 00708 { 00709 KConfigGroup g( KGlobal::config(), "KDE" ); 00710 return g.readEntry( "WheelMouseZooms", KDE_DEFAULT_WHEEL_ZOOM ); 00711 } 00712 00713 QRect KGlobalSettings::splashScreenDesktopGeometry() 00714 { 00715 QDesktopWidget *dw = QApplication::desktop(); 00716 00717 if (dw->isVirtualDesktop()) { 00718 KConfigGroup group(KGlobal::config(), "Windows"); 00719 int scr = group.readEntry("Unmanaged", -3); 00720 if (group.readEntry("XineramaEnabled", true) && scr != -2) { 00721 if (scr == -3) 00722 scr = dw->screenNumber(QCursor::pos()); 00723 return dw->screenGeometry(scr); 00724 } else { 00725 return dw->geometry(); 00726 } 00727 } else { 00728 return dw->geometry(); 00729 } 00730 } 00731 00732 QRect KGlobalSettings::desktopGeometry(const QPoint& point) 00733 { 00734 QDesktopWidget *dw = QApplication::desktop(); 00735 00736 if (dw->isVirtualDesktop()) { 00737 KConfigGroup group(KGlobal::config(), "Windows"); 00738 if (group.readEntry("XineramaEnabled", true) && 00739 group.readEntry("XineramaPlacementEnabled", true)) { 00740 return dw->screenGeometry(dw->screenNumber(point)); 00741 } else { 00742 return dw->geometry(); 00743 } 00744 } else { 00745 return dw->geometry(); 00746 } 00747 } 00748 00749 QRect KGlobalSettings::desktopGeometry(const QWidget* w) 00750 { 00751 QDesktopWidget *dw = QApplication::desktop(); 00752 00753 if (dw->isVirtualDesktop()) { 00754 KConfigGroup group(KGlobal::config(), "Windows"); 00755 if (group.readEntry("XineramaEnabled", true) && 00756 group.readEntry("XineramaPlacementEnabled", true)) { 00757 if (w) 00758 return dw->screenGeometry(dw->screenNumber(w)); 00759 else return dw->screenGeometry(-1); 00760 } else { 00761 return dw->geometry(); 00762 } 00763 } else { 00764 return dw->geometry(); 00765 } 00766 } 00767 00768 bool KGlobalSettings::showIconsOnPushButtons() 00769 { 00770 KConfigGroup g( KGlobal::config(), "KDE" ); 00771 return g.readEntry("ShowIconsOnPushButtons", 00772 KDE_DEFAULT_ICON_ON_PUSHBUTTON); 00773 } 00774 00775 bool KGlobalSettings::naturalSorting() 00776 { 00777 KConfigGroup g( KGlobal::config(), "KDE" ); 00778 return g.readEntry("NaturalSorting", 00779 KDE_DEFAULT_NATURAL_SORTING); 00780 } 00781 00782 KGlobalSettings::GraphicEffects KGlobalSettings::graphicEffectsLevel() 00783 { 00784 // This variable stores whether _graphicEffects has the default value because it has not been 00785 // loaded yet, or if it has been loaded from the user settings or defaults and contains a valid 00786 // value. 00787 static bool _graphicEffectsInitialized = false; 00788 00789 if (!_graphicEffectsInitialized) { 00790 _graphicEffectsInitialized = true; 00791 Private::reloadStyleSettings(); 00792 } 00793 00794 return _graphicEffects; 00795 } 00796 00797 KGlobalSettings::GraphicEffects KGlobalSettings::graphicEffectsLevelDefault() 00798 { 00799 // For now, let always enable animations by default. The plan is to make 00800 // this code a bit smarter. (ereslibre) 00801 00802 return ComplexAnimationEffects; 00803 } 00804 00805 bool KGlobalSettings::showFilePreview(const KUrl &url) 00806 { 00807 KConfigGroup g(KGlobal::config(), "PreviewSettings"); 00808 QString protocol = url.protocol(); 00809 bool defaultSetting = KProtocolInfo::showFilePreview( protocol ); 00810 return g.readEntry(protocol, defaultSetting ); 00811 } 00812 00813 bool KGlobalSettings::opaqueResize() 00814 { 00815 KConfigGroup g( KGlobal::config(), "KDE" ); 00816 return g.readEntry("OpaqueResize", KDE_DEFAULT_OPAQUE_RESIZE); 00817 } 00818 00819 int KGlobalSettings::buttonLayout() 00820 { 00821 KConfigGroup g( KGlobal::config(), "KDE" ); 00822 return g.readEntry("ButtonLayout", KDE_DEFAULT_BUTTON_LAYOUT); 00823 } 00824 00825 void KGlobalSettings::emitChange(ChangeType changeType, int arg) 00826 { 00827 QDBusMessage message = QDBusMessage::createSignal("/KGlobalSettings", "org.kde.KGlobalSettings", "notifyChange" ); 00828 QList<QVariant> args; 00829 args.append(static_cast<int>(changeType)); 00830 args.append(arg); 00831 message.setArguments(args); 00832 QDBusConnection::sessionBus().send(message); 00833 #ifdef Q_WS_X11 00834 if (qApp && qApp->type() != QApplication::Tty) { 00835 //notify non-kde qt applications of the change 00836 extern void qt_x11_apply_settings_in_all_apps(); 00837 qt_x11_apply_settings_in_all_apps(); 00838 } 00839 #endif 00840 } 00841 00842 void KGlobalSettings::Private::_k_slotNotifyChange(int changeType, int arg) 00843 { 00844 switch(changeType) { 00845 case StyleChanged: 00846 if (activated) { 00847 KGlobal::config()->reparseConfiguration(); 00848 kdisplaySetStyle(); 00849 } 00850 break; 00851 00852 case ToolbarStyleChanged: 00853 KGlobal::config()->reparseConfiguration(); 00854 emit q->toolbarAppearanceChanged(arg); 00855 break; 00856 00857 case PaletteChanged: 00858 if (activated) { 00859 KGlobal::config()->reparseConfiguration(); 00860 paletteCreated = false; 00861 kdisplaySetPalette(); 00862 } 00863 break; 00864 00865 case FontChanged: 00866 KGlobal::config()->reparseConfiguration(); 00867 KGlobalSettingsData::self()->dropFontSettingsCache(); 00868 if (activated) { 00869 kdisplaySetFont(); 00870 } 00871 break; 00872 00873 case SettingsChanged: { 00874 KGlobal::config()->reparseConfiguration(); 00875 SettingsCategory category = static_cast<SettingsCategory>(arg); 00876 if (category == SETTINGS_QT) { 00877 if (activated) { 00878 propagateQtSettings(); 00879 } 00880 } else { 00881 switch (category) { 00882 case SETTINGS_STYLE: 00883 reloadStyleSettings(); 00884 break; 00885 case SETTINGS_MOUSE: 00886 KGlobalSettingsData::self()->dropMouseSettingsCache(); 00887 break; 00888 case SETTINGS_LOCALE: 00889 KGlobal::locale()->reparseConfiguration(); 00890 break; 00891 default: 00892 break; 00893 } 00894 emit q->settingsChanged(category); 00895 } 00896 break; 00897 } 00898 case IconChanged: 00899 QPixmapCache::clear(); 00900 KGlobal::config()->reparseConfiguration(); 00901 emit q->iconChanged(arg); 00902 break; 00903 00904 case CursorChanged: 00905 applyCursorTheme(); 00906 break; 00907 00908 case BlockShortcuts: 00909 // FIXME KAccel port 00910 //KGlobalAccel::blockShortcuts(arg); 00911 emit q->blockShortcuts(arg); // see kwin 00912 break; 00913 00914 case NaturalSortingChanged: 00915 emit q->naturalSortingChanged(); 00916 break; 00917 00918 default: 00919 kWarning(240) << "Unknown type of change in KGlobalSettings::slotNotifyChange: " << changeType; 00920 } 00921 } 00922 00923 // Set by KApplication 00924 QString kde_overrideStyle; 00925 00926 void KGlobalSettings::Private::applyGUIStyle() 00927 { 00928 //Platform plugin only loaded on X11 systems 00929 #ifdef Q_WS_X11 00930 if (!kde_overrideStyle.isEmpty()) { 00931 const QLatin1String currentStyleName(qApp->style()->metaObject()->className()); 00932 if (0 != kde_overrideStyle.compare(currentStyleName, Qt::CaseInsensitive) && 00933 0 != (QString(kde_overrideStyle + QLatin1String("Style"))).compare(currentStyleName, Qt::CaseInsensitive)) { 00934 qApp->setStyle(kde_overrideStyle); 00935 } 00936 } else { 00937 emit q->kdisplayStyleChanged(); 00938 } 00939 #else 00940 const QLatin1String currentStyleName(qApp->style()->metaObject()->className()); 00941 00942 if (kde_overrideStyle.isEmpty()) { 00943 const QString &defaultStyle = KStyle::defaultStyle(); 00944 const KConfigGroup pConfig(KGlobal::config(), "General"); 00945 const QString &styleStr = pConfig.readEntry("widgetStyle", defaultStyle); 00946 00947 if (styleStr.isEmpty() || 00948 // check whether we already use the correct style to return then 00949 // (workaround for Qt misbehavior to avoid double style initialization) 00950 0 == (QString(styleStr + QLatin1String("Style"))).compare(currentStyleName, Qt::CaseInsensitive) || 00951 0 == styleStr.compare(currentStyleName, Qt::CaseInsensitive)) { 00952 return; 00953 } 00954 00955 QStyle* sp = QStyleFactory::create( styleStr ); 00956 if (sp && currentStyleName == sp->metaObject()->className()) { 00957 delete sp; 00958 return; 00959 } 00960 00961 // If there is no default style available, try falling back any available style 00962 if ( !sp && styleStr != defaultStyle) 00963 sp = QStyleFactory::create( defaultStyle ); 00964 if ( !sp ) 00965 sp = QStyleFactory::create( QStyleFactory::keys().first() ); 00966 qApp->setStyle(sp); 00967 } else if (0 != kde_overrideStyle.compare(currentStyleName, Qt::CaseInsensitive) && 00968 0 != (QString(kde_overrideStyle + QLatin1String("Style"))).compare(currentStyleName, Qt::CaseInsensitive)) { 00969 qApp->setStyle(kde_overrideStyle); 00970 } 00971 emit q->kdisplayStyleChanged(); 00972 #endif //Q_WS_X11 00973 } 00974 00975 QPalette KGlobalSettings::createApplicationPalette(const KSharedConfigPtr &config) 00976 { 00977 return self()->d->createApplicationPalette(config); 00978 } 00979 00980 QPalette KGlobalSettings::createNewApplicationPalette(const KSharedConfigPtr &config) 00981 { 00982 return self()->d->createNewApplicationPalette(config); 00983 } 00984 00985 QPalette KGlobalSettings::Private::createApplicationPalette(const KSharedConfigPtr &config) 00986 { 00987 // This method is typically called once by KQGuiPlatformPlugin::palette and once again 00988 // by kdisplaySetPalette(), so we cache the palette to save time. 00989 if (config == KGlobal::config() && paletteCreated) { 00990 return applicationPalette; 00991 } 00992 return createNewApplicationPalette(config); 00993 } 00994 00995 QPalette KGlobalSettings::Private::createNewApplicationPalette(const KSharedConfigPtr &config) 00996 { 00997 QPalette palette; 00998 00999 QPalette::ColorGroup states[3] = { QPalette::Active, QPalette::Inactive, 01000 QPalette::Disabled }; 01001 01002 // TT thinks tooltips shouldn't use active, so we use our active colors for all states 01003 KColorScheme schemeTooltip(QPalette::Active, KColorScheme::Tooltip, config); 01004 01005 for ( int i = 0; i < 3 ; i++ ) { 01006 QPalette::ColorGroup state = states[i]; 01007 KColorScheme schemeView(state, KColorScheme::View, config); 01008 KColorScheme schemeWindow(state, KColorScheme::Window, config); 01009 KColorScheme schemeButton(state, KColorScheme::Button, config); 01010 KColorScheme schemeSelection(state, KColorScheme::Selection, config); 01011 01012 palette.setBrush( state, QPalette::WindowText, schemeWindow.foreground() ); 01013 palette.setBrush( state, QPalette::Window, schemeWindow.background() ); 01014 palette.setBrush( state, QPalette::Base, schemeView.background() ); 01015 palette.setBrush( state, QPalette::Text, schemeView.foreground() ); 01016 palette.setBrush( state, QPalette::Button, schemeButton.background() ); 01017 palette.setBrush( state, QPalette::ButtonText, schemeButton.foreground() ); 01018 palette.setBrush( state, QPalette::Highlight, schemeSelection.background() ); 01019 palette.setBrush( state, QPalette::HighlightedText, schemeSelection.foreground() ); 01020 palette.setBrush( state, QPalette::ToolTipBase, schemeTooltip.background() ); 01021 palette.setBrush( state, QPalette::ToolTipText, schemeTooltip.foreground() ); 01022 01023 palette.setColor( state, QPalette::Light, schemeWindow.shade( KColorScheme::LightShade ) ); 01024 palette.setColor( state, QPalette::Midlight, schemeWindow.shade( KColorScheme::MidlightShade ) ); 01025 palette.setColor( state, QPalette::Mid, schemeWindow.shade( KColorScheme::MidShade ) ); 01026 palette.setColor( state, QPalette::Dark, schemeWindow.shade( KColorScheme::DarkShade ) ); 01027 palette.setColor( state, QPalette::Shadow, schemeWindow.shade( KColorScheme::ShadowShade ) ); 01028 01029 palette.setBrush( state, QPalette::AlternateBase, schemeView.background( KColorScheme::AlternateBackground) ); 01030 palette.setBrush( state, QPalette::Link, schemeView.foreground( KColorScheme::LinkText ) ); 01031 palette.setBrush( state, QPalette::LinkVisited, schemeView.foreground( KColorScheme::VisitedText ) ); 01032 } 01033 01034 if (config == KGlobal::config()) { 01035 paletteCreated = true; 01036 applicationPalette = palette; 01037 } 01038 01039 return palette; 01040 } 01041 01042 void KGlobalSettings::Private::kdisplaySetPalette() 01043 { 01044 #if !defined(Q_WS_MAEMO_5) && !defined(Q_OS_WINCE) && !defined(MEEGO_EDITION_HARMATTAN) 01045 if (!kdeFullSession) { 01046 return; 01047 } 01048 01049 if (qApp->type() == QApplication::GuiClient) { 01050 QApplication::setPalette( q->createApplicationPalette() ); 01051 } 01052 emit q->kdisplayPaletteChanged(); 01053 emit q->appearanceChanged(); 01054 #endif 01055 } 01056 01057 01058 void KGlobalSettings::Private::kdisplaySetFont() 01059 { 01060 #if !defined(Q_WS_MAEMO_5) && !defined(Q_OS_WINCE) && !defined(MEEGO_EDITION_HARMATTAN) 01061 if (!kdeFullSession) { 01062 return; 01063 } 01064 01065 if (qApp->type() == QApplication::GuiClient) { 01066 KGlobalSettingsData* data = KGlobalSettingsData::self(); 01067 01068 QApplication::setFont( data->font(KGlobalSettingsData::GeneralFont) ); 01069 const QFont menuFont = data->font( KGlobalSettingsData::MenuFont ); 01070 QApplication::setFont( menuFont, "QMenuBar" ); 01071 QApplication::setFont( menuFont, "QMenu" ); 01072 QApplication::setFont( menuFont, "KPopupTitle" ); 01073 QApplication::setFont( data->font(KGlobalSettingsData::ToolbarFont), "QToolBar" ); 01074 } 01075 emit q->kdisplayFontChanged(); 01076 emit q->appearanceChanged(); 01077 #endif 01078 } 01079 01080 01081 void KGlobalSettings::Private::kdisplaySetStyle() 01082 { 01083 if (qApp->type() == QApplication::GuiClient) { 01084 applyGUIStyle(); 01085 01086 // Reread palette from config file. 01087 kdisplaySetPalette(); 01088 } 01089 } 01090 01091 01092 void KGlobalSettings::Private::reloadStyleSettings() 01093 { 01094 KConfigGroup g( KGlobal::config(), "KDE-Global GUI Settings" ); 01095 01096 // Asking for hasKey we do not ask for graphicEffectsLevelDefault() that can 01097 // contain some very slow code. If we can save that time, do it. (ereslibre) 01098 01099 if (g.hasKey("GraphicEffectsLevel")) { 01100 _graphicEffects = ((GraphicEffects) g.readEntry("GraphicEffectsLevel", QVariant((int) NoEffects)).toInt()); 01101 01102 return; 01103 } 01104 01105 _graphicEffects = KGlobalSettings::graphicEffectsLevelDefault(); 01106 } 01107 01108 01109 void KGlobalSettings::Private::applyCursorTheme() 01110 { 01111 #if defined(Q_WS_X11) && defined(HAVE_XCURSOR) 01112 KConfig config("kcminputrc"); 01113 KConfigGroup g(&config, "Mouse"); 01114 01115 QString theme = g.readEntry("cursorTheme", QString()); 01116 int size = g.readEntry("cursorSize", -1); 01117 01118 // Default cursor size is 16 points 01119 if (size == -1) 01120 { 01121 QApplication *app = static_cast<QApplication*>(QApplication::instance()); 01122 size = app->desktop()->screen(0)->logicalDpiY() * 16 / 72; 01123 } 01124 01125 // Note that in X11R7.1 and earlier, calling XcursorSetTheme() 01126 // with a NULL theme would cause Xcursor to use "default", but 01127 // in 7.2 and later it will cause it to revert to the theme that 01128 // was configured when the application was started. 01129 XcursorSetTheme(QX11Info::display(), theme.isNull() ? 01130 "default" : QFile::encodeName(theme)); 01131 XcursorSetDefaultSize(QX11Info::display(), size); 01132 01133 emit q->cursorChanged(); 01134 #endif 01135 } 01136 01137 01138 void KGlobalSettings::Private::propagateQtSettings() 01139 { 01140 KConfigGroup cg( KGlobal::config(), "KDE" ); 01141 #ifndef Q_WS_WIN 01142 int num = cg.readEntry("CursorBlinkRate", QApplication::cursorFlashTime()); 01143 if ((num != 0) && (num < 200)) 01144 num = 200; 01145 if (num > 2000) 01146 num = 2000; 01147 QApplication::setCursorFlashTime(num); 01148 #else 01149 int num; 01150 #endif 01151 num = cg.readEntry("DoubleClickInterval", QApplication::doubleClickInterval()); 01152 QApplication::setDoubleClickInterval(num); 01153 num = cg.readEntry("StartDragTime", QApplication::startDragTime()); 01154 QApplication::setStartDragTime(num); 01155 num = cg.readEntry("StartDragDist", QApplication::startDragDistance()); 01156 QApplication::setStartDragDistance(num); 01157 num = cg.readEntry("WheelScrollLines", QApplication::wheelScrollLines()); 01158 QApplication::setWheelScrollLines(num); 01159 bool showIcons = cg.readEntry("ShowIconsInMenuItems", !QApplication::testAttribute(Qt::AA_DontShowIconsInMenus)); 01160 QApplication::setAttribute(Qt::AA_DontShowIconsInMenus, !showIcons); 01161 01162 // KDE5: this seems fairly pointless 01163 emit q->settingsChanged(SETTINGS_QT); 01164 } 01165 01166 #include "kglobalsettings.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2019 The KDE developers.
Generated on Mon Jan 21 2019 12:32:39 by doxygen 1.7.5.1 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2019 The KDE developers.
Generated on Mon Jan 21 2019 12:32:39 by doxygen 1.7.5.1 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.