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) KeePassDX(2.5)
* First stable version of KeePassDX * First stable version of KeePassDX
* Fork completely rewritten from the KeePassDroid project * Fork completely rewritten from the KeePassDroid project

View File

@@ -11,8 +11,8 @@ android {
applicationId "com.kunzisoft.keepass" applicationId "com.kunzisoft.keepass"
minSdkVersion 14 minSdkVersion 14
targetSdkVersion 29 targetSdkVersion 29
versionCode = 33 versionCode = 35
versionName = "2.5" versionName = "2.7"
multiDexEnabled true multiDexEnabled true
testApplicationId = "com.kunzisoft.keepass.tests" testApplicationId = "com.kunzisoft.keepass.tests"
@@ -42,9 +42,6 @@ android {
} }
} }
dexOptions {
}
flavorDimensions "version" flavorDimensions "version"
productFlavors { productFlavors {
libre { libre {
@@ -72,7 +69,7 @@ android {
buildConfigField "String", "BUILD_VERSION", "\"free\"" buildConfigField "String", "BUILD_VERSION", "\"free\""
buildConfigField "boolean", "FULL_VERSION", "false" buildConfigField "boolean", "FULL_VERSION", "false"
buildConfigField "boolean", "CLOSED_STORE", "true" 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", "{}" buildConfigField "String[]", "ICON_PACKS_DISABLED", "{}"
manifestPlaceholders = [ googleAndroidBackupAPIKey:"AEdPqrEAAAAIbRfbV8fHLItXo8OcHwrO0sSNblqhPwkc0DPTqg" ] manifestPlaceholders = [ googleAndroidBackupAPIKey:"AEdPqrEAAAAIbRfbV8fHLItXo8OcHwrO0sSNblqhPwkc0DPTqg" ]
} }
@@ -88,42 +85,44 @@ android {
targetCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_8
} }
kotlinOptions {
jvmTarget = "1.8"
}
} }
def room_version = "2.2.5" def room_version = "2.2.5"
dependencies { 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.appcompat:appcompat:1.1.0'
implementation 'androidx.preference:preference:1.1.1' 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.cardview:cardview:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.documentfile:documentfile:1.0.1' implementation 'androidx.documentfile:documentfile:1.0.1'
implementation 'androidx.biometric:biometric: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 // To upgrade with style
implementation 'com.google.android.material:material:1.0.0' implementation 'com.google.android.material:material:1.0.0'
// Database // Database
implementation "androidx.room:room-runtime:$room_version" implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version" kapt "androidx.room:room-compiler:$room_version"
// Crypto // Crypto
implementation 'org.bouncycastle:bcprov-jdk15on:1.65' implementation 'org.bouncycastle:bcprov-jdk15on:1.65.01'
// Time // Time
implementation 'joda-time:joda-time:2.9.9' implementation 'joda-time:joda-time:2.10.6'
// Color // Color
implementation 'com.github.Kunzisoft:AndroidClearChroma:2.3' implementation 'com.github.Kunzisoft:AndroidClearChroma:2.3'
// Education // Education
implementation 'com.getkeepsafe.taptargetview:taptargetview:1.13.0' implementation 'com.getkeepsafe.taptargetview:taptargetview:1.13.0'
// Apache Commons Collections // Apache Commons Collections
implementation 'commons-collections:commons-collections:3.2.1' implementation 'commons-collections:commons-collections:3.2.2'
implementation 'org.apache.commons:commons-io:1.3.2'
// Apache Commons Codec // Apache Commons Codec
implementation 'commons-codec:commons-codec:1.11' implementation 'commons-codec:commons-codec:1.14'
// Icon pack // Icon pack
implementation project(path: ':icon-pack-classic') implementation project(path: ':icon-pack-classic')
implementation project(path: ':icon-pack-material') implementation project(path: ':icon-pack-material')
// Tests // 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:name="com.kunzisoft.keepass.activities.AboutActivity"
android:launchMode="singleTask" android:launchMode="singleTask"
android:label="@string/about" /> android:label="@string/about" />
<activity android:name="com.kunzisoft.keepass.settings.SettingsActivity" /> <activity
<activity android:name="com.kunzisoft.keepass.autofill.AutofillLauncherActivity" android:name="com.kunzisoft.keepass.settings.SettingsActivity" />
<activity
android:name="com.kunzisoft.keepass.activities.AutofillLauncherActivity"
android:theme="@style/Theme.Transparent"
android:configChanges="keyboardHidden" /> android:configChanges="keyboardHidden" />
<activity android:name="com.kunzisoft.keepass.settings.SettingsAdvancedUnlockActivity" /> <activity
<activity android:name="com.kunzisoft.keepass.settings.AutofillSettingsActivity" /> android:name="com.kunzisoft.keepass.settings.SettingsAdvancedUnlockActivity" />
<activity android:name="com.kunzisoft.keepass.magikeyboard.KeyboardLauncherActivity" <activity
android:label="@string/keyboard_name" android:name="com.kunzisoft.keepass.settings.AutofillSettingsActivity" />
android:exported="true"> <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>
<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"> android:label="@string/keyboard_setting_label">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN"/>

View File

@@ -17,7 +17,7 @@
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>. * 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.Activity
import android.app.PendingIntent import android.app.PendingIntent
@@ -26,27 +26,45 @@ import android.content.Intent
import android.content.IntentSender import android.content.IntentSender
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.widget.Toast
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import com.kunzisoft.keepass.activities.FileDatabaseSelectActivity import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.GroupActivity import com.kunzisoft.keepass.autofill.AutofillHelper
import com.kunzisoft.keepass.autofill.KeeAutofillService
import com.kunzisoft.keepass.database.element.Database import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.search.SearchHelper
import com.kunzisoft.keepass.model.SearchInfo import com.kunzisoft.keepass.model.SearchInfo
import com.kunzisoft.keepass.settings.PreferencesUtil
@RequiresApi(api = Build.VERSION_CODES.O) @RequiresApi(api = Build.VERSION_CODES.O)
class AutofillLauncherActivity : AppCompatActivity() { class AutofillLauncherActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { 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) // Pass extra for Autofill (EXTRA_ASSIST_STRUCTURE)
val assistStructure = AutofillHelper.retrieveAssistStructure(intent) val assistStructure = AutofillHelper.retrieveAssistStructure(intent)
if (assistStructure != null) {
// Build search param if (assistStructure == null) {
val searchInfo = SearchInfo().apply { setResult(Activity.RESULT_CANCELED)
applicationId = intent.getStringExtra(KEY_SEARCH_APPLICATION_ID) finish()
webDomain = intent.getStringExtra(KEY_SEARCH_DOMAIN) } 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 // If database is open
AutofillHelper.checkAutoSearchInfo(this, SearchHelper.checkAutoSearchInfo(this,
Database.getInstance(), Database.getInstance(),
searchInfo, searchInfo,
{ items -> { items ->
@@ -57,17 +75,17 @@ class AutofillLauncherActivity : AppCompatActivity() {
{ {
// Show the database UI to select the entry // Show the database UI to select the entry
GroupActivity.launchForAutofillResult(this, GroupActivity.launchForAutofillResult(this,
assistStructure) assistStructure,
false,
searchInfo)
}, },
{ {
// If database not open // If database not open
FileDatabaseSelectActivity.launchForAutofillResult(this, FileDatabaseSelectActivity.launchForAutofillResult(this,
assistStructure, searchInfo) assistStructure,
searchInfo)
} }
) )
} else {
setResult(Activity.RESULT_CANCELED)
finish()
} }
super.onCreate(savedInstanceState) 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.Entry
import com.kunzisoft.keepass.database.element.Group import com.kunzisoft.keepass.database.element.Group
import com.kunzisoft.keepass.database.element.icon.IconImage 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.database.element.node.NodeId
import com.kunzisoft.keepass.education.EntryEditActivityEducation import com.kunzisoft.keepass.education.EntryEditActivityEducation
import com.kunzisoft.keepass.notifications.ClipboardEntryNotificationService import com.kunzisoft.keepass.notifications.ClipboardEntryNotificationService
@@ -166,9 +167,16 @@ class EntryEditActivity : LockingActivity(),
mNewEntry = mDatabase?.createEntry() mNewEntry = mDatabase?.createEntry()
} }
mParent = mDatabase?.getGroupById(it) mParent = mDatabase?.getGroupById(it)
// Add the default icon // Add the default icon from parent if not a folder
mDatabase?.drawFactory?.let { iconFactory -> val parentIcon = mParent?.icon
entryEditContentsView?.setDefaultIcon(iconFactory) 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.annotation.SuppressLint
import android.app.Activity import android.app.Activity
import android.app.assist.AssistStructure import android.app.assist.AssistStructure
import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
@@ -41,12 +42,12 @@ import com.google.android.material.snackbar.Snackbar
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.dialogs.AssignMasterKeyDialogFragment import com.kunzisoft.keepass.activities.dialogs.AssignMasterKeyDialogFragment
import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper 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.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.adapters.FileDatabaseHistoryAdapter
import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction
import com.kunzisoft.keepass.autofill.AutofillHelper 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.action.ProgressDialogThread
import com.kunzisoft.keepass.database.element.Database import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.education.FileDatabaseSelectActivityEducation 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 kotlinx.android.synthetic.main.activity_file_selection.*
import java.io.FileNotFoundException import java.io.FileNotFoundException
class FileDatabaseSelectActivity : StylishActivity(), class FileDatabaseSelectActivity : SpecialModeActivity(),
AssignMasterKeyDialogFragment.AssignPasswordDialogListener { AssignMasterKeyDialogFragment.AssignPasswordDialogListener {
// Views // Views
private var coordinatorLayout: CoordinatorLayout? = null private var coordinatorLayout: CoordinatorLayout? = null
private var fileManagerExplanationButton: View? = 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 private var openDatabaseButtonView: View? = null
// Adapter to manage database history list // Adapter to manage database history list
@@ -95,19 +97,13 @@ class FileDatabaseSelectActivity : StylishActivity(),
UriUtil.gotoUrl(this, R.string.file_manager_explanation_url) UriUtil.gotoUrl(this, R.string.file_manager_explanation_url)
} }
// Create button databaseButtonsContainerView = findViewById(R.id.database_buttons_container)
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
}
createButtonView?.setOnClickListener { createNewFile() } // Create database button
createDatabaseButtonView = findViewById(R.id.create_database_button)
createDatabaseButtonView?.setOnClickListener { createNewFile() }
// Open database button
mOpenFileHelper = OpenFileHelper(this) mOpenFileHelper = OpenFileHelper(this)
openDatabaseButtonView = findViewById(R.id.open_keyfile_button) openDatabaseButtonView = findViewById(R.id.open_keyfile_button)
openDatabaseButtonView?.apply { openDatabaseButtonView?.apply {
@@ -156,7 +152,7 @@ class FileDatabaseSelectActivity : StylishActivity(),
UriUtil.parse(databasePath)?.let { databaseFileUri -> UriUtil.parse(databasePath)?.let { databaseFileUri ->
launchPasswordActivityWithPath(databaseFileUri) launchPasswordActivityWithPath(databaseFileUri)
} ?: run { } ?: 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?) { private fun launchPasswordActivity(databaseUri: Uri, keyFile: Uri?) {
val searchInfo: SearchInfo? = intent.getParcelableExtra(KEY_SEARCH_INFO)
EntrySelectionHelper.doEntrySelectionAction(intent, EntrySelectionHelper.doEntrySelectionAction(intent,
{ {
try { try {
PasswordActivity.launch(this@FileDatabaseSelectActivity, PasswordActivity.launch(this@FileDatabaseSelectActivity,
databaseUri, keyFile) databaseUri, keyFile,
searchInfo)
} catch (e: FileNotFoundException) { } catch (e: FileNotFoundException) {
fileNoFoundAction(e) fileNoFoundAction(e)
} }
// Remove the search info from intent
if (searchInfo != null) {
finish()
}
}, },
{ {
try { try {
PasswordActivity.launchForKeyboardResult(this@FileDatabaseSelectActivity, PasswordActivity.launchForKeyboardResult(this@FileDatabaseSelectActivity,
databaseUri, keyFile) databaseUri, keyFile,
finish() searchInfo)
} catch (e: FileNotFoundException) { } catch (e: FileNotFoundException) {
fileNoFoundAction(e) fileNoFoundAction(e)
} }
finish()
}, },
{ assistStructure -> { assistStructure ->
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
@@ -220,23 +223,27 @@ class FileDatabaseSelectActivity : StylishActivity(),
PasswordActivity.launchForAutofillResult(this@FileDatabaseSelectActivity, PasswordActivity.launchForAutofillResult(this@FileDatabaseSelectActivity,
databaseUri, keyFile, databaseUri, keyFile,
assistStructure, assistStructure,
intent.getParcelableExtra(KEY_SEARCH_INFO)) searchInfo)
} catch (e: FileNotFoundException) { } catch (e: FileNotFoundException) {
fileNoFoundAction(e) fileNoFoundAction(e)
} }
} }
}) })
} }
private fun launchGroupActivity(readOnly: Boolean) { private fun launchGroupActivity(readOnly: Boolean) {
val searchInfo: SearchInfo? = intent.getParcelableExtra(KEY_SEARCH_INFO)
EntrySelectionHelper.doEntrySelectionAction(intent, EntrySelectionHelper.doEntrySelectionAction(intent,
{ {
GroupActivity.launch(this@FileDatabaseSelectActivity, GroupActivity.launch(this@FileDatabaseSelectActivity,
false,
searchInfo,
readOnly) readOnly)
}, },
{ {
GroupActivity.launchForKeyboardSelection(this@FileDatabaseSelectActivity, GroupActivity.launchForEntrySelectionResult(this@FileDatabaseSelectActivity,
false,
searchInfo,
readOnly) readOnly)
// Do not keep history // Do not keep history
finish() finish()
@@ -245,7 +252,8 @@ class FileDatabaseSelectActivity : StylishActivity(),
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
GroupActivity.launchForAutofillResult(this@FileDatabaseSelectActivity, GroupActivity.launchForAutofillResult(this@FileDatabaseSelectActivity,
assistStructure, assistStructure,
intent.getParcelableExtra(KEY_SEARCH_INFO), false,
searchInfo,
readOnly) readOnly)
} }
}) })
@@ -259,37 +267,52 @@ class FileDatabaseSelectActivity : StylishActivity(),
} }
override fun onResume() { 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() val database = Database.getInstance()
if (database.loaded) { if (database.loaded) {
launchGroupActivity(database.isReadOnly) 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 { } else {
mAdapterDatabaseHistory?.clearDatabaseFileHistoryList() // Construct adapter with listeners
mAdapterDatabaseHistory?.notifyDataSetChanged() 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 // Register progress task
mProgressDialogThread?.registerProgressTask() mProgressDialogThread?.registerProgressTask()
}
} }
override fun onPause() { override fun onPause() {
@@ -368,7 +391,10 @@ class FileDatabaseSelectActivity : StylishActivity(),
override fun onCreateOptionsMenu(menu: Menu): Boolean { override fun onCreateOptionsMenu(menu: Menu): Boolean {
super.onCreateOptionsMenu(menu) super.onCreateOptionsMenu(menu)
MenuUtil.defaultMenuInflater(menuInflater, menu)
if (!mSelectionMode) {
MenuUtil.defaultMenuInflater(menuInflater, menu)
}
Handler().post { performedNextEducation(FileDatabaseSelectActivityEducation(this)) } Handler().post { performedNextEducation(FileDatabaseSelectActivityEducation(this)) }
@@ -377,11 +403,11 @@ class FileDatabaseSelectActivity : StylishActivity(),
private fun performedNextEducation(fileDatabaseSelectActivityEducation: FileDatabaseSelectActivityEducation) { private fun performedNextEducation(fileDatabaseSelectActivityEducation: FileDatabaseSelectActivityEducation) {
// If no recent files // If no recent files
val createDatabaseEducationPerformed = createButtonView != null && createButtonView!!.visibility == View.VISIBLE val createDatabaseEducationPerformed = createDatabaseButtonView != null && createDatabaseButtonView!!.visibility == View.VISIBLE
&& mAdapterDatabaseHistory != null && mAdapterDatabaseHistory != null
&& mAdapterDatabaseHistory!!.itemCount > 0 && mAdapterDatabaseHistory!!.itemCount > 0
&& fileDatabaseSelectActivityEducation.checkAndPerformedCreateDatabaseEducation( && fileDatabaseSelectActivityEducation.checkAndPerformedCreateDatabaseEducation(
createButtonView!!, createDatabaseButtonView!!,
{ {
createNewFile() 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 * Keyboard Launch
* ------------------------- * -------------------------
*/ */
fun launchForKeyboardSelection(activity: Activity) { fun launchForEntrySelectionResult(activity: Activity,
EntrySelectionHelper.startActivityForEntrySelection(activity, Intent(activity, FileDatabaseSelectActivity::class.java)) 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) @RequiresApi(api = Build.VERSION_CODES.O)
fun launchForAutofillResult(activity: Activity, fun launchForAutofillResult(activity: Activity,
assistStructure: AssistStructure, assistStructure: AssistStructure,
searchInfo: SearchInfo?) { searchInfo: SearchInfo? = null) {
AutofillHelper.startActivityForAutofillResult(activity, AutofillHelper.startActivityForAutofillResult(activity,
Intent(activity, FileDatabaseSelectActivity::class.java), Intent(activity, FileDatabaseSelectActivity::class.java),
assistStructure, 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.IconPickerDialogFragment
import com.kunzisoft.keepass.activities.dialogs.SortDialogFragment import com.kunzisoft.keepass.activities.dialogs.SortDialogFragment
import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper 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.helpers.ReadOnlyHelper
import com.kunzisoft.keepass.activities.lock.LockingActivity import com.kunzisoft.keepass.activities.lock.LockingActivity
import com.kunzisoft.keepass.adapters.SearchEntryCursorAdapter 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.database.element.node.Type
import com.kunzisoft.keepass.education.GroupActivityEducation import com.kunzisoft.keepass.education.GroupActivityEducation
import com.kunzisoft.keepass.icons.assignDatabaseIcon import com.kunzisoft.keepass.icons.assignDatabaseIcon
import com.kunzisoft.keepass.magikeyboard.MagikIME
import com.kunzisoft.keepass.model.SearchInfo 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_COPY_NODES_TASK
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_CREATE_GROUP_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 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.settings.PreferencesUtil
import com.kunzisoft.keepass.timeout.TimeoutHelper import com.kunzisoft.keepass.timeout.TimeoutHelper
import com.kunzisoft.keepass.utils.MenuUtil import com.kunzisoft.keepass.utils.MenuUtil
import com.kunzisoft.keepass.view.AddNodeButtonView import com.kunzisoft.keepass.view.*
import com.kunzisoft.keepass.view.ToolbarAction
import com.kunzisoft.keepass.view.asError
import com.kunzisoft.keepass.view.showActionError
class GroupActivity : LockingActivity(), class GroupActivity : LockingActivity(),
GroupEditDialogFragment.EditGroupListener, GroupEditDialogFragment.EditGroupListener,
@@ -96,7 +94,6 @@ class GroupActivity : LockingActivity(),
private var toolbarAction: ToolbarAction? = null private var toolbarAction: ToolbarAction? = null
private var iconView: ImageView? = null private var iconView: ImageView? = null
private var numberChildrenView: TextView? = null private var numberChildrenView: TextView? = null
private var modeTitleView: TextView? = null
private var addNodeButtonView: AddNodeButtonView? = null private var addNodeButtonView: AddNodeButtonView? = null
private var groupNameView: TextView? = null private var groupNameView: TextView? = null
@@ -106,6 +103,9 @@ class GroupActivity : LockingActivity(),
private var mCurrentGroupIsASearch: Boolean = false private var mCurrentGroupIsASearch: Boolean = false
private var mRequestStartupSearch = true private var mRequestStartupSearch = true
// To manage history in selection mode
private var mSelectionModeCountBackStack = 0
// Nodes // Nodes
private var mRootGroup: Group? = null private var mRootGroup: Group? = null
private var mCurrentGroup: Group? = null private var mCurrentGroup: Group? = null
@@ -135,7 +135,6 @@ class GroupActivity : LockingActivity(),
searchTitleView = findViewById(R.id.search_title) searchTitleView = findViewById(R.id.search_title)
groupNameView = findViewById(R.id.group_name) groupNameView = findViewById(R.id.group_name)
toolbarAction = findViewById(R.id.toolbar_action) toolbarAction = findViewById(R.id.toolbar_action)
modeTitleView = findViewById(R.id.mode_title_view)
lockView = findViewById(R.id.lock_button) lockView = findViewById(R.id.lock_button)
lockView?.setOnClickListener { lockView?.setOnClickListener {
@@ -145,6 +144,11 @@ class GroupActivity : LockingActivity(),
toolbar?.title = "" toolbar?.title = ""
setSupportActionBar(toolbar) 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 // Focus view to reinitialize timeout
resetAppTimeoutWhenViewFocusedOrChanged(addNodeButtonView) resetAppTimeoutWhenViewFocusedOrChanged(addNodeButtonView)
@@ -171,14 +175,6 @@ class GroupActivity : LockingActivity(),
return 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 var fragmentTag = LIST_NODES_FRAGMENT_TAG
if (mCurrentGroupIsASearch) if (mCurrentGroupIsASearch)
fragmentTag = SEARCH_FRAGMENT_TAG fragmentTag = SEARCH_FRAGMENT_TAG
@@ -195,6 +191,14 @@ class GroupActivity : LockingActivity(),
fragmentTag) fragmentTag)
.commit() .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 // Add listeners to the add buttons
addNodeButtonView?.setAddGroupClickListener(View.OnClickListener { addNodeButtonView?.setAddGroupClickListener(View.OnClickListener {
GroupEditDialogFragment.build() GroupEditDialogFragment.build()
@@ -223,6 +227,8 @@ class GroupActivity : LockingActivity(),
newNodes = getListNodesFromBundle(database, newNodesBundle) newNodes = getListNodesFromBundle(database, newNodesBundle)
} }
refreshSearchGroup()
when (actionTask) { when (actionTask) {
ACTION_DATABASE_UPDATE_GROUP_TASK -> { ACTION_DATABASE_UPDATE_GROUP_TASK -> {
if (result.isSuccess) { if (result.isSuccess) {
@@ -277,11 +283,14 @@ class GroupActivity : LockingActivity(),
super.onNewIntent(intent) super.onNewIntent(intent)
intent?.let { intentNotNull -> intent?.let { intentNotNull ->
// To transform KEY_SEARCH_INFO in ACTION_SEARCH
manageSearchInfoIntent(intentNotNull)
Log.d(TAG, "setNewIntent: $intentNotNull") Log.d(TAG, "setNewIntent: $intentNotNull")
setIntent(intentNotNull) setIntent(intentNotNull)
mCurrentGroupIsASearch = if (Intent.ACTION_SEARCH == intentNotNull.action) { mCurrentGroupIsASearch = if (Intent.ACTION_SEARCH == intentNotNull.action) {
// only one instance of search in backstack // only one instance of search in backstack
openSearchGroup(retrieveCurrentGroup(intentNotNull, null)) deletePreviousSearchGroup()
openGroup(retrieveCurrentGroup(intentNotNull, null), true)
true true
} else { } else {
false false
@@ -289,20 +298,34 @@ class GroupActivity : LockingActivity(),
} }
} }
private fun openSearchGroup(group: Group?) { /**
// Delete the previous search fragment * Transform the KEY_SEARCH_INFO in ACTION_SEARCH, return true if KEY_SEARCH_INFO was present
val searchFragment = supportFragmentManager.findFragmentByTag(SEARCH_FRAGMENT_TAG) */
if (searchFragment != null) { private fun manageSearchInfoIntent(intent: Intent): Boolean {
if (supportFragmentManager // To relaunch the activity as ACTION_SEARCH
.popBackStackImmediate(SEARCH_FRAGMENT_TAG, val searchInfo: SearchInfo? = intent.getParcelableExtra(KEY_SEARCH_INFO)
FragmentManager.POP_BACK_STACK_INCLUSIVE)) val autoSearch = intent.getBooleanExtra(AUTO_SEARCH_KEY, false)
supportFragmentManager.beginTransaction().remove(searchFragment).commit() 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) { private fun deletePreviousSearchGroup() {
openGroup(group, false) // 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) { private fun openGroup(group: Group?, isASearch: Boolean) {
@@ -329,6 +352,12 @@ class GroupActivity : LockingActivity(),
fragmentTransaction.addToBackStack(fragmentTag) fragmentTransaction.addToBackStack(fragmentTag)
fragmentTransaction.commit() fragmentTransaction.commit()
if (mSelectionMode)
mSelectionModeCountBackStack++
// Update last access time.
group?.touch(modified = false, touchParents = false)
mListNodesFragment = newListNodeFragment mListNodesFragment = newListNodeFragment
mCurrentGroup = group mCurrentGroup = group
assignGroupViewElements() assignGroupViewElements()
@@ -346,6 +375,12 @@ class GroupActivity : LockingActivity(),
super.onSaveInstanceState(outState) super.onSaveInstanceState(outState)
} }
private fun refreshSearchGroup() {
deletePreviousSearchGroup()
if (mCurrentGroupIsASearch)
openGroup(retrieveCurrentGroup(intent, null), true)
}
private fun retrieveCurrentGroup(intent: Intent, savedInstanceState: Bundle?): Group? { private fun retrieveCurrentGroup(intent: Intent, savedInstanceState: Bundle?): Group? {
// Force read only if the database is like that // Force read only if the database is like that
@@ -426,13 +461,6 @@ class GroupActivity : LockingActivity(),
// Assign number of children // Assign number of children
refreshNumberOfChildren() refreshNumberOfChildren()
// Show selection mode message if needed
if (mSelectionMode) {
modeTitleView?.visibility = View.VISIBLE
} else {
modeTitleView?.visibility = View.GONE
}
// Show button if allowed // Show button if allowed
addNodeButtonView?.apply { 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() { private fun refreshNumberOfChildren() {
numberChildrenView?.apply { numberChildrenView?.apply {
if (PreferencesUtil.showNumberEntries(context)) { if (PreferencesUtil.showNumberEntries(context)) {
@@ -468,7 +510,8 @@ class GroupActivity : LockingActivity(),
override fun onNodeClick(node: Node) { override fun onNodeClick(node: Node) {
when (node.type) { when (node.type) {
Type.GROUP -> try { Type.GROUP -> try {
openChildGroup(node as Group) // Open child group
openGroup(node as Group, false)
} catch (e: ClassCastException) { } catch (e: ClassCastException) {
Log.e(TAG, "Node can't be cast in Group") Log.e(TAG, "Node can't be cast in Group")
} }
@@ -480,14 +523,13 @@ class GroupActivity : LockingActivity(),
EntryActivity.launch(this@GroupActivity, entryVersioned, mReadOnly) EntryActivity.launch(this@GroupActivity, entryVersioned, mReadOnly)
}, },
{ {
rebuildListNodes()
// Populate Magikeyboard with entry // Populate Magikeyboard with entry
mDatabase?.let { database -> mDatabase?.let { database ->
MagikIME.addEntryAndLaunchNotificationIfAllowed(this@GroupActivity, populateKeyboardAndMoveAppToBackground(this@GroupActivity,
entryVersioned.getEntryInfo(database)) entryVersioned.getEntryInfo(database),
intent)
} }
// Consume the selection mode
EntrySelectionHelper.removeEntrySelectionModeFromIntent(intent)
moveTaskToBack(true)
}, },
{ {
// Build response with the entry selected // Build response with the entry selected
@@ -616,6 +658,7 @@ class GroupActivity : LockingActivity(),
if (database != null if (database != null
&& database.isRecycleBinEnabled && database.isRecycleBinEnabled
&& database.recycleBin != mCurrentGroup) { && database.recycleBin != mCurrentGroup) {
mProgressDialogThread?.startDatabaseDeleteNodes( mProgressDialogThread?.startDatabaseDeleteNodes(
nodes, nodes,
!mReadOnly && mAutoSaveEnable !mReadOnly && mAutoSaveEnable
@@ -667,8 +710,7 @@ class GroupActivity : LockingActivity(),
menu.findItem(R.id.menu_save_database)?.isVisible = false menu.findItem(R.id.menu_save_database)?.isVisible = false
} }
if (!mSelectionMode) { if (!mSelectionMode) {
inflater.inflate(R.menu.default_menu, menu) MenuUtil.defaultMenuInflater(inflater, menu)
MenuUtil.contributionMenuInflater(inflater, menu)
} }
// Menu for recycle bin // Menu for recycle bin
@@ -877,19 +919,16 @@ class GroupActivity : LockingActivity(),
} }
override fun startActivity(intent: Intent) { override fun startActivity(intent: Intent) {
// Get the intent, verify the action and get the query // Get the intent, verify the action and get the query
if (Intent.ACTION_SEARCH == intent.action) { if (Intent.ACTION_SEARCH == intent.action) {
// manually launch the real search activity // manually launch the same search activity
val searchIntent = Intent(applicationContext, GroupActivity::class.java).apply { val searchIntent = getIntent().apply {
// Add bundle of current intent
putExtras(this@GroupActivity.intent)
// add query to the Intent Extras // add query to the Intent Extras
action = Intent.ACTION_SEARCH action = Intent.ACTION_SEARCH
putExtra(SearchManager.QUERY, intent.getStringExtra(SearchManager.QUERY)) putExtra(SearchManager.QUERY, intent.getStringExtra(SearchManager.QUERY))
} }
setIntent(searchIntent)
super.startActivity(searchIntent) onNewIntent(searchIntent)
} else { } else {
super.startActivity(intent) super.startActivity(intent)
} }
@@ -921,12 +960,29 @@ class GroupActivity : LockingActivity(),
mListNodesFragment?.onActivityResult(requestCode, resultCode, data) 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) { if (Intent.ACTION_SEARCH == intent.action) {
mCurrentGroupIsASearch = false
intent.action = Intent.ACTION_DEFAULT intent.action = Intent.ACTION_DEFAULT
intent.removeExtra(SearchManager.QUERY) 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() { override fun onBackPressed() {
@@ -934,24 +990,23 @@ class GroupActivity : LockingActivity(),
finishNodeAction() finishNodeAction()
} else { } else {
// Normal way when we are not in root // Normal way when we are not in root
if (mRootGroup != null && mRootGroup != mCurrentGroup) if (mRootGroup != null && mRootGroup != mCurrentGroup) {
super.onBackPressed() super.onBackPressed()
// Else lock if needed rebuildListNodes()
}
// Else in root, lock if needed
else { else {
intent.removeExtra(AUTO_SEARCH_KEY)
intent.removeExtra(KEY_SEARCH_INFO)
if (PreferencesUtil.isLockDatabaseWhenBackButtonOnRootClicked(this)) { if (PreferencesUtil.isLockDatabaseWhenBackButtonOnRootClicked(this)) {
lockAndExit() lockAndExit()
super.onBackPressed() super.onBackPressed()
} else { } 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 LIST_NODES_FRAGMENT_TAG = "LIST_NODES_FRAGMENT_TAG"
private const val SEARCH_FRAGMENT_TAG = "SEARCH_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 OLD_GROUP_TO_UPDATE_KEY = "OLD_GROUP_TO_UPDATE_KEY"
private const val AUTO_SEARCH_KEY = "AUTO_SEARCH_KEY"
private fun buildIntent(context: Context, private fun buildIntent(context: Context,
group: Group?, group: Group?,
searchInfo: SearchInfo?,
readOnly: Boolean, readOnly: Boolean,
intentBuildLauncher: (Intent) -> Unit) { intentBuildLauncher: (Intent) -> Unit) {
val intent = Intent(context, GroupActivity::class.java) val intent = Intent(context, GroupActivity::class.java)
if (group != null) { if (group != null) {
intent.putExtra(GROUP_ID_KEY, group.nodeId) 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) ReadOnlyHelper.putReadOnlyInIntent(intent, readOnly)
intentBuildLauncher.invoke(intent) intentBuildLauncher.invoke(intent)
} }
private fun checkTimeAndBuildIntent(activity: Activity, private fun checkTimeAndBuildIntent(activity: Activity,
group: Group?, group: Group?,
searchInfo: SearchInfo?,
readOnly: Boolean, readOnly: Boolean,
intentBuildLauncher: (Intent) -> Unit) { intentBuildLauncher: (Intent) -> Unit) {
if (TimeoutHelper.checkTimeAndLockIfTimeout(activity)) { if (TimeoutHelper.checkTimeAndLockIfTimeout(activity)) {
buildIntent(activity, group, searchInfo, readOnly, intentBuildLauncher) buildIntent(activity, group, readOnly, intentBuildLauncher)
} }
} }
private fun checkTimeAndBuildIntent(context: Context, private fun checkTimeAndBuildIntent(context: Context,
group: Group?, group: Group?,
searchInfo: SearchInfo?,
readOnly: Boolean, readOnly: Boolean,
intentBuildLauncher: (Intent) -> Unit) { intentBuildLauncher: (Intent) -> Unit) {
if (TimeoutHelper.checkTime(context)) { 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, fun launch(context: Context,
autoSearch: Boolean = false,
searchInfo: SearchInfo? = null,
readOnly: Boolean = PreferencesUtil.enableReadOnlyDatabase(context)) { 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) context.startActivity(intent)
} }
} }
@@ -1020,11 +1074,13 @@ class GroupActivity : LockingActivity(),
* Keyboard Launch * Keyboard Launch
* ------------------------- * -------------------------
*/ */
// TODO implement pre search to directly open the direct group #280 fun launchForEntrySelectionResult(context: Context,
fun launchForKeyboardSelection(context: Context, autoSearch: Boolean = false,
readOnly: Boolean = PreferencesUtil.enableReadOnlyDatabase(context)) { searchInfo: SearchInfo? = null,
checkTimeAndBuildIntent(context, null, null, readOnly) { intent -> readOnly: Boolean = PreferencesUtil.enableReadOnlyDatabase(context)) {
EntrySelectionHelper.startActivityForEntrySelection(context, intent) 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) @RequiresApi(api = Build.VERSION_CODES.O)
fun launchForAutofillResult(activity: Activity, fun launchForAutofillResult(activity: Activity,
assistStructure: AssistStructure, assistStructure: AssistStructure,
autoSearch: Boolean = false,
searchInfo: SearchInfo? = null, searchInfo: SearchInfo? = null,
readOnly: Boolean = PreferencesUtil.enableReadOnlyDatabase(activity)) { 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) 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. * This file is part of KeePassDX.
* *
@@ -17,24 +17,31 @@
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>. * 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 android.os.Bundle
import androidx.appcompat.app.AppCompatActivity 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.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?) { override fun onCreate(savedInstanceState: Bundle?) {
if (Database.getInstance().loaded && TimeoutHelper.checkTime(this)) SearchHelper.checkAutoSearchInfo(this,
GroupActivity.launchForKeyboardSelection(this) Database.getInstance(),
else { null,
// Pass extra to get entry {},
FileDatabaseSelectActivity.launchForKeyboardSelection(this) {
} GroupActivity.launchForEntrySelectionResult(this)
},
{
// Pass extra to get entry
FileDatabaseSelectActivity.launchForEntrySelectionResult(this)
}
)
finish() finish()
super.onCreate(savedInstanceState) 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.R
import com.kunzisoft.keepass.activities.dialogs.DuplicateUuidDialog import com.kunzisoft.keepass.activities.dialogs.DuplicateUuidDialog
import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper 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.OpenFileHelper
import com.kunzisoft.keepass.activities.helpers.ReadOnlyHelper import com.kunzisoft.keepass.activities.helpers.ReadOnlyHelper
import com.kunzisoft.keepass.activities.lock.LockingActivity 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.CipherDatabaseEntity
import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction
import com.kunzisoft.keepass.autofill.AutofillHelper 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.biometric.AdvancedUnlockedManager
import com.kunzisoft.keepass.database.action.ProgressDialogThread import com.kunzisoft.keepass.database.action.ProgressDialogThread
import com.kunzisoft.keepass.database.element.Database import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.exception.DuplicateUuidDatabaseException import com.kunzisoft.keepass.database.exception.DuplicateUuidDatabaseException
import com.kunzisoft.keepass.database.search.SearchHelper
import com.kunzisoft.keepass.education.PasswordActivityEducation import com.kunzisoft.keepass.education.PasswordActivityEducation
import com.kunzisoft.keepass.model.SearchInfo import com.kunzisoft.keepass.model.SearchInfo
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_LOAD_TASK 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 kotlinx.android.synthetic.main.activity_password.*
import java.io.FileNotFoundException import java.io.FileNotFoundException
open class PasswordActivity : StylishActivity() { open class PasswordActivity : SpecialModeActivity() {
// Views // Views
private var toolbar: Toolbar? = null private var toolbar: Toolbar? = null
private var containerView: View? = null
private var filenameView: TextView? = null private var filenameView: TextView? = null
private var passwordView: EditText? = null private var passwordView: EditText? = null
private var keyFileSelectionView: KeyFileSelectionView? = null private var keyFileSelectionView: KeyFileSelectionView? = null
@@ -110,6 +110,7 @@ open class PasswordActivity : StylishActivity() {
private var mProgressDialogThread: ProgressDialogThread? = null private var mProgressDialogThread: ProgressDialogThread? = null
private var advancedUnlockedManager: AdvancedUnlockedManager? = null private var advancedUnlockedManager: AdvancedUnlockedManager? = null
private var mAllowAutoOpenBiometricPrompt: Boolean = true
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@@ -122,7 +123,6 @@ open class PasswordActivity : StylishActivity() {
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true) supportActionBar?.setDisplayShowHomeEnabled(true)
containerView = findViewById(R.id.container)
confirmButtonView = findViewById(R.id.activity_password_open_button) confirmButtonView = findViewById(R.id.activity_password_open_button)
filenameView = findViewById(R.id.filename) filenameView = findViewById(R.id.filename)
passwordView = findViewById(R.id.password) passwordView = findViewById(R.id.password)
@@ -166,6 +166,10 @@ open class PasswordActivity : StylishActivity() {
mDatabaseKeyFileUri = UriUtil.parse(savedInstanceState.getString(KEY_KEYFILE)) 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 { mProgressDialogThread = ProgressDialogThread(this).apply {
onActionFinish = { actionTask, result -> onActionFinish = { actionTask, result ->
when (actionTask) { when (actionTask) {
@@ -255,21 +259,52 @@ open class PasswordActivity : StylishActivity() {
} }
private fun launchGroupActivity() { private fun launchGroupActivity() {
val searchInfo: SearchInfo? = intent.getParcelableExtra(KEY_SEARCH_INFO)
EntrySelectionHelper.doEntrySelectionAction(intent, EntrySelectionHelper.doEntrySelectionAction(intent,
{ {
GroupActivity.launch(this@PasswordActivity, GroupActivity.launch(this@PasswordActivity,
true,
searchInfo,
readOnly) readOnly)
// Finish activity if no search info
if (searchInfo != null) {
finish()
}
}, },
{ {
GroupActivity.launchForKeyboardSelection(this@PasswordActivity, SearchHelper.checkAutoSearchInfo(this,
readOnly) 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 // Do not keep history
finish() finish()
}, },
{ assistStructure -> { assistStructure ->
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val searchInfo: SearchInfo? = intent.getParcelableExtra(KEY_SEARCH_INFO) SearchHelper.checkAutoSearchInfo(this,
AutofillHelper.checkAutoSearchInfo(this,
Database.getInstance(), Database.getInstance(),
searchInfo, searchInfo,
{ items -> { items ->
@@ -278,10 +313,11 @@ open class PasswordActivity : StylishActivity() {
finish() finish()
}, },
{ {
// Here no search info found // Here no search info found, disable auto search
GroupActivity.launchForAutofillResult(this@PasswordActivity, GroupActivity.launchForAutofillResult(this@PasswordActivity,
assistStructure, assistStructure,
null, false,
searchInfo,
readOnly) readOnly)
}, },
{ {
@@ -304,35 +340,31 @@ open class PasswordActivity : StylishActivity() {
} }
override fun onResume() { 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() 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) { // Don't allow auto open prompt if lock become when UI visible
outState.putBoolean(KEY_PERMISSION_ASKED, mPermissionAsked) mAllowAutoOpenBiometricPrompt = if (LockingActivity.LOCKING_ACTIVITY_UI_VISIBLE_DURING_LOCK == true)
mDatabaseKeyFileUri?.let { false
outState.putString(KEY_KEYFILE, it.toString()) else
mAllowAutoOpenBiometricPrompt
initUriFromIntent()
checkPermission()
} }
ReadOnlyHelper.onSaveInstanceState(outState, readOnly)
super.onSaveInstanceState(outState)
} }
private fun initUriFromIntent() { private fun initUriFromIntent() {
@@ -438,6 +470,7 @@ open class PasswordActivity : StylishActivity() {
} }
}) })
} }
advancedUnlockedManager?.isBiometricPromptAutoOpenEnable = mAllowAutoOpenBiometricPrompt
advancedUnlockedManager?.checkBiometricAvailability() advancedUnlockedManager?.checkBiometricAvailability()
biometricInitialize = true biometricInitialize = true
} else { } else {
@@ -499,14 +532,26 @@ open class PasswordActivity : StylishActivity() {
override fun onPause() { override fun onPause() {
mProgressDialogThread?.unregisterProgressTask() 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() super.onPause()
} }
override fun onDestroy() { override fun onSaveInstanceState(outState: Bundle) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { outState.putBoolean(KEY_PERMISSION_ASKED, mPermissionAsked)
advancedUnlockedManager?.destroy() 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) { private fun verifyCheckboxesAndLoadDatabase(cipherDatabaseEntity: CipherDatabaseEntity? = null) {
@@ -580,14 +625,15 @@ open class PasswordActivity : StylishActivity() {
val inflater = menuInflater val inflater = menuInflater
// Read menu // Read menu
inflater.inflate(R.menu.open_file, menu) inflater.inflate(R.menu.open_file, menu)
if (mSelectionMode || mForceReadOnly) {
if (mForceReadOnly) {
menu.removeItem(R.id.menu_open_file_read_mode_key) menu.removeItem(R.id.menu_open_file_read_mode_key)
} else { } else {
changeOpenFileReadIcon(menu.findItem(R.id.menu_open_file_read_mode_key)) 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) { if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// biometric menu // biometric menu
@@ -715,6 +761,8 @@ open class PasswordActivity : StylishActivity() {
data: Intent?) { data: Intent?) {
super.onActivityResult(requestCode, resultCode, data) super.onActivityResult(requestCode, resultCode, data)
mAllowAutoOpenBiometricPrompt = false
// To get entry in result // To get entry in result
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
AutofillHelper.onActivityResultSetResultAndFinish(this, requestCode, resultCode, data) AutofillHelper.onActivityResultSetResultAndFinish(this, requestCode, resultCode, data)
@@ -733,10 +781,13 @@ open class PasswordActivity : StylishActivity() {
if (!keyFileResult) { if (!keyFileResult) {
// this block if not a key file response // this block if not a key file response
when (resultCode) { when (resultCode) {
LockingActivity.RESULT_EXIT_LOCK, Activity.RESULT_CANCELED -> { LockingActivity.RESULT_EXIT_LOCK -> {
clearCredentialsViews() clearCredentialsViews()
Database.getInstance().closeAndClear(applicationContext.filesDir) 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 KEY_PERMISSION_ASKED = "KEY_PERMISSION_ASKED"
private const val WRITE_EXTERNAL_STORAGE_REQUEST = 647 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?, private fun buildAndLaunchIntent(activity: Activity, databaseFile: Uri, keyFile: Uri?,
intentBuildLauncher: (Intent) -> Unit) { intentBuildLauncher: (Intent) -> Unit) {
val intent = Intent(activity, PasswordActivity::class.java) val intent = Intent(activity, PasswordActivity::class.java)
@@ -773,8 +826,12 @@ open class PasswordActivity : StylishActivity() {
fun launch( fun launch(
activity: Activity, activity: Activity,
databaseFile: Uri, databaseFile: Uri,
keyFile: Uri?) { keyFile: Uri?,
searchInfo: SearchInfo?) {
buildAndLaunchIntent(activity, databaseFile, keyFile) { intent -> buildAndLaunchIntent(activity, databaseFile, keyFile) { intent ->
searchInfo?.let {
intent.putExtra(KEY_SEARCH_INFO, it)
}
activity.startActivity(intent) activity.startActivity(intent)
} }
} }
@@ -789,9 +846,13 @@ open class PasswordActivity : StylishActivity() {
fun launchForKeyboardResult( fun launchForKeyboardResult(
activity: Activity, activity: Activity,
databaseFile: Uri, databaseFile: Uri,
keyFile: Uri?) { keyFile: Uri?,
searchInfo: SearchInfo?) {
buildAndLaunchIntent(activity, databaseFile, keyFile) { intent -> buildAndLaunchIntent(activity, databaseFile, keyFile) { intent ->
EntrySelectionHelper.startActivityForEntrySelection(activity, intent) EntrySelectionHelper.startActivityForEntrySelectionResult(
activity,
intent,
searchInfo)
} }
} }
@@ -818,7 +879,7 @@ open class PasswordActivity : StylishActivity() {
searchInfo) searchInfo)
} }
} else { } 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.GridView
import android.widget.ImageView import android.widget.ImageView
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.widget.ImageViewCompat import androidx.core.widget.ImageViewCompat
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.stylish.StylishActivity
import com.kunzisoft.keepass.database.element.icon.IconImageStandard import com.kunzisoft.keepass.database.element.icon.IconImageStandard
import com.kunzisoft.keepass.icons.IconPack import com.kunzisoft.keepass.icons.IconPack
import com.kunzisoft.keepass.icons.IconPackChooser import com.kunzisoft.keepass.icons.IconPackChooser
@@ -132,7 +132,7 @@ class IconPickerDialogFragment : DialogFragment() {
return bundle.getParcelable(KEY_ICON_STANDARD) return bundle.getParcelable(KEY_ICON_STANDARD)
} }
fun launch(activity: StylishActivity) { fun launch(activity: AppCompatActivity) {
// Create an instance of the dialog fragment and show it // Create an instance of the dialog fragment and show it
val dialog = IconPickerDialogFragment() val dialog = IconPickerDialogFragment()
dialog.show(activity.supportFragmentManager, "IconPickerDialogFragment") dialog.show(activity.supportFragmentManager, "IconPickerDialogFragment")

View File

@@ -24,15 +24,22 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Build import android.os.Build
import com.kunzisoft.keepass.autofill.AutofillHelper import com.kunzisoft.keepass.autofill.AutofillHelper
import com.kunzisoft.keepass.model.SearchInfo
object EntrySelectionHelper { object EntrySelectionHelper {
private const val EXTRA_ENTRY_SELECTION_MODE = "com.kunzisoft.keepass.extra.ENTRY_SELECTION_MODE" private const val EXTRA_ENTRY_SELECTION_MODE = "com.kunzisoft.keepass.extra.ENTRY_SELECTION_MODE"
private const val DEFAULT_ENTRY_SELECTION_MODE = false 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) addEntrySelectionModeExtraInIntent(intent)
// only to avoid visible flickering when redirecting searchInfo?.let {
intent.putExtra(KEY_SEARCH_INFO, it)
}
context.startActivity(intent) context.startActivity(intent)
} }

View File

@@ -24,26 +24,15 @@ import android.os.Bundle
import android.util.Log import android.util.Log
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper
import com.kunzisoft.keepass.activities.helpers.ReadOnlyHelper 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.action.ProgressDialogThread
import com.kunzisoft.keepass.database.element.Database import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.settings.PreferencesUtil import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.timeout.TimeoutHelper import com.kunzisoft.keepass.timeout.TimeoutHelper
import com.kunzisoft.keepass.utils.* import com.kunzisoft.keepass.utils.*
abstract class LockingActivity : StylishActivity() { abstract class LockingActivity : SpecialModeActivity() {
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
}
protected var mTimeoutEnable: Boolean = true protected var mTimeoutEnable: Boolean = true
@@ -51,11 +40,14 @@ abstract class LockingActivity : StylishActivity() {
private var mExitLock: Boolean = false private var mExitLock: Boolean = false
// Force readOnly if Entry Selection mode // Force readOnly if Entry Selection mode
protected var mReadOnly: Boolean = false protected var mReadOnly: Boolean
get() { 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 protected var mAutoSaveEnable: Boolean = true
var mProgressDialogThread: ProgressDialogThread? = null var mProgressDialogThread: ProgressDialogThread? = null
@@ -75,6 +67,8 @@ abstract class LockingActivity : StylishActivity() {
if (mTimeoutEnable) { if (mTimeoutEnable) {
mLockReceiver = LockReceiver { mLockReceiver = LockReceiver {
closeDatabase() closeDatabase()
if (LOCKING_ACTIVITY_UI_VISIBLE_DURING_LOCK == null)
LOCKING_ACTIVITY_UI_VISIBLE_DURING_LOCK = LOCKING_ACTIVITY_UI_VISIBLE
// Add onActivityForResult response // Add onActivityForResult response
setResult(RESULT_EXIT_LOCK) setResult(RESULT_EXIT_LOCK)
finish() finish()
@@ -83,7 +77,6 @@ abstract class LockingActivity : StylishActivity() {
} }
mExitLock = false mExitLock = false
mReadOnly = ReadOnlyHelper.retrieveReadOnlyFromInstanceStateOrIntent(savedInstanceState, intent)
mProgressDialogThread = ProgressDialogThread(this) mProgressDialogThread = ProgressDialogThread(this)
} }
@@ -104,7 +97,7 @@ abstract class LockingActivity : StylishActivity() {
mProgressDialogThread?.registerProgressTask() mProgressDialogThread?.registerProgressTask()
// To refresh when back to normal workflow from selection workflow // To refresh when back to normal workflow from selection workflow
mSelectionMode = EntrySelectionHelper.retrieveEntrySelectionModeFromIntent(intent) mReadOnlyToSave = ReadOnlyHelper.retrieveReadOnlyFromIntent(intent)
mAutoSaveEnable = PreferencesUtil.isAutoSaveDatabaseEnabled(this) mAutoSaveEnable = PreferencesUtil.isAutoSaveDatabaseEnabled(this)
invalidateOptionsMenu() invalidateOptionsMenu()
@@ -124,15 +117,18 @@ abstract class LockingActivity : StylishActivity() {
if (!mExitLock) if (!mExitLock)
TimeoutHelper.recordTime(this) TimeoutHelper.recordTime(this)
} }
LOCKING_ACTIVITY_UI_VISIBLE = true
} }
override fun onSaveInstanceState(outState: Bundle) { override fun onSaveInstanceState(outState: Bundle) {
ReadOnlyHelper.onSaveInstanceState(outState, mReadOnly)
outState.putBoolean(TIMEOUT_ENABLE_KEY, mTimeoutEnable) outState.putBoolean(TIMEOUT_ENABLE_KEY, mTimeoutEnable)
super.onSaveInstanceState(outState) super.onSaveInstanceState(outState)
} }
override fun onPause() { override fun onPause() {
LOCKING_ACTIVITY_UI_VISIBLE = false
mProgressDialogThread?.unregisterProgressTask() mProgressDialogThread?.unregisterProgressTask()
super.onPause() super.onPause()
@@ -180,4 +176,17 @@ abstract class LockingActivity : StylishActivity() {
super.onBackPressed() 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.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import androidx.annotation.ColorInt
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.SortedList import androidx.recyclerview.widget.SortedList
import androidx.recyclerview.widget.SortedListAdapterCallback import androidx.recyclerview.widget.SortedListAdapterCallback
@@ -73,7 +74,11 @@ class NodeAdapter (private val context: Context)
private val mDatabase: Database private val mDatabase: Database
@ColorInt
private val contentSelectionColor: Int
@ColorInt
private val iconGroupColor: Int private val iconGroupColor: Int
@ColorInt
private val iconEntryColor: Int private val iconEntryColor: Int
/** /**
@@ -97,6 +102,10 @@ class NodeAdapter (private val context: Context)
// Database // Database
this.mDatabase = Database.getInstance() 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 // Retrieve the color to tint the icon
val taTextColorPrimary = context.theme.obtainStyledAttributes(intArrayOf(android.R.attr.textColorPrimary)) val taTextColorPrimary = context.theme.obtainStyledAttributes(intArrayOf(android.R.attr.textColorPrimary))
this.iconGroupColor = taTextColorPrimary.getColor(0, Color.BLACK) this.iconGroupColor = taTextColorPrimary.getColor(0, Color.BLACK)
@@ -280,11 +289,18 @@ class NodeAdapter (private val context: Context)
override fun onBindViewHolder(holder: NodeViewHolder, position: Int) { override fun onBindViewHolder(holder: NodeViewHolder, position: Int) {
val subNode = nodeSortedList.get(position) val subNode = nodeSortedList.get(position)
// Node selection
holder.container.isSelected = actionNodesList.contains(subNode)
// Assign image // Assign image
val iconColor = when (subNode.type) { val iconColor = if (holder.container.isSelected)
contentSelectionColor
else when (subNode.type) {
Type.GROUP -> iconGroupColor Type.GROUP -> iconGroupColor
Type.ENTRY -> iconEntryColor Type.ENTRY -> iconEntryColor
} }
holder.imageIdentifier?.setColorFilter(iconColor)
holder.icon.apply { holder.icon.apply {
assignDatabaseIcon(mDatabase.drawFactory, subNode.icon, iconColor) assignDatabaseIcon(mDatabase.drawFactory, subNode.icon, iconColor)
// Relative size of the icon // Relative size of the icon
@@ -347,8 +363,6 @@ class NodeAdapter (private val context: Context)
holder.container.setOnLongClickListener { holder.container.setOnLongClickListener {
nodeClickCallback?.onNodeLongClick(subNode) ?: false nodeClickCallback?.onNodeLongClick(subNode) ?: false
} }
holder.container.isSelected = actionNodesList.contains(subNode)
} }
override fun getItemCount(): Int { override fun getItemCount(): Int {
@@ -372,6 +386,7 @@ class NodeAdapter (private val context: Context)
class NodeViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { class NodeViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var container: View = itemView.findViewById(R.id.node_container) 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 icon: ImageView = itemView.findViewById(R.id.node_icon)
var text: TextView = itemView.findViewById(R.id.node_text) var text: TextView = itemView.findViewById(R.id.node_text)
var subText: TextView = itemView.findViewById(R.id.node_subtext) 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 androidx.core.content.ContextCompat
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper 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.Database
import com.kunzisoft.keepass.database.element.icon.IconImage 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.icons.assignDatabaseIcon
import com.kunzisoft.keepass.model.EntryInfo import com.kunzisoft.keepass.model.EntryInfo
import com.kunzisoft.keepass.model.SearchInfo import com.kunzisoft.keepass.model.SearchInfo
import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.timeout.TimeoutHelper
@RequiresApi(api = Build.VERSION_CODES.O) @RequiresApi(api = Build.VERSION_CODES.O)
@@ -50,7 +48,6 @@ object AutofillHelper {
private const val AUTOFILL_RESPONSE_REQUEST_CODE = 8165 private const val AUTOFILL_RESPONSE_REQUEST_CODE = 8165
private const val ASSIST_STRUCTURE = AutofillManager.EXTRA_ASSIST_STRUCTURE private const val ASSIST_STRUCTURE = AutofillManager.EXTRA_ASSIST_STRUCTURE
const val KEY_SEARCH_INFO = "KEY_SEARCH_INFO"
fun retrieveAssistStructure(intent: Intent?): AssistStructure? { fun retrieveAssistStructure(intent: Intent?): AssistStructure? {
intent?.let { intent?.let {
@@ -122,60 +119,34 @@ object AutofillHelper {
* Build the Autofill response for many entry * Build the Autofill response for many entry
*/ */
fun buildResponse(activity: Activity, entriesInfo: List<EntryInfo>) { fun buildResponse(activity: Activity, entriesInfo: List<EntryInfo>) {
var setResultOk = false if (entriesInfo.isEmpty()) {
activity.intent?.extras?.let { extras -> activity.setResult(Activity.RESULT_CANCELED)
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()
}
} else { } 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 android.widget.RemoteViews
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.AutofillLauncherActivity
import com.kunzisoft.keepass.database.element.Database import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.search.SearchHelper
import com.kunzisoft.keepass.model.SearchInfo import com.kunzisoft.keepass.model.SearchInfo
import com.kunzisoft.keepass.settings.PreferencesUtil
@RequiresApi(api = Build.VERSION_CODES.O) @RequiresApi(api = Build.VERSION_CODES.O)
class KeeAutofillService : AutofillService() { 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, override fun onFillRequest(request: FillRequest,
cancellationSignal: CancellationSignal, cancellationSignal: CancellationSignal,
callback: FillCallback) { callback: FillCallback) {
@@ -43,32 +56,36 @@ class KeeAutofillService : AutofillService() {
// Check user's settings for authenticating Responses and Datasets. // Check user's settings for authenticating Responses and Datasets.
StructureParser(latestStructure).parse()?.let { parseResult -> StructureParser(latestStructure).parse()?.let { parseResult ->
val searchInfo = SearchInfo().apply { // Build search info only if applicationId or webDomain are not blocked
applicationId = parseResult.applicationId if (searchAllowedFor(parseResult.applicationId, applicationIdBlocklist)
webDomain = parseResult.domain && searchAllowedFor(parseResult.domain, webDomainBlocklist)) {
} val searchInfo = SearchInfo().apply {
applicationId = parseResult.applicationId
webDomain = parseResult.domain
}
AutofillHelper.checkAutoSearchInfo(this, SearchHelper.checkAutoSearchInfo(this,
Database.getInstance(), Database.getInstance(),
searchInfo, searchInfo,
{ items -> { items ->
val responseBuilder = FillResponse.Builder() val responseBuilder = FillResponse.Builder()
AutofillHelper.addHeader(responseBuilder, packageName, AutofillHelper.addHeader(responseBuilder, packageName,
parseResult.domain, parseResult.applicationId) parseResult.domain, parseResult.applicationId)
items.forEach { items.forEach {
responseBuilder.addDataset(AutofillHelper.buildDataset(this, it, parseResult)) 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 { companion object {
private val TAG = KeeAutofillService::class.java.name 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 { when {
it.equals(View.AUTOFILL_HINT_USERNAME, true) it.equals(View.AUTOFILL_HINT_USERNAME, true)
|| it.equals(View.AUTOFILL_HINT_EMAIL_ADDRESS, true) || it.equals(View.AUTOFILL_HINT_EMAIL_ADDRESS, true)
|| it.equals(View.AUTOFILL_HINT_PHONE, true)
|| it.equals("email", 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 result?.usernameId = autofillId
Log.d(TAG, "Autofill username hint") Log.d(TAG, "Autofill username hint")
} }
@@ -112,7 +115,7 @@ internal class StructureParser(private val structure: AssistStructure) {
|| it.contains("password", true) -> { || it.contains("password", true) -> {
result?.passwordId = autofillId result?.passwordId = autofillId
Log.d(TAG, "Autofill password hint") Log.d(TAG, "Autofill password hint")
// Username not needed in this specific case // Username not needed in this case
usernameNeeded = false usernameNeeded = false
return true return true
} }
@@ -160,42 +163,78 @@ internal class StructureParser(private val structure: AssistStructure) {
return false 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 { private fun parseNodeByAndroidInput(node: AssistStructure.ViewNode): Boolean {
val autofillId = node.autofillId val autofillId = node.autofillId
val inputType = node.inputType val inputType = node.inputType
if (inputType and InputType.TYPE_CLASS_TEXT != 0) { when (inputType and InputType.TYPE_MASK_CLASS) {
when { InputType.TYPE_CLASS_TEXT -> {
inputType and InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS != 0 -> { when {
result?.usernameId = autofillId inputIsVariationType(inputType,
Log.d(TAG, "Autofill username android type: $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.TYPE_CLASS_NUMBER -> {
inputType and InputType.TYPE_TEXT_VARIATION_PERSON_NAME != 0 -> { when {
usernameCandidate = autofillId inputIsVariationType(inputType,
Log.d(TAG, "Autofill username candidate android type: $inputType") InputType.TYPE_NUMBER_VARIATION_NORMAL) -> {
} usernameCandidate = autofillId
inputType and InputType.TYPE_TEXT_VARIATION_PASSWORD != 0 || Log.d(TAG, "Autofill usernale candidate android number type: ${showHexInputType(inputType)}")
inputType and InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD != 0 || }
inputType and InputType.TYPE_NUMBER_VARIATION_PASSWORD != 0 -> { inputIsVariationType(inputType,
result?.passwordId = autofillId InputType.TYPE_NUMBER_VARIATION_PASSWORD) -> {
Log.d(TAG, "Autofill password android type: $inputType") result?.passwordId = autofillId
return true Log.d(TAG, "Autofill password android number type: ${showHexInputType(inputType)}")
} usernameNeeded = false
inputType and InputType.TYPE_TEXT_VARIATION_EMAIL_SUBJECT != 0 || return true
inputType and InputType.TYPE_TEXT_VARIATION_FILTER != 0 || }
inputType and InputType.TYPE_TEXT_VARIATION_LONG_MESSAGE != 0 || else -> {
inputType and InputType.TYPE_TEXT_VARIATION_PHONETIC != 0 || Log.d(TAG, "Autofill unknown android number type: ${showHexInputType(inputType)}")
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
} }
} }
} }

View File

@@ -52,7 +52,11 @@ class AdvancedUnlockedManager(var context: FragmentActivity,
private var biometricUnlockDatabaseHelper: BiometricUnlockDatabaseHelper? = null private var biometricUnlockDatabaseHelper: BiometricUnlockDatabaseHelper? = null
private var biometricMode: Mode = Mode.UNAVAILABLE 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) private var cipherDatabaseAction = CipherDatabaseAction.getInstance(context.applicationContext)
@@ -272,6 +276,8 @@ class AdvancedUnlockedManager(var context: FragmentActivity,
} }
fun destroy() { fun destroy() {
// Close the biometric prompt
biometricUnlockDatabaseHelper?.closeBiometricPrompt()
// Restore the checked listener // Restore the checked listener
checkboxPasswordView?.setOnCheckedChangeListener(onCheckedPasswordChangeListener) checkboxPasswordView?.setOnCheckedChangeListener(onCheckedPasswordChangeListener)
} }

View File

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

View File

@@ -41,17 +41,6 @@ object CipherFactory {
Security.addProvider(BouncyCastleProvider()) 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 { fun deviceBlacklisted(): Boolean {
if (!blacklistInit) { if (!blacklistInit) {
blacklistInit = true blacklistInit = true
@@ -65,6 +54,16 @@ object CipherFactory {
return transformation == "AES/CBC/PKCS5Padding" 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 * Generate appropriate cipher based on KeePass 2.x UUID's
*/ */

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -19,17 +19,57 @@
*/ */
package com.kunzisoft.keepass.database.search package com.kunzisoft.keepass.database.search
import android.content.Context
import com.kunzisoft.keepass.database.action.node.NodeHandler import com.kunzisoft.keepass.database.action.node.NodeHandler
import com.kunzisoft.keepass.database.element.Database import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.element.Entry import com.kunzisoft.keepass.database.element.Entry
import com.kunzisoft.keepass.database.element.Group import com.kunzisoft.keepass.database.element.Group
import com.kunzisoft.keepass.database.search.iterator.EntrySearchStringIteratorKDB import com.kunzisoft.keepass.database.search.iterator.EntrySearchStringIteratorKDB
import com.kunzisoft.keepass.database.search.iterator.EntrySearchStringIteratorKDBX 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) { class SearchHelper(private val isOmitBackup: Boolean) {
companion object { companion object {
const val MAX_SEARCH_ENTRY = 6 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 private var incrementEntry = 0

View File

@@ -36,6 +36,7 @@ import android.widget.FrameLayout
import android.widget.PopupWindow import android.widget.PopupWindow
import android.widget.TextView import android.widget.TextView
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.MagikeyboardLauncherActivity
import com.kunzisoft.keepass.adapters.FieldsAdapter import com.kunzisoft.keepass.adapters.FieldsAdapter
import com.kunzisoft.keepass.database.element.Database import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.model.EntryInfo import com.kunzisoft.keepass.model.EntryInfo
@@ -211,7 +212,7 @@ class MagikIME : InputMethodService(), KeyboardView.OnKeyboardActionListener {
// Stop current service and reinit entry // Stop current service and reinit entry
stopService(Intent(this, KeyboardEntryNotificationService::class.java)) stopService(Intent(this, KeyboardEntryNotificationService::class.java))
removeEntryInfo() 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 // New task needed because don't launch from an Activity context
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
startActivity(intent) startActivity(intent)
@@ -248,7 +249,9 @@ class MagikIME : InputMethodService(), KeyboardView.OnKeyboardActionListener {
} }
popupCustomKeys?.showAtLocation(keyboardView, Gravity.END or Gravity.TOP, 0, 0) 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) 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)) 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 // Add a new entry
entryInfoKey = entry entryInfoKey = entry
// Launch notification if allowed // Launch notification if allowed
KeyboardEntryNotificationService.launchNotificationIfAllowed(context, entry) KeyboardEntryNotificationService.launchNotificationIfAllowed(context, entry, toast)
} }
} }
} }

View File

@@ -1,12 +1,31 @@
package com.kunzisoft.keepass.model package com.kunzisoft.keepass.model
import android.content.Context
import android.content.res.Resources
import android.os.Parcel import android.os.Parcel
import android.os.Parcelable 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 var applicationId: String? = null
set(value) {
field = when {
value == null -> null
Regex(APPLICATION_ID_REGEX).matches(value) -> value
else -> null
}
}
var webDomain: String? = null var webDomain: String? = null
set(value) {
field = when {
value == null -> null
Regex(WEB_DOMAIN_REGEX).matches(value) -> value
else -> null
}
}
constructor() constructor()
@@ -26,7 +45,40 @@ class SearchInfo : Parcelable {
parcel.writeString(webDomain ?: "") 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 { 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 @JvmField
val CREATOR: Parcelable.Creator<SearchInfo> = object : Parcelable.Creator<SearchInfo> { val CREATOR: Parcelable.Creator<SearchInfo> = object : Parcelable.Creator<SearchInfo> {
@@ -39,4 +91,15 @@ 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 { 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) { val downloadFileUri: Uri? = if (intent?.hasExtra(DOWNLOAD_FILE_URI_KEY) == true) {
intent.getParcelableExtra(DOWNLOAD_FILE_URI_KEY) 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 { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
super.onStartCommand(intent, flags, startId)
// Get entry info from intent // Get entry info from intent
mEntryInfo = intent?.getParcelableExtra(EXTRA_ENTRY_INFO) 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 { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
super.onStartCommand(intent, flags, startId)
when(intent?.action) { when(intent?.action) {
ACTION_CLOSE_DATABASE -> { 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_START_TASK_ACTION
import com.kunzisoft.keepass.utils.DATABASE_STOP_TASK_ACTION import com.kunzisoft.keepass.utils.DATABASE_STOP_TASK_ACTION
import java.util.* import java.util.*
import java.util.concurrent.atomic.AtomicBoolean
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdater { class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdater {
@@ -61,8 +60,6 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
fun addActionTaskListener(actionTaskListener: ActionTaskListener) { fun addActionTaskListener(actionTaskListener: ActionTaskListener) {
mActionTaskListeners.add(actionTaskListener) mActionTaskListeners.add(actionTaskListener)
// To prevent task dialog to be unbound before the display
actionRunnableAsyncTask?.allowFinishTask?.set(true)
} }
fun removeActionTaskListener(actionTaskListener: ActionTaskListener) { fun removeActionTaskListener(actionTaskListener: ActionTaskListener) {
@@ -78,7 +75,7 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
fun checkAction() { fun checkAction() {
mActionTaskListeners.forEach { actionTaskListener -> 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 { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
super.onStartCommand(intent, flags, startId)
if (intent == null) return START_REDELIVER_INTENT if (intent == null) return START_REDELIVER_INTENT
@@ -571,8 +569,6 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
private val onPostExecute: (result: ActionRunnable.Result) -> Unit) private val onPostExecute: (result: ActionRunnable.Result) -> Unit)
: AsyncTask<((ProgressTaskUpdater?) -> ActionRunnable), Void, ActionRunnable.Result>() { : AsyncTask<((ProgressTaskUpdater?) -> ActionRunnable), Void, ActionRunnable.Result>() {
var allowFinishTask = AtomicBoolean(false)
override fun onPreExecute() { override fun onPreExecute() {
super.onPreExecute() super.onPreExecute()
onPreExecute.invoke() onPreExecute.invoke()
@@ -586,10 +582,6 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
resultTask = result resultTask = result
} }
} }
// Additional wait if the dialog take time to show
while(!allowFinishTask.get()) {
Thread.sleep(250)
}
return resultTask return resultTask
} }

View File

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

View File

@@ -26,6 +26,7 @@ import com.kunzisoft.keepass.utils.unregisterLockReceiver
abstract class LockNotificationService : NotificationService() { abstract class LockNotificationService : NotificationService() {
private var onStart: Boolean = false
private var mLockReceiver: LockReceiver? = null private var mLockReceiver: LockReceiver? = null
protected open fun actionOnLock() { 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 // Register a lock receiver to stop notification service when lock on keyboard is performed
mLockReceiver = LockReceiver { mLockReceiver = LockReceiver {
if (onStart)
actionOnLock() actionOnLock()
} }
registerLockReceiver(mLockReceiver) 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?) { protected fun stopTask(task: Thread?) {
if (task != null && task.isAlive) if (task != null && task.isAlive)
task.interrupt() task.interrupt()

View File

@@ -23,9 +23,9 @@ import android.os.Bundle
import android.view.MenuItem import android.view.MenuItem
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import com.kunzisoft.keepass.R 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?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)

View File

@@ -20,9 +20,12 @@
package com.kunzisoft.keepass.settings package com.kunzisoft.keepass.settings
import android.os.Bundle import android.os.Bundle
import androidx.fragment.app.DialogFragment
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.settings.preferencedialogfragment.AutofillBlocklistAppIdPreferenceDialogFragmentCompat
import com.kunzisoft.keepass.settings.preferencedialogfragment.AutofillBlocklistWebDomainPreferenceDialogFragmentCompat
class AutofillSettingsFragment : PreferenceFragmentCompat() { class AutofillSettingsFragment : PreferenceFragmentCompat() {
@@ -30,4 +33,34 @@ class AutofillSettingsFragment : PreferenceFragmentCompat() {
// Load the preferences from an XML resource // Load the preferences from an XML resource
setPreferencesFromResource(R.xml.preferences_autofill, rootKey) 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 android.view.MenuItem
import com.kunzisoft.keepass.R 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?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)

View File

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

View File

@@ -20,8 +20,10 @@
package com.kunzisoft.keepass.settings package com.kunzisoft.keepass.settings
import android.content.Context import android.content.Context
import android.content.res.Resources
import android.net.Uri import android.net.Uri
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import com.kunzisoft.keepass.BuildConfig
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.element.SortNodeEnum import com.kunzisoft.keepass.database.element.SortNodeEnum
import com.kunzisoft.keepass.timeout.TimeoutHelper import com.kunzisoft.keepass.timeout.TimeoutHelper
@@ -97,6 +99,12 @@ object PreferencesUtil {
context.resources.getBoolean(R.bool.auto_focus_search_default)) 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 { fun showUsernamesListEntries(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context) val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.list_entries_show_username_key), 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)) 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 { fun isAutoGoActionEnable(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context) val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.keyboard_auto_go_action_key), 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), return prefs.getBoolean(context.getString(R.string.autofill_auto_search_key),
context.resources.getBoolean(R.bool.autofill_auto_search_default)) 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.View
import android.view.inputmethod.EditorInfo import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import android.widget.CompoundButton import android.widget.CompoundButton
import android.widget.EditText import android.widget.EditText
import android.widget.TextView import android.widget.TextView
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.core.content.ContextCompat
import androidx.preference.PreferenceDialogFragmentCompat import androidx.preference.PreferenceDialogFragmentCompat
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
@@ -34,6 +36,8 @@ abstract class InputPreferenceDialogFragmentCompat : PreferenceDialogFragmentCom
private var textExplanationView: TextView? = null private var textExplanationView: TextView? = null
private var switchElementView: CompoundButton? = null private var switchElementView: CompoundButton? = null
private var mOnInputTextEditorActionListener: TextView.OnEditorActionListener? = null
var inputText: String var inputText: String
get() = this.inputTextView?.text?.toString() ?: "" get() = this.inputTextView?.text?.toString() ?: ""
set(inputText) { 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? var explanationText: String?
get() = textExplanationView?.text?.toString() ?: "" get() = textExplanationView?.text?.toString() ?: ""
set(explanationText) { set(explanationText) {
@@ -63,16 +75,21 @@ abstract class InputPreferenceDialogFragmentCompat : PreferenceDialogFragmentCom
inputTextView = view.findViewById(R.id.input_text) inputTextView = view.findViewById(R.id.input_text)
inputTextView?.apply { inputTextView?.apply {
imeOptions = EditorInfo.IME_ACTION_DONE imeOptions = EditorInfo.IME_ACTION_DONE
setOnEditorActionListener { _, actionId, _ -> setOnEditorActionListener { v, actionId, event ->
when (actionId) { if (mOnInputTextEditorActionListener == null) {
EditorInfo.IME_ACTION_DONE -> { when (actionId) {
onDialogClosed(true) EditorInfo.IME_ACTION_DONE -> {
dialog?.dismiss() onDialogClosed(true)
true dialog?.dismiss()
} true
else -> { }
false else -> {
false
}
} }
} else {
mOnInputTextEditorActionListener?.onEditorAction(v, actionId, event)
?: false
} }
} }
} }
@@ -82,6 +99,20 @@ abstract class InputPreferenceDialogFragmentCompat : PreferenceDialogFragmentCom
switchElementView?.visibility = View.GONE 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) { fun setInoutText(@StringRes inputTextId: Int) {
inputText = getString(inputTextId) 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 * @param checkLock Check the time lock before launch settings in LockingActivity
*/ */
@JvmOverloads
fun onDefaultMenuOptionsItemSelected(activity: Activity, fun onDefaultMenuOptionsItemSelected(activity: Activity,
item: MenuItem, item: MenuItem,
readOnly: Boolean = READ_ONLY_DEFAULT, readOnly: Boolean = READ_ONLY_DEFAULT,

View File

@@ -86,6 +86,19 @@ object UriUtil {
null 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 { fun decode(uri: String?): String {
return Uri.decode(uri) ?: "" return Uri.decode(uri) ?: ""
} }

View File

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

View File

@@ -29,9 +29,9 @@ import android.widget.TextView
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
open class EntryCustomField @JvmOverloads constructor(context: Context, class EntryCustomField @JvmOverloads constructor(context: Context,
attrs: AttributeSet? = null, attrs: AttributeSet? = null,
defStyle: Int = 0) defStyle: Int = 0)
: LinearLayout(context, attrs, defStyle) { : LinearLayout(context, attrs, defStyle) {
private val labelView: TextView 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.google.android.material.snackbar.Snackbar
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.tasks.ActionRunnable import com.kunzisoft.keepass.tasks.ActionRunnable
import java.util.*
/** /**
* Replace font by monospace, must be called after seText() * 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) { fun Toolbar.expand(animate: Boolean = true) {
visibility = View.VISIBLE
val actionBarHeight = layoutParams.height val actionBarHeight = layoutParams.height
layoutParams.height = 0
val slideAnimator = ValueAnimator val slideAnimator = ValueAnimator
.ofInt(0, actionBarHeight) .ofInt(0, actionBarHeight)
if (animate) if (animate)
slideAnimator.duration = 300L slideAnimator.duration = 300L
slideAnimator.addUpdateListener { animation -> slideAnimator.addUpdateListener { animation ->
layoutParams.height = animation.animatedValue as Int layoutParams.height = animation.animatedValue as Int
if (layoutParams.height >= 1) {
visibility = View.VISIBLE
}
requestLayout() requestLayout()
} }
AnimatorSet().apply { 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 <corners
android:radius="0dp" /> android:radius="0dp" />
<padding <padding
android:left="0dp" android:left="8dp"
android:right="0dp" android:right="8dp"
android:top="12dp" android:top="12dp"
android:bottom="12dp"/> android:bottom="12dp"/>
<solid android:color="?attr/colorAccent"/> <solid android:color="?attr/colorAccent"/>

View File

@@ -5,8 +5,8 @@
<corners <corners
android:radius="0dp" /> android:radius="0dp" />
<padding <padding
android:left="0dp" android:left="8dp"
android:right="0dp" android:right="8dp"
android:top="12dp" android:top="12dp"
android:bottom="12dp"/> android:bottom="12dp"/>
<solid android:color="@color/orange_light"/> <solid android:color="@color/orange_light"/>
@@ -17,8 +17,8 @@
<corners <corners
android:radius="0dp" /> android:radius="0dp" />
<padding <padding
android:left="0dp" android:left="8dp"
android:right="0dp" android:right="8dp"
android:top="12dp" android:top="12dp"
android:bottom="12dp"/> android:bottom="12dp"/>
<solid android:color="@color/orange"/> <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" android:importantForAutofill="noExcludeDescendants"
tools:targetApi="o"> 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 <androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/activity_file_selection_coordinator_layout" android:id="@+id/activity_file_selection_coordinator_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"
android:background="@drawable/background_repeat" android:background="@drawable/background_repeat"
android:backgroundTint="?attr/colorPrimary" android:backgroundTint="?android:attr/textColor"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toBottomOf="@+id/special_mode_view"
app:layout_constraintBottom_toTopOf="@+id/file_selection_buttons_container"> app:layout_constraintBottom_toTopOf="@+id/file_selection_buttons_container">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
@@ -156,11 +165,18 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"> app:layout_constraintStart_toStartOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/database_buttons_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="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 <androidx.appcompat.widget.AppCompatButton
android:id="@+id/open_keyfile_button" android:id="@+id/open_keyfile_button"
@@ -191,11 +207,6 @@
android:paddingEnd="24dp" android:paddingEnd="24dp"
android:text="@string/create_keepass_file"/> android:text="@string/create_keepass_file"/>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_gravity="top"
android:background="?attr/colorPrimaryDark"/>
</FrameLayout> </FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -17,18 +17,28 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>. 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:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="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 <androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/group_coordinator" android:id="@+id/group_coordinator"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="0dp"
android:layout_above="@+id/toolbar_action"> app:layout_constraintTop_toBottomOf="@+id/special_mode_view"
app:layout_constraintBottom_toTopOf="@+id/toolbar_action">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar" android:id="@+id/app_bar"
@@ -124,15 +134,6 @@
android:orientation="vertical" android:orientation="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior" app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:layout_below="@+id/toolbar"> 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 <FrameLayout
android:id="@+id/nodes_list_fragment_container" android:id="@+id/nodes_list_fragment_container"
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -159,10 +160,10 @@
android:id="@+id/toolbar_action" android:id="@+id/toolbar_action"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="?attr/actionBarSize"
android:layout_alignParentBottom="true" app:layout_constraintBottom_toBottomOf="parent"
android:elevation="4dp" android:elevation="4dp"
android:theme="?attr/toolbarBottomAppearance" android:theme="?attr/actionToolbarAppearance"
android:background="?attr/colorAccent" android:background="?attr/colorAccent"
tools:targetApi="lollipop" /> tools:targetApi="lollipop" />
</RelativeLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -21,17 +21,24 @@
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/container"
android:importantForAutofill="noExcludeDescendants"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:targetApi="o"> 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 <androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/activity_password_coordinator_layout" android:id="@+id/activity_password_coordinator_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" 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"> app:layout_constraintBottom_toTopOf="@+id/activity_password_info_container">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
@@ -155,7 +162,8 @@
android:hint="@string/password" android:hint="@string/password"
android:inputType="textPassword" android:inputType="textPassword"
android:importantForAccessibility="no" android:importantForAccessibility="no"
android:importantForAutofill="no" android:importantForAutofill="yes"
android:autofillHints="password|"
android:imeOptions="actionDone" android:imeOptions="actionDone"
android:maxLines="1"/> android:maxLines="1"/>
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
@@ -213,7 +221,7 @@
android:paddingLeft="24dp" android:paddingLeft="24dp"
android:paddingEnd="24dp" android:paddingEnd="24dp"
android:paddingRight="24dp" android:paddingRight="24dp"
style="@style/KeepassDXStyle.TextAppearance.TinyText" style="@style/KeepassDXStyle.TextAppearance.Tiny"
android:text="@string/warning_database_link_revoked" android:text="@string/warning_database_link_revoked"
android:textColor="?attr/textColorInverse" android:textColor="?attr/textColorInverse"
android:background="?attr/colorAccent" android:background="?attr/colorAccent"

View File

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

View File

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

View File

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

View File

@@ -35,11 +35,10 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
android:background="?android:attr/selectableItemBackground" > android:background="?android:attr/selectableItemBackground" >
<androidx.appcompat.widget.AppCompatImageView <androidx.appcompat.widget.AppCompatImageView
android:id="@+id/group_arrow" android:id="@+id/node_image_identifier"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:src="@drawable/ic_arrow_right_white_24dp" android:src="@drawable/ic_arrow_right_white_24dp"
android:tint="?android:attr/textColorPrimary"
android:layout_marginLeft="4dp" android:layout_marginLeft="4dp"
android:layout_marginStart="4dp" android:layout_marginStart="4dp"
android:layout_centerVertical="true" android:layout_centerVertical="true"
@@ -58,8 +57,8 @@
android:src="@drawable/ic_blank_32dp" android:src="@drawable/ic_blank_32dp"
android:scaleType="fitXY" android:scaleType="fitXY"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:layout_toRightOf="@+id/group_arrow" android:layout_toRightOf="@+id/node_image_identifier"
android:layout_toEndOf="@+id/group_arrow" /> android:layout_toEndOf="@+id/node_image_identifier" />
<TextView <TextView
android:id="@+id/node_child_numbers" android:id="@+id/node_child_numbers"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -90,7 +89,7 @@
tools:text="Node Title" tools:text="Node Title"
android:lines="1" android:lines="1"
android:singleLine="true" android:singleLine="true"
style="@style/KeepassDXStyle.TextAppearance.Title" /> <!-- style override --> style="@style/KeepassDXStyle.TextAppearance.Group.Title" />
<TextView <TextView
android:id="@+id/node_subtext" android:id="@+id/node_subtext"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -100,7 +99,7 @@
android:layout_marginTop="-4dp" android:layout_marginTop="-4dp"
android:lines="1" android:lines="1"
android:singleLine="true" android:singleLine="true"
style="@style/KeepassDXStyle.TextAppearance.Secondary" /> <!-- style override --> style="@style/KeepassDXStyle.TextAppearance.Group.SubTitle" />
</LinearLayout> </LinearLayout>
</RelativeLayout> </RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </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 You should have received a copy of the GNU General Public License
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>. 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="homepage">الصفحة الرئيسية</string>
<string name="accept">قبول</string> <string name="accept">قبول</string>
<string name="add_group">إضافة مجموعة</string> <string name="add_group">إضافة مجموعة</string>
<string name="encryption">التعمية</string> <string name="encryption">التعمية</string>
<string name="encryption_algorithm">خوارزمية التعمية</string> <string name="encryption_algorithm">خوارزمية التعمية</string>
<string name="application">التطبيق</string> <string name="application">التطبيق</string>
<string name="beta_dontask">لا تظهر مرة أخرى</string>
<string name="brackets">أقواس</string> <string name="brackets">أقواس</string>
<string name="extended_ASCII">تمديد ASCII</string> <string name="extended_ASCII">تمديد ASCII</string>
<string name="allow">السماح</string> <string name="allow">السماح</string>
@@ -117,15 +115,16 @@
<string name="edit_entry">تحرير مدخلة</string> <string name="edit_entry">تحرير مدخلة</string>
<string name="key_derivation_function">وظيفة اشتقاق المفتاح</string> <string name="key_derivation_function">وظيفة اشتقاق المفتاح</string>
<string name="app_timeout">مهلة التطبيق</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="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">مهلة الحافظة</string>
<string name="clipboard_timeout_summary">مدة التخزين في الحافظة</string> <string name="clipboard_timeout_summary">مدة التخزين في الحافظة</string>
<string name="select_to_copy">اختر لنسخ %1$s إلى الحافظة</string> <string name="select_to_copy">اختر لنسخ %1$s إلى الحافظة</string>
<string name="retrieving_db_key">يجلب مفتاح قاعدة البيانات…</string> <string name="retrieving_db_key">يجلب مفتاح قاعدة البيانات…</string>
<string name="default_checkbox">استخدامها كقاعدة بيانات افتراضية</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_accessed">نُفذ إليه</string>
<string name="entry_expires">تنتهي صلاحيته في</string> <string name="entry_expires">تنتهي صلاحيته في</string>
<string name="entry_keyfile">ملف المفتاح</string> <string name="entry_keyfile">ملف المفتاح</string>
@@ -278,4 +277,12 @@
<string name="content_description_keyboard_close_fields">أغلق الحقول</string> <string name="content_description_keyboard_close_fields">أغلق الحقول</string>
<string name="error_create_database_file">لا يمكن انشاء قاعدة بيانات بكلمة السر وملف المفتاح الحاليين.</string> <string name="error_create_database_file">لا يمكن انشاء قاعدة بيانات بكلمة السر وملف المفتاح الحاليين.</string>
<string name="menu_advanced_unlock_settings">إلغاء القفل المتقدم</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> </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 You should have received a copy of the GNU General Public License
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>. along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
Catalan translation by Oriol Garrote Catalan translation by Oriol Garrote
--> --><resources>
<resources> <string name="feedback">Comentaris</string>
<string name="feedback">Comentaris:</string>
<string name="homepage">Pàgina inici:</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="about_description">KeePassDX és una implementació per a Android de KeePass password manager</string>
<string name="accept">Accepta</string> <string name="accept">Accepta</string>
@@ -77,7 +76,7 @@
<string name="hint_length">Longitud</string> <string name="hint_length">Longitud</string>
<string name="hint_pass">Contrasenya</string> <string name="hint_pass">Contrasenya</string>
<string name="password">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="invalid_db_sig">No s\'ha pogut reconèixer el format de la base de dades.</string>
<string name="length">Longitud</string> <string name="length">Longitud</string>
<string name="list_size_title">Mida de la llista de grups</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="edit_entry">Edita l\'entrada</string>
<string name="contribution">Contribució</string> <string name="contribution">Contribució</string>
<string name="contact">Contacte</string> <string name="contact">Contacte</string>
<string name="beta_dontask">No tornis a mostrar</string>
<string name="extended_ASCII">ASCII ampliat</string> <string name="extended_ASCII">ASCII ampliat</string>
<string name="sort_username">Nom d\'usuari</string> <string name="sort_username">Nom d\'usuari</string>
<string name="sort_title">Títol</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="app_timeout_summary">Doba nečinnosti než se aplikace zamkne</string>
<string name="application">Aplikace</string> <string name="application">Aplikace</string>
<string name="menu_app_settings">Nastavení 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="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="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> <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_length">Délka</string>
<string name="hint_pass">Heslo</string> <string name="hint_pass">Heslo</string>
<string name="password">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_algorithm">Nesprávný algoritmus.</string>
<string name="invalid_db_sig">Nedaří se rozpoznat formát databáze.</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> <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_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="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="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="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_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> <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_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="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_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_open_file">Otevři soubor</string>
<string name="content_description_node_children">Potomci uzlu</string> <string name="content_description_node_children">Potomci uzlu</string>
<string name="content_description_add_node">Přidej uzel</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="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="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="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> </resources>

View File

@@ -28,7 +28,6 @@
<string name="app_timeout_summary">Inaktiv tid, før databasen låses</string> <string name="app_timeout_summary">Inaktiv tid, før databasen låses</string>
<string name="application">Program</string> <string name="application">Program</string>
<string name="menu_app_settings">Indstillinger</string> <string name="menu_app_settings">Indstillinger</string>
<string name="beta_dontask">Vis ikke igen</string>
<string name="brackets">Parenteser</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="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> <string name="clipboard_cleared">Udklipsholder ryddet</string>
@@ -81,7 +80,7 @@
<string name="hint_length">Længde</string> <string name="hint_length">Længde</string>
<string name="hint_pass">Adgangskode</string> <string name="hint_pass">Adgangskode</string>
<string name="password">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_algorithm">Forkert algoritme.</string>
<string name="invalid_db_sig">Kunne ikke genkende databaseformat.</string> <string name="invalid_db_sig">Kunne ikke genkende databaseformat.</string>
<string name="keyfile_is_empty">Nøglefilen er tom.</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_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="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="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="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_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_not_recognized">Kunne ikke genkende biometrisk</string>
<string name="biometric_scanning_error">Problem med fingeraftryk: %1$s</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="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="no_credentials_stored">Databasen har endnu ikke en adgangskode.</string>
<string name="database_history">Historik</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_title">Skærmlås</string>
<string name="lock_database_screen_off_summary">Lås databasen, når skærmen er slukket</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="advanced_unlock">Fingeraftryk</string>
<string name="biometric_unlock_enable_title">Fingeraftryksscanning</string> <string name="biometric_unlock_enable_title">Biometrisk oplåsning</string>
<string name="biometric_unlock_enable_summary">Lader dig scanne din biometrisk for at åbne databasen</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_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_summary">Slet alle krypteringsnøgler, der er relateret til biometrisk genkendelse</string>
<string name="biometric_delete_all_key_warning">Slet alle nøgler, der er relateret til fingeraftryksgenkendelse\?</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_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_version">Android-version %1$s opfylder ikke minimum versionskrav %2$s.</string>
<string name="unavailable_feature_hardware">Kunne ikke finde den tilsvarende hardware.</string> <string name="unavailable_feature_hardware">Kunne ikke finde den tilsvarende hardware.</string>
@@ -270,8 +269,8 @@
\nGrupper (~mapper) organiserer poster i databasen.</string> \nGrupper (~mapper) organiserer poster i databasen.</string>
<string name="education_search_title">Søg i poster</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_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_title">Oplåsning af database ved hjælp af biometrisk</string>
<string name="education_biometric_summary">Link adgangskoden til det scannede fingeraftryk for hurtigt at låse databasen op.</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_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_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> <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_title">Valg af indtastning</string>
<string name="keyboard_selection_entry_summary">Vis indtastningsfelter i Magikeyboard, når der vises en post</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_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_open_file">Åbn fil</string>
<string name="content_description_node_children">Undernode</string> <string name="content_description_node_children">Undernode</string>
<string name="content_description_add_node">Tilføj knude</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_prompt_extract_credential_message">Uddrag databasens legitimationsoplysninger med biometriske data</string>
<string name="biometric">Biometrisk</string> <string name="biometric">Biometrisk</string>
<string name="biometric_auto_open_prompt_title">Åbn automatisk biometrisk prompt</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="enable">Aktiver</string>
<string name="disable">Deaktiver</string> <string name="disable">Deaktiver</string>
<string name="master_key">Hovednøgle</string> <string name="master_key">Hovednøgle</string>
@@ -429,7 +428,7 @@
<string name="command_execution">Udfører kommandoen…</string> <string name="command_execution">Udfører kommandoen…</string>
<string name="warning_permanently_delete_nodes">Slet markerede noder permanent\?</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="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="recycle_bin_group_title">Papirkurvsgruppe</string>
<string name="enable_auto_save_database_title">Gem automatisk database</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> <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="autofill_preference_title">Indstillinger for automatisk udfyldning</string>
<string name="warning_database_link_revoked">Adgang til filen tilbagekaldt af filadministratoren</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="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> </resources>

View File

@@ -34,7 +34,6 @@
<string name="app_timeout_summary">Inaktivität vor dem Sperren der Datenbank</string> <string name="app_timeout_summary">Inaktivität vor dem Sperren der Datenbank</string>
<string name="application">App</string> <string name="application">App</string>
<string name="menu_app_settings">App-Einstellungen</string> <string name="menu_app_settings">App-Einstellungen</string>
<string name="beta_dontask">Nicht mehr anzeigen</string>
<string name="brackets">Klammern</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="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> <string name="clipboard_cleared">Zwischenablage geleert</string>
@@ -91,7 +90,7 @@
<string name="hint_length">Länge</string> <string name="hint_length">Länge</string>
<string name="hint_pass">Passwort</string> <string name="hint_pass">Passwort</string>
<string name="password">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_algorithm">Falscher Algorithmus.</string>
<string name="invalid_db_sig">Datenbankformat nicht erkannt.</string> <string name="invalid_db_sig">Datenbankformat nicht erkannt.</string>
<string name="keyfile_is_empty">Die Schlüsseldatei ist leer.</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_summary">Erlaubte Zeichen für Passwortgenerator festlegen</string>
<string name="list_password_generator_options_title">Passwortzeichen</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="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="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_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> <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_title">Eintragsauswahl</string>
<string name="keyboard_selection_entry_summary">Eingabefelder beim Betrachten eines Eintrags im Magikeyboard anzeigen</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_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_open_file">Datei öffnen</string>
<string name="content_description_add_entry">Eintrag hinzufügen</string> <string name="content_description_add_entry">Eintrag hinzufügen</string>
<string name="content_description_add_group">Gruppe hinzufügen</string> <string name="content_description_add_group">Gruppe hinzufügen</string>
@@ -390,7 +389,7 @@
<string name="biometric">Biometrisch</string> <string name="biometric">Biometrisch</string>
<string name="enable">Aktivieren</string> <string name="enable">Aktivieren</string>
<string name="disable">Deaktivieren</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_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_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> <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="autofill_preference_title">Autofill-Einstellungen</string>
<string name="warning_database_link_revoked">Zugriff auf die Datei durch den Dateimanager widerrufen</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="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> </resources>

View File

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

View File

@@ -143,7 +143,6 @@
</string-array> </string-array>
<string name="encryption">Cifrado</string> <string name="encryption">Cifrado</string>
<string name="key_derivation_function">Función de derivación de clave</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="extended_ASCII">ASCII extendido</string>
<string name="allow">Permitir</string> <string name="allow">Permitir</string>
<string name="clipboard_error_title">Error del portapapeles</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 You should have received a copy of the GNU General Public License
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>. along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
Basque translation by David García-Abad Basque translation by David García-Abad
--> --><resources>
<resources> <string name="feedback">Feedback</string>
<string name="feedback">Feedback:</string>
<string name="homepage">Hasiera orria</string> <string name="homepage">Hasiera orria</string>
<string name="about_description">Keepass pasahitza kudeatzailearen Androiderako inplementazioa</string> <string name="about_description">Keepass pasahitza kudeatzailearen Androiderako inplementazioa</string>
<string name="accept">Onartu</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="app_timeout_summary">Denbora datubasea blokeatu baino lehenago aplikazioa erabili gabe dagoenean</string>
<string name="application">Aplikazioa</string> <string name="application">Aplikazioa</string>
<string name="menu_app_settings">Aplikazioaren ezarpenak</string> <string name="menu_app_settings">Aplikazioaren ezarpenak</string>
<string name="beta_dontask">Ez erakutsi berriro</string>
<string name="brackets">Brackets</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="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> <string name="clipboard_cleared">Arbela ezabatuta.</string>
@@ -135,23 +133,21 @@
<string name="unsupported_db_version">Euskarririk gabeko datubase bertsioa.</string> <string name="unsupported_db_version">Euskarririk gabeko datubase bertsioa.</string>
<string name="uppercase">Maiuskulak</string> <string name="uppercase">Maiuskulak</string>
<string name="version_label">Bertsioa %1$s</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 name="education_unlock_summary">Sartu pasahitz eta / edo gako fitxategi bat zure datubasea desblokeatzeko.</string>
<string-array name="timeout_options"> <string-array name="timeout_options">
<item>5 segundu</item> <item>5 segundu</item>
<item>10 segundu</item> <item>10 segundu</item>
<item>20 segundu</item> <item>20 segundu</item>
<item>30 segundu</item> <item>30 segundu</item>
<item>minutu 1</item> <item>minutu 1</item>
<item>5 minutu</item> <item>5 minutu</item>
<item>15 minutu</item> <item>15 minutu</item>
<item>30 minutu</item> <item>30 minutu</item>
<item>Inoiz ez</item> <item>Inoiz ez</item>
</string-array> </string-array>
<string-array name="list_size_options"> <string-array name="list_size_options">
<item>Txikia</item> <item>Txikia</item>
<item>Ertaina</item> <item>Ertaina</item>
<item>Handia</item> <item>Handia</item>
</string-array> </string-array>
</resources> </resources>

View File

@@ -16,32 +16,30 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>. along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
--> --><resources>
<resources> <string name="feedback">Palaute</string>
<string name="feedback">Palaute:</string> <string name="homepage">Kotisivu</string>
<string name="homepage">Kotisivu:</string> <string name="about_description">KeePass-salasanahallintaohjelman Android toteutus</string>
<string name="about_description">KeePassDX on KeePass-salasanahallintaohjelman Android-versio</string>
<string name="accept">Hyväksy</string> <string name="accept">Hyväksy</string>
<string name="add_entry">Lisää uusi salasanatietue</string> <string name="add_entry">Lisää uusi salasanatietue</string>
<string name="add_group">Lisää ryhmä</string> <string name="add_group">Lisää ryhmä</string>
<string name="encryption_algorithm">Algoritmi</string> <string name="encryption_algorithm">Salausalgoritmi</string>
<string name="app_timeout">Ohjelman aikakatkaisu</string> <string name="app_timeout">Sovelluksen aikakatkaisu</string>
<string name="app_timeout_summary">Aika, jonka jälkeen KeePass lukitaan jos se on ollut toimeton.</string> <string name="app_timeout_summary">Joutoaika ennen tietokannan lukkiutumista</string>
<string name="application">Ohjelma</string> <string name="application">Sovellus</string>
<string name="menu_app_settings">Ohjelman asetukset</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="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_cleared">Leikepöytä tyhjennetty.</string>
<string name="clipboard_error_title">Leikepöytävirhe</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">Jotkin laitteet eivät anna sovellusten käyttää leikepöytää.</string>
<string name="clipboard_error_clear">Leikepöydän tyhjennys epäonnistui</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">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="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="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="default_checkbox">Käytä tätä oletustietokantana</string>
<string name="digits">Numerot</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> <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="length">Pituus</string>
<string name="list_size_title">Ryhmälistan pituus</string> <string name="list_size_title">Ryhmälistan pituus</string>
<string name="list_size_summary">Tekstin koko ryhmälistauksessa</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="lowercase">pienet kirjaimet</string>
<string name="hide_password_title">Piilota salasaan</string> <string name="hide_password_title">Piilota salasaan</string>
<string name="hide_password_summary">Piilota salasanat oletuksena</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="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_title">Älä etsi varmuuskopioista eikä roskakorista</string>
<string name="omit_backup_search_summary">Poista \'Varmuuskopiot\' ja roskakori hakutuloksista</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_create">Luodaan uutta tietokantaa</string>
<string name="progress_title">Työskennellään&#8230;</string> <string name="progress_title">Työskennellään</string>
<string name="protection">Suojaus</string> <string name="protection">Suojaus</string>
<string name="content_description_remove_from_list">Poista</string> <string name="content_description_remove_from_list">Poista</string>
<string name="encryption_rijndael">Rijndael (AES)</string> <string name="encryption_rijndael">Rijndael (AES)</string>
<string name="root">Juuri</string> <string name="root">Juuri</string>
<string name="rounds">Salauskierroksia</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="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="space">Tila</string>
<string name="search_label">Etsi</string> <string name="search_label">Etsi</string>
<string name="sort_db">Tietokannan lajittelujärjestys</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="unsupported_db_version">Ei-tuettu salasanatietokannan versio.</string>
<string name="uppercase">Isot kirjaimet</string> <string name="uppercase">Isot kirjaimet</string>
<string name="version_label">Versio %1$s</string> <string name="version_label">Versio %1$s</string>
<string name="education_unlock_summary">Syötä salasana ja/tai avaintiedosto avataksesi tietokantasi.</string> <string name="education_unlock_summary">Syötä salasana ja/tai avaintiedosto avataksesi tietokantasi.</string>
<string-array name="timeout_options"> <string-array name="timeout_options">
<item>5 sekuntia</item> <item>5 sekuntia</item>
<item>10 sekuntia</item> <item>10 sekuntia</item>
<item>20 sekuntia</item> <item>20 sekuntia</item>
<item>30 sekuntia</item> <item>30 sekuntia</item>
<item>1 minuutti</item> <item>1 minuutti</item>
<item>5 minuttia</item> <item>5 minuttia</item>
<item>15 minuttia</item> <item>15 minuttia</item>
<item>30 minuttia</item> <item>30 minuttia</item>
<item>Ei koskaan</item> <item>Ei koskaan</item>
</string-array> </string-array>
<string-array name="list_size_options"> <string-array name="list_size_options">
<item>Pieni</item> <item>Pieni</item>
<item>Keskikokoinen</item> <item>Keskikokoinen</item>
<item>Suuri</item> <item>Suuri</item>
</string-array> </string-array>
</resources> <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="application">Application</string>
<string name="menu_app_settings">Paramètres de lapplication</string> <string name="menu_app_settings">Paramètres de lapplication</string>
<string name="menu_form_filling_settings">Remplissage de formulaire</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="brackets">Parenthèses (ou autres)</string>
<string name="extended_ASCII">ASCII étendu</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> <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_length">Longueur</string>
<string name="hint_pass">Mot de passe</string> <string name="hint_pass">Mot de passe</string>
<string name="password">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_algorithm">Algorithme invalide.</string>
<string name="invalid_db_sig">Impossible de reconnaître le format de la base de données.</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> <string name="keyfile_is_empty">Le fichier clé est vide.</string>
@@ -484,4 +483,4 @@
<string name="autofill_preference_title">Paramètres de remplissage automatique</string> <string name="autofill_preference_title">Paramètres de remplissage automatique</string>
<string name="warning_database_link_revoked">Accès au fichier révoqué par le gestionnaire de fichiers</string> <string name="warning_database_link_revoked">Accès au fichier révoqué par le gestionnaire de fichiers</string>
<string name="error_label_exists">Ce label existe déjà.</string> <string name="error_label_exists">Ce label existe déjà.</string>
</resources> </resources>

View File

@@ -16,10 +16,9 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>. along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
--> --><resources>
<resources> <string name="feedback">Comentarios</string>
<string name="feedback">Comentarios:</string> <string name="homepage">Páxina inicial</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="about_description">KeePassDX é unha implementación para Android do xestor de contrasinais KeePass.</string>
<string name="accept">Aceptar</string> <string name="accept">Aceptar</string>
<string name="add_entry">Engadir entrada</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">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="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="application">Aplicación</string>
<string name="beta_dontask">Non amosar de novo</string>
<string name="brackets">Parénteses</string> <string name="brackets">Parénteses</string>
<string name="extended_ASCII">ASCII extendido</string> <string name="extended_ASCII">ASCII extendido</string>
<string name="allow">Permitir</string> <string name="allow">Permitir</string>

View File

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

View File

@@ -16,8 +16,7 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>. 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="about_description">Android implementacija KeePass upravitelja lozinki</string>
<string name="accept">Prihvati</string> <string name="accept">Prihvati</string>
<string name="add_entry">Dodaj unos</string> <string name="add_entry">Dodaj unos</string>
@@ -30,7 +29,6 @@
<string name="key_derivation_function">Funkcija izvedbe ključa</string> <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="app_timeout_summary">Vrijeme neaktivnosti prije zaključavanja baze podataka</string>
<string name="application">Aplikacija</string> <string name="application">Aplikacija</string>
<string name="beta_dontask">Ne prikazuj ponovno</string>
<string name="brackets">Zagrade</string> <string name="brackets">Zagrade</string>
<string name="extended_ASCII">Prošireni ASCII kod</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> <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_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="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="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_title">Veličina članova liste</string>
<string name="list_size_summary">Veličina teksta članova liste</string> <string name="list_size_summary">Veličina teksta članova liste</string>
<string name="lowercase">Mala slova</string> <string name="lowercase">Mala slova</string>
@@ -274,7 +272,7 @@
<string name="progress_title">Obrada…</string> <string name="progress_title">Obrada…</string>
<string name="read_only">Zaštićeno od pisanja</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="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="root">Korijen</string>
<string name="memory_usage_explanation">Količina memorije (u bajtovima) koju će koristiti funkcija izvedbe ključa.</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> <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_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_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="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> </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="app_timeout_summary">Tétlenség az adatbázis feloldása előtt</string>
<string name="application">Alkalmazás</string> <string name="application">Alkalmazás</string>
<string name="menu_app_settings">Alkalmazásbeállítások</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="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="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> <string name="clipboard_cleared">Vágólap törölve</string>
@@ -84,7 +83,7 @@
<string name="hint_length">Hossz</string> <string name="hint_length">Hossz</string>
<string name="hint_pass">Jelszó</string> <string name="hint_pass">Jelszó</string>
<string name="password">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_algorithm">Hibás algoritmus.</string>
<string name="invalid_db_sig">Az adatbázis formátuma nem ismerhető fel.</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> <string name="keyfile_is_empty">A kulcsfájl üres.</string>

View File

@@ -85,7 +85,7 @@
<string name="hint_length">Lunghezza</string> <string name="hint_length">Lunghezza</string>
<string name="password">Password</string> <string name="password">Password</string>
<string name="hint_pass">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_algorithm">Algoritmo errato.</string>
<string name="invalid_db_sig">Formato database non riconosciuto.</string> <string name="invalid_db_sig">Formato database non riconosciuto.</string>
<string name="keyfile_is_empty">Il file chiave è vuoto.</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="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="version_label">Versione %1$s</string>
<string name="configure_biometric">La scansione di impronte è supportata ma non impostata.</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="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_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> <string name="biometric_scanning_error">Problema impronta: %1$s</string>
@@ -163,7 +163,6 @@
<item>Medio</item> <item>Medio</item>
<item>Grande</item> <item>Grande</item>
</string-array> </string-array>
<string name="beta_dontask">Non mostrare di nuovo</string>
<string name="allow">Consenti</string> <string name="allow">Consenti</string>
<string name="copy_field">Copia di %1$s</string> <string name="copy_field">Copia di %1$s</string>
<string name="encryption">Cifratura</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="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_title">Protetto da scrittura</string>
<string name="enable_read_only_summary">Apri il database in sola lettura in modo predefinito</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="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_title">Ripristina le schermate educative</string>
<string name="reset_education_screens_summary">Mostra di nuovo tutti gli elementi educativi</string> <string name="reset_education_screens_summary">Mostra di nuovo tutti gli elementi educativi</string>
@@ -480,4 +479,4 @@
<string name="warning_database_link_revoked">Accesso al file revocato dal file manager</string> <string name="warning_database_link_revoked">Accesso al file revocato dal file manager</string>
<string name="remember_keyfile_locations_summary">Ricorda la posizione dei keyfiles dei database</string> <string name="remember_keyfile_locations_summary">Ricorda la posizione dei keyfiles dei database</string>
<string name="error_label_exists">Questa etichetta esiste già.</string> <string name="error_label_exists">Questa etichetta esiste già.</string>
</resources> </resources>

View File

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

View File

@@ -16,8 +16,7 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>. along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
--> --><resources>
<resources>
<string name="feedback">フィードバック</string> <string name="feedback">フィードバック</string>
<string name="homepage">ホームページ</string> <string name="homepage">ホームページ</string>
<string name="about_description">KeePass パスワードマネージャーの Android 実装</string> <string name="about_description">KeePass パスワードマネージャーの Android 実装</string>
@@ -26,22 +25,23 @@
<string name="add_group">グループを追加</string> <string name="add_group">グループを追加</string>
<string name="encryption_algorithm">暗号化アルゴリズム</string> <string name="encryption_algorithm">暗号化アルゴリズム</string>
<string name="app_timeout">アプリ タイムアウト</string> <string name="app_timeout">アプリ タイムアウト</string>
<string name="app_timeout_summary">KeePassがこの時間非アクティブだった場合、データベースをロックします。</string> <string name="app_timeout_summary">データベースをロックするまでの休止時間</string>
<string name="application">アプリケーション</string> <string name="application">アプリ</string>
<string name="menu_app_settings">アプリケーション設定</string> <string name="menu_app_settings">アプリ設定</string>
<string name="brackets">カッコ</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_cleared">クリップボードを消去しました。</string>
<string name="clipboard_timeout">クリップボード タイムアウト</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="select_to_copy">ここをタップすると%1$sをクリップボードにコピーします</string>
<string name="retrieving_db_key">データベース認証中…</string> <string name="retrieving_db_key">データベース認証中…</string>
<string name="database">データベース</string> <string name="database">データベース</string>
<string name="decrypting_db">データベースを解析中…</string> <string name="decrypting_db">データベースを復号中…</string>
<string name="default_checkbox">のデータベースを次回以降も利用する</string> <string name="default_checkbox">デフォルトのデータベースとして使う</string>
<string name="digits">数字</string> <string name="digits">数字</string>
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft によって作られたフリーソフトウェアであり、無保証です。GPLバージョン3以上の条件下でこれを再頒布することができます。</string> <string name="html_about_licence">KeePassDX © %1$d Kunzisoft &lt;strong&gt;オープンソース&lt;/strong&gt; であり &lt;strong&gt;広告はありません&lt;/strong&gt;
<string name="select_database_file">データベースファイル</string> \n現状のまま、&lt;strong&gt;GPLv3&lt;/strong&gt; ライセンスのもとで、何らの保証もなく提供されます。</string>
<string name="select_database_file">既存のデータベースを開く</string>
<string name="entry_accessed">最終アクセス日</string> <string name="entry_accessed">最終アクセス日</string>
<string name="entry_cancel">キャンセル</string> <string name="entry_cancel">キャンセル</string>
<string name="entry_notes">備考</string> <string name="entry_notes">備考</string>
@@ -55,28 +55,28 @@
<string name="entry_title">タイトル</string> <string name="entry_title">タイトル</string>
<string name="entry_url">URL</string> <string name="entry_url">URL</string>
<string name="entry_user_name">ユーザー名</string> <string name="entry_user_name">ユーザー名</string>
<string name="error_arc4">Arcfour stream cipherには対応していません。</string> <string name="error_arc4">Arcfourストリーム暗号には対応していません。</string>
<string name="error_can_not_handle_uri">KeePassDXはこのuriを処理できません。</string> <string name="error_can_not_handle_uri">KeePassDXはこのURIを処理できません。</string>
<string name="error_file_not_create">ファイルを作成できません。</string> <string name="error_file_not_create">ファイルを作成できません。</string>
<string name="error_invalid_db">無効なデータベースです</string> <string name="error_invalid_db">データベースを読み込めません</string>
<string name="error_invalid_path">パスが無効です</string> <string name="error_invalid_path">パスが正しいことを確認してください</string>
<string name="error_no_name">タイトルは必須入力です</string> <string name="error_no_name">名前を入力してください</string>
<string name="error_nokeyfile">パスワードかキーファイルが必要です</string> <string name="error_nokeyfile">キーファイルを選択してください</string>
<string name="error_out_of_memory">データベース解析中にメモリ不足になりました</string> <string name="error_out_of_memory">データベース全体を読み込むメモリがありません</string>
<string name="error_pass_gen_type">少なくとも1つ以上のパスワード生成タイプを選択する必要があります。</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_rounds_too_large">値が大きすぎます。 2147483648にセットしました。</string>
<string name="error_wrong_length">\"長さ\"欄には正の整数を入力してください。</string> <string name="error_wrong_length">\"長さ\"欄には正の整数を入力してください。</string>
<string name="file_browser">ファイルブラウザ</string> <string name="file_browser">ファイルマネージャー</string>
<string name="generate_password">パスワードを生成する</string> <string name="generate_password">パスワードを生成する</string>
<string name="hint_conf_pass">パスワードをもう一度入力</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_group_name">グループ名</string>
<string name="hint_keyfile">キーファイル</string> <string name="hint_keyfile">キーファイル</string>
<string name="hint_length">長さ</string> <string name="hint_length">長さ</string>
<string name="password">パスワード</string> <string name="password">パスワード</string>
<string name="hint_pass">パスワード</string> <string name="hint_pass">パスワード</string>
<string name="invalid_credentials">パスワード/キーファイルが違います</string> <string name="invalid_credentials">認証情報が読めません</string>
<string name="invalid_db_sig">データベースフォーマットが認識できません。</string> <string name="invalid_db_sig">データベースフォーマットが認識できません。</string>
<string name="length">生成するパスワードの長さ</string> <string name="length">生成するパスワードの長さ</string>
<string name="list_size_title">グループ一覧サイズ</string> <string name="list_size_title">グループ一覧サイズ</string>
@@ -142,11 +142,10 @@
<string name="edit_entry">エントリーを編集</string> <string name="edit_entry">エントリーを編集</string>
<string name="encryption">暗号化</string> <string name="encryption">暗号化</string>
<string name="key_derivation_function">鍵導出関数</string> <string name="key_derivation_function">鍵導出関数</string>
<string name="beta_dontask">今後、表示しない</string>
<string name="extended_ASCII">拡張 ASCII</string> <string name="extended_ASCII">拡張 ASCII</string>
<string name="allow">許可</string> <string name="allow">許可</string>
<string name="clipboard_error_title">クリップボードエラー</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_error_clear">クリップボードをクリアできません</string>
<string name="clipboard_swipe_clean">スワイプすると今すぐクリップボードをクリアします</string> <string name="clipboard_swipe_clean">スワイプすると今すぐクリップボードをクリアします</string>
<string name="entry_not_found">エントリデータが見つかりませんでした。</string> <string name="entry_not_found">エントリデータが見つかりませんでした。</string>
@@ -214,4 +213,28 @@
<string name="menu_empty_recycle_bin">ゴミ箱を空にする</string> <string name="menu_empty_recycle_bin">ゴミ箱を空にする</string>
<string name="command_execution">コマンド実行中…</string> <string name="command_execution">コマンド実行中…</string>
<string name="warning_permanently_delete_nodes">削除するとこのエントリーは復活できませんがよろしいですか?</string> <string name="warning_permanently_delete_nodes">削除するとこのエントリーは復活できませんがよろしいですか?</string>
</resources> <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">앱 자동 종료 시간</string>
<string name="app_timeout_summary">앱이 잠기기 전에 비활성화됨</string> <string name="app_timeout_summary">앱이 잠기기 전에 비활성화됨</string>
<string name="application"></string> <string name="application"></string>
<string name="beta_dontask">다시 보이지 않음</string>
<string name="brackets">브라켓</string> <string name="brackets">브라켓</string>
<string name="extended_ASCII">확장 ASCII</string> <string name="extended_ASCII">확장 ASCII</string>
<string name="file_manager_install_description">OpenIntents File Manager를 설치하여 파일 찾아보기</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 You should have received a copy of the GNU General Public License
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>. 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="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="clipboard_cleared">Iškarpinė išvalyta.</string>
<string name="invalid_credentials">Neteisingas slaptažodis arba rakto failas.</string> <string name="invalid_credentials">Neteisingas slaptažodis arba rakto failas.</string>
<string name="feedback">Atsiliepimai:</string> <string name="feedback">Atsiliepimai</string>
<string name="homepage">Pagrindinis puslapis:</string> <string name="homepage">Pagrindinis puslapis</string>
<string name="accept">Priimti</string> <string name="accept">Priimti</string>
<string name="add_entry">Pridėti įrašą</string> <string name="add_entry">Pridėti įrašą</string>
<string name="add_group">Pridėti grupę</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="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="application">Programėlė</string>
<string name="menu_app_settings">Programėlės nustatymai</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="brackets">Skliaustai</string>
<string name="database">Duomenų bazė</string> <string name="database">Duomenų bazė</string>
<string name="digits">Skaitmenys</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="hide_password_summary">Slėpti slaptažodžius pagal nutylėjimą</string>
<string name="invalid_algorithm">Neteisingas algoritmas.</string> <string name="invalid_algorithm">Neteisingas algoritmas.</string>
<string name="error_invalid_path">Neteisingas kelias.</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> <string name="education_unlock_summary">Įveskite slaptažodį rba raktą, tam kad atidarytumėte duomenų bazę.</string>
</resources>
</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. Copyright 2020 Jeremy Jamet / Kunzisoft.
@@ -16,10 +16,9 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>. along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
--> --><resources>
<resources> <string name="feedback">Atsauksmes</string>
<string name="feedback">Atsauksmes:</string> <string name="homepage">Mājaslapa</string>
<string name="homepage">Mājaslapa:</string>
<string name="about_description">KeePassDX ir KeePass paroļu menedžera Android implementācija</string> <string name="about_description">KeePassDX ir KeePass paroļu menedžera Android implementācija</string>
<string name="accept">Pieņemt</string> <string name="accept">Pieņemt</string>
<string name="add_entry">Jauns ieraksts</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="app_timeout_summary">Bloķēšanas taimauts, kad programma nav aktīva.</string>
<string name="application">Programma</string> <string name="application">Programma</string>
<string name="menu_app_settings">Programmas iestatījumi</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="brackets">Iekavas</string>
<string name="file_manager_install_description">Failu pārlūkošanai nepieciešams pārlūks.</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> <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="unsupported_db_version">Neatbalstīta datu bāzes versija.</string>
<string name="uppercase">Lielie burti</string> <string name="uppercase">Lielie burti</string>
<string name="version_label">Versija %1$s</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 name="education_unlock_summary">Ievadiet paroli/atslēgas failu, lai atbloķētu savu datu bāzi.</string>
<string-array name="timeout_options"> <string-array name="timeout_options">
<item>5 sekundes</item> <item>5 sekundes</item>
<item>10 sekundes</item> <item>10 sekundes</item>
@@ -151,9 +147,9 @@
<item>Vidējs</item> <item>Vidējs</item>
<item>Liels</item> <item>Liels</item>
</string-array> </string-array>
<string name="edit_entry">Labot ierakstu</string> <string name="edit_entry">Labot ierakstu</string>
<string name="encryption">Šifrēšana</string> <string name="encryption">Šifrēšana</string>
<string name="extended_ASCII">Paplašinātais ASCII</string> <string name="extended_ASCII">Paplašinātais ASCII</string>
<string name="allow">Atļaut</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> <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">Programtidsavbrudd</string>
<string name="app_timeout_summary">Inaktivitet før programmet låses</string> <string name="app_timeout_summary">Inaktivitet før programmet låses</string>
<string name="application">Program</string> <string name="application">Program</string>
<string name="beta_dontask">Ikke vis igjen</string>
<string name="brackets">Parenteser</string> <string name="brackets">Parenteser</string>
<string name="extended_ASCII">Utvidet ASCII</string> <string name="extended_ASCII">Utvidet ASCII</string>
<string name="file_manager_install_description">Utforsk filer ved å installere OpenIntents-filbehandleren</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="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_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_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_name_title">Databasenavn</string>
<string name="database_description_title">Databasebeskrivelse</string> <string name="database_description_title">Databasebeskrivelse</string>
<string name="database_version_title">Databaseversjon</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_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_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_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_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_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> <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_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 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>
<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 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>
<string name="html_text_dev_feature">Denne funksjonen er &lt;strong&gt;under utvikling&lt;/strong&gt; og krever &lt;strong&gt;bidrag&lt;/strong&gt; for å bli tilgjengelig snart.</string> <string name="html_text_dev_feature">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_rijndael">Rijndael (AES)</string>
<string name="encryption_twofish">Twofish</string> <string name="encryption_twofish">Twofish</string>
<string name="encryption_chacha20">ChaCha20</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="kdf_Argon2">Argon2</string>
<string name="style_choose_title">Velg en drakt</string> <string name="style_choose_title">Velg en drakt</string>
<string name="style_choose_summary">Tilpass programdrakten ved å endre fargene</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_appearance_category">Utseende</string>
<string name="keyboard_theme_title">Tastaturdrakt</string> <string name="keyboard_theme_title">Tastaturdrakt</string>
<string name="keyboard_keys_category">Taster</string> <string name="keyboard_keys_category">Taster</string>
<string name="keyboard_key_vibrate_title">Vibrer ved tastetrykk</string> <string name="keyboard_key_vibrate_title">Vibrasjonstastetrykk</string>
<string name="keyboard_key_sound_title">Lyd ved tastetrykk</string> <string name="keyboard_key_sound_title">Hørbare tastetrykk</string>
<string name="selection_mode">Valgmodus</string> <string name="selection_mode">Valgmodus</string>
<string name="do_not_kill_app">Ikke drep programmet…</string> <string name="do_not_kill_app">Ikke drep programmet…</string>
<string name="lock_database_back_root_title">Tilbakelås</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_title">Oppføringsvalg</string>
<string name="keyboard_selection_entry_summary">Vis inndatafelter i Magikeyboard når en oppføring vises</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_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_open_file">Åpne fil</string>
<string name="content_description_add_node">Legg til node</string> <string name="content_description_add_node">Legg til node</string>
<string name="content_description_add_entry">Legg til oppføring</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_summary">Viser låseknappen i brukergrensesnittet</string>
<string name="lock_database_show_button_title">Vis låseknapp</string> <string name="lock_database_show_button_title">Vis låseknapp</string>
<string name="error_label_exists">Denne etiketten finnes allerede.</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> </resources>

View File

@@ -18,37 +18,37 @@
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>. along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
Dutch translation by Erik Devriendt, corrected by Erik Jan Meijer Dutch translation by Erik Devriendt, corrected by Erik Jan Meijer
--> --><resources>
<resources>
<string name="feedback">Reacties</string> <string name="feedback">Reacties</string>
<string name="homepage">Website</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="accept">Accepteren</string>
<string name="add_entry">Item toevoegen</string> <string name="add_entry">Item toevoegen</string>
<string name="add_group">Groep toevoegen</string> <string name="add_group">Groep toevoegen</string>
<string name="encryption_algorithm">Algoritme</string> <string name="encryption_algorithm">Algoritme</string>
<string name="app_timeout">App-time-out</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="application">App</string>
<string name="menu_app_settings">App-instellingen</string> <string name="menu_app_settings">App-instellingen</string>
<string name="brackets">Haakjes</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_cleared">Klembord gewist</string>
<string name="clipboard_timeout">Klembordtime-out</string> <string name="clipboard_timeout">Klembordtime-out</string>
<string name="clipboard_timeout_summary">Tijd van opslag op het klembord</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="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="retrieving_db_key">Databasesleutel ophalen</string>
<string name="database">Databank</string> <string name="database">Database</string>
<string name="decrypting_db">Bezig met ontsleutelen van databankinhoud…</string> <string name="decrypting_db">Database-inhoud decoderen </string>
<string name="default_checkbox">Gebruiken als standaarddatabank</string> <string name="default_checkbox">Gebruiken als standaarddatabase</string>
<string name="digits">Getallen</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="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;.
<string name="select_database_file">Bestaande databank openen</string> \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_accessed">Laatst geopend</string>
<string name="entry_cancel">Annuleren</string> <string name="entry_cancel">Annuleren</string>
<string name="entry_notes">Opmerkingen</string> <string name="entry_notes">Opmerkingen</string>
<string name="entry_confpassword">Wachtwoord bevestigen</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_expires">Verloopt op</string>
<string name="entry_keyfile">Sleutelbestand</string> <string name="entry_keyfile">Sleutelbestand</string>
<string name="entry_modified">Bewerkt op</string> <string name="entry_modified">Bewerkt op</string>
@@ -59,43 +59,43 @@
<string name="entry_user_name">Gebruikersnaam</string> <string name="entry_user_name">Gebruikersnaam</string>
<string name="error_arc4">De Arcfour stream-versleuteling wordt niet ondersteund.</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_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_file_not_create">Bestand is niet aangemaakt:</string>
<string name="error_invalid_db">Kan databank niet uitlezen.</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_invalid_path">Zorg ervoor dat het pad juist is.</string>
<string name="error_no_name">Voer een naam in.</string> <string name="error_no_name">Voer een naam in.</string>
<string name="error_nokeyfile">Kies een sleutelbestand.</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_gen_type">Je moet minimaal één soort wachtwoordgenerering kiezen.</string>
<string name="error_pass_match">De wachtwoorden komen niet overeen.</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_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="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="generate_password">Wachtwoord genereren</string>
<string name="hint_conf_pass">wachtwoord bevestigen</string> <string name="hint_conf_pass">Wachtwoord bevestigen</string>
<string name="hint_generated_password">gegenereerd wachtwoord</string> <string name="hint_generated_password">Gegenereerd wachtwoord</string>
<string name="hint_group_name">Groepsnaam</string> <string name="hint_group_name">Groepsnaam</string>
<string name="hint_keyfile">sleutelbestand</string> <string name="hint_keyfile">Sleutelbestand</string>
<string name="hint_length">lengte</string> <string name="hint_length">Lengte</string>
<string name="password">Wachtwoord</string> <string name="password">Wachtwoord</string>
<string name="hint_pass">wachtwoord</string> <string name="hint_pass">Wachtwoord</string>
<string name="invalid_credentials">Ongeldig wachtwoord of sleutelbestand.</string> <string name="invalid_credentials">Kan referenties niet lezen.</string>
<string name="invalid_db_sig">Databankformaat kan niet worden herkend.</string> <string name="invalid_db_sig">Databaseformaat kan niet worden herkend.</string>
<string name="length">Lengte</string> <string name="length">Lengte</string>
<string name="list_size_title">Grootte van itemlijst</string> <string name="list_size_title">Lengte van lijst met items</string>
<string name="list_size_summary">Tekstgrootte van itemlijst</string> <string name="list_size_summary">Tekstgrootte in de lijst</string>
<string name="loading_database">Bezig met laden van databank</string> <string name="loading_database">Database laden</string>
<string name="lowercase">Kleine letters</string> <string name="lowercase">Kleine letters</string>
<string name="hide_password_title">Wachtwoord verbergen</string> <string name="hide_password_title">Wachtwoorden verbergen</string>
<string name="hide_password_summary">Wachtwoorden standaard afschermen (***)</string> <string name="hide_password_summary">Wachtwoorden standaard verbergen (***)</string>
<string name="about">Over</string> <string name="about">Over</string>
<string name="menu_change_key_settings">Hoofdsleutel wijzigen</string> <string name="menu_change_key_settings">Hoofdsleutel wijzigen</string>
<string name="settings">Instellingen</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_delete">Verwijderen</string>
<string name="menu_donate">Doneren</string> <string name="menu_donate">Doneren</string>
<string name="menu_edit">Bewerken</string> <string name="menu_edit">Bewerken</string>
<string name="menu_hide_password">Wachtwoord verbergen</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_open">Openen</string>
<string name="menu_search">Zoeken</string> <string name="menu_search">Zoeken</string>
<string name="menu_showpass">Wachtwoord tonen</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="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_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="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="progress_title">Bezig met verwerken…</string>
<string name="content_description_remove_from_list">Verwijderen</string> <string name="content_description_remove_from_list">Verwijderen</string>
<string name="encryption_rijndael">Rijndael (AES)</string> <string name="encryption_rijndael">Rijndael (AES)</string>
<string name="root">Hoofdmap</string> <string name="root">Hoofdmap</string>
<string name="rounds">Encryptie-cycli</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="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="space">Ruimte</string>
<string name="search_label">Zoeken</string> <string name="search_label">Zoeken</string>
<string name="sort_db">Natuurlijke volgorde</string> <string name="sort_db">Natuurlijke volgorde</string>
@@ -121,11 +121,11 @@
<string name="search">Zoeken</string> <string name="search">Zoeken</string>
<string name="encryption_twofish">Twofish</string> <string name="encryption_twofish">Twofish</string>
<string name="underline">Onderstrepen</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="uppercase">Hoofdletters</string>
<string name="version_label">Versie %1$s</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 \n
\nMaak na elke aanpassing een kopie van je .kdbx-bestand op een veilige locatie.</string> \nMaak na elke aanpassing een kopie van je .kdbx-bestand op een veilige locatie.</string>
<string-array name="timeout_options"> <string-array name="timeout_options">
<item>5 seconden</item> <item>5 seconden</item>
@@ -146,44 +146,43 @@
<string name="edit_entry">Item bewerken</string> <string name="edit_entry">Item bewerken</string>
<string name="encryption">Versleuteling</string> <string name="encryption">Versleuteling</string>
<string name="key_derivation_function">Sleutelafleidingsfunctie</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="extended_ASCII">Uitgebreide ASCII</string>
<string name="allow">Toestaan</string> <string name="allow">Toestaan</string>
<string name="clipboard_error_title">Klembordfout</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_error_clear">Wissen van klembord mislukt</string>
<string name="clipboard_swipe_clean">Veeg om klembord nu te wissen</string> <string name="clipboard_swipe_clean">Veeg om klembord nu te wissen</string>
<string name="entry_not_found">Geen iteminhoud gevonden.</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_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_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_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="error_move_folder_in_itself">Een groep kan niet naar zichzelf worden verplaatst.</string>
<string name="field_name">Veldnaam</string> <string name="field_name">Veldnaam</string>
<string name="field_value">Veldwaarde</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="invalid_algorithm">Ongeldig algoritme.</string>
<string name="keyfile_is_empty">Het sleutelbestand is leeg.</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_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="copy_field">Kopie van %1$s</string>
<string name="menu_form_filling_settings">Formulierinvulling</string> <string name="menu_form_filling_settings">Formulierinvulling</string>
<string name="menu_copy">Kopiëren</string> <string name="menu_copy">Kopiëren</string>
<string name="menu_move">Verplaatsen</string> <string name="menu_move">Verplaatsen</string>
<string name="menu_paste">Plakken</string> <string name="menu_paste">Plakken</string>
<string name="menu_cancel">Annuleren</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_file_selection_read_only">Alleen-lezen</string>
<string name="menu_open_file_read_and_write">Lezen en schrijven</string> <string name="menu_open_file_read_and_write">Lezen en schrijven</string>
<string name="protection">Beveiliging</string> <string name="protection">Beveiliging</string>
<string name="read_only">Alleen-lezen</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="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_title">Bestandsgeschiedenis</string>
<string name="show_recent_files_summary">Recent gebruikte bestandsnamen onthouden</string> <string name="show_recent_files_summary">Toon locaties van recente databases</string>
<string name="encryption_explanation">Het algoritme dat moet worden gebruikt om de gehele databank te versleutelen.</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="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">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">Parallellen</string>
<string name="parallelism_explanation">Het aantal parallellen (aantal threads) dat de afleidingsfunctie mag gebruiken.</string> <string name="parallelism_explanation">Het aantal parallellen (aantal threads) dat de afleidingsfunctie mag gebruiken.</string>
<string name="sort_menu">Sorteren</string> <string name="sort_menu">Sorteren</string>
@@ -198,15 +197,15 @@
<string name="search_results">Zoekresultaten</string> <string name="search_results">Zoekresultaten</string>
<string name="warning">Waarschuwing</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_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_empty_password">Doorgaan zonder beveiliging voor wachtwoordontgrendeling\?</string>
<string name="warning_no_encryption_key">Weet je zeker dat je geen sleutel wilt koppelen aan je versleuteling?</string> <string name="warning_no_encryption_key">Doorgaan zonder coderingssleutel\?</string>
<string name="configure_biometric">Vingerafdruk wordt ondersteund, maar is niet ingesteld.</string> <string name="configure_biometric">Biometrische herkenning is ondersteund, maar niet ingesteld.</string>
<string name="open_biometric_prompt_unlock_database">Vingerafdrukscanning</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="encrypted_value_stored">Versleuteld wachtwoord is opgeslagen</string>
<string name="biometric_invalid_key">Kan vingerafdruksleutel niet lezen; herstel je wachtwoord.</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">Vingerafdruk niet herkend</string> <string name="biometric_not_recognized">Biometrie niet herkend</string>
<string name="biometric_scanning_error">Vingerafdrukprobleem: %1$s</string> <string name="biometric_scanning_error">Probleem met biometrie: %1$s</string>
<string name="open_biometric_prompt_store_credential">Vingerafdruk gebruiken om dit wachtwoord op te slaan</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="no_credentials_stored">Deze databank heeft nog geen wachtwoord.</string>
<string name="database_history">Geschiedenis</string> <string name="database_history">Geschiedenis</string>
<string name="menu_appearance_settings">Uiterlijk</string> <string name="menu_appearance_settings">Uiterlijk</string>
@@ -214,32 +213,32 @@
<string name="autofill">Auto-aanvullen</string> <string name="autofill">Auto-aanvullen</string>
<string name="autofill_service_name">KeePassDX auto-aanvullendienst</string> <string name="autofill_service_name">KeePassDX auto-aanvullendienst</string>
<string name="autofill_sign_in_prompt">Inloggen met KeePassDX</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="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_title">Gegenereerde wachtwoordlengte</string>
<string name="password_size_summary">Standaardgrootte instellen van gegenereerd wachtwoord</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_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">Klembord</string>
<string name="clipboard_notifications_title">Klembordmeldingen</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_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="clipboard_warning">Als automatisch wissen van het klembord mislukt, doe dit dan handmatig.</string>
<string name="lock">Vergrendelen</string> <string name="lock">Vergrendelen</string>
<string name="lock_database_screen_off_title">Schermvergrendeling</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="lock_database_screen_off_summary">Database vergrendelen wanneer het scherm is uitgeschakeld</string>
<string name="advanced_unlock">Vingerafdruk</string> <string name="advanced_unlock">Geavanceerd ontgrendelen</string>
<string name="biometric_unlock_enable_title">Vingerafdrukherkenning</string> <string name="biometric_unlock_enable_title">Ontgrendelen met biometrie</string>
<string name="biometric_unlock_enable_summary">Laat u uw biometrische gegevens scannen om de database te openen</string> <string name="biometric_unlock_enable_summary">Gebruik biometrische herkenning om de database te openen</string>
<string name="biometric_delete_all_key_title">Sleutels voor versleuteling verwijderen</string> <string name="biometric_delete_all_key_title">Coderingssleutels verwijderen</string>
<string name="biometric_delete_all_key_summary">Alle aan vingerafdrukherkenning gerelateerde sleutels wilt verwijderen</string> <string name="biometric_delete_all_key_summary">Alle sleutels voor biometrische herkenning verwijderen</string>
<string name="biometric_delete_all_key_warning">Weet je zeker dat je alle sleutels van de vingerafdrukherkenning wilt 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_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_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="unavailable_feature_hardware">De bijbehorende hardware werd niet gevonden.</string>
<string name="file_name">Bestandsnaam</string> <string name="file_name">Bestandsnaam</string>
<string name="path">Pad</string> <string name="path">Pad</string>
<string name="assign_master_key">Hoofdsleutel toewijzen</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_title">Bestandspad</string>
<string name="full_file_path_enable_summary">Volledig bestandspad tonen</string> <string name="full_file_path_enable_summary">Volledig bestandspad tonen</string>
<string name="recycle_bin_title">Prullenbak gebruiken</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_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="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_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_summary">Toestaan dat het wachtwoord en beveiligde velden naar het klembord worden gekopieerd</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="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">Databanknaam</string> <string name="database_name_title">Databasenaam</string>
<string name="database_description_title">Databankomschrijving</string> <string name="database_description_title">Databaseomschrijving</string>
<string name="database_version_title">Databankversie</string> <string name="database_version_title">Databaseversie</string>
<string name="text_appearance">Tekst</string> <string name="text_appearance">Tekst</string>
<string name="application_appearance">App</string> <string name="application_appearance">App</string>
<string name="other">Overig</string> <string name="other">Overig</string>
<string name="keyboard">Toetsenbord</string> <string name="keyboard">Toetsenbord</string>
<string name="magic_keyboard_title">Magikeyboard</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="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="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_title">Alleen-lezen</string>
<string name="enable_read_only_summary">Open de databank standaard alleen-lezen</string> <string name="enable_read_only_summary">Open de database standaard alleen-lezen</string>
<string name="enable_education_screens_title">Educatieve vensters</string> <string name="enable_education_screens_title">Informatieve tips</string>
<string name="enable_education_screens_summary">Markeert de elementen om te leren hoe de app werkt</string> <string name="enable_education_screens_summary">Markeer elementen om te leren hoe de app werkt</string>
<string name="reset_education_screens_title">Standaardwaarden</string> <string name="reset_education_screens_title">Informatieve tips opnieuw instellen</string>
<string name="reset_education_screens_summary">Educatieve vensters opnieuw weergeven</string> <string name="reset_education_screens_summary">Informatieve tips opnieuw weergeven</string>
<string name="reset_education_screens_text">Educatieve vensters hersteld</string> <string name="reset_education_screens_text">Informatieve tips opnieuw ingesteld</string>
<string name="education_create_database_title">Creëer je databankbestand</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_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_title">Open een bestaande database</string>
<string name="education_select_database_summary">Open vanuit je bestandsverkenner een bestaande databank om dit verder te gebruiken.</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 databank</string> <string name="education_new_node_title">Voeg items toe aan de database</string>
<string name="education_new_node_summary">Voeg items toe om je digitale identiteiten te beheren. <string name="education_new_node_summary">Items helpen om je digitale identiteiten te beheren.
\n \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_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_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_title">Database-ontgrendeling met biometrie</string>
<string name="education_biometric_summary">Koppel je wachtwoord en vingerafdruk om de databank snel te ontgrendelen.</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_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_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_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_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_entry_new_field_summary">Registreer een extra veld, voeg een waarde toe en bescherm dit desgewenst.</string>
<string name="education_unlock_title">Ontgrendel je databank</string> <string name="education_unlock_title">Ontgrendel je database</string>
<string name="education_read_only_title">Databank alleen-lezen</string> <string name="education_read_only_title">Database alleen-lezen</string>
<string name="education_read_only_summary">Wijzig de opstartmodus van de sessie. <string name="education_read_only_summary">Wijzig de opstartmodus van de sessie.
\n \n
\nIn alleen-lezenmodus kunnen geen onbedoelde wijzigingen worden gemaakt. \nIn alleen-lezenmodus kunnen geen onbedoelde wijzigingen worden gemaakt.
\n
\nIn schrijfmodus kun je elementen toevoegen, verwijderen of aanpassen.</string> \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_title">Veld kopiëren toestaan</string>
<string name="education_field_copy_summary">Kopieer een veld en plak de inhoud waar je maar wilt. <string name="education_field_copy_summary">Kopieer een veld en plak de inhoud waar je maar wilt.
\n \n
\nJe kunt verschillende formulier-invulmethodes gebruiken; kies je voorkeursmethode.</string> \nJe kunt verschillende formulier-invulmethodes gebruiken; kies je voorkeursmethode.</string>
<string name="education_lock_title">Databank vergrendelen</string> <string name="education_lock_title">Database 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_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_title">Items sorteren</string>
<string name="education_sort_summary">Kies hoe items en groepen worden gesorteerd.</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_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="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_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 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 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> <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_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, rekenen we op jouw &lt;strong&gt;bijdrage.&lt;/strong&gt;</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_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">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_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_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_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_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="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="download">Downloaden</string>
<string name="contribute">Bijdragen</string> <string name="contribute">Bijdragen</string>
<string name="encryption_chacha20">ChaCha20</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="kdf_Argon2">Argon2</string>
<string name="style_choose_title">App-thema</string> <string name="style_choose_title">App-thema</string>
<string name="style_choose_summary">Thema gebruikt in de app</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_title">Icoonverzameling</string>
<string name="icon_pack_choose_summary">Iconenverzameling gebruikt in de app</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_name">Magikeyboard</string>
<string name="keyboard_label">Magikeyboard (KeePassDX)</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_category">Item</string>
<string name="keyboard_entry_timeout_title">Time-out</string> <string name="keyboard_entry_timeout_title">Time-out</string>
<string name="keyboard_entry_timeout_summary">Time-out om de toetsenbordinvoer te wissen</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_title">%1$s beschikbaar op Magikeyboard</string>
<string name="keyboard_notification_entry_content_text">%1$s</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_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_appearance_category">Uiterlijk</string>
<string name="keyboard_theme_title">Toetsenbordthema</string> <string name="keyboard_theme_title">Toetsenbordthema</string>
<string name="keyboard_keys_category">Toetsen</string> <string name="keyboard_keys_category">Toetsen</string>
@@ -345,15 +341,15 @@
<string name="keyboard_key_sound_title">Geluid bij toetsaanslag</string> <string name="keyboard_key_sound_title">Geluid bij toetsaanslag</string>
<string name="selection_mode">Selectiemodus</string> <string name="selection_mode">Selectiemodus</string>
<string name="do_not_kill_app">App niet afsluiten…</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_title">Druk \'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_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_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="recycle_bin">Prullenmand</string>
<string name="keyboard_selection_entry_title">Itemselectie</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="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_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_open_file">Bestand openen</string>
<string name="content_description_node_children">Onderliggende items</string> <string name="content_description_node_children">Onderliggende items</string>
<string name="content_description_add_node">Knooppunt toevoegen</string> <string name="content_description_add_node">Knooppunt toevoegen</string>
@@ -371,7 +367,7 @@
<string name="entry_UUID">UUID</string> <string name="entry_UUID">UUID</string>
<string name="error_move_entry_here">Je kan hier geen item plaatsen.</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="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="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_background">Achtergrond</string>
<string name="content_description_update_from_list">Update</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="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="menu_advanced_unlock_settings">Geavanceerd ontgrendelen</string>
<string name="biometric_prompt_store_credential_title">Biometrische herkenning opslaan</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_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 met biometrische herkenning openen</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 gegevens</string> <string name="biometric_prompt_extract_credential_message">Database-referenties uitpakken met biometrische herkenning</string>
<string name="biometric">Biometrisch</string> <string name="biometric">Biometrie</string>
<string name="biometric_auto_open_prompt_title">Automatisch biometrische prompt openen</string> <string name="biometric_auto_open_prompt_title">Automatisch om biometrie vragen</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_auto_open_prompt_summary">Automatisch om biometrie vragen als een database hiervoor is ingesteld</string>
<string name="enable">Inschakelen</string> <string name="enable">Inschakelen</string>
<string name="disable">Uitschakelen</string> <string name="disable">Uitschakelen</string>
<string name="master_key">Hoofdsleutel</string> <string name="master_key">Hoofdsleutel</string>
@@ -399,7 +395,7 @@
<string name="otp_algorithm">Algoritme</string> <string name="otp_algorithm">Algoritme</string>
<string name="entry_otp">OTP</string> <string name="entry_otp">OTP</string>
<string name="error_invalid_OTP">Ongeldig OTP-geheim.</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_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_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> <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_security_settings">Beveiligingsinstellingen</string>
<string name="menu_master_key_settings">Instellingen hoofdsleutel</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">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="database_opened">Database geopend</string>
<string name="clipboard_explanation_summary">Kopieer invoervelden met behulp van het klembord van uw apparaat</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="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_title">Gegevenscompressie</string>
<string name="database_data_compression_summary">Gegevenscompressie verkleint de omvang van de database.</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_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_title">Maximum</string>
<string name="max_history_size_summary">Grootte van geschiedenis beperken per invoer (in binaire bytes)</string> <string name="max_history_size_summary">Geschiedenis (bytes) per item beperken</string>
<string name="settings_database_recommend_changing_master_key_title">Aanbevolen wijzigen</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_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_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_title">Volgende keer verplicht vernieuwen</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_summary">Het hoofdwachtwoord de volgende keer (eenmalig) vernieuwen</string>
<string name="database_default_username_title">Standaard gebruikersnaam</string> <string name="database_default_username_title">Standaard gebruikersnaam</string>
<string name="database_custom_color_title">Aangepaste databasekleur</string> <string name="database_custom_color_title">Aangepaste databasekleur</string>
<string name="compression">Compressie</string> <string name="compression">Compressie</string>
<string name="compression_none">Geen</string> <string name="compression_none">Geen</string>
<string name="compression_gzip">GZip</string> <string name="compression_gzip">gzip</string>
<string name="device_keyboard_setting_title">Toetsenbordinstellingen voor apparaat</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> </resources>

View File

@@ -16,12 +16,11 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>. along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
--> --><resources>
<resources> <string name="feedback">Tilbakemelding</string>
<string name="feedback">Tilbakemelding:</string> <string name="homepage">Heimeside</string>
<string name="homepage">Heimeside:</string>
<string name="about_description">KeePassDX er ei android-utgåve av KeePass passordstyrar.</string> <string name="about_description">KeePassDX er ei android-utgåve av KeePass passordstyrar.</string>
<string name="accept">Godta</string> <string name="accept">Godta</string>
<string name="add_entry">Legg til post</string> <string name="add_entry">Legg til post</string>
<string name="add_group">Legg til gruppe</string> <string name="add_group">Legg til gruppe</string>
<string name="encryption_algorithm">Algoritme</string> <string name="encryption_algorithm">Algoritme</string>
@@ -122,23 +121,21 @@
<string name="unsupported_db_version">Kan ikkje bruka databaseutgåva.</string> <string name="unsupported_db_version">Kan ikkje bruka databaseutgåva.</string>
<string name="uppercase">Store bokstavar</string> <string name="uppercase">Store bokstavar</string>
<string name="version_label">Utgåve %1$s</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 name="education_unlock_summary">Skriv inn passordet og/eller nøkkelfil for å låsa opp databasen.</string>
<string-array name="timeout_options"> <string-array name="timeout_options">
<item>5 sekund</item> <item>5 sekund</item>
<item>10 sekund</item> <item>10 sekund</item>
<item>20 sekund</item> <item>20 sekund</item>
<item>30 sekund</item> <item>30 sekund</item>
<item>1 minutt</item> <item>1 minutt</item>
<item>5 minutt</item> <item>5 minutt</item>
<item>15 minutt</item> <item>15 minutt</item>
<item>30 minutt</item> <item>30 minutt</item>
<item>Aldri</item> <item>Aldri</item>
</string-array> </string-array>
<string-array name="list_size_options"> <string-array name="list_size_options">
<item>Liten</item> <item>Liten</item>
<item>Middels</item> <item>Middels</item>
<item>Stor</item> <item>Stor</item>
</string-array> </string-array>
</resources> </resources>

View File

@@ -74,7 +74,7 @@
<string name="hint_length">Długość</string> <string name="hint_length">Długość</string>
<string name="password">Hasło</string> <string name="password">Hasło</string>
<string name="hint_pass">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="invalid_db_sig">Nie można rozpoznać formatu bazy danych.</string>
<string name="length">Długość</string> <string name="length">Długość</string>
<string name="list_size_title">Wielkość listy grup</string> <string name="list_size_title">Wielkość listy grup</string>
@@ -115,7 +115,7 @@
<string name="sort_db">Porządek naturalny</string> <string name="sort_db">Porządek naturalny</string>
<string name="special">Znaki specjalne</string> <string name="special">Znaki specjalne</string>
<string name="search">Szukaj</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="underline">Podkreślenie</string>
<string name="unsupported_db_version">Nieobsługiwana wersja bazy danych.</string> <string name="unsupported_db_version">Nieobsługiwana wersja bazy danych.</string>
<string name="uppercase">Wielkie litery</string> <string name="uppercase">Wielkie litery</string>
@@ -141,7 +141,6 @@
<string name="edit_entry">Edytuj wpis</string> <string name="edit_entry">Edytuj wpis</string>
<string name="encryption">Szyfrowanie</string> <string name="encryption">Szyfrowanie</string>
<string name="key_derivation_function">Funkcja generująca klucz</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="extended_ASCII">Rozszerzone ASCII</string>
<string name="allow">Zezwalaj</string> <string name="allow">Zezwalaj</string>
<string name="clipboard_error_title">Błąd schowka</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="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="encrypted_value_stored">Zapisano zaszyfrowane hasło</string>
<string name="sort_groups_before">Grupy poprzednie</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_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_not_recognized">Nie można rozpoznać odcisku palca</string>
<string name="biometric_scanning_error">Problem z odciskiem palca: %1$s</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_title">Wybór wpisu</string>
<string name="keyboard_selection_entry_summary">Pokaż pola wprowadzania w Magikeyboard podczas przeglądania 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_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_open_file">Otwórz plik</string>
<string name="content_description_add_entry">Dodaj wpis</string> <string name="content_description_add_entry">Dodaj wpis</string>
<string name="content_description_add_group">Dodaj grupę</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="autofill_preference_title">Ustawienia autouzupełniania</string>
<string name="warning_database_link_revoked">Dostęp do pliku anulowany przez menedżera plików</string> <string name="warning_database_link_revoked">Dostęp do pliku anulowany przez menedżera plików</string>
<string name="error_label_exists">Ta etykieta już istnieje.</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> </resources>

View File

@@ -75,7 +75,7 @@
<string name="hint_length">Tamanho</string> <string name="hint_length">Tamanho</string>
<string name="password">Senha</string> <string name="password">Senha</string>
<string name="hint_pass">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="invalid_db_sig">Não pôde reconhecer formato do banco de dados.</string>
<string name="length">Tamanho</string> <string name="length">Tamanho</string>
<string name="list_size_title">Tamanho da lista de grupos</string> <string name="list_size_title">Tamanho da lista de grupos</string>
@@ -142,7 +142,6 @@
</string-array> </string-array>
<string name="encryption">Encriptação</string> <string name="encryption">Encriptação</string>
<string name="key_derivation_function">Função de derivação de chave</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="extended_ASCII">ASCII Extendido</string>
<string name="allow">Permitir</string> <string name="allow">Permitir</string>
<string name="clipboard_error_title">Erro na área de transferência</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_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="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="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="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_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> <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_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="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_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_open_file">Abrir arquivo</string>
<string name="content_description_add_node">Inserir nó</string> <string name="content_description_add_node">Inserir nó</string>
<string name="content_description_add_entry">Adicionar entrada</string> <string name="content_description_add_entry">Adicionar entrada</string>
@@ -475,4 +474,6 @@
<string name="discard_changes">Descartar alterações\?</string> <string name="discard_changes">Descartar alterações\?</string>
<string name="validate">Validação</string> <string name="validate">Validação</string>
<string name="contribution">Contribuiçã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> </resources>

View File

@@ -29,7 +29,6 @@
<string name="app_timeout_summary">Inatividade antes da app ser bloqueada</string> <string name="app_timeout_summary">Inatividade antes da app ser bloqueada</string>
<string name="application">App</string> <string name="application">App</string>
<string name="menu_app_settings">Configurações do aplicativo</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="brackets">Parênteses</string>
<string name="file_manager_install_description">Explore ficheiros instalando o gestor de ficheiros OpenIntents</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> <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