X-Git-Url: https://git.quassel-irc.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fqtui%2Fchatscene.cpp;h=67415cc3b7f658cbf8255e5424d81be1351e8535;hb=22128f214112de5e4f3111e0a90f7d5d99e82dac;hp=b5dd4528cb26e5c01544130c0b67e0638012f96c;hpb=d77cc962c2bc0de9e6288020804842ffe116f838;p=quassel.git diff --git a/src/qtui/chatscene.cpp b/src/qtui/chatscene.cpp index b5dd4528..67415cc3 100644 --- a/src/qtui/chatscene.cpp +++ b/src/qtui/chatscene.cpp @@ -38,6 +38,11 @@ const qreal minContentsWidth = 200; +class ClearWebPreviewEvent : public QEvent { +public: + inline ClearWebPreviewEvent() : QEvent(QEvent::User) {} +}; + ChatScene::ChatScene(QAbstractItemModel *model, const QString &idString, qreal width, QObject *parent) : QGraphicsScene(0, 0, width, 0, parent), _idString(idString), @@ -85,6 +90,9 @@ ChatScene::ChatScene(QAbstractItemModel *model, const QString &idString, qreal w if(model->rowCount() > 0) rowsInserted(QModelIndex(), 0, model->rowCount() - 1); + + webPreview.delayTimer.setSingleShot(true); + connect(&webPreview.delayTimer, SIGNAL(timeout()), this, SLOT(showWebPreview())); } ChatScene::~ChatScene() { @@ -92,9 +100,6 @@ ChatScene::~ChatScene() { void ChatScene::rowsInserted(const QModelIndex &index, int start, int end) { Q_UNUSED(index); - - clearWebPreview(); - // QModelIndex sidx = model()->index(start, 0); // QModelIndex eidx = model()->index(end, 0); // qDebug() << "rowsInserted" << start << end << "-" << sidx.data(MessageModel::MsgIdRole).value() << eidx.data(MessageModel::MsgIdRole).value(); @@ -122,20 +127,28 @@ void ChatScene::rowsInserted(const QModelIndex &index, int start, int end) { QPointF contentsPos(secondColumnHandle()->sceneRight(), 0); QPointF senderPos(firstColumnHandle()->sceneRight(), 0); - for(int i = start; i <= end; i++) { - ChatLine *line = new ChatLine(i, model(), - width, - timestampWidth, senderWidth, contentsWidth, - senderPos, contentsPos); - if(atTop) { + if(atTop) { + for(int i = end; i >= start; i--) { + ChatLine *line = new ChatLine(i, model(), + width, + timestampWidth, senderWidth, contentsWidth, + senderPos, contentsPos); h += line->height(); line->setPos(0, y-h); - } else { + _lines.insert(start, line); + addItem(line); + } + } else { + for(int i = start; i <= end; i++) { + ChatLine *line = new ChatLine(i, model(), + width, + timestampWidth, senderWidth, contentsWidth, + senderPos, contentsPos); line->setPos(0, y+h); h += line->height(); + _lines.insert(i, line); + addItem(line); } - _lines.insert(i, line); - addItem(line); } // update existing items @@ -166,7 +179,7 @@ void ChatScene::rowsInserted(const QModelIndex &index, int start, int end) { moveEnd = end; } else { // move bottom part - moveStart = start; + moveStart = end + 1; } ChatLine *line = 0; for(int i = moveStart; i <= moveEnd; i++) { @@ -186,8 +199,8 @@ void ChatScene::rowsInserted(const QModelIndex &index, int start, int end) { _firstLineRow = -1; } updateSceneRect(); - if(atBottom) { - emit lastLineChanged(_lines.last()); + if(atBottom || (!atTop && !moveTop)) { + emit lastLineChanged(_lines.last(), h); } } @@ -195,8 +208,6 @@ void ChatScene::rowsInserted(const QModelIndex &index, int start, int end) { void ChatScene::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) { Q_UNUSED(parent); - clearWebPreview(); - qreal h = 0; // total height of removed items; bool atTop = (start == 0); @@ -548,6 +559,13 @@ void ChatScene::updateSceneRect(const QRectF &rect) { setSceneRect(rect); } +void ChatScene::customEvent(QEvent *event) { + if(event->type() != QEvent::User) + return; + + event->accept(); + clearWebPreviewEvent(); +} void ChatScene::loadWebPreview(ChatItem *parentItem, const QString &url, const QRectF &urlRect) { #ifndef HAVE_WEBKIT @@ -566,7 +584,7 @@ void ChatScene::loadWebPreview(ChatItem *parentItem, const QString &url, const Q delete webPreview.previewItem; } webPreview.previewItem = new WebPreviewItem(url); - addItem(webPreview.previewItem); + webPreview.delayTimer.start(2000); } if(webPreview.urlRect != urlRect) { webPreview.urlRect = urlRect; @@ -588,14 +606,31 @@ void ChatScene::clearWebPreview(ChatItem *parentItem) { Q_UNUSED(parentItem) #else if(parentItem == 0 || webPreview.parentItem == parentItem) { - if(webPreview.previewItem) { + // posting an event ensures that the item will not be removed as + // the result of another event. this could result in bad segfaults + QCoreApplication::postEvent(this, new ClearWebPreviewEvent()); + } +#endif +} + +void ChatScene::showWebPreview() { +#ifdef HAVE_WEBKIT + if(webPreview.previewItem) + addItem(webPreview.previewItem); +#endif +} + +void ChatScene::clearWebPreviewEvent() { +#ifdef HAVE_WEBKIT + if(webPreview.previewItem) { + if(webPreview.previewItem->scene()) { removeItem(webPreview.previewItem); - delete webPreview.previewItem; - webPreview.previewItem = 0; } - webPreview.parentItem = 0; - webPreview.url = QString(); - webPreview.urlRect = QRectF(); + delete webPreview.previewItem; + webPreview.previewItem = 0; } + webPreview.parentItem = 0; + webPreview.url = QString(); + webPreview.urlRect = QRectF(); #endif }