Refactor the markerline into a proper QGraphicsWidget
authorManuel Nickschas <sputnick@quassel-irc.org>
Wed, 16 Jun 2010 15:21:21 +0000 (17:21 +0200)
committerManuel Nickschas <sputnick@quassel-irc.org>
Wed, 16 Jun 2010 16:13:51 +0000 (18:13 +0200)
Unitl now, ChatLines would check if they're the one supposed to display the markerline
for every paintEvent, and the one appropriate would draw it then. Besides being inefficient,
this also caused trouble with the more flexible markerline stuff introduced recently.

Now the markerline is a proper QGraphicsWidget. It can be fully styled via a brush property:

Palette {
  marker-line: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop:0 red, stop: 0.1 transparent);
}

This lets it look identical to the "old" markerline and is hence the default now. Note that the
height of the markerline object is equal to a single line of text (so this is the area you get
to play in), unless the brush is set to a solid color, in which case it's a simple line 1px wide.
This makes it look acceptable when using an older stylesheet.

This commit also fixes a crash introduced with the markerline rewrite a few weeks ago.

src/qtui/CMakeLists.txt
src/qtui/bufferwidget.cpp
src/qtui/bufferwidget.h
src/qtui/chatline.cpp
src/qtui/chatscene.cpp
src/qtui/chatscene.h
src/qtui/chatview.cpp
src/qtui/chatview.h
src/qtui/markerlineitem.cpp [new file with mode: 0644]
src/qtui/markerlineitem.h [new file with mode: 0644]

