diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp --- a/src/kitemviews/kitemlistview.cpp +++ b/src/kitemviews/kitemlistview.cpp @@ -1548,16 +1548,16 @@ { disconnectRoleEditingSignals(index); - emit roleEditingCanceled(index, role, value); m_editingRole = false; + emit roleEditingCanceled(index, role, value); } void KItemListView::slotRoleEditingFinished(int index, const QByteArray& role, const QVariant& value) { disconnectRoleEditingSignals(index); - emit roleEditingFinished(index, role, value); m_editingRole = false; + emit roleEditingFinished(index, role, value); } void KItemListView::setController(KItemListController* controller) diff --git a/src/kitemviews/kstandarditemlistwidget.cpp b/src/kitemviews/kstandarditemlistwidget.cpp --- a/src/kitemviews/kstandarditemlistwidget.cpp +++ b/src/kitemviews/kstandarditemlistwidget.cpp @@ -776,6 +776,7 @@ m_roleEditor = new KItemListRoleEditor(parent); m_roleEditor->setRole(current); + m_roleEditor->setLayout(layout()); m_roleEditor->setFont(styleOption().font); const QString text = data().value(current).toString(); diff --git a/src/kitemviews/private/kitemlistroleeditor.h b/src/kitemviews/private/kitemlistroleeditor.h --- a/src/kitemviews/private/kitemlistroleeditor.h +++ b/src/kitemviews/private/kitemlistroleeditor.h @@ -23,13 +23,21 @@ #include "dolphin_export.h" #include +#include + +struct EditResult +{ + QString newName; + int editNextIdxChange; +}; +Q_DECLARE_METATYPE(EditResult) /** * @brief Editor for renaming roles of a KItemListWidget. * * Provides signals when the editing got cancelled (e.g. by * pressing Escape or when losing the focus) or when the editing - * got finished (e.g. by pressing Enter or Return). + * got finished (e.g. by pressing Enter, Tab or Return). * * The size automatically gets increased if the text does not fit. */ @@ -42,6 +50,7 @@ ~KItemListRoleEditor() override; void setRole(const QByteArray& role); + void setLayout(const KStandardItemListWidget::Layout); QByteArray role() const; bool eventFilter(QObject* watched, QEvent* event) override; @@ -66,11 +75,12 @@ * Emits the signal roleEditingFinished if m_blockFinishedSignal * is false. */ - void emitRoleEditingFinished(); + void emitRoleEditingFinished(int editNextIdxChange = 0); private: QByteArray m_role; bool m_blockFinishedSignal; + KStandardItemListWidget::Layout m_layout; }; #endif diff --git a/src/kitemviews/private/kitemlistroleeditor.cpp b/src/kitemviews/private/kitemlistroleeditor.cpp --- a/src/kitemviews/private/kitemlistroleeditor.cpp +++ b/src/kitemviews/private/kitemlistroleeditor.cpp @@ -20,6 +20,7 @@ #include "kitemlistroleeditor.h" #include +#include KItemListRoleEditor::KItemListRoleEditor(QWidget *parent) : KTextEdit(parent), @@ -48,6 +49,11 @@ m_role = role; } +void KItemListRoleEditor::setLayout(const KStandardItemListWidget::Layout layout) +{ + m_layout = layout; +} + QByteArray KItemListRoleEditor::role() const { return m_role; @@ -91,6 +97,10 @@ emitRoleEditingFinished(); event->accept(); return; + case Qt::Key_Tab: + emitRoleEditingFinished(1); + event->accept(); + return; case Qt::Key_Left: case Qt::Key_Right: { QTextCursor cursor = textCursor(); @@ -107,6 +117,19 @@ } break; } + case Qt::Key_Up: + case Qt::Key_Down: + if (m_layout == KStandardItemListWidget::CompactLayout || + m_layout == KStandardItemListWidget::DetailsLayout) { + if (event->key() == Qt::Key_Down) { + emitRoleEditingFinished(1); + } else { + emitRoleEditingFinished(-1); + } + event->accept(); + return; + } + break; default: break; } @@ -139,10 +162,13 @@ } } -void KItemListRoleEditor::emitRoleEditingFinished() +void KItemListRoleEditor::emitRoleEditingFinished(int editNextIdxChange) { + QVariant ret; + ret.setValue(EditResult {KIO::encodeFileName(toPlainText()), editNextIdxChange}); + if (!m_blockFinishedSignal) { - emit roleEditingFinished(m_role, KIO::encodeFileName(toPlainText())); + emit roleEditingFinished(m_role, ret); } } diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp --- a/src/views/dolphinview.cpp +++ b/src/views/dolphinview.cpp @@ -68,6 +68,7 @@ #include #include #include +#include DolphinView::DolphinView(const QUrl& url, QWidget* parent) : QWidget(parent), @@ -1566,13 +1567,15 @@ disconnect(m_view, &DolphinItemListView::roleEditingFinished, this, &DolphinView::slotRoleEditingFinished); - if (index < 0 || index >= m_model->count()) { + const KFileItemList items = selectedItems(); + if (items.count() != 1) { return; } if (role == "text") { - const KFileItem oldItem = m_model->fileItem(index); - const QString newName = value.toString(); + const KFileItem oldItem = items.first(); + const EditResult retVal = value.value(); + const QString newName = retVal.newName; if (!newName.isEmpty() && newName != oldItem.text() && newName != QLatin1Char('.') && newName != QLatin1String("..")) { const QUrl oldUrl = oldItem.url(); @@ -1603,14 +1606,14 @@ #endif const bool newNameExistsAlready = (m_model->index(newUrl) >= 0); - if (!newNameExistsAlready) { + if (!newNameExistsAlready && m_model->index(oldUrl) == index) { // Only change the data in the model if no item with the new name // is in the model yet. If there is an item with the new name // already, calling KIO::CopyJob will open a dialog // asking for a new name, and KFileItemModel will update the // data when the dir lister signals that the file name has changed. QHash data; - data.insert(role, value); + data.insert(role, retVal.newName); m_model->setData(index, data); } @@ -1627,6 +1630,13 @@ connect(job, &KJob::result, this, &DolphinView::slotRenamingResult); } } + + if (retVal.editNextIdxChange) { + m_container->controller()->selectionManager()->setSelected(index, 1, KItemListSelectionManager::Deselect); + m_container->controller()->selectionManager()->setSelected(index + retVal.editNextIdxChange, 1, + KItemListSelectionManager::Select); + renameSelectedItems(); + } } }