From 2aed8a120982c7e04b7e6d94c39b4a1e7a10343e Mon Sep 17 00:00:00 2001 From: blue Date: Sun, 8 Jan 2023 18:16:41 +0300 Subject: [PATCH] a bit better drawing of a key fingerprint --- ui/widgets/vcard/omemo/keydelegate.cpp | 79 +++++++++++++++++++++++--- ui/widgets/vcard/omemo/keydelegate.h | 7 +++ 2 files changed, 77 insertions(+), 9 deletions(-) diff --git a/ui/widgets/vcard/omemo/keydelegate.cpp b/ui/widgets/vcard/omemo/keydelegate.cpp index 1816ecd..2ab969d 100644 --- a/ui/widgets/vcard/omemo/keydelegate.cpp +++ b/ui/widgets/vcard/omemo/keydelegate.cpp @@ -22,10 +22,15 @@ constexpr int minHeight = 50; constexpr int minWidth = 400; +constexpr uint8_t margin = 10; +constexpr uint8_t partSize = 8; +constexpr uint8_t maxSingleLineParts = 3; UI::KeyDelegate::KeyDelegate(QObject* parent): QStyledItemDelegate(parent), - fingerPrintFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)) + fingerPrintFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)), + fingerPrintMetrics(fingerPrintFont), + spaceWidth(fingerPrintMetrics.horizontalAdvance(" ")) { } @@ -46,14 +51,31 @@ void UI::KeyDelegate::paint(QPainter* painter, const QStyleOptionViewItem& optio QVariant fingerPrintV = index.data(UI::KeysModel::FingerPrint); if (fingerPrintV.isValid()) { painter->save(); - QByteArray fingerPrint = fingerPrintV.toByteArray(); - painter->setFont(fingerPrintFont); - painter->drawText(option.rect, option.displayAlignment | Qt::AlignTop, fingerPrint.toHex()); + QByteArray fingerPrint = fingerPrintV.toByteArray(); + std::vector parts = getParts(fingerPrint); + uint8_t partsLength = parts.size(); + QRect rect = option.rect; + rect.adjust(margin, margin, 0, 0); + QRect r; + uint8_t firstLine; + if (partsLength > maxSingleLineParts) + firstLine = partsLength / 2 + partsLength % 2; + else + firstLine = partsLength; + + for (uint8_t i = 0; i < partsLength; ++i) { + if (i == firstLine) { + rect.setLeft(option.rect.left() + margin); + rect.adjust(0, r.height() + fingerPrintMetrics.leading(), 0, 0); + } + painter->drawText(rect, Qt::AlignLeft | Qt::AlignTop, parts[i], &r); + rect.adjust(r.width() + spaceWidth ,0, 0, 0); + } painter->restore(); } - painter->drawText(option.rect, option.displayAlignment, index.data().toString()); + //painter->drawText(option.rect, option.displayAlignment, index.data().toString()); painter->restore(); } @@ -61,11 +83,50 @@ void UI::KeyDelegate::paint(QPainter* painter, const QStyleOptionViewItem& optio QSize UI::KeyDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const { QSize size = QStyledItemDelegate::sizeHint(option, index); - if (size.width() < minWidth) - size.setWidth(minWidth); + int mh = margin * 2; + int mw = margin * 2; + QVariant fingerPrintV = index.data(UI::KeysModel::FingerPrint); + if (fingerPrintV.isValid()) { + QString hex = fingerPrintV.toByteArray().toHex(); + uint8_t parts = hex.size() / partSize; - if (size.height() < minHeight) - size.setHeight(minHeight); + mh += fingerPrintMetrics.height(); + if (parts > maxSingleLineParts) { + mh += fingerPrintMetrics.height() + fingerPrintMetrics.leading(); + } + + uint8_t firstLine; + if (parts > maxSingleLineParts) + firstLine = parts / 2 + parts % 2; + else + firstLine = parts; + + mw += firstLine * partSize * spaceWidth + (firstLine - 1) * spaceWidth; + } + + + if (size.width() < mw) + size.setWidth(mw); + + if (size.height() < mh) + size.setHeight(mh); return size; } + +std::vector UI::KeyDelegate::getParts(const QByteArray& data) { + QString hex = data.toHex(); + uint8_t parts = hex.size() / partSize; + std::vector result(parts); + for (uint8_t i = 0; i < parts; ++i) { + uint16_t index = i * partSize; + uint8_t length = partSize; + if (index + length > hex.size()) + length = hex.size() - index; + QStringRef part(&hex, index, length); + result[i] = part.toString(); + } + + return result; +} + diff --git a/ui/widgets/vcard/omemo/keydelegate.h b/ui/widgets/vcard/omemo/keydelegate.h index d1f768b..0ce3e7f 100644 --- a/ui/widgets/vcard/omemo/keydelegate.h +++ b/ui/widgets/vcard/omemo/keydelegate.h @@ -18,6 +18,8 @@ #define UI_KEYDELEGATE_H #include +#include +#include namespace UI { @@ -32,6 +34,11 @@ public: private: QFont fingerPrintFont; + QFontMetrics fingerPrintMetrics; + int spaceWidth; + +private: + static std::vector getParts(const QByteArray& data); }; }