Merge branch 'master' into develop

This commit is contained in:
Janek Bevendorff 2021-01-12 18:24:59 +01:00
commit 86278311d2
No known key found for this signature in database
GPG Key ID: 2FDEB0D40BCA5E11
47 changed files with 8492 additions and 286 deletions

View File

@ -1,13 +1,37 @@
# Changelog # Changelog
## 2.7.0 (in development) ## 2.6.3 (2020-01-12)
### Added ### Added
- Support Argon2id KDF [#5778]
- Support XMLv2 key files [#5798]
### Changed ### Changed
- Improve CSV Import/Export, include time fields and TOTP [#5346]
- Support empty area dragging of the application window [#5860]
- Display default Auto-Type sequence in preview pane [#5654]
- Remove strict length limit on generated passwords [#5748]
- Hide key file path by default when unlocking database [#5779]
- Document browser extension use with Edge in managed mode [#5692]
- Windows: Prevent clipboard history and cloud sync [#5853]
- macOS: Update the application icon to Big Sur styling [#5851]
### Fixed ### Fixed
- Re-select previously selected entry on database unlock [#5559]
- Properly save special character choice in password generator [#5610]
- Fix crash in browser integration with multiple similar entries [#5653]
- Remove offset on username field in classic theme [#5788]
- Ensure entry history is copied when drag/dropping entries and groups [#5817]
- Close modal dialogs when database is locked [#5820]
- Prevent crash when KeeShare modifies an entry that is currently being edited [#5827]
- Improve preview of entry attributes [#5834]
- Always activate/focus database open dialog preventing mistype [#5878]
- Reports: fix calculation of average password length [#5862]
- Linux: Delay startup on login to correct tray icon issues [#5724]
## 2.6.2 (2020-10-21) ## 2.6.2 (2020-10-21)
### Added ### Added

View File

@ -50,6 +50,33 @@
</screenshots> </screenshots>
<releases> <releases>
<release version="2.6.3" date="2021-01-12">
<description>
<ul>
<li>Support Argon2id KDF [#5778]</li>
<li>Support XMLv2 key files [#5798]</li>
<li>Improve CSV Import/Export, include time fields and TOTP [#5346]</li>
<li>Support empty area dragging of the application window [#5860]</li>
<li>Display default Auto-Type sequence in preview pane [#5654]</li>
<li>Remove strict length limit on generated passwords [#5748]</li>
<li>Hide key file path by default when unlocking database [#5779]</li>
<li>Document browser extension use with Edge in managed mode [#5692]</li>
<li>Windows: Prevent clipboard history and cloud sync [#5853]</li>
<li>macOS: Update the application icon to Big Sur styling [#5851]</li>
<li>Re-select previously selected entry on database unlock [#5559]</li>
<li>Properly save special character choice in password generator [#5610]</li>
<li>Fix crash in browser integration with multiple similar entries [#5653]</li>
<li>Remove offset on username field in classic theme [#5788]</li>
<li>Ensure entry history is copied when drag/dropping entries and groups [#5817]</li>
<li>Close modal dialogs when database is locked [#5820]</li>
<li>Prevent crash when KeeShare modifies an entry that is currently being edited [#5827]</li>
<li>Improve preview of entry attributes [#5834]</li>
<li>Always activate/focus database open dialog preventing mistype [#5878]</li>
<li>Reports: fix calculation of average password length [#5862]</li>
<li>Linux: Delay startup on login to correct tray icon issues [#5724]</li>
</ul>
</description>
</release>
<release version="2.6.2" date="2020-10-21"> <release version="2.6.2" date="2020-10-21">
<description> <description>
<ul> <ul>

View File

@ -245,7 +245,7 @@
</message> </message>
<message> <message>
<source>(restart program to activate)</source> <source>(restart program to activate)</source>
<translation type="unfinished"/> <translation>(genstart program for at aktivere)</translation>
</message> </message>
<message> <message>
<source>Minimize window after unlocking database</source> <source>Minimize window after unlocking database</source>

View File

@ -233,7 +233,7 @@
</message> </message>
<message> <message>
<source>Check for updates at application startup once per week</source> <source>Check for updates at application startup once per week</source>
<translation>Bei Programmstartstart wöchentlich auf Updates prüfen</translation> <translation>Bei Programmstart wöchentlich auf Updates prüfen</translation>
</message> </message>
<message> <message>
<source>Include beta releases when checking for updates</source> <source>Include beta releases when checking for updates</source>

View File

@ -1114,6 +1114,14 @@ chrome-laptop.</source>
<source>Column %1</source> <source>Column %1</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>TOTP</source>
<translation type="unfinished">TOTP</translation>
</message>
<message>
<source>Icon</source>
<translation type="unfinished">Icon</translation>
</message>
</context> </context>
<context> <context>
<name>CsvParserModel</name> <name>CsvParserModel</name>
@ -1218,20 +1226,6 @@ Backup database located at %2</source>
<source>Refresh</source> <source>Refresh</source>
<translation>Refresh</translation> <translation>Refresh</translation>
</message> </message>
<message>
<source>Legacy key file format</source>
<translation>Legacy key file format</translation>
</message>
<message>
<source>You are using a legacy key file format which may become
unsupported in the future.
Please consider generating a new key file.</source>
<translation>You are using a legacy key file format which may become
unsupported in the future.
Please consider generating a new key file.</translation>
</message>
<message> <message>
<source>Don&apos;t show this warning again</source> <source>Don&apos;t show this warning again</source>
<translation>Don&apos;t show this warning again</translation> <translation>Don&apos;t show this warning again</translation>
@ -1357,6 +1351,14 @@ If you do not have a key file, please leave the field empty.</source>
<source>Select hardware key</source> <source>Select hardware key</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Old key file format</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>You are using an old key file format which KeePassXC may&lt;br&gt;stop supporting in the future.&lt;br&gt;&lt;br&gt;Please consider generating a new key file by going to:&lt;br&gt;&lt;strong&gt;Database / Database Security / Change Key File.&lt;/strong&gt;&lt;br&gt;</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>DatabaseSettingWidgetMetaData</name> <name>DatabaseSettingWidgetMetaData</name>
@ -2324,6 +2326,15 @@ Disable safe saves and try again?</translation>
<source>[PROTECTED] Press Reveal to view or edit</source> <source>[PROTECTED] Press Reveal to view or edit</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Invalid Entry</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>An external merge operation has invalidated this entry.
Unfortunately, any changes made have been lost.</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>EditEntryWidgetAdvanced</name> <name>EditEntryWidgetAdvanced</name>
@ -3464,11 +3475,6 @@ Are you sure to add this file?</source>
<source>[PROTECTED]</source> <source>[PROTECTED]</source>
<translation>[PROTECTED]</translation> <translation>[PROTECTED]</translation>
</message> </message>
<message>
<source>&lt;b&gt;%1&lt;/b&gt;: %2</source>
<comment>attributes line</comment>
<translation>&lt;b&gt;%1&lt;/b&gt;: %2</translation>
</message>
<message> <message>
<source>Enabled</source> <source>Enabled</source>
<translation>Enabled</translation> <translation>Enabled</translation>
@ -3489,6 +3495,15 @@ Are you sure to add this file?</source>
<source>Advanced</source> <source>Advanced</source>
<translation type="unfinished">Advanced</translation> <translation type="unfinished">Advanced</translation>
</message> </message>
<message>
<source>Default Sequence</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;tr&gt;&lt;td&gt;&lt;b&gt;%1&lt;/b&gt;:&lt;/td&gt;&lt;td&gt;%2&lt;/td&gt;&lt;/tr&gt;</source>
<comment>attributes line</comment>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>EntryURLModel</name> <name>EntryURLModel</name>
@ -3522,23 +3537,8 @@ Are you sure to add this file?</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context>
<name>FdoSecrets::Item</name>
<message>
<source>Entry &quot;%1&quot; from database &quot;%2&quot; was used by %3</source>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>FdoSecrets::Service</name> <name>FdoSecrets::Service</name>
<message numerus="yes">
<source>%n Entry(s) was used by %1</source>
<comment>%1 is the name of an application</comment>
<translation type="unfinished">
<numerusform></numerusform>
<numerusform></numerusform>
</translation>
</message>
<message> <message>
<source>Failed to register DBus service at %1.&lt;br/&gt;</source> <source>Failed to register DBus service at %1.&lt;br/&gt;</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@ -4362,10 +4362,6 @@ If this reoccurs, then your database file may be corrupt.</source>
<source>&lt;p&gt;You can add a key file containing random bytes for additional security.&lt;/p&gt;&lt;p&gt;You must keep it secret and never lose it or you will be locked out!&lt;/p&gt;</source> <source>&lt;p&gt;You can add a key file containing random bytes for additional security.&lt;/p&gt;&lt;p&gt;You must keep it secret and never lose it or you will be locked out!&lt;/p&gt;</source>
<translation>&lt;p&gt;You can add a key file containing random bytes for additional security.&lt;/p&gt;&lt;p&gt;You must keep it secret and never lose it or you will be locked out!&lt;/p&gt;</translation> <translation>&lt;p&gt;You can add a key file containing random bytes for additional security.&lt;/p&gt;&lt;p&gt;You must keep it secret and never lose it or you will be locked out!&lt;/p&gt;</translation>
</message> </message>
<message>
<source>Legacy key file format</source>
<translation>Legacy key file format</translation>
</message>
<message> <message>
<source>Error loading the key file &apos;%1&apos; <source>Error loading the key file &apos;%1&apos;
Message: %2</source> Message: %2</source>
@ -4434,10 +4430,11 @@ Are you sure you want to continue with this file?</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<source>You are using a legacy key file format which may become <source>Old key file format</source>
unsupported in the future. <translation type="unfinished"></translation>
</message>
Generate a new key file in the database security settings.</source> <message>
<source>You selected a key file in an old format which KeePassXC&lt;br&gt;may stop supporting in the future.&lt;br&gt;&lt;br&gt;Please consider generating a new key file instead.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
@ -5784,16 +5781,6 @@ Expect some bugs and minor issues, this version is not meant for production use.
<source>Perform advanced analysis on the password.</source> <source>Perform advanced analysis on the password.</source>
<translation>Perform advanced analysis on the password.</translation> <translation>Perform advanced analysis on the password.</translation>
</message> </message>
<message>
<source>WARNING: You are using a legacy key file format which may become
unsupported in the future.
Please consider generating a new key file.</source>
<translation>WARNING: You are using a legacy key file format which may become
unsupported in the future.
Please consider generating a new key file.</translation>
</message>
<message> <message>
<source> <source>
@ -6184,10 +6171,6 @@ Available commands:
<source>%1: (row, col) %2,%3</source> <source>%1: (row, col) %2,%3</source>
<translation>%1: (row, col) %2,%3</translation> <translation>%1: (row, col) %2,%3</translation>
</message> </message>
<message>
<source>Argon2 (KDBX 4 recommended)</source>
<translation>Argon2 (KDBX 4 recommended)</translation>
</message>
<message> <message>
<source>AES-KDF (KDBX 4)</source> <source>AES-KDF (KDBX 4)</source>
<translation>AES-KDF (KDBX 4)</translation> <translation>AES-KDF (KDBX 4)</translation>
@ -6764,10 +6747,6 @@ Kernel: %3 %4</source>
<source>AES (%1 rounds)</source> <source>AES (%1 rounds)</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Argon2 (%1 rounds, %2 KB)</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>AES 256-bit</source> <source>AES 256-bit</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@ -6804,6 +6783,45 @@ Kernel: %3 %4</source>
<source>path to a custom local config file</source> <source>path to a custom local config file</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>WARNING: You are using an old key file format which KeePassXC may
stop supporting in the future.
Please consider generating a new key file.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Argon2%1 (%2 rounds, %3 KB)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Argon2d (KDBX 4 recommended)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Argon2id (KDBX 4)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>TOTP</source>
<translation type="unfinished">TOTP</translation>
</message>
<message>
<source>Icon</source>
<translation type="unfinished">Icon</translation>
</message>
<message>
<source>Unsupported key file version: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Checksum mismatch! Key file may be corrupt.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Unexpected key file data! Key file may be corrupt.</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>QtIOCompressor</name> <name>QtIOCompressor</name>

View File

@ -2454,7 +2454,7 @@ Disable safe saves and try again?</translation>
<name>EditEntryWidgetBrowser</name> <name>EditEntryWidgetBrowser</name>
<message> <message>
<source>These settings affect to the entry&apos;s behaviour with the browser extension.</source> <source>These settings affect to the entry&apos;s behaviour with the browser extension.</source>
<translation>These settings affect to the entry&apos;s behavior with the browser extension.</translation> <translation>These settings affect the browser extensions behavior with regard to this database entry.</translation>
</message> </message>
<message> <message>
<source>General</source> <source>General</source>
@ -2470,7 +2470,7 @@ Disable safe saves and try again?</translation>
</message> </message>
<message> <message>
<source>Additional URL&apos;s</source> <source>Additional URL&apos;s</source>
<translation>Additional URL&apos;s</translation> <translation>Additional URLs</translation>
</message> </message>
<message> <message>
<source>Add</source> <source>Add</source>

View File

@ -229,7 +229,7 @@
</message> </message>
<message> <message>
<source>Remember database key files and security dongles</source> <source>Remember database key files and security dongles</source>
<translation>Recordar los últimos ficheros claves y los «dongle» de seguridad</translation> <translation>Recuerde los archivos de clave de la base de datos y los «dongle» de seguridad</translation>
</message> </message>
<message> <message>
<source>Check for updates at application startup once per week</source> <source>Check for updates at application startup once per week</source>
@ -1177,7 +1177,7 @@ Copia de seguridad de base de datos ubicada en %2</translation>
</message> </message>
<message> <message>
<source>Recycle Bin</source> <source>Recycle Bin</source>
<translation>Papelera</translation> <translation>Papelera de reciclaje</translation>
</message> </message>
<message> <message>
<source>Passwords</source> <source>Passwords</source>
@ -1204,7 +1204,7 @@ Copia de seguridad de base de datos ubicada en %2</translation>
<name>DatabaseOpenWidget</name> <name>DatabaseOpenWidget</name>
<message> <message>
<source>Key File:</source> <source>Key File:</source>
<translation>Fichero clave:</translation> <translation>Fichero Clave:</translation>
</message> </message>
<message> <message>
<source>Refresh</source> <source>Refresh</source>
@ -1258,7 +1258,7 @@ Considere generar un nuevo fichero clave.</translation>
</message> </message>
<message> <message>
<source>Hardware key slot selection</source> <source>Hardware key slot selection</source>
<translation>Selección de ranura de clave hardware</translation> <translation>Selección de ranura de llave por hardware</translation>
</message> </message>
<message> <message>
<source>Browse for key file</source> <source>Browse for key file</source>
@ -1274,11 +1274,11 @@ Considere generar un nuevo fichero clave.</translation>
</message> </message>
<message> <message>
<source>Hardware Key:</source> <source>Hardware Key:</source>
<translation>Clave hardware:</translation> <translation>Llave por hardware:</translation>
</message> </message>
<message> <message>
<source>Hardware key help</source> <source>Hardware key help</source>
<translation>Ayuda de clave hardware</translation> <translation>Ayuda de la llave por hardware</translation>
</message> </message>
<message> <message>
<source>TouchID for Quick Unlock</source> <source>TouchID for Quick Unlock</source>
@ -1317,7 +1317,7 @@ Para prevenir que aparezca este error, debe ir a «Configuración de base de dat
<message> <message>
<source>&lt;p&gt;You can use a hardware security key such as a &lt;strong&gt;YubiKey&lt;/strong&gt; or &lt;strong&gt;OnlyKey&lt;/strong&gt; with slots configured for HMAC-SHA1.&lt;/p&gt; <source>&lt;p&gt;You can use a hardware security key such as a &lt;strong&gt;YubiKey&lt;/strong&gt; or &lt;strong&gt;OnlyKey&lt;/strong&gt; with slots configured for HMAC-SHA1.&lt;/p&gt;
&lt;p&gt;Click for more information...&lt;/p&gt;</source> &lt;p&gt;Click for more information...&lt;/p&gt;</source>
<translation>&lt;p&gt;Puede usar una clave de seguridad hardware como &lt;strong&gt;YubiKey&lt;/strong&gt; o &lt;strong&gt;OnlyKey&lt;/strong&gt; con ranuras configuradas para HMAC-SHA1.&lt;/p&gt; <translation>&lt;p&gt;Puede usar una llave de seguridad por hardware como &lt;strong&gt;YubiKey&lt;/strong&gt; o &lt;strong&gt;OnlyKey&lt;/strong&gt; con ranuras configuradas para HMAC-SHA1.&lt;/p&gt;
&lt;p&gt;Clic para más información...&lt;/p&gt;</translation> &lt;p&gt;Clic para más información...&lt;/p&gt;</translation>
</message> </message>
<message> <message>
@ -1352,15 +1352,15 @@ Si no tiene un fichero clave, deje el campo vacío.</translation>
</message> </message>
<message> <message>
<source>Detecting hardware keys</source> <source>Detecting hardware keys</source>
<translation>Detectando claves hardware...</translation> <translation>Detectando llaves por hardware...</translation>
</message> </message>
<message> <message>
<source>No hardware keys detected</source> <source>No hardware keys detected</source>
<translation>No se detectaron claves hardware</translation> <translation>No se detectaron llaves por hardware</translation>
</message> </message>
<message> <message>
<source>Select hardware key</source> <source>Select hardware key</source>
<translation>Seleccionar clave hardware...</translation> <translation>Seleccionar llave por hardware...</translation>
</message> </message>
</context> </context>
<context> <context>
@ -1589,7 +1589,7 @@ Are you sure you want to continue without a password?</source>
</message> </message>
<message> <message>
<source>Key Derivation Function:</source> <source>Key Derivation Function:</source>
<translation>Función de derivación de la llave:</translation> <translation>Función de derivación de la clave:</translation>
</message> </message>
<message> <message>
<source>Transform rounds:</source> <source>Transform rounds:</source>
@ -1670,7 +1670,7 @@ Si conserva este número, ¡su base de datos puede tardar horas o días (o inclu
<source>You are using a very low number of key transform rounds with AES-KDF. <source>You are using a very low number of key transform rounds with AES-KDF.
If you keep this number, your database may be too easy to crack!</source> If you keep this number, your database may be too easy to crack!</source>
<translation>Está utilizando una cantidad muy baja de rondas de transformación de llave con AES-KDF. <translation>Está utilizando un número muy bajo de rondas de transformación de clave con AES-KDF.
Si conserva este número, ¡su base de datos puede ser muy fácil de descifrar!</translation> Si conserva este número, ¡su base de datos puede ser muy fácil de descifrar!</translation>
</message> </message>
@ -1680,7 +1680,7 @@ Si conserva este número, ¡su base de datos puede ser muy fácil de descifrar!<
</message> </message>
<message> <message>
<source>Failed to transform key with new KDF parameters; KDF unchanged.</source> <source>Failed to transform key with new KDF parameters; KDF unchanged.</source>
<translation>Error al transformar la llave con nuevos parámetros KDF; KDF sin cambios.</translation> <translation>Error al transformar la clave con nuevos parámetros KDF; KDF sin cambios.</translation>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source> MiB</source> <source> MiB</source>
@ -1710,7 +1710,7 @@ Si conserva este número, ¡su base de datos puede ser muy fácil de descifrar!<
</message> </message>
<message> <message>
<source>Key derivation function</source> <source>Key derivation function</source>
<translation>Función de derivación de la llave</translation> <translation>Función de derivación de la clave</translation>
</message> </message>
<message> <message>
<source>Transform rounds</source> <source>Transform rounds</source>
@ -2000,7 +2000,7 @@ Esto es definitivamente un error, por favor repórtelo a los desarrolladores.</t
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>Do you really want to move %n entry(s) to the recycle bin?</source> <source>Do you really want to move %n entry(s) to the recycle bin?</source>
<translation><numerusform>¿Desea mover %n apunte a la papelera?</numerusform><numerusform>¿Desea mover %n apuntes a la papelera?</numerusform></translation> <translation><numerusform>¿Desea mover %n apunte a la papelera?</numerusform><numerusform>¿Desea mover %n apuntes a la papelera de reciclaje?</numerusform></translation>
</message> </message>
<message> <message>
<source>Execute command?</source> <source>Execute command?</source>
@ -2137,11 +2137,11 @@ Disable safe saves and try again?</source>
</message> </message>
<message> <message>
<source>Move group to recycle bin?</source> <source>Move group to recycle bin?</source>
<translation>¿Mover grupo a la papelera?</translation> <translation>¿Mover grupo a la papelera de reciclaje?</translation>
</message> </message>
<message> <message>
<source>Do you really want to move the group &quot;%1&quot; to the recycle bin?</source> <source>Do you really want to move the group &quot;%1&quot; to the recycle bin?</source>
<translation>¿Desea mover el grupo «%1» a la papelera?</translation> <translation>¿Desea mover el grupo «%1» a la papelera de reciclaje?</translation>
</message> </message>
<message> <message>
<source>Successfully merged the database files.</source> <source>Successfully merged the database files.</source>
@ -2642,7 +2642,7 @@ Disable safe saves and try again?</source>
</message> </message>
<message> <message>
<source>Add key to agent when database is opened/unlocked</source> <source>Add key to agent when database is opened/unlocked</source>
<translation>Añadir llave al agente cuando la base de datos se abre/desbloquea</translation> <translation>Añadir clave al agente cuando la base de datos se abre/desbloquea</translation>
</message> </message>
<message> <message>
<source>Comment</source> <source>Comment</source>
@ -2687,7 +2687,7 @@ Disable safe saves and try again?</source>
</message> </message>
<message> <message>
<source>Require user confirmation when this key is used</source> <source>Require user confirmation when this key is used</source>
<translation>Requiere confirmación del usuario cuando se usa esta llave</translation> <translation>Requiere confirmación del usuario cuando se usa esta clave</translation>
</message> </message>
<message> <message>
<source>Remove key from agent after specified seconds</source> <source>Remove key from agent after specified seconds</source>
@ -2958,7 +2958,7 @@ Las extensiones soportadas son: %1.</translation>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>%n icon(s) already exist in the database</source> <source>%n icon(s) already exist in the database</source>
<translation><numerusform>El icono %n ya existe en la base de datos</numerusform><numerusform>Los %n iconos ya existen en la base de datos</numerusform></translation> <translation><numerusform>El icono %n ya existe en la base de datos</numerusform><numerusform>Los %n icono(s) ya existe(n) en la base de datos</numerusform></translation>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>The following icon(s) failed:</source> <source>The following icon(s) failed:</source>
@ -2966,7 +2966,7 @@ Las extensiones soportadas son: %1.</translation>
</message> </message>
<message numerus="yes"> <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> <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>Este icono es usado en %1 apunte, y será remplazado por el icono por defecto. ¿Está seguro que desea eliminarlo?</numerusform><numerusform>Este icono es usado en %1 apuntes, y será remplazado por el icono predeterminado. ¿Está seguro que desea eliminarlo?</numerusform></translation> <translation><numerusform>Este icono es usado en %1 apunte, y será remplazado por el icono por defecto. ¿Está seguro que desea eliminarlo?</numerusform><numerusform>Este icono es usado en %n apunte(s), y será remplazado por el icono predeterminado. ¿Está seguro que desea eliminarlo?</numerusform></translation>
</message> </message>
<message> <message>
<source>You can enable the DuckDuckGo website icon service under Tools -&gt; Settings -&gt; Security</source> <source>You can enable the DuckDuckGo website icon service under Tools -&gt; Settings -&gt; Security</source>
@ -3203,9 +3203,9 @@ Your database may get very large and reduce performance.
Are you sure to add this file?</source> Are you sure to add this file?</source>
<translation>%1 es un fichero grande (%2 MB). <translation>%1 es un fichero grande (%2 MB).
Tu base de datos puede vovlerse muy grande y reducir el rendimiento. Su base de datos puede vovlerse muy grande y reducir el rendimiento.
¿Estás seguro de añadir este fichero?</translation> ¿Está seguro de añadir este fichero?</translation>
</message> </message>
<message> <message>
<source>Confirm Attachment</source> <source>Confirm Attachment</source>
@ -3724,7 +3724,7 @@ Si ocurre nuevamente entonces su archivo de base de datos puede estar corrupto.<
</message> </message>
<message> <message>
<source>Unsupported key derivation function (KDF) or invalid parameters</source> <source>Unsupported key derivation function (KDF) or invalid parameters</source>
<translation>Función de derivación de cerradura no admitida (KDF) o parámetros no válidos</translation> <translation>Función de derivación de clave no admitida (KDF) o parámetros no válidos</translation>
</message> </message>
<message> <message>
<source>Legacy header fields found in KDBX4 file.</source> <source>Legacy header fields found in KDBX4 file.</source>
@ -4118,7 +4118,7 @@ Linea %2, columna %3</translation>
</message> </message>
<message> <message>
<source>Key transformation failed</source> <source>Key transformation failed</source>
<translation>Error en la transformación de la llave</translation> <translation>Error en la transformación de la clave</translation>
</message> </message>
<message> <message>
<source>Invalid group field type number</source> <source>Invalid group field type number</source>
@ -4317,7 +4317,7 @@ Si ocurre nuevamente entonces su archivo de base de datos puede estar corrupto.<
</message> </message>
<message> <message>
<source>Key File</source> <source>Key File</source>
<translation>Fichero clave</translation> <translation>Fichero Clave</translation>
</message> </message>
<message> <message>
<source>&lt;p&gt;You can add a key file containing random bytes for additional security.&lt;/p&gt;&lt;p&gt;You must keep it secret and never lose it or you will be locked out!&lt;/p&gt;</source> <source>&lt;p&gt;You can add a key file containing random bytes for additional security.&lt;/p&gt;&lt;p&gt;You must keep it secret and never lose it or you will be locked out!&lt;/p&gt;</source>
@ -4325,7 +4325,7 @@ Si ocurre nuevamente entonces su archivo de base de datos puede estar corrupto.<
</message> </message>
<message> <message>
<source>Legacy key file format</source> <source>Legacy key file format</source>
<translation>Formato de archivo llave heredado</translation> <translation>Formato de archivo fichero clave heredado</translation>
</message> </message>
<message> <message>
<source>Error loading the key file '%1' <source>Error loading the key file '%1'
@ -4355,7 +4355,7 @@ Mensaje: %2</translation>
</message> </message>
<message> <message>
<source>Select a key file</source> <source>Select a key file</source>
<translation>Seleccione un archivo llave</translation> <translation>Seleccionar un fichero clave</translation>
</message> </message>
<message> <message>
<source>Key file selection</source> <source>Key file selection</source>
@ -4829,11 +4829,11 @@ Espere algunos errores y problemas menores, esta versión no está destinada par
</message> </message>
<message> <message>
<source>Show Toolbar</source> <source>Show Toolbar</source>
<translation>Mostrar barra de herrameintas</translation> <translation>Mostrar barra de herramientas</translation>
</message> </message>
<message> <message>
<source>Show Preview Panel</source> <source>Show Preview Panel</source>
<translation>Mostrar panel de previsualizción</translation> <translation>Mostrar panel de previsualización</translation>
</message> </message>
<message> <message>
<source>Don&apos;t show again for this version</source> <source>Don&apos;t show again for this version</source>
@ -5115,7 +5115,7 @@ Espere algunos errores y problemas menores, esta versión no está destinada par
<name>OpenSSHKey</name> <name>OpenSSHKey</name>
<message> <message>
<source>Invalid key file, expecting an OpenSSH key</source> <source>Invalid key file, expecting an OpenSSH key</source>
<translation>Archivo llave no válido, esperando una llave de OpenSSH</translation> <translation>Fichero clave no válido, esperando una clave de OpenSSH</translation>
</message> </message>
<message> <message>
<source>PEM boundary mismatch</source> <source>PEM boundary mismatch</source>
@ -5579,7 +5579,7 @@ Espere algunos errores y problemas menores, esta versión no está destinada par
</message> </message>
<message> <message>
<source>Empty</source> <source>Empty</source>
<translation>Vacío</translation> <translation>Vaciar</translation>
</message> </message>
<message> <message>
<source>Remove</source> <source>Remove</source>
@ -6791,7 +6791,7 @@ Núcleo: %3 %4</translation>
</message> </message>
<message> <message>
<source>Hover over reason to show additional details. Double-click entries to edit.</source> <source>Hover over reason to show additional details. Double-click entries to edit.</source>
<translation>Pasar por encima de la razón para mostrar detalles adicionales. Doble clic para editar.</translation> <translation>Pasar por encima del motivo para mostrar detalles adicionales. Doble clic para editar.</translation>
</message> </message>
<message> <message>
<source>Bad</source> <source>Bad</source>
@ -6850,7 +6850,7 @@ Núcleo: %3 %4</translation>
</message> </message>
<message> <message>
<source>Reason</source> <source>Reason</source>
<translation>Razón</translation> <translation>Motivo</translation>
</message> </message>
<message> <message>
<source>Edit Entry...</source> <source>Edit Entry...</source>
@ -7087,7 +7087,7 @@ Núcleo: %3 %4</translation>
</message> </message>
<message> <message>
<source>Agent refused this identity. Possible reasons include:</source> <source>Agent refused this identity. Possible reasons include:</source>
<translation>El agente rechazó esta identidad. Las posibles razones incluyen:</translation> <translation>El agente rechazó esta identidad. Los posibles motivos incluyen:</translation>
</message> </message>
<message> <message>
<source>The key has already been added.</source> <source>The key has already been added.</source>
@ -7569,7 +7569,7 @@ Núcleo: %3 %4</translation>
<name>TotpDialog</name> <name>TotpDialog</name>
<message> <message>
<source>Timed Password</source> <source>Timed Password</source>
<translation>Contraseña cronometrada</translation> <translation>Contraseña temporizada</translation>
</message> </message>
<message> <message>
<source>000000</source> <source>000000</source>
@ -7581,7 +7581,7 @@ Núcleo: %3 %4</translation>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>Expires in &lt;b&gt;%n&lt;/b&gt; second(s)</source> <source>Expires in &lt;b&gt;%n&lt;/b&gt; second(s)</source>
<translation><numerusform>Caduca en &lt;b&gt;%n&lt;/b&gt; segundo(s)</numerusform><numerusform>Caduca en &lt;b&gt;%n&lt;/b&gt; segundo (s)</numerusform></translation> <translation><numerusform>Caduca en &lt;b&gt;%n&lt;/b&gt; segundo</numerusform><numerusform>Caduca en &lt;b&gt;%n&lt;/b&gt; segundos</numerusform></translation>
</message> </message>
</context> </context>
<context> <context>
@ -7601,7 +7601,7 @@ Núcleo: %3 %4</translation>
</message> </message>
<message> <message>
<source>Closing in %1 seconds.</source> <source>Closing in %1 seconds.</source>
<translation>Cernado en %1 segundos.</translation> <translation>Cerrando en %1 segundos.</translation>
</message> </message>
</context> </context>
<context> <context>
@ -7807,19 +7807,19 @@ Ejemplo: JBSWY3DPEHPK3PXP</translation>
</message> </message>
<message> <message>
<source>Hardware key is currently in use.</source> <source>Hardware key is currently in use.</source>
<translation>La clave hardware está actualmente en uso.</translation> <translation>La llave por hardware está actualmente en uso.</translation>
</message> </message>
<message> <message>
<source>Could not find hardware key with serial number %1. Please plug it in to continue.</source> <source>Could not find hardware key with serial number %1. Please plug it in to continue.</source>
<translation>No se puede encontrar hardware con número de serie %1. Conéctelo para continuar.</translation> <translation>No se puede encontrar llave por hardware con número de serie %1. Conéctelo para continuar.</translation>
</message> </message>
<message> <message>
<source>Hardware key timed out waiting for user interaction.</source> <source>Hardware key timed out waiting for user interaction.</source>
<translation>La clave hardware expiró esperando interacción del usuario.</translation> <translation>La llave por hardware expiró esperando interacción del usuario.</translation>
</message> </message>
<message> <message>
<source>A USB error ocurred when accessing the hardware key: %1</source> <source>A USB error ocurred when accessing the hardware key: %1</source>
<translation>Ha ocurrido un error USB al acceder a la clave hardware: %1</translation> <translation>Ha ocurrido un error USB al acceder a la llave por hardware: %1</translation>
</message> </message>
<message> <message>
<source>Failed to complete a challenge-response, the specific error was: %1</source> <source>Failed to complete a challenge-response, the specific error was: %1</source>
@ -7846,23 +7846,23 @@ Ejemplo: JBSWY3DPEHPK3PXP</translation>
</message> </message>
<message> <message>
<source>Hardware key slot selection</source> <source>Hardware key slot selection</source>
<translation>Selección de ranura de clave hardware</translation> <translation>Selección de ranura de llave por hardware</translation>
</message> </message>
<message> <message>
<source>Could not find any hardware keys!</source> <source>Could not find any hardware keys!</source>
<translation>¡No se puede encontrar ninguna clave hardware!</translation> <translation>¡No se puede encontrar ninguna llave por hardware!</translation>
</message> </message>
<message> <message>
<source>Selected hardware key slot does not support challenge-response!</source> <source>Selected hardware key slot does not support challenge-response!</source>
<translation>¡La ranura de la clave hardware seleccionada no soporta reto-respuesta!</translation> <translation>¡La ranura de la llave por hardware seleccionada no soporta reto-respuesta!</translation>
</message> </message>
<message> <message>
<source>Detecting hardware keys</source> <source>Detecting hardware keys</source>
<translation>Detectando claves hardware...</translation> <translation>Detectando llaves por hardware...</translation>
</message> </message>
<message> <message>
<source>No hardware keys detected</source> <source>No hardware keys detected</source>
<translation>No se detectaron claves hardware</translation> <translation>No se detectaron llaves por hardware</translation>
</message> </message>
</context> </context>
</TS> </TS>

View File

@ -137,7 +137,7 @@
</message> </message>
<message> <message>
<source>You must restart the application to set the new language. Would you like to restart now?</source> <source>You must restart the application to set the new language. Would you like to restart now?</source>
<translation type="unfinished"/> <translation>Ohjelma täytyy käynnistää uudelleen, jotta uusi kieli voidaan ottaa käyttöön. Haluatko käynnistää uudelleen nyt?</translation>
</message> </message>
</context> </context>
<context> <context>
@ -342,15 +342,15 @@
</message> </message>
<message> <message>
<source>Automatically save when locking database</source> <source>Automatically save when locking database</source>
<translation type="unfinished"/> <translation>Tallenna automaattisesti, kun tietokanta lukitaan</translation>
</message> </message>
<message> <message>
<source>Automatically save non-data changes when locking database</source> <source>Automatically save non-data changes when locking database</source>
<translation type="unfinished"/> <translation>Tallenna automaattisesti asetukset jotka eivät liity varsinaisiin tietoihin, kun tietokanta lukitaan</translation>
</message> </message>
<message> <message>
<source>Tray icon type</source> <source>Tray icon type</source>
<translation type="unfinished"/> <translation>Ilmoitusalueen ikonin tyyppi</translation>
</message> </message>
</context> </context>
<context> <context>
@ -4849,23 +4849,23 @@ Bugeja ja ongelmia voi esiintyä. Tämä versio ei ole tarkoitettu päivittäise
</message> </message>
<message> <message>
<source>Perform Auto-Type Sequence</source> <source>Perform Auto-Type Sequence</source>
<translation type="unfinished"/> <translation>Suorita automaattisyötön sekvenssi</translation>
</message> </message>
<message> <message>
<source>{USERNAME}</source> <source>{USERNAME}</source>
<translation type="unfinished"/> <translation>{USERNAME}</translation>
</message> </message>
<message> <message>
<source>{USERNAME}{ENTER}</source> <source>{USERNAME}{ENTER}</source>
<translation type="unfinished"/> <translation>{USERNAME}{ENTER}</translation>
</message> </message>
<message> <message>
<source>{PASSWORD}</source> <source>{PASSWORD}</source>
<translation type="unfinished"/> <translation>{PASSWORD}</translation>
</message> </message>
<message> <message>
<source>{PASSWORD}{ENTER}</source> <source>{PASSWORD}{ENTER}</source>
<translation type="unfinished"/> <translation>{PASSWORD}{ENTER}</translation>
</message> </message>
</context> </context>
<context> <context>

View File

@ -330,15 +330,15 @@
</message> </message>
<message> <message>
<source>Auto-Type typing delay:</source> <source>Auto-Type typing delay:</source>
<translation>Vitesse de remplissage de la saisie automatique :</translation> <translation>Vitesse de remplissage de la saisie automatique :</translation>
</message> </message>
<message> <message>
<source>Global Auto-Type shortcut:</source> <source>Global Auto-Type shortcut:</source>
<translation>Raccourci de la saisie automatique :</translation> <translation>Raccourci de la saisie automatique :</translation>
</message> </message>
<message> <message>
<source>Auto-Type start delay:</source> <source>Auto-Type start delay:</source>
<translation>Délai de démarrage de la saisie automatique :</translation> <translation>Délai de démarrage de la saisie automatique :</translation>
</message> </message>
<message> <message>
<source>Automatically save when locking database</source> <source>Automatically save when locking database</source>
@ -439,11 +439,11 @@
</message> </message>
<message> <message>
<source>Require password repeat when it is visible</source> <source>Require password repeat when it is visible</source>
<translation>Demander de confirmer le mot de passe lorsque celui-ci est visible</translation> <translation>Exiger la confirmation du mot de passe sil est visible</translation>
</message> </message>
<message> <message>
<source>Hide passwords when editing them</source> <source>Hide passwords when editing them</source>
<translation>Cacher les mots de passe pendant leur modification</translation> <translation>Cacher les mots de passe lors de leur modification</translation>
</message> </message>
<message> <message>
<source>Use placeholder for empty password fields</source> <source>Use placeholder for empty password fields</source>
@ -564,11 +564,11 @@
<name>BrowserAccessControlDialog</name> <name>BrowserAccessControlDialog</name>
<message> <message>
<source>KeePassXC - Browser Access Request</source> <source>KeePassXC - Browser Access Request</source>
<translation>Requiert laccès à KeePassXC-Browser</translation> <translation>KeePassXC-Browser - Requête d&apos;accès au navigateur</translation>
</message> </message>
<message> <message>
<source>%1 is requesting access to the following entries:</source> <source>%1 is requesting access to the following entries:</source>
<translation>%1 demande laccès aux entrées suivantes :</translation> <translation>%1 demande laccès aux entrées suivantes :</translation>
</message> </message>
<message> <message>
<source>Remember access to checked entries</source> <source>Remember access to checked entries</source>
@ -892,7 +892,7 @@ chrome-laptop</translation>
</message> </message>
<message> <message>
<source>Browser type:</source> <source>Browser type:</source>
<translation>Type de navigateur :</translation> <translation>Type de navigateur :</translation>
</message> </message>
<message> <message>
<source>Toolbar button style</source> <source>Toolbar button style</source>
@ -900,7 +900,7 @@ chrome-laptop</translation>
</message> </message>
<message> <message>
<source>Config Location:</source> <source>Config Location:</source>
<translation>Emplacement de configuration :</translation> <translation>Emplacement de configuration :</translation>
</message> </message>
<message> <message>
<source>Custom browser location field</source> <source>Custom browser location field</source>
@ -2764,7 +2764,7 @@ Désactiver les enregistrements sécurisés et ressayer?</translation>
</message> </message>
<message> <message>
<source>KeeShare unsigned container</source> <source>KeeShare unsigned container</source>
<translation>Conteneur KeeShare non signé</translation> <translation>Conteneur KeeShare non signé</translation>
</message> </message>
<message> <message>
<source>KeeShare signed container</source> <source>KeeShare signed container</source>
@ -4135,7 +4135,7 @@ Ligne %2, colonne %3</translation>
</message> </message>
<message> <message>
<source>Incorrect group creation time field size</source> <source>Incorrect group creation time field size</source>
<translation>Taille du champ &quot;date du la création du groupe&quot; incorrect.</translation> <translation>Taille du champ « date du la création du groupe » incorrect.</translation>
</message> </message>
<message> <message>
<source>Incorrect group modification time field size</source> <source>Incorrect group modification time field size</source>
@ -4151,7 +4151,7 @@ Ligne %2, colonne %3</translation>
</message> </message>
<message> <message>
<source>Incorrect group icon field size</source> <source>Incorrect group icon field size</source>
<translation>Taille du champ &quot;icône du groupe&quot; incorrect.</translation> <translation>Taille du champ « icône du groupe » incorrect.</translation>
</message> </message>
<message> <message>
<source>Incorrect group level field size</source> <source>Incorrect group level field size</source>
@ -4911,11 +4911,11 @@ Attendez-vous à des bogues et des problèmes mineurs. Cette version nest pas
</message> </message>
<message> <message>
<source>Overwriting %1 [%2]</source> <source>Overwriting %1 [%2]</source>
<translation>Écrasement de %1 [%2]</translation> <translation>Remplacement de %1 [%2]</translation>
</message> </message>
<message> <message>
<source>older entry merged from database &quot;%1&quot;</source> <source>older entry merged from database &quot;%1&quot;</source>
<translation>ancienne entrée fusionnée de la base de données &quot;%1&quot;</translation> <translation>ancienne entrée fusionnée de la base de données « %1 »</translation>
</message> </message>
<message> <message>
<source>Adding backup for older target %1 [%2]</source> <source>Adding backup for older target %1 [%2]</source>
@ -5065,7 +5065,7 @@ Attendez-vous à des bogues et des problèmes mineurs. Cette version nest pas
</message> </message>
<message> <message>
<source>Unable to process clearText in place</source> <source>Unable to process clearText in place</source>
<translation>Impossible dactiver le traitement de ClearText</translation> <translation>Impossible dappliquer l&apos;amélioration ClearText</translation>
</message> </message>
<message> <message>
<source>Expected %1 bytes of clear-text, found %2</source> <source>Expected %1 bytes of clear-text, found %2</source>
@ -5282,7 +5282,7 @@ Attendez-vous à des bogues et des problèmes mineurs. Cette version nest pas
</message> </message>
<message> <message>
<source>Character Types</source> <source>Character Types</source>
<translation>Types de caractères:</translation> <translation>Types de caractères</translation>
</message> </message>
<message> <message>
<source>Numbers</source> <source>Numbers</source>
@ -5326,7 +5326,7 @@ Attendez-vous à des bogues et des problèmes mineurs. Cette version nest pas
</message> </message>
<message> <message>
<source>Password Quality: %1</source> <source>Password Quality: %1</source>
<translation>Qualité du mot de passe : %1</translation> <translation>Qualité du mot de passe : %1</translation>
</message> </message>
<message> <message>
<source>Poor</source> <source>Poor</source>
@ -5382,7 +5382,7 @@ Attendez-vous à des bogues et des problèmes mineurs. Cette version nest pas
</message> </message>
<message> <message>
<source>Add non-hex letters to &quot;do not include&quot; list</source> <source>Add non-hex letters to &quot;do not include&quot; list</source>
<translation>Ajouter les lettres non-hexadécimales à la liste &quot;Ne pas inclure&quot;</translation> <translation>Ajouter les lettres non-hexadécimales à la liste « Ne pas inclure »</translation>
</message> </message>
<message> <message>
<source>Hex</source> <source>Hex</source>
@ -5815,7 +5815,7 @@ Commandes proposées :
</message> </message>
<message> <message>
<source>malformed string</source> <source>malformed string</source>
<translation>chaîne de caractères malformée</translation> <translation>chaîne de caractères incorrecte</translation>
</message> </message>
<message> <message>
<source>missing closing quote</source> <source>missing closing quote</source>
@ -5889,7 +5889,7 @@ Commandes proposées :
</message> </message>
<message> <message>
<source>Successfully added entry %1.</source> <source>Successfully added entry %1.</source>
<translation>Ajouté avec succès lentrée %1.</translation> <translation>Lentrée %1 a bien é ajoutée.</translation>
</message> </message>
<message> <message>
<source>Invalid timeout value %1.</source> <source>Invalid timeout value %1.</source>
@ -6091,7 +6091,7 @@ Commandes proposées :
<message> <message>
<source>Error reading merge file: <source>Error reading merge file:
%1</source> %1</source>
<translation>Erreur lors de la lecture du fichier fusionner : <translation>Erreur lors de la lecture du fichier à fusionner :
%1</translation> %1</translation>
</message> </message>
<message> <message>
@ -6104,11 +6104,11 @@ Commandes proposées :
</message> </message>
<message> <message>
<source>Successfully recycled entry %1.</source> <source>Successfully recycled entry %1.</source>
<translation>Entrée %1 recyclée avec succès.</translation> <translation>L&apos;entrée %1 a bien é recyclée.</translation>
</message> </message>
<message> <message>
<source>Successfully deleted entry %1.</source> <source>Successfully deleted entry %1.</source>
<translation>Supprimé lentrée %1 avec succès.</translation> <translation>Lentrée %1 a bien é supprimée.</translation>
</message> </message>
<message> <message>
<source>Show the entry&apos;s current TOTP.</source> <source>Show the entry&apos;s current TOTP.</source>
@ -6128,7 +6128,7 @@ Commandes proposées :
</message> </message>
<message> <message>
<source>%1: (row, col) %2,%3</source> <source>%1: (row, col) %2,%3</source>
<translation>%1: (ligne,colonne) %2,%3</translation> <translation>%1 : (ligne, colonne) %2, %3</translation>
</message> </message>
<message> <message>
<source>Argon2 (KDBX 4 recommended)</source> <source>Argon2 (KDBX 4 recommended)</source>
@ -6174,7 +6174,7 @@ Commandes proposées :
</message> </message>
<message> <message>
<source>No key is set. Aborting database creation.</source> <source>No key is set. Aborting database creation.</source>
<translation>Aucune clé définie. Abandon de la création de la base de données.</translation> <translation>Aucune clé définie. La création de la base de données a é abandonnée.</translation>
</message> </message>
<message> <message>
<source>Failed to save the database: %1.</source> <source>Failed to save the database: %1.</source>
@ -6186,11 +6186,11 @@ Commandes proposées :
</message> </message>
<message> <message>
<source>Creating KeyFile %1 failed: %2</source> <source>Creating KeyFile %1 failed: %2</source>
<translation>Creation du fichier clé %1 échoué : %2 </translation> <translation>Impossible de créer le fichier clé %1 : %2 </translation>
</message> </message>
<message> <message>
<source>Loading KeyFile %1 failed: %2</source> <source>Loading KeyFile %1 failed: %2</source>
<translation>Chargement du fichier clé %1 échoué : %2</translation> <translation>Impossible de charger le fichier clé %1 : %2</translation>
</message> </message>
<message> <message>
<source>Path of the entry to remove.</source> <source>Path of the entry to remove.</source>
@ -6366,7 +6366,7 @@ Noyau : %3 %4</translation>
</message> </message>
<message> <message>
<source>Failed to open HIBP file %1: %2</source> <source>Failed to open HIBP file %1: %2</source>
<translation>Échec de louverture du fichier HIBP %1 : %2</translation> <translation>Impossible d&apos;ouvrir le fichier HIBP %1 : %2</translation>
</message> </message>
<message> <message>
<source>Evaluating database entries against HIBP file, this will take a while...</source> <source>Evaluating database entries against HIBP file, this will take a while...</source>
@ -6728,7 +6728,7 @@ Noyau : %3 %4</translation>
</message> </message>
<message> <message>
<source>ChaCha20 256-bit</source> <source>ChaCha20 256-bit</source>
<translation>ChaCha20 : 256 bits {20 256 à ?}</translation> <translation>ChaCha20 : 256 bits {20 256 à ?}</translation>
</message> </message>
<message> <message>
<source>Benchmark %1 delay</source> <source>Benchmark %1 delay</source>
@ -7272,7 +7272,7 @@ Noyau : %3 %4</translation>
</message> </message>
<message> <message>
<source>Key:</source> <source>Key:</source>
<translation>Clé:</translation> <translation>Clé :</translation>
</message> </message>
<message> <message>
<source>Generate</source> <source>Generate</source>
@ -7357,7 +7357,7 @@ Noyau : %3 %4</translation>
</message> </message>
<message> <message>
<source>The exported certificate is not the same as the one in use. Do you want to export the current certificate?</source> <source>The exported certificate is not the same as the one in use. Do you want to export the current certificate?</source>
<translation>Le certificat exporté est différent de celui en cours dutilisation. Souhaitez-vous exporter le certificat actuel?</translation> <translation>Le certificat exporté est différent de celui en cours dutilisation. Souhaitez-vous exporter le certificat actuel ?</translation>
</message> </message>
<message> <message>
<source>Signer:</source> <source>Signer:</source>
@ -7565,7 +7565,7 @@ Noyau : %3 %4</translation>
<name>TotpDialog</name> <name>TotpDialog</name>
<message> <message>
<source>Timed Password</source> <source>Timed Password</source>
<translation>Mot de passe programmé</translation> <translation>Mot de passe planifié</translation>
</message> </message>
<message> <message>
<source>000000</source> <source>000000</source>
@ -7633,7 +7633,7 @@ Noyau : %3 %4</translation>
</message> </message>
<message> <message>
<source>Code size:</source> <source>Code size:</source>
<translation>Taille du code:</translation> <translation>Taille du code :</translation>
</message> </message>
<message> <message>
<source>Secret Key:</source> <source>Secret Key:</source>
@ -7701,7 +7701,7 @@ Exemple : JBSWY3DPEHPK3PXP</translation>
</message> </message>
<message> <message>
<source>Update Error!</source> <source>Update Error!</source>
<translation>Erreur de mise à jour!</translation> <translation>Erreur lors de mise à jour !</translation>
</message> </message>
<message> <message>
<source>An error occurred in retrieving update information.</source> <source>An error occurred in retrieving update information.</source>
@ -7729,7 +7729,7 @@ Exemple : JBSWY3DPEHPK3PXP</translation>
</message> </message>
<message> <message>
<source>You&apos;re up-to-date!</source> <source>You&apos;re up-to-date!</source>
<translation>Votre version est à jour!</translation> <translation>Votre version est à jour !</translation>
</message> </message>
<message> <message>
<source>KeePassXC %1 is currently the newest version available</source> <source>KeePassXC %1 is currently the newest version available</source>

File diff suppressed because it is too large Load Diff

View File

@ -3032,7 +3032,7 @@ Támogatott kiterjesztések: %1.</translation>
</message> </message>
<message> <message>
<source>Plugin Data</source> <source>Plugin Data</source>
<translation>Beépülő adati</translation> <translation>Beépülő adatai</translation>
</message> </message>
<message> <message>
<source>Remove</source> <source>Remove</source>
@ -3085,7 +3085,7 @@ Ez a kijelölt bővítmény hibás működését eredményezheti.</translation>
<name>Entry</name> <name>Entry</name>
<message> <message>
<source>%1 - Clone</source> <source>%1 - Clone</source>
<translation>%1 Klónozás</translation> <translation>%1 Klón</translation>
</message> </message>
</context> </context>
<context> <context>
@ -4851,19 +4851,19 @@ Néhány hiba és kisebb nehézségek várhatóak, ezért ez a verzió nem aján
</message> </message>
<message> <message>
<source>{USERNAME}</source> <source>{USERNAME}</source>
<translation type="unfinished"/> <translation>{FELHASZNÁLÓNÉV}</translation>
</message> </message>
<message> <message>
<source>{USERNAME}{ENTER}</source> <source>{USERNAME}{ENTER}</source>
<translation type="unfinished"/> <translation>{FELHASZNÁLÓNÉV}{ENTER}</translation>
</message> </message>
<message> <message>
<source>{PASSWORD}</source> <source>{PASSWORD}</source>
<translation type="unfinished"/> <translation>{JELSZÓ}</translation>
</message> </message>
<message> <message>
<source>{PASSWORD}{ENTER}</source> <source>{PASSWORD}{ENTER}</source>
<translation type="unfinished"/> <translation>{JELSZÓ}{ENTER}</translation>
</message> </message>
</context> </context>
<context> <context>
@ -5510,7 +5510,7 @@ Néhány hiba és kisebb nehézségek várhatóak, ezért ez a verzió nem aján
</message> </message>
<message> <message>
<source>Very weak password</source> <source>Very weak password</source>
<translation>Nagy gyenge jelszó</translation> <translation>Nagyon gyenge jelszó</translation>
</message> </message>
<message> <message>
<source>Password entropy is %1 bits</source> <source>Password entropy is %1 bits</source>

View File

@ -350,7 +350,7 @@
</message> </message>
<message> <message>
<source>Tray icon type</source> <source>Tray icon type</source>
<translation type="unfinished"/> <translation>Systeemvak-pictogram</translation>
</message> </message>
</context> </context>
<context> <context>
@ -4852,19 +4852,19 @@ Wil je KeePassXC nu opnieuw opstarten?</translation>
</message> </message>
<message> <message>
<source>{USERNAME}</source> <source>{USERNAME}</source>
<translation type="unfinished"/> <translation>{GEBRUIKERSNAAM}</translation>
</message> </message>
<message> <message>
<source>{USERNAME}{ENTER}</source> <source>{USERNAME}{ENTER}</source>
<translation type="unfinished"/> <translation>{GEBRUIKERSNAAM}{ENTER}</translation>
</message> </message>
<message> <message>
<source>{PASSWORD}</source> <source>{PASSWORD}</source>
<translation type="unfinished"/> <translation>{WACHTWOORD}</translation>
</message> </message>
<message> <message>
<source>{PASSWORD}{ENTER}</source> <source>{PASSWORD}{ENTER}</source>
<translation type="unfinished"/> <translation>{WACHTWOORD}{ENTER}</translation>
</message> </message>
</context> </context>
<context> <context>

View File

@ -11,7 +11,7 @@
</message> </message>
<message> <message>
<source>Report bugs at: &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot; style=&quot;text-decoration: underline;&quot;&gt;https://github.com&lt;/a&gt;</source> <source>Report bugs at: &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot; style=&quot;text-decoration: underline;&quot;&gt;https://github.com&lt;/a&gt;</source>
<translation>Сообщать об ошибках: &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot; style=&quot;text-decoration: underline;&quot;&gt;https://github.com&lt;/a&gt;</translation> <translation>Сообщить об &lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/issues&quot; style=&quot;text-decoration: underline;&quot;&gt;ошибках&lt;/a&gt; по https://github.com</translation>
</message> </message>
<message> <message>
<source>KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.</source> <source>KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.</source>
@ -19,11 +19,11 @@
</message> </message>
<message> <message>
<source>Contributors</source> <source>Contributors</source>
<translation>Авторы</translation> <translation>Соавторы</translation>
</message> </message>
<message> <message>
<source>&lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/graphs/contributors&quot;&gt;See Contributions on GitHub&lt;/a&gt;</source> <source>&lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/graphs/contributors&quot;&gt;See Contributions on GitHub&lt;/a&gt;</source>
<translation>&lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/graphs/contributors&quot;&gt;Посмотреть вклад на GitHub&lt;/a&gt;</translation> <translation>&lt;a href=&quot;https://github.com/keepassxreboot/keepassxc/graphs/contributors&quot;&gt;Посмотреть соавторов на GitHub&lt;/a&gt;</translation>
</message> </message>
<message> <message>
<source>Debug Info</source> <source>Debug Info</source>
@ -2368,7 +2368,7 @@ Disable safe saves and try again?</source>
</message> </message>
<message> <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If checked, the entry will not appear in reports like Health Check and HIBP even if it doesn&apos;t match the quality requirements (e. g. password entropy or re-use). You can set the check mark if the password is beyond your control (e. g. if it needs to be a four-digit PIN) to prevent it from cluttering the reports.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source> <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If checked, the entry will not appear in reports like Health Check and HIBP even if it doesn&apos;t match the quality requirements (e. g. password entropy or re-use). You can set the check mark if the password is beyond your control (e. g. if it needs to be a four-digit PIN) to prevent it from cluttering the reports.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"/> <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;При включении, запись не появится в отчетах (например, Проверки безопасности или HIBP), даже если она не соответствует требованиям к качеству (энтропия, переиспользование). Можно включить этот параметр, если вы не можете контролировать этот пароль (например, 4-значные пин-кодыж), чтобы не засорять отчет.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message> </message>
<message> <message>
<source>Exclude from database reports</source> <source>Exclude from database reports</source>
@ -2482,7 +2482,7 @@ Disable safe saves and try again?</source>
</message> </message>
<message> <message>
<source>Only send this setting to the browser for HTTP Auth dialogs. If enabled, normal login forms will not show this entry for selection.</source> <source>Only send this setting to the browser for HTTP Auth dialogs. If enabled, normal login forms will not show this entry for selection.</source>
<translation type="unfinished"/> <translation>Отправлять эту настройку только браузерным диалогам для HTTP Auth. Если включено, обычные формы авторизации не покажут запись среди вариантов выбора.</translation>
</message> </message>
<message> <message>
<source>Use this entry only with HTTP Basic Auth</source> <source>Use this entry only with HTTP Basic Auth</source>
@ -6709,7 +6709,7 @@ Kernel: %3 %4</source>
<message> <message>
<source>All clipping programs failed. Tried %1 <source>All clipping programs failed. Tried %1
</source> </source>
<translation type="unfinished"/> <translation>Ни одна программа копирования не сработала. Пробовали %1</translation>
</message> </message>
<message> <message>
<source>AES (%1 rounds)</source> <source>AES (%1 rounds)</source>
@ -6847,7 +6847,7 @@ Kernel: %3 %4</source>
</message> </message>
<message> <message>
<source>Reason</source> <source>Reason</source>
<translation>Причика</translation> <translation>Причина</translation>
</message> </message>
<message> <message>
<source>Edit Entry...</source> <source>Edit Entry...</source>

View File

@ -137,7 +137,7 @@
</message> </message>
<message> <message>
<source>You must restart the application to set the new language. Would you like to restart now?</source> <source>You must restart the application to set the new language. Would you like to restart now?</source>
<translation type="unfinished"/> <translation>Musíte reštartovať aplikáciu, aby sa tieto zmeny prejavili. Chcete ju reštartovať teraz?</translation>
</message> </message>
</context> </context>
<context> <context>
@ -342,15 +342,15 @@
</message> </message>
<message> <message>
<source>Automatically save when locking database</source> <source>Automatically save when locking database</source>
<translation type="unfinished"/> <translation>Pri zamknutí databázy automaticky uložiť</translation>
</message> </message>
<message> <message>
<source>Automatically save non-data changes when locking database</source> <source>Automatically save non-data changes when locking database</source>
<translation type="unfinished"/> <translation>Pri zamknutí databázy automaticky uložiť nedátové zmeny</translation>
</message> </message>
<message> <message>
<source>Tray icon type</source> <source>Tray icon type</source>
<translation type="unfinished"/> <translation>Typ ikona oznamovacej oblasti</translation>
</message> </message>
</context> </context>
<context> <context>
@ -956,7 +956,7 @@ chrome-laptop.</translation>
</message> </message>
<message> <message>
<source>Select native messaging host folder location</source> <source>Select native messaging host folder location</source>
<translation type="unfinished"/> <translation>Vyberte umiestnenie zložky hostiteľa správe medzi prehliadačom a KeePassXC</translation>
</message> </message>
</context> </context>
<context> <context>
@ -4854,23 +4854,23 @@ Očakávajte chyby a menšie problémy, táto verzia nie je určená na produkč
</message> </message>
<message> <message>
<source>Perform Auto-Type Sequence</source> <source>Perform Auto-Type Sequence</source>
<translation type="unfinished"/> <translation>Vykonať Automatické vypĺňanie</translation>
</message> </message>
<message> <message>
<source>{USERNAME}</source> <source>{USERNAME}</source>
<translation type="unfinished"/> <translation>{POUŽÍVATEĽ}</translation>
</message> </message>
<message> <message>
<source>{USERNAME}{ENTER}</source> <source>{USERNAME}{ENTER}</source>
<translation type="unfinished"/> <translation>{POUŽÍVATEĽ}{ENTER}</translation>
</message> </message>
<message> <message>
<source>{PASSWORD}</source> <source>{PASSWORD}</source>
<translation type="unfinished"/> <translation>{HESLO}</translation>
</message> </message>
<message> <message>
<source>{PASSWORD}{ENTER}</source> <source>{PASSWORD}{ENTER}</source>
<translation type="unfinished"/> <translation>{HESLO}{ENTER}</translation>
</message> </message>
</context> </context>
<context> <context>
@ -6571,7 +6571,7 @@ Jadro: %3 %4</translation>
</message> </message>
<message> <message>
<source>Could not save the native messaging script file for %1.</source> <source>Could not save the native messaging script file for %1.</source>
<translation type="unfinished"/> <translation>Nemožno uložiť súbor skriptu správ medzi prehliadačom a KeePassXC (native messaging) pre %1.</translation>
</message> </message>
<message> <message>
<source>Copy the given attribute to the clipboard. Defaults to &quot;password&quot; if not specified.</source> <source>Copy the given attribute to the clipboard. Defaults to &quot;password&quot; if not specified.</source>

View File

@ -3127,7 +3127,7 @@ This may cause the affected plugins to malfunction.</source>
</message> </message>
<message numerus="yes"> <message numerus="yes">
<source>Are you sure you want to remove %n attachment(s)?</source> <source>Are you sure you want to remove %n attachment(s)?</source>
<translation><numerusform> n </numerusform></translation> <translation><numerusform></numerusform></translation>
</message> </message>
<message> <message>
<source>Save attachments</source> <source>Save attachments</source>

View File

@ -4853,19 +4853,19 @@ Expect some bugs and minor issues, this version is not meant for production use.
</message> </message>
<message> <message>
<source>{USERNAME}</source> <source>{USERNAME}</source>
<translation type="unfinished"/> <translation>{USERNAME}</translation>
</message> </message>
<message> <message>
<source>{USERNAME}{ENTER}</source> <source>{USERNAME}{ENTER}</source>
<translation type="unfinished"/> <translation>{USERNAME}{ENTER}</translation>
</message> </message>
<message> <message>
<source>{PASSWORD}</source> <source>{PASSWORD}</source>
<translation type="unfinished"/> <translation>{PASSWORD}</translation>
</message> </message>
<message> <message>
<source>{PASSWORD}{ENTER}</source> <source>{PASSWORD}{ENTER}</source>
<translation type="unfinished"/> <translation>{PASSWORD}{ENTER}</translation>
</message> </message>
</context> </context>
<context> <context>

View File

@ -322,7 +322,7 @@ QString BrowserService::storeKey(const QString& key)
do { do {
QInputDialog keyDialog; QInputDialog keyDialog;
connect(m_currentDatabaseWidget, SIGNAL(databaseLocked()), &keyDialog, SLOT(reject())); connect(m_currentDatabaseWidget, SIGNAL(databaseLockRequested()), &keyDialog, SLOT(reject()));
keyDialog.setWindowTitle(tr("KeePassXC: New key association request")); keyDialog.setWindowTitle(tr("KeePassXC: New key association request"));
keyDialog.setLabelText(tr("You have received an association request for the following database:\n%1\n\n" keyDialog.setLabelText(tr("You have received an association request for the following database:\n%1\n\n"
"Give the connection a unique name or ID, for example:\nchrome-laptop.") "Give the connection a unique name or ID, for example:\nchrome-laptop.")
@ -778,7 +778,7 @@ QList<Entry*> BrowserService::confirmEntries(QList<Entry*>& pwEntriesToConfirm,
updateWindowState(); updateWindowState();
BrowserAccessControlDialog accessControlDialog; BrowserAccessControlDialog accessControlDialog;
connect(m_currentDatabaseWidget, SIGNAL(databaseLocked()), &accessControlDialog, SLOT(reject())); connect(m_currentDatabaseWidget, SIGNAL(databaseLockRequested()), &accessControlDialog, SLOT(reject()));
connect(&accessControlDialog, &BrowserAccessControlDialog::disableAccess, [&](QTableWidgetItem* item) { connect(&accessControlDialog, &BrowserAccessControlDialog::disableAccess, [&](QTableWidgetItem* item) {
auto entry = pwEntriesToConfirm[item->row()]; auto entry = pwEntriesToConfirm[item->row()];

View File

@ -36,8 +36,6 @@ const int Entry::ResolveMaximumDepth = 10;
const QString Entry::AutoTypeSequenceUsername = "{USERNAME}{ENTER}"; const QString Entry::AutoTypeSequenceUsername = "{USERNAME}{ENTER}";
const QString Entry::AutoTypeSequencePassword = "{PASSWORD}{ENTER}"; const QString Entry::AutoTypeSequencePassword = "{PASSWORD}{ENTER}";
Entry::CloneFlags Entry::DefaultCloneFlags = Entry::CloneNewUuid | Entry::CloneResetTimeInfo;
Entry::Entry() Entry::Entry()
: m_attributes(new EntryAttributes(this)) : m_attributes(new EntryAttributes(this))
, m_attachments(new EntryAttachments(this)) , m_attachments(new EntryAttachments(this))

View File

@ -161,6 +161,8 @@ public:
CloneNewUuid = 1, // generate a random uuid for the clone CloneNewUuid = 1, // generate a random uuid for the clone
CloneResetTimeInfo = 2, // set all TimeInfo attributes to the current time CloneResetTimeInfo = 2, // set all TimeInfo attributes to the current time
CloneIncludeHistory = 4, // clone the history items CloneIncludeHistory = 4, // clone the history items
CloneDefault = CloneNewUuid | CloneResetTimeInfo,
CloneCopy = CloneNewUuid | CloneResetTimeInfo | CloneIncludeHistory,
CloneRenameTitle = 8, // add "-Clone" after the original title CloneRenameTitle = 8, // add "-Clone" after the original title
CloneUserAsRef = 16, // Add the user as a reference to the original entry CloneUserAsRef = 16, // Add the user as a reference to the original entry
ClonePassAsRef = 32, // Add the password as a reference to the original entry ClonePassAsRef = 32, // Add the password as a reference to the original entry
@ -210,7 +212,6 @@ public:
static const int ResolveMaximumDepth; static const int ResolveMaximumDepth;
static const QString AutoTypeSequenceUsername; static const QString AutoTypeSequenceUsername;
static const QString AutoTypeSequencePassword; static const QString AutoTypeSequencePassword;
static CloneFlags DefaultCloneFlags;
/** /**
* Creates a duplicate of this entry except that the returned entry isn't * Creates a duplicate of this entry except that the returned entry isn't
@ -218,7 +219,7 @@ public:
* Note that you need to copy the custom icons manually when inserting the * Note that you need to copy the custom icons manually when inserting the
* new entry into another database. * new entry into another database.
*/ */
Entry* clone(CloneFlags flags = DefaultCloneFlags) const; Entry* clone(CloneFlags flags = CloneDefault) const;
void copyDataFrom(const Entry* other); void copyDataFrom(const Entry* other);
QString maskPasswordPlaceholders(const QString& str) const; QString maskPasswordPlaceholders(const QString& str) const;
Entry* resolveReference(const QString& str) const; Entry* resolveReference(const QString& str) const;

View File

@ -36,9 +36,6 @@ const int Group::DefaultIconNumber = 48;
const int Group::RecycleBinIconNumber = 43; const int Group::RecycleBinIconNumber = 43;
const QString Group::RootAutoTypeSequence = "{USERNAME}{TAB}{PASSWORD}{ENTER}"; const QString Group::RootAutoTypeSequence = "{USERNAME}{TAB}{PASSWORD}{ENTER}";
Group::CloneFlags Group::DefaultCloneFlags =
Group::CloneNewUuid | Group::CloneResetTimeInfo | Group::CloneIncludeEntries;
Group::Group() Group::Group()
: m_customData(new CustomData(this)) : m_customData(new CustomData(this))
, m_updateTimeinfo(true) , m_updateTimeinfo(true)

View File

@ -56,6 +56,7 @@ public:
CloneNewUuid = 1, // generate a random uuid for the clone CloneNewUuid = 1, // generate a random uuid for the clone
CloneResetTimeInfo = 2, // set all TimeInfo attributes to the current time CloneResetTimeInfo = 2, // set all TimeInfo attributes to the current time
CloneIncludeEntries = 4, // clone the group entries CloneIncludeEntries = 4, // clone the group entries
CloneDefault = CloneNewUuid | CloneResetTimeInfo | CloneIncludeEntries,
}; };
Q_DECLARE_FLAGS(CloneFlags, CloneFlag) Q_DECLARE_FLAGS(CloneFlags, CloneFlag)
@ -108,7 +109,6 @@ public:
static const int DefaultIconNumber; static const int DefaultIconNumber;
static const int RecycleBinIconNumber; static const int RecycleBinIconNumber;
static CloneFlags DefaultCloneFlags;
static const QString RootAutoTypeSequence; static const QString RootAutoTypeSequence;
Group* findChildByName(const QString& name); Group* findChildByName(const QString& name);
@ -157,8 +157,8 @@ public:
QSet<QUuid> customIconsRecursive() const; QSet<QUuid> customIconsRecursive() const;
QList<QString> usernamesRecursive(int topN = -1) const; QList<QString> usernamesRecursive(int topN = -1) const;
Group* clone(Entry::CloneFlags entryFlags = Entry::DefaultCloneFlags, Group* clone(Entry::CloneFlags entryFlags = Entry::CloneDefault,
CloneFlags groupFlags = DefaultCloneFlags) const; Group::CloneFlags groupFlags = Group::CloneDefault) const;
void copyDataFrom(const Group* other); void copyDataFrom(const Group* other);
QString print(bool recursive = false, bool flatten = false, int depth = 0); QString print(bool recursive = false, bool flatten = false, int depth = 0);

View File

@ -73,7 +73,7 @@ QString Crypto::debugInfo()
Q_ASSERT(Crypto::initialized()); Q_ASSERT(Crypto::initialized());
QString debugInfo = QObject::tr("Cryptographic libraries:").append("\n"); QString debugInfo = QObject::tr("Cryptographic libraries:").append("\n");
debugInfo.append(" libgcrypt ").append(m_backendVersion).append("\n"); debugInfo.append("- libgcrypt ").append(m_backendVersion).append("\n");
return debugInfo; return debugInfo;
} }

View File

@ -59,6 +59,7 @@ static const QString aboutContributors = R"(
<li>Kernellinux</li> <li>Kernellinux</li>
<li>Micha Ober</li> <li>Micha Ober</li>
<li>PublicByte</li> <li>PublicByte</li>
<li>Clayton Casciato</li>
</ul> </ul>
<h3>Notable Code Contributions:</h3> <h3>Notable Code Contributions:</h3>
<ul> <ul>
@ -86,7 +87,6 @@ static const QString aboutContributors = R"(
</ul> </ul>
<h3>Patreon Supporters:</h3> <h3>Patreon Supporters:</h3>
<ul> <ul>
<li>Igor Zinovik</li>
<li>Alexanderjb</li> <li>Alexanderjb</li>
<li>Richard Ames</li> <li>Richard Ames</li>
<li>SLmanDR</li> <li>SLmanDR</li>
@ -94,7 +94,7 @@ static const QString aboutContributors = R"(
<li>Tyler Gass</li> <li>Tyler Gass</li>
<li>Nuutti Toivola</li> <li>Nuutti Toivola</li>
<li>Gregory Werbin</li> <li>Gregory Werbin</li>
<li>Lionel Laské</li> <li>Lionel Laské</li>
<li>Ivar</li> <li>Ivar</li>
<li>Darren</li> <li>Darren</li>
<li>Brad</li> <li>Brad</li>

View File

@ -59,7 +59,12 @@ void Clipboard::setText(const QString& text, bool clear)
clipboard->setMimeData(mime, QClipboard::Clipboard); clipboard->setMimeData(mime, QClipboard::Clipboard);
#else #else
mime->setText(text); mime->setText(text);
#ifdef Q_OS_LINUX
mime->setData("x-kde-passwordManagerHint", QByteArrayLiteral("secret")); mime->setData("x-kde-passwordManagerHint", QByteArrayLiteral("secret"));
#endif
#ifdef Q_OS_WIN
mime->setData("ExcludeClipboardContentFromMonitorProcessing", QByteArrayLiteral("1"));
#endif
clipboard->setMimeData(mime, QClipboard::Clipboard); clipboard->setMimeData(mime, QClipboard::Clipboard);
if (clipboard->supportsSelection()) { if (clipboard->supportsSelection()) {

View File

@ -20,12 +20,19 @@
#include "DatabaseWidget.h" #include "DatabaseWidget.h"
#include "core/Database.h" #include "core/Database.h"
#ifdef Q_OS_WIN
#include <QtPlatformHeaders/QWindowsWindowFunctions>
#endif
DatabaseOpenDialog::DatabaseOpenDialog(QWidget* parent) DatabaseOpenDialog::DatabaseOpenDialog(QWidget* parent)
: QDialog(parent) : QDialog(parent)
, m_view(new DatabaseOpenWidget(this)) , m_view(new DatabaseOpenWidget(this))
{ {
setWindowTitle(tr("Unlock Database - KeePassXC")); setWindowTitle(tr("Unlock Database - KeePassXC"));
setWindowFlags(Qt::Dialog | Qt::WindowStaysOnTopHint); setWindowFlags(Qt::Dialog | Qt::WindowStaysOnTopHint);
#ifdef Q_OS_WIN
QWindowsWindowFunctions::setWindowActivationBehavior(QWindowsWindowFunctions::AlwaysActivateWindow);
#endif
connect(m_view, SIGNAL(dialogFinished(bool)), this, SLOT(complete(bool))); connect(m_view, SIGNAL(dialogFinished(bool)), this, SLOT(complete(bool)));
auto* layout = new QVBoxLayout(); auto* layout = new QVBoxLayout();
layout->setMargin(0); layout->setMargin(0);

View File

@ -165,6 +165,7 @@ void DatabaseOpenWidget::clearForms()
m_ui->editPassword->setText(""); m_ui->editPassword->setText("");
m_ui->editPassword->setShowPassword(false); m_ui->editPassword->setShowPassword(false);
m_ui->keyFileLineEdit->clear(); m_ui->keyFileLineEdit->clear();
m_ui->keyFileLineEdit->setShowPassword(false);
m_ui->checkTouchID->setChecked(false); m_ui->checkTouchID->setChecked(false);
m_ui->challengeResponseCombo->clear(); m_ui->challengeResponseCombo->clear();
m_db.reset(); m_db.reset();
@ -380,6 +381,7 @@ void DatabaseOpenWidget::browseKeyFile()
void DatabaseOpenWidget::clearKeyFileText() void DatabaseOpenWidget::clearKeyFileText()
{ {
m_ui->keyFileLineEdit->clear(); m_ui->keyFileLineEdit->clear();
m_ui->keyFileLineEdit->setShowPassword(false);
} }
void DatabaseOpenWidget::pollHardwareKey() void DatabaseOpenWidget::pollHardwareKey()

View File

@ -406,7 +406,7 @@
<number>0</number> <number>0</number>
</property> </property>
<item row="0" column="1"> <item row="0" column="1">
<widget class="QLineEdit" name="keyFileLineEdit"> <widget class="PasswordEdit" name="keyFileLineEdit">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -416,6 +416,9 @@
<property name="accessibleName"> <property name="accessibleName">
<string>Key file to unlock the database</string> <string>Key file to unlock the database</string>
</property> </property>
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
<property name="clearButtonEnabled"> <property name="clearButtonEnabled">
<bool>true</bool> <bool>true</bool>
</property> </property>

View File

@ -216,7 +216,7 @@ DatabaseWidget::DatabaseWidget(QSharedPointer<Database> db, QWidget* parent)
#ifdef WITH_XC_SSHAGENT #ifdef WITH_XC_SSHAGENT
if (sshAgent()->isEnabled()) { if (sshAgent()->isEnabled()) {
connect(this, SIGNAL(databaseLockRequested()), sshAgent(), SLOT(databaseLocked())); connect(this, SIGNAL(databaseLocked()), sshAgent(), SLOT(databaseLocked()));
connect(this, SIGNAL(databaseUnlocked()), sshAgent(), SLOT(databaseUnlocked())); connect(this, SIGNAL(databaseUnlocked()), sshAgent(), SLOT(databaseUnlocked()));
} }
#endif #endif
@ -437,6 +437,7 @@ void DatabaseWidget::showTotp()
} }
auto totpDialog = new TotpDialog(this, currentEntry); auto totpDialog = new TotpDialog(this, currentEntry);
connect(this, &DatabaseWidget::databaseLockRequested, totpDialog, &TotpDialog::close);
totpDialog->open(); totpDialog->open();
} }
@ -460,6 +461,7 @@ void DatabaseWidget::setupTotp()
auto setupTotpDialog = new TotpSetupDialog(this, currentEntry); auto setupTotpDialog = new TotpSetupDialog(this, currentEntry);
connect(setupTotpDialog, SIGNAL(totpUpdated()), SIGNAL(entrySelectionChanged())); connect(setupTotpDialog, SIGNAL(totpUpdated()), SIGNAL(entrySelectionChanged()));
connect(this, &DatabaseWidget::databaseLockRequested, setupTotpDialog, &TotpSetupDialog::close);
setupTotpDialog->open(); setupTotpDialog->open();
} }
@ -703,6 +705,7 @@ void DatabaseWidget::showTotpKeyQrCode()
auto currentEntry = currentSelectedEntry(); auto currentEntry = currentSelectedEntry();
if (currentEntry) { if (currentEntry) {
auto totpDisplayDialog = new TotpExportSettingsDialog(this, currentEntry); auto totpDisplayDialog = new TotpExportSettingsDialog(this, currentEntry);
connect(this, &DatabaseWidget::databaseLockRequested, totpDisplayDialog, &TotpExportSettingsDialog::close);
totpDisplayDialog->open(); totpDisplayDialog->open();
} }
} }
@ -1533,6 +1536,11 @@ bool DatabaseWidget::lock()
emit databaseLockRequested(); emit databaseLockRequested();
// ignore event if we are active and a modal dialog is still open (such as a message box or file dialog)
if (isVisible() && QApplication::activeModalWidget()) {
return false;
}
clipboard()->clearCopiedText(); clipboard()->clearCopiedText();
if (isEditWidgetModified()) { if (isEditWidgetModified()) {

View File

@ -74,6 +74,18 @@ void EditWidget::addPage(const QString& labelText, const QIcon& icon, QWidget* w
m_ui->categoryList->addCategory(labelText, icon); m_ui->categoryList->addCategory(labelText, icon);
} }
bool EditWidget::hasPage(QWidget* widget)
{
for (int i = 0; i < m_ui->stackedWidget->count(); i++) {
auto* scrollArea = qobject_cast<QScrollArea*>(m_ui->stackedWidget->widget(i));
if (scrollArea && scrollArea->widget() == widget) {
return true;
}
}
return false;
}
void EditWidget::setPageHidden(QWidget* widget, bool hidden) void EditWidget::setPageHidden(QWidget* widget, bool hidden)
{ {
int index = -1; int index = -1;

View File

@ -42,6 +42,7 @@ public:
~EditWidget(); ~EditWidget();
void addPage(const QString& labelText, const QIcon& icon, QWidget* widget); void addPage(const QString& labelText, const QIcon& icon, QWidget* widget);
bool hasPage(QWidget* widget);
void setPageHidden(QWidget* widget, bool hidden); void setPageHidden(QWidget* widget, bool hidden);
void setCurrentPage(int index); void setCurrentPage(int index);
void setHeadline(const QString& text); void setHeadline(const QString& text);

View File

@ -286,14 +286,18 @@ void EntryPreviewWidget::updateEntryAdvancedTab()
setTabEnabled(m_ui->entryTabWidget, m_ui->entryAdvancedTab, hasAttributes || hasAttachments); setTabEnabled(m_ui->entryTabWidget, m_ui->entryAdvancedTab, hasAttributes || hasAttachments);
if (hasAttributes) { if (hasAttributes) {
QString attributesText; QString attributesText("<table>");
for (const QString& key : customAttributes) { for (const QString& key : customAttributes) {
QString value = m_currentEntry->attributes()->value(key); QString value;
if (m_currentEntry->attributes()->isProtected(key)) { if (m_currentEntry->attributes()->isProtected(key)) {
value = "<i>" + tr("[PROTECTED]") + "</i>"; value = "<i>" + tr("[PROTECTED]") + "</i>";
} else {
value = m_currentEntry->attributes()->value(key).toHtmlEscaped();
value.replace('\n', QLatin1String("<br/>"));
} }
attributesText.append(tr("<b>%1</b>: %2", "attributes line").arg(key, value).append("<br/>")); attributesText.append(tr("<tr><td><b>%1</b>:</td><td>%2</td></tr>", "attributes line").arg(key, value));
} }
attributesText.append("</table>");
m_ui->entryAttributesEdit->setText(attributesText); m_ui->entryAttributesEdit->setText(attributesText);
} }
@ -303,6 +307,8 @@ void EntryPreviewWidget::updateEntryAdvancedTab()
void EntryPreviewWidget::updateEntryAutotypeTab() void EntryPreviewWidget::updateEntryAutotypeTab()
{ {
Q_ASSERT(m_currentEntry); Q_ASSERT(m_currentEntry);
m_ui->entrySequenceLabel->setText(m_currentEntry->effectiveAutoTypeSequence());
m_ui->entryAutotypeTree->clear(); m_ui->entryAutotypeTree->clear();
QList<QTreeWidgetItem*> items; QList<QTreeWidgetItem*> items;
const AutoTypeAssociations* autotypeAssociations = m_currentEntry->autoTypeAssociations(); const AutoTypeAssociations* autotypeAssociations = m_currentEntry->autoTypeAssociations();
@ -314,7 +320,7 @@ void EntryPreviewWidget::updateEntryAutotypeTab()
} }
m_ui->entryAutotypeTree->addTopLevelItems(items); m_ui->entryAutotypeTree->addTopLevelItems(items);
setTabEnabled(m_ui->entryTabWidget, m_ui->entryAutotypeTab, !items.isEmpty()); setTabEnabled(m_ui->entryTabWidget, m_ui->entryAutotypeTab, m_currentEntry->autoTypeEnabled());
} }
void EntryPreviewWidget::updateGroupHeaderLine() void EntryPreviewWidget::updateGroupHeaderLine()

View File

@ -705,6 +705,62 @@
<string>Autotype</string> <string>Autotype</string>
</attribute> </attribute>
<layout class="QVBoxLayout" name="verticalLayout_4"> <layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QWidget" name="entryAutotypeWidget" native="true">
<layout class="QGridLayout" name="gridLayout_3">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="entrySequenceTitleLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Default Sequence</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="entrySequenceLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true">sequence</string>
</property>
<property name="alignment">
<set>Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item> <item>
<widget class="QTreeWidget" name="entryAutotypeTree"> <widget class="QTreeWidget" name="entryAutotypeTree">
<property name="focusPolicy"> <property name="focusPolicy">

View File

@ -536,6 +536,11 @@ MainWindow::MainWindow()
m_ui->actionGroupDownloadFavicons->setVisible(false); m_ui->actionGroupDownloadFavicons->setVisible(false);
m_ui->actionEntryDownloadIcon->setVisible(false); m_ui->actionEntryDownloadIcon->setVisible(false);
#endif #endif
#ifndef WITH_XC_DOCS
m_ui->actionGettingStarted->setVisible(false);
m_ui->actionUserGuide->setVisible(false);
m_ui->actionKeyboardShortcuts->setVisible(false);
#endif
// clang-format off // clang-format off
connect(m_ui->tabWidget, SIGNAL(messageGlobal(QString,MessageWidget::MessageType)), connect(m_ui->tabWidget, SIGNAL(messageGlobal(QString,MessageWidget::MessageType)),
@ -793,7 +798,9 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
m_ui->actionGroupSortDesc->setEnabled(groupSelected && currentGroupHasChildren); m_ui->actionGroupSortDesc->setEnabled(groupSelected && currentGroupHasChildren);
m_ui->actionGroupEmptyRecycleBin->setVisible(recycleBinSelected); m_ui->actionGroupEmptyRecycleBin->setVisible(recycleBinSelected);
m_ui->actionGroupEmptyRecycleBin->setEnabled(recycleBinSelected); m_ui->actionGroupEmptyRecycleBin->setEnabled(recycleBinSelected);
#ifdef WITH_XC_NETWORKING
m_ui->actionGroupDownloadFavicons->setVisible(!recycleBinSelected); m_ui->actionGroupDownloadFavicons->setVisible(!recycleBinSelected);
#endif
m_ui->actionGroupDownloadFavicons->setEnabled(groupSelected && currentGroupHasEntries m_ui->actionGroupDownloadFavicons->setEnabled(groupSelected && currentGroupHasEntries
&& !recycleBinSelected); && !recycleBinSelected);
m_ui->actionDatabaseSecurity->setEnabled(true); m_ui->actionDatabaseSecurity->setEnabled(true);
@ -1579,11 +1586,6 @@ void MainWindow::toggleWindow()
void MainWindow::lockDatabasesAfterInactivity() void MainWindow::lockDatabasesAfterInactivity()
{ {
// ignore event if a modal dialog is open (such as a message box or file dialog)
if (QApplication::activeModalWidget()) {
return;
}
m_ui->tabWidget->lockDatabases(); m_ui->tabWidget->lockDatabases();
} }

View File

@ -174,9 +174,9 @@ void PasswordGeneratorWidget::saveSettings()
config()->set(Config::PasswordGenerator_AdvancedMode, m_ui->buttonAdvancedMode->isChecked()); config()->set(Config::PasswordGenerator_AdvancedMode, m_ui->buttonAdvancedMode->isChecked());
if (m_ui->buttonAdvancedMode->isChecked()) { if (m_ui->buttonAdvancedMode->isChecked()) {
config()->set(Config::PasswordGenerator_SpecialChars, m_ui->checkBoxSpecialChars->isChecked());
} else {
config()->set(Config::PasswordGenerator_Logograms, m_ui->checkBoxSpecialChars->isChecked()); config()->set(Config::PasswordGenerator_Logograms, m_ui->checkBoxSpecialChars->isChecked());
} else {
config()->set(Config::PasswordGenerator_SpecialChars, m_ui->checkBoxSpecialChars->isChecked());
} }
config()->set(Config::PasswordGenerator_Braces, m_ui->checkBoxBraces->isChecked()); config()->set(Config::PasswordGenerator_Braces, m_ui->checkBoxBraces->isChecked());
config()->set(Config::PasswordGenerator_Punctuation, m_ui->checkBoxPunctuation->isChecked()); config()->set(Config::PasswordGenerator_Punctuation, m_ui->checkBoxPunctuation->isChecked());

View File

@ -259,9 +259,6 @@ QProgressBar::chunk {
<property name="minimum"> <property name="minimum">
<number>1</number> <number>1</number>
</property> </property>
<property name="maximum">
<number>128</number>
</property>
<property name="value"> <property name="value">
<number>20</number> <number>20</number>
</property> </property>

View File

@ -31,10 +31,7 @@ TotpDialog::TotpDialog(QWidget* parent, Entry* entry)
, m_ui(new Ui::TotpDialog()) , m_ui(new Ui::TotpDialog())
, m_entry(entry) , m_entry(entry)
{ {
if (!m_entry->hasTotp()) { setAttribute(Qt::WA_DeleteOnClose);
close();
return;
}
m_ui->setupUi(this); m_ui->setupUi(this);
@ -42,14 +39,11 @@ TotpDialog::TotpDialog(QWidget* parent, Entry* entry)
resetCounter(); resetCounter();
updateProgressBar(); updateProgressBar();
connect(parent, SIGNAL(databaseLocked()), SLOT(close()));
connect(&m_totpUpdateTimer, SIGNAL(timeout()), this, SLOT(updateProgressBar())); connect(&m_totpUpdateTimer, SIGNAL(timeout()), this, SLOT(updateProgressBar()));
connect(&m_totpUpdateTimer, SIGNAL(timeout()), this, SLOT(updateSeconds())); connect(&m_totpUpdateTimer, SIGNAL(timeout()), this, SLOT(updateSeconds()));
m_totpUpdateTimer.start(m_step * 10); m_totpUpdateTimer.start(m_step * 10);
updateTotp(); updateTotp();
setAttribute(Qt::WA_DeleteOnClose);
new QShortcut(QKeySequence(QKeySequence::Copy), this, SLOT(copyToClipboard())); new QShortcut(QKeySequence(QKeySequence::Copy), this, SLOT(copyToClipboard()));
m_ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Copy")); m_ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Copy"));

View File

@ -59,7 +59,6 @@ TotpExportSettingsDialog::TotpExportSettingsDialog(DatabaseWidget* parent, Entry
connect(m_buttonBox, SIGNAL(rejected()), SLOT(close())); connect(m_buttonBox, SIGNAL(rejected()), SLOT(close()));
connect(m_buttonBox, SIGNAL(accepted()), SLOT(copyToClipboard())); connect(m_buttonBox, SIGNAL(accepted()), SLOT(copyToClipboard()));
connect(m_timer, SIGNAL(timeout()), SLOT(autoClose())); connect(m_timer, SIGNAL(timeout()), SLOT(autoClose()));
connect(parent, SIGNAL(lockedDatabase()), SLOT(close()));
new QShortcut(QKeySequence(QKeySequence::Copy), this, SLOT(copyToClipboard())); new QShortcut(QKeySequence(QKeySequence::Copy), this, SLOT(copyToClipboard()));

View File

@ -178,9 +178,6 @@ void EditEntryWidget::setupMain()
m_mainUi->expirePresets->setMenu(createPresetsMenu()); m_mainUi->expirePresets->setMenu(createPresetsMenu());
connect(m_mainUi->expirePresets->menu(), SIGNAL(triggered(QAction*)), this, SLOT(useExpiryPreset(QAction*))); connect(m_mainUi->expirePresets->menu(), SIGNAL(triggered(QAction*)), this, SLOT(useExpiryPreset(QAction*)));
// HACK: Align username text with other line edits. Qt does not let you do this with an application stylesheet.
m_mainUi->usernameComboBox->lineEdit()->setStyleSheet("padding-left: 8px;");
} }
void EditEntryWidget::setupAdvanced() void EditEntryWidget::setupAdvanced()
@ -268,9 +265,8 @@ void EditEntryWidget::setupAutoType()
#ifdef WITH_XC_BROWSER #ifdef WITH_XC_BROWSER
void EditEntryWidget::setupBrowser() void EditEntryWidget::setupBrowser()
{ {
m_browserUi->setupUi(m_browserWidget);
if (config()->get(Config::Browser_Enabled).toBool()) { if (config()->get(Config::Browser_Enabled).toBool()) {
m_browserUi->setupUi(m_browserWidget);
addPage(tr("Browser Integration"), icons()->icon("internet-web-browser"), m_browserWidget); addPage(tr("Browser Integration"), icons()->icon("internet-web-browser"), m_browserWidget);
m_additionalURLsDataModel->setEntryAttributes(m_entryAttributes); m_additionalURLsDataModel->setEntryAttributes(m_entryAttributes);
m_browserUi->additionalURLsView->setModel(m_additionalURLsDataModel); m_browserUi->additionalURLsView->setModel(m_additionalURLsDataModel);
@ -944,6 +940,11 @@ void EditEntryWidget::setForms(Entry* entry, bool restore)
#endif #endif
#ifdef WITH_XC_BROWSER #ifdef WITH_XC_BROWSER
if (config()->get(Config::Browser_Enabled).toBool()) {
if (!hasPage(m_browserWidget)) {
setupBrowser();
}
if (m_customData->contains(BrowserService::OPTION_SKIP_AUTO_SUBMIT)) { if (m_customData->contains(BrowserService::OPTION_SKIP_AUTO_SUBMIT)) {
// clang-format off // clang-format off
m_browserUi->skipAutoSubmitCheckbox->setChecked(m_customData->value(BrowserService::OPTION_SKIP_AUTO_SUBMIT) == TRUE_STR); m_browserUi->skipAutoSubmitCheckbox->setChecked(m_customData->value(BrowserService::OPTION_SKIP_AUTO_SUBMIT) == TRUE_STR);
@ -953,7 +954,8 @@ void EditEntryWidget::setForms(Entry* entry, bool restore)
} }
if (m_customData->contains(BrowserService::OPTION_HIDE_ENTRY)) { if (m_customData->contains(BrowserService::OPTION_HIDE_ENTRY)) {
m_browserUi->hideEntryCheckbox->setChecked(m_customData->value(BrowserService::OPTION_HIDE_ENTRY) == TRUE_STR); m_browserUi->hideEntryCheckbox->setChecked(m_customData->value(BrowserService::OPTION_HIDE_ENTRY)
== TRUE_STR);
} else { } else {
m_browserUi->hideEntryCheckbox->setChecked(false); m_browserUi->hideEntryCheckbox->setChecked(false);
} }
@ -980,6 +982,9 @@ void EditEntryWidget::setForms(Entry* entry, bool restore)
if (m_additionalURLsDataModel->rowCount() != 0) { if (m_additionalURLsDataModel->rowCount() != 0) {
m_browserUi->additionalURLsView->setCurrentIndex(m_additionalURLsDataModel->index(0, 0)); m_browserUi->additionalURLsView->setCurrentIndex(m_additionalURLsDataModel->index(0, 0));
} }
}
setPageHidden(m_browserWidget, !config()->get(Config::Browser_Enabled).toBool());
#endif #endif
m_editWidgetProperties->setFields(entry->timeInfo(), entry->uuid()); m_editWidgetProperties->setFields(entry->timeInfo(), entry->uuid());
@ -1013,6 +1018,15 @@ bool EditEntryWidget::commitEntry()
return true; return true;
} }
// HACK: Check that entry pointer is still valid, see https://github.com/keepassxreboot/keepassxc/issues/5722
if (!m_entry) {
QMessageBox::information(this,
tr("Invalid Entry"),
tr("An external merge operation has invalidated this entry.\n"
"Unfortunately, any changes made have been lost."));
return true;
}
// Check Auto-Type validity early // Check Auto-Type validity early
if (!AutoType::verifyAutoTypeSyntax(m_autoTypeUi->sequenceEdit->text())) { if (!AutoType::verifyAutoTypeSyntax(m_autoTypeUi->sequenceEdit->text())) {
return false; return false;

View File

@ -262,13 +262,13 @@ bool GroupModel::dropMimeData(const QMimeData* data,
targetDb->metadata()->copyCustomIcons(customIcons, sourceDb->metadata()); targetDb->metadata()->copyCustomIcons(customIcons, sourceDb->metadata());
// Always clone the group across db's to reset UUIDs // Always clone the group across db's to reset UUIDs
group = dragGroup->clone(); group = dragGroup->clone(Entry::CloneDefault | Entry::CloneIncludeHistory);
if (action == Qt::MoveAction) { if (action == Qt::MoveAction) {
// Remove the original group from the sourceDb // Remove the original group from the sourceDb
delete dragGroup; delete dragGroup;
} }
} else if (action == Qt::CopyAction) { } else if (action == Qt::CopyAction) {
group = dragGroup->clone(); group = dragGroup->clone(Entry::CloneCopy);
} }
group->setParent(parentGroup, row); group->setParent(parentGroup, row);
@ -303,13 +303,13 @@ bool GroupModel::dropMimeData(const QMimeData* data,
targetDb->metadata()->addCustomIcon(customIcon, sourceDb->metadata()->customIcon(customIcon)); targetDb->metadata()->addCustomIcon(customIcon, sourceDb->metadata()->customIcon(customIcon));
} }
// Always clone the entry across db's to reset the UUID // Reset the UUID when moving across db boundary
entry = dragEntry->clone(); entry = dragEntry->clone(Entry::CloneDefault | Entry::CloneIncludeHistory);
if (action == Qt::MoveAction) { if (action == Qt::MoveAction) {
delete dragEntry; delete dragEntry;
} }
} else if (action == Qt::CopyAction) { } else if (action == Qt::CopyAction) {
entry = dragEntry->clone(); entry = dragEntry->clone(Entry::CloneCopy);
} }
entry->setGroup(parentGroup); entry->setGroup(parentGroup);

View File

@ -127,10 +127,12 @@ void NixUtils::setLaunchAtStartup(bool enable)
<< QStringLiteral("StartupNotify=true") << '\n' << QStringLiteral("StartupNotify=true") << '\n'
<< QStringLiteral("Terminal=false") << '\n' << QStringLiteral("Terminal=false") << '\n'
<< QStringLiteral("Type=Application") << '\n' << QStringLiteral("Type=Application") << '\n'
<< QStringLiteral("Version=1.0") << "true" << '\n' << QStringLiteral("Version=1.0") << '\n'
<< QStringLiteral("Categories=Utility;Security;Qt;") << '\n' << QStringLiteral("Categories=Utility;Security;Qt;") << '\n'
<< QStringLiteral("MimeType=application/x-keepass2;") << '\n' << QStringLiteral("MimeType=application/x-keepass2;") << '\n'
<< QStringLiteral("X-GNOME-Autostart-enabled=true") << endl; << QStringLiteral("X-GNOME-Autostart-enabled=true") << '\n'
<< QStringLiteral("X-GNOME-Autostart-Delay=2") << '\n'
<< QStringLiteral("X-KDE-autostart-after=panel") << endl;
desktopFile.close(); desktopFile.close();
} else if (isLaunchAtStartupEnabled()) { } else if (isLaunchAtStartupEnabled()) {
QFile::remove(getAutostartDesktopFilename()); QFile::remove(getAutostartDesktopFilename());

View File

@ -58,7 +58,8 @@ namespace
// Get average password length // Get average password length
int averagePwdLength() const int averagePwdLength() const
{ {
return m_passwords.empty() ? 0 : pwdTotalLen / m_passwords.size(); const auto nPwds = nPwdsUnique + nPwdsReused;
return nPwds == 0 ? 0 : std::round(pwdTotalLen / double(nPwds));
} }
// Get max number of password reuse (=how many entries // Get max number of password reuse (=how many entries

View File

@ -4766,7 +4766,11 @@ QRect BaseStyle::subElementRect(SubElement sr, const QStyleOption* opt, const QW
} }
case SE_LineEditContents: { case SE_LineEditContents: {
QRect r = QCommonStyle::subElementRect(sr, opt, w); QRect r = QCommonStyle::subElementRect(sr, opt, w);
int pad = Phantom::dpiScaled(Phantom::LineEdit_ContentsHPad); int pad = Phantom::LineEdit_ContentsHPad;
if (w && qobject_cast<const QComboBox*>(w->parentWidget())) {
pad += 3;
}
pad = Phantom::dpiScaled(pad);
return r.adjusted(pad, 0, -pad, 0); return r.adjusted(pad, 0, -pad, 0);
} }
default: default:

View File

@ -13,3 +13,7 @@ DatabaseWidget #SearchBanner, DatabaseWidget #KeeShareBanner {
border: 1px solid rgb(190, 190, 190); border: 1px solid rgb(190, 190, 190);
padding: 2px; padding: 2px;
} }
QLineEdit {
padding-left: 2px;
}

View File

@ -186,7 +186,10 @@ void ShareObserver::handleDatabaseChanged()
void ShareObserver::handleFileUpdated(const QString& path) void ShareObserver::handleFileUpdated(const QString& path)
{ {
if (!m_inFileUpdate) {
QTimer::singleShot(100, this, [this, path] {
const Result result = importShare(path); const Result result = importShare(path);
m_inFileUpdate = false;
if (!result.isValid()) { if (!result.isValid()) {
return; return;
} }
@ -203,6 +206,9 @@ void ShareObserver::handleFileUpdated(const QString& path)
success << tr("Imported from %1").arg(result.path); success << tr("Imported from %1").arg(result.path);
} }
notifyAbout(success, warning, error); notifyAbout(success, warning, error);
});
m_inFileUpdate = true;
}
} }
ShareObserver::Result ShareObserver::importShare(const QString& path) ShareObserver::Result ShareObserver::importShare(const QString& path)

View File

@ -83,6 +83,7 @@ private:
QMap<QPointer<Group>, KeeShareSettings::Reference> m_groupToReference; QMap<QPointer<Group>, KeeShareSettings::Reference> m_groupToReference;
QMap<QString, QPointer<Group>> m_shareToGroup; QMap<QString, QPointer<Group>> m_shareToGroup;
QMap<QString, QSharedPointer<FileWatcher>> m_fileWatchers; QMap<QString, QSharedPointer<FileWatcher>> m_fileWatchers;
bool m_inFileUpdate = false;
}; };
#endif // KEEPASSXC_SHAREOBSERVER_H #endif // KEEPASSXC_SHAREOBSERVER_H

View File

@ -29,14 +29,18 @@
#include <QDialogButtonBox> #include <QDialogButtonBox>
#include <QLabel> #include <QLabel>
#include <QLineEdit> #include <QLineEdit>
#include <QListWidgetItem>
#include <QMimeData> #include <QMimeData>
#include <QPlainTextEdit> #include <QPlainTextEdit>
#include <QPushButton> #include <QPushButton>
#include <QRadioButton>
#include <QSignalSpy> #include <QSignalSpy>
#include <QSpinBox> #include <QSpinBox>
#include <QTest>
#include <QTimer> #include <QTimer>
#include <QToolBar> #include <QToolBar>
#include <QToolButton> #include <QToolButton>
#include <QTreeWidgetItem>
#include "config-keepassx-tests.h" #include "config-keepassx-tests.h"
#include "core/Config.h" #include "core/Config.h"
@ -141,6 +145,9 @@ void TestGui::init()
fileDialog()->setNextFileName(m_dbFilePath); fileDialog()->setNextFileName(m_dbFilePath);
triggerAction("actionDatabaseOpen"); triggerAction("actionDatabaseOpen");
QApplication::processEvents();
m_dbWidget = m_tabWidget->currentDatabaseWidget();
auto* databaseOpenWidget = m_tabWidget->currentDatabaseWidget()->findChild<QWidget*>("databaseOpenWidget"); auto* databaseOpenWidget = m_tabWidget->currentDatabaseWidget()->findChild<QWidget*>("databaseOpenWidget");
QVERIFY(databaseOpenWidget); QVERIFY(databaseOpenWidget);
auto* editPassword = databaseOpenWidget->findChild<QLineEdit*>("editPassword"); auto* editPassword = databaseOpenWidget->findChild<QLineEdit*>("editPassword");
@ -150,8 +157,10 @@ void TestGui::init()
QTest::keyClicks(editPassword, "a"); QTest::keyClicks(editPassword, "a");
QTest::keyClick(editPassword, Qt::Key_Enter); QTest::keyClick(editPassword, Qt::Key_Enter);
m_dbWidget = m_tabWidget->currentDatabaseWidget(); QTRY_VERIFY(!m_dbWidget->isLocked());
m_db = m_dbWidget->database(); m_db = m_dbWidget->database();
QApplication::processEvents();
} }
// Every test ends with closing the temp database without saving // Every test ends with closing the temp database without saving
@ -1159,24 +1168,45 @@ void TestGui::testEntryPlaceholders()
void TestGui::testDragAndDropEntry() void TestGui::testDragAndDropEntry()
{ {
auto* entryView = m_dbWidget->findChild<EntryView*>("entryView"); auto entryView = m_dbWidget->findChild<EntryView*>("entryView");
auto* groupView = m_dbWidget->findChild<GroupView*>("groupView"); auto groupView = m_dbWidget->findChild<GroupView*>("groupView");
QAbstractItemModel* groupModel = groupView->model(); auto groupModel = qobject_cast<GroupModel*>(groupView->model());
QModelIndex sourceIndex = entryView->model()->index(0, 1); QModelIndex sourceIndex = entryView->model()->index(0, 1);
QModelIndex targetIndex = groupModel->index(0, 0, groupModel->index(0, 0)); QModelIndex targetIndex = groupModel->index(0, 0, groupModel->index(0, 0));
QVERIFY(sourceIndex.isValid()); QVERIFY(sourceIndex.isValid());
QVERIFY(targetIndex.isValid()); QVERIFY(targetIndex.isValid());
auto targetGroup = groupModel->groupFromIndex(targetIndex);
QMimeData mimeData; QMimeData mimeData;
QByteArray encoded; QByteArray encoded;
QDataStream stream(&encoded, QIODevice::WriteOnly); QDataStream stream(&encoded, QIODevice::WriteOnly);
Entry* entry = entryView->entryFromIndex(sourceIndex);
auto entry = entryView->entryFromIndex(sourceIndex);
stream << entry->group()->database()->uuid() << entry->uuid(); stream << entry->group()->database()->uuid() << entry->uuid();
mimeData.setData("application/x-keepassx-entry", encoded); mimeData.setData("application/x-keepassx-entry", encoded);
// Test Copy, UUID should change, history remain
QVERIFY(groupModel->dropMimeData(&mimeData, Qt::CopyAction, -1, 0, targetIndex));
// Find the copied entry
auto newEntry = targetGroup->findEntryByPath(entry->title());
QVERIFY(newEntry);
QVERIFY(entry->uuid() != newEntry->uuid());
QCOMPARE(entry->historyItems().count(), newEntry->historyItems().count());
encoded.clear();
entry = entryView->entryFromIndex(sourceIndex);
auto history = entry->historyItems().count();
auto uuid = entry->uuid();
stream << entry->group()->database()->uuid() << entry->uuid();
mimeData.setData("application/x-keepassx-entry", encoded);
// Test Move, entry pointer should remain the same
QCOMPARE(entry->group()->name(), QString("NewDatabase"));
QVERIFY(groupModel->dropMimeData(&mimeData, Qt::MoveAction, -1, 0, targetIndex)); QVERIFY(groupModel->dropMimeData(&mimeData, Qt::MoveAction, -1, 0, targetIndex));
QCOMPARE(entry->group()->name(), QString("General")); QCOMPARE(entry->group()->name(), QString("General"));
QCOMPARE(entry->uuid(), uuid);
QCOMPARE(entry->historyItems().count(), history);
} }
void TestGui::testDragAndDropGroup() void TestGui::testDragAndDropGroup()
@ -1497,6 +1527,163 @@ void TestGui::testTrayRestoreHide()
trayIcon->activated(QSystemTrayIcon::DoubleClick); trayIcon->activated(QSystemTrayIcon::DoubleClick);
QTRY_VERIFY(!m_mainWindow->isVisible()); QTRY_VERIFY(!m_mainWindow->isVisible());
// Ensure window is visible at the end
trayIcon->activated(QSystemTrayIcon::DoubleClick);
QTRY_VERIFY(m_mainWindow->isVisible());
}
void TestGui::testAutoType()
{
// Clear entries from root group to guarantee order
for (Entry* entry : m_db->rootGroup()->entries()) {
m_db->rootGroup()->removeEntry(entry);
}
Tools::wait(150);
// 1. Create an entry with Auto-Type disabled
// 1.a) Click the new entry button and set the title
auto* entryNewAction = m_mainWindow->findChild<QAction*>("actionEntryNew");
QVERIFY(entryNewAction->isEnabled());
auto* toolBar = m_mainWindow->findChild<QToolBar*>("toolBar");
QVERIFY(toolBar);
QWidget* entryNewWidget = toolBar->widgetForAction(entryNewAction);
QVERIFY(entryNewWidget->isVisible());
QVERIFY(entryNewWidget->isEnabled());
QTest::mouseClick(entryNewWidget, Qt::LeftButton);
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::EditMode);
auto* editEntryWidget = m_dbWidget->findChild<EditEntryWidget*>("editEntryWidget");
QVERIFY(editEntryWidget);
auto* titleEdit = editEntryWidget->findChild<QLineEdit*>("titleEdit");
QVERIFY(titleEdit);
QTest::keyClicks(titleEdit, "1. Entry With Disabled Auto-Type");
auto* usernameComboBox = editEntryWidget->findChild<QComboBox*>("usernameComboBox");
QVERIFY(usernameComboBox);
QTest::mouseClick(usernameComboBox, Qt::LeftButton);
QTest::keyClicks(usernameComboBox, "AutocompletionUsername");
// 1.b) Uncheck Auto-Type checkbox
editEntryWidget->setCurrentPage(3);
auto* enableAutoTypeButton = editEntryWidget->findChild<QCheckBox*>("enableButton");
QVERIFY(enableAutoTypeButton);
QVERIFY(enableAutoTypeButton->isVisible());
QVERIFY(enableAutoTypeButton->isEnabled());
enableAutoTypeButton->click();
QVERIFY(!enableAutoTypeButton->isChecked());
// 1.c) Save changes
editEntryWidget->setCurrentPage(0);
auto* editEntryWidgetButtonBox = editEntryWidget->findChild<QDialogButtonBox*>("buttonBox");
QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton);
// 2. Create an entry with default/inherited Auto-Type sequence
// 2.a) Click the new entry button and set the title
QTest::mouseClick(entryNewWidget, Qt::LeftButton);
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::EditMode);
QTest::keyClicks(titleEdit, "2. Entry With Default Auto-Type Sequence");
QTest::mouseClick(usernameComboBox, Qt::LeftButton);
QTest::keyClicks(usernameComboBox, "AutocompletionUsername");
// 2.b) Confirm AutoType is enabled and default
editEntryWidget->setCurrentPage(3);
QVERIFY(enableAutoTypeButton->isChecked());
auto* inheritSequenceButton = editEntryWidget->findChild<QRadioButton*>("inheritSequenceButton");
QVERIFY(inheritSequenceButton->isChecked());
// 2.c) Save changes
editEntryWidget->setCurrentPage(0);
QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton);
// 3. Create an entry with custom Auto-Type sequence
// 3.a) Click the new entry button and set the title
QTest::mouseClick(entryNewWidget, Qt::LeftButton);
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::EditMode);
QTest::keyClicks(titleEdit, "3. Entry With Custom Auto-Type Sequence");
QTest::mouseClick(usernameComboBox, Qt::LeftButton);
QTest::keyClicks(usernameComboBox, "AutocompletionUsername");
// 3.b) Confirm AutoType is enabled and set custom sequence
editEntryWidget->setCurrentPage(3);
QVERIFY(enableAutoTypeButton->isChecked());
auto* customSequenceButton = editEntryWidget->findChild<QRadioButton*>("customSequenceButton");
QTest::mouseClick(customSequenceButton, Qt::LeftButton);
QVERIFY(customSequenceButton->isChecked());
QVERIFY(!inheritSequenceButton->isChecked());
auto* sequenceEdit = editEntryWidget->findChild<QLineEdit*>("sequenceEdit");
QVERIFY(sequenceEdit);
sequenceEdit->setFocus();
QTRY_VERIFY(sequenceEdit->hasFocus());
QTest::keyClicks(sequenceEdit, "{USERNAME}{TAB}{TAB}{PASSWORD}{ENTER}");
// 3.c) Save changes
editEntryWidget->setCurrentPage(0);
QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton);
QApplication::processEvents();
// Check total number of entries matches expected
auto* entryView = m_dbWidget->findChild<EntryView*>("entryView");
QVERIFY(entryView);
QTRY_COMPARE(entryView->model()->rowCount(), 3);
// Sort entries by title
entryView->sortByColumn(1, Qt::AscendingOrder);
// Select first entry
entryView->selectionModel()->clearSelection();
QModelIndex entryIndex = entryView->model()->index(0, 0);
entryView->selectionModel()->select(entryIndex, QItemSelectionModel::Rows | QItemSelectionModel::Select);
auto* entryPreviewWidget = m_dbWidget->findChild<EntryPreviewWidget*>("previewWidget");
QVERIFY(entryPreviewWidget->isVisible());
// Check that the Autotype tab in entry preview pane is disabled for entry with disabled Auto-Type
auto* entryAutotypeTab = entryPreviewWidget->findChild<QWidget*>("entryAutotypeTab");
QVERIFY(!entryAutotypeTab->isEnabled());
// Check that Auto-Type is disabled in the actual entry model as well
Entry* entry = entryView->entryFromIndex(entryIndex);
QVERIFY(!entry->autoTypeEnabled());
// Select second entry
entryView->selectionModel()->clearSelection();
entryIndex = entryView->model()->index(1, 0);
entryView->selectionModel()->select(entryIndex, QItemSelectionModel::Rows | QItemSelectionModel::Select);
QVERIFY(entryPreviewWidget->isVisible());
// Check that the Autotype tab in entry preview pane is enabled for entry with default Auto-Type sequence;
QVERIFY(entryAutotypeTab->isEnabled());
// Check that Auto-Type is enabled in the actual entry model as well
entry = entryView->entryFromIndex(entryIndex);
QVERIFY(entry->autoTypeEnabled());
// Select third entry
entryView->selectionModel()->clearSelection();
entryIndex = entryView->model()->index(2, 0);
entryView->selectionModel()->select(entryIndex, QItemSelectionModel::Rows | QItemSelectionModel::Select);
QVERIFY(entryPreviewWidget->isVisible());
// Check that the Autotype tab in entry preview pane is enabled for entry with custom Auto-Type sequence
QVERIFY(entryAutotypeTab->isEnabled());
// Check that Auto-Type is enabled in the actual entry model as well
entry = entryView->entryFromIndex(entryIndex);
QVERIFY(entry->autoTypeEnabled());
// De-select third entry
entryView->selectionModel()->clearSelection();
} }
int TestGui::addCannedEntries() int TestGui::addCannedEntries()

View File

@ -68,6 +68,7 @@ private slots:
void testDatabaseLocking(); void testDatabaseLocking();
void testDragAndDropKdbxFiles(); void testDragAndDropKdbxFiles();
void testSortGroups(); void testSortGroups();
void testAutoType();
void testTrayRestoreHide(); void testTrayRestoreHide();
private: private: