Compare commits

...

123 Commits
4.1.7 ... 4.1.9

Author SHA1 Message Date
J-Jamet
1b98bd740c Merge branch 'release/4.1.9' 2025-10-06 17:27:26 +02:00
J-Jamet
5adeb5cde0 fix: Tags 2025-10-06 17:20:59 +02:00
J-Jamet
b949d5d861 Merge branch 'develop' of https://hosted.weblate.org/projects/keepass-dx/strings into translations 2025-10-06 17:18:20 +02:00
J-Jamet
b4264a30a4 fix: Update description 2025-10-06 17:16:57 +02:00
J-Jamet
cf799c0f68 fix: Update to 4.1.9 2025-10-06 17:14:10 +02:00
J-Jamet
97f0ca519b fix: Killed service #2201 2025-10-06 16:59:42 +02:00
J-Jamet
cf4047b701 Merge branch 'chenxiaolong-landscape-insets' into develop 2025-10-06 13:58:39 +02:00
J-Jamet
40608a3eb5 Merge branch 'landscape-insets' of github.com:chenxiaolong/KeePassDX into chenxiaolong-landscape-insets 2025-10-06 13:58:20 +02:00
J-Jamet
99cb50d031 fix: Bug report title 2025-10-06 12:47:30 +02:00
Oğuz Ersen
b0d0c35241 Translated using Weblate (Turkish)
Currently translated at 100.0% (3 of 3 strings)

