blob: da4bd9cf69b12ed6cdd2429989fb2053ae5890e7 [file] [log] [blame]
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04001/***************************************************************************
Sébastien Blin68abac92019-01-02 17:41:31 -05002 * Copyright (C) 2019-2019 by Savoir-faire Linux *
Andreas Traczykb8b13ba2018-08-21 16:30:16 -04003 * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com> *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 3 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
17 **************************************************************************/
18
19#include "accountitemdelegate.h"
20
21#include <QApplication>
22#include <QTextDocument>
23#include <QPixmap>
24
25#include "utils.h"
26#include "accountlistmodel.h"
27#include "ringthemeutils.h"
Andreas Traczyk6ace34f2018-12-14 14:31:23 -050028#include "lrcinstance.h"
Andreas Traczyk46508b52019-01-04 11:49:24 -050029#include "mainwindow.h"
Andreas Traczykb8b13ba2018-08-21 16:30:16 -040030
31#undef REGISTERED
32
33AccountItemDelegate::AccountItemDelegate(QObject *parent)
34 : QItemDelegate(parent)
35{
36}
37
38void
39AccountItemDelegate::paint(QPainter* painter,
40 const QStyleOptionViewItem& option,
41 const QModelIndex& index) const
42{
43 QStyleOptionViewItem opt(option);
44 painter->setRenderHint(QPainter::Antialiasing);
45
46 // Not having focus removes dotted lines around the item
47 if (opt.state & QStyle::State_HasFocus) {
48 opt.state.setFlag(QStyle::State_HasFocus, false);
49 }
50
51 // First, we draw the control itself
52 QStyle* style = opt.widget ? opt.widget->style() : QApplication::style();
53 style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, opt.widget);
54
Andreas Traczykdc2703e2019-01-17 18:02:31 -050055 QColor presenceBorderColor = Qt::white;
Andreas Traczykb8b13ba2018-08-21 16:30:16 -040056 bool selected = false;
57 if (option.state & QStyle::State_Selected) {
58 selected = true;
59 opt.state ^= QStyle::State_Selected;
60 painter->fillRect(option.rect, RingTheme::smartlistSelection_);
Andreas Traczykdc2703e2019-01-17 18:02:31 -050061 presenceBorderColor = RingTheme::smartlistSelection_;
Andreas Traczykb8b13ba2018-08-21 16:30:16 -040062 }
63 else if (option.state & QStyle::State_MouseOver) {
64 painter->fillRect(option.rect, RingTheme::smartlistHighlight_);
Andreas Traczykdc2703e2019-01-17 18:02:31 -050065 presenceBorderColor = RingTheme::smartlistHighlight_;
Andreas Traczykb8b13ba2018-08-21 16:30:16 -040066 }
67
68 QRect &rect = opt.rect;
69
Andreas Traczyk46508b52019-01-04 11:49:24 -050070 // define and set the two fonts
71 QFont fontPrimary = painter->font();
72 QFont fontSecondary = painter->font();
73 fontPrimary.setWeight(QFont::ExtraLight);
74 auto scalingRatio = MainWindow::instance().getCurrentScalingRatio();
75 if (scalingRatio > 1.0) {
76 fontPrimary.setPointSize(fontSize_ - 1);
77 fontSecondary.setPointSize(fontSize_ - 2);
78 } else {
79 fontPrimary.setPointSize(fontSize_);
80 fontSecondary.setPointSize(fontSize_ - 1);
81 }
Andreas Traczyk29650142019-01-03 20:33:56 -050082
Andreas Traczyk6ace34f2018-12-14 14:31:23 -050083 QPen pen(painter->pen());
84
85 // is it the add account row?
86 if (index.row() == LRCInstance::accountModel().getAccountList().size()) {
87 pen.setColor(RingTheme::lightBlack_);
88 painter->setPen(pen);
Andreas Traczyk46508b52019-01-04 11:49:24 -050089 painter->setFont(fontPrimary);
90 QFontMetrics fontMetrics(fontPrimary);
Andreas Traczyk6ace34f2018-12-14 14:31:23 -050091 painter->drawText(rect, Qt::AlignVCenter | Qt::AlignHCenter, tr("Add Account") + "+");
92 return;
93 }
94
Andreas Traczykb8b13ba2018-08-21 16:30:16 -040095 // Avatar drawing
96 opt.decorationSize = QSize(avatarSize_, avatarSize_);
97 opt.decorationPosition = QStyleOptionViewItem::Left;
98 opt.decorationAlignment = Qt::AlignCenter;
99
Andreas Traczyk29650142019-01-03 20:33:56 -0500100 QRect rectAvatar(
101 leftPadding_ + rect.left(),
102 rect.top() + topPadding_,
103 avatarSize_,
104 avatarSize_
105 );
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400106 drawDecoration(painter, opt, rectAvatar,
107 QPixmap::fromImage(index.data(AccountListModel::Role::Picture).value<QImage>())
108 .scaled(avatarSize_, avatarSize_, Qt::KeepAspectRatio, Qt::SmoothTransformation));
109
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400110 auto status = index.data(static_cast<int>(AccountListModel::Role::Status)).value<int>();
111 auto isPresent = Utils::toEnum<lrc::api::account::Status>(status) == lrc::api::account::Status::REGISTERED;
Andreas Traczyk1c1302c2018-12-31 12:28:16 -0500112 // Presence indicator
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400113 if (isPresent) {
Andreas Traczyk1c1302c2018-12-31 12:28:16 -0500114 QPainterPath outerCircle, innerCircle;
115 QPointF center(rectAvatar.right() - avatarSize_ / 6, (rectAvatar.bottom() - avatarSize_ / 6) + 1);
116 qreal outerCRadius = avatarSize_ / 6, innerCRadius = outerCRadius * 0.75;
117 outerCircle.addEllipse(center, outerCRadius, outerCRadius);
118 innerCircle.addEllipse(center, innerCRadius, innerCRadius);
Andreas Traczykdc2703e2019-01-17 18:02:31 -0500119 painter->fillPath(outerCircle, presenceBorderColor);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400120 painter->fillPath(innerCircle, RingTheme::presenceGreen_);
121 }
122
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400123 painter->setPen(pen);
124
Andreas Traczyk29650142019-01-03 20:33:56 -0500125 QRect rectTexts(leftPadding_ + rect.left() + leftPadding_ + avatarSize_,
126 rect.top() + topPadding_ / 2,
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400127 rect.width(),
128 rect.height() / 2);
129
130 // The name is displayed at the avatar's right
131 QVariant name = index.data(static_cast<int>(AccountListModel::Role::Alias));
132 if (name.isValid())
133 {
Andreas Traczyk46508b52019-01-04 11:49:24 -0500134 fontPrimary.setItalic(false);
135 fontPrimary.setBold(false);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400136 pen.setColor(RingTheme::lightBlack_);
137 painter->setPen(pen);
Andreas Traczyk46508b52019-01-04 11:49:24 -0500138 painter->setFont(fontPrimary);
139 QFontMetrics fontMetrics(fontPrimary);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400140 QString nameStr = fontMetrics.elidedText(name.value<QString>(), Qt::ElideRight,
Andreas Traczyk29650142019-01-03 20:33:56 -0500141 rectTexts.width() - avatarSize_ - leftPadding_ - rightPadding_ * 2);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400142 painter->drawText(rectTexts, Qt::AlignVCenter | Qt::AlignLeft, nameStr);
143 }
144
Isa Nanicf7e07922018-10-29 10:52:05 -0400145 // Display the secondary ID under the name
146
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400147 QString idStr = index.data(static_cast<int>(AccountListModel::Role::Username)).value<QString>();
148 if (idStr != name.toString()) {
Andreas Traczyk46508b52019-01-04 11:49:24 -0500149 fontSecondary.setItalic(false);
150 fontSecondary.setBold(false);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400151 pen.setColor(RingTheme::grey_);
152 painter->setPen(pen);
Andreas Traczyk46508b52019-01-04 11:49:24 -0500153 painter->setFont(fontSecondary);
154 QFontMetrics fontMetrics(fontSecondary);
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400155 if (!idStr.isNull()) {
156 idStr = fontMetrics.elidedText(idStr, Qt::ElideRight,
Andreas Traczyk29650142019-01-03 20:33:56 -0500157 rectTexts.width() - avatarSize_ - leftPadding_ - rightPadding_ * 2);
158 painter->drawText(QRect(leftPadding_ + rect.left() + leftPadding_ + avatarSize_,
159 rect.top() + topPadding_ * 3,
Andreas Traczykb8b13ba2018-08-21 16:30:16 -0400160 rect.width(),
161 rect.height() / 2),
162 Qt::AlignBottom | Qt::AlignLeft, idStr);
163 }
164 }
165}
166
167QSize AccountItemDelegate::sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const
168{
169 QSize size = QItemDelegate::sizeHint(option, index);
170 size.setHeight(cellHeight_);
171 return size;
172}