Messagelib

csshelperbase.cpp
1 /*
2  csshelper.cpp
3 
4  This file is part of KMail, the KDE mail client.
5  SPDX-FileCopyrightText: 2003 Marc Mutz <[email protected]>
6 
7  SPDX-License-Identifier: GPL-2.0-or-later
8 */
9 
10 #include "csshelperbase.h"
11 #include "header/headerstyleplugin.h"
12 #include "utils/iconnamecache.h"
13 
14 #include <QApplication>
15 #include <QPaintDevice>
16 #include <QPalette>
17 #include <QUrl>
18 
19 #define USE_HTML_STYLE_COLOR 1
20 namespace MessageViewer
21 {
22 namespace
23 {
24 // some QColor manipulators that hide the ugly QColor API w.r.t. HSV:
25 inline QColor darker(const QColor &c)
26 {
27  int h, s, v;
28  c.getHsv(&h, &s, &v);
29  return QColor::fromHsv(h, s, v * 4 / 5);
30 }
31 
32 inline QColor desaturate(const QColor &c)
33 {
34  int h, s, v;
35  c.getHsv(&h, &s, &v);
36  return QColor::fromHsv(h, s / 8, v);
37 }
38 
39 inline QColor fixValue(const QColor &c, int newV)
40 {
41  int h, s, v;
42  c.getHsv(&h, &s, &v);
43  return QColor::fromHsv(h, s, newV);
44 }
45 
46 inline int getValueOf(const QColor &c)
47 {
48  int h, s, v;
49  c.getHsv(&h, &s, &v);
50  return v;
51 }
52 
53 static const struct {
54  CSSHelperBase::InlineMessageType type;
55  const char *cssName;
56 } inlineMessageStyles[] = {{CSSHelperBase::Positive, "inlineMessagePositive"},
57  {CSSHelperBase::Information, "inlineMessageInformation"},
58  {CSSHelperBase::Warning, "inlineMessageWarning"},
59  {CSSHelperBase::Error, "inlineMessageError"}};
60 }
61 
63  : mPaintDevice(pd)
64 {
66  const QString imgSrcShow = QStringLiteral("quicklistClosed.png");
67  const QString imgSrcHide = QStringLiteral("quicklistOpened.png");
68  imgShowUrl = QUrl::fromLocalFile(MessageViewer::IconNameCache::instance()->iconPathFromLocal(imgSrcShow)).url();
69  imgHideUrl = QUrl::fromLocalFile(MessageViewer::IconNameCache::instance()->iconPathFromLocal(imgSrcHide)).url();
70 }
71 
72 CSSHelperBase::~CSSHelperBase()
73 {
74 }
75 
77 {
78  // determine the frame and body color for PGP messages from the header color
79  // if the header color equals the background color then the other colors are
80  // also set to the background color (-> old style PGP message viewing)
81  // else
82  // the brightness of the frame is set to 4/5 of the brightness of the header
83  // and in case of a light background color
84  // the saturation of the body is set to 1/8 of the saturation of the header
85  // while in case of a dark background color
86  // the value of the body is set to the value of the background color
87 
88  // Check whether the user uses a light color scheme
89  const int vBG = getValueOf(mBackgroundColor);
90  const bool lightBG = vBG >= 128;
91  if (cPgpOk1H == mBackgroundColor) {
92  cPgpOk1F = mBackgroundColor;
93  cPgpOk1B = mBackgroundColor;
94  } else {
95  cPgpOk1F = darker(cPgpOk1H);
96  cPgpOk1B = lightBG ? desaturate(cPgpOk1H) : fixValue(cPgpOk1H, vBG);
97  }
98  if (cPgpOk0H == mBackgroundColor) {
99  cPgpOk0F = mBackgroundColor;
100  cPgpOk0B = mBackgroundColor;
101  } else {
102  cPgpOk0F = darker(cPgpOk0H);
103  cPgpOk0B = lightBG ? desaturate(cPgpOk0H) : fixValue(cPgpOk0H, vBG);
104  }
105  if (cPgpWarnH == mBackgroundColor) {
106  cPgpWarnF = mBackgroundColor;
107  cPgpWarnB = mBackgroundColor;
108  } else {
109  cPgpWarnF = darker(cPgpWarnH);
110  cPgpWarnB = lightBG ? desaturate(cPgpWarnH) : fixValue(cPgpWarnH, vBG);
111  }
112  if (cPgpErrH == mBackgroundColor) {
113  cPgpErrF = mBackgroundColor;
114  cPgpErrB = mBackgroundColor;
115  } else {
116  cPgpErrF = darker(cPgpErrH);
117  cPgpErrB = lightBG ? desaturate(cPgpErrH) : fixValue(cPgpErrH, vBG);
118  }
119  if (cPgpEncrH == mBackgroundColor) {
120  cPgpEncrF = mBackgroundColor;
121  cPgpEncrB = mBackgroundColor;
122  } else {
123  cPgpEncrF = darker(cPgpEncrH);
124  cPgpEncrB = lightBG ? desaturate(cPgpEncrH) : fixValue(cPgpEncrH, vBG);
125  }
126 }
127 
128 QString CSSHelperBase::addEndBlockQuote(int numberBlock) const
129 {
130  QString blockQuote;
131  for (int i = 0; i < numberBlock; ++i) {
132  blockQuote += QLatin1String("</blockquote>");
133  }
134  return blockQuote;
135 }
136 
137 QString CSSHelperBase::addStartBlockQuote(int numberBlock) const
138 {
139  QString blockQuote;
140  for (int i = 0; i < numberBlock; ++i) {
141  blockQuote += QLatin1String("<blockquote>");
142  }
143  return blockQuote;
144 }
145 
146 QString CSSHelperBase::extraScreenCss(const QString &headerFont) const
147 {
148  if (mHeaderPlugin) {
149  return mHeaderPlugin->extraScreenCss(headerFont);
150  }
151  return {};
152 }
153 
154 QString CSSHelperBase::extraPrintCss(const QString &headerFont) const
155 {
156  if (mHeaderPlugin) {
157  return mHeaderPlugin->extraPrintCss(headerFont);
158  }
159  return {};
160 }
161 
162 QString CSSHelperBase::extraCommonCss(const QString &headerFont) const
163 {
164  QString result;
165  if (mHeaderPlugin) {
166  result = mHeaderPlugin->extraCommonCss(headerFont);
167  if (result.isEmpty()) {
168  // Add default value
169  result = QStringLiteral(
170  "div.header table {\n"
171  " width: 100% ! important;\n"
172  " border-width: 0px ! important;\n"
173  " line-height: normal;\n"
174  "}\n\n");
175  }
176  }
177  return result;
178 }
179 
181 {
182  return commonCssDefinitions() + QLatin1String("@media screen {\n\n") + screenCssDefinitions(this, fixed)
183  + QLatin1String(
184  "}\n"
185  "@media print {\n\n")
186  + printCssDefinitions(fixed) + QLatin1String("}\n");
187 }
188 
189 QString CSSHelperBase::htmlHead(bool fixedFont) const
190 {
191  Q_UNUSED(fixedFont)
192  return QStringLiteral(
193  "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n"
194  "<html><head><title></title></head>\n"
195  "<body>\n");
196 }
197 
199 {
200  if (level < 0) {
201  level = 0;
202  }
203  static const int numQuoteLevels = 3;
204  const int effectiveLevel = mRecycleQuoteColors ? level % numQuoteLevels + 1 : qMin(level + 1, numQuoteLevels);
205  if (level >= numQuoteLevels) {
206  return QStringLiteral("<div class=\"deepquotelevel%1\">").arg(effectiveLevel);
207  } else {
208  return QStringLiteral("<div class=\"quotelevel%1\">").arg(effectiveLevel);
209  }
210 }
211 
212 QString CSSHelperBase::fullAddressList() const
213 {
214  QString css = QStringLiteral(
215  "input[type=checkbox].addresslist_checkbox {display: none}\n"
216  ".addresslist_label_short {border: 1px; border-radius: 5px; padding: 0px 10px 0px 10px; white-space: nowrap}\n"
217  ".addresslist_label_full {border: 1px; border-radius: 5px; padding: 0px 10px 0px 10px; white-space: nowrap}\n");
218  css += QStringLiteral(".addresslist_label_short {background-image:url(%1);\nbackground-repeat: no-repeat}\n").arg(imgShowUrl);
219  css += QStringLiteral(".addresslist_label_full {background-image:url(%1);\nbackground-repeat: no-repeat}\n\n").arg(imgHideUrl);
220  for (const QString &str : {QStringLiteral("Cc"), QStringLiteral("To"), QStringLiteral("Bcc")}) {
221  css += QStringLiteral(
222  "input ~ span.fullFull%1AddressList {display: block}\n"
223  "input ~ span.shortFull%1AddressList {display: none}\n"
224  "input:checked ~ span.fullFull%1AddressList {display: none}\n"
225  "input:checked ~ span.shortFull%1AddressList {display: block}\n\n")
226  .arg(str);
227  }
228  return css;
229 }
230 
232 {
233  return QStringLiteral("<div class=\"noquote\">");
234 }
235 
236 QFont CSSHelperBase::bodyFont(bool fixed, bool print) const
237 {
238  return fixed ? (print ? mFixedPrintFont : mFixedFont) : (print ? mPrintFont : mBodyFont);
239 }
240 
241 int CSSHelperBase::fontSize(bool fixed, bool print) const
242 {
243  return bodyFont(fixed, print).pointSize();
244 }
245 
246 namespace
247 {
248 int pointsToPixel(const QPaintDevice *pd, int pointSize)
249 {
250  return (pointSize * pd->logicalDpiY() + 36) / 72;
251 }
252 }
253 
254 void CSSHelperBase::setHeaderPlugin(const HeaderStylePlugin *headerPlugin)
255 {
256  mHeaderPlugin = headerPlugin;
257 }
258 
259 static const char *const quoteFontSizes[] = {"85", "80", "75"};
260 
261 QString CSSHelperBase::printCssDefinitions(bool fixed) const
262 {
263  const QString headerFont = defaultPrintHeaderFont();
264 
265  const QFont printFont = bodyFont(fixed, true /* print */);
266  QString quoteCSS;
267  if (printFont.italic()) {
268  quoteCSS += QLatin1String(" font-style: italic ! important;\n");
269  }
270  if (printFont.bold()) {
271  quoteCSS += QLatin1String(" font-weight: bold ! important;\n");
272  }
273  if (!quoteCSS.isEmpty()) {
274  quoteCSS = QLatin1String("div.noquote {\n") + quoteCSS + QLatin1String("}\n\n");
275  }
276  quoteCSS += quoteCssDefinition();
277 
278  QStringList inlineMessageCss;
279  inlineMessageCss.reserve(MESSAGE_TYPE_COUNT);
280  for (const auto &msgStyle : inlineMessageStyles) {
281  inlineMessageCss.push_back(QLatin1String("div.") + QString::fromLatin1(msgStyle.cssName));
282  }
283 
284  return QStringLiteral(
285  "body {\n"
286  " font-family: \"%1\" ! important;\n"
287  " font-size: %2pt ! important;\n"
288  " color: #000000 ! important;\n"
289  " background-color: #ffffff ! important\n"
290  "}\n\n")
291  .arg(printFont.family(), QString::number(printFont.pointSize()))
292  + linkColorDefinition()
293  + QStringLiteral(
294  "tr.textAtmH,\n"
295  "tr.signInProgressH,\n"
296  "tr.rfc822H,\n"
297  "tr.encrH,\n"
298  "tr.signOkKeyOkH,\n"
299  "tr.signOkKeyBadH,\n"
300  "tr.signWarnH,\n"
301  "tr.signErrH,\n"
302  "div.header {\n"
303  "%1"
304  "}\n\n"
305 
306  "%2"
307 
308  "div.spamheader {\n"
309  " display:none ! important;\n"
310  "}\n\n"
311 
312  "%3 {\n"
313  " border: 2px solid #ffffff ! important;\n"
314  " line-height: normal;\n"
315  "}\n\n"
316 
317  "div.senderpic{\n"
318  " font-size:0.8em ! important;\n"
319  " border:1px solid black ! important;\n"
320  " background-color:%2 ! important;\n"
321  "}\n\n"
322 
323  "div.senderstatus{\n"
324  " text-align:center ! important;\n"
325  "}\n\n"
326 
327  "div.noprint {\n"
328  " display:none ! important;\n"
329  "}\n\n")
330  .arg(headerFont, extraPrintCss(headerFont), inlineMessageCss.join(QLatin1String(", ")))
331  + quoteCSS + fullAddressList();
332 }
333 
334 QString CSSHelperBase::linkColorDefinition() const
335 {
336  const QString linkColor = mLinkColor.name();
337  if (mUseBrowserColor) {
338 #ifdef USE_HTML_STYLE_COLOR
339  const QString bgColor = mBackgroundColor.name();
340  const QString background = QStringLiteral(" background: %1 ! important;\n").arg(bgColor);
341 
342  return QStringLiteral(
343  "div#headerbox a:link {\n"
344  " color: %1 ! important;\n"
345  " text-decoration: none ! important;\n"
346  "}\n\n"
347  "div#header a:link {\n"
348  " color: %1 ! important;\n"
349  " text-decoration: none ! important;\n"
350  "}\n\n"
351  "div.header {\n"
352  " %2"
353  "}\n\n"
354  "div#headerbox {\n"
355  " %2"
356  "}\n\n")
357  .arg(linkColor, background);
358 #else
359  return QStringLiteral(
360  "div#headerbox a:link {\n"
361  " color: %1 ! important;\n"
362  " text-decoration: none ! important;\n"
363  "}\n\n"
364  "div#header a:link {\n"
365  " color: %1 ! important;\n"
366  " text-decoration: none ! important;\n"
367  "}\n\n")
368  .arg(linkColor);
369 #endif
370  } else {
371  return QStringLiteral(
372  "a {\n"
373  " color: %1 ! important;\n"
374  " text-decoration: none ! important;\n"
375  "}\n\n")
376  .arg(linkColor);
377  }
378 }
379 
380 QString CSSHelperBase::quoteCssDefinition() const
381 {
382  QString quoteCSS;
383  QString blockQuote;
384  for (int i = 0; i < 9; ++i) {
385  blockQuote += QStringLiteral("blockquote ");
386  quoteCSS += QStringLiteral(
387  "%2{\n"
388  " margin: 4pt 0 4pt 0;\n"
389  " padding: 0 0 0 1em;\n"
390  " border-left: 2px solid %1;\n"
391  " unicode-bidi: plaintext\n"
392  "}\n\n")
393  .arg(quoteColorName(i), blockQuote);
394  }
395  quoteCSS += QStringLiteral(
396  ".quotemarks{\n"
397  " color:transparent;\n"
398  " font-size:0px;\n"
399  "}\n\n");
400  quoteCSS += QStringLiteral(
401  ".quotemarksemptyline{\n"
402  " color:transparent;\n"
403  " font-size:0px;\n"
404  " line-height: 12pt;\n"
405  "}\n\n");
406  return quoteCSS;
407 }
408 
409 QString CSSHelperBase::defaultPrintHeaderFont() const
410 {
411  const QString headerFont = QStringLiteral(
412  " font-family: \"%1\" ! important;\n"
413  " font-size: %2pt ! important;\n")
414  .arg(mPrintFont.family())
415  .arg(mPrintFont.pointSize());
416  return headerFont;
417 }
418 
419 QString CSSHelperBase::defaultScreenHeaderFont() const
420 {
421  const QString headerFont = QStringLiteral(
422  " font-family: \"%1\" ! important;\n"
423  " font-size: %2px ! important;\n")
424  .arg(mBodyFont.family())
425  .arg(pointsToPixel(mPaintDevice, mBodyFont.pointSize()));
426  return headerFont;
427 }
428 
429 QString CSSHelperBase::screenCssDefinitions(const CSSHelperBase *helper, bool fixed) const
430 {
431  const QString bgColor = mBackgroundColor.name();
432  const QString headerFont = defaultScreenHeaderFont();
433 #ifdef USE_HTML_STYLE_COLOR
434  const QString fgColor = mUseBrowserColor ? QStringLiteral("black") : mForegroundColor.name();
435  const QString background = mUseBrowserColor ? QString() : QStringLiteral(" background-color: %1 ! important;\n").arg(bgColor);
436  const QString signWarnBColorName = mUseBrowserColor ? QStringLiteral("white") : cPgpWarnB.name();
437  const QString cPgpErrBColorName = mUseBrowserColor ? QStringLiteral("white") : cPgpErrB.name();
438  const QString cPgpEncrBColorName = mUseBrowserColor ? QStringLiteral("white") : cPgpEncrB.name();
439  const QString cPgpOk1BColorName = mUseBrowserColor ? QStringLiteral("white") : cPgpOk1B.name();
440  const QString cPgpOk0BColorName = mUseBrowserColor ? QStringLiteral("white") : cPgpOk0B.name();
441 #else
442  const QString fgColor = mForegroundColor.name();
443  const QString background = QStringLiteral(" background-color: %1 ! important;\n").arg(bgColor);
444  const QString signWarnBColorName = cPgpWarnB.name();
445  const QString cPgpErrBColorName = cPgpErrB.name();
446  const QString cPgpEncrBColorName = cPgpEncrB.name();
447  const QString cPgpOk1BColorName = cPgpOk1B.name();
448  const QString cPgpOk0BColorName = cPgpOk0B.name();
449 #endif
450  const QString bodyFontSize = QString::number(pointsToPixel(helper->mPaintDevice, fontSize(fixed))) + QLatin1String("px");
451  const QPalette &pal = QApplication::palette();
452 
453  QString quoteCSS;
454  if (bodyFont(fixed).italic()) {
455  quoteCSS += QLatin1String(" font-style: italic ! important;\n");
456  }
457  if (bodyFont(fixed).bold()) {
458  quoteCSS += QLatin1String(" font-weight: bold ! important;\n");
459  }
460  if (!quoteCSS.isEmpty()) {
461  quoteCSS = QLatin1String("div.noquote {\n") + quoteCSS + QLatin1String("}\n\n");
462  }
463 
464  // CSS definitions for quote levels 1-3
465  for (int i = 0; i < 3; ++i) {
466  quoteCSS += QStringLiteral(
467  "div.quotelevel%1 {\n"
468  " color: %2 ! important;\n")
469  .arg(QString::number(i + 1), quoteColorName(i));
470  if (mQuoteFont.italic()) {
471  quoteCSS += QStringLiteral(" font-style: italic ! important;\n");
472  }
473  if (mQuoteFont.bold()) {
474  quoteCSS += QStringLiteral(" font-weight: bold ! important;\n");
475  }
476  if (mShrinkQuotes) {
477  quoteCSS += QLatin1String(" font-size: ") + QString::fromLatin1(quoteFontSizes[i]) + QLatin1String("% ! important;\n");
478  }
479  quoteCSS += QStringLiteral("}\n\n");
480  }
481 
482  // CSS definitions for quote levels 4+
483  for (int i = 0; i < 3; ++i) {
484  quoteCSS += QStringLiteral(
485  "div.deepquotelevel%1 {\n"
486  " color: %2 ! important;\n")
487  .arg(QString::number(i + 1), quoteColorName(i));
488  if (mQuoteFont.italic()) {
489  quoteCSS += QStringLiteral(" font-style: italic ! important;\n");
490  }
491  if (mQuoteFont.bold()) {
492  quoteCSS += QStringLiteral(" font-weight: bold ! important;\n");
493  }
494  if (mShrinkQuotes) {
495  quoteCSS += QStringLiteral(" font-size: 70% ! important;\n");
496  }
497  quoteCSS += QLatin1String("}\n\n");
498  }
499 
500  quoteCSS += quoteCssDefinition();
501 
502  // CSS definitions for inline message boxes
503  QString inlineMessageCss;
504  for (const auto &msgStyle : inlineMessageStyles) {
505  const auto c = cInlineMessage[msgStyle.type];
506  inlineMessageCss += QStringLiteral(
507  R"(
508  div.%1 {
509  border: 1px solid rgba(%2, %3, %4) ! important;
510  border-radius: 2px;
511  box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.5);
512  background-color: rgba(%2, %3, %4, 0.2) ! important;
513  }
514  div.%1 a:link {
515  color: %5 ! important;
516  text-decoration: none ! important;
517  }
518  )")
519  .arg(QString::fromLatin1(msgStyle.cssName))
520  .arg(c.red())
521  .arg(c.green())
522  .arg(c.blue())
523  .arg(mLinkColor.name());
524  }
525 
526  return QStringLiteral(
527  "body {\n"
528  " font-family: \"%1\" ! important;\n"
529  " font-size: %2 ! important;\n"
530  " color: %3 ! important;\n"
531  "%4"
532  "}\n\n")
533  .arg(bodyFont(fixed).family(), bodyFontSize, fgColor, background)
534  + linkColorDefinition()
535  + QStringLiteral(
536  "a.white {\n"
537  " color: white ! important;\n"
538  "}\n\n"
539 
540  "a.black {\n"
541  " color: black ! important;\n"
542  "}\n\n"
543 
544  "table.textAtm { background-color: %1 ! important; }\n\n"
545 
546  "tr.textAtmH {\n"
547  " background-color: %2 ! important;\n"
548  "%3"
549  "}\n\n"
550 
551  "tr.textAtmB {\n"
552  " background-color: %2 ! important;\n"
553  "}\n\n"
554 
555  "table.signInProgress,\n"
556  "table.rfc822 {\n"
557  " background-color: %2 ! important;\n"
558  "}\n\n"
559 
560  "tr.signInProgressH,\n"
561  "tr.rfc822H {\n"
562  "%3"
563  "}\n\n")
564  .arg(fgColor, bgColor, headerFont)
565  + QStringLiteral(
566  "table.encr {\n"
567  " background-color: %1 ! important;\n"
568  "}\n\n"
569 
570  "tr.encrH {\n"
571  " background-color: %2 ! important;\n"
572  " color: %3 ! important;\n"
573  "%4"
574  "}\n\n"
575 
576  "tr.encrB { background-color: %5 ! important; }\n\n")
577  .arg(cPgpEncrF.name(), cPgpEncrH.name(), cPgpEncrHT.name(), headerFont, cPgpEncrBColorName)
578  + QStringLiteral(
579  "table.signOkKeyOk {\n"
580  " background-color: %1 ! important;\n"
581  "}\n\n"
582 
583  "tr.signOkKeyOkH {\n"
584  " background-color: %2 ! important;\n"
585  " color: %3 ! important;\n"
586  "%4"
587  "}\n\n"
588 
589  "tr.signOkKeyOkB { background-color: %5 ! important; }\n\n")
590  .arg(cPgpOk1F.name(), cPgpOk1H.name(), cPgpOk1HT.name(), headerFont, cPgpOk1BColorName)
591  + QStringLiteral(
592  "table.signOkKeyBad {\n"
593  " background-color: %1 ! important;\n"
594  "}\n\n"
595 
596  "tr.signOkKeyBadH {\n"
597  " background-color: %2 ! important;\n"
598  " color: %3 ! important;\n"
599  "%4"
600  "}\n\n"
601 
602  "tr.signOkKeyBadB { background-color: %5 ! important; }\n\n")
603  .arg(cPgpOk0F.name(), cPgpOk0H.name(), cPgpOk0HT.name(), headerFont, cPgpOk0BColorName)
604  + QStringLiteral(
605  "table.signWarn {\n"
606  " background-color: %1 ! important;\n"
607  "}\n\n"
608 
609  "tr.signWarnH {\n"
610  " background-color: %2 ! important;\n"
611  " color: %3 ! important;\n"
612  "%4"
613  "}\n\n"
614 
615  "tr.signWarnB { background-color: %5 ! important; }\n\n")
616  .arg(cPgpWarnF.name(), cPgpWarnH.name(), cPgpWarnHT.name(), headerFont, signWarnBColorName)
617  + QStringLiteral(
618  "table.signErr {\n"
619  " background-color: %1 ! important;\n"
620  "}\n\n"
621 
622  "tr.signErrH {\n"
623  " background-color: %2 ! important;\n"
624  " color: %3 ! important;\n"
625  "%4"
626  "}\n\n"
627 
628  "tr.signErrB { background-color: %5 ! important; }\n\n")
629  .arg(cPgpErrF.name(), cPgpErrH.name(), cPgpErrHT.name(), headerFont, cPgpErrBColorName)
630  + inlineMessageCss
631  + QStringLiteral(
632  "div.header {\n"
633  "%1"
634  "}\n\n"
635 
636  "%2"
637 
638  "div.senderpic{\n"
639  " padding: 0px ! important;\n"
640  " font-size:0.8em ! important;\n"
641  " border:1px solid %4 ! important;\n"
642  " background-color:%3 ! important;\n"
643  "}\n\n"
644 
645  "div.senderstatus{\n"
646  " text-align:center ! important;\n"
647  "}\n\n")
648 
649  .arg(headerFont, extraScreenCss(headerFont), pal.color(QPalette::Highlight).name(), pal.color(QPalette::Window).name())
650  + quoteCSS + fullAddressList();
651 }
652 
653 QString CSSHelperBase::commonCssDefinitions() const
654 {
655  const QString headerFont = defaultScreenHeaderFont();
656 
657  QStringList inlineMessageCss;
658  inlineMessageCss.reserve(MESSAGE_TYPE_COUNT);
659  for (const auto &msgStyle : inlineMessageStyles) {
660  inlineMessageCss.push_back(QLatin1String("div.") + QString::fromLatin1(msgStyle.cssName));
661  }
662 
663  return QStringLiteral(
664  "div.header {\n"
665  " margin-bottom: 10pt ! important;\n"
666  "}\n\n"
667 
668  "pre.highlightattachment {\n"
669  " white-space: pre-wrap;\n"
670  "}\n\n"
671 
672  "table.textAtm {\n"
673  " margin-top: 10pt ! important;\n"
674  " margin-bottom: 10pt ! important;\n"
675  "}\n\n"
676 
677  "tr.textAtmH,\n"
678  "tr.textAtmB,\n"
679  "tr.rfc822B {\n"
680  " font-weight: normal ! important;\n"
681  "}\n\n"
682 
683  "tr.signInProgressH,\n"
684  "tr.rfc822H,\n"
685  "tr.encrH,\n"
686  "tr.signOkKeyOkH,\n"
687  "tr.signOkKeyBadH,\n"
688  "tr.signWarnH,\n"
689  "tr.signErrH {\n"
690  " font-weight: bold ! important;\n"
691  "}\n\n"
692 
693  "tr.textAtmH td,\n"
694  "tr.textAtmB td {\n"
695  " padding: 3px ! important;\n"
696  "}\n\n"
697 
698  "table.rfc822 {\n"
699  " width: 100% ! important;\n"
700  " border: solid 1px black ! important;\n"
701  " margin-top: 10pt ! important;\n"
702  " margin-bottom: 10pt ! important;\n"
703  "}\n\n"
704 
705  "table.textAtm,\n"
706  "table.encr,\n"
707  "table.signWarn,\n"
708  "table.signErr,\n"
709  "table.signOkKeyBad,\n"
710  "table.signOkKeyOk,\n"
711  "table.signInProgress,\n"
712 
713  "%1"
714 
715  "%2 {\n"
716  " margin: 0px 5% 10px 5% ! important;\n"
717  " padding: 10px ! important;\n"
718  " text-align: left ! important;\n"
719  " line-height: normal;\n"
720  " min-height: %6px;\n"
721  "}\n\n"
722 
723  "hr {\n"
724  " border: 0;\n"
725  " height: 0;\n"
726  " border-top: 1px solid rgba(%3, %4, %5, 0.3);\n"
727  "}\n\n"
728 
729  "div.quotelevelmark {\n"
730  " position: absolute;\n"
731  " margin-left:-10px;\n"
732  "}\n\n")
733  .arg(extraCommonCss(headerFont), inlineMessageCss.join(QLatin1String(", ")))
734  .arg(mForegroundColor.red())
735  .arg(mForegroundColor.green())
736  .arg(mForegroundColor.blue())
737  .arg(QString::number(48));
738 }
739 
740 void CSSHelperBase::setBodyFont(const QFont &font)
741 {
742  mBodyFont = font;
743 }
744 
745 void CSSHelperBase::setPrintFont(const QFont &font)
746 {
747  mPrintFont = font;
748 }
749 
750 QString CSSHelperBase::quoteColorName(int level) const
751 {
752  return quoteColor(level).name();
753 }
754 
756 {
757  const int actualLevel = qMax(level, 0) % 3;
758  return mQuoteColor[actualLevel];
759 }
760 
761 QColor CSSHelperBase::pgpWarnColor() const
762 {
763  return cPgpWarnH;
764 }
765 }
QString url(QUrl::FormattingOptions options) const const
QString nonQuotedFontTag() const
void push_back(const T &value)
QString name() const const
void reserve(int alloc)
void recalculatePGPColors()
Recalculate PGP frame and body colors (should be called after changing color settings) ...
const QColor & color(QPalette::ColorGroup group, QPalette::ColorRole role) const const
QString join(const QString &separator) const const
void getHsv(int *h, int *s, int *v, int *a) const const
bool bold() const const
bool italic() const const
QColor fromHsv(int h, int s, int v, int a)
QColor quoteColor(int level) const
QString number(int n, int base)
int red() const const
QPalette palette()
The CSSHelperBase class.
Definition: csshelperbase.h:26
bool isEmpty() const const
QString cssDefinitions(bool fixedFont=false) const
The HeaderStylePlugin class.
int logicalDpiY() const const
int green() const const
QString quoteFontTag(int level) const
int blue() const const
virtual QString htmlHead(bool fixedFont=false) const
QString family() const const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
QString fromLatin1(const char *str, int size)
CSSHelperBase(const QPaintDevice *pd)
Construct a CSSHelper object and set its font and color settings to default values.
int pointSize() const const
QUrl fromLocalFile(const QString &localFile)
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Thu Jun 17 2021 23:13:58 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.