From e909d1b5945f0e82ac4a6a9edb6784b83a547e7e Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Tue, 19 Mar 2019 21:12:39 -0400 Subject: Correct invalid conditional check in release-tool --- release-tool | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/release-tool b/release-tool index a04ad5de9..ab4128a35 100755 --- a/release-tool +++ b/release-tool @@ -810,10 +810,6 @@ build() { shift done - if [[ ${build_appsign} && ! -f ${build_key} ]]; then - exitError "--appsign specified with invalid key file\n" - fi - init OUTPUT_DIR="$(realpath "$OUTPUT_DIR")" @@ -908,7 +904,7 @@ build() { make ${MAKE_OPTIONS} package # Appsign the executables if desired - if [[ ${build_appsign} ]]; then + if ${build_appsign}; then logInfo "Signing executable files" appsign "-f" "./${APP_NAME}-${RELEASE_NAME}.dmg" "-k" "${build_key}" fi @@ -924,7 +920,7 @@ build() { mingw32-make ${MAKE_OPTIONS} preinstall # Appsign the executables if desired - if [[ ${build_appsign} ]]; then + if ${build_appsign} && [ -f ${build_key} ]; then logInfo "Signing executable files" appsign "-f" $(find src | grep -P '\.exe$|\.dll$') "-k" "${build_key}" fi -- cgit v1.2.3 From eb9ff677d0c681a86a9ef296f5a363549b94c42c Mon Sep 17 00:00:00 2001 From: Lars Wendler Date: Wed, 20 Mar 2019 11:53:21 +0100 Subject: src/gui/DatabaseWidget.cpp: Build fails without WITH_XC_KEESHARE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit /var/tmp/portage/app-admin/keepassxc-2.4.0/work/keepassxc-2.4.0/src/gui/DatabaseWidget.cpp: In member function ‘void DatabaseWidget::search(const QString&)’: /var/tmp/portage/app-admin/keepassxc-2.4.0/work/keepassxc-2.4.0/src/gui/DatabaseWidget.cpp:1115:5: error: ‘m_shareLabel’ was not declared in this scope m_shareLabel->setVisible(false); ^~~~~~~~~~~~ /var/tmp/portage/app-admin/keepassxc-2.4.0/work/keepassxc-2.4.0/src/gui/DatabaseWidget.cpp:1115:5: note: suggested alternative: ‘m_searchingLabel’ m_shareLabel->setVisible(false); ^~~~~~~~~~~~ m_searchingLabel --- src/gui/DatabaseWidget.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp index 8728c331f..e4196734b 100644 --- a/src/gui/DatabaseWidget.cpp +++ b/src/gui/DatabaseWidget.cpp @@ -1112,7 +1112,9 @@ void DatabaseWidget::search(const QString& searchtext) } m_searchingLabel->setVisible(true); +#ifdef WITH_XC_KEESHARE m_shareLabel->setVisible(false); +#endif emit searchModeActivated(); } -- cgit v1.2.3 From 4a0bb32c2ec13e142b5eec80423678f466a7b1a1 Mon Sep 17 00:00:00 2001 From: Lars Wendler Date: Fri, 8 Mar 2019 14:48:13 +0100 Subject: Don't call mandb There are other man implementations beside man-db so it is not even sure that the "mandb" binary even exists on all unices. Other than that, usually there's a cron job running "mandb" on a daily basis. --- src/cli/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cli/CMakeLists.txt b/src/cli/CMakeLists.txt index e59a911a5..c3f97a2cd 100644 --- a/src/cli/CMakeLists.txt +++ b/src/cli/CMakeLists.txt @@ -94,5 +94,4 @@ endif() if(APPLE OR UNIX) install(FILES keepassxc-cli.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1/) - execute_process(COMMAND mandb -q) endif() -- cgit v1.2.3 From 76913a5dd1411fc911fd9a346a2d230d5cb6d18e Mon Sep 17 00:00:00 2001 From: Oirio Joshi Date: Thu, 21 Mar 2019 23:53:50 +0100 Subject: Snap: improve cursor theme --- snapcraft.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/snapcraft.yaml b/snapcraft.yaml index 16eb0890d..6dd3ea2c1 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -9,6 +9,12 @@ description: | confinement: strict base: core18 +plugs: + icon-themes: # fix mouse cursor theme + interface: content + target: $SNAP/data-dir/icons + default-provider: gtk-common-themes + apps: keepassxc: command: desktop-launch keepassxc @@ -67,6 +73,7 @@ parts: - libquazip5-1 - libusb-1.0-0 - qtwayland5 + - qt5-style-plugins # for mouse cursor theme fix override-build: | snapcraftctl build sed -i 's|Icon=keepassxc|Icon=${SNAP}/usr/share/icons/hicolor/256x256/apps/keepassxc.png|g' $SNAPCRAFT_PART_INSTALL/usr/share/applications/org.keepassxc.KeePassXC.desktop -- cgit v1.2.3 From a58e3d5ee0113019adea182830b2fcc9e5387184 Mon Sep 17 00:00:00 2001 From: louib Date: Mon, 18 Feb 2019 20:17:28 -0500 Subject: Adding debug info to CLI. Adding debug info to the CLI and the general option of the main Qt app. Also took time to: * use `EXIT_SUCCESS`/`EXIT_FAILURE` constants for main.cpp (this is what is used in `src/cli`); * fixed `m_initalized` typo; * added info on debugging mode being disabled or not; * regrouped Qt related stuff in the debug output. --- src/cli/keepassxc-cli.1 | 5 ++- src/cli/keepassxc-cli.cpp | 8 ++++ src/core/Tools.cpp | 76 ++++++++++++++++++++++++++++++++++++ src/core/Tools.h | 1 + src/crypto/Crypto.cpp | 22 ++++++----- src/crypto/Crypto.h | 6 +-- src/crypto/CryptoHash.cpp | 2 +- src/crypto/Random.cpp | 2 +- src/crypto/SymmetricCipherGcrypt.cpp | 2 +- src/gui/AboutDialog.cpp | 66 ++----------------------------- src/main.cpp | 18 +++++++-- 11 files changed, 126 insertions(+), 82 deletions(-) diff --git a/src/cli/keepassxc-cli.1 b/src/cli/keepassxc-cli.1 index 22cf88a3a..4cee31774 100644 --- a/src/cli/keepassxc-cli.1 +++ b/src/cli/keepassxc-cli.1 @@ -56,6 +56,9 @@ Shows the title, username, password, URL and notes of a database entry. Can also .SS "General options" +.IP "--debug-info" +Displays debugging information. + .IP "-k, --key-file " Specifies a path to a key file for unlocking the database. In a merge operation this option is used to specify the key file path for the first database. @@ -66,7 +69,7 @@ Silence password prompt and other secondary outputs. Displays help information. .IP "-v, --version" -Shows the program version. +Displays the program version. .SS "Merge options" diff --git a/src/cli/keepassxc-cli.cpp b/src/cli/keepassxc-cli.cpp index b9e3853f2..2c6ce4660 100644 --- a/src/cli/keepassxc-cli.cpp +++ b/src/cli/keepassxc-cli.cpp @@ -26,6 +26,7 @@ #include "config-keepassx.h" #include "core/Bootstrap.h" +#include "core/Tools.h" #include "crypto/Crypto.h" #if defined(WITH_ASAN) && defined(WITH_LSAN) @@ -60,6 +61,9 @@ int main(int argc, char** argv) parser.addPositionalArgument("command", QObject::tr("Name of the command to execute.")); + QCommandLineOption debugInfoOption(QStringList() << "debug-info", + QObject::tr("Displays debugging information.")); + parser.addOption(debugInfoOption); parser.addHelpOption(); parser.addVersionOption(); // TODO : use the setOptionsAfterPositionalArgumentsMode (Qt 5.6) function @@ -72,6 +76,10 @@ int main(int argc, char** argv) // Switch to parser.showVersion() when available (QT 5.4). out << KEEPASSXC_VERSION << endl; return EXIT_SUCCESS; + } else if (parser.isSet(debugInfoOption)) { + QString debugInfo = Tools::debugInfo().append("\n").append(Crypto::debugInfo()); + out << debugInfo << endl; + return EXIT_SUCCESS; } parser.showHelp(); } diff --git a/src/core/Tools.cpp b/src/core/Tools.cpp index b77a460d4..09938b82a 100644 --- a/src/core/Tools.cpp +++ b/src/core/Tools.cpp @@ -18,6 +18,8 @@ */ #include "Tools.h" + +#include "config-keepassx.h" #include "core/Config.h" #include "core/Translator.h" @@ -28,8 +30,10 @@ #include #include #include +#include #include #include +#include "git-info.h" #ifdef Q_OS_WIN #include // for Sleep() @@ -41,6 +45,78 @@ namespace Tools { + QString debugInfo() + { + QString debugInfo = "KeePassXC - "; + debugInfo.append(QObject::tr("Version %1").arg(KEEPASSXC_VERSION).append("\n")); +#ifndef KEEPASSXC_BUILD_TYPE_RELEASE + debugInfo.append(QObject::tr("Build Type: %1").arg(KEEPASSXC_BUILD_TYPE).append("\n")); +#endif + + QString commitHash; + if (!QString(GIT_HEAD).isEmpty()) { + commitHash = GIT_HEAD; + } + if (!commitHash.isEmpty()) { + debugInfo.append(QObject::tr("Revision: %1").arg(commitHash.left(7)).append("\n")); + } + +#ifdef KEEPASSXC_DIST + debugInfo.append(QObject::tr("Distribution: %1").arg(KEEPASSXC_DIST_TYPE).append("\n")); +#endif + + // Qt related debugging information. + debugInfo.append("\n"); + debugInfo.append("Qt ").append(QString::fromLocal8Bit(qVersion())).append("\n"); +#ifdef QT_NO_DEBUG + debugInfo.append(QObject::tr("Debugging mode is disabled.").append("\n")); +#else + debugInfo.append(QObject::tr("Debugging mode is enabled.").append("\n")); +#endif + debugInfo.append("\n"); + + +#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) + debugInfo.append(QObject::tr("Operating system: %1\nCPU architecture: %2\nKernel: %3 %4") + .arg(QSysInfo::prettyProductName(), + QSysInfo::currentCpuArchitecture(), + QSysInfo::kernelType(), + QSysInfo::kernelVersion())); + + debugInfo.append("\n\n"); +#endif + + QString extensions; +#ifdef WITH_XC_AUTOTYPE + extensions += "\n- " + QObject::tr("Auto-Type"); +#endif +#ifdef WITH_XC_BROWSER + extensions += "\n- " + QObject::tr("Browser Integration"); +#endif +#ifdef WITH_XC_SSHAGENT + extensions += "\n- " + QObject::tr("SSH Agent"); +#endif +#if defined(WITH_XC_KEESHARE_SECURE) && defined(WITH_XC_KEESHARE_INSECURE) + extensions += "\n- " + QObject::tr("KeeShare (signed and unsigned sharing)"); +#elif defined(WITH_XC_KEESHARE_SECURE) + extensions += "\n- " + QObject::tr("KeeShare (only signed sharing)"); +#elif defined(WITH_XC_KEESHARE_INSECURE) + extensions += "\n- " + QObject::tr("KeeShare (only unsigned sharing)"); +#endif +#ifdef WITH_XC_YUBIKEY + extensions += "\n- " + QObject::tr("YubiKey"); +#endif +#ifdef WITH_XC_TOUCHID + extensions += "\n- " + QObject::tr("TouchID"); +#endif + + if (extensions.isEmpty()) + extensions = " " + QObject::tr("None"); + + debugInfo.append(QObject::tr("Enabled extensions:").append(extensions).append("\n")); + return debugInfo; + } + QString humanReadableFileSize(qint64 bytes, quint32 precision) { constexpr auto kibibyte = 1024; diff --git a/src/core/Tools.h b/src/core/Tools.h index a2c09efe2..1fa5e6a9a 100644 --- a/src/core/Tools.h +++ b/src/core/Tools.h @@ -32,6 +32,7 @@ class QRegularExpression; namespace Tools { + QString debugInfo(); QString humanReadableFileSize(qint64 bytes, quint32 precision = 2); bool readFromDevice(QIODevice* device, QByteArray& data, int size = 16384); bool readAllFromDevice(QIODevice* device, QByteArray& data); diff --git a/src/crypto/Crypto.cpp b/src/crypto/Crypto.cpp index ab97322ca..4f54ac1d3 100644 --- a/src/crypto/Crypto.cpp +++ b/src/crypto/Crypto.cpp @@ -25,7 +25,7 @@ #include "crypto/CryptoHash.h" #include "crypto/SymmetricCipher.h" -bool Crypto::m_initalized(false); +bool Crypto::m_initialized(false); QString Crypto::m_errorStr; QString Crypto::m_backendVersion; @@ -35,8 +35,8 @@ Crypto::Crypto() bool Crypto::init() { - if (m_initalized) { - qWarning("Crypto::init: already initalized"); + if (m_initialized) { + qWarning("Crypto::init: already initialized"); return true; } @@ -48,19 +48,19 @@ bool Crypto::init() } // has to be set before testing Crypto classes - m_initalized = true; + m_initialized = true; if (!backendSelfTest() || !selfTest()) { - m_initalized = false; + m_initialized = false; return false; } return true; } -bool Crypto::initalized() +bool Crypto::initialized() { - return m_initalized; + return m_initialized; } QString Crypto::errorString() @@ -68,9 +68,13 @@ QString Crypto::errorString() return m_errorStr; } -QString Crypto::backendVersion() +QString Crypto::debugInfo() { - return QString("libgcrypt ").append(m_backendVersion); + Q_ASSERT(Crypto::initialized()); + + QString debugInfo = QObject::tr("Cryptographic libraries:").append("\n"); + debugInfo.append(" libgcrypt ").append(m_backendVersion).append("\n"); + return debugInfo; } bool Crypto::backendSelfTest() diff --git a/src/crypto/Crypto.h b/src/crypto/Crypto.h index 379068eb4..4346f5055 100644 --- a/src/crypto/Crypto.h +++ b/src/crypto/Crypto.h @@ -24,10 +24,10 @@ class Crypto { public: static bool init(); - static bool initalized(); + static bool initialized(); static bool backendSelfTest(); static QString errorString(); - static QString backendVersion(); + static QString debugInfo(); private: Crypto(); @@ -42,7 +42,7 @@ private: static bool testSalsa20(); static bool testChaCha20(); - static bool m_initalized; + static bool m_initialized; static QString m_errorStr; static QString m_backendVersion; }; diff --git a/src/crypto/CryptoHash.cpp b/src/crypto/CryptoHash.cpp index 07bf5efc9..5eab8567a 100644 --- a/src/crypto/CryptoHash.cpp +++ b/src/crypto/CryptoHash.cpp @@ -33,7 +33,7 @@ CryptoHash::CryptoHash(Algorithm algo, bool hmac) { Q_D(CryptoHash); - Q_ASSERT(Crypto::initalized()); + Q_ASSERT(Crypto::initialized()); int algoGcrypt = -1; unsigned int flagsGcrypt = GCRY_MD_FLAG_SECURE; diff --git a/src/crypto/Random.cpp b/src/crypto/Random.cpp index 4203b6c0c..024a82f91 100644 --- a/src/crypto/Random.cpp +++ b/src/crypto/Random.cpp @@ -93,7 +93,7 @@ Random::Random(RandomBackend* backend) void RandomBackendGcrypt::randomize(void* data, int len) { - Q_ASSERT(Crypto::initalized()); + Q_ASSERT(Crypto::initialized()); gcry_randomize(data, len, GCRY_STRONG_RANDOM); } diff --git a/src/crypto/SymmetricCipherGcrypt.cpp b/src/crypto/SymmetricCipherGcrypt.cpp index fb436522d..4d12d25a9 100644 --- a/src/crypto/SymmetricCipherGcrypt.cpp +++ b/src/crypto/SymmetricCipherGcrypt.cpp @@ -90,7 +90,7 @@ void SymmetricCipherGcrypt::setError(const gcry_error_t& err) bool SymmetricCipherGcrypt::init() { - Q_ASSERT(Crypto::initalized()); + Q_ASSERT(Crypto::initialized()); gcry_error_t error; diff --git a/src/gui/AboutDialog.cpp b/src/gui/AboutDialog.cpp index 0de79fccc..f37baedc0 100644 --- a/src/gui/AboutDialog.cpp +++ b/src/gui/AboutDialog.cpp @@ -21,11 +21,11 @@ #include "config-keepassx.h" #include "core/FilePath.h" +#include "core/Tools.h" #include "crypto/Crypto.h" -#include "git-info.h" #include -#include + static const QString aboutMaintainers = R"(

    @@ -175,67 +175,7 @@ AboutDialog::AboutDialog(QWidget* parent) m_ui->iconLabel->setPixmap(filePath()->applicationIcon().pixmap(48)); - QString commitHash; - if (!QString(GIT_HEAD).isEmpty()) { - commitHash = GIT_HEAD; - } - - QString debugInfo = "KeePassXC - "; - debugInfo.append(tr("Version %1").arg(KEEPASSXC_VERSION).append("\n")); -#ifndef KEEPASSXC_BUILD_TYPE_RELEASE - debugInfo.append(tr("Build Type: %1").arg(KEEPASSXC_BUILD_TYPE).append("\n")); -#endif - if (!commitHash.isEmpty()) { - debugInfo.append(tr("Revision: %1").arg(commitHash.left(7)).append("\n")); - } - -#ifdef KEEPASSXC_DIST - debugInfo.append(tr("Distribution: %1").arg(KEEPASSXC_DIST_TYPE).append("\n")); -#endif - - debugInfo.append("\n").append( - QString("%1\n- Qt %2\n- %3\n\n") - .arg(tr("Libraries:"), QString::fromLocal8Bit(qVersion()), Crypto::backendVersion())); - -#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) - debugInfo.append(tr("Operating system: %1\nCPU architecture: %2\nKernel: %3 %4") - .arg(QSysInfo::prettyProductName(), - QSysInfo::currentCpuArchitecture(), - QSysInfo::kernelType(), - QSysInfo::kernelVersion())); - - debugInfo.append("\n\n"); -#endif - - QString extensions; -#ifdef WITH_XC_AUTOTYPE - extensions += "\n- " + tr("Auto-Type"); -#endif -#ifdef WITH_XC_BROWSER - extensions += "\n- " + tr("Browser Integration"); -#endif -#ifdef WITH_XC_SSHAGENT - extensions += "\n- " + tr("SSH Agent"); -#endif -#if defined(WITH_XC_KEESHARE_SECURE) && defined(WITH_XC_KEESHARE_INSECURE) - extensions += "\n- " + tr("KeeShare (signed and unsigned sharing)"); -#elif defined(WITH_XC_KEESHARE_SECURE) - extensions += "\n- " + tr("KeeShare (only signed sharing)"); -#elif defined(WITH_XC_KEESHARE_INSECURE) - extensions += "\n- " + tr("KeeShare (only unsigned sharing)"); -#endif -#ifdef WITH_XC_YUBIKEY - extensions += "\n- " + tr("YubiKey"); -#endif -#ifdef WITH_XC_TOUCHID - extensions += "\n- " + tr("TouchID"); -#endif - - if (extensions.isEmpty()) - extensions = " " + tr("None"); - - debugInfo.append(tr("Enabled extensions:").append(extensions)); - + QString debugInfo = Tools::debugInfo().append("\n").append(Crypto::debugInfo()); m_ui->debugInfo->setPlainText(debugInfo); m_ui->maintainers->setText(aboutMaintainers); diff --git a/src/main.cpp b/src/main.cpp index a546c0491..e975a6b9c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -82,16 +82,19 @@ int main(int argc, char** argv) QCommandLineOption helpOption = parser.addHelpOption(); QCommandLineOption versionOption = parser.addVersionOption(); + QCommandLineOption debugInfoOption(QStringList() << "debug-info", + QObject::tr("Displays debugging information.")); parser.addOption(configOption); parser.addOption(keyfileOption); parser.addOption(pwstdinOption); parser.addOption(parentWindowOption); + parser.addOption(debugInfoOption); parser.process(app); // Don't try and do anything with the application if we're only showing the help / version if (parser.isSet(versionOption) || parser.isSet(helpOption)) { - return 0; + return EXIT_SUCCESS; } const QStringList fileNames = parser.positionalArguments(); @@ -101,7 +104,7 @@ int main(int argc, char** argv) app.sendFileNamesToRunningInstance(fileNames); } qWarning() << QObject::tr("Another instance of KeePassXC is already running.").toUtf8().constData(); - return 0; + return EXIT_SUCCESS; } QApplication::setQuitOnLastWindowClosed(false); @@ -111,7 +114,16 @@ int main(int argc, char** argv) error.append("\n"); error.append(Crypto::errorString()); MessageBox::critical(nullptr, QObject::tr("KeePassXC - Error"), error); - return 1; + return EXIT_FAILURE; + } + + // Displaying the debugging informations must be done after Crypto::init, + // to make sure we know which libgcrypt version is used. + if (parser.isSet(debugInfoOption)) { + QTextStream out(stdout, QIODevice::WriteOnly); + QString debugInfo = Tools::debugInfo().append("\n").append(Crypto::debugInfo()); + out << debugInfo << endl; + return EXIT_SUCCESS; } if (parser.isSet(configOption)) { -- cgit v1.2.3 From 13a9ac8f576539aace93a2d5faa2c4d35474f95e Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Sun, 24 Mar 2019 08:51:40 -0400 Subject: Adding --no-password option to CLI I also added tests for the --key-file option, which was untested. --- src/cli/Add.cpp | 2 + src/cli/Clip.cpp | 2 + src/cli/Command.cpp | 4 ++ src/cli/Command.h | 1 + src/cli/Edit.cpp | 2 + src/cli/Extract.cpp | 21 ++++--- src/cli/List.cpp | 2 + src/cli/Locate.cpp | 2 + src/cli/Merge.cpp | 7 +++ src/cli/Remove.cpp | 2 + src/cli/Show.cpp | 3 + src/cli/Utils.cpp | 14 +++-- src/cli/Utils.h | 1 + src/cli/keepassxc-cli.1 | 6 ++ tests/TestCli.cpp | 91 +++++++++++++++++++++++++++-- tests/TestCli.h | 6 ++ tests/data/KeyFileProtected.kdbx | Bin 0 -> 1637 bytes tests/data/KeyFileProtected.key | Bin 0 -> 128 bytes tests/data/KeyFileProtectedNoPassword.kdbx | Bin 0 -> 1589 bytes tests/data/KeyFileProtectedNoPassword.key | Bin 0 -> 128 bytes 20 files changed, 146 insertions(+), 20 deletions(-) create mode 100644 tests/data/KeyFileProtected.kdbx create mode 100644 tests/data/KeyFileProtected.key create mode 100644 tests/data/KeyFileProtectedNoPassword.kdbx create mode 100644 tests/data/KeyFileProtectedNoPassword.key diff --git a/src/cli/Add.cpp b/src/cli/Add.cpp index dd9d0b50c..395b84919 100644 --- a/src/cli/Add.cpp +++ b/src/cli/Add.cpp @@ -50,6 +50,7 @@ int Add::execute(const QStringList& arguments) parser.addPositionalArgument("database", QObject::tr("Path of the database.")); parser.addOption(Command::QuietOption); parser.addOption(Command::KeyFileOption); + parser.addOption(Command::NoPasswordOption); QCommandLineOption username(QStringList() << "u" << "username", @@ -91,6 +92,7 @@ int Add::execute(const QStringList& arguments) const QString& entryPath = args.at(1); auto db = Utils::unlockDatabase(databasePath, + !parser.isSet(Command::NoPasswordOption), parser.value(Command::KeyFileOption), parser.isSet(Command::QuietOption) ? Utils::DEVNULL : Utils::STDOUT, Utils::STDERR); diff --git a/src/cli/Clip.cpp b/src/cli/Clip.cpp index 6e346f25c..31b421de6 100644 --- a/src/cli/Clip.cpp +++ b/src/cli/Clip.cpp @@ -49,6 +49,7 @@ int Clip::execute(const QStringList& arguments) parser.addPositionalArgument("database", QObject::tr("Path of the database.")); parser.addOption(Command::QuietOption); parser.addOption(Command::KeyFileOption); + parser.addOption(Command::NoPasswordOption); QCommandLineOption totp(QStringList() << "t" << "totp", @@ -67,6 +68,7 @@ int Clip::execute(const QStringList& arguments) } auto db = Utils::unlockDatabase(args.at(0), + !parser.isSet(Command::NoPasswordOption), parser.value(Command::KeyFileOption), parser.isSet(Command::QuietOption) ? Utils::DEVNULL : Utils::STDOUT, Utils::STDERR); diff --git a/src/cli/Command.cpp b/src/cli/Command.cpp index 79d56c360..e64dd4aaa 100644 --- a/src/cli/Command.cpp +++ b/src/cli/Command.cpp @@ -46,6 +46,10 @@ const QCommandLineOption Command::KeyFileOption = QCommandLineOption(QStringList QObject::tr("Key file of the database."), QObject::tr("path")); +const QCommandLineOption Command::NoPasswordOption = + QCommandLineOption(QStringList() << "no-password", + QObject::tr("Deactivate password key for the database.")); + QMap commands; Command::~Command() diff --git a/src/cli/Command.h b/src/cli/Command.h index b74a312df..30af61702 100644 --- a/src/cli/Command.h +++ b/src/cli/Command.h @@ -40,6 +40,7 @@ public: static const QCommandLineOption QuietOption; static const QCommandLineOption KeyFileOption; + static const QCommandLineOption NoPasswordOption; }; #endif // KEEPASSXC_COMMAND_H diff --git a/src/cli/Edit.cpp b/src/cli/Edit.cpp index 7954648ce..76e996c98 100644 --- a/src/cli/Edit.cpp +++ b/src/cli/Edit.cpp @@ -49,6 +49,7 @@ int Edit::execute(const QStringList& arguments) parser.addPositionalArgument("database", QObject::tr("Path of the database.")); parser.addOption(Command::QuietOption); parser.addOption(Command::KeyFileOption); + parser.addOption(Command::NoPasswordOption); QCommandLineOption username(QStringList() << "u" << "username", @@ -95,6 +96,7 @@ int Edit::execute(const QStringList& arguments) const QString& entryPath = args.at(1); auto db = Utils::unlockDatabase(databasePath, + !parser.isSet(Command::NoPasswordOption), parser.value(Command::KeyFileOption), parser.isSet(Command::QuietOption) ? Utils::DEVNULL : Utils::STDOUT, Utils::STDERR); diff --git a/src/cli/Extract.cpp b/src/cli/Extract.cpp index be5abb920..729687fe3 100644 --- a/src/cli/Extract.cpp +++ b/src/cli/Extract.cpp @@ -51,6 +51,7 @@ int Extract::execute(const QStringList& arguments) parser.addPositionalArgument("database", QObject::tr("Path of the database to extract.")); parser.addOption(Command::QuietOption); parser.addOption(Command::KeyFileOption); + parser.addOption(Command::NoPasswordOption); parser.addHelpOption(); parser.process(arguments); @@ -59,17 +60,19 @@ int Extract::execute(const QStringList& arguments) errorTextStream << parser.helpText().replace("keepassxc-cli", "keepassxc-cli extract"); return EXIT_FAILURE; } - - if (!parser.isSet(Command::QuietOption)) { - outputTextStream << QObject::tr("Insert password to unlock %1: ").arg(args.at(0)) << flush; - } - + auto compositeKey = QSharedPointer::create(); - QString line = Utils::getPassword(parser.isSet(Command::QuietOption) ? Utils::DEVNULL : Utils::STDOUT); - auto passwordKey = QSharedPointer::create(); - passwordKey->setPassword(line); - compositeKey->addKey(passwordKey); + if (!parser.isSet(Command::NoPasswordOption)) { + if (!parser.isSet(Command::QuietOption)) { + outputTextStream << QObject::tr("Insert password to unlock %1: ").arg(args.at(0)) << flush; + } + + QString line = Utils::getPassword(parser.isSet(Command::QuietOption) ? Utils::DEVNULL : Utils::STDOUT); + auto passwordKey = QSharedPointer::create(); + passwordKey->setPassword(line); + compositeKey->addKey(passwordKey); + } QString keyFilePath = parser.value(Command::KeyFileOption); if (!keyFilePath.isEmpty()) { diff --git a/src/cli/List.cpp b/src/cli/List.cpp index 11650d405..ebf7bfda1 100644 --- a/src/cli/List.cpp +++ b/src/cli/List.cpp @@ -48,6 +48,7 @@ int List::execute(const QStringList& arguments) parser.addPositionalArgument("group", QObject::tr("Path of the group to list. Default is /"), "[group]"); parser.addOption(Command::QuietOption); parser.addOption(Command::KeyFileOption); + parser.addOption(Command::NoPasswordOption); QCommandLineOption recursiveOption(QStringList() << "R" << "recursive", @@ -65,6 +66,7 @@ int List::execute(const QStringList& arguments) bool recursive = parser.isSet(recursiveOption); auto db = Utils::unlockDatabase(args.at(0), + !parser.isSet(Command::NoPasswordOption), parser.value(Command::KeyFileOption), parser.isSet(Command::QuietOption) ? Utils::DEVNULL : Utils::STDOUT, Utils::STDERR); diff --git a/src/cli/Locate.cpp b/src/cli/Locate.cpp index f25ce79af..81bbdd55d 100644 --- a/src/cli/Locate.cpp +++ b/src/cli/Locate.cpp @@ -50,6 +50,7 @@ int Locate::execute(const QStringList& arguments) parser.addPositionalArgument("term", QObject::tr("Search term.")); parser.addOption(Command::QuietOption); parser.addOption(Command::KeyFileOption); + parser.addOption(Command::NoPasswordOption); parser.addHelpOption(); parser.process(arguments); @@ -60,6 +61,7 @@ int Locate::execute(const QStringList& arguments) } auto db = Utils::unlockDatabase(args.at(0), + !parser.isSet(Command::NoPasswordOption), parser.value(Command::KeyFileOption), parser.isSet(Command::QuietOption) ? Utils::DEVNULL : Utils::STDOUT, Utils::STDERR); diff --git a/src/cli/Merge.cpp b/src/cli/Merge.cpp index b0e4cabca..a7357394f 100644 --- a/src/cli/Merge.cpp +++ b/src/cli/Merge.cpp @@ -52,6 +52,7 @@ int Merge::execute(const QStringList& arguments) QObject::tr("Use the same credentials for both database files.")); parser.addOption(samePasswordOption); parser.addOption(Command::KeyFileOption); + parser.addOption(Command::NoPasswordOption); QCommandLineOption keyFileFromOption(QStringList() << "f" << "key-file-from", @@ -59,6 +60,10 @@ int Merge::execute(const QStringList& arguments) QObject::tr("path")); parser.addOption(keyFileFromOption); + QCommandLineOption noPasswordFromOption(QStringList() << "no-password-from", + QObject::tr("Deactivate password key for the database to merge from.")); + parser.addOption(noPasswordFromOption); + parser.addHelpOption(); parser.process(arguments); @@ -69,6 +74,7 @@ int Merge::execute(const QStringList& arguments) } auto db1 = Utils::unlockDatabase(args.at(0), + !parser.isSet(Command::NoPasswordOption), parser.value(Command::KeyFileOption), parser.isSet(Command::QuietOption) ? Utils::DEVNULL : Utils::STDOUT, Utils::STDERR); @@ -79,6 +85,7 @@ int Merge::execute(const QStringList& arguments) QSharedPointer db2; if (!parser.isSet("same-credentials")) { db2 = Utils::unlockDatabase(args.at(1), + !parser.isSet(noPasswordFromOption), parser.value(keyFileFromOption), parser.isSet(Command::QuietOption) ? Utils::DEVNULL : Utils::STDOUT, Utils::STDERR); diff --git a/src/cli/Remove.cpp b/src/cli/Remove.cpp index 4663d83ec..07da23b7b 100644 --- a/src/cli/Remove.cpp +++ b/src/cli/Remove.cpp @@ -51,6 +51,7 @@ int Remove::execute(const QStringList& arguments) parser.addPositionalArgument("database", QObject::tr("Path of the database.")); parser.addOption(Command::QuietOption); parser.addOption(Command::KeyFileOption); + parser.addOption(Command::NoPasswordOption); parser.addPositionalArgument("entry", QObject::tr("Path of the entry to remove.")); parser.addHelpOption(); parser.process(arguments); @@ -62,6 +63,7 @@ int Remove::execute(const QStringList& arguments) } auto db = Utils::unlockDatabase(args.at(0), + !parser.isSet(Command::NoPasswordOption), parser.value(Command::KeyFileOption), parser.isSet(Command::QuietOption) ? Utils::DEVNULL : Utils::STDOUT, Utils::STDERR); diff --git a/src/cli/Show.cpp b/src/cli/Show.cpp index 9ae3f4d0f..d16fbfe3c 100644 --- a/src/cli/Show.cpp +++ b/src/cli/Show.cpp @@ -48,6 +48,8 @@ int Show::execute(const QStringList& arguments) parser.addPositionalArgument("database", QObject::tr("Path of the database.")); parser.addOption(Command::QuietOption); parser.addOption(Command::KeyFileOption); + parser.addOption(Command::NoPasswordOption); + QCommandLineOption totp(QStringList() << "t" << "totp", QObject::tr("Show the entry's current TOTP.")); @@ -72,6 +74,7 @@ int Show::execute(const QStringList& arguments) } auto db = Utils::unlockDatabase(args.at(0), + !parser.isSet(Command::NoPasswordOption), parser.value(Command::KeyFileOption), parser.isSet(Command::QuietOption) ? Utils::DEVNULL : Utils::STDOUT, Utils::STDERR); diff --git a/src/cli/Utils.cpp b/src/cli/Utils.cpp index 344e2b7f7..06d2bcf23 100644 --- a/src/cli/Utils.cpp +++ b/src/cli/Utils.cpp @@ -98,6 +98,7 @@ namespace Utils } // namespace Test QSharedPointer unlockDatabase(const QString& databaseFilename, + const bool isPasswordProtected, const QString& keyFilename, FILE* outputDescriptor, FILE* errorDescriptor) @@ -106,12 +107,13 @@ namespace Utils TextStream out(outputDescriptor); TextStream err(errorDescriptor); - out << QObject::tr("Insert password to unlock %1: ").arg(databaseFilename) << flush; - - QString line = Utils::getPassword(outputDescriptor); - auto passwordKey = QSharedPointer::create(); - passwordKey->setPassword(line); - compositeKey->addKey(passwordKey); + if (isPasswordProtected) { + out << QObject::tr("Insert password to unlock %1: ").arg(databaseFilename) << flush; + QString line = Utils::getPassword(outputDescriptor); + auto passwordKey = QSharedPointer::create(); + passwordKey->setPassword(line); + compositeKey->addKey(passwordKey); + } if (!keyFilename.isEmpty()) { auto fileKey = QSharedPointer::create(); diff --git a/src/cli/Utils.h b/src/cli/Utils.h index bb4d8f09a..bd89a2a5c 100644 --- a/src/cli/Utils.h +++ b/src/cli/Utils.h @@ -36,6 +36,7 @@ namespace Utils QString getPassword(FILE* outputDescriptor = STDOUT); int clipText(const QString& text); QSharedPointer unlockDatabase(const QString& databaseFilename, + const bool isPasswordProtected = true, const QString& keyFilename = {}, FILE* outputDescriptor = STDOUT, FILE* errorDescriptor = STDERR); diff --git a/src/cli/keepassxc-cli.1 b/src/cli/keepassxc-cli.1 index 4cee31774..bd7f5d5c5 100644 --- a/src/cli/keepassxc-cli.1 +++ b/src/cli/keepassxc-cli.1 @@ -62,6 +62,9 @@ Displays debugging information. .IP "-k, --key-file " Specifies a path to a key file for unlocking the database. In a merge operation this option is used to specify the key file path for the first database. +.IP "--no-password" +Deactivate password key for the database. + .IP "-q, --quiet " Silence password prompt and other secondary outputs. @@ -77,6 +80,9 @@ Displays the program version. .IP "-f, --key-file-from " Path of the key file for the second database. +.IP "--no-password-from" +Deactivate password key for the database to merge from. + .IP "-s, --same-credentials" Use the same credentials for unlocking both database. diff --git a/tests/TestCli.cpp b/tests/TestCli.cpp index e2e66c2a4..3ba40b904 100644 --- a/tests/TestCli.cpp +++ b/tests/TestCli.cpp @@ -70,11 +70,23 @@ void TestCli::initTestCase() QVERIFY(Tools::readAllFromDevice(&sourceDbFile, m_dbData)); sourceDbFile.close(); - // Load the NewDatabase.kdbx file into temporary storage + // Load the NewDatabase2.kdbx file into temporary storage QFile sourceDbFile2(QString(KEEPASSX_TEST_DATA_DIR).append("/NewDatabase2.kdbx")); QVERIFY(sourceDbFile2.open(QIODevice::ReadOnly)); QVERIFY(Tools::readAllFromDevice(&sourceDbFile2, m_dbData2)); sourceDbFile2.close(); + + // Load the KeyFileProtected.kdbx file into temporary storage + QFile sourceDbFile3(QString(KEEPASSX_TEST_DATA_DIR).append("/KeyFileProtected.kdbx")); + QVERIFY(sourceDbFile3.open(QIODevice::ReadOnly)); + QVERIFY(Tools::readAllFromDevice(&sourceDbFile3, m_keyFileProtectedDbData)); + sourceDbFile3.close(); + + // Load the KeyFileProtectedNoPassword.kdbx file into temporary storage + QFile sourceDbFile4(QString(KEEPASSX_TEST_DATA_DIR).append("/KeyFileProtectedNoPassword.kdbx")); + QVERIFY(sourceDbFile4.open(QIODevice::ReadOnly)); + QVERIFY(Tools::readAllFromDevice(&sourceDbFile4, m_keyFileProtectedNoPasswordDbData)); + sourceDbFile4.close(); } void TestCli::init() @@ -89,6 +101,16 @@ void TestCli::init() m_dbFile2->write(m_dbData2); m_dbFile2->close(); + m_keyFileProtectedDbFile.reset(new TemporaryFile()); + m_keyFileProtectedDbFile->open(); + m_keyFileProtectedDbFile->write(m_keyFileProtectedDbData); + m_keyFileProtectedDbFile->close(); + + m_keyFileProtectedNoPasswordDbFile.reset(new TemporaryFile()); + m_keyFileProtectedNoPasswordDbFile->open(); + m_keyFileProtectedNoPasswordDbFile->write(m_keyFileProtectedNoPasswordDbData); + m_keyFileProtectedNoPasswordDbFile->close(); + m_stdinFile.reset(new TemporaryFile()); m_stdinFile->open(); m_stdinHandle = fdopen(m_stdinFile->handle(), "r+"); @@ -131,7 +153,7 @@ void TestCli::cleanupTestCase() QSharedPointer TestCli::readTestDatabase() const { Utils::Test::setNextPassword("a"); - auto db = QSharedPointer(Utils::unlockDatabase(m_dbFile->fileName(), "", m_stdoutHandle)); + auto db = QSharedPointer(Utils::unlockDatabase(m_dbFile->fileName(), true, "", m_stdoutHandle)); m_stdoutFile->seek(ftell(m_stdoutHandle)); // re-synchronize handles return db; } @@ -320,7 +342,7 @@ void TestCli::testCreate() QCOMPARE(m_stdoutFile->readLine(), QByteArray("Successfully created new database.\n")); Utils::Test::setNextPassword("a"); - auto db = QSharedPointer(Utils::unlockDatabase(databaseFilename, "", Utils::DEVNULL)); + auto db = QSharedPointer(Utils::unlockDatabase(databaseFilename, true, "", Utils::DEVNULL)); QVERIFY(db); // Should refuse to create the database if it already exists. @@ -349,7 +371,7 @@ void TestCli::testCreate() QCOMPARE(m_stdoutFile->readLine(), QByteArray("Successfully created new database.\n")); Utils::Test::setNextPassword("a"); - auto db2 = QSharedPointer(Utils::unlockDatabase(databaseFilename2, keyfilePath, Utils::DEVNULL)); + auto db2 = QSharedPointer(Utils::unlockDatabase(databaseFilename2, true, keyfilePath, Utils::DEVNULL)); QVERIFY(db2); // Testing with existing keyfile @@ -366,7 +388,7 @@ void TestCli::testCreate() QCOMPARE(m_stdoutFile->readLine(), QByteArray("Successfully created new database.\n")); Utils::Test::setNextPassword("a"); - auto db3 = QSharedPointer(Utils::unlockDatabase(databaseFilename3, keyfilePath, Utils::DEVNULL)); + auto db3 = QSharedPointer(Utils::unlockDatabase(databaseFilename3, true, keyfilePath, Utils::DEVNULL)); QVERIFY(db3); } @@ -659,6 +681,65 @@ void TestCli::testGenerate() } } +void TestCli::testKeyFileOption() +{ + List listCmd; + + QString keyFilePath(QString(KEEPASSX_TEST_DATA_DIR).append("/KeyFileProtected.key")); + Utils::Test::setNextPassword("a"); + listCmd.execute({"ls", "-k", keyFilePath, m_keyFileProtectedDbFile->fileName()}); + m_stdoutFile->reset(); + m_stdoutFile->readLine(); // skip password prompt + QCOMPARE(m_stdoutFile->readAll(), QByteArray("entry1\n" + "entry2\n")); + + // Should raise an error with no key file. + qint64 pos = m_stdoutFile->pos(); + qint64 posErr = m_stderrFile->pos(); + Utils::Test::setNextPassword("a"); + listCmd.execute({"ls", m_keyFileProtectedDbFile->fileName()}); + m_stdoutFile->seek(pos); + m_stdoutFile->readLine(); // skip password prompt + m_stderrFile->seek(posErr); + QCOMPARE(m_stdoutFile->readAll(), QByteArray("")); + QCOMPARE(m_stderrFile->readAll(), + QByteArray("Error while reading the database: Wrong key or database file is corrupt. (HMAC mismatch)\n")); + + // Should raise an error if key file path is invalid. + pos = m_stdoutFile->pos(); + posErr = m_stderrFile->pos(); + Utils::Test::setNextPassword("a"); + listCmd.execute({"ls", "-k", "invalidpath", m_keyFileProtectedDbFile->fileName()}); + m_stdoutFile->seek(pos); + m_stdoutFile->readLine(); // skip password prompt + m_stderrFile->seek(posErr); + QCOMPARE(m_stdoutFile->readAll(), QByteArray("")); + QCOMPARE(m_stderrFile->readAll().split(':').at(0), + QByteArray("Failed to load key file invalidpath")); +} + +void TestCli::testNoPasswordOption() +{ + List listCmd; + + QString keyFilePath(QString(KEEPASSX_TEST_DATA_DIR).append("/KeyFileProtectedNoPassword.key")); + listCmd.execute({"ls", "-k", keyFilePath, "--no-password", m_keyFileProtectedNoPasswordDbFile->fileName()}); + m_stdoutFile->reset(); + QCOMPARE(m_stdoutFile->readAll(), QByteArray("entry1\n" + "entry2\n")); + + // Should raise an error with no key file. + qint64 pos = m_stdoutFile->pos(); + qint64 posErr = m_stderrFile->pos(); + listCmd.execute({"ls", "--no-password", m_keyFileProtectedNoPasswordDbFile->fileName()}); + m_stdoutFile->seek(pos); + m_stdoutFile->readLine(); // skip password prompt + m_stderrFile->seek(posErr); + QCOMPARE(m_stdoutFile->readAll(), QByteArray("")); + QCOMPARE(m_stderrFile->readAll(), + QByteArray("Error while reading the database: Wrong key or database file is corrupt. (HMAC mismatch)\n")); +} + void TestCli::testList() { List listCmd; diff --git a/tests/TestCli.h b/tests/TestCli.h index f3655e6cd..cd8ebacfb 100644 --- a/tests/TestCli.h +++ b/tests/TestCli.h @@ -51,6 +51,8 @@ private slots: void testExtract(); void testGenerate_data(); void testGenerate(); + void testKeyFileOption(); + void testNoPasswordOption(); void testList(); void testLocate(); void testMerge(); @@ -61,8 +63,12 @@ private slots: private: QByteArray m_dbData; QByteArray m_dbData2; + QByteArray m_keyFileProtectedDbData; + QByteArray m_keyFileProtectedNoPasswordDbData; QScopedPointer m_dbFile; QScopedPointer m_dbFile2; + QScopedPointer m_keyFileProtectedDbFile; + QScopedPointer m_keyFileProtectedNoPasswordDbFile; QScopedPointer m_stdoutFile; QScopedPointer m_stderrFile; QScopedPointer m_stdinFile; diff --git a/tests/data/KeyFileProtected.kdbx b/tests/data/KeyFileProtected.kdbx new file mode 100644 index 000000000..eeda44d58 Binary files /dev/null and b/tests/data/KeyFileProtected.kdbx differ diff --git a/tests/data/KeyFileProtected.key b/tests/data/KeyFileProtected.key new file mode 100644 index 000000000..31314b953 Binary files /dev/null and b/tests/data/KeyFileProtected.key differ diff --git a/tests/data/KeyFileProtectedNoPassword.kdbx b/tests/data/KeyFileProtectedNoPassword.kdbx new file mode 100644 index 000000000..6ee188da8 Binary files /dev/null and b/tests/data/KeyFileProtectedNoPassword.kdbx differ diff --git a/tests/data/KeyFileProtectedNoPassword.key b/tests/data/KeyFileProtectedNoPassword.key new file mode 100644 index 000000000..a6131f09e Binary files /dev/null and b/tests/data/KeyFileProtectedNoPassword.key differ -- cgit v1.2.3 From 86e5dbda4fe267ef237ba68c791c56dd1e95475a Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Sun, 24 Mar 2019 09:26:34 -0400 Subject: Add Haiku support --- CMakeLists.txt | 2 ++ share/CMakeLists.txt | 4 ++-- src/CMakeLists.txt | 3 +++ src/autotype/CMakeLists.txt | 2 +- src/crypto/ssh/includes.h | 2 +- src/gui/MainWindow.cpp | 2 ++ 6 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 658548f70..969b3727c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -192,11 +192,13 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug") add_gcc_compiler_flags("-Werror") endif() +if (NOT HAIKU) if((CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.8.999) OR CMAKE_COMPILER_IS_CLANGXX) add_gcc_compiler_flags("-fstack-protector-strong") else() add_gcc_compiler_flags("-fstack-protector --param=ssp-buffer-size=4") endif() +endif() add_gcc_compiler_cxxflags("-fno-exceptions -fno-rtti") add_gcc_compiler_cxxflags("-Wnon-virtual-dtor -Wold-style-cast -Woverloaded-virtual") diff --git a/share/CMakeLists.txt b/share/CMakeLists.txt index 214c0ec92..635ee5963 100644 --- a/share/CMakeLists.txt +++ b/share/CMakeLists.txt @@ -23,7 +23,7 @@ file(GLOB DATABASE_ICONS icons/database/*.png) install(FILES ${DATABASE_ICONS} DESTINATION ${DATA_INSTALL_DIR}/icons/database) -if(UNIX AND NOT APPLE) +if(UNIX AND NOT APPLE AND NOT HAIKU) install(DIRECTORY icons/application/ DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor FILES_MATCHING PATTERN "keepassx*.png" PATTERN "keepassx*.svg" PATTERN "status" EXCLUDE PATTERN "actions" EXCLUDE PATTERN "categories" EXCLUDE) @@ -33,7 +33,7 @@ if(UNIX AND NOT APPLE) install(FILES linux/org.keepassxc.KeePassXC.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications) install(FILES linux/org.keepassxc.KeePassXC.appdata.xml DESTINATION ${CMAKE_INSTALL_DATADIR}/metainfo) install(FILES linux/keepassxc.xml DESTINATION ${CMAKE_INSTALL_DATADIR}/mime/packages) -endif(UNIX AND NOT APPLE) +endif(UNIX AND NOT APPLE AND NOT HAIKU) if(APPLE) install(FILES macosx/keepassxc.icns DESTINATION ${DATA_INSTALL_DIR}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 110dc606c..b2cd27232 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -293,6 +293,9 @@ if(APPLE) target_link_libraries(keepassx_core "-framework LocalAuthentication") endif() endif() +if(HAIKU) + target_link_libraries(keepassx_core network) +endif() if(UNIX AND NOT APPLE) target_link_libraries(keepassx_core Qt5::DBus) endif() diff --git a/src/autotype/CMakeLists.txt b/src/autotype/CMakeLists.txt index df0483a08..6b9b8b678 100644 --- a/src/autotype/CMakeLists.txt +++ b/src/autotype/CMakeLists.txt @@ -1,5 +1,5 @@ if(WITH_XC_AUTOTYPE) - if(UNIX AND NOT APPLE) + if(UNIX AND NOT APPLE AND NOT HAIKU) find_package(X11) find_package(Qt5X11Extras 5.2) if(PRINT_SUMMARY) diff --git a/src/crypto/ssh/includes.h b/src/crypto/ssh/includes.h index 23b4aeeb6..ab29d77dd 100644 --- a/src/crypto/ssh/includes.h +++ b/src/crypto/ssh/includes.h @@ -8,7 +8,7 @@ #endif #include -#ifdef _WIN32 +#if defined(_WIN32) || defined(__HAIKU__) #include typedef uint32_t u_int32_t; diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 6e3c96af0..e91f35ed9 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -391,8 +391,10 @@ MainWindow::MainWindow() connect(m_ui->tabWidget, SIGNAL(messageDismissGlobal()), this, SLOT(hideGlobalMessage())); +#ifndef Q_OS_HAIKU m_screenLockListener = new ScreenLockListener(this); connect(m_screenLockListener, SIGNAL(screenLocked()), SLOT(handleScreenLock())); +#endif updateTrayIcon(); -- cgit v1.2.3 From 28a3824d2d594429b38ca441ff0a718b6ec7092a Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Thu, 21 Mar 2019 17:36:57 -0400 Subject: Use existing database open function on startup * Fix #2828 --- src/gui/DatabaseTabWidget.cpp | 13 +++++++++---- src/gui/DatabaseTabWidget.h | 5 ++++- src/gui/MainWindow.cpp | 23 ++--------------------- src/gui/MainWindow.h | 2 +- 4 files changed, 16 insertions(+), 27 deletions(-) diff --git a/src/gui/DatabaseTabWidget.cpp b/src/gui/DatabaseTabWidget.cpp index c908a82ec..7693c9016 100644 --- a/src/gui/DatabaseTabWidget.cpp +++ b/src/gui/DatabaseTabWidget.cpp @@ -137,10 +137,15 @@ void DatabaseTabWidget::openDatabase() * database has been opened already. * * @param filePath database file path - * @param password optional, password to unlock database * @param inBackground optional, don't focus tab after opening + * @param password optional, password to unlock database + * @param keyfile optional, path to keyfile to unlock database + * */ -void DatabaseTabWidget::addDatabaseTab(const QString& filePath, bool inBackground, const QString& password) +void DatabaseTabWidget::addDatabaseTab(const QString& filePath, + bool inBackground, + const QString& password, + const QString& keyfile) { QFileInfo fileInfo(filePath); QString canonicalFilePath = fileInfo.canonicalFilePath(); @@ -154,7 +159,7 @@ void DatabaseTabWidget::addDatabaseTab(const QString& filePath, bool inBackgroun Q_ASSERT(dbWidget); if (dbWidget && dbWidget->database()->filePath() == canonicalFilePath) { if (!password.isEmpty()) { - dbWidget->performUnlockDatabase(password); + dbWidget->performUnlockDatabase(password, keyfile); } if (!inBackground) { // switch to existing tab if file is already open @@ -167,7 +172,7 @@ void DatabaseTabWidget::addDatabaseTab(const QString& filePath, bool inBackgroun auto* dbWidget = new DatabaseWidget(QSharedPointer::create(filePath), this); addDatabaseTab(dbWidget, inBackground); if (!password.isEmpty()) { - dbWidget->performUnlockDatabase(password); + dbWidget->performUnlockDatabase(password, keyfile); } updateLastDatabases(filePath); } diff --git a/src/gui/DatabaseTabWidget.h b/src/gui/DatabaseTabWidget.h index eda28839a..bafbfa37a 100644 --- a/src/gui/DatabaseTabWidget.h +++ b/src/gui/DatabaseTabWidget.h @@ -48,7 +48,10 @@ public: bool hasLockableDatabases() const; public slots: - void addDatabaseTab(const QString& filePath, bool inBackground = false, const QString& password = {}); + void addDatabaseTab(const QString& filePath, + bool inBackground = false, + const QString& password = {}, + const QString& keyfile = {}); void addDatabaseTab(DatabaseWidget* dbWidget, bool inBackground = false); bool closeDatabaseTab(int index); bool closeDatabaseTab(DatabaseWidget* dbWidget); diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index e91f35ed9..03fa54945 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -496,28 +496,9 @@ void MainWindow::clearLastDatabases() } } -void MainWindow::openDatabase(const QString& filePath, const QString& pw, const QString& keyFile) +void MainWindow::openDatabase(const QString& filePath, const QString& password, const QString& keyfile) { - if (pw.isEmpty() && keyFile.isEmpty()) { - m_ui->tabWidget->addDatabaseTab(filePath); - return; - } - - auto db = QSharedPointer::create(); - auto key = QSharedPointer::create(); - if (!pw.isEmpty()) { - key->addKey(QSharedPointer::create(pw)); - } - if (!keyFile.isEmpty()) { - auto fileKey = QSharedPointer::create(); - fileKey->load(keyFile); - key->addKey(fileKey); - } - if (db->open(filePath, key, nullptr, false)) { - auto* dbWidget = new DatabaseWidget(db, this); - m_ui->tabWidget->addDatabaseTab(dbWidget); - dbWidget->switchToMainView(true); - } + m_ui->tabWidget->addDatabaseTab(filePath, false, password, keyfile); } void MainWindow::setMenuActionState(DatabaseWidget::Mode mode) diff --git a/src/gui/MainWindow.h b/src/gui/MainWindow.h index cd7b1a39b..14083da70 100644 --- a/src/gui/MainWindow.h +++ b/src/gui/MainWindow.h @@ -56,7 +56,7 @@ public: }; public slots: - void openDatabase(const QString& filePath, const QString& pw = {}, const QString& keyFile = {}); + void openDatabase(const QString& filePath, const QString& password = {}, const QString& keyfile = {}); void appExit(); void displayGlobalMessage(const QString& text, MessageWidget::MessageType type, -- cgit v1.2.3 From 72f0e9ba77ab2fc4f3d563d3fc43ee6f7a064c1b Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Thu, 21 Mar 2019 17:39:02 -0400 Subject: Fix saving order of open databases * Order of previously open databases are preserved when closing the application * The active database on closing remains active after startup * Nested open previous databases and remember key files under the remember previously open databases setting * Fix #1675 --- src/core/Bootstrap.cpp | 4 ++ src/gui/ApplicationSettingsWidget.cpp | 22 ++++-- src/gui/ApplicationSettingsWidget.h | 3 +- src/gui/ApplicationSettingsWidgetGeneral.ui | 104 ++++++++++++++++++++++------ src/gui/MainWindow.cpp | 36 +++++----- src/gui/MainWindow.h | 2 - 6 files changed, 122 insertions(+), 49 deletions(-) diff --git a/src/core/Bootstrap.cpp b/src/core/Bootstrap.cpp index 1950735ae..a06bf74c1 100644 --- a/src/core/Bootstrap.cpp +++ b/src/core/Bootstrap.cpp @@ -112,6 +112,10 @@ namespace Bootstrap mainWindow.openDatabase(filename); } } + auto lastActiveFile = config()->get("LastActiveDatabase").toString(); + if (!lastActiveFile.isEmpty()) { + mainWindow.openDatabase(lastActiveFile); + } } } diff --git a/src/gui/ApplicationSettingsWidget.cpp b/src/gui/ApplicationSettingsWidget.cpp index 90b851bd9..849df03ae 100644 --- a/src/gui/ApplicationSettingsWidget.cpp +++ b/src/gui/ApplicationSettingsWidget.cpp @@ -81,7 +81,8 @@ ApplicationSettingsWidget::ApplicationSettingsWidget(QWidget* parent) // clang-format off connect(m_generalUi->autoSaveAfterEveryChangeCheckBox, SIGNAL(toggled(bool)), SLOT(autoSaveToggled(bool))); connect(m_generalUi->systrayShowCheckBox, SIGNAL(toggled(bool)), SLOT(systrayToggled(bool))); - connect(m_generalUi->toolbarHideCheckBox, SIGNAL(toggled(bool)), SLOT(enableToolbarSettings(bool))); + connect(m_generalUi->toolbarHideCheckBox, SIGNAL(toggled(bool)), SLOT(toolbarSettingsToggled(bool))); + connect(m_generalUi->rememberLastDatabasesCheckBox, SIGNAL(toggled(bool)), SLOT(rememberDatabasesToggled(bool))); connect(m_secUi->clearClipboardCheckBox, SIGNAL(toggled(bool)), m_secUi->clearClipboardSpinBox, SLOT(setEnabled(bool))); @@ -294,11 +295,13 @@ void ApplicationSettingsWidget::saveSettings() // Security: clear storage if related settings are disabled if (!config()->get("RememberLastDatabases").toBool()) { - config()->set("LastDatabases", QVariant()); + config()->set("LastDatabases", {}); + config()->set("OpenPreviousDatabasesOnStartup", {}); + config()->set("LastActiveDatabase", {}); } if (!config()->get("RememberLastKeyFiles").toBool()) { - config()->set("LastKeyFiles", QVariant()); + config()->set("LastKeyFiles", {}); config()->set("LastDir", ""); } @@ -330,9 +333,20 @@ void ApplicationSettingsWidget::systrayToggled(bool checked) m_generalUi->systrayMinimizeToTrayCheckBox->setEnabled(checked); } -void ApplicationSettingsWidget::enableToolbarSettings(bool checked) +void ApplicationSettingsWidget::toolbarSettingsToggled(bool checked) { m_generalUi->toolbarMovableCheckBox->setEnabled(!checked); m_generalUi->toolButtonStyleComboBox->setEnabled(!checked); m_generalUi->toolButtonStyleLabel->setEnabled(!checked); } + +void ApplicationSettingsWidget::rememberDatabasesToggled(bool checked) +{ + if (!checked) { + m_generalUi->rememberLastKeyFilesCheckBox->setChecked(false); + m_generalUi->openPreviousDatabasesOnStartupCheckBox->setChecked(false); + } + + m_generalUi->rememberLastKeyFilesCheckBox->setEnabled(checked); + m_generalUi->openPreviousDatabasesOnStartupCheckBox->setEnabled(checked); +} diff --git a/src/gui/ApplicationSettingsWidget.h b/src/gui/ApplicationSettingsWidget.h index ffcfea2be..85b3b4700 100644 --- a/src/gui/ApplicationSettingsWidget.h +++ b/src/gui/ApplicationSettingsWidget.h @@ -55,7 +55,8 @@ private slots: void reject(); void autoSaveToggled(bool checked); void systrayToggled(bool checked); - void enableToolbarSettings(bool checked); + void toolbarSettingsToggled(bool checked); + void rememberDatabasesToggled(bool checked); private: QWidget* const m_secWidget; diff --git a/src/gui/ApplicationSettingsWidgetGeneral.ui b/src/gui/ApplicationSettingsWidgetGeneral.ui index 798971bfe..8885ef7cb 100644 --- a/src/gui/ApplicationSettingsWidgetGeneral.ui +++ b/src/gui/ApplicationSettingsWidgetGeneral.ui @@ -50,19 +50,16 @@ - + - Remember last databases - - - true + Minimize window at application startup - + - Remember last key files and security dongles + Remember previously used databases true @@ -70,18 +67,76 @@ - - - Load previous databases on startup + + + 0 - + + QLayout::SetMaximumSize + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + Load previously open databases on startup + + + true + + + + - - - Minimize window at application startup + + + 0 - + + QLayout::SetMaximumSize + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + Remember database key files and security dongles + + + true + + + + @@ -218,7 +273,7 @@ - 40 + 20 20 @@ -245,7 +300,7 @@ - 15 + 0 @@ -257,7 +312,7 @@ - 40 + 20 20 @@ -274,8 +329,11 @@ 0 + + margin-right: 5px + - Button style + Button style: @@ -326,7 +384,7 @@ - 40 + 20 20 @@ -377,7 +435,7 @@ - 40 + 20 20 @@ -407,7 +465,7 @@ - 15 + 8 @@ -418,7 +476,7 @@ - Language + Language: diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 03fa54945..9e60b53e2 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -903,24 +903,27 @@ void MainWindow::saveWindowInformation() bool MainWindow::saveLastDatabases() { - bool accept; - m_openDatabases.clear(); - bool openPreviousDatabasesOnStartup = config()->get("OpenPreviousDatabasesOnStartup").toBool(); - - if (openPreviousDatabasesOnStartup) { - connect( - m_ui->tabWidget, SIGNAL(databaseClosed(const QString&)), this, SLOT(rememberOpenDatabases(const QString&))); - } + if (config()->get("OpenPreviousDatabasesOnStartup").toBool()) { + auto currentDbWidget = m_ui->tabWidget->currentDatabaseWidget(); + if (currentDbWidget) { + config()->set("LastActiveDatabase", currentDbWidget->database()->filePath()); + } else { + config()->set("LastActiveDatabase", {}); + } - accept = m_ui->tabWidget->closeAllDatabaseTabs(); + QStringList openDatabases; + for (int i=0; i < m_ui->tabWidget->count(); ++i) { + auto dbWidget = m_ui->tabWidget->databaseWidgetFromIndex(i); + openDatabases.append(dbWidget->database()->filePath()); + } - if (openPreviousDatabasesOnStartup) { - disconnect( - m_ui->tabWidget, SIGNAL(databaseClosed(const QString&)), this, SLOT(rememberOpenDatabases(const QString&))); - config()->set("LastOpenedDatabases", m_openDatabases); + config()->set("LastOpenedDatabases", openDatabases); + } else { + config()->set("LastActiveDatabase", {}); + config()->set("LastOpenedDatabases", {}); } - return accept; + return m_ui->tabWidget->closeAllDatabaseTabs(); } void MainWindow::updateTrayIcon() @@ -985,11 +988,6 @@ void MainWindow::setShortcut(QAction* action, QKeySequence::StandardKey standard } } -void MainWindow::rememberOpenDatabases(const QString& filePath) -{ - m_openDatabases.prepend(filePath); -} - void MainWindow::applySettingsChanges() { int timeout = config()->get("security/lockdatabaseidlesec").toInt() * 1000; diff --git a/src/gui/MainWindow.h b/src/gui/MainWindow.h index 14083da70..5a72d6f02 100644 --- a/src/gui/MainWindow.h +++ b/src/gui/MainWindow.h @@ -105,7 +105,6 @@ private slots: void updateCopyAttributesMenu(); void showEntryContextMenu(const QPoint& globalPos); void showGroupContextMenu(const QPoint& globalPos); - void rememberOpenDatabases(const QString& filePath); void applySettingsChanges(); void trayIconTriggered(QSystemTrayIcon::ActivationReason reason); void lockDatabasesAfterInactivity(); @@ -137,7 +136,6 @@ private: QAction* m_searchWidgetAction; QActionGroup* m_lastDatabasesActions; QActionGroup* m_copyAdditionalAttributeActions; - QStringList m_openDatabases; InactivityTimer* m_inactivityTimer; InactivityTimer* m_touchIDinactivityTimer; int m_countDefaultAttributes; -- cgit v1.2.3 From 38826a851da650609b7456a8a931835423189ad7 Mon Sep 17 00:00:00 2001 From: Julius Bullinger <303458+bllngr@users.noreply.github.com> Date: Sun, 24 Mar 2019 15:13:50 +0100 Subject: Add button to open Custom Auto-type sequence documentation (#2733) This change adds a button next to the text edit field which opens the following wiki page: https://github.com/keepassxreboot/keepassxc/wiki/Autotype-Custom-Sequence --- src/gui/entry/EditEntryWidget.cpp | 11 +++++++++++ src/gui/entry/EditEntryWidget.h | 1 + src/gui/entry/EditEntryWidgetAutoType.ui | 17 +++++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/src/gui/entry/EditEntryWidget.cpp b/src/gui/entry/EditEntryWidget.cpp index e57bc97d6..9a4c1600f 100644 --- a/src/gui/entry/EditEntryWidget.cpp +++ b/src/gui/entry/EditEntryWidget.cpp @@ -198,11 +198,18 @@ void EditEntryWidget::setupIcon() connect(this, SIGNAL(rejected()), m_iconsWidget, SLOT(abortRequests())); } +void EditEntryWidget::openAutotypeHelp() +{ + QDesktopServices::openUrl(QUrl("https://github.com/keepassxreboot/keepassxc/wiki/Autotype-Custom-Sequence")); +} + void EditEntryWidget::setupAutoType() { m_autoTypeUi->setupUi(m_autoTypeWidget); addPage(tr("Auto-Type"), FilePath::instance()->icon("actions", "key-enter"), m_autoTypeWidget); + m_autoTypeUi->openHelpButton->setIcon(filePath()->icon("actions", "system-help")); + m_autoTypeDefaultSequenceGroup->addButton(m_autoTypeUi->inheritSequenceButton); m_autoTypeDefaultSequenceGroup->addButton(m_autoTypeUi->customSequenceButton); m_autoTypeAssocModel->setAutoTypeAssociations(m_autoTypeAssoc); @@ -213,6 +220,9 @@ void EditEntryWidget::setupAutoType() connect(m_autoTypeUi->enableButton, SIGNAL(toggled(bool)), SLOT(updateAutoTypeEnabled())); connect(m_autoTypeUi->customSequenceButton, SIGNAL(toggled(bool)), m_autoTypeUi->sequenceEdit, SLOT(setEnabled(bool))); + connect(m_autoTypeUi->customSequenceButton, SIGNAL(toggled(bool)), + m_autoTypeUi->openHelpButton, SLOT(setEnabled(bool))); + connect(m_autoTypeUi->openHelpButton, SIGNAL(clicked()), SLOT(openAutotypeHelp())); connect(m_autoTypeUi->customWindowSequenceButton, SIGNAL(toggled(bool)), m_autoTypeUi->windowSequenceEdit, SLOT(setEnabled(bool))); connect(m_autoTypeUi->assocAddButton, SIGNAL(clicked()), SLOT(insertAutoTypeAssoc())); @@ -1185,6 +1195,7 @@ void EditEntryWidget::updateAutoTypeEnabled() m_autoTypeUi->inheritSequenceButton->setEnabled(!m_history && autoTypeEnabled); m_autoTypeUi->customSequenceButton->setEnabled(!m_history && autoTypeEnabled); m_autoTypeUi->sequenceEdit->setEnabled(autoTypeEnabled && m_autoTypeUi->customSequenceButton->isChecked()); + m_autoTypeUi->openHelpButton->setEnabled(autoTypeEnabled && m_autoTypeUi->customSequenceButton->isChecked()); m_autoTypeUi->assocView->setEnabled(autoTypeEnabled); m_autoTypeUi->assocAddButton->setEnabled(!m_history); diff --git a/src/gui/entry/EditEntryWidget.h b/src/gui/entry/EditEntryWidget.h index 07a4b7895..4c6870594 100644 --- a/src/gui/entry/EditEntryWidget.h +++ b/src/gui/entry/EditEntryWidget.h @@ -90,6 +90,7 @@ private slots: void protectCurrentAttribute(bool state); void revealCurrentAttribute(); void updateAutoTypeEnabled(); + void openAutotypeHelp(); void insertAutoTypeAssoc(); void removeAutoTypeAssoc(); void loadCurrentAssoc(const QModelIndex& current); diff --git a/src/gui/entry/EditEntryWidgetAutoType.ui b/src/gui/entry/EditEntryWidgetAutoType.ui index 3d4ec7a3e..81261394d 100644 --- a/src/gui/entry/EditEntryWidgetAutoType.ui +++ b/src/gui/entry/EditEntryWidgetAutoType.ui @@ -85,6 +85,22 @@ + + + + false + + + Open AutoType help webpage + + + AutoType help button + + + + + + @@ -268,6 +284,7 @@ inheritSequenceButton customSequenceButton sequenceEdit + openHelpButton assocView windowTitleCombo customWindowSequenceButton -- cgit v1.2.3 From bc3a7522a2e95ba3689e8f0ccfaa9a09c36981b9 Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Fri, 22 Mar 2019 09:01:41 -0400 Subject: Prevent crash when editing master key --- src/gui/masterkey/PasswordEditWidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/masterkey/PasswordEditWidget.cpp b/src/gui/masterkey/PasswordEditWidget.cpp index 6f85bb198..86d629da0 100644 --- a/src/gui/masterkey/PasswordEditWidget.cpp +++ b/src/gui/masterkey/PasswordEditWidget.cpp @@ -65,7 +65,7 @@ bool PasswordEditWidget::isPasswordVisible() const bool PasswordEditWidget::isEmpty() const { - return m_compUi->enterPasswordEdit->text().isEmpty(); + return (visiblePage() == Page::Edit) && m_compUi->enterPasswordEdit->text().isEmpty(); } QWidget* PasswordEditWidget::componentEditWidget() -- cgit v1.2.3 From d6324feafd8d138819534520f3193a5fe18a691e Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Mon, 25 Mar 2019 08:40:55 -0400 Subject: Fix base64 check missing '/' as valid character * Issue introduced in 558cb3d * Corrects loading of legacy KeePass Key Files that included a '/' in their data section. Fix #2863 and Fix #2834 --- src/core/Tools.cpp | 2 +- tests/TestTools.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/Tools.cpp b/src/core/Tools.cpp index 09938b82a..46cde95bc 100644 --- a/src/core/Tools.cpp +++ b/src/core/Tools.cpp @@ -205,7 +205,7 @@ namespace Tools bool isBase64(const QByteArray& ba) { - constexpr auto pattern = R"(^(?:[a-z0-9+]{4})*(?:[a-z0-9+]{3}=|[a-z0-9+]{2}==)?$)"; + constexpr auto pattern = R"(^(?:[a-z0-9+/]{4})*(?:[a-z0-9+/]{3}=|[a-z0-9+/]{2}==)?$)"; QRegExp regexp(pattern, Qt::CaseInsensitive, QRegExp::RegExp2); QString base64 = QString::fromLatin1(ba.constData(), ba.size()); diff --git a/tests/TestTools.cpp b/tests/TestTools.cpp index de5a80c0a..100eb6306 100644 --- a/tests/TestTools.cpp +++ b/tests/TestTools.cpp @@ -59,6 +59,7 @@ void TestTools::testIsBase64() QVERIFY(Tools::isBase64(QByteArray("12=="))); QVERIFY(Tools::isBase64(QByteArray("abcd9876MN=="))); QVERIFY(Tools::isBase64(QByteArray("abcd9876DEFGhijkMNO="))); + QVERIFY(Tools::isBase64(QByteArray("abcd987/DEFGh+jk/NO="))); QVERIFY(not Tools::isBase64(QByteArray("abcd123=="))); QVERIFY(not Tools::isBase64(QByteArray("abc_"))); QVERIFY(not Tools::isBase64(QByteArray("123"))); -- cgit v1.2.3 From e7862910869b45d4391c30e0194b774d77cb4606 Mon Sep 17 00:00:00 2001 From: Vladimir Svyatski Date: Wed, 27 Mar 2019 01:54:54 +0200 Subject: Make KeeShare user messages easier to understand (#2824) --- src/keeshare/KeeShare.cpp | 16 ++++++------- src/keeshare/ShareObserver.cpp | 2 +- src/keeshare/group/EditGroupWidgetKeeShare.cpp | 31 +++++++++++++++----------- 3 files changed, 27 insertions(+), 22 deletions(-) diff --git a/src/keeshare/KeeShare.cpp b/src/keeshare/KeeShare.cpp index 08c7b4f17..01d11f02c 100644 --- a/src/keeshare/KeeShare.cpp +++ b/src/keeshare/KeeShare.cpp @@ -164,13 +164,13 @@ QString KeeShare::sharingLabel(const Group* group) const auto reference = referenceOf(share); switch (reference.type) { case KeeShareSettings::Inactive: - return tr("Disabled share %1").arg(reference.path); + return tr("Inactive share %1").arg(reference.path); case KeeShareSettings::ImportFrom: - return tr("Import from share %1").arg(reference.path); + return tr("Imported from %1").arg(reference.path); case KeeShareSettings::ExportTo: - return tr("Export to share %1").arg(reference.path); + return tr("Exported to %1").arg(reference.path); case KeeShareSettings::SynchronizeWith: - return tr("Synchronize with share %1").arg(reference.path); + return tr("Synchronized with %1").arg(reference.path); } return {}; @@ -196,13 +196,13 @@ QString KeeShare::referenceTypeLabel(const KeeShareSettings::Reference& referenc { switch (reference.type) { case KeeShareSettings::Inactive: - return tr("Disabled share"); + return tr("Inactive share"); case KeeShareSettings::ImportFrom: - return tr("Import from"); + return tr("Imported from"); case KeeShareSettings::ExportTo: - return tr("Export to"); + return tr("Exported to"); case KeeShareSettings::SynchronizeWith: - return tr("Synchronize with"); + return tr("Synchronized with"); } return ""; } diff --git a/src/keeshare/ShareObserver.cpp b/src/keeshare/ShareObserver.cpp index 63d8358c2..82d02a7da 100644 --- a/src/keeshare/ShareObserver.cpp +++ b/src/keeshare/ShareObserver.cpp @@ -84,7 +84,7 @@ namespace key.openKey(QString()); const auto signer = Signature(); if (!signer.verify(data, sign.signature, key)) { - qCritical("Invalid signature for sharing container %s.", qPrintable(reference.path)); + qCritical("Invalid signature for shared container %s.", qPrintable(reference.path)); return {Invalid, KeeShareSettings::Certificate()}; } diff --git a/src/keeshare/group/EditGroupWidgetKeeShare.cpp b/src/keeshare/group/EditGroupWidgetKeeShare.cpp index 49e640639..0170a82af 100644 --- a/src/keeshare/group/EditGroupWidgetKeeShare.cpp +++ b/src/keeshare/group/EditGroupWidgetKeeShare.cpp @@ -68,13 +68,13 @@ EditGroupWidgetKeeShare::EditGroupWidgetKeeShare(QWidget* parent) name = tr("Inactive"); break; case KeeShareSettings::ImportFrom: - name = tr("Import from path"); + name = tr("Import"); break; case KeeShareSettings::ExportTo: - name = tr("Export to path"); + name = tr("Export"); break; case KeeShareSettings::SynchronizeWith: - name = tr("Synchronize with path"); + name = tr("Synchronize"); break; } m_ui->typeComboBox->insertItem(type, name, static_cast(type)); @@ -124,10 +124,10 @@ void EditGroupWidgetKeeShare::showSharingState() } } if (!supported) { - m_ui->messageWidget->showMessage( - tr("Your KeePassXC version does not support sharing your container type. Please use %1.") - .arg(supportedExtensions.join(", ")), - MessageWidget::Warning); + m_ui->messageWidget->showMessage(tr("Your KeePassXC version does not support sharing this container type.\n" + "Supported extensions are: %1.") + .arg(supportedExtensions.join(", ")), + MessageWidget::Warning); return; } @@ -149,18 +149,18 @@ void EditGroupWidgetKeeShare::showSharingState() (other.isImporting() && reference.isExporting()) || (other.isExporting() && reference.isImporting()); } if (conflictExport) { - m_ui->messageWidget->showMessage(tr("The export container %1 is already referenced.").arg(reference.path), + m_ui->messageWidget->showMessage(tr("%1 is already being exported by this database.").arg(reference.path), MessageWidget::Error); return; } if (multipleImport) { - m_ui->messageWidget->showMessage(tr("The import container %1 is already imported.").arg(reference.path), + m_ui->messageWidget->showMessage(tr("%1 is already being imported by this database.").arg(reference.path), MessageWidget::Warning); return; } if (cycleImportExport) { m_ui->messageWidget->showMessage( - tr("The container %1 imported and export by different groups.").arg(reference.path), + tr("%1 is being imported and exported by different groups in this database.").arg(reference.path), MessageWidget::Warning); return; } @@ -169,15 +169,20 @@ void EditGroupWidgetKeeShare::showSharingState() } const auto active = KeeShare::active(); if (!active.in && !active.out) { - m_ui->messageWidget->showMessage(tr("Database sharing is disabled"), MessageWidget::Information); + m_ui->messageWidget->showMessage( + tr("KeeShare is currently disabled. You can enable import/export in the application settings.", + "KeeShare is a proper noun"), + MessageWidget::Information); return; } if (active.in && !active.out) { - m_ui->messageWidget->showMessage(tr("Database export is disabled"), MessageWidget::Information); + m_ui->messageWidget->showMessage(tr("Database export is currently disabled by application settings."), + MessageWidget::Information); return; } if (!active.in && active.out) { - m_ui->messageWidget->showMessage(tr("Database import is disabled"), MessageWidget::Information); + m_ui->messageWidget->showMessage(tr("Database import is currently disabled by application settings."), + MessageWidget::Information); return; } } -- cgit v1.2.3 From 52d411f423391ccb3b952a08afc1f6465054245b Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Tue, 26 Mar 2019 17:14:42 -0400 Subject: Use existing base64 check in Tools namespace --- src/format/KdbxXmlReader.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/format/KdbxXmlReader.cpp b/src/format/KdbxXmlReader.cpp index 84d597bdb..ab2b9aeb7 100644 --- a/src/format/KdbxXmlReader.cpp +++ b/src/format/KdbxXmlReader.cpp @@ -1028,10 +1028,8 @@ bool KdbxXmlReader::readBool() QDateTime KdbxXmlReader::readDateTime() { - static QRegularExpression b64regex("^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$"); QString str = readString(); - - if (b64regex.match(str).hasMatch()) { + if (Tools::isBase64(str.toLatin1())) { QByteArray secsBytes = QByteArray::fromBase64(str.toUtf8()).leftJustified(8, '\0', true).left(8); qint64 secs = Endian::bytesToSizedInt(secsBytes, KeePass2::BYTEORDER); return QDateTime(QDate(1, 1, 1), QTime(0, 0, 0, 0), Qt::UTC).addSecs(secs); -- cgit v1.2.3 From edef225eab4698ea0a0bc6bc7996369ff5d1c6fb Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Tue, 26 Mar 2019 22:23:16 -0400 Subject: Fix opening files from command line * Fix #2877 - password is unchecked by default * Smarter activation of key components based on contents of text entry fields * Prevent multiple copies of the same database from opening when the canonicalFileName != fileName --- src/core/Database.cpp | 20 ++++++++++++++++++++ src/core/Database.h | 1 + src/gui/DatabaseOpenWidget.cpp | 23 +++++++++++------------ src/gui/DatabaseTabWidget.cpp | 10 +++------- 4 files changed, 35 insertions(+), 19 deletions(-) diff --git a/src/core/Database.cpp b/src/core/Database.cpp index 22484cb80..cb3039cd9 100644 --- a/src/core/Database.cpp +++ b/src/core/Database.cpp @@ -388,11 +388,31 @@ const Metadata* Database::metadata() const return m_metadata; } +/** + * Returns the original file path that was provided for + * this database. This path may not exist, may contain + * unresolved symlinks, or have malformed slashes. + * + * @return original file path + */ QString Database::filePath() const { return m_data.filePath; } +/** + * Returns the canonical file path of this databases' + * set file path. This returns an empty string if the + * file does not exist or cannot be resolved. + * + * @return canonical file path + */ +QString Database::canonicalFilePath() const +{ + QFileInfo fileInfo(m_data.filePath); + return fileInfo.canonicalFilePath(); +} + void Database::setFilePath(const QString& filePath) { if (filePath == m_data.filePath) { diff --git a/src/core/Database.h b/src/core/Database.h index 8df2b9317..bfdbf7915 100644 --- a/src/core/Database.h +++ b/src/core/Database.h @@ -82,6 +82,7 @@ public: QUuid uuid() const; QString filePath() const; + QString canonicalFilePath() const; void setFilePath(const QString& filePath); Metadata* metadata(); diff --git a/src/gui/DatabaseOpenWidget.cpp b/src/gui/DatabaseOpenWidget.cpp index 155846640..c7237a369 100644 --- a/src/gui/DatabaseOpenWidget.cpp +++ b/src/gui/DatabaseOpenWidget.cpp @@ -45,7 +45,6 @@ DatabaseOpenWidget::DatabaseOpenWidget(QWidget* parent) m_ui->setupUi(this); m_ui->messageWidget->setHidden(true); - m_ui->checkPassword->setChecked(true); QFont font = m_ui->labelHeadline->font(); font.setBold(true); @@ -159,7 +158,7 @@ void DatabaseOpenWidget::clearForms() m_ui->editPassword->setText(""); m_ui->comboKeyFile->clear(); m_ui->comboKeyFile->setEditText(""); - m_ui->checkPassword->setChecked(true); + m_ui->checkPassword->setChecked(false); m_ui->checkKeyFile->setChecked(false); m_ui->checkChallengeResponse->setChecked(false); m_ui->checkTouchID->setChecked(false); @@ -174,13 +173,8 @@ QSharedPointer DatabaseOpenWidget::database() void DatabaseOpenWidget::enterKey(const QString& pw, const QString& keyFile) { - if (!pw.isEmpty()) { - m_ui->editPassword->setText(pw); - } - if (!keyFile.isEmpty()) { - m_ui->comboKeyFile->setEditText(keyFile); - } - + m_ui->editPassword->setText(pw); + m_ui->comboKeyFile->setEditText(keyFile); openDatabase(); } @@ -339,17 +333,20 @@ void DatabaseOpenWidget::reject() void DatabaseOpenWidget::activatePassword() { - m_ui->checkPassword->setChecked(true); + bool hasPassword = !m_ui->editPassword->text().isEmpty(); + m_ui->checkPassword->setChecked(hasPassword); } void DatabaseOpenWidget::activateKeyFile() { - m_ui->checkKeyFile->setChecked(true); + bool hasKeyFile = !m_ui->comboKeyFile->lineEdit()->text().isEmpty(); + m_ui->checkKeyFile->setChecked(hasKeyFile); } void DatabaseOpenWidget::activateChallengeResponse() { - m_ui->checkChallengeResponse->setChecked(true); + bool hasCR = m_ui->comboChallengeResponse->currentData().toInt() != -1; + m_ui->checkChallengeResponse->setChecked(hasCR); } void DatabaseOpenWidget::browseKeyFile() @@ -372,6 +369,7 @@ void DatabaseOpenWidget::pollYubikey() m_ui->checkChallengeResponse->setChecked(false); m_ui->comboChallengeResponse->setEnabled(false); m_ui->comboChallengeResponse->clear(); + m_ui->comboChallengeResponse->addItem(tr("-- SELECT --"), -1); m_ui->yubikeyProgress->setVisible(true); // YubiKey init is slow, detect asynchronously to not block the UI @@ -388,6 +386,7 @@ void DatabaseOpenWidget::yubikeyDetected(int slot, bool blocking) QHash lastChallengeResponse = config()->get("LastChallengeResponse").toHash(); if (lastChallengeResponse.contains(m_filename)) { m_ui->checkChallengeResponse->setChecked(true); + m_ui->comboChallengeResponse->setCurrentIndex(1); } } } diff --git a/src/gui/DatabaseTabWidget.cpp b/src/gui/DatabaseTabWidget.cpp index 7693c9016..a7fed628b 100644 --- a/src/gui/DatabaseTabWidget.cpp +++ b/src/gui/DatabaseTabWidget.cpp @@ -157,10 +157,8 @@ void DatabaseTabWidget::addDatabaseTab(const QString& filePath, for (int i = 0, c = count(); i < c; ++i) { auto* dbWidget = databaseWidgetFromIndex(i); Q_ASSERT(dbWidget); - if (dbWidget && dbWidget->database()->filePath() == canonicalFilePath) { - if (!password.isEmpty()) { - dbWidget->performUnlockDatabase(password, keyfile); - } + if (dbWidget && dbWidget->database()->canonicalFilePath() == canonicalFilePath) { + dbWidget->performUnlockDatabase(password, keyfile); if (!inBackground) { // switch to existing tab if file is already open setCurrentIndex(indexOf(dbWidget)); @@ -171,9 +169,7 @@ void DatabaseTabWidget::addDatabaseTab(const QString& filePath, auto* dbWidget = new DatabaseWidget(QSharedPointer::create(filePath), this); addDatabaseTab(dbWidget, inBackground); - if (!password.isEmpty()) { - dbWidget->performUnlockDatabase(password, keyfile); - } + dbWidget->performUnlockDatabase(password, keyfile); updateLastDatabases(filePath); } -- cgit v1.2.3 From cb2900f5a98b3774b9dfaa4c6ead4f1a3b18c6fc Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Sat, 30 Mar 2019 21:31:32 -0400 Subject: Fix database master key dirtying * When removing portions of the master key, the key is marked dirty for saving * Properly clear password and other fields in edit entry widget and password widgets --- src/gui/dbsettings/DatabaseSettingsWidgetMasterKey.cpp | 7 +++---- src/gui/entry/EditEntryWidget.cpp | 7 +++++++ src/gui/masterkey/PasswordEditWidget.cpp | 9 +++++++++ src/gui/masterkey/PasswordEditWidget.h | 1 + 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/gui/dbsettings/DatabaseSettingsWidgetMasterKey.cpp b/src/gui/dbsettings/DatabaseSettingsWidgetMasterKey.cpp index d1a64b529..a8425aae1 100644 --- a/src/gui/dbsettings/DatabaseSettingsWidgetMasterKey.cpp +++ b/src/gui/dbsettings/DatabaseSettingsWidgetMasterKey.cpp @@ -77,11 +77,8 @@ void DatabaseSettingsWidgetMasterKey::load(QSharedPointer db) // database has no key, we are about to add a new one m_passwordEditWidget->changeVisiblePage(KeyComponentWidget::Page::Edit); m_passwordEditWidget->setPasswordVisible(true); - m_isDirty = true; - return; } - bool isDirty = false; bool hasAdditionalKeys = false; for (const auto& key : m_db->key()->keys()) { if (key->uuid() == PasswordKey::UUID) { @@ -103,7 +100,9 @@ void DatabaseSettingsWidgetMasterKey::load(QSharedPointer db) setAdditionalKeyOptionsVisible(hasAdditionalKeys); - m_isDirty = isDirty; + connect(m_passwordEditWidget->findChild("removeButton"), SIGNAL(clicked()), SLOT(markDirty())); + connect(m_keyFileEditWidget->findChild("removeButton"), SIGNAL(clicked()), SLOT(markDirty())); + connect(m_yubiKeyEditWidget->findChild("removeButton"), SIGNAL(clicked()), SLOT(markDirty())); } void DatabaseSettingsWidgetMasterKey::initialize() diff --git a/src/gui/entry/EditEntryWidget.cpp b/src/gui/entry/EditEntryWidget.cpp index 9a4c1600f..74a1fcd36 100644 --- a/src/gui/entry/EditEntryWidget.cpp +++ b/src/gui/entry/EditEntryWidget.cpp @@ -993,6 +993,13 @@ void EditEntryWidget::clear() { m_entry = nullptr; m_db.reset(); + + m_mainUi->titleEdit->setText(""); + m_mainUi->passwordEdit->setText(""); + m_mainUi->passwordRepeatEdit->setText(""); + m_mainUi->urlEdit->setText(""); + m_mainUi->notesEdit->clear(); + m_entryAttributes->clear(); m_advancedUi->attachmentsWidget->clearAttachments(); m_autoTypeAssoc->clear(); diff --git a/src/gui/masterkey/PasswordEditWidget.cpp b/src/gui/masterkey/PasswordEditWidget.cpp index 86d629da0..6f6cf4d99 100644 --- a/src/gui/masterkey/PasswordEditWidget.cpp +++ b/src/gui/masterkey/PasswordEditWidget.cpp @@ -92,6 +92,15 @@ void PasswordEditWidget::initComponentEditWidget(QWidget* widget) m_compUi->enterPasswordEdit->setFocus(); } +void PasswordEditWidget::hideEvent(QHideEvent* event) +{ + if (!isVisible() && m_compUi->enterPasswordEdit) { + m_compUi->enterPasswordEdit->setText(""); + } + + QWidget::hideEvent(event); +} + bool PasswordEditWidget::validate(QString& errorMessage) const { if (m_compUi->enterPasswordEdit->text() != m_compUi->repeatPasswordEdit->text()) { diff --git a/src/gui/masterkey/PasswordEditWidget.h b/src/gui/masterkey/PasswordEditWidget.h index 9f3eb75ce..57c225c1f 100644 --- a/src/gui/masterkey/PasswordEditWidget.h +++ b/src/gui/masterkey/PasswordEditWidget.h @@ -44,6 +44,7 @@ public: protected: QWidget* componentEditWidget() override; void initComponentEditWidget(QWidget* widget) override; + void hideEvent(QHideEvent* event) override; private slots: void showPasswordGenerator(); -- cgit v1.2.3 From f49a8a7f70fd5cdf0da6ed555c651bfcc2cbe8ca Mon Sep 17 00:00:00 2001 From: Janek Bevendorff Date: Tue, 2 Apr 2019 00:01:58 +0200 Subject: Fix key component widget initialization and password field echo mode on database open --- src/gui/DatabaseOpenWidget.cpp | 6 ++---- src/gui/masterkey/KeyComponentWidget.cpp | 20 ++++++++++++++------ src/gui/masterkey/KeyComponentWidget.h | 5 ++++- src/gui/masterkey/PasswordEditWidget.cpp | 3 +++ 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/gui/DatabaseOpenWidget.cpp b/src/gui/DatabaseOpenWidget.cpp index c7237a369..0f540bca8 100644 --- a/src/gui/DatabaseOpenWidget.cpp +++ b/src/gui/DatabaseOpenWidget.cpp @@ -185,9 +185,7 @@ void DatabaseOpenWidget::openDatabase() return; } - if (!m_ui->editPassword->isPasswordVisible()) { - m_ui->editPassword->setShowPassword(false); - } + m_ui->editPassword->setShowPassword(false); QCoreApplication::processEvents(); m_db.reset(new Database()); @@ -369,7 +367,7 @@ void DatabaseOpenWidget::pollYubikey() m_ui->checkChallengeResponse->setChecked(false); m_ui->comboChallengeResponse->setEnabled(false); m_ui->comboChallengeResponse->clear(); - m_ui->comboChallengeResponse->addItem(tr("-- SELECT --"), -1); + m_ui->comboChallengeResponse->addItem(tr("Select slot..."), -1); m_ui->yubikeyProgress->setVisible(true); // YubiKey init is slow, detect asynchronously to not block the UI diff --git a/src/gui/masterkey/KeyComponentWidget.cpp b/src/gui/masterkey/KeyComponentWidget.cpp index 7d795aca1..da362a952 100644 --- a/src/gui/masterkey/KeyComponentWidget.cpp +++ b/src/gui/masterkey/KeyComponentWidget.cpp @@ -37,7 +37,7 @@ KeyComponentWidget::KeyComponentWidget(const QString& name, QWidget* parent) connect(m_ui->removeButton, SIGNAL(clicked(bool)), SIGNAL(componentRemovalRequested())); connect(m_ui->cancelButton, SIGNAL(clicked(bool)), SLOT(cancelEdit())); - connect(m_ui->stackedWidget, SIGNAL(currentChanged(int)), SLOT(reset())); + connect(m_ui->stackedWidget, SIGNAL(currentChanged(int)), SLOT(resetComponentEditWidget())); connect(this, SIGNAL(nameChanged(QString)), SLOT(updateComponentName(QString))); connect(this, SIGNAL(descriptionChanged(QString)), SLOT(updateComponentDescription(QString))); @@ -46,11 +46,13 @@ KeyComponentWidget::KeyComponentWidget(const QString& name, QWidget* parent) connect(this, SIGNAL(componentRemovalRequested()), SLOT(doRemove())); connect(this, SIGNAL(componentAddChanged(bool)), SLOT(updateAddStatus(bool))); - blockSignals(true); + bool prev = blockSignals(true); setComponentName(name); + blockSignals(prev); + + prev = m_ui->stackedWidget->blockSignals(true); m_ui->stackedWidget->setCurrentIndex(Page::AddNew); - updateSize(); - blockSignals(false); + m_ui->stackedWidget->blockSignals(prev); } KeyComponentWidget::~KeyComponentWidget() @@ -164,9 +166,15 @@ void KeyComponentWidget::cancelEdit() emit editCanceled(); } -void KeyComponentWidget::reset() +void KeyComponentWidget::showEvent(QShowEvent* event) +{ + QWidget::showEvent(event); + resetComponentEditWidget(); +} + +void KeyComponentWidget::resetComponentEditWidget() { - if (static_cast(m_ui->stackedWidget->currentIndex()) == Page::Edit) { + if (m_ui->componentWidgetLayout->isEmpty() || static_cast(m_ui->stackedWidget->currentIndex()) == Page::Edit) { if (!m_ui->componentWidgetLayout->isEmpty()) { auto* item = m_ui->componentWidgetLayout->takeAt(0); if (item->widget()) { diff --git a/src/gui/masterkey/KeyComponentWidget.h b/src/gui/masterkey/KeyComponentWidget.h index cf2ae4947..f184c1321 100644 --- a/src/gui/masterkey/KeyComponentWidget.h +++ b/src/gui/masterkey/KeyComponentWidget.h @@ -109,6 +109,9 @@ signals: void editCanceled(); void componentRemovalRequested(); +protected: + void showEvent(QShowEvent* event) override ; + private slots: void updateComponentName(const QString& name); void updateComponentDescription(const QString& decription); @@ -117,7 +120,7 @@ private slots: void doEdit(); void doRemove(); void cancelEdit(); - void reset(); + void resetComponentEditWidget(); void updateSize(); private: diff --git a/src/gui/masterkey/PasswordEditWidget.cpp b/src/gui/masterkey/PasswordEditWidget.cpp index 6f6cf4d99..de00199bb 100644 --- a/src/gui/masterkey/PasswordEditWidget.cpp +++ b/src/gui/masterkey/PasswordEditWidget.cpp @@ -94,8 +94,11 @@ void PasswordEditWidget::initComponentEditWidget(QWidget* widget) void PasswordEditWidget::hideEvent(QHideEvent* event) { + Q_ASSERT(m_compUi->enterPasswordEdit); + if (!isVisible() && m_compUi->enterPasswordEdit) { m_compUi->enterPasswordEdit->setText(""); + m_compUi->repeatPasswordEdit->setText(""); } QWidget::hideEvent(event); -- cgit v1.2.3 From e025444c869b40aec75fe90e095cd888f64d1b21 Mon Sep 17 00:00:00 2001 From: Janek Bevendorff Date: Tue, 2 Apr 2019 22:32:48 +0200 Subject: Fix double password edit field --- src/gui/masterkey/KeyComponentWidget.cpp | 19 +++++++------------ src/gui/masterkey/KeyComponentWidget.h | 2 ++ 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/gui/masterkey/KeyComponentWidget.cpp b/src/gui/masterkey/KeyComponentWidget.cpp index da362a952..769cbab95 100644 --- a/src/gui/masterkey/KeyComponentWidget.cpp +++ b/src/gui/masterkey/KeyComponentWidget.cpp @@ -168,25 +168,20 @@ void KeyComponentWidget::cancelEdit() void KeyComponentWidget::showEvent(QShowEvent* event) { - QWidget::showEvent(event); resetComponentEditWidget(); + QWidget::showEvent(event); } void KeyComponentWidget::resetComponentEditWidget() { - if (m_ui->componentWidgetLayout->isEmpty() || static_cast(m_ui->stackedWidget->currentIndex()) == Page::Edit) { - if (!m_ui->componentWidgetLayout->isEmpty()) { - auto* item = m_ui->componentWidgetLayout->takeAt(0); - if (item->widget()) { - delete item->widget(); - } - delete item; + if (!m_componentWidget || static_cast(m_ui->stackedWidget->currentIndex()) == Page::Edit) { + if (m_componentWidget) { + delete m_componentWidget; } - QWidget* widget = componentEditWidget(); - m_ui->componentWidgetLayout->addWidget(widget); - - initComponentEditWidget(widget); + m_componentWidget = componentEditWidget(); + m_ui->componentWidgetLayout->addWidget(m_componentWidget); + initComponentEditWidget(m_componentWidget); } QTimer::singleShot(0, this, SLOT(updateSize())); diff --git a/src/gui/masterkey/KeyComponentWidget.h b/src/gui/masterkey/KeyComponentWidget.h index f184c1321..63079863e 100644 --- a/src/gui/masterkey/KeyComponentWidget.h +++ b/src/gui/masterkey/KeyComponentWidget.h @@ -20,6 +20,7 @@ #include #include +#include namespace Ui { @@ -128,6 +129,7 @@ private: Page m_previousPage = Page::AddNew; QString m_componentName; QString m_componentDescription; + QPointer m_componentWidget; const QScopedPointer m_ui; }; -- cgit v1.2.3 From ec829315730e07e5db42358cfa36a190eaea55c4 Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Tue, 26 Mar 2019 18:49:26 -0400 Subject: Fix broken safe saves across file systems * Fix #2888 * Qt has an undocumented rename implementation for QTemporaryFile that does not fallback to the copy implementation. Forcing the use of QFile::rename(...) allows for this fallback and protects against cross-device link errors. --- src/core/Database.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/core/Database.cpp b/src/core/Database.cpp index cb3039cd9..3593466e1 100644 --- a/src/core/Database.cpp +++ b/src/core/Database.cpp @@ -241,20 +241,16 @@ bool Database::save(const QString& filePath, QString* error, bool atomic, bool b // Delete the original db and move the temp file in place QFile::remove(filePath); -#ifdef Q_OS_LINUX - // workaround to make this workaround work, see: https://bugreports.qt.io/browse/QTBUG-64008 - if (tempFile.copy(filePath)) { - // successfully saved database file - return true; - } -#else - if (tempFile.rename(filePath)) { + + // Note: call into the QFile rename instead of QTemporaryFile + // due to an undocumented difference in how the function handles + // errors. This prevents errors when saving across file systems. + if (tempFile.QFile::rename(filePath)) { // successfully saved database file tempFile.setAutoRemove(false); setFilePath(filePath); return true; } -#endif } if (error) { *error = tempFile.errorString(); -- cgit v1.2.3 From 3b0b5d85e962b57b14507f9b07ee187aa35ecaf4 Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Wed, 3 Apr 2019 10:23:18 -0400 Subject: Correct behaviors when saving database fails * Mark database dirty if saving fails * Restore database file from backup if unsafe save fails between deleting database file and copying temporary file into place * Improve error message display for opening and saving database files * Do not automatically retry saving after failure. This prevents deletion of the backup database file and improves user awareness of issues. --- src/core/Database.cpp | 28 +++++++++++++++++++++++++++- src/core/Database.h | 1 + src/gui/DatabaseTabWidget.cpp | 3 ++- src/gui/DatabaseWidget.cpp | 24 +++++++++++++++--------- src/gui/DatabaseWidget.h | 4 +++- src/gui/MessageWidget.cpp | 1 + src/gui/MessageWidget.h | 1 + 7 files changed, 50 insertions(+), 12 deletions(-) diff --git a/src/core/Database.cpp b/src/core/Database.cpp index 3593466e1..8c1f22138 100644 --- a/src/core/Database.cpp +++ b/src/core/Database.cpp @@ -222,6 +222,7 @@ bool Database::save(const QString& filePath, QString* error, bool atomic, bool b return true; } } + if (error) { *error = saveFile.errorString(); } @@ -246,18 +247,25 @@ bool Database::save(const QString& filePath, QString* error, bool atomic, bool b // due to an undocumented difference in how the function handles // errors. This prevents errors when saving across file systems. if (tempFile.QFile::rename(filePath)) { - // successfully saved database file + // successfully saved the database tempFile.setAutoRemove(false); setFilePath(filePath); return true; + } else { + // restore the database from the backup + if (backup) { + restoreDatabase(filePath); + } } } + if (error) { *error = tempFile.errorString(); } } // Saving failed + markAsModified(); return false; } @@ -316,6 +324,24 @@ bool Database::backupDatabase(const QString& filePath) return QFile::copy(filePath, backupFilePath); } +/** + * Restores the database file from the backup file with + * name .old. to filePath. This will + * overwrite the existing file! + * + * @param filePath Path to the file to restore + * @return true on success + */ +bool Database::restoreDatabase(const QString& filePath) +{ + static auto re = QRegularExpression("^(.*?)(\\.[^.]+)?$"); + + auto match = re.match(filePath); + auto backupFilePath = match.captured(1) + ".old" + match.captured(2); + QFile::remove(filePath); + return QFile::copy(backupFilePath, filePath); +} + bool Database::isReadOnly() const { return m_data.isReadOnly; diff --git a/src/core/Database.h b/src/core/Database.h index bfdbf7915..27bb3e4a5 100644 --- a/src/core/Database.h +++ b/src/core/Database.h @@ -172,6 +172,7 @@ private: bool writeDatabase(QIODevice* device, QString* error = nullptr); bool backupDatabase(const QString& filePath); + bool restoreDatabase(const QString& filePath); Metadata* const m_metadata; DatabaseData m_data; diff --git a/src/gui/DatabaseTabWidget.cpp b/src/gui/DatabaseTabWidget.cpp index a7fed628b..313bfabb1 100644 --- a/src/gui/DatabaseTabWidget.cpp +++ b/src/gui/DatabaseTabWidget.cpp @@ -150,7 +150,8 @@ void DatabaseTabWidget::addDatabaseTab(const QString& filePath, QFileInfo fileInfo(filePath); QString canonicalFilePath = fileInfo.canonicalFilePath(); if (canonicalFilePath.isEmpty()) { - emit messageGlobal(tr("The database file does not exist or is not accessible."), MessageWidget::Error); + emit messageGlobal(tr("Failed to open %1. It either does not exist or is not accessible.").arg(filePath), + MessageWidget::Error); return; } diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp index e4196734b..abf8fcf73 100644 --- a/src/gui/DatabaseWidget.cpp +++ b/src/gui/DatabaseWidget.cpp @@ -89,6 +89,7 @@ DatabaseWidget::DatabaseWidget(QSharedPointer db, QWidget* parent) , m_databaseOpenWidget(new DatabaseOpenWidget(this)) , m_keepass1OpenWidget(new KeePass1OpenWidget(this)) , m_groupView(new GroupView(m_db.data(), m_mainSplitter)) + , m_saveAttempts(0) , m_fileWatcher(new DelayingFileWatcher(this)) { m_messageWidget->setHidden(true); @@ -859,6 +860,7 @@ void DatabaseWidget::loadDatabase(bool accepted) replaceDatabase(openWidget->database()); switchToMainView(); m_fileWatcher->restart(); + m_saveAttempts = 0; emit databaseUnlocked(); } else { m_fileWatcher->stop(); @@ -1512,7 +1514,7 @@ EntryView* DatabaseWidget::entryView() * @param attempt current save attempt or -1 to disable attempts * @return true on success */ -bool DatabaseWidget::save(int attempt) +bool DatabaseWidget::save() { // Never allow saving a locked database; it causes corruption Q_ASSERT(!isLocked()); @@ -1527,6 +1529,8 @@ bool DatabaseWidget::save(int attempt) } blockAutoReload(true); + ++m_saveAttempts; + // TODO: Make this async, but lock out the database widget to prevent re-entrance bool useAtomicSaves = config()->get("UseAtomicSaves", true).toBool(); QString errorMessage; @@ -1534,14 +1538,11 @@ bool DatabaseWidget::save(int attempt) blockAutoReload(false); if (ok) { + m_saveAttempts = 0; return true; } - if (attempt >= 0 && attempt <= 2) { - return save(attempt + 1); - } - - if (attempt > 2 && useAtomicSaves) { + if (m_saveAttempts > 2 && useAtomicSaves) { // Saving failed 3 times, issue a warning and attempt to resolve auto result = MessageBox::question(this, tr("Disable safe saves?"), @@ -1552,11 +1553,15 @@ bool DatabaseWidget::save(int attempt) MessageBox::Disable); if (result == MessageBox::Disable) { config()->set("UseAtomicSaves", false); - return save(attempt + 1); + return save(); } } - showMessage(tr("Writing the database failed.\n%1").arg(errorMessage), MessageWidget::Error); + showMessage(tr("Writing the database failed: %1").arg(errorMessage), + MessageWidget::Error, + true, + MessageWidget::LongAutoHideTimeout); + return false; } @@ -1585,8 +1590,9 @@ bool DatabaseWidget::saveAs() // Ensure we don't recurse back into this function m_db->setReadOnly(false); m_db->setFilePath(newFilePath); + m_saveAttempts = 0; - if (!save(-1)) { + if (!save()) { // Failed to save, try again continue; } diff --git a/src/gui/DatabaseWidget.h b/src/gui/DatabaseWidget.h index 9c2788995..11b2f710c 100644 --- a/src/gui/DatabaseWidget.h +++ b/src/gui/DatabaseWidget.h @@ -144,7 +144,7 @@ signals: public slots: bool lock(); - bool save(int attempt = 0); + bool save(); bool saveAs(); void replaceDatabase(QSharedPointer db); @@ -255,6 +255,8 @@ private: QUuid m_groupBeforeLock; QUuid m_entryBeforeLock; + int m_saveAttempts; + // Search state EntrySearcher* m_EntrySearcher; QString m_lastSearchText; diff --git a/src/gui/MessageWidget.cpp b/src/gui/MessageWidget.cpp index 5b18a583d..4b7e67a22 100644 --- a/src/gui/MessageWidget.cpp +++ b/src/gui/MessageWidget.cpp @@ -23,6 +23,7 @@ #include const int MessageWidget::DefaultAutoHideTimeout = 6000; +const int MessageWidget::LongAutoHideTimeout = 15000; const int MessageWidget::DisableAutoHide = -1; MessageWidget::MessageWidget(QWidget* parent) diff --git a/src/gui/MessageWidget.h b/src/gui/MessageWidget.h index eac506014..fe4baec4a 100644 --- a/src/gui/MessageWidget.h +++ b/src/gui/MessageWidget.h @@ -33,6 +33,7 @@ public: int autoHideTimeout() const; static const int DefaultAutoHideTimeout; + static const int LongAutoHideTimeout; static const int DisableAutoHide; signals: -- cgit v1.2.3 From 791b796c234176646f43ce61da98fb1ec92e54f0 Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Sun, 7 Apr 2019 09:21:58 -0400 Subject: Additional layer of protection for unsafe saves * Attempt to restore database, if that fails retain the temporary file and tell the user where it is located --- src/core/Database.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/core/Database.cpp b/src/core/Database.cpp index 8c1f22138..ee888327b 100644 --- a/src/core/Database.cpp +++ b/src/core/Database.cpp @@ -251,11 +251,15 @@ bool Database::save(const QString& filePath, QString* error, bool atomic, bool b tempFile.setAutoRemove(false); setFilePath(filePath); return true; - } else { - // restore the database from the backup - if (backup) { - restoreDatabase(filePath); + } else if (!backup || !restoreDatabase(filePath)) { + // Failed to copy new database in place, and + // failed to restore from backup or backups disabled + tempFile.setAutoRemove(false); + if (error) { + *error = tr("%1\nBackup database located at %2").arg(tempFile.errorString(), tempFile.fileName()); } + markAsModified(); + return false; } } @@ -338,8 +342,12 @@ bool Database::restoreDatabase(const QString& filePath) auto match = re.match(filePath); auto backupFilePath = match.captured(1) + ".old" + match.captured(2); - QFile::remove(filePath); - return QFile::copy(backupFilePath, filePath); + // Only try to restore if the backup file actually exists + if (QFile::exists(backupFilePath)) { + QFile::remove(filePath); + return QFile::copy(backupFilePath, filePath); + } + return false; } bool Database::isReadOnly() const -- cgit v1.2.3 From 0201fcd400cbc89f1231ea685d10a0d847221969 Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Fri, 5 Apr 2019 08:31:37 -0400 Subject: Improved error messages when opening database * Reduced wording and confusion * Streamlined delivery format * Fix #813 --- src/format/Kdbx3Reader.cpp | 3 ++- src/format/Kdbx4Reader.cpp | 3 ++- src/format/KeePass1Reader.cpp | 3 ++- src/gui/DatabaseOpenWidget.cpp | 7 +++---- tests/TestCli.cpp | 6 ++---- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/format/Kdbx3Reader.cpp b/src/format/Kdbx3Reader.cpp index 4fec74718..9196bc616 100644 --- a/src/format/Kdbx3Reader.cpp +++ b/src/format/Kdbx3Reader.cpp @@ -78,7 +78,8 @@ bool Kdbx3Reader::readDatabaseImpl(QIODevice* device, QByteArray realStart = cipherStream.read(32); if (realStart != m_streamStartBytes) { - raiseError(tr("Wrong key or database file is corrupt.")); + raiseError(tr("Invalid credentials were provided, please try again.\n" + "If this reoccurs, then your database file may be corrupt.")); return false; } diff --git a/src/format/Kdbx4Reader.cpp b/src/format/Kdbx4Reader.cpp index fbdf865bc..4bb0202b1 100644 --- a/src/format/Kdbx4Reader.cpp +++ b/src/format/Kdbx4Reader.cpp @@ -71,7 +71,8 @@ bool Kdbx4Reader::readDatabaseImpl(QIODevice* device, // clang-format off QByteArray hmacKey = KeePass2::hmacKey(m_masterSeed, db->transformedMasterKey()); if (headerHmac != CryptoHash::hmac(headerData, HmacBlockStream::getHmacKey(UINT64_MAX, hmacKey), CryptoHash::Sha256)) { - raiseError(tr("Wrong key or database file is corrupt. (HMAC mismatch)")); + raiseError(tr("Invalid credentials were provided, please try again.\n" + "If this reoccurs, then your database file may be corrupt.") + " " + tr("(HMAC mismatch)")); return false; } HmacBlockStream hmacStream(device, hmacKey); diff --git a/src/format/KeePass1Reader.cpp b/src/format/KeePass1Reader.cpp index e42449358..0319b1b2d 100644 --- a/src/format/KeePass1Reader.cpp +++ b/src/format/KeePass1Reader.cpp @@ -372,7 +372,8 @@ KeePass1Reader::testKeys(const QString& password, const QByteArray& keyfileData, } if (!cipherStream) { - raiseError(tr("Wrong key or database file is corrupt.")); + raiseError(tr("Invalid credentials were provided, please try again.\n" + "If this reoccurs, then your database file may be corrupt.")); } return cipherStream.take(); diff --git a/src/gui/DatabaseOpenWidget.cpp b/src/gui/DatabaseOpenWidget.cpp index 0f540bca8..ced72485e 100644 --- a/src/gui/DatabaseOpenWidget.cpp +++ b/src/gui/DatabaseOpenWidget.cpp @@ -194,8 +194,7 @@ void DatabaseOpenWidget::openDatabase() bool ok = m_db->open(m_filename, masterKey, &error, false); QApplication::restoreOverrideCursor(); if (!ok) { - m_ui->messageWidget->showMessage(tr("Unable to open the database:\n%1").arg(error), - MessageWidget::MessageType::Error); + m_ui->messageWidget->showMessage(error, MessageWidget::MessageType::Error); return; } @@ -223,7 +222,7 @@ void DatabaseOpenWidget::openDatabase() } emit dialogFinished(true); } else { - m_ui->messageWidget->showMessage(tr("Unable to open the database:\n%1").arg(error), MessageWidget::Error); + m_ui->messageWidget->showMessage(error, MessageWidget::Error); m_ui->editPassword->setText(""); #ifdef WITH_XC_TOUCHID @@ -268,7 +267,7 @@ QSharedPointer DatabaseOpenWidget::databaseKey() QString keyFilename = m_ui->comboKeyFile->currentText(); QString errorMsg; if (!key->load(keyFilename, &errorMsg)) { - m_ui->messageWidget->showMessage(tr("Can't open key file:\n%1").arg(errorMsg), MessageWidget::Error); + m_ui->messageWidget->showMessage(tr("Failed to open key file: %1").arg(errorMsg), MessageWidget::Error); return {}; } if (key->type() != FileKey::Hashed && !config()->get("Messages/NoLegacyKeyFileWarning").toBool()) { diff --git a/tests/TestCli.cpp b/tests/TestCli.cpp index 3ba40b904..9574f6d32 100644 --- a/tests/TestCli.cpp +++ b/tests/TestCli.cpp @@ -702,8 +702,7 @@ void TestCli::testKeyFileOption() m_stdoutFile->readLine(); // skip password prompt m_stderrFile->seek(posErr); QCOMPARE(m_stdoutFile->readAll(), QByteArray("")); - QCOMPARE(m_stderrFile->readAll(), - QByteArray("Error while reading the database: Wrong key or database file is corrupt. (HMAC mismatch)\n")); + QVERIFY(m_stderrFile->readAll().contains("Invalid credentials were provided")); // Should raise an error if key file path is invalid. pos = m_stdoutFile->pos(); @@ -736,8 +735,7 @@ void TestCli::testNoPasswordOption() m_stdoutFile->readLine(); // skip password prompt m_stderrFile->seek(posErr); QCOMPARE(m_stdoutFile->readAll(), QByteArray("")); - QCOMPARE(m_stderrFile->readAll(), - QByteArray("Error while reading the database: Wrong key or database file is corrupt. (HMAC mismatch)\n")); + QVERIFY(m_stderrFile->readAll().contains("Invalid credentials were provided")); } void TestCli::testList() -- cgit v1.2.3 From 88c8cdd800413fd72b320c6780366cf6db0da589 Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Fri, 5 Apr 2019 08:42:35 -0400 Subject: Add note to restart after changing language * Fix #2713 --- src/gui/ApplicationSettingsWidgetGeneral.ui | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/gui/ApplicationSettingsWidgetGeneral.ui b/src/gui/ApplicationSettingsWidgetGeneral.ui index 8885ef7cb..f84c6a550 100644 --- a/src/gui/ApplicationSettingsWidgetGeneral.ui +++ b/src/gui/ApplicationSettingsWidgetGeneral.ui @@ -470,7 +470,7 @@ - + 0 0 @@ -490,6 +490,13 @@ + + + + (restart program to activate) + + + -- cgit v1.2.3 From 71e375aff0bea60233fd1907011a1c4a576c18e9 Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Sun, 7 Apr 2019 12:00:02 -0400 Subject: Allow copying passwords directly from searching * Reverts removal of previously implemented feature * Fix #2630 * Make gui search tests more robust --- src/gui/SearchWidget.cpp | 8 +++++++- tests/gui/TestGui.cpp | 24 ++++++++++++++++++------ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/gui/SearchWidget.cpp b/src/gui/SearchWidget.cpp index 6e9b66929..5667852b0 100644 --- a/src/gui/SearchWidget.cpp +++ b/src/gui/SearchWidget.cpp @@ -1,5 +1,4 @@ /* - * Copyright (C) 2016 Jonathan White * Copyright (C) 2017 KeePassXC Team * * This program is free software: you can redistribute it and/or modify @@ -97,6 +96,13 @@ bool SearchWidget::eventFilter(QObject* obj, QEvent* event) if (keyEvent->key() == Qt::Key_Escape) { emit escapePressed(); return true; + } else if (keyEvent->matches(QKeySequence::Copy)) { + // If Control+C is pressed in the search edit when no text + // is selected, copy the password of the current entry. + if (!m_ui->searchEdit->hasSelectedText()) { + emit copyPressed(); + return true; + } } else if (keyEvent->matches(QKeySequence::MoveToNextLine)) { if (m_ui->searchEdit->cursorPosition() == m_ui->searchEdit->text().length()) { // If down is pressed at EOL, move the focus to the entry view diff --git a/tests/gui/TestGui.cpp b/tests/gui/TestGui.cpp index 127563798..7d907dc95 100644 --- a/tests/gui/TestGui.cpp +++ b/tests/gui/TestGui.cpp @@ -849,19 +849,31 @@ void TestGui::testSearch() QTRY_VERIFY(searchTextEdit->hasFocus()); QTest::keyClick(searchTextEdit, Qt::Key_Down); QTRY_VERIFY(entryView->hasFocus()); + auto* searchedEntry = entryView->currentEntry(); // Restore focus and search text selection QTest::keyClick(m_mainWindow.data(), Qt::Key_F, Qt::ControlModifier); QTRY_COMPARE(searchTextEdit->selectedText(), QString("someTHING")); + QTRY_VERIFY(searchTextEdit->hasFocus()); + + searchedEntry->setPassword("password"); + QClipboard* clipboard = QApplication::clipboard(); + + // Attempt password copy with selected test (should fail) + QTest::keyClick(searchTextEdit, Qt::Key_C, Qt::ControlModifier); + QVERIFY(clipboard->text() != searchedEntry->password()); + // Deselect text and confirm password copies + QTest::mouseClick(searchTextEdit, Qt::LeftButton); + QTRY_VERIFY(searchTextEdit->selectedText().isEmpty()); + QTRY_VERIFY(searchTextEdit->hasFocus()); + QTest::keyClick(searchTextEdit, Qt::Key_C, Qt::ControlModifier); + QCOMPARE(searchedEntry->password(), clipboard->text()); // Ensure Down focuses on entry view when search text is selected QTest::keyClick(searchTextEdit, Qt::Key_Down); QTRY_VERIFY(entryView->hasFocus()); - QCOMPARE(entryView->selectionModel()->currentIndex().row(), 0); - // Test that password copies (entry has focus) - QClipboard* clipboard = QApplication::clipboard(); + QCOMPARE(entryView->currentEntry(), searchedEntry); + // Test that password copies with entry focused QTest::keyClick(entryView, Qt::Key_C, Qt::ControlModifier); - QModelIndex searchedItem = entryView->model()->index(0, 1); - Entry* searchedEntry = entryView->entryFromIndex(searchedItem); - QTRY_COMPARE(searchedEntry->password(), clipboard->text()); + QCOMPARE(searchedEntry->password(), clipboard->text()); // Refocus back to search edit QTest::mouseClick(searchTextEdit, Qt::LeftButton); QTRY_VERIFY(searchTextEdit->hasFocus()); -- cgit v1.2.3 From 4b1258f5851c12e2fbe7991fff794a8e78237656 Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Sun, 7 Apr 2019 09:56:25 -0400 Subject: Correct issues with apply button * Don't show apply button when creating new entries or groups (Fix #2191) * Don't mark entry/group as dirty when first creating a new one (prevents unnecessary discard dialog on cancel) * Properly enable/disable apply button when changes are made to entries and groups * Don't show discard change warning when locking database unless their are actual changes made NOTE: Extra pages in the group edit widget are not watched for changes yet. Requires a major refactor. --- src/gui/DatabaseWidget.cpp | 11 ++-- src/gui/EditWidget.cpp | 37 +++++++++++- src/gui/EditWidget.h | 5 ++ src/gui/entry/EditEntryWidget.cpp | 121 ++++++++++++++++---------------------- src/gui/entry/EditEntryWidget.h | 3 - src/gui/group/EditGroupWidget.cpp | 45 ++++++++++++++ src/gui/group/EditGroupWidget.h | 1 + tests/gui/TestGui.cpp | 21 +++++-- 8 files changed, 155 insertions(+), 89 deletions(-) diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp index abf8fcf73..97fdeb0f9 100644 --- a/src/gui/DatabaseWidget.cpp +++ b/src/gui/DatabaseWidget.cpp @@ -261,12 +261,11 @@ bool DatabaseWidget::isSearchActive() const bool DatabaseWidget::isEditWidgetModified() const { if (currentWidget() == m_editEntryWidget) { - return m_editEntryWidget->hasBeenModified(); - } else { - // other edit widget don't have a hasBeenModified() method yet - // assume that they already have been modified - return true; + return m_editEntryWidget->isModified(); + } else if (currentWidget() == m_editGroupWidget) { + return m_editGroupWidget->isModified(); } + return false; } QList DatabaseWidget::mainSplitterSizes() const @@ -1249,7 +1248,7 @@ bool DatabaseWidget::lock() clipboard()->clearCopiedText(); - if (currentMode() == DatabaseWidget::Mode::EditMode) { + if (isEditWidgetModified()) { auto result = MessageBox::question(this, tr("Lock Database?"), tr("You are editing an entry. Discard changes and lock anyway?"), diff --git a/src/gui/EditWidget.cpp b/src/gui/EditWidget.cpp index be7ea01df..f7030c9d7 100644 --- a/src/gui/EditWidget.cpp +++ b/src/gui/EditWidget.cpp @@ -30,6 +30,7 @@ EditWidget::EditWidget(QWidget* parent) { m_ui->setupUi(this); setReadOnly(false); + setModified(false); m_ui->messageWidget->setHidden(true); @@ -43,6 +44,7 @@ EditWidget::EditWidget(QWidget* parent) connect(m_ui->buttonBox, SIGNAL(accepted()), SIGNAL(accepted())); connect(m_ui->buttonBox, SIGNAL(rejected()), SIGNAL(rejected())); + connect(m_ui->buttonBox, SIGNAL(clicked(QAbstractButton*)), SLOT(buttonClicked(QAbstractButton*))); } EditWidget::~EditWidget() @@ -106,9 +108,6 @@ void EditWidget::setReadOnly(bool readOnly) m_ui->buttonBox->setStandardButtons(QDialogButtonBox::Close); } else { m_ui->buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Apply); - // Find and connect the apply button - QPushButton* applyButton = m_ui->buttonBox->button(QDialogButtonBox::Apply); - connect(applyButton, SIGNAL(clicked()), SIGNAL(apply())); } } @@ -117,6 +116,17 @@ bool EditWidget::readOnly() const return m_readOnly; } +void EditWidget::setModified(bool state) +{ + m_modified = state; + enableApplyButton(state); +} + +bool EditWidget::isModified() const +{ + return m_modified; +} + void EditWidget::enableApplyButton(bool enabled) { QPushButton* applyButton = m_ui->buttonBox->button(QDialogButtonBox::Apply); @@ -125,6 +135,27 @@ void EditWidget::enableApplyButton(bool enabled) } } +void EditWidget::showApplyButton(bool state) +{ + if (!m_readOnly) { + auto buttons = m_ui->buttonBox->standardButtons(); + if (state) { + buttons |= QDialogButtonBox::Apply; + } else { + buttons &= ~QDialogButtonBox::Apply; + } + m_ui->buttonBox->setStandardButtons(buttons); + } +} + +void EditWidget::buttonClicked(QAbstractButton* button) +{ + auto stdButton = m_ui->buttonBox->standardButton(button); + if (stdButton == QDialogButtonBox::Apply) { + emit apply(); + } +} + void EditWidget::showMessage(const QString& text, MessageWidget::MessageType type) { // Show error messages for a longer time to make sure the user can read them diff --git a/src/gui/EditWidget.h b/src/gui/EditWidget.h index f0d157c49..361961f76 100644 --- a/src/gui/EditWidget.h +++ b/src/gui/EditWidget.h @@ -49,6 +49,8 @@ public: void setReadOnly(bool readOnly); bool readOnly() const; void enableApplyButton(bool enabled); + void showApplyButton(bool state); + virtual bool isModified() const; signals: void apply(); @@ -58,10 +60,13 @@ signals: protected slots: void showMessage(const QString& text, MessageWidget::MessageType type); void hideMessage(); + void setModified(bool state = true); + void buttonClicked(QAbstractButton* button); private: const QScopedPointer m_ui; bool m_readOnly; + bool m_modified; Q_DISABLE_COPY(EditWidget) }; diff --git a/src/gui/entry/EditEntryWidget.cpp b/src/gui/entry/EditEntryWidget.cpp index 74a1fcd36..508f3c68c 100644 --- a/src/gui/entry/EditEntryWidget.cpp +++ b/src/gui/entry/EditEntryWidget.cpp @@ -276,55 +276,54 @@ void EditEntryWidget::setupHistory() void EditEntryWidget::setupEntryUpdate() { // Entry tab - connect(m_mainUi->titleEdit, SIGNAL(textChanged(QString)), this, SLOT(setUnsavedChanges())); - connect(m_mainUi->usernameEdit, SIGNAL(textChanged(QString)), this, SLOT(setUnsavedChanges())); - connect(m_mainUi->passwordEdit, SIGNAL(textChanged(QString)), this, SLOT(setUnsavedChanges())); - connect(m_mainUi->passwordRepeatEdit, SIGNAL(textChanged(QString)), this, SLOT(setUnsavedChanges())); - connect(m_mainUi->urlEdit, SIGNAL(textChanged(QString)), this, SLOT(setUnsavedChanges())); + connect(m_mainUi->titleEdit, SIGNAL(textChanged(QString)), this, SLOT(setModified())); + connect(m_mainUi->usernameEdit, SIGNAL(textChanged(QString)), this, SLOT(setModified())); + connect(m_mainUi->passwordEdit, SIGNAL(textChanged(QString)), this, SLOT(setModified())); + connect(m_mainUi->passwordRepeatEdit, SIGNAL(textChanged(QString)), this, SLOT(setModified())); + connect(m_mainUi->urlEdit, SIGNAL(textChanged(QString)), this, SLOT(setModified())); #ifdef WITH_XC_NETWORKING connect(m_mainUi->urlEdit, SIGNAL(textChanged(QString)), this, SLOT(updateFaviconButtonEnable(QString))); #endif - connect(m_mainUi->expireCheck, SIGNAL(stateChanged(int)), this, SLOT(setUnsavedChanges())); - connect(m_mainUi->notesEnabled, SIGNAL(stateChanged(int)), this, SLOT(setUnsavedChanges())); - connect(m_mainUi->expireDatePicker, SIGNAL(dateTimeChanged(QDateTime)), this, SLOT(setUnsavedChanges())); - connect(m_mainUi->notesEdit, SIGNAL(textChanged()), this, SLOT(setUnsavedChanges())); + connect(m_mainUi->expireCheck, SIGNAL(stateChanged(int)), this, SLOT(setModified())); + connect(m_mainUi->notesEnabled, SIGNAL(stateChanged(int)), this, SLOT(setModified())); + connect(m_mainUi->expireDatePicker, SIGNAL(dateTimeChanged(QDateTime)), this, SLOT(setModified())); + connect(m_mainUi->notesEdit, SIGNAL(textChanged()), this, SLOT(setModified())); // Advanced tab - connect(m_advancedUi->attributesEdit, SIGNAL(textChanged()), this, SLOT(setUnsavedChanges())); - connect(m_advancedUi->protectAttributeButton, SIGNAL(stateChanged(int)), this, SLOT(setUnsavedChanges())); - connect(m_advancedUi->fgColorCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setUnsavedChanges())); - connect(m_advancedUi->bgColorCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setUnsavedChanges())); - connect(m_advancedUi->attachmentsWidget, SIGNAL(widgetUpdated()), this, SLOT(setUnsavedChanges())); + connect(m_advancedUi->attributesEdit, SIGNAL(textChanged()), this, SLOT(setModified())); + connect(m_advancedUi->protectAttributeButton, SIGNAL(stateChanged(int)), this, SLOT(setModified())); + connect(m_advancedUi->fgColorCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setModified())); + connect(m_advancedUi->bgColorCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setModified())); + connect(m_advancedUi->attachmentsWidget, SIGNAL(widgetUpdated()), this, SLOT(setModified())); // Icon tab - connect(m_iconsWidget, SIGNAL(widgetUpdated()), this, SLOT(setUnsavedChanges())); + connect(m_iconsWidget, SIGNAL(widgetUpdated()), this, SLOT(setModified())); // Auto-Type tab - connect(m_autoTypeUi->enableButton, SIGNAL(stateChanged(int)), this, SLOT(setUnsavedChanges())); - connect(m_autoTypeUi->customWindowSequenceButton, SIGNAL(stateChanged(int)), this, SLOT(setUnsavedChanges())); - connect(m_autoTypeUi->inheritSequenceButton, SIGNAL(toggled(bool)), this, SLOT(setUnsavedChanges())); - connect(m_autoTypeUi->customSequenceButton, SIGNAL(toggled(bool)), this, SLOT(setUnsavedChanges())); - connect(m_autoTypeUi->windowSequenceEdit, SIGNAL(textChanged(QString)), this, SLOT(setUnsavedChanges())); - connect(m_autoTypeUi->sequenceEdit, SIGNAL(textChanged(QString)), this, SLOT(setUnsavedChanges())); - connect(m_autoTypeUi->windowTitleCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(setUnsavedChanges())); - connect(m_autoTypeUi->windowTitleCombo, SIGNAL(editTextChanged(QString)), this, SLOT(setUnsavedChanges())); + connect(m_autoTypeUi->enableButton, SIGNAL(stateChanged(int)), this, SLOT(setModified())); + connect(m_autoTypeUi->customWindowSequenceButton, SIGNAL(stateChanged(int)), this, SLOT(setModified())); + connect(m_autoTypeUi->inheritSequenceButton, SIGNAL(toggled(bool)), this, SLOT(setModified())); + connect(m_autoTypeUi->customSequenceButton, SIGNAL(toggled(bool)), this, SLOT(setModified())); + connect(m_autoTypeUi->windowSequenceEdit, SIGNAL(textChanged(QString)), this, SLOT(setModified())); + connect(m_autoTypeUi->sequenceEdit, SIGNAL(textChanged(QString)), this, SLOT(setModified())); + connect(m_autoTypeUi->windowTitleCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(setModified())); + connect(m_autoTypeUi->windowTitleCombo, SIGNAL(editTextChanged(QString)), this, SLOT(setModified())); // Properties and History tabs don't need extra connections #ifdef WITH_XC_SSHAGENT // SSH Agent tab if (config()->get("SSHAgent", false).toBool()) { - connect(m_sshAgentUi->attachmentRadioButton, SIGNAL(toggled(bool)), this, SLOT(setUnsavedChanges())); - connect(m_sshAgentUi->externalFileRadioButton, SIGNAL(toggled(bool)), this, SLOT(setUnsavedChanges())); - connect(m_sshAgentUi->attachmentComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setUnsavedChanges())); - connect(m_sshAgentUi->attachmentComboBox, SIGNAL(editTextChanged(QString)), this, SLOT(setUnsavedChanges())); - connect(m_sshAgentUi->externalFileEdit, SIGNAL(textChanged(QString)), this, SLOT(setUnsavedChanges())); - connect(m_sshAgentUi->addKeyToAgentCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setUnsavedChanges())); - connect(m_sshAgentUi->removeKeyFromAgentCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setUnsavedChanges())); - connect( - m_sshAgentUi->requireUserConfirmationCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setUnsavedChanges())); - connect(m_sshAgentUi->lifetimeCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setUnsavedChanges())); - connect(m_sshAgentUi->lifetimeSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setUnsavedChanges())); + connect(m_sshAgentUi->attachmentRadioButton, SIGNAL(toggled(bool)), this, SLOT(setModified())); + connect(m_sshAgentUi->externalFileRadioButton, SIGNAL(toggled(bool)), this, SLOT(setModified())); + connect(m_sshAgentUi->attachmentComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setModified())); + connect(m_sshAgentUi->attachmentComboBox, SIGNAL(editTextChanged(QString)), this, SLOT(setModified())); + connect(m_sshAgentUi->externalFileEdit, SIGNAL(textChanged(QString)), this, SLOT(setModified())); + connect(m_sshAgentUi->addKeyToAgentCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setModified())); + connect(m_sshAgentUi->removeKeyFromAgentCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setModified())); + connect(m_sshAgentUi->requireUserConfirmationCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setModified())); + connect(m_sshAgentUi->lifetimeCheckBox, SIGNAL(stateChanged(int)), this, SLOT(setModified())); + connect(m_sshAgentUi->lifetimeSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setModified())); } #endif } @@ -703,8 +702,10 @@ void EditEntryWidget::loadEntry(Entry* entry, setCurrentPage(0); setPageHidden(m_historyWidget, m_history || m_entry->historyItems().count() < 1); - // Force the user to Save/Apply/Discard new entries - setUnsavedChanges(m_create); + // Force the user to Save/Discard new entries + showApplyButton(!m_create); + + setModified(false); } void EditEntryWidget::setForms(Entry* entry, bool restore) @@ -881,7 +882,6 @@ bool EditEntryWidget::commitEntry() } updateEntryData(m_entry); - setUnsavedChanges(false); if (!m_create) { m_entry->endUpdate(); @@ -896,6 +896,7 @@ bool EditEntryWidget::commitEntry() m_historyModel->setEntries(m_entry->historyItems()); showMessage(tr("Entry updated successfully."), MessageWidget::Positive); + setModified(false); return true; } @@ -968,7 +969,7 @@ void EditEntryWidget::cancel() m_entry->setIcon(Entry::DefaultIconNumber); } - if (!m_saved) { + if (isModified()) { auto result = MessageBox::question(this, QString(), tr("Entry has unsaved changes"), @@ -980,13 +981,13 @@ void EditEntryWidget::cancel() } if (result == MessageBox::Save) { commitEntry(); - m_saved = true; + setModified(false); } } clear(); - emit editFinished(m_saved); + emit editFinished(!isModified()); } void EditEntryWidget::clear() @@ -1008,22 +1009,6 @@ void EditEntryWidget::clear() hideMessage(); } -bool EditEntryWidget::hasBeenModified() const -{ - // entry has been modified if a history item is to be deleted - if (!m_historyModel->deletedEntries().isEmpty()) { - return true; - } - - // check if updating the entry would modify it - auto* entry = new Entry(); - entry->copyDataFrom(m_entry.data()); - - entry->beginUpdate(); - updateEntryData(entry); - return entry->endUpdate(); -} - void EditEntryWidget::togglePasswordGeneratorButton(bool checked) { if (checked) { @@ -1070,7 +1055,7 @@ void EditEntryWidget::insertAttribute() m_advancedUi->attributesView->setCurrentIndex(index); m_advancedUi->attributesView->edit(index); - setUnsavedChanges(true); + setModified(true); } void EditEntryWidget::editCurrentAttribute() @@ -1081,7 +1066,7 @@ void EditEntryWidget::editCurrentAttribute() if (index.isValid()) { m_advancedUi->attributesView->edit(index); - setUnsavedChanges(true); + setModified(true); } } @@ -1101,7 +1086,7 @@ void EditEntryWidget::removeCurrentAttribute() if (result == MessageBox::Remove) { m_entryAttributes->remove(m_attributesModel->keyByIndex(index)); - setUnsavedChanges(true); + setModified(true); } } } @@ -1223,7 +1208,7 @@ void EditEntryWidget::insertAutoTypeAssoc() m_autoTypeUi->assocView->setCurrentIndex(newIndex); loadCurrentAssoc(newIndex); m_autoTypeUi->windowTitleCombo->setFocus(); - setUnsavedChanges(true); + setModified(true); } void EditEntryWidget::removeAutoTypeAssoc() @@ -1232,7 +1217,7 @@ void EditEntryWidget::removeAutoTypeAssoc() if (currentIndex.isValid()) { m_autoTypeAssoc->remove(currentIndex.row()); - setUnsavedChanges(true); + setModified(true); } } @@ -1295,7 +1280,7 @@ void EditEntryWidget::restoreHistoryEntry() QModelIndex index = m_sortModel->mapToSource(m_historyUi->historyView->currentIndex()); if (index.isValid()) { setForms(m_historyModel->entryFromIndex(index), true); - setUnsavedChanges(true); + setModified(true); } } @@ -1309,7 +1294,7 @@ void EditEntryWidget::deleteHistoryEntry() } else { m_historyUi->deleteAllButton->setEnabled(false); } - setUnsavedChanges(true); + setModified(true); } } @@ -1317,7 +1302,7 @@ void EditEntryWidget::deleteAllHistoryEntries() { m_historyModel->deleteAll(); m_historyUi->deleteAllButton->setEnabled(m_historyModel->rowCount() > 0); - setUnsavedChanges(true); + setModified(true); } QMenu* EditEntryWidget::createPresetsMenu() @@ -1370,12 +1355,6 @@ void EditEntryWidget::pickColor() QColor newColor = QColorDialog::getColor(oldColor); if (newColor.isValid()) { setupColorButton(isForeground, newColor); - setUnsavedChanges(true); + setModified(true); } } - -void EditEntryWidget::setUnsavedChanges(bool hasUnsaved) -{ - m_saved = !hasUnsaved; - enableApplyButton(hasUnsaved); -} diff --git a/src/gui/entry/EditEntryWidget.h b/src/gui/entry/EditEntryWidget.h index 4c6870594..aea3c894b 100644 --- a/src/gui/entry/EditEntryWidget.h +++ b/src/gui/entry/EditEntryWidget.h @@ -68,7 +68,6 @@ public: QString entryTitle() const; void clear(); - bool hasBeenModified() const; signals: void editFinished(bool accepted); @@ -106,7 +105,6 @@ private slots: void useExpiryPreset(QAction* action); void toggleHideNotes(bool visible); void pickColor(); - void setUnsavedChanges(bool hasUnsaved = true); #ifdef WITH_XC_SSHAGENT void updateSSHAgent(); void updateSSHAgentAttachment(); @@ -148,7 +146,6 @@ private: bool m_create; bool m_history; - bool m_saved; #ifdef WITH_XC_SSHAGENT bool m_sshAgentEnabled; KeeAgentSettings m_sshAgentSettings; diff --git a/src/gui/group/EditGroupWidget.cpp b/src/gui/group/EditGroupWidget.cpp index 6c869cf28..fe83a943e 100644 --- a/src/gui/group/EditGroupWidget.cpp +++ b/src/gui/group/EditGroupWidget.cpp @@ -22,6 +22,7 @@ #include "core/Metadata.h" #include "gui/EditWidgetIcons.h" #include "gui/EditWidgetProperties.h" +#include "gui/MessageBox.h" #if defined(WITH_XC_KEESHARE) #include "keeshare/group/EditGroupPageKeeShare.h" @@ -46,6 +47,11 @@ public: editPage->assign(widget); } + QWidget* getWidget() + { + return widget; + } + private: QSharedPointer editPage; QWidget* widget; @@ -85,18 +91,38 @@ EditGroupWidget::EditGroupWidget(QWidget* parent) // clang-format on connect(m_editGroupWidgetIcons, SIGNAL(messageEditEntryDismiss()), SLOT(hideMessage())); + + setupModifiedTracking(); } EditGroupWidget::~EditGroupWidget() { } +void EditGroupWidget::setupModifiedTracking() +{ + // Group tab + connect(m_mainUi->editName, SIGNAL(textChanged(QString)), SLOT(setModified())); + connect(m_mainUi->editNotes, SIGNAL(textChanged()), SLOT(setModified())); + connect(m_mainUi->expireCheck, SIGNAL(stateChanged(int)), SLOT(setModified())); + connect(m_mainUi->expireDatePicker, SIGNAL(dateTimeChanged(QDateTime)), SLOT(setModified())); + connect(m_mainUi->searchComboBox, SIGNAL(currentIndexChanged(int)), SLOT(setModified())); + connect(m_mainUi->autotypeComboBox, SIGNAL(currentIndexChanged(int)), SLOT(setModified())); + connect(m_mainUi->autoTypeSequenceInherit, SIGNAL(toggled(bool)), SLOT(setModified())); + connect(m_mainUi->autoTypeSequenceCustomRadio, SIGNAL(toggled(bool)), SLOT(setModified())); + connect(m_mainUi->autoTypeSequenceCustomEdit, SIGNAL(textChanged(QString)), SLOT(setModified())); + + // Icon tab + connect(m_editGroupWidgetIcons, SIGNAL(widgetUpdated()), SLOT(setModified())); +} + void EditGroupWidget::loadGroup(Group* group, bool create, const QSharedPointer& database) { m_group = group; m_db = database; m_temporaryGroup.reset(group->clone(Entry::CloneNoFlags, Group::CloneNoFlags)); + connect(m_temporaryGroup->customData(), SIGNAL(customDataModified()), SLOT(setModified())); if (create) { setHeadline(tr("Add group")); @@ -139,6 +165,11 @@ void EditGroupWidget::loadGroup(Group* group, bool create, const QSharedPointer< setCurrentPage(0); m_mainUi->editName->setFocus(); + + // Force the user to Save/Discard new groups + showApplyButton(!create); + + setModified(false); } void EditGroupWidget::save() @@ -180,6 +211,8 @@ void EditGroupWidget::apply() // Icons add/remove are applied globally outside the transaction! m_group->copyDataFrom(m_temporaryGroup.data()); + + setModified(false); } void EditGroupWidget::cancel() @@ -188,6 +221,18 @@ void EditGroupWidget::cancel() m_group->setIcon(Entry::DefaultIconNumber); } + if (isModified()) { + auto result = MessageBox::question(this, + QString(), + tr("Entry has unsaved changes"), + MessageBox::Cancel | MessageBox::Save | MessageBox::Discard, + MessageBox::Cancel); + if (result == MessageBox::Save) { + apply(); + setModified(false); + } + } + clear(); emit editFinished(false); } diff --git a/src/gui/group/EditGroupWidget.h b/src/gui/group/EditGroupWidget.h index fd744503c..cc8738d8c 100644 --- a/src/gui/group/EditGroupWidget.h +++ b/src/gui/group/EditGroupWidget.h @@ -74,6 +74,7 @@ private: void addTriStateItems(QComboBox* comboBox, bool inheritValue); int indexFromTriState(Group::TriState triState); Group::TriState triStateFromIndex(int index); + void setupModifiedTracking(); const QScopedPointer m_mainUi; diff --git a/tests/gui/TestGui.cpp b/tests/gui/TestGui.cpp index 7d907dc95..63e36fbaa 100644 --- a/tests/gui/TestGui.cpp +++ b/tests/gui/TestGui.cpp @@ -429,13 +429,20 @@ void TestGui::testEditEntry() auto* titleEdit = editEntryWidget->findChild("titleEdit"); QTest::keyClicks(titleEdit, "_test"); - // Apply the edit auto* editEntryWidgetButtonBox = editEntryWidget->findChild("buttonBox"); QVERIFY(editEntryWidgetButtonBox); - QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Apply), Qt::LeftButton); + auto* okButton = editEntryWidgetButtonBox->button(QDialogButtonBox::Ok); + QVERIFY(okButton); + auto* applyButton = editEntryWidgetButtonBox->button(QDialogButtonBox::Apply); + QVERIFY(applyButton); + + // Apply the edit + QTRY_VERIFY(applyButton->isEnabled()); + QTest::mouseClick(applyButton, Qt::LeftButton); QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::EditMode); QCOMPARE(entry->title(), QString("Sample Entry_test")); QCOMPARE(entry->historyItems().size(), ++editCount); + QVERIFY(!applyButton->isEnabled()); // Test entry colors (simulate choosing a color) editEntryWidget->setCurrentPage(1); @@ -451,7 +458,7 @@ void TestGui::testEditEntry() colorCheckBox = editEntryWidget->findChild("bgColorCheckBox"); colorButton->setProperty("color", bgColor); colorCheckBox->setChecked(true); - QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Apply), Qt::LeftButton); + QTest::mouseClick(applyButton, Qt::LeftButton); QCOMPARE(entry->historyItems().size(), ++editCount); // Test protected attributes @@ -471,7 +478,7 @@ void TestGui::testEditEntry() auto* passwordEdit = editEntryWidget->findChild("passwordEdit"); QString originalPassword = passwordEdit->text(); passwordEdit->setText("newpass"); - QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton); + QTest::mouseClick(okButton, Qt::LeftButton); auto* messageWiget = editEntryWidget->findChild("messageWidget"); QTRY_VERIFY(messageWiget->isVisible()); QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::EditMode); @@ -479,7 +486,7 @@ void TestGui::testEditEntry() passwordEdit->setText(originalPassword); // Save the edit (press OK) - QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton); + QTest::mouseClick(okButton, Qt::LeftButton); QApplication::processEvents(); // Confirm edit was made @@ -496,13 +503,15 @@ void TestGui::testEditEntry() // Test copy & paste newline sanitization QTest::mouseClick(entryEditWidget, Qt::LeftButton); + okButton = editEntryWidgetButtonBox->button(QDialogButtonBox::Ok); + QVERIFY(okButton); QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::EditMode); titleEdit->setText("multiline\ntitle"); editEntryWidget->findChild("usernameEdit")->setText("multiline\nusername"); editEntryWidget->findChild("passwordEdit")->setText("multiline\npassword"); editEntryWidget->findChild("passwordRepeatEdit")->setText("multiline\npassword"); editEntryWidget->findChild("urlEdit")->setText("multiline\nurl"); - QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton); + QTest::mouseClick(okButton, Qt::LeftButton); QCOMPARE(entry->title(), QString("multiline title")); QCOMPARE(entry->username(), QString("multiline username")); -- cgit v1.2.3 From 1493943e2e34e4c9c270521032023c20244bac51 Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Fri, 5 Apr 2019 21:04:56 -0400 Subject: Add integration with Brave browser Fixes #2414 --- README.md | 2 +- src/browser/BrowserOptionDialog.cpp | 8 ++++++-- src/browser/BrowserOptionDialog.ui | 10 ++++++++++ src/browser/BrowserSettings.cpp | 11 +++++++++++ src/browser/BrowserSettings.h | 2 ++ src/browser/HostInstaller.cpp | 12 ++++++++++-- src/browser/HostInstaller.h | 4 +++- utils/keepassxc-snap-helper.sh | 18 ++++++++++++------ 8 files changed, 55 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 608dfd363..3048e2ea3 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ so please check out your distribution's package list to see if KeePassXC is avai - Using website favicons as entry icons - Merging of databases - Automatic reload when the database changed on disk -- Browser integration with KeePassXC-Browser using [native messaging](https://developer.chrome.com/extensions/nativeMessaging) for [Mozilla Firefox](https://addons.mozilla.org/en-US/firefox/addon/keepassxc-browser/) and [Google Chrome or Chromium](https://chrome.google.com/webstore/detail/keepassxc-browser/oboonakemofpalcgghocfoadofidjkkk) +- Browser integration with KeePassXC-Browser using [native messaging](https://developer.chrome.com/extensions/nativeMessaging) for [Mozilla Firefox](https://addons.mozilla.org/en-US/firefox/addon/keepassxc-browser/) and [Google Chrome, Chromium, Vivaldi, or Brave](https://chrome.google.com/webstore/detail/keepassxc-browser/oboonakemofpalcgghocfoadofidjkkk) - Synchronize passwords using KeeShare. See [Using Sharing](./docs/QUICKSTART.md#using-sharing) for more details. - Many bug fixes diff --git a/src/browser/BrowserOptionDialog.cpp b/src/browser/BrowserOptionDialog.cpp index dd91f1594..9eecc63f9 100644 --- a/src/browser/BrowserOptionDialog.cpp +++ b/src/browser/BrowserOptionDialog.cpp @@ -47,7 +47,7 @@ BrowserOptionDialog::BrowserOptionDialog(QWidget* parent) tr("KeePassXC-Browser is needed for the browser integration to work.
    Download it for %1 and %2. %3") .arg("Firefox", "" - "Google Chrome / Chromium / Vivaldi", + "Google Chrome / Chromium / Vivaldi / Brave", snapInstructions)); // clang-format on @@ -75,9 +75,11 @@ BrowserOptionDialog::BrowserOptionDialog(QWidget* parent) connect(m_ui->customProxyLocationBrowseButton, SIGNAL(clicked()), this, SLOT(showProxyLocationFileDialog())); #ifdef Q_OS_WIN + // Brave uses Chrome's registry settings + m_ui->braveSupport->setHidden(true); // Vivaldi uses Chrome's registry settings m_ui->vivaldiSupport->setHidden(true); - m_ui->chromeSupport->setText("Chrome and Vivaldi"); + m_ui->chromeSupport->setText("Chrome, Vivaldi, and Brave"); // Tor Browser uses Firefox's registry settings m_ui->torBrowserSupport->setHidden(true); m_ui->firefoxSupport->setText("Firefox and Tor Browser"); @@ -122,6 +124,7 @@ void BrowserOptionDialog::loadSettings() m_ui->chromiumSupport->setChecked(settings->chromiumSupport()); m_ui->firefoxSupport->setChecked(settings->firefoxSupport()); #ifndef Q_OS_WIN + m_ui->braveSupport->setChecked(settings->braveSupport()); m_ui->vivaldiSupport->setChecked(settings->vivaldiSupport()); m_ui->torBrowserSupport->setChecked(settings->torBrowserSupport()); #endif @@ -183,6 +186,7 @@ void BrowserOptionDialog::saveSettings() settings->setChromiumSupport(m_ui->chromiumSupport->isChecked()); settings->setFirefoxSupport(m_ui->firefoxSupport->isChecked()); #ifndef Q_OS_WIN + settings->setBraveSupport(m_ui->braveSupport->isChecked()); settings->setVivaldiSupport(m_ui->vivaldiSupport->isChecked()); settings->setTorBrowserSupport(m_ui->torBrowserSupport->isChecked()); #endif diff --git a/src/browser/BrowserOptionDialog.ui b/src/browser/BrowserOptionDialog.ui index 2b32bb9e8..50fd9d205 100755 --- a/src/browser/BrowserOptionDialog.ui +++ b/src/browser/BrowserOptionDialog.ui @@ -150,6 +150,16 @@ + + + + &Brave + + + false + + + diff --git a/src/browser/BrowserSettings.cpp b/src/browser/BrowserSettings.cpp index 9aab68f7e..dd74dc1cb 100644 --- a/src/browser/BrowserSettings.cpp +++ b/src/browser/BrowserSettings.cpp @@ -238,6 +238,17 @@ void BrowserSettings::setVivaldiSupport(bool enabled) HostInstaller::SupportedBrowsers::VIVALDI, enabled, supportBrowserProxy(), customProxyLocation()); } +bool BrowserSettings::braveSupport() +{ + return m_hostInstaller.checkIfInstalled(HostInstaller::SupportedBrowsers::BRAVE); +} + +void BrowserSettings::setBraveSupport(bool enabled) +{ + m_hostInstaller.installBrowser( + HostInstaller::SupportedBrowsers::BRAVE, enabled, supportBrowserProxy(), customProxyLocation()); +} + bool BrowserSettings::torBrowserSupport() { return m_hostInstaller.checkIfInstalled(HostInstaller::SupportedBrowsers::TOR_BROWSER); diff --git a/src/browser/BrowserSettings.h b/src/browser/BrowserSettings.h index b00c75b71..ba74ff53e 100644 --- a/src/browser/BrowserSettings.h +++ b/src/browser/BrowserSettings.h @@ -72,6 +72,8 @@ public: void setFirefoxSupport(bool enabled); bool vivaldiSupport(); void setVivaldiSupport(bool enabled); + bool braveSupport(); + void setBraveSupport(bool enabled); bool torBrowserSupport(); void setTorBrowserSupport(bool enabled); diff --git a/src/browser/HostInstaller.cpp b/src/browser/HostInstaller.cpp index 08782fa16..20c554566 100644 --- a/src/browser/HostInstaller.cpp +++ b/src/browser/HostInstaller.cpp @@ -39,12 +39,14 @@ HostInstaller::HostInstaller() , TARGET_DIR_FIREFOX("/Library/Application Support/Mozilla/NativeMessagingHosts") , TARGET_DIR_VIVALDI("/Library/Application Support/Vivaldi/NativeMessagingHosts") , TARGET_DIR_TOR_BROWSER("/Library/Application Support/TorBrowser-Data/Browser/Mozilla/NativeMessagingHosts") + , TARGET_DIR_BRAVE("/Library/Application Support/BraveSoftware/Brave-Browser/NativeMessagingHosts") #elif defined(Q_OS_LINUX) , TARGET_DIR_CHROME("/.config/google-chrome/NativeMessagingHosts") , TARGET_DIR_CHROMIUM("/.config/chromium/NativeMessagingHosts") , TARGET_DIR_FIREFOX("/.mozilla/native-messaging-hosts") , TARGET_DIR_VIVALDI("/.config/vivaldi/NativeMessagingHosts") , TARGET_DIR_TOR_BROWSER("/.tor-browser/app/Browser/TorBrowser/Data/Browser/.mozilla/native-messaging-hosts") + , TARGET_DIR_BRAVE("/.config/BraveSoftware/Brave-Browser/NativeMessagingHosts") #elif defined(Q_OS_WIN) // clang-format off , TARGET_DIR_CHROME("HKEY_CURRENT_USER\\Software\\Google\\Chrome\\NativeMessagingHosts\\org.keepassxc.keepassxc_browser") @@ -53,6 +55,7 @@ HostInstaller::HostInstaller() , TARGET_DIR_FIREFOX("HKEY_CURRENT_USER\\Software\\Mozilla\\NativeMessagingHosts\\org.keepassxc.keepassxc_browser") , TARGET_DIR_VIVALDI(TARGET_DIR_CHROME) , TARGET_DIR_TOR_BROWSER(TARGET_DIR_FIREFOX) + , TARGET_DIR_BRAVE(TARGET_DIR_CHROME) #endif { } @@ -140,7 +143,8 @@ void HostInstaller::installBrowser(SupportedBrowsers browser, */ void HostInstaller::updateBinaryPaths(const bool& proxy, const QString& location) { - for (int i = 0; i < 4; ++i) { + // Where 6 is the number of entries in the SupportedBrowsers enum declared in HostInstaller.h + for (int i = 0; i < 6; ++i) { if (checkIfInstalled(static_cast(i))) { installBrowser(static_cast(i), true, proxy, location); } @@ -166,6 +170,8 @@ QString HostInstaller::getTargetPath(SupportedBrowsers browser) const return TARGET_DIR_VIVALDI; case SupportedBrowsers::TOR_BROWSER: return TARGET_DIR_TOR_BROWSER; + case SupportedBrowsers::BRAVE: + return TARGET_DIR_BRAVE; default: return QString(); } @@ -188,9 +194,11 @@ QString HostInstaller::getBrowserName(SupportedBrowsers browser) const case SupportedBrowsers::FIREFOX: return "firefox"; case SupportedBrowsers::VIVALDI: - return "vivaldi"; + return "vivaldi"; case SupportedBrowsers::TOR_BROWSER: return "tor-browser"; + case SupportedBrowsers::BRAVE: + return "brave"; default: return QString(); } diff --git a/src/browser/HostInstaller.h b/src/browser/HostInstaller.h index ea0c4bd2f..154fe21a9 100644 --- a/src/browser/HostInstaller.h +++ b/src/browser/HostInstaller.h @@ -34,7 +34,8 @@ public: CHROMIUM = 1, FIREFOX = 2, VIVALDI = 3, - TOR_BROWSER = 4 + TOR_BROWSER = 4, + BRAVE = 5 }; public: @@ -66,6 +67,7 @@ private: const QString TARGET_DIR_FIREFOX; const QString TARGET_DIR_VIVALDI; const QString TARGET_DIR_TOR_BROWSER; + const QString TARGET_DIR_BRAVE; }; #endif // HOSTINSTALLER_H diff --git a/utils/keepassxc-snap-helper.sh b/utils/keepassxc-snap-helper.sh index 4b2ce94d6..206accaf1 100755 --- a/utils/keepassxc-snap-helper.sh +++ b/utils/keepassxc-snap-helper.sh @@ -92,6 +92,11 @@ setupVivaldi() { INSTALL_DIR="${BASE_DIR}/.config/vivaldi/NativeMessagingHosts" } +setupBrave() { + buildJson + INSTALL_DIR="${BASE_DIR}/.config/BraveSoftware/Brave-Browser/NativeMessagingHosts" +} + setupTorBrowser() { buildJson "firefox" INSTALL_DIR="${BASE_DIR}/.tor-browser/app/Browser/TorBrowser/Data/Browser/.mozilla/native-messaging-hosts" @@ -109,9 +114,10 @@ BROWSER=$(whiptail \ "2" "Chrome" \ "3" "Chromium" \ "4" "Vivaldi" \ - "5" "Tor Browser" \ + "5" "Brave" \ + "6" "Tor Browser" \ 3>&1 1>&2 2>&3) - + clear exitstatus=$? @@ -122,16 +128,17 @@ if [ $exitstatus = 0 ]; then 2) setupChrome ;; 3) setupChromium ;; 4) setupVivaldi ;; - 5) setupTorBrowser ;; + 5) setupBrave ;; + 6) setupTorBrowser ;; esac # Install the JSON file cd ~ mkdir -p "$INSTALL_DIR" echo "$JSON_OUT" > ${INSTALL_DIR}/${INSTALL_FILE} - + $DEBUG && echo "Installed to: ${INSTALL_DIR}/${INSTALL_FILE}" - + whiptail \ --title "Installation Complete" \ --msgbox "You will need to restart your browser in order to connect to KeePassXC" \ @@ -139,4 +146,3 @@ if [ $exitstatus = 0 ]; then else whiptail --title "Installation Canceled" --msgbox "No changes were made to your system" 8 50 fi - -- cgit v1.2.3 From 29c79c935ab80095b510020fe77e68d01377473b Mon Sep 17 00:00:00 2001 From: ckieschnick Date: Mon, 8 Apr 2019 04:19:51 +0200 Subject: More detailed KeeShare sharing messages (#2946) * ShareObserver watches all shares ShareObserver watches all shares to and considers settings only on checking for changes. This fixes an assertion when an export group signal is received, but export was disabled. * Extend share message in group view Extended the message for shared groups to indicate deactivate import/export and errors when the share was not correctly configured. --- src/keeshare/KeeShare.cpp | 26 ++++++++++++++++++++------ src/keeshare/ShareObserver.cpp | 5 +---- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/keeshare/KeeShare.cpp b/src/keeshare/KeeShare.cpp index 01d11f02c..d1cbde099 100644 --- a/src/keeshare/KeeShare.cpp +++ b/src/keeshare/KeeShare.cpp @@ -162,18 +162,32 @@ QString KeeShare::sharingLabel(const Group* group) } const auto reference = referenceOf(share); + if (!reference.isValid()) { + return tr("Invalid sharing reference"); + } + QStringList messages; switch (reference.type) { case KeeShareSettings::Inactive: - return tr("Inactive share %1").arg(reference.path); + messages << tr("Inactive share %1").arg(reference.path); + break; case KeeShareSettings::ImportFrom: - return tr("Imported from %1").arg(reference.path); + messages << tr("Imported from %1").arg(reference.path); + break; case KeeShareSettings::ExportTo: - return tr("Exported to %1").arg(reference.path); + messages << tr("Exported to %1").arg(reference.path); + break; case KeeShareSettings::SynchronizeWith: - return tr("Synchronized with %1").arg(reference.path); + messages << tr("Synchronized with %1").arg(reference.path); + break; } - - return {}; + const auto active = KeeShare::active(); + if (reference.isImporting() && !active.in) { + messages << tr("Import is disabled in settings"); + } + if (reference.isExporting() && !active.out) { + messages << tr("Export is disabled in settings"); + } + return messages.join("\n"); } QPixmap KeeShare::indicatorBadge(const Group* group, QPixmap pixmap) diff --git a/src/keeshare/ShareObserver.cpp b/src/keeshare/ShareObserver.cpp index 82d02a7da..295883ab8 100644 --- a/src/keeshare/ShareObserver.cpp +++ b/src/keeshare/ShareObserver.cpp @@ -190,7 +190,6 @@ void ShareObserver::reinitialize() KeeShareSettings::Reference newReference; }; - const auto active = KeeShare::active(); QList updated; const QList groups = m_db->rootGroup()->groupsRecursive(true); for (Group* group : groups) { @@ -202,9 +201,7 @@ void ShareObserver::reinitialize() m_groupToReference.remove(couple.group); m_referenceToGroup.remove(couple.oldReference); m_shareToGroup.remove(couple.oldReference.path); - if (couple.newReference.isValid() - && ((active.in && couple.newReference.isImporting()) - || (active.out && couple.newReference.isExporting()))) { + if (couple.newReference.isValid()) { m_groupToReference[couple.group] = couple.newReference; m_referenceToGroup[couple.newReference] = couple.group; m_shareToGroup[couple.newReference.path] = couple.group; -- cgit v1.2.3 From 8bc94874a1a2e39a9d4d63600d569bb8edf363b6 Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Thu, 21 Mar 2019 16:21:45 -0400 Subject: Enhance release-tool handling of app signing * Introduce .gitrev file to tarball generation * Correct labeling of builds based on supplied parameters to CMake * Convert supplied key file path to absolute when building under MSYS * Support OVERRIDE_VERSION to build properly version numbered snapshots * Do not build tests for any build --- CMakeLists.txt | 20 +++++++++++++------- release-tool | 33 +++++++++++++++++++-------------- 2 files changed, 32 insertions(+), 21 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 969b3727c..3e7928570 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,6 +80,7 @@ set(KEEPASSXC_VERSION_MAJOR "2") set(KEEPASSXC_VERSION_MINOR "4") set(KEEPASSXC_VERSION_PATCH "0") set(KEEPASSXC_VERSION "${KEEPASSXC_VERSION_MAJOR}.${KEEPASSXC_VERSION_MINOR}.${KEEPASSXC_VERSION_PATCH}") +set(OVERRIDE_VERSION "" CACHE STRING "Override the KeePassXC Version for Snapshot builds") set(KEEPASSXC_BUILD_TYPE "Snapshot" CACHE STRING "Set KeePassXC build type to distinguish between stable releases and snapshots") set_property(CACHE KEEPASSXC_BUILD_TYPE PROPERTY STRINGS Snapshot Release PreRelease) @@ -91,8 +92,10 @@ execute_process(COMMAND git rev-parse --short=7 HEAD OUTPUT_VARIABLE GIT_HEAD ERROR_QUIET) string(STRIP "${GIT_HEAD}" GIT_HEAD) -if(GIT_HEAD STREQUAL "") +if(GIT_HEAD STREQUAL "" AND NOT GIT_HEAD_OVERRIDE STREQUAL "") string(SUBSTRING "${GIT_HEAD_OVERRIDE}" 0 7 GIT_HEAD) +elseif(EXISTS ${CMAKE_SOURCE_DIR}/.gitrev) + file(READ ${CMAKE_SOURCE_DIR}/.gitrev GIT_HEAD) endif() message(STATUS "Found Git HEAD Revision: ${GIT_HEAD}\n") @@ -116,13 +119,16 @@ if(OVERRIDE_VERSION) elseif(OVERRIDE_VERSION MATCHES "^[\\.0-9]+$") set(KEEPASSXC_BUILD_TYPE Release) set(KEEPASSXC_VERSION ${OVERRIDE_VERSION}) + else() + set(KEEPASSXC_BUILD_TYPE Snapshot) + set(KEEPASSXC_VERSION ${OVERRIDE_VERSION}) + endif() +else() + if(KEEPASSXC_BUILD_TYPE STREQUAL "PreRelease") + set(KEEPASSXC_VERSION "${KEEPASSXC_VERSION}-preview") + elseif(KEEPASSXC_BUILD_TYPE STREQUAL "Snapshot") + set(KEEPASSXC_VERSION "${KEEPASSXC_VERSION}-snapshot") endif() -endif() - -if(KEEPASSXC_BUILD_TYPE STREQUAL "PreRelease" AND NOT OVERRIDE_VERSION) - set(KEEPASSXC_VERSION "${KEEPASSXC_VERSION}-preview") -elseif(KEEPASSXC_BUILD_TYPE STREQUAL "Snapshot") - set(KEEPASSXC_VERSION "${KEEPASSXC_VERSION}-snapshot") endif() if(KEEPASSXC_BUILD_TYPE STREQUAL "Release") diff --git a/release-tool b/release-tool index ab4128a35..821a1e8c1 100755 --- a/release-tool +++ b/release-tool @@ -813,13 +813,17 @@ build() { init OUTPUT_DIR="$(realpath "$OUTPUT_DIR")" + # Resolve appsign key to absolute path if under Windows + if [[ "${build_key}" && "$(uname -o)" == "Msys" ]]; then + build_key="$(realpath "${build_key}")" + fi if ${build_snapshot}; then TAG_NAME="HEAD" local branch=`git rev-parse --abbrev-ref HEAD` logInfo "Using current branch ${branch} to build..." RELEASE_NAME="${RELEASE_NAME}-snapshot" - CMAKE_OPTIONS="${CMAKE_OPTIONS} -DKEEPASSXC_BUILD_TYPE=Snapshot" + CMAKE_OPTIONS="${CMAKE_OPTIONS} -DKEEPASSXC_BUILD_TYPE=Snapshot -DOVERRIDE_VERSION=${RELEASE_NAME}" else checkWorkingTreeClean @@ -848,14 +852,13 @@ build() { git archive --format=tar "$TAG_NAME" --prefix="${prefix}/" --output="${OUTPUT_DIR}/${tarball_name}" - if ! ${build_snapshot}; then - # add .version file to tar - mkdir "${prefix}" - echo -n ${RELEASE_NAME} > "${prefix}/.version" - tar --append --file="${OUTPUT_DIR}/${tarball_name}" "${prefix}/.version" - rm "${prefix}/.version" - rmdir "${prefix}" 2> /dev/null - fi + # add .version and .gitrev files to tarball + mkdir "${prefix}" + echo -n ${RELEASE_NAME} > "${prefix}/.version" + echo -n `git rev-parse --short=7 HEAD` > "${prefix}/.gitrev" + tar --append --file="${OUTPUT_DIR}/${tarball_name}" "${prefix}/.version" "${prefix}/.gitrev" + rm "${prefix}/.version" "${prefix}/.gitrev" + rmdir "${prefix}" 2> /dev/null xz -6 "${OUTPUT_DIR}/${tarball_name}" fi @@ -881,6 +884,8 @@ build() { # linuxdeploy requires /usr as install prefix INSTALL_PREFIX="/usr" fi + # Do not build tests cases + CMAKE_OPTIONS="${CMAKE_OPTIONS} -DWITH_TESTS=OFF" if [ "$COMPILER" == "g++" ]; then export CC=gcc @@ -913,14 +918,14 @@ build() { elif [ "$(uname -o)" == "Msys" ]; then # Building on Windows with Msys2 logInfo "Configuring build..." - cmake -DCMAKE_BUILD_TYPE=Release -DWITH_TESTS=Off -G"MSYS Makefiles" \ + cmake -DCMAKE_BUILD_TYPE=Release -G"MSYS Makefiles" \ -DCMAKE_INSTALL_PREFIX="${INSTALL_PREFIX}" ${CMAKE_OPTIONS} "$SRC_DIR" logInfo "Compiling and packaging sources..." mingw32-make ${MAKE_OPTIONS} preinstall # Appsign the executables if desired - if ${build_appsign} && [ -f ${build_key} ]; then + if ${build_appsign} && [ -f "${build_key}" ]; then logInfo "Signing executable files" appsign "-f" $(find src | grep -P '\.exe$|\.dll$') "-k" "${build_key}" fi @@ -945,7 +950,7 @@ build() { # Building on Linux without Docker container logInfo "Configuring build..." - cmake -DCMAKE_BUILD_TYPE=Release -DWITH_TESTS=Off ${CMAKE_OPTIONS} \ + cmake -DCMAKE_BUILD_TYPE=Release ${CMAKE_OPTIONS} \ -DCMAKE_INSTALL_PREFIX="${INSTALL_PREFIX}" "$SRC_DIR" logInfo "Compiling sources..." @@ -977,7 +982,7 @@ build() { -v "$(realpath "$OUTPUT_DIR"):/keepassxc/out:rw" \ "$DOCKER_IMAGE" \ bash -c "cd /keepassxc/out/build-release && \ - cmake -DCMAKE_BUILD_TYPE=Release -DWITH_TESTS=Off ${CMAKE_OPTIONS} \ + cmake -DCMAKE_BUILD_TYPE=Release ${CMAKE_OPTIONS} \ -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} /keepassxc/src && \ make ${MAKE_OPTIONS} && make DESTDIR=/keepassxc/out/KeePassXC.AppDir install/strip" fi @@ -1139,7 +1144,7 @@ appsign() { fi logInfo "Signing app using codesign..." - codesign --sign "${key}" --verbose --deep --entitlements ${orig_dir}/share/macosx/keepassxc.entitlements ./app/KeePassXC.app + codesign --sign "${key}" --verbose --deep --entitlements "${SRC_DIR}/share/macosx/keepassxc.entitlements" ./app/KeePassXC.app if [ 0 -ne $? ]; then cd "${orig_dir}" -- cgit v1.2.3 From 53a57ee8c7b0f6ebb9ec89321a005833a1b5f9ba Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Tue, 9 Apr 2019 21:32:10 -0400 Subject: Hide window when performing entry auto-type on macOS * Instead of choosing the last active window, always hide the current window (ie, KeePassXC) * Fixes #2883 --- src/autotype/AutoType.cpp | 2 +- src/autotype/AutoTypePlatformPlugin.h | 2 +- src/autotype/mac/AutoTypeMac.cpp | 4 ++-- src/autotype/mac/AutoTypeMac.h | 2 +- src/autotype/test/AutoTypeTest.cpp | 2 +- src/autotype/test/AutoTypeTest.h | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/autotype/AutoType.cpp b/src/autotype/AutoType.cpp index 012dee62c..0f772d8d3 100644 --- a/src/autotype/AutoType.cpp +++ b/src/autotype/AutoType.cpp @@ -214,7 +214,7 @@ void AutoType::executeAutoTypeActions(const Entry* entry, QWidget* hideWindow, c if (hideWindow) { #if defined(Q_OS_MACOS) - m_plugin->raiseLastActiveWindow(); + m_plugin->hideOwnWindow(); #else hideWindow->showMinimized(); #endif diff --git a/src/autotype/AutoTypePlatformPlugin.h b/src/autotype/AutoTypePlatformPlugin.h index 68cf99be2..059e7e134 100644 --- a/src/autotype/AutoTypePlatformPlugin.h +++ b/src/autotype/AutoTypePlatformPlugin.h @@ -43,7 +43,7 @@ public: virtual AutoTypeExecutor* createExecutor() = 0; #if defined(Q_OS_MACOS) - virtual bool raiseLastActiveWindow() = 0; + virtual bool hideOwnWindow() = 0; virtual bool raiseOwnWindow() = 0; #endif diff --git a/src/autotype/mac/AutoTypeMac.cpp b/src/autotype/mac/AutoTypeMac.cpp index 60cec1144..e73e53777 100644 --- a/src/autotype/mac/AutoTypeMac.cpp +++ b/src/autotype/mac/AutoTypeMac.cpp @@ -165,9 +165,9 @@ bool AutoTypePlatformMac::raiseWindow(WId pid) // // Activate last active window // -bool AutoTypePlatformMac::raiseLastActiveWindow() +bool AutoTypePlatformMac::hideOwnWindow() { - return macUtils()->raiseLastActiveWindow(); + return macUtils()->hideOwnWindow(); } // diff --git a/src/autotype/mac/AutoTypeMac.h b/src/autotype/mac/AutoTypeMac.h index 875c21764..55963da51 100644 --- a/src/autotype/mac/AutoTypeMac.h +++ b/src/autotype/mac/AutoTypeMac.h @@ -44,7 +44,7 @@ public: bool raiseWindow(WId pid) override; AutoTypeExecutor* createExecutor() override; - bool raiseLastActiveWindow() override; + bool hideOwnWindow() override; bool raiseOwnWindow() override; void sendChar(const QChar& ch, bool isKeyDown); diff --git a/src/autotype/test/AutoTypeTest.cpp b/src/autotype/test/AutoTypeTest.cpp index f8754ef3b..9a1b65013 100644 --- a/src/autotype/test/AutoTypeTest.cpp +++ b/src/autotype/test/AutoTypeTest.cpp @@ -111,7 +111,7 @@ bool AutoTypePlatformTest::raiseWindow(WId window) } #if defined(Q_OS_MACOS) -bool AutoTypePlatformTest::raiseLastActiveWindow() +bool AutoTypePlatformTest::hideOwnWindow() { return false; } diff --git a/src/autotype/test/AutoTypeTest.h b/src/autotype/test/AutoTypeTest.h index a17028b51..87d19491a 100644 --- a/src/autotype/test/AutoTypeTest.h +++ b/src/autotype/test/AutoTypeTest.h @@ -44,7 +44,7 @@ public: AutoTypeExecutor* createExecutor() override; #if defined(Q_OS_MACOS) - bool raiseLastActiveWindow() override; + bool hideOwnWindow() override; bool raiseOwnWindow() override; #endif -- cgit v1.2.3 From 2ffefc95ae22f25d5bac2f60bd486640eff7cea0 Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Tue, 9 Apr 2019 21:06:13 -0400 Subject: Enhance update checker * Reduce initial update check notification to 500 ms to prevent inappropriately stealing focus from user * Add build flag WITH_XC_UPDATECHECK which defaults to ON * Update checks are resolved every 7 days instead of every time the application is started * Better checks for beta builds; ignore snapshots * Increase test cases --- CMakeLists.txt | 5 ++ src/CMakeLists.txt | 1 + src/config-keepassx.h.cmake | 1 + src/core/Clock.cpp | 1 + src/gui/ApplicationSettingsWidget.cpp | 14 ++++- src/gui/ApplicationSettingsWidget.h | 1 + src/gui/ApplicationSettingsWidgetGeneral.ui | 39 +++++++++++--- src/gui/MainWindow.cpp | 12 ++--- src/updatecheck/UpdateChecker.cpp | 79 ++++++++++++++++++----------- src/updatecheck/UpdateChecker.h | 2 +- tests/TestUpdateCheck.cpp | 35 ++++++++++--- 11 files changed, 135 insertions(+), 55 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3e7928570..536b08d9d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,6 +49,7 @@ option(WITH_XC_YUBIKEY "Include YubiKey support." OFF) option(WITH_XC_SSHAGENT "Include SSH agent support." OFF) option(WITH_XC_KEESHARE "Sharing integration with KeeShare" OFF) option(WITH_XC_KEESHARE_SECURE "Sharing integration with secured KeeShare containers" OFF) +option(WITH_XC_UPDATECHECK "Include automatic update checks; disable for controlled distributions" ON) if(APPLE) option(WITH_XC_TOUCHID "Include TouchID support for macOS." OFF) endif() @@ -76,6 +77,10 @@ else() set(WITH_XC_CRYPTO_SSH OFF) endif() +if(WITH_XC_UPDATECHECK) + set(WITH_XC_NETWORKING ON) +endif() + set(KEEPASSXC_VERSION_MAJOR "2") set(KEEPASSXC_VERSION_MINOR "4") set(KEEPASSXC_VERSION_PATCH "0") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b2cd27232..d8eb681e3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -195,6 +195,7 @@ add_feature_info(SSHAgent WITH_XC_SSHAGENT "SSH agent integration compatible wit add_feature_info(KeeShare WITH_XC_KEESHARE "Sharing integration with KeeShare") add_feature_info(KeeShare-Secure WITH_XC_KEESHARE_SECURE "Sharing integration with KeeShare with secure sources") add_feature_info(YubiKey WITH_XC_YUBIKEY "YubiKey HMAC-SHA1 challenge-response") +add_feature_info(UpdateCheck WITH_XC_UPDATECHECK "Automatic update checking") if(APPLE) add_feature_info(TouchID WITH_XC_TOUCHID "TouchID integration") endif() diff --git a/src/config-keepassx.h.cmake b/src/config-keepassx.h.cmake index 7d7018861..2acff4466 100644 --- a/src/config-keepassx.h.cmake +++ b/src/config-keepassx.h.cmake @@ -20,6 +20,7 @@ #cmakedefine WITH_XC_KEESHARE #cmakedefine WITH_XC_KEESHARE_INSECURE #cmakedefine WITH_XC_KEESHARE_SECURE +#cmakedefine WITH_XC_UPDATECHECK #cmakedefine WITH_XC_TOUCHID #cmakedefine KEEPASSXC_BUILD_TYPE "@KEEPASSXC_BUILD_TYPE@" diff --git a/src/core/Clock.cpp b/src/core/Clock.cpp index 88ac4fb77..be9e91dcf 100644 --- a/src/core/Clock.cpp +++ b/src/core/Clock.cpp @@ -30,6 +30,7 @@ QDateTime Clock::currentDateTime() uint Clock::currentSecondsSinceEpoch() { + // TODO: change to toSecsSinceEpoch() when min Qt >= 5.8 return instance().currentDateTimeImpl().toTime_t(); } diff --git a/src/gui/ApplicationSettingsWidget.cpp b/src/gui/ApplicationSettingsWidget.cpp index 849df03ae..22a49dece 100644 --- a/src/gui/ApplicationSettingsWidget.cpp +++ b/src/gui/ApplicationSettingsWidget.cpp @@ -92,8 +92,15 @@ ApplicationSettingsWidget::ApplicationSettingsWidget(QWidget* parent) m_secUi->touchIDResetSpinBox, SLOT(setEnabled(bool))); // clang-format on -#ifndef WITH_XC_NETWORKING +#ifdef WITH_XC_UPDATECHECK + connect(m_generalUi->checkForUpdatesOnStartupCheckBox, SIGNAL(toggled(bool)), SLOT(checkUpdatesToggled(bool))); +#else m_generalUi->checkForUpdatesOnStartupCheckBox->setVisible(false); + m_generalUi->checkForUpdatesIncludeBetasCheckBox->setVisible(false); + m_generalUi->checkUpdatesSpacer->changeSize(0,0, QSizePolicy::Fixed, QSizePolicy::Fixed); +#endif + +#ifndef WITH_XC_NETWORKING m_secUi->privacy->setVisible(false); #endif @@ -350,3 +357,8 @@ void ApplicationSettingsWidget::rememberDatabasesToggled(bool checked) m_generalUi->rememberLastKeyFilesCheckBox->setEnabled(checked); m_generalUi->openPreviousDatabasesOnStartupCheckBox->setEnabled(checked); } + +void ApplicationSettingsWidget::checkUpdatesToggled(bool checked) +{ + m_generalUi->checkForUpdatesIncludeBetasCheckBox->setEnabled(checked); +} diff --git a/src/gui/ApplicationSettingsWidget.h b/src/gui/ApplicationSettingsWidget.h index 85b3b4700..dfffbddbd 100644 --- a/src/gui/ApplicationSettingsWidget.h +++ b/src/gui/ApplicationSettingsWidget.h @@ -57,6 +57,7 @@ private slots: void systrayToggled(bool checked); void toolbarSettingsToggled(bool checked); void rememberDatabasesToggled(bool checked); + void checkUpdatesToggled(bool checked); private: QWidget* const m_secWidget; diff --git a/src/gui/ApplicationSettingsWidgetGeneral.ui b/src/gui/ApplicationSettingsWidgetGeneral.ui index f84c6a550..9f03bbb50 100644 --- a/src/gui/ApplicationSettingsWidgetGeneral.ui +++ b/src/gui/ApplicationSettingsWidgetGeneral.ui @@ -141,10 +141,40 @@ - Check for updates at application startup + Check for updates at application startup once per week + + + + 0 + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + Include beta releases when checking for updates + + + + + @@ -241,13 +271,6 @@ General - - - - Include pre-releases when checking for updates - - - diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 9e60b53e2..bf8c6654e 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -41,7 +41,7 @@ #include "keys/FileKey.h" #include "keys/PasswordKey.h" -#ifdef WITH_XC_NETWORKING +#ifdef WITH_XC_UPDATECHECK #include "gui/MessageBox.h" #include "gui/UpdateCheckDialog.h" #include "updatecheck/UpdateChecker.h" @@ -372,12 +372,12 @@ MainWindow::MainWindow() setUnifiedTitleAndToolBarOnMac(true); #endif -#ifdef WITH_XC_NETWORKING +#ifdef WITH_XC_UPDATECHECK connect(m_ui->actionCheckForUpdates, SIGNAL(triggered()), SLOT(showUpdateCheckDialog())); connect(UpdateChecker::instance(), SIGNAL(updateCheckFinished(bool, QString, bool)), SLOT(hasUpdateAvailable(bool, QString, bool))); - QTimer::singleShot(3000, this, SLOT(showUpdateCheckStartup())); + QTimer::singleShot(500, this, SLOT(showUpdateCheckStartup())); #else m_ui->actionCheckForUpdates->setVisible(false); #endif @@ -670,7 +670,7 @@ void MainWindow::showAboutDialog() void MainWindow::showUpdateCheckStartup() { -#ifdef WITH_XC_NETWORKING +#ifdef WITH_XC_UPDATECHECK if (!config()->get("UpdateCheckMessageShown", false).toBool()) { auto result = MessageBox::question(this, @@ -693,7 +693,7 @@ void MainWindow::showUpdateCheckStartup() void MainWindow::hasUpdateAvailable(bool hasUpdate, const QString& version, bool isManuallyRequested) { -#ifdef WITH_XC_NETWORKING +#ifdef WITH_XC_UPDATECHECK if (hasUpdate && !isManuallyRequested) { auto* updateCheckDialog = new UpdateCheckDialog(this); updateCheckDialog->showUpdateCheckResponse(hasUpdate, version); @@ -708,7 +708,7 @@ void MainWindow::hasUpdateAvailable(bool hasUpdate, const QString& version, bool void MainWindow::showUpdateCheckDialog() { -#ifdef WITH_XC_NETWORKING +#ifdef WITH_XC_UPDATECHECK updateCheck()->checkForUpdates(true); auto* updateCheckDialog = new UpdateCheckDialog(this); updateCheckDialog->show(); diff --git a/src/updatecheck/UpdateChecker.cpp b/src/updatecheck/UpdateChecker.cpp index 4272410b6..145312907 100644 --- a/src/updatecheck/UpdateChecker.cpp +++ b/src/updatecheck/UpdateChecker.cpp @@ -17,6 +17,7 @@ #include "UpdateChecker.h" #include "config-keepassx.h" +#include "core/Clock.h" #include "core/Config.h" #include #include @@ -38,24 +39,28 @@ UpdateChecker::~UpdateChecker() void UpdateChecker::checkForUpdates(bool manuallyRequested) { + auto nextCheck = config()->get("GUI/CheckForUpdatesNextCheck", 0).toULongLong(); m_isManuallyRequested = manuallyRequested; - m_bytesReceived.clear(); - QString apiUrlStr = QString("https://api.github.com/repos/keepassxreboot/keepassxc/releases"); + if (m_isManuallyRequested || Clock::currentSecondsSinceEpoch() >= nextCheck) { + m_bytesReceived.clear(); - if (!config()->get("GUI/CheckForUpdatesIncludeBetas", false).toBool()) { - apiUrlStr += "/latest"; - } + QString apiUrlStr = QString("https://api.github.com/repos/keepassxreboot/keepassxc/releases"); + + if (!config()->get("GUI/CheckForUpdatesIncludeBetas", false).toBool()) { + apiUrlStr += "/latest"; + } - QUrl apiUrl = QUrl(apiUrlStr); + QUrl apiUrl = QUrl(apiUrlStr); - QNetworkRequest request(apiUrl); - request.setRawHeader("Accept", "application/json"); + QNetworkRequest request(apiUrl); + request.setRawHeader("Accept", "application/json"); - m_reply = m_netMgr->get(request); + m_reply = m_netMgr->get(request); - connect(m_reply, &QNetworkReply::finished, this, &UpdateChecker::fetchFinished); - connect(m_reply, &QIODevice::readyRead, this, &UpdateChecker::fetchReadyRead); + connect(m_reply, &QNetworkReply::finished, this, &UpdateChecker::fetchFinished); + connect(m_reply, &QIODevice::readyRead, this, &UpdateChecker::fetchReadyRead); + } } void UpdateChecker::fetchReadyRead() @@ -84,8 +89,12 @@ void UpdateChecker::fetchFinished() if (!jsonObject.value("tag_name").isUndefined()) { version = jsonObject.value("tag_name").toString(); - hasNewVersion = compareVersions(version, QString(KEEPASSXC_VERSION)); + hasNewVersion = compareVersions(QString(KEEPASSXC_VERSION), version); } + + // Check again in 7 days + // TODO: change to toSecsSinceEpoch() when min Qt >= 5.8 + config()->set("GUI/CheckForUpdatesNextCheck", Clock::currentDateTime().addDays(7).toTime_t()); } else { version = "error"; } @@ -93,38 +102,46 @@ void UpdateChecker::fetchFinished() emit updateCheckFinished(hasNewVersion, version, m_isManuallyRequested); } -bool UpdateChecker::compareVersions(const QString& remoteVersion, const QString& localVersion) +bool UpdateChecker::compareVersions(const QString& localVersion, const QString& remoteVersion) { + // Quick full-string equivalence check if (localVersion == remoteVersion) { - return false; // Currently using updated version + return false; } - QRegularExpression verRegex("^(\\d+(\\.\\d+){0,2})(-\\w+)?$", QRegularExpression::CaseInsensitiveOption); + QRegularExpression verRegex(R"(^((?:\d+\.){2}\d+)(?:-(\w+?)(\d+)?)?$)"); - QRegularExpressionMatch lmatch = verRegex.match(localVersion); - QRegularExpressionMatch rmatch = verRegex.match(remoteVersion); + auto lmatch = verRegex.match(localVersion); + auto rmatch = verRegex.match(remoteVersion); - if (!lmatch.captured(1).isNull() && !rmatch.captured(1).isNull()) { - if (lmatch.captured(1) == rmatch.captured(1) && !lmatch.captured(3).isNull()) { - // Same version, but installed version has snapshot/beta suffix and should be updated to stable - return true; - } + auto lVersion = lmatch.captured(1).split("."); + auto lSuffix = lmatch.captured(2); + auto lBetaNum = lmatch.captured(3); - QStringList lparts = lmatch.captured(1).split("."); - QStringList rparts = rmatch.captured(1).split("."); + auto rVersion = rmatch.captured(1).split("."); + auto rSuffix = rmatch.captured(2); + auto rBetaNum = rmatch.captured(3); - if (lparts.length() < 3) - lparts << "0"; + if (!lVersion.isEmpty() && !rVersion.isEmpty()) { + if (lSuffix.compare("snapshot", Qt::CaseInsensitive) == 0) { + // Snapshots are not checked for version updates + return false; + } - if (rparts.length() < 3) - rparts << "0"; + // Check "-beta[X]" versions + if (lVersion == rVersion && !lSuffix.isEmpty()) { + // Check if stable version has been released or new beta is available + // otherwise the version numbers are equal + return rSuffix.isEmpty() || lBetaNum.toInt() < rBetaNum.toInt(); + } for (int i = 0; i < 3; i++) { - int l = lparts[i].toInt(); - int r = rparts[i].toInt(); + int l = lVersion[i].toInt(); + int r = rVersion[i].toInt(); - if (l == r) + if (l == r) { continue; + } if (l > r) { return false; // Installed version is newer than release diff --git a/src/updatecheck/UpdateChecker.h b/src/updatecheck/UpdateChecker.h index ac6471d64..64430bda3 100644 --- a/src/updatecheck/UpdateChecker.h +++ b/src/updatecheck/UpdateChecker.h @@ -31,7 +31,7 @@ public: ~UpdateChecker() override; void checkForUpdates(bool manuallyRequested); - static bool compareVersions(const QString& remoteVersion, const QString& localVersion); + static bool compareVersions(const QString& localVersion, const QString& remoteVersion); static UpdateChecker* instance(); signals: diff --git a/tests/TestUpdateCheck.cpp b/tests/TestUpdateCheck.cpp index 8cba43b1d..ff709cd56 100644 --- a/tests/TestUpdateCheck.cpp +++ b/tests/TestUpdateCheck.cpp @@ -29,13 +29,32 @@ void TestUpdateCheck::initTestCase() void TestUpdateCheck::testCompareVersion() { - // Remote Version , Installed Version - QCOMPARE(UpdateChecker::compareVersions(QString("2.4.0"), QString("2.3.4")), true); - QCOMPARE(UpdateChecker::compareVersions(QString("2.3.0"), QString("2.4.0")), false); + // No upgrade QCOMPARE(UpdateChecker::compareVersions(QString("2.3.0"), QString("2.3.0")), false); - QCOMPARE(UpdateChecker::compareVersions(QString("2.3.0"), QString("2.3.0-beta1")), true); - QCOMPARE(UpdateChecker::compareVersions(QString("2.3.0-beta2"), QString("2.3.0-beta1")), true); - QCOMPARE(UpdateChecker::compareVersions(QString("2.3.4"), QString("2.4.0-snapshot")), false); - QCOMPARE(UpdateChecker::compareVersions(QString("invalid"), QString("2.4.0")), false); - QCOMPARE(UpdateChecker::compareVersions(QString(""), QString("2.4.0")), false); + + // First digit upgrade + QCOMPARE(UpdateChecker::compareVersions(QString("2.4.0"), QString("3.0.0")), true); + QCOMPARE(UpdateChecker::compareVersions(QString("3.0.0"), QString("2.4.0")), false); + + // Second digit upgrade + QCOMPARE(UpdateChecker::compareVersions(QString("2.3.4"), QString("2.4.0")), true); + QCOMPARE(UpdateChecker::compareVersions(QString("2.4.0"), QString("2.3.4")), false); + + // Third digit upgrade + QCOMPARE(UpdateChecker::compareVersions(QString("2.3.0"), QString("2.3.1")), true); + QCOMPARE(UpdateChecker::compareVersions(QString("2.3.1"), QString("2.3.0")), false); + + // Beta builds + QCOMPARE(UpdateChecker::compareVersions(QString("2.3.0"), QString("2.3.0-beta1")), false); + QCOMPARE(UpdateChecker::compareVersions(QString("2.3.0"), QString("2.3.1-beta1")), true); + QCOMPARE(UpdateChecker::compareVersions(QString("2.3.0-beta1"), QString("2.3.0")), true); + QCOMPARE(UpdateChecker::compareVersions(QString("2.3.0-beta"), QString("2.3.0-beta1")), true); + QCOMPARE(UpdateChecker::compareVersions(QString("2.3.0-beta1"), QString("2.3.0-beta")), false); + QCOMPARE(UpdateChecker::compareVersions(QString("2.3.0-beta1"), QString("2.3.0-beta2")), true); + QCOMPARE(UpdateChecker::compareVersions(QString("2.3.0-beta2"), QString("2.3.0-beta1")), false); + + // Snapshot and invalid data + QCOMPARE(UpdateChecker::compareVersions(QString("2.3.4-snapshot"), QString("2.4.0")), false); + QCOMPARE(UpdateChecker::compareVersions(QString("2.4.0"), QString("invalid")), false); + QCOMPARE(UpdateChecker::compareVersions(QString("2.4.0"), QString("")), false); } -- cgit v1.2.3 From c195452c54ef67b02d590d37c7e413606a35ffcc Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Thu, 11 Apr 2019 10:17:18 -0400 Subject: Re-Add keys on database unlock * Keys that were previously added do not show an error message (they are most likely still in the agent) * Shifted to using the KeeAgentSettings class to guide behavior of addIdentity function * Fixes #2902 --- src/gui/entry/EditEntryWidget.cpp | 13 ++++++------- src/sshagent/SSHAgent.cpp | 31 ++++++++++++++----------------- src/sshagent/SSHAgent.h | 3 ++- 3 files changed, 22 insertions(+), 25 deletions(-) diff --git a/src/gui/entry/EditEntryWidget.cpp b/src/gui/entry/EditEntryWidget.cpp index 508f3c68c..063f8da2c 100644 --- a/src/gui/entry/EditEntryWidget.cpp +++ b/src/gui/entry/EditEntryWidget.cpp @@ -597,15 +597,14 @@ void EditEntryWidget::addKeyToAgent() m_sshAgentUi->commentTextLabel->setText(key.comment()); m_sshAgentUi->publicKeyEdit->document()->setPlainText(key.publicKey()); - int lifetime = 0; - bool confirm = m_sshAgentUi->requireUserConfirmationCheckBox->isChecked(); + KeeAgentSettings settings; - if (m_sshAgentUi->lifetimeCheckBox->isChecked()) { - lifetime = m_sshAgentUi->lifetimeSpinBox->value(); - } + settings.setRemoveAtDatabaseClose(m_sshAgentUi->removeKeyFromAgentCheckBox->isChecked()); + settings.setUseConfirmConstraintWhenAdding(m_sshAgentUi->requireUserConfirmationCheckBox->isChecked()); + settings.setUseLifetimeConstraintWhenAdding(m_sshAgentUi->lifetimeCheckBox->isChecked()); + settings.setLifetimeConstraintDuration(m_sshAgentUi->lifetimeSpinBox->value()); - if (!SSHAgent::instance()->addIdentity( - key, m_sshAgentUi->removeKeyFromAgentCheckBox->isChecked(), static_cast(lifetime), confirm)) { + if (!SSHAgent::instance()->addIdentity(key, settings)) { showMessage(SSHAgent::instance()->errorString(), MessageWidget::Error); return; } diff --git a/src/sshagent/SSHAgent.cpp b/src/sshagent/SSHAgent.cpp index c2ef7084a..033c72330 100644 --- a/src/sshagent/SSHAgent.cpp +++ b/src/sshagent/SSHAgent.cpp @@ -187,7 +187,7 @@ bool SSHAgent::sendMessagePageant(const QByteArray& in, QByteArray& out) * @param removeOnLock autoremove from agent when the Database is locked * @return true on success */ -bool SSHAgent::addIdentity(OpenSSHKey& key, bool removeOnLock, quint32 lifetime, bool confirm) +bool SSHAgent::addIdentity(OpenSSHKey& key, KeeAgentSettings& settings) { if (!isAgentRunning()) { m_error = tr("No agent running, cannot add identity."); @@ -197,15 +197,17 @@ bool SSHAgent::addIdentity(OpenSSHKey& key, bool removeOnLock, quint32 lifetime, QByteArray requestData; BinaryStream request(&requestData); - request.write((lifetime > 0 || confirm) ? SSH_AGENTC_ADD_ID_CONSTRAINED : SSH_AGENTC_ADD_IDENTITY); + request.write((settings.useLifetimeConstraintWhenAdding() || settings.useConfirmConstraintWhenAdding()) + ? SSH_AGENTC_ADD_ID_CONSTRAINED + : SSH_AGENTC_ADD_IDENTITY); key.writePrivate(request); - if (lifetime > 0) { + if (settings.useLifetimeConstraintWhenAdding()) { request.write(SSH_AGENT_CONSTRAIN_LIFETIME); - request.write(lifetime); + request.write(static_cast(settings.lifetimeConstraintDuration())); } - if (confirm) { + if (settings.useConfirmConstraintWhenAdding()) { request.write(SSH_AGENT_CONSTRAIN_CONFIRM); } @@ -218,11 +220,11 @@ bool SSHAgent::addIdentity(OpenSSHKey& key, bool removeOnLock, quint32 lifetime, m_error = tr("Agent refused this identity. Possible reasons include:") + "\n" + tr("The key has already been added."); - if (lifetime > 0) { + if (settings.useLifetimeConstraintWhenAdding()) { m_error += "\n" + tr("Restricted lifetime is not supported by the agent (check options)."); } - if (confirm) { + if (settings.useConfirmConstraintWhenAdding()) { m_error += "\n" + tr("A confirmation request is not supported by the agent (check options)."); } @@ -231,7 +233,7 @@ bool SSHAgent::addIdentity(OpenSSHKey& key, bool removeOnLock, quint32 lifetime, OpenSSHKey keyCopy = key; keyCopy.clearPrivate(); - m_addedKeys[keyCopy] = removeOnLock; + m_addedKeys[keyCopy] = settings.removeAtDatabaseClose(); return true; } @@ -364,15 +366,10 @@ void SSHAgent::databaseModeChanged() key.setComment(fileName); } - if (!m_addedKeys.contains(key) && settings.addAtDatabaseOpen()) { - quint32 lifetime = 0; - - if (settings.useLifetimeConstraintWhenAdding()) { - lifetime = static_cast(settings.lifetimeConstraintDuration()); - } - - if (!addIdentity( - key, settings.removeAtDatabaseClose(), lifetime, settings.useConfirmConstraintWhenAdding())) { + if (settings.addAtDatabaseOpen()) { + // Add key to agent; ignore errors if we have previously added the key + bool known_key = m_addedKeys.contains(key); + if (!addIdentity(key, settings) && !known_key) { emit error(m_error); } } diff --git a/src/sshagent/SSHAgent.h b/src/sshagent/SSHAgent.h index 90adfa82f..940d8c554 100644 --- a/src/sshagent/SSHAgent.h +++ b/src/sshagent/SSHAgent.h @@ -25,6 +25,7 @@ #include "crypto/ssh/OpenSSHKey.h" #include "gui/DatabaseWidget.h" +#include "sshagent/KeeAgentSettings.h" class SSHAgent : public QObject { @@ -36,7 +37,7 @@ public: const QString errorString() const; bool isAgentRunning() const; - bool addIdentity(OpenSSHKey& key, bool removeOnLock, quint32 lifetime, bool confirm); + bool addIdentity(OpenSSHKey& key, KeeAgentSettings& settings); bool removeIdentity(OpenSSHKey& key); void setAutoRemoveOnLock(const OpenSSHKey& key, bool autoRemove); -- cgit v1.2.3 From bc5173bac709d6abd0d651937164cc9d6a8aefd3 Mon Sep 17 00:00:00 2001 From: Janek Bevendorff Date: Fri, 12 Apr 2019 19:49:43 +0200 Subject: Fix compilation with GCC 5 (#2990) --- src/keeshare/KeeShareSettings.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/keeshare/KeeShareSettings.cpp b/src/keeshare/KeeShareSettings.cpp index 5b087a294..a640cdaed 100644 --- a/src/keeshare/KeeShareSettings.cpp +++ b/src/keeshare/KeeShareSettings.cpp @@ -28,6 +28,8 @@ #include #include +#include + namespace KeeShareSettings { namespace -- cgit v1.2.3 From cc27a367d6c161d563ee63568578cd50debb77d5 Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Fri, 12 Apr 2019 13:55:28 -0400 Subject: Only remove keys on exit if they would remove on lock (#2985) * Don't remove keys on app exit that would not be removed due to database locking. * Restores behavior from 2.3.4 * Fixes #2980 --- src/sshagent/SSHAgent.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sshagent/SSHAgent.cpp b/src/sshagent/SSHAgent.cpp index 033c72330..ac25a7066 100644 --- a/src/sshagent/SSHAgent.cpp +++ b/src/sshagent/SSHAgent.cpp @@ -45,8 +45,11 @@ SSHAgent::~SSHAgent() { auto it = m_addedKeys.begin(); while (it != m_addedKeys.end()) { - OpenSSHKey key = it.key(); - removeIdentity(key); + // Remove key if requested to remove on lock + if (it.value()) { + OpenSSHKey key = it.key(); + removeIdentity(key); + } it = m_addedKeys.erase(it); } } -- cgit v1.2.3 From e7815787c72d3f97f79321b764196eeaf57b9fa9 Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Fri, 12 Apr 2019 13:57:49 -0400 Subject: Fix referenced entry color on macOS dark mode (#2984) Introduce macUtils()->isDarkMode() function to detect Mojave dark mode and correct reference entry text color. Fixes #860. --- src/gui/entry/EntryModel.cpp | 8 ++++++++ src/gui/macutils/AppKit.h | 1 + src/gui/macutils/AppKitImpl.h | 1 + src/gui/macutils/AppKitImpl.mm | 8 ++++++++ src/gui/macutils/MacUtils.cpp | 5 +++++ src/gui/macutils/MacUtils.h | 1 + 6 files changed, 24 insertions(+) diff --git a/src/gui/entry/EntryModel.cpp b/src/gui/entry/EntryModel.cpp index 04b6abc17..bf7eca0c7 100644 --- a/src/gui/entry/EntryModel.cpp +++ b/src/gui/entry/EntryModel.cpp @@ -30,6 +30,9 @@ #include "core/Global.h" #include "core/Group.h" #include "core/Metadata.h" +#ifdef Q_OS_MACOS +#include "gui/macutils/MacUtils.h" +#endif EntryModel::EntryModel(QObject* parent) : QAbstractTableModel(parent) @@ -270,6 +273,11 @@ QVariant EntryModel::data(const QModelIndex& index, int role) const } else if (role == Qt::ForegroundRole) { if (entry->hasReferences()) { QPalette p; +#ifdef Q_OS_MACOS + if (macUtils()->isDarkMode()) { + return QVariant(p.color(QPalette::Inactive, QPalette::Dark)); + } +#endif return QVariant(p.color(QPalette::Active, QPalette::Mid)); } else if (entry->foregroundColor().isValid()) { return QVariant(entry->foregroundColor()); diff --git a/src/gui/macutils/AppKit.h b/src/gui/macutils/AppKit.h index ecd11c421..cdb822ffc 100644 --- a/src/gui/macutils/AppKit.h +++ b/src/gui/macutils/AppKit.h @@ -35,6 +35,7 @@ public: bool activateProcess(pid_t pid); bool hideProcess(pid_t pid); bool isHidden(pid_t pid); + bool isDarkMode(); private: void *self; diff --git a/src/gui/macutils/AppKitImpl.h b/src/gui/macutils/AppKitImpl.h index 97673b071..3bf2d20ef 100644 --- a/src/gui/macutils/AppKitImpl.h +++ b/src/gui/macutils/AppKitImpl.h @@ -30,5 +30,6 @@ - (bool) activateProcess:(pid_t) pid; - (bool) hideProcess:(pid_t) pid; - (bool) isHidden:(pid_t) pid; +- (bool) isDarkMode; @end diff --git a/src/gui/macutils/AppKitImpl.mm b/src/gui/macutils/AppKitImpl.mm index ca4e9f10e..3727878e7 100644 --- a/src/gui/macutils/AppKitImpl.mm +++ b/src/gui/macutils/AppKitImpl.mm @@ -127,4 +127,12 @@ bool AppKit::isHidden(pid_t pid) return [static_cast(self) isHidden:pid]; } +bool AppKit::isDarkMode() +{ + NSDictionary *dict = [[NSUserDefaults standardUserDefaults] persistentDomainForName:NSGlobalDomain]; + id style = [dict objectForKey:@"AppleInterfaceStyle"]; + return ( style && [style isKindOfClass:[NSString class]] + && NSOrderedSame == [style caseInsensitiveCompare:@"dark"] ); +} + @end diff --git a/src/gui/macutils/MacUtils.cpp b/src/gui/macutils/MacUtils.cpp index 602c1958f..c362fe1bd 100644 --- a/src/gui/macutils/MacUtils.cpp +++ b/src/gui/macutils/MacUtils.cpp @@ -70,3 +70,8 @@ bool MacUtils::isHidden() { return m_appkit->isHidden(m_appkit->ownProcessId()); } + +bool MacUtils::isDarkMode() +{ + return m_appkit->isDarkMode(); +} diff --git a/src/gui/macutils/MacUtils.h b/src/gui/macutils/MacUtils.h index 67c53dd22..39a06bd84 100644 --- a/src/gui/macutils/MacUtils.h +++ b/src/gui/macutils/MacUtils.h @@ -37,6 +37,7 @@ public: bool raiseOwnWindow(); bool hideOwnWindow(); bool isHidden(); + bool isDarkMode(); private: explicit MacUtils(QObject* parent = nullptr); -- cgit v1.2.3 From 2eb82c83560844f32f38d17d9ecbd719aed12acb Mon Sep 17 00:00:00 2001 From: ckieschnick Date: Fri, 12 Apr 2019 19:59:50 +0200 Subject: Improve file tracking in BulkFileWatcher (#2978) Introduce modification-based change tracking in BulkFileWatcher to reduce emitted signals caused by file changes within the same directory. Resolves #2895. --- src/core/FileWatcher.cpp | 56 +++++++++++++++++++++++++++--------------------- src/core/FileWatcher.h | 6 +++--- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/src/core/FileWatcher.cpp b/src/core/FileWatcher.cpp index 64e86c3fa..ae7878191 100644 --- a/src/core/FileWatcher.cpp +++ b/src/core/FileWatcher.cpp @@ -120,9 +120,9 @@ BulkFileWatcher::BulkFileWatcher(QObject* parent) { connect(&m_fileWatcher, SIGNAL(fileChanged(QString)), SLOT(handleFileChanged(QString))); connect(&m_fileWatcher, SIGNAL(directoryChanged(QString)), SLOT(handleDirectoryChanged(QString))); - connect(&m_fileWatchUnblockTimer, SIGNAL(timeout()), this, SLOT(observeFileChanges())); + connect(&m_watchedFilesIgnoreTimer, SIGNAL(timeout()), this, SLOT(observeFileChanges())); connect(&m_pendingSignalsTimer, SIGNAL(timeout()), this, SLOT(emitSignals())); - m_fileWatchUnblockTimer.setSingleShot(true); + m_watchedFilesIgnoreTimer.setSingleShot(true); m_pendingSignalsTimer.setSingleShot(true); } @@ -135,7 +135,7 @@ void BulkFileWatcher::clear() } m_watchedPaths.clear(); m_watchedFilesInDirectory.clear(); - m_ignoreFilesChangess.clear(); + m_watchedFilesIgnored.clear(); } void BulkFileWatcher::removePath(const QString& path) @@ -166,7 +166,7 @@ void BulkFileWatcher::addPath(const QString& path) const bool directorySuccess = m_fileWatcher.addPath(directoryPath); m_watchedPaths[directoryPath] = directorySuccess; } - m_watchedFilesInDirectory[directoryPath][filePath] = info.exists(); + m_watchedFilesInDirectory[directoryPath][filePath] = info.exists() ? info.lastModified().toMSecsSinceEpoch() : 0; } void BulkFileWatcher::handleFileChanged(const QString& path) @@ -174,13 +174,15 @@ void BulkFileWatcher::handleFileChanged(const QString& path) const QFileInfo info(path); const QString filePath = info.absoluteFilePath(); const QString directoryPath = info.absolutePath(); - const QMap& watchedFiles = m_watchedFilesInDirectory[directoryPath]; - const bool created = !watchedFiles[filePath] && info.exists(); - const bool deleted = watchedFiles[filePath] && !info.exists(); - const bool changed = !created && !deleted; + const QMap& watchedFiles = m_watchedFilesInDirectory[directoryPath]; + const qint64 lastModificationTime = info.lastModified().toMSecsSinceEpoch(); + const bool created = watchedFiles[filePath] == 0 && info.exists(); + const bool deleted = watchedFiles[filePath] != 0 && !info.exists(); + const bool changed = !created && !deleted && lastModificationTime != watchedFiles[filePath]; + addPath(path); - if (m_ignoreFilesChangess[info.canonicalFilePath()] > Clock::currentDateTimeUtc()) { + if (m_watchedFilesIgnored[info.canonicalFilePath()] > Clock::currentDateTimeUtc()) { // changes are blocked return; } @@ -203,35 +205,36 @@ void BulkFileWatcher::handleDirectoryChanged(const QString& path) qDebug("Directory changed %s", qPrintable(path)); const QFileInfo directoryInfo(path); const QString directoryPath = directoryInfo.absoluteFilePath(); - QMap& watchedFiles = m_watchedFilesInDirectory[directoryPath]; + QMap& watchedFiles = m_watchedFilesInDirectory[directoryPath]; for (const QString& filename : watchedFiles.keys()) { const QFileInfo fileInfo(filename); const QString filePath = fileInfo.absoluteFilePath(); - const bool existed = watchedFiles[filePath]; - if (!fileInfo.exists() && existed) { - qDebug("Remove watch file %s", qPrintable(filePath)); + const qint64 previousModificationTime = watchedFiles[filePath]; + const qint64 lastModificationTime = fileInfo.lastModified().toMSecsSinceEpoch(); + if (!fileInfo.exists() && previousModificationTime != 0) { + qDebug("Remove watch file %s", qPrintable(fileInfo.absoluteFilePath())); m_fileWatcher.removePath(filePath); m_watchedPaths.remove(filePath); watchedFiles.remove(filePath); scheduleSignal(Removed, filePath); } - if (!existed && fileInfo.exists()) { - qDebug("Add watch file %s", qPrintable(filePath)); + if (previousModificationTime == 0 && fileInfo.exists()) { + qDebug("Add watch file %s", qPrintable(fileInfo.absoluteFilePath())); if (!m_watchedPaths.value(filePath)) { const bool success = m_fileWatcher.addPath(filePath); m_watchedPaths[filePath] = success; - watchedFiles[filePath] = fileInfo.exists(); + watchedFiles[filePath] = lastModificationTime; } scheduleSignal(Created, filePath); } - if (existed && fileInfo.exists()) { + if (fileInfo.exists() && previousModificationTime != lastModificationTime) { // this case is handled using qDebug("Refresh watch file %s", qPrintable(fileInfo.absoluteFilePath())); m_fileWatcher.removePath(fileInfo.absolutePath()); m_fileWatcher.addPath(fileInfo.absolutePath()); scheduleSignal(Updated, filePath); } - m_watchedFilesInDirectory[directoryPath][filePath] = fileInfo.exists(); + m_watchedFilesInDirectory[directoryPath][filePath] = fileInfo.exists() ? lastModificationTime : 0; } } @@ -242,13 +245,16 @@ void BulkFileWatcher::emitSignals() for (const auto& path : queued.keys()) { const auto& signal = queued[path]; if (signal.last() == Removed) { + qDebug("Emit %s removed", qPrintable(path)); emit fileRemoved(path); continue; } if (signal.first() == Created) { + qDebug("Emit %s created", qPrintable(path)); emit fileCreated(path); continue; } + qDebug("Emit %s changed", qPrintable(path)); emit fileChanged(path); } } @@ -268,7 +274,7 @@ void BulkFileWatcher::scheduleSignal(Signal signal, const QString& path) void BulkFileWatcher::ignoreFileChanges(const QString& path) { const QFileInfo info(path); - m_ignoreFilesChangess[info.canonicalFilePath()] = Clock::currentDateTimeUtc().addMSecs(FileChangeDelay); + m_watchedFilesIgnored[info.canonicalFilePath()] = Clock::currentDateTimeUtc().addMSecs(FileChangeDelay); } void BulkFileWatcher::observeFileChanges(bool delayed) @@ -278,19 +284,19 @@ void BulkFileWatcher::observeFileChanges(bool delayed) timeout = TimerResolution; } else { const QDateTime current = Clock::currentDateTimeUtc(); - for (const QString& key : m_ignoreFilesChangess.keys()) { - if (m_ignoreFilesChangess[key] < current) { + for (const QString& key : m_watchedFilesIgnored.keys()) { + if (m_watchedFilesIgnored[key] < current) { // We assume that there was no concurrent change of the database // during our block - so no need to reimport qDebug("Remove block from %s", qPrintable(key)); - m_ignoreFilesChangess.remove(key); + m_watchedFilesIgnored.remove(key); continue; } qDebug("Keep block from %s", qPrintable(key)); - timeout = static_cast(current.msecsTo(m_ignoreFilesChangess[key])); + timeout = qMin(timeout, static_cast(current.msecsTo(m_watchedFilesIgnored[key]))); } } - if (timeout > 0 && !m_fileWatchUnblockTimer.isActive()) { - m_fileWatchUnblockTimer.start(timeout); + if (timeout > 0 && !m_watchedFilesIgnoreTimer.isActive()) { + m_watchedFilesIgnoreTimer.start(timeout); } } diff --git a/src/core/FileWatcher.h b/src/core/FileWatcher.h index 00d6a6c69..f6953cf80 100644 --- a/src/core/FileWatcher.h +++ b/src/core/FileWatcher.h @@ -93,11 +93,11 @@ private: private: QMap m_watchedPaths; - QMap m_ignoreFilesChangess; + QMap m_watchedFilesIgnored; QFileSystemWatcher m_fileWatcher; - QMap> m_watchedFilesInDirectory; + QMap> m_watchedFilesInDirectory; // needed for Import/Export-References to prevent update after self-write - QTimer m_fileWatchUnblockTimer; + QTimer m_watchedFilesIgnoreTimer; // needed to tolerate multiple signals for same event QTimer m_pendingSignalsTimer; QMap> m_pendingSignals; -- cgit v1.2.3 From 771ecdba12279f410239bd5a9836862c4285c7af Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Fri, 12 Apr 2019 16:08:38 -0400 Subject: Fix missing function definition on macOS --- src/gui/macutils/AppKitImpl.mm | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/gui/macutils/AppKitImpl.mm b/src/gui/macutils/AppKitImpl.mm index 3727878e7..cd709df27 100644 --- a/src/gui/macutils/AppKitImpl.mm +++ b/src/gui/macutils/AppKitImpl.mm @@ -93,6 +93,17 @@ AppKit::~AppKit() return [app isHidden]; } +// +// Get state of macOS Dark Mode color scheme +// +- (bool) isDarkMode +{ + NSDictionary *dict = [[NSUserDefaults standardUserDefaults] persistentDomainForName:NSGlobalDomain]; + id style = [dict objectForKey:@"AppleInterfaceStyle"]; + return ( style && [style isKindOfClass:[NSString class]] + && NSOrderedSame == [style caseInsensitiveCompare:@"dark"] ); +} + // // ------------------------- C++ Trampolines ------------------------- // @@ -129,10 +140,7 @@ bool AppKit::isHidden(pid_t pid) bool AppKit::isDarkMode() { - NSDictionary *dict = [[NSUserDefaults standardUserDefaults] persistentDomainForName:NSGlobalDomain]; - id style = [dict objectForKey:@"AppleInterfaceStyle"]; - return ( style && [style isKindOfClass:[NSString class]] - && NSOrderedSame == [style caseInsensitiveCompare:@"dark"] ); + return [static_cast(self) isDarkMode]; } @end -- cgit v1.2.3 From 05bee40f0ad6a916708e1bb10f3af8d21c7942ec Mon Sep 17 00:00:00 2001 From: Christian Kieschnick Date: Fri, 12 Apr 2019 12:21:20 +0200 Subject: Fix duplicate icon add in export SharedObserver did not check for already added icons add during export leading to duplicate icons in the target db. --- src/core/Merger.cpp | 2 +- src/core/Metadata.cpp | 4 +++- src/keeshare/ShareObserver.cpp | 7 ++++--- tests/TestMerge.cpp | 28 ++++++++++++++++++++++++++++ tests/TestMerge.h | 1 + 5 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/core/Merger.cpp b/src/core/Merger.cpp index e4cf0f994..c73248388 100644 --- a/src/core/Merger.cpp +++ b/src/core/Merger.cpp @@ -618,8 +618,8 @@ Merger::ChangeList Merger::mergeMetadata(const MergeContext& context) const auto keys = sourceMetadata->customIcons().keys(); for (QUuid customIconId : keys) { - QImage customIcon = sourceMetadata->customIcon(customIconId); if (!targetMetadata->containsCustomIcon(customIconId)) { + QImage customIcon = sourceMetadata->customIcon(customIconId); targetMetadata->addCustomIcon(customIconId, customIcon); changes << tr("Adding missing icon %1").arg(QString::fromLatin1(customIconId.toRfc4122().toHex())); } diff --git a/src/core/Metadata.cpp b/src/core/Metadata.cpp index 45010a4ff..6448c391a 100644 --- a/src/core/Metadata.cpp +++ b/src/core/Metadata.cpp @@ -382,10 +382,12 @@ void Metadata::addCustomIcon(const QUuid& uuid, const QImage& icon) Q_ASSERT(!uuid.isNull()); Q_ASSERT(!m_customIcons.contains(uuid)); - m_customIcons.insert(uuid, icon); + m_customIcons[uuid] = icon; // reset cache in case there is also an icon with that uuid m_customIconCacheKeys[uuid] = QPixmapCache::Key(); m_customIconScaledCacheKeys[uuid] = QPixmapCache::Key(); + // remove all uuids to prevent duplicates in release mode + m_customIconsOrder.removeAll(uuid); m_customIconsOrder.append(uuid); // Associate image hash to uuid QByteArray hash = hashImage(icon); diff --git a/src/keeshare/ShareObserver.cpp b/src/keeshare/ShareObserver.cpp index 295883ab8..33f5ed1f6 100644 --- a/src/keeshare/ShareObserver.cpp +++ b/src/keeshare/ShareObserver.cpp @@ -592,7 +592,8 @@ Database* ShareObserver::exportIntoContainer(const KeeShareSettings::Reference& { const auto* sourceDb = sourceRoot->database(); auto* targetDb = new Database(); - targetDb->metadata()->setRecycleBinEnabled(false); + auto* targetMetadata = targetDb->metadata(); + targetMetadata->setRecycleBinEnabled(false); auto key = QSharedPointer::create(); key->addKey(QSharedPointer::create(reference.password)); @@ -610,8 +611,8 @@ Database* ShareObserver::exportIntoContainer(const KeeShareSettings::Reference& targetEntry->setGroup(targetRoot); targetEntry->setUpdateTimeinfo(updateTimeinfo); const auto iconUuid = targetEntry->iconUuid(); - if (!iconUuid.isNull()) { - targetDb->metadata()->addCustomIcon(iconUuid, sourceEntry->icon()); + if (!iconUuid.isNull() && !targetMetadata->containsCustomIcon(iconUuid)) { + targetMetadata->addCustomIcon(iconUuid, sourceEntry->icon()); } } diff --git a/tests/TestMerge.cpp b/tests/TestMerge.cpp index a09eb32e6..03eae32ef 100644 --- a/tests/TestMerge.cpp +++ b/tests/TestMerge.cpp @@ -1127,6 +1127,34 @@ void TestMerge::testMergeCustomIcons() QVERIFY(dbDestination->metadata()->containsCustomIcon(customIconId)); } +/** + * No duplicate icons should be created + */ +void TestMerge::testMergeDuplicateCustomIcons() +{ + QScopedPointer dbDestination(new Database()); + QScopedPointer dbSource(createTestDatabase()); + + m_clock->advanceSecond(1); + + QUuid customIconId = QUuid::createUuid(); + QImage customIcon; + + dbSource->metadata()->addCustomIcon(customIconId, customIcon); + dbDestination->metadata()->addCustomIcon(customIconId, customIcon); + // Sanity check. + QVERIFY(dbSource->metadata()->containsCustomIcon(customIconId)); + QVERIFY(dbDestination->metadata()->containsCustomIcon(customIconId)); + + m_clock->advanceSecond(1); + + Merger merger(dbSource.data(), dbDestination.data()); + merger.merge(); + + QVERIFY(dbDestination->metadata()->containsCustomIcon(customIconId)); + QCOMPARE(dbDestination->metadata()->customIcons().count(), 1); +} + void TestMerge::testMetadata() { QSKIP("Sophisticated merging for Metadata not implemented"); diff --git a/tests/TestMerge.h b/tests/TestMerge.h index 159256f2b..357f85262 100644 --- a/tests/TestMerge.h +++ b/tests/TestMerge.h @@ -57,6 +57,7 @@ private slots: void testUpdateGroupLocation(); void testMergeAndSync(); void testMergeCustomIcons(); + void testMergeDuplicateCustomIcons(); void testMetadata(); void testDeletedEntry(); void testDeletedGroup(); -- cgit v1.2.3 From fbba5b14206ff4782f70fc0ce91df95508459626 Mon Sep 17 00:00:00 2001 From: Weslly Date: Fri, 12 Apr 2019 06:57:09 -0300 Subject: Fix conditional build flags for yubikey and keeshare --- src/gui/DatabaseWidget.cpp | 2 -- src/gui/DatabaseWidget.h | 2 -- src/gui/dbsettings/DatabaseSettingsWidgetMasterKey.cpp | 2 ++ 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp index 97fdeb0f9..8cfc40815 100644 --- a/src/gui/DatabaseWidget.cpp +++ b/src/gui/DatabaseWidget.cpp @@ -78,9 +78,7 @@ DatabaseWidget::DatabaseWidget(QSharedPointer db, QWidget* parent) , m_previewView(new EntryPreviewWidget(this)) , m_previewSplitter(new QSplitter(m_mainWidget)) , m_searchingLabel(new QLabel(this)) -#ifdef WITH_XC_KEESHARE , m_shareLabel(new QLabel(this)) -#endif , m_csvImportWizard(new CsvImportWizard(this)) , m_editEntryWidget(new EditEntryWidget(this)) , m_editGroupWidget(new EditGroupWidget(this)) diff --git a/src/gui/DatabaseWidget.h b/src/gui/DatabaseWidget.h index 11b2f710c..fb9cf817e 100644 --- a/src/gui/DatabaseWidget.h +++ b/src/gui/DatabaseWidget.h @@ -235,9 +235,7 @@ private: QPointer m_previewView; QPointer m_previewSplitter; QPointer m_searchingLabel; -#ifdef WITH_XC_KEESHARE QPointer m_shareLabel; -#endif QPointer m_csvImportWizard; QPointer m_editEntryWidget; QPointer m_editGroupWidget; diff --git a/src/gui/dbsettings/DatabaseSettingsWidgetMasterKey.cpp b/src/gui/dbsettings/DatabaseSettingsWidgetMasterKey.cpp index a8425aae1..ed22244c7 100644 --- a/src/gui/dbsettings/DatabaseSettingsWidgetMasterKey.cpp +++ b/src/gui/dbsettings/DatabaseSettingsWidgetMasterKey.cpp @@ -102,7 +102,9 @@ void DatabaseSettingsWidgetMasterKey::load(QSharedPointer db) connect(m_passwordEditWidget->findChild("removeButton"), SIGNAL(clicked()), SLOT(markDirty())); connect(m_keyFileEditWidget->findChild("removeButton"), SIGNAL(clicked()), SLOT(markDirty())); +#ifdef WITH_XC_YUBIKEY connect(m_yubiKeyEditWidget->findChild("removeButton"), SIGNAL(clicked()), SLOT(markDirty())); +#endif } void DatabaseSettingsWidgetMasterKey::initialize() -- cgit v1.2.3 From b97cc1d398bfb25c9ec74d0ae8b447088b81845f Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Fri, 12 Apr 2019 16:37:13 -0400 Subject: Reverse direction of CTRL+PGUP/PGDN * Conform to standard selection direction --- src/gui/MainWindow.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index bf8c6654e..077ee796e 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -253,9 +253,9 @@ MainWindow::MainWindow() new QShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_M, this, SLOT(hideWindow())); // Control database tabs new QShortcut(Qt::CTRL + Qt::Key_Tab, this, SLOT(selectNextDatabaseTab())); - new QShortcut(Qt::CTRL + Qt::Key_PageUp, this, SLOT(selectNextDatabaseTab())); + new QShortcut(Qt::CTRL + Qt::Key_PageDown, this, SLOT(selectNextDatabaseTab())); new QShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_Tab, this, SLOT(selectPreviousDatabaseTab())); - new QShortcut(Qt::CTRL + Qt::Key_PageDown, this, SLOT(selectPreviousDatabaseTab())); + new QShortcut(Qt::CTRL + Qt::Key_PageUp, this, SLOT(selectPreviousDatabaseTab())); // Toggle password and username visibility in entry view new QShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_C, this, SLOT(togglePasswordsHidden())); new QShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_B, this, SLOT(toggleUsernamesHidden())); -- cgit v1.2.3 From 0d4318e466bf994c9631938c5ff8a0c56a1d804e Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Fri, 12 Apr 2019 18:04:45 -0400 Subject: Version bump to 2.4.1 --- CHANGELOG | 29 +++++++++++++++++++++++ CMakeLists.txt | 2 +- share/linux/org.keepassxc.KeePassXC.appdata.xml | 31 +++++++++++++++++++++++++ snapcraft.yaml | 2 +- 4 files changed, 62 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 4f9943abe..059fce8b3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,32 @@ +2.4.1 (2019-04-12) +========================= + +- Fix database deletion when using unsafe saves to a different file system [#2889] +- Fix opening databases with legacy key files that contain '/' [#2872] +- Fix opening database files from the command line [#2919] +- Fix crash when editing master key [#2836] +- Fix multiple issues with apply button behavior [#2947] +- Fix issues on application startup (tab order, --pw-stdin, etc.) [#2830] +- Fix building without WITH_XC_KEESHARE +- Fix reference entry coloring on macOS dark mode [#2984] +- Hide window when performing entry auto-type on macOS [#2969] +- Improve UX of update checker; reduce checks to every 7 days [#2968] +- KeeShare improvements [#2946, #2978, #2824] +- Re-enable Ctrl+C to copy password from search box [#2947] +- Add KeePassXC-Browser integration for Brave browser [#2933] +- SSH Agent: Re-Add keys on database unlock [#2982] +- SSH Agent: Only remove keys on app exit if they are removed on lock [#2985] +- CLI: Add --no-password option [#2708] +- CLI: Improve database extraction to XML [#2698] +- CLI: Don't call mandb on build [#2774] +- CLI: Add debug info [#2714] +- Improve support for Snap theming [#2832] +- Add support for building on Haiku OS [#2859] +- Ctrl+PgDn now goes to the next tab and Ctrl+PgUp to the previous +- Fix compiling on GCC 5 / Xenial [#2990] +- Add .gitrev output to tarball for third-party builds [#2970] +- Add WITH_XC_UPDATECHECK compile flag to toggle the update checker [#2968] + 2.4.0 (2019-03-19) ========================= diff --git a/CMakeLists.txt b/CMakeLists.txt index 536b08d9d..16d574f01 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -83,7 +83,7 @@ endif() set(KEEPASSXC_VERSION_MAJOR "2") set(KEEPASSXC_VERSION_MINOR "4") -set(KEEPASSXC_VERSION_PATCH "0") +set(KEEPASSXC_VERSION_PATCH "1") set(KEEPASSXC_VERSION "${KEEPASSXC_VERSION_MAJOR}.${KEEPASSXC_VERSION_MINOR}.${KEEPASSXC_VERSION_PATCH}") set(OVERRIDE_VERSION "" CACHE STRING "Override the KeePassXC Version for Snapshot builds") diff --git a/share/linux/org.keepassxc.KeePassXC.appdata.xml b/share/linux/org.keepassxc.KeePassXC.appdata.xml index 45480333c..5c616b69a 100644 --- a/share/linux/org.keepassxc.KeePassXC.appdata.xml +++ b/share/linux/org.keepassxc.KeePassXC.appdata.xml @@ -50,6 +50,37 @@ + + +
      +
    • Fix database deletion when using unsafe saves to a different file system [#2889]
    • +
    • Fix opening databases with legacy key files that contain '/' [#2872]
    • +
    • Fix opening database files from the command line [#2919]
    • +
    • Fix crash when editing master key [#2836]
    • +
    • Fix multiple issues with apply button behavior [#2947]
    • +
    • Fix issues on application startup (tab order, --pw-stdin, etc.) [#2830]
    • +
    • Fix building without WITH_XC_KEESHARE
    • +
    • Fix reference entry coloring on macOS dark mode [#2984]
    • +
    • Hide window when performing entry auto-type on macOS [#2969]
    • +
    • Improve UX of update checker; reduce checks to every 7 days [#2968]
    • +
    • KeeShare improvements [#2946, #2978, #2824]
    • +
    • Re-enable Ctrl+C to copy password from search box [#2947]
    • +
    • Add KeePassXC-Browser integration for Brave browser [#2933]
    • +
    • SSH Agent: Re-Add keys on database unlock [#2982]
    • +
    • SSH Agent: Only remove keys on app exit if they are removed on lock [#2985]
    • +
    • CLI: Add --no-password option [#2708]
    • +
    • CLI: Improve database extraction to XML [#2698]
    • +
    • CLI: Don't call mandb on build [#2774]
    • +
    • CLI: Add debug info [#2714]
    • +
    • Improve support for Snap theming [#2832]
    • +
    • Add support for building on Haiku OS [#2859]
    • +
    • Ctrl+PgDn now goes to the next tab and Ctrl+PgUp to the previous
    • +
    • Fix compiling on GCC 5 / Xenial [#2990]
    • +
    • Add .gitrev output to tarball for third-party builds [#2970]
    • +
    • Add WITH_XC_UPDATECHECK compile flag to enable/disable the update checker [#2968]
    • +
    +
    +
      diff --git a/snapcraft.yaml b/snapcraft.yaml index 6dd3ea2c1..fdeef7766 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -1,5 +1,5 @@ name: keepassxc -version: 2.4.0 +version: 2.4.1 grade: stable summary: Community-driven port of the Windows application “KeePass Password Safe” description: | -- cgit v1.2.3 From 5b007ece1409114f0935978b9d4e4dc0f3c47025 Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Fri, 12 Apr 2019 18:11:57 -0400 Subject: Update translations --- share/translations/keepassx_ca.ts | 58 +- share/translations/keepassx_cs.ts | 52 +- share/translations/keepassx_de.ts | 84 +-- share/translations/keepassx_en.ts | 308 +++++++--- share/translations/keepassx_es.ts | 78 +-- share/translations/keepassx_fi.ts | 51 +- share/translations/keepassx_fr.ts | 50 +- share/translations/keepassx_hu.ts | 65 ++- share/translations/keepassx_id.ts | 4 +- share/translations/keepassx_ja.ts | 42 +- share/translations/keepassx_ko.ts | 1053 ++++++++++++++++++---------------- share/translations/keepassx_nb.ts | 60 +- share/translations/keepassx_nl_NL.ts | 76 +-- share/translations/keepassx_pl.ts | 50 +- share/translations/keepassx_pt.ts | 48 +- share/translations/keepassx_pt_BR.ts | 98 ++-- share/translations/keepassx_pt_PT.ts | 72 +-- share/translations/keepassx_ru.ts | 64 ++- share/translations/keepassx_sk.ts | 655 +++++++++++---------- share/translations/keepassx_sv.ts | 77 +-- share/translations/keepassx_tr.ts | 211 +++---- share/translations/keepassx_uk.ts | 52 +- share/translations/keepassx_zh_CN.ts | 49 +- 23 files changed, 1800 insertions(+), 1557 deletions(-) diff --git a/share/translations/keepassx_ca.ts b/share/translations/keepassx_ca.ts index b6041417e..5cc02be24 100644 --- a/share/translations/keepassx_ca.ts +++ b/share/translations/keepassx_ca.ts @@ -104,7 +104,7 @@ Startup - + Inicialització Start only a single instance of KeePassXC @@ -128,7 +128,7 @@ File Management - + Gestió de fitxers Safely save database files (may be incompatible with Dropbox, etc) @@ -136,7 +136,7 @@ Backup database file before saving - + Fes una còpia de seguretat abans de desar Automatically save after every change @@ -156,7 +156,7 @@ Entry Management - + Gestió d'entrades Use group icon on entry creation @@ -168,7 +168,7 @@ Hide the entry preview panel - + Oculta el panell de previsualització d'entrades General @@ -176,7 +176,7 @@ Hide toolbar (icons) - + Oculta la barra d'eines (les icones) Minimize instead of app exit @@ -233,11 +233,11 @@ Check for updates at application startup - + Comprova si hi ha actualitzacions a l'inici Include pre-releases when checking for updates - + Inclou versions provisionals quan es comprovi si hi ha actualitzacions Movable toolbar @@ -245,7 +245,7 @@ Button style - + Estil de botó @@ -433,7 +433,7 @@ Seleccioneu si voleu permetre l'accés. Ok - + D'acord Cancel @@ -589,7 +589,7 @@ Please select the correct database for saving credentials. &Tor Browser - + Navegador &Tor <b>Warning</b>, the keepassxc-proxy application was not found!<br />Please check the KeePassXC installation directory or confirm the custom path in advanced options.<br />Browser integration WILL NOT WORK without the proxy application.<br />Expected Path: @@ -597,7 +597,7 @@ Please select the correct database for saving credentials. Executable Files - + Fitxers executables All Files @@ -3507,7 +3507,7 @@ We recommend you use the AppImage available on our downloads page. Check for Updates... - + Comprova si hi ha actualitzacions... Share entry @@ -3520,15 +3520,15 @@ Expect some bugs and minor issues, this version is not meant for production use. Check for updates on startup? - + Voleu comprovar si hi ha actualitzacions a l'inici? Would you like KeePassXC to check for updates on startup? - + Voleu que KeePassXC comprovi si hi ha actualitzacions a l'inici? You can always check for updates manually from the application menu. - + Sempre pots comprovar si hi ha actualitzacions manualment als menús de l'aplicació. @@ -5194,7 +5194,7 @@ Available commands: Export to %1 - + Exporta a %1 Do you want to trust %1 with the fingerprint of %2 from %3? @@ -5261,7 +5261,7 @@ Available commands: Closing in %1 seconds. - + Tancant en %1 segons. @@ -5288,7 +5288,7 @@ Available commands: Custom Settings - + Paràmetres a mida Time step: @@ -5309,7 +5309,7 @@ Available commands: 7 digits - + 7 dígits 8 digits @@ -5320,11 +5320,11 @@ Available commands: UpdateCheckDialog Checking for updates - + Comprovant si hi ha actualitzacions Checking for updates... - + Comprovant si hi ha actualitzacions... Close @@ -5332,7 +5332,7 @@ Available commands: Update Error! - + Error d'actualització! An error occurred in retrieving update information. @@ -5340,15 +5340,15 @@ Available commands: Please try again later. - + Si us plau, proveu-ho altre cop més tard. Software Update - + Actualització de programari A new version of KeePassXC is available! - + Hi ha disponible una nova versió de KeePassXC! KeePassXC %1 is now available — you have %2. @@ -5356,11 +5356,11 @@ Available commands: Download it at keepassxc.org - + Descarregueu-ho a keepassxc.org You're up-to-date! - + Esteu actualitzats! KeePassXC %1 is currently the newest version available @@ -5395,7 +5395,7 @@ Available commands: Welcome to KeePassXC %1 - + Benvinguts/des al KeePassXC %1 diff --git a/share/translations/keepassx_cs.ts b/share/translations/keepassx_cs.ts index 60ea7985a..98f5fcb0e 100644 --- a/share/translations/keepassx_cs.ts +++ b/share/translations/keepassx_cs.ts @@ -611,15 +611,15 @@ Vyberte databázi, do které chcete přihlašovací údaje uložit. Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1 - + Z důvodu, že software ze Snap balíčku je provozován v ohraničeném prostředí, je třeba spustit skript, který zapíná napojení na webový prohlížeč. <br />Tento skript je možné získat z %1 Please see special instructions for browser extension use below - + Níže si přečtěte konkrétní pokyny pro rozšíření do webového prohlížeče KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3 - + Aby fungovalo napojení na prohlížeč, je třeba KeePassXC. <br /> Stáhnete ho pro %1 a %2. %3 @@ -696,19 +696,23 @@ Přesunuto %2 klíčů do uživatelsky určených dat. KeePassXC: Create a new group - + KeePassXC: vytvořit novou skupinu A request for creating a new group "%1" has been received. Do you want to create this group? - + Byl obdržen požadavek na vytvoření nové skupiny „%1“. +Chcete tuto skupinu vytvořit? + Your KeePassXC-Browser settings need to be moved into the database settings. This is necessary to maintain your current browser connections. Would you like to migrate your existing settings now? - + Vaše nastavení KeePassXC-Browser je třeba přesunout do nastavení databáze. +Toto je nezbytné pro zachování vašich stávajících spojení prohlížeče. +Chcete přenést vaše stávající nastavení nyní? @@ -872,7 +876,7 @@ Would you like to migrate your existing settings now? Key not transformed. This is a bug, please report it to the developers! - + Klíč nebyl přeměněn. Toto je chyba, nahlaste to vývojářům. @@ -1630,7 +1634,7 @@ Vypnout bezpečné ukládání a zkusit to znovu? Shared group... - + Sdílená skupina… @@ -2075,15 +2079,15 @@ Vypnout bezpečné ukládání a zkusit to znovu? The export container %1 is already referenced. - + Exportní kontejner %1 už je odkazován. The import container %1 is already imported. - + Importní kontejner %1 už byl naimportován. The container %1 imported and export by different groups. - + Kontejner %1 naimportován a exportován různými skupinami. @@ -3156,19 +3160,19 @@ Line %2, column %3 Disabled share %1 - + Sdílení %1 vypnuto Import from share %1 - + Importovat ze sdílení %1 Export to share %1 - + Exportovat do sdílení %1 Synchronize with share %1 - + Synchronizovat se sdílením %1 @@ -4053,7 +4057,7 @@ Očekávejte chyby a drobné problémy, tato verze není určena pro produkční Regenerate - Regenerovat + Vytvoř nové @@ -4856,7 +4860,7 @@ Příkazy k dispozici: Cannot create new group - + Novou skupinu se nedaří vytvořit @@ -5132,7 +5136,7 @@ Příkazy k dispozici: Signer: - + Podepsal(a): @@ -5255,27 +5259,27 @@ Příkazy k dispozici: Multiple import source path to %1 in %2 - + Popis umístění zdroje pro vícero importů do %1 v %2 Conflicting export target path %1 in %2 - + Kolidující popis umístění %1 cíle exportu v %2 Could not embed signature: Could not open file to write (%1) - + Nedaří se zapouzdřit podpis: Soubor se nedaří otevřít pro zápis (%1) Could not embed signature: Could not write file (%1) - + Nedaří se zapouzdřit podpis: Do souboru se nedaří zapsat (%1) Could not embed database: Could not open file to write (%1) - + Nedaří se zapouzdřit databázi: Soubor se nedaří otevřít pro zápis (%1) Could not embed database: Could not write file (%1) - + Nedaří se zapouzdřit databázi: Do souboru se nedaří zapsat (%1) diff --git a/share/translations/keepassx_de.ts b/share/translations/keepassx_de.ts index 89b9f0b6e..954a16a2e 100644 --- a/share/translations/keepassx_de.ts +++ b/share/translations/keepassx_de.ts @@ -192,7 +192,7 @@ Hide window to system tray when minimized - Fenster verstecken wenn minimiert + Fenster verstecken, wenn minimiert Language @@ -293,11 +293,11 @@ Re-lock previously locked database after performing Auto-Type - Datenbank nach Auto-Type automatisch wieder sperren. + Datenbank nach Auto-Type automatisch wieder sperren Don't require password repeat when it is visible - Keine erneute Passworteingabe verlangen, wenn das Passwort sichtbar ist. + Keine erneute Passworteingabe verlangen, wenn das Passwort sichtbar ist Don't hide passwords when editing them @@ -313,7 +313,7 @@ Hide entry notes by default - Eintrags-Notizen standardmäßig verstecken + Eintragsnotizen standardmäßig verstecken Privacy @@ -443,7 +443,7 @@ Bitte wählen Sie, ob Sie den Zugriff erlauben möchten. You have multiple databases open. Please select the correct database for saving credentials. Du hast mehrere Datenbanken geöffnet. -Bitte wähle die richtige Datenbank zum speichern der Anmeldedaten. +Bitte wähle die richtige Datenbank zum Speichern der Anmeldedaten. @@ -594,7 +594,7 @@ Bitte wähle die richtige Datenbank zum speichern der Anmeldedaten. <b>Warning</b>, the keepassxc-proxy application was not found!<br />Please check the KeePassXC installation directory or confirm the custom path in advanced options.<br />Browser integration WILL NOT WORK without the proxy application.<br />Expected Path: - <b>Achtung</b>, die keepassxc-proxy Anwendung wurde nicht gefunden!<br />Bitte überprüfe den KeePassXC-Ordner oder bestätige den benutzerdefinierten Ort in den erweiterten Einstellungen.<br />Die Browseranbindung wird nicht funktionieren, wenn das Proxyprogramm nicht eingebunden ist.<br />Vermuteter Pfad: + <b>Achtung</b>, die KeePassXC-Proxy Anwendung wurde nicht gefunden!<br />Bitte überprüfen Sie den KeePassXC-Ordner oder bestätigen Sie den benutzerdefinierten Ort in den erweiterten Einstellungen.<br />Die Browseranbindung wird nicht funktionieren, wenn das Proxyprogramm nicht eingebunden ist.<br />Vermuteter Pfad: Executable Files @@ -607,19 +607,19 @@ Bitte wähle die richtige Datenbank zum speichern der Anmeldedaten. Do not ask permission for HTTP &Basic Auth An extra HTTP Basic Auth setting - Nicht nach HTTP Basic Auth fragen + Niemals fragen, bevor für "HTTP Basic Auth" auf Anmeldedaten zugegriffen wird Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1 - + Aufgrund von Snap Sandboxing müssen Sie ein Skript ausführen, um die Browser-Integration zu aktivieren.<br />Sie können dieses Skript erhalten unter %1 Please see special instructions for browser extension use below - + Bitte beachten Sie die untenstehenden speziellen Anweisungen für die Verwendung der Browser-Erweiterung KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3 - + KeePassXC-Browser wird für die Funktion der Browserintegration benötigt. <br />Laden Sie es für %1 und %2. %3 herunter. @@ -670,7 +670,7 @@ Möchten Sie diesen überschreiben? KeePassXC: Converted KeePassHTTP attributes - KeepassXC: KeePassHTTP-Attribute wurden umgewandelt + KeePassXC: KeePassHTTP-Attribute wurden umgewandelt Successfully converted attributes from %1 entry(s). @@ -696,19 +696,23 @@ Moved %2 keys to custom data. KeePassXC: Create a new group - + KeePassXC: Neue Gruppe erstellen A request for creating a new group "%1" has been received. Do you want to create this group? - + Eine Anfrage zur Erstellung einer neuen Gruppe "%1" ist eingegangen. +Möchten Sie diese Gruppe erstellen? + Your KeePassXC-Browser settings need to be moved into the database settings. This is necessary to maintain your current browser connections. Would you like to migrate your existing settings now? - + Ihre KeePassXC-Browser-Einstellungen müssen in die Datenbankeinstellungen verschoben werden. +Dies ist notwendig, um Ihre aktuellen Browserverbindungen aufrechtzuerhalten. +Möchten Sie Ihre bestehenden Einstellungen jetzt migrieren? @@ -871,7 +875,7 @@ Would you like to migrate your existing settings now? Key not transformed. This is a bug, please report it to the developers! - + Schlüssel nicht umgewandelt. Dies ist ein Fehler, bitte melden Sie ihn den Entwicklern! @@ -1630,7 +1634,7 @@ Sicheres Speichern deaktivieren und erneut versuchen? Shared group... - + Gemeinsame Gruppe... @@ -2075,15 +2079,15 @@ Sicheres Speichern deaktivieren und erneut versuchen? The export container %1 is already referenced. - + Der Exportcontainer %1 wird bereits referenziert. The import container %1 is already imported. - + Der Importcontainer %1 ist bereits importiert. The container %1 imported and export by different groups. - + Der Container %1 wird von unterschiedlichen Gruppen importiert und exportiert. @@ -3154,19 +3158,19 @@ Zeile %2, Spalte %3 Disabled share %1 - + Freigabe %1 deaktiviert Import from share %1 - + Von Freigabe %1 importieren Export to share %1 - + Zu Freigabe %1 exportieren Synchronize with share %1 - + Mit Freigabe %1 synchronisieren @@ -3447,8 +3451,8 @@ Diese Version ist nicht für den Produktiveinsatz gedacht. WARNING: Your Qt version may cause KeePassXC to crash with an On-Screen Keyboard! We recommend you use the AppImage available on our downloads page. - WARNUNG: Deine Qt Version könnte KeePassXC mit einer Bildschirmtastatur zu abstürzen bringen! -Wir empfehlen dir die Verwendung des auf unserer Downloadseite verfügbaren AppImage. + WARNUNG: Deine Qt-Version könnte KeePassXC mit einer Bildschirmtastatur zu abstürzen bringen! +Wir empfehlen die Verwendung des verfügbaren App-Images auf unserer Downloadseite. &Import @@ -3815,7 +3819,7 @@ Da sie Fehler beinhalten könnte, ist diese Version nicht für den Produktiveins <p>A password is the primary method for securing your database.</p><p>Good passwords are long and unique. KeePassXC can generate one for you.</p> - <p>Ein Passwort ist die primäre Methode, Ihre Datenbank abzusichern.</p><p>Gute Passwörter sind lang und einzigartig. KeepassXC kann eins für Sie generieren.</p> + <p>Ein Passwort ist die primäre Methode, Ihre Datenbank abzusichern.</p><p>Gute Passwörter sind lang und einzigartig. KeePassXC kann eins für Sie generieren.</p> Passwords do not match. @@ -4854,7 +4858,7 @@ Verfügbare Kommandos: Cannot create new group - + Neue Gruppe kann nicht erstellt werden @@ -5130,7 +5134,7 @@ Verfügbare Kommandos: Signer: - + Unterzeichner: @@ -5177,7 +5181,7 @@ Verfügbare Kommandos: Signed share container are not supported - import prevented - Unterzeichnete geteilte Container werden nicht unterstützt. Import verhindert. + Unterzeichnete geteilte Container werden nicht unterstützt - Import verhindert File is not readable @@ -5201,7 +5205,7 @@ Verfügbare Kommandos: Unsigned share container are not supported - import prevented - Nicht unterzeichnete geteilte Container werden nicht unterstützt. Import verhindert. + Nicht unterzeichnete geteilte Container werden nicht unterstützt - Import verhindert Successful unsigned import @@ -5213,11 +5217,11 @@ Verfügbare Kommandos: Unknown share container type - Unbekannter geteilter Container-Typ + Unbekannter geteilter Containertyp Overwriting signed share container is not supported - export prevented - Überschreiben von unterzeichneten geteilten Containern nicht unterstützt. Export verhindert. + Überschreiben von unterzeichneten geteilten Containern nicht unterstützt - Export verhindert Could not write export container (%1) @@ -5225,7 +5229,7 @@ Verfügbare Kommandos: Overwriting unsigned share container is not supported - export prevented - Überschreiben von nicht unterzeichneten geteilten Containern nicht unterstützt. Export verhindert. + Überschreiben von nicht unterzeichneten geteilten Containern nicht unterstützt - Export verhindert Could not write export container @@ -5253,27 +5257,27 @@ Verfügbare Kommandos: Multiple import source path to %1 in %2 - + Multipler Import-Quellpfad zu %1 in %2 Conflicting export target path %1 in %2 - + Konflikt beim Export-Zielpfad %1 in %2 Could not embed signature: Could not open file to write (%1) - + Signatur konnte nicht eingebunden werden: Zum Schreiben konnte die Datei (%1) nicht geöffnet werden Could not embed signature: Could not write file (%1) - + Signatur konnte nicht eingebunden werden: Datei konnte nicht geschrieben werden (%1) Could not embed database: Could not open file to write (%1) - + Datenbank konnte nicht eingebunden werden: Zum Schreiben konnte die Datei (%1) nicht geöffnet werden Could not embed database: Could not write file (%1) - + Datenbank konnte nicht eingebunden werden: Datei konnte nicht geschrieben werden (%1) @@ -5411,7 +5415,7 @@ Verfügbare Kommandos: You're up-to-date! - Version aktuel + Version aktuell KeePassXC %1 is currently the newest version available diff --git a/share/translations/keepassx_en.ts b/share/translations/keepassx_en.ts index 1f6b00076..f49602bb5 100644 --- a/share/translations/keepassx_en.ts +++ b/share/translations/keepassx_en.ts @@ -112,18 +112,6 @@ Start only a single instance of KeePassXC Start only a single instance of KeePassXC - - Remember last databases - Remember last databases - - - Remember last key files and security dongles - Remember last key files and security dongles - - - Load previous databases on startup - Load previous databases on startup - Minimize window at application startup Minimize window at application startup @@ -196,10 +184,6 @@ Hide window to system tray when minimized Hide window to system tray when minimized - - Language - Language - Auto-Type Auto-Type @@ -234,20 +218,40 @@ Auto-Type start delay - Check for updates at application startup - Check for updates at application startup + Movable toolbar + Movable toolbar - Include pre-releases when checking for updates - Include pre-releases when checking for updates + Remember previously used databases + - Movable toolbar - Movable toolbar + Load previously open databases on startup + + + + Remember database key files and security dongles + + + + Check for updates at application startup once per week + + + + Include beta releases when checking for updates + - Button style - Button style + Button style: + + + + Language: + + + + (restart program to activate) + @@ -623,6 +627,10 @@ Please select the correct database for saving credentials. KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3 + + &Brave + + BrowserService @@ -891,6 +899,11 @@ Would you like to migrate your existing settings now? Key not transformed. This is a bug, please report it to the developers! + + %1 +Backup database located at %2 + + DatabaseOpenDialog @@ -960,16 +973,12 @@ Please consider generating a new key file. TouchID for quick unlock - Unable to open the database: -%1 - Unable to open the database: -%1 + Failed to open key file: %1 + - Can't open key file: -%1 - Can't open key file: -%1 + Select slot... + @@ -1458,10 +1467,6 @@ This is definitely a bug, please report it to the developers. The created database has no key or KDF, refusing to save it. This is definitely a bug, please report it to the developers. - - The database file does not exist or is not accessible. - The database file does not exist or is not accessible. - Select CSV file Select CSV file @@ -1485,6 +1490,10 @@ This is definitely a bug, please report it to the developers. Database tab name modifier %1 [Read-only] + + Failed to open %1. It either does not exist or is not accessible. + + DatabaseWidget @@ -1629,12 +1638,6 @@ Error: %1 Disable safe saves and try again? KeePassXC has failed to save the database multiple times. This is likely caused by file sync services holding a lock on the save file. Disable safe saves and try again? - - - Writing the database failed. -%1 - Writing the database failed. -%1 Passwords @@ -1683,6 +1686,10 @@ Disable safe saves and try again? Shared group... + + Writing the database failed: %1 + Writing the database failed: %1 + EditEntryWidget @@ -1885,6 +1892,14 @@ Disable safe saves and try again? Use a specific sequence for this association: Use a specific sequence for this association: + + Open AutoType help webpage + + + + AutoType help button + + EditEntryWidgetHistory @@ -2054,6 +2069,10 @@ Disable safe saves and try again? Inherit from parent group (%1) Inherit from parent group (%1) + + Entry has unsaved changes + Entry has unsaved changes + EditGroupWidgetKeeShare @@ -2082,67 +2101,69 @@ Disable safe saves and try again? Inactive - Import from path - Import from path + KeeShare unsigned container + KeeShare unsigned container - Export to path - Export to path + KeeShare signed container + KeeShare signed container - Synchronize with path - Synchronize with path + Select import source + Select import source - Your KeePassXC version does not support sharing your container type. Please use %1. - Your KeePassXC version does not support sharing your container type. Please use %1. + Select export target + Select export target - Database sharing is disabled - Database sharing is disabled + Select import/export file + Select import/export file - Database export is disabled - Database export is disabled + Clear + Clear - Database import is disabled - Database import is disabled + Import + Import - KeeShare unsigned container - KeeShare unsigned container + Export + Export - KeeShare signed container - KeeShare signed container + Synchronize + - Select import source - Select import source + Your KeePassXC version does not support sharing this container type. +Supported extensions are: %1. + - Select export target - Select export target + %1 is already being exported by this database. + - Select import/export file - Select import/export file + %1 is already being imported by this database. + - Clear - Clear + %1 is being imported and exported by different groups in this database. + - The export container %1 is already referenced. + KeeShare is currently disabled. You can enable import/export in the application settings. + KeeShare is a proper noun - The import container %1 is already imported. + Database export is currently disabled by application settings. - The container %1 imported and export by different groups. + Database import is currently disabled by application settings. @@ -2668,10 +2689,6 @@ This may cause the affected plugins to malfunction. Unable to issue challenge-response. Unable to issue challenge-response. - - Wrong key or database file is corrupt. - Wrong key or database file is corrupt. - missing database headers missing database headers @@ -2692,6 +2709,11 @@ This may cause the affected plugins to malfunction. Invalid header data length Invalid header data length + + Invalid credentials were provided, please try again. +If this reoccurs, then your database file may be corrupt. + + Kdbx3Writer @@ -2722,10 +2744,6 @@ This may cause the affected plugins to malfunction. Header SHA256 mismatch Header SHA256 mismatch - - Wrong key or database file is corrupt. (HMAC mismatch) - Wrong key or database file is corrupt. (HMAC mismatch) - Unknown cipher Unknown cipher @@ -2826,6 +2844,15 @@ This may cause the affected plugins to malfunction. Translation: variant map = data structure for storing meta data Invalid variant map field type size + + Invalid credentials were provided, please try again. +If this reoccurs, then your database file may be corrupt. + + + + (HMAC mismatch) + + Kdbx4Writer @@ -3111,10 +3138,6 @@ Line %2, column %3 Unable to calculate master key Unable to calculate master key - - Wrong key or database file is corrupt. - Wrong key or database file is corrupt. - Key transformation failed Key transformation failed @@ -3211,39 +3234,56 @@ Line %2, column %3 unable to seek to content position unable to seek to content position + + Invalid credentials were provided, please try again. +If this reoccurs, then your database file may be corrupt. + + KeeShare - Disabled share - Disabled share + Invalid sharing reference + + + + Inactive share %1 + + + + Imported from %1 + Imported from %1 + + + Exported to %1 + - Import from - Import from + Synchronized with %1 + - Export to - Export to + Import is disabled in settings + - Synchronize with - Synchronize with + Export is disabled in settings + - Disabled share %1 + Inactive share - Import from share %1 + Imported from - Export to share %1 + Exported to - Synchronize with share %1 + Synchronized with @@ -4939,6 +4979,84 @@ Available commands: Cannot create new group + + Deactivate password key for the database. + + + + Displays debugging information. + + + + Deactivate password key for the database to merge from. + + + + Version %1 + + + + Build Type: %1 + + + + Revision: %1 + + + + Distribution: %1 + + + + Debugging mode is disabled. + + + + Debugging mode is enabled. + + + + Operating system: %1 +CPU architecture: %2 +Kernel: %3 %4 + + + + Auto-Type + Auto-Type + + + KeeShare (signed and unsigned sharing) + + + + KeeShare (only signed sharing) + + + + KeeShare (only unsigned sharing) + + + + YubiKey + + + + TouchID + + + + None + + + + Enabled extensions: + + + + Cryptographic libraries: + + QtIOCompressor diff --git a/share/translations/keepassx_es.ts b/share/translations/keepassx_es.ts index 99d394ff9..4615ba30e 100644 --- a/share/translations/keepassx_es.ts +++ b/share/translations/keepassx_es.ts @@ -50,7 +50,7 @@ AgentSettingsWidget Enable SSH Agent (requires restart) - Habilitar el Agente SSH (requiere reinicio) + Habilitar el Agente de SSH (requiere reinicio) Use OpenSSH for Windows instead of Pageant @@ -184,7 +184,7 @@ Show a system tray icon - Mostrar icono en la bandeja de del sistema + Mostrar icono en la bandeja del sistema Dark system tray icon @@ -204,11 +204,11 @@ Use entry title to match windows for global Auto-Type - Use título de entrada para acertar ventanas en Auto-Tipeado global. + Use título de entrada para acertar ventanas en Auto-Escritura global. Use entry URL to match windows for global Auto-Type - Use URL para acertar ventanas en Auto-Tipedo global + Use URL para acertar ventanas en Auto-Escritura global Always ask before performing Auto-Type @@ -340,7 +340,7 @@ The Syntax of your Auto-Type statement is incorrect! - ¡La sintaxis de la declaración de su auto-escritura es incorrecta! + ¡La sintaxis de la declaración de su Auto-Escritura es incorrecta! This Auto-Type command contains a very long delay. Do you really want to proceed? @@ -404,7 +404,7 @@ BrowserAccessControlDialog KeePassXC-Browser Confirm Access - KeePassXC-Navegador Confirmar Acceso + KeePassXC-Browser Confirmar Acceso Remember this decision @@ -454,7 +454,7 @@ Por favor, seleccione la base de datos correcta para guardar las credenciales. This is required for accessing your databases with KeePassXC-Browser - Esto es necesario para acceder a las bases de datos con KeePassXC-Navegador + Esto es necesario para acceder a las bases de datos con KeePassXC-Browser Enable KeepassXC browser integration @@ -611,15 +611,15 @@ Por favor, seleccione la base de datos correcta para guardar las credenciales. Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1 - + Debido al modo aislado de Snap, debes ejecutar un código para permitir la integración con el navegador.<br/>Puedes obtener este código desde %1 Please see special instructions for browser extension use below - + Por favor ve las instrucciones especiales para el uso de extensiones del navegador debajo. KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3 - + KeePassXC-Browser es necesario para que la integración con el navegador funcione. <br />Descárguelo para %1 y %2. %3 @@ -697,19 +697,23 @@ Movió %2 claves a datos personalizados. KeePassXC: Create a new group - + KeePassXC: Crear un grupo nuevo A request for creating a new group "%1" has been received. Do you want to create this group? - + Una solicitud para crear un nuevo grupo "%1" se ha recibido. +¿Quiere crear este grupo? + Your KeePassXC-Browser settings need to be moved into the database settings. This is necessary to maintain your current browser connections. Would you like to migrate your existing settings now? - + Sus configuraciones de KeePassXC-Browser necesitan moverse a las configuraciones de base de datos. +Es necesario para mantener sus conexiones presentes del navegador. +¿Le gustaría migrar sus configuraciones existentes ahora? @@ -873,7 +877,7 @@ Would you like to migrate your existing settings now? Key not transformed. This is a bug, please report it to the developers! - + Llave no está transformada. Esto es un bug, por favor, ¡informe sobre él a los desarrolladores! @@ -1006,7 +1010,7 @@ Considere generar un nuevo archivo llave. Move KeePassHTTP attributes to KeePassXC-Browser &custom data - Mueva los atributos de KeePassHTTP a los datos &personalizados de KeePassXC-Browser + Mover los atributos de KeePassHTTP a los datos &personalizados de KeePassXC-Browser Stored keys @@ -1631,7 +1635,7 @@ Disable safe saves and try again? Shared group... - + Grupo compartido... @@ -2076,15 +2080,15 @@ Disable safe saves and try again? The export container %1 is already referenced. - + El contenedor de exportación %1 ya es referenciado. The import container %1 is already imported. - + El contenedor de importación %1 ya es importado. The container %1 imported and export by different groups. - + El contenedor %1 se importa y se exporta por grupos diferentes. @@ -2928,7 +2932,7 @@ Esta migración es en único sentido. No podrá abrir la base de datos importada Auto-type association window or sequence missing - Falta de secuencia o ventana de Asociación de auto-tipeado + Falta de secuencia o ventana de asociación de Auto-Escritura Invalid bool value @@ -3155,19 +3159,19 @@ Linea %2, columna %3 Disabled share %1 - + Deshabilitada cuota %1 Import from share %1 - + Importar de cuota %1 Export to share %1 - + Exportar a cuota %1 Synchronize with share %1 - + Sincronizar con cuota %1 @@ -3518,7 +3522,7 @@ Le recomendamos que utilice la AppImage disponible en nuestra página de descarg Perform &Auto-Type - Relizar &Auto-Escritura + Realizar &Auto-Escritura Open &URL @@ -4205,7 +4209,7 @@ Espere algunos errores y problemas menores, esta versión no está destinada par Path of the entry to add. - Camino de la entrada para añadir. + Ruta de la entrada para añadir. Copy an entry's password to the clipboard. @@ -4214,7 +4218,7 @@ Espere algunos errores y problemas menores, esta versión no está destinada par Path of the entry to clip. clip = copy to clipboard - Camino de la entrada para copiar. + Ruta de la entrada para copiar. Timeout in seconds before clearing the clipboard. @@ -4234,7 +4238,7 @@ Espere algunos errores y problemas menores, esta versión no está destinada par Path of the entry to edit. - Camino de la entrada para editar. + Ruta de la entrada para editar. Estimate the entropy of a password. @@ -4805,7 +4809,7 @@ Comandos disponibles: Path of the entry to remove. - Camino de la entrada a quitar. + Ruta de la entrada a quitar. Existing single-instance lock file is invalid. Launching new instance. @@ -4857,7 +4861,7 @@ Comandos disponibles: Cannot create new group - + No se puede crear el nuevo grupo @@ -5133,7 +5137,7 @@ Comandos disponibles: Signer: - + Firmante: @@ -5256,27 +5260,27 @@ Comandos disponibles: Multiple import source path to %1 in %2 - + Ruta de origen de importación múltiple a %1 en %2 Conflicting export target path %1 in %2 - + Ruta de destino de exportación contradictoria %1 en %2 Could not embed signature: Could not open file to write (%1) - + No se puede incrustar la firma: no se puede abrir el archivo para escribir (%1) Could not embed signature: Could not write file (%1) - + No se puede incrustar la firma: no se puede escribir el archivo (%1) Could not embed database: Could not open file to write (%1) - + No se puede incrustar la base de datos: no se puede abrir el archivo para escribir (%1) Could not embed database: Could not write file (%1) - + No se puede incrustar la base de datos: no se puede escribir el archivo (%1) diff --git a/share/translations/keepassx_fi.ts b/share/translations/keepassx_fi.ts index de8237ea5..e70665f90 100644 --- a/share/translations/keepassx_fi.ts +++ b/share/translations/keepassx_fi.ts @@ -611,15 +611,15 @@ Valitse oikea tietokanta tietueen tallentamiseksi Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1 - + Snap:in hiekkalaatikon takia sinun täytyy suorittaa komentosarja jotta voit aktivoida selainintegraation.<br />Voit ladata komentosarjan osoitteesta %1 Please see special instructions for browser extension use below - + Katso yksityiskohtaisemmat ohjeet selainlaajennuksen käyttöön alta KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3 - + KeePassXC-Browser tarvitaan selainintegraation toimimista varten.<br />Dataa se seuraaville selaimille: %1 ja %2. %3 @@ -695,19 +695,22 @@ Siirrettiin %2 avainta mukautettuihin tietoihin. KeePassXC: Create a new group - + KeePassXC: Luo uusi ryhmä A request for creating a new group "%1" has been received. Do you want to create this group? - + Vastaanotettiin pyyntö luoda uusi ryhmä "%1". +Haluatko varmasti luoda tämän ryhmän? Your KeePassXC-Browser settings need to be moved into the database settings. This is necessary to maintain your current browser connections. Would you like to migrate your existing settings now? - + KeePassXC-Browser:in asetukset täytyy siirtää tietokannan asetuksiin. +Tämä on välttämätöntä, jotta yhteys selainlaajennukseen säilyy muuttumattomana. +Haluat siirtää asetukset nyt? @@ -871,7 +874,7 @@ Would you like to migrate your existing settings now? Key not transformed. This is a bug, please report it to the developers! - + Avainmuunnosta ei voitu suorittaa. Ole hyvä ja ilmoita tästä virheestä sovelluksen kehittäjille. @@ -1630,7 +1633,7 @@ Ota turvallinen tallennus pois käytöstä ja yritä uudelleen? Shared group... - + Jaettu ryhmä... @@ -2075,15 +2078,15 @@ Ota turvallinen tallennus pois käytöstä ja yritä uudelleen? The export container %1 is already referenced. - + Vientisäiliöön %1 on jo viitattu. The import container %1 is already imported. - + Tuontisäiliö %1 on jo tuotu. The container %1 imported and export by different groups. - + Säiliö %1 on tuotu ja viety eri ryhmien perusteella. @@ -3154,19 +3157,19 @@ Rivi %2, sarake %3 Disabled share %1 - + Jako %1 otettu pois käytöstä Import from share %1 - + Tuo jaosta %1 Export to share %1 - + Vie jaosta %1 Synchronize with share %1 - + Synkronoi jaon %1 kanssa @@ -4855,7 +4858,7 @@ Käytettävissä olevat komennot: Cannot create new group - + Uutta ryhmää ei voitu luoda @@ -5131,7 +5134,7 @@ Käytettävissä olevat komennot: Signer: - + Allekirjoittaja: @@ -5250,31 +5253,31 @@ Käytettävissä olevat komennot: Do you want to trust %1 with the fingerprint of %2 from %3? - + Haluatko luottaa kohteeseen %1 sormenjäljellä %2, joka on peräisin kohteesta %3? {1 ?} {2 ?} Multiple import source path to %1 in %2 - + Useampi lähde kohteeseen %1 tuonnissa %2 Conflicting export target path %1 in %2 - + Ristiriita viennin %2 kohdepolussa %1 Could not embed signature: Could not open file to write (%1) - + Allekirjoitusta ei voitu sisällyttää: Tiedostoa ei voitu avata kirjoitusta varten (%1) Could not embed signature: Could not write file (%1) - + Allekirjoitusta ei voitu sisällyttää: Tiedostoon kirjoitus epäonnistui (%1) Could not embed database: Could not open file to write (%1) - + Tietokantaa ei voitu sisällyttää: Tiedostoa ei voitu avata kirjoitusta varten (%1) Could not embed database: Could not write file (%1) - + Tietokantaa ei voitu sisällyttää: Tiedostoon kirjoitus epäonnistui (%1) diff --git a/share/translations/keepassx_fr.ts b/share/translations/keepassx_fr.ts index 8384e1462..bf305ac4b 100644 --- a/share/translations/keepassx_fr.ts +++ b/share/translations/keepassx_fr.ts @@ -615,11 +615,11 @@ Veuillez sélectionner la base de donnée souhaitée pour enregistrer les identi Please see special instructions for browser extension use below - + Veuillez regarder les instructions spéciales pour l'extension du navigateur utilisé ci-dessous KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3 - + KeePassXC-Browser est nécessaire pour que l'intégration au navigateur fonctionne. <br />Téléchargez-le pour %1 et%2. %3 @@ -696,13 +696,15 @@ Moved %2 keys to custom data. KeePassXC: Create a new group - + KeePassXC : Créer un nouveau groupe A request for creating a new group "%1" has been received. Do you want to create this group? - + Une demande de création pour un nouveau groupe "%1" a été reçue. +Voulez-vous créer ce groupe ? + Your KeePassXC-Browser settings need to be moved into the database settings. @@ -1628,7 +1630,7 @@ Désactiver les enregistrements sécurisés et ressayer ? Shared group... - + Groupe partagé ... @@ -2033,7 +2035,7 @@ Désactiver les enregistrements sécurisés et ressayer ? Your KeePassXC version does not support sharing your container type. Please use %1. - + Votre version de KeePassXC ne supporte pas le partage de ce type de conteneur. Veuillez utiliser %1. Database sharing is disabled @@ -2073,15 +2075,15 @@ Désactiver les enregistrements sécurisés et ressayer ? The export container %1 is already referenced. - + Le conteneur d'export %1 est déjà référencé. The import container %1 is already imported. - + Le conteneur d'import %1 est déjà importé. The container %1 imported and export by different groups. - + Le conteneur %1 est importé et exporté par des groupes différents. @@ -3151,19 +3153,19 @@ Ligne %2, colonne %3 Disabled share %1 - + Partage %1 désactivé Import from share %1 - + Importer du partage %1 Export to share %1 - + Exporter vers le partage %1 Synchronize with share %1 - + Synchroniser avec le partage %1 @@ -4685,7 +4687,7 @@ Commandes disponibles : Successfully recycled entry %1. - + Entrée %1 recyclée avec succès. Successfully deleted entry %1. @@ -4783,7 +4785,7 @@ Commandes disponibles : Insert password to encrypt database (Press enter to leave blank): - + Introduire le mot de passe pour chiffrer la base de données (Presser retour pour laisser vide) : Creating KeyFile %1 failed: %2 @@ -4851,7 +4853,7 @@ Commandes disponibles : Cannot create new group - + Impossible de créer de nouveau groupe @@ -4943,7 +4945,7 @@ Commandes disponibles : exclude term from results - + exclure le terme des résultats match term exactly @@ -4951,7 +4953,7 @@ Commandes disponibles : use regex in term - + utiliser les expressions régulières dans le terminal Fields @@ -5107,7 +5109,7 @@ Commandes disponibles : KeeShare key file - + fichier-clé KeeShare All files @@ -5134,7 +5136,7 @@ Commandes disponibles : ShareObserver Import from container without signature - + Importer depuis le conteneur sans signature We cannot verify the source of the shared container because it is not signed. Do you really want to import from %1? @@ -5142,7 +5144,7 @@ Commandes disponibles : Import from container with certificate - + Importer depuis le conteneur avec certificat Not this time @@ -5234,15 +5236,15 @@ Commandes disponibles : Export to %1 failed (%2) - + Échec de l'export vers %1 (%2) Export to %1 successful (%2) - + Réussite de l'export vers %1 (%2) Export to %1 - + Exporter vers %1 Do you want to trust %1 with the fingerprint of %2 from %3? diff --git a/share/translations/keepassx_hu.ts b/share/translations/keepassx_hu.ts index 95e035abb..5173dbf0c 100644 --- a/share/translations/keepassx_hu.ts +++ b/share/translations/keepassx_hu.ts @@ -611,15 +611,15 @@ Válassza ki a helyes adatbázist a hitelesítő adatok mentéséhez. Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1 - + A Snap homokozó miatt egy parancsfájlt kell futtatni a böngészőintegráció engedélyezéséhez.<br />Ezt innen szerezheti be: %1 Please see special instructions for browser extension use below - + Olvassa el a böngészőkiegészítő használatáról szóló különleges utasításokat alább KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3 - + A böngészőintegráció működéséhez a KeePassXC-böngészőre van szükség. <br />Letölthető ezen böngészőkre: %1 és %2. %3 @@ -695,19 +695,22 @@ Moved %2 keys to custom data. KeePassXC: Create a new group - + KeePassXC: Új csoport létrehozása A request for creating a new group "%1" has been received. Do you want to create this group? - + Az új „%1” csoport létrehozási kérése fogadva. +Biztos, hogy létrehozza ezt a csoportot? Your KeePassXC-Browser settings need to be moved into the database settings. This is necessary to maintain your current browser connections. Would you like to migrate your existing settings now? - + A KeePassXC-Browser beállításait át kell helyezni az adatbázis-beállításokba. +Ez szükséges a jelenlegi böngészőkapcsolatok fenntartásához. +Biztos, hogy migrálja most a meglévő beállításokat? @@ -871,7 +874,7 @@ Would you like to migrate your existing settings now? Key not transformed. This is a bug, please report it to the developers! - + A kulcs nincs átalakítva. Ez egy hiba, jelezze a fejlesztőknek! @@ -1531,7 +1534,7 @@ Egyesíti a módosításokat? Delete entry(s)? - Törli az bejegyzést?Törli az bejegyzéseket? + Törli a bejegyzést?Törli a bejegyzéseket? Move entry(s) to recycle bin? @@ -1601,11 +1604,11 @@ Letiltható a biztonságos mentés és úgy megkísérelhető a mentés? Replace references to entry? - Lecserélhető a bejegyzésre való hivatkozás? + Lecseréli a bejegyzésre mutató hivatkozásokat? Entry "%1" has %2 reference(s). Do you want to overwrite references with values, skip this entry, or delete anyway? - A(z) „%1” bejegyzésnek van %2 hivatkozása. Felül lehet írni a hivatkozást az értékekkel, vagy legyen átugorva, ill. legyen mindenképpen törölve?A(z) „%1” bejegyzésnek van %2 hivatkozása. Felül lehet írni a hivatkozásokat az értékekkel, vagy legyenek átugorva, ill. legyenek mindenképpen törölve? + A(z) „%1” bejegyzésnek van %2 hivatkozása. Felülírja a hivatkozásokat az értékekkel, átugorja a bejegyzést, vagy törli mindenképp?A(z) „%1” bejegyzésnek van %2 hivatkozása. Felülírja a hivatkozásokat az értékekkel, átugorja a bejegyzést, vagy törli mindenképp? Delete group @@ -1613,11 +1616,11 @@ Letiltható a biztonságos mentés és úgy megkísérelhető a mentés? Move group to recycle bin? - Legyen a csoport áthelyezve a kukába? + Áthelyezi a csoportot a kukába? Do you really want to move the group "%1" to the recycle bin? - Valóban legyen a(z) „%1” csoport áthelyezve a kukába? + Valóban áthelyezi a(z) „%1” csoportok a kukába? Successfully merged the database files. @@ -1629,7 +1632,7 @@ Letiltható a biztonságos mentés és úgy megkísérelhető a mentés? Shared group... - + Megosztott csoport… @@ -1798,7 +1801,7 @@ Letiltható a biztonságos mentés és úgy megkísérelhető a mentés? Inherit default Auto-Type sequence from the &group - Az alapértelmezett automatikus beírási sorrend öröklése a cso&porttól + Az alapértelmezett automatikus beírási sorrend öröklése a &csoporttól &Use custom Auto-Type sequence: @@ -2074,15 +2077,15 @@ Letiltható a biztonságos mentés és úgy megkísérelhető a mentés? The export container %1 is already referenced. - + A(z) %1 exportálása konténerre már van hivatkozás. The import container %1 is already imported. - + A(z) %1 importálási konténer már be lett importálva. The container %1 imported and export by different groups. - + A(z) %1 konténer importálva, és exportálás különböző csoportoknak. @@ -3153,19 +3156,19 @@ Line %2, column %3 Disabled share %1 - + %1 megosztás letiltva Import from share %1 - + Importálás a(z) %1 megosztásból Export to share %1 - + Exportálás a(z) %1 megosztásba Synchronize with share %1 - + Szinkronizálás a(z) %1 megosztásssal @@ -3285,11 +3288,11 @@ Message: %2 E&ntries - Be&jegyzések + &Bejegyzések &Groups - Cso&portok + &Csoportok &Tools @@ -4852,7 +4855,7 @@ Elérhető parancsok: Cannot create new group - + Nem hozható létre új csoport @@ -5128,7 +5131,7 @@ Elérhető parancsok: Signer: - + Aláíró: @@ -5251,27 +5254,27 @@ Elérhető parancsok: Multiple import source path to %1 in %2 - + Több importálási forrásútvonal ehhez: %1, itt: %2 Conflicting export target path %1 in %2 - + Ütköző %1 exportálási célútvonal itt: %2 Could not embed signature: Could not open file to write (%1) - + Az aláírás nem ágyazható be: A fájl nem nyitható meg írásra (%1) Could not embed signature: Could not write file (%1) - + Az aláírás nem ágyazható be: A fájl nem írható (%1) Could not embed database: Could not open file to write (%1) - + Az adatbázis nem ágyazható be: A fájl nem nyitható meg írásra (%1) Could not embed database: Could not write file (%1) - + Az adatbázis nem ágyazható be: A fájl nem írható (%1) diff --git a/share/translations/keepassx_id.ts b/share/translations/keepassx_id.ts index efbc39535..555aa987c 100644 --- a/share/translations/keepassx_id.ts +++ b/share/translations/keepassx_id.ts @@ -180,7 +180,7 @@ Minimize instead of app exit - + sembunyikan jendela ke baki sistem Show a system tray icon @@ -614,7 +614,7 @@ Please select the correct database for saving credentials. Please see special instructions for browser extension use below - + Lihat instruksi untuk penggunaan browser extension KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3 diff --git a/share/translations/keepassx_ja.ts b/share/translations/keepassx_ja.ts index 025d7ef28..8fb6e259e 100644 --- a/share/translations/keepassx_ja.ts +++ b/share/translations/keepassx_ja.ts @@ -611,15 +611,15 @@ Please select the correct database for saving credentials. Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1 - + Snap によってサンドボックス化されているため、ブラウザー統合を有効にするにはスクリプトを実行する必要があります。<br />スクリプトは次の場所から入手できます: %1 Please see special instructions for browser extension use below - + ブラウザー拡張機能を使用するための次の手順を参照してください KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3 - + ブラウザー統合の動作には KeePassXC-Browser が必要です。<br />KeePassXC-Browser は %1 用と %2 用の2種類あります。%3 @@ -676,11 +676,11 @@ Do you want to overwrite it? Successfully converted attributes from %1 entry(s). Moved %2 keys to custom data. %1 個のエントリーから属性を正常に変換しました。 -%2 個のキーをカスタムデータに移行しました。 +%2 個のキーをカスタムデータに移動しました。 Successfully moved %n keys to custom data. - %n 個のキーを正常にカスタムデータに移行しました。 + %n 個のキーを正常にカスタムデータに移動しました。 KeePassXC: No entry with KeePassHTTP attributes found! @@ -696,19 +696,23 @@ Moved %2 keys to custom data. KeePassXC: Create a new group - + KeePassXC: 新しいグループを作成 A request for creating a new group "%1" has been received. Do you want to create this group? - + 新しいグループ "%1" の作成要求を受け取りました。 +このグループを作成しますか? + Your KeePassXC-Browser settings need to be moved into the database settings. This is necessary to maintain your current browser connections. Would you like to migrate your existing settings now? - + KeePassXC-Browser の設定をデータベース設定内に移動する必要があります。 +これはブラウザーとの接続を維持するのに必要です。 +既存の設定を移動しますか? @@ -872,7 +876,7 @@ Would you like to migrate your existing settings now? Key not transformed. This is a bug, please report it to the developers! - + キーは変換されません。これはバグなので、開発者への報告をお願いします。 @@ -1005,7 +1009,7 @@ Please consider generating a new key file. Move KeePassHTTP attributes to KeePassXC-Browser &custom data - KeePassHTTP の属性を KeePassXC-Browser のカスタムデータに移行する(&C) + KeePassHTTP の属性を KeePassXC-Browser のカスタムデータに移動する(&C) Stored keys @@ -1631,7 +1635,7 @@ Disable safe saves and try again? Shared group... - + 共有グループ... @@ -2076,11 +2080,11 @@ Disable safe saves and try again? The export container %1 is already referenced. - + エクスポートするコンテナ %1 は既に参照されています。 The import container %1 is already imported. - + インポートするコンテナ %1 は既にインポートされています。 The container %1 imported and export by different groups. @@ -4856,7 +4860,7 @@ Available commands: Cannot create new group - + 新しいグループを作成できません @@ -5132,7 +5136,7 @@ Available commands: Signer: - + 署名者: @@ -5263,19 +5267,19 @@ Available commands: Could not embed signature: Could not open file to write (%1) - + 署名を埋め込めませんでした: ファイルを書き込み用に開くことができません (%1) Could not embed signature: Could not write file (%1) - + 署名を埋め込めませんでした: ファイルに書き込むことができません (%1) Could not embed database: Could not open file to write (%1) - + データベースを埋め込めませんでした: ファイルを書き込み用に開くことができません (%1) Could not embed database: Could not write file (%1) - + データベースを埋め込めませんでした: ファイルに書き込むことができません (%1) diff --git a/share/translations/keepassx_ko.ts b/share/translations/keepassx_ko.ts index 240fbaed2..7ab65f3f6 100644 --- a/share/translations/keepassx_ko.ts +++ b/share/translations/keepassx_ko.ts @@ -43,7 +43,7 @@ Special thanks from the KeePassXC team go to debfx for creating the original KeePassX. - + KeePassXC 팀은 원 프로젝트인 KeePassX의 개발자 debfx에게 특별한 감사를 전합니다. @@ -54,7 +54,7 @@ Use OpenSSH for Windows instead of Pageant - + Pageant 대신 OpenSSH for Windows 사용 @@ -77,23 +77,23 @@ Icon only - + 아이콘만 Text only - + 텍스트만 Text beside icon - + 아이콘 옆에 텍스트 Text under icon - + 아이콘 밑에 텍스트 Follow style - + 스타일 따르기 @@ -168,7 +168,7 @@ Hide the entry preview panel - + 항목 미리 보기 패널 숨기기 General @@ -176,11 +176,11 @@ Hide toolbar (icons) - + 도구 모음(아이콘) 숨기기 Minimize instead of app exit - + 프로그램을 끝내지 않고 최소화 Show a system tray icon @@ -220,7 +220,7 @@ Auto-Type typing delay - + 자동 입력 지연 시간 ms @@ -229,23 +229,23 @@ Auto-Type start delay - + 자동 입력 시작 지연 시간 Check for updates at application startup - + 시작할 때 업데이트 확인 Include pre-releases when checking for updates - + 업데이트를 확인할 때 불안정 버전 포함 Movable toolbar - + 이동 가능한 도구 모음 Button style - + 단추 스타일 @@ -269,11 +269,11 @@ min - + Forget TouchID after inactivity of - + 다음 시간 동안 활동이 없을 때 TouchID 잊기 Convenience @@ -285,7 +285,7 @@ Forget TouchID when session is locked or lid is closed - + 세션을 잠그거나 덮개를 닫았을 때 TouchID 잊기 Lock databases after minimizing the window @@ -293,7 +293,7 @@ Re-lock previously locked database after performing Auto-Type - + 자동 입력 이후 이전에 잠긴 데이터베이스 다시 잠그기 Don't require password repeat when it is visible @@ -301,15 +301,15 @@ Don't hide passwords when editing them - + 암호를 편집할 때 숨기지 않기 Don't use placeholder for empty password fields - + 빈 암호 필드에 자리 비움자 사용하지 않기 Hide passwords in the entry preview panel - + 항목 미리 보기 패널에서 암호 숨기기 Hide entry notes by default @@ -321,7 +321,7 @@ Use DuckDuckGo as fallback for downloading website icons - + 웹사이트 아이콘을 다운로드할 때 DuckDuckGo를 폴백으로 사용하기 @@ -429,11 +429,11 @@ Please select whether you want to allow access. BrowserEntrySaveDialog KeePassXC-Browser Save Entry - + KeePassXC-브라우저 항목 저장 Ok - + 확인 Cancel @@ -442,7 +442,8 @@ Please select whether you want to allow access. You have multiple databases open. Please select the correct database for saving credentials. - + 여러 개의 데이터베이스를 열었습니다. +인증 정보를 저장할 데이터베이스를 선택하십시오. @@ -589,36 +590,36 @@ Please select the correct database for saving credentials. &Tor Browser - + Tor 브라우저(&T) <b>Warning</b>, the keepassxc-proxy application was not found!<br />Please check the KeePassXC installation directory or confirm the custom path in advanced options.<br />Browser integration WILL NOT WORK without the proxy application.<br />Expected Path: - + <b>경고</b>, keepassxc-proxy 프로그램을 찾을 수 없습니다!<br />KeePassXC 설치 디렉터리를 확인하거나 고급 설정의 사용자 경로를 확인하십시오.<br />프록시 프로그램이 없으면 브라우저 통합 기능을 사용할 수 없습니다.<br />예상하는 경로: Executable Files - + 실행 파일 All Files - + 모든 파일 Do not ask permission for HTTP &Basic Auth An extra HTTP Basic Auth setting - + HTTP 기본 인증 묻지 않기(&B) Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1 - + Snap 샌드박스로 인하여 브라우저 확장 기능을 사용하려면 스크립트를 실행해야 합니다.<br />%1에서 스크립트를 확인할 수 있습니다 Please see special instructions for browser extension use below - + 브라우저 확장 기능을 위한 추가 절차를 참조하십시오 KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3 - + 브라우저 통합을 사용하려면 KeePassXC-브라우저가 필요합니다.<br /> %1 및 %2용으로 다운로드할 수 있습니다. %3 @@ -665,48 +666,53 @@ Do you want to overwrite it? Converting attributes to custom data… - + 속성을 사용자 정의 데이터로 변환 중… KeePassXC: Converted KeePassHTTP attributes - + KeePassXC: KeePassHTTP 속성 변환됨 Successfully converted attributes from %1 entry(s). Moved %2 keys to custom data. - + %1개 항목의 속성을 변환했습니다. +키 %2개를 사용자 정의 데이터로 이동했습니다. Successfully moved %n keys to custom data. - + 키 %n개를 사용자 정의 데이터로 이동했습니다. KeePassXC: No entry with KeePassHTTP attributes found! - + KeePassXC: KeePassHTTP 속성이 있는 항목을 찾을 수 없습니다! The active database does not contain an entry with KeePassHTTP attributes. - + 현재 활성화된 데이터베이스에 KeePassHTTP 속성이 있는 항목이 없습니다. KeePassXC: Legacy browser integration settings detected - + KeePassXC: 레거시 브라우저 통합 설정 감지됨 KeePassXC: Create a new group - + KeePassXC: 새 그룹 생성 A request for creating a new group "%1" has been received. Do you want to create this group? - + 새 그룹 "%1"을(를) 생성하는 요청을 받았습니다. +이 그룹을 생성하시겠습니까? + Your KeePassXC-Browser settings need to be moved into the database settings. This is necessary to maintain your current browser connections. Would you like to migrate your existing settings now? - + KeePassXC-브라우저 설정을 데이터베이스 설정으로 이동해야 합니다. +현재 브라우저 연결을 유지하려면 이 작업이 필요합니다. +존재하는 설정을 이전하시겠습니까? @@ -800,24 +806,25 @@ Would you like to migrate your existing settings now? Empty fieldname %1 - + 빈 필드 이름 %1 column %1 - + 칸 %1 Error(s) detected in CSV file! - + CSV 파일에 오류가 있습니다! [%n more message(s) skipped] - + [추가 메시지 %n개 건너뜀] CSV import: writer has errors: %1 - + CSV 가져오기: 기록 도구에 오류가 있습니다: +%1 @@ -829,15 +836,15 @@ Would you like to migrate your existing settings now? %1, %2, %3 file info: bytes, rows, columns - + %1, %2, %3 %n byte(s) - + %n바이트 %n row(s) - + %n줄 @@ -849,34 +856,34 @@ Would you like to migrate your existing settings now? File %1 does not exist. - + 파일 %1이(가) 존재하지 않습니다. Unable to open file %1. - + 파일 %1을(를) 열 수 없습니다. Error while reading the database: %1 - + 데이터베이스 읽기 오류: %1 Could not save, database has no file name. - + 데이터베이스 파일 이름이 없어서 저장할 수 없습니다. File cannot be written as it is opened in read-only mode. - + 읽기 전용 모드로 파일을 열었기 때문에 저장할 수 없습니다. Key not transformed. This is a bug, please report it to the developers! - + 키 변형 과정이 일어나지 않았습니다. 버그이므로 개발자에게 보고해 주십시오! DatabaseOpenDialog Unlock Database - KeePassXC - + 데이터베이스 잠금 해제 - KeePassXC @@ -937,17 +944,19 @@ Please consider generating a new key file. TouchID for quick unlock - + 빠른 잠금 해제용 TouchID Unable to open the database: %1 - + 데이터베이스를 열 수 없음: +%1 Can't open key file: %1 - + 키 파일을 열 수 없음: +%1 @@ -961,7 +970,7 @@ Please consider generating a new key file. DatabaseSettingsDialog Advanced Settings - + 고급 설정 General @@ -973,11 +982,11 @@ Please consider generating a new key file. Master Key - + 마스터 키 Encryption Settings - + 암호화 설정 Browser Integration @@ -988,7 +997,7 @@ Please consider generating a new key file. DatabaseSettingsWidgetBrowser KeePassXC-Browser settings - + KeePassXC-브라우저 설정 &Disconnect all browsers @@ -996,15 +1005,15 @@ Please consider generating a new key file. Forg&et all site-specific settings on entries - + 항목의 모든 사이트별 설정 삭제(&E) Move KeePassHTTP attributes to KeePassXC-Browser &custom data - + KeePassHTTP 속성을 KeePassXC-브라우저 사용자 정의 데이터로 이동(&C) Stored keys - + 저장된 키 Remove @@ -1012,33 +1021,35 @@ Please consider generating a new key file. Delete the selected key? - + 선택한 키를 삭제하시겠습니까? Do you really want to delete the selected key? This may prevent connection to the browser plugin. - + 선택한 키를 삭제하시겠습니까? +브라우저 플러그인에 연결하지 못할 수도 있습니다. Key - + Value - + Enable Browser Integration to access these settings. - + 이 설정을 변경하려면 브라우저 통합을 활성화하십시오. Disconnect all browsers - + 모든 브라우저 연결 끊기 Do you really want to disconnect all browsers? This may prevent connection to the browser plugin. - + 모든 브라우저 연결을 끊으시겠습니까? +브라우저 플러그인에 연결하지 못할 수도 있습니다. KeePassXC: No keys found @@ -1046,7 +1057,7 @@ This may prevent connection to the browser plugin. No shared encryption keys found in KeePassXC settings. - + KeePassXC 설정에서 공유된 암호화 키를 찾을 수 없습니다. KeePassXC: Removed keys from database @@ -1054,16 +1065,17 @@ This may prevent connection to the browser plugin. Successfully removed %n encryption key(s) from KeePassXC settings. - + KeePassXC 설정에서 암호화 키 %n개를 삭제했습니다. Forget all site-specific settings on entries - + 항목의 모든 사이트별 설정 삭제 Do you really want forget all site-specific settings on every entry? Permissions to access entries will be revoked. - + 모든 항목의 사이트별 설정을 삭제하시겠습니까? +항목에 접근할 권한이 취소됩니다. Removing stored permissions… @@ -1079,7 +1091,7 @@ Permissions to access entries will be revoked. Successfully removed permissions from %n entry(s). - + 항목 %n개에서 권한을 삭제했습니다. KeePassXC: No entry with permissions found! @@ -1091,12 +1103,13 @@ Permissions to access entries will be revoked. Move KeePassHTTP attributes to custom data - + KeePassHTTP 속성을 사용자 정의 데이터로 이동 Do you really want to move all legacy browser integration data to the latest standard? This is necessary to maintain compatibility with the browser plugin. - + 모든 레거시 브라우저 통합 데이터를 최신 표준으로 이전하시겠습니까? +브라우저 통합 플러그인과 호환성을 유지하기 위해서 필요합니다. @@ -1135,48 +1148,48 @@ This is necessary to maintain compatibility with the browser plugin. Decryption Time: - + 복호화 시간: ?? s - + ??초 Change - + 변경 100 ms - + 100 ms 5 s - + 5초 Higher values offer more protection, but opening the database will take longer. - + 시간을 더 늘리면 보호 정도를 높일 수 있지만 데이터베이스를 여는 데 더 오랜 시간이 걸릴 것입니다. Database format: - + 데이터베이스 형식: This is only important if you need to use your database with other programs. - + 데이터베이스를 다른 프로그램에서 사용할 일이 있을 때 중요합니다. KDBX 4.0 (recommended) - + KDBX 4.0(추천) KDBX 3.1 - + KDBX 3.1 unchanged Database decryption time is unchanged - + 변경되지 않음 Number of rounds too high @@ -1223,22 +1236,22 @@ If you keep this number, your database may be too easy to crack! MiB Abbreviation for Mebibytes (KDF settings) - + MiB thread(s) Threads for parallel execution (KDF settings) - + 개 스레드 %1 ms milliseconds - + %1 ms %1 s seconds - + %1초 @@ -1292,57 +1305,59 @@ If you keep this number, your database may be too easy to crack! DatabaseSettingsWidgetKeeShare Sharing - + 공유 Breadcrumb - + 단계 Type - + 형식 Path - + 경로 Last Signer - + 마지막 서명자 Certificates - + 인증서 > Breadcrumb separator - + > DatabaseSettingsWidgetMasterKey Add additional protection... - + 추가 보호 추가... No encryption key added - + 암호화 키가 추가되지 않았음 You must add at least one encryption key to secure your database! - + 데이터베이스를 보호할 암호화 키를 최소 하나 추가해야 합니다! No password set - + 암호가 설정되지 않았음 WARNING! You have not set a password. Using a database without a password is strongly discouraged! Are you sure you want to continue without a password? - + 경고! 암호를 설정하지 않았습니다. 데이터베이스 암호를 설정하지 않는 것은 추천하지 않습니다! + +암호를 지정하지 않고 계속 진행하시겠습니까? Unknown error @@ -1350,18 +1365,18 @@ Are you sure you want to continue without a password? Failed to change master key - + 마스터 키를 변경할 수 없음 DatabaseSettingsWidgetMetaDataSimple Database Name: - + 데이터베이스 이름: Description: - + 설명: @@ -1404,39 +1419,40 @@ Are you sure you want to continue without a password? Database creation error - + Database creation error The created database has no key or KDF, refusing to save it. This is definitely a bug, please report it to the developers. - + 이 생성된 데이터베이스에 키나 KDF가 없어서 저장하지 않을 것입니다. +버그이므로 개발자에게 보고해 주십시오. The database file does not exist or is not accessible. - + 데이터베이스 파일이 존재하지 않거나 접근할 수 없습니다. Select CSV file - + CSV 파일 선택 New Database - + 새 데이터베이스 %1 [New Database] Database tab name modifier - + %1 [새 데이터베이스] %1 [Locked] Database tab name modifier - + %1 [잠김] %1 [Read-only] Database tab name modifier - + %1 [읽기 전용] @@ -1517,15 +1533,15 @@ Do you want to merge your changes? Do you really want to delete %n entry(s) for good? - + 항목 %n개를 영원히 삭제하시겠습니까? Delete entry(s)? - + 항목을 삭제하시겠습니까? Move entry(s) to recycle bin? - + 항목을 휴지통으로 이동하시겠습니까? File opened in read only mode. @@ -1533,11 +1549,11 @@ Do you want to merge your changes? Lock Database? - + 데이터베이스를 잠그시겠습니까? You are editing an entry. Discard changes and lock anyway? - + 항목을 편집하고 있습니다. 변경 사항을 무시하고 잠그시겠습니까? "%1" was modified. @@ -1547,7 +1563,8 @@ Save changes? Database was modified. Save changes? - + 데이터베이스가 변경되었습니다. +저장하시겠습니까? Save changes? @@ -1556,7 +1573,8 @@ Save changes? Could not open the new database file while attempting to autoreload. Error: %1 - + 자동으로 다시 불러오려는 중 새 데이터베이스 파일을 열 수 없었습니다. +오류: %1 Disable safe saves? @@ -1571,7 +1589,8 @@ Disable safe saves and try again? Writing the database failed. %1 - + 데이터베이스 파일에 기록할 수 없습니다. +%1 Passwords @@ -1587,11 +1606,11 @@ Disable safe saves and try again? Replace references to entry? - + 항목에 대한 참조를 변경하시겠습니까? Entry "%1" has %2 reference(s). Do you want to overwrite references with values, skip this entry, or delete anyway? - + 항목 "%1"에 참조 %2개가 있습니다. 해당 참조를 값으로 덮어 쓰거나, 항목을 건너뛰거나, 그래도 삭제하시겠습니까? Delete group @@ -1599,23 +1618,23 @@ Disable safe saves and try again? Move group to recycle bin? - + 그룹을 휴지통으로 이동하시겠습니까? Do you really want to move the group "%1" to the recycle bin? - + 그룹 "%1"을(를) 휴지통으로 이동하시겠습니까? Successfully merged the database files. - + 데이터베이스 파일을 합쳤습니다. Database was not modified by merge operation. - + 수정 작업으로 데이터베이스가 변경되지 않았습니다. Shared group... - + 공유된 그룹... @@ -1706,23 +1725,23 @@ Disable safe saves and try again? Apply generated password? - + 생성된 암호를 적용하시겠습니까? Do you want to apply the generated password to this entry? - + 이 항목에 생성된 암호를 적용하시겠습니까? Entry updated successfully. - + 항목을 업데이트했습니다. Entry has unsaved changes - + 항목에 저장되지 않은 변경 사항이 있음 New attribute %1 - + 새 속성 %1 [PROTECTED] Press reveal to view or edit @@ -1730,11 +1749,11 @@ Disable safe saves and try again? %n year(s) - + %n년 Confirm Removal - + 삭제 확인 @@ -1769,11 +1788,11 @@ Disable safe saves and try again? Foreground Color: - + 글자색: Background Color: - + 배경색: @@ -1808,7 +1827,7 @@ Disable safe saves and try again? Use a specific sequence for this association: - + 이 조합에 지정된 시퀀스 사용: @@ -1988,15 +2007,15 @@ Disable safe saves and try again? Type: - + 형식: Path: - + 경로: ... - + ... Password: @@ -2004,55 +2023,55 @@ Disable safe saves and try again? Inactive - + 비활성 Import from path - + 경로에서 가져오기 Export to path - + 경로로 내보내기 Synchronize with path - + 다음 경로와 동기화 Your KeePassXC version does not support sharing your container type. Please use %1. - + KeePassXC 현재 버전에서 현재 컨테이너 형식을 공유할 수 없습니다. %1을(를) 사용하십시오. Database sharing is disabled - + 데이터베이스 공유 비활성화됨 Database export is disabled - + 데이터베이스 내보내기 비활성화됨 Database import is disabled - + 데이터베이스 가져오기 비활성화됨 KeeShare unsigned container - + KeeShare 서명되지 않은 컨테이너 KeeShare signed container - + KeeShare 서명된 컨테이너 Select import source - + 가져올 원본 선택 Select export target - + 내보낼 대상 선택 Select import/export file - + 가져올/내보낼 파일 선택 Clear @@ -2060,15 +2079,15 @@ Disable safe saves and try again? The export container %1 is already referenced. - + 내보내기 컨테이너 %1이(가) 이미 참조되었습니다. The import container %1 is already imported. - + 가져오기 컨테이너 %1이(가) 이미 참조되었습니다. The container %1 imported and export by different groups. - + 컨테이너 %1을(를) 가져왔고 다른 그룹에서 내보냈습니다. @@ -2146,35 +2165,35 @@ Disable safe saves and try again? Custom icon successfully downloaded - + 사용자 정의 아이콘 다운로드됨 Hint: You can enable DuckDuckGo as a fallback under Tools>Settings>Security - + 힌트: 도구>설정>보안에서 DuckDuckGo를 폴백으로 지정할 수 있습니다 Select Image(s) - + 이미지 선택 Successfully loaded %1 of %n icon(s) - + 아이콘 %n개 중 %1개 불러옴 No icons were loaded - + 아이콘을 불러오지 않았음 %n icon(s) already exist in the database - + 데이터베이스에 아이콘 %n개가 이미 존재함 The following icon(s) failed: - + 다음 아이콘에서 오류가 발생했습니다: This icon is used by %n entry(s), and will be replaced by the default icon. Are you sure you want to delete it? - + %n개 항목에서 이 아이콘을 사용하고 있으며 기본 아이콘으로 대체됩니다. 삭제하시겠습니까? @@ -2197,7 +2216,7 @@ Disable safe saves and try again? Plugin Data - + 플러그인 데이터 Remove @@ -2205,27 +2224,28 @@ Disable safe saves and try again? Delete plugin data? - + 플러그인 데이터를 삭제하시겠습니까? Do you really want to delete the selected plugin data? This may cause the affected plugins to malfunction. - + 선택한 플러그인 데이터를 삭제하시겠습니까? +영향받는 플러그인이 제대로 동작하지 않을 수도 있습니다. Key - + Value - + Entry %1 - Clone - + %1 - 사본 @@ -2307,12 +2327,13 @@ This may cause the affected plugins to malfunction. Confirm remove - + 삭제 확인 Unable to open file(s): %1 - + 파일을 열 수 없음: +%1 @@ -2398,11 +2419,11 @@ This may cause the affected plugins to malfunction. Yes - + TOTP - + TOTP @@ -2482,7 +2503,7 @@ This may cause the affected plugins to malfunction. <b>%1</b>: %2 attributes line - + <b>%1</b>: %2 Enabled @@ -2494,7 +2515,7 @@ This may cause the affected plugins to malfunction. Share - + 공유 @@ -2525,7 +2546,7 @@ This may cause the affected plugins to malfunction. Attachments (icon) - + 첨부(아이콘) @@ -2537,7 +2558,7 @@ This may cause the affected plugins to malfunction. [empty] group has no children - + [비어 있음] @@ -2582,7 +2603,7 @@ This may cause the affected plugins to malfunction. Header doesn't match hash - + 헤더의 해시가 일치하지 않음 Invalid header id size @@ -2810,15 +2831,15 @@ This is a one-way migration. You won't be able to open the imported databas Invalid cipher uuid length: %1 (length=%2) - + 잘못된 암호화 UUID 길이: %1(length=%2) Unable to parse UUID: %1 - + UUID를 처리할 수 없음: %1 Failed to read database file. - + 데이터베이스 파일을 읽을 수 없습니다. @@ -2944,7 +2965,9 @@ This is a one-way migration. You won't be able to open the imported databas XML error: %1 Line %2, column %3 - + XML 오류: +%1 +%2줄, %3칸 @@ -3111,53 +3134,53 @@ Line %2, column %3 unable to seek to content position - + 내용 위치로 이동할 수 없음 KeeShare Disabled share - + 비활성화된 공유 Import from - + 다음에서 가져오기 Export to - + 다음으로 내보내기 Synchronize with - + 다음과 동기화 Disabled share %1 - + 비활성화된 공유 %1 Import from share %1 - + 공유 %1에서 가져오기 Export to share %1 - + 공유 %1(으)로 내보내기 Synchronize with share %1 - + 공유 %1와(과) 동기화 KeyComponentWidget Key Component - + 키 구성 요소 Key Component Description - + 키 구성 요소 설명 Cancel @@ -3165,27 +3188,27 @@ Line %2, column %3 Key Component set, click to change or remove - + 키 구성 요소 집합, 눌러서 변경하거나 삭제 Add %1 Add a key component - + %1 추가 Change %1 Change a key component - + %1 변경 Remove %1 Remove a key component - + %1 삭제 %1 set, click to change or remove Change or remove a key component - + %1 설정됨, 눌러서 변경 및 삭제 @@ -3200,11 +3223,11 @@ Line %2, column %3 Key File - + 키 파일 <p>You can add a key file containing random bytes for additional security.</p><p>You must keep it secret and never lose it or you will be locked out!</p> - + <p>무작위 바이트가 들어 있는 키 파일을 추가하여 보안을 향상시킬 수 있습니다.</p><p>키 파일을 안전한 곳에 보관해야 하며 키 파일을 잃어버리면 데이터베이스에 접근할 수 없습니다!</p> Legacy key file format @@ -3215,12 +3238,16 @@ Line %2, column %3 unsupported in the future. Please go to the master key settings and generate a new key file. - + 차후 버전에서 지원이 중단될 예정인 레거시 키 파일 +형식을 사용하고 있습니다. + +마스터 키 설정으로 이동하여 새 키 파일을 생성하십시오. Error loading the key file '%1' Message: %2 - + 키 파일 '%1'을(를) 불러올 수 없음 +메시지: %2 Key files @@ -3236,11 +3263,11 @@ Message: %2 Error creating key file - + 키 파일 생성 오류 Unable to create key file: %1 - + 키 파일을 만들 수 없음: %1 Select a key file @@ -3415,203 +3442,205 @@ This version is not meant for production use. &Donate - + 기부(&D) Report a &bug - + 버그 보고(&B) WARNING: Your Qt version may cause KeePassXC to crash with an On-Screen Keyboard! We recommend you use the AppImage available on our downloads page. - + 경고: 사용 중인 Qt 버전에서 KeePassXC를 화상 키보드와 사용했을 때 충돌할 수 있습니다! +다운로드 페이지에 있는 AppImage 사용을 추천합니다. &Import - + 가져오기(&I) Copy att&ribute... - + 속성 복사(&R)... TOTP... - + TOTP... &New database... - + 새 데이터베이스(&N)... Create a new database - + 새 데이터베이스 만들기 &Merge from database... - + 데이터베이스에서 합치기(&M)... Merge from another KDBX database - + 다른 KDBX 데이터베이스에서 합치기 &New entry - + 새 항목(&N) Add a new entry - + 새 항목 추가하기 &Edit entry - + 항목 편집(&E) View or edit entry - + 항목을 보거나 편집하기 &New group - + 새 그룹(&N) Add a new group - + 새 그룹 추가하기 Change master &key... - + 마스터 키 변경(&K)... &Database settings... - + 데이터베이스 설정(&D)... Copy &password - + 암호 복사(&P) Perform &Auto-Type - + 자동 입력 실행(&A) Open &URL - + URL 열기(&U) KeePass 1 database... - + KeePass 1 데이터베이스... Import a KeePass 1 database - + KeePass 1 데이터베이스 가져오기 CSV file... - + CSV 파일... Import a CSV file - + CSV 파일 가져오기 Show TOTP... - + TOTP 보이기... Show TOTP QR Code... - + TOTP QR 코드 보이기... Check for Updates... - + 업데이트 확인... Share entry - + 항목 공유 NOTE: You are using a pre-release version of KeePassXC! Expect some bugs and minor issues, this version is not meant for production use. - + 알림: KeePassXC의 미리 보기 버전을 사용하고 있습니다! +이 버전은 일반 사용자 대상 버전이 아니므로 버그나 사소한 문제가 발생할 수 있습니다. Check for updates on startup? - + 시작할 때 업데이트를 확인하시겠습니까? Would you like KeePassXC to check for updates on startup? - + KeePassXC를 시작할 때 업데이트를 확인하시겠습니까? You can always check for updates manually from the application menu. - + 언제든지 프로그램 메뉴에서 수동으로 업데이트를 확인할 수 있습니다. Merger Creating missing %1 [%2] - + 존재하지 않는 %1 [%2] 생성 중 Relocating %1 [%2] - + %1 [%2] 위치 변경 중 Overwriting %1 [%2] - + %1 [%2] 덮어쓰는 중 older entry merged from database "%1" - + 데이터베이스 "%1"에서 합쳐진 이전 항목 Adding backup for older target %1 [%2] - + 오래된 대상 %1 [%2]의 백업 추가 중 Adding backup for older source %1 [%2] - + 오래된 원본 %1 [%2]의 백업 추가 중 Reapplying older target entry on top of newer source %1 [%2] - + 새로운 원본 %1 [%2]에 오래된 대상 항목 다시 적용하는 중 Reapplying older source entry on top of newer target %1 [%2] - + 새로운 대상 %1 [%2]에 오래된 원본 항목 다시 적용하는 중 Synchronizing from newer source %1 [%2] - + 새로운 원본 %1 [%2]에서 동기화하는 중 Synchronizing from older source %1 [%2] - + 오래된 원본 %1 [%2]에서 동기화하는 중 Deleting child %1 [%2] - + 자식 항목 %1 [%2] 삭제 중 Deleting orphan %1 [%2] - + 고립된 항목 %1 [%2] 삭제 중 Changed deleted objects - + 변경된 삭제된 개체 Adding missing icon %1 - + 빠진 아이콘 %1 추가하는 중 NewDatabaseWizard Create a new KeePassXC database... - + 새 KeePassXC 데이터베이스 만들기... Root @@ -3623,56 +3652,56 @@ Expect some bugs and minor issues, this version is not meant for production use. NewDatabaseWizardPage WizardPage - + 마법사페이지 En&cryption Settings - + 암호화 설정(&C) Here you can adjust the database encryption settings. Don't worry, you can change them later in the database settings. - + 데이터베이스 암호화 설정을 변경할 수 있습니다. 나중에 데이터베이스 설정에서도 변경할 수 있습니다. Advanced Settings - + 고급 설정 Simple Settings - + 간단한 설정 NewDatabaseWizardPageEncryption Encryption Settings - + 암호화 설정 Here you can adjust the database encryption settings. Don't worry, you can change them later in the database settings. - + 데이터베이스 암호화 설정을 변경할 수 있습니다. 나중에 데이터베이스 설정에서도 변경할 수 있습니다. NewDatabaseWizardPageMasterKey Database Master Key - + 데이터베이스 마스터 키 A master key known only to you protects your database. - + 나만 알고 있는 마스터 키로 데이터베이스를 보호하십시오. NewDatabaseWizardPageMetaData General Database Information - + 일반 데이터베이스 정보 Please fill in the display name and an optional description for your new database: - + 새 데이터베이스 표시 이름과 추가 설명(선택)을 입력하십시오: @@ -3755,23 +3784,23 @@ Expect some bugs and minor issues, this version is not meant for production use. Unsupported key type: %1 - + 지원하지 않는 키 형식: %1 Unknown cipher: %1 - + 알 수 없는 암호화: %1 Cipher IV is too short for MD5 kdf - + MD5 키 유도 함수에 IV가 너무 짧음 Unknown KDF: %1 - + 알 수 없는 KDF: %1 Unknown key type: %1 - + 알 수 없는 키 형식: %1 @@ -3782,7 +3811,7 @@ Expect some bugs and minor issues, this version is not meant for production use. Confirm password: - + 암호 확인: Password @@ -3790,15 +3819,15 @@ Expect some bugs and minor issues, this version is not meant for production use. <p>A password is the primary method for securing your database.</p><p>Good passwords are long and unique. KeePassXC can generate one for you.</p> - + <p>암호는 데이터베이스를 보호하는 주요 수단입니다.</p><p>좋은 암호는 길고 예측할 수 없어야 합니다. KeePassXC에서 암호를 생성할 수 있습니다.</p> Passwords do not match. - + 암호가 일치하지 않습니다. Generate master password - + 마스터 암호 생성 @@ -3914,11 +3943,11 @@ Expect some bugs and minor issues, this version is not meant for production use. ExtendedASCII - + 확장 ASCII Switch to advanced mode - + 고급 모드로 전환 Advanced @@ -3926,7 +3955,7 @@ Expect some bugs and minor issues, this version is not meant for production use. Upper Case Letters A to F - + 대문자 A-F A-Z @@ -3934,7 +3963,7 @@ Expect some bugs and minor issues, this version is not meant for production use. Lower Case Letters A to F - + 소문자 A-F a-z @@ -3946,108 +3975,108 @@ Expect some bugs and minor issues, this version is not meant for production use. Braces - + 괄호 {[( - + {[( Punctuation - + 구두점 .,:; - + .,:; Quotes - + 따옴표 " ' - + " ' Math - + 수학 기호 <*+!?= - + <*+!?= Dashes - + 대시 \_|-/ - + \_|-/ Logograms - + 로고그램 #$%&&@^`~ - + #$%&&@^`~ Switch to simple mode - + 간단한 모드로 전환 Simple - + 간단히 Character set to exclude from generated password - + 생성된 암호에서 제외할 문자 집합 Do not include: - + 포함하지 않음: Add non-hex letters to "do not include" list - + "포함하지 않음" 목록에 16진수가 아닌 문자 추가 Hex - + 16진 Excluded characters: "0", "1", "l", "I", "O", "|", "﹒" - + 제외할 글자: "0", "1", "l", "I", "O", "|", "﹒" Word Co&unt: - + 단어 개수(&U): Regenerate - + 다시 생성 QApplication KeeShare - + KeeShare QFileDialog Select - + 선택 QMessageBox Overwrite - + 덮어쓰기 Delete @@ -4055,11 +4084,11 @@ Expect some bugs and minor issues, this version is not meant for production use. Move - + 이동 Empty - + 비어 있음 Remove @@ -4067,7 +4096,7 @@ Expect some bugs and minor issues, this version is not meant for production use. Skip - + 건너뛰기 Disable @@ -4075,7 +4104,7 @@ Expect some bugs and minor issues, this version is not meant for production use. Merge - + 합치기 @@ -4375,320 +4404,324 @@ Available commands: Generate a new random diceware passphrase. - + 새로운 주사위 암호를 생성합니다. Word count for the diceware passphrase. - + 주사위 암호 단어 개수입니다. Wordlist for the diceware generator. [Default: EFF English] - + 주사위 암호 생성 시 사용할 단어 목록입니다. +[기본값: EFF 영어] Generate a new random password. - + 새 무작위 암호를 생성합니다. Invalid value for password length %1. - + 암호 길이 %1의 값이 잘못되었습니다. Could not create entry with path %1. - + 경로 %1에 항목을 만들 수 없습니다. Enter password for new entry: - + 새 항목의 암호 입력: Writing the database failed %1. - + 데이터베이스에 기록할 수 없습니다 %1. Successfully added entry %1. - + 항목 %1을(를) 추가했습니다. Copy the current TOTP to the clipboard. - + 현재 TOTP를 클립보드에 복사합니다. Invalid timeout value %1. - + 시간 제한 값 %1이(가) 잘못되었습니다. Entry %1 not found. - + 항목 %1을(를) 찾을 수 없습니다. Entry with path %1 has no TOTP set up. - + 경로 %1에 있는 항목에 TOTP가 설정되지 않았습니다. Entry's current TOTP copied to the clipboard! - + 항목의 현재 TOTP를 클립보드에 복사했습니다! Entry's password copied to the clipboard! - + 항목의 암호를 클립보드에 복사했습니다! Clearing the clipboard in %1 second(s)... - + %1초 후 클립보드를 지웁니다... Clipboard cleared! - + 클립보드를 지웠습니다! Silence password prompt and other secondary outputs. - + 암호 입력 프롬프트 및 추가 출력을 숨깁니다. count CLI parameter - + count Invalid value for password length: %1 - + 암호 길이 값이 잘못됨: %1 Could not find entry with path %1. - + 경로 %1에서 항목을 찾을 수 없습니다. Not changing any field for entry %1. - + 항목 %1의 필드를 변경하지 않습니다. Enter new password for entry: - + 항목의 새로운 암호 입력: Writing the database failed: %1 - + 데이터베이스에기록할 수 없음: %1 Successfully edited entry %1. - + 항목 %1을(를) 편집했습니다. Length %1 - + 길이 %1 Entropy %1 - + 엔트로피 %1 Log10 %1 - + Log10 %1 Multi-word extra bits %1 - + 여러 단어 추가 비트 %1 Type: Bruteforce - + 형식: 무작위 대입 Type: Dictionary - + 형식: 사전 Type: Dict+Leet - + 형식: 사전+Leet Type: User Words - + 형식: 사용자 단어 Type: User+Leet - + 형식: 사용자+Leet Type: Repeated - + 형식: 반복됨 Type: Sequence - + 형식: 시퀀스 Type: Spatial - + 형식: 인접 Type: Date - + 형식: 날짜 Type: Bruteforce(Rep) - + 형식: 무작위 대입(반복) Type: Dictionary(Rep) - + 형식: 사전(반복) Type: Dict+Leet(Rep) - + 형식: 사전+Leet(반복) Type: User Words(Rep) - + 형식: 사용자 단어(반복) Type: User+Leet(Rep) - + 형식: 사용자+Leet(반복) Type: Repeated(Rep) - + 형식: 반복됨(반복) Type: Sequence(Rep) - + 형식: 시퀀스(반복) Type: Spatial(Rep) - + 형식: 인접(반복) Type: Date(Rep) - + 형식: 날짜(반복) Type: Unknown%1 - + 형식: 알 수 없음%1 Entropy %1 (%2) - + 엔트로피 %1(%2) *** Password length (%1) != sum of length of parts (%2) *** - + *** 암호 길이 (%1) != 개별 부분 길이의 합 (%2) *** Failed to load key file %1: %2 - + 키 파일 %1을(를) 불러올 수 없음: %2 File %1 does not exist. - + 파일 %1이(가) 존재하지 않습니다. Unable to open file %1. - + 파일 %1을(를) 열 수 없습니다. Error while reading the database: %1 - + 데이터베이스 읽기 오류: +%1 Error while parsing the database: %1 - + 데이터베이스 처리 오류: +%1 Length of the generated password - + 생성된 암호의 길이 Use lowercase characters - + 소문자 사용 Use uppercase characters - + 대문자 사용 Use numbers. - + 숫자를 사용합니다. Use special characters - + 특수 문자 사용 Use extended ASCII - + 확장 ASCII 사용 Exclude character set - + 제외할 문자 집합 chars - + 글자 Exclude similar looking characters - + 비슷하게 생긴 문자 제외 Include characters from every selected group - + 모든 그룹에서 글자 선택 Recursively list the elements of the group. - + 그룹의 구성 요소를 재귀적으로 표시합니다. Cannot find group %1. - + 그룹 %1을(를) 찾을 수 없습니다. Error reading merge file: %1 - + 합칠 파일을 읽는 중 오류 발생: +%1 Unable to save database to file : %1 - + 데이터베이스를 파일로 저장할 수 없음: %1 Unable to save database to file: %1 - + 데이터베이스를 파일로 저장할 수 없음: %1 Successfully recycled entry %1. - + 항목 %1을(를) 휴지통으로 이동했습니다. Successfully deleted entry %1. - + 항목 %1을(를) 삭제했습니다. Show the entry's current TOTP. - + 항목의 현재 TOTP를 표시합니다. ERROR: unknown attribute %1. - + 오류: 알 수 없는 속성 %1. No program defined for clipboard manipulation - + 클립보드 변경 프로그램이 지정되지 않았음 Unable to start program %1 - + 프로그램 %1을(를) 시작할 수 없음 file empty - + 파일이 비어 있음 %1: (row, col) %2,%3 - + %1: (줄, 칸) %2, %3 AES: 256-bit @@ -4717,56 +4750,56 @@ Available commands: Invalid Settings TOTP - + 잘못된 설정 Invalid Key TOTP - + 잘못된 키 Message encryption failed. - + 메시지를 암호화할 수 없습니다. No groups found - + 그룹을 찾을 수 없음 Create a new database. - + 새 데이터베이스를 만듭니다. File %1 already exists. - + 파일 %1이(가) 이미 존재합니다. Loading the key file failed - + 키 파일을 불러올 수 없음 No key is set. Aborting database creation. - + 설정된 키가 없습니다. 데이터베이스 생성을 중단합니다. Failed to save the database: %1. - + 데이터베이스를 저장할 수 없음: %1. Successfully created new database. - + 새 데이터베이스를 만들었습니다. Insert password to encrypt database (Press enter to leave blank): - + 데이터베이스를 암호화할 암호 입력(Enter 키를 누르면 비워 둡니다): Creating KeyFile %1 failed: %2 - + 키 파일 %1 생성 실패: %2 Loading KeyFile %1 failed: %2 - + 키 파일 %1 불러오기 실패: %2 Remove an entry from the database. @@ -4822,11 +4855,11 @@ Available commands: Database password: - + 데이터베이스 암호: Cannot create new group - + 새 그룹을 만들 수 없음 @@ -4867,90 +4900,90 @@ Available commands: SSHAgent Agent connection failed. - + 에이전트에 연결할 수 없습니다. Agent protocol error. - + 에이전트 프로토콜 오류입니다. No agent running, cannot add identity. - + 에이전트가 실행 중이지 않아서 정보를 추가할 수 없습니다. No agent running, cannot remove identity. - + 에이전트가 실행 중이지 않아서 정보를 삭제할 수 없습니다. Agent refused this identity. Possible reasons include: - + 에이전트에서 이 정보를 거부했습니다. 가능한 이유: The key has already been added. - + 키가 이미 추가되었습니다. Restricted lifetime is not supported by the agent (check options). - + 에이전트에서 시간 제한을 지원하지 않습니다(옵션을 확인하십시오). A confirmation request is not supported by the agent (check options). - + 에이전트에서 확인 요청을 지원하지 않습니다(옵션을 확인하십시오). SearchHelpWidget Search Help - + 검색 도움말 Search terms are as follows: [modifiers][field:]["]term["] - + 다음 검색어를 사용할 수 있습니다: [수정자][필드:]["]검색어["] Every search term must match (ie, logical AND) - + 모든 검색어가 일치해야 합니다(논리곱, AND) Modifiers - + 수정자 exclude term from results - + 결과에서 검색어 제외 match term exactly - + 검색어와 정확히 일치 use regex in term - + 검색어에 정규 표현식 사용 Fields - + 필드 Term Wildcards - + 항목 와일드카드 match anything - + 모든 것과 일치 match one - + 하나와 일치 logical OR - + 논리합(OR) Examples - + 예제 @@ -4969,12 +5002,12 @@ Available commands: Search Help - + 검색 도움말 Search (%1)... Search placeholder text, %1 is the keyboard shortcut - + 검색(%1)... Case sensitive @@ -4985,31 +5018,31 @@ Available commands: SettingsWidgetKeeShare Active - + 활성 Allow export - + 내보내기 허용 Allow import - + 가져오기 허용 Own certificate - + 자가 인증서 Fingerprint: - + 지문: Certificate: - + 인증서: Signer - + 서명자 Key: @@ -5025,23 +5058,23 @@ Available commands: Export - + 내보내기 Imported certificates - + 가져온 인증서 Trust - + 신뢰 Ask - + 묻기 Untrust - + 믿지 않음 Remove @@ -5049,11 +5082,11 @@ Available commands: Path - + 경로 Status - + 상태 Fingerprint @@ -5061,28 +5094,28 @@ Available commands: Certificate - + 인증서 Trusted - + 신뢰함 Untrusted - + 신뢰하지 않음 Unknown - + 알 수 없음 key.share Filetype for KeeShare key - + key.share KeeShare key file - + KeeShare 키 파일 All files @@ -5090,38 +5123,38 @@ Available commands: Select path - + 경로 선택 Exporting changed certificate - + 변경된 인증서 내보내기 The exported certificate is not the same as the one in use. Do you want to export the current certificate? - + 내보낸 인증서가 사용 중인 인증서와 다릅니다. 현재 인증서를 내보내시겠습니까? Signer: - + 서명자: ShareObserver Import from container without signature - + 서명되지 않은 컨테이너에서 가져오기 We cannot verify the source of the shared container because it is not signed. Do you really want to import from %1? - + 공유된 컨테이너가 서명되어 있지 않아서 원본을 확인할 수 없습니다. %1에서 가져오시겠습니까? Import from container with certificate - + 서명된 컨테이너에서 가져오기 Not this time - + 지금은 하지 않음 Never @@ -5129,123 +5162,123 @@ Available commands: Always - + 항상 Just this time - + 이번 한 번 Import from %1 failed (%2) - + %1에서 가져오기 실패 (%2) Import from %1 successful (%2) - + %1에서 가져오기 성공 (%2) Imported from %1 - + %1에서 가져옴 Signed share container are not supported - import prevented - + 서명된 공유 컨테이너는 지원하지 않음 - 가져오기 중단됨 File is not readable - + 파일에서 읽을 수 없음 Invalid sharing container - + 잘못된 공유 컨테이너 Untrusted import prevented - + 신뢰할 수 없는 가져오기 중단됨 Successful signed import - + 서명된 가져오기 성공 Unexpected error - + 예상하지 못한 오류 Unsigned share container are not supported - import prevented - + 서명되지 않은 공유 컨테이너는 지원하지 않음 - 가져오기 중단됨 Successful unsigned import - + 서명되지 않은 가져오기 성공 File does not exist - + 파일이 존재하지 않음 Unknown share container type - + 알 수 없는 공유 컨테이너 형식 Overwriting signed share container is not supported - export prevented - + 서명된 공유 컨테이너에 덮어쓰기는 지원되지 않음 - 내보내기 중단됨 Could not write export container (%1) - + 내보내기 컨테이너에 기록할 수 없음 (%1) Overwriting unsigned share container is not supported - export prevented - + 서명되지 않은 공유 컨테이너에 덮어쓰기는 지원되지 않음 - 내보내기 중단됨 Could not write export container - + 내보내기 컨테이너에 기록할 수 없음 Unexpected export error occurred - + 예상하지 못한 내보내기 오류 Export to %1 failed (%2) - + %1(으)로 내보내기 실패 (%2) Export to %1 successful (%2) - + %1(으)로 내보내기 성공 (%2) Export to %1 - + %1(으)로 내보내기 Do you want to trust %1 with the fingerprint of %2 from %3? - + %3에서 온 지문이 %2인 %1을(를) 신뢰하시겠습니까? Multiple import source path to %1 in %2 - + %2의 %1(으)로 다중 가져오기 원본 경로 Conflicting export target path %1 in %2 - + %2의 내보내기 대상 경로 %1이(가) 충돌함 Could not embed signature: Could not open file to write (%1) - + 서명을 임베드할 수 없음: 쓰기 위해 파일을 열 수 없음 (%1) Could not embed signature: Could not write file (%1) - + 서명을 임베드할 수 없음: 파일에 쓸 수 없음 (%1) Could not embed database: Could not open file to write (%1) - + 데이터베이스를 임베드할 수 없음: 쓰기 위해 파일을 열 수 없음 (%1) Could not embed database: Could not write file (%1) - + 데이터베이스를 임베드할 수 없음: 파일에 쓸 수 없음 (%1) @@ -5264,7 +5297,7 @@ Available commands: Expires in <b>%n</b> second(s) - + <b>%n</b>초 후 만료됨 @@ -5276,15 +5309,15 @@ Available commands: NOTE: These TOTP settings are custom and may not work with other authenticators. TOTP QR code dialog warning - + 메모: 이 TOTP 설정은 사용자 정의 설정이며 다른 인증기에서 동작하지 않을 수도 있습니다. There was an error creating the QR code. - + QR 코드를 생성하는 중 오류가 발생했습니다. Closing in %1 seconds. - + %1초 후 닫습니다. @@ -5311,7 +5344,7 @@ Available commands: Custom Settings - + 사용자 정의 설정 Time step: @@ -5332,7 +5365,7 @@ Available commands: 7 digits - + 7자리 8 digits @@ -5343,11 +5376,11 @@ Available commands: UpdateCheckDialog Checking for updates - + 업데이트 확인 중 Checking for updates... - + 업데이트 확인 중... Close @@ -5355,39 +5388,39 @@ Available commands: Update Error! - + 업데이트 오류! An error occurred in retrieving update information. - + 업데이트 정보를 가져오는 중 오류가 발생했습니다. Please try again later. - + 나중에 다시 시도하십시오. Software Update - + 소프트웨어 업데이트 A new version of KeePassXC is available! - + KeePassXC의 새로운 버전을 사용할 수 있습니다! KeePassXC %1 is now available — you have %2. - + KeePassXC %1을(를) 사용할 수 있습니다 — 사용 중인 버전은 %2입니다. Download it at keepassxc.org - + keepassxc.org에서 다운로드 You're up-to-date! - + 최신 버전을 사용하고 있습니다! KeePassXC %1 is currently the newest version available - + KeePassXC의 현재 최신 버전은 %1입니다 @@ -5429,19 +5462,19 @@ Available commands: YubiKey Challenge-Response - + YubiKey 질의 응답 <p>If you own a <a href="https://www.yubico.com/">YubiKey</a>, you can use it for additional security.</p><p>The YubiKey requires one of its slots to be programmed as <a href="https://www.yubico.com/products/services-software/personalization-tools/challenge-response/">HMAC-SHA1 Challenge-Response</a>.</p> - + <p><a href="https://www.yubico.com/">YubiKey</a>를 가지고 있다면 추가 보안에 사용할 수 있습니다.</p><p>YubiKey 슬롯 중 하나를 <a href="https://www.yubico.com/products/services-software/personalization-tools/challenge-response/">HMAC-SHA1 Challenge-Response</a> 모드로 프로그래밍해야 합니다.</p> No YubiKey detected, please ensure it's plugged in. - + YubiKey를 찾을 수 없습니다. 연결 상태를 확인하십시오. No YubiKey inserted. - + YubiKey가 연결되지 않았습니다. \ No newline at end of file diff --git a/share/translations/keepassx_nb.ts b/share/translations/keepassx_nb.ts index 58a820a42..cdf0a12b5 100644 --- a/share/translations/keepassx_nb.ts +++ b/share/translations/keepassx_nb.ts @@ -693,7 +693,7 @@ Moved %2 keys to custom data. KeePassXC: Create a new group - + KeePassXC: Lag en ny gruppe A request for creating a new group "%1" has been received. @@ -803,7 +803,7 @@ Would you like to migrate your existing settings now? column %1 - + kolonne %1 Error(s) detected in CSV file! @@ -852,7 +852,7 @@ Would you like to migrate your existing settings now? Unable to open file %1. - + Kan ikke åpne filen %1. Error while reading the database: %1 @@ -860,7 +860,7 @@ Would you like to migrate your existing settings now? Could not save, database has no file name. - + Kunne ikke lagre, databasen har ingen filnavn. File cannot be written as it is opened in read-only mode. @@ -959,7 +959,7 @@ Vurder å opprette en ny nøkkelfil. DatabaseSettingsDialog Advanced Settings - + Avanserte Innstillinger General @@ -1056,7 +1056,7 @@ This may prevent connection to the browser plugin. Forget all site-specific settings on entries - + Glem alle side-spesifikke innstillinger og oppføringer Do you really want forget all site-specific settings on every entry? @@ -1294,7 +1294,7 @@ Dersom du beholder dette antallet så kan databasen være for lett å knekke! Breadcrumb - + Brødsmule Type @@ -1306,11 +1306,11 @@ Dersom du beholder dette antallet så kan databasen være for lett å knekke! Last Signer - + Siste Signatur Certificates - Sertifikat + Sertifikater > @@ -1355,11 +1355,11 @@ Are you sure you want to continue without a password? DatabaseSettingsWidgetMetaDataSimple Database Name: - + Databasenavn: Description: - + Beskrivelse: @@ -2043,11 +2043,11 @@ Deaktivere sikker lagring og prøve igjen? Select import source - + Velg kilde for importering Select export target - + Velg eksporteringsmål Select import/export file @@ -2153,7 +2153,7 @@ Deaktivere sikker lagring og prøve igjen? Select Image(s) - + Velg Bilde(-r) Successfully loaded %1 of %n icon(s) @@ -2382,7 +2382,7 @@ Dette kan føre til feil for de berørte programtilleggene. Created - Oppretta + Opprettet Modified @@ -2494,7 +2494,7 @@ Dette kan føre til feil for de berørte programtilleggene. Share - + Del @@ -3122,19 +3122,19 @@ Line %2, column %3 Import from - + Importer fra Export to - + Eksporter til Synchronize with - + Synkroniser med Disabled share %1 - + Deaktiver deling %1 Import from share %1 @@ -3153,7 +3153,7 @@ Line %2, column %3 KeyComponentWidget Key Component - + Nøkkelkomponent Key Component Description @@ -3170,7 +3170,7 @@ Line %2, column %3 Add %1 Add a key component - + Legg til %1 Change %1 @@ -3200,7 +3200,7 @@ Line %2, column %3 Key File - + Nøkkelfil <p>You can add a key file containing random bytes for additional security.</p><p>You must keep it secret and never lose it or you will be locked out!</p> @@ -3477,7 +3477,7 @@ Vi anbefaler at du bruker det AppImage som er tilgjengelig på nedlastingssiden. Add a new group - + Legg til ny gruppe Change master &key... @@ -3636,7 +3636,7 @@ Expect some bugs and minor issues, this version is not meant for production use. Advanced Settings - + Avanserte Innstillinger Simple Settings @@ -4351,7 +4351,7 @@ Tilgjengelige kommandoer: Created - Oppretta + Opprettet Browser Integration @@ -4586,7 +4586,7 @@ Tilgjengelige kommandoer: Unable to open file %1. - + Kan ikke åpne filen %1. Error while reading the database: @@ -4998,7 +4998,7 @@ Tilgjengelige kommandoer: Own certificate - + Egne sertifikat Fingerprint: @@ -5006,7 +5006,7 @@ Tilgjengelige kommandoer: Certificate: - + Sertifikat Signer @@ -5030,7 +5030,7 @@ Tilgjengelige kommandoer: Imported certificates - Importerte sertikikat + Importerte sertifikater Trust diff --git a/share/translations/keepassx_nl_NL.ts b/share/translations/keepassx_nl_NL.ts index 6b25466e6..3939985fc 100644 --- a/share/translations/keepassx_nl_NL.ts +++ b/share/translations/keepassx_nl_NL.ts @@ -421,7 +421,7 @@ %1 has requested access to passwords for the following item(s). Please select whether you want to allow access. - %1 vraagt toegang tot jouw wachtwoorden voor het volgende. + %1 vraagt toegang tot jouw wachtwoorden voor de volgende item(s). Geef aan of je toegang wilt verlenen of niet. @@ -611,15 +611,15 @@ Selecteer de database voor het opslaan van de inloggegevens. Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1 - + Vanwege de Snap sandboxing, moet je een script uitvoeren waarmee browser integratie mogelijk wordt. <br /> Je kunt dit script vinden op %1 Please see special instructions for browser extension use below - + Raadpleeg onderstaand speciale instructies voor gebruik van browserextensie KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3 - + KeePassXC-Browser is vereist om de integratie van de browser te laten werken. <br /> download het voor %1 en %2. %3 @@ -696,19 +696,23 @@ Moved %2 keys to custom data. KeePassXC: Create a new group - + KeePassXC: Een nieuwe groep maken A request for creating a new group "%1" has been received. Do you want to create this group? - + Een aanvraag voor het maken van een nieuwe groep '%1' werd ontvangen. +Wil je deze groep maken? + Your KeePassXC-Browser settings need to be moved into the database settings. This is necessary to maintain your current browser connections. Would you like to migrate your existing settings now? - + De KeePassXC-Browser instellingen moeten worden verplaatst naar de instellingen-database. +Dit is nodig om de huidige browser verbindingen te behouden. +Wil je de bestaande instellingen nu migreren? @@ -872,7 +876,7 @@ Would you like to migrate your existing settings now? Key not transformed. This is a bug, please report it to the developers! - + Toets niet getransformeerd. Dit is een bug, rapporteer deze alstublieft aan de ontwikkelaars! @@ -1069,7 +1073,7 @@ Hierdoor werkt de verbinding met de browser plugin mogelijk niet meer. Do you really want forget all site-specific settings on every entry? Permissions to access entries will be revoked. - Wilt u echt alle site-specifieke instellingen bij items vergeten? Machtigingen voor toegang zullen worden ingetrokken. + Wil je echt alle site-specifieke instellingen bij items vergeten? Machtigingen voor toegang zullen worden ingetrokken. Removing stored permissions… @@ -1339,7 +1343,7 @@ Als je dit aantal aanhoudt is het mogelijk heel gemakkelijk om de database te kr You must add at least one encryption key to secure your database! - Je moet minstens één coderingssleutel aan uw database toevoegen om deze te beveiligen! + Je moet minstens één coderingssleutel aan de database toevoegen om deze te beveiligen! No password set @@ -1527,7 +1531,7 @@ Wil je de wijzigingen samenvoegen? Do you really want to delete %n entry(s) for good? - Wilt u echt %n item(s) voorgoed verwijderen?Wilt u echt %n item(s) voorgoed verwijderen? + Wilt u echt %n item(s) voorgoed verwijderen?Wil je echt %n item(s) voorgoed verwijderen? Delete entry(s)? @@ -1605,7 +1609,7 @@ Veilig opslaan afschakelen en opnieuw proberen? Entry "%1" has %2 reference(s). Do you want to overwrite references with values, skip this entry, or delete anyway? - Vermelding "%1" heeft %2 reference(s). Wilt u verwijzingen vervangen door waarden, dit bericht overslaan of verwijderen toch?Item "%1" heeft %2 referentie(s). Wilt u verwijzingen vervangen door waarden, dit bericht overslaan of toch verwijderen ? + Vermelding "%1" heeft %2 reference(s). Wilt u verwijzingen vervangen door waarden, dit bericht overslaan of verwijderen toch?Item "%1" heeft %2 referentie(s). Wil je de verwijzingen vervangen door waarden, dit bericht overslaan, of toch verwijderen ? Delete group @@ -1617,7 +1621,7 @@ Veilig opslaan afschakelen en opnieuw proberen? Do you really want to move the group "%1" to the recycle bin? - Wilt u echt de groep '%1' naar de prullenbak verplaatsen? + Wil je echt de groep '%1' naar de prullenbak verplaatsen? Successfully merged the database files. @@ -1629,7 +1633,7 @@ Veilig opslaan afschakelen en opnieuw proberen? Shared group... - + Gedeelde groep... @@ -2034,7 +2038,7 @@ Veilig opslaan afschakelen en opnieuw proberen? Your KeePassXC version does not support sharing your container type. Please use %1. - Uw KeePassXC-versie biedt geen ondersteuning voor het delen van uw Containertype. Gebruik %1. + Deze KeePassXC-versie biedt geen ondersteuning voor het delen van jouw container type. Gebruik %1. Database sharing is disabled @@ -2074,15 +2078,15 @@ Veilig opslaan afschakelen en opnieuw proberen? The export container %1 is already referenced. - + Er wordt al verwezen naar export container %1. The import container %1 is already imported. - + Import container %1 is al geïmporteerd. The container %1 imported and export by different groups. - + De container %1 is geïmporteerd en geëxporteerd door verschillende groepen. @@ -3151,19 +3155,19 @@ Lijn %2, kolom %3 Disabled share %1 - + Delen uitgeschakeld %1 Import from share %1 - + Geïmporteerd van %1 Export to share %1 - + Ge-exporteerd naar %1 Synchronize with share %1 - + Synchroniseren met %1 @@ -3423,7 +3427,7 @@ Bericht: %2 Please touch the button on your YubiKey! - Druk de knop op uw YubiKey! + Druk op de knop van je YubiKey! WARNING: You are using an unstable build of KeePassXC! @@ -3554,7 +3558,7 @@ Wij raden je aan om de AppImage te gebruiken welke beschikbaar is op onze downlo NOTE: You are using a pre-release version of KeePassXC! Expect some bugs and minor issues, this version is not meant for production use. - Opmerking: U gebruikt een pre-release versie van KeePassXC! + Opmerking: Je gebruikt een pre-release versie van KeePassXC! Verwacht een aantal bugs en kleine problemen, deze versie is niet bedoeld voor productiedoeleinden. @@ -3567,7 +3571,7 @@ Verwacht een aantal bugs en kleine problemen, deze versie is niet bedoeld voor p You can always check for updates manually from the application menu. - U kunt altijd handmatig controleren op updates vanuit het programmamenu. + Je kunt altijd handmatig controleren of er updates zijn vanuit het programmamenu. @@ -4851,7 +4855,7 @@ Beschikbare opdrachten: Cannot create new group - + Kon nieuwe groep niet maken @@ -5123,11 +5127,11 @@ Beschikbare opdrachten: The exported certificate is not the same as the one in use. Do you want to export the current certificate? - Het geëxporteerde certificaat is niet hetzelfde als die in gebruik is. Wilt u het huidige certificaat exporteren? + Het geëxporteerde certificaat is niet hetzelfde als die in gebruik is. Wil je het huidige certificaat exporteren? Signer: - + Ondertekenaar: @@ -5246,31 +5250,31 @@ Beschikbare opdrachten: Do you want to trust %1 with the fingerprint of %2 from %3? - Wilt u %1 met de vingerafdruk van %2 vanaf %3 vertrouwen? {1 ?} {2 ?}  + Wil je %1 met de vingerafdruk van %2 vanaf %3 vertrouwen? {1 ?} {2 ?}  Multiple import source path to %1 in %2 - + Meerdere import bronpaden naar %1 in %2 Conflicting export target path %1 in %2 - + Conflicterende exporteerdoelpad %1 in %2 Could not embed signature: Could not open file to write (%1) - + Kon handtekening niet insluiten: Kan bestand niet openen om naar te schrijven (%1) Could not embed signature: Could not write file (%1) - + Kon handtekening niet insluiten: Kan niet schrijven naar bestand (%1) Could not embed database: Could not open file to write (%1) - + Kon database niet insluiten: Kan bestand niet openen om naar te schrijven (%1) Could not embed database: Could not write file (%1) - + Kon database niet insluiten: Kan niet schrijven naar bestand (%1) @@ -5301,7 +5305,7 @@ Beschikbare opdrachten: NOTE: These TOTP settings are custom and may not work with other authenticators. TOTP QR code dialog warning - Let op: deze TOTP-instellingen zijn op maat en werken mogelijk niet met andere authenticators. + Let op: deze TOTP-instellingen zijn applicatie specifiek en werken mogelijk niet met andere authenticators. There was an error creating the QR code. diff --git a/share/translations/keepassx_pl.ts b/share/translations/keepassx_pl.ts index ed32eff41..9bcb1f41a 100644 --- a/share/translations/keepassx_pl.ts +++ b/share/translations/keepassx_pl.ts @@ -611,15 +611,15 @@ Wybierz właściwą bazę danych do zapisania danych uwierzytelniających. Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1 - + Ze względu na sandboxing Snap należy uruchomić skrypt, aby umożliwić integrację przeglądarki.<br />Możesz uzyskać ten skrypt z %1 Please see special instructions for browser extension use below - + Zobacz poniżej specjalne instrukcje dotyczące używania rozszerzenia przeglądarki KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3 - + KeePassXC-Browser jest potrzebny do integracji przeglądarki. <br />Pobierz go dla %1 i %2. %3 @@ -696,19 +696,23 @@ Przeniesiono %2 klucze do niestandardowych danych. KeePassXC: Create a new group - + KeePassXC: Utwórz nową grupę A request for creating a new group "%1" has been received. Do you want to create this group? - + Otrzymano żądanie utworzenia nowej grupy "%1". +Czy chcesz stworzyć tę grupę? + Your KeePassXC-Browser settings need to be moved into the database settings. This is necessary to maintain your current browser connections. Would you like to migrate your existing settings now? - + Twoje ustawienia KeePassXC-Browser należy przenieść do ustawień bazy danych. +Jest to konieczne, aby utrzymać bieżące połączenia przeglądarki. +Czy chcesz teraz migrować istniejące ustawienia? @@ -872,7 +876,7 @@ Would you like to migrate your existing settings now? Key not transformed. This is a bug, please report it to the developers! - + Klucz nie został przekształcony. To jest błąd, zgłoś go deweloperom! @@ -1631,7 +1635,7 @@ Wyłączyć bezpieczne zapisywanie i spróbować ponownie? Shared group... - + Grupa współdzielona... @@ -2076,15 +2080,15 @@ Wyłączyć bezpieczne zapisywanie i spróbować ponownie? The export container %1 is already referenced. - + Odwołanie do kontenera eksportu %1 już istnieje. The import container %1 is already imported. - + Kontener importu %1 jest już zaimportowany. The container %1 imported and export by different groups. - + Kontener %1 importowany i eksportowany przez różne grupy. @@ -3157,19 +3161,19 @@ Wiersz %2, kolumna %3 Disabled share %1 - + Wyłączony udział %1 Import from share %1 - + Importuj z udziału %1 Export to share %1 - + Eksportuj do udziału %1 Synchronize with share %1 - + Synchronizuj z udziałem %1 @@ -4858,7 +4862,7 @@ Dostępne polecenia: Cannot create new group - + Nie można utworzyć nowej grupy @@ -5134,7 +5138,7 @@ Dostępne polecenia: Signer: - + Podpisujący: @@ -5257,27 +5261,27 @@ Dostępne polecenia: Multiple import source path to %1 in %2 - + Wiele ścieżek źródłowych importu do %1 w %2 Conflicting export target path %1 in %2 - + Sprzeczna ścieżka docelowa eksportu %1 w %2 Could not embed signature: Could not open file to write (%1) - + Nie można osadzić podpisu: Nie można otworzyć pliku do zapisu (%1) Could not embed signature: Could not write file (%1) - + Nie można osadzić podpisu: Nie można zapisać pliku (%1) Could not embed database: Could not open file to write (%1) - + Nie można osadzić bazy danych: Nie można otworzyć pliku do zapisu (%1) Could not embed database: Could not write file (%1) - + Nie można osadzić bazy danych: nie można zapisać pliku (%1) diff --git a/share/translations/keepassx_pt.ts b/share/translations/keepassx_pt.ts index 71df82a7b..c2aad239c 100644 --- a/share/translations/keepassx_pt.ts +++ b/share/translations/keepassx_pt.ts @@ -611,15 +611,15 @@ Selecione a base de dados correta para guardar as credenciais. Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1 - + Devido a 'Snap sandboxing', tem que executar um script para ativar a integração com o navegador.<br />Pode obter este script em %1. Please see special instructions for browser extension use below - + Por favor consulte as instruções para a utilização da extensão abaixo KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3 - + Necessita do KeePassXC-Browser para que a integração funcione corretamente.<br />Pode descarregar para %1 e para %2. %3 @@ -696,19 +696,23 @@ Moved %2 keys to custom data. KeePassXC: Create a new group - + KeePassXC: criar um novo grupo A request for creating a new group "%1" has been received. Do you want to create this group? - + Foi recebido um pedido para a criação do grupo "%1". +Quer criar este grupo? + Your KeePassXC-Browser settings need to be moved into the database settings. This is necessary to maintain your current browser connections. Would you like to migrate your existing settings now? - + Tem que mover as suas definições do KeePassXC-Browser para as definições da base de dados. +Este procedimento é necessário para manter as ligações existentes. +Quer migrar as definições agora? @@ -872,7 +876,7 @@ Would you like to migrate your existing settings now? Key not transformed. This is a bug, please report it to the developers! - + Chave não transformada. Isto é um erro e deve ser reportado aos programadores! @@ -1631,7 +1635,7 @@ Desativar salvaguardas e tentar novamente? Shared group... - + Grupo partilhado... @@ -2077,11 +2081,11 @@ Por favor utilize %1. The export container %1 is already referenced. - + O contentor de exportação %1 já está referenciado. The import container %1 is already imported. - + O contentor de importação %1 já está referenciado. The container %1 imported and export by different groups. @@ -3156,19 +3160,19 @@ Linha %2, coluna %3 Disabled share %1 - + Desativar partilha %1 Import from share %1 - + Importar da partilha %1 Export to share %1 - + Exportar para a partilha %1 Synchronize with share %1 - + Sincronizar com a partilha %1 @@ -4858,7 +4862,7 @@ Comandos disponíveis: Cannot create new group - + Não foi possível criar o novo grupo @@ -5134,7 +5138,7 @@ Comandos disponíveis: Signer: - + Signatário: @@ -5257,27 +5261,27 @@ Comandos disponíveis: Multiple import source path to %1 in %2 - + Diversos caminhos de importação para %1 em %2 Conflicting export target path %1 in %2 - + Conflito no caminho de exportação para %1 em %2 Could not embed signature: Could not open file to write (%1) - + Assinatura não incorporada. Não foi possível abrir o ficheiro para escrita (%1) Could not embed signature: Could not write file (%1) - + Assinatura não incorporada. Não foi possível escrever no ficheiro (%1) Could not embed database: Could not open file to write (%1) - + Base de dados não incorporada. Não foi possível abrir o ficheiro para escrita (%1) Could not embed database: Could not write file (%1) - + Base de dados não incorporada. Não foi possível escrever no ficheiro (%1) diff --git a/share/translations/keepassx_pt_BR.ts b/share/translations/keepassx_pt_BR.ts index 3199b21e0..a7a7e4732 100644 --- a/share/translations/keepassx_pt_BR.ts +++ b/share/translations/keepassx_pt_BR.ts @@ -611,15 +611,15 @@ Por favor, selecione o banco de dados correto para salvar as credenciais. Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1 - + Devido ao sandbox do Snap, você deve executar um script para ativar a integração do navegador.<br />Você pode obter este script de %1 Please see special instructions for browser extension use below - + Por favor, veja as instruções especiais para o uso da extensão do navegador abaixo KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3 - + O KeePassXC-Browser é necessário para que a integração do navegador funcione. <br />Faça o download para %1 e %2. %3 @@ -695,19 +695,23 @@ Movido %2 chaves para dados personalizados. KeePassXC: Create a new group - + KeePassXC: Crie um novo grupo A request for creating a new group "%1" has been received. Do you want to create this group? - + Um pedido para criar um novo grupo "%1" foi recebido. +Você quer criar este grupo? + Your KeePassXC-Browser settings need to be moved into the database settings. This is necessary to maintain your current browser connections. Would you like to migrate your existing settings now? - + As configurações do seu navegador KeePassXC precisam ser movidas para as configurações do banco de dados. +Isso é necessário para manter as conexões atuais do navegador. +Gostaria de migrar suas configurações existentes agora? @@ -813,7 +817,7 @@ Would you like to migrate your existing settings now? [%n more message(s) skipped] - + [%n mais mensagem(ns) ignoradas][%n mais mensagem(ns) ignoradas] CSV import: writer has errors: @@ -871,7 +875,7 @@ Would you like to migrate your existing settings now? Key not transformed. This is a bug, please report it to the developers! - + Chave não transformada. Este é um bug, por favor denuncie para os desenvolvedores! @@ -999,11 +1003,11 @@ Por favor, considere-se gerar um novo arquivo de chave. Forg&et all site-specific settings on entries - + Esq&uecer todas as configurações específicas do site nas entradas Move KeePassHTTP attributes to KeePassXC-Browser &custom data - + Mover os atributos do KeePassHTTP para o KeePassXC-Browser &dados personalizados Stored keys @@ -1068,7 +1072,8 @@ Isso pode impedir a conexão com o plugin do navegador. Do you really want forget all site-specific settings on every entry? Permissions to access entries will be revoked. - + Você realmente quer esquecer todas as configurações específicas do site em cada entrada? +Permissões para acessar entradas serão revogadas. Removing stored permissions… @@ -1084,7 +1089,7 @@ Permissions to access entries will be revoked. Successfully removed permissions from %n entry(s). - + Permissões removidas com sucesso de %n entrada(s).Permissões removidas com sucesso de %n entrada(s). KeePassXC: No entry with permissions found! @@ -1101,7 +1106,8 @@ Permissions to access entries will be revoked. Do you really want to move all legacy browser integration data to the latest standard? This is necessary to maintain compatibility with the browser plugin. - + Você realmente deseja mover todos os dados de integração do navegador herdados para o padrão mais recente? +Isso é necessário para manter a compatibilidade com o plugin do navegador. @@ -1160,7 +1166,7 @@ This is necessary to maintain compatibility with the browser plugin. Higher values offer more protection, but opening the database will take longer. - + Valores mais altos oferecem mais proteção, mas a abertura do banco de dados levará mais tempo. Database format: @@ -1313,7 +1319,7 @@ Se você manter este número, seu banco de dados pode ser facilmente crackeado!< Last Signer - + Último Signatário Certificates @@ -1566,7 +1572,8 @@ Salvar alterações? Could not open the new database file while attempting to autoreload. Error: %1 - + Não foi possível abrir o novo arquivo de banco de dados ao tentar executar o carregamento automático. +Erro: %1 Disable safe saves? @@ -1581,7 +1588,8 @@ Deseja desabilitar salvamento seguro e tentar novamente? Writing the database failed. %1 - + Escrevendo o banco de dados falhou. +%1 Passwords @@ -1625,7 +1633,7 @@ Deseja desabilitar salvamento seguro e tentar novamente? Shared group... - + Grupo compartilhado... @@ -2168,7 +2176,7 @@ Deseja desabilitar salvamento seguro e tentar novamente? Successfully loaded %1 of %n icon(s) - + Carregado com sucesso %1 de %n ícone(s)Carregado com sucesso %1 de %n ícone(s) No icons were loaded @@ -3124,7 +3132,7 @@ Linha %2, coluna %3 unable to seek to content position - + incapaz de buscar a posição de conteúdo @@ -3147,19 +3155,19 @@ Linha %2, coluna %3 Disabled share %1 - + Desabilitar compartilhamento %1 Import from share %1 - + Importar do compartilhamento %1 Export to share %1 - + Exportar para compartilhamento %1 Synchronize with share %1 - + Sincronizar com compartilhamento %1 @@ -3178,7 +3186,7 @@ Linha %2, coluna %3 Key Component set, click to change or remove - + Componente Chave definido, clique para alterar ou remover Add %1 @@ -3615,11 +3623,11 @@ Espere alguns bugs e problemas menores, esta versão não é para uso em produç Changed deleted objects - + Objetos excluídos alterados Adding missing icon %1 - + Adicionando ícone ausente %1 @@ -3805,7 +3813,7 @@ Espere alguns bugs e problemas menores, esta versão não é para uso em produç <p>A password is the primary method for securing your database.</p><p>Good passwords are long and unique. KeePassXC can generate one for you.</p> - + <p>Uma senha é o principal método para proteger seu banco de dados.</p><p>Boas senhas são longas e únicas. KeePassXC pode gerar uma para você.</p> Passwords do not match. @@ -4447,7 +4455,7 @@ Comandos disponíveis: Entry's password copied to the clipboard! - + Entrada da senha copiada para a área de transferência! Clearing the clipboard in %1 second(s)... @@ -4646,11 +4654,11 @@ Comandos disponíveis: Exclude similar looking characters - + Excluir caracteres parecidos Include characters from every selected group - + Incluir caracteres de cada grupo selecionado Recursively list the elements of the group. @@ -4741,7 +4749,7 @@ Comandos disponíveis: Message encryption failed. - + Criptografia de mensagens falhou. No groups found @@ -4753,7 +4761,7 @@ Comandos disponíveis: File %1 already exists. - + Arquivo %1 já existe. Loading the key file failed @@ -4841,7 +4849,7 @@ Comandos disponíveis: Cannot create new group - + Não é possível criar um novo grupo @@ -4906,11 +4914,11 @@ Comandos disponíveis: Restricted lifetime is not supported by the agent (check options). - + Vida útil limitada não é suportado pelo agente (verificar opções). A confirmation request is not supported by the agent (check options). - + Uma solicitação de confirmação não é suportado pelo agente (verificar opções). @@ -4921,7 +4929,7 @@ Comandos disponíveis: Search terms are as follows: [modifiers][field:]["]term["] - + Termos de pesquisa são as seguintes: [modifiers][field:]["]term["] Every search term must match (ie, logical AND) @@ -5024,7 +5032,7 @@ Comandos disponíveis: Signer - + Signatário Key: @@ -5093,11 +5101,11 @@ Comandos disponíveis: key.share Filetype for KeeShare key - + key.share KeeShare key file - + Arquivo chave KeeShare All files @@ -5117,7 +5125,7 @@ Comandos disponíveis: Signer: - + Signatário: @@ -5152,11 +5160,11 @@ Comandos disponíveis: Import from %1 failed (%2) - + Importação de %1 falhou (%2) Import from %1 successful (%2) - + Importado de %1 com sucesso (%2) Imported from %1 @@ -5444,11 +5452,11 @@ Comandos disponíveis: YubiKey Challenge-Response - + YubiKey Desafio-Resposta <p>If you own a <a href="https://www.yubico.com/">YubiKey</a>, you can use it for additional security.</p><p>The YubiKey requires one of its slots to be programmed as <a href="https://www.yubico.com/products/services-software/personalization-tools/challenge-response/">HMAC-SHA1 Challenge-Response</a>.</p> - + <p>Se você possui uma <a href="https://www.yubico.com/">YubiKey</a>, você pode usá-la para segurança adicional.</p><p>A YubiKey requer que um de seus slots seja programado como <a href="https://www.yubico.com/products/services-software/personalization-tools/challenge-response/">HMAC-SHA1 Desafio-Resposta</a>.</p> No YubiKey detected, please ensure it's plugged in. diff --git a/share/translations/keepassx_pt_PT.ts b/share/translations/keepassx_pt_PT.ts index 5e2014fc8..1c264b06f 100644 --- a/share/translations/keepassx_pt_PT.ts +++ b/share/translations/keepassx_pt_PT.ts @@ -54,7 +54,7 @@ Use OpenSSH for Windows instead of Pageant - Utilizar OpeSSH for Windows em vez de Pageant + Utilizar OpenSSH for Windows em vez de Pageant @@ -120,7 +120,7 @@ Load previous databases on startup - Ao iniciar, carregar as últimas base de dados utilizadas + Ao iniciar, carregar últimas base de dados utilizadas Minimize window at application startup @@ -512,12 +512,12 @@ Selecione a base de dados correta para guardar as credenciais. Sort &matching credentials by title Credentials mean login data requested via browser extension - Ordenar credenciais coi&ncidentes por título + Ordenar por título as credenciais coi&ncidentes Sort matching credentials by &username Credentials mean login data requested via browser extension - Ordenar credenciais coincidentes por nome de &utilizador + Ordenar por nome de &utilizador as credenciais coincidentes Advanced @@ -611,15 +611,15 @@ Selecione a base de dados correta para guardar as credenciais. Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1 - + Devido a 'Snap sandboxing', tem que executar um script para ativar a integração com o navegador.<br />Pode obter este script em %1. Please see special instructions for browser extension use below - + Por favor consulte as instruções para a utilização da extensão abaixo KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3 - + Necessita de KeePassXC-Browser para que a integração funcione corretamente.<br />Pode descarregar para %1 e %2. %3 @@ -696,19 +696,23 @@ Moved %2 keys to custom data. KeePassXC: Create a new group - + KeePassXC: Criar um novo grupo A request for creating a new group "%1" has been received. Do you want to create this group? - + Foi recebido um pedido para a criação do grupo "%1". +Deseja criar este grupo? + Your KeePassXC-Browser settings need to be moved into the database settings. This is necessary to maintain your current browser connections. Would you like to migrate your existing settings now? - + Tem que mover as suas definições KeePassXC-Browser para as definições da base de dados. +Este procedimento é necessário para manter as ligações existentes. +Gostaria de migrar agora as definições? @@ -872,7 +876,7 @@ Would you like to migrate your existing settings now? Key not transformed. This is a bug, please report it to the developers! - + Chave não transformada. Isto é um erro e deve ser reportado aos programadores! @@ -1631,7 +1635,7 @@ Desativar salvaguardas e tentar novamente? Shared group... - + Grupo partilhado... @@ -2077,15 +2081,15 @@ Por favor utilize %1. The export container %1 is already referenced. - + O contentor de exportação %1 já está referenciado. The import container %1 is already imported. - + O contentor de importação %1 já está referenciado. The container %1 imported and export by different groups. - + Erro ao exportar. A partilha %1 está a ser importada por outro grupo. @@ -2869,7 +2873,7 @@ Esta é uma migração unidirecional. Não será possível abrir a base de dados Invalid group icon number - Número inválido de ícone de grupo + Número inválido no ícone de grupo Invalid EnableAutoType value @@ -3017,7 +3021,7 @@ Linha %2, coluna %3 Invalid transform seed size - Tamanho inválido da semente de transformação + Tamanho inválido na semente de transformação Invalid number of transform rounds @@ -3156,19 +3160,19 @@ Linha %2, coluna %3 Disabled share %1 - + Desativar partilha %1 Import from share %1 - + Importar da partilha %1 Export to share %1 - + Exportar para a partilha %1 Synchronize with share %1 - + Sincronizar com a partilha %1 @@ -3639,7 +3643,7 @@ Pode encontrar erros graves e esta versão não deve ser utilizada em ambientes NewDatabaseWizard Create a new KeePassXC database... - A criar uma nova base de dados do KeePassXC... + Criar uma nova base de dados do KeePassXC... Root @@ -3659,7 +3663,7 @@ Pode encontrar erros graves e esta versão não deve ser utilizada em ambientes Here you can adjust the database encryption settings. Don't worry, you can change them later in the database settings. - Aqui pode ajustar as definições de cifra da sua base de dados. Não se preocupe porque pode sempre reverter as alterações nas definições. + Aqui pode ajustar as definições de cifra da sua base de dados. Não se preocupe porque, a qualquer momento, poderá alterar esta opção nas definições da base de dados. Advanced Settings @@ -3678,7 +3682,7 @@ Pode encontrar erros graves e esta versão não deve ser utilizada em ambientes Here you can adjust the database encryption settings. Don't worry, you can change them later in the database settings. - Aqui pode ajustar as definições de cifra da sua base de dados. Não se preocupe porque pode sempre reverter as alterações nas definições. + Aqui pode ajustar as definições de cifra da sua base de dados. Não se preocupe porque, a qualquer momento, poderá alterar esta opção nas definições da base de dados. @@ -4858,7 +4862,7 @@ Comandos disponíveis: Cannot create new group - + Não foi possível criar o novo grupo @@ -5110,7 +5114,7 @@ Comandos disponíveis: key.share Filetype for KeeShare key - partilha da chave + chave.partilha KeeShare key file @@ -5134,7 +5138,7 @@ Comandos disponíveis: Signer: - + Signatário: @@ -5233,7 +5237,7 @@ Comandos disponíveis: Could not write export container - Não foi possível escrever contentor de exportação + Não foi possível escrever o contentor de exportação Unexpected export error occurred @@ -5257,27 +5261,27 @@ Comandos disponíveis: Multiple import source path to %1 in %2 - + Diversos caminhos de importação para %1 em %2 Conflicting export target path %1 in %2 - + Conflito no caminho de exportação para %1 em %2 Could not embed signature: Could not open file to write (%1) - + Assinatura não incorporada. Não foi possível abrir o ficheiro para escrita (%1) Could not embed signature: Could not write file (%1) - + Assinatura não incorporada. Não foi possível escrever no ficheiro (%1) Could not embed database: Could not open file to write (%1) - + Base de dados não incorporada. Não foi possível abrir o ficheiro para escrita (%1) Could not embed database: Could not write file (%1) - + Base de dados não incorporada. Não foi possível escrever no ficheiro (%1) diff --git a/share/translations/keepassx_ru.ts b/share/translations/keepassx_ru.ts index 10b78f00d..fbada2f71 100644 --- a/share/translations/keepassx_ru.ts +++ b/share/translations/keepassx_ru.ts @@ -176,7 +176,7 @@ Hide toolbar (icons) - Скрыть панель инструментов (иконки) + Скрывать панель инструментов (значки) Minimize instead of app exit @@ -611,15 +611,15 @@ Please select the correct database for saving credentials. Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1 - + Из-за того, что Snap - это песочница, Вы должны запустить скрипт, чтобы разрешить браузерную интеграцию.<br />Вы можете получить этот скрипт с %1 Please see special instructions for browser extension use below - + Пожалуйста, смотрите особые инструкции по использованию расширения браузера ниже KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3 - + KeePassXC-Browser необходим для работы интеграции браузера. <br />Скачайте его для %1 и %2. %3 @@ -696,19 +696,23 @@ Moved %2 keys to custom data. KeePassXC: Create a new group - + KeePassXC: Создать новую группу A request for creating a new group "%1" has been received. Do you want to create this group? - + Был получен запрос для создания новой группы "%1". +Вы хотите создать эту группу? + Your KeePassXC-Browser settings need to be moved into the database settings. This is necessary to maintain your current browser connections. Would you like to migrate your existing settings now? - + Нужно переместить Ваши настройки KeePassXC-Browser в настройки базы данных. +Это необходимо, чтобы поддерживать Ваши текущие соединения браузера. +Желаете ли Вы мигрировать Ваши существующие настройки сейчас? @@ -871,7 +875,7 @@ Would you like to migrate your existing settings now? Key not transformed. This is a bug, please report it to the developers! - + Ключ не преобразован. Это ошибка, пожалуйста, сообщите о нём разработчикам! @@ -1629,7 +1633,7 @@ Disable safe saves and try again? Shared group... - + Общая группа... @@ -2074,15 +2078,15 @@ Disable safe saves and try again? The export container %1 is already referenced. - + На контейнер экспорта %1 уже есть ссылка. The import container %1 is already imported. - + Контейнер импорта %1 уже импортирован. The container %1 imported and export by different groups. - + Контейнер %1 импортируется и экспортируется разными группами. @@ -2160,7 +2164,7 @@ Disable safe saves and try again? Custom icon successfully downloaded - Пользовательская иконка успешно загружена + Пользовательский значок успешно загружен Hint: You can enable DuckDuckGo as a fallback under Tools>Settings>Security @@ -2172,7 +2176,7 @@ Disable safe saves and try again? Successfully loaded %1 of %n icon(s) - Успешно загружено %1 из %n иконкиУспешно загружено %1 из %n иконокУспешно загружено %1 из %n иконокУспешно загружено %1 из %n иконки(ок) + Успешно загружен %1 из %n значкаУспешно загружены %1 из %n значковУспешно загружены %1 из %n значковУспешно загружены %1 из %n значков No icons were loaded @@ -2180,15 +2184,15 @@ Disable safe saves and try again? %n icon(s) already exist in the database - %n иконка уже существует в базе данных%n иконки уже существуют в базе данных%n иконок уже существуют в базе данных%n иконка(ок) уже существует(ют) в базе данных + %n значок уже существует в базе данных%n значка уже существуют в базе данных%n значков уже существуют в базе данных%n значков уже существуют в базе данных The following icon(s) failed: - Следующие иконки не удалось:Следующие иконки не удалось:Следующие иконки не удалось:Следующие иконки не удалось: + Следующий значок потерпел неудачу:Следующие значки потерпели неудачу:Следующие значки потерпели неудачу:Следующие значки потерпели неудачу: This icon is used by %n entry(s), and will be replaced by the default icon. Are you sure you want to delete it? - Эта иконка используется %n записью и будет замещена иконкой по умолчанию. Вы уверены, что хотите удалить её?Эта иконка используется %n записями и будет замещена иконкой по умолчанию. Вы уверены, что хотите удалить её?Эта иконка используется %n записями и будет замещена иконкой по умолчанию. Вы уверены, что хотите удалить её?Эта иконка используется %n записью(ями) и будет замещена иконкой по умолчанию. Вы уверены, что хотите удалить её? + Этот значок используется %n записью и будет замещён значком по умолчанию. Вы уверены, что хотите удалить его?Этот значок используется %n записями и будет замещён значком по умолчанию. Вы уверены, что хотите удалить его?Этот значок используется %n записями и будет замещён значком по умолчанию. Вы уверены, что хотите удалить его?Этот значок используется %n записями и будет замещён значком по умолчанию. Вы уверены, что хотите удалить его? @@ -3154,19 +3158,19 @@ Line %2, column %3 Disabled share %1 - + Отключённая часть %1 Import from share %1 - + Импортировать из части %1 Export to share %1 - + Экспортировать в часть %1 Synchronize with share %1 - + Синхронизировать с частью %1 @@ -3629,7 +3633,7 @@ Expect some bugs and minor issues, this version is not meant for production use. Adding missing icon %1 - Добавление отсутствующей иконки %1 + Добавление отсутствующего значка %1 @@ -4855,7 +4859,7 @@ Available commands: Cannot create new group - + Не удаётся создать новую группу @@ -5131,7 +5135,7 @@ Available commands: Signer: - + Подписавшийся: @@ -5254,27 +5258,27 @@ Available commands: Multiple import source path to %1 in %2 - + Множественный путь источника импорта к %1 в %2 Conflicting export target path %1 in %2 - + Конфликтный путь цели экспорта %1 в %2 Could not embed signature: Could not open file to write (%1) - + Не удалось встроить подпись: Не удалось открыть файл для записи (%1) Could not embed signature: Could not write file (%1) - + Не удалось встроить подпись: Не удалось записать файл (%1) Could not embed database: Could not open file to write (%1) - + Не удалось встроить базу данных: Не удалось открыть файл для записи (%1) Could not embed database: Could not write file (%1) - + Не удалось встроить базу данных: Не удалось записать файл (%1) diff --git a/share/translations/keepassx_sk.ts b/share/translations/keepassx_sk.ts index 450f50f42..50de22846 100644 --- a/share/translations/keepassx_sk.ts +++ b/share/translations/keepassx_sk.ts @@ -93,7 +93,7 @@ Follow style - + Štýl nasledovania @@ -168,7 +168,7 @@ Hide the entry preview panel - + Skryť panel náhľadu položky General @@ -269,11 +269,11 @@ min - + min Forget TouchID after inactivity of - + Zabudnúť TouchID po neaktivite dlhšej ako Convenience @@ -285,7 +285,7 @@ Forget TouchID when session is locked or lid is closed - + Zabudnúť TouchID po neaktivite dlhšej ako Lock databases after minimizing the window @@ -429,7 +429,7 @@ Prosím, zvoľte, či chcete povoliť prístup. BrowserEntrySaveDialog KeePassXC-Browser Save Entry - + KeePassXC-Browser Uložiť položku Ok @@ -611,15 +611,15 @@ Prosím, vyberte správnu databázu na uloženie prihlasovacích údajov. Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1 - + Kvôli ochrane Snap v sandboxe, musíte na povolenie integrácie prehliadača spustiť skript.<br />Skript môžete získať z %1 Please see special instructions for browser extension use below - + Prosím, pozrite si špeciálne inštrukcie na použite integrácie prehliadača nižšie KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3 - + KeePassXC-Browser je potrebný aby fungovala integrácia s prehliadačom<br /> Stiahnite ho pre %1 a %2. %3 @@ -649,7 +649,7 @@ zadajte mu jedinečný názov na identifikáciu a potvrďte ho. A shared encryption key with the name "%1" already exists. Do you want to overwrite it? - Zdiľaný šifrovací kľúč s menom „%1” už existuje. + Zdieľaný šifrovací kľúč s menom „%1” už existuje. Chcete ho prepísať? @@ -666,48 +666,53 @@ Chcete ho prepísať? Converting attributes to custom data… - + Konvertovanie atribútov na vlastné dáta… KeePassXC: Converted KeePassHTTP attributes - + KeePassXC: Konvertované atribúty KeePassHTTP Successfully converted attributes from %1 entry(s). Moved %2 keys to custom data. - + Úspešne skonvertované atribúty z %1 položky(iek). +Do vlastných dát presunuté %2 kľúče. Successfully moved %n keys to custom data. - + Úspešne presunutý %n kľúč do vlastných dát.Úspešne presunuté %n kľúče do vlastných dát.Úspešne presunutých %n kľúčov do vlastných dát.Úspešne presunutých %n kľúčov do vlastných dát. KeePassXC: No entry with KeePassHTTP attributes found! - + KeePassXC: Nenájdená žiadna položka s atribútmi KeePassHTTP! The active database does not contain an entry with KeePassHTTP attributes. - + Aktívna databáza neobsahuje žiadnu položku s atribútmi KeePassHTTP. KeePassXC: Legacy browser integration settings detected - + KeePassXC: Zistené staré nastavenia integrácie prehliadača KeePassXC: Create a new group - + KeePassXC: Vytvoriť novú skupinu A request for creating a new group "%1" has been received. Do you want to create this group? - + Bola prijatá požiadavka n novú skupinu „%1”. +Chcete vytvoriť túto skupinu? + Your KeePassXC-Browser settings need to be moved into the database settings. This is necessary to maintain your current browser connections. Would you like to migrate your existing settings now? - + Je potrebné presunúť vaše nastavenia KeePassXC-Browser do nastavenia databázovy. +Je to potrebné kvôli správe aktuálnych pripojení prehliadača. +Chcete teraz migrovať svoje nastavenia? @@ -813,12 +818,13 @@ Would you like to migrate your existing settings now? [%n more message(s) skipped] - + [%n ďalšia správa preskočená][%n ďalšie správy preskočené[%n ďalších správ preskočených][%n ďalších správ preskočených] CSV import: writer has errors: %1 - + Import CSV: chyby zápisu: +%1 @@ -838,7 +844,7 @@ Would you like to migrate your existing settings now? %n row(s) - + %n riadok%n riadky%n riadkov%n riadkov @@ -866,18 +872,18 @@ Would you like to migrate your existing settings now? File cannot be written as it is opened in read-only mode. - + Do súboru nemožno zapisovať, pretože je otvorený v režime len na čítanie. Key not transformed. This is a bug, please report it to the developers! - + Kľúč nebol transformovaný. Je to chyba, prosím, nahláste ju vývojárom! DatabaseOpenDialog Unlock Database - KeePassXC - + Odomknúť databázu – KeePassXC @@ -938,17 +944,19 @@ Prosím, zvážte vygenerovanie nového súboru kľúča. TouchID for quick unlock - + TouchID na rýchle odomknutie Unable to open the database: %1 - + Nemožno otvoriť databázu: +%1 Can't open key file: %1 - + Nemožno otvoriť súbor kľúča: +%1 @@ -962,7 +970,7 @@ Prosím, zvážte vygenerovanie nového súboru kľúča. DatabaseSettingsDialog Advanced Settings - + Pokročilé nastavenia General @@ -989,7 +997,7 @@ Prosím, zvážte vygenerovanie nového súboru kľúča. DatabaseSettingsWidgetBrowser KeePassXC-Browser settings - + Nastavenia KeePassXC-Browser &Disconnect all browsers @@ -997,11 +1005,11 @@ Prosím, zvážte vygenerovanie nového súboru kľúča. Forg&et all site-specific settings on entries - + Zabudnúť všetky nastavenia &stránok vo všetkých položkách Move KeePassHTTP attributes to KeePassXC-Browser &custom data - + Presunúť atribúty KeePassHTTP do vlastný&ch dát KeePassXC-Browser Stored keys @@ -1057,7 +1065,7 @@ Môže to brániť pripojeniu zásuvného modulu prehliadača. Successfully removed %n encryption key(s) from KeePassXC settings. - + Úspešne odstránený %n šifrovací kľúč z nastavení KeePassXC.Úspešne odstránené %n šifrovacie kľúče z nastavení KeePassXC.Úspešne odstránených %n šifrovacích kľúčov z nastavení KeePassXC.Úspešne odstránených %n šifrovacích kľúčov z nastavení KeePassXC. Forget all site-specific settings on entries @@ -1066,7 +1074,8 @@ Môže to brániť pripojeniu zásuvného modulu prehliadača. Do you really want forget all site-specific settings on every entry? Permissions to access entries will be revoked. - + Naozaj chcete zabudnúť všetky nastavenia stránok v každej položke? +Povolenia na prístup k položkám budú odvolané. Removing stored permissions… @@ -1082,7 +1091,7 @@ Permissions to access entries will be revoked. Successfully removed permissions from %n entry(s). - + Úspešne odstránené povolenia z %n položky.Úspešne odstránené povolenia z %n položiek.Úspešne odstránené povolenia z %n položiek.Úspešne odstránené povolenia z %n položky. KeePassXC: No entry with permissions found! @@ -1094,12 +1103,13 @@ Permissions to access entries will be revoked. Move KeePassHTTP attributes to custom data - + Presunúť atribúty KeePassHTTP do vlastných dát Do you really want to move all legacy browser integration data to the latest standard? This is necessary to maintain compatibility with the browser plugin. - + Naozaj chcete presunúť všetky staré dáta integrácie prehliadača do najnovšej normy? +Je to potrebné kvôli udržaniu kompatibility so zásuvným modulom prehliadača. @@ -1142,7 +1152,7 @@ This is necessary to maintain compatibility with the browser plugin. ?? s - + ?? s Change @@ -1231,7 +1241,7 @@ Ak ponecháte toto číslo, môže byť prelomenie ochrany databázy príliš je thread(s) Threads for parallel execution (KDF settings) - + vláknovláknavlákien vlákien %1 ms @@ -1311,7 +1321,7 @@ Ak ponecháte toto číslo, môže byť prelomenie ochrany databázy príliš je Last Signer - + Naposledy podpísal Certificates @@ -1327,25 +1337,27 @@ Ak ponecháte toto číslo, môže byť prelomenie ochrany databázy príliš je DatabaseSettingsWidgetMasterKey Add additional protection... - + Pridať dodatočné zabezpečenie… No encryption key added - + Nie je pridaný šifrovací kľúč You must add at least one encryption key to secure your database! - + Na zabezpečenie svojej databázy musíte pridať aspoň jeden šifrovací kľúč! No password set - + Nie je nastavené heslo WARNING! You have not set a password. Using a database without a password is strongly discouraged! Are you sure you want to continue without a password? - + UPOZORNENIE! Nenastavili iste heslo. Použitie databázy bez hesla dôrazne neodporúčame! + +Naozaj chcete pokračovať bez hesla? Unknown error @@ -1353,7 +1365,7 @@ Are you sure you want to continue without a password? Failed to change master key - + Zlyhala zmena hlavného kľúča @@ -1412,11 +1424,12 @@ Are you sure you want to continue without a password? The created database has no key or KDF, refusing to save it. This is definitely a bug, please report it to the developers. - + Vytvorená databáza nemá kľúča alebo KDF, jej uloženie je odmietnuté. +Toto je určite chyba, prosím nahláste ju vývojárom. The database file does not exist or is not accessible. - + Súbor databázy neexistuje alebo nie je dostupný. Select CSV file @@ -1520,15 +1533,15 @@ Chcete zlúčiť svoje zmeny? Do you really want to delete %n entry(s) for good? - + Naozaj chcete natrvalo odstrániť %n položku?Naozaj chcete natrvalo odstrániť %n položky?Naozaj chcete natrvalo odstrániť %n položiek?Naozaj chcete natrvalo odstrániť %n položky? Delete entry(s)? - + Odstrániť položku?Odstrániť položky?Odstrániť položky?Odstrániť položky? Move entry(s) to recycle bin? - + Presunúť položku do koša?Presunúť položky do koša?Presunúť položky do koša?Presunúť položky do koša? File opened in read only mode. @@ -1540,7 +1553,7 @@ Chcete zlúčiť svoje zmeny? You are editing an entry. Discard changes and lock anyway? - + Upravujete položku. Zahodiť zmeny a zamknúť napriek tomu? "%1" was modified. @@ -1551,7 +1564,8 @@ Uložiť zmeny? Database was modified. Save changes? - + Databáza bola zmenená. +Uložiť zmeny? Save changes? @@ -1560,7 +1574,8 @@ Save changes? Could not open the new database file while attempting to autoreload. Error: %1 - + Nemožno otvoriť nový databázový súbor počas pokusu o automatické opätovné načítanie. +Chyba: %1 Disable safe saves? @@ -1575,7 +1590,8 @@ Vypnúť bezpečné ukladanie a skúsiť znova? Writing the database failed. %1 - + Zapisovanie do databázy zlyhalo. +%1 Passwords @@ -1591,35 +1607,35 @@ Vypnúť bezpečné ukladanie a skúsiť znova? Replace references to entry? - + Nahradiť existujúcu položku? Entry "%1" has %2 reference(s). Do you want to overwrite references with values, skip this entry, or delete anyway? - + Položka „%1” má %2 odkaz. Chcete prepísať odkazy hodnotami, preskočiť túto položku alebo ju i tak odstrániť?Položka „%1” má %2 odkazy. Chcete prepísať odkazy hodnotami, preskočiť túto položku alebo ju i tak odstrániť?Položka „%1” má %2 odkazov. Chcete prepísať odkazy hodnotami, preskočiť túto položku alebo ju i tak odstrániť?Položka „%1” má %2 odkazu. Chcete prepísať odkazy hodnotami, preskočiť túto položku alebo ju i tak odstrániť? Delete group - + Odstrániť skupinu Move group to recycle bin? - + Presunúť skupinu do koša? Do you really want to move the group "%1" to the recycle bin? - + Naozaj chcete presunúť skupinu „%1” do koša? Successfully merged the database files. - + Úspešne zlúčené databázové súbory. Database was not modified by merge operation. - + Databáza nebola operáciou zlúčenia zmenená. Shared group... - + Zdieľaná skupina… @@ -1722,23 +1738,23 @@ Vypnúť bezpečné ukladanie a skúsiť znova? Entry has unsaved changes - + Položka má neuložené zmeny New attribute %1 - + Nový atribút %1 [PROTECTED] Press reveal to view or edit - + [CHRÁNENÉ] Stlačte odkryť na zobrazenie alebo úpravu %n year(s) - + %n rok%n roky%n rokov%n rokov Confirm Removal - + Potvrdiť odstránenie @@ -1992,15 +2008,15 @@ Vypnúť bezpečné ukladanie a skúsiť znova? Type: - + Typ: Path: - + Cesta: ... - + Password: @@ -2008,55 +2024,55 @@ Vypnúť bezpečné ukladanie a skúsiť znova? Inactive - + Neaktívne Import from path - + Importovať z cesty Export to path - + Exportovať do cesty Synchronize with path - + Synchronizovať s cestou Your KeePassXC version does not support sharing your container type. Please use %1. - + Táto verzia KeePassXC nepodporuje zdieľanie Vášho typu kontajnera. Prosím použite %1. Database sharing is disabled - + Zdieľanie databázy je vypnuté Database export is disabled - + Export databázy je vpynutý Database import is disabled - + Import databázy je vpynutý KeeShare unsigned container - + Nepodpísaný kontajner KeeShare KeeShare signed container - + Podpísaný kontajner KeeShare Select import source - + Vyberte zdroj importu Select export target - + Vyberte cieľ exportu Select import/export file - + Vyberte súbor importu/exportu Clear @@ -2064,15 +2080,15 @@ Vypnúť bezpečné ukladanie a skúsiť znova? The export container %1 is already referenced. - + Kontajner exportu %1 už je odkazovaný. The import container %1 is already imported. - + Kontajner importu %1 už je importovaný. The container %1 imported and export by different groups. - + Kontajner %1 importovaný a exportovaný rôznymi skupinami. @@ -2150,35 +2166,35 @@ Vypnúť bezpečné ukladanie a skúsiť znova? Custom icon successfully downloaded - + Vlastná ikona úspešne stiahnutá Hint: You can enable DuckDuckGo as a fallback under Tools>Settings>Security - + Tip: Môžete zapnúť DuckDuckGo ako náhradné riešenie v Nástroje>Nastavenie>Bezpečnosť Select Image(s) - + vyberte obrázok(y) Successfully loaded %1 of %n icon(s) - + Úspešne načítané %1 z %n ikonyÚspešne načítané %1 z %n ikonÚspešne načítané %1 z %n ikonÚspešne načítané %1 z %n ikony No icons were loaded - + Neboli načítané ikony %n icon(s) already exist in the database - + %n ikony už v databáze existuje%n ikony už v databáze existujú%n ikon už v databáze existuje%n ikony už v databáze existuje The following icon(s) failed: - + Nasledujúca ikona zlyhala:Nasledujúce ikony zlyhali:Nasledujúce ikony zlyhali:Nasledujúce ikony zlyhali: This icon is used by %n entry(s), and will be replaced by the default icon. Are you sure you want to delete it? - + Táto ikona je použitá v %n položke a bude nahradená predvolenou ikonou. Naozaj ju chcete odstrániť?Táto ikona je použitá v %n položkách a bude nahradená predvolenou ikonou. Naozaj ju chcete odstrániť?Táto ikona je použitá v %n položkách a bude nahradená predvolenou ikonou. Naozaj ju chcete odstrániť?Táto ikona je použitá v %n položke a bude nahradená predvolenou ikonou. Naozaj ju chcete odstrániť? @@ -2230,7 +2246,7 @@ Môže to spôsobiť nefunkčnosť dotknutých zásuvných modulov.Entry %1 - Clone - + %1 – Klon @@ -2312,12 +2328,16 @@ Môže to spôsobiť nefunkčnosť dotknutých zásuvných modulov. Confirm remove - + Potvrdiť odstránenie Unable to open file(s): %1 - + Nemožno otvoriť súbor: +%1Nemožno otvoriť súbory: +%1Nemožno otvoriť súbory: +%1Nemožno otvoriť súbory: +%1 @@ -2403,11 +2423,11 @@ Môže to spôsobiť nefunkčnosť dotknutých zásuvných modulov. Yes - + Áno TOTP - + TOTP @@ -2487,7 +2507,7 @@ Môže to spôsobiť nefunkčnosť dotknutých zásuvných modulov. <b>%1</b>: %2 attributes line - + <b>%1</b>: %2 Enabled @@ -2499,7 +2519,7 @@ Môže to spôsobiť nefunkčnosť dotknutých zásuvných modulov. Share - + Zdieľať @@ -2542,7 +2562,7 @@ Môže to spôsobiť nefunkčnosť dotknutých zásuvných modulov. [empty] group has no children - + [prázdne] @@ -2587,7 +2607,7 @@ Môže to spôsobiť nefunkčnosť dotknutých zásuvných modulov. Header doesn't match hash - + Hlavička nezodpovedá odtlačku Invalid header id size @@ -2816,15 +2836,15 @@ Je to jednosmerná migrácia. Importovanú databázu už nebude možné otvoriť Invalid cipher uuid length: %1 (length=%2) - + Neplatná dĺžka UUID šifry: %1 (length=%2) Unable to parse UUID: %1 - + Nemožno spracovať UUID: %1 Failed to read database file. - + Zlyhalo čítanie súboru databázy. @@ -2950,7 +2970,9 @@ Je to jednosmerná migrácia. Importovanú databázu už nebude možné otvoriť XML error: %1 Line %2, column %3 - + Chyba XML: +%1 +Riadok %2, stĺpec %3 @@ -3117,53 +3139,53 @@ Line %2, column %3 unable to seek to content position - + nemožno sa posunúť na pozíciu obsahu KeeShare Disabled share - + Vypnúť zdieľanie Import from - + Importovať z Export to - + Exportovať do Synchronize with - + Synchronizovať s Disabled share %1 - + Vypnuté zdieľanie %1 Import from share %1 - + Importovať zo zdieľania %1 Export to share %1 - + Exportovať do zdieľania %1 Synchronize with share %1 - + Synchronizovať so zdieľaním %1 KeyComponentWidget Key Component - + Kľúč komponentu Key Component Description - + Popis kľúča komponentu Cancel @@ -3171,27 +3193,27 @@ Line %2, column %3 Key Component set, click to change or remove - + Nastavenie kľúča komponentu, kliknite na zmenu alebo odstránenie Add %1 Add a key component - + Pridať %1 Change %1 Change a key component - + Zmeniť %1 Remove %1 Remove a key component - + Odstrániť %1 %1 set, click to change or remove Change or remove a key component - + %1 nastavené, kliknite na zmenu alebo odstránenie @@ -3206,11 +3228,11 @@ Line %2, column %3 Key File - + Súbor kľúča <p>You can add a key file containing random bytes for additional security.</p><p>You must keep it secret and never lose it or you will be locked out!</p> - + <p>Môžete pridať súbor kľúča s náhodnými bajtmi, na dodatočnú bezpečnosť .</p><p>Musíte ho držať v tajnosti a nikdy nestratiť, inak prídete o prístup!</p> Legacy key file format @@ -3221,12 +3243,15 @@ Line %2, column %3 unsupported in the future. Please go to the master key settings and generate a new key file. - + Používate starý formát súboru kľúča, ktorý nemusí byť v budúcnosti podporovaný. + +Prosím, prejdite do nastavení hlavného kľúča a vygenerujte nový súbor kľúča. Error loading the key file '%1' Message: %2 - + Chyba načítania súboru kľúča „%1” +Správa: %2 Key files @@ -3242,11 +3267,11 @@ Message: %2 Error creating key file - + Chyba vytvárania súboru kľúča Unable to create key file: %1 - + Nemožno vytvoriť súbor kľúča: %1 Select a key file @@ -3435,151 +3460,152 @@ Odporúčame použiť AppImage dostupný v našej stránke sťahovaní. &Import - + &Import Copy att&ribute... - + Kopírovať at&ribút... TOTP... - + TOTP… &New database... - + &Nová databáza… Create a new database - + Vytvoriť novú databázu &Merge from database... - + &Zlúčiť z databázou… Merge from another KDBX database - + Zlúčiť s inou databázou KDBX &New entry - + &Nová položka Add a new entry - + Pridať novú položku &Edit entry - + &Upraviť položku View or edit entry - + Zobraziť alebo upraviť položku &New group - + &Nová skupina Add a new group - + Pridať novú skupinu Change master &key... - + Zmeniť hlavný &kľúč… &Database settings... - + Nastavenia &databázy… Copy &password - + Kopírovať &heslo Perform &Auto-Type - + Vykonať &Automatické vypĺňanie Open &URL - + Otvoriť &URL KeePass 1 database... - + Databáza KeePass 1… Import a KeePass 1 database - + Importovať databázu KeePass 1… CSV file... - + Súbor CSV Import a CSV file - + Importovať súbor CSV… Show TOTP... - + Zobraziť TOTP… Show TOTP QR Code... - + Zobraziť QR kód TOTP Check for Updates... - + Skontrolovať aktualizácie… Share entry - + Zdieľať položku NOTE: You are using a pre-release version of KeePassXC! Expect some bugs and minor issues, this version is not meant for production use. - + UPOZORNENIE: Používate nestabilné zostavenie KeePassXC! +Očakávajte chyby a menšie problémy, táto verzia nie je určená na produkčné použitie. Check for updates on startup? - + Skontrolovať aktualizácie pri štarte? Would you like KeePassXC to check for updates on startup? - + Chcete aby KeePassXC skontroloval aktualizácie pri štarte? You can always check for updates manually from the application menu. - + Vždy môžete skontrolovať aktualizácie manuálne z menu aplikácie. Merger Creating missing %1 [%2] - + Vytváranie chýbajúceho %1 [%2] Relocating %1 [%2] - + Relokácia %1 [%2] Overwriting %1 [%2] - + Prepísanie %1 [%2] older entry merged from database "%1" - + staršia položka zlúčená z databázy „%1” Adding backup for older target %1 [%2] - + Pridávanie zálohy staršieho cieľa %1 [%2] Adding backup for older source %1 [%2] - + Pridávanie zálohy staršieho zdroja %1 [%2] Reapplying older target entry on top of newer source %1 [%2] @@ -3630,23 +3656,23 @@ Expect some bugs and minor issues, this version is not meant for production use. NewDatabaseWizardPage WizardPage - + Stránka sprievodcu En&cryption Settings - + Nastavenia &šifrovanie Here you can adjust the database encryption settings. Don't worry, you can change them later in the database settings. - + Tu môžete prispôsobiť nastavenia šifrovania databázy. Nebojte sa, neskôr ich môžete zmeniť v nastavení databázy. Advanced Settings - + Pokročilé nastavenia Simple Settings - + Jednoduché nastavenia @@ -3657,29 +3683,29 @@ Expect some bugs and minor issues, this version is not meant for production use. Here you can adjust the database encryption settings. Don't worry, you can change them later in the database settings. - + Tu môžete prispôsobiť nastavenia šifrovania databázy. Nebojte sa, neskôr ich môžete zmeniť v nastavení databázy. NewDatabaseWizardPageMasterKey Database Master Key - + Hlavný kľúč databázy A master key known only to you protects your database. - + Hlavný kľúč, známy len vám, chráni vašu databázu. NewDatabaseWizardPageMetaData General Database Information - + Všeobecné informácie databázy Please fill in the display name and an optional description for your new database: - + Prosím, vyplňte meno a prípadne aj popis svojej novej databázy: @@ -3789,7 +3815,7 @@ Expect some bugs and minor issues, this version is not meant for production use. Confirm password: - + Potvrďte heslo: Password @@ -3797,15 +3823,15 @@ Expect some bugs and minor issues, this version is not meant for production use. <p>A password is the primary method for securing your database.</p><p>Good passwords are long and unique. KeePassXC can generate one for you.</p> - + <p>Heslo je primárna metóda na zabezpečenie svojej databázy.</p><p>Dobré heslá sú dlhé a jedinečné. KeePassXC Vám môže nejaké vygenerovať.</p> Passwords do not match. - + Heslá sa nezhodujú. Generate master password - + Vygenerovať hlavné heslo @@ -3921,11 +3947,11 @@ Expect some bugs and minor issues, this version is not meant for production use. ExtendedASCII - + Rozšírené ASCII Switch to advanced mode - + Prepnúť na pokročilý režim Advanced @@ -3933,7 +3959,7 @@ Expect some bugs and minor issues, this version is not meant for production use. Upper Case Letters A to F - + Veľké písmená A až F A-Z @@ -3941,7 +3967,7 @@ Expect some bugs and minor issues, this version is not meant for production use. Lower Case Letters A to F - + Malé písmená A až F a-z @@ -3953,108 +3979,108 @@ Expect some bugs and minor issues, this version is not meant for production use. Braces - + Zátvorky {[( - + {[( Punctuation - + Interpunkcia .,:; - + .,:; Quotes - + Úvodzovky " ' - + " ' Math - + Matematické <*+!?= - + <*+!?= Dashes - + Oddeľovače \_|-/ - + \_|-/ Logograms - + Zástupné znaky #$%&&@^`~ - + #$%&&@^`~ Switch to simple mode - + Prepnúť na jednoduchý režim Simple - + jednoduché Character set to exclude from generated password - + Sady znakov, ktoré majú byť vynechané pri generovaní hesla Do not include: - + Nezahŕňať: Add non-hex letters to "do not include" list - + Pridajte nie-šestnástkové písmená do zoznamu „vynechať” Hex - + Šestnástkové Excluded characters: "0", "1", "l", "I", "O", "|", "﹒" - + Vynechané znaky: „0”, „1”, „l”, „I”, „O”, „|”, „﹒” Word Co&unt: - + Počet &slov: Regenerate - + Obnoviť QApplication KeeShare - + KeeShare QFileDialog Select - + Vybrať QMessageBox Overwrite - + Prepísať Delete @@ -4062,11 +4088,11 @@ Expect some bugs and minor issues, this version is not meant for production use. Move - + Presunúť Empty - + Vyprádzniť Remove @@ -4074,7 +4100,7 @@ Expect some bugs and minor issues, this version is not meant for production use. Skip - + Preskočiť Disable @@ -4082,7 +4108,7 @@ Expect some bugs and minor issues, this version is not meant for production use. Merge - + Zlúčiť @@ -4400,47 +4426,47 @@ Dostupné príkazy: Invalid value for password length %1. - + Neplatná hodnota dĺžky hesla %1. Could not create entry with path %1. - + Nemožno vytvoriť položku s cestou %1. Enter password for new entry: - + Zadajte heslo novej položky: Writing the database failed %1. - + Zápis do databázy zlyhal %1. Successfully added entry %1. - + Úspešne pridaná položka %1. Copy the current TOTP to the clipboard. - + Kopírovať aktuálny TOTP do schránky. Invalid timeout value %1. - + Neplatná hodnota časového limitu %1. Entry %1 not found. - + Položka %1 nenájdená. Entry with path %1 has no TOTP set up. - + Položka s cestou %1 nemá nastavený TOTP. Entry's current TOTP copied to the clipboard! - + TTOP aktuálnej položky skopírovaný do schránky! Entry's password copied to the clipboard! - + Heslo položky skopírované schránky! Clearing the clipboard in %1 second(s)... @@ -4448,7 +4474,7 @@ Dostupné príkazy: Clipboard cleared! - + Schránka vymazaná! Silence password prompt and other secondary outputs. @@ -4473,27 +4499,27 @@ Dostupné príkazy: Enter new password for entry: - + Zadajte nové heslo položky: Writing the database failed: %1 - + Zápis do databázy zlyhal: %1 Successfully edited entry %1. - + Úspešne upravená položka %1. Length %1 - + Dĺžka %1 Entropy %1 - + Náhodnosť %1 Log10 %1 - + Log10 %1 Multi-word extra bits %1 @@ -4501,83 +4527,83 @@ Dostupné príkazy: Type: Bruteforce - + Type: Hrubou silou Type: Dictionary - + Typ: Slovník Type: Dict+Leet - + Typ: Slovník+Leet Type: User Words - + Typ: Použ. slová Type: User+Leet - + Typ: Použ.+Leet Type: Repeated - + Typ: Opakované Type: Sequence - + Typ: Postupné Type: Spatial - + Typ: Geometrické Type: Date - + Typ: Dátum Type: Bruteforce(Rep) - + Typ: Hrubou silou(Rep) Type: Dictionary(Rep) - + Typ: Slovník(Rep) Type: Dict+Leet(Rep) - + Typ: Slovník+Leet(Rep) Type: User Words(Rep) - + Type: Použ. slová(Rep) Type: User+Leet(Rep) - + Typ: Použ.+Leet(Rep) Type: Repeated(Rep) - + Typ: Opakované(Rep) Type: Sequence(Rep) - + Typ: Postupné(Rep) Type: Spatial(Rep) - + Typ: Geometrické(Rep) Type: Date(Rep) - + Typ: Dátum(Rep) Type: Unknown%1 - + Type: Neznámy%1 Entropy %1 (%2) - + Náhodnosť %1 (%2) *** Password length (%1) != sum of length of parts (%2) *** @@ -4585,7 +4611,7 @@ Dostupné príkazy: Failed to load key file %1: %2 - + Zlyhalo načítanie súboru kľúča %1: %2 File %1 does not exist. @@ -4598,52 +4624,54 @@ Dostupné príkazy: Error while reading the database: %1 - + Chyba čítania databázy: +%1 Error while parsing the database: %1 - + Chyba spracovania databázy: +1 Length of the generated password - + Dĺžka generovaného hesla Use lowercase characters - + Požiť malé písmená Use uppercase characters - + Použiť veľké písmená Use numbers. - + Použiť čísla Use special characters - + Použiť špeciálne znaky Use extended ASCII - + Použiť rozšírené ASCII Exclude character set - + Množina vynechaných znakov chars - + znaky Exclude similar looking characters - + Vynechať podobne vyzerajúce znaky Include characters from every selected group - + Použiť znaky z každej zvolenej skupiny Recursively list the elements of the group. @@ -4651,20 +4679,21 @@ Dostupné príkazy: Cannot find group %1. - + Nemožno nájsť skupinu %1. Error reading merge file: %1 - + Chyba čítania súboru zlúčenia: +%1 Unable to save database to file : %1 - + Nemožno uložiť databázu do súboru: %1 Unable to save database to file: %1 - + Nemožno uložiť databázu do súboru: %1 Successfully recycled entry %1. @@ -4676,23 +4705,23 @@ Dostupné príkazy: Show the entry's current TOTP. - + Zobraziť aktuálny TOTP položky. ERROR: unknown attribute %1. - + CHYBA: Neznámy atribút %1. No program defined for clipboard manipulation - + Nie je definovaný program na manipuláciu so schránkou Unable to start program %1 - + Nemožno spustiť program %1 file empty - + prázdny súbor %1: (row, col) %2,%3 @@ -4725,48 +4754,48 @@ Dostupné príkazy: Invalid Settings TOTP - + Neplatné nastavenia Invalid Key TOTP - + Neplatný kľúč Message encryption failed. - + Šifrovanie správy zlyhalo. No groups found - + Skupiny nenájdené Create a new database. - + Vytvoriť novú databázu. File %1 already exists. - + Súbor %1 už existuje. Loading the key file failed - + Načítanie nového kľúča zlyhalo No key is set. Aborting database creation. - + Nie je nastavený kľúč. Vytvorenie novej databázy zrušené. Failed to save the database: %1. - + Zlyhalo uloženie databázy: %1. Successfully created new database. - + Úspešne vytvorená nová databáza. Insert password to encrypt database (Press enter to leave blank): - + Zadajte heslo na zašifrovanie databázy (Stlačte Enter na ponechanie prázdneho): Creating KeyFile %1 failed: %2 @@ -4834,7 +4863,7 @@ Dostupné príkazy: Cannot create new group - + Nemožno vytvoriť novú skupinu @@ -4910,7 +4939,7 @@ Dostupné príkazy: SearchHelpWidget Search Help - + Hľadať v pomocníkovi Search terms are as follows: [modifiers][field:]["]term["] @@ -4922,7 +4951,7 @@ Dostupné príkazy: Modifiers - + Modifikátory exclude term from results @@ -4938,7 +4967,7 @@ Dostupné príkazy: Fields - + Polia Term Wildcards @@ -4958,7 +4987,7 @@ Dostupné príkazy: Examples - + Príklady @@ -4977,47 +5006,47 @@ Dostupné príkazy: Search Help - + Hľadať v pomocníkovi Search (%1)... Search placeholder text, %1 is the keyboard shortcut - + Hľadanie (%1)... Case sensitive - + Rozlišovať veľkosť písmen SettingsWidgetKeeShare Active - + Aktívne Allow export - + Povoliť export Allow import - + Povoliť import Own certificate - + Vlastný certifikát Fingerprint: - + Odtlačok: Certificate: - + Certifikát: Signer - + Podpísal Key: @@ -5033,23 +5062,23 @@ Dostupné príkazy: Export - + Export Imported certificates - + Importované certifikáty Trust - + Dôverovať Ask - + Spýtať sa Untrust - + Nedôverovať Remove @@ -5061,7 +5090,7 @@ Dostupné príkazy: Status - + Status Fingerprint @@ -5069,19 +5098,19 @@ Dostupné príkazy: Certificate - + Certifikát Trusted - + Dôveryhodný Untrusted - + Nedôveryhodný Unknown - + Neznámy key.share @@ -5098,7 +5127,7 @@ Dostupné príkazy: Select path - + Zvoľte cestu Exporting changed certificate @@ -5129,7 +5158,7 @@ Dostupné príkazy: Not this time - + Teraz nie Never @@ -5137,11 +5166,11 @@ Dostupné príkazy: Always - + Vždy Just this time - + Len tentokrát Import from %1 failed (%2) diff --git a/share/translations/keepassx_sv.ts b/share/translations/keepassx_sv.ts index ffc647903..059932ecd 100644 --- a/share/translations/keepassx_sv.ts +++ b/share/translations/keepassx_sv.ts @@ -39,7 +39,7 @@ Project Maintainers: - Projekt Ansvariga: + Projekt ansvariga: Special thanks from the KeePassXC team go to debfx for creating the original KeePassX. @@ -93,7 +93,7 @@ Follow style - + Följ stil @@ -116,7 +116,7 @@ Remember last key files and security dongles - + Kom ihåg senaste nyckel-fil och säkerhets-enhet Load previous databases on startup @@ -132,7 +132,7 @@ Safely save database files (may be incompatible with Dropbox, etc) - + Spara databasfiler säkert (kan vara inkompatibelt med Dropbox, etc) Backup database file before saving @@ -168,7 +168,7 @@ Hide the entry preview panel - + Göm post förhandsvisningspanelen General @@ -176,11 +176,11 @@ Hide toolbar (icons) - + Göm verktygsfält (ikonerna) Minimize instead of app exit - + Minimera istället för att avsluta Show a system tray icon @@ -200,7 +200,7 @@ Auto-Type - Autoskriv + Auto-skriv Use entry title to match windows for global Auto-Type @@ -220,7 +220,7 @@ Auto-Type typing delay - + Auto-skriv fördröjning ms @@ -229,23 +229,23 @@ Auto-Type start delay - + Auto-skriv start fördröjning Check for updates at application startup - + Leta efter uppdateringar vid start Include pre-releases when checking for updates - + Inkludera förhandsversioner vid sökning efter uppdateringar Movable toolbar - + Rörligt verktygsfält Button style - + Knapp-stil @@ -273,7 +273,7 @@ Forget TouchID after inactivity of - + Glöm TouchID efter inaktivitet i Convenience @@ -285,7 +285,7 @@ Forget TouchID when session is locked or lid is closed - + Glöm TouchID när sessionen låses eller locket stängs Lock databases after minimizing the window @@ -293,7 +293,7 @@ Re-lock previously locked database after performing Auto-Type - + Lås tidigare låst databas efter att ha utfört Auto-skriv Don't require password repeat when it is visible @@ -309,7 +309,7 @@ Hide passwords in the entry preview panel - + Göm lösenord i förhandsgranskningsrutan Hide entry notes by default @@ -321,7 +321,7 @@ Use DuckDuckGo as fallback for downloading website icons - + Använd DuckDuckGo som alternativ vid nedladdning av webbplatsikoner @@ -429,7 +429,7 @@ Vill du tillåta det? BrowserEntrySaveDialog KeePassXC-Browser Save Entry - + KeePassXC-Browser spara post Ok @@ -442,7 +442,8 @@ Vill du tillåta det? You have multiple databases open. Please select the correct database for saving credentials. - + Du ha flera databaser öppna. +Välj databas för att spara uppgifter. @@ -539,7 +540,7 @@ Please select the correct database for saving credentials. Searc&h in all opened databases for matching credentials Credentials mean login data requested via browser extension - + Sök i alla öppna databaser efter matchande uppgifter Automatically creating or updating string fields is not supported. @@ -547,7 +548,7 @@ Please select the correct database for saving credentials. &Return advanced string fields which start with "KPH: " - + Returnera avancerade text-fält som börjar med "KPH: " Updates KeePassXC or keepassxc-proxy binary path automatically to native messaging scripts on startup. @@ -873,7 +874,7 @@ Would you like to migrate your existing settings now? DatabaseOpenDialog Unlock Database - KeePassXC - + Lås upp databas - KeePassXC @@ -969,7 +970,7 @@ Please consider generating a new key file. Master Key - + Huvud-lösenord Encryption Settings @@ -1029,7 +1030,7 @@ This may prevent connection to the browser plugin. Disconnect all browsers - + Koppla från alla webbläsare Do you really want to disconnect all browsers? @@ -1131,7 +1132,7 @@ This is necessary to maintain compatibility with the browser plugin. Decryption Time: - + Dektypterings-tid: ?? s @@ -1512,7 +1513,7 @@ Do you want to merge your changes? Delete entry(s)? - + Ta bort post?Ta bort poster? Move entry(s) to recycle bin? @@ -1606,7 +1607,7 @@ Disable safe saves and try again? Shared group... - + Delad grupp... @@ -1884,7 +1885,7 @@ Disable safe saves and try again? Public key - + Publik nyckel Add key to agent when database is opened/unlocked @@ -2097,7 +2098,7 @@ Disable safe saves and try again? EditWidgetIcons &Use default icon - + Använd standard ikon Use custo&m icon @@ -3109,15 +3110,15 @@ Line %2, column %3 Import from - + Importera från Export to - + Exportera till Synchronize with - + Synkronisera med Disabled share %1 @@ -3187,7 +3188,7 @@ Line %2, column %3 Key File - + Nyckel-fil <p>You can add a key file containing random bytes for additional security.</p><p>You must keep it secret and never lose it or you will be locked out!</p> @@ -3250,7 +3251,7 @@ Message: %2 E&ntries - + Poster &Groups @@ -3441,11 +3442,11 @@ We recommend you use the AppImage available on our downloads page. &New entry - + Ny post Add a new entry - + Lägg till ny post &Edit entry diff --git a/share/translations/keepassx_tr.ts b/share/translations/keepassx_tr.ts index 84a331e3d..cb8db274b 100644 --- a/share/translations/keepassx_tr.ts +++ b/share/translations/keepassx_tr.ts @@ -50,7 +50,7 @@ AgentSettingsWidget Enable SSH Agent (requires restart) - SSH Aracısını etkinleştir (yeniden başlatma gerektirir) + SSH İstemcisini etkinleştir (yeniden başlatma gerektirir) Use OpenSSH for Windows instead of Pageant @@ -93,7 +93,7 @@ Follow style - Takip tarzı + Takip tipi @@ -245,7 +245,7 @@ Button style - Düğme tarzı + Düğme tipi @@ -367,7 +367,7 @@ Default sequence - Varsayılan sıra + Öntanımlı sıra @@ -491,7 +491,7 @@ Lütfen kimlik bilgilerini kaydetmek için doğru veritabanını seç. Re&quest to unlock the database if it is locked - Eğer kilitliyse veri tabanını açmayı is&te + Eğer kilitliyse veritabanının kilidini açma is&teği Only entries with the same scheme (http://, https://, ...) are returned. @@ -535,7 +535,7 @@ Lütfen kimlik bilgilerini kaydetmek için doğru veritabanını seç. Only the selected database has to be connected with a client. - Yalnızca seçilen veri tabanı istemciyle bağlanmış olmalıdır. + Yalnızca seçilen veritabanı istemciyle bağlanmış olmalıdır. Searc&h in all opened databases for matching credentials @@ -611,15 +611,15 @@ Lütfen kimlik bilgilerini kaydetmek için doğru veritabanını seç. Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1 - + Snap sanal alanı nedeniyle, tarayıcı bütünleşmesini etkinleştirmek için bir komut dosyası çalıştırmalısınız.<br />Bu betiği %1 adresinden edinebilirsiniz. Please see special instructions for browser extension use below - + Lütfen aşağıdaki tarayıcı uzantısı kullanımına ilişkin özel talimatlara bakın KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3 - + Tarayıcı bütünleşmesinin çalışması için KeePassXC-Tarayıcı gereklidir. <br />%1 ve %2 için indirin. %3 @@ -696,19 +696,23 @@ Moved %2 keys to custom data. KeePassXC: Create a new group - + KeePassXC: Yeni bir küme oluştur A request for creating a new group "%1" has been received. Do you want to create this group? - + "%1" adlı yeni bir küme oluşturma isteği alındı. +Bu kümeyi oluşturmak ister misiniz? + Your KeePassXC-Browser settings need to be moved into the database settings. This is necessary to maintain your current browser connections. Would you like to migrate your existing settings now? - + KeePassXC-Tarayıcı ayarlarınızın veritabanı ayarlarına taşınması gerekir. +Bu, mevcut tarayıcı bağlantılarınızı korumak için gereklidir. +Mevcut ayarlarınızı şimdi taşımak ister misiniz? @@ -872,7 +876,7 @@ Would you like to migrate your existing settings now? Key not transformed. This is a bug, please report it to the developers! - + Anahtar dönüştürülmedi. Bu bir hatadır, lütfen geliştiricilere bildirin! @@ -997,7 +1001,7 @@ Lütfen yeni bir anahtar dosyası oluşturmayı düşünün. &Disconnect all browsers - &Tüm tarayıcıları kapatın + &Tüm tarayıcıların bağlantısını kes Forg&et all site-specific settings on entries @@ -1039,13 +1043,13 @@ Bu işlem, tarayıcı eklentisine bağlantıyı engelleyebilir. Disconnect all browsers - Tüm tarayıcıları kapatın + Tüm tarayıcıların bağlantısını kes Do you really want to disconnect all browsers? This may prevent connection to the browser plugin. Tüm tarayıcıların bağlantısını kesmek istiyor musunuz? -Bu işlem, tarayıcı eklentisine bağlantıyı engelleyebilir. +Bu işlem, tarayıcı eklentisi bağlantısını engelleyebilir. KeePassXC: No keys found @@ -1095,7 +1099,7 @@ Girişlere erişim izinleri iptal edilecek. The active database does not contain an entry with permissions. - Etkin veritabanı izinleri olan bir girdi içermiyor. + Etkin veritabanı, izinleri olan bir girdi içermiyor. Move KeePassHTTP attributes to custom data @@ -1254,15 +1258,15 @@ Eğer bu sayı ile devam ederseniz, veritabanınız çok kolay çözülerek kır DatabaseSettingsWidgetGeneral Database Meta Data - Veritabanı Meta Verileri + Veritabanı Üst Veri Database name: - Veri tabanı adı: + Veritabanı adı: Database description: - Veri tabanı ayrıntısı: + Veritabanı açıklaması: Default username: @@ -1379,7 +1383,7 @@ Parola olmadan devam etmek istediğinize emin misiniz? DatabaseTabWidget KeePass 2 Database - KeePass 2 Veri Tabanı + KeePass 2 Veritabanı All files @@ -1387,7 +1391,7 @@ Parola olmadan devam etmek istediğinize emin misiniz? Open database - Veri tabanı aç + Veritabanı aç CSV file @@ -1395,19 +1399,19 @@ Parola olmadan devam etmek istediğinize emin misiniz? Merge database - Veri tabanı birleştir + Veritabanını birleştir Open KeePass 1 database - KeePass 1 veri tabanı aç + KeePass 1 veritabanı aç KeePass 1 database - KeePass 1 veri tabanı + KeePass 1 veritabanı Export database to CSV file - Veri tabanını CSV dosyasına dışa aktar + Veritabanını CSV dosyasına dışa aktar Writing the CSV file failed. @@ -1487,11 +1491,11 @@ Bu kesinlikle bir hatadır, lütfen geliştiricilere bildirin. No current database. - Geçerli veri tabanı yok. + Geçerli veritabanı yok. No source database, nothing to do. - Kaynak veri tabanı yok, yapılacak bir şey yok. + Kaynak veritabanı yok, yapılacak bir şey yok. Search Results (%1) @@ -1507,7 +1511,7 @@ Bu kesinlikle bir hatadır, lütfen geliştiricilere bildirin. The database file has changed. Do you want to load the changes? - Veri tabanı dosyası değiştirildi. Değişiklikleri yüklemek ister misiniz? + Veritabanı dosyası değiştirildi. Değişiklikleri yüklemek ister misiniz? Merge Request @@ -1586,7 +1590,7 @@ Güvenli kaydetme devre dışı bırakılsın ve tekrar denensin mi? Writing the database failed. %1 - Veritabanını yazma başarısız + Veritabanına yazma başarısız %1 @@ -1631,7 +1635,7 @@ Güvenli kaydetme devre dışı bırakılsın ve tekrar denensin mi? Shared group... - + Paylaşılan küme... @@ -1662,7 +1666,7 @@ Güvenli kaydetme devre dışı bırakılsın ve tekrar denensin mi? SSH Agent - SSH Aracısı + SSH İstemcisi n/a @@ -1893,7 +1897,7 @@ Güvenli kaydetme devre dışı bırakılsın ve tekrar denensin mi? Remove key from agent after - Sonra ajandan anahtarı kaldır + Anahtarı istemciden sonra kaldır seconds @@ -1905,7 +1909,7 @@ Güvenli kaydetme devre dışı bırakılsın ve tekrar denensin mi? Remove key from agent when database is closed/locked - Veritabanı kapalı/kilitliyken ajandan anahtarı kaldır + Veritabanı kapalı/kilitliyken istemciden anahtarı kaldır Public key @@ -1913,7 +1917,7 @@ Güvenli kaydetme devre dışı bırakılsın ve tekrar denensin mi? Add key to agent when database is opened/unlocked - Veritabanı kapalı/kilitliyken ajana anahtarı ekle + Veritabanı kapalı/kilitliyken istemciye anahtar ekle Comment @@ -2076,15 +2080,15 @@ Güvenli kaydetme devre dışı bırakılsın ve tekrar denensin mi? The export container %1 is already referenced. - + %1 dışa aktarma kapsayıcı zaten referans alındı. The import container %1 is already imported. - + %1 içe aktarma kapsayıcı zaten içe aktarıldı The container %1 imported and export by different groups. - + %1 kapsayıcı, farklı kümelere göre içe ve dışa aktarıldı. @@ -2190,7 +2194,7 @@ Güvenli kaydetme devre dışı bırakılsın ve tekrar denensin mi? This icon is used by %n entry(s), and will be replaced by the default icon. Are you sure you want to delete it? - Bu simge %n girişi tarafından kullanılır ve varsayılan simge ile değiştirilir. Silmek istediğinize emin misiniz?Bu simge %n girişi tarafından kullanılır ve varsayılan simge ile değiştirilir. Silmek istediğinize emin misiniz? + Bu simge %n girişi tarafından kullanılır ve öntanımlı simge ile değiştirilir. Silmek istediğinize emin misiniz?Bu simge %n girişi tarafından kullanılır ve öntanımlı simge ile değiştirilir. Silmek istediğinize emin misiniz? @@ -2449,7 +2453,7 @@ Bu etkilenen eklentilerin bozulmasına neden olabilir. Expiration - Geçerlilik + Süre bitimi URL @@ -2594,7 +2598,7 @@ Bu etkilenen eklentilerin bozulmasına neden olabilir. Wrong key or database file is corrupt. - Yanlış anahtar veya veri tabanı dosyası bozuk. + Yanlış anahtar veya veritabanı dosyası bozuk. missing database headers @@ -2632,7 +2636,7 @@ Bu etkilenen eklentilerin bozulmasına neden olabilir. Kdbx4Reader missing database headers - eksik veri tabanı başlıkları + eksik veritabanı başlıkları Unable to calculate master key @@ -2648,7 +2652,7 @@ Bu etkilenen eklentilerin bozulmasına neden olabilir. Wrong key or database file is corrupt. (HMAC mismatch) - Yanlış anahtar veya veri tabanı dosyası bozuk. (HMAC uyuşmuyor) + Yanlış anahtar veya veritabanı dosyası bozuk. (HMAC uyuşmuyor) Unknown cipher @@ -2812,21 +2816,21 @@ Bu etkilenen eklentilerin bozulmasına neden olabilir. Not a KeePass database. - KeePass veri tabanı değil. + KeePass veritabanı değil. The selected file is an old KeePass 1 database (.kdb). You can import it by clicking on Database > 'Import KeePass 1 database...'. This is a one-way migration. You won't be able to open the imported database with the old KeePassX 0.4 version. - Seçilen dosya eski bir KeePass1 veri tabanıdır (.kdb). + Seçilen dosya eski bir KeePass1 veritabanıdır (.kdb). -Veri tabanı > 'KeePass1 veri tabanı içe aktar...'a tıklayarak içe aktarabilirsiniz. -Bu tek yönlü bir yer değiştirmedir. İçe aktarılan veri tabanını eski KeePassX 0.4 sürümüyle açamayacaksınız. +Veritabanı > 'KeePass1 veritabanı içe aktar...' üzerine tıklayarak içe aktarabilirsiniz. +Bu tek yönlü bir yer değiştirmedir. İçe aktarılan veritabanını eski KeePassX 0.4 sürümüyle açamayacaksınız. Unsupported KeePass 2 database version. - Desteklenmeyen KeePass 2 veri tabanı sürümü. + Desteklenmeyen KeePass 2 veritabanı sürümü. Invalid cipher uuid length: %1 (length=%2) @@ -2853,7 +2857,7 @@ Bu tek yönlü bir yer değiştirmedir. İçe aktarılan veri tabanını eski Ke Missing icon uuid or data - Simge uuid'si veya verisi eksik + Simge UUID'si veya verisi eksik Missing custom data key or value @@ -2885,15 +2889,15 @@ Bu tek yönlü bir yer değiştirmedir. İçe aktarılan veri tabanını eski Ke Null DeleteObject uuid - Boş "DeleteObject" "uuid" + Boş "DeleteObject" UUID Missing DeletedObject uuid or time - Hatalı "DeleteObject" evrensel benzersiz tanımlayıcı "uuid" veya zamanı + DeletedObject UUID veya zaman eksik Null entry uuid - Boş evrensel benzersiz tanımlayıcı "uuid" girdisi + Boş UUID girdisi Invalid entry icon number @@ -2905,12 +2909,11 @@ Bu tek yönlü bir yer değiştirmedir. İçe aktarılan veri tabanını eski Ke No entry uuid found - -Evrensel benzersiz tanımlayıcı "uuid" girdisi bulunamadı + UUID girdisi bulunamadı History element with different uuid - Farklı evrensel benzersiz tanımlayıcı "uuid" ile geçmiş öğesi + Farklı UUID ile tarih elemanı Duplicate custom attribute found @@ -2954,7 +2957,7 @@ Evrensel benzersiz tanımlayıcı "uuid" girdisi bulunamadı Invalid uuid value - Geçersiz Evrensel Benzersiz Tanımlayıcı "uuid" değeri + Geçersiz UUID değeri Unable to decompress binary @@ -2974,11 +2977,11 @@ Satır %2, sütun %3 KeePass1OpenWidget Import KeePass1 database - KeePass1 veri tabanı içe aktar + KeePass1 veritabanı içe aktar Unable to open the database. - Veri tabanı açılamıyor. + Veritabanı açılamıyor. @@ -2989,7 +2992,7 @@ Satır %2, sütun %3 Not a KeePass database. - KeePass veri tabanı değil. + KeePass veritabanı değil. Unsupported encryption algorithm. @@ -2997,7 +3000,7 @@ Satır %2, sütun %3 Unsupported KeePass database version. - Desteklenmeyen KeePass veri tabanı sürümü. + Desteklenmeyen KeePass veritabanı sürümü. Unable to read encryption IV @@ -3038,7 +3041,7 @@ Satır %2, sütun %3 Wrong key or database file is corrupt. - Yanlış anahtar veya veri tabanı dosyası bozuk. + Yanlış anahtar veya veritabanı dosyası bozuk. Key transformation failed @@ -3157,19 +3160,19 @@ Satır %2, sütun %3 Disabled share %1 - + Paylaşım devre dışı %1 Import from share %1 - + %1 paylaşımından içe aktar Export to share %1 - + %1 paylaşımına aktar Synchronize with share %1 - + %1 paylaşımına eşitle @@ -3255,7 +3258,7 @@ Message: %2 All files - Bütün dosyalar + Tüm dosyalar Create Key File... @@ -3278,11 +3281,11 @@ Message: %2 MainWindow &Database - &Veri tabanı + &Veritabanı &Recent databases - &Son veri tabanları + &Son veritabanları &Help @@ -3310,15 +3313,15 @@ Message: %2 &Open database... - &Veri tabanı aç... + &Veritabanı aç... &Save database - Veri tabanını k&aydet + Veritabanını k&aydet &Close database - Veri tabanını &kapat + Veritabanını &kapat &Delete entry @@ -3334,11 +3337,11 @@ Message: %2 Sa&ve database as... - Veri tabanını farklı ka&ydet... + Veritabanını farklı ka&ydet... Database settings - Veri tabnı ayarları + Veritabanı ayarları &Clone entry @@ -3362,11 +3365,11 @@ Message: %2 Password Generator - Parola Oluşturucu + Parola oluşturucu &Lock databases - Veri tabanlarını &kilitle + Veritabanlarını &kilitle &Title @@ -3476,7 +3479,7 @@ Keepassxc indirme sayfasında mevcut Appımage kullanmanızı öneririz. &Merge from database... - Veritabanından &birleştir ... + Veritabanından &birleştir... Merge from another KDBX database @@ -3516,7 +3519,7 @@ Keepassxc indirme sayfasında mevcut Appımage kullanmanızı öneririz. Copy &password - Kopyala &parola + &Parolayı kopyala Perform &Auto-Type @@ -3593,7 +3596,7 @@ Bazı hatalar ve küçük sorunlar olabilir, bu sürüm şu an dağıtımda değ older entry merged from database "%1" - eski giriş "%1" veritabanından birleştirildi + eski giriş "%1" veritabanıyla birleştirildi Adding backup for older target %1 [%2] @@ -3668,7 +3671,7 @@ Bazı hatalar ve küçük sorunlar olabilir, bu sürüm şu an dağıtımda değ Simple Settings - Temel Ayarlar + Basit Ayarlar @@ -4159,15 +4162,15 @@ Bazı hatalar ve küçük sorunlar olabilir, bu sürüm şu an dağıtımda değ Add a new entry to a database. - Veri tabanına yeni girdi ekle. + Veritabanına yeni girdi ekle. Path of the database. - Veri tabanının yolu. + Veritabanının yolu. Key file of the database. - Veri tabanının anahtar dosyası. + Veritabanının anahtar dosyası. path @@ -4252,11 +4255,11 @@ Bazı hatalar ve küçük sorunlar olabilir, bu sürüm şu an dağıtımda değ Extract and print the content of a database. - Veri tabanının içeriğini çıkar ve yazdır. + Veritabanının içeriğini çıkar ve yazdır. Path of the database to extract. - Veri tabanının çıkarılacağı yol. + Veritabanının çıkarılacağı yol. Insert password to unlock %1: @@ -4328,7 +4331,7 @@ Kullanılabilir komutlar: Names of the attributes to show. This option can be specified more than once, with each attribute shown one-per-line in the given order. If no attributes are specified, a summary of the default attributes is given. - Gösterilecek özniteliklerin isimleri. Bu seçenek, her bir özniteliğin verilen sıraya göre bir satırda gösterilmesiyle birden fazla kez belirtilebilir. Eğer hiçbir öznitelik belirtilmediyse, varsayılan özniteliklerin bir özeti verilir. + Gösterilecek özniteliklerin isimleri. Bu seçenek, her bir özniteliğin verilen sıraya göre bir satırda gösterilmesiyle birden fazla kez belirtilebilir. Eğer hiçbir öznitelik belirtilmediyse, öntanımlı özniteliklerin bir özeti verilir. attribute @@ -4340,7 +4343,7 @@ Kullanılabilir komutlar: NULL device - NULL aygıtı + Geçersiz aygıt error reading from device @@ -4400,7 +4403,7 @@ Kullanılabilir komutlar: SSH Agent - SSH Aracısı + SSH İstemcisi Generate a new random diceware passphrase. @@ -4414,11 +4417,11 @@ Kullanılabilir komutlar: Wordlist for the diceware generator. [Default: EFF English] Diceware oluşturucu için Kelime Listesi. -[Varsayılan: EFF İngilizce] +[Öntanımlı: EFF İngilizce] Generate a new random password. - Yeni bir karışık şifre oluştur. + Yeni bir karışık parola oluştur. Invalid value for password length %1. @@ -4495,7 +4498,7 @@ Kullanılabilir komutlar: Enter new password for entry: - Girdi için yeni şifre girin: + Girdi için yeni parola gir: Writing the database failed: %1 @@ -4759,7 +4762,7 @@ Kullanılabilir komutlar: Message encryption failed. - Mesaj şifreleme başarısız. + İleti şifreleme başarısız. No groups found @@ -4859,7 +4862,7 @@ Kullanılabilir komutlar: Cannot create new group - + Yeni küme oluşturulamıyor @@ -5119,7 +5122,7 @@ Kullanılabilir komutlar: All files - Bütün dosyalar + Tüm dosyalar Select path @@ -5135,7 +5138,7 @@ Kullanılabilir komutlar: Signer: - + İmzalayan: @@ -5258,27 +5261,27 @@ Kullanılabilir komutlar: Multiple import source path to %1 in %2 - + %2 içinde %1'e çoklu içe aktarma kaynak yolu Conflicting export target path %1 in %2 - + Çakışan aktarma hedef yolu %1 %2 Could not embed signature: Could not open file to write (%1) - + İmza gömülemedi: Yazılacak dosya açılamadı (%1) Could not embed signature: Could not write file (%1) - + İmza gömülemedi: Dosya yazılamadı (%1) Could not embed database: Could not open file to write (%1) - + Veritabanı gömülemedi: Yazılacak dosya açılamadı (%1) Could not embed database: Could not write file (%1) - + Veritabanı gömülemedi: dosya yazılamadı (%1) @@ -5332,7 +5335,7 @@ Kullanılabilir komutlar: Default RFC 6238 token settings - Varsayılan RFC 6238 anahtar ayarları + Öntanımlı RFC 6238 anahtar ayarları Steam token settings @@ -5427,7 +5430,7 @@ Kullanılabilir komutlar: WelcomeWidget Start storing your passwords securely in a KeePassXC database - Parolalarınızı KeePassXC veri tabanında güvenle depolamaya başlayın + Parolalarınızı KeePassXC veritabanında güvenle depolamaya başlayın Create new database @@ -5462,11 +5465,11 @@ Kullanılabilir komutlar: YubiKey Challenge-Response - YubiKey Challenge-Response + YubiKey Karşılama Yanıtı <p>If you own a <a href="https://www.yubico.com/">YubiKey</a>, you can use it for additional security.</p><p>The YubiKey requires one of its slots to be programmed as <a href="https://www.yubico.com/products/services-software/personalization-tools/challenge-response/">HMAC-SHA1 Challenge-Response</a>.</p> - <p>Eğer bir <a href="https://www.yubico.com/">YubiKey</a>sahibiyseniz ek güvenlik için kullanabilirsiniz.</p><p>YubiKey, yuvalarından birinin programlanması gerekir <a href="https://www.yubico.com/products/services-software/personalization-tools/challenge-response/">HMAC-SHA1 Challenge-Response</a>.</p> + <p>Eğer bir <a href="https://www.yubico.com/">YubiKey</a> sahibiyseniz ek güvenlik için kullanabilirsiniz.</p><p>YubiKey yuvalarından birinin programlanması gerekir <a href="https://www.yubico.com/products/services-software/personalization-tools/challenge-response/">HMAC-SHA1 Karşılama-Yanıtı</a>.</p> No YubiKey detected, please ensure it's plugged in. diff --git a/share/translations/keepassx_uk.ts b/share/translations/keepassx_uk.ts index fbd14999b..6eb5f6eec 100644 --- a/share/translations/keepassx_uk.ts +++ b/share/translations/keepassx_uk.ts @@ -611,15 +611,15 @@ Please select the correct database for saving credentials. Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1 - + Через заходи безпеки у Snap Вам необхідно виконати сценарій для сполучення з переглядачем. <br />Ви можете знайти файл сценарію у %1 Please see special instructions for browser extension use below - + Нижче Ви можете знайти інструкції для використання додатку для браузера KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3 - + Для сполучення з переглядачем необхідний KeePassXC-Browser. <br />Завантажте його для %1 та %2. %3 @@ -696,19 +696,23 @@ Moved %2 keys to custom data. KeePassXC: Create a new group - + KeePassXC: Створити нову групу A request for creating a new group "%1" has been received. Do you want to create this group? - + Отримано запит для створення нової групи "%1". +Ви хочете створити цю групу? + Your KeePassXC-Browser settings need to be moved into the database settings. This is necessary to maintain your current browser connections. Would you like to migrate your existing settings now? - + Ваші параметри KeePassXC-Переглядача мають бути переміщені до параметрів сховища. +Це необхідно для підтримання сполучень з Вашим поточним переглядачем. +Бажаєте перемістити параметри зараз? @@ -872,7 +876,7 @@ Would you like to migrate your existing settings now? Key not transformed. This is a bug, please report it to the developers! - + Ключ не перетворено через ваду в програмі. Будь ласка, повідомте про це розробникам! @@ -1631,7 +1635,7 @@ Disable safe saves and try again? Shared group... - + Спільна група... @@ -2076,15 +2080,15 @@ Disable safe saves and try again? The export container %1 is already referenced. - + На експортну оболонку %1 вже існує посилання. The import container %1 is already imported. - + Оболонку %1 вже імпортовано. The container %1 imported and export by different groups. - + Оболонку %1 імпортують та експортують різні групи. @@ -3157,19 +3161,19 @@ Line %2, column %3 Disabled share %1 - + Вимкнутий спільний ресурс %1 Import from share %1 - + Імпортувати зі спільного ресурсу %1 Export to share %1 - + Експортувати до спільного ресурсу %1 Synchronize with share %1 - + Узгодити зі спільним ресурсом %1 @@ -4858,7 +4862,7 @@ Available commands: Cannot create new group - + Неможливо створити нову групу @@ -5134,7 +5138,7 @@ Available commands: Signer: - + Підписувач: @@ -5253,31 +5257,31 @@ Available commands: Do you want to trust %1 with the fingerprint of %2 from %3? - + Довірити %1, що має відбиток %2 з %3? {1 ?} {2 ?} Multiple import source path to %1 in %2 - + Шлях до %1 має декілька джерел імпорту в %2. Conflicting export target path %1 in %2 - + Суперечливий шлях для експорту %1 у %2 Could not embed signature: Could not open file to write (%1) - + Неможливо вкласти підпис: неможливо відкрити файл для запису (%1) Could not embed signature: Could not write file (%1) - + Неможливо вкласти підпис: неможливо записати файл (%1) Could not embed database: Could not open file to write (%1) - + Неможливо вкласти сховище: неможливо відкрити файл для запису (%1) Could not embed database: Could not write file (%1) - + Неможливо вкласти сховище: неможливо записати файл (%1) diff --git a/share/translations/keepassx_zh_CN.ts b/share/translations/keepassx_zh_CN.ts index a50530b00..d1b17aae0 100644 --- a/share/translations/keepassx_zh_CN.ts +++ b/share/translations/keepassx_zh_CN.ts @@ -611,15 +611,15 @@ Please select the correct database for saving credentials. Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1 - + 由于快照沙盒,必须运行脚本才能启用浏览器集成。<br />您可以从 %1 获取此脚本 Please see special instructions for browser extension use below - + 请参阅下面的浏览器扩展使用的特殊说明 KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3 - + 浏览器集成需要KeePassXC-Browser才能工作。<br />下载%1 和 %2. %3 @@ -696,19 +696,22 @@ Moved %2 keys to custom data. KeePassXC: Create a new group - + keepassxc: 创建新群组 A request for creating a new group "%1" has been received. Do you want to create this group? - + 已收到创建新群组 "%1" 的请求。 +是否要创建此群组? Your KeePassXC-Browser settings need to be moved into the database settings. This is necessary to maintain your current browser connections. Would you like to migrate your existing settings now? - + 您的keepassxc浏览器设置需要移动到数据库设置中。 +这是保持当前浏览器连接所必需的。 +是否要立即迁移现有设置? @@ -872,7 +875,7 @@ Would you like to migrate your existing settings now? Key not transformed. This is a bug, please report it to the developers! - + 密钥未转换。这是一个bug,请报告给开发者! @@ -1630,7 +1633,7 @@ Disable safe saves and try again? Shared group... - + 共享群组... @@ -2075,15 +2078,15 @@ Disable safe saves and try again? The export container %1 is already referenced. - + 导出容器 %1 已被引用。 The import container %1 is already imported. - + 导入容器 %1 已导入。 The container %1 imported and export by different groups. - + 容器 %1 由不同的群组导入和导出。 @@ -3151,19 +3154,19 @@ Line %2, column %3 Disabled share %1 - + 已禁用共享 %1 Import from share %1 - + 从共享 %1 导入 Export to share %1 - + 导出到共享 %1 Synchronize with share %1 - + 与共享 %1 同步 @@ -4853,7 +4856,7 @@ Available commands: Cannot create new group - + 无法创建新群组 @@ -5129,7 +5132,7 @@ Available commands: Signer: - + 签名: @@ -5252,27 +5255,27 @@ Available commands: Multiple import source path to %1 in %2 - + 多个导入源路径到 %1 in %2 Conflicting export target path %1 in %2 - + 冲突的导出目标路径 %1 in %2 Could not embed signature: Could not open file to write (%1) - + 无法嵌入签名:无法打开要写入的文件 (%1) Could not embed signature: Could not write file (%1) - + 无法嵌入签名:无法写入文件 (%1) Could not embed database: Could not open file to write (%1) - + 无法嵌入数据库:无法打开要写入的文件 (%1) Could not embed database: Could not write file (%1) - + 无法嵌入数据库:无法写入文件 (%1) -- cgit v1.2.3