Skip to content

Commit

Permalink
Automatically load selected docsets without enter or click
Browse files Browse the repository at this point in the history
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)
  • Loading branch information
stecman committed Jan 17, 2018
1 parent 44e0289 commit 5cd78d1
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 7 deletions.
47 changes: 40 additions & 7 deletions src/libs/ui/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -307,9 +307,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,
Expand Down Expand Up @@ -365,9 +368,6 @@ MainWindow::MainWindow(Core::Application *app, QWidget *parent) :
return;

openDocset(index);

// Get focus back.
ui->lineEdit->setFocus(Qt::MouseFocusReason);
});

ui->actionNewTab->setShortcut(QKeySequence::AddTab);
Expand Down Expand Up @@ -442,13 +442,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();
}

Expand All @@ -472,8 +490,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)
Expand Down Expand Up @@ -544,6 +561,13 @@ void MainWindow::duplicateTab(int index)

void MainWindow::syncTreeView()
{
// Disconnect the previous selection model before it changes (caused by setModel)
auto oldSelectionModel = ui->treeView->selectionModel();
if (oldSelectionModel) {
disconnect(oldSelectionModel, &QItemSelectionModel::selectionChanged,
this, &MainWindow::docsetSelectionChanged);
}

TabState *tabState = currentTabState();

if (!tabState->searchQuery.isEmpty()) {
Expand All @@ -556,6 +580,10 @@ void MainWindow::syncTreeView()
}

ui->treeView->reset();

// Connect to new selection model
connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &MainWindow::docsetSelectionChanged);
}

void MainWindow::syncToc()
Expand All @@ -569,6 +597,11 @@ void MainWindow::syncToc()

}

void MainWindow::docsetSelectionChanged(const QItemSelection &selected)
{
openDocsetDelayed(selected.indexes().first());
}

TabState *MainWindow::currentTabState() const
{
return m_tabStates.at(m_tabBar->currentIndex());
Expand Down
4 changes: 4 additions & 0 deletions src/libs/ui/mainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

class QxtGlobalShortcut;

class QItemSelection;
class QModelIndex;
class QSystemTrayIcon;
class QTabBar;
Expand Down Expand Up @@ -79,10 +80,13 @@ 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);
void duplicateTab(int index);
void docsetSelectionChanged(const QItemSelection &selected);

private:
void syncTreeView();
Expand Down

0 comments on commit 5cd78d1

Please sign in to comment.