From: Marcus Eggenberger Date: Tue, 5 Aug 2008 14:35:27 +0000 (+0200) Subject: persitentmodelindexes-- X-Git-Tag: 0.3.0~105 X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=commitdiff_plain;h=ba9de06a8634a30863d54001cb8f934746333d58 persitentmodelindexes-- --- diff --git a/src/qtui/chatitem.cpp b/src/qtui/chatitem.cpp index f09553b5..d58c6bcf 100644 --- a/src/qtui/chatitem.cpp +++ b/src/qtui/chatitem.cpp @@ -31,12 +31,18 @@ #include "chatlinemodel.h" #include "qtui.h" -ChatItem::ChatItem(const QPersistentModelIndex &index_, QGraphicsItem *parent) : QGraphicsItem(parent), _index(index_) { - _fontMetrics = QtUi::style()->fontMetrics(data(ChatLineModel::FormatRole).value().at(0).second); - _layout = 0; - _lines = 0; - _selectionStart = -1; - _selectionMode = NoSelection; +ChatItem::ChatItem(int col, QAbstractItemModel *model, QGraphicsItem *parent) + : QGraphicsItem(parent), + _fontMetrics(0), + _col(col), + _lines(0), + _layout(0), + _selectionMode(NoSelection), + _selectionStart(-1) +{ + Q_ASSERT(model); + QModelIndex index = model->index(row(), col); + _fontMetrics = QtUi::style()->fontMetrics(model->data(index, ChatLineModel::FormatRole).value().at(0).second); setAcceptHoverEvents(true); setZValue(20); } @@ -46,11 +52,12 @@ ChatItem::~ChatItem() { } QVariant ChatItem::data(int role) const { - if(!_index.isValid()) { - qWarning() << "ChatItem::data(): Model index is invalid!" << _index; + QModelIndex index = model()->index(row(), column()); + if(!index.isValid()) { + qWarning() << "ChatItem::data(): model index is invalid!" << index; return QVariant(); } - return _index.data(role); + return model()->data(index, role); } qreal ChatItem::setWidth(qreal w) { diff --git a/src/qtui/chatitem.h b/src/qtui/chatitem.h index 840184d7..b0375d6c 100644 --- a/src/qtui/chatitem.h +++ b/src/qtui/chatitem.h @@ -24,23 +24,23 @@ #include #include -#include "chatline.h" #include "chatlinemodel.h" #include "chatscene.h" #include "uistyle.h" +#include "qtui.h" class QTextLayout; class ChatItem : public QGraphicsItem { public: - ChatItem(const QPersistentModelIndex &index, QGraphicsItem *parent); + ChatItem(int col, QAbstractItemModel *, QGraphicsItem *parent); virtual ~ChatItem(); - inline QPersistentModelIndex index() const { return _index; } - inline const MessageModel *model() const { return _index.isValid() ? qobject_cast(_index.model()) : 0; } - inline int row() const { return _index.isValid() ? _index.row() : 0; } - inline ChatScene *chatScene() const { return qobject_cast(scene()); } + inline const QAbstractItemModel *model() const { return chatScene() ? chatScene()->model() : 0; } + int row() const; + inline int column() const { return _col; } + inline ChatScene *chatScene() const { return qobject_cast(scene()); } inline QFontMetricsF *fontMetrics() const { return _fontMetrics; } inline virtual QRectF boundingRect() const { return _boundingRect; } @@ -82,8 +82,8 @@ class ChatItem : public QGraphicsItem { QRectF _boundingRect; QFontMetricsF *_fontMetrics; + int _col; quint8 _lines; - QPersistentModelIndex _index; QTextLayout * _layout; QList _wrapPositions; @@ -113,4 +113,8 @@ class ChatItem::WrapColumnFinder { qreal w; }; +#include "chatline.h" +inline int ChatItem::row() const { return static_cast(parentItem())->row(); } + + #endif diff --git a/src/qtui/chatline.cpp b/src/qtui/chatline.cpp index 5f03d9d0..0e4df226 100644 --- a/src/qtui/chatline.cpp +++ b/src/qtui/chatline.cpp @@ -27,22 +27,19 @@ #include "chatline.h" #include "qtui.h" -ChatLine::ChatLine(const QModelIndex &index, QGraphicsItem *parent) : QGraphicsItem(parent) { - _timestampItem = new ChatItem(QPersistentModelIndex(index.sibling(index.row(), ChatLineModel::TimestampColumn)), this); - _senderItem = new ChatItem(QPersistentModelIndex(index.sibling(index.row(), ChatLineModel::SenderColumn)), this); - _contentsItem = new ChatItem(QPersistentModelIndex(index.sibling(index.row(), ChatLineModel::ContentsColumn)), this); - - _timestampItem->setPos(0,0); - _width = _height = 0; - _selection = 0; - - if(_contentsItem->data(MessageModel::FlagsRole).toInt() & Message::Highlight) setHighlighted(true); -} - -ChatLine::~ChatLine() { - delete _timestampItem; - delete _senderItem; - delete _contentsItem; +ChatLine::ChatLine(int row, QAbstractItemModel *model, QGraphicsItem *parent) + : QGraphicsItem(parent), + _row(row), // needs to be set before the items + _timestampItem(ChatLineModel::TimestampColumn, model, this), + _senderItem(ChatLineModel::SenderColumn, model, this), + _contentsItem(ChatLineModel::ContentsColumn, model, this), + _width(0), + _height(0), + _selection(0) +{ + Q_ASSERT(model); + QModelIndex index = model->index(row, ChatLineModel::ContentsColumn); + setHighlighted(model->data(index, MessageModel::FlagsRole).toInt() & Message::Highlight); } QRectF ChatLine::boundingRect () const { @@ -50,26 +47,31 @@ QRectF ChatLine::boundingRect () const { return QRectF(0, 0, _width, _height); } -ChatItem *ChatLine::item(ChatLineModel::ColumnType column) const { +ChatItem &ChatLine::item(ChatLineModel::ColumnType column) { switch(column) { - case ChatLineModel::TimestampColumn: return _timestampItem; - case ChatLineModel::SenderColumn: return _senderItem; - case ChatLineModel::ContentsColumn: return _contentsItem; - default: return 0; + case ChatLineModel::TimestampColumn: + return _timestampItem; + case ChatLineModel::SenderColumn: + return _senderItem; + case ChatLineModel::ContentsColumn: + return _contentsItem; + default: + return *(ChatItem *)0; // provoke an error } } qreal ChatLine::setGeometry(qreal width, qreal firstHandlePos, qreal secondHandlePos) { - if(width != _width) prepareGeometryChange(); + if(width != _width) + prepareGeometryChange(); qreal firstsep = QtUi::style()->firstColumnSeparator()/2; qreal secondsep = QtUi::style()->secondColumnSeparator()/2; - _timestampItem->setWidth(firstHandlePos - firstsep); - _senderItem->setWidth(secondHandlePos - firstHandlePos - (firstsep+secondsep)); - _height = _contentsItem->setWidth(width - secondHandlePos - secondsep); + _timestampItem.setWidth(firstHandlePos - firstsep); + _senderItem.setWidth(secondHandlePos - firstHandlePos - (firstsep+secondsep)); + _height = _contentsItem.setWidth(width - secondHandlePos - secondsep); - _senderItem->setPos(firstHandlePos + firstsep, 0); - _contentsItem->setPos(secondHandlePos + secondsep, 0); + _senderItem.setPos(firstHandlePos + firstsep, 0); + _contentsItem.setPos(secondHandlePos + secondsep, 0); _width = width; return _height; @@ -80,15 +82,18 @@ void ChatLine::setSelected(bool selected, ChatLineModel::ColumnType minColumn) { quint8 sel = (_selection & 0x80) | 0x40 | minColumn; if(sel != _selection) { _selection = sel; - for(int i = 0; i < minColumn; i++) item((ChatLineModel::ColumnType)i)->clearSelection(); - for(int i = minColumn; i <= ChatLineModel::ContentsColumn; i++) item((ChatLineModel::ColumnType)i)->setFullSelection(); + for(int i = 0; i < minColumn; i++) + item((ChatLineModel::ColumnType)i).clearSelection(); + for(int i = minColumn; i <= ChatLineModel::ContentsColumn; i++) + item((ChatLineModel::ColumnType)i).setFullSelection(); update(); } } else { quint8 sel = _selection & 0x80; if(sel != _selection) { _selection = sel; - for(int i = 0; i <= ChatLineModel::ContentsColumn; i++) item((ChatLineModel::ColumnType)i)->clearSelection(); + for(int i = 0; i <= ChatLineModel::ContentsColumn; i++) + item((ChatLineModel::ColumnType)i).clearSelection(); update(); } } @@ -105,7 +110,7 @@ void ChatLine::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, painter->fillRect(boundingRect(), QBrush(QtUi::style()->highlightColor())); } if(_selection & Selected) { - qreal left = item((ChatLineModel::ColumnType)(_selection & 0x3f))->x(); + qreal left = item((ChatLineModel::ColumnType)(_selection & 0x3f)).x(); QRectF selectRect(left, 0, width() - left, height()); painter->fillRect(selectRect, QApplication::palette().brush(QPalette::Highlight)); } diff --git a/src/qtui/chatline.h b/src/qtui/chatline.h index 3649c549..724be7dc 100644 --- a/src/qtui/chatline.h +++ b/src/qtui/chatline.h @@ -24,19 +24,20 @@ #include #include "chatlinemodel.h" - -class ChatItem; +#include "chatitem.h" class ChatLine : public QGraphicsItem { public: - ChatLine(const QModelIndex &tempIndex, QGraphicsItem *parent = 0); - virtual ~ChatLine(); + ChatLine(int row, QAbstractItemModel *model, QGraphicsItem *parent = 0); virtual QRectF boundingRect () const; + + inline int row() { return _row; } + inline void setRow(int row) { _row = row; } inline qreal width() const { return _width; } inline qreal height() const { return _height; } - ChatItem *item(ChatLineModel::ColumnType) const; + ChatItem &item(ChatLineModel::ColumnType); virtual void paint (QPainter * painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); @@ -48,7 +49,8 @@ class ChatLine : public QGraphicsItem { protected: private: - ChatItem *_timestampItem, *_senderItem, *_contentsItem; + int _row; + ChatItem _timestampItem, _senderItem, _contentsItem; qreal _width, _height; enum { Selected = 0x40, Highlighted = 0x80 }; diff --git a/src/qtui/chatscene.cpp b/src/qtui/chatscene.cpp index 8f36e1d2..43ff2480 100644 --- a/src/qtui/chatscene.cpp +++ b/src/qtui/chatscene.cpp @@ -25,6 +25,7 @@ #include "buffer.h" #include "chatitem.h" +#include "chatline.h" #include "chatlinemodelitem.h" #include "chatscene.h" #include "columnhandleitem.h" @@ -47,7 +48,7 @@ ChatScene::ChatScene(QAbstractItemModel *model, const QString &idString, QObject connect(model, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SLOT(rowsInserted(const QModelIndex &, int, int))); connect(model, SIGNAL(modelAboutToBeReset()), this, SLOT(modelReset())); for(int i = 0; i < model->rowCount(); i++) { - ChatLine *line = new ChatLine(model->index(i, 0)); + ChatLine *line = new ChatLine(i, model); _lines.append(line); addItem(line); } @@ -88,7 +89,7 @@ void ChatScene::rowsInserted(const QModelIndex &index, int start, int end) { qreal y = 0; if(_width && start > 0) y = _lines.value(start - 1)->y() + _lines.value(start - 1)->height(); for(int i = start; i <= end; i++) { - ChatLine *line = new ChatLine(model()->index(i, 0)); + ChatLine *line = new ChatLine(i, model()); _lines.insert(i, line); addItem(line); if(_width > 0) { @@ -96,6 +97,11 @@ void ChatScene::rowsInserted(const QModelIndex &index, int start, int end) { h += line->setGeometry(_width, firstColHandlePos, secondColHandlePos); } } + // update existing items + for(int i = end+1; i < _lines.count(); i++) { + _lines[i]->setRow(i); + } + if(h > 0) { _height += h; for(int i = end+1; i < _lines.count(); i++) { @@ -160,8 +166,8 @@ void ChatScene::setSelectingItem(ChatItem *item) { } void ChatScene::startGlobalSelection(ChatItem *item, const QPointF &itemPos) { - _selectionStart = _selectionEnd = item->index().row(); - _selectionStartCol = _selectionMinCol = item->index().column(); + _selectionStart = _selectionEnd = item->row(); + _selectionStartCol = _selectionMinCol = item->column(); _isSelecting = true; _lines[_selectionStart]->setSelected(true, (ChatLineModel::ColumnType)_selectionMinCol); updateSelection(item->mapToScene(itemPos)); @@ -173,7 +179,7 @@ void ChatScene::updateSelection(const QPointF &pos) { ChatItem *contentItem = static_cast(itemAt(QPointF(secondColHandlePos + secondColHandle->width()/2, pos.y()))); if(!contentItem) return; - int curRow = contentItem->index().row(); + int curRow = contentItem->row(); int curColumn; if(pos.x() > secondColHandlePos + secondColHandle->width()/2) curColumn = ChatLineModel::ContentsColumn; else if(pos.x() > firstColHandlePos) curColumn = ChatLineModel::SenderColumn; @@ -262,10 +268,10 @@ QString ChatScene::selectionToString() const { QString result; for(int l = start; l <= end; l++) { if(_selectionMinCol == ChatLineModel::TimestampColumn) - result += _lines[l]->item(ChatLineModel::TimestampColumn)->data(MessageModel::DisplayRole).toString() + " "; + result += _lines[l]->item(ChatLineModel::TimestampColumn).data(MessageModel::DisplayRole).toString() + " "; if(_selectionMinCol <= ChatLineModel::SenderColumn) - result += _lines[l]->item(ChatLineModel::SenderColumn)->data(MessageModel::DisplayRole).toString() + " "; - result += _lines[l]->item(ChatLineModel::ContentsColumn)->data(MessageModel::DisplayRole).toString() + "\n"; + result += _lines[l]->item(ChatLineModel::SenderColumn).data(MessageModel::DisplayRole).toString() + " "; + result += _lines[l]->item(ChatLineModel::ContentsColumn).data(MessageModel::DisplayRole).toString() + "\n"; } return result; }