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

KDE's Doxygen guidelines are available online.