-
- Q_ASSERT(parent);
-
- QScrollBar *scrollBar = parent->horizontalScrollBar();
- if (scrollBar == NULL)
- {
- qDebug() << "Warning: no scrollbar present, but told to scroll.";
- scrollTimer.stop();
- return;
- }
-
- int currentScroll = scrollBar->value();
-
- int difference = currentScroll - scrollTowards;
-
- if (qAbs(difference) < scrollPixels)
- {
- scrollBar->setValue(scrollTowards);
- scrollTimer.stop();
- return;
- }
-
- if (difference < 0)
- {
- scrollBar->setValue(currentScroll + scrollPixels);
- }
- else
- {
- scrollBar->setValue(currentScroll - scrollPixels);
- }
+ QModelIndex index;
+
+ const int viewportHeight = parent->viewport()->height();
+
+ // check whether there is a selected index which is partly visible
+ const QModelIndexList selectedIndexes = parent->selectionModel()->selectedIndexes();
+ if (selectedIndexes.count() == 1) {
+ QModelIndex selectedIndex = selectedIndexes.first();
+ const QRect rect = parent->visualRect(selectedIndex);
+ if ((rect.bottom() >= 0) && (rect.top() <= viewportHeight)) {
+ // the selected index is (at least partly) visible, use it as
+ // scroll target
+ index = selectedIndex;
+ }
+ }
+
+ if (!index.isValid()) {
+ // no partly selected index is visible, determine the most left visual index
+ QModelIndex visibleIndex = parent->indexAt(QPoint(0, 0));
+ if (!visibleIndex.isValid()) {
+ return;
+ }
+
+ index = visibleIndex;
+ int minimum = parent->width();
+ do {
+ const QRect rect = parent->visualRect(visibleIndex);
+ if (rect.top() > viewportHeight) {
+ // the current index and all successors are not visible anymore
+ break;
+ }
+ if (rect.left() < minimum) {
+ minimum = rect.left();
+ index = visibleIndex;
+ }
+ visibleIndex = parent->indexBelow(visibleIndex);
+ } while (visibleIndex.isValid());
+ }
+
+ // start the horizontal scrolling to assure that the item indicated by 'index' gets fully visible
+ Q_ASSERT(index.isValid());
+ const QRect rect = parent->visualRect(index);
+
+ QScrollBar *scrollBar = parent->horizontalScrollBar();
+ const int oldScrollBarPos = scrollBar->value();
+
+ const int itemRight = oldScrollBarPos + rect.left() + rect.width() - 1;
+ const int availableWidth = parent->viewport()->width();
+ int scrollBarPos = itemRight - availableWidth;
+ const int scrollBarPosMax = oldScrollBarPos + rect.left() - parent->indentation();
+ if (scrollBarPos > scrollBarPosMax) {
+ scrollBarPos = scrollBarPosMax;
+ }
+
+ if (scrollBarPos != oldScrollBarPos) {
+ timeLine->setFrameRange(oldScrollBarPos, scrollBarPos);
+ timeLine->start();
+ }