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

KDE's Doxygen guidelines are available online.