diff -U 3 -H -d -r -N -x '*~' -- tmpfs/quassel/src/client/messagemodel.cpp home/sphilips/projects/quassel/src/client/messagemodel.cpp --- tmpfs/quassel/src/client/messagemodel.cpp 2008-08-29 17:41:14.000000000 +0000 +++ home/sphilips/projects/quassel/src/client/messagemodel.cpp 2008-08-30 03:15:00.000000000 +0000 @@ -25,6 +25,7 @@ MessageModel::MessageModel(QObject *parent) : QAbstractItemModel(parent) { + _grouping = false; } QVariant MessageModel::data(const QModelIndex &index, int role) const { @@ -51,6 +52,22 @@ return false; } + +/* Functions that allow intercepting the insertMessage() function. + This way the rest of the program can still call insertMessage() without + knowing what's happening under the hood. */ +void MessageModel::startGroupingMessages() { + _grouping = true; +} + +void MessageModel::stopGroupingMessages() { + _grouping = false; + if (_pendingList.isEmpty()) return; + insertMessageGroup(_pendingList); + _pendingList.clear(); +} + + bool MessageModel::insertMessage(const Message &msg, bool fakeMsg) { MsgId id = msg.msgId(); int idx = indexForId(id); @@ -59,6 +76,16 @@ return false; } + if (_grouping) { + // Prevent inserting everything backwards + if (!_pendingList.isEmpty() && _pendingList.first().msgId() > id) + _pendingList.prepend(msg); + else + _pendingList.append(msg); + return true; + } + + // Grouping is disabled, insert it the normal way. MessageModelItem *item = createMessageModelItem(msg); beginInsertRows(QModelIndex(), idx, idx); _messageList.insert(idx, item); @@ -66,13 +93,36 @@ return true; } + +void MessageModel::insertMessageGroup(const QList &msglist) { + if(msglist.isEmpty()) return; + + //qDebug() << "Inserting Group: " << msglist.count(); + + int idx = indexForId(msglist.first().msgId()); + beginInsertRows(QModelIndex(), idx, idx+msglist.count()-1); + + foreach(Message msg, msglist) { + MessageModelItem *item = createMessageModelItem(msg); + _messageList.insert(idx, item); + idx++; + } + + endInsertRows(); +} + + + +// Old code, not sure if this is doing something or not. void MessageModel::insertMessages(const QList &msglist) { if(msglist.isEmpty()) return; + // FIXME make this more efficient by grouping msgs foreach(Message msg, msglist) insertMessage(msg); } + void MessageModel::clear() { beginRemoveRows(QModelIndex(), 0, rowCount() - 1); qDeleteAll(_messageList); @@ -80,6 +130,7 @@ endRemoveRows(); } + // returns index of msg with given Id or of the next message after that (i.e., the index where we'd insert this msg) int MessageModel::indexForId(MsgId id) { if(_messageList.isEmpty() || id <= _messageList.value(0)->data(0, MsgIdRole).value()) return 0; diff -U 3 -H -d -r -N -x '*~' -- tmpfs/quassel/src/client/messagemodel.h home/sphilips/projects/quassel/src/client/messagemodel.h --- tmpfs/quassel/src/client/messagemodel.h 2008-08-29 17:41:14.000000000 +0000 +++ home/sphilips/projects/quassel/src/client/messagemodel.h 2008-08-30 01:53:12.000000000 +0000 @@ -65,6 +65,10 @@ bool insertMessage(const Message &, bool fakeMsg = false); void insertMessages(const QList &); + void insertMessageGroup(const QList &); + + void startGroupingMessages(); + void stopGroupingMessages(); void clear(); @@ -73,6 +77,9 @@ private: QList _messageList; + QList _pendingList; // About to be inserted. + + bool _grouping; int indexForId(MsgId); }; diff -U 3 -H -d -r -N -x '*~' -- tmpfs/quassel/src/qtui/chatline.cpp home/sphilips/projects/quassel/src/qtui/chatline.cpp --- tmpfs/quassel/src/qtui/chatline.cpp 2008-08-29 17:41:14.000000000 +0000 +++ home/sphilips/projects/quassel/src/qtui/chatline.cpp 2008-08-30 03:05:18.000000000 +0000 @@ -113,6 +113,11 @@ void ChatLine::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(option); Q_UNUSED(widget); + + // Some tweaks. They gain us a few ms, but every bit helps. + painter->setPen(Qt::NoPen); // Apparently, using a Pen is slow when drawing text. + painter->setClipRect(option->exposedRect); // Don't repaint things that don't have to be repainted. + if(_selection & Highlighted) { painter->fillRect(boundingRect(), QBrush(QtUi::style()->highlightColor())); } diff -U 3 -H -d -r -N -x '*~' -- tmpfs/quassel/src/qtui/chatview.cpp home/sphilips/projects/quassel/src/qtui/chatview.cpp --- tmpfs/quassel/src/qtui/chatview.cpp 2008-08-29 17:41:14.000000000 +0000 +++ home/sphilips/projects/quassel/src/qtui/chatview.cpp 2008-08-30 03:08:06.000000000 +0000 @@ -50,6 +50,15 @@ setAlignment(Qt::AlignBottom); setInteractive(true); + // We don't need any of those as we just draw text and horizontal/vertical lines. + setOptimizationFlag(QGraphicsView::DontClipPainter); + setOptimizationFlag(QGraphicsView::DontSavePainterState); + setOptimizationFlag(QGraphicsView::DontAdjustForAntialiasing); + + // Not sure which of these two is the fastest. + //setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate); + setViewportUpdateMode(QGraphicsView::SmartViewportUpdate); + _scene = new ChatScene(filter, filter->idString(), this); connect(_scene, SIGNAL(heightChangedAt(qreal, qreal)), this, SLOT(sceneHeightChangedAt(qreal, qreal))); setScene(_scene); diff -U 3 -H -d -r -N -x '*~' -- tmpfs/quassel/src/qtui/qtuimessageprocessor.cpp home/sphilips/projects/quassel/src/qtui/qtuimessageprocessor.cpp --- tmpfs/quassel/src/qtui/qtuimessageprocessor.cpp 2008-08-29 17:41:14.000000000 +0000 +++ home/sphilips/projects/quassel/src/qtui/qtuimessageprocessor.cpp 2008-08-30 02:56:10.000000000 +0000 @@ -82,6 +82,7 @@ void QtUiMessageProcessor::processNextMessage() { if(_currentBatch.isEmpty()) { + Client::messageModel()->stopGroupingMessages(); if(_processQueue.isEmpty()) { _processTimer.stop(); _processing = false; @@ -90,6 +91,8 @@ return; } _currentBatch = _processQueue.takeFirst(); + if (_currentBatch.count() > 1) // Otherwise it's a waste of resources + Client::messageModel()->startGroupingMessages(); } Message msg = _currentBatch.takeFirst(); process(msg); @@ -125,7 +128,7 @@ nickList = myIdentity->nicks(); } foreach(QString nickname, nickList) { - QRegExp nickRegExp("^(.*\\W)?" + QRegExp::escape(nickname) + "(\\W.*)?$"); + QRegExp nickRegExp("^(?:.*\\W)?" + QRegExp::escape(nickname) + "(?:\\W.*)?$"); if(nickRegExp.exactMatch(msg.contents())) { msg.setFlags(msg.flags() | Message::Highlight); return; @@ -135,13 +138,13 @@ for(int i = 0; i < _highlightRules.count(); i++) { const HighlightRule &rule = _highlightRules[i]; if(!rule.isEnabled) - continue; + continue; QRegExp userRegExp; if(rule.isRegExp) { userRegExp = QRegExp(rule.name, rule.caseSensitive); } else { - userRegExp = QRegExp("^(.*\\W)?" + QRegExp::escape(rule.name) + "(\\W.*)?$", rule.caseSensitive); + userRegExp = QRegExp("^(?:.*\\W)?" + QRegExp::escape(rule.name) + "(?:\\W.*)?$", rule.caseSensitive); } if(userRegExp.exactMatch(msg.contents())) { msg.setFlags(msg.flags() | Message::Highlight);