Translation: KeePassDX/Metadata
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/metadata/tr/
2025-10-05 18:02:07 +00:00
Mekyla Credo
6044c93a4a Translated using Weblate (Filipino)
Currently translated at 46.5% (309 of 664 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fil/
2025-10-05 18:02:05 +00:00
Oğuz Ersen
b544b5d54d Translated using Weblate (Turkish)
Currently translated at 100.0% (664 of 664 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2025-10-05 18:02:02 +00:00
Andrew Gunnerson
852378e484 Simplify inset logic, fix landscape mode, fix cutout overlapping
The commit primarily fixes a few overlapping issues caused by the window
inset handling. Previously, there were two main issues:

* Because setTransparentNavigationBar() checked for portrait mode, the
  inset logic never executed in landscape mode. This caused the app to
  overlap the status bar and navigation bar.

* The inset logic did not have handling for displayCutout insets. In
  landscape mode, this would cause the app to overlap the notch or
  camera hole punch area on phones.

In addition to fixing those issues, this commit simplifies the inset
logic a bit:

* applyWindowInsets() now accepts an EnumSet of WindowInsetPosition to
  avoid needing to duplicate logic for the various position
  combinations.

* Insets are now applied to the main container in the layout instead of
  individual elements where possible. This eliminates the need for the
  previous manual IME height handling logic in BOTTOM_IME vs
  TOP_BOTTOM_IME (for avoiding the insets being applied twice).

* Since insets are now applied to the main layout container,
  applyWindowInsets() now takes systemBars, displayCutout, and ime all
  into consideration. This should avoid all possible overlapping.

* Add support for using padding instead of margins for insets. This is
  used for GroupActivity's navigation drawer, where Material design
  intends for the drawer background to be drawn behind system bars.

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
2025-10-04 17:24:24 -04:00
Alonso González Chaves
711a344860 Translated using Weblate (Spanish)
Currently translated at 100.0% (3 of 3 strings)

Translation: KeePassDX/Metadata
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/metadata/es/
2025-10-04 14:02:05 +02:00
Alonso González Chaves
72087c7e5c Translated using Weblate (Spanish)
Currently translated at 100.0% (664 of 664 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/es/
2025-10-04 14:02:01 +02:00
J-Jamet
f17d211fbd fix: Change appearance summary #2171 2025-09-24 13:19:57 +02:00
Xo
ae903ad236 Translated using Weblate (Hebrew)
Currently translated at 100.0% (664 of 664 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/he/
2025-09-15 09:02:00 +00:00
Milo Ivir
7c3a15ce79 Translated using Weblate (Croatian)
Currently translated at 100.0% (664 of 664 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hr/
2025-09-12 16:01:59 +00:00
J-Jamet
2230fe66ab Merge tag '4.1.8' into develop
4.1.8
2025-09-12 16:04:08 +02:00
J-Jamet
84a62a32ff Merge branch 'release/4.1.8' 2025-09-12 16:03:59 +02:00
J-Jamet
da8ef9340c fix: Loading ViewModel 2025-09-12 15:23:32 +02:00
J-Jamet
af068349e4 fix: Upgrade to 4.1.8 2025-09-12 14:14:06 +02:00
J-Jamet
56cb5953dd fix: Deletable recycle bin #2163 2025-09-12 13:00:56 +02:00
J-Jamet
2fc2a9c7c1 fix: Delete algo during merge #1516 2025-09-11 21:19:40 +02:00
J-Jamet
69e7cdbc47 fix: Search with space #175 2025-09-11 16:43:40 +02:00
J-Jamet
39d9a74a73 fix: Warnings 2025-09-11 16:36:35 +02:00
shinebrillant
b609d4e182 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (3 of 3 strings)

Translation: KeePassDX/Metadata
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/metadata/zh_Hant/
2025-09-11 13:02:01 +00:00
J-Jamet
7212c73481 fix: Warnings 2025-09-11 14:55:37 +02:00
J-Jamet
3ee4caa153 fix: Warnings 2025-09-11 14:53:41 +02:00
J-Jamet
28e4d929bb fix: Warnings 2025-09-11 14:51:35 +02:00
Artyom Rybakov
e8ecf28f7c Translated using Weblate (Russian)
Currently translated at 100.0% (3 of 3 strings)

Translation: KeePassDX/Metadata
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/metadata/ru/
2025-09-10 14:21:47 +02:00
shinebrillant
3d5adbfc01 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (664 of 664 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hant/
2025-09-10 14:21:46 +02:00
Matthaiks
72bfc50703 Translated using Weblate (Polish)
Currently translated at 100.0% (664 of 664 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2025-09-10 14:21:46 +02:00
Matthaiks
a60e2e780d Translated using Weblate (Polish)
Currently translated at 100.0% (664 of 664 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2025-09-09 12:01:58 +00:00
Retrial
9210851765 Translated using Weblate (Greek)
Currently translated at 100.0% (664 of 664 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/el/
2025-09-09 12:01:56 +00:00
J-Jamet
a46251be7b fix: Better biometric exception implementation 2025-09-09 13:37:50 +02:00
J-Jamet
e8ec27dc38 fix: Upgrade to API 35 2025-09-09 11:45:30 +02:00
J-Jamet
30dd7c567c fix: Autofill compatibility package 2025-09-08 15:17:09 +02:00
J-Jamet
b196145578 Merge branch 'milotype-croatian-translation-20250907' into translations
# Conflicts:
#	fastlane/metadata/android/hr/full_description.txt
#	fastlane/metadata/android/hr/short_description.txt
#	fastlane/metadata/android/hr/title.txt
2025-09-08 12:45:09 +02:00
J-Jamet
ac347db2d1 fix: Translations 2025-09-08 12:43:06 +02:00
J-Jamet
013c437cf7 Merge branch 'develop' of https://hosted.weblate.org/projects/keepass-dx/strings into translations 2025-09-08 12:38:51 +02:00
Milo Ivir
1f600d60e3 Translated using Weblate (Croatian)
Currently translated at 100.0% (3 of 3 strings)

Translation: KeePassDX/Metadata
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/metadata/hr/
2025-09-08 12:33:27 +02:00
Milo Ivir
d5ecaeb331 Add Croatian translation 2025-09-07 16:29:42 +02:00
Milo Ivir
db8b0100de Translated using Weblate (Croatian)
Currently translated at 100.0% (666 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hr/
2025-09-07 15:51:05 +02:00
Ihor Hordiichuk
5f41177a1f Translated using Weblate (Ukrainian)
Currently translated at 100.0% (666 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2025-09-06 12:01:59 +00:00
Artyom Rybakov
0db2b7023e Translated using Weblate (Russian)
Currently translated at 100.0% (3 of 3 strings)

Translation: KeePassDX/Metadata
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/metadata/ru/
2025-09-02 14:02:02 +00:00
Artyom Rybakov
a2c2a21dde Translated using Weblate (Russian)
Currently translated at 100.0% (666 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2025-09-02 14:02:00 +00:00
scollovati
d7a3e7fedd Translated using Weblate (Italian)
Currently translated at 100.0% (666 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2025-09-02 14:01:58 +00:00
J-Jamet
5e4ee167fc Merge branch 'rmacklin-remember-last-read-only-state-of-each-database' into develop 2025-09-01 19:02:59 +02:00
J-Jamet
c911b7c511 fix: Import DatabaseFile 2025-09-01 19:01:35 +02:00
J-Jamet
c79d1f1b81 Merge branch 'Dev-ClayP-master' into develop 2025-09-01 18:19:11 +02:00
J-Jamet
daf717becd fix: Remove JELLY_BEAN_MR1 conditions and unused PRNGFixes 2025-09-01 18:15:00 +02:00
J-Jamet
48d4483484 Merge branch 'master' of github.com:Dev-ClayP/KeePassDX into Dev-ClayP-master 2025-09-01 17:34:46 +02:00
leap123
c6b0ee27df Translated using Weblate (Indonesian)
Currently translated at 100.0% (3 of 3 strings)

Translation: KeePassDX/Metadata
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/metadata/id/
2025-08-31 17:01:54 +00:00
Priit Jõerüüt
0053726d0b Translated using Weblate (Estonian)
Currently translated at 100.0% (666 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/et/
2025-08-30 18:16:53 +02:00
leap123
1395af88d1 Translated using Weblate (Indonesian)
Currently translated at 100.0% (666 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/id/
2025-08-30 18:16:52 +02:00
Fjuro
2e3ade1b4a Translated using Weblate (Czech)
Currently translated at 100.0% (666 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2025-08-30 18:16:52 +02:00
XiveZ
90c43acfbf Translated using Weblate (Belarusian)
Currently translated at 100.0% (666 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/be/
2025-08-30 07:03:02 +02:00
Ghost of Sparta
90b68fd972 Translated using Weblate (Hungarian)
Currently translated at 100.0% (666 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hu/
2025-08-30 07:03:02 +02:00
XiveZ
ef6aeceb20 Translated using Weblate (Belarusian)
Currently translated at 5.2% (35 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/be/
2025-08-29 07:25:41 +02:00
jonnysemon
ef8685f0e7 Translated using Weblate (Arabic)
Currently translated at 100.0% (666 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ar/
2025-08-29 07:25:41 +02:00
XiveZ
3021ed158b Added translation using Weblate (Belarusian) 2025-08-29 07:02:51 +02:00
weblator
a57043f496 Translated using Weblate (Azerbaijani)
Currently translated at 96.8% (645 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/az/
2025-08-29 07:02:51 +02:00
weblator
fdfd124fee Translated using Weblate (Serbian)
Currently translated at 50.3% (335 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/sr/
2025-08-29 07:02:50 +02:00
weblator
71739de91a Translated using Weblate (Cantonese (Traditional Han script))
Currently translated at 19.9% (133 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/yue_Hant/
2025-08-29 07:02:50 +02:00
weblator
041b1fbf53 Translated using Weblate (Burmese)
Currently translated at 6.4% (43 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/my/
2025-08-29 07:02:50 +02:00
weblator
3a72b32b4a Translated using Weblate (Slovenian)
Currently translated at 9.7% (65 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/sl/
2025-08-29 07:02:50 +02:00
weblator
994f174300 Translated using Weblate (Marathi)
Currently translated at 1.2% (8 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/mr/
2025-08-29 07:02:49 +02:00
weblator
c0f32254bb Translated using Weblate (Esperanto)
Currently translated at 21.1% (141 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/eo/
2025-08-29 07:02:49 +02:00
109247019824
fd98dbeebe Translated using Weblate (Bulgarian)
Currently translated at 100.0% (666 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/bg/
2025-08-29 07:02:49 +02:00
weblator
69ac6e6698 Translated using Weblate (Serbian (Latin script))
Currently translated at 59.0% (393 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/sr_Latn/
2025-08-29 07:02:48 +02:00
weblator
35e224d227 Translated using Weblate (Portuguese)
Currently translated at 99.6% (664 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pt/
2025-08-29 07:02:47 +02:00
weblator
2da8552a53 Translated using Weblate (Javanese)
Currently translated at 3.6% (24 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/jv/
2025-08-29 07:02:47 +02:00
weblator
a9a5047949 Translated using Weblate (Persian)
Currently translated at 43.8% (292 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fa/
2025-08-29 07:02:47 +02:00
weblator
17c98f7fea Translated using Weblate (Indonesian)
Currently translated at 99.6% (664 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/id/
2025-08-29 07:02:47 +02:00
weblator
c3bc890665 Translated using Weblate (Malayalam)
Currently translated at 56.4% (376 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ml/
2025-08-29 07:02:47 +02:00
weblator
7a295c2541 Translated using Weblate (Punjabi)
Currently translated at 48.4% (323 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pa/
2025-08-29 07:02:46 +02:00
weblator
01b1b74c6a Translated using Weblate (Bengali (Bangladesh))
Currently translated at 13.3% (89 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/bn_BD/
2025-08-29 07:02:46 +02:00
weblator
fd25d21c72 Translated using Weblate (Hindi)
Currently translated at 21.9% (146 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hi/
2025-08-29 07:02:46 +02:00
Telaneo
6b1d8d24dd Translated using Weblate (Norwegian Bokmål)
Currently translated at 100.0% (666 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nb_NO/
2025-08-29 07:02:46 +02:00
大王叫我来巡山
5d002f5128 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (666 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2025-08-29 07:02:45 +02:00
weblator
98314c466f Translated using Weblate (Portuguese (Brazil))
Currently translated at 99.6% (664 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pt_BR/
2025-08-29 07:02:44 +02:00
Matthaiks
4f7afd7c97 Translated using Weblate (Polish)
Currently translated at 100.0% (666 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2025-08-29 07:02:44 +02:00
weblator
a9e139ff7e Translated using Weblate (Norwegian Nynorsk)
Currently translated at 42.6% (284 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nn/
2025-08-29 07:02:44 +02:00
Stephan Paternotte
4ff483a8d2 Translated using Weblate (Dutch)
Currently translated at 100.0% (666 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nl/
2025-08-29 07:02:44 +02:00
weblator
1916b79df1 Translated using Weblate (Lithuanian)
Currently translated at 60.2% (401 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/lt/
2025-08-29 07:02:44 +02:00
Liner Seven
98e15a7717 Translated using Weblate (Japanese)
Currently translated at 100.0% (666 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2025-08-29 07:02:43 +02:00
Masowick
dfd18e3c7f Translated using Weblate (German)
Currently translated at 100.0% (666 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2025-08-29 07:02:42 +02:00
weblator
8fbbaae05b Translated using Weblate (English)
Currently translated at 99.8% (665 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/en/
2025-08-29 07:02:41 +02:00
Richard Macklin
8a60056866 Remove no-longer-needed enable_read_only_* string resources
(We just removed the usages of these strings)
2025-08-26 20:10:46 -07:00
Richard Macklin
e9d20a51a5 Remove global "Write-protected" setting
This addresses J-Jamet's feedback that keeping the global setting would
potentially lead to confusion, so it should be removed now that we are
remembering each database's read-only state.
2025-08-26 20:10:42 -07:00
Richard Macklin
a28d77ba32 feat: Remember the last read-only state of each database
The app has supported a global setting for opening (all) databases in
read-only mode. But that's not particularly flexible for the use case
where you have one database that should be read-only and one that should
be read-write.

Previously, to handle this use case you could open one database in
read-only mode, but the next time you attempted to open the same
database, it would "forget" that, so you would have to toggle it to
read-only mode again manually. This commit changes that behavior so that
if you toggle a database to read-only mode, it'll be remembered the next
time you open the database. (You can still toggle it back to read-write
if you change your mind, and that, too, will be remembered the next time
you open the database.)
2025-08-26 20:08:22 -07:00
Telaneo
d143605a40 Translated using Weblate (Norwegian Bokmål)
Currently translated at 100.0% (666 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nb_NO/
2025-08-25 17:28:06 +02:00
J-Jamet
15972efb4f Merge branch 'develop' 2025-08-23 00:40:23 +02:00
Liner Seven
2befa68c93 Translated using Weblate (Japanese)
Currently translated at 100.0% (666 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2025-08-22 11:02:30 +02:00
Random
4034a2bfc4 Translated using Weblate (Italian)
Currently translated at 100.0% (3 of 3 strings)

Translation: KeePassDX/Metadata
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/metadata/it/
2025-08-20 13:02:22 +00:00
Nara Huang
0d93e867cf Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (666 of 666 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hant/
2025-08-20 13:02:18 +00:00
Hosted Weblate
8cac4eb51c Merge branch 'origin/develop' into Weblate. 2025-08-19 10:32:22 +02:00
Alex Ionescu
933d34ff1d Translated using Weblate (Romanian)
Currently translated at 100.0% (667 of 667 strings)

Translation: KeePassDX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ro/
2025-08-19 10:32:21 +02:00
J-Jamet
d34f460b98 fix: Remove title in template issue 2025-08-19 10:12:11 +02:00
J-Jamet
7632face63 fix: Update issue template 2025-08-19 10:09:48 +02:00
Dev-ClayP
1f678fc975 Update Loupe.kt
removed old sdk checks
2025-07-09 11:24:30 -04:00
Dev-ClayP
082c839639 Update EntryEditActivity.kt
removed old sdk checks
2025-07-09 11:18:59 -04:00
Dev-ClayP
600d548fce Update BroadcastAction.kt
removed old SDK check
2025-07-09 11:15:46 -04:00
Dev-ClayP
3035f9b686 Update TimeoutHelper.kt
Removed old SDK check
2025-07-09 11:14:18 -04:00
Dev-ClayP
6eae0f02d3 Update FileDatabaseSelectActivity.kt
removed PackageManager.allowCreateDocumentByStorageAccessFramework()
2025-07-09 11:11:53 -04:00
Dev-ClayP
87be2f4b9e Update UriHelper.kt
removed PackageManager.allowCreateDocumentByStorageAccessFramework()  it will always eval to true with sdk update
2025-07-09 11:09:44 -04:00
Dev-ClayP
3b054504a1 Update UriUtil.kt
removed another kitkat check
2025-07-09 11:05:01 -04:00
Dev-ClayP
a88f6b968a Update UriUtil.kt
Removed KitKat sdk check
2025-07-09 11:04:12 -04:00
Dev-ClayP
1fc4f150bf Update item_breadcrumb.xml
Removed jelly_bean target check
2025-07-09 10:45:16 -04:00
Dev-ClayP
1f4e59cbdc Update fragment_set_otp.xml
Removed sdk target checks for jelly_bean
2025-07-09 10:44:21 -04:00
Dev-ClayP
b5dc8d9adf Update build.gradle
changed minsdk to 19
2025-07-09 10:40:38 -04:00
Dev-ClayP
43f7e08548 Update build.gradle
changed minsdk to 19
2025-07-09 10:40:13 -04:00
Dev-ClayP
05fc6f87ec Update build.gradle
changed minsdk to 19
2025-07-09 10:39:34 -04:00
Dev-ClayP
daae535fa1 Update TemplateView.kt
Removed old SDK checks
2025-07-09 10:28:27 -04:00
Dev-ClayP
90c8cb3455 Update ViewUtil.kt
Removed SDK check
2025-07-09 10:26:12 -04:00
Dev-ClayP
daeee10de9 Update TemplateEditView.kt
Removed old SDK check
2025-07-09 10:25:15 -04:00
Dev-ClayP
6c1c401a71 Update NodesAdapter.kt
Removed old SDK check
2025-07-09 10:23:44 -04:00
Dev-ClayP
fd7f0fceb2 Update UriUtil.kt
Removed Old SDK Check
2025-07-09 10:21:55 -04:00
Dev-ClayP
26b8a616be Update AboutActivity.kt
Removed old SDK Check
2025-07-09 10:19:54 -04:00
Dev-ClayP
d88882f439 Removed PRNGFixes App.kt 2025-07-09 10:15:36 -04:00
Dev-ClayP
09dc1d6baa Removed sdk checks on TextFieldView.kt
Removed SDK checks that will always resolve to true now. Since we are updating min sdk to 19, these checks are no longer necessary.
2025-07-09 09:57:23 -04:00
Clay Perry
f4f5e86979 Updated Minimum SDK to 16 2025-07-08 12:52:14 -04:00
141 changed files with 1813 additions and 1390 deletions

View File

@@ -1,7 +1,6 @@
name: Bug Report
name: Bug report
description: Report a bug.
title: ""
labels: bug
labels: ["bug"]
body:
- type: markdown
attributes:

1
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1 @@
blank_issues_enabled: false

View File

@@ -1,7 +1,6 @@
name: Feature request
description: Suggest an idea.
title: ""
labels: feature
labels: ["feature"]
body:
- type: markdown
attributes:

View File

@@ -1,3 +1,16 @@
KeePassDX(4.1.9)
* Fix landscape UI #2198 #2200 (@chenxiaolong)
* Fix start loop and flash screen #2201
* Small fixes
KeePassDX(4.1.8)
* Updated to API 35 minimum SDK 19 #2073 #2138 #2067 #2133 #1687 (Thx @Dev-ClayP)
* Remember last read-only state #2099 #2100 (Thx @rmacklin)
* Fix merge deletion #1516
* Fix space in search #175
* Fix deletable recycle bin #2163
* Small fixes
KeePassDX(4.1.7)
* Fix CipherDatabase for biometric states #2119

View File

@@ -5,14 +5,14 @@ apply plugin: 'kotlin-kapt'
android {
namespace 'com.kunzisoft.keepass'
compileSdkVersion 34
compileSdkVersion 36
defaultConfig {
applicationId "com.kunzisoft.keepass"
minSdkVersion 15
targetSdkVersion 34
versionCode = 139
versionName = "4.1.7"
minSdkVersion 19
targetSdkVersion 35
versionCode = 143
versionName = "4.1.9"
multiDexEnabled true
testApplicationId = "com.kunzisoft.keepass.tests"

View File

@@ -0,0 +1,96 @@
{
"formatVersion": 1,
"database": {
"version": 3,
"identityHash": "a20aec7cf09664b1102ec659fa51160a",
"entities": [
{
"tableName": "file_database_history",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`database_uri` TEXT NOT NULL, `database_alias` TEXT NOT NULL, `keyfile_uri` TEXT, `hardware_key` TEXT, `read_only` INTEGER, `updated` INTEGER NOT NULL, PRIMARY KEY(`database_uri`))",
"fields": [
{
"fieldPath": "databaseUri",
"columnName": "database_uri",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "databaseAlias",
"columnName": "database_alias",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "keyFileUri",
"columnName": "keyfile_uri",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "hardwareKey",
"columnName": "hardware_key",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "readOnly",
"columnName": "read_only",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "updated",
"columnName": "updated",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"database_uri"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "cipher_database",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`database_uri` TEXT NOT NULL, `encrypted_value` TEXT NOT NULL, `specs_parameters` TEXT NOT NULL, PRIMARY KEY(`database_uri`))",
"fields": [
{
"fieldPath": "databaseUri",
"columnName": "database_uri",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "encryptedValue",
"columnName": "encrypted_value",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "specParameters",
"columnName": "specs_parameters",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"database_uri"
]
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'a20aec7cf09664b1102ec659fa51160a')"
]
}
}

View File

@@ -359,8 +359,6 @@ class Loupe(imageView: ImageView, container: ViewGroup) : View.OnTouchListener,
isViewTranslateAnimationRunning = true
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
imageView.run {
val translationY = if (velY > 0) {
originalViewBounds.top + height - top
@@ -396,41 +394,6 @@ class Loupe(imageView: ImageView, container: ViewGroup) : View.OnTouchListener,
}
})
}
} else {
ObjectAnimator.ofFloat(imageView, View.TRANSLATION_Y, if (velY > 0) {
originalViewBounds.top + imageView.height - imageView.top
} else {
originalViewBounds.top - imageView.height - imageView.top
}.toFloat()).apply {
duration = dismissAnimationDuration
interpolator = dismissAnimationInterpolator
addUpdateListener {
val amount = calcTranslationAmount()
changeBackgroundAlpha(amount)
onViewTranslateListener?.onViewTranslate(imageView, amount)
}
addListener(object : Animator.AnimatorListener {
override fun onAnimationStart(p0: Animator) {
// no op
}
override fun onAnimationEnd(p0: Animator) {
isViewTranslateAnimationRunning = false
onViewTranslateListener?.onDismiss(imageView)
cleanup()
}
override fun onAnimationCancel(p0: Animator) {
isViewTranslateAnimationRunning = false
}
override fun onAnimationRepeat(p0: Animator) {
// no op
}
})
start()
}
}
}
private fun processFlingBitmap(velocityX: Float, velocityY: Float) {
@@ -657,8 +620,6 @@ class Loupe(imageView: ImageView, container: ViewGroup) : View.OnTouchListener,
private fun restoreViewTransform() {
val imageView = imageViewRef.get() ?: return
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
imageView.run {
animate()
.setDuration(restoreAnimationDuration)
@@ -687,41 +648,12 @@ class Loupe(imageView: ImageView, container: ViewGroup) : View.OnTouchListener,
}
})
}
} else {
ObjectAnimator.ofFloat(imageView, View.TRANSLATION_Y, (originalViewBounds.top - imageView.top).toFloat()).apply {
duration = restoreAnimationDuration
interpolator = restoreAnimationInterpolator
addUpdateListener {
val amount = calcTranslationAmount()
changeBackgroundAlpha(amount)
onViewTranslateListener?.onViewTranslate(imageView, amount)
}
addListener(object : Animator.AnimatorListener {
override fun onAnimationStart(p0: Animator) {
// no op
}
override fun onAnimationEnd(p0: Animator) {
onViewTranslateListener?.onRestore(imageView)
}
override fun onAnimationCancel(p0: Animator) {
// no op
}
override fun onAnimationRepeat(p0: Animator) {
// no op
}
})
start()
}
}
}
private fun startDragToDismissAnimation() {
val imageView = imageViewRef.get() ?: return
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
imageView.run {
val translationY = if (y - initialY > 0) {
originalViewBounds.top + height - top
@@ -757,37 +689,7 @@ class Loupe(imageView: ImageView, container: ViewGroup) : View.OnTouchListener,
}
})
}
} else {
ObjectAnimator.ofFloat(imageView, View.TRANSLATION_Y, imageView.translationY).apply {
duration = dismissAnimationDuration
interpolator = AccelerateDecelerateInterpolator()
addUpdateListener {
val amount = calcTranslationAmount()
changeBackgroundAlpha(amount)
onViewTranslateListener?.onViewTranslate(imageView, amount)
}
addListener(object : Animator.AnimatorListener {
override fun onAnimationStart(p0: Animator) {
isViewTranslateAnimationRunning = true
}
override fun onAnimationEnd(p0: Animator) {
isViewTranslateAnimationRunning = false
onViewTranslateListener?.onDismiss(imageView)
cleanup()
}
override fun onAnimationCancel(p0: Animator) {
isViewTranslateAnimationRunning = false
}
override fun onAnimationRepeat(p0: Animator) {
// no op
}
})
start()
}
}
}
private fun processFlingToDismiss(velocityY: Float) {

View File

@@ -58,7 +58,7 @@ class AboutActivity : StylishActivity() {
var version: String
var build: String
try {
version = packageManager.getPackageInfoCompat(packageName).versionName
version = packageManager.getPackageInfoCompat(packageName).versionName ?: ""
build = BuildConfig.BUILD_VERSION
} catch (e: NameNotFoundException) {
Log.w(javaClass.simpleName, "Unable to get the app or the build version", e)
@@ -78,9 +78,8 @@ class AboutActivity : StylishActivity() {
movementMethod = LinkMovementMethod.getInstance()
text = HtmlCompat.fromHtml(getString(R.string.html_about_licence, DateTime().year),
HtmlCompat.FROM_HTML_MODE_LEGACY)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
textDirection = View.TEXT_DIRECTION_ANY_RTL
}
}
findViewById<TextView>(R.id.activity_about_privacy_text).apply {

View File

@@ -23,7 +23,6 @@ import android.content.Intent
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.Looper
@@ -38,13 +37,10 @@ import androidx.activity.result.ActivityResultLauncher
import androidx.activity.viewModels
import androidx.appcompat.widget.Toolbar
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.content.ContextCompat
import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.BlendModeColorFilterCompat
import androidx.core.graphics.BlendModeCompat
import androidx.core.graphics.ColorUtils
import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.appbar.AppBarLayout
@@ -83,11 +79,13 @@ import com.kunzisoft.keepass.view.hideByFading
import com.kunzisoft.keepass.view.setTransparentNavigationBar
import com.kunzisoft.keepass.view.showActionErrorIfNeeded
import com.kunzisoft.keepass.viewmodels.EntryViewModel
import java.util.EnumSet
import java.util.UUID
class EntryActivity : DatabaseLockActivity() {
private var footer: ViewGroup? = null
private var container: View? = null
private var coordinatorLayout: CoordinatorLayout? = null
private var collapsingToolbarLayout: CollapsingToolbarLayout? = null
private var appBarLayout: AppBarLayout? = null
@@ -139,6 +137,7 @@ class EntryActivity : DatabaseLockActivity() {
// Get views
footer = findViewById(R.id.activity_entry_footer)
container = findViewById(R.id.activity_entry_container)
coordinatorLayout = findViewById(R.id.toolbar_coordinator)
collapsingToolbarLayout = findViewById(R.id.toolbar_layout)
appBarLayout = findViewById(R.id.app_bar)
@@ -154,8 +153,12 @@ class EntryActivity : DatabaseLockActivity() {
setTransparentNavigationBar {
// To fix margin with API 27
ViewCompat.setOnApplyWindowInsetsListener(collapsingToolbarLayout!!, null)
coordinatorLayout?.applyWindowInsets(WindowInsetPosition.TOP)
footer?.applyWindowInsets(WindowInsetPosition.BOTTOM)
container?.applyWindowInsets(EnumSet.of(
WindowInsetPosition.TOP_MARGINS,
WindowInsetPosition.BOTTOM_MARGINS,
WindowInsetPosition.START_MARGINS,
WindowInsetPosition.END_MARGINS,
))
}
// Empty title

View File

@@ -100,6 +100,7 @@ import com.kunzisoft.keepass.view.showActionErrorIfNeeded
import com.kunzisoft.keepass.view.updateLockPaddingStart
import com.kunzisoft.keepass.viewmodels.ColorPickerViewModel
import com.kunzisoft.keepass.viewmodels.EntryEditViewModel
import java.util.EnumSet
import java.util.UUID
class EntryEditActivity : DatabaseLockActivity(),
@@ -180,8 +181,12 @@ class EntryEditActivity : DatabaseLockActivity(),
// To apply fit window with transparency
setTransparentNavigationBar(applyToStatusBar = true) {
container?.applyWindowInsets(WindowInsetPosition.TOP_BOTTOM_IME)
footer?.applyWindowInsets(WindowInsetPosition.BOTTOM_IME)
container?.applyWindowInsets(EnumSet.of(
WindowInsetPosition.TOP_MARGINS,
WindowInsetPosition.BOTTOM_MARGINS,
WindowInsetPosition.START_MARGINS,
WindowInsetPosition.END_MARGINS,
))
}
stopService(Intent(this, ClipboardEntryNotificationService::class.java))
@@ -604,16 +609,12 @@ class EntryEditActivity : DatabaseLockActivity(),
isVisible = isEnabled
}
menu?.findItem(R.id.menu_add_attachment)?.apply {
// Attachment not compatible below KitKat
isEnabled = !mIsTemplate
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
isVisible = isEnabled
}
menu?.findItem(R.id.menu_add_otp)?.apply {
// OTP not compatible below KitKat
isEnabled = mAllowOTP
&& !mIsTemplate
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
isVisible = isEnabled
}
return super.onPrepareOptionsMenu(menu)

View File

@@ -70,7 +70,6 @@ import com.kunzisoft.keepass.utils.MagikeyboardUtil
import com.kunzisoft.keepass.utils.MenuUtil
import com.kunzisoft.keepass.utils.UriUtil.isContributingUser
import com.kunzisoft.keepass.utils.UriUtil.openUrl
import com.kunzisoft.keepass.utils.allowCreateDocumentByStorageAccessFramework
import com.kunzisoft.keepass.utils.getParcelableCompat
import com.kunzisoft.keepass.view.asError
import com.kunzisoft.keepass.view.showActionErrorIfNeeded
@@ -263,7 +262,7 @@ class FileDatabaseSelectActivity : DatabaseModeActivity(),
GroupActivity.launch(
this@FileDatabaseSelectActivity,
database,
PreferencesUtil.enableReadOnlyDatabase(this@FileDatabaseSelectActivity)
false
)
}
ACTION_DATABASE_LOAD_TASK -> {
@@ -330,13 +329,7 @@ class FileDatabaseSelectActivity : DatabaseModeActivity(),
// Show open and create button or special mode
when (mSpecialMode) {
SpecialMode.DEFAULT -> {
if (packageManager.allowCreateDocumentByStorageAccessFramework()) {
// There is an activity which can handle this intent.
createDatabaseButtonView?.visibility = View.VISIBLE
} else{
// No Activity found that can handle this intent.
createDatabaseButtonView?.visibility = View.GONE
}
}
else -> {
// Disable create button if in selection mode or request for autofill

View File

@@ -48,6 +48,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.view.ActionMode
import androidx.appcompat.widget.SearchView
import androidx.appcompat.widget.Toolbar
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.view.GravityCompat
import androidx.core.view.WindowInsetsCompat
@@ -117,6 +118,7 @@ import com.kunzisoft.keepass.view.updateLockPaddingStart
import com.kunzisoft.keepass.viewmodels.GroupEditViewModel
import com.kunzisoft.keepass.viewmodels.GroupViewModel
import org.joda.time.LocalDateTime
import java.util.EnumSet
class GroupActivity : DatabaseLockActivity(),
@@ -131,6 +133,7 @@ class GroupActivity : DatabaseLockActivity(),
private var header: ViewGroup? = null
private var footer: ViewGroup? = null
private var drawerLayout: DrawerLayout? = null
private var constraintLayout: ConstraintLayout? = null
private var databaseNavView: NavigationDatabaseView? = null
private var coordinatorLayout: CoordinatorLayout? = null
private var coordinatorError: CoordinatorLayout? = null
@@ -279,6 +282,7 @@ class GroupActivity : DatabaseLockActivity(),
header = findViewById(R.id.activity_group_header)
footer = findViewById(R.id.activity_group_footer)
drawerLayout = findViewById(R.id.drawer_layout)
constraintLayout = findViewById(R.id.activity_group_container_view)
databaseNavView = findViewById(R.id.database_nav_view)
coordinatorLayout = findViewById(R.id.group_coordinator)
coordinatorError = findViewById(R.id.error_coordinator)
@@ -296,8 +300,19 @@ class GroupActivity : DatabaseLockActivity(),
// To apply fit window with transparency
setTransparentNavigationBar(applyToStatusBar = true) {
drawerLayout?.applyWindowInsets(WindowInsetPosition.TOP_BOTTOM_IME)
footer?.applyWindowInsets(WindowInsetPosition.BOTTOM_IME)
constraintLayout?.applyWindowInsets(EnumSet.of(
WindowInsetPosition.TOP_MARGINS,
WindowInsetPosition.BOTTOM_MARGINS,
WindowInsetPosition.START_MARGINS,
WindowInsetPosition.END_MARGINS,
))
// The background of the drawer is meant to overlap system bars, so use padding
databaseNavView?.applyWindowInsets(EnumSet.of(
WindowInsetPosition.TOP_PADDING,
WindowInsetPosition.BOTTOM_PADDING,
// Only on the start side, since the drawer is anchored to one side of the screen
WindowInsetPosition.START_PADDING,
))
}
lockView?.setOnClickListener {
@@ -1373,7 +1388,8 @@ class GroupActivity : DatabaseLockActivity(),
}
else -> {
// Load the previous group
loadMainGroup(mPreviousGroupsIds.removeLast())
loadMainGroup(mPreviousGroupsIds
.removeAt(mPreviousGroupsIds.lastIndex))
}
}
}

View File

@@ -43,6 +43,7 @@ import androidx.biometric.BiometricManager
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.fragment.app.commit
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.google.android.material.snackbar.Snackbar
@@ -52,6 +53,7 @@ import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper
import com.kunzisoft.keepass.activities.helpers.ExternalFileHelper
import com.kunzisoft.keepass.activities.helpers.SpecialMode
import com.kunzisoft.keepass.activities.legacy.DatabaseModeActivity
import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction
import com.kunzisoft.keepass.autofill.AutofillComponent
import com.kunzisoft.keepass.autofill.AutofillHelper
import com.kunzisoft.keepass.biometric.DeviceUnlockFragment
@@ -66,6 +68,7 @@ import com.kunzisoft.keepass.hardware.HardwareKey
import com.kunzisoft.keepass.model.CipherDecryptDatabase
import com.kunzisoft.keepass.model.CipherEncryptDatabase
import com.kunzisoft.keepass.model.CredentialStorage
import com.kunzisoft.keepass.model.DatabaseFile
import com.kunzisoft.keepass.model.RegisterInfo
import com.kunzisoft.keepass.model.SearchInfo
import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_LOAD_TASK
@@ -73,8 +76,8 @@ import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.
import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.DATABASE_URI_KEY
import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.MAIN_CREDENTIAL_KEY
import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.READ_ONLY_KEY
import com.kunzisoft.keepass.settings.DeviceUnlockSettingsActivity
import com.kunzisoft.keepass.settings.AppearanceSettingsActivity
import com.kunzisoft.keepass.settings.DeviceUnlockSettingsActivity
import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.tasks.ActionRunnable
import com.kunzisoft.keepass.utils.BACK_PREVIOUS_KEYBOARD_ACTION
@@ -105,7 +108,11 @@ class MainCredentialActivity : DatabaseModeActivity() {
private var deviceUnlockFragment: DeviceUnlockFragment? = null
private val mDatabaseFileViewModel: DatabaseFileViewModel by viewModels()
private val mDeviceUnlockViewModel: DeviceUnlockViewModel by viewModels()
private val mDeviceUnlockViewModel: DeviceUnlockViewModel? by lazy {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
ViewModelProvider(this)[DeviceUnlockViewModel::class.java]
} else null
}
private val mPasswordActivityEducation = PasswordActivityEducation(this)
@@ -147,7 +154,7 @@ class MainCredentialActivity : DatabaseModeActivity() {
mReadOnly = if (savedInstanceState != null && savedInstanceState.containsKey(KEY_READ_ONLY)) {
savedInstanceState.getBoolean(KEY_READ_ONLY)
} else {
PreferencesUtil.enableReadOnlyDatabase(this)
false
}
mRememberKeyFile = PreferencesUtil.rememberKeyFileLocations(this)
mRememberHardwareKey = PreferencesUtil.rememberHardwareKey(this)
@@ -175,7 +182,7 @@ class MainCredentialActivity : DatabaseModeActivity() {
// Listen password checkbox to init advanced unlock and confirmation button
mainCredentialView?.onConditionToStoreCredentialChanged = { _, verified ->
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mDeviceUnlockViewModel.checkConditionToStoreCredential(
mDeviceUnlockViewModel?.checkConditionToStoreCredential(
condition = verified
)
}
@@ -203,6 +210,13 @@ class MainCredentialActivity : DatabaseModeActivity() {
}
mForceReadOnly = databaseFileNotExists
// Restore read-only state from database file if not forced
if (!mForceReadOnly) {
databaseFile?.readOnly?.let { savedReadOnlyState ->
mReadOnly = savedReadOnlyState
}
}
invalidateOptionsMenu()
// Post init uri with KeyFile only if needed
@@ -233,21 +247,22 @@ class MainCredentialActivity : DatabaseModeActivity() {
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mDeviceUnlockViewModel.uiState.collect { uiState ->
mDeviceUnlockViewModel?.let { deviceUnlockViewModel ->
deviceUnlockViewModel.uiState.collect { uiState ->
// New value received
uiState.credentialRequiredCipher?.let { cipher ->
mDeviceUnlockViewModel.encryptCredential(
deviceUnlockViewModel.encryptCredential(
credential = getCredentialForEncryption(),
cipher = cipher
)
}
uiState.cipherEncryptDatabase?.let { cipherEncryptDatabase ->
onCredentialEncrypted(cipherEncryptDatabase)
mDeviceUnlockViewModel.consumeCredentialEncrypted()
deviceUnlockViewModel.consumeCredentialEncrypted()
}
uiState.cipherDecryptDatabase?.let { cipherDecryptDatabase ->
onCredentialDecrypted(cipherDecryptDatabase)
mDeviceUnlockViewModel.consumeCredentialDecrypted()
deviceUnlockViewModel.consumeCredentialDecrypted()
}
uiState.exception?.let { error ->
Snackbar.make(
@@ -255,7 +270,8 @@ class MainCredentialActivity : DatabaseModeActivity() {
deviceUnlockError(error, this@MainCredentialActivity),
Snackbar.LENGTH_LONG
).asError().show()
mDeviceUnlockViewModel.exceptionShown()
deviceUnlockViewModel.exceptionShown()
}
}
}
}
@@ -295,10 +311,6 @@ class MainCredentialActivity : DatabaseModeActivity() {
mDatabaseFileUri?.let { databaseFileUri ->
mDatabaseFileViewModel.loadDatabaseFile(databaseFileUri)
}
mDatabase?.let { database ->
launchGroupActivityIfLoaded(database)
}
}
override fun onDatabaseRetrieved(database: ContextualDatabase?) {
@@ -508,7 +520,7 @@ class MainCredentialActivity : DatabaseModeActivity() {
} else {
// Init Biometric elements
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mDeviceUnlockViewModel.connect(databaseFileUri)
mDeviceUnlockViewModel?.connect(databaseFileUri)
}
}
@@ -652,7 +664,7 @@ class MainCredentialActivity : DatabaseModeActivity() {
try {
menu.findItem(R.id.menu_open_file_read_mode_key)
} catch (e: Exception) {
Log.e(TAG, "Unable to find read mode menu")
Log.e(TAG, "Unable to find read mode menu", e)
}
performedNextEducation(menu)
},
@@ -681,7 +693,7 @@ class MainCredentialActivity : DatabaseModeActivity() {
})
}
}
} catch (ignored: Exception) {}
} catch (_: Exception) {}
}
}
@@ -702,6 +714,12 @@ class MainCredentialActivity : DatabaseModeActivity() {
R.id.menu_open_file_read_mode_key -> {
mReadOnly = !mReadOnly
changeOpenFileReadIcon(item)
// Save the read-only state to database
mDatabaseFileUri?.let { databaseUri ->
FileDatabaseHistoryAction.getInstance(applicationContext).addOrUpdateDatabaseFile(
DatabaseFile(databaseUri = databaseUri, readOnly = mReadOnly)
)
}
}
else -> MenuUtil.onDefaultMenuOptionsItemSelected(this, item)
}
@@ -712,7 +730,7 @@ class MainCredentialActivity : DatabaseModeActivity() {
override fun onDestroy() {
super.onDestroy()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mDeviceUnlockViewModel.disconnect()
mDeviceUnlockViewModel?.disconnect()
}
}

View File

@@ -176,21 +176,14 @@ class SortDialogFragment : DatabaseDialogFragment() {
return bundle
}
fun getInstance(sortNodeEnum: SortNodeEnum,
ascending: Boolean,
groupsBefore: Boolean): SortDialogFragment {
val bundle = buildBundle(sortNodeEnum, ascending, groupsBefore)
val fragment = SortDialogFragment()
fragment.arguments = bundle
return fragment
}
fun getInstance(sortNodeEnum: SortNodeEnum,
ascending: Boolean,
groupsBefore: Boolean,
recycleBinBottom: Boolean): SortDialogFragment {
recycleBinBottom: Boolean?): SortDialogFragment {
val bundle = buildBundle(sortNodeEnum, ascending, groupsBefore)
recycleBinBottom?.let {
bundle.putBoolean(SORT_RECYCLE_BIN_BOTTOM_BUNDLE_KEY, recycleBinBottom)
}
val fragment = SortDialogFragment()
fragment.arguments = bundle
return fragment

View File

@@ -76,9 +76,6 @@ class GroupFragment : DatabaseFragment(), SortDialogFragment.SortSelectionListen
private var specialMode: SpecialMode = SpecialMode.DEFAULT
private var mRecycleBinEnable: Boolean = false
private var mRecycleBin: Group? = null
private var mRecycleViewScrollListener = object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
@@ -102,21 +99,14 @@ class GroupFragment : DatabaseFragment(), SortDialogFragment.SortSelectionListen
R.id.menu_sort -> {
context?.let { context ->
val sortDialogFragment: SortDialogFragment =
if (mRecycleBinEnable) {
SortDialogFragment.getInstance(
PreferencesUtil.getListSort(context),
PreferencesUtil.getAscendingSort(context),
PreferencesUtil.getGroupsBeforeSort(context),
if (mDatabase?.isRecycleBinEnabled == true) {
PreferencesUtil.getRecycleBinBottomSort(context)
} else null
)
} else {
SortDialogFragment.getInstance(
PreferencesUtil.getListSort(context),
PreferencesUtil.getAscendingSort(context),
PreferencesUtil.getGroupsBeforeSort(context)
)
}
sortDialogFragment.show(childFragmentManager, "sortDialog")
}
true
@@ -165,9 +155,6 @@ class GroupFragment : DatabaseFragment(), SortDialogFragment.SortSelectionListen
}
override fun onDatabaseRetrieved(database: ContextualDatabase?) {
mRecycleBinEnable = database?.isRecycleBinEnabled == true
mRecycleBin = database?.recycleBin
context?.let { context ->
database?.let { database ->
mAdapter = NodesAdapter(context, database).apply {
@@ -312,6 +299,11 @@ class GroupFragment : DatabaseFragment(), SortDialogFragment.SortSelectionListen
}
}
private fun containsRecycleBin(nodes: List<Node>): Boolean {
return mDatabase?.isRecycleBinEnabled == true
&& nodes.any { it == mDatabase?.recycleBin }
}
fun actionNodesCallback(database: ContextualDatabase,
nodes: List<Node>,
menuListener: NodesActionMenuListener?,
@@ -336,8 +328,7 @@ class GroupFragment : DatabaseFragment(), SortDialogFragment.SortSelectionListen
// Open and Edit for a single item
if (nodes.size == 1) {
// Edition
if (database.isReadOnly
|| (mRecycleBinEnable && nodes[0] == mRecycleBin)) {
if (database.isReadOnly || containsRecycleBin(nodes)) {
menu?.removeItem(R.id.menu_edit)
}
} else {
@@ -357,8 +348,7 @@ class GroupFragment : DatabaseFragment(), SortDialogFragment.SortSelectionListen
}
// Deletion
if (database.isReadOnly
|| (mRecycleBinEnable && nodes.any { it == mRecycleBin })) {
if (database.isReadOnly || containsRecycleBin(nodes)) {
menu?.removeItem(R.id.menu_delete)
}
}

View File

@@ -530,9 +530,8 @@ class NodesAdapter (
holder?.otpToken?.apply {
text = otpElement?.tokenString
setTextSize(mTextSizeUnit, mOtpTokenTextDefaultDimension, mPrefSizeMultiplier)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
textDirection = View.TEXT_DIRECTION_LTR
}
}
holder?.otpContainer?.setOnClickListener {
otpElement?.token?.let { token ->

View File

@@ -38,7 +38,6 @@ class App : MultiDexApplication() {
ProcessLifecycleOwner.get().lifecycle.addObserver(AppLifecycleObserver)
Stylish.load(this)
PRNGFixes.apply()
}
}

View File

@@ -1,399 +0,0 @@
package com.kunzisoft.keepass.app;
/*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will Google be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, as long as the origin is not misrepresented.
*/
import android.os.Build;
import android.os.Process;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.SecureRandom;
import java.security.SecureRandomSpi;
import java.security.Security;
import java.util.Locale;
/**
* Fixes for the output of the default PRNG having low entropy.
*
* The fixes need to be applied via {@link #apply()} before any use of Java
* Cryptography Architecture primitives. A good place to invoke them is in the
* application's {@code onCreate}.
*/
public final class PRNGFixes {
private static final byte[] BUILD_FINGERPRINT_AND_DEVICE_SERIAL =
getBuildFingerprintAndDeviceSerial();
/** Hidden constructor to prevent instantiation. */
private PRNGFixes() {}
/**
* Applies all fixes.
*
* @throws SecurityException if a fix is needed but could not be applied.
*/
public static void apply() {
try {
if (supportedOnThisDevice()) {
applyOpenSSLFix();
installLinuxPRNGSecureRandom();
}
} catch (Exception e) {
// Do nothing, do the best we can to implement the workaround
}
}
private static boolean supportedOnThisDevice() {
// Blacklist on samsung devices
if (Build.MANUFACTURER.toLowerCase(Locale.ENGLISH).contains("samsung")) {
return false;
}
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR2) {
return false;
}
if (onSELinuxEnforce()) {
return false;
}
File urandom = new File("/dev/urandom");
// Test permissions
if ( !(urandom.canRead() && urandom.canWrite()) ) {
return false;
}
// Test actually writing to urandom
try {
FileOutputStream fos = new FileOutputStream(urandom);
fos.write(0);
} catch (Exception e) {
return false;
}
return true;
}
private static boolean onSELinuxEnforce() {
try {
ProcessBuilder builder = new ProcessBuilder("getenforce");
builder.redirectErrorStream(true);
java.lang.Process process = builder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
process.waitFor();
String output = reader.readLine();
if (output == null) {
return false;
}
return output.toLowerCase(Locale.US).startsWith("enforcing");
} catch (Exception e) {
return false;
}
}
/**
* Applies the fix for OpenSSL PRNG having low entropy. Does nothing if the
* fix is not needed.
*
* @throws SecurityException if the fix is needed but could not be applied.
*/
private static void applyOpenSSLFix() throws SecurityException {
if ((Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN)
|| (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR2)) {
// No need to apply the fix
return;
}
try {
// Mix in the device- and invocation-specific seed.
Class.forName("org.apache.harmony.xnet.provider.jsse.NativeCrypto")
.getMethod("RAND_seed", byte[].class)
.invoke(null, generateSeed());
// Mix output of Linux PRNG into OpenSSL's PRNG
int bytesRead = (Integer) Class.forName(
"org.apache.harmony.xnet.provider.jsse.NativeCrypto")
.getMethod("RAND_load_file", String.class, long.class)
.invoke(null, "/dev/urandom", 1024);
if (bytesRead != 1024) {
throw new IOException(
"Unexpected number of bytes read from Linux PRNG: "
+ bytesRead);
}
} catch (Exception e) {
throw new SecurityException("Failed to seed OpenSSL PRNG", e);
}
}
/**
* Installs a Linux PRNG-backed {@code SecureRandom} implementation as the
* default. Does nothing if the implementation is already the default or if
* there is not need to install the implementation.
*
* @throws SecurityException if the fix is needed but could not be applied.
*/
private static void installLinuxPRNGSecureRandom()
throws SecurityException {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR2) {
// No need to apply the fix
return;
}
// Install a Linux PRNG-based SecureRandom implementation as the
// default, if not yet installed.
Provider[] secureRandomProviders =
Security.getProviders("SecureRandom.SHA1PRNG");
if ((secureRandomProviders == null)
|| (secureRandomProviders.length < 1)
|| (!LinuxPRNGSecureRandomProvider.class.equals(
secureRandomProviders[0].getClass()))) {
Security.insertProviderAt(new LinuxPRNGSecureRandomProvider(), 1);
}
// Assert that new SecureRandom() and
// SecureRandom.getInstance("SHA1PRNG") return a SecureRandom backed
// by the Linux PRNG-based SecureRandom implementation.
SecureRandom rng1 = new SecureRandom();
if (!LinuxPRNGSecureRandomProvider.class.equals(
rng1.getProvider().getClass())) {
throw new SecurityException(
"new SecureRandom() backed by wrong Provider: "
+ rng1.getProvider().getClass());
}
SecureRandom rng2;
try {
rng2 = SecureRandom.getInstance("SHA1PRNG");
} catch (NoSuchAlgorithmException e) {
throw new SecurityException("SHA1PRNG not available", e);
}
if (!LinuxPRNGSecureRandomProvider.class.equals(
rng2.getProvider().getClass())) {
throw new SecurityException(
"SecureRandom.getInstance(\"SHA1PRNG\") backed by wrong"
+ " Provider: " + rng2.getProvider().getClass());
}
}
/**
* {@code Provider} of {@code SecureRandom} engines which pass through
* all requests to the Linux PRNG.
*/
private static class LinuxPRNGSecureRandomProvider extends Provider {
public LinuxPRNGSecureRandomProvider() {
super("LinuxPRNG",
1.0,
"A Linux-specific random number provider that uses"
+ " /dev/urandom");
// Although /dev/urandom is not a SHA-1 PRNG, some apps
// explicitly request a SHA1PRNG SecureRandom and we thus need to
// prevent them from getting the default implementation whose output
// may have low entropy.
put("SecureRandom.SHA1PRNG", LinuxPRNGSecureRandom.class.getName());
put("SecureRandom.SHA1PRNG ImplementedIn", "Software");
}
}
/**
* {@link SecureRandomSpi} which passes all requests to the Linux PRNG
* ({@code /dev/urandom}).
*/
public static class LinuxPRNGSecureRandom extends SecureRandomSpi {
/*
* IMPLEMENTATION NOTE: Requests to generate bytes and to mix in a seed
* are passed through to the Linux PRNG (/dev/urandom). Instances of
* this class seed themselves by mixing in the current time, PID, UID,
* build fingerprint, and hardware serial number (where available) into
* Linux PRNG.
*
* Concurrency: Read requests to the underlying Linux PRNG are
* serialized (on sLock) to ensure that multiple threads do not get
* duplicated PRNG output.
*/
private static final File URANDOM_FILE = new File("/dev/urandom");
private static final Object sLock = new Object();
/**
* Input stream for reading from Linux PRNG or {@code null} if not yet
* opened.
*
* @GuardedBy("sLock")
*/
private static DataInputStream sUrandomIn;
/**
* Output stream for writing to Linux PRNG or {@code null} if not yet
* opened.
*
* @GuardedBy("sLock")
*/
private static OutputStream sUrandomOut;
/**
* Whether this engine instance has been seeded. This is needed because
* each instance needs to seed itself if the client does not explicitly
* seed it.
*/
private boolean mSeeded;
@Override
protected void engineSetSeed(byte[] bytes) {
try {
OutputStream out;
synchronized (sLock) {
out = getUrandomOutputStream();
}
out.write(bytes);
out.flush();
mSeeded = true;
} catch (IOException e) {
throw new SecurityException(
"Failed to mix seed into " + URANDOM_FILE, e);
}
}
@Override
protected void engineNextBytes(byte[] bytes) {
if (!mSeeded) {
// Mix in the device- and invocation-specific seed.
engineSetSeed(generateSeed());
}
try {
DataInputStream in;
synchronized (sLock) {
in = getUrandomInputStream();
}
synchronized (in) {
in.readFully(bytes);
}
} catch (IOException e) {
throw new SecurityException(
"Failed to read from " + URANDOM_FILE, e);
}
}
@Override
protected byte[] engineGenerateSeed(int size) {
byte[] seed = new byte[size];
engineNextBytes(seed);
return seed;
}
private DataInputStream getUrandomInputStream() {
synchronized (sLock) {
if (sUrandomIn == null) {
// NOTE: Consider inserting a BufferedInputStream between
// DataInputStream and FileInputStream if you need higher
// PRNG output performance and can live with future PRNG
// output being pulled into this process prematurely.
try {
sUrandomIn = new DataInputStream(
new FileInputStream(URANDOM_FILE));
} catch (IOException e) {
throw new SecurityException("Failed to open "
+ URANDOM_FILE + " for reading", e);
}
}
return sUrandomIn;
}
}
private OutputStream getUrandomOutputStream() {
synchronized (sLock) {
if (sUrandomOut == null) {
try {
sUrandomOut = new FileOutputStream(URANDOM_FILE);
} catch (IOException e) {
throw new SecurityException("Failed to open "
+ URANDOM_FILE + " for writing", e);
}
}
return sUrandomOut;
}
}
}
/**
* Generates a device- and invocation-specific seed to be mixed into the
* Linux PRNG.
*/
private static byte[] generateSeed() {
try {
ByteArrayOutputStream seedBuffer = new ByteArrayOutputStream();
DataOutputStream seedBufferOut =
new DataOutputStream(seedBuffer);
seedBufferOut.writeLong(System.currentTimeMillis());
seedBufferOut.writeLong(System.nanoTime());
seedBufferOut.writeInt(Process.myPid());
seedBufferOut.writeInt(Process.myUid());
seedBufferOut.write(BUILD_FINGERPRINT_AND_DEVICE_SERIAL);
seedBufferOut.close();
return seedBuffer.toByteArray();
} catch (IOException e) {
throw new SecurityException("Failed to generate seed", e);
}
}
/**
* Gets the hardware serial number of this device.
*
* @return serial number or {@code null} if not available.
*/
private static String getDeviceSerialNumber() {
// We're using the Reflection API because Build.SERIAL is only available
// since API Level 9 (Gingerbread, Android 2.3).
try {
return (String) Build.class.getField("SERIAL").get(null);
} catch (Exception ignored) {
return null;
}
}
private static byte[] getBuildFingerprintAndDeviceSerial() {
StringBuilder result = new StringBuilder();
String fingerprint = Build.FINGERPRINT;
if (fingerprint != null) {
result.append(fingerprint);
}
String serial = getDeviceSerialNumber();
if (serial != null) {
result.append(serial);
}
try {
return result.toString().getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("UTF-8 encoding not supported");
}
}
}

View File

@@ -26,10 +26,11 @@ import android.content.Context
import androidx.room.AutoMigration
@Database(
version = 2,
version = 3,
entities = [FileDatabaseHistoryEntity::class, CipherDatabaseEntity::class],
autoMigrations = [
AutoMigration (from = 1, to = 2)
AutoMigration (from = 1, to = 2),
AutoMigration (from = 2, to = 3)
]
)
abstract class AppDatabase : RoomDatabase() {

View File

@@ -49,6 +49,7 @@ class FileDatabaseHistoryAction(private val applicationContext: Context) {
databaseUri,
fileDatabaseHistoryEntity?.keyFileUri?.parseUri(),
HardwareKey.getHardwareKeyFromString(fileDatabaseHistoryEntity?.hardwareKey),
fileDatabaseHistoryEntity?.readOnly,
fileDatabaseHistoryEntity?.databaseUri?.decodeUri(),
fileDatabaseInfo.retrieveDatabaseAlias(fileDatabaseHistoryEntity?.databaseAlias
?: ""),
@@ -99,6 +100,7 @@ class FileDatabaseHistoryAction(private val applicationContext: Context) {
fileDatabaseHistoryEntity.databaseUri.parseUri(),
fileDatabaseHistoryEntity.keyFileUri?.parseUri(),
HardwareKey.getHardwareKeyFromString(fileDatabaseHistoryEntity.hardwareKey),
fileDatabaseHistoryEntity.readOnly,
fileDatabaseHistoryEntity.databaseUri.decodeUri(),
fileDatabaseInfo.retrieveDatabaseAlias(fileDatabaseHistoryEntity.databaseAlias),
fileDatabaseInfo.exists,
@@ -147,6 +149,8 @@ class FileDatabaseHistoryAction(private val applicationContext: Context) {
?: "",
databaseFileToAddOrUpdate.keyFileUri?.toString(),
databaseFileToAddOrUpdate.hardwareKey?.value,
databaseFileToAddOrUpdate.readOnly
?: fileDatabaseHistoryRetrieve?.readOnly,
System.currentTimeMillis()
)
@@ -168,6 +172,7 @@ class FileDatabaseHistoryAction(private val applicationContext: Context) {
fileDatabaseHistory.databaseUri.parseUri(),
fileDatabaseHistory.keyFileUri?.parseUri(),
HardwareKey.getHardwareKeyFromString(fileDatabaseHistory.hardwareKey),
fileDatabaseHistory.readOnly,
fileDatabaseHistory.databaseUri.decodeUri(),
fileDatabaseInfo.retrieveDatabaseAlias(fileDatabaseHistory.databaseAlias),
fileDatabaseInfo.exists,
@@ -195,6 +200,7 @@ class FileDatabaseHistoryAction(private val applicationContext: Context) {
fileDatabaseHistory.databaseUri.parseUri(),
fileDatabaseHistory.keyFileUri?.parseUri(),
HardwareKey.getHardwareKeyFromString(fileDatabaseHistory.hardwareKey),
fileDatabaseHistory.readOnly,
fileDatabaseHistory.databaseUri.decodeUri(),
databaseFileToDelete.databaseAlias
)

View File

@@ -38,6 +38,9 @@ data class FileDatabaseHistoryEntity(
@ColumnInfo(name = "hardware_key")
var hardwareKey: String?,
@ColumnInfo(name = "read_only")
var readOnly: Boolean?,
@ColumnInfo(name = "updated")
val updated: Long
) {

View File

@@ -380,7 +380,7 @@ class DeviceUnlockManager(private var appContext: Context) {
}
}
fun deviceUnlockError(error: Exception, context: Context): String {
fun deviceUnlockError(error: Throwable, context: Context): String {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& (error is UnrecoverableKeyException
|| error is KeyPermanentlyInvalidatedException)) {

View File

@@ -254,6 +254,7 @@ class DatabaseTaskProvider(
}
private fun initServiceConnection() {
stopDialog()
if (serviceConnection == null) {
serviceConnection = object : ServiceConnection {
override fun onBindingDied(name: ComponentName?) {

View File

@@ -59,9 +59,9 @@ object SearchHelper {
&& !searchInfo.containsOnlyNullValues()) {
// If search provide results
database.createVirtualGroupFromSearchInfo(
searchInfo.toString(),
searchInfo.isASearchByDomain(),
MAX_SEARCH_ENTRY
searchInfoString = searchInfo.toString(),
searchInfoByDomain = searchInfo.isASearchByDomain(),
max = MAX_SEARCH_ENTRY
)?.let { searchGroup ->
if (searchGroup.numberOfChildEntries > 0) {
searchWithoutUI = true

View File

@@ -12,6 +12,7 @@ import android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_NONE
import android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE
import android.os.Build
import android.os.IBinder
import android.util.Log
import android.util.TypedValue
import android.widget.Toast
import androidx.core.app.NotificationCompat
@@ -156,11 +157,21 @@ abstract class NotificationService : Service() {
mReset = true
}
override fun onDestroy() {
override fun onTimeout(startId: Int, fgsType: Int) {
super.onTimeout(startId, fgsType)
Log.e(javaClass::class.simpleName, "The service took too long to execute")
cancelNotification()
stopSelf()
}
protected fun cancelNotification() {
mTimerJob?.cancel()
mTimerJob = null
notificationManager?.cancel(notificationId)
}
override fun onDestroy() {
cancelNotification()
super.onDestroy()
}

View File

@@ -618,12 +618,6 @@ object PreferencesUtil {
context.resources.getBoolean(R.bool.allow_no_password_default))
}
fun enableReadOnlyDatabase(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.enable_read_only_key),
context.resources.getBoolean(R.bool.enable_read_only_default))
}
fun deletePasswordAfterConnexionAttempt(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.delete_entered_password_key),
@@ -804,7 +798,6 @@ object PreferencesUtil {
when (name) {
context.getString(R.string.allow_no_password_key) -> editor.putBoolean(name, value.toBoolean())
context.getString(R.string.delete_entered_password_key) -> editor.putBoolean(name, value.toBoolean())
context.getString(R.string.enable_read_only_key) -> editor.putBoolean(name, value.toBoolean())
context.getString(R.string.enable_auto_save_database_key) -> editor.putBoolean(name, value.toBoolean())
context.getString(R.string.enable_keep_screen_on_key) -> editor.putBoolean(name, value.toBoolean())
context.getString(R.string.auto_focus_search_key) -> editor.putBoolean(name, value.toBoolean())

View File

@@ -70,8 +70,12 @@ open class SettingsActivity
// To apply navigation bar with background color
/* TODO Settings nav bar
setTransparentNavigationBar {
coordinatorLayout?.applyWindowInsets(WindowInsetPosition.TOP)
footer?.applyWindowInsets(WindowInsetPosition.BOTTOM)
coordinatorLayout?.applyWindowInsets(EnumSet.of(
WindowInsetPosition.TOP_MARGINS,
WindowInsetPosition.BOTTOM_MARGINS,
WindowInsetPosition.START_MARGINS,
WindowInsetPosition.END_MARGINS,
))
}*/
mExternalFileHelper = ExternalFileHelper(this)

View File

@@ -65,7 +65,6 @@ object TimeoutHelper {
(context.applicationContext.getSystemService(Context.ALARM_SERVICE) as AlarmManager?)?.let { alarmManager ->
val triggerTime = System.currentTimeMillis() + timeout
Log.d(TAG, "TimeoutHelper start")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
&& !alarmManager.canScheduleExactAlarms()) {
alarmManager.set(
@@ -80,13 +79,6 @@ object TimeoutHelper {
getLockPendingIntent(context)
)
}
} else {
alarmManager.set(
AlarmManager.RTC,
triggerTime,
getLockPendingIntent(context)
)
}
}
}
}

View File

@@ -77,7 +77,6 @@ class LockReceiver(private var lockAction: () -> Unit) : BroadcastReceiver() {
// Launch the effective action after a small time
val first: Long = System.currentTimeMillis() + context.getString(R.string.timeout_screen_off).toLong()
(context.getSystemService(ALARM_SERVICE) as AlarmManager?)?.let { alarmManager ->
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
&& !alarmManager.canScheduleExactAlarms()) {
alarmManager.set(
@@ -92,13 +91,6 @@ class LockReceiver(private var lockAction: () -> Unit) : BroadcastReceiver() {
lockPendingIntent
)
}
} else {
alarmManager.set(
AlarmManager.RTC_WAKEUP,
first,
lockPendingIntent
)
}
}
} else {
cancelLockPendingIntent(context)

View File

@@ -67,7 +67,6 @@ object UriUtil {
readOnly: Boolean) {
try {
// try to persist read and write permissions
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
contentResolver?.apply {
var readPermissionAllowed = false
var writePermissionAllowed = false
@@ -118,7 +117,6 @@ object UriUtil {
}
}
}
}
} catch (e: Exception) {
if (release)
Log.e(TAG, "Unable to release persistable URI permission", e)
@@ -140,7 +138,6 @@ object UriUtil {
}
fun Context.releaseAllUnnecessaryPermissionUris() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
applicationContext?.let { appContext ->
val fileDatabaseHistoryAction = FileDatabaseHistoryAction.getInstance(appContext)
fileDatabaseHistoryAction.getDatabaseFileList { databaseFileList ->
@@ -163,11 +160,9 @@ object UriUtil {
}
}
}
}
fun Intent.getUri(key: String): Uri? {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
val clipData = this.clipData
if (clipData != null) {
if (clipData.description.label == key) {
@@ -179,7 +174,6 @@ object UriUtil {
}
}
}
}
} catch (e: Exception) {
return this.getParcelableExtraCompat(key)
}

View File

@@ -20,7 +20,6 @@
package com.kunzisoft.keepass.view
import android.content.Context
import android.os.Build
import android.text.Spannable
import android.util.AttributeSet
import android.util.TypedValue
@@ -104,21 +103,17 @@ class PasswordTextEditFieldView @JvmOverloads constructor(context: Context,
id = passwordProgressViewId
layoutParams = (layoutParams as LayoutParams?)?.also {
it.addRule(LEFT_OF, actionImageButtonId)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
it.addRule(START_OF, actionImageButtonId)
}
}
}
mPasswordEntropyView.apply {
id = passwordEntropyViewId
layoutParams = (layoutParams as LayoutParams?)?.also {
it.addRule(ALIGN_RIGHT, passwordProgressViewId)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
it.addRule(ALIGN_END, passwordProgressViewId)
}
}
}
}
private fun getEntropyStrength(passwordText: String) {
mPasswordEntropyCalculator.getEntropyStrength(passwordText) { entropyStrength ->

View File

@@ -123,7 +123,6 @@ class TemplateEditView @JvmOverloads constructor(context: Context,
setMaxChars(templateAttribute.options.getNumberChars())
setMaxLines(templateAttribute.options.getNumberLines())
setActionClick(templateAttribute, field, this)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
if (field.protectedValue.isProtected) {
textDirection = TEXT_DIRECTION_LTR
}
@@ -133,7 +132,6 @@ class TemplateEditView @JvmOverloads constructor(context: Context,
}
}
}
}
override fun buildListItemsView(templateAttribute: TemplateAttribute,
field: Field): TextSelectFieldView? {

View File

@@ -63,9 +63,7 @@ class TemplateView @JvmOverloads constructor(context: Context,
// Here the value is often empty
if (field.protectedValue.isProtected) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
textDirection = TEXT_DIRECTION_LTR
}
if (mFirstTimeAskAllowCopyProtectedFields) {
setCopyButtonState(TextFieldView.ButtonState.DEACTIVATE)
setCopyButtonClickListener { _, _ ->
@@ -179,9 +177,7 @@ class TemplateView @JvmOverloads constructor(context: Context,
otpElement.type.name,
ProtectedString(false, otpElement.token)))
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
textDirection = TEXT_DIRECTION_LTR
}
mLastOtpTokenView = this
mOtpRunnable = Runnable {
if (otpElement.shouldRefreshToken()) {

View File

@@ -51,9 +51,7 @@ open class TextEditFieldView @JvmOverloads constructor(context: Context,
imeOptions = EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING
importantForAutofill = IMPORTANT_FOR_AUTOFILL_NO
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
importantForAccessibility = IMPORTANT_FOR_ACCESSIBILITY_NO
}
maxLines = 1
}
private var actionImageButton = AppCompatImageButton(
@@ -70,11 +68,9 @@ open class TextEditFieldView @JvmOverloads constructor(context: Context,
resources.displayMetrics
).toInt()
it.addRule(ALIGN_PARENT_RIGHT)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
it.addRule(ALIGN_PARENT_END)
}
}
visibility = View.GONE
visibility = GONE
contentDescription = context.getString(R.string.menu_edit)
}
@@ -91,11 +87,9 @@ open class TextEditFieldView @JvmOverloads constructor(context: Context,
id = labelViewId
layoutParams = (layoutParams as LayoutParams?)?.also {
it.addRule(LEFT_OF, actionImageButtonId)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
it.addRule(START_OF, actionImageButtonId)
}
}
}
valueView.apply {
id = valueViewId
}
@@ -192,7 +186,7 @@ open class TextEditFieldView @JvmOverloads constructor(context: Context,
actionImageButton.setImageDrawable(ContextCompat.getDrawable(context, it))
}
actionImageButton.setOnClickListener(onActionClickListener)
actionImageButton.visibility = if (onActionClickListener == null) View.GONE else View.VISIBLE
actionImageButton.visibility = if (onActionClickListener == null) GONE else VISIBLE
}
override var isFieldVisible: Boolean

View File

@@ -63,13 +63,12 @@ open class TextFieldView @JvmOverloads constructor(context: Context,
4f,
resources.displayMetrics
).toInt()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
it.marginStart = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
4f,
resources.displayMetrics
).toInt()
}
}
}
protected val valueView = AppCompatTextView(context).apply {
@@ -88,14 +87,12 @@ open class TextFieldView @JvmOverloads constructor(context: Context,
8f,
resources.displayMetrics
).toInt()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
it.marginStart = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
8f,
resources.displayMetrics
).toInt()
}
}
setTextIsSelectable(true)
}
private var showButton = AppCompatImageButton(
@@ -128,24 +125,22 @@ open class TextFieldView @JvmOverloads constructor(context: Context,
id = copyButtonId
layoutParams = (layoutParams as LayoutParams?)?.also {
it.addRule(ALIGN_PARENT_RIGHT)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
it.addRule(ALIGN_PARENT_END)
}
}
}
showButton.apply {
id = showButtonId
layoutParams = (layoutParams as LayoutParams?)?.also {
if (copyButton.isVisible) {
it.addRule(LEFT_OF, copyButtonId)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
it.addRule(START_OF, copyButtonId)
}
} else {
it.addRule(ALIGN_PARENT_RIGHT)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
it.addRule(ALIGN_PARENT_END)
}
}
}
}
@@ -153,18 +148,14 @@ open class TextFieldView @JvmOverloads constructor(context: Context,
id = labelViewId
layoutParams = (layoutParams as LayoutParams?)?.also {
it.addRule(LEFT_OF, showButtonId)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
it.addRule(START_OF, showButtonId)
}
}
}
valueView.apply {
id = valueViewId
layoutParams = (layoutParams as LayoutParams?)?.also {
it.addRule(LEFT_OF, showButtonId)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
it.addRule(START_OF, showButtonId)
}
it.addRule(BELOW, labelViewId)
}
}

View File

@@ -10,7 +10,12 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import android.widget.*
import android.widget.AdapterView
import android.widget.BaseAdapter
import android.widget.LinearLayout
import android.widget.RelativeLayout
import android.widget.Spinner
import android.widget.TextView
import androidx.annotation.DrawableRes
import androidx.appcompat.widget.AppCompatImageButton
import androidx.core.content.ContextCompat
@@ -51,9 +56,7 @@ class TextSelectFieldView @JvmOverloads constructor(context: Context,
imeOptions = EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING
importantForAutofill = IMPORTANT_FOR_AUTOFILL_NO
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
importantForAccessibility = IMPORTANT_FOR_ACCESSIBILITY_NO
}
val drawable = ContextCompat.getDrawable(context, R.drawable.ic_arrow_down_white_24dp)
?.apply {
mutate().colorFilter = BlendModeColorFilterCompat
@@ -65,14 +68,12 @@ class TextSelectFieldView @JvmOverloads constructor(context: Context,
drawable,
null
)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
setCompoundDrawablesRelativeWithIntrinsicBounds(
null,
null,
drawable,
null
)
}
isFocusable = false
inputType = InputType.TYPE_NULL
maxLines = 1
@@ -94,10 +95,8 @@ class TextSelectFieldView @JvmOverloads constructor(context: Context,
resources.displayMetrics
).toInt()
it.addRule(ALIGN_PARENT_RIGHT)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
it.addRule(ALIGN_PARENT_END)
}
}
visibility = View.GONE
contentDescription = context.getString(R.string.menu_edit)
}
@@ -132,18 +131,14 @@ class TextSelectFieldView @JvmOverloads constructor(context: Context,
id = labelViewId
layoutParams = (layoutParams as LayoutParams?).also {
it?.addRule(LEFT_OF, actionImageButtonId)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
it?.addRule(START_OF, actionImageButtonId)
}
}
}
valueSpinnerView.apply {
id = valueViewId
layoutParams = (layoutParams as LayoutParams?).also {
it?.addRule(LEFT_OF, actionImageButtonId)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
it?.addRule(START_OF, actionImageButtonId)
}
it?.addRule(BELOW, labelViewId)
}
}

View File

@@ -24,7 +24,6 @@ import android.animation.AnimatorSet
import android.animation.ValueAnimator
import android.app.Activity
import android.content.Context
import android.content.res.Configuration
import android.graphics.Color
import android.graphics.Paint
import android.graphics.PorterDuff
@@ -58,7 +57,6 @@ import androidx.core.view.WindowInsetsCompat
import androidx.core.view.forEach
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding
import androidx.core.view.updatePaddingRelative
import com.google.android.material.appbar.CollapsingToolbarLayout
import com.google.android.material.snackbar.Snackbar
@@ -66,6 +64,7 @@ import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.helper.getLocalizedMessage
import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.tasks.ActionRunnable
import java.util.EnumSet
/**
@@ -234,11 +233,7 @@ fun View.updateLockPaddingStart() {
R.dimen.hidden_lock_button_size
}
).let { lockPadding ->
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
updatePaddingRelative(lockPadding)
} else {
updatePadding(lockPadding)
}
}
}
@@ -308,10 +303,9 @@ fun CollapsingToolbarLayout.changeTitleColor(color: Int) {
invalidate()
}
@Suppress("DEPRECATION")
fun Activity.setTransparentNavigationBar(applyToStatusBar: Boolean = false, applyWindowInsets: () -> Unit) {
// Only in portrait
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1
&& resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
WindowCompat.setDecorFitsSystemWindows(window, false)
window.navigationBarColor = ContextCompat.getColor(this, R.color.surface_selector)
if (applyToStatusBar) {
@@ -327,7 +321,7 @@ fun Activity.setTransparentNavigationBar(applyToStatusBar: Boolean = false, appl
/**
* Apply a margin to a view to fix the window inset
*/
fun View.applyWindowInsets(position: WindowInsetPosition = WindowInsetPosition.BOTTOM) {
fun View.applyWindowInsets(positions: EnumSet<WindowInsetPosition>) {
ViewCompat.setOnApplyWindowInsetsListener(this) { view, windowInsets ->
var consumed = false
@@ -343,52 +337,78 @@ fun View.applyWindowInsets(position: WindowInsetPosition = WindowInsetPosition.B
}
}
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
when (position) {
WindowInsetPosition.TOP -> {
if (view.layoutParams is ViewGroup.MarginLayoutParams) {
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()
or WindowInsetsCompat.Type.displayCutout()
or WindowInsetsCompat.Type.ime())
val isRtl = layoutDirection == View.LAYOUT_DIRECTION_RTL
val wantTopMargins = positions.contains(WindowInsetPosition.TOP_MARGINS)
val wantBottomMargins = positions.contains(WindowInsetPosition.BOTTOM_MARGINS)
val wantStartMargins = positions.contains(WindowInsetPosition.START_MARGINS)
val wantEndMargins = positions.contains(WindowInsetPosition.END_MARGINS)
if (view.layoutParams is ViewGroup.MarginLayoutParams
&& (wantTopMargins || wantBottomMargins || wantStartMargins || wantEndMargins)) {
view.updateLayoutParams<ViewGroup.MarginLayoutParams> {
if (wantTopMargins) {
topMargin = insets.top
}
}
}
WindowInsetPosition.LEGIT_TOP -> {
if (view.layoutParams is ViewGroup.MarginLayoutParams) {
view.updateLayoutParams<ViewGroup.MarginLayoutParams> {
topMargin = 0
}
}
}
WindowInsetPosition.BOTTOM -> {
if (view.layoutParams is ViewGroup.MarginLayoutParams) {
view.updateLayoutParams<ViewGroup.MarginLayoutParams> {
if (wantBottomMargins) {
bottomMargin = insets.bottom
}
if (wantStartMargins) {
if (isRtl) {
rightMargin = insets.right
} else {
leftMargin = insets.left
}
}
WindowInsetPosition.BOTTOM_IME -> {
val imeHeight = windowInsets.getInsets(WindowInsetsCompat.Type.ime()).bottom
if (view.layoutParams is ViewGroup.MarginLayoutParams) {
view.updateLayoutParams<ViewGroup.MarginLayoutParams> {
bottomMargin = if (imeHeight > 1) 0 else insets.bottom
}
}
}
WindowInsetPosition.TOP_BOTTOM_IME -> {
val imeHeight = windowInsets.getInsets(WindowInsetsCompat.Type.ime()).bottom
if (view.layoutParams is ViewGroup.MarginLayoutParams) {
view.updateLayoutParams<ViewGroup.MarginLayoutParams> {
topMargin = insets.top
bottomMargin = if (imeHeight > 1) imeHeight else 0
if (wantEndMargins) {
if (isRtl) {
leftMargin = insets.left
} else {
rightMargin = insets.right
}
}
}
}
val wantTopPadding = positions.contains(WindowInsetPosition.TOP_PADDING)
val wantBottomPadding = positions.contains(WindowInsetPosition.BOTTOM_PADDING)
val wantStartPadding = positions.contains(WindowInsetPosition.START_PADDING)
val wantEndPadding = positions.contains(WindowInsetPosition.END_PADDING)
if (wantTopPadding || wantBottomPadding || wantStartPadding || wantEndPadding) {
val topPadding = if (wantTopPadding) insets.top else 0
val bottomPadding = if (wantBottomPadding) insets.bottom else 0
var leftPadding = 0
var rightPadding = 0
if (wantStartPadding) {
if (isRtl) {
rightPadding = insets.right
} else {
leftPadding = insets.left
}
}
if (wantEndPadding) {
if (isRtl) {
leftPadding = insets.left
} else {
rightPadding = insets.right
}
}
setPadding(leftPadding, topPadding, rightPadding, bottomPadding)
}
// If any of the children consumed the insets, return an appropriate value
if (consumed) WindowInsetsCompat.CONSUMED else windowInsets
}
}
enum class WindowInsetPosition {
TOP, BOTTOM, LEGIT_TOP, BOTTOM_IME, TOP_BOTTOM_IME
TOP_MARGINS, BOTTOM_MARGINS, START_MARGINS, END_MARGINS,
TOP_PADDING, BOTTOM_PADDING, START_PADDING, END_PADDING,
}

View File

@@ -20,11 +20,14 @@ import com.kunzisoft.keepass.model.CipherDecryptDatabase
import com.kunzisoft.keepass.model.CipherEncryptDatabase
import com.kunzisoft.keepass.model.CredentialStorage
import com.kunzisoft.keepass.settings.PreferencesUtil
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import javax.crypto.Cipher
@@ -37,6 +40,8 @@ class DeviceUnlockViewModel(application: Application): AndroidViewModel(applicat
private var deviceUnlockManager: DeviceUnlockManager? = null
private var databaseUri: Uri? = null
private var mCipherJob: Job? = null
private var deviceUnlockMode = DeviceUnlockMode.BIOMETRIC_UNAVAILABLE
var cryptoPrompt: DeviceUnlockCryptoPrompt? = null
private set
@@ -95,6 +100,18 @@ class DeviceUnlockViewModel(application: Application): AndroidViewModel(applicat
cipherDatabaseAction.registerDatabaseListener(cipherDatabaseListener)
}
private fun cancelAndLaunchCipherJob(
coroutineExceptionHandler: CoroutineExceptionHandler = CoroutineExceptionHandler { _, e ->
setException(e)
},
block: suspend () -> Unit
) {
mCipherJob?.cancel()
mCipherJob = viewModelScope.launch(coroutineExceptionHandler) {
block()
}
}
fun checkConditionToStoreCredential(condition: Boolean) {
isConditionToStoreCredentialVerified = condition
checkUnlockAvailability()
@@ -153,12 +170,8 @@ class DeviceUnlockViewModel(application: Application): AndroidViewModel(applicat
private fun changeMode(deviceUnlockMode: DeviceUnlockMode) {
this.deviceUnlockMode = deviceUnlockMode
when (deviceUnlockMode) {
DeviceUnlockMode.STORE_CREDENTIAL -> {
initEncryptData()
}
DeviceUnlockMode.EXTRACT_CREDENTIAL -> {
initDecryptData()
}
DeviceUnlockMode.STORE_CREDENTIAL -> initEncryptData()
DeviceUnlockMode.EXTRACT_CREDENTIAL -> initDecryptData()
else -> {}
}
_uiState.update { currentState ->
@@ -246,7 +259,7 @@ class DeviceUnlockViewModel(application: Application): AndroidViewModel(applicat
credential: ByteArray,
cipher: Cipher?
) {
try {
cancelAndLaunchCipherJob {
deviceUnlockManager?.encryptData(
value = credential,
cipher = cipher,
@@ -260,12 +273,10 @@ class DeviceUnlockViewModel(application: Application): AndroidViewModel(applicat
this.specParameters = ivSpec
}
)
} ?: setException(UnknownDatabaseLocationException())
} ?: throw UnknownDatabaseLocationException()
}
)
} catch (e: Exception) {
setException(e)
} finally {
}
// Reinit credential storage request
_uiState.update { currentState ->
currentState.copy(
@@ -273,13 +284,12 @@ class DeviceUnlockViewModel(application: Application): AndroidViewModel(applicat
)
}
}
}
fun decryptCredential(cipher: Cipher?) {
// retrieve the encrypted value from preferences
cancelAndLaunchCipherJob {
databaseUri?.let { databaseUri ->
cipherDatabase?.encryptedValue?.let { encryptedCredential ->
try {
deviceUnlockManager?.decryptData(
encryptedValue = encryptedCredential,
cipher = cipher,
@@ -295,12 +305,10 @@ class DeviceUnlockViewModel(application: Application): AndroidViewModel(applicat
cipherDatabaseAction.resetCipherParameters(databaseUri)
}
)
} catch (e: Exception) {
setException(e)
}
} ?: deleteEncryptedDatabaseKey()
} ?: run {
setException(UnknownDatabaseLocationException())
throw UnknownDatabaseLocationException()
}
}
}
@@ -368,7 +376,7 @@ class DeviceUnlockViewModel(application: Application): AndroidViewModel(applicat
}
}
fun setException(value: Exception?) {
fun setException(value: Throwable?) {
_uiState.update { currentState ->
currentState.copy(
exception = value
@@ -385,18 +393,16 @@ class DeviceUnlockViewModel(application: Application): AndroidViewModel(applicat
}
private fun initEncryptData() {
try {
cancelAndLaunchCipherJob {
deviceUnlockManager = DeviceUnlockManager(getApplication())
deviceUnlockManager?.initEncryptData { cryptoPrompt ->
onPromptRequested(cryptoPrompt)
} ?: setException(Exception("Device unlock manager not initialized"))
} catch (e: Exception) {
setException(e)
} ?: throw Exception("Device unlock manager not initialized")
}
}
private fun initDecryptData() {
try {
cancelAndLaunchCipherJob {
cipherDatabase?.let { cipherDb ->
deviceUnlockManager = DeviceUnlockManager(getApplication())
deviceUnlockManager?.initDecryptData(cipherDb.specParameters) { cryptoPrompt ->
@@ -404,10 +410,8 @@ class DeviceUnlockViewModel(application: Application): AndroidViewModel(applicat
cryptoPrompt,
autoOpen = isAutoOpenBiometricPromptAllowed
)
} ?: setException(Exception("Device unlock manager not initialized"))
} ?: setException(Exception("Cipher database not initialized"))
} catch (e: Exception) {
setException(e)
} ?: throw Exception("Device unlock manager not initialized")
} ?: throw Exception("Cipher database not initialized")
}
}
@@ -475,5 +479,5 @@ data class DeviceUnlockState(
val cipherDecryptDatabase: CipherDecryptDatabase? = null,
val cryptoPromptState: DeviceUnlockPromptMode = DeviceUnlockPromptMode.IDLE_CLOSE,
val autoOpenPrompt: Boolean = false,
val exception: Exception? = null
val exception: Throwable? = null
)

View File

@@ -19,10 +19,11 @@
-->
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:filterTouchesWhenObscured="true"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical">
<include

View File

@@ -20,6 +20,7 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_entry_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:filterTouchesWhenObscured="true">

View File

@@ -21,6 +21,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:filterTouchesWhenObscured="true"

View File

@@ -19,11 +19,12 @@
-->
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:fitsSystemWindows="true"
android:id="@+id/icon_picker_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:filterTouchesWhenObscured="true"
xmlns:app="http://schemas.android.com/apk/res-auto">
android:filterTouchesWhenObscured="true">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/icon_picker_coordinator"

View File

@@ -19,11 +19,12 @@
-->
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:fitsSystemWindows="true"
android:id="@+id/key_generator_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:filterTouchesWhenObscured="true"
xmlns:app="http://schemas.android.com/apk/res-auto">
android:filterTouchesWhenObscured="true">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/key_generator_coordinator"

View File

@@ -21,6 +21,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:filterTouchesWhenObscured="true"

View File

@@ -19,6 +19,7 @@
-->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:filterTouchesWhenObscured="true"

View File

@@ -122,8 +122,7 @@
android:inputType="textPassword"
android:importantForAccessibility="no"
android:importantForAutofill="no"
android:hint="@string/otp_secret"
tools:targetApi="jelly_bean" />
android:hint="@string/otp_secret" />
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
@@ -178,8 +177,7 @@
tools:text="30"
android:maxLength="3"
android:digits="0123456789"
android:imeOptions="actionNext"
tools:targetApi="jelly_bean" />
android:imeOptions="actionNext" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/setup_otp_counter_label"
@@ -198,8 +196,7 @@
android:importantForAutofill="no"
android:hint="@string/otp_counter"
tools:text="1"
android:imeOptions="actionNext"
tools:targetApi="jelly_bean" />
android:imeOptions="actionNext" />
</com.google.android.material.textfield.TextInputLayout>
<androidx.constraintlayout.widget.Guideline
@@ -228,8 +225,7 @@
tools:text="6"
android:maxLength="2"
android:digits="0123456789"
android:imeOptions="actionNext"
tools:targetApi="jelly_bean" />
android:imeOptions="actionNext" />
</com.google.android.material.textfield.TextInputLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -65,7 +65,6 @@
android:layout_height="wrap_content"
android:src="@drawable/ic_arrow_right_white_24dp"
app:tint="?attr/colorOnSurface"
android:importantForAccessibility="no"
tools:targetApi="jelly_bean" />
android:importantForAccessibility="no" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>

View File

@@ -17,10 +17,12 @@
You should have received a copy of the GNU General Public License
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:layout_alignParentBottom="true"
android:paddingTop="4dp"
android:paddingBottom="8dp"

View File

@@ -105,7 +105,7 @@
<string name="education_field_copy_title">انسخ حقل</string>
<string name="education_lock_title">اقفل قاعدة البيانات</string>
<string name="feedback">أرسل انطباعاتك</string>
<string name="about_description">\"KeePassDX\" هو تطبيق أندرويد لمدير كلمات السر كي باس \"KeePass\"</string>
<string name="about_description">تطبيق أندرويد لمدير كلمات السر KeePass.</string>
<string name="add_entry">أضف مدخل</string>
<string name="edit_entry">عدّل مدخل</string>
<string name="key_derivation_function">وظيفة اشتقاق المفتاح</string>
@@ -213,8 +213,6 @@
<string name="keyboard_key_vibrate_title">إهتزاز عند اللمس</string>
<string name="keyboard_key_sound_title">صوت عند اللمس</string>
<string name="allow_no_password_title">اسمح بدون المفتاح الرئيسي</string>
<string name="enable_read_only_title">محمي من التعديل</string>
<string name="enable_read_only_summary">افتح قاعدة البيانات في وضع القراءة افتراضيا</string>
<string name="enable_education_screens_title">تلميحات تعليمية</string>
<string name="reset_education_screens_summary">أعد عرض كل المعلومات التعليمية</string>
<string name="reset_education_screens_text">إعادة تعيين الشاشات التلميحات</string>

View File

@@ -349,7 +349,6 @@
<string name="autofill_save_search_info_title">Axtarış məlumatlarını yadda saxla</string>
<string name="autofill_inline_suggestions_keyboard">Avtomatik doldurma təklifləri əlavə edildi.</string>
<string name="allow_no_password_title">Ana açar olmamasına icazə ver</string>
<string name="enable_read_only_summary">Məlumat bazasını standart olaraq yazma-qorumalı (dəyişməz) aç</string>
<string name="enable_auto_save_database_title">Məlumat bazasını avtomatik olaraq yadda saxla</string>
<string name="reset_education_screens_summary">Bütün təlim məlumatlarını yenidən göstər</string>
<string name="reset_education_screens_text">Təlim ipuclarını sıfırlamaq</string>
@@ -572,7 +571,6 @@
<string name="allow_no_password_summary">Əgər şəxsiyyəti təsdiq edən məlumatlar seçilməyibsə, \"Aç\" düyməsinin sıxılmasına icazə ver</string>
<string name="delete_entered_password_title">Şifrəni sil</string>
<string name="delete_entered_password_summary">Məlumat bazasına bağlantı cəhdindən sonra daxil edilmiş şifrəni sil</string>
<string name="enable_read_only_title">Yazma qorumalı</string>
<string name="enable_auto_save_database_summary">Hər önəmli prossesdən sonra məlumat bazasını yadda saxla (\"Modifikasiya edilə bilən\" modda keçərlidir)</string>
<string name="enable_keep_screen_on_title">Ekranııq saxla</string>
<string name="enable_keep_screen_on_summary">Şifrəyə baxarkən və ya redaktə edərkən ekranııq saxla</string>

View File

@@ -0,0 +1,667 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="contact">Кантакт</string>
<string name="info">Iнфа</string>
<string name="contribution">Унёсак</string>
<string name="feedback">Зваротная сувязь</string>
<string name="homepage">Хатняя старонка</string>
<string name="about_description">Android рэалізацыя мэнэджара пароляў KeePass.</string>
<string name="accept">Прыняць</string>
<string name="add_entry">Дадаць запіс</string>
<string name="edit_entry">Рэдагаваць запіс</string>
<string name="add_group">Дадаць групу</string>
<string name="master_key">Галоўны ключ</string>
<string name="security">Бяспека</string>
<string name="encryption">Шыфраванне</string>
<string name="encryption_algorithm">Алгарытм шыфравання</string>
<string name="key_derivation_function">Функцыя вывядзення ключа</string>
<string name="app_timeout">Тайм-аўт</string>
<string name="app_timeout_summary">Час бяздзейнасці перад блакаваннем базы дадзеных</string>
<string name="application">Праграма</string>
<string name="extended_ASCII">Пашыраны ASCII</string>
<string name="file_manager_install_description">Каб ствараць, адкрываць і захоўваць файлы базы дадзеных, патрабуецца файлавы мэнэджар, які прымае дзеянні ACTION_CREATE_DOCUMENT і ACTION_OPEN_DOCUMENT.</string>
<string name="allow">Дазволіць</string>
<string name="clipboard_cleared">Буфер абмену ачышчаны</string>
<string name="clipboard_error_title">Памылка буфера абмену</string>
<string name="clipboard_error">Некаторыя прылады не дазваляюць праграмам выкарыстоўваць буфер абмену.</string>
<string name="clipboard_error_clear">Не ўдалося ачысціць буфер абмену</string>
<string name="clipboard_timeout">Тайм-аўт буфера абмену</string>
<string name="clipboard_timeout_summary">Працягласць захоўвання ў буферы абмену (калі падтрымліваецца прыладай)</string>
<string name="content_description_open_file">Адкрыць файл</string>
<string name="content_description_add_node">Дадаць вузел</string>
<string name="content_description_add_entry">Дадаць запіс</string>
<string name="content_description_add_group">Дадаць групу</string>
<string name="content_description_add_item">Дадаць элемент</string>
<string name="content_description_file_information">Інфармацыя пра файл</string>
<string name="content_description_credentials_information">Інфармацыя пра ўліковыя дадзеныя</string>
<string name="content_description_otp_information">Інфармацыя пра аднаразовы пароль</string>
<string name="brackets">Дужкі</string>
<string name="content_description_background">Фон</string>
<string name="content_description_node_children">Даччыныя вузлы</string>
<string name="content_description_password_checkbox">Сцяжок пароля</string>
<string name="content_description_keyfile_checkbox">Сцяжок файла ключа</string>
<string name="content_description_hardware_key_checkbox">Сцяжок апаратнага ключа</string>
<string name="content_description_repeat_toggle_password_visibility">Паўтарыць пераключэнне бачнасці пароля</string>
<string name="content_description_entry_icon">Значок запісу</string>
<string name="content_description_database_color">Колер базы дадзеных</string>
<string name="content_description_entry_foreground_color">Колер пярэдняга плану запісу</string>
<string name="content_description_entry_background_color">Колер фону запісу</string>
<string name="content_description_nav_header">Загаловак навігацыі</string>
<string name="navigation_drawer_open">Навігацыйны скрыню адкрыты</string>
<string name="navigation_drawer_close">Навігацыйны скрыню зачынены</string>
<string name="validate">Праверыць</string>
<string name="discard_changes">Адхіліць змены?</string>
<string name="discard">Адхіліць</string>
<string name="entry_password_generator">Генератар пароляў</string>
<string name="content_description_password_length">Даўжыня пароля</string>
<string name="content_description_passphrase_word_count">Колькасць слоў парольнай фразы</string>
<string name="entry_add_field">Дадаць поле</string>
<string name="entry_add_attachment">Дадаць укладанне</string>
<string name="content_description_remove_field">Выдаліць поле</string>
<string name="content_description_update_from_list">Абнавіць</string>
<string name="content_description_remove_from_list">Сцерці</string>
<string name="content_description_keyboard_close_fields">Закрыць палі</string>
<string name="select_to_copy">Выберыце, каб скапіяваць %1$s у буфер абмену</string>
<string name="retrieving_db_key">Атрыманне ключа базы дадзеных…</string>
<string name="waiting_challenge_request">Чаканне запыту выкліку…</string>
<string name="waiting_challenge_response">Чаканне адказу на выклік…</string>
<string name="database">База дадзеных</string>
<string name="template_group_name">Шаблоны</string>
<string name="decrypting_db">Расшыфроўка змесціва базы дадзеных…</string>
<string name="default_checkbox">Выкарыстоўваць як базу дадзеных па змаўчанні</string>
<string name="digits">Лічбы</string>
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft з\'яўляецца &lt;strong&gt;праграмай з адкрытым зыходным кодам&lt;/strong&gt; і &lt;strong&gt;без рэкламы&lt;/strong&gt;. \nПрадастаўляецца «як ёсць», па ліцэнзіі &lt;strong&gt;GPLv3&lt;/strong&gt;, без якіх-небудзь гарантый.</string>
<string name="html_about_privacy">&lt;strong&gt;Карыстальніцкія дадзеныя не атрымліваюцца&lt;/strong&gt;, гэтая праграма не падключаецца да сервераў, працуе толькі лакальна і цалкам паважае прыватнасць карыстальнікаў.</string>
<string name="html_about_contribution">Каб &lt;strong&gt;захаваць нашу свабоду&lt;/strong&gt;, &lt;strong&gt;выпраўляць памылкі&lt;/strong&gt;, &lt;strong&gt;дадаваць функцыі&lt;/strong&gt; і &lt;strong&gt;заўсёды быць актыўнымі&lt;/strong&gt;, мы разлічваем на ваш &lt;strong&gt;уклад&lt;/strong&gt;.</string>
<string name="entry_accessed">Доступ</string>
<string name="entry_cancel">Адмена</string>
<string name="entry_notes">Заўвагі</string>
<string name="entry_confpassword">Пацвердзіць пароль</string>
<string name="entry_created">Створаны</string>
<string name="entry_expires">Тэрмін дзеяння</string>
<string name="expired">Скончыўся</string>
<string name="entry_UUID">UUID</string>
<string name="entry_history">Гісторыя</string>
<string name="entry_attachments">Укладанні</string>
<string name="entry_keyfile">Файл ключа</string>
<string name="hardware_key">Апаратны ключ</string>
<string name="entry_modified">Зменены</string>
<string name="searchable">Магчымасць пошуку</string>
<string name="inherited">Успадкаваць</string>
<string name="auto_type">Аўта-ўвод</string>
<string name="auto_type_sequence">Паслядоўнасць аўта-ўводу</string>
<string name="entry_not_found">Не ўдалося знайсці дадзеныя запісу.</string>
<string name="entry_password">Пароль</string>
<string name="tags">Тэгі</string>
<string name="custom_data">Карыстальніцкія дадзеныя</string>
<string name="save">Захаваць</string>
<string name="entry_title">Назва</string>
<string name="entry_setup_otp">Наладзіць аднаразовы пароль</string>
<string name="otp_type">Тып OTP</string>
<string name="otp_secret">Сакрэт</string>
<string name="otp_period">Перыяд (секунды)</string>
<string name="otp_counter">Лічыльнік</string>
<string name="otp_digits">Лічбы</string>
<string name="search_filters">Фільтры пошуку</string>
<string name="otp_algorithm">Алгарытм</string>
<string name="current_group">Цяперашняя група</string>
<string name="case_sensitive">З улікам рэгістра</string>
<string name="regex">Рэгулярны выраз</string>
<string name="debit_credit_card">Дэбетавая / Крэдытная карта</string>
<string name="holder">Уладальнік</string>
<string name="number">Нумар</string>
<string name="card_verification_value">CVV</string>
<string name="personal_identification_number">PIN</string>
<string name="id_card">Пасведчанне асобы</string>
<string name="name">Назва</string>
<string name="place_of_issue">Месца выдачы</string>
<string name="date_of_issue">Дата выдачы</string>
<string name="email">Электронная пошта</string>
<string name="email_address">Адрас электроннай пошты</string>
<string name="wireless">Wi-Fi</string>
<string name="ssid">SSID</string>
<string name="type">Тып</string>
<string name="cryptocurrency">Крыптавалютны кашалёк</string>
<string name="token">Токен</string>
<string name="public_key">Адкрыты ключ</string>
<string name="private_key">Закрыты ключ</string>
<string name="seed">Насенне</string>
<string name="account">Рахунак</string>
<string name="bank">Банк</string>
<string name="bank_name">Назва банка</string>
<string name="bank_identifier_code">SWIFT / BIC</string>
<string name="international_bank_account_number">IBAN</string>
<string name="secure_note">Бяспечная нататка</string>
<string name="membership">Членства</string>
<string name="standard">Стандартны</string>
<string name="template">Шаблон</string>
<string name="version">Версія</string>
<string name="entry_otp">OTP</string>
<string name="entry_url">URL</string>
<string name="entry_user_name">Імя карыстальніка</string>
<string name="error_arc4">Патокавы шыфр Arcfour не падтрымліваецца.</string>
<string name="error_can_not_handle_uri">Не ўдалося апрацаваць гэты URI ў KeePassDX.</string>
<string name="error_file_not_create">Не ўдалося стварыць файл.</string>
<string name="error_invalid_db">Не ўдалося прачытаць базу дадзеных.</string>
<string name="error_invalid_path">Пераканайцеся, што шлях правільны.</string>
<string name="error_invalid_OTP">Няправільны сакрэт OTP.</string>
<string name="error_no_name">Увядзіце імя.</string>
<string name="error_word_reserved">Гэтае слова зарэзервавана і не можа быць выкарыстана.</string>
<string name="error_nokeyfile">Выберыце файл ключа.</string>
<string name="error_no_hardware_key">Выберыце апаратны ключ.</string>
<string name="error_out_of_memory">Не хапае памяці для загрузкі ўсёй базы дадзеных.</string>
<string name="error_XML_malformed">XML мае няправільны фармат.</string>
<string name="error_load_database">Не ўдалося загрузіць базу дадзеных.</string>
<string name="error_load_database_KDF_memory">Не ўдалося загрузіць ключ. Паспрабуйце знізіць Выкарыстанне памяці KDF.</string>
<string name="error_pass_gen_type">Павінен быць абраны хаця б адзін тып генерацыі пароляў.</string>
<string name="error_disallow_no_credentials">Павінен быць усталяваны хаця б адзін набор уліковых дадзеных.</string>
<string name="error_pass_match">Паролі не супадаюць.</string>
<string name="error_rounds_too_large">Колькасць цыклаў пераўтварэння занадта высокая. Устаноўка 2147483648.</string>
<string name="error_string_key">Кожны радок павінен мець назву поля.</string>
<string name="error_label_exists">Гэтая метка ўжо існуе.</string>
<string name="error_wrong_length">Увядзіце станоўчае цэлае лік у полі Даўжыня.</string>
<string name="error_autofill_enable_service">Не ўдалося ўключыць службу аўтазапаўнення.</string>
<string name="error_move_group_here">Вы не можаце перамясціць групу сюды.</string>
<string name="error_move_entry_here">Вы не можаце перамясціць запіс сюды.</string>
<string name="error_copy_entry_here">Вы не можаце скапіяваць запіс сюды.</string>
<string name="error_copy_group_here">Вы не можаце скапіяваць групу сюды.</string>
<string name="error_create_database">Немагчыма стварыць файл базы дадзеных.</string>
<string name="error_create_database_file">Немагчыма стварыць базу дадзеных з гэтым паролем і файлам ключа.</string>
<string name="error_save_database">Не ўдалося захаваць базу дадзеных.</string>
<string name="error_otp_secret_key">Сакрэтны ключ павінен быць у фармаце Base32.</string>
<string name="error_otp_secret_length">Даўжыня сакрэтнага ключа павінна быць не менш за %1$d сімвалаў.</string>
<string name="error_otp_counter">Лічыльнік павінен быць паміж %1$d і %2$d.</string>
<string name="error_otp_period">Перыяд павінен быць ад %1$d да %2$d секунд.</string>
<string name="error_otp_digits">Токен павінен утрымоўваць ад %1$d да %2$d лічбаў.</string>
<string name="error_otp_type">Існуючы тып OTP не распазнаецца гэтай формай, яго праверка можа больш не генераваць токен правільна.</string>
<string name="error_string_type">Гэты тэкст не супадае з запытаным элементам.</string>
<string name="error_registration_read_only">Захаванне новага элемента недапушчальна ў базе дадзеных, адкрытай толькі для чытання.</string>
<string name="error_field_name_already_exists">Назва поля ўжо існуе.</string>
<string name="error_database_uri_null">Немагчыма атрымаць URI базы дадзеных.</string>
<string name="error_rebuild_list">Не ўдалося правільна аднавіць спіс.</string>
<string name="error_file_to_big">Файл, які вы спрабуеце загрузіць, занадта вялікі.</string>
<string name="error_upload_file">Адбылася памылка пры загрузцы дадзеных файла.</string>
<string name="error_duplicate_file">Дадзеныя файла ўжо існуюць.</string>
<string name="error_remove_file">Адбылася памылка пры выдаленні дадзеных файла.</string>
<string name="error_start_database_action">Адбылася памылка пры выкананні дзеянняў з базай дадзеных.</string>
<string name="error_challenge_already_requested">Выклік ужо запытаны.</string>
<string name="error_response_already_provided">Адказнае дзеянне ўжо выканана.</string>
<string name="error_no_response_from_challenge">Немагчыма атрымаць адказ на выклік.</string>
<string name="error_cancel_by_user">Скасавана карыстальнікам.</string>
<string name="error_driver_required">Патрабуецца драйвер для %1$s.</string>
<string name="error_unable_merge_database_kdb">Немагчыма аб\'яднаць з файламі базы дадзеных kdb.</string>
<string name="error_location_unknown">Месцазнаходжанне базы дадзеных невядома, дзеянне з базай дадзеных не можа быць выканана.</string>
<string name="error_hardware_key_unsupported">Апаратны ключ не падтрымліваецца.</string>
<string name="error_empty_key">Ключ не можа быць пустым.</string>
<string name="field_name">Назва поля</string>
<string name="field_value">Значэнне поля</string>
<string name="file_not_found_content">Не ўдалося знайсці файл. Паспрабуйце зноў адкрыць яго з файлавага мэнэджара.</string>
<string name="corrupted_file">Пашкоджаны файл.</string>
<string name="file_browser">Файлавы мэнэджар</string>
<string name="generate_password">Стварыць пароль</string>
<string name="generate_keyfile">Стварыць файл ключа</string>
<string name="hint_conf_pass">Пацвердзіць пароль</string>
<string name="hint_generated_password">Згенераваны пароль</string>
<string name="hint_group_name">Назва групы</string>
<string name="hint_icon_name">Назва значка</string>
<string name="hint_keyfile">Файл ключа</string>
<string name="hint_length">Даўжыня</string>
<string name="hint_pass">Пароль</string>
<string name="password">Пароль</string>
<string name="passphrase">Парольная фраза</string>
<string name="invalid_credentials">Не ўдалося прачытаць уліковыя дадзеныя.</string>
<string name="invalid_algorithm">Няправільны алгарытм.</string>
<string name="invalid_db_same_uuid">%1$s з такім жа UUID %2$s ужо існуе.</string>
<string name="invalid_db_sig">Не ўдалося распазнаць фармат базы дадзеных.</string>
<string name="keyfile_is_empty">Файл ключа пусты.</string>
<string name="length">Даўжыня</string>
<string name="nodes">Вузлы</string>
<string name="hide_password_title">Схаваць паролі</string>
<string name="hide_password_summary">Маскіраваць паролі (***) па змаўчанні</string>
<string name="colorize_password_title">Размаляваць паролі</string>
<string name="colorize_password_summary">Размаляваць сімвалы пароля па тыпу</string>
<string name="list_entries_show_username_title">Паказаць імёны карыстальнікаў</string>
<string name="list_entries_show_username_summary">Адлюстроўвае імёны карыстальнікаў у спісах запісаў</string>
<string name="list_groups_show_number_entries_title">Паказаць колькасць запісаў</string>
<string name="list_groups_show_number_entries_summary">Адлюстроўвае колькасць запісаў у групе</string>
<string name="recursive_number_entries_title">Рэкурсіўная колькасць запісаў</string>
<string name="recursive_number_entries_summary">Рэкурсіўна падлічвае колькасць запісаў у групе</string>
<string name="show_otp_token_title">Паказаць токен OTP</string>
<string name="show_otp_token_summary">Адлюстроўвае токены OTP у спісе запісаў</string>
<string name="show_uuid_title">Паказаць UUID</string>
<string name="show_uuid_summary">Адлюстроўвае UUID, прывязаны да запісу або групы</string>
<string name="list_size_title">Памер элементаў спісу</string>
<string name="list_size_summary">Памер тэксту ў спісе элементаў</string>
<string name="creating_database">Стварэнне базы дадзеных…</string>
<string name="loading_database">Загрузка базы дадзеных…</string>
<string name="lowercase">Ніжні рэгістр</string>
<string name="about">Аб праграме</string>
<string name="menu_change_key_settings">Змяніць галоўны ключ</string>
<string name="copy_field">Копія %1$s</string>
<string name="settings">Налады</string>
<string name="menu_app_settings">Налады праграмы</string>
<string name="menu_app_settings_summary">Пошук, блакаванне, гісторыя, уласцівасці</string>
<string name="menu_form_filling_settings">Запаўненне формы</string>
<string name="menu_form_filling_settings_summary">Клавіятура, аўтазапаўненне, буфер абмену</string>
<string name="menu_device_unlock_settings">Разблакіроўка прылады</string>
<string name="menu_device_unlock_settings_summary">Біяметрыя, уліковыя дадзеныя прылады</string>
<string name="menu_database_settings">Налады базы дадзеных</string>
<string name="menu_database_settings_summary">Метададзеныя, смеццевая скрыня, шаблоны, гісторыя</string>
<string name="menu_security_settings">Налады бяспекі</string>
<string name="menu_security_settings_summary">Шыфраванне, функцыя вывядзення ключа</string>
<string name="menu_master_key_settings">Налады галоўнага ключа</string>
<string name="master_key_settings_summary">Змена, аднаўленне</string>
<string name="menu_donate">Ахвяраваць</string>
<string name="menu_edit">Рэдагаваць</string>
<string name="menu_copy">Капіяваць</string>
<string name="menu_move">Перамясціць</string>
<string name="menu_paste">Уставіць</string>
<string name="menu_delete">Выдаліць</string>
<string name="menu_cancel">Адмена</string>
<string name="menu_hide_password">Схаваць пароль</string>
<string name="menu_lock">Заблакаваць базу дадзеных</string>
<string name="menu_save_database">Захаваць дадзеныя</string>
<string name="menu_merge_database">Аб\'яднаць дадзеныя</string>
<string name="menu_reload_database">Перазагрузіць дадзеныя</string>
<string name="menu_merge_from">Аб\'яднаць з…</string>
<string name="menu_save_copy_to">Захаваць копію ў…</string>
<string name="menu_open">Адкрыць</string>
<string name="menu_search">Пошук</string>
<string name="menu_showpass">Паказаць пароль</string>
<string name="menu_keystore_remove_key">Выдаліць ключ разблакіроўкі прылады</string>
<string name="menu_url">Перайсці па URL</string>
<string name="menu_file_selection_read_only">Абаронены ад запісу</string>
<string name="menu_open_file_read_and_write">З магчымасцю змены</string>
<string name="menu_empty_recycle_bin">Ачысціць смеццевую скрыню</string>
<string name="menu_restore_entry_history">Аднавіць гісторыю</string>
<string name="menu_delete_entry_history">Выдаліць гісторыю</string>
<string name="menu_external_icon">Знешні значок</string>
<string name="minus">Мінус</string>
<string name="never">Ніколі</string>
<string name="no_results">Няма вынікаў пошуку</string>
<string name="no_url_handler">Усталюйце вэб-браўзер, каб адкрыць гэты URL.</string>
<string name="select_database_file">Адкрыць існуючае сховішча</string>
<string name="create_keepass_file">Стварыць новае сховішча</string>
<string name="auto_focus_search_title">Хуткі пошук</string>
<string name="auto_focus_search_summary">Запытаць пошук пры адкрыцці базы дадзеных</string>
<string name="subdomain_search_title">Пошук па паддаменах</string>
<string name="subdomain_search_summary">Пошук вэб-даменаў з абмежаваннямі паддаменаў</string>
<string name="progress_create">Стварэнне новай базы дадзеных…</string>
<string name="progress_title">Працую…</string>
<string name="protection">Абарона</string>
<string name="read_only">Абаронены ад запісу</string>
<string name="read_only_warning">У залежнасці ад вашага файлавага мэнэджара, KeePassDX можа не мець дазволу на запіс у сховішча.</string>
<string name="contains_duplicate_uuid">База дадзеных змяшчае дублікаты UUID.</string>
<string name="contains_duplicate_uuid_procedure">Вырашыць праблему шляхам генерацыі новых UUID для дублікатаў, каб працягнуць?</string>
<string name="search_mode">Рэжым пошуку</string>
<string name="save_mode">Рэжым захавання</string>
<string name="selection_mode">Рэжым выбару</string>
<string name="registration_mode">Рэжым рэгістрацыі</string>
<string name="remember_database_locations_title">Запамінаць размяшчэнне баз дадзеных</string>
<string name="remember_database_locations_summary">Адсочвае, дзе захоўваюцца базы дадзеных</string>
<string name="remember_keyfile_locations_title">Запамінаць размяшчэнне файлаў ключоў</string>
<string name="remember_keyfile_locations_summary">Адсочвае, дзе захоўваюцца файлы ключоў</string>
<string name="remember_hardware_key_title">Запамінаць апаратныя ключы</string>
<string name="remember_hardware_key_summary">Адсочвае выкарыстаныя апаратныя ключы</string>
<string name="show_recent_files_title">Паказваць апошнія файлы</string>
<string name="show_recent_files_summary">Паказваць размяшчэнне нядаўніх баз дадзеных</string>
<string name="hide_broken_locations_title">Схаваць зламаныя спасылкі на базы дадзеных</string>
<string name="hide_broken_locations_summary">Схаваць зламаныя спасылкі ў спісе нядаўніх баз дадзеных</string>
<string name="import_app_properties_title">Імпартаваць налады праграмы</string>
<string name="import_app_properties_summary">Выберыце файл для імпарту налад праграмы</string>
<string name="export_app_properties_title">Экспартаваць налады праграмы</string>
<string name="export_app_properties_summary">Стварыць файл для экспарту налад праграмы</string>
<string name="description_app_properties">Уласцівасці KeePassDX для кіравання наладамі праграмы</string>
<string name="success_import_app_properties">Налады праграмы імпартаваны</string>
<string name="error_import_app_properties">Памылка падчас імпарту налад праграмы.</string>
<string name="success_export_app_properties">Налады праграмы экспартаваны</string>
<string name="error_export_app_properties">Памылка падчас экспарту налад праграмы.</string>
<string name="root">Корань</string>
<string name="encryption_explanation">Алгарытм шыфравання базы дадзеных, які выкарыстоўваецца для ўсіх дадзеных</string>
<string name="kdf_explanation">Каб стварыць ключ для алгарытму шыфравання, галоўны ключ пераўтворыцца з дапамогай выпадкова саленай функцыі вывядзення ключа.</string>
<string name="rounds">Цыклы пераўтварэння</string>
<string name="rounds_explanation">Дадатковыя цыклы шыфравання забяспечваюць больш высокую абарону ад нападаў грубай сілы, але могуць моцна запаволіць загрузку і захаванне.</string>
<string name="memory_usage">Выкарыстанне памяці</string>
<string name="memory_usage_explanation">Аб\'ём памяці, які будзе выкарыстоўвацца функцыяй вывядзення ключа.</string>
<string name="parallelism">Паралелізм</string>
<string name="parallelism_explanation">Ступень паралелізму (г.зн. колькасць патокаў), выкарыстоўваных функцыяй вывядзення ключа.</string>
<string name="saving_database">Захаванне базы дадзеных…</string>
<string name="command_execution">Выкананне каманды…</string>
<string name="do_not_kill_app">Не зачыняйце праграму…</string>
<string name="space">Прабел</string>
<string name="filter">Фільтр</string>
<string name="sort_menu">Сартаваць</string>
<string name="sort_ascending">Спачатку ніжэйшыя ↓</string>
<string name="sort_groups_before">Групы спачатку</string>
<string name="sort_recycle_bin_bottom">Смеццевая скрыня ўнізе</string>
<string name="sort_db">Натуральны парадак</string>
<string name="sort_title">Назва</string>
<string name="sort_username">Імя карыстальніка</string>
<string name="sort_creation_time">Стварэнне</string>
<string name="sort_last_modify_time">Змена</string>
<string name="sort_last_access_time">Доступ</string>
<string name="special">Спецыяльныя</string>
<string name="search">Пошук</string>
<string name="underline">Падкрэсліванне</string>
<string name="unsupported_db_version">Непадтрымліваемая версія базы дадзеных.</string>
<string name="uppercase">ВЕРХНІ РЭГІСТР</string>
<string name="warning">Папярэджанне</string>
<string name="warning_password_encoding">Пазбягайце сімвалаў пароляў па-за межамі фармату кадоўкі тэксту ў файле базы дадзеных (нераспазнаныя сімвалы пераўтвараюцца ў адну і тую ж літару).</string>
<string name="warning_database_read_only">Дайце дазвол на запіс у файл, каб захаваць змены ў базе дадзеных</string>
<string name="warning_database_link_revoked">Доступ да файла скасаваны файлавым мэнэджарам</string>
<string name="warning_database_already_opened">База дадзеных ужо адкрыта, спачатку зачыніце яе, каб адкрыць новую</string>
<string name="warning_empty_password">Працягнуць без абароны блакаваннем паролем?</string>
<string name="warning_no_encryption_key">Працягнуць без ключа шыфравання?</string>
<string name="warning_permanently_delete_nodes">Беззваротна выдаліць выбраныя вузлы?</string>
<string name="warning_empty_recycle_bin">Беззваротна выдаліць усе вузлы са смеццевай скрыні?</string>
<string name="warning_file_too_big">База дадзеных KeePass павінна ўтрымліваць толькі невялікія службовыя файлы (напрыклад, файлы PGP-ключа).\n\nВаша база дадзеных можа стаць вельмі вялікай і знізіць прадукцыйнасць пасля гэтай загрузкі.</string>
<string name="warning_replace_file">Загрузка гэтага файла заменіць існуючы.</string>
<string name="warning_sure_add_file">Усё роўна дадаць файл?</string>
<string name="warning_remove_unlinked_attachment">Выдаленне незвязаных дадзеных можа паменшыць памер вашай базы дадзеных, але таксама можа выдаліць дадзеныя, якія выкарыстоўваюцца для плагінаў KeePass.</string>
<string name="warning_sure_remove_data">Усё роўна выдаліць гэтыя дадзеныя?</string>
<string name="warning_empty_keyfile">Не рэкамендуецца дадаваць пусты файл ключа.</string>
<string name="warning_large_keyfile">Не рэкамендуецца дадаваць вялікі файл ключа, гэта можа перашкодзіць адкрыццю базы дадзеных.</string>
<string name="warning_empty_keyfile_explanation">Змесціва файла ключа ніколі не павінна змяняцца, і ў лепшым выпадку, павінна ўтрымліваць выпадкова згенераваныя дадзеныя.</string>
<string name="warning_database_info_changed">Інфармацыя, якая змяшчаецца ў файле базы дадзеных, была зменена па-за межамі праграмы.</string>
<string name="warning_database_info_changed_options">Аб\'яднаць дадзеныя, захаваць базу дадзеных з перазапісам знешніх мадыфікацый або перазагрузіць яе з апошнімі зменамі.</string>
<string name="warning_database_info_changed_options_read_only">Перазагрузіць базу дадзеных з апошнімі зменамі.</string>
<string name="warning_database_info_reloaded">Перазагрузка базы дадзеных выдаліць лакальна змененыя дадзеныя.</string>
<string name="warning_database_revoked">Доступ да файла скасаваны файлавым мэнэджарам, зачыніце базу дадзеных і зноў адкрыйце яе з яе месцазнаходжання.</string>
<string name="warning_exact_alarm">Вы не дазволілі праграме выкарыстоўваць дакладны таймер. У выніку функцыі, якія патрабуюць таймера, не будуць выкананы з дакладным часам.</string>
<string name="warning_keyfile_integrity">Цэласнасць файла не гарантуецца, бо Android можа змяняць яго дадзеныя на хаду. Зменіце пашырэнне файла на .bin для правільнай цэласнасці.</string>
<string name="warning_database_notification_permission">Дазвол на апавяшчэнні дазваляе адлюстроўваць статус базы дадзеных і блакаваць яе з дапамогай лёгкадаступнай кнопкі.\n\nКалі вы не актывуеце гэты дазвол, база дадзеных, адкрытая ў фонавым рэжыме, не будзе бачная, калі на пярэднім плане знаходзіцца іншая праграма.</string>
<string name="warning_copy_permission">Дазвол на апавяшчэнні неабходны для выкарыстання функцыі апавяшчэння аб буферы абмену.</string>
<string name="later">Пазней</string>
<string name="ask">Спытаць</string>
<string name="merge_success">Аб\'яднанне паспяхова завершана</string>
<string name="permission">Дазвол</string>
<string name="version_label">Версія %1$s</string>
<string name="build_label">Зборка %1$s</string>
<string name="configure">Наладзіць</string>
<string name="configure_biometric">Біяметрычныя або ўліковыя дадзеныя прылады не зарэгістраваны.</string>
<string name="biometric_security_update_required">Патрабуецца абнаўленне біяметрычнай бяспекі.</string>
<string name="keystore_not_accessible">Сховішча ключоў неналежным чынам ініцыялізавана.</string>
<string name="unlock_and_link_biometric">Спасылка на разблакіроўку прылады</string>
<string name="device_unlock_prompt_store_credential_title">Спасылка на разблакіроўку прылады</string>
<string name="device_unlock_prompt_store_credential_message">Вам усё роўна трэба памятаць асноўныя ўліковыя дадзеныя сховішча, калі вы выкарыстоўваеце распазнаванне разблакіроўкі прылады.</string>
<string name="device_unlock_prompt_extract_credential_title">Распазнаванне разблакіроўкі прылады</string>
<string name="device_unlock_prompt_extract_credential_message">Выняць уліковыя дадзеныя базы дадзеных з дапамогай дадзеных разблакіроўкі прылады</string>
<string name="encrypted_value_stored">Зашыфраваны пароль захаваны</string>
<string name="device_unlock_invalid_key">Немагчыма прачытаць ключ разблакіроўкі прылады. Выдаліце яго і паўтарыце працэдуру распазнавання разблакіроўкі.</string>
<string name="device_unlock_not_recognized">Не ўдалося распазнаць адбітак разблакіроўкі прылады</string>
<string name="unavailable">Недаступна</string>
<string name="device_unlock_prompt_not_initialized">Немагчыма ініцыялізаваць запыт разблакіроўкі прылады.</string>
<string name="credential_before_click_device_unlock_button">Увядзіце пароль, а затым націсніце гэтую кнопку.</string>
<string name="database_history">Гісторыя</string>
<string name="properties">Уласцівасці</string>
<string name="menu_appearance_settings">Знешні выгляд</string>
<string name="menu_appearance_settings_summary">Тэмы, колеры, атрыбуты</string>
<string name="biometric">Біяметрычны</string>
<string name="device_credential">Уліковыя дадзеныя прылады</string>
<string name="general">Агульнае</string>
<string name="autofill">Аўтазапаўненне</string>
<string name="autofill_service_name">Аўтазапаўненне формы KeePassDX</string>
<string name="autofill_sign_in_prompt">Увайсці з дапамогай KeePassDX</string>
<string name="autofill_explanation_summary">Уключыце аўтазапаўненне, каб хутка запаўняць формы ў іншых праграмах</string>
<string name="autofill_select_entry">Выбраць запіс…</string>
<string name="set_autofill_service_title">Усталяваць службу аўтазапаўнення па змаўчанні</string>
<string name="autofill_preference_title">Налады аўтазапаўнення</string>
<string name="password_size_title">Памер згенераванага пароля</string>
<string name="password_size_summary">Усталёўвае памер згенераваных пароляў па змаўчанні</string>
<string name="list_password_generator_options_title">Сімвалы пароля</string>
<string name="list_password_generator_options_summary">Усталяваць дазволеныя сімвалы генератара пароляў</string>
<string name="database_opened">База дадзеных адкрыта</string>
<string name="clipboard">Буфер абмену</string>
<string name="clipboard_explanation_summary">Капіюйце палі запісу, выкарыстоўваючы буфер абмену вашай прылады</string>
<string name="clipboard_notifications_title">Апавяшчэнні буфера абмену</string>
<string name="clipboard_notifications_summary">Паказваць апавяшчэнні буфера абмену, каб капіяваць палі пры праглядзе запісу</string>
<string name="clipboard_warning">Калі аўтаматычнае выдаленне з буфера абмену не ўдаецца, выдаліце яго гісторыю ўручную.</string>
<string name="lock">Блакаванне</string>
<string name="lock_database_screen_off_title">Блакаванне экрана</string>
<string name="lock_database_screen_off_summary">Блакаваць базу дадзеных праз некалькі секунд пасля выключэння экрана</string>
<string name="lock_database_back_root_title">Націснуць «Назад», каб заблакаваць</string>
<string name="lock_database_back_root_summary">Блакаваць базу дадзеных, калі карыстальнік націскае кнопку «Назад» на галоўным экране</string>
<string name="lock_database_show_button_title">Паказаць кнопку блакавання</string>
<string name="lock_database_show_button_summary">Адлюстроўвае кнопку блакавання ў карыстальніцкім інтэрфейсе</string>
<string name="content">Змесціва</string>
<string name="unlock">Разблакіраваць</string>
<string name="device_unlock">Разблакіроўка прылады</string>
<string name="device_unlock_tap_delete">Націсніце, каб выдаліць ключы разблакіроўкі прылады</string>
<string name="device_unlock_explanation_summary">Выкарыстоўвайце разблакіроўку прылады, каб лягчэй адкрываць базу дадзеных</string>
<string name="biometric_unlock_enable_title">Біяметрычная разблакіроўка</string>
<string name="biometric_unlock_enable_summary">Дазваляе сканаваць біяметрыю для адкрыцця базы дадзеных</string>
<string name="device_credential_unlock_enable_title">Разблакіроўка з дапамогай уліковых дадзеных прылады</string>
<string name="device_credential_unlock_enable_summary">Дазваляе выкарыстоўваць уліковыя дадзеныя прылады для адкрыцця базы дадзеных</string>
<string name="biometric_auto_open_prompt_title">Запыт на аўтаматычнае адкрыццё</string>
<string name="biometric_auto_open_prompt_summary">Аўтаматычна запытваць разблакіроўку прылады, калі база дадзеных наладжана на яе выкарыстанне</string>
<string name="temp_device_unlock_enable_title">Часовая разблакіроўка прылады</string>
<string name="temp_device_unlock_enable_summary">Не захоўваць зашыфраванае змесціва для выкарыстання разблакіроўкі прылады</string>
<string name="temp_device_unlock_timeout_title">Тэрмін дзеяння разблакіроўкі прылады</string>
<string name="temp_device_unlock_timeout_summary">Працягласць выкарыстання разблакіроўкі прылады перад выдаленнем яе змесціва</string>
<string name="device_unlock_timeout">Тайм-аўт разблакіроўкі прылады</string>
<string name="biometric_delete_all_key_title">Выдаліць ключы шыфравання</string>
<string name="biometric_delete_all_key_summary">Выдаліць усе ключы шыфравання, звязаныя з распазнаваннем разблакіроўкі прылады</string>
<string name="device_unlock_delete_all_key_warning">Выдаліць усе ключы шыфравання, звязаныя з распазнаваннем разблакіроўкі прылады?</string>
<string name="device_unlock_keystore_warning">Гэтая функцыя будзе захоўваць зашыфраваныя дадзеныя ўліковых дадзеных у бяспечным Keystore вашай прылады.\n\nУ залежнасці ад рэалізацыі натыўнага API аперацыйнай сістэмы, яна можа быць не цалкам функцыянальнай.\n\nПраверце сумяшчальнасць і бяспеку Keystore з вытворцам вашай прылады і стваральнікам ПЗ, якое вы выкарыстоўваеце.</string>
<string name="unavailable_feature_text">Не ўдалося запусціць гэтую функцыю.</string>
<string name="unavailable_feature_version">Прылада працуе на Android %1$s, але патрабуецца %2$s або больш позняя версія.</string>
<string name="unavailable_feature_hardware">Не ўдалося знайсці адпаведнае апаратнае забеспячэнне.</string>
<string name="file_name">Імя файла</string>
<string name="path">Шлях</string>
<string name="assign_master_key">Прызначыць галоўны ключ</string>
<string name="data">Дадзеныя</string>
<string name="database_data_compression_title">Сцісканне дадзеных</string>
<string name="database_data_compression_summary">Сцісканне дадзеных памяншае памер базы дадзеных</string>
<string name="database_data_remove_unlinked_attachments_title">Выдаліць незвязаныя дадзеныя</string>
<string name="database_data_remove_unlinked_attachments_summary">Выдаляе ўкладанні, якія змяшчаюцца ў базе дадзеных, але не звязаны з запісам</string>
<string name="recycle_bin_title">Выкарыстанне смеццевай скрыні</string>
<string name="recycle_bin_summary">Перамяшчае групы і запісы ў групу Смеццевая скрыня перад выдаленнем</string>
<string name="recycle_bin_group_title">Група смеццевай скрыні</string>
<string name="templates_group_enable_title">Выкарыстанне шаблонаў</string>
<string name="templates_group_enable_summary">Выкарыстоўвайце дынамічныя шаблоны для запаўнення палёў запісу</string>
<string name="templates_group_uuid_title">Група шаблонаў</string>
<string name="max_history_items_title">Максімальная колькасць</string>
<string name="max_history_items_summary">Абмежаваць колькасць элементаў гісторыі на запіс</string>
<string name="max_history_size_title">Максімальны памер</string>
<string name="max_history_size_summary">Абмежаваць памер гісторыі на запіс</string>
<string name="settings_database_recommend_changing_master_key_title">Рэкамендаваць абнаўленне</string>
<string name="settings_database_recommend_changing_master_key_summary">Рэкамендаваць змену галоўнага ключа (дні)</string>
<string name="settings_database_force_changing_master_key_title">Прымусовае абнаўленне</string>
<string name="settings_database_force_changing_master_key_summary">Патрабаваць змены галоўнага ключа (дні)</string>
<string name="settings_database_force_changing_master_key_next_time_title">Прымусовае абнаўленне наступным разам</string>
<string name="settings_database_force_changing_master_key_next_time_summary">Патрабаваць змены галоўнага ключа ў наступны раз (адзін раз)</string>
<string name="monospace_font_fields_enable_title">Шрыфт поля</string>
<string name="monospace_font_fields_enable_summary">Змяніць шрыфт, які выкарыстоўваецца ў палях, для лепшай бачнасці сімвалаў</string>
<string name="allow_copy_password_title">Давер буфера абмену</string>
<string name="allow_copy_password_summary">Дазволіць капіяванне пароля запісу і абароненых палёў у буфер абмену</string>
<string name="allow_copy_password_warning">Папярэджанне: Буфер абмену выкарыстоўваецца ўсімі праграмамі. Калі капіююцца канфідэнцыйныя дадзеныя, іншае праграмнае забеспячэнне можа аднавіць іх.</string>
<string name="enable">Уключыць</string>
<string name="disable">Адключыць</string>
<string name="notification">Апавяшчэнне</string>
<string name="clear_clipboard_notification_title">Ачысціць пры закрыцці</string>
<string name="clear_clipboard_notification_summary">Блакаваць базу дадзеных пасля заканчэння тэрміну дзеяння буфера абмену або закрыцця апавяшчэння пасля пачатку выкарыстання</string>
<string name="database_name_title">Назва базы дадзеных</string>
<string name="database_description_title">Апісанне базы дадзеных</string>
<string name="database_default_username_title">Імя карыстальніка па змаўчанні</string>
<string name="database_custom_color_title">Карыстальніцкі колер базы дадзеных</string>
<string name="database_version_title">Версія базы дадзеных</string>
<string name="text_appearance">Тэкст</string>
<string name="application_appearance">Інтэрфейс</string>
<string name="other">Іншае</string>
<string name="compression">Сцісканне</string>
<string name="compression_none">Няма</string>
<string name="compression_gzip">Gzip</string>
<string name="recycle_bin">Смеццевая скрыня</string>
<string name="templates">Шаблоны</string>
<string name="keyboard">Клавіятура</string>
<string name="magic_keyboard_title">Магічная клавіятура</string>
<string name="magic_keyboard_explanation_summary">Актываваць карыстальніцкую клавіятуру, якая запаўняе вашыя паролі і ўсе палі ідэнтычнасці</string>
<string name="device_keyboard_setting_title">Налады клавіятуры прылады</string>
<string name="keyboard_name">Магічная клавіятура</string>
<string name="keyboard_label">Магічная клавіятура (KeePassDX)</string>
<string name="keyboard_setting_label">Налады магічнай клавіятуры</string>
<string name="keyboard_entry_category">Запіс</string>
<string name="keyboard_selection_entry_title">Выбар запісу</string>
<string name="keyboard_selection_entry_summary">Пры праглядзе запісу ў KeePassDX, запоўніце магічную клавіятуру гэтым запісам</string>
<string name="keyboard_notification_entry_title">Інфармацыя аб апавяшчэннях</string>
<string name="keyboard_notification_entry_summary">Паказваць апавяшчэнне, калі запіс даступны</string>
<string name="keyboard_save_search_info_title">Захаваць агульную інфармацыю</string>
<string name="keyboard_save_search_info_summary">Паспрабаваць захаваць агульную інфармацыю пры ручным выбары запісу для палягчэння будучага выкарыстання</string>
<string name="keyboard_notification_entry_clear_close_title">Ачысціць пры закрыцці</string>
<string name="keyboard_notification_entry_clear_close_summary">Зачыніць базу дадзеных пры закрыцці апавяшчэння</string>
<string name="keyboard_entry_timeout_title">Тайм-аўт</string>
<string name="keyboard_entry_timeout_summary">Тайм-аўт для ачысткі запісу клавіятуры</string>
<string name="keyboard_notification_entry_content_title_text">Запіс</string>
<string name="keyboard_notification_entry_content_title">%1$s даступны на магічнай клавіятуры</string>
<string name="keyboard_notification_entry_content_text">%1$s</string>
<string name="keyboard_appearance_category">Знешні выгляд</string>
<string name="keyboard_theme_title">Тэма клавіятуры</string>
<string name="keyboard_keys_category">Клавішы</string>
<string name="keyboard_auto_go_action_title">Аўтаматычнае дзеянне клавішы</string>
<string name="keyboard_auto_go_action_summary">Дзеянне клавішы Go пасля націску на клавішу Поле</string>
<string name="keyboard_key_vibrate_title">Вібрацыйныя націскі клавіш</string>
<string name="keyboard_key_sound_title">Гукавыя націскі клавіш</string>
<string name="keyboard_change">Змяніць клавіятуру</string>
<string name="keyboard_previous_database_credentials_title">Экран уліковых дадзеных базы дадзеных</string>
<string name="keyboard_previous_database_credentials_summary">Аўтаматычна пераключацца назад на папярэднюю клавіятуру на экране ўліковых дадзеных базы дадзеных</string>
<string name="keyboard_previous_search_title">Экран пошуку</string>
<string name="keyboard_previous_search_summary">Аўтаматычна пераключацца назад на папярэднюю клавіятуру на экране пошуку</string>
<string name="keyboard_previous_fill_in_title">Пераключыцца назад</string>
<string name="keyboard_previous_fill_in_summary">Аўтаматычна пераключацца назад на папярэднюю клавіятуру пасля выканання Аўтаматычнага дзеяння клавішы</string>
<string name="keyboard_previous_lock_title">Заблакаваць базу дадзеных</string>
<string name="keyboard_previous_lock_summary">Аўтаматычна пераключацца назад на папярэднюю клавіятуру пасля блакавання базы дадзеных</string>
<string name="custom_fields">Карыстальніцкія палі</string>
<string name="back_to_previous_keyboard">Вярнуцца да папярэдняй клавіятуры</string>
<string name="select_entry">Выбраць запіс</string>
<string name="backspace">Backspace</string>
<string name="enter">Enter</string>
<string name="autofill_close_database_title">Зачыніць базу дадзеных</string>
<string name="autofill_close_database_summary">Зачыніць базу дадзеных пасля выбару аўтазапаўнення</string>
<string name="autofill_inline_suggestions_title">Убудаваныя прапановы</string>
<string name="autofill_inline_suggestions_summary">Спрабаваць адлюстраваць прапановы аўтазапаўнення непасрэдна з сумяшчальнай клавіятуры</string>
<string name="autofill_manual_selection_title">Ручной выбар</string>
<string name="autofill_manual_selection_summary">Адлюстраваць опцыю, каб дазволіць карыстальніку выбраць запіс базы дадзеных</string>
<string name="autofill_save_search_info_title">Захаваць інфармацыю пошуку</string>
<string name="autofill_save_search_info_summary">Спрабаваць захаваць інфармацыю пошуку пры ручным выбары запісу для палягчэння будучага выкарыстання</string>
<string name="autofill_ask_to_save_data_title">Спытаць пра захаванне дадзеных</string>
<string name="autofill_ask_to_save_data_summary">Спытаць пра захаванне дадзеных пасля завяршэння запаўнення формы</string>
<string name="autofill_application_id_blocklist_title">Чорны спіс праграм</string>
<string name="autofill_application_id_blocklist_summary">Чорны спіс, які перашкаджае аўтазапаўненню праграм</string>
<string name="autofill_web_domain_blocklist_title">Чорны спіс вэб-даменаў</string>
<string name="autofill_web_domain_blocklist_summary">Чорны спіс, які перашкаджае аўтазапаўненню вэб-даменаў</string>
<string name="autofill_block">Заблакаваць аўтазапаўненне</string>
<string name="autofill_block_restart">Перазапусціце праграму, якая змяшчае форму, каб актываваць блакаванне.</string>
<string name="autofill_read_only_save">Захаванне дадзеных недапушчальна для базы дадзеных, адкрытай толькі для чытання.</string>
<string name="autofill_inline_suggestions_keyboard">Прапановы аўтазапаўнення дададзены.</string>
<string name="allow_no_password_title">Дазволіць без галоўнага ключа</string>
<string name="allow_no_password_summary">Дазваляе націснуць кнопку Адкрыць, калі не выбраны ўліковыя дадзеныя</string>
<string name="delete_entered_password_title">Выдаліць пароль</string>
<string name="delete_entered_password_summary">Выдаляе ўведзены пароль пасля спробы падключэння да базы дадзеных</string>
<string name="enable_auto_save_database_title">Аўтазахаванне базы дадзеных</string>
<string name="enable_auto_save_database_summary">Захоўваць базу дадзеных пасля кожнага важнага дзеяння (у рэжыме З магчымасцю змены)</string>
<string name="enable_keep_screen_on_title">Трымаць экран уключаным</string>
<string name="enable_keep_screen_on_summary">Трымаць экран уключаным пры праглядзе або рэдагаванні запісу</string>
<string name="enable_screenshot_mode_title">Рэжым скрыншота</string>
<string name="enable_screenshot_mode_summary">Дазволіць староннім праграмам запісваць або рабіць скрыншоты праграмы</string>
<string name="enable_education_screens_title">Навучальныя падказкі</string>
<string name="enable_education_screens_summary">Вылучыць элементы, каб даведацца, як працуе праграма</string>
<string name="reset_education_screens_title">Скінуць навучальныя падказкі</string>
<string name="reset_education_screens_summary">Паказаць усю навучальную інфармацыю зноўку</string>
<string name="reset_education_screens_text">Навучальныя падказкі скінуты</string>
<string name="education_create_database_title">Стварыце свой файл базы дадзеных</string>
<string name="education_create_database_summary">Стварыце свой першы файл кіравання паролямі.</string>
<string name="education_select_database_title">Адкрыць існуючую базу дадзеных</string>
<string name="education_select_database_summary">Адкрыйце свой папярэдні файл базы дадзеных з файлавага браўзера, каб працягнуць выкарыстоўваць яго.</string>
<string name="education_new_node_title">Дадаць элементы ў вашу базу дадзеных</string>
<string name="education_new_node_summary">Запісы дапамагаюць кіраваць лічбавымі ідэнтыфікацыйнымі дадзенымі.\n\nГрупы (~тэчкі) арганізуюць запісы ў вашай базе дадзеных.</string>
<string name="education_search_title">Пошук па запісах</string>
<string name="education_search_summary">Увядзіце назву, імя карыстальніка або змесціва іншых палёў, каб знайсці свае паролі.</string>
<string name="education_device_unlock_title">Разблакіроўка базы дадзеных прылады</string>
<string name="education_device_unlock_summary">Прывяжыце свой пароль да адсканаванай біяметрыі або ўліковых дадзеных прылады, каб хутка разблакаваць базу дадзеных.</string>
<string name="education_entry_edit_title">Рэдагаваць гэты запіс</string>
<string name="education_entry_edit_summary">Рэдагуйце свой запіс з дапамогай карыстальніцкіх палёў. Дадзеныя пула могуць спасылацца паміж рознымі палямі запісаў.</string>
<string name="education_generate_password_title">Стварыць надзейны пароль</string>
<string name="education_generate_password_summary">Стварыце надзейны пароль, каб звязаць яго са сваім запісам, лёгка вызначыце яго ў адпаведнасці з крытэрыямі формы і не забудзьцеся пра бяспечны пароль.</string>
<string name="education_validate_entry_title">Праверыць запіс</string>
<string name="education_validate_entry_summary">Не забудзьцеся праверыць свой запіс і захаваць базу дадзеных.\n\nКалі актывавана аўтаматычнае блакаванне і вы забыліся, што рабілі змены, вы рызыкуеце страціць свае дадзеныя.</string>
<string name="education_entry_new_field_title">Дадаць карыстальніцкія палі</string>
<string name="education_entry_new_field_summary">Зарэгіструйце дадатковае поле, дадайце значэнне і пры жаданні абароніце яго.</string>
<string name="education_add_attachment_title">Дадаць укладанне</string>
<string name="education_add_attachment_summary">Загрузіце ўкладанне ў свой запіс, каб захаваць важныя знешнія дадзеныя.</string>
<string name="education_setup_OTP_title">Наладзіць OTP</string>
<string name="education_setup_OTP_summary">Наладзьце кіраванне аднаразовым паролем (HOTP / TOTP) для стварэння токена, які запытваецца для двухфактарнай аўтэнтыфікацыі (2FA).</string>
<string name="education_unlock_title">Разблакаваць вашу базу дадзеных</string>
<string name="education_unlock_summary">Увядзіце пароль і/або файл ключа, каб разблакаваць базу дадзеных.\n\nСтварыце рэзервовую копію файла базы дадзеных у бяспечным месцы пасля кожнай змены.</string>
<string name="education_read_only_title">Абараніць вашу базу дадзеных ад запісу</string>
<string name="education_read_only_summary">Змяніць рэжым адкрыцця для сеансу.\n\n\"Абаронены ад запісу\"- прадухіляе ненаўмысныя змены ў базе дадзеных.\n\"Мадыкафаны\"- дазваляе вам дадаваць, выдаляць або змяняць усе элементы, як пажадаеце.</string>
<string name="education_field_copy_title">Скапіяваць поле</string>
<string name="education_field_copy_summary">Скапіяваныя палі можна ўставіць у любым месцы.\n\nВыкарыстоўвайце метад запаўнення формы, які вам больш падабаецца.</string>
<string name="education_lock_title">Заблакаваць базу дадзеных</string>
<string name="education_lock_summary">Хутка заблакаваць базу дадзеных, вы можаце наладзіць праграму, каб яна блакавалася праз некаторы час і калі экран выключаецца.</string>
<string name="education_sort_title">Сартаванне элементаў</string>
<string name="education_sort_summary">Выберыце, як сартаваць запісы і групы.</string>
<string name="education_donation_title">Удзельнічаць</string>
<string name="education_donation_summary">Дапамажыце павысіць стабільнасць, бяспеку і дадаць больш функцый.</string>
<string name="html_text_ad_free">У адрозненне ад многіх праграм для кіравання паролямі, гэтая &lt;strong&gt;без рэкламы&lt;/strong&gt;, &lt;strong&gt;копілефтнае свабоднае праграмнае забеспячэнне&lt;/strong&gt; і не збірае персанальныя дадзеныя на сваіх серверах, незалежна ад версіі, якой вы карыстаецеся.</string>
<string name="html_text_buy_pro">Купляючы pro-версію, вы атрымаеце доступ да гэтага &lt;strong&gt;візуальнага стылю&lt;/strong&gt; і асабліва дапаможаце &lt;strong&gt;рэалізацыі грамадскіх праектаў.&lt;/strong&gt;</string>
<string name="html_text_feature_generosity">Гэты &lt;strong&gt;візуальны стыль&lt;/strong&gt; даступны дзякуючы вашай шчодрасці.</string>
<string name="html_text_donation">&lt;strong&gt;Унёсшы ўклад&lt;/strong&gt; у праект &lt;i&gt;(матэрыяльна, кодам, перакладам)&lt;/i&gt;, вы дапаможаце яму працягваць жыць і развівацца, а таксама будзеце мець права на працэдуру разблакіроўкі &lt;strong&gt;тэмы&lt;/strong&gt;.</string>
<string name="html_text_dev_feature">Гэтая функцыя &lt;strong&gt;знаходзіцца ў стадыі распрацоўкі&lt;/strong&gt; і патрабуе вашага &lt;strong&gt;ўкладу&lt;/strong&gt;, каб неўзабаве стаць даступнай.</string>
<string name="html_text_dev_feature_buy_pro">Купляючы &lt;strong&gt;pro-версію&lt;/strong&gt;,</string>
<string name="html_text_dev_feature_contibute">&lt;strong&gt;Унёсшы ўклад&lt;/strong&gt;,</string>
<string name="html_text_dev_feature_encourage">вы заахвочваеце распрацоўшчыкаў ствараць &lt;strong&gt;новыя функцыі&lt;/strong&gt; і &lt;strong&gt;выпраўляць памылкі&lt;/strong&gt; ў адпаведнасці з вашымі заўвагамі.</string>
<string name="html_text_dev_feature_thanks">Вялікі дзякуй за ваш уклад.</string>
<string name="html_text_dev_feature_work_hard">Мы прыкладаем усе намаганні, каб хутка выпусціць гэтую функцыю.</string>
<string name="html_text_dev_feature_upgrade">Не забудзьцеся абнаўляць праграму, усталёўваючы новыя версіі.</string>
<string name="download">Спампаваць</string>
<string name="contribute">Унесці ўклад</string>
<string name="download_attachment">Спампаваць %1$s</string>
<string name="upload_attachment">Загрузіць %1$s</string>
<string name="download_initialization">Ініцыялізацыя…</string>
<string name="download_progression">Выконваецца: %1$d%%</string>
<string name="download_finalization">Завяршэнне…</string>
<string name="download_complete">Гатова!</string>
<string name="download_canceled">Скасавана!</string>
<string name="unit_byte">Б</string>
<string name="unit_kibibyte">КіБ</string>
<string name="unit_mebibyte">МіБ</string>
<string name="unit_gibibyte">ГіБ</string>
<string name="entropy">Энтрапія: %1$s біт</string>
<string name="entropy_high">Энтрапія: Высокая</string>
<string name="entropy_calculate">Энтрапія: Разлік…</string>
<string name="at_least_one_char">Хаця б адзін сімвал з кожнай</string>
<string name="exclude_ambiguous_chars">Выключыць неадназначныя сімвалы</string>
<string name="consider_chars_filter">Разглядаць сімвалы</string>
<string name="word_separator">Падзяляльнік слоў</string>
<string name="ignore_chars_filter">Ігнараваць сімвалы</string>
<string name="lower_case">ніжні рэгістр</string>
<string name="upper_case">ВЕРХНІ РЭГІСТР</string>
<string name="title_case">Рэгістр загалоўкаў</string>
<string name="character_count">Колькасць сімвалаў: %1$d</string>
<string name="screenshot_mode_banner_text">Рэжым скрыншота</string>
<string name="style_choose_title">Тэма праграмы</string>
<string name="style_choose_summary">Тэма, якая выкарыстоўваецца ў праграме</string>
<string name="style_name_forest">Лес</string>
<string name="style_name_divine">Боскі</string>
<string name="style_name_classic">Класічны</string>
<string name="style_name_simple">Просты</string>
<string name="style_name_moon">Месяц</string>
<string name="style_name_sun">Сонца</string>
<string name="style_name_reply">Адказ</string>
<string name="style_name_kunzite">Кунцыт</string>
<string name="style_name_follow_system">Па сістэме</string>
<string name="style_brightness_title">Яркасць тэмы</string>
<string name="style_brightness_summary">Выбраць светлыя або цёмныя тэмы</string>
<string name="style_name_light">Светлая</string>
<string name="style_name_dark">Цёмная</string>
<string name="icon_section_standard">Стандартны</string>
<string name="icon_section_custom">Карыстальніцкі</string>
<string name="icon_pack_choose_title">Пакет значкоў</string>
<string name="icon_pack_choose_summary">Пакет значкоў, які выкарыстоўваецца ў праграме</string>
<string name="show_entry_colors_title">Колеры запісаў</string>
<string name="show_entry_colors_summary">Адлюстроўвае колеры пярэдняга плану і фону для запісу</string>
<string name="hide_expired_entries_title">Схаваць запісы з мінулым тэрмінам дзеяння</string>
<string name="hide_expired_entries_summary">Запісы з мінулым тэрмінам дзеяння не паказваюцца</string>
<string name="hide_templates_title">Схаваць шаблоны</string>
<string name="hide_templates_summary">Шаблоны не паказваюцца</string>
</resources>

View File

@@ -22,7 +22,7 @@
<string name="clipboard_timeout_summary">Продължителност на съхранение в клипборда (ако се поддържа от вашето устройство)</string>
<string name="clipboard_error">Някои устройства не позволяват на приложенията да използват клипборда.</string>
<string name="entry_title">Заглавие</string>
<string name="about_description">Версия за Андроид на приложението за управление на пароли KeePass</string>
<string name="about_description">Разработка за Андроид на приложението за управление на пароли KeePass.</string>
<string name="save">Запазване</string>
<string name="entry_confpassword">Потвърждаване на парола</string>
<string name="key_derivation_function">Функция за извличане на ключ</string>
@@ -352,7 +352,6 @@
<string name="keyboard_setting_label">Настройки на Magikeyboard</string>
<string name="keyboard_selection_entry_title">Избор на записи</string>
<string name="allow_no_password_title">Разрешаване без главна парола</string>
<string name="enable_read_only_title">Само за четене</string>
<string name="keyboard_notification_entry_content_text">%1$s</string>
<string name="keyboard_notification_entry_content_title">Записът %1$s е достъпен в Magikeyboard</string>
<string name="keyboard_notification_entry_content_title_text">Запис</string>
@@ -402,7 +401,6 @@
<string name="lock_database_show_button_title">Бутон за заключване</string>
<string name="autofill_explanation_summary">Включете услугата за попълване на формуляри в други приложения</string>
<string name="properties">Свойства</string>
<string name="enable_read_only_summary">По подразбиране отваря хранилището само за четене</string>
<string name="education_validate_entry_summary">Не забравяйте да потвърдите записа и да го запазите в хранилището.
\n
\nАко се задейства автоматичното заключване, а сте направили промени, рискувате загуба на данни.</string>

View File

@@ -471,8 +471,6 @@
<string name="menu_database_settings_summary">Metadades, paperera de reciclatge, plantilles, historial</string>
<string name="encryption_explanation">Algorisme de xifratge de la base de dades utilitzat per a totes les dades</string>
<string name="delete_entered_password_summary">Suprimeix la contrasenya introduïda després d\'un intent de connexió a una base de dades</string>
<string name="enable_read_only_title">Protegit contra l\'escriptura</string>
<string name="enable_read_only_summary">Obre la base de dades en mode només de lectura per defecte</string>
<string name="enable_screenshot_mode_summary">Permet que les aplicacions de tercers gravin o facin captures de pantalla de l\'aplicació</string>
<string name="enable_education_screens_summary">Ressalta els elements per saber com funciona l\'aplicació</string>
<string name="reset_education_screens_title">Reinicia els consells educatius</string>

View File

@@ -19,7 +19,7 @@
Czech translation by Jan Vaněk
--><resources>
<string name="homepage">Domovská stránka</string>
<string name="about_description">Implementace správce hesel KeePass pro Android</string>
<string name="about_description">Implementace správce hesel KeePass pro Android.</string>
<string name="accept">Přijmout</string>
<string name="add_entry">Přidat záznam</string>
<string name="add_group">Přidat skupinu</string>
@@ -224,8 +224,6 @@
<string name="magic_keyboard_explanation_summary">Aktivovat vlastní klávesnici, která snadno vyplní hesla a další položky identity</string>
<string name="allow_no_password_title">Umožnit bez hlavního klíče</string>
<string name="allow_no_password_summary">Povolit klepnutí na \"Otevřít\", i když není vybráno žádné heslo</string>
<string name="enable_read_only_title">Chráněno před zápisem</string>
<string name="enable_read_only_summary">Ve výchozím stavu otevřít databázi pouze pro čtení</string>
<string name="enable_education_screens_title">Vzdělávací nápovědy</string>
<string name="enable_education_screens_summary">Zvýraznit prvky k pochopení práce s aplikací</string>
<string name="reset_education_screens_title">Nastavit vzdělávací nápovědy do výchozího stavu</string>

View File

@@ -223,8 +223,6 @@
<string name="magic_keyboard_explanation_summary">Aktiver et brugerdefineret tastatur, der udfylder adgangskoder og alle identitetsfelter</string>
<string name="allow_no_password_title">Tillad ingen hovednøgle</string>
<string name="allow_no_password_summary">Tillader at trykke på knappen \"Åbn\", hvis der ikke er valgt nogen legitimationsoplysninger</string>
<string name="enable_read_only_title">Skrivebeskyttet</string>
<string name="enable_read_only_summary">Åbn som standard databasen skrivebeskyttet</string>
<string name="enable_education_screens_title">Praktiske tips</string>
<string name="enable_education_screens_summary">Fremhæv elementer for at lære, hvordan appen fungerer</string>
<string name="reset_education_screens_title">Nulstil praktiske tips</string>

View File

@@ -25,7 +25,7 @@
<string name="contribution">Beiträge</string>
<string name="feedback">Feedback</string>
<string name="homepage">Webseite</string>
<string name="about_description">Android-Implementierung des Passwortmanagers KeePass</string>
<string name="about_description">Android-Implementierung des Passwortmanagers KeePass.</string>
<string name="accept">Akzeptieren</string>
<string name="add_entry">Eintrag hinzufügen</string>
<string name="add_group">Gruppe hinzufügen</string>
@@ -277,9 +277,7 @@
<string name="enable_education_screens_summary">Bedienelemente hervorheben, um die Funktionsweise der App zu lernen</string>
<string name="menu_open_file_read_and_write">Änderbar</string>
<string name="menu_file_selection_read_only">Schreibgeschützt</string>
<string name="enable_read_only_title">Schreibgeschützt</string>
<string name="education_read_only_title">Datenbank-Schreibschutz aktivieren</string>
<string name="enable_read_only_summary">Datenbank standardmäßig schreibgeschützt öffnen</string>
<string name="education_read_only_summary">Den Öffnungsmodus für die Sitzung ändern. \n \n„Schreibgeschützt“ verhindert unbeabsichtigte Änderungen an der Datenbank. \nMit „Änderbar“ lässt sich jedes Element frei bearbeiten, hinzufügen oder löschen.</string>
<string name="edit_entry">Eintrag bearbeiten</string>
<string name="error_load_database">Die Datenbank konnte nicht geladen werden.</string>

View File

@@ -19,7 +19,7 @@
--><resources>
<string name="feedback">Σχόλια</string>
<string name="homepage">Αρχική Σελίδα</string>
<string name="about_description">Το KeePassDX είναι μία εφαρμογή Android του διαχειριστή κωδικών KeePass</string>
<string name="about_description">Υλοποίηση του διαχειριστή κωδικών πρόσβασης KeePass για Android.</string>
<string name="accept">Αποδοχή</string>
<string name="add_entry">Προσθήκη καταχώρησης</string>
<string name="add_group">Προσθήκη ομάδας</string>
@@ -259,8 +259,6 @@
<string name="enable_education_screens_summary">Επισήμανση στοιχείων για να μάθετε πώς λειτουργεί η εφαρμογή</string>
<string name="menu_file_selection_read_only">Προστασία εγγραφής</string>
<string name="menu_open_file_read_and_write">Τροποποιήσιμο</string>
<string name="enable_read_only_title">Προστασία Εγγραφής</string>
<string name="enable_read_only_summary">Ανοίξτε τη βάση δεδομένων μόνο για ανάγνωση από προεπιλογή</string>
<string name="education_read_only_title">Προστασία Εγγραφής της βάσης δεδομένων σας</string>
<string name="education_read_only_summary">Αλλάξτε τη λειτουργία ανοίγματος για το session.
\n

View File

@@ -21,7 +21,7 @@
--><resources>
<string name="feedback">Comentarios</string>
<string name="homepage">Página de inicio</string>
<string name="about_description">Implementación para Android del gestor de contraseñas KeePass</string>
<string name="about_description">Implementación para Android del gestor de contraseñas KeePass.</string>
<string name="accept">Aceptar</string>
<string name="add_entry">Añadir apunte</string>
<string name="add_group">Añadir grupo</string>
@@ -271,8 +271,6 @@
<string name="allow_no_password_summary">Permite pulsar el botón \"Abrir\" si no son seleccionadas las credenciales</string>
<string name="enable_education_screens_title">Consejos educativos</string>
<string name="enable_education_screens_summary">Destaca los elementos para aprender cómo funciona la aplicación</string>
<string name="enable_read_only_title">Protegida contra escritura</string>
<string name="enable_read_only_summary">Abre la base de datos como solo lectura por defecto</string>
<string name="education_read_only_title">Proteja la base de datos contra escritura</string>
<string name="keyboard_name">Magikeyboard</string>
<string name="keyboard_label">Magikeyboard (KeePassDX)</string>
@@ -693,4 +691,5 @@
<string name="generate_keyfile">Generar archivo de claves</string>
<string name="recursive_number_entries_title">Número recursivo de entradas</string>
<string name="hide_templates_summary">Las plantillas no se muestran</string>
<string name="error_otp_secret_length">La clave secreta debe tener al menos %1$d caracteres.</string>
</resources>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="homepage">Meie veebisait</string>
<string name="about_description">KeePassi salasõnahalduri Androidi variant</string>
<string name="about_description">KeePassi salasõnahalduri variant Androidile.</string>
<string name="contact">Meie kontaktid</string>
<string name="info">Teave</string>
<string name="accept">Nõustu</string>
@@ -84,7 +84,7 @@
<string name="content_description_hardware_key_checkbox">Füüsilise võtme märkruut</string>
<string name="content_description_credentials_information">Mandaatide info</string>
<string name="content_description_nav_header">Navigatsiooni päis</string>
<string name="retrieving_db_key">Laadime andmebaasi võtme</string>
<string name="retrieving_db_key">Laadin andmebaasi võtit</string>
<string name="content_description_passphrase_word_count">Sõnu salafraasis</string>
<string name="default_checkbox">Kasuta vaikeandmebaasina</string>
<string name="entry_accessed">Viimati kasutatud</string>
@@ -128,7 +128,7 @@
<string name="error_nokeyfile">Vali võtmefail.</string>
<string name="error_pass_match">Salasõnad ei klapi.</string>
<string name="error_create_database">Andmebaasifaili loomine ei õnnestunud.</string>
<string name="entry_url">URL</string>
<string name="entry_url">Võrguaadress</string>
<string name="error_file_not_create">Faili loomine ei õnnestunud.</string>
<string name="entry_otp">Ühekordne salasõna</string>
<string name="clipboard_timeout_summary">Lõikelauale kopeeritud andmete hoidmise aeg (kui sinu seade sellist võimalust toetab)</string>
@@ -245,7 +245,7 @@
<string name="list_size_title">Loendite suurus</string>
<string name="list_size_summary">Teksti suurus loendites</string>
<string name="creating_database">Loome salasõnade andmebaasi…</string>
<string name="loading_database">Laadime salasõnade andmebaasi…</string>
<string name="loading_database">Laadin salasõnade andmebaasi…</string>
<string name="lowercase">väiketähed</string>
<string name="about">Rakenduse teave</string>
<string name="menu_change_key_settings">Muuda peavõtit</string>
@@ -531,7 +531,6 @@
<string name="autofill_inline_suggestions_keyboard">Automaattäite soovitused on lisatud.</string>
<string name="autofill_read_only_save">Kui andmebaas on avatud ainult lugemiseks, siis andmete salvestamine pole võimalik.</string>
<string name="delete_entered_password_summary">Kustutab salasõna, mis oli kasutusel andmebaasiga ühenduse loomise ajal</string>
<string name="enable_read_only_summary">Vaikimisi ava andmebaas vaid lugemiseks</string>
<string name="enable_screenshot_mode_summary">Luba teistel rakendusel teha sellest rakendusest ekraanitõmmist või salvestada tema ekraanivaadet</string>
<string name="autofill_close_database_title">Sulge andmebaas</string>
<string name="autofill_close_database_summary">Peale automaattäite kasutamist sulega andmebaas</string>
@@ -547,7 +546,6 @@
<string name="allow_no_password_title">Ära kasuta peavõtit</string>
<string name="allow_no_password_summary">Kui kasutajanimi või salasõna pole valitud, siis võimaldab klõpsida „Ava“ nuppu</string>
<string name="delete_entered_password_title">Kustuta salasõna</string>
<string name="enable_read_only_title">Kirjutuskaitstud</string>
<string name="enable_screenshot_mode_title">Ekraanitõmmiste lubamine</string>
<string name="enable_education_screens_title">Koolitusvihjed</string>
<string name="enable_education_screens_summary">Õppimaks, kuidas rakendus toimib, tõsta esile kasutajaliidese elemente</string>

View File

@@ -397,7 +397,6 @@
<string name="memory_usage_explanation">Gakoaren eratorpen funtzioak erabiliko duen memoria kopurua.</string>
<string name="autofill_ask_to_save_data_summary">Datuak gordetzeko eskatu formulario bat betetzean</string>
<string name="education_select_database_summary">Ireki zure aurreko datu-base fitxategia zure fitxategi kudeatzailetik erabiltzen jarraitzeko.</string>
<string name="enable_read_only_title">Idazketaren aurka babestuta</string>
<string name="autofill_application_id_blocklist_title">Aplikazioen blokeo zerrenda</string>
<string name="keyboard_previous_fill_in_title">Tekla automatikoaren akzioa</string>
<string name="keyboard_previous_database_credentials_summary">Aldatu automatikoki aurreko teklatura datu-basearen kredentzialen pantailan</string>
@@ -478,7 +477,6 @@
<string name="kdf_explanation">Zifraketa algoritmorako gakoa sortzeko, gako nagusia itxuraldatu egiten da eratorpen funtzio eta ausazko gatz baten bidez.</string>
<string name="keyboard_previous_search_title">Bilaketa pantaila</string>
<string name="autofill_manual_selection_summary">Erabiltzaileari datu-baseko sarrera hautatzeko aukera erakutsi</string>
<string name="enable_read_only_summary">Lehenetsi irakurketa soilerako datu-basea irekitzea</string>
<string name="reset_education_screens_title">Berrezarri hezkuntza-pistak</string>
<string name="education_new_node_summary">Sarrerek zure identitate digitalak administratzen laguntzen dute.
\n

View File

@@ -75,7 +75,7 @@
<string name="content_description_update_from_list">I-update</string>
<string name="content_description_keyboard_close_fields">Isara ang mga field</string>
<string name="select_to_copy">Piliin para kopyahin ang %1$s sa clipboard</string>
<string name="html_about_licence">KeePassDX © %1$d Ang Kunzisoft ay &lt;strong&gt;open source&lt;/strong&gt; at &lt;strong&gt;walang advertising&lt;/strong&gt;. \nIbinigay ito nang as is, sa ilalim &lt;strong&gt;GPLv3&lt;/strong&gt; na lisensya, nang walang anumang warranty.</string>
<string name="html_about_licence">Ang KeePassDX © Kunzisoft ay open source at walang kasamang patalastas.\nIbinibigay ito nang buo sa ilalim ng lisensiyang GPLv3, nang walang anumang garantiya.</string>
<string name="html_about_privacy">&lt;strong&gt;Walang user data ay kinukuha&lt;/strong&gt;, ang aplikasyon na ito ay hindi kumokonekta sa anumang server, gumanagana ng lokal at ganap na ginagalang ang pagkapribado ng mga gumagamit.</string>
<string name="html_about_contribution">Para &lt;strong&gt;panatilihin ang aming kalayaan&lt;/strong&gt;, &lt;strong&gt;ayusin ang mga bug&lt;/strong&gt;, &lt;strong&gt;magdagdag ng mga feature&lt;/strong&gt; at &lt;strong&gt;maging palaging aktibo&lt;/strong&gt;, umaasa kami sa iyong &lt;strong&gt;kontribusyon&lt;/strong&gt;.</string>
<string name="entry_accessed">Na-access</string>

View File

@@ -283,8 +283,6 @@
<string name="allow_no_password_summary">Autorise lappui du bouton \"Ouvrir\" si aucun identifiant nest sélectionné</string>
<string name="menu_file_selection_read_only">Protéger en écriture</string>
<string name="menu_open_file_read_and_write">Modifiable</string>
<string name="enable_read_only_title">Protéger en écriture</string>
<string name="enable_read_only_summary">Ouvre la base de données en lecture seule par défaut</string>
<string name="education_read_only_title">Protégez en écriture votre base de données</string>
<string name="education_read_only_summary">Changez le mode douverture pour la session.
\n

View File

@@ -556,7 +556,6 @@
<string name="enable_auto_save_database_title">Gardar base de datos automaticamente</string>
<string name="enable_keep_screen_on_title">Manter a pantalla acesa</string>
<string name="allow_no_password_summary">Permitir pulsar o botón \"Abrir\" se non seleccionar ningunha credencial</string>
<string name="enable_read_only_title">Só lectura</string>
<string name="enable_education_screens_summary">Destacar elementos para saber como funciona a aplicación</string>
<string name="reset_education_screens_text">Suxestións educativas restabelecidas</string>
<string name="education_create_database_title">Crear o teu arquivo de base de datos</string>
@@ -593,7 +592,6 @@
<string name="education_entry_new_field_title">Engadir campos personalizados</string>
<string name="menu_form_filling_settings">Completado de formularios</string>
<string name="keyboard_notification_entry_content_title">%1$s dispoñíbel no Magikeyboard</string>
<string name="enable_read_only_summary">Abrir a base de datos en modo de só lectura por defecto</string>
<string name="education_setup_OTP_summary">Configure a xestión do contrasinal dun só uso (HOTP / TOTP) para xerar un token solicitado para a autenticación de dous factores (2FA).</string>
<string name="education_unlock_title">Desbloquee a súa base de datos</string>
<string name="delete_entered_password_title">Eliminar contrasinal</string>

View File

@@ -17,7 +17,7 @@
You should have received a copy of the GNU General Public License
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
--><resources>
<string name="about_description">Android implementacija KeePass upravljača lozinki</string>
<string name="about_description">Android implementacija KeePass upravljača lozinki.</string>
<string name="accept">Prihvati</string>
<string name="add_entry">Dodaj unos</string>
<string name="edit_entry">Uredi unos</string>
@@ -187,7 +187,7 @@
<string name="clipboard_warning">Ako automatsko brisanje međuspremnika ne uspije, izbriši njegovu povijest ručno.</string>
<string name="lock_database_screen_off_summary">Zaključaj bazu podataka nakon par sekundi kad se ekran ugasi</string>
<string name="lock_database_back_root_title">Pritisni \'Natrag\' za zaključavanje</string>
<string name="device_unlock">Otključavanje uređaja</string>
<string name="device_unlock">Otključaj uređaj</string>
<string name="device_unlock_explanation_summary">Koristi otključavanje uređaja za jednostavnije otvaranje baze podataka</string>
<string name="biometric_unlock_enable_title">Biometrijsko otključavanje</string>
<string name="biometric_unlock_enable_summary">Otvaranje baze podataka skeniranjem biometrike</string>
@@ -310,8 +310,6 @@
<string name="allow_no_password_summary">Dozvoljava dodir gumba „Otvori”, ako nisu odabrani nikoji podaci za prijavu</string>
<string name="delete_entered_password_title">Izbriši lozinku</string>
<string name="delete_entered_password_summary">Briše upisanu lozinku nakon pokušaja povezivanja s bazom podataka</string>
<string name="enable_read_only_title">Zaštićeno od pisanja</string>
<string name="enable_read_only_summary">Standardno otvori bazu podataka u zaštićenom stanju</string>
<string name="enable_auto_save_database_title">Automatski spremi bazu podataka</string>
<string name="enable_auto_save_database_summary">Automatski spremi bazu podataka nakon svake važne radnje (samo u modusu „Promjenjivo”)</string>
<string name="enable_education_screens_title">Edukativne poruke</string>
@@ -385,7 +383,7 @@
<string name="education_lock_summary">Zaključaj bazu podataka brzo, aplikaciju možeš postaviti tako da bazu nakon nekog vremena zaključa i kad se ekran isključi.</string>
<string name="show_recent_files_summary">Prikaži mjesto nedavnih baza podataka</string>
<string name="education_device_unlock_summary">Za brzo otključavanje baze podataka, poveži lozinku sa skeniranom biometrijom ili podacima za prijavu uređaja.</string>
<string name="html_text_donation">Kako bismo zadržali našu slobodu i uvijek bili aktivni, računamo na tvoj&lt;strong&gt;doprinos.&lt;/strong&gt;</string>
<string name="html_text_donation">&lt;strong&gt;Doprinosom&lt;/strong&gt; projektu &lt;i&gt;(novčano, kodom, prijevodom)&lt;/i&gt; pomažeš mu da živi i napreduje, a također stječeš pravo na postupak otključavanja &lt;strong&gt;tema&lt;/strong&gt;.</string>
<string name="kdf_explanation">Za stvaranje ključa za algoritam šifriranja, glavni ključ se transformira pomoću funkcije za generiranje ključeva koja sadrži slučajnu komponentu.</string>
<string name="lock_database_back_root_summary">Zaključaj bazu podataka kad korisnik pritisne gumb za natrag na glavnom ekranu</string>
<string name="hide_broken_locations_title">Sakrij pokvarene poveznice baze podataka</string>
@@ -700,4 +698,7 @@
<string name="recursive_number_entries_summary">Rekurzivno izračunava broj unosa u grupi</string>
<string name="hide_templates_title">Sakrij predloške</string>
<string name="hide_templates_summary">Predlošci se ne prikazuju</string>
<string name="error_otp_secret_length">Tajni ključ mora sadržati barem %1$d znakova.</string>
<string name="generate_keyfile">Generiraj datoteku ključeva</string>
<string name="warning_large_keyfile">Ne preporučuje se dodavanje velike datoteke ključeva, jer to može spriječiti otvaranje baze podataka.</string>
</resources>

View File

@@ -19,7 +19,7 @@
--><resources>
<string name="feedback">Visszajelzés</string>
<string name="homepage">Honlap</string>
<string name="about_description">A KeePass jelszókezelő androidos megvalósítása</string>
<string name="about_description">A KeePass jelszókezelő androidos megvalósítása.</string>
<string name="accept">Elfogadás</string>
<string name="add_entry">Bejegyzés hozzáadása</string>
<string name="add_group">Csoport hozzáadása</string>
@@ -245,8 +245,6 @@
<string name="keyboard_key_sound_title">Hang gombnyomáskor</string>
<string name="allow_no_password_title">Mesterkulcs elhagyásának engedélyezése</string>
<string name="allow_no_password_summary">A „Megnyitás” gomb engedélyezése, ha nincsenek hitelesítő adatok kiválasztva</string>
<string name="enable_read_only_title">Írásvédett</string>
<string name="enable_read_only_summary">Az adatbázis megnyitása alapértelmezetten írásvédett módban</string>
<string name="enable_education_screens_title">Oktatóképernyők</string>
<string name="enable_education_screens_summary">Elemek kiemelése, hogy megtudja hogyan működik az alkalmazás</string>
<string name="reset_education_screens_title">Oktatóképernyők visszaállítása</string>

View File

@@ -170,7 +170,7 @@
<string name="edit_entry">Rubah Entri</string>
<string name="add_entry">Tambahkan Entri</string>
<string name="accept">Terima</string>
<string name="about_description">Implementasi Android dari pengelola kata sandi KeePass</string>
<string name="about_description">Implementasi Android dari pengelola kata sandi KeePass.</string>
<string name="homepage">Beranda</string>
<string name="feedback">Umpan Balik</string>
<string name="contribution">Kontribusi</string>
@@ -515,7 +515,7 @@
<string name="education_donation_summary">Bantu meningkatkan stabilitas, keamanan, dan menambahkan lebih banyak fitur.</string>
<string name="html_text_ad_free">Tidak seperti banyak aplikasi pengelola kata sandi, ini &lt;strong&gt;bebas iklan&lt;/strong&gt;, &lt;strong&gt;perangkat lunak libre copyleft&lt;/strong&gt;, dan tidak mengumpulkan data pribadi di peladennya, tidak peduli versi apa yang Anda gunakan.</string>
<string name="html_text_feature_generosity">&lt;strong&gt;Gaya visual&lt;/strong&gt; ini tersedia berkat kemurahan hati Anda.</string>
<string name="html_text_donation">Dengan &lt;strong&gt;berkontribusi&lt;strong&gt; kepada proyek &lt;i&gt;(dalam bentuk uang, kode, penerjemahan)&lt;i&gt;, Anda akan membantu proyek tersebut supaya terus hidup dan berkembang, dan Anda juga akan memenuhi syarat untuk prosedur pembukaan kunci &lt;strong&gt;tema&lt;strong&gt;.</string>
<string name="html_text_donation">Dengan &lt;strong&gt;berkontribusi&lt;/strong&gt; kepada proyek &lt;i&gt;(dalam bentuk uang, kode, penerjemahan)&lt;/i&gt;, Anda akan membantu proyek tersebut supaya terus hidup dan berkembang, dan Anda juga akan memenuhi syarat untuk prosedur pembukaan kunci &lt;strong&gt;tema&lt;/strong&gt;.</string>
<string name="html_text_dev_feature">Fitur ini &lt;strong&gt;sedang dalam pengembangan&lt;/strong&gt; dan memerlukan &lt;strong&gt;kontribusi&lt;/strong&gt; Anda untuk bisa tersedia segera.</string>
<string name="show_otp_token_title">Tampilkan Token OTP</string>
<string name="text_appearance">Teks</string>
@@ -554,7 +554,6 @@
<string name="allow_no_password_title">Izinkan tidak ada kunci utama</string>
<string name="allow_no_password_summary">Memungkinkan mengetuk tombol \"Buka\" jika tidak ada kredensial yang dipilih</string>
<string name="delete_entered_password_summary">Menghapus kata sandi yang dimasukkan setelah upaya koneksi ke basis data</string>
<string name="enable_read_only_summary">Buka basis data baca-saja secara baku</string>
<string name="enable_keep_screen_on_title">Biarkan layar nyala</string>
<string name="enable_education_screens_summary">Sorot elemen untuk mempelajari cara kerja aplikasi</string>
<string name="education_create_database_summary">Buat file pengelola kata sandi pertama Anda.</string>
@@ -618,7 +617,6 @@
\nPeriksa kompatibilitas dan keamanan KeyStore dengan produsen perangkat Anda dan pembuat ROM yang Anda gunakan.</string>
<string name="education_read_only_title">Lindungi basis data Anda dari penulisan</string>
<string name="keyboard_save_search_info_summary">Coba simpan informasi terbagi ketika membuat sebuah pilihan entri manual untuk penggunaan mudah di waktu mendatang</string>
<string name="enable_read_only_title">Terlindungi-tulis</string>
<string name="enable_keep_screen_on_summary">Jaga layar tetap menyala saat melihat atau menyunting sebuah entri</string>
<string name="content_description_hardware_key_checkbox">Kotak centang kunci perangkat keras</string>
<string name="waiting_challenge_request">Menunggu untuk permintaan tantangan…</string>
@@ -685,4 +683,5 @@
<string name="recursive_number_entries_title">Jumlah entri rekursif</string>
<string name="warning_large_keyfile">Tidak disarankan menambahkan berkas kunci yang besar, ini dapat mencegah pembukaan basis data.</string>
<string name="hide_templates_title">Sembunyikan templat</string>
<string name="error_otp_secret_length">Kunci rahasia minimal harus %1$d karakter.</string>
</resources>

View File

@@ -21,7 +21,7 @@
--><resources>
<string name="feedback">Commenti</string>
<string name="homepage">Pagina web</string>
<string name="about_description">Implementazione Android del gestore password KeePass</string>
<string name="about_description">Implementazione Android del gestore password KeePass.</string>
<string name="accept">Accetto</string>
<string name="add_entry">Aggiungi elemento</string>
<string name="add_group">Aggiungi gruppo</string>
@@ -222,8 +222,6 @@
<string name="magic_keyboard_explanation_summary">Attiva una tastiera personale che inserisce le tue password e i campi di identità</string>
<string name="allow_no_password_title">Non consentire chiavi principali</string>
<string name="allow_no_password_summary">Permetti di toccare il pulsante \"Apri\" se non sono selezionate credenziali</string>
<string name="enable_read_only_title">Protetto da scrittura</string>
<string name="enable_read_only_summary">Apri il database in sola lettura in modo predefinito</string>
<string name="enable_education_screens_title">Suggerimenti educativi</string>
<string name="enable_education_screens_summary">Evidenzia gli elementi per imparare come funziona l\'app</string>
<string name="reset_education_screens_title">Ripristina i suggerimenti educativi</string>

View File

@@ -20,7 +20,7 @@
--><resources>
<string name="feedback">משוב</string>
<string name="homepage">דף הבית</string>
<string name="about_description">מימוש אנדרואיד של מנהל הסיסמאות KeePass</string>
<string name="about_description">מימוש אנדרואיד של מנהל הסיסמאות KeePass.</string>
<string name="accept">קבל</string>
<string name="add_entry">הוסף ערך</string>
<string name="add_group">הוסף קבוצה</string>
@@ -334,7 +334,6 @@
<string name="allow_copy_password_warning">אזהרה: לוח ההעתקה משותף לכל היישומים. אם מידע רגיש יועתק, תוכנות אחרות עשויות לשחזר אותו.</string>
<string name="disable">השבת</string>
<string name="keyboard_label">Magikeyboard (KeePassDX)</string>
<string name="enable_read_only_title">מוגן מפני כתיבה</string>
<string name="keyboard_notification_entry_clear_close_title">נקה בסגירה</string>
<string name="keyboard_notification_entry_content_title_text">רשומה</string>
<string name="keyboard_notification_entry_content_title">%1$s זמין ב־Magikeyboard</string>
@@ -469,7 +468,6 @@
<string name="keyboard_auto_go_action_title">פעולת מקש אוטומטית</string>
<string name="allow_no_password_title">אפשר עבודה ללא מפתח ראשי</string>
<string name="allow_no_password_summary">מאפשר הקשה על הכפתור \"פתח\" אם לא נבחרו אישורים</string>
<string name="enable_read_only_summary">פתח את מסד הנתונים לקריאה בלבד כברירת מחדל</string>
<string name="delete_entered_password_title">מחק סיסמה</string>
<string name="delete_entered_password_summary">מוחק את הסיסמה שהוזנה לאחר ניסיון התחברות למסד נתונים</string>
<string name="reset_education_screens_summary">הראה שוב את כל המידע הלימודי</string>

View File

@@ -21,7 +21,7 @@
<string name="contribution">貢献</string>
<string name="feedback">フィードバック</string>
<string name="homepage">ホームページ</string>
<string name="about_description">KeePass パスワード マネージャーの Android 実装</string>
<string name="about_description">KeePassパスワードマネージャーのAndroid実装版。</string>
<string name="accept">承認</string>
<string name="add_entry">エントリーを追加</string>
<string name="edit_entry">エントリーを編集</string>
@@ -400,8 +400,6 @@
<string name="allow_no_password_summary">認証情報が選択されていない場合でも、[開く] ボタンのタップを許可します</string>
<string name="delete_entered_password_title">パスワードの削除</string>
<string name="delete_entered_password_summary">入力されたパスワードをデータベースへの接続試行後に削除します</string>
<string name="enable_read_only_title">書き込み禁止</string>
<string name="enable_read_only_summary">デフォルトでデータベースを読み取り専用として開きます</string>
<string name="enable_auto_save_database_title">データベースの自動保存</string>
<string name="enable_auto_save_database_summary">重要なアクションを起こすたびにデータベースを保存します( [変更可能] モードのとき)</string>
<string name="enable_education_screens_title">教育的なヒント</string>
@@ -445,7 +443,7 @@
<string name="html_text_ad_free">多くのパスワード管理アプリとは異なり、このアプリは&lt;strong&gt;広告なし&lt;/strong&gt;かつ&lt;strong&gt;コピーレフトの自由ソフトウェア&lt;/strong&gt;です。どのバージョンを使っても、サーバー上で個人情報が収集されることはありません。</string>
<string name="html_text_buy_pro">Pro バージョンを購入すると、この&lt;strong&gt;ビジュアル スタイル&lt;/strong&gt;にアクセスできるようになり、また&lt;strong&gt;コミュニティ プロジェクトの実現&lt;/strong&gt;を特に支援できます。</string>
<string name="html_text_feature_generosity">この&lt;strong&gt;ビジュアル スタイル&lt;/strong&gt;はあなたの厚意により利用可能となります。</string>
<string name="html_text_donation">&lt;strong&gt;プロジェクトに貢献&lt;/strong&gt;することによって(お金、コード、翻訳など)、プロジェクトは継続して成長することができ、さらに&lt;strong&gt;テーマ&lt;/strong&gt;のアンロック手続きにも参加できるようになります。</string>
<string name="html_text_donation">&lt;strong&gt;プロジェクトに貢献&lt;/strong&gt;することによって &lt;i&gt;(お金、コード、翻訳など)&lt;/i&gt;、プロジェクトは継続して成長することができ、さらに&lt;strong&gt;テーマ&lt;/strong&gt;のアンロック手続きにも参加できるようになります。</string>
<string name="html_text_dev_feature">この機能は&lt;strong&gt;開発中&lt;/strong&gt;であり、早期に提供するにはあなたの&lt;strong&gt;貢献&lt;/strong&gt;が必要です。</string>
<string name="html_text_dev_feature_buy_pro">&lt;strong&gt;pro&lt;/strong&gt; バージョンを購入することによる、</string>
<string name="html_text_dev_feature_contibute">&lt;strong&gt;貢献&lt;/strong&gt;による、</string>

View File

@@ -19,7 +19,7 @@
--><resources>
<string name="feedback">Tilbakemelding</string>
<string name="homepage">Hjemmeside</string>
<string name="about_description">Android-implementasjon av KeePass-passordsbehandleren</string>
<string name="about_description">Android-implementasjon av KeePass-passordsbehandleren.</string>
<string name="accept">Godta</string>
<string name="add_entry">Legg til oppføring</string>
<string name="edit_entry">Rediger oppføring</string>
@@ -90,7 +90,7 @@
<string name="hint_length">Lengde</string>
<string name="hint_pass">Passord</string>
<string name="password">Passord</string>
<string name="invalid_credentials">Kunne ikke lese legitimasjonen.</string>
<string name="invalid_credentials">Kunne ikke lese autentiseringsopplysningene.</string>
<string name="invalid_algorithm">Ugyldig algoritme.</string>
<string name="invalid_db_sig">Fremmed databaseformat.</string>
<string name="keyfile_is_empty">Nøkkelfilen er tom.</string>
@@ -168,7 +168,7 @@
<string name="warning_no_encryption_key">Ønsker du å fortsette uten en krypteringsnøkkel\?</string>
<string name="version_label">Versjon %1$s</string>
<string name="encrypted_value_stored">Kryptert passord lagret</string>
<string name="unavailable">Denne databasen har ikke et passord enda.</string>
<string name="unavailable">Utilgjengelig</string>
<string name="database_history">Historikk</string>
<string name="menu_appearance_settings">Utseende</string>
<string name="general">Generelt</string>
@@ -201,7 +201,7 @@
<string name="assign_master_key">Tildel en hovednøkkel</string>
<string name="create_keepass_file">Opprett nytt hvelv</string>
<string name="recycle_bin_title">Papirkurvbruk</string>
<string name="recycle_bin_summary">Flytter grupper og oppføringer til \"Papirkurv\"-gruppen før sletting</string>
<string name="recycle_bin_summary">Flytter grupper og oppføringer til «Papirkurv»-gruppen før sletting</string>
<string name="monospace_font_fields_enable_title">Felt-skrift</string>
<string name="monospace_font_fields_enable_summary">Endre skriften brukt i felter for bedre tegngjengivelse</string>
<string name="allow_copy_password_title">Kopi av passord</string>
@@ -218,8 +218,6 @@
<string name="magic_keyboard_explanation_summary">Aktiver et egendefinert tastatur som fyller inn passordene og alle identitetsfelter</string>
<string name="allow_no_password_title">Tillat ingen hovednøkkel</string>
<string name="allow_no_password_summary">Tillater å trykke på \"Åpne\"-knappen hvis ingen legitimasjon er valgt</string>
<string name="enable_read_only_title">Skrivebeskyttet</string>
<string name="enable_read_only_summary">Åpne databasen skrivebeskyttet som standard</string>
<string name="enable_education_screens_title">Lærerike tips</string>
<string name="enable_education_screens_summary">Fremhev elementer for å finne ut hvordan appen fungerer</string>
<string name="reset_education_screens_title">Tilbakestill lærerike tips</string>
@@ -246,14 +244,9 @@
\n
\nHusk å lagre en kopi av din .kdbx-fil på et trygt sted etter hver endring.</string>
<string name="education_read_only_title">Skrivebeskytt databasen din</string>
<string name="education_read_only_summary">Endre åpningsmodus for økten.
\n
\nI skrivebeskyttet modus, kan du forhindre utilsiktede endringer i databasen.
\n
\nI skrivemodus, kan du legge til, slette eller endre alle elementene.</string>
<string name="education_read_only_summary">Endre åpningsmodus for sesjonen. \n \n«Skrivebeskyttet» hindrer utilsiktede endringer i databasen. \n«Modifiserbar» lar deg endre, slette eller modifisere alle elementene etter eget ønske.</string>
<string name="education_field_copy_title">Kopier et felt</string>
<string name="education_field_copy_summary">Kopier et felt for å lime det inn der du ønsker.
\nBruk den skjemautfyllingsmetoden du foretrekker.</string>
<string name="education_field_copy_summary">Kopierte felt kan limes inn hvorsomhelst.\n\nBruk den utfyllingsmetoden du foretrekker.</string>
<string name="education_lock_title">Lås databasen</string>
<string name="education_lock_summary">Lås din database raskt. Du kan sette opp programmet slik at det låser den etter en stund, og når skjermen slår seg av.</string>
<string name="education_sort_title">Sorter elementer</string>
@@ -263,7 +256,7 @@
<string name="html_text_ad_free">I motsetning til mange passordadministrasjons-apper er denne &lt;strong&gt;annonsefri&lt;/strong&gt;, &lt;strong&gt;copylefted libre-programvare&lt;/strong&gt; og samler ikke inn personlige data på serverne, uansett hvilken versjon du bruker.</string>
<string name="html_text_buy_pro">Ved kjøp av pro-versjonen, vil du få tilgang til denne &lt;strong&gt;visuelle funksjonen&lt;/strong&gt; og du vil bidra med støtte til &lt;strong&gt; realisering av fellesskaps prosjekter.&lt;/strong&gt;</string>
<string name="html_text_feature_generosity">Denne &lt;strong&gt;visuelle stilen&lt;/strong&gt; er tilgjengelig takket være din generøsitet.</string>
<string name="html_text_donation">For å beholde vår frihet og alltid være aktive, stoler vi på dine &lt;strong&gt;bidrag.&lt;/strong&gt;</string>
<string name="html_text_donation">Ved å &lt;strong&gt;bidra&lt;/strong&gt; til prosjektet &lt;i&gt;(med penger, kode eller oversettelser)&lt;/i&gt;, bidrar du til å holde prosjektet gående og trivende, og du vil også kunne få mulighet til å låse opp &lt;strong&gt;drakter&lt;/strong&gt;.</string>
<string name="html_text_dev_feature">Denne funksjonen er &lt;strong&gt;under utvikling&lt;/strong&gt; og krever &lt;strong&gt;bidrag&lt;/strong&gt; for å bli tilgjengelig snart.</string>
<string name="html_text_dev_feature_buy_pro">Ved å kjøpe &lt;strong&gt;pro&lt;/strong&gt;-versjonen,</string>
<string name="html_text_dev_feature_contibute">Ved å &lt;strong&gt;bidra&lt;/strong&gt;,</string>
@@ -334,7 +327,7 @@
<string name="entry_history">Historikk</string>
<string name="entry_setup_otp">Sett opp engangspassord</string>
<string name="otp_type">OTP-type</string>
<string name="otp_secret">Hemmelig</string>
<string name="otp_secret">Hemmelighet</string>
<string name="otp_period">Periode (sekunder)</string>
<string name="otp_counter">Teller</string>
<string name="otp_digits">Siffer</string>
@@ -345,7 +338,7 @@
<string name="error_otp_period">Periode må være mellom %1$d og %2$d sekunder.</string>
<string name="database_opened">Database åpnet</string>
<string name="menu_save_database">Lagre data</string>
<string name="content_description_password_checkbox">Passord avkrysningsrute</string>
<string name="content_description_password_checkbox">Passordsavkryssningsboks</string>
<string name="content_description_keyfile_checkbox">Avkrysningsrute for nøkkelfil</string>
<string name="biometric">Biometrisk</string>
<string name="error_disallow_no_credentials">Minst én identitetsdetalj må angis.</string>
@@ -355,7 +348,7 @@
<string name="invalid_db_same_uuid">%1$s med samme UUID %2$s finnes allerede.</string>
<string name="creating_database">Oppretter database…</string>
<string name="menu_security_settings">Sikkerhetsinnstillinger</string>
<string name="menu_master_key_settings">Hovednøkkel innstillinger</string>
<string name="menu_master_key_settings">Innstillinger for hovednøkkel</string>
<string name="contains_duplicate_uuid">Databasen inneholder dupliserte UUID-er.</string>
<string name="database_data_compression_title">Datakomprimering</string>
<string name="database_data_compression_summary">Datakomprimering reduserer databasens størrelse</string>
@@ -411,7 +404,7 @@
<string name="save_mode">Lagringsmodus</string>
<string name="search_mode">Søkemodus</string>
<string name="error_field_name_already_exists">Feltnavnet finnes allerede.</string>
<string name="content_description_add_item">Legg til element</string>
<string name="content_description_add_item">Legg til ny</string>
<string name="education_device_unlock_title">Opplåsing av enhetsdatabase</string>
<string name="unit_byte">B</string>
<string name="show_uuid_summary">Viser UUID-en som er tilknyttet en oppføring eller en gruppe</string>
@@ -445,7 +438,7 @@
<string name="content_description_repeat_toggle_password_visibility">Gjenta for å skifte passordsynlighet</string>
<string name="icon_section_custom">Egendefinert</string>
<string name="icon_section_standard">Forvalg</string>
<string name="style_brightness_summary">Velg et lyst eller mørkt tema</string>
<string name="style_brightness_summary">Velg en lys eller mørk drakt</string>
<string name="style_brightness_title">Draktlysstyrke</string>
<string name="backspace">Rettetast</string>
<string name="keyboard_save_search_info_title">Lagre delt info</string>
@@ -520,7 +513,7 @@
<string name="secure_note">Sikkehetsnotis</string>
<string name="standard">Standard</string>
<string name="bank_identifier_code">SWIFT/BIC</string>
<string name="error_registration_read_only">Å lagre et nytt element tillates ikke i skrivebeskyttet database.</string>
<string name="error_registration_read_only">Å lagre et nytt element tillates ikke i en skrivebeskyttet database.</string>
<string name="error_database_uri_null">Database-URI kan ikke innhentes.</string>
<string name="error_rebuild_list">Kunne ikke gjenoppbygge listen på riktig måte.</string>
<string name="error_upload_file">En feil inntraff under opplasting av fildataen.</string>
@@ -617,7 +610,7 @@
<string name="expired">Utløpt</string>
<string name="hardware_key">Maskinvarenøkkel</string>
<string name="error_no_hardware_key">Velg en maskinvarenøkkel.</string>
<string name="error_unable_merge_database_kdb">Kan ikke slå sammen fra en V1 database.</string>
<string name="error_unable_merge_database_kdb">Kan ikke slå sammen med en kdb-databasefil.</string>
<string name="error_location_unknown">Databaseplasseringen er ukjent, databasehandlingen kan ikke utføres.</string>
<string name="remember_hardware_key_summary">Holder styr på maskinvarenøklene som brukes</string>
<string name="exclude_ambiguous_chars">Ekskluder tvetydige tegn</string>
@@ -670,7 +663,7 @@
<string name="ask">Spør</string>
<string name="merge_success">Sammenslåingen er fullført</string>
<string name="configure">Konfigurer</string>
<string name="menu_appearance_settings_summary">Temaer, farger, attributter</string>
<string name="menu_appearance_settings_summary">Drakter, farger, attributter</string>
<string name="enable_screenshot_mode_title">Skjermbilde-modus</string>
<string name="consider_chars_filter">Vurder karakterer</string>
<string name="entropy_calculate">Entropi: Beregn…</string>
@@ -685,7 +678,7 @@
<string name="entropy_high">Entropi: Høy</string>
<string name="lower_case">små bokstaver</string>
<string name="upper_case">STORE BOKSTAVER</string>
<string name="style_name_divine">Divine</string>
<string name="style_name_divine">Gudommelig</string>
<string name="style_name_classic">Classic</string>
<string name="style_name_simple">Enkel</string>
<string name="style_name_moon">Moon</string>
@@ -695,4 +688,12 @@
<string name="style_name_follow_system">Følg systemet</string>
<string name="style_name_light">Lyst</string>
<string name="style_name_dark">Mørkt</string>
<string name="error_otp_secret_length">Den hemmelige nøkkelen må være minst %1$d tegn.</string>
<string name="generate_keyfile">Generer nøkkelfil</string>
<string name="nodes">Noder</string>
<string name="recursive_number_entries_title">Rekursivt antall oppføringer</string>
<string name="recursive_number_entries_summary">Regner ut antallet oppføringer i en gruppe rekursivt</string>
<string name="warning_large_keyfile">Det anbefales ikke å legge til en stor nøkkelfil, siden dette kan hindre databasen i å åpnes.</string>
<string name="hide_templates_title">Skjul maler</string>
<string name="hide_templates_summary">Maler vises ikke</string>
</resources>

View File

@@ -21,7 +21,7 @@
--><resources>
<string name="feedback">Feedback</string>
<string name="homepage">Startpagina</string>
<string name="about_description">Android-implementatie van KeePass-wachtwoordmanager</string>
<string name="about_description">Android-implementatie van de KeePass-wachtwoordmanager.</string>
<string name="accept">Accepteren</string>
<string name="add_entry">Item toevoegen</string>
<string name="add_group">Groep toevoegen</string>
@@ -230,8 +230,6 @@
<string name="magic_keyboard_explanation_summary">Activeer een aangepast toetsenbord dat je wachtwoorden en identiteitsvelden vult</string>
<string name="allow_no_password_title">Geen hoofdwachtwoord toestaan</string>
<string name="allow_no_password_summary">Schakel de knop \"Openen\" in als er geen referenties zijn geselecteerd</string>
<string name="enable_read_only_title">Alleen-lezen</string>
<string name="enable_read_only_summary">Open de database standaard alleen-lezen</string>
<string name="enable_education_screens_title">Informatieve tips</string>
<string name="enable_education_screens_summary">Markeer elementen om te leren hoe de app werkt</string>
<string name="reset_education_screens_title">Informatieve tips opnieuw instellen</string>

View File

@@ -331,7 +331,6 @@
<string name="keyboard_notification_entry_content_title_text">ਐਂਟਰੀ</string>
<string name="keyboard_entry_category">ਐਂਟਰੀ</string>
<string name="autofill_close_database_title">ਡਾਟਾਬੇਸ ਬੰਦ ਕਰੋ</string>
<string name="enable_read_only_title">ਲਿਖਣ ਤੋਂ ਸੁਰੱਖਿਅਤ</string>
<string name="education_search_title">ਐਂਟਰੀਆਂ ਵਿੱਚੋਂ ਲੱਭੋ</string>
<string name="education_entry_edit_title">ਐਂਟਰੀ ਨੂੰ ਸੋਧੋ</string>
<string name="education_add_attachment_title">ਅਟੈਚਮੈਂਟ ਜੋੜੋ</string>

View File

@@ -19,17 +19,17 @@
--><resources>
<string name="feedback">Zgłoś błąd lub sugestię</string>
<string name="homepage">Strona główna</string>
<string name="about_description">Implementacja menedżera haseł KeePass w systemie Android</string>
<string name="about_description">Implementacja menedżera haseł KeePass w systemie Android.</string>
<string name="accept">Akceptuj</string>
<string name="add_entry">Dodaj wpis</string>
<string name="add_group">Dodaj grupę</string>
<string name="encryption_algorithm">Algorytm szyfrowania</string>
<string name="app_timeout">Koniec czasu</string>
<string name="app_timeout">Limit czasu</string>
<string name="app_timeout_summary">Czas bezczynności przed zablokowaniem bazy danych</string>
<string name="application">Aplikacja</string>
<string name="menu_app_settings">Ustawienia ogólne</string>
<string name="brackets">Nawiasy</string>
<string name="file_manager_install_description">Do tworzenia, otwierania i zapisywania plików bazy danych potrzebny jest menedżer plików, który akceptuje działanie Intent Action ACTION_CREATE_DOCUMENT i ACTION_OPEN_DOCUMENT.</string>
<string name="file_manager_install_description">Do tworzenia, otwierania i zapisywania plików bazy danych wymagany jest menedżer plików akceptujący zamierzone działania ACTION_CREATE_DOCUMENT i ACTION_OPEN_DOCUMENT.</string>
<string name="clipboard_cleared">Schowek został wyczyszczony</string>
<string name="clipboard_timeout">Czas wygaśnięcia schowka</string>
<string name="clipboard_timeout_summary">Czas przechowywania w schowku (jeśli jest obsługiwany przez urządzenie)</string>
@@ -60,11 +60,11 @@
<string name="error_invalid_path">Upewnij się, że ścieżka jest prawidłowa.</string>
<string name="error_no_name">Wpisz nazwę.</string>
<string name="error_nokeyfile">Wybierz plik klucza.</string>
<string name="error_out_of_memory">W urządzeniu zabrakło pamięci do załadowania całej bazy danych.</string>
<string name="error_out_of_memory">Brak pamięci na załadowanie całej bazy danych.</string>
<string name="error_pass_gen_type">Należy wybrać co najmniej jeden rodzaj generowania hasła.</string>
<string name="error_pass_match">Hasła nie pasują do siebie.</string>
<string name="error_rounds_too_large">\"Rundy szyfrowania\" są zbyt wysokie. Ustaw na 2147483648.</string>
<string name="error_wrong_length">Wprowadź dodatnią liczbę całkowitą w polu \"Długość\".</string>
<string name="error_rounds_too_large">Rundy transformacji” są zbyt wysokie. Ustaw na 2147483648.</string>
<string name="error_wrong_length">Wprowadź dodatnią liczbę całkowitą w polu Długość.</string>
<string name="file_browser">Menedżer plików</string>
<string name="generate_password">Generuj hasło</string>
<string name="hint_conf_pass">Potwierdź hasło</string>
@@ -77,8 +77,8 @@
<string name="invalid_credentials">Nie można odczytać uwierzytelnień.</string>
<string name="invalid_db_sig">Nie można rozpoznać formatu bazy danych.</string>
<string name="length">Długość</string>
<string name="list_size_title">Wielkość listy grup</string>
<string name="list_size_summary">Wielkość tekstu w liście grup</string>
<string name="list_size_title">Rozmiar elementów listy</string>
<string name="list_size_summary">Rozmiar tekstu na liście elementów</string>
<string name="loading_database">Wczytywanie bazy danych…</string>
<string name="lowercase">Małe litery</string>
<string name="hide_password_title">Ukryj hasła</string>
@@ -103,7 +103,7 @@
<string name="progress_create">Tworzenie nowej bazy danych…</string>
<string name="progress_title">Pracuję…</string>
<string name="content_description_remove_from_list">Usuń</string>
<string name="root">Root</string>
<string name="root">Główny</string>
<string name="rounds">Rundy szyfrowania</string>
<string name="rounds_explanation">Dodatkowe rundy szyfrowania zapewniają lepszą ochronę przed atakami typu brute force, ale mogą znacznie spowolnić ładowanie i zapisywanie.</string>
<string name="saving_database">Zapisywanie bazy danych…</string>
@@ -133,7 +133,7 @@
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft jest &lt;strong&gt;open source&lt;/strong&gt; i &lt;strong&gt;bez reklam&lt;/strong&gt;. \nJest on dostarczany w stanie, zgodnie z licencją &lt;strong&gt;GPLv3&lt;/strong&gt; bez żadnych gwarancji.</string>
<string name="entry_not_found">Nie znaleziono danych wejściowych.</string>
<string name="error_load_database">Nie można załadować bazy danych.</string>
<string name="error_load_database_KDF_memory">Nie można załadować klucza. Spróbuj zmniejszyć użycie pamięć KDF.</string>
<string name="error_load_database_KDF_memory">Nie można załadować klucza. Spróbuj zmniejszyć „Użycie pamięci” KDF.</string>
<string name="error_string_key">Każdy ciąg musi mieć nazwę pola.</string>
<string name="error_autofill_enable_service">Nie można włączyć usługi autouzupełniania.</string>
<string name="field_name">Nazwa pola</string>
@@ -149,8 +149,8 @@
<string name="menu_move">Przenieś</string>
<string name="menu_paste">Wklej</string>
<string name="menu_cancel">Anuluj</string>
<string name="menu_file_selection_read_only">Chroniony przed zapisem</string>
<string name="menu_open_file_read_and_write">Modyfikowalne</string>
<string name="menu_file_selection_read_only">Ochrona przed zapisem</string>
<string name="menu_open_file_read_and_write">Modyfikowalny</string>
<string name="protection">Ochrona</string>
<string name="read_only">Ochrona przed zapisem</string>
<string name="read_only_warning">KeePassDX potrzebuje uprawnień do zapisu, aby mógł modyfikować bazę danych.</string>
@@ -208,12 +208,12 @@
<string name="assign_master_key">Przypisz klucz główny</string>
<string name="create_keepass_file">Utwórz nowy sejf</string>
<string name="recycle_bin_title">Wykorzystanie kosza</string>
<string name="recycle_bin_summary">Przenosi grupy i wpisy do grupy \"Kosz\" przed usunięciem</string>
<string name="recycle_bin_summary">Przenosi grupy i wpisy do grupy Kosz przed usunięciem</string>
<string name="monospace_font_fields_enable_title">Czcionka pola</string>
<string name="monospace_font_fields_enable_summary">Zmień czcionkę użytą w polach, aby poprawić widoczność znaków</string>
<string name="allow_copy_password_title">Ochrona schowka</string>
<string name="allow_copy_password_summary">Zezwalanie na kopiowanie hasła wejściowego i chronionych pól do schowka</string>
<string name="allow_copy_password_warning">Ostrzeżenie: Schowek jest współużytkowany przez wszystkie aplikacje. Jeśli poufne dane są kopiowane, inne oprogramowanie może je odzyskać.</string>
<string name="allow_copy_password_warning">Ostrzeżenie: schowek jest współużytkowany przez wszystkie aplikacje. Jeśli poufne dane są kopiowane, inne oprogramowanie może je odzyskać.</string>
<string name="database_name_title">Nazwa bazy danych</string>
<string name="database_description_title">Opis bazy danych</string>
<string name="database_version_title">Wersja bazy danych</string>
@@ -224,9 +224,7 @@
<string name="magic_keyboard_title">Magikeyboard</string>
<string name="magic_keyboard_explanation_summary">Aktywuj niestandardową klawiaturę wypełniającą hasła i wszystkie pola tożsamości</string>
<string name="allow_no_password_title">Zezwalaj na brak klucza głównego</string>
<string name="allow_no_password_summary">Umożliwia naciśnięcie przycisku \"Otwórz\", jeśli nie wybrano żadnych poświadczeń</string>
<string name="enable_read_only_title">Ochrona przed zapisem</string>
<string name="enable_read_only_summary">Domyślnie otwarte bazy danych są tylko do odczytu</string>
<string name="allow_no_password_summary">Umożliwia naciśnięcie przycisku Otwórz, jeśli nie wybrano żadnych poświadczeń</string>
<string name="enable_education_screens_title">Wskazówki edukacyjne</string>
<string name="enable_education_screens_summary">Podświetl elementy, aby dowiedzieć się, jak działa aplikacja</string>
<string name="reset_education_screens_title">Zresetuj wskazówki edukacyjne</string>
@@ -250,10 +248,7 @@
<string name="education_entry_new_field_summary">Zarejestruj dodatkowe pole, dodaj wartość i opcjonalnie chroń je.</string>
<string name="education_unlock_title">Odblokuj swoją bazę danych</string>
<string name="education_read_only_title">Zapisz ochronę swojej bazy danych</string>
<string name="education_read_only_summary">Zmień tryb otwierania sesji.
\n
\n\"Ochrona przed zapisem\" zapobiega niezamierzonych zmian w bazie danych.
\n\"Modyfikowalne\" pozwala dodawać, usuwać lub modyfikować wszystkie elementy, jak chcesz.</string>
<string name="education_read_only_summary">Zmień tryb otwierania sesji. \n \n„Ochrona przed zapisem” zapobiega niezamierzonym zmianom w bazie danych. \n„Modyfikowalny” pozwala dodawać, usuwać lub modyfikować wszystkie elementy według uznania.</string>
<string name="education_field_copy_title">Skopiuj pole</string>
<string name="education_field_copy_summary">Skopiowane pola można wkleić w dowolnym miejscu.
\n
@@ -297,17 +292,17 @@
<string name="keyboard_notification_entry_clear_close_summary">Zamknij bazę danych podczas zamykania powiadomienia</string>
<string name="keyboard_appearance_category">Wygląd</string>
<string name="keyboard_theme_title">Motyw klawiatury</string>
<string name="keyboard_keys_category">Klawiatura</string>
<string name="keyboard_key_vibrate_title">Wibracja po naciśnięciu klawisza</string>
<string name="keyboard_key_sound_title">Dźwięk przy naciśnięciu</string>
<string name="do_not_kill_app">Nie zabijaj aplikacji…</string>
<string name="lock_database_back_root_title">Wciśnij \'Powrót\', aby zablokować</string>
<string name="lock_database_back_root_summary">Zablokuj bazę danych, gdy użytkownik kliknie przycisk \"Wstecz\" na ekranie głównym</string>
<string name="keyboard_keys_category">Klawisze</string>
<string name="keyboard_key_vibrate_title">Wibracje przy naciskaniu klawiszy</string>
<string name="keyboard_key_sound_title">Dźwięk przy naciskaniu klawiszy</string>
<string name="do_not_kill_app">Nie zamykaj aplikacji…</string>
<string name="lock_database_back_root_title">Naciśnij „Wstecz”, aby zablokować</string>
<string name="lock_database_back_root_summary">Zablokuj bazę danych, gdy użytkownik kliknie przycisk Wstecz na ekranie głównym</string>
<string name="clear_clipboard_notification_title">Wyczyść po zamknięciu</string>
<string name="clear_clipboard_notification_summary">Blokowanie bazy danych po wygaśnięciu czasu trwania schowka lub zamknięciu powiadomienia po rozpoczęciu korzystania z niej</string>
<string name="recycle_bin">Kosz</string>
<string name="keyboard_selection_entry_title">Wybór wpisu</string>
<string name="keyboard_selection_entry_summary">Podczas przeglądania wpisu w KeePassDX zapełnij Magikeyboard tym wpisem</string>
<string name="keyboard_selection_entry_summary">Podczas przeglądania wpisu w KeePassDX zapełnij Magikeyboard tym wpisem</string>
<string name="delete_entered_password_title">Usuń hasło</string>
<string name="delete_entered_password_summary">Usuwa hasło wprowadzone po próbie połączenia z bazą danych</string>
<string name="content_description_open_file">Otwórz plik</string>
@@ -369,7 +364,7 @@
<string name="compression_none">Żadna</string>
<string name="compression_gzip">Gzip</string>
<string name="device_keyboard_setting_title">Ustawienia klawiatury urządzenia</string>
<string name="error_invalid_OTP">Nieprawidłowy klucz OTP.</string>
<string name="error_invalid_OTP">Nieprawidłowy klucz tajny OTP.</string>
<string name="error_disallow_no_credentials">Należy ustawić co najmniej jedno poświadczenie.</string>
<string name="error_otp_secret_key">Klucz tajny musi być w formacie Base32.</string>
<string name="error_otp_counter">Licznik musi być między %1$d a %2$d.</string>
@@ -393,11 +388,11 @@
<string name="keystore_not_accessible">Magazyn kluczy nie został poprawnie zainicjowany.</string>
<string name="recycle_bin_group_title">Kosz grupy</string>
<string name="enable_auto_save_database_title">Automatycznie zapisuj bazę danych</string>
<string name="enable_auto_save_database_summary">Zapisz bazę danych po każdym ważnym działaniu (w trybie „Modyfikowalnym”)</string>
<string name="enable_auto_save_database_summary">Zapisz bazę danych po każdym ważnym działaniu (w trybie „Modyfikowalny”)</string>
<string name="entry_attachments">Załączniki</string>
<string name="menu_restore_entry_history">Przywróć historię</string>
<string name="menu_delete_entry_history">Usuń historię</string>
<string name="keyboard_auto_go_action_title">Automatyczne działanie klucza</string>
<string name="keyboard_auto_go_action_title">Automatyczna akcja klawiszy</string>
<string name="keyboard_auto_go_action_summary">Akcja klawisza „Idź” po naciśnięciu klawisza „Pole”</string>
<string name="download_attachment">Pobierz %1$s</string>
<string name="download_initialization">Inicjowanie…</string>
@@ -430,7 +425,7 @@
<string name="lock_database_show_button_summary">Wyświetla przycisk blokady w interfejsie użytkownika</string>
<string name="lock_database_show_button_title">Pokaż przycisk blokady</string>
<string name="autofill_preference_title">Ustawienia autouzupełniania</string>
<string name="warning_database_link_revoked">Dostęp do pliku anulowany przez menedżera plików</string>
<string name="warning_database_link_revoked">Dostęp do pliku anulowany przez menedżer plików</string>
<string name="error_label_exists">Ta etykieta już istnieje.</string>
<string name="autofill_block_restart">Zrestartuj aplikację zawierającą formularz, aby aktywować blokadę.</string>
<string name="autofill_block">Blokowanie autouzupełniania</string>
@@ -443,9 +438,9 @@
<string name="autofill_web_domain_blocklist_summary">Lista zablokowanych, która uniemożliwia automatyczne wypełnianie domen internetowych</string>
<string name="autofill_web_domain_blocklist_title">Lista zablokowanych domen internetowych</string>
<string name="autofill_application_id_blocklist_title">Lista zablokowanych aplikacji</string>
<string name="keyboard_previous_fill_in_summary">Automatycznie przełącz się z powrotem na poprzednią klawiaturę po wykonaniu automatycznej akcji klawiszy</string>
<string name="keyboard_previous_fill_in_title">Przełącz się z powrotem</string>
<string name="keyboard_previous_database_credentials_summary">Automatycznie przełącz się z powrotem do poprzedniej klawiatury na ekranie poświadczeń bazy danych</string>
<string name="keyboard_previous_fill_in_summary">Automatycznie przełącz z powrotem do poprzedniej klawiatury po wykonaniu automatycznej akcji klawiszy</string>
<string name="keyboard_previous_fill_in_title">Przełącz z powrotem</string>
<string name="keyboard_previous_database_credentials_summary">Automatycznie przełącz z powrotem do poprzedniej klawiatury na ekranie poświadczeń bazy danych</string>
<string name="keyboard_previous_database_credentials_title">Ekran poświadczeń bazy danych</string>
<string name="keyboard_change">Przełącz klawiaturę</string>
<string name="upload_attachment">Prześlij %1$s</string>
@@ -453,9 +448,7 @@
<string name="education_add_attachment_title">Dodaj załącznik</string>
<string name="warning_sure_add_file">Czy mimo to dodać plik\?</string>
<string name="warning_replace_file">Przesłanie tego pliku spowoduje zastąpienie istniejącego.</string>
<string name="warning_file_too_big">Baza danych KeePass powinna zawierać tylko małe pliki narzędziowe (takie jak pliki kluczy PGP).
\n
\nTwoja baza danych może stać się bardzo duża i zmniejszyć wydajność dzięki temu wgrywaniu danych.</string>
<string name="warning_file_too_big">Baza danych KeePass powinna zawierać tylko małe pliki narzędziowe (takie jak pliki kluczy PGP). \n \nTwoja baza danych może stać się bardzo duża i obniżyć wydajność w wyniku tego przesyłania.</string>
<string name="database_data_remove_unlinked_attachments_summary">Usuwa załączniki znajdujące się w bazie danych, ale niepowiązane z danym wpisem</string>
<string name="database_data_remove_unlinked_attachments_title">Usuń niepołączone dane</string>
<string name="data">Dane</string>
@@ -473,7 +466,7 @@
<string name="autofill_save_search_info_title">Zapisz informacje wyszukiwania</string>
<string name="autofill_close_database_summary">Zamknij bazę danych po wybraniu autouzupełniania</string>
<string name="autofill_close_database_title">Zamknij bazę danych</string>
<string name="keyboard_previous_lock_summary">Automatycznie przełącz się z powrotem do poprzedniej klawiatury po zablokowaniu bazy danych</string>
<string name="keyboard_previous_lock_summary">Automatycznie przełącz z powrotem do poprzedniej klawiatury po zablokowaniu bazy danych</string>
<string name="keyboard_previous_lock_title">Zablokuj bazę danych</string>
<string name="keyboard_save_search_info_summary">Staraj się zapisywać udostępnione informacje podczas dokonywania ręcznego wyboru wpisu, aby ułatwić sobie przyszłe użycie</string>
<string name="keyboard_save_search_info_title">Zapisz udostępnione informacje</string>
@@ -620,17 +613,13 @@
<string name="menu_save_copy_to">Zapisz kopię w …</string>
<string name="expired">Wygasłe</string>
<string name="warning_database_already_opened">Baza danych jest już otwarta, należy ją najpierw zamknąć, aby otworzyć nową</string>
<string name="device_unlock_keystore_warning">Ta funkcja umożliwia przechowywanie zaszyfrowanych danych uwierzytelniających w bezpiecznym magazynie kluczy urządzenia.
\n
\nW zależności od konkretnej implementacji interfejsu API systemu operacyjnego, może nie być w pełni funkcjonalna.
\n
\nSprawdź kompatybilność i bezpieczeństwo magazynu kluczy u producenta urządzenia i twórcy używanego ROM-u.</string>
<string name="device_unlock_keystore_warning">Ta funkcja umożliwia przechowywanie zaszyfrowanych danych uwierzytelniających w bezpiecznym magazynie kluczy urządzenia. \n \nMoże nie być w pełni funkcjonalna w zależności od konkretnej implementacji interfejsu API systemu operacyjnego. \n \nSprawdź kompatybilność i bezpieczeństwo magazynu kluczy u producenta urządzenia i twórcy używanego ROM-u.</string>
<string name="passphrase">Fraza hasła</string>
<string name="colorize_password_summary">Koloruj znaki hasła według typu</string>
<string name="keyboard_previous_search_title">Ekran wyszukiwania</string>
<string name="entropy">Entropia: %1$s bitowa</string>
<string name="entropy_high">Entropia: Wysoka</string>
<string name="entropy_calculate">Entropia: Oblicz…</string>
<string name="entropy_high">Entropia: wysoka</string>
<string name="entropy_calculate">Entropia: oblicz…</string>
<string name="at_least_one_char">Co najmniej po jednym znaku z każdego</string>
<string name="exclude_ambiguous_chars">Wyklucz niejednoznaczne znaki</string>
<string name="consider_chars_filter">Rozważ znaki</string>
@@ -642,7 +631,7 @@
<string name="content_description_passphrase_word_count">Liczba słów frazy hasła</string>
<string name="ignore_chars_filter">Ignoruj znaki</string>
<string name="colorize_password_title">Koloruj hasła</string>
<string name="keyboard_previous_search_summary">Automatycznie przełączaj z powrotem do poprzedniej klawiatury na ekranie wyszukiwania</string>
<string name="keyboard_previous_search_summary">Automatycznie przełącz z powrotem do poprzedniej klawiatury na ekranie wyszukiwania</string>
<string name="waiting_challenge_request">Oczekiwanie na żądanie wyzwania…</string>
<string name="waiting_challenge_response">Oczekiwanie na odpowiedź na wyzwanie…</string>
<string name="error_challenge_already_requested">Wyzwanie już zażądane.</string>
@@ -702,7 +691,7 @@
<string name="nodes">Węzły</string>
<string name="warning_large_keyfile">Nie zaleca się dodawania dużego pliku klucza, ponieważ może to uniemożliwić otwarcie bazy danych.</string>
<string name="generate_keyfile">Wygeneruj plik klucza</string>
<string name="recursive_number_entries_summary">Rekurencyjnie oblicza liczbę wpisów w grupie</string>
<string name="recursive_number_entries_summary">Rekurencyjnie oblicza liczbę wpisów w grupie</string>
<string name="recursive_number_entries_title">Rekurencyjna liczba wpisów</string>
<string name="hide_templates_title">Ukryj szablony</string>
<string name="hide_templates_summary">Szablony nie są wyświetlane</string>

View File

@@ -222,8 +222,6 @@
<string name="magic_keyboard_explanation_summary">Ative um teclado customizado, populando suas senhas e todos os campos de identidade</string>
<string name="allow_no_password_title">Permitir chave-mestra vazia</string>
<string name="allow_no_password_summary">Permite tocar no botão \"Abrir\" mesmo se nenhuma credencial for selecionada</string>
<string name="enable_read_only_title">Somente leitura</string>
<string name="enable_read_only_summary">Abre o banco de dados no modo somente leitura por padrão</string>
<string name="enable_education_screens_title">Dicas educacionais</string>
<string name="enable_education_screens_summary">Destaque os elementos para aprender como o aplicativo funciona</string>
<string name="reset_education_screens_title">Reiniciar telas educacionais</string>

View File

@@ -269,8 +269,6 @@
<string name="allow_no_password_summary">Permite tocar no botão \"Abrir\" se não estiverem selecionadas nenhumas credenciais</string>
<string name="enable_education_screens_title">Dicas educacionais</string>
<string name="enable_education_screens_summary">Destacar elementos para saber como a aplicação funciona</string>
<string name="enable_read_only_title">Apenas leitura</string>
<string name="enable_read_only_summary">Abrir a base de dados com permissão de apenas leitura por predefinição</string>
<string name="education_read_only_title">Proteger a base de dados contra alterações</string>
<string name="education_read_only_summary">Altere o modo de abertura para a sessão.
\n

View File

@@ -1,7 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="enable_read_only_summary">Abrir a base de dados com permissão de apenas leitura por predefinição</string>
<string name="enable_read_only_title">Apenas leitura</string>
<string name="menu_open_file_read_and_write">Alterável</string>
<string name="menu_file_selection_read_only">Apenas leitura</string>
<string name="enable_education_screens_summary">Destacar elementos para saber como a aplicação funciona</string>

View File

@@ -99,7 +99,7 @@
<string name="error_invalid_db">Nu s-a putut citi baza de date.</string>
<string name="error_invalid_path">Asigurați-vă că calea este corectă.</string>
<string name="error_invalid_OTP">Secret OTP nevalid.</string>
<string name="error_no_name">Introduce un nume.</string>
<string name="error_no_name">Introduceți un nume.</string>
<string name="error_nokeyfile">Alege un fisier cheie.</string>
<string name="error_out_of_memory">Nicio memorie pentru a încărca întreaga dvs. bază de date.</string>
<string name="error_load_database">Nu s-a putut încărca baza de date.</string>
@@ -107,7 +107,7 @@
<string name="error_pass_gen_type">Trebuie selectat cel puțin un tip de generare a parolei.</string>
<string name="error_disallow_no_credentials">Trebuie să setați cel puțin o credențială.</string>
<string name="error_pass_match">Parolele nu se potrivesc.</string>
<string name="error_rounds_too_large">\"Transformările rotunde\" prea sus. Setarea la 2147483648.</string>
<string name="error_rounds_too_large">Prea multe runde de transformare. Setare la 2147483648.</string>
<string name="error_string_key">Fiecare șir trebuie să aibă un nume de câmp.</string>
<string name="error_wrong_length">Introduceți un număr întreg pozitiv în câmpul \"Lungime\".</string>
<string name="error_autofill_enable_service">Nu s-a putut activa serviciul de completare automată.</string>
@@ -178,7 +178,7 @@
<string name="minus">Mai puțin</string>
<string name="never">Niciodată</string>
<string name="no_results">Nu există rezultate de căutare</string>
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft este &lt;strong&gt;open source&lt;/strong&gt; și &lt;strong&gt;fără reclame&lt;/strong&gt;. \n\nEste furnizat ca atare, sub licență &lt;strong&gt;GPLv3&lt;/strong&gt;, fără nicio garanție.</string>
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft este &lt;strong&gt;open source&lt;/strong&gt; și &lt;strong&gt;fără reclame&lt;/strong&gt;. \nEste furnizat ca atare, sub licență &lt;strong&gt;GPLv3&lt;/strong&gt;, fără nicio garanție.</string>
<string name="html_about_contribution">Pentru a ne &lt;strong&gt;păstra libertatea&lt;/strong&gt;, &lt;strong&gt;pentru a remedia erori&lt;/strong&gt;, &lt;strong&gt;pentru a adăuga funcții&lt;/strong&gt; și &lt;strong&gt;pentru a fi mereu activi&lt;/strong&gt;, ne bazăm pe &lt;strong&gt;contribuția&lt;/strong&gt; dvs.</string>
<string name="hide_password_title">Ascundeți parolele</string>
<string name="hide_password_summary">Mascați parolele (***) în mod implicit</string>
@@ -336,8 +336,6 @@
<string name="allow_no_password_summary">Permite apăsarea butonului \"Deschidere\" în cazul în care nu sunt selectate credențiale</string>
<string name="delete_entered_password_title">Ștergere parolă</string>
<string name="delete_entered_password_summary">Șterge parola introdusă după o încercare de conectare la o bază de date</string>
<string name="enable_read_only_title">Protejat la scriere</string>
<string name="enable_read_only_summary">Deschideți baza de date numai în citire în mod implicit</string>
<string name="enable_auto_save_database_title">Salvare automată a bazei de date</string>
<string name="enable_auto_save_database_summary">Salvați baza de date după fiecare acțiune importantă (în modul \"Modificabil\")</string>
<string name="enable_education_screens_title">Sugestii educaționale</string>
@@ -383,7 +381,7 @@
<string name="html_text_ad_free">Spre deosebire de multe aplicații de gestionare a parolelor, aceasta este &lt;strong&gt;fără reclame&lt;/strong&gt;, &lt;strong&gt;software liber cu copyleft&lt;/strong&gt; și nu colectează date personale pe serverele sale, indiferent de versiunea pe care o utilizați.</string>
<string name="html_text_buy_pro">Prin cumpărarea versiunii pro, veți avea acces la acest lucru &lt;strong&gt;stil vizual&lt;/strong&gt; și veți ajuta în special la &lt;strong&gt;realizarea proiectelor comunitare.&lt;/strong&gt;</string>
<string name="html_text_feature_generosity">Acest &lt;strong&gt; stil vizual &lt;/strong&gt; este disponibil datorită generozității tale.</string>
<string name="html_text_donation">strong&gt;Contribuind&lt;/strong&gt; la proiect &lt;i&gt;(financiar, cod, traducere)&lt;/i&gt;, îl veți ajuta să continue să trăiască și să prospere și veți fi, de asemenea, eligibil pentru procedura de deblocare a &lt;strong&gt;temei&lt;/strong&gt;.</string>
<string name="html_text_donation">&lt;strong&gt;Contribuind&lt;/strong&gt; la proiect &lt;i&gt;(financiar, cod, traducere)&lt;/i&gt;, îl veți ajuta să continue să trăiască și să prospere și veți fi, de asemenea, eligibil pentru procedura de deblocare a &lt;strong&gt;temelor&lt;/strong&gt;.</string>
<string name="html_text_dev_feature">Această caracteristică este &lt;strong&gt; în curs de dezvoltare&lt;/strong&gt; și necesită ca &lt;strong&gt;contribuția&lt;/strong&gt; dvs. să fie disponibilă în curând.</string>
<string name="html_text_dev_feature_buy_pro">Cumpărând versiunea &lt;strong&gt; pro &lt;/strong&gt;,</string>
<string name="html_text_dev_feature_contibute">Prin &lt;strong&gt; contribuție &lt;/strong&gt;,</string>
@@ -462,7 +460,7 @@
<string name="custom_data">Date personalizate</string>
<string name="tags">Etichete</string>
<string name="error_otp_type">Tipul de OTP existent nu este recunoscut de acest formular, este posibil ca validarea acestuia să nu mai genereze corect token-ul.</string>
<string name="error_move_group_here">Nu poți muta grupul aici.</string>
<string name="error_move_group_here">Nu puteți muta un grup aici.</string>
<string name="error_string_type">Acest text nu se potrivește cu articolul solicitat.</string>
<string name="error_registration_read_only">Salvarea unui element nou nu este permisă într-o bază de date numai pentru citire.</string>
<string name="error_field_name_already_exists">Numele câmpului există deja.</string>
@@ -701,4 +699,5 @@
<string name="warning_large_keyfile">Nu este recomandat să adăugați un fișier cheie mare, acest lucru poate împiedica deschiderea bazei de date.</string>
<string name="hide_templates_title">Ascundeți șabloanele</string>
<string name="hide_templates_summary">Șabloanele nu sunt afișate</string>
<string name="error_otp_secret_length">Cheia secretă trebuie să conțină cel puțin %1$d caractere.</string>
</resources>

View File

@@ -19,7 +19,7 @@
--><resources>
<string name="feedback">Отзыв</string>
<string name="homepage">Сайт</string>
<string name="about_description">Androidверсия менеджера паролей KeePass</string>
<string name="about_description">Androidверсия менеджера паролей KeePass.</string>
<string name="accept">Принять</string>
<string name="add_entry">Новая запись</string>
<string name="add_group">Новая группа</string>
@@ -226,8 +226,6 @@
<string name="magic_keyboard_explanation_summary">Активируйте пользовательскую клавиатуру для простого заполнения паролей и любых идентификаторов</string>
<string name="allow_no_password_title">Разрешить без главного пароля</string>
<string name="allow_no_password_summary">Разрешить нажимать кнопку \"Открыть\", если главный пароль не указан</string>
<string name="enable_read_only_title">Только чтение</string>
<string name="enable_read_only_summary">По умолчанию открывать базу только для чтения</string>
<string name="enable_education_screens_title">Обучающие подсказки</string>
<string name="enable_education_screens_summary">Выделять элементы, чтобы показать, как работает приложение</string>
<string name="reset_education_screens_title">Вернуть обучающие подсказки</string>

View File

@@ -620,8 +620,6 @@
<string name="allow_no_password_summary">Umožňuje klepnúť na tlačidlo „Otvoriť“, ak nie sú vybraté žiadne poverenia</string>
<string name="delete_entered_password_title">Vymazať heslo</string>
<string name="delete_entered_password_summary">Odstráni heslo zadané po pokuse o pripojenie k databáze</string>
<string name="enable_read_only_title">Ochrana proti zápisu</string>
<string name="enable_read_only_summary">V predvolenom nastavení otvorte databázu len na čítanie</string>
<string name="enable_keep_screen_on_title">Nechajte obrazovku zapnutú</string>
<string name="enable_keep_screen_on_summary">Pri sledovaní alebo úprave záznamu ponechať obrazovku zapnutú</string>
<string name="enable_screenshot_mode_title">Režim snímky obrazovky</string>

View File

@@ -555,7 +555,6 @@
<string name="keyboard_key_vibrate_title">Shtypje tastesh me dridhje</string>
<string name="autofill_save_search_info_title">Ruaj hollësi kërkimi</string>
<string name="autofill_web_domain_blocklist_summary">Listë bllokimesh që pengon vetëplotësim përkatësish web</string>
<string name="enable_read_only_title">Mbrojtur nga shkrimi</string>
<string name="enable_keep_screen_on_title">Mbaje ekranin ndezur</string>
<string name="enable_education_screens_title">Ndihmëza edukative</string>
<string name="education_search_summary">Jepni titull, emër përdoruesi, ose lëndë fushash të tjera, për të marrë fjalëkalimet tuaja.</string>
@@ -610,7 +609,6 @@
<string name="autofill_manual_selection_summary">Shfaq mundësi për ta lënë përdoruesin të përzgjedhë zë baze të dhënash</string>
<string name="autofill_save_search_info_summary">Provo të ruash informacion, kur bëhet një përzgjedhje dorazi e zërit, për përdorim më të kollajtë në të ardhmen</string>
<string name="autofill_read_only_save">Slejohet ruajtje të dhënash për një bazë të dhënash të hapur vetëm-për-lexim.</string>
<string name="enable_read_only_summary">Si parazgjedhje, bazën e të dhënave hape si vetëm-për-lexim</string>
<string name="enable_auto_save_database_summary">Ruaje bazën e të dhënave pas çdo veprimi të rëndësishëm (nën mënyrën “E ndryshueshme”)</string>
<string name="enable_keep_screen_on_summary">Mbaje hapur ekranin, kur shihet ose përpunohet një zë</string>
<string name="enable_screenshot_mode_summary">Lejo aplikacione palësh të treta të regjistrojnë, ose bëjnë foto ekrani të aplikacionit</string>

View File

@@ -279,8 +279,6 @@
<string name="enable_education_screens_summary">Markerar element för att lära dig hur appen fungerar</string>
<string name="menu_file_selection_read_only">Skrivskyddad</string>
<string name="menu_open_file_read_and_write">Modifierbar</string>
<string name="enable_read_only_title">Skrivskyddad</string>
<string name="enable_read_only_summary">Öppna databasen i skrivskyddat läge som standard</string>
<string name="education_read_only_title">Skrivskydda din databas</string>
<string name="education_read_only_summary">Ändra öppningsläge för sessionen.
\n

View File

@@ -647,8 +647,6 @@
<string name="autofill_web_domain_blocklist_summary">வலை களங்களை தானாக நிரப்புவதைத் தடுக்கும் பிளாக்லிச்ட்</string>
<string name="autofill_read_only_save">படிக்க மட்டும் திறக்கப்பட்ட தரவுத்தளத்திற்கு தரவு சேமிப்பு அனுமதிக்கப்படவில்லை.</string>
<string name="autofill_inline_suggestions_keyboard">ஆட்டோஃபில் பரிந்துரைகள் சேர்க்கப்பட்டன.</string>
<string name="enable_read_only_title">எழுது பாதுகாக்கப்பட்ட</string>
<string name="enable_read_only_summary">இயல்பாகவே தரவுத்தளத்தை படிக்க மட்டுமே திறக்கவும்</string>
<string name="education_new_node_summary">உங்கள் டிசிட்டல் அடையாளங்களை நிர்வகிக்க உள்ளீடுகள் உதவுகின்றன.\n\n குழுக்கள் (~ கோப்புறைகள்) உங்கள் தரவுத்தளத்தில் உள்ளீடுகளை ஒழுங்கமைக்கின்றன.</string>
<string name="education_search_title">உள்ளீடுகள் மூலம் தேடுங்கள்</string>
<string name="education_generate_password_summary">உங்கள் நுழைவுடன் தொடர்புபடுத்த ஒரு வலுவான கடவுச்சொல்லை உருவாக்குங்கள், படிவத்தின் அளவுகோல்களின்படி அதை எளிதாக வரையறுக்கவும், பாதுகாப்பான கடவுச்சொல்லை மறந்துவிடாதீர்கள்.</string>

View File

@@ -416,7 +416,6 @@
<string name="autofill_inline_suggestions_title">การแนะนำแบบอินไลน์</string>
<string name="autofill_ask_to_save_data_title">ถามเพื่อบันทึกข้อมูล</string>
<string name="autofill_block">บล็อกการกรอกอัตโนมัติ</string>
<string name="enable_read_only_title">ป้องกันการเขียน</string>
<string name="reset_education_screens_title">รีเซ็ทคำแนะนำการใช้งาน</string>
<string name="reset_education_screens_summary">แสดงคำแนะนำการใช้งานอีกครั้ง</string>
<string name="html_text_dev_feature_contibute">โดยการ&lt;strong&gt;ร่วมแก้ไข&lt;/strong&gt;</string>
@@ -620,7 +619,6 @@
<string name="allow_no_password_title">อนุญาตให้ไม่มีรหัสผ่านหลัก</string>
<string name="allow_no_password_summary">อนุญาตให้แตะปุ่ม \"เปิด\" เมื่อไม่มีข้อมูลประจำตัวถูกเลือก</string>
<string name="delete_entered_password_summary">ลบรหัสผ่านที่ป้อนแล้วหลังจากพยายามเชื่อมต่อที่ฐานข้อมูล</string>
<string name="enable_read_only_summary">เปิดฐานข้อมูลแบบอ่านอย่างเดียวเป็นค่าเรื่มต้น</string>
<string name="reset_education_screens_text">คำแนะนำการใช้งานถูกรีเซ็ทแล้ว</string>
<string name="icon_pack_choose_title">ชุดไอคอน</string>
<string name="enable_auto_save_database_summary">บันทึกฐานข้อมูลหลังจากการกระทำที่สำคัญ(ในโหมด\"แก้ไขได้\")</string>

View File

@@ -19,7 +19,7 @@
--><resources>
<string name="feedback">Geri bildirim</string>
<string name="homepage">Ana Sayfa</string>
<string name="about_description">KeePass Parola Yöneticisi\'nin Android uygulama uyarlaması</string>
<string name="about_description">KeePass Parola Yöneticisi\'nin Android uygulama uyarlaması.</string>
<string name="accept">Kabul et</string>
<string name="add_entry">Girdi ekle</string>
<string name="edit_entry">Girdi düzenle</string>
@@ -236,8 +236,6 @@
<string name="keyboard_key_sound_title">Tuşa basıldığında ses çıkar</string>
<string name="allow_no_password_title">Ana anahtar olmamasına izin ver</string>
<string name="allow_no_password_summary">Seçili kimlik bilgisi yoksa \"Aç\" düğmesine dokunmaya izin verir</string>
<string name="enable_read_only_title">Yazma korumalı</string>
<string name="enable_read_only_summary">Veri tabanını öntanımlı olarak salt okunur aç</string>
<string name="enable_education_screens_title">Eğitim ipuçları</string>
<string name="enable_education_screens_summary">Uygulamanın nasıl çalıştığını öğrenmek için ögeleri vurgulayın</string>
<string name="reset_education_screens_title">Eğitici ipuçlarını sıfırla</string>

View File

@@ -19,7 +19,7 @@
--><resources>
<string name="feedback">Відгук</string>
<string name="homepage">Домівка</string>
<string name="about_description">KeePassDX є Android-версією менеджера паролів KeePass</string>
<string name="about_description">KeePassDX Android-версія менеджера паролів KeePass.</string>
<string name="accept">Прийняти</string>
<string name="add_entry">Додати запис</string>
<string name="add_group">Додати групу</string>
@@ -314,8 +314,6 @@
<string name="enable_education_screens_summary">Виділяти елементи, щоб дізнатися, як працює застосунок</string>
<string name="enable_education_screens_title">Навчальні підказки</string>
<string name="enable_auto_save_database_title">Автозбереження бази даних</string>
<string name="enable_read_only_summary">Типово відкривати базу даних лише для читання</string>
<string name="enable_read_only_title">Захист від запису</string>
<string name="delete_entered_password_summary">Видаляти пароль, введений після спроби з\'єднання з базою даних</string>
<string name="delete_entered_password_title">Видаляти пароль</string>
<string name="allow_no_password_summary">Дозволяє натискання «Відкрити», якщо не вибрано головний пароль</string>

View File

@@ -568,8 +568,6 @@
<string name="allow_no_password_summary">Cho phép nhấn vào nút \"Mở\" nếu không có thông tin xác thực nào được chọn</string>
<string name="delete_entered_password_title">Xóa mật khẩu</string>
<string name="delete_entered_password_summary">Xóa mật khẩu đã nhập sau khi cố gắng kết nối với cơ sở dữ liệu</string>
<string name="enable_read_only_title">Bảo vệ chống ghi</string>
<string name="enable_read_only_summary">Mở cơ sở dữ liệu ở chế độ chỉ đọc theo mặc định</string>
<string name="enable_auto_save_database_title">Tự động lưu cơ sở dữ liệu</string>
<string name="enable_auto_save_database_summary">Lưu cơ sở dữ liệu sau mỗi hành động quan trọng (ở chế độ \"Có thể sửa đổi\")</string>
<string name="enable_keep_screen_on_title">Giữ màn hình luôn bật</string>

View File

@@ -19,7 +19,7 @@
--><resources>
<string name="feedback">反馈</string>
<string name="homepage">主页</string>
<string name="about_description">Android 平台上基于 KeePass 实现的密码管理器</string>
<string name="about_description">Android 平台 KeePass 密码管理器实现。</string>
<string name="accept">接受</string>
<string name="add_entry">添加条目</string>
<string name="add_group">添加分组</string>
@@ -190,8 +190,6 @@
<string name="other">其他</string>
<string name="keyboard">键盘</string>
<string name="magic_keyboard_title">魔法键盘</string>
<string name="enable_read_only_title">写入保护(只读模式)</string>
<string name="enable_read_only_summary">默认以只读方式打开数据库</string>
<string name="download">下载</string>
<string name="contribute">贡献</string>
<string name="style_choose_summary">应用中使用的主题</string>

View File

@@ -14,7 +14,7 @@
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
--><resources>
<string name="about">關於</string>
<string name="about_description">兼容KeePass密碼管理軟體的Android程式</string>
<string name="about_description">兼容KeePass密碼管理軟體的Android程式</string>
<string name="accept">接受</string>
<string name="account">帳戶</string>
<string name="add_entry">新增項目</string>
@@ -218,15 +218,13 @@
<string name="enable_auto_save_database_title">自動儲存資料庫</string>
<string name="enable_education_screens_summary">高亮界面元素來學習本應用工作方式</string>
<string name="enable_education_screens_title">教學提示</string>
<string name="enable_read_only_summary">預設以唯讀方式開啟資料庫</string>
<string name="enable_read_only_title">寫入保護(唯讀模式)</string>
<string name="encrypted_value_stored">已儲存加密密碼</string>
<string name="encryption">加密</string>
<string name="encryption_algorithm">加密演算法</string>
<string name="encryption_explanation">資料庫所有資料均採用加密演算法</string>
<string name="enter">輸入</string>
<string name="entry_UUID">UUID</string>
<string name="entry_accessed">存取</string>
<string name="entry_accessed">存取時間</string>
<string name="entry_add_attachment">添加附件</string>
<string name="entry_add_field">添加欄位</string>
<string name="entry_attachments">附件</string>
@@ -280,7 +278,7 @@
<string name="error_pass_gen_type">必須至少選擇一個密碼生成類型。</string>
<string name="error_pass_match">密碼不正確。</string>
<string name="error_rebuild_list">無法正確地重建列表。</string>
<string name="error_registration_read_only">唯讀資料庫不允許儲存新項目</string>
<string name="error_registration_read_only">唯讀資料庫不允許儲存新項目</string>
<string name="error_remove_file">刪除檔案資料時發生了一個錯誤。</string>
<string name="error_rounds_too_large">次數太多,最大設置到 2147483648。</string>
<string name="error_save_database">無法儲存資料庫。</string>
@@ -645,7 +643,7 @@
<string name="auto_type">自動填入</string>
<string name="info">資訊</string>
<string name="html_about_privacy">&lt;strong&gt;不收集用戶資料。&lt;/strong&gt;,此應用程式不連接任何伺服器,僅在裝置上運作,而且完全尊重用戶私穩。</string>
<string name="waiting_challenge_request">正在等待挑戰請求…</string>
<string name="waiting_challenge_request">正在等待開發請求…</string>
<string name="waiting_challenge_response">正等待Challenge回應……</string>
<string name="error_XML_malformed">XML格式錯誤。</string>
<string name="error_challenge_already_requested">已請求Challenge。</string>
@@ -667,10 +665,10 @@
<string name="menu_appearance_settings_summary">主題、顏色、屬性</string>
<string name="unlock">解鎖</string>
<string name="at_least_one_char">從每組中選擇字完</string>
<string name="consider_chars_filter">可以包</string>
<string name="consider_chars_filter">可以包</string>
<string name="ignore_chars_filter">不要包括</string>
<string name="title_case">標題大小寫</string>
<string name="content_description_nav_header">導航列</string>
<string name="content_description_nav_header">導航列標題</string>
<string name="education_validate_entry_summary">記得驗證和儲存你的資料庫。
\n
\n如果自動鎖定已啓用而你又忘記你在更改資料你可能會失去你的資料。</string>
@@ -699,4 +697,5 @@
<string name="nodes">節點</string>
<string name="recursive_number_entries_summary">遞歸計算群組中的項目數</string>
<string name="warning_large_keyfile">不建議增加較大的密鑰檔案,這可能會阻止資料庫開啟。</string>
<string name="error_otp_secret_length">密鑰必須包含至少%1$d個字元。</string>
</resources>

View File

@@ -67,8 +67,6 @@
<bool name="allow_no_password_default" translatable="false">false</bool>
<string name="delete_entered_password_key" translatable="false">delete_entered_password_key</string>
<bool name="delete_entered_password_default" translatable="false">true</bool>
<string name="enable_read_only_key" translatable="false">enable_read_only_key</string>
<bool name="enable_read_only_default" translatable="false">false</bool>
<string name="enable_auto_save_database_key" translatable="false">enable_auto_save_database_key</string>
<bool name="enable_auto_save_database_default" translatable="false">true</bool>
<string name="enable_keep_screen_on_key" translatable="false">enable_keep_screen_on_key</string>

View File

@@ -22,7 +22,7 @@
<string name="contribution">Contribution</string>
<string name="feedback">Feedback</string>
<string name="homepage">Homepage</string>
<string name="about_description">Android implementation of the KeePass password manager</string>
<string name="about_description">Android implementation of the KeePass password manager.</string>
<string name="accept">Accept</string>
<string name="add_entry">Add entry</string>
<string name="edit_entry">Edit entry</string>
@@ -413,7 +413,7 @@
<string name="database_history">History</string>
<string name="properties">Properties</string>
<string name="menu_appearance_settings">Appearance</string>
<string name="menu_appearance_settings_summary">Themes, colors, attributes</string>
<string name="menu_appearance_settings_summary">Themes, colors, icons, fonts, attributes</string>
<string name="biometric">Biometric</string>
<string name="device_credential">Device credential</string>
<string name="general">General</string>
@@ -575,8 +575,6 @@
<string name="allow_no_password_summary">Allows tapping the \"Open\" button if no credentials are selected</string>
<string name="delete_entered_password_title">Delete password</string>
<string name="delete_entered_password_summary">Deletes the password entered after a connection attempt to a database</string>
<string name="enable_read_only_title">Write-protected</string>
<string name="enable_read_only_summary">Open the database read-only by default</string>
<string name="enable_auto_save_database_title">Autosave database</string>
<string name="enable_auto_save_database_summary">Save the database after every important action (in \"Modifiable\" mode)</string>
<string name="enable_keep_screen_on_title">Keep screen on</string>

View File

@@ -43,7 +43,7 @@ Settings Activity. This is pointed to in the service's meta-data in the applicat
android:maxLongVersionCode="10000000000" />
<compatibility-package
android:name="com.android.chrome"
android:maxLongVersionCode="10000000000"/>
android:maxLongVersionCode="711900039" />
<compatibility-package
android:name="com.android.htmlviewer"
android:maxLongVersionCode="10000000000" />
@@ -55,7 +55,7 @@ Settings Activity. This is pointed to in the service's meta-data in the applicat
android:maxLongVersionCode="10000000000" />
<compatibility-package
android:name="com.brave.browser"
android:maxLongVersionCode="10000000000"/>
android:maxLongVersionCode="427912623" />
<compatibility-package
android:name="com.brave.browser_beta"
android:maxLongVersionCode="10000000000" />
@@ -70,13 +70,7 @@ Settings Activity. This is pointed to in the service's meta-data in the applicat
android:maxLongVersionCode="10000000000" />
<compatibility-package
android:name="com.chrome.beta"
android:maxLongVersionCode="10000000000"/>
<compatibility-package
android:name="com.chrome.canary"
android:maxLongVersionCode="10000000000"/>
<compatibility-package
android:name="com.chrome.dev"
android:maxLongVersionCode="10000000000"/>
android:maxLongVersionCode="711900039" />
<compatibility-package
android:name="com.cookiegames.smartcookie"
android:maxLongVersionCode="10000000000" />
@@ -107,6 +101,9 @@ Settings Activity. This is pointed to in the service's meta-data in the applicat
<compatibility-package
android:name="com.kiwibrowser.browser.dev"
android:maxLongVersionCode="10000000000" />
<compatibility-package
android:name="com.ktllq.play"
android:maxLongVersionCode="10000000000" />
<compatibility-package
android:name="com.lemurbrowser.exts"
android:maxLongVersionCode="10000000000" />
@@ -188,12 +185,18 @@ Settings Activity. This is pointed to in the service's meta-data in the applicat
<compatibility-package
android:name="com.yandex.browser"
android:maxLongVersionCode="10000000000" />
<compatibility-package
android:name="com.yjllq.chrome.beta"
android:maxLongVersionCode="10000000000" />
<compatibility-package
android:name="com.yjllq.internet"
android:maxLongVersionCode="10000000000" />
<compatibility-package
android:name="com.yjllq.kito"
android:maxLongVersionCode="10000000000" />
<compatibility-package
android:name="com.yjllqint.kito"
android:maxLongVersionCode="10000000000" />
<compatibility-package
android:name="com.yujian.ResideMenuDemo"
android:maxLongVersionCode="10000000000" />
@@ -251,9 +254,15 @@ Settings Activity. This is pointed to in the service's meta-data in the applicat
<compatibility-package
android:name="org.codeaurora.swe.browser"
android:maxLongVersionCode="10000000000" />
<compatibility-package
android:name="org.cromite.cromite"
android:maxLongVersionCode="10000000000" />
<compatibility-package
android:name="org.gnu.icecat"
android:maxLongVersionCode="10000000000" />
<compatibility-package
android:name="org.ironfoxoss.ironfox"
android:maxLongVersionCode="10000000000" />
<compatibility-package
android:name="org.mozilla.fenix"
android:maxLongVersionCode="10000000000" />
@@ -290,7 +299,4 @@ Settings Activity. This is pointed to in the service's meta-data in the applicat
<compatibility-package
android:name="org.ungoogled.chromium.stable"
android:maxLongVersionCode="10000000000" />
<compatibility-package
android:name="us.spotco.fennec_dos"
android:maxLongVersionCode="10000000000"/>
</autofill-service>

View File

@@ -32,11 +32,6 @@
android:title="@string/delete_entered_password_title"
android:summary="@string/delete_entered_password_summary"
android:defaultValue="@bool/delete_entered_password_default"/>
<SwitchPreferenceCompat
android:key="@string/enable_read_only_key"
android:title="@string/enable_read_only_title"
android:summary="@string/enable_read_only_summary"
android:defaultValue="@bool/enable_read_only_default"/>
<SwitchPreferenceCompat
android:key="@string/enable_auto_save_database_key"
android:title="@string/enable_auto_save_database_title"

View File

@@ -5,12 +5,12 @@ plugins {
android {
namespace 'com.kunzisoft.encrypt'
compileSdkVersion 34
compileSdkVersion 36
ndkVersion "21.4.7075529"
defaultConfig {
minSdkVersion 15
targetSdkVersion 34
minSdkVersion 19
targetSdkVersion 35
multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

View File

@@ -3,11 +3,11 @@ apply plugin: 'kotlin-android'
android {
namespace 'com.kunzisoft.keepass.database'
compileSdkVersion 34
compileSdkVersion 36
defaultConfig {
minSdkVersion 15
targetSdk 34
minSdkVersion 19
targetSdk 35
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

View File

@@ -22,6 +22,7 @@ package com.kunzisoft.keepass.database.merge
import com.kunzisoft.keepass.database.element.Attachment
import com.kunzisoft.keepass.database.element.CustomData
import com.kunzisoft.keepass.database.element.DateInstant
import com.kunzisoft.keepass.database.element.DeletedObject
import com.kunzisoft.keepass.database.element.database.DatabaseKDB
import com.kunzisoft.keepass.database.element.database.DatabaseKDBX
import com.kunzisoft.keepass.database.element.entry.EntryKDB
@@ -32,9 +33,10 @@ import com.kunzisoft.keepass.database.element.node.NodeHandler
import com.kunzisoft.keepass.database.element.node.NodeId
import com.kunzisoft.keepass.database.element.node.NodeIdInt
import com.kunzisoft.keepass.database.element.node.NodeIdUUID
import com.kunzisoft.keepass.database.element.node.NodeVersioned
import com.kunzisoft.keepass.utils.readAllBytes
import java.io.IOException
import java.util.*
import java.util.UUID
class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
@@ -180,7 +182,7 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
}
/**
* Merge a KDB> database in a KDBX database,
* Merge a KDBX database in a KDBX database,
* Try to take into account the modification date of each element
* To make a merge as accurate as possible
*/
@@ -302,30 +304,111 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
}
// Manage deleted objects
databaseToMerge.deletedObjects.forEach { deletedObject ->
val deletedObjectId = deletedObject.uuid
val databaseEntry = database.getEntryById(deletedObjectId)
val databaseGroup = database.getGroupById(deletedObjectId)
val databaseIcon = database.iconsManager.getIcon(deletedObjectId)
val databaseIconModificationTime = databaseIcon?.lastModificationTime
val deletedObjects = databaseToMerge.deletedObjects
deletedObjects.forEach { deletedObject ->
deleteEntry(deletedObject)
deleteGroup(deletedObject, deletedObjects)
deleteIcon(deletedObject)
// Attachments are removed and optimized during the database save
}
}
/**
* Delete an entry from the database with the [deletedEntry] id
*/
private fun deleteEntry(deletedEntry: DeletedObject) {
val databaseEntry = database.getEntryById(deletedEntry.uuid)
if (databaseEntry != null
&& deletedObject.deletionTime.isAfter(databaseEntry.lastModificationTime)) {
&& deletedEntry.deletionTime.isAfter(databaseEntry.lastModificationTime)) {
database.removeEntryFrom(databaseEntry, databaseEntry.parent)
}
}
/**
* Check whether a node is in the list of deleted objects
*/
private fun Set<DeletedObject>.containsNode(node: NodeVersioned<UUID, GroupKDBX, EntryKDBX>): Boolean {
return this.any { it.uuid == node.nodeId.id }
}
/**
* Check whether a node is not in the list of deleted objects
*/
private fun Set<DeletedObject>.notContainsNode(node: NodeVersioned<UUID, GroupKDBX, EntryKDBX>): Boolean {
return !this.containsNode(node)
}
/**
* Get the first parent not deleted
*/
private fun firstNotDeletedParent(
node: NodeVersioned<UUID, GroupKDBX, EntryKDBX>,
deletedObjects: Set<DeletedObject>
): GroupKDBX? {
var parent = node.parent
while (parent != null && deletedObjects.containsNode(parent)) {
parent = node.parent
}
return parent
}
/**
* Delete a group from the database with the [deletedGroup] id
* Recursively check whether a group to be deleted contains a node not to be deleted with [deletedObjects]
* and move it to the first parent that has not been deleted.
*/
private fun deleteGroup(deletedGroup: DeletedObject, deletedObjects: Set<DeletedObject>) {
val databaseGroup = database.getGroupById(deletedGroup.uuid)
if (databaseGroup != null
&& deletedObject.deletionTime.isAfter(databaseGroup.lastModificationTime)) {
&& deletedGroup.deletionTime.isAfter(databaseGroup.lastModificationTime)) {
// Must be in dedicated list to prevent modification collision
val entriesToMove = mutableListOf<EntryKDBX>()
databaseGroup.getChildEntries().forEach { child ->
// If the child entry is not a deleted object,
if (deletedObjects.notContainsNode(child)) {
entriesToMove.add(child)
}
}
val groupsToMove = mutableListOf<GroupKDBX>()
databaseGroup.getChildGroups().forEach { child ->
// Move the group to the first parent not deleted
// the deleted objects will take care of remove it later
groupsToMove.add(child)
}
// For each node to move, move it
// try to move the child entry in the first parent not deleted
entriesToMove.forEach { child ->
database.removeEntryFrom(child, child.parent)
database.addEntryTo(
child,
firstNotDeletedParent(databaseGroup, deletedObjects)
)
}
groupsToMove.forEach { child ->
database.removeGroupFrom(child, child.parent)
database.addGroupTo(
child,
firstNotDeletedParent(databaseGroup, deletedObjects)
)
}
// Then delete the group
database.removeGroupFrom(databaseGroup, databaseGroup.parent)
}
}
/**
* Delete an icon from the database with the [deletedIcon] id
*/
private fun deleteIcon(deletedIcon: DeletedObject) {
val deletedObjectId = deletedIcon.uuid
val databaseIcon = database.iconsManager.getIcon(deletedObjectId)
val databaseIconModificationTime = databaseIcon?.lastModificationTime
if (databaseIcon != null
&& (
databaseIconModificationTime == null
|| (deletedObject.deletionTime.isAfter(databaseIconModificationTime))
)
&& (databaseIconModificationTime == null
|| (deletedIcon.deletionTime.isAfter(databaseIconModificationTime)))
) {
database.removeCustomIcon(deletedObjectId)
}
// Attachments are removed and optimized during the database save
}
}
/**

View File

@@ -151,7 +151,7 @@ class SearchHelper {
if (searchParameters.searchByDomain) {
try {
stringToCheck.inTheSameDomainAs(word, sameSubDomain = true)
} catch (e: Exception) {
} catch (_: Exception) {
false
}
} else null
@@ -204,11 +204,19 @@ class SearchHelper {
regex.matches(stringToCheck)
} else {
specialComparison?.invoke(stringToCheck, searchParameters.searchQuery)
?: stringToCheck.contains(
searchParameters.searchQuery,
?: run {
// Search with space separator #175
var searchFound = true
searchParameters.searchQuery.split(" ").forEach { word ->
searchFound = searchFound
&& stringToCheck.contains(
word,
!searchParameters.caseSensitive
)
}
searchFound
}
}
}
}
}

View File

@@ -6,6 +6,7 @@ import com.kunzisoft.keepass.hardware.HardwareKey
data class DatabaseFile(var databaseUri: Uri? = null,
var keyFileUri: Uri? = null,
var hardwareKey: HardwareKey? = null,
var readOnly: Boolean? = null,
var databaseDecodedPath: String? = null,
var databaseAlias: String? = null,
var databaseFileExists: Boolean = false,

View File

@@ -92,7 +92,7 @@ inline fun <reified T : Parcelable> Parcel.readParcelableCompat(): T? = when {
fun <T> Parcel.readParcelableCompat(clazz: Class<T>): T? = when {
SDK_INT >= 33 -> readParcelable(clazz.classLoader, clazz)
else -> @Suppress("DEPRECATION") readParcelable(clazz.classLoader) as? T
else -> @Suppress("DEPRECATION", "UNCHECKED_CAST") (readParcelable(clazz.classLoader) as? T)
}
inline fun <reified T : Serializable> Parcel.readSerializableCompat(): T? = when {
@@ -120,19 +120,19 @@ fun <K : Parcelable, V : Parcelable> Parcel.writeParcelableMap(map: Map<K, V>, f
inline fun <reified K : Parcelable, reified V : Parcelable> Parcel.readParcelableMap(): Map<K, V> {
val size = readInt()
val map = HashMap<K, V>(size)
for (i in 0 until size) {
(0 until size).forEach { i ->
val key: K? = try {
when {
SDK_INT >= 33 -> readParcelable(K::class.java.classLoader, K::class.java)
else -> @Suppress("DEPRECATION") readParcelable(K::class.java.classLoader)
}
} catch (e: Exception) { null }
} catch (_: Exception) { null }
val value: V? = try {
when {
SDK_INT >= 33 -> readParcelable(V::class.java.classLoader, V::class.java)
else -> @Suppress("DEPRECATION") readParcelable(V::class.java.classLoader)
}
} catch (e: Exception) { null }
} catch (_: Exception) { null }
if (key != null && value != null)
map[key] = value
}
@@ -152,14 +152,14 @@ fun <V : Parcelable> Parcel.writeStringParcelableMap(map: HashMap<String, V>, fl
inline fun <reified V : Parcelable> Parcel.readStringParcelableMap(): LinkedHashMap<String, V> {
val size = readInt()
val map = LinkedHashMap<String, V>(size)
for (i in 0 until size) {
(0 until size).forEach { i ->
val key: String? = readString()
val value: V? = try {
when {
SDK_INT >= 33 -> readParcelable(V::class.java.classLoader, V::class.java)
else -> @Suppress("DEPRECATION") readParcelable(V::class.java.classLoader)
}
} catch (e: Exception) { null }
} catch (_: Exception) { null }
if (key != null && value != null)
map[key] = value
}
@@ -179,7 +179,7 @@ fun Parcel.writeStringIntMap(map: LinkedHashMap<String, Int>) {
fun Parcel.readStringIntMap(): LinkedHashMap<String, Int> {
val size = readInt()
val map = LinkedHashMap<String, Int>(size)
for (i in 0 until size) {
(0 until size).forEach { i ->
val key: String? = readString()
val value: Int = readInt()
if (key != null)
@@ -201,7 +201,7 @@ fun Parcel.writeStringStringMap(map: MutableMap<String, String>) {
fun Parcel.readStringStringMap(): LinkedHashMap<String, String> {
val size = readInt()
val map = LinkedHashMap<String, String>(size)
for (i in 0 until size) {
(0 until size).forEach { i ->
val key: String? = readString()
val value: String? = readString()
if (key != null && value != null)

View File

@@ -148,23 +148,6 @@ fun PackageManager.getPackageInfoCompat(packageName: String, flags: Int = 0): Pa
@Suppress("DEPRECATION") getPackageInfo(packageName, flags)
}
@SuppressLint("InlinedApi")
fun PackageManager.allowCreateDocumentByStorageAccessFramework(): Boolean {
return when {
// To check if a custom file manager can manage the ACTION_CREATE_DOCUMENT
// queries filter is in Manifest
Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT -> {
queryIntentActivitiesCompat(
Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "application/octet-stream"
}, PackageManager.MATCH_DEFAULT_ONLY
).isNotEmpty()
}
else -> true
}
}
@SuppressLint("QueryPermissionsNeeded")
private fun PackageManager.queryIntentActivitiesCompat(intent: Intent, flags: Int): List<ResolveInfo> {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {

View File

@@ -0,0 +1,6 @@
* Updated to API 35 minimum SDK 19 #2073 #2138 #2067 #2133 #1687 (Thx @Dev-ClayP)
* Remember last read-only state #2099 #2100 (Thx @rmacklin)
* Fix merge deletion #1516
* Fix space in search #175
* Fix deletable recycle bin #2163
* Small fixes

Some files were not shown because too many files have changed in this diff Show More