From: Marcus Eggenberger Date: Tue, 4 Nov 2008 14:20:40 +0000 (+0100) Subject: Search result highlights are now properly repositioned on resize X-Git-Tag: 0.3.1~73 X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=commitdiff_plain;h=61e0633ce94a38e669382c29db498f335d2e0fa8;hp=114f8a14b8bc82669ffda0599ce30fc299be9396 Search result highlights are now properly repositioned on resize Most GraphicsItems support now qgraphicsitem_cast --- diff --git a/src/qtui/chatitem.h b/src/qtui/chatitem.h index 996cb432..cf608cd4 100644 --- a/src/qtui/chatitem.h +++ b/src/qtui/chatitem.h @@ -52,6 +52,8 @@ public: void clearLayout(); virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); + enum { Type = ChatScene::ChatItemType }; + virtual inline int type() const { return Type; } QVariant data(int role) const; @@ -126,6 +128,8 @@ ChatItemPrivate *ChatItem::newPrivateData() { return new ChatItemPrivate(createL class TimestampChatItem : public ChatItem { public: TimestampChatItem(const qreal &width, const qreal &height, QGraphicsItem *parent) : ChatItem(width, height, QPointF(0, 0), parent) {} + enum { Type = ChatScene::TimestampChatItemType }; + virtual inline int type() const { return Type; } virtual inline ChatLineModel::ColumnType column() const { return ChatLineModel::TimestampColumn; } }; @@ -140,6 +144,8 @@ public: protected: virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); + enum { Type = ChatScene::SenderChatItemType }; + virtual inline int type() const { return Type; } virtual inline ChatItemPrivate *newPrivateData() { return new ChatItemPrivate(createLayout(QTextOption::ManualWrap, Qt::AlignRight)); } }; @@ -153,6 +159,9 @@ class ContentsChatItem : public ChatItem { public: ContentsChatItem(const qreal &width, const QPointF &pos, QGraphicsItem *parent); + enum { Type = ChatScene::ContentsChatItemType }; + virtual inline int type() const { return Type; } + inline ChatLineModel::ColumnType column() const { return ChatLineModel::ContentsColumn; } inline QFontMetricsF *fontMetrics() const { return _fontMetrics; } diff --git a/src/qtui/chatline.h b/src/qtui/chatline.h index afdd380f..20afe66f 100644 --- a/src/qtui/chatline.h +++ b/src/qtui/chatline.h @@ -25,6 +25,7 @@ #include "chatlinemodel.h" #include "chatitem.h" +#include "chatscene.h" class ChatLine : public QGraphicsItem { public: @@ -51,6 +52,8 @@ public: inline ContentsChatItem &contentsItem() { return _contentsItem; } virtual void paint (QPainter * painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); + enum { Type = ChatScene::ChatLineType }; + virtual inline int type() const { return Type; } void setFirstColumn(const qreal ×tampWidth, const qreal &senderWidth, const QPointF &senderPos); // setSecondColumn and setGeometryByWidth both also relocate the chatline. diff --git a/src/qtui/chatscene.cpp b/src/qtui/chatscene.cpp index 833cfe3e..87dfae57 100644 --- a/src/qtui/chatscene.cpp +++ b/src/qtui/chatscene.cpp @@ -350,6 +350,7 @@ void ChatScene::setWidth(qreal width) { updateSceneRect(width); setHandleXLimits(); + emit layoutChanged(); // clock_t endT = clock(); // qDebug() << "resized" << _lines.count() << "in" << (float)(endT - startT) / CLOCKS_PER_SEC << "sec"; @@ -417,7 +418,9 @@ void ChatScene::secondHandlePositionChanged(qreal xpos) { } //setItemIndexMethod(QGraphicsScene::BspTreeIndex); + updateSceneRect(); setHandleXLimits(); + emit layoutChanged(); // clock_t endT = clock(); // qDebug() << "resized" << _lines.count() << "in" << (float)(endT - startT) / CLOCKS_PER_SEC << "sec"; diff --git a/src/qtui/chatscene.h b/src/qtui/chatscene.h index 78ba3418..a60b8428 100644 --- a/src/qtui/chatscene.h +++ b/src/qtui/chatscene.h @@ -44,6 +44,16 @@ public: CutoffRight }; + enum ItemType { + ChatLineType = QGraphicsItem::UserType + 1, + ChatItemType, + TimestampChatItemType, + SenderChatItemType, + ContentsChatItemType, + SearchHighlightType, + WebPreviewType + }; + ChatScene(QAbstractItemModel *model, const QString &idString, qreal width, QObject *parent); virtual ~ChatScene(); @@ -81,6 +91,7 @@ public: signals: void lastLineChanged(QGraphicsItem *item, qreal offset); + void layoutChanged(); // indicates changes to the scenerect due to resizing of the contentsitems protected: virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent); diff --git a/src/qtui/chatviewsearchcontroller.cpp b/src/qtui/chatviewsearchcontroller.cpp index 1635d909..3828de64 100644 --- a/src/qtui/chatviewsearchcontroller.cpp +++ b/src/qtui/chatviewsearchcontroller.cpp @@ -69,6 +69,7 @@ void ChatViewSearchController::setSearchString(const QString &searchString) { return; connect(_scene, SIGNAL(destroyed()), this, SLOT(sceneDestroyed())); + connect(_scene, SIGNAL(layoutChanged()), this, SLOT(repositionHighlights())); updateHighlights(); } @@ -176,6 +177,50 @@ void ChatViewSearchController::highlightLine(ChatLine *line) { } } +void ChatViewSearchController::repositionHighlights() { + QSet chatLines; + foreach(SearchHighlightItem *item, _highlightItems) { + ChatLine *line = qgraphicsitem_cast(item->parentItem()); + if(line) + chatLines << line; + } + QList chatLineList(chatLines.toList()); + foreach(ChatLine *line, chatLineList) { + repositionHighlights(line); + } +} + +void ChatViewSearchController::repositionHighlights(ChatLine *line) { + QList searchHighlights; + foreach(QGraphicsItem *child, line->childItems()) { + SearchHighlightItem *highlightItem = qgraphicsitem_cast(child); + if(highlightItem) + searchHighlights << highlightItem; + } + + if(searchHighlights.isEmpty()) + return; + + QList wordPos; + if(_searchSenders) { + foreach(QRectF wordRect, line->senderItem().findWords(searchString(), caseSensitive())) { + wordPos << QPointF(wordRect.x() + line->senderItem().x(), wordRect.y()); + } + } + if(_searchMsgs) { + foreach(QRectF wordRect, line->contentsItem().findWords(searchString(), caseSensitive())) { + wordPos << QPointF(wordRect.x() + line->contentsItem().x(), wordRect.y()); + } + } + + qSort(searchHighlights.begin(), searchHighlights.end(), SearchHighlightItem::firstInLine); + + Q_ASSERT(wordPos.count() == searchHighlights.count()); + for(int i = 0; i < searchHighlights.count(); i++) { + searchHighlights.at(i)->setPos(wordPos.at(i)); + } +} + void ChatViewSearchController::sceneDestroyed() { // WARNING: don't call any methods on scene! _scene = 0; @@ -274,3 +319,10 @@ void SearchHighlightItem::paint(QPainter *painter, const QStyleOptionGraphicsIte qreal radius = boundingRect().height() * 0.30; painter->drawRoundedRect(boundingRect(), radius, radius); } + +bool SearchHighlightItem::firstInLine(QGraphicsItem *item1, QGraphicsItem *item2) { + if(item1->pos().y() != item2->pos().y()) + return item1->pos().y() < item2->pos().y(); + else + return item1->pos().x() < item2->pos().x(); +} diff --git a/src/qtui/chatviewsearchcontroller.h b/src/qtui/chatviewsearchcontroller.h index 51b6ff0a..ca7bea8f 100644 --- a/src/qtui/chatviewsearchcontroller.h +++ b/src/qtui/chatviewsearchcontroller.h @@ -27,6 +27,7 @@ #include #include +#include "chatscene.h" #include "message.h" class QGraphicsItem; @@ -58,6 +59,9 @@ private slots: void sceneDestroyed(); void updateHighlights(bool reuse = false); + void repositionHighlights(); + void repositionHighlights(ChatLine *line); + signals: void newCurrentHighlight(QGraphicsItem *highlightItem); @@ -87,10 +91,15 @@ class SearchHighlightItem : public QObject, public QGraphicsItem { public: SearchHighlightItem(QRectF wordRect, QGraphicsItem *parent = 0); - inline virtual QRectF boundingRect() const { return _boundingRect; } + virtual inline QRectF boundingRect() const { return _boundingRect; } virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); + enum { Type = ChatScene::SearchHighlightType }; + virtual inline int type() const { return Type; } + void setHighlighted(bool highlighted); + static bool firstInLine(QGraphicsItem *item1, QGraphicsItem *item2); + private slots: void updateHighlight(qreal value);