00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <config.h>
00033
00034 #include "csshelper.h"
00035
00036 #include "kmkernel.h"
00037
00038 #include <kconfig.h>
00039 #include <kglobalsettings.h>
00040 #include <kdebug.h>
00041 #include <kglobal.h>
00042
00043 #include <qcolor.h>
00044 #include <qfont.h>
00045 #include <qstring.h>
00046 #include <qapplication.h>
00047
00048 #include <cassert>
00049
00050 namespace KMail {
00051
00052 class CSSHelper::Private {
00053 friend class CSSHelper;
00054 public:
00055 Private() {}
00056 ~Private() {}
00057
00058 bool operator==( const Private & other ) const;
00059 bool operator!=( const Private & other ) const {
00060 return !operator==( other );
00061 }
00062
00063 void readColorConfig();
00064
00065
00066 QString printCssDefinitions() const;
00067
00068
00069 QString screenCssDefinitions( const CSSHelper * helper, bool fixed ) const;
00070
00071
00072 QString commonCssDefinitions() const;
00073
00074 QFont bodyFont( bool fixed, bool print=false ) const {
00075 return fixed ? mFixedFont : print ? mPrintFont : mBodyFont ;
00076 }
00077 int fontSize( bool fixed, bool print=false ) const {
00078 return bodyFont( fixed, print ).pointSize();
00079 }
00080
00081 QString quoteFontTag( int level ) const;
00082
00083 private:
00084 QFont mBodyFont, mPrintFont, mFixedFont;
00085 QFont mQuoteFont[3];
00086 QColor mQuoteColor[3];
00087 bool mRecycleQuoteColors;
00088 bool mBackingPixmapOn;
00089 QString mBackingPixmapStr;
00090 QColor c1, c2, c3, c4;
00091
00092 QColor cPgpOk1F, cPgpOk1H, cPgpOk1B,
00093 cPgpOk0F, cPgpOk0H, cPgpOk0B,
00094 cPgpWarnF, cPgpWarnH, cPgpWarnB,
00095 cPgpErrF, cPgpErrH, cPgpErrB,
00096 cPgpEncrF, cPgpEncrH, cPgpEncrB;
00097
00098 QColor cHtmlWarning;
00099 };
00100
00101 bool CSSHelper::Private::operator==( const Private & other ) const {
00102 for ( int i = 0 ; i < 3 ; ++i )
00103 if ( mQuoteFont[i] != other.mQuoteFont[i] ||
00104 mQuoteColor[i] != other.mQuoteColor[i] )
00105 return false;
00106 return
00107 mBodyFont == other.mBodyFont &&
00108 mPrintFont == other.mPrintFont &&
00109 mFixedFont == other.mFixedFont &&
00110 mRecycleQuoteColors == other.mRecycleQuoteColors &&
00111 mBackingPixmapOn == other.mBackingPixmapOn &&
00112 mBackingPixmapStr == other.mBackingPixmapStr &&
00113 c1 == other.c1 && c2 == other.c2 && c3 == other.c3 && c4 == other.c4 &&
00114 cHtmlWarning == other.cHtmlWarning &&
00115 cPgpOk1F == other.cPgpOk1F && cPgpOk1H == other.cPgpOk1H && cPgpOk1B == other.cPgpOk1B &&
00116 cPgpOk0F == other.cPgpOk0F && cPgpOk0H == other.cPgpOk0H && cPgpOk0B == other.cPgpOk0B &&
00117 cPgpWarnF == other.cPgpWarnF && cPgpWarnH == other.cPgpWarnH && cPgpWarnB == other.cPgpWarnB &&
00118 cPgpErrF == other.cPgpErrF && cPgpErrH == other.cPgpErrH && cPgpErrB == other.cPgpErrB &&
00119 cPgpEncrF == other.cPgpEncrF && cPgpEncrH == other.cPgpEncrH && cPgpEncrB == other.cPgpEncrB ;
00120 }
00121
00122 namespace {
00123
00124 inline QColor darker( const QColor & c ) {
00125 int h, s, v;
00126 c.hsv( &h, &s, &v );
00127 return QColor( h, s, v*4/5, QColor::Hsv );
00128 }
00129
00130 inline QColor desaturate( const QColor & c ) {
00131 int h, s, v;
00132 c.hsv( &h, &s, &v );
00133 return QColor( h, s/8, v, QColor::Hsv );
00134 }
00135
00136 inline QColor fixValue( const QColor & c, int newV ) {
00137 int h, s, v;
00138 c.hsv( &h, &s, &v );
00139 return QColor( h, s, newV, QColor::Hsv );
00140 }
00141
00142 inline int getValueOf( const QColor & c ) {
00143 int h, s, v;
00144 c.hsv( &h, &s, &v );
00145 return v;
00146 }
00147 }
00148
00149 void CSSHelper::Private::readColorConfig() {
00150 KConfig * config = KMKernel::config();
00151
00152 KConfigGroup reader( config, "Reader" );
00153 KConfigGroup fonts( config, "Fonts" );
00154 KConfigGroup pixmaps( config, "Pixmaps" );
00155
00156 c1 = QApplication::palette().active().text();
00157 c2 = KGlobalSettings::linkColor();
00158 c3 = KGlobalSettings::visitedLinkColor();
00159 c4 = QApplication::palette().active().base();
00160 cHtmlWarning = QColor( 0xFF, 0x40, 0x40 );
00161
00162
00163 cPgpEncrH = QColor( 0x00, 0x80, 0xFF );
00164 cPgpOk1H = QColor( 0x40, 0xFF, 0x40 );
00165 cPgpOk0H = QColor( 0xFF, 0xFF, 0x40 );
00166 cPgpWarnH = QColor( 0xFF, 0xFF, 0x40 );
00167 cPgpErrH = Qt::red;
00168
00169 for ( int i = 0 ; i < 3 ; ++i )
00170 mQuoteColor[i] = QColor( 0x00, 0x80 - i * 0x10, 0x00 );
00171 mRecycleQuoteColors = reader.readBoolEntry( "RecycleQuoteColors", false );
00172
00173 if ( !reader.readBoolEntry( "defaultColors", true ) ) {
00174 c1 = reader.readColorEntry("ForegroundColor",&c1);
00175 c2 = reader.readColorEntry("LinkColor",&c2);
00176 c3 = reader.readColorEntry("FollowedColor",&c3);
00177 c4 = reader.readColorEntry("BackgroundColor",&c4);
00178 cPgpEncrH = reader.readColorEntry( "PGPMessageEncr", &cPgpEncrH );
00179 cPgpOk1H = reader.readColorEntry( "PGPMessageOkKeyOk", &cPgpOk1H );
00180 cPgpOk0H = reader.readColorEntry( "PGPMessageOkKeyBad", &cPgpOk0H );
00181 cPgpWarnH = reader.readColorEntry( "PGPMessageWarn", &cPgpWarnH );
00182 cPgpErrH = reader.readColorEntry( "PGPMessageErr", &cPgpErrH );
00183 cHtmlWarning = reader.readColorEntry( "HTMLWarningColor", &cHtmlWarning );
00184 for ( int i = 0 ; i < 3 ; ++i ) {
00185 const QString key = "QuotedText" + QString::number( i+1 );
00186 mQuoteColor[i] = reader.readColorEntry( key, &mQuoteColor[i] );
00187 }
00188 }
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201 const int vBG = getValueOf( c4 );
00202 const bool lightBG = vBG >= 128;
00203 if ( cPgpOk1H == c4 ) {
00204 cPgpOk1F = c4;
00205 cPgpOk1B = c4;
00206 } else {
00207 cPgpOk1F= darker( cPgpOk1H );
00208 cPgpOk1B = lightBG ? desaturate( cPgpOk1H ) : fixValue( cPgpOk1H, vBG );
00209 }
00210 if ( cPgpOk0H == c4 ) {
00211 cPgpOk0F = c4;
00212 cPgpOk0B = c4;
00213 } else {
00214 cPgpOk0F = darker( cPgpOk0H );
00215 cPgpOk0B = lightBG ? desaturate( cPgpOk0H ) : fixValue( cPgpOk0H, vBG );
00216 }
00217 if ( cPgpWarnH == c4 ) {
00218 cPgpWarnF = c4;
00219 cPgpWarnB = c4;
00220 } else {
00221 cPgpWarnF = darker( cPgpWarnH );
00222 cPgpWarnB = lightBG ? desaturate( cPgpWarnH ) : fixValue( cPgpWarnH, vBG );
00223 }
00224 if ( cPgpErrH == c4 ) {
00225 cPgpErrF = c4;
00226 cPgpErrB = c4;
00227 } else {
00228 cPgpErrF = darker( cPgpErrH );
00229 cPgpErrB = lightBG ? desaturate( cPgpErrH ) : fixValue( cPgpErrH, vBG );
00230 }
00231 if ( cPgpEncrH == c4 ) {
00232 cPgpEncrF = c4;
00233 cPgpEncrB = c4;
00234 } else {
00235 cPgpEncrF = darker( cPgpEncrH );
00236 cPgpEncrB = lightBG ? desaturate( cPgpEncrH ) : fixValue( cPgpEncrH, vBG );
00237 }
00238
00239 QFont defaultFont = KGlobalSettings::generalFont();
00240 if ( fonts.readBoolEntry( "defaultFonts", true ) ) {
00241 mBodyFont = mPrintFont = defaultFont;
00242 mFixedFont = KGlobalSettings::fixedFont();
00243 defaultFont.setItalic( true );
00244 for ( int i = 0 ; i < 3 ; ++i )
00245 mQuoteFont[i] = defaultFont;
00246 } else {
00247 mBodyFont = fonts.readFontEntry( "body-font", &defaultFont);
00248 mPrintFont = fonts.readFontEntry( "print-font", &defaultFont);
00249 mFixedFont = fonts.readFontEntry( "fixed-font", &defaultFont);
00250 defaultFont.setItalic( true );
00251 for ( int i = 0 ; i < 3 ; ++i ) {
00252 const QString key = QString( "quote%1-font" ).arg( i+1 );
00253 mQuoteFont[i] = fonts.readFontEntry( key, &defaultFont );
00254 }
00255 }
00256
00257 mBackingPixmapStr = pixmaps.readPathEntry("Readerwin");
00258 mBackingPixmapOn = !mBackingPixmapStr.isEmpty();
00259 }
00260
00261 CSSHelper::CSSHelper( const QPaintDeviceMetrics & pdm, QObject * parent, const char * name )
00262 : ConfigManager( parent, name ),
00263 d( 0 ), s( 0 ), mMetrics( pdm )
00264 {
00265 d = new Private();
00266 d->readColorConfig();
00267 }
00268
00269 CSSHelper::~CSSHelper() {
00270 kdWarning( hasPendingChanges(), 5006 )
00271 << "CSSHelper: There were uncommitted changes!" << endl;
00272 delete d; d = 0;
00273 delete s; s = 0;
00274 }
00275
00276 void CSSHelper::commit() {
00277
00278 }
00279
00280 void CSSHelper::rollback() {
00281 delete s; s = 0;
00282 }
00283
00284 bool CSSHelper::hasPendingChanges() const {
00285 assert( d );
00286 return s && *s != *d ;
00287 }
00288
00289 QString CSSHelper::cssDefinitions( bool fixed ) const {
00290 assert( d );
00291 return
00292 d->commonCssDefinitions()
00293 +
00294 "@media screen {\n\n"
00295 +
00296 d->screenCssDefinitions( this, fixed )
00297 +
00298 "}\n"
00299 "@media print {\n\n"
00300 +
00301 d->printCssDefinitions()
00302 +
00303 "}\n";
00304 }
00305
00306 QString CSSHelper::htmlHead( bool fixed ) const {
00307 return
00308 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n"
00309 "<html><head><title></title></head>\n"
00310 +
00311 QString( fixed ? "<body class\"fixedfont\">\n" : "<body>\n" );
00312 }
00313
00314 QString CSSHelper::Private::quoteFontTag( int level ) const {
00315 if ( level < 0 )
00316 level = 0;
00317 static const int numQuoteLevels = sizeof mQuoteFont / sizeof *mQuoteFont ;
00318 const int effectiveLevel = mRecycleQuoteColors
00319 ? level % numQuoteLevels + 1
00320 : kMin( level + 1, numQuoteLevels ) ;
00321 return QString( "<div class=\"quotelevel%1\">" ).arg( effectiveLevel );
00322 }
00323
00324 QString CSSHelper::quoteFontTag( int level ) const {
00325 assert( d );
00326 return d->quoteFontTag( level );
00327 }
00328
00329 QString CSSHelper::nonQuotedFontTag() const {
00330 return "<div class=\"noquote\">";
00331 }
00332
00333 QFont CSSHelper::bodyFont( bool fixed, bool print ) const {
00334 assert( d );
00335 return d->bodyFont( fixed, print );
00336 }
00337
00338 namespace {
00339 int pointsToPixel( const QPaintDeviceMetrics & metrics, int pointSize ) {
00340 return ( pointSize * metrics.logicalDpiY() + 36 ) / 72 ;
00341 }
00342 }
00343
00344 QString CSSHelper::Private::printCssDefinitions() const {
00345 const QString headerFont = QString( " font-family: \"%1\" ! important;\n"
00346 " font-size: %2pt ! important;\n" )
00347 .arg( mPrintFont.family() )
00348 .arg( mPrintFont.pointSize() );
00349 const QColorGroup & cg = QApplication::palette().active();
00350
00351 QString quoteCSS;
00352 if ( mPrintFont.italic() )
00353 quoteCSS += " font-style: italic ! important;\n";
00354 if ( mPrintFont.bold() )
00355 quoteCSS += " font-weight: bold ! important;\n";
00356 if ( !quoteCSS.isEmpty() )
00357 quoteCSS = "div.noquote {\n" + quoteCSS + "}\n\n";
00358
00359 return
00360 QString( "body {\n"
00361 " font-family: \"%1\" ! important;\n"
00362 " font-size: %2pt ! important;\n"
00363 " color: #000000 ! important;\n"
00364 " background-color: #ffffff ! important\n"
00365 "}\n\n" )
00366 .arg( mPrintFont.family(),
00367 QString::number( mPrintFont.pointSize() ) )
00368 +
00369 QString( "tr.textAtmH,\n"
00370 "tr.rfc822H,\n"
00371 "tr.encrH,\n"
00372 "tr.signOkKeyOkH,\n"
00373 "tr.signOkKeyBadH,\n"
00374 "tr.signWarnH,\n"
00375 "tr.signErrH,\n"
00376 "div.header {\n"
00377 "%1"
00378 "}\n\n"
00379
00380 "div.fancy.header > div {\n"
00381 " background-color: %2 ! important;\n"
00382 " color: %3 ! important;\n"
00383 " padding: 4px ! important;\n"
00384 " border: solid %3 1px ! important;\n"
00385 "}\n\n"
00386
00387 "div.fancy.header > div a[href] { color: %3 ! important; }\n\n"
00388
00389 "div.fancy.header table {\n"
00390 " background-color: %2 ! important;\n"
00391 " color: %3 ! important;\n"
00392 " border-bottom: solid %3 1px ! important;\n"
00393 " border-left: solid %3 1px ! important;\n"
00394 " border-right: solid %3 1px ! important;\n"
00395 "}\n\n"
00396
00397 "div.htmlWarn {\n"
00398 " border: 2px solid #ffffff ! important;\n"
00399 "}\n\n" )
00400 .arg( headerFont,
00401 cg.background().name(),
00402 cg.foreground().name() )
00403 + quoteCSS;
00404 }
00405
00406 QString CSSHelper::Private::screenCssDefinitions( const CSSHelper * helper, bool fixed ) const {
00407 const QString fgColor = c1.name();
00408 const QString bgColor = c4.name();
00409 const QString linkColor = c2.name();
00410 const QString headerFont = QString(" font-family: \"%1\" ! important;\n"
00411 " font-size: %2px ! important;\n")
00412 .arg( mBodyFont.family() )
00413 .arg( pointsToPixel( helper->mMetrics, mBodyFont.pointSize() ) );
00414 const QString background = ( mBackingPixmapOn
00415 ? QString( " background-image:url(file://%1) ! important;\n" )
00416 .arg( mBackingPixmapStr )
00417 : QString( " background-color: %1 ! important;\n" )
00418 .arg( bgColor ) );
00419 const QString bodyFontSize = QString::number( pointsToPixel( helper->mMetrics, fontSize( fixed ) ) ) + "px" ;
00420 const QColorGroup & cg = QApplication::palette().active();
00421
00422 QString quoteCSS;
00423 if ( bodyFont( fixed ).italic() )
00424 quoteCSS += " font-style: italic ! important;\n";
00425 if ( bodyFont( fixed ).bold() )
00426 quoteCSS += " font-weight: bold ! important;\n";
00427 if ( !quoteCSS.isEmpty() )
00428 quoteCSS = "div.noquote {\n" + quoteCSS + "}\n\n";
00429
00430 for ( int i = 0 ; i < 3 ; ++i ) {
00431 quoteCSS += QString( "div.quotelevel%1 {\n"
00432 " color: %2 ! important;\n" )
00433 .arg( QString::number(i+1), mQuoteColor[i].name() );
00434 if ( mQuoteFont[i].italic() )
00435 quoteCSS += " font-style: italic ! important;\n";
00436 if ( mQuoteFont[i].bold() )
00437 quoteCSS += " font-weight: bold ! important;\n";
00438 quoteCSS += "}\n\n";
00439 }
00440
00441 return
00442 QString( "body {\n"
00443 " font-family: \"%1\" ! important;\n"
00444 " font-size: %2 ! important;\n"
00445 " color: %3 ! important;\n"
00446 "%4"
00447 "}\n\n" )
00448 .arg( bodyFont( fixed ).family(),
00449 bodyFontSize,
00450 fgColor,
00451 background )
00452 +
00453 QString( "a {\n"
00454 " color: %1 ! important;\n"
00455 " text-decoration: none ! important;\n"
00456 "}\n\n"
00457
00458 "table.textAtm { background-color: %2 ! important; }\n\n"
00459
00460 "tr.textAtmH {\n"
00461 " background-color: %3 ! important;\n"
00462 "%4"
00463 "}\n\n"
00464
00465 "tr.textAtmB {\n"
00466 " background-color: %3 ! important;\n"
00467 "}\n\n"
00468
00469 "table.rfc822 {\n"
00470 " background-color: %3 ! important;\n"
00471 "}\n\n"
00472
00473 "tr.rfc822H {\n"
00474 "%4"
00475 "}\n\n" )
00476 .arg( linkColor, fgColor, bgColor, headerFont )
00477 +
00478 QString( "table.encr {\n"
00479 " background-color: %1 ! important;\n"
00480 "}\n\n"
00481
00482 "tr.encrH {\n"
00483 " background-color: %2 ! important;\n"
00484 "%3"
00485 "}\n\n"
00486
00487 "tr.encrB { background-color: %4 ! important; }\n\n" )
00488 .arg( cPgpEncrF.name(),
00489 cPgpEncrH.name(),
00490 headerFont,
00491 cPgpEncrB.name() )
00492 +
00493 QString( "table.signOkKeyOk {\n"
00494 " background-color: %1 ! important;\n"
00495 "}\n\n"
00496
00497 "tr.signOkKeyOkH {\n"
00498 " background-color: %2 ! important;\n"
00499 "%3"
00500 "}\n\n"
00501
00502 "tr.signOkKeyOkB { background-color: %4 ! important; }\n\n" )
00503 .arg( cPgpOk1F.name(),
00504 cPgpOk1H.name(),
00505 headerFont,
00506 cPgpOk1B.name() )
00507 +
00508 QString( "table.signOkKeyBad {\n"
00509 " background-color: %1 ! important;\n"
00510 "}\n\n"
00511
00512 "tr.signOkKeyBadH {\n"
00513 " background-color: %2 ! important;\n"
00514 "%3"
00515 "}\n\n"
00516
00517 "tr.signOkKeyBadB { background-color: %4 ! important; }\n\n" )
00518 .arg( cPgpOk0F.name(),
00519 cPgpOk0H.name(),
00520 headerFont,
00521 cPgpOk0B.name() )
00522 +
00523 QString( "table.signWarn {\n"
00524 " background-color: %1 ! important;\n"
00525 "}\n\n"
00526
00527 "tr.signWarnH {\n"
00528 " background-color: %2 ! important;\n"
00529 "%3"
00530 "}\n\n"
00531
00532 "tr.signWarnB { background-color: %4 ! important; }\n\n" )
00533 .arg( cPgpWarnF.name(),
00534 cPgpWarnH.name(),
00535 headerFont,
00536 cPgpWarnB.name() )
00537 +
00538 QString( "table.signErr {\n"
00539 " background-color: %1 ! important;\n"
00540 "}\n\n"
00541
00542 "tr.signErrH {\n"
00543 " background-color: %2 ! important;\n"
00544 "%3"
00545 "}\n\n"
00546
00547 "tr.signErrB { background-color: %4 ! important; }\n\n" )
00548 .arg( cPgpErrF.name(),
00549 cPgpErrH.name(),
00550 headerFont,
00551 cPgpErrB.name() )
00552 +
00553 QString( "div.htmlWarn {\n"
00554 " border: 2px solid %1 ! important;\n"
00555 "}\n\n" )
00556 .arg( cHtmlWarning.name() )
00557 +
00558 QString( "div.header {\n"
00559 "%1"
00560 "}\n\n"
00561
00562 "div.fancy.header > div {\n"
00563 " background-color: %2 ! important;\n"
00564 " color: %3 ! important;\n"
00565 " border: solid %4 1px ! important;\n"
00566 "}\n\n"
00567
00568 "div.fancy.header > div a[href] { color: %3 ! important; }\n\n"
00569
00570 "div.fancy.header > div a[href]:hover { text-decoration: underline ! important; }\n\n"
00571
00572 "div.fancy.header table {\n"
00573 " background-color: %5 ! important;\n"
00574 " color: %4 ! important;\n"
00575 " border-bottom: solid %4 1px ! important;\n"
00576 " border-left: solid %4 1px ! important;\n"
00577 " border-right: solid %4 1px ! important;\n"
00578 "}\n\n" )
00579 .arg( headerFont )
00580 .arg( cg.highlight().name(),
00581 cg.highlightedText().name(),
00582 cg.foreground().name(),
00583 cg.background().name() )
00584 + quoteCSS;
00585 }
00586
00587 QString CSSHelper::Private::commonCssDefinitions() const {
00588 return
00589 "div.header {\n"
00590 " margin-bottom: 10pt ! important;\n"
00591 "}\n\n"
00592
00593 "table.textAtm {\n"
00594 " margin-top: 10pt ! important;\n"
00595 " margin-bottom: 10pt ! important;\n"
00596 "}\n\n"
00597
00598 "tr.textAtmH,\n"
00599 "tr.textAtmB,\n"
00600 "tr.rfc822B {\n"
00601 " font-weight: normal ! important;\n"
00602 "}\n\n"
00603
00604 "tr.rfc822H,\n"
00605 "tr.encrH,\n"
00606 "tr.signOkKeyOkH,\n"
00607 "tr.signOkKeyBadH,\n"
00608 "tr.signWarnH,\n"
00609 "tr.signErrH {\n"
00610 " font-weight: bold ! important;\n"
00611 "}\n\n"
00612
00613 "tr.textAtmH td,\n"
00614 "tr.textAtmB td {\n"
00615 " padding: 3px ! important;\n"
00616 "}\n\n"
00617
00618 "table.rfc822 {\n"
00619 " width: 100% ! important;\n"
00620 " border: solid 1px black ! important;\n"
00621 " margin-top: 10pt ! important;\n"
00622 " margin-bottom: 10pt ! important;\n"
00623 "}\n\n"
00624
00625 "table.textAtm,\n"
00626 "table.encr,\n"
00627 "table.signWarn,\n"
00628 "table.signErr,\n"
00629 "table.signOkKeyBad,\n"
00630 "table.signOkKeyOk,\n"
00631 "div.fancy.header table {\n"
00632 " width: 100% ! important;\n"
00633 " border-width: 0px ! important;\n"
00634 "}\n\n"
00635
00636 "div.htmlWarn {\n"
00637 " margin: 0px 5% ! important;\n"
00638 " padding: 10px ! important;\n"
00639 " text-align: left ! important;\n"
00640 "}\n\n"
00641
00642 "div.fancy.header > div {\n"
00643 " font-weight: bold ! important;\n"
00644 " padding: 4px ! important;\n"
00645 "}\n\n"
00646
00647 "div.fancy.header table {\n"
00648 " padding: 2px ! important;\n"
00649 " text-align: left ! important\n"
00650 "}\n\n"
00651
00652 "div.fancy.header table th {\n"
00653 " padding: 0px ! important;\n"
00654 " white-space: nowrap ! important;\n"
00655 " border-spacing: 0px ! important;\n"
00656 " text-align: left ! important;\n"
00657 " vertical-align: top ! important;\n"
00658 "}\n\n"
00659
00660 "div.fancy.header table td {\n"
00661 " padding: 0px ! important;\n"
00662 " border-spacing: 0px ! important;\n"
00663 " text-align: left ! important;\n"
00664 " vertical-align: top ! important;\n"
00665 " width: 100% ! important;\n"
00666 "}\n\n"
00667 ;
00668 }
00669
00670 }
00671