Fix changing focus around the main window using tab

* Override Qt's default [broken] behavior of handling Tab/Shift+Tab to navigate around the MainWindow. Completely fixes trapped focus.

* Improve handling of search results when navigating the UI.

* Fix selecting first entry after ending a search.

* Add keyboard shortcuts to directly focus on search (F1), Group List (F2), and Entry List (F3)

* Fixes #2878, #4636, and #4221
This commit is contained in:
Jonathan White 2020-04-21 18:46:21 -04:00
parent 5142981018
commit 49487f9d4a
11 changed files with 129 additions and 66 deletions

View File

@ -193,8 +193,9 @@ DatabaseWidget::DatabaseWidget(QSharedPointer<Database> db, QWidget* parent)
connect(m_previewView, SIGNAL(errorOccurred(QString)), SLOT(showErrorMessage(QString))); connect(m_previewView, SIGNAL(errorOccurred(QString)), SLOT(showErrorMessage(QString)));
connect(m_previewView, SIGNAL(entryUrlActivated(Entry*)), SLOT(openUrlForEntry(Entry*))); connect(m_previewView, SIGNAL(entryUrlActivated(Entry*)), SLOT(openUrlForEntry(Entry*)));
connect(m_entryView, SIGNAL(viewStateChanged()), SIGNAL(entryViewStateChanged())); connect(m_entryView, SIGNAL(viewStateChanged()), SIGNAL(entryViewStateChanged()));
connect(m_groupView, SIGNAL(groupSelectionChanged(Group*)), SLOT(onGroupChanged(Group*))); connect(m_groupView, SIGNAL(groupSelectionChanged()), SLOT(onGroupChanged()));
connect(m_groupView, SIGNAL(groupSelectionChanged(Group*)), SIGNAL(groupChanged())); connect(m_groupView, SIGNAL(groupSelectionChanged()), SIGNAL(groupChanged()));
connect(m_groupView, &GroupView::groupFocused, this, [this] { m_previewView->setGroup(currentGroup()); });
connect(m_entryView, SIGNAL(entryActivated(Entry*,EntryModel::ModelColumn)), connect(m_entryView, SIGNAL(entryActivated(Entry*,EntryModel::ModelColumn)),
SLOT(entryActivationSignalReceived(Entry*,EntryModel::ModelColumn))); SLOT(entryActivationSignalReceived(Entry*,EntryModel::ModelColumn)));
connect(m_entryView, SIGNAL(entrySelectionChanged(Entry*)), SLOT(onEntryChanged(Entry*))); connect(m_entryView, SIGNAL(entrySelectionChanged(Entry*)), SLOT(onEntryChanged(Entry*)));
@ -283,6 +284,11 @@ bool DatabaseWidget::isSearchActive() const
return m_entryView->inSearchMode(); return m_entryView->inSearchMode();
} }
bool DatabaseWidget::isEntryViewActive() const
{
return currentWidget() == m_mainWidget;
}
bool DatabaseWidget::isEntryEditActive() const bool DatabaseWidget::isEntryEditActive() const
{ {
return currentWidget() == m_editEntryWidget; return currentWidget() == m_editEntryWidget;
@ -616,9 +622,27 @@ bool DatabaseWidget::confirmDeleteEntries(QList<Entry*> entries, bool permanent)
} }
} }
void DatabaseWidget::setFocus() void DatabaseWidget::setFocus(Qt::FocusReason reason)
{ {
m_entryView->setFocus(); if (reason == Qt::BacktabFocusReason) {
m_previewView->setFocus();
} else {
m_groupView->setFocus();
}
}
void DatabaseWidget::focusOnEntries()
{
if (isEntryViewActive()) {
m_entryView->setFocus();
}
}
void DatabaseWidget::focusOnGroups()
{
if (isEntryViewActive()) {
m_groupView->setFocus();
}
} }
void DatabaseWidget::copyTitle() void DatabaseWidget::copyTitle()
@ -925,6 +949,8 @@ int DatabaseWidget::addChildWidget(QWidget* w)
void DatabaseWidget::switchToMainView(bool previousDialogAccepted) void DatabaseWidget::switchToMainView(bool previousDialogAccepted)
{ {
setCurrentWidget(m_mainWidget);
if (m_newGroup) { if (m_newGroup) {
if (previousDialogAccepted) { if (previousDialogAccepted) {
m_newGroup->setParent(m_newParent); m_newGroup->setParent(m_newParent);
@ -950,12 +976,10 @@ void DatabaseWidget::switchToMainView(bool previousDialogAccepted)
m_entryView->setFocus(); m_entryView->setFocus();
} }
setCurrentWidget(m_mainWidget);
if (sender() == m_entryView || sender() == m_editEntryWidget) { if (sender() == m_entryView || sender() == m_editEntryWidget) {
onEntryChanged(m_entryView->currentEntry()); onEntryChanged(m_entryView->currentEntry());
} else if (sender() == m_groupView || sender() == m_editGroupWidget) { } else if (sender() == m_groupView || sender() == m_editGroupWidget) {
onGroupChanged(m_groupView->currentGroup()); onGroupChanged();
} }
} }
@ -1325,8 +1349,10 @@ void DatabaseWidget::setSearchLimitGroup(bool state)
refreshSearch(); refreshSearch();
} }
void DatabaseWidget::onGroupChanged(Group* group) void DatabaseWidget::onGroupChanged()
{ {
auto group = m_groupView->currentGroup();
// Intercept group changes if in search mode // Intercept group changes if in search mode
if (isSearchActive() && m_searchLimitGroup) { if (isSearchActive() && m_searchLimitGroup) {
search(m_lastSearchText); search(m_lastSearchText);
@ -1367,13 +1393,11 @@ QString DatabaseWidget::getCurrentSearch()
void DatabaseWidget::endSearch() void DatabaseWidget::endSearch()
{ {
if (isSearchActive()) { if (isSearchActive()) {
emit listModeAboutToActivate();
// Show the normal entry view of the current group // Show the normal entry view of the current group
emit listModeAboutToActivate();
m_entryView->displayGroup(currentGroup()); m_entryView->displayGroup(currentGroup());
onGroupChanged(currentGroup());
emit listModeActivated(); emit listModeActivated();
m_entryView->setFirstEntryActive();
} }
m_searchingLabel->setVisible(false); m_searchingLabel->setVisible(false);
@ -1434,6 +1458,31 @@ void DatabaseWidget::showEvent(QShowEvent* event)
event->accept(); event->accept();
} }
bool DatabaseWidget::focusNextPrevChild(bool next)
{
// [parent] <-> GroupView <-> EntryView <-> EntryPreview <-> [parent]
if (next) {
if (m_groupView->hasFocus()) {
m_entryView->setFocus();
return true;
} else if (m_entryView->hasFocus()) {
m_previewView->setFocus();
return true;
}
} else {
if (m_previewView->hasFocus()) {
m_entryView->setFocus();
return true;
} else if (m_entryView->hasFocus()) {
m_groupView->setFocus();
return true;
}
}
// Defer to the parent widget to make a decision
return QStackedWidget::focusNextPrevChild(next);
}
bool DatabaseWidget::lock() bool DatabaseWidget::lock()
{ {
if (isLocked()) { if (isLocked()) {

View File

@ -76,12 +76,15 @@ public:
explicit DatabaseWidget(const QString& filePath, QWidget* parent = nullptr); explicit DatabaseWidget(const QString& filePath, QWidget* parent = nullptr);
~DatabaseWidget(); ~DatabaseWidget();
void setFocus(Qt::FocusReason reason);
QSharedPointer<Database> database() const; QSharedPointer<Database> database() const;
DatabaseWidget::Mode currentMode() const; DatabaseWidget::Mode currentMode() const;
bool isLocked() const; bool isLocked() const;
bool isSaving() const; bool isSaving() const;
bool isSearchActive() const; bool isSearchActive() const;
bool isEntryViewActive() const;
bool isEntryEditActive() const; bool isEntryEditActive() const;
bool isGroupEditActive() const; bool isGroupEditActive() const;
@ -161,7 +164,8 @@ public slots:
void cloneEntry(); void cloneEntry();
void deleteSelectedEntries(); void deleteSelectedEntries();
void deleteEntries(QList<Entry*> entries); void deleteEntries(QList<Entry*> entries);
void setFocus(); void focusOnEntries();
void focusOnGroups();
void copyTitle(); void copyTitle();
void copyUsername(); void copyUsername();
void copyPassword(); void copyPassword();
@ -217,6 +221,7 @@ public slots:
protected: protected:
void closeEvent(QCloseEvent* event) override; void closeEvent(QCloseEvent* event) override;
void showEvent(QShowEvent* event) override; void showEvent(QShowEvent* event) override;
bool focusNextPrevChild(bool next) override;
private slots: private slots:
void entryActivationSignalReceived(Entry* entry, EntryModel::ModelColumn column); void entryActivationSignalReceived(Entry* entry, EntryModel::ModelColumn column);
@ -228,7 +233,7 @@ private slots:
void emitGroupContextMenuRequested(const QPoint& pos); void emitGroupContextMenuRequested(const QPoint& pos);
void emitEntryContextMenuRequested(const QPoint& pos); void emitEntryContextMenuRequested(const QPoint& pos);
void onEntryChanged(Entry* entry); void onEntryChanged(Entry* entry);
void onGroupChanged(Group* group); void onGroupChanged();
void onDatabaseModified(); void onDatabaseModified();
void connectDatabaseSignals(); void connectDatabaseSignals();
void loadDatabase(bool accepted); void loadDatabase(bool accepted);

View File

@ -82,6 +82,8 @@ EntryPreviewWidget::EntryPreviewWidget(QWidget* parent)
connect(m_ui->groupCloseButton, SIGNAL(clicked()), SLOT(hide())); connect(m_ui->groupCloseButton, SIGNAL(clicked()), SLOT(hide()));
connect(m_ui->groupTabWidget, SIGNAL(tabBarClicked(int)), SLOT(updateTabIndexes()), Qt::QueuedConnection); connect(m_ui->groupTabWidget, SIGNAL(tabBarClicked(int)), SLOT(updateTabIndexes()), Qt::QueuedConnection);
setFocusProxy(m_ui->entryTabWidget);
#if !defined(WITH_XC_KEESHARE) #if !defined(WITH_XC_KEESHARE)
removeTab(m_ui->groupTabWidget, m_ui->groupShareTab); removeTab(m_ui->groupTabWidget, m_ui->groupShareTab);
#endif #endif

View File

@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>566</width> <width>566</width>
<height>169</height> <height>206</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_7"> <layout class="QVBoxLayout" name="verticalLayout_7">
@ -106,9 +106,6 @@
</item> </item>
<item> <item>
<widget class="QToolButton" name="entryTotpButton"> <widget class="QToolButton" name="entryTotpButton">
<property name="focusPolicy">
<enum>Qt::TabFocus</enum>
</property>
<property name="toolTip"> <property name="toolTip">
<string>Display current TOTP value</string> <string>Display current TOTP value</string>
</property> </property>
@ -122,9 +119,6 @@
</item> </item>
<item> <item>
<widget class="QToolButton" name="entryCloseButton"> <widget class="QToolButton" name="entryCloseButton">
<property name="focusPolicy">
<enum>Qt::TabFocus</enum>
</property>
<property name="toolTip"> <property name="toolTip">
<string>Close</string> <string>Close</string>
</property> </property>
@ -137,9 +131,6 @@
</item> </item>
<item> <item>
<widget class="QTabWidget" name="entryTabWidget"> <widget class="QTabWidget" name="entryTabWidget">
<property name="focusPolicy">
<enum>Qt::ClickFocus</enum>
</property>
<property name="currentIndex"> <property name="currentIndex">
<number>0</number> <number>0</number>
</property> </property>
@ -1147,12 +1138,13 @@
</customwidgets> </customwidgets>
<tabstops> <tabstops>
<tabstop>entryCloseButton</tabstop> <tabstop>entryCloseButton</tabstop>
<tabstop>entryTotpButton</tabstop> <tabstop>entryTabWidget</tabstop>
<tabstop>togglePasswordButton</tabstop> <tabstop>togglePasswordButton</tabstop>
<tabstop>toggleEntryNotesButton</tabstop> <tabstop>toggleEntryNotesButton</tabstop>
<tabstop>entryAutotypeTree</tabstop>
<tabstop>groupCloseButton</tabstop> <tabstop>groupCloseButton</tabstop>
<tabstop>groupTabWidget</tabstop> <tabstop>groupTabWidget</tabstop>
<tabstop>toggleGroupNotesButton</tabstop>
<tabstop>entryTotpButton</tabstop>
</tabstops> </tabstops>
<resources/> <resources/>
<connections/> <connections/>

View File

@ -308,6 +308,14 @@ MainWindow::MainWindow()
shortcut = new QShortcut(dbTabModifier + Qt::Key_9, this); shortcut = new QShortcut(dbTabModifier + Qt::Key_9, this);
connect(shortcut, &QShortcut::activated, [this]() { selectDatabaseTab(m_ui->tabWidget->count() - 1); }); connect(shortcut, &QShortcut::activated, [this]() { selectDatabaseTab(m_ui->tabWidget->count() - 1); });
// Allow for direct focus of search, group view, and entry view
shortcut = new QShortcut(Qt::Key_F1, this);
connect(shortcut, SIGNAL(activated()), m_searchWidget, SLOT(searchFocus()));
shortcut = new QShortcut(Qt::Key_F2, this);
m_actionMultiplexer.connect(shortcut, SIGNAL(activated()), SLOT(focusOnGroups()));
shortcut = new QShortcut(Qt::Key_F3, this);
m_actionMultiplexer.connect(shortcut, SIGNAL(activated()), SLOT(focusOnEntries()));
// Toggle password and username visibility in entry view // Toggle password and username visibility in entry view
new QShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_C, this, SLOT(togglePasswordsHidden())); new QShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_C, this, SLOT(togglePasswordsHidden()));
new QShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_B, this, SLOT(toggleUsernamesHidden())); new QShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_B, this, SLOT(toggleUsernamesHidden()));
@ -1104,6 +1112,36 @@ void MainWindow::changeEvent(QEvent* event)
} }
} }
bool MainWindow::focusNextPrevChild(bool next)
{
// Only navigate around the main window if the database widget is showing the entry view
auto dbWidget = m_ui->tabWidget->currentDatabaseWidget();
if (dbWidget && dbWidget->isVisible() && dbWidget->isEntryViewActive()) {
// Search Widget <-> Tab Widget <-> DbWidget
if (next) {
if (m_searchWidget->hasFocus()) {
m_ui->tabWidget->setFocus(Qt::TabFocusReason);
} else if (m_ui->tabWidget->hasFocus()) {
dbWidget->setFocus(Qt::TabFocusReason);
} else {
m_searchWidget->setFocus(Qt::TabFocusReason);
}
} else {
if (m_searchWidget->hasFocus()) {
dbWidget->setFocus(Qt::BacktabFocusReason);
} else if (m_ui->tabWidget->hasFocus()) {
m_searchWidget->setFocus(Qt::BacktabFocusReason);
} else {
m_ui->tabWidget->setFocus(Qt::BacktabFocusReason);
}
}
return true;
}
// Defer to Qt to make a decision, this maintains normal behavior
return QMainWindow::focusNextPrevChild(next);
}
void MainWindow::saveWindowInformation() void MainWindow::saveWindowInformation()
{ {
if (isVisible()) { if (isVisible()) {

View File

@ -85,6 +85,7 @@ public slots:
protected: protected:
void closeEvent(QCloseEvent* event) override; void closeEvent(QCloseEvent* event) override;
void changeEvent(QEvent* event) override; void changeEvent(QEvent* event) override;
bool focusNextPrevChild(bool next) override;
private slots: private slots:
void setMenuActionState(DatabaseWidget::Mode mode = DatabaseWidget::Mode::None); void setMenuActionState(DatabaseWidget::Mode mode = DatabaseWidget::Mode::None);

View File

@ -79,9 +79,6 @@
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="focusPolicy">
<enum>Qt::TabFocus</enum>
</property>
<property name="currentIndex"> <property name="currentIndex">
<number>2</number> <number>2</number>
</property> </property>
@ -129,11 +126,7 @@
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
<widget class="ApplicationSettingsWidget" name="settingsWidget" native="true"> <widget class="ApplicationSettingsWidget" name="settingsWidget" native="true"/>
<property name="focusPolicy">
<enum>Qt::TabFocus</enum>
</property>
</widget>
</item> </item>
</layout> </layout>
</widget> </widget>
@ -158,11 +151,7 @@
</spacer> </spacer>
</item> </item>
<item> <item>
<widget class="WelcomeWidget" name="welcomeWidget" native="true"> <widget class="WelcomeWidget" name="welcomeWidget" native="true"/>
<property name="focusPolicy">
<enum>Qt::TabFocus</enum>
</property>
</widget>
</item> </item>
<item> <item>
<spacer name="horizontalSpacer_2"> <spacer name="horizontalSpacer_2">
@ -209,11 +198,7 @@
</spacer> </spacer>
</item> </item>
<item> <item>
<widget class="PasswordGeneratorWidget" name="passwordGeneratorWidget" native="true"> <widget class="PasswordGeneratorWidget" name="passwordGeneratorWidget" native="true"/>
<property name="focusPolicy">
<enum>Qt::TabFocus</enum>
</property>
</widget>
</item> </item>
<item> <item>
<spacer name="verticalSpacer"> <spacer name="verticalSpacer">
@ -240,12 +225,9 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>800</width> <width>800</width>
<height>24</height> <height>22</height>
</rect> </rect>
</property> </property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="contextMenuPolicy"> <property name="contextMenuPolicy">
<enum>Qt::PreventContextMenu</enum> <enum>Qt::PreventContextMenu</enum>
</property> </property>
@ -383,9 +365,6 @@
<addaction name="menuHelp"/> <addaction name="menuHelp"/>
</widget> </widget>
<widget class="QToolBar" name="toolBar"> <widget class="QToolBar" name="toolBar">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="contextMenuPolicy"> <property name="contextMenuPolicy">
<enum>Qt::PreventContextMenu</enum> <enum>Qt::PreventContextMenu</enum>
</property> </property>

View File

@ -137,10 +137,11 @@ void SearchWidget::connectSignals(SignalMultiplexer& mx)
mx.connect(this, SIGNAL(caseSensitiveChanged(bool)), SLOT(setSearchCaseSensitive(bool))); mx.connect(this, SIGNAL(caseSensitiveChanged(bool)), SLOT(setSearchCaseSensitive(bool)));
mx.connect(this, SIGNAL(limitGroupChanged(bool)), SLOT(setSearchLimitGroup(bool))); mx.connect(this, SIGNAL(limitGroupChanged(bool)), SLOT(setSearchLimitGroup(bool)));
mx.connect(this, SIGNAL(copyPressed()), SLOT(copyPassword())); mx.connect(this, SIGNAL(copyPressed()), SLOT(copyPassword()));
mx.connect(this, SIGNAL(downPressed()), SLOT(setFocus())); mx.connect(this, SIGNAL(downPressed()), SLOT(focusOnEntries()));
mx.connect(SIGNAL(clearSearch()), m_ui->searchEdit, SLOT(clear())); mx.connect(SIGNAL(clearSearch()), m_ui->searchEdit, SLOT(clear()));
mx.connect(SIGNAL(entrySelectionChanged()), this, SLOT(resetSearchClearTimer())); mx.connect(SIGNAL(entrySelectionChanged()), this, SLOT(resetSearchClearTimer()));
mx.connect(SIGNAL(currentModeChanged(DatabaseWidget::Mode)), this, SLOT(resetSearchClearTimer())); mx.connect(SIGNAL(currentModeChanged(DatabaseWidget::Mode)), this, SLOT(resetSearchClearTimer()));
mx.connect(SIGNAL(databaseUnlocked()), this, SLOT(searchFocus()));
mx.connect(m_ui->searchEdit, SIGNAL(returnPressed()), SLOT(switchToEntryEdit())); mx.connect(m_ui->searchEdit, SIGNAL(returnPressed()), SLOT(switchToEntryEdit()));
} }
@ -149,8 +150,6 @@ void SearchWidget::databaseChanged(DatabaseWidget* dbWidget)
if (dbWidget != nullptr) { if (dbWidget != nullptr) {
// Set current search text from this database // Set current search text from this database
m_ui->searchEdit->setText(dbWidget->getCurrentSearch()); m_ui->searchEdit->setText(dbWidget->getCurrentSearch());
// Keyboard focus on search widget at database unlocking
connect(dbWidget, SIGNAL(databaseUnlocked()), this, SLOT(searchFocus()));
// Enforce search policy // Enforce search policy
emit caseSensitiveChanged(m_actionCaseSensitive->isChecked()); emit caseSensitiveChanged(m_actionCaseSensitive->isChecked());
emit limitGroupChanged(m_actionLimitGroup->isChecked()); emit limitGroupChanged(m_actionLimitGroup->isChecked());

View File

@ -38,9 +38,10 @@ GroupView::GroupView(Database* db, QWidget* parent)
// clang-format off // clang-format off
connect(this, SIGNAL(expanded(QModelIndex)), SLOT(expandedChanged(QModelIndex))); connect(this, SIGNAL(expanded(QModelIndex)), SLOT(expandedChanged(QModelIndex)));
connect(this, SIGNAL(collapsed(QModelIndex)), SLOT(expandedChanged(QModelIndex))); connect(this, SIGNAL(collapsed(QModelIndex)), SLOT(expandedChanged(QModelIndex)));
connect(this, SIGNAL(clicked(QModelIndex)), SIGNAL(groupSelectionChanged()));
connect(m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), SLOT(syncExpandedState(QModelIndex,int,int))); connect(m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), SLOT(syncExpandedState(QModelIndex,int,int)));
connect(m_model, SIGNAL(modelReset()), SLOT(modelReset())); connect(m_model, SIGNAL(modelReset()), SLOT(modelReset()));
connect(selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), SLOT(emitGroupChanged())); connect(selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), SIGNAL(groupSelectionChanged()));
// clang-format on // clang-format on
new QShortcut(Qt::CTRL + Qt::Key_F10, this, SLOT(contextMenuShortcutPressed()), nullptr, Qt::WidgetShortcut); new QShortcut(Qt::CTRL + Qt::Key_F10, this, SLOT(contextMenuShortcutPressed()), nullptr, Qt::WidgetShortcut);
@ -85,7 +86,7 @@ void GroupView::dragMoveEvent(QDragMoveEvent* event)
void GroupView::focusInEvent(QFocusEvent* event) void GroupView::focusInEvent(QFocusEvent* event)
{ {
emitGroupChanged(); emit groupFocused();
QTreeView::focusInEvent(event); QTreeView::focusInEvent(event);
} }
@ -140,11 +141,6 @@ void GroupView::setModel(QAbstractItemModel* model)
Q_ASSERT(false); Q_ASSERT(false);
} }
void GroupView::emitGroupChanged()
{
emit groupSelectionChanged(currentGroup());
}
void GroupView::syncExpandedState(const QModelIndex& parent, int start, int end) void GroupView::syncExpandedState(const QModelIndex& parent, int start, int end)
{ {
for (int row = start; row <= end; row++) { for (int row = start; row <= end; row++) {

View File

@ -38,11 +38,11 @@ public:
void sortGroups(bool reverse = false); void sortGroups(bool reverse = false);
signals: signals:
void groupSelectionChanged(Group* group); void groupSelectionChanged();
void groupFocused();
private slots: private slots:
void expandedChanged(const QModelIndex& index); void expandedChanged(const QModelIndex& index);
void emitGroupChanged();
void syncExpandedState(const QModelIndex& parent, int start, int end); void syncExpandedState(const QModelIndex& parent, int start, int end);
void modelReset(); void modelReset();
void contextMenuShortcutPressed(); void contextMenuShortcutPressed();

View File

@ -901,8 +901,8 @@ void TestGui::testSearch()
QTest::keyClick(searchTextEdit, Qt::Key_Down); QTest::keyClick(searchTextEdit, Qt::Key_Down);
QTRY_VERIFY(entryView->hasFocus()); QTRY_VERIFY(entryView->hasFocus());
auto* searchedEntry = entryView->currentEntry(); auto* searchedEntry = entryView->currentEntry();
// Restore focus and search text selection // Restore focus using F1 key and search text selection
QTest::keyClick(m_mainWindow.data(), Qt::Key_F, Qt::ControlModifier); QTest::keyClick(m_mainWindow.data(), Qt::Key_F1);
QTRY_COMPARE(searchTextEdit->selectedText(), QString("someTHING")); QTRY_COMPARE(searchTextEdit->selectedText(), QString("someTHING"));
QTRY_VERIFY(searchTextEdit->hasFocus()); QTRY_VERIFY(searchTextEdit->hasFocus());
@ -965,12 +965,14 @@ void TestGui::testSearch()
searchWidget->setLimitGroup(false); searchWidget->setLimitGroup(false);
clickIndex(rootGroupIndex, groupView, Qt::LeftButton); clickIndex(rootGroupIndex, groupView, Qt::LeftButton);
QCOMPARE(groupView->currentGroup(), m_db->rootGroup()); QCOMPARE(groupView->currentGroup(), m_db->rootGroup());
QVERIFY(!m_dbWidget->isSearchActive());
// Try to edit the first entry from the search view // Try to edit the first entry from the search view
// Refocus back to search edit // Refocus back to search edit
QTest::mouseClick(searchTextEdit, Qt::LeftButton); QTest::mouseClick(searchTextEdit, Qt::LeftButton);
QTRY_VERIFY(searchTextEdit->hasFocus()); QTRY_VERIFY(searchTextEdit->hasFocus());
QVERIFY(m_dbWidget->isSearchActive()); QTest::keyClicks(searchTextEdit, "someTHING");
QTRY_VERIFY(m_dbWidget->isSearchActive());
QModelIndex item = entryView->model()->index(0, 1); QModelIndex item = entryView->model()->index(0, 1);
Entry* entry = entryView->entryFromIndex(item); Entry* entry = entryView->entryFromIndex(item);