MailJD nbsp;·nbsp; Test Dashboard nbsp;·nbsp; Coverage
LCOV - code coverage report
Current view: top level - ui - MdiIconProvider.cpp (source / functions) Coverage Total Hit
Test: MailJD Coverage (Unit + E2E) Lines: 90.4 % 83 75
Test Date: 2026-06-21 21:10:19 Functions: 100.0 % 5 5
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 50.0 % 202 101

             Branch data     Line data    Source code
       1                 :             : #include "MdiIconProvider.h"
       2                 :             : 
       3                 :             : #include "ui/ThemeManager.h"
       4                 :             : 
       5                 :             : #include <QFile>
       6                 :             : #include <QFontDatabase>
       7                 :             : #include <QIODevice>
       8                 :             : #include <QLoggingCategory>
       9                 :             : #include <QPainter>
      10                 :             : #include <QPixmap>
      11                 :             : #include <QTextStream>
      12                 :             : 
      13   [ +  +  +  -  :          86 : Q_LOGGING_CATEGORY(lcMdi, "mailjd.mdi")
             +  -  -  - ]
      14                 :             : 
      15                 :         472 : MdiIconProvider &MdiIconProvider::instance() {
      16   [ +  +  +  -  :         472 :   static MdiIconProvider s_instance;
             +  -  -  - ]
      17                 :         472 :   return s_instance;
      18                 :             : }
      19                 :             : 
      20                 :          74 : void MdiIconProvider::init() {
      21         [ -  + ]:          74 :   if (m_ready)
      22                 :          62 :     return;
      23                 :             : 
      24                 :             :   // 1. Register font
      25                 :             :   int fontId =
      26         [ +  - ]:          74 :       QFontDatabase::addApplicationFont(
      27                 :         148 :           QStringLiteral(":/fonts/materialdesignicons-webfont.ttf"));
      28         [ +  + ]:          74 :   if (fontId < 0) {
      29   [ +  -  +  -  :         124 :     qCWarning(lcMdi) << "Failed to load MDI webfont from resources";
             +  -  +  + ]
      30                 :          62 :     return;
      31                 :             :   }
      32         [ +  - ]:          12 :   QStringList families = QFontDatabase::applicationFontFamilies(fontId);
      33         [ -  + ]:          12 :   if (families.isEmpty()) {
      34   [ #  #  #  #  :           0 :     qCWarning(lcMdi) << "MDI font has no families";
             #  #  #  # ]
      35                 :           0 :     return;
      36                 :             :   }
      37   [ +  -  +  - ]:          12 :   m_font = QFont(families.first());
      38   [ +  -  +  -  :          24 :   qCInfo(lcMdi) << "MDI font loaded:" << families.first();
          +  -  +  -  +  
                -  +  + ]
      39                 :             : 
      40                 :             :   // 2. Parse codemap CSV
      41         [ +  - ]:          12 :   QFile f(QStringLiteral(":/mdi-codemap.csv"));
      42   [ +  -  -  + ]:          12 :   if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) {
      43   [ #  #  #  #  :           0 :     qCWarning(lcMdi) << "Failed to open mdi-codemap.csv from resources";
             #  #  #  # ]
      44                 :           0 :     return;
      45                 :             :   }
      46         [ +  - ]:          12 :   QTextStream ts(&f);
      47         [ +  - ]:          12 :   ts.readLine(); // skip header
      48         [ +  - ]:          12 :   m_icons.clear();
      49         [ +  - ]:          12 :   m_lookup.clear();
      50   [ +  -  +  + ]:       89388 :   while (!ts.atEnd()) {
      51   [ +  -  +  - ]:       89376 :     QString line = ts.readLine().trimmed();
      52         [ -  + ]:       89376 :     if (line.isEmpty())
      53                 :           0 :       continue;
      54                 :       89376 :     int comma = line.indexOf(',');
      55         [ -  + ]:       89376 :     if (comma < 0)
      56                 :           0 :       continue;
      57         [ +  - ]:       89376 :     QString name = line.left(comma);
      58                 :             :     bool ok;
      59   [ +  -  +  - ]:       89376 :     uint cp = line.mid(comma + 1).toUInt(&ok, 16);
      60         [ -  + ]:       89376 :     if (!ok)
      61                 :           0 :       continue;
      62                 :       89376 :     m_icons.append({name, cp});
      63         [ +  - ]:       89376 :     m_lookup.insert(name, cp);
      64   [ +  -  +  - ]:       89376 :   }
      65   [ +  -  +  -  :          24 :   qCInfo(lcMdi) << "MDI codemap loaded:" << m_icons.size() << "icons";
          +  -  +  -  +  
                -  +  + ]
      66                 :          12 :   m_ready = true;
      67   [ +  -  +  -  :       89388 : }
             +  -  -  - ]
      68                 :             : 
      69                 :       74935 : QIcon MdiIconProvider::icon(const QString &name, int size,
      70                 :             :                             const QColor &colorIn) {
      71         [ +  - ]:       74935 :   ensureInit();
      72         [ +  + ]:       74935 :   if (!m_ready)
      73                 :          62 :     return {};
      74                 :             : 
      75                 :             :   // 67.B3: default (invalid) color → theme secondary text color
      76                 :             :   const QColor color =
      77                 :       74873 :       colorIn.isValid()
      78                 :       74873 :           ? colorIn
      79   [ +  -  +  -  :      223833 :           : QColor(ThemeManager::instance().color(
             +  +  -  - ]
      80   [ +  +  +  +  :      298706 :                 QStringLiteral("@text_secondary")));
          +  +  -  -  -  
                      - ]
      81                 :             : 
      82         [ +  - ]:       74873 :   auto it = m_lookup.constFind(name);
      83   [ +  -  -  + ]:       74873 :   if (it == m_lookup.constEnd())
      84                 :           0 :     return {};
      85                 :             : 
      86                 :      149746 :   QString cacheKey = QStringLiteral("%1@%2@%3")
      87         [ +  - ]:      149746 :                          .arg(name)
      88         [ +  - ]:      149746 :                          .arg(size)
      89         [ +  - ]:       74873 :                          .arg(color.rgba(), 0, 16);
      90         [ +  + ]:       74873 :   if (QIcon *cached = m_cache[cacheKey])
      91         [ +  - ]:         342 :     return *cached;
      92                 :             : 
      93                 :             :   // Render glyph via QPainter
      94         [ +  - ]:       74531 :   QPixmap pix(size, size);
      95         [ +  - ]:       74531 :   pix.fill(Qt::transparent);
      96         [ +  - ]:       74531 :   QPainter p(&pix);
      97         [ +  - ]:       74531 :   QFont f = m_font;
      98         [ +  - ]:       74531 :   f.setPixelSize(size - 2);
      99         [ +  - ]:       74531 :   p.setFont(f);
     100         [ +  - ]:       74531 :   p.setPen(color);
     101                 :       74531 :   uint cp = it.value();
     102                 :       74531 :   QString glyphStr;
     103         [ +  + ]:       74531 :   if (cp <= 0xFFFF) {
     104         [ +  - ]:          10 :     glyphStr = QChar(static_cast<ushort>(cp));
     105                 :             :   } else {
     106                 :       74521 :     char32_t cp32 = static_cast<char32_t>(cp);
     107         [ +  - ]:       74521 :     glyphStr = QString::fromUcs4(&cp32, 1);
     108                 :             :   }
     109         [ +  - ]:       74531 :   p.drawText(QRect(0, 0, size, size), Qt::AlignCenter, glyphStr);
     110         [ +  - ]:       74531 :   p.end();
     111                 :             : 
     112   [ +  -  +  -  :       74531 :   auto *icon = new QIcon(pix);
             -  +  -  - ]
     113         [ +  - ]:       74531 :   m_cache.insert(cacheKey, icon);
     114         [ +  - ]:       74531 :   return *icon;
     115                 :       74873 : }
     116                 :             : 
     117                 :       74945 : void MdiIconProvider::ensureInit() {
     118         [ +  + ]:       74945 :   if (!m_ready)
     119                 :          74 :     init();
     120                 :       74945 : }
        

Generated by: LCOV version 2.0-1