10#include "csshelperbase.h"
11#include "header/headerstyleplugin.h"
12#include "utils/iconnamecache.h"
14#include <QApplication>
15#include <QPaintDevice>
19namespace MessageViewer
51inline int getValueOf(
const QColor &c)
61 CSSHelperBase::InlineMessageType type;
63} inlineMessageStyles[] = {{CSSHelperBase::Positive,
"inlineMessagePositive"},
64 {CSSHelperBase::Information,
"inlineMessageInformation"},
65 {CSSHelperBase::Warning,
"inlineMessageWarning"},
66 {CSSHelperBase::Error,
"inlineMessageError"}};
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();
78CSSHelperBase::~CSSHelperBase() =
default;
93 const int vBG = getValueOf(mBackgroundColor);
94 const bool lightBG = vBG >= 128;
95 if (cPgpOk1H == mBackgroundColor) {
96 cPgpOk1F = mBackgroundColor;
97 cPgpOk1B = mBackgroundColor;
99 cPgpOk1F = darker(cPgpOk1H);
100 cPgpOk1B = lightBG ? desaturate(cPgpOk1H) : fixValue(cPgpOk1H, vBG);
102 if (cPgpOk0H == mBackgroundColor) {
103 cPgpOk0F = mBackgroundColor;
104 cPgpOk0B = mBackgroundColor;
106 cPgpOk0F = darker(cPgpOk0H);
107 cPgpOk0B = lightBG ? desaturate(cPgpOk0H) : fixValue(cPgpOk0H, vBG);
109 if (cPgpWarnH == mBackgroundColor) {
110 cPgpWarnF = mBackgroundColor;
111 cPgpWarnB = mBackgroundColor;
113 cPgpWarnF = darker(cPgpWarnH);
114 cPgpWarnB = lightBG ? desaturate(cPgpWarnH) : fixValue(cPgpWarnH, vBG);
116 if (cPgpErrH == mBackgroundColor) {
117 cPgpErrF = mBackgroundColor;
118 cPgpErrB = mBackgroundColor;
120 cPgpErrF = darker(cPgpErrH);
121 cPgpErrB = lightBG ? desaturate(cPgpErrH) : fixValue(cPgpErrH, vBG);
123 if (cPgpEncrH == mBackgroundColor) {
124 cPgpEncrF = mBackgroundColor;
125 cPgpEncrB = mBackgroundColor;
127 cPgpEncrF = darker(cPgpEncrH);
128 cPgpEncrB = lightBG ? desaturate(cPgpEncrH) : fixValue(cPgpEncrH, vBG);
132QString CSSHelperBase::addEndBlockQuote(
int numberBlock)
const
135 for (
int i = 0; i < numberBlock; ++i) {
141QString CSSHelperBase::addStartBlockQuote(
int numberBlock)
const
144 for (
int i = 0; i < numberBlock; ++i) {
150QString CSSHelperBase::extraScreenCss(
const QString &headerFont)
const
153 return mHeaderPlugin->extraScreenCss(headerFont);
158QString CSSHelperBase::extraPrintCss(
const QString &headerFont)
const
161 return mHeaderPlugin->extraPrintCss(headerFont);
166QString CSSHelperBase::extraCommonCss(
const QString &headerFont)
const
170 result = mHeaderPlugin->extraCommonCss(headerFont);
174 result = QStringLiteral(
175 "div.header table {\n"
176 " width: 100% ! important;\n"
177 " border-width: 0px ! important;\n"
178 " line-height: normal;\n"
186 return commonCssDefinitions() +
QLatin1StringView(
"@media screen {\n\n") + screenCssDefinitions(
this, htmlHeadSetting)
189 "@media print {\n\n")
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"
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);
212 return QStringLiteral(
"<div class=\"quotelevel%1\">").arg(effectiveLevel);
216QString CSSHelperBase::fullAddressList()
const
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")
237 return QStringLiteral(
"<div class=\"noquote\">");
240QFont CSSHelperBase::bodyFont(
bool fixed,
bool print)
const
242 return fixed ? (print ? mFixedPrintFont : mFixedFont) : (print ? mPrintFont : mBodyFont);
245int CSSHelperBase::fontSize(
bool fixed,
bool print)
const
247 return bodyFont(fixed, print).
pointSize();
258void CSSHelperBase::setHeaderPlugin(
const HeaderStylePlugin *headerPlugin)
260 mHeaderPlugin = headerPlugin;
263static const char *
const quoteFontSizes[] = {
"85",
"80",
"75"};
265QString CSSHelperBase::printCssDefinitions(
const HtmlHeadSettings &htmlHeadSettings)
const
267 const QString headerFont = defaultPrintHeaderFont();
269 const QFont printFont = bodyFont(htmlHeadSettings.fixedFont,
true );
274 if (printFont.
bold()) {
280 quoteCSS += quoteCssDefinition();
283 inlineMessageCss.
reserve(MESSAGE_TYPE_COUNT);
284 for (
const auto &msgStyle : inlineMessageStyles) {
288 return QStringLiteral(
290 " font-family: \"%1\" ! important;\n"
291 " font-size: %2pt ! important;\n"
292 " color: #000000 ! important;\n"
293 " background-color: #ffffff ! important\n"
296 + linkColorDefinition(htmlHeadSettings)
299 "tr.signInProgressH,\n"
303 "tr.signOkKeyBadH,\n"
313 " display:none ! important;\n"
317 " display:none ! important;\n"
321 " font-size:0.8em ! important;\n"
322 " border:1px solid black ! important;\n"
323 " background-color:%2 ! important;\n"
326 "div.senderstatus{\n"
327 " text-align:center ! important;\n"
331 " display:none ! important;\n"
334 + quoteCSS + fullAddressList();
337QString CSSHelperBase::linkColorDefinition(
const HtmlHeadSettings &htmlHeadSettings)
const
340 if (useBrowserColor(htmlHeadSettings)) {
342 const QString background = QStringLiteral(
" background: %1 ! important;\n").
arg(bgColor);
344 return QStringLiteral(
345 "div#headerbox a:link {\n"
346 " color: %1 ! important;\n"
347 " text-decoration: none ! important;\n"
349 "div#header a:link {\n"
350 " color: %1 ! important;\n"
351 " text-decoration: none ! important;\n"
359 .
arg(linkColor, background);
361 return QStringLiteral(
363 " color: %1 ! important;\n"
364 " text-decoration: none ! important;\n"
370QString CSSHelperBase::quoteCssDefinition()
const
374 for (
int i = 0; i < 9; ++i) {
375 blockQuote += QStringLiteral(
"blockquote ");
376 quoteCSS += QStringLiteral(
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"
383 .
arg(quoteColorName(i), blockQuote);
385 quoteCSS += QStringLiteral(
387 " color:transparent;\n"
390 quoteCSS += QStringLiteral(
391 ".quotemarksemptyline{\n"
392 " color:transparent;\n"
394 " line-height: 12pt;\n"
399QString CSSHelperBase::defaultPrintHeaderFont()
const
401 const QString headerFont = QStringLiteral(
402 " font-family: \"%1\" ! important;\n"
403 " font-size: %2pt ! important;\n")
409QString CSSHelperBase::defaultScreenHeaderFont()
const
411 const QString headerFont = QStringLiteral(
412 " font-family: \"%1\" ! important;\n"
413 " font-size: %2px ! important;\n")
415 .
arg(pointsToPixel(mPaintDevice, mBodyFont.
pointSize()));
419bool CSSHelperBase::useBrowserColor(
const HtmlHeadSettings &htmlHeadSettings)
const
421 return mUseBrowserColor && htmlHeadSettings.htmlFormat;
424const HeaderStylePlugin *CSSHelperBase::headerPlugin()
const
426 return mHeaderPlugin;
429QString CSSHelperBase::screenCssDefinitions(
const CSSHelperBase *helper,
const HtmlHeadSettings &htmlHeadSettings)
const
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();
444 if (bodyFont(htmlHeadSettings.fixedFont).
italic()) {
447 if (bodyFont(htmlHeadSettings.fixedFont).
bold()) {
455 for (
int i = 0; i < 3; ++i) {
456 quoteCSS += QStringLiteral(
457 "div.quotelevel%1 {\n"
458 " color: %2 ! important;\n")
460 if (mQuoteFont.
italic()) {
461 quoteCSS += QStringLiteral(
" font-style: italic ! important;\n");
463 if (mQuoteFont.
bold()) {
464 quoteCSS += QStringLiteral(
" font-weight: bold ! important;\n");
469 quoteCSS += QStringLiteral(
"}\n\n");
473 for (
int i = 0; i < 3; ++i) {
474 quoteCSS += QStringLiteral(
475 "div.deepquotelevel%1 {\n"
476 " color: %2 ! important;\n")
478 if (mQuoteFont.
italic()) {
479 quoteCSS += QStringLiteral(
" font-style: italic ! important;\n");
481 if (mQuoteFont.
bold()) {
482 quoteCSS += QStringLiteral(
" font-weight: bold ! important;\n");
485 quoteCSS += QStringLiteral(
" font-size: 70% ! important;\n");
490 quoteCSS += quoteCssDefinition();
494 for (
const auto &msgStyle : inlineMessageStyles) {
495 const auto c = cInlineMessage[msgStyle.type];
496 inlineMessageCss += QStringLiteral(
499 border: 1px solid rgba(%2, %3, %4) ! important;
501 box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.5);
502 background-color: rgba(%2, %3, %4, 0.2) ! important;
505 color: %5 ! important;
506 text-decoration: none ! important;
516 const auto scrollBarCss = QStringLiteral(
517 "html::-webkit-scrollbar {\n"
518 " /* we'll add padding as \"border\" in the thumb*/\n"
521 " background: white;\n"
522 " border-left: 1px solid #e5e5e5;\n"
523 " padding-left: 1px;\n"
526 "html::-webkit-scrollbar-track {\n"
527 " border-radius: 20px;\n"
528 " width: 6px !important;\n"
529 " box-sizing: content-box;\n"
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"
542 "html::-webkit-scrollbar-thumb:window-inactive {\n"
543 " background-color: #949699; /* when window is inactive it's gray */\n"
546 "html::-webkit-scrollbar-thumb:hover {\n"
547 " background-color: #93CEE9; /* hovered is a lighter blue */\n"
550 "html::-webkit-scrollbar-corner {\n"
551 " background-color: white;\n"
554 return QStringLiteral(
556 " font-family: \"%1\" ! important;\n"
557 " font-size: %2 ! important;\n"
558 " color: %3 ! important;\n"
561 .arg(bodyFont(htmlHeadSettings.fixedFont).
family(), bodyFontSize, fgColor, background)
562 + linkColorDefinition(htmlHeadSettings)
565 " color: white ! important;\n"
569 " color: black ! important;\n"
572 "table.textAtm { background-color: %1 ! important; }\n\n"
575 " background-color: %2 ! important;\n"
580 " background-color: %2 ! important;\n"
583 "table.signInProgress,\n"
585 " background-color: %2 ! important;\n"
588 "tr.signInProgressH,\n"
592 .
arg(fgColor, bgColor, headerFont)
595 " background-color: %1 ! important;\n"
599 " background-color: %2 ! important;\n"
600 " color: %3 ! important;\n"
604 "tr.encrB { background-color: %5 ! important; }\n\n")
605 .
arg(cPgpEncrF.
name(), cPgpEncrH.
name(), cPgpEncrHT.
name(), headerFont, cPgpEncrBColorName)
607 "table.signOkKeyOk {\n"
608 " background-color: %1 ! important;\n"
611 "tr.signOkKeyOkH {\n"
612 " background-color: %2 ! important;\n"
613 " color: %3 ! important;\n"
617 "tr.signOkKeyOkB { background-color: %5 ! important; }\n\n")
618 .
arg(cPgpOk1F.
name(), cPgpOk1H.
name(), cPgpOk1HT.
name(), headerFont, cPgpOk1BColorName)
620 "table.signOkKeyBad {\n"
621 " background-color: %1 ! important;\n"
624 "tr.signOkKeyBadH {\n"
625 " background-color: %2 ! important;\n"
626 " color: %3 ! important;\n"
630 "tr.signOkKeyBadB { background-color: %5 ! important; }\n\n")
631 .
arg(cPgpOk0F.
name(), cPgpOk0H.
name(), cPgpOk0HT.
name(), headerFont, cPgpOk0BColorName)
634 " background-color: %1 ! important;\n"
638 " background-color: %2 ! important;\n"
639 " color: %3 ! important;\n"
643 "tr.signWarnB { background-color: %5 ! important; }\n\n")
644 .
arg(cPgpWarnF.
name(), cPgpWarnH.
name(), cPgpWarnHT.
name(), headerFont, signWarnBColorName)
647 " background-color: %1 ! important;\n"
651 " background-color: %2 ! important;\n"
652 " color: %3 ! important;\n"
656 "tr.signErrB { background-color: %5 ! important; }\n\n")
657 .
arg(cPgpErrF.
name(), cPgpErrH.
name(), cPgpErrHT.
name(), headerFont, cPgpErrBColorName)
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"
675 "div.senderstatus{\n"
676 " text-align:center ! important;\n"
680 + quoteCSS + fullAddressList();
683QString CSSHelperBase::commonCssDefinitions()
const
685 const QString headerFont = defaultScreenHeaderFont();
688 inlineMessageCss.
reserve(MESSAGE_TYPE_COUNT);
689 for (
const auto &msgStyle : inlineMessageStyles) {
692 return QStringLiteral(
694 " margin-bottom: 10pt ! important;\n"
697 "pre.highlightattachment {\n"
698 " white-space: pre-wrap;\n"
702 " margin-top: 10pt ! important;\n"
703 " margin-bottom: 10pt ! important;\n"
709 " font-weight: normal ! important;\n"
712 "tr.signInProgressH,\n"
716 "tr.signOkKeyBadH,\n"
719 " font-weight: bold ! important;\n"
724 " padding: 3px ! important;\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"
738 "table.signOkKeyBad,\n"
739 "table.signOkKeyOk,\n"
740 "table.signInProgress,\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"
755 " border-top: 1px solid rgba(%3, %4, %5, 0.3);\n"
758 "div.quotelevelmark {\n"
759 " position: absolute;\n"
760 " margin-left:-10px;\n"
762 .arg(extraCommonCss(headerFont))
764 .arg(mForegroundColor.
red())
765 .arg(mForegroundColor.
green())
766 .arg(mForegroundColor.
blue())
770void CSSHelperBase::setBodyFont(
const QFont &font)
775void CSSHelperBase::setPrintFont(
const QFont &font)
780QString CSSHelperBase::quoteColorName(
int level)
const
787 const int actualLevel = qMax(level, 0) % 3;
788 return mQuoteColor[actualLevel];
791QColor CSSHelperBase::pgpWarnColor()
const
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
QString nonQuotedFontTag() const
virtual QString htmlHead(const HtmlHeadSettings &) const
QString name(StandardAction id)
QColor fromHsv(int h, int s, int v, int a)
void getHsv(int *h, int *s, int *v, int *a) const const
QString name(NameFormat format) const const
QString family() const const
bool italic() const const
int pointSize() const const
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