mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2025-08-03 20:14:17 -04:00
Autocomplete usernames based on most frequent in database
* Fixes #3126 * Limit autocompletion to the top ten used usernames - Load common usernames when database is opened - Transition from QLineEdit to QComboBox for usernames - Dropdown menu of the combobox lets user choose a common username - Common usernames are autocompleted via inline completion - Common usernames are sorted by frequency (first) and name (second)
This commit is contained in:
parent
a22e8a1f40
commit
f85642741d
13 changed files with 134 additions and 10 deletions
|
@ -1181,3 +1181,29 @@ void TestGroup::testApplyGroupIconRecursively()
|
|||
QVERIFY(subsubgroup->iconNumber() == iconForGroups);
|
||||
QVERIFY(subsubgroupEntry->iconNumber() == iconForEntries);
|
||||
}
|
||||
|
||||
void TestGroup::testUsernamesRecursive()
|
||||
{
|
||||
Database* database = new Database();
|
||||
|
||||
// Create a subgroup
|
||||
Group* subgroup = new Group();
|
||||
subgroup->setName("Subgroup");
|
||||
subgroup->setParent(database->rootGroup());
|
||||
|
||||
// Generate entries in the root group and the subgroup
|
||||
Entry* rootGroupEntry = database->rootGroup()->addEntryWithPath("Root group entry");
|
||||
rootGroupEntry->setUsername("Name1");
|
||||
|
||||
Entry* subgroupEntry = subgroup->addEntryWithPath("Subgroup entry");
|
||||
subgroupEntry->setUsername("Name2");
|
||||
|
||||
Entry* subgroupEntryReusingUsername = subgroup->addEntryWithPath("Another subgroup entry");
|
||||
subgroupEntryReusingUsername->setUsername("Name2");
|
||||
|
||||
QList<QString> usernames = database->rootGroup()->usernamesRecursive();
|
||||
QCOMPARE(usernames.size(), 2);
|
||||
QVERIFY(usernames.contains("Name1"));
|
||||
QVERIFY(usernames.contains("Name2"));
|
||||
QVERIFY(usernames.indexOf("Name2") < usernames.indexOf("Name1"));
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ private slots:
|
|||
void testChildrenSort();
|
||||
void testHierarchy();
|
||||
void testApplyGroupIconRecursively();
|
||||
void testUsernamesRecursive();
|
||||
};
|
||||
|
||||
#endif // KEEPASSX_TESTGROUP_H
|
||||
|
|
|
@ -507,7 +507,7 @@ void TestGui::testEditEntry()
|
|||
QVERIFY(okButton);
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::EditMode);
|
||||
titleEdit->setText("multiline\ntitle");
|
||||
editEntryWidget->findChild<QLineEdit*>("usernameEdit")->setText("multiline\nusername");
|
||||
editEntryWidget->findChild<QComboBox*>("usernameComboBox")->lineEdit()->setText("multiline\nusername");
|
||||
editEntryWidget->findChild<QLineEdit*>("passwordEdit")->setText("multiline\npassword");
|
||||
editEntryWidget->findChild<QLineEdit*>("passwordRepeatEdit")->setText("multiline\npassword");
|
||||
editEntryWidget->findChild<QLineEdit*>("urlEdit")->setText("multiline\nurl");
|
||||
|
@ -594,6 +594,10 @@ void TestGui::testAddEntry()
|
|||
auto* editEntryWidget = m_dbWidget->findChild<EditEntryWidget*>("editEntryWidget");
|
||||
auto* titleEdit = editEntryWidget->findChild<QLineEdit*>("titleEdit");
|
||||
QTest::keyClicks(titleEdit, "test");
|
||||
auto* usernameComboBox = editEntryWidget->findChild<QComboBox*>("usernameComboBox");
|
||||
QVERIFY(usernameComboBox);
|
||||
QTest::mouseClick(usernameComboBox, Qt::LeftButton);
|
||||
QTest::keyClicks(usernameComboBox, "AutocompletionUsername");
|
||||
auto* editEntryWidgetButtonBox = editEntryWidget->findChild<QDialogButtonBox*>("buttonBox");
|
||||
QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton);
|
||||
|
||||
|
@ -602,17 +606,31 @@ void TestGui::testAddEntry()
|
|||
Entry* entry = entryView->entryFromIndex(item);
|
||||
|
||||
QCOMPARE(entry->title(), QString("test"));
|
||||
QCOMPARE(entry->username(), QString("AutocompletionUsername"));
|
||||
QCOMPARE(entry->historyItems().size(), 0);
|
||||
|
||||
m_db->updateCommonUsernames();
|
||||
|
||||
// Add entry "something 2"
|
||||
QTest::mouseClick(entryNewWidget, Qt::LeftButton);
|
||||
QTest::keyClicks(titleEdit, "something 2");
|
||||
QTest::mouseClick(usernameComboBox, Qt::LeftButton);
|
||||
QTest::keyClicks(usernameComboBox, "Auto");
|
||||
QTest::keyPress(usernameComboBox, Qt::Key_Right);
|
||||
auto* passwordEdit = editEntryWidget->findChild<QLineEdit*>("passwordEdit");
|
||||
auto* passwordRepeatEdit = editEntryWidget->findChild<QLineEdit*>("passwordRepeatEdit");
|
||||
QTest::keyClicks(passwordEdit, "something 2");
|
||||
QTest::keyClicks(passwordRepeatEdit, "something 2");
|
||||
QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton);
|
||||
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::ViewMode);
|
||||
item = entryView->model()->index(1, 1);
|
||||
entry = entryView->entryFromIndex(item);
|
||||
|
||||
QCOMPARE(entry->title(), QString("something 2"));
|
||||
QCOMPARE(entry->username(), QString("AutocompletionUsername"));
|
||||
QCOMPARE(entry->historyItems().size(), 0);
|
||||
|
||||
// Add entry "something 5" but click cancel button (does NOT add entry)
|
||||
QTest::mouseClick(entryNewWidget, Qt::LeftButton);
|
||||
QTest::keyClicks(titleEdit, "something 5");
|
||||
|
@ -1063,8 +1081,8 @@ void TestGui::testEntryPlaceholders()
|
|||
auto* editEntryWidget = m_dbWidget->findChild<EditEntryWidget*>("editEntryWidget");
|
||||
auto* titleEdit = editEntryWidget->findChild<QLineEdit*>("titleEdit");
|
||||
QTest::keyClicks(titleEdit, "test");
|
||||
QLineEdit* usernameEdit = editEntryWidget->findChild<QLineEdit*>("usernameEdit");
|
||||
QTest::keyClicks(usernameEdit, "john");
|
||||
QComboBox* usernameComboBox = editEntryWidget->findChild<QComboBox*>("usernameComboBox");
|
||||
QTest::keyClicks(usernameComboBox, "john");
|
||||
QLineEdit* urlEdit = editEntryWidget->findChild<QLineEdit*>("urlEdit");
|
||||
QTest::keyClicks(urlEdit, "{TITLE}.{USERNAME}");
|
||||
auto* editEntryWidgetButtonBox = editEntryWidget->findChild<QDialogButtonBox*>("buttonBox");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue