From 791a749c2f2069115f8fd75196d30e80088fe8a4 Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Mon, 28 Nov 2016 19:02:21 -0500 Subject: [PATCH] Search scopes to currently selected group (and children) (#118) * Added test cases for case sensitive and group search --- src/gui/DatabaseWidget.cpp | 44 ++++++++----------------------- src/gui/DatabaseWidget.h | 5 +--- src/gui/SearchWidget.cpp | 18 +++++-------- src/gui/SearchWidget.h | 6 ++--- tests/gui/TestGui.cpp | 54 +++++++++++++++++++++++--------------- 5 files changed, 54 insertions(+), 73 deletions(-) diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp index 30924d67..f880b9e6 100644 --- a/src/gui/DatabaseWidget.cpp +++ b/src/gui/DatabaseWidget.cpp @@ -142,9 +142,8 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent) connect(m_splitter, SIGNAL(splitterMoved(int,int)), SIGNAL(splitterSizesChanged())); connect(m_entryView->header(), SIGNAL(sectionResized(int,int,int)), SIGNAL(entryColumnSizesChanged())); - connect(m_groupView, SIGNAL(groupChanged(Group*)), this, SLOT(clearLastGroup(Group*))); + connect(m_groupView, SIGNAL(groupChanged(Group*)), this, SLOT(onGroupChanged(Group*))); connect(m_groupView, SIGNAL(groupChanged(Group*)), SIGNAL(groupChanged())); - connect(m_groupView, SIGNAL(groupChanged(Group*)), m_entryView, SLOT(setGroup(Group*))); connect(m_entryView, SIGNAL(entryActivated(Entry*, EntryModel::ModelColumn)), SLOT(entryActivationSignalReceived(Entry*, EntryModel::ModelColumn))); connect(m_entryView, SIGNAL(entrySelectionChanged()), SIGNAL(entrySelectionChanged())); @@ -171,7 +170,6 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent) m_ignoreNextAutoreload = false; m_searchCaseSensitive = false; - m_searchCurrentGroup = false; setCurrentWidget(m_mainWidget); } @@ -624,11 +622,7 @@ void DatabaseWidget::switchToEntryEdit(Entry* entry) void DatabaseWidget::switchToEntryEdit(Entry* entry, bool create) { - Group* group = m_groupView->currentGroup(); - if (!group) { - Q_ASSERT(m_entryView->inEntryListMode()); - group = m_lastGroup; - } + Group* group = currentGroup(); Q_ASSERT(group); m_editEntryWidget->loadEntry(entry, create, false, group->name(), m_db); @@ -842,16 +836,9 @@ void DatabaseWidget::search(const QString& searchtext) Q_EMIT searchModeAboutToActivate(); - if (!isInSearchMode()) - { - m_lastGroup = m_groupView->currentGroup(); - Q_ASSERT(m_lastGroup); - } + Qt::CaseSensitivity caseSensitive = m_searchCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive; - Group* searchGroup = m_searchCurrentGroup ? m_lastGroup : m_db->rootGroup(); - Qt::CaseSensitivity sensitivity = m_searchCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive; - - QList searchResult = EntrySearcher().search(searchtext, searchGroup, sensitivity); + QList searchResult = EntrySearcher().search(searchtext, currentGroup(), caseSensitive); m_entryView->setEntryList(searchResult); m_lastSearchText = searchtext; @@ -877,12 +864,13 @@ void DatabaseWidget::setSearchCaseSensitive(bool state) search(m_lastSearchText); } -void DatabaseWidget::setSearchCurrentGroup(bool state) +void DatabaseWidget::onGroupChanged(Group* group) { - m_searchCurrentGroup = state; - + // Intercept group changes if in search mode if (isInSearchMode()) search(m_lastSearchText); + else + m_entryView->setGroup(group); } QString DatabaseWidget::getCurrentSearch() @@ -894,12 +882,10 @@ void DatabaseWidget::endSearch() { if (isInSearchMode()) { - Q_ASSERT(m_lastGroup); - Q_EMIT listModeAboutToActivate(); - m_groupView->setCurrentGroup(m_lastGroup); - m_entryView->setGroup(m_lastGroup); + // Show the normal entry view of the current group + m_entryView->setGroup(currentGroup()); Q_EMIT listModeActivated(); } @@ -938,15 +924,7 @@ bool DatabaseWidget::isInSearchMode() const Group* DatabaseWidget::currentGroup() const { - return isInSearchMode() ? m_lastGroup - : m_groupView->currentGroup(); -} - -void DatabaseWidget::clearLastGroup(Group* group) -{ - if (group) { - m_lastGroup = nullptr; - } + return m_groupView->currentGroup(); } void DatabaseWidget::lock() diff --git a/src/gui/DatabaseWidget.h b/src/gui/DatabaseWidget.h index 1031def4..2fd37354 100644 --- a/src/gui/DatabaseWidget.h +++ b/src/gui/DatabaseWidget.h @@ -127,6 +127,7 @@ public Q_SLOTS: void openUrlForEntry(Entry* entry); void createGroup(); void deleteGroup(); + void onGroupChanged(Group* group); void switchToView(bool accepted); void switchToEntryEdit(); void switchToGroupEdit(); @@ -142,7 +143,6 @@ public Q_SLOTS: // Search related slots void search(const QString& searchtext); void setSearchCaseSensitive(bool state); - void setSearchCurrentGroup(bool state); void endSearch(); private Q_SLOTS: @@ -159,7 +159,6 @@ private Q_SLOTS: void mergeDatabase(bool accepted); void unlockDatabase(bool accepted); void emitCurrentModeChanged(); - void clearLastGroup(Group* group); // Database autoreload slots void onWatchedFileChanged(); void reloadDatabaseFile(); @@ -188,14 +187,12 @@ private: Group* m_newGroup; Entry* m_newEntry; Group* m_newParent; - Group* m_lastGroup; QString m_filename; Uuid m_groupBeforeLock; // Search state QString m_lastSearchText; bool m_searchCaseSensitive; - bool m_searchCurrentGroup; // Autoreload QFileSystemWatcher m_fileWatcher; diff --git a/src/gui/SearchWidget.cpp b/src/gui/SearchWidget.cpp index 1de392b4..3d9325a0 100644 --- a/src/gui/SearchWidget.cpp +++ b/src/gui/SearchWidget.cpp @@ -59,11 +59,9 @@ SearchWidget::SearchWidget(QWidget *parent) QMenu *searchMenu = new QMenu(); m_actionCaseSensitive = searchMenu->addAction(tr("Case Sensitive"), this, SLOT(updateCaseSensitive())); + m_actionCaseSensitive->setObjectName("actionSearchCaseSensitive"); m_actionCaseSensitive->setCheckable(true); - m_actionGroupSearch = searchMenu->addAction(tr("Search Current Group"), this, SLOT(updateGroupSearch())); - m_actionGroupSearch->setCheckable(true); - m_ui->searchIcon->setIcon(filePath()->icon("actions", "system-search")); m_ui->searchIcon->setMenu(searchMenu); m_ui->searchIcon->setPopupMode(QToolButton::MenuButtonPopup); @@ -77,9 +75,7 @@ SearchWidget::~SearchWidget() void SearchWidget::connectSignals(SignalMultiplexer& mx) { mx.connect(this, SIGNAL(search(QString)), SLOT(search(QString))); - mx.connect(this, SIGNAL(setCaseSensitive(bool)), SLOT(setSearchCaseSensitive(bool))); - mx.connect(this, SIGNAL(setGroupSearch(bool)), SLOT(setSearchCurrentGroup(bool))); - mx.connect(SIGNAL(groupChanged()), m_ui->searchEdit, SLOT(clear())); + mx.connect(this, SIGNAL(caseSensitiveChanged(bool)), SLOT(setSearchCaseSensitive(bool))); } void SearchWidget::databaseChanged(DatabaseWidget *dbWidget) @@ -89,8 +85,7 @@ void SearchWidget::databaseChanged(DatabaseWidget *dbWidget) m_ui->searchEdit->setText(dbWidget->getCurrentSearch()); // Enforce search policy - emit setCaseSensitive(m_actionCaseSensitive->isChecked()); - emit setGroupSearch(m_actionGroupSearch->isChecked()); + emit caseSensitiveChanged(m_actionCaseSensitive->isChecked()); } else { m_ui->searchEdit->clear(); } @@ -115,10 +110,11 @@ void SearchWidget::startSearch() void SearchWidget::updateCaseSensitive() { - emit setCaseSensitive(m_actionCaseSensitive->isChecked()); + emit caseSensitiveChanged(m_actionCaseSensitive->isChecked()); } -void SearchWidget::updateGroupSearch() +void SearchWidget::setCaseSensitive(bool state) { - emit setGroupSearch(m_actionGroupSearch->isChecked()); + m_actionCaseSensitive->setChecked(state); + updateCaseSensitive(); } diff --git a/src/gui/SearchWidget.h b/src/gui/SearchWidget.h index 49e4a6a0..844cfb0d 100644 --- a/src/gui/SearchWidget.h +++ b/src/gui/SearchWidget.h @@ -48,11 +48,11 @@ public: ~SearchWidget(); void connectSignals(SignalMultiplexer& mx); + void setCaseSensitive(bool state); signals: void search(const QString &text); - void setCaseSensitive(bool state); - void setGroupSearch(bool state); + void caseSensitiveChanged(bool state); public slots: void databaseChanged(DatabaseWidget* dbWidget); @@ -61,7 +61,6 @@ private slots: void startSearchTimer(); void startSearch(); void updateCaseSensitive(); - void updateGroupSearch(); private: const QScopedPointer m_ui; @@ -69,7 +68,6 @@ private: SearchEventFilter m_searchEventFilter; QAction *m_actionCaseSensitive; - QAction *m_actionGroupSearch; Q_DISABLE_COPY(SearchWidget) }; diff --git a/tests/gui/TestGui.cpp b/tests/gui/TestGui.cpp index 169b8ef4..41059276 100644 --- a/tests/gui/TestGui.cpp +++ b/tests/gui/TestGui.cpp @@ -46,6 +46,7 @@ #include "gui/FileDialog.h" #include "gui/MainWindow.h" #include "gui/MessageBox.h" +#include "gui/SearchWidget.h" #include "gui/entry/EditEntryWidget.h" #include "gui/entry/EntryView.h" #include "gui/group/GroupModel.h" @@ -378,36 +379,50 @@ void TestGui::testSearch() QToolBar* toolBar = m_mainWindow->findChild("toolBar"); - QWidget* searchActionWidget = toolBar->findChild("SearchWidget"); - QVERIFY(searchActionWidget->isEnabled()); - QLineEdit* searchEdit = searchActionWidget->findChild("searchEdit"); + SearchWidget* searchWidget = toolBar->findChild("SearchWidget"); + QVERIFY(searchWidget->isEnabled()); + QLineEdit* searchTextEdit = searchWidget->findChild("searchEdit"); EntryView* entryView = m_dbWidget->findChild("entryView"); QVERIFY(entryView->isVisible()); // Enter search - QTest::mouseClick(searchEdit, Qt::LeftButton); - QTRY_VERIFY(searchEdit->hasFocus()); + QTest::mouseClick(searchTextEdit, Qt::LeftButton); + QTRY_VERIFY(searchTextEdit->hasFocus()); // Search for "ZZZ" - QTest::keyClicks(searchEdit, "ZZZ"); - QTRY_COMPARE(searchEdit->text(), QString("ZZZ")); + QTest::keyClicks(searchTextEdit, "ZZZ"); + QTRY_COMPARE(searchTextEdit->text(), QString("ZZZ")); QTRY_VERIFY(m_dbWidget->isInSearchMode()); QTRY_COMPARE(entryView->model()->rowCount(), 0); // Escape clears searchedit and retains focus - QTest::keyClick(searchEdit, Qt::Key_Escape); - QTRY_VERIFY(searchEdit->text().isEmpty()); - QTRY_VERIFY(searchEdit->hasFocus()); + QTest::keyClick(searchTextEdit, Qt::Key_Escape); + QTRY_VERIFY(searchTextEdit->text().isEmpty()); + QTRY_VERIFY(searchTextEdit->hasFocus()); QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::ViewMode); // Search for "some" - QTest::keyClicks(searchEdit, "some"); + QTest::keyClicks(searchTextEdit, "some"); QTRY_VERIFY(m_dbWidget->isInSearchMode()); QTRY_COMPARE(entryView->model()->rowCount(), 3); - // Press Down to focus on the entry view - QTest::keyClicks(searchEdit, "thing"); + // Search for "someTHING" + QTest::keyClicks(searchTextEdit, "THING"); QTRY_COMPARE(entryView->model()->rowCount(), 2); - //QVERIFY(!entryView->hasFocus()); - //QTest::keyClick(searchEdit, Qt::Key_Down); - //QVERIFY(entryView->hasFocus()); + + // Test case sensitive search + searchWidget->setCaseSensitive(true); + QTRY_COMPARE(entryView->model()->rowCount(), 0); + searchWidget->setCaseSensitive(false); + QTRY_COMPARE(entryView->model()->rowCount(), 2); + + // Test group search + GroupView* groupView = m_dbWidget->findChild("groupView"); + QCOMPARE(groupView->currentGroup(), m_db->rootGroup()); + QModelIndex rootGroupIndex = groupView->model()->index(0, 0); + clickIndex(groupView->model()->index(0, 0, rootGroupIndex), groupView, Qt::LeftButton); + QCOMPARE(groupView->currentGroup()->name(), QString("General")); + QTRY_COMPARE(entryView->model()->rowCount(), 0); + // reset + clickIndex(rootGroupIndex, groupView, Qt::LeftButton); + QCOMPARE(groupView->currentGroup(), m_db->rootGroup()); // Try to edit the first entry from the search view QModelIndex item = entryView->model()->index(0, 1); @@ -435,12 +450,9 @@ void TestGui::testSearch() QCOMPARE(entry->title(), origTitle.append("_edited")); // Cancel search, should return to normal view - QTest::mouseClick(searchEdit, Qt::LeftButton); - QTest::keyClick(searchEdit, Qt::Key_Escape); + QTest::mouseClick(searchTextEdit, Qt::LeftButton); + QTest::keyClick(searchTextEdit, Qt::Key_Escape); QTRY_COMPARE(m_dbWidget->currentMode(), DatabaseWidget::ViewMode); - //QCOMPARE(entryView->model()->rowCount(), 4); - - // TODO: add tests to confirm case sensitive and group search } void TestGui::testDeleteEntry()