mirror of
				https://github.com/keepassxreboot/keepassxc.git
				synced 2025-10-31 06:35:00 -04:00 
			
		
		
		
	Search scopes to currently selected group (and children) (#118)
* Added test cases for case sensitive and group search
This commit is contained in:
		
							parent
							
								
									9261d8ae9d
								
							
						
					
					
						commit
						791a749c2f
					
				
					 5 changed files with 54 additions and 73 deletions
				
			
		|  | @ -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<Entry*> searchResult = EntrySearcher().search(searchtext, searchGroup, sensitivity); | ||||
|     QList<Entry*> 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() | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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(); | ||||
| } | ||||
|  |  | |||
|  | @ -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<Ui::SearchWidget> m_ui; | ||||
|  | @ -69,7 +68,6 @@ private: | |||
|     SearchEventFilter m_searchEventFilter; | ||||
| 
 | ||||
|     QAction *m_actionCaseSensitive; | ||||
|     QAction *m_actionGroupSearch; | ||||
| 
 | ||||
|     Q_DISABLE_COPY(SearchWidget) | ||||
| }; | ||||
|  |  | |||
|  | @ -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<QToolBar*>("toolBar"); | ||||
| 
 | ||||
|     QWidget* searchActionWidget = toolBar->findChild<QWidget*>("SearchWidget"); | ||||
|     QVERIFY(searchActionWidget->isEnabled()); | ||||
|     QLineEdit* searchEdit = searchActionWidget->findChild<QLineEdit*>("searchEdit"); | ||||
|     SearchWidget* searchWidget = toolBar->findChild<SearchWidget*>("SearchWidget"); | ||||
|     QVERIFY(searchWidget->isEnabled()); | ||||
|     QLineEdit* searchTextEdit = searchWidget->findChild<QLineEdit*>("searchEdit"); | ||||
| 
 | ||||
|     EntryView* entryView = m_dbWidget->findChild<EntryView*>("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*>("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() | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Jonathan White
						Jonathan White