]> cloud.milkyroute.net Git - dolphin.git/commitdiff
When renaming files, move to next file using tab key or up/down
authorMéven Car <meven29@gmail.com>
Mon, 19 Apr 2021 05:10:11 +0000 (05:10 +0000)
committerMéven Car <meven29@gmail.com>
Mon, 19 Apr 2021 05:10:11 +0000 (05:10 +0000)
To rename previous file:
 Up or Shift-Tab

To rename next file:
 Down or Tab

Credit goes to msciubidlo

FEATURE: 403931
FEATURE: 269987
BUG: 334533
FIXED-IN: 21.08

src/kitemviews/kitemlistcontainer.cpp
src/kitemviews/kitemlistview.cpp
src/kitemviews/kitemlistview.h
src/kitemviews/kstandarditemlistwidget.cpp
src/kitemviews/private/kitemlistroleeditor.cpp
src/kitemviews/private/kitemlistroleeditor.h
src/kitemviews/private/kitemlistsmoothscroller.cpp
src/kitemviews/private/kitemlistsmoothscroller.h
src/views/dolphinview.cpp

index f253cda539dc03d2957516a07bedbbd6822c0323..10b9f1415c95f6064aa95daca68651287d948706 100644 (file)
@@ -208,6 +208,8 @@ void KItemListContainer::slotViewChanged(KItemListView* current, KItemListView*
         disconnect(previous, &KItemListView::maximumItemOffsetChanged,
                    this, &KItemListContainer::updateItemOffsetScrollBar);
         disconnect(previous, &KItemListView::scrollTo, this, &KItemListContainer::scrollTo);
+        disconnect(m_horizontalSmoothScroller, &KItemListSmoothScroller::scrollingStopped, previous, &KItemListView::scrollingStopped);
+        disconnect(m_verticalSmoothScroller, &KItemListSmoothScroller::scrollingStopped, previous, &KItemListView::scrollingStopped);
         m_horizontalSmoothScroller->setTargetObject(nullptr);
         m_verticalSmoothScroller->setTargetObject(nullptr);
     }
@@ -224,6 +226,9 @@ void KItemListContainer::slotViewChanged(KItemListView* current, KItemListView*
         connect(current, &KItemListView::maximumItemOffsetChanged,
                 this, &KItemListContainer::updateItemOffsetScrollBar);
         connect(current, &KItemListView::scrollTo, this, &KItemListContainer::scrollTo);
+        connect(m_horizontalSmoothScroller, &KItemListSmoothScroller::scrollingStopped, current, &KItemListView::scrollingStopped);
+        connect(m_verticalSmoothScroller, &KItemListSmoothScroller::scrollingStopped, current, &KItemListView::scrollingStopped);
+
         m_horizontalSmoothScroller->setTargetObject(current);
         m_verticalSmoothScroller->setTargetObject(current);
         updateSmoothScrollers(current->scrollOrientation());
index 14ac22ca97df53973ee24168c08b2cc41e910cb3..e4dd7bb2be0a462ae9bc82247097796497baa6f7 100644 (file)
@@ -526,8 +526,11 @@ void KItemListView::scrollToItem(int index)
 
         if (newOffset != scrollOffset()) {
             Q_EMIT scrollTo(newOffset);
+            return;
         }
     }
+
+    Q_EMIT scrollingStopped();
 }
 
 void KItemListView::beginTransaction()
