+void KItemListController::updateKeyboardAnchor()
+{
+ const bool validAnchor = m_keyboardAnchorIndex >= 0 &&
+ m_keyboardAnchorIndex < m_model->count() &&
+ keyboardAnchorPos(m_keyboardAnchorIndex) == m_keyboardAnchorXPos;
+ if (!validAnchor) {
+ const int index = m_selectionManager->currentItem();
+ m_keyboardAnchorIndex = index;
+ m_keyboardAnchorXPos = keyboardAnchorPos(index);
+ }
+}
+
+int KItemListController::nextRowIndex() const
+{
+ const int currentIndex = m_selectionManager->currentItem();
+ if (m_keyboardAnchorIndex < 0) {
+ return currentIndex;
+ }
+
+ const int maxIndex = m_model->count() - 1;
+ if (currentIndex == maxIndex) {
+ return currentIndex;
+ }
+
+ // Calculate the index of the last column inside the row of the current index
+ int lastColumnIndex = currentIndex;
+ while (keyboardAnchorPos(lastColumnIndex + 1) > keyboardAnchorPos(lastColumnIndex)) {
+ ++lastColumnIndex;
+ if (lastColumnIndex >= maxIndex) {
+ return currentIndex;
+ }
+ }
+
+ // Based on the last column index go to the next row and calculate the nearest index
+ // that is below the current index
+ int nextRowIndex = lastColumnIndex + 1;
+ int searchIndex = nextRowIndex;
+ qreal minDiff = qAbs(m_keyboardAnchorXPos - keyboardAnchorPos(nextRowIndex));
+ while (searchIndex < maxIndex && keyboardAnchorPos(searchIndex + 1) > keyboardAnchorPos(searchIndex)) {
+ ++searchIndex;
+ const qreal searchDiff = qAbs(m_keyboardAnchorXPos - keyboardAnchorPos(searchIndex));
+ if (searchDiff < minDiff) {
+ minDiff = searchDiff;
+ nextRowIndex = searchIndex;
+ }
+ }
+
+ return nextRowIndex;
+}
+
+int KItemListController::previousRowIndex() const
+{
+ const int currentIndex = m_selectionManager->currentItem();
+ if (m_keyboardAnchorIndex < 0 || currentIndex == 0) {
+ return currentIndex;
+ }
+
+ // Calculate the index of the first column inside the row of the current index
+ int firstColumnIndex = currentIndex;
+ while (keyboardAnchorPos(firstColumnIndex - 1) < keyboardAnchorPos(firstColumnIndex)) {
+ --firstColumnIndex;
+ if (firstColumnIndex <= 0) {
+ return currentIndex;
+ }
+ }
+
+ // Based on the first column index go to the previous row and calculate the nearest index
+ // that is above the current index
+ int previousRowIndex = firstColumnIndex - 1;
+ int searchIndex = previousRowIndex;
+ qreal minDiff = qAbs(m_keyboardAnchorXPos - keyboardAnchorPos(previousRowIndex));
+ while (searchIndex > 0 && keyboardAnchorPos(searchIndex - 1) < keyboardAnchorPos(searchIndex)) {
+ --searchIndex;
+ const qreal searchDiff = qAbs(m_keyboardAnchorXPos - keyboardAnchorPos(searchIndex));
+ if (searchDiff < minDiff) {
+ minDiff = searchDiff;
+ previousRowIndex = searchIndex;
+ }
+ }
+
+ return previousRowIndex;
+}
+
+qreal KItemListController::keyboardAnchorPos(int index) const
+{
+ const QRectF itemRect = m_view->itemRect(index);
+ if (!itemRect.isEmpty()) {
+ return (m_view->scrollOrientation() == Qt::Vertical) ? itemRect.x() : itemRect.y();
+ }
+
+ return 0;
+}
+