khtml Library API Documentation

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., 59 Temple Place - Suite 330,
00017    Boston, MA 02111-1307, USA.
00018 */
00019 
00020 #include <qfontdatabase.h>
00021 #include <qregexp.h>
00022 
00023 #include "khtml_settings.h"
00024 #include "khtmldefaults.h"
00025 #include <kglobalsettings.h>
00026 #include <kconfig.h>
00027 #include <kglobal.h>
00028 #include <klocale.h>
00029 #include <kdebug.h>
00030 #include <qregexp.h>
00031 
00032 
00033 typedef QMap<QString,KHTMLSettings::KJavaScriptAdvice> PolicyMap;
00034 
00035 class KHTMLSettingsPrivate
00036 {
00037 public:
00038     bool m_bChangeCursor : 1;
00039     bool m_bBackRightClick : 1;
00040     bool m_underlineLink : 1;
00041     bool m_hoverLink : 1;
00042     bool enforceCharset : 1;
00043     bool m_bAutoLoadImages : 1;
00044     bool m_bEnableJava : 1;
00045     bool m_bEnableJavaScript : 1;
00046     bool m_bEnableJavaScriptDebug : 1;
00047     bool m_bEnablePlugins : 1;
00048     bool m_formCompletionEnabled : 1;
00049     bool m_autoDelayedActionsEnabled: 1;
00050 
00051     int m_fontSize;
00052     int m_minFontSize;
00053     int m_maxFormCompletionItems;
00054     KHTMLSettings::KAnimationAdvice m_showAnimations;
00055 
00056     QString m_encoding;
00057     QString m_userSheet;
00058 
00059     QColor m_textColor;
00060     QColor m_linkColor;
00061     QColor m_vLinkColor;
00062 
00063     QMap<QString,KHTMLSettings::KJavaScriptAdvice> javaDomainPolicy;
00064     QMap<QString,KHTMLSettings::KJavaScriptAdvice> javaScriptDomainPolicy;
00065     QStringList fonts;
00066     QStringList defaultFonts;
00067 };
00068 
00069 
00070 KHTMLSettings::KJavaScriptAdvice KHTMLSettings::strToAdvice(const QString& _str)
00071 {
00072   KJavaScriptAdvice ret = KJavaScriptDunno;
00073 
00074   if (!_str)
00075         ret = KJavaScriptDunno;
00076 
00077   if (_str.lower() == QString::fromLatin1("accept"))
00078         ret = KJavaScriptAccept;
00079   else if (_str.lower() == QString::fromLatin1("reject"))
00080         ret = KJavaScriptReject;
00081 
00082   return ret;
00083 }
00084 
00085 const char* KHTMLSettings::adviceToStr(KJavaScriptAdvice _advice)
00086 {
00087     switch( _advice ) {
00088     case KJavaScriptAccept: return I18N_NOOP("Accept");
00089     case KJavaScriptReject: return I18N_NOOP("Reject");
00090     default: return 0;
00091     }
00092         return 0;
00093 }
00094 
00095 
00096 void KHTMLSettings::splitDomainAdvice(const QString& configStr, QString &domain,
00097                                       KJavaScriptAdvice &javaAdvice, KJavaScriptAdvice& javaScriptAdvice)
00098 {
00099     QString tmp(configStr);
00100     int splitIndex = tmp.find(':');
00101     if ( splitIndex == -1)
00102     {
00103         domain = configStr.lower();
00104         javaAdvice = KJavaScriptDunno;
00105         javaScriptAdvice = KJavaScriptDunno;
00106     }
00107     else
00108     {
00109         domain = tmp.left(splitIndex).lower();
00110         QString adviceString = tmp.mid( splitIndex+1, tmp.length() );
00111         int splitIndex2 = adviceString.find( ':' );
00112         if( splitIndex2 == -1 ) {
00113             // Java advice only
00114             javaAdvice = strToAdvice( adviceString );
00115             javaScriptAdvice = KJavaScriptDunno;
00116         } else {
00117             // Java and JavaScript advice
00118             javaAdvice = strToAdvice( adviceString.left( splitIndex2 ) );
00119             javaScriptAdvice = strToAdvice( adviceString.mid( splitIndex2+1,
00120                                                               adviceString.length() ) );
00121         }
00122     }
00123 }
00124 
00125 
00126 KHTMLSettings::KHTMLSettings()
00127 {
00128   d = new KHTMLSettingsPrivate();
00129   init();
00130 }
00131 
00132 KHTMLSettings::KHTMLSettings(const KHTMLSettings &other)
00133 {
00134   d = new KHTMLSettingsPrivate();
00135   *d = *other.d;
00136 }
00137 
00138 KHTMLSettings::~KHTMLSettings()
00139 {
00140   delete d;
00141 }
00142 
00143 bool KHTMLSettings::changeCursor() const
00144 {
00145   return d->m_bChangeCursor;
00146 }
00147 
00148 bool KHTMLSettings::underlineLink() const
00149 {
00150   return d->m_underlineLink;
00151 }
00152 
00153 bool KHTMLSettings::hoverLink() const
00154 {
00155   return d->m_hoverLink;
00156 }
00157 
00158 void KHTMLSettings::init()
00159 {
00160   KConfig global( "khtmlrc", true, false );
00161   init( &global, true );
00162 
00163   KConfig *local = KGlobal::config();
00164   if ( !local )
00165     return;
00166 
00167   init( local, false );
00168 }
00169 
00170 void KHTMLSettings::init( KConfig * config, bool reset )
00171 {
00172   QString group_save = config->group();
00173   if (reset || config->hasGroup("MainView Settings"))
00174   {
00175     config->setGroup( "MainView Settings" );
00176     if ( reset || config->hasKey( "BackRightClick" ) )
00177         d->m_bBackRightClick = config->readBoolEntry( "BackRightClick", false );
00178   }
00179   
00180   if (reset || config->hasGroup("HTML Settings"))
00181   {
00182     config->setGroup( "HTML Settings" );
00183     // Fonts and colors
00184     if( reset ) {
00185         d->defaultFonts = QStringList();
00186         d->defaultFonts.append( config->readEntry( "StandardFont", KGlobalSettings::generalFont().family() ) );
00187         d->defaultFonts.append( config->readEntry( "FixedFont", KGlobalSettings::fixedFont().family() ) );
00188         d->defaultFonts.append( config->readEntry( "SerifFont", HTML_DEFAULT_VIEW_SERIF_FONT ) );
00189         d->defaultFonts.append( config->readEntry( "SansSerifFont", HTML_DEFAULT_VIEW_SANSSERIF_FONT ) );
00190         d->defaultFonts.append( config->readEntry( "CursiveFont", HTML_DEFAULT_VIEW_CURSIVE_FONT ) );
00191         d->defaultFonts.append( config->readEntry( "FantasyFont", HTML_DEFAULT_VIEW_FANTASY_FONT ) );
00192         d->defaultFonts.append( QString( "0" ) ); // font size adjustment
00193     }
00194 
00195     if ( reset || config->hasKey( "MinimumFontSize" ) )
00196         d->m_minFontSize = config->readNumEntry( "MinimumFontSize", HTML_DEFAULT_MIN_FONT_SIZE );
00197 
00198     if ( reset || config->hasKey( "MediumFontSize" ) )
00199         d->m_fontSize = config->readNumEntry( "MediumFontSize", 10 );
00200 
00201     d->fonts = config->readListEntry( "Fonts" );
00202 
00203     if ( reset || config->hasKey( "DefaultEncoding" ) ) {
00204         d->m_encoding = config->readEntry( "DefaultEncoding", "" );
00205         if ( d->m_encoding.isEmpty() )
00206             d->m_encoding = KGlobal::locale()->encoding();
00207     }
00208 
00209     if ( reset || config->hasKey( "EnforceDefaultCharset" ) )
00210         d->enforceCharset = config->readBoolEntry( "EnforceDefaultCharset", false );
00211 
00212     // Behaviour
00213     if ( reset || config->hasKey( "ChangeCursor" ) )
00214         d->m_bChangeCursor = config->readBoolEntry( "ChangeCursor", KDE_DEFAULT_CHANGECURSOR );
00215 
00216     if ( reset || config->hasKey("UnderlineLinks") )
00217         d->m_underlineLink = config->readBoolEntry( "UnderlineLinks", true );
00218 
00219     if ( reset || config->hasKey( "HoverLinks" ) )
00220     {
00221         if ( ( d->m_hoverLink = config->readBoolEntry( "HoverLinks", false ) ) )
00222             d->m_underlineLink = false;
00223     }
00224 
00225     // Other
00226     if ( reset || config->hasKey( "AutoLoadImages" ) )
00227       d->m_bAutoLoadImages = config->readBoolEntry( "AutoLoadImages", true );
00228 
00229     if ( reset || config->hasKey( "ShowAnimations" ) )
00230     {
00231       QString value = config->readEntry( "ShowAnimations").lower();
00232       if (value == "disabled")
00233          d->m_showAnimations = KAnimationDisabled;
00234       else if (value == "looponce")
00235          d->m_showAnimations = KAnimationLoopOnce;
00236       else
00237          d->m_showAnimations = KAnimationEnabled;
00238     }
00239 
00240     if ( config->readBoolEntry( "UserStyleSheetEnabled", false ) == true ) {
00241         if ( reset || config->hasKey( "UserStyleSheet" ) )
00242             d->m_userSheet = config->readEntry( "UserStyleSheet", "" );
00243     }
00244 
00245     d->m_formCompletionEnabled = config->readBoolEntry("FormCompletion", true);
00246     d->m_maxFormCompletionItems = config->readNumEntry("MaxFormCompletionItems", 10);
00247     d->m_autoDelayedActionsEnabled = config->readBoolEntry ("AutoDelayedActions", true);
00248   }
00249 
00250   // Colors
00251   if ( reset || config->hasGroup( "General" ) )
00252   {
00253     config->setGroup( "General" ); // group will be restored by cgs anyway
00254     if ( reset || config->hasKey( "foreground" ) )
00255       d->m_textColor = config->readColorEntry( "foreground", &HTML_DEFAULT_TXT_COLOR );
00256 
00257     if ( reset || config->hasKey( "linkColor" ) )
00258       d->m_linkColor = config->readColorEntry( "linkColor", &HTML_DEFAULT_LNK_COLOR );
00259 
00260     if ( reset || config->hasKey( "visitedLinkColor" ) )
00261       d->m_vLinkColor = config->readColorEntry( "visitedLinkColor", &HTML_DEFAULT_VLNK_COLOR);
00262   }
00263 
00264 
00265   if( reset || config->hasGroup( "Java/JavaScript Settings" ) )
00266   {
00267     config->setGroup( "Java/JavaScript Settings" );
00268 
00269     // The global setting for Java
00270     if ( reset || config->hasKey( "EnableJava" ) )
00271       d->m_bEnableJava = config->readBoolEntry( "EnableJava", false );
00272 
00273     // The global setting for JavaScript
00274     if ( reset || config->hasKey( "EnableJavaScript" ) )
00275       d->m_bEnableJavaScript = config->readBoolEntry( "EnableJavaScript", true );
00276 
00277     // The global setting for JavaScript debugging
00278     if ( reset || config->hasKey( "EnableJavaScriptDebug" ) )
00279       d->m_bEnableJavaScriptDebug = config->readBoolEntry( "EnableJavaScriptDebug", false );
00280 
00281     // The global setting for Plugins (there's no local setting yet)
00282     if ( reset || config->hasKey( "EnablePlugins" ) )
00283       d->m_bEnablePlugins = config->readBoolEntry( "EnablePlugins", true );
00284 
00285     // The domain-specific settings.
00286     bool check_old_java = true;
00287     if( reset || config->hasKey( "JavaDomainSettings" ) )
00288     {
00289       check_old_java = false;
00290       QStringList domainList = config->readListEntry( "JavaDomainSettings" );
00291       for ( QStringList::ConstIterator it = domainList.begin();
00292                 it != domainList.end(); ++it)
00293       {
00294         QString domain;
00295         KJavaScriptAdvice javaAdvice;
00296         KJavaScriptAdvice javaScriptAdvice;
00297         splitDomainAdvice(*it, domain, javaAdvice, javaScriptAdvice);
00298         d->javaDomainPolicy[domain] = javaAdvice;
00299       }
00300     }
00301 
00302     bool check_old_ecma = true;
00303     if( reset || config->hasKey( "ECMADomainSettings" ) )
00304     {
00305       check_old_ecma = false;
00306       QStringList domainList = config->readListEntry( "ECMADomainSettings" );
00307       for ( QStringList::ConstIterator it = domainList.begin();
00308                 it != domainList.end(); ++it)
00309       {
00310         QString domain;
00311         KJavaScriptAdvice javaAdvice;
00312         KJavaScriptAdvice javaScriptAdvice;
00313         splitDomainAdvice(*it, domain, javaAdvice, javaScriptAdvice);
00314         d->javaScriptDomainPolicy[domain] = javaScriptAdvice;
00315       }
00316     }
00317 
00318     if( reset || config->hasKey( "JavaScriptDomainAdvice" )
00319              && ( check_old_java || check_old_ecma ) )
00320     {
00321       QStringList domainList = config->readListEntry( "JavaScriptDomainAdvice" );
00322       for ( QStringList::ConstIterator it = domainList.begin();
00323                 it != domainList.end(); ++it)
00324       {
00325         QString domain;
00326         KJavaScriptAdvice javaAdvice;
00327         KJavaScriptAdvice javaScriptAdvice;
00328         splitDomainAdvice(*it, domain, javaAdvice, javaScriptAdvice);
00329         if( check_old_java )
00330           d->javaDomainPolicy[domain] = javaAdvice;
00331         if( check_old_ecma )
00332           d->javaScriptDomainPolicy[domain] = javaScriptAdvice;
00333       }
00334 
00335       //save all the settings into the new keywords if they don't exist
00336       if( check_old_java )
00337       {
00338         QStringList domainConfig;
00339         PolicyMap::Iterator it;
00340         for( it = d->javaDomainPolicy.begin(); it != d->javaDomainPolicy.end(); ++it )
00341         {
00342           QCString javaPolicy = adviceToStr( it.data() );
00343           QCString javaScriptPolicy = adviceToStr( KJavaScriptDunno );
00344           domainConfig.append(QString::fromLatin1("%1:%2:%3").arg(it.key()).arg(javaPolicy).arg(javaScriptPolicy));
00345         }
00346         config->writeEntry( "JavaDomainSettings", domainConfig );
00347       }
00348 
00349       if( check_old_ecma )
00350       {
00351         QStringList domainConfig;
00352         PolicyMap::Iterator it;
00353         for( it = d->javaScriptDomainPolicy.begin(); it != d->javaScriptDomainPolicy.end(); ++it )
00354         {
00355           QCString javaPolicy = adviceToStr( KJavaScriptDunno );
00356           QCString javaScriptPolicy = adviceToStr( it.data() );
00357           domainConfig.append(QString::fromLatin1("%1:%2:%3").arg(it.key()).arg(javaPolicy).arg(javaScriptPolicy));
00358         }
00359         config->writeEntry( "ECMADomainSettings", domainConfig );
00360       }
00361     }
00362   }
00363   config->setGroup(group_save);
00364 }
00365 
00366 
00367 // Local helper for isJavaEnabled & isJavaScriptEnabled.
00368 static bool lookup_hostname_policy(const QString& hostname,
00369                                    const PolicyMap& policy,
00370                                    const bool default_retval)
00371 {
00372   if (hostname.isEmpty()) {
00373     return default_retval;
00374   }
00375 
00376   // First check whether there is a perfect match.
00377   if( policy.contains( hostname ) ) {
00378     // yes, use it (unless dunno)
00379     KHTMLSettings::KJavaScriptAdvice adv = policy[ hostname ];
00380     if( adv == KHTMLSettings::KJavaScriptReject ) {
00381       return false;
00382     } else if( adv == KHTMLSettings::KJavaScriptAccept ) {
00383       return true;
00384     }
00385   }
00386 
00387   // Now, check for partial match.  Chop host from the left until
00388   // there's no dots left.
00389   QString host_part = hostname;
00390   int dot_idx = -1;
00391   while( (dot_idx = host_part.find(QChar('.'))) >= 0 ) {
00392     host_part.remove(0,dot_idx);
00393     if( policy.contains( host_part ) ) {
00394       KHTMLSettings::KJavaScriptAdvice adv = policy[ host_part ];
00395       if( adv == KHTMLSettings::KJavaScriptReject ) {
00396         return false;
00397       } else if( adv == KHTMLSettings::KJavaScriptAccept ) {
00398         return true;
00399       }
00400     }
00401     // assert(host_part[0] == QChar('.'));
00402     host_part.remove(0,1); // Chop off the dot.
00403   }
00404 
00405   // No domain-specific entry, or was dunno: use global setting
00406   return default_retval;
00407 }
00408 
00409 bool KHTMLSettings::isBackRightClickEnabled()
00410 {
00411   return d->m_bBackRightClick;
00412 }
00413 
00414 bool KHTMLSettings::isJavaEnabled( const QString& hostname )
00415 {
00416   return lookup_hostname_policy(hostname.lower(), d->javaDomainPolicy, d->m_bEnableJava);
00417 }
00418 
00419 bool KHTMLSettings::isJavaScriptEnabled( const QString& hostname )
00420 {
00421   return lookup_hostname_policy(hostname.lower(), d->javaScriptDomainPolicy, d->m_bEnableJavaScript);
00422 }
00423 
00424 bool KHTMLSettings::isJavaScriptDebugEnabled( const QString& /*hostname*/ )
00425 {
00426   // debug setting is global for now, but could change in the future
00427   return d->m_bEnableJavaScriptDebug;
00428 }
00429 
00430 bool KHTMLSettings::isPluginsEnabled( const QString& /* hostname */ )
00431 {
00432   // FIXME: hostname is ignored (dnaber, 2001-01-03)
00433   return d->m_bEnablePlugins;
00434 }
00435 
00436 int KHTMLSettings::mediumFontSize() const
00437 {
00438     return d->m_fontSize;
00439 }
00440 
00441 int KHTMLSettings::minFontSize() const
00442 {
00443   return d->m_minFontSize;
00444 }
00445 
00446 QString KHTMLSettings::settingsToCSS() const
00447 {
00448     // lets start with the link properties
00449     QString str = "a:link {\ncolor: ";
00450     str += d->m_linkColor.name();
00451     str += ";";
00452     if(d->m_underlineLink)
00453         str += "\ntext-decoration: underline;";
00454 
00455     if( d->m_bChangeCursor )
00456     {
00457         str += "\ncursor: pointer;";
00458         str += "\n}\ninput[type=image] { cursor: pointer;";
00459     }
00460     str += "\n}\n";
00461     str += "a:visited {\ncolor: ";
00462     str += d->m_vLinkColor.name();
00463     str += ";";
00464     if(d->m_underlineLink)
00465         str += "\ntext-decoration: underline;";
00466 
00467     if( d->m_bChangeCursor )
00468         str += "\ncursor: pointer;";
00469     str += "\n}\n";
00470 
00471     if(d->m_hoverLink)
00472         str += "a:link:hover, a:visited:hover { text-decoration: underline; }\n";
00473 
00474     return str;
00475 }
00476 
00477 const QString &KHTMLSettings::availableFamilies()
00478 {
00479     if ( !avFamilies ) {
00480         avFamilies = new QString;
00481         QFontDatabase db;
00482         QStringList families = db.families();
00483         QStringList s;
00484         QRegExp foundryExp(" \\[.+\\]");
00485 
00486         //remove foundry info
00487         for ( QStringList::Iterator f = families.begin(); f != families.end(); ++f ) {
00488                 (*f).replace( foundryExp, "");
00489                 if (!s.contains(*f))
00490                         s << *f;
00491         }
00492         s.sort();
00493 
00494         *avFamilies = s.join(",");
00495     }
00496 
00497   return *avFamilies;
00498 }
00499 
00500 QString KHTMLSettings::lookupFont(int i) const
00501 {
00502     QString font;
00503     if (d->fonts.count() > (uint) i)
00504        font = d->fonts[i];
00505     if (font.isEmpty())
00506         font = d->defaultFonts[i];
00507     return font;
00508 }
00509 
00510 QString KHTMLSettings::stdFontName() const
00511 {
00512     return lookupFont(0);
00513 }
00514 
00515 QString KHTMLSettings::fixedFontName() const
00516 {
00517     return lookupFont(1);
00518 }
00519 
00520 QString KHTMLSettings::serifFontName() const
00521 {
00522     return lookupFont(2);
00523 }
00524 
00525 QString KHTMLSettings::sansSerifFontName() const
00526 {
00527     return lookupFont(3);
00528 }
00529 
00530 QString KHTMLSettings::cursiveFontName() const
00531 {
00532     return lookupFont(4);
00533 }
00534 
00535 QString KHTMLSettings::fantasyFontName() const
00536 {
00537     return lookupFont(5);
00538 }
00539 
00540 void KHTMLSettings::setStdFontName(const QString &n)
00541 {
00542     while(d->fonts.count() <= 0)
00543         d->fonts.append(QString::null);
00544     d->fonts[0] = n;
00545 }
00546 
00547 void KHTMLSettings::setFixedFontName(const QString &n)
00548 {
00549     while(d->fonts.count() <= 1)
00550         d->fonts.append(QString::null);
00551     d->fonts[1] = n;
00552 }
00553 
00554 QString KHTMLSettings::userStyleSheet() const
00555 {
00556     return d->m_userSheet;
00557 }
00558 
00559 bool KHTMLSettings::isFormCompletionEnabled() const
00560 {
00561   return d->m_formCompletionEnabled;
00562 }
00563 
00564 int KHTMLSettings::maxFormCompletionItems() const
00565 {
00566   return d->m_maxFormCompletionItems;
00567 }
00568 
00569 const QString &KHTMLSettings::encoding() const
00570 {
00571   return d->m_encoding;
00572 }
00573 
00574 const QColor& KHTMLSettings::textColor() const
00575 {
00576   return d->m_textColor;
00577 }
00578 
00579 const QColor& KHTMLSettings::linkColor() const
00580 {
00581   return d->m_linkColor;
00582 }
00583 
00584 const QColor& KHTMLSettings::vLinkColor() const
00585 {
00586   return d->m_vLinkColor;
00587 }
00588 
00589 bool KHTMLSettings::autoLoadImages() const
00590 {
00591   return d->m_bAutoLoadImages;
00592 }
00593 
00594 KHTMLSettings::KAnimationAdvice KHTMLSettings::showAnimations() const
00595 {
00596   return d->m_showAnimations;
00597 }
00598 
00599 bool KHTMLSettings::isAutoDelayedActionsEnabled() const
00600 {
00601   return d->m_autoDelayedActionsEnabled;
00602 }
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.4.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Sun Feb 27 22:16:37 2005 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001