blob: 76f3cb0cab774ddc2ba1cd31a2231a8a31a15395 [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) {
Anthony Léonard04097312017-07-17 11:54:27 -040097 painter->fillPath(path, RingTheme::imBlue_);
Nicolas Jagerd0b33752016-01-17 00:00:40 -050098 }
99 else {
Anthony Léonard04097312017-07-17 11:54:27 -0400100 painter->fillPath(path, RingTheme::imGrey_);
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
Anthony Léonard04097312017-07-17 11:54:27 -0400108 document.setDefaultStyleSheet("body { color : black; } i { opacity: 100; font-size : 11px; text-align : right; }");
Edric Milaret70ae8782016-04-18 16:10:44 -0400109
110 document.setHtml(msg);
111
112 auto textOptions = QTextOption(Qt::AlignLeft);
113 textOptions.setWrapMode(QTextOption::WrapMode::WordWrap);
114 document.setDefaultTextOption(textOptions);
115 document.setTextWidth(textRect.width());
116
117 painter->translate(textRect.topLeft());
118 document.drawContents(painter);
119 painter->restore();
Edric Milaret83b248c2015-06-02 11:42:23 -0400120 }
121}
122
Edric Milaret70ae8782016-04-18 16:10:44 -0400123QRect ImDelegate::getBoundingRect(const Qt::AlignmentFlag& dir,
124 const QString& msg,
125 const QStyleOptionViewItem &option) const
Edric Milaret83b248c2015-06-02 11:42:23 -0400126{
Edric Milareta0ebd062016-01-13 12:18:23 -0500127 QRect textRect;
128
Edric Milaret70ae8782016-04-18 16:10:44 -0400129 QTextDocument txtDoc;
130 txtDoc.setDefaultFont(fontMsg_);
131 txtDoc.setHtml(msg);
132 auto textOptions = QTextOption(Qt::AlignLeft);
133 textOptions.setWrapMode(QTextOption::WrapMode::WordWrap);
134 txtDoc.setDefaultTextOption(textOptions);
135
136 if (dir == Qt::AlignLeft) {
137 txtDoc.setTextWidth(option.rect.width() - iconSize_.width() - padding_);
138 textRect.setRect(option.rect.left() + iconSize_.width() + padding_,
139 option.rect.top() + padding_,
140 txtDoc.idealWidth(),
141 txtDoc.size().height());
Edric Milareta0ebd062016-01-13 12:18:23 -0500142 } else {
Edric Milaret70ae8782016-04-18 16:10:44 -0400143 txtDoc.setTextWidth(option.rect.width() - padding_);
144 textRect.setRect(option.rect.right() - padding_ - txtDoc.idealWidth(),
145 option.rect.top() + padding_,
146 txtDoc.idealWidth(),
147 txtDoc.size().height());
Edric Milareta0ebd062016-01-13 12:18:23 -0500148 }
149 return textRect;
150}
151
152QSize
153ImDelegate::sizeHint(const QStyleOptionViewItem& option,
154 const QModelIndex& index) const
155{
Nicolas Jagerd0b33752016-01-17 00:00:40 -0500156 QStyleOptionViewItem opt = option;
157 opt.font = fontMsg_;
158
Edric Milaret70ae8782016-04-18 16:10:44 -0400159 QString msg = index.data(static_cast<int>(Media::TextRecording::Role::FormattedHtml)).toString();
Edric Milareta0ebd062016-01-13 12:18:23 -0500160
161 auto dir = index.data(
162 static_cast<int>(Media::TextRecording::Role::Direction))
163 .value<Media::Media::Direction>() == Media::Media::Direction::IN
164 ? Qt::AlignLeft : Qt::AlignRight;
165
166 formatMsg(index, msg);
167
Nicolas Jagerd0b33752016-01-17 00:00:40 -0500168 QRect boundingRect = getBoundingRect(dir, msg, opt);
Edric Milareta0ebd062016-01-13 12:18:23 -0500169
Edric Milaret70ae8782016-04-18 16:10:44 -0400170 QSize size(option.rect.width(), boundingRect.height());
Edric Milareta0ebd062016-01-13 12:18:23 -0500171
172 /* Keep the minimum height needed. */
173 if(size.height() < iconSize_.height())
Edric Milaret70ae8782016-04-18 16:10:44 -0400174 size.setHeight(iconSize_.height());
175
176 size.setHeight(size.height() + 2 * padding_);
Edric Milareta0ebd062016-01-13 12:18:23 -0500177
178 return size;
Edric Milaret83b248c2015-06-02 11:42:23 -0400179}
180