this should fix BR #377 - needs to be tested
[quassel.git] / src / qtui / chatscene.cpp
index f71c857..c062082 100644 (file)
@@ -47,10 +47,10 @@ ChatScene::ChatScene(QAbstractItemModel *model, const QString &idString, qreal w
     _sceneRect(0, 0, width, 0),
     _firstLineRow(-1),
     _viewportHeight(0),
+    _cutoffMode(CutoffRight),
     _selectingItem(0),
     _selectionStart(-1),
-    _isSelecting(false),
-    _lastBacklogSize(0)
+    _isSelecting(false)
 {
   MessageFilter *filter = qobject_cast<MessageFilter*>(model);
   if(filter) {
@@ -75,6 +75,7 @@ ChatScene::ChatScene(QAbstractItemModel *model, const QString &idString, qreal w
   addItem(_secondColHandle);
   _secondColHandle->setXPos(_secondColHandlePos);
   connect(_secondColHandle, SIGNAL(positionChanged(qreal)), this, SLOT(secondHandlePositionChanged(qreal)));
+
   connect(this, SIGNAL(sceneRectChanged(const QRectF &)), _secondColHandle, SLOT(sceneRectChanged(const QRectF &)));
 
   setHandleXLimits();
@@ -107,20 +108,16 @@ void ChatScene::rowsInserted(const QModelIndex &index, int start, int end) {
 //   qDebug() << "rowsInserted" << start << end << "-" << sidx.data(MessageModel::MsgIdRole).value<MsgId>() << eidx.data(MessageModel::MsgIdRole).value<MsgId>();
 
   qreal h = 0;
-  qreal y = _sceneRect.y();
+  qreal y = 0;
   qreal width = _sceneRect.width();
-  bool atTop = true;
-  bool atBottom = false;
+  bool atBottom = (start == _lines.count());
+  bool atTop = !atBottom && (start == 0);
   bool moveTop = false;
 
-  if(start > 0 && start < _lines.count()) {
+  if(start < _lines.count()) {
     y = _lines.value(start)->y();
-    atTop = false;
-  }
-  if(start == _lines.count()) {
-    y = _sceneRect.bottom();
-    atTop = false;
-    atBottom = true;
+  } else if(atBottom && !_lines.isEmpty()) {
+    y = _lines.last()->y() + _lines.last()->height();
   }
 
   qreal contentsWidth = width - secondColumnHandle()->sceneRight();
@@ -168,10 +165,10 @@ void ChatScene::rowsInserted(const QModelIndex &index, int start, int end) {
   }
 
   // neither pre- or append means we have to do dirty work: move items...
+  int moveStart = 0;
+  int moveEnd = _lines.count() - 1;
+  qreal offset = h;
   if(!(atTop || atBottom)) {
-    qreal offset = h;
-    int moveStart = 0;
-    int moveEnd = _lines.count() - 1;
     // move top means: moving 0 to end (aka: end + 1)
     // move top means: moving end + 1 to _lines.count() - 1 (aka: _lines.count() - (end + 1)
     if(end + 1 < _lines.count() - end - 1) {
@@ -192,7 +189,25 @@ void ChatScene::rowsInserted(const QModelIndex &index, int start, int end) {
 
   // check if all went right
   Q_ASSERT(start == 0 || _lines.at(start - 1)->pos().y() + _lines.at(start - 1)->height() == _lines.at(start)->pos().y());
+//   if(start != 0) {
+//     if(_lines.at(start - 1)->pos().y() + _lines.at(start - 1)->height() != _lines.at(start)->pos().y()) {
+//       qDebug() << "lines:" << _lines.count() << "start:" << start << "end:" << end;
+//       qDebug() << "line[start - 1]:" << _lines.at(start - 1)->pos().y() << "+" << _lines.at(start - 1)->height() << "=" << _lines.at(start - 1)->pos().y() + _lines.at(start - 1)->height();
+//       qDebug() << "line[start]" << _lines.at(start)->pos().y();
+//       qDebug() << "needed moving:" << !(atTop || atBottom) << moveTop << moveStart << moveEnd << offset;
+//       Q_ASSERT(false)
+//     }
+//   }
   Q_ASSERT(end + 1 == _lines.count() || _lines.at(end)->pos().y() + _lines.at(end)->height() == _lines.at(end + 1)->pos().y());
+//   if(end + 1 < _lines.count()) {
+//     if(_lines.at(end)->pos().y() + _lines.at(end)->height() != _lines.at(end + 1)->pos().y()) {
+//       qDebug() << "lines:" << _lines.count() << "start:" << start << "end:" << end;
+//       qDebug() << "line[end]:" << _lines.at(end)->pos().y() << "+" << _lines.at(end)->height() << "=" << _lines.at(end)->pos().y() + _lines.at(end)->height();
+//       qDebug() << "line[end+1]" << _lines.at(end + 1)->pos().y();
+//       qDebug() << "needed moving:" << !(atTop || atBottom) << moveTop << moveStart << moveEnd << offset;
+//       Q_ASSERT(false);
+//     }
+//   }
 
   if(!atBottom) {
     if(start < _firstLineRow) {
@@ -525,18 +540,10 @@ QString ChatScene::selectionToString() const {
 }
 
 void ChatScene::requestBacklog() {
-  static const int REQUEST_COUNT = 500;
-  int backlogSize = model()->rowCount();
-  if(isSingleBufferScene() && backlogSize != 0 && _lastBacklogSize + REQUEST_COUNT <= backlogSize) {
-    QModelIndex msgIdx = model()->index(0, 0);
-    while((Message::Type)(model()->data(msgIdx, ChatLineModel::TypeRole).toInt()) == Message::DayChange) {
-      msgIdx = msgIdx.sibling(msgIdx.row() + 1, 0);
-    }
-    MsgId msgId = model()->data(msgIdx, ChatLineModel::MsgIdRole).value<MsgId>();
-    BufferId bufferId = model()->data(msgIdx, ChatLineModel::BufferIdRole).value<BufferId>();
-    _lastBacklogSize = backlogSize;
-    Client::backlogManager()->requestBacklog(bufferId, REQUEST_COUNT, msgId.toInt());
-  }
+  MessageFilter *filter = qobject_cast<MessageFilter*>(model());
+  if(filter)
+    return filter->requestBacklog();
+  return;
 }
 
 int ChatScene::sectionByScenePos(int x) {
@@ -573,9 +580,14 @@ void ChatScene::updateSceneRect(qreal width) {
   }
 
   // the following call should be safe. If it crashes something went wrong during insert/remove
-  ChatLine *firstLine = _lines.at(_firstLineRow);
-  ChatLine *lastLine = _lines.last();
-  updateSceneRect(QRectF(0, firstLine->pos().y(), width, lastLine->pos().y() + lastLine->height() - firstLine->pos().y()));
+  if(_firstLineRow < _lines.count()) {
+    ChatLine *firstLine = _lines.at(_firstLineRow);
+    ChatLine *lastLine = _lines.last();
+    updateSceneRect(QRectF(0, firstLine->pos().y(), width, lastLine->pos().y() + lastLine->height() - firstLine->pos().y()));
+  } else {
+    // empty scene rect
+    updateSceneRect(QRectF(0, 0, width, 0));
+  }
 }
 
 void ChatScene::updateSceneRect(const QRectF &rect) {
@@ -584,11 +596,12 @@ void ChatScene::updateSceneRect(const QRectF &rect) {
   update();
 }
 
-void ChatScene::customEvent(QEvent *event) {
-  switch(event->type()) {
-  default:
-    return;
+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);
 }
 
 void ChatScene::loadWebPreview(ChatItem *parentItem, const QString &url, const QRectF &urlRect) {