Enhanced search ui keypress actions

* Pressing down arrow will always focus on entry view
* Pressing enter opens currently selected entry
* Pressing CTRL+F focuses and selects search text
* Rewrote test cases to cover the new functionality
This commit is contained in:
Jonathan White 2017-01-04 20:46:52 -05:00
parent 9dadafe20a
commit 36df21d823
No known key found for this signature in database
GPG Key ID: 440FC65F2E0C6E01
3 changed files with 32 additions and 24 deletions

View File

@ -34,12 +34,11 @@ SearchWidget::SearchWidget(QWidget *parent)
m_searchTimer->setSingleShot(true); m_searchTimer->setSingleShot(true);
connect(m_ui->searchEdit, SIGNAL(textChanged(QString)), SLOT(startSearchTimer())); connect(m_ui->searchEdit, SIGNAL(textChanged(QString)), SLOT(startSearchTimer()));
connect(m_ui->searchEdit, SIGNAL(returnPressed()), SLOT(startSearch()));
connect(m_ui->searchIcon, SIGNAL(triggered(QAction*)), m_ui->searchEdit, SLOT(setFocus())); connect(m_ui->searchIcon, SIGNAL(triggered(QAction*)), m_ui->searchEdit, SLOT(setFocus()));
connect(m_searchTimer, SIGNAL(timeout()), this, SLOT(startSearch())); connect(m_searchTimer, SIGNAL(timeout()), this, SLOT(startSearch()));
connect(this, SIGNAL(escapePressed()), m_ui->searchEdit, SLOT(clear())); connect(this, SIGNAL(escapePressed()), m_ui->searchEdit, SLOT(clear()));
new QShortcut(Qt::CTRL + Qt::Key_F, m_ui->searchEdit, SLOT(setFocus()), nullptr, Qt::ApplicationShortcut); new QShortcut(Qt::CTRL + Qt::Key_F, this, SLOT(searchFocus()), nullptr, Qt::ApplicationShortcut);
m_ui->searchEdit->installEventFilter(this); m_ui->searchEdit->installEventFilter(this);
@ -76,16 +75,11 @@ bool SearchWidget::eventFilter(QObject *obj, QEvent *event)
} }
} }
else if (keyEvent->matches(QKeySequence::MoveToNextLine)) { else if (keyEvent->matches(QKeySequence::MoveToNextLine)) {
// If Down is pressed at EOL in the search edit, move // If Down is pressed move the focus to the entry view.
// the focus to the entry view.
QLineEdit* searchEdit = m_ui->searchEdit;
if (!searchEdit->hasSelectedText() &&
searchEdit->cursorPosition() == searchEdit->text().length()) {
emit downPressed(); emit downPressed();
return true; return true;
} }
} }
}
return QObject::eventFilter(obj, event); return QObject::eventFilter(obj, event);
} }
@ -96,6 +90,7 @@ 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(copyPressed()), SLOT(copyPassword())); mx.connect(this, SIGNAL(copyPressed()), SLOT(copyPassword()));
mx.connect(this, SIGNAL(downPressed()), SLOT(setFocus())); mx.connect(this, SIGNAL(downPressed()), SLOT(setFocus()));
mx.connect(m_ui->searchEdit, SIGNAL(returnPressed()), SLOT(switchToEntryEdit()));
} }
void SearchWidget::databaseChanged(DatabaseWidget *dbWidget) void SearchWidget::databaseChanged(DatabaseWidget *dbWidget)
@ -138,3 +133,9 @@ void SearchWidget::setCaseSensitive(bool state)
m_actionCaseSensitive->setChecked(state); m_actionCaseSensitive->setChecked(state);
updateCaseSensitive(); updateCaseSensitive();
} }
void SearchWidget::searchFocus()
{
m_ui->searchEdit->setFocus();
m_ui->searchEdit->selectAll();
}

View File

@ -48,6 +48,7 @@ signals:
void escapePressed(); void escapePressed();
void copyPressed(); void copyPressed();
void downPressed(); void downPressed();
void enterPressed();
public slots: public slots:
void databaseChanged(DatabaseWidget* dbWidget); void databaseChanged(DatabaseWidget* dbWidget);
@ -56,6 +57,7 @@ private slots:
void startSearchTimer(); void startSearchTimer();
void startSearch(); void startSearch();
void updateCaseSensitive(); void updateCaseSensitive();
void searchFocus();
private: private:
const QScopedPointer<Ui::SearchWidget> m_ui; const QScopedPointer<Ui::SearchWidget> m_ui;

View File