index fb74978..46eb704 100644 (file)
@@ -40,6 +40,7 @@ set(SOURCES
     legacysystemtray.cpp
     mainpage.cpp
     mainwin.cpp
     legacysystemtray.cpp
     mainpage.cpp
     mainwin.cpp
+    markerlineitem.cpp
     msgprocessorstatuswidget.cpp
     nicklistwidget.cpp
     qtui.cpp
     msgprocessorstatuswidget.cpp
     nicklistwidget.cpp
     qtui.cpp
@@ -86,6 +87,7 @@ set(MOC_HDRS
     legacysystemtray.h
     mainpage.h
     mainwin.h
     legacysystemtray.h
     mainpage.h
     mainwin.h
+    markerlineitem.h
     msgprocessorstatuswidget.h
     nicklistwidget.h
     qtui.h
     msgprocessorstatuswidget.h
     nicklistwidget.h
     qtui.h
index ab06899..047759e 100644 (file)
@@ -238,14 +238,15 @@ void BufferWidget::setMarkerLine(ChatView *view, bool allowGoingBack) {
 
   ChatLine *lastLine = view->lastVisibleChatLine();
   if(lastLine) {
 
   ChatLine *lastLine = view->lastVisibleChatLine();
   if(lastLine) {
+    QModelIndex idx = lastLine->index();
+    MsgId msgId = idx.data(MessageModel::MsgIdRole).value<MsgId>();
+
     if(!allowGoingBack) {
     if(!allowGoingBack) {
-      QModelIndex idx = lastLine->index();
       BufferId bufId = view->scene()->singleBufferId();
       BufferId bufId = view->scene()->singleBufferId();
-      MsgId msgId = idx.data(MessageModel::MsgIdRole).value<MsgId>();
       MsgId oldMsgId = Client::markerLine(bufId);
       if(oldMsgId.isValid() && msgId <= oldMsgId)
         return;
     }
       MsgId oldMsgId = Client::markerLine(bufId);
       if(oldMsgId.isValid() && msgId <= oldMsgId)
         return;
     }
-    view->setMarkedLine(lastLine);
+    view->setMarkerLine(msgId);
   }
 }
   }
 }
index dc8b823..b818435 100644 (file)
@@ -42,6 +42,9 @@ public:
   inline ChatViewSearchBar *searchBar() const { return ui.searchBar; }
   void addActionsToMenu(QMenu *, const QPointF &pos);
 
   inline ChatViewSearchBar *searchBar() const { return ui.searchBar; }
   void addActionsToMenu(QMenu *, const QPointF &pos);
 
+public slots:
+  virtual void setMarkerLine(ChatView *view = 0, bool allowGoingBack = true);
+
 protected:
   virtual AbstractChatView *createChatView(BufferId);
   virtual void removeChatView(BufferId);
 protected:
   virtual AbstractChatView *createChatView(BufferId);
   virtual void removeChatView(BufferId);
@@ -50,8 +53,6 @@ protected:
 protected slots:
   virtual void currentChanged(const QModelIndex &current, const QModelIndex &previous);
   virtual void showChatView(BufferId);
 protected slots:
   virtual void currentChanged(const QModelIndex &current, const QModelIndex &previous);
   virtual void showChatView(BufferId);
-public slots:
-  virtual void setMarkerLine(ChatView *view = 0, bool allowGoingBack = true);
 
 private slots:
   void scrollToHighlight(QGraphicsItem *highlightItem);
 
 private slots:
   void scrollToHighlight(QGraphicsItem *highlightItem);
index 99e0982..4f03794 100644 (file)
@@ -209,25 +209,6 @@ void ChatLine::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
   timestampItem()->paint(painter, option, widget);
   senderItem()->paint(painter, option, widget);
   contentsItem()->paint(painter, option, widget);
   timestampItem()->paint(painter, option, widget);
   senderItem()->paint(painter, option, widget);
   contentsItem()->paint(painter, option, widget);
-
-  // new line marker
-  if(model_ && row() > 0  && chatScene()->isSingleBufferScene()) {
-    QModelIndex prevRowIdx = model_->index(row() - 1, 0);
-    MsgId prevMsgId = prevRowIdx.data(MessageModel::MsgIdRole).value<MsgId>();
-    MsgId myMsgId = myIdx.data(MessageModel::MsgIdRole).value<MsgId>();
-    Message::Flags flags = (Message::Flags)myIdx.data(MessageModel::FlagsRole).toInt();
-
-    if(chatView()->isMarkerLineVisible()) {
-      BufferId bufferId = BufferId(chatScene()->idString().toInt());
-      MsgId lastSeenMsgId = Client::networkModel()->markerLineMsgId(bufferId);
-      if(lastSeenMsgId < myMsgId && lastSeenMsgId >= prevMsgId) {
-        QLinearGradient gradient(0, 0, 0, contentsItem()->fontMetrics()->lineSpacing());
-        gradient.setColorAt(0, QtUi::style()->brush(UiStyle::MarkerLine).color()); // FIXME: Use full (gradient?) brush instead of just the color
-        gradient.setColorAt(0.1, Qt::transparent);
-        painter->fillRect(boundingRect(), gradient);
-      }
-    }
-  }
 }
 
 // We need to dispatch all mouse-related events to the appropriate (mouse grabbing) ChatItem
 }
 
 // We need to dispatch all mouse-related events to the appropriate (mouse grabbing) ChatItem
index cb5b3f7..46cfc3e 100644 (file)
@@ -47,6 +47,7 @@
 #include "contextmenuactionprovider.h"
 #include "iconloader.h"
 #include "mainwin.h"
 #include "contextmenuactionprovider.h"
 #include "iconloader.h"
 #include "mainwin.h"
+#include "markerlineitem.h"
 #include "messagefilter.h"
 #include "qtui.h"
 #include "qtuistyle.h"
 #include "messagefilter.h"
 #include "qtui.h"
 #include "qtuistyle.h"
@@ -64,6 +65,9 @@ ChatScene::ChatScene(QAbstractItemModel *model, const QString &idString, qreal w
     _sceneRect(0, 0, width, 0),
     _firstLineRow(-1),
     _viewportHeight(0),
     _sceneRect(0, 0, width, 0),
     _firstLineRow(-1),
     _viewportHeight(0),
+    _markerLine(new MarkerLineItem(width)),
+    _markerLineValid(false),
+    _markerLineVisible(false),
     _cutoffMode(CutoffRight),
     _selectingItem(0),
     _selectionStart(-1),
     _cutoffMode(CutoffRight),
     _selectingItem(0),
     _selectionStart(-1),
@@ -77,6 +81,9 @@ ChatScene::ChatScene(QAbstractItemModel *model, const QString &idString, qreal w
     _singleBufferId = filter->singleBufferId();
   }
 
     _singleBufferId = filter->singleBufferId();
   }
 
