• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • Contact Us
 

KHTML

khtml_settings.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE project
00002    Copyright (C) 1999 David Faure <faure@kde.org>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
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 "khtml_settings.h"
00021 #include "khtmldefaults.h"
00022 
00023 #include <kconfig.h>
00024 #include <kconfiggroup.h>
00025 #include <kdebug.h>
00026 #include <kglobal.h>
00027 #include <kglobalsettings.h>
00028 #include <klocale.h>
00029 #include <kmessagebox.h>
00030 #include <khtml_filter_p.h>
00031 #include <kstandarddirs.h>
00032 #include <kjob.h>
00033 #include <kio/job.h>
00034 
00035 #include <QFile>
00036 #include <QFileInfo>
00037 #include <QtGui/QFontDatabase>
00038 #include <QByteArray>
00039 
00044 struct KPerDomainSettings {
00045     bool m_bEnableJava : 1;
00046     bool m_bEnableJavaScript : 1;
00047     bool m_bEnablePlugins : 1;
00048     // don't forget to maintain the bitfields as the enums grow
00049     KHTMLSettings::KJSWindowOpenPolicy m_windowOpenPolicy : 2;
00050     KHTMLSettings::KJSWindowStatusPolicy m_windowStatusPolicy : 1;
00051     KHTMLSettings::KJSWindowFocusPolicy m_windowFocusPolicy : 1;
00052     KHTMLSettings::KJSWindowMovePolicy m_windowMovePolicy : 1;
00053     KHTMLSettings::KJSWindowResizePolicy m_windowResizePolicy : 1;
00054 
00055 #ifdef DEBUG_SETTINGS
00056     void dump(const QString &infix = QString()) const {
00057       kDebug() << "KPerDomainSettings " << infix << " @" << this << ":";
00058       kDebug() << "  m_bEnableJava: " << m_bEnableJava;
00059       kDebug() << "  m_bEnableJavaScript: " << m_bEnableJavaScript;
00060       kDebug() << "  m_bEnablePlugins: " << m_bEnablePlugins;
00061       kDebug() << "  m_windowOpenPolicy: " << m_windowOpenPolicy;
00062       kDebug() << "  m_windowStatusPolicy: " << m_windowStatusPolicy;
00063       kDebug() << "  m_windowFocusPolicy: " << m_windowFocusPolicy;
00064       kDebug() << "  m_windowMovePolicy: " << m_windowMovePolicy;
00065       kDebug() << "  m_windowResizePolicy: " << m_windowResizePolicy;
00066     }
00067 #endif
00068 };
00069 
00070 QString *KHTMLSettings::avFamilies = 0;
00071 typedef QMap<QString,KPerDomainSettings> PolicyMap;
00072 
00073 // The "struct" that contains all the data. Must be copiable (no pointers).
00074 class KHTMLSettingsData
00075 {
00076 public:
00077     bool m_bChangeCursor : 1;
00078     bool m_bOpenMiddleClick : 1;
00079     bool m_underlineLink : 1;
00080     bool m_hoverLink : 1;
00081     bool m_bEnableJavaScriptDebug : 1;
00082     bool m_bEnableJavaScriptErrorReporting : 1;
00083     bool enforceCharset : 1;
00084     bool m_bAutoLoadImages : 1;
00085     bool m_bUnfinishedImageFrame : 1;
00086     bool m_formCompletionEnabled : 1;
00087     bool m_autoDelayedActionsEnabled : 1;
00088     bool m_jsErrorsEnabled : 1;
00089     bool m_follow_system_colors : 1;
00090     bool m_allowTabulation : 1;
00091     bool m_autoSpellCheck : 1;
00092     bool m_adFilterEnabled : 1;
00093     bool m_hideAdsEnabled : 1;
00094     bool m_jsPopupBlockerPassivePopup : 1;
00095     bool m_accessKeysEnabled : 1;
00096 
00097     // the virtual global "domain"
00098     KPerDomainSettings global;
00099 
00100     int m_fontSize;
00101     int m_minFontSize;
00102     int m_maxFormCompletionItems;
00103     KHTMLSettings::KAnimationAdvice m_showAnimations;
00104     KHTMLSettings::KSmoothScrollingMode m_smoothScrolling;
00105     KHTMLSettings::KDNSPrefetch m_dnsPrefetch;
00106 
00107     QString m_encoding;
00108     QString m_userSheet;
00109 
00110     QColor m_textColor;
00111     QColor m_baseColor;
00112     QColor m_linkColor;
00113     QColor m_vLinkColor;
00114 
00115     PolicyMap domainPolicy;
00116     QStringList fonts;
00117     QStringList defaultFonts;
00118 
00119     khtml::FilterSet adBlackList;
00120     khtml::FilterSet adWhiteList;
00121     QList< QPair< QString, QChar > > m_fallbackAccessKeysAssignments;
00122 };
00123 
00124 class KHTMLSettingsPrivate : public QObject, public KHTMLSettingsData
00125 {
00126     Q_OBJECT
00127 public:
00128 
00129     void adblockFilterLoadList(const QString& filename)
00130     {
00131         kDebug(6000) << "Loading filter list from" << filename;
00133         QFile file(filename);
00134         if (file.open(QIODevice::ReadOnly)) {
00135             QTextStream ts(&file);
00136             QString line = ts.readLine();
00137 #ifndef NDEBUG /// only count when compiled for debugging
00138             int whiteCounter = 0, blackCounter = 0;
00139 #endif // NDEBUG
00140             while (!line.isEmpty()) {
00142                 if (line.startsWith(QLatin1String("@@")))
00143                 {
00144 #ifndef NDEBUG
00145                     ++whiteCounter;
00146 #endif // NDEBUG
00147                     adWhiteList.addFilter(line);
00148                 }
00149                 else
00150                 {
00151 #ifndef NDEBUG
00152                     ++blackCounter;
00153 #endif // NDEBUG
00154                     adBlackList.addFilter(line);
00155                 }
00156 
00157                 line = ts.readLine();
00158             }
00159             file.close();
00160 
00161 #ifndef NDEBUG
00162             kDebug(6000) << "Filter list loaded" << whiteCounter << "white list entries and" << blackCounter << "black list entries";
00163 #endif // NDEBUG
00164         }
00165     }
00166 
00167 public slots:
00168     void adblockFilterResult(KJob *job)
00169     {
00170       KIO::StoredTransferJob *tJob = qobject_cast<KIO::StoredTransferJob*>(job);
00171       Q_ASSERT(tJob);
00172 
00173       if ( job->error() == KJob::NoError )
00174       {
00175           const QByteArray byteArray = tJob->data();
00176           const QString localFileName = tJob->property( "khtmlsettings_adBlock_filename" ).toString();
00177 
00178           QFile file(localFileName);
00179           if ( file.open(QFile::WriteOnly) )
00180           {
00181               bool success = file.write(byteArray) == byteArray.size();
00182               file.close();
00183               if ( success )
00184                   adblockFilterLoadList(localFileName);
00185               else
00186                   kDebug(6000) << "Could not write" << byteArray.size() << "to file" << localFileName;
00187           }
00188           else
00189               kDebug(6000) << "Cannot open file" << localFileName << "for filter list";
00190       }
00191       else
00192           kDebug(6000) << "Downloading" << tJob->url() << "failed with message:" << job->errorText();
00193   }
00194 };
00195 
00196 
00200 static KPerDomainSettings &setup_per_domain_policy(
00201                 KHTMLSettingsPrivate* const d,
00202                 const QString &domain) {
00203   if (domain.isEmpty()) {
00204     kWarning(6000) << "setup_per_domain_policy: domain is empty";
00205   }
00206   const QString ldomain = domain.toLower();
00207   PolicyMap::iterator it = d->domainPolicy.find(ldomain);
00208   if (it == d->domainPolicy.end()) {
00209     // simply copy global domain settings (they should have been initialized
00210     // by this time)
00211     it = d->domainPolicy.insert(ldomain,d->global);
00212   }
00213   return *it;
00214 }
00215 
00216 
00217 KHTMLSettings::KJavaScriptAdvice KHTMLSettings::strToAdvice(const QString& _str)
00218 {
00219   KJavaScriptAdvice ret = KJavaScriptDunno;
00220 
00221   if (_str.isNull())
00222         ret = KJavaScriptDunno;
00223 
00224   if (_str.toLower() == QLatin1String("accept"))
00225         ret = KJavaScriptAccept;
00226   else if (_str.toLower() == QLatin1String("reject"))
00227         ret = KJavaScriptReject;
00228 
00229   return ret;
00230 }
00231 
00232 const char* KHTMLSettings::adviceToStr(KJavaScriptAdvice _advice)
00233 {
00234     switch( _advice ) {
00235     case KJavaScriptAccept: return I18N_NOOP("Accept");
00236     case KJavaScriptReject: return I18N_NOOP("Reject");
00237     default: return 0;
00238     }
00239         return 0;
00240 }
00241 
00242 
00243 void KHTMLSettings::splitDomainAdvice(const QString& configStr, QString &domain,
00244                                       KJavaScriptAdvice &javaAdvice, KJavaScriptAdvice& javaScriptAdvice)
00245 {
00246     QString tmp(configStr);
00247     int splitIndex = tmp.indexOf(':');
00248     if ( splitIndex == -1)
00249     {
00250         domain = configStr.toLower();
00251         javaAdvice = KJavaScriptDunno;
00252         javaScriptAdvice = KJavaScriptDunno;
00253     }
00254     else
00255     {
00256         domain = tmp.left(splitIndex).toLower();
00257         QString adviceString = tmp.mid( splitIndex+1, tmp.length() );
00258         int splitIndex2 = adviceString.indexOf( ':' );
00259         if( splitIndex2 == -1 ) {
00260             // Java advice only
00261             javaAdvice = strToAdvice( adviceString );
00262             javaScriptAdvice = KJavaScriptDunno;
00263         } else {
00264             // Java and JavaScript advice
00265             javaAdvice = strToAdvice( adviceString.left( splitIndex2 ) );
00266             javaScriptAdvice = strToAdvice( adviceString.mid( splitIndex2+1,
00267                                                               adviceString.length() ) );
00268         }
00269     }
00270 }
00271 
00272 void KHTMLSettings::readDomainSettings(const KConfigGroup &config, bool reset,
00273     bool global, KPerDomainSettings &pd_settings) {
00274   QString jsPrefix = global ? QString()
00275                 : QString::fromLatin1("javascript.");
00276   QString javaPrefix = global ? QString()
00277                 : QString::fromLatin1("java.");
00278   QString pluginsPrefix = global ? QString()
00279                 : QString::fromLatin1("plugins.");
00280 
00281   // The setting for Java
00282   QString key = javaPrefix + QLatin1String("EnableJava");
00283   if ( (global && reset) || config.hasKey( key ) )
00284     pd_settings.m_bEnableJava = config.readEntry( key, false );
00285   else if ( !global )
00286     pd_settings.m_bEnableJava = d->global.m_bEnableJava;
00287 
00288   // The setting for Plugins
00289   key = pluginsPrefix + QLatin1String("EnablePlugins");
00290   if ( (global && reset) || config.hasKey( key ) )
00291     pd_settings.m_bEnablePlugins = config.readEntry( key, true );
00292   else if ( !global )
00293     pd_settings.m_bEnablePlugins = d->global.m_bEnablePlugins;
00294 
00295   // The setting for JavaScript
00296   key = jsPrefix + QLatin1String("EnableJavaScript");
00297   if ( (global && reset) || config.hasKey( key ) )
00298     pd_settings.m_bEnableJavaScript = config.readEntry( key, true );
00299   else if ( !global )
00300     pd_settings.m_bEnableJavaScript = d->global.m_bEnableJavaScript;
00301 
00302   // window property policies
00303   key = jsPrefix + QLatin1String("WindowOpenPolicy");
00304   if ( (global && reset) || config.hasKey( key ) )
00305     pd_settings.m_windowOpenPolicy = (KJSWindowOpenPolicy)
00306             config.readEntry( key, uint(KJSWindowOpenSmart) );
00307   else if ( !global )
00308     pd_settings.m_windowOpenPolicy = d->global.m_windowOpenPolicy;
00309 
00310   key = jsPrefix + QLatin1String("WindowMovePolicy");
00311   if ( (global && reset) || config.hasKey( key ) )
00312     pd_settings.m_windowMovePolicy = (KJSWindowMovePolicy)
00313             config.readEntry( key, uint(KJSWindowMoveAllow) );
00314   else if ( !global )
00315     pd_settings.m_windowMovePolicy = d->global.m_windowMovePolicy;
00316 
00317   key = jsPrefix + QLatin1String("WindowResizePolicy");
00318   if ( (global && reset) || config.hasKey( key ) )
00319     pd_settings.m_windowResizePolicy = (KJSWindowResizePolicy)
00320             config.readEntry( key, uint(KJSWindowResizeAllow) );
00321   else if ( !global )
00322     pd_settings.m_windowResizePolicy = d->global.m_windowResizePolicy;
00323 
00324   key = jsPrefix + QLatin1String("WindowStatusPolicy");
00325   if ( (global && reset) || config.hasKey( key ) )
00326     pd_settings.m_windowStatusPolicy = (KJSWindowStatusPolicy)
00327             config.readEntry( key, uint(KJSWindowStatusAllow) );
00328   else if ( !global )
00329     pd_settings.m_windowStatusPolicy = d->global.m_windowStatusPolicy;
00330 
00331   key = jsPrefix + QLatin1String("WindowFocusPolicy");
00332   if ( (global && reset) || config.hasKey( key ) )
00333     pd_settings.m_windowFocusPolicy = (KJSWindowFocusPolicy)
00334             config.readEntry( key, uint(KJSWindowFocusAllow) );
00335   else if ( !global )
00336     pd_settings.m_windowFocusPolicy = d->global.m_windowFocusPolicy;
00337 
00338 }
00339 
00340 
00341 KHTMLSettings::KHTMLSettings()
00342     :d (new KHTMLSettingsPrivate())
00343 {
00344   init();
00345 }
00346 
00347 KHTMLSettings::KHTMLSettings(const KHTMLSettings &other)
00348     :d(new KHTMLSettingsPrivate())
00349 {
00350   KHTMLSettingsData* data = d;
00351   *data = *other.d;
00352 }
00353 
00354 KHTMLSettings::~KHTMLSettings()
00355 {
00356   delete d;
00357 }
00358 
00359 bool KHTMLSettings::changeCursor() const
00360 {
00361   return d->m_bChangeCursor;
00362 }
00363 
00364 bool KHTMLSettings::underlineLink() const
00365 {
00366   return d->m_underlineLink;
00367 }
00368 
00369 bool KHTMLSettings::hoverLink() const
00370 {
00371   return d->m_hoverLink;
00372 }
00373 
00374 void KHTMLSettings::init()
00375 {
00376   KConfig global( "khtmlrc", KConfig::NoGlobals );
00377   init( &global, true );
00378 
00379   KSharedConfig::Ptr local = KGlobal::config();
00380   if ( !local )
00381     return;
00382 
00383   init( local.data(), false );
00384 }
00385 
00386 void KHTMLSettings::init( KConfig * config, bool reset )
00387 {
00388   KConfigGroup cg( config, "MainView Settings" );
00389   if (reset || cg.exists() )
00390   {
00391     if ( reset || cg.hasKey( "OpenMiddleClick" ) )
00392         d->m_bOpenMiddleClick = cg.readEntry( "OpenMiddleClick", true );
00393   }
00394 
00395   KConfigGroup cgAccess(config,"Access Keys" );
00396   if (reset || cgAccess.exists() ) {
00397       d->m_accessKeysEnabled = cgAccess.readEntry( "Enabled", true );
00398   }
00399 
00400   KConfigGroup cgFilter( config, "Filter Settings" );
00401 
00402   if (reset || cgFilter.exists() )
00403   {
00404       d->m_adFilterEnabled = cgFilter.readEntry("Enabled", false);
00405       d->m_hideAdsEnabled = cgFilter.readEntry("Shrink", false);
00406 
00407       d->adBlackList.clear();
00408       d->adWhiteList.clear();
00409 
00411       int htmlFilterListMaxAgeDays = cgFilter.readEntry(QString("HTMLFilterListMaxAgeDays")).toInt();
00412       if (htmlFilterListMaxAgeDays < 1)
00413           htmlFilterListMaxAgeDays = 1;
00414 
00415       QMap<QString,QString> entryMap = cgFilter.entryMap();
00416       QMap<QString,QString>::ConstIterator it;
00417       for( it = entryMap.constBegin(); it != entryMap.constEnd(); ++it )
00418       {
00419           int id = -1;
00420           QString name = it.key();
00421           QString url = it.value();
00422 
00423           if (name.startsWith("Filter"))
00424           {
00425               if (url.startsWith(QLatin1String("@@")))
00426                   d->adWhiteList.addFilter(url);
00427               else
00428                   d->adBlackList.addFilter(url);
00429           } else if (name.startsWith("HTMLFilterListName-") && (id = name.mid(19).toInt()) > 0)
00430           {
00432               bool filterEnabled = cgFilter.readEntry(QString("HTMLFilterListEnabled-").append(QString::number(id))) != QLatin1String("false");
00433 
00435               KUrl url(cgFilter.readEntry(QString("HTMLFilterListURL-").append(QString::number(id))));
00436 
00437               if (filterEnabled && url.isValid()) {
00439                   QString localFile = cgFilter.readEntry(QString("HTMLFilterListLocalFilename-").append(QString::number(id)));
00440                   localFile = KStandardDirs::locateLocal("data", "khtml/" + localFile);
00441 
00443                   QFileInfo fileInfo(localFile);
00444 
00446                   if (fileInfo.exists())
00447                       d->adblockFilterLoadList( localFile );
00448 
00450                   if (!fileInfo.exists() || fileInfo.lastModified().daysTo(QDateTime::currentDateTime()) > htmlFilterListMaxAgeDays)
00451                   {
00453                       kDebug(6000) << "Asynchronously fetching filter list from" << url << "to" << localFile;
00454 
00455                       KIO::StoredTransferJob *job = KIO::storedGet( url, KIO::Reload, KIO::HideProgressInfo );
00456                       QObject::connect( job, SIGNAL( result(KJob *) ), d, SLOT( adblockFilterResult(KJob *) ) );
00458                       job->setProperty("khtmlsettings_adBlock_filename", localFile);
00459                   }
00460               }
00461           }
00462       }
00463   }
00464 
00465   KConfigGroup cgHtml( config, "HTML Settings" );
00466   if (reset || cgHtml.exists() )
00467   {
00468     // Fonts and colors
00469     if( reset ) {
00470         d->defaultFonts = QStringList();
00471         d->defaultFonts.append( cgHtml.readEntry( "StandardFont", KGlobalSettings::generalFont().family() ) );
00472         d->defaultFonts.append( cgHtml.readEntry( "FixedFont", KGlobalSettings::fixedFont().family() ) );
00473         d->defaultFonts.append( cgHtml.readEntry( "SerifFont", HTML_DEFAULT_VIEW_SERIF_FONT ) );
00474         d->defaultFonts.append( cgHtml.readEntry( "SansSerifFont", HTML_DEFAULT_VIEW_SANSSERIF_FONT ) );
00475         d->defaultFonts.append( cgHtml.readEntry( "CursiveFont", HTML_DEFAULT_VIEW_CURSIVE_FONT ) );
00476         d->defaultFonts.append( cgHtml.readEntry( "FantasyFont", HTML_DEFAULT_VIEW_FANTASY_FONT ) );
00477         d->defaultFonts.append( QString( "0" ) ); // font size adjustment
00478     }
00479 
00480     if ( reset || cgHtml.hasKey( "MinimumFontSize" ) )
00481         d->m_minFontSize = cgHtml.readEntry( "MinimumFontSize", HTML_DEFAULT_MIN_FONT_SIZE );
00482 
00483     if ( reset || cgHtml.hasKey( "MediumFontSize" ) )
00484         d->m_fontSize = cgHtml.readEntry( "MediumFontSize", 12 );
00485 
00486     d->fonts = cgHtml.readEntry( "Fonts", QStringList() );
00487 
00488     if ( reset || cgHtml.hasKey( "DefaultEncoding" ) )
00489         d->m_encoding = cgHtml.readEntry( "DefaultEncoding", "" );
00490 
00491     if ( reset || cgHtml.hasKey( "EnforceDefaultCharset" ) )
00492         d->enforceCharset = cgHtml.readEntry( "EnforceDefaultCharset", false );
00493 
00494     // Behavior
00495     if ( reset || cgHtml.hasKey( "ChangeCursor" ) )
00496         d->m_bChangeCursor = cgHtml.readEntry( "ChangeCursor", KDE_DEFAULT_CHANGECURSOR );
00497 
00498     if ( reset || cgHtml.hasKey("UnderlineLinks") )
00499         d->m_underlineLink = cgHtml.readEntry( "UnderlineLinks", true );
00500 
00501     if ( reset || cgHtml.hasKey( "HoverLinks" ) )
00502     {
00503         if ( (d->m_hoverLink = cgHtml.readEntry( "HoverLinks", false )))
00504             d->m_underlineLink = false;
00505     }
00506 
00507     if ( reset || cgHtml.hasKey( "AllowTabulation" ) )
00508         d->m_allowTabulation = cgHtml.readEntry( "AllowTabulation", false );
00509 
00510     if ( reset || cgHtml.hasKey( "AutoSpellCheck" ) )
00511         d->m_autoSpellCheck = cgHtml.readEntry( "AutoSpellCheck", true );
00512 
00513     // Other
00514     if ( reset || cgHtml.hasKey( "AutoLoadImages" ) )
00515       d->m_bAutoLoadImages = cgHtml.readEntry( "AutoLoadImages", true );
00516 
00517     if ( reset || cgHtml.hasKey( "UnfinishedImageFrame" ) )
00518       d->m_bUnfinishedImageFrame = cgHtml.readEntry( "UnfinishedImageFrame", true );
00519 
00520     if ( reset || cgHtml.hasKey( "ShowAnimations" ) )
00521     {
00522       QString value = cgHtml.readEntry( "ShowAnimations").toLower();
00523       if (value == "disabled")
00524          d->m_showAnimations = KAnimationDisabled;
00525       else if (value == "looponce")
00526          d->m_showAnimations = KAnimationLoopOnce;
00527       else
00528          d->m_showAnimations = KAnimationEnabled;
00529     }
00530 
00531     if ( reset || cgHtml.hasKey( "SmoothScrolling" ) )
00532     {
00533       QString value = cgHtml.readEntry( "SmoothScrolling", "whenefficient" ).toLower();
00534       if (value == "disabled")
00535          d->m_smoothScrolling = KSmoothScrollingDisabled;
00536       else if (value == "whenefficient")
00537          d->m_smoothScrolling = KSmoothScrollingWhenEfficient;
00538       else
00539          d->m_smoothScrolling = KSmoothScrollingEnabled;
00540     }
00541 
00542     if ( reset || cgHtml.hasKey( "DNSPrefetch" ) )
00543     {
00544       // Enabled, Disabled, OnlyWWWAndSLD
00545       QString value = cgHtml.readEntry( "DNSPrefetch", "Enabled" ).toLower();
00546       if (value == "enabled")
00547          d->m_dnsPrefetch = KDNSPrefetchEnabled;
00548       else if (value == "onlywwwandsld")
00549          d->m_dnsPrefetch = KDNSPrefetchOnlyWWWAndSLD;
00550       else
00551          d->m_dnsPrefetch = KDNSPrefetchDisabled;
00552     }
00553 
00554     if ( cgHtml.readEntry( "UserStyleSheetEnabled", false ) == true ) {
00555         if ( reset || cgHtml.hasKey( "UserStyleSheet" ) )
00556             d->m_userSheet = cgHtml.readEntry( "UserStyleSheet", "" );
00557     }
00558 
00559     d->m_formCompletionEnabled = cgHtml.readEntry("FormCompletion", true);
00560     d->m_maxFormCompletionItems = cgHtml.readEntry("MaxFormCompletionItems", 10);
00561     d->m_autoDelayedActionsEnabled = cgHtml.readEntry ("AutoDelayedActions", true);
00562     d->m_jsErrorsEnabled = cgHtml.readEntry("ReportJSErrors", true);
00563     const QStringList accesskeys = cgHtml.readEntry("FallbackAccessKeysAssignments", QStringList());
00564     d->m_fallbackAccessKeysAssignments.clear();
00565     for( QStringList::ConstIterator it = accesskeys.begin(); it != accesskeys.end(); ++it )
00566         if( (*it).length() > 2 && (*it)[ 1 ] == ':' )
00567             d->m_fallbackAccessKeysAssignments.append( qMakePair( (*it).mid( 2 ), (*it)[ 0 ] ));
00568   }
00569 
00570   // Colors
00571   //In which group ?????
00572   if ( reset || cg.hasKey( "FollowSystemColors" ) )
00573       d->m_follow_system_colors = cg.readEntry( "FollowSystemColors", false );
00574 
00575   KConfigGroup cgGeneral( config, "General" );
00576   if ( reset || cgGeneral.exists( ) )
00577   {
00578     if ( reset || cgGeneral.hasKey( "foreground" ) ) {
00579       QColor def(HTML_DEFAULT_TXT_COLOR);
00580       d->m_textColor = cgGeneral.readEntry( "foreground", def );
00581     }
00582 
00583     if ( reset || cgGeneral.hasKey( "linkColor" ) ) {
00584       QColor def(HTML_DEFAULT_LNK_COLOR);
00585       d->m_linkColor = cgGeneral.readEntry( "linkColor", def );
00586     }
00587 
00588     if ( reset || cgGeneral.hasKey( "visitedLinkColor" ) ) {
00589       QColor def(HTML_DEFAULT_VLNK_COLOR);
00590       d->m_vLinkColor = cgGeneral.readEntry( "visitedLinkColor", def);
00591     }
00592 
00593     if ( reset || cgGeneral.hasKey( "background" ) ) {
00594       QColor def(HTML_DEFAULT_BASE_COLOR);
00595       d->m_baseColor = cgGeneral.readEntry( "background", def);
00596     }
00597   }
00598 
00599   KConfigGroup cgJava( config, "Java/JavaScript Settings" );
00600   if( reset || cgJava.exists() )
00601   {
00602     // The global setting for JavaScript debugging
00603     // This is currently always enabled by default
00604     if ( reset || cgJava.hasKey( "EnableJavaScriptDebug" ) )
00605       d->m_bEnableJavaScriptDebug = cgJava.readEntry( "EnableJavaScriptDebug", false );
00606 
00607     // The global setting for JavaScript error reporting
00608     if ( reset || cgJava.hasKey( "ReportJavaScriptErrors" ) )
00609       d->m_bEnableJavaScriptErrorReporting = cgJava.readEntry( "ReportJavaScriptErrors", false );
00610 
00611     // The global setting for popup block passive popup
00612     if ( reset || cgJava.hasKey( "PopupBlockerPassivePopup" ) )
00613       d->m_jsPopupBlockerPassivePopup = cgJava.readEntry("PopupBlockerPassivePopup", true );
00614 
00615     // Read options from the global "domain"
00616     readDomainSettings(cgJava,reset,true,d->global);
00617 #ifdef DEBUG_SETTINGS
00618     d->global.dump("init global");
00619 #endif
00620 
00621     // The domain-specific settings.
00622 
00623     static const char *const domain_keys[] = {  // always keep order of keys
00624         "ECMADomains", "JavaDomains", "PluginDomains"
00625     };
00626     bool check_old_ecma_settings = true;
00627     bool check_old_java_settings = true;
00628     // merge all domains into one list
00629     QMap<QString,int> domainList;   // why can't Qt have a QSet?
00630     for (unsigned i = 0; i < sizeof domain_keys/sizeof domain_keys[0]; ++i) {
00631       if ( reset || cgJava.hasKey(domain_keys[i]) ) {
00632         if (i == 0) check_old_ecma_settings = false;
00633     else if (i == 1) check_old_java_settings = false;
00634         const QStringList dl = cgJava.readEntry( domain_keys[i], QStringList() );
00635     const QMap<QString,int>::Iterator notfound = domainList.end();
00636     QStringList::ConstIterator it = dl.begin();
00637     const QStringList::ConstIterator itEnd = dl.end();
00638     for (; it != itEnd; ++it) {
00639       const QString domain = (*it).toLower();
00640       QMap<QString,int>::Iterator pos = domainList.find(domain);
00641       if (pos == notfound) domainList.insert(domain,0);
00642     }/*next it*/
00643       }
00644     }/*next i*/
00645 
00646     if (reset)
00647       d->domainPolicy.clear();
00648 
00649     {
00650       QMap<QString,int>::ConstIterator it = domainList.constBegin();
00651       const QMap<QString,int>::ConstIterator itEnd = domainList.constEnd();
00652       for ( ; it != itEnd; ++it)
00653       {
00654         const QString domain = it.key();
00655         KConfigGroup cg( config, domain );
00656         readDomainSettings(cg,reset,false,d->domainPolicy[domain]);
00657 #ifdef DEBUG_SETTINGS
00658         d->domainPolicy[domain].dump("init "+domain);
00659 #endif
00660       }
00661     }
00662 
00663     bool check_old_java = true;
00664     if( ( reset || cgJava.hasKey( "JavaDomainSettings" ) )
00665         && check_old_java_settings )
00666     {
00667       check_old_java = false;
00668       const QStringList domainList = cgJava.readEntry( "JavaDomainSettings", QStringList() );
00669       QStringList::ConstIterator it = domainList.constBegin();
00670       const QStringList::ConstIterator itEnd = domainList.constEnd();
00671       for ( ; it != itEnd; ++it)
00672       {
00673         QString domain;
00674         KJavaScriptAdvice javaAdvice;
00675         KJavaScriptAdvice javaScriptAdvice;
00676         splitDomainAdvice(*it, domain, javaAdvice, javaScriptAdvice);
00677         setup_per_domain_policy(d,domain).m_bEnableJava =
00678         javaAdvice == KJavaScriptAccept;
00679 #ifdef DEBUG_SETTINGS
00680     setup_per_domain_policy(d,domain).dump("JavaDomainSettings 4 "+domain);
00681 #endif
00682       }
00683     }
00684 
00685     bool check_old_ecma = true;
00686     if( ( reset || cgJava.hasKey( "ECMADomainSettings" ) )
00687     && check_old_ecma_settings )
00688     {
00689       check_old_ecma = false;
00690       const QStringList domainList = cgJava.readEntry( "ECMADomainSettings", QStringList() );
00691       QStringList::ConstIterator it = domainList.constBegin();
00692       const QStringList::ConstIterator itEnd = domainList.constEnd();
00693       for ( ; it != itEnd; ++it)
00694       {
00695         QString domain;
00696         KJavaScriptAdvice javaAdvice;
00697         KJavaScriptAdvice javaScriptAdvice;
00698         splitDomainAdvice(*it, domain, javaAdvice, javaScriptAdvice);
00699         setup_per_domain_policy(d,domain).m_bEnableJavaScript =
00700             javaScriptAdvice == KJavaScriptAccept;
00701 #ifdef DEBUG_SETTINGS
00702     setup_per_domain_policy(d,domain).dump("ECMADomainSettings 4 "+domain);
00703 #endif
00704       }
00705     }
00706 
00707     if( ( reset || cgJava.hasKey( "JavaScriptDomainAdvice" ) )
00708              && ( check_old_java || check_old_ecma )
00709          && ( check_old_ecma_settings || check_old_java_settings ) )
00710     {
00711       const QStringList domainList = cgJava.readEntry( "JavaScriptDomainAdvice", QStringList() );
00712       QStringList::ConstIterator it = domainList.constBegin();
00713       const QStringList::ConstIterator itEnd = domainList.constEnd();
00714       for ( ; it != itEnd; ++it)
00715       {
00716         QString domain;
00717         KJavaScriptAdvice javaAdvice;
00718         KJavaScriptAdvice javaScriptAdvice;
00719         splitDomainAdvice(*it, domain, javaAdvice, javaScriptAdvice);
00720         if( check_old_java )
00721           setup_per_domain_policy(d,domain).m_bEnableJava =
00722             javaAdvice == KJavaScriptAccept;
00723         if( check_old_ecma )
00724           setup_per_domain_policy(d,domain).m_bEnableJavaScript =
00725             javaScriptAdvice == KJavaScriptAccept;
00726 #ifdef DEBUG_SETTINGS
00727     setup_per_domain_policy(d,domain).dump("JavaScriptDomainAdvice 4 "+domain);
00728 #endif
00729       }
00730 
00731       //save all the settings into the new keywords if they don't exist
00732 #if 0
00733       if( check_old_java )
00734       {
00735         QStringList domainConfig;
00736         PolicyMap::Iterator it;
00737         for( it = d->javaDomainPolicy.begin(); it != d->javaDomainPolicy.end(); ++it )
00738         {
00739           QByteArray javaPolicy = adviceToStr( it.value() );
00740           QByteArray javaScriptPolicy = adviceToStr( KJavaScriptDunno );
00741           domainConfig.append(QString::fromLatin1("%1:%2:%3").arg(it.key()).arg(javaPolicy).arg(javaScriptPolicy));
00742         }
00743         cg.writeEntry( "JavaDomainSettings", domainConfig );
00744       }
00745 
00746       if( check_old_ecma )
00747       {
00748         QStringList domainConfig;
00749         PolicyMap::Iterator it;
00750         for( it = d->javaScriptDomainPolicy.begin(); it != d->javaScriptDomainPolicy.end(); ++it )
00751         {
00752           QByteArray javaPolicy = adviceToStr( KJavaScriptDunno );
00753           QByteArray javaScriptPolicy = adviceToStr( it.value() );
00754           domainConfig.append(QString::fromLatin1("%1:%2:%3").arg(it.key()).arg(javaPolicy).arg(javaScriptPolicy));
00755         }
00756         cg.writeEntry( "ECMADomainSettings", domainConfig );
00757       }
00758 #endif
00759     }
00760   }
00761 }
00762 
00763 
00768 static const KPerDomainSettings &lookup_hostname_policy(
00769             const KHTMLSettingsPrivate* const d,
00770             const QString& hostname)
00771 {
00772 #ifdef DEBUG_SETTINGS
00773   kDebug() << "lookup_hostname_policy(" << hostname << ")";
00774 #endif
00775   if (hostname.isEmpty()) {
00776 #ifdef DEBUG_SETTINGS
00777     d->global.dump("global");
00778 #endif
00779     return d->global;
00780   }
00781 
00782   const PolicyMap::const_iterator notfound = d->domainPolicy.constEnd();
00783 
00784   // First check whether there is a perfect match.
00785   PolicyMap::const_iterator it = d->domainPolicy.find(hostname);
00786   if( it != notfound ) {
00787 #ifdef DEBUG_SETTINGS
00788     kDebug() << "perfect match";
00789     (*it).dump(hostname);
00790 #endif
00791     // yes, use it (unless dunno)
00792     return *it;
00793   }
00794 
00795   // Now, check for partial match.  Chop host from the left until
00796   // there's no dots left.
00797   QString host_part = hostname;
00798   int dot_idx = -1;
00799   while( (dot_idx = host_part.indexOf(QChar('.'))) >= 0 ) {
00800     host_part.remove(0,dot_idx);
00801     it = d->domainPolicy.find(host_part);
00802     Q_ASSERT(notfound == d->domainPolicy.end());
00803     if( it != notfound ) {
00804 #ifdef DEBUG_SETTINGS
00805       kDebug() << "partial match";
00806       (*it).dump(host_part);
00807 #endif
00808       return *it;
00809     }
00810     // assert(host_part[0] == QChar('.'));
00811     host_part.remove(0,1); // Chop off the dot.
00812   }
00813 
00814   // No domain-specific entry: use global domain
00815 #ifdef DEBUG_SETTINGS
00816   kDebug() << "no match";
00817   d->global.dump("global");
00818 #endif
00819   return d->global;
00820 }
00821 
00822 bool KHTMLSettings::isOpenMiddleClickEnabled()
00823 {
00824   return d->m_bOpenMiddleClick;
00825 }
00826 
00827 bool KHTMLSettings::isBackRightClickEnabled()
00828 {
00829   return false; // ## the feature moved to konqueror
00830 }
00831 
00832 bool KHTMLSettings::accessKeysEnabled() const
00833 {
00834     return d->m_accessKeysEnabled;
00835 }
00836 
00837 bool KHTMLSettings::isAdFilterEnabled() const
00838 {
00839     return d->m_adFilterEnabled;
00840 }
00841 
00842 bool KHTMLSettings::isHideAdsEnabled() const
00843 {
00844     return d->m_hideAdsEnabled;
00845 }
00846 
00847 bool KHTMLSettings::isAdFiltered( const QString &url ) const
00848 {
00849     if (d->m_adFilterEnabled)
00850     {
00851         if (!url.startsWith("data:"))
00852         {
00853             // Check the blacklist, and only if that matches, the whitelist
00854             return d->adBlackList.isUrlMatched(url) && !d->adWhiteList.isUrlMatched(url);
00855         }
00856     }
00857     return false;
00858 }
00859 
00860 QString KHTMLSettings::adFilteredBy( const QString &url, bool *isWhiteListed ) const
00861 {
00862     QString m = d->adWhiteList.urlMatchedBy(url);
00863     if (!m.isEmpty())
00864     {
00865         if (isWhiteListed != 0)
00866             *isWhiteListed = true;
00867         return (m);
00868     }
00869 
00870     m = d->adBlackList.urlMatchedBy(url);
00871     if (!m.isEmpty())
00872     {
00873         if (isWhiteListed != 0)
00874             *isWhiteListed = false;
00875         return (m);
00876     }
00877 
00878     return (QString());
00879 }
00880 
00881 void KHTMLSettings::addAdFilter( const QString &url )
00882 {
00883     KConfigGroup config = KSharedConfig::openConfig( "khtmlrc", KConfig::NoGlobals )->group( "Filter Settings" );
00884 
00885     QRegExp rx;
00886 
00887     // Try compiling to avoid invalid stuff. Only support the basic syntax here...
00888     // ### refactor somewhat
00889     if (url.length()>2 && url[0]=='/' && url[url.length()-1] == '/')
00890     {
00891         QString inside = url.mid(1, url.length()-2);
00892         rx.setPattern(inside);
00893     }
00894     else
00895     {
00896         rx.setPatternSyntax(QRegExp::Wildcard);
00897         rx.setPattern(url);
00898     }
00899 
00900     if (rx.isValid())
00901     {
00902         int last=config.readEntry("Count", 0);
00903         QString key = "Filter-" + QString::number(last);
00904         config.writeEntry(key, url);
00905         config.writeEntry("Count",last+1);
00906         config.sync();
00907         if (url.startsWith(QLatin1String("@@")))
00908              d->adWhiteList.addFilter(url);
00909         else
00910              d->adBlackList.addFilter(url);
00911     }
00912     else
00913     {
00914         KMessageBox::error(0,
00915                            rx.errorString(),
00916                            i18n("Filter error"));
00917     }
00918 }
00919 
00920 bool KHTMLSettings::isJavaEnabled( const QString& hostname ) const
00921 {
00922   return lookup_hostname_policy(d,hostname.toLower()).m_bEnableJava;
00923 }
00924 
00925 bool KHTMLSettings::isJavaScriptEnabled( const QString& hostname ) const
00926 {
00927   return lookup_hostname_policy(d,hostname.toLower()).m_bEnableJavaScript;
00928 }
00929 
00930 bool KHTMLSettings::isJavaScriptDebugEnabled( const QString& /*hostname*/ ) const
00931 {
00932   // debug setting is global for now, but could change in the future
00933   return d->m_bEnableJavaScriptDebug;
00934 }
00935 
00936 bool KHTMLSettings::isJavaScriptErrorReportingEnabled( const QString& /*hostname*/ ) const
00937 {
00938   // error reporting setting is global for now, but could change in the future
00939   return d->m_bEnableJavaScriptErrorReporting;
00940 }
00941 
00942 bool KHTMLSettings::isPluginsEnabled( const QString& hostname ) const
00943 {
00944   return lookup_hostname_policy(d,hostname.toLower()).m_bEnablePlugins;
00945 }
00946 
00947 KHTMLSettings::KJSWindowOpenPolicy KHTMLSettings::windowOpenPolicy(
00948                 const QString& hostname) const {
00949   return lookup_hostname_policy(d,hostname.toLower()).m_windowOpenPolicy;
00950 }
00951 
00952 KHTMLSettings::KJSWindowMovePolicy KHTMLSettings::windowMovePolicy(
00953                 const QString& hostname) const {
00954   return lookup_hostname_policy(d,hostname.toLower()).m_windowMovePolicy;
00955 }
00956 
00957 KHTMLSettings::KJSWindowResizePolicy KHTMLSettings::windowResizePolicy(
00958                 const QString& hostname) const {
00959   return lookup_hostname_policy(d,hostname.toLower()).m_windowResizePolicy;
00960 }
00961 
00962 KHTMLSettings::KJSWindowStatusPolicy KHTMLSettings::windowStatusPolicy(
00963                 const QString& hostname) const {
00964   return lookup_hostname_policy(d,hostname.toLower()).m_windowStatusPolicy;
00965 }
00966 
00967 KHTMLSettings::KJSWindowFocusPolicy KHTMLSettings::windowFocusPolicy(
00968                 const QString& hostname) const {
00969   return lookup_hostname_policy(d,hostname.toLower()).m_windowFocusPolicy;
00970 }
00971 
00972 int KHTMLSettings::mediumFontSize() const
00973 {
00974     return d->m_fontSize;
00975 }
00976 
00977 int KHTMLSettings::minFontSize() const
00978 {
00979   return d->m_minFontSize;
00980 }
00981 
00982 QString KHTMLSettings::settingsToCSS() const
00983 {
00984     // lets start with the link properties
00985     QString str = "a:link {\ncolor: ";
00986     str += d->m_linkColor.name();
00987     str += ';';
00988     if(d->m_underlineLink)
00989         str += "\ntext-decoration: underline;";
00990 
00991     if( d->m_bChangeCursor )
00992     {
00993         str += "\ncursor: pointer;";
00994         str += "\n}\ninput[type=image] { cursor: pointer;";
00995     }
00996     str += "\n}\n";
00997     str += "a:visited {\ncolor: ";
00998     str += d->m_vLinkColor.name();
00999     str += ';';
01000     if(d->m_underlineLink)
01001         str += "\ntext-decoration: underline;";
01002 
01003     if( d->m_bChangeCursor )
01004         str += "\ncursor: pointer;";
01005     str += "\n}\n";
01006 
01007     if(d->m_hoverLink)
01008         str += "a:link:hover, a:visited:hover { text-decoration: underline; }\n";
01009 
01010     return str;
01011 }
01012 
01013 const QString &KHTMLSettings::availableFamilies()
01014 {
01015     if ( !avFamilies ) {
01016         avFamilies = new QString;
01017         QFontDatabase db;
01018         QStringList families = db.families();
01019         QStringList s;
01020         QRegExp foundryExp(" \\[.+\\]");
01021 
01022         //remove foundry info
01023         QStringList::Iterator f = families.begin();
01024         const QStringList::Iterator fEnd = families.end();
01025 
01026         for ( ; f != fEnd; ++f ) {
01027                 (*f).replace( foundryExp, "");
01028                 if (!s.contains(*f))
01029                         s << *f;
01030         }
01031         s.sort();
01032 
01033         *avFamilies = ',' + s.join(",") + ',';
01034     }
01035 
01036   return *avFamilies;
01037 }
01038 
01039 QString KHTMLSettings::lookupFont(int i) const
01040 {
01041     QString font;
01042     if (d->fonts.count() > i)
01043        font = d->fonts[i];
01044     if (font.isEmpty())
01045         font = d->defaultFonts[i];
01046     return font;
01047 }
01048 
01049 QString KHTMLSettings::stdFontName() const
01050 {
01051     return lookupFont(0);
01052 }
01053 
01054 QString KHTMLSettings::fixedFontName() const
01055 {
01056     return lookupFont(1);
01057 }
01058 
01059 QString KHTMLSettings::serifFontName() const
01060 {
01061     return lookupFont(2);
01062 }
01063 
01064 QString KHTMLSettings::sansSerifFontName() const
01065 {
01066     return lookupFont(3);
01067 }
01068 
01069 QString KHTMLSettings::cursiveFontName() const
01070 {
01071     return lookupFont(4);
01072 }
01073 
01074 QString KHTMLSettings::fantasyFontName() const
01075 {
01076     return lookupFont(5);
01077 }
01078 
01079 void KHTMLSettings::setStdFontName(const QString &n)
01080 {
01081     while(d->fonts.count() <= 0)
01082         d->fonts.append(QString());
01083     d->fonts[0] = n;
01084 }
01085 
01086 void KHTMLSettings::setFixedFontName(const QString &n)
01087 {
01088     while(d->fonts.count() <= 1)
01089         d->fonts.append(QString());
01090     d->fonts[1] = n;
01091 }
01092 
01093 QString KHTMLSettings::userStyleSheet() const
01094 {
01095     return d->m_userSheet;
01096 }
01097 
01098 bool KHTMLSettings::isFormCompletionEnabled() const
01099 {
01100   return d->m_formCompletionEnabled;
01101 }
01102 
01103 int KHTMLSettings::maxFormCompletionItems() const
01104 {
01105   return d->m_maxFormCompletionItems;
01106 }
01107 
01108 const QString &KHTMLSettings::encoding() const
01109 {
01110   return d->m_encoding;
01111 }
01112 
01113 bool KHTMLSettings::followSystemColors() const
01114 {
01115     return d->m_follow_system_colors;
01116 }
01117 
01118 const QColor& KHTMLSettings::textColor() const
01119 {
01120   return d->m_textColor;
01121 }
01122 
01123 const QColor& KHTMLSettings::baseColor() const
01124 {
01125   return d->m_baseColor;
01126 }
01127 
01128 const QColor& KHTMLSettings::linkColor() const
01129 {
01130   return d->m_linkColor;
01131 }
01132 
01133 const QColor& KHTMLSettings::vLinkColor() const
01134 {
01135   return d->m_vLinkColor;
01136 }
01137 
01138 bool KHTMLSettings::autoLoadImages() const
01139 {
01140   return d->m_bAutoLoadImages;
01141 }
01142 
01143 bool KHTMLSettings::unfinishedImageFrame() const
01144 {
01145   return d->m_bUnfinishedImageFrame;
01146 }
01147 
01148 KHTMLSettings::KAnimationAdvice KHTMLSettings::showAnimations() const
01149 {
01150   return d->m_showAnimations;
01151 }
01152 
01153 KHTMLSettings::KSmoothScrollingMode KHTMLSettings::smoothScrolling() const
01154 {
01155   return d->m_smoothScrolling;
01156 }
01157 
01158 KHTMLSettings::KDNSPrefetch KHTMLSettings::dnsPrefetch() const
01159 {
01160   return d->m_dnsPrefetch;
01161 }
01162 
01163 bool KHTMLSettings::isAutoDelayedActionsEnabled() const
01164 {
01165   return d->m_autoDelayedActionsEnabled;
01166 }
01167 
01168 bool KHTMLSettings::jsErrorsEnabled() const
01169 {
01170   return d->m_jsErrorsEnabled;
01171 }
01172 
01173 void KHTMLSettings::setJSErrorsEnabled(bool enabled)
01174 {
01175   d->m_jsErrorsEnabled = enabled;
01176   // save it
01177   KConfigGroup cg( KGlobal::config(), "HTML Settings");
01178   cg.writeEntry("ReportJSErrors", enabled);
01179   cg.sync();
01180 }
01181 
01182 bool KHTMLSettings::allowTabulation() const
01183 {
01184     return d->m_allowTabulation;
01185 }
01186 
01187 bool KHTMLSettings::autoSpellCheck() const
01188 {
01189     return d->m_autoSpellCheck;
01190 }
01191 
01192 QList< QPair< QString, QChar > > KHTMLSettings::fallbackAccessKeysAssignments() const
01193 {
01194     return d->m_fallbackAccessKeysAssignments;
01195 }
01196 
01197 void KHTMLSettings::setJSPopupBlockerPassivePopup(bool enabled)
01198 {
01199     d->m_jsPopupBlockerPassivePopup = enabled;
01200     // save it
01201     KConfigGroup cg( KGlobal::config(), "Java/JavaScript Settings");
01202     cg.writeEntry("PopupBlockerPassivePopup", enabled);
01203     cg.sync();
01204 }
01205 
01206 bool KHTMLSettings::jsPopupBlockerPassivePopup() const
01207 {
01208     return d->m_jsPopupBlockerPassivePopup;
01209 }
01210 
01211 #include "khtml_settings.moc"

KHTML

Skip menu "KHTML"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.3
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal