warning--
[quassel.git] / src / qtui / chatscene.cpp
index 2f145e9..f111781 100644 (file)
@@ -92,13 +92,14 @@ ChatScene::ChatScene(QAbstractItemModel *model, const QString &idString, qreal w
 
   setHandleXLimits();
 
+  if(model->rowCount() > 0)
+    rowsInserted(QModelIndex(), 0, model->rowCount() - 1);
+
   connect(model, SIGNAL(rowsInserted(const QModelIndex &, int, int)),
           this, SLOT(rowsInserted(const QModelIndex &, int, int)));
   connect(model, SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)),
           this, SLOT(rowsAboutToBeRemoved(const QModelIndex &, int, int)));
-
-  if(model->rowCount() > 0)
-    rowsInserted(QModelIndex(), 0, model->rowCount() - 1);
+  connect(model, SIGNAL(dataChanged(QModelIndex, QModelIndex)), SLOT(dataChanged(QModelIndex, QModelIndex)));
 
 #ifdef HAVE_WEBKIT
   webPreview.timer.setSingleShot(true);
@@ -169,7 +170,6 @@ void ChatScene::rowsInserted(const QModelIndex &index, int start, int end) {
   qreal width = _sceneRect.width();
   bool atBottom = (start == _lines.count());
   bool atTop = !atBottom && (start == 0);
-  bool moveTop = false;
 
   if(start < _lines.count()) {
     y = _lines.value(start)->y();
@@ -229,25 +229,11 @@ 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)) {
-    // 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) {
-      // move top part
-      moveTop = true;
-      offset = -offset;
-      moveEnd = end;
-    } else {
-      // move bottom part
-      moveStart = end + 1;
-    }
     ChatLine *line = 0;
-    for(int i = moveStart; i <= moveEnd; i++) {
+    for(int i = 0; i <= end; i++) {
       line = _lines.at(i);
-      line->setPos(0, line->pos().y() + offset);
+      line->setPos(0, line->pos().y() - h);
     }
   }
 
@@ -284,7 +270,7 @@ void ChatScene::rowsInserted(const QModelIndex &index, int start, int end) {
     _firstLineRow = -1;
   }
   updateSceneRect();
-  if(atBottom || (!atTop && !moveTop)) {
+  if(atBottom) {
     emit lastLineChanged(_lines.last(), h);
   }
 }
@@ -380,6 +366,10 @@ void ChatScene::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int e
   updateSceneRect();
 }
 
+void ChatScene::dataChanged(const QModelIndex &tl, const QModelIndex &br) {
+  layout(tl.row(), br.row(), _sceneRect.width());
+}
+
 void ChatScene::updateForViewport(qreal width, qreal height) {
   _viewportHeight = height;
   setWidth(width);
@@ -388,21 +378,37 @@ void ChatScene::updateForViewport(qreal width, qreal height) {
 void ChatScene::setWidth(qreal width) {
   if(width == _sceneRect.width())
     return;
+  layout(0, _lines.count()-1, width);
+}
 
+void ChatScene::layout(int start, int end, qreal width) {
   // clock_t startT = clock();
 
   // disabling the index while doing this complex updates is about
   // 2 to 10 times faster!
   //setItemIndexMethod(QGraphicsScene::NoIndex);
 
-  QList<ChatLine *>::iterator lineIter = _lines.end();
-  QList<ChatLine *>::iterator lineIterBegin = _lines.begin();
-  qreal linePos = _sceneRect.y() + _sceneRect.height();
-  qreal contentsWidth = width - secondColumnHandle()->sceneRight();
-  while(lineIter != lineIterBegin) {
-    lineIter--;
-    (*lineIter)->setGeometryByWidth(width, contentsWidth, linePos);
+  if(end >= 0) {
+    int row = end;
+    qreal linePos = _lines.at(row)->scenePos().y() + _lines.at(row)->height();
+    qreal contentsWidth = width - secondColumnHandle()->sceneRight();
+    while(row >= start) {
+      _lines.at(row--)->setGeometryByWidth(width, contentsWidth, linePos);
+    }
+
+    if(row >= 0) {
+      // remaining items don't need geometry changes, but maybe repositioning?
+      ChatLine *line = _lines.at(row);
+      qreal offset = linePos - (line->scenePos().y() + line->height());
+      if(offset != 0) {
+        while(row >= 0) {
+          line = _lines.at(row--);
+          line->setPos(0, line->scenePos().y() + offset);
+        }
+      }
+    }
   }
+
   //setItemIndexMethod(QGraphicsScene::BspTreeIndex);
 
   updateSceneRect(width);
@@ -417,7 +423,7 @@ void ChatScene::firstHandlePositionChanged(qreal xpos) {
   if(_firstColHandlePos == xpos)
     return;
 
-  _firstColHandlePos = xpos;
+  _firstColHandlePos = xpos >= 0 ? xpos : 0;
   ChatViewSettings viewSettings(this);
   viewSettings.setValue("FirstColumnHandlePos", _firstColHandlePos);
   ChatViewSettings defaultSettings;
@@ -861,7 +867,7 @@ bool ChatScene::event(QEvent *e) {
 //  Webkit Only stuff
 // ========================================
 #ifdef HAVE_WEBKIT
-void ChatScene::loadWebPreview(ChatItem *parentItem, const QString &url, const QRectF &urlRect) {
+void ChatScene::loadWebPreview(ChatItem *parentItem, const QUrl &url, const QRectF &urlRect) {
   if(!_showWebPreview)
     return;
 
@@ -946,7 +952,7 @@ void ChatScene::webPreviewNextStep() {
       webPreview.previewItem = 0;
     }
     webPreview.parentItem = 0;
-    webPreview.url = QString();
+    webPreview.url = QUrl();
     webPreview.urlRect = QRectF();
     webPreview.previewState = WebPreview::NoPreview;
   }