+  addItem(_markerLine);
+  connect(this, SIGNAL(sceneRectChanged(const QRectF &)), _markerLine, SLOT(sceneRectChanged(const QRectF &)));
+
   ChatViewSettings defaultSettings;
   int defaultFirstColHandlePos = defaultSettings.value("FirstColumnHandlePos", 80).toInt();
   int defaultSecondColHandlePos = defaultSettings.value("SecondColumnHandlePos", 200).toInt();
   ChatViewSettings defaultSettings;
   int defaultFirstColHandlePos = defaultSettings.value("FirstColumnHandlePos", 80).toInt();
   int defaultSecondColHandlePos = defaultSettings.value("SecondColumnHandlePos", 200).toInt();
@@ -107,6 +114,8 @@ ChatScene::ChatScene(QAbstractItemModel *model, const QString &idString, qreal w
           this, SLOT(rowsInserted(const QModelIndex &, int, int)));
   connect(model, SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)),
           this, SLOT(rowsAboutToBeRemoved(const QModelIndex &, int, int)));
           this, SLOT(rowsInserted(const QModelIndex &, int, int)));
   connect(model, SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)),
           this, SLOT(rowsAboutToBeRemoved(const QModelIndex &, int, int)));
+  connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
+          this, SLOT(rowsRemoved()));
   connect(model, SIGNAL(dataChanged(QModelIndex, QModelIndex)), SLOT(dataChanged(QModelIndex, QModelIndex)));
 
 #ifdef HAVE_WEBKIT
   connect(model, SIGNAL(dataChanged(QModelIndex, QModelIndex)), SLOT(dataChanged(QModelIndex, QModelIndex)));
 
 #ifdef HAVE_WEBKIT
@@ -138,7 +147,7 @@ ColumnHandleItem *ChatScene::secondColumnHandle() const {
   return _secondColHandle;
 }
 
   return _secondColHandle;
 }
 
-ChatLine *ChatScene::chatLine(MsgId msgId) const {
+ChatLine *ChatScene::chatLine(MsgId msgId, bool matchExact) const {
   if(!_lines.count())
     return 0;
 
   if(!_lines.count())
     return 0;
 
@@ -159,10 +168,22 @@ ChatLine *ChatScene::chatLine(MsgId msgId) const {
       n = half;
     }
   }
       n = half;
     }
   }
-  if((*start)->msgId() == msgId)
+
+  if(start != end && (*start)->msgId() == msgId)
     return *start;
 
     return *start;
 
-  return 0;
+  if(matchExact)
+    return 0;
+
+  // if we didn't find the exact msgId, take the next-lower one (this makes sense for lastSeen)
+  if(start == end) // higher than last element
+    return _lines.last();
+
+  if(start == _lines.begin()) // not (yet?) in our scene
+    return 0;
+
+  // return the next-lower line
+  return *(--start);
 }
 
 ChatItem *ChatScene::chatItemAt(const QPointF &scenePos) const {
 }
 
 ChatItem *ChatScene::chatItemAt(const QPointF &scenePos) const {
@@ -180,6 +201,35 @@ bool ChatScene::containsBuffer(const BufferId &id) const {
     return false;
 }
 
     return false;
 }
 
+void ChatScene::setMarkerLineVisible(bool visible) {
+  _markerLineVisible = visible;
+  if(visible && _markerLineValid)
+    _markerLine->setVisible(true);
+  else
+    _markerLine->setVisible(false);
+}
+
+void ChatScene::setMarkerLine(MsgId msgId) {
+  if(msgId.isValid()) {
+    ChatLine *line = chatLine(msgId, false);
+    if(line) {
+      // if this was the last line, we won't see it because it's outside the sceneRect
+      // .. which is exactly what we want :)
+      _markerLine->setPos(line->pos() + QPointF(0, line->height()));
+
+      // DayChange messages might have been hidden outside the scene rect, don't make the markerline visible then!
+      if(_markerLine->pos().y() >= sceneRect().y()) {
+        _markerLineValid = true;
+        if(_markerLineVisible)
+          _markerLine->setVisible(true);
+        return;
+      }
+    }
+  }
+  _markerLineValid = false;
+  _markerLine->setVisible(false);
+}
+
 void ChatScene::rowsInserted(const QModelIndex &index, int start, int end) {
   Q_UNUSED(index);
 
 void ChatScene::rowsInserted(const QModelIndex &index, int start, int end) {
   Q_UNUSED(index);
 
@@ -310,6 +360,14 @@ void ChatScene::rowsInserted(const QModelIndex &index, int start, int end) {
   if(atBottom) {
     emit lastLineChanged(_lines.last(), h);
   }
   if(atBottom) {
     emit lastLineChanged(_lines.last(), h);
   }
+
+  // now move the marker line if necessary. we don't need to do anything if we appended lines though...
+  if(isSingleBufferScene()) {
+    if(!_markerLineValid || !atBottom) {
+      MsgId msgId = Client::markerLine(singleBufferId());
+      setMarkerLine(msgId);
+    }
+  }
 }
 
 void ChatScene::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) {
 }
 
 void ChatScene::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) {
@@ -403,6 +461,14 @@ void ChatScene::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int e
   updateSceneRect();
 }
 
   updateSceneRect();
 }
 
+void ChatScene::rowsRemoved() {
+  // move the marker line if necessary
+  if(isSingleBufferScene()) {
+    MsgId msgId = Client::markerLine(singleBufferId());
+    setMarkerLine(msgId);
+  }
+}
+
 void ChatScene::dataChanged(const QModelIndex &tl, const QModelIndex &br) {
   layout(tl.row(), br.row(), _sceneRect.width());
 }
 void ChatScene::dataChanged(const QModelIndex &tl, const QModelIndex &br) {
   layout(tl.row(), br.row(), _sceneRect.width());
 }
index 3daf861..c4a8b01 100644 (file)
@@ -36,6 +36,7 @@ class ChatItem;
 class ChatLine;
 class ChatView;
 class ColumnHandleItem;
 class ChatLine;
 class ChatView;
 class ColumnHandleItem;
+class MarkerLineItem;
 class WebPreviewItem;
 
 class QGraphicsSceneMouseEvent;
 class WebPreviewItem;
 
 class QGraphicsSceneMouseEvent;
@@ -57,7 +58,8 @@ public:
     ContentsChatItemType,
     SearchHighlightType,
     WebPreviewType,
     ContentsChatItemType,
     SearchHighlightType,
     WebPreviewType,
-    ColumnHandleType
+    ColumnHandleType,
+    MarkerLineType
   };
 
   enum ClickMode {
   };
 
   enum ClickMode {
@@ -88,11 +90,13 @@ public:
   //! Find the ChatLine belonging to a MsgId
   /** Searches for the ChatLine belonging to a MsgId.
    *  Note that this method performs a binary search, hence it has as complexity of O(log n).
   //! Find the ChatLine belonging to a MsgId
   /** Searches for the ChatLine belonging to a MsgId.
    *  Note that this method performs a binary search, hence it has as complexity of O(log n).
-   *  If there is more than one ChatLine for the given ID, the first one will be returned.
-   *  \param msgId The message ID to look for
+   *  If matchExact is false, and we don't have an exact match for the given msgId, we return the visible line right
+   *  above the requested one.
+   *  \param msgId      The message ID to look for
+   *  \param matchExact Whether we find only exact matches
    *  \return The ChatLine corresponding to the given MsgId
    */
    *  \return The ChatLine corresponding to the given MsgId
    */
-  ChatLine *chatLine(MsgId msgId) const;
+  ChatLine *chatLine(MsgId msgId, bool matchExact = true) const;
 
   inline ChatLine *lastLine() const { return _lines.count() ? _lines.last() : 0; }
 
 
   inline ChatLine *lastLine() const { return _lines.count() ? _lines.last() : 0; }
 
@@ -122,6 +126,9 @@ public:
   void setWidth(qreal width);
   void layout(int start, int end, qreal width);
 
   void setWidth(qreal width);
   void layout(int start, int end, qreal width);
 
+  void setMarkerLineVisible(bool visible = true);
+  void setMarkerLine(MsgId msgId);
+
   // these are used by the chatitems to notify the scene and manage selections
   void setSelectingItem(ChatItem *item);
   ChatItem *selectingItem() const { return _selectingItem; }
   // these are used by the chatitems to notify the scene and manage selections
   void setSelectingItem(ChatItem *item);
   ChatItem *selectingItem() const { return _selectingItem; }
@@ -164,6 +171,8 @@ private slots:
 #endif
   void showWebPreviewChanged();
 
 #endif
   void showWebPreviewChanged();
 
+  void rowsRemoved();
+
   void clickTimeout();
 
 private:
   void clickTimeout();
 
 private:
@@ -185,6 +194,9 @@ private:
   void updateSceneRect(const QRectF &rect);
   qreal _viewportHeight;
 
   void updateSceneRect(const QRectF &rect);
   qreal _viewportHeight;
 
+  MarkerLineItem *_markerLine;
+  bool _markerLineValid, _markerLineVisible;
+
   ColumnHandleItem *_firstColHandle, *_secondColHandle;
   qreal _firstColHandlePos, _secondColHandlePos;
   CutoffMode _cutoffMode;
   ColumnHandleItem *_firstColHandle, *_secondColHandle;
   qreal _firstColHandlePos, _secondColHandlePos;
   CutoffMode _cutoffMode;
index e61dc9e..96d7ee2 100644 (file)
@@ -55,8 +55,6 @@ void ChatView::init(MessageFilter *filter) {
   _bufferContainer = 0;
   _currentScaleFactor = 1;
   _invalidateFilter = false;
   _bufferContainer = 0;
   _currentScaleFactor = 1;
   _invalidateFilter = false;
-  _markerLineVisible = true;
-  _markedLine = 0;
 
   setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
   setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
 
   setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
   setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
@@ -266,42 +264,23 @@ ChatLine *ChatView::lastVisibleChatLine() const {
 }
 
 void ChatView::setMarkerLineVisible(bool visible) {
 }
 
 void ChatView::setMarkerLineVisible(bool visible) {
-  if(visible != _markerLineVisible) {
-    _markerLineVisible = visible;
-  }
+  scene()->setMarkerLineVisible(visible);
 }
 
 }
 
-void ChatView::setMarkedLine(ChatLine *line) {
-  if(_markedLine == line)
-    return;
-
+void ChatView::setMarkerLine(MsgId msgId) {
   if(!scene()->isSingleBufferScene())
     return;
 
   if(!scene()->isSingleBufferScene())
     return;
 
-  if(line) {
-    BufferId bufId = scene()->singleBufferId();
-    Client::setMarkerLine(bufId, line->msgId());
-  }
+  BufferId bufId = scene()->singleBufferId();
+  Client::setMarkerLine(bufId, msgId);
 }
 
 }
 
-void ChatView::markerLineSet(BufferId buffer, MsgId msg) {
+void ChatView::markerLineSet(BufferId buffer, MsgId msgId) {
   if(!scene()->isSingleBufferScene() || scene()->singleBufferId() != buffer)
     return;
 
   if(!scene()->isSingleBufferScene() || scene()->singleBufferId() != buffer)
     return;
 
-  ChatLine *newLine = scene()->chatLine(msg);
-  if(_markedLine == newLine)
-    return;
-
-  ChatLine *oldLine = _markedLine;
-  _markedLine = newLine;
-
-  if(oldLine)
-    oldLine->update();
-
-  if(newLine) {
-    setMarkerLineVisible(true);
-    newLine->update();
-  }
+  scene()->setMarkerLine(msgId);
+  scene()->setMarkerLineVisible(true);
 }
 
 void ChatView::addActionsToMenu(QMenu *menu, const QPointF &pos) {
 }
 
 void ChatView::addActionsToMenu(QMenu *menu, const QPointF &pos) {
index 0265567..c2aa604 100644 (file)
@@ -69,9 +69,6 @@ public:
 
   virtual void addActionsToMenu(QMenu *, const QPointF &pos);
 
 
   virtual void addActionsToMenu(QMenu *, const QPointF &pos);
 
-  inline bool isMarkerLineVisible() const { return _markerLineVisible; }
-  inline ChatLine *markedLine() const { return _markedLine; }
-
   //! Tell the view that this ChatLine has cached data
   /** ChatLines cache some layout data that should be cleared as soon as it's no
    *  longer visible. A ChatLine caching data registers itself with this method to
   //! Tell the view that this ChatLine has cached data
   /** ChatLines cache some layout data that should be cleared as soon as it's no
    *  longer visible. A ChatLine caching data registers itself with this method to
@@ -88,7 +85,7 @@ public slots:
   void zoomOriginal();
 
   void setMarkerLineVisible(bool visible = true);
   void zoomOriginal();
 
   void setMarkerLineVisible(bool visible = true);
-  void setMarkedLine(ChatLine *line);
+  void setMarkerLine(MsgId msgId);
 
 protected:
   virtual bool event(QEvent *event);
 
 protected:
   virtual bool event(QEvent *event);
@@ -117,8 +114,6 @@ private:
   QTimer _scrollTimer;
   int _scrollOffset;
   bool _invalidateFilter;
   QTimer _scrollTimer;
   int _scrollOffset;
   bool _invalidateFilter;
-  bool _markerLineVisible;
-  ChatLine *_markedLine;
   QSet<ChatLine *> _linesWithCache;
 };
 
   QSet<ChatLine *> _linesWithCache;
 };
 
diff --git a/src/qtui/markerlineitem.cpp b/src/qtui/markerlineitem.cpp
new file mode 100644 (file)
index 0000000..9782a79
--- /dev/null
@@ -0,0 +1,59 @@
+/***************************************************************************
+ *   Copyright (C) 2010 by the Quassel Project                             *
+ *   devel@quassel-irc.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) version 3.                                           *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#include <QPainter>
+
+#include "markerlineitem.h"
+#include "qtui.h"
+
+MarkerLineItem::MarkerLineItem(qreal sceneWidth, QGraphicsItem *parent)
+  : QGraphicsObject(parent),
+    _boundingRect(0, 0, sceneWidth, 1)
+{
+  setZValue(8);
+  styleChanged(); // init brush and height
+  connect(QtUi::style(), SIGNAL(changed()), SLOT(styleChanged()));
+}
+
+void MarkerLineItem::styleChanged() {
+  _brush = QtUi::style()->brush(UiStyle::MarkerLine);
+
+  // if this is a solid color, we assume 1px because wesurely  don't surely don't want to fill the entire chatline.
+  // else, use the height of a single line of text to play around with gradients etc.
+  qreal height = 1.;
+  if(_brush.style() != Qt::SolidPattern)
+    height = QtUi::style()->fontMetrics(QtUiStyle::PlainMsg, 0)->lineSpacing();
+
+
+  prepareGeometryChange();
+  _boundingRect = QRectF(0, 0, scene()? scene()->width() : 100, height);
+}
+
+void MarkerLineItem::sceneRectChanged(const QRectF &rect) {
+  prepareGeometryChange();
+  _boundingRect.setWidth(rect.width());
+}
+
+void MarkerLineItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
+  Q_UNUSED(option);
+  Q_UNUSED(widget);
+
+  painter->fillRect(boundingRect(), _brush);
+}
diff --git a/src/qtui/markerlineitem.h b/src/qtui/markerlineitem.h
new file mode 100644 (file)
index 0000000..3911da8
--- /dev/null
@@ -0,0 +1,50 @@
+/***************************************************************************
+ *   Copyright (C) 2010 by the Quassel Project                             *
+ *   devel@quassel-irc.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) version 3.                                           *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#ifndef MARKERLINEITEM_H_
+#define MARKERLINEITEM_H_
+
+#include <QGraphicsObject>
+
+#include "chatscene.h"
+
+class MarkerLineItem : public QGraphicsObject {
+  Q_OBJECT
+
+public:
+  MarkerLineItem(qreal sceneWidth, QGraphicsItem *parent = 0);
+  virtual inline int type() const { return ChatScene::MarkerLineType; }
+
+  inline QRectF boundingRect() const { return _boundingRect; }
+
+  void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+public slots:
+  void sceneRectChanged(const QRectF &);
+
+private slots:
+  void styleChanged();
+
+private:
+  QRectF _boundingRect;
+  QBrush _brush;
+};
+
+#endif