X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fqtui%2Fchatscene.cpp;h=e5537a054b3da285450b8779b4a2ade17b5c0d91;hp=d78ee1c825eede84a29e4a6c9579da0c697294eb;hb=a4eb9eaf480ea9df5b4a070ad40171c5f2345440;hpb=894e2dd800e90ab52618fa620b1c995545506574 diff --git a/src/qtui/chatscene.cpp b/src/qtui/chatscene.cpp index d78ee1c8..e5537a05 100644 --- a/src/qtui/chatscene.cpp +++ b/src/qtui/chatscene.cpp @@ -66,8 +66,9 @@ ChatScene::ChatScene(QAbstractItemModel *model, const QString &idString, qreal w _firstLineRow(-1), _viewportHeight(0), _markerLine(new MarkerLineItem(width)), - _markerLineValid(false), _markerLineVisible(false), + _markerLineValid(false), + _markerLineJumpPending(false), _cutoffMode(CutoffRight), _selectingItem(0), _selectionStart(-1), @@ -147,7 +148,7 @@ ColumnHandleItem *ChatScene::secondColumnHandle() const { return _secondColHandle; } -ChatLine *ChatScene::chatLine(MsgId msgId, bool matchExact) const { +ChatLine *ChatScene::chatLine(MsgId msgId, bool matchExact, bool ignoreDayChange) const { if(!_lines.count()) return 0; @@ -169,21 +170,37 @@ ChatLine *ChatScene::chatLine(MsgId msgId, bool matchExact) const { } } - if(start != end && (*start)->msgId() == msgId) + if(start != end && (*start)->msgId() == msgId && (ignoreDayChange? (*start)->msgType() != Message::DayChange : true)) return *start; if(matchExact) return 0; + if(start == _lines.begin()) // not (yet?) in our scene + 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 + if(start == end) { // higher than last element + if(!ignoreDayChange) + return _lines.last(); + + for(int i = _lines.count() -1; i >= 0; i--) { + if(_lines.at(i)->msgType() != Message::DayChange) + return _lines.at(i); + } return 0; + } // return the next-lower line - return *(--start); + if(!ignoreDayChange) + return *(--start); + + do { + if((*(--start))->msgType() != Message::DayChange) + return *start; + } while(start != _lines.begin()); + return 0; } ChatItem *ChatScene::chatItemAt(const QPointF &scenePos) const { @@ -206,36 +223,71 @@ bool ChatScene::containsBuffer(const BufferId &id) const { void ChatScene::setMarkerLineVisible(bool visible) { _markerLineVisible = visible; if(visible && _markerLineValid) - _markerLine->setVisible(true); + markerLine()->setVisible(true); else - _markerLine->setVisible(false); + markerLine()->setVisible(false); } void ChatScene::setMarkerLine(MsgId msgId) { + if(!isSingleBufferScene()) + return; + + if(!msgId.isValid()) + msgId = Client::markerLine(singleBufferId()); + if(msgId.isValid()) { - ChatLine *line = chatLine(msgId, false); + ChatLine *line = chatLine(msgId, false, true); if(line) { + markerLine()->setChatLine(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())); + 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()) { + if(markerLine()->pos().y() >= sceneRect().y()) { _markerLineValid = true; if(_markerLineVisible) - _markerLine->setVisible(true); + markerLine()->setVisible(true); + if(_markerLineJumpPending) { + _markerLineJumpPending = false; + if(markerLine()->isVisible()) { + markerLine()->ensureVisible(QRectF(), 50, 50); + } + } return; } } } _markerLineValid = false; - _markerLine->setVisible(false); + markerLine()->setVisible(false); +} + +void ChatScene::jumpToMarkerLine(bool requestBacklog) { + if(!isSingleBufferScene()) + return; + + if(markerLine()->isVisible()) { + markerLine()->ensureVisible(QRectF(), 50, 50); + return; + } + if(!_markerLineValid && requestBacklog) { + MsgId msgId = Client::markerLine(singleBufferId()); + if(msgId.isValid()) { + _markerLineJumpPending = true; + Client::backlogManager()->requestBacklog(singleBufferId(), msgId, -1, -1, 0); + + // If we filtered out the lastSeenMsg (by changing filters after setting it), we'd never jump because the above request + // won't fetch any prior lines. Thus, trigger a dynamic backlog request just in case, so repeated + // jump tries will eventually cause enough backlog to be fetched. + // This is a bit hackish, but not wasteful, as jumping to the top of the ChatView would trigger a dynamic fetch anyway. + this->requestBacklog(); + } + } } void ChatScene::rowsInserted(const QModelIndex &index, int start, int end) { Q_UNUSED(index); - // QModelIndex sidx = model()->index(start, 2); // QModelIndex eidx = model()->index(end, 2); // qDebug() << "rowsInserted:"; @@ -323,6 +375,8 @@ void ChatScene::rowsInserted(const QModelIndex &index, int start, int end) { for(int i = 0; i <= end; i++) { line = _lines.at(i); line->setPos(0, line->pos().y() - h); + if(line == markerLine()->chatLine()) + markerLine()->setPos(line->pos() + QPointF(0, line->height())); } } @@ -364,12 +418,8 @@ void ChatScene::rowsInserted(const QModelIndex &index, int start, int end) { } // 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); - } - } + if(!_markerLineValid) + setMarkerLine(); } void ChatScene::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) { @@ -392,6 +442,8 @@ void ChatScene::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int e QList::iterator lineIter = _lines.begin() + start; int lineCount = start; while(lineIter != _lines.end() && lineCount <= end) { + if((*lineIter) == markerLine()->chatLine()) + markerLine()->setChatLine(0); h += (*lineIter)->height(); delete *lineIter; lineIter = _lines.erase(lineIter); @@ -465,10 +517,7 @@ void ChatScene::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int e void ChatScene::rowsRemoved() { // move the marker line if necessary - if(isSingleBufferScene()) { - MsgId msgId = Client::markerLine(singleBufferId()); - setMarkerLine(msgId); - } + setMarkerLine(); } void ChatScene::dataChanged(const QModelIndex &tl, const QModelIndex &br) { @@ -518,6 +567,7 @@ void ChatScene::layout(int start, int end, qreal width) { updateSceneRect(width); setHandleXLimits(); + setMarkerLine(); emit layoutChanged(); // clock_t endT = clock(); @@ -967,14 +1017,6 @@ void ChatScene::updateSceneRect(const QRectF &rect) { update(); } -bool ChatScene::event(QEvent *e) { - if(e->type() == QEvent::ApplicationPaletteChange) { - _firstColHandle->setColor(QApplication::palette().windowText().color()); - _secondColHandle->setColor(QApplication::palette().windowText().color()); - } - return QGraphicsScene::event(e); -} - // ======================================== // Webkit Only stuff // ========================================