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

KDE's Doxygen guidelines are available online.