Search result highlights are now properly repositioned on resize
authorMarcus Eggenberger <egs@quassel-irc.org>
Tue, 4 Nov 2008 14:20:40 +0000 (15:20 +0100)
committerMarcus Eggenberger <egs@quassel-irc.org>
Tue, 4 Nov 2008 14:20:40 +0000 (15:20 +0100)
Most GraphicsItems support now qgraphicsitem_cast

src/qtui/chatitem.h
src/qtui/chatline.h
src/qtui/chatscene.cpp
src/qtui/chatscene.h
src/qtui/chatviewsearchcontroller.cpp
src/qtui/chatviewsearchcontroller.h

index 996cb43..cf608cd 100644 (file)
@@ -52,6 +52,8 @@ public:
   void clearLayout();
 
   virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
   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;
 
 
   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) {}
 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; }
 };
 
   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);
 
 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)); }
 };
 
   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);
 
 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; }
 
   inline ChatLineModel::ColumnType column() const { return ChatLineModel::ContentsColumn; }
   inline QFontMetricsF *fontMetrics() const { return _fontMetrics; }
 
index afdd380..20afe66 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "chatlinemodel.h"
 #include "chatitem.h"
 
 #include "chatlinemodel.h"
 #include "chatitem.h"
+#include "chatscene.h"
 
 class ChatLine : public QGraphicsItem {
 public:
 
 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);
   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 &timestampWidth, const qreal &senderWidth, const QPointF &senderPos);
   // setSecondColumn and setGeometryByWidth both also relocate the chatline.
 
   void setFirstColumn(const qreal &timestampWidth, const qreal &senderWidth, const QPointF &senderPos);
   // setSecondColumn and setGeometryByWidth both also relocate the chatline.
index 833cfe3..87dfae5 100644 (file)
@@ -350,6 +350,7 @@ void ChatScene::setWidth(qreal width) {
 
   updateSceneRect(width);
   setHandleXLimits();
 
   updateSceneRect(width);
   setHandleXLimits();
+  emit layoutChanged();
 
 //   clock_t endT = clock();
 //   qDebug() << "resized" << _lines.count() << "in" << (float)(endT - startT) / CLOCKS_PER_SEC << "sec";
 
 //   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);
 
   }
   //setItemIndexMethod(QGraphicsScene::BspTreeIndex);
 
+  updateSceneRect();
   setHandleXLimits();
   setHandleXLimits();
+  emit layoutChanged();
 
 //   clock_t endT = clock();
 //   qDebug() << "resized" << _lines.count() << "in" << (float)(endT - startT) / CLOCKS_PER_SEC << "sec";
 
 //   clock_t endT = clock();
 //   qDebug() << "resized" << _lines.count() << "in" << (float)(endT - startT) / CLOCKS_PER_SEC << "sec";
index 78ba341..a60b842 100644 (file)
@@ -44,6 +44,16 @@ public:
     CutoffRight
   };
 
     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();
 
   ChatScene(QAbstractItemModel *model, const QString &idString, qreal width, QObject *parent);
   virtual ~ChatScene();
 
@@ -81,6 +91,7 @@ public:
 
 signals:
   void lastLineChanged(QGraphicsItem *item, qreal offset);
 
 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);
 
 protected:
   virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent);
index 1635d90..3828de6 100644 (file)
@@ -69,6 +69,7 @@ void ChatViewSearchController::setSearchString(const QString &searchString) {
     return;
 
   connect(_scene, SIGNAL(destroyed()), this, SLOT(sceneDestroyed()));
     return;
 
   connect(_scene, SIGNAL(destroyed()), this, SLOT(sceneDestroyed()));
+  connect(_scene, SIGNAL(layoutChanged()), this, SLOT(repositionHighlights()));
   updateHighlights();
  }
 
   updateHighlights();
  }
 
@@ -176,6 +177,50 @@ void ChatViewSearchController::highlightLine(ChatLine *line) {
   }
 }
 
   }
 }
 
+void ChatViewSearchController::repositionHighlights() {
+  QSet<ChatLine *> chatLines;
+  foreach(SearchHighlightItem *item, _highlightItems) {
+    ChatLine *line = qgraphicsitem_cast<ChatLine *>(item->parentItem());
+    if(line)
+      chatLines << line;
+  }
+  QList<ChatLine *> chatLineList(chatLines.toList());
+  foreach(ChatLine *line, chatLineList) {
+    repositionHighlights(line);
+  }
+}
+
+void ChatViewSearchController::repositionHighlights(ChatLine *line) {
+  QList<SearchHighlightItem *> searchHighlights;
+  foreach(QGraphicsItem *child, line->childItems()) {
+    SearchHighlightItem *highlightItem = qgraphicsitem_cast<SearchHighlightItem *>(child);
+    if(highlightItem)
+      searchHighlights << highlightItem;
+  }
+
+  if(searchHighlights.isEmpty())
+    return;
+
+  QList<QPointF> 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;
 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);
 }
   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();
+}
index 51b6ff0..ca7bea8 100644 (file)
@@ -27,6 +27,7 @@
 #include <QString>
 #include <QTimeLine>
 
 #include <QString>
 #include <QTimeLine>
 
+#include "chatscene.h"
 #include "message.h"
 
 class QGraphicsItem;
 #include "message.h"
 
 class QGraphicsItem;
@@ -58,6 +59,9 @@ private slots:
   void sceneDestroyed();
   void updateHighlights(bool reuse = false);
 
   void sceneDestroyed();
   void updateHighlights(bool reuse = false);
 
+  void repositionHighlights();
+  void repositionHighlights(ChatLine *line);
+
 signals:
   void newCurrentHighlight(QGraphicsItem *highlightItem);
 
 signals:
   void newCurrentHighlight(QGraphicsItem *highlightItem);
 
@@ -87,10 +91,15 @@ class SearchHighlightItem : public QObject, public QGraphicsItem {
 
 public:
   SearchHighlightItem(QRectF wordRect, QGraphicsItem *parent = 0);
 
 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);
   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);
 
   void setHighlighted(bool highlighted);
 
+  static bool firstInLine(QGraphicsItem *item1, QGraphicsItem *item2);
+
 private slots:
   void updateHighlight(qreal value);
 
 private slots:
   void updateHighlight(qreal value);