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 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
00114 javaAdvice = strToAdvice( adviceString );
00115 javaScriptAdvice = KJavaScriptDunno;
00116 } else {
00117
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
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" ) );
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
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
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
00251 if ( reset || config->hasGroup( "General" ) )
00252 {
00253 config->setGroup( "General" );
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
00270 if ( reset || config->hasKey( "EnableJava" ) )
00271 d->m_bEnableJava = config->readBoolEntry( "EnableJava", false );
00272
00273
00274 if ( reset || config->hasKey( "EnableJavaScript" ) )
00275 d->m_bEnableJavaScript = config->readBoolEntry( "EnableJavaScript", true );
00276
00277
00278 if ( reset || config->hasKey( "EnableJavaScriptDebug" ) )
00279 d->m_bEnableJavaScriptDebug = config->readBoolEntry( "EnableJavaScriptDebug", false );
00280
00281
00282 if ( reset || config->hasKey( "EnablePlugins" ) )
00283 d->m_bEnablePlugins = config->readBoolEntry( "EnablePlugins", true );
00284
00285
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
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
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
00377 if( policy.contains( hostname ) ) {
00378
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
00388
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
00402 host_part.remove(0,1);
00403 }
00404
00405
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& )
00425 {
00426
00427 return d->m_bEnableJavaScriptDebug;
00428 }
00429
00430 bool KHTMLSettings::isPluginsEnabled( const QString& )
00431 {
00432
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
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
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 }