diff options
author | Jonathan White <support@dmapps.us> | 2019-04-13 01:12:12 +0300 |
---|---|---|
committer | Jonathan White <support@dmapps.us> | 2019-04-13 01:12:12 +0300 |
commit | 7bafe65d17e98348b0ff5fb46f117bdf05764cc6 (patch) | |
tree | 215441a91db17ad578960fb208e7e2a19dca3067 | |
parent | c51752df3913329d6fc78563c54ddd6ebd994b0f (diff) | |
parent | 5b007ece1409114f0935978b9d4e4dc0f3c47025 (diff) |
Release 2.4.12.4.1
- 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]
134 files changed, 3075 insertions, 2107 deletions
@@ -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 658548f70..16d574f01 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,10 +77,15 @@ 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") +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") 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 +97,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 +124,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") @@ -192,11 +203,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") @@ -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/release-tool b/release-tool index a04ad5de9..821a1e8c1 100755 --- a/release-tool +++ b/release-tool @@ -810,20 +810,20 @@ 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")" + # 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 @@ -852,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 @@ -885,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 @@ -908,7 +909,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 @@ -917,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} ]]; then + if ${build_appsign} && [ -f "${build_key}" ]; then logInfo "Signing executable files" appsign "-f" $(find src | grep -P '\.exe$|\.dll$') "-k" "${build_key}" fi @@ -949,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..." @@ -981,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 @@ -1143,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}" 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/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 @@ </screenshots> <releases> + <release version="2.4.1" date="2019-04-12"> + <description> + <ul> + <li>Fix database deletion when using unsafe saves to a different file system [#2889]</li> + <li>Fix opening databases with legacy key files that contain '/' [#2872]</li> + <li>Fix opening database files from the command line [#2919]</li> + <li>Fix crash when editing master key [#2836]</li> + <li>Fix multiple issues with apply button behavior [#2947]</li> + <li>Fix issues on application startup (tab order, --pw-stdin, etc.) [#2830]</li> + <li>Fix building without WITH_XC_KEESHARE</li> + <li>Fix reference entry coloring on macOS dark mode [#2984]</li> + <li>Hide window when performing entry auto-type on macOS [#2969]</li> + <li>Improve UX of update checker; reduce checks to every 7 days [#2968]</li> + <li>KeeShare improvements [#2946, #2978, #2824]</li> + <li>Re-enable Ctrl+C to copy password from search box [#2947]</li> + <li>Add KeePassXC-Browser integration for Brave browser [#2933]</li> + <li>SSH Agent: Re-Add keys on database unlock [#2982]</li> + <li>SSH Agent: Only remove keys on app exit if they are removed on lock [#2985]</li> + <li>CLI: Add --no-password option [#2708]</li> + <li>CLI: Improve database extraction to XML [#2698]</li> + <li>CLI: Don't call mandb on build [#2774]</li> + <li>CLI: Add debug info [#2714]</li> + <li>Improve support for Snap theming [#2832]</li> + <li>Add support for building on Haiku OS [#2859]</li> + <li>Ctrl+PgDn now goes to the next tab and Ctrl+PgUp to the previous</li> + <li>Fix compiling on GCC 5 / Xenial [#2990]</li> + <li>Add .gitrev output to tarball for third-party builds [#2970]</li> + <li>Add WITH_XC_UPDATECHECK compile flag to enable/disable the update checker [#2968]</li> + </ul> + </description> + </release> <release version="2.4.0" date="2019-03-19"> <description> <ul> 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 @@ </message> <message> <source>Startup</source> - <translation type="unfinished"/> + <translation>Inicialització</translation> </message> <message> <source>Start only a single instance of KeePassXC</source> @@ -128,7 +128,7 @@ </message> <message> <source>File Management</source> - <translation type="unfinished"/> + <translation>Gestió de fitxers</translation> </message> <message> <source>Safely save database files (may be incompatible with Dropbox, etc)</source> @@ -136,7 +136,7 @@ </message> <message> <source>Backup database file before saving</source> - <translation type="unfinished"/> + <translation>Fes una còpia de seguretat abans de desar</translation> </message> <message> <source>Automatically save after every change</source> @@ -156,7 +156,7 @@ </message> <message> <source>Entry Management</source> - <translation type="unfinished"/> + <translation>Gestió d'entrades</translation> </message> <message> <source>Use group icon on entry creation</source> @@ -168,7 +168,7 @@ </message> <message> <source>Hide the entry preview panel</source> - <translation type="unfinished"/> + <translation>Oculta el panell de previsualització d'entrades</translation> </message> <message> <source>General</source> @@ -176,7 +176,7 @@ </message> <message> <source>Hide toolbar (icons)</source> - <translation type="unfinished"/> + <translation>Oculta la barra d'eines (les icones)</translation> </message> <message> <source>Minimize instead of app exit</source> @@ -233,11 +233,11 @@ </message> <message> <source>Check for updates at application startup</source> - <translation type="unfinished"/> + <translation>Comprova si hi ha actualitzacions a l'inici</translation> </message> <message> <source>Include pre-releases when checking for updates</source> - <translation type="unfinished"/> + <translation>Inclou versions provisionals quan es comprovi si hi ha actualitzacions</translation> </message> <message> <source>Movable toolbar</source> @@ -245,7 +245,7 @@ </message> <message> <source>Button style</source> - <translation type="unfinished"/> + <translation>Estil de botó</translation> </message> </context> <context> @@ -433,7 +433,7 @@ Seleccioneu si voleu permetre l'accés.</translation> </message> <message> <source>Ok</source> - <translation type="unfinished"/> + <translation>D'acord</translation> </message> <message> <source>Cancel</source> @@ -589,7 +589,7 @@ Please select the correct database for saving credentials.</source> </message> <message> <source>&Tor Browser</source> - <translation type="unfinished"/> + <translation>Navegador &Tor</translation> </message> <message> <source><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: </source> @@ -597,7 +597,7 @@ Please select the correct database for saving credentials.</source> </message> <message> <source>Executable Files</source> - <translation type="unfinished"/> + <translation>Fitxers executables</translation> </message> <message> <source>All Files</source> @@ -3507,7 +3507,7 @@ We recommend you use the AppImage available on our downloads page.</source> </message> <message> <source>Check for Updates...</source> - <translation type="unfinished"/> + <translation>Comprova si hi ha actualitzacions...</translation> </message> <message> <source>Share entry</source> @@ -3520,15 +3520,15 @@ Expect some bugs and minor issues, this version is not meant for production use. </message> <message> <source>Check for updates on startup?</source> - <translation type="unfinished"/> + <translation>Voleu comprovar si hi ha actualitzacions a l'inici?</translation> </message> <message> <source>Would you like KeePassXC to check for updates on startup?</source> - <translation type="unfinished"/> + <translation>Voleu que KeePassXC comprovi si hi ha actualitzacions a l'inici?</translation> </message> <message> <source>You can always check for updates manually from the application menu.</source> - <translation type="unfinished"/> + <translation>Sempre pots comprovar si hi ha actualitzacions manualment als menús de l'aplicació.</translation> </message> </context> <context> @@ -5194,7 +5194,7 @@ Available commands: </message> <message> <source>Export to %1</source> - <translation type="unfinished"/> + <translation>Exporta a %1</translation> </message> <message> <source>Do you want to trust %1 with the fingerprint of %2 from %3?</source> @@ -5261,7 +5261,7 @@ Available commands: </message> <message> <source>Closing in %1 seconds.</source> - <translation type="unfinished"/> + <translation>Tancant en %1 segons.</translation> </message> </context> <context> @@ -5288,7 +5288,7 @@ Available commands: </message> <message> <source>Custom Settings</source> - <translation type="unfinished"/> + <translation>Paràmetres a mida</translation> </message> <message> <source>Time step:</source> @@ -5309,7 +5309,7 @@ Available commands: </message> <message> <source>7 digits</source> - <translation type="unfinished"/> + <translation>7 dígits</translation> </message> <message> <source>8 digits</source> @@ -5320,11 +5320,11 @@ Available commands: <name>UpdateCheckDialog</name> <message> <source>Checking for updates</source> - <translation type="unfinished"/> + <translation>Comprovant si hi ha actualitzacions</translation> </message> <message> <source>Checking for updates...</source> - <translation type="unfinished"/> + <translation>Comprovant si hi ha actualitzacions...</translation> </message> <message> <source>Close</source> @@ -5332,7 +5332,7 @@ Available commands: </message> <message> <source>Update Error!</source> - <translation type="unfinished"/> + <translation>Error d'actualització!</translation> </message> <message> <source>An error occurred in retrieving update information.</source> @@ -5340,15 +5340,15 @@ Available commands: </message> <message> <source>Please try again later.</source> - <translation type="unfinished"/> + <translation>Si us plau, proveu-ho altre cop més tard.</translation> </message> <message> <source>Software Update</source> - <translation type="unfinished"/> + <translation>Actualització de programari</translation> </message> <message> <source>A new version of KeePassXC is available!</source> - <translation type="unfinished"/> + <translation>Hi ha disponible una nova versió de KeePassXC!</translation> </message> <message> <source>KeePassXC %1 is now available — you have %2.</source> @@ -5356,11 +5356,11 @@ Available commands: </message> <message> <source>Download it at keepassxc.org</source> - <translation type="unfinished"/> + <translation>Descarregueu-ho a keepassxc.org</translation> </message> <message> <source>You're up-to-date!</source> - <translation type="unfinished"/> + <translation>Esteu actualitzats!</translation> </message> <message> <source>KeePassXC %1 is currently the newest version available</source> @@ -5395,7 +5395,7 @@ Available commands: </message> <message> <source>Welcome to KeePassXC %1</source> - <translation type="unfinished"/> + <translation>Benvinguts/des al KeePassXC %1</translation> </message> </context> <context> 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.</translation </message> <message> <source>Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1</source> - <translation type="unfinished"/> + <translation>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</translation> </message> <message> <source>Please see special instructions for browser extension use below</source> - <translation type="unfinished"/> + <translation>Níže si přečtěte konkrétní pokyny pro rozšíření do webového prohlížeče</translation> </message> <message> <source>KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3</source> - <translation type="unfinished"/> + <translation>Aby fungovalo napojení na prohlížeč, je třeba KeePassXC. <br /> Stáhnete ho pro %1 a %2. %3</translation> </message> </context> <context> @@ -696,19 +696,23 @@ Přesunuto %2 klíčů do uživatelsky určených dat.</translation> </message> <message> <source>KeePassXC: Create a new group</source> - <translation type="unfinished"/> + <translation>KeePassXC: vytvořit novou skupinu</translation> </message> <message> <source>A request for creating a new group "%1" has been received. Do you want to create this group? </source> - <translation type="unfinished"/> + <translation>Byl obdržen požadavek na vytvoření nové skupiny „%1“. +Chcete tuto skupinu vytvořit? +</translation> </message> <message> <source>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?</source> - <translation type="unfinished"/> + <translation>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í?</translation> </message> </context> <context> @@ -872,7 +876,7 @@ Would you like to migrate your existing settings now?</source> </message> <message> <source>Key not transformed. This is a bug, please report it to the developers!</source> - <translation type="unfinished"/> + <translation>Klíč nebyl přeměněn. Toto je chyba, nahlaste to vývojářům.</translation> </message> </context> <context> @@ -1630,7 +1634,7 @@ Vypnout bezpečné ukládání a zkusit to znovu?</translation> </message> <message> <source>Shared group...</source> - <translation type="unfinished"/> + <translation>Sdílená skupina…</translation> </message> </context> <context> @@ -2075,15 +2079,15 @@ Vypnout bezpečné ukládání a zkusit to znovu?</translation> </message> <message> <source>The export container %1 is already referenced.</source> - <translation type="unfinished"/> + <translation>Exportní kontejner %1 už je odkazován.</translation> </message> <message> <source>The import container %1 is already imported.</source> - <translation type="unfinished"/> + <translation>Importní kontejner %1 už byl naimportován.</translation> </message> <message> <source>The container %1 imported and export by different groups.</source> - <translation type="unfinished"/> + <translation>Kontejner %1 naimportován a exportován různými skupinami.</translation> </message> </context> <context> @@ -3156,19 +3160,19 @@ Line %2, column %3</source> </message> <message> <source>Disabled share %1</source> - <translation type="unfinished"/> + <translation>Sdílení %1 vypnuto</translation> </message> <message> <source>Import from share %1</source> - <translation type="unfinished"/> + <translation>Importovat ze sdílení %1</translation> </message> <message> <source>Export to share %1</source> - <translation type="unfinished"/> + <translation>Exportovat do sdílení %1</translation> </message> <message> <source>Synchronize with share %1</source> - <translation type="unfinished"/> + <translation>Synchronizovat se sdílením %1</translation> </message> </context> <context> @@ -4053,7 +4057,7 @@ Očekávejte chyby a drobné problémy, tato verze není určena pro produkční </message> <message> <source>Regenerate</source> - <translation>Regenerovat</translation> + <translation>Vytvoř nové</translation> </message> </context> <context> @@ -4856,7 +4860,7 @@ Příkazy k dispozici: </message> <message> <source>Cannot create new group</source> - <translation type="unfinished"/> + <translation>Novou skupinu se nedaří vytvořit</translation> </message> </context> <context> @@ -5132,7 +5136,7 @@ Příkazy k dispozici: </message> <message> <source>Signer:</source> - <translation type="unfinished"/> + <translation>Podepsal(a):</translation> </message> </context> <context> @@ -5255,27 +5259,27 @@ Příkazy k dispozici: </message> <message> <source>Multiple import source path to %1 in %2</source> - <translation type="unfinished"/> + <translation>Popis umístění zdroje pro vícero importů do %1 v %2</translation> </message> <message> <source>Conflicting export target path %1 in %2</source> - <translation type="unfinished"/> + <translation>Kolidující popis umístění %1 cíle exportu v %2</translation> </message> <message> <source>Could not embed signature: Could not open file to write (%1)</source> - <translation type="unfinished"/> + <translation>Nedaří se zapouzdřit podpis: Soubor se nedaří otevřít pro zápis (%1)</translation> </message> <message> <source>Could not embed signature: Could not write file (%1)</source> - <translation type="unfinished"/> + <translation>Nedaří se zapouzdřit podpis: Do souboru se nedaří zapsat (%1)</translation> </message> <message> <source>Could not embed database: Could not open file to write (%1)</source> - <translation type="unfinished"/> + <translation>Nedaří se zapouzdřit databázi: Soubor se nedaří otevřít pro zápis (%1)</translation> </message> <message> <source>Could not embed database: Could not write file (%1)</source> - <translation type="unfinished"/> + <translation>Nedaří se zapouzdřit databázi: Do souboru se nedaří zapsat (%1)</translation> </message> </context> <context> 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 @@ </message> <message> <source>Hide window to system tray when minimized</source> - <translation>Fenster verstecken wenn minimiert</translation> + <translation>Fenster verstecken, wenn minimiert</translation> </message> <message> <source>Language</source> @@ -293,11 +293,11 @@ </message> <message> <source>Re-lock previously locked database after performing Auto-Type</source> - <translation>Datenbank nach Auto-Type automatisch wieder sperren.</translation> + <translation>Datenbank nach Auto-Type automatisch wieder sperren</translation> </message> <message> <source>Don't require password repeat when it is visible</source> - <translation>Keine erneute Passworteingabe verlangen, wenn das Passwort sichtbar ist.</translation> + <translation>Keine erneute Passworteingabe verlangen, wenn das Passwort sichtbar ist</translation> </message> <message> <source>Don't hide passwords when editing them</source> @@ -313,7 +313,7 @@ </message> <message> <source>Hide entry notes by default</source> - <translation>Eintrags-Notizen standardmäßig verstecken</translation> + <translation>Eintragsnotizen standardmäßig verstecken</translation> </message> <message> <source>Privacy</source> @@ -443,7 +443,7 @@ Bitte wählen Sie, ob Sie den Zugriff erlauben möchten.</translation> <source>You have multiple databases open. Please select the correct database for saving credentials.</source> <translation>Du hast mehrere Datenbanken geöffnet. -Bitte wähle die richtige Datenbank zum speichern der Anmeldedaten.</translation> +Bitte wähle die richtige Datenbank zum Speichern der Anmeldedaten.</translation> </message> </context> <context> @@ -594,7 +594,7 @@ Bitte wähle die richtige Datenbank zum speichern der Anmeldedaten.</translation </message> <message> <source><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: </source> - <translation><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:</translation> + <translation><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:</translation> </message> <message> <source>Executable Files</source> @@ -607,19 +607,19 @@ Bitte wähle die richtige Datenbank zum speichern der Anmeldedaten.</translation <message> <source>Do not ask permission for HTTP &Basic Auth</source> <extracomment>An extra HTTP Basic Auth setting</extracomment> - <translation>Nicht nach HTTP Basic Auth fragen</translation> + <translation>Niemals fragen, bevor für "HTTP Basic Auth" auf Anmeldedaten zugegriffen wird</translation> </message> <message> <source>Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1</source> - <translation type="unfinished"/> + <translation>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</translation> </message> <message> <source>Please see special instructions for browser extension use below</source> - <translation type="unfinished"/> + <translation>Bitte beachten Sie die untenstehenden speziellen Anweisungen für die Verwendung der Browser-Erweiterung</translation> </message> <message> <source>KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3</source> - <translation type="unfinished"/> + <translation>KeePassXC-Browser wird für die Funktion der Browserintegration benötigt. <br />Laden Sie es für %1 und %2. %3 herunter.</translation> </message> </context> <context> @@ -670,7 +670,7 @@ Möchten Sie diesen überschreiben?</translation> </message> <message> <source>KeePassXC: Converted KeePassHTTP attributes</source> - <translation>KeepassXC: KeePassHTTP-Attribute wurden umgewandelt</translation> + <translation>KeePassXC: KeePassHTTP-Attribute wurden umgewandelt</translation> </message> <message> <source>Successfully converted attributes from %1 entry(s). @@ -696,19 +696,23 @@ Moved %2 keys to custom data.</source> </message> <message> <source>KeePassXC: Create a new group</source> - <translation type="unfinished"/> + <translation>KeePassXC: Neue Gruppe erstellen</translation> </message> <message> <source>A request for creating a new group "%1" has been received. Do you want to create this group? </source> - <translation type="unfinished"/> + <translation>Eine Anfrage zur Erstellung einer neuen Gruppe "%1" ist eingegangen. +Möchten Sie diese Gruppe erstellen? +</translation> </message> <message> <source>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?</source> - <translation type="unfinished"/> + <translation>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?</translation> </message> </context> <context> @@ -871,7 +875,7 @@ Would you like to migrate your existing settings now?</source> </message> <message> <source>Key not transformed. This is a bug, please report it to the developers!</source> - <translation type="unfinished"/> + <translation>Schlüssel nicht umgewandelt. Dies ist ein Fehler, bitte melden Sie ihn den Entwicklern!</translation> </message> </context> <context> @@ -1630,7 +1634,7 @@ Sicheres Speichern deaktivieren und erneut versuchen?</translation> </message> <message> <source>Shared group...</source> - <translation type="unfinished"/> + <translation>Gemeinsame Gruppe...</translation> </message> </context> <context> @@ -2075,15 +2079,15 @@ Sicheres Speichern deaktivieren und erneut versuchen?</translation> </message> <message> <source>The export container %1 is already referenced.</source> - <translation type="unfinished"/> + <translation>Der Exportcontainer %1 wird bereits referenziert.</translation> </message> <message> <source>The import container %1 is already imported.</source> - <translation type="unfinished"/> + <translation>Der Importcontainer %1 ist bereits importiert.</translation> </message> <message> <source>The container %1 imported and export by different groups.</source> - <translation type="unfinished"/> + <translation>Der Container %1 wird von unterschiedlichen Gruppen importiert und exportiert.</translation> </message> </context> <context> @@ -3154,19 +3158,19 @@ Zeile %2, Spalte %3</translation> </message> <message> <source>Disabled share %1</source> - <translation type="unfinished"/> + <translation>Freigabe %1 deaktiviert</translation> </message> <message> <source>Import from share %1</source> - <translation type="unfinished"/> + <translation>Von Freigabe %1 importieren</translation> </message> <message> <source>Export to share %1</source> - <translation type="unfinished"/> + <translation>Zu Freigabe %1 exportieren</translation> </message> <message> <source>Synchronize with share %1</source> - <translation type="unfinished"/> + <translation>Mit Freigabe %1 synchronisieren</translation> </message> </context> <context> @@ -3447,8 +3451,8 @@ Diese Version ist nicht für den Produktiveinsatz gedacht.</translation> <message> <source>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.</source> - <translation>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.</translation> + <translation>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.</translation> </message> <message> <source>&Import</source> @@ -3815,7 +3819,7 @@ Da sie Fehler beinhalten könnte, ist diese Version nicht für den Produktiveins </message> <message> <source><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></source> - <translation><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></translation> + <translation><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></translation> </message> <message> <source>Passwords do not match.</source> @@ -4854,7 +4858,7 @@ Verfügbare Kommandos: </message> <message> <source>Cannot create new group</source> - <translation type="unfinished"/> + <translation>Neue Gruppe kann nicht erstellt werden</translation> </message> </context> <context> @@ -5130,7 +5134,7 @@ Verfügbare Kommandos: </message> <message> <source>Signer:</source> - <translation type="unfinished"/> + <translation>Unterzeichner:</translation> </message> </context> <context> @@ -5177,7 +5181,7 @@ Verfügbare Kommandos: </message> <message> <source>Signed share container are not supported - import prevented</source> - <translation>Unterzeichnete geteilte Container werden nicht unterstützt. Import verhindert.</translation> + <translation>Unterzeichnete geteilte Container werden nicht unterstützt - Import verhindert</translation> </message> <message> <source>File is not readable</source> @@ -5201,7 +5205,7 @@ Verfügbare Kommandos: </message> <message> <source>Unsigned share container are not supported - import prevented</source> - <translation>Nicht unterzeichnete geteilte Container werden nicht unterstützt. Import verhindert.</translation> + <translation>Nicht unterzeichnete geteilte Container werden nicht unterstützt - Import verhindert</translation> </message> <message> <source>Successful unsigned import</source> @@ -5213,11 +5217,11 @@ Verfügbare Kommandos: </message> <message> <source>Unknown share container type</source> - <translation>Unbekannter geteilter Container-Typ</translation> + <translation>Unbekannter geteilter Containertyp</translation> </message> <message> <source>Overwriting signed share container is not supported - export prevented</source> - <translation>Überschreiben von unterzeichneten geteilten Containern nicht unterstützt. Export verhindert.</translation> + <translation>Überschreiben von unterzeichneten geteilten Containern nicht unterstützt - Export verhindert</translation> </message> <message> <source>Could not write export container (%1)</source> @@ -5225,7 +5229,7 @@ Verfügbare Kommandos: </message> <message> <source>Overwriting unsigned share container is not supported - export prevented</source> - <translation>Überschreiben von nicht unterzeichneten geteilten Containern nicht unterstützt. Export verhindert.</translation> + <translation>Überschreiben von nicht unterzeichneten geteilten Containern nicht unterstützt - Export verhindert</translation> </message> <message> <source>Could not write export container</source> @@ -5253,27 +5257,27 @@ Verfügbare Kommandos: </message> <message> <source>Multiple import source path to %1 in %2</source> - <translation type="unfinished"/> + <translation>Multipler Import-Quellpfad zu %1 in %2</translation> </message> <message> <source>Conflicting export target path %1 in %2</source> - <translation type="unfinished"/> + <translation>Konflikt beim Export-Zielpfad %1 in %2 </translation> </message> <message> <source>Could not embed signature: Could not open file to write (%1)</source> - <translation type="unfinished"/> + <translation>Signatur konnte nicht eingebunden werden: Zum Schreiben konnte die Datei (%1) nicht geöffnet werden </translation> </message> <message> <source>Could not embed signature: Could not write file (%1)</source> - <translation type="unfinished"/> + <translation>Signatur konnte nicht eingebunden werden: Datei konnte nicht geschrieben werden (%1)</translation> </message> <message> <source>Could not embed database: Could not open file to write (%1)</source> - <translation type="unfinished"/> + <translation>Datenbank konnte nicht eingebunden werden: Zum Schreiben konnte die Datei (%1) nicht geöffnet werden </translation> </message> <message> <source>Could not embed database: Could not write file (%1)</source> - <translation type="unfinished"/> + <translation>Datenbank konnte nicht eingebunden werden: Datei konnte nicht geschrieben werden (%1)</translation> </message> </context> <context> @@ -5411,7 +5415,7 @@ Verfügbare Kommandos: </message> <message> <source>You're up-to-date!</source> - <translation>Version aktuel</translation> + <translation>Version aktuell</translation> </message> <message> <source>KeePassXC %1 is currently the newest version available</source> 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 @@ -113,18 +113,6 @@ <translation>Start only a single instance of KeePassXC</translation> </message> <message> - <source>Remember last databases</source> - <translation>Remember last databases</translation> - </message> - <message> - <source>Remember last key files and security dongles</source> - <translation>Remember last key files and security dongles</translation> - </message> - <message> - <source>Load previous databases on startup</source> - <translation>Load previous databases on startup</translation> - </message> - <message> <source>Minimize window at application startup</source> <translation>Minimize window at application startup</translation> </message> @@ -197,10 +185,6 @@ <translation>Hide window to system tray when minimized</translation> </message> <message> - <source>Language</source> - <translation>Language</translation> - </message> - <message> <source>Auto-Type</source> <translation>Auto-Type</translation> </message> @@ -234,20 +218,40 @@ <translation>Auto-Type start delay</translation> </message> <message> - <source>Check for updates at application startup</source> - <translation>Check for updates at application startup</translation> + <source>Movable toolbar</source> + <translation>Movable toolbar</translation> </message> <message> - <source>Include pre-releases when checking for updates</source> - <translation>Include pre-releases when checking for updates</translation> + <source>Remember previously used databases</source> + <translation type="unfinished"></translation> </message> <message> - <source>Movable toolbar</source> - <translation>Movable toolbar</translation> + <source>Load previously open databases on startup</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Remember database key files and security dongles</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Check for updates at application startup once per week</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Include beta releases when checking for updates</source> + <translation type="unfinished"></translation> </message> <message> - <source>Button style</source> - <translation>Button style</translation> + <source>Button style:</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Language:</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>(restart program to activate)</source> + <translation type="unfinished"></translation> </message> </context> <context> @@ -623,6 +627,10 @@ Please select the correct database for saving credentials.</translation> <source>KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3</source> <translation type="unfinished"></translation> </message> + <message> + <source>&Brave</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>BrowserService</name> @@ -891,6 +899,11 @@ Would you like to migrate your existing settings now?</source> <source>Key not transformed. This is a bug, please report it to the developers!</source> <translation type="unfinished"></translation> </message> + <message> + <source>%1 +Backup database located at %2</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>DatabaseOpenDialog</name> @@ -960,16 +973,12 @@ Please consider generating a new key file.</translation> <translation>TouchID for quick unlock</translation> </message> <message> - <source>Unable to open the database: -%1</source> - <translation>Unable to open the database: -%1</translation> + <source>Failed to open key file: %1</source> + <translation type="unfinished"></translation> </message> <message> - <source>Can't open key file: -%1</source> - <translation>Can't open key file: -%1</translation> + <source>Select slot...</source> + <translation type="unfinished"></translation> </message> </context> <context> @@ -1459,10 +1468,6 @@ This is definitely a bug, please report it to the developers.</source> This is definitely a bug, please report it to the developers.</translation> </message> <message> - <source>The database file does not exist or is not accessible.</source> - <translation>The database file does not exist or is not accessible.</translation> - </message> - <message> <source>Select CSV file</source> <translation>Select CSV file</translation> </message> @@ -1485,6 +1490,10 @@ This is definitely a bug, please report it to the developers.</translation> <comment>Database tab name modifier</comment> <translation>%1 [Read-only]</translation> </message> + <message> + <source>Failed to open %1. It either does not exist or is not accessible.</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>DatabaseWidget</name> @@ -1631,12 +1640,6 @@ Disable safe saves and try again?</source> Disable safe saves and try again?</translation> </message> <message> - <source>Writing the database failed. -%1</source> - <translation>Writing the database failed. -%1</translation> - </message> - <message> <source>Passwords</source> <translation>Passwords</translation> </message> @@ -1683,6 +1686,10 @@ Disable safe saves and try again?</translation> <source>Shared group...</source> <translation type="unfinished"></translation> </message> + <message> + <source>Writing the database failed: %1</source> + <translation type="unfinished">Writing the database failed: %1</translation> + </message> </context> <context> <name>EditEntryWidget</name> @@ -1885,6 +1892,14 @@ Disable safe saves and try again?</translation> <source>Use a specific sequence for this association:</source> <translation>Use a specific sequence for this association:</translation> </message> + <message> + <source>Open AutoType help webpage</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>AutoType help button</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>EditEntryWidgetHistory</name> @@ -2054,6 +2069,10 @@ Disable safe saves and try again?</translation> <source>Inherit from parent group (%1)</source> <translation>Inherit from parent group (%1)</translation> </message> + <message> + <source>Entry has unsaved changes</source> + <translation type="unfinished">Entry has unsaved changes</translation> + </message> </context> <context> <name>EditGroupWidgetKeeShare</name> @@ -2082,67 +2101,69 @@ Disable safe saves and try again?</translation> <translation>Inactive</translation> </message> <message> - <source>Import from path</source> - <translation>Import from path</translation> + <source>KeeShare unsigned container</source> + <translation>KeeShare unsigned container</translation> </message> <message> - <source>Export to path</source> - <translation>Export to path</translation> + <source>KeeShare signed container</source> + <translation>KeeShare signed container</translation> </message> <message> - <source>Synchronize with path</source> - <translation>Synchronize with path</translation> + <source>Select import source</source> + <translation>Select import source</translation> </message> <message> - <source>Your KeePassXC version does not support sharing your container type. Please use %1.</source> - <translation>Your KeePassXC version does not support sharing your container type. Please use %1.</translation> + <source>Select export target</source> + <translation>Select export target</translation> </message> <message> - <source>Database sharing is disabled</source> - <translation>Database sharing is disabled</translation> + <source>Select import/export file</source> + <translation>Select import/export file</translation> </message> <message> - <source>Database export is disabled</source> - <translation>Database export is disabled</translation> + <source>Clear</source> + <translation type="unfinished">Clear</translation> </message> <message> - <source>Database import is disabled</source> - <translation>Database import is disabled</translation> + <source>Import</source> + <translation type="unfinished">Import</translation> </message> <message> - <source>KeeShare unsigned container</source> - <translation>KeeShare unsigned container</translation> + <source>Export</source> + <translation type="unfinished">Export</translation> </message> <message> - <source>KeeShare signed container</source> - <translation>KeeShare signed container</translation> + <source>Synchronize</source> + <translation type="unfinished"></translation> </message> <message> - <source>Select import source</source> - <translation>Select import source</translation> + <source>Your KeePassXC version does not support sharing this container type. +Supported extensions are: %1.</source> + <translation type="unfinished"></translation> </message> <message> - <source>Select export target</source> - <translation>Select export target</translation> + <source>%1 is already being exported by this database.</source> + <translation type="unfinished"></translation> </message> <message> - <source>Select import/export file</source> - <translation>Select import/export file</translation> + <source>%1 is already being imported by this database.</source> + <translation type="unfinished"></translation> </message> <message> - <source>Clear</source> - <translation type="unfinished">Clear</translation> + <source>%1 is being imported and exported by different groups in this database.</source> + <translation type="unfinished"></translation> </message> <message> - <source>The export container %1 is already referenced.</source> + <source>KeeShare is currently disabled. You can enable import/export in the application settings.</source> + <comment>KeeShare is a proper noun</comment> <translation type="unfinished"></translation> </message> <message> - <source>The import container %1 is already imported.</source> + <source>Database export is currently disabled by application settings.</source> <translation type="unfinished"></translation> </message> <message> - <source>The container %1 imported and export by different groups.</source> + <source>Database import is currently disabled by application settings.</source> <translation type="unfinished"></translation> </message> </context> @@ -2669,10 +2690,6 @@ This may cause the affected plugins to malfunction.</translation> <translation>Unable to issue challenge-response.</translation> </message> <message> - <source>Wrong key or database file is corrupt.</source> - <translation>Wrong key or database file is corrupt.</translation> - </message> - <message> <source>missing database headers</source> <translation>missing database headers</translation> </message> @@ -2692,6 +2709,11 @@ This may cause the affected plugins to malfunction.</translation> <source>Invalid header data length</source> <translation>Invalid header data length</translation> </message> + <message> + <source>Invalid credentials were provided, please try again. +If this reoccurs, then your database file may be corrupt.</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>Kdbx3Writer</name> @@ -2723,10 +2745,6 @@ This may cause the affected plugins to malfunction.</translation> <translation>Header SHA256 mismatch</translation> </message> <message> - <source>Wrong key or database file is corrupt. (HMAC mismatch)</source> - <translation>Wrong key or database file is corrupt. (HMAC mismatch)</translation> - </message> - <message> <source>Unknown cipher</source> <translation>Unknown cipher</translation> </message> @@ -2826,6 +2844,15 @@ This may cause the affected plugins to malfunction.</translation> <extracomment>Translation: variant map = data structure for storing meta data</extracomment> <translation>Invalid variant map field type size</translation> </message> + <message> + <source>Invalid credentials were provided, please try again. +If this reoccurs, then your database file may be corrupt.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>(HMAC mismatch)</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>Kdbx4Writer</name> @@ -3112,10 +3139,6 @@ Line %2, column %3</translation> <translation>Unable to calculate master key</translation> </message> <message> - <source>Wrong key or database file is corrupt.</source> - <translation>Wrong key or database file is corrupt.</translation> - </message> - <message> <source>Key transformation failed</source> <translation>Key transformation failed</translation> </message> @@ -3211,39 +3234,56 @@ Line %2, column %3</translation> <source>unable to seek to content position</source> <translation>unable to seek to content position</translation> </message> + <message> + <source>Invalid credentials were provided, please try again. +If this reoccurs, then your database file may be corrupt.</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>KeeShare</name> <message> - <source>Disabled share</source> - <translation>Disabled share</translation> + <source>Invalid sharing reference</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Inactive share %1</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Imported from %1</source> + <translation type="unfinished">Imported from %1</translation> + </message> + <message> + <source>Exported to %1</source> + <translation type="unfinished"></translation> </message> <message> - <source>Import from</source> - <translation>Import from</translation> + <source>Synchronized with %1</source> + <translation type="unfinished"></translation> </message> <message> - <source>Export to</source> - <translation>Export to</translation> + <source>Import is disabled in settings</source> + <translation type="unfinished"></translation> </message> <message> - <source>Synchronize with</source> - <translation>Synchronize with</translation> + <source>Export is disabled in settings</source> + <translation type="unfinished"></translation> </message> <message> - <source>Disabled share %1</source> + <source>Inactive share</source> <translation type="unfinished"></translation> </message> <message> - <source>Import from share %1</source> + <source>Imported from</source> <translation type="unfinished"></translation> </message> <message> - <source>Export to share %1</source> + <source>Exported to</source> <translation type="unfinished"></translation> </message> <message> - <source>Synchronize with share %1</source> + <source>Synchronized with</source> <translation type="unfinished"></translation> </message> </context> @@ -4939,6 +4979,84 @@ Available commands: <source>Cannot create new group</source> <translation type="unfinished"></translation> </message> + <message> + <source>Deactivate password key for the database.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Displays debugging information.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Deactivate password key for the database to merge from.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Version %1</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Build Type: %1</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Revision: %1</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Distribution: %1</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Debugging mode is disabled.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Debugging mode is enabled.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Operating system: %1 +CPU architecture: %2 +Kernel: %3 %4</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Auto-Type</source> + <translation type="unfinished">Auto-Type</translation> + </message> + <message> + <source>KeeShare (signed and unsigned sharing)</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>KeeShare (only signed sharing)</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>KeeShare (only unsigned sharing)</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>YubiKey</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>TouchID</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>None</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Enabled extensions:</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Cryptographic libraries:</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>QtIOCompressor</name> 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 @@ <name>AgentSettingsWidget</name> <message> <source>Enable SSH Agent (requires restart)</source> - <translation>Habilitar el Agente SSH (requiere reinicio)</translation> + <translation>Habilitar el Agente de SSH (requiere reinicio)</translation> </message> <message> <source>Use OpenSSH for Windows instead of Pageant</source> @@ -184,7 +184,7 @@ </message> <message> <source>Show a system tray icon</source> - <translation>Mostrar icono en la bandeja de del sistema</translation> + <translation>Mostrar icono en la bandeja del sistema</translation> </message> <message> <source>Dark system tray icon</source> @@ -204,11 +204,11 @@ </message> <message> <source>Use entry title to match windows for global Auto-Type</source> - <translation>Use título de entrada para acertar ventanas en Auto-Tipeado global.</translation> + <translation>Use título de entrada para acertar ventanas en Auto-Escritura global.</translation> </message> <message> <source>Use entry URL to match windows for global Auto-Type</source> - <translation>Use URL para acertar ventanas en Auto-Tipedo global</translation> + <translation>Use URL para acertar ventanas en Auto-Escritura global</translation> </message> <message> <source>Always ask before performing Auto-Type</source> @@ -340,7 +340,7 @@ </message> <message> <source>The Syntax of your Auto-Type statement is incorrect!</source> - <translation>¡La sintaxis de la declaración de su auto-escritura es incorrecta!</translation> + <translation>¡La sintaxis de la declaración de su Auto-Escritura es incorrecta!</translation> </message> <message> <source>This Auto-Type command contains a very long delay. Do you really want to proceed?</source> @@ -404,7 +404,7 @@ <name>BrowserAccessControlDialog</name> <message> <source>KeePassXC-Browser Confirm Access</source> - <translation>KeePassXC-Navegador Confirmar Acceso</translation> + <translation>KeePassXC-Browser Confirmar Acceso</translation> </message> <message> <source>Remember this decision</source> @@ -454,7 +454,7 @@ Por favor, seleccione la base de datos correcta para guardar las credenciales.</ </message> <message> <source>This is required for accessing your databases with KeePassXC-Browser</source> - <translation>Esto es necesario para acceder a las bases de datos con KeePassXC-Navegador</translation> + <translation>Esto es necesario para acceder a las bases de datos con KeePassXC-Browser</translation> </message> <message> <source>Enable KeepassXC browser integration</source> @@ -611,15 +611,15 @@ Por favor, seleccione la base de datos correcta para guardar las credenciales.</ </message> <message> <source>Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1</source> - <translation type="unfinished"/> + <translation>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</translation> </message> <message> <source>Please see special instructions for browser extension use below</source> - <translation type="unfinished"/> + <translation>Por favor ve las instrucciones especiales para el uso de extensiones del navegador debajo.</translation> </message> <message> <source>KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3</source> - <translation type="unfinished"/> + <translation>KeePassXC-Browser es necesario para que la integración con el navegador funcione. <br />Descárguelo para %1 y %2. %3</translation> </message> </context> <context> @@ -697,19 +697,23 @@ Movió %2 claves a datos personalizados.</translation> </message> <message> <source>KeePassXC: Create a new group</source> - <translation type="unfinished"/> + <translation>KeePassXC: Crear un grupo nuevo</translation> </message> <message> <source>A request for creating a new group "%1" has been received. Do you want to create this group? </source> - <translation type="unfinished"/> + <translation>Una solicitud para crear un nuevo grupo "%1" se ha recibido. +¿Quiere crear este grupo? +</translation> </message> <message> <source>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?</source> - <translation type="unfinished"/> + <translation>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?</translation> </message> </context> <context> @@ -873,7 +877,7 @@ Would you like to migrate your existing settings now?</source> </message> <message> <source>Key not transformed. This is a bug, please report it to the developers!</source> - <translation type="unfinished"/> + <translation>Llave no está transformada. Esto es un bug, por favor, ¡informe sobre él a los desarrolladores!</translation> </message> </context> <context> @@ -1006,7 +1010,7 @@ Considere generar un nuevo archivo llave.</translation> </message> <message> <source>Move KeePassHTTP attributes to KeePassXC-Browser &custom data</source> - <translation>Mueva los atributos de KeePassHTTP a los datos &personalizados de KeePassXC-Browser</translation> + <translation>Mover los atributos de KeePassHTTP a los datos &personalizados de KeePassXC-Browser</translation> </message> <message> <source>Stored keys</source> @@ -1631,7 +1635,7 @@ Disable safe saves and try again?</source> </message> <message> <source>Shared group...</source> - <translation type="unfinished"/> + <translation>Grupo compartido...</translation> </message> </context> <context> @@ -2076,15 +2080,15 @@ Disable safe saves and try again?</source> </message> <message> <source>The export container %1 is already referenced.</source> - <translation type="unfinished"/> + <translation>El contenedor de exportación %1 ya es referenciado.</translation> </message> <message> <source>The import container %1 is already imported.</source> - <translation type="unfinished"/> + <translation>El contenedor de importación %1 ya es importado.</translation> </message> <message> <source>The container %1 imported and export by different groups.</source> - <translation type="unfinished"/> + <translation>El contenedor %1 se importa y se exporta por grupos diferentes.</translation> </message> </context> <context> @@ -2928,7 +2932,7 @@ Esta migración es en único sentido. No podrá abrir la base de datos importada </message> <message> <source>Auto-type association window or sequence missing</source> - <translation>Falta de secuencia o ventana de Asociación de auto-tipeado</translation> + <translation>Falta de secuencia o ventana de asociación de Auto-Escritura</translation> </message> <message> <source>Invalid bool value</source> @@ -3155,19 +3159,19 @@ Linea %2, columna %3</translation> </message> <message> <source>Disabled share %1</source> - <translation type="unfinished"/> + <translation>Deshabilitada cuota %1</translation> </message> <message> <source>Import from share %1</source> - <translation type="unfinished"/> + <translation>Importar de cuota %1</translation> </message> <message> <source>Export to share %1</source> - <translation type="unfinished"/> + <translation>Exportar a cuota %1</translation> </message> <message> <source>Synchronize with share %1</source> - <translation type="unfinished"/> + <translation>Sincronizar con cuota %1</translation> </message> </context> <context> @@ -3518,7 +3522,7 @@ Le recomendamos que utilice la AppImage disponible en nuestra página de descarg </message> <message> <source>Perform &Auto-Type</source> - <translation>Relizar &Auto-Escritura</translation> + <translation>Realizar &Auto-Escritura</translation> </message> <message> <source>Open &URL</source> @@ -4205,7 +4209,7 @@ Espere algunos errores y problemas menores, esta versión no está destinada par </message> <message> <source>Path of the entry to add.</source> - <translation>Camino de la entrada para añadir.</translation> + <translation>Ruta de la entrada para añadir.</translation> </message> <message> <source>Copy an entry's password to the clipboard.</source> @@ -4214,7 +4218,7 @@ Espere algunos errores y problemas menores, esta versión no está destinada par <message> <source>Path of the entry to clip.</source> <comment>clip = copy to clipboard</comment> - <translation>Camino de la entrada para copiar.</translation> + <translation>Ruta de la entrada para copiar.</translation> </message> <message> <source>Timeout in seconds before clearing the clipboard.</source> @@ -4234,7 +4238,7 @@ Espere algunos errores y problemas menores, esta versión no está destinada par </message> <message> <source>Path of the entry to edit.</source> - <translation>Camino de la entrada para editar.</translation> + <translation>Ruta de la entrada para editar.</translation> </message> <message> <source>Estimate the entropy of a password.</source> @@ -4805,7 +4809,7 @@ Comandos disponibles: </message> <message> <source>Path of the entry to remove.</source> - <translation>Camino de la entrada a quitar.</translation> + <translation>Ruta de la entrada a quitar.</translation> </message> <message> <source>Existing single-instance lock file is invalid. Launching new instance.</source> @@ -4857,7 +4861,7 @@ Comandos disponibles: </message> <message> <source>Cannot create new group</source> - <translation type="unfinished"/> + <translation>No se puede crear el nuevo grupo</translation> </message> </context> <context> @@ -5133,7 +5137,7 @@ Comandos disponibles: </message> <message> <source>Signer:</source> - <translation type="unfinished"/> + <translation>Firmante:</translation> </message> </context> <context> @@ -5256,27 +5260,27 @@ Comandos disponibles: </message> <message> <source>Multiple import source path to %1 in %2</source> - <translation type="unfinished"/> + <translation>Ruta de origen de importación múltiple a %1 en %2</translation> </message> <message> <source>Conflicting export target path %1 in %2</source> - <translation type="unfinished"/> + <translation>Ruta de destino de exportación contradictoria %1 en %2</translation> </message> <message> <source>Could not embed signature: Could not open file to write (%1)</source> - <translation type="unfinished"/> + <translation>No se puede incrustar la firma: no se puede abrir el archivo para escribir (%1)</translation> </message> <message> <source>Could not embed signature: Could not write file (%1)</source> - <translation type="unfinished"/> + <translation>No se puede incrustar la firma: no se puede escribir el archivo (%1)</translation> </message> <message> <source>Could not embed database: Could not open file to write (%1)</source> - <translation type="unfinished"/> + <translation>No se puede incrustar la base de datos: no se puede abrir el archivo para escribir (%1)</translation> </message> <message> <source>Could not embed database: Could not write file (%1)</source> - <translation type="unfinished"/> + <translation>No se puede incrustar la base de datos: no se puede escribir el archivo (%1)</translation> </message> </context> <context> 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</translation> </message> <message> <source>Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1</source> - <translation type="unfinished"/> + <translation>Snap:in hiekkalaatikon takia sinun täytyy suorittaa komentosarja jotta voit aktivoida selainintegraation.<br />Voit ladata komentosarjan osoitteesta %1</translation> </message> <message> <source>Please see special instructions for browser extension use below</source> - <translation type="unfinished"/> + <translation>Katso yksityiskohtaisemmat ohjeet selainlaajennuksen käyttöön alta</translation> </message> <message> <source>KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3</source> - <translation type="unfinished"/> + <translation>KeePassXC-Browser tarvitaan selainintegraation toimimista varten.<br />Dataa se seuraaville selaimille: %1 ja %2. %3</translation> </message> </context> <context> @@ -695,19 +695,22 @@ Siirrettiin %2 avainta mukautettuihin tietoihin.</translation> </message> <message> <source>KeePassXC: Create a new group</source> - <translation type="unfinished"/> + <translation>KeePassXC: Luo uusi ryhmä</translation> </message> <message> <source>A request for creating a new group "%1" has been received. Do you want to create this group? </source> - <translation type="unfinished"/> + <translation>Vastaanotettiin pyyntö luoda uusi ryhmä "%1". +Haluatko varmasti luoda tämän ryhmän?</translation> </message> <message> <source>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?</source> - <translation type="unfinished"/> + <translation>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?</translation> </message> </context> <context> @@ -871,7 +874,7 @@ Would you like to migrate your existing settings now?</source> </message> <message> <source>Key not transformed. This is a bug, please report it to the developers!</source> - <translation type="unfinished"/> + <translation>Avainmuunnosta ei voitu suorittaa. Ole hyvä ja ilmoita tästä virheestä sovelluksen kehittäjille.</translation> </message> </context> <context> @@ -1630,7 +1633,7 @@ Ota turvallinen tallennus pois käytöstä ja yritä uudelleen?</translation> </message> <message> <source>Shared group...</source> - <translation type="unfinished"/> + <translation>Jaettu ryhmä...</translation> </message> </context> <context> @@ -2075,15 +2078,15 @@ Ota turvallinen tallennus pois käytöstä ja yritä uudelleen?</translation> </message> <message> <source>The export container %1 is already referenced.</source> - <translation type="unfinished"/> + <translation>Vientisäiliöön %1 on jo viitattu.</translation> </message> <message> <source>The import container %1 is already imported.</source> - <translation type="unfinished"/> + <translation>Tuontisäiliö %1 on jo tuotu.</translation> </message> <message> <source>The container %1 imported and export by different groups.</source> - <translation type="unfinished"/> + <translation>Säiliö %1 on tuotu ja viety eri ryhmien perusteella.</translation> </message> </context> <context> @@ -3154,19 +3157,19 @@ Rivi %2, sarake %3</translation> </message> <message> <source>Disabled share %1</source> - <translation type="unfinished"/> + <translation>Jako %1 otettu pois käytöstä</translation> </message> <message> <source>Import from share %1</source> - <translation type="unfinished"/> + <translation>Tuo jaosta %1</translation> </message> <message> <source>Export to share %1</source> - <translation type="unfinished"/> + <translation>Vie jaosta %1</translation> </message> <message> <source>Synchronize with share %1</source> - <translation type="unfinished"/> + <translation>Synkronoi jaon %1 kanssa</translation> </message> </context> <context> @@ -4855,7 +4858,7 @@ Käytettävissä olevat komennot: </message> <message> <source>Cannot create new group</source> - <translation type="unfinished"/> + <translation>Uutta ryhmää ei voitu luoda</translation> </message> </context> <context> @@ -5131,7 +5134,7 @@ Käytettävissä olevat komennot: </message> <message> <source>Signer:</source> - <translation type="unfinished"/> + <translation>Allekirjoittaja:</translation> </message> </context> <context> @@ -5250,31 +5253,31 @@ Käytettävissä olevat komennot: </message> <message> <source>Do you want to trust %1 with the fingerprint of %2 from %3?</source> - <translation type="unfinished"/> + <translation>Haluatko luottaa kohteeseen %1 sormenjäljellä %2, joka on peräisin kohteesta %3? {1 ?} {2 ?}</translation> </message> <message> <source>Multiple import source path to %1 in %2</source> - <translation type="unfinished"/> + <translation>Useampi lähde kohteeseen %1 tuonnissa %2</translation> </message> <message> <source>Conflicting export target path %1 in %2</source> - <translation type="unfinished"/> + <translation>Ristiriita viennin %2 kohdepolussa %1</translation> </message> <message> <source>Could not embed signature: Could not open file to write (%1)</source> - <translation type="unfinished"/> + <translation>Allekirjoitusta ei voitu sisällyttää: Tiedostoa ei voitu avata kirjoitusta varten (%1)</translation> </message> <message> <source>Could not embed signature: Could not write file (%1)</source> - <translation type="unfinished"/> + <translation>Allekirjoitusta ei voitu sisällyttää: Tiedostoon kirjoitus epäonnistui (%1)</translation> </message> <message> <source>Could not embed database: Could not open file to write (%1)</source> - <translation type="unfinished"/> + <translation>Tietokantaa ei voitu sisällyttää: Tiedostoa ei voitu avata kirjoitusta varten (%1)</translation> </message> <message> <source>Could not embed database: Could not write file (%1)</source> - <translation type="unfinished"/> + <translation>Tietokantaa ei voitu sisällyttää: Tiedostoon kirjoitus epäonnistui (%1)</translation> </message> </context> <context> 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 </message> <message> <source>Please see special instructions for browser extension use below</source> - <translation type="unfinished"/> + <translation>Veuillez regarder les instructions spéciales pour l'extension du navigateur utilisé ci-dessous</translation> </message> <message> <source>KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3</source> - <translation type="unfinished"/> + <translation>KeePassXC-Browser est nécessaire pour que l'intégration au navigateur fonctionne. <br />Téléchargez-le pour %1 et%2. %3</translation> </message> </context> <context> @@ -696,13 +696,15 @@ Moved %2 keys to custom data.</source> </message> <message> <source>KeePassXC: Create a new group</source> - <translation type="unfinished"/> + <translation>KeePassXC : Créer un nouveau groupe</translation> </message> <message> <source>A request for creating a new group "%1" has been received. Do you want to create this group? </source> - <translation type="unfinished"/> + <translation>Une demande de création pour un nouveau groupe "%1" a été reçue. +Voulez-vous créer ce groupe ? +</translation> </message> <message> <source>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 ?</translation> </message> <message> <source>Shared group...</source> - <translation type="unfinished"/> + <translation>Groupe partagé ...</translation> </message> </context> <context> @@ -2033,7 +2035,7 @@ Désactiver les enregistrements sécurisés et ressayer ?</translation> </message> <message> <source>Your KeePassXC version does not support sharing your container type. Please use %1.</source> - <translation type="unfinished"/> + <translation>Votre version de KeePassXC ne supporte pas le partage de ce type de conteneur. Veuillez utiliser %1.</translation> </message> <message> <source>Database sharing is disabled</source> @@ -2073,15 +2075,15 @@ Désactiver les enregistrements sécurisés et ressayer ?</translation> </message> <message> <source>The export container %1 is already referenced.</source> - <translation type="unfinished"/> + <translation>Le conteneur d'export %1 est déjà référencé.</translation> </message> <message> <source>The import container %1 is already imported.</source> - <translation type="unfinished"/> + <translation>Le conteneur d'import %1 est déjà importé.</translation> </message> <message> <source>The container %1 imported and export by different groups.</source> - <translation type="unfinished"/> + <translation>Le conteneur %1 est importé et exporté par des groupes différents.</translation> </message> </context> <context> @@ -3151,19 +3153,19 @@ Ligne %2, colonne %3</translation> </message> <message> <source>Disabled share %1</source> - <translation type="unfinished"/> + <translation>Partage %1 désactivé</translation> </message> <message> <source>Import from share %1</source> - <translation type="unfinished"/> + <translation>Importer du partage %1</translation> </message> <message> <source>Export to share %1</source> - <translation type="unfinished"/> + <translation>Exporter vers le partage %1</translation> </message> <message> <source>Synchronize with share %1</source> - <translation type="unfinished"/> + <translation>Synchroniser avec le partage %1</translation> </message> </context> <context> @@ -4685,7 +4687,7 @@ Commandes disponibles : </message> <message> <source>Successfully recycled entry %1.</source> - <translation type="unfinished"/> + <translation>Entrée %1 recyclée avec succès.</translation> </message> <message> <source>Successfully deleted entry %1.</source> @@ -4783,7 +4785,7 @@ Commandes disponibles : </message> <message> <source>Insert password to encrypt database (Press enter to leave blank): </source> - <translation type="unfinished"/> + <translation>Introduire le mot de passe pour chiffrer la base de données (Presser retour pour laisser vide) :</translation> </message> <message> <source>Creating KeyFile %1 failed: %2</source> @@ -4851,7 +4853,7 @@ Commandes disponibles : </message> <message> <source>Cannot create new group</source> - <translation type="unfinished"/> + <translation>Impossible de créer de nouveau groupe</translation> </message> </context> <context> @@ -4943,7 +4945,7 @@ Commandes disponibles : </message> <message> <source>exclude term from results</source> - <translation type="unfinished"/> + <translation>exclure le terme des résultats</translation> </message> <message> <source>match term exactly</source> @@ -4951,7 +4953,7 @@ Commandes disponibles : </message> <message> <source>use regex in term</source> - <translation type="unfinished"/> + <translation>utiliser les expressions régulières dans le terminal</translation> </message> <message> <source>Fields</source> @@ -5107,7 +5109,7 @@ Commandes disponibles : </message> <message> <source>KeeShare key file</source> - <translation type="unfinished"/> + <translation>fichier-clé KeeShare</translation> </message> <message> <source>All files</source> @@ -5134,7 +5136,7 @@ Commandes disponibles : <name>ShareObserver</name> <message> <source>Import from container without signature</source> - <translation type="unfinished"/> + <translation>Importer depuis le conteneur sans signature</translation> </message> <message> <source>We cannot verify the source of the shared container because it is not signed. Do you really want to import from %1?</source> @@ -5142,7 +5144,7 @@ Commandes disponibles : </message> <message> <source>Import from container with certificate</source> - <translation type="unfinished"/> + <translation>Importer depuis le conteneur avec certificat</translation> </message> <message> <source>Not this time</source> @@ -5234,15 +5236,15 @@ Commandes disponibles : </message> <message> <source>Export to %1 failed (%2)</source> - <translation type="unfinished"/> + <translation>Échec de l'export vers %1 (%2)</translation> </message> <message> <source>Export to %1 successful (%2)</source> - <translation type="unfinished"/> + <translation>Réussite de l'export vers %1 (%2)</translation> </message> <message> <source>Export to %1</source> - <translation type="unfinished"/> + <translation>Exporter vers %1</translation> </message> <message> <source>Do you want to trust %1 with the fingerprint of %2 from %3?</source> 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.</translati </message> <message> <source>Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1</source> - <translation type="unfinished"/> + <translation>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</translation> </message> <message> <source>Please see special instructions for browser extension use below</source> - <translation type="unfinished"/> + <translation>Olvassa el a böngészőkiegészítő használatáról szóló különleges utasításokat alább</translation> </message> <message> <source>KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3</source> - <translation type="unfinished"/> + <translation>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</translation> </message> </context> <context> @@ -695,19 +695,22 @@ Moved %2 keys to custom data.</source> </message> <message> <source>KeePassXC: Create a new group</source> - <translation type="unfinished"/> + <translation>KeePassXC: Új csoport létrehozása</translation> </message> <message> <source>A request for creating a new group "%1" has been received. Do you want to create this group? </source> - <translation type="unfinished"/> + <translation>Az új „%1” csoport létrehozási kérése fogadva. +Biztos, hogy létrehozza ezt a csoportot?</translation> </message> <message> <source>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?</source> - <translation type="unfinished"/> + <translation>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?</translation> </message> </context> <context> @@ -871,7 +874,7 @@ Would you like to migrate your existing settings now?</source> </message> <message> <source>Key not transformed. This is a bug, please report it to the developers!</source> - <translation type="unfinished"/> + <translation>A kulcs nincs átalakítva. Ez egy hiba, jelezze a fejlesztőknek!</translation> </message> </context> <context> @@ -1531,7 +1534,7 @@ Egyesíti a módosításokat?</translation> </message> <message numerus="yes"> <source>Delete entry(s)?</source> - <translation><numerusform>Törli az bejegyzést?</numerusform><numerusform>Törli az bejegyzéseket?</numerusform></translation> + <translation><numerusform>Törli a bejegyzést?</numerusform><numerusform>Törli a bejegyzéseket?</numerusform></translation> </message> <message numerus="yes"> <source>Move entry(s) to recycle bin?</source> @@ -1601,11 +1604,11 @@ Letiltható a biztonságos mentés és úgy megkísérelhető a mentés?</transl </message> <message> <source>Replace references to entry?</source> - <translation>Lecserélhető a bejegyzésre való hivatkozás?</translation> + <translation>Lecseréli a bejegyzésre mutató hivatkozásokat?</translation> </message> <message numerus="yes"> <source>Entry "%1" has %2 reference(s). Do you want to overwrite references with values, skip this entry, or delete anyway?</source> - <translation><numerusform>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?</numerusform><numerusform>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?</numerusform></translation> + <translation><numerusform>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?</numerusform><numerusform>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?</numerusform></translation> </message> <message> <source>Delete group</source> @@ -1613,11 +1616,11 @@ Letiltható a biztonságos mentés és úgy megkísérelhető a mentés?</transl </message> <message> <source>Move group to recycle bin?</source> - <translation>Legyen a csoport áthelyezve a kukába?</translation> + <translation>Áthelyezi a csoportot a kukába?</translation> </message> <message> <source>Do you really want to move the group "%1" to the recycle bin?</source> - <translation>Valóban legyen a(z) „%1” csoport áthelyezve a kukába?</translation> + <translation>Valóban áthelyezi a(z) „%1” csoportok a kukába?</translation> </message> <message> <source>Successfully merged the database files.</source> @@ -1629,7 +1632,7 @@ Letiltható a biztonságos mentés és úgy megkísérelhető a mentés?</transl </message> <message> <source>Shared group...</source> - <translation type="unfinished"/> + <translation>Megosztott csoport…</translation> </message> </context> <context> @@ -1798,7 +1801,7 @@ Letiltható a biztonságos mentés és úgy megkísérelhető a mentés?</transl </message> <message> <source>Inherit default Auto-Type sequence from the &group</source> - <translation>Az alapértelmezett automatikus beírási sorrend öröklése a cso&porttól</translation> + <translation>Az alapértelmezett automatikus beírási sorrend öröklése a &csoporttól</translation> </message> <message> <source>&Use custom Auto-Type sequence:</source> @@ -2074,15 +2077,15 @@ Letiltható a biztonságos mentés és úgy megkísérelhető a mentés?</transl </message> <message> <source>The export container %1 is already referenced.</source> - <translation type="unfinished"/> + <translation>A(z) %1 exportálása konténerre már van hivatkozás.</translation> </message> <message> <source>The import container %1 is already imported.</source> - <translation type="unfinished"/> + <translation>A(z) %1 importálási konténer már be lett importálva.</translation> </message> <message> <source>The container %1 imported and export by different groups.</source> - <translation type="unfinished"/> + <translation>A(z) %1 konténer importálva, és exportálás különböző csoportoknak.</translation> </message> </context> <context> @@ -3153,19 +3156,19 @@ Line %2, column %3</source> </message> <message> <source>Disabled share %1</source> - <translation type="unfinished"/> + <translation>%1 megosztás letiltva</translation> </message> <message> <source>Import from share %1</source> - <translation type="unfinished"/> + <translation>Importálás a(z) %1 megosztásból</translation> </message> <message> <source>Export to share %1</source> - <translation type="unfinished"/> + <translation>Exportálás a(z) %1 megosztásba</translation> </message> <message> <source>Synchronize with share %1</source> - <translation type="unfinished"/> + <translation>Szinkronizálás a(z) %1 megosztásssal</translation> </message> </context> <context> @@ -3285,11 +3288,11 @@ Message: %2</source> </message> <message> <source>E&ntries</source> - <translation>Be&jegyzések</translation> + <translation>&Bejegyzések</translation> </message> <message> <source>&Groups</source> - <translation>Cso&portok</translation> + <translation>&Csoportok</translation> </message> <message> <source>&Tools</source> @@ -4852,7 +4855,7 @@ Elérhető parancsok: </message> <message> <source>Cannot create new group</source> - <translation type="unfinished"/> + <translation>Nem hozható létre új csoport</translation> </message> </context> <context> @@ -5128,7 +5131,7 @@ Elérhető parancsok: </message> <message> <source>Signer:</source> - <translation type="unfinished"/> + <translation>Aláíró:</translation> </message> </context> <context> @@ -5251,27 +5254,27 @@ Elérhető parancsok: </message> <message> <source>Multiple import source path to %1 in %2</source> - <translation type="unfinished"/> + <translation>Több importálási forrásútvonal ehhez: %1, itt: %2</translation> </message> <message> <source>Conflicting export target path %1 in %2</source> - <translation type="unfinished"/> + <translation>Ütköző %1 exportálási célútvonal itt: %2</translation> </message> <message> <source>Could not embed signature: Could not open file to write (%1)</source> - <translation type="unfinished"/> + <translation>Az aláírás nem ágyazható be: A fájl nem nyitható meg írásra (%1)</translation> </message> <message> <source>Could not embed signature: Could not write file (%1)</source> - <translation type="unfinished"/> + <translation>Az aláírás nem ágyazható be: A fájl nem írható (%1)</translation> </message> <message> <source>Could not embed database: Could not open file to write (%1)</source> - <translation type="unfinished"/> + <translation>Az adatbázis nem ágyazható be: A fájl nem nyitható meg írásra (%1)</translation> </message> <message> <source>Could not embed database: Could not write file (%1)</source> - <translation type="unfinished"/> + <translation>Az adatbázis nem ágyazható be: A fájl nem írható (%1)</translation> </message> </context> <context> 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 @@ </message> <message> <source>Minimize instead of app exit</source> - <translation type="unfinished"/> + <translation>sembunyikan jendela ke baki sistem</translation> </message> <message> <source>Show a system tray icon</source> @@ -614,7 +614,7 @@ Please select the correct database for saving credentials.</source> </message> <message> <source>Please see special instructions for browser extension use below</source> - <translation type="unfinished"/> + <translation>Lihat instruksi untuk penggunaan browser extension</translation> </message> <message> <source>KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3</source> 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.</source> </message> <message> <source>Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1</source> - <translation type="unfinished"/> + <translation>Snap によってサンドボックス化されているため、ブラウザー統合を有効にするにはスクリプトを実行する必要があります。<br />スクリプトは次の場所から入手できます: %1</translation> </message> <message> <source>Please see special instructions for browser extension use below</source> - <translation type="unfinished"/> + <translation>ブラウザー拡張機能を使用するための次の手順を参照してください</translation> </message> <message> <source>KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3</source> - <translation type="unfinished"/> + <translation>ブラウザー統合の動作には KeePassXC-Browser が必要です。<br />KeePassXC-Browser は %1 用と %2 用の2種類あります。%3</translation> </message> </context> <context> @@ -676,11 +676,11 @@ Do you want to overwrite it?</source> <source>Successfully converted attributes from %1 entry(s). Moved %2 keys to custom data.</source> <translation>%1 個のエントリーから属性を正常に変換しました。 -%2 個のキーをカスタムデータに移行しました。</translation> +%2 個のキーをカスタムデータに移動しました。</translation> </message> <message numerus="yes"> <source>Successfully moved %n keys to custom data.</source> - <translation><numerusform>%n 個のキーを正常にカスタムデータに移行しました。</numerusform></translation> + <translation><numerusform>%n 個のキーを正常にカスタムデータに移動しました。</numerusform></translation> </message> <message> <source>KeePassXC: No entry with KeePassHTTP attributes found!</source> @@ -696,19 +696,23 @@ Moved %2 keys to custom data.</source> </message> <message> <source>KeePassXC: Create a new group</source> - <translation type="unfinished"/> + <translation>KeePassXC: 新しいグループを作成</translation> </message> <message> <source>A request for creating a new group "%1" has been received. Do you want to create this group? </source> - <translation type="unfinished"/> + <translation>新しいグループ "%1" の作成要求を受け取りました。 +このグループを作成しますか? +</translation> </message> <message> <source>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?</source> - <translation type="unfinished"/> + <translation>KeePassXC-Browser の設定をデータベース設定内に移動する必要があります。 +これはブラウザーとの接続を維持するのに必要です。 +既存の設定を移動しますか?</translation> </message> </context> <context> @@ -872,7 +876,7 @@ Would you like to migrate your existing settings now?</source> </message> <message> <source>Key not transformed. This is a bug, please report it to the developers!</source> - <translation type="unfinished"/> + <translation>キーは変換されません。これはバグなので、開発者への報告をお願いします。</translation> </message> </context> <context> @@ -1005,7 +1009,7 @@ Please consider generating a new key file.</source> </message> <message> <source>Move KeePassHTTP attributes to KeePassXC-Browser &custom data</source> - <translation>KeePassHTTP の属性を KeePassXC-Browser のカスタムデータに移行する(&C)</translation> + <translation>KeePassHTTP の属性を KeePassXC-Browser のカスタムデータに移動する(&C)</translation> </message> <message> <source>Stored keys</source> @@ -1631,7 +1635,7 @@ Disable safe saves and try again?</source> </message> <message> <source>Shared group...</source> - <translation type="unfinished"/> + <translation>共有グループ...</translation> </message> </context> <context> @@ -2076,11 +2080,11 @@ Disable safe saves and try again?</source> </message> <message> <source>The export container %1 is already referenced.</source> - <translation type="unfinished"/> + <translation>エクスポートするコンテナ %1 は既に参照されています。</translation> </message> <message> <source>The import container %1 is already imported.</source> - <translation type="unfinished"/> + <translation>インポートするコンテナ %1 は既にインポートされています。</translation> </message> <message> <source>The container %1 imported and export by different groups.</source> @@ -4856,7 +4860,7 @@ Available commands: </message> <message> <source>Cannot create new group</source> - <translation type="unfinished"/> + <translation>新しいグループを作成できません</translation> </message> </context> <context> @@ -5132,7 +5136,7 @@ Available commands: </message> <message> <source>Signer:</source> - <translation type="unfinished"/> + <translation>署名者:</translation> </message> </context> <context> @@ -5263,19 +5267,19 @@ Available commands: </message> <message> <source>Could not embed signature: Could not open file to write (%1)</source> - <translation type="unfinished"/> + <translation>署名を埋め込めませんでした: ファイルを書き込み用に開くことができません (%1)</translation> </message> <message> <source>Could not embed signature: Could not write file (%1)</source> - <translation type="unfinished"/> + <translation>署名を埋め込めませんでした: ファイルに書き込むことができません (%1)</translation> </message> <message> <source>Could not embed database: Could not open file to write (%1)</source> - <translation type="unfinished"/> + <translation>データベースを埋め込めませんでした: ファイルを書き込み用に開くことができません (%1)</translation> </message> <message> <source>Could not embed database: Could not write file (%1)</source> - <translation type="unfinished"/> + <translation>データベースを埋め込めませんでした: ファイルに書き込むことができません (%1)</translation> </message> </context> <context> 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 @@ </message> <message> <source>Special thanks from the KeePassXC team go to debfx for creating the original KeePassX.</source> - <translation type="unfinished"/> + <translation>KeePassXC 팀은 원 프로젝트인 KeePassX의 개발자 debfx에게 특별한 감사를 전합니다.</translation> </message> </context> <context> @@ -54,7 +54,7 @@ </message> <message> <source>Use OpenSSH for Windows instead of Pageant</source> - <translation type="unfinished"/> + <translation>Pageant 대신 OpenSSH for Windows 사용</translation> </message> </context> <context> @@ -77,23 +77,23 @@ </message> <message> <source>Icon only</source> - <translation type="unfinished"/> + <translation>아이콘만</translation> </message> <message> <source>Text only</source> - <translation type="unfinished"/> + <translation>텍스트만</translation> </message> <message> <source>Text beside icon</source> - <translation type="unfinished"/> + <translation>아이콘 옆에 텍스트</translation> </message> <message> <source>Text under icon</source> - <translation type="unfinished"/> + <translation>아이콘 밑에 텍스트</translation> </message> <message> <source>Follow style</source> - <translation type="unfinished"/> + <translation>스타일 따르기</translation> </message> </context> <context> @@ -168,7 +168,7 @@ </message> <message> <source>Hide the entry preview panel</source> - <translation type="unfinished"/> + <translation>항목 미리 보기 패널 숨기기</translation> </message> <message> <source>General</source> @@ -176,11 +176,11 @@ </message> <message> <source>Hide toolbar (icons)</source> - <translation type="unfinished"/> + <translation>도구 모음(아이콘) 숨기기</translation> </message> <message> <source>Minimize instead of app exit</source> - <translation type="unfinished"/> + <translation>프로그램을 끝내지 않고 최소화</translation> </message> <message> <source>Show a system tray icon</source> @@ -220,7 +220,7 @@ </message> <message> <source>Auto-Type typing delay</source> - <translation type="unfinished"/> + <translation>자동 입력 지연 시간</translation> </message> <message> <source> ms</source> @@ -229,23 +229,23 @@ </message> <message> <source>Auto-Type start delay</source> - <translation type="unfinished"/> + <translation>자동 입력 시작 지연 시간</translation> </message> <message> <source>Check for updates at application startup</source> - <translation type="unfinished"/> + <translation>시작할 때 업데이트 확인</translation> </message> <message> <source>Include pre-releases when checking for updates</source> - <translation type="unfinished"/> + <translation>업데이트를 확인할 때 불안정 버전 포함</translation> </message> <message> <source>Movable toolbar</source> - <translation type="unfinished"/> + <translation>이동 가능한 도구 모음</translation> </message> <message> <source>Button style</source> - <translation type="unfinished"/> + <translation>단추 스타일</translation> </message> </context> <context> @@ -269,11 +269,11 @@ </message> <message> <source> min</source> - <translation type="unfinished"/> + <translation>분</translation> </message> <message> <source>Forget TouchID after inactivity of</source> - <translation type="unfinished"/> + <translation>다음 시간 동안 활동이 없을 때 TouchID 잊기</translation> </message> <message> <source>Convenience</source> @@ -285,7 +285,7 @@ </message> <message> <source>Forget TouchID when session is locked or lid is closed</source> - <translation type="unfinished"/> + <translation>세션을 잠그거나 덮개를 닫았을 때 TouchID 잊기</translation> </message> <message> <source>Lock databases after minimizing the window</source> @@ -293,7 +293,7 @@ </message> <message> <source>Re-lock previously locked database after performing Auto-Type</source> - <translation type="unfinished"/> + <translation>자동 입력 이후 이전에 잠긴 데이터베이스 다시 잠그기</translation> </message> <message> <source>Don't require password repeat when it is visible</source> @@ -301,15 +301,15 @@ </message> <message> <source>Don't hide passwords when editing them</source> - <translation type="unfinished"/> + <translation>암호를 편집할 때 숨기지 않기</translation> </message> <message> <source>Don't use placeholder for empty password fields</source> - <translation type="unfinished"/> + <translation>빈 암호 필드에 자리 비움자 사용하지 않기</translation> </message> <message> <source>Hide passwords in the entry preview panel</source> - <translation type="unfinished"/> + <translation>항목 미리 보기 패널에서 암호 숨기기</translation> </message> <message> <source>Hide entry notes by default</source> @@ -321,7 +321,7 @@ </message> <message> <source>Use DuckDuckGo as fallback for downloading website icons</source> - <translation type="unfinished"/> + <translation>웹사이트 아이콘을 다운로드할 때 DuckDuckGo를 폴백으로 사용하기</translation> </message> </context> <context> @@ -429,11 +429,11 @@ Please select whether you want to allow access.</source> <name>BrowserEntrySaveDialog</name> <message> <source>KeePassXC-Browser Save Entry</source> - <translation type="unfinished"/> + <translation>KeePassXC-브라우저 항목 저장</translation> </message> <message> <source>Ok</source> - <translation type="unfinished"/> + <translation>확인</translation> </message> <message> <source>Cancel</source> @@ -442,7 +442,8 @@ Please select whether you want to allow access.</source> <message> <source>You have multiple databases open. Please select the correct database for saving credentials.</source> - <translation type="unfinished"/> + <translation>여러 개의 데이터베이스를 열었습니다. +인증 정보를 저장할 데이터베이스를 선택하십시오.</translation> </message> </context> <context> @@ -589,36 +590,36 @@ Please select the correct database for saving credentials.</source> </message> <message> <source>&Tor Browser</source> - <translation type="unfinished"/> + <translation>Tor 브라우저(&T)</translation> </message> <message> <source><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: </source> - <translation type="unfinished"/> + <translation><b>경고</b>, keepassxc-proxy 프로그램을 찾을 수 없습니다!<br />KeePassXC 설치 디렉터리를 확인하거나 고급 설정의 사용자 경로를 확인하십시오.<br />프록시 프로그램이 없으면 브라우저 통합 기능을 사용할 수 없습니다.<br />예상하는 경로: </translation> </message> <message> <source>Executable Files</source> - <translation type="unfinished"/> + <translation>실행 파일</translation> </message> <message> <source>All Files</source> - <translation type="unfinished"/> + <translation>모든 파일</translation> </message> <message> <source>Do not ask permission for HTTP &Basic Auth</source> <extracomment>An extra HTTP Basic Auth setting</extracomment> - <translation type="unfinished"/> + <translation>HTTP 기본 인증 묻지 않기(&B)</translation> </message> <message> <source>Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1</source> - <translation type="unfinished"/> + <translation>Snap 샌드박스로 인하여 브라우저 확장 기능을 사용하려면 스크립트를 실행해야 합니다.<br />%1에서 스크립트를 확인할 수 있습니다</translation> </message> <message> <source>Please see special instructions for browser extension use below</source> - <translation type="unfinished"/> + <translation>브라우저 확장 기능을 위한 추가 절차를 참조하십시오</translation> </message> <message> <source>KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3</source> - <translation type="unfinished"/> + <translation>브라우저 통합을 사용하려면 KeePassXC-브라우저가 필요합니다.<br /> %1 및 %2용으로 다운로드할 수 있습니다. %3</translation> </message> </context> <context> @@ -665,48 +666,53 @@ Do you want to overwrite it?</source> </message> <message> <source>Converting attributes to custom data…</source> - <translation type="unfinished"/> + <translation>속성을 사용자 정의 데이터로 변환 중…</translation> </message> <message> <source>KeePassXC: Converted KeePassHTTP attributes</source> - <translation type="unfinished"/> + <translation>KeePassXC: KeePassHTTP 속성 변환됨</translation> </message> <message> <source>Successfully converted attributes from %1 entry(s). Moved %2 keys to custom data.</source> - <translation type="unfinished"/> + <translation>%1개 항목의 속성을 변환했습니다. +키 %2개를 사용자 정의 데이터로 이동했습니다.</translation> </message> <message numerus="yes"> <source>Successfully moved %n keys to custom data.</source> - <translation type="unfinished"><numerusform></numerusform></translation> + <translation><numerusform>키 %n개를 사용자 정의 데이터로 이동했습니다.</numerusform></translation> </message> <message> <source>KeePassXC: No entry with KeePassHTTP attributes found!</source> - <translation type="unfinished"/> + <translation>KeePassXC: KeePassHTTP 속성이 있는 항목을 찾을 수 없습니다!</translation> </message> <message> <source>The active database does not contain an entry with KeePassHTTP attributes.</source> - <translation type="unfinished"/> + <translation>현재 활성화된 데이터베이스에 KeePassHTTP 속성이 있는 항목이 없습니다.</translation> </message> <message> <source>KeePassXC: Legacy browser integration settings detected</source> - <translation type="unfinished"/> + <translation>KeePassXC: 레거시 브라우저 통합 설정 감지됨</translation> </message> <message> <source>KeePassXC: Create a new group</source> - <translation type="unfinished"/> + <translation>KeePassXC: 새 그룹 생성</translation> </message> <message> <source>A request for creating a new group "%1" has been received. Do you want to create this group? </source> - <translation type="unfinished"/> + <translation>새 그룹 "%1"을(를) 생성하는 요청을 받았습니다. +이 그룹을 생성하시겠습니까? +</translation> </message> <message> <source>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?</source> - <translation type="unfinished"/> + <translation>KeePassXC-브라우저 설정을 데이터베이스 설정으로 이동해야 합니다. +현재 브라우저 연결을 유지하려면 이 작업이 필요합니다. +존재하는 설정을 이전하시겠습니까?</translation> </message> </context> <context> @@ -800,24 +806,25 @@ Would you like to migrate your existing settings now?</source> </message> <message> <source>Empty fieldname %1</source> - <translation type="unfinished"/> + <translation>빈 필드 이름 %1</translation> </message> <message> <source>column %1</source> - <translation type="unfinished"/> + <translation>칸 %1</translation> </message> <message> <source>Error(s) detected in CSV file!</source> - <translation type="unfinished"/> + <translation>CSV 파일에 오류가 있습니다!</translation> </message> <message numerus="yes"> <source>[%n more message(s) skipped]</source> - <translation type="unfinished"><numerusform></numerusform></translation> + <translation><numerusform>[추가 메시지 %n개 건너뜀]</numerusform></translation> </message> <message> <source>CSV import: writer has errors: %1</source> - <translation type="unfinished"/> + <translation>CSV 가져오기: 기록 도구에 오류가 있습니다: +%1</translation> </message> </context> <context> @@ -829,15 +836,15 @@ Would you like to migrate your existing settings now?</source> <message> <source>%1, %2, %3</source> <comment>file info: bytes, rows, columns</comment> - <translation type="unfinished"/> + <translation>%1, %2, %3</translation> </message> <message numerus="yes"> <source>%n byte(s)</source> - <translation type="unfinished"><numerusform></numerusform></translation> + <translation><numerusform>%n바이트</numerusform></translation> </message> <message numerus="yes"> <source>%n row(s)</source> - <translation type="unfinished"><numerusform></numerusform></translation> + <translation><numerusform>%n줄</numerusform></translation> </message> </context> <context> @@ -849,34 +856,34 @@ Would you like to migrate your existing settings now?</source> </message> <message> <source>File %1 does not exist.</source> - <translation type="unfinished"/> + <translation>파일 %1이(가) 존재하지 않습니다.</translation> </message> <message> <source>Unable to open file %1.</source> - <translation type="unfinished"/> + <translation>파일 %1을(를) 열 수 없습니다.</translation> </message> <message> <source>Error while reading the database: %1</source> - <translation type="unfinished"/> + <translation>데이터베이스 읽기 오류: %1</translation> </message> <message> <source>Could not save, database has no file name.</source> - <translation type="unfinished"/> + <translation>데이터베이스 파일 이름이 없어서 저장할 수 없습니다.</translation> </message> <message> <source>File cannot be written as it is opened in read-only mode.</source> - <translation type="unfinished"/> + <translation>읽기 전용 모드로 파일을 열었기 때문에 저장할 수 없습니다.</translation> </message> <message> <source>Key not transformed. This is a bug, please report it to the developers!</source> - <translation type="unfinished"/> + <translation>키 변형 과정이 일어나지 않았습니다. 버그이므로 개발자에게 보고해 주십시오!</translation> </message> </context> <context> <name>DatabaseOpenDialog</name> <message> <source>Unlock Database - KeePassXC</source> - <translation type="unfinished"/> + <translation>데이터베이스 잠금 해제 - KeePassXC</translation> </message> </context> <context> @@ -937,17 +944,19 @@ Please consider generating a new key file.</source> </message> <message> <source>TouchID for quick unlock</source> - <translation type="unfinished"/> + <translation>빠른 잠금 해제용 TouchID</translation> </message> <message> <source>Unable to open the database: %1</source> - <translation type="unfinished"/> + <translation>데이터베이스를 열 수 없음: +%1</translation> </message> <message> <source>Can't open key file: %1</source> - <translation type="unfinished"/> + <translation>키 파일을 열 수 없음: +%1</translation> </message> </context> <context> @@ -961,7 +970,7 @@ Please consider generating a new key file.</source> <name>DatabaseSettingsDialog</name> <message> <source>Advanced Settings</source> - <translation type="unfinished"/> + <translation>고급 설정</translation> </message> <message> <source>General</source> @@ -973,11 +982,11 @@ Please consider generating a new key file.</source> </message> <message> <source>Master Key</source> - <translation type="unfinished"/> + <translation>마스터 키</translation> </message> <message> <source>Encryption Settings</source> - <translation type="unfinished"/> + <translation>암호화 설정</translation> </message> <message> <source>Browser Integration</source> @@ -988,7 +997,7 @@ Please consider generating a new key file.</source> <name>DatabaseSettingsWidgetBrowser</name> <message> <source>KeePassXC-Browser settings</source> - <translation type="unfinished"/> + <translation>KeePassXC-브라우저 설정</translation> </message> <message> <source>&Disconnect all browsers</source> @@ -996,15 +1005,15 @@ Please consider generating a new key file.</source> </message> <message> <source>Forg&et all site-specific settings on entries</source> - <translation type="unfinished"/> + <translation>항목의 모든 사이트별 설정 삭제(&E)</translation> </message> <message> <source>Move KeePassHTTP attributes to KeePassXC-Browser &custom data</source> - <translation type="unfinished"/> + <translation>KeePassHTTP 속성을 KeePassXC-브라우저 사용자 정의 데이터로 이동(&C)</translation> </message> <message> <source>Stored keys</source> - <translation type="unfinished"/> + <translation>저장된 키</translation> </message> <message> <source>Remove</source> @@ -1012,33 +1021,35 @@ Please consider generating a new key file.</source> </message> <message> <source>Delete the selected key?</source> - <translation type="unfinished"/> + <translation>선택한 키를 삭제하시겠습니까?</translation> </message> <message> <source>Do you really want to delete the selected key? This may prevent connection to the browser plugin.</source> - <translation type="unfinished"/> + <translation>선택한 키를 삭제하시겠습니까? +브라우저 플러그인에 연결하지 못할 수도 있습니다.</translation> </message> <message> <source>Key</source> - <translation type="unfinished"/> + <translation>키</translation> </message> <message> <source>Value</source> - <translation type="unfinished"/> + <translation>값</translation> </message> <message> <source>Enable Browser Integration to access these settings.</source> - <translation type="unfinished"/> + <translation>이 설정을 변경하려면 브라우저 통합을 활성화하십시오.</translation> </message> <message> <source>Disconnect all browsers</source> - <translation type="unfinished"/> + <translation>모든 브라우저 연결 끊기</translation> </message> <message> <source>Do you really want to disconnect all browsers? This may prevent connection to the browser plugin.</source> - <translation type="unfinished"/> + <translation>모든 브라우저 연결을 끊으시겠습니까? +브라우저 플러그인에 연결하지 못할 수도 있습니다.</translation> </message> <message> <source>KeePassXC: No keys found</source> @@ -1046,7 +1057,7 @@ This may prevent connection to the browser plugin.</source> </message> <message> <source>No shared encryption keys found in KeePassXC settings.</source> - <translation type="unfinished"/> + <translation>KeePassXC 설정에서 공유된 암호화 키를 찾을 수 없습니다.</translation> </message> <message> <source>KeePassXC: Removed keys from database</source> @@ -1054,16 +1065,17 @@ This may prevent connection to the browser plugin.</source> </message> <message numerus="yes"> <source>Successfully removed %n encryption key(s) from KeePassXC settings.</source> - <translation type="unfinished"><numerusform></numerusform></translation> + <translation><numerusform>KeePassXC 설정에서 암호화 키 %n개를 삭제했습니다.</numerusform></translation> </message> <message> <source>Forget all site-specific settings on entries</source> - <translation type="unfinished"/> + <translation>항목의 모든 사이트별 설정 삭제</translation> </message> <message> <source>Do you really want forget all site-specific settings on every entry? Permissions to access entries will be revoked.</source> - <translation type="unfinished"/> + <translation>모든 항목의 사이트별 설정을 삭제하시겠습니까? +항목에 접근할 권한이 취소됩니다.</translation> </message> <message> <source>Removing stored permissions…</source> @@ -1079,7 +1091,7 @@ Permissions to access entries will be revoked.</source> </message> <message numerus="yes"> <source>Successfully removed permissions from %n entry(s).</source> - <translation type="unfinished"><numerusform></numerusform></translation> + <translation><numerusform>항목 %n개에서 권한을 삭제했습니다.</numerusform></translation> </message> <message> <source>KeePassXC: No entry with permissions found!</source> @@ -1091,12 +1103,13 @@ Permissions to access entries will be revoked.</source> </message> <message> <source>Move KeePassHTTP attributes to custom data</source> - <translation type="unfinished"/> + <translation>KeePassHTTP 속성을 사용자 정의 데이터로 이동</translation> </message> <message> <source>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.</source> - <translation type="unfinished"/> + <translation>모든 레거시 브라우저 통합 데이터를 최신 표준으로 이전하시겠습니까? +브라우저 통합 플러그인과 호환성을 유지하기 위해서 필요합니다.</translation> </message> </context> <context> @@ -1135,48 +1148,48 @@ This is necessary to maintain compatibility with the browser plugin.</source> </message> <message> <source>Decryption Time:</source> - <translation type="unfinished"/> + <translation>복호화 시간:</translation> </message> <message> <source>?? s</source> - <translation type="unfinished"/> + <translation>??초</translation> </message> <message> <source>Change</source> - <translation type="unfinished"/> + <translation>변경</translation> </message> <message> <source>100 ms</source> - <translation type="unfinished"/> + <translation>100 ms</translation> </message> <message> <source>5 s</source> - <translation type="unfinished"/> + <translation>5초</translation> </message> <message> <source>Higher values offer more protection, but opening the database will take longer.</source> - <translation type="unfinished"/> + <translation>시간을 더 늘리면 보호 정도를 높일 수 있지만 데이터베이스를 여는 데 더 오랜 시간이 걸릴 것입니다.</translation> </message> <message> <source>Database format:</source> - <translation type="unfinished"/> + <translation>데이터베이스 형식:</translation> </message> <message> <source>This is only important if you need to use your database with other programs.</source> - <translation type="unfinished"/> + <translation>데이터베이스를 다른 프로그램에서 사용할 일이 있을 때 중요합니다.</translation> </message> <message> <source>KDBX 4.0 (recommended)</source> - <translation type="unfinished"/> + <translation>KDBX 4.0(추천)</translation> </message> <message> <source>KDBX 3.1</source> - <translation type="unfinished"/> + <translation>KDBX 3.1</translation> </message> <message> <source>unchanged</source> <comment>Database decryption time is unchanged</comment> - <translation type="unfinished"/> + <translation>변경되지 않음</translation> </message> <message> <source>Number of rounds too high</source> @@ -1223,22 +1236,22 @@ If you keep this number, your database may be too easy to crack!</source> <message numerus="yes"> <source> MiB</source> <comment>Abbreviation for Mebibytes (KDF settings)</comment> - <translation type="unfinished"><numerusform></numerusform></translation> + <translation><numerusform>MiB</numerusform></translation> </message> <message numerus="yes"> <source> thread(s)</source> <comment>Threads for parallel execution (KDF settings)</comment> - <translation type="unfinished"><numerusform></numerusform></translation> + <translation><numerusform>개 스레드</numerusform></translation> </message> <message numerus="yes"> <source>%1 ms</source> <comment>milliseconds</comment> - <translation type="unfinished"><numerusform></numerusform></translation> + <translation><numerusform>%1 ms</numerusform></translation> </message> <message numerus="yes"> <source>%1 s</source> <comment>seconds</comment> - <translation type="unfinished"><numerusform></numerusform></translation> + <translation><numerusform>%1초</numerusform></translation> </message> </context> <context> @@ -1292,57 +1305,59 @@ If you keep this number, your database may be too easy to crack!</source> <name>DatabaseSettingsWidgetKeeShare</name> <message> <source>Sharing</source> - <translation type="unfinished"/> + <translation>공유</translation> </message> <message> <source>Breadcrumb</source> - <translation type="unfinished"/> + <translation>단계</translation> </message> <message> <source>Type</source> - <translation type="unfinished"/> + <translation>형식</translation> </message> <message> <source>Path</source> - <translation type="unfinished"/> + <translation>경로</translation> </message> <message> <source>Last Signer</source> - <translation type="unfinished"/> + <translation>마지막 서명자</translation> </message> <message> <source>Certificates</source> - <translation type="unfinished"/> + <translation>인증서</translation> </message> <message> <source> > </source> <comment>Breadcrumb separator</comment> - <translation type="unfinished"/> + <translation> > </translation> </message> </context> <context> <name>DatabaseSettingsWidgetMasterKey</name> <message> <source>Add additional protection...</source> - <translation type="unfinished"/> + <translation>추가 보호 추가...</translation> </message> <message> <source>No encryption key added</source> - <translation type="unfinished"/> + <translation>암호화 키가 추가되지 않았음</translation> </message> <message> <source>You must add at least one encryption key to secure your database!</source> - <translation type="unfinished"/> + <translation>데이터베이스를 보호할 암호화 키를 최소 하나 추가해야 합니다!</translation> </message> <message> <source>No password set</source> - <translation type="unfinished"/> + <translation>암호가 설정되지 않았음</translation> </message> <message> <source>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?</source> - <translation type="unfinished"/> + <translation>경고! 암호를 설정하지 않았습니다. 데이터베이스 암호를 설정하지 않는 것은 추천하지 않습니다! + +암호를 지정하지 않고 계속 진행하시겠습니까?</translation> </message> <message> <source>Unknown error</source> @@ -1350,18 +1365,18 @@ Are you sure you want to continue without a password?</source> </message> <message> <source>Failed to change master key</source> - <translation type="unfinished"/> + <translation>마스터 키를 변경할 수 없음</translation> </message> </context> <context> <name>DatabaseSettingsWidgetMetaDataSimple</name> <message> <source>Database Name:</source> - <translation type="unfinished"/> + <translation>데이터베이스 이름:</translation> </message> <message> <source>Description:</source> - <translation type="unfinished"/> + <translation>설명:</translation> </message> </context> <context> @@ -1404,39 +1419,40 @@ Are you sure you want to continue without a password?</source> </message> <message> <source>Database creation error</source> - <translation type="unfinished"/> + <translation>Database creation error</translation> </message> <message> <source>The created database has no key or KDF, refusing to save it. This is definitely a bug, please report it to the developers.</source> - <translation type="unfinished"/> + <translation>이 생성된 데이터베이스에 키나 KDF가 없어서 저장하지 않을 것입니다. +버그이므로 개발자에게 보고해 주십시오.</translation> </message> <message> <source>The database file does not exist or is not accessible.</source> - <translation type="unfinished"/> + <translation>데이터베이스 파일이 존재하지 않거나 접근할 수 없습니다.</translation> </message> <message> <source>Select CSV file</source> - <translation type="unfinished"/> + <translation>CSV 파일 선택</translation> </message> <message> <source>New Database</source> - <translation type="unfinished"/> + <translation>새 데이터베이스</translation> </message> <message> <source>%1 [New Database]</source> <comment>Database tab name modifier</comment> - <translation type="unfinished"/> + <translation>%1 [새 데이터베이스]</translation> </message> <message> <source>%1 [Locked]</source> <comment>Database tab name modifier</comment> - <translation type="unfinished"/> + <translation>%1 [잠김]</translation> </message> <message> <source>%1 [Read-only]</source> <comment>Database tab name modifier</comment> - <translation type="unfinished"/> + <translation>%1 [읽기 전용]</translation> </message> </context> <context> @@ -1517,15 +1533,15 @@ Do you want to merge your changes?</source> </message> <message numerus="yes"> <source>Do you really want to delete %n entry(s) for good?</source> - <translation type="unfinished"><numerusform></numerusform></translation> + <translation><numerusform>항목 %n개를 영원히 삭제하시겠습니까?</numerusform></translation> </message> <message numerus="yes"> <source>Delete entry(s)?</source> - <translation type="unfinished"><numerusform></numerusform></translation> + <translation><numerusform>항목을 삭제하시겠습니까?</numerusform></translation> </message> <message numerus="yes"> <source>Move entry(s) to recycle bin?</source> - <translation type="unfinished"><numerusform></numerusform></translation> + <translation><numerusform>항목을 휴지통으로 이동하시겠습니까?</numerusform></translation> </message> <message> <source>File opened in read only mode.</source> @@ -1533,11 +1549,11 @@ Do you want to merge your changes?</source> </message> <message> <source>Lock Database?</source> - <translation type="unfinished"/> + <translation>데이터베이스를 잠그시겠습니까?</translation> </message> <message> <source>You are editing an entry. Discard changes and lock anyway?</source> - <translation type="unfinished"/> + <translation>항목을 편집하고 있습니다. 변경 사항을 무시하고 잠그시겠습니까?</translation> </message> <message> <source>"%1" was modified. @@ -1547,7 +1563,8 @@ Save changes?</source> <message> <source>Database was modified. Save changes?</source> - <translation type="unfinished"/> + <translation>데이터베이스가 변경되었습니다. +저장하시겠습니까?</translation> </message> <message> <source>Save changes?</source> @@ -1556,7 +1573,8 @@ Save changes?</source> <message> <source>Could not open the new database file while attempting to autoreload. Error: %1</source> - <translation type="unfinished"/> + <translation>자동으로 다시 불러오려는 중 새 데이터베이스 파일을 열 수 없었습니다. +오류: %1</translation> </message> <message> <source>Disable safe saves?</source> @@ -1571,7 +1589,8 @@ Disable safe saves and try again?</source> <message> <source>Writing the database failed. %1</source> - <translation type="unfinished"/> + <translation>데이터베이스 파일에 기록할 수 없습니다. +%1</translation> </message> <message> <source>Passwords</source> @@ -1587,11 +1606,11 @@ Disable safe saves and try again?</source> </message> <message> <source>Replace references to entry?</source> - <translation type="unfinished"/> + <translation>항목에 대한 참조를 변경하시겠습니까?</translation> </message> <message numerus="yes"> <source>Entry "%1" has %2 reference(s). Do you want to overwrite references with values, skip this entry, or delete anyway?</source> - <translation type="unfinished"><numerusform></numerusform></translation> + <translation><numerusform>항목 "%1"에 참조 %2개가 있습니다. 해당 참조를 값으로 덮어 쓰거나, 항목을 건너뛰거나, 그래도 삭제하시겠습니까?</numerusform></translation> </message> <message> <source>Delete group</source> @@ -1599,23 +1618,23 @@ Disable safe saves and try again?</source> </message> <message> <source>Move group to recycle bin?</source> - <translation type="unfinished"/> + <translation>그룹을 휴지통으로 이동하시겠습니까?</translation> </message> <message> <source>Do you really want to move the group "%1" to the recycle bin?</source> - <translation type="unfinished"/> + <translation>그룹 "%1"을(를) 휴지통으로 이동하시겠습니까?</translation> </message> <message> <source>Successfully merged the database files.</source> - <translation type="unfinished"/> + <translation>데이터베이스 파일을 합쳤습니다.</translation> </message> <message> <source>Database was not modified by merge operation.</source> - <translation type="unfinished"/> + <translation>수정 작업으로 데이터베이스가 변경되지 않았습니다.</translation> </message> <message> <source>Shared group...</source> - <translation type="unfinished"/> + <translation>공유된 그룹...</translation> </message> </context> <context> @@ -1706,23 +1725,23 @@ Disable safe saves and try again?</source> </message> <message> <source>Apply generated password?</source> - <translation type="unfinished"/> + <translation>생성된 암호를 적용하시겠습니까?</translation> </message> <message> <source>Do you want to apply the generated password to this entry?</source> - <translation type="unfinished"/> + <translation>이 항목에 생성된 암호를 적용하시겠습니까?</translation> </message> <message> <source>Entry updated successfully.</source> - <translation type="unfinished"/> + <translation>항목을 업데이트했습니다.</translation> </message> <message> <source>Entry has unsaved changes</source> - <translation type="unfinished"/> + <translation>항목에 저장되지 않은 변경 사항이 있음</translation> </message> <message> <source>New attribute %1</source> - <translation type="unfinished"/> + <translation>새 속성 %1</translation> </message> <message> <source>[PROTECTED] Press reveal to view or edit</source> @@ -1730,11 +1749,11 @@ Disable safe saves and try again?</source> </message> <message numerus="yes"> <source>%n year(s)</source> - <translation type="unfinished"><numerusform></numerusform></translation> + <translation><numerusform>%n년</numerusform></translation> </message> <message> <source>Confirm Removal</source> - <translation type="unfinished"/> + <translation>삭제 확인</translation> </message> </context> <context> @@ -1769,11 +1788,11 @@ Disable safe saves and try again?</source> </message> <message> <source>Foreground Color:</source> - <translation type="unfinished"/> + <translation>글자색:</translation> </message> <message> <source>Background Color:</source> - <translation type="unfinished"/> + <translation>배경색:</translation> </message> </context> <context> @@ -1808,7 +1827,7 @@ Disable safe saves and try again?</source> </message> <message> <source>Use a specific sequence for this association:</source> - <translation type="unfinished"/> + <translation>이 조합에 지정된 시퀀스 사용:</translation> </message> </context> <context> @@ -1988,15 +2007,15 @@ Disable safe saves and try again?</source> </message> <message> <source>Type:</source> - <translation type="unfinished"/> + <translation>형식:</translation> </message> <message> <source>Path:</source> - <translation type="unfinished"/> + <translation>경로:</translation> </message> <message> <source>...</source> - <translation type="unfinished"/> + <translation>...</translation> </message> <message> <source>Password:</source> @@ -2004,55 +2023,55 @@ Disable safe saves and try again?</source> </message> <message> <source>Inactive</source> - <translation type="unfinished"/> + <translation>비활성</translation> </message> <message> <source>Import from path</source> - <translation type="unfinished"/> + <translation>경로에서 가져오기</translation> </message> <message> <source>Export to path</source> - <translation type="unfinished"/> + <translation>경로로 내보내기</translation> </message> <message> <source>Synchronize with path</source> - <translation type="unfinished"/> + <translation>다음 경로와 동기화</translation> </message> <message> <source>Your KeePassXC version does not support sharing your container type. Please use %1.</source> - <translation type="unfinished"/> + <translation>KeePassXC 현재 버전에서 현재 컨테이너 형식을 공유할 수 없습니다. %1을(를) 사용하십시오.</translation> </message> <message> <source>Database sharing is disabled</source> - <translation type="unfinished"/> + <translation>데이터베이스 공유 비활성화됨</translation> </message> <message> <source>Database export is disabled</source> - <translation type="unfinished"/> + <translation>데이터베이스 내보내기 비활성화됨</translation> </message> <message> <source>Database import is disabled</source> - <translation type="unfinished"/> + <translation>데이터베이스 가져오기 비활성화됨</translation> </message> <message> <source>KeeShare unsigned container</source> - <translation type="unfinished"/> + <translation>KeeShare 서명되지 않은 컨테이너</translation> </message> <message> <source>KeeShare signed container</source> - <translation type="unfinished"/> + <translation>KeeShare 서명된 컨테이너</translation> </message> <message> <source>Select import source</source> - <translation type="unfinished"/> + <translation>가져올 원본 선택</translation> </message> <message> <source>Select export target</source> - <translation type="unfinished"/> + <translation>내보낼 대상 선택</translation> </message> <message> <source>Select import/export file</source> - <translation type="unfinished"/> + <translation>가져올/내보낼 파일 선택</translation> </message> <message> <source>Clear</source> @@ -2060,15 +2079,15 @@ Disable safe saves and try again?</source> </message> <message> <source>The export container %1 is already referenced.</source> - <translation type="unfinished"/> + <translation>내보내기 컨테이너 %1이(가) 이미 참조되었습니다.</translation> </message> <message> <source>The import container %1 is already imported.</source> - <translation type="unfinished"/> + <translation>가져오기 컨테이너 %1이(가) 이미 참조되었습니다.</translation> </message> <message> <source>The container %1 imported and export by different groups.</source> - <translation type="unfinished"/> + <translation>컨테이너 %1을(를) 가져왔고 다른 그룹에서 내보냈습니다.</translation> </message> </context> <context> @@ -2146,35 +2165,35 @@ Disable safe saves and try again?</source> </message> <message> <source>Custom icon successfully downloaded</source> - <translation type="unfinished"/> + <translation>사용자 정의 아이콘 다운로드됨</translation> </message> <message> <source>Hint: You can enable DuckDuckGo as a fallback under Tools>Settings>Security</source> - <translation type="unfinished"/> + <translation>힌트: 도구>설정>보안에서 DuckDuckGo를 폴백으로 지정할 수 있습니다</translation> </message> <message> <source>Select Image(s)</source> - <translation type="unfinished"/> + <translation>이미지 선택</translation> </message> <message numerus="yes"> <source>Successfully loaded %1 of %n icon(s)</source> - <translation type="unfinished"><numerusform></numerusform></translation> + <translation><numerusform>아이콘 %n개 중 %1개 불러옴</numerusform></translation> </message> <message> <source>No icons were loaded</source> - <translation type="unfinished"/> + <translation>아이콘을 불러오지 않았음</translation> </message> <message numerus="yes"> <source>%n icon(s) already exist in the database</source> - <translation type="unfinished"><numerusform></numerusform></translation> + <translation><numerusform>데이터베이스에 아이콘 %n개가 이미 존재함</numerusform></translation> </message> <message numerus="yes"> <source>The following icon(s) failed:</source> - <translation type="unfinished"><numerusform></numerusform></translation> + <translation><numerusform>다음 아이콘에서 오류가 발생했습니다:</numerusform></translation> </message> <message numerus="yes"> <source>This icon is used by %n entry(s), and will be replaced by the default icon. Are you sure you want to delete it?</source> - <translation type="unfinished"><numerusform></numerusform></translation> + <translation><numerusform>%n개 항목에서 이 아이콘을 사용하고 있으며 기본 아이콘으로 대체됩니다. 삭제하시겠습니까?</numerusform></translation> </message> </context> <context> @@ -2197,7 +2216,7 @@ Disable safe saves and try again?</source> </message> <message> <source>Plugin Data</source> - <translation type="unfinished"/> + <translation>플러그인 데이터</translation> </message> <message> <source>Remove</source> @@ -2205,27 +2224,28 @@ Disable safe saves and try again?</source> </message> <message> <source>Delete plugin data?</source> - <translation type="unfinished"/> + <translation>플러그인 데이터를 삭제하시겠습니까?</translation> </message> <message> <source>Do you really want to delete the selected plugin data? This may cause the affected plugins to malfunction.</source> - <translation type="unfinished"/> + <translation>선택한 플러그인 데이터를 삭제하시겠습니까? +영향받는 플러그인이 제대로 동작하지 않을 수도 있습니다.</translation> </message> <message> <source>Key</source> - <translation type="unfinished"/> + <translation>키</translation> </message> <message> <source>Value</source> - <translation type="unfinished"/> + <translation>값</translation> </message> </context> <context> <name>Entry</name> <message> <source>%1 - Clone</source> - <translation type="unfinished"/> + <translation>%1 - 사본</translation> </message> </context> <context> @@ -2307,12 +2327,13 @@ This may cause the affected plugins to malfunction.</source> </message> <message> <source>Confirm remove</source> - <translation type="unfinished"/> + <translation>삭제 확인</translation> </message> <message numerus="yes"> <source>Unable to open file(s): %1</source> - <translation type="unfinished"><numerusform></numerusform></translation> + <translation><numerusform>파일을 열 수 없음: +%1</numerusform></translation> </message> </context> <context> @@ -2398,11 +2419,11 @@ This may cause the affected plugins to malfunction.</source> </message> <message> <source>Yes</source> - <translation type="unfinished"/> + <translation>예</translation> </message> <message> <source>TOTP</source> - <translation type="unfinished"/> + <translation>TOTP</translation> </message> </context> <context> @@ -2482,7 +2503,7 @@ This may cause the affected plugins to malfunction.</source> <message> <source><b>%1</b>: %2</source> <comment>attributes line</comment> - <translation type="unfinished"/> + <translation><b>%1</b>: %2</translation> </message> <message> <source>Enabled</source> @@ -2494,7 +2515,7 @@ This may cause the affected plugins to malfunction.</source> </message> <message> <source>Share</source> - <translation type="unfinished"/> + <translation>공유</translation> </message> </context> <context> @@ -2525,7 +2546,7 @@ This may cause the affected plugins to malfunction.</source> </message> <message> <source>Attachments (icon)</source> - <translation type="unfinished"/> + <translation>첨부(아이콘)</translation> </message> </context> <context> @@ -2537,7 +2558,7 @@ This may cause the affected plugins to malfunction.</source> <message> <source>[empty]</source> <comment>group has no children</comment> - <translation type="unfinished"/> + <translation>[비어 있음]</translation> </message> </context> <context> @@ -2582,7 +2603,7 @@ This may cause the affected plugins to malfunction.</source> </message> <message> <source>Header doesn't match hash</source> - <translation type="unfinished"/> + <translation>헤더의 해시가 일치하지 않음</translation> </message> <message> <source>Invalid header id size</source> @@ -2810,15 +2831,15 @@ This is a one-way migration. You won't be able to open the imported databas </message> <message> <source>Invalid cipher uuid length: %1 (length=%2)</source> - <translation type="unfinished"/> + <translation>잘못된 암호화 UUID 길이: %1(length=%2)</translation> </message> <message> <source>Unable to parse UUID: %1</source> - <translation type="unfinished"/> + <translation>UUID를 처리할 수 없음: %1</translation> </message> <message> <source>Failed to read database file.</source> - <translation type="unfinished"/> + <translation>데이터베이스 파일을 읽을 수 없습니다.</translation> </message> </context> <context> @@ -2944,7 +2965,9 @@ This is a one-way migration. You won't be able to open the imported databas <source>XML error: %1 Line %2, column %3</source> - <translation type="unfinished"/> + <translation>XML 오류: +%1 +%2줄, %3칸</translation> </message> </context> <context> @@ -3111,53 +3134,53 @@ Line %2, column %3</source> </message> <message> <source>unable to seek to content position</source> - <translation type="unfinished"/> + <translation>내용 위치로 이동할 수 없음</translation> </message> </context> <context> <name>KeeShare</name> <message> <source>Disabled share</source> - <translation type="unfinished"/> + <translation>비활성화된 공유</translation> </message> <message> <source>Import from</source> - <translation type="unfinished"/> + <translation>다음에서 가져오기</translation> </message> <message> <source>Export to</source> - <translation type="unfinished"/> + <translation>다음으로 내보내기</translation> </message> <message> <source>Synchronize with</source> - <translation type="unfinished"/> + <translation>다음과 동기화</translation> </message> <message> <source>Disabled share %1</source> - <translation type="unfinished"/> + <translation>비활성화된 공유 %1</translation> </message> <message> <source>Import from share %1</source> - <translation type="unfinished"/> + <translation>공유 %1에서 가져오기</translation> </message> <message> <source>Export to share %1</source> - <translation type="unfinished"/> + <translation>공유 %1(으)로 내보내기</translation> </message> <message> <source>Synchronize with share %1</source> - <translation type="unfinished"/> + <translation>공유 %1와(과) 동기화</translation> </message> </context> <context> <name>KeyComponentWidget</name> <message> <source>Key Component</source> - <translation type="unfinished"/> + <translation>키 구성 요소</translation> </message> <message> <source>Key Component Description</source> - <translation type="unfinished"/> + <translation>키 구성 요소 설명</translation> </message> <message> <source>Cancel</source> @@ -3165,27 +3188,27 @@ Line %2, column %3</source> </message> <message> <source>Key Component set, click to change or remove</source> - <translation type="unfinished"/> + <translation>키 구성 요소 집합, 눌러서 변경하거나 삭제</translation> </message> <message> <source>Add %1</source> <comment>Add a key component</comment> - <translation type="unfinished"/> + <translation>%1 추가</translation> </message> <message> <source>Change %1</source> <comment>Change a key component</comment> - <translation type="unfinished"/> + <translation>%1 변경</translation> </message> <message> <source>Remove %1</source> <comment>Remove a key component</comment> - <translation type="unfinished"/> + <translation>%1 삭제</translation> </message> <message> <source>%1 set, click to change or remove</source> <comment>Change or remove a key component</comment> - <translation type="unfinished"/> + <translation>%1 설정됨, 눌러서 변경 및 삭제</translation> </message> </context> <context> @@ -3200,11 +3223,11 @@ Line %2, column %3</source> </message> <message> <source>Key File</source> - <translation type="unfinished"/> + <translation>키 파일</translation> </message> <message> <source><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></source> - <translation type="unfinished"/> + <translation><p>무작위 바이트가 들어 있는 키 파일을 추가하여 보안을 향상시킬 수 있습니다.</p><p>키 파일을 안전한 곳에 보관해야 하며 키 파일을 잃어버리면 데이터베이스에 접근할 수 없습니다!</p></translation> </message> <message> <source>Legacy key file format</source> @@ -3215,12 +3238,16 @@ Line %2, column %3</source> unsupported in the future. Please go to the master key settings and generate a new key file.</source> - <translation type="unfinished"/> + <translation>차후 버전에서 지원이 중단될 예정인 레거시 키 파일 +형식을 사용하고 있습니다. + +마스터 키 설정으로 이동하여 새 키 파일을 생성하십시오.</translation> </message> <message> <source>Error loading the key file '%1' Message: %2</source> - <translation type="unfinished"/> + <translation>키 파일 '%1'을(를) 불러올 수 없음 +메시지: %2</translation> </message> <message> <source>Key files</source> @@ -3236,11 +3263,11 @@ Message: %2</source> </message> <message> <source>Error creating key file</source> - <translation type="unfinished"/> + <translation>키 파일 생성 오류</translation> </message> <message> <source>Unable to create key file: %1</source> - <translation type="unfinished"/> + <translation>키 파일을 만들 수 없음: %1</translation> </message> <message> <source>Select a key file</source> @@ -3415,203 +3442,205 @@ This version is not meant for production use.</source> </message> <message> <source>&Donate</source> - <translation type="unfinished"/> + <translation>기부(&D)</translation> </message> <message> <source>Report a &bug</source> - <translation type="unfinished"/> + <translation>버그 보고(&B)</translation> </message> <message> <source>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.</source> - <translation type="unfinished"/> + <translation>경고: 사용 중인 Qt 버전에서 KeePassXC를 화상 키보드와 사용했을 때 충돌할 수 있습니다! +다운로드 페이지에 있는 AppImage 사용을 추천합니다.</translation> </message> <message> <source>&Import</source> - <translation type="unfinished"/> + <translation>가져오기(&I)</translation> </message> <message> <source>Copy att&ribute...</source> - <translation type="unfinished"/> + <translation>속성 복사(&R)...</translation> </message> <message> <source>TOTP...</source> - <translation type="unfinished"/> + <translation>TOTP...</translation> </message> <message> <source>&New database...</source> - <translation type="unfinished"/> + <translation>새 데이터베이스(&N)...</translation> </message> <message> <source>Create a new database</source> - <translation type="unfinished"/> + <translation>새 데이터베이스 만들기</translation> </message> <message> <source>&Merge from database...</source> - <translation type="unfinished"/> + <translation>데이터베이스에서 합치기(&M)...</translation> </message> <message> <source>Merge from another KDBX database</source> - <translation type="unfinished"/> + <translation>다른 KDBX 데이터베이스에서 합치기</translation> </message> <message> <source>&New entry</source> - <translation type="unfinished"/> + <translation>새 항목(&N)</translation> </message> <message> <source>Add a new entry</source> - <translation type="unfinished"/> + <translation>새 항목 추가하기</translation> </message> <message> <source>&Edit entry</source> - <translation type="unfinished"/> + <translation>항목 편집(&E)</translation> </message> <message> <source>View or edit entry</source> - <translation type="unfinished"/> + <translation>항목을 보거나 편집하기</translation> </message> <message> <source>&New group</source> - <translation type="unfinished"/> + <translation>새 그룹(&N)</translation> </message> <message> <source>Add a new group</source> - <translation type="unfinished"/> + <translation>새 그룹 추가하기</translation> </message> <message> <source>Change master &key...</source> - <translation type="unfinished"/> + <translation>마스터 키 변경(&K)...</translation> </message> <message> <source>&Database settings...</source> - <translation type="unfinished"/> + <translation>데이터베이스 설정(&D)...</translation> </message> <message> <source>Copy &password</source> - <translation type="unfinished"/> + <translation>암호 복사(&P)</translation> </message> <message> <source>Perform &Auto-Type</source> - <translation type="unfinished"/> + <translation>자동 입력 실행(&A)</translation> </message> <message> <source>Open &URL</source> - <translation type="unfinished"/> + <translation>URL 열기(&U)</translation> </message> <message> <source>KeePass 1 database...</source> - <translation type="unfinished"/> + <translation>KeePass 1 데이터베이스...</translation> </message> <message> <source>Import a KeePass 1 database</source> - <translation type="unfinished"/> + <translation>KeePass 1 데이터베이스 가져오기</translation> </message> <message> <source>CSV file...</source> - <translation type="unfinished"/> + <translation>CSV 파일...</translation> </message> <message> <source>Import a CSV file</source> - <translation type="unfinished"/> + <translation>CSV 파일 가져오기</translation> </message> <message> <source>Show TOTP...</source> - <translation type="unfinished"/> + <translation>TOTP 보이기...</translation> </message> <message> <source>Show TOTP QR Code...</source> - <translation type="unfinished"/> + <translation>TOTP QR 코드 보이기...</translation> </message> <message> <source>Check for Updates...</source> - <translation type="unfinished"/> + <translation>업데이트 확인...</translation> </message> <message> <source>Share entry</source> - <translation type="unfinished"/> + <translation>항목 공유</translation> </message> <message> <source>NOTE: You are using a pre-release version of KeePassXC! Expect some bugs and minor issues, this version is not meant for production use.</source> - <translation type="unfinished"/> + <translation>알림: KeePassXC의 미리 보기 버전을 사용하고 있습니다! +이 버전은 일반 사용자 대상 버전이 아니므로 버그나 사소한 문제가 발생할 수 있습니다.</translation> </message> <message> <source>Check for updates on startup?</source> - <translation type="unfinished"/> + <translation>시작할 때 업데이트를 확인하시겠습니까?</translation> </message> <message> <source>Would you like KeePassXC to check for updates on startup?</source> - <translation type="unfinished"/> + <translation>KeePassXC를 시작할 때 업데이트를 확인하시겠습니까?</translation> </message> <message> <source>You can always check for updates manually from the application menu.</source> - <translation type="unfinished"/> + <translation>언제든지 프로그램 메뉴에서 수동으로 업데이트를 확인할 수 있습니다.</translation> </message> </context> <context> <name>Merger</name> <message> <source>Creating missing %1 [%2]</source> - <translation type="unfinished"/> + <translation>존재하지 않는 %1 [%2] 생성 중</translation> </message> <message> <source>Relocating %1 [%2]</source> - <translation type="unfinished"/> + <translation>%1 [%2] 위치 변경 중</translation> </message> <message> <source>Overwriting %1 [%2]</source> - <translation type="unfinished"/> + <translation>%1 [%2] 덮어쓰는 중</translation> </message> <message> <source>older entry merged from database "%1"</source> - <translation type="unfinished"/> + <translation>데이터베이스 "%1"에서 합쳐진 이전 항목</translation> </message> <message> <source>Adding backup for older target %1 [%2]</source> - <translation type="unfinished"/> + <translation>오래된 대상 %1 [%2]의 백업 추가 중</translation> </message> <message> <source>Adding backup for older source %1 [%2]</source> - <translation type="unfinished"/> + <translation>오래된 원본 %1 [%2]의 백업 추가 중</translation> </message> <message> <source>Reapplying older target entry on top of newer source %1 [%2]</source> - <translation type="unfinished"/> + <translation>새로운 원본 %1 [%2]에 오래된 대상 항목 다시 적용하는 중</translation> </message> <message> <source>Reapplying older source entry on top of newer target %1 [%2]</source> - <translation type="unfinished"/> + <translation>새로운 대상 %1 [%2]에 오래된 원본 항목 다시 적용하는 중</translation> </message> <message> <source>Synchronizing from newer source %1 [%2]</source> - <translation type="unfinished"/> + <translation>새로운 원본 %1 [%2]에서 동기화하는 중</translation> </message> <message> <source>Synchronizing from older source %1 [%2]</source> - <translation type="unfinished"/> + <translation>오래된 원본 %1 [%2]에서 동기화하는 중</translation> </message> <message> <source>Deleting child %1 [%2]</source> - <translation type="unfinished"/> + <translation>자식 항목 %1 [%2] 삭제 중</translation> </message> <message> <source>Deleting orphan %1 [%2]</source> - <translation type="unfinished"/> + <translation>고립된 항목 %1 [%2] 삭제 중</translation> </message> <message> <source>Changed deleted objects</source> - <translation type="unfinished"/> + <translation>변경된 삭제된 개체</translation> </message> <message> <source>Adding missing icon %1</source> - <translation type="unfinished"/> + <translation>빠진 아이콘 %1 추가하는 중</translation> </message> </context> <context> <name>NewDatabaseWizard</name> <message> <source>Create a new KeePassXC database...</source> - <translation type="unfinished"/> + <translation>새 KeePassXC 데이터베이스 만들기...</translation> </message> <message> <source>Root</source> @@ -3623,56 +3652,56 @@ Expect some bugs and minor issues, this version is not meant for production use. <name>NewDatabaseWizardPage</name> <message> <source>WizardPage</source> - <translation type="unfinished"/> + <translation>마법사페이지</translation> </message> <message> <source>En&cryption Settings</source> - <translation type="unfinished"/> + <translation>암호화 설정(&C)</translation> </message> <message> <source>Here you can adjust the database encryption settings. Don't worry, you can change them later in the database settings.</source> - <translation type="unfinished"/> + <translation>데이터베이스 암호화 설정을 변경할 수 있습니다. 나중에 데이터베이스 설정에서도 변경할 수 있습니다.</translation> </message> <message> <source>Advanced Settings</source> - <translation type="unfinished"/> + <translation>고급 설정</translation> </message> <message> <source>Simple Settings</source> - <translation type="unfinished"/> + <translation>간단한 설정</translation> </message> </context> <context> <name>NewDatabaseWizardPageEncryption</name> <message> <source>Encryption Settings</source> - <translation type="unfinished"/> + <translation>암호화 설정</translation> </message> <message> <source>Here you can adjust the database encryption settings. Don't worry, you can change them later in the database settings.</source> - <translation type="unfinished"/> + <translation>데이터베이스 암호화 설정을 변경할 수 있습니다. 나중에 데이터베이스 설정에서도 변경할 수 있습니다.</translation> </message> </context> <context> <name>NewDatabaseWizardPageMasterKey</name> <message> <source>Database Master Key</source> - <translation type="unfinished"/> + <translation>데이터베이스 마스터 키</translation> </message> <message> <source>A master key known only to you protects your database.</source> - <translation type="unfinished"/> + <translation>나만 알고 있는 마스터 키로 데이터베이스를 보호하십시오.</translation> </message> </context> <context> <name>NewDatabaseWizardPageMetaData</name> <message> <source>General Database Information</source> - <translation type="unfinished"/> + <translation>일반 데이터베이스 정보</translation> </message> <message> <source>Please fill in the display name and an optional description for your new database:</source> - <translation type="unfinished"/> + <translation>새 데이터베이스 표시 이름과 추가 설명(선택)을 입력하십시오:</translation> </message> </context> <context> @@ -3755,23 +3784,23 @@ Expect some bugs and minor issues, this version is not meant for production use. </message> <message> <source>Unsupported key type: %1</source> - <translation type="unfinished"/> + <translation>지원하지 않는 키 형식: %1</translation> </message> <message> <source>Unknown cipher: %1</source> - <translation type="unfinished"/> + <translation>알 수 없는 암호화: %1</translation> </message> <message> <source>Cipher IV is too short for MD5 kdf</source> - <translation type="unfinished"/> + <translation>MD5 키 유도 함수에 IV가 너무 짧음</translation> </message> <message> <source>Unknown KDF: %1</source> - <translation type="unfinished"/> + <translation>알 수 없는 KDF: %1</translation> </message> <message> <source>Unknown key type: %1</source> - <translation type="unfinished"/> + <translation>알 수 없는 키 형식: %1</translation> </message> </context> <context> @@ -3782,7 +3811,7 @@ Expect some bugs and minor issues, this version is not meant for production use. </message> <message> <source>Confirm password:</source> - <translation type="unfinished"/> + <translation>암호 확인:</translation> </message> <message> <source>Password</source> @@ -3790,15 +3819,15 @@ Expect some bugs and minor issues, this version is not meant for production use. </message> <message> <source><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></source> - <translation type="unfinished"/> + <translation><p>암호는 데이터베이스를 보호하는 주요 수단입니다.</p><p>좋은 암호는 길고 예측할 수 없어야 합니다. KeePassXC에서 암호를 생성할 수 있습니다.</p></translation> </message> <message> <source>Passwords do not match.</source> - <translation type="unfinished"/> + <translation>암호가 일치하지 않습니다.</translation> </message> <message> <source>Generate master password</source> - <translation type="unfinished"/> + <translation>마스터 암호 생성</translation> </message> </context> <context> @@ -3914,11 +3943,11 @@ Expect some bugs and minor issues, this version is not meant for production use. </message> <message> <source>ExtendedASCII</source> - <translation type="unfinished"/> + <translation>확장 ASCII</translation> </message> <message> <source>Switch to advanced mode</source> - <translation type="unfinished"/> + <translation>고급 모드로 전환</translation> </message> <message> <source>Advanced</source> @@ -3926,7 +3955,7 @@ Expect some bugs and minor issues, this version is not meant for production use. </message> <message> <source>Upper Case Letters A to F</source> - <translation type="unfinished"/> + <translation>대문자 A-F</translation> </message> <message> <source>A-Z</source> @@ -3934,7 +3963,7 @@ Expect some bugs and minor issues, this version is not meant for production use. </message> <message> <source>Lower Case Letters A to F</source> - <translation type="unfinished"/> + <translation>소문자 A-F</translation> </message> <message> <source>a-z</source> @@ -3946,108 +3975,108 @@ Expect some bugs and minor issues, this version is not meant for production use. </message> <message> <source>Braces</source> - <translation type="unfinished"/> + <translation>괄호</translation> </message> <message> <source>{[(</source> - <translation type="unfinished"/> + <translation>{[(</translation> </message> <message> <source>Punctuation</source> - <translation type="unfinished"/> + <translation>구두점</translation> </message> <message> <source>.,:;</source> - <translation type="unfinished"/> + <translation>.,:;</translation> </message> <message> <source>Quotes</source> - <translation type="unfinished"/> + <translation>따옴표</translation> </message> <message> <source>" '</source> - <translation type="unfinished"/> + <translation>" '</translation> </message> <message> <source>Math</source> - <translation type="unfinished"/> + <translation>수학 기호</translation> </message> <message> <source><*+!?=</source> - <translation type="unfinished"/> + <translation><*+!?=</translation> </message> <message> <source>Dashes</source> - <translation type="unfinished"/> + <translation>대시</translation> </message> <message> <source>\_|-/</source> - <translation type="unfinished"/> + <translation>\_|-/</translation> </message> <message> <source>Logograms</source> - <translation type="unfinished"/> + <translation>로고그램</translation> </message> <message> <source>#$%&&@^`~</source> - <translation type="unfinished"/> + <translation>#$%&&@^`~</translation> </message> <message> <source>Switch to simple mode</source> - <translation type="unfinished"/> + <translation>간단한 모드로 전환</translation> </message> <message> <source>Simple</source> - <translation type="unfinished"/> + <translation>간단히</translation> </message> <message> <source>Character set to exclude from generated password</source> - <translation type="unfinished"/> + <translation>생성된 암호에서 제외할 문자 집합</translation> </message> <message> <source>Do not include:</source> - <translation type="unfinished"/> + <translation>포함하지 않음:</translation> </message> <message> <source>Add non-hex letters to "do not include" list</source> - <translation type="unfinished"/> + <translation>"포함하지 않음" 목록에 16진수가 아닌 문자 추가</translation> </message> <message> <source>Hex</source> - <translation type="unfinished"/> + <translation>16진</translation> </message> <message> <source>Excluded characters: "0", "1", "l", "I", "O", "|", "﹒"</source> - <translation type="unfinished"/> + <translation>제외할 글자: "0", "1", "l", "I", "O", "|", "﹒"</translation> </message> <message> <source>Word Co&unt:</source> - <translation type="unfinished"/> + <translation>단어 개수(&U):</translation> </message> <message> <source>Regenerate</source> - <translation type="unfinished"/> + <translation>다시 생성</translation> </message> </context> <context> <name>QApplication</name> <message> <source>KeeShare</source> - <translation type="unfinished"/> + <translation>KeeShare</translation> </message> </context> <context> <name>QFileDialog</name> <message> <source>Select</source> - <translation type="unfinished"/> + <translation>선택</translation> </message> </context> <context> <name>QMessageBox</name> <message> <source>Overwrite</source> - <translation type="unfinished"/> + <translation>덮어쓰기</translation> </message> <message> <source>Delete</source> @@ -4055,11 +4084,11 @@ Expect some bugs and minor issues, this version is not meant for production use. </message> <message> <source>Move</source> - <translation type="unfinished"/> + <translation>이동</translation> </message> <message> <source>Empty</source> - <translation type="unfinished"/> + <translation>비어 있음</translation> </message> <message> <source>Remove</source> @@ -4067,7 +4096,7 @@ Expect some bugs and minor issues, this version is not meant for production use. </message> <message> <source>Skip</source> - <translation type="unfinished"/> + <translation>건너뛰기</translation> </message> <message> <source>Disable</source> @@ -4075,7 +4104,7 @@ Expect some bugs and minor issues, this version is not meant for production use. </message> <message> <source>Merge</source> - <translation type="unfinished"/> + <translation>합치기</translation> </message> </context> <context> @@ -4375,320 +4404,324 @@ Available commands: </message> <message> <source>Generate a new random diceware passphrase.</source> - <translation type="unfinished"/> + <translation>새로운 주사위 암호를 생성합니다.</translation> </message> <message> <source>Word count for the diceware passphrase.</source> - <translation type="unfinished"/> + <translation>주사위 암호 단어 개수입니다.</translation> </message> <message> <source>Wordlist for the diceware generator. [Default: EFF English]</source> - <translation type="unfinished"/> + <translation>주사위 암호 생성 시 사용할 단어 목록입니다. +[기본값: EFF 영어]</translation> </message> <message> <source>Generate a new random password.</source> - <translation type="unfinished"/> + <translation>새 무작위 암호를 생성합니다.</translation> </message> <message> <source>Invalid value for password length %1.</source> - <translation type="unfinished"/> + <translation>암호 길이 %1의 값이 잘못되었습니다.</translation> </message> <message> <source>Could not create entry with path %1.</source> - <translation type="unfinished"/> + <translation>경로 %1에 항목을 만들 수 없습니다.</translation> </message> <message> <source>Enter password for new entry: </source> - <translation type="unfinished"/> + <translation>새 항목의 암호 입력: </translation> </message> <message> <source>Writing the database failed %1.</source> - <translation type="unfinished"/> + <translation>데이터베이스에 기록할 수 없습니다 %1.</translation> </message> <message> <source>Successfully added entry %1.</source> - <translation type="unfinished"/> + <translation>항목 %1을(를) 추가했습니다.</translation> </message> <message> <source>Copy the current TOTP to the clipboard.</source> - <translation type="unfinished"/> + <translation>현재 TOTP를 클립보드에 복사합니다.</translation> </message> <message> <source>Invalid timeout value %1.</source> - <translation type="unfinished"/> + <translation>시간 제한 값 %1이(가) 잘못되었습니다.</translation> </message> <message> <source>Entry %1 not found.</source> - <translation type="unfinished"/> + <translation>항목 %1을(를) 찾을 수 없습니다.</translation> </message> <message> <source>Entry with path %1 has no TOTP set up.</source> - <translation type="unfinished"/> + <translation>경로 %1에 있는 항목에 TOTP가 설정되지 않았습니다.</translation> </message> <message> <source>Entry's current TOTP copied to the clipboard!</source> - <translation type="unfinished"/> + <translation>항목의 현재 TOTP를 클립보드에 복사했습니다!</translation> </message> <message> <source>Entry's password copied to the clipboard!</source> - <translation type="unfinished"/> + <translation>항목의 암호를 클립보드에 복사했습니다!</translation> </message> <message numerus="yes"> <source>Clearing the clipboard in %1 second(s)...</source> - <translation type="unfinished"><numerusform></numerusform></translation> + <translation><numerusform>%1초 후 클립보드를 지웁니다...</numerusform></translation> </message> <message> <source>Clipboard cleared!</source> - <translation type="unfinished"/> + <translation>클립보드를 지웠습니다!</translation> </message> <message> <source>Silence password prompt and other secondary outputs.</source> - <translation type="unfinished"/> + <translation>암호 입력 프롬프트 및 추가 출력을 숨깁니다.</translation> </message> <message> <source>count</source> <comment>CLI parameter</comment> - <translation type="unfinished"/> + <translation>count</translation> </message> <message> <source>Invalid value for password length: %1</source> - <translation type="unfinished"/> + <translation>암호 길이 값이 잘못됨: %1</translation> </message> <message> <source>Could not find entry with path %1.</source> - <translation type="unfinished"/> + <translation>경로 %1에서 항목을 찾을 수 없습니다.</translation> </message> <message> <source>Not changing any field for entry %1.</source> - <translation type="unfinished"/> + <translation>항목 %1의 필드를 변경하지 않습니다.</translation> </message> <message> <source>Enter new password for entry: </source> - <translation type="unfinished"/> + <translation>항목의 새로운 암호 입력: </translation> </message> <message> <source>Writing the database failed: %1</source> - <translation type="unfinished"/> + <translation>데이터베이스에기록할 수 없음: %1</translation> </message> <message> <source>Successfully edited entry %1.</source> - <translation type="unfinished"/> + <translation>항목 %1을(를) 편집했습니다.</translation> </message> <message> <source>Length %1</source> - <translation type="unfinished"/> + <translation>길이 %1</translation> </message> <message> <source>Entropy %1</source> - <translation type="unfinished"/> + <translation>엔트로피 %1</translation> </message> <message> <source>Log10 %1</source> - <translation type="unfinished"/> + <translation>Log10 %1</translation> </message> <message> <source>Multi-word extra bits %1</source> - <translation type="unfinished"/> + <translation>여러 단어 추가 비트 %1</translation> </message> <message> <source>Type: Bruteforce</source> - <translation type="unfinished"/> + <translation>형식: 무작위 대입</translation> </message> <message> <source>Type: Dictionary</source> - <translation type="unfinished"/> + <translation>형식: 사전</translation> </message> <message> <source>Type: Dict+Leet</source> - <translation type="unfinished"/> + <translation>형식: 사전+Leet</translation> </message> <message> <source>Type: User Words</source> - <translation type="unfinished"/> + <translation>형식: 사용자 단어</translation> </message> <message> <source>Type: User+Leet</source> - <translation type="unfinished"/> + <translation>형식: 사용자+Leet</translation> </message> <message> <source>Type: Repeated</source> - <translation type="unfinished"/> + <translation>형식: 반복됨</translation> </message> <message> <source>Type: Sequence</source> - <translation type="unfinished"/> + <translation>형식: 시퀀스</translation> </message> <message> <source>Type: Spatial</source> - <translation type="unfinished"/> + <translation>형식: 인접</translation> </message> <message> <source>Type: Date</source> - <translation type="unfinished"/> + <translation>형식: 날짜</translation> </message> <message> <source>Type: Bruteforce(Rep)</source> - <translation type="unfinished"/> + <translation>형식: 무작위 대입(반복)</translation> </message> <message> <source>Type: Dictionary(Rep)</source> - <translation type="unfinished"/> + <translation>형식: 사전(반복)</translation> </message> <message> <source>Type: Dict+Leet(Rep)</source> - <translation type="unfinished"/> + <translation>형식: 사전+Leet(반복)</translation> </message> <message> <source>Type: User Words(Rep)</source> - <translation type="unfinished"/> + <translation>형식: 사용자 단어(반복)</translation> </message> <message> <source>Type: User+Leet(Rep)</source> - <translation type="unfinished"/> + <translation>형식: 사용자+Leet(반복)</translation> </message> <message> <source>Type: Repeated(Rep)</source> - <translation type="unfinished"/> + <translation>형식: 반복됨(반복)</translation> </message> <message> <source>Type: Sequence(Rep)</source> - <translation type="unfinished"/> + <translation>형식: 시퀀스(반복)</translation> </message> <message> <source>Type: Spatial(Rep)</source> - <translation type="unfinished"/> + <translation>형식: 인접(반복)</translation> </message> <message> <source>Type: Date(Rep)</source> - <translation type="unfinished"/> + <translation>형식: 날짜(반복)</translation> </message> <message> <source>Type: Unknown%1</source> - <translation type="unfinished"/> + <translation>형식: 알 수 없음%1</translation> </message> <message> <source>Entropy %1 (%2)</source> - <translation type="unfinished"/> + <translation>엔트로피 %1(%2)</translation> </message> <message> <source>*** Password length (%1) != sum of length of parts (%2) ***</source> - <translation type="unfinished"/> + <translation>*** 암호 길이 (%1) != 개별 부분 길이의 합 (%2) ***</translation> </message> <message> <source>Failed to load key file %1: %2</source> - <translation type="unfinished"/> + <translation>키 파일 %1을(를) 불러올 수 없음: %2</translation> </message> <message> <source>File %1 does not exist.</source> - <translation type="unfinished"/> + <translation>파일 %1이(가) 존재하지 않습니다.</translation> </message> <message> <source>Unable to open file %1.</source> - <translation type="unfinished"/> + <translation>파일 %1을(를) 열 수 없습니다.</translation> </message> <message> <source>Error while reading the database: %1</source> - <translation type="unfinished"/> + <translation>데이터베이스 읽기 오류: +%1</translation> </message> <message> <source>Error while parsing the database: %1</source> - <translation type="unfinished"/> + <translation>데이터베이스 처리 오류: +%1</translation> </message> <message> <source>Length of the generated password</source> - <translation type="unfinished"/> + <translation>생성된 암호의 길이</translation> </message> <message> <source>Use lowercase characters</source> - <translation type="unfinished"/> + <translation>소문자 사용</translation> </message> <message> <source>Use uppercase characters</source> - <translation type="unfinished"/> + <translation>대문자 사용</translation> </message> <message> <source>Use numbers.</source> - <translation type="unfinished"/> + <translation>숫자를 사용합니다.</translation> </message> <message> <source>Use special characters</source> - <translation type="unfinished"/> + <translation>특수 문자 사용</translation> </message> <message> <source>Use extended ASCII</source> - <translation type="unfinished"/> + <translation>확장 ASCII 사용</translation> </message> <message> <source>Exclude character set</source> - <translation type="unfinished"/> + <translation>제외할 문자 집합</translation> </message> <message> <source>chars</source> - <translation type="unfinished"/> + <translation>글자</translation> </message> <message> <source>Exclude similar looking characters</source> - <translation type="unfinished"/> + <translation>비슷하게 생긴 문자 제외</translation> </message> <message> <source>Include characters from every selected group</source> - <translation type="unfinished"/> + <translation>모든 그룹에서 글자 선택</translation> </message> <message> <source>Recursively list the elements of the group.</source> - <translation type="unfinished"/> + <translation>그룹의 구성 요소를 재귀적으로 표시합니다.</translation> </message> <message> <source>Cannot find group %1.</source> - <translation type="unfinished"/> + <translation>그룹 %1을(를) 찾을 수 없습니다.</translation> </message> <message> <source>Error reading merge file: %1</source> - <translation type="unfinished"/> + <translation>합칠 파일을 읽는 중 오류 발생: +%1</translation> </message> <message> <source>Unable to save database to file : %1</source> - <translation type="unfinished"/> + <translation>데이터베이스를 파일로 저장할 수 없음: %1</translation> </message> <message> <source>Unable to save database to file: %1</source> - <translation type="unfinished"/> + <translation>데이터베이스를 파일로 저장할 수 없음: %1</translation> </message> <message> <source>Successfully recycled entry %1.</source> - <translation type="unfinished"/> + <translation>항목 %1을(를) 휴지통으로 이동했습니다.</translation> </message> <message> <source>Successfully deleted entry %1.</source> - <translation type="unfinished"/> + <translation>항목 %1을(를) 삭제했습니다.</translation> </message> <message> <source>Show the entry's current TOTP.</source> - <translation type="unfinished"/> + <translation>항목의 현재 TOTP를 표시합니다.</translation> </message> <message> <source>ERROR: unknown attribute %1.</source> - <translation type="unfinished"/> + <translation>오류: 알 수 없는 속성 %1.</translation> </message> <message> <source>No program defined for clipboard manipulation</source> - <translation type="unfinished"/> + <translation>클립보드 변경 프로그램이 지정되지 않았음</translation> </message> <message> <source>Unable to start program %1</source> - <translation type="unfinished"/> + <translation>프로그램 %1을(를) 시작할 수 없음</translation> </message> <message> <source>file empty</source> - <translation type="unfinished"/> + <translation>파일이 비어 있음</translation> </message> <message> <source>%1: (row, col) %2,%3</source> - <translation type="unfinished"/> + <translation>%1: (줄, 칸) %2, %3</translation> </message> <message> <source>AES: 256-bit</source> @@ -4717,56 +4750,56 @@ Available commands: <message> <source>Invalid Settings</source> <comment>TOTP</comment> - <translation type="unfinished"/> + <translation>잘못된 설정</translation> </message> <message> <source>Invalid Key</source> <comment>TOTP</comment> - <translation type="unfinished"/> + <translation>잘못된 키</translation> </message> <message> <source>Message encryption failed.</source> - <translation type="unfinished"/> + <translation>메시지를 암호화할 수 없습니다.</translation> </message> <message> <source>No groups found</source> - <translation type="unfinished"/> + <translation>그룹을 찾을 수 없음</translation> </message> <message> <source>Create a new database.</source> - <translation type="unfinished"/> + <translation>새 데이터베이스를 만듭니다.</translation> </message> <message> <source>File %1 already exists.</source> - <translation type="unfinished"/> + <translation>파일 %1이(가) 이미 존재합니다.</translation> </message> <message> <source>Loading the key file failed</source> - <translation type="unfinished"/> + <translation>키 파일을 불러올 수 없음</translation> </message> <message> <source>No key is set. Aborting database creation.</source> - <translation type="unfinished"/> + <translation>설정된 키가 없습니다. 데이터베이스 생성을 중단합니다.</translation> </message> <message> <source>Failed to save the database: %1.</source> - <translation type="unfinished"/> + <translation>데이터베이스를 저장할 수 없음: %1.</translation> </message> <message> <source>Successfully created new database.</source> - <translation type="unfinished"/> + <translation>새 데이터베이스를 만들었습니다.</translation> </message> <message> <source>Insert password to encrypt database (Press enter to leave blank): </source> - <translation type="unfinished"/> + <translation>데이터베이스를 암호화할 암호 입력(Enter 키를 누르면 비워 둡니다): </translation> </message> <message> <source>Creating KeyFile %1 failed: %2</source> - <translation type="unfinished"/> + <translation>키 파일 %1 생성 실패: %2</translation> </message> <message> <source>Loading KeyFile %1 failed: %2</source> - <translation type="unfinished"/> + <translation>키 파일 %1 불러오기 실패: %2</translation> </message> <message> <source>Remove an entry from the database.</source> @@ -4822,11 +4855,11 @@ Available commands: </message> <message> <source>Database password: </source> - <translation type="unfinished"/> + <translation>데이터베이스 암호: </translation> </message> <message> <source>Cannot create new group</source> - <translation type="unfinished"/> + <translation>새 그룹을 만들 수 없음</translation> </message> </context> <context> @@ -4867,90 +4900,90 @@ Available commands: <name>SSHAgent</name> <message> <source>Agent connection failed.</source> - <translation type="unfinished"/> + <translation>에이전트에 연결할 수 없습니다.</translation> </message> <message> <source>Agent protocol error.</source> - <translation type="unfinished"/> + <translation>에이전트 프로토콜 오류입니다.</translation> </message> <message> <source>No agent running, cannot add identity.</source> - <translation type="unfinished"/> + <translation>에이전트가 실행 중이지 않아서 정보를 추가할 수 없습니다.</translation> </message> <message> <source>No agent running, cannot remove identity.</source> - <translation type="unfinished"/> + <translation>에이전트가 실행 중이지 않아서 정보를 삭제할 수 없습니다.</translation> </message> <message> <source>Agent refused this identity. Possible reasons include:</source> - <translation type="unfinished"/> + <translation>에이전트에서 이 정보를 거부했습니다. 가능한 이유:</translation> </message> <message> <source>The key has already been added.</source> - <translation type="unfinished"/> + <translation>키가 이미 추가되었습니다.</translation> </message> <message> <source>Restricted lifetime is not supported by the agent (check options).</source> - <translation type="unfinished"/> + <translation>에이전트에서 시간 제한을 지원하지 않습니다(옵션을 확인하십시오).</translation> </message> <message> <source>A confirmation request is not supported by the agent (check options).</source> - <translation type="unfinished"/> + <translation>에이전트에서 확인 요청을 지원하지 않습니다(옵션을 확인하십시오).</translation> </message> </context> <context> <name>SearchHelpWidget</name> <message> <source>Search Help</source> - <translation type="unfinished"/> + <translation>검색 도움말</translation> </message> <message> <source>Search terms are as follows: [modifiers][field:]["]term["]</source> - <translation type="unfinished"/> + <translation>다음 검색어를 사용할 수 있습니다: [수정자][필드:]["]검색어["]</translation> </message> <message> <source>Every search term must match (ie, logical AND)</source> - <translation type="unfinished"/> + <translation>모든 검색어가 일치해야 합니다(논리곱, AND)</translation> </message> <message> <source>Modifiers</source> - <translation type="unfinished"/> + <translation>수정자</translation> </message> <message> <source>exclude term from results</source> - <translation type="unfinished"/> + <translation>결과에서 검색어 제외</translation> </message> <message> <source>match term exactly</source> - <translation type="unfinished"/> + <translation>검색어와 정확히 일치</translation> </message> <message> <source>use regex in term</source> - <translation type="unfinished"/> + <translation>검색어에 정규 표현식 사용</translation> </message> <message> <source>Fields</source> - <translation type="unfinished"/> + <translation>필드</translation> </message> <message> <source>Term Wildcards</source> - <translation type="unfinished"/> + <translation>항목 와일드카드</translation> </message> <message> <source>match anything</source> - <translation type="unfinished"/> + <translation>모든 것과 일치</translation> </message> <message> <source>match one</source> - <translation type="unfinished"/> + <translation>하나와 일치</translation> </message> <message> <source>logical OR</source> - <translation type="unfinished"/> + <translation>논리합(OR)</translation> </message> <message> <source>Examples</source> - <translation type="unfinished"/> + <translation>예제</translation> </message> </context> <context> @@ -4969,12 +5002,12 @@ Available commands: </message> <message> <source>Search Help</source> - <translation type="unfinished"/> + <translation>검색 도움말</translation> </message> <message> <source>Search (%1)...</source> <comment>Search placeholder text, %1 is the keyboard shortcut</comment> - <translation type="unfinished"/> + <translation>검색(%1)...</translation> </message> <message> <source>Case sensitive</source> @@ -4985,31 +5018,31 @@ Available commands: <name>SettingsWidgetKeeShare</name> <message> <source>Active</source> - <translation type="unfinished"/> + <translation>활성</translation> </message> <message> <source>Allow export</source> - <translation type="unfinished"/> + <translation>내보내기 허용</translation> </message> <message> <source>Allow import</source> - <translation type="unfinished"/> + <translation>가져오기 허용</translation> </message> <message> <source>Own certificate</source> - <translation type="unfinished"/> + <translation>자가 인증서</translation> </message> <message> <source>Fingerprint:</source> - <translation type="unfinished"/> + <translation>지문:</translation> </message> <message> <source>Certificate:</source> - <translation type="unfinished"/> + <translation>인증서:</translation> </message> <message> <source>Signer</source> - <translation type="unfinished"/> + <translation>서명자</translation> </message> <message> <source>Key:</source> @@ -5025,23 +5058,23 @@ Available commands: </message> <message> <source>Export</source> - <translation type="unfinished"/> + <translation>내보내기</translation> </message> <message> <source>Imported certificates</source> - <translation type="unfinished"/> + <translation>가져온 인증서</translation> </message> <message> <source>Trust</source> - <translation type="unfinished"/> + <translation>신뢰</translation> </message> <message> <source>Ask</source> - <translation type="unfinished"/> + <translation>묻기</translation> </message> <message> <source>Untrust</source> - <translation type="unfinished"/> + <translation>믿지 않음</translation> </message> <message> <source>Remove</source> @@ -5049,11 +5082,11 @@ Available commands: </message> <message> <source>Path</source> - <translation type="unfinished"/> + <translation>경로</translation> </message> <message> <source>Status</source> - <translation type="unfinished"/> + <translation>상태</translation> </message> <message> <source>Fingerprint</source> @@ -5061,28 +5094,28 @@ Available commands: </message> <message> <source>Certificate</source> - <translation type="unfinished"/> + <translation>인증서</translation> </message> <message> <source>Trusted</source> - <translation type="unfinished"/> + <translation>신뢰함</translation> </message> <message> <source>Untrusted</source> - <translation type="unfinished"/> + <translation>신뢰하지 않음</translation> </message> <message> <source>Unknown</source> - <translation type="unfinished"/> + <translation>알 수 없음</translation> </message> <message> <source>key.share</source> <comment>Filetype for KeeShare key</comment> - <translation type="unfinished"/> + <translation>key.share</translation> </message> <message> <source>KeeShare key file</source> - <translation type="unfinished"/> + <translation>KeeShare 키 파일</translation> </message> <message> <source>All files</source> @@ -5090,38 +5123,38 @@ Available commands: </message> <message> <source>Select path</source> - <translation type="unfinished"/> + <translation>경로 선택</translation> </message> <message> <source>Exporting changed certificate</source> - <translation type="unfinished"/> + <translation>변경된 인증서 내보내기</translation> </message> <message> <source>The exported certificate is not the same as the one in use. Do you want to export the current certificate?</source> - <translation type="unfinished"/> + <translation>내보낸 인증서가 사용 중인 인증서와 다릅니다. 현재 인증서를 내보내시겠습니까?</translation> </message> <message> <source>Signer:</source> - <translation type="unfinished"/> + <translation>서명자:</translation> </message> </context> <context> <name>ShareObserver</name> <message> <source>Import from container without signature</source> - <translation type="unfinished"/> + <translation>서명되지 않은 컨테이너에서 가져오기</translation> </message> <message> <source>We cannot verify the source of the shared container because it is not signed. Do you really want to import from %1?</source> - <translation type="unfinished"/> + <translation>공유된 컨테이너가 서명되어 있지 않아서 원본을 확인할 수 없습니다. %1에서 가져오시겠습니까?</translation> </message> <message> <source>Import from container with certificate</source> - <translation type="unfinished"/> + <translation>서명된 컨테이너에서 가져오기</translation> </message> <message> <source>Not this time</source> - <translation type="unfinished"/> + <translation>지금은 하지 않음</translation> </message> <message> <source>Never</source> @@ -5129,123 +5162,123 @@ Available commands: </message> <message> <source>Always</source> - <translation type="unfinished"/> + <translation>항상</translation> </message> <message> <source>Just this time</source> - <translation type="unfinished"/> + <translation>이번 한 번</translation> </message> <message> <source>Import from %1 failed (%2)</source> - <translation type="unfinished"/> + <translation>%1에서 가져오기 실패 (%2)</translation> </message> <message> <source>Import from %1 successful (%2)</source> - <translation type="unfinished"/> + <translation>%1에서 가져오기 성공 (%2)</translation> </message> <message> <source>Imported from %1</source> - <translation type="unfinished"/> + <translation>%1에서 가져옴</translation> </message> <message> <source>Signed share container are not supported - import prevented</source> - <translation type="unfinished"/> + <translation>서명된 공유 컨테이너는 지원하지 않음 - 가져오기 중단됨</translation> </message> <message> <source>File is not readable</source> - <translation type="unfinished"/> + <translation>파일에서 읽을 수 없음</translation> </message> <message> <source>Invalid sharing container</source> - <translation type="unfinished"/> + <translation>잘못된 공유 컨테이너</translation> </message> <message> <source>Untrusted import prevented</source> - <translation type="unfinished"/> + <translation>신뢰할 수 없는 가져오기 중단됨</translation> </message> <message> <source>Successful signed import</source> - <translation type="unfinished"/> + <translation>서명된 가져오기 성공</translation> </message> <message> <source>Unexpected error</source> - <translation type="unfinished"/> + <translation>예상하지 못한 오류</translation> </message> <message> <source>Unsigned share container are not supported - import prevented</source> - <translation type="unfinished"/> + <translation>서명되지 않은 공유 컨테이너는 지원하지 않음 - 가져오기 중단됨</translation> </message> <message> <source>Successful unsigned import</source> - <translation type="unfinished"/> + <translation>서명되지 않은 가져오기 성공</translation> </message> <message> <source>File does not exist</source> - <translation type="unfinished"/> + <translation>파일이 존재하지 않음</translation> </message> <message> <source>Unknown share container type</source> - <translation type="unfinished"/> + <translation>알 수 없는 공유 컨테이너 형식</translation> </message> <message> <source>Overwriting signed share container is not supported - export prevented</source> - <translation type="unfinished"/> + <translation>서명된 공유 컨테이너에 덮어쓰기는 지원되지 않음 - 내보내기 중단됨</translation> </message> <message> <source>Could not write export container (%1)</source> - <translation type="unfinished"/> + <translation>내보내기 컨테이너에 기록할 수 없음 (%1)</translation> </message> <message> <source>Overwriting unsigned share container is not supported - export prevented</source> - <translation type="unfinished"/> + <translation>서명되지 않은 공유 컨테이너에 덮어쓰기는 지원되지 않음 - 내보내기 중단됨</translation> </message> <message> <source>Could not write export container</source> - <translation type="unfinished"/> + <translation>내보내기 컨테이너에 기록할 수 없음</translation> </message> <message> <source>Unexpected export error occurred</source> - <translation type="unfinished"/> + <translation>예상하지 못한 내보내기 오류</translation> </message> <message> <source>Export to %1 failed (%2)</source> - <translation type="unfinished"/> + <translation>%1(으)로 내보내기 실패 (%2)</translation> </message> <message> <source>Export to %1 successful (%2)</source> - <translation type="unfinished"/> + <translation>%1(으)로 내보내기 성공 (%2)</translation> </message> <message> <source>Export to %1</source> - <translation type="unfinished"/> + <translation>%1(으)로 내보내기</translation> </message> <message> <source>Do you want to trust %1 with the fingerprint of %2 from %3?</source> - <translation type="unfinished"/> + <translation>%3에서 온 지문이 %2인 %1을(를) 신뢰하시겠습니까?</translation> </message> <message> <source>Multiple import source path to %1 in %2</source> - <translation type="unfinished"/> + <translation>%2의 %1(으)로 다중 가져오기 원본 경로</translation> </message> <message> <source>Conflicting export target path %1 in %2</source> - <translation type="unfinished"/> + <translation>%2의 내보내기 대상 경로 %1이(가) 충돌함</translation> </message> <message> <source>Could not embed signature: Could not open file to write (%1)</source> - <translation type="unfinished"/> + <translation>서명을 임베드할 수 없음: 쓰기 위해 파일을 열 수 없음 (%1)</translation> </message> <message> <source>Could not embed signature: Could not write file (%1)</source> - <translation type="unfinished"/> + <translation>서명을 임베드할 수 없음: 파일에 쓸 수 없음 (%1)</translation> </message> <message> <source>Could not embed database: Could not open file to write (%1)</source> - <translation type="unfinished"/> + <translation>데이터베이스를 임베드할 수 없음: 쓰기 위해 파일을 열 수 없음 (%1)</translation> </message> <message> <source>Could not embed database: Could not write file (%1)</source> - <translation type="unfinished"/> + <translation>데이터베이스를 임베드할 수 없음: 파일에 쓸 수 없음 (%1)</translation> </message> </context> <context> @@ -5264,7 +5297,7 @@ Available commands: </message> <message numerus="yes"> <source>Expires in <b>%n</b> second(s)</source> - <translation type="unfinished"><numerusform></numerusform></translation> + <translation><numerusform><b>%n</b>초 후 만료됨</numerusform></translation> </message> </context> <context> @@ -5276,15 +5309,15 @@ Available commands: <message> <source>NOTE: These TOTP settings are custom and may not work with other authenticators.</source> <comment>TOTP QR code dialog warning</comment> - <translation type="unfinished"/> + <translation>메모: 이 TOTP 설정은 사용자 정의 설정이며 다른 인증기에서 동작하지 않을 수도 있습니다.</translation> </message> <message> <source>There was an error creating the QR code.</source> - <translation type="unfinished"/> + <translation>QR 코드를 생성하는 중 오류가 발생했습니다.</translation> </message> <message> <source>Closing in %1 seconds.</source> - <translation type="unfinished"/> + <translation>%1초 후 닫습니다.</translation> </message> </context> <context> @@ -5311,7 +5344,7 @@ Available commands: </message> <message> <source>Custom Settings</source> - <translation type="unfinished"/> + <translation>사용자 정의 설정</translation> </message> <message> <source>Time step:</source> @@ -5332,7 +5365,7 @@ Available commands: </message> <message> <source>7 digits</source> - <translation type="unfinished"/> + <translation>7자리</translation> </message> <message> <source>8 digits</source> @@ -5343,11 +5376,11 @@ Available commands: <name>UpdateCheckDialog</name> <message> <source>Checking for updates</source> - <translation type="unfinished"/> + <translation>업데이트 확인 중</translation> </message> <message> <source>Checking for updates...</source> - <translation type="unfinished"/> + <translation>업데이트 확인 중...</translation> </message> <message> <source>Close</source> @@ -5355,39 +5388,39 @@ Available commands: </message> <message> <source>Update Error!</source> - <translation type="unfinished"/> + <translation>업데이트 오류!</translation> </message> <message> <source>An error occurred in retrieving update information.</source> - <translation type="unfinished"/> + <translation>업데이트 정보를 가져오는 중 오류가 발생했습니다.</translation> </message> <message> <source>Please try again later.</source> - <translation type="unfinished"/> + <translation>나중에 다시 시도하십시오.</translation> </message> <message> <source>Software Update</source> - <translation type="unfinished"/> + <translation>소프트웨어 업데이트</translation> </message> <message> <source>A new version of KeePassXC is available!</source> - <translation type="unfinished"/> + <translation>KeePassXC의 새로운 버전을 사용할 수 있습니다!</translation> </message> <message> <source>KeePassXC %1 is now available — you have %2.</source> - <translation type="unfinished"/> + <translation>KeePassXC %1을(를) 사용할 수 있습니다 — 사용 중인 버전은 %2입니다.</translation> </message> <message> <source>Download it at keepassxc.org</source> - <translation type="unfinished"/> + <translation>keepassxc.org에서 다운로드</translation> </message> <message> <source>You're up-to-date!</source> - <translation type="unfinished"/> + <translation>최신 버전을 사용하고 있습니다!</translation> </message> <message> <source>KeePassXC %1 is currently the newest version available</source> - <translation type="unfinished"/> + <translation>KeePassXC의 현재 최신 버전은 %1입니다</translation> </message> </context> <context> @@ -5429,19 +5462,19 @@ Available commands: </message> <message> <source>YubiKey Challenge-Response</source> - <translation type="unfinished"/> + <translation>YubiKey 질의 응답</translation> </message> <message> <source><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></source> - <translation type="unfinished"/> + <translation><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></translation> </message> <message> <source>No YubiKey detected, please ensure it's plugged in.</source> - <translation type="unfinished"/> + <translation>YubiKey를 찾을 수 없습니다. 연결 상태를 확인하십시오.</translation> </message> <message> <source>No YubiKey inserted.</source> - <translation type="unfinished"/> + <translation>YubiKey가 연결되지 않았습니다.</translation> </message> </context> </TS>
\ 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.</source> </message> <message> <source>KeePassXC: Create a new group</source> - <translation type="unfinished"/> + <translation>KeePassXC: Lag en ny gruppe</translation> </message> <message> <source>A request for creating a new group "%1" has been received. @@ -803,7 +803,7 @@ Would you like to migrate your existing settings now?</source> </message> <message> <source>column %1</source> - <translation type="unfinished"/> + <translation>kolonne %1</translation> </message> <message> <source>Error(s) detected in CSV file!</source> @@ -852,7 +852,7 @@ Would you like to migrate your existing settings now?</source> </message> <message> <source>Unable to open file %1.</source> - <translation type="unfinished"/> + <translation>Kan ikke åpne filen %1.</translation> </message> <message> <source>Error while reading the database: %1</source> @@ -860,7 +860,7 @@ Would you like to migrate your existing settings now?</source> </message> <message> <source>Could not save, database has no file name.</source> - <translation type="unfinished"/> + <translation>Kunne ikke lagre, databasen har ingen filnavn.</translation> </message> <message> <source>File cannot be written as it is opened in read-only mode.</source> @@ -959,7 +959,7 @@ Vurder å opprette en ny nøkkelfil.</translation> <name>DatabaseSettingsDialog</name> <message> <source>Advanced Settings</source> - <translation type="unfinished"/> + <translation>Avanserte Innstillinger</translation> </message> <message> <source>General</source> @@ -1056,7 +1056,7 @@ This may prevent connection to the browser plugin.</source> </message> <message> <source>Forget all site-specific settings on entries</source> - <translation type="unfinished"/> + <translation>Glem alle side-spesifikke innstillinger og oppføringer</translation> </message> <message> <source>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!</t </message> <message> <source>Breadcrumb</source> - <translation type="unfinished"/> + <translation>Brødsmule</translation> </message> <message> <source>Type</source> @@ -1306,11 +1306,11 @@ Dersom du beholder dette antallet så kan databasen være for lett å knekke!</t </message> <message> <source>Last Signer</source> - <translation type="unfinished"/> + <translation>Siste Signatur</translation> </message> <message> <source>Certificates</source> - <translation>Sertifikat</translation> + <translation>Sertifikater</translation> </message> <message> <source> > </source> @@ -1355,11 +1355,11 @@ Are you sure you want to continue without a password?</source> <name>DatabaseSettingsWidgetMetaDataSimple</name> <message> <source>Database Name:</source> - <translation type="unfinished"/> + <translation>Databasenavn:</translation> </message> <message> <source>Description:</source> - <translation type="unfinished"/> + <translation>Beskrivelse:</translation> </message> </context> <context> @@ -2043,11 +2043,11 @@ Deaktivere sikker lagring og prøve igjen?</translation> </message> <message> <source>Select import source</source> - <translation type="unfinished"/> + <translation>Velg kilde for importering</translation> </message> <message> <source>Select export target</source> - <translation type="unfinished"/> + <translation>Velg eksporteringsmål</translation> </message> <message> <source>Select import/export file</source> @@ -2153,7 +2153,7 @@ Deaktivere sikker lagring og prøve igjen?</translation> </message> <message> <source>Select Image(s)</source> - <translation type="unfinished"/> + <translation>Velg Bilde(-r)</translation> </message> <message numerus="yes"> <source>Successfully loaded %1 of %n icon(s)</source> @@ -2382,7 +2382,7 @@ Dette kan føre til feil for de berørte programtilleggene.</translation> </message> <message> <source>Created</source> - <translation>Oppretta</translation> + <translation>Opprettet</translation> </message> <message> <source>Modified</source> @@ -2494,7 +2494,7 @@ Dette kan føre til feil for de berørte programtilleggene.</translation> </message> <message> <source>Share</source> - <translation type="unfinished"/> + <translation>Del</translation> </message> </context> <context> @@ -3122,19 +3122,19 @@ Line %2, column %3</source> </message> <message> <source>Import from</source> - <translation type="unfinished"/> + <translation>Importer fra</translation> </message> <message> <source>Export to</source> - <translation type="unfinished"/> + <translation>Eksporter til</translation> </message> <message> <source>Synchronize with</source> - <translation type="unfinished"/> + <translation>Synkroniser med</translation> </message> <message> <source>Disabled share %1</source> - <translation type="unfinished"/> + <translation>Deaktiver deling %1</translation> </message> <message> <source>Import from share %1</source> @@ -3153,7 +3153,7 @@ Line %2, column %3</source> <name>KeyComponentWidget</name> <message> <source>Key Component</source> - <translation type="unfinished"/> + <translation>Nøkkelkomponent</translation> </message> <message> <source>Key Component Description</source> @@ -3170,7 +3170,7 @@ Line %2, column %3</source> <message> <source>Add %1</source> <comment>Add a key component</comment> - <translation type="unfinished"/> + <translation>Legg til %1</translation> </message> <message> <source>Change %1</source> @@ -3200,7 +3200,7 @@ Line %2, column %3</source> </message> <message> <source>Key File</source> - <translation type="unfinished"/> + <translation>Nøkkelfil</translation> </message> <message> <source><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></source> @@ -3477,7 +3477,7 @@ Vi anbefaler at du bruker det AppImage som er tilgjengelig på nedlastingssiden. </message> <message> <source>Add a new group</source> - <translation type="unfinished"/> + <translation>Legg til ny gruppe</translation> </message> <message> <source>Change master &key...</source> @@ -3636,7 +3636,7 @@ Expect some bugs and minor issues, this version is not meant for production use. </message> <message> <source>Advanced Settings</source> - <translation type="unfinished"/> + <translation>Avanserte Innstillinger</translation> </message> <message> <source>Simple Settings</source> @@ -4351,7 +4351,7 @@ Tilgjengelige kommandoer: </message> <message> <source>Created</source> - <translation>Oppretta</translation> + <translation>Opprettet</translation> </message> <message> <source>Browser Integration</source> @@ -4586,7 +4586,7 @@ Tilgjengelige kommandoer: </message> <message> <source>Unable to open file %1.</source> - <translation type="unfinished"/> + <translation>Kan ikke åpne filen %1.</translation> </message> <message> <source>Error while reading the database: @@ -4998,7 +4998,7 @@ Tilgjengelige kommandoer: </message> <message> <source>Own certificate</source> - <translation type="unfinished"/> + <translation>Egne sertifikat</translation> </message> <message> <source>Fingerprint:</source> @@ -5006,7 +5006,7 @@ Tilgjengelige kommandoer: </message> <message> <source>Certificate:</source> - <translation type="unfinished"/> + <translation>Sertifikat</translation> </message> <message> <source>Signer</source> @@ -5030,7 +5030,7 @@ Tilgjengelige kommandoer: </message> <message> <source>Imported certificates</source> - <translation>Importerte sertikikat</translation> + <translation>Importerte sertifikater</translation> </message> <message> <source>Trust</source> 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 @@ <message> <source>%1 has requested access to passwords for the following item(s). Please select whether you want to allow access.</source> - <translation>%1 vraagt toegang tot jouw wachtwoorden voor het volgende. + <translation>%1 vraagt toegang tot jouw wachtwoorden voor de volgende item(s). Geef aan of je toegang wilt verlenen of niet.</translation> </message> </context> @@ -611,15 +611,15 @@ Selecteer de database voor het opslaan van de inloggegevens.</translation> </message> <message> <source>Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1</source> - <translation type="unfinished"/> + <translation>Vanwege de Snap sandboxing, moet je een script uitvoeren waarmee browser integratie mogelijk wordt. <br /> Je kunt dit script vinden op %1</translation> </message> <message> <source>Please see special instructions for browser extension use below</source> - <translation type="unfinished"/> + <translation>Raadpleeg onderstaand speciale instructies voor gebruik van browserextensie </translation> </message> <message> <source>KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3</source> - <translation type="unfinished"/> + <translation>KeePassXC-Browser is vereist om de integratie van de browser te laten werken. <br /> download het voor %1 en %2. %3</translation> </message> </context> <context> @@ -696,19 +696,23 @@ Moved %2 keys to custom data.</source> </message> <message> <source>KeePassXC: Create a new group</source> - <translation type="unfinished"/> + <translation>KeePassXC: Een nieuwe groep maken</translation> </message> <message> <source>A request for creating a new group "%1" has been received. Do you want to create this group? </source> - <translation type="unfinished"/> + <translation>Een aanvraag voor het maken van een nieuwe groep '%1' werd ontvangen. +Wil je deze groep maken? +</translation> </message> <message> <source>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?</source> - <translation type="unfinished"/> + <translation>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?</translation> </message> </context> <context> @@ -872,7 +876,7 @@ Would you like to migrate your existing settings now?</source> </message> <message> <source>Key not transformed. This is a bug, please report it to the developers!</source> - <translation type="unfinished"/> + <translation>Toets niet getransformeerd. Dit is een bug, rapporteer deze alstublieft aan de ontwikkelaars!</translation> </message> </context> <context> @@ -1069,7 +1073,7 @@ Hierdoor werkt de verbinding met de browser plugin mogelijk niet meer.</translat <message> <source>Do you really want forget all site-specific settings on every entry? Permissions to access entries will be revoked.</source> - <translation>Wilt u echt alle site-specifieke instellingen bij items vergeten? Machtigingen voor toegang zullen worden ingetrokken.</translation> + <translation>Wil je echt alle site-specifieke instellingen bij items vergeten? Machtigingen voor toegang zullen worden ingetrokken.</translation> </message> <message> <source>Removing stored permissions…</source> @@ -1339,7 +1343,7 @@ Als je dit aantal aanhoudt is het mogelijk heel gemakkelijk om de database te kr </message> <message> <source>You must add at least one encryption key to secure your database!</source> - <translation>Je moet minstens één coderingssleutel aan uw database toevoegen om deze te beveiligen!</translation> + <translation>Je moet minstens één coderingssleutel aan de database toevoegen om deze te beveiligen!</translation> </message> <message> <source>No password set</source> @@ -1527,7 +1531,7 @@ Wil je de wijzigingen samenvoegen?</translation> </message> <message numerus="yes"> <source>Do you really want to delete %n entry(s) for good?</source> - <translation><numerusform>Wilt u echt %n item(s) voorgoed verwijderen?</numerusform><numerusform>Wilt u echt %n item(s) voorgoed verwijderen?</numerusform></translation> + <translation><numerusform>Wilt u echt %n item(s) voorgoed verwijderen?</numerusform><numerusform>Wil je echt %n item(s) voorgoed verwijderen?</numerusform></translation> </message> <message numerus="yes"> <source>Delete entry(s)?</source> @@ -1605,7 +1609,7 @@ Veilig opslaan afschakelen en opnieuw proberen?</translation> </message> <message numerus="yes"> <source>Entry "%1" has %2 reference(s). Do you want to overwrite references with values, skip this entry, or delete anyway?</source> - <translation><numerusform>Vermelding "%1" heeft %2 reference(s). Wilt u verwijzingen vervangen door waarden, dit bericht overslaan of verwijderen toch?</numerusform><numerusform>Item "%1" heeft %2 referentie(s). Wilt u verwijzingen vervangen door waarden, dit bericht overslaan of toch verwijderen ?</numerusform></translation> + <translation><numerusform>Vermelding "%1" heeft %2 reference(s). Wilt u verwijzingen vervangen door waarden, dit bericht overslaan of verwijderen toch?</numerusform><numerusform>Item "%1" heeft %2 referentie(s). Wil je de verwijzingen vervangen door waarden, dit bericht overslaan, of toch verwijderen ?</numerusform></translation> </message> <message> <source>Delete group</source> @@ -1617,7 +1621,7 @@ Veilig opslaan afschakelen en opnieuw proberen?</translation> </message> <message> <source>Do you really want to move the group "%1" to the recycle bin?</source> - <translation>Wilt u echt de groep '%1' naar de prullenbak verplaatsen?</translation> + <translation>Wil je echt de groep '%1' naar de prullenbak verplaatsen?</translation> </message> <message> <source>Successfully merged the database files.</source> @@ -1629,7 +1633,7 @@ Veilig opslaan afschakelen en opnieuw proberen?</translation> </message> <message> <source>Shared group...</source> - <translation type="unfinished"/> + <translation>Gedeelde groep...</translation> </message> </context> <context> @@ -2034,7 +2038,7 @@ Veilig opslaan afschakelen en opnieuw proberen?</translation> </message> <message> <source>Your KeePassXC version does not support sharing your container type. Please use %1.</source> - <translation>Uw KeePassXC-versie biedt geen ondersteuning voor het delen van uw Containertype. Gebruik %1.</translation> + <translation>Deze KeePassXC-versie biedt geen ondersteuning voor het delen van jouw container type. Gebruik %1.</translation> </message> <message> <source>Database sharing is disabled</source> @@ -2074,15 +2078,15 @@ Veilig opslaan afschakelen en opnieuw proberen?</translation> </message> <message> <source>The export container %1 is already referenced.</source> - <translation type="unfinished"/> + <translation>Er wordt al verwezen naar export container %1.</translation> </message> <message> <source>The import container %1 is already imported.</source> - <translation type="unfinished"/> + <translation>Import container %1 is al geïmporteerd.</translation> </message> <message> <source>The container %1 imported and export by different groups.</source> - <translation type="unfinished"/> + <translation>De container %1 is geïmporteerd en geëxporteerd door verschillende groepen.</translation> </message> </context> <context> @@ -3151,19 +3155,19 @@ Lijn %2, kolom %3</translation> </message> <message> <source>Disabled share %1</source> - <translation type="unfinished"/> + <translation>Delen uitgeschakeld %1</translation> </message> <message> <source>Import from share %1</source> - <translation type="unfinished"/> + <translation>Geïmporteerd van %1</translation> </message> <message> <source>Export to share %1</source> - <translation type="unfinished"/> + <translation>Ge-exporteerd naar %1</translation> </message> <message> <source>Synchronize with share %1</source> - <translation type="unfinished"/> + <translation>Synchroniseren met %1</translation> </message> </context> <context> @@ -3423,7 +3427,7 @@ Bericht: %2</translation> </message> <message> <source>Please touch the button on your YubiKey!</source> - <translation>Druk de knop op uw YubiKey!</translation> + <translation>Druk op de knop van je YubiKey!</translation> </message> <message> <source>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 <message> <source>NOTE: You are using a pre-release version of KeePassXC! Expect some bugs and minor issues, this version is not meant for production use.</source> - <translation>Opmerking: U gebruikt een pre-release versie van KeePassXC! + <translation>Opmerking: Je gebruikt een pre-release versie van KeePassXC! Verwacht een aantal bugs en kleine problemen, deze versie is niet bedoeld voor productiedoeleinden.</translation> </message> <message> @@ -3567,7 +3571,7 @@ Verwacht een aantal bugs en kleine problemen, deze versie is niet bedoeld voor p </message> <message> <source>You can always check for updates manually from the application menu.</source> - <translation>U kunt altijd handmatig controleren op updates vanuit het programmamenu.</translation> + <translation>Je kunt altijd handmatig controleren of er updates zijn vanuit het programmamenu.</translation> </message> </context> <context> @@ -4851,7 +4855,7 @@ Beschikbare opdrachten: </message> <message> <source>Cannot create new group</source> - <translation type="unfinished"/> + <translation>Kon nieuwe groep niet maken</translation> </message> </context> <context> @@ -5123,11 +5127,11 @@ Beschikbare opdrachten: </message> <message> <source>The exported certificate is not the same as the one in use. Do you want to export the current certificate?</source> - <translation>Het geëxporteerde certificaat is niet hetzelfde als die in gebruik is. Wilt u het huidige certificaat exporteren?</translation> + <translation>Het geëxporteerde certificaat is niet hetzelfde als die in gebruik is. Wil je het huidige certificaat exporteren?</translation> </message> <message> <source>Signer:</source> - <translation type="unfinished"/> + <translation>Ondertekenaar:</translation> </message> </context> <context> @@ -5246,31 +5250,31 @@ Beschikbare opdrachten: </message> <message> <source>Do you want to trust %1 with the fingerprint of %2 from %3?</source> - <translation>Wilt u %1 met de vingerafdruk van %2 vanaf %3 vertrouwen? {1 ?} {2 ?} </translation> + <translation>Wil je %1 met de vingerafdruk van %2 vanaf %3 vertrouwen? {1 ?} {2 ?} </translation> </message> <message> <source>Multiple import source path to %1 in %2</source> - <translation type="unfinished"/> + <translation>Meerdere import bronpaden naar %1 in %2</translation> </message> <message> <source>Conflicting export target path %1 in %2</source> - <translation type="unfinished"/> + <translation>Conflicterende exporteerdoelpad %1 in %2</translation> </message> <message> <source>Could not embed signature: Could not open file to write (%1)</source> - <translation type="unfinished"/> + <translation>Kon handtekening niet insluiten: Kan bestand niet openen om naar te schrijven (%1)</translation> </message> <message> <source>Could not embed signature: Could not write file (%1)</source> - <translation type="unfinished"/> + <translation>Kon handtekening niet insluiten: Kan niet schrijven naar bestand (%1)</translation> </message> <message> <source>Could not embed database: Could not open file to write (%1)</source> - <translation type="unfinished"/> + <translation>Kon database niet insluiten: Kan bestand niet openen om naar te schrijven (%1) </translation> </message> <message> <source>Could not embed database: Could not write file (%1)</source> - <translation type="unfinished"/> + <translation>Kon database niet insluiten: Kan niet schrijven naar bestand (%1)</translation> </message> </context> <context> @@ -5301,7 +5305,7 @@ Beschikbare opdrachten: <message> <source>NOTE: These TOTP settings are custom and may not work with other authenticators.</source> <comment>TOTP QR code dialog warning</comment> - <translation>Let op: deze TOTP-instellingen zijn op maat en werken mogelijk niet met andere authenticators.</translation> + <translation>Let op: deze TOTP-instellingen zijn applicatie specifiek en werken mogelijk niet met andere authenticators.</translation> </message> <message> <source>There was an error creating the QR code.</source> 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.</tran </message> <message> <source>Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1</source> - <translation type="unfinished"/> + <translation>Ze względu na sandboxing Snap należy uruchomić skrypt, aby umożliwić integrację przeglądarki.<br />Możesz uzyskać ten skrypt z %1</translation> </message> <message> <source>Please see special instructions for browser extension use below</source> - <translation type="unfinished"/> + <translation>Zobacz poniżej specjalne instrukcje dotyczące używania rozszerzenia przeglądarki</translation> </message> <message> <source>KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3</source> - <translation type="unfinished"/> + <translation>KeePassXC-Browser jest potrzebny do integracji przeglądarki. <br />Pobierz go dla %1 i %2. %3</translation> </message> </context> <context> @@ -696,19 +696,23 @@ Przeniesiono %2 klucze do niestandardowych danych.</translation> </message> <message> <source>KeePassXC: Create a new group</source> - <translation type="unfinished"/> + <translation>KeePassXC: Utwórz nową grupę</translation> </message> <message> <source>A request for creating a new group "%1" has been received. Do you want to create this group? </source> - <translation type="unfinished"/> + <translation>Otrzymano żądanie utworzenia nowej grupy "%1". +Czy chcesz stworzyć tę grupę? +</translation> </message> <message> <source>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?</source> - <translation type="unfinished"/> + <translation>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?</translation> </message> </context> <context> @@ -872,7 +876,7 @@ Would you like to migrate your existing settings now?</source> </message> <message> <source>Key not transformed. This is a bug, please report it to the developers!</source> - <translation type="unfinished"/> + <translation>Klucz nie został przekształcony. To jest błąd, zgłoś go deweloperom!</translation> </message> </context> <context> @@ -1631,7 +1635,7 @@ Wyłączyć bezpieczne zapisywanie i spróbować ponownie?</translation> </message> <message> <source>Shared group...</source> - <translation type="unfinished"/> + <translation>Grupa współdzielona...</translation> </message> </context> <context> @@ -2076,15 +2080,15 @@ Wyłączyć bezpieczne zapisywanie i spróbować ponownie?</translation> </message> <message> <source>The export container %1 is already referenced.</source> - <translation type="unfinished"/> + <translation>Odwołanie do kontenera eksportu %1 już istnieje.</translation> </message> <message> <source>The import container %1 is already imported.</source> - <translation type="unfinished"/> + <translation>Kontener importu %1 jest już zaimportowany.</translation> </message> <message> <source>The container %1 imported and export by different groups.</source> - <translation type="unfinished"/> + <translation>Kontener %1 importowany i eksportowany przez różne grupy.</translation> </message> </context> <context> @@ -3157,19 +3161,19 @@ Wiersz %2, kolumna %3</translation> </message> <message> <source>Disabled share %1</source> - <translation type="unfinished"/> + <translation>Wyłączony udział %1</translation> </message> <message> <source>Import from share %1</source> - <translation type="unfinished"/> + <translation>Importuj z udziału %1</translation> </message> <message> <source>Export to share %1</source> - <translation type="unfinished"/> + <translation>Eksportuj do udziału %1</translation> </message> <message> <source>Synchronize with share %1</source> - <translation type="unfinished"/> + <translation>Synchronizuj z udziałem %1</translation> </message> </context> <context> @@ -4858,7 +4862,7 @@ Dostępne polecenia: </message> <message> <source>Cannot create new group</source> - <translation type="unfinished"/> + <translation>Nie można utworzyć nowej grupy</translation> </message> </context> <context> @@ -5134,7 +5138,7 @@ Dostępne polecenia: </message> <message> <source>Signer:</source> - <translation type="unfinished"/> + <translation>Podpisujący:</translation> </message> </context> <context> @@ -5257,27 +5261,27 @@ Dostępne polecenia: </message> <message> <source>Multiple import source path to %1 in %2</source> - <translation type="unfinished"/> + <translation>Wiele ścieżek źródłowych importu do %1 w %2</translation> </message> <message> <source>Conflicting export target path %1 in %2</source> - <translation type="unfinished"/> + <translation>Sprzeczna ścieżka docelowa eksportu %1 w %2</translation> </message> <message> <source>Could not embed signature: Could not open file to write (%1)</source> - <translation type="unfinished"/> + <translation>Nie można osadzić podpisu: Nie można otworzyć pliku do zapisu (%1)</translation> </message> <message> <source>Could not embed signature: Could not write file (%1)</source> - <translation type="unfinished"/> + <translation>Nie można osadzić podpisu: Nie można zapisać pliku (%1)</translation> </message> <message> <source>Could not embed database: Could not open file to write (%1)</source> - <translation type="unfinished"/> + <translation>Nie można osadzić bazy danych: Nie można otworzyć pliku do zapisu (%1)</translation> </message> <message> <source>Could not embed database: Could not write file (%1)</source> - <translation type="unfinished"/> + <translation>Nie można osadzić bazy danych: nie można zapisać pliku (%1)</translation> </message> </context> <context> 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.</translation> </message> <message> <source>Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1</source> - <translation type="unfinished"/> + <translation>Devido a 'Snap sandboxing', tem que executar um script para ativar a integração com o navegador.<br />Pode obter este script em %1.</translation> </message> <message> <source>Please see special instructions for browser extension use below</source> - <translation type="unfinished"/> + <translation>Por favor consulte as instruções para a utilização da extensão abaixo</translation> </message> <message> <source>KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3</source> - <translation type="unfinished"/> + <translation>Necessita do KeePassXC-Browser para que a integração funcione corretamente.<br />Pode descarregar para %1 e para %2. %3</translation> </message> </context> <context> @@ -696,19 +696,23 @@ Moved %2 keys to custom data.</source> </message> <message> <source>KeePassXC: Create a new group</source> - <translation type="unfinished"/> + <translation>KeePassXC: criar um novo grupo</translation> </message> <message> <source>A request for creating a new group "%1" has been received. Do you want to create this group? </source> - <translation type="unfinished"/> + <translation>Foi recebido um pedido para a criação do grupo "%1". +Quer criar este grupo? +</translation> </message> <message> <source>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?</source> - <translation type="unfinished"/> + <translation>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?</translation> </message> </context> <context> @@ -872,7 +876,7 @@ Would you like to migrate your existing settings now?</source> </message> <message> <source>Key not transformed. This is a bug, please report it to the developers!</source> - <translation type="unfinished"/> + <translation>Chave não transformada. Isto é um erro e deve ser reportado aos programadores!</translation> </message> </context> <context> @@ -1631,7 +1635,7 @@ Desativar salvaguardas e tentar novamente?</translation> </message> <message> <source>Shared group...</source> - <translation type="unfinished"/> + <translation>Grupo partilhado...</translation> </message> </context> <context> @@ -2077,11 +2081,11 @@ Por favor utilize %1.</translation> </message> <message> <source>The export container %1 is already referenced.</source> - <translation type="unfinished"/> + <translation>O contentor de exportação %1 já está referenciado.</translation> </message> <message> <source>The import container %1 is already imported.</source> - <translation type="unfinished"/> + <translation>O contentor de importação %1 já está referenciado.</translation> </message> <message> <source>The container %1 imported and export by different groups.</source> @@ -3156,19 +3160,19 @@ Linha %2, coluna %3</translation> </message> <message> <source>Disabled share %1</source> - <translation type="unfinished"/> + <translation>Desativar partilha %1</translation> </message> <message> <source>Import from share %1</source> - <translation type="unfinished"/> + <translation>Importar da partilha %1</translation> </message> <message> <source>Export to share %1</source> - <translation type="unfinished"/> + <translation>Exportar para a partilha %1</translation> </message> <message> <source>Synchronize with share %1</source> - <translation type="unfinished"/> + <translation>Sincronizar com a partilha %1</translation> </message> </context> <context> @@ -4858,7 +4862,7 @@ Comandos disponíveis: </message> <message> <source>Cannot create new group</source> - <translation type="unfinished"/> + <translation>Não foi possível criar o novo grupo</translation> </message> </context> <context> @@ -5134,7 +5138,7 @@ Comandos disponíveis: </message> <message> <source>Signer:</source> - <translation type="unfinished"/> + <translation>Signatário:</translation> </message> </context> <context> @@ -5257,27 +5261,27 @@ Comandos disponíveis: </message> <message> <source>Multiple import source path to %1 in %2</source> - <translation type="unfinished"/> + <translation>Diversos caminhos de importação para %1 em %2</translation> </message> <message> <source>Conflicting export target path %1 in %2</source> - <translation type="unfinished"/> + <translation>Conflito no caminho de exportação para %1 em %2</translation> </message> <message> <source>Could not embed signature: Could not open file to write (%1)</source> - <translation type="unfinished"/> + <translation>Assinatura não incorporada. Não foi possível abrir o ficheiro para escrita (%1)</translation> </message> <message> <source>Could not embed signature: Could not write file (%1)</source> - <translation type="unfinished"/> + <translation>Assinatura não incorporada. Não foi possível escrever no ficheiro (%1)</translation> </message> <message> <source>Could not embed database: Could not open file to write (%1)</source> - <translation type="unfinished"/> + <translation>Base de dados não incorporada. Não foi possível abrir o ficheiro para escrita (%1)</translation> </message> <message> <source>Could not embed database: Could not write file (%1)</source> - <translation type="unfinished"/> + <translation>Base de dados não incorporada. Não foi possível escrever no ficheiro (%1)</translation> </message> </context> <context> 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.</trans </message> <message> <source>Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1</source> - <translation type="unfinished"/> + <translation>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</translation> </message> <message> <source>Please see special instructions for browser extension use below</source> - <translation type="unfinished"/> + <translation>Por favor, veja as instruções especiais para o uso da extensão do navegador abaixo</translation> </message> <message> <source>KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3</source> - <translation type="unfinished"/> + <translation>O KeePassXC-Browser é necessário para que a integração do navegador funcione. <br />Faça o download para %1 e %2. %3</translation> </message> </context> <context> @@ -695,19 +695,23 @@ Movido %2 chaves para dados personalizados.</translation> </message> <message> <source>KeePassXC: Create a new group</source> - <translation type="unfinished"/> + <translation>KeePassXC: Crie um novo grupo</translation> </message> <message> <source>A request for creating a new group "%1" has been received. Do you want to create this group? </source> - <translation type="unfinished"/> + <translation>Um pedido para criar um novo grupo "%1" foi recebido. +Você quer criar este grupo? +</translation> </message> <message> <source>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?</source> - <translation type="unfinished"/> + <translation>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?</translation> </message> </context> <context> @@ -813,7 +817,7 @@ Would you like to migrate your existing settings now?</source> </message> <message numerus="yes"> <source>[%n more message(s) skipped]</source> - <translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation> + <translation><numerusform>[%n mais mensagem(ns) ignoradas]</numerusform><numerusform>[%n mais mensagem(ns) ignoradas]</numerusform></translation> </message> <message> <source>CSV import: writer has errors: @@ -871,7 +875,7 @@ Would you like to migrate your existing settings now?</source> </message> <message> <source>Key not transformed. This is a bug, please report it to the developers!</source> - <translation type="unfinished"/> + <translation>Chave não transformada. Este é um bug, por favor denuncie para os desenvolvedores!</translation> </message> </context> <context> @@ -999,11 +1003,11 @@ Por favor, considere-se gerar um novo arquivo de chave.</translation> </message> <message> <source>Forg&et all site-specific settings on entries</source> - <translation type="unfinished"/> + <translation>Esq&uecer todas as configurações específicas do site nas entradas</translation> </message> <message> <source>Move KeePassHTTP attributes to KeePassXC-Browser &custom data</source> - <translation type="unfinished"/> + <translation>Mover os atributos do KeePassHTTP para o KeePassXC-Browser &dados personalizados</translation> </message> <message> <source>Stored keys</source> @@ -1068,7 +1072,8 @@ Isso pode impedir a conexão com o plugin do navegador.</translation> <message> <source>Do you really want forget all site-specific settings on every entry? Permissions to access entries will be revoked.</source> - <translation type="unfinished"/> + <translation>Você realmente quer esquecer todas as configurações específicas do site em cada entrada? +Permissões para acessar entradas serão revogadas.</translation> </message> <message> <source>Removing stored permissions…</source> @@ -1084,7 +1089,7 @@ Permissions to access entries will be revoked.</source> </message> <message numerus="yes"> <source>Successfully removed permissions from %n entry(s).</source> - <translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation> + <translation><numerusform>Permissões removidas com sucesso de %n entrada(s).</numerusform><numerusform>Permissões removidas com sucesso de %n entrada(s).</numerusform></translation> </message> <message> <source>KeePassXC: No entry with permissions found!</source> @@ -1101,7 +1106,8 @@ Permissions to access entries will be revoked.</source> <message> <source>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.</source> - <translation type="unfinished"/> + <translation>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.</translation> </message> </context> <context> @@ -1160,7 +1166,7 @@ This is necessary to maintain compatibility with the browser plugin.</source> </message> <message> <source>Higher values offer more protection, but opening the database will take longer.</source> - <translation type="unfinished"/> + <translation>Valores mais altos oferecem mais proteção, mas a abertura do banco de dados levará mais tempo.</translation> </message> <message> <source>Database format:</source> @@ -1313,7 +1319,7 @@ Se você manter este número, seu banco de dados pode ser facilmente crackeado!< </message> <message> <source>Last Signer</source> - <translation type="unfinished"/> + <translation>Último Signatário</translation> </message> <message> <source>Certificates</source> @@ -1566,7 +1572,8 @@ Salvar alterações?</translation> <message> <source>Could not open the new database file while attempting to autoreload. Error: %1</source> - <translation type="unfinished"/> + <translation>Não foi possível abrir o novo arquivo de banco de dados ao tentar executar o carregamento automático. +Erro: %1</translation> </message> <message> <source>Disable safe saves?</source> @@ -1581,7 +1588,8 @@ Deseja desabilitar salvamento seguro e tentar novamente?</translation> <message> <source>Writing the database failed. %1</source> - <translation type="unfinished"/> + <translation>Escrevendo o banco de dados falhou. +%1</translation> </message> <message> <source>Passwords</source> @@ -1625,7 +1633,7 @@ Deseja desabilitar salvamento seguro e tentar novamente?</translation> </message> <message> <source>Shared group...</source> - <translation type="unfinished"/> + <translation>Grupo compartilhado...</translation> </message> </context> <context> @@ -2168,7 +2176,7 @@ Deseja desabilitar salvamento seguro e tentar novamente?</translation> </message> <message numerus="yes"> <source>Successfully loaded %1 of %n icon(s)</source> - <translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation> + <translation><numerusform>Carregado com sucesso %1 de %n ícone(s)</numerusform><numerusform>Carregado com sucesso %1 de %n ícone(s)</numerusform></translation> </message> <message> <source>No icons were loaded</source> @@ -3124,7 +3132,7 @@ Linha %2, coluna %3</translation> </message> <message> <source>unable to seek to content position</source> - <translation type="unfinished"/> + <translation>incapaz de buscar a posição de conteúdo</translation> </message> </context> <context> @@ -3147,19 +3155,19 @@ Linha %2, coluna %3</translation> </message> <message> <source>Disabled share %1</source> - <translation type="unfinished"/> + <translation>Desabilitar compartilhamento %1</translation> </message> <message> <source>Import from share %1</source> - <translation type="unfinished"/> + <translation>Importar do compartilhamento %1</translation> </message> <message> <source>Export to share %1</source> - <translation type="unfinished"/> + <translation>Exportar para compartilhamento %1</translation> </message> <message> <source>Synchronize with share %1</source> - <translation type="unfinished"/> + <translation>Sincronizar com compartilhamento %1</translation> </message> </context> <context> @@ -3178,7 +3186,7 @@ Linha %2, coluna %3</translation> </message> <message> <source>Key Component set, click to change or remove</source> - <translation type="unfinished"/> + <translation>Componente Chave definido, clique para alterar ou remover</translation> </message> <message> <source>Add %1</source> @@ -3615,11 +3623,11 @@ Espere alguns bugs e problemas menores, esta versão não é para uso em produç </message> <message> <source>Changed deleted objects</source> - <translation type="unfinished"/> + <translation>Objetos excluídos alterados</translation> </message> <message> <source>Adding missing icon %1</source> - <translation type="unfinished"/> + <translation>Adicionando ícone ausente %1</translation> </message> </context> <context> @@ -3805,7 +3813,7 @@ Espere alguns bugs e problemas menores, esta versão não é para uso em produç </message> <message> <source><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></source> - <translation type="unfinished"/> + <translation><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></translation> </message> <message> <source>Passwords do not match.</source> @@ -4447,7 +4455,7 @@ Comandos disponíveis: </message> <message> <source>Entry's password copied to the clipboard!</source> - <translation type="unfinished"/> + <translation>Entrada da senha copiada para a área de transferência!</translation> </message> <message numerus="yes"> <source>Clearing the clipboard in %1 second(s)...</source> @@ -4646,11 +4654,11 @@ Comandos disponíveis: </message> <message> <source>Exclude similar looking characters</source> - <translation type="unfinished"/> + <translation>Excluir caracteres parecidos</translation> </message> <message> <source>Include characters from every selected group</source> - <translation type="unfinished"/> + <translation>Incluir caracteres de cada grupo selecionado</translation> </message> <message> <source>Recursively list the elements of the group.</source> @@ -4741,7 +4749,7 @@ Comandos disponíveis: </message> <message> <source>Message encryption failed.</source> - <translation type="unfinished"/> + <translation>Criptografia de mensagens falhou.</translation> </message> <message> <source>No groups found</source> @@ -4753,7 +4761,7 @@ Comandos disponíveis: </message> <message> <source>File %1 already exists.</source> - <translation type="unfinished"/> + <translation>Arquivo %1 já existe.</translation> </message> <message> <source>Loading the key file failed</source> @@ -4841,7 +4849,7 @@ Comandos disponíveis: </message> <message> <source>Cannot create new group</source> - <translation type="unfinished"/> + <translation>Não é possível criar um novo grupo</translation> </message> </context> <context> @@ -4906,11 +4914,11 @@ Comandos disponíveis: </message> <message> <source>Restricted lifetime is not supported by the agent (check options).</source> - <translation type="unfinished"/> + <translation>Vida útil limitada não é suportado pelo agente (verificar opções).</translation> </message> <message> <source>A confirmation request is not supported by the agent (check options).</source> - <translation type="unfinished"/> + <translation>Uma solicitação de confirmação não é suportado pelo agente (verificar opções).</translation> </message> </context> <context> @@ -4921,7 +4929,7 @@ Comandos disponíveis: </message> <message> <source>Search terms are as follows: [modifiers][field:]["]term["]</source> - <translation type="unfinished"/> + <translation>Termos de pesquisa são as seguintes: [modifiers][field:]["]term["]</translation> </message> <message> <source>Every search term must match (ie, logical AND)</source> @@ -5024,7 +5032,7 @@ Comandos disponíveis: </message> <message> <source>Signer</source> - <translation type="unfinished"/> + <translation>Signatário</translation> </message> <message> <source>Key:</source> @@ -5093,11 +5101,11 @@ Comandos disponíveis: <message> <source>key.share</source> <comment>Filetype for KeeShare key</comment> - <translation type="unfinished"/> + <translation>key.share</translation> </message> <message> <source>KeeShare key file</source> - <translation type="unfinished"/> + <translation>Arquivo chave KeeShare</translation> </message> <message> <source>All files</source> @@ -5117,7 +5125,7 @@ Comandos disponíveis: </message> <message> <source>Signer:</source> - <translation type="unfinished"/> + <translation>Signatário:</translation> </message> </context> <context> @@ -5152,11 +5160,11 @@ Comandos disponíveis: </message> <message> <source>Import from %1 failed (%2)</source> - <translation type="unfinished"/> + <translation>Importação de %1 falhou (%2)</translation> </message> <message> <source>Import from %1 successful (%2)</source> - <translation type="unfinished"/> + <translation>Importado de %1 com sucesso (%2)</translation> </message> <message> <source>Imported from %1</source> @@ -5444,11 +5452,11 @@ Comandos disponíveis: </message> <message> <source>YubiKey Challenge-Response</source> - <translation type="unfinished"/> + <translation>YubiKey Desafio-Resposta</translation> </message> <message> <source><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></source> - <translation type="unfinished"/> + <translation><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></translation> </message> <message> <source>No YubiKey detected, please ensure it's plugged in.</source> 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 @@ </message> <message> <source>Use OpenSSH for Windows instead of Pageant</source> - <translation>Utilizar OpeSSH for Windows em vez de Pageant</translation> + <translation>Utilizar OpenSSH for Windows em vez de Pageant</translation> </message> </context> <context> @@ -120,7 +120,7 @@ </message> <message> <source>Load previous databases on startup</source> - <translation>Ao iniciar, carregar as últimas base de dados utilizadas</translation> + <translation>Ao iniciar, carregar últimas base de dados utilizadas</translation> </message> <message> <source>Minimize window at application startup</source> @@ -512,12 +512,12 @@ Selecione a base de dados correta para guardar as credenciais.</translation> <message> <source>Sort &matching credentials by title</source> <extracomment>Credentials mean login data requested via browser extension</extracomment> - <translation>Ordenar credenciais coi&ncidentes por título</translation> + <translation>Ordenar por título as credenciais coi&ncidentes</translation> </message> <message> <source>Sort matching credentials by &username</source> <extracomment>Credentials mean login data requested via browser extension</extracomment> - <translation>Ordenar credenciais coincidentes por nome de &utilizador</translation> + <translation>Ordenar por nome de &utilizador as credenciais coincidentes</translation> </message> <message> <source>Advanced</source> @@ -611,15 +611,15 @@ Selecione a base de dados correta para guardar as credenciais.</translation> </message> <message> <source>Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1</source> - <translation type="unfinished"/> + <translation>Devido a 'Snap sandboxing', tem que executar um script para ativar a integração com o navegador.<br />Pode obter este script em %1.</translation> </message> <message> <source>Please see special instructions for browser extension use below</source> - <translation type="unfinished"/> + <translation>Por favor consulte as instruções para a utilização da extensão abaixo</translation> </message> <message> <source>KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3</source> - <translation type="unfinished"/> + <translation>Necessita de KeePassXC-Browser para que a integração funcione corretamente.<br />Pode descarregar para %1 e %2. %3</translation> </message> </context> <context> @@ -696,19 +696,23 @@ Moved %2 keys to custom data.</source> </message> <message> <source>KeePassXC: Create a new group</source> - <translation type="unfinished"/> + <translation>KeePassXC: Criar um novo grupo</translation> </message> <message> <source>A request for creating a new group "%1" has been received. Do you want to create this group? </source> - <translation type="unfinished"/> + <translation>Foi recebido um pedido para a criação do grupo "%1". +Deseja criar este grupo? +</translation> </message> <message> <source>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?</source> - <translation type="unfinished"/> + <translation>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?</translation> </message> </context> <context> @@ -872,7 +876,7 @@ Would you like to migrate your existing settings now?</source> </message> <message> <source>Key not transformed. This is a bug, please report it to the developers!</source> - <translation type="unfinished"/> + <translation>Chave não transformada. Isto é um erro e deve ser reportado aos programadores!</translation> </message> </context> <context> @@ -1631,7 +1635,7 @@ Desativar salvaguardas e tentar novamente?</translation> </message> <message> <source>Shared group...</source> - <translation type="unfinished"/> + <translation>Grupo partilhado...</translation> </message> </context> <context> @@ -2077,15 +2081,15 @@ Por favor utilize %1.</translation> </message> <message> <source>The export container %1 is already referenced.</source> - <translation type="unfinished"/> + <translation>O contentor de exportação %1 já está referenciado.</translation> </message> <message> <source>The import container %1 is already imported.</source> - <translation type="unfinished"/> + <translation>O contentor de importação %1 já está referenciado.</translation> </message> <message> <source>The container %1 imported and export by different groups.</source> - <translation type="unfinished"/> + <translation>Erro ao exportar. A partilha %1 está a ser importada por outro grupo.</translation> </message> </context> <context> @@ -2869,7 +2873,7 @@ Esta é uma migração unidirecional. Não será possível abrir a base de dados </message> <message> <source>Invalid group icon number</source> - <translation>Número inválido de ícone de grupo</translation> + <translation>Número inválido no ícone de grupo</translation> </message> <message> <source>Invalid EnableAutoType value</source> @@ -3017,7 +3021,7 @@ Linha %2, coluna %3</translation> </message> <message> <source>Invalid transform seed size</source> - <translation>Tamanho inválido da semente de transformação</translation> + <translation>Tamanho inválido na semente de transformação</translation> </message> <message> <source>Invalid number of transform rounds</source> @@ -3156,19 +3160,19 @@ Linha %2, coluna %3</translation> </message> <message> <source>Disabled share %1</source> - <translation type="unfinished"/> + <translation>Desativar partilha %1</translation> </message> <message> <source>Import from share %1</source> - <translation type="unfinished"/> + <translation>Importar da partilha %1</translation> </message> <message> <source>Export to share %1</source> - <translation type="unfinished"/> + <translation>Exportar para a partilha %1</translation> </message> <message> <source>Synchronize with share %1</source> - <translation type="unfinished"/> + <translation>Sincronizar com a partilha %1</translation> </message> </context> <context> @@ -3639,7 +3643,7 @@ Pode encontrar erros graves e esta versão não deve ser utilizada em ambientes <name>NewDatabaseWizard</name> <message> <source>Create a new KeePassXC database...</source> - <translation>A criar uma nova base de dados do KeePassXC...</translation> + <translation>Criar uma nova base de dados do KeePassXC...</translation> </message> <message> <source>Root</source> @@ -3659,7 +3663,7 @@ Pode encontrar erros graves e esta versão não deve ser utilizada em ambientes </message> <message> <source>Here you can adjust the database encryption settings. Don't worry, you can change them later in the database settings.</source> - <translation>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.</translation> + <translation>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.</translation> </message> <message> <source>Advanced Settings</source> @@ -3678,7 +3682,7 @@ Pode encontrar erros graves e esta versão não deve ser utilizada em ambientes </message> <message> <source>Here you can adjust the database encryption settings. Don't worry, you can change them later in the database settings.</source> - <translation>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.</translation> + <translation>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.</translation> </message> </context> <context> @@ -4858,7 +4862,7 @@ Comandos disponíveis: </message> <message> <source>Cannot create new group</source> - <translation type="unfinished"/> + <translation>Não foi possível criar o novo grupo</translation> </message> </context> <context> @@ -5110,7 +5114,7 @@ Comandos disponíveis: <message> <source>key.share</source> <comment>Filetype for KeeShare key</comment> - <translation>partilha da chave</translation> + <translation>chave.partilha</translation> </message> <message> <source>KeeShare key file</source> @@ -5134,7 +5138,7 @@ Comandos disponíveis: </message> <message> <source>Signer:</source> - <translation type="unfinished"/> + <translation>Signatário:</translation> </message> </context> <context> @@ -5233,7 +5237,7 @@ Comandos disponíveis: </message> <message> <source>Could not write export container</source> - <translation>Não foi possível escrever contentor de exportação</translation> + <translation>Não foi possível escrever o contentor de exportação</translation> </message> <message> <source>Unexpected export error occurred</source> @@ -5257,27 +5261,27 @@ Comandos disponíveis: </message> <message> <source>Multiple import source path to %1 in %2</source> - <translation type="unfinished"/> + <translation>Diversos caminhos de importação para %1 em %2</translation> </message> <message> <source>Conflicting export target path %1 in %2</source> - <translation type="unfinished"/> + <translation>Conflito no caminho de exportação para %1 em %2</translation> </message> <message> <source>Could not embed signature: Could not open file to write (%1)</source> - <translation type="unfinished"/> + <translation>Assinatura não incorporada. Não foi possível abrir o ficheiro para escrita (%1)</translation> </message> <message> <source>Could not embed signature: Could not write file (%1)</source> - <translation type="unfinished"/> + <translation>Assinatura não incorporada. Não foi possível escrever no ficheiro (%1)</translation> </message> <message> <source>Could not embed database: Could not open file to write (%1)</source> - <translation type="unfinished"/> + <translation>Base de dados não incorporada. Não foi possível abrir o ficheiro para escrita (%1)</translation> </message> <message> <source>Could not embed database: Could not write file (%1)</source> - <translation type="unfinished"/> + <translation>Base de dados não incorporada. Não foi possível escrever no ficheiro (%1)</translation> </message> </context> <context> 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 @@ </message> <message> <source>Hide toolbar (icons)</source> - <translation>Скрыть панель инструментов (иконки)</translation> + <translation>Скрывать панель инструментов (значки)</translation> </message> <message> <source>Minimize instead of app exit</source> @@ -611,15 +611,15 @@ Please select the correct database for saving credentials.</source> </message> <message> <source>Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1</source> - <translation type="unfinished"/> + <translation>Из-за того, что Snap - это песочница, Вы должны запустить скрипт, чтобы разрешить браузерную интеграцию.<br />Вы можете получить этот скрипт с %1</translation> </message> <message> <source>Please see special instructions for browser extension use below</source> - <translation type="unfinished"/> + <translation>Пожалуйста, смотрите особые инструкции по использованию расширения браузера ниже</translation> </message> <message> <source>KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3</source> - <translation type="unfinished"/> + <translation>KeePassXC-Browser необходим для работы интеграции браузера. <br />Скачайте его для %1 и %2. %3</translation> </message> </context> <context> @@ -696,19 +696,23 @@ Moved %2 keys to custom data.</source> </message> <message> <source>KeePassXC: Create a new group</source> - <translation type="unfinished"/> + <translation>KeePassXC: Создать новую группу</translation> </message> <message> <source>A request for creating a new group "%1" has been received. Do you want to create this group? </source> - <translation type="unfinished"/> + <translation>Был получен запрос для создания новой группы "%1". +Вы хотите создать эту группу? +</translation> </message> <message> <source>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?</source> - <translation type="unfinished"/> + <translation>Нужно переместить Ваши настройки KeePassXC-Browser в настройки базы данных. +Это необходимо, чтобы поддерживать Ваши текущие соединения браузера. +Желаете ли Вы мигрировать Ваши существующие настройки сейчас?</translation> </message> </context> <context> @@ -871,7 +875,7 @@ Would you like to migrate your existing settings now?</source> </message> <message> <source>Key not transformed. This is a bug, please report it to the developers!</source> - <translation type="unfinished"/> + <translation>Ключ не преобразован. Это ошибка, пожалуйста, сообщите о нём разработчикам!</translation> </message> </context> <context> @@ -1629,7 +1633,7 @@ Disable safe saves and try again?</source> </message> <message> <source>Shared group...</source> - <translation type="unfinished"/> + <translation>Общая группа...</translation> </message> </context> <context> @@ -2074,15 +2078,15 @@ Disable safe saves and try again?</source> </message> <message> <source>The export container %1 is already referenced.</source> - <translation type="unfinished"/> + <translation>На контейнер экспорта %1 уже есть ссылка.</translation> </message> <message> <source>The import container %1 is already imported.</source> - <translation type="unfinished"/> + <translation>Контейнер импорта %1 уже импортирован.</translation> </message> <message> <source>The container %1 imported and export by different groups.</source> - <translation type="unfinished"/> + <translation>Контейнер %1 импортируется и экспортируется разными группами.</translation> </message> </context> <context> @@ -2160,7 +2164,7 @@ Disable safe saves and try again?</source> </message> <message> <source>Custom icon successfully downloaded</source> - <translation>Пользовательская иконка успешно загружена</translation> + <translation>Пользовательский значок успешно загружен</translation> </message> <message> <source>Hint: You can enable DuckDuckGo as a fallback under Tools>Settings>Security</source> @@ -2172,7 +2176,7 @@ Disable safe saves and try again?</source> </message> <message numerus="yes"> <source>Successfully loaded %1 of %n icon(s)</source> - <translation><numerusform>Успешно загружено %1 из %n иконки</numerusform><numerusform>Успешно загружено %1 из %n иконок</numerusform><numerusform>Успешно загружено %1 из %n иконок</numerusform><numerusform>Успешно загружено %1 из %n иконки(ок)</numerusform></translation> + <translation><numerusform>Успешно загружен %1 из %n значка</numerusform><numerusform>Успешно загружены %1 из %n значков</numerusform><numerusform>Успешно загружены %1 из %n значков</numerusform><numerusform>Успешно загружены %1 из %n значков</numerusform></translation> </message> <message> <source>No icons were loaded</source> @@ -2180,15 +2184,15 @@ Disable safe saves and try again?</source> </message> <message numerus="yes"> <source>%n icon(s) already exist in the database</source> - <translation><numerusform>%n иконка уже существует в базе данных</numerusform><numerusform>%n иконки уже существуют в базе данных</numerusform><numerusform>%n иконок уже существуют в базе данных</numerusform><numerusform>%n иконка(ок) уже существует(ют) в базе данных</numerusform></translation> + <translation><numerusform>%n значок уже существует в базе данных</numerusform><numerusform>%n значка уже существуют в базе данных</numerusform><numerusform>%n значков уже существуют в базе данных</numerusform><numerusform>%n значков уже существуют в базе данных</numerusform></translation> </message> <message numerus="yes"> <source>The following icon(s) failed:</source> - <translation><numerusform>Следующие иконки не удалось:</numerusform><numerusform>Следующие иконки не удалось:</numerusform><numerusform>Следующие иконки не удалось:</numerusform><numerusform>Следующие иконки не удалось:</numerusform></translation> + <translation><numerusform>Следующий значок потерпел неудачу:</numerusform><numerusform>Следующие значки потерпели неудачу:</numerusform><numerusform>Следующие значки потерпели неудачу:</numerusform><numerusform>Следующие значки потерпели неудачу:</numerusform></translation> </message> <message numerus="yes"> <source>This icon is used by %n entry(s), and will be replaced by the default icon. Are you sure you want to delete it?</source> - <translation><numerusform>Эта иконка используется %n записью и будет замещена иконкой по умолчанию. Вы уверены, что хотите удалить её?</numerusform><numerusform>Эта иконка используется %n записями и будет замещена иконкой по умолчанию. Вы уверены, что хотите удалить её?</numerusform><numerusform>Эта иконка используется %n записями и будет замещена иконкой по умолчанию. Вы уверены, что хотите удалить её?</numerusform><numerusform>Эта иконка используется %n записью(ями) и будет замещена иконкой по умолчанию. Вы уверены, что хотите удалить её?</numerusform></translation> + <translation><numerusform>Этот значок используется %n записью и будет замещён значком по умолчанию. Вы уверены, что хотите удалить его?</numerusform><numerusform>Этот значок используется %n записями и будет замещён значком по умолчанию. Вы уверены, что хотите удалить его?</numerusform><numerusform>Этот значок используется %n записями и будет замещён значком по умолчанию. Вы уверены, что хотите удалить его?</numerusform><numerusform>Этот значок используется %n записями и будет замещён значком по умолчанию. Вы уверены, что хотите удалить его?</numerusform></translation> </message> </context> <context> @@ -3154,19 +3158,19 @@ Line %2, column %3</source> </message> <message> <source>Disabled share %1</source> - <translation type="unfinished"/> + <translation>Отключённая часть %1</translation> </message> <message> <source>Import from share %1</source> - <translation type="unfinished"/> + <translation>Импортировать из части %1</translation> </message> <message> <source>Export to share %1</source> - <translation type="unfinished"/> + <translation>Экспортировать в часть %1</translation> </message> <message> <source>Synchronize with share %1</source> - <translation type="unfinished"/> + <translation>Синхронизировать с частью %1</translation> </message> </context> <context> @@ -3629,7 +3633,7 @@ Expect some bugs and minor issues, this version is not meant for production use. </message> <message> <source>Adding missing icon %1</source> - <translation>Добавление отсутствующей иконки %1</translation> + <translation>Добавление отсутствующего значка %1</translation> </message> </context> <context> @@ -4855,7 +4859,7 @@ Available commands: </message> <message> <source>Cannot create new group</source> - <translation type="unfinished"/> + <translation>Не удаётся создать новую группу</translation> </message> </context> <context> @@ -5131,7 +5135,7 @@ Available commands: </message> <message> <source>Signer:</source> - <translation type="unfinished"/> + <translation>Подписавшийся:</translation> </message> </context> <context> @@ -5254,27 +5258,27 @@ Available commands: </message> <message> <source>Multiple import source path to %1 in %2</source> - <translation type="unfinished"/> + <translation>Множественный путь источника импорта к %1 в %2</translation> </message> <message> <source>Conflicting export target path %1 in %2</source> - <translation type="unfinished"/> + <translation>Конфликтный путь цели экспорта %1 в %2</translation> </message> <message> <source>Could not embed signature: Could not open file to write (%1)</source> - <translation type="unfinished"/> + <translation>Не удалось встроить подпись: Не удалось открыть файл для записи (%1)</translation> </message> <message> <source>Could not embed signature: Could not write file (%1)</source> - <translation type="unfinished"/> + <translation>Не удалось встроить подпись: Не удалось записать файл (%1)</translation> </message> <message> <source>Could not embed database: Could not open file to write (%1)</source> - <translation type="unfinished"/> + <translation>Не удалось встроить базу данных: Не удалось открыть файл для записи (%1)</translation> </message> <message> <source>Could not embed database: Could not write file (%1)</source> - <translation type="unfinished"/> + <translation>Не удалось встроить базу данных: Не удалось записать файл (%1)</translation> </message> </context> <context> 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 @@ </message> <message> <source>Follow style</source> - <translation type="unfinished"/> + <translation>Štýl nasledovania</translation> </message> </context> <context> @@ -168,7 +168,7 @@ </message> <message> <source>Hide the entry preview panel</source> - <translation type="unfinished"/> + <translation>Skryť panel náhľadu položky</translation> </message> <message> <source>General</source> @@ -269,11 +269,11 @@ </message> <message> <source> min</source> - <translation type="unfinished"/> + <translation> min</translation> </message> <message> <source>Forget TouchID after inactivity of</source> - <translation type="unfinished"/> + <translation>Zabudnúť TouchID po neaktivite dlhšej ako</translation> </message> <message> <source>Convenience</source> @@ -285,7 +285,7 @@ </message> <message> <source>Forget TouchID when session is locked or lid is closed</source> - <translation type="unfinished"/> + <translation>Zabudnúť TouchID po neaktivite dlhšej ako</translation> </message> <message> <source>Lock databases after minimizing the window</source> @@ -429,7 +429,7 @@ Prosím, zvoľte, či chcete povoliť prístup.</translation> <name>BrowserEntrySaveDialog</name> <message> <source>KeePassXC-Browser Save Entry</source> - <translation type="unfinished"/> + <translation>KeePassXC-Browser Uložiť položku</translation> </message> <message> <source>Ok</source> @@ -611,15 +611,15 @@ Prosím, vyberte správnu databázu na uloženie prihlasovacích údajov.</trans </message> <message> <source>Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1</source> - <translation type="unfinished"/> + <translation>Kvôli ochrane Snap v sandboxe, musíte na povolenie integrácie prehliadača spustiť skript.<br />Skript môžete získať z %1</translation> </message> <message> <source>Please see special instructions for browser extension use below</source> - <translation type="unfinished"/> + <translation>Prosím, pozrite si špeciálne inštrukcie na použite integrácie prehliadača nižšie</translation> </message> <message> <source>KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3</source> - <translation type="unfinished"/> + <translation>KeePassXC-Browser je potrebný aby fungovala integrácia s prehliadačom<br /> Stiahnite ho pre %1 a %2. %3</translation> </message> </context> <context> @@ -649,7 +649,7 @@ zadajte mu jedinečný názov na identifikáciu a potvrďte ho.</translation> <message> <source>A shared encryption key with the name "%1" already exists. Do you want to overwrite it?</source> - <translation>Zdiľaný šifrovací kľúč s menom „%1” už existuje. + <translation>Zdieľaný šifrovací kľúč s menom „%1” už existuje. Chcete ho prepísať?</translation> </message> <message> @@ -666,48 +666,53 @@ Chcete ho prepísať?</translation> </message> <message> <source>Converting attributes to custom data…</source> - <translation type="unfinished"/> + <translation>Konvertovanie atribútov na vlastné dáta…</translation> </message> <message> <source>KeePassXC: Converted KeePassHTTP attributes</source> - <translation type="unfinished"/> + <translation>KeePassXC: Konvertované atribúty KeePassHTTP</translation> </message> <message> <source>Successfully converted attributes from %1 entry(s). Moved %2 keys to custom data.</source> - <translation type="unfinished"/> + <translation>Úspešne skonvertované atribúty z %1 položky(iek). +Do vlastných dát presunuté %2 kľúče.</translation> </message> <message numerus="yes"> <source>Successfully moved %n keys to custom data.</source> - <translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation> + <translation><numerusform>Úspešne presunutý %n kľúč do vlastných dát.</numerusform><numerusform>Úspešne presunuté %n kľúče do vlastných dát.</numerusform><numerusform>Úspešne presunutých %n kľúčov do vlastných dát.</numerusform><numerusform>Úspešne presunutých %n kľúčov do vlastných dát.</numerusform></translation> </message> <message> <source>KeePassXC: No entry with KeePassHTTP attributes found!</source> - <translation type="unfinished"/> + <translation>KeePassXC: Nenájdená žiadna položka s atribútmi KeePassHTTP!</translation> </message> <message> <source>The active database does not contain an entry with KeePassHTTP attributes.</source> - <translation type="unfinished"/> + <translation>Aktívna databáza neobsahuje žiadnu položku s atribútmi KeePassHTTP.</translation> </message> <message> <source>KeePassXC: Legacy browser integration settings detected</source> - <translation type="unfinished"/> + <translation>KeePassXC: Zistené staré nastavenia integrácie prehliadača</translation> </message> <message> <source>KeePassXC: Create a new group</source> - <translation type="unfinished"/> + <translation>KeePassXC: Vytvoriť novú skupinu</translation> </message> <message> <source>A request for creating a new group "%1" has been received. Do you want to create this group? </source> - <translation type="unfinished"/> + <translation>Bola prijatá požiadavka n novú skupinu „%1”. +Chcete vytvoriť túto skupinu? +</translation> </message> <message> <source>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?</source> - <translation type="unfinished"/> + <translation>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?</translation> </message> </context> <context> @@ -813,12 +818,13 @@ Would you like to migrate your existing settings now?</source> </message> <message numerus="yes"> <source>[%n more message(s) skipped]</source> - <translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation> + <translation><numerusform>[%n ďalšia správa preskočená]</numerusform><numerusform>[%n ďalšie správy preskočené</numerusform><numerusform>[%n ďalších správ preskočených]</numerusform><numerusform>[%n ďalších správ preskočených]</numerusform></translation> </message> <message> <source>CSV import: writer has errors: %1</source> - <translation type="unfinished"/> + <translation>Import CSV: chyby zápisu: +%1</translation> </message> </context> <context> @@ -838,7 +844,7 @@ Would you like to migrate your existing settings now?</source> </message> <message numerus="yes"> <source>%n row(s)</source> - <translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation> + <translation><numerusform>%n riadok</numerusform><numerusform>%n riadky</numerusform><numerusform>%n riadkov</numerusform><numerusform>%n riadkov</numerusform></translation> </message> </context> <context> @@ -866,18 +872,18 @@ Would you like to migrate your existing settings now?</source> </message> <message> <source>File cannot be written as it is opened in read-only mode.</source> - <translation type="unfinished"/> + <translation>Do súboru nemožno zapisovať, pretože je otvorený v režime len na čítanie.</translation> </message> <message> <source>Key not transformed. This is a bug, please report it to the developers!</source> - <translation type="unfinished"/> + <translation>Kľúč nebol transformovaný. Je to chyba, prosím, nahláste ju vývojárom!</translation> </message> </context> <context> <name>DatabaseOpenDialog</name> <message> <source>Unlock Database - KeePassXC</source> - <translation type="unfinished"/> + <translation>Odomknúť databázu – KeePassXC</translation> </message> </context> <context> @@ -938,17 +944,19 @@ Prosím, zvážte vygenerovanie nového súboru kľúča.</translation> </message> <message> <source>TouchID for quick unlock</source> - <translation type="unfinished"/> + <translation>TouchID na rýchle odomknutie</translation> </message> <message> <source>Unable to open the database: %1</source> - <translation type="unfinished"/> + <translation>Nemožno otvoriť databázu: +%1</translation> </message> <message> <source>Can't open key file: %1</source> - <translation type="unfinished"/> + <translation>Nemožno otvoriť súbor kľúča: +%1</translation> </message> </context> <context> @@ -962,7 +970,7 @@ Prosím, zvážte vygenerovanie nového súboru kľúča.</translation> <name>DatabaseSettingsDialog</name> <message> <source>Advanced Settings</source> - <translation type="unfinished"/> + <translation>Pokročilé nastavenia</translation> </message> <message> <source>General</source> @@ -989,7 +997,7 @@ Prosím, zvážte vygenerovanie nového súboru kľúča.</translation> <name>DatabaseSettingsWidgetBrowser</name> <message> <source>KeePassXC-Browser settings</source> - <translation type="unfinished"/> + <translation>Nastavenia KeePassXC-Browser</translation> </message> <message> <source>&Disconnect all browsers</source> @@ -997,11 +1005,11 @@ Prosím, zvážte vygenerovanie nového súboru kľúča.</translation> </message> <message> <source>Forg&et all site-specific settings on entries</source> - <translation type="unfinished"/> + <translation>Zabudnúť všetky nastavenia &stránok vo všetkých položkách</translation> </message> <message> <source>Move KeePassHTTP attributes to KeePassXC-Browser &custom data</source> - <translation type="unfinished"/> + <translation>Presunúť atribúty KeePassHTTP do vlastný&ch dát KeePassXC-Browser</translation> </message> <message> <source>Stored keys</source> @@ -1057,7 +1065,7 @@ Môže to brániť pripojeniu zásuvného modulu prehliadača.</translation> </message> <message numerus="yes"> <source>Successfully removed %n encryption key(s) from KeePassXC settings.</source> - <translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation> + <translation><numerusform>Úspešne odstránený %n šifrovací kľúč z nastavení KeePassXC.</numerusform><numerusform>Úspešne odstránené %n šifrovacie kľúče z nastavení KeePassXC.</numerusform><numerusform>Úspešne odstránených %n šifrovacích kľúčov z nastavení KeePassXC.</numerusform><numerusform>Úspešne odstránených %n šifrovacích kľúčov z nastavení KeePassXC.</numerusform></translation> </message> <message> <source>Forget all site-specific settings on entries</source> @@ -1066,7 +1074,8 @@ Môže to brániť pripojeniu zásuvného modulu prehliadača.</translation> <message> <source>Do you really want forget all site-specific settings on every entry? Permissions to access entries will be revoked.</source> - <translation type="unfinished"/> + <translation>Naozaj chcete zabudnúť všetky nastavenia stránok v každej položke? +Povolenia na prístup k položkám budú odvolané.</translation> </message> <message> <source>Removing stored permissions…</source> @@ -1082,7 +1091,7 @@ Permissions to access entries will be revoked.</source> </message> <message numerus="yes"> <source>Successfully removed permissions from %n entry(s).</source> - <translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation> + <translation><numerusform>Úspešne odstránené povolenia z %n položky.</numerusform><numerusform>Úspešne odstránené povolenia z %n položiek.</numerusform><numerusform>Úspešne odstránené povolenia z %n položiek.</numerusform><numerusform>Úspešne odstránené povolenia z %n položky.</numerusform></translation> </message> <message> <source>KeePassXC: No entry with permissions found!</source> @@ -1094,12 +1103,13 @@ Permissions to access entries will be revoked.</source> </message> <message> <source>Move KeePassHTTP attributes to custom data</source> - <translation type="unfinished"/> + <translation>Presunúť atribúty KeePassHTTP do vlastných dát</translation> </message> <message> <source>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.</source> - <translation type="unfinished"/> + <translation>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.</translation> </message> </context> <context> @@ -1142,7 +1152,7 @@ This is necessary to maintain compatibility with the browser plugin.</source> </message> <message> <source>?? s</source> - <translation type="unfinished"/> + <translation>?? s</translation> </message> <message> <source>Change</source> @@ -1231,7 +1241,7 @@ Ak ponecháte toto číslo, môže byť prelomenie ochrany databázy príliš je <message numerus="yes"> <source> thread(s)</source> <comment>Threads for parallel execution (KDF settings)</comment> - <translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation> + <translation><numerusform>vlákno</numerusform><numerusform>vlákna</numerusform><numerusform>vlákien</numerusform><numerusform> vlákien</numerusform></translation> </message> <message numerus="yes"> <source>%1 ms</source> @@ -1311,7 +1321,7 @@ Ak ponecháte toto číslo, môže byť prelomenie ochrany databázy príliš je </message> <message> <source>Last Signer</source> - <translation type="unfinished"/> + <translation>Naposledy podpísal</translation> </message> <message> <source>Certificates</source> @@ -1327,25 +1337,27 @@ Ak ponecháte toto číslo, môže byť prelomenie ochrany databázy príliš je <name>DatabaseSettingsWidgetMasterKey</name> <message> <source>Add additional protection...</source> - <translation type="unfinished"/> + <translation>Pridať dodatočné zabezpečenie…</translation> </message> <message> <source>No encryption key added</source> - <translation type="unfinished"/> + <translation>Nie je pridaný šifrovací kľúč</translation> </message> <message> <source>You must add at least one encryption key to secure your database!</source> - <translation type="unfinished"/> + <translation>Na zabezpečenie svojej databázy musíte pridať aspoň jeden šifrovací kľúč!</translation> </message> <message> <source>No password set</source> - <translation type="unfinished"/> + <translation>Nie je nastavené heslo</translation> </message> <message> <source>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?</source> - <translation type="unfinished"/> + <translation>UPOZORNENIE! Nenastavili iste heslo. Použitie databázy bez hesla dôrazne neodporúčame! + +Naozaj chcete pokračovať bez hesla?</translation> </message> <message> <source>Unknown error</source> @@ -1353,7 +1365,7 @@ Are you sure you want to continue without a password?</source> </message> <message> <source>Failed to change master key</source> - <translation type="unfinished"/> + <translation>Zlyhala zmena hlavného kľúča</translation> </message> </context> <context> @@ -1412,11 +1424,12 @@ Are you sure you want to continue without a password?</source> <message> <source>The created database has no key or KDF, refusing to save it. This is definitely a bug, please report it to the developers.</source> - <translation type="unfinished"/> + <translation>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.</translation> </message> <message> <source>The database file does not exist or is not accessible.</source> - <translation type="unfinished"/> + <translation>Súbor databázy neexistuje alebo nie je dostupný.</translation> </message> <message> <source>Select CSV file</source> @@ -1520,15 +1533,15 @@ Chcete zlúčiť svoje zmeny?</translation> </message> <message numerus="yes"> <source>Do you really want to delete %n entry(s) for good?</source> - <translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation> + <translation><numerusform>Naozaj chcete natrvalo odstrániť %n položku?</numerusform><numerusform>Naozaj chcete natrvalo odstrániť %n položky?</numerusform><numerusform>Naozaj chcete natrvalo odstrániť %n položiek?</numerusform><numerusform>Naozaj chcete natrvalo odstrániť %n položky?</numerusform></translation> </message> <message numerus="yes"> <source>Delete entry(s)?</source> - <translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation> + <translation><numerusform>Odstrániť položku?</numerusform><numerusform>Odstrániť položky?</numerusform><numerusform>Odstrániť položky?</numerusform><numerusform>Odstrániť položky?</numerusform></translation> </message> <message numerus="yes"> <source>Move entry(s) to recycle bin?</source> - <translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation> + <translation><numerusform>Presunúť položku do koša?</numerusform><numerusform>Presunúť položky do koša?</numerusform><numerusform>Presunúť položky do koša?</numerusform><numerusform>Presunúť položky do koša?</numerusform></translation> </message> <message> <source>File opened in read only mode.</source> @@ -1540,7 +1553,7 @@ Chcete zlúčiť svoje zmeny?</translation> </message> <message> <source>You are editing an entry. Discard changes and lock anyway?</source> - <translation type="unfinished"/> + <translation>Upravujete položku. Zahodiť zmeny a zamknúť napriek tomu?</translation> </message> <message> <source>"%1" was modified. @@ -1551,7 +1564,8 @@ Uložiť zmeny?</translation> <message> <source>Database was modified. Save changes?</source> - <translation type="unfinished"/> + <translation>Databáza bola zmenená. +Uložiť zmeny?</translation> </message> <message> <source>Save changes?</source> @@ -1560,7 +1574,8 @@ Save changes?</source> <message> <source>Could not open the new database file while attempting to autoreload. Error: %1</source> - <translation type="unfinished"/> + <translation>Nemožno otvoriť nový databázový súbor počas pokusu o automatické opätovné načítanie. +Chyba: %1</translation> </message> <message> <source>Disable safe saves?</source> @@ -1575,7 +1590,8 @@ Vypnúť bezpečné ukladanie a skúsiť znova?</translation> <message> <source>Writing the database failed. %1</source> - <translation type="unfinished"/> + <translation>Zapisovanie do databázy zlyhalo. +%1</translation> </message> <message> <source>Passwords</source> @@ -1591,35 +1607,35 @@ Vypnúť bezpečné ukladanie a skúsiť znova?</translation> </message> <message> <source>Replace references to entry?</source> - <translation type="unfinished"/> + <translation>Nahradiť existujúcu položku?</translation> </message> <message numerus="yes"> <source>Entry "%1" has %2 reference(s). Do you want to overwrite references with values, skip this entry, or delete anyway?</source> - <translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation> + <translation><numerusform>Položka „%1” má %2 odkaz. Chcete prepísať odkazy hodnotami, preskočiť túto položku alebo ju i tak odstrániť?</numerusform><numerusform>Položka „%1” má %2 odkazy. Chcete prepísať odkazy hodnotami, preskočiť túto položku alebo ju i tak odstrániť?</numerusform><numerusform>Položka „%1” má %2 odkazov. Chcete prepísať odkazy hodnotami, preskočiť túto položku alebo ju i tak odstrániť?</numerusform><numerusform>Položka „%1” má %2 odkazu. Chcete prepísať odkazy hodnotami, preskočiť túto položku alebo ju i tak odstrániť?</numerusform></translation> </message> <message> <source>Delete group</source> - <translation type="unfinished"/> + <translation>Odstrániť skupinu</translation> </message> <message> <source>Move group to recycle bin?</source> - <translation type="unfinished"/> + <translation>Presunúť skupinu do koša?</translation> </message> <message> <source>Do you really want to move the group "%1" to the recycle bin?</source> - <translation type="unfinished"/> + <translation>Naozaj chcete presunúť skupinu „%1” do koša?</translation> </message> <message> <source>Successfully merged the database files.</source> - <translation type="unfinished"/> + <translation>Úspešne zlúčené databázové súbory.</translation> </message> <message> <source>Database was not modified by merge operation.</source> - <translation type="unfinished"/> + <translation>Databáza nebola operáciou zlúčenia zmenená.</translation> </message> <message> <source>Shared group...</source> - <translation type="unfinished"/> + <translation>Zdieľaná skupina…</translation> </message> </context> <context> @@ -1722,23 +1738,23 @@ Vypnúť bezpečné ukladanie a skúsiť znova?</translation> </message> <message> <source>Entry has unsaved changes</source> - <translation type="unfinished"/> + <translation>Položka má neuložené zmeny</translation> </message> <message> <source>New attribute %1</source> - <translation type="unfinished"/> + <translation>Nový atribút %1</translation> </message> <message> <source>[PROTECTED] Press reveal to view or edit</source> - <translation type="unfinished"/> + <translation>[CHRÁNENÉ] Stlačte odkryť na zobrazenie alebo úpravu</translation> </message> <message numerus="yes"> <source>%n year(s)</source> - <translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation> + <translation><numerusform>%n rok</numerusform><numerusform>%n roky</numerusform><numerusform>%n rokov</numerusform><numerusform>%n rokov</numerusform></translation> </message> <message> <source>Confirm Removal</source> - <translation type="unfinished"/> + <translation>Potvrdiť odstránenie</translation> </message> </context> <context> @@ -1992,15 +2008,15 @@ Vypnúť bezpečné ukladanie a skúsiť znova?</translation> </message> <message> <source>Type:</source> - <translation type="unfinished"/> + <translation>Typ:</translation> </message> <message> <source>Path:</source> - <translation type="unfinished"/> + <translation>Cesta:</translation> </message> <message> <source>...</source> - <translation type="unfinished"/> + <translation>…</translation> </message> <message> <source>Password:</source> @@ -2008,55 +2024,55 @@ Vypnúť bezpečné ukladanie a skúsiť znova?</translation> </message> <message> <source>Inactive</source> - <translation type="unfinished"/> + <translation>Neaktívne</translation> </message> <message> <source>Import from path</source> - <translation type="unfinished"/> + <translation>Importovať z cesty</translation> </message> <message> <source>Export to path</source> - <translation type="unfinished"/> + <translation>Exportovať do cesty</translation> </message> <message> <source>Synchronize with path</source> - <translation type="unfinished"/> + <translation>Synchronizovať s cestou</translation> </message> <message> <source>Your KeePassXC version does not support sharing your container type. Please use %1.</source> - <translation type="unfinished"/> + <translation>Táto verzia KeePassXC nepodporuje zdieľanie Vášho typu kontajnera. Prosím použite %1.</translation> </message> <message> <source>Database sharing is disabled</source> - <translation type="unfinished"/> + <translation>Zdieľanie databázy je vypnuté</translation> </message> <message> <source>Database export is disabled</source> - <translation type="unfinished"/> + <translation>Export databázy je vpynutý</translation> </message> <message> <source>Database import is disabled</source> - <translation type="unfinished"/> + <translation>Import databázy je vpynutý</translation> </message> <message> <source>KeeShare unsigned container</source> - <translation type="unfinished"/> + <translation>Nepodpísaný kontajner KeeShare</translation> </message> <message> <source>KeeShare signed container</source> - <translation type="unfinished"/> + <translation>Podpísaný kontajner KeeShare</translation> </message> <message> <source>Select import source</source> - <translation type="unfinished"/> + <translation>Vyberte zdroj importu</translation> </message> <message> <source>Select export target</source> - <translation type="unfinished"/> + <translation>Vyberte cieľ exportu</translation> </message> <message> <source>Select import/export file</source> - <translation type="unfinished"/> + <translation>Vyberte súbor importu/exportu</translation> </message> <message> <source>Clear</source> @@ -2064,15 +2080,15 @@ Vypnúť bezpečné ukladanie a skúsiť znova?</translation> </message> <message> <source>The export container %1 is already referenced.</source> - <translation type="unfinished"/> + <translation>Kontajner exportu %1 už je odkazovaný.</translation> </message> <message> <source>The import container %1 is already imported.</source> - <translation type="unfinished"/> + <translation>Kontajner importu %1 už je importovaný.</translation> </message> <message> <source>The container %1 imported and export by different groups.</source> - <translation type="unfinished"/> + <translation>Kontajner %1 importovaný a exportovaný rôznymi skupinami.</translation> </message> </context> <context> @@ -2150,35 +2166,35 @@ Vypnúť bezpečné ukladanie a skúsiť znova?</translation> </message> <message> <source>Custom icon successfully downloaded</source> - <translation type="unfinished"/> + <translation>Vlastná ikona úspešne stiahnutá</translation> </message> <message> <source>Hint: You can enable DuckDuckGo as a fallback under Tools>Settings>Security</source> - <translation type="unfinished"/> + <translation>Tip: Môžete zapnúť DuckDuckGo ako náhradné riešenie v Nástroje>Nastavenie>Bezpečnosť</translation> </message> <message> <source>Select Image(s)</source> - <translation type="unfinished"/> + <translation>vyberte obrázok(y)</translation> </message> <message numerus="yes"> <source>Successfully loaded %1 of %n icon(s)</source> - <translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation> + <translation><numerusform>Úspešne načítané %1 z %n ikony</numerusform><numerusform>Úspešne načítané %1 z %n ikon</numerusform><numerusform>Úspešne načítané %1 z %n ikon</numerusform><numerusform>Úspešne načítané %1 z %n ikony</numerusform></translation> </message> <message> <source>No icons were loaded</source> - <translation type="unfinished"/> + <translation>Neboli načítané ikony</translation> </message> <message numerus="yes"> <source>%n icon(s) already exist in the database</source> - <translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation> + <translation><numerusform>%n ikony už v databáze existuje</numerusform><numerusform>%n ikony už v databáze existujú</numerusform><numerusform>%n ikon už v databáze existuje</numerusform><numerusform>%n ikony už v databáze existuje</numerusform></translation> </message> <message numerus="yes"> <source>The following icon(s) failed:</source> - <translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation> + <translation><numerusform>Nasledujúca ikona zlyhala:</numerusform><numerusform>Nasledujúce ikony zlyhali:</numerusform><numerusform>Nasledujúce ikony zlyhali:</numerusform><numerusform>Nasledujúce ikony zlyhali:</numerusform></translation> </message> <message numerus="yes"> <source>This icon is used by %n entry(s), and will be replaced by the default icon. Are you sure you want to delete it?</source> - <translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation> + <translation><numerusform>Táto ikona je použitá v %n položke a bude nahradená predvolenou ikonou. Naozaj ju chcete odstrániť?</numerusform><numerusform>Táto ikona je použitá v %n položkách a bude nahradená predvolenou ikonou. Naozaj ju chcete odstrániť?</numerusform><numerusform>Táto ikona je použitá v %n položkách a bude nahradená predvolenou ikonou. Naozaj ju chcete odstrániť?</numerusform><numerusform>Táto ikona je použitá v %n položke a bude nahradená predvolenou ikonou. Naozaj ju chcete odstrániť?</numerusform></translation> </message> </context> <context> @@ -2230,7 +2246,7 @@ Môže to spôsobiť nefunkčnosť dotknutých zásuvných modulov.</translation <name>Entry</name> <message> <source>%1 - Clone</source> - <translation type="unfinished"/> + <translation>%1 – Klon</translation> </message> </context> <context> @@ -2312,12 +2328,16 @@ Môže to spôsobiť nefunkčnosť dotknutých zásuvných modulov.</translation </message> <message> <source>Confirm remove</source> - <translation type="unfinished"/> + <translation>Potvrdiť odstránenie</translation> </message> <message numerus="yes"> <source>Unable to open file(s): %1</source> - <translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation> + <translation><numerusform>Nemožno otvoriť súbor: +%1</numerusform><numerusform>Nemožno otvoriť súbory: +%1</numerusform><numerusform>Nemožno otvoriť súbory: +%1</numerusform><numerusform>Nemožno otvoriť súbory: +%1</numerusform></translation> </message> </context> <context> @@ -2403,11 +2423,11 @@ Môže to spôsobiť nefunkčnosť dotknutých zásuvných modulov.</translation </message> <message> <source>Yes</source> - <translation type="unfinished"/> + <translation>Áno</translation> </message> <message> <source>TOTP</source> - <translation type="unfinished"/> + <translation>TOTP</translation> </message> </context> <context> @@ -2487,7 +2507,7 @@ Môže to spôsobiť nefunkčnosť dotknutých zásuvných modulov.</translation <message> <source><b>%1</b>: %2</source> <comment>attributes line</comment> - <translation type="unfinished"/> + <translation><b>%1</b>: %2</translation> </message> <message> <source>Enabled</source> @@ -2499,7 +2519,7 @@ Môže to spôsobiť nefunkčnosť dotknutých zásuvných modulov.</translation </message> <message> <source>Share</source> - <translation type="unfinished"/> + <translation>Zdieľať</translation> </message> </context> <context> @@ -2542,7 +2562,7 @@ Môže to spôsobiť nefunkčnosť dotknutých zásuvných modulov.</translation <message> <source>[empty]</source> <comment>group has no children</comment> - <translation type="unfinished"/> + <translation>[prázdne]</translation> </message> </context> <context> @@ -2587,7 +2607,7 @@ Môže to spôsobiť nefunkčnosť dotknutých zásuvných modulov.</translation </message> <message> <source>Header doesn't match hash</source> - <translation type="unfinished"/> + <translation>Hlavička nezodpovedá odtlačku</translation> </message> <message> <source>Invalid header id size</source> @@ -2816,15 +2836,15 @@ Je to jednosmerná migrácia. Importovanú databázu už nebude možné otvoriť </message> <message> <source>Invalid cipher uuid length: %1 (length=%2)</source> - <translation type="unfinished"/> + <translation>Neplatná dĺžka UUID šifry: %1 (length=%2)</translation> </message> <message> <source>Unable to parse UUID: %1</source> - <translation type="unfinished"/> + <translation>Nemožno spracovať UUID: %1</translation> </message> <message> <source>Failed to read database file.</source> - <translation type="unfinished"/> + <translation>Zlyhalo čítanie súboru databázy.</translation> </message> </context> <context> @@ -2950,7 +2970,9 @@ Je to jednosmerná migrácia. Importovanú databázu už nebude možné otvoriť <source>XML error: %1 Line %2, column %3</source> - <translation type="unfinished"/> + <translation>Chyba XML: +%1 +Riadok %2, stĺpec %3</translation> </message> </context> <context> @@ -3117,53 +3139,53 @@ Line %2, column %3</source> </message> <message> <source>unable to seek to content position</source> - <translation type="unfinished"/> + <translation>nemožno sa posunúť na pozíciu obsahu</translation> </message> </context> <context> <name>KeeShare</name> <message> <source>Disabled share</source> - <translation type="unfinished"/> + <translation>Vypnúť zdieľanie</translation> </message> <message> <source>Import from</source> - <translation type="unfinished"/> + <translation>Importovať z</translation> </message> <message> <source>Export to</source> - <translation type="unfinished"/> + <translation>Exportovať do</translation> </message> <message> <source>Synchronize with</source> - <translation type="unfinished"/> + <translation>Synchronizovať s</translation> </message> <message> <source>Disabled share %1</source> - <translation type="unfinished"/> + <translation>Vypnuté zdieľanie %1</translation> </message> <message> <source>Import from share %1</source> - <translation type="unfinished"/> + <translation>Importovať zo zdieľania %1</translation> </message> <message> <source>Export to share %1</source> - <translation type="unfinished"/> + <translation>Exportovať do zdieľania %1</translation> </message> <message> <source>Synchronize with share %1</source> - <translation type="unfinished"/> + <translation>Synchronizovať so zdieľaním %1</translation> </message> </context> <context> <name>KeyComponentWidget</name> <message> <source>Key Component</source> - <translation type="unfinished"/> + <translation>Kľúč komponentu</translation> </message> <message> <source>Key Component Description</source> - <translation type="unfinished"/> + <translation>Popis kľúča komponentu</translation> </message> <message> <source>Cancel</source> @@ -3171,27 +3193,27 @@ Line %2, column %3</source> </message> <message> <source>Key Component set, click to change or remove</source> - <translation type="unfinished"/> + <translation>Nastavenie kľúča komponentu, kliknite na zmenu alebo odstránenie</translation> </message> <message> <source>Add %1</source> <comment>Add a key component</comment> - <translation type="unfinished"/> + <translation>Pridať %1</translation> </message> <message> <source>Change %1</source> <comment>Change a key component</comment> - <translation type="unfinished"/> + <translation>Zmeniť %1</translation> </message> <message> <source>Remove %1</source> <comment>Remove a key component</comment> - <translation type="unfinished"/> + <translation>Odstrániť %1</translation> </message> <message> <source>%1 set, click to change or remove</source> <comment>Change or remove a key component</comment> - <translation type="unfinished"/> + <translation>%1 nastavené, kliknite na zmenu alebo odstránenie</translation> </message> </context> <context> @@ -3206,11 +3228,11 @@ Line %2, column %3</source> </message> <message> <source>Key File</source> - <translation type="unfinished"/> + <translation>Súbor kľúča</translation> </message> <message> <source><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></source> - <translation type="unfinished"/> + <translation><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></translation> </message> <message> <source>Legacy key file format</source> @@ -3221,12 +3243,15 @@ Line %2, column %3</source> unsupported in the future. Please go to the master key settings and generate a new key file.</source> - <translation type="unfinished"/> + <translation>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.</translation> </message> <message> <source>Error loading the key file '%1' Message: %2</source> - <translation type="unfinished"/> + <translation>Chyba načítania súboru kľúča „%1” +Správa: %2</translation> </message> <message> <source>Key files</source> @@ -3242,11 +3267,11 @@ Message: %2</source> </message> <message> <source>Error creating key file</source> - <translation type="unfinished"/> + <translation>Chyba vytvárania súboru kľúča</translation> </message> <message> <source>Unable to create key file: %1</source> - <translation type="unfinished"/> + <translation>Nemožno vytvoriť súbor kľúča: %1</translation> </message> <message> <source>Select a key file</source> @@ -3435,151 +3460,152 @@ Odporúčame použiť AppImage dostupný v našej stránke sťahovaní.</transla </message> <message> <source>&Import</source> - <translation type="unfinished"/> + <translation>&Import</translation> </message> <message> <source>Copy att&ribute...</source> - <translation type="unfinished"/> + <translation>Kopírovať at&ribút...</translation> </message> <message> <source>TOTP...</source> - <translation type="unfinished"/> + <translation>TOTP…</translation> </message> <message> <source>&New database...</source> - <translation type="unfinished"/> + <translation>&Nová databáza…</translation> </message> <message> <source>Create a new database</source> - <translation type="unfinished"/> + <translation>Vytvoriť novú databázu</translation> </message> <message> <source>&Merge from database...</source> - <translation type="unfinished"/> + <translation>&Zlúčiť z databázou…</translation> </message> <message> <source>Merge from another KDBX database</source> - <translation type="unfinished"/> + <translation>Zlúčiť s inou databázou KDBX</translation> </message> <message> <source>&New entry</source> - <translation type="unfinished"/> + <translation>&Nová položka</translation> </message> <message> <source>Add a new entry</source> - <translation type="unfinished"/> + <translation>Pridať novú položku</translation> </message> <message> <source>&Edit entry</source> - <translation type="unfinished"/> + <translation>&Upraviť položku</translation> </message> <message> <source>View or edit entry</source> - <translation type="unfinished"/> + <translation>Zobraziť alebo upraviť položku</translation> </message> <message> <source>&New group</source> - <translation type="unfinished"/> + <translation>&Nová skupina</translation> </message> <message> <source>Add a new group</source> - <translation type="unfinished"/> + <translation>Pridať novú skupinu</translation> </message> <message> <source>Change master &key...</source> - <translation type="unfinished"/> + <translation>Zmeniť hlavný &kľúč…</translation> </message> <message> <source>&Database settings...</source> - <translation type="unfinished"/> + <translation>Nastavenia &databázy…</translation> </message> <message> <source>Copy &password</source> - <translation type="unfinished"/> + <translation>Kopírovať &heslo</translation> </message> <message> <source>Perform &Auto-Type</source> - <translation type="unfinished"/> + <translation>Vykonať &Automatické vypĺňanie</translation> </message> <message> <source>Open &URL</source> - <translation type="unfinished"/> + <translation>Otvoriť &URL</translation> </message> <message> <source>KeePass 1 database...</source> - <translation type="unfinished"/> + <translation>Databáza KeePass 1…</translation> </message> <message> <source>Import a KeePass 1 database</source> - <translation type="unfinished"/> + <translation>Importovať databázu KeePass 1…</translation> </message> <message> <source>CSV file...</source> - <translation type="unfinished"/> + <translation>Súbor CSV</translation> </message> <message> <source>Import a CSV file</source> - <translation type="unfinished"/> + <translation>Importovať súbor CSV…</translation> </message> <message> <source>Show TOTP...</source> - <translation type="unfinished"/> + <translation>Zobraziť TOTP…</translation> </message> <message> <source>Show TOTP QR Code...</source> - <translation type="unfinished"/> + <translation>Zobraziť QR kód TOTP</translation> </message> <message> <source>Check for Updates...</source> - <translation type="unfinished"/> + <translation>Skontrolovať aktualizácie…</translation> </message> <message> <source>Share entry</source> - <translation type="unfinished"/> + <translation>Zdieľať položku</translation> </message> <message> <source>NOTE: You are using a pre-release version of KeePassXC! Expect some bugs and minor issues, this version is not meant for production use.</source> - <translation type="unfinished"/> + <translation>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.</translation> </message> <message> <source>Check for updates on startup?</source> - <translation type="unfinished"/> + <translation>Skontrolovať aktualizácie pri štarte?</translation> </message> <message> <source>Would you like KeePassXC to check for updates on startup?</source> - <translation type="unfinished"/> + <translation>Chcete aby KeePassXC skontroloval aktualizácie pri štarte?</translation> </message> <message> <source>You can always check for updates manually from the application menu.</source> - <translation type="unfinished"/> + <translation>Vždy môžete skontrolovať aktualizácie manuálne z menu aplikácie.</translation> </message> </context> <context> <name>Merger</name> <message> <source>Creating missing %1 [%2]</source> - <translation type="unfinished"/> + <translation>Vytváranie chýbajúceho %1 [%2]</translation> </message> <message> <source>Relocating %1 [%2]</source> - <translation type="unfinished"/> + <translation>Relokácia %1 [%2]</translation> </message> <message> <source>Overwriting %1 [%2]</source> - <translation type="unfinished"/> + <translation>Prepísanie %1 [%2]</translation> </message> <message> <source>older entry merged from database "%1"</source> - <translation type="unfinished"/> + <translation>staršia položka zlúčená z databázy „%1”</translation> </message> <message> <source>Adding backup for older target %1 [%2]</source> - <translation type="unfinished"/> + <translation>Pridávanie zálohy staršieho cieľa %1 [%2]</translation> </message> <message> <source>Adding backup for older source %1 [%2]</source> - <translation type="unfinished"/> + <translation>Pridávanie zálohy staršieho zdroja %1 [%2]</translation> </message> <message> <source>Reapplying older target entry on top of newer source %1 [%2]</source> @@ -3630,23 +3656,23 @@ Expect some bugs and minor issues, this version is not meant for production use. <name>NewDatabaseWizardPage</name> <message> <source>WizardPage</source> - <translation type="unfinished"/> + <translation>Stránka sprievodcu</translation> </message> <message> <source>En&cryption Settings</source> - <translation type="unfinished"/> + <translation>Nastavenia &šifrovanie</translation> </message> <message> <source>Here you can adjust the database encryption settings. Don't worry, you can change them later in the database settings.</source> - <translation type="unfinished"/> + <translation>Tu môžete prispôsobiť nastavenia šifrovania databázy. Nebojte sa, neskôr ich môžete zmeniť v nastavení databázy.</translation> </message> <message> <source>Advanced Settings</source> - <translation type="unfinished"/> + <translation>Pokročilé nastavenia</translation> </message> <message> <source>Simple Settings</source> - <translation type="unfinished"/> + <translation>Jednoduché nastavenia</translation> </message> </context> <context> @@ -3657,29 +3683,29 @@ Expect some bugs and minor issues, this version is not meant for production use. </message> <message> <source>Here you can adjust the database encryption settings. Don't worry, you can change them later in the database settings.</source> - <translation type="unfinished"/> + <translation>Tu môžete prispôsobiť nastavenia šifrovania databázy. Nebojte sa, neskôr ich môžete zmeniť v nastavení databázy.</translation> </message> </context> <context> <name>NewDatabaseWizardPageMasterKey</name> <message> <source>Database Master Key</source> - <translation type="unfinished"/> + <translation>Hlavný kľúč databázy</translation> </message> <message> <source>A master key known only to you protects your database.</source> - <translation type="unfinished"/> + <translation>Hlavný kľúč, známy len vám, chráni vašu databázu.</translation> </message> </context> <context> <name>NewDatabaseWizardPageMetaData</name> <message> <source>General Database Information</source> - <translation type="unfinished"/> + <translation>Všeobecné informácie databázy</translation> </message> <message> <source>Please fill in the display name and an optional description for your new database:</source> - <translation type="unfinished"/> + <translation>Prosím, vyplňte meno a prípadne aj popis svojej novej databázy:</translation> </message> </context> <context> @@ -3789,7 +3815,7 @@ Expect some bugs and minor issues, this version is not meant for production use. </message> <message> <source>Confirm password:</source> - <translation type="unfinished"/> + <translation>Potvrďte heslo:</translation> </message> <message> <source>Password</source> @@ -3797,15 +3823,15 @@ Expect some bugs and minor issues, this version is not meant for production use. </message> <message> <source><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></source> - <translation type="unfinished"/> + <translation><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></translation> </message> <message> <source>Passwords do not match.</source> - <translation type="unfinished"/> + <translation>Heslá sa nezhodujú.</translation> </message> <message> <source>Generate master password</source> - <translation type="unfinished"/> + <translation>Vygenerovať hlavné heslo</translation> </message> </context> <context> @@ -3921,11 +3947,11 @@ Expect some bugs and minor issues, this version is not meant for production use. </message> <message> <source>ExtendedASCII</source> - <translation type="unfinished"/> + <translation>Rozšírené ASCII</translation> </message> <message> <source>Switch to advanced mode</source> - <translation type="unfinished"/> + <translation>Prepnúť na pokročilý režim</translation> </message> <message> <source>Advanced</source> @@ -3933,7 +3959,7 @@ Expect some bugs and minor issues, this version is not meant for production use. </message> <message> <source>Upper Case Letters A to F</source> - <translation type="unfinished"/> + <translation>Veľké písmená A až F</translation> </message> <message> <source>A-Z</source> @@ -3941,7 +3967,7 @@ Expect some bugs and minor issues, this version is not meant for production use. </message> <message> <source>Lower Case Letters A to F</source> - <translation type="unfinished"/> + <translation>Malé písmená A až F</translation> </message> <message> <source>a-z</source> @@ -3953,108 +3979,108 @@ Expect some bugs and minor issues, this version is not meant for production use. </message> <message> <source>Braces</source> - <translation type="unfinished"/> + <translation>Zátvorky</translation> </message> <message> <source>{[(</source> - <translation type="unfinished"/> + <translation>{[(</translation> </message> <message> <source>Punctuation</source> - <translation type="unfinished"/> + <translation>Interpunkcia</translation> </message> <message> <source>.,:;</source> - <translation type="unfinished"/> + <translation>.,:;</translation> </message> <message> <source>Quotes</source> - <translation type="unfinished"/> + <translation>Úvodzovky</translation> </message> <message> <source>" '</source> - <translation type="unfinished"/> + <translation>" '</translation> </message> <message> <source>Math</source> - <translation type="unfinished"/> + <translation>Matematické</translation> </message> <message> <source><*+!?=</source> - <translation type="unfinished"/> + <translation><*+!?=</translation> </message> <message> <source>Dashes</source> - <translation type="unfinished"/> + <translation>Oddeľovače</translation> </message> <message> <source>\_|-/</source> - <translation type="unfinished"/> + <translation>\_|-/</translation> </message> <message> <source>Logograms</source> - <translation type="unfinished"/> + <translation>Zástupné znaky</translation> </message> <message> <source>#$%&&@^`~</source> - <translation type="unfinished"/> + <translation>#$%&&@^`~</translation> </message> <message> <source>Switch to simple mode</source> - <translation type="unfinished"/> + <translation>Prepnúť na jednoduchý režim</translation> </message> <message> <source>Simple</source> - <translation type="unfinished"/> + <translation>jednoduché</translation> </message> <message> <source>Character set to exclude from generated password</source> - <translation type="unfinished"/> + <translation>Sady znakov, ktoré majú byť vynechané pri generovaní hesla</translation> </message> <message> <source>Do not include:</source> - <translation type="unfinished"/> + <translation>Nezahŕňať:</translation> </message> <message> <source>Add non-hex letters to "do not include" list</source> - <translation type="unfinished"/> + <translation>Pridajte nie-šestnástkové písmená do zoznamu „vynechať”</translation> </message> <message> <source>Hex</source> - <translation type="unfinished"/> + <translation>Šestnástkové</translation> </message> <message> <source>Excluded characters: "0", "1", "l", "I", "O", "|", "﹒"</source> - <translation type="unfinished"/> + <translation>Vynechané znaky: „0”, „1”, „l”, „I”, „O”, „|”, „﹒”</translation> </message> <message> <source>Word Co&unt:</source> - <translation type="unfinished"/> + <translation>Počet &slov:</translation> </message> <message> <source>Regenerate</source> - <translation type="unfinished"/> + <translation>Obnoviť</translation> </message> </context> <context> <name>QApplication</name> <message> <source>KeeShare</source> - <translation type="unfinished"/> + <translation>KeeShare</translation> </message> </context> <context> <name>QFileDialog</name> <message> <source>Select</source> - <translation type="unfinished"/> + <translation>Vybrať</translation> </message> </context> <context> <name>QMessageBox</name> <message> <source>Overwrite</source> - <translation type="unfinished"/> + <translation>Prepísať</translation> </message> <message> <source>Delete</source> @@ -4062,11 +4088,11 @@ Expect some bugs and minor issues, this version is not meant for production use. </message> <message> <source>Move</source> - <translation type="unfinished"/> + <translation>Presunúť</translation> </message> <message> <source>Empty</source> - <translation type="unfinished"/> + <translation>Vyprádzniť</translation> </message> <message> <source>Remove</source> @@ -4074,7 +4100,7 @@ Expect some bugs and minor issues, this version is not meant for production use. </message> <message> <source>Skip</source> - <translation type="unfinished"/> + <translation>Preskočiť</translation> </message> <message> <source>Disable</source> @@ -4082,7 +4108,7 @@ Expect some bugs and minor issues, this version is not meant for production use. </message> <message> <source>Merge</source> - <translation type="unfinished"/> + <translation>Zlúčiť</translation> </message> </context> <context> @@ -4400,47 +4426,47 @@ Dostupné príkazy: </message> <message> <source>Invalid value for password length %1.</source> - <translation type="unfinished"/> + <translation>Neplatná hodnota dĺžky hesla %1.</translation> </message> <message> <source>Could not create entry with path %1.</source> - <translation type="unfinished"/> + <translation>Nemožno vytvoriť položku s cestou %1.</translation> </message> <message> <source>Enter password for new entry: </source> - <translation type="unfinished"/> + <translation>Zadajte heslo novej položky:</translation> </message> <message> <source>Writing the database failed %1.</source> - <translation type="unfinished"/> + <translation>Zápis do databázy zlyhal %1.</translation> </message> <message> <source>Successfully added entry %1.</source> - <translation type="unfinished"/> + <translation>Úspešne pridaná položka %1.</translation> </message> <message> <source>Copy the current TOTP to the clipboard.</source> - <translation type="unfinished"/> + <translation>Kopírovať aktuálny TOTP do schránky.</translation> </message> <message> <source>Invalid timeout value %1.</source> - <translation type="unfinished"/> + <translation>Neplatná hodnota časového limitu %1.</translation> </message> <message> <source>Entry %1 not found.</source> - <translation type="unfinished"/> + <translation>Položka %1 nenájdená.</translation> </message> <message> <source>Entry with path %1 has no TOTP set up.</source> - <translation type="unfinished"/> + <translation>Položka s cestou %1 nemá nastavený TOTP.</translation> </message> <message> <source>Entry's current TOTP copied to the clipboard!</source> - <translation type="unfinished"/> + <translation>TTOP aktuálnej položky skopírovaný do schránky!</translation> </message> <message> <source>Entry's password copied to the clipboard!</source> - <translation type="unfinished"/> + <translation>Heslo položky skopírované schránky!</translation> </message> <message numerus="yes"> <source>Clearing the clipboard in %1 second(s)...</source> @@ -4448,7 +4474,7 @@ Dostupné príkazy: </message> <message> <source>Clipboard cleared!</source> - <translation type="unfinished"/> + <translation>Schránka vymazaná!</translation> </message> <message> <source>Silence password prompt and other secondary outputs.</source> @@ -4473,27 +4499,27 @@ Dostupné príkazy: </message> <message> <source>Enter new password for entry: </source> - <translation type="unfinished"/> + <translation>Zadajte nové heslo položky:</translation> </message> <message> <source>Writing the database failed: %1</source> - <translation type="unfinished"/> + <translation>Zápis do databázy zlyhal: %1</translation> </message> <message> <source>Successfully edited entry %1.</source> - <translation type="unfinished"/> + <translation>Úspešne upravená položka %1.</translation> </message> <message> <source>Length %1</source> - <translation type="unfinished"/> + <translation>Dĺžka %1</translation> </message> <message> <source>Entropy %1</source> - <translation type="unfinished"/> + <translation>Náhodnosť %1</translation> </message> <message> <source>Log10 %1</source> - <translation type="unfinished"/> + <translation>Log10 %1</translation> </message> <message> <source>Multi-word extra bits %1</source> @@ -4501,83 +4527,83 @@ Dostupné príkazy: </message> <message> <source>Type: Bruteforce</source> - <translation type="unfinished"/> + <translation>Type: Hrubou silou</translation> </message> <message> <source>Type: Dictionary</source> - <translation type="unfinished"/> + <translation>Typ: Slovník</translation> </message> <message> <source>Type: Dict+Leet</source> - <translation type="unfinished"/> + <translation>Typ: Slovník+Leet</translation> </message> <message> <source>Type: User Words</source> - <translation type="unfinished"/> + <translation>Typ: Použ. slová</translation> </message> <message> <source>Type: User+Leet</source> - <translation type="unfinished"/> + <translation>Typ: Použ.+Leet</translation> </message> <message> <source>Type: Repeated</source> - <translation type="unfinished"/> + <translation>Typ: Opakované</translation> </message> <message> <source>Type: Sequence</source> - <translation type="unfinished"/> + <translation>Typ: Postupné</translation> </message> <message> <source>Type: Spatial</source> - <translation type="unfinished"/> + <translation>Typ: Geometrické</translation> </message> <message> <source>Type: Date</source> - <translation type="unfinished"/> + <translation>Typ: Dátum</translation> </message> <message> <source>Type: Bruteforce(Rep)</source> - <translation type="unfinished"/> + <translation>Typ: Hrubou silou(Rep)</translation> </message> <message> <source>Type: Dictionary(Rep)</source> - <translation type="unfinished"/> + <translation>Typ: Slovník(Rep)</translation> </message> <message> <source>Type: Dict+Leet(Rep)</source> - <translation type="unfinished"/> + <translation>Typ: Slovník+Leet(Rep)</translation> </message> <message> <source>Type: User Words(Rep)</source> - <translation type="unfinished"/> + <translation>Type: Použ. slová(Rep)</translation> </message> <message> <source>Type: User+Leet(Rep)</source> - <translation type="unfinished"/> + <translation>Typ: Použ.+Leet(Rep)</translation> </message> <message> <source>Type: Repeated(Rep)</source> - <translation type="unfinished"/> + <translation>Typ: Opakované(Rep)</translation> </message> <message> <source>Type: Sequence(Rep)</source> - <translation type="unfinished"/> + <translation>Typ: Postupné(Rep)</translation> </message> <message> <source>Type: Spatial(Rep)</source> - <translation type="unfinished"/> + <translation>Typ: Geometrické(Rep)</translation> </message> <message> <source>Type: Date(Rep)</source> - <translation type="unfinished"/> + <translation>Typ: Dátum(Rep)</translation> </message> <message> <source>Type: Unknown%1</source> - <translation type="unfinished"/> + <translation>Type: Neznámy%1</translation> </message> <message> <source>Entropy %1 (%2)</source> - <translation type="unfinished"/> + <translation>Náhodnosť %1 (%2)</translation> </message> <message> <source>*** Password length (%1) != sum of length of parts (%2) ***</source> @@ -4585,7 +4611,7 @@ Dostupné príkazy: </message> <message> <source>Failed to load key file %1: %2</source> - <translation type="unfinished"/> + <translation>Zlyhalo načítanie súboru kľúča %1: %2</translation> </message> <message> <source>File %1 does not exist.</source> @@ -4598,52 +4624,54 @@ Dostupné príkazy: <message> <source>Error while reading the database: %1</source> - <translation type="unfinished"/> + <translation>Chyba čítania databázy: +%1</translation> </message> <message> <source>Error while parsing the database: %1</source> - <translation type="unfinished"/> + <translation>Chyba spracovania databázy: +1</translation> </message> <message> <source>Length of the generated password</source> - <translation type="unfinished"/> + <translation>Dĺžka generovaného hesla</translation> </message> <message> <source>Use lowercase characters</source> - <translation type="unfinished"/> + <translation>Požiť malé písmená</translation> </message> <message> <source>Use uppercase characters</source> - <translation type="unfinished"/> + <translation>Použiť veľké písmená</translation> </message> <message> <source>Use numbers.</source> - <translation type="unfinished"/> + <translation>Použiť čísla</translation> </message> <message> <source>Use special characters</source> - <translation type="unfinished"/> + <translation>Použiť špeciálne znaky</translation> </message> <message> <source>Use extended ASCII</source> - <translation type="unfinished"/> + <translation>Použiť rozšírené ASCII</translation> </message> <message> <source>Exclude character set</source> - <translation type="unfinished"/> + <translation>Množina vynechaných znakov</translation> </message> <message> <source>chars</source> - <translation type="unfinished"/> + <translation>znaky</translation> </message> <message> <source>Exclude similar looking characters</source> - <translation type="unfinished"/> + <translation>Vynechať podobne vyzerajúce znaky</translation> </message> <message> <source>Include characters from every selected group</source> - <translation type="unfinished"/> + <translation>Použiť znaky z každej zvolenej skupiny</translation> </message> <message> <source>Recursively list the elements of the group.</source> @@ -4651,20 +4679,21 @@ Dostupné príkazy: </message> <message> <source>Cannot find group %1.</source> - <translation type="unfinished"/> + <translation>Nemožno nájsť skupinu %1.</translation> </message> <message> <source>Error reading merge file: %1</source> - <translation type="unfinished"/> + <translation>Chyba čítania súboru zlúčenia: +%1</translation> </message> <message> <source>Unable to save database to file : %1</source> - <translation type="unfinished"/> + <translation>Nemožno uložiť databázu do súboru: %1</translation> </message> <message> <source>Unable to save database to file: %1</source> - <translation type="unfinished"/> + <translation>Nemožno uložiť databázu do súboru: %1</translation> </message> <message> <source>Successfully recycled entry %1.</source> @@ -4676,23 +4705,23 @@ Dostupné príkazy: </message> <message> <source>Show the entry's current TOTP.</source> - <translation type="unfinished"/> + <translation>Zobraziť aktuálny TOTP položky.</translation> </message> <message> <source>ERROR: unknown attribute %1.</source> - <translation type="unfinished"/> + <translation>CHYBA: Neznámy atribút %1.</translation> </message> <message> <source>No program defined for clipboard manipulation</source> - <translation type="unfinished"/> + <translation>Nie je definovaný program na manipuláciu so schránkou</translation> </message> <message> <source>Unable to start program %1</source> - <translation type="unfinished"/> + <translation>Nemožno spustiť program %1</translation> </message> <message> <source>file empty</source> - <translation type="unfinished"/> + <translation>prázdny súbor</translation> </message> <message> <source>%1: (row, col) %2,%3</source> @@ -4725,48 +4754,48 @@ Dostupné príkazy: <message> <source>Invalid Settings</source> <comment>TOTP</comment> - <translation type="unfinished"/> + <translation>Neplatné nastavenia</translation> </message> <message> <source>Invalid Key</source> <comment>TOTP</comment> - <translation type="unfinished"/> + <translation>Neplatný kľúč</translation> </message> <message> <source>Message encryption failed.</source> - <translation type="unfinished"/> + <translation>Šifrovanie správy zlyhalo.</translation> </message> <message> <source>No groups found</source> - <translation type="unfinished"/> + <translation>Skupiny nenájdené</translation> </message> <message> <source>Create a new database.</source> - <translation type="unfinished"/> + <translation>Vytvoriť novú databázu.</translation> </message> <message> <source>File %1 already exists.</source> - <translation type="unfinished"/> + <translation>Súbor %1 už existuje.</translation> </message> <message> <source>Loading the key file failed</source> - <translation type="unfinished"/> + <translation>Načítanie nového kľúča zlyhalo</translation> </message> <message> <source>No key is set. Aborting database creation.</source> - <translation type="unfinished"/> + <translation>Nie je nastavený kľúč. Vytvorenie novej databázy zrušené.</translation> </message> <message> <source>Failed to save the database: %1.</source> - <translation type="unfinished"/> + <translation>Zlyhalo uloženie databázy: %1.</translation> </message> <message> <source>Successfully created new database.</source> - <translation type="unfinished"/> + <translation>Úspešne vytvorená nová databáza.</translation> </message> <message> <source>Insert password to encrypt database (Press enter to leave blank): </source> - <translation type="unfinished"/> + <translation>Zadajte heslo na zašifrovanie databázy (Stlačte Enter na ponechanie prázdneho): </translation> </message> <message> <source>Creating KeyFile %1 failed: %2</source> @@ -4834,7 +4863,7 @@ Dostupné príkazy: </message> <message> <source>Cannot create new group</source> - <translation type="unfinished"/> + <translation>Nemožno vytvoriť novú skupinu</translation> </message> </context> <context> @@ -4910,7 +4939,7 @@ Dostupné príkazy: <name>SearchHelpWidget</name> <message> <source>Search Help</source> - <translation type="unfinished"/> + <translation>Hľadať v pomocníkovi</translation> </message> <message> <source>Search terms are as follows: [modifiers][field:]["]term["]</source> @@ -4922,7 +4951,7 @@ Dostupné príkazy: </message> <message> <source>Modifiers</source> - <translation type="unfinished"/> + <translation>Modifikátory</translation> </message> <message> <source>exclude term from results</source> @@ -4938,7 +4967,7 @@ Dostupné príkazy: </message> <message> <source>Fields</source> - <translation type="unfinished"/> + <translation>Polia</translation> </message> <message> <source>Term Wildcards</source> @@ -4958,7 +4987,7 @@ Dostupné príkazy: </message> <message> <source>Examples</source> - <translation type="unfinished"/> + <translation>Príklady</translation> </message> </context> <context> @@ -4977,47 +5006,47 @@ Dostupné príkazy: </message> <message> <source>Search Help</source> - <translation type="unfinished"/> + <translation>Hľadať v pomocníkovi</translation> </message> <message> <source>Search (%1)...</source> <comment>Search placeholder text, %1 is the keyboard shortcut</comment> - <translation type="unfinished"/> + <translation>Hľadanie (%1)...</translation> </message> <message> <source>Case sensitive</source> - <translation type="unfinished"/> + <translation>Rozlišovať veľkosť písmen</translation> </message> </context> <context> <name>SettingsWidgetKeeShare</name> <message> <source>Active</source> - <translation type="unfinished"/> + <translation>Aktívne</translation> </message> <message> <source>Allow export</source> - <translation type="unfinished"/> + <translation>Povoliť export</translation> </message> <message> <source>Allow import</source> - <translation type="unfinished"/> + <translation>Povoliť import</translation> </message> <message> <source>Own certificate</source> - <translation type="unfinished"/> + <translation>Vlastný certifikát</translation> </message> <message> <source>Fingerprint:</source> - <translation type="unfinished"/> + <translation>Odtlačok:</translation> </message> <message> <source>Certificate:</source> - <translation type="unfinished"/> + <translation>Certifikát:</translation> </message> <message> <source>Signer</source> - <translation type="unfinished"/> + <translation>Podpísal</translation> </message> <message> <source>Key:</source> @@ -5033,23 +5062,23 @@ Dostupné príkazy: </message> <message> <source>Export</source> - <translation type="unfinished"/> + <translation>Export</translation> </message> <message> <source>Imported certificates</source> - <translation type="unfinished"/> + <translation>Importované certifikáty</translation> </message> <message> <source>Trust</source> - <translation type="unfinished"/> + <translation>Dôverovať</translation> </message> <message> <source>Ask</source> - <translation type="unfinished"/> + <translation>Spýtať sa</translation> </message> <message> <source>Untrust</source> - <translation type="unfinished"/> + <translation>Nedôverovať</translation> </message> <message> <source>Remove</source> @@ -5061,7 +5090,7 @@ Dostupné príkazy: </message> <message> <source>Status</source> - <translation type="unfinished"/> + <translation>Status</translation> </message> <message> <source>Fingerprint</source> @@ -5069,19 +5098,19 @@ Dostupné príkazy: </message> <message> <source>Certificate</source> - <translation type="unfinished"/> + <translation>Certifikát</translation> </message> <message> <source>Trusted</source> - <translation type="unfinished"/> + <translation>Dôveryhodný</translation> </message> <message> <source>Untrusted</source> - <translation type="unfinished"/> + <translation>Nedôveryhodný</translation> </message> <message> <source>Unknown</source> - <translation type="unfinished"/> + <translation>Neznámy</translation> </message> <message> <source>key.share</source> @@ -5098,7 +5127,7 @@ Dostupné príkazy: </message> <message> <source>Select path</source> - <translation type="unfinished"/> + <translation>Zvoľte cestu</translation> </message> <message> <source>Exporting changed certificate</source> @@ -5129,7 +5158,7 @@ Dostupné príkazy: </message> <message> <source>Not this time</source> - <translation type="unfinished"/> + <translation>Teraz nie</translation> </message> <message> <source>Never</source> @@ -5137,11 +5166,11 @@ Dostupné príkazy: </message> <message> <source>Always</source> - <translation type="unfinished"/> + <translation>Vždy</translation> </message> <message> <source>Just this time</source> - <translation type="unfinished"/> + <translation>Len tentokrát</translation> </message> <message> <source>Import from %1 failed (%2)</source> 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 @@ </message> <message> <source>Project Maintainers:</source> - <translation>Projekt Ansvariga:</translation> + <translation>Projekt ansvariga:</translation> </message> <message> <source>Special thanks from the KeePassXC team go to debfx for creating the original KeePassX.</source> @@ -93,7 +93,7 @@ </message> <message> <source>Follow style</source> - <translation type="unfinished"/> + <translation>Följ stil</translation> </message> </context> <context> @@ -116,7 +116,7 @@ </message> <message> <source>Remember last key files and security dongles</source> - <translation type="unfinished"/> + <translation>Kom ihåg senaste nyckel-fil och säkerhets-enhet</translation> </message> <message> <source>Load previous databases on startup</source> @@ -132,7 +132,7 @@ </message> <message> <source>Safely save database files (may be incompatible with Dropbox, etc)</source> - <translation type="unfinished"/> + <translation>Spara databasfiler säkert (kan vara inkompatibelt med Dropbox, etc)</translation> </message> <message> <source>Backup database file before saving</source> @@ -168,7 +168,7 @@ </message> <message> <source>Hide the entry preview panel</source> - <translation type="unfinished"/> + <translation>Göm post förhandsvisningspanelen</translation> </message> <message> <source>General</source> @@ -176,11 +176,11 @@ </message> <message> <source>Hide toolbar (icons)</source> - <translation type="unfinished"/> + <translation>Göm verktygsfält (ikonerna)</translation> </message> <message> <source>Minimize instead of app exit</source> - <translation type="unfinished"/> + <translation>Minimera istället för att avsluta</translation> </message> <message> <source>Show a system tray icon</source> @@ -200,7 +200,7 @@ </message> <message> <source>Auto-Type</source> - <translation>Autoskriv</translation> + <translation>Auto-skriv</translation> </message> <message> <source>Use entry title to match windows for global Auto-Type</source> @@ -220,7 +220,7 @@ </message> <message> <source>Auto-Type typing delay</source> - <translation type="unfinished"/> + <translation>Auto-skriv fördröjning</translation> </message> <message> <source> ms</source> @@ -229,23 +229,23 @@ </message> <message> <source>Auto-Type start delay</source> - <translation type="unfinished"/> + <translation>Auto-skriv start fördröjning</translation> </message> <message> <source>Check for updates at application startup</source> - <translation type="unfinished"/> + <translation>Leta efter uppdateringar vid start</translation> </message> <message> <source>Include pre-releases when checking for updates</source> - <translation type="unfinished"/> + <translation>Inkludera förhandsversioner vid sökning efter uppdateringar</translation> </message> <message> <source>Movable toolbar</source> - <translation type="unfinished"/> + <translation>Rörligt verktygsfält</translation> </message> <message> <source>Button style</source> - <translation type="unfinished"/> + <translation>Knapp-stil</translation> </message> </context> <context> @@ -273,7 +273,7 @@ </message> <message> <source>Forget TouchID after inactivity of</source> - <translation type="unfinished"/> + <translation>Glöm TouchID efter inaktivitet i</translation> </message> <message> <source>Convenience</source> @@ -285,7 +285,7 @@ </message> <message> <source>Forget TouchID when session is locked or lid is closed</source> - <translation type="unfinished"/> + <translation>Glöm TouchID när sessionen låses eller locket stängs</translation> </message> <message> <source>Lock databases after minimizing the window</source> @@ -293,7 +293,7 @@ </message> <message> <source>Re-lock previously locked database after performing Auto-Type</source> - <translation type="unfinished"/> + <translation>Lås tidigare låst databas efter att ha utfört Auto-skriv</translation> </message> <message> <source>Don't require password repeat when it is visible</source> @@ -309,7 +309,7 @@ </message> <message> <source>Hide passwords in the entry preview panel</source> - <translation type="unfinished"/> + <translation>Göm lösenord i förhandsgranskningsrutan</translation> </message> <message> <source>Hide entry notes by default</source> @@ -321,7 +321,7 @@ </message> <message> <source>Use DuckDuckGo as fallback for downloading website icons</source> - <translation type="unfinished"/> + <translation>Använd DuckDuckGo som alternativ vid nedladdning av webbplatsikoner</translation> </message> </context> <context> @@ -429,7 +429,7 @@ Vill du tillåta det?</translation> <name>BrowserEntrySaveDialog</name> <message> <source>KeePassXC-Browser Save Entry</source> - <translation type="unfinished"/> + <translation>KeePassXC-Browser spara post</translation> </message> <message> <source>Ok</source> @@ -442,7 +442,8 @@ Vill du tillåta det?</translation> <message> <source>You have multiple databases open. Please select the correct database for saving credentials.</source> - <translation type="unfinished"/> + <translation>Du ha flera databaser öppna. +Välj databas för att spara uppgifter.</translation> </message> </context> <context> @@ -539,7 +540,7 @@ Please select the correct database for saving credentials.</source> <message> <source>Searc&h in all opened databases for matching credentials</source> <extracomment>Credentials mean login data requested via browser extension</extracomment> - <translation type="unfinished"/> + <translation>Sök i alla öppna databaser efter matchande uppgifter</translation> </message> <message> <source>Automatically creating or updating string fields is not supported.</source> @@ -547,7 +548,7 @@ Please select the correct database for saving credentials.</source> </message> <message> <source>&Return advanced string fields which start with "KPH: "</source> - <translation type="unfinished"/> + <translation>Returnera avancerade text-fält som börjar med "KPH: "</translation> </message> <message> <source>Updates KeePassXC or keepassxc-proxy binary path automatically to native messaging scripts on startup.</source> @@ -873,7 +874,7 @@ Would you like to migrate your existing settings now?</source> <name>DatabaseOpenDialog</name> <message> <source>Unlock Database - KeePassXC</source> - <translation type="unfinished"/> + <translation>Lås upp databas - KeePassXC</translation> </message> </context> <context> @@ -969,7 +970,7 @@ Please consider generating a new key file.</source> </message> <message> <source>Master Key</source> - <translation type="unfinished"/> + <translation>Huvud-lösenord</translation> </message> <message> <source>Encryption Settings</source> @@ -1029,7 +1030,7 @@ This may prevent connection to the browser plugin.</source> </message> <message> <source>Disconnect all browsers</source> - <translation type="unfinished"/> + <translation>Koppla från alla webbläsare</translation> </message> <message> <source>Do you really want to disconnect all browsers? @@ -1131,7 +1132,7 @@ This is necessary to maintain compatibility with the browser plugin.</source> </message> <message> <source>Decryption Time:</source> - <translation type="unfinished"/> + <translation>Dektypterings-tid:</translation> </message> <message> <source>?? s</source> @@ -1512,7 +1513,7 @@ Do you want to merge your changes?</source> </message> <message numerus="yes"> <source>Delete entry(s)?</source> - <translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation> + <translation><numerusform>Ta bort post?</numerusform><numerusform>Ta bort poster?</numerusform></translation> </message> <message numerus="yes"> <source>Move entry(s) to recycle bin?</source> @@ -1606,7 +1607,7 @@ Disable safe saves and try again?</source> </message> <message> <source>Shared group...</source> - <translation type="unfinished"/> + <translation>Delad grupp...</translation> </message> </context> <context> @@ -1884,7 +1885,7 @@ Disable safe saves and try again?</source> </message> <message> <source>Public key</source> - <translation type="unfinished"/> + <translation>Publik nyckel</translation> </message> <message> <source>Add key to agent when database is opened/unlocked</source> @@ -2097,7 +2098,7 @@ Disable safe saves and try again?</source> <name>EditWidgetIcons</name> <message> <source>&Use default icon</source> - <translation type="unfinished"/> + <translation>Använd standard ikon</translation> </message> <message> <source>Use custo&m icon</source> @@ -3109,15 +3110,15 @@ Line %2, column %3</source> </message> <message> <source>Import from</source> - <translation type="unfinished"/> + <translation>Importera från</translation> </message> <message> <source>Export to</source> - <translation type="unfinished"/> + <translation>Exportera till</translation> </message> <message> <source>Synchronize with</source> - <translation type="unfinished"/> + <translation>Synkronisera med</translation> </message> <message> <source>Disabled share %1</source> @@ -3187,7 +3188,7 @@ Line %2, column %3</source> </message> <message> <source>Key File</source> - <translation type="unfinished"/> + <translation>Nyckel-fil</translation> </message> <message> <source><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></source> @@ -3250,7 +3251,7 @@ Message: %2</source> </message> <message> <source>E&ntries</source> - <translation type="unfinished"/> + <translation>Poster</translation> </message> <message> <source>&Groups</source> @@ -3441,11 +3442,11 @@ We recommend you use the AppImage available on our downloads page.</source> </message> <message> <source>&New entry</source> - <translation type="unfinished"/> + <translation>Ny post</translation> </message> <message> <source>Add a new entry</source> - <translation type="unfinished"/> + <translation>Lägg till ny post</translation> </message> <message> <source>&Edit entry</source> 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 @@ <name>AgentSettingsWidget</name> <message> <source>Enable SSH Agent (requires restart)</source> - <translation>SSH Aracısını etkinleştir (yeniden başlatma gerektirir)</translation> + <translation>SSH İstemcisini etkinleştir (yeniden başlatma gerektirir)</translation> </message> <message> <source>Use OpenSSH for Windows instead of Pageant</source> @@ -93,7 +93,7 @@ </message> <message> <source>Follow style</source> - <translation>Takip tarzı</translation> + <translation>Takip tipi</translation> </message> </context> <context> @@ -245,7 +245,7 @@ </message> <message> <source>Button style</source> - <translation>Düğme tarzı</translation> + <translation>Düğme tipi</translation> </message> </context> <context> @@ -367,7 +367,7 @@ </message> <message> <source>Default sequence</source> - <translation>Varsayılan sıra</translation> + <translation>Öntanımlı sıra</translation> </message> </context> <context> @@ -491,7 +491,7 @@ Lütfen kimlik bilgilerini kaydetmek için doğru veritabanını seç.</translat </message> <message> <source>Re&quest to unlock the database if it is locked</source> - <translation>Eğer kilitliyse veri tabanını açmayı is&te</translation> + <translation>Eğer kilitliyse veritabanının kilidini açma is&teği</translation> </message> <message> <source>Only entries with the same scheme (http://, https://, ...) are returned.</source> @@ -535,7 +535,7 @@ Lütfen kimlik bilgilerini kaydetmek için doğru veritabanını seç.</translat </message> <message> <source>Only the selected database has to be connected with a client.</source> - <translation>Yalnızca seçilen veri tabanı istemciyle bağlanmış olmalıdır.</translation> + <translation>Yalnızca seçilen veritabanı istemciyle bağlanmış olmalıdır.</translation> </message> <message> <source>Searc&h in all opened databases for matching credentials</source> @@ -611,15 +611,15 @@ Lütfen kimlik bilgilerini kaydetmek için doğru veritabanını seç.</translat </message> <message> <source>Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1</source> - <translation type="unfinished"/> + <translation>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.</translation> </message> <message> <source>Please see special instructions for browser extension use below</source> - <translation type="unfinished"/> + <translation>Lütfen aşağıdaki tarayıcı uzantısı kullanımına ilişkin özel talimatlara bakın</translation> </message> <message> <source>KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3</source> - <translation type="unfinished"/> + <translation>Tarayıcı bütünleşmesinin çalışması için KeePassXC-Tarayıcı gereklidir. <br />%1 ve %2 için indirin. %3</translation> </message> </context> <context> @@ -696,19 +696,23 @@ Moved %2 keys to custom data.</source> </message> <message> <source>KeePassXC: Create a new group</source> - <translation type="unfinished"/> + <translation>KeePassXC: Yeni bir küme oluştur</translation> </message> <message> <source>A request for creating a new group "%1" has been received. Do you want to create this group? </source> - <translation type="unfinished"/> + <translation>"%1" adlı yeni bir küme oluşturma isteği alındı. +Bu kümeyi oluşturmak ister misiniz? +</translation> </message> <message> <source>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?</source> - <translation type="unfinished"/> + <translation>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?</translation> </message> </context> <context> @@ -872,7 +876,7 @@ Would you like to migrate your existing settings now?</source> </message> <message> <source>Key not transformed. This is a bug, please report it to the developers!</source> - <translation type="unfinished"/> + <translation>Anahtar dönüştürülmedi. Bu bir hatadır, lütfen geliştiricilere bildirin!</translation> </message> </context> <context> @@ -997,7 +1001,7 @@ Lütfen yeni bir anahtar dosyası oluşturmayı düşünün.</translation> </message> <message> <source>&Disconnect all browsers</source> - <translation>&Tüm tarayıcıları kapatın</translation> + <translation>&Tüm tarayıcıların bağlantısını kes</translation> </message> <message> <source>Forg&et all site-specific settings on entries</source> @@ -1039,13 +1043,13 @@ Bu işlem, tarayıcı eklentisine bağlantıyı engelleyebilir.</translation> </message> <message> <source>Disconnect all browsers</source> - <translation>Tüm tarayıcıları kapatın</translation> + <translation>Tüm tarayıcıların bağlantısını kes</translation> </message> <message> <source>Do you really want to disconnect all browsers? This may prevent connection to the browser plugin.</source> <translation>Tüm tarayıcıların bağlantısını kesmek istiyor musunuz? -Bu işlem, tarayıcı eklentisine bağlantıyı engelleyebilir.</translation> +Bu işlem, tarayıcı eklentisi bağlantısını engelleyebilir.</translation> </message> <message> <source>KeePassXC: No keys found</source> @@ -1095,7 +1099,7 @@ Girişlere erişim izinleri iptal edilecek.</translation> </message> <message> <source>The active database does not contain an entry with permissions.</source> - <translation>Etkin veritabanı izinleri olan bir girdi içermiyor.</translation> + <translation>Etkin veritabanı, izinleri olan bir girdi içermiyor.</translation> </message> <message> <source>Move KeePassHTTP attributes to custom data</source> @@ -1254,15 +1258,15 @@ Eğer bu sayı ile devam ederseniz, veritabanınız çok kolay çözülerek kır <name>DatabaseSettingsWidgetGeneral</name> <message> <source>Database Meta Data</source> - <translation>Veritabanı Meta Verileri</translation> + <translation>Veritabanı Üst Veri</translation> </message> <message> <source>Database name:</source> - <translation>Veri tabanı adı:</translation> + <translation>Veritabanı adı:</translation> </message> <message> <source>Database description:</source> - <translation>Veri tabanı ayrıntısı:</translation> + <translation>Veritabanı açıklaması:</translation> </message> <message> <source>Default username:</source> @@ -1379,7 +1383,7 @@ Parola olmadan devam etmek istediğinize emin misiniz?</translation> <name>DatabaseTabWidget</name> <message> <source>KeePass 2 Database</source> - <translation>KeePass 2 Veri Tabanı</translation> + <translation>KeePass 2 Veritabanı</translation> </message> <message> <source>All files</source> @@ -1387,7 +1391,7 @@ Parola olmadan devam etmek istediğinize emin misiniz?</translation> </message> <message> <source>Open database</source> - <translation>Veri tabanı aç</translation> + <translation>Veritabanı aç</translation> </message> <message> <source>CSV file</source> @@ -1395,19 +1399,19 @@ Parola olmadan devam etmek istediğinize emin misiniz?</translation> </message> <message> <source>Merge database</source> - <translation>Veri tabanı birleştir</translation> + <translation>Veritabanını birleştir</translation> </message> <message> <source>Open KeePass 1 database</source> - <translation>KeePass 1 veri tabanı aç</translation> + <translation>KeePass 1 veritabanı aç</translation> </message> <message> <source>KeePass 1 database</source> - <translation>KeePass 1 veri tabanı</translation> + <translation>KeePass 1 veritabanı</translation> </message> <message> <source>Export database to CSV file</source> - <translation>Veri tabanını CSV dosyasına dışa aktar</translation> + <translation>Veritabanını CSV dosyasına dışa aktar</translation> </message> <message> <source>Writing the CSV file failed.</source> @@ -1487,11 +1491,11 @@ Bu kesinlikle bir hatadır, lütfen geliştiricilere bildirin.</translation> </message> <message> <source>No current database.</source> - <translation>Geçerli veri tabanı yok.</translation> + <translation>Geçerli veritabanı yok.</translation> </message> <message> <source>No source database, nothing to do.</source> - <translation>Kaynak veri tabanı yok, yapılacak bir şey yok.</translation> + <translation>Kaynak veritabanı yok, yapılacak bir şey yok.</translation> </message> <message> <source>Search Results (%1)</source> @@ -1507,7 +1511,7 @@ Bu kesinlikle bir hatadır, lütfen geliştiricilere bildirin.</translation> </message> <message> <source>The database file has changed. Do you want to load the changes?</source> - <translation>Veri tabanı dosyası değiştirildi. Değişiklikleri yüklemek ister misiniz?</translation> + <translation>Veritabanı dosyası değiştirildi. Değişiklikleri yüklemek ister misiniz?</translation> </message> <message> <source>Merge Request</source> @@ -1586,7 +1590,7 @@ Güvenli kaydetme devre dışı bırakılsın ve tekrar denensin mi?</translatio <message> <source>Writing the database failed. %1</source> - <translation>Veritabanını yazma başarısız + <translation>Veritabanına yazma başarısız %1</translation> </message> <message> @@ -1631,7 +1635,7 @@ Güvenli kaydetme devre dışı bırakılsın ve tekrar denensin mi?</translatio </message> <message> <source>Shared group...</source> - <translation type="unfinished"/> + <translation>Paylaşılan küme...</translation> </message> </context> <context> @@ -1662,7 +1666,7 @@ Güvenli kaydetme devre dışı bırakılsın ve tekrar denensin mi?</translatio </message> <message> <source>SSH Agent</source> - <translation>SSH Aracısı</translation> + <translation>SSH İstemcisi</translation> </message> <message> <source>n/a</source> @@ -1893,7 +1897,7 @@ Güvenli kaydetme devre dışı bırakılsın ve tekrar denensin mi?</translatio </message> <message> <source>Remove key from agent after</source> - <translation>Sonra ajandan anahtarı kaldır</translation> + <translation>Anahtarı istemciden sonra kaldır</translation> </message> <message> <source> seconds</source> @@ -1905,7 +1909,7 @@ Güvenli kaydetme devre dışı bırakılsın ve tekrar denensin mi?</translatio </message> <message> <source>Remove key from agent when database is closed/locked</source> - <translation>Veritabanı kapalı/kilitliyken ajandan anahtarı kaldır</translation> + <translation>Veritabanı kapalı/kilitliyken istemciden anahtarı kaldır</translation> </message> <message> <source>Public key</source> @@ -1913,7 +1917,7 @@ Güvenli kaydetme devre dışı bırakılsın ve tekrar denensin mi?</translatio </message> <message> <source>Add key to agent when database is opened/unlocked</source> - <translation>Veritabanı kapalı/kilitliyken ajana anahtarı ekle</translation> + <translation>Veritabanı kapalı/kilitliyken istemciye anahtar ekle</translation> </message> <message> <source>Comment</source> @@ -2076,15 +2080,15 @@ Güvenli kaydetme devre dışı bırakılsın ve tekrar denensin mi?</translatio </message> <message> <source>The export container %1 is already referenced.</source> - <translation type="unfinished"/> + <translation>%1 dışa aktarma kapsayıcı zaten referans alındı.</translation> </message> <message> <source>The import container %1 is already imported.</source> - <translation type="unfinished"/> + <translation>%1 içe aktarma kapsayıcı zaten içe aktarıldı</translation> </message> <message> <source>The container %1 imported and export by different groups.</source> - <translation type="unfinished"/> + <translation>%1 kapsayıcı, farklı kümelere göre içe ve dışa aktarıldı.</translation> </message> </context> <context> @@ -2190,7 +2194,7 @@ Güvenli kaydetme devre dışı bırakılsın ve tekrar denensin mi?</translatio </message> <message numerus="yes"> <source>This icon is used by %n entry(s), and will be replaced by the default icon. Are you sure you want to delete it?</source> - <translation><numerusform>Bu simge %n girişi tarafından kullanılır ve varsayılan simge ile değiştirilir. Silmek istediğinize emin misiniz?</numerusform><numerusform>Bu simge %n girişi tarafından kullanılır ve varsayılan simge ile değiştirilir. Silmek istediğinize emin misiniz?</numerusform></translation> + <translation><numerusform>Bu simge %n girişi tarafından kullanılır ve öntanımlı simge ile değiştirilir. Silmek istediğinize emin misiniz?</numerusform><numerusform>Bu simge %n girişi tarafından kullanılır ve öntanımlı simge ile değiştirilir. Silmek istediğinize emin misiniz?</numerusform></translation> </message> </context> <context> @@ -2449,7 +2453,7 @@ Bu etkilenen eklentilerin bozulmasına neden olabilir.</translation> </message> <message> <source>Expiration</source> - <translation>Geçerlilik</translation> + <translation>Süre bitimi</translation> </message> <message> <source>URL</source> @@ -2594,7 +2598,7 @@ Bu etkilenen eklentilerin bozulmasına neden olabilir.</translation> </message> <message> <source>Wrong key or database file is corrupt.</source> - <translation>Yanlış anahtar veya veri tabanı dosyası bozuk.</translation> + <translation>Yanlış anahtar veya veritabanı dosyası bozuk.</translation> </message> <message> <source>missing database headers</source> @@ -2632,7 +2636,7 @@ Bu etkilenen eklentilerin bozulmasına neden olabilir.</translation> <name>Kdbx4Reader</name> <message> <source>missing database headers</source> - <translation>eksik veri tabanı başlıkları</translation> + <translation>eksik veritabanı başlıkları</translation> </message> <message> <source>Unable to calculate master key</source> @@ -2648,7 +2652,7 @@ Bu etkilenen eklentilerin bozulmasına neden olabilir.</translation> </message> <message> <source>Wrong key or database file is corrupt. (HMAC mismatch)</source> - <translation>Yanlış anahtar veya veri tabanı dosyası bozuk. (HMAC uyuşmuyor)</translation> + <translation>Yanlış anahtar veya veritabanı dosyası bozuk. (HMAC uyuşmuyor)</translation> </message> <message> <source>Unknown cipher</source> @@ -2812,21 +2816,21 @@ Bu etkilenen eklentilerin bozulmasına neden olabilir.</translation> </message> <message> <source>Not a KeePass database.</source> - <translation>KeePass veri tabanı değil.</translation> + <translation>KeePass veritabanı değil.</translation> </message> <message> <source>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.</source> - <translation>Seçilen dosya eski bir KeePass1 veri tabanıdır (.kdb). + <translation>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.</translation> +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.</translation> </message> <message> <source>Unsupported KeePass 2 database version.</source> - <translation>Desteklenmeyen KeePass 2 veri tabanı sürümü.</translation> + <translation>Desteklenmeyen KeePass 2 veritabanı sürümü.</translation> </message> <message> <source>Invalid cipher uuid length: %1 (length=%2)</source> @@ -2853,7 +2857,7 @@ Bu tek yönlü bir yer değiştirmedir. İçe aktarılan veri tabanını eski Ke </message> <message> <source>Missing icon uuid or data</source> - <translation>Simge uuid'si veya verisi eksik</translation> + <translation>Simge UUID'si veya verisi eksik</translation> </message> <message> <source>Missing custom data key or value</source> @@ -2885,15 +2889,15 @@ Bu tek yönlü bir yer değiştirmedir. İçe aktarılan veri tabanını eski Ke </message> <message> <source>Null DeleteObject uuid</source> - <translation>Boş "DeleteObject" "uuid"</translation> + <translation>Boş "DeleteObject" UUID</translation> </message> <message> <source>Missing DeletedObject uuid or time</source> - <translation>Hatalı "DeleteObject" evrensel benzersiz tanımlayıcı "uuid" veya zamanı</translation> + <translation>DeletedObject UUID veya zaman eksik</translation> </message> <message> <source>Null entry uuid</source> - <translation>Boş evrensel benzersiz tanımlayıcı "uuid" girdisi</translation> + <translation>Boş UUID girdisi</translation> </message> <message> <source>Invalid entry icon number</source> @@ -2905,12 +2909,11 @@ Bu tek yönlü bir yer değiştirmedir. İçe aktarılan veri tabanını eski Ke </message> <message> <source>No entry uuid found</source> - <translation> -Evrensel benzersiz tanımlayıcı "uuid" girdisi bulunamadı</translation> + <translation>UUID girdisi bulunamadı</translation> </message> <message> <source>History element with different uuid</source> - <translation>Farklı evrensel benzersiz tanımlayıcı "uuid" ile geçmiş öğesi</translation> + <translation>Farklı UUID ile tarih elemanı</translation> </message> <message> <source>Duplicate custom attribute found</source> @@ -2954,7 +2957,7 @@ Evrensel benzersiz tanımlayıcı "uuid" girdisi bulunamadı</translat </message> <message> <source>Invalid uuid value</source> - <translation>Geçersiz Evrensel Benzersiz Tanımlayıcı "uuid" değeri</translation> + <translation>Geçersiz UUID değeri</translation> </message> <message> <source>Unable to decompress binary</source> @@ -2974,11 +2977,11 @@ Satır %2, sütun %3</translation> <name>KeePass1OpenWidget</name> <message> <source>Import KeePass1 database</source> - <translation>KeePass1 veri tabanı içe aktar</translation> + <translation>KeePass1 veritabanı içe aktar</translation> </message> <message> <source>Unable to open the database.</source> - <translation>Veri tabanı açılamıyor.</translation> + <translation>Veritabanı açılamıyor.</translation> </message> </context> <context> @@ -2989,7 +2992,7 @@ Satır %2, sütun %3</translation> </message> <message> <source>Not a KeePass database.</source> - <translation>KeePass veri tabanı değil.</translation> + <translation>KeePass veritabanı değil.</translation> </message> <message> <source>Unsupported encryption algorithm.</source> @@ -2997,7 +3000,7 @@ Satır %2, sütun %3</translation> </message> <message> <source>Unsupported KeePass database version.</source> - <translation>Desteklenmeyen KeePass veri tabanı sürümü.</translation> + <translation>Desteklenmeyen KeePass veritabanı sürümü.</translation> </message> <message> <source>Unable to read encryption IV</source> @@ -3038,7 +3041,7 @@ Satır %2, sütun %3</translation> </message> <message> <source>Wrong key or database file is corrupt.</source> - <translation>Yanlış anahtar veya veri tabanı dosyası bozuk.</translation> + <translation>Yanlış anahtar veya veritabanı dosyası bozuk.</translation> </message> <message> <source>Key transformation failed</source> @@ -3157,19 +3160,19 @@ Satır %2, sütun %3</translation> </message> <message> <source>Disabled share %1</source> - <translation type="unfinished"/> + <translation>Paylaşım devre dışı %1</translation> </message> <message> <source>Import from share %1</source> - <translation type="unfinished"/> + <translation>%1 paylaşımından içe aktar</translation> </message> <message> <source>Export to share %1</source> - <translation type="unfinished"/> + <translation>%1 paylaşımına aktar</translation> </message> <message> <source>Synchronize with share %1</source> - <translation type="unfinished"/> + <translation>%1 paylaşımına eşitle</translation> </message> </context> <context> @@ -3255,7 +3258,7 @@ Message: %2</source> </message> <message> <source>All files</source> - <translation>Bütün dosyalar</translation> + <translation>Tüm dosyalar</translation> </message> <message> <source>Create Key File...</source> @@ -3278,11 +3281,11 @@ Message: %2</source> <name>MainWindow</name> <message> <source>&Database</source> - <translation>&Veri tabanı</translation> + <translation>&Veritabanı</translation> </message> <message> <source>&Recent databases</source> - <translation>&Son veri tabanları</translation> + <translation>&Son veritabanları</translation> </message> <message> <source>&Help</source> @@ -3310,15 +3313,15 @@ Message: %2</source> </message> <message> <source>&Open database...</source> - <translation>&Veri tabanı aç...</translation> + <translation>&Veritabanı aç...</translation> </message> <message> <source>&Save database</source> - <translation>Veri tabanını k&aydet</translation> + <translation>Veritabanını k&aydet</translation> </message> <message> <source>&Close database</source> - <translation>Veri tabanını &kapat</translation> + <translation>Veritabanını &kapat</translation> </message> <message> <source>&Delete entry</source> @@ -3334,11 +3337,11 @@ Message: %2</source> </message> <message> <source>Sa&ve database as...</source> - <translation>Veri tabanını farklı ka&ydet...</translation> + <translation>Veritabanını farklı ka&ydet...</translation> </message> <message> <source>Database settings</source> - <translation>Veri tabnı ayarları</translation> + <translation>Veritabanı ayarları</translation> </message> <message> <source>&Clone entry</source> @@ -3362,11 +3365,11 @@ Message: %2</source> </message> <message> <source>Password Generator</source> - <translation>Parola Oluşturucu</translation> + <translation>Parola oluşturucu</translation> </message> <message> <source>&Lock databases</source> - <translation>Veri tabanlarını &kilitle</translation> + <translation>Veritabanlarını &kilitle</translation> </message> <message> <source>&Title</source> @@ -3476,7 +3479,7 @@ Keepassxc indirme sayfasında mevcut Appımage kullanmanızı öneririz.</transl </message> <message> <source>&Merge from database...</source> - <translation>Veritabanından &birleştir ...</translation> + <translation>Veritabanından &birleştir...</translation> </message> <message> <source>Merge from another KDBX database</source> @@ -3516,7 +3519,7 @@ Keepassxc indirme sayfasında mevcut Appımage kullanmanızı öneririz.</transl </message> <message> <source>Copy &password</source> - <translation>Kopyala &parola</translation> + <translation>&Parolayı kopyala</translation> </message> <message> <source>Perform &Auto-Type</source> @@ -3593,7 +3596,7 @@ Bazı hatalar ve küçük sorunlar olabilir, bu sürüm şu an dağıtımda değ </message> <message> <source>older entry merged from database "%1"</source> - <translation>eski giriş "%1" veritabanından birleştirildi</translation> + <translation>eski giriş "%1" veritabanıyla birleştirildi</translation> </message> <message> <source>Adding backup for older target %1 [%2]</source> @@ -3668,7 +3671,7 @@ Bazı hatalar ve küçük sorunlar olabilir, bu sürüm şu an dağıtımda değ </message> <message> <source>Simple Settings</source> - <translation>Temel Ayarlar</translation> + <translation>Basit Ayarlar</translation> </message> </context> <context> @@ -4159,15 +4162,15 @@ Bazı hatalar ve küçük sorunlar olabilir, bu sürüm şu an dağıtımda değ </message> <message> <source>Add a new entry to a database.</source> - <translation>Veri tabanına yeni girdi ekle.</translation> + <translation>Veritabanına yeni girdi ekle.</translation> </message> <message> <source>Path of the database.</source> - <translation>Veri tabanının yolu.</translation> + <translation>Veritabanının yolu.</translation> </message> <message> <source>Key file of the database.</source> - <translation>Veri tabanının anahtar dosyası.</translation> + <translation>Veritabanının anahtar dosyası.</translation> </message> <message> <source>path</source> @@ -4252,11 +4255,11 @@ Bazı hatalar ve küçük sorunlar olabilir, bu sürüm şu an dağıtımda değ </message> <message> <source>Extract and print the content of a database.</source> - <translation>Veri tabanının içeriğini çıkar ve yazdır.</translation> + <translation>Veritabanının içeriğini çıkar ve yazdır.</translation> </message> <message> <source>Path of the database to extract.</source> - <translation>Veri tabanının çıkarılacağı yol.</translation> + <translation>Veritabanının çıkarılacağı yol.</translation> </message> <message> <source>Insert password to unlock %1: </source> @@ -4328,7 +4331,7 @@ Kullanılabilir komutlar: </message> <message> <source>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.</source> - <translation>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.</translation> + <translation>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.</translation> </message> <message> <source>attribute</source> @@ -4340,7 +4343,7 @@ Kullanılabilir komutlar: </message> <message> <source>NULL device</source> - <translation>NULL aygıtı</translation> + <translation>Geçersiz aygıt</translation> </message> <message> <source>error reading from device</source> @@ -4400,7 +4403,7 @@ Kullanılabilir komutlar: </message> <message> <source>SSH Agent</source> - <translation>SSH Aracısı</translation> + <translation>SSH İstemcisi</translation> </message> <message> <source>Generate a new random diceware passphrase.</source> @@ -4414,11 +4417,11 @@ Kullanılabilir komutlar: <source>Wordlist for the diceware generator. [Default: EFF English]</source> <translation>Diceware oluşturucu için Kelime Listesi. -[Varsayılan: EFF İngilizce]</translation> +[Öntanımlı: EFF İngilizce]</translation> </message> <message> <source>Generate a new random password.</source> - <translation>Yeni bir karışık şifre oluştur.</translation> + <translation>Yeni bir karışık parola oluştur.</translation> </message> <message> <source>Invalid value for password length %1.</source> @@ -4495,7 +4498,7 @@ Kullanılabilir komutlar: </message> <message> <source>Enter new password for entry: </source> - <translation>Girdi için yeni şifre girin: </translation> + <translation>Girdi için yeni parola gir: </translation> </message> <message> <source>Writing the database failed: %1</source> @@ -4759,7 +4762,7 @@ Kullanılabilir komutlar: </message> <message> <source>Message encryption failed.</source> - <translation>Mesaj şifreleme başarısız.</translation> + <translation>İleti şifreleme başarısız.</translation> </message> <message> <source>No groups found</source> @@ -4859,7 +4862,7 @@ Kullanılabilir komutlar: </message> <message> <source>Cannot create new group</source> - <translation type="unfinished"/> + <translation>Yeni küme oluşturulamıyor</translation> </message> </context> <context> @@ -5119,7 +5122,7 @@ Kullanılabilir komutlar: </message> <message> <source>All files</source> - <translation>Bütün dosyalar</translation> + <translation>Tüm dosyalar</translation> </message> <message> <source>Select path</source> @@ -5135,7 +5138,7 @@ Kullanılabilir komutlar: </message> <message> <source>Signer:</source> - <translation type="unfinished"/> + <translation>İmzalayan:</translation> </message> </context> <context> @@ -5258,27 +5261,27 @@ Kullanılabilir komutlar: </message> <message> <source>Multiple import source path to %1 in %2</source> - <translation type="unfinished"/> + <translation>%2 içinde %1'e çoklu içe aktarma kaynak yolu</translation> </message> <message> <source>Conflicting export target path %1 in %2</source> - <translation type="unfinished"/> + <translation>Çakışan aktarma hedef yolu %1 %2</translation> </message> <message> <source>Could not embed signature: Could not open file to write (%1)</source> - <translation type="unfinished"/> + <translation>İmza gömülemedi: Yazılacak dosya açılamadı (%1)</translation> </message> <message> <source>Could not embed signature: Could not write file (%1)</source> - <translation type="unfinished"/> + <translation>İmza gömülemedi: Dosya yazılamadı (%1)</translation> </message> <message> <source>Could not embed database: Could not open file to write (%1)</source> - <translation type="unfinished"/> + <translation>Veritabanı gömülemedi: Yazılacak dosya açılamadı (%1)</translation> </message> <message> <source>Could not embed database: Could not write file (%1)</source> - <translation type="unfinished"/> + <translation>Veritabanı gömülemedi: dosya yazılamadı (%1)</translation> </message> </context> <context> @@ -5332,7 +5335,7 @@ Kullanılabilir komutlar: </message> <message> <source>Default RFC 6238 token settings</source> - <translation>Varsayılan RFC 6238 anahtar ayarları</translation> + <translation>Öntanımlı RFC 6238 anahtar ayarları</translation> </message> <message> <source>Steam token settings</source> @@ -5427,7 +5430,7 @@ Kullanılabilir komutlar: <name>WelcomeWidget</name> <message> <source>Start storing your passwords securely in a KeePassXC database</source> - <translation>Parolalarınızı KeePassXC veri tabanında güvenle depolamaya başlayın</translation> + <translation>Parolalarınızı KeePassXC veritabanında güvenle depolamaya başlayın</translation> </message> <message> <source>Create new database</source> @@ -5462,11 +5465,11 @@ Kullanılabilir komutlar: </message> <message> <source>YubiKey Challenge-Response</source> - <translation>YubiKey Challenge-Response</translation> + <translation>YubiKey Karşılama Yanıtı</translation> </message> <message> <source><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></source> - <translation><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></translation> + <translation><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></translation> </message> <message> <source>No YubiKey detected, please ensure it's plugged in.</source> 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.</source> </message> <message> <source>Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1</source> - <translation type="unfinished"/> + <translation>Через заходи безпеки у Snap Вам необхідно виконати сценарій для сполучення з переглядачем. <br />Ви можете знайти файл сценарію у %1</translation> </message> <message> <source>Please see special instructions for browser extension use below</source> - <translation type="unfinished"/> + <translation>Нижче Ви можете знайти інструкції для використання додатку для браузера</translation> </message> <message> <source>KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3</source> - <translation type="unfinished"/> + <translation>Для сполучення з переглядачем необхідний KeePassXC-Browser. <br />Завантажте його для %1 та %2. %3</translation> </message> </context> <context> @@ -696,19 +696,23 @@ Moved %2 keys to custom data.</source> </message> <message> <source>KeePassXC: Create a new group</source> - <translation type="unfinished"/> + <translation>KeePassXC: Створити нову групу</translation> </message> <message> <source>A request for creating a new group "%1" has been received. Do you want to create this group? </source> - <translation type="unfinished"/> + <translation>Отримано запит для створення нової групи "%1". +Ви хочете створити цю групу? +</translation> </message> <message> <source>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?</source> - <translation type="unfinished"/> + <translation>Ваші параметри KeePassXC-Переглядача мають бути переміщені до параметрів сховища. +Це необхідно для підтримання сполучень з Вашим поточним переглядачем. +Бажаєте перемістити параметри зараз?</translation> </message> </context> <context> @@ -872,7 +876,7 @@ Would you like to migrate your existing settings now?</source> </message> <message> <source>Key not transformed. This is a bug, please report it to the developers!</source> - <translation type="unfinished"/> + <translation>Ключ не перетворено через ваду в програмі. Будь ласка, повідомте про це розробникам!</translation> </message> </context> <context> @@ -1631,7 +1635,7 @@ Disable safe saves and try again?</source> </message> <message> <source>Shared group...</source> - <translation type="unfinished"/> + <translation>Спільна група...</translation> </message> </context> <context> @@ -2076,15 +2080,15 @@ Disable safe saves and try again?</source> </message> <message> <source>The export container %1 is already referenced.</source> - <translation type="unfinished"/> + <translation>На експортну оболонку %1 вже існує посилання.</translation> </message> <message> <source>The import container %1 is already imported.</source> - <translation type="unfinished"/> + <translation>Оболонку %1 вже імпортовано.</translation> </message> <message> <source>The container %1 imported and export by different groups.</source> - <translation type="unfinished"/> + <translation>Оболонку %1 імпортують та експортують різні групи.</translation> </message> </context> <context> @@ -3157,19 +3161,19 @@ Line %2, column %3</source> </message> <message> <source>Disabled share %1</source> - <translation type="unfinished"/> + <translation>Вимкнутий спільний ресурс %1</translation> </message> <message> <source>Import from share %1</source> - <translation type="unfinished"/> + <translation>Імпортувати зі спільного ресурсу %1</translation> </message> <message> <source>Export to share %1</source> - <translation type="unfinished"/> + <translation>Експортувати до спільного ресурсу %1</translation> </message> <message> <source>Synchronize with share %1</source> - <translation type="unfinished"/> + <translation>Узгодити зі спільним ресурсом %1</translation> </message> </context> <context> @@ -4858,7 +4862,7 @@ Available commands: </message> <message> <source>Cannot create new group</source> - <translation type="unfinished"/> + <translation>Неможливо створити нову групу</translation> </message> </context> <context> @@ -5134,7 +5138,7 @@ Available commands: </message> <message> <source>Signer:</source> - <translation type="unfinished"/> + <translation>Підписувач:</translation> </message> </context> <context> @@ -5253,31 +5257,31 @@ Available commands: </message> <message> <source>Do you want to trust %1 with the fingerprint of %2 from %3?</source> - <translation type="unfinished"/> + <translation>Довірити %1, що має відбиток %2 з %3? {1 ?} {2 ?}</translation> </message> <message> <source>Multiple import source path to %1 in %2</source> - <translation type="unfinished"/> + <translation>Шлях до %1 має декілька джерел імпорту в %2.</translation> </message> <message> <source>Conflicting export target path %1 in %2</source> - <translation type="unfinished"/> + <translation>Суперечливий шлях для експорту %1 у %2</translation> </message> <message> <source>Could not embed signature: Could not open file to write (%1)</source> - <translation type="unfinished"/> + <translation>Неможливо вкласти підпис: неможливо відкрити файл для запису (%1)</translation> </message> <message> <source>Could not embed signature: Could not write file (%1)</source> - <translation type="unfinished"/> + <translation>Неможливо вкласти підпис: неможливо записати файл (%1)</translation> </message> <message> <source>Could not embed database: Could not open file to write (%1)</source> - <translation type="unfinished"/> + <translation>Неможливо вкласти сховище: неможливо відкрити файл для запису (%1)</translation> </message> <message> <source>Could not embed database: Could not write file (%1)</source> - <translation type="unfinished"/> + <translation>Неможливо вкласти сховище: неможливо записати файл (%1)</translation> </message> </context> <context> 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.</source> </message> <message> <source>Due to Snap sandboxing, you must run a script to enable browser integration.<br />You can obtain this script from %1</source> - <translation type="unfinished"/> + <translation>由于快照沙盒,必须运行脚本才能启用浏览器集成。<br />您可以从 %1 获取此脚本</translation> </message> <message> <source>Please see special instructions for browser extension use below</source> - <translation type="unfinished"/> + <translation>请参阅下面的浏览器扩展使用的特殊说明</translation> </message> <message> <source>KeePassXC-Browser is needed for the browser integration to work. <br />Download it for %1 and %2. %3</source> - <translation type="unfinished"/> + <translation>浏览器集成需要KeePassXC-Browser才能工作。<br />下载%1 和 %2. %3</translation> </message> </context> <context> @@ -696,19 +696,22 @@ Moved %2 keys to custom data.</source> </message> <message> <source>KeePassXC: Create a new group</source> - <translation type="unfinished"/> + <translation>keepassxc: 创建新群组</translation> </message> <message> <source>A request for creating a new group "%1" has been received. Do you want to create this group? </source> - <translation type="unfinished"/> + <translation>已收到创建新群组 "%1" 的请求。 +是否要创建此群组?</translation> </message> <message> <source>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?</source> - <translation type="unfinished"/> + <translation>您的keepassxc浏览器设置需要移动到数据库设置中。 +这是保持当前浏览器连接所必需的。 +是否要立即迁移现有设置?</translation> </message> </context> <context> @@ -872,7 +875,7 @@ Would you like to migrate your existing settings now?</source> </message> <message> <source>Key not transformed. This is a bug, please report it to the developers!</source> - <translation type="unfinished"/> + <translation>密钥未转换。这是一个bug,请报告给开发者!</translation> </message> </context> <context> @@ -1630,7 +1633,7 @@ Disable safe saves and try again?</source> </message> <message> <source>Shared group...</source> - <translation type="unfinished"/> + <translation>共享群组...</translation> </message> </context> <context> @@ -2075,15 +2078,15 @@ Disable safe saves and try again?</source> </message> <message> <source>The export container %1 is already referenced.</source> - <translation type="unfinished"/> + <translation>导出容器 %1 已被引用。</translation> </message> <message> <source>The import container %1 is already imported.</source> - <translation type="unfinished"/> + <translation>导入容器 %1 已导入。</translation> </message> <message> <source>The container %1 imported and export by different groups.</source> - <translation type="unfinished"/> + <translation>容器 %1 由不同的群组导入和导出。</translation> </message> </context> <context> @@ -3151,19 +3154,19 @@ Line %2, column %3</source> </message> <message> <source>Disabled share %1</source> - <translation type="unfinished"/> + <translation>已禁用共享 %1</translation> </message> <message> <source>Import from share %1</source> - <translation type="unfinished"/> + <translation>从共享 %1 导入</translation> </message> <message> <source>Export to share %1</source> - <translation type="unfinished"/> + <translation>导出到共享 %1</translation> </message> <message> <source>Synchronize with share %1</source> - <translation type="unfinished"/> + <translation>与共享 %1 同步</translation> </message> </context> <context> @@ -4853,7 +4856,7 @@ Available commands: </message> <message> <source>Cannot create new group</source> - <translation type="unfinished"/> + <translation>无法创建新群组</translation> </message> </context> <context> @@ -5129,7 +5132,7 @@ Available commands: </message> <message> <source>Signer:</source> - <translation type="unfinished"/> + <translation>签名:</translation> </message> </context> <context> @@ -5252,27 +5255,27 @@ Available commands: </message> <message> <source>Multiple import source path to %1 in %2</source> - <translation type="unfinished"/> + <translation>多个导入源路径到 %1 in %2</translation> </message> <message> <source>Conflicting export target path %1 in %2</source> - <translation type="unfinished"/> + <translation>冲突的导出目标路径 %1 in %2</translation> </message> <message> <source>Could not embed signature: Could not open file to write (%1)</source> - <translation type="unfinished"/> + <translation>无法嵌入签名:无法打开要写入的文件 (%1)</translation> </message> <message> <source>Could not embed signature: Could not write file (%1)</source> - <translation type="unfinished"/> + <translation>无法嵌入签名:无法写入文件 (%1)</translation> </message> <message> <source>Could not embed database: Could not open file to write (%1)</source> - <translation type="unfinished"/> + <translation>无法嵌入数据库:无法打开要写入的文件 (%1)</translation> </message> <message> <source>Could not embed database: Could not write file (%1)</source> - <translation type="unfinished"/> + <translation>无法嵌入数据库:无法写入文件 (%1)</translation> </message> </context> <context> diff --git a/snapcraft.yaml b/snapcraft.yaml index 16eb0890d..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: | @@ -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 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 110dc606c..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() @@ -293,6 +294,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/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/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/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 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. <br />Download it for %1 and %2. %3") .arg("<a href=\"https://addons.mozilla.org/en-US/firefox/addon/keepassxc-browser/\">Firefox</a>", "<a href=\"https://chrome.google.com/webstore/detail/keepassxc-browser/oboonakemofpalcgghocfoadofidjkkk\">" - "Google Chrome / Chromium / Vivaldi</a>", + "Google Chrome / Chromium / Vivaldi / Brave</a>", 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 @@ </property> </widget> </item> + <item row="1" column="2"> + <widget class="QCheckBox" name="braveSupport"> + <property name="text"> + <string>&Brave</string> + </property> + <property name="checked"> + <bool>false</bool> + </property> + </widget> + </item> </layout> </widget> </item> 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<SupportedBrowsers>(i))) { installBrowser(static_cast<SupportedBrowsers>(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/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/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() 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<QString, Command*> 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<CompositeKey>::create(); - QString line = Utils::getPassword(parser.isSet(Command::QuietOption) ? Utils::DEVNULL : Utils::STDOUT); - auto passwordKey = QSharedPointer<PasswordKey>::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<PasswordKey>::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<Database> 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<Database> 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<PasswordKey>::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<PasswordKey>::create(); + passwordKey->setPassword(line); + compositeKey->addKey(passwordKey); + } if (!keyFilename.isEmpty()) { auto fileKey = QSharedPointer<FileKey>::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<Database> 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 22cf88a3a..bd7f5d5c5 100644 --- a/src/cli/keepassxc-cli.1 +++ b/src/cli/keepassxc-cli.1 @@ -56,9 +56,15 @@ 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 <path>" 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 <path>" Silence password prompt and other secondary outputs. @@ -66,7 +72,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" @@ -74,6 +80,9 @@ Shows the program version. .IP "-f, --key-file-from <path>" 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/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/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/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/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/core/Database.cpp b/src/core/Database.cpp index 22484cb80..ee888327b 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(); } @@ -241,27 +242,34 @@ 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)) { - // successfully saved database file + + // 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 the database tempFile.setAutoRemove(false); setFilePath(filePath); return true; + } 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; } -#endif } + if (error) { *error = tempFile.errorString(); } } // Saving failed + markAsModified(); return false; } @@ -320,6 +328,28 @@ bool Database::backupDatabase(const QString& filePath) return QFile::copy(filePath, backupFilePath); } +/** + * Restores the database file from the backup file with + * name <filename>.old.<extension> 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); + // 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 { return m_data.isReadOnly; @@ -388,11 +418,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..27bb3e4a5 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(); @@ -171,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/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<QString, bool>& 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<QString, qint64>& 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<QString, bool>& watchedFiles = m_watchedFilesInDirectory[directoryPath]; + QMap<QString, qint64>& 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<int>(current.msecsTo(m_ignoreFilesChangess[key])); + timeout = qMin(timeout, static_cast<int>(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<QString, bool> m_watchedPaths; - QMap<QString, QDateTime> m_ignoreFilesChangess; + QMap<QString, QDateTime> m_watchedFilesIgnored; QFileSystemWatcher m_fileWatcher; - QMap<QString, QMap<QString, bool>> m_watchedFilesInDirectory; + QMap<QString, QMap<QString, qint64>> 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<QString, QList<Signal>> m_pendingSignals; 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/core/Tools.cpp b/src/core/Tools.cpp index b77a460d4..46cde95bc 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 <QLocale> #include <QRegularExpression> #include <QStringList> +#include <QSysInfo> #include <QUuid> #include <cctype> +#include "git-info.h" #ifdef Q_OS_WIN #include <windows.h> // 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; @@ -129,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/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/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 <sys/types.h> -#ifdef _WIN32 +#if defined(_WIN32) || defined(__HAIKU__) #include <stdint.h> typedef uint32_t u_int32_t; 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/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<quint64>(secsBytes, KeePass2::BYTEORDER); return QDateTime(QDate(1, 1, 1), QTime(0, 0, 0, 0), Qt::UTC).addSecs(secs); 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/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 <QClipboard> -#include <QSysInfo> + static const QString aboutMaintainers = R"( <p><ul> @@ -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/gui/ApplicationSettingsWidget.cpp b/src/gui/ApplicationSettingsWidget.cpp index 90b851bd9..22a49dece 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))); @@ -91,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 @@ -294,11 +302,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 +340,25 @@ 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); +} + +void ApplicationSettingsWidget::checkUpdatesToggled(bool checked) +{ + m_generalUi->checkForUpdatesIncludeBetasCheckBox->setEnabled(checked); +} diff --git a/src/gui/ApplicationSettingsWidget.h b/src/gui/ApplicationSettingsWidget.h index ffcfea2be..dfffbddbd 100644 --- a/src/gui/ApplicationSettingsWidget.h +++ b/src/gui/ApplicationSettingsWidget.h @@ -55,7 +55,9 @@ private slots: void reject(); void autoSaveToggled(bool checked); void systrayToggled(bool checked); - void enableToolbarSettings(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 798971bfe..9f03bbb50 100644 --- a/src/gui/ApplicationSettingsWidgetGeneral.ui +++ b/src/gui/ApplicationSettingsWidgetGeneral.ui @@ -50,19 +50,16 @@ </widget> </item> <item> - <widget class="QCheckBox" name="rememberLastDatabasesCheckBox"> + <widget class="QCheckBox" name="systrayMinimizeOnStartup"> <property name="text"> - <string>Remember last databases</string> - </property> - <property name="checked"> - <bool>true</bool> + <string>Minimize window at application startup</string> </property> </widget> </item> <item> - <widget class="QCheckBox" name="rememberLastKeyFilesCheckBox"> + <widget class="QCheckBox" name="rememberLastDatabasesCheckBox"> <property name="text"> - <string>Remember last key files and security dongles</string> + <string>Remember previously used databases</string> </property> <property name="checked"> <bool>true</bool> @@ -70,26 +67,114 @@ </widget> </item> <item> - <widget class="QCheckBox" name="openPreviousDatabasesOnStartupCheckBox"> - <property name="text"> - <string>Load previous databases on startup</string> + <layout class="QHBoxLayout" name="rememberDbSubLayout_2"> + <property name="spacing"> + <number>0</number> </property> - </widget> + <property name="sizeConstraint"> + <enum>QLayout::SetMaximumSize</enum> + </property> + <item> + <spacer name="toolbarMovableSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QCheckBox" name="openPreviousDatabasesOnStartupCheckBox"> + <property name="text"> + <string>Load previously open databases on startup</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> </item> <item> - <widget class="QCheckBox" name="systrayMinimizeOnStartup"> - <property name="text"> - <string>Minimize window at application startup</string> + <layout class="QHBoxLayout" name="rememberDbSubLayout"> + <property name="spacing"> + <number>0</number> </property> - </widget> + <property name="sizeConstraint"> + <enum>QLayout::SetMaximumSize</enum> + </property> + <item> + <spacer name="toolbarMovableSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QCheckBox" name="rememberLastKeyFilesCheckBox"> + <property name="text"> + <string>Remember database key files and security dongles</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> </item> <item> <widget class="QCheckBox" name="checkForUpdatesOnStartupCheckBox"> <property name="text"> - <string>Check for updates at application startup</string> + <string>Check for updates at application startup once per week</string> </property> </widget> </item> + <item> + <layout class="QHBoxLayout" name="checkUpdatesSubLayout"> + <property name="spacing"> + <number>0</number> + </property> + <item> + <spacer name="checkUpdatesSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QCheckBox" name="checkForUpdatesIncludeBetasCheckBox"> + <property name="text"> + <string>Include beta releases when checking for updates</string> + </property> + </widget> + </item> + </layout> + </item> </layout> </widget> </item> @@ -187,13 +272,6 @@ </property> <layout class="QVBoxLayout" name="verticalLayout_7"> <item> - <widget class="QCheckBox" name="checkForUpdatesIncludeBetasCheckBox"> - <property name="text"> - <string>Include pre-releases when checking for updates</string> - </property> - </widget> - </item> - <item> <widget class="QCheckBox" name="toolbarHideCheckBox"> <property name="text"> <string>Hide toolbar (icons)</string> @@ -218,7 +296,7 @@ </property> <property name="sizeHint" stdset="0"> <size> - <width>40</width> + <width>20</width> <height>20</height> </size> </property> @@ -245,7 +323,7 @@ <item> <layout class="QHBoxLayout" name="toolButtonStyleLayout"> <property name="spacing"> - <number>15</number> + <number>0</number> </property> <item> <spacer name="toolButtonStyleSpacer"> @@ -257,7 +335,7 @@ </property> <property name="sizeHint" stdset="0"> <size> - <width>40</width> + <width>20</width> <height>20</height> </size> </property> @@ -274,8 +352,11 @@ <verstretch>0</verstretch> </sizepolicy> </property> + <property name="styleSheet"> + <string notr="true">margin-right: 5px</string> + </property> <property name="text"> - <string>Button style</string> + <string>Button style:</string> </property> </widget> </item> @@ -326,7 +407,7 @@ </property> <property name="sizeHint" stdset="0"> <size> - <width>40</width> + <width>20</width> <height>20</height> </size> </property> @@ -377,7 +458,7 @@ </property> <property name="sizeHint" stdset="0"> <size> - <width>40</width> + <width>20</width> <height>20</height> </size> </property> @@ -407,18 +488,18 @@ <item> <layout class="QHBoxLayout" name="languageLabelLayout_2"> <property name="spacing"> - <number>15</number> + <number>8</number> </property> <item alignment="Qt::AlignRight"> <widget class="QLabel" name="languageLabel_2"> <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="text"> - <string>Language</string> + <string>Language:</string> </property> </widget> </item> @@ -432,6 +513,13 @@ </property> </widget> </item> + <item> + <widget class="QLabel" name="languageLabel_3"> + <property name="text"> + <string>(restart program to activate)</string> + </property> + </widget> + </item> </layout> </item> </layout> diff --git a/src/gui/DatabaseOpenWidget.cpp b/src/gui/DatabaseOpenWidget.cpp index 155846640..ced72485e 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<Database> 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(); } @@ -191,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()); @@ -202,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; } @@ -231,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 @@ -276,7 +267,7 @@ QSharedPointer<CompositeKey> 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()) { @@ -339,17 +330,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 +366,7 @@ void DatabaseOpenWidget::pollYubikey() m_ui->checkChallengeResponse->setChecked(false); m_ui->comboChallengeResponse->setEnabled(false); m_ui->comboChallengeResponse->clear(); + m_ui->comboChallengeResponse->addItem(tr("Select slot..."), -1); m_ui->yubikeyProgress->setVisible(true); // YubiKey init is slow, detect asynchronously to not block the UI @@ -388,6 +383,7 @@ void DatabaseOpenWidget::yubikeyDetected(int slot, bool blocking) QHash<QString, QVariant> 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 c908a82ec..313bfabb1 100644 --- a/src/gui/DatabaseTabWidget.cpp +++ b/src/gui/DatabaseTabWidget.cpp @@ -137,25 +137,29 @@ 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(); 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; } 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); - } + if (dbWidget && dbWidget->database()->canonicalFilePath() == canonicalFilePath) { + dbWidget->performUnlockDatabase(password, keyfile); if (!inBackground) { // switch to existing tab if file is already open setCurrentIndex(indexOf(dbWidget)); @@ -166,9 +170,7 @@ void DatabaseTabWidget::addDatabaseTab(const QString& filePath, bool inBackgroun auto* dbWidget = new DatabaseWidget(QSharedPointer<Database>::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/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp index 8728c331f..8cfc40815 100644 --- a/src/gui/DatabaseWidget.cpp +++ b/src/gui/DatabaseWidget.cpp @@ -78,9 +78,7 @@ DatabaseWidget::DatabaseWidget(QSharedPointer<Database> 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)) @@ -89,6 +87,7 @@ DatabaseWidget::DatabaseWidget(QSharedPointer<Database> 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); @@ -260,12 +259,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<int> DatabaseWidget::mainSplitterSizes() const @@ -859,6 +857,7 @@ void DatabaseWidget::loadDatabase(bool accepted) replaceDatabase(openWidget->database()); switchToMainView(); m_fileWatcher->restart(); + m_saveAttempts = 0; emit databaseUnlocked(); } else { m_fileWatcher->stop(); @@ -1112,7 +1111,9 @@ void DatabaseWidget::search(const QString& searchtext) } m_searchingLabel->setVisible(true); +#ifdef WITH_XC_KEESHARE m_shareLabel->setVisible(false); +#endif emit searchModeActivated(); } @@ -1245,7 +1246,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?"), @@ -1510,7 +1511,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()); @@ -1525,6 +1526,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; @@ -1532,14 +1535,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?"), @@ -1550,11 +1550,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; } @@ -1583,8 +1587,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..fb9cf817e 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<Database> db); @@ -235,9 +235,7 @@ private: QPointer<EntryPreviewWidget> m_previewView; QPointer<QSplitter> m_previewSplitter; QPointer<QLabel> m_searchingLabel; -#ifdef WITH_XC_KEESHARE QPointer<QLabel> m_shareLabel; -#endif QPointer<CsvImportWizard> m_csvImportWizard; QPointer<EditEntryWidget> m_editEntryWidget; QPointer<EditGroupWidget> m_editGroupWidget; @@ -255,6 +253,8 @@ private: QUuid m_groupBeforeLock; QUuid m_entryBeforeLock; + int m_saveAttempts; + // Search state EntrySearcher* m_EntrySearcher; QString m_lastSearchText; 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<Ui::EditWidget> m_ui; bool m_readOnly; + bool m_modified; Q_DISABLE_COPY(EditWidget) }; diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 6e3c96af0..077ee796e 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" @@ -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())); @@ -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 @@ -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(); @@ -494,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<Database>::create(); - auto key = QSharedPointer<CompositeKey>::create(); - if (!pw.isEmpty()) { - key->addKey(QSharedPointer<PasswordKey>::create(pw)); - } - if (!keyFile.isEmpty()) { - auto fileKey = QSharedPointer<FileKey>::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) @@ -687,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, @@ -710,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); @@ -725,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(); @@ -920,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() @@ -1002,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 cd7b1a39b..5a72d6f02 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, @@ -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; 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 <QUrl> 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: 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 <support@dmapps.us> * Copyright (C) 2017 KeePassXC Team <team@keepassxc.org> * * 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/src/gui/dbsettings/DatabaseSettingsWidgetMasterKey.cpp b/src/gui/dbsettings/DatabaseSettingsWidgetMasterKey.cpp index d1a64b529..ed22244c7 100644 --- a/src/gui/dbsettings/DatabaseSettingsWidgetMasterKey.cpp +++ b/src/gui/dbsettings/DatabaseSettingsWidgetMasterKey.cpp @@ -77,11 +77,8 @@ void DatabaseSettingsWidgetMasterKey::load(QSharedPointer<Database> 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,11 @@ void DatabaseSettingsWidgetMasterKey::load(QSharedPointer<Database> db) setAdditionalKeyOptionsVisible(hasAdditionalKeys); - m_isDirty = isDirty; + connect(m_passwordEditWidget->findChild<QPushButton*>("removeButton"), SIGNAL(clicked()), SLOT(markDirty())); + connect(m_keyFileEditWidget->findChild<QPushButton*>("removeButton"), SIGNAL(clicked()), SLOT(markDirty())); +#ifdef WITH_XC_YUBIKEY + connect(m_yubiKeyEditWidget->findChild<QPushButton*>("removeButton"), SIGNAL(clicked()), SLOT(markDirty())); +#endif } void DatabaseSettingsWidgetMasterKey::initialize() diff --git a/src/gui/entry/EditEntryWidget.cpp b/src/gui/entry/EditEntryWidget.cpp index e57bc97d6..063f8da2c 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())); @@ -266,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 } @@ -588,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<quint32>(lifetime), confirm)) { + if (!SSHAgent::instance()->addIdentity(key, settings)) { showMessage(SSHAgent::instance()->errorString(), MessageWidget::Error); return; } @@ -693,8 +701,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) @@ -871,7 +881,6 @@ bool EditEntryWidget::commitEntry() } updateEntryData(m_entry); - setUnsavedChanges(false); if (!m_create) { m_entry->endUpdate(); @@ -886,6 +895,7 @@ bool EditEntryWidget::commitEntry() m_historyModel->setEntries(m_entry->historyItems()); showMessage(tr("Entry updated successfully."), MessageWidget::Positive); + setModified(false); return true; } @@ -958,7 +968,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"), @@ -970,19 +980,26 @@ void EditEntryWidget::cancel() } if (result == MessageBox::Save) { commitEntry(); - m_saved = true; + setModified(false); } } clear(); - emit editFinished(m_saved); + emit editFinished(!isModified()); } 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(); @@ -991,22 +1008,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) { @@ -1053,7 +1054,7 @@ void EditEntryWidget::insertAttribute() m_advancedUi->attributesView->setCurrentIndex(index); m_advancedUi->attributesView->edit(index); - setUnsavedChanges(true); + setModified(true); } void EditEntryWidget::editCurrentAttribute() @@ -1064,7 +1065,7 @@ void EditEntryWidget::editCurrentAttribute() if (index.isValid()) { m_advancedUi->attributesView->edit(index); - setUnsavedChanges(true); + setModified(true); } } @@ -1084,7 +1085,7 @@ void EditEntryWidget::removeCurrentAttribute() if (result == MessageBox::Remove) { m_entryAttributes->remove(m_attributesModel->keyByIndex(index)); - setUnsavedChanges(true); + setModified(true); } } } @@ -1185,6 +1186,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); @@ -1205,7 +1207,7 @@ void EditEntryWidget::insertAutoTypeAssoc() m_autoTypeUi->assocView->setCurrentIndex(newIndex); loadCurrentAssoc(newIndex); m_autoTypeUi->windowTitleCombo->setFocus(); - setUnsavedChanges(true); + setModified(true); } void EditEntryWidget::removeAutoTypeAssoc() @@ -1214,7 +1216,7 @@ void EditEntryWidget::removeAutoTypeAssoc() if (currentIndex.isValid()) { m_autoTypeAssoc->remove(currentIndex.row()); - setUnsavedChanges(true); + setModified(true); } } @@ -1277,7 +1279,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); } } @@ -1291,7 +1293,7 @@ void EditEntryWidget::deleteHistoryEntry() } else { m_historyUi->deleteAllButton->setEnabled(false); } - setUnsavedChanges(true); + setModified(true); } } @@ -1299,7 +1301,7 @@ void EditEntryWidget::deleteAllHistoryEntries() { m_historyModel->deleteAll(); m_historyUi->deleteAllButton->setEnabled(m_historyModel->rowCount() > 0); - setUnsavedChanges(true); + setModified(true); } QMenu* EditEntryWidget::createPresetsMenu() @@ -1352,12 +1354,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 07a4b7895..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); @@ -90,6 +89,7 @@ private slots: void protectCurrentAttribute(bool state); void revealCurrentAttribute(); void updateAutoTypeEnabled(); + void openAutotypeHelp(); void insertAutoTypeAssoc(); void removeAutoTypeAssoc(); void loadCurrentAssoc(const QModelIndex& current); @@ -105,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(); @@ -147,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/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 @@ </property> </widget> </item> + <item> + <widget class="QToolButton" name="openHelpButton"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="toolTip"> + <string>Open AutoType help webpage</string> + </property> + <property name="accessibleName"> + <string>AutoType help button</string> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> </layout> </item> <item> @@ -268,6 +284,7 @@ <tabstop>inheritSequenceButton</tabstop> <tabstop>customSequenceButton</tabstop> <tabstop>sequenceEdit</tabstop> + <tabstop>openHelpButton</tabstop> <tabstop>assocView</tabstop> <tabstop>windowTitleCombo</tabstop> <tabstop>customWindowSequenceButton</tabstop> 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/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<IEditGroupPage> 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>& 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<Ui::EditGroupWidgetMain> m_mainUi; 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..cd709df27 100644 --- a/src/gui/macutils/AppKitImpl.mm +++ b/src/gui/macutils/AppKitImpl.mm @@ -94,6 +94,17 @@ AppKit::~AppKit() } // +// 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 ------------------------- // @@ -127,4 +138,9 @@ bool AppKit::isHidden(pid_t pid) return [static_cast<id>(self) isHidden:pid]; } +bool AppKit::isDarkMode() +{ + return [static_cast<id>(self) isDarkMode]; +} + @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); diff --git a/src/gui/masterkey/KeyComponentWidget.cpp b/src/gui/masterkey/KeyComponentWidget.cpp index 7d795aca1..769cbab95 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,21 +166,22 @@ void KeyComponentWidget::cancelEdit() emit editCanceled(); } -void KeyComponentWidget::reset() +void KeyComponentWidget::showEvent(QShowEvent* event) { - if (static_cast<Page>(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; - } + resetComponentEditWidget(); + QWidget::showEvent(event); +} - QWidget* widget = componentEditWidget(); - m_ui->componentWidgetLayout->addWidget(widget); +void KeyComponentWidget::resetComponentEditWidget() +{ + if (!m_componentWidget || static_cast<Page>(m_ui->stackedWidget->currentIndex()) == Page::Edit) { + if (m_componentWidget) { + delete m_componentWidget; + } - 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 cf2ae4947..63079863e 100644 --- a/src/gui/masterkey/KeyComponentWidget.h +++ b/src/gui/masterkey/KeyComponentWidget.h @@ -20,6 +20,7 @@ #include <QScopedPointer> #include <QWidget> +#include <QPointer> namespace Ui { @@ -109,6 +110,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 +121,7 @@ private slots: void doEdit(); void doRemove(); void cancelEdit(); - void reset(); + void resetComponentEditWidget(); void updateSize(); private: @@ -125,6 +129,7 @@ private: Page m_previousPage = Page::AddNew; QString m_componentName; QString m_componentDescription; + QPointer<QWidget> m_componentWidget; const QScopedPointer<Ui::KeyComponentWidget> m_ui; }; diff --git a/src/gui/masterkey/PasswordEditWidget.cpp b/src/gui/masterkey/PasswordEditWidget.cpp index 6f85bb198..de00199bb 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() @@ -92,6 +92,18 @@ void PasswordEditWidget::initComponentEditWidget(QWidget* widget) m_compUi->enterPasswordEdit->setFocus(); } +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); +} + 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(); diff --git a/src/keeshare/KeeShare.cpp b/src/keeshare/KeeShare.cpp index 08c7b4f17..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("Disabled share %1").arg(reference.path); + messages << tr("Inactive share %1").arg(reference.path); + break; case KeeShareSettings::ImportFrom: - return tr("Import from share %1").arg(reference.path); + messages << tr("Imported from %1").arg(reference.path); + break; case KeeShareSettings::ExportTo: - return tr("Export to share %1").arg(reference.path); + messages << tr("Exported to %1").arg(reference.path); + break; case KeeShareSettings::SynchronizeWith: - return tr("Synchronize with share %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) @@ -196,13 +210,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/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 <QPainter> #include <QPushButton> +#include <functional> + namespace KeeShareSettings { namespace diff --git a/src/keeshare/ShareObserver.cpp b/src/keeshare/ShareObserver.cpp index 63d8358c2..33f5ed1f6 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()}; } @@ -190,7 +190,6 @@ void ShareObserver::reinitialize() KeeShareSettings::Reference newReference; }; - const auto active = KeeShare::active(); QList<Update> updated; const QList<Group*> 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; @@ -595,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<CompositeKey>::create(); key->addKey(QSharedPointer<PasswordKey>::create(reference.password)); @@ -613,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/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<int>(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; } } 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)) { diff --git a/src/sshagent/SSHAgent.cpp b/src/sshagent/SSHAgent.cpp index c2ef7084a..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); } } @@ -187,7 +190,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 +200,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<quint32>(settings.lifetimeConstraintDuration())); } - if (confirm) { + if (settings.useConfirmConstraintWhenAdding()) { request.write(SSH_AGENT_CONSTRAIN_CONFIRM); } @@ -218,11 +223,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 +236,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 +369,10 @@ void SSHAgent::databaseModeChanged() key.setComment(fileName); } - if (!m_addedKeys.contains(key) && settings.addAtDatabaseOpen()) { - quint32 lifetime = 0; - - if (settings.useLifetimeConstraintWhenAdding()) { - lifetime = static_cast<quint32>(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); 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 <QJsonObject> #include <QNetworkAccessManager> @@ -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/TestCli.cpp b/tests/TestCli.cpp index e2e66c2a4..9574f6d32 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<Database> TestCli::readTestDatabase() const { Utils::Test::setNextPassword("a"); - auto db = QSharedPointer<Database>(Utils::unlockDatabase(m_dbFile->fileName(), "", m_stdoutHandle)); + auto db = QSharedPointer<Database>(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<Database>(Utils::unlockDatabase(databaseFilename, "", Utils::DEVNULL)); + auto db = QSharedPointer<Database>(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<Database>(Utils::unlockDatabase(databaseFilename2, keyfilePath, Utils::DEVNULL)); + auto db2 = QSharedPointer<Database>(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<Database>(Utils::unlockDatabase(databaseFilename3, keyfilePath, Utils::DEVNULL)); + auto db3 = QSharedPointer<Database>(Utils::unlockDatabase(databaseFilename3, true, keyfilePath, Utils::DEVNULL)); QVERIFY(db3); } @@ -659,6 +681,63 @@ 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("")); + QVERIFY(m_stderrFile->readAll().contains("Invalid credentials were provided")); + + // 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("")); + QVERIFY(m_stderrFile->readAll().contains("Invalid credentials were provided")); +} + 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<TemporaryFile> m_dbFile; QScopedPointer<TemporaryFile> m_dbFile2; + QScopedPointer<TemporaryFile> m_keyFileProtectedDbFile; + QScopedPointer<TemporaryFile> m_keyFileProtectedNoPasswordDbFile; QScopedPointer<TemporaryFile> m_stdoutFile; QScopedPointer<TemporaryFile> m_stderrFile; QScopedPointer<TemporaryFile> m_stdinFile; 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<Database> dbDestination(new Database()); + QScopedPointer<Database> 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(); 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"))); 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); } diff --git a/tests/data/KeyFileProtected.kdbx b/tests/data/KeyFileProtected.kdbx Binary files differnew file mode 100644 index 000000000..eeda44d58 --- /dev/null +++ b/tests/data/KeyFileProtected.kdbx diff --git a/tests/data/KeyFileProtected.key b/tests/data/KeyFileProtected.key Binary files differnew file mode 100644 index 000000000..31314b953 --- /dev/null +++ b/tests/data/KeyFileProtected.key diff --git a/tests/data/KeyFileProtectedNoPassword.kdbx b/tests/data/KeyFileProtectedNoPassword.kdbx Binary files differnew file mode 100644 index 000000000..6ee188da8 --- /dev/null +++ b/tests/data/KeyFileProtectedNoPassword.kdbx diff --git a/tests/data/KeyFileProtectedNoPassword.key b/tests/data/KeyFileProtectedNoPassword.key Binary files differnew file mode 100644 index 000000000..a6131f09e --- /dev/null +++ b/tests/data/KeyFileProtectedNoPassword.key diff --git a/tests/gui/TestGui.cpp b/tests/gui/TestGui.cpp index 127563798..63e36fbaa 100644 --- a/tests/gui/TestGui.cpp +++ b/tests/gui/TestGui.cpp @@ -429,13 +429,20 @@ void TestGui::testEditEntry() auto* titleEdit = editEntryWidget->findChild<QLineEdit*>("titleEdit"); QTest::keyClicks(titleEdit, "_test"); - // Apply the edit auto* editEntryWidgetButtonBox = editEntryWidget->findChild<QDialogButtonBox*>("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<QCheckBox*>("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<QLineEdit*>("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*>("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<QLineEdit*>("usernameEdit")->setText("multiline\nusername"); editEntryWidget->findChild<QLineEdit*>("passwordEdit")->setText("multiline\npassword"); editEntryWidget->findChild<QLineEdit*>("passwordRepeatEdit")->setText("multiline\npassword"); editEntryWidget->findChild<QLineEdit*>("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")); @@ -849,19 +858,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()); 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 - |