X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fqtui%2Fchatitem.cpp;h=913c81e72784bcf06688ea5b8bf7b7fb979286ab;hp=9b2e1a645839157df968afc6a9bc31468d02b354;hb=3dd76d9373fb46b7be3f7f963b3d3a38ded63ae5;hpb=f3d6f8088d8be6af9319a99fb8d2fee2837b540a diff --git a/src/qtui/chatitem.cpp b/src/qtui/chatitem.cpp index 9b2e1a64..913c81e7 100644 --- a/src/qtui/chatitem.cpp +++ b/src/qtui/chatitem.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-2014 by the Quassel Project * + * Copyright (C) 2005-2019 by the Quassel Project * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -18,99 +18,92 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ +#include "chatitem.h" + +#include +#include + #include #include #include #include #include -#include +#include #include #include #include -#include +#include "action.h" #include "buffermodel.h" #include "bufferview.h" -#include "chatitem.h" #include "chatline.h" #include "chatlinemodel.h" #include "chatview.h" #include "contextmenuactionprovider.h" +#include "icon.h" #include "mainwin.h" #include "qtui.h" #include "qtuistyle.h" -ChatItem::ChatItem(const QRectF &boundingRect, ChatLine *parent) - : _parent(parent), - _boundingRect(boundingRect), - _selectionMode(NoSelection), - _selectionStart(-1), - _cachedLayout(0) -{ -} - +ChatItem::ChatItem(const QRectF& boundingRect, ChatLine* parent) + : _parent(parent) + , _boundingRect(boundingRect) + , _selectionMode(NoSelection) + , _selectionStart(-1) + , _cachedLayout(nullptr) +{} ChatItem::~ChatItem() { delete _cachedLayout; } - -ChatLine *ChatItem::chatLine() const +ChatLine* ChatItem::chatLine() const { return _parent; } - -ChatScene *ChatItem::chatScene() const +ChatScene* ChatItem::chatScene() const { return chatLine()->chatScene(); } - -ChatView *ChatItem::chatView() const +ChatView* ChatItem::chatView() const { return chatScene()->chatView(); } - -const QAbstractItemModel *ChatItem::model() const +const QAbstractItemModel* ChatItem::model() const { return chatLine()->model(); } - int ChatItem::row() const { return chatLine()->row(); } - -QPointF ChatItem::mapToLine(const QPointF &p) const +QPointF ChatItem::mapToLine(const QPointF& p) const { return p + pos(); } - -QPointF ChatItem::mapFromLine(const QPointF &p) const +QPointF ChatItem::mapFromLine(const QPointF& p) const { return p - pos(); } - // relative to the ChatLine -QPointF ChatItem::mapToScene(const QPointF &p) const +QPointF ChatItem::mapToScene(const QPointF& p) const { return chatLine()->mapToScene(p /* + pos() */); } - -QPointF ChatItem::mapFromScene(const QPointF &p) const +QPointF ChatItem::mapFromScene(const QPointF& p) const { return chatLine()->mapFromScene(p) /* - pos() */; } - QVariant ChatItem::data(int role) const { QModelIndex index = model()->index(row(), column()); @@ -121,8 +114,7 @@ QVariant ChatItem::data(int role) const return model()->data(index, role); } - -QTextLayout *ChatItem::layout() const +QTextLayout* ChatItem::layout() const { if (_cachedLayout) return _cachedLayout; @@ -133,15 +125,13 @@ QTextLayout *ChatItem::layout() const return _cachedLayout; } - void ChatItem::clearCache() { delete _cachedLayout; - _cachedLayout = 0; + _cachedLayout = nullptr; } - -void ChatItem::initLayoutHelper(QTextLayout *layout, QTextOption::WrapMode wrapMode, Qt::Alignment alignment) const +void ChatItem::initLayoutHelper(QTextLayout* layout, QTextOption::WrapMode wrapMode, Qt::Alignment alignment) const { Q_ASSERT(layout); @@ -152,20 +142,21 @@ void ChatItem::initLayoutHelper(QTextLayout *layout, QTextOption::WrapMode wrapM option.setAlignment(alignment); layout->setTextOption(option); - QList formatRanges - = QtUi::style()->toTextLayoutList(formatList(), layout->text().length(), data(ChatLineModel::MsgLabelRole).toUInt()); - layout->setAdditionalFormats(formatRanges); + UiStyle::FormatContainer formatRanges = QtUi::style()->toTextLayoutList( + formatList(), + layout->text().length(), + data(ChatLineModel::MsgLabelRole).value() + ); + UiStyle::setTextLayoutFormats(*layout, formatRanges); } - -void ChatItem::initLayout(QTextLayout *layout) const +void ChatItem::initLayout(QTextLayout* layout) const { initLayoutHelper(layout, QTextOption::NoWrap); doLayout(layout); } - -void ChatItem::doLayout(QTextLayout *layout) const +void ChatItem::doLayout(QTextLayout* layout) const { layout->beginLayout(); QTextLine line = layout->createLine(); @@ -176,14 +167,12 @@ void ChatItem::doLayout(QTextLayout *layout) const layout->endLayout(); } - UiStyle::FormatList ChatItem::formatList() const { return data(MessageModel::FormatRole).value(); } - -qint16 ChatItem::posToCursor(const QPointF &posInLine) const +qint16 ChatItem::posToCursor(const QPointF& posInLine) const { QPointF pos = mapFromLine(posInLine); if (pos.y() > height()) @@ -200,8 +189,7 @@ qint16 ChatItem::posToCursor(const QPointF &posInLine) const return 0; } - -void ChatItem::paintBackground(QPainter *painter) +void ChatItem::paintBackground(QPainter* painter) { QVariant bgBrush; if (_selectionMode == FullSelection) @@ -212,12 +200,12 @@ void ChatItem::paintBackground(QPainter *painter) painter->fillRect(boundingRect(), bgBrush.value()); } - // NOTE: This is not the most time-efficient implementation, but it saves space by not caching unnecessary data // This is a deliberate trade-off. (-> selectFmt creation, data() call) -void ChatItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +void ChatItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { - Q_UNUSED(option); Q_UNUSED(widget); + Q_UNUSED(option); + Q_UNUSED(widget); painter->save(); painter->setClipRect(boundingRect()); paintBackground(painter); @@ -230,38 +218,37 @@ void ChatItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, // uncomment partially or all of the following stuff: // // 0) alternativ painter color for debug stuff -// if(row() % 2) -// painter->setPen(Qt::red); -// else -// painter->setPen(Qt::blue); -// 1) draw wordwrap points in the first line -// if(column() == 2) { -// ChatLineModel::WrapList wrapList = data(ChatLineModel::WrapListRole).value(); -// foreach(ChatLineModel::Word word, wrapList) { -// if(word.endX > width()) -// break; -// painter->drawLine(word.endX, 0, word.endX, height()); -// } -// } -// 2) draw MsgId over the time column -// if(column() == 0) { -// QString msgIdString = QString::number(data(MessageModel::MsgIdRole).value().toInt()); -// QPointF bottomPoint = boundingRect().bottomLeft(); -// bottomPoint.ry() -= 2; -// painter->drawText(bottomPoint, msgIdString); -// } -// 3) draw bounding rect -// painter->drawRect(_boundingRect.adjusted(0, 0, -1, -1)); + // if(row() % 2) + // painter->setPen(Qt::red); + // else + // painter->setPen(Qt::blue); + // 1) draw wordwrap points in the first line + // if(column() == 2) { + // ChatLineModel::WrapList wrapList = data(ChatLineModel::WrapListRole).value(); + // foreach(ChatLineModel::Word word, wrapList) { + // if(word.endX > width()) + // break; + // painter->drawLine(word.endX, 0, word.endX, height()); + // } + // } + // 2) draw MsgId over the time column + // if(column() == 0) { + // QString msgIdString = QString::number(data(MessageModel::MsgIdRole).value().toLongLong()); + // QPointF bottomPoint = boundingRect().bottomLeft(); + // bottomPoint.ry() -= 2; + // painter->drawText(bottomPoint, msgIdString); + // } + // 3) draw bounding rect + // painter->drawRect(_boundingRect.adjusted(0, 0, -1, -1)); painter->restore(); } - -void ChatItem::overlayFormat(UiStyle::FormatList &fmtList, int start, int end, quint32 overlayFmt) const +void ChatItem::overlayFormat(UiStyle::FormatList& fmtList, quint16 start, quint16 end, UiStyle::FormatType overlayFmt) const { - for (int i = 0; i < fmtList.count(); i++) { + for (size_t i = 0; i < fmtList.size(); i++) { int fmtStart = fmtList.at(i).first; - int fmtEnd = (i < fmtList.count()-1 ? fmtList.at(i+1).first : data(MessageModel::DisplayRole).toString().length()); + int fmtEnd = (i < fmtList.size() - 1 ? fmtList.at(i + 1).first : data(MessageModel::DisplayRole).toString().length()); if (fmtEnd <= start) continue; @@ -270,54 +257,109 @@ void ChatItem::overlayFormat(UiStyle::FormatList &fmtList, int start, int end, q // split the format if necessary if (fmtStart < start) { - fmtList.insert(i, fmtList.at(i)); + fmtList.insert(fmtList.begin() + i, fmtList.at(i)); fmtList[++i].first = start; } if (end < fmtEnd) { - fmtList.insert(i, fmtList.at(i)); - fmtList[i+1].first = end; + fmtList.insert(fmtList.begin() + i, fmtList.at(i)); + fmtList[i + 1].first = end; } - fmtList[i].second |= overlayFmt; + fmtList[i].second.type |= overlayFmt; } } - QVector ChatItem::additionalFormats() const { - return selectionFormats(); -} + // Calculate formats to overlay (only) if there's a selection, and/or a hovered clickable + if (!hasSelection() && !hasActiveClickable()) { + return {}; + } + using Label = UiStyle::MessageLabel; + using Format = UiStyle::Format; -QVector ChatItem::selectionFormats() const -{ - if (!hasSelection()) - return QVector(); + auto itemLabel = data(ChatLineModel::MsgLabelRole).value