// Squawk messenger. // Copyright (C) 2019 Yury Gubich // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "keydelegate.h" #include #include "keysmodel.h" #include constexpr uint8_t margin = 10; constexpr uint8_t partSize = 8; constexpr uint8_t maxSingleLineParts = 3; UI::KeyDelegate::KeyDelegate(QObject* parent): QStyledItemDelegate(parent), fingerPrintFont(Shared::Global::getInstance()->defaultFont), labelFont(Shared::Global::getInstance()->smallFont), fingerPrintMetrics(Shared::Global::getInstance()->defaultFontMetrics), labelFontMetrics(Shared::Global::getInstance()->smallFontMetrics), spaceWidth(fingerPrintMetrics.horizontalAdvance(" ")) {} UI::KeyDelegate::~KeyDelegate() {} void UI::KeyDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { painter->save(); painter->setRenderHint(QPainter::Antialiasing, true); bool hover = option.state & QStyle::State_MouseOver; if (hover) { painter->save(); painter->fillRect(option.rect, option.palette.brush(QPalette::Inactive, QPalette::Highlight)); painter->restore(); } QColor q = painter->pen().color(); q.setAlpha(180); QRect rect = option.rect; rect.adjust(margin, margin, 0, 0); QVariant labelV = index.data(UI::KeysModel::Label); if (labelV.isValid()) { QString label = labelV.toString(); if (label.size() > 0) { painter->save(); painter->setFont(labelFont); painter->setPen(q); painter->drawText(rect, Qt::AlignLeft | Qt::AlignTop, label); rect.adjust(0, labelFontMetrics.lineSpacing(), 0, 0); painter->restore(); } } QVariant fingerPrintV = index.data(UI::KeysModel::FingerPrint); if (fingerPrintV.isValid()) { painter->save(); painter->setFont(fingerPrintFont); QByteArray fingerPrint = fingerPrintV.toByteArray(); std::vector parts = getParts(fingerPrint); uint8_t partsLength = parts.size(); 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); } rect.adjust(0, r.height() + fingerPrintMetrics.leading(), 0, 0); rect.setLeft(option.rect.left() + margin); painter->restore(); } QVariant lastV = index.data(UI::KeysModel::LastInteraction); if (lastV.isValid()) { QDateTime last = lastV.toDateTime(); if (last.isValid()) { painter->save(); painter->setFont(labelFont); painter->setPen(q); painter->drawText(rect, Qt::AlignLeft | Qt::AlignTop, last.toString()); rect.adjust(0, labelFontMetrics.lineSpacing(), 0, 0); painter->restore(); } } //painter->drawText(option.rect, option.displayAlignment, index.data().toString()); painter->restore(); } QSize UI::KeyDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const { QSize size = QStyledItemDelegate::sizeHint(option, index); int mh = margin * 2; int mw = margin * 2; QVariant labelV = index.data(UI::KeysModel::Label); if (labelV.isValid() && labelV.toString().size() > 0) { mh += labelFontMetrics.lineSpacing(); } QVariant fingerPrintV = index.data(UI::KeysModel::FingerPrint); if (fingerPrintV.isValid()) { QString hex = fingerPrintV.toByteArray().toHex(); uint8_t parts = hex.size() / partSize; 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; } QVariant lastV = index.data(UI::KeysModel::LastInteraction); if (lastV.isValid() && lastV.toDateTime().isValid()) { mh += labelFontMetrics.lineSpacing(); } 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; }