@@ -1602,16 +1605,16 @@ void KItemListView::slotRoleEditingCanceled(int index, const QByteArray& role, c
 {
     disconnectRoleEditingSignals(index);
 
-    Q_EMIT roleEditingCanceled(index, role, value);
     m_editingRole = false;
+    Q_EMIT roleEditingCanceled(index, role, value);
 }
 
 void KItemListView::slotRoleEditingFinished(int index, const QByteArray& role, const QVariant& value)
 {
     disconnectRoleEditingSignals(index);
 
-    Q_EMIT roleEditingFinished(index, role, value);
     m_editingRole = false;
+    Q_EMIT roleEditingFinished(index, role, value);
 }
 
 void KItemListView::setController(KItemListController* controller)
index a847943350b18a1804952706350f38ed25b0ec14..5453d851fd3996e0cbece99dbdb657a445d1c803 100644 (file)
@@ -307,6 +307,12 @@ Q_SIGNALS:
     void roleEditingCanceled(int index, const QByteArray& role, const QVariant& value);
     void roleEditingFinished(int index, const QByteArray& role, const QVariant& value);
 
+    /**
+     * Emitted once scrolling has finished, or immediately if no scrolling was necessary
+     * to get item in view in scrollToItem.
+     */
+    void scrollingStopped();
+
 protected:
     QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;
     void setItemSize(const QSizeF& size);
index 73744b385e3f7e5e00f25272cc276cd0ce56b07a..e58340fb891b581e1423084469fb63eca8990928 100644 (file)
@@ -764,6 +764,7 @@ void KStandardItemListWidget::editedRoleChanged(const QByteArray& current, const
 
     m_roleEditor = new KItemListRoleEditor(parent);
     m_roleEditor->setRole(current);
+    m_roleEditor->setAllowUpDownKeyChainEdit(m_layout != IconsLayout);
     m_roleEditor->setFont(styleOption().font);
 
     const QString text = data().value(current).toString();
index df142a4564dea91ab87c64903069f3c51d8a8309..cc10bd58ae58ea75ba6262724577db99c8441d03 100644 (file)
@@ -40,6 +40,11 @@ QByteArray KItemListRoleEditor::role() const
     return m_role;
 }
 
+void KItemListRoleEditor::setAllowUpDownKeyChainEdit(bool allowChainEdit)
+{
+    m_allowUpDownKeyChainEdit = allowChainEdit;
+}
+
 bool KItemListRoleEditor::eventFilter(QObject* watched, QEvent* event)
 {
     if (watched == parentWidget() && event->type() == QEvent::Resize) {
@@ -78,6 +83,20 @@ void KItemListRoleEditor::keyPressEvent(QKeyEvent* event)
         emitRoleEditingFinished();
         event->accept();
         return;
+    case Qt::Key_Tab:
+    case Qt::Key_Down:
+        if (m_allowUpDownKeyChainEdit || event->key() == Qt::Key_Tab) {
+            emitRoleEditingFinished(EditNext);
+            event->accept();
+            return;
+        }
+    case Qt::Key_Backtab:
+    case Qt::Key_Up:
+        if (m_allowUpDownKeyChainEdit || event->key() == Qt::Key_Backtab) {
+            emitRoleEditingFinished(EditPrevious);
+            event->accept();
+            return;
+        }
     case Qt::Key_Left:
     case Qt::Key_Right: {
         QTextCursor cursor = textCursor();
@@ -143,10 +162,13 @@ void KItemListRoleEditor::autoAdjustSize()
     }
 }
 
-void KItemListRoleEditor::emitRoleEditingFinished()
+void KItemListRoleEditor::emitRoleEditingFinished(EditResultDirection direction)
 {
+    QVariant ret;
+    ret.setValue(EditResult {KIO::encodeFileName(toPlainText()), direction});
+
     if (!m_blockFinishedSignal) {
-        Q_EMIT roleEditingFinished(m_role, KIO::encodeFileName(toPlainText()));
+        Q_EMIT roleEditingFinished(m_role, ret);
     }
 }
 
index 070cf5ce95062026417f9b0e9f35cf7246310943..a0f55df51f89e871f2da5556c8e5f2dc94080c10 100644 (file)
 
 #include <KTextEdit>
 
+enum EditResultDirection{
+    EditDone,
+    EditNext,
+    EditPrevious,
+};
+Q_DECLARE_METATYPE(EditResultDirection)
+
+struct EditResult
+{
+    QString newName;
+    EditResultDirection direction;
+};
+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.
  */
@@ -31,6 +45,7 @@ public:
     void setRole(const QByteArray& role);
     QByteArray role() const;
 
+    void setAllowUpDownKeyChainEdit(bool allowChainEdit);
     bool eventFilter(QObject* watched, QEvent* event) override;
 
 Q_SIGNALS:
@@ -53,11 +68,12 @@ private:
      * Emits the signal roleEditingFinished if m_blockFinishedSignal
      * is false.
      */
-    void emitRoleEditingFinished();
+    void emitRoleEditingFinished(EditResultDirection direction = EditDone);
 
 private:
     QByteArray m_role;
     bool m_blockFinishedSignal;
+    bool m_allowUpDownKeyChainEdit;
 };
 
 #endif
index 1465361ed38846bd0f54498a6e87d620c10ddb20..f77d3df58d73e2a327ed17a93c4b1e48f051a797 100644 (file)
@@ -175,6 +175,9 @@ void KItemListSmoothScroller::slotAnimationStateChanged(QAbstractAnimation::Stat
     if (newState == QAbstractAnimation::Stopped && m_smoothScrolling && !m_scrollBarPressed) {
         m_smoothScrolling = false;
     }
+    if (newState == QAbstractAnimation::Stopped) {
+        Q_EMIT scrollingStopped();
+    }
 }
 
 void KItemListSmoothScroller::handleWheelEvent(QWheelEvent* event)
index 55548219ed803c41b8ba67e67b302a0c26acf19a..7b2839884f8ee1ea8b76b1efba8d2d7aa9894c9e 100644 (file)
@@ -69,6 +69,11 @@ public:
      */
     void handleWheelEvent(QWheelEvent* event);
 
+Q_SIGNALS:
+    /**
+     * Emitted when the scrolling animation has finished
+     */
+    void scrollingStopped();
 protected:
     bool eventFilter(QObject* obj, QEvent* event) override;
 
index f0f67c9d0b91210091b5a22ca6661d6230c0116f..987066419528eed6e5cd59c5d49c120ef5b76ec9 100644 (file)
@@ -18,6 +18,7 @@
 #include "kitemviews/kitemlistcontroller.h"
 #include "kitemviews/kitemlistheader.h"
 #include "kitemviews/kitemlistselectionmanager.h"
+#include "kitemviews/private/kitemlistroleeditor.h"
 #include "versioncontrol/versioncontrolobserver.h"
 #include "viewproperties.h"
 #include "views/tooltips/tooltipmanager.h"
@@ -674,12 +675,21 @@ void DolphinView::renameSelectedItems()
 
     if (items.count() == 1 && GeneralSettings::renameInline()) {
         const int index = m_model->index(items.first());
-        m_view->editRole(index, "text");
 
-        hideToolTip();
+        QMetaObject::Connection * const connection = new QMetaObject::Connection;
+        *connection = connect(m_view, &KItemListView::scrollingStopped, this, [=](){
+            QObject::disconnect(*connection);
+            delete connection;
+
+            m_view->editRole(index, "text");
+
+            hideToolTip();
+
+            connect(m_view, &DolphinItemListView::roleEditingFinished,
+                    this, &DolphinView::slotRoleEditingFinished);
+        });
+        m_view->scrollToItem(index);
 
-        connect(m_view, &DolphinItemListView::roleEditingFinished,
-                this, &DolphinView::slotRoleEditingFinished);
     } else {
         KIO::RenameFileDialog* dialog = new KIO::RenameFileDialog(items, this);
         connect(dialog, &KIO::RenameFileDialog::renamingFinished,
@@ -1736,13 +1746,15 @@ void DolphinView::slotRoleEditingFinished(int index, const QByteArray& role, con
     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<EditResult>();
+        const QString newName = retVal.newName;
         if (!newName.isEmpty() && newName != oldItem.text() && newName != QLatin1Char('.') && newName != QLatin1String("..")) {
             const QUrl oldUrl = oldItem.url();
 
@@ -1773,14 +1785,14 @@ void DolphinView::slotRoleEditingFinished(int index, const QByteArray& role, con
 #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<QByteArray, QVariant> data;
-                data.insert(role, value);
+                data.insert(role, retVal.newName);
                 m_model->setData(index, data);
             }
 
@@ -1797,6 +1809,13 @@ void DolphinView::slotRoleEditingFinished(int index, const QByteArray& role, con
                 connect(job, &KJob::result, this, &DolphinView::slotRenamingResult);
             }
         }
+        if (retVal.direction != EditDone) {
+            const short indexShift = retVal.direction == EditNext ? 1 : -1;
+            m_container->controller()->selectionManager()->setSelected(index, 1, KItemListSelectionManager::Deselect);
+            m_container->controller()->selectionManager()->setSelected(index + indexShift, 1,
+                    KItemListSelectionManager::Select);
+            renameSelectedItems();
+        }
     }
 }