X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fqtui%2Fchatitem.cpp;h=2ca66aa17b9d07c30256fc7e829255e6e8bb907c;hp=e3ab1abb408f148b90979c36b715b6c2e458f07d;hb=edc446b0c31b048efddaf1943cb85eb0db6a0faa;hpb=d36a37a4a2e2fa889cf12d596258f9ba4dfcc5ed diff --git a/src/qtui/chatitem.cpp b/src/qtui/chatitem.cpp index e3ab1abb..2ca66aa1 100644 --- a/src/qtui/chatitem.cpp +++ b/src/qtui/chatitem.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-09 by the Quassel Project * + * Copyright (C) 2005-2010 by the Quassel Project * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -31,6 +31,7 @@ #include "buffermodel.h" #include "bufferview.h" #include "chatitem.h" +#include "chatline.h" #include "chatlinemodel.h" #include "contextmenuactionprovider.h" #include "iconloader.h" @@ -38,15 +39,13 @@ #include "qtui.h" #include "qtuistyle.h" -ChatItem::ChatItem(const qreal &width, const qreal &height, const QPointF &pos, QGraphicsItem *parent) - : QGraphicsItem(parent), - _boundingRect(0, 0, width, height), - _selectionMode(NoSelection), - _selectionStart(-1) +ChatItem::ChatItem(const QRectF &boundingRect, ChatLine *parent) +: _parent(parent), + _boundingRect(boundingRect), + _selectionMode(NoSelection), + _selectionStart(-1) { - setAcceptHoverEvents(true); - setZValue(20); - setPos(pos); + } QVariant ChatItem::data(int role) const { @@ -58,7 +57,8 @@ QVariant ChatItem::data(int role) const { return model()->data(index, role); } -qint16 ChatItem::posToCursor(const QPointF &pos) const { +qint16 ChatItem::posToCursor(const QPointF &posInLine) const { + QPointF pos = mapFromLine(posInLine); if(pos.y() > height()) return data(MessageModel::DisplayRole).toString().length(); if(pos.y() < 0) return 0; @@ -103,8 +103,6 @@ void ChatItem::doLayout(QTextLayout *layout) const { } void ChatItem::paintBackground(QPainter *painter) { - painter->setClipRect(boundingRect()); // no idea why QGraphicsItem clipping won't work - QVariant bgBrush; if(_selectionMode == FullSelection) bgBrush = data(ChatLineModel::SelectedBackgroundRole); @@ -122,7 +120,7 @@ void ChatItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QTextLayout layout; initLayout(&layout); - layout.draw(painter, QPointF(0,0), additionalFormats(), boundingRect()); + layout.draw(painter, pos(), additionalFormats(), boundingRect()); // layout()->draw(painter, QPointF(0,0), formats, boundingRect()); @@ -229,27 +227,27 @@ void ChatItem::setSelection(SelectionMode mode, qint16 start, qint16 end) { _selectionMode = mode; _selectionStart = start; _selectionEnd = end; - update(); + chatLine()->update(); } void ChatItem::setFullSelection() { if(_selectionMode != FullSelection) { _selectionMode = FullSelection; - update(); + chatLine()->update(); } } void ChatItem::clearSelection() { if(_selectionMode != NoSelection) { _selectionMode = NoSelection; - update(); + chatLine()->update(); } } void ChatItem::continueSelecting(const QPointF &pos) { _selectionMode = PartialSelection; _selectionEnd = posToCursor(pos); - update(); + chatLine()->update(); } bool ChatItem::isPosOverSelection(const QPointF &pos) const { @@ -296,18 +294,18 @@ void ChatItem::handleClick(const QPointF &pos, ChatScene::ClickMode clickMode) { chatScene()->setSelectingItem(this); _selectionStart = _selectionEnd = posToCursor(pos); _selectionMode = NoSelection; // will be set to PartialSelection by mouseMoveEvent - update(); + chatLine()->update(); } } void ChatItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { if(event->buttons() == Qt::LeftButton) { - if(contains(event->pos())) { + if(boundingRect().contains(event->pos())) { qint16 end = posToCursor(event->pos()); if(end != _selectionEnd) { _selectionEnd = end; _selectionMode = (_selectionStart != _selectionEnd ? PartialSelection : NoSelection); - update(); + chatLine()->update(); } } else { setFullSelection(); @@ -381,12 +379,24 @@ void SenderChatItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *op gradient.setColorAt(0, Qt::white); gradient.setColorAt(1, Qt::black); } - maskPainter.fillRect(boundingRect(), gradient); + maskPainter.fillRect(0, 0, pixmap.width(), pixmap.height(), gradient); pixmap.setAlphaChannel(mask); - painter->drawPixmap(0, 0, pixmap); + painter->drawPixmap(pos(), pixmap); } else { - layout.draw(painter, QPointF(0,0), additionalFormats(), boundingRect()); + layout.draw(painter, pos(), additionalFormats(), boundingRect()); + } +} + +void SenderChatItem::handleClick(const QPointF &pos, ChatScene::ClickMode clickMode) { + if(clickMode == ChatScene::DoubleClick) { + BufferInfo curBufInfo = Client::networkModel()->bufferInfo(data(MessageModel::BufferIdRole).value()); + QString nick = data(MessageModel::EditRole).toString(); + // check if the nick is a valid ircUser + if(!nick.isEmpty() && Client::network(curBufInfo.networkId())->ircUser(nick)) + Client::bufferModel()->switchToOrStartQuery(curBufInfo.networkId(), nick); } + else + ChatItem::handleClick(pos, clickMode); } // ************************************************************ @@ -395,10 +405,11 @@ void SenderChatItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *op ContentsChatItem::ActionProxy ContentsChatItem::_actionProxy; -ContentsChatItem::ContentsChatItem(const qreal &width, const QPointF &pos, QGraphicsItem *parent) - : ChatItem(0, 0, pos, parent), +ContentsChatItem::ContentsChatItem(const QPointF &pos, const qreal &width, ChatLine *parent) + : ChatItem(QRectF(pos, QSizeF(width, 0)), parent), _data(0) { + setPos(pos); setGeometryByWidth(width); } @@ -426,14 +437,14 @@ qreal ContentsChatItem::setGeometryByWidth(qreal w) { WrapColumnFinder finder(this); while(finder.nextWrapColumn(w) > 0) lines++; - qreal h = lines * fontMetrics()->lineSpacing(); + qreal spacing = qMax(fontMetrics()->lineSpacing(), fontMetrics()->height()); // cope with negative leading() + qreal h = lines * spacing; delete _data; _data = 0; - if(w != width() || h != height()) { - prepareGeometryChange(); + if(w != width() || h != height()) setGeometry(w, h); - } + return h; } @@ -443,6 +454,7 @@ void ContentsChatItem::doLayout(QTextLayout *layout) const { if(!wrapList.count()) return; // empty chatitem qreal h = 0; + qreal spacing = qMax(fontMetrics()->lineSpacing(), fontMetrics()->height()); // cope with negative leading() WrapColumnFinder finder(this); layout->beginLayout(); forever { @@ -460,7 +472,7 @@ void ContentsChatItem::doLayout(QTextLayout *layout) const { // Sometimes, setNumColumns will create a line that's too long (cf. Qt bug 238249) // We verify this and try setting the width again, making it shorter each time until the lengths match. // Dead fugly, but seems to work… - for(int i = line.textLength()-1; line.textLength() > num; i--) { + for(int i = line.textLength()-1; i >= 0 && line.textLength() > num; i--) { line.setNumColumns(i); } if(num != line.textLength()) { @@ -469,7 +481,7 @@ void ContentsChatItem::doLayout(QTextLayout *layout) const { } line.setPosition(QPointF(0, h)); - h += fontMetrics()->lineSpacing(); + h += spacing; } layout->endLayout(); } @@ -506,11 +518,11 @@ QVector ContentsChatItem::additionalFormats() const { void ContentsChatItem::endHoverMode() { if(privateData()) { if(privateData()->currentClickable.isValid()) { - setCursor(Qt::ArrowCursor); + chatLine()->setCursor(Qt::ArrowCursor); privateData()->currentClickable = Clickable(); } clearWebPreview(); - update(); + chatLine()->update(); } } @@ -540,7 +552,7 @@ void ContentsChatItem::handleClick(const QPointF &pos, ChatScene::ClickMode clic setSelectionStart(start); setSelectionEnd(end); } - update(); + chatLine()->update(); } else if(clickMode == ChatScene::TripleClick) { setSelection(PartialSelection, 0, data(ChatLineModel::DisplayRole).toString().length()); } @@ -573,9 +585,9 @@ void ContentsChatItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { onClickable = true; } if(onClickable) { - setCursor(Qt::PointingHandCursor); + chatLine()->setCursor(Qt::PointingHandCursor); privateData()->currentClickable = click; - update(); + chatLine()->update(); return; } } @@ -633,7 +645,7 @@ void ContentsChatItem::showWebPreview(const Clickable &click) { qreal height = line.height(); qreal y = height * line.lineNumber(); - QPointF topLeft = scenePos() + QPointF(x, y); + QPointF topLeft = mapToScene(pos()) + QPointF(x, y); QRectF urlRect = QRectF(topLeft.x(), topLeft.y(), width, height); QString urlstr = data(ChatLineModel::DisplayRole).toString().mid(click.start(), click.length());