Search scopes to currently selected group (and children) (#118)

* Added test cases for case sensitive and group search
This commit is contained in:
Jonathan White 2016-11-28 19:02:21 -05:00 committed by GitHub
parent 9261d8ae9d
commit 791a749c2f
5 changed files with 54 additions and 73 deletions

View File

@ -142,9 +142,8 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)
connect(m_splitter, SIGNAL(splitterMoved(int,int)), SIGNAL(splitterSizesChanged())); connect(m_splitter, SIGNAL(splitterMoved(int,int)), SIGNAL(splitterSizesChanged()));
connect(m_entryView->header(), SIGNAL(sectionResized(int,int,int)), SIGNAL(entryColumnSizesChanged())); 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*)), SIGNAL(groupChanged()));
connect(m_groupView, SIGNAL(groupChanged(Group*)), m_entryView, SLOT(setGroup(Group*)));
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()), SIGNAL(entrySelectionChanged())); connect(m_entryView, SIGNAL(entrySelectionChanged()), SIGNAL(entrySelectionChanged()));
@ -171,7 +170,6 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)
m_ignoreNextAutoreload = false; m_ignoreNextAutoreload = false;
m_searchCaseSensitive = false; m_searchCaseSensitive = false;
m_searchCurrentGroup = false;
setCurrentWidget(m_mainWidget); setCurrentWidget(m_mainWidget);
} }
@ -624,11 +622,7 @@ void DatabaseWidget::switchToEntryEdit(Entry* entry)
void DatabaseWidget::switchToEntryEdit(Entry* entry, bool create) void DatabaseWidget::switchToEntryEdit(Entry* entry, bool create)
{ {
Group* group = m_groupView->currentGroup(); Group* group = currentGroup();
if (!group) {
Q_ASSERT(m_entryView->inEntryListMode());
group = m_lastGroup;
}
Q_ASSERT(group); Q_ASSERT(group);
m_editEntryWidget->loadEntry(entry, create, false, group->name(), m_db); m_editEntryWidget->loadEntry(entry, create, false, group->name(), m_db);
@ -842,16 +836,9 @@ void DatabaseWidget::search(const QString& searchtext)
Q_EMIT searchModeAboutToActivate(); Q_EMIT searchModeAboutToActivate();
if (!isInSearchMode()) Qt::CaseSensitivity caseSensitive = m_searchCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive;
{
m_lastGroup = m_groupView->currentGroup();
Q_ASSERT(m_lastGroup);
}
Group* searchGroup = m_searchCurrentGroup ? m_lastGroup : m_db->rootGroup(); QList<Entry*> searchResult = EntrySearcher().search(searchtext, currentGroup(), caseSensitive);
Qt::CaseSensitivity sensitivity = m_searchCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive;
QList<Entry*> searchResult = EntrySearcher().search(searchtext, searchGroup, sensitivity);
m_entryView->setEntryList(searchResult); m_entryView->setEntryList(searchResult);
m_lastSearchText = searchtext; m_lastSearchText = searchtext;
@ -877,12 +864,13 @@ void DatabaseWidget::setSearchCaseSensitive(bool state)
search(m_lastSearchText); 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()) if (isInSearchMode())
search(m_lastSearchText); search(m_lastSearchText);
else
m_entryView->setGroup(group);
} }
QString DatabaseWidget::getCurrentSearch() QString DatabaseWidget::getCurrentSearch()
@ -894,12 +882,10 @@ void DatabaseWidget::endSearch()
{ {
if (isInSearchMode()) if (isInSearchMode())
{ {
Q_ASSERT(m_lastGroup);
Q_EMIT listModeAboutToActivate(); Q_EMIT listModeAboutToActivate();
m_groupView->setCurrentGroup(m_lastGroup); // Show the normal entry view of the current group
m_entryView->setGroup(m_lastGroup); m_entryView->setGroup(currentGroup());
Q_EMIT listModeActivated(); Q_EMIT listModeActivated();
} }
@ -938,15 +924,7 @@ bool DatabaseWidget::isInSearchMode() const
Group* DatabaseWidget::currentGroup() const Group* DatabaseWidget::currentGroup() const
{ {
return isInSearchMode() ? m_lastGroup return m_groupView->currentGroup();
: m_groupView->currentGroup();
}
void DatabaseWidget::clearLastGroup(Group* group)
{
if (group) {
m_lastGroup = nullptr;
}
} }
void DatabaseWidget::lock() void DatabaseWidget::lock()

View File

@ -127,6 +127,7 @@ public Q_SLOTS:
void openUrlForEntry(Entry* entry); void openUrlForEntry(Entry* entry);
void createGroup(); void createGroup();
void deleteGroup(); void deleteGroup();
void onGroupChanged(Group* group);
void switchToView(bool accepted); void switchToView(bool accepted);
void switchToEntryEdit(); void switchToEntryEdit();
void switchToGroupEdit(); void switchToGroupEdit();
@ -142,7 +143,6 @@ public Q_SLOTS:
// Search related slots // Search related slots
void search(const QString& searchtext); void search(const QString& searchtext);
void setSearchCaseSensitive(bool state); void setSearchCaseSensitive(bool state);
void setSearchCurrentGroup(bool state);
void endSearch(); void endSearch();
private Q_SLOTS: private Q_SLOTS:
@ -159,7 +159,6 @@ private Q_SLOTS:
void mergeDatabase(bool accepted); void mergeDatabase(bool accepted);
void unlockDatabase(bool accepted); void unlockDatabase(bool accepted);
void emitCurrentModeChanged(); void emitCurrentModeChanged();
void clearLastGroup(Group* group);
// Database autoreload slots // Database autoreload slots
void onWatchedFileChanged(); void onWatchedFileChanged();
void reloadDatabaseFile(); void reloadDatabaseFile();
@ -188,14 +187,12 @@ private:
Group* m_newGroup; Group* m_newGroup;
Entry* m_newEntry; Entry* m_newEntry;
Group* m_newParent; Group* m_newParent;
Group* m_lastGroup;
QString m_filename; QString m_filename;
Uuid m_groupBeforeLock; Uuid m_groupBeforeLock;
// Search state // Search state
QString m_lastSearchText; QString m_lastSearchText;
bool m_searchCaseSensitive; bool m_searchCaseSensitive;
bool m_searchCurrentGroup;
// Autoreload // Autoreload
QFileSystemWatcher m_fileWatcher; QFileSystemWatcher m_fileWatcher;

View File

@ -59,11 +59,9 @@ SearchWidget::SearchWidget(QWidget *parent)
QMenu *searchMenu = new QMenu(); QMenu *searchMenu = new QMenu();
m_actionCaseSensitive = searchMenu->addAction(tr("Case Sensitive"), this, SLOT(updateCaseSensitive())); m_actionCaseSensitive = searchMenu->addAction(tr("Case Sensitive"), this, SLOT(updateCaseSensitive()));
m_actionCaseSensitive->setObjectName("actionSearchCaseSensitive");
m_actionCaseSensitive->setCheckable(true); 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->setIcon(filePath()->icon("actions", "system-search"));
m_ui->searchIcon->setMenu(searchMenu); m_ui->searchIcon->setMenu(searchMenu);
m_ui->searchIcon->setPopupMode(QToolButton::MenuButtonPopup); m_ui->searchIcon->setPopupMode(QToolButton::MenuButtonPopup);
@ -77,9 +75,7 @@ SearchWidget::~SearchWidget()
void SearchWidget::connectSignals(SignalMultiplexer& mx) void SearchWidget::connectSignals(SignalMultiplexer& mx)
{ {
mx.connect(this, SIGNAL(search(QString)), SLOT(search(QString))); mx.connect(this, SIGNAL(search(QString)), SLOT(search(QString)));
mx.connect(this, SIGNAL(setCaseSensitive(bool)), SLOT(setSearchCaseSensitive(bool))); mx.connect(this, SIGNAL(caseSensitiveChanged(bool)), SLOT(setSearchCaseSensitive(bool)));
mx.connect(this, SIGNAL(setGroupSearch(bool)), SLOT(setSearchCurrentGroup(bool)));
mx.connect(SIGNAL(groupChanged()), m_ui->searchEdit, SLOT(clear()));
} }
void SearchWidget::databaseChanged(DatabaseWidget *dbWidget) void SearchWidget::databaseChanged(DatabaseWidget *dbWidget)
@ -89,8 +85,7 @@ void SearchWidget::databaseChanged(DatabaseWidget *dbWidget)
m_ui->searchEdit->setText(dbWidget->getCurrentSearch()); m_ui->searchEdit->setText(dbWidget->getCurrentSearch());
// Enforce search policy // Enforce search policy
emit setCaseSensitive(m_actionCaseSensitive->isChecked()); emit caseSensitiveChanged(m_actionCaseSensitive->isChecked());
emit setGroupSearch(m_actionGroupSearch->isChecked());
} else { } else {
m_ui->searchEdit->clear(); m_ui->searchEdit->clear();
} }
@ -115,10 +110,11 @@ void SearchWidget::startSearch()
void SearchWidget::updateCaseSensitive() 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();
} }

