diff --git a/share/translations/keepassxc_en.ts b/share/translations/keepassxc_en.ts
index f7bb5c14c..47c82f849 100644
--- a/share/translations/keepassxc_en.ts
+++ b/share/translations/keepassxc_en.ts
@@ -844,16 +844,6 @@
Use Virtual Keyboard
-
- <p>You can use advanced search queries to find any entry in your open databases. The following shortcuts are useful:<br/>
-Ctrl+F - Toggle database search<br/>
-Ctrl+1 - Type username<br/>
-Ctrl+2 - Type password<br/>
-Ctrl+3 - Type TOTP<br/>
-Ctrl+4 - Type URL<br/>
-Ctrl+5 - Use Virtual Keyboard (Windows Only)</p>
-
-
Type {URL}
@@ -862,6 +852,25 @@ Ctrl+5 - Use Virtual Keyboard (Windows Only)</p>
Copy URL
+
+ <p>The following shortcuts are available:<br/>
+Ctrl+F - Focus search<br/>
+Ctrl+1 - Type username<br/>
+Ctrl+2 - Type password<br/>
+Ctrl+3 - Type TOTP<br/>
+Ctrl+4 - Type URL<br/>
+Ctrl+5 - Use Virtual Keyboard (Windows Only)<br/>
+Ctrl+Shift+1 - Copy username<br/>
+Ctrl+Shift+2 - Copy password<br/>
+Ctrl+Shift+3 - Copy TOTP<br/>
+Ctrl+Shift+4 - Copy URL<br/>
+</p>
+
+
+
+ You can use advanced search queries to find any entry in your open databases.
+
+
BrowserAccessControlDialog
@@ -2638,18 +2647,6 @@ This is definitely a bug, please report it to the developers.
Remember my choice
-
- Delete group
-
-
-
- Do you really want to delete the group "%1" for good?
-
-
-
- Move group to recycle bin?
-
-
Do you really want to move the group "%1" to the recycle bin?
@@ -2748,10 +2745,6 @@ Disable safe saves and try again?
KeePass 2 Database
-
- Save database backup
-
-
Empty recycle bin?
@@ -2861,6 +2854,22 @@ Disable safe saves and try again?
Save
+
+ Save Database Backup
+
+
+
+ Confirm Delete Group
+
+
+
+ Do you really want to permanently delete the group "%1"?
+
+
+
+ Confirm Recycle Group
+
+
EditEntryAttachmentsDialog
@@ -4472,10 +4481,6 @@ This will leave your passwords and sensitive information vulnerable!
name (descending)
-
- unknown
-
-
Export database to HTML file
@@ -4484,6 +4489,10 @@ This will leave your passwords and sensitive information vulnerable!
HTML file
+
+ invalid sort order
+
+
FdoSecrets::DBusMgr
@@ -5718,10 +5727,6 @@ Are you sure you want to continue with this file?
&Edit Entry…
-
- &Delete Entry…
-
-
&New Group…
@@ -6087,10 +6092,6 @@ Expect some bugs and minor issues, this version is meant for testing purposes.
Merge From Database
-
- Create Entry
-
-
Edit Entry
@@ -6335,10 +6336,6 @@ Expect some bugs and minor issues, this version is meant for testing purposes.
Password Generator
-
- E&xpire Entry…
-
-
Clear SSH Agent
@@ -6347,6 +6344,40 @@ Expect some bugs and minor issues, this version is meant for testing purposes.
Clear all identities in ssh-agent
+
+ New Entry
+
+
+
+ Edit Entry…
+
+
+
+ E&xpire Entry
+
+
+
+ Expire Entry
+
+
+
+ &Delete Entry
+
+
+
+ Move selected entry(s) to the recycle bin
+
+
+
+
+
+
+ Permanently delete the selected entry(s)
+
+
+
+
+
ManageDatabase
@@ -6741,10 +6772,6 @@ Expect some bugs and minor issues, this version is meant for testing purposes.
PasskeyExporter
-
- KeePassXC: Passkey Export
-
-
File "%1.passkey" already exists.
Do you want to overwrite it?
@@ -6763,6 +6790,10 @@ Do you want to overwrite it?
Cannot write to file
+
+ Overwrite Existing File?
+
+
PasskeyImportDialog
@@ -6837,14 +6868,6 @@ Do you want to overwrite it?
Cannot open file "%1" for reading.
-
- Open passkey file
-
-
-
- Cannot import passkey
-
-
Cannot import passkey file "%1". Data is missing.
@@ -6859,6 +6882,14 @@ The following data is missing:
Cannot import passkey file "%1". Private key is missing or malformed.
+
+ Open Passkey File
+
+
+
+ Passkey Import Failed
+
+
PasswordEditWidget
@@ -7938,10 +7969,6 @@ Do you want to overwrite it?
Average password length
-
- %1 characters
-
-
Word count for the diceware passphrase.
@@ -8805,24 +8832,6 @@ Kernel: %3 %4
-
- Do you really want to delete the entry "%1" for good?
-
-
-
- Do you really want to delete %n entry(s) for good?
-
-
-
-
-
-
- Delete entry(s)?
-
-
-
-
-
Do you really want to move entry "%1" to the recycle bin?
@@ -8834,17 +8843,6 @@ Kernel: %3 %4
-
- Move entry(s) to recycle bin?
-
-
-
-
-
-
- Replace references to entry?
-
-
Entry "%1" has %2 reference(s). Do you want to overwrite references with values, skip this entry, or delete anyway?
@@ -9221,17 +9219,6 @@ This option is deprecated, use --set-key-file instead.
Proton Pass Import
-
- Delete plugin data?
-
-
-
- Delete plugin data from Entry(s)?
-
-
-
-
-
Passkey
@@ -9278,6 +9265,53 @@ This option is deprecated, use --set-key-file instead.
Fit
+
+ %1 character(s)
+
+
+
+
+
+
+ Do you really want to permanently delete the entry "%1"?
+
+
+
+ Do you really want to permanently delete %n entry(s)?
+
+
+
+
+
+
+ Confirm Delete Entry(s)
+
+
+
+
+
+
+ Confirm Recycle Entry(s)
+
+
+
+
+
+
+ Confirm Delete Plugin Data
+
+
+
+ Delete plugin data from the selected entry(s)?
+
+
+
+
+
+
+ Confirm Replace Entry References
+
+
QtIOCompressor
@@ -9822,14 +9856,17 @@ This option is deprecated, use --set-key-file instead.
Average password length
-
- %1 characters
-
-
Average password length is less than ten characters. Longer passwords provide more security.
+
+ %1 character(s)
+
+
+
+
+
SSHAgent
@@ -10505,10 +10542,6 @@ Example: JBSWY3DPEHPK3PXP
YubiKeyInterfacePCSC
-
- The YubiKey PCSC interface has not been initialized.
-
-
Could not find or access hardware key with serial number %1. Please present it to continue.
@@ -10521,10 +10554,6 @@ Example: JBSWY3DPEHPK3PXP
Hardware key was not found or is not configured.
-
- Failed to complete a challenge-response, the PCSC error code was: %1
-
-
(NFC) %1 [%2] - Slot %3, %4
YubiKey display fields
@@ -10540,13 +10569,17 @@ Example: JBSWY3DPEHPK3PXP
USB Challenge-Response Key no interaction required
+
+ The YubiKey PC/SC interface has not been initialized.
+
+
+
+ Failed to complete a challenge-response, the PC/SC error code was: %1
+
+
YubiKeyInterfaceUSB
-
- Unknown
-
-
Press
USB Challenge-Response Key interaction request
@@ -10587,5 +10620,10 @@ Example: JBSWY3DPEHPK3PXP
YubiKey display fields
+
+ Unknown
+ Unknown hardware key name
+
+
diff --git a/src/autotype/AutoTypeSelectDialog.ui b/src/autotype/AutoTypeSelectDialog.ui
index 0c0f6561e..07a200842 100644
--- a/src/autotype/AutoTypeSelectDialog.ui
+++ b/src/autotype/AutoTypeSelectDialog.ui
@@ -50,14 +50,19 @@
Qt::NoFocus
-
- <p>You can use advanced search queries to find any entry in your open databases. The following shortcuts are useful:<br/>
-Ctrl+F - Toggle database search<br/>
-Ctrl+1 - Type username<br/>
-Ctrl+2 - Type password<br/>
-Ctrl+3 - Type TOTP<br/>
-Ctrl+4 - Type URL<br/>
-Ctrl+5 - Use Virtual Keyboard (Windows Only)</p>
+
+ <p>The following shortcuts are available:<br/>
+Ctrl+F - Focus search<br/>
+Ctrl+1 - Type username<br/>
+Ctrl+2 - Type password<br/>
+Ctrl+3 - Type TOTP<br/>
+Ctrl+4 - Type URL<br/>
+Ctrl+5 - Use Virtual Keyboard (Windows Only)<br/>
+Ctrl+Shift+1 - Copy username<br/>
+Ctrl+Shift+2 - Copy password<br/>
+Ctrl+Shift+3 - Copy TOTP<br/>
+Ctrl+Shift+4 - Copy URL<br/>
+</p>
QToolButton {
@@ -173,6 +178,9 @@ Ctrl+5 - Use Virtual Keyboard (Windows Only)</p>
0
+
+ You can use advanced search queries to find any entry in your open databases.
+
Search…
diff --git a/src/cli/DatabaseInfo.cpp b/src/cli/DatabaseInfo.cpp
index 0b205157c..44030d5e1 100644
--- a/src/cli/DatabaseInfo.cpp
+++ b/src/cli/DatabaseInfo.cpp
@@ -67,8 +67,8 @@ int DatabaseInfo::executeWithDatabase(QSharedPointer database, QShared
out << QObject::tr("Number of short passwords") << ": " << QString::number(stats.shortPasswords) << Qt::endl;
out << QObject::tr("Number of weak passwords") << ": " << QString::number(stats.weakPasswords) << Qt::endl;
out << QObject::tr("Entries excluded from reports") << ": " << QString::number(stats.excludedEntries) << Qt::endl;
- out << QObject::tr("Average password length") << ": " << QObject::tr("%1 characters").arg(stats.averagePwdLength())
- << Qt::endl;
+ out << QObject::tr("Average password length") << ": "
+ << QObject::tr("%1 character(s)", "", stats.averagePwdLength()).arg(stats.averagePwdLength()) << Qt::endl;
return EXIT_SUCCESS;
}
diff --git a/src/core/Tools.cpp b/src/core/Tools.cpp
index 814233941..1d0bb1ba0 100644
--- a/src/core/Tools.cpp
+++ b/src/core/Tools.cpp
@@ -151,23 +151,23 @@ namespace Tools
if (seconds >= secondsInYear) {
auto years = std::floor(seconds / secondsInYear);
- return QObject::tr("over %1 year(s)", nullptr, years).arg(years);
+ return QObject::tr("over %1 year(s)", "", years).arg(years);
} else if (seconds >= secondsInMonth) {
auto months = std::round(seconds / secondsInMonth);
- return QObject::tr("about %1 month(s)", nullptr, months).arg(months);
+ return QObject::tr("about %1 month(s)", "", months).arg(months);
} else if (seconds >= secondsInWeek) {
auto weeks = std::round(seconds / secondsInWeek);
- return QObject::tr("%1 week(s)", nullptr, weeks).arg(weeks);
+ return QObject::tr("%1 week(s)", "", weeks).arg(weeks);
} else if (seconds >= secondsInDay) {
auto days = std::floor(seconds / secondsInDay);
- return QObject::tr("%1 day(s)", nullptr, days).arg(days);
+ return QObject::tr("%1 day(s)", "", days).arg(days);
} else if (seconds >= secondsInHour) {
auto hours = std::floor(seconds / secondsInHour);
- return QObject::tr("%1 hour(s)", nullptr, hours).arg(hours);
+ return QObject::tr("%1 hour(s)", "", hours).arg(hours);
}
auto minutes = std::floor(seconds / 60);
- return QObject::tr("%1 minute(s)", nullptr, minutes).arg(minutes);
+ return QObject::tr("%1 minute(s)", "", minutes).arg(minutes);
}
bool readFromDevice(QIODevice* device, QByteArray& data, int size)
diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp
index 73434c3a4..df13b1d5a 100644
--- a/src/gui/DatabaseWidget.cpp
+++ b/src/gui/DatabaseWidget.cpp
@@ -1120,8 +1120,8 @@ void DatabaseWidget::deleteGroup()
if (inRecycleBin || isRecycleBin || isRecycleBinSubgroup || !m_db->metadata()->recycleBinEnabled()) {
auto result = MessageBox::question(
this,
- tr("Delete group"),
- tr("Do you really want to delete the group \"%1\" for good?").arg(currentGroup->name().toHtmlEscaped()),
+ tr("Confirm Delete Group"),
+ tr("Do you really want to permanently delete the group \"%1\"?").arg(currentGroup->name().toHtmlEscaped()),
MessageBox::Delete | MessageBox::Cancel,
MessageBox::Cancel);
@@ -1130,7 +1130,7 @@ void DatabaseWidget::deleteGroup()
}
} else {
auto result = MessageBox::question(this,
- tr("Move group to recycle bin?"),
+ tr("Confirm Recycle Group"),
tr("Do you really want to move the group "
"\"%1\" to the recycle bin?")
.arg(currentGroup->name().toHtmlEscaped()),
@@ -2640,7 +2640,7 @@ bool DatabaseWidget::saveBackup()
}
const QString newFilePath = fileDialog()->getSaveFileName(this,
- tr("Save database backup"),
+ tr("Save Database Backup"),
FileDialog::getLastDir("backup", oldFilePath),
tr("KeePass 2 Database").append(" (*.kdbx)"));
diff --git a/src/gui/GuiTools.cpp b/src/gui/GuiTools.cpp
index b2dfa63f3..b448e87e7 100644
--- a/src/gui/GuiTools.cpp
+++ b/src/gui/GuiTools.cpp
@@ -32,14 +32,15 @@ namespace GuiTools
if (permanent) {
QString prompt;
if (entries.size() == 1) {
- prompt = QObject::tr("Do you really want to delete the entry \"%1\" for good?")
- .arg(entries.first()->title().toHtmlEscaped());
+ auto entry = entries.first();
+ prompt = QObject::tr("Do you really want to permanently delete the entry \"%1\"?")
+ .arg(entry->resolvePlaceholder(entry->title()).toHtmlEscaped());
} else {
- prompt = QObject::tr("Do you really want to delete %n entry(s) for good?", "", entries.size());
+ prompt = QObject::tr("Do you really want to permanently delete %n entry(s)?", "", entries.size());
}
auto answer = MessageBox::question(parent,
- QObject::tr("Delete entry(s)?", "", entries.size()),
+ QObject::tr("Confirm Delete Entry(s)", "", entries.size()),
prompt,
MessageBox::Delete | MessageBox::Cancel,
MessageBox::Cancel);
@@ -50,14 +51,15 @@ namespace GuiTools
} else {
QString prompt;
if (entries.size() == 1) {
+ auto entry = entries.first();
prompt = QObject::tr("Do you really want to move entry \"%1\" to the recycle bin?")
- .arg(entries.first()->title().toHtmlEscaped());
+ .arg(entry->resolvePlaceholder(entry->title()).toHtmlEscaped());
} else {
prompt = QObject::tr("Do you really want to move %n entry(s) to the recycle bin?", "", entries.size());
}
auto answer = MessageBox::question(parent,
- QObject::tr("Move entry(s) to recycle bin?", "", entries.size()),
+ QObject::tr("Confirm Recycle Entry(s)", "", entries.size()),
prompt,
MessageBox::Move | MessageBox::Cancel,
MessageBox::Cancel);
@@ -72,11 +74,12 @@ namespace GuiTools
return false;
}
- auto answer = MessageBox::question(parent,
- QObject::tr("Delete plugin data?"),
- QObject::tr("Delete plugin data from Entry(s)?", "", entries.size()),
- MessageBox::Delete | MessageBox::Cancel,
- MessageBox::Cancel);
+ auto answer =
+ MessageBox::question(parent,
+ QObject::tr("Confirm Delete Plugin Data"),
+ QObject::tr("Delete plugin data from the selected entry(s)?", "", entries.size()),
+ MessageBox::Delete | MessageBox::Cancel,
+ MessageBox::Cancel);
return answer == MessageBox::Delete;
}
@@ -100,7 +103,7 @@ namespace GuiTools
// Prompt the user on what to do with the reference (Overwrite, Delete, Skip)
auto result = MessageBox::question(
parent,
- QObject::tr("Replace references to entry?"),
+ QObject::tr("Confirm Replace Entry References"),
QObject::tr(
"Entry \"%1\" has %2 reference(s). "
"Do you want to overwrite references with values, skip this entry, or delete anyway?",
diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp
index 035ea8c38..927406ded 100644
--- a/src/gui/MainWindow.cpp
+++ b/src/gui/MainWindow.cpp
@@ -944,6 +944,17 @@ void MainWindow::updateMenuActionState()
m_ui->actionEntryEdit->setEnabled(singleEntrySelected);
m_ui->actionEntryExpire->setEnabled(multiEntrySelected);
m_ui->actionEntryDelete->setEnabled(multiEntrySelected);
+ if (dbWidget) {
+ if (dbWidget->database()->metadata()->recycleBinEnabled() && !inRecycleBin) {
+ m_ui->actionEntryDelete->setToolTip(
+ tr("Move selected entry(s) to the recycle bin", "", dbWidget->numberOfSelectedEntries()));
+ } else {
+ m_ui->actionEntryDelete->setToolTip(
+ tr("Permanently delete the selected entry(s)", "", dbWidget->numberOfSelectedEntries()));
+ }
+ } else {
+ m_ui->actionEntryDelete->setToolTip(tr("Delete Entry"));
+ }
m_ui->actionEntryRestore->setVisible(multiEntrySelected && inRecycleBin);
m_ui->actionEntryRestore->setEnabled(multiEntrySelected && inRecycleBin);
if (dbWidget) {
diff --git a/src/gui/MainWindow.ui b/src/gui/MainWindow.ui
index 558320003..79f2ab36c 100644
--- a/src/gui/MainWindow.ui
+++ b/src/gui/MainWindow.ui
@@ -532,7 +532,7 @@
&New Entry…
- Create Entry
+ New Entry
Ctrl+N
@@ -542,6 +542,9 @@
&Edit Entry…
+
+ Edit Entry…
+
Edit Entry
@@ -554,12 +557,21 @@
false
- E&xpire Entry…
+ E&xpire Entry
+
+
+ Expire Entry
+
+
+ Expire Entry
- &Delete Entry…
+ &Delete Entry
+
+
+ Delete Entry
Delete Entry
diff --git a/src/gui/entry/EditEntryWidget.cpp b/src/gui/entry/EditEntryWidget.cpp
index 65e5dd0cc..05a52c3ff 100644
--- a/src/gui/entry/EditEntryWidget.cpp
+++ b/src/gui/entry/EditEntryWidget.cpp
@@ -1690,21 +1690,21 @@ void EditEntryWidget::deleteAllHistoryEntries()
QMenu* EditEntryWidget::createPresetsMenu()
{
auto* expirePresetsMenu = new QMenu(this);
- expirePresetsMenu->addAction(tr("%n hour(s)", nullptr, 12))->setData(QVariant::fromValue(TimeDelta::fromHours(12)));
- expirePresetsMenu->addAction(tr("%n hour(s)", nullptr, 24))->setData(QVariant::fromValue(TimeDelta::fromHours(24)));
+ expirePresetsMenu->addAction(tr("%n hour(s)", "", 12))->setData(QVariant::fromValue(TimeDelta::fromHours(12)));
+ expirePresetsMenu->addAction(tr("%n hour(s)", "", 24))->setData(QVariant::fromValue(TimeDelta::fromHours(24)));
expirePresetsMenu->addSeparator();
- expirePresetsMenu->addAction(tr("%n week(s)", nullptr, 1))->setData(QVariant::fromValue(TimeDelta::fromDays(7)));
- expirePresetsMenu->addAction(tr("%n week(s)", nullptr, 2))->setData(QVariant::fromValue(TimeDelta::fromDays(14)));
- expirePresetsMenu->addAction(tr("%n week(s)", nullptr, 3))->setData(QVariant::fromValue(TimeDelta::fromDays(21)));
+ expirePresetsMenu->addAction(tr("%n week(s)", "", 1))->setData(QVariant::fromValue(TimeDelta::fromDays(7)));
+ expirePresetsMenu->addAction(tr("%n week(s)", "", 2))->setData(QVariant::fromValue(TimeDelta::fromDays(14)));
+ expirePresetsMenu->addAction(tr("%n week(s)", "", 3))->setData(QVariant::fromValue(TimeDelta::fromDays(21)));
expirePresetsMenu->addSeparator();
- expirePresetsMenu->addAction(tr("%n month(s)", nullptr, 1))->setData(QVariant::fromValue(TimeDelta::fromMonths(1)));
- expirePresetsMenu->addAction(tr("%n month(s)", nullptr, 2))->setData(QVariant::fromValue(TimeDelta::fromMonths(2)));
- expirePresetsMenu->addAction(tr("%n month(s)", nullptr, 3))->setData(QVariant::fromValue(TimeDelta::fromMonths(3)));
- expirePresetsMenu->addAction(tr("%n month(s)", nullptr, 6))->setData(QVariant::fromValue(TimeDelta::fromMonths(6)));
+ expirePresetsMenu->addAction(tr("%n month(s)", "", 1))->setData(QVariant::fromValue(TimeDelta::fromMonths(1)));
+ expirePresetsMenu->addAction(tr("%n month(s)", "", 2))->setData(QVariant::fromValue(TimeDelta::fromMonths(2)));
+ expirePresetsMenu->addAction(tr("%n month(s)", "", 3))->setData(QVariant::fromValue(TimeDelta::fromMonths(3)));
+ expirePresetsMenu->addAction(tr("%n month(s)", "", 6))->setData(QVariant::fromValue(TimeDelta::fromMonths(6)));
expirePresetsMenu->addSeparator();
- expirePresetsMenu->addAction(tr("%n year(s)", nullptr, 1))->setData(QVariant::fromValue(TimeDelta::fromYears(1)));
- expirePresetsMenu->addAction(tr("%n year(s)", nullptr, 2))->setData(QVariant::fromValue(TimeDelta::fromYears(2)));
- expirePresetsMenu->addAction(tr("%n year(s)", nullptr, 3))->setData(QVariant::fromValue(TimeDelta::fromYears(3)));
+ expirePresetsMenu->addAction(tr("%n year(s)", "", 1))->setData(QVariant::fromValue(TimeDelta::fromYears(1)));
+ expirePresetsMenu->addAction(tr("%n year(s)", "", 2))->setData(QVariant::fromValue(TimeDelta::fromYears(2)));
+ expirePresetsMenu->addAction(tr("%n year(s)", "", 3))->setData(QVariant::fromValue(TimeDelta::fromYears(3)));
return expirePresetsMenu;
}
diff --git a/src/gui/entry/EntryView.cpp b/src/gui/entry/EntryView.cpp
index 74dd2a60f..bacf0c05f 100644
--- a/src/gui/entry/EntryView.cpp
+++ b/src/gui/entry/EntryView.cpp
@@ -548,7 +548,7 @@ void EntryView::startDrag(Qt::DropActions supportedActions)
for (auto& index : selectedIndexes) {
if (++i > 4) {
int remaining = selectedIndexes.size() - i + 1;
- listWidget.addItem(tr("+ %1 entry(s)...", nullptr, remaining).arg(remaining));
+ listWidget.addItem(tr("+ %1 entry(s)...", "", remaining).arg(remaining));
break;
}
diff --git a/src/gui/export/ExportDialog.cpp b/src/gui/export/ExportDialog.cpp
index 4c2c2e6b5..31d3b480b 100644
--- a/src/gui/export/ExportDialog.cpp
+++ b/src/gui/export/ExportDialog.cpp
@@ -55,8 +55,10 @@ QString ExportDialog::getStrategyName(ExportSortingStrategy strategy)
return tr("name (ascending)");
case ExportSortingStrategy::BY_NAME_DESC:
return tr("name (descending)");
+ default:
+ Q_ASSERT(false);
+ return tr("invalid sort order");
}
- return tr("unknown");
}
void ExportDialog::exportDatabase()
diff --git a/src/gui/passkeys/PasskeyExporter.cpp b/src/gui/passkeys/PasskeyExporter.cpp
index 4ff84e5f8..5d0b0c586 100644
--- a/src/gui/passkeys/PasskeyExporter.cpp
+++ b/src/gui/passkeys/PasskeyExporter.cpp
@@ -76,7 +76,7 @@ void PasskeyExporter::exportSelectedEntry(const Entry* entry, const QString& fol
const auto fullPath = QString("%1/%2.passkey").arg(folder, Tools::cleanFilename(entry->title()));
if (QFile::exists(fullPath)) {
auto dialogResult = MessageBox::warning(m_parent,
- tr("KeePassXC: Passkey Export"),
+ tr("Overwrite Existing File?"),
tr("File \"%1.passkey\" already exists.\n"
"Do you want to overwrite it?\n")
.arg(entry->title()),
diff --git a/src/gui/passkeys/PasskeyImporter.cpp b/src/gui/passkeys/PasskeyImporter.cpp
index df4042069..f55751740 100644
--- a/src/gui/passkeys/PasskeyImporter.cpp
+++ b/src/gui/passkeys/PasskeyImporter.cpp
@@ -39,7 +39,7 @@ void PasskeyImporter::importPasskey(QSharedPointer& database, Entry* e
{
auto filter = QString("%1 (*.passkey);;%2 (*)").arg(tr("Passkey file"), tr("All files"));
auto fileName =
- fileDialog()->getOpenFileName(m_parent, tr("Open passkey file"), FileDialog::getLastDir("passkey"), filter);
+ fileDialog()->getOpenFileName(m_parent, tr("Open Passkey File"), FileDialog::getLastDir("passkey"), filter);
if (fileName.isEmpty()) {
return;
}
@@ -62,7 +62,7 @@ void PasskeyImporter::importSelectedFile(QFile& file, QSharedPointer&
const auto passkeyObject = browserMessageBuilder()->getJsonObject(fileData);
if (passkeyObject.isEmpty()) {
MessageBox::information(m_parent,
- tr("Cannot import passkey"),
+ tr("Passkey Import Failed"),
tr("Cannot import passkey file \"%1\". Data is missing.").arg(file.fileName()));
return;
}
@@ -73,14 +73,14 @@ void PasskeyImporter::importSelectedFile(QFile& file, QSharedPointer&
QStringList() << "relyingParty" << "url" << "username" << "credentialId" << "userHandle" << "privateKey");
if (!missingKeys.isEmpty()) {
MessageBox::information(m_parent,
- tr("Cannot import passkey"),
+ tr("Passkey Import Failed"),
tr("Cannot import passkey file \"%1\".\nThe following data is missing:\n%2")
.arg(file.fileName(), missingKeys.join(", ")));
} else if (!privateKey.startsWith(EntryAttributes::KPEX_PASSKEY_PRIVATE_KEY_START)
|| !privateKey.trimmed().endsWith(EntryAttributes::KPEX_PASSKEY_PRIVATE_KEY_END)) {
MessageBox::information(
m_parent,
- tr("Cannot import passkey"),
+ tr("Passkey Import Failed"),
tr("Cannot import passkey file \"%1\". Private key is missing or malformed.").arg(file.fileName()));
} else {
const auto relyingParty = passkeyObject["relyingParty"].toString();
diff --git a/src/gui/reports/ReportsWidgetStatistics.cpp b/src/gui/reports/ReportsWidgetStatistics.cpp
index 2f1759cd7..0aced6ae5 100644
--- a/src/gui/reports/ReportsWidgetStatistics.cpp
+++ b/src/gui/reports/ReportsWidgetStatistics.cpp
@@ -122,7 +122,7 @@ void ReportsWidgetStatistics::calculateStats()
tr("Excluding entries from reports, e. g. because they are known to have a poor password, isn't "
"necessarily a problem but you should keep an eye on them."));
addStatsRow(tr("Average password length"),
- tr("%1 characters").arg(stats->averagePwdLength()),
+ tr("%1 character(s)", "", stats->averagePwdLength()).arg(stats->averagePwdLength()),
stats->isAvgPwdTooShort(),
tr("Average password length is less than ten characters. Longer passwords provide more security."));
}
diff --git a/src/keys/drivers/YubiKey.cpp b/src/keys/drivers/YubiKey.cpp
index c07bcc072..dfc4b6b13 100644
--- a/src/keys/drivers/YubiKey.cpp
+++ b/src/keys/drivers/YubiKey.cpp
@@ -43,7 +43,7 @@ YubiKey::YubiKey()
connect(YubiKeyInterfacePCSC::instance(), SIGNAL(challengeStarted()), this, SIGNAL(challengeStarted()));
connect(YubiKeyInterfacePCSC::instance(), SIGNAL(challengeCompleted()), this, SIGNAL(challengeCompleted()));
} else {
- qDebug("YubiKey: PCSC interface is disabled or not initialized.");
+ qDebug("YubiKey: PC/SC interface is disabled or not initialized.");
}
m_initialized = num_interfaces > 0;
diff --git a/src/keys/drivers/YubiKeyInterfacePCSC.cpp b/src/keys/drivers/YubiKeyInterfacePCSC.cpp
index 765d3d0d8..6cec11b1a 100644
--- a/src/keys/drivers/YubiKeyInterfacePCSC.cpp
+++ b/src/keys/drivers/YubiKeyInterfacePCSC.cpp
@@ -519,7 +519,7 @@ YubiKeyInterfacePCSC::YubiKeyInterfacePCSC()
: YubiKeyInterface()
{
if (ensureValidContext(m_sc_context) != SCARD_S_SUCCESS) {
- qDebug("YubiKey: Failed to establish PCSC context.");
+ qDebug("YubiKey: Failed to establish PC/SC context.");
} else {
m_initialized = true;
}
@@ -528,7 +528,7 @@ YubiKeyInterfacePCSC::YubiKeyInterfacePCSC()
YubiKeyInterfacePCSC::~YubiKeyInterfacePCSC()
{
if (m_initialized && SCardReleaseContext(m_sc_context) != SCARD_S_SUCCESS) {
- qDebug("YubiKey: Failed to release PCSC context.");
+ qDebug("YubiKey: Failed to release PC/SC context.");
}
}
@@ -678,7 +678,7 @@ YubiKeyInterfacePCSC::challenge(YubiKeySlot slot, const QByteArray& challenge, B
{
m_error.clear();
if (!m_initialized) {
- m_error = tr("The YubiKey PCSC interface has not been initialized.");
+ m_error = tr("The YubiKey PC/SC interface has not been initialized.");
return YubiKey::ChallengeResult::YCR_ERROR;
}
@@ -762,7 +762,7 @@ YubiKey::ChallengeResult YubiKeyInterfacePCSC::performChallenge(void* key,
m_error = tr("Hardware key was not found or is not configured.");
} else {
m_error =
- tr("Failed to complete a challenge-response, the PCSC error code was: %1").arg(QString::number(rv));
+ tr("Failed to complete a challenge-response, the PC/SC error code was: %1").arg(QString::number(rv));
}
return YubiKey::ChallengeResult::YCR_ERROR;
diff --git a/src/keys/drivers/YubiKeyInterfaceUSB.cpp b/src/keys/drivers/YubiKeyInterfaceUSB.cpp
index a39b39dce..dba27d370 100644
--- a/src/keys/drivers/YubiKeyInterfaceUSB.cpp
+++ b/src/keys/drivers/YubiKeyInterfaceUSB.cpp
@@ -144,7 +144,7 @@ YubiKey::KeyMap YubiKeyInterfaceUSB::findValidKeys(int& connectedKeys)
int vid, pid;
yk_get_key_vid_pid(yk_key.get(), &vid, &pid);
- QString name = m_pid_names.value(pid, tr("Unknown"));
+ QString name = m_pid_names.value(pid, tr("Unknown", "Unknown hardware key name"));
if (vid == ONLYKEY_VID) {
name = QStringLiteral("OnlyKey %ver");
}
diff --git a/tests/TestCli.cpp b/tests/TestCli.cpp
index e70b7b2df..c23b62cbd 100644
--- a/tests/TestCli.cpp
+++ b/tests/TestCli.cpp
@@ -1026,7 +1026,7 @@ void TestCli::testInfo()
QCOMPARE(m_stdout->readLine(), QByteArray("Number of short passwords: 0\n"));
QCOMPARE(m_stdout->readLine(), QByteArray("Number of weak passwords: 2\n"));
QCOMPARE(m_stdout->readLine(), QByteArray("Entries excluded from reports: 0\n"));
- QCOMPARE(m_stdout->readLine(), QByteArray("Average password length: 11 characters\n"));
+ QCOMPARE(m_stdout->readLine(), QByteArray("Average password length: 11 character(s)\n"));
// Test with quiet option.
setInput("a");