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

KDE's Doxygen guidelines are available online.