10 #include "csshelperbase.h"
11 #include "header/headerstyleplugin.h"
12 #include "utils/iconnamecache.h"
14 #include <QApplication>
15 #include <QPaintDevice>
19 #define USE_HTML_STYLE_COLOR 1
20 namespace MessageViewer
52 inline int getValueOf(
const QColor &c)
62 CSSHelperBase::InlineMessageType type;
64 } inlineMessageStyles[] = {{CSSHelperBase::Positive,
"inlineMessagePositive"},
65 {CSSHelperBase::Information,
"inlineMessageInformation"},
66 {CSSHelperBase::Warning,
"inlineMessageWarning"},
67 {CSSHelperBase::Error,
"inlineMessageError"}};
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();
80 CSSHelperBase::~CSSHelperBase() =
default;
95 const int vBG = getValueOf(mBackgroundColor);
96 const bool lightBG = vBG >= 128;
97 if (cPgpOk1H == mBackgroundColor) {
98 cPgpOk1F = mBackgroundColor;
99 cPgpOk1B = mBackgroundColor;
101 cPgpOk1F = darker(cPgpOk1H);
102 cPgpOk1B = lightBG ? desaturate(cPgpOk1H) : fixValue(cPgpOk1H, vBG);
104 if (cPgpOk0H == mBackgroundColor) {
105 cPgpOk0F = mBackgroundColor;
106 cPgpOk0B = mBackgroundColor;
108 cPgpOk0F = darker(cPgpOk0H);
109 cPgpOk0B = lightBG ? desaturate(cPgpOk0H) : fixValue(cPgpOk0H, vBG);
111 if (cPgpWarnH == mBackgroundColor) {
112 cPgpWarnF = mBackgroundColor;
113 cPgpWarnB = mBackgroundColor;
115 cPgpWarnF = darker(cPgpWarnH);
116 cPgpWarnB = lightBG ? desaturate(cPgpWarnH) : fixValue(cPgpWarnH, vBG);
118 if (cPgpErrH == mBackgroundColor) {
119 cPgpErrF = mBackgroundColor;
120 cPgpErrB = mBackgroundColor;
122 cPgpErrF = darker(cPgpErrH);
123 cPgpErrB = lightBG ? desaturate(cPgpErrH) : fixValue(cPgpErrH, vBG);
125 if (cPgpEncrH == mBackgroundColor) {
126 cPgpEncrF = mBackgroundColor;
127 cPgpEncrB = mBackgroundColor;
129 cPgpEncrF = darker(cPgpEncrH);
130 cPgpEncrB = lightBG ? desaturate(cPgpEncrH) : fixValue(cPgpEncrH, vBG);
134 QString CSSHelperBase::addEndBlockQuote(
int numberBlock)
const
137 for (
int i = 0; i < numberBlock; ++i) {
143 QString CSSHelperBase::addStartBlockQuote(
int numberBlock)
const
146 for (
int i = 0; i < numberBlock; ++i) {
152 QString CSSHelperBase::extraScreenCss(
const QString &headerFont)
const
155 return mHeaderPlugin->extraScreenCss(headerFont);
160 QString CSSHelperBase::extraPrintCss(
const QString &headerFont)
const
163 return mHeaderPlugin->extraPrintCss(headerFont);
168 QString CSSHelperBase::extraCommonCss(
const QString &headerFont)
const
172 result = mHeaderPlugin->extraCommonCss(headerFont);
175 result = QStringLiteral(
176 "div.header table {\n"
177 " width: 100% ! important;\n"
178 " border-width: 0px ! important;\n"
179 " line-height: normal;\n"
188 return commonCssDefinitions() +
QLatin1String(
"@media screen {\n\n") + screenCssDefinitions(
this, fixed)
191 "@media print {\n\n")
198 return QStringLiteral(
199 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n"
200 "<html><head><title></title></head>\n"
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);
214 return QStringLiteral(
"<div class=\"quotelevel%1\">").arg(effectiveLevel);
218 QString CSSHelperBase::fullAddressList()
const
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")
239 return QStringLiteral(
"<div class=\"noquote\">");
242 QFont CSSHelperBase::bodyFont(
bool fixed,
bool print)
const
244 return fixed ? (print ? mFixedPrintFont : mFixedFont) : (print ? mPrintFont : mBodyFont);
247 int CSSHelperBase::fontSize(
bool fixed,
bool print)
const
249 return bodyFont(fixed, print).
pointSize();
254 int pointsToPixel(
const QPaintDevice *pd,
int pointSize)
260 void CSSHelperBase::setHeaderPlugin(
const HeaderStylePlugin *headerPlugin)
262 mHeaderPlugin = headerPlugin;
265 static const char *
const quoteFontSizes[] = {
"85",
"80",
"75"};
267 QString CSSHelperBase::printCssDefinitions(
bool fixed)
const
269 const QString headerFont = defaultPrintHeaderFont();
271 const QFont printFont = bodyFont(fixed,
true );
274 quoteCSS +=
QLatin1String(
" font-style: italic ! important;\n");
276 if (printFont.
bold()) {
277 quoteCSS +=
QLatin1String(
" font-weight: bold ! important;\n");
282 quoteCSS += quoteCssDefinition();
285 inlineMessageCss.
reserve(MESSAGE_TYPE_COUNT);
286 for (
const auto &msgStyle : inlineMessageStyles) {
290 return QStringLiteral(
292 " font-family: \"%1\" ! important;\n"
293 " font-size: %2pt ! important;\n"
294 " color: #000000 ! important;\n"
295 " background-color: #ffffff ! important\n"
298 + linkColorDefinition()
301 "tr.signInProgressH,\n"
305 "tr.signOkKeyBadH,\n"
315 " display:none ! important;\n"
319 " border: 2px solid #ffffff ! important;\n"
320 " line-height: normal;\n"
324 " font-size:0.8em ! important;\n"
325 " border:1px solid black ! important;\n"
326 " background-color:%2 ! important;\n"
329 "div.senderstatus{\n"
330 " text-align:center ! important;\n"
334 " display:none ! important;\n"
337 + quoteCSS + fullAddressList();
340 QString CSSHelperBase::linkColorDefinition()
const
343 if (mUseBrowserColor) {
344 #ifdef USE_HTML_STYLE_COLOR
346 const QString background = QStringLiteral(
" background: %1 ! important;\n").
arg(bgColor);
348 return QStringLiteral(
349 "div#headerbox a:link {\n"
350 " color: %1 ! important;\n"
351 " text-decoration: none ! important;\n"
353 "div#header a:link {\n"
354 " color: %1 ! important;\n"
355 " text-decoration: none ! important;\n"
363 .
arg(linkColor, background);
365 return QStringLiteral(
366 "div#headerbox a:link {\n"
367 " color: %1 ! important;\n"
368 " text-decoration: none ! important;\n"
370 "div#header a:link {\n"
371 " color: %1 ! important;\n"
372 " text-decoration: none ! important;\n"
377 return QStringLiteral(
379 " color: %1 ! important;\n"
380 " text-decoration: none ! important;\n"
386 QString CSSHelperBase::quoteCssDefinition()
const
390 for (
int i = 0; i < 9; ++i) {
391 blockQuote += QStringLiteral(
"blockquote ");
392 quoteCSS += QStringLiteral(
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"
399 .
arg(quoteColorName(i), blockQuote);
401 quoteCSS += QStringLiteral(
403 " color:transparent;\n"
406 quoteCSS += QStringLiteral(
407 ".quotemarksemptyline{\n"
408 " color:transparent;\n"
410 " line-height: 12pt;\n"
415 QString CSSHelperBase::defaultPrintHeaderFont()
const
417 const QString headerFont = QStringLiteral(
418 " font-family: \"%1\" ! important;\n"
419 " font-size: %2pt ! important;\n")
425 QString CSSHelperBase::defaultScreenHeaderFont()
const
427 const QString headerFont = QStringLiteral(
428 " font-family: \"%1\" ! important;\n"
429 " font-size: %2px ! important;\n")
431 .
arg(pointsToPixel(mPaintDevice, mBodyFont.
pointSize()));
435 QString CSSHelperBase::screenCssDefinitions(
const CSSHelperBase *helper,
bool fixed)
const
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();
449 const QString background = QStringLiteral(
" background-color: %1 ! important;\n").
arg(bgColor);
450 const QString signWarnBColorName = cPgpWarnB.
name();
452 const QString cPgpEncrBColorName = cPgpEncrB.
name();
460 if (bodyFont(fixed).italic()) {
461 quoteCSS +=
QLatin1String(
" font-style: italic ! important;\n");
463 if (bodyFont(fixed).bold()) {
464 quoteCSS +=
QLatin1String(
" font-weight: bold ! important;\n");
471 for (
int i = 0; i < 3; ++i) {
472 quoteCSS += QStringLiteral(
473 "div.quotelevel%1 {\n"
474 " color: %2 ! important;\n")
476 if (mQuoteFont.
italic()) {
477 quoteCSS += QStringLiteral(
" font-style: italic ! important;\n");
479 if (mQuoteFont.
bold()) {
480 quoteCSS += QStringLiteral(
" font-weight: bold ! important;\n");
485 quoteCSS += QStringLiteral(
"}\n\n");
489 for (
int i = 0; i < 3; ++i) {
490 quoteCSS += QStringLiteral(
491 "div.deepquotelevel%1 {\n"
492 " color: %2 ! important;\n")
494 if (mQuoteFont.
italic()) {
495 quoteCSS += QStringLiteral(
" font-style: italic ! important;\n");
497 if (mQuoteFont.
bold()) {
498 quoteCSS += QStringLiteral(
" font-weight: bold ! important;\n");
501 quoteCSS += QStringLiteral(
" font-size: 70% ! important;\n");
506 quoteCSS += quoteCssDefinition();
510 for (
const auto &msgStyle : inlineMessageStyles) {
511 const auto c = cInlineMessage[msgStyle.type];
512 inlineMessageCss += QStringLiteral(
515 border: 1px solid rgba(%2, %3, %4) ! important;
517 box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.5);
518 background-color: rgba(%2, %3, %4, 0.2) ! important;
521 color: %5 ! important;
522 text-decoration: none ! important;
532 return QStringLiteral(
534 " font-family: \"%1\" ! important;\n"
535 " font-size: %2 ! important;\n"
536 " color: %3 ! important;\n"
539 .
arg(bodyFont(fixed).family(), bodyFontSize, fgColor, background)
540 + linkColorDefinition()
543 " color: white ! important;\n"
547 " color: black ! important;\n"
550 "table.textAtm { background-color: %1 ! important; }\n\n"
553 " background-color: %2 ! important;\n"
558 " background-color: %2 ! important;\n"
561 "table.signInProgress,\n"
563 " background-color: %2 ! important;\n"
566 "tr.signInProgressH,\n"
570 .
arg(fgColor, bgColor, headerFont)
573 " background-color: %1 ! important;\n"
577 " background-color: %2 ! important;\n"
578 " color: %3 ! important;\n"
582 "tr.encrB { background-color: %5 ! important; }\n\n")
583 .
arg(cPgpEncrF.
name(), cPgpEncrH.
name(), cPgpEncrHT.
name(), headerFont, cPgpEncrBColorName)
585 "table.signOkKeyOk {\n"
586 " background-color: %1 ! important;\n"
589 "tr.signOkKeyOkH {\n"
590 " background-color: %2 ! important;\n"
591 " color: %3 ! important;\n"
595 "tr.signOkKeyOkB { background-color: %5 ! important; }\n\n")
596 .
arg(cPgpOk1F.
name(), cPgpOk1H.
name(), cPgpOk1HT.
name(), headerFont, cPgpOk1BColorName)
598 "table.signOkKeyBad {\n"
599 " background-color: %1 ! important;\n"
602 "tr.signOkKeyBadH {\n"
603 " background-color: %2 ! important;\n"
604 " color: %3 ! important;\n"
608 "tr.signOkKeyBadB { background-color: %5 ! important; }\n\n")
609 .
arg(cPgpOk0F.
name(), cPgpOk0H.
name(), cPgpOk0HT.
name(), headerFont, cPgpOk0BColorName)
612 " background-color: %1 ! important;\n"
616 " background-color: %2 ! important;\n"
617 " color: %3 ! important;\n"
621 "tr.signWarnB { background-color: %5 ! important; }\n\n")
622 .
arg(cPgpWarnF.
name(), cPgpWarnH.
name(), cPgpWarnHT.
name(), headerFont, signWarnBColorName)
625 " background-color: %1 ! important;\n"
629 " background-color: %2 ! important;\n"
630 " color: %3 ! important;\n"
634 "tr.signErrB { background-color: %5 ! important; }\n\n")
635 .
arg(cPgpErrF.
name(), cPgpErrH.
name(), cPgpErrHT.
name(), headerFont, cPgpErrBColorName)
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"
651 "div.senderstatus{\n"
652 " text-align:center ! important;\n"
656 + quoteCSS + fullAddressList();
659 QString CSSHelperBase::commonCssDefinitions()
const
661 const QString headerFont = defaultScreenHeaderFont();
664 inlineMessageCss.
reserve(MESSAGE_TYPE_COUNT);
665 for (
const auto &msgStyle : inlineMessageStyles) {
669 return QStringLiteral(
671 " margin-bottom: 10pt ! important;\n"
674 "pre.highlightattachment {\n"
675 " white-space: pre-wrap;\n"
679 " margin-top: 10pt ! important;\n"
680 " margin-bottom: 10pt ! important;\n"
686 " font-weight: normal ! important;\n"
689 "tr.signInProgressH,\n"
693 "tr.signOkKeyBadH,\n"
696 " font-weight: bold ! important;\n"
701 " padding: 3px ! important;\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"
715 "table.signOkKeyBad,\n"
716 "table.signOkKeyOk,\n"
717 "table.signInProgress,\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"
732 " border-top: 1px solid rgba(%3, %4, %5, 0.3);\n"
735 "div.quotelevelmark {\n"
736 " position: absolute;\n"
737 " margin-left:-10px;\n"
740 .arg(mForegroundColor.
red())
741 .arg(mForegroundColor.
green())
742 .arg(mForegroundColor.
blue())
746 void CSSHelperBase::setBodyFont(
const QFont &font)
751 void CSSHelperBase::setPrintFont(
const QFont &font)
756 QString CSSHelperBase::quoteColorName(
int level)
const
763 const int actualLevel = qMax(level, 0) % 3;
764 return mQuoteColor[actualLevel];
767 QColor CSSHelperBase::pgpWarnColor()
const