blob: db4f1e7a868eac5994b4361d3e4ba1ef8182224b [file] [log] [blame]
Edric Milaret83b248c2015-06-02 11:42:23 -04001/***************************************************************************
Anthony LĂ©onard2fde81d2017-04-17 10:06:55 -04002 * Copyright (C) 2015-2017 by Savoir-faire Linux *
Edric Milaret83b248c2015-06-02 11:42:23 -04003 * Author: Edric Ladent Milaret <edric.ladent-milaret@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 "imdelegate.h"
20
Edric Milaret4e370992016-01-20 11:29:32 -050021#include <QApplication>
Edric Milaret70ae8782016-04-18 16:10:44 -040022#include <QTextDocument>
23#include <QSettings>
24#include <QDateTime>
Edric Milaret4e370992016-01-20 11:29:32 -050025
Edric Milaret83b248c2015-06-02 11:42:23 -040026#include "media/text.h"
27#include "media/textrecording.h"
28
Edric Milaret4e370992016-01-20 11:29:32 -050029#include "ringthemeutils.h"
Edric Milaret70ae8782016-04-18 16:10:44 -040030#include "settingskey.h"
Edric Milareta0ebd062016-01-13 12:18:23 -050031
Edric Milaret83b248c2015-06-02 11:42:23 -040032ImDelegate::ImDelegate(QObject *parent)
Edric Milaret70ae8782016-04-18 16:10:44 -040033 : QStyledItemDelegate(parent)
Edric Milaret83b248c2015-06-02 11:42:23 -040034{
Edric Milaret83b248c2015-06-02 11:42:23 -040035}
36
37void
Edric Milareta0ebd062016-01-13 12:18:23 -050038ImDelegate::formatMsg(const QModelIndex& index, QString& msg) const
39{
Edric Milaret70ae8782016-04-18 16:10:44 -040040 QSettings settings;
41 QStringList meta;
42 if (settings.value(SettingsKey::imShowAuthor).toBool()) {
43 meta << index.data(
Edric Milareta0ebd062016-01-13 12:18:23 -050044 static_cast<int>(Media::TextRecording::Role::AuthorDisplayname)).toString();
Edric Milareta0ebd062016-01-13 12:18:23 -050045 }
Edric Milaret70ae8782016-04-18 16:10:44 -040046 if (settings.value(SettingsKey::imShowDate).toBool()) {
47 auto timeStamp = index.data(
48 static_cast<int>(Media::TextRecording::Role::Timestamp)).value<uint>();
49 auto date = QDateTime::fromTime_t(timeStamp);
50 auto now = QDateTime::currentDateTime();
51 if (now.date() == date.date())
52 meta << date.time().toString();
53 else
54 meta << date.toString();
Edric Milareta0ebd062016-01-13 12:18:23 -050055 }
Edric Milaret70ae8782016-04-18 16:10:44 -040056 msg = QString("%2<footer><i>%1</i></footer>").arg(meta.join(" - "), msg);
Edric Milareta0ebd062016-01-13 12:18:23 -050057}
58
59void
60ImDelegate::paint(QPainter* painter,
61 const QStyleOptionViewItem& option,
62 const QModelIndex& index) const
Edric Milaret83b248c2015-06-02 11:42:23 -040063{
Edric Milareted0b2802015-10-01 15:10:02 -040064 QStyleOptionViewItem opt = option;
Edric Milaret83b248c2015-06-02 11:42:23 -040065 initStyleOption(&opt, index);
Edric Milaretda51e382016-01-15 15:47:14 -050066 painter->setRenderHint(QPainter::Antialiasing);
67
Nicolas Jagerd0b33752016-01-17 00:00:40 -050068 opt.font = fontMsg_;
69 painter->setFont(fontMsg_);
70
Edric Milaret83b248c2015-06-02 11:42:23 -040071 if (index.isValid()) {
Edric Milaret70ae8782016-04-18 16:10:44 -040072 auto msg = index.data(static_cast<int>(Media::TextRecording::Role::FormattedHtml)).toString();
Edric Milareted0b2802015-10-01 15:10:02 -040073 opt.text.clear();
Edric Milareta0ebd062016-01-13 12:18:23 -050074 QStyle* style = opt.widget ? opt.widget->style() : QApplication::style();
Edric Milareta0ebd062016-01-13 12:18:23 -050075
76 auto dir = index.data(static_cast<int>(Media::TextRecording::Role::Direction))
Edric Milaret83b248c2015-06-02 11:42:23 -040077 .value<Media::Media::Direction>() == Media::Media::Direction::IN
78 ? Qt::AlignLeft : Qt::AlignRight;
79
Edric Milareta0ebd062016-01-13 12:18:23 -050080 formatMsg(index, msg);
81
82 QRect textRect = getBoundingRect(dir, msg, opt);
Nicolas Jagerd0b33752016-01-17 00:00:40 -050083
Edric Milaret70ae8782016-04-18 16:10:44 -040084 if (dir == Qt::AlignLeft) {
85 opt.decorationSize = iconSize_;
86 opt.decorationPosition = (dir == Qt::AlignRight ?
87 QStyleOptionViewItem::Right : QStyleOptionViewItem::Left);
88 opt.decorationAlignment = Qt::AlignTop | Qt::AlignHCenter;
89 } else
90 opt.decorationSize = QSize();
Edric Milareta0ebd062016-01-13 12:18:23 -050091 style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, opt.widget);
Edric Milaretda51e382016-01-15 15:47:14 -050092
Edric Milaretda51e382016-01-15 15:47:14 -050093 QPainterPath path;
Edric Milaret70ae8782016-04-18 16:10:44 -040094 path.addRoundedRect(textRect, padding_, padding_);
Nicolas Jagerd0b33752016-01-17 00:00:40 -050095
96 if (dir == Qt::AlignRight) {
Edric Milaret4e370992016-01-20 11:29:32 -050097 painter->fillPath(path, RingTheme::blue_);
Nicolas Jagerd0b33752016-01-17 00:00:40 -050098 }
99 else {
100 painter->fillPath(path, Qt::white);
Nicolas Jagerd0b33752016-01-17 00:00:40 -0500101 }
Edric Milaretda51e382016-01-15 15:47:14 -0500102
Edric Milaret70ae8782016-04-18 16:10:44 -0400103 painter->save();
104
105 QTextDocument document;
106 document.setDefaultFont(fontMsg_);
107
108 if (dir == Qt::AlignRight)
109 document.setDefaultStyleSheet("body { color : white; } i { opacity: 100; font-size : 11px; text-align : right; }");
110 else
111 document.setDefaultStyleSheet("body { color : black; } i { opacity: 100; font-size : 11px; text-align : right; }");
112
113 document.setHtml(msg);
114
115 auto textOptions = QTextOption(Qt::AlignLeft);
116 textOptions.setWrapMode(QTextOption::WrapMode::WordWrap);
117 document.setDefaultTextOption(textOptions);
118 document.setTextWidth(textRect.width());
119
120 painter->translate(textRect.topLeft());
121 document.drawContents(painter);
122 painter->restore();
Edric Milaret83b248c2015-06-02 11:42:23 -0400123 }
124}
125
Edric Milaret70ae8782016-04-18 16:10:44 -0400126QRect ImDelegate::getBoundingRect(const Qt::AlignmentFlag& dir,
127 const QString& msg,
128 const QStyleOptionViewItem &option) const
Edric Milaret83b248c2015-06-02 11:42:23 -0400129{
Edric Milareta0ebd062016-01-13 12:18:23 -0500130 QRect textRect;
131
Edric Milaret70ae8782016-04-18 16:10:44 -0400132 QTextDocument txtDoc;
133 txtDoc.setDefaultFont(fontMsg_);
134 txtDoc.setHtml(msg);
135 auto textOptions = QTextOption(Qt::AlignLeft);
136 textOptions.setWrapMode(QTextOption::WrapMode::WordWrap);
137 txtDoc.setDefaultTextOption(textOptions);
138
139 if (dir == Qt::AlignLeft) {
140 txtDoc.setTextWidth(option.rect.width() - iconSize_.width() - padding_);
141 textRect.setRect(option.rect.left() + iconSize_.width() + padding_,
142 option.rect.top() + padding_,
143 txtDoc.idealWidth(),
144 txtDoc.size().height());
Edric Milareta0ebd062016-01-13 12:18:23 -0500145 } else {
Edric Milaret70ae8782016-04-18 16:10:44 -0400146 txtDoc.setTextWidth(option.rect.width() - padding_);
147 textRect.setRect(option.rect.right() - padding_ - txtDoc.idealWidth(),
148 option.rect.top() + padding_,
149 txtDoc.idealWidth(),
150 txtDoc.size().height());
Edric Milareta0ebd062016-01-13 12:18:23 -0500151 }
152 return textRect;
153}
154
155QSize
156ImDelegate::sizeHint(const QStyleOptionViewItem& option,
157 const QModelIndex& index) const
158{
Nicolas Jagerd0b33752016-01-17 00:00:40 -0500159 QStyleOptionViewItem opt = option;
160 opt.font = fontMsg_;
161
Edric Milaret70ae8782016-04-18 16:10:44 -0400162 QString msg = index.data(static_cast<int>(Media::TextRecording::Role::FormattedHtml)).toString();
Edric Milareta0ebd062016-01-13 12:18:23 -0500163
164 auto dir = index.data(
165 static_cast<int>(Media::TextRecording::Role::Direction))
166 .value<Media::Media::Direction>() == Media::Media::Direction::IN
167 ? Qt::AlignLeft : Qt::AlignRight;
168
169 formatMsg(index, msg);
170
Nicolas Jagerd0b33752016-01-17 00:00:40 -0500171 QRect boundingRect = getBoundingRect(dir, msg, opt);
Edric Milareta0ebd062016-01-13 12:18:23 -0500172
Edric Milaret70ae8782016-04-18 16:10:44 -0400173 QSize size(option.rect.width(), boundingRect.height());
Edric Milareta0ebd062016-01-13 12:18:23 -0500174
175 /* Keep the minimum height needed. */
176 if(size.height() < iconSize_.height())
Edric Milaret70ae8782016-04-18 16:10:44 -0400177 size.setHeight(iconSize_.height());
178
179 size.setHeight(size.height() + 2 * padding_);
Edric Milareta0ebd062016-01-13 12:18:23 -0500180
181 return size;
Edric Milaret83b248c2015-06-02 11:42:23 -0400182}
183