Fix all Qt 5.15 deprecation warnings (#7783)

* Deprecated qSort() -> std::sort()
* Replace QDateTime::toString(Qt::DefaultLocaleShortDate) with Clock::toString()
* Replace QDateTime::toString(Qt::SystemLocaleShortDate) with QLocale::system().toString(..., QLocale::ShortFormat)
* Use QDateTime::startOfDay() instead of QDate(QDateTime) 
  Note: QDateTime::startOfDay() is only available in Qt 5.14, we need to guard it
* Replace QString::SkipEmptyParts with Qt::SkipEmptyParts
  Note: Its designated replacement, Qt::SplitBehavior, was only added in Qt 5.14.
* Don't call deprecated QFlags(nullptr) constructor
* QSet::{toList->values}
* Replace QList::toSet, QSet::fromList with Tools::asSet()
* QHash::insertMulti -> QMultiHash::insert
* QProcess::startDetached: non-deprecated overload
* QProcess::{pid->processId}
* QPainter::{HighQuality->}Antialiasing
* QPalette::{background->window}()
* Use Qt::{Background,Foreground}Role
* endl -> Qt::endl, flush -> Qt::flush
* Make YubiKey::s_interfaceMutex non-recursive
* OpenSSHKeyGenDialog: use non-deprecated QComboBox::sizeAdjustPolicy setting
This commit is contained in:
Carlo Teubner 2024-06-22 12:22:44 +01:00 committed by GitHub
parent 5bf5b93836
commit 88b76244cf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
67 changed files with 341 additions and 240 deletions

View file

@ -29,6 +29,7 @@
#include "autotype/AutoTypePlatformPlugin.h" #include "autotype/AutoTypePlatformPlugin.h"
#include "autotype/AutoTypeSelectDialog.h" #include "autotype/AutoTypeSelectDialog.h"
#include "autotype/PickcharsDialog.h" #include "autotype/PickcharsDialog.h"
#include "core/Global.h"
#include "core/Resources.h" #include "core/Resources.h"
#include "core/Tools.h" #include "core/Tools.h"
#include "gui/MainWindow.h" #include "gui/MainWindow.h"
@ -460,7 +461,7 @@ void AutoType::performGlobalAutoType(const QList<QSharedPointer<Database>>& dbLi
if (hideExpired && entry->isExpired()) { if (hideExpired && entry->isExpired()) {
continue; continue;
} }
auto sequences = entry->autoTypeSequences(m_windowTitleForGlobal).toSet(); const QSet<QString> sequences = Tools::asSet(entry->autoTypeSequences(m_windowTitleForGlobal));
for (const auto& sequence : sequences) { for (const auto& sequence : sequences) {
matchList << AutoTypeMatch(entry, sequence); matchList << AutoTypeMatch(entry, sequence);
} }

View file

@ -19,6 +19,7 @@
#include "BrowserEntryConfig.h" #include "BrowserEntryConfig.h"
#include "core/Entry.h" #include "core/Entry.h"
#include "core/Global.h"
#include "core/Tools.h" #include "core/Tools.h"
#include <QJsonDocument> #include <QJsonDocument>
@ -34,22 +35,22 @@ BrowserEntryConfig::BrowserEntryConfig(QObject* parent)
QStringList BrowserEntryConfig::allowedHosts() const QStringList BrowserEntryConfig::allowedHosts() const
{ {
return m_allowedHosts.toList(); return m_allowedHosts.values();
} }
void BrowserEntryConfig::setAllowedHosts(const QStringList& allowedHosts) void BrowserEntryConfig::setAllowedHosts(const QStringList& allowedHosts)
{ {
m_allowedHosts = allowedHosts.toSet(); m_allowedHosts = Tools::asSet(allowedHosts);
} }
QStringList BrowserEntryConfig::deniedHosts() const QStringList BrowserEntryConfig::deniedHosts() const
{ {
return m_deniedHosts.toList(); return m_deniedHosts.values();
} }
void BrowserEntryConfig::setDeniedHosts(const QStringList& deniedHosts) void BrowserEntryConfig::setDeniedHosts(const QStringList& deniedHosts)
{ {
m_deniedHosts = deniedHosts.toSet(); m_deniedHosts = Tools::asSet(deniedHosts);
} }
bool BrowserEntryConfig::isAllowed(const QString& host) const bool BrowserEntryConfig::isAllowed(const QString& host) const

View file

@ -48,6 +48,7 @@
#include <QJsonObject> #include <QJsonObject>
#include <QListWidget> #include <QListWidget>
#include <QLocalSocket> #include <QLocalSocket>
#include <QLocale>
#include <QProgressDialog> #include <QProgressDialog>
#include <QUrl> #include <QUrl>
@ -601,7 +602,7 @@ QString BrowserService::storeKey(const QString& key)
hideWindow(); hideWindow();
db->metadata()->customData()->set(CustomData::BrowserKeyPrefix + id, key); db->metadata()->customData()->set(CustomData::BrowserKeyPrefix + id, key);
db->metadata()->customData()->set(QString("%1_%2").arg(CustomData::Created, id), db->metadata()->customData()->set(QString("%1_%2").arg(CustomData::Created, id),
Clock::currentDateTime().toString(Qt::SystemLocaleShortDate)); QLocale::system().toString(Clock::currentDateTime(), QLocale::ShortFormat));
return id; return id;
} }

View file

