From db053653c1bee06e581633a5a038ae596ce00049 Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Sat, 15 Aug 2015 10:58:43 +0200 Subject: [PATCH] GUI: chapters: make return focus the next appropriate chapter element Which element will be selected and focused depends on which is selected when the user presses return: * If an input other than the chapter's name is focused then the first chapter name will be selected, and the chapter name line edit will be focused. * If the chapter name line edit is focused then the next chapter name will be selected and focus. * If the last chapter name is selected then the next chapter entry in the tree will be selected, and that entry's start time will be focused. Implements #1358. --- ChangeLog | 9 +++ src/mkvtoolnix-gui/chapter_editor/tab.cpp | 86 +++++++++++++++++++++++ src/mkvtoolnix-gui/chapter_editor/tab.h | 7 +- src/mkvtoolnix-gui/util/util.cpp | 10 +++ src/mkvtoolnix-gui/util/util.h | 5 +- 5 files changed, 114 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index da744a4f6..59515ee3c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2015-08-15 Moritz Bunkus + + * MKVToolNix GUI: chapter editor enhancement: pressing return will + cause the next appropriate chapter control to be selected + depending on where the focus currently is: from a chapter input to + the first chapter name, from a chapter name to the next chapter + name and from the last chapter name to the next chapter entry's + start time. Implements #1358. + 2015-08-14 Moritz Bunkus * MKVToolNix GUI: new job queue feature: added a context menu for diff --git a/src/mkvtoolnix-gui/chapter_editor/tab.cpp b/src/mkvtoolnix-gui/chapter_editor/tab.cpp index dfb5044d9..e958ccbd0 100644 --- a/src/mkvtoolnix-gui/chapter_editor/tab.cpp +++ b/src/mkvtoolnix-gui/chapter_editor/tab.cpp @@ -112,6 +112,10 @@ Tab::setupUi() { connect(mw, &MainWindow::preferencesChanged, ui->cbChNameLanguage, &Util::ComboBoxBase::reInitialize); connect(mw, &MainWindow::preferencesChanged, ui->cbChNameCountry, &Util::ComboBoxBase::reInitialize); + + auto chapterLineEdits = QList{} << ui->leChStart << ui->leChEnd << ui->leChUid << ui->leChSegmentUid << ui->leChSegmentEditionUid << ui->leChName; + for (auto const &lineEdit : chapterLineEdits) + connect(lineEdit, &QLineEdit::returnPressed, this, &Tab::focusNextChapterElement); } void @@ -1391,4 +1395,86 @@ Tab::hasBeenModified() return currentState() != m_savedState; } +bool +Tab::focusNextChapterName() { + auto selectedRows = ui->tvChNames->selectionModel()->selectedRows(); + if (selectedRows.isEmpty()) + return false; + + auto nextRow = selectedRows.at(0).row() + 1; + if (nextRow >= m_nameModel->rowCount()) + return false; + + Util::selectRow(ui->tvChNames, nextRow); + + return true; +} + +bool +Tab::focusNextChapterAtom() { + auto doSelect = [this](QModelIndex const &idx) -> bool { + Util::selectRow(ui->elements, idx.row(), idx.parent()); + + ui->leChStart->selectAll(); + ui->leChStart->setFocus(); + + return true; + }; + + auto selectedRows = ui->elements->selectionModel()->selectedRows(); + if (selectedRows.isEmpty()) + return false; + + auto selectedIdx = selectedRows.at(0); + selectedIdx = selectedIdx.sibling(selectedIdx.row(), 0); + auto selectedItem = m_chapterModel->itemFromIndex(selectedIdx); + + if (selectedItem->rowCount()) + return doSelect(selectedIdx.child(0, 0)); + + auto parentIdx = selectedIdx.parent(); + auto parentItem = m_chapterModel->itemFromIndex(parentIdx); + auto nextRow = selectedIdx.row() + 1; + + if (nextRow < parentItem->rowCount()) + return doSelect(parentIdx.child(nextRow, 0)); + + while (parentIdx.parent().isValid()) { + nextRow = parentIdx.row() + 1; + parentIdx = parentIdx.parent(); + parentItem = m_chapterModel->itemFromIndex(parentIdx); + + if (nextRow < parentItem->rowCount()) + return doSelect(parentIdx.child(nextRow, 0)); + } + + auto editionIdx = parentIdx.sibling(parentIdx.row() + 1, 0); + + while (editionIdx.isValid()) { + if (m_chapterModel->itemFromIndex(editionIdx)->rowCount()) + return doSelect(editionIdx.child(0, 0)); + + editionIdx = editionIdx.sibling(editionIdx.row() + 1, 0); + } + + return false; +} + +void +Tab::focusNextChapterElement() { + if (!copyControlsToStorage()) + return; + + if (QObject::sender() != ui->leChName) { + ui->leChName->selectAll(); + ui->leChName->setFocus(); + return; + } + + if (focusNextChapterName()) + return; + + focusNextChapterAtom(); +} + }}} diff --git a/src/mkvtoolnix-gui/chapter_editor/tab.h b/src/mkvtoolnix-gui/chapter_editor/tab.h index 68f6ae01e..201233c99 100644 --- a/src/mkvtoolnix-gui/chapter_editor/tab.h +++ b/src/mkvtoolnix-gui/chapter_editor/tab.h @@ -100,6 +100,8 @@ public slots: virtual void showChapterContextMenu(QPoint const &pos); + virtual void focusNextChapterElement(); + protected: void setupUi(); void resetData(); @@ -150,9 +152,12 @@ protected: protected: QString currentState() const; ChaptersPtr timecodesToChapters(std::vector const &timecodes) const; - QString formatChapterName(QString const &nameTemplate, int chapterNumer) const; + QString formatChapterName(QString const &nameTemplate, int chapterNumber) const; void changeChapterName(QModelIndex const &parentIdx, int row, int chapterNumber, QString const &nameTemplate, RenumberSubChaptersParametersDialog::NameMatch nameMatchingMode, QString const &languageOfNamesToReplace); + bool focusNextChapterAtom(); + bool focusNextChapterName(); + static QString formatEbmlBinary(EbmlBinary *binary); }; diff --git a/src/mkvtoolnix-gui/util/util.cpp b/src/mkvtoolnix-gui/util/util.cpp index 33b17d4b6..633dabedc 100644 --- a/src/mkvtoolnix-gui/util/util.cpp +++ b/src/mkvtoolnix-gui/util/util.cpp @@ -182,6 +182,16 @@ selectedRowIdx(QAbstractItemView *view) { return selectedRowIdx(view->selectionModel()->selection()); } +void +selectRow(QAbstractItemView *view, + int row, + QModelIndex const &parentIdx) { + auto itemModel = view->model(); + auto selectionModel = view->selectionModel(); + auto selection = QItemSelection{itemModel->index(row, 0, parentIdx), itemModel->index(row, itemModel->columnCount() - 1, parentIdx)}; + selectionModel->select(selection, QItemSelectionModel::ClearAndSelect); +} + QModelIndex toTopLevelIdx(QModelIndex const &idx) { if (!idx.isValid()) diff --git a/src/mkvtoolnix-gui/util/util.h b/src/mkvtoolnix-gui/util/util.h index 2a8cf7098..7c95da222 100644 --- a/src/mkvtoolnix-gui/util/util.h +++ b/src/mkvtoolnix-gui/util/util.h @@ -5,6 +5,7 @@ #include #include +#include class QAbstractItemView; class QComboBox; @@ -12,7 +13,6 @@ class QDateTime; class QIcon; class QItemSelection; class QItemSelectionModel; -class QModelIndex; class QScrollArea; class QTabWidget; class QTableView; @@ -65,10 +65,11 @@ enum MtxGuiRoles { void resizeViewColumnsToContents(QTableView *view); void resizeViewColumnsToContents(QTreeView *view); int numSelectedRows(QItemSelection &selection); -QModelIndex SelectedRowIdx(QItemSelection const &selection); +QModelIndex selectedRowIdx(QItemSelection const &selection); QModelIndex selectedRowIdx(QAbstractItemView *view); void withSelectedIndexes(QItemSelectionModel *selectionModel, std::function worker); void withSelectedIndexes(QAbstractItemView *view, std::function worker); +void selectRow(QAbstractItemView *view, int row, QModelIndex const &parentIdx = QModelIndex{}); QModelIndex toTopLevelIdx(QModelIndex const &idx); // String stuff