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