Search result highlights are now properly repositioned on resize
[quassel.git] / src / qtui / chatscene.cpp
index 0a53dfe..87dfae5 100644 (file)
@@ -108,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();
@@ -162,17 +158,24 @@ void ChatScene::rowsInserted(const QModelIndex &index, int start, int end) {
   // update selection
   if(_selectionStart >= 0) {
     int offset = end - start + 1;
-    if(_selectionStart >= start) _selectionStart += offset;
-    if(_selectionEnd >= start) _selectionEnd += offset;
-    if(_firstSelectionRow >= start) _firstSelectionRow += offset;
-    if(_lastSelectionRow >= start) _lastSelectionRow += offset;
+    int oldStart = _selectionStart;
+    if(_selectionStart >= start)
+      _selectionStart += offset;
+    if(_selectionEnd >= start) {
+      _selectionEnd += offset;
+      if(_selectionStart == oldStart)
+        for(int i = start; i < start + offset; i++)
+          _lines[i]->setSelected(true);
+    }
+    if(_firstSelectionRow >= start)
+      _firstSelectionRow += offset;
   }
 
   // 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) {
@@ -193,7 +196,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) {
@@ -220,6 +241,13 @@ void ChatScene::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int e
   bool atBottom = (end == _lines.count() - 1);
   bool moveTop = false;
 
+  // clear selection
+  if(_selectingItem) {
+    int row = _selectingItem->row();
+    if(row >= start && row <= end)
+      setSelectingItem(0);
+  }
+
   // remove items from scene
   QList<ChatLine *>::iterator lineIter = _lines.begin() + start;
   int lineCount = start;
@@ -239,13 +267,16 @@ void ChatScene::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int e
   if(_selectionStart >= 0) {
     int offset = end - start + 1;
     if(_selectionStart >= start)
-      _selectionStart -= offset;
+      _selectionStart = qMax(_selectionStart -= offset, start);
     if(_selectionEnd >= start)
       _selectionEnd -= offset;
     if(_firstSelectionRow >= start)
       _firstSelectionRow -= offset;
-    if(_lastSelectionRow >= start)
-      _lastSelectionRow -= offset;
+
+    if(_selectionEnd < _selectionStart) {
+      _isSelecting = false;
+      _selectionStart = -1;
+    }
   }
 
   // neither removing at bottom or top means we have to move items...
@@ -319,6 +350,7 @@ void ChatScene::setWidth(qreal width) {
 
   updateSceneRect(width);
   setHandleXLimits();
+  emit layoutChanged();
 
 //   clock_t endT = clock();
 //   qDebug() << "resized" << _lines.count() << "in" << (float)(endT - startT) / CLOCKS_PER_SEC << "sec";
@@ -386,7 +418,9 @@ void ChatScene::secondHandlePositionChanged(qreal xpos) {
   }
   //setItemIndexMethod(QGraphicsScene::BspTreeIndex);
 
+  updateSceneRect();
   setHandleXLimits();
+  emit layoutChanged();
 
 //   clock_t endT = clock();
 //   qDebug() << "resized" << _lines.count() << "in" << (float)(endT - startT) / CLOCKS_PER_SEC << "sec";
@@ -403,7 +437,7 @@ void ChatScene::setSelectingItem(ChatItem *item) {
 }
 
 void ChatScene::startGlobalSelection(ChatItem *item, const QPointF &itemPos) {
-  _selectionStart = _selectionEnd = _lastSelectionRow = _firstSelectionRow = item->row();
+  _selectionStart = _selectionEnd = _firstSelectionRow = item->row();
   _selectionStartCol = _selectionMinCol = item->column();
   _isSelecting = true;
   _lines[_selectionStart]->setSelected(true, (ChatLineModel::ColumnType)_selectionMinCol);
@@ -450,11 +484,10 @@ void ChatScene::updateSelection(const QPointF &pos) {
 
   _selectionStart = newstart;
   _selectionEnd = newend;
-  _lastSelectionRow = curRow;
 
   if(newstart == newend && minColumn == ChatLineModel::ContentsColumn) {
     if(!_selectingItem) {
-      qWarning() << "WARNING: ChatScene::updateSelection() has a null _selectingItem, this should never happen! Please report.";
+      // _selectingItem has been removed already
       return;
     }
     _lines[curRow]->setSelected(false);
@@ -473,10 +506,11 @@ void ChatScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
 }
 
 void ChatScene::mousePressEvent(QGraphicsSceneMouseEvent *event) {
-  if(event->buttons() == Qt::LeftButton && _selectionStart >= 0) {
+  if(_selectionStart >= 0 && event->buttons() == Qt::LeftButton) {
     for(int l = qMin(_selectionStart, _selectionEnd); l <= qMax(_selectionStart, _selectionEnd); l++) {
       _lines[l]->setSelected(false);
     }
+    _isSelecting = false;
     _selectionStart = -1;
     QGraphicsScene::mousePressEvent(event);  // so we can start a new local selection
   } else {