@ -19,6 +19,7 @@
#include "Generate.h" #include "Generate.h"
#include "Utils.h" #include "Utils.h"
#include "core/Global.h"
#include "core/Group.h" #include "core/Group.h"
#include "core/PasswordGenerator.h" #include "core/PasswordGenerator.h"
@ -78,7 +79,7 @@ int Add::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<Q
// Cannot use those 2 options at the same time! // Cannot use those 2 options at the same time!
if (parser->isSet(Add::GenerateOption) && parser->isSet(Add::PasswordPromptOption)) { if (parser->isSet(Add::GenerateOption) && parser->isSet(Add::PasswordPromptOption)) {
err << QObject::tr("Cannot generate a password and prompt at the same time.") << endl; err << QObject::tr("Cannot generate a password and prompt at the same time.") << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -94,7 +95,7 @@ int Add::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<Q
Entry* entry = database->rootGroup()->addEntryWithPath(entryPath); Entry* entry = database->rootGroup()->addEntryWithPath(entryPath);
if (!entry) { if (!entry) {
err << QObject::tr("Could not create entry with path %1.").arg(entryPath) << endl; err << QObject::tr("Could not create entry with path %1.").arg(entryPath) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -112,7 +113,7 @@ int Add::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<Q
if (parser->isSet(Add::PasswordPromptOption)) { if (parser->isSet(Add::PasswordPromptOption)) {
if (!parser->isSet(Command::QuietOption)) { if (!parser->isSet(Command::QuietOption)) {
out << QObject::tr("Enter password for new entry: ") << flush; out << QObject::tr("Enter password for new entry: ") << Qt::flush;
} }
QString password = Utils::getPassword(parser->isSet(Command::QuietOption)); QString password = Utils::getPassword(parser->isSet(Command::QuietOption));
entry->setPassword(password); entry->setPassword(password);
@ -123,12 +124,12 @@ int Add::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<Q
QString errorMessage; QString errorMessage;
if (!database->save(Database::Atomic, {}, &errorMessage)) { if (!database->save(Database::Atomic, {}, &errorMessage)) {
err << QObject::tr("Writing the database failed %1.").arg(errorMessage) << endl; err << QObject::tr("Writing the database failed %1.").arg(errorMessage) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (!parser->isSet(Command::QuietOption)) { if (!parser->isSet(Command::QuietOption)) {
out << QObject::tr("Successfully added entry %1.").arg(entry->title()) << endl; out << QObject::tr("Successfully added entry %1.").arg(entry->title()) << Qt::endl;
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View file

@ -18,6 +18,7 @@
#include "AddGroup.h" #include "AddGroup.h"
#include "Utils.h" #include "Utils.h"
#include "core/Global.h"
#include "core/Group.h" #include "core/Group.h"
#include <QCommandLineParser> #include <QCommandLineParser>
@ -45,13 +46,13 @@ int AddGroup::executeWithDatabase(QSharedPointer<Database> database, QSharedPoin
Group* group = database->rootGroup()->findGroupByPath(groupPath); Group* group = database->rootGroup()->findGroupByPath(groupPath);
if (group) { if (group) {
err << QObject::tr("Group %1 already exists!").arg(groupPath) << endl; err << QObject::tr("Group %1 already exists!").arg(groupPath) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
Group* parentGroup = database->rootGroup()->findGroupByPath(parentGroupPath); Group* parentGroup = database->rootGroup()->findGroupByPath(parentGroupPath);
if (!parentGroup) { if (!parentGroup) {
err << QObject::tr("Group %1 not found.").arg(parentGroupPath) << endl; err << QObject::tr("Group %1 not found.").arg(parentGroupPath) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -62,12 +63,12 @@ int AddGroup::executeWithDatabase(QSharedPointer<Database> database, QSharedPoin
QString errorMessage; QString errorMessage;
if (!database->save(Database::Atomic, {}, &errorMessage)) { if (!database->save(Database::Atomic, {}, &errorMessage)) {
err << QObject::tr("Writing the database failed %1.").arg(errorMessage) << endl; err << QObject::tr("Writing the database failed %1.").arg(errorMessage) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (!parser->isSet(Command::QuietOption)) { if (!parser->isSet(Command::QuietOption)) {
out << QObject::tr("Successfully added group %1.").arg(groupName) << endl; out << QObject::tr("Successfully added group %1.").arg(groupName) << Qt::endl;
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View file

@ -18,6 +18,7 @@
#include "Analyze.h" #include "Analyze.h"
#include "Utils.h" #include "Utils.h"
#include "core/Global.h"
#include "core/Group.h" #include "core/Group.h"
#include "core/HibpOffline.h" #include "core/HibpOffline.h"
@ -60,23 +61,24 @@ int Analyze::executeWithDatabase(QSharedPointer<Database> database, QSharedPoint
auto okon = parser->value(Analyze::OkonOption); auto okon = parser->value(Analyze::OkonOption);
if (!okon.isEmpty()) { if (!okon.isEmpty()) {
out << QObject::tr("Evaluating database entries using okon…") << endl; out << QObject::tr("Evaluating database entries using okon…") << Qt::endl;
if (!HibpOffline::okonReport(database, okon, hibpDatabase, findings, &error)) { if (!HibpOffline::okonReport(database, okon, hibpDatabase, findings, &error)) {
err << error << endl; err << error << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} else { } else {
QFile hibpFile(hibpDatabase); QFile hibpFile(hibpDatabase);
if (!hibpFile.open(QFile::ReadOnly)) { if (!hibpFile.open(QFile::ReadOnly)) {
err << QObject::tr("Failed to open HIBP file %1: %2").arg(hibpDatabase).arg(hibpFile.errorString()) << endl; err << QObject::tr("Failed to open HIBP file %1: %2").arg(hibpDatabase).arg(hibpFile.errorString())
<< Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
out << QObject::tr("Evaluating database entries against HIBP file, this will take a while…") << endl; out << QObject::tr("Evaluating database entries against HIBP file, this will take a while…") << Qt::endl;
if (!HibpOffline::report(database, hibpFile, findings, &error)) { if (!HibpOffline::report(database, hibpFile, findings, &error)) {
err << error << endl; err << error << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} }
@ -91,9 +93,10 @@ int Analyze::executeWithDatabase(QSharedPointer<Database> database, QSharedPoint
} }
if (count > 0) { if (count > 0) {
out << QObject::tr("Password for '%1' has been leaked %2 time(s)!", "", count).arg(path).arg(count) << endl; out << QObject::tr("Password for '%1' has been leaked %2 time(s)!", "", count).arg(path).arg(count)
<< Qt::endl;
} else { } else {
out << QObject::tr("Password for '%1' has been leaked!").arg(path) << endl; out << QObject::tr("Password for '%1' has been leaked!").arg(path) << Qt::endl;
} }
} }

View file

@ -18,6 +18,7 @@
#include "AttachmentExport.h" #include "AttachmentExport.h"
#include "Utils.h" #include "Utils.h"
#include "core/Global.h"
#include "core/Group.h" #include "core/Group.h"
#include <QCommandLineParser> #include <QCommandLineParser>
@ -49,7 +50,7 @@ int AttachmentExport::executeWithDatabase(QSharedPointer<Database> database, QSh
auto entry = database->rootGroup()->findEntryByPath(entryPath); auto entry = database->rootGroup()->findEntryByPath(entryPath);
if (!entry) { if (!entry) {
err << QObject::tr("Could not find entry with path %1.").arg(entryPath) << endl; err << QObject::tr("Could not find entry with path %1.").arg(entryPath) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -57,32 +58,32 @@ int AttachmentExport::executeWithDatabase(QSharedPointer<Database> database, QSh
auto attachments = entry->attachments(); auto attachments = entry->attachments();
if (!attachments->hasKey(attachmentName)) { if (!attachments->hasKey(attachmentName)) {
err << QObject::tr("Could not find attachment with name %1.").arg(attachmentName) << endl; err << QObject::tr("Could not find attachment with name %1.").arg(attachmentName) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (parser->isSet(AttachmentExport::StdoutOption)) { if (parser->isSet(AttachmentExport::StdoutOption)) {
// Output to STDOUT even in quiet mode // Output to STDOUT even in quiet mode
Utils::STDOUT << attachments->value(attachmentName) << flush; Utils::STDOUT << attachments->value(attachmentName) << Qt::flush;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
if (args.size() < 4) { if (args.size() < 4) {
err << QObject::tr("No export target given. Please use '--stdout' or specify an 'export-file'.") << endl; err << QObject::tr("No export target given. Please use '--stdout' or specify an 'export-file'.") << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
auto exportFileName = args.at(3); auto exportFileName = args.at(3);
QFile exportFile(exportFileName); QFile exportFile(exportFileName);
if (!exportFile.open(QIODevice::WriteOnly)) { if (!exportFile.open(QIODevice::WriteOnly)) {
err << QObject::tr("Could not open output file %1.").arg(exportFileName) << endl; err << QObject::tr("Could not open output file %1.").arg(exportFileName) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
exportFile.write(attachments->value(attachmentName)); exportFile.write(attachments->value(attachmentName));
out << QObject::tr("Successfully exported attachment %1 of entry %2 to %3.") out << QObject::tr("Successfully exported attachment %1 of entry %2 to %3.")
.arg(attachmentName, entryPath, exportFileName) .arg(attachmentName, entryPath, exportFileName)
<< endl; << Qt::endl;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View file

@ -18,6 +18,7 @@
#include "AttachmentImport.h" #include "AttachmentImport.h"
#include "Utils.h" #include "Utils.h"
#include "core/Global.h"
#include "core/Group.h" #include "core/Group.h"
#include <QCommandLineParser> #include <QCommandLineParser>
@ -50,7 +51,7 @@ int AttachmentImport::executeWithDatabase(QSharedPointer<Database> database, QSh
auto entry = database->rootGroup()->findEntryByPath(entryPath); auto entry = database->rootGroup()->findEntryByPath(entryPath);
if (!entry) { if (!entry) {
err << QObject::tr("Could not find entry with path %1.").arg(entryPath) << endl; err << QObject::tr("Could not find entry with path %1.").arg(entryPath) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -58,7 +59,7 @@ int AttachmentImport::executeWithDatabase(QSharedPointer<Database> database, QSh
auto attachments = entry->attachments(); auto attachments = entry->attachments();
if (attachments->hasKey(attachmentName) && !parser->isSet(AttachmentImport::ForceOption)) { if (attachments->hasKey(attachmentName) && !parser->isSet(AttachmentImport::ForceOption)) {
err << QObject::tr("Attachment %1 already exists for entry %2.").arg(attachmentName, entryPath) << endl; err << QObject::tr("Attachment %1 already exists for entry %2.").arg(attachmentName, entryPath) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -66,7 +67,7 @@ int AttachmentImport::executeWithDatabase(QSharedPointer<Database> database, QSh
QFile importFile(importFileName); QFile importFile(importFileName);
if (!importFile.open(QIODevice::ReadOnly)) { if (!importFile.open(QIODevice::ReadOnly)) {
err << QObject::tr("Could not open attachment file %1.").arg(importFileName) << endl; err << QObject::tr("Could not open attachment file %1.").arg(importFileName) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -76,12 +77,12 @@ int AttachmentImport::executeWithDatabase(QSharedPointer<Database> database, QSh
QString errorMessage; QString errorMessage;
if (!database->save(Database::Atomic, {}, &errorMessage)) { if (!database->save(Database::Atomic, {}, &errorMessage)) {
err << QObject::tr("Writing the database failed %1.").arg(errorMessage) << endl; err << QObject::tr("Writing the database failed %1.").arg(errorMessage) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
out << QObject::tr("Successfully imported attachment %1 as %2 to entry %3.") out << QObject::tr("Successfully imported attachment %1 as %2 to entry %3.")
.arg(importFileName, attachmentName, entryPath) .arg(importFileName, attachmentName, entryPath)
<< endl; << Qt::endl;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View file

@ -18,6 +18,7 @@
#include "AttachmentRemove.h" #include "AttachmentRemove.h"
#include "Utils.h" #include "Utils.h"
#include "core/Global.h"
#include "core/Group.h" #include "core/Group.h"
#include <QCommandLineParser> #include <QCommandLineParser>
@ -41,7 +42,7 @@ int AttachmentRemove::executeWithDatabase(QSharedPointer<Database> database, QSh
auto entry = database->rootGroup()->findEntryByPath(entryPath); auto entry = database->rootGroup()->findEntryByPath(entryPath);
if (!entry) { if (!entry) {
err << QObject::tr("Could not find entry with path %1.").arg(entryPath) << endl; err << QObject::tr("Could not find entry with path %1.").arg(entryPath) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -49,7 +50,7 @@ int AttachmentRemove::executeWithDatabase(QSharedPointer<Database> database, QSh
auto attachments = entry->attachments(); auto attachments = entry->attachments();
if (!attachments->hasKey(attachmentName)) { if (!attachments->hasKey(attachmentName)) {
err << QObject::tr("Could not find attachment with name %1.").arg(attachmentName) << endl; err << QObject::tr("Could not find attachment with name %1.").arg(attachmentName) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -59,10 +60,10 @@ int AttachmentRemove::executeWithDatabase(QSharedPointer<Database> database, QSh
QString errorMessage; QString errorMessage;
if (!database->save(Database::Atomic, {}, &errorMessage)) { if (!database->save(Database::Atomic, {}, &errorMessage)) {
err << QObject::tr("Writing the database failed %1.").arg(errorMessage) << endl; err << QObject::tr("Writing the database failed %1.").arg(errorMessage) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
out << QObject::tr("Successfully removed attachment %1 from entry %2.").arg(attachmentName, entryPath) << endl; out << QObject::tr("Successfully removed attachment %1 from entry %2.").arg(attachmentName, entryPath) << Qt::endl;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View file

@ -72,7 +72,7 @@ int Clip::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
bool ok; bool ok;
timeout = args.at(2).toInt(&ok); timeout = args.at(2).toInt(&ok);
if (!ok) { if (!ok) {
err << QObject::tr("Invalid timeout value %1.").arg(args.at(2)) << endl; err << QObject::tr("Invalid timeout value %1.").arg(args.at(2)) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} }
@ -83,14 +83,14 @@ int Clip::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
const auto& searchTerm = args.at(1); const auto& searchTerm = args.at(1);
const auto results = searcher.search(QString("title:%1").arg(searchTerm), database->rootGroup(), true); const auto results = searcher.search(QString("title:%1").arg(searchTerm), database->rootGroup(), true);
if (results.count() > 1) { if (results.count() > 1) {
err << QObject::tr("Multiple entries matching:") << endl; err << QObject::tr("Multiple entries matching:") << Qt::endl;
for (const Entry* result : results) { for (const Entry* result : results) {
err << result->path().prepend('/') << endl; err << result->path().prepend('/') << Qt::endl;
} }
return EXIT_FAILURE; return EXIT_FAILURE;
} else { } else {
entryPath = (results.isEmpty()) ? searchTerm : results[0]->path().prepend('/'); entryPath = (results.isEmpty()) ? searchTerm : results[0]->path().prepend('/');
out << QObject::tr("Using matching entry: %1").arg(entryPath) << endl; out << QObject::tr("Using matching entry: %1").arg(entryPath) << Qt::endl;
} }
} else { } else {
entryPath = args.at(1); entryPath = args.at(1);
@ -98,12 +98,12 @@ int Clip::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
auto* entry = database->rootGroup()->findEntryByPath(entryPath); auto* entry = database->rootGroup()->findEntryByPath(entryPath);
if (!entry) { if (!entry) {
err << QObject::tr("Entry %1 not found.").arg(entryPath) << endl; err << QObject::tr("Entry %1 not found.").arg(entryPath) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (parser->isSet(AttributeOption) && parser->isSet(TotpOption)) { if (parser->isSet(AttributeOption) && parser->isSet(TotpOption)) {
err << QObject::tr("ERROR: Please specify one of --attribute or --totp, not both.") << endl; err << QObject::tr("ERROR: Please specify one of --attribute or --totp, not both.") << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -112,7 +112,7 @@ int Clip::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
bool found = false; bool found = false;
if (parser->isSet(TotpOption) || selectedAttribute == "totp") { if (parser->isSet(TotpOption) || selectedAttribute == "totp") {
if (!entry->hasTotp()) { if (!entry->hasTotp()) {
err << QObject::tr("Entry with path %1 has no TOTP set up.").arg(entryPath) << endl; err << QObject::tr("Entry with path %1 has no TOTP set up.").arg(entryPath) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -127,7 +127,7 @@ int Clip::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
if (attrs.size() > 1) { if (attrs.size() > 1) {
err << QObject::tr("ERROR: attribute %1 is ambiguous, it matches %2.") err << QObject::tr("ERROR: attribute %1 is ambiguous, it matches %2.")
.arg(selectedAttribute, QLocale().createSeparatedList(attrs)) .arg(selectedAttribute, QLocale().createSeparatedList(attrs))
<< endl; << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} else if (attrs.size() == 1) { } else if (attrs.size() == 1) {
found = true; found = true;
@ -137,7 +137,7 @@ int Clip::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
} }
if (!found) { if (!found) {
out << QObject::tr("Attribute \"%1\" not found.").arg(selectedAttribute) << endl; out << QObject::tr("Attribute \"%1\" not found.").arg(selectedAttribute) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -146,7 +146,7 @@ int Clip::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
return exitCode; return exitCode;
} }
out << QObject::tr("Entry's \"%1\" attribute copied to the clipboard!").arg(selectedAttribute) << endl; out << QObject::tr("Entry's \"%1\" attribute copied to the clipboard!").arg(selectedAttribute) << Qt::endl;
if (timeout <= 0) { if (timeout <= 0) {
return exitCode; return exitCode;
@ -156,13 +156,13 @@ int Clip::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
while (timeout > 0) { while (timeout > 0) {
out << '\r' << QString(lastLine.size(), ' ') << '\r'; out << '\r' << QString(lastLine.size(), ' ') << '\r';
lastLine = QObject::tr("Clearing the clipboard in %1 second(s)...", "", timeout).arg(timeout); lastLine = QObject::tr("Clearing the clipboard in %1 second(s)...", "", timeout).arg(timeout);
out << lastLine << flush; out << lastLine << Qt::flush;
Tools::sleep(1000); Tools::sleep(1000);
--timeout; --timeout;
} }
Utils::clipText(""); Utils::clipText("");
out << '\r' << QString(lastLine.size(), ' ') << '\r'; out << '\r' << QString(lastLine.size(), ' ') << '\r';
out << QObject::tr("Clipboard cleared!") << endl; out << QObject::tr("Clipboard cleared!") << Qt::endl;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View file

@ -18,6 +18,7 @@
#include "DatabaseCreate.h" #include "DatabaseCreate.h"
#include "Utils.h" #include "Utils.h"
#include "core/Global.h"
#include "keys/FileKey.h" #include "keys/FileKey.h"
#include <QCommandLineParser> #include <QCommandLineParser>
@ -70,13 +71,13 @@ QSharedPointer<Database> DatabaseCreate::initializeDatabaseFromOptions(const QSh
if (decryptionTimeValue.length() != 0) { if (decryptionTimeValue.length() != 0) {
decryptionTime = decryptionTimeValue.toInt(); decryptionTime = decryptionTimeValue.toInt();
if (decryptionTime <= 0) { if (decryptionTime <= 0) {
err << QObject::tr("Invalid decryption time %1.").arg(decryptionTimeValue) << endl; err << QObject::tr("Invalid decryption time %1.").arg(decryptionTimeValue) << Qt::endl;
return {}; return {};
} }
if (decryptionTime < Kdf::MIN_ENCRYPTION_TIME || decryptionTime > Kdf::MAX_ENCRYPTION_TIME) { if (decryptionTime < Kdf::MIN_ENCRYPTION_TIME || decryptionTime > Kdf::MAX_ENCRYPTION_TIME) {
err << QObject::tr("Target decryption time must be between %1 and %2.") err << QObject::tr("Target decryption time must be between %1 and %2.")
.arg(QString::number(Kdf::MIN_ENCRYPTION_TIME), QString::number(Kdf::MAX_ENCRYPTION_TIME)) .arg(QString::number(Kdf::MIN_ENCRYPTION_TIME), QString::number(Kdf::MAX_ENCRYPTION_TIME))
<< endl; << Qt::endl;
return {}; return {};
} }
} }
@ -86,7 +87,7 @@ QSharedPointer<Database> DatabaseCreate::initializeDatabaseFromOptions(const QSh
if (parser->isSet(DatabaseCreate::SetPasswordOption)) { if (parser->isSet(DatabaseCreate::SetPasswordOption)) {
auto passwordKey = Utils::getConfirmedPassword(); auto passwordKey = Utils::getConfirmedPassword();
if (passwordKey.isNull()) { if (passwordKey.isNull()) {
err << QObject::tr("Failed to set database password.") << endl; err << QObject::tr("Failed to set database password.") << Qt::endl;
return {}; return {};
} }
key->addKey(passwordKey); key->addKey(passwordKey);
@ -104,7 +105,7 @@ QSharedPointer<Database> DatabaseCreate::initializeDatabaseFromOptions(const QSh
} }
if (!Utils::loadFileKey(keyFilePath, fileKey)) { if (!Utils::loadFileKey(keyFilePath, fileKey)) {
err << QObject::tr("Loading the key file failed") << endl; err << QObject::tr("Loading the key file failed") << Qt::endl;
return {}; return {};
} }
@ -114,7 +115,7 @@ QSharedPointer<Database> DatabaseCreate::initializeDatabaseFromOptions(const QSh
} }
if (key->isEmpty()) { if (key->isEmpty()) {
err << QObject::tr("No key is set. Aborting database creation.") << endl; err << QObject::tr("No key is set. Aborting database creation.") << Qt::endl;
return {}; return {};
} }
@ -125,15 +126,15 @@ QSharedPointer<Database> DatabaseCreate::initializeDatabaseFromOptions(const QSh
auto kdf = db->kdf(); auto kdf = db->kdf();
Q_ASSERT(kdf); Q_ASSERT(kdf);
out << QObject::tr("Benchmarking key derivation function for %1ms delay.").arg(decryptionTimeValue) << endl; out << QObject::tr("Benchmarking key derivation function for %1ms delay.").arg(decryptionTimeValue) << Qt::endl;
int rounds = kdf->benchmark(decryptionTime); int rounds = kdf->benchmark(decryptionTime);
out << QObject::tr("Setting %1 rounds for key derivation function.").arg(QString::number(rounds)) << endl; out << QObject::tr("Setting %1 rounds for key derivation function.").arg(QString::number(rounds)) << Qt::endl;
kdf->setRounds(rounds); kdf->setRounds(rounds);
bool ok = db->changeKdf(kdf); bool ok = db->changeKdf(kdf);
if (!ok) { if (!ok) {
err << QObject::tr("error while setting database key derivation settings.") << endl; err << QObject::tr("error while setting database key derivation settings.") << Qt::endl;
return {}; return {};
} }
} }
@ -168,7 +169,7 @@ int DatabaseCreate::execute(const QStringList& arguments)
const QString& databaseFilename = args.at(0); const QString& databaseFilename = args.at(0);
if (QFileInfo::exists(databaseFilename)) { if (QFileInfo::exists(databaseFilename)) {
err << QObject::tr("File %1 already exists.").arg(databaseFilename) << endl; err << QObject::tr("File %1 already exists.").arg(databaseFilename) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -179,10 +180,10 @@ int DatabaseCreate::execute(const QStringList& arguments)
QString errorMessage; QString errorMessage;
if (!db->saveAs(databaseFilename, Database::Atomic, {}, &errorMessage)) { if (!db->saveAs(databaseFilename, Database::Atomic, {}, &errorMessage)) {
err << QObject::tr("Failed to save the database: %1.").arg(errorMessage) << endl; err << QObject::tr("Failed to save the database: %1.").arg(errorMessage) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
out << QObject::tr("Successfully created new database.") << endl; out << QObject::tr("Successfully created new database.") << Qt::endl;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View file

@ -19,6 +19,7 @@
#include "Utils.h" #include "Utils.h"
#include "cli/DatabaseCreate.h" #include "cli/DatabaseCreate.h"
#include "core/Global.h"
#include "keys/ChallengeResponseKey.h" #include "keys/ChallengeResponseKey.h"
#include "keys/FileKey.h" #include "keys/FileKey.h"
#include "keys/PasswordKey.h" #include "keys/PasswordKey.h"
@ -53,7 +54,7 @@ int DatabaseEdit::executeWithDatabase(QSharedPointer<Database> database, QShared
err << QObject::tr("Cannot use %1 and %2 at the same time.") err << QObject::tr("Cannot use %1 and %2 at the same time.")
.arg(DatabaseCreate::SetPasswordOption.names().at(0)) .arg(DatabaseCreate::SetPasswordOption.names().at(0))
.arg(DatabaseEdit::UnsetPasswordOption.names().at(0)) .arg(DatabaseEdit::UnsetPasswordOption.names().at(0))
<< endl; << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -61,7 +62,7 @@ int DatabaseEdit::executeWithDatabase(QSharedPointer<Database> database, QShared
err << QObject::tr("Cannot use %1 and %2 at the same time.") err << QObject::tr("Cannot use %1 and %2 at the same time.")
.arg(DatabaseCreate::SetKeyFileOption.names().at(0)) .arg(DatabaseCreate::SetKeyFileOption.names().at(0))
.arg(DatabaseEdit::UnsetKeyFileOption.names().at(0)) .arg(DatabaseEdit::UnsetKeyFileOption.names().at(0))
<< endl; << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -76,7 +77,7 @@ int DatabaseEdit::executeWithDatabase(QSharedPointer<Database> database, QShared
parser->value(DatabaseCreate::SetKeyFileOption), parser->value(DatabaseCreate::SetKeyFileOption),
parser->isSet(DatabaseEdit::UnsetKeyFileOption)); parser->isSet(DatabaseEdit::UnsetKeyFileOption));
if (newDatabaseKey.isNull()) { if (newDatabaseKey.isNull()) {
err << QObject::tr("Could not change the database key.") << endl; err << QObject::tr("Could not change the database key.") << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
database->setKey(newDatabaseKey); database->setKey(newDatabaseKey);
@ -84,17 +85,17 @@ int DatabaseEdit::executeWithDatabase(QSharedPointer<Database> database, QShared
} }
if (!databaseWasChanged) { if (!databaseWasChanged) {
out << QObject::tr("Database was not modified.") << endl; out << QObject::tr("Database was not modified.") << Qt::endl;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
QString errorMessage; QString errorMessage;
if (!database->save(Database::Atomic, {}, &errorMessage)) { if (!database->save(Database::Atomic, {}, &errorMessage)) {
err << QObject::tr("Writing the database failed: %1").arg(errorMessage) << endl; err << QObject::tr("Writing the database failed: %1").arg(errorMessage) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
out << QObject::tr("Successfully edited the database.") << endl; out << QObject::tr("Successfully edited the database.") << Qt::endl;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
@ -113,19 +114,19 @@ QSharedPointer<CompositeKey> DatabaseEdit::getNewDatabaseKey(QSharedPointer<Data
auto currentChallengeResponseKey = database->key()->getChallengeResponseKey(ChallengeResponseKey::UUID); auto currentChallengeResponseKey = database->key()->getChallengeResponseKey(ChallengeResponseKey::UUID);
if (removePassword && currentPasswordKey.isNull()) { if (removePassword && currentPasswordKey.isNull()) {
err << QObject::tr("Cannot remove password: The database does not have a password.") << endl; err << QObject::tr("Cannot remove password: The database does not have a password.") << Qt::endl;
return {}; return {};
} }
if (removeKeyFile && currentFileKey.isNull()) { if (removeKeyFile && currentFileKey.isNull()) {
err << QObject::tr("Cannot remove file key: The database does not have a file key.") << endl; err << QObject::tr("Cannot remove file key: The database does not have a file key.") << Qt::endl;
return {}; return {};
} }
if (updatePassword) { if (updatePassword) {
QSharedPointer<PasswordKey> newPasswordKey = Utils::getConfirmedPassword(); QSharedPointer<PasswordKey> newPasswordKey = Utils::getConfirmedPassword();
if (newPasswordKey.isNull()) { if (newPasswordKey.isNull()) {
err << QObject::tr("Failed to set database password.") << endl; err << QObject::tr("Failed to set database password.") << Qt::endl;
return {}; return {};
} }
newDatabaseKey->addKey(newPasswordKey); newDatabaseKey->addKey(newPasswordKey);
@ -137,7 +138,7 @@ QSharedPointer<CompositeKey> DatabaseEdit::getNewDatabaseKey(QSharedPointer<Data
QSharedPointer<FileKey> newFileKey = QSharedPointer<FileKey>::create(); QSharedPointer<FileKey> newFileKey = QSharedPointer<FileKey>::create();
QString errorMessage; QString errorMessage;
if (!Utils::loadFileKey(newFileKeyPath, newFileKey)) { if (!Utils::loadFileKey(newFileKeyPath, newFileKey)) {
err << QObject::tr("Loading the new key file failed: %1").arg(errorMessage) << endl; err << QObject::tr("Loading the new key file failed: %1").arg(errorMessage) << Qt::endl;
return {}; return {};
} }
newDatabaseKey->addKey(newFileKey); newDatabaseKey->addKey(newFileKey);
@ -150,13 +151,13 @@ QSharedPointer<CompositeKey> DatabaseEdit::getNewDatabaseKey(QSharedPointer<Data
// silently removed from the database. // silently removed from the database.
for (const QSharedPointer<Key>& key : database->key()->keys()) { for (const QSharedPointer<Key>& key : database->key()->keys()) {
if (key->uuid() != PasswordKey::UUID && key->uuid() != FileKey::UUID) { if (key->uuid() != PasswordKey::UUID && key->uuid() != FileKey::UUID) {
err << QObject::tr("Found unexpected Key type %1").arg(key->uuid().toString()) << endl; err << QObject::tr("Found unexpected Key type %1").arg(key->uuid().toString()) << Qt::endl;
return {}; return {};
} }
} }
for (const QSharedPointer<ChallengeResponseKey>& key : database->key()->challengeResponseKeys()) { for (const QSharedPointer<ChallengeResponseKey>& key : database->key()->challengeResponseKeys()) {
if (key->uuid() != ChallengeResponseKey::UUID) { if (key->uuid() != ChallengeResponseKey::UUID) {
err << QObject::tr("Found unexpected Key type %1").arg(key->uuid().toString()) << endl; err << QObject::tr("Found unexpected Key type %1").arg(key->uuid().toString()) << Qt::endl;
return {}; return {};
} }
} }
@ -166,7 +167,7 @@ QSharedPointer<CompositeKey> DatabaseEdit::getNewDatabaseKey(QSharedPointer<Data
} }
if (newDatabaseKey->keys().isEmpty() && newDatabaseKey->challengeResponseKeys().isEmpty()) { if (newDatabaseKey->keys().isEmpty() && newDatabaseKey->challengeResponseKeys().isEmpty()) {
err << QObject::tr("Cannot remove all the keys from a database.") << endl; err << QObject::tr("Cannot remove all the keys from a database.") << Qt::endl;
return {}; return {};
} }

View file

@ -18,6 +18,7 @@
#include "DatabaseInfo.h" #include "DatabaseInfo.h"
#include "Utils.h" #include "Utils.h"
#include "core/Clock.h"
#include "core/DatabaseStats.h" #include "core/DatabaseStats.h"
#include "core/Global.h" #include "core/Global.h"
#include "core/Group.h" #include "core/Group.h"
@ -35,39 +36,39 @@ int DatabaseInfo::executeWithDatabase(QSharedPointer<Database> database, QShared
{ {
auto& out = Utils::STDOUT; auto& out = Utils::STDOUT;
out << QObject::tr("UUID: ") << database->uuid().toString() << endl; out << QObject::tr("UUID: ") << database->uuid().toString() << Qt::endl;
out << QObject::tr("Name: ") << database->metadata()->name() << endl; out << QObject::tr("Name: ") << database->metadata()->name() << Qt::endl;
out << QObject::tr("Description: ") << database->metadata()->description() << endl; out << QObject::tr("Description: ") << database->metadata()->description() << Qt::endl;
for (auto& cipher : asConst(KeePass2::CIPHERS)) { for (auto& cipher : asConst(KeePass2::CIPHERS)) {
if (cipher == database->cipher()) { if (cipher == database->cipher()) {
out << QObject::tr("Cipher: ") << KeePass2::cipherToString(cipher) << endl; out << QObject::tr("Cipher: ") << KeePass2::cipherToString(cipher) << Qt::endl;
} }
} }
out << QObject::tr("KDF: ") << database->kdf()->toString() << endl; out << QObject::tr("KDF: ") << database->kdf()->toString() << Qt::endl;
if (database->metadata()->recycleBinEnabled()) { if (database->metadata()->recycleBinEnabled()) {
out << QObject::tr("Recycle bin is enabled.") << endl; out << QObject::tr("Recycle bin is enabled.") << Qt::endl;
} else { } else {
out << QObject::tr("Recycle bin is not enabled.") << endl; out << QObject::tr("Recycle bin is not enabled.") << Qt::endl;
} }
DatabaseStats stats(database); DatabaseStats stats(database);
out << QObject::tr("Location") << ": " << database->filePath() << endl; out << QObject::tr("Location") << ": " << database->filePath() << Qt::endl;
out << QObject::tr("Database created") << ": " out << QObject::tr("Database created") << ": " << Clock::toString(database->rootGroup()->timeInfo().creationTime())
<< database->rootGroup()->timeInfo().creationTime().toString(Qt::DefaultLocaleShortDate) << endl; << Qt::endl;
out << QObject::tr("Last saved") << ": " << stats.modified.toString(Qt::DefaultLocaleShortDate) << endl; out << QObject::tr("Last saved") << ": " << Clock::toString(stats.modified) << Qt::endl;
out << QObject::tr("Unsaved changes") << ": " << (database->isModified() ? QObject::tr("yes") : QObject::tr("no")) out << QObject::tr("Unsaved changes") << ": " << (database->isModified() ? QObject::tr("yes") : QObject::tr("no"))
<< endl; << Qt::endl;
out << QObject::tr("Number of groups") << ": " << QString::number(stats.groupCount) << endl; out << QObject::tr("Number of groups") << ": " << QString::number(stats.groupCount) << Qt::endl;
out << QObject::tr("Number of entries") << ": " << QString::number(stats.entryCount) << endl; out << QObject::tr("Number of entries") << ": " << QString::number(stats.entryCount) << Qt::endl;
out << QObject::tr("Number of expired entries") << ": " << QString::number(stats.expiredEntries) << endl; out << QObject::tr("Number of expired entries") << ": " << QString::number(stats.expiredEntries) << Qt::endl;
out << QObject::tr("Unique passwords") << ": " << QString::number(stats.uniquePasswords) << endl; out << QObject::tr("Unique passwords") << ": " << QString::number(stats.uniquePasswords) << Qt::endl;
out << QObject::tr("Non-unique passwords") << ": " << QString::number(stats.reusedPasswords) << endl; out << QObject::tr("Non-unique passwords") << ": " << QString::number(stats.reusedPasswords) << Qt::endl;
out << QObject::tr("Maximum password reuse") << ": " << QString::number(stats.maxPwdReuse()) << endl; out << QObject::tr("Maximum password reuse") << ": " << QString::number(stats.maxPwdReuse()) << Qt::endl;
out << QObject::tr("Number of short passwords") << ": " << QString::number(stats.shortPasswords) << endl; out << QObject::tr("Number of short passwords") << ": " << QString::number(stats.shortPasswords) << Qt::endl;
out << QObject::tr("Number of weak passwords") << ": " << QString::number(stats.weakPasswords) << 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) << 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()) out << QObject::tr("Average password length") << ": " << QObject::tr("%1 characters").arg(stats.averagePwdLength())
<< endl; << Qt::endl;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View file

@ -18,6 +18,7 @@
#include "Diceware.h" #include "Diceware.h"
#include "Utils.h" #include "Utils.h"
#include "core/Global.h"
#include "core/PassphraseGenerator.h" #include "core/PassphraseGenerator.h"
#include <QCommandLineParser> #include <QCommandLineParser>
@ -58,7 +59,7 @@ int Diceware::execute(const QStringList& arguments)
if (wordCount.isEmpty()) { if (wordCount.isEmpty()) {
dicewareGenerator.setWordCount(PassphraseGenerator::DefaultWordCount); dicewareGenerator.setWordCount(PassphraseGenerator::DefaultWordCount);
} else if (wordCount.toInt() <= 0) { } else if (wordCount.toInt() <= 0) {
err << QObject::tr("Invalid word count %1").arg(wordCount) << endl; err << QObject::tr("Invalid word count %1").arg(wordCount) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} else { } else {
dicewareGenerator.setWordCount(wordCount.toInt()); dicewareGenerator.setWordCount(wordCount.toInt());
@ -72,12 +73,12 @@ int Diceware::execute(const QStringList& arguments)
if (!dicewareGenerator.isValid()) { if (!dicewareGenerator.isValid()) {
// We already validated the word count input so if the generator is invalid, it // We already validated the word count input so if the generator is invalid, it
// must be because the word list is too small. // must be because the word list is too small.
err << QObject::tr("The word list is too small (< 1000 items)") << endl; err << QObject::tr("The word list is too small (< 1000 items)") << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
QString password = dicewareGenerator.generatePassphrase(); QString password = dicewareGenerator.generatePassphrase();
out << password << endl; out << password << Qt::endl;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View file

@ -20,6 +20,7 @@
#include "Add.h" #include "Add.h"
#include "Generate.h" #include "Generate.h"
#include "Utils.h" #include "Utils.h"
#include "core/Global.h"
#include "core/Group.h" #include "core/Group.h"
#include "core/PasswordGenerator.h" #include "core/PasswordGenerator.h"
@ -66,7 +67,7 @@ int Edit::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
// Cannot use those 2 options at the same time! // Cannot use those 2 options at the same time!
if (parser->isSet(Add::GenerateOption) && parser->isSet(Add::PasswordPromptOption)) { if (parser->isSet(Add::GenerateOption) && parser->isSet(Add::PasswordPromptOption)) {
err << QObject::tr("Cannot generate a password and prompt at the same time.") << endl; err << QObject::tr("Cannot generate a password and prompt at the same time.") << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -83,7 +84,7 @@ int Edit::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
Entry* entry = database->rootGroup()->findEntryByPath(entryPath); Entry* entry = database->rootGroup()->findEntryByPath(entryPath);
if (!entry) { if (!entry) {
err << QObject::tr("Could not find entry with path %1.").arg(entryPath) << endl; err << QObject::tr("Could not find entry with path %1.").arg(entryPath) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -93,7 +94,7 @@ int Edit::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
QString title = parser->value(Edit::TitleOption); QString title = parser->value(Edit::TitleOption);
bool prompt = parser->isSet(Add::PasswordPromptOption); bool prompt = parser->isSet(Add::PasswordPromptOption);
if (username.isEmpty() && url.isEmpty() && notes.isEmpty() && title.isEmpty() && !prompt && !generate) { if (username.isEmpty() && url.isEmpty() && notes.isEmpty() && title.isEmpty() && !prompt && !generate) {
err << QObject::tr("Not changing any field for entry %1.").arg(entryPath) << endl; err << QObject::tr("Not changing any field for entry %1.").arg(entryPath) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -116,7 +117,7 @@ int Edit::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
} }
if (prompt) { if (prompt) {
out << QObject::tr("Enter new password for entry: ") << flush; out << QObject::tr("Enter new password for entry: ") << Qt::flush;
QString password = Utils::getPassword(parser->isSet(Command::QuietOption)); QString password = Utils::getPassword(parser->isSet(Command::QuietOption));
entry->setPassword(password); entry->setPassword(password);
} else if (generate) { } else if (generate) {
@ -128,10 +129,10 @@ int Edit::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
QString errorMessage; QString errorMessage;
if (!database->save(Database::Atomic, {}, &errorMessage)) { if (!database->save(Database::Atomic, {}, &errorMessage)) {
err << QObject::tr("Writing the database failed: %1").arg(errorMessage) << endl; err << QObject::tr("Writing the database failed: %1").arg(errorMessage) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
out << QObject::tr("Successfully edited entry %1.").arg(entry->title()) << endl; out << QObject::tr("Successfully edited entry %1.").arg(entry->title()) << Qt::endl;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View file

@ -18,6 +18,7 @@
#include "Estimate.h" #include "Estimate.h"
#include "Utils.h" #include "Utils.h"
#include "core/Global.h"
#include "core/PasswordHealth.h" #include "core/PasswordHealth.h"
#include <QCommandLineParser> #include <QCommandLineParser>
@ -47,7 +48,7 @@ static void estimate(const char* pwd, bool advanced)
// clang-format off // clang-format off
out << QObject::tr("Length %1").arg(len, 0) << '\t' out << QObject::tr("Length %1").arg(len, 0) << '\t'
<< QObject::tr("Entropy %1").arg(e, 0, 'f', 3) << '\t' << QObject::tr("Entropy %1").arg(e, 0, 'f', 3) << '\t'
<< QObject::tr("Log10 %1").arg(e * 0.301029996, 0, 'f', 3) << endl; << QObject::tr("Log10 %1").arg(e * 0.301029996, 0, 'f', 3) << Qt::endl;
// clang-format on // clang-format on
} else { } else {
int pwdLen = 0; int pwdLen = 0;
@ -62,7 +63,7 @@ static void estimate(const char* pwd, bool advanced)
out << QObject::tr("Length %1").arg(len) << '\t' out << QObject::tr("Length %1").arg(len) << '\t'
<< QObject::tr("Entropy %1").arg(e, 0, 'f', 3) << '\t' << QObject::tr("Entropy %1").arg(e, 0, 'f', 3) << '\t'
<< QObject::tr("Log10 %1").arg(e * 0.301029996, 0, 'f', 3) << "\n " << QObject::tr("Log10 %1").arg(e * 0.301029996, 0, 'f', 3) << "\n "
<< QObject::tr("Multi-word extra bits %1").arg(m, 0, 'f', 1) << endl; << QObject::tr("Multi-word extra bits %1").arg(m, 0, 'f', 1) << Qt::endl;
// clang-format on // clang-format on
p = info; p = info;
pwdLen = 0; pwdLen = 0;
@ -135,13 +136,13 @@ static void estimate(const char* pwd, bool advanced)
for (n = 0; n < p->Length; ++n, ++pwd) { for (n = 0; n < p->Length; ++n, ++pwd) {
out << *pwd; out << *pwd;
} }
out << endl; out << Qt::endl;
p = p->Next; p = p->Next;
} }
ZxcvbnFreeInfo(info); ZxcvbnFreeInfo(info);
if (pwdLen != len) { if (pwdLen != len) {
out << QObject::tr("*** Password length (%1) != sum of length of parts (%2) ***").arg(len).arg(pwdLen) out << QObject::tr("*** Password length (%1) != sum of length of parts (%2) ***").arg(len).arg(pwdLen)
<< endl; << Qt::endl;
} }
} }
} }

View file

@ -19,6 +19,7 @@
#include "TextStream.h" #include "TextStream.h"
#include "Utils.h" #include "Utils.h"
#include "core/Global.h"
#include "format/CsvExporter.h" #include "format/CsvExporter.h"
#include <QCommandLineParser> #include <QCommandLineParser>
@ -46,7 +47,7 @@ int Export::executeWithDatabase(QSharedPointer<Database> database, QSharedPointe
QByteArray xmlData; QByteArray xmlData;
QString errorMessage; QString errorMessage;
if (!database->extract(xmlData, &errorMessage)) { if (!database->extract(xmlData, &errorMessage)) {
err << QObject::tr("Unable to export database to XML: %1").arg(errorMessage) << endl; err << QObject::tr("Unable to export database to XML: %1").arg(errorMessage) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
out.write(xmlData.constData()); out.write(xmlData.constData());
@ -54,7 +55,7 @@ int Export::executeWithDatabase(QSharedPointer<Database> database, QSharedPointe
CsvExporter csvExporter; CsvExporter csvExporter;
out << csvExporter.exportDatabase(database); out << csvExporter.exportDatabase(database);
} else { } else {
err << QObject::tr("Unsupported format %1").arg(format) << endl; err << QObject::tr("Unsupported format %1").arg(format) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }

View file

@ -18,6 +18,7 @@
#include "Generate.h" #include "Generate.h"
#include "Utils.h" #include "Utils.h"
#include "core/Global.h"
#include "core/PasswordGenerator.h" #include "core/PasswordGenerator.h"
#include <QCommandLineParser> #include <QCommandLineParser>
@ -92,7 +93,7 @@ QSharedPointer<PasswordGenerator> Generate::createGenerator(QSharedPointer<QComm
if (passwordLength.isEmpty()) { if (passwordLength.isEmpty()) {
passwordGenerator->setLength(PasswordGenerator::DefaultLength); passwordGenerator->setLength(PasswordGenerator::DefaultLength);
} else if (passwordLength.toInt() <= 0) { } else if (passwordLength.toInt() <= 0) {
err << QObject::tr("Invalid password length %1").arg(passwordLength) << endl; err << QObject::tr("Invalid password length %1").arg(passwordLength) << Qt::endl;
return {}; return {};
} else { } else {
passwordGenerator->setLength(passwordLength.toInt()); passwordGenerator->setLength(passwordLength.toInt());
@ -138,7 +139,7 @@ QSharedPointer<PasswordGenerator> Generate::createGenerator(QSharedPointer<QComm
passwordGenerator->setExcludedCharacterSet(parser->value(Generate::ExcludeCharsOption)); passwordGenerator->setExcludedCharacterSet(parser->value(Generate::ExcludeCharsOption));
if (!passwordGenerator->isValid()) { if (!passwordGenerator->isValid()) {
err << QObject::tr("Invalid password generator after applying all options") << endl; err << QObject::tr("Invalid password generator after applying all options") << Qt::endl;
return {}; return {};
} }
@ -159,7 +160,7 @@ int Generate::execute(const QStringList& arguments)
auto& out = Utils::STDOUT; auto& out = Utils::STDOUT;
QString password = passwordGenerator->generatePassword(); QString password = passwordGenerator->generatePassword();
out << password << endl; out << password << Qt::endl;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View file

@ -20,6 +20,8 @@
#include "DatabaseCreate.h" #include "DatabaseCreate.h"
#include "Utils.h" #include "Utils.h"
#include "core/Global.h"
#include <QCommandLineParser> #include <QCommandLineParser>
#include <QFileInfo> #include <QFileInfo>
@ -61,7 +63,7 @@ int Import::execute(const QStringList& arguments)
const QString& dbPath = args.at(1); const QString& dbPath = args.at(1);
if (QFileInfo::exists(dbPath)) { if (QFileInfo::exists(dbPath)) {
err << QObject::tr("File %1 already exists.").arg(dbPath) << endl; err << QObject::tr("File %1 already exists.").arg(dbPath) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -72,15 +74,15 @@ int Import::execute(const QStringList& arguments)
QString errorMessage; QString errorMessage;
if (!db->import(xmlExportPath, &errorMessage)) { if (!db->import(xmlExportPath, &errorMessage)) {
err << QObject::tr("Unable to import XML database: %1").arg(errorMessage) << endl; err << QObject::tr("Unable to import XML database: %1").arg(errorMessage) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (!db->saveAs(dbPath, Database::Atomic, {}, &errorMessage)) { if (!db->saveAs(dbPath, Database::Atomic, {}, &errorMessage)) {
err << QObject::tr("Failed to save the database: %1.").arg(errorMessage) << endl; err << QObject::tr("Failed to save the database: %1.").arg(errorMessage) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
out << QObject::tr("Successfully imported database.") << endl; out << QObject::tr("Successfully imported database.") << Qt::endl;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View file

@ -18,6 +18,7 @@
#include "List.h" #include "List.h"
#include "Utils.h" #include "Utils.h"
#include "core/Global.h"
#include "core/Group.h" #include "core/Group.h"
#include <QCommandLineParser> #include <QCommandLineParser>
@ -52,17 +53,17 @@ int List::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
// No group provided, defaulting to root group. // No group provided, defaulting to root group.
if (args.size() == 1) { if (args.size() == 1) {
out << database->rootGroup()->print(recursive, flatten) << flush; out << database->rootGroup()->print(recursive, flatten) << Qt::flush;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
const QString& groupPath = args.at(1); const QString& groupPath = args.at(1);
Group* group = database->rootGroup()->findGroupByPath(groupPath); Group* group = database->rootGroup()->findGroupByPath(groupPath);
if (!group) { if (!group) {
err << QObject::tr("Cannot find group %1.").arg(groupPath) << endl; err << QObject::tr("Cannot find group %1.").arg(groupPath) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
out << group->print(recursive, flatten) << flush; out << group->print(recursive, flatten) << Qt::flush;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View file

@ -18,6 +18,7 @@
#include "Merge.h" #include "Merge.h"
#include "Utils.h" #include "Utils.h"
#include "core/Global.h"
#include "core/Merger.h" #include "core/Merger.h"
#include <QCommandLineParser> #include <QCommandLineParser>
@ -90,18 +91,18 @@ int Merge::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer
QStringList changeList = merger.merge(); QStringList changeList = merger.merge();
for (auto& mergeChange : changeList) { for (auto& mergeChange : changeList) {
out << "\t" << mergeChange << endl; out << "\t" << mergeChange << Qt::endl;
} }
if (!changeList.isEmpty() && !parser->isSet(Merge::DryRunOption)) { if (!changeList.isEmpty() && !parser->isSet(Merge::DryRunOption)) {
QString errorMessage; QString errorMessage;
if (!database->save(Database::Atomic, {}, &errorMessage)) { if (!database->save(Database::Atomic, {}, &errorMessage)) {
err << QObject::tr("Unable to save database to file : %1").arg(errorMessage) << endl; err << QObject::tr("Unable to save database to file : %1").arg(errorMessage) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
out << QObject::tr("Successfully merged %1 into %2.").arg(fromDatabasePath, toDatabasePath) << endl; out << QObject::tr("Successfully merged %1 into %2.").arg(fromDatabasePath, toDatabasePath) << Qt::endl;
} else { } else {
out << QObject::tr("Database was not modified by merge operation.") << endl; out << QObject::tr("Database was not modified by merge operation.") << Qt::endl;
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;

View file

@ -18,6 +18,7 @@
#include "Move.h" #include "Move.h"
#include "Utils.h" #include "Utils.h"
#include "core/Global.h"
#include "core/Group.h" #include "core/Group.h"
#include <QCommandLineParser> #include <QCommandLineParser>
@ -43,18 +44,18 @@ int Move::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
Entry* entry = database->rootGroup()->findEntryByPath(entryPath); Entry* entry = database->rootGroup()->findEntryByPath(entryPath);
if (!entry) { if (!entry) {
err << QObject::tr("Could not find entry with path %1.").arg(entryPath) << endl; err << QObject::tr("Could not find entry with path %1.").arg(entryPath) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
Group* destinationGroup = database->rootGroup()->findGroupByPath(destinationPath); Group* destinationGroup = database->rootGroup()->findGroupByPath(destinationPath);
if (!destinationGroup) { if (!destinationGroup) {
err << QObject::tr("Could not find group with path %1.").arg(destinationPath) << endl; err << QObject::tr("Could not find group with path %1.").arg(destinationPath) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (destinationGroup == entry->parent()) { if (destinationGroup == entry->parent()) {
err << QObject::tr("Entry is already in group %1.").arg(destinationPath) << endl; err << QObject::tr("Entry is already in group %1.").arg(destinationPath) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -64,10 +65,10 @@ int Move::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
QString errorMessage; QString errorMessage;
if (!database->save(Database::Atomic, {}, &errorMessage)) { if (!database->save(Database::Atomic, {}, &errorMessage)) {
err << QObject::tr("Writing the database failed %1.").arg(errorMessage) << endl; err << QObject::tr("Writing the database failed %1.").arg(errorMessage) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
out << QObject::tr("Successfully moved entry %1 to group %2.").arg(entry->title(), destinationPath) << endl; out << QObject::tr("Successfully moved entry %1 to group %2.").arg(entry->title(), destinationPath) << Qt::endl;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View file

@ -18,6 +18,7 @@
#include "Remove.h" #include "Remove.h"
#include "Utils.h" #include "Utils.h"
#include "core/Global.h"
#include "core/Group.h" #include "core/Group.h"
#include "core/Metadata.h" #include "core/Metadata.h"
@ -38,7 +39,7 @@ int Remove::executeWithDatabase(QSharedPointer<Database> database, QSharedPointe
auto entryPath = parser->positionalArguments().at(1); auto entryPath = parser->positionalArguments().at(1);
QPointer<Entry> entry = database->rootGroup()->findEntryByPath(entryPath); QPointer<Entry> entry = database->rootGroup()->findEntryByPath(entryPath);
if (!entry) { if (!entry) {
err << QObject::tr("Entry %1 not found.").arg(entryPath) << endl; err << QObject::tr("Entry %1 not found.").arg(entryPath) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -54,14 +55,14 @@ int Remove::executeWithDatabase(QSharedPointer<Database> database, QSharedPointe
QString errorMessage; QString errorMessage;
if (!database->save(Database::Atomic, {}, &errorMessage)) { if (!database->save(Database::Atomic, {}, &errorMessage)) {
err << QObject::tr("Unable to save database to file: %1").arg(errorMessage) << endl; err << QObject::tr("Unable to save database to file: %1").arg(errorMessage) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (recycled) { if (recycled) {
out << QObject::tr("Successfully recycled entry %1.").arg(entryTitle) << endl; out << QObject::tr("Successfully recycled entry %1.").arg(entryTitle) << Qt::endl;
} else { } else {
out << QObject::tr("Successfully deleted entry %1.").arg(entryTitle) << endl; out << QObject::tr("Successfully deleted entry %1.").arg(entryTitle) << Qt::endl;
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;

View file

@ -18,6 +18,7 @@
#include "RemoveGroup.h" #include "RemoveGroup.h"
#include "Utils.h" #include "Utils.h"
#include "core/Global.h"
#include "core/Group.h" #include "core/Group.h"
#include "core/Metadata.h" #include "core/Metadata.h"
@ -42,12 +43,12 @@ int RemoveGroup::executeWithDatabase(QSharedPointer<Database> database, QSharedP
// Recursive option means were looking for a group to remove. // Recursive option means were looking for a group to remove.
QPointer<Group> group = database->rootGroup()->findGroupByPath(groupPath); QPointer<Group> group = database->rootGroup()->findGroupByPath(groupPath);
if (!group) { if (!group) {
err << QObject::tr("Group %1 not found.").arg(groupPath) << endl; err << QObject::tr("Group %1 not found.").arg(groupPath) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (group == database->rootGroup()) { if (group == database->rootGroup()) {
err << QObject::tr("Cannot remove root group from database.") << endl; err << QObject::tr("Cannot remove root group from database.") << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -62,14 +63,14 @@ int RemoveGroup::executeWithDatabase(QSharedPointer<Database> database, QSharedP
QString errorMessage; QString errorMessage;
if (!database->save(Database::Atomic, {}, &errorMessage)) { if (!database->save(Database::Atomic, {}, &errorMessage)) {
err << QObject::tr("Unable to save database to file: %1").arg(errorMessage) << endl; err << QObject::tr("Unable to save database to file: %1").arg(errorMessage) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (recycled) { if (recycled) {
out << QObject::tr("Successfully recycled group %1.").arg(groupPath) << endl; out << QObject::tr("Successfully recycled group %1.").arg(groupPath) << Qt::endl;
} else { } else {
out << QObject::tr("Successfully deleted group %1.").arg(groupPath) << endl; out << QObject::tr("Successfully deleted group %1.").arg(groupPath) << Qt::endl;
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;

View file

@ -21,6 +21,7 @@
#include "Utils.h" #include "Utils.h"
#include "core/EntrySearcher.h" #include "core/EntrySearcher.h"
#include "core/Global.h"
#include "core/Group.h" #include "core/Group.h"
Search::Search() Search::Search()
@ -40,12 +41,12 @@ int Search::executeWithDatabase(QSharedPointer<Database> database, QSharedPointe
EntrySearcher searcher; EntrySearcher searcher;
auto results = searcher.search(args.at(1), database->rootGroup(), true); auto results = searcher.search(args.at(1), database->rootGroup(), true);
if (results.isEmpty()) { if (results.isEmpty()) {
err << "No results for that search term." << endl; err << "No results for that search term." << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
for (const Entry* result : asConst(results)) { for (const Entry* result : asConst(results)) {
out << result->path().prepend('/') << endl; out << result->path().prepend('/') << Qt::endl;
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View file

@ -73,12 +73,12 @@ int Show::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
Entry* entry = database->rootGroup()->findEntryByPath(entryPath); Entry* entry = database->rootGroup()->findEntryByPath(entryPath);
if (!entry) { if (!entry) {
err << QObject::tr("Could not find entry with path %1.").arg(entryPath) << endl; err << QObject::tr("Could not find entry with path %1.").arg(entryPath) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (showTotp && !entry->hasTotp()) { if (showTotp && !entry->hasTotp()) {
err << QObject::tr("Entry with path %1 has no TOTP set up.").arg(entryPath) << endl; err << QObject::tr("Entry with path %1 has no TOTP set up.").arg(entryPath) << Qt::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -113,20 +113,20 @@ int Show::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
if (!attributesWereSpecified) { if (!attributesWereSpecified) {
out << attributeName << ": "; out << attributeName << ": ";
} }
out << Utils::getTopLevelField(entry, attributeName) << endl; out << Utils::getTopLevelField(entry, attributeName) << Qt::endl;
continue; continue;
} }
QStringList attrs = Utils::findAttributes(*entry->attributes(), attributeName); QStringList attrs = Utils::findAttributes(*entry->attributes(), attributeName);
if (attrs.isEmpty()) { if (attrs.isEmpty()) {
encounteredError = true; encounteredError = true;
err << QObject::tr("ERROR: unknown attribute %1.").arg(attributeName) << endl; err << QObject::tr("ERROR: unknown attribute %1.").arg(attributeName) << Qt::endl;
continue; continue;
} else if (attrs.size() > 1) { } else if (attrs.size() > 1) {
encounteredError = true; encounteredError = true;
err << QObject::tr("ERROR: attribute %1 is ambiguous, it matches %2.") err << QObject::tr("ERROR: attribute %1 is ambiguous, it matches %2.")
.arg(attributeName, QLocale().createSeparatedList(attrs)) .arg(attributeName, QLocale().createSeparatedList(attrs))
<< endl; << Qt::endl;
continue; continue;
} }
QString canonicalName = attrs[0]; QString canonicalName = attrs[0];
@ -134,33 +134,33 @@ int Show::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
out << canonicalName << ": "; out << canonicalName << ": ";
} }
if (entry->attributes()->isProtected(canonicalName) && !attributesWereSpecified && !showProtectedAttributes) { if (entry->attributes()->isProtected(canonicalName) && !attributesWereSpecified && !showProtectedAttributes) {
out << "PROTECTED" << endl; out << "PROTECTED" << Qt::endl;
} else { } else {
out << entry->resolveMultiplePlaceholders(entry->attributes()->value(canonicalName)) << endl; out << entry->resolveMultiplePlaceholders(entry->attributes()->value(canonicalName)) << Qt::endl;
} }
} }
if (parser->isSet(Show::AttachmentsOption)) { if (parser->isSet(Show::AttachmentsOption)) {
// Separate attachment output from attributes output via a newline. // Separate attachment output from attributes output via a newline.
out << endl; out << Qt::endl;
EntryAttachments* attachments = entry->attachments(); EntryAttachments* attachments = entry->attachments();
if (attachments->isEmpty()) { if (attachments->isEmpty()) {
out << QObject::tr("No attachments present.") << endl; out << QObject::tr("No attachments present.") << Qt::endl;
} else { } else {
out << QObject::tr("Attachments:") << endl; out << QObject::tr("Attachments:") << Qt::endl;
// Iterate over the attachments and output their names and size line-by-line, indented. // Iterate over the attachments and output their names and size line-by-line, indented.
for (const QString& attachmentName : attachments->keys()) { for (const QString& attachmentName : attachments->keys()) {
// TODO: use QLocale::formattedDataSize when >= Qt 5.10 // TODO: use QLocale::formattedDataSize when >= Qt 5.10
QString attachmentSize = Tools::humanReadableFileSize(attachments->value(attachmentName).size(), 1); QString attachmentSize = Tools::humanReadableFileSize(attachments->value(attachmentName).size(), 1);
out << " " << attachmentName << " (" << attachmentSize << ")" << endl; out << " " << attachmentName << " (" << attachmentSize << ")" << Qt::endl;
} }
} }
} }
if (showTotp) { if (showTotp) {
out << entry->totp() << endl; out << entry->totp() << Qt::endl;
} }
return encounteredError ? EXIT_FAILURE : EXIT_SUCCESS; return encounteredError ? EXIT_FAILURE : EXIT_SUCCESS;

View file

@ -20,6 +20,7 @@
#include "core/Database.h" #include "core/Database.h"
#include "core/Entry.h" #include "core/Entry.h"
#include "core/EntryAttributes.h" #include "core/EntryAttributes.h"
#include "core/Global.h"
#include "keys/FileKey.h" #include "keys/FileKey.h"
#ifdef WITH_XC_YUBIKEY #ifdef WITH_XC_YUBIKEY
#include "keys/ChallengeResponseKey.h" #include "keys/ChallengeResponseKey.h"
@ -111,22 +112,22 @@ namespace Utils
QFileInfo dbFileInfo(databaseFilename); QFileInfo dbFileInfo(databaseFilename);
if (dbFileInfo.canonicalFilePath().isEmpty()) { if (dbFileInfo.canonicalFilePath().isEmpty()) {
err << QObject::tr("Failed to open database file %1: not found").arg(databaseFilename) << endl; err << QObject::tr("Failed to open database file %1: not found").arg(databaseFilename) << Qt::endl;
return {}; return {};
} }
if (!dbFileInfo.isFile()) { if (!dbFileInfo.isFile()) {
err << QObject::tr("Failed to open database file %1: not a plain file").arg(databaseFilename) << endl; err << QObject::tr("Failed to open database file %1: not a plain file").arg(databaseFilename) << Qt::endl;
return {}; return {};
} }
if (!dbFileInfo.isReadable()) { if (!dbFileInfo.isReadable()) {
err << QObject::tr("Failed to open database file %1: not readable").arg(databaseFilename) << endl; err << QObject::tr("Failed to open database file %1: not readable").arg(databaseFilename) << Qt::endl;
return {}; return {};
} }
if (isPasswordProtected) { if (isPasswordProtected) {
err << QObject::tr("Enter password to unlock %1: ").arg(databaseFilename) << flush; err << QObject::tr("Enter password to unlock %1: ").arg(databaseFilename) << Qt::flush;
QString line = Utils::getPassword(quiet); QString line = Utils::getPassword(quiet);
auto passwordKey = QSharedPointer<PasswordKey>::create(); auto passwordKey = QSharedPointer<PasswordKey>::create();
passwordKey->setPassword(line); passwordKey->setPassword(line);
@ -138,7 +139,7 @@ namespace Utils
QString errorMessage; QString errorMessage;
// LCOV_EXCL_START // LCOV_EXCL_START
if (!fileKey->load(keyFilename, &errorMessage)) { if (!fileKey->load(keyFilename, &errorMessage)) {
err << QObject::tr("Failed to load key file %1: %2").arg(keyFilename, errorMessage) << endl; err << QObject::tr("Failed to load key file %1: %2").arg(keyFilename, errorMessage) << Qt::endl;
return {}; return {};
} }
@ -146,7 +147,7 @@ namespace Utils
err << QObject::tr("WARNING: You are using an old key file format which KeePassXC may\n" err << QObject::tr("WARNING: You are using an old key file format which KeePassXC may\n"
"stop supporting in the future.\n\n" "stop supporting in the future.\n\n"
"Please consider generating a new key file.") "Please consider generating a new key file.")
<< endl; << Qt::endl;
} }
// LCOV_EXCL_STOP // LCOV_EXCL_STOP
@ -163,20 +164,20 @@ namespace Utils
slot = parts[0].toInt(&ok); slot = parts[0].toInt(&ok);
if (!ok || (slot != 1 && slot != 2)) { if (!ok || (slot != 1 && slot != 2)) {
err << QObject::tr("Invalid YubiKey slot %1").arg(parts[0]) << endl; err << QObject::tr("Invalid YubiKey slot %1").arg(parts[0]) << Qt::endl;
return {}; return {};
} }
if (parts.size() > 1) { if (parts.size() > 1) {
serial = parts[1].toUInt(&ok, 10); serial = parts[1].toUInt(&ok, 10);
if (!ok) { if (!ok) {
err << QObject::tr("Invalid YubiKey serial %1").arg(parts[1]) << endl; err << QObject::tr("Invalid YubiKey serial %1").arg(parts[1]) << Qt::endl;
return {}; return {};
} }
} }
QObject::connect(YubiKey::instance(), &YubiKey::userInteractionRequest, [&] { QObject::connect(YubiKey::instance(), &YubiKey::userInteractionRequest, [&] {
err << QObject::tr("Please present or touch your YubiKey to continue.") << "\n\n" << flush; err << QObject::tr("Please present or touch your YubiKey to continue.") << "\n\n" << Qt::flush;
}); });
auto key = QSharedPointer<ChallengeResponseKey>(new ChallengeResponseKey({serial, slot})); auto key = QSharedPointer<ChallengeResponseKey>(new ChallengeResponseKey({serial, slot}));
@ -193,7 +194,7 @@ namespace Utils
if (db->open(databaseFilename, compositeKey, &error)) { if (db->open(databaseFilename, compositeKey, &error)) {
return db; return db;
} else { } else {
err << error << endl; err << error << Qt::endl;
return {}; return {};
} }
} }
@ -218,7 +219,7 @@ namespace Utils
setStdinEcho(false); setStdinEcho(false);
QString line = in.readLine(); QString line = in.readLine();
setStdinEcho(true); setStdinEcho(true);
out << endl; out << Qt::endl;
return line; return line;
#endif // __AFL_COMPILER #endif // __AFL_COMPILER
@ -248,7 +249,7 @@ namespace Utils
if (ans.toLower().startsWith("y")) { if (ans.toLower().startsWith("y")) {
passwordKey = QSharedPointer<PasswordKey>::create(""); passwordKey = QSharedPointer<PasswordKey>::create("");
} }
err << endl; err << Qt::endl;
} else { } else {
err << QObject::tr("Repeat password: "); err << QObject::tr("Repeat password: ");
err.flush(); err.flush();
@ -257,7 +258,7 @@ namespace Utils
if (password == repeat) { if (password == repeat) {
passwordKey = QSharedPointer<PasswordKey>::create(password); passwordKey = QSharedPointer<PasswordKey>::create(password);
} else { } else {
err << QObject::tr("Error: Passwords do not match.") << endl; err << QObject::tr("Error: Passwords do not match.") << Qt::endl;
} }
} }
@ -303,7 +304,7 @@ namespace Utils
QScopedPointer<QProcess> clipProcess(new QProcess(nullptr)); QScopedPointer<QProcess> clipProcess(new QProcess(nullptr));
// Skip empty parts, otherwise the program may clip the empty string // Skip empty parts, otherwise the program may clip the empty string
QStringList progArgs = prog.second.split(" ", QString::SkipEmptyParts); QStringList progArgs = prog.second.split(" ", Qt::SkipEmptyParts);
clipProcess->start(prog.first, progArgs); clipProcess->start(prog.first, progArgs);
clipProcess->waitForStarted(); clipProcess->waitForStarted();
@ -427,13 +428,13 @@ namespace Utils
fileKey->create(path, &error); fileKey->create(path, &error);
if (!error.isEmpty()) { if (!error.isEmpty()) {
err << QObject::tr("Creating KeyFile %1 failed: %2").arg(path, error) << endl; err << QObject::tr("Creating KeyFile %1 failed: %2").arg(path, error) << Qt::endl;
return false; return false;
} }
} }
if (!fileKey->load(path, &error)) { if (!fileKey->load(path, &error)) {
err << QObject::tr("Loading KeyFile %1 failed: %2").arg(path, error) << endl; err << QObject::tr("Loading KeyFile %1 failed: %2").arg(path, error) << Qt::endl;
return false; return false;
} }

View file

@ -154,7 +154,7 @@ int enterInteractiveMode(const QStringList& arguments)
auto cmd = Commands::getCommand(args[0]); auto cmd = Commands::getCommand(args[0]);
if (!cmd) { if (!cmd) {
err << QObject::tr("Unknown command %1").arg(args[0]) << endl; err << QObject::tr("Unknown command %1").arg(args[0]) << Qt::endl;
continue; continue;
} else if (cmd->name == "quit" || cmd->name == "exit") { } else if (cmd->name == "quit" || cmd->name == "exit") {
break; break;
@ -216,11 +216,11 @@ int main(int argc, char** argv)
if (parser.positionalArguments().empty()) { if (parser.positionalArguments().empty()) {
if (parser.isSet("version")) { if (parser.isSet("version")) {
// Switch to parser.showVersion() when available (QT 5.4). // Switch to parser.showVersion() when available (QT 5.4).
out << KEEPASSXC_VERSION << endl; out << KEEPASSXC_VERSION << Qt::endl;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} else if (parser.isSet(debugInfoOption)) { } else if (parser.isSet(debugInfoOption)) {
QString debugInfo = Tools::debugInfo().append("\n").append(Crypto::debugInfo()); QString debugInfo = Tools::debugInfo().append("\n").append(Crypto::debugInfo());
out << debugInfo << endl; out << debugInfo << Qt::endl;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
// showHelp exits the application immediately. // showHelp exits the application immediately.
@ -234,7 +234,7 @@ int main(int argc, char** argv)
auto command = Commands::getCommand(commandName); auto command = Commands::getCommand(commandName);
if (!command) { if (!command) {
err << QObject::tr("Invalid command %1.").arg(commandName) << endl; err << QObject::tr("Invalid command %1.").arg(commandName) << Qt::endl;
err << parser.helpText(); err << parser.helpText();
return EXIT_FAILURE; return EXIT_FAILURE;
} }

View file

@ -16,6 +16,8 @@
*/ */
#include "Clock.h" #include "Clock.h"
#include <QLocale>
QSharedPointer<Clock> Clock::m_instance; QSharedPointer<Clock> Clock::m_instance;
QDateTime Clock::currentDateTimeUtc() QDateTime Clock::currentDateTimeUtc()
@ -78,6 +80,12 @@ QDateTime Clock::parse(const QString& text, const QString& format)
return QDateTime::fromString(text, format); return QDateTime::fromString(text, format);
} }
QString Clock::toString(const QDateTime& dateTime)
{
static QLocale locale;
return locale.toString(dateTime, QLocale::ShortFormat);
}
Clock::~Clock() = default; Clock::~Clock() = default;
Clock::Clock() = default; Clock::Clock() = default;

View file

@ -41,6 +41,8 @@ public:
static QDateTime parse(const QString& text, Qt::DateFormat format = Qt::TextDate); static QDateTime parse(const QString& text, Qt::DateFormat format = Qt::TextDate);
static QDateTime parse(const QString& text, const QString& format); static QDateTime parse(const QString& text, const QString& format);
static QString toString(const QDateTime& dateTime);
virtual ~Clock(); virtual ~Clock();
protected: protected:

View file

@ -736,7 +736,7 @@ void Database::updateTagList()
} }
} }
m_tagList = tagSet.toList(); m_tagList = tagSet.values();
m_tagList.sort(); m_tagList.sort();
emit tagListUpdated(); emit tagListUpdated();
} }

View file

@ -20,6 +20,7 @@
#include "core/Config.h" #include "core/Config.h"
#include "core/Database.h" #include "core/Database.h"
#include "core/Global.h"
#include "core/Group.h" #include "core/Group.h"
#include "core/Metadata.h" #include "core/Metadata.h"
#include "core/PasswordHealth.h" #include "core/PasswordHealth.h"
@ -292,7 +293,7 @@ QString Entry::effectiveAutoTypeSequence() const
/** /**
* Retrieve the Auto-Type sequences matches for a given windowTitle * Retrieve the Auto-Type sequences matches for a given windowTitle
* This returns a list with priority ordering. If you don't want duplicates call .toSet() on it. * This returns a list with priority ordering. If you don't want duplicates, convert it to a QSet<QString>.
*/ */
QList<QString> Entry::autoTypeSequences(const QString& windowTitle) const QList<QString> Entry::autoTypeSequences(const QString& windowTitle) const
{ {
@ -677,8 +678,7 @@ void Entry::setTags(const QString& tags)
tag = tag.trimmed(); tag = tag.trimmed();
} }
// Remove duplicates // Remove duplicates
auto tagSet = QSet<QString>::fromList(taglist); taglist = Tools::asSet(taglist).values();
taglist = tagSet.toList();
// Sort alphabetically // Sort alphabetically
taglist.sort(); taglist.sort();
set(m_data.tags, taglist); set(m_data.tags, taglist);

View file

@ -19,6 +19,7 @@
#include "config-keepassx.h" #include "config-keepassx.h"
#include "core/Global.h" #include "core/Global.h"
#include "core/Tools.h"
#include "crypto/Random.h" #include "crypto/Random.h"
#include <QDesktopServices> #include <QDesktopServices>
@ -50,7 +51,7 @@ bool EntryAttachments::hasKey(const QString& key) const
QSet<QByteArray> EntryAttachments::values() const QSet<QByteArray> EntryAttachments::values() const
{ {
return asConst(m_attachments).values().toSet(); return Tools::asSet(m_attachments.values());
} }
QByteArray EntryAttachments::value(const QString& key) const QByteArray EntryAttachments::value(const QString& key) const

View file

@ -18,6 +18,7 @@
#include "EntryAttributes.h" #include "EntryAttributes.h"
#include "core/Global.h" #include "core/Global.h"
#include "core/Tools.h"
#include <QRegularExpression> #include <QRegularExpression>
#include <QUuid> #include <QUuid>
@ -248,7 +249,7 @@ void EntryAttributes::copyCustomKeysFrom(const EntryAttributes* other)
bool EntryAttributes::areCustomKeysDifferent(const EntryAttributes* other) bool EntryAttributes::areCustomKeysDifferent(const EntryAttributes* other)
{ {
// check if they are equal ignoring the order of the keys // check if they are equal ignoring the order of the keys
if (keys().toSet() != other->keys().toSet()) { if (Tools::asSet(keys()) != Tools::asSet(other->keys())) {
return true; return true;
} }

View file

@ -203,7 +203,7 @@ bool EntrySearcher::searchEntryImpl(const Entry* entry)
case Field::Is: case Field::Is:
if (term.word.startsWith("expired", Qt::CaseInsensitive)) { if (term.word.startsWith("expired", Qt::CaseInsensitive)) {
auto days = 0; auto days = 0;
auto parts = term.word.split("-", QString::SkipEmptyParts); auto parts = term.word.split("-", Qt::SkipEmptyParts);
if (parts.length() >= 2) { if (parts.length() >= 2) {
days = parts[1].toInt(); days = parts[1].toInt();
} }

View file

@ -21,6 +21,7 @@
#define KEEPASSX_GLOBAL_H #define KEEPASSX_GLOBAL_H
#include <QString> #include <QString>
#include <QTextStream>
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
#if defined(KEEPASSX_BUILDING_CORE) #if defined(KEEPASSX_BUILDING_CORE)
@ -42,6 +43,23 @@
#define FILE_CASE_SENSITIVE Qt::CaseSensitive #define FILE_CASE_SENSITIVE Qt::CaseSensitive
#endif #endif
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
// "Backport" a few things to the 'Qt' namespace as required for older Qt
// versions.
namespace Qt
{
const QString::SplitBehavior SkipEmptyParts = QString::SkipEmptyParts;
inline QTextStream& endl(QTextStream& s)
{
return ::endl(s);
}
inline QTextStream& flush(QTextStream& s)
{
return ::flush(s);
}
} // namespace Qt
#endif
static const auto TRUE_STR = QStringLiteral("true"); static const auto TRUE_STR = QStringLiteral("true");
static const auto FALSE_STR = QStringLiteral("false"); static const auto FALSE_STR = QStringLiteral("false");

View file

@ -17,7 +17,9 @@
#include "Merger.h" #include "Merger.h"
#include "core/Global.h"
#include "core/Metadata.h" #include "core/Metadata.h"
#include "core/Tools.h"
Merger::Merger(const Database* sourceDb, Database* targetDb) Merger::Merger(const Database* sourceDb, Database* targetDb)
: m_mode(Group::Default) : m_mode(Group::Default)
@ -473,7 +475,7 @@ Merger::ChangeList Merger::mergeDeletions(const MergeContext& context)
while (!groups.isEmpty()) { while (!groups.isEmpty()) {
auto* group = groups.takeFirst(); auto* group = groups.takeFirst();
if (!(group->children().toSet() & groups.toSet()).isEmpty()) { if (Tools::asSet(group->children()).intersects(Tools::asSet(groups))) {
// we need to finish all children before we are able to determine if the group can be removed // we need to finish all children before we are able to determine if the group can be removed
groups << group; groups << group;
continue; continue;

View file

@ -17,6 +17,7 @@
#include <QString> #include <QString>
#include "Clock.h"
#include "Group.h" #include "Group.h"
#include "PasswordHealth.h" #include "PasswordHealth.h"
#include "zxcvbn.h" #include "zxcvbn.h"
@ -171,8 +172,8 @@ QSharedPointer<PasswordHealth> HealthChecker::evaluate(const Entry* entry) const
if (entry->isExpired()) { if (entry->isExpired()) {
health->setScore(0); health->setScore(0);
health->addScoreReason(QObject::tr("Password has expired")); health->addScoreReason(QObject::tr("Password has expired"));
health->addScoreDetails(QObject::tr("Password expiry was %1") health->addScoreDetails(
.arg(entry->timeInfo().expiryTime().toString(Qt::DefaultLocaleShortDate))); QObject::tr("Password expiry was %1").arg(Clock::toString(entry->timeInfo().expiryTime())));
} else if (entry->timeInfo().expires()) { } else if (entry->timeInfo().expires()) {
const int days = QDateTime::currentDateTime().daysTo(entry->timeInfo().expiryTime()); const int days = QDateTime::currentDateTime().daysTo(entry->timeInfo().expiryTime());
if (days <= 30) { if (days <= 30) {
@ -186,8 +187,8 @@ QSharedPointer<PasswordHealth> HealthChecker::evaluate(const Entry* entry) const
} }
health->adjustScore((30 - days) * -2); health->adjustScore((30 - days) * -2);
health->addScoreDetails(QObject::tr("Password expires on %1") health->addScoreDetails(
.arg(entry->timeInfo().expiryTime().toString(Qt::DefaultLocaleShortDate))); QObject::tr("Password expires on %1").arg(Clock::toString(entry->timeInfo().expiryTime())));
if (days <= 2) { if (days <= 2) {
health->addScoreReason(QObject::tr("Password is about to expire")); health->addScoreReason(QObject::tr("Password is about to expire"));
} else if (days <= 10) { } else if (days <= 10) {

View file

@ -24,6 +24,7 @@
#include <QDateTime> #include <QDateTime>
#include <QList> #include <QList>
#include <QProcessEnvironment> #include <QProcessEnvironment>
#include <QSet>
class QIODevice; class QIODevice;
class QRegularExpression; class QRegularExpression;
@ -47,6 +48,15 @@ namespace Tools
QProcessEnvironment environment = QProcessEnvironment::systemEnvironment()); QProcessEnvironment environment = QProcessEnvironment::systemEnvironment());
QString cleanFilename(QString filename); QString cleanFilename(QString filename);
template <class T> QSet<T> asSet(const QList<T>& a)
{
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
return QSet<T>(a.begin(), a.end());
#else
return QSet<T>::fromList(a);
#endif
}
/** /**
* Escapes all characters in regex such that they do not receive any special treatment when used * Escapes all characters in regex such that they do not receive any special treatment when used
* in a regular expression. Essentially, this function escapes any characters not in a-zA-Z0-9. * in a regular expression. Essentially, this function escapes any characters not in a-zA-Z0-9.

View file

@ -648,7 +648,7 @@ namespace FdoSecrets
// groupPath can't be empty here, because otherwise it will match m_exposedGroup and was returned above // groupPath can't be empty here, because otherwise it will match m_exposedGroup and was returned above
Q_ASSERT(!groupPath.isEmpty()); Q_ASSERT(!groupPath.isEmpty());
auto groups = groupPath.split('/', QString::SkipEmptyParts); auto groups = groupPath.split('/', Qt::SkipEmptyParts);
auto groupName = groups.takeLast(); auto groupName = groups.takeLast();
// create parent group // create parent group

View file

@ -24,6 +24,8 @@
#include "fdosecrets/widgets/RowButtonHelper.h" #include "fdosecrets/widgets/RowButtonHelper.h"
#include "core/Entry.h" #include "core/Entry.h"
#include "core/Global.h"
#include "core/Tools.h"
#include "gui/Icons.h" #include "gui/Icons.h"
#include <QWindow> #include <QWindow>
@ -206,7 +208,7 @@ QHash<Entry*, AuthDecision> AccessControlDialog::decisions() const
AccessControlDialog::EntryModel::EntryModel(QList<Entry*> entries, QObject* parent) AccessControlDialog::EntryModel::EntryModel(QList<Entry*> entries, QObject* parent)
: QAbstractTableModel(parent) : QAbstractTableModel(parent)
, m_entries(std::move(entries)) , m_entries(std::move(entries))
, m_selected(QSet<Entry*>::fromList(m_entries)) , m_selected(Tools::asSet(m_entries))
{ {
} }

View file

@ -19,6 +19,7 @@
#include "KeePass2RandomStream.h" #include "KeePass2RandomStream.h"
#include "core/Clock.h" #include "core/Clock.h"
#include "core/Endian.h" #include "core/Endian.h"
#include "core/Global.h"
#include "core/Group.h" #include "core/Group.h"
#include "core/Tools.h" #include "core/Tools.h"
#include "streams/qtiocompressor.h" #include "streams/qtiocompressor.h"
@ -120,8 +121,8 @@ void KdbxXmlReader::readDatabase(QIODevice* device, Database* db, KeePass2Random
qWarning("KdbxXmlReader::readDatabase: found %d invalid entry reference(s)", m_tmpParent->children().size()); qWarning("KdbxXmlReader::readDatabase: found %d invalid entry reference(s)", m_tmpParent->children().size());
} }
const QSet<QString> poolKeys = asConst(m_binaryPool).keys().toSet(); const QSet<QString> poolKeys = Tools::asSet(m_binaryPool.keys());
const QSet<QString> entryKeys = asConst(m_binaryMap).keys().toSet(); const QSet<QString> entryKeys = Tools::asSet(m_binaryMap.keys());
const QSet<QString> unmappedKeys = entryKeys - poolKeys; const QSet<QString> unmappedKeys = entryKeys - poolKeys;
const QSet<QString> unusedKeys = poolKeys - entryKeys; const QSet<QString> unusedKeys = poolKeys - entryKeys;
@ -133,7 +134,7 @@ void KdbxXmlReader::readDatabase(QIODevice* device, Database* db, KeePass2Random
qWarning("KdbxXmlReader::readDatabase: found unused key \"%s\"", qPrintable(key)); qWarning("KdbxXmlReader::readDatabase: found unused key \"%s\"", qPrintable(key));
} }
QHash<QString, QPair<Entry*, QString>>::const_iterator i; QMultiHash<QString, QPair<Entry*, QString>>::const_iterator i;
for (i = m_binaryMap.constBegin(); i != m_binaryMap.constEnd(); ++i) { for (i = m_binaryMap.constBegin(); i != m_binaryMap.constEnd(); ++i) {
const QPair<Entry*, QString>& target = i.value(); const QPair<Entry*, QString>& target = i.value();
target.first->attachments()->set(target.second, m_binaryPool[i.key()]); target.first->attachments()->set(target.second, m_binaryPool[i.key()]);
@ -814,7 +815,7 @@ Entry* KdbxXmlReader::parseEntry(bool history)
} }
for (const StringPair& ref : asConst(binaryRefs)) { for (const StringPair& ref : asConst(binaryRefs)) {
m_binaryMap.insertMulti(ref.first, qMakePair(entry, ref.second)); m_binaryMap.insert(ref.first, qMakePair(entry, ref.second));
} }
return entry; return entry;

View file

@ -22,6 +22,7 @@
#include "core/Metadata.h" #include "core/Metadata.h"
#include <QCoreApplication> #include <QCoreApplication>
#include <QMultiHash>
#include <QXmlStreamReader> #include <QXmlStreamReader>
class QIODevice; class QIODevice;
@ -109,7 +110,7 @@ protected:
QHash<QUuid, Entry*> m_entries; QHash<QUuid, Entry*> m_entries;
QHash<QString, QByteArray> m_binaryPool; QHash<QString, QByteArray> m_binaryPool;
QHash<QString, QPair<Entry*, QString>> m_binaryMap; QMultiHash<QString, QPair<Entry*, QString>> m_binaryMap;
QByteArray m_headerHash; QByteArray m_headerHash;
bool m_error = false; bool m_error = false;

View file

@ -23,6 +23,7 @@
#include <QDebug> #include <QDebug>
#include <QJsonArray> #include <QJsonArray>
#include <QJsonObject> #include <QJsonObject>
#include <QLocale>
#include <QUrlQuery> #include <QUrlQuery>
namespace namespace
@ -120,7 +121,7 @@ void OpVaultReader::fillFromSectionField(Entry* entry, const QString& sectionNam
if (kind == "date" || kind == "monthYear") { if (kind == "date" || kind == "monthYear") {
QDateTime date = resolveDate(kind, field.value("v")); QDateTime date = resolveDate(kind, field.value("v"));
if (date.isValid()) { if (date.isValid()) {
entry->attributes()->set(attrName, date.toString(Qt::SystemLocaleShortDate)); entry->attributes()->set(attrName, QLocale::system().toString(date, QLocale::ShortFormat));
} else { } else {
qWarning() qWarning()
<< QString("[%1] Invalid date attribute found: %2 = %3").arg(entry->title(), attrName, attrValue); << QString("[%1] Invalid date attribute found: %2 = %3").arg(entry->title(), attrName, attrValue);

View file

@ -981,7 +981,16 @@ void DatabaseWidget::openUrlForEntry(Entry* entry)
} }
if (launch) { if (launch) {
QProcess::startDetached(cmdString.mid(6)); const QString cmd = cmdString.mid(6);
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
QStringList cmdList = QProcess::splitCommand(cmd);
if (!cmdList.isEmpty()) {
const QString program = cmdList.takeFirst();
QProcess::startDetached(program, cmdList);
}
#else
QProcess::startDetached(cmd);
#endif
if (config()->get(Config::MinimizeOnOpenUrl).toBool()) { if (config()->get(Config::MinimizeOnOpenUrl).toBool()) {
getMainWindow()->minimizeOrHide(); getMainWindow()->minimizeOrHide();
@ -2329,7 +2338,7 @@ bool DatabaseWidget::saveAs()
+ (defaultFileName.isEmpty() ? tr("Passwords").append(".kdbx") : defaultFileName)); + (defaultFileName.isEmpty() ? tr("Passwords").append(".kdbx") : defaultFileName));
} }
const QString newFilePath = fileDialog()->getSaveFileName( const QString newFilePath = fileDialog()->getSaveFileName(
this, tr("Save database as"), oldFilePath, tr("KeePass 2 Database").append(" (*.kdbx)"), nullptr, nullptr); this, tr("Save database as"), oldFilePath, tr("KeePass 2 Database").append(" (*.kdbx)"));
bool ok = false; bool ok = false;
if (!newFilePath.isEmpty()) { if (!newFilePath.isEmpty()) {
@ -2422,9 +2431,7 @@ bool DatabaseWidget::saveBackup()
const QString newFilePath = fileDialog()->getSaveFileName(this, const QString newFilePath = fileDialog()->getSaveFileName(this,
tr("Save database backup"), tr("Save database backup"),
FileDialog::getLastDir("backup", oldFilePath), FileDialog::getLastDir("backup", oldFilePath),
tr("KeePass 2 Database").append(" (*.kdbx)"), tr("KeePass 2 Database").append(" (*.kdbx)"));
nullptr,
nullptr);
if (!newFilePath.isEmpty()) { if (!newFilePath.isEmpty()) {
// Ensure we don't recurse back into this function // Ensure we don't recurse back into this function

View file

@ -20,6 +20,7 @@
#include "ui_EntryPreviewWidget.h" #include "ui_EntryPreviewWidget.h"
#include "Application.h" #include "Application.h"
#include "core/Clock.h"
#include "core/Config.h" #include "core/Config.h"
#include "core/Totp.h" #include "core/Totp.h"
#include "gui/Font.h" #include "gui/Font.h"
@ -398,8 +399,7 @@ void EntryPreviewWidget::updateEntryGeneralTab()
} }
const TimeInfo entryTime = m_currentEntry->timeInfo(); const TimeInfo entryTime = m_currentEntry->timeInfo();
const QString expires = const QString expires = entryTime.expires() ? Clock::toString(entryTime.expiryTime().toLocalTime()) : tr("Never");
entryTime.expires() ? entryTime.expiryTime().toLocalTime().toString(Qt::DefaultLocaleShortDate) : tr("Never");
m_ui->entryExpirationLabel->setText(expires); m_ui->entryExpirationLabel->setText(expires);
m_ui->entryTagsList->tags(m_currentEntry->tagList()); m_ui->entryTagsList->tags(m_currentEntry->tagList());
m_ui->entryTagsList->setReadOnly(true); m_ui->entryTagsList->setReadOnly(true);
@ -508,8 +508,7 @@ void EntryPreviewWidget::updateGroupGeneralTab()
m_ui->groupAutotypeLabel->setText(autotypeText); m_ui->groupAutotypeLabel->setText(autotypeText);
const TimeInfo groupTime = m_currentGroup->timeInfo(); const TimeInfo groupTime = m_currentGroup->timeInfo();
const QString expiresText = const QString expiresText = groupTime.expires() ? Clock::toString(groupTime.expiryTime()) : tr("Never");
groupTime.expires() ? groupTime.expiryTime().toString(Qt::DefaultLocaleShortDate) : tr("Never");
m_ui->groupExpirationLabel->setText(expiresText); m_ui->groupExpirationLabel->setText(expiresText);
if (config()->get(Config::Security_HideNotes).toBool()) { if (config()->get(Config::Security_HideNotes).toBool()) {

View file

@ -280,7 +280,11 @@ void KMessageWidget::setMessageType(KMessageWidget::MessageType type)
auto closeButtonPixmap = d->closeButtonPixmap; auto closeButtonPixmap = d->closeButtonPixmap;
QPainter painter; QPainter painter;
painter.begin(&closeButtonPixmap); painter.begin(&closeButtonPixmap);
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
painter.setRenderHints(QPainter::Antialiasing);
#else
painter.setRenderHints(QPainter::HighQualityAntialiasing); painter.setRenderHints(QPainter::HighQualityAntialiasing);
#endif
painter.setCompositionMode(QPainter::CompositionMode_SourceIn); painter.setCompositionMode(QPainter::CompositionMode_SourceIn);
painter.fillRect(QRect(0, 0, 16, 16), fg); painter.fillRect(QRect(0, 0, 16, 16), fg);
painter.end(); painter.end();

View file

@ -40,7 +40,7 @@ namespace
return group; return group;
} }
auto nameList = groupPath.split("/", QString::SkipEmptyParts); auto nameList = groupPath.split("/", Qt::SkipEmptyParts);
// Skip over first group name if root // Skip over first group name if root
if (nameList.first().compare("root", Qt::CaseInsensitive) == 0) { if (nameList.first().compare("root", Qt::CaseInsensitive) == 0) {
nameList.removeFirst(); nameList.removeFirst();

View file

@ -1220,7 +1220,10 @@ void EditEntryWidget::updateEntryData(Entry* entry) const
entry->setPassword(m_mainUi->passwordEdit->text()); entry->setPassword(m_mainUi->passwordEdit->text());
entry->setExpires(m_mainUi->expireCheck->isChecked()); entry->setExpires(m_mainUi->expireCheck->isChecked());
entry->setExpiryTime(m_mainUi->expireDatePicker->dateTime().toUTC()); entry->setExpiryTime(m_mainUi->expireDatePicker->dateTime().toUTC());
entry->setTags(m_mainUi->tagsList->tags().toSet().toList().join(";")); // remove repeated tags
QStringList uniqueTags(m_mainUi->tagsList->tags());
uniqueTags.removeDuplicates();
entry->setTags(uniqueTags.join(";"));
entry->setNotes(m_mainUi->notesEdit->toPlainText()); entry->setNotes(m_mainUi->notesEdit->toPlainText());

View file

@ -26,6 +26,7 @@
EntryHistoryModel::EntryHistoryModel(QObject* parent) EntryHistoryModel::EntryHistoryModel(QObject* parent)
: QAbstractTableModel(parent) : QAbstractTableModel(parent)
, m_systemLocale(QLocale::system())
{ {
} }
@ -67,7 +68,7 @@ QVariant EntryHistoryModel::data(const QModelIndex& index, int role) const
switch (index.column()) { switch (index.column()) {
case 0: case 0:
if (role == Qt::DisplayRole) { if (role == Qt::DisplayRole) {
return lastModified.toString(Qt::SystemLocaleShortDate); return m_systemLocale.toString(lastModified, QLocale::ShortFormat);
} else { } else {
return lastModified; return lastModified;
} }

View file

@ -19,6 +19,7 @@
#define KEEPASSX_ENTRYHISTORYMODEL_H #define KEEPASSX_ENTRYHISTORYMODEL_H
#include <QAbstractTableModel> #include <QAbstractTableModel>
#include <QLocale>
class Entry; class Entry;
@ -45,6 +46,7 @@ public:
private: private:
void calculateHistoryModifications(); void calculateHistoryModifications();
QLocale m_systemLocale;
QList<Entry*> m_historyEntries; QList<Entry*> m_historyEntries;
QList<Entry*> m_deletedHistoryEntries; QList<Entry*> m_deletedHistoryEntries;
QStringList m_historyModifications; QStringList m_historyModifications;

View file

@ -21,6 +21,7 @@
#include <QMimeData> #include <QMimeData>
#include <QPalette> #include <QPalette>
#include "core/Clock.h"
#include "core/Entry.h" #include "core/Entry.h"
#include "core/Group.h" #include "core/Group.h"
#include "core/Metadata.h" #include "core/Metadata.h"
@ -36,7 +37,6 @@ EntryModel::EntryModel(QObject* parent)
: QAbstractTableModel(parent) : QAbstractTableModel(parent)
, m_group(nullptr) , m_group(nullptr)
, HiddenContentDisplay(QString("\u25cf").repeated(6)) , HiddenContentDisplay(QString("\u25cf").repeated(6))
, DateFormat(Qt::DefaultLocaleShortDate)
{ {
connect(config(), &Config::changed, this, &EntryModel::onConfigChanged); connect(config(), &Config::changed, this, &EntryModel::onConfigChanged);
} }
@ -189,18 +189,17 @@ QVariant EntryModel::data(const QModelIndex& index, int role) const
return result; return result;
case Expires: case Expires:
// Display either date of expiry or 'Never' // Display either date of expiry or 'Never'
result = entry->timeInfo().expires() result = entry->timeInfo().expires() ? Clock::toString(entry->timeInfo().expiryTime().toLocalTime())
? entry->timeInfo().expiryTime().toLocalTime().toString(EntryModel::DateFormat)
: tr("Never"); : tr("Never");
return result; return result;
case Created: case Created:
result = entry->timeInfo().creationTime().toLocalTime().toString(EntryModel::DateFormat); result = Clock::toString(entry->timeInfo().creationTime().toLocalTime());
return result; return result;
case Modified: case Modified:
result = entry->timeInfo().lastModificationTime().toLocalTime().toString(EntryModel::DateFormat); result = Clock::toString(entry->timeInfo().lastModificationTime().toLocalTime());
return result; return result;
case Accessed: case Accessed:
result = entry->timeInfo().lastAccessTime().toLocalTime().toString(EntryModel::DateFormat); result = Clock::toString(entry->timeInfo().lastAccessTime().toLocalTime());
return result; return result;
case Attachments: { case Attachments: {
// Display comma-separated list of attachments // Display comma-separated list of attachments
@ -251,8 +250,13 @@ QVariant EntryModel::data(const QModelIndex& index, int role) const
return 0; return 0;
} }
case Expires: case Expires:
return entry->timeInfo().expires() ? entry->timeInfo().expiryTime()
// There seems to be no better way of expressing 'infinity' // There seems to be no better way of expressing 'infinity'
return entry->timeInfo().expires() ? entry->timeInfo().expiryTime() : QDateTime(QDate(9999, 1, 1)); #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
: QDate(9999, 1, 1).startOfDay();
#else
: QDateTime(QDate(9999, 1, 1));
#endif
case Created: case Created:
return entry->timeInfo().creationTime(); return entry->timeInfo().creationTime();
case Modified: case Modified:

View file

@ -94,7 +94,6 @@ private:
QSet<const Group*> m_allGroups; QSet<const Group*> m_allGroups;
const QString HiddenContentDisplay; const QString HiddenContentDisplay;
const Qt::DateFormat DateFormat;
}; };
#endif // KEEPASSX_ENTRYMODEL_H #endif // KEEPASSX_ENTRYMODEL_H

View file

@ -19,6 +19,7 @@
#include "config-keepassx.h" #include "config-keepassx.h"
#include "core/Config.h" #include "core/Config.h"
#include "core/Global.h"
#include <QApplication> #include <QApplication>
#include <QDBusInterface> #include <QDBusInterface>
@ -164,7 +165,7 @@ void NixUtils::setLaunchAtStartup(bool enable)
<< QStringLiteral("X-GNOME-Autostart-enabled=true") << '\n' << QStringLiteral("X-GNOME-Autostart-enabled=true") << '\n'
<< QStringLiteral("X-GNOME-Autostart-Delay=2") << '\n' << QStringLiteral("X-GNOME-Autostart-Delay=2") << '\n'
<< QStringLiteral("X-KDE-autostart-after=panel") << '\n' << QStringLiteral("X-KDE-autostart-after=panel") << '\n'
<< QStringLiteral("X-LXQt-Need-Tray=true") << endl; << QStringLiteral("X-LXQt-Need-Tray=true") << Qt::endl;
desktopFile.close(); desktopFile.close();
} else if (isLaunchAtStartupEnabled()) { } else if (isLaunchAtStartupEnabled()) {
QFile::remove(getAutostartDesktopFilename()); QFile::remove(getAutostartDesktopFilename());

View file

@ -29,6 +29,8 @@
#include <QSortFilterProxyModel> #include <QSortFilterProxyModel>
#include <QStandardItemModel> #include <QStandardItemModel>
#include <algorithm>
namespace namespace
{ {
class ReportSortProxyModel : public QSortFilterProxyModel class ReportSortProxyModel : public QSortFilterProxyModel
@ -131,8 +133,8 @@ void ReportsWidgetHibp::makeHibpTable()
} }
} }
// Sort descending by the number the password has been exposed // Sort decending by the number the password has been exposed
qSort(items.begin(), items.end(), [](QPair<Entry*, int>& lhs, QPair<Entry*, int>& rhs) { std::sort(items.begin(), items.end(), [](QPair<Entry*, int>& lhs, QPair<Entry*, int>& rhs) {
return lhs.second > rhs.second; return lhs.second > rhs.second;
}); });

View file

@ -19,6 +19,7 @@
#include "ui_ReportsWidgetStatistics.h" #include "ui_ReportsWidgetStatistics.h"
#include "core/AsyncTask.h" #include "core/AsyncTask.h"
#include "core/Clock.h"
#include "core/DatabaseStats.h" #include "core/DatabaseStats.h"
#include "core/Group.h" #include "core/Group.h"
#include "core/Metadata.h" #include "core/Metadata.h"
@ -86,9 +87,8 @@ void ReportsWidgetStatistics::calculateStats()
addStatsRow(tr("Database name"), m_db->metadata()->name()); addStatsRow(tr("Database name"), m_db->metadata()->name());
addStatsRow(tr("Description"), m_db->metadata()->description()); addStatsRow(tr("Description"), m_db->metadata()->description());
addStatsRow(tr("Location"), m_db->filePath()); addStatsRow(tr("Location"), m_db->filePath());
addStatsRow(tr("Database created"), addStatsRow(tr("Database created"), Clock::toString(m_db->rootGroup()->timeInfo().creationTime()));
m_db->rootGroup()->timeInfo().creationTime().toString(Qt::DefaultLocaleShortDate)); addStatsRow(tr("Last saved"), Clock::toString(stats->modified));
addStatsRow(tr("Last saved"), stats->modified.toString(Qt::DefaultLocaleShortDate));
addStatsRow(tr("Unsaved changes"), addStatsRow(tr("Unsaved changes"),
m_db->isModified() ? tr("yes") : tr("no"), m_db->isModified() ? tr("yes") : tr("no"),
m_db->isModified(), m_db->isModified(),

View file

@ -1456,13 +1456,13 @@ void BaseStyle::drawPrimitive(PrimitiveElement elem,
} }
case PE_FrameDockWidget: { case PE_FrameDockWidget: {
painter->save(); painter->save();
QColor softshadow = option->palette.background().color().darker(120); QColor softshadow = option->palette.window().color().darker(120);
QRect r = option->rect; QRect r = option->rect;
painter->setPen(softshadow); painter->setPen(softshadow);
painter->drawRect(r.adjusted(0, 0, -1, -1)); painter->drawRect(r.adjusted(0, 0, -1, -1));
painter->setPen(QPen(option->palette.light(), 1)); painter->setPen(QPen(option->palette.light(), 1));
painter->drawLine(QPoint(r.left() + 1, r.top() + 1), QPoint(r.left() + 1, r.bottom() - 1)); painter->drawLine(QPoint(r.left() + 1, r.top() + 1), QPoint(r.left() + 1, r.bottom() - 1));
painter->setPen(QPen(option->palette.background().color().darker(120))); painter->setPen(QPen(option->palette.window().color().darker(120)));
painter->drawLine(QPoint(r.left() + 1, r.bottom() - 1), QPoint(r.right() - 2, r.bottom() - 1)); painter->drawLine(QPoint(r.left() + 1, r.bottom() - 1), QPoint(r.right() - 2, r.bottom() - 1));
painter->drawLine(QPoint(r.right() - 1, r.top() + 1), QPoint(r.right() - 1, r.bottom() - 1)); painter->drawLine(QPoint(r.right() - 1, r.top() + 1), QPoint(r.right() - 1, r.bottom() - 1));
painter->restore(); painter->restore();
@ -1714,12 +1714,12 @@ void BaseStyle::drawPrimitive(PrimitiveElement elem,
// TODO replace with new code // TODO replace with new code
const int margin = 6; const int margin = 6;
const int offset = r.height() / 2; const int offset = r.height() / 2;
painter->setPen(QPen(option->palette.background().color().darker(110))); painter->setPen(QPen(option->palette.window().color().darker(110)));
painter->drawLine(r.topLeft().x() + margin, painter->drawLine(r.topLeft().x() + margin,
r.topLeft().y() + offset, r.topLeft().y() + offset,
r.topRight().x() - margin, r.topRight().x() - margin,
r.topRight().y() + offset); r.topRight().y() + offset);
painter->setPen(QPen(option->palette.background().color().lighter(110))); painter->setPen(QPen(option->palette.window().color().lighter(110)));
painter->drawLine(r.topLeft().x() + margin, painter->drawLine(r.topLeft().x() + margin,
r.topLeft().y() + offset + 1, r.topLeft().y() + offset + 1,
r.topRight().x() - margin, r.topRight().x() - margin,
@ -3248,13 +3248,13 @@ void BaseStyle::drawComplexControl(ComplexControl control,
QColor outline = option->palette.dark().color(); QColor outline = option->palette.dark().color();
QColor titleBarFrameBorder(active ? highlight.darker(180) : outline.darker(110)); QColor titleBarFrameBorder(active ? highlight.darker(180) : outline.darker(110));
QColor titleBarHighlight(active ? highlight.lighter(120) : palette.background().color().lighter(120)); QColor titleBarHighlight(active ? highlight.lighter(120) : palette.window().color().lighter(120));
QColor textColor(active ? 0xffffff : 0xff000000); QColor textColor(active ? 0xffffff : 0xff000000);
QColor textAlphaColor(active ? 0xffffff : 0xff000000); QColor textAlphaColor(active ? 0xffffff : 0xff000000);
{ {
// Fill title // Fill title
auto titlebarColor = QColor(active ? highlight : palette.background().color()); auto titlebarColor = QColor(active ? highlight : palette.window().color());
painter->fillRect(option->rect.adjusted(1, 1, -1, 0), titlebarColor); painter->fillRect(option->rect.adjusted(1, 1, -1, 0), titlebarColor);
// Frame and rounded corners // Frame and rounded corners
painter->setPen(titleBarFrameBorder); painter->setPen(titleBarFrameBorder);

View file

@ -24,7 +24,7 @@
#include <QSet> #include <QSet>
#include <QtConcurrent> #include <QtConcurrent>
QMutex YubiKey::s_interfaceMutex(QMutex::Recursive); QMutex YubiKey::s_interfaceMutex;
YubiKey::YubiKey() YubiKey::YubiKey()
{ {

View file

@ -24,6 +24,7 @@
#include <QMutex> #include <QMutex>
#include <QObject> #include <QObject>
#include <QTimer> #include <QTimer>
#include <botan/secmem.h> #include <botan/secmem.h>
typedef QPair<unsigned int, int> YubiKeySlot; typedef QPair<unsigned int, int> YubiKeySlot;

View file

@ -100,7 +100,7 @@ int main(int argc, char** argv)
if (parser.isSet(debugInfoOption)) { if (parser.isSet(debugInfoOption)) {
QTextStream out(stdout, QIODevice::WriteOnly); QTextStream out(stdout, QIODevice::WriteOnly);
QString debugInfo = Tools::debugInfo().append("\n").append(Crypto::debugInfo()); QString debugInfo = Tools::debugInfo().append("\n").append(Crypto::debugInfo());
out << debugInfo << endl; out << debugInfo << Qt::endl;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
@ -194,7 +194,7 @@ int main(int argc, char** argv)
// we always need consume a line of STDIN if --pw-stdin is set to clear out the // we always need consume a line of STDIN if --pw-stdin is set to clear out the
// buffer for native messaging, even if the specified file does not exist // buffer for native messaging, even if the specified file does not exist
QTextStream out(stdout, QIODevice::WriteOnly); QTextStream out(stdout, QIODevice::WriteOnly);
out << QObject::tr("Database password: ") << flush; out << QObject::tr("Database password: ") << Qt::flush;
password = Utils::getPassword(); password = Utils::getPassword();
} }
mainWindow.openDatabase(filename, password, parser.value(keyfileOption)); mainWindow.openDatabase(filename, password, parser.value(keyfileOption));

View file

@ -20,6 +20,7 @@
#include "ASN1Key.h" #include "ASN1Key.h"
#include "BinaryStream.h" #include "BinaryStream.h"
#include "core/Global.h"
#include "crypto/Random.h" #include "crypto/Random.h"
#include "crypto/SymmetricCipher.h" #include "crypto/SymmetricCipher.h"
@ -226,7 +227,7 @@ void OpenSSHKey::clearPrivate()
bool OpenSSHKey::extractPEM(const QByteArray& in, QByteArray& out) bool OpenSSHKey::extractPEM(const QByteArray& in, QByteArray& out)
{ {
QString pem = QString::fromLatin1(in); QString pem = QString::fromLatin1(in);
QStringList rows = pem.split(QRegularExpression("(?:\r?\n|\r)"), QString::SkipEmptyParts); QStringList rows = pem.split(QRegularExpression("(?:\r?\n|\r)"), Qt::SkipEmptyParts);
if (rows.length() < 3) { if (rows.length() < 3) {
m_error = tr("Invalid key file, expecting an OpenSSH key"); m_error = tr("Invalid key file, expecting an OpenSSH key");

View file

@ -78,7 +78,7 @@
</sizepolicy> </sizepolicy>
</property> </property>
<property name="sizeAdjustPolicy"> <property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToMinimumContentsLength</enum> <enum>QComboBox::AdjustToContents</enum>
</property> </property>
<property name="minimumContentsLength"> <property name="minimumContentsLength">
<number>4</number> <number>4</number>

View file

@ -57,7 +57,7 @@ void TestSSHAgent::initTestCase()
QSKIP("ssh-agent could not be started"); QSKIP("ssh-agent could not be started");
} }
qDebug() << "ssh-agent started as pid" << m_agentProcess.pid(); qDebug() << "ssh-agent started as pid" << m_agentProcess.processId();
// we need to wait for the agent to open the socket before going into real tests // we need to wait for the agent to open the socket before going into real tests
QFileInfo socketFileInfo(m_agentSocketFileName); QFileInfo socketFileInfo(m_agentSocketFileName);
@ -288,7 +288,7 @@ void TestSSHAgent::testKeyGenEd25519()
void TestSSHAgent::cleanupTestCase() void TestSSHAgent::cleanupTestCase()
{ {
if (m_agentProcess.state() != QProcess::NotRunning) { if (m_agentProcess.state() != QProcess::NotRunning) {
qDebug() << "Killing ssh-agent pid" << m_agentProcess.pid(); qDebug() << "Killing ssh-agent pid" << m_agentProcess.processId();
m_agentProcess.terminate(); m_agentProcess.terminate();
m_agentProcess.waitForFinished(); m_agentProcess.waitForFinished();
} }

View file

@ -84,7 +84,7 @@ private:
void clickIndex(const QModelIndex& index, void clickIndex(const QModelIndex& index,
QAbstractItemView* view, QAbstractItemView* view,
Qt::MouseButton button, Qt::MouseButton button,
Qt::KeyboardModifiers stateKey = 0); Qt::KeyboardModifiers stateKey = {});
void checkSaveDatabase(); void checkSaveDatabase();
void checkStatusBarText(const QString& textFragment); void checkStatusBarText(const QString& textFragment);
void prepareAndTriggerRemoteSync(const QString& sourceToSync); void prepareAndTriggerRemoteSync(const QString& sourceToSync);

View file

@ -46,7 +46,7 @@ private:
void clickIndex(const QModelIndex& index, void clickIndex(const QModelIndex& index,
QAbstractItemView* view, QAbstractItemView* view,
Qt::MouseButton button, Qt::MouseButton button,
Qt::KeyboardModifiers stateKey = 0); Qt::KeyboardModifiers stateKey = {});
QScopedPointer<MainWindow> m_mainWindow; QScopedPointer<MainWindow> m_mainWindow;
QPointer<DatabaseTabWidget> m_tabWidget; QPointer<DatabaseTabWidget> m_tabWidget;

View file

@ -26,6 +26,7 @@
#include "config-keepassx-tests.h" #include "config-keepassx-tests.h"
#include "core/Global.h"
#include "core/Tools.h" #include "core/Tools.h"
#include "crypto/Crypto.h" #include "crypto/Crypto.h"
#include "gui/Application.h" #include "gui/Application.h"
@ -1246,7 +1247,7 @@ void TestGuiFdoSecrets::testItemReplace()
{ {
DBUS_GET2(unlocked, locked, service->SearchItems({{"application", "fdosecrets-test"}})); DBUS_GET2(unlocked, locked, service->SearchItems({{"application", "fdosecrets-test"}}));
QSet<QDBusObjectPath> expected{QDBusObjectPath(item1->path()), QDBusObjectPath(item2->path())}; QSet<QDBusObjectPath> expected{QDBusObjectPath(item1->path()), QDBusObjectPath(item2->path())};
COMPARE(QSet<QDBusObjectPath>::fromList(unlocked), expected); COMPARE(Tools::asSet(unlocked), expected);
} }
QSignalSpy spyItemCreated(coll.data(), SIGNAL(ItemCreated(QDBusObjectPath))); QSignalSpy spyItemCreated(coll.data(), SIGNAL(ItemCreated(QDBusObjectPath)));
@ -1263,7 +1264,7 @@ void TestGuiFdoSecrets::testItemReplace()
// there are still 2 entries // there are still 2 entries
DBUS_GET2(unlocked, locked, service->SearchItems({{"application", "fdosecrets-test"}})); DBUS_GET2(unlocked, locked, service->SearchItems({{"application", "fdosecrets-test"}}));
QSet<QDBusObjectPath> expected{QDBusObjectPath(item1->path()), QDBusObjectPath(item2->path())}; QSet<QDBusObjectPath> expected{QDBusObjectPath(item1->path()), QDBusObjectPath(item2->path())};
COMPARE(QSet<QDBusObjectPath>::fromList(unlocked), expected); COMPARE(Tools::asSet(unlocked), expected);
VERIFY(waitForSignal(spyItemCreated, 0)); VERIFY(waitForSignal(spyItemCreated, 0));
// there may be multiple changed signals, due to each item attribute is set separately // there may be multiple changed signals, due to each item attribute is set separately
@ -1289,7 +1290,7 @@ void TestGuiFdoSecrets::testItemReplace()
QDBusObjectPath(item2->path()), QDBusObjectPath(item2->path()),
QDBusObjectPath(item4->path()), QDBusObjectPath(item4->path()),
}; };
COMPARE(QSet<QDBusObjectPath>::fromList(unlocked), expected); COMPARE(Tools::asSet(unlocked), expected);
VERIFY(waitForSignal(spyItemCreated, 1)); VERIFY(waitForSignal(spyItemCreated, 1));
{ {
@ -1617,7 +1618,7 @@ void TestGuiFdoSecrets::testExposeSubgroup()
for (const auto& itemPath : itemPaths) { for (const auto& itemPath : itemPaths) {
exposedEntries << m_plugin->dbus()->pathToObject<Item>(itemPath)->backend(); exposedEntries << m_plugin->dbus()->pathToObject<Item>(itemPath)->backend();
} }
COMPARE(exposedEntries, QSet<Entry*>::fromList(subgroup->entries())); COMPARE(exposedEntries, Tools::asSet(subgroup->entries()));
} }
void TestGuiFdoSecrets::testModifyingExposedGroup() void TestGuiFdoSecrets::testModifyingExposedGroup()

View file

@ -452,12 +452,12 @@ void ModelTest::data()
} }
// General Purpose roles that should return a QColor // General Purpose roles that should return a QColor
QVariant colorVariant = model->data ( model->index ( 0, 0 ), Qt::BackgroundColorRole ); QVariant colorVariant = model->data ( model->index ( 0, 0 ), Qt::BackgroundRole );
if ( colorVariant.isValid() ) { if ( colorVariant.isValid() ) {
QVERIFY( colorVariant.canConvert<QColor>() ); QVERIFY( colorVariant.canConvert<QColor>() );
} }
colorVariant = model->data ( model->index ( 0, 0 ), Qt::TextColorRole ); colorVariant = model->data ( model->index ( 0, 0 ), Qt::ForegroundRole );
if ( colorVariant.isValid() ) { if ( colorVariant.isValid() ) {
QVERIFY( colorVariant.canConvert<QColor>() ); QVERIFY( colorVariant.canConvert<QColor>() );
} }