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