View File

@ -48,11 +48,11 @@ public:
~SearchWidget(); ~SearchWidget();
void connectSignals(SignalMultiplexer& mx); void connectSignals(SignalMultiplexer& mx);
void setCaseSensitive(bool state);
signals: signals:
void search(const QString &text); void search(const QString &text);
void setCaseSensitive(bool state); void caseSensitiveChanged(bool state);
void setGroupSearch(bool state);
public slots: public slots:
void databaseChanged(DatabaseWidget* dbWidget); void databaseChanged(DatabaseWidget* dbWidget);
@ -61,7 +61,6 @@ private slots:
void startSearchTimer(); void startSearchTimer();
void startSearch(); void startSearch();
void updateCaseSensitive(); void updateCaseSensitive();
void updateGroupSearch();
private: private:
const QScopedPointer<Ui::SearchWidget> m_ui; const QScopedPointer<Ui::SearchWidget> m_ui;
@ -69,7 +68,6 @@ private:
SearchEventFilter m_searchEventFilter; SearchEventFilter m_searchEventFilter;
QAction *m_actionCaseSensitive; QAction *m_actionCaseSensitive;
QAction *m_actionGroupSearch;
Q_DISABLE_COPY(SearchWidget) Q_DISABLE_COPY(SearchWidget)
}; };

View File

@ -46,6 +46,7 @@
#include "gui/FileDialog.h" #include "gui/FileDialog.h"
#include "gui/MainWindow.h" #include "gui/MainWindow.h"
#include "gui/MessageBox.h" #include "gui/MessageBox.h"
#include "gui/SearchWidget.h"
#include "gui/entry/EditEntryWidget.h" #include "gui/entry/EditEntryWidget.h"
#include "gui/entry/EntryView.h" #include "gui/entry/EntryView.h"
#include "gui/group/GroupModel.h" #include "gui/group/GroupModel.h"
@ -378,36 +379,50 @@ void TestGui::testSearch()
QToolBar* toolBar = m_mainWindow->findChild<QToolBar*>("toolBar"); QToolBar* toolBar = m_mainWindow->findChild<QToolBar*>("toolBar");
QWidget* searchActionWidget = toolBar->findChild<QWidget*>("SearchWidget"); SearchWidget* searchWidget = toolBar->findChild<SearchWidget*>("SearchWidget");
QVERIFY(searchActionWidget->isEnabled()); QVERIFY(searchWidget->isEnabled());
QLineEdit* searchEdit = searchActionWidget->findChild<QLineEdit*>("searchEdit"); QLineEdit* searchTextEdit = searchWidget->findChild<QLineEdit*>("searchEdit");
EntryView* entryView = m_dbWidget->findChild<EntryView*>("entryView"); EntryView* entryView = m_dbWidget->findChild<EntryView*>("entryView");
QVERIFY(entryView->isVisible()); QVERIFY(entryView->isVisible());
// Enter search // Enter search
QTest::mouseClick(searchEdit, Qt::LeftButton); QTest::mouseClick(searchTextEdit, Qt::LeftButton);
QTRY_VERIFY(searchEdit->hasFocus()); QTRY_VERIFY(searchTextEdit->hasFocus());
// Search for "ZZZ" // Search for "ZZZ"
QTest::keyClicks(searchEdit, "ZZZ"); QTest::keyClicks(searchTextEdit, "ZZZ");
QTRY_COMPARE(searchEdit->text(), QString("ZZZ")); QTRY_COMPARE(searchTextEdit->text(), QString("ZZZ"));
QTRY_VERIFY(m_dbWidget->isInSearchMode()); QTRY_VERIFY(m_dbWidget->isInSearchMode());
QTRY_COMPARE(entryView->model()->rowCount(), 0); QTRY_COMPARE(entryView->model()->rowCount(), 0);
// Escape clears searchedit and retains focus // Escape clears searchedit and retains focus
QTest::keyClick(searchEdit, Qt::Key_Escape); QTest::keyClick(searchTextEdit, Qt::Key_Escape);
QTRY_VERIFY(searchEdit->text().isEmpty()); QTRY_VERIFY(searchTextEdit->text().isEmpty());
QTRY_VERIFY(searchEdit->hasFocus()); QTRY_VERIFY(searchTextEdit->hasFocus());
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::ViewMode); QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::ViewMode);
// Search for "some" // Search for "some"
QTest::keyClicks(searchEdit, "some"); QTest::keyClicks(searchTextEdit, "some");
QTRY_VERIFY(m_dbWidget->isInSearchMode()); QTRY_VERIFY(m_dbWidget->isInSearchMode());
QTRY_COMPARE(entryView->model()->rowCount(), 3); QTRY_COMPARE(entryView->model()->rowCount(), 3);
// Press Down to focus on the entry view // Search for "someTHING"
QTest::keyClicks(searchEdit, "thing"); QTest::keyClicks(searchTextEdit, "THING");
QTRY_COMPARE(entryView->model()->rowCount(), 2); QTRY_COMPARE(entryView->model()->rowCount(), 2);
//QVERIFY(!entryView->hasFocus());
//QTest::keyClick(searchEdit, Qt::Key_Down); // Test case sensitive search
//QVERIFY(entryView->hasFocus()); 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 // Try to edit the first entry from the search view
QModelIndex item = entryView->model()->index(0, 1); QModelIndex item = entryView->model()->index(0, 1);
@ -435,12 +450,9 @@ void TestGui::testSearch()
QCOMPARE(entry->title(), origTitle.append("_edited")); QCOMPARE(entry->title(), origTitle.append("_edited"));
// Cancel search, should return to normal view // Cancel search, should return to normal view
QTest::mouseClick(searchEdit, Qt::LeftButton); QTest::mouseClick(searchTextEdit, Qt::LeftButton);
QTest::keyClick(searchEdit, Qt::Key_Escape); QTest::keyClick(searchTextEdit, Qt::Key_Escape);
QTRY_COMPARE(m_dbWidget->currentMode(), DatabaseWidget::ViewMode); 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() void TestGui::testDeleteEntry()