Compare commits

...

167 Commits
2.5 ... 2.7

Author SHA1 Message Date
J-Jamet
dae19bbccf Merge branch 'release/2.7' 2020-06-18 14:59:28 +02:00
J-Jamet
c81f83887e Replace <strong> tags 2020-06-18 14:44:50 +02:00
J-Jamet
04e555dde9 Merge branch 'master' of https://hosted.weblate.org/projects/keepass-dx/strings into translations 2020-06-18 14:25:28 +02:00
J-Jamet
be94518e31 Upgrade CHANGELOG 2020-06-18 14:25:06 +02:00
J-Jamet
66bec1e08c Merge branch 'feature/Button_Block_Autofill' into develop 2020-06-18 14:14:58 +02:00
J-Jamet
f61ce10716 Fix action bar style 2020-06-17 23:23:57 +02:00
J-Jamet
b1b92b2995 Add only the current app id in blocklist 2020-06-17 23:06:04 +02:00
J-Jamet
bd9f2c4757 Check if the search element is blocked after Autofill popup click 2020-06-17 22:49:09 +02:00
abidin toumi
a3ead2153e Translated using Weblate (Arabic)
Currently translated at 51.2% (222 of 433 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ar/
2020-06-17 22:41:44 +02:00
J-Jamet
e12f008b92 Merge branch 'develop' into feature/Button_Block_Autofill 2020-06-17 22:16:08 +02:00
J-Jamet
d064ece0ff Fix view flickering 2020-06-17 22:13:18 +02:00
J-Jamet
379fbf68b1 Fix special mode title 2020-06-17 21:54:59 +02:00
J-Jamet
83783c1a88 Better special mode implementation 2020-06-17 21:49:20 +02:00
J-Jamet
c7e46205b3 Encapsulate special mode view and add blocking menu for autofill 2020-06-17 21:29:28 +02:00
J-Jamet
0c61f0ded2 Better search info title 2020-06-17 20:22:17 +02:00
J-Jamet
49e2ec0498 Toolbar as SpecialModeView, show title 2020-06-17 20:01:45 +02:00
ihor_ck
fb0a74c101 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (433 of 433 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2020-06-16 20:41:43 +02:00
Renann Prado
245a7ddfe9 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (433 of 433 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pt_BR/
2020-06-14 23:19:30 +02:00
Stephan Paternotte
ca8874c2e1 Translated using Weblate (Dutch)
Currently translated at 99.5% (431 of 433 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nl/
2020-06-14 23:19:29 +02:00
Oliver
dbcd7c8e03 Translated using Weblate (German)
Currently translated at 100.0% (433 of 433 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-06-14 23:19:29 +02:00
J-Jamet
9cce63659e Fix selection mode and search with autofill 2020-06-13 23:18:39 +02:00
J-Jamet
be0bbab0c8 Add default values in Blocklists and input password as autofill hints 2020-06-13 17:01:59 +02:00
J-Jamet
7b6d3698c4 Add inputType as Hex 2020-06-13 15:20:24 +02:00
J-Jamet
56daca8b4f Fix default entry icon #589 2020-06-12 20:17:01 +02:00
J-Jamet
ed382d102e Fix backstack in selection mode, add cancel button #589 2020-06-12 19:57:01 +02:00
Filip Miletic
745de2502e Translated using Weblate (Croatian)
Currently translated at 71.5% (310 of 433 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/hr/
2020-06-11 04:41:42 +02:00
zeritti
503a4b1374 Translated using Weblate (Czech)
Currently translated at 100.0% (433 of 433 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2020-06-11 04:41:42 +02:00
J-Jamet
0b71b2d659 Fix populate Magikeyboard when URL is present 2020-06-10 20:50:55 +02:00
J-Jamet
2ad244df94 Update CHANGELOG 2020-06-10 20:43:16 +02:00
J-Jamet
d0da4f03a6 Search through subdomains as parameter #584 2020-06-10 20:40:01 +02:00
J-Jamet
ab0cd4152a Fix search and autofill performance 2020-06-10 20:25:54 +02:00
J-Jamet
93d04bfe60 Fix crash 2020-06-10 20:20:18 +02:00
J-Jamet
b1ccb40bd3 Upgrade CHANGELOG 2020-06-10 19:08:19 +02:00
J-Jamet
d177001ea8 Upgrade CHANGELOG 2020-06-10 19:03:28 +02:00
J-Jamet
2f921897c7 Block list to blocklist 2020-06-10 18:58:40 +02:00
J-Jamet
1a0f7146ce Merge branch 'feature/Autofill_Blocklist' #571 2020-06-10 18:53:53 +02:00
J-Jamet
dff2386594 Fix shrink 2020-06-10 18:47:10 +02:00
J-Jamet
55cc782cc6 Keep list during orientation change 2020-06-10 18:33:22 +02:00
J-Jamet
6903099873 Better block list algorithm 2020-06-10 18:16:37 +02:00
J-Jamet
6e2d84be33 Dialog input much better 2020-06-10 18:02:52 +02:00
J-Jamet
9e542d0bbe Dialog input much better 2020-06-10 17:52:35 +02:00
J-Jamet
ade9af9ecd Block list verification 2020-06-10 16:43:23 +02:00
J-Jamet
59f11a1b26 Distinct block lists for AppId and WebDomain 2020-06-10 15:40:04 +02:00
Stephan Paternotte
cc1d6e2b47 Translated using Weblate (Dutch)
Currently translated at 99.5% (431 of 433 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nl/
2020-06-09 22:41:42 +02:00
J-Jamet
2655b1b3d1 Fix blocklist views 2020-06-09 20:15:27 +02:00
J-Jamet
053dd28f8c Rename to blocklist and fix persistent element 2020-06-09 20:07:34 +02:00
J-Jamet
65e4cf83d8 First commit for autofill blocklist 2020-06-09 18:35:40 +02:00
Oğuz Ersen
419099318c Translated using Weblate (Turkish)
Currently translated at 100.0% (433 of 433 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-06-08 02:41:43 +02:00
Allan Nordhøy
972edd3a30 Translated using Weblate (Norwegian Bokmål)
Currently translated at 80.3% (348 of 433 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nb_NO/
2020-06-08 02:41:42 +02:00
Eric
cc4125e766 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (433 of 433 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2020-06-08 02:41:42 +02:00
ihor_ck
da40cc9830 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (433 of 433 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2020-06-08 02:41:41 +02:00
solokot
29d7e2dcfe Translated using Weblate (Russian)
Currently translated at 100.0% (433 of 433 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-06-06 11:58:57 +02:00
WaldiS
3d906fd582 Translated using Weblate (Polish)
Currently translated at 100.0% (433 of 433 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2020-06-06 11:58:56 +02:00
jan madsen
0cad43c18b Translated using Weblate (Danish)
Currently translated at 98.6% (427 of 433 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/da/
2020-06-06 11:58:56 +02:00
Hosted Weblate
c66b686a63 Merge branch 'origin/master' into Weblate. 2020-06-06 08:22:05 +02:00
J-Jamet
e2a1e3f327 Fix autofill for chrome 83.0.4103.96 #551 2020-06-05 22:56:00 +02:00
J-Jamet
2b5cf75a53 Update to 2.7 2020-06-05 15:46:25 +02:00
J-Jamet
1c350ac87b Merge tag '2.6' into develop
2.6
2020-06-05 14:31:39 +02:00
J-Jamet
ef6539909c Merge branch 'release/2.6' 2020-06-05 14:31:30 +02:00
J-Jamet
47d7c6fe65 Fix could not read credentials 2020-06-05 14:04:30 +02:00
J-Jamet
c94c5fbc95 Replace KeePass DX by KeePassDX 2020-06-05 13:20:09 +02:00
J-Jamet
63a833d114 Remove beta_dontask 2020-06-05 13:12:03 +02:00
J-Jamet
72162128e2 Fix strings 2020-06-05 12:56:48 +02:00
Kunzisoft
a8f712c335 Translated using Weblate (Telugu)
Currently translated at 1.8% (8 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/te/
2020-06-05 12:41:42 +02:00
Kunzisoft
ea8888a685 Translated using Weblate (Galician)
Currently translated at 6.7% (29 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/gl/
2020-06-05 12:41:42 +02:00
Kunzisoft
2aecf69b67 Translated using Weblate (Norwegian Nynorsk)
Currently translated at 14.5% (63 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nn/
2020-06-05 12:41:42 +02:00
Kunzisoft
1a4c24dd86 Translated using Weblate (Latvian)
Currently translated at 16.2% (70 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/lv/
2020-06-05 12:41:41 +02:00
Kunzisoft
6cf2b45051 Translated using Weblate (Lithuanian)
Currently translated at 12.7% (55 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/lt/
2020-06-05 12:41:41 +02:00
Kunzisoft
38dd2bdf6e Translated using Weblate (Finnish)
Currently translated at 20.1% (87 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fi/
2020-06-05 12:41:41 +02:00
Kunzisoft
8784f1da70 Translated using Weblate (Basque)
Currently translated at 15.7% (68 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/eu/
2020-06-05 12:41:41 +02:00
Kunzisoft
b9208ea94e Translated using Weblate (Catalan)
Currently translated at 59.7% (258 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ca/
2020-06-05 12:41:41 +02:00
J-Jamet
dfb648b480 Merge branch 'master' of https://hosted.weblate.org/projects/keepass-dx/strings into translations 2020-06-05 11:31:40 +02:00
J-Jamet
f7af4f06ea Add short Toast after populate Magikeyboard 2020-06-03 19:24:05 +02:00
Destiny Li
d98f9eb62c Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (432 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2020-06-03 08:41:41 +02:00
Jörgen Sjöbom
fef1335f51 Translated using Weblate (Swedish)
Currently translated at 85.8% (371 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/sv/
2020-06-03 08:41:41 +02:00
J. Lavoie
59f14cbdd4 Translated using Weblate (Italian)
Currently translated at 96.2% (416 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-06-03 08:41:40 +02:00
J. Lavoie
e8645c543f Translated using Weblate (French)
Currently translated at 100.0% (432 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2020-06-03 08:41:39 +02:00
Filippo De Bortoli
b92f6177e3 Translated using Weblate (Italian)
Currently translated at 95.6% (413 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-06-02 07:41:30 +02:00
J. Lavoie
2888829a4f Translated using Weblate (Italian)
Currently translated at 95.6% (413 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/it/
2020-06-02 07:41:30 +02:00
J-Jamet
3d392ead19 Try to fix biometric prompt flickering 2020-06-01 21:16:58 +02:00
J-Jamet
a79b2bfa79 Merge branch 'develop' into TacoTheDank-develop 2020-06-01 13:59:56 +02:00
J-Jamet
15e1e2f02e Remove apache commons-io lib dependencies 2020-06-01 13:55:17 +02:00
J-Jamet
9e652803d0 Merge branch 'develop' of git://github.com/TacoTheDank/KeePassDX into TacoTheDank-develop 2020-06-01 12:07:10 +02:00
J-Jamet
7795fceb72 Merge branch 'mattiasduerrmeier-master' into develop 2020-05-31 16:32:05 +02:00
J-Jamet
9f01f26ea6 Merge branch 'master' of git://github.com/mattiasduerrmeier/KeePassDX into mattiasduerrmeier-master 2020-05-31 16:31:07 +02:00
TacoTheDank
abbc9a1d7a Update firamono font 2020-05-29 22:53:53 -04:00
TacoTheDank
2c15befb8e Update many dependencies 2020-05-29 22:35:53 -04:00
TacoTheDank
ba8ea84c4e Update Studio, use Kotlin JDK8 2020-05-29 21:25:59 -04:00
TacoTheDank
97912046da Update gradle wrapper 2020-05-29 21:21:57 -04:00
mattiasduerrmeier
43e99c23e3 Update strings.xml 2020-05-29 10:35:55 +02:00
mattiasduerrmeier
ffe14d75fc update : delete password description
I didn't quite understand what the delete password settings does, and I found the description not to be complete.
I think changing the description could make it clearer. 
I thought about adding "to an existing database", but I wanted to keep it short.
2020-05-28 15:40:25 +02:00
ButterflyOfFire
872ef66641 Translated using Weblate (Arabic)
Currently translated at 50.0% (216 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ar/
2020-05-28 10:41:37 +02:00
J-Jamet
6363862ec2 Fix Autofill for in-app purchases #529 2020-05-27 13:48:46 +02:00
J-Jamet
775a112e83 Fix Magikeyboard delete key 2020-05-27 13:01:06 +02:00
J-Jamet
7168904290 Fix node selection color 2020-05-27 12:28:58 +02:00
Stephan Paternotte
4213209b08 Translated using Weblate (Dutch)
Currently translated at 99.5% (430 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nl/
2020-05-27 08:41:37 +02:00
Oymate
5dce91b7f6 Translated using Weblate (Bengali (Bangladesh))
Currently translated at 4.6% (20 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/bn_BD/
2020-05-25 23:17:27 +02:00
Eric
6d7fb9f87c Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (432 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2020-05-25 23:17:26 +02:00
ihor_ck
cc6c9dd8d1 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (432 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2020-05-25 23:17:26 +02:00
Allan Nordhøy
21ebec52f3 Translated using Weblate (Greek)
Currently translated at 99.3% (429 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/el/
2020-05-25 23:17:26 +02:00
C. Rüdinger
11023ab225 Translated using Weblate (German)
Currently translated at 100.0% (432 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-05-25 23:17:26 +02:00
scootergrisen
fe97b15905 Translated using Weblate (Danish)
Currently translated at 97.6% (422 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/da/
2020-05-25 23:17:25 +02:00
J-Jamet
de8738aa03 Default group icon for a new entry #293 2020-05-25 19:36:36 +02:00
J-Jamet
568bbf9126 Upgrade CHANGELOG 2020-05-25 19:06:57 +02:00
J-Jamet
a2481652da Better Autofill recognition #564 2020-05-25 19:03:33 +02:00
Aurel F
33e3d3272d Translated using Weblate (Romanian)
Currently translated at 92.8% (401 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ro/
2020-05-24 11:41:46 +02:00
Stephan Paternotte
b909651c29 Translated using Weblate (Dutch)
Currently translated at 99.5% (430 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nl/
2020-05-24 11:41:45 +02:00
J-Jamet
16794c5252 Merge branch 'feature/ShareTarget' into develop 2020-05-23 18:23:42 +02:00
J-Jamet
49ad270d88 Remove keyboard entry when no info to fill
Remove toast
2020-05-23 18:17:01 +02:00
J-Jamet
df9b6cb7e8 Revert "Fix back stack"
This reverts commit 797dc706e2.
2020-05-23 15:57:39 +02:00
J-Jamet
c6c4551928 Fix small string 2020-05-23 15:45:56 +02:00
J-Jamet
de84353eb0 Add MagikeyboardLauncherActivity 2020-05-23 15:34:04 +02:00
J-Jamet
6f05b80f34 Remove exported for EntrySelectionLauncherActivity 2020-05-23 15:02:45 +02:00
J-Jamet
797dc706e2 Fix back stack 2020-05-23 15:01:34 +02:00
J-Jamet
bdb615bcf9 Fix readonly and search after orientation change 2020-05-23 14:12:33 +02:00
J-Jamet
1b98717b0e Fix readonly and search after orientation change 2020-05-23 13:59:24 +02:00
J-Jamet
7bd1aedada Search improvement 2020-05-23 12:59:05 +02:00
J-Jamet
34bf8f9d1f Fix flickering during share 2020-05-23 10:48:36 +02:00
J-Jamet
b07f70e9fe Fix Share search without Magikeyboard 2020-05-22 22:01:10 +02:00
J-Jamet
e635788955 Add standard search 2020-05-22 13:22:09 +02:00
ihor_ck
bdb1cef3e5 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (432 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2020-05-22 11:58:34 +02:00
zeritti
e5a32e65c0 Translated using Weblate (Czech)
Currently translated at 100.0% (432 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2020-05-22 11:58:33 +02:00
J-Jamet
5fc77922b4 Auto search entry by share to populate keyboard 2020-05-21 14:54:14 +02:00
J-Jamet
ce8add2895 Upgrade CHANGELOG 2020-05-21 12:29:28 +02:00
J-Jamet
88e1e5b770 Fix background theme color 2020-05-21 11:52:06 +02:00
J-Jamet
76ecbd3497 Revert NotificationService to keep notification in API23 2020-05-21 11:39:17 +02:00
J-Jamet
e33c9b932f LockReceiver in onCreate NotificationService 2020-05-20 20:00:12 +02:00
J-Jamet
038f6caa04 Fix notification hide 2020-05-20 19:01:19 +02:00
Oymate
36f5249d71 Translated using Weblate (Bengali (Bangladesh))
Currently translated at 0.9% (4 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/bn_BD/
2020-05-20 17:41:38 +02:00
Oğuz Ersen
570702a5bd Translated using Weblate (Turkish)
Currently translated at 100.0% (432 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-05-20 17:41:38 +02:00
Andrew
5d03c9c644 Translated using Weblate (English)
Currently translated at 100.0% (432 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/en/
2020-05-20 17:41:38 +02:00
Dwhite Reeves
83906def4a Translated using Weblate (Chinese (Simplified))
Currently translated at 99.7% (431 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2020-05-20 17:41:37 +02:00
ihor_ck
33e0f25fb1 Translated using Weblate (Ukrainian)
Currently translated at 99.7% (431 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2020-05-20 17:41:37 +02:00
solokot
2080de4139 Translated using Weblate (Russian)
Currently translated at 100.0% (432 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-05-20 17:41:36 +02:00
WaldiS
decaca889c Translated using Weblate (Polish)
Currently translated at 100.0% (432 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2020-05-20 17:41:36 +02:00
Anonymous
794a39032f Translated using Weblate (Finnish)
Currently translated at 20.1% (87 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fi/
2020-05-20 17:41:36 +02:00
Jami Kettunen
cc3cf17060 Translated using Weblate (Finnish)
Currently translated at 20.1% (87 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fi/
2020-05-20 17:41:35 +02:00
C. Rüdinger
b07da4bfa8 Translated using Weblate (German)
Currently translated at 100.0% (432 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-05-20 17:41:35 +02:00
J-Jamet
4f52a4ee79 Fix biometric prompt - better code implementation #554 2020-05-20 17:30:50 +02:00
J-Jamet
cf77b999a3 Fix biometric prompt auto open after orientation change #554 2020-05-20 16:24:06 +02:00
J-Jamet
c9f062bdd9 Fix biometric prompt auto open after activity result #554 2020-05-20 15:27:34 +02:00
J-Jamet
12669f7ea0 Fix biometric prompt auto open after lock #554 2020-05-20 15:19:10 +02:00
J-Jamet
03451d2a6e Remove unused @JvmOverloads 2020-05-20 13:31:23 +02:00
J-Jamet
b5d7595f87 Try to fix service bug 2020-05-20 12:03:54 +02:00
J-Jamet
0d3d760a43 Try to fix custom field bug 2020-05-20 11:36:19 +02:00
J-Jamet
1cfc86e5ce Fix auto biometric prompt in background #554 2020-05-20 11:09:45 +02:00
J-Jamet
938343323d Shorter message for invalid credentials 2020-05-19 21:44:40 +02:00
Oymate
37112715c0 Added translation using Weblate (Bengali (Bangladesh)) 2020-05-19 17:08:25 +02:00
Andrew
bc80c10193 Translated using Weblate (Russian)
Currently translated at 99.7% (431 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-05-18 13:56:29 +02:00
J-Jamet
d989f48226 Fix unwanted opening of the dialog task #187 2020-05-17 14:19:52 +02:00
J-Jamet
45bcbb3a3d Fix entry not visually deleted in search #559 2020-05-16 19:06:30 +02:00
Oğuz Ersen
f4a74e0254 Translated using Weblate (Turkish)
Currently translated at 100.0% (432 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-05-16 06:41:36 +02:00
Ashley Ouding
ace83cf68d Translated using Weblate (English)
Currently translated at 100.0% (432 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/en/
2020-05-16 06:41:36 +02:00
Eric
209b9b9a6f Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (432 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2020-05-16 06:41:36 +02:00
ihor_ck
0d9dd6a33e Translated using Weblate (Ukrainian)
Currently translated at 100.0% (432 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/uk/
2020-05-16 06:41:35 +02:00
WaldiS
e4137a031e Translated using Weblate (Polish)
Currently translated at 100.0% (432 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/pl/
2020-05-16 06:41:35 +02:00
Anonymous
41e9ea7e4f Translated using Weblate (Japanese)
Currently translated at 44.4% (192 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-05-16 06:41:35 +02:00
librada
1a8b88973d Translated using Weblate (Japanese)
Currently translated at 44.4% (192 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ja/
2020-05-16 06:41:35 +02:00
zykure
3109e251b9 Translated using Weblate (German)
Currently translated at 100.0% (432 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/de/
2020-05-16 06:41:34 +02:00
zeritti
452ab280f1 Translated using Weblate (Czech)
Currently translated at 100.0% (432 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/cs/
2020-05-16 06:41:33 +02:00
solokot
34ecfbb846 Translated using Weblate (Russian)
Currently translated at 99.7% (431 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-05-14 10:01:38 +02:00
Andrew
11fb97d275 Translated using Weblate (Russian)
Currently translated at 99.7% (431 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-05-14 10:01:38 +02:00
Hosted Weblate
4bb30d075b Merge branch 'origin/master' into Weblate. 2020-05-12 09:06:25 +02:00
Oğuz Ersen
f38af55c05 Translated using Weblate (Turkish)
Currently translated at 100.0% (432 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/tr/
2020-05-11 22:01:00 +02:00
Allan Nordhøy
8a007376cc Translated using Weblate (Norwegian Bokmål)
Currently translated at 78.0% (337 of 432 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/nb_NO/
2020-05-11 22:01:00 +02:00
J-Jamet
940a1dfc78 Upgrade to versionCode 34 2020-05-10 20:07:58 +02:00
J-Jamet
cbd64d1602 Merge tag '2.5' into develop
2.5
2020-05-10 19:32:48 +02:00
134 changed files with 2927 additions and 1041 deletions

View File

@@ -1,3 +1,19 @@
KeePassDX(2.7)
* Add blocklists for autofill
* Add autofill compatibility mode (usefull for Browser not compatible)
* Upgrade autofill recognition algorithm
* Setting to search through web subdomains
* Refactoring selection mode
KeePassDX(2.6)
* Share a web domain to automatically search for an entry
* Default group icon for a new entry
* Better autofill recognition
* Fix entry not visually deleted in search
* Fix hanged loading dialog
* Fix auto open biometric prompt if comes from background
* Minor fixes
KeePassDX(2.5)
* First stable version of KeePassDX
* Fork completely rewritten from the KeePassDroid project

View File

@@ -11,8 +11,8 @@ android {
applicationId "com.kunzisoft.keepass"
minSdkVersion 14
targetSdkVersion 29
versionCode = 33
versionName = "2.5"
versionCode = 35
versionName = "2.7"
multiDexEnabled true
testApplicationId = "com.kunzisoft.keepass.tests"
@@ -42,9 +42,6 @@ android {
}
}
dexOptions {
}
flavorDimensions "version"
productFlavors {
libre {
@@ -72,7 +69,7 @@ android {
buildConfigField "String", "BUILD_VERSION", "\"free\""
buildConfigField "boolean", "FULL_VERSION", "false"
buildConfigField "boolean", "CLOSED_STORE", "true"
buildConfigField "String[]", "STYLES_DISABLED", "{\"KeepassDXStyle_Dark\",\"KeepassDXStyle_Blue\",\"KeepassDXStyle_Red\",\"KeepassDXStyle_Purple\"}"
buildConfigField "String[]", "STYLES_DISABLED", "{}"
buildConfigField "String[]", "ICON_PACKS_DISABLED", "{}"
manifestPlaceholders = [ googleAndroidBackupAPIKey:"AEdPqrEAAAAIbRfbV8fHLItXo8OcHwrO0sSNblqhPwkc0DPTqg" ]
}
@@ -88,42 +85,44 @@ android {
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}
def room_version = "2.2.5"
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.preference:preference:1.1.1'
implementation 'androidx.legacy:legacy-preference-v14:1.0.0'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.documentfile:documentfile:1.0.1'
implementation 'androidx.biometric:biometric:1.0.1'
implementation "androidx.core:core-ktx:1.2.0"
implementation 'androidx.core:core-ktx:1.2.0'
// To upgrade with style
implementation 'com.google.android.material:material:1.0.0'
// Database
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
// Crypto
implementation 'org.bouncycastle:bcprov-jdk15on:1.65'
implementation 'org.bouncycastle:bcprov-jdk15on:1.65.01'
// Time
implementation 'joda-time:joda-time:2.9.9'
implementation 'joda-time:joda-time:2.10.6'
// Color
implementation 'com.github.Kunzisoft:AndroidClearChroma:2.3'
// Education
implementation 'com.getkeepsafe.taptargetview:taptargetview:1.13.0'
// Apache Commons Collections
implementation 'commons-collections:commons-collections:3.2.1'
implementation 'org.apache.commons:commons-io:1.3.2'
implementation 'commons-collections:commons-collections:3.2.2'
// Apache Commons Codec
implementation 'commons-codec:commons-codec:1.11'
implementation 'commons-codec:commons-codec:1.14'
// Icon pack
implementation project(path: ':icon-pack-classic')
implementation project(path: ':icon-pack-material')
// Tests
androidTestImplementation 'junit:junit:4.12'
androidTestImplementation 'junit:junit:4.13'
}

View File

@@ -131,16 +131,30 @@
android:name="com.kunzisoft.keepass.activities.AboutActivity"
android:launchMode="singleTask"
android:label="@string/about" />
<activity android:name="com.kunzisoft.keepass.settings.SettingsActivity" />
<activity android:name="com.kunzisoft.keepass.autofill.AutofillLauncherActivity"
<activity
android:name="com.kunzisoft.keepass.settings.SettingsActivity" />
<activity
android:name="com.kunzisoft.keepass.activities.AutofillLauncherActivity"
android:theme="@style/Theme.Transparent"
android:configChanges="keyboardHidden" />
<activity android:name="com.kunzisoft.keepass.settings.SettingsAdvancedUnlockActivity" />
<activity android:name="com.kunzisoft.keepass.settings.AutofillSettingsActivity" />
<activity android:name="com.kunzisoft.keepass.magikeyboard.KeyboardLauncherActivity"
android:label="@string/keyboard_name"
android:exported="true">
<activity
android:name="com.kunzisoft.keepass.settings.SettingsAdvancedUnlockActivity" />
<activity
android:name="com.kunzisoft.keepass.settings.AutofillSettingsActivity" />
<activity
android:name="com.kunzisoft.keepass.activities.EntrySelectionLauncherActivity"
android:theme="@style/Theme.Transparent">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
<activity android:name="com.kunzisoft.keepass.settings.MagikeyboardSettingsActivity"
<activity
android:name="com.kunzisoft.keepass.activities.MagikeyboardLauncherActivity"
android:theme="@style/Theme.Transparent" />
<activity
android:name="com.kunzisoft.keepass.settings.MagikeyboardSettingsActivity"
android:label="@string/keyboard_setting_label">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>

View File

@@ -17,7 +17,7 @@
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.autofill
package com.kunzisoft.keepass.activities
import android.app.Activity
import android.app.PendingIntent
@@ -26,27 +26,45 @@ import android.content.Intent
import android.content.IntentSender
import android.os.Build
import android.os.Bundle
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import com.kunzisoft.keepass.activities.FileDatabaseSelectActivity
import com.kunzisoft.keepass.activities.GroupActivity
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.autofill.AutofillHelper
import com.kunzisoft.keepass.autofill.KeeAutofillService
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.search.SearchHelper
import com.kunzisoft.keepass.model.SearchInfo
import com.kunzisoft.keepass.settings.PreferencesUtil
@RequiresApi(api = Build.VERSION_CODES.O)
class AutofillLauncherActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// Build search param
val searchInfo = SearchInfo().apply {
applicationId = intent.getStringExtra(KEY_SEARCH_APPLICATION_ID)
webDomain = intent.getStringExtra(KEY_SEARCH_DOMAIN)
}
// Pass extra for Autofill (EXTRA_ASSIST_STRUCTURE)
val assistStructure = AutofillHelper.retrieveAssistStructure(intent)
if (assistStructure != null) {
// Build search param
val searchInfo = SearchInfo().apply {
applicationId = intent.getStringExtra(KEY_SEARCH_APPLICATION_ID)
webDomain = intent.getStringExtra(KEY_SEARCH_DOMAIN)
}
if (assistStructure == null) {
setResult(Activity.RESULT_CANCELED)
finish()
} else if (!KeeAutofillService.searchAllowedFor(searchInfo.applicationId,
PreferencesUtil.applicationIdBlocklist(this))
|| !KeeAutofillService.searchAllowedFor(searchInfo.webDomain,
PreferencesUtil.webDomainBlocklist(this))) {
// If item not allowed, show a toast
Toast.makeText(this.applicationContext, R.string.autofill_block_restart, Toast.LENGTH_LONG).show()
setResult(Activity.RESULT_CANCELED)
finish()
} else {
// If database is open
AutofillHelper.checkAutoSearchInfo(this,
SearchHelper.checkAutoSearchInfo(this,
Database.getInstance(),
searchInfo,
{ items ->
@@ -57,17 +75,17 @@ class AutofillLauncherActivity : AppCompatActivity() {
{
// Show the database UI to select the entry
GroupActivity.launchForAutofillResult(this,
assistStructure)
assistStructure,
false,
searchInfo)
},
{
// If database not open
FileDatabaseSelectActivity.launchForAutofillResult(this,
assistStructure, searchInfo)
assistStructure,
searchInfo)
}
)
} else {
setResult(Activity.RESULT_CANCELED)
finish()
}
super.onCreate(savedInstanceState)

View File

@@ -43,6 +43,7 @@ import com.kunzisoft.keepass.database.element.DateInstant
import com.kunzisoft.keepass.database.element.Entry
import com.kunzisoft.keepass.database.element.Group
import com.kunzisoft.keepass.database.element.icon.IconImage
import com.kunzisoft.keepass.database.element.icon.IconImageStandard
import com.kunzisoft.keepass.database.element.node.NodeId
import com.kunzisoft.keepass.education.EntryEditActivityEducation
import com.kunzisoft.keepass.notifications.ClipboardEntryNotificationService
@@ -166,9 +167,16 @@ class EntryEditActivity : LockingActivity(),
mNewEntry = mDatabase?.createEntry()
}
mParent = mDatabase?.getGroupById(it)
// Add the default icon
mDatabase?.drawFactory?.let { iconFactory ->
entryEditContentsView?.setDefaultIcon(iconFactory)
// Add the default icon from parent if not a folder
val parentIcon = mParent?.icon
if (parentIcon != null
&& parentIcon.iconId != IconImage.UNKNOWN_ID
&& parentIcon.iconId != IconImageStandard.FOLDER) {
temporarilySaveAndShowSelectedIcon(parentIcon)
} else {
mDatabase?.drawFactory?.let { iconFactory ->
entryEditContentsView?.setDefaultIcon(iconFactory)
}
}
}

View File

@@ -0,0 +1,130 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePassDX.
*
* KeePassDX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* KeePassDX is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.activities
import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.search.SearchHelper
import com.kunzisoft.keepass.magikeyboard.MagikIME
import com.kunzisoft.keepass.model.EntryInfo
import com.kunzisoft.keepass.model.SearchInfo
import com.kunzisoft.keepass.settings.PreferencesUtil
/**
* Activity to search or select entry in database,
* Commonly used with Magikeyboard
*/
class EntrySelectionLauncherActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
var sharedWebDomain: String? = null
when (intent?.action) {
Intent.ACTION_SEND -> {
if ("text/plain" == intent.type) {
// Retrieve web domain
intent.getStringExtra(Intent.EXTRA_TEXT)?.let {
sharedWebDomain = Uri.parse(it).host
}
}
}
else -> {}
}
// Setting to integrate Magikeyboard
val searchShareForMagikeyboard = PreferencesUtil.isKeyboardSearchShareEnable(this)
// Build search param
val searchInfo = SearchInfo().apply {
webDomain = sharedWebDomain
}
// If database is open
SearchHelper.checkAutoSearchInfo(this,
Database.getInstance(),
searchInfo,
{ items ->
// Items found
if (searchShareForMagikeyboard) {
if (items.size == 1) {
// Automatically populate keyboard
val entryPopulate = items[0]
populateKeyboardAndMoveAppToBackground(this,
entryPopulate,
intent)
} else {
// Select the one we want
GroupActivity.launchForEntrySelectionResult(this,
true,
searchInfo)
}
} else {
GroupActivity.launch(this,
true,
searchInfo)
}
},
{
// Show the database UI to select the entry
if (searchShareForMagikeyboard) {
GroupActivity.launchForEntrySelectionResult(this,
false,
searchInfo)
} else {
GroupActivity.launch(this,
false,
searchInfo)
}
},
{
// If database not open
if (searchShareForMagikeyboard) {
FileDatabaseSelectActivity.launchForEntrySelectionResult(this,
searchInfo)
} else {
FileDatabaseSelectActivity.launch(this,
searchInfo)
}
}
)
finish()
super.onCreate(savedInstanceState)
}
}
fun populateKeyboardAndMoveAppToBackground(activity: Activity,
entry: EntryInfo,
intent: Intent,
toast: Boolean = true) {
// Populate Magikeyboard with entry
MagikIME.addEntryAndLaunchNotificationIfAllowed(activity, entry, toast)
// Consume the selection mode
EntrySelectionHelper.removeEntrySelectionModeFromIntent(intent)
activity.moveTaskToBack(true)
}

View File

@@ -22,6 +22,7 @@ package com.kunzisoft.keepass.activities
import android.annotation.SuppressLint
import android.app.Activity
import android.app.assist.AssistStructure
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
@@ -41,12 +42,12 @@ import com.google.android.material.snackbar.Snackbar
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.dialogs.AssignMasterKeyDialogFragment
import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper
import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper.KEY_SEARCH_INFO
import com.kunzisoft.keepass.activities.helpers.OpenFileHelper
import com.kunzisoft.keepass.activities.stylish.StylishActivity
import com.kunzisoft.keepass.activities.selection.SpecialModeActivity
import com.kunzisoft.keepass.adapters.FileDatabaseHistoryAdapter
import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction
import com.kunzisoft.keepass.autofill.AutofillHelper
import com.kunzisoft.keepass.autofill.AutofillHelper.KEY_SEARCH_INFO
import com.kunzisoft.keepass.database.action.ProgressDialogThread
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.education.FileDatabaseSelectActivityEducation
@@ -58,13 +59,14 @@ import com.kunzisoft.keepass.view.asError
import kotlinx.android.synthetic.main.activity_file_selection.*
import java.io.FileNotFoundException
class FileDatabaseSelectActivity : StylishActivity(),
class FileDatabaseSelectActivity : SpecialModeActivity(),
AssignMasterKeyDialogFragment.AssignPasswordDialogListener {
// Views
private var coordinatorLayout: CoordinatorLayout? = null
private var fileManagerExplanationButton: View? = null
private var createButtonView: View? = null
private var databaseButtonsContainerView: View? = null
private var createDatabaseButtonView: View? = null
private var openDatabaseButtonView: View? = null
// Adapter to manage database history list
@@ -95,19 +97,13 @@ class FileDatabaseSelectActivity : StylishActivity(),
UriUtil.gotoUrl(this, R.string.file_manager_explanation_url)
}
// Create button
createButtonView = findViewById(R.id.create_database_button)
if (allowCreateDocumentByStorageAccessFramework(packageManager)) {
// There is an activity which can handle this intent.
createButtonView?.visibility = View.VISIBLE
}
else{
// No Activity found that can handle this intent.
createButtonView?.visibility = View.GONE
}
databaseButtonsContainerView = findViewById(R.id.database_buttons_container)
createButtonView?.setOnClickListener { createNewFile() }
// Create database button
createDatabaseButtonView = findViewById(R.id.create_database_button)
createDatabaseButtonView?.setOnClickListener { createNewFile() }
// Open database button
mOpenFileHelper = OpenFileHelper(this)
openDatabaseButtonView = findViewById(R.id.open_keyfile_button)
openDatabaseButtonView?.apply {
@@ -156,7 +152,7 @@ class FileDatabaseSelectActivity : StylishActivity(),
UriUtil.parse(databasePath)?.let { databaseFileUri ->
launchPasswordActivityWithPath(databaseFileUri)
} ?: run {
Log.i(TAG, "Unable to launch Password Activity")
Log.i(TAG, "No default database to prepare")
}
}
@@ -196,23 +192,30 @@ class FileDatabaseSelectActivity : StylishActivity(),
}
private fun launchPasswordActivity(databaseUri: Uri, keyFile: Uri?) {
val searchInfo: SearchInfo? = intent.getParcelableExtra(KEY_SEARCH_INFO)
EntrySelectionHelper.doEntrySelectionAction(intent,
{
try {
PasswordActivity.launch(this@FileDatabaseSelectActivity,
databaseUri, keyFile)
databaseUri, keyFile,
searchInfo)
} catch (e: FileNotFoundException) {
fileNoFoundAction(e)
}
// Remove the search info from intent
if (searchInfo != null) {
finish()
}
},
{
try {
PasswordActivity.launchForKeyboardResult(this@FileDatabaseSelectActivity,
databaseUri, keyFile)
finish()
databaseUri, keyFile,
searchInfo)
} catch (e: FileNotFoundException) {
fileNoFoundAction(e)
}
finish()
},
{ assistStructure ->
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
@@ -220,23 +223,27 @@ class FileDatabaseSelectActivity : StylishActivity(),
PasswordActivity.launchForAutofillResult(this@FileDatabaseSelectActivity,
databaseUri, keyFile,
assistStructure,
intent.getParcelableExtra(KEY_SEARCH_INFO))
searchInfo)
} catch (e: FileNotFoundException) {
fileNoFoundAction(e)
}
}
})
}
private fun launchGroupActivity(readOnly: Boolean) {
val searchInfo: SearchInfo? = intent.getParcelableExtra(KEY_SEARCH_INFO)
EntrySelectionHelper.doEntrySelectionAction(intent,
{
GroupActivity.launch(this@FileDatabaseSelectActivity,
false,
searchInfo,
readOnly)
},
{
GroupActivity.launchForKeyboardSelection(this@FileDatabaseSelectActivity,
GroupActivity.launchForEntrySelectionResult(this@FileDatabaseSelectActivity,
false,
searchInfo,
readOnly)
// Do not keep history
finish()
@@ -245,7 +252,8 @@ class FileDatabaseSelectActivity : StylishActivity(),
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
GroupActivity.launchForAutofillResult(this@FileDatabaseSelectActivity,
assistStructure,
intent.getParcelableExtra(KEY_SEARCH_INFO),
false,
searchInfo,
readOnly)
}
})
@@ -259,37 +267,52 @@ class FileDatabaseSelectActivity : StylishActivity(),
}
override fun onResume() {
super.onResume()
// Show open and create button or special mode
if (mSelectionMode) {
// Disable buttons if in selection mode or request for autofill
databaseButtonsContainerView?.visibility = View.GONE
} else {
if (allowCreateDocumentByStorageAccessFramework(packageManager)) {
// 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
}
databaseButtonsContainerView?.visibility = View.VISIBLE
}
val database = Database.getInstance()
if (database.loaded) {
launchGroupActivity(database.isReadOnly)
}
super.onResume()
// Construct adapter with listeners
if (PreferencesUtil.showRecentFiles(this)) {
mFileDatabaseHistoryAction?.getAllFileDatabaseHistories { databaseFileHistoryList ->
databaseFileHistoryList?.let { historyList ->
val hideBrokenLocations = PreferencesUtil.hideBrokenLocations(this@FileDatabaseSelectActivity)
mAdapterDatabaseHistory?.addDatabaseFileHistoryList(
// Show only uri accessible
historyList.filter {
if (hideBrokenLocations) {
FileDatabaseInfo(this@FileDatabaseSelectActivity,
it.databaseUri).exists
} else
true
})
mAdapterDatabaseHistory?.notifyDataSetChanged()
}
}
} else {
mAdapterDatabaseHistory?.clearDatabaseFileHistoryList()
mAdapterDatabaseHistory?.notifyDataSetChanged()
}
// Construct adapter with listeners
if (PreferencesUtil.showRecentFiles(this)) {
mFileDatabaseHistoryAction?.getAllFileDatabaseHistories { databaseFileHistoryList ->
databaseFileHistoryList?.let { historyList ->
val hideBrokenLocations = PreferencesUtil.hideBrokenLocations(this@FileDatabaseSelectActivity)
mAdapterDatabaseHistory?.addDatabaseFileHistoryList(
// Show only uri accessible
historyList.filter {
if (hideBrokenLocations) {
FileDatabaseInfo(this@FileDatabaseSelectActivity,
it.databaseUri).exists
} else
true
})
mAdapterDatabaseHistory?.notifyDataSetChanged()
}
}
} else {
mAdapterDatabaseHistory?.clearDatabaseFileHistoryList()
mAdapterDatabaseHistory?.notifyDataSetChanged()
}
// Register progress task
mProgressDialogThread?.registerProgressTask()
// Register progress task
mProgressDialogThread?.registerProgressTask()
}
}
override fun onPause() {
@@ -368,7 +391,10 @@ class FileDatabaseSelectActivity : StylishActivity(),
override fun onCreateOptionsMenu(menu: Menu): Boolean {
super.onCreateOptionsMenu(menu)
MenuUtil.defaultMenuInflater(menuInflater, menu)
if (!mSelectionMode) {
MenuUtil.defaultMenuInflater(menuInflater, menu)
}
Handler().post { performedNextEducation(FileDatabaseSelectActivityEducation(this)) }
@@ -377,11 +403,11 @@ class FileDatabaseSelectActivity : StylishActivity(),
private fun performedNextEducation(fileDatabaseSelectActivityEducation: FileDatabaseSelectActivityEducation) {
// If no recent files
val createDatabaseEducationPerformed = createButtonView != null && createButtonView!!.visibility == View.VISIBLE
val createDatabaseEducationPerformed = createDatabaseButtonView != null && createDatabaseButtonView!!.visibility == View.VISIBLE
&& mAdapterDatabaseHistory != null
&& mAdapterDatabaseHistory!!.itemCount > 0
&& fileDatabaseSelectActivityEducation.checkAndPerformedCreateDatabaseEducation(
createButtonView!!,
createDatabaseButtonView!!,
{
createNewFile()
},
@@ -416,18 +442,30 @@ class FileDatabaseSelectActivity : StylishActivity(),
/*
* -------------------------
* No Standard Launch, pass by PasswordActivity
* Launch only to standard search, else pass by PasswordActivity
* -------------------------
*/
fun launch(context: Context,
searchInfo: SearchInfo? = null) {
val intent = Intent(context, FileDatabaseSelectActivity::class.java)
searchInfo?.let {
intent.putExtra(KEY_SEARCH_INFO, it)
}
context.startActivity(intent)
}
/*
* -------------------------
* Keyboard Launch
* -------------------------
*/
fun launchForKeyboardSelection(activity: Activity) {
EntrySelectionHelper.startActivityForEntrySelection(activity, Intent(activity, FileDatabaseSelectActivity::class.java))
fun launchForEntrySelectionResult(activity: Activity,
searchInfo: SearchInfo? = null) {
EntrySelectionHelper.startActivityForEntrySelectionResult(activity,
Intent(activity, FileDatabaseSelectActivity::class.java),
searchInfo)
}
/*
@@ -439,7 +477,7 @@ class FileDatabaseSelectActivity : StylishActivity(),
@RequiresApi(api = Build.VERSION_CODES.O)
fun launchForAutofillResult(activity: Activity,
assistStructure: AssistStructure,
searchInfo: SearchInfo?) {
searchInfo: SearchInfo? = null) {
AutofillHelper.startActivityForAutofillResult(activity,
Intent(activity, FileDatabaseSelectActivity::class.java),
assistStructure,

View File

@@ -47,6 +47,7 @@ import com.kunzisoft.keepass.activities.dialogs.GroupEditDialogFragment
import com.kunzisoft.keepass.activities.dialogs.IconPickerDialogFragment
import com.kunzisoft.keepass.activities.dialogs.SortDialogFragment
import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper
import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper.KEY_SEARCH_INFO
import com.kunzisoft.keepass.activities.helpers.ReadOnlyHelper
import com.kunzisoft.keepass.activities.lock.LockingActivity
import com.kunzisoft.keepass.adapters.SearchEntryCursorAdapter
@@ -61,8 +62,8 @@ import com.kunzisoft.keepass.database.element.node.NodeId
import com.kunzisoft.keepass.database.element.node.Type
import com.kunzisoft.keepass.education.GroupActivityEducation
import com.kunzisoft.keepass.icons.assignDatabaseIcon
import com.kunzisoft.keepass.magikeyboard.MagikIME
import com.kunzisoft.keepass.model.SearchInfo
import com.kunzisoft.keepass.model.getSearchString
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_COPY_NODES_TASK
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_CREATE_GROUP_TASK
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_DELETE_NODES_TASK
@@ -74,10 +75,7 @@ import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Compa
import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.timeout.TimeoutHelper
import com.kunzisoft.keepass.utils.MenuUtil
import com.kunzisoft.keepass.view.AddNodeButtonView
import com.kunzisoft.keepass.view.ToolbarAction
import com.kunzisoft.keepass.view.asError
import com.kunzisoft.keepass.view.showActionError
import com.kunzisoft.keepass.view.*
class GroupActivity : LockingActivity(),
GroupEditDialogFragment.EditGroupListener,
@@ -96,7 +94,6 @@ class GroupActivity : LockingActivity(),
private var toolbarAction: ToolbarAction? = null
private var iconView: ImageView? = null
private var numberChildrenView: TextView? = null
private var modeTitleView: TextView? = null
private var addNodeButtonView: AddNodeButtonView? = null
private var groupNameView: TextView? = null
@@ -106,6 +103,9 @@ class GroupActivity : LockingActivity(),
private var mCurrentGroupIsASearch: Boolean = false
private var mRequestStartupSearch = true
// To manage history in selection mode
private var mSelectionModeCountBackStack = 0
// Nodes
private var mRootGroup: Group? = null
private var mCurrentGroup: Group? = null
@@ -135,7 +135,6 @@ class GroupActivity : LockingActivity(),
searchTitleView = findViewById(R.id.search_title)
groupNameView = findViewById(R.id.group_name)
toolbarAction = findViewById(R.id.toolbar_action)
modeTitleView = findViewById(R.id.mode_title_view)
lockView = findViewById(R.id.lock_button)
lockView?.setOnClickListener {
@@ -145,6 +144,11 @@ class GroupActivity : LockingActivity(),
toolbar?.title = ""
setSupportActionBar(toolbar)
// Retrieve the textColor to tint the icon
val taTextColor = theme.obtainStyledAttributes(intArrayOf(R.attr.textColorInverse))
mIconColor = taTextColor.getColor(0, Color.WHITE)
taTextColor.recycle()
// Focus view to reinitialize timeout
resetAppTimeoutWhenViewFocusedOrChanged(addNodeButtonView)
@@ -171,14 +175,6 @@ class GroupActivity : LockingActivity(),
return
}
// Update last access time.
mCurrentGroup?.touch(modified = false, touchParents = false)
// Retrieve the textColor to tint the icon
val taTextColor = theme.obtainStyledAttributes(intArrayOf(R.attr.textColorInverse))
mIconColor = taTextColor.getColor(0, Color.WHITE)
taTextColor.recycle()
var fragmentTag = LIST_NODES_FRAGMENT_TAG
if (mCurrentGroupIsASearch)
fragmentTag = SEARCH_FRAGMENT_TAG
@@ -195,6 +191,14 @@ class GroupActivity : LockingActivity(),
fragmentTag)
.commit()
// Update last access time.
mCurrentGroup?.touch(modified = false, touchParents = false)
// To relaunch the activity with ACTION_SEARCH
if (manageSearchInfoIntent(intent)) {
startActivity(intent)
}
// Add listeners to the add buttons
addNodeButtonView?.setAddGroupClickListener(View.OnClickListener {
GroupEditDialogFragment.build()
@@ -223,6 +227,8 @@ class GroupActivity : LockingActivity(),
newNodes = getListNodesFromBundle(database, newNodesBundle)
}
refreshSearchGroup()
when (actionTask) {
ACTION_DATABASE_UPDATE_GROUP_TASK -> {
if (result.isSuccess) {
@@ -277,11 +283,14 @@ class GroupActivity : LockingActivity(),
super.onNewIntent(intent)
intent?.let { intentNotNull ->
// To transform KEY_SEARCH_INFO in ACTION_SEARCH
manageSearchInfoIntent(intentNotNull)
Log.d(TAG, "setNewIntent: $intentNotNull")
setIntent(intentNotNull)
mCurrentGroupIsASearch = if (Intent.ACTION_SEARCH == intentNotNull.action) {
// only one instance of search in backstack
openSearchGroup(retrieveCurrentGroup(intentNotNull, null))
deletePreviousSearchGroup()
openGroup(retrieveCurrentGroup(intentNotNull, null), true)
true
} else {
false
@@ -289,20 +298,34 @@ class GroupActivity : LockingActivity(),
}
}
private fun openSearchGroup(group: Group?) {
// Delete the previous search fragment
val searchFragment = supportFragmentManager.findFragmentByTag(SEARCH_FRAGMENT_TAG)
if (searchFragment != null) {
if (supportFragmentManager
.popBackStackImmediate(SEARCH_FRAGMENT_TAG,
FragmentManager.POP_BACK_STACK_INCLUSIVE))
supportFragmentManager.beginTransaction().remove(searchFragment).commit()
/**
* Transform the KEY_SEARCH_INFO in ACTION_SEARCH, return true if KEY_SEARCH_INFO was present
*/
private fun manageSearchInfoIntent(intent: Intent): Boolean {
// To relaunch the activity as ACTION_SEARCH
val searchInfo: SearchInfo? = intent.getParcelableExtra(KEY_SEARCH_INFO)
val autoSearch = intent.getBooleanExtra(AUTO_SEARCH_KEY, false)
if (searchInfo != null && autoSearch) {
intent.action = Intent.ACTION_SEARCH
intent.putExtra(SearchManager.QUERY, searchInfo.getSearchString(this))
return true
}
openGroup(group, true)
return false
}
private fun openChildGroup(group: Group) {
openGroup(group, false)
private fun deletePreviousSearchGroup() {
// Delete the previous search fragment
try {
val searchFragment = supportFragmentManager.findFragmentByTag(SEARCH_FRAGMENT_TAG)
if (searchFragment != null) {
if (supportFragmentManager
.popBackStackImmediate(SEARCH_FRAGMENT_TAG,
FragmentManager.POP_BACK_STACK_INCLUSIVE))
supportFragmentManager.beginTransaction().remove(searchFragment).commit()
}
} catch (exception: Exception) {
Log.e(TAG, "unable to remove previous search fragment", exception)
}
}
private fun openGroup(group: Group?, isASearch: Boolean) {
@@ -329,6 +352,12 @@ class GroupActivity : LockingActivity(),
fragmentTransaction.addToBackStack(fragmentTag)
fragmentTransaction.commit()
if (mSelectionMode)
mSelectionModeCountBackStack++
// Update last access time.
group?.touch(modified = false, touchParents = false)
mListNodesFragment = newListNodeFragment
mCurrentGroup = group
assignGroupViewElements()
@@ -346,6 +375,12 @@ class GroupActivity : LockingActivity(),
super.onSaveInstanceState(outState)
}
private fun refreshSearchGroup() {
deletePreviousSearchGroup()
if (mCurrentGroupIsASearch)
openGroup(retrieveCurrentGroup(intent, null), true)
}
private fun retrieveCurrentGroup(intent: Intent, savedInstanceState: Bundle?): Group? {
// Force read only if the database is like that
@@ -426,13 +461,6 @@ class GroupActivity : LockingActivity(),
// Assign number of children
refreshNumberOfChildren()
// Show selection mode message if needed
if (mSelectionMode) {
modeTitleView?.visibility = View.VISIBLE
} else {
modeTitleView?.visibility = View.GONE
}
// Show button if allowed
addNodeButtonView?.apply {
@@ -450,6 +478,20 @@ class GroupActivity : LockingActivity(),
}
}
override fun onCancelSpecialMode() {
// To remove the navigation history and
EntrySelectionHelper.removeEntrySelectionModeFromIntent(intent)
val fragmentManager = supportFragmentManager
if (mSelectionModeCountBackStack > 0) {
for (selectionMode in 0 .. mSelectionModeCountBackStack) {
fragmentManager.popBackStack()
}
}
// Reinit the counter for navigation history
mSelectionModeCountBackStack = 0
backToTheAppCaller()
}
private fun refreshNumberOfChildren() {
numberChildrenView?.apply {
if (PreferencesUtil.showNumberEntries(context)) {
@@ -468,7 +510,8 @@ class GroupActivity : LockingActivity(),
override fun onNodeClick(node: Node) {
when (node.type) {
Type.GROUP -> try {
openChildGroup(node as Group)
// Open child group
openGroup(node as Group, false)
} catch (e: ClassCastException) {
Log.e(TAG, "Node can't be cast in Group")
}
@@ -480,14 +523,13 @@ class GroupActivity : LockingActivity(),
EntryActivity.launch(this@GroupActivity, entryVersioned, mReadOnly)
},
{
rebuildListNodes()
// Populate Magikeyboard with entry
mDatabase?.let { database ->
MagikIME.addEntryAndLaunchNotificationIfAllowed(this@GroupActivity,
entryVersioned.getEntryInfo(database))
populateKeyboardAndMoveAppToBackground(this@GroupActivity,
entryVersioned.getEntryInfo(database),
intent)
}
// Consume the selection mode
EntrySelectionHelper.removeEntrySelectionModeFromIntent(intent)
moveTaskToBack(true)
},
{
// Build response with the entry selected
@@ -616,6 +658,7 @@ class GroupActivity : LockingActivity(),
if (database != null
&& database.isRecycleBinEnabled
&& database.recycleBin != mCurrentGroup) {
mProgressDialogThread?.startDatabaseDeleteNodes(
nodes,
!mReadOnly && mAutoSaveEnable
@@ -667,8 +710,7 @@ class GroupActivity : LockingActivity(),
menu.findItem(R.id.menu_save_database)?.isVisible = false
}
if (!mSelectionMode) {
inflater.inflate(R.menu.default_menu, menu)
MenuUtil.contributionMenuInflater(inflater, menu)
MenuUtil.defaultMenuInflater(inflater, menu)
}
// Menu for recycle bin
@@ -877,19 +919,16 @@ class GroupActivity : LockingActivity(),
}
override fun startActivity(intent: Intent) {
// Get the intent, verify the action and get the query
if (Intent.ACTION_SEARCH == intent.action) {
// manually launch the real search activity
val searchIntent = Intent(applicationContext, GroupActivity::class.java).apply {
// Add bundle of current intent
putExtras(this@GroupActivity.intent)
// manually launch the same search activity
val searchIntent = getIntent().apply {
// add query to the Intent Extras
action = Intent.ACTION_SEARCH
putExtra(SearchManager.QUERY, intent.getStringExtra(SearchManager.QUERY))
}
super.startActivity(searchIntent)
setIntent(searchIntent)
onNewIntent(searchIntent)
} else {
super.startActivity(intent)
}
@@ -921,12 +960,29 @@ class GroupActivity : LockingActivity(),
mListNodesFragment?.onActivityResult(requestCode, resultCode, data)
}
private fun removeSearchInIntent(intent: Intent) {
private fun rebuildListNodes() {
mListNodesFragment = supportFragmentManager.findFragmentByTag(LIST_NODES_FRAGMENT_TAG) as ListNodesFragment?
// to refresh fragment
mListNodesFragment?.rebuildList()
mCurrentGroup = mListNodesFragment?.mainGroup
// Remove search in intent
deletePreviousSearchGroup()
mCurrentGroupIsASearch = false
if (Intent.ACTION_SEARCH == intent.action) {
mCurrentGroupIsASearch = false
intent.action = Intent.ACTION_DEFAULT
intent.removeExtra(SearchManager.QUERY)
}
assignGroupViewElements()
}
private fun backToTheAppCaller() {
if (mAutofillSelection) {
// To get the app caller, only for autofill
super.onBackPressed()
} else {
// To move the app in background
moveTaskToBack(true)
}
}
override fun onBackPressed() {
@@ -934,24 +990,23 @@ class GroupActivity : LockingActivity(),
finishNodeAction()
} else {
// Normal way when we are not in root
if (mRootGroup != null && mRootGroup != mCurrentGroup)
if (mRootGroup != null && mRootGroup != mCurrentGroup) {
super.onBackPressed()
// Else lock if needed
rebuildListNodes()
}
// Else in root, lock if needed
else {
intent.removeExtra(AUTO_SEARCH_KEY)
intent.removeExtra(KEY_SEARCH_INFO)
if (PreferencesUtil.isLockDatabaseWhenBackButtonOnRootClicked(this)) {
lockAndExit()
super.onBackPressed()
} else {
moveTaskToBack(true)
// To restore standard mode
EntrySelectionHelper.removeEntrySelectionModeFromIntent(intent)
backToTheAppCaller()
}
}
mListNodesFragment = supportFragmentManager.findFragmentByTag(LIST_NODES_FRAGMENT_TAG) as ListNodesFragment?
// to refresh fragment
mListNodesFragment?.rebuildList()
mCurrentGroup = mListNodesFragment?.mainGroup
removeSearchInIntent(intent)
assignGroupViewElements()
}
}
@@ -964,42 +1019,35 @@ class GroupActivity : LockingActivity(),
private const val LIST_NODES_FRAGMENT_TAG = "LIST_NODES_FRAGMENT_TAG"
private const val SEARCH_FRAGMENT_TAG = "SEARCH_FRAGMENT_TAG"
private const val OLD_GROUP_TO_UPDATE_KEY = "OLD_GROUP_TO_UPDATE_KEY"
private const val AUTO_SEARCH_KEY = "AUTO_SEARCH_KEY"
private fun buildIntent(context: Context,
group: Group?,
searchInfo: SearchInfo?,
readOnly: Boolean,
intentBuildLauncher: (Intent) -> Unit) {
val intent = Intent(context, GroupActivity::class.java)
if (group != null) {
intent.putExtra(GROUP_ID_KEY, group.nodeId)
}
if (searchInfo != null) {
intent.action = Intent.ACTION_SEARCH
val searchQuery = searchInfo.webDomain ?: searchInfo.applicationId
intent.putExtra(SearchManager.QUERY, searchQuery)
}
ReadOnlyHelper.putReadOnlyInIntent(intent, readOnly)
intentBuildLauncher.invoke(intent)
}
private fun checkTimeAndBuildIntent(activity: Activity,
group: Group?,
searchInfo: SearchInfo?,
readOnly: Boolean,
intentBuildLauncher: (Intent) -> Unit) {
if (TimeoutHelper.checkTimeAndLockIfTimeout(activity)) {
buildIntent(activity, group, searchInfo, readOnly, intentBuildLauncher)
buildIntent(activity, group, readOnly, intentBuildLauncher)
}
}
private fun checkTimeAndBuildIntent(context: Context,
group: Group?,
searchInfo: SearchInfo?,
readOnly: Boolean,
intentBuildLauncher: (Intent) -> Unit) {
if (TimeoutHelper.checkTime(context)) {
buildIntent(context, group, searchInfo, readOnly, intentBuildLauncher)
buildIntent(context, group, readOnly, intentBuildLauncher)
}
}
@@ -1009,8 +1057,14 @@ class GroupActivity : LockingActivity(),
* -------------------------
*/
fun launch(context: Context,
autoSearch: Boolean = false,
searchInfo: SearchInfo? = null,
readOnly: Boolean = PreferencesUtil.enableReadOnlyDatabase(context)) {
checkTimeAndBuildIntent(context, null, null, readOnly) { intent ->
checkTimeAndBuildIntent(context, null, readOnly) { intent ->
searchInfo?.let {
intent.putExtra(KEY_SEARCH_INFO, it)
}
intent.putExtra(AUTO_SEARCH_KEY, autoSearch)
context.startActivity(intent)
}
}
@@ -1020,11 +1074,13 @@ class GroupActivity : LockingActivity(),
* Keyboard Launch
* -------------------------
*/
// TODO implement pre search to directly open the direct group #280
fun launchForKeyboardSelection(context: Context,
readOnly: Boolean = PreferencesUtil.enableReadOnlyDatabase(context)) {
checkTimeAndBuildIntent(context, null, null, readOnly) { intent ->
EntrySelectionHelper.startActivityForEntrySelection(context, intent)
fun launchForEntrySelectionResult(context: Context,
autoSearch: Boolean = false,
searchInfo: SearchInfo? = null,
readOnly: Boolean = PreferencesUtil.enableReadOnlyDatabase(context)) {
checkTimeAndBuildIntent(context, null, readOnly) { intent ->
intent.putExtra(AUTO_SEARCH_KEY, autoSearch)
EntrySelectionHelper.startActivityForEntrySelectionResult(context, intent, searchInfo)
}
}
@@ -1036,9 +1092,11 @@ class GroupActivity : LockingActivity(),
@RequiresApi(api = Build.VERSION_CODES.O)
fun launchForAutofillResult(activity: Activity,
assistStructure: AssistStructure,
autoSearch: Boolean = false,
searchInfo: SearchInfo? = null,
readOnly: Boolean = PreferencesUtil.enableReadOnlyDatabase(activity)) {
checkTimeAndBuildIntent(activity, null, searchInfo, readOnly) { intent ->
checkTimeAndBuildIntent(activity, null, readOnly) { intent ->
intent.putExtra(AUTO_SEARCH_KEY, autoSearch)
AutofillHelper.startActivityForAutofillResult(activity, intent, assistStructure, searchInfo)
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
* Copyright 2020 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePassDX.
*
@@ -17,24 +17,31 @@
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.magikeyboard
package com.kunzisoft.keepass.activities
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.kunzisoft.keepass.activities.FileDatabaseSelectActivity
import com.kunzisoft.keepass.activities.GroupActivity
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.timeout.TimeoutHelper
import com.kunzisoft.keepass.database.search.SearchHelper
class KeyboardLauncherActivity : AppCompatActivity() {
/**
* Activity to select entry in database and populate it in Magikeyboard
*/
class MagikeyboardLauncherActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
if (Database.getInstance().loaded && TimeoutHelper.checkTime(this))
GroupActivity.launchForKeyboardSelection(this)
else {
// Pass extra to get entry
FileDatabaseSelectActivity.launchForKeyboardSelection(this)
}
SearchHelper.checkAutoSearchInfo(this,
Database.getInstance(),
null,
{},
{
GroupActivity.launchForEntrySelectionResult(this)
},
{
// Pass extra to get entry
FileDatabaseSelectActivity.launchForEntrySelectionResult(this)
}
)
finish()
super.onCreate(savedInstanceState)
}

View File

@@ -42,18 +42,19 @@ import com.google.android.material.snackbar.Snackbar
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.dialogs.DuplicateUuidDialog
import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper
import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper.KEY_SEARCH_INFO
import com.kunzisoft.keepass.activities.helpers.OpenFileHelper
import com.kunzisoft.keepass.activities.helpers.ReadOnlyHelper
import com.kunzisoft.keepass.activities.lock.LockingActivity
import com.kunzisoft.keepass.activities.stylish.StylishActivity
import com.kunzisoft.keepass.activities.selection.SpecialModeActivity
import com.kunzisoft.keepass.app.database.CipherDatabaseEntity
import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction
import com.kunzisoft.keepass.autofill.AutofillHelper
import com.kunzisoft.keepass.autofill.AutofillHelper.KEY_SEARCH_INFO
import com.kunzisoft.keepass.biometric.AdvancedUnlockedManager
import com.kunzisoft.keepass.database.action.ProgressDialogThread
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.exception.DuplicateUuidDatabaseException
import com.kunzisoft.keepass.database.search.SearchHelper
import com.kunzisoft.keepass.education.PasswordActivityEducation
import com.kunzisoft.keepass.model.SearchInfo
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_LOAD_TASK
@@ -72,11 +73,10 @@ import com.kunzisoft.keepass.view.asError
import kotlinx.android.synthetic.main.activity_password.*
import java.io.FileNotFoundException
open class PasswordActivity : StylishActivity() {
open class PasswordActivity : SpecialModeActivity() {
// Views
private var toolbar: Toolbar? = null
private var containerView: View? = null
private var filenameView: TextView? = null
private var passwordView: EditText? = null
private var keyFileSelectionView: KeyFileSelectionView? = null
@@ -110,6 +110,7 @@ open class PasswordActivity : StylishActivity() {
private var mProgressDialogThread: ProgressDialogThread? = null
private var advancedUnlockedManager: AdvancedUnlockedManager? = null
private var mAllowAutoOpenBiometricPrompt: Boolean = true
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -122,7 +123,6 @@ open class PasswordActivity : StylishActivity() {
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true)
containerView = findViewById(R.id.container)
confirmButtonView = findViewById(R.id.activity_password_open_button)
filenameView = findViewById(R.id.filename)
passwordView = findViewById(R.id.password)
@@ -166,6 +166,10 @@ open class PasswordActivity : StylishActivity() {
mDatabaseKeyFileUri = UriUtil.parse(savedInstanceState.getString(KEY_KEYFILE))
}
if (savedInstanceState?.containsKey(ALLOW_AUTO_OPEN_BIOMETRIC_PROMPT) == true) {
mAllowAutoOpenBiometricPrompt = savedInstanceState.getBoolean(ALLOW_AUTO_OPEN_BIOMETRIC_PROMPT)
}
mProgressDialogThread = ProgressDialogThread(this).apply {
onActionFinish = { actionTask, result ->
when (actionTask) {
@@ -255,21 +259,52 @@ open class PasswordActivity : StylishActivity() {
}
private fun launchGroupActivity() {
val searchInfo: SearchInfo? = intent.getParcelableExtra(KEY_SEARCH_INFO)
EntrySelectionHelper.doEntrySelectionAction(intent,
{
GroupActivity.launch(this@PasswordActivity,
true,
searchInfo,
readOnly)
// Finish activity if no search info
if (searchInfo != null) {
finish()
}
},
{
GroupActivity.launchForKeyboardSelection(this@PasswordActivity,
readOnly)
SearchHelper.checkAutoSearchInfo(this,
Database.getInstance(),
searchInfo,
{ items ->
// Response is build
if (items.size == 1) {
populateKeyboardAndMoveAppToBackground(this@PasswordActivity,
items[0],
intent)
} else {
// Select the one we want
GroupActivity.launchForEntrySelectionResult(this,
true,
searchInfo)
}
},
{
// Here no search info found, disable auto search
GroupActivity.launchForEntrySelectionResult(this@PasswordActivity,
false,
searchInfo,
readOnly)
},
{
// Simply close if database not opened, normally not happened
}
)
// Do not keep history
finish()
},
{ assistStructure ->
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val searchInfo: SearchInfo? = intent.getParcelableExtra(KEY_SEARCH_INFO)
AutofillHelper.checkAutoSearchInfo(this,
SearchHelper.checkAutoSearchInfo(this,
Database.getInstance(),
searchInfo,
{ items ->
@@ -278,10 +313,11 @@ open class PasswordActivity : StylishActivity() {
finish()
},
{
// Here no search info found
// Here no search info found, disable auto search
GroupActivity.launchForAutofillResult(this@PasswordActivity,
assistStructure,
null,
false,
searchInfo,
readOnly)
},
{
@@ -304,35 +340,31 @@ open class PasswordActivity : StylishActivity() {
}
override fun onResume() {
if (Database.getInstance().loaded)
launchGroupActivity()
mRememberKeyFile = PreferencesUtil.rememberKeyFileLocations(this)
// If the database isn't accessible make sure to clear the password field, if it
// was saved in the instance state
if (Database.getInstance().loaded) {
clearCredentialsViews()
}
// For check shutdown
super.onResume()
mProgressDialogThread?.registerProgressTask()
if (Database.getInstance().loaded) {
launchGroupActivity()
} else {
mRememberKeyFile = PreferencesUtil.rememberKeyFileLocations(this)
initUriFromIntent()
// If the database isn't accessible make sure to clear the password field, if it
// was saved in the instance state
if (Database.getInstance().loaded) {
clearCredentialsViews()
}
checkPermission()
}
mProgressDialogThread?.registerProgressTask()
override fun onSaveInstanceState(outState: Bundle) {
outState.putBoolean(KEY_PERMISSION_ASKED, mPermissionAsked)
mDatabaseKeyFileUri?.let {
outState.putString(KEY_KEYFILE, it.toString())
// Don't allow auto open prompt if lock become when UI visible
mAllowAutoOpenBiometricPrompt = if (LockingActivity.LOCKING_ACTIVITY_UI_VISIBLE_DURING_LOCK == true)
false
else
mAllowAutoOpenBiometricPrompt
initUriFromIntent()
checkPermission()
}
ReadOnlyHelper.onSaveInstanceState(outState, readOnly)
super.onSaveInstanceState(outState)
}
private fun initUriFromIntent() {
@@ -438,6 +470,7 @@ open class PasswordActivity : StylishActivity() {
}
})
}
advancedUnlockedManager?.isBiometricPromptAutoOpenEnable = mAllowAutoOpenBiometricPrompt
advancedUnlockedManager?.checkBiometricAvailability()
biometricInitialize = true
} else {
@@ -499,14 +532,26 @@ open class PasswordActivity : StylishActivity() {
override fun onPause() {
mProgressDialogThread?.unregisterProgressTask()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
advancedUnlockedManager?.destroy()
advancedUnlockedManager = null
}
// Reinit locking activity UI variable
LockingActivity.LOCKING_ACTIVITY_UI_VISIBLE_DURING_LOCK = null
mAllowAutoOpenBiometricPrompt = true
super.onPause()
}
override fun onDestroy() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
advancedUnlockedManager?.destroy()
override fun onSaveInstanceState(outState: Bundle) {
outState.putBoolean(KEY_PERMISSION_ASKED, mPermissionAsked)
mDatabaseKeyFileUri?.let {
outState.putString(KEY_KEYFILE, it.toString())
}
super.onDestroy()
ReadOnlyHelper.onSaveInstanceState(outState, readOnly)
outState.putBoolean(ALLOW_AUTO_OPEN_BIOMETRIC_PROMPT, false)
super.onSaveInstanceState(outState)
}
private fun verifyCheckboxesAndLoadDatabase(cipherDatabaseEntity: CipherDatabaseEntity? = null) {
@@ -580,14 +625,15 @@ open class PasswordActivity : StylishActivity() {
val inflater = menuInflater
// Read menu
inflater.inflate(R.menu.open_file, menu)
if (mForceReadOnly) {
if (mSelectionMode || mForceReadOnly) {
menu.removeItem(R.id.menu_open_file_read_mode_key)
} else {
changeOpenFileReadIcon(menu.findItem(R.id.menu_open_file_read_mode_key))
}
MenuUtil.defaultMenuInflater(inflater, menu)
if (!mSelectionMode) {
MenuUtil.defaultMenuInflater(inflater, menu)
}
if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// biometric menu
@@ -715,6 +761,8 @@ open class PasswordActivity : StylishActivity() {
data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
mAllowAutoOpenBiometricPrompt = false
// To get entry in result
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
AutofillHelper.onActivityResultSetResultAndFinish(this, requestCode, resultCode, data)
@@ -733,10 +781,13 @@ open class PasswordActivity : StylishActivity() {
if (!keyFileResult) {
// this block if not a key file response
when (resultCode) {
LockingActivity.RESULT_EXIT_LOCK, Activity.RESULT_CANCELED -> {
LockingActivity.RESULT_EXIT_LOCK -> {
clearCredentialsViews()
Database.getInstance().closeAndClear(applicationContext.filesDir)
}
Activity.RESULT_CANCELED -> {
clearCredentialsViews()
}
}
}
}
@@ -754,6 +805,8 @@ open class PasswordActivity : StylishActivity() {
private const val KEY_PERMISSION_ASKED = "KEY_PERMISSION_ASKED"
private const val WRITE_EXTERNAL_STORAGE_REQUEST = 647
private const val ALLOW_AUTO_OPEN_BIOMETRIC_PROMPT = "ALLOW_AUTO_OPEN_BIOMETRIC_PROMPT"
private fun buildAndLaunchIntent(activity: Activity, databaseFile: Uri, keyFile: Uri?,
intentBuildLauncher: (Intent) -> Unit) {
val intent = Intent(activity, PasswordActivity::class.java)
@@ -773,8 +826,12 @@ open class PasswordActivity : StylishActivity() {
fun launch(
activity: Activity,
databaseFile: Uri,
keyFile: Uri?) {
keyFile: Uri?,
searchInfo: SearchInfo?) {
buildAndLaunchIntent(activity, databaseFile, keyFile) { intent ->
searchInfo?.let {
intent.putExtra(KEY_SEARCH_INFO, it)
}
activity.startActivity(intent)
}
}
@@ -789,9 +846,13 @@ open class PasswordActivity : StylishActivity() {
fun launchForKeyboardResult(
activity: Activity,
databaseFile: Uri,
keyFile: Uri?) {
keyFile: Uri?,
searchInfo: SearchInfo?) {
buildAndLaunchIntent(activity, databaseFile, keyFile) { intent ->
EntrySelectionHelper.startActivityForEntrySelection(activity, intent)
EntrySelectionHelper.startActivityForEntrySelectionResult(
activity,
intent,
searchInfo)
}
}
@@ -818,7 +879,7 @@ open class PasswordActivity : StylishActivity() {
searchInfo)
}
} else {
launch(activity, databaseFile, keyFile)
launch(activity, databaseFile, keyFile, searchInfo)
}
}
}

View File

@@ -31,10 +31,10 @@ import android.widget.BaseAdapter
import android.widget.GridView
import android.widget.ImageView
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.widget.ImageViewCompat
import androidx.fragment.app.DialogFragment
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.stylish.StylishActivity
import com.kunzisoft.keepass.database.element.icon.IconImageStandard
import com.kunzisoft.keepass.icons.IconPack
import com.kunzisoft.keepass.icons.IconPackChooser
@@ -132,7 +132,7 @@ class IconPickerDialogFragment : DialogFragment() {
return bundle.getParcelable(KEY_ICON_STANDARD)
}
fun launch(activity: StylishActivity) {
fun launch(activity: AppCompatActivity) {
// Create an instance of the dialog fragment and show it
val dialog = IconPickerDialogFragment()
dialog.show(activity.supportFragmentManager, "IconPickerDialogFragment")

View File

@@ -24,15 +24,22 @@ import android.content.Context
import android.content.Intent
import android.os.Build
import com.kunzisoft.keepass.autofill.AutofillHelper
import com.kunzisoft.keepass.model.SearchInfo
object EntrySelectionHelper {
private const val EXTRA_ENTRY_SELECTION_MODE = "com.kunzisoft.keepass.extra.ENTRY_SELECTION_MODE"
private const val DEFAULT_ENTRY_SELECTION_MODE = false
// Key to retrieve search in intent
const val KEY_SEARCH_INFO = "KEY_SEARCH_INFO"
fun startActivityForEntrySelection(context: Context, intent: Intent) {
fun startActivityForEntrySelectionResult(context: Context,
intent: Intent,
searchInfo: SearchInfo?) {
addEntrySelectionModeExtraInIntent(intent)
// only to avoid visible flickering when redirecting
searchInfo?.let {
intent.putExtra(KEY_SEARCH_INFO, it)
}
context.startActivity(intent)
}

View File

@@ -24,26 +24,15 @@ import android.os.Bundle
import android.util.Log
import android.view.View
import android.view.ViewGroup
import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper
import com.kunzisoft.keepass.activities.helpers.ReadOnlyHelper
import com.kunzisoft.keepass.activities.stylish.StylishActivity
import com.kunzisoft.keepass.activities.selection.SpecialModeActivity
import com.kunzisoft.keepass.database.action.ProgressDialogThread
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.timeout.TimeoutHelper
import com.kunzisoft.keepass.utils.*
abstract class LockingActivity : StylishActivity() {
companion object {
private const val TAG = "LockingActivity"
const val RESULT_EXIT_LOCK = 1450
const val TIMEOUT_ENABLE_KEY = "TIMEOUT_ENABLE_KEY"
const val TIMEOUT_ENABLE_KEY_DEFAULT = true
}
abstract class LockingActivity : SpecialModeActivity() {
protected var mTimeoutEnable: Boolean = true
@@ -51,11 +40,14 @@ abstract class LockingActivity : StylishActivity() {
private var mExitLock: Boolean = false
// Force readOnly if Entry Selection mode
protected var mReadOnly: Boolean = false
protected var mReadOnly: Boolean
get() {
return field || mSelectionMode
return mReadOnlyToSave || mSelectionMode
}
protected var mSelectionMode: Boolean = false
set(value) {
mReadOnlyToSave = value
}
private var mReadOnlyToSave: Boolean = false
protected var mAutoSaveEnable: Boolean = true
var mProgressDialogThread: ProgressDialogThread? = null
@@ -75,6 +67,8 @@ abstract class LockingActivity : StylishActivity() {
if (mTimeoutEnable) {
mLockReceiver = LockReceiver {
closeDatabase()
if (LOCKING_ACTIVITY_UI_VISIBLE_DURING_LOCK == null)
LOCKING_ACTIVITY_UI_VISIBLE_DURING_LOCK = LOCKING_ACTIVITY_UI_VISIBLE
// Add onActivityForResult response
setResult(RESULT_EXIT_LOCK)
finish()
@@ -83,7 +77,6 @@ abstract class LockingActivity : StylishActivity() {
}
mExitLock = false
mReadOnly = ReadOnlyHelper.retrieveReadOnlyFromInstanceStateOrIntent(savedInstanceState, intent)
mProgressDialogThread = ProgressDialogThread(this)
}
@@ -104,7 +97,7 @@ abstract class LockingActivity : StylishActivity() {
mProgressDialogThread?.registerProgressTask()
// To refresh when back to normal workflow from selection workflow
mSelectionMode = EntrySelectionHelper.retrieveEntrySelectionModeFromIntent(intent)
mReadOnlyToSave = ReadOnlyHelper.retrieveReadOnlyFromIntent(intent)
mAutoSaveEnable = PreferencesUtil.isAutoSaveDatabaseEnabled(this)
invalidateOptionsMenu()
@@ -124,15 +117,18 @@ abstract class LockingActivity : StylishActivity() {
if (!mExitLock)
TimeoutHelper.recordTime(this)
}
LOCKING_ACTIVITY_UI_VISIBLE = true
}
override fun onSaveInstanceState(outState: Bundle) {
ReadOnlyHelper.onSaveInstanceState(outState, mReadOnly)
outState.putBoolean(TIMEOUT_ENABLE_KEY, mTimeoutEnable)
super.onSaveInstanceState(outState)
}
override fun onPause() {
LOCKING_ACTIVITY_UI_VISIBLE = false
mProgressDialogThread?.unregisterProgressTask()
super.onPause()
@@ -180,4 +176,17 @@ abstract class LockingActivity : StylishActivity() {
super.onBackPressed()
}
}
companion object {
private const val TAG = "LockingActivity"
const val RESULT_EXIT_LOCK = 1450
const val TIMEOUT_ENABLE_KEY = "TIMEOUT_ENABLE_KEY"
const val TIMEOUT_ENABLE_KEY_DEFAULT = true
private var LOCKING_ACTIVITY_UI_VISIBLE = false
var LOCKING_ACTIVITY_UI_VISIBLE_DURING_LOCK: Boolean? = null
}
}

View File

@@ -0,0 +1,90 @@
package com.kunzisoft.keepass.activities.selection
import android.os.Build
import android.view.View
import android.widget.Toast
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper
import com.kunzisoft.keepass.activities.stylish.StylishActivity
import com.kunzisoft.keepass.autofill.AutofillHelper
import com.kunzisoft.keepass.model.SearchInfo
import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.view.SpecialModeView
/**
* Activity to manage special mode (ie: selection mode)
*/
abstract class SpecialModeActivity : StylishActivity() {
protected var mSelectionMode: Boolean = false
protected var mAutofillSelection: Boolean = false
private var specialModeView: SpecialModeView? = null
open fun onCancelSpecialMode() {
onBackPressed()
}
override fun onResume() {
super.onResume()
mSelectionMode = EntrySelectionHelper.retrieveEntrySelectionModeFromIntent(intent)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mAutofillSelection = AutofillHelper.retrieveAssistStructure(intent) != null
}
val searchInfo: SearchInfo? = intent.getParcelableExtra(EntrySelectionHelper.KEY_SEARCH_INFO)
// To show the selection mode
specialModeView = findViewById(R.id.special_mode_view)
specialModeView?.apply {
// Populate title
val typeModeId = if (mAutofillSelection)
R.string.autofill
else
R.string.magic_keyboard_title
title = "${resources.getString(R.string.selection_mode)} (${getString(typeModeId)})"
// Populate subtitle
subtitle = searchInfo?.getName(resources)
// Show the toolbar or not
visible = mSelectionMode
// Add back listener
onCancelButtonClickListener = View.OnClickListener {
onCancelSpecialMode()
}
// Create menu
menu.clear()
if (mAutofillSelection) {
menuInflater.inflate(R.menu.autofill, menu)
setOnMenuItemClickListener { menuItem ->
when (menuItem.itemId) {
R.id.menu_block_autofill -> {
blockAutofill(searchInfo)
}
}
true
}
}
}
}
fun blockAutofill(searchInfo: SearchInfo?) {
val webDomain = searchInfo?.webDomain
val applicationId = searchInfo?.applicationId
if (webDomain != null) {
PreferencesUtil.addWebDomainToBlocklist(this,
webDomain)
} else if (applicationId != null) {
PreferencesUtil.addApplicationIdToBlocklist(this,
applicationId)
}
onCancelSpecialMode()
Toast.makeText(this.applicationContext,
R.string.autofill_block_restart,
Toast.LENGTH_LONG).show()
}
}

View File

@@ -27,6 +27,7 @@ import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.annotation.ColorInt
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.SortedList
import androidx.recyclerview.widget.SortedListAdapterCallback
@@ -73,7 +74,11 @@ class NodeAdapter (private val context: Context)
private val mDatabase: Database
@ColorInt
private val contentSelectionColor: Int
@ColorInt
private val iconGroupColor: Int
@ColorInt
private val iconEntryColor: Int
/**
@@ -97,6 +102,10 @@ class NodeAdapter (private val context: Context)
// Database
this.mDatabase = Database.getInstance()
// Color of content selection
val taContentSelectionColor = context.theme.obtainStyledAttributes(intArrayOf(R.attr.textColorInverse))
this.contentSelectionColor = taContentSelectionColor.getColor(0, Color.WHITE)
taContentSelectionColor.recycle()
// Retrieve the color to tint the icon
val taTextColorPrimary = context.theme.obtainStyledAttributes(intArrayOf(android.R.attr.textColorPrimary))
this.iconGroupColor = taTextColorPrimary.getColor(0, Color.BLACK)
@@ -280,11 +289,18 @@ class NodeAdapter (private val context: Context)
override fun onBindViewHolder(holder: NodeViewHolder, position: Int) {
val subNode = nodeSortedList.get(position)
// Node selection
holder.container.isSelected = actionNodesList.contains(subNode)
// Assign image
val iconColor = when (subNode.type) {
val iconColor = if (holder.container.isSelected)
contentSelectionColor
else when (subNode.type) {
Type.GROUP -> iconGroupColor
Type.ENTRY -> iconEntryColor
}
holder.imageIdentifier?.setColorFilter(iconColor)
holder.icon.apply {
assignDatabaseIcon(mDatabase.drawFactory, subNode.icon, iconColor)
// Relative size of the icon
@@ -347,8 +363,6 @@ class NodeAdapter (private val context: Context)
holder.container.setOnLongClickListener {
nodeClickCallback?.onNodeLongClick(subNode) ?: false
}
holder.container.isSelected = actionNodesList.contains(subNode)
}
override fun getItemCount(): Int {
@@ -372,6 +386,7 @@ class NodeAdapter (private val context: Context)
class NodeViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var container: View = itemView.findViewById(R.id.node_container)
var imageIdentifier: ImageView? = itemView.findViewById(R.id.node_image_identifier)
var icon: ImageView = itemView.findViewById(R.id.node_icon)
var text: TextView = itemView.findViewById(R.id.node_text)
var subText: TextView = itemView.findViewById(R.id.node_subtext)

View File

@@ -34,14 +34,12 @@ import androidx.annotation.RequiresApi
import androidx.core.content.ContextCompat
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper
import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper.KEY_SEARCH_INFO
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.element.icon.IconImage
import com.kunzisoft.keepass.database.search.SearchHelper
import com.kunzisoft.keepass.icons.assignDatabaseIcon
import com.kunzisoft.keepass.model.EntryInfo
import com.kunzisoft.keepass.model.SearchInfo
import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.timeout.TimeoutHelper
@RequiresApi(api = Build.VERSION_CODES.O)
@@ -50,7 +48,6 @@ object AutofillHelper {
private const val AUTOFILL_RESPONSE_REQUEST_CODE = 8165
private const val ASSIST_STRUCTURE = AutofillManager.EXTRA_ASSIST_STRUCTURE
const val KEY_SEARCH_INFO = "KEY_SEARCH_INFO"
fun retrieveAssistStructure(intent: Intent?): AssistStructure? {
intent?.let {
@@ -122,60 +119,34 @@ object AutofillHelper {
* Build the Autofill response for many entry
*/
fun buildResponse(activity: Activity, entriesInfo: List<EntryInfo>) {
var setResultOk = false
activity.intent?.extras?.let { extras ->
if (extras.containsKey(ASSIST_STRUCTURE)) {
activity.intent?.getParcelableExtra<AssistStructure>(ASSIST_STRUCTURE)?.let { structure ->
StructureParser(structure).parse()?.let { result ->
// New Response
val responseBuilder = FillResponse.Builder()
entriesInfo.forEach {
responseBuilder.addDataset(buildDataset(activity, it, result))
}
val mReplyIntent = Intent()
Log.d(activity.javaClass.name, "Successed Autofill auth.")
mReplyIntent.putExtra(
AutofillManager.EXTRA_AUTHENTICATION_RESULT,
responseBuilder.build())
setResultOk = true
activity.setResult(Activity.RESULT_OK, mReplyIntent)
}
}
}
if (!setResultOk) {
Log.w(activity.javaClass.name, "Failed Autofill auth.")
activity.setResult(Activity.RESULT_CANCELED)
}
}
}
/**
* Utility method to perform actions if item is found or not after an auto search in [database]
*/
fun checkAutoSearchInfo(context: Context,
database: Database,
searchInfo: SearchInfo?,
onItemsFound: (items: List<EntryInfo>) -> Unit,
onItemNotFound: () -> Unit,
onDatabaseClosed: () -> Unit) {
if (database.loaded && TimeoutHelper.checkTime(context)) {
var searchWithoutUI = false
if (PreferencesUtil.isAutofillAutoSearchEnable(context)
&& searchInfo != null) {
// If search provide results
database.createVirtualGroupFromSearch(searchInfo, SearchHelper.MAX_SEARCH_ENTRY)?.let { searchGroup ->
if (searchGroup.getNumberOfChildEntries() > 0) {
searchWithoutUI = true
onItemsFound.invoke(
searchGroup.getChildEntriesInfo(database))
}
}
}
if (!searchWithoutUI) {
onItemNotFound.invoke()
}
if (entriesInfo.isEmpty()) {
activity.setResult(Activity.RESULT_CANCELED)
} else {
onDatabaseClosed.invoke()
var setResultOk = false
activity.intent?.extras?.let { extras ->
if (extras.containsKey(ASSIST_STRUCTURE)) {
activity.intent?.getParcelableExtra<AssistStructure>(ASSIST_STRUCTURE)?.let { structure ->
StructureParser(structure).parse()?.let { result ->
// New Response
val responseBuilder = FillResponse.Builder()
entriesInfo.forEach {
responseBuilder.addDataset(buildDataset(activity, it, result))
}
val mReplyIntent = Intent()
Log.d(activity.javaClass.name, "Successed Autofill auth.")
mReplyIntent.putExtra(
AutofillManager.EXTRA_AUTHENTICATION_RESULT,
responseBuilder.build())
setResultOk = true
activity.setResult(Activity.RESULT_OK, mReplyIntent)
}
}
}
if (!setResultOk) {
Log.w(activity.javaClass.name, "Failed Autofill auth.")
activity.setResult(Activity.RESULT_CANCELED)
}
}
}
}

View File

@@ -26,12 +26,25 @@ import android.util.Log
import android.widget.RemoteViews
import androidx.annotation.RequiresApi
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.AutofillLauncherActivity
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.search.SearchHelper
import com.kunzisoft.keepass.model.SearchInfo
import com.kunzisoft.keepass.settings.PreferencesUtil
@RequiresApi(api = Build.VERSION_CODES.O)
class KeeAutofillService : AutofillService() {
var applicationIdBlocklist: Set<String>? = null
var webDomainBlocklist: Set<String>? = null
override fun onCreate() {
super.onCreate()
applicationIdBlocklist = PreferencesUtil.applicationIdBlocklist(this)
webDomainBlocklist = PreferencesUtil.webDomainBlocklist(this)
}
override fun onFillRequest(request: FillRequest,
cancellationSignal: CancellationSignal,
callback: FillCallback) {
@@ -43,32 +56,36 @@ class KeeAutofillService : AutofillService() {
// Check user's settings for authenticating Responses and Datasets.
StructureParser(latestStructure).parse()?.let { parseResult ->
val searchInfo = SearchInfo().apply {
applicationId = parseResult.applicationId
webDomain = parseResult.domain
}
// Build search info only if applicationId or webDomain are not blocked
if (searchAllowedFor(parseResult.applicationId, applicationIdBlocklist)
&& searchAllowedFor(parseResult.domain, webDomainBlocklist)) {
val searchInfo = SearchInfo().apply {
applicationId = parseResult.applicationId
webDomain = parseResult.domain
}
AutofillHelper.checkAutoSearchInfo(this,
Database.getInstance(),
searchInfo,
{ items ->
val responseBuilder = FillResponse.Builder()
AutofillHelper.addHeader(responseBuilder, packageName,
parseResult.domain, parseResult.applicationId)
items.forEach {
responseBuilder.addDataset(AutofillHelper.buildDataset(this, it, parseResult))
SearchHelper.checkAutoSearchInfo(this,
Database.getInstance(),
searchInfo,
{ items ->
val responseBuilder = FillResponse.Builder()
AutofillHelper.addHeader(responseBuilder, packageName,
parseResult.domain, parseResult.applicationId)
items.forEach {
responseBuilder.addDataset(AutofillHelper.buildDataset(this, it, parseResult))
}
callback.onSuccess(responseBuilder.build())
},
{
// Show UI if no search result
showUIForEntrySelection(parseResult, searchInfo, callback)
},
{
// Show UI if database not open
showUIForEntrySelection(parseResult, searchInfo, callback)
}
callback.onSuccess(responseBuilder.build())
},
{
// Show UI if no search result
showUIForEntrySelection(parseResult, searchInfo, callback)
},
{
// Show UI if database not open
showUIForEntrySelection(parseResult, searchInfo, callback)
}
)
)
}
}
}
@@ -114,5 +131,18 @@ class KeeAutofillService : AutofillService() {
companion object {
private val TAG = KeeAutofillService::class.java.name
fun searchAllowedFor(element: String?, blockList: Set<String>?): Boolean {
element?.let { elementNotNull ->
if (blockList?.any { appIdBlocked ->
elementNotNull.contains(appIdBlocked)
} == true
) {
Log.d(TAG, "Autofill not allowed for $elementNotNull")
return false
}
}
return true
}
}
}

View File

@@ -102,9 +102,12 @@ internal class StructureParser(private val structure: AssistStructure) {
when {
it.equals(View.AUTOFILL_HINT_USERNAME, true)
|| it.equals(View.AUTOFILL_HINT_EMAIL_ADDRESS, true)
|| it.equals(View.AUTOFILL_HINT_PHONE, true)
|| it.equals("email", true)
|| it.equals("usernameOrEmail", true)-> {
|| it.equals(View.AUTOFILL_HINT_PHONE, true)
|| it.contains("OrUsername", true)
|| it.contains("OrEmailAddress", true)
|| it.contains("OrEmail", true)
|| it.contains("OrPhone", true)-> {
result?.usernameId = autofillId
Log.d(TAG, "Autofill username hint")
}
@@ -112,7 +115,7 @@ internal class StructureParser(private val structure: AssistStructure) {
|| it.contains("password", true) -> {
result?.passwordId = autofillId
Log.d(TAG, "Autofill password hint")
// Username not needed in this specific case
// Username not needed in this case
usernameNeeded = false
return true
}
@@ -160,42 +163,78 @@ internal class StructureParser(private val structure: AssistStructure) {
return false
}
private fun inputIsVariationType(inputType: Int, vararg type: Int): Boolean {
type.forEach {
if (inputType and InputType.TYPE_MASK_VARIATION == it)
return true
}
return false
}
private fun showHexInputType(inputType: Int): String {
return "0x${"%08x".format(inputType)}"
}
private fun parseNodeByAndroidInput(node: AssistStructure.ViewNode): Boolean {
val autofillId = node.autofillId
val inputType = node.inputType
if (inputType and InputType.TYPE_CLASS_TEXT != 0) {
when {
inputType and InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS != 0 -> {
result?.usernameId = autofillId
Log.d(TAG, "Autofill username android type: $inputType")
when (inputType and InputType.TYPE_MASK_CLASS) {
InputType.TYPE_CLASS_TEXT -> {
when {
inputIsVariationType(inputType,
InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS,
InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS) -> {
result?.usernameId = autofillId
Log.d(TAG, "Autofill username android text type: ${showHexInputType(inputType)}")
}
inputIsVariationType(inputType,
InputType.TYPE_TEXT_VARIATION_NORMAL,
InputType.TYPE_TEXT_VARIATION_PERSON_NAME,
InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT) -> {
usernameCandidate = autofillId
Log.d(TAG, "Autofill username candidate android text type: ${showHexInputType(inputType)}")
}
inputIsVariationType(inputType,
InputType.TYPE_TEXT_VARIATION_PASSWORD,
InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD,
InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD) -> {
result?.passwordId = autofillId
Log.d(TAG, "Autofill password android text type: ${showHexInputType(inputType)}")
usernameNeeded = false
return true
}
inputIsVariationType(inputType,
InputType.TYPE_TEXT_VARIATION_EMAIL_SUBJECT,
InputType.TYPE_TEXT_VARIATION_FILTER,
InputType.TYPE_TEXT_VARIATION_LONG_MESSAGE,
InputType.TYPE_TEXT_VARIATION_PHONETIC,
InputType.TYPE_TEXT_VARIATION_POSTAL_ADDRESS,
InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE,
InputType.TYPE_TEXT_VARIATION_URI) -> {
// Type not used
}
else -> {
Log.d(TAG, "Autofill unknown android text type: ${showHexInputType(inputType)}")
}
}
inputType and InputType.TYPE_TEXT_VARIATION_NORMAL != 0 ||
inputType and InputType.TYPE_NUMBER_VARIATION_NORMAL != 0 ||
inputType and InputType.TYPE_TEXT_VARIATION_PERSON_NAME != 0 -> {
usernameCandidate = autofillId
Log.d(TAG, "Autofill username candidate android type: $inputType")
}
inputType and InputType.TYPE_TEXT_VARIATION_PASSWORD != 0 ||
inputType and InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD != 0 ||
inputType and InputType.TYPE_NUMBER_VARIATION_PASSWORD != 0 -> {
result?.passwordId = autofillId
Log.d(TAG, "Autofill password android type: $inputType")
return true
}
inputType and InputType.TYPE_TEXT_VARIATION_EMAIL_SUBJECT != 0 ||
inputType and InputType.TYPE_TEXT_VARIATION_FILTER != 0 ||
inputType and InputType.TYPE_TEXT_VARIATION_LONG_MESSAGE != 0 ||
inputType and InputType.TYPE_TEXT_VARIATION_PHONETIC != 0 ||
inputType and InputType.TYPE_TEXT_VARIATION_POSTAL_ADDRESS != 0 ||
inputType and InputType.TYPE_TEXT_VARIATION_URI != 0 ||
inputType and InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT != 0 ||
inputType and InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS != 0 ||
inputType and InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD != 0 -> {
// Type not used
}
else -> {
Log.d(TAG, "Autofill unknown android type: $inputType")
usernameCandidate = autofillId
}
InputType.TYPE_CLASS_NUMBER -> {
when {
inputIsVariationType(inputType,
InputType.TYPE_NUMBER_VARIATION_NORMAL) -> {
usernameCandidate = autofillId
Log.d(TAG, "Autofill usernale candidate android number type: ${showHexInputType(inputType)}")
}
inputIsVariationType(inputType,
InputType.TYPE_NUMBER_VARIATION_PASSWORD) -> {
result?.passwordId = autofillId
Log.d(TAG, "Autofill password android number type: ${showHexInputType(inputType)}")
usernameNeeded = false
return true
}
else -> {
Log.d(TAG, "Autofill unknown android number type: ${showHexInputType(inputType)}")
}
}
}
}

View File

@@ -52,7 +52,11 @@ class AdvancedUnlockedManager(var context: FragmentActivity,
private var biometricUnlockDatabaseHelper: BiometricUnlockDatabaseHelper? = null
private var biometricMode: Mode = Mode.UNAVAILABLE
private var isBiometricPromptAutoOpenEnable = PreferencesUtil.isBiometricPromptAutoOpenEnable(context)
private var biometricPromptAutoOpenPreference = PreferencesUtil.isBiometricPromptAutoOpenEnable(context)
var isBiometricPromptAutoOpenEnable: Boolean = true
get() {
return field && biometricPromptAutoOpenPreference
}
private var cipherDatabaseAction = CipherDatabaseAction.getInstance(context.applicationContext)
@@ -272,6 +276,8 @@ class AdvancedUnlockedManager(var context: FragmentActivity,
}
fun destroy() {
// Close the biometric prompt
biometricUnlockDatabaseHelper?.closeBiometricPrompt()
// Restore the checked listener
checkboxPasswordView?.setOnCheckedChangeListener(onCheckedPasswordChangeListener)
}

View File

@@ -271,6 +271,10 @@ class BiometricUnlockDatabaseHelper(private val context: FragmentActivity) {
}
}
fun closeBiometricPrompt() {
biometricPrompt?.cancelAuthentication()
}
interface BiometricUnlockErrorCallback {
fun onInvalidKeyException(e: Exception)
fun onBiometricException(e: Exception)

View File

@@ -41,17 +41,6 @@ object CipherFactory {
Security.addProvider(BouncyCastleProvider())
}
@Throws(NoSuchAlgorithmException::class, NoSuchPaddingException::class)
@JvmOverloads
fun getInstance(transformation: String, androidOverride: Boolean = false): Cipher {
// Return the native AES if it is possible
return if (!deviceBlacklisted() && !androidOverride && hasNativeImplementation(transformation) && NativeLib.loaded()) {
Cipher.getInstance(transformation, AESProvider())
} else {
Cipher.getInstance(transformation)
}
}
fun deviceBlacklisted(): Boolean {
if (!blacklistInit) {
blacklistInit = true
@@ -65,6 +54,16 @@ object CipherFactory {
return transformation == "AES/CBC/PKCS5Padding"
}
@Throws(NoSuchAlgorithmException::class, NoSuchPaddingException::class)
fun getInstance(transformation: String, androidOverride: Boolean = false): Cipher {
// Return the native AES if it is possible
return if (!deviceBlacklisted() && !androidOverride && hasNativeImplementation(transformation) && NativeLib.loaded()) {
Cipher.getInstance(transformation, AESProvider())
} else {
Cipher.getInstance(transformation)
}
}
/**
* Generate appropriate cipher based on KeePass 2.x UUID's
*/

View File

@@ -74,12 +74,10 @@ object CryptoUtil {
return ret
}
@JvmOverloads
fun hashSha256(data: ByteArray, offset: Int = 0, count: Int = data.size): ByteArray {
return hashGen("SHA-256", data, offset, count)
}
@JvmOverloads
fun hashSha512(data: ByteArray, offset: Int = 0, count: Int = data.size): ByteArray {
return hashGen("SHA-512", data, offset, count)
}

View File

@@ -93,11 +93,11 @@ class ProgressDialogThread(private val activity: FragmentActivity) {
TimeoutHelper.temporarilyDisableTimeout()
// Stop the opening notification
DatabaseOpenNotificationService.stop(activity)
startOrUpdateDialog(titleId, messageId, warningId)
startDialog(titleId, messageId, warningId)
}
override fun onUpdateAction(titleId: Int?, messageId: Int?, warningId: Int?) {
startOrUpdateDialog(titleId, messageId, warningId)
updateDialog(titleId, messageId, warningId)
}
override fun onStopAction(actionTask: String, result: ActionRunnable.Result) {
@@ -120,7 +120,9 @@ class ProgressDialogThread(private val activity: FragmentActivity) {
}
}
private fun startOrUpdateDialog(titleId: Int?, messageId: Int?, warningId: Int?) {
private fun startDialog(titleId: Int? = null,
messageId: Int? = null,
warningId: Int? = null) {
if (progressTaskDialogFragment == null) {
progressTaskDialogFragment = activity.supportFragmentManager
.findFragmentByTag(PROGRESS_TASK_DIALOG_TAG) as ProgressTaskDialogFragment?
@@ -129,6 +131,10 @@ class ProgressDialogThread(private val activity: FragmentActivity) {
progressTaskDialogFragment = ProgressTaskDialogFragment()
progressTaskDialogFragment?.show(activity.supportFragmentManager, PROGRESS_TASK_DIALOG_TAG)
}
updateDialog(titleId, messageId, warningId)
}
private fun updateDialog(titleId: Int?, messageId: Int?, warningId: Int?) {
progressTaskDialogFragment?.apply {
titleId?.let {
updateTitle(it)
@@ -194,6 +200,8 @@ class ProgressDialogThread(private val activity: FragmentActivity) {
bindService()
}
DATABASE_STOP_TASK_ACTION -> {
// Remove the progress task
stopDialog()
unBindService()
}
}

View File

@@ -51,7 +51,6 @@ import com.kunzisoft.keepass.stream.readBytes4ToUInt
import com.kunzisoft.keepass.tasks.ProgressTaskUpdater
import com.kunzisoft.keepass.utils.SingletonHolder
import com.kunzisoft.keepass.utils.UriUtil
import org.apache.commons.io.FileUtils
import java.io.*
import java.util.*
@@ -405,14 +404,9 @@ class Database {
return mSearchHelper?.createVirtualGroupWithSearchResult(this, searchQuery, SearchParameters(), max)
}
fun createVirtualGroupFromSearch(searchInfo: SearchInfo,
max: Int = Integer.MAX_VALUE): Group? {
val query = (if (searchInfo.webDomain != null)
searchInfo.webDomain
else
searchInfo.applicationId)
?: return null
return mSearchHelper?.createVirtualGroupWithSearchResult(this, query, SearchParameters().apply {
fun createVirtualGroupFromSearchInfo(searchInfoString: String,
max: Int = Integer.MAX_VALUE): Group? {
return mSearchHelper?.createVirtualGroupWithSearchResult(this, searchInfoString, SearchParameters().apply {
searchInTitles = false
searchInUserNames = false
searchInPasswords = false
@@ -492,7 +486,9 @@ class Database {
mDatabaseKDBX?.clearCache()
// In all cases, delete all the files in the temp dir
try {
FileUtils.cleanDirectory(filesDirectory)
filesDirectory?.let { directory ->
cleanDirectory(directory)
}
} catch (e: Exception) {
Log.e(TAG, "Unable to clear the directory cache.", e)
}
@@ -503,6 +499,17 @@ class Database {
this.loaded = false
}
private fun cleanDirectory(directory: File) {
directory.listFiles()?.let { files ->
for (file in files) {
if (file.isDirectory) {
cleanDirectory(file)
}
file.delete()
}
}
}
fun validatePasswordEncoding(password: String?, containsKeyFile: Boolean): Boolean {
return mDatabaseKDB?.validatePasswordEncoding(password, containsKeyFile)
?: mDatabaseKDBX?.validatePasswordEncoding(password, containsKeyFile)

View File

@@ -41,7 +41,6 @@ class DeletedObject {
constructor()
@JvmOverloads
constructor(uuid: UUID, deletionTime: Date = Date()) {
this.uuid = uuid
this.mDeletionTime = deletionTime

View File

@@ -20,15 +20,14 @@
package com.kunzisoft.keepass.database.element.database
import com.kunzisoft.keepass.crypto.keyDerivation.KdfEngine
import com.kunzisoft.keepass.database.element.security.EncryptionAlgorithm
import com.kunzisoft.keepass.database.element.entry.EntryVersioned
import com.kunzisoft.keepass.database.element.group.GroupVersioned
import com.kunzisoft.keepass.database.element.icon.IconImageFactory
import com.kunzisoft.keepass.database.element.node.NodeId
import com.kunzisoft.keepass.database.element.node.Type
import com.kunzisoft.keepass.database.element.security.EncryptionAlgorithm
import com.kunzisoft.keepass.database.exception.DuplicateUuidDatabaseException
import com.kunzisoft.keepass.database.exception.KeyFileEmptyDatabaseException
import org.apache.commons.io.IOUtils
import java.io.*
import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
@@ -127,7 +126,7 @@ abstract class DatabaseVersioned<
protected fun getFileKey(keyInputStream: InputStream): ByteArray {
val keyByteArrayOutputStream = ByteArrayOutputStream()
IOUtils.copy(keyInputStream, keyByteArrayOutputStream)
keyInputStream.copyTo(keyByteArrayOutputStream)
val keyData = keyByteArrayOutputStream.toByteArray()
val keyByteArrayInputStream = ByteArrayInputStream(keyData)

View File

@@ -31,7 +31,6 @@ class NodeIdInt : NodeId<Int> {
constructor(source: NodeIdInt) : this(source.id)
@JvmOverloads
constructor(groupId: Int = Random().nextInt()) : super() {
this.id = groupId
}

View File

@@ -30,7 +30,6 @@ class NodeIdUUID : NodeId<UUID> {
constructor(source: NodeIdUUID) : this(source.id)
@JvmOverloads
constructor(uuid: UUID = UUID.randomUUID()) : super() {
this.id = uuid
}

View File

@@ -33,7 +33,6 @@ class ProtectedString : Parcelable {
this.stringValue = toCopy.stringValue
}
@JvmOverloads
constructor(enableProtection: Boolean = false, string: String = "") {
this.isProtected = enableProtection
this.stringValue = string

View File

@@ -19,17 +19,57 @@
*/
package com.kunzisoft.keepass.database.search
import android.content.Context
import com.kunzisoft.keepass.database.action.node.NodeHandler
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.element.Entry
import com.kunzisoft.keepass.database.element.Group
import com.kunzisoft.keepass.database.search.iterator.EntrySearchStringIteratorKDB
import com.kunzisoft.keepass.database.search.iterator.EntrySearchStringIteratorKDBX
import com.kunzisoft.keepass.model.EntryInfo
import com.kunzisoft.keepass.model.SearchInfo
import com.kunzisoft.keepass.model.getSearchString
import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.timeout.TimeoutHelper
class SearchHelper(private val isOmitBackup: Boolean) {
companion object {
const val MAX_SEARCH_ENTRY = 6
/**
* Utility method to perform actions if item is found or not after an auto search in [database]
*/
fun checkAutoSearchInfo(context: Context,
database: Database,
searchInfo: SearchInfo?,
onItemsFound: (items: List<EntryInfo>) -> Unit,
onItemNotFound: () -> Unit,
onDatabaseClosed: () -> Unit) {
if (database.loaded && TimeoutHelper.checkTime(context)) {
var searchWithoutUI = false
if (PreferencesUtil.isAutofillAutoSearchEnable(context)
&& searchInfo != null
&& !searchInfo.containsOnlyNullValues()) {
// If search provide results
database.createVirtualGroupFromSearchInfo(
searchInfo.getSearchString(context),
MAX_SEARCH_ENTRY
)?.let { searchGroup ->
if (searchGroup.getNumberOfChildEntries() > 0) {
searchWithoutUI = true
onItemsFound.invoke(
searchGroup.getChildEntriesInfo(database))
}
}
}
if (!searchWithoutUI) {
onItemNotFound.invoke()
}
} else {
onDatabaseClosed.invoke()
}
}
}
private var incrementEntry = 0

View File

@@ -36,6 +36,7 @@ import android.widget.FrameLayout
import android.widget.PopupWindow
import android.widget.TextView
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.MagikeyboardLauncherActivity
import com.kunzisoft.keepass.adapters.FieldsAdapter
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.model.EntryInfo
@@ -211,7 +212,7 @@ class MagikIME : InputMethodService(), KeyboardView.OnKeyboardActionListener {
// Stop current service and reinit entry
stopService(Intent(this, KeyboardEntryNotificationService::class.java))
removeEntryInfo()
val intent = Intent(this, KeyboardLauncherActivity::class.java)
val intent = Intent(this, MagikeyboardLauncherActivity::class.java)
// New task needed because don't launch from an Activity context
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
startActivity(intent)
@@ -248,7 +249,9 @@ class MagikIME : InputMethodService(), KeyboardView.OnKeyboardActionListener {
}
popupCustomKeys?.showAtLocation(keyboardView, Gravity.END or Gravity.TOP, 0, 0)
}
Keyboard.KEYCODE_DELETE -> inputConnection.deleteSurroundingText(1, 0)
Keyboard.KEYCODE_DELETE -> {
inputConnection.sendKeyEvent(KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL))
}
Keyboard.KEYCODE_DONE -> inputConnection.performEditorAction(EditorInfo.IME_ACTION_GO)
}
}
@@ -321,11 +324,11 @@ class MagikIME : InputMethodService(), KeyboardView.OnKeyboardActionListener {
context.sendBroadcast(Intent(REMOVE_ENTRY_MAGIKEYBOARD_ACTION))
}
fun addEntryAndLaunchNotificationIfAllowed(context: Context, entry: EntryInfo) {
fun addEntryAndLaunchNotificationIfAllowed(context: Context, entry: EntryInfo, toast: Boolean = false) {
// Add a new entry
entryInfoKey = entry
// Launch notification if allowed
KeyboardEntryNotificationService.launchNotificationIfAllowed(context, entry)
KeyboardEntryNotificationService.launchNotificationIfAllowed(context, entry, toast)
}
}
}

View File

@@ -1,12 +1,31 @@
package com.kunzisoft.keepass.model
import android.content.Context
import android.content.res.Resources
import android.os.Parcel
import android.os.Parcelable
import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.utils.ObjectNameResource
import com.kunzisoft.keepass.utils.UriUtil
class SearchInfo : Parcelable {
class SearchInfo : ObjectNameResource, Parcelable {
var applicationId: String? = null
set(value) {
field = when {
value == null -> null
Regex(APPLICATION_ID_REGEX).matches(value) -> value
else -> null
}
}
var webDomain: String? = null
set(value) {
field = when {
value == null -> null
Regex(WEB_DOMAIN_REGEX).matches(value) -> value
else -> null
}
}
constructor()
@@ -26,7 +45,40 @@ class SearchInfo : Parcelable {
parcel.writeString(webDomain ?: "")
}
override fun getName(resources: Resources): String {
return toString()
}
fun containsOnlyNullValues(): Boolean {
return applicationId == null && webDomain == null
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as SearchInfo
if (applicationId != other.applicationId) return false
if (webDomain != other.webDomain) return false
return true
}
override fun hashCode(): Int {
var result = applicationId?.hashCode() ?: 0
result = 31 * result + (webDomain?.hashCode() ?: 0)
return result
}
override fun toString(): String {
return webDomain ?: applicationId ?: ""
}
companion object {
// https://gist.github.com/rishabhmhjn/8663966
const val APPLICATION_ID_REGEX = "^(?:[a-zA-Z]+(?:\\d*[a-zA-Z_]*)*)(?:\\.[a-zA-Z]+(?:\\d*[a-zA-Z_]*)*)+\$"
const val WEB_DOMAIN_REGEX = "^(?!://)([a-zA-Z0-9-_]+\\.)*[a-zA-Z0-9][a-zA-Z0-9-_]+\\.[a-zA-Z]{2,11}?\$"
@JvmField
val CREATOR: Parcelable.Creator<SearchInfo> = object : Parcelable.Creator<SearchInfo> {
@@ -40,3 +92,14 @@ class SearchInfo : Parcelable {
}
}
}
fun SearchInfo.getSearchString(context: Context): String {
return run {
if (!PreferencesUtil.searchSubdomains(context))
UriUtil.getWebDomainWithoutSubDomain(webDomain)
else
webDomain
}
?: applicationId
?: ""
}

View File

@@ -81,6 +81,7 @@ class AttachmentFileNotificationService: LockNotificationService() {
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
super.onStartCommand(intent, flags, startId)
val downloadFileUri: Uri? = if (intent?.hasExtra(DOWNLOAD_FILE_URI_KEY) == true) {
intent.getParcelableExtra(DOWNLOAD_FILE_URI_KEY)

View File

@@ -55,6 +55,8 @@ class ClipboardEntryNotificationService : LockNotificationService() {
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
super.onStartCommand(intent, flags, startId)
// Get entry info from intent
mEntryInfo = intent?.getParcelableExtra(EXTRA_ENTRY_INFO)

View File

@@ -48,6 +48,7 @@ class DatabaseOpenNotificationService: LockNotificationService() {
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
super.onStartCommand(intent, flags, startId)
when(intent?.action) {
ACTION_CLOSE_DATABASE -> {

View File

@@ -39,7 +39,6 @@ import com.kunzisoft.keepass.tasks.ProgressTaskUpdater
import com.kunzisoft.keepass.utils.DATABASE_START_TASK_ACTION
import com.kunzisoft.keepass.utils.DATABASE_STOP_TASK_ACTION
import java.util.*
import java.util.concurrent.atomic.AtomicBoolean
import kotlin.collections.ArrayList
class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdater {
@@ -61,8 +60,6 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
fun addActionTaskListener(actionTaskListener: ActionTaskListener) {
mActionTaskListeners.add(actionTaskListener)
// To prevent task dialog to be unbound before the display
actionRunnableAsyncTask?.allowFinishTask?.set(true)
}
fun removeActionTaskListener(actionTaskListener: ActionTaskListener) {
@@ -78,7 +75,7 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
fun checkAction() {
mActionTaskListeners.forEach { actionTaskListener ->
actionTaskListener.onUpdateAction(mTitleId, mMessageId, mWarningId)
actionTaskListener.onStartAction(mTitleId, mMessageId, mWarningId)
}
}
@@ -87,6 +84,7 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
super.onStartCommand(intent, flags, startId)
if (intent == null) return START_REDELIVER_INTENT
@@ -571,8 +569,6 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
private val onPostExecute: (result: ActionRunnable.Result) -> Unit)
: AsyncTask<((ProgressTaskUpdater?) -> ActionRunnable), Void, ActionRunnable.Result>() {
var allowFinishTask = AtomicBoolean(false)
override fun onPreExecute() {
super.onPreExecute()
onPreExecute.invoke()
@@ -586,10 +582,6 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
resultTask = result
}
}
// Additional wait if the dialog take time to show
while(!allowFinishTask.get()) {
Thread.sleep(250)
}
return resultTask
}

View File

@@ -23,6 +23,7 @@ import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.util.Log
import android.widget.Toast
import androidx.preference.PreferenceManager
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.magikeyboard.MagikIME
@@ -49,6 +50,8 @@ class KeyboardEntryNotificationService : LockNotificationService() {
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
super.onStartCommand(intent, flags, startId)
//Get settings
notificationTimeoutMilliSecs = PreferenceManager.getDefaultSharedPreferences(this)
.getString(getString(R.string.keyboard_entry_timeout_key),
@@ -146,8 +149,9 @@ class KeyboardEntryNotificationService : LockNotificationService() {
const val ACTION_CLEAN_KEYBOARD_ENTRY = "ACTION_CLEAN_KEYBOARD_ENTRY"
fun launchNotificationIfAllowed(context: Context, entry: EntryInfo) {
fun launchNotificationIfAllowed(context: Context, entry: EntryInfo, toast: Boolean) {
val containsURLToCopy = entry.url.isNotEmpty()
val containsUsernameToCopy = entry.username.isNotEmpty()
val containsPasswordToCopy = entry.password.isNotEmpty()
val containsExtraFieldToCopy = entry.customFields.isNotEmpty()
@@ -155,14 +159,22 @@ class KeyboardEntryNotificationService : LockNotificationService() {
var startService = false
val intent = Intent(context, KeyboardEntryNotificationService::class.java)
// Show the notification if allowed in Preferences
if (PreferencesUtil.isKeyboardNotificationEntryEnable(context)) {
if (containsUsernameToCopy || containsPasswordToCopy || containsExtraFieldToCopy) {
if (containsURLToCopy || containsUsernameToCopy || containsPasswordToCopy || containsExtraFieldToCopy) {
if (toast) {
Toast.makeText(context,
context.getString(R.string.keyboard_notification_entry_content_title, entry.title),
Toast.LENGTH_SHORT).show()
}
// Show the notification if allowed in Preferences
if (PreferencesUtil.isKeyboardNotificationEntryEnable(context)) {
startService = true
context.startService(intent.apply {
putExtra(ENTRY_INFO_KEY, entry)
})
}
} else {
MagikIME.removeEntry(context)
}
if (!startService)

View File

@@ -26,6 +26,7 @@ import com.kunzisoft.keepass.utils.unregisterLockReceiver
abstract class LockNotificationService : NotificationService() {
private var onStart: Boolean = false
private var mLockReceiver: LockReceiver? = null
protected open fun actionOnLock() {
@@ -38,11 +39,17 @@ abstract class LockNotificationService : NotificationService() {
// Register a lock receiver to stop notification service when lock on keyboard is performed
mLockReceiver = LockReceiver {
if (onStart)
actionOnLock()
}
registerLockReceiver(mLockReceiver)
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
onStart = true
return super.onStartCommand(intent, flags, startId)
}
protected fun stopTask(task: Thread?) {
if (task != null && task.isAlive)
task.interrupt()

View File

@@ -23,9 +23,9 @@ import android.os.Bundle
import android.view.MenuItem
import androidx.appcompat.widget.Toolbar
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.stylish.StylishActivity
import com.kunzisoft.keepass.activities.selection.SpecialModeActivity
class AutofillSettingsActivity : StylishActivity() {
class AutofillSettingsActivity : SpecialModeActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

View File

@@ -20,9 +20,12 @@
package com.kunzisoft.keepass.settings
import android.os.Bundle
import androidx.fragment.app.DialogFragment
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.settings.preferencedialogfragment.AutofillBlocklistAppIdPreferenceDialogFragmentCompat
import com.kunzisoft.keepass.settings.preferencedialogfragment.AutofillBlocklistWebDomainPreferenceDialogFragmentCompat
class AutofillSettingsFragment : PreferenceFragmentCompat() {
@@ -30,4 +33,34 @@ class AutofillSettingsFragment : PreferenceFragmentCompat() {
// Load the preferences from an XML resource
setPreferencesFromResource(R.xml.preferences_autofill, rootKey)
}
override fun onDisplayPreferenceDialog(preference: Preference?) {
var otherDialogFragment = false
var dialogFragment: DialogFragment? = null
when (preference?.key) {
getString(R.string.autofill_application_id_blocklist_key) -> {
dialogFragment = AutofillBlocklistAppIdPreferenceDialogFragmentCompat.newInstance(preference.key)
}
getString(R.string.autofill_web_domain_blocklist_key) -> {
dialogFragment = AutofillBlocklistWebDomainPreferenceDialogFragmentCompat.newInstance(preference.key)
}
else -> otherDialogFragment = true
}
if (dialogFragment != null) {
dialogFragment.setTargetFragment(this, 0)
dialogFragment.show(parentFragmentManager, TAG_AUTOFILL_PREF_FRAGMENT)
}
// Could not be handled here. Try with the super method.
else if (otherDialogFragment) {
super.onDisplayPreferenceDialog(preference)
}
}
companion object {
private const val TAG_AUTOFILL_PREF_FRAGMENT = "TAG_AUTOFILL_PREF_FRAGMENT"
}
}

View File

@@ -24,9 +24,9 @@ import androidx.appcompat.widget.Toolbar
import android.view.MenuItem
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.stylish.StylishActivity
import com.kunzisoft.keepass.activities.selection.SpecialModeActivity
class MagikeyboardSettingsActivity : StylishActivity() {
class MagikeyboardSettingsActivity : SpecialModeActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

View File

@@ -62,7 +62,6 @@ abstract class NestedSettingsFragment : PreferenceFragmentCompat() {
private const val TAG_KEY = "NESTED_KEY"
@JvmOverloads
fun newInstance(key: Screen, databaseReadOnly: Boolean = ReadOnlyHelper.READ_ONLY_DEFAULT)
: NestedSettingsFragment {
val fragment: NestedSettingsFragment = when (key) {

View File

@@ -20,8 +20,10 @@
package com.kunzisoft.keepass.settings
import android.content.Context
import android.content.res.Resources
import android.net.Uri
import androidx.preference.PreferenceManager
import com.kunzisoft.keepass.BuildConfig
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.element.SortNodeEnum
import com.kunzisoft.keepass.timeout.TimeoutHelper
@@ -97,6 +99,12 @@ object PreferencesUtil {
context.resources.getBoolean(R.bool.auto_focus_search_default))
}
fun searchSubdomains(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.subdomain_search_key),
context.resources.getBoolean(R.bool.subdomain_search_default))
}
fun showUsernamesListEntries(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.list_entries_show_username_key),
@@ -337,6 +345,12 @@ object PreferencesUtil {
context.resources.getBoolean(R.bool.keyboard_notification_entry_default))
}
fun isKeyboardSearchShareEnable(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.keyboard_search_share_key),
context.resources.getBoolean(R.bool.keyboard_search_share_default))
}
fun isAutoGoActionEnable(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.keyboard_auto_go_action_key),
@@ -360,4 +374,46 @@ object PreferencesUtil {
return prefs.getBoolean(context.getString(R.string.autofill_auto_search_key),
context.resources.getBoolean(R.bool.autofill_auto_search_default))
}
/**
* Retrieve the default Blocklist for application ID, including the current app
*/
fun getDefaultApplicationIdBlocklist(resources: Resources?): Set<String> {
return resources?.getStringArray(R.array.autofill_application_id_blocklist_default)
?.toMutableSet()?.apply {
add(BuildConfig.APPLICATION_ID)
} ?: emptySet()
}
fun applicationIdBlocklist(context: Context): Set<String> {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getStringSet(context.getString(R.string.autofill_application_id_blocklist_key),
getDefaultApplicationIdBlocklist(context.resources))
?: emptySet()
}
fun webDomainBlocklist(context: Context): Set<String> {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getStringSet(context.getString(R.string.autofill_web_domain_blocklist_key),
context.resources.getStringArray(R.array.autofill_web_domain_blocklist_default).toMutableSet())
?: emptySet()
}
fun addApplicationIdToBlocklist(context: Context, applicationId: String) {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
val setItems: MutableSet<String> = applicationIdBlocklist(context).toMutableSet()
setItems.add(applicationId)
prefs.edit()
.putStringSet(context.getString(R.string.autofill_application_id_blocklist_key), setItems)
.apply()
}
fun addWebDomainToBlocklist(context: Context, webDomain: String) {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
val setItems: MutableSet<String> = webDomainBlocklist(context).toMutableSet()
setItems.add(webDomain)
prefs.edit()
.putStringSet(context.getString(R.string.autofill_web_domain_blocklist_key), setItems)
.apply()
}
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePassDX.
*
* KeePassDX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* KeePassDX is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.settings.preference
import android.content.Context
import android.util.AttributeSet
import androidx.preference.DialogPreference
import com.kunzisoft.keepass.R
open class InputListPreference @JvmOverloads constructor(context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = R.attr.dialogPreferenceStyle,
defStyleRes: Int = defStyleAttr)
: DialogPreference(context, attrs, defStyleAttr, defStyleRes) {
override fun getDialogLayoutResource(): Int {
return R.layout.pref_dialog_input_list
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright 2020 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePassDX.
*
* KeePassDX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* KeePassDX is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.settings.preferencedialogfragment
import android.os.Bundle
import com.kunzisoft.keepass.model.SearchInfo
import com.kunzisoft.keepass.settings.PreferencesUtil
class AutofillBlocklistAppIdPreferenceDialogFragmentCompat
: AutofillBlocklistPreferenceDialogFragmentCompat() {
override fun buildSearchInfoFromString(searchInfoString: String): SearchInfo? {
val newSearchInfo = searchInfoString
// remove chars not allowed in application ID
.replace(Regex("[^a-zA-Z0-9_.]+"), "")
return SearchInfo().apply { this.applicationId = newSearchInfo }
}
override fun getDefaultValues(): Set<String> {
return PreferencesUtil.getDefaultApplicationIdBlocklist(this.resources)
}
companion object {
fun newInstance(key: String): AutofillBlocklistAppIdPreferenceDialogFragmentCompat {
val fragment = AutofillBlocklistAppIdPreferenceDialogFragmentCompat()
val bundle = Bundle(1)
bundle.putString(ARG_KEY, key)
fragment.arguments = bundle
return fragment
}
}
}

View File

@@ -0,0 +1,149 @@
/*
* Copyright 2020 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePassDX.
*
* KeePassDX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* KeePassDX is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.settings.preferencedialogfragment
import android.os.Bundle
import android.view.View
import android.view.inputmethod.EditorInfo
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.model.SearchInfo
import com.kunzisoft.keepass.settings.preferencedialogfragment.adapter.AutofillBlocklistAdapter
import java.util.*
import kotlin.Comparator
import kotlin.collections.HashSet
abstract class AutofillBlocklistPreferenceDialogFragmentCompat
: InputPreferenceDialogFragmentCompat(),
AutofillBlocklistAdapter.ItemDeletedCallback<SearchInfo> {
private var persistedItems = TreeSet<SearchInfo>(
Comparator { o1, o2 -> o1.toString().compareTo(o2.toString()) })
private var filterAdapter: AutofillBlocklistAdapter<SearchInfo>? = null
abstract fun buildSearchInfoFromString(searchInfoString: String): SearchInfo?
abstract fun getDefaultValues(): Set<String>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// To get items for saved instance state
savedInstanceState?.getParcelableArray(ITEMS_KEY)?.let {
it.forEach { itemSaved ->
(itemSaved as SearchInfo?)?.let { item ->
persistedItems.add(item)
}
}
} ?: run {
// Or from preference
preference.getPersistedStringSet(getDefaultValues()).forEach { searchInfoString ->
addSearchInfo(searchInfoString)
}
}
}
override fun onBindDialogView(view: View) {
super.onBindDialogView(view)
setOnInputTextEditorActionListener(TextView.OnEditorActionListener { _, actionId, _ ->
when (actionId) {
EditorInfo.IME_ACTION_DONE -> {
if (inputText.isEmpty()) {
onDialogClosed(true)
dialog?.dismiss()
true
} else {
addItemFromInputText()
false
}
}
else -> false
}
})
val addItemButton = view.findViewById<View>(R.id.add_item_button)
addItemButton?.setOnClickListener {
addItemFromInputText()
}
val recyclerView = view.findViewById<RecyclerView>(R.id.pref_dialog_list)
recyclerView.layoutManager = LinearLayoutManager(context)
activity?.let { activity ->
filterAdapter = AutofillBlocklistAdapter(activity)
filterAdapter?.setItemDeletedCallback(this)
recyclerView.adapter = filterAdapter
filterAdapter?.replaceItems(persistedItems.toList())
}
}
private fun addSearchInfo(searchInfoString: String): Boolean {
val itemToAdd = buildSearchInfoFromString(searchInfoString)
return if (itemToAdd != null && !itemToAdd.containsOnlyNullValues()) {
persistedItems.add(itemToAdd)
true
} else {
false
}
}
private fun addItemFromInputText() {
if (addSearchInfo(inputText)) {
inputText = ""
} else {
setInputTextError(getString(R.string.error_string_type))
}
filterAdapter?.replaceItems(persistedItems.toList())
}
override fun onItemDeleted(item: SearchInfo) {
persistedItems.remove(item)
filterAdapter?.replaceItems(persistedItems.toList())
}
private fun getStringItems(): Set<String> {
val setItems = HashSet<String>()
persistedItems.forEach {
it.getName(resources).let { item ->
setItems.add(item)
}
}
return setItems
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putParcelableArray(ITEMS_KEY, persistedItems.toTypedArray())
}
override fun onDialogClosed(positiveResult: Boolean) {
if (positiveResult) {
preference.persistStringSet(getStringItems())
}
}
companion object {
private const val ITEMS_KEY = "ITEMS_KEY"
}
}

View File

@@ -0,0 +1,55 @@
/*
* Copyright 2020 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePassDX.
*
* KeePassDX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* KeePassDX is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.settings.preferencedialogfragment
import android.os.Bundle
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.model.SearchInfo
class AutofillBlocklistWebDomainPreferenceDialogFragmentCompat
: AutofillBlocklistPreferenceDialogFragmentCompat() {
override fun buildSearchInfoFromString(searchInfoString: String): SearchInfo? {
val newSearchInfo = searchInfoString
// remove prefix https://
.replace(Regex("^.*://"), "")
// Remove suffix /login...
.replace(Regex("/.*$"), "")
return SearchInfo().apply { webDomain = newSearchInfo }
}
override fun getDefaultValues(): Set<String> {
return context?.resources
?.getStringArray(R.array.autofill_web_domain_blocklist_default)
?.toMutableSet()
?: emptySet()
}
companion object {
fun newInstance(key: String): AutofillBlocklistWebDomainPreferenceDialogFragmentCompat {
val fragment = AutofillBlocklistWebDomainPreferenceDialogFragmentCompat()
val bundle = Bundle(1)
bundle.putString(ARG_KEY, key)
fragment.arguments = bundle
return fragment
}
}
}

View File

@@ -21,10 +21,12 @@ package com.kunzisoft.keepass.settings.preferencedialogfragment
import android.view.View
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import android.widget.CompoundButton
import android.widget.EditText
import android.widget.TextView
import androidx.annotation.StringRes
import androidx.core.content.ContextCompat
import androidx.preference.PreferenceDialogFragmentCompat
import com.kunzisoft.keepass.R
@@ -34,6 +36,8 @@ abstract class InputPreferenceDialogFragmentCompat : PreferenceDialogFragmentCom
private var textExplanationView: TextView? = null
private var switchElementView: CompoundButton? = null
private var mOnInputTextEditorActionListener: TextView.OnEditorActionListener? = null
var inputText: String
get() = this.inputTextView?.text?.toString() ?: ""
set(inputText) {
@@ -43,6 +47,14 @@ abstract class InputPreferenceDialogFragmentCompat : PreferenceDialogFragmentCom
}
}
fun setInputTextError(error: CharSequence) {
this.inputTextView?.error = error
}
fun setOnInputTextEditorActionListener(onEditorActionListener: TextView.OnEditorActionListener) {
this.mOnInputTextEditorActionListener = onEditorActionListener
}
var explanationText: String?
get() = textExplanationView?.text?.toString() ?: ""
set(explanationText) {
@@ -63,16 +75,21 @@ abstract class InputPreferenceDialogFragmentCompat : PreferenceDialogFragmentCom
inputTextView = view.findViewById(R.id.input_text)
inputTextView?.apply {
imeOptions = EditorInfo.IME_ACTION_DONE
setOnEditorActionListener { _, actionId, _ ->
when (actionId) {
EditorInfo.IME_ACTION_DONE -> {
onDialogClosed(true)
dialog?.dismiss()
true
}
else -> {
false
setOnEditorActionListener { v, actionId, event ->
if (mOnInputTextEditorActionListener == null) {
when (actionId) {
EditorInfo.IME_ACTION_DONE -> {
onDialogClosed(true)
dialog?.dismiss()
true
}
else -> {
false
}
}
} else {
mOnInputTextEditorActionListener?.onEditorAction(v, actionId, event)
?: false
}
}
}
@@ -82,6 +99,20 @@ abstract class InputPreferenceDialogFragmentCompat : PreferenceDialogFragmentCom
switchElementView?.visibility = View.GONE
}
protected fun hideKeyboard(): Boolean {
context?.let {
ContextCompat.getSystemService(it, InputMethodManager::class.java)?.let { inputManager ->
activity?.currentFocus?.let { focus ->
val windowToken = focus.windowToken
if (windowToken != null) {
return inputManager.hideSoftInputFromWindow(windowToken, 0)
}
}
}
}
return false
}
fun setInoutText(@StringRes inputTextId: Int) {
inputText = getString(inputTextId)
}

View File

@@ -0,0 +1,85 @@
/*
* Copyright 2020 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePassDX.
*
* KeePassDX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* KeePassDX is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.settings.preferencedialogfragment.adapter
import android.content.Context
import androidx.recyclerview.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.utils.ObjectNameResource
import java.util.ArrayList
class AutofillBlocklistAdapter<T : ObjectNameResource>(private val context: Context)
: RecyclerView.Adapter<AutofillBlocklistAdapter.BlocklistItemViewHolder>() {
private val inflater: LayoutInflater = LayoutInflater.from(context)
val items: MutableList<T> = ArrayList()
private var itemDeletedCallback: ItemDeletedCallback<T>? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BlocklistItemViewHolder {
val view = inflater.inflate(R.layout.pref_dialog_list_removable_item, parent, false)
return BlocklistItemViewHolder(view)
}
override fun onBindViewHolder(holder: BlocklistItemViewHolder, position: Int) {
val item = this.items[position]
holder.textItem.text = item.getName(context.resources)
holder.deleteButton.setOnClickListener(OnItemDeleteClickListener(item))
}
override fun getItemCount(): Int {
return items.size
}
fun replaceItems(items: List<T>) {
this.items.clear()
this.items.addAll(items)
notifyDataSetChanged()
}
private inner class OnItemDeleteClickListener(private val itemClicked: T) : View.OnClickListener {
override fun onClick(view: View) {
itemDeletedCallback?.onItemDeleted(itemClicked)
notifyDataSetChanged()
}
}
fun setItemDeletedCallback(itemDeletedCallback: ItemDeletedCallback<T>) {
this.itemDeletedCallback = itemDeletedCallback
}
interface ItemDeletedCallback<T> {
fun onItemDeleted(item: T)
}
class BlocklistItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var textItem: TextView = itemView.findViewById(R.id.pref_dialog_list_text)
var deleteButton: ImageView = itemView.findViewById(R.id.pref_dialog_list_delete_button)
}
}

View File

@@ -50,7 +50,6 @@ object MenuUtil {
/*
* @param checkLock Check the time lock before launch settings in LockingActivity
*/
@JvmOverloads
fun onDefaultMenuOptionsItemSelected(activity: Activity,
item: MenuItem,
readOnly: Boolean = READ_ONLY_DEFAULT,

View File

@@ -86,6 +86,19 @@ object UriUtil {
null
}
fun getWebDomainWithoutSubDomain(webDomain: String?): String? {
webDomain?.split(".")?.let { domainArray ->
if (domainArray.isEmpty()) {
return ""
}
if (domainArray.size == 1) {
return domainArray[0];
}
return domainArray[domainArray.size - 2] + "." + domainArray[domainArray.size - 1]
}
return null
}
fun decode(uri: String?): String {
return Uri.decode(uri) ?: ""
}

View File

@@ -309,15 +309,17 @@ class EntryContentsView @JvmOverloads constructor(context: Context,
enableActionButton: Boolean,
onActionClickListener: OnClickListener?) {
val entryCustomField = EntryCustomField(context, attrs, defStyle)
entryCustomField.apply {
val entryCustomField: EntryCustomField? = EntryCustomField(context, attrs, defStyle)
entryCustomField?.apply {
setLabel(title)
setValue(value.toString(), value.isProtected)
enableActionButton(enableActionButton)
assignActionButtonClickListener(onActionClickListener)
applyFontVisibility(fontInVisibility)
}
extrasView.addView(entryCustomField)
entryCustomField?.let {
extrasView.addView(it)
}
extrasContainerView.visibility = View.VISIBLE
}

View File

@@ -29,9 +29,9 @@ import android.widget.TextView
import androidx.core.content.ContextCompat
import com.kunzisoft.keepass.R
open class EntryCustomField @JvmOverloads constructor(context: Context,
attrs: AttributeSet? = null,
defStyle: Int = 0)
class EntryCustomField @JvmOverloads constructor(context: Context,
attrs: AttributeSet? = null,
defStyle: Int = 0)
: LinearLayout(context, attrs, defStyle) {
private val labelView: TextView

View File

@@ -0,0 +1,53 @@
/*
* Copyright 2020 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePassDX.
*
* KeePassDX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* KeePassDX is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.view
import android.content.Context
import android.util.AttributeSet
import android.view.View
import androidx.appcompat.widget.Toolbar
import com.kunzisoft.keepass.R
class SpecialModeView @JvmOverloads constructor(context: Context,
attrs: AttributeSet? = null,
defStyle: Int = androidx.appcompat.R.attr.toolbarStyle)
: Toolbar(context, attrs, defStyle) {
init {
setNavigationIcon(R.drawable.ic_close_white_24dp)
title = resources.getString(R.string.selection_mode)
}
var onCancelButtonClickListener: OnClickListener? = null
set(value) {
if (value != null)
setNavigationOnClickListener(value)
}
var visible: Boolean = false
set(value) {
visibility = if (value) {
View.VISIBLE
} else {
View.GONE
}
field = value
}
}

View File

@@ -33,7 +33,6 @@ import androidx.coordinatorlayout.widget.CoordinatorLayout
import com.google.android.material.snackbar.Snackbar
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.tasks.ActionRunnable
import java.util.*
/**
* Replace font by monospace, must be called after seText()
@@ -93,14 +92,17 @@ fun Toolbar.collapse(animate: Boolean = true) {
}
fun Toolbar.expand(animate: Boolean = true) {
visibility = View.VISIBLE
val actionBarHeight = layoutParams.height
layoutParams.height = 0
val slideAnimator = ValueAnimator
.ofInt(0, actionBarHeight)
if (animate)
slideAnimator.duration = 300L
slideAnimator.addUpdateListener { animation ->
layoutParams.height = animation.animatedValue as Int
if (layoutParams.height >= 1) {
visibility = View.VISIBLE
}
requestLayout()
}
AnimatorSet().apply {

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_selected="true" android:color="@color/colorTextInverse"/>
<item android:color="?android:attr/textColorSecondary"/>
</selector>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_selected="true" android:color="@color/colorTextInverse"/>
<item android:color="?android:attr/textColor"/>
</selector>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_selected="true" android:color="@color/colorTextInverse"/>
<item android:color="?android:attr/textColorSecondary"/>
</selector>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_selected="true" android:color="@color/colorTextInverse"/>
<item android:color="?android:attr/textColorPrimary"/>
</selector>

View File

@@ -8,8 +8,8 @@
<corners
android:radius="0dp" />
<padding
android:left="0dp"
android:right="0dp"
android:left="8dp"
android:right="8dp"
android:top="12dp"
android:bottom="12dp"/>
<solid android:color="?attr/colorAccent"/>

View File

@@ -5,8 +5,8 @@
<corners
android:radius="0dp" />
<padding
android:left="0dp"
android:right="0dp"
android:left="8dp"
android:right="8dp"
android:top="12dp"
android:bottom="12dp"/>
<solid android:color="@color/orange_light"/>
@@ -17,8 +17,8 @@
<corners
android:radius="0dp" />
<padding
android:left="0dp"
android:right="0dp"
android:left="8dp"
android:right="8dp"
android:top="12dp"
android:bottom="12dp"/>
<solid android:color="@color/orange"/>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FFFFFF"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM4,12c0,-4.42 3.58,-8 8,-8 1.85,0 3.55,0.63 4.9,1.69L5.69,16.9C4.63,15.55 4,13.85 4,12zM12,20c-1.85,0 -3.55,-0.63 -4.9,-1.69L18.31,7.1C19.37,8.45 20,10.15 20,12c0,4.42 -3.58,8 -8,8z"/>
</vector>

View File

@@ -26,13 +26,22 @@
android:importantForAutofill="noExcludeDescendants"
tools:targetApi="o">
<com.kunzisoft.keepass.view.SpecialModeView
android:id="@+id/special_mode_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="?attr/specialToolbarAppearance"
app:titleTextAppearance="@style/KeepassDXStyle.TextAppearance.Toolbar.Special.Title"
app:subtitleTextAppearance="@style/KeepassDXStyle.TextAppearance.Toolbar.Special.SubTitle"
app:layout_constraintTop_toTopOf="parent" />
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/activity_file_selection_coordinator_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="@drawable/background_repeat"
android:backgroundTint="?attr/colorPrimary"
app:layout_constraintTop_toTopOf="parent"
android:backgroundTint="?android:attr/textColor"
app:layout_constraintTop_toBottomOf="@+id/special_mode_view"
app:layout_constraintBottom_toTopOf="@+id/file_selection_buttons_container">
<com.google.android.material.appbar.AppBarLayout
@@ -156,11 +165,18 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/database_buttons_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_gravity="top"
app:layout_constraintBottom_toTopOf="@+id/open_keyfile_button"
android:background="?attr/colorPrimaryDark"/>
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/open_keyfile_button"
@@ -191,11 +207,6 @@
android:paddingEnd="24dp"
android:text="@string/create_keepass_file"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_gravity="top"
android:background="?attr/colorPrimaryDark"/>
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -17,18 +17,28 @@
You should have received a copy of the GNU General Public License
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
-->
<RelativeLayout
<androidx.constraintlayout.widget.ConstraintLayout
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:layout_width="match_parent"
android:layout_height="match_parent">
<com.kunzisoft.keepass.view.SpecialModeView
android:id="@+id/special_mode_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="?attr/specialToolbarAppearance"
app:titleTextAppearance="@style/KeepassDXStyle.TextAppearance.Toolbar.Special.Title"
app:subtitleTextAppearance="@style/KeepassDXStyle.TextAppearance.Toolbar.Special.SubTitle"
app:layout_constraintTop_toTopOf="parent" />
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/group_coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/toolbar_action">
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@+id/special_mode_view"
app:layout_constraintBottom_toTopOf="@+id/toolbar_action">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar"
@@ -124,15 +134,6 @@
android:orientation="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:layout_below="@+id/toolbar">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/mode_title_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="6dp"
android:gravity="center_horizontal"
android:background="?attr/colorAccent"
android:textColor="?attr/textColorInverse"
android:text="@string/selection_mode"/>
<FrameLayout
android:id="@+id/nodes_list_fragment_container"
android:layout_width="match_parent"
@@ -159,10 +160,10 @@
android:id="@+id/toolbar_action"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_alignParentBottom="true"
app:layout_constraintBottom_toBottomOf="parent"
android:elevation="4dp"
android:theme="?attr/toolbarBottomAppearance"
android:theme="?attr/actionToolbarAppearance"
android:background="?attr/colorAccent"
tools:targetApi="lollipop" />
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -21,17 +21,24 @@
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:id="@+id/container"
android:importantForAutofill="noExcludeDescendants"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:targetApi="o">
<com.kunzisoft.keepass.view.SpecialModeView
android:id="@+id/special_mode_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="?attr/specialToolbarAppearance"
app:titleTextAppearance="@style/KeepassDXStyle.TextAppearance.Toolbar.Special.Title"
app:subtitleTextAppearance="@style/KeepassDXStyle.TextAppearance.Toolbar.Special.SubTitle"
app:layout_constraintTop_toTopOf="parent" />
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/activity_password_coordinator_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintTop_toBottomOf="@+id/special_mode_view"
app:layout_constraintBottom_toTopOf="@+id/activity_password_info_container">
<com.google.android.material.appbar.AppBarLayout
@@ -155,7 +162,8 @@
android:hint="@string/password"
android:inputType="textPassword"
android:importantForAccessibility="no"
android:importantForAutofill="no"
android:importantForAutofill="yes"
android:autofillHints="password|"
android:imeOptions="actionDone"
android:maxLines="1"/>
</com.google.android.material.textfield.TextInputLayout>
@@ -213,7 +221,7 @@
android:paddingLeft="24dp"
android:paddingEnd="24dp"
android:paddingRight="24dp"
style="@style/KeepassDXStyle.TextAppearance.TinyText"
style="@style/KeepassDXStyle.TextAppearance.Tiny"
android:text="@string/warning_database_link_revoked"
android:textColor="?attr/textColorInverse"
android:background="?attr/colorAccent"

View File

@@ -27,7 +27,6 @@
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:importantForAutofill="noExcludeDescendants"
tools:targetApi="o">
<androidx.cardview.widget.CardView
android:id="@+id/card_view_master_password"
@@ -63,7 +62,8 @@
android:layout_height="wrap_content"
android:inputType="textPassword"
android:importantForAccessibility="no"
android:importantForAutofill="no"
android:importantForAutofill="yes"
android:autofillHints="newPassword"
android:maxLines="1"
android:hint="@string/hint_pass"/>
</com.google.android.material.textfield.TextInputLayout>
@@ -81,7 +81,8 @@
android:layout_height="wrap_content"
android:inputType="textPassword"
android:importantForAccessibility="no"
android:importantForAutofill="no"
android:importantForAutofill="yes"
android:autofillHints="newPassword"
android:maxLines="1"
android:hint="@string/hint_conf_pass"/>
</com.google.android.material.textfield.TextInputLayout>

View File

@@ -58,7 +58,7 @@
android:id="@+id/item_attachment_compression"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/KeepassDXStyle.TextAppearance.TinyText"
style="@style/KeepassDXStyle.TextAppearance.Tiny"
android:firstBaselineToTopHeight="0dp"
android:includeFontPadding="false"
android:paddingStart="8dp"

View File

@@ -67,7 +67,7 @@
tools:text="Node Title"
android:lines="1"
android:singleLine="true"
style="@style/KeepassDXStyle.TextAppearance.Default" /> <!-- style override -->
style="@style/KeepassDXStyle.TextAppearance.Entry.Title" />
<TextView
android:id="@+id/node_subtext"
android:layout_height="wrap_content"
@@ -76,7 +76,7 @@
tools:text="Node SubTitle"
android:lines="1"
android:singleLine="true"
style="@style/KeepassDXStyle.TextAppearance.Secondary" /> <!-- style override -->
style="@style/KeepassDXStyle.TextAppearance.Entry.SubTitle" />
</LinearLayout>
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -35,11 +35,10 @@
app:layout_constraintEnd_toEndOf="parent"
android:background="?android:attr/selectableItemBackground" >
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/group_arrow"
android:id="@+id/node_image_identifier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_arrow_right_white_24dp"
android:tint="?android:attr/textColorPrimary"
android:layout_marginLeft="4dp"
android:layout_marginStart="4dp"
android:layout_centerVertical="true"
@@ -58,8 +57,8 @@
android:src="@drawable/ic_blank_32dp"
android:scaleType="fitXY"
android:layout_centerVertical="true"
android:layout_toRightOf="@+id/group_arrow"
android:layout_toEndOf="@+id/group_arrow" />
android:layout_toRightOf="@+id/node_image_identifier"
android:layout_toEndOf="@+id/node_image_identifier" />
<TextView
android:id="@+id/node_child_numbers"
android:layout_width="wrap_content"
@@ -90,7 +89,7 @@
tools:text="Node Title"
android:lines="1"
android:singleLine="true"
style="@style/KeepassDXStyle.TextAppearance.Title" /> <!-- style override -->
style="@style/KeepassDXStyle.TextAppearance.Group.Title" />
<TextView
android:id="@+id/node_subtext"
android:layout_width="wrap_content"
@@ -100,7 +99,7 @@
android:layout_marginTop="-4dp"
android:lines="1"
android:singleLine="true"
style="@style/KeepassDXStyle.TextAppearance.Secondary" /> <!-- style override -->
style="@style/KeepassDXStyle.TextAppearance.Group.SubTitle" />
</LinearLayout>
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2020 Jeremy Jamet / Kunzisoft.
This file is part of KeePassDX.
KeePassDX is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
KeePassDX is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
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"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/edit"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:importantForAutofill="noExcludeDescendants"
tools:targetApi="o">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/explanation_text"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:gravity="center"
android:layout_marginBottom="8dp"
style="@style/KeepassDXStyle.TextAppearance.SmallTitle"/>
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/switch_element"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="24dp"
android:text="@string/enable"
android:background="@drawable/background_button_small"
android:textColor="?attr/textColorInverse"
android:minHeight="48dp"/>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/add_item_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginStart="24dp"
android:layout_marginLeft="24dp"
android:layout_marginEnd="24dp"
android:layout_marginRight="24dp"
android:orientation="horizontal">
<EditText
android:id="@+id/input_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@+id/add_item_button"
app:layout_constraintBottom_toBottomOf="@id/add_item_button"
android:inputType="textUri"
android:hint="@string/content_description_add_item"/>
<ImageButton
android:id="@+id/add_item_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:contentDescription="@string/content_description_add_item"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:src="@drawable/ic_add_white_24dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/pref_dialog_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/default_margin"
android:paddingStart="24dp"
android:paddingLeft="24dp"
android:paddingEnd="24dp"
android:paddingRight="24dp" />
</LinearLayout>

View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2019 Jeremy Jamet / Kunzisoft.
This file is part of KeePassDX.
KeePassDX is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
KeePassDX is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
-->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/pref_dialog_list_container"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/pref_dialog_list_text"
android:layout_width="0dp"
android:layout_height="0dp"
android:gravity="center_vertical"
app:layout_constraintTop_toTopOf="@+id/pref_dialog_list_delete_button"
app:layout_constraintBottom_toBottomOf="@+id/pref_dialog_list_delete_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@+id/pref_dialog_list_delete_button"/>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/pref_dialog_list_delete_button"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:src="@drawable/ic_content_delete_white_24dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2020 Jeremy Jamet / Kunzisoft.
This file is part of KeePassDX.
KeePassDX is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
KeePassDX is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
-->
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/menu_block_autofill"
android:icon="@drawable/ic_block_white_24dp"
android:title="@string/autofill_block"
android:orderInCategory="1"
app:showAsAction="ifRoom" />
</menu>

View File

@@ -16,15 +16,13 @@
You should have received a copy of the GNU General Public License
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
-->
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
--><resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
<string name="homepage">الصفحة الرئيسية</string>
<string name="accept">قبول</string>
<string name="add_group">إضافة مجموعة</string>
<string name="encryption">التعمية</string>
<string name="encryption_algorithm">خوارزمية التعمية</string>
<string name="application">التطبيق</string>
<string name="beta_dontask">لا تظهر مرة أخرى</string>
<string name="brackets">أقواس</string>
<string name="extended_ASCII">تمديد ASCII</string>
<string name="allow">السماح</string>
@@ -117,15 +115,16 @@
<string name="edit_entry">تحرير مدخلة</string>
<string name="key_derivation_function">وظيفة اشتقاق المفتاح</string>
<string name="app_timeout">مهلة التطبيق</string>
<string name="app_timeout_summary">مدة الانتظار قبل إقفال التطبيق</string>
<string name="app_timeout_summary">مدة الانتظار قبل إقفال قاعدة البيانات</string>
<string name="file_manager_install_description">تصفَّح الملفات بتثبيت مدير الملفات OpenIntents</string>
<string name="clipboard_error">بعض هواتف سامسونغ لا تسمح للتطبيقات باستعمال الحافظة.</string>
<string name="clipboard_error">بعض الأجهزة لا تسمح للتطبيقات باستعمال الحافظة.</string>
<string name="clipboard_timeout">مهلة الحافظة</string>
<string name="clipboard_timeout_summary">مدة التخزين في الحافظة</string>
<string name="select_to_copy">اختر لنسخ %1$s إلى الحافظة</string>
<string name="retrieving_db_key">يجلب مفتاح قاعدة البيانات…</string>
<string name="default_checkbox">استخدامها كقاعدة بيانات افتراضية</string>
<string name="html_about_licence">KeePassDX © %1$d د كونزيسوفت تأتي مع الضمان لا على الإطلاق؛ هذا هو البرمجيات الحرة، وكنت أهلا إعادة توزيعه تحت شروط إصدار الترخيص 3 أو في وقت لاحق.</string>
<string name="html_about_licence">KeePassDX © %1$d كونزيسوفت &lt;strong&gt;مفتوح المصدر&lt;/strong&gt; و &lt;strong&gt;بدون اعلانات&lt;/strong&gt;.
\n يوزع كما هو، بدون ضمان, تحت ترخيص &lt;strong&gt;GPLv3&lt;/strong&gt;</string>
<string name="entry_accessed">نُفذ إليه</string>
<string name="entry_expires">تنتهي صلاحيته في</string>
<string name="entry_keyfile">ملف المفتاح</string>
@@ -278,4 +277,12 @@
<string name="content_description_keyboard_close_fields">أغلق الحقول</string>
<string name="error_create_database_file">لا يمكن انشاء قاعدة بيانات بكلمة السر وملف المفتاح الحاليين.</string>
<string name="menu_advanced_unlock_settings">إلغاء القفل المتقدم</string>
<string name="entry_attachments">مرفقات</string>
<string name="entry_history">السجل</string>
<string name="entry_add_attachment">أضف مرفقا</string>
<string name="discard">إلغاء</string>
<string name="discard_changes">تجاهل التغييرات؟</string>
<string name="validate">تأكيد</string>
<string name="security">الأمان</string>
<string name="master_key">المفتاح الرئيسي</string>
</resources>

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="homepage">মূলপাতা</string>
<string name="feedback">প্রতিক্রিয়া</string>
<string name="contribution">অবদান</string>
<string name="contact">যোগাযোগ</string>
<string name="extended_ASCII">বর্ধিত ASCII</string>
<string name="brackets">ব্র্যাকেট</string>
<string name="application">অ্যাপ</string>
<string name="app_timeout_summary">ডাটাবেস লক করার আগে অব্যবহৃত সময়</string>
<string name="app_timeout">অ্যাপের সময় পার হয়ে গিয়েছিলো</string>
<string name="key_derivation_function">কি পাওয়ার ফাংশন</string>
<string name="encryption_algorithm">এনক্রিপশন অ্যালগরিদম</string>
<string name="encryption">এনক্রিপশন</string>
<string name="security">নিরাপত্তা</string>
<string name="master_key">প্রধান চাবি</string>
<string name="add_group">গ্রুপ যোগ করুন</string>
<string name="edit_entry">এন্টরি সম্পাদনা করুন</string>
<string name="add_entry">এন্টরি যোগ করুন</string>
<string name="accept">গ্রহণ</string>
<string name="about_description">কিপাস পাসওয়ার্ড ম্যানেজারের অ্যান্ড্রয়েড বাস্তবায়ন</string>
</resources>

View File

@@ -17,9 +17,8 @@
You should have received a copy of the GNU General Public License
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
Catalan translation by Oriol Garrote
-->
<resources>
<string name="feedback">Comentaris:</string>
--><resources>
<string name="feedback">Comentaris</string>
<string name="homepage">Pàgina inici:</string>
<string name="about_description">KeePassDX és una implementació per a Android de KeePass password manager</string>
<string name="accept">Accepta</string>
@@ -77,7 +76,7 @@
<string name="hint_length">Longitud</string>
<string name="hint_pass">Contrasenya</string>
<string name="password">Contrasenya</string>
<string name="invalid_credentials">No s\'han pogut llegir les credencials. Si torna a passar, el fitxer de la vostra base de dades podria estar malmès.</string>
<string name="invalid_credentials">No s\'han pogut llegir les credencials.</string>
<string name="invalid_db_sig">No s\'ha pogut reconèixer el format de la base de dades.</string>
<string name="length">Longitud</string>
<string name="list_size_title">Mida de la llista de grups</string>
@@ -147,7 +146,6 @@
<string name="edit_entry">Edita l\'entrada</string>
<string name="contribution">Contribució</string>
<string name="contact">Contacte</string>
<string name="beta_dontask">No tornis a mostrar</string>
<string name="extended_ASCII">ASCII ampliat</string>
<string name="sort_username">Nom d\'usuari</string>
<string name="sort_title">Títol</string>

View File

@@ -28,7 +28,6 @@
<string name="app_timeout_summary">Doba nečinnosti než se aplikace zamkne</string>
<string name="application">Aplikace</string>
<string name="menu_app_settings">Nastavení aplikace</string>
<string name="beta_dontask">Znovu neukázat</string>
<string name="brackets">Závorky</string>
<string name="file_manager_install_description">K založení, otevření a uložení databázových souborů je potřebný správce souborů, který akceptuje akci intentu ACTION_CREATE_DOCUMENT a ACTION_OPEN_DOCUMENT.</string>
<string name="clipboard_cleared">Schránka vyčištěna</string>
@@ -82,7 +81,7 @@
<string name="hint_length">Délka</string>
<string name="hint_pass">Heslo</string>
<string name="password">Heslo</string>
<string name="invalid_credentials">Nebylo možno načíst autentizační údaje. Pokud se chyba opakuje, databázový soubor může být poškozen.</string>
<string name="invalid_credentials">Nebylo možno načíst autentizační údaje.</string>
<string name="invalid_algorithm">Nesprávný algoritmus.</string>
<string name="invalid_db_sig">Nedaří se rozpoznat formát databáze.</string>
<string name="keyfile_is_empty">Soubor s klíčem je prázdný.</string>
@@ -195,7 +194,7 @@
<string name="warning_empty_password">Pokračovat bez ochrany odemknutím heslem\?</string>
<string name="warning_no_encryption_key">Pokračovat bez šifrovacího klíče\?</string>
<string name="configure_biometric">Biometrická pobídka je zařízením podporována, ale není nastavena.</string>
<string name="open_biometric_prompt_unlock_database">Otevři biometrickou pobídku k otevření databáze</string>
<string name="open_biometric_prompt_unlock_database">Otevřít biometrickou pobídku k otevření databáze</string>
<string name="encrypted_value_stored">Šifrované heslo uloženo</string>
<string name="biometric_invalid_key">Nelze načíst biometrický klíč. Prosím, smažte jej a opakujte proceduru biometrického rozpoznání.</string>
<string name="biometric_not_recognized">Biometrický prvek nerozpoznán</string>
@@ -345,7 +344,7 @@
<string name="keyboard_selection_entry_title">Výběr položky</string>
<string name="keyboard_selection_entry_summary">Při prohlížení záznamu ukázat na Magikeyboard pole položek</string>
<string name="delete_entered_password_title">Smazat heslo</string>
<string name="delete_entered_password_summary">Smaže heslo zadané po pokusu o připojení</string>
<string name="delete_entered_password_summary">Smaže heslo zadané po pokusu o připojení k databázi</string>
<string name="content_description_open_file">Otevři soubor</string>
<string name="content_description_node_children">Potomci uzlu</string>
<string name="content_description_add_node">Přidej uzel</string>
@@ -477,4 +476,6 @@
<string name="autofill_preference_title">Nastavení samovyplnění</string>
<string name="warning_database_link_revoked">Přístup k souboru zrušenému správcem souborů</string>
<string name="error_label_exists">Tento štítek již existuje.</string>
<string name="keyboard_search_share_summary">Automaticky vyhledat sdílené informace pro naplnění klávesnice</string>
<string name="keyboard_search_share_title">Prohledat sdílené info</string>
</resources>

View File

@@ -28,7 +28,6 @@
<string name="app_timeout_summary">Inaktiv tid, før databasen låses</string>
<string name="application">Program</string>
<string name="menu_app_settings">Indstillinger</string>
<string name="beta_dontask">Vis ikke igen</string>
<string name="brackets">Parenteser</string>
<string name="file_manager_install_description">En filhåndtering, der accepterer intensionshandlingen ACTION_CREATE_DOCUMENT og ACTION_OPEN_DOCUMENT, er nødvendig for at oprette, åbne og gemme databasefiler.</string>
<string name="clipboard_cleared">Udklipsholder ryddet</string>
@@ -81,7 +80,7 @@
<string name="hint_length">Længde</string>
<string name="hint_pass">Adgangskode</string>
<string name="password">Adgangskode</string>
<string name="invalid_credentials">Legitimationsoplysningerne kunne ikke læses. Hvis det sker igen, kan databasefilen være beskadiget.</string>
<string name="invalid_credentials">Legitimationsoplysningerne kunne ikke læses.</string>
<string name="invalid_algorithm">Forkert algoritme.</string>
<string name="invalid_db_sig">Kunne ikke genkende databaseformat.</string>
<string name="keyfile_is_empty">Nøglefilen er tom.</string>
@@ -194,11 +193,11 @@
<string name="warning_empty_password">Bekræft brug af ingen adgangskode til beskyttelse mod oplåsning\?</string>
<string name="warning_no_encryption_key">Fortsæt uden krypteringsnøgle\?</string>
<string name="configure_biometric">Biometrisk prompt understøttes, men er ikke konfigureret.</string>
<string name="open_biometric_prompt_unlock_database">Åbn den biometriske prompt for at låse databasen op</string>
<string name="open_biometric_prompt_unlock_database">Åbn biometriske forespørgsel for at låse databasen op</string>
<string name="encrypted_value_stored">Krypteret adgangskode er gemt</string>
<string name="biometric_invalid_key">Kan ikke læse den biometriske nøgle. Slet den og gentag den biometriske genkendelsesprocedure.</string>
<string name="biometric_not_recognized">Kunne ikke genkende fingeraftryk</string>
<string name="biometric_scanning_error">Problem med fingeraftryk: %1$s</string>
<string name="biometric_not_recognized">Kunne ikke genkende biometrisk</string>
<string name="biometric_scanning_error">Biometrisk fejl: %1$s</string>
<string name="open_biometric_prompt_store_credential">Åbn den biometriske prompt for at gemme legitimationsoplysninger</string>
<string name="no_credentials_stored">Databasen har endnu ikke en adgangskode.</string>
<string name="database_history">Historik</string>
@@ -221,11 +220,11 @@
<string name="lock_database_screen_off_title">Skærmlås</string>
<string name="lock_database_screen_off_summary">Lås databasen, når skærmen er slukket</string>
<string name="advanced_unlock">Fingeraftryk</string>
<string name="biometric_unlock_enable_title">Fingeraftryksscanning</string>
<string name="biometric_unlock_enable_summary">Lader dig scanne din biometrisk for at åbne databasen</string>
<string name="biometric_unlock_enable_title">Biometrisk oplåsning</string>
<string name="biometric_unlock_enable_summary">Giver mulighed for at scanne biometriske for at åbne databasen</string>
<string name="biometric_delete_all_key_title">Slet krypteringsnøgler</string>
<string name="biometric_delete_all_key_summary">Slet alle krypteringsnøgler, der er relateret til fingeraftryk</string>
<string name="biometric_delete_all_key_warning">Slet alle nøgler, der er relateret til fingeraftryksgenkendelse\?</string>
<string name="biometric_delete_all_key_summary">Slet alle krypteringsnøgler, der er relateret til biometrisk genkendelse</string>
<string name="biometric_delete_all_key_warning">Slet alle krypteringsnøgler, der er relateret til biometrisk genkendelse\?</string>
<string name="unavailable_feature_text">Funktionen kunne ikke startes.</string>
<string name="unavailable_feature_version">Android-version %1$s opfylder ikke minimum versionskrav %2$s.</string>
<string name="unavailable_feature_hardware">Kunne ikke finde den tilsvarende hardware.</string>
@@ -270,8 +269,8 @@
\nGrupper (~mapper) organiserer poster i databasen.</string>
<string name="education_search_title">Søg i poster</string>
<string name="education_search_summary">Indtast titel, brugernavn eller indhold af andre felter for at hente adgangskoder.</string>
<string name="education_biometric_title">Database oplåsning med fingeraftryk</string>
<string name="education_biometric_summary">Link adgangskoden til det scannede fingeraftryk for hurtigt at låse databasen op.</string>
<string name="education_biometric_title">Oplåsning af database ved hjælp af biometrisk</string>
<string name="education_biometric_summary">Knyt adgangskoden til det scannede biometri for hurtigt at låse databasen op.</string>
<string name="education_entry_edit_title">Rediger posten</string>
<string name="education_entry_edit_summary">Rediger post med brugerdefinerede felter. Pool data kan refereres mellem forskellige indtastningsfelter.</string>
<string name="education_generate_password_title">Opret en stærk adgangskode</string>
@@ -344,7 +343,7 @@
<string name="keyboard_selection_entry_title">Valg af indtastning</string>
<string name="keyboard_selection_entry_summary">Vis indtastningsfelter i Magikeyboard, når der vises en post</string>
<string name="delete_entered_password_title">Slet adgangskode</string>
<string name="delete_entered_password_summary">Sletter adgangskoden som er indtastet efter et forbindelsesforsøg</string>
<string name="delete_entered_password_summary">Sletter adgangskoden der er angivet efter et forsøg på at oprette forbindelse til en database</string>
<string name="content_description_open_file">Åbn fil</string>
<string name="content_description_node_children">Undernode</string>
<string name="content_description_add_node">Tilføj knude</string>
@@ -375,7 +374,7 @@
<string name="biometric_prompt_extract_credential_message">Uddrag databasens legitimationsoplysninger med biometriske data</string>
<string name="biometric">Biometrisk</string>
<string name="biometric_auto_open_prompt_title">Åbn automatisk biometrisk prompt</string>
<string name="biometric_auto_open_prompt_summary">Spørg automatisk efter biometrisk, hvis databasen er konfigureret til at bruge den</string>
<string name="biometric_auto_open_prompt_summary">Spørg automatisk efter biometri, hvis databasen er konfigureret til at bruge den</string>
<string name="enable">Aktiver</string>
<string name="disable">Deaktiver</string>
<string name="master_key">Hovednøgle</string>
@@ -429,7 +428,7 @@
<string name="command_execution">Udfører kommandoen…</string>
<string name="warning_permanently_delete_nodes">Slet markerede noder permanent\?</string>
<string name="keystore_not_accessible">Nøglelageret er ikke korrekt initialiseret.</string>
<string name="credential_before_click_biometric_button">Skriv adgangskoden, før der klikkes på den biometriske knap.</string>
<string name="credential_before_click_biometric_button">Indtast adgangskoden, og klik derefter på knappen \"Biometrisk\".</string>
<string name="recycle_bin_group_title">Papirkurvsgruppe</string>
<string name="enable_auto_save_database_title">Gem automatisk database</string>
<string name="enable_auto_save_database_summary">Gem databasen efter hver en vigtig handling (i tilstanden \"Modificerbar\")</string>
@@ -476,4 +475,6 @@
<string name="autofill_preference_title">Indstillinger for automatisk udfyldning</string>
<string name="warning_database_link_revoked">Adgang til filen tilbagekaldt af filadministratoren</string>
<string name="error_label_exists">Etiketten findes allerede.</string>
<string name="keyboard_search_share_summary">Søg automatisk efter delte oplysninger for at udfylde tastaturet</string>
<string name="keyboard_search_share_title">Søg i delte oplysninger</string>
</resources>

View File

@@ -34,7 +34,6 @@
<string name="app_timeout_summary">Inaktivität vor dem Sperren der Datenbank</string>
<string name="application">App</string>
<string name="menu_app_settings">App-Einstellungen</string>
<string name="beta_dontask">Nicht mehr anzeigen</string>
<string name="brackets">Klammern</string>
<string name="file_manager_install_description">Zum Erstellen, Öffnen und Speichern von Datenbankdateien wird ein Dateimanager benötigt, der die beabsichtigte Aktion ACTION_CREATE_DOCUMENT und ACTION_OPEN_DOCUMENT akzeptiert.</string>
<string name="clipboard_cleared">Zwischenablage geleert</string>
@@ -91,7 +90,7 @@
<string name="hint_length">Länge</string>
<string name="hint_pass">Passwort</string>
<string name="password">Passwort</string>
<string name="invalid_credentials">Die Anmeldeinformationen konnten nicht gelesen werden. Wenn dies erneut auftritt, kann Ihre Datenbankdatei beschädigt sein.</string>
<string name="invalid_credentials">Die Anmeldeinformationen konnten nicht gelesen werden.</string>
<string name="invalid_algorithm">Falscher Algorithmus.</string>
<string name="invalid_db_sig">Datenbankformat nicht erkannt.</string>
<string name="keyfile_is_empty">Die Schlüsseldatei ist leer.</string>
@@ -187,7 +186,7 @@
<string name="list_password_generator_options_summary">Erlaubte Zeichen für Passwortgenerator festlegen</string>
<string name="list_password_generator_options_title">Passwortzeichen</string>
<string name="configure_biometric">Die biometrische Abfrage wird unterstützt, ist aber nicht eingerichtet.</string>
<string name="open_biometric_prompt_unlock_database">Biometrische Abfrage öffnen, um die Datenbank zu entsperren.</string>
<string name="open_biometric_prompt_unlock_database">Biometrie-Abfrage öffnen, um die Datenbank zu entsperrenœ</string>
<string name="encrypted_value_stored">Verschlüsseltes Passwort wurde gespeichert</string>
<string name="biometric_invalid_key">Der biometrische Schlüssel kann nicht gelesen werden. Bitte löschen Sie ihn und wiederholen Sie den biometrischen Erkennungsprozess.</string>
<string name="biometric_scanning_error">Biometrischer Fehler: %1$s</string>
@@ -358,7 +357,7 @@
<string name="keyboard_selection_entry_title">Eintragsauswahl</string>
<string name="keyboard_selection_entry_summary">Eingabefelder beim Betrachten eines Eintrags im Magikeyboard anzeigen</string>
<string name="delete_entered_password_title">Passwort löschen</string>
<string name="delete_entered_password_summary">Löscht das eingegebene Passwort nach einem Verbindungsversuch</string>
<string name="delete_entered_password_summary">Löscht das eingegebene Passwort nach einem Verbindungsversuch zu einer Datenbank</string>
<string name="content_description_open_file">Datei öffnen</string>
<string name="content_description_add_entry">Eintrag hinzufügen</string>
<string name="content_description_add_group">Gruppe hinzufügen</string>
@@ -390,7 +389,7 @@
<string name="biometric">Biometrisch</string>
<string name="enable">Aktivieren</string>
<string name="disable">Deaktivieren</string>
<string name="biometric_prompt_store_credential_message">Achtung: Wenn du die biometrische Erkennung verwendest, musst du dir das Master-Passwort trotzdem merken.</string>
<string name="biometric_prompt_store_credential_message">Achtung: Wenn Sie die biometrische Erkennung verwenden, müssen Sie sich trotzdem Ihr Master-Passwort merken.</string>
<string name="biometric_prompt_extract_credential_message">Datenbank-Anmeldeinformationen aus biometrischen Daten extrahieren</string>
<string name="biometric_auto_open_prompt_title">Biometrische Abfrage automatisch öffnen</string>
<string name="biometric_auto_open_prompt_summary">Automatisch nach Biometrie fragen, wenn die Datenbank dafür eingerichtet ist</string>
@@ -487,4 +486,6 @@
<string name="autofill_preference_title">Autofill-Einstellungen</string>
<string name="warning_database_link_revoked">Zugriff auf die Datei durch den Dateimanager widerrufen</string>
<string name="error_label_exists">Diese Bezeichnung existiert bereits.</string>
<string name="keyboard_search_share_summary">Automatische Suche nach gemeinsam genutzten Informationen zur Belegung der Tastatur</string>
<string name="keyboard_search_share_title">Gemeinsame Infos durchsuchen</string>
</resources>

View File

@@ -28,7 +28,6 @@
<string name="app_timeout_summary">Χρόνος αδράνειας πριν από το κλείδωμα της βάσης δεδομένων</string>
<string name="application">Εφαρμογή</string>
<string name="menu_app_settings">Ρυθμίσεις εφαρμογής</string>
<string name="beta_dontask">Να μην εμφανιστεί ξανά</string>
<string name="brackets">Αγκύλες</string>
<string name="file_manager_install_description">Ένας διαχειριστής αρχείων που δέχεται τις ενέργειες δράσης ACTION_CREATE_DOCUMENT και ACTION_OPEN_DOCUMENT είναι απαραίτητος για τη δημιουργία, το άνοιγμα και την αποθήκευση αρχείων βάσης δεδομένων.</string>
<string name="clipboard_cleared">Το πρόχειρο καθαρίστηκε</string>
@@ -43,7 +42,7 @@
<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;.
<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="select_database_file">Ανοίξτε την υπάρχουσα βάση δεδομένων</string>
<string name="entry_accessed">Πρόσβαση</string>
@@ -84,7 +83,7 @@
<string name="hint_length">Μήκος</string>
<string name="hint_pass">Κωδικός</string>
<string name="password">Κωδικός Πρόσβασης</string>
<string name="invalid_credentials">Δεν ήταν δυνατή η ανάγνωση διαπιστευτηρίων. Εάν αυτό επαναληφθεί, το αρχείο της βάσης δεδομένων ενδέχεται να είναι κατεστραμμένο.</string>
<string name="invalid_credentials">Δεν ήταν δυνατή η ανάγνωση διαπιστευτηρίων.</string>
<string name="invalid_algorithm">Λάθος αλγόριθμος.</string>
<string name="invalid_db_sig">Δεν ήταν δυνατή η αναγνώριση της μορφής της βάσης δεδομένων.</string>
<string name="keyfile_is_empty">Το αρχείο-κλειδί είναι κενό.</string>

View File

@@ -143,7 +143,6 @@
</string-array>
<string name="encryption">Cifrado</string>
<string name="key_derivation_function">Función de derivación de clave</string>
<string name="beta_dontask">No mostrar nuevamente</string>
<string name="extended_ASCII">ASCII extendido</string>
<string name="allow">Permitir</string>
<string name="clipboard_error_title">Error del portapapeles</string>

View File

@@ -17,9 +17,8 @@
You should have received a copy of the GNU General Public License
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
Basque translation by David García-Abad
-->
<resources>
<string name="feedback">Feedback:</string>
--><resources>
<string name="feedback">Feedback</string>
<string name="homepage">Hasiera orria</string>
<string name="about_description">Keepass pasahitza kudeatzailearen Androiderako inplementazioa</string>
<string name="accept">Onartu</string>
@@ -30,7 +29,6 @@
<string name="app_timeout_summary">Denbora datubasea blokeatu baino lehenago aplikazioa erabili gabe dagoenean</string>
<string name="application">Aplikazioa</string>
<string name="menu_app_settings">Aplikazioaren ezarpenak</string>
<string name="beta_dontask">Ez erakutsi berriro</string>
<string name="brackets">Brackets</string>
<string name="file_manager_install_description">Fitxategietan nabigatzeak Open Intents Fitxategi Kudeatzailea behar du. Klik egin azpian instalatzeko. Fitxategien kudeatzailaren arazo batzuk direla eta, izan daiteke nabigazioak ondo ez funtzionatzea lehenengo aldian.</string>
<string name="clipboard_cleared">Arbela ezabatuta.</string>
@@ -135,23 +133,21 @@
<string name="unsupported_db_version">Euskarririk gabeko datubase bertsioa.</string>
<string name="uppercase">Maiuskulak</string>
<string name="version_label">Bertsioa %1$s</string>
<string name="education_unlock_summary">Sartu pasahitz eta / edo gako fitxategi bat zure datubasea desblokeatzeko.</string>
<string-array name="timeout_options">
<item>5 segundu</item>
<item>10 segundu</item>
<item>20 segundu</item>
<item>30 segundu</item>
<item>minutu 1</item>
<item>5 minutu</item>
<item>15 minutu</item>
<item>30 minutu</item>
<item>Inoiz ez</item>
<item>5 segundu</item>
<item>10 segundu</item>
<item>20 segundu</item>
<item>30 segundu</item>
<item>minutu 1</item>
<item>5 minutu</item>
<item>15 minutu</item>
<item>30 minutu</item>
<item>Inoiz ez</item>
</string-array>
<string-array name="list_size_options">
<item>Txikia</item>
<item>Ertaina</item>
<item>Handia</item>
<item>Txikia</item>
<item>Ertaina</item>
<item>Handia</item>
</string-array>
</resources>

View File

@@ -16,32 +16,30 @@
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="feedback">Palaute:</string>
<string name="homepage">Kotisivu:</string>
<string name="about_description">KeePassDX on KeePass-salasanahallintaohjelman Android-versio</string>
--><resources>
<string name="feedback">Palaute</string>
<string name="homepage">Kotisivu</string>
<string name="about_description">KeePass-salasanahallintaohjelman Android toteutus</string>
<string name="accept">Hyväksy</string>
<string name="add_entry">Lisää uusi salasanatietue</string>
<string name="add_group">Lisää ryhmä</string>
<string name="encryption_algorithm">Algoritmi</string>
<string name="app_timeout">Ohjelman aikakatkaisu</string>
<string name="app_timeout_summary">Aika, jonka jälkeen KeePass lukitaan jos se on ollut toimeton.</string>
<string name="application">Ohjelma</string>
<string name="encryption_algorithm">Salausalgoritmi</string>
<string name="app_timeout">Sovelluksen aikakatkaisu</string>
<string name="app_timeout_summary">Joutoaika ennen tietokannan lukkiutumista</string>
<string name="application">Sovellus</string>
<string name="menu_app_settings">Ohjelman asetukset</string>
<string name="beta_dontask">Älä näytä enää uudelleen</string>
<string name="brackets">Hakasulkeet</string>
<string name="file_manager_install_description">Tiedostojen selaus vaatii Open Intents File Manager -tiedostonhallintaohjelman, klikkaa alla olevaa linkkiä asentaaksesi sen. Joidenkin ominaisuuksien takia se ei ehkä toimi oikein ensimmäisellä käynnistyksellä.</string>
<string name="file_manager_install_description">Tietokantojen avaamista, luomista ja tallentamista varten tarvitaan tiedostonhallintaohjelma, joka tukee ACTION_CREATE_DOCUMENT ja ACTION_OPEN_DOCUMENT Intent-toimintoja.</string>
<string name="clipboard_cleared">Leikepöytä tyhjennetty.</string>
<string name="clipboard_error_title">Leikepöytävirhe</string>
<string name="clipboard_error">Joissakin Android-puhelimissa on virhe leikepöydän toteutuksessa, mikä aiheuttaa kopioinnin epäonnistumisen. Lisätietoa:</string>
<string name="clipboard_error_clear">Leikepöydän tyhjennys epäonnistui</string>
<string name="clipboard_error">Jotkin laitteet eivät anna sovellusten käyttää leikepöytää.</string>
<string name="clipboard_error_clear">Leikepöytää ei voitu tyhjentää</string>
<string name="clipboard_timeout">Leikepöydän aikakatkaisu</string>
<string name="clipboard_timeout_summary">Aika, jonka jälkeen leikepöytä tyhjennetään käyttäjätunnuksen tai salasanan kopioinnin jälkeen</string>
<string name="clipboard_timeout_summary">Leikepöydälle tallennuksen kesto</string>
<string name="select_to_copy">Valitse kopioidaksesi %1$s</string>
<string name="retrieving_db_key">Luodaan tietokanta-avainta&#8230;</string>
<string name="retrieving_db_key">Luodaan tietokanta-avainta</string>
<string name="database">Tietokanta</string>
<string name="decrypting_db">Puretaan tietokannan salausta&#8230;</string>
<string name="decrypting_db">Puretaan tietokannan salausta</string>
<string name="default_checkbox">Käytä tätä oletustietokantana</string>
<string name="digits">Numerot</string>
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft comes with absolutely no warranty. This is free software, and you are welcome to redistribute it under the conditions of the GPL version 3 or later.</string>
@@ -91,7 +89,7 @@
<string name="length">Pituus</string>
<string name="list_size_title">Ryhmälistan pituus</string>
<string name="list_size_summary">Tekstin koko ryhmälistauksessa</string>
<string name="loading_database">Ladataan salasanatietokantaa&#8230;</string>
<string name="loading_database">Ladataan salasanatietokantaa</string>
<string name="lowercase">pienet kirjaimet</string>
<string name="hide_password_title">Piilota salasaan</string>
<string name="hide_password_summary">Piilota salasanat oletuksena</string>
@@ -114,15 +112,15 @@
<string name="no_url_handler">Tälle URL:lle ei ole käsittelijää.</string>
<string name="omit_backup_search_title">Älä etsi varmuuskopioista eikä roskakorista</string>
<string name="omit_backup_search_summary">Poista \'Varmuuskopiot\' ja roskakori hakutuloksista</string>
<string name="progress_create">Luodaan uutta tietokantaa&#8230;</string>
<string name="progress_title">Työskennellään&#8230;</string>
<string name="progress_create">Luodaan uutta tietokantaa</string>
<string name="progress_title">Työskennellään</string>
<string name="protection">Suojaus</string>
<string name="content_description_remove_from_list">Poista</string>
<string name="encryption_rijndael">Rijndael (AES)</string>
<string name="root">Juuri</string>
<string name="rounds">Salauskierroksia</string>
<string name="rounds_explanation">Suurempi kierrosten määrä parantaa suojausta raa\'alla voimalla tehdyiltä murtoyrityksiltä, mutta voi todella hidastaa lataamista ja tallentamista.</string>
<string name="saving_database">Tallennetaan tietokantaa&#8230;</string>
<string name="saving_database">Tallennetaan tietokantaa</string>
<string name="space">Tila</string>
<string name="search_label">Etsi</string>
<string name="sort_db">Tietokannan lajittelujärjestys</string>
@@ -134,23 +132,32 @@
<string name="unsupported_db_version">Ei-tuettu salasanatietokannan versio.</string>
<string name="uppercase">Isot kirjaimet</string>
<string name="version_label">Versio %1$s</string>
<string name="education_unlock_summary">Syötä salasana ja/tai avaintiedosto avataksesi tietokantasi.</string>
<string-array name="timeout_options">
<item>5 sekuntia</item>
<item>10 sekuntia</item>
<item>20 sekuntia</item>
<item>30 sekuntia</item>
<item>1 minuutti</item>
<item>5 minuttia</item>
<item>15 minuttia</item>
<item>30 minuttia</item>
<item>Ei koskaan</item>
<item>5 sekuntia</item>
<item>10 sekuntia</item>
<item>20 sekuntia</item>
<item>30 sekuntia</item>
<item>1 minuutti</item>
<item>5 minuttia</item>
<item>15 minuttia</item>
<item>30 minuttia</item>
<item>Ei koskaan</item>
</string-array>
<string-array name="list_size_options">
<item>Pieni</item>
<item>Keskikokoinen</item>
<item>Suuri</item>
<item>Pieni</item>
<item>Keskikokoinen</item>
<item>Suuri</item>
</string-array>
<string name="clipboard_swipe_clean">Pyyhkäise tyhjentääksesi leikepöydän</string>
<string name="allow">Salli</string>
<string name="extended_ASCII">Laajennettu ASCII</string>
<string name="key_derivation_function">Avaimen derivointifunktio</string>
<string name="master_key">Pääavain</string>
<string name="contribution">Avustus</string>
<string name="contact">Ota yhteyttä</string>
<string name="content_description_open_file">Avaa tiedosto</string>
<string name="encryption">Salaus</string>
<string name="security">Turvallisuus</string>
<string name="edit_entry">Muokkaa merkintää</string>
</resources>

View File

@@ -31,7 +31,6 @@
<string name="application">Application</string>
<string name="menu_app_settings">Paramètres de lapplication</string>
<string name="menu_form_filling_settings">Remplissage de formulaire</string>
<string name="beta_dontask">Ne plus afficher</string>
<string name="brackets">Parenthèses (ou autres)</string>
<string name="extended_ASCII">ASCII étendu</string>
<string name="file_manager_install_description">Un gestionnaire de fichiers qui accepte l\'action d\'intention ACTION_CREATE_DOCUMENT et ACTION_OPEN_DOCUMENT est nécessaire pour créer, ouvrir et enregistrer des fichiers de base de données.</string>
@@ -91,7 +90,7 @@
<string name="hint_length">Longueur</string>
<string name="hint_pass">Mot de passe</string>
<string name="password">Mot de passe</string>
<string name="invalid_credentials">Impossible de lire les identifiants. Si cela se reproduit, votre fichier de base de données est peut-être corrompu.</string>
<string name="invalid_credentials">Impossible de lire les identifiants.</string>
<string name="invalid_algorithm">Algorithme invalide.</string>
<string name="invalid_db_sig">Impossible de reconnaître le format de la base de données.</string>
<string name="keyfile_is_empty">Le fichier clé est vide.</string>

View File

@@ -16,10 +16,9 @@
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="feedback">Comentarios:</string>
<string name="homepage">Páxina inicial:</string>
--><resources>
<string name="feedback">Comentarios</string>
<string name="homepage">Páxina inicial</string>
<string name="about_description">KeePassDX é unha implementación para Android do xestor de contrasinais KeePass.</string>
<string name="accept">Aceptar</string>
<string name="add_entry">Engadir entrada</string>
@@ -30,7 +29,6 @@
<string name="app_timeout">Tempo de espera da aplicación</string>
<string name="app_timeout_summary">Tempo antes de bloquear a base de datos cando a aplicación está inactiva.</string>
<string name="application">Aplicación</string>
<string name="beta_dontask">Non amosar de novo</string>
<string name="brackets">Parénteses</string>
<string name="extended_ASCII">ASCII extendido</string>
<string name="allow">Permitir</string>

View File

@@ -31,7 +31,6 @@
<string name="app_timeout">ऐप का समय समाप्त</string>
<string name="app_timeout_summary">ऐप लॉक होने से पहले निष्क्रियता</string>
<string name="application">ऐप</string>
<string name="beta_dontask">फिर मत दिखाना</string>
<string name="brackets">कोष्ठक</string>
<string name="extended_ASCII">विस्तारित ASCII</string>
<string name="allow">अनुमति दें</string>

View File

@@ -16,8 +16,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>
--><resources>
<string name="about_description">Android implementacija KeePass upravitelja lozinki</string>
<string name="accept">Prihvati</string>
<string name="add_entry">Dodaj unos</string>
@@ -30,7 +29,6 @@
<string name="key_derivation_function">Funkcija izvedbe ključa</string>
<string name="app_timeout_summary">Vrijeme neaktivnosti prije zaključavanja baze podataka</string>
<string name="application">Aplikacija</string>
<string name="beta_dontask">Ne prikazuj ponovno</string>
<string name="brackets">Zagrade</string>
<string name="extended_ASCII">Prošireni ASCII kod</string>
<string name="file_manager_install_description">Za stvaranje, otvaranje i pohranu datoteka baze podataka potreban je upravitelj datoteka koji prihvaća zahtjeve ACTION_CREATE_DOCUMENT i ACTION_OPEN_DOCUMENT.</string>
@@ -260,7 +258,7 @@
<string name="error_save_database">Nije moguće spremiti bazu podataka.</string>
<string name="error_otp_period">Razdoblje mora biti između %1$d i %2$d sekundi.</string>
<string name="file_not_found_content">Nije moguće pronaći datoteku. Probajte je ponovno otvoriti iz vašeg upravitelja datotekama.</string>
<string name="invalid_credentials">Akreditacija se ne može pročitati. Ako se ovo ponavlja, vaša datoteka baze podataka je možda oštećena.</string>
<string name="invalid_credentials">Akreditacija se ne može pročitati.</string>
<string name="list_size_title">Veličina članova liste</string>
<string name="list_size_summary">Veličina teksta članova liste</string>
<string name="lowercase">Mala slova</string>
@@ -274,7 +272,7 @@
<string name="progress_title">Obrada…</string>
<string name="read_only">Zaštićeno od pisanja</string>
<string name="read_only_warning">Zavisno o vašem upravitelju datotekama, KeePassDX možda neće moći zapisivati u vašu pohranu.</string>
<string name="contains_duplicate_uuid_procedure">Potvrdom ovog dialoga, KeePassDX će riješiti problem (generiranjem novih UUID-ova za duplikate) i nastaviti.</string>
<string name="contains_duplicate_uuid_procedure">Riješi problem generiranjem novih UUID-ova za duplikate\?</string>
<string name="root">Korijen</string>
<string name="memory_usage_explanation">Količina memorije (u bajtovima) koju će koristiti funkcija izvedbe ključa.</string>
<string name="do_not_kill_app">Ne zatvarajte aplikaciju…</string>
@@ -342,4 +340,15 @@
<string name="education_create_database_summary">Kreirajte svoju prvu datoteku za upravljanje lozinkama.</string>
<string name="education_select_database_title">Otvaranje postojeće baze podataka</string>
<string name="education_select_database_summary">Otvorite vašu prijašnju bazu podataka iz vašeg upravitelja datotekama kako bi je nastavili koristiti.</string>
<string name="remember_database_locations_title">Zapamti lokaciju baze podataka</string>
<string name="auto_focus_search_title">Brzo pretraživanje</string>
<string name="error_create_database">Nije moguće kreirati datoteku baze podataka.</string>
<string name="error_rounds_too_large">Prevelik broj \"transformacijskih rundi\". Postavljeno na 2147483648.</string>
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft je &lt;strong&gt;open source&lt;/strong&gt; te &lt;strong&gt;bez reklama&lt;/strong&gt;.
\nDostupan kakav je, pod &lt;strong&gt;GPLv3&lt;/strong&gt; licencom, bez ikakvog jamstva.</string>
<string name="entry_add_attachment">Dodaj privitak</string>
<string name="discard">Odbaci</string>
<string name="discard_changes">Odbaci promjene\?</string>
<string name="contact">Kontakt</string>
<string name="homepage">Početna stranica</string>
</resources>

View File

@@ -28,7 +28,6 @@
<string name="app_timeout_summary">Tétlenség az adatbázis feloldása előtt</string>
<string name="application">Alkalmazás</string>
<string name="menu_app_settings">Alkalmazásbeállítások</string>
<string name="beta_dontask">Ne mutassa újra</string>
<string name="brackets">Zárójelek</string>
<string name="file_manager_install_description">Egy fájlkezelő, amely fogadja az ACTION_CREATE_DOCUMENT és ACTION_OPEN_DOCUMENT Intenteket, melyek az adatbázisfájlok létrehozásához, megnyitásához és mentéséhez szükségesek.</string>
<string name="clipboard_cleared">Vágólap törölve</string>
@@ -84,7 +83,7 @@
<string name="hint_length">Hossz</string>
<string name="hint_pass">Jelszó</string>
<string name="password">Jelszó</string>
<string name="invalid_credentials">A hitelesítő adatok nem olvashatók. Ha ez újra megtörténik, akkor az adatbázisfájl sérült lehet.</string>
<string name="invalid_credentials">A hitelesítő adatok nem olvashatók.</string>
<string name="invalid_algorithm">Hibás algoritmus.</string>
<string name="invalid_db_sig">Az adatbázis formátuma nem ismerhető fel.</string>
<string name="keyfile_is_empty">A kulcsfájl üres.</string>

View File

@@ -85,7 +85,7 @@
<string name="hint_length">Lunghezza</string>
<string name="password">Password</string>
<string name="hint_pass">Password</string>
<string name="invalid_credentials">Non è possibile leggere le credenziali. Se questo dovesse riaccadere, il file del databese potrebbe essere corrotto.</string>
<string name="invalid_credentials">Non è possibile leggere le credenziali.</string>
<string name="invalid_algorithm">Algoritmo errato.</string>
<string name="invalid_db_sig">Formato database non riconosciuto.</string>
<string name="keyfile_is_empty">Il file chiave è vuoto.</string>
@@ -138,7 +138,7 @@
<string name="warning_password_encoding">Evita password con caratteri al di fuori del formato di codifica del testo nel file di database (i caratteri non riconosciuti vengono convertiti nella stessa lettera).</string>
<string name="version_label">Versione %1$s</string>
<string name="configure_biometric">La scansione di impronte è supportata ma non impostata.</string>
<string name="open_biometric_prompt_unlock_database">Scansione impronte</string>
<string name="open_biometric_prompt_unlock_database">Usa la scansione impronte per sbloccare la banca dati</string>
<string name="encrypted_value_stored">Password criptata salvata</string>
<string name="biometric_invalid_key">Impossibile leggere la chiave biometrica. Eliminala e ripeti la procedura di riconoscimento.</string>
<string name="biometric_scanning_error">Problema impronta: %1$s</string>
@@ -163,7 +163,6 @@
<item>Medio</item>
<item>Grande</item>
</string-array>
<string name="beta_dontask">Non mostrare di nuovo</string>
<string name="allow">Consenti</string>
<string name="copy_field">Copia di %1$s</string>
<string name="encryption">Cifratura</string>
@@ -252,7 +251,7 @@
<string name="allow_no_password_summary">Abilita il pulsante «Apri» se le credenziali non sono selezionate</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">Schermate educative</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 le schermate educative</string>
<string name="reset_education_screens_summary">Mostra di nuovo tutti gli elementi educativi</string>

View File

@@ -30,7 +30,6 @@
<string name="app_timeout_summary">זמן לפני נעילת מסד הנתונים כאשר היישום לא פעיל.</string>
<string name="application">יישום</string>
<string name="menu_app_settings">הגדרות יישום</string>
<string name="beta_dontask">אל תציג שוב</string>
<string name="brackets">סוגריים</string>
<string name="file_manager_install_description">סייר הקבצים דורש את סייר הקבצים Open Intents, לחץ למטע כדי להתקין. בגלל מספר בעיות בסייר, ייתכן ויהיו בעיות בהפעלה הראשונה.</string>
<string name="clipboard_cleared">לוח ההעתקה נוקה.</string>

View File

@@ -16,8 +16,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>
--><resources>
<string name="feedback">フィードバック</string>
<string name="homepage">ホームページ</string>
<string name="about_description">KeePass パスワードマネージャーの Android 実装</string>
@@ -26,22 +25,23 @@
<string name="add_group">グループを追加</string>
<string name="encryption_algorithm">暗号化アルゴリズム</string>
<string name="app_timeout">アプリ タイムアウト</string>
<string name="app_timeout_summary">KeePassがこの時間非アクティブだった場合、データベースをロックします。</string>
<string name="application">アプリケーション</string>
<string name="menu_app_settings">アプリケーション設定</string>
<string name="app_timeout_summary">データベースをロックするまでの休止時間</string>
<string name="application">アプリ</string>
<string name="menu_app_settings">アプリ設定</string>
<string name="brackets">カッコ</string>
<string name="file_manager_install_description">ファイルを検索するには OI File Manager が必要です。</string>
<string name="file_manager_install_description">ACTION_CREATE_DOCUMENT と ACTION_OPEN_DOCUMENT のインテントアクションを受け付けるファイルマネージャーがデータベースファイルの作成、オープン、保存に必要です。</string>
<string name="clipboard_cleared">クリップボードを消去しました。</string>
<string name="clipboard_timeout">クリップボード タイムアウト</string>
<string name="clipboard_timeout_summary">コピーした情報をクリップボードから消去する時間</string>
<string name="clipboard_timeout_summary">クリップボードでの保存時間</string>
<string name="select_to_copy">ここをタップすると%1$sをクリップボードにコピーします</string>
<string name="retrieving_db_key">データベース認証中…</string>
<string name="database">データベース</string>
<string name="decrypting_db">データベースを解析中…</string>
<string name="default_checkbox">のデータベースを次回以降も利用する</string>
<string name="decrypting_db">データベースを復号中…</string>
<string name="default_checkbox">デフォルトのデータベースとして使う</string>
<string name="digits">数字</string>
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft によって作られたフリーソフトウェアであり、無保証です。GPLバージョン3以上の条件下でこれを再頒布することができます。</string>
<string name="select_database_file">データベースファイル</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="select_database_file">既存のデータベースを開く</string>
<string name="entry_accessed">最終アクセス日</string>
<string name="entry_cancel">キャンセル</string>
<string name="entry_notes">備考</string>
@@ -55,28 +55,28 @@
<string name="entry_title">タイトル</string>
<string name="entry_url">URL</string>
<string name="entry_user_name">ユーザー名</string>
<string name="error_arc4">Arcfour stream cipherには対応していません。</string>
<string name="error_can_not_handle_uri">KeePassDXはこのuriを処理できません。</string>
<string name="error_arc4">Arcfourストリーム暗号には対応していません。</string>
<string name="error_can_not_handle_uri">KeePassDXはこのURIを処理できません。</string>
<string name="error_file_not_create">ファイルを作成できません。</string>
<string name="error_invalid_db">無効なデータベースです</string>
<string name="error_invalid_path">パスが無効です</string>
<string name="error_no_name">タイトルは必須入力です</string>
<string name="error_nokeyfile">パスワードかキーファイルが必要です</string>
<string name="error_out_of_memory">データベース解析中にメモリ不足になりました</string>
<string name="error_invalid_db">データベースを読み込めません</string>
<string name="error_invalid_path">パスが正しいことを確認してください</string>
<string name="error_no_name">名前を入力してください</string>
<string name="error_nokeyfile">キーファイルを選択してください</string>
<string name="error_out_of_memory">データベース全体を読み込むメモリがありません</string>
<string name="error_pass_gen_type">少なくとも1つ以上のパスワード生成タイプを選択する必要があります。</string>
<string name="error_pass_match">パスワードが一致しません</string>
<string name="error_pass_match">パスワードが一致しません</string>
<string name="error_rounds_too_large">値が大きすぎます。 2147483648にセットしました。</string>
<string name="error_wrong_length">\"長さ\"欄には正の整数を入力してください。</string>
<string name="file_browser">ファイルブラウザ</string>
<string name="file_browser">ファイルマネージャー</string>
<string name="generate_password">パスワードを生成する</string>
<string name="hint_conf_pass">パスワードをもう一度入力</string>
<string name="hint_generated_password">生成されたパスワードが表示されます</string>
<string name="hint_generated_password">生成されたパスワード</string>
<string name="hint_group_name">グループ名</string>
<string name="hint_keyfile">キーファイル</string>
<string name="hint_length">長さ</string>
<string name="password">パスワード</string>
<string name="hint_pass">パスワード</string>
<string name="invalid_credentials">パスワード/キーファイルが違います</string>
<string name="invalid_credentials">認証情報が読めません</string>
<string name="invalid_db_sig">データベースフォーマットが認識できません。</string>
<string name="length">生成するパスワードの長さ</string>
<string name="list_size_title">グループ一覧サイズ</string>
@@ -142,11 +142,10 @@
<string name="edit_entry">エントリーを編集</string>
<string name="encryption">暗号化</string>
<string name="key_derivation_function">鍵導出関数</string>
<string name="beta_dontask">今後、表示しない</string>
<string name="extended_ASCII">拡張 ASCII</string>
<string name="allow">許可</string>
<string name="clipboard_error_title">クリップボードエラー</string>
<string name="clipboard_error">一部の Samsung Android 携帯電話はアプリからクリップボード使用できません。</string>
<string name="clipboard_error">一部の端末ではアプリからクリップボード使用できません。</string>
<string name="clipboard_error_clear">クリップボードをクリアできません</string>
<string name="clipboard_swipe_clean">スワイプすると今すぐクリップボードをクリアします</string>
<string name="entry_not_found">エントリデータが見つかりませんでした。</string>
@@ -214,4 +213,28 @@
<string name="menu_empty_recycle_bin">ゴミ箱を空にする</string>
<string name="command_execution">コマンド実行中…</string>
<string name="warning_permanently_delete_nodes">削除するとこのエントリーは復活できませんがよろしいですか?</string>
<string name="auto_focus_search_summary">データベースを開くとき検索を要求する</string>
<string name="auto_focus_search_title">クイックサーチ</string>
<string name="menu_delete_entry_history">履歴を削除する</string>
<string name="menu_restore_entry_history">履歴を復元する</string>
<string name="list_groups_show_number_entries_summary">グループ内のエントリーの数を表示</string>
<string name="list_groups_show_number_entries_title">エントリーの数を表示</string>
<string name="error_otp_digits">トークンは %1$d 桁 から %2$d 桁である必要があります。</string>
<string name="error_create_database_file">このパスワードとキーファイルでデータベースを作成できません。</string>
<string name="error_create_database">データベースファイルを作成できません。</string>
<string name="error_label_exists">このラベルはすでに存在します。</string>
<string name="error_disallow_no_credentials">少なくとも一つの認証情報がセットされる必要があります。</string>
<string name="error_invalid_OTP">無効な OTP 秘密鍵。</string>
<string name="otp_digits"></string>
<string name="entry_setup_otp">ワンタイムパスワードを設定する</string>
<string name="entry_attachments">添付</string>
<string name="entry_UUID">UUID</string>
<string name="html_about_contribution">&lt;strong&gt;自由を維持し&lt;/strong&gt;&lt;strong&gt;バグを修正し&lt;/strong&gt;&lt;strong&gt;機能を追加し&lt;/strong&gt; and &lt;strong&gt;活発に開発し続ける&lt;/strong&gt;ためには、あなたの&lt;strong&gt;貢献&lt;/strong&gt;が頼りです。</string>
<string name="content_description_keyfile_checkbox">キーファイルのチェックボックス</string>
<string name="content_description_password_checkbox">パスワードのチェックボックス</string>
<string name="content_description_add_node">ノードの追加</string>
<string name="content_description_node_children">ノードの子要素</string>
<string name="content_description_background">バックグラウンド</string>
<string name="security">セキュリティ</string>
<string name="contribution">貢献</string>
</resources>

View File

@@ -31,7 +31,6 @@
<string name="app_timeout">앱 자동 종료 시간</string>
<string name="app_timeout_summary">앱이 잠기기 전에 비활성화됨</string>
<string name="application"></string>
<string name="beta_dontask">다시 보이지 않음</string>
<string name="brackets">브라켓</string>
<string name="extended_ASCII">확장 ASCII</string>
<string name="file_manager_install_description">OpenIntents File Manager를 설치하여 파일 찾아보기</string>

View File

@@ -16,13 +16,12 @@
You should have received a copy of the GNU General Public License
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
-->
<resources>
--><resources>
<string name="about_description">KeePassDX yra KeePass slaptažodžių tvarkyklės realizacija Android platformai</string>
<string name="clipboard_cleared">Iškarpinė išvalyta.</string>
<string name="invalid_credentials">Neteisingas slaptažodis arba rakto failas.</string>
<string name="feedback">Atsiliepimai:</string>
<string name="homepage">Pagrindinis puslapis:</string>
<string name="feedback">Atsiliepimai</string>
<string name="homepage">Pagrindinis puslapis</string>
<string name="accept">Priimti</string>
<string name="add_entry">Pridėti įrašą</string>
<string name="add_group">Pridėti grupę</string>
@@ -30,7 +29,6 @@
<string name="app_timeout_summary">Laikas, per kurį yra užrakinama duomenų bazė po neveiklumo programėlėje.</string>
<string name="application">Programėlė</string>
<string name="menu_app_settings">Programėlės nustatymai</string>
<string name="beta_dontask">Daugiau neberodyti</string>
<string name="brackets">Skliaustai</string>
<string name="database">Duomenų bazė</string>
<string name="digits">Skaitmenys</string>
@@ -108,7 +106,5 @@
<string name="hide_password_summary">Slėpti slaptažodžius pagal nutylėjimą</string>
<string name="invalid_algorithm">Neteisingas algoritmas.</string>
<string name="error_invalid_path">Neteisingas kelias.</string>
<string name="education_unlock_summary">Įveskite slaptažodį rba raktą, tam kad atidarytumėte duomenų bazę.</string>
</resources>

View File

@@ -1,4 +1,4 @@
<?xml version='1.0' encoding='UTF-8'?>
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2020 Jeremy Jamet / Kunzisoft.
@@ -16,10 +16,9 @@
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="feedback">Atsauksmes:</string>
<string name="homepage">Mājaslapa:</string>
--><resources>
<string name="feedback">Atsauksmes</string>
<string name="homepage">Mājaslapa</string>
<string name="about_description">KeePassDX ir KeePass paroļu menedžera Android implementācija</string>
<string name="accept">Pieņemt</string>
<string name="add_entry">Jauns ieraksts</string>
@@ -29,7 +28,6 @@
<string name="app_timeout_summary">Bloķēšanas taimauts, kad programma nav aktīva.</string>
<string name="application">Programma</string>
<string name="menu_app_settings">Programmas iestatījumi</string>
<string name="beta_dontask">Turpmāk nerādīt</string>
<string name="brackets">Iekavas</string>
<string name="file_manager_install_description">Failu pārlūkošanai nepieciešams pārlūks.</string>
<string name="clipboard_cleared">Starpliktuve notīrīta</string>
@@ -132,9 +130,7 @@
<string name="unsupported_db_version">Neatbalstīta datu bāzes versija.</string>
<string name="uppercase">Lielie burti</string>
<string name="version_label">Versija %1$s</string>
<string name="education_unlock_summary">Ievadiet paroli/atslēgas failu, lai atbloķētu savu datu bāzi.</string>
<string-array name="timeout_options">
<item>5 sekundes</item>
<item>10 sekundes</item>
@@ -151,9 +147,9 @@
<item>Vidējs</item>
<item>Liels</item>
</string-array>
<string name="edit_entry">Labot ierakstu</string>
<string name="edit_entry">Labot ierakstu</string>
<string name="encryption">Šifrēšana</string>
<string name="extended_ASCII">Paplašinātais ASCII</string>
<string name="allow">Atļaut</string>
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft nāk bez jebkādas garantijas. Šī ir bezmaksas programmatūra un jūs to varat izplatīt apstākļos, kas aprakstīti GPL 3 versijā vai jaunākā.</string>
</resources>
</resources>

View File

@@ -30,7 +30,6 @@
<string name="app_timeout">Programtidsavbrudd</string>
<string name="app_timeout_summary">Inaktivitet før programmet låses</string>
<string name="application">Program</string>
<string name="beta_dontask">Ikke vis igjen</string>
<string name="brackets">Parenteser</string>
<string name="extended_ASCII">Utvidet ASCII</string>
<string name="file_manager_install_description">Utforsk filer ved å installere OpenIntents-filbehandleren</string>
@@ -223,7 +222,7 @@
<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>
<string name="allow_copy_password_summary">Tillat kopiering av adgangspassordet og beskyttede felter til utklippstavlen</string>
<string name="allow_copy_password_warning">ADVARSEL: Utklippstavlen deles av alle programmer. Hvis sensitiv data kopieres, kan annen programvare gjenopprette den.</string>
<string name="allow_copy_password_warning">Advarsel: Utklippstavlen deles av alle programmer. Hvis sensitiv data kopieres, kan annen programvare gjenopprette den.</string>
<string name="database_name_title">Databasenavn</string>
<string name="database_description_title">Databasebeskrivelse</string>
<string name="database_version_title">Databaseversjon</string>
@@ -256,7 +255,7 @@
<string name="education_biometric_summary">Lenk passordet og fingeravtrykket ditt for å låse opp databasen din enkelt.</string>
<string name="education_entry_edit_title">Rediger oppføringen</string>
<string name="education_entry_edit_summary">Rediger din oppføring med egendefinerte felter, referanser til pooldata kan legges til mellom felter av forskjellige oppføringer.</string>
<string name="education_generate_password_title">Opprett et sterkt passord.</string>
<string name="education_generate_password_title">Opprett et sterkt passord</string>
<string name="education_generate_password_summary">Generer et sterkt passord å tilknytte oppføringen din, definer det i henhold til kriteriene i skjemaet, og ikke glem å gjøre passordet sikkert.</string>
<string name="education_entry_new_field_title">Legg til egendefinerte felter</string>
<string name="education_entry_new_field_summary">Du ønsker å registrere et grunnleggende felt som ikke allerede finnes, fyll inn et nytt et du også kan beskytte visuelt.</string>
@@ -282,7 +281,7 @@
<string name="html_text_ad_free">Ulikt mange passordbehandlingsprogrammer, er dette &lt;strong&gt;reklamefri&lt;/strong&gt;, &lt;strong&gt;copyleftbasert fri programvare&lt;/strong&gt; og samler ikke inn personlig data på tjenerne sine, selv i sin gratisversjon.</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 spesielt hjelpe &lt;strong&gt; realiseringen av gemenskapsprosjekter.&lt;/strong&gt;
</string>
<string name="html_text_feature_generosity">Denne &lt;strong&gt;visuelle funksjonen&lt;/strong&gt; er tilgjengelig takket være din generøsitet.</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_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>
@@ -297,7 +296,7 @@
<string name="encryption_rijndael">Rijndael (AES)</string>
<string name="encryption_twofish">Twofish</string>
<string name="encryption_chacha20">ChaCha20</string>
<string name="kdf_AES">AES KDF</string>
<string name="kdf_AES">AES</string>
<string name="kdf_Argon2">Argon2</string>
<string name="style_choose_title">Velg en drakt</string>
<string name="style_choose_summary">Tilpass programdrakten ved å endre fargene</string>
@@ -320,8 +319,8 @@
<string name="keyboard_appearance_category">Utseende</string>
<string name="keyboard_theme_title">Tastaturdrakt</string>
<string name="keyboard_keys_category">Taster</string>
<string name="keyboard_key_vibrate_title">Vibrer ved tastetrykk</string>
<string name="keyboard_key_sound_title">Lyd ved tastetrykk</string>
<string name="keyboard_key_vibrate_title">Vibrasjonstastetrykk</string>
<string name="keyboard_key_sound_title">Hørbare tastetrykk</string>
<string name="selection_mode">Valgmodus</string>
<string name="do_not_kill_app">Ikke drep programmet…</string>
<string name="lock_database_back_root_title">Tilbakelås</string>
@@ -332,7 +331,7 @@
<string name="keyboard_selection_entry_title">Oppføringsvalg</string>
<string name="keyboard_selection_entry_summary">Vis inndatafelter i Magikeyboard når en oppføring vises</string>
<string name="delete_entered_password_title">Slett passord</string>
<string name="delete_entered_password_summary">Sletter passord innskrevet etter et tilkoblingsforsøk</string>
<string name="delete_entered_password_summary">Sletter passord innskrevet etter et tilkoblingsforsøk til en database</string>
<string name="content_description_open_file">Åpne fil</string>
<string name="content_description_add_node">Legg til node</string>
<string name="content_description_add_entry">Legg til oppføring</string>
@@ -428,4 +427,10 @@
<string name="lock_database_show_button_summary">Viser låseknappen i brukergrensesnittet</string>
<string name="lock_database_show_button_title">Vis låseknapp</string>
<string name="error_label_exists">Denne etiketten finnes allerede.</string>
<string name="validate">Bekreft</string>
<string name="biometric_prompt_extract_credential_title">Åpne database med biometrisk gjenkjenning</string>
<string name="warning_database_link_revoked">Tilgang til filen nektes av filbehandleren</string>
<string name="warning_database_read_only">Innvilg skrivetilgang for å lagre databaseendringer</string>
<string name="hide_broken_locations_summary">Skjul ødelagte lenker i listen over nylige databaser</string>
<string name="hide_broken_locations_title">Skjul ødelagte databaselenker</string>
</resources>

View File

@@ -18,37 +18,37 @@
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
Dutch translation by Erik Devriendt, corrected by Erik Jan Meijer
-->
<resources>
--><resources>
<string name="feedback">Reacties</string>
<string name="homepage">Website</string>
<string name="about_description">Android-implementatie van de KeePass-wachtwoordbeheerder</string>
<string name="about_description">Android-implementatie van KeePass-wachtwoordbeheer</string>
<string name="accept">Accepteren</string>
<string name="add_entry">Item toevoegen</string>
<string name="add_group">Groep toevoegen</string>
<string name="encryption_algorithm">Algoritme</string>
<string name="app_timeout">App-time-out</string>
<string name="app_timeout_summary">Tijd tot vergrendelen bij inactiviteit</string>
<string name="app_timeout_summary">Tijd tot vergrendeling bij inactiviteit</string>
<string name="application">App</string>
<string name="menu_app_settings">App-instellingen</string>
<string name="brackets">Haakjes</string>
<string name="file_manager_install_description">Zoek een bestand op door het installeren van de OpenIntents File Manager</string>
<string name="file_manager_install_description">Bestandsbeheer dat de Intent-actie ACTION_CREATE_DOCUMENT en ACTION_OPEN_DOCUMENT accepteert, is nodig om databasebestanden aan te maken, te openen en op te slaan.</string>
<string name="clipboard_cleared">Klembord gewist</string>
<string name="clipboard_timeout">Klembordtime-out</string>
<string name="clipboard_timeout_summary">Tijd van opslag op het klembord</string>
<string name="select_to_copy">Selecteer om %1$s naar klembord te kopiëren</string>
<string name="retrieving_db_key">Bezig met creëren van databanksleutel…</string>
<string name="database">Databank</string>
<string name="decrypting_db">Bezig met ontsleutelen van databankinhoud…</string>
<string name="default_checkbox">Gebruiken als standaarddatabank</string>
<string name="retrieving_db_key">Databasesleutel ophalen</string>
<string name="database">Database</string>
<string name="decrypting_db">Database-inhoud decoderen </string>
<string name="default_checkbox">Gebruiken als standaarddatabase</string>
<string name="digits">Getallen</string>
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft biedt geen enkele garantie. Dit is vrije software, dus je mag deze software verspreiden onder de voorwaarden van de GPL versie 3 of recenter.</string>
<string name="select_database_file">Bestaande databank openen</string>
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft is &lt;strong&gt;open source&lt;/strong&gt; en &lt;strong&gt;zonder reclame&lt;/strong&gt;.
\nHet wordt geleverd zoals het is, onder &lt;strong&gt;GPLv3&lt;/strong&gt; -licentie, zonder enige garantie.</string>
<string name="select_database_file">Bestaande database openen</string>
<string name="entry_accessed">Laatst geopend</string>
<string name="entry_cancel">Annuleren</string>
<string name="entry_notes">Opmerkingen</string>
<string name="entry_confpassword">Wachtwoord bevestigen</string>
<string name="entry_created">Gecreëerd op</string>
<string name="entry_created">Aangemaakt</string>
<string name="entry_expires">Verloopt op</string>
<string name="entry_keyfile">Sleutelbestand</string>
<string name="entry_modified">Bewerkt op</string>
@@ -59,43 +59,43 @@
<string name="entry_user_name">Gebruikersnaam</string>
<string name="error_arc4">De Arcfour stream-versleuteling wordt niet ondersteund.</string>
<string name="error_can_not_handle_uri">KeePassDX kan deze URI niet verwerken.</string>
<string name="error_file_not_create">Kan bestand niet creëren:</string>
<string name="error_invalid_db">Kan databank niet uitlezen.</string>
<string name="error_file_not_create">Bestand is niet aangemaakt:</string>
<string name="error_invalid_db">Kan database niet uitlezen.</string>
<string name="error_invalid_path">Zorg ervoor dat het pad juist is.</string>
<string name="error_no_name">Voer een naam in.</string>
<string name="error_nokeyfile">Kies een sleutelbestand.</string>
<string name="error_out_of_memory">Onvoldoende vrij geheugen om de gehele databank te laden.</string>
<string name="error_out_of_memory">Onvoldoende vrij geheugen om de gehele database te laden.</string>
<string name="error_pass_gen_type">Je moet minimaal één soort wachtwoordgenerering kiezen.</string>
<string name="error_pass_match">De wachtwoorden komen niet overeen.</string>
<string name="error_rounds_too_large">\"Cycli-waarde\" te groot. Wordt ingesteld op 2147483648.</string>
<string name="error_wrong_length">Voer een positief geheel getal in in het veld \"Lengte\".</string>
<string name="file_browser">Bestandsverkenner</string>
<string name="file_browser">Bestandsbeheer</string>
<string name="generate_password">Wachtwoord genereren</string>
<string name="hint_conf_pass">wachtwoord bevestigen</string>
<string name="hint_generated_password">gegenereerd wachtwoord</string>
<string name="hint_conf_pass">Wachtwoord bevestigen</string>
<string name="hint_generated_password">Gegenereerd wachtwoord</string>
<string name="hint_group_name">Groepsnaam</string>
<string name="hint_keyfile">sleutelbestand</string>
<string name="hint_length">lengte</string>
<string name="hint_keyfile">Sleutelbestand</string>
<string name="hint_length">Lengte</string>
<string name="password">Wachtwoord</string>
<string name="hint_pass">wachtwoord</string>
<string name="invalid_credentials">Ongeldig wachtwoord of sleutelbestand.</string>
<string name="invalid_db_sig">Databankformaat kan niet worden herkend.</string>
<string name="hint_pass">Wachtwoord</string>
<string name="invalid_credentials">Kan referenties niet lezen.</string>
<string name="invalid_db_sig">Databaseformaat kan niet worden herkend.</string>
<string name="length">Lengte</string>
<string name="list_size_title">Grootte van itemlijst</string>
<string name="list_size_summary">Tekstgrootte van itemlijst</string>
<string name="loading_database">Bezig met laden van databank</string>
<string name="list_size_title">Lengte van lijst met items</string>
<string name="list_size_summary">Tekstgrootte in de lijst</string>
<string name="loading_database">Database laden</string>
<string name="lowercase">Kleine letters</string>
<string name="hide_password_title">Wachtwoord verbergen</string>
<string name="hide_password_summary">Wachtwoorden standaard afschermen (***)</string>
<string name="hide_password_title">Wachtwoorden verbergen</string>
<string name="hide_password_summary">Wachtwoorden standaard verbergen (***)</string>
<string name="about">Over</string>
<string name="menu_change_key_settings">Hoofdsleutel wijzigen</string>
<string name="settings">Instellingen</string>
<string name="menu_database_settings">Databank-instellingen</string>
<string name="menu_database_settings">Instellingen database</string>
<string name="menu_delete">Verwijderen</string>
<string name="menu_donate">Doneren</string>
<string name="menu_edit">Bewerken</string>
<string name="menu_hide_password">Wachtwoord verbergen</string>
<string name="menu_lock">Databank vergrendelen</string>
<string name="menu_lock">Database vergrendelen</string>
<string name="menu_open">Openen</string>
<string name="menu_search">Zoeken</string>
<string name="menu_showpass">Wachtwoord tonen</string>
@@ -106,14 +106,14 @@
<string name="no_url_handler">Installeer een webbrowser om deze URL te openen.</string>
<string name="omit_backup_search_title">Back-upitems niet doorzoeken</string>
<string name="omit_backup_search_summary">Hiermee worden groepen \"Back-up\" en \"Prullenbak\" uit de zoekresultaten weggelaten</string>
<string name="progress_create">Bezig met creëren van nieuwe databank</string>
<string name="progress_create">Nieuwe database aanmaken…</string>
<string name="progress_title">Bezig met verwerken…</string>
<string name="content_description_remove_from_list">Verwijderen</string>
<string name="encryption_rijndael">Rijndael (AES)</string>
<string name="root">Hoofdmap</string>
<string name="rounds">Encryptie-cycli</string>
<string name="rounds_explanation">Een hoger aantal encryptie-cycli geeft bijkomende bescherming tegen brute-force aanvallen, maar kan het laden en opslaan sterk vertragen.</string>
<string name="saving_database">Bezig met opslaan van databank</string>
<string name="saving_database">Database opslaan</string>
<string name="space">Ruimte</string>
<string name="search_label">Zoeken</string>
<string name="sort_db">Natuurlijke volgorde</string>
@@ -121,10 +121,10 @@
<string name="search">Zoeken</string>
<string name="encryption_twofish">Twofish</string>
<string name="underline">Onderstrepen</string>
<string name="unsupported_db_version">Niet-ondersteunde databankversie.</string>
<string name="unsupported_db_version">Niet-ondersteunde databaseversie.</string>
<string name="uppercase">Hoofdletters</string>
<string name="version_label">Versie %1$s</string>
<string name="education_unlock_summary">Geef het wachtwoord en/of sleutelbestand op om je databank te ontgrendelen.
<string name="education_unlock_summary">Voer het wachtwoord en/of sleutelbestand in om je database te ontgrendelen.
\n
\nMaak na elke aanpassing een kopie van je .kdbx-bestand op een veilige locatie.</string>
<string-array name="timeout_options">
@@ -146,44 +146,43 @@
<string name="edit_entry">Item bewerken</string>
<string name="encryption">Versleuteling</string>
<string name="key_derivation_function">Sleutelafleidingsfunctie</string>
<string name="beta_dontask">Niet meer tonen</string>
<string name="extended_ASCII">Uitgebreide ASCII</string>
<string name="allow">Toestaan</string>
<string name="clipboard_error_title">Klembordfout</string>
<string name="clipboard_error">Op sommige Samsung-telefoons hebben apps geen toegang tot het klembord.</string>
<string name="clipboard_error">Sommige apparaten staan niet toe dat apps het klembord gebruiken.</string>
<string name="clipboard_error_clear">Wissen van klembord mislukt</string>
<string name="clipboard_swipe_clean">Veeg om klembord nu te wissen</string>
<string name="entry_not_found">Geen iteminhoud gevonden.</string>
<string name="error_load_database">Je databank kan niet worden geladen.</string>
<string name="error_load_database">Je database kan niet worden geladen.</string>
<string name="error_load_database_KDF_memory">De sleutel kan niet worden geladen. Probeer om het \"geheugengebruik\" van KDF te verminderen.</string>
<string name="error_string_key">Elke zin moet een veldnaam bevatten.</string>
<string name="error_autofill_enable_service">De dienst automatisch aanvullen kan niet worden ingeschakeld.</string>
<string name="error_move_folder_in_itself">Een groep kan niet naar zichzelf worden verplaatst.</string>
<string name="field_name">Veldnaam</string>
<string name="field_value">Veldwaarde</string>
<string name="file_not_found_content">Bestand niet gevonden. Probeer opnieuw te openen via je bestandsbeheerder.</string>
<string name="file_not_found_content">Bestand niet gevonden. Probeer opnieuw te openen via bestandsbeheer.</string>
<string name="invalid_algorithm">Ongeldig algoritme.</string>
<string name="keyfile_is_empty">Het sleutelbestand is leeg.</string>
<string name="list_entries_show_username_title">Gebruikersnamen tonen</string>
<string name="list_entries_show_username_summary">Gebruikersnamen tonen in itemlijsten</string>
<string name="list_entries_show_username_summary">Gebruikersnamen tonen in lijsten</string>
<string name="copy_field">Kopie van %1$s</string>
<string name="menu_form_filling_settings">Formulierinvulling</string>
<string name="menu_copy">Kopiëren</string>
<string name="menu_move">Verplaatsen</string>
<string name="menu_paste">Plakken</string>
<string name="menu_cancel">Annuleren</string>
<string name="menu_biometric_remove_key">Opgeslagen vingerafdruk verwijderen</string>
<string name="menu_biometric_remove_key">Opgeslagen biometrische gegevens verwijderen</string>
<string name="menu_file_selection_read_only">Alleen-lezen</string>
<string name="menu_open_file_read_and_write">Lezen en schrijven</string>
<string name="protection">Beveiliging</string>
<string name="read_only">Alleen-lezen</string>
<string name="read_only_warning">KeePassDX moet worden gemachtigd om je databank te kunnen aanpassen.</string>
<string name="show_recent_files_title">Recente bestandgeschiedenis</string>
<string name="show_recent_files_summary">Recent gebruikte bestandsnamen onthouden</string>
<string name="encryption_explanation">Het algoritme dat moet worden gebruikt om de gehele databank te versleutelen.</string>
<string name="show_recent_files_title">Bestandsgeschiedenis</string>
<string name="show_recent_files_summary">Toon locaties van recente databases</string>
<string name="encryption_explanation">Database-encryptie-algoritme dat voor alle gegevens wordt gebruikt.</string>
<string name="kdf_explanation">Om de sleutel voor het algoritme te kunnen genereren, wordt de hoofdsleutel getransformeerd middels een willekeurige afleidingsfunctie.</string>
<string name="memory_usage">Geheugengebruik</string>
<string name="memory_usage_explanation">Het geheugen (in binaire bytes) dat de afleidingsfunctie mag gebruiken.</string>
<string name="memory_usage_explanation">De hoeveelheid geheugen (bytes) dat de afleidingsfunctie mag gebruiken.</string>
<string name="parallelism">Parallellen</string>
<string name="parallelism_explanation">Het aantal parallellen (aantal threads) dat de afleidingsfunctie mag gebruiken.</string>
<string name="sort_menu">Sorteren</string>
@@ -198,15 +197,15 @@
<string name="search_results">Zoekresultaten</string>
<string name="warning">Waarschuwing</string>
<string name="warning_password_encoding">Vermijd wachtwoordtekens buiten het tekstcoderingsformaat in het databasebestand (niet-herkende tekens worden geconverteerd naar dezelfde letter).</string>
<string name="warning_empty_password">Weet je zeker dat je geen wachtwoordontgrendelbescherming wilt\?</string>
<string name="warning_no_encryption_key">Weet je zeker dat je geen sleutel wilt koppelen aan je versleuteling?</string>
<string name="configure_biometric">Vingerafdruk wordt ondersteund, maar is niet ingesteld.</string>
<string name="open_biometric_prompt_unlock_database">Vingerafdrukscanning</string>
<string name="warning_empty_password">Doorgaan zonder beveiliging voor wachtwoordontgrendeling\?</string>
<string name="warning_no_encryption_key">Doorgaan zonder coderingssleutel\?</string>
<string name="configure_biometric">Biometrische herkenning is ondersteund, maar niet ingesteld.</string>
<string name="open_biometric_prompt_unlock_database">Biometrische herkenning gebruiken om de database te ontgrendelen</string>
<string name="encrypted_value_stored">Versleuteld wachtwoord is opgeslagen</string>
<string name="biometric_invalid_key">Kan vingerafdruksleutel niet lezen; herstel je wachtwoord.</string>
<string name="biometric_not_recognized">Vingerafdruk niet herkend</string>
<string name="biometric_scanning_error">Vingerafdrukprobleem: %1$s</string>
<string name="open_biometric_prompt_store_credential">Vingerafdruk gebruiken om dit wachtwoord op te slaan</string>
<string name="biometric_invalid_key">Kan de biometrische gegevens niet lezen. Verwijder deze en herhaal de procedure voor biometrische herkenning.</string>
<string name="biometric_not_recognized">Biometrie niet herkend</string>
<string name="biometric_scanning_error">Probleem met biometrie: %1$s</string>
<string name="open_biometric_prompt_store_credential">Biometrische herkenning gebruiken om wachtwoorden op te slaan</string>
<string name="no_credentials_stored">Deze databank heeft nog geen wachtwoord.</string>
<string name="database_history">Geschiedenis</string>
<string name="menu_appearance_settings">Uiterlijk</string>
@@ -214,32 +213,32 @@
<string name="autofill">Auto-aanvullen</string>
<string name="autofill_service_name">KeePassDX auto-aanvullendienst</string>
<string name="autofill_sign_in_prompt">Inloggen met KeePassDX</string>
<string name="set_autofill_service_title">Standaard aanvuldienst instellen</string>
<string name="set_autofill_service_title">Dienst voor automatisch aanvullen</string>
<string name="autofill_explanation_summary">Schakel de dienst in om formulieren in andere apps snel in te vullen</string>
<string name="password_size_title">Gegenereerde wachtwoordgrootte</string>
<string name="password_size_summary">Standaardgrootte instellen van gegenereerd wachtwoord</string>
<string name="password_size_title">Gegenereerde wachtwoordlengte</string>
<string name="password_size_summary">Standaardlengte van gegenereerd wachtwoord instellen</string>
<string name="list_password_generator_options_title">Wachtwoordtekens</string>
<string name="list_password_generator_options_summary">Standaard wachtwoordtekens instellen</string>
<string name="list_password_generator_options_summary">Toegestane wachtwoordtekens instellen</string>
<string name="clipboard">Klembord</string>
<string name="clipboard_notifications_title">Klembordmeldingen</string>
<string name="clipboard_notifications_summary">Schakel klembordmeldingen in om velden te kopiëren bij het bekijken van een item</string>
<string name="clipboard_warning">Als automatisch wissen van het klembord mislukt, doe dit dan handmatig.</string>
<string name="lock">Vergrendelen</string>
<string name="lock_database_screen_off_title">Schermvergrendeling</string>
<string name="lock_database_screen_off_summary">Databank vergrendelen als het scherm uitgaat</string>
<string name="advanced_unlock">Vingerafdruk</string>
<string name="biometric_unlock_enable_title">Vingerafdrukherkenning</string>
<string name="biometric_unlock_enable_summary">Laat u uw biometrische gegevens scannen om de database te openen</string>
<string name="biometric_delete_all_key_title">Sleutels voor versleuteling verwijderen</string>
<string name="biometric_delete_all_key_summary">Alle aan vingerafdrukherkenning gerelateerde sleutels wilt verwijderen</string>
<string name="biometric_delete_all_key_warning">Weet je zeker dat je alle sleutels van de vingerafdrukherkenning wilt verwijderen\?</string>
<string name="lock_database_screen_off_summary">Database vergrendelen wanneer het scherm is uitgeschakeld</string>
<string name="advanced_unlock">Geavanceerd ontgrendelen</string>
<string name="biometric_unlock_enable_title">Ontgrendelen met biometrie</string>
<string name="biometric_unlock_enable_summary">Gebruik biometrische herkenning om de database te openen</string>
<string name="biometric_delete_all_key_title">Coderingssleutels verwijderen</string>
<string name="biometric_delete_all_key_summary">Alle sleutels voor biometrische herkenning verwijderen</string>
<string name="biometric_delete_all_key_warning">Alle coderingssleutels voor biometrische herkenning verwijderen\?</string>
<string name="unavailable_feature_text">Kan deze functie niet starten.</string>
<string name="unavailable_feature_version">Je Android-versie, %1$s, voldoet niet aan de minimumvereiste %2$s.</string>
<string name="unavailable_feature_hardware">De bijbehorende hardware werd niet gevonden.</string>
<string name="file_name">Bestandsnaam</string>
<string name="path">Pad</string>
<string name="assign_master_key">Hoofdsleutel toewijzen</string>
<string name="create_keepass_file">Nieuwe databank creëren</string>
<string name="create_keepass_file">Nieuwe database aanmaken</string>
<string name="full_file_path_enable_title">Bestandspad</string>
<string name="full_file_path_enable_summary">Volledig bestandspad tonen</string>
<string name="recycle_bin_title">Prullenbak gebruiken</string>
@@ -247,87 +246,84 @@
<string name="monospace_font_fields_enable_title">Veldlettertype</string>
<string name="monospace_font_fields_enable_summary">Wijzig het lettertype dat in velden wordt gebruikt voor een betere leesbaarheid</string>
<string name="allow_copy_password_title">Klembord vertrouwen</string>
<string name="allow_copy_password_summary">Toestaan dat het wachtwoord en beveiligde velden worden gekopieerd naar het klembord</string>
<string name="allow_copy_password_warning">WAARSCHUWING: het klembord wordt gedeeld door alle apps. Als gevoelige gegevens worden gekopieerd, kan andere software deze opvragen.</string>
<string name="database_name_title">Databanknaam</string>
<string name="database_description_title">Databankomschrijving</string>
<string name="database_version_title">Databankversie</string>
<string name="allow_copy_password_summary">Toestaan dat het wachtwoord en beveiligde velden naar het klembord worden gekopieerd</string>
<string name="allow_copy_password_warning">Waarschuwing: Het klembord wordt met alle aps gedeeld. Als gevoelige gegevens worden gekopieerd, kan andere software deze opvragen.</string>
<string name="database_name_title">Databasenaam</string>
<string name="database_description_title">Databaseomschrijving</string>
<string name="database_version_title">Databaseversie</string>
<string name="text_appearance">Tekst</string>
<string name="application_appearance">App</string>
<string name="other">Overig</string>
<string name="keyboard">Toetsenbord</string>
<string name="magic_keyboard_title">Magikeyboard</string>
<string name="magic_keyboard_explanation_summary">Aangepast toetsenbord met je wachtwoorden en alle identiteitsvelden activeren</string>
<string name="allow_no_password_title">Geen hoofdwachtwoord toestaan</string>
<string name="allow_no_password_title">Geen hoofdwachtwoord</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 databank standaard alleen-lezen</string>
<string name="enable_education_screens_title">Educatieve vensters</string>
<string name="enable_education_screens_summary">Markeert de elementen om te leren hoe de app werkt</string>
<string name="reset_education_screens_title">Standaardwaarden</string>
<string name="reset_education_screens_summary">Educatieve vensters opnieuw weergeven</string>
<string name="reset_education_screens_text">Educatieve vensters hersteld</string>
<string name="education_create_database_title">Creëer je databankbestand</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>
<string name="reset_education_screens_summary">Informatieve tips opnieuw weergeven</string>
<string name="reset_education_screens_text">Informatieve tips opnieuw ingesteld</string>
<string name="education_create_database_title">Maak je databasebestand aan</string>
<string name="education_create_database_summary">Maak je eerste wachtwoordbeheerbestand aan.</string>
<string name="education_select_database_title">Open een bestaande databank</string>
<string name="education_select_database_summary">Open vanuit je bestandsverkenner een bestaande databank om dit verder te gebruiken.</string>
<string name="education_new_node_title">Voeg items toe aan de databank</string>
<string name="education_new_node_summary">Voeg items toe om je digitale identiteiten te beheren.
<string name="education_select_database_title">Open een bestaande database</string>
<string name="education_select_database_summary">Open vanuit je bestandsverkenner een bestaande database om dit verder te gebruiken.</string>
<string name="education_new_node_title">Voeg items toe aan de database</string>
<string name="education_new_node_summary">Items helpen om je digitale identiteiten te beheren.
\n
\nVoeg groepen toe (groepen zijn gelijk aan mappen) om items in je databank te organiseren.</string>
\nGroepen (~mappen) organiseren de items in je database.</string>
<string name="education_search_title">Doorzoek al je items</string>
<string name="education_search_summary">Doorzoek items op titel, gebruikersnaam of andere velden om wachtwoorden te vinden.</string>
<string name="education_biometric_title">Ontgrendel de databank met je vingerafdruk</string>
<string name="education_biometric_summary">Koppel je wachtwoord en vingerafdruk om de databank snel te ontgrendelen.</string>
<string name="education_biometric_title">Database-ontgrendeling met biometrie</string>
<string name="education_biometric_summary">Koppel je wachtwoord aan je biometrie om de database snel te ontgrendelen.</string>
<string name="education_entry_edit_title">Item bewerken</string>
<string name="education_entry_edit_summary">Bewerk het item met aangepaste velden. Referenties kunnen worden toegevoegd tussen velden van verschillende items.</string>
<string name="education_generate_password_title">Genereer een sterk wachtwoord voor het item.</string>
<string name="education_generate_password_title">Genereer een sterk wachtwoord</string>
<string name="education_generate_password_summary">Genereer een sterk wachtwoord om aan het item te koppelen, definieer het eenvoudig volgens de criteria van het formulier en vergeet het veilige wachtwoord niet.</string>
<string name="education_entry_new_field_title">Voeg aangepaste velden toe</string>
<string name="education_entry_new_field_summary">Registreer een aanvullend veld door een nieuw aan te maken en dit tevens te beschermen.</string>
<string name="education_unlock_title">Ontgrendel je databank</string>
<string name="education_read_only_title">Databank alleen-lezen</string>
<string name="education_entry_new_field_summary">Registreer een extra veld, voeg een waarde toe en bescherm dit desgewenst.</string>
<string name="education_unlock_title">Ontgrendel je database</string>
<string name="education_read_only_title">Database alleen-lezen</string>
<string name="education_read_only_summary">Wijzig de opstartmodus van de sessie.
\n
\nIn alleen-lezenmodus kunnen geen onbedoelde wijzigingen worden gemaakt.
\n
\nIn schrijfmodus kun je elementen toevoegen, verwijderen of aanpassen.</string>
<string name="education_field_copy_title">Veld kopiëren toestaan</string>
<string name="education_field_copy_summary">Kopieer een veld en plak de inhoud waar je maar wilt.
\n
\nJe kunt verschillende formulier-invulmethodes gebruiken; kies je voorkeursmethode.</string>
<string name="education_lock_title">Databank vergrendelen</string>
<string name="education_lock_summary">Databank snel vergrendelen. Je kunt de app zo instellen dat deze na een tijdje wordt vergrendeld en wanneer het scherm wordt uitgeschakeld.</string>
<string name="education_lock_title">Database vergrendelen</string>
<string name="education_lock_summary">Database snel vergrendelen. Je kunt de app zo instellen dat deze na een tijdje wordt vergrendeld en wanneer het scherm wordt uitgeschakeld.</string>
<string name="education_sort_title">Items sorteren</string>
<string name="education_sort_summary">Kies hoe items en groepen worden gesorteerd.</string>
<string name="education_donation_title">Bijdragen</string>
<string name="education_donation_summary">Draag bij om de stabiliteit en veiligheid te vergroten en door meer functies toe te voegen.</string>
<string name="html_text_ad_free">In tegenstelling tot veel wachtwoordbeheerapps is deze &lt;strong&gt;reclamevrij&lt;/strong&gt;, &lt;strong&gt;vrije software&lt;/strong&gt; en slaat geen persoonlijke gegevens op op haar servers, ongeacht de versie die je gebruikt.</string>
<string name="html_text_buy_pro">Door de pro-versie te kopen krijg je toegang tot deze &lt;strong&gt;visuele functie&lt;/strong&gt; en draag je bij aan het &lt;strong&gt;realiseren van gemeenschapsprojecten.&lt;/strong&gt;
</string>
<string name="html_text_feature_generosity">Deze &lt;strong&gt;visuele functie&lt;/strong&gt; is beschikbaar gekomen door jullie gulheid.</string>
<string name="html_text_donation">Om altijd vrij en actief te blijven, zijn we afhankelijk van jouw &lt;strong&gt;bijdrage.&lt;/strong&gt;
</string>
<string name="html_text_ad_free">In tegenstelling tot veel apps voor wachtwoordbeheer, is deze &lt;strong&gt; reclamevrij&lt;/strong&gt;, &lt;strong&gt; vrije software &lt;/strong&gt; en verzamelt het geen persoonlijke gegevens op haar servers, ongeacht welke versie je gebruikt.</string>
<string name="html_text_buy_pro">Door de pro-versie te kopen krijg je toegang tot dit &lt;strong&gt;visuele thema&lt;/strong&gt; en draag je bij aan het &lt;strong&gt;realiseren van gemeenschapsprojecten.&lt;/strong&gt;</string>
<string name="html_text_feature_generosity">Dit &lt;strong&gt;visuele thema&lt;/strong&gt; is beschikbaar gemaakt dankzij jouw vrijgevigheid.</string>
<string name="html_text_donation">Om altijd vrij en actief te blijven, rekenen we op jouw &lt;strong&gt;bijdrage.&lt;/strong&gt;</string>
<string name="html_text_dev_feature">Deze functie &lt;strong&gt;wordt momenteel ontwikkeld&lt;/strong&gt; en kan alleen beschikbaar komen middels jouw &lt;strong&gt;bijdrage&lt;/strong&gt;.</string>
<string name="html_text_dev_feature_buy_pro">Door de &lt;strong&gt;pro&lt;/strong&gt;-versie te kopen,</string>
<string name="html_text_dev_feature_contibute">Door &lt;strong&gt;bij te dragen&lt;/strong&gt;,</string>
<string name="html_text_dev_feature_encourage">motiveer je ontwikkelaars om &lt;strong&gt;nieuwe functies&lt;/strong&gt; te creëren en &lt;strong&gt;bugs op te lossen&lt;/strong&gt;.</string>
<string name="html_text_dev_feature_encourage">motiveer je ontwikkelaars om &lt;strong&gt;nieuwe functies&lt;/strong&gt; te creëren en &lt;strong&gt;problemen op te lossen&lt;/strong&gt;.</string>
<string name="html_text_dev_feature_thanks">Hartelijk bedankt voor je bijdrage.</string>
<string name="html_text_dev_feature_work_hard">We zijn druk bezig om deze functie snel beschikbaar te stellen.</string>
<string name="html_text_dev_feature_upgrade">Vergeet niet om je app up-to-date te houden door nieuwe versies te installeren.</string>
<string name="download">Downloaden</string>
<string name="contribute">Bijdragen</string>
<string name="encryption_chacha20">ChaCha20</string>
<string name="kdf_AES">AES KDF</string>
<string name="kdf_AES">AES</string>
<string name="kdf_Argon2">Argon2</string>
<string name="style_choose_title">App-thema</string>
<string name="style_choose_summary">Thema gebruikt in de app</string>
<string name="icon_pack_choose_title">Icoonverzameling</string>
<string name="icon_pack_choose_summary">Iconenverzameling gebruikt in de app</string>
<string name="build_label">Bouw %1$s</string>
<string name="build_label">Build %1$s</string>
<string name="keyboard_name">Magikeyboard</string>
<string name="keyboard_label">Magikeyboard (KeePassDX)</string>
<string name="keyboard_setting_label">Magikeyboard-instellingen</string>
<string name="keyboard_setting_label">Instellingen Magikeyboard</string>
<string name="keyboard_entry_category">Item</string>
<string name="keyboard_entry_timeout_title">Time-out</string>
<string name="keyboard_entry_timeout_summary">Time-out om de toetsenbordinvoer te wissen</string>
@@ -337,7 +333,7 @@
<string name="keyboard_notification_entry_content_title">%1$s beschikbaar op Magikeyboard</string>
<string name="keyboard_notification_entry_content_text">%1$s</string>
<string name="keyboard_notification_entry_clear_close_title">Wissen bij het sluiten</string>
<string name="keyboard_notification_entry_clear_close_summary">Sluit de databank tegelijk met de melding</string>
<string name="keyboard_notification_entry_clear_close_summary">Sluit de database tegelijk met de melding</string>
<string name="keyboard_appearance_category">Uiterlijk</string>
<string name="keyboard_theme_title">Toetsenbordthema</string>
<string name="keyboard_keys_category">Toetsen</string>
@@ -345,15 +341,15 @@
<string name="keyboard_key_sound_title">Geluid bij toetsaanslag</string>
<string name="selection_mode">Selectiemodus</string>
<string name="do_not_kill_app">App niet afsluiten…</string>
<string name="lock_database_back_root_title">Druk op \'Terug\' om te vergrendelen</string>
<string name="lock_database_back_root_summary">Vergrendel de databank wanneer de gebruiker op de knop Terug in het hoofdscherm klikt</string>
<string name="lock_database_back_root_title">Druk \'Terug\' om te vergrendelen</string>
<string name="lock_database_back_root_summary">Vergrendel de database wanneer de gebruiker op de knop Terug in het hoofdscherm klikt</string>
<string name="clear_clipboard_notification_title">Wissen bij afsluiten</string>
<string name="clear_clipboard_notification_summary">Sluit de databank tegelijk met de melding</string>
<string name="clear_clipboard_notification_summary">Vergrendel de database wanneer u de melding sluit</string>
<string name="recycle_bin">Prullenmand</string>
<string name="keyboard_selection_entry_title">Itemselectie</string>
<string name="keyboard_selection_entry_summary">Invoervelden in Magikeyboard tonen bij het bekijken van een item</string>
<string name="delete_entered_password_title">Wachtwoord wissen</string>
<string name="delete_entered_password_summary">Wist het ingevoerde wachtwoord na een verbindingspoging</string>
<string name="delete_entered_password_summary">Wis het ingevoerde wachtwoord na een poging met een database te verbinden</string>
<string name="content_description_open_file">Bestand openen</string>
<string name="content_description_node_children">Onderliggende items</string>
<string name="content_description_add_node">Knooppunt toevoegen</string>
@@ -371,7 +367,7 @@
<string name="entry_UUID">UUID</string>
<string name="error_move_entry_here">Je kan hier geen item plaatsen.</string>
<string name="error_copy_entry_here">Je kan hier geen item kopiëren.</string>
<string name="list_groups_show_number_entries_title">Het aantal items tonen</string>
<string name="list_groups_show_number_entries_title">Toon het aantal items</string>
<string name="list_groups_show_number_entries_summary">Toon het aantal items in een groep</string>
<string name="content_description_background">Achtergrond</string>
<string name="content_description_update_from_list">Update</string>
@@ -379,12 +375,12 @@
<string name="error_create_database_file">Kan geen database aanmaken met dit wachtwoord en sleutelbestand.</string>
<string name="menu_advanced_unlock_settings">Geavanceerd ontgrendelen</string>
<string name="biometric_prompt_store_credential_title">Biometrische herkenning opslaan</string>
<string name="biometric_prompt_store_credential_message">Databasereferenties opslaan met biometrische gegevens</string>
<string name="biometric_prompt_extract_credential_title">Database met biometrische herkenning openen</string>
<string name="biometric_prompt_extract_credential_message">Database-referenties uitpakken met biometrische gegevens</string>
<string name="biometric">Biometrisch</string>
<string name="biometric_auto_open_prompt_title">Automatisch biometrische prompt openen</string>
<string name="biometric_auto_open_prompt_summary">Biometrische prompt automatisch openen wanneer een biometrische sleutel is gedefinieerd voor een database</string>
<string name="biometric_prompt_store_credential_message">Waarschuwing: Je moet nog steeds je hoofdwachtwoord onthouden als je biometrische herkenning gebruikt.</string>
<string name="biometric_prompt_extract_credential_title">Database openen met biometrische herkenning</string>
<string name="biometric_prompt_extract_credential_message">Database-referenties uitpakken met biometrische herkenning</string>
<string name="biometric">Biometrie</string>
<string name="biometric_auto_open_prompt_title">Automatisch om biometrie vragen</string>
<string name="biometric_auto_open_prompt_summary">Automatisch om biometrie vragen als een database hiervoor is ingesteld</string>
<string name="enable">Inschakelen</string>
<string name="disable">Uitschakelen</string>
<string name="master_key">Hoofdsleutel</string>
@@ -399,7 +395,7 @@
<string name="otp_algorithm">Algoritme</string>
<string name="entry_otp">OTP</string>
<string name="error_invalid_OTP">Ongeldig OTP-geheim.</string>
<string name="error_disallow_no_credentials">Tenminste één referentie moet worden ingesteld.</string>
<string name="error_disallow_no_credentials">Er moet tenminste één referentie worden ingesteld.</string>
<string name="error_copy_group_here">Je kunt hier geen groep kopiëren.</string>
<string name="error_otp_secret_key">Geheime sleutel moet in Base32-indeling zijn.</string>
<string name="error_otp_counter">Teller moet tussen %1$d en %2$d liggen.</string>
@@ -410,26 +406,74 @@
<string name="menu_security_settings">Beveiligingsinstellingen</string>
<string name="menu_master_key_settings">Instellingen hoofdsleutel</string>
<string name="contains_duplicate_uuid">De database bevat dubbele UUID\'s.</string>
<string name="contains_duplicate_uuid_procedure">Door dit dialoogvenster te valideren, zal KeePassDX het probleem oplossen (door nieuwe UUID\'s voor duplicaten te genereren) en doorgaan.</string>
<string name="contains_duplicate_uuid_procedure">Probleem oplossen door nieuwe UUID\'s te genereren voor de duplicaten\?</string>
<string name="database_opened">Database geopend</string>
<string name="clipboard_explanation_summary">Kopieer invoervelden met behulp van het klembord van uw apparaat</string>
<string name="advanced_unlock_explanation_summary">Geavanceerde ontgrendeling gebruiken om een database gemakkelijker te openen</string>
<string name="database_data_compression_title">Gegevenscompressie</string>
<string name="database_data_compression_summary">Gegevenscompressie verkleint de omvang van de database.</string>
<string name="max_history_items_title">Max. geschiedenis items</string>
<string name="max_history_items_title">Maximum aantal</string>
<string name="max_history_items_summary">Beperk het aantal geschiedenisitems per item</string>
<string name="max_history_size_title">Max. grootte van de geschiedenis</string>
<string name="max_history_size_summary">Grootte van geschiedenis beperken per invoer (in binaire bytes)</string>
<string name="settings_database_recommend_changing_master_key_title">Aanbevolen wijzigen</string>
<string name="max_history_size_title">Maximum</string>
<string name="max_history_size_summary">Geschiedenis (bytes) per item beperken</string>
<string name="settings_database_recommend_changing_master_key_title">Vernieuwing aanbevelen</string>
<string name="settings_database_recommend_changing_master_key_summary">Aanbeveling de hoofdsleutel te wijzigen (dagen)</string>
<string name="settings_database_force_changing_master_key_title">Wijziging afdwingen</string>
<string name="settings_database_force_changing_master_key_title">Vernieuwing afdwingen</string>
<string name="settings_database_force_changing_master_key_summary">De hoofdsleutel verplicht wijzigen (dagen)</string>
<string name="settings_database_force_changing_master_key_next_time_title">Volgende keer verplicht wijzigen</string>
<string name="settings_database_force_changing_master_key_next_time_summary">Het hoofdwachtwoord de volgende keer verplicht wijzigen (eenmalig)</string>
<string name="settings_database_force_changing_master_key_next_time_title">Volgende keer verplicht vernieuwen</string>
<string name="settings_database_force_changing_master_key_next_time_summary">Het hoofdwachtwoord de volgende keer (eenmalig) vernieuwen</string>
<string name="database_default_username_title">Standaard gebruikersnaam</string>
<string name="database_custom_color_title">Aangepaste databasekleur</string>
<string name="compression">Compressie</string>
<string name="compression_none">Geen</string>
<string name="compression_gzip">GZip</string>
<string name="device_keyboard_setting_title">Toetsenbordinstellingen voor apparaat</string>
<string name="compression_gzip">gzip</string>
<string name="device_keyboard_setting_title">Toetsenbordinstellingen</string>
<string name="enable_auto_save_database_summary">Sla de database op na elke belangrijke actie (in \"Schrijf\" modus)</string>
<string name="education_setup_OTP_title">Instellingen OTP</string>
<string name="remember_keyfile_locations_title">Locatie van sleutelbestanden opslaan</string>
<string name="remember_database_locations_title">Databaselocatie opslaan</string>
<string name="hide_expired_entries_summary">Verlopen items worden verborgen</string>
<string name="hide_expired_entries_title">Verberg verlopen items</string>
<string name="download_complete">Klaar! Tik om het bestand te openen.</string>
<string name="download_finalization">Voltooien…</string>
<string name="download_progression">Voortgang: %1$d%%</string>
<string name="download_initialization">Initialiseren…</string>
<string name="download_attachment">Download %1$s</string>
<string name="education_setup_OTP_summary">Stel eenmalig wachtwoordbeheer (HOTP / TOTP) in om een token te genereren dat is aangevraagd voor tweefactorauthenticatie (2FA).</string>
<string name="enable_auto_save_database_title">Automatisch opslaan</string>
<string name="autofill_auto_search_summary">Automatisch zoekresultaten voorstellen vanuit het webdomein of de toepassings-ID</string>
<string name="autofill_auto_search_title">Automatisch zoeken</string>
<string name="recycle_bin_group_title">Prullenbak</string>
<string name="lock_database_show_button_summary">Geeft de vergrendelknop weer in de gebruikersinterface</string>
<string name="lock_database_show_button_title">Vergrendelknop weergeven</string>
<string name="autofill_preference_title">Instellingen voor automatisch aanvullen</string>
<string name="credential_before_click_biometric_button">Voer het wachtwoord in en klik vervolgens op de knop \"Biometrie\".</string>
<string name="keystore_not_accessible">De sleutelopslag is niet correct geïnitialiseerd.</string>
<string name="warning_permanently_delete_nodes">Geselecteerde knooppunten definitief verwijderen\?</string>
<string name="warning_database_link_revoked">Toegang tot het bestand ingetrokken door bestandsbeheer</string>
<string name="warning_database_read_only">Bestandstoegang verlenen om databasewijzigingen op te slaan</string>
<string name="command_execution">Opdracht uitvoeren…</string>
<string name="hide_broken_locations_summary">Verberg gebroken links in de lijst met recente databases</string>
<string name="hide_broken_locations_title">Verberg corrupte databasekoppelingen</string>
<string name="remember_keyfile_locations_summary">Onthoud de locatie van databasesleutelbestanden</string>
<string name="remember_database_locations_summary">Onthoud de locatie van databases</string>
<string name="auto_focus_search_summary">Zoekopdracht aanmaken bij het openen van een database</string>
<string name="auto_focus_search_title">Snel zoeken</string>
<string name="menu_delete_entry_history">Geschiedenis wissen</string>
<string name="menu_restore_entry_history">Geschiedenis herstellen</string>
<string name="menu_empty_recycle_bin">Prullenbak legen</string>
<string name="menu_save_database">Database opslaan</string>
<string name="error_save_database">Kan database niet opslaan.</string>
<string name="error_create_database">Databasebestand is niet aangemaakt.</string>
<string name="error_label_exists">Dit label bestaat al.</string>
<string name="entry_attachments">Bijlagen</string>
<string name="html_about_contribution">Om &lt;strong&gt;onze vrijheid te behouden&lt;/strong&gt;, &lt;strong&gt;bugs te verhelpen&lt;/strong&gt;, &lt;strong&gt;functies toe te voegen&lt;/strong&gt; en &lt;strong&gt;altijd actief te blijven&lt;/strong&gt;, rekenen wij op jouw &lt;strong&gt;bijdrage&lt;/strong&gt;.</string>
<string name="entry_add_attachment">Bijlage toevoegen</string>
<string name="discard">Weggooien</string>
<string name="discard_changes">Veranderingen ongedaan maken\?</string>
<string name="validate">Valideren</string>
<string name="contribution">Bijdragen</string>
<string name="contact">Contact</string>
<string name="keyboard_search_share_summary">Zoek automatisch naar gedeelde informatie om het toetsenbord te vullen</string>
<string name="keyboard_search_share_title">Gedeelde informatie zoeken</string>
</resources>

View File

@@ -16,10 +16,9 @@
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="feedback">Tilbakemelding:</string>
<string name="homepage">Heimeside:</string>
--><resources>
<string name="feedback">Tilbakemelding</string>
<string name="homepage">Heimeside</string>
<string name="about_description">KeePassDX er ei android-utgåve av KeePass passordstyrar.</string>
<string name="accept">Godta</string>
<string name="add_entry">Legg til post</string>
@@ -122,23 +121,21 @@
<string name="unsupported_db_version">Kan ikkje bruka databaseutgåva.</string>
<string name="uppercase">Store bokstavar</string>
<string name="version_label">Utgåve %1$s</string>
<string name="education_unlock_summary">Skriv inn passordet og/eller nøkkelfil for å låsa opp databasen.</string>
<string-array name="timeout_options">
<item>5 sekund</item>
<item>10 sekund</item>
<item>20 sekund</item>
<item>30 sekund</item>
<item>1 minutt</item>
<item>5 minutt</item>
<item>15 minutt</item>
<item>30 minutt</item>
<item>Aldri</item>
<item>5 sekund</item>
<item>10 sekund</item>
<item>20 sekund</item>
<item>30 sekund</item>
<item>1 minutt</item>
<item>5 minutt</item>
<item>15 minutt</item>
<item>30 minutt</item>
<item>Aldri</item>
</string-array>
<string-array name="list_size_options">
<item>Liten</item>
<item>Middels</item>
<item>Stor</item>
<item>Liten</item>
<item>Middels</item>
<item>Stor</item>
</string-array>
</resources>

View File

@@ -74,7 +74,7 @@
<string name="hint_length">Długość</string>
<string name="password">Hasło</string>
<string name="hint_pass">Hasło</string>
<string name="invalid_credentials">Nie można odczytać uwierzytelnień. Jeśli to się powtórzy, plik bazy danych może być uszkodzony.</string>
<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>
@@ -115,7 +115,7 @@
<string name="sort_db">Porządek naturalny</string>
<string name="special">Znaki specjalne</string>
<string name="search">Szukaj</string>
<string name="encryption_twofish">Dwie ryby</string>
<string name="encryption_twofish">Algorytm szyfrujący Twofish</string>
<string name="underline">Podkreślenie</string>
<string name="unsupported_db_version">Nieobsługiwana wersja bazy danych.</string>
<string name="uppercase">Wielkie litery</string>
@@ -141,7 +141,6 @@
<string name="edit_entry">Edytuj wpis</string>
<string name="encryption">Szyfrowanie</string>
<string name="key_derivation_function">Funkcja generująca klucz</string>
<string name="beta_dontask">Nie pokazuj ponownie</string>
<string name="extended_ASCII">Rozszerzone ASCII</string>
<string name="allow">Zezwalaj</string>
<string name="clipboard_error_title">Błąd schowka</string>
@@ -198,7 +197,7 @@
<string name="configure_biometric">Skanowanie odcisków palców jest obsługiwane, ale nie skonfigurowane.</string>
<string name="encrypted_value_stored">Zapisano zaszyfrowane hasło</string>
<string name="sort_groups_before">Grupy poprzednie</string>
<string name="open_biometric_prompt_unlock_database">Skanowanie odcisków palców</string>
<string name="open_biometric_prompt_unlock_database">Otwórz żądanie biometryczne, aby odblokować bazę danych</string>
<string name="biometric_invalid_key">Nie można odczytać klucza biometrycznego. Usuń go i powtórz procedurę rozpoznawania biometrycznego.</string>
<string name="biometric_not_recognized">Nie można rozpoznać odcisku palca</string>
<string name="biometric_scanning_error">Problem z odciskiem palca: %1$s</string>
@@ -345,7 +344,7 @@
<string name="keyboard_selection_entry_title">Wybór wpisu</string>
<string name="keyboard_selection_entry_summary">Pokaż pola wprowadzania w Magikeyboard podczas przeglądania wpisu</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</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>
<string name="content_description_add_entry">Dodaj wpis</string>
<string name="content_description_add_group">Dodaj grupę</string>
@@ -475,4 +474,6 @@
<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="error_label_exists">Ta etykieta już istnieje.</string>
<string name="keyboard_search_share_summary">Automatyczne wyszukiwanie udostępnionych informacji w celu zapełnienia klawiatury</string>
<string name="keyboard_search_share_title">Wyszukaj udostępnione informacje</string>
</resources>

View File

@@ -75,7 +75,7 @@
<string name="hint_length">Tamanho</string>
<string name="password">Senha</string>
<string name="hint_pass">Senha</string>
<string name="invalid_credentials">Não foi possível ler credenciais. Se isso ocorrer novamente, seu arquivo de banco de dados pode estar corrompido.</string>
<string name="invalid_credentials">Não foi possível ler credenciais.</string>
<string name="invalid_db_sig">Não pôde reconhecer formato do banco de dados.</string>
<string name="length">Tamanho</string>
<string name="list_size_title">Tamanho da lista de grupos</string>
@@ -142,7 +142,6 @@
</string-array>
<string name="encryption">Encriptação</string>
<string name="key_derivation_function">Função de derivação de chave</string>
<string name="beta_dontask">Não mostrar novamente</string>
<string name="extended_ASCII">ASCII Extendido</string>
<string name="allow">Permitir</string>
<string name="clipboard_error_title">Erro na área de transferência</string>
@@ -193,7 +192,7 @@
<string name="warning_empty_password">Continuar sem proteção de desbloqueio de senha\?</string>
<string name="warning_no_encryption_key">Continuar sem chave de criptografia\?</string>
<string name="configure_biometric">Impressão digital é suportada, mas não está configurada.</string>
<string name="open_biometric_prompt_unlock_database">Escaneamento de impressão digital</string>
<string name="open_biometric_prompt_unlock_database">Escaneamento de impressão digital para abrir o bando de dados</string>
<string name="encrypted_value_stored">Senha encriptada armazenada</string>
<string name="biometric_invalid_key">Não pôde ler chave de impressão digital. Por favor, apague-a e repita o procedimento de reconhecimento biométrico.</string>
<string name="biometric_not_recognized">Não pôde reconhecer impressão digital</string>
@@ -348,7 +347,7 @@
<string name="keyboard_selection_entry_title">Seleção de entrada</string>
<string name="keyboard_selection_entry_summary">Mostrar campos de entrada no Magikeyboard quando estiver visualizando uma Entrada</string>
<string name="delete_entered_password_title">Deletar senha</string>
<string name="delete_entered_password_summary">Deleta a senha inserida após uma tentativa de conexão</string>
<string name="delete_entered_password_summary">Deleta a senha inserida após uma tentativa de conexão com o banco de dados</string>
<string name="content_description_open_file">Abrir arquivo</string>
<string name="content_description_add_node">Inserir nó</string>
<string name="content_description_add_entry">Adicionar entrada</string>
@@ -475,4 +474,6 @@
<string name="discard_changes">Descartar alterações\?</string>
<string name="validate">Validação</string>
<string name="contribution">Contribuição</string>
<string name="keyboard_search_share_summary">Procurar automaticamente por informação compartilhada para popular o teclado</string>
<string name="keyboard_search_share_title">Procurar informação compartilhada</string>
</resources>

View File

@@ -29,7 +29,6 @@
<string name="app_timeout_summary">Inatividade antes da app ser bloqueada</string>
<string name="application">App</string>
<string name="menu_app_settings">Configurações do aplicativo</string>
<string name="beta_dontask">Não mostrar novamente</string>
<string name="brackets">Parênteses</string>
<string name="file_manager_install_description">Explore ficheiros instalando o gestor de ficheiros OpenIntents</string>
<string name="clipboard_cleared">Área de transferência limpa</string>

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