mirror of
https://invent.kde.org/system/dolphin
synced 2024-09-19 16:31:21 +00:00
Fix keyboard issues when groups are enabled
When groups are enabled in Dolphin the key-up and key-down keys did not behave consistent in comparison to traditional views or like done in editors. CCBUG: 261995 CCBUG: 262038
This commit is contained in:
parent
4dc5714016
commit
118fe89449
|
@ -50,7 +50,9 @@ KItemListController::KItemListController(QObject* parent) :
|
|||
m_pressedIndex(-1),
|
||||
m_pressedMousePos(),
|
||||
m_autoActivationTimer(0),
|
||||
m_oldSelection()
|
||||
m_oldSelection(),
|
||||
m_keyboardAnchorIndex(-1),
|
||||
m_keyboardAnchorXPos(0)
|
||||
{
|
||||
connect(m_keyboardManager, SIGNAL(changeCurrentItem(QString,bool)),
|
||||
this, SLOT(slotChangeCurrentItem(QString,bool)));
|
||||
|
@ -175,7 +177,6 @@ bool KItemListController::keyPressEvent(QKeyEvent* event)
|
|||
const bool shiftOrControlPressed = shiftPressed || controlPressed;
|
||||
|
||||
const int itemCount = m_model->count();
|
||||
const int itemsPerRow = m_view->itemsPerOffset();
|
||||
|
||||
// For horizontal scroll orientation, transform
|
||||
// the arrow keys to simplify the event handling.
|
||||
|
@ -210,37 +211,28 @@ bool KItemListController::keyPressEvent(QKeyEvent* event)
|
|||
|
||||
case Qt::Key_Left:
|
||||
if (index > 0) {
|
||||
index--;
|
||||
--index;
|
||||
m_keyboardAnchorIndex = index;
|
||||
m_keyboardAnchorXPos = keyboardAnchorPos(index);
|
||||
}
|
||||
break;
|
||||
|
||||
case Qt::Key_Right:
|
||||
if (index < itemCount - 1) {
|
||||
index++;
|
||||
++index;
|
||||
m_keyboardAnchorIndex = index;
|
||||
m_keyboardAnchorXPos = keyboardAnchorPos(index);
|
||||
}
|
||||
break;
|
||||
|
||||
case Qt::Key_Up:
|
||||
if (index >= itemsPerRow) {
|
||||
index -= itemsPerRow;
|
||||
}
|
||||
updateKeyboardAnchor();
|
||||
index = previousRowIndex();
|
||||
break;
|
||||
|
||||
case Qt::Key_Down:
|
||||
if (index + itemsPerRow < itemCount) {
|
||||
// We are not in the last row yet.
|
||||
index += itemsPerRow;
|
||||
} else {
|
||||
// We are either in the last row already, or we are in the second-last row,
|
||||
// and there is no item below the current item.
|
||||
// In the latter case, we jump to the very last item.
|
||||
const int currentColumn = index % itemsPerRow;
|
||||
const int lastItemColumn = (itemCount - 1) % itemsPerRow;
|
||||
const bool inLastRow = currentColumn < lastItemColumn;
|
||||
if (!inLastRow) {
|
||||
index = itemCount - 1;
|
||||
}
|
||||
}
|
||||
updateKeyboardAnchor();
|
||||
index = nextRowIndex();
|
||||
break;
|
||||
|
||||
case Qt::Key_Enter:
|
||||
|
@ -955,4 +947,97 @@ KItemListWidget* KItemListController::widgetForPos(const QPointF& pos) const
|
|||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#include "kitemlistcontroller.moc"
|
||||
|
|
|
@ -220,6 +220,34 @@ private:
|
|||
*/
|
||||
KItemListWidget* widgetForPos(const QPointF& pos) const;
|
||||
|
||||
/**
|
||||
* Updates m_keyboardAnchorIndex and m_keyboardAnchorPos. If no anchor is
|
||||
* set, it will be adjusted to the current item. If it is set it will be
|
||||
* checked whether it is still valid, otherwise it will be reset to the
|
||||
* current item.
|
||||
*/
|
||||
void updateKeyboardAnchor();
|
||||
|
||||
/**
|
||||
* @return Index for the next row based on the current index.
|
||||
* If there is no next row the current index will be returned.
|
||||
*/
|
||||
int nextRowIndex() const;
|
||||
|
||||
/**
|
||||
* @return Index for the previous row based on the current index.
|
||||
* If there is no previous row the current index will be returned.
|
||||
*/
|
||||
int previousRowIndex() const;
|
||||
|
||||
/**
|
||||
* Helper method for updateKeyboardAnchor(), previousRowIndex() and nextRowIndex().
|
||||
* @return The position of the keyboard anchor for the item with the index \a index.
|
||||
* If a horizontal scrolling is used the y-position of the item will be returned,
|
||||
* for the vertical scrolling the x-position will be returned.
|
||||
*/
|
||||
qreal keyboardAnchorPos(int index) const;
|
||||
|
||||
private:
|
||||
bool m_selectionTogglePressed;
|
||||
SelectionBehavior m_selectionBehavior;
|
||||
|
@ -235,10 +263,27 @@ private:
|
|||
/**
|
||||
* When starting a rubberband selection during a Shift- or Control-key has been
|
||||
* pressed the current selection should never be deleted. To be able to restore
|
||||
* the current selection it is remembered in m_oldSelection before
|
||||
* the current selection it is remembered in m_oldSelection before the
|
||||
* rubberband gets activated.
|
||||
*/
|
||||
QSet<int> m_oldSelection;
|
||||
|
||||
/**
|
||||
* Assuming a view is given with a vertical scroll-orientation, grouped items and
|
||||
* a maximum of 4 columns:
|
||||
*
|
||||
* 1 2 3 4
|
||||
* 5 6 7
|
||||
* 8 9 10 11
|
||||
* 12 13 14
|
||||
*
|
||||
* If the current index is on 4 and key-down is pressed, then item 7 gets the current
|
||||
* item. Now when pressing key-down again item 11 should get the current item and not
|
||||
* item 10. This makes it necessary to keep track of the requested column to have a
|
||||
* similar behavior like in a text editor:
|
||||
*/
|
||||
int m_keyboardAnchorIndex;
|
||||
qreal m_keyboardAnchorXPos;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -485,11 +485,6 @@ void KItemListView::scrollToItem(int index)
|
|||
}
|
||||
}
|
||||
|
||||
int KItemListView::itemsPerOffset() const
|
||||
{
|
||||
return m_layouter->itemsPerOffset();
|
||||
}
|
||||
|
||||
void KItemListView::beginTransaction()
|
||||
{
|
||||
++m_activeTransactions;
|
||||
|
|
|
@ -202,15 +202,6 @@ public:
|
|||
*/
|
||||
void scrollToItem(int index);
|
||||
|
||||
/**
|
||||
* @return The number of items that can be shown in parallel for one offset.
|
||||
* Assuming the scrolldirection is vertical then a value of 4 means
|
||||
* that 4 columns for items are available. Assuming the scrolldirection
|
||||
* is horizontal then a value of 4 means that 4 lines for items are
|
||||
* available.
|
||||
*/
|
||||
int itemsPerOffset() const;
|
||||
|
||||
void beginTransaction();
|
||||
void endTransaction();
|
||||
bool isTransactionActive() const;
|
||||
|
|
|
@ -253,11 +253,6 @@ int KItemListViewLayouter::maximumVisibleItems() const
|
|||
return rows * m_columnCount;
|
||||
}
|
||||
|
||||
int KItemListViewLayouter::itemsPerOffset() const
|
||||
{
|
||||
return m_columnCount;
|
||||
}
|
||||
|
||||
bool KItemListViewLayouter::isFirstGroupItem(int itemIndex) const
|
||||
{
|
||||
const_cast<KItemListViewLayouter*>(this)->doLayout();
|
||||
|
|
|
@ -107,13 +107,6 @@ public:
|
|||
*/
|
||||
int maximumVisibleItems() const;
|
||||
|
||||
/**
|
||||
* @return Maximum number of items that can be shown in the same row
|
||||
* (= vertical scrolldirection) or same column
|
||||
* (= horizontal scrolldirection).
|
||||
*/
|
||||
int itemsPerOffset() const;
|
||||
|
||||
/**
|
||||
* @return True if the item with the index \p itemIndex
|
||||
* is the first item within a group.
|
||||
|
|
Loading…
Reference in a new issue