imdelegate.cpp 6.24 KB
Newer Older
Edric Milaret's avatar
Edric Milaret committed
1
/***************************************************************************
2
 * Copyright (C) 2015-2016 by Savoir-faire Linux                           *
Edric Milaret's avatar
Edric Milaret committed
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
 * Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>*
 *                                                                         *
 * 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 <http://www.gnu.org/licenses/>.   *
 **************************************************************************/

#include "imdelegate.h"

21 22
#include <QApplication>

Edric Milaret's avatar
Edric Milaret committed
23 24 25
#include "media/text.h"
#include "media/textrecording.h"

26
#include "ringthemeutils.h"
Edric Milaret's avatar
Edric Milaret committed
27

Edric Milaret's avatar
Edric Milaret committed
28 29 30 31 32 33 34 35
ImDelegate::ImDelegate(QObject *parent)
    : QStyledItemDelegate(parent), showDate_(false), showAuthor_(false)
{}

void ImDelegate::setDisplayOptions(ImDelegate::DisplayOptions opt)
{
    showAuthor_ = opt & DisplayOptions::AUTHOR;
    showDate_ = opt & DisplayOptions::DATE;
Edric Milaret's avatar
Edric Milaret committed
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
    emit sizeHintChanged(QModelIndex());
}

void
ImDelegate::formatMsg(const QModelIndex& index, QString& msg) const
{
    if (showAuthor_) {
        auto author = index.data(
                    static_cast<int>(Media::TextRecording::Role::AuthorDisplayname)).toString();
        msg = QString("(%1)\n%2").arg(author, msg);
    }
    if (showDate_) {
        auto formattedDate = index.data(
                    static_cast<int>(Media::TextRecording::Role::FormattedDate)).toString();
        msg = QString("%2\n%1").arg(formattedDate, msg);
    }
Edric Milaret's avatar
Edric Milaret committed
52 53 54
}

void
Edric Milaret's avatar
Edric Milaret committed
55 56 57
ImDelegate::paint(QPainter* painter,
                  const QStyleOptionViewItem& option,
                  const QModelIndex& index) const
Edric Milaret's avatar
Edric Milaret committed
58
{
59
    QStyleOptionViewItem opt = option;
Edric Milaret's avatar
Edric Milaret committed
60
    initStyleOption(&opt, index);
61 62
    painter->setRenderHint(QPainter::Antialiasing);

63 64 65
    opt.font = fontMsg_;
    painter->setFont(fontMsg_);

Edric Milaret's avatar
Edric Milaret committed
66
    if (index.isValid()) {
Edric Milaret's avatar
Edric Milaret committed
67
        auto msg = index.data(Qt::DisplayRole).toString();
68
        opt.text.clear();
Edric Milaret's avatar
Edric Milaret committed
69
        QStyle* style = opt.widget ? opt.widget->style() : QApplication::style();
Edric Milaret's avatar
Edric Milaret committed
70 71 72 73
        QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled
                ? QPalette::Normal : QPalette::Disabled;
        if (cg == QPalette::Normal && !(opt.state & QStyle::State_Active))
            cg = QPalette::Inactive;
Edric Milaret's avatar
Edric Milaret committed
74 75

        auto dir = index.data(static_cast<int>(Media::TextRecording::Role::Direction))
Edric Milaret's avatar
Edric Milaret committed
76 77 78
                .value<Media::Media::Direction>() == Media::Media::Direction::IN
                ? Qt::AlignLeft : Qt::AlignRight;

Edric Milaret's avatar
Edric Milaret committed
79 80 81
        formatMsg(index, msg);

        QRect textRect = getBoundingRect(dir, msg, opt);
82 83 84 85 86 87

        QRect bubbleRect(textRect.left() - padding_,
                         textRect.top() - padding_,
                         textRect.width() + 2 * padding_,
                         textRect.height() + 2 * padding_ );

Edric Milaret's avatar
Edric Milaret committed
88
        opt.decorationSize = iconSize_;
89 90
        opt.decorationPosition = (dir == Qt::AlignRight ?
                                      QStyleOptionViewItem::Right : QStyleOptionViewItem::Left);
Edric Milaret's avatar
Edric Milaret committed
91 92
        opt.decorationAlignment = Qt::AlignTop | Qt::AlignHCenter;
        style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, opt.widget);
93 94 95

        QPainterPath path;
        path.addRoundedRect(bubbleRect, padding_, padding_);
96 97

        if (dir == Qt::AlignRight) {
98
            painter->fillPath(path, RingTheme::blue_);
99 100 101 102 103 104
            painter->setPen(Qt::white);
        }
        else {
            painter->fillPath(path, Qt::white);
            painter->setPen(Qt::black);
        }
105

Edric Milaret's avatar
Edric Milaret committed
106
        painter->drawText(textRect, Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, msg);
Edric Milaret's avatar
Edric Milaret committed
107 108 109
    }
}

Edric Milaret's avatar
Edric Milaret committed
110 111 112 113 114 115 116
QRect ImDelegate::getBoundingRect(const Qt::AlignmentFlag& dir, const QString& msg, const QStyleOptionViewItem &option) const
{
    QFont textFont = option.font;
    QFontMetrics textFontMetrics(textFont);
    QRect textRect;

    if (dir == Qt::AlignRight) {
117 118 119
        textRect = textFontMetrics.boundingRect(option.rect.left() + 2 * padding_,
                                                option.rect.top() + 2 * padding_,
                                                option.rect.width() - iconSize_.width() - 4 * padding_,
Edric Milaret's avatar
Edric Milaret committed
120 121 122 123 124
                                                0,
                                                dir|Qt::AlignTop|Qt::TextWordWrap,
                                                msg);
    } else {
        textRect = textFontMetrics.boundingRect(option.rect.left() + iconSize_.width() + 2 * padding_,
125 126
                                                option.rect.top() + 2 * padding_,
                                                option.rect.width() - iconSize_.width() - 4 * padding_ ,
Edric Milaret's avatar
Edric Milaret committed
127 128 129 130 131 132 133
                                                0,
                                                dir|Qt::AlignTop|Qt::TextWordWrap,
                                                msg);
    }
    return textRect;
}

Edric Milaret's avatar
Edric Milaret committed
134
QSize
Edric Milaret's avatar
Edric Milaret committed
135 136
ImDelegate::sizeHint(const QStyleOptionViewItem& option,
                     const QModelIndex& index) const
Edric Milaret's avatar
Edric Milaret committed
137
{
138 139 140
    QStyleOptionViewItem opt = option;
    opt.font = fontMsg_;

Edric Milaret's avatar
Edric Milaret committed
141 142 143 144 145 146 147 148 149
    QString msg = index.data(Qt::DisplayRole).toString();

    auto dir = index.data(
                static_cast<int>(Media::TextRecording::Role::Direction))
            .value<Media::Media::Direction>() == Media::Media::Direction::IN
            ? Qt::AlignLeft : Qt::AlignRight;

    formatMsg(index, msg);

150
    QRect boundingRect = getBoundingRect(dir, msg, opt);
Edric Milaret's avatar
Edric Milaret committed
151

152
    QSize size(option.rect.width(), boundingRect.height() + padding_);
Edric Milaret's avatar
Edric Milaret committed
153 154 155

    /* Keep the minimum height needed. */
    if(size.height() < iconSize_.height())
156
        size.setHeight(iconSize_.height() + padding_);
Edric Milaret's avatar
Edric Milaret committed
157 158

    return size;
Edric Milaret's avatar
Edric Milaret committed
159 160
}