X-Git-Url: https://git.quassel-irc.org/?a=blobdiff_plain;f=src%2Fqtui%2Fchatitem.cpp;h=e2fa55b6fce93c8aa127e77b21416e3e309ebe21;hb=e036ee9df2219667ce1cc22d42a7c50fbdf5b3ba;hp=b52fe3f0bc09848d53d9759588292e1bd36c859d;hpb=9fd12737c55a0119801c90c399c926b35ffee708;p=quassel.git diff --git a/src/qtui/chatitem.cpp b/src/qtui/chatitem.cpp index b52fe3f0..e2fa55b6 100644 --- a/src/qtui/chatitem.cpp +++ b/src/qtui/chatitem.cpp @@ -84,10 +84,14 @@ void ChatItem::initLayoutHelper(QTextLayout *layout, QTextOption::WrapMode wrapM layout->setTextOption(option); QList formatRanges - = QtUi::style()->toTextLayoutList(data(MessageModel::FormatRole).value(), layout->text().length(), data(ChatLineModel::MsgLabelRole).toUInt()); + = QtUi::style()->toTextLayoutList(formatList(), layout->text().length(), data(ChatLineModel::MsgLabelRole).toUInt()); layout->setAdditionalFormats(formatRanges); } +UiStyle::FormatList ChatItem::formatList() const { + return data(MessageModel::FormatRole).value(); +} + void ChatItem::doLayout(QTextLayout *layout) const { layout->beginLayout(); QTextLine line = layout->createLine(); @@ -118,7 +122,7 @@ void ChatItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QTextLayout layout; initLayout(&layout); - layout.draw(painter, QPointF(0,0), selectionFormats(), boundingRect()); + layout.draw(painter, QPointF(0,0), additionalFormats(), boundingRect()); // layout()->draw(painter, QPointF(0,0), formats, boundingRect()); @@ -150,6 +154,34 @@ void ChatItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, // painter->drawRect(_boundingRect.adjusted(0, 0, -1, -1)); } +void ChatItem::overlayFormat(UiStyle::FormatList &fmtList, int start, int end, quint32 overlayFmt) const { + for(int i = 0; i < fmtList.count(); i++) { + int fmtStart = fmtList.at(i).first; + int fmtEnd = (i < fmtList.count()-1 ? fmtList.at(i+1).first : data(MessageModel::DisplayRole).toString().length()); + + if(fmtEnd <= start) + continue; + if(fmtStart >= end) + break; + + // split the format if necessary + if(fmtStart < start) { + fmtList.insert(i, fmtList.at(i)); + fmtList[++i].first = start; + } + if(end < fmtEnd) { + fmtList.insert(i, fmtList.at(i)); + fmtList[i+1].first = end; + } + + fmtList[i].second |= overlayFmt; + } +} + +QVector ChatItem::additionalFormats() const { + return selectionFormats(); +} + QVector ChatItem::selectionFormats() const { if(!hasSelection()) return QVector(); @@ -163,14 +195,14 @@ QVector ChatItem::selectionFormats() const { end = qMax(_selectionStart, _selectionEnd); } - UiStyle::FormatList fmtList = data(MessageModel::FormatRole).value(); + UiStyle::FormatList fmtList = formatList(); - while(fmtList.count() >=2 && fmtList.at(1).first <= start) + while(fmtList.count() > 1 && fmtList.at(1).first <= start) fmtList.removeFirst(); fmtList.first().first = start; - while(fmtList.count() >= 2 && fmtList.last().first >= end) + while(fmtList.count() > 1 && fmtList.last().first >= end) fmtList.removeLast(); return QtUi::style()->toTextLayoutList(fmtList, end, UiStyle::Selected|data(ChatLineModel::MsgLabelRole).toUInt()).toVector(); @@ -331,7 +363,7 @@ void SenderChatItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *op QPixmap pixmap(layout.boundingRect().toRect().size()); pixmap.fill(Qt::transparent); QPainter pixPainter(&pixmap); - layout.draw(&pixPainter, QPointF(qMax(offset, (qreal)0), 0), selectionFormats()); + layout.draw(&pixPainter, QPointF(qMax(offset, (qreal)0), 0), additionalFormats()); pixPainter.end(); // Create alpha channel mask @@ -353,7 +385,7 @@ void SenderChatItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *op pixmap.setAlphaChannel(mask); painter->drawPixmap(0, 0, pixmap); } else { - layout.draw(painter, QPointF(0,0), selectionFormats(), boundingRect()); + layout.draw(painter, QPointF(0,0), additionalFormats(), boundingRect()); } } @@ -371,7 +403,7 @@ ContentsChatItem::ContentsChatItem(const qreal &width, const QPointF &pos, QGrap } QFontMetricsF *ContentsChatItem::fontMetrics() const { - return QtUi::style()->fontMetrics(data(ChatLineModel::FormatRole).value().at(0).second); + return QtUi::style()->fontMetrics(data(ChatLineModel::FormatRole).value().at(0).second, 0); } ContentsChatItem::~ContentsChatItem() { @@ -507,9 +539,20 @@ ContentsChatItem::Clickable ContentsChatItem::clickableAt(const QPointF &pos) co return Clickable(); } +UiStyle::FormatList ContentsChatItem::formatList() const { + UiStyle::FormatList fmtList = ChatItem::formatList(); + for(int i = 0; i < privateData()->clickables.count(); i++) { + Clickable click = privateData()->clickables.at(i); + if(click.type == Clickable::Url) { + overlayFormat(fmtList, click.start, click.start + click.length, UiStyle::Url); + } + } + return fmtList; +} + QVector ContentsChatItem::additionalFormats() const { + QVector fmt = ChatItem::additionalFormats(); // mark a clickable if hovered upon - QVector fmt; if(privateData()->currentClickable.isValid()) { Clickable click = privateData()->currentClickable; QTextLayout::FormatRange f;