From 3797af265a3a0131b71098f2684c1fde61cb76c7 Mon Sep 17 00:00:00 2001 From: Stephen Holdaway Date: Fri, 14 Jul 2017 23:38:59 +1200 Subject: [PATCH] Automatically load selected docsets without enter or click This fixes one of my main peeves working between Dash and Zeal. Dash automatically loads the selected docset in the tree when changing the selection with the keyboard. Up until now, Zeal has required enter to be pressed to load a docset selected with the keyboard, which additionally moved focus away from the tree. That is, in Dash the workflow is: - search something - use up/down arrows to move to relevant looking item - [docset loads after a small delay] - use up/down arrows to move to a different item - ... While in Zeal this has been: - search something - use up/down arrows to move to an item - press enter to load selected item - [focus moves to web view, keyboard can no longer change selection] - use mouse to pick a different item or to focus tree again - ... This commit implements behaviour similar to Dash. Notably: - Focus is no longer lost when a docset is loaded unless it is actively selected with enter or a click. This is mostly to maintain the existing behaviour for these actions. Personally I feel clicking an item should leave focus in the tree for further keyboard selection. - The timeout for searching now serves as a general purpose delayed docset load timeout. This limits the typing and selection delays to the same value, but the 400ms currently used seems to work well in both cases. - An "active" load (click/enter) overrides any delayed load (keyboard selection) --- src/libs/ui/mainwindow.cpp | 47 ++++++++++++++++++++++++++++++-------- src/libs/ui/mainwindow.h | 3 +++ 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/libs/ui/mainwindow.cpp b/src/libs/ui/mainwindow.cpp index 1166579d3..9a821ae7a 100644 --- a/src/libs/ui/mainwindow.cpp +++ b/src/libs/ui/mainwindow.cpp @@ -328,9 +328,12 @@ MainWindow::MainWindow(Core::Application *app, QWidget *parent) : createTab(); - connect(ui->treeView, &QTreeView::clicked, this, &MainWindow::openDocset); + // Focus web view on any active interaction with tree (enter, clicking) + connect(ui->treeView, &QTreeView::clicked, this, &MainWindow::openAndFocusDocset); + connect(ui->treeView, &QTreeView::activated, this, &MainWindow::openAndFocusDocset); + + // Handle selections in the table of contents list connect(ui->tocListView, &QListView::clicked, this, &MainWindow::openDocset); - connect(ui->treeView, &QTreeView::activated, this, &MainWindow::openDocset); connect(ui->tocListView, &QListView::activated, this, &MainWindow::openDocset); connect(m_application->docsetRegistry(), &Registry::DocsetRegistry::searchCompleted, @@ -386,9 +389,6 @@ MainWindow::MainWindow(Core::Application *app, QWidget *parent) : return; openDocset(index); - - // Get focus back. - ui->lineEdit->setFocus(Qt::MouseFocusReason); }); ui->actionNewTab->setShortcut(QKeySequence::AddTab); @@ -463,13 +463,31 @@ void MainWindow::search(const Registry::SearchQuery &query) emit ui->treeView->activated(ui->treeView->currentIndex()); } +// Open the docset at index immediately void MainWindow::openDocset(const QModelIndex &index) { + // Cancel any other pending docset open + m_openDocsetTimer->stop(); + const QVariant url = index.data(Registry::ItemDataRole::UrlRole); if (url.isNull()) return; currentTab()->load(url.toUrl()); +} + +// Open the docset at index after a delay (for typing, keyboard selection, etc) +void MainWindow::openDocsetDelayed(const QModelIndex &index) +{ + m_openDocsetTimer->stop(); + m_openDocsetTimer->setProperty("index", index); + m_openDocsetTimer->start(); +} + +// Open the docset at index and move focus to the web view +void MainWindow::openAndFocusDocset(const QModelIndex &index) +{ + openDocset(index); currentTab()->focus(); } @@ -493,8 +511,7 @@ void MainWindow::queryCompleted() ui->treeView->setCurrentIndex(currentTabState()->searchModel->index(0, 0, QModelIndex())); - m_openDocsetTimer->setProperty("index", ui->treeView->currentIndex()); - m_openDocsetTimer->start(); + openDocsetDelayed(ui->treeView->currentIndex()); } void MainWindow::closeTab(int index) @@ -580,8 +597,20 @@ void MainWindow::syncTreeView() // TODO: Remove once QTBUG-49966 is addressed. QItemSelectionModel *newSelectionModel = ui->treeView->selectionModel(); - if (oldSelectionModel && newSelectionModel != oldSelectionModel) { - oldSelectionModel->deleteLater(); + if (newSelectionModel != oldSelectionModel) { + if (oldSelectionModel) { + oldSelectionModel->deleteLater(); + } + + // Connect to new selection model + connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, + this, [this](const QItemSelection &selected) { + if (selected.isEmpty()) { + return; + } + + openDocsetDelayed(selected.indexes().first()); + }); } ui->treeView->reset(); diff --git a/src/libs/ui/mainwindow.h b/src/libs/ui/mainwindow.h index dc9a85969..6b79ed0d8 100644 --- a/src/libs/ui/mainwindow.h +++ b/src/libs/ui/mainwindow.h @@ -28,6 +28,7 @@ class QxtGlobalShortcut; +class QItemSelection; class QModelIndex; class QSystemTrayIcon; class QTabBar; @@ -79,6 +80,8 @@ public slots: private slots: void applySettings(); void openDocset(const QModelIndex &index); + void openAndFocusDocset(const QModelIndex &index); + void openDocsetDelayed(const QModelIndex &index); void queryCompleted(); void closeTab(int index = -1); void moveTab(int from, int to);