+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:";
+ // if(start > 0) {
+ // QModelIndex ssidx = model()->index(start - 1, 2);
+ // qDebug() << "Start--:" << start - 1 << ssidx.data(MessageModel::MsgIdRole).value<MsgId>()
+ // << ssidx.data(Qt::DisplayRole).toString();
+ // }
+ // qDebug() << "Start:" << start << sidx.data(MessageModel::MsgIdRole).value<MsgId>()
+ // << sidx.data(Qt::DisplayRole).toString();
+ // qDebug() << "End:" << end << eidx.data(MessageModel::MsgIdRole).value<MsgId>()
+ // << eidx.data(Qt::DisplayRole).toString();
+ // if(end + 1 < model()->rowCount()) {
+ // QModelIndex eeidx = model()->index(end + 1, 2);
+ // qDebug() << "End++:" << end + 1 << eeidx.data(MessageModel::MsgIdRole).value<MsgId>()
+ // << eeidx.data(Qt::DisplayRole).toString();
+ // }
+
+ qreal h = 0;
+ qreal y = 0;
+ qreal width = _sceneRect.width();
+ bool atBottom = (start == _lines.count());
+ bool atTop = !atBottom && (start == 0);
+
+ if (start < _lines.count()) {
+ y = _lines.value(start)->y();
+ }
+ else if (atBottom && !_lines.isEmpty()) {
+ y = _lines.last()->y() + _lines.last()->height();
+ }
+
+ qreal contentsWidth = width - secondColumnHandle()->sceneRight();
+ qreal senderWidth = secondColumnHandle()->sceneLeft() - firstColumnHandle()->sceneRight();
+ qreal timestampWidth = firstColumnHandle()->sceneLeft();
+ QPointF contentsPos(secondColumnHandle()->sceneRight(), 0);
+ QPointF senderPos(firstColumnHandle()->sceneRight(), 0);
+
+ if (atTop) {
+ for (int i = end; i >= start; i--) {
+ auto* line = new ChatLine(i, model(), width, timestampWidth, senderWidth, contentsWidth, senderPos, contentsPos);
+ h += line->height();
+ line->setPos(0, y - h);
+ _lines.insert(start, line);
+ addItem(line);
+ }
+ }
+ else {
+ for (int i = start; i <= end; i++) {
+ auto* 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);
+ }
+ }
+
+ // update existing items
+ for (int i = end + 1; i < _lines.count(); i++) {
+ _lines[i]->setRow(i);
+ }
+
+ // update selection
+ if (_selectionStart >= 0) {
+ int offset = end - start + 1;
+ 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...
+ if (!(atTop || atBottom)) {
+ ChatLine* line = nullptr;
+ 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()));
+ }
+ }
+
+ // 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) {
+ int prevFirstLineRow = _firstLineRow + (end - start + 1);
+ for (int i = end + 1; i < prevFirstLineRow; i++) {
+ _lines.at(i)->show();
+ }
+ }
+ // force new search for first proper line
+ _firstLineRow = -1;
+ }
+ updateSceneRect();
+ if (atBottom) {
+ emit lastLineChanged(_lines.last(), h);
+ }
+
+ // now move the marker line if necessary. we don't need to do anything if we appended lines though...
+ if (!_markerLineValid)
+ setMarkerLine();