khtml_settings.cc

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 <qfontdatabase.h>
00021 
00022 #include "khtml_settings.h"
00023 #include "khtmldefaults.h"
00024 #include <kglobalsettings.h>
00025 #include <kconfig.h>
00026 #include <kglobal.h>
00027 #include <klocale.h>
00028 #include <kdebug.h>
00029 #include <qregexp.h>
00030 #include <qvaluevector.h>
00031 #include <kmessagebox.h>
00032 
00037 struct KPerDomainSettings {
00038     bool m_bEnableJava : 1;
00039     bool m_bEnableJavaScript : 1;
00040     bool m_bEnablePlugins : 1;
00041     // don't forget to maintain the bitfields as the enums grow
00042     KHTMLSettings::KJSWindowOpenPolicy m_windowOpenPolicy : 2;
00043     KHTMLSettings::KJSWindowStatusPolicy m_windowStatusPolicy : 1;
00044     KHTMLSettings::KJSWindowFocusPolicy m_windowFocusPolicy : 1;
00045     KHTMLSettings::KJSWindowMovePolicy m_windowMovePolicy : 1;
00046     KHTMLSettings::KJSWindowResizePolicy m_windowResizePolicy : 1;
00047 
00048 #ifdef DEBUG_SETTINGS
00049     void dump(const QString &infix = QString::null) const {
00050       kdDebug() << "KPerDomainSettings " << infix << " @" << this << ":" << endl;
00051       kdDebug() << "  m_bEnableJava: " << m_bEnableJava << endl;
00052       kdDebug() << "  m_bEnableJavaScript: " << m_bEnableJavaScript << endl;
00053       kdDebug() << "  m_bEnablePlugins: " << m_bEnablePlugins << endl;
00054       kdDebug() << "  m_windowOpenPolicy: " << m_windowOpenPolicy << endl;
00055       kdDebug() << "  m_windowStatusPolicy: " << m_windowStatusPolicy << endl;
00056       kdDebug() << "  m_windowFocusPolicy: " << m_windowFocusPolicy << endl;
00057       kdDebug() << "  m_windowMovePolicy: " << m_windowMovePolicy << endl;
00058       kdDebug() << "  m_windowResizePolicy: " << m_windowResizePolicy << endl;
00059     }
00060 #endif
00061 };
00062 
00063 typedef QMap<QString,KPerDomainSettings> PolicyMap;
00064 
00065 class KHTMLSettingsPrivate
00066 {
00067 public:
00068     bool m_bChangeCursor : 1;
00069     bool m_bOpenMiddleClick : 1;
00070     bool m_bBackRightClick : 1;
00071     bool m_underlineLink : 1;
00072     bool m_hoverLink : 1;
00073     bool m_bEnableJavaScriptDebug : 1;
00074     bool m_bEnableJavaScriptErrorReporting : 1;
00075     bool enforceCharset : 1;
00076     bool m_bAutoLoadImages : 1;
00077     bool m_bUnfinishedImageFrame : 1;
00078     bool m_formCompletionEnabled : 1;
00079     bool m_autoDelayedActionsEnabled : 1;
00080     bool m_jsErrorsEnabled : 1;
00081     bool m_follow_system_colors : 1;
00082     bool m_allowTabulation : 1;
00083     bool m_autoSpellCheck : 1;
00084     bool m_adFilterEnabled : 1;
00085     bool m_hideAdsEnabled : 1;
00086     bool m_jsPopupBlockerPassivePopup : 1;
00087     bool m_accessKeysEnabled : 1;
00088 
00089     // the virtual global "domain"
00090     KPerDomainSettings global;
00091 
00092     int m_fontSize;
00093     int m_minFontSize;
00094     int m_maxFormCompletionItems;
00095     KHTMLSettings::KAnimationAdvice m_showAnimations;
00096 
00097     QString m_encoding;
00098     QString m_userSheet;
00099 
00100     QColor m_textColor;
00101     QColor m_baseColor;
00102     QColor m_linkColor;
00103     QColor m_vLinkColor;
00104 
00105     PolicyMap domainPolicy;
00106     QStringList fonts;
00107     QStringList defaultFonts;
00108 
00109     QValueVector<QRegExp> adFilters;
00110     QValueList< QPair< QString, QChar > > m_fallbackAccessKeysAssignments;
00111 };
00112 
00113 
00117 static KPerDomainSettings &setup_per_domain_policy(
00118                 KHTMLSettingsPrivate *d,
00119                 const QString &domain) {
00120   if (domain.isEmpty()) {
00121     kdWarning() << "setup_per_domain_policy: domain is empty" << endl;
00122   }
00123   const QString ldomain = domain.lower();
00124   PolicyMap::iterator it = d->domainPolicy.find(ldomain);
00125   if (it == d->domainPolicy.end()) {
00126     // simply copy global domain settings (they should have been initialized
00127     // by this time)
00128     it = d->domainPolicy.insert(ldomain,d->global);
00129   }
00130   return *it;
00131 }
00132 
00133 
00134 KHTMLSettings::KJavaScriptAdvice KHTMLSettings::strToAdvice(const QString& _str)
00135 {
00136   KJavaScriptAdvice ret = KJavaScriptDunno;
00137 
00138   if (!_str)
00139         ret = KJavaScriptDunno;
00140 
00141   if (_str.lower() == QString::fromLatin1("accept"))
00142         ret = KJavaScriptAccept;
00143   else if (_str.lower() == QString::fromLatin1("reject"))
00144         ret = KJavaScriptReject;
00145 
00146   return ret;
00147 }
00148 
00149 const char* KHTMLSettings::adviceToStr(KJavaScriptAdvice _advice)
00150 {
00151     switch( _advice ) {
00152     case KJavaScriptAccept: return I18N_NOOP("Accept");
00153     case KJavaScriptReject: return I18N_NOOP("Reject");
00154     default: return 0;
00155     }
00156         return 0;
00157 }
00158 
00159 
00160 void KHTMLSettings::splitDomainAdvice(const QString& configStr, QString &domain,
00161                                       KJavaScriptAdvice &javaAdvice, KJavaScriptAdvice& javaScriptAdvice)
00162 {
00163     QString tmp(configStr);
00164     int splitIndex = tmp.find(':');
00165     if ( splitIndex == -1)
00166     {
00167         domain = configStr.lower();
00168         javaAdvice = KJavaScriptDunno;
00169         javaScriptAdvice = KJavaScriptDunno;
00170     }
00171     else
00172     {
00173         domain = tmp.left(splitIndex).lower();
00174         QString adviceString = tmp.mid( splitIndex+1, tmp.length() );
00175         int splitIndex2 = adviceString.find( ':' );
00176         if( splitIndex2 == -1 ) {
00177             // Java advice only
00178             javaAdvice = strToAdvice( adviceString );
00179             javaScriptAdvice = KJavaScriptDunno;
00180         } else {
00181             // Java and JavaScript advice
00182             javaAdvice = strToAdvice( adviceString.left( splitIndex2 ) );
00183             javaScriptAdvice = strToAdvice( adviceString.mid( splitIndex2+1,
00184                                                               adviceString.length() ) );
00185         }
00186     }
00187 }
00188 
00189 void KHTMLSettings::readDomainSettings(KConfig *config, bool reset,
00190     bool global, KPerDomainSettings &pd_settings) {
00191   QString jsPrefix = global ? QString::null
00192                 : QString::fromLatin1("javascript.");
00193   QString javaPrefix = global ? QString::null
00194                 : QString::fromLatin1("java.");
00195   QString pluginsPrefix = global ? QString::null
00196                 : QString::fromLatin1("plugins.");
00197 
00198   // The setting for Java
00199   QString key = javaPrefix + QString::fromLatin1("EnableJava");
00200   if ( (global && reset) || config->hasKey( key ) )
00201     pd_settings.m_bEnableJava = config->readBoolEntry( key, false );
00202   else if ( !global )
00203     pd_settings.m_bEnableJava = d->global.m_bEnableJava;
00204 
00205   // The setting for Plugins
00206   key = pluginsPrefix + QString::fromLatin1("EnablePlugins");
00207   if ( (global && reset) || config->hasKey( key ) )
00208     pd_settings.m_bEnablePlugins = config->readBoolEntry( key, true );
00209   else if ( !global )
00210     pd_settings.m_bEnablePlugins = d->global.m_bEnablePlugins;
00211 
00212   // The setting for JavaScript
00213   key = jsPrefix + QString::fromLatin1("EnableJavaScript");
00214   if ( (global && reset) || config->hasKey( key ) )
00215     pd_settings.m_bEnableJavaScript = config->readBoolEntry( key, true );
00216   else if ( !global )
00217     pd_settings.m_bEnableJavaScript = d->global.m_bEnableJavaScript;
00218 
00219   // window property policies
00220   key = jsPrefix + QString::fromLatin1("WindowOpenPolicy");
00221   if ( (global && reset) || config->hasKey( key ) )
00222     pd_settings.m_windowOpenPolicy = (KJSWindowOpenPolicy)
00223             config->readUnsignedNumEntry( key, KJSWindowOpenSmart );
00224   else if ( !global )
00225     pd_settings.m_windowOpenPolicy = d->global.m_windowOpenPolicy;
00226 
00227   key = jsPrefix + QString::fromLatin1("WindowMovePolicy");
00228   if ( (global && reset) || config->hasKey( key ) )
00229     pd_settings.m_windowMovePolicy = (KJSWindowMovePolicy)
00230             config->readUnsignedNumEntry( key, KJSWindowMoveAllow );
00231   else if ( !global )
00232     pd_settings.m_windowMovePolicy = d->global.m_windowMovePolicy;
00233 
00234   key = jsPrefix + QString::fromLatin1("WindowResizePolicy");
00235   if ( (global && reset) || config->hasKey( key ) )
00236     pd_settings.m_windowResizePolicy = (KJSWindowResizePolicy)
00237             config->readUnsignedNumEntry( key, KJSWindowResizeAllow );
00238   else if ( !global )
00239     pd_settings.m_windowResizePolicy = d->global.m_windowResizePolicy;
00240 
00241   key = jsPrefix + QString::fromLatin1("WindowStatusPolicy");
00242   if ( (global && reset) || config->hasKey( key ) )
00243     pd_settings.m_windowStatusPolicy = (KJSWindowStatusPolicy)
00244             config->readUnsignedNumEntry( key, KJSWindowStatusAllow );
00245   else if ( !global )
00246     pd_settings.m_windowStatusPolicy = d->global.m_windowStatusPolicy;
00247 
00248   key = jsPrefix + QString::fromLatin1("WindowFocusPolicy");
00249   if ( (global && reset) || config->hasKey( key ) )
00250     pd_settings.m_windowFocusPolicy = (KJSWindowFocusPolicy)
00251             config->readUnsignedNumEntry( key, KJSWindowFocusAllow );
00252   else if ( !global )
00253     pd_settings.m_windowFocusPolicy = d->global.m_windowFocusPolicy;
00254 
00255 }
00256 
00257 
00258 KHTMLSettings::KHTMLSettings()
00259 {
00260   d = new KHTMLSettingsPrivate();
00261   init();
00262 }
00263 
00264 KHTMLSettings::KHTMLSettings(const KHTMLSettings &other)
00265 {
00266   d = new KHTMLSettingsPrivate();
00267   *d = *other.d;
00268 }
00269 
00270 KHTMLSettings::~KHTMLSettings()
00271 {
00272   delete d;
00273 }
00274 
00275 bool KHTMLSettings::changeCursor() const
00276 {
00277   return d->m_bChangeCursor;
00278 }
00279 
00280 bool KHTMLSettings::underlineLink() const
00281 {
00282   return d->m_underlineLink;
00283 }
00284 
00285 bool KHTMLSettings::hoverLink() const
00286 {
00287   return d->m_hoverLink;
00288 }
00289 
00290 void KHTMLSettings::init()
00291 {
00292   KConfig global( "khtmlrc", true, false );
00293   init( &global, true );
00294 
00295   KConfig *local = KGlobal::config();
00296   if ( !local )
00297     return;
00298 
00299   init( local, false );
00300 }
00301 
00302 void KHTMLSettings::init( KConfig * config, bool reset )
00303 {
00304   QString group_save = config->group();
00305   if (reset || config->hasGroup("MainView Settings"))
00306   {
00307     config->setGroup( "MainView Settings" );
00308 
00309     if ( reset || config->hasKey( "OpenMiddleClick" ) )
00310         d->m_bOpenMiddleClick = config->readBoolEntry( "OpenMiddleClick", true );
00311 
00312     if ( reset || config->hasKey( "BackRightClick" ) )
00313         d->m_bBackRightClick = config->readBoolEntry( "BackRightClick", false );
00314   }
00315 
00316   if (reset || config->hasGroup("Access Keys")) {
00317       config->setGroup( "Access Keys" );
00318       d->m_accessKeysEnabled = config->readBoolEntry( "Enabled", true );
00319   }
00320 
00321   if (reset || config->hasGroup("Filter Settings"))
00322   {
00323       config->setGroup( "Filter Settings" );
00324       d->m_adFilterEnabled = config->readBoolEntry("Enabled", false);
00325       d->m_hideAdsEnabled = config->readBoolEntry("Shrink", false);
00326 
00327       d->adFilters.clear();
00328 
00329       QMap<QString,QString> entryMap = config->entryMap("Filter Settings");
00330       QMap<QString,QString>::ConstIterator it;
00331       d->adFilters.reserve(entryMap.count());
00332       for( it = entryMap.constBegin(); it != entryMap.constEnd(); ++it )
00333       {
00334           QString name = it.key();
00335           QString url = it.data();
00336 
00337           if (url.startsWith("!"))
00338               continue;
00339 
00340           if (name.startsWith("Filter"))
00341           {
00342               if (url.length()>2 && url[0]=='/' && url[url.length()-1] == '/')
00343               {
00344                   QString inside = url.mid(1, url.length()-2);
00345                   QRegExp rx(inside);
00346                   d->adFilters.append(rx);
00347               }
00348               else
00349               {
00350                   QRegExp rx;
00351                   int left,right;
00352 
00353                   for (right=url.length(); right>0 && url[right-1]=='*' ; --right);
00354                   for (left=0; left<right && url[left]=='*' ; ++left);
00355 
00356                   rx.setWildcard(true);
00357                   rx.setPattern(url.mid(left,right-left));
00358 
00359                   d->adFilters.append(rx);
00360               }
00361           }
00362       }
00363   }
00364 
00365 
00366   if (reset || config->hasGroup("HTML Settings"))
00367   {
00368     config->setGroup( "HTML Settings" );
00369     // Fonts and colors
00370     if( reset ) {
00371         d->defaultFonts = QStringList();
00372         d->defaultFonts.append( config->readEntry( "StandardFont", KGlobalSettings::generalFont().family() ) );
00373         d->defaultFonts.append( config->readEntry( "FixedFont", KGlobalSettings::fixedFont().family() ) );
00374         d->defaultFonts.append( config->readEntry( "SerifFont", HTML_DEFAULT_VIEW_SERIF_FONT ) );
00375         d->defaultFonts.append( config->readEntry( "SansSerifFont", HTML_DEFAULT_VIEW_SANSSERIF_FONT ) );
00376         d->defaultFonts.append( config->readEntry( "CursiveFont", HTML_DEFAULT_VIEW_CURSIVE_FONT ) );
00377         d->defaultFonts.append( config->readEntry( "FantasyFont", HTML_DEFAULT_VIEW_FANTASY_FONT ) );
00378         d->defaultFonts.append( QString( "0" ) ); // font size adjustment
00379     }
00380 
00381     if ( reset || config->hasKey( "MinimumFontSize" ) )
00382         d->m_minFontSize = config->readNumEntry( "MinimumFontSize", HTML_DEFAULT_MIN_FONT_SIZE );
00383 
00384     if ( reset || config->hasKey( "MediumFontSize" ) )
00385         d->m_fontSize = config->readNumEntry( "MediumFontSize", 12 );
00386 
00387     d->fonts = config->readListEntry( "Fonts" );
00388 
00389     if ( reset || config->hasKey( "DefaultEncoding" ) )
00390         d->m_encoding = config->readEntry( "DefaultEncoding", "" );
00391 
00392     if ( reset || config->hasKey( "EnforceDefaultCharset" ) )
00393         d->enforceCharset = config->readBoolEntry( "EnforceDefaultCharset", false );
00394 
00395     // Behavior
00396     if ( reset || config->hasKey( "ChangeCursor" ) )
00397         d->m_bChangeCursor = config->readBoolEntry( "ChangeCursor", KDE_DEFAULT_CHANGECURSOR );
00398 
00399     if ( reset || config->hasKey("UnderlineLinks") )
00400         d->m_underlineLink = config->readBoolEntry( "UnderlineLinks", true );
00401 
00402     if ( reset || config->hasKey( "HoverLinks" ) )
00403     {
00404         if ( ( d->m_hoverLink = config->readBoolEntry( "HoverLinks", false ) ) )
00405             d->m_underlineLink = false;
00406     }
00407 
00408     if ( reset || config->hasKey( "AllowTabulation" ) )
00409         d->m_allowTabulation = config->readBoolEntry( "AllowTabulation", false );
00410 
00411     if ( reset || config->hasKey( "AutoSpellCheck" ) )
00412         d->m_autoSpellCheck = config->readBoolEntry( "AutoSpellCheck", true );
00413 
00414     // Other
00415     if ( reset || config->hasKey( "AutoLoadImages" ) )
00416       d->m_bAutoLoadImages = config->readBoolEntry( "AutoLoadImages", true );
00417 
00418     if ( reset || config->hasKey( "UnfinishedImageFrame" ) )
00419       d->m_bUnfinishedImageFrame = config->readBoolEntry( "UnfinishedImageFrame", true );
00420 
00421     if ( reset || config->hasKey( "ShowAnimations" ) )
00422     {
00423       QString value = config->readEntry( "ShowAnimations").lower();
00424       if (value == "disabled")
00425          d->m_showAnimations = KAnimationDisabled;
00426       else if (value == "looponce")
00427          d->m_showAnimations = KAnimationLoopOnce;
00428       else
00429          d->m_showAnimations = KAnimationEnabled;
00430     }
00431 
00432     if ( config->readBoolEntry( "UserStyleSheetEnabled", false ) == true ) {
00433         if ( reset || config->hasKey( "UserStyleSheet" ) )
00434             d->m_userSheet = config->readEntry( "UserStyleSheet", "" );
00435     }
00436 
00437     d->m_formCompletionEnabled = config->readBoolEntry("FormCompletion", true);
00438     d->m_maxFormCompletionItems = config->readNumEntry("MaxFormCompletionItems", 10);
00439     d->m_autoDelayedActionsEnabled = config->readBoolEntry ("AutoDelayedActions", true);
00440     d->m_jsErrorsEnabled = config->readBoolEntry("ReportJSErrors", true);
00441     QStringList accesskeys = config->readListEntry("FallbackAccessKeysAssignments");
00442     d->m_fallbackAccessKeysAssignments.clear();
00443     for( QStringList::ConstIterator it = accesskeys.begin(); it != accesskeys.end(); ++it )
00444         if( (*it).length() > 2 && (*it)[ 1 ] == ':' )
00445             d->m_fallbackAccessKeysAssignments.append( qMakePair( (*it).mid( 2 ), (*it)[ 0 ] ));
00446   }
00447 
00448   // Colors
00449 
00450   if ( reset || config->hasKey( "FollowSystemColors" ) )
00451       d->m_follow_system_colors = config->readBoolEntry( "FollowSystemColors", false );
00452 
00453   if ( reset || config->hasGroup( "General" ) )
00454   {
00455     config->setGroup( "General" ); // group will be restored by cgs anyway
00456     if ( reset || config->hasKey( "foreground" ) )
00457       d->m_textColor = config->readColorEntry( "foreground", &HTML_DEFAULT_TXT_COLOR );
00458 
00459     if ( reset || config->hasKey( "linkColor" ) )
00460       d->m_linkColor = config->readColorEntry( "linkColor", &HTML_DEFAULT_LNK_COLOR );
00461 
00462     if ( reset || config->hasKey( "visitedLinkColor" ) )
00463       d->m_vLinkColor = config->readColorEntry( "visitedLinkColor", &HTML_DEFAULT_VLNK_COLOR);
00464 
00465     if ( reset || config->hasKey( "background" ) )
00466       d->m_baseColor = config->readColorEntry( "background", &HTML_DEFAULT_BASE_COLOR);
00467   }
00468 
00469   if( reset || config->hasGroup( "Java/JavaScript Settings" ) )
00470   {
00471     config->setGroup( "Java/JavaScript Settings" );
00472 
00473     // The global setting for JavaScript debugging
00474     // This is currently always enabled by default
00475     if ( reset || config->hasKey( "EnableJavaScriptDebug" ) )
00476       d->m_bEnableJavaScriptDebug = config->readBoolEntry( "EnableJavaScriptDebug", false );
00477 
00478     // The global setting for JavaScript error reporting
00479     if ( reset || config->hasKey( "ReportJavaScriptErrors" ) )
00480       d->m_bEnableJavaScriptErrorReporting = config->readBoolEntry( "ReportJavaScriptErrors", false );
00481 
00482     // The global setting for popup block passive popup
00483     if ( reset || config->hasKey( "PopupBlockerPassivePopup" ) )
00484       d->m_jsPopupBlockerPassivePopup = config->readBoolEntry("PopupBlockerPassivePopup", true);
00485 
00486     // Read options from the global "domain"
00487     readDomainSettings(config,reset,true,d->global);
00488 #ifdef DEBUG_SETTINGS
00489     d->global.dump("init global");
00490 #endif
00491 
00492     // The domain-specific settings.
00493 
00494     static const char *const domain_keys[] = {  // always keep order of keys
00495         "ECMADomains", "JavaDomains", "PluginDomains"
00496     };
00497     bool check_old_ecma_settings = true;
00498     bool check_old_java_settings = true;
00499     // merge all domains into one list
00500     QMap<QString,int> domainList;   // why can't Qt have a QSet?
00501     for (unsigned i = 0; i < sizeof domain_keys/sizeof domain_keys[0]; ++i) {
00502       if ( reset || config->hasKey(domain_keys[i]) ) {
00503         if (i == 0) check_old_ecma_settings = false;
00504     else if (i == 1) check_old_java_settings = false;
00505         const QStringList dl = config->readListEntry( domain_keys[i] );
00506     const QMap<QString,int>::Iterator notfound = domainList.end();
00507     QStringList::ConstIterator it = dl.begin();
00508     const QStringList::ConstIterator itEnd = dl.end();
00509     for (; it != itEnd; ++it) {
00510       const QString domain = (*it).lower();
00511       QMap<QString,int>::Iterator pos = domainList.find(domain);
00512       if (pos == notfound) domainList.insert(domain,0);
00513     }/*next it*/
00514       }
00515     }/*next i*/
00516 
00517     if (reset)
00518       d->domainPolicy.clear();
00519 
00520     QString js_group_save = config->group();
00521     {
00522       QMap<QString,int>::ConstIterator it = domainList.begin();
00523       const QMap<QString,int>::ConstIterator itEnd = domainList.end();
00524       for ( ; it != itEnd; ++it)
00525       {
00526         const QString domain = it.key();
00527         config->setGroup(domain);
00528         readDomainSettings(config,reset,false,d->domainPolicy[domain]);
00529 #ifdef DEBUG_SETTINGS
00530         d->domainPolicy[domain].dump("init "+domain);
00531 #endif
00532       }
00533     }
00534     config->setGroup(js_group_save);
00535 
00536     bool check_old_java = true;
00537     if( ( reset || config->hasKey( "JavaDomainSettings" ) )
00538         && check_old_java_settings )
00539     {
00540       check_old_java = false;
00541       const QStringList domainList = config->readListEntry( "JavaDomainSettings" );
00542       QStringList::ConstIterator it = domainList.begin();
00543       const QStringList::ConstIterator itEnd = domainList.end();
00544       for ( ; it != itEnd; ++it)
00545       {
00546         QString domain;
00547         KJavaScriptAdvice javaAdvice;
00548         KJavaScriptAdvice javaScriptAdvice;
00549         splitDomainAdvice(*it, domain, javaAdvice, javaScriptAdvice);
00550         setup_per_domain_policy(d,domain).m_bEnableJava =
00551         javaAdvice == KJavaScriptAccept;
00552 #ifdef DEBUG_SETTINGS
00553     setup_per_domain_policy(d,domain).dump("JavaDomainSettings 4 "+domain);
00554 #endif
00555       }
00556     }
00557 
00558     bool check_old_ecma = true;
00559     if( ( reset || config->hasKey( "ECMADomainSettings" ) )
00560     && check_old_ecma_settings )
00561     {
00562       check_old_ecma = false;
00563       const QStringList domainList = config->readListEntry( "ECMADomainSettings" );
00564       QStringList::ConstIterator it = domainList.begin();
00565       const QStringList::ConstIterator itEnd = domainList.end();
00566       for ( ; it != itEnd; ++it)
00567       {
00568         QString domain;
00569         KJavaScriptAdvice javaAdvice;
00570         KJavaScriptAdvice javaScriptAdvice;
00571         splitDomainAdvice(*it, domain, javaAdvice, javaScriptAdvice);
00572         setup_per_domain_policy(d,domain).m_bEnableJavaScript =
00573             javaScriptAdvice == KJavaScriptAccept;
00574 #ifdef DEBUG_SETTINGS
00575     setup_per_domain_policy(d,domain).dump("ECMADomainSettings 4 "+domain);
00576 #endif
00577       }
00578     }
00579 
00580     if( ( reset || config->hasKey( "JavaScriptDomainAdvice" ) )
00581              && ( check_old_java || check_old_ecma )
00582          && ( check_old_ecma_settings || check_old_java_settings ) )
00583     {
00584       const QStringList domainList = config->readListEntry( "JavaScriptDomainAdvice" );
00585       QStringList::ConstIterator it = domainList.begin();
00586       const QStringList::ConstIterator itEnd = domainList.end();
00587       for ( ; it != itEnd; ++it)
00588       {
00589         QString domain;
00590         KJavaScriptAdvice javaAdvice;
00591         KJavaScriptAdvice javaScriptAdvice;
00592         splitDomainAdvice(*it, domain, javaAdvice, javaScriptAdvice);
00593         if( check_old_java )
00594           setup_per_domain_policy(d,domain).m_bEnableJava =
00595             javaAdvice == KJavaScriptAccept;
00596         if( check_old_ecma )
00597           setup_per_domain_policy(d,domain).m_bEnableJavaScript =
00598             javaScriptAdvice == KJavaScriptAccept;
00599 #ifdef DEBUG_SETTINGS
00600     setup_per_domain_policy(d,domain).dump("JavaScriptDomainAdvice 4 "+domain);
00601 #endif
00602       }
00603 
00604       //save all the settings into the new keywords if they don't exist
00605 #if 0
00606       if( check_old_java )
00607       {
00608         QStringList domainConfig;
00609         PolicyMap::Iterator it;
00610         for( it = d->javaDomainPolicy.begin(); it != d->javaDomainPolicy.end(); ++it )
00611         {
00612           QCString javaPolicy = adviceToStr( it.data() );
00613           QCString javaScriptPolicy = adviceToStr( KJavaScriptDunno );
00614           domainConfig.append(QString::fromLatin1("%1:%2:%3").arg(it.key()).arg(javaPolicy).arg(javaScriptPolicy));
00615         }
00616         config->writeEntry( "JavaDomainSettings", domainConfig );
00617       }
00618 
00619       if( check_old_ecma )
00620       {
00621         QStringList domainConfig;
00622         PolicyMap::Iterator it;
00623         for( it = d->javaScriptDomainPolicy.begin(); it != d->javaScriptDomainPolicy.end(); ++it )
00624         {
00625           QCString javaPolicy = adviceToStr( KJavaScriptDunno );
00626           QCString javaScriptPolicy = adviceToStr( it.data() );
00627           domainConfig.append(QString::fromLatin1("%1:%2:%3").arg(it.key()).arg(javaPolicy).arg(javaScriptPolicy));
00628         }
00629         config->writeEntry( "ECMADomainSettings", domainConfig );
00630       }
00631 #endif
00632     }
00633   }
00634   config->setGroup(group_save);
00635 }
00636 
00637 
00642 static const KPerDomainSettings &lookup_hostname_policy(
00643             const KHTMLSettingsPrivate *d,
00644             const QString& hostname)
00645 {
00646 #ifdef DEBUG_SETTINGS
00647   kdDebug() << "lookup_hostname_policy(" << hostname << ")" << endl;
00648 #endif
00649   if (hostname.isEmpty()) {
00650 #ifdef DEBUG_SETTINGS
00651     d->global.dump("global");
00652 #endif
00653     return d->global;
00654   }
00655 
00656   const PolicyMap::const_iterator notfound = d->domainPolicy.end();
00657 
00658   // First check whether there is a perfect match.
00659   PolicyMap::const_iterator it = d->domainPolicy.find(hostname);
00660   if( it != notfound ) {
00661 #ifdef DEBUG_SETTINGS
00662     kdDebug() << "perfect match" << endl;
00663     (*it).dump(hostname);
00664 #endif
00665     // yes, use it (unless dunno)
00666     return *it;
00667   }
00668 
00669   // Now, check for partial match.  Chop host from the left until
00670   // there's no dots left.
00671   QString host_part = hostname;
00672   int dot_idx = -1;
00673   while( (dot_idx = host_part.find(QChar('.'))) >= 0 ) {
00674     host_part.remove(0,dot_idx);
00675     it = d->domainPolicy.find(host_part);
00676     Q_ASSERT(notfound == d->domainPolicy.end());
00677     if( it != notfound ) {
00678 #ifdef DEBUG_SETTINGS
00679       kdDebug() << "partial match" << endl;
00680       (*it).dump(host_part);
00681 #endif
00682       return *it;
00683     }
00684     // assert(host_part[0] == QChar('.'));
00685     host_part.remove(0,1); // Chop off the dot.
00686   }
00687 
00688   // No domain-specific entry: use global domain
00689 #ifdef DEBUG_SETTINGS
00690   kdDebug() << "no match" << endl;
00691   d->global.dump("global");
00692 #endif
00693   return d->global;
00694 }
00695 
00696 bool KHTMLSettings::isOpenMiddleClickEnabled()
00697 {
00698   return d->m_bOpenMiddleClick;
00699 }
00700 
00701 bool KHTMLSettings::isBackRightClickEnabled()
00702 {
00703   return d->m_bBackRightClick;
00704 }
00705 
00706 bool KHTMLSettings::accessKeysEnabled() const
00707 {
00708     return d->m_accessKeysEnabled;
00709 }
00710 
00711 bool KHTMLSettings::isAdFilterEnabled() const
00712 {
00713     return d->m_adFilterEnabled;
00714 }
00715 
00716 bool KHTMLSettings::isHideAdsEnabled() const
00717 {
00718     return d->m_hideAdsEnabled;
00719 }
00720 
00721 bool KHTMLSettings::isAdFiltered( const QString &url ) const
00722 {
00723     if (d->m_adFilterEnabled)
00724     {
00725         if (!url.startsWith("data:"))
00726         {
00727             QValueVector<QRegExp>::iterator it;
00728             for (it=d->adFilters.begin(); it != d->adFilters.end(); ++it)
00729             {
00730                 if ((*it).search(url) != -1)
00731                 {
00732                     kdDebug( 6080 ) << "Filtered: " << url << endl;
00733                     return true;
00734                 }
00735             }
00736         }
00737     }
00738     return false;
00739 }
00740 
00741 void KHTMLSettings::addAdFilter( const QString &url )
00742 {
00743     KConfig config( "khtmlrc", false, false );
00744     config.setGroup( "Filter Settings" );
00745 
00746     QRegExp rx;
00747     if (url.length()>2 && url[0]=='/' && url[url.length()-1] == '/')
00748     {
00749         QString inside = url.mid(1, url.length()-2);
00750         rx.setWildcard(false);
00751         rx.setPattern(inside);
00752     }
00753     else
00754     {
00755         int left,right;
00756 
00757         rx.setWildcard(true);
00758         for (right=url.length(); right>0 && url[right-1]=='*' ; --right);
00759         for (left=0; left<right && url[left]=='*' ; ++left);
00760 
00761         rx.setPattern(url.mid(left,right-left));
00762     }
00763 
00764     if (rx.isValid())
00765     {
00766         int last=config.readNumEntry("Count",0);
00767         QString key = "Filter-" + QString::number(last);
00768         config.writeEntry(key, url);
00769         config.writeEntry("Count",last+1);
00770         config.sync();
00771 
00772         d->adFilters.append(rx);
00773     }
00774     else
00775     {
00776         KMessageBox::error(0,
00777                            rx.errorString(),
00778                            i18n("Filter error"));
00779     }
00780 }
00781 
00782 bool KHTMLSettings::isJavaEnabled( const QString& hostname )
00783 {
00784   return lookup_hostname_policy(d,hostname.lower()).m_bEnableJava;
00785 }
00786 
00787 bool KHTMLSettings::isJavaScriptEnabled( const QString& hostname )
00788 {
00789   return lookup_hostname_policy(d,hostname.lower()).m_bEnableJavaScript;
00790 }
00791 
00792 bool KHTMLSettings::isJavaScriptDebugEnabled( const QString& /*hostname*/ )
00793 {
00794   // debug setting is global for now, but could change in the future
00795   return d->m_bEnableJavaScriptDebug;
00796 }
00797 
00798 bool KHTMLSettings::isJavaScriptErrorReportingEnabled( const QString& /*hostname*/ ) const
00799 {
00800   // error reporting setting is global for now, but could change in the future
00801   return d->m_bEnableJavaScriptErrorReporting;
00802 }
00803 
00804 bool KHTMLSettings::isPluginsEnabled( const QString& hostname )
00805 {
00806   return lookup_hostname_policy(d,hostname.lower()).m_bEnablePlugins;
00807 }
00808 
00809 KHTMLSettings::KJSWindowOpenPolicy KHTMLSettings::windowOpenPolicy(
00810                 const QString& hostname) const {
00811   return lookup_hostname_policy(d,hostname.lower()).m_windowOpenPolicy;
00812 }
00813 
00814 KHTMLSettings::KJSWindowMovePolicy KHTMLSettings::windowMovePolicy(
00815                 const QString& hostname) const {
00816   return lookup_hostname_policy(d,hostname.lower()).m_windowMovePolicy;
00817 }
00818 
00819 KHTMLSettings::KJSWindowResizePolicy KHTMLSettings::windowResizePolicy(
00820                 const QString& hostname) const {
00821   return lookup_hostname_policy(d,hostname.lower()).m_windowResizePolicy;
00822 }
00823 
00824 KHTMLSettings::KJSWindowStatusPolicy KHTMLSettings::windowStatusPolicy(
00825                 const QString& hostname) const {
00826   return lookup_hostname_policy(d,hostname.lower()).m_windowStatusPolicy;
00827 }
00828 
00829 KHTMLSettings::KJSWindowFocusPolicy KHTMLSettings::windowFocusPolicy(
00830                 const QString& hostname) const {
00831   return lookup_hostname_policy(d,hostname.lower()).m_windowFocusPolicy;
00832 }
00833 
00834 int KHTMLSettings::mediumFontSize() const
00835 {
00836     return d->m_fontSize;
00837 }
00838 
00839 int KHTMLSettings::minFontSize() const
00840 {
00841   return d->m_minFontSize;
00842 }
00843 
00844 QString KHTMLSettings::settingsToCSS() const
00845 {
00846     // lets start with the link properties
00847     QString str = "a:link {\ncolor: ";
00848     str += d->m_linkColor.name();
00849     str += ";";
00850     if(d->m_underlineLink)
00851         str += "\ntext-decoration: underline;";
00852 
00853     if( d->m_bChangeCursor )
00854     {
00855         str += "\ncursor: pointer;";
00856         str += "\n}\ninput[type=image] { cursor: pointer;";
00857     }
00858     str += "\n}\n";
00859     str += "a:visited {\ncolor: ";
00860     str += d->m_vLinkColor.name();
00861     str += ";";
00862     if(d->m_underlineLink)
00863         str += "\ntext-decoration: underline;";
00864 
00865     if( d->m_bChangeCursor )
00866         str += "\ncursor: pointer;";
00867     str += "\n}\n";
00868 
00869     if(d->m_hoverLink)
00870         str += "a:link:hover, a:visited:hover { text-decoration: underline; }\n";
00871 
00872     return str;
00873 }
00874 
00875 const QString &KHTMLSettings::availableFamilies()
00876 {
00877     if ( !avFamilies ) {
00878         avFamilies = new QString;
00879         QFontDatabase db;
00880         QStringList families = db.families();
00881         QStringList s;
00882         QRegExp foundryExp(" \\[.+\\]");
00883 
00884         //remove foundry info
00885         QStringList::Iterator f = families.begin();
00886         const QStringList::Iterator fEnd = families.end();
00887 
00888         for ( ; f != fEnd; ++f ) {
00889                 (*f).replace( foundryExp, "");
00890                 if (!s.contains(*f))
00891                         s << *f;
00892         }
00893         s.sort();
00894 
00895         *avFamilies = ',' + s.join(",") + ',';
00896     }
00897 
00898   return *avFamilies;
00899 }
00900 
00901 QString KHTMLSettings::lookupFont(int i) const
00902 {
00903     QString font;
00904     if (d->fonts.count() > (uint) i)
00905        font = d->fonts[i];
00906     if (font.isEmpty())
00907         font = d->defaultFonts[i];
00908     return font;
00909 }
00910 
00911 QString KHTMLSettings::stdFontName() const
00912 {
00913     return lookupFont(0);
00914 }
00915 
00916 QString KHTMLSettings::fixedFontName() const
00917 {
00918     return lookupFont(1);
00919 }
00920 
00921 QString KHTMLSettings::serifFontName() const
00922 {
00923     return lookupFont(2);
00924 }
00925 
00926 QString KHTMLSettings::sansSerifFontName() const
00927 {
00928     return lookupFont(3);
00929 }
00930 
00931 QString KHTMLSettings::cursiveFontName() const
00932 {
00933     return lookupFont(4);
00934 }
00935 
00936 QString KHTMLSettings::fantasyFontName() const
00937 {
00938     return lookupFont(5);
00939 }
00940 
00941 void KHTMLSettings::setStdFontName(const QString &n)
00942 {
00943     while(d->fonts.count() <= 0)
00944         d->fonts.append(QString::null);
00945     d->fonts[0] = n;
00946 }
00947 
00948 void KHTMLSettings::setFixedFontName(const QString &n)
00949 {
00950     while(d->fonts.count() <= 1)
00951         d->fonts.append(QString::null);
00952     d->fonts[1] = n;
00953 }
00954 
00955 QString KHTMLSettings::userStyleSheet() const
00956 {
00957     return d->m_userSheet;
00958 }
00959 
00960 bool KHTMLSettings::isFormCompletionEnabled() const
00961 {
00962   return d->m_formCompletionEnabled;
00963 }
00964 
00965 int KHTMLSettings::maxFormCompletionItems() const
00966 {
00967   return d->m_maxFormCompletionItems;
00968 }
00969 
00970 const QString &KHTMLSettings::encoding() const
00971 {
00972   return d->m_encoding;
00973 }
00974 
00975 bool KHTMLSettings::followSystemColors() const
00976 {
00977     return d->m_follow_system_colors;
00978 }
00979 
00980 const QColor& KHTMLSettings::textColor() const
00981 {
00982   return d->m_textColor;
00983 }
00984 
00985 const QColor& KHTMLSettings::baseColor() const
00986 {
00987   return d->m_baseColor;
00988 }
00989 
00990 const QColor& KHTMLSettings::linkColor() const
00991 {
00992   return d->m_linkColor;
00993 }
00994 
00995 const QColor& KHTMLSettings::vLinkColor() const
00996 {
00997   return d->m_vLinkColor;
00998 }
00999 
01000 bool KHTMLSettings::autoLoadImages() const
01001 {
01002   return d->m_bAutoLoadImages;
01003 }
01004 
01005 bool KHTMLSettings::unfinishedImageFrame() const
01006 {
01007   return d->m_bUnfinishedImageFrame;
01008 }
01009 
01010 KHTMLSettings::KAnimationAdvice KHTMLSettings::showAnimations() const
01011 {
01012   return d->m_showAnimations;
01013 }
01014 
01015 bool KHTMLSettings::isAutoDelayedActionsEnabled() const
01016 {
01017   return d->m_autoDelayedActionsEnabled;
01018 }
01019 
01020 bool KHTMLSettings::jsErrorsEnabled() const
01021 {
01022   return d->m_jsErrorsEnabled;
01023 }
01024 
01025 void KHTMLSettings::setJSErrorsEnabled(bool enabled)
01026 {
01027   d->m_jsErrorsEnabled = enabled;
01028   // save it
01029   KConfig *config = KGlobal::config();
01030   config->setGroup("HTML Settings");
01031   config->writeEntry("ReportJSErrors", enabled);
01032   config->sync();
01033 }
01034 
01035 bool KHTMLSettings::allowTabulation() const
01036 {
01037     return d->m_allowTabulation;
01038 }
01039 
01040 bool KHTMLSettings::autoSpellCheck() const
01041 {
01042     return d->m_autoSpellCheck;
01043 }
01044 
01045 QValueList< QPair< QString, QChar > > KHTMLSettings::fallbackAccessKeysAssignments() const
01046 {
01047     return d->m_fallbackAccessKeysAssignments;
01048 }
01049 
01050 void KHTMLSettings::setJSPopupBlockerPassivePopup(bool enabled)
01051 {
01052     d->m_jsPopupBlockerPassivePopup = enabled;
01053     // save it
01054     KConfig *config = KGlobal::config();
01055     config->setGroup("Java/JavaScript Settings");
01056     config->writeEntry("PopupBlockerPassivePopup", enabled);
01057     config->sync();
01058 }
01059 
01060 bool KHTMLSettings::jsPopupBlockerPassivePopup() const
01061 {
01062     return d->m_jsPopupBlockerPassivePopup;
01063 }
KDE Home | KDE Accessibility Home | Description of Access Keys