@ -413,19 +413,26 @@ void TestGui::testSearch()
// Search for "someTHING" // Search for "someTHING"
QTest::keyClicks(searchTextEdit, "THING"); QTest::keyClicks(searchTextEdit, "THING");
QTRY_COMPARE(entryView->model()->rowCount(), 2); QTRY_COMPARE(entryView->model()->rowCount(), 2);
// Press Down to focus on the entry view if at EOL // Press Down to focus on the entry view
QTest::keyClick(searchTextEdit, Qt::Key_Right, Qt::ControlModifier); QTest::keyClick(searchTextEdit, Qt::Key_Right, Qt::ControlModifier);
QTRY_VERIFY(searchTextEdit->hasFocus()); QTRY_VERIFY(searchTextEdit->hasFocus());
QTest::keyClick(searchTextEdit, Qt::Key_Down); QTest::keyClick(searchTextEdit, Qt::Key_Down);
QTRY_VERIFY(entryView->hasFocus()); QTRY_VERIFY(entryView->hasFocus());
// Test clipboard // Restore focus and search text selection
QTest::keyClick(m_mainWindow, Qt::Key_F, Qt::ControlModifier);
QTRY_COMPARE(searchTextEdit->selectedText(), QString("someTHING"));
// Ensure Down focuses on entry view when search text is selected
QTest::keyClick(searchTextEdit, Qt::Key_Down);
QTRY_VERIFY(entryView->hasFocus());
// Refocus back to search edit
QTest::mouseClick(searchTextEdit, Qt::LeftButton);
QTRY_VERIFY(searchTextEdit->hasFocus());
// Test password copy
QClipboard *clipboard = QApplication::clipboard(); QClipboard *clipboard = QApplication::clipboard();
QTest::keyClick(entryView, Qt::Key_C, Qt::ControlModifier); QTest::keyClick(searchTextEdit, Qt::Key_C, Qt::ControlModifier);
QModelIndex searchedItem = entryView->model()->index(0, 1); QModelIndex searchedItem = entryView->model()->index(0, 1);
Entry* searchedEntry = entryView->entryFromIndex(searchedItem); Entry* searchedEntry = entryView->entryFromIndex(searchedItem);
QTRY_COMPARE(searchedEntry->password(), clipboard->text()); QTRY_COMPARE(searchedEntry->password(), clipboard->text());
// Restore focus
QTest::mouseClick(searchTextEdit, Qt::LeftButton);
// Test case sensitive search // Test case sensitive search
searchWidget->setCaseSensitive(true); searchWidget->setCaseSensitive(true);
@ -445,16 +452,14 @@ void TestGui::testSearch()
QCOMPARE(groupView->currentGroup(), m_db->rootGroup()); QCOMPARE(groupView->currentGroup(), m_db->rootGroup());
// 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
QTest::mouseClick(searchTextEdit, Qt::LeftButton);
QTRY_VERIFY(searchTextEdit->hasFocus());
QVERIFY(m_dbWidget->isInSearchMode());
QModelIndex item = entryView->model()->index(0, 1); QModelIndex item = entryView->model()->index(0, 1);
Entry* entry = entryView->entryFromIndex(item); Entry* entry = entryView->entryFromIndex(item);
QVERIFY(m_dbWidget->isInSearchMode()); QTest::keyClick(searchTextEdit, Qt::Key_Return);
clickIndex(item, entryView, Qt::LeftButton);
QAction* entryEditAction = m_mainWindow->findChild<QAction*>("actionEntryEdit");
QVERIFY(entryEditAction->isEnabled());
QWidget* entryEditWidget = toolBar->widgetForAction(entryEditAction);
QVERIFY(entryEditWidget->isVisible());
QVERIFY(entryEditWidget->isEnabled());
QTest::mouseClick(entryEditWidget, Qt::LeftButton);
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::EditMode); QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::EditMode);
// Perform the edit and save it // Perform the edit and save it
@ -465,7 +470,7 @@ void TestGui::testSearch()
QDialogButtonBox* editEntryWidgetButtonBox = editEntryWidget->findChild<QDialogButtonBox*>("buttonBox"); QDialogButtonBox* editEntryWidgetButtonBox = editEntryWidget->findChild<QDialogButtonBox*>("buttonBox");
QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton); QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton);
// Confirm the edit was made and we are back in view mode // Confirm the edit was made and we are back in search mode
QTRY_VERIFY(m_dbWidget->isInSearchMode()); QTRY_VERIFY(m_dbWidget->isInSearchMode());
QCOMPARE(entry->title(), origTitle.append("_edited")); QCOMPARE(entry->title(), origTitle.append